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