Add support for --manifest flags
This patch allows users to build a multi arch image with simple commands using emulation software. ``` buildah bud --arch arm --manifest myimage /tmp/mysrc buildah bud --arch amd64 --manifest myimage /tmp/mysrc buildah bud --arch s390x --manifest myimage /tmp/mysrc ``` And something like this for buildah commit ``` build() { ctr=$(./bin/buildah from --arch $1 ubi8) ./bin/buildah run $ctr dnf install -y iputils ./bin/buildah commit --manifest ubi8ping $ctr } build arm build amd64 build s390x ``` Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
f01ddd6800
commit
7acdfe8e8d
|
@ -330,6 +330,7 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budOptions) error {
|
|||
Isolation: isolation,
|
||||
Labels: iopts.Label,
|
||||
Layers: layers,
|
||||
Manifest: iopts.Manifest,
|
||||
MaxPullPushRetries: maxPullPushRetries,
|
||||
NamespaceOptions: namespaceOptions,
|
||||
NoCache: iopts.NoCache,
|
||||
|
|
|
@ -27,6 +27,7 @@ type commitInputOptions struct {
|
|||
disableCompression bool
|
||||
format string
|
||||
iidfile string
|
||||
manifest string
|
||||
omitTimestamp bool
|
||||
timestamp int64
|
||||
quiet bool
|
||||
|
@ -73,6 +74,7 @@ func init() {
|
|||
flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
||||
flags.BoolVarP(&opts.disableCompression, "disable-compression", "D", true, "don't compress layers")
|
||||
flags.StringVarP(&opts.format, "format", "f", defaultFormat(), "`format` of the image manifest and metadata")
|
||||
flags.StringVar(&opts.manifest, "manifest", "", "create image with as part of the specified manifest list. Creates manifest if it does not exist")
|
||||
flags.StringVar(&opts.iidfile, "iidfile", "", "Write the image ID to the file")
|
||||
flags.BoolVar(&opts.omitTimestamp, "omit-timestamp", false, "set created timestamp to epoch 0 to allow for deterministic builds")
|
||||
flags.Int64Var(&opts.timestamp, "timestamp", 0, "set created timestamp to epoch seconds to allow for deterministic builds, defaults to current time")
|
||||
|
@ -175,6 +177,7 @@ func commitCmd(c *cobra.Command, args []string, iopts commitInputOptions) error
|
|||
|
||||
options := buildah.CommitOptions{
|
||||
PreferredManifestType: format,
|
||||
Manifest: iopts.manifest,
|
||||
Compression: compress,
|
||||
SignaturePolicyPath: iopts.signaturePolicy,
|
||||
SystemContext: systemContext,
|
||||
|
|
58
commit.go
58
commit.go
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/buildah/manifests"
|
||||
"github.com/containers/buildah/pkg/blobcache"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v5/docker"
|
||||
|
@ -18,6 +19,7 @@ import (
|
|||
"github.com/containers/image/v5/signature"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
encconfig "github.com/containers/ocicrypt/config"
|
||||
"github.com/containers/storage"
|
||||
|
@ -83,6 +85,8 @@ type CommitOptions struct {
|
|||
OmitTimestamp bool
|
||||
// SignBy is the fingerprint of a GPG key to use for signing the image.
|
||||
SignBy string
|
||||
// Manifest list to add the image to.
|
||||
Manifest string
|
||||
// MaxRetries is the maximum number of attempts we'll make to commit
|
||||
// the image to an external registry if the first attempt fails.
|
||||
MaxRetries int
|
||||
|
@ -220,12 +224,59 @@ func checkRegistrySourcesAllows(forWhat string, dest types.ImageReference) (inse
|
|||
return false, nil
|
||||
}
|
||||
|
||||
func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpec string) error {
|
||||
var create bool
|
||||
systemContext := &types.SystemContext{}
|
||||
var list manifests.List
|
||||
_, listImage, err := util.FindImage(b.store, "", systemContext, manifestName)
|
||||
if err != nil {
|
||||
create = true
|
||||
list = manifests.Create()
|
||||
} else {
|
||||
_, list, err = manifests.LoadFromImage(b.store, listImage.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
names, err := util.ExpandNames([]string{manifestName}, "", systemContext, b.store)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error encountered while expanding image name %q", manifestName)
|
||||
}
|
||||
|
||||
ref, err := alltransports.ParseImageName(imageSpec)
|
||||
if err != nil {
|
||||
if ref, err = alltransports.ParseImageName(util.DefaultTransport + imageSpec); err != nil {
|
||||
// check if the local image exists
|
||||
if ref, _, err = util.FindImage(b.store, "", systemContext, imageSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = list.Add(ctx, systemContext, ref, true); err != nil {
|
||||
return err
|
||||
}
|
||||
var imageID string
|
||||
if create {
|
||||
imageID, err = list.SaveToImage(b.store, "", names, manifest.DockerV2ListMediaType)
|
||||
} else {
|
||||
imageID, err = list.SaveToImage(b.store, listImage.ID, nil, "")
|
||||
}
|
||||
if err == nil {
|
||||
fmt.Printf("%s\n", imageID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Commit writes the contents of the container, along with its updated
|
||||
// configuration, to a new image in the specified location, and if we know how,
|
||||
// add any additional tags that were specified. Returns the ID of the new image
|
||||
// if commit was successful and the image destination was local.
|
||||
func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) (string, reference.Canonical, digest.Digest, error) {
|
||||
var imgID string
|
||||
var (
|
||||
imgID string
|
||||
)
|
||||
|
||||
// If we weren't given a name, build a destination reference using a
|
||||
// temporary name that we'll remove later. The correct thing to do
|
||||
|
@ -437,6 +488,11 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
|||
}
|
||||
}
|
||||
|
||||
if options.Manifest != "" {
|
||||
if err := b.addManifest(ctx, options.Manifest, imgID); err != nil {
|
||||
return imgID, nil, "", err
|
||||
}
|
||||
}
|
||||
return imgID, ref, manifestDigest, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -324,6 +324,7 @@ return 1
|
|||
-h
|
||||
--disable-compression
|
||||
-D
|
||||
--manifest
|
||||
--quiet
|
||||
-q
|
||||
--rm
|
||||
|
@ -424,6 +425,7 @@ return 1
|
|||
--ipc
|
||||
--label
|
||||
--loglevel
|
||||
--manifest
|
||||
-m
|
||||
--memory
|
||||
--memory-swap
|
||||
|
|
|
@ -355,6 +355,11 @@ Adjust the logging level up or down. Valid option values range from -2 to 3,
|
|||
with 3 being roughly equivalent to using the global *--log-level=debug* option, and
|
||||
values below 0 omitting even error messages which accompany fatal errors.
|
||||
|
||||
**--manifest** "manifest"
|
||||
|
||||
Name of the manifest list to which the image will be added. Creates the manifest list
|
||||
if it does not exist. This option is useful for building multi architecture images.
|
||||
|
||||
**--memory**, **-m**=""
|
||||
|
||||
Memory limit (format: <number>[<unit>], where unit = b, k, m or g)
|
||||
|
@ -519,7 +524,7 @@ When --timestamp is set, the created timestamp is always set to the time specifi
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
**--ulimit** *type*=*soft-limit*[:*hard-limit*]
|
||||
|
||||
|
@ -749,6 +754,12 @@ buildah bud --no-cache --rm=false -t imageName .
|
|||
|
||||
buildah bud --dns-search=example.com --dns=223.5.5.5 --dns-option=use-vc .
|
||||
|
||||
### Building an multi-architecture image using a --manifest option (Requires emulation software)
|
||||
|
||||
buildah bud --arch arm --manifest myimage /tmp/mysrc
|
||||
buildah bud --arch amd64 --manifest myimage /tmp/mysrc
|
||||
buildah bud --arch s390x --manifest myimage /tmp/mysrc
|
||||
|
||||
### Building an image using a URL
|
||||
|
||||
This will clone the specified GitHub repository from the URL and use it as context. The Containerfile or Dockerfile at the root of the repository is used as the context of the build. This only works if the GitHub repository is a dedicated repository.
|
||||
|
|
|
@ -65,6 +65,11 @@ environment variable. `export BUILDAH\_FORMAT=docker`
|
|||
|
||||
Write the image ID to the file.
|
||||
|
||||
**--manifest** "manifest"
|
||||
|
||||
Name of the manifest list to which the image will be added. Creates the manifest list
|
||||
if it does not exist. This option is useful for building multi architecture images.
|
||||
|
||||
**--quiet**, **-q**
|
||||
|
||||
When writing the output image, suppress progress output.
|
||||
|
@ -81,10 +86,6 @@ Sign the new image using the GPG key that matches the specified fingerprint.
|
|||
|
||||
Squash all of the new image's layers (including those inherited from a base image) into a single new layer.
|
||||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
**--timestamp** *seconds*
|
||||
|
||||
Set the create timestamp to seconds since epoch to allow for deterministic builds (defaults to current time).
|
||||
|
@ -92,6 +93,10 @@ By default, the created timestamp is changed and written into the image manifest
|
|||
causing the image's sha256 hash to be different even if the sources are exactly the same otherwise.
|
||||
When --timestamp is set, the created timestamp is always set to the time specified and therefore not changed, allowing the image's sha256 to remain the same. All files committed to the layers of the image will be created with the timestamp.
|
||||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
This example saves an image based on the container.
|
||||
|
@ -121,6 +126,20 @@ This example commits the container to the image on the local registry using cred
|
|||
This example saves an image based on the container, but stores dates based on epoch time.
|
||||
`buildah commit --timestamp=0 containerID newImageName`
|
||||
|
||||
### Building an multi-architecture image using a --manifest option (Requires emulation software)
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
build() {
|
||||
ctr=$(./bin/buildah from --arch $1 ubi8)
|
||||
./bin/buildah run $ctr dnf install -y iputils
|
||||
./bin/buildah commit --manifest ubi8ping $ctr
|
||||
}
|
||||
build arm
|
||||
build amd64
|
||||
build s390x
|
||||
```
|
||||
|
||||
## ENVIRONMENT
|
||||
|
||||
**BUILD\_REGISTRY\_SOURCES**
|
||||
|
|
|
@ -53,6 +53,10 @@ Add a line to /etc/hosts. The format is hostname:ip. The **--add-host** option c
|
|||
|
||||
Set the ARCH of the image to be pulled to the provided value instead of using the architecture of the host. (Examples: aarch64, arm, i686, ppc64le, s390x, x86_64)
|
||||
|
||||
**--arch**="ARCH"
|
||||
|
||||
Set the ARCH of the image to be pulled to the provided value instead of using the architecture of the host.
|
||||
|
||||
**--authfile** *path*
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `buildah login`.
|
||||
|
@ -279,6 +283,10 @@ another process.
|
|||
|
||||
Set the OS of the image to be pulled instead of using the current operating system of the host.
|
||||
|
||||
**--os**="OS"
|
||||
|
||||
Set the OS of the image to be pulled to the provided value instead of using the current operating system of the host.
|
||||
|
||||
**--pid** *how*
|
||||
|
||||
Sets the configuration for PID namespaces when the container is subsequently
|
||||
|
@ -341,7 +349,7 @@ If you omit the unit, the system uses bytes. If you omit the size entirely, the
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
**--ulimit** *type*=*soft-limit*[:*hard-limit*]
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ The default certificates directory is _/etc/containers/certs.d_.
|
|||
|
||||
**--tls-verify**
|
||||
|
||||
Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true,
|
||||
Require HTTPS and verification of certificates when talking to container registries (default: true). If explicitly set to true,
|
||||
then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified,
|
||||
TLS verification will be used unless the target registry is listed as an insecure registry in registries.conf.
|
||||
TLS verification cannot be used when talking to an insecure registry.
|
||||
|
|
|
@ -76,7 +76,7 @@ image. This option is rarely used.
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
**--variant**
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ Sign the pushed images using the GPG key that matches the specified fingerprint.
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
|
|
|
@ -78,6 +78,10 @@ If an image needs to be pulled from the registry, suppress progress output.
|
|||
|
||||
Set the OS of the image to be pulled instead of using the current operating system of the host.
|
||||
|
||||
**--os**="OS"
|
||||
|
||||
Set the OS of the image to be pulled to the provided value instead of using the current operating system of the host.
|
||||
|
||||
**--policy**=**always**|**missing**|**never**
|
||||
|
||||
Pull image policy. The default is **missing**.
|
||||
|
@ -92,7 +96,7 @@ Don't copy signatures when pulling images.
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
**--variant**=""
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ Sign the pushed image using the GPG key that matches the specified fingerprint.
|
|||
|
||||
**--tls-verify** *bool-value*
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ type BuildOptions struct {
|
|||
// IgnoreUnrecognizedInstructions tells us to just log instructions we
|
||||
// don't recognize, and try to keep going.
|
||||
IgnoreUnrecognizedInstructions bool
|
||||
// Manifest Name to which the image will be added.
|
||||
Manifest string
|
||||
// Quiet tells us whether or not to announce steps as we go through them.
|
||||
Quiet bool
|
||||
// Isolation controls how Run() runs things.
|
||||
|
|
|
@ -67,6 +67,7 @@ type BudResults struct {
|
|||
Label []string
|
||||
Logfile string
|
||||
Loglevel int
|
||||
Manifest string
|
||||
NoCache bool
|
||||
Timestamp int64
|
||||
Pull bool
|
||||
|
@ -197,6 +198,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
|||
if err := fs.MarkHidden("log-rusage"); err != nil {
|
||||
panic(fmt.Sprintf("error marking the log-rusage flag as hidden: %v", err))
|
||||
}
|
||||
fs.StringVar(&flags.Manifest, "manifest", "", "add the image to the specified manifest list. Creates manifest if it does not exist")
|
||||
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.String("os", runtime.GOOS, "set the OS to the provided value instead of the current operating system of the host")
|
||||
fs.String("platform", parse.DefaultPlatform(), "set the OS/ARCH to the provided value instead of the current operating system and architecture of the host (for example `linux/arm`)")
|
||||
|
@ -241,6 +243,7 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
|
|||
flagCompletion["label"] = commonComp.AutocompleteNone
|
||||
flagCompletion["logfile"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["loglevel"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["manifest"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["os"] = commonComp.AutocompleteNone
|
||||
flagCompletion["platform"] = commonComp.AutocompleteNone
|
||||
flagCompletion["runtime-flag"] = commonComp.AutocompleteNone
|
||||
|
|
Loading…
Reference in New Issue