mirror of https://github.com/containers/podman.git
podman manifest create: accept --amend and --insecure flags
Accept a --amend flag in `podman manifest create`, and treat `--insecure` as we would `--tls-verify=false` in `podman manifest`'s "add", "create", and "push" subcommands. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
3aa92010df
commit
7e7a79b075
|
@ -2,6 +2,7 @@ package manifest
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/common/pkg/auth"
|
||||
|
@ -20,6 +21,7 @@ type manifestAddOptsWrapper struct {
|
|||
entities.ManifestAddOptions
|
||||
|
||||
TLSVerifyCLI bool // CLI only
|
||||
Insecure bool // CLI only
|
||||
CredentialsCLI string
|
||||
}
|
||||
|
||||
|
@ -77,6 +79,8 @@ func init() {
|
|||
flags.StringVar(&manifestAddOpts.OSVersion, osVersionFlagName, "", "override the OS `version` of the specified image")
|
||||
_ = addCmd.RegisterFlagCompletionFunc(osVersionFlagName, completion.AutocompleteNone)
|
||||
|
||||
flags.BoolVar(&manifestAddOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
|
||||
_ = flags.MarkHidden("insecure")
|
||||
flags.BoolVar(&manifestAddOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
|
||||
|
||||
variantFlagName := "variant"
|
||||
|
@ -89,7 +93,7 @@ func init() {
|
|||
}
|
||||
|
||||
func add(cmd *cobra.Command, args []string) error {
|
||||
if err := auth.CheckAuthFile(manifestPushOpts.Authfile); err != nil {
|
||||
if err := auth.CheckAuthFile(manifestAddOpts.Authfile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -109,6 +113,12 @@ func add(cmd *cobra.Command, args []string) error {
|
|||
if cmd.Flags().Changed("tls-verify") {
|
||||
manifestAddOpts.SkipTLSVerify = types.NewOptionalBool(!manifestAddOpts.TLSVerifyCLI)
|
||||
}
|
||||
if cmd.Flags().Changed("insecure") {
|
||||
if manifestAddOpts.SkipTLSVerify != types.OptionalBoolUndefined {
|
||||
return errors.New("--insecure may not be used with --tls-verify")
|
||||
}
|
||||
manifestAddOpts.SkipTLSVerify = types.NewOptionalBool(manifestAddOpts.Insecure)
|
||||
}
|
||||
|
||||
listID, err := registry.ImageEngine().ManifestAdd(context.Background(), args[0], args[1:], manifestAddOpts.ManifestAddOptions)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
package manifest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/podman/v4/cmd/podman/common"
|
||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||
"github.com/containers/podman/v4/pkg/domain/entities"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// manifestCreateOptsWrapper wraps entities.ManifestCreateOptions and prevents leaking
|
||||
// CLI-only fields into the API types.
|
||||
type manifestCreateOptsWrapper struct {
|
||||
entities.ManifestCreateOptions
|
||||
|
||||
TLSVerifyCLI, Insecure bool // CLI only
|
||||
}
|
||||
|
||||
var (
|
||||
manifestCreateOpts = entities.ManifestCreateOptions{}
|
||||
manifestCreateOpts = manifestCreateOptsWrapper{}
|
||||
createCmd = &cobra.Command{
|
||||
Use: "create [options] LIST [IMAGE...]",
|
||||
Short: "Create manifest list or image index",
|
||||
|
@ -32,10 +42,28 @@ func init() {
|
|||
})
|
||||
flags := createCmd.Flags()
|
||||
flags.BoolVar(&manifestCreateOpts.All, "all", false, "add all of the lists' images if the images to add are lists")
|
||||
flags.BoolVar(&manifestCreateOpts.Amend, "amend", false, "modify an existing list if one with the desired name already exists")
|
||||
flags.BoolVar(&manifestCreateOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
|
||||
_ = flags.MarkHidden("insecure")
|
||||
flags.BoolVar(&manifestCreateOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
|
||||
}
|
||||
|
||||
func create(cmd *cobra.Command, args []string) error {
|
||||
imageID, err := registry.ImageEngine().ManifestCreate(registry.Context(), args[0], args[1:], manifestCreateOpts)
|
||||
// TLS verification in c/image is controlled via a `types.OptionalBool`
|
||||
// which allows for distinguishing among set-true, set-false, unspecified
|
||||
// which is important to implement a sane way of dealing with defaults of
|
||||
// boolean CLI flags.
|
||||
if cmd.Flags().Changed("tls-verify") {
|
||||
manifestCreateOpts.SkipTLSVerify = types.NewOptionalBool(!manifestCreateOpts.TLSVerifyCLI)
|
||||
}
|
||||
if cmd.Flags().Changed("insecure") {
|
||||
if manifestCreateOpts.SkipTLSVerify != types.OptionalBoolUndefined {
|
||||
return errors.New("--insecure may not be used with --tls-verify")
|
||||
}
|
||||
manifestCreateOpts.SkipTLSVerify = types.NewOptionalBool(manifestCreateOpts.Insecure)
|
||||
}
|
||||
|
||||
imageID, err := registry.ImageEngine().ManifestCreate(registry.Context(), args[0], args[1:], manifestCreateOpts.ManifestCreateOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package manifest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
|
@ -20,9 +21,9 @@ import (
|
|||
type manifestPushOptsWrapper struct {
|
||||
entities.ImagePushOptions
|
||||
|
||||
TLSVerifyCLI bool // CLI only
|
||||
CredentialsCLI string
|
||||
SignPassphraseFileCLI string
|
||||
TLSVerifyCLI, Insecure bool // CLI only
|
||||
CredentialsCLI string
|
||||
SignPassphraseFileCLI string
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -82,6 +83,8 @@ func init() {
|
|||
_ = pushCmd.RegisterFlagCompletionFunc(signPassphraseFileFlagName, completion.AutocompleteDefault)
|
||||
|
||||
flags.BoolVar(&manifestPushOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
|
||||
flags.BoolVar(&manifestPushOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
|
||||
_ = flags.MarkHidden("insecure")
|
||||
flags.BoolVarP(&manifestPushOpts.Quiet, "quiet", "q", false, "don't output progress information when pushing lists")
|
||||
flags.SetNormalizeFunc(utils.AliasFlags)
|
||||
|
||||
|
@ -130,6 +133,12 @@ func push(cmd *cobra.Command, args []string) error {
|
|||
if cmd.Flags().Changed("tls-verify") {
|
||||
manifestPushOpts.SkipTLSVerify = types.NewOptionalBool(!manifestPushOpts.TLSVerifyCLI)
|
||||
}
|
||||
if cmd.Flags().Changed("insecure") {
|
||||
if manifestPushOpts.SkipTLSVerify != types.OptionalBoolUndefined {
|
||||
return errors.New("--insecure may not be used with --tls-verify")
|
||||
}
|
||||
manifestPushOpts.SkipTLSVerify = types.NewOptionalBool(manifestPushOpts.Insecure)
|
||||
}
|
||||
digest, err := registry.ImageEngine().ManifestPush(registry.Context(), args[0], args[1], manifestPushOpts.ImagePushOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -22,11 +22,23 @@ If any of the images which should be added to the new list or index are
|
|||
themselves lists or indexes, add all of their contents. By default, only one
|
||||
image from such a list will be added to the newly-created list or index.
|
||||
|
||||
#### **--amend**
|
||||
|
||||
If a manifest list named *listnameorindexname* already exists, modify the
|
||||
preexisting list instead of exiting with an error. The contents of
|
||||
*listnameorindexname* are not modified if no *imagename*s are given.
|
||||
|
||||
#### **--tls-verify**
|
||||
|
||||
Require HTTPS and verify certificates when talking to container registries. (defaults to true)
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
```
|
||||
podman manifest create mylist:v1.11
|
||||
9cfd24048d5fc80903f088f1531a21bff01172abe66effa8941a4c2308dc745f
|
||||
podman manifest create --amend mylist:v1.11
|
||||
9cfd24048d5fc80903f088f1531a21bff01172abe66effa8941a4c2308dc745f
|
||||
```
|
||||
|
||||
```
|
||||
|
|
|
@ -36,6 +36,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
|
|||
Name string `schema:"name"`
|
||||
Images []string `schema:"images"`
|
||||
All bool `schema:"all"`
|
||||
Amend bool `schema:"amend"`
|
||||
}{
|
||||
// Add defaults here once needed.
|
||||
}
|
||||
|
@ -70,7 +71,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
imageEngine := abi.ImageEngine{Libpod: runtime}
|
||||
|
||||
createOptions := entities.ManifestCreateOptions{All: query.All}
|
||||
createOptions := entities.ManifestCreateOptions{All: query.All, Amend: query.Amend}
|
||||
manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Images, createOptions)
|
||||
if err != nil {
|
||||
utils.InternalServerError(w, err)
|
||||
|
|
|
@ -117,6 +117,10 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
|
|||
// name: all
|
||||
// type: boolean
|
||||
// description: add all contents if given list
|
||||
// - in: query
|
||||
// name: amend
|
||||
// type: boolean
|
||||
// description: modify an existing list if one with the desired name already exists
|
||||
// - in: body
|
||||
// name: options
|
||||
// description: options for new manifest
|
||||
|
|
|
@ -8,7 +8,8 @@ type InspectOptions struct {
|
|||
//go:generate go run ../generator/generator.go CreateOptions
|
||||
// CreateOptions are optional options for creating manifests
|
||||
type CreateOptions struct {
|
||||
All *bool
|
||||
All *bool
|
||||
Amend *bool
|
||||
}
|
||||
|
||||
//go:generate go run ../generator/generator.go ExistsOptions
|
||||
|
|
|
@ -31,3 +31,18 @@ func (o *CreateOptions) GetAll() bool {
|
|||
}
|
||||
return *o.All
|
||||
}
|
||||
|
||||
// WithAmend set field Amend to given value
|
||||
func (o *CreateOptions) WithAmend(value bool) *CreateOptions {
|
||||
o.Amend = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetAmend returns value of field Amend
|
||||
func (o *CreateOptions) GetAmend() bool {
|
||||
if o.Amend == nil {
|
||||
var z bool
|
||||
return z
|
||||
}
|
||||
return *o.Amend
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ import "github.com/containers/image/v5/types"
|
|||
|
||||
// ManifestCreateOptions provides model for creating manifest
|
||||
type ManifestCreateOptions struct {
|
||||
// True when adding lists to include all images
|
||||
All bool `schema:"all"`
|
||||
// Amend an extant list if there's already one with the desired name
|
||||
Amend bool `schema:"amend"`
|
||||
// Should TLS registry certificate be verified?
|
||||
SkipTLSVerify types.OptionalBool `json:"-" schema:"-"`
|
||||
}
|
||||
|
||||
// ManifestAddOptions provides model for adding digests to manifest list
|
||||
|
|
|
@ -32,7 +32,15 @@ func (ir *ImageEngine) ManifestCreate(ctx context.Context, name string, images [
|
|||
|
||||
manifestList, err := ir.Libpod.LibimageRuntime().CreateManifestList(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
if errors.Is(err, storage.ErrDuplicateName) && opts.Amend {
|
||||
amendList, amendErr := ir.Libpod.LibimageRuntime().LookupManifestList(name)
|
||||
if amendErr != nil {
|
||||
return "", err
|
||||
}
|
||||
manifestList = amendList
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
addOptions := &libimage.ManifestListAddOptions{All: opts.All}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
// ManifestCreate implements manifest create via ImageEngine
|
||||
func (ir *ImageEngine) ManifestCreate(ctx context.Context, name string, images []string, opts entities.ManifestCreateOptions) (string, error) {
|
||||
options := new(manifests.CreateOptions).WithAll(opts.All)
|
||||
options := new(manifests.CreateOptions).WithAll(opts.All).WithAmend(opts.Amend)
|
||||
imageID, err := manifests.Create(ir.ClientCtx, name, images, options)
|
||||
if err != nil {
|
||||
return imageID, fmt.Errorf("error creating manifest: %w", err)
|
||||
|
|
|
@ -49,6 +49,14 @@ var _ = Describe("Podman manifest", func() {
|
|||
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"manifest", "create", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).To(ExitWithError())
|
||||
|
||||
session = podmanTest.Podman([]string{"manifest", "create", "--amend", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
})
|
||||
|
||||
It("create w/ image", func() {
|
||||
|
|
Loading…
Reference in New Issue