Skip to content

Commit

Permalink
docker: support the variant field
Browse files Browse the repository at this point in the history
The Docker v2Image structure picked up a variant field in early 2019,
but our copy of it didn't.  Add the field, along with methods for
setting and querying it, and expose them in the `buildah config` and
`buildah inspect` commands.

When setting an initial architecture for a container based on an image
which doesn't contain an architecture, or from "scratch", normalize the
architecture name we've been given, and set both it and the variant
field at the same time.

Provide normalized architecture+variant values in `buildah info`.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
  • Loading branch information
nalind committed Nov 4, 2021
1 parent e3283ab commit ef5a382
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 3 deletions.
5 changes: 5 additions & 0 deletions cmd/buildah/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type configResults struct {
shell string
stopSignal string
user string
variant string
volume []string
workingDir string
}
Expand Down Expand Up @@ -91,6 +92,7 @@ func init() {
flags.StringVar(&opts.shell, "shell", "", "add `shell` to run in containers")
flags.StringVar(&opts.stopSignal, "stop-signal", "", "set `stop signal` for containers based on image")
flags.StringVarP(&opts.user, "user", "u", "", "set default `user` to run inside containers based on image")
flags.StringVar(&opts.variant, "variant", "", "set architecture `variant` of the target image")
flags.StringSliceVarP(&opts.volume, "volume", "v", []string{}, "add default `volume` path to be created for containers based on image (default [])")
flags.StringVar(&opts.workingDir, "workingdir", "", "set working `directory` for containers based on image")

Expand Down Expand Up @@ -169,6 +171,9 @@ func updateConfig(builder *buildah.Builder, c *cobra.Command, iopts configResult
if c.Flag("arch").Changed {
builder.SetArchitecture(iopts.arch)
}
if c.Flag("variant").Changed {
builder.SetVariant(iopts.variant)
}
if c.Flag("os").Changed {
builder.SetOS(iopts.os)
}
Expand Down
19 changes: 19 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/containerd/containerd/platforms"
"github.com/containers/buildah/define"
"github.com/containers/buildah/docker"
"github.com/containers/image/v5/manifest"
Expand Down Expand Up @@ -133,6 +134,10 @@ func (b *Builder) fixupConfig(sys *types.SystemContext) {
} else {
b.SetArchitecture(runtime.GOARCH)
}
// in case the arch string we started with was shorthand for a known arch+variant pair, normalize it
ps := platforms.Normalize(ociv1.Platform{OS: b.OS(), Architecture: b.Architecture(), Variant: b.Variant()})
b.SetArchitecture(ps.Architecture)
b.SetVariant(ps.Variant)
}
if b.Format == define.Dockerv2ImageManifest && b.Hostname() == "" {
b.SetHostname(stringid.TruncateID(stringid.GenerateRandomID()))
Expand Down Expand Up @@ -212,6 +217,20 @@ func (b *Builder) SetArchitecture(arch string) {
b.Docker.Architecture = arch
}

// Variant returns a name of the architecture variant on which the container,
// or a container built using an image built from this container, is intended
// to be run.
func (b *Builder) Variant() string {
return b.Docker.Variant
}

// SetVariant sets the name of the architecture variant on which the container,
// or a container built using an image built from this container, is intended
// to be run.
func (b *Builder) SetVariant(variant string) {
b.Docker.Variant = variant
}

// Maintainer returns contact information for the person who built the image.
func (b *Builder) Maintainer() string {
return b.OCIv1.Author
Expand Down
4 changes: 3 additions & 1 deletion contrib/completions/bash/buildah
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ return 1
--stop-signal
--user
-u
--variant
--volume
-v
--workingdir
Expand Down Expand Up @@ -396,6 +397,7 @@ return 1
local options_with_args="
--arch
--add-host
--all-platforms
--annotation
--authfile
--build-arg
Expand Down Expand Up @@ -435,7 +437,6 @@ return 1
--os
--pid
--platform
--platforms
--runtime
--runtime-flag
--security-opt
Expand All @@ -451,6 +452,7 @@ return 1
--userns-uid-map-user
--userns-gid-map-group
--uts
--variant
--volume
-v
"
Expand Down
2 changes: 2 additions & 0 deletions docker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ type V1Image struct {
Config *Config `json:"config,omitempty"`
// Architecture is the hardware that the image is build and runs on
Architecture string `json:"architecture,omitempty"`
// Variant is a variant of the CPU that the image is built and runs on
Variant string `json:"variant,omitempty"`
// OS is the operating system used to build and run the image
OS string `json:"os,omitempty"`
// Size is the total size of the image including all layers it is composed of
Expand Down
7 changes: 7 additions & 0 deletions docs/buildah-config.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ or UID, optionally followed by a group name or GID, separated by a colon (':').
If names are used, the container should include entries for those names in its
*/etc/passwd* and */etc/group* files.

**--variant** *variant*

Set the target architecture *variant* for any images which will be built using
the specified container. By default, if the container was based on an image,
that image's target architecture and variant information is kept, otherwise the
host's architecture and variant are recorded.

**--volume**, **-v** *volume*

Add a location in the directory tree which should be marked as a *volume* in any images which will be built using the specified container. Can be used multiple times. If *volume* has a trailing `-`, and is already set, then the *volume* is removed from the config.
Expand Down
8 changes: 6 additions & 2 deletions info.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (
"strings"
"time"

"github.com/containerd/containerd/platforms"
"github.com/containers/buildah/util"
"github.com/containers/storage"
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -43,8 +45,10 @@ func Info(store storage.Store) ([]InfoData, error) {

func hostInfo() map[string]interface{} {
info := map[string]interface{}{}
info["os"] = runtime.GOOS
info["arch"] = runtime.GOARCH
ps := platforms.Normalize(v1.Platform{OS: runtime.GOOS, Architecture: runtime.GOARCH})
info["os"] = ps.OS
info["arch"] = ps.Architecture
info["variant"] = ps.Variant
info["cpus"] = runtime.NumCPU()
info["rootless"] = unshare.IsRootless()

Expand Down
11 changes: 11 additions & 0 deletions tests/inspect.bats
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,14 @@ load helpers
run_buildah inspect --format "{{.Docker}}" alpine
expect_output --substring '\{'
}

@test "inspect-format-docker-variant" {
# github.com/containerd/containerd/platforms.Normalize() converts Arch:"armhf" to Arch:"arm"+Variant:"v7",
# so check that platform normalization happens at least for that one
run_buildah from --quiet --pull=false --signature-policy ${TESTSDIR}/policy.json --arch=armhf scratch
cid=$output
run_buildah inspect --format "{{.Docker.Architecture}}" $cid
[[ "$output" == "arm" ]]
run_buildah inspect --format "{{.Docker.Variant}}" $cid
[[ "$output" == "v7" ]]
}

0 comments on commit ef5a382

Please sign in to comment.