Jenkinsのテンプレートとなるジョブを作っておいて、そこから必要な部分だけを変更して新しいジョブを作成する手順です。
ジョブが1つだけならそれほど手間ではありませんが、似たようなジョブを大量に作る場合に楽をしたくて調べました。
全体的な流れとしては以下の通りです。
- APIトークンを取得しておく
- コピー元ジョブの一覧を取得
- APIトークンを使って、それぞれのジョブ単位でジョブのコピーを実施
- それぞれのコピー後ジョブの単位でconfigを一旦取得
- configを適当に書き換えてジョブ設定を更新
事前準備 : APIトークンを調べる
大抵の場合はJenkinsは認証を必要とする場合が多いと思いますが、その場合はこのAPIトークンを調べておく必要があります。
コピーしたいジョブの一覧を取得
例えば、Template
という名前のViewからコピー元のジョブ名を取得する場合。
(localhost:8080
でjenkinsが起動している場合とします)
結果をjson形式で取得し、jq
によりパースしてジョブ名だけを取得しています。
curl -s "http://localhost:8080/view/Template/api/json?tree=jobs\[name\]" | ./jq -r ".jobs[] | .name"
testjob
ここでは、Template View配下に testjob
という1つだけが存在しているため、1件しか取得していませんが、複数のジョブをまとめてコピーする場合は同じViewにまとめておくとやりやすいでしょう。
ジョブをコピー
先ほどのAPIトークンを利用して、ジョブをコピーします。注意点としては、ここで利用するbasic認証のID/Passwordは、決して Jenkins画面にログインするときのID/Passwordではないということです。
curl --user 'testuser:c7e7e1260784d54f6f512231941aece5' -H 'Content-type: application/xml' -XPOST "http://localhost:8080/createItem?name=new-testjob&mode=copy&from=testjob"
ここでは、先ほど取得した testjob
というジョブから、新しく new-testjob
というジョブを作成しています。
ヘッダとしてContent-type: application/xml
を指定しないと、以下のようなエラーが出るケースもあるようですが、条件は不明です。(手元の環境では指定しなくても出なかった)
HTTP Status 400 - No Content-Type header set
この時点で、ジョブは全く同じ状態でコピーされています。
ジョブの詳細設定を取得
このままでは全く同じジョブが生成されただけなので、必要な書き換えを行います。
一旦、ジョブの設定を手元に取得します。ここでは、config.xml
という名前で保存しています。
curl -so config.xml --user 'testuser:c7e7e1260784d54f6f512231941aece5' http://localhost:8080/job/new-testjob/config.xml
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></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 "this is testjob"</command>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
this is testjob
と表示するだけのジョブです。
ジョブの設定を変更・反映
この部分を書き換えて、新しいジョブになるようにします。
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></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 "this is new-testjob!"</command>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
this is new-testjob!
と表示するようにしました。ここだけ変更しています。
実際のケースでは、書き換え対象となるような文字列のパターンを決めて、sed
などで一気に変更すると良いと思われます。
新しいconfigで反映します。
curl -XPOST --data-binary @config.xml --user 'testuser:c7e7e1260784d54f6f512231941aece5' http://localhost:8080/job/new-testjob/config.xml
--data-binary
ではなく-d
とか--data
オプションでPOSTしてしまうと、改行が崩れてシェルスクリプト部分は動かなくなるので注意してください。
この時点で、以下のようにジョブが変更されています。
今回の例では1つのジョブしか変更していないのであまり旨味はないですが、この順序に従って
- 大量のテンプレートジョブを取得
- ジョブ単位に新ジョブ名を指定してコピー生成
- ジョブ単位に設定を書き換えて反映
ということをシェルスクリプトなどで行えばかなり使いやすくなりそうです。
APIで何ができるのか
今回のケースでは、Jenkins APIのごく一部の機能を使っています。
他にどんな機能があるのかはReferenceのリンクを参照することでも分かりますが、画面上のJenkinsのURLの末尾にapi/
をつけてアクセスするだけでも、大体のことは分かるので便利です。
例えば、ジョブで何ができるのかは
http://localhost:8080/job/new-testjob/api/
で分かりますし、viewで何ができるのかは
http://localhost:8080/view/Template/api/
で分かります。要は、その画面でGUI操作によりできることが、api
をつければできるようなイメージです。