Τα πακέτα Adobe Experience Manager (AEM) είναι οι αφανείς ήρωες της διαχείρισης περιεχομένου — ισχυρά κοντέινερ που συνδυάζουν τα πάντα, από κώδικα και διαμορφώσεις έως κρίσιμο περιεχόμενο. Αλλά ας το παραδεχτούμε: η μη αυτόματη δημιουργία, διαμόρφωση και λήψη αυτών των πακέτων μπορεί να μοιάζει σαν ένας κουραστικός χορός κλικ.
Τι θα γινόταν αν μπορούσατε να αυτοματοποιήσετε αυτή τη διαδικασία με μερικά πλήκτρα, διασφαλίζοντας συνέπεια, ταχύτητα, αξιοπιστία και λιγότερη άρση βαρών;
Θα σας δείξω ένα σενάριο Bash που ανατρέπει το σενάριο (λογοπαίγνιο!) σχετικά με τον τρόπο με τον οποίο οι προγραμματιστές και οι διαχειριστές AEM λειτουργούν με το API του Package Manager. Σκεφτείτε να δημιουργήσετε πακέτα σε δευτερόλεπτα, να προσαρμόσετε τα φίλτρα εν κινήσει και να δημιουργήσετε αντίγραφα ασφαλείας με χειρουργική ακρίβεια — όλα αυτά πριν κρυώσει ο καφές σας σε αυτήν την τέλεια θερμοκρασία. ☕
Πριν βουτήξουμε, μια γρήγορη σημείωση : Αυτό το άρθρο είναι μια βαθιά κατάδυση, σχολαστικά λεπτομερής και μη απολογητικά τεχνικό. Θα αναλύσουμε τη λογική του σεναρίου, θα εξερευνήσουμε τις περιπλοκές του AEM API και θα αντιμετωπίσουμε προβλήματα αιχμής. Για προγραμματιστές που θέλουν να μεταβούν κατευθείαν στον κώδικα, μπορείτε να μεταβείτε στο κάτω μέρος του άρθρου. Αλλά αν είστε εδώ για να καταλάβετε πώς και γιατί πίσω από τον αυτοματισμό, βάλτε τον ιμάντα - πηγαίνουμε μέχρι την τρύπα του κουνελιού. 🕳️
Το σενάριο create-remote-aem-pkg.sh
αυτοματοποιεί τις αλληλεπιδράσεις με το API Package Manager της AEM, προσφέροντας μια δομημένη προσέγγιση για τη δημιουργία, τη διαμόρφωση και τη διανομή πακέτων. Σχεδιασμένο για προγραμματιστές και διαχειριστές, αντικαθιστά τις μη αυτόματες ροές εργασίας με μια διαδικασία που βασίζεται στη γραμμή εντολών που δίνει έμφαση στη συνέπεια και την αξιοπιστία.
/content/dam
, /apps
) που θα συμπεριληφθούν στο πακέτο.curl
./etc
ή /apps
πριν από την εφαρμογή ενημερώσεων συστήματος. ./create-remote-aem-pkg.sh admin securepass123 localhost 4502 backup-group "Content Backup" /backups /content/dam /etc/clientlibs
Αυτή η εντολή δημιουργεί ένα πακέτο με το όνομα "Content Backup" κάτω από την ομάδα backup-group
, συμπεριλαμβανομένων /content/dam
και /etc/clientlibs
, και αποθηκεύει την έξοδο στον κατάλογο /backups
.
Ας αναλύσουμε το σενάριο create-remote-aem-pkg.sh
(μπορείτε να το βρείτε στο κάτω μέρος του άρθρου) για να κατανοήσουμε πώς ενορχηστρώνει τη διαχείριση πακέτων AEM. Θα εστιάσουμε στη δομή του, τις βασικές λειτουργίες και τη λογική ροής εργασίας — ιδανικό για προγραμματιστές που θέλουν να προσαρμόσουν ή να διορθώσουν το εργαλείο.
_log()
: Μια βοηθητική συνάρτηση που προσαρτά μηνύματα με χρονικές σημάνσεις για σαφείς διαδρομές ελέγχου. _log () { echo "[$(date +%Y.%m.%d-%H:%M:%S)] $1" }
Γιατί έχει σημασία : Διασφαλίζει ότι κάθε ενέργεια (π.χ. "Έγινε δημιουργία πακέτου") καταγράφεται με το περιβάλλον, απλοποιώντας την αντιμετώπιση προβλημάτων.
check_last_exec()
: Επικυρώνει την επιτυχία προηγούμενων εντολών ελέγχοντας τους κωδικούς εξόδου και τις αποκρίσεις API. 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 }
Γιατί έχει σημασία : Αποτρέπει τις σιωπηλές αποτυχίες σταματώντας την εκτέλεση σε κρίσιμα σφάλματα όπως ζητήματα ελέγχου ταυτότητας ή μη έγκυρες διαδρομές.
Το σενάριο δέχεται επτά ορίσματα θέσης που ακολουθούνται από δυναμικά φίλτρα:
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")
Τα επιχειρήματα θέσης εξασφαλίζουν απλότητα, ενώ shift
χειρίζεται τις μεταβλητές διαδρομές φίλτρου με ευελιξία.
PKG_NAME
με υπογράμμιση για την αποφυγή προβλημάτων διεύθυνσης URL. PKG_NAME=${PKG_NAME// /_}
curl
για τη λίστα πακέτων μέσω του API της AEM, αποφεύγοντας περιττές δημιουργίες. if [ $(curl ... | grep "$PKG_NAME.zip" | wc -l) -eq 1 ]; then _log "Package exists—skipping creation." else curl -X POST ... # Creates the package fi
Κατασκευάζει έναν πίνακα JSON φίλτρων από διαδρομές εισόδου:
FILTERS_PARAM="" for i in "${!FILTERS[@]}"; do FILTERS_PARAM+="{\"root\": \"${FILTERS[$i]}\", \"rules\": []}" # Adds commas between entries, but not after the last done
Παράδειγμα εξόδου :
[{"root": "/content/dam"}, {"root": "/apps"}]
Αυτό το JSON εισάγεται στον ορισμό του πακέτου μέσω του τερματικού σημείου /crx/packmgr/update.jsp
της AEM.
build
της AEM: curl -X POST … -F "cmd=build"
Σημείωση : Το σενάριο περιμένει να ολοκληρωθεί η κατασκευή πριν συνεχίσει.
curl
για να ανακτήσει το .zip
και να το αποθηκεύσει με ένα όνομα αρχείου με χρονική σήμανση: BK_FILE="$PKG_NAME-$(date +%Y%m%d-%H%M%S).zip" curl -o "$BK_FOLDER/$BK_FILE" ...
Ο ισχυρός χειρισμός σφαλμάτων και η καταγραφή είναι ζωτικής σημασίας για σενάρια χωρίς παρακολούθηση, όπως create-remote-aem-pkg.sh
, διασφαλίζοντας ότι οι αποτυχίες εντοπίζονται έγκαιρα και καταγράφονται με σαφήνεια. Δείτε πώς το σενάριο προστατεύεται από απροσδόκητα ζητήματα και παρέχει χρήσιμες πληροφορίες.
_log
δίνει πρόθεμα σε κάθε μήνυμα με μια χρονική σήμανση [YYYY.MM.DD-HH:MM:SS]
, δημιουργώντας μια διαδρομή ελέγχου για τον εντοπισμό σφαλμάτων: _log "Starting backup process..." # Output: [2023.10.25-14:30:45] Starting backup process...
Γιατί έχει σημασία : Οι χρονικές σημάνσεις βοηθούν στο συσχετισμό της δραστηριότητας σεναρίου με αρχεία καταγραφής διακομιστή AEM ή εξωτερικά συμβάντα (π.χ. προγράμματα εργασιών cron).
Έλεγχοι πριν από την πτήση :
BK_FOLDER
) πριν συνεχίσετε: if [ ! -d "$BK_FOLDER" ]; then _log "Backup folder '$BK_FOLDER' does not exist!" && exit 1 fi
PKG_NAME
για να αποφύγει προβλήματα διεύθυνσης URL (π.χ. αντικατάσταση διαστημάτων με κάτω παύλες).
Επικύρωση απόκρισης API :
Η συνάρτηση check_last_exec
εξετάζει τόσο τους κωδικούς εξόδου φλοιού ( $?
) όσο και τις αποκρίσεις AEM API:
check_last_exec "Error message" "$CURL_OUTPUT" $CURL_STATUS
curl
) ενεργοποιούν άμεσες εξόδους.
success\":false
απαντήσεις JSON ή συμβολοσειρές "ΣΦΑΛΜΑ HTTP" στην έξοδο AEM.
3.3 Επαλήθευση κατάστασης HTTP : Κατά τη λήψη του πακέτου, το σενάριο ελέγχει για κωδικό κατάστασης 200
:
if [ "$(curl -w "%{http_code}" ...)" -eq "200" ]; then # Proceed if download succeeds else _log "Error downloading the package!" && exit 1 fi
check_last_exec
συλλαμβάνει 401 Unauthorized
απαντήσεις και εξέρχεται με ένα σαφές μήνυμα σφάλματος.success:false
, το σενάριο καταγράφει "Σφάλμα προσθήκης φίλτρων" και τερματίζει.BK_FILE
, ελέγχει το μέγεθος του αρχείου με σημαία -s
και ειδοποιήσεις πριν από την έξοδο.curl
εξέρχεται με έναν μη μηδενικό κωδικό, το σενάριο καταγράφει "Σφάλμα κατά τη δημιουργία του πακέτου".curl -k
για απλότητα, το οποίο παρακάμπτει την επαλήθευση SSL. Σύσταση για παραγωγή : Αντικαταστήστε με --cacert
για να καθορίσετε ένα πακέτο CA.
$AEM_PASSWORD
).set -x
στην αρχή του σεναρίου για να εκτυπώσετε τις εκτελεσμένες εντολές.curl
εκτός του σεναρίου ./create-remote-aem-pkg.sh ... >> /var/log/aem_backup.log 2>&1
Το σενάριο create-remote-aem-pkg.sh
έχει σχεδιαστεί για να είναι ένα σημείο εκκίνησης — μια βάση που μπορείτε να τροποποιήσετε για να ευθυγραμμιστεί με τις ανάγκες της ομάδας σας. Ακολουθούν κοινές προσαρμογές, μαζί με οδηγίες υλοποίησης, για την επέκταση της λειτουργικότητάς του ή την προσαρμογή του σε συγκεκριμένες περιπτώσεις χρήσης.
Το προεπιλεγμένο όνομα αρχείου χρησιμοποιεί μια χρονική σήμανση ( $PKG_NAME-$(date +%Y%m%d-%H%M%S).zip
). Τροποποιήστε το για να συμπεριλάβετε ονόματα περιβάλλοντος, αναγνωριστικά έργου ή σημασιολογική έκδοση:
# 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"
Συμβουλή : Βεβαιωθείτε ότι οι μορφές ημερομηνίας/ώρας αποφεύγουν τους χαρακτήρες που απαγορεύονται στα ονόματα αρχείων (π.χ. άνω και κάτω τελεία :
στα Windows).
Το σενάριο δέχεται δυναμικές διαδρομές ως φίλτρα, αλλά μπορείτε επίσης να κωδικοποιήσετε διαδρομές που χρησιμοποιούνται συχνά ή να προσθέσετε εξαιρέσεις:
# 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/*\"}]}"
Αποφύγετε τους κωδικούς πρόσβασης απλού κειμένου :
Χρησιμοποιήστε μεταβλητές περιβάλλοντος ή διαχειριστή μυστικών για την εισαγωγή διαπιστευτηρίων:
# 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)
Επιβολή επικύρωσης SSL :
Αντικαταστήστε curl -k
(μη ασφαλές) με ένα αξιόπιστο πιστοποιητικό CA:
curl --cacert /path/to/ca-bundle.crt -u "$USR":"$PWD" ...
Επεκτείνετε το σενάριο για να ενεργοποιήσετε τις μεταγενέστερες διαδικασίες μετά από μια επιτυχημένη λήψη:
# 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 {} \;
Ειδοποιήστε τις ομάδες για επιτυχία/αποτυχία μέσω Slack, email ή εργαλείων παρακολούθησης:
# 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
Η διαχείριση πακέτων AEM δεν χρειάζεται να είναι μια χειροκίνητη, επιρρεπής σε σφάλματα αγγαρεία. Με το σενάριο create-remote-aem-pkg.sh
, μπορείτε να μετατρέψετε τη δημιουργία, το φιλτράρισμα και τη διανομή πακέτων σε μια απλοποιημένη, επαναλαμβανόμενη διαδικασία. Αυτό το εργαλείο δεν αφορά μόνο την εξοικονόμηση χρόνου, αλλά και την ενεργοποίηση της συνέπειας, της αξιοπιστίας και της επεκτασιμότητας στις λειτουργίες AEM.
Ο αυτοματισμός κερδίζει : Με την εξάλειψη των επαναλαμβανόμενων αλληλεπιδράσεων GUI, το σενάριο μειώνει το ανθρώπινο σφάλμα και ελευθερώνει τις ομάδες να επικεντρωθούν σε εργασίες υψηλότερης αξίας.
Θέματα ευελιξίας : Είτε δημιουργείτε αντίγραφα ασφαλείας κρίσιμου περιεχομένου, συγχρονίζετε περιβάλλοντα ή προετοιμαζόμαστε για ενημερώσεις, το σενάριο προσαρμόζεται σε διάφορες περιπτώσεις χρήσης με ελάχιστες τροποποιήσεις.
Η ανθεκτικότητα είναι το κλειδί : Η ενσωματωμένη σύνδεση, οι έλεγχοι σφαλμάτων και τα ζητήματα ασφαλείας διασφαλίζουν ότι το σενάριο συμπεριφέρεται προβλέψιμα, ακόμη και όταν τα πράγματα πάνε στο πλάι.
Τα σπουδαία εργαλεία γεννιούνται από τις προκλήσεις του πραγματικού κόσμου. Αυτό το σενάριο είναι ένα σημείο εκκίνησης. σκεφτείτε το ως ένα θεμέλιο πάνω στο οποίο θα χτίσετε καθώς αυξάνονται οι ανάγκες της ομάδας σας. Είτε είστε μεμονωμένος προγραμματιστής είτε μέλος μιας μεγάλης ομάδας DevOps, η αυτοματοποίηση όπως αυτή αποτελεί παράδειγμα του τρόπου με τον οποίο μικρές επενδύσεις σε κώδικα μπορούν να αποφέρουν μεγάλες αποδόσεις σε παραγωγικότητα και ηρεμία.
Είστε έτοιμοι να κάνετε το επόμενο βήμα;
Σας ευχαριστούμε που παρακολουθήσατε - τώρα προχωρήστε και αυτοματοποιήστε! 🚀
#!/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
[¹] Η παράλειψη της επαλήθευσης SSL με curl -k
είναι χρήσιμη για δοκιμή, αλλά θα θέλετε κάτι πιο στιβαρό στην παραγωγή (για παράδειγμα --cacert
)!