From d40229da37d4ebeb3834f6f6e57f6615b66b56bb Mon Sep 17 00:00:00 2001 From: Barret Rennie Date: Wed, 20 Sep 2023 14:29:15 -0400 Subject: [PATCH] Build linux nimbus binaries with Ubuntu 20.04 This introduces a second docker image based on Ubuntu 20.04 to build nimbus-fml and nimbus-cli for the x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu targets. The regular container uses a newer version of Ubuntu (22.04) which has a newer version of glibc, which makes the binaries harder to distribute. Building with an older version of glibc means that the *-unknown-linux-gnu binaries can be used by @mozilla/experimenter. --- install-nimbus-cli.sh | 8 +- .../transforms/nimbus.py | 23 ++++- taskcluster/ci/docker-image/kind.yml | 1 + taskcluster/ci/nimbus-build/kind.yml | 16 +++- taskcluster/docker/linux2004/Dockerfile | 86 +++++++++++++++++++ taskcluster/scripts/nimbus-build.py | 8 +- .../scripts/toolchain/build-rust-toolchain.sh | 1 + 7 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 taskcluster/docker/linux2004/Dockerfile diff --git a/install-nimbus-cli.sh b/install-nimbus-cli.sh index 3b996e571..9f75ebc71 100755 --- a/install-nimbus-cli.sh +++ b/install-nimbus-cli.sh @@ -85,6 +85,7 @@ initTargetBinary() { "aarch64-darwin") file="aarch64-apple-darwin" ;; "x86_64-windows") file="x86_64-pc-windows-gnu" ;; "x86_64-linux") file="x86_64-unknown-linux-musl" ;; + "aarch64-linux") file="aarch64-unknown-linux-gnu" ;; *) fail_target "$ARCH-$OS" ;; @@ -99,7 +100,8 @@ check_target() { "aarch64-apple-darwin" |\ "x86_64-pc-windows-gnu" |\ "x86_64-unknown-linux-gnu" |\ - "x86_64-unknown-linux-musl") + "x86_64-unknown-linux-musl" |\ + "aarch64-unknown-linux-gnu") ;; *) fail_target "$TARGET" @@ -111,6 +113,7 @@ fail_target() { echoError "No pre-built binary for $1." echo -e " Available pre-built binaries are:" echo -e " aarch64-apple-darwin" + echo -e " aarch64-unknown-linux-gnu" echo -e " x86_64-apple-darwin" echo -e " x86_64-pc-windows-gnu" echo -e " x86_64-unknown-linux-gnu" @@ -252,7 +255,8 @@ help () { echo -e "\t--host HOST get from the given taskcluster host" echo -e "\t--binary|-B BINARY the binary that is installed, leave blank to derive a default" echo -e " try: x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl," - echo -e " x86_64-pc-windows-gnu, x86_64-apple-darwin, aarch64-apple-darwin" + echo -e " x86_64-pc-windows-gnu, x86_64-apple-darwin, aarch64-apple-darwin," + echo -e " aarch64-unknown-linux-gnu" echo echo -e "\t--debug be verbose in output" echo -e "\t--help|-h prints this help" diff --git a/taskcluster/app_services_taskgraph/transforms/nimbus.py b/taskcluster/app_services_taskgraph/transforms/nimbus.py index 5706466ce..3134fb627 100644 --- a/taskcluster/app_services_taskgraph/transforms/nimbus.py +++ b/taskcluster/app_services_taskgraph/transforms/nimbus.py @@ -5,6 +5,18 @@ from collections import namedtuple from taskgraph.transforms.base import TransformSequence +LINUX_BUILD_TARGETS = ( + 'aarch64-unknown-linux-gnu', + 'x86_64-unknown-linux-gnu', + 'x86_64-unknown-linux-musl', + 'x86_64-pc-windows-gnu', +) + +MAC_BUILD_TARGETS = ( + 'x86_64-apple-darwin', + 'aarch64-apple-darwin', +) + # Transform for the nimbus-build tasks build = TransformSequence() @@ -13,20 +25,25 @@ def setup_build_tasks(config, tasks): for task in tasks: binary = task['attributes']['binary'] target = task['attributes']['target'] - if target in ('x86_64-unknown-linux-gnu', 'x86_64-unknown-linux-musl', 'x86_64-pc-windows-gnu'): + if target in LINUX_BUILD_TARGETS: setup_linux_build_task(task, target, binary) - elif target in ('x86_64-apple-darwin', 'aarch64-apple-darwin'): + elif target in MAC_BUILD_TARGETS: setup_mac_build_task(task, target, binary) else: raise ValueError(f"Unknown target for nimbus build task: {target}") yield task def setup_linux_build_task(task, target, binary): + docker_image = 'linux' + + if target in ('aarch64-unknown-linux-gnu', 'x86_64-unknown-linux-gnu'): + docker_image = 'linux2004' + task['description'] = f'Build {binary} ({target})' task['worker-type'] = 'b-linux' task['worker'] = { 'max-run-time': 1800, - 'docker-image': { 'in-tree': 'linux' }, + 'docker-image': { 'in-tree': docker_image }, 'artifacts': [ { 'name': f'public/build/{binary}-{target}.zip', diff --git a/taskcluster/ci/docker-image/kind.yml b/taskcluster/ci/docker-image/kind.yml index 109b2e9dc..0624e994e 100644 --- a/taskcluster/ci/docker-image/kind.yml +++ b/taskcluster/ci/docker-image/kind.yml @@ -12,3 +12,4 @@ transforms: tasks: linux: {} + linux2004: {} diff --git a/taskcluster/ci/nimbus-build/kind.yml b/taskcluster/ci/nimbus-build/kind.yml index 52e2fc0eb..fa8957d08 100644 --- a/taskcluster/ci/nimbus-build/kind.yml +++ b/taskcluster/ci/nimbus-build/kind.yml @@ -23,11 +23,16 @@ task-defaults: - project:releng:services/tooltool/api/download/internal tasks: - fml-linux: + fml-linux-x86_64-musl: attributes: target: x86_64-unknown-linux-musl binary: nimbus-fml + fml-linux-aarch64-gnu: + attributes: + target: aarch64-unknown-linux-gnu + binary: nimbus-fml + fml-windows: attributes: target: x86_64-pc-windows-gnu @@ -43,12 +48,17 @@ tasks: target: aarch64-apple-darwin binary: nimbus-fml - cli-linux-gnu: + cli-linux-aarch64-gnu: + attributes: + target: aarch64-unknown-linux-gnu + binary: nimbus-cli + + cli-linux-x86_64-gnu: attributes: target: x86_64-unknown-linux-gnu binary: nimbus-cli - cli-linux-musl: + cli-linux-x86_64-musl: attributes: target: x86_64-unknown-linux-musl binary: nimbus-cli diff --git a/taskcluster/docker/linux2004/Dockerfile b/taskcluster/docker/linux2004/Dockerfile new file mode 100644 index 000000000..27adde793 --- /dev/null +++ b/taskcluster/docker/linux2004/Dockerfile @@ -0,0 +1,86 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This is intended to be a minimal Dockerfile only to build nimbus-fml and +# nimbus-cli with an older version of glibc. + +FROM ubuntu:20.04 + +# Add worker user + +RUN mkdir /builds && \ + useradd -d /builds/worker -s /bin/bash -m worker && \ + chown worker:worker /builds/worker && \ + mkdir /builds/worker/artifacts && \ + chown worker:worker /builds/worker/artifacts + +WORKDIR /builds/worker/ + +# Set up the language variables to avoid problems (we run locale-gen later). +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +# Do not use fancy output on taskcluster +ENV TERM dumb + +# Used to detect in scripts whether we are running on taskcluster +ENV CI 1 +ENV CI_TASKCLUSTER true + +ENV \ + # Some APT packages like 'tzdata' wait for user input on install by default. + # https://stackoverflow.com/questions/44331836/apt-get-install-tzdata-noninteractive + DEBIAN_FRONTEND=noninteractive + +RUN apt-get update -qq \ + && apt-get install -qy --no-install-recommends \ + python3 \ + python3-pip \ + ########################## + # CI-specific dependencies + ########################## + git \ + curl \ + # Will set up the timezone to UTC (?). + tzdata \ + # To install UTF-8 locales. + locales \ + # Required to rsync the `libs` folder after fetch (see taskcluster/ci/android-build/kind.yml) + rsync \ + # Required for creating a venv for glean_parser + python3-venv \ + # Required to zip targets after build + zip \ + # Required to build nimbus-cli and nimbus-fml + build-essential \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + binutils-aarch64-linux-gnu \ + && apt-get clean + +RUN pip3 install --upgrade pip +RUN pip3 install \ + pyyaml \ + toml \ + taskcluster + +# tooltool +RUN \ + curl -sfSL --retry 5 --retry-delay 10 \ + -o /usr/local/bin/tooltool.py \ + https://raw.githubusercontent.com/mozilla-releng/tooltool/master/client/tooltool.py && \ + chmod +x /usr/local/bin/tooltool.py + +# %include-run-task + +ENV SHELL=/bin/bash \ + HOME=/builds/worker \ + PATH=/builds/worker/.local/bin:$PATH + +VOLUME /builds/worker/checkouts +VOLUME /builds/worker/.cache + +# run-task needs to run as root (after initialization, it changes to `worker`) +USER root diff --git a/taskcluster/scripts/nimbus-build.py b/taskcluster/scripts/nimbus-build.py index 453ad5993..df5d6404d 100755 --- a/taskcluster/scripts/nimbus-build.py +++ b/taskcluster/scripts/nimbus-build.py @@ -14,9 +14,15 @@ def main(): os.makedirs(args.out_dir, exist_ok=True) filename = f'{binary}.exe' if '-windows-' in target else binary + env = os.environ + + if target == 'aarch64-unknown-linux-gnu': + env = os.environ.copy() + env['RUSTFLAGS'] = '-C linker=aarch64-linux-gnu-gcc' + subprocess.check_call([ 'cargo', 'build', '--bin', binary, '--release', '--target', target, - ]) + ], env=env) subprocess.check_call([ 'zip', '-r', f'../build/{binary}-{target}.zip', pathlib.Path(target).joinpath('release', filename), diff --git a/taskcluster/scripts/toolchain/build-rust-toolchain.sh b/taskcluster/scripts/toolchain/build-rust-toolchain.sh index c29236452..3635332c3 100755 --- a/taskcluster/scripts/toolchain/build-rust-toolchain.sh +++ b/taskcluster/scripts/toolchain/build-rust-toolchain.sh @@ -30,6 +30,7 @@ rustup --version rustup target add x86_64-apple-darwin rustup target add x86_64-pc-windows-gnu rustup target add x86_64-unknown-linux-musl +rustup target add aarch64-unknown-linux-gnu rustup target add aarch64-unknown-linux-musl # Tar everything into UPLOAD_DIR