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