xref: /openbmc/openbmc-build-scripts/build-setup.sh (revision be6aab2ec9c57cca916d4a78a69f852867428751)
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
133MACHINE=""
134case ${target} in
135  palmetto)
136    LAYER_DIR="meta-ibm/meta-palmetto"
137    ;;
138  witherspoon)
139    LAYER_DIR="meta-ibm/meta-witherspoon"
140    ;;
141  evb-ast2500)
142    LAYER_DIR="meta-evb/meta-evb-aspeed/meta-evb-ast2500"
143    ;;
144  s2600wf)
145    LAYER_DIR="meta-intel/meta-s2600wf"
146    ;;
147  zaius)
148    LAYER_DIR="meta-ingrasys/meta-zaius"
149    ;;
150  romulus)
151    LAYER_DIR="meta-ibm/meta-romulus"
152    ;;
153  qemu)
154    LAYER_DIR="meta-phosphor"
155    # MACHINE defaults to `qemuarm` in this layer, no change necessary
156    ;;
157  qemux86-64)
158    LAYER_DIR="meta-phosphor"
159    # MACHINE defaults to `qemuarm` in this layer, change to `qemux86-64`
160    MACHINE="qemux86-64"
161    ;;
162  *)
163    exit 1
164    ;;
165esac
166
167BITBAKE_CMD="TEMPLATECONF=${LAYER_DIR}/conf source oe-init-build-env"
168
169# Configure Docker build
170if [[ "${distro}" == fedora ]];then
171
172  if [[ -n "${http_proxy}" ]]; then
173    PROXY="RUN echo \"proxy=${http_proxy}\" >> /etc/dnf/dnf.conf"
174  fi
175
176  Dockerfile=$(cat << EOF
177  FROM ${DOCKER_BASE}${distro}:${img_tag}
178
179  ${PROXY}
180
181  # Set the locale
182  RUN locale-gen en_US.UTF-8
183  ENV LANG en_US.UTF-8
184  ENV LANGUAGE en_US:en
185  ENV LC_ALL en_US.UTF-8
186
187  RUN dnf --refresh install -y \
188      bzip2 \
189      chrpath \
190      cpio \
191      diffstat \
192      findutils \
193      gcc \
194      gcc-c++ \
195      git \
196      make \
197      patch \
198      perl-bignum \
199      perl-Data-Dumper \
200      perl-Thread-Queue \
201      python-devel \
202      python3-devel \
203      SDL-devel \
204      socat \
205      subversion \
206      tar \
207      texinfo \
208      wget \
209      which \
210      iputils-ping
211
212  RUN grep -q ${GROUPS} /etc/group || groupadd -g ${GROUPS} ${USER}
213  RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS} ${USER}
214
215  USER ${USER}
216  ENV HOME ${HOME}
217  RUN /bin/bash
218EOF
219)
220
221elif [[ "${distro}" == ubuntu ]]; then
222
223  if [[ -n "${http_proxy}" ]]; then
224    PROXY="RUN echo \"Acquire::http::Proxy \\"\"${http_proxy}/\\"\";\" > /etc/apt/apt.conf.d/000apt-cacher-ng-proxy"
225  fi
226
227  Dockerfile=$(cat << EOF
228  FROM ${DOCKER_BASE}${distro}:${img_tag}
229
230  ${PROXY}
231
232  ENV DEBIAN_FRONTEND noninteractive
233
234  RUN apt-get update && apt-get install -yy \
235      build-essential \
236      chrpath \
237      debianutils \
238      diffstat \
239      gawk \
240      git \
241      libdata-dumper-simple-perl \
242      libsdl1.2-dev \
243      libthread-queue-any-perl \
244      locales \
245      python \
246      python3 \
247      socat \
248      subversion \
249      texinfo \
250      cpio \
251      wget \
252      iputils-ping
253
254  # Set the locale
255  RUN locale-gen en_US.UTF-8
256  ENV LANG en_US.UTF-8
257  ENV LANGUAGE en_US:en
258  ENV LC_ALL en_US.UTF-8
259
260  RUN grep -q ${GROUPS} /etc/group || groupadd -g ${GROUPS} ${USER}
261  RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS} ${USER}
262
263  USER ${USER}
264  ENV HOME ${HOME}
265  RUN /bin/bash
266EOF
267)
268fi
269
270# Create the Docker run script
271export PROXY_HOST=${http_proxy/#http*:\/\/}
272export PROXY_HOST=${PROXY_HOST/%:[0-9]*}
273export PROXY_PORT=${http_proxy/#http*:\/\/*:}
274
275mkdir -p ${WORKSPACE}
276
277cat > "${WORKSPACE}"/build.sh << EOF_SCRIPT
278#!/bin/bash
279
280set -xeo pipefail
281
282# Go into the OpenBMC directory, the build will handle changing directories
283cd ${obmc_dir}
284
285# Set up proxies
286export ftp_proxy=${http_proxy}
287export http_proxy=${http_proxy}
288export https_proxy=${http_proxy}
289
290mkdir -p ${WORKSPACE}/bin
291
292# Configure proxies for BitBake
293if [[ -n "${http_proxy}" ]]; then
294
295  cat > ${WORKSPACE}/bin/git-proxy << \EOF_GIT
296  #!/bin/bash
297  # \$1 = hostname, \$2 = port
298  PROXY=${PROXY_HOST}
299  PROXY_PORT=${PROXY_PORT}
300  exec socat STDIO PROXY:\${PROXY}:\${1}:\${2},proxyport=\${PROXY_PORT}
301EOF_GIT
302
303  chmod a+x ${WORKSPACE}/bin/git-proxy
304  export PATH=${WORKSPACE}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}
305  git config core.gitProxy git-proxy
306
307  mkdir -p ~/.subversion
308
309  cat > ~/.subversion/servers << EOF_SVN
310  [global]
311  http-proxy-host = ${PROXY_HOST}
312  http-proxy-port = ${PROXY_PORT}
313EOF_SVN
314fi
315
316# Source our build env
317${BITBAKE_CMD}
318
319# Change MACHINE name when given for build target
320if [[ -n "${MACHINE}" ]]; then
321  sed "s/^MACHINE\ ??=.*/MACHINE\ ??=\ \"${MACHINE}\"/" -i conf/local.conf
322fi
323
324# Custom BitBake config settings
325cat >> conf/local.conf << EOF_CONF
326BB_NUMBER_THREADS = "$(nproc)"
327PARALLEL_MAKE = "-j$(nproc)"
328INHERIT += "rm_work"
329BB_GENERATE_MIRROR_TARBALLS = "1"
330DL_DIR="${ssc_dir}/bitbake_downloads"
331SSTATE_DIR="${ssc_dir}/bitbake_sharedstatecache"
332USER_CLASSES += "buildstats"
333INHERIT_remove = "uninative"
334TMPDIR="${build_dir}"
335EOF_CONF
336
337# Kick off a build
338bitbake ${BITBAKE_OPTS} obmc-phosphor-image
339
340# Copy internal build directory into xtrct_path directory
341if [[ ${xtrct_small_copy_dir} ]]; then
342  mkdir -p ${xtrct_path}/${xtrct_small_copy_dir}
343  timeout ${xtrct_copy_timeout} cp -r ${build_dir}/${xtrct_small_copy_dir}/* ${xtrct_path}/${xtrct_small_copy_dir}
344else
345  timeout ${xtrct_copy_timeout} cp -r ${build_dir}/* ${xtrct_path}
346fi
347
348if [[ 0 -ne $? ]]; then
349  echo "Received a non-zero exit code from timeout"
350  exit 1
351fi
352
353EOF_SCRIPT
354
355chmod a+x ${WORKSPACE}/build.sh
356
357# Give the Docker image a name based on the distro,tag,arch,and target
358img_name=${img_name:-openbmc/${distro}:${img_tag}-${target}-${ARCH}}
359
360# Build the Docker image
361docker build -t ${img_name} - <<< "${Dockerfile}"
362
363# Determine if the build container will be launched with Docker or Kubernetes
364if [[ "${launch}" == "" ]]; then
365
366  # If obmc_dir or ssc_dir are ${HOME} or a subdirectory they will not be mounted
367  mount_obmc_dir="-v ""${obmc_dir}"":""${obmc_dir}"" "
368  mount_ssc_dir="-v ""${ssc_dir}"":""${ssc_dir}"" "
369  if [[ "${obmc_dir}" = "${HOME}/"* || "${obmc_dir}" = "${HOME}" ]];then
370    mount_obmc_dir=""
371  fi
372  if [[ "${ssc_dir}" = "${HOME}/"* || "${ssc_dir}" = "${HOME}" ]];then
373    mount_ssc_dir=""
374  fi
375
376  # Run the Docker container, execute the build.sh script
377  docker run \
378  --cap-add=sys_admin \
379  --net=host \
380  --rm=true \
381  -e WORKSPACE=${WORKSPACE} \
382  -w "${HOME}" \
383  -v "${HOME}":"${HOME}" \
384  ${mount_obmc_dir} \
385  ${mount_ssc_dir} \
386  --cpus="$num_cpu" \
387  -t ${img_name} \
388  ${WORKSPACE}/build.sh
389
390elif [[ "${launch}" == "job" || "${launch}" == "pod" ]]; then
391
392  # Source and run the helper script to launch the pod or job
393  . ${build_scripts_dir}/kubernetes/kubernetes-launch.sh OpenBMC-build true true
394
395else
396  echo "Launch Parameter is invalid"
397fi
398
399# To maintain function of resources that used an older path, add a link
400ln -sf ${xtrct_path}/deploy ${WORKSPACE}/deploy
401
402# Timestamp for build
403echo "Build completed, $(date)"
404