[05] declarative pipeline の使用例 -- 複数ノードでビルドをする（分散ビルド）


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/52a393aee1ba57999196|


## 概要

最終的には Slave 8台を同時に実行し、かつ、終了待合せをする.
実施する処理は簡単のために sleep のみとする.
なお、使用した Jenkins バージョンは Jenkins 2.314 である.

[1. まずは Slave 3台を同時実行する (処理内容は sleep するのみ)](#1-まずは-slave-3台を同時実行する-処理内容は-sleep-するのみ)
[2. 上記 1 を Map を使って簡潔に記す](#2-上記-1-を-map-を使って簡潔に記す)
[3. 記載予定]()



## 環境

下記で構築した Master(1台) - Slave(8台) [SSH通信] を使って Pipeline を書いてみる. 
(OS は Linux である)

・[[シリーズ] docker-compose を使って同一物理マシン上に Jenkins Master(docker) - Slave(docker) [SSH通信]を構築する](https://qiita.com/robozushi10/items/80bfd9934500b458b831)


## コード

### 1. まずは Slave 3台を同時実行する (処理内容は sleep するのみ)

ここでは slave001, slave002, slave003 の 3台を同時実行する.
そして次のように sleep をする.
・slave001 は 13秒間の sleep
・slave002 は 1秒間の sleep
・slave003 は 9秒間の sleep

そして、3台全てが終了したら、ジョブを終了させる.

```groovy
// デバッグのための変数
def MESG = 'DONE ... '

pipeline {
    agent any
    stages {
        stage('並列実行') {
            steps { 
                script {
                    parallel(
                        [
                            'slave001':{
                                node('slave001'){
                                    stage('slave001 での実行'){
                                        script {
                                            sh "sleep 13"
                                            MESG += " ${env.NODE_NAME} "
                                        }
                                    }
                                }
                            },
                            'slave002':{
                                node('slave002'){
                                    stage('slave002 での実行'){
                                        script {
                                            sh "sleep 1"
                                            MESG += " ${env.NODE_NAME} "
                                        }
                                    }
                                }
                            },
                            'slave003':{
                                node('slave003'){
                                    stage('slave003 での実行'){
                                        script {
                                            sh "sleep 4"
                                            MESG += " ${env.NODE_NAME} "
                                        }
                                    }
                                }
                            },
                        ]
                    )
                }
            } 
        }
        stage('Done') {
            steps {
                script {
                    echo "MESG => ${MESG}"
                }
            }
        }
    }
}

```

#### 結果

次のように、終了したノード順に MESG 変数に対してノード名が書き込まれている.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/57de182c-97be-00a2-aa16-81cf6ec19c23.png)

　

### 2. 上記 1 を Map を使って簡潔に記す

処理内容は同じだが、Map<String, Object> を使って記述する.

```groovy
def MESG = 'DONE ... '

Map<String, Object> pipelines = [:]
pipelines['slave001'] = { node('slave001'){ stage('slave001 での実行'){ script { sh "sleep 13"; MESG += " ${env.NODE_NAME} " } } } }
pipelines['slave002'] = { node('slave002'){ stage('slave002 での実行'){ script { sh "sleep 1" ; MESG += " ${env.NODE_NAME} " } } } }
pipelines['slave003'] = { node('slave003'){ stage('slave003 での実行'){ script { sh "sleep 4" ; MESG += " ${env.NODE_NAME} " } } } }

pipeline {
    agent any
    stages {
        stage('並列実行') {
            steps { 
                script {
                    parallel( pipelines )
                }
            } 
        }
        stage('Done') {
            steps {
                script {
                    echo "MESG => ${MESG}"
                }
            }
        }
    }
}
```



## 参考にしたサイト

・https://gist.github.com/hartsock/f76f2bf150644c16d2a7831b0688933a
・https://stackoverflow.com/questions/59261562/jenkinshow-to-achieve-parallel-dynamic-stages-in-jenkins-declarative-pipeline