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 file \ 186 findutils \ 187 gcc \ 188 gcc-c++ \ 189 git \ 190 make \ 191 patch \ 192 perl-bignum \ 193 perl-Data-Dumper \ 194 perl-Thread-Queue \ 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 file \ 243 gawk \ 244 git \ 245 iputils-ping \ 246 libdata-dumper-simple-perl \ 247 liblz4-tool \ 248 libsdl1.2-dev \ 249 libthread-queue-any-perl \ 250 locales \ 251 python3 \ 252 socat \ 253 subversion \ 254 texinfo \ 255 vim \ 256 wget \ 257 zstd 258 259 # Set the locale 260 RUN locale-gen en_US.UTF-8 261 ENV LANG en_US.UTF-8 262 ENV LANGUAGE en_US:en 263 ENV LC_ALL en_US.UTF-8 264 265 RUN grep -q ${GROUPS[0]} /etc/group || groupadd -g ${GROUPS[0]} ${USER} 266 RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS[0]} ${USER} 267 268 USER ${USER} 269 ENV HOME ${HOME} 270 RUN /bin/bash 271EOF 272 ) 273fi 274 275# Create the Docker run script 276export PROXY_HOST=${http_proxy/#http*:\/\/} 277export PROXY_HOST=${PROXY_HOST/%:[0-9]*} 278export PROXY_PORT=${http_proxy/#http*:\/\/*:} 279 280mkdir -p "${WORKSPACE}" 281 282# Determine command for bitbake image build 283if [ "$no_tar" = "false" ]; then 284 bitbake_target="${bitbake_target} obmc-phosphor-debug-tarball" 285fi 286 287cat > "${WORKSPACE}"/build.sh << EOF_SCRIPT 288#!/bin/bash 289 290set -xeo pipefail 291 292# Go into the OpenBMC directory, the build will handle changing directories 293cd ${obmc_dir} 294 295# Set up proxies 296export ftp_proxy=${http_proxy} 297export http_proxy=${http_proxy} 298export https_proxy=${http_proxy} 299 300mkdir -p ${WORKSPACE}/bin 301 302# Configure proxies for BitBake 303if [[ -n "${http_proxy}" ]]; then 304 305 cat > ${WORKSPACE}/bin/git-proxy << \EOF_GIT 306 #!/bin/bash 307 # \$1 = hostname, \$2 = port 308 PROXY=${PROXY_HOST} 309 PROXY_PORT=${PROXY_PORT} 310 exec socat STDIO PROXY:\${PROXY}:\${1}:\${2},proxyport=\${PROXY_PORT} 311EOF_GIT 312 313 chmod a+x ${WORKSPACE}/bin/git-proxy 314 export PATH=${WORKSPACE}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH} 315 316 lock=${HOME}/build-setup.lock 317 flock \${lock} git config --global core.gitProxy ${WORKSPACE}/bin/git-proxy 318 flock \${lock} git config --global http.proxy ${http_proxy} 319 320 flock \${lock} mkdir -p ~/.subversion 321 flock \${lock} cat > ~/.subversion/servers << EOF_SVN 322 [global] 323 http-proxy-host = ${PROXY_HOST} 324 http-proxy-port = ${PROXY_PORT} 325EOF_SVN 326 327 flock \${lock} cat > ~/.wgetrc << EOF_WGETRC 328 https_proxy = ${http_proxy} 329 http_proxy = ${http_proxy} 330 use_proxy = on 331EOF_WGETRC 332 333 flock \${lock} cat > ~/.curlrc << EOF_CURLRC 334 proxy = ${PROXY_HOST}:${PROXY_PORT} 335EOF_CURLRC 336fi 337 338# Source our build env 339${BITBAKE_CMD} 340 341if [[ -z "${MACHINE}" ]]; then 342 echo "MACHINE is not configured for ${target}" 343 exit 1 344fi 345 346export MACHINE="${MACHINE}" 347if [[ -z "${DISTRO}" ]]; then 348 echo "DISTRO is not configured for ${target} so will use default" 349 unset DISTRO 350else 351 export DISTRO="${DISTRO}" 352fi 353 354# bitbake requires SDKMACHINE be x86 355export SDKMACHINE=x86_64 356 357# Custom BitBake config settings 358cat >> conf/local.conf << EOF_CONF 359BB_NUMBER_THREADS = "$num_cpu" 360PARALLEL_MAKE = "-j$num_cpu" 361INHERIT += "rm_work" 362BB_GENERATE_MIRROR_TARBALLS = "1" 363DL_DIR="${ssc_dir}/bitbake_downloads" 364SSTATE_DIR="${ssc_dir}/bitbake_sharedstatecache" 365USER_CLASSES += "buildstats" 366INHERIT:remove = "uninative" 367TMPDIR="${build_dir}" 368${ENV_LOCAL_CONF} 369EOF_CONF 370 371# Kick off a build 372if [[ -n "${nice_priority}" ]]; then 373 nice -${nice_priority} bitbake -k ${BITBAKE_OPTS} ${bitbake_target} 374else 375 bitbake -k ${BITBAKE_OPTS} ${bitbake_target} 376fi 377 378# Copy internal build directory into xtrct_path directory 379if [[ ${xtrct_small_copy_dir} ]]; then 380 mkdir -p ${xtrct_path}/${xtrct_small_copy_dir} 381 timeout ${xtrct_copy_timeout} cp -r ${build_dir}/${xtrct_small_copy_dir}/* ${xtrct_path}/${xtrct_small_copy_dir} 382else 383 timeout ${xtrct_copy_timeout} cp -r ${build_dir}/* ${xtrct_path} 384fi 385 386if [[ 0 -ne $? ]]; then 387 echo "Received a non-zero exit code from timeout" 388 exit 1 389fi 390 391EOF_SCRIPT 392 393chmod a+x "${WORKSPACE}/build.sh" 394 395# Give the Docker image a name based on the distro,tag,arch,and target 396img_name=${img_name:-openbmc/${distro}:${img_tag}-${target}-${ARCH}} 397 398# Ensure appropriate docker build output to see progress and identify 399# any issues 400export BUILDKIT_PROGRESS=plain 401 402# Build the Docker image 403docker build -t "${img_name}" - <<< "${Dockerfile}" 404 405# If obmc_dir or ssc_dir are ${HOME} or a subdirectory they will not be mounted 406mount_obmc_dir="-v ""${obmc_dir}"":""${obmc_dir}"" " 407mount_ssc_dir="-v ""${ssc_dir}"":""${ssc_dir}"" " 408mount_workspace_dir="-v ""${WORKSPACE}"":""${WORKSPACE}"" " 409if [[ "${obmc_dir}" = "${HOME}/"* || "${obmc_dir}" = "${HOME}" ]];then 410 mount_obmc_dir="" 411fi 412if [[ "${ssc_dir}" = "${HOME}/"* || "${ssc_dir}" = "${HOME}" ]];then 413 mount_ssc_dir="" 414fi 415if [[ "${WORKSPACE}" = "${HOME}/"* || "${WORKSPACE}" = "${HOME}" ]];then 416 mount_workspace_dir="" 417fi 418 419# If we are building on a podman based machine, need to have this set in 420# the env to allow the home mount to work (no impact on non-podman systems) 421export PODMAN_USERNS="keep-id" 422 423# Run the Docker container, execute the build.sh script 424# shellcheck disable=SC2086 # mount commands word-split purposefully 425docker run \ 426 --cap-add=sys_admin \ 427 --cap-add=sys_nice \ 428 --net=host \ 429 --rm=true \ 430 -e WORKSPACE="${WORKSPACE}" \ 431 -w "${HOME}" \ 432 -v "${HOME}:${HOME}" \ 433 ${mount_obmc_dir} \ 434 ${mount_ssc_dir} \ 435 ${mount_workspace_dir} \ 436 "${img_name}" \ 437 "${WORKSPACE}/build.sh" 438 439# To maintain function of resources that used an older path, add a link 440ln -sf "${xtrct_path}/deploy" "${WORKSPACE}/deploy" 441 442# Timestamp for build 443echo "Build completed, $(date)" 444