プラグインを再起動無しでインストールする

今日からJenkins アドベントカレンダー企画が始まります。今日から25日間、コミュニティの皆さんで一日一人一つの記事を順番に書いていくという企画です。そのトップバッターになるこの記事では、今週末登場予定のJenkins 1.442での新機能、「再起動しないでプラグインをインストール」を紹介しようと思います。


後述するように内部的には色々大変なことがあるのですが、ユーザーの方には簡単に使えます。まず、今まで通りにプラグインの管理から一覧を表示し、インストールするプラグインを選びます。画面最下部にスクロールすると「Install without restart」ボタンと「Download now and install after restart」ボタンの2つが出ます。前者が再起動無しでインストールするモードで、後者が今までのように再起動後にインストールをするモードです。暫くしたら後者のボタンは削ってしまってもいいかなと思っています。





左のボタンをクリックするとダウンロード&インストールが始まります。





インストールが完了すると、今までなら再起動するところなのですが、今回からは「Go back to the top page」をクリックしてさっさとトップページに戻ってしまって構いません。インストールしたばかりのプラグインがもう使えるようになっているはずです。簡単でしたね。

アップデートは?

残念ながら、内部的な設計の制約上、この方式を使って既にインストールされたプラグインをアップデートするのは難しいと思います。詳細は内部的な話のところで説明します。

アンインストールは?

同様に、正確な意味でのアンインストールを実現するのも難しいと思います。ですが、ある種の限定的なものなら不可能ではないかもしれないと思っています。既にプラグインが使われているジョブの設定には再起動まで影響を及ぼさないけれども、設定画面には表示されなくなる、みたいな感じで。

内部的な話

歴史を遡ること約400リリース前、1.44でプラグインがサポートされた時からずっと、Jenkinsではプラグインのインストール後には再起動が必要でした。Jenkinsはスタートアップ時にプラグインに対して色々な計算をして、プラグインに関するimmutableなデータ構造を作っていくわけです。このあたりの処理がそもそもは逐次的に書かれていたので、これを動的に実行できるようにするのは結構面倒くさい仕事でした。アップデートセンターを書くとか他にプライオリティの高い作業があって、動的インストールまではなかなか手が回らなかったわけです。


その後Jenkinsの起動速度の改善のために、Jenkinsの初期化を細かいタスクに分解し、その依存関係をトポロジカルソートして並列に実行...みたいな機能が入ってから、追加の初期化タスクを実行するのが現実的になってきました。その時実装しておけばよかったのですが、その後、Guiceを使って内部的にコンポーネントを結線するようになると、動的にコンポーネントを追加するのがまた難しくなってしまったのです。現在のバージョンでは、Guiceのchild injectorを使って追加されたプラグインから貢献された実装をホストするようにしています。これでほとんどのプラグインはごまかされてくれています。


では、なぜアップデートは難しいのでしょうか?Jenkinsの設計では、通常のデータベースアプリケーションとは異なり、モデルオブジェクトはメモリ内に長期間とどまるように設計されているからです。このデザイン自体は自分は気に入っているのですが、欠点の一つとして、動的に定義を変更するのが難しいことになってしまうというわけです。Javaではメモリ上のインスタンスをリロードすることはできないので。なので、これはHAみたいな方向で解決するのがいいのかなと思っています。

まとめ

そんなわけで、内部的には結構頑張ったので、ぜひこれを使って、どんどんプラグインを試してやってください。