手持ちのJenkinsをいくつかアップデートすることがあったので備忘がてらまとめておきます。*1
Jenkins 1系 -> 2系などの大幅アップデートに限らず、プラグインのアップデートでも使えると思います。
事前にやるべきこと
アップデート後に何か問題があって戻さざるを得ないこともありうるので、すぐに元に戻せる状態にしておきます。*2
Jenkins本体のバックアップ
jenkins.warをそのまま使ってる場合
jenkins.warをどこかにバックアップするか、アップデート前のバージョンをどこかにメモっておいてください。
jenkins.warの過去バージョンは http://mirrors.jenkins-ci.org/war/ からダウンロードできます。
yumやaptを使ってる場合
yum install
や apt-get install
では最新版しかインストールされないので、ロールバックも考慮するとパッケージ指定でインストールした方がいいと思います。
ちなみにパッケージからインストールしておくとjenkinsユーザ作ってくれたりデーモン化までやってくれるのでおすすめです
自分の場合こういうitamaeレシピ書いてます(Debian版)
jenkins.rb
execute "wget http://pkg.jenkins-ci.org/debian/binary/jenkins_#{node[:jenkins][:version]}_all.deb -P #{node[:jenkins][:deb_dir]} && dpkg -i #{node[:jenkins][:deb_dir]}/jenkins_#{node[:jenkins][:version]}_all.deb" do not_if "ls #{node[:jenkins][:deb_dir]}/jenkins_#{node[:jenkins][:version]}_all.deb" end
node.yml
jenkins: version: "2.8" deb_dir: "/data/backup/jenkins_deb"
コマンドに書き下すとこんな感じ
cd /path/to/backup_dir wget http://pkg.jenkins-ci.org/debian/binary/jenkins_2.8_all.deb dpkg -i jenkins_2.8_all.deb
この場合でも戻す場合は過去バージョンのrpmやdebでインストールしなおすだけです
最初ymlでバージョン変えてitamae実行したのですが、 /etc/default/jenkins
で JENKINS_HOME
やJVMのメモリ割り当てで編集してた関係で差分適用するかどうかの入力待ち*3でずっと止まってたので、もしかしたら手動の方がいいかもしれないです。
プラグインや設定一式のバックアップ
手前味噌ですが jenkins-backup-script を使うのがいいです。設定ファイルやプラグイン一式全部バックアップされます。
こういう風にジョブ登録しておいて1日1回夜中に定期実行したり、Jenkins本体やプラグインのアップデート前に手動実行したりしています。
一応tarは外部のバックアップサーバにも転送してるので、突然Jenkinsマシンが死んでもすぐに復旧できる状態にはなってます
Jenkins本体はそうでもないのですが、プラグインは稀に下位互換性をぶっ壊すような変更が入るのでバックアップは必須かと *4
アップデート手順
warなりdebなりrpmなり最新版でインストールし直すだけ。
確認方法
主要なジョブをいくつか手動実行してみる
戻す方法
- jenkins.warを使ってる場合は過去バージョンのを置き直すだけ
- rpmやdeb使ってる場合は過去バージョンでインストールしなおすだけ
- jenkins-backup-scriptは下記のようなコマンドで設定ファイルを上書きするだけ
cd /path/to/backup_dir tar xzvf backup.tar.gz sudo cp -R jenkins-backup/* /path/to/jenkins/ sudo chown jenkins:jenkins -R /path/to/jenkins/
アップデート時にハマったこと
Branches to build で変数が取れなくなった
jenkins-gitlab-merge-request-builder-plugin を使ってた時にビルド対象のブランチ名がとれなくなったハマりました
設定
正常な時のログ
20:11:03 > git rev-parse refs/remotes/origin/feature/remove_alias_method_chain^{commit} # timeout=10 20:11:03 > git rev-parse refs/remotes/origin/refs/remotes/origin/feature/remove_alias_method_chain^{commit} # timeout=10 20:11:03 Checking out Revision 4e9593d92e293c5ca99eaa6de3b92b973cb1716a (refs/remotes/origin/feature/remove_alias_method_chain) 20:11:03 > git config core.sparsecheckout # timeout=10 20:11:03 > git checkout -f 4e9593d92e293c5ca99eaa6de3b92b973cb1716a
エラー時のログ
19:09:00 Gitlab Merge Request #9222 : xxxx/my_xxxx/feature/update_ruby => master 19:09:01 > git rev-parse refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10 19:09:01 > git rev-parse refs/remotes/origin/refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10 19:09:01 > git rev-parse refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10 19:09:01 ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.
GitLabのwebhookからJenkinsにブランチ名は渡されてるっぽいのだけど、 git rev-parse
する時にはブランチ名がとれなくなってるような挙動。
「明示的に設定したパラメータしか変数としてバインドされなくなったのかなー」と思って「ビルドのパラメータ化」のところに gitlabSourceBranch
を定義したらビルドが動くようになりました。*5
所感
- 1系 -> 2系のアップデートで身構えてたけど、アップデート自体は驚くほどサクッとできました
- パイプラインやJob DSLに全部置き換えるとかだと大変そうだけど、既存のジョブをそのまま移行する分には問題なさそうです
- とはいえ保険が多いにこしたことはないのでバックアップはしておいた方がいいです
まとめ
- 何かあった時のロールバック手順は必ず用意しておく(石橋を叩いて渡るくらいが丁度いい)
- Jenkins 2系はいいぞ
ブコメレス
JenkinsCIををrpmでアップデートすると、$JENKINS_HOMEをchown -Rする糞コマンド入っているので、workspace/以下を綺麗にしておくかexport JENKINS_INSTALL_SKIP_CHOWN=trueしておかないと何時間もupdate終わらんとかになる
ナルホディウス。debだと時間かかっていなかったのでプラットフォームごとに違うのですね。(自分のところのJENKINS_HOME配下もファイル数カオスなので一瞬でchown -Rが終わるとも思えない)