Skip to content

Commit

Permalink
Merge #1033
Browse files Browse the repository at this point in the history
1033: Fix image build errors with podman and nerdctl. r=Emilgardis a=Alexhuszagh

Ensures that docker and nerdctl, which support the custom `--output` and `--cache-from` flags use them, while podman and unknown container engines use the strict, minimal subset podman supports. This is because podman only supports a registry/repository, without a tag, for `--cache-from`, which means it synchronizes poorly with our target subs, like `centos`. Therefore, unless unsupported, we should always use the features available for our container engine.

This also fixes the `--pull` flag on nerdctl, which is unsupported. Engines without BuildKit extensions by default, such as nerdctl, now do not use `buildx` unless explicitly enabled with `CROSS_CONTAINER_ENGINE_NO_BUILDKIT=0`.

Closes #1031.

Co-authored-by: Alex Huszagh <[email protected]>
  • Loading branch information
bors[bot] and Alexhuszagh authored Sep 30, 2022
2 parents 5261b6a + e5d58cc commit ab01c6e
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changes/1033.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"description": "fix --cache-from using podman.",
"type": "fixed",
"issues": [1031]
}
41 changes: 40 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,45 @@ jobs:
run: ./ci/test-docker-in-docker.sh
shell: bash

podman:
name: podman
runs-on: ubuntu-latest
needs: [shellcheck, test, check]
if: github.event_name == 'push'
strategy:
fail-fast: false
outputs:
has-image: ${{ steps.prepare-meta.outputs.has-image }}
images: ${{ steps.build-docker-image.outputs.images && fromJSON(steps.build-docker-image.outputs.images) }}
coverage-artifact: ${{ steps.cov.outputs.artifact-name }}
steps:
- uses: actions/checkout@v3

- uses: ./.github/actions/setup-rust

- name: Install Podman
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update
sudo apt-get install podman --no-install-recommends --assume-yes
- name: LLVM instrument coverage
id: cov
uses: ./.github/actions/cargo-llvm-cov
with:
name: cross-podman-aarch64-unknown-linux-gnu

- name: Install cross
run: cargo install --path . --force --debug

- name: Run Podman Test
run: ./ci/test-podman.sh
env:
CROSS_CONTAINER_ENGINE: podman
TARGET: aarch64-unknown-linux-gnu
shell: bash

publish:
needs: [build, check, fmt, clippy, cargo-deny]
runs-on: ubuntu-latest
Expand All @@ -331,7 +370,7 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}

conclusion:
needs: [shellcheck, fmt, clippy, test, generate-matrix, build, publish, check, remote, bisect, docker-in-docker, foreign]
needs: [shellcheck, fmt, clippy, test, generate-matrix, build, publish, check, remote, bisect, docker-in-docker, foreign, podman]
if: always()
runs-on: ubuntu-latest
steps:
Expand Down
41 changes: 41 additions & 0 deletions ci/test-podman.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091,SC1090

# test to see that running and building images with podman works.

set -x
set -eo pipefail

export CROSS_CONTAINER_ENGINE=podman
if [[ -z "${TARGET}" ]]; then
export TARGET="aarch64-unknown-linux-gnu"
fi

ci_dir=$(dirname "${BASH_SOURCE[0]}")
ci_dir=$(realpath "${ci_dir}")
. "${ci_dir}"/shared.sh

main() {
local td=
local parent=
local target="${TARGET}"

retry cargo fetch
cargo build
export CROSS="${PROJECT_HOME}/target/debug/cross"

td="$(mkcargotemp -d)"
parent=$(dirname "${td}")
pushd "${td}"
cargo init --bin --name "hello" .

echo '[build]
pre-build = ["apt-get update"]' > "${parent}/Cross.toml"

CROSS_CONTAINER_ENGINE="${CROSS_ENGINE}" "${CROSS}" build --target "${target}" --verbose

popd
rm -rf "${td}"
}

main
30 changes: 28 additions & 2 deletions src/docker/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,45 @@ pub enum EngineType {
Docker,
Podman,
PodmanRemote,
Nerdctl,
Other,
}

impl EngineType {
/// Returns `true` if the engine type is [`Podman`](Self::Podman) or [`PodmanRemote`](Self::PodmanRemote).
#[must_use]
pub fn is_podman(&self) -> bool {
pub const fn is_podman(&self) -> bool {
matches!(self, Self::Podman | Self::PodmanRemote)
}

/// Returns `true` if the engine type is [`Docker`](EngineType::Docker).
#[must_use]
pub fn is_docker(&self) -> bool {
pub const fn is_docker(&self) -> bool {
matches!(self, Self::Docker)
}

/// Returns `true` if the build command supports the `--output` flag.
#[must_use]
pub const fn supports_output_flag(&self) -> bool {
!matches!(self, Self::Other)
}

/// Returns `true` if the build command supports the `--pull` flag.
#[must_use]
pub const fn supports_pull_flag(&self) -> bool {
!matches!(self, Self::Nerdctl | Self::Other)
}

/// Returns `true` if the build command supports the `--cache-from type=` key.
///
/// Some container engines, especially podman, do not support the `type`
/// key of `--cache-from` during the image build steps. They also do
/// not support any tags for the `--cache-from` steps either. See:
/// https://docs.podman.io/en/latest/markdown/podman-build.1.html#cache-from
#[must_use]
pub const fn supports_cache_from_type(&self) -> bool {
matches!(self, Self::Docker | Self::Nerdctl)
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -132,6 +156,8 @@ fn get_engine_info(
EngineType::PodmanRemote
} else if stdout_help.contains("podman") {
EngineType::Podman
} else if stdout_help.contains("nerdctl") {
EngineType::Nerdctl
} else if stdout_help.contains("docker") && !stdout_help.contains("emulate") {
EngineType::Docker
} else {
Expand Down
12 changes: 9 additions & 3 deletions xtask/src/build_docker_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,10 @@ pub fn build_docker_image(

if push {
docker_build.arg("--push");
} else if engine.kind.is_docker() && no_output {
} else if engine.kind.supports_output_flag() && no_output {
docker_build.args(["--output", "type=tar,dest=/dev/null"]);
} else if no_output {
msg_info.fatal("cannot specify `--no-output` with engine that does not support the `--output` flag", 1);
} else if has_buildkit {
docker_build.arg("--load");
}
Expand Down Expand Up @@ -216,17 +218,21 @@ pub fn build_docker_image(
tags = vec![target.image_name(&repository, tag)];
}

docker_build.arg("--pull");
if engine.kind.supports_pull_flag() {
docker_build.arg("--pull");
}
if no_cache {
docker_build.arg("--no-cache");
} else {
} else if engine.kind.supports_cache_from_type() {
docker_build.args([
"--cache-from",
&format!(
"type=registry,ref={}",
target.image_name(&repository, "main")
),
]);
} else {
docker_build.args(["--cache-from", &format!("{repository}/{}", target.name)]);
}

if push {
Expand Down

0 comments on commit ab01c6e

Please sign in to comment.