github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/manifest/create_list.go (about)

     1  package manifest
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/docker/cli/cli"
     8  	"github.com/docker/cli/cli/command"
     9  	"github.com/docker/cli/cli/manifest/store"
    10  	"github.com/docker/docker/registry"
    11  	"github.com/pkg/errors"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  type createOpts struct {
    16  	amend    bool
    17  	insecure bool
    18  }
    19  
    20  func newCreateListCommand(dockerCli command.Cli) *cobra.Command {
    21  	opts := createOpts{}
    22  
    23  	cmd := &cobra.Command{
    24  		Use:   "create MANIFEST_LIST MANIFEST [MANIFEST...]",
    25  		Short: "Create a local manifest list for annotating and pushing to a registry",
    26  		Args:  cli.RequiresMinArgs(2),
    27  		RunE: func(cmd *cobra.Command, args []string) error {
    28  			return createManifestList(cmd.Context(), dockerCli, args, opts)
    29  		},
    30  	}
    31  
    32  	flags := cmd.Flags()
    33  	flags.BoolVar(&opts.insecure, "insecure", false, "Allow communication with an insecure registry")
    34  	flags.BoolVarP(&opts.amend, "amend", "a", false, "Amend an existing manifest list")
    35  	return cmd
    36  }
    37  
    38  func createManifestList(ctx context.Context, dockerCli command.Cli, args []string, opts createOpts) error {
    39  	newRef := args[0]
    40  	targetRef, err := normalizeReference(newRef)
    41  	if err != nil {
    42  		return errors.Wrapf(err, "error parsing name for manifest list %s", newRef)
    43  	}
    44  
    45  	_, err = registry.ParseRepositoryInfo(targetRef)
    46  	if err != nil {
    47  		return errors.Wrapf(err, "error parsing repository name for manifest list %s", newRef)
    48  	}
    49  
    50  	manifestStore := dockerCli.ManifestStore()
    51  	_, err = manifestStore.GetList(targetRef)
    52  	switch {
    53  	case store.IsNotFound(err):
    54  		// New manifest list
    55  	case err != nil:
    56  		return err
    57  	case !opts.amend:
    58  		return errors.Errorf("refusing to amend an existing manifest list with no --amend flag")
    59  	}
    60  
    61  	// Now create the local manifest list transaction by looking up the manifest schemas
    62  	// for the constituent images:
    63  	manifests := args[1:]
    64  	for _, manifestRef := range manifests {
    65  		namedRef, err := normalizeReference(manifestRef)
    66  		if err != nil {
    67  			// TODO: wrap error?
    68  			return err
    69  		}
    70  
    71  		manifest, err := getManifest(ctx, dockerCli, targetRef, namedRef, opts.insecure)
    72  		if err != nil {
    73  			return err
    74  		}
    75  		if err := manifestStore.Save(targetRef, namedRef, manifest); err != nil {
    76  			return err
    77  		}
    78  	}
    79  	fmt.Fprintf(dockerCli.Out(), "Created manifest list %s\n", targetRef.String())
    80  	return nil
    81  }