Jenkins와 cron에서 일과 요일을 모두 지정했을 때의 거동이 다른 건

5136 단어 Jenkinscron
Jenkins의 「정기적으로 실행」과 cron으로 일과 요일을 모두 지정했을 때의 거동이 다른 건에 대해.
(Jenkins라면 「제 몇 X요일」의 지정을 할 수 있다)

어쩌면 유명한 것일지도 모릅니다만, 대충 구구한 범위에서는 언급하고 있는 것이 보이지 않았기 때문에 기사로 해 보겠습니다.
  • 수중에서는, Jenkins의 2.32.1과 2.121.3에서 확인했습니다
  • 처음 발견 된 것은 Jenkins 1.656 (2016/04/03)이었기 때문에 아마도 얼마 전부터이 사양이라고 생각됩니다.
  • 대략 Blame 한 느낌이라면, 8년 전(2010년: Hudson에서 Jenkins가 된 정도의 시기?)에는 이런 느낌이었던 것이 아닐까, 라고 생각합니다

  • cron 사양



    아는 사람은 알고 있다고 생각합니다만, cron의 서식에 있어서, 일(day of month)과 요일(day of week)을 양쪽 모두 지정하면 or 로 조건을 결합합니다.
    (다른 조건은 and 그런데!)

    예를 들어, 첫 번째 월요일에만 실행하고 싶다면 다음 설정을 수행하면 작동하지 않습니다.
    # 分 時 日 月 曜日
    0 10 1-7 * 1 {実行コマンド}
    # -> 実際は、1-7日の間の毎日と、全ての月曜日に実行される
    

    이 사양은 직관적이지 않으므로 모르면 걸립니다.
    이것을 해결하기 위해 세상에는 다양한 기사가 쓰여져 있습니다.
    예: crontab에서 번호? 요일에 작업을 수행하는 방법 - 웹 서비스에서 기업을 목표로하는 프로그래머 blog

    Jenkins의 "정기적으로 실행"사양



    Jenkins의 「정기적으로 실행」은, 작업의 실행 스케줄을 cron풍(다른 곳도 있다)의 기법으로 설정하는 기능입니다.

    그러나 여기에서는 일(day of month)과 요일(day of week)에 모두 지정하면 and 로 조건을 결합합니다. 1


    제대로, 2018/8/6(월)과 2018/9/3(월)이 각각 마지막 실행과 다음 실행으로 표시됩니다.

    네,

    Declarative Pipeline의 cron 사양은?



    Declarative Pipeline의 cron 사양도 문서 ( triggers - Pipeline Syntax )에 특별히 자세히 쓰여지지 않았지만,
    이쪽도 같은 거동을 확인했습니다.
    (단, 1번 수동 실행하지 않으면 변경이 반영되지 않는 생각이……?)

    활용 예



    이를 통해 Jenkins의 '정기 실행'에서 '매월 첫 평일에 실행'을 설정할 수 있습니다.
    
    # 基本的に毎月1日の10時台に実行するが、土日や祝日の場合は次の平日にずらす。
    # 祝日に関しては、現時点でわかっているもののみ対応 ※通常は翌年の祝日が確定するのは2月
    ## 1月・5月・11月以外(1日が土日→2日か3日が月曜日で最初の平日)
    H 10 1 2-4,6-10,12 1-5
    H 10 2,3 2-4,6-10,12 1
    ## 1月の三賀日対応(実質4日が月初)
    H 10 4 1 1-5
    H 10 5,6 1 1
    ## 例年の5月のGW対応 ※2019年は年号切り替えで例外
    ### 5月1日が何曜日かで場合分け
    ### - 1日が月-金→1日でok
    ### - 1日が日曜日→2日が月曜日で最初の平日
    ### - 1日が土曜日→2,3,4,5も休みで6日が木曜日で最初の平日
    H 10 1 5 1-5
    H 10 2 5 1
    H 10 6 5 4
    ## 11月の文化の日対応(1日が日曜日→2日が月曜日、1日が土曜日→3日が月曜だが祝日で4日が最初の平日)
    H 10 1 11 1-5
    H 10 2 11 1
    H 10 4 11 2
    
    
    ## 2019年5月限定。年号切り替えで5/1が祝日になった場合は、4/30と5/2も祝日になるので、7日が最初の平日で確定
    H 10 7 5 1-5
    

    덤: Jenkins의 "정기적으로 실행"주위 구현?



    움직인다고는 해도, (?) 아이콘으로 나오는 설명에도 실려 있지 않고, 우연히 아직 하거나 하면 곤란하지,라고 생각해 GitHub - jenkinsci/jenkins 의 리포지토리를 조사해 보았습니다.
    java.hudson.scheduler.CronTab 가 수상할 것 같습니다.


    CronTab.java # L359-360
    if (f.redoAdjustmentIfModified)
        continue OUTER; // when we modify DAY_OF_MONTH and DAY_OF_WEEK, do it all over from the top
    

    이것은, 인수로 주어진 시간으로부터 봐 다음에 조건을 채우는 시간을 계산한다 public Calendar ceil(Calendar cal) 내의 단편으로,
    여기에 도달하는 것은, 현재 체크하고 있는 필드(월/일/요일/시/분)의 값에 대해, while 개시시점의 값과 조건을 만족하는 값이 다른 경우입니다.
    댓글에 쓰여진 것처럼 f.redoAdjustmentIfModifiedf이 경우 DAY_OF_MONTH 의 외부에서 다시 시작됩니다.

    이것에 의해, 일과 요일의 양쪽 모두가 조건을 채울 때까지, DAY_OF_WEEK (을)를 앞으로 진행해 계속하게 됩니다.
    true 라는 필드를 마련하고,
    일( while )과 요일( Calendar )의 경우에만 redoAdjustmentIfModifiedDAY_OF_MONTH 라는 조건을 사용하고 있는 이상,
    이 사양은 의도적인 것으로 보입니다.
    ("이 부분이 '정기적으로 실행'에서 사용되는 코드이다"라는 추측이 맞다면, 의 이야기입니다만)

    그럼 좋은 Jenkins 생활을



    잘 보면 이미지중의 입력의 DAY_OF_WEEK 의 반대입니다…

    좋은 웹페이지 즐겨찾기