Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trust sign: add --local flag #575

Merged
merged 1 commit into from
Nov 7, 2017
Merged

trust sign: add --local flag #575

merged 1 commit into from
Nov 7, 2017

Conversation

eiais
Copy link
Contributor

@eiais eiais commented Sep 29, 2017

The --local flag will force the signing of a local image.

cc @riyazdf @ashfall

Signed-off-by: Kyle Spiers kyle@spiers.me

@codecov-io
Copy link

codecov-io commented Sep 29, 2017

Codecov Report

Merging #575 into master will decrease coverage by 0.66%.
The diff coverage is 90%.

@@            Coverage Diff             @@
##           master     #575      +/-   ##
==========================================
- Coverage   50.09%   49.43%   -0.67%     
==========================================
  Files         216      208       -8     
  Lines       17696    17170     -526     
==========================================
- Hits         8865     8488     -377     
+ Misses       8387     8249     -138     
+ Partials      444      433      -11

Copy link
Contributor

@mdlinville mdlinville left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question and a small nit

@@ -16,10 +16,14 @@ keywords: "sign, notary, trust"
# trust sign

```markdown
Usage: docker trust sign IMAGE:TAG
Usage: docker trust sign [OPTIONS] IMAGE:TAG
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @riyazdf pulled [OPTIONS] out of a bunch of the other commands. Is it OK here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we pulled it out because they didn't have options yet. This one now does.

@@ -295,3 +295,13 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, len(cl.List()), 0)
}

func TestLocalFlag(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eiais Not sure I clearly understand that test 🤔
Shouldn't we also test the happy path (i.e. "Signing and pushing trust data for local image" […]).

@thaJeztah
Copy link
Member

I also left a similar proposal in the original PR: #472 (review)

Wondering if it's always desirable to push the image, or if there should be an option to either make pushing optional, or to disable pushing.

An alternative could be to have a --push flag, but @riyazdf is more familiar with the common workflow / expectations than I am 😅

@riyazdf
Copy link

riyazdf commented Oct 2, 2017

@thaJeztah: yup - this is a followup PR that addresses your feedback, though in a slightly different fashion.

In the context of docker, it doesn't really make sense to have a signature without a pushed image - so we've deliberately made the workflows such that if you sign an image there should always be an associated image in the registry unless you manually delete images in the registry or the signatures with notary.

Taking this into account on docker trust sign: if the image doesn't exist in a signed repository then it will push and sign. However, if the image does exist with signatures docker trust sign will multi-sign over the same digest/tag without pushing anything to the registry.

This PR adds a --local flag to always attempt pushing and signing a locally tagged image, even if signatures already exist, potentially clobbering the digest for the tag if it was previously signed.

cmd := &cobra.Command{
Use: "sign IMAGE:TAG",
Short: "Sign an image",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runSignImage(dockerCli, args[0])
return signImage(dockerCli, args[0], options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small thing, but would you mind making the args[0] part of options struct by adding an imageName field? We do this for most commands.

@@ -295,3 +295,13 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, len(cl.List()), 0)
}

func TestLocalFlag(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name should reflect the function that is being tested, so the name should be something like TestSignCommandLocalFlag

return cmd
}

func runSignImage(cli command.Cli, imageName string) error {
func signImage(cli command.Cli, imageName string, options signOptions) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be runSignImage() (or runSign would be fine too). This is another convention we use in the cli. The run prefix refers to the fact this is the function called for RunE of the Command.

},
}
flags := cmd.Flags()
flags.BoolVarP(&options.local, "local", "l", false, "Sign a locally tagged image")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the shorthand -l for now? Trying to be a bit conservative adding shorthands, unless a) frequently used, and b) we know it's not going to conflict with a possibly more-frequently-used option.

It's easier to add them later then removing/deprecating

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Copy link
Collaborator

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🐸


Sign an image

Options:
--help print usage
-l, --local force the signing of a local image
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-l should be removed here as well

cmd := newSignCommand(cli)
cmd.SetArgs([]string{"--local", "reg-name.io/image:red"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "error during connect: Get /images/reg-name.io/image:red/json: unsupported protocol scheme")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a strange expectation for a test case. Can't this use the notary fakes we have in client_test.go to make it a success case?

// Fail fast if the image doesn't exist locally
if err := checkLocalImageExistence(ctx, cli, imageName); err != nil {
return err
}
fmt.Fprintf(cli.Out(), "Signing and pushing trust data for local image %s, may overwrite remote trust data\n", imageName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use cli.Err() instead of cli.Out(). This message is informational (like logging), it's not part of "normal program output" (what the user asked for by running the command).

cmd := &cobra.Command{
Use: "sign IMAGE:TAG",
Short: "Sign an image",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runSignImage(dockerCli, args[0])
return runSignImage(dockerCli, args[0], options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: now that we have an options struct, the imageName can be passed as part of that struct, instead of a separate parameter. Not super important at this point since there is only a single arg, but it would be more consistent.

},
}
flags := cmd.Flags()
flags.BoolVarP(&options.local, "local", "", false, "Sign a locally tagged image")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should also use flags.BoolVar() now that it doesn't have a shorthand flag.

@thaJeztah
Copy link
Member

Linting failure, @eiais

cli/command/trust/sign.go:1::warning: file is not gofmted with -s (gofmt)
cli/command/trust/sign.go:1::warning: file is not goimported (goimports)

Signed-off-by: Kyle Spiers <kyle@spiers.me>
@docker docker deleted a comment from GordonTheTurtle Oct 31, 2017
Copy link
Contributor

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants