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