Jenkins Pipeline、Jenkinsfileではまったところメモ
parallelとnodeを組み合わせた場合のワークスペースの確保方法の違い
- Jenkins 2.63
- Pipeline: Nodes and Processes 2.11
ラベル指定なしのnodeの場合、env.WORKSPACEは別々のものが確保される
def allocateNode() {
node {
echo env.WORKSPACE
}
}
parallel a: { allocateNode() }, b: { allocateNode() }
[Pipeline] parallel
[Pipeline] [a] { (Branch: a)
[Pipeline] [b] { (Branch: b)
[Pipeline] [a] node
[Pipeline] [b] node
[a] Running on master in /var/lib/jenkins/jobs/pipeline-test/workspace
[Pipeline] [a] {
[b] Running on master in /var/lib/jenkins/jobs/pipeline-test/workspace@2
[Pipeline] [a] echo
[a] /var/lib/jenkins/jobs/pipeline-test/workspace
[Pipeline] [a] }
[Pipeline] [b] {
[Pipeline] [a] // node
[Pipeline] [a] }
[Pipeline] [b] echo
[b] /var/lib/jenkins/jobs/pipeline-test/workspace@2
[Pipeline] [b] }
[Pipeline] [b] // node
[Pipeline] [b] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
ラベル指定有りのnodeの場合、env.WORKSPACEは同じものが利用される
def allocateNode() {
node('docker') {
echo env.WORKSPACE
}
}
parallel a: { allocateNode() }, b: { allocateNode() }
[Pipeline] parallel
[Pipeline] [a] { (Branch: a)
[Pipeline] [b] { (Branch: b)
[Pipeline] [a] node
[a] Running on jenkins-slave-docker1 in /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [b] node
[Pipeline] [a] {
[Pipeline] [a] echo
[a] /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [a] }
[b] Running on jenkins-slave-docker1 in /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [a] // node
[Pipeline] [b] {
[Pipeline] [a] }
[Pipeline] [b] echo
[b] /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [b] }
[Pipeline] [b] // node
[Pipeline] [b] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
wsを利用すればワークスペースを確保することができる。
def allocateNode(buildType) {
node('docker') {
ws("${env.WORKSPACE}/${buildType}") {
echo env.WORKSPACE
}
}
}
parallel a: { allocateNode('a') }, b: { allocateNode('b') }
[Pipeline] parallel
[Pipeline] [a] { (Branch: a)
[Pipeline] [b] { (Branch: b)
[Pipeline] [a] node
[Pipeline] [b] node
[a] Running on jenkins-slave-docker1 in /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [a] {
[Pipeline] [a] ws
[a] Running in /home/jenkins-slave/workspace/pipeline-test/a
[Pipeline] [a] {
[Pipeline] [a] echo
[a] /home/jenkins-slave/workspace/pipeline-test/a
[Pipeline] [a] }
[Pipeline] [a] // ws
[Pipeline] [a] }
[Pipeline] [a] // node
[Pipeline] [a] }
[b] Running on jenkins-slave-docker1 in /home/jenkins-slave/workspace/pipeline-test
[Pipeline] [b] {
[Pipeline] [b] ws
[b] Running in /home/jenkins-slave/workspace/pipeline-test/b
[Pipeline] [b] {
[Pipeline] [b] echo
[b] /home/jenkins-slave/workspace/pipeline-test/b
[Pipeline] [b] }
[Pipeline] [b] // ws
[Pipeline] [b] }
[Pipeline] [b] // node
[Pipeline] [b] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
複数のリポジトリをチェックアウト
dir で囲もう
node {
git url: 'repo.git'
checkout scm
dir('subrepo') {
git url: 'subrepo.git'
}
}
docker + dir + sh の動き
今の所うまく動かない。
node('docker') {
echo env.WORKSPACE
sh 'mkdir -p hoge/hoge'
sh 'pwd'
dir('hoge/hoge') {
sh 'pwd' // これはOK
}
sh 'pwd'
docker.image('ruby:2.4.1').inside {
sh 'pwd'
dir('hoge/hoge') {
sh 'pwd' // こっちはダメ
}
sh 'pwd'
}
}
[Pipeline] node
Running on jenkins-slave-docker1 in /home/jenkins-slave/workspace/pipeline-test
[Pipeline] {
[Pipeline] echo
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] sh
[pipeline-test] Running shell script
+ mkdir -p hoge/hoge
[Pipeline] sh
[pipeline-test] Running shell script
+ pwd
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] dir
Running in /home/jenkins-slave/workspace/pipeline-test/hoge/hoge
[Pipeline] {
[Pipeline] sh
[hoge] Running shell script
+ pwd
/home/jenkins-slave/workspace/pipeline-test/hoge/hoge
[Pipeline] }
[Pipeline] // dir
[Pipeline] sh
[pipeline-test] Running shell script
+ pwd
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] sh
[pipeline-test] Running shell script
+ docker inspect -f . ruby:2.4.1
.
[Pipeline] withDockerContainer
jenkins-slave-docker1 does not seem to be running inside a container
$ docker run -t -d -u 1001:1001 -w /home/jenkins-slave/workspace/pipeline-test -v /home/jenkins-slave/workspace/pipeline-test:/home/jenkins-slave/workspace/pipeline-test:rw -v /home/jenkins-slave/workspace/pipeline-test@tmp:/home/jenkins-slave/workspace/pipeline-test@tmp:rw -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** --entrypoint cat ruby:2.4.1
[Pipeline] {
[Pipeline] sh
[pipeline-test] Running shell script
+ pwd
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] dir
Running in /home/jenkins-slave/workspace/pipeline-test/hoge/hoge
[Pipeline] {
[Pipeline] sh
[hoge] Running shell script
JENKINS-33510: working directory will be /home/jenkins-slave/workspace/pipeline-test not /home/jenkins-slave/workspace/pipeline-test/hoge/hoge
+ pwd
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] }
[Pipeline] // dir
[Pipeline] sh
[pipeline-test] Running shell script
+ pwd
/home/jenkins-slave/workspace/pipeline-test
[Pipeline] }
$ docker stop --time=1 b10d417e8ef04951965997a6d80c4357eec39758e634f833b1d2cc5704cd223a
$ docker rm -f b10d417e8ef04951965997a6d80c4357eec39758e634f833b1d2cc5704cd223a
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
dockerにログインしてるユーザー
jenkins(かjenkins-slave)を実行しているユーザー。ユーザー名ではなくuid、gidを使っている。
環境変数
-u $(id -u)の有無で$HOMEが異なる。
% docker run -it node:6 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=d57d403199c8
TERM=xterm
NODE_VERSION=6.13.0
YARN_VERSION=1.3.2
HOME=/root
% docker run -it -u $(id -u) node:6 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=f85550e1e0a8
TERM=xterm
NODE_VERSION=6.13.0
YARN_VERSION=1.3.2
HOME=/
% docker run -it -u $(id -u) ruby:2.4.3 env
PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=b5771e49dde3
TERM=xterm
RUBY_MAJOR=2.4
RUBY_VERSION=2.4.3
RUBY_DOWNLOAD_SHA256=23677d40bf3b7621ba64593c978df40b1e026d8653c74a0599f0ead78ed92b51
RUBYGEMS_VERSION=2.7.6
BUNDLER_VERSION=1.16.1
GEM_HOME=/usr/local/bundle
BUNDLE_PATH=/usr/local/bundle
BUNDLE_BIN=/usr/local/bundle/bin
BUNDLE_SILENCE_ROOT_WARNING=1
BUNDLE_APP_CONFIG=/usr/local/bundle
HOME=/
Jenkinsで起動するときは常に-uが設定されるので上書きしない限りHOME=/になっていることを前提としたほうがいい。
LANGとTZは次を指定しておきたい。
-e LANG=C.UTF-8 -e TZ=Asia/Tokyo
HOME=/と書き込み権限
ruby(というかbundler)
HOMEは使っていないし、GEM_HOME、BUNDLE_BINのパーミッションを777にしている。偉大な正義。
yarnとかbower
こんかな感じで警告が出る
% docker run -it -v (pwd):/opt/project --workdir /opt/project -u (id -u) node:6 yarn
yarn install v1.3.2
warning Skipping preferred cache folder "/.cache/yarn" because it is not writable.
warning Selected the next writable cache folder in the list, will be "/tmp/.yarn-cache-501".
[1/4] Resolving packages...
[2/4] Fetching packages...
...
warning Your current version of Yarn is out of date. The latest version is "1.5.1" while you're on "1.3.2".
info To upgrade, run the following command:
$ curl -o- -L https://yarnpkg.com/install.sh | bash
Done in 70.84s.
Error: EACCES: permission denied, open '/.yarnrc'
at Error (native)
$HOME/.cache/yarn = /.cache/yarnだけどどこの馬の骨とも知らない-u $(id -u)なユーザは当然書き込み権限などない。-e YARN_CACHE_FOLDER=/tmpのように指定して回避する方法もある。
/.yarnrc(のlastUpdateCheckの更新)についてはちょっといい案が浮かばない。書き込み権限のある適当なHOMEを設定するのが一番かな。。
参考にしているJenkinsfile
- https://github.com/jenkinsci/jenkins/blob/master/Jenkinsfile
- https://github.com/jenkinsci/pipeline-examples
- https://jenkins.io/blog/2016/08/10/rails-cd-with-pipeline/
- https://github.com/jenkins-infra/jenkins-infra/blob/staging/Jenkinsfile
- https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile
- https://github.com/jenkins-infra/pipeline-library/blob/master/vars/buildPlugin.groovy