3 shell scripts to help you manage AEM Instances

Reading Time: 5 minutes

The Problem

Every AEM developers career starts by double-clicking the AEM jar file. And that’s where you can do your first mistake. AEM might shout at to you “Hey NOOB you need a license!”. You forgot to copy the license file next to the jar… *sigh*. But don’t worry, this happens to everybody.

After copying the license file, AEM will start and you will get a nice little GUI.

Congratulations! You are ready to go! You know where AEM is running (localhost:4502) and you even have a little stop button in the bottom left corner. But this is probably the only time you see this GUI. All the cool kids start AEM with the start script in crx-quickstart/bin/. But how do you know if AEM is running? How can you find out which port is used and how do you stop the instance?

This blogpost will provide you with three little shell scripts to address these problems and help you to manage your AEM instances without the need for a GUI.

#1 Get information about running AEM instances

To figure out which AEM instances are currently running you might smash something like this into your terminal window:

This method has several disadvantages. The command is hard to remember and the output is very hard to read.

Here’s a little challenge for you: Can you figure out the port, debug port and runmodes in the gif above before it loops? Give it a try.

And anyway, what does this command even mean?

Bonus Tip – Great page to explain shell commands (bookmark it!): https://explainshell.com/explain?cmd=ps+aux+%7C+grep+cq

Back to the topic. Our first script (“aeminfo”) provides a simple overview of all running AEM instances. It turns the complicated output into a readable form:

Nice! All you have to do is adding this script to your .bash_profile. The script does not use any external dependencies and should run many unix/linux based systems (tested on OSX and CentOS).

# Displays all running AEM instances
function aeminfo(){

    if [ "$(ps aux | grep q | grep crx)" ]
        then

            count=0;
            echo ""
            ps auxeww | grep q | grep sling | while read -r line ; do

                ((count++));
                params=($line);

                username=(${params[0]});
                pid=(${params[1]});
                port="not found";
                debugPort="not found";
                xmx="not found";
                runmodes="not found";
                path="not found";

                portRegex="-p ([0-9]+)";
                debugPortRegex="address=([0-9]+)";
                xmxRegex="-Xmx([^[:space:]]+)";
                runmodesRegex="-Dsling.run.modes=([^[:space:]]+)";
                pathRegex="PWD=([^[:space:]]+)";

                [[ $line =~ $portRegex ]] && port="${BASH_REMATCH[1]}";
                [[ $line =~ $runmodesRegex ]] && runmodes="${BASH_REMATCH[1]}";
                [[ $line =~ $debugPortRegex ]] && debugPort="${BASH_REMATCH[1]}";
                [[ $line =~ $pathRegex ]] && path="${BASH_REMATCH[1]}";
                [[ $line =~ $xmxRegex ]] && xmx="${BASH_REMATCH[1]}";

                echo "----------------------";
                echo "AEM Instance" $count;
                echo "----------------------";
                echo "username:  "$username;
                echo "pid:       "$pid;
                echo "port:      "$port;
                echo "debugPort: "$debugPort;
                echo "memory:    "$xmx;
                echo "runmodes:  "$runmodes;
                echo "path:      "$path;
                echo "----------------------";
                echo "";

            done

        else
            echo "";
            echo "No running AEM instances found";
            echo "";
        fi
}

#2 Death to all AEM instances!

Our next script (“killaem”) is pretty small. It just shuts down a running AEM instance:

function killaem() {
    kill $(ps aux | grep 'rx-quickstart' | awk '{print $2}')
}

But experienced AEM developers might know that asking AEM politely to stop is sometimes not enough.

Especially when it’s Friday evening and you’re looking forward to a cold beer in your local pub. For this emergency situation you could use a slight variation of the script (“KILLAEM”) (notice the capitalisation!). This will kill your instance definitely. No matter what. The consequences might be that the instance will be in the same condition as you are after too many beers in said pub. Broken and unable to work. So be careful with this command (and with drinking for that matter!)

function KILLAEM() {
    kill -9 $(ps aux | grep 'rx-quickstart' | awk '{print $2}')
}

#3 Improved debugging

So you destroyed your instance and it won’t start properly? What to do next? Have a look at your log files!

If you use the regular “tail -f error.log” command you will quickly notice that AEM logs a lot of stuff. How could you ever find that one useful log entry in the haystack of unnecessary INFO logs? This “aemlog” script might help you! It displays different log levels with different colours:

function aemlog() {
    tail -fn 128 "$@" | awk '
    /SEVERE/ {print "\033[35m" $0 "\033[39m"}
    /ERROR/ {print "\033[31m" $0 "\033[39m"}
    /WARN/ {print "\033[33m" $0 "\033[39m"}
    /DEBUG/ {print "\033[30m" $0 "\033[39m"}
    !/SEVERE|ERROR|WARN|DEBUG/ {print $0 }
';}
You could even observe multiple log files at once. Just pass them as parameters to the command: aemlog error.log access.log audit.log

Conclusion

The three little scripts might not do very much but they are easy to set up, don’t need any third-party software and provide some useful functionalities.

Just copy all shell scripts from this page into your ~/.bash_profile and you are ready to go!

If you have any suggestions for improvements feel free to leave a comment!

Deploy Spring Boot Application on Google Cloud with GitLab

Reading Time: 5 minutes

A lot of developers experience a painful process with their code being deployed on the environment. We, as a company, suffer the same thing so that we wanted to create something to make our life easier.

After internal discussions, we decided to make fully automated CI/CD process. We investigated and came up with decision for that purpose to implement Gitlab CI/CD with google cloud deployment.

Further in this blog you can see how we achieved that and how you can achieve the same.

Let’s start with setting up. 🙂

  • After that, we create simple rest controller for testing purposes.
package com.northlabs.gitlabdemo.rest;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RootController {

    @GetMapping(value = "/")
    public String root() {
        return "Hello from Root";
    }

    @GetMapping(value = "/demo")
    public String demo() {
        return "Hello from Demo";
    }

}
  • Next step is to push the application to our GitLab repo.
  1. cd path_to_root_folder
  2. git init
  3. git remote add origin https://gitlab.com/47northlabs/47northlabs/product/playground/gitlab-demo.git
  4. git add .
  5. git commit -m “Initial commit”
  6. git push -u origin master

Now, after we have our application in GitLab repository, we can go to setup Google Cloud. But, before you start, be sure that you have a G-Suite account with enabled billing.

  • First step is to create a new project: in my case it is northlabsgitlab-demo.

Create project: northlabs-gitlab-demo
  • Now, let’s create our Kubernetes Cluster.

It will take some time after Kubernetes clusters are initialized so that GitLab will be able to create a cluster.

We are done with Google Cloud, so it’s time to setup Kubernetes in our GitLab repository.

  • First we add Kubernetes cluster.
Add Kubernetes Cluster
Sign in with Google
  • Next, we give a name to the cluster and select a project from our Google Cloud account: in my case it’s gitlab-demo.
  • The base domain name should be set up.
  • Installing Helm Tiller is required, and installing other applications is optional (I installed Ingress, Cert-Manager, Prometheus, and GitLab Runner).

Install Helm Tiller

Installed Ingress, Cert-Manager, Prometheus, and GitLab Runner

After installing the applications it’s IMPORTANT to update your DNS settings. Ingress IP address should be copied and added to your DNS configuration.
In my case, it looks like this:

Configure DNS

We are almost done. 🙂

  • The last thing that should be done is to enable Auto DevOps.
  • And to setup Auto DevOps.

Now take your coffee and watch your pipelines. 🙂
After couple of minutes your pipeline will finish and will look like this:

Now open the production pipeline and in the log, under notes section, check the URL of the application. In my case that is:

Application should be accessible at: http://47northlabs-47northlabs-product-playground-gitlab-demo.gitlab-demo.north-47.com

Open the URL in browser or postman.

https://47northlabs-47northlabs-product-playground-gitlab-demo.gitlab-demo.north-47.com
https://47northlabs-47northlabs-product-playground-gitlab-demo.gitlab-demo.north-47.com/demo
  • Let’s edit our code and push it to GitLab repository.
package com.northlabs.gitlabdemo.rest;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RootController {

    @GetMapping(value = "/")
    public String root() {
        return "Hello from Root v1";
    }

    @GetMapping(value = "/demo")
    public String demo() {
        return "Hello from Demo v1";
    }
}

After the job is finished, if you check the same URL, you will see that the values are now changed.


https://47northlabs-47northlabs-product-playground-gitlab-demo.gitlab-demo.north-47.com

https://47northlabs-47northlabs-product-playground-gitlab-demo.gitlab-demo.north-47.com/demo

And we are done !!!

This is just a basic implementation of the GitLab Auto DevOps. In some of the next blogs we will show how to customize your pipeline, and how to add, remove or edit jobs.