Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,21 @@ Execution modes:
Not reproducible; uses whatever Ruby/Node is installed.

With neither a container engine nor DOCS_TOOLBOX_LOCAL=1, the task aborts.
Override the image with DOCS_TOOLBOX_IMAGE.
Override the image with DOCS_TOOLBOX_IMAGE, and the engine with
DOCS_TOOLBOX_ENGINE (podman or docker) when detection picks a broken one.
USAGE
}

# DOCS_TOOLBOX_ENGINE forces an engine and skips detection. It exists because
# `podman info` only reports that the engine is *configured* -- it says nothing
# about whether the OCI runtime can start a container, and that gap is real: on
# some hosts `podman info` succeeds while `podman run` dies in crun. When the
# preferred engine is broken in a way detection cannot see, naming the other one
# is the only way out.
find_engine() {
if command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
if [ -n "${DOCS_TOOLBOX_ENGINE:-}" ]; then
printf '%s\n' "$DOCS_TOOLBOX_ENGINE"
elif command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
printf '%s\n' "podman"
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
printf '%s\n' "docker"
Expand Down
16 changes: 13 additions & 3 deletions templates/scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,23 @@ Execution modes:
Not reproducible; uses whatever Ruby/Node is installed.

With neither a container engine nor DOCS_TOOLBOX_LOCAL=1, the task aborts.
Override the image with DOCS_TOOLBOX_IMAGE. Application code is built with its
own tooling, not this script (docs-toolbox carries only the docs toolchain).
Override the image with DOCS_TOOLBOX_IMAGE, and the engine with
DOCS_TOOLBOX_ENGINE (podman or docker) when detection picks a broken one.
Application code is built with its own tooling, not this script (docs-toolbox
carries only the docs toolchain).
USAGE
}

# DOCS_TOOLBOX_ENGINE forces an engine and skips detection. It exists because
# `podman info` only reports that the engine is *configured* -- it says nothing
# about whether the OCI runtime can start a container, and that gap is real: on
# some hosts `podman info` succeeds while `podman run` dies in crun. When the
# preferred engine is broken in a way detection cannot see, naming the other one
# is the only way out.
find_engine() {
if command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
if [ -n "${DOCS_TOOLBOX_ENGINE:-}" ]; then
printf '%s\n' "$DOCS_TOOLBOX_ENGINE"
elif command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
printf '%s\n' "podman"
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
printf '%s\n' "docker"
Expand Down
53 changes: 53 additions & 0 deletions test/build-sh-template.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,56 @@ test("local-mode check-adapters runs the adapter checker", (t) => {
assert.equal(result.status, 0, result.stderr);
assert.match(invocations, /node scripts\/check-agent-adapters\.js/);
});

// Container-mode engine selection. Both engines are stubbed so nothing is
// actually pulled: each records the command it was given and exits 0, which is
// enough to see which one the runner reached for.
function runContainerTaskWithEngineStubs(t, env) {
const parent = fs.mkdtempSync(path.join(os.tmpdir(), "akt-buildsh-engine-"));
t.after(() => fs.rmSync(parent, { recursive: true, force: true }));

fs.copyFileSync(templateBuildSh, path.join(parent, "build.sh"));

const binDir = path.join(parent, "stub-bin");
fs.mkdirSync(binDir);
const log = path.join(parent, "invocations.log");
for (const engine of ["podman", "docker"]) {
const stub = path.join(binDir, engine);
fs.writeFileSync(stub, `#!/bin/sh\necho "${engine} $1" >> "$STUB_LOG"\n`);
fs.chmodSync(stub, 0o755);
}

const result = spawnSync("sh", ["build.sh", "validate"], {
cwd: parent,
encoding: "utf8",
env: {
...process.env,
PATH: `${binDir}:${process.env.PATH}`,
STUB_LOG: log,
DOCS_TOOLBOX_LOCAL: "",
...env,
},
});

return {
result,
invocations: fs.existsSync(log) ? fs.readFileSync(log, "utf8") : "",
};
}

test("container mode prefers podman when nothing is forced", (t) => {
const { invocations } = runContainerTaskWithEngineStubs(t, {});
assert.match(invocations, /^podman run$/m);
assert.doesNotMatch(invocations, /^docker run$/m);
});

test("DOCS_TOOLBOX_ENGINE overrides detection", (t) => {
// podman is on PATH and its `info` probe succeeds, so detection would pick it.
// The override has to win anyway -- that is the whole point: `podman info`
// cannot see an OCI runtime that fails only at container start.
const { invocations } = runContainerTaskWithEngineStubs(t, {
DOCS_TOOLBOX_ENGINE: "docker",
});
assert.match(invocations, /^docker run$/m);
assert.doesNotMatch(invocations, /^podman run$/m);
});
Loading