blob: 91f032e2dd0b8acef7cd1d84cee80cd5663f71a6 [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
Alanny Lopez29cc3b12017-10-18 15:18:00 -050019# Default: "", variable ignored by default
Alanny Lopez620baa12017-10-10 11:50:03 -050020# cont_import_mnt The directory on the container used to import extra files
Alanny Lopez29cc3b12017-10-18 15:18:00 -050021# Default: "/mnt/jenkins_import", will be ignored by default
Alanny Lopez492c52c2017-11-10 15:06:26 -060022# jenkins_options What will be passed as the environment variable for the
Alanny Lopez29cc3b12017-10-18 15:18:00 -050023# JENKINS_OPTS environment variable.
24# Default: "--prefix=/jenkins"
Alanny Lopez492c52c2017-11-10 15:06:26 -060025# java_options What will be passed as the environment variable for the
26# JAVA_OPTS environment variable.
27# Default: "-Xmx4096m"
Alanny Lopez620baa12017-10-10 11:50:03 -050028# Build Variables:
29# img_tag The tag for the OpenJDK image used to build the Dockerfile
30# Default: "/8-jdk"
31# tini_vrsn The version of Tini to use in the dockerfile, 0.16.1 is
32# the first release with ppc64le release support
33# Default: "0.16.1"
34# j_vrsn The version of the Jenkins war file you wish to use
35# Default: "2.60.3"
36# j_user Username tag the container will use to run Jenkins
37# Default: "jenkins"
38# j_group Group name tag the container will use to run Jenkins
39# Default: "jenkins"
40# j_uid Jenkins user ID the container will use to run Jenkins
41# Default: "1000"
42# j_gif Jenkins group ID the container will use to run Jenkins
43# Default: "1000"
44# j_home Directory used as the Jenkins Home in the container
Alanny Lopez29cc3b12017-10-18 15:18:00 -050045# Default: "/var/jenkins_home"
Alanny Lopez620baa12017-10-10 11:50:03 -050046# http_port The port used as Jenkins UI port
47# Default: "8080"
48# agent_port The port used as the Jenkins slave agent port
49# Default: "50000"
50# out_img The name given to the Docker image when it is built
51# Default: "openbmc/jenkins-master-${ARCH}:${JENKINS_VRSN}"
52#
53################################################################################
54
55set -xeo pipefail
56ARCH=$(uname -m)
57
58# Launch Variables
59workspace=${workspace:-${HOME}/jenkins-build-${RANDOM}}
60launch=${launch:-docker}
61home_mnt=${home_mnt:-${workspace}/jenkins_home}
Alanny Lopez29cc3b12017-10-18 15:18:00 -050062host_import_mnt=${host_import_mnt:-}
Alanny Lopez620baa12017-10-10 11:50:03 -050063cont_import_mnt=${cont_import_mnt:-/mnt/jenkins_import}
Alanny Lopez492c52c2017-11-10 15:06:26 -060064jenkins_options=${jenkins_options:-"--prefix=/jenkins"}
65java_options=${java_options:-"-Xmx4096m"}
Alanny Lopez620baa12017-10-10 11:50:03 -050066
67# Dockerfile Variables
68img_tag=${img_tag:-8-jdk}
69tini_vrsn=${tini_vrsn:-0.16.1}
70j_vrsn=${j_vrsn:-2.60.3}
71j_user=${j_user:-jenkins}
72j_group=${j_group:-jenkins}
73j_uid=${j_uid:-1000}
74j_gid=${j_gid:-1000}
75j_home=${j_home:-/var/jenkins_home}
Alanny Lopez29cc3b12017-10-18 15:18:00 -050076http_port=${http_port:-8080}
Alanny Lopez620baa12017-10-10 11:50:03 -050077agent_port=${agent_port:-50000}
Alanny Lopez29cc3b12017-10-18 15:18:00 -050078out_img=${out_img:-openbmc/jenkins-master-${ARCH}:${j_vrsn}}
Alanny Lopez620baa12017-10-10 11:50:03 -050079
80# Save the Jenkins.war URL to a variable and SHA if we care about verification
81j_url=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${j_vrsn}/jenkins-war-${j_vrsn}.war
82
83# Make or Clean WORKSPACE
84if [[ -d ${workspace} ]]; then
85 rm -rf ${workspace}/Dockerfile \
86 ${workspace}/docker-jenkins \
87 ${workspace}/plugins.* \
88 ${workspace}/install-plugins.sh \
89 ${workspace}/jenkins.sh \
90 ${workspace}/jenkins-support \
91 ${workspace}/init.groovy
92else
93 mkdir -p ${workspace}
94fi
95
96# Determine the prefix of the Dockerfile's base image
97case ${ARCH} in
98 "ppc64le")
99 docker_base="ppc64le/"
100 tini_arch="ppc64el"
101 ;;
102 "x86_64")
103 docker_base=""
104 tini_arch="amd64"
105 ;;
106 *)
107 echo "Unsupported system architecture(${ARCH}) found for docker image"
108 exit 1
109esac
110
111# Move Into the WORKSPACE
112cd ${workspace}
113
114# Make the Dockerfile
115################################################################################
116cat >> Dockerfile << EOF
117FROM ${docker_base}openjdk:${img_tag}
118
119RUN apt-get update && apt-get install -y git curl
120
121ENV JENKINS_HOME ${j_home}
122ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
123
Alanny Lopez492c52c2017-11-10 15:06:26 -0600124# Jenkins will default to run with user jenkins, uid = 1000
Alanny Lopez620baa12017-10-10 11:50:03 -0500125# If you bind mount a volume from the host or a data container,
126# ensure you use the same uid
127RUN groupadd -g ${j_gid} ${j_group} && \
128 useradd -d ${j_home} -u ${j_uid} -g ${j_gid} -m -s /bin/bash ${j_user}
129
130# Jenkins home directory is a volume, so configuration and build history
131# can be persisted and survive image upgrades
132VOLUME ${j_home}
133
Alanny Lopez492c52c2017-11-10 15:06:26 -0600134# /usr/share/jenkins/ref/ contains all reference configuration we want
Alanny Lopez620baa12017-10-10 11:50:03 -0500135# to set on a fresh new installation. Use it to bundle additional plugins
136# or config file with your custom jenkins Docker image.
137RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d
138
139# Use tini as subreaper in Docker container to adopt zombie processes
140RUN curl -fsSL https://github.com/krallin/tini/releases/download/v${tini_vrsn}/tini-static-${tini_arch} \
141 -o /bin/tini && \
142 chmod +x /bin/tini
143
144COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy
145
146# could use ADD but this one does not check Last-Modified header neither does it allow to control checksum
147# see https://github.com/docker/docker/issues/8331
148RUN curl -fsSL ${j_url} -o /usr/share/jenkins/jenkins.war
149
150ENV JENKINS_UC https://updates.jenkins.io
151ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental
152RUN chown -R ${j_user} ${j_home} /usr/share/jenkins/ref
153
154# for main web interface:
155EXPOSE ${http_port}
156
157# will be used by attached slave agents:
158EXPOSE ${agent_port}
159
160ENV COPY_REFERENCE_FILE_LOG ${j_home}/copy_reference_file.log
161USER ${j_user}
162
163COPY jenkins-support /usr/local/bin/jenkins-support
164COPY jenkins.sh /usr/local/bin/jenkins.sh
165ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]
166
Alanny Lopez492c52c2017-11-10 15:06:26 -0600167# from a derived Dockerfile, can use RUN plugins.sh active.txt to setup /usr/share/jenkins/ref/plugins from a support bundle
Alanny Lopez620baa12017-10-10 11:50:03 -0500168COPY plugins.sh /usr/local/bin/plugins.sh
169COPY install-plugins.sh /usr/local/bin/install-plugins.sh
170
171# Install plugins.txt plugins
172COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
173RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
174EOF
175################################################################################
176
177# Clone in the jenkinsci docker jenkins repo and copy some files into WORKSPACE
178git clone https://github.com/jenkinsci/docker.git docker-jenkins
179cp docker-jenkins/init.groovy .
180cp docker-jenkins/jenkins-support .
181cp docker-jenkins/jenkins.sh .
182cp docker-jenkins/plugins.sh .
183cp docker-jenkins/install-plugins.sh .
184
185# Generate Plugins.txt, the plugins you want installed automatically go here
186################################################################################
187cat >> plugins.txt << EOF
188kubernetes
189EOF
190################################################################################
191
192# Build the image
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500193docker build -t ${out_img} .
Alanny Lopez620baa12017-10-10 11:50:03 -0500194
195if [[ ${launch} == "docker" ]]; then
196
197 # Ensure directories that will be mounted exist
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500198 if [[ ! -z ${host_import_mnt} && ! -d ${host_import_mnt} ]]; then
199 mkdir -p ${host_import_mnt}
Alanny Lopez620baa12017-10-10 11:50:03 -0500200 fi
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500201
Alanny Lopez620baa12017-10-10 11:50:03 -0500202 if [[ ! -d ${home_mnt} ]]; then
203 mkdir -p ${home_mnt}
204 fi
205
206 # Ensure directories tht will be mounted are owned by the jenkins user
207 if [[ "$(id -u)" != 0 ]]; then
208 echo "Not running as root:"
209 echo "Checking if jgid and juid are the owners of mounted directories"
210 test1=$(ls -nd ${home_mnt} | awk '{print $3 " " $4}')
Alanny Lopez620baa12017-10-10 11:50:03 -0500211 if [[ "${test1}" != "${j_uid} ${j_gid}" ]]; then
212 echo "Owner of ${home_mnt} is not the jenkins user"
213 echo "${test1} != ${j_uid} ${j_gid}"
214 willfail=1
215 fi
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500216 if [[ ! -z "${host_import_mnt}" ]]; then
217 test2=$(ls -nd ${host_import_mnt} | awk '{print $3 " " $4}' )
218 if [[ "${test2}" != "${j_uid} ${j_gid}" ]]; then
219 echo "Owner of ${host_import_mnt} is not the jenkins user"
220 echo "${test2} != ${j_uid} ${j_gid}"
221 willfail=1
222 fi
Alanny Lopez620baa12017-10-10 11:50:03 -0500223 fi
224 if [[ "${willfail}" == 1 ]]; then
225 echo "Failing before attempting to launch container"
226 echo "Try again as root or use correct uid/gid pairs"
227 exit 1
228 fi
229 else
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500230 if [[ ! -z ${host_import_mnt} ]]; then
231 chown -R ${j_uid}:${j_gid} ${host_import_mnt}
232 fi
Alanny Lopez620baa12017-10-10 11:50:03 -0500233 chown -R ${j_uid}:${j_gid} ${home_mnt}
234 fi
235
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500236 #If we don't have import mount don't add to docker command
237 if [[ ! -z ${host_import_mnt} ]]; then
238 importvolcmd="-v ${host_import_mnt}:${cont_import_mnt}"
239 fi
Alanny Lopez620baa12017-10-10 11:50:03 -0500240 # Launch the jenkins image with Docker
241 docker run -d \
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500242 ${importvolcmd} \
Alanny Lopez620baa12017-10-10 11:50:03 -0500243 -v ${home_mnt}:${j_home} \
244 -p ${http_port}:8080 \
245 -p ${agent_port}:${agent_port} \
Alanny Lopez492c52c2017-11-10 15:06:26 -0600246 --env JAVA_OPTS=\"${java_options}\" \
247 --env JENKINS_OPTS=\"${jenkins_options}\" \
Alanny Lopez620baa12017-10-10 11:50:03 -0500248 ${out_img}
249
250elif [[ ${launch} == "k8s" ]]; then
251 # launch using the k8s template
252 echo "Not yet Implemented"
253 exit 1
254 source ./kubernetes/kubernetes-launch.sh Build-Jenkins false false
Alanny Lopez29cc3b12017-10-18 15:18:00 -0500255fi