blob: eb9457e54d8ad68baf0d973a95c22c87dfeb723d [file] [log] [blame]
Alanny Lopez620baa12017-10-10 11:50:03 -05001#!/bin/bash
2################################################################################
3# Script used to create a Jenkins master that can run amd64 or ppc64le. It can
4# be used to launch the Jenkins master as a Docker container locally or as a
5# Kubernetes Deployment in a Kubernetes cluster.
6################################################################################
7# Launch Variables:
8# These variables are used to determine how the master will be launched
9# workspace The directory that hold files used to deploy the Jenkins
10# master
11# Default: "${HOME}/jenkins-build-${RANDOM}"
12# launch Method in which the container will be launched, either as
13# a Docker container launched via Docker or by using a
14# helper script to launch into Kubernetes (docker or k8s)
15# Default: "docker"
16# home_mnt The directory on the host used as the Jenkins home
17# Default: "${WORKSPACE}/jenkins_home"
18# host_import_mnt The directory on the host used to import extra files
19# Default: "${WORKSPACE}/jenkins_import"
20# cont_import_mnt The directory on the container used to import extra files
21# Default: "/mnt/jenkins_import"
22#
23# Build Variables:
24# img_tag The tag for the OpenJDK image used to build the Dockerfile
25# Default: "/8-jdk"
26# tini_vrsn The version of Tini to use in the dockerfile, 0.16.1 is
27# the first release with ppc64le release support
28# Default: "0.16.1"
29# j_vrsn The version of the Jenkins war file you wish to use
30# Default: "2.60.3"
31# j_user Username tag the container will use to run Jenkins
32# Default: "jenkins"
33# j_group Group name tag the container will use to run Jenkins
34# Default: "jenkins"
35# j_uid Jenkins user ID the container will use to run Jenkins
36# Default: "1000"
37# j_gif Jenkins group ID the container will use to run Jenkins
38# Default: "1000"
39# j_home Directory used as the Jenkins Home in the container
40# Default: "${WORKSPACE}/jenkins_home"
41# http_port The port used as Jenkins UI port
42# Default: "8080"
43# agent_port The port used as the Jenkins slave agent port
44# Default: "50000"
45# out_img The name given to the Docker image when it is built
46# Default: "openbmc/jenkins-master-${ARCH}:${JENKINS_VRSN}"
47#
48################################################################################
49
50set -xeo pipefail
51ARCH=$(uname -m)
52
53# Launch Variables
54workspace=${workspace:-${HOME}/jenkins-build-${RANDOM}}
55launch=${launch:-docker}
56home_mnt=${home_mnt:-${workspace}/jenkins_home}
57host_import_mnt=${host_import_mnt:-${workspace}/jenkins_import}
58cont_import_mnt=${cont_import_mnt:-/mnt/jenkins_import}
59
60# Dockerfile Variables
61img_tag=${img_tag:-8-jdk}
62tini_vrsn=${tini_vrsn:-0.16.1}
63j_vrsn=${j_vrsn:-2.60.3}
64j_user=${j_user:-jenkins}
65j_group=${j_group:-jenkins}
66j_uid=${j_uid:-1000}
67j_gid=${j_gid:-1000}
68j_home=${j_home:-/var/jenkins_home}
69agent_port=${http_port:-8080}
70agent_port=${agent_port:-50000}
71out_img=${out_img:-openbmc/jenkins-master-${ARCH}:${JENKINS_VRSN}}
72
73# Save the Jenkins.war URL to a variable and SHA if we care about verification
74j_url=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${j_vrsn}/jenkins-war-${j_vrsn}.war
75
76# Make or Clean WORKSPACE
77if [[ -d ${workspace} ]]; then
78 rm -rf ${workspace}/Dockerfile \
79 ${workspace}/docker-jenkins \
80 ${workspace}/plugins.* \
81 ${workspace}/install-plugins.sh \
82 ${workspace}/jenkins.sh \
83 ${workspace}/jenkins-support \
84 ${workspace}/init.groovy
85else
86 mkdir -p ${workspace}
87fi
88
89# Determine the prefix of the Dockerfile's base image
90case ${ARCH} in
91 "ppc64le")
92 docker_base="ppc64le/"
93 tini_arch="ppc64el"
94 ;;
95 "x86_64")
96 docker_base=""
97 tini_arch="amd64"
98 ;;
99 *)
100 echo "Unsupported system architecture(${ARCH}) found for docker image"
101 exit 1
102esac
103
104# Move Into the WORKSPACE
105cd ${workspace}
106
107# Make the Dockerfile
108################################################################################
109cat >> Dockerfile << EOF
110FROM ${docker_base}openjdk:${img_tag}
111
112RUN apt-get update && apt-get install -y git curl
113
114ENV JENKINS_HOME ${j_home}
115ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
116
117# Jenkins will default to run with user `jenkins`, uid = 1000
118# If you bind mount a volume from the host or a data container,
119# ensure you use the same uid
120RUN groupadd -g ${j_gid} ${j_group} && \
121 useradd -d ${j_home} -u ${j_uid} -g ${j_gid} -m -s /bin/bash ${j_user}
122
123# Jenkins home directory is a volume, so configuration and build history
124# can be persisted and survive image upgrades
125VOLUME ${j_home}
126
127# `/usr/share/jenkins/ref/` contains all reference configuration we want
128# to set on a fresh new installation. Use it to bundle additional plugins
129# or config file with your custom jenkins Docker image.
130RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d
131
132# Use tini as subreaper in Docker container to adopt zombie processes
133RUN curl -fsSL https://github.com/krallin/tini/releases/download/v${tini_vrsn}/tini-static-${tini_arch} \
134 -o /bin/tini && \
135 chmod +x /bin/tini
136
137COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy
138
139# could use ADD but this one does not check Last-Modified header neither does it allow to control checksum
140# see https://github.com/docker/docker/issues/8331
141RUN curl -fsSL ${j_url} -o /usr/share/jenkins/jenkins.war
142
143ENV JENKINS_UC https://updates.jenkins.io
144ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental
145RUN chown -R ${j_user} ${j_home} /usr/share/jenkins/ref
146
147# for main web interface:
148EXPOSE ${http_port}
149
150# will be used by attached slave agents:
151EXPOSE ${agent_port}
152
153ENV COPY_REFERENCE_FILE_LOG ${j_home}/copy_reference_file.log
154USER ${j_user}
155
156COPY jenkins-support /usr/local/bin/jenkins-support
157COPY jenkins.sh /usr/local/bin/jenkins.sh
158ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]
159
160# from a derived Dockerfile, can use `RUN plugins.sh active.txt` to setup /usr/share/jenkins/ref/plugins from a support bundle
161COPY plugins.sh /usr/local/bin/plugins.sh
162COPY install-plugins.sh /usr/local/bin/install-plugins.sh
163
164# Install plugins.txt plugins
165COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
166RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
167EOF
168################################################################################
169
170# Clone in the jenkinsci docker jenkins repo and copy some files into WORKSPACE
171git clone https://github.com/jenkinsci/docker.git docker-jenkins
172cp docker-jenkins/init.groovy .
173cp docker-jenkins/jenkins-support .
174cp docker-jenkins/jenkins.sh .
175cp docker-jenkins/plugins.sh .
176cp docker-jenkins/install-plugins.sh .
177
178# Generate Plugins.txt, the plugins you want installed automatically go here
179################################################################################
180cat >> plugins.txt << EOF
181kubernetes
182EOF
183################################################################################
184
185# Build the image
186docker build --pull -t ${out_img} .
187
188if [[ ${launch} == "docker" ]]; then
189
190 # Ensure directories that will be mounted exist
191 if [[ ! -d ${host_import_mnt} ]]; then
192 mkdir -p ${host_import_mnt}
193 fi
194 if [[ ! -d ${home_mnt} ]]; then
195 mkdir -p ${home_mnt}
196 fi
197
198 # Ensure directories tht will be mounted are owned by the jenkins user
199 if [[ "$(id -u)" != 0 ]]; then
200 echo "Not running as root:"
201 echo "Checking if jgid and juid are the owners of mounted directories"
202 test1=$(ls -nd ${home_mnt} | awk '{print $3 " " $4}')
203 test2=$(ls -nd ${host_import_mnt} | awk '{print $3 " " $4}' )
204 if [[ "${test1}" != "${j_uid} ${j_gid}" ]]; then
205 echo "Owner of ${home_mnt} is not the jenkins user"
206 echo "${test1} != ${j_uid} ${j_gid}"
207 willfail=1
208 fi
209 if [[ "${test2}" != "${j_uid} ${j_gid}" ]]; then
210 echo "Owner of ${host_import_mnt} is not the jenkins user"
211 echo "${test2} != ${j_uid} ${j_gid}"
212 willfail=1
213 fi
214 if [[ "${willfail}" == 1 ]]; then
215 echo "Failing before attempting to launch container"
216 echo "Try again as root or use correct uid/gid pairs"
217 exit 1
218 fi
219 else
220 chown -R ${j_uid}:${j_gid} ${host_import_mnt}
221 chown -R ${j_uid}:${j_gid} ${home_mnt}
222 fi
223
224 # Launch the jenkins image with Docker
225 docker run -d \
226 -v ${host_import_mnt}:${cont_import_mnt} \
227 -v ${home_mnt}:${j_home} \
228 -p ${http_port}:8080 \
229 -p ${agent_port}:${agent_port} \
230 ${out_img}
231
232elif [[ ${launch} == "k8s" ]]; then
233 # launch using the k8s template
234 echo "Not yet Implemented"
235 exit 1
236 source ./kubernetes/kubernetes-launch.sh Build-Jenkins false false
237fi