mirror of
https://github.com/containers/buildah.git
synced 2025-07-31 15:24:26 +03:00
add --sign-by to bud/commit/push, --remove-signatures for pull/push
Add the --sign-by option to `buildah build-using-dockerfile`, `buildah commit`, `buildah push`, and `buildah manifest push`. Add the `--remove-signatures` option to `buildah pull`, `buildah push`, and `buildah manifest push`. We just pass them to the image library, which does all of the heavy lifting. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com> Closes: #2085 Approved by: rhatdan
This commit is contained in:
committed by
Atomic Bot
parent
ca0819f640
commit
a925f79cc3
@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type budResults struct {
|
type budOptions struct {
|
||||||
*buildahcli.LayerResults
|
*buildahcli.LayerResults
|
||||||
*buildahcli.BudResults
|
*buildahcli.BudResults
|
||||||
*buildahcli.UserNSResults
|
*buildahcli.UserNSResults
|
||||||
@ -45,7 +45,7 @@ func init() {
|
|||||||
Long: budDescription,
|
Long: budDescription,
|
||||||
//Flags: sortFlags(append(append(buildahcli.BudFlags, buildahcli.LayerFlags...), buildahcli.FromAndBudFlags...)),
|
//Flags: sortFlags(append(append(buildahcli.BudFlags, buildahcli.LayerFlags...), buildahcli.FromAndBudFlags...)),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
br := budResults{
|
br := budOptions{
|
||||||
&layerFlagsResults,
|
&layerFlagsResults,
|
||||||
&budFlagResults,
|
&budFlagResults,
|
||||||
&userNSResults,
|
&userNSResults,
|
||||||
@ -90,7 +90,7 @@ func getDockerfiles(files []string) []string {
|
|||||||
return dockerfiles
|
return dockerfiles
|
||||||
}
|
}
|
||||||
|
|
||||||
func budCmd(c *cobra.Command, inputArgs []string, iopts budResults) error {
|
func budCmd(c *cobra.Command, inputArgs []string, iopts budOptions) error {
|
||||||
output := ""
|
output := ""
|
||||||
tags := []string{}
|
tags := []string{}
|
||||||
if c.Flag("tag").Changed {
|
if c.Flag("tag").Changed {
|
||||||
@ -340,6 +340,7 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budResults) error {
|
|||||||
TransientMounts: transientMounts,
|
TransientMounts: transientMounts,
|
||||||
Devices: devices,
|
Devices: devices,
|
||||||
DefaultEnv: defaultContainerConfig.GetDefaultEnv(),
|
DefaultEnv: defaultContainerConfig.GetDefaultEnv(),
|
||||||
|
SignBy: iopts.SignBy,
|
||||||
}
|
}
|
||||||
|
|
||||||
if iopts.Quiet {
|
if iopts.Quiet {
|
||||||
|
@ -31,6 +31,7 @@ type commitInputOptions struct {
|
|||||||
referenceTime string
|
referenceTime string
|
||||||
rm bool
|
rm bool
|
||||||
signaturePolicy string
|
signaturePolicy string
|
||||||
|
signBy string
|
||||||
squash bool
|
squash bool
|
||||||
tlsVerify bool
|
tlsVerify bool
|
||||||
}
|
}
|
||||||
@ -70,6 +71,7 @@ func init() {
|
|||||||
flags.BoolVar(&opts.omitTimestamp, "omit-timestamp", false, "set created timestamp to epoch 0 to allow for deterministic builds")
|
flags.BoolVar(&opts.omitTimestamp, "omit-timestamp", false, "set created timestamp to epoch 0 to allow for deterministic builds")
|
||||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when writing images")
|
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when writing images")
|
||||||
flags.StringVar(&opts.referenceTime, "reference-time", "", "set the timestamp on the image to match the named `file`")
|
flags.StringVar(&opts.referenceTime, "reference-time", "", "set the timestamp on the image to match the named `file`")
|
||||||
|
flags.StringVar(&opts.signBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||||
|
|
||||||
if err := flags.MarkHidden("reference-time"); err != nil {
|
if err := flags.MarkHidden("reference-time"); err != nil {
|
||||||
panic(fmt.Sprintf("error marking reference-time as hidden: %v", err))
|
panic(fmt.Sprintf("error marking reference-time as hidden: %v", err))
|
||||||
@ -175,6 +177,7 @@ func commitCmd(c *cobra.Command, args []string, iopts commitInputOptions) error
|
|||||||
Squash: iopts.squash,
|
Squash: iopts.squash,
|
||||||
BlobDirectory: iopts.blobCache,
|
BlobDirectory: iopts.blobCache,
|
||||||
OmitTimestamp: iopts.omitTimestamp,
|
OmitTimestamp: iopts.omitTimestamp,
|
||||||
|
SignBy: iopts.signBy,
|
||||||
}
|
}
|
||||||
if !iopts.quiet {
|
if !iopts.quiet {
|
||||||
options.ReportWriter = os.Stderr
|
options.ReportWriter = os.Stderr
|
||||||
|
@ -38,8 +38,8 @@ type manifestAnnotateOpts = struct {
|
|||||||
}
|
}
|
||||||
type manifestInspectOpts = struct{}
|
type manifestInspectOpts = struct{}
|
||||||
type manifestPushOpts = struct {
|
type manifestPushOpts = struct {
|
||||||
purge, quiet, all, tlsVerify bool
|
purge, quiet, all, tlsVerify, removeSignatures bool
|
||||||
authfile, certDir, creds, digestfile, signaturePolicy string
|
authfile, certDir, creds, digestfile, signaturePolicy, signBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -194,6 +194,8 @@ func init() {
|
|||||||
flags.StringVar(&manifestPushOpts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
|
flags.StringVar(&manifestPushOpts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
|
||||||
flags.StringVar(&manifestPushOpts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
flags.StringVar(&manifestPushOpts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
||||||
flags.StringVar(&manifestPushOpts.digestfile, "digestfile", "", "after copying the image, write the digest of the resulting digest to the file")
|
flags.StringVar(&manifestPushOpts.digestfile, "digestfile", "", "after copying the image, write the digest of the resulting digest to the file")
|
||||||
|
flags.BoolVarP(&manifestPushOpts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pushing images")
|
||||||
|
flags.StringVar(&manifestPushOpts.signBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||||
flags.StringVar(&manifestPushOpts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
flags.StringVar(&manifestPushOpts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
||||||
if err := flags.MarkHidden("signature-policy"); err != nil {
|
if err := flags.MarkHidden("signature-policy"); err != nil {
|
||||||
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
||||||
@ -642,6 +644,8 @@ func manifestPushCmd(c *cobra.Command, args []string, opts manifestPushOpts) err
|
|||||||
SystemContext: systemContext,
|
SystemContext: systemContext,
|
||||||
ImageListSelection: cp.CopySpecificImages,
|
ImageListSelection: cp.CopySpecificImages,
|
||||||
Instances: nil,
|
Instances: nil,
|
||||||
|
RemoveSignatures: opts.removeSignatures,
|
||||||
|
SignBy: opts.signBy,
|
||||||
}
|
}
|
||||||
if opts.all {
|
if opts.all {
|
||||||
options.ImageListSelection = cp.CopyAllImages
|
options.ImageListSelection = cp.CopyAllImages
|
||||||
|
@ -12,22 +12,23 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pullResults struct {
|
type pullOptions struct {
|
||||||
allTags bool
|
allTags bool
|
||||||
authfile string
|
authfile string
|
||||||
blobCache string
|
blobCache string
|
||||||
certDir string
|
certDir string
|
||||||
creds string
|
creds string
|
||||||
overrideArch string
|
overrideArch string
|
||||||
overrideOS string
|
overrideOS string
|
||||||
signaturePolicy string
|
signaturePolicy string
|
||||||
quiet bool
|
quiet bool
|
||||||
tlsVerify bool
|
removeSignatures bool
|
||||||
|
tlsVerify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var (
|
var (
|
||||||
opts pullResults
|
opts pullOptions
|
||||||
|
|
||||||
pullDescription = ` Pulls an image from a registry and stores it locally.
|
pullDescription = ` Pulls an image from a registry and stores it locally.
|
||||||
An image can be pulled using its tag or digest. If a tag is not
|
An image can be pulled using its tag or digest. If a tag is not
|
||||||
@ -54,6 +55,7 @@ func init() {
|
|||||||
flags.StringVar(&opts.blobCache, "blob-cache", "", "store copies of pulled image blobs in the specified directory")
|
flags.StringVar(&opts.blobCache, "blob-cache", "", "store copies of pulled image blobs in the specified directory")
|
||||||
flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
|
flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
|
||||||
flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
||||||
|
flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pulling image")
|
||||||
flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
||||||
if err := flags.MarkHidden("signature-policy"); err != nil {
|
if err := flags.MarkHidden("signature-policy"); err != nil {
|
||||||
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
||||||
@ -75,7 +77,7 @@ func init() {
|
|||||||
rootCmd.AddCommand(pullCommand)
|
rootCmd.AddCommand(pullCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pullCmd(c *cobra.Command, args []string, iopts pullResults) error {
|
func pullCmd(c *cobra.Command, args []string, iopts pullOptions) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return errors.Errorf("an image name must be specified")
|
return errors.Errorf("an image name must be specified")
|
||||||
}
|
}
|
||||||
@ -106,6 +108,7 @@ func pullCmd(c *cobra.Command, args []string, iopts pullResults) error {
|
|||||||
BlobDirectory: iopts.blobCache,
|
BlobDirectory: iopts.blobCache,
|
||||||
AllTags: iopts.allTags,
|
AllTags: iopts.allTags,
|
||||||
ReportWriter: os.Stderr,
|
ReportWriter: os.Stderr,
|
||||||
|
RemoveSignatures: iopts.removeSignatures,
|
||||||
}
|
}
|
||||||
|
|
||||||
if iopts.quiet {
|
if iopts.quiet {
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pushResults struct {
|
type pushOptions struct {
|
||||||
authfile string
|
authfile string
|
||||||
blobCache string
|
blobCache string
|
||||||
certDir string
|
certDir string
|
||||||
@ -29,13 +29,15 @@ type pushResults struct {
|
|||||||
disableCompression bool
|
disableCompression bool
|
||||||
format string
|
format string
|
||||||
quiet bool
|
quiet bool
|
||||||
|
removeSignatures bool
|
||||||
signaturePolicy string
|
signaturePolicy string
|
||||||
|
signBy string
|
||||||
tlsVerify bool
|
tlsVerify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var (
|
var (
|
||||||
opts pushResults
|
opts pushOptions
|
||||||
pushDescription = fmt.Sprintf(`
|
pushDescription = fmt.Sprintf(`
|
||||||
Pushes an image to a specified location.
|
Pushes an image to a specified location.
|
||||||
|
|
||||||
@ -71,6 +73,8 @@ func init() {
|
|||||||
flags.BoolVarP(&opts.disableCompression, "disable-compression", "D", false, "don't compress layers")
|
flags.BoolVarP(&opts.disableCompression, "disable-compression", "D", false, "don't compress layers")
|
||||||
flags.StringVarP(&opts.format, "format", "f", "", "manifest type (oci, v2s1, or v2s2) to use when saving image using the 'dir:' transport (default is manifest type of source)")
|
flags.StringVarP(&opts.format, "format", "f", "", "manifest type (oci, v2s1, or v2s2) to use when saving image using the 'dir:' transport (default is manifest type of source)")
|
||||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pushing images")
|
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pushing images")
|
||||||
|
flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pushing image")
|
||||||
|
flags.StringVar(&opts.signBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||||
flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
||||||
if err := flags.MarkHidden("signature-policy"); err != nil {
|
if err := flags.MarkHidden("signature-policy"); err != nil {
|
||||||
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
|
||||||
@ -83,7 +87,7 @@ func init() {
|
|||||||
rootCmd.AddCommand(pushCommand)
|
rootCmd.AddCommand(pushCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pushCmd(c *cobra.Command, args []string, iopts pushResults) error {
|
func pushCmd(c *cobra.Command, args []string, iopts pushOptions) error {
|
||||||
var src, destSpec string
|
var src, destSpec string
|
||||||
|
|
||||||
if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
|
if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
|
||||||
@ -167,6 +171,8 @@ func pushCmd(c *cobra.Command, args []string, iopts pushResults) error {
|
|||||||
Store: store,
|
Store: store,
|
||||||
SystemContext: systemContext,
|
SystemContext: systemContext,
|
||||||
BlobDirectory: iopts.blobCache,
|
BlobDirectory: iopts.blobCache,
|
||||||
|
RemoveSignatures: iopts.removeSignatures,
|
||||||
|
SignBy: iopts.signBy,
|
||||||
}
|
}
|
||||||
if !iopts.quiet {
|
if !iopts.quiet {
|
||||||
options.ReportWriter = os.Stderr
|
options.ReportWriter = os.Stderr
|
||||||
|
11
commit.go
11
commit.go
@ -81,6 +81,8 @@ type CommitOptions struct {
|
|||||||
// OmitTimestamp forces epoch 0 as created timestamp to allow for
|
// OmitTimestamp forces epoch 0 as created timestamp to allow for
|
||||||
// deterministic, content-addressable builds.
|
// deterministic, content-addressable builds.
|
||||||
OmitTimestamp bool
|
OmitTimestamp bool
|
||||||
|
// SignBy is the fingerprint of a GPG key to use for signing the image.
|
||||||
|
SignBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushOptions can be used to alter how an image is copied somewhere.
|
// PushOptions can be used to alter how an image is copied somewhere.
|
||||||
@ -115,6 +117,11 @@ type PushOptions struct {
|
|||||||
// the user will be displayed, this is best used for logging.
|
// the user will be displayed, this is best used for logging.
|
||||||
// The default is false.
|
// The default is false.
|
||||||
Quiet bool
|
Quiet bool
|
||||||
|
// SignBy is the fingerprint of a GPG key to use for signing the image.
|
||||||
|
SignBy string
|
||||||
|
// RemoveSignatures causes any existing signatures for the image to be
|
||||||
|
// discarded for the pushed copy.
|
||||||
|
RemoveSignatures bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -294,7 +301,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
|||||||
systemContext.DirForceCompress = true
|
systemContext.DirForceCompress = true
|
||||||
}
|
}
|
||||||
var manifestBytes []byte
|
var manifestBytes []byte
|
||||||
if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "")); err != nil {
|
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)
|
return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID)
|
||||||
}
|
}
|
||||||
// If we've got more names to attach, and we know how to do that for
|
// If we've got more names to attach, and we know how to do that for
|
||||||
@ -426,7 +433,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
|
|||||||
systemContext.DirForceCompress = true
|
systemContext.DirForceCompress = true
|
||||||
}
|
}
|
||||||
var manifestBytes []byte
|
var manifestBytes []byte
|
||||||
if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType)); err != nil {
|
if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType, options.RemoveSignatures, options.SignBy)); err != nil {
|
||||||
return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(maybeCachedSrc), transports.ImageName(dest))
|
return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(maybeCachedSrc), transports.ImageName(dest))
|
||||||
}
|
}
|
||||||
if options.ReportWriter != nil {
|
if options.ReportWriter != nil {
|
||||||
|
@ -18,7 +18,7 @@ const (
|
|||||||
DOCKER = "docker"
|
DOCKER = "docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
|
func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string, removeSignatures bool, addSigner string) *cp.Options {
|
||||||
sourceCtx := getSystemContext(store, nil, "")
|
sourceCtx := getSystemContext(store, nil, "")
|
||||||
if sourceSystemContext != nil {
|
if sourceSystemContext != nil {
|
||||||
*sourceCtx = *sourceSystemContext
|
*sourceCtx = *sourceSystemContext
|
||||||
@ -33,6 +33,8 @@ func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemCon
|
|||||||
SourceCtx: sourceCtx,
|
SourceCtx: sourceCtx,
|
||||||
DestinationCtx: destinationCtx,
|
DestinationCtx: destinationCtx,
|
||||||
ForceManifestMIMEType: manifestType,
|
ForceManifestMIMEType: manifestType,
|
||||||
|
RemoveSignatures: removeSignatures,
|
||||||
|
SignBy: addSigner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +326,7 @@ return 1
|
|||||||
--format
|
--format
|
||||||
-f
|
-f
|
||||||
--iidfile
|
--iidfile
|
||||||
|
--sign-by
|
||||||
"
|
"
|
||||||
|
|
||||||
local all_options="$options_with_args $boolean_options"
|
local all_options="$options_with_args $boolean_options"
|
||||||
@ -415,6 +416,7 @@ return 1
|
|||||||
--runtime-flag
|
--runtime-flag
|
||||||
--security-opt
|
--security-opt
|
||||||
--shm-size
|
--shm-size
|
||||||
|
--sign-by
|
||||||
-t
|
-t
|
||||||
--tag
|
--tag
|
||||||
--target
|
--target
|
||||||
@ -577,6 +579,7 @@ return 1
|
|||||||
--quiet
|
--quiet
|
||||||
-q
|
-q
|
||||||
--tls-verify
|
--tls-verify
|
||||||
|
--remove-signatures
|
||||||
"
|
"
|
||||||
|
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
@ -603,6 +606,7 @@ return 1
|
|||||||
--quiet
|
--quiet
|
||||||
-q
|
-q
|
||||||
--tls-verify
|
--tls-verify
|
||||||
|
--remove-signatures
|
||||||
"
|
"
|
||||||
|
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
@ -611,6 +615,7 @@ return 1
|
|||||||
--creds
|
--creds
|
||||||
--format
|
--format
|
||||||
-f
|
-f
|
||||||
|
--sign-by
|
||||||
"
|
"
|
||||||
|
|
||||||
local all_options="$options_with_args $boolean_options"
|
local all_options="$options_with_args $boolean_options"
|
||||||
@ -810,6 +815,7 @@ return 1
|
|||||||
--help
|
--help
|
||||||
-h
|
-h
|
||||||
--all
|
--all
|
||||||
|
--remove-signatures
|
||||||
"
|
"
|
||||||
|
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
@ -818,6 +824,7 @@ return 1
|
|||||||
--creds
|
--creds
|
||||||
--digestfile
|
--digestfile
|
||||||
--purge
|
--purge
|
||||||
|
--sign-by
|
||||||
--tls-verify
|
--tls-verify
|
||||||
"
|
"
|
||||||
|
|
||||||
|
@ -414,6 +414,10 @@ Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater tha
|
|||||||
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m`(megabytes), or `g` (gigabytes).
|
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m`(megabytes), or `g` (gigabytes).
|
||||||
If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`.
|
If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`.
|
||||||
|
|
||||||
|
**--sign-by** *fingerprint*
|
||||||
|
|
||||||
|
Sign the built image using the GPG key that matches the specified fingerprint.
|
||||||
|
|
||||||
**--squash**
|
**--squash**
|
||||||
|
|
||||||
Squash all of the new image's layers (including those inherited from a base image) into a single new layer.
|
Squash all of the new image's layers (including those inherited from a base image) into a single new layer.
|
||||||
|
@ -64,6 +64,10 @@ When writing the output image, suppress progress output.
|
|||||||
Remove the container and its content after committing it to an image.
|
Remove the container and its content after committing it to an image.
|
||||||
Default leaves the container and its content in place.
|
Default leaves the container and its content in place.
|
||||||
|
|
||||||
|
**--sign-by** *fingerprint*
|
||||||
|
|
||||||
|
Sign the new image using the GPG key that matches the specified fingerprint.
|
||||||
|
|
||||||
**--squash**
|
**--squash**
|
||||||
|
|
||||||
Squash all of the new image's layers (including those inherited from a base image) into a single new layer.
|
Squash all of the new image's layers (including those inherited from a base image) into a single new layer.
|
||||||
|
@ -47,6 +47,14 @@ After copying the image, write the digest of the resulting image to the file.
|
|||||||
|
|
||||||
Delete the manifest list or image index from local storage if pushing succeeds.
|
Delete the manifest list or image index from local storage if pushing succeeds.
|
||||||
|
|
||||||
|
**--remove-signatures**
|
||||||
|
|
||||||
|
Don't copy signatures when pushing images.
|
||||||
|
|
||||||
|
**--sign-by** *fingerprint*
|
||||||
|
|
||||||
|
Sign the pushed images using the GPG key that matches the specified fingerprint.
|
||||||
|
|
||||||
**--tls-verify** *bool-value*
|
**--tls-verify** *bool-value*
|
||||||
|
|
||||||
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
||||||
|
@ -66,6 +66,10 @@ value can be entered. The password is entered without echo.
|
|||||||
|
|
||||||
If an image needs to be pulled from the registry, suppress progress output.
|
If an image needs to be pulled from the registry, suppress progress output.
|
||||||
|
|
||||||
|
**--remove-signatures**
|
||||||
|
|
||||||
|
Don't copy signatures when pulling images.
|
||||||
|
|
||||||
**--shm-size**=""
|
**--shm-size**=""
|
||||||
|
|
||||||
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# buildah-push"1" "June 2017" "buildah"
|
# buildah-push "1" "June 2017" "buildah"
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
buildah\-push - Push an image from local storage to elsewhere.
|
buildah\-push - Push an image from local storage to elsewhere.
|
||||||
@ -74,6 +74,14 @@ Manifest Type (oci, v2s1, or v2s2) to use when saving image to directory using t
|
|||||||
|
|
||||||
When writing the output image, suppress progress output.
|
When writing the output image, suppress progress output.
|
||||||
|
|
||||||
|
**--remove-signatures**
|
||||||
|
|
||||||
|
Don't copy signatures when pushing images.
|
||||||
|
|
||||||
|
**--sign-by** *fingerprint*
|
||||||
|
|
||||||
|
Sign the pushed image using the GPG key that matches the specified fingerprint.
|
||||||
|
|
||||||
**--tls-verify** *bool-value*
|
**--tls-verify** *bool-value*
|
||||||
|
|
||||||
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# buildah-rename "9" "July 2018" "buildah"
|
# buildah-rename "1" "July 2018" "buildah"
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
buildah\-rename - Rename a local container.
|
buildah\-rename - Rename a local container.
|
||||||
|
@ -152,12 +152,14 @@ type BuildOptions struct {
|
|||||||
ForceRmIntermediateCtrs bool
|
ForceRmIntermediateCtrs bool
|
||||||
// BlobDirectory is a directory which we'll use for caching layer blobs.
|
// BlobDirectory is a directory which we'll use for caching layer blobs.
|
||||||
BlobDirectory string
|
BlobDirectory string
|
||||||
// Target the targeted FROM in the Dockerfile to build
|
// Target the targeted FROM in the Dockerfile to build.
|
||||||
Target string
|
Target string
|
||||||
// Devices are the additional devices to add to the containers
|
// Devices are the additional devices to add to the containers.
|
||||||
Devices []configs.Device
|
Devices []configs.Device
|
||||||
//DefaultEnv for containers
|
// DefaultEnv for containers.
|
||||||
DefaultEnv []string
|
DefaultEnv []string
|
||||||
|
// SignBy is the fingerprint of a GPG key to use for signing images.
|
||||||
|
SignBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
|
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
|
||||||
|
@ -93,6 +93,7 @@ type Executor struct {
|
|||||||
buildArgs map[string]string
|
buildArgs map[string]string
|
||||||
capabilities []string
|
capabilities []string
|
||||||
devices []configs.Device
|
devices []configs.Device
|
||||||
|
signBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
|
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
|
||||||
@ -149,6 +150,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
|
|||||||
buildArgs: options.Args,
|
buildArgs: options.Args,
|
||||||
capabilities: options.Capabilities,
|
capabilities: options.Capabilities,
|
||||||
devices: options.Devices,
|
devices: options.Devices,
|
||||||
|
signBy: options.SignBy,
|
||||||
}
|
}
|
||||||
if exec.err == nil {
|
if exec.err == nil {
|
||||||
exec.err = os.Stderr
|
exec.err = os.Stderr
|
||||||
|
@ -1203,6 +1203,7 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
|
|||||||
Squash: s.executor.squash,
|
Squash: s.executor.squash,
|
||||||
EmptyLayer: emptyLayer,
|
EmptyLayer: emptyLayer,
|
||||||
BlobDirectory: s.executor.blobDirectory,
|
BlobDirectory: s.executor.blobDirectory,
|
||||||
|
SignBy: s.executor.signBy,
|
||||||
}
|
}
|
||||||
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
|
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -53,6 +53,8 @@ type PushOptions struct {
|
|||||||
ImageListSelection cp.ImageListSelection // set to either CopySystemImage, CopyAllImages, or CopySpecificImages
|
ImageListSelection cp.ImageListSelection // set to either CopySystemImage, CopyAllImages, or CopySpecificImages
|
||||||
Instances []digest.Digest // instances to copy if ImageListSelection == CopySpecificImages
|
Instances []digest.Digest // instances to copy if ImageListSelection == CopySpecificImages
|
||||||
ReportWriter io.Writer // will be used to log the writing of the list and any blobs
|
ReportWriter io.Writer // will be used to log the writing of the list and any blobs
|
||||||
|
SignBy string // fingerprint of GPG key to use to sign images
|
||||||
|
RemoveSignatures bool // true to discard signatures in images
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new list containing information about the specified image,
|
// Create creates a new list containing information about the specified image,
|
||||||
@ -211,6 +213,8 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push
|
|||||||
SourceCtx: options.SystemContext,
|
SourceCtx: options.SystemContext,
|
||||||
DestinationCtx: options.SystemContext,
|
DestinationCtx: options.SystemContext,
|
||||||
ReportWriter: options.ReportWriter,
|
ReportWriter: options.ReportWriter,
|
||||||
|
RemoveSignatures: options.RemoveSignatures,
|
||||||
|
SignBy: options.SignBy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy whatever we were asked to copy.
|
// Copy whatever we were asked to copy.
|
||||||
|
@ -70,6 +70,7 @@ type BudResults struct {
|
|||||||
Runtime string
|
Runtime string
|
||||||
RuntimeFlags []string
|
RuntimeFlags []string
|
||||||
SignaturePolicy string
|
SignaturePolicy string
|
||||||
|
SignBy string
|
||||||
Squash bool
|
Squash bool
|
||||||
Tag []string
|
Tag []string
|
||||||
Target string
|
Target string
|
||||||
@ -168,8 +169,9 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
|||||||
fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build")
|
fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build")
|
||||||
// "runtime" definition moved to avoid name collision in podman build. Defined in cmd/buildah/bud.go.
|
// "runtime" definition moved to avoid name collision in podman build. Defined in cmd/buildah/bud.go.
|
||||||
fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
|
fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
|
||||||
|
fs.StringVar(&flags.SignBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||||
fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
||||||
fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer.")
|
fs.BoolVar(&flags.Squash, "squash", false, "squash newly built layers into a single new layer")
|
||||||
fs.StringArrayVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image")
|
fs.StringArrayVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image")
|
||||||
fs.StringVar(&flags.Target, "target", "", "set the target build stage to build")
|
fs.StringVar(&flags.Target, "target", "", "set the target build stage to build")
|
||||||
fs.BoolVar(&flags.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
|
fs.BoolVar(&flags.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
|
||||||
|
5
pull.go
5
pull.go
@ -49,6 +49,9 @@ type PullOptions struct {
|
|||||||
// AllTags is a boolean value that determines if all tagged images
|
// AllTags is a boolean value that determines if all tagged images
|
||||||
// will be downloaded from the repository. The default is false.
|
// will be downloaded from the repository. The default is false.
|
||||||
AllTags bool
|
AllTags bool
|
||||||
|
// RemoveSignatures causes any existing signatures for the image to be
|
||||||
|
// discarded when pulling it.
|
||||||
|
RemoveSignatures bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference) (string, error) {
|
func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference) (string, error) {
|
||||||
@ -260,7 +263,7 @@ func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageRefer
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName)
|
logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName)
|
||||||
if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "")); err != nil {
|
if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "", options.RemoveSignatures, "")); err != nil {
|
||||||
logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err)
|
logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
94
tests/sign.bats
Normal file
94
tests/sign.bats
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
@test "commit-pull-push-signatures" {
|
||||||
|
if ! which gpg > /dev/null 2> /dev/null ; then
|
||||||
|
skip 'gpg command not found in $PATH'
|
||||||
|
fi
|
||||||
|
|
||||||
|
export GNUPGHOME=${TESTDIR}/.gnupg
|
||||||
|
cat > genkey-answers <<- EOF
|
||||||
|
%echo Generating a basic OpenPGP key
|
||||||
|
Key-Type: RSA
|
||||||
|
Key-Length: 512
|
||||||
|
Name-Real: Amanda Lorian
|
||||||
|
Name-Comment: Mandy to her friends
|
||||||
|
Name-Email: amanda@localhost
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
gpg --batch --gen-key < genkey-answers
|
||||||
|
|
||||||
|
mkdir -p ${TESTDIR}/signed-image ${TESTDIR}/unsigned-image
|
||||||
|
|
||||||
|
run_buildah from --quiet --pull=false --signature-policy ${TESTSDIR}/policy.json alpine
|
||||||
|
cid=$output
|
||||||
|
run_buildah commit --signature-policy ${TESTSDIR}/policy.json --sign-by amanda@localhost $cid signed-alpine-image
|
||||||
|
|
||||||
|
# Pushing should preserve the signature.
|
||||||
|
run_buildah push --signature-policy ${TESTSDIR}/policy.json signed-alpine-image dir:${TESTDIR}/signed-image
|
||||||
|
ls -l ${TESTDIR}/signed-image/
|
||||||
|
test -s ${TESTDIR}/signed-image/signature-1
|
||||||
|
|
||||||
|
# Pushing with --remove-signatures should remove the signature.
|
||||||
|
run_buildah push --signature-policy ${TESTSDIR}/policy.json --remove-signatures signed-alpine-image dir:${TESTDIR}/unsigned-image
|
||||||
|
ls -l ${TESTDIR}/unsigned-image/
|
||||||
|
! test -s ${TESTDIR}/unsigned-image/signature-1
|
||||||
|
|
||||||
|
run_buildah commit --signature-policy ${TESTSDIR}/policy.json $cid unsigned-alpine-image
|
||||||
|
# Pushing with --sign-by should fail add the signature to a dir: location, if it tries to add them.
|
||||||
|
run_buildah 1 push --signature-policy ${TESTSDIR}/policy.json --sign-by amanda@localhost unsigned-alpine-image dir:${TESTDIR}/signed-image
|
||||||
|
expect_output --substring "Cannot determine canonical Docker reference"
|
||||||
|
|
||||||
|
# Clear out images, so that we don't have leftover signatures when we pull in an image that will end up
|
||||||
|
# causing us to merge its contents with the image with the same ID.
|
||||||
|
run_buildah rmi -a -f
|
||||||
|
|
||||||
|
# Pulling with --remove-signatures should remove signatures, and pushing should have none to keep.
|
||||||
|
run_buildah pull --signature-policy ${TESTSDIR}/policy.json --quiet dir:${TESTDIR}/signed-image
|
||||||
|
imageID="$output"
|
||||||
|
run_buildah push --signature-policy ${TESTSDIR}/policy.json "$imageID" dir:${TESTDIR}/unsigned-image
|
||||||
|
ls -l ${TESTDIR}/unsigned-image/
|
||||||
|
! test -s ${TESTDIR}/unsigned-image/signature-1
|
||||||
|
|
||||||
|
# Build a manifest list and try to push the list with signatures.
|
||||||
|
run_buildah manifest create list
|
||||||
|
run_buildah manifest add list $imageID
|
||||||
|
run_buildah 1 manifest push --signature-policy ${TESTSDIR}/policy.json --sign-by amanda@localhost --all list dir:${TESTDIR}/signed-image
|
||||||
|
expect_output --substring "Cannot determine canonical Docker reference"
|
||||||
|
run_buildah manifest push --signature-policy ${TESTSDIR}/policy.json --all list dir:${TESTDIR}/unsigned-image
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "build-with-dockerfile-signatures" {
|
||||||
|
if ! which gpg > /dev/null 2> /dev/null ; then
|
||||||
|
skip 'gpg command not found in $PATH'
|
||||||
|
fi
|
||||||
|
|
||||||
|
export GNUPGHOME=${TESTDIR}/.gnupg
|
||||||
|
cat > genkey-answers <<- EOF
|
||||||
|
%echo Generating a basic OpenPGP key
|
||||||
|
Key-Type: RSA
|
||||||
|
Key-Length: 512
|
||||||
|
Name-Real: Amanda Lorian
|
||||||
|
Name-Comment: Mandy to her friends
|
||||||
|
Name-Email: amanda@localhost
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
gpg --batch --gen-key < genkey-answers
|
||||||
|
|
||||||
|
cat > Dockerfile <<- EOF
|
||||||
|
FROM scratch
|
||||||
|
ADD Dockerfile /
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# We should be able to sign at build-time.
|
||||||
|
run_buildah bud --signature-policy ${TESTSDIR}/policy.json --sign-by amanda@localhost -t signed-scratch-image .
|
||||||
|
|
||||||
|
mkdir -p ${TESTDIR}/signed-image
|
||||||
|
# Pushing should preserve the signature.
|
||||||
|
run_buildah push --signature-policy ${TESTSDIR}/policy.json signed-scratch-image dir:${TESTDIR}/signed-image
|
||||||
|
ls -l ${TESTDIR}/signed-image/
|
||||||
|
test -s ${TESTDIR}/signed-image/signature-1
|
||||||
|
}
|
Reference in New Issue
Block a user