SSH-Capture-Exit-Code von Remote-SSH-Befehlen

Aug 24 2020

Ich habe ein Skript geschrieben, das Teil einer gitlab ci-Pipeline ist, um Code über ssh auf einem Remote-Server bereitzustellen. Das Skript befindet sich lokal und wird an den Remote-Server weitergeleitet. Das funktioniert soweit in Ordnung, aber leider gibt es ein Problem, wenn Fehler auftreten. Im Moment wird der Migrationsbefehl beendet, da keine Datenbankanmeldeinformationen gespeichert sind. Der Befehl wird mit einem Code ungleich Null beendet, aber die Pipeline ist weiterhin erfolgreich, was irreführend ist, und zwingt mich, mich beim Remote-Server anzumelden und die Protokolle dort zu überprüfen.

Wie kann ich die Exit-Codes von der Fernbedienung an den lokalen Computer weiterleiten, damit in diesem Fall auch der gitlab-ci-Job fehlschlägt?

Ich bin auf diese Fragen und Antworten gestoßen, aber da ich ziemlich neu im Bash bin, verstehe ich die Lösung nicht. Entfernen set -ehat nicht geholfen.

  • bash - Erfasst den Exit-Code des Remote-SSH-Befehls
  • SSH-Befehl zum Beenden des Remote-Befehls

Der gitlab-ci-Konfigurationsteil sieht folgendermaßen aus:

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"

Das Skript post_deploy.sh sieht folgendermaßen aus:

#!/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 {} \;

Antworten

1 Novikov Aug 27 2020 at 04:42

Es sollte funktionieren, wenn Sie wirklich Code ungleich Null erhalten. Ich habe auf meinen Maschinen getestet

$ ssh user@host 'bash -s' < script.sh remote script execute with exit 1 $ echo $?
1

Gitlab muss einen Job fehlschlagen, wenn mindestens eine Skriptzeile ungleich Null zurückgibt.

Soweit ich Sie verstehe, außer Sie haben über diese Zeile gesagt

php "$RELEASE_DIR" artisan migrate --no-interaction --force

Ich weiß nichts über dieses Tool, aber oft --forcesollten Flags Befehle ohne Nullcode ausführen. Bitte überprüfen Sie die Flaggen.

Wenn das nicht funktioniert, versuchen Sie es mit Putten

if [[ $? != 0 ]]; then
  exit 1
fi

nach Zeile mit migrate

1 Tom Aug 27 2020 at 15:10

Okay. Es scheint, dass dies ein Fehler für mich war und alles richtig funktioniert. Ich habe einen der Befehle nicht richtig aufgerufen:

php "$RELEASE_DIR" artisan migrate --no-interaction --force

Dies behebt es:

php "$RELEASE_DIR/artisan" migrate --no-interaction --force