mirror of
https://github.com/containers/buildah.git
synced 2025-07-31 15:24:26 +03:00
Allow users to set OS and architecture on bud
When building images we now allow the architecture and operating system to be overwritten via the new `--os` and `--arch` flags. This allows the use case of packing pre-built or cross-compiled binaries into container images with specifying the correct environment. The `--platform` flag now takes the `os/arch` format into account as well. Signed-off-by: Sascha Grunert <sgrunert@suse.com> Closes: #2097 Approved by: rhatdan
This commit is contained in:
committed by
Atomic Bot
parent
0c3234f226
commit
6417a9a074
@ -301,6 +301,11 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budOptions) error {
|
||||
|
||||
capabilities := defaultContainerConfig.Capabilities("", iopts.CapAdd, iopts.CapDrop)
|
||||
|
||||
os, arch, err := parse.PlatformFromOptions(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
options := imagebuildah.BuildOptions{
|
||||
ContextDirectory: contextDir,
|
||||
PullPolicy: pullPolicy,
|
||||
@ -341,6 +346,8 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budOptions) error {
|
||||
Devices: devices,
|
||||
DefaultEnv: defaultContainerConfig.GetDefaultEnv(),
|
||||
SignBy: iopts.SignBy,
|
||||
Architecture: arch,
|
||||
OS: os,
|
||||
}
|
||||
|
||||
if iopts.Quiet {
|
||||
|
@ -300,6 +300,14 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
||||
case archive.Gzip:
|
||||
systemContext.DirForceCompress = true
|
||||
}
|
||||
|
||||
if systemContext.ArchitectureChoice != b.Architecture() {
|
||||
systemContext.ArchitectureChoice = b.Architecture()
|
||||
}
|
||||
if systemContext.OSChoice != b.OS() {
|
||||
systemContext.OSChoice = b.OS()
|
||||
}
|
||||
|
||||
var manifestBytes []byte
|
||||
if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy)); err != nil {
|
||||
return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID)
|
||||
|
@ -375,6 +375,7 @@ return 1
|
||||
"
|
||||
|
||||
local options_with_args="
|
||||
--arch
|
||||
--add-host
|
||||
--annotation
|
||||
--authfile
|
||||
@ -410,6 +411,7 @@ return 1
|
||||
--net
|
||||
--network
|
||||
--no-pivot
|
||||
--os
|
||||
--pid
|
||||
--platform
|
||||
--runtime
|
||||
|
@ -42,6 +42,10 @@ Add an image *annotation* (e.g. annotation=*value*) to the image metadata. Can b
|
||||
|
||||
Note: this information is not present in Docker image formats, so it is discarded when writing images in Docker formats.
|
||||
|
||||
**--arch**="ARCH"
|
||||
|
||||
Set the ARCH instead of the architecture of the current machine in the image manifest and config.
|
||||
|
||||
**--authfile** *path*
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `buildah login`.
|
||||
@ -327,6 +331,10 @@ another process.
|
||||
|
||||
Do not use existing cached images for the container build. Build from the start with a new set of cached layers.
|
||||
|
||||
**--os**="OS"
|
||||
|
||||
Set the OS instead of the current operating system of the machine in the image manifest and config.
|
||||
|
||||
**--pid** *how*
|
||||
|
||||
Sets the configuration for PID namespaces when handling `RUN` instructions.
|
||||
@ -336,11 +344,11 @@ that the PID namespace in which `buildah` itself is being run should be reused,
|
||||
or it can be the path to a PID namespace which is already in use by another
|
||||
process.
|
||||
|
||||
**--platform**="Linux"
|
||||
**--platform**="OS/ARCH"
|
||||
|
||||
This option has no effect on the build. Other container engines use this option
|
||||
to control the execution platform for the build (e.g., Windows, Linux) which is
|
||||
not required for Buildah as it supports only Linux.
|
||||
Set the OS/ARCH instead of the current operating system and architecture of the
|
||||
machine in the image manifest and config (for example `linux/arm`). If
|
||||
`--platform` is set, then the values of `--arch` and `--os` will be overwritten.
|
||||
|
||||
**--pull**
|
||||
|
||||
|
@ -160,6 +160,10 @@ type BuildOptions struct {
|
||||
DefaultEnv []string
|
||||
// SignBy is the fingerprint of a GPG key to use for signing images.
|
||||
SignBy string
|
||||
// Architecture specifies the target architecture of the image to be built.
|
||||
Architecture string
|
||||
// OS is the specifies the operating system of the image to be built.
|
||||
OS string
|
||||
}
|
||||
|
||||
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
|
||||
|
@ -94,6 +94,8 @@ type Executor struct {
|
||||
capabilities []string
|
||||
devices []configs.Device
|
||||
signBy string
|
||||
architecture string
|
||||
os string
|
||||
}
|
||||
|
||||
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
|
||||
@ -151,6 +153,8 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
|
||||
capabilities: options.Capabilities,
|
||||
devices: options.Devices,
|
||||
signBy: options.SignBy,
|
||||
architecture: options.Architecture,
|
||||
os: options.OS,
|
||||
}
|
||||
if exec.err == nil {
|
||||
exec.err = os.Stderr
|
||||
|
@ -1132,6 +1132,8 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
|
||||
}
|
||||
s.builder.SetHostname(config.Hostname)
|
||||
s.builder.SetDomainname(config.Domainname)
|
||||
s.builder.SetArchitecture(s.executor.architecture)
|
||||
s.builder.SetOS(s.executor.os)
|
||||
s.builder.SetUser(config.User)
|
||||
s.builder.ClearPorts()
|
||||
for p := range config.ExposedPorts {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -46,6 +47,7 @@ type NameSpaceResults struct {
|
||||
// BudResults represents the results for Bud flags
|
||||
type BudResults struct {
|
||||
Annotation []string
|
||||
Arch string
|
||||
Authfile string
|
||||
BuildArg []string
|
||||
CacheFrom string
|
||||
@ -61,6 +63,7 @@ type BudResults struct {
|
||||
Logfile string
|
||||
Loglevel int
|
||||
NoCache bool
|
||||
OS string
|
||||
Platform string
|
||||
Pull bool
|
||||
PullAlways bool
|
||||
@ -145,6 +148,7 @@ func GetLayerFlags(flags *LayerResults) pflag.FlagSet {
|
||||
// GetBudFlags returns common bud flags
|
||||
func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
||||
fs := pflag.FlagSet{}
|
||||
fs.StringVar(&flags.Arch, "arch", runtime.GOARCH, "set the ARCH instead of the architecture of the current machine in the image manifest and config")
|
||||
fs.StringArrayVar(&flags.Annotation, "annotation", []string{}, "Set metadata for an image (default [])")
|
||||
fs.StringVar(&flags.Authfile, "authfile", GetDefaultAuthFile(), "path of the authentication file.")
|
||||
fs.StringArrayVar(&flags.BuildArg, "build-arg", []string{}, "`argument=value` to supply to the builder")
|
||||
@ -161,7 +165,8 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
||||
fs.BoolVar(&flags.NoCache, "no-cache", false, "Do not use existing cached images for the container build. Build from the start with a new set of cached layers.")
|
||||
fs.StringVar(&flags.Logfile, "logfile", "", "log to `file` instead of stdout/stderr")
|
||||
fs.IntVar(&flags.Loglevel, "loglevel", 0, "adjust logging level (range from -2 to 3)")
|
||||
fs.StringVar(&flags.Platform, "platform", "", "CLI compatibility: no action or effect")
|
||||
fs.StringVar(&flags.OS, "os", runtime.GOOS, "set the OS instead of the current operating system of the machine in the image manifest and config")
|
||||
fs.StringVar(&flags.Platform, "platform", parse.DefaultPlatform(), "set the OS/ARCH instead of the current operating system and architecture of the machine in the image manifest and config (for example `linux/arm`)")
|
||||
fs.BoolVar(&flags.Pull, "pull", true, "pull the image from the registry if newer or not present in store, if false, only pull the image if not present")
|
||||
fs.BoolVar(&flags.PullAlways, "pull-always", false, "pull the image even if the named image is present in store")
|
||||
fs.BoolVar(&flags.PullNever, "pull-never", false, "do not pull the image, use the image present in store if available")
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
@ -606,6 +607,46 @@ func getAuthFile(authfile string) string {
|
||||
return os.Getenv("REGISTRY_AUTH_FILE")
|
||||
}
|
||||
|
||||
// PlatformFromOptions parses the operating system (os) and architecture (arch)
|
||||
// from the provided command line options.
|
||||
func PlatformFromOptions(c *cobra.Command) (os, arch string, err error) {
|
||||
os = runtime.GOOS
|
||||
arch = runtime.GOARCH
|
||||
|
||||
if selectedOS, err := c.Flags().GetString("os"); err == nil && selectedOS != runtime.GOOS {
|
||||
os = selectedOS
|
||||
}
|
||||
if selectedArch, err := c.Flags().GetString("arch"); err == nil && selectedArch != runtime.GOARCH {
|
||||
arch = selectedArch
|
||||
}
|
||||
|
||||
if pf, err := c.Flags().GetString("platform"); err == nil && pf != DefaultPlatform() {
|
||||
selectedOS, selectedArch, err := parsePlatform(pf)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "unable to parse platform")
|
||||
}
|
||||
arch = selectedArch
|
||||
os = selectedOS
|
||||
}
|
||||
|
||||
return os, arch, nil
|
||||
}
|
||||
|
||||
const platformSep = "/"
|
||||
|
||||
// DefaultPlatform returns the standard platform for the current system
|
||||
func DefaultPlatform() string {
|
||||
return runtime.GOOS + platformSep + runtime.GOARCH
|
||||
}
|
||||
|
||||
func parsePlatform(platform string) (os, arch string, err error) {
|
||||
split := strings.Split(platform, platformSep)
|
||||
if len(split) != 2 {
|
||||
return "", "", errors.Errorf("invalid platform syntax for %q (use OS/ARCH)", platform)
|
||||
}
|
||||
return split[0], split[1], nil
|
||||
}
|
||||
|
||||
func parseCreds(creds string) (string, string) {
|
||||
if creds == "" {
|
||||
return "", ""
|
||||
|
@ -1750,3 +1750,48 @@ EOM
|
||||
run_buildah run testctr-working-container ls /file-0.0.1.txt
|
||||
run_buildah rm -a
|
||||
}
|
||||
|
||||
@test "bud with custom arch" {
|
||||
run_buildah bud --signature-policy ${TESTSDIR}/policy.json \
|
||||
-f ${TESTSDIR}/bud/from-scratch/Dockerfile \
|
||||
-t arch-test \
|
||||
--arch=arm
|
||||
|
||||
run_buildah inspect --format "{{ .Docker.Architecture }}" arch-test
|
||||
expect_output arm
|
||||
|
||||
run_buildah inspect --format "{{ .OCIv1.Architecture }}" arch-test
|
||||
expect_output arm
|
||||
}
|
||||
|
||||
@test "bud with custom os" {
|
||||
run_buildah bud --signature-policy ${TESTSDIR}/policy.json \
|
||||
-f ${TESTSDIR}/bud/from-scratch/Dockerfile \
|
||||
-t os-test \
|
||||
--os=windows
|
||||
|
||||
run_buildah inspect --format "{{ .Docker.OS }}" os-test
|
||||
expect_output windows
|
||||
|
||||
run_buildah inspect --format "{{ .OCIv1.OS }}" os-test
|
||||
expect_output windows
|
||||
}
|
||||
|
||||
@test "bud with custom platform" {
|
||||
run_buildah bud --signature-policy ${TESTSDIR}/policy.json \
|
||||
-f ${TESTSDIR}/bud/from-scratch/Dockerfile \
|
||||
-t platform-test \
|
||||
--platform=windows/arm
|
||||
|
||||
run_buildah inspect --format "{{ .Docker.OS }}" platform-test
|
||||
expect_output windows
|
||||
|
||||
run_buildah inspect --format "{{ .OCIv1.OS }}" platform-test
|
||||
expect_output windows
|
||||
|
||||
run_buildah inspect --format "{{ .Docker.Architecture }}" platform-test
|
||||
expect_output arm
|
||||
|
||||
run_buildah inspect --format "{{ .OCIv1.Architecture }}" platform-test
|
||||
expect_output arm
|
||||
}
|
||||
|
Reference in New Issue
Block a user