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