From 485a7aa330ade7da57c545b72c2be2da64f7d1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Sat, 7 Jul 2018 02:33:47 +0200 Subject: [PATCH] Use the *Options structures for command-specific options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Destionation: &opts.flag in the flag definition instead of c.String("flag-name") and the like in the hadler and matching only by strings. Signed-off-by: Miloslav Trmač --- cmd/skopeo/copy.go | 50 +++++++++++++++++++++++-------------------- cmd/skopeo/inspect.go | 8 ++++--- cmd/skopeo/signing.go | 13 +++++------ 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/cmd/skopeo/copy.go b/cmd/skopeo/copy.go index 69d7503e..23da3919 100644 --- a/cmd/skopeo/copy.go +++ b/cmd/skopeo/copy.go @@ -32,6 +32,10 @@ func contextsFromGlobalOptions(c *cli.Context) (*types.SystemContext, *types.Sys } type copyOptions struct { + additionalTags cli.StringSlice // For docker-archive: destinations, in addition to the name:tag specified as destination, also add these + removeSignatures bool // Do not copy signatures from the source image + signByFingerprint string // Sign the image using a GPG key with the specified fingerprint + format optionalString // Force conversion of the image to a specified format } func copyCmd() cli.Command { @@ -55,18 +59,21 @@ func copyCmd() cli.Command { cli.StringSliceFlag{ Name: "additional-tag", Usage: "additional tags (supports docker-archive)", + Value: &opts.additionalTags, // Surprisingly StringSliceFlag does not support Destination:, but modifies Value: in place. }, cli.StringFlag{ Name: "authfile", Usage: "path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json", }, cli.BoolFlag{ - Name: "remove-signatures", - Usage: "Do not copy signatures from SOURCE-IMAGE", + Name: "remove-signatures", + Usage: "Do not copy signatures from SOURCE-IMAGE", + Destination: &opts.removeSignatures, }, cli.StringFlag{ - Name: "sign-by", - Usage: "Sign the image using a GPG key with the specified `FINGERPRINT`", + Name: "sign-by", + Usage: "Sign the image using a GPG key with the specified `FINGERPRINT`", + Destination: &opts.signByFingerprint, }, cli.StringFlag{ Name: "src-creds, screds", @@ -111,9 +118,10 @@ func copyCmd() cli.Command { Value: "", Usage: "`DIRECTORY` to use to store retrieved blobs (OCI layout destinations only)", }, - cli.StringFlag{ + cli.GenericFlag{ Name: "format, f", Usage: "`MANIFEST TYPE` (oci, v2s1, or v2s2) to use when saving image to directory using the 'dir:' transport (default is manifest type of source)", + Value: newOptionalStringValue(&opts.format), }, cli.BoolFlag{ Name: "dest-compress", @@ -153,8 +161,6 @@ func (opts *copyOptions) run(c *cli.Context) error { if err != nil { return fmt.Errorf("Invalid destination name %s: %v", c.Args()[1], err) } - signBy := c.String("sign-by") - removeSignatures := c.Bool("remove-signatures") sourceCtx, destinationCtx, err := contextsFromGlobalOptions(c) if err != nil { @@ -162,8 +168,8 @@ func (opts *copyOptions) run(c *cli.Context) error { } var manifestType string - if c.IsSet("format") { - switch c.String("format") { + if opts.format.present { + switch opts.format.value { case "oci": manifestType = imgspecv1.MediaTypeImageManifest case "v2s1": @@ -171,30 +177,28 @@ func (opts *copyOptions) run(c *cli.Context) error { case "v2s2": manifestType = manifest.DockerV2Schema2MediaType default: - return fmt.Errorf("unknown format %q. Choose one of the supported formats: 'oci', 'v2s1', or 'v2s2'", c.String("format")) + return fmt.Errorf("unknown format %q. Choose one of the supported formats: 'oci', 'v2s1', or 'v2s2'", opts.format.value) } } - if c.IsSet("additional-tag") { - for _, image := range c.StringSlice("additional-tag") { - ref, err := reference.ParseNormalizedNamed(image) - if err != nil { - return fmt.Errorf("error parsing additional-tag '%s': %v", image, err) - } - namedTagged, isNamedTagged := ref.(reference.NamedTagged) - if !isNamedTagged { - return fmt.Errorf("additional-tag '%s' must be a tagged reference", image) - } - destinationCtx.DockerArchiveAdditionalTags = append(destinationCtx.DockerArchiveAdditionalTags, namedTagged) + for _, image := range opts.additionalTags { + ref, err := reference.ParseNormalizedNamed(image) + if err != nil { + return fmt.Errorf("error parsing additional-tag '%s': %v", image, err) } + namedTagged, isNamedTagged := ref.(reference.NamedTagged) + if !isNamedTagged { + return fmt.Errorf("additional-tag '%s' must be a tagged reference", image) + } + destinationCtx.DockerArchiveAdditionalTags = append(destinationCtx.DockerArchiveAdditionalTags, namedTagged) } ctx, cancel := commandTimeoutContextFromGlobalOptions(c) defer cancel() _, err = copy.Image(ctx, policyContext, destRef, srcRef, ©.Options{ - RemoveSignatures: removeSignatures, - SignBy: signBy, + RemoveSignatures: opts.removeSignatures, + SignBy: opts.signByFingerprint, ReportWriter: os.Stdout, SourceCtx: sourceCtx, DestinationCtx: destinationCtx, diff --git a/cmd/skopeo/inspect.go b/cmd/skopeo/inspect.go index ab1b0781..fbad4f68 100644 --- a/cmd/skopeo/inspect.go +++ b/cmd/skopeo/inspect.go @@ -30,6 +30,7 @@ type inspectOutput struct { } type inspectOptions struct { + raw bool // Output the raw manifest instead of parsing information about the image } func inspectCmd() cli.Command { @@ -61,8 +62,9 @@ func inspectCmd() cli.Command { Usage: "require HTTPS and verify certificates when talking to container registries (defaults to true)", }, cli.BoolFlag{ - Name: "raw", - Usage: "output raw manifest", + Name: "raw", + Usage: "output raw manifest", + Destination: &opts.raw, }, cli.StringFlag{ Name: "creds", @@ -93,7 +95,7 @@ func (opts *inspectOptions) run(c *cli.Context) (retErr error) { if err != nil { return err } - if c.Bool("raw") { + if opts.raw { _, err := c.App.Writer.Write(rawManifest) if err != nil { return fmt.Errorf("Error writing manifest to standard output: %v", err) diff --git a/cmd/skopeo/signing.go b/cmd/skopeo/signing.go index fd0332e3..9d7a29a5 100644 --- a/cmd/skopeo/signing.go +++ b/cmd/skopeo/signing.go @@ -11,6 +11,7 @@ import ( ) type standaloneSignOptions struct { + output string // Output file path } func standaloneSignCmd() cli.Command { @@ -22,16 +23,16 @@ func standaloneSignCmd() cli.Command { Action: opts.run, Flags: []cli.Flag{ cli.StringFlag{ - Name: "output, o", - Usage: "output the signature to `SIGNATURE`", + Name: "output, o", + Usage: "output the signature to `SIGNATURE`", + Destination: &opts.output, }, }, } } func (opts *standaloneSignOptions) run(c *cli.Context) error { - outputFile := c.String("output") - if len(c.Args()) != 3 || outputFile == "" { + if len(c.Args()) != 3 || opts.output == "" { return errors.New("Usage: skopeo standalone-sign manifest docker-reference key-fingerprint -o signature") } manifestPath := c.Args()[0] @@ -53,8 +54,8 @@ func (opts *standaloneSignOptions) run(c *cli.Context) error { return fmt.Errorf("Error creating signature: %v", err) } - if err := ioutil.WriteFile(outputFile, signature, 0644); err != nil { - return fmt.Errorf("Error writing signature to %s: %v", outputFile, err) + if err := ioutil.WriteFile(opts.output, signature, 0644); err != nil { + return fmt.Errorf("Error writing signature to %s: %v", opts.output, err) } return nil }