はじめに
こんにちはSREエンジニアのMakiです。
この記事ではJenkinsのジョブを無効化するやり方を紹介します。
Jenkinsのジョブを一時的に動かないようにさせたいということってありませんか?定期実行しているジョブを動かないようにさせるなどのニーズは時々あるのではないかと思います。この記事ではそのような場合への対処方法をまとめていきます。
プロジェクトの無効化
では、さっそくジョブの無効化をするやり方を見ていきます。
- Jenkinsでジョブを実行できなくしたい場合は
プロジェクトの無効化
をしましょう。
プロジェクトを無効化すると パラメータ付きビルド
や Rebuild
といったジョブ実行にかかわる捜査が行えなくなります。
- 再び ジョブを使えるようにする場合は
有効化
をしましょう。
どんなときに無効化するの?
ではどんなの時にジョブの無効化を制御する必要があるのか?
- Jenkinsジョブをほかの環境に移行するときに実行されないように制御しておきたい。
- 承認されていないジョブが実行されないようにしたい。
- 失敗したジョブの原因調査が終わるまで実行させないようにしたい。
こういったことが考えられますね。
一定期間更新がなかったジョブを一括で無効化したい。
以下のようなスクリプトを作って一定期間更新がなかったジョブは一括で無効化するといった運用も可能です。
Python にもJenkinsのライブラリがあり、それを使って実装したものが下記の内容です。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import sys
import datetime
from argparse import ArgumentParser
import jenkins
BUILDABLE = 'buildable'
FULLNAME = 'fullname'
JOB_CONFIG_HISTORY = 'jobConfigHistory'
LAST_UPDATE_CONFIG = 'jobLastUpdateConfig'
DATE = 'date'
NONE = 'none'
def login(args):
server = jenkins.Jenkins(args.jenkins_url, username=args.jenkins_username, password=args.jenkins_password)
return server
def getDisableTargetJobInfos(server,args):
_disable_target_job_infos = []
jobs = server.get_all_jobs()
for job in jobs :
if not job[FULLNAME].startswith(args.disable_job_prefix):
continue
if server.is_folder(job[FULLNAME]) :
continue
job_info = server.get_job_info(job[FULLNAME])
if not (BUILDABLE in job_info and job_info[BUILDABLE]) :
continue
_config_history_info = getJobConfigHistry(server, job[FULLNAME])
# if job config history is not empty add last update config history info
if _config_history_info[JOB_CONFIG_HISTORY] :
job_info[LAST_UPDATE_CONFIG] = _config_history_info[JOB_CONFIG_HISTORY][0]
else :
job_info[LAST_UPDATE_CONFIG] = {}
job_info[LAST_UPDATE_CONFIG][DATE] = NONE
if isDisableTargetJob(job_info, args):
_disable_target_job_infos.append(job_info)
print("Hit : " + job[FULLNAME] +" LastUpdated:" + job_info[LAST_UPDATE_CONFIG][DATE])
return _disable_target_job_infos
def getJobConfigHistry(server,name):
folder_url, short_name = server._get_job_folder(name)
_config_history_url = folder_url + 'job/' + short_name + '/' + JOB_CONFIG_HISTORY + '/'
_config_history_info = server.get_info(_config_history_url)
return _config_history_info
def isDisableTargetJob(job_info,args):
_isDisableTarget = False
if job_info[LAST_UPDATE_CONFIG][DATE] == NONE or isNotUpdatedRecentryJob(job_info[LAST_UPDATE_CONFIG][DATE], args.days_ago):
_isDisableTarget = True
return _isDisableTarget
def isNotUpdatedRecentryJob(update_date,days_ago):
_isNotUpdatedRecentry = False
_days_ago = datetime.datetime.today() - datetime.timedelta(days=days_ago)
datetime_formatted = datetime.datetime.strptime(update_date, "%Y-%m-%d_%H-%M-%S")
if(datetime_formatted < _days_ago):
_isNotUpdatedRecentry = True
return _isNotUpdatedRecentry
def disableJobs(server,job_infos,args):
_FULL_NAME = 'fullName'
for job_info in job_infos :
server.disable_job(job_info[_FULL_NAME])
print("Disabled : " + job_info[_FULL_NAME] +" LastUpdated:" + job_info[LAST_UPDATE_CONFIG][DATE])
def writeJson(job_infos,outfile):
with open(outfile, 'w') as jsonfile:
json.dump(job_infos, jsonfile)
def parse_args():
argparser = ArgumentParser()
argparser.add_argument('-j', '--jenkins-url', type=str, default="",required = True, help='input $JENKINS_URL')
argparser.add_argument('-u', '--jenkins-username', type=str, default="", required=True, help='input jenkins username')
argparser.add_argument('-p', '--jenkins-password', type=str, default="", required=True, help='input jenkins password')
argparser.add_argument('-a', '--days-ago', type=int, default="14", required=False, help='input days before get target')
argparser.add_argument('-o', '--output-json', type=str, default="jenkins_job_infos.json", required=False, help='input disable target job prefix')
argparser.add_argument('-d', '--disable-job-prefix', type=str, default="operation-working/", required=False, help='input disable target job prefix')
argparser.add_argument('-s', '--skip-disable', action='store_true', required=False, help = 'skip disable job')
return argparser.parse_args()
def main():
args = parse_args()
server = login(args)
print('--- start detect disable target jobs ---')
disable_target_job_infos = getDisableTargetJobInfos(server,args)
writeJson(disable_target_job_infos, args.output_json)
print('--- finish detect disable target jobs ---')
if not args.skip_disable :
print('--- start disable jobs ---')
disableJobs(server,disable_target_job_infos,args)
print('--- finish disable jobs ---')
if __name__ == '__main__':
sys.exit(main())
実行コマンド
python disable-not-recentry-updated-jobs.py -j ${JENKINS_URL} -u ${JENKINS_USER} -p ${JENKINS_PASS} -a ${BEFORE_DAYS_AGO} -o ${OLD_JENKINS_JOBS_JSON} -d ${DISABLE_TARGET_JOB_PREFIX}
※実行には以下のライブラリが必要です。
- python-jenkins
- argparse
オプションについて
-j : jenkinsのURLを指定します。
-u : jenkinsのログインユーザーを指定します。
-p : jenkinsのログインパスワードを指定します。
-a : 何日より古いものを対象にするかを数字で指定します。
-o : 対象のジョブを書き込むjsonの名前を指定します。
-d : 無効化の対象とするジョブのプレフィックスを指定します。
-s : 無効化をしないで対象となるジョブの確認のみを行う際に指定するオプションです。
サンプルコマンド
python disable-not-recentry-updated-jobs.py -j http://my.jenkins.host:8080/ -u hoge -p fuga -a 30 -o old_jenkins_jobs.json -d work/
このコマンドの例だと30日より古いジョブでプレフィックスが work/
となっているジョブを一括で無効化します。
無効化する前に確認したいという場合は -s
オプションをつけると先に確認が行えます。
まとめ
- ジョブの無効化は
プロジェクトの無効化
を操作すると行えます。 - 環境移行やトラブル調査の時に無効化をするといった利用が考えられます。
- 一括でジョブを無効化したいときはスクリプトを作ると便利です。
おすすめ書籍
[改訂第3版]Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)
初めてJenkinsを学ぶ方におすすめです。
Jenkins
Jenkinsでできることについてもう少し詳しく学びたい方におすすめです。
コメント