diff --git a/go.mod b/go.mod index 61e615e088..0ef21a7016 100644 --- a/go.mod +++ b/go.mod @@ -134,3 +134,9 @@ require ( sigs.k8s.io/yaml v1.6.0 // indirect tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect ) + +replace go.podman.io/common => github.com/TrevorBurnham/container-libs/common v0.0.0-20260225192346-ebad6b016844 + +replace go.podman.io/image/v5 => github.com/TrevorBurnham/container-libs/image/v5 v5.0.0-20260225192346-ebad6b016844 + +replace go.podman.io/storage => github.com/TrevorBurnham/container-libs/storage v0.0.0-20260225192346-ebad6b016844 diff --git a/go.sum b/go.sum index 10cf022e67..3ac160f2bc 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,12 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1 github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/TrevorBurnham/container-libs/common v0.0.0-20260225192346-ebad6b016844 h1:QmZVSHJsbBqCfkPoW1yVQ2tWCb3MEGXPGaBBaGqGNmM= +github.com/TrevorBurnham/container-libs/common v0.0.0-20260225192346-ebad6b016844/go.mod h1:0DeDsVv70xdub5XMurYkseMEwQQ2NdwtG1+Es24VzX4= +github.com/TrevorBurnham/container-libs/image/v5 v5.0.0-20260225192346-ebad6b016844 h1:wTuMtjFpbFLFhkxsrzLrfhvagYPcIssZFWJN3+LRGic= +github.com/TrevorBurnham/container-libs/image/v5 v5.0.0-20260225192346-ebad6b016844/go.mod h1:aOKcsA9y3xfvAW5jGk8evBoQyJGJzhOIrXjwc4iRXcw= +github.com/TrevorBurnham/container-libs/storage v0.0.0-20260225192346-ebad6b016844 h1:bYgfHmfH4oQ3K/jKtbLeicAQBASMhEyjRBPFJRXVZV0= +github.com/TrevorBurnham/container-libs/storage v0.0.0-20260225192346-ebad6b016844/go.mod h1:B83Ad8mtO0GZs7rEwb66f0Ed5G57NyKI/iJZHoJrpUE= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 9ba17e1b00..7aa82642a5 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -522,6 +522,20 @@ func SystemContextFromFlagSet(flags *pflag.FlagSet, findFlagFunc func(name strin ctx.VariantChoice = variant } + // If no platform-related flags were explicitly set, fall back to the + // default platform from containers.conf [engine] platform. + if ctx.OSChoice == "" && ctx.ArchitectureChoice == "" && ctx.VariantChoice == "" { + if defaultPlatform, err := defaultPlatformFromConfig(); err == nil && defaultPlatform != "" { + os, arch, variant, err := Platform(defaultPlatform) + if err != nil { + return nil, fmt.Errorf("parsing containers.conf platform %q: %w", defaultPlatform, err) + } + ctx.OSChoice = os + ctx.ArchitectureChoice = arch + ctx.VariantChoice = variant + } + } + ctx.BigFilesTemporaryDir = GetTempDir() return ctx, nil } @@ -671,6 +685,17 @@ func PlatformsFromOptions(c *cobra.Command) (platforms []struct{ OS, Arch, Varia platforms = append(platforms, struct{ OS, Arch, Variant string }{os, arch, variant}) } } + // If no platform-related flags were explicitly set, fall back to the + // default platform from containers.conf [engine] platform. + if len(platforms) == 1 && platforms[0].OS == "" && platforms[0].Arch == "" && platforms[0].Variant == "" { + if defaultPlatform, err := defaultPlatformFromConfig(); err == nil && defaultPlatform != "" { + os, arch, variant, err := Platform(defaultPlatform) + if err != nil { + return nil, fmt.Errorf("parsing containers.conf platform %q: %w", defaultPlatform, err) + } + platforms = []struct{ OS, Arch, Variant string }{{os, arch, variant}} + } + } return platforms, nil } @@ -679,6 +704,16 @@ func DefaultPlatform() string { return platforms.DefaultString() } +// defaultPlatformFromConfig returns the default platform from +// containers.conf [engine] platform, if set. +func defaultPlatformFromConfig() (string, error) { + cfg, err := config.Default() + if err != nil { + return "", err + } + return cfg.Engine.Platform, nil +} + // Platform separates the platform string into os, arch and variant, // accepting any of $arch, $os/$arch, or $os/$arch/$variant. func Platform(platform string) (os, arch, variant string, err error) { diff --git a/tests/containers_conf.bats b/tests/containers_conf.bats index 1e8e16dffa..d59ee97ddc 100644 --- a/tests/containers_conf.bats +++ b/tests/containers_conf.bats @@ -173,3 +173,31 @@ EOF expect_output --substring "retry.*\(default 10\)" expect_output --substring "retry-delay.*\(default \"5s\"\)" } + + +@test "containers.conf engine.platform" { + cat >${TEST_SCRATCH_DIR}/containers.conf << EOF +[engine] +platform = "linux/arm64" +EOF + local context="$TEST_SCRATCH_DIR"/context + mkdir -p "$context" + cat > "$context"/Containerfile << _EOF +FROM scratch +COPY . . +_EOF + + # Build with the custom containers.conf and push to an OCI layout + CONTAINERS_CONF=${TEST_SCRATCH_DIR}/containers.conf run_buildah build \ + $WITH_POLICY_JSON -t localhost/testplatform \ + -f "$context"/Containerfile "$context" + CONTAINERS_CONF=${TEST_SCRATCH_DIR}/containers.conf run_buildah push \ + $WITH_POLICY_JSON localhost/testplatform oci:"$TEST_SCRATCH_DIR"/output + + # Verify the image platform matches what we set in containers.conf + local config="$TEST_SCRATCH_DIR"/output/$(oci_image_config "$TEST_SCRATCH_DIR"/output) + run jq -r '.os' "$config" + assert "$output" = "linux" "os should be linux" + run jq -r '.architecture' "$config" + assert "$output" = "arm64" "architecture should be arm64" +} diff --git a/vendor/go.podman.io/common/pkg/config/config.go b/vendor/go.podman.io/common/pkg/config/config.go index 7864f9f381..d4eff65047 100644 --- a/vendor/go.podman.io/common/pkg/config/config.go +++ b/vendor/go.podman.io/common/pkg/config/config.go @@ -422,6 +422,12 @@ type EngineConfig struct { // OCIRuntimesFlags are the set of configured OCI runtimes' flags OCIRuntimesFlags map[string][]string `toml:"runtimes_flags,omitempty"` + // Platform specifies the default platform (os/arch[/variant]) for image + // operations such as pull, build, run, and create. If empty, the host's + // platform is used. Format: "os/arch" or "os/arch/variant" (e.g., + // "linux/amd64", "linux/arm64/v8"). + Platform string `toml:"platform,omitempty"` + // PlatformToOCIRuntime requests specific OCI runtime for a specified platform of image. PlatformToOCIRuntime map[string]string `toml:"platform_to_oci_runtime,omitempty"` diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf b/vendor/go.podman.io/common/pkg/config/containers.conf index 49fd38390b..8496c0d528 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf +++ b/vendor/go.podman.io/common/pkg/config/containers.conf @@ -696,6 +696,11 @@ default_sysctls = [ # #num_locks = 2048 +# Default platform (os/arch[/variant]) for image operations such as pull, +# build, run, and create. If empty, the host's platform is used. +# +#platform = "" + # Set the exit policy of the pod when the last container exits. #pod_exit_policy = "continue" diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd index 620bd0ca4f..4a68e9a3d7 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd +++ b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd @@ -528,6 +528,11 @@ default_sysctls = [ # #num_locks = 2048 +# Default platform (os/arch[/variant]) for image operations such as pull, +# build, run, and create. If empty, the host's platform is used. +# +#platform = "" + # Whether to pull new image before running a container # #pull_policy = "missing" diff --git a/vendor/modules.txt b/vendor/modules.txt index df263cccbe..693df16abd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -454,8 +454,8 @@ go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# go.podman.io/common v0.67.1-0.20260325203629-8af78737e8bb -## explicit; go 1.25.6 +# go.podman.io/common v0.67.1-0.20260325203629-8af78737e8bb => github.com/TrevorBurnham/container-libs/common v0.0.0-20260225192346-ebad6b016844 +## explicit; go 1.24.6 go.podman.io/common/internal go.podman.io/common/libimage go.podman.io/common/libimage/define @@ -505,8 +505,8 @@ go.podman.io/common/pkg/umask go.podman.io/common/pkg/util go.podman.io/common/pkg/version go.podman.io/common/version -# go.podman.io/image/v5 v5.39.2-0.20260325203629-8af78737e8bb -## explicit; go 1.25.6 +# go.podman.io/image/v5 v5.39.2-0.20260325203629-8af78737e8bb => github.com/TrevorBurnham/container-libs/image/v5 v5.0.0-20260225192346-ebad6b016844 +## explicit; go 1.24.6 go.podman.io/image/v5/copy go.podman.io/image/v5/directory go.podman.io/image/v5/directory/explicitfilepath @@ -574,8 +574,8 @@ go.podman.io/image/v5/transports go.podman.io/image/v5/transports/alltransports go.podman.io/image/v5/types go.podman.io/image/v5/version -# go.podman.io/storage v1.62.1-0.20260325203629-8af78737e8bb -## explicit; go 1.25.0 +# go.podman.io/storage v1.62.1-0.20260325203629-8af78737e8bb => github.com/TrevorBurnham/container-libs/storage v0.0.0-20260225192346-ebad6b016844 +## explicit; go 1.24.0 go.podman.io/storage go.podman.io/storage/drivers go.podman.io/storage/drivers/btrfs @@ -821,3 +821,6 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.1.0 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go +# go.podman.io/common => github.com/TrevorBurnham/container-libs/common v0.0.0-20260225192346-ebad6b016844 +# go.podman.io/image/v5 => github.com/TrevorBurnham/container-libs/image/v5 v5.0.0-20260225192346-ebad6b016844 +# go.podman.io/storage => github.com/TrevorBurnham/container-libs/storage v0.0.0-20260225192346-ebad6b016844