github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/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(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(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  	ctx := context.Background()
    62  	// Now create the local manifest list transaction by looking up the manifest schemas
    63  	// for the constituent images:
    64  	manifests := args[1:]
    65  	for _, manifestRef := range manifests {
    66  		namedRef, err := normalizeReference(manifestRef)
    67  		if err != nil {
    68  			// TODO: wrap error?
    69  			return err
    70  		}
    71  
    72  		manifest, err := getManifest(ctx, dockerCli, targetRef, namedRef, opts.insecure)
    73  		if err != nil {
    74  			return err
    75  		}
    76  		if err := manifestStore.Save(targetRef, namedRef, manifest); err != nil {
    77  			return err
    78  		}
    79  	}
    80  	fmt.Fprintf(dockerCli.Out(), "Created manifest list %s\n", targetRef.String())
    81  	return nil
    82  }