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. 🕳️
1. Script Oversigt
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.
1.1 Kernefunktioner
- Pakkevalidering : Kontrollerer for eksisterende pakker for at undgå redundans før oprettelse påbegyndes.
- Dynamisk filterindsprøjtning : Definerer programmatisk indholdsstier (f.eks.
/content/dam
,/apps
), der skal inkluderes i pakken. - Byg automatisering : Udløser pakkekompilering og downloader output til en specificeret mappe, tilføjer et tidsstempel til filnavne til versionskontrol.
- Fejlhåndtering : Validerer HTTP-svar, mappestier og godkendelse for at give handlingsvenlig feedback under fejl.
- Godkendelse : Understøtter grundlæggende¹ legitimationsbaseret godkendelse via
curl
.
1.2 Vigtigste fordele
- Effektivitet : Reducerer manuelle trin, der kræves til pakkeoprettelse, konfiguration og download.
- Konsistens : Sikrer ensartede pakkestrukturer og navnekonventioner på tværs af miljøer.
- Sporbarhed : Detaljeret logning på hvert trin (oprettelse, filtrering, bygning, download) hjælper med revision og fejlfinding.
1.3 Praktiske anvendelser
- Planlagte sikkerhedskopier : Integrer med cron-job for regelmæssigt at arkivere kritiske indholdsstier.
- Miljøsynkronisering : Repliker konfigurationer eller indhold mellem AEM-instanser under implementeringer.
- Snapshots før opdatering : Optag stabile tilstande af
/etc
eller/apps
før du anvender systemopdateringer.
1.4 Forudsætninger
- Adgang til en AEM-instans (legitimationsoplysninger, server, port).
- Grundlæggende kendskab til Bash scripting og AEM's Package Manager.
- Tilladelse til at oprette og downloade pakker via AEM API.
1.5 Eksempel på brug
./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
.
2. Script Opdeling
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.
2.1 Kernefunktioner
-
_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.
2.2 Indgangsparametre
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.
2.3 Pakkevalidering og oprettelse
- Sanitize Names : Erstatter mellemrum i
PKG_NAME
med understregninger for at undgå URL-problemer.
PKG_NAME=${PKG_NAME// /_}
- Tjek eksisterende pakker : Bruger
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
2.4 Dynamisk filterkonfiguration
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
.
2.5 Byg og download arbejdsgang
- Byg pakken : Udløser kompilering ved hjælp af AEM's
build
-kommando:
curl -X POST … -F "cmd=build"
Bemærk : Scriptet venter på, at buildet er fuldført, før det fortsætter.
- Download : Bruger
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" ...
3. Fejlhåndtering, sikkerhedsbemærkninger og logføring
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.
3.1 Logningsmekanisme
- Tidsstemplede logs :
_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).
- Udførligt output : Kritiske trin, som pakkeoprettelse, filteropdateringer og downloads, logges eksplicit for at spore fremskridt.
3.2 Workflow for fejlvalidering
Kontrol før flyvning :
- Validerer eksistensen af sikkerhedskopieringsmappen (
BK_FOLDER
), før du fortsætter:
if [ ! -d "$BK_FOLDER" ]; then _log "Backup folder '$BK_FOLDER' does not exist!" && exit 1 fi
- Renser
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
- Afslutningskoder : Værdier, der ikke er nul (f.eks.
curl
netværksfejl) udløser øjeblikkelige afslutninger.
- API-fejl : Registrerer
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
3.4 Almindelige fejlscenarier
- Ugyldige legitimationsoplysninger:
check_last_exec
fanger401 Unauthorized
svar og afslutter med en klar fejlmeddelelse. - Ugyldig filtersti: AEM API returnerer
success:false
, scriptet logger "Fejl ved tilføjelse af filtre" og afsluttes. - Disk fuld: Kan ikke skrive
BK_FILE
, kontrollerer filstørrelsen med-s
flag og advarer, før den afsluttes. - AEM-instans kan ikke nås:
curl
afsluttes med en kode, der ikke er nul, scriptet logger "Fejl ved bygning af pakken".
3.5 Sikkerhedshensyn
- SSL Certificate Bypass : Scriptet bruger
curl -k
for enkelhedens skyld, hvilket springer SSL-verifikation over. Anbefaling til produktion : Erstat med--cacert
for at angive et CA-bundt.
- Plaintext-adgangskoder : Legitimationsoplysninger sendes som argumenter, som kan vises i proceslogfiler. Afbødning : Brug miljøvariabler eller en hemmelighedsboks (f.eks.
$AEM_PASSWORD
).
3.6 Fejlretningstips
- Aktiver detaljeret output : Tilføj midlertidigt
set -x
ved scriptets start for at udskrive udførte kommandoer. - Test API-kald manuelt : Isoler problemer ved at køre kritiske
curl
kommandoer uden for scriptet - Inspicer logfiler : Omdiriger scriptoutput til en fil til senere analyse:
./create-remote-aem-pkg.sh ... >> /var/log/aem_backup.log 2>&1
4. Skræddersy værktøjet til din arbejdsgang
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.
4.1 Justering af sikkerhedskopieringsfilnavnsformatet
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).
4.2 Udvidelse eller ændring af filtre
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/*\"}]}"
4.3 Forbedring af sikkerheden
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" ...
4.4 Tilføjelse af Post-Build-handlinger
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 {} \;
4.5 Tilføjelse af meddelelsesalarmer
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
5. Konklusion
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.
Nøgle takeaways
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?
- 🛠️ Tilpas : Skræddersy scriptet ved at bruge sektion 6 som din guide.
- 🔍 Audit : Gennemgå dine eksisterende AEM-arbejdsgange for automatiseringsmuligheder.
- 🤝 Del : Mentor dit team eller skriv et blogindlæg om dine ændringer.
Tak fordi du følger med - gå nu videre og automatiser! 🚀
Tillæg
Komplet kode
#!/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
Referencer
[¹] At springe SSL-verifikation over med curl -k
er praktisk til test, men du vil have noget mere robust i produktionen (for eksempel --cacert
)!