xref: /openbmc/openbmc-build-scripts/build-setup.sh (revision 366dd7689fda298abcbcaa2c37993602acd02729)
1#!/bin/bash
2###############################################################################
3#
4# This build script is for running the OpenBMC builds as containers with the
5# option of launching the containers with Docker or Kubernetes.
6#
7###############################################################################
8#
9# Script Variables:
10#  build_scripts_dir  The path of the openbmc-build-scripts directory.
11#                     Default: The directory containing this script
12#  http_proxy         The HTTP address of the proxy server to connect to.
13#                     Default: "", proxy is not setup if this is not set
14#  WORKSPACE          Path of the workspace directory where some intermediate
15#                     files and the images will be saved to.
16#                     Default: "~/{RandomNumber}"
17#  num_cpu            Number of cpu's to give bitbake, default is total amount
18#                     in system
19#
20# Docker Image Build Variables:
21#  BITBAKE_OPTS       Set to "-c populate_sdk" or whatever other BitBake options
22#                     you'd like to pass into the build.
23#                     Default: "", no options set
24#  build_dir          Path where the actual BitBake build occurs inside the
25#                     container, path cannot be located on network storage.
26#                     Default: "/tmp/openbmc"
27#  distro             The distro used as the base image for the build image:
28#                     fedora|ubuntu
29#                     Default: "ubuntu"
30#  img_name           The name given to the target build's docker image.
31#                     Default: "openbmc/${distro}:${imgtag}-${target}-${ARCH}"
32#  img_tag            The base docker image distro tag:
33#                     ubuntu: latest|16.04|14.04|trusty|xenial
34#                     fedora: 23|24|25
35#                     Default: "latest"
36#  target             The target we aim to build:
37#                     evb-ast2500|palmetto|qemu|qemux86-64
38#                     romulus|s2600wf|witherspoon|zaius
39#                     Default: "qemu"
40#
41# Deployment Variables:
42#  launch             ""|job|pod
43#                     Can be left blank to launch the container via Docker
44#                     Job lets you keep a copy of job and container logs on the
45#                     api, can be useful if not using Jenkins as you can run the
46#                     job again via the api without needing this script.
47#                     Pod launches a container which runs to completion without
48#                     saving anything to the api when it completes.
49#  obmc_dir           Path of the OpenBMC repo directory used as a reference
50#                     for the build inside the container.
51#                     Default: "${WORKSPACE}/openbmc"
52#  ssc_dir            Path to use as the BitBake shared-state cache directory.
53#                     Default: "/home/${USER}"
54#  xtrct_small_copy_dir
55#                     Directory within build_dir that should be copied to
56#                     xtrct_path. The directory and all parents up to, but not
57#                     including, build_dir will be copied. For example, if
58#                     build_dir is set to "/tmp/openbmc" and this is set to
59#                     "build/tmp", the directory at xtrct_path will have the
60#                     following directory structure:
61#                     xtrct_path
62#                      | - build
63#                        | - tmp
64#                          ...
65#                     Can also be set to the empty string to copy the entire
66#                     contents of build_dir to xtrct_path.
67#                     Default: "deploy/images".
68#  xtrct_path         Path where the build_dir contents will be copied out to
69#                     when the build completes.
70#                     Default: "${obmc_dir}/build/tmp"
71#  xtrct_copy_timeout Timeout (in seconds) for copying the contents of
72#                     build_dir to xtrct_path.
73#                     Default: "300"
74#
75###############################################################################
76# Trace bash processing. Set -e so when a step fails, we fail the build
77set -xeo pipefail
78
79# Script Variables:
80build_scripts_dir=${build_scripts_dir:-"$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"}
81http_proxy=${http_proxy:-}
82WORKSPACE=${WORKSPACE:-${HOME}/${RANDOM}${RANDOM}}
83num_cpu=${num_cpu:-$(nproc)}
84
85# Docker Image Build Variables:
86build_dir=${build_dir:-/tmp/openbmc}
87distro=${distro:-ubuntu}
88img_tag=${img_tag:-latest}
89target=${target:-qemu}
90
91# Deployment variables
92launch=${launch:-}
93obmc_dir=${obmc_dir:-${WORKSPACE}/openbmc}
94ssc_dir=${ssc_dir:-${HOME}}
95xtrct_small_copy_dir=${xtrct_small_copy_dir:-deploy/images}
96xtrct_path=${xtrct_path:-${obmc_dir}/build/tmp}
97xtrct_copy_timeout=${xtrct_copy_timeout:-300}
98
99PROXY=""
100
101# Determine the architecture
102ARCH=$(uname -m)
103
104# Determine the prefix of the Dockerfile's base image
105case ${ARCH} in
106  "ppc64le")
107    DOCKER_BASE="ppc64le/"
108    ;;
109  "x86_64")
110    DOCKER_BASE=""
111    ;;
112  *)
113    echo "Unsupported system architecture(${ARCH}) found for docker image"
114    exit 1
115esac
116
117# Timestamp for job
118echo "Build started, $(date)"
119
120# If the obmc_dir directory doesn't exist clone it in
121if [ ! -d ${obmc_dir} ]; then
122  echo "Clone in openbmc master to ${obmc_dir}"
123  git clone https://github.com/openbmc/openbmc ${obmc_dir}
124fi
125
126# Make and chown the xtrct_path directory to avoid permission errors
127if [ ! -d ${xtrct_path} ]; then
128  mkdir -p ${xtrct_path}
129fi
130chown ${UID}:${GROUPS} ${xtrct_path}
131
132# Work out what build target we should be running and set BitBake command
133case ${target} in
134  palmetto)
135    LAYER_DIR="meta-ibm/meta-palmetto"
136    ;;
137  witherspoon)
138    LAYER_DIR="meta-ibm/meta-witherspoon"
139    ;;
140  evb-ast2500)
141    LAYER_DIR="meta-evb/meta-evb-aspeed/meta-evb-ast2500"
142    ;;
143  s2600wf)
144    LAYER_DIR="meta-intel/meta-s2600wf"
145    ;;
146  zaius)
147    LAYER_DIR="meta-ingrasys/meta-zaius"
148    ;;
149  romulus)
150    LAYER_DIR="meta-ibm/meta-romulus"
151    ;;
152  qemu)
153    LAYER_DIR="meta-phosphor"
154    ;;
155  qemux86-64)
156    BITBAKE_CMD="MACHINE=qemux86-64 source oe-init-build-env"
157    ;;
158  *)
159    exit 1
160    ;;
161esac
162
163BITBAKE_CMD="TEMPLATECONF=${LAYER_DIR}/conf source oe-init-build-env"
164
165# Configure Docker build
166if [[ "${distro}" == fedora ]];then
167
168  if [[ -n "${http_proxy}" ]]; then
169    PROXY="RUN echo \"proxy=${http_proxy}\" >> /etc/dnf/dnf.conf"
170  fi
171
172  Dockerfile=$(cat << EOF
173  FROM ${DOCKER_BASE}${distro}:${img_tag}
174
175  ${PROXY}
176
177  # Set the locale
178  RUN locale-gen en_US.UTF-8
179  ENV LANG en_US.UTF-8
180  ENV LANGUAGE en_US:en
181  ENV LC_ALL en_US.UTF-8
182
183  RUN dnf --refresh install -y \
184      bzip2 \
185      chrpath \
186      cpio \
187      diffstat \
188      findutils \
189      gcc \
190      gcc-c++ \
191      git \
192      make \
193      patch \
194      perl-bignum \
195      perl-Data-Dumper \
196      perl-Thread-Queue \
197      python-devel \
198      python3-devel \
199      SDL-devel \
200      socat \
201      subversion \
202      tar \
203      texinfo \
204      wget \
205      which \
206      iputils-ping
207
208  RUN grep -q ${GROUPS} /etc/group || groupadd -g ${GROUPS} ${USER}
209  RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS} ${USER}
210
211  USER ${USER}
212  ENV HOME ${HOME}
213  RUN /bin/bash
214EOF
215)
216
217elif [[ "${distro}" == ubuntu ]]; then
218
219  if [[ -n "${http_proxy}" ]]; then
220    PROXY="RUN echo \"Acquire::http::Proxy \\"\"${http_proxy}/\\"\";\" > /etc/apt/apt.conf.d/000apt-cacher-ng-proxy"
221  fi
222
223  Dockerfile=$(cat << EOF
224  FROM ${DOCKER_BASE}${distro}:${img_tag}
225
226  ${PROXY}
227
228  ENV DEBIAN_FRONTEND noninteractive
229
230  RUN apt-get update && apt-get install -yy \
231      build-essential \
232      chrpath \
233      debianutils \
234      diffstat \
235      gawk \
236      git \
237      libdata-dumper-simple-perl \
238      libsdl1.2-dev \
239      libthread-queue-any-perl \
240      locales \
241      python \
242      python3 \
243      socat \
244      subversion \
245      texinfo \
246      cpio \
247      wget \
248      iputils-ping
249
250  # Set the locale
251  RUN locale-gen en_US.UTF-8
252  ENV LANG en_US.UTF-8
253  ENV LANGUAGE en_US:en
254  ENV LC_ALL en_US.UTF-8
255
256  RUN grep -q ${GROUPS} /etc/group || groupadd -g ${GROUPS} ${USER}
257  RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS} ${USER}
258
259  USER ${USER}
260  ENV HOME ${HOME}
261  RUN /bin/bash
262EOF
263)
264fi
265
266# Create the Docker run script
267export PROXY_HOST=${http_proxy/#http*:\/\/}
268export PROXY_HOST=${PROXY_HOST/%:[0-9]*}
269export PROXY_PORT=${http_proxy/#http*:\/\/*:}
270
271mkdir -p ${WORKSPACE}
272
273cat > "${WORKSPACE}"/build.sh << EOF_SCRIPT
274#!/bin/bash
275
276set -xeo pipefail
277
278# Go into the OpenBMC directory, the build will handle changing directories
279cd ${obmc_dir}
280
281# Set up proxies
282export ftp_proxy=${http_proxy}
283export http_proxy=${http_proxy}
284export https_proxy=${http_proxy}
285
286mkdir -p ${WORKSPACE}/bin
287
288# Configure proxies for BitBake
289if [[ -n "${http_proxy}" ]]; then
290
291  cat > ${WORKSPACE}/bin/git-proxy << \EOF_GIT
292  #!/bin/bash
293  # \$1 = hostname, \$2 = port
294  PROXY=${PROXY_HOST}
295  PROXY_PORT=${PROXY_PORT}
296  exec socat STDIO PROXY:\${PROXY}:\${1}:\${2},proxyport=\${PROXY_PORT}
297EOF_GIT
298
299  chmod a+x ${WORKSPACE}/bin/git-proxy
300  export PATH=${WORKSPACE}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}
301  git config core.gitProxy git-proxy
302
303  mkdir -p ~/.subversion
304
305  cat > ~/.subversion/servers << EOF_SVN
306  [global]
307  http-proxy-host = ${PROXY_HOST}
308  http-proxy-port = ${PROXY_PORT}
309EOF_SVN
310fi
311
312# Source our build env
313${BITBAKE_CMD}
314
315# Custom BitBake config settings
316cat >> conf/local.conf << EOF_CONF
317BB_NUMBER_THREADS = "$(nproc)"
318PARALLEL_MAKE = "-j$(nproc)"
319INHERIT += "rm_work"
320BB_GENERATE_MIRROR_TARBALLS = "1"
321DL_DIR="${ssc_dir}/bitbake_downloads"
322SSTATE_DIR="${ssc_dir}/bitbake_sharedstatecache"
323USER_CLASSES += "buildstats"
324INHERIT_remove = "uninative"
325TMPDIR="${build_dir}"
326EOF_CONF
327
328# Kick off a build
329bitbake ${BITBAKE_OPTS} obmc-phosphor-image
330
331# Copy internal build directory into xtrct_path directory
332if [[ ${xtrct_small_copy_dir} ]]; then
333  mkdir -p ${xtrct_path}/${xtrct_small_copy_dir}
334  timeout ${xtrct_copy_timeout} cp -r ${build_dir}/${xtrct_small_copy_dir}/* ${xtrct_path}/${xtrct_small_copy_dir}
335else
336  timeout ${xtrct_copy_timeout} cp -r ${build_dir}/* ${xtrct_path}
337fi
338
339if [[ 0 -ne $? ]]; then
340  echo "Received a non-zero exit code from timeout"
341  exit 1
342fi
343
344EOF_SCRIPT
345
346chmod a+x ${WORKSPACE}/build.sh
347
348# Give the Docker image a name based on the distro,tag,arch,and target
349img_name=${img_name:-openbmc/${distro}:${img_tag}-${target}-${ARCH}}
350
351# Build the Docker image
352docker build -t ${img_name} - <<< "${Dockerfile}"
353
354# Determine if the build container will be launched with Docker or Kubernetes
355if [[ "${launch}" == "" ]]; then
356
357  # If obmc_dir or ssc_dir are ${HOME} or a subdirectory they will not be mounted
358  mount_obmc_dir="-v ""${obmc_dir}"":""${obmc_dir}"" "
359  mount_ssc_dir="-v ""${ssc_dir}"":""${ssc_dir}"" "
360  if [[ "${obmc_dir}" = "${HOME}/"* || "${obmc_dir}" = "${HOME}" ]];then
361    mount_obmc_dir=""
362  fi
363  if [[ "${ssc_dir}" = "${HOME}/"* || "${ssc_dir}" = "${HOME}" ]];then
364    mount_ssc_dir=""
365  fi
366
367  # Run the Docker container, execute the build.sh script
368  docker run \
369  --cap-add=sys_admin \
370  --net=host \
371  --rm=true \
372  -e WORKSPACE=${WORKSPACE} \
373  -w "${HOME}" \
374  -v "${HOME}":"${HOME}" \
375  ${mount_obmc_dir} \
376  ${mount_ssc_dir} \
377  --cpus="$num_cpu" \
378  -t ${img_name} \
379  ${WORKSPACE}/build.sh
380
381elif [[ "${launch}" == "job" || "${launch}" == "pod" ]]; then
382
383  # Source and run the helper script to launch the pod or job
384  . ${build_scripts_dir}/kubernetes/kubernetes-launch.sh OpenBMC-build true true
385
386else
387  echo "Launch Parameter is invalid"
388fi
389
390# To maintain function of resources that used an older path, add a link
391ln -sf ${xtrct_path}/deploy ${WORKSPACE}/deploy
392
393# Timestamp for build
394echo "Build completed, $(date)"
395