From 376593eb3ec9453cf5faa6ac16990ed8beb18faf Mon Sep 17 00:00:00 2001 From: Alex Huszagh Date: Fri, 1 Jul 2022 09:41:05 -0500 Subject: [PATCH] Add dockerfile for cross. This uses the installs Docker from the official sources using the latest Ubuntu image stable, and installs the latest stable Rust version internally. Cross is installed from the latest git (locked), which when tagged will work well with our releases. It exports the environment variable `CROSS_CONTAINER_IN_CONTAINER` so everything should work as expected. --- .github/workflows/ci.yml | 10 +++++++++- CHANGELOG.md | 1 + ci/test-cross-image.sh | 26 ++++++++++++++++++++++++++ docker/Dockerfile.cross | 22 ++++++++++++++++++++++ docker/cross.sh | 24 ++++++++++++++++++++++++ xtask/src/build_docker_image.rs | 9 +++++++-- xtask/src/ci.rs | 14 ++++++++++---- xtask/src/util.rs | 10 ++++++++++ 8 files changed, 109 insertions(+), 7 deletions(-) create mode 100755 ci/test-cross-image.sh create mode 100644 docker/Dockerfile.cross create mode 100755 docker/cross.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f535b5f1a..715269afc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -207,6 +207,7 @@ jobs: - { target: thumbv7em-none-eabi, os: ubuntu-latest, std: 1 } - { target: thumbv7em-none-eabihf, os: ubuntu-latest, std: 1 } - { target: thumbv7m-none-eabi, os: ubuntu-latest, std: 1 } + - { target: cross, os: ubuntu-latest } build: name: target (${{ matrix.pretty }},${{ matrix.os }}) @@ -283,7 +284,7 @@ jobs: IMAGE: ${{ steps.build-docker-image.outputs.image }} shell: bash - name: Test Image - if: steps.prepare-meta.outputs.has-image + if: steps.prepare-meta.outputs.has-image && steps.prepare-meta.outputs.test-variant == 'default' run: ./ci/test.sh env: TARGET: ${{ matrix.target }} @@ -300,6 +301,13 @@ jobs: target: ${{ matrix.target }} image: ${{ steps.build-docker-image.outputs.image }} + - name: Test Cross Image + if: steps.prepare-meta.outputs.has-image && steps.prepare-meta.outputs.test-variant == 'cross' + run: ./ci/test-cross-image.sh + env: + TARGET: 'aarch64-unknown-linux-gnu' + shell: bash + - name: Login to GitHub Container Registry if: steps.prepare-meta.outputs.has-image uses: docker/login-action@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6db56e71a..ba3e71345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #900 - add the option to skip copying build artifacts back to host when using remote cross via `CROSS_REMOTE_SKIP_BUILD_ARTIFACTS`. - #891 - support custom user namespace overrides by setting the `CROSS_CONTAINER_USER_NAMESPACE` environment variable. - #890 - support rootless docker via the `CROSS_ROOTLESS_CONTAINER_ENGINE` environment variable. +- #878 - added an image `ghcr.io/cross-rs/cross` containing cross. ### Changed diff --git a/ci/test-cross-image.sh b/ci/test-cross-image.sh new file mode 100755 index 000000000..d94f7b814 --- /dev/null +++ b/ci/test-cross-image.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2086 + +set -x +set -eo pipefail + +if [[ -z "${TARGET}" ]]; then + export TARGET="aarch64-unknown-linux-gnu" +fi +if [[ -z "${CROSS_TARGET_CROSS_IMAGE}" ]]; then + CROSS_TARGET_CROSS_IMAGE="ghcr.io/cross-rs/cross:main" +fi + +main() { + docker run --rm -e TARGET \ + -v /var/run/docker.sock:/var/run/docker.sock \ + "${CROSS_TARGET_CROSS_IMAGE}" sh -c ' +#!/usr/bin/env sh +td="$(mktemp -d)" +git clone --depth 1 https://github.com/cross-rs/rust-cpp-hello-word "${td}" +cd "${td}" +cross run --target "${TARGET}" +' +} + +main "${@}" diff --git a/docker/Dockerfile.cross b/docker/Dockerfile.cross new file mode 100644 index 000000000..bb0fd55d7 --- /dev/null +++ b/docker/Dockerfile.cross @@ -0,0 +1,22 @@ +FROM ubuntu:20.04 as rust +ARG DEBIAN_FRONTEND=noninteractive +COPY docker/lib.sh docker/cross.sh / +COPY ./ /project +RUN /cross.sh /project + +# we build our images in 2 steps, to ensure we have a compact +# image, since we want to add our current subdirectory +FROM ubuntu:20.04 +COPY --from=rust /root/.cargo /root/.cargo +COPY --from=rust /root/.rustup /root/.rustup + +# need some basic devtools, and requirements for docker +RUN apt-get update && apt-get install --assume-yes --no-install-recommends \ + ca-certificates \ + curl \ + git + +RUN curl -fsSL https://get.docker.com | sh + +ENV CROSS_CONTAINER_IN_CONTAINER=1 \ + PATH=/root/.cargo/bin:$PATH diff --git a/docker/cross.sh b/docker/cross.sh new file mode 100755 index 000000000..aef03add0 --- /dev/null +++ b/docker/cross.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1090,SC1091 + +set -x +set -euo pipefail + +. lib.sh + +main() { + local project_dir="${1}" + + install_packages ca-certificates curl gcc libc6-dev + + cd "${project_dir}" + curl --proto "=https" --tlsv1.2 --retry 3 -sSfL https://sh.rustup.rs | sh -s -- -y + source "${HOME}"/.cargo/env + cargo install --path . --locked + + purge_packages + + rm -rf "${0}" +} + +main "${@}" diff --git a/xtask/src/build_docker_image.rs b/xtask/src/build_docker_image.rs index eacaf171d..d6828927d 100644 --- a/xtask/src/build_docker_image.rs +++ b/xtask/src/build_docker_image.rs @@ -144,7 +144,8 @@ pub fn build_docker_image( } } let gha = std::env::var("GITHUB_ACTIONS").is_ok(); - let docker_root = metadata.workspace_root.join("docker"); + let root = metadata.workspace_root; + let docker_root = root.join("docker"); let cross_toolchains_root = docker_root.join("cross-toolchains").join("docker"); let targets = targets .into_iter() @@ -237,7 +238,11 @@ pub fn build_docker_image( docker_build.args(&["--build-arg", arg]); } - docker_build.arg("."); + if target.needs_workspace_root_context() { + docker_build.arg(&root); + } else { + docker_build.arg("."); + } if !dry_run && (force || !push || gha) { let result = docker_build.run(msg_info, false); diff --git a/xtask/src/ci.rs b/xtask/src/ci.rs index d32b2c02f..125fc8777 100644 --- a/xtask/src/ci.rs +++ b/xtask/src/ci.rs @@ -40,10 +40,11 @@ pub fn ci(args: CiJob, metadata: CargoMetadata) -> cross::Result<()> { // Set labels let mut labels = vec![]; - labels.push(format!( - "org.opencontainers.image.title=cross (for {})", - target.triplet - )); + let image_title = match target.triplet.as_ref() { + "cross" => target.triplet.to_string(), + _ => format!("cross (for {})", target.triplet), + }; + labels.push(format!("org.opencontainers.image.title={image_title}")); labels.push(format!( "org.opencontainers.image.licenses={}", cross_meta.license.as_deref().unwrap_or_default() @@ -69,6 +70,11 @@ pub fn ci(args: CiJob, metadata: CargoMetadata) -> cross::Result<()> { if target.has_ci_image() { gha_output("has-image", "true") } + if target.is_default_test_image() { + gha_output("test-variant", "default") + } else { + gha_output("test-variant", &target.triplet) + } } CiJob::Check { ref_type, ref_name } => { let version = semver::Version::parse(&cross_meta.version)?; diff --git a/xtask/src/util.rs b/xtask/src/util.rs index 8eafeb3a0..312f1aada 100644 --- a/xtask/src/util.rs +++ b/xtask/src/util.rs @@ -129,6 +129,16 @@ impl ImageTarget { .iter() .any(|m| m.builds_image() && m.target == self.triplet && m.sub == self.sub) } + + /// Determine if this target uses the default test script + pub fn is_default_test_image(&self) -> bool { + self.triplet != "cross" + } + + /// Determine if this target needs to interact with the project root. + pub fn needs_workspace_root_context(&self) -> bool { + self.triplet == "cross" + } } impl std::str::FromStr for ImageTarget {