SSH cattura il codice di uscita dei comandi ssh remoti
Ho scritto uno script, che fa parte di una pipeline gitlab ci, per distribuire il codice tramite ssh a un server remoto. Lo script si trova localmente e inoltrato al server remoto. Finora funziona bene, ma sfortunatamente c'è un problema quando si verificano errori. In questo momento il comando migrate termina, perché non ci sono credenziali db salvate. Il comando termina con un codice diverso da zero, ma la pipeline riesce ancora, il che è fuorviante e mi costringe ad accedere al server remoto e controllare lì i log.
Come posso inoltrare i codici di uscita dal computer remoto a quello locale, in modo che in questo caso anche il lavoro gitlab-ci fallisca?
Mi sono imbattuto in queste domande e risposte, ma dato che sono abbastanza nuovo a bash non capisco la soluzione. La rimozione set -e
non ha aiutato.
- bash - Cattura il codice di uscita dal comando ssh remoto
- Codice di uscita del comando remoto SSH
La parte di configurazione di gitlab-ci ha questo aspetto:
script:
# Change directory to the packaged app (not the repo).
- cd /var/www/html
# Copy over the code.
- |
rsync \
-azc \
--exclude-from="$RSYNC_EXCLUDES" \
"$(pwd)/" "$SSH_CONNECTION:$BASE_DIR/releases/$CI_COMMIT_SHA/"
# Run the post deployment script.
- ssh -T "$SSH_CONNECTION" "bash -s" < ./.deploy/post_deploy.sh "$BASE_DIR" "$CI_COMMIT_SHA"
Lo script post_deploy.sh ha questo aspetto:
#!/bin/bash
# Terminate execution if any command fails
set -e
########################
# Program arguments:
########################
## The base directory
BASE_DIR=$1
# The commit sha that is being deployed.
COMMIT_SHA=$2
################
# Variables:
################
# The path to the releases directory
RELEASE_DIR=$BASE_DIR/releases/$COMMIT_SHA
# The path to the shared directory.
SHARED_DIR=$BASE_DIR/shared
###############
# Deployment:
###############
echo "Symlink $SHARED_DIR/.env to $RELEASE_DIR/.env."
rm -rf "$RELEASE_DIR/.env" && ln -sf "$SHARED_DIR/.env" "$RELEASE_DIR/.env."
echo "Symlink $SHARED_DIR/storage to $RELEASE_DIR."
rm -rf "$RELEASE_DIR/storage" && ln -sf "$SHARED_DIR/storage" "$RELEASE_DIR"
echo "Fixing permissions."
find "$RELEASE_DIR" -type f -exec chmod 644 {} \;
find "$RELEASE_DIR" -type d -exec chmod 755 {} \;
echo "Running custom scripts."
php "$RELEASE_DIR" artisan storage:link
php "$RELEASE_DIR" artisan migrate --no-interaction --force
php "$RELEASE_DIR" artisan cache:clear
php "$RELEASE_DIR" artisan config:clear
php "$RELEASE_DIR" artisan config:cache
php "$RELEASE_DIR" artisan view:cache
echo "Releasing the new version (symlink current/)."
ln -nsf "$RELEASE_DIR/" "$BASE_DIR/current"
echo "Remove all releases older than a day."
find "$BASE_DIR/releases" -maxdepth 1 -mindepth 1 -mtime +1 -exec rm -r {} \;
Risposte
dovrebbe funzionare se ottieni davvero un codice diverso da zero. Ho provato sulle mie macchine
$ ssh user@host 'bash -s' < script.sh
remote script execute with exit 1
$ echo $?
1
Gitlab deve fallire un lavoro se almeno una riga di script restituisce un valore diverso da zero.
Per quanto ho capito, tranne che hai detto di questa linea
php "$RELEASE_DIR" artisan migrate --no-interaction --force
Non conosco questo strumento, ma spesso i flag --force
dovrebbero eseguire comandi senza codice zero. Si prega di controllare le bandiere.
Se non funziona, prova a mettere
if [[ $? != 0 ]]; then
exit 1
fi
dopo la riga conmigrate
Bene. Sembra che questo sia stato un errore da parte mia e tutto funziona correttamente. Non stavo chiamando correttamente uno dei comandi:
php "$RELEASE_DIR" artisan migrate --no-interaction --force
Questo lo risolve:
php "$RELEASE_DIR/artisan" migrate --no-interaction --force