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 "aarch64") 127 DOCKER_BASE="arm64v8/" 128 ;; 129 *) 130 echo "Unsupported system architecture(${ARCH}) found for docker image" 131 exit 1 132esac 133 134# Timestamp for job 135echo "Build started, $(date)" 136 137# If the obmc_dir directory doesn't exist clone it in 138if [ ! -d "${obmc_dir}" ]; then 139 echo "Clone in openbmc master to ${obmc_dir}" 140 git clone https://github.com/openbmc/openbmc "${obmc_dir}" 141fi 142 143if [[ "$target" = repotest ]]; then 144 DOCKER_IMAGE_NAME=$(./scripts/build-unit-test-docker) 145 docker run --cap-add=sys_admin --rm=true \ 146 --network host \ 147 --privileged=true \ 148 -u "$USER" \ 149 -w "${obmc_dir}" -v "${obmc_dir}:${obmc_dir}" \ 150 -t "${DOCKER_IMAGE_NAME}" \ 151 "${obmc_dir}"/meta-phosphor/scripts/run-repotest 152 exit 153fi 154 155# Make and chown the xtrct_path directory to avoid permission errors 156if [ ! -d "${xtrct_path}" ]; then 157 mkdir -p "${xtrct_path}" 158fi 159chown "${UID}:${GROUPS[0]}" "${xtrct_path}" 160 161# Perform overrides for specific machines as required. 162DISTRO=${DISTRO:-} 163 164# Set build target and BitBake command 165MACHINE="${target}" 166BITBAKE_CMD="source ./setup ${MACHINE} ${build_dir}" 167 168# Configure Docker build 169if [[ "${distro}" == fedora ]];then 170 171 if [[ -n "${http_proxy}" ]]; then 172 PROXY="RUN echo \"proxy=${http_proxy}\" >> /etc/dnf/dnf.conf" 173 fi 174 175 Dockerfile=$(cat << EOF 176 FROM ${DOCKER_BASE}${distro}:${img_tag} 177 178 ${PROXY} 179 180 RUN dnf --refresh install -y \ 181 bzip2 \ 182 chrpath \ 183 cpio \ 184 diffstat \ 185 findutils \ 186 gcc \ 187 gcc-c++ \ 188 git \ 189 make \ 190 patch \ 191 perl-bignum \ 192 perl-Data-Dumper \ 193 perl-Thread-Queue \ 194 python-devel \ 195 python3-devel \ 196 SDL-devel \ 197 socat \ 198 subversion \ 199 tar \ 200 texinfo \ 201 wget \ 202 which \ 203 file \ 204 hostname \ 205 rpcgen \ 206 glibc-langpack-en \ 207 glibc-locale-source 208 209 # Set the locale 210 ENV LANG=en_US.utf8 211 RUN localedef -f UTF-8 -i en_US en_US.UTF-8 212 213 RUN grep -q ${GROUPS[0]} /etc/group || groupadd -g ${GROUPS[0]} ${USER} 214 RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS[0]} ${USER} 215 216 USER ${USER} 217 ENV HOME ${HOME} 218 RUN /bin/bash 219EOF 220) 221 222elif [[ "${distro}" == ubuntu ]]; then 223 224 if [[ -n "${http_proxy}" ]]; then 225 PROXY="RUN echo \"Acquire::http::Proxy \\"\"${http_proxy}/\\"\";\" > /etc/apt/apt.conf.d/000apt-cacher-ng-proxy" 226 fi 227 228 Dockerfile=$(cat << EOF 229 FROM ${DOCKER_BASE}${distro}:${img_tag} 230 231 ${PROXY} 232 ${MIRROR} 233 234 ENV DEBIAN_FRONTEND noninteractive 235 236 RUN apt-get update && apt-get install -yy \ 237 build-essential \ 238 chrpath \ 239 cpio \ 240 debianutils \ 241 diffstat \ 242 gawk \ 243 git \ 244 iputils-ping \ 245 libdata-dumper-simple-perl \ 246 liblz4-tool \ 247 libsdl1.2-dev \ 248 libthread-queue-any-perl \ 249 locales \ 250 python \ 251 python3 \ 252 socat \ 253 subversion \ 254 texinfo \ 255 wget \ 256 zstd 257 258 # Set the locale 259 RUN locale-gen en_US.UTF-8 260 ENV LANG en_US.UTF-8 261 ENV LANGUAGE en_US:en 262 ENV LC_ALL en_US.UTF-8 263 264 RUN grep -q ${GROUPS[0]} /etc/group || groupadd -g ${GROUPS[0]} ${USER} 265 RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS[0]} ${USER} 266 267 USER ${USER} 268 ENV HOME ${HOME} 269 RUN /bin/bash 270EOF 271) 272fi 273 274# Create the Docker run script 275export PROXY_HOST=${http_proxy/#http*:\/\/} 276export PROXY_HOST=${PROXY_HOST/%:[0-9]*} 277export PROXY_PORT=${http_proxy/#http*:\/\/*:} 278 279mkdir -p "${WORKSPACE}" 280 281# Determine command for bitbake image build 282if [ "$no_tar" = "false" ]; then 283 bitbake_target="${bitbake_target} obmc-phosphor-debug-tarball" 284fi 285 286cat > "${WORKSPACE}"/build.sh << EOF_SCRIPT 287#!/bin/bash 288 289set -xeo pipefail 290 291# Go into the OpenBMC directory, the build will handle changing directories 292cd ${obmc_dir} 293 294# Set up proxies 295export ftp_proxy=${http_proxy} 296export http_proxy=${http_proxy} 297export https_proxy=${http_proxy} 298 299mkdir -p ${WORKSPACE}/bin 300 301# Configure proxies for BitBake 302if [[ -n "${http_proxy}" ]]; then 303 304 cat > ${WORKSPACE}/bin/git-proxy << \EOF_GIT 305 #!/bin/bash 306 # \$1 = hostname, \$2 = port 307 PROXY=${PROXY_HOST} 308 PROXY_PORT=${PROXY_PORT} 309 exec socat STDIO PROXY:\${PROXY}:\${1}:\${2},proxyport=\${PROXY_PORT} 310EOF_GIT 311 312 chmod a+x ${WORKSPACE}/bin/git-proxy 313 export PATH=${WORKSPACE}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH} 314 315 lock=${HOME}/build-setup.lock 316 flock \${lock} git config --global core.gitProxy ${WORKSPACE}/bin/git-proxy 317 flock \${lock} git config --global http.proxy ${http_proxy} 318 319 flock \${lock} mkdir -p ~/.subversion 320 flock \${lock} cat > ~/.subversion/servers << EOF_SVN 321 [global] 322 http-proxy-host = ${PROXY_HOST} 323 http-proxy-port = ${PROXY_PORT} 324EOF_SVN 325 326 flock \${lock} cat > ~/.wgetrc << EOF_WGETRC 327 https_proxy = ${http_proxy} 328 http_proxy = ${http_proxy} 329 use_proxy = on 330EOF_WGETRC 331 332 flock \${lock} cat > ~/.curlrc << EOF_CURLRC 333 proxy = ${PROXY_HOST}:${PROXY_PORT} 334EOF_CURLRC 335fi 336 337# Source our build env 338${BITBAKE_CMD} 339 340if [[ -z "${MACHINE}" ]]; then 341 echo "MACHINE is not configured for ${target}" 342 exit 1 343fi 344 345export MACHINE="${MACHINE}" 346if [[ -z "${DISTRO}" ]]; then 347 echo "DISTRO is not configured for ${target} so will use default" 348 unset DISTRO 349else 350 export DISTRO="${DISTRO}" 351fi 352 353# bitbake requires SDKMACHINE be x86 354export SDKMACHINE=x86_64 355 356# Custom BitBake config settings 357cat >> conf/local.conf << EOF_CONF 358BB_NUMBER_THREADS = "$(nproc)" 359PARALLEL_MAKE = "-j$(nproc)" 360INHERIT += "rm_work" 361BB_GENERATE_MIRROR_TARBALLS = "1" 362DL_DIR="${ssc_dir}/bitbake_downloads" 363SSTATE_DIR="${ssc_dir}/bitbake_sharedstatecache" 364USER_CLASSES += "buildstats" 365INHERIT:remove = "uninative" 366TMPDIR="${build_dir}" 367${ENV_LOCAL_CONF} 368EOF_CONF 369 370# Kick off a build 371if [[ -n "${nice_priority}" ]]; then 372 nice -${nice_priority} bitbake ${BITBAKE_OPTS} ${bitbake_target} 373else 374 bitbake ${BITBAKE_OPTS} ${bitbake_target} 375fi 376 377# Copy internal build directory into xtrct_path directory 378if [[ ${xtrct_small_copy_dir} ]]; then 379 mkdir -p ${xtrct_path}/${xtrct_small_copy_dir} 380 timeout ${xtrct_copy_timeout} cp -r ${build_dir}/${xtrct_small_copy_dir}/* ${xtrct_path}/${xtrct_small_copy_dir} 381else 382 timeout ${xtrct_copy_timeout} cp -r ${build_dir}/* ${xtrct_path} 383fi 384 385if [[ 0 -ne $? ]]; then 386 echo "Received a non-zero exit code from timeout" 387 exit 1 388fi 389 390EOF_SCRIPT 391 392chmod a+x "${WORKSPACE}/build.sh" 393 394# Give the Docker image a name based on the distro,tag,arch,and target 395img_name=${img_name:-openbmc/${distro}:${img_tag}-${target}-${ARCH}} 396 397# Build the Docker image 398docker build -t "${img_name}" - <<< "${Dockerfile}" 399 400# If obmc_dir or ssc_dir are ${HOME} or a subdirectory they will not be mounted 401mount_obmc_dir="-v ""${obmc_dir}"":""${obmc_dir}"" " 402mount_ssc_dir="-v ""${ssc_dir}"":""${ssc_dir}"" " 403mount_workspace_dir="-v ""${WORKSPACE}"":""${WORKSPACE}"" " 404if [[ "${obmc_dir}" = "${HOME}/"* || "${obmc_dir}" = "${HOME}" ]];then 405mount_obmc_dir="" 406fi 407if [[ "${ssc_dir}" = "${HOME}/"* || "${ssc_dir}" = "${HOME}" ]];then 408mount_ssc_dir="" 409fi 410if [[ "${WORKSPACE}" = "${HOME}/"* || "${WORKSPACE}" = "${HOME}" ]];then 411mount_workspace_dir="" 412fi 413 414# Run the Docker container, execute the build.sh script 415# shellcheck disable=SC2086 # mount commands word-split purposefully 416docker run \ 417--cap-add=sys_admin \ 418--cap-add=sys_nice \ 419--net=host \ 420--rm=true \ 421-e WORKSPACE="${WORKSPACE}" \ 422-w "${HOME}" \ 423-v "${HOME}:${HOME}" \ 424${mount_obmc_dir} \ 425${mount_ssc_dir} \ 426${mount_workspace_dir} \ 427--cpus="$num_cpu" \ 428"${img_name}" \ 429"${WORKSPACE}/build.sh" 430 431# To maintain function of resources that used an older path, add a link 432ln -sf "${xtrct_path}/deploy" "${WORKSPACE}/deploy" 433 434# Timestamp for build 435echo "Build completed, $(date)" 436