はじめに
Jenkins は、コントローラーとジョブのほとんどの設定を JENKINS_HOME 配下のファイルとして保存しています。実用的なバックアップ計画には、ジョブとコントローラーの設定を定義するファイルを確実に取得することが求められます。また、リストア計画では、リストアしたファイルを Jenkins が正しく読み込めることを証明する必要があります。
この実験では、サンプルジョブを作成し、その config.xml をバックアップしてジョブを削除した後、tar アーカイブからリストアし、Jenkins をリロードしてジョブが正常に動作することを確認します。
バックアップ対象となる Jenkins 状態の作成
このステップでは、backup-restore-demo という名前のフリースタイルジョブを作成します。これにより、バックアップとリストアの対象となる実際の Jenkins 設定ファイルを用意します。
ジョブ設定を作成します:
cat > /home/labex/project/backup-restore-demo-config.xml <<'XML'
<?xml version='1.1' encoding='UTF-8'?>
<project>
<actions/>
<description>Job used to practice Jenkins backup and restore.</description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>echo "Restored Jenkins job is running"</command>
<configuredLocalRules/>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
XML
ジョブを Jenkins にコピーし、リロードします:
docker exec -u root jenkins mkdir -p /var/jenkins_home/jobs/backup-restore-demo
docker cp /home/labex/project/backup-restore-demo-config.xml jenkins:/var/jenkins_home/jobs/backup-restore-demo/config.xml
docker exec -u root jenkins chown -R jenkins:jenkins /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
Jenkins がジョブを読み込めることを確認します:
curl -fsS http://localhost:8080/job/backup-restore-demo/api/json | grep -o '"name":"backup-restore-demo"'
ジョブ設定のバックアップ
このステップでは、Jenkins コンテナからジョブ設定をコピーし、アーカイブします。バックアップには jobs/backup-restore-demo/config.xml という相対パスを保持させることで、リストア時のパスを明確にします。
バックアップ用の作業ディレクトリを作成し、ジョブ設定をコピーします:
mkdir -p /home/labex/project/jenkins-backup-work/jobs/backup-restore-demo
docker cp jenkins:/var/jenkins_home/jobs/backup-restore-demo/config.xml /home/labex/project/jenkins-backup-work/jobs/backup-restore-demo/config.xml
圧縮された tar アーカイブを作成します:
cd /home/labex/project/jenkins-backup-work
tar -czf /home/labex/project/backup-restore-demo.tar.gz jobs/backup-restore-demo/config.xml
アーカイブの内容を一覧表示します:
tar -tzf /home/labex/project/backup-restore-demo.tar.gz
出力には以下が含まれているはずです:
jobs/backup-restore-demo/config.xml
データ損失をシミュレートするためのジョブ削除
このステップでは、Jenkins からジョブを削除します。これは誤操作による削除をシミュレートするもので、明確なリストア対象を作成します。
ジョブディレクトリを削除し、Jenkins をリロードします:
docker exec -u root jenkins rm -rf /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
ジョブにアクセスできないことを確認します。以下のコマンドでは、このチェックのために 404 レスポンスを成功とみなします:
if curl -fsS http://localhost:8080/job/backup-restore-demo/api/json >/dev/null 2>&1; then
echo "Job still exists"
exit 1
else
echo "Job is absent and ready to restore"
fi
バックアップからのジョブのリストア
このステップでは、バックアップアーカイブを展開し、リストアされたジョブディレクトリを Jenkins に戻して、コントローラーをリロードします。
アーカイブをリストア用ディレクトリに展開します:
rm -rf /home/labex/project/restore-work
mkdir -p /home/labex/project/restore-work
tar -xzf /home/labex/project/backup-restore-demo.tar.gz -C /home/labex/project/restore-work
リストアされたジョブディレクトリを Jenkins にコピーし、リロードします:
docker cp /home/labex/project/restore-work/jobs/backup-restore-demo jenkins:/var/jenkins_home/jobs/backup-restore-demo
docker exec -u root jenkins chown -R jenkins:jenkins /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
Jenkins がリストアされたジョブを読み込めることを確認します:
curl -fsS http://localhost:8080/job/backup-restore-demo/api/json | grep -o '"name":"backup-restore-demo"'
リストアされたジョブの実行
このステップでは、リストアされたジョブを実行します。リストアは、Jenkins が設定を読み込み、実行できて初めて意味を成します。
ビルドをトリガーします。Jenkins は最初にキューアイテムを返すため、レスポンスヘッダーを保存し、Location ヘッダーを読み取ります:
CRUMB=$(curl -fsS -c /tmp/jenkins-backup-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -D /tmp/backup-restore-build.headers -o /dev/null -b /tmp/jenkins-backup-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/backup-restore-demo/build
QUEUE_URL=$(awk 'tolower($1)=="location:" {print $2}' /tmp/backup-restore-build.headers | tr -d '\r')
echo "Jenkins queued the restored job at ${QUEUE_URL}"
キューに入れられたアイテムが実際のビルドになるまで待ちます。Jenkins は最終的なビルド番号を割り当てる前に、数秒間の静止期間(quiet period)を設けることがあります:
until BUILD_NUMBER=$(python3 - "$QUEUE_URL" <<'PY'
import json
import sys
import urllib.request
with urllib.request.urlopen(sys.argv[1] + 'api/json') as response:
data = json.load(response)
executable = data.get('executable')
if not executable:
raise SystemExit(1)
print(executable['number'])
PY
); do
echo "Waiting for Jenkins to assign a build number..."
sleep 3
done
echo "The restored job is running as build #${BUILD_NUMBER}"
ビルドが完了するまで待ちます:
until curl -fsS "http://localhost:8080/job/backup-restore-demo/${BUILD_NUMBER}/api/json" >/tmp/backup-restore-build.json 2>/dev/null && grep -q '"building":false' /tmp/backup-restore-build.json; do
echo "Waiting for restored job build #${BUILD_NUMBER}..."
sleep 3
done
コンソール出力を確認します:
curl -fsS "http://localhost:8080/job/backup-restore-demo/${BUILD_NUMBER}/consoleText" | grep -E 'Restored Jenkins job is running|Finished: SUCCESS'
デスクトップインターフェースから Firefox を開き、ターミナルに表示されたビルド番号のコンソール URL(例:http://localhost:8080/job/backup-restore-demo/2/console)にアクセスしてください。コンソールページには、リストアされたジョブが正常に実行されたことが表示されているはずです。

まとめ
バックアップ対象となる Jenkins 設定を作成し、ジョブの config.xml をアーカイブし、ジョブを削除し、バックアップアーカイブからリストアし、Jenkins をリロードして、ビルドを実行することでリストアされたジョブを検証しました。