Skip to content

Commit ab01c6e

Browse files
Merge #1033
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 <ahuszagh@gmail.com>
2 parents 5261b6a + e5d58cc commit ab01c6e

File tree

5 files changed

+123
-6
lines changed

5 files changed

+123
-6
lines changed

.changes/1033.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"description": "fix --cache-from using podman.",
3+
"type": "fixed",
4+
"issues": [1031]
5+
}

.github/workflows/ci.yml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,45 @@ jobs:
319319
run: ./ci/test-docker-in-docker.sh
320320
shell: bash
321321

322+
podman:
323+
name: podman
324+
runs-on: ubuntu-latest
325+
needs: [shellcheck, test, check]
326+
if: github.event_name == 'push'
327+
strategy:
328+
fail-fast: false
329+
outputs:
330+
has-image: ${{ steps.prepare-meta.outputs.has-image }}
331+
images: ${{ steps.build-docker-image.outputs.images && fromJSON(steps.build-docker-image.outputs.images) }}
332+
coverage-artifact: ${{ steps.cov.outputs.artifact-name }}
333+
steps:
334+
- uses: actions/checkout@v3
335+
336+
- uses: ./.github/actions/setup-rust
337+
338+
- name: Install Podman
339+
env:
340+
DEBIAN_FRONTEND: noninteractive
341+
run: |
342+
sudo apt-get update
343+
sudo apt-get install podman --no-install-recommends --assume-yes
344+
345+
- name: LLVM instrument coverage
346+
id: cov
347+
uses: ./.github/actions/cargo-llvm-cov
348+
with:
349+
name: cross-podman-aarch64-unknown-linux-gnu
350+
351+
- name: Install cross
352+
run: cargo install --path . --force --debug
353+
354+
- name: Run Podman Test
355+
run: ./ci/test-podman.sh
356+
env:
357+
CROSS_CONTAINER_ENGINE: podman
358+
TARGET: aarch64-unknown-linux-gnu
359+
shell: bash
360+
322361
publish:
323362
needs: [build, check, fmt, clippy, cargo-deny]
324363
runs-on: ubuntu-latest
@@ -331,7 +370,7 @@ jobs:
331370
github-token: ${{ secrets.GITHUB_TOKEN }}
332371

333372
conclusion:
334-
needs: [shellcheck, fmt, clippy, test, generate-matrix, build, publish, check, remote, bisect, docker-in-docker, foreign]
373+
needs: [shellcheck, fmt, clippy, test, generate-matrix, build, publish, check, remote, bisect, docker-in-docker, foreign, podman]
335374
if: always()
336375
runs-on: ubuntu-latest
337376
steps:

ci/test-podman.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
# shellcheck disable=SC1091,SC1090
3+
4+
# test to see that running and building images with podman works.
5+
6+
set -x
7+
set -eo pipefail
8+
9+
export CROSS_CONTAINER_ENGINE=podman
10+
if [[ -z "${TARGET}" ]]; then
11+
export TARGET="aarch64-unknown-linux-gnu"
12+
fi
13+
14+
ci_dir=$(dirname "${BASH_SOURCE[0]}")
15+
ci_dir=$(realpath "${ci_dir}")
16+
. "${ci_dir}"/shared.sh
17+
18+
main() {
19+
local td=
20+
local parent=
21+
local target="${TARGET}"
22+
23+
retry cargo fetch
24+
cargo build
25+
export CROSS="${PROJECT_HOME}/target/debug/cross"
26+
27+
td="$(mkcargotemp -d)"
28+
parent=$(dirname "${td}")
29+
pushd "${td}"
30+
cargo init --bin --name "hello" .
31+
32+
echo '[build]
33+
pre-build = ["apt-get update"]' > "${parent}/Cross.toml"
34+
35+
CROSS_CONTAINER_ENGINE="${CROSS_ENGINE}" "${CROSS}" build --target "${target}" --verbose
36+
37+
popd
38+
rm -rf "${td}"
39+
}
40+
41+
main

src/docker/engine.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,45 @@ pub enum EngineType {
1717
Docker,
1818
Podman,
1919
PodmanRemote,
20+
Nerdctl,
2021
Other,
2122
}
2223

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

3031
/// Returns `true` if the engine type is [`Docker`](EngineType::Docker).
3132
#[must_use]
32-
pub fn is_docker(&self) -> bool {
33+
pub const fn is_docker(&self) -> bool {
3334
matches!(self, Self::Docker)
3435
}
36+
37+
/// Returns `true` if the build command supports the `--output` flag.
38+
#[must_use]
39+
pub const fn supports_output_flag(&self) -> bool {
40+
!matches!(self, Self::Other)
41+
}
42+
43+
/// Returns `true` if the build command supports the `--pull` flag.
44+
#[must_use]
45+
pub const fn supports_pull_flag(&self) -> bool {
46+
!matches!(self, Self::Nerdctl | Self::Other)
47+
}
48+
49+
/// Returns `true` if the build command supports the `--cache-from type=` key.
50+
///
51+
/// Some container engines, especially podman, do not support the `type`
52+
/// key of `--cache-from` during the image build steps. They also do
53+
/// not support any tags for the `--cache-from` steps either. See:
54+
/// https://docs.podman.io/en/latest/markdown/podman-build.1.html#cache-from
55+
#[must_use]
56+
pub const fn supports_cache_from_type(&self) -> bool {
57+
matches!(self, Self::Docker | Self::Nerdctl)
58+
}
3559
}
3660

3761
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -132,6 +156,8 @@ fn get_engine_info(
132156
EngineType::PodmanRemote
133157
} else if stdout_help.contains("podman") {
134158
EngineType::Podman
159+
} else if stdout_help.contains("nerdctl") {
160+
EngineType::Nerdctl
135161
} else if stdout_help.contains("docker") && !stdout_help.contains("emulate") {
136162
EngineType::Docker
137163
} else {

xtask/src/build_docker_image.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,10 @@ pub fn build_docker_image(
187187

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

219-
docker_build.arg("--pull");
221+
if engine.kind.supports_pull_flag() {
222+
docker_build.arg("--pull");
223+
}
220224
if no_cache {
221225
docker_build.arg("--no-cache");
222-
} else {
226+
} else if engine.kind.supports_cache_from_type() {
223227
docker_build.args([
224228
"--cache-from",
225229
&format!(
226230
"type=registry,ref={}",
227231
target.image_name(&repository, "main")
228232
),
229233
]);
234+
} else {
235+
docker_build.args(["--cache-from", &format!("{repository}/{}", target.name)]);
230236
}
231237

232238
if push {

0 commit comments

Comments
 (0)