You’ve probably seen the curl command shown below in many articles online.
curl -u admin:admin -F file=@"name of zip file" -F name="name of package" -F force=true -F install=true http://localhost:4505/crx/packmgr/service.jsp
It allows you to upload and install a package to an AEM server, and can also be used in builds within Jenkins to deploy a package after the maven build completes.
In this post, I will walk through a script that will do this for us in a cleaner manner. This script will fail if the package deployment fails or if the AEM server returns anything but 200.
The Process
The script:
#!/bin/bash
# Doc
HELP_TEXT="
A shell script to install packages to AEM
Params:
-f, --file The zip file to instal (cannot be used with -m, --module param)
-m, --module The folder name of maven module that produces a zip package (cannot be used with -f, --file param)
-h, --host The instance host
-p, --port The instance port
-u, --user The user name to use for auth
Password should be set via env variable:
CRX_PASSWORD Set from env variable, default to 'admin'
Other variables you can set via environment variables:
CRX_USER Set via user argument above, defaults to 'admin'
CRX_PORT Set via port argument above, defaults to '4502'
CRX_HOST Set via host argument above, defaults to 'localhost'
"
# if the first arg is "--help", "help" or "-h" print help message and exit
if [ $1 = "--help" ] || [ $1 = "help" ] || [ $1 = "-h" ]; then
printf "$HELP_TEXT"
exit 1
fi
# parse params as per: https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
# parse file argument
-f|--file)
FILE="$2"
shift # past argument
shift # past value
;;
# parse file argument
-m|--module)
MVN_MODULE="$2"
shift # past argument
shift # past value
;;
# parse host argument
-h|--host)
CRX_HOST="$2"
shift # past argument
shift # past value
;;
# parse port argument
-p|--port)
CRX_PORT="$2"
shift # past argument
shift # past value
;;
# parse user argument
-u|--user)
CRX_USER="$2"
shift # past argument
shift # past value
;;
# unknown option
*)
echo "WARNING: unknown option: $1"
shift # past argument
;;
esac
done
# use defaults if param was not passed
CRX_USER="${CRX_USER:-admin}"
CRX_PASSWORD="${CRX_PASSWORD:-admin}" # password should be passed as an env variable
CRX_HOST="${CRX_HOST:-localhost}"
CRX_PORT="${CRX_PORT:-4502}"
# If an module folder name is passed, use that to find the zip package to install
if [ ! -z "$MVN_MODULE" ]
then
if [ -d "$MVN_MODULE" ]
then
ZIP_PATTERN="$MVN_MODULE/target/*.zip"
ZIP_PACKAGES=( $ZIP_PATTERN )
FILE="${ZIP_PACKAGES[0]}"
else
echo "ERROR: The module folder: $MVN_MODULE does not exist}"
exit 1
fi
else
echo "INFO: no module param was passed. Using file param if exists"
fi
# sets INSTALL_COMMAND, first arg is the password
setInstallCommand(){
# --fai : https://curl.haxx.se/docs/manpage.html#-f fails on server error
# -u : user:password for basic auth
# -F force=true : force install
# -F install=true : install after upload
# -F strict=true : fails if package fails to deploy
eval "INSTALL_COMMAND='curl --fail -u $CRX_USER:$1 -F file=@$FILE -F name=$FILE -F force=true -F install=true -F strict=true http://$CRX_HOST:$CRX_PORT/crx/packmgr/service.jsp'"
}
# print command that will be executed, sub password with "*****"setInstallCommand "*****"
echo "Executing command: $INSTALL_COMMAND"
# Execute command
setInstallCommand "$CRX_PASSWORD"
eval "$INSTALL_COMMAND"
Copy the code and paste it into a file
deploy.sh
Make it executable
chmod +x deploy.sh
Now, let’s explore what we can do with it
(You should first copy paste it into the root of your AEM project):
Run ./deploy help to view the help message and all available params.
A shell script to install packages to AEM
Params:
-f, --file The zip file to instal (cannot be used with -m, --module param)
-m, --module The folder name of maven module that produces a zip package (cannot be used with -f, --file param)
-h, --host The instance host
-p, --port The instance port
-u, --user The user name to use for auth
Password should be set via env variable:
CRX_PASSWORD Set from env variable, default to 'admin'
Other variables you can set via environment variables:
CRX_USER Set via user argument above, defaults to 'admin'
CRX_PORT Set via port argument above, defaults to '4502'
CRX_HOST Set via host argument above, defaults to 'localhost'
./deploy.sh -m ui.apps
./deploy.sh -m ui.apps -p 4503
Wait a sec! What just happened there?
We specified that the maven module via “-m ui.apps” the deploy script will go to the folder `ui.apps/target` and pick the first .zip file it finds and deploy that. Remember that this assumes that your module produces one package, as is often the case.
OK, now let’s say you want to deploy a very specific package in a very specific location in your repo: “packages/my-favorite-package.zip”. You can use -f for that:
./deploy.sh -f packages/my-favorite-package.zip
Now let’s move to Jenkins (or your favorite CD). Things get a little interesting here. You have a secret password and you don’t want to share it with everyone who can see the build. Fear not! You can use secret environment variables!
There are a few ways to do this, which I won’t get into. You can refer to this and this and many others to see how you can bind a password to an environment variable. In our case, the goal is to bind your password to CRX_PASSWORD environment variable.
Note: you can also specify the username, host and port via CRX_USER, CRX_HOST and CRX_PORT respectively.
Now in your Jenkins build, you can add a post-build script that looks like:
./deploy.sh -m ui.apps -u adminusername -h dev-author.mycompany.com -p 4502
If you have more than one module that produces packages, you can keep calling the deploy script. For example, if you want to deploy both ui.apps and ui.content packages to both your author and publish instance:
./deploy.sh -m ui.apps -u adminusername -h dev-author.mycompany.com -p 4502
./deploy.sh -m ui.apps -u adminusername -h dev-publish.mycompany.com -p 4503
./deploy.sh -m ui.content -u adminusername -h dev-author.mycompany.com -p 4502
./deploy.sh -m ui.content -u adminusername -h dev-publish.mycompany.com -p 4503
No comments:
Post a Comment
If you have any doubts or questions, please let us know.