Adobe Experience Manager (AEM)-pakker er indholdsstyringens ubesungne helte - kraftfulde containere, der samler alt fra kode og konfigurationer til kritisk indhold. Men lad os se det i øjnene: Manuel oprettelse, konfiguration og download af disse pakker kan føles som en kedelig dans af klik.
Hvad hvis du kunne automatisere denne proces med et par tastetryk, hvilket sikrer konsistens, hastighed, pålidelighed og mindre tunge løft?
Jeg vil vise dig et Bash-script, der vender scriptet (pun intended!) om, hvordan AEM-udviklere og -administratorer arbejder med Package Manager API. Tænk på at lave pakker på få sekunder, skræddersy filtre i farten og snappe backups med kirurgisk præcision - alt sammen før din kaffe afkøles til den perfekte nippetemperatur. ☕
Før vi dykker ind, en hurtig bemærkning : Denne artikel er et dybt dyk, omhyggeligt detaljeret og unapologetisk teknisk. Vi vil dissekere scriptets logik, udforske AEM API forviklinger og fejlfinde edge cases. For udviklere, der er ivrige efter at hoppe direkte ind i koden, kan du hoppe til bunden af artiklen. Men hvis du er her for at forstå hvordan og hvorfor bag automatiseringen, så spænd fast - vi går hele vejen ned i kaninhullet. 🕳️
create-remote-aem-pkg.sh
scriptet automatiserer interaktioner med AEM's Package Manager API, og tilbyder en struktureret tilgang til pakkeoprettelse, konfiguration og distribution. Den er designet til udviklere og administratorer og erstatter manuelle arbejdsgange med en kommandolinjedrevet proces, der understreger konsistens og pålidelighed.
/content/dam
, /apps
), der skal inkluderes i pakken.curl
./etc
eller /apps
før du anvender systemopdateringer. ./create-remote-aem-pkg.sh admin securepass123 localhost 4502 backup-group "Content Backup" /backups /content/dam /etc/clientlibs
Denne kommando opretter en pakke med navnet "Content Backup" under gruppen backup-group
, inklusive /content/dam
og /etc/clientlibs
, og gemmer outputtet i mappen /backups
.
Lad os dissekere create-remote-aem-pkg.sh
-scriptet (du kan finde det nederst i artiklen) for at forstå, hvordan det orkestrerer AEM-pakkehåndtering. Vi vil fokusere på dens struktur, nøglefunktioner og workflowlogik – ideel til udviklere, der ønsker at tilpasse eller fejlfinde værktøjet.
_log()
: En hjælpefunktion, der præfikser meddelelser med tidsstempler for klare revisionsspor. _log () { echo "[$(date +%Y.%m.%d-%H:%M:%S)] $1" }
Hvorfor det er vigtigt : Sikrer, at hver handling (f.eks. "Pakkebygget") logges med kontekst, hvilket forenkler fejlfinding.
check_last_exec()
: Validerer succesen af tidligere kommandoer ved at kontrollere afslutningskoder og API-svar. check_last_exec () { # Checks $? (exit status) and $CURL_OUTPUT for errors if [ "$status" -ne 0 ] || [[ $output =~ .*success\":false* ]]; then _log "Error detected!"; exit 1; fi }
Hvorfor det er vigtigt : Forhindrer stille fejl ved at standse eksekvering på kritiske fejl som autentificeringsproblemer eller ugyldige stier.
Scriptet accepterer syv positionelle argumenter efterfulgt af dynamiske filtre:
USR="$1" # AEM username PWD="$2" # AEM password SVR="$3" # Server host (eg, localhost) PORT="$4" # Port (eg, 4502) PKG_GROUP="$5" # Package group (eg, "backups") PKG_NAME="$6" # Package name (eg, "dam-backup") BK_FOLDER="$7" # Backup directory (eg, "/backups") shift 7 # Remaining arguments become filters (eg, "/content/dam")
Positionelle argumenter sikrer enkelhed, mens shift
håndterer variable filterveje fleksibelt.
PKG_NAME
med understregninger for at undgå URL-problemer. PKG_NAME=${PKG_NAME// /_}
curl
til at liste pakker via AEM's API, og undgår overflødige oprettelser. if [ $(curl ... | grep "$PKG_NAME.zip" | wc -l) -eq 1 ]; then _log "Package exists—skipping creation." else curl -X POST ... # Creates the package fi
Konstruerer et JSON-array af filtre fra inputstier:
FILTERS_PARAM="" for i in "${!FILTERS[@]}"; do FILTERS_PARAM+="{\"root\": \"${FILTERS[$i]}\", \"rules\": []}" # Adds commas between entries, but not after the last done
Eksempel output :
[{"root": "/content/dam"}, {"root": "/apps"}]
Denne JSON injiceres i pakkedefinitionen via AEM's /crx/packmgr/update.jsp
.
build
-kommando: curl -X POST … -F "cmd=build"
Bemærk : Scriptet venter på, at buildet er fuldført, før det fortsætter.
curl
til at hente .zip
og gemme den med et tidsstemplet filnavn: BK_FILE="$PKG_NAME-$(date +%Y%m%d-%H%M%S).zip" curl -o "$BK_FOLDER/$BK_FILE" ...
Robust fejlhåndtering og logning er afgørende for uovervågede scripts som create-remote-aem-pkg.sh
, der sikrer, at fejl fanges tidligt og logges tydeligt. Her kan du se, hvordan scriptet beskytter mod uventede problemer og giver praktisk indsigt.
_log
funktionen præfikser hver meddelelse med et [YYYY.MM.DD-HH:MM:SS]
tidsstempel, hvilket skaber et revisionsspor til fejlretning: _log "Starting backup process..." # Output: [2023.10.25-14:30:45] Starting backup process...
Hvorfor det er vigtigt : Tidsstempler hjælper med at korrelere scriptaktivitet med AEM-serverlogfiler eller eksterne hændelser (f.eks. cron-jobplaner).
Kontrol før flyvning :
BK_FOLDER
), før du fortsætter: if [ ! -d "$BK_FOLDER" ]; then _log "Backup folder '$BK_FOLDER' does not exist!" && exit 1 fi
PKG_NAME
for at undgå URL-problemer (f.eks. mellemrum erstattet med understregninger).
API-svarvalidering :
check_last_exec
funktionen undersøger både shell-udgangskoder ( $?
) og AEM API-svar:
check_last_exec "Error message" "$CURL_OUTPUT" $CURL_STATUS
curl
netværksfejl) udløser øjeblikkelige afslutninger.
success\":false
JSON-svar eller "HTTP ERROR"-strenge i AEM-output.
3.3 HTTP-statusbekræftelse : Når pakken downloades, søger scriptet for en 200
statuskode:
if [ "$(curl -w "%{http_code}" ...)" -eq "200" ]; then # Proceed if download succeeds else _log "Error downloading the package!" && exit 1 fi
check_last_exec
fanger 401 Unauthorized
svar og afslutter med en klar fejlmeddelelse.success:false
, scriptet logger "Fejl ved tilføjelse af filtre" og afsluttes.BK_FILE
, kontrollerer filstørrelsen med -s
flag og advarer, før den afsluttes.curl
afsluttes med en kode, der ikke er nul, scriptet logger "Fejl ved bygning af pakken".curl -k
for enkelhedens skyld, hvilket springer SSL-verifikation over. Anbefaling til produktion : Erstat med --cacert
for at angive et CA-bundt.
$AEM_PASSWORD
).set -x
ved scriptets start for at udskrive udførte kommandoer.curl
kommandoer uden for scriptet ./create-remote-aem-pkg.sh ... >> /var/log/aem_backup.log 2>&1
Scriptet create-remote-aem-pkg.sh
er designet til at være et udgangspunkt – et fundament, du kan ændre for at tilpasse sig dit teams behov. Nedenfor er almindelige tilpasninger, sammen med implementeringsvejledning, for at udvide dens funktionalitet eller tilpasse den til specifikke use cases.
Standardfilnavnet bruger et tidsstempel ( $PKG_NAME-$(date +%Y%m%d-%H%M%S).zip
). Rediger dette til at inkludere miljønavne, projekt-id'er eller semantisk versionering:
# Example: Include environment (eg, "dev", "prod") BK_FILE="${PKG_NAME}-${ENV}-$(date +%Y%m%d).zip" # Example: Add Git commit SHA for traceability COMMIT_SHA=$(git rev-parse --short HEAD) BK_FILE="${PKG_NAME}-${COMMIT_SHA}.zip"
Tip : Sørg for, at dato-/tidsformater undgår tegn, der er forbudt i filnavne (f.eks. kolon :
på Windows).
Scriptet accepterer dynamiske stier som filtre, men du kan også hardkode ofte brugte stier eller tilføje ekskluderinger:
# Hardcode essential paths (eg, "/var/audit") DEFAULT_FILTERS=("/content/dam" "/apps" "/var/audit") FILTERS=("${DEFAULT_FILTERS[@]}" "${@}") # Merge with command-line inputs # Add exclusion rules (requires AEM API support) FILTERS_PARAM+="{\"root\": \"${FILTERS[$i]}\", \"rules\": [{\"modifier\": \"exclude\", \"pattern\": \".*/test/*\"}]}"
Undgå almindelige kodeord :
Brug miljøvariabler eller en hemmelighedsmanager til at indsætte legitimationsoplysninger:
# Fetch password from environment variable PWD="$AEM_PASSWORD" # Use AWS Secrets Manager (example) PWD=$(aws secretsmanager get-secret-value --secret-id aem/prod/password --query SecretString --output text)
Håndhæv SSL-validering :
Erstat curl -k
(usikker) med et betroet CA-certifikat:
curl --cacert /path/to/ca-bundle.crt -u "$USR":"$PWD" ...
Udvid scriptet for at udløse downstream-processer efter en vellykket download:
# Example: Upload to cloud storage aws s3 cp "$BK_FOLDER/$BK_FILE" s3://my-backup-bucket/ # Example: Validate package integrity CHECKSUM=$(sha256sum "$BK_FOLDER/$BK_FILE" | cut -d ' ' -f 1) _log "SHA-256 checksum: $CHECKSUM" # Example: Clean up old backups (retain last 7 days) find "$BK_FOLDER" -name "*.zip" -mtime +7 -exec rm {} \;
Giv teams besked om succes/fiasko via Slack, e-mail eller overvågningsværktøjer:
# Post to Slack on failure curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"🚨 AEM backup failed: $(hostname)\"}" \ https://hooks.slack.com/services/YOUR/WEBHOOK/URL # Send email via sendmail if [ $? -ne 0 ]; then echo "Subject: Backup Failed" | sendmail [email protected] fi
Håndtering af AEM-pakker behøver ikke at være en manuel opgave, der er udsat for fejl. Med create-remote-aem-pkg.sh
scriptet kan du transformere pakkeoprettelse, filtrering og distribution til en strømlinet, gentagelig proces. Dette værktøj handler ikke kun om at spare tid, det handler om at muliggøre konsekvens, pålidelighed og skalerbarhed i dine AEM-operationer.
Automatisering vinder : Ved at eliminere gentagne GUI-interaktioner reducerer scriptet menneskelige fejl og frigør teams til at fokusere på opgaver af højere værdi.
Fleksibilitet betyder noget : Uanset om der sikkerhedskopieres kritisk indhold, synkroniseres miljøer eller forberedes til opdateringer, tilpasser scriptet sig til forskellige brugssager med minimal justering.
Resiliens er nøglen : Indbygget logning, fejltjek og sikkerhedsovervejelser sikrer, at scriptet opfører sig forudsigeligt, selv når tingene går sidelæns.
Fantastiske værktøjer er født af udfordringer i den virkelige verden. Dette script er et udgangspunkt; tænk på det som et fundament at bygge videre på, efterhånden som dit teams behov vokser. Uanset om du er en solo-udvikler eller en del af et stort DevOps-team, eksemplificerer automatisering som denne, hvordan små investeringer i kode kan give store afkast i produktivitet og ro i sindet.
Klar til at tage det næste skridt?
Tak fordi du følger med - gå nu videre og automatiser! 🚀
#!/bin/bash set -eo pipefail # The script will create a package thought the package manager api: # - The package is created, if not already present # - Package filters are populated accordingly to specified paths # - Package is builded # - Package is download to the specified folder _log () { echo "[$(date +%Y.%m.%d-%H:%M:%S)] $1" } check_last_exec () { local message="$1" local output="$2" local status=$3 if [ "$status" -ne 0 ]; then echo && echo "$message" && echo exit 1 fi if [[ $output =~ .*success\":false* ]] || [[ $output =~ .*"HTTP ERROR"* ]]; then _log "$message" exit 1 fi } USR="$1" PWD="$2" SVR="$3" PORT="$4" PKG_GROUP="$5" PKG_NAME="$6" BK_FOLDER="$7" shift 7 # The following paths will be included in the package FILTERS=($@) BK_FILE=$PKG_NAME"-"$(date +%Y%m%d-%H%M%S).zip _log "Starting backup process..." echo "AEM instance: '$SVR':'$PORT' AEM User: '$USR' Package group: $PKG_GROUP Package name: '$PKG_NAME' Destination folder: $BK_FOLDER Destination file: '$BK_FILE' Filter paths: " printf '\t%s\n\n' "${FILTERS[@]}" if [ ! -d "$BK_FOLDER" ]; then _log "Backup folder '$BK_FOLDER' does not exist!" && echo exit 1 fi PKG_NAME=${PKG_NAME// /_} check_last_exec "Error replacing white space chars from package name!" "" $? || exit 1 _log "Removed whitespaces from package name: '$PKG_NAME'" BK_FILE=$PKG_NAME.zip _log "Backup file: '$BK_FILE'" _log "Creating the package..." if [ $(curl -k -u "$USR":"$PWD" "$SVR:$PORT/crx/packmgr/service.jsp?cmd=ls" 2>/dev/null | grep "$PKG_NAME.zip" | wc -l) -eq 1 ]; then _log " Package '$PKG_GROUP/$PKG_NAME' is already present: skipping creation." else curl -k --silent -u "$USR":"$PWD" -X POST \ "$SVR:$PORT/crx/packmgr/service/.json/etc/packages/$PKG_GROUP/$PKG_NAME?cmd=create" \ -d packageName="$PKG_NAME" -d groupName="$PKG_GROUP" check_last_exec " Error creating the package!" "" $? _log " Package created" fi # create filters variable FILTERS_PARAM="" ARR_LEN="${#FILTERS[@]}" for i in "${!FILTERS[@]}"; do FILTERS_PARAM=$FILTERS_PARAM"{\"root\": \"${FILTERS[$i]}\", \"rules\": []}" T=$((i+1)) if [ $T -ne $ARR_LEN ]; then FILTERS_PARAM=$FILTERS_PARAM", " fi done # add filters _log "Adding filters to the package..." CURL_OUTPUT=$(curl -k --silent -u "$USR":"$PWD" -X POST "$SVR:$PORT/crx/packmgr/update.jsp" \ -F path=/etc/packages/"$PKG_GROUP"/"$PKG_NAME".zip -F packageName="$PKG_NAME" \ -F groupName="$PKG_GROUP" \ -F filter="[$FILTERS_PARAM]" \ -F "_charset_=UTF-8") CURL_STATUS=$? # Pass the status to the check_last_exec function check_last_exec "Error adding filters to the package!" "$CURL_OUTPUT" $CURL_STATUS _log " Package filters updated successfully." # build package _log "Building the package..." CURL_OUTPUT=$(curl -k -u "$USR":"$PWD" -X POST \ "$SVR:$PORT/crx/packmgr/service/script.html/etc/packages/$PKG_GROUP/$PKG_NAME.zip" \ -F "cmd=build") check_last_exec " Error building the package!" "$CURL_OUTPUT" $? _log " Package built." # download package _log "Downloading the package..." if [ "$(curl -w "%{http_code}" -o "$BK_FOLDER/$BK_FILE" -k --silent -u "$USR":"$PWD" "$SVR:$PORT/etc/packages/$PKG_GROUP/$PKG_NAME.zip")" -eq "200" ]; then if [ -f "$BK_FOLDER/$BK_FILE" ] && [ -s "$BK_FOLDER/$BK_FILE" ]; then _log " Package $BK_FILE downloaded in $BK_FOLDER." exit 0 fi fi _log " Error downloading the package!" exit 1
[¹] At springe SSL-verifikation over med curl -k
er praktisk til test, men du vil have noget mere robust i produktionen (for eksempel --cacert
)!