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

Introduce notary reset command from notary status flags #959

Merged
merged 2 commits into from
Sep 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/notary/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,7 @@ func TestWitness(t *testing.T) {
// 12. check non-targets base roles all fail
for _, role := range []string{data.CanonicalRootRole, data.CanonicalSnapshotRole, data.CanonicalTimestampRole} {
// clear any pending changes to ensure errors are only related to the specific role we're trying to witness
_, err = runCommand(t, tempDir, "status", "gun", "--reset")
_, err = runCommand(t, tempDir, "reset", "gun", "--all")
require.NoError(t, err)

_, err = runCommand(t, tempDir, "witness", "gun", role)
Expand All @@ -1618,7 +1618,7 @@ func TestWitness(t *testing.T) {
// 13. test auto-publish functionality (just for witness)

// purge the old staged witness
_, err = runCommand(t, tempDir, "status", "gun", "--reset")
_, err = runCommand(t, tempDir, "reset", "gun", "--all")
require.NoError(t, err)

// remove key2 and add back key1
Expand Down
1 change: 1 addition & 0 deletions cmd/notary/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ var exampleValidCommands = []string{
"init repo",
"list repo",
"status repo",
"reset repo --all",
"publish repo",
"add repo v1 somefile",
"addhash repo targetv1 --sha256 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 10",
Expand Down
64 changes: 51 additions & 13 deletions cmd/notary/tuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ var cmdTUFStatusTemplate = usageTemplate{
Long: "Displays status of unpublished changes to the local trusted collection identified by the Globally Unique Name.",
}

var cmdTUFResetTemplate = usageTemplate{
Use: "reset [ GUN ]",
Short: "Resets unpublished changes for the local trusted collection.",
Long: "Resets unpublished changes for the local trusted collection identified by the Globally Unique Name.",
}

var cmdTUFVerifyTemplate = usageTemplate{
Use: "verify [ GUN ] <target>",
Short: "Verifies if the content is included in the remote trusted collection",
Expand Down Expand Up @@ -110,8 +116,8 @@ type tufCommander struct {
output string
quiet bool

resetAll bool
deleteIdx []int
reset bool
archiveChangelist string

deleteRemote bool
Expand All @@ -125,10 +131,12 @@ func (t *tufCommander) AddToCommand(cmd *cobra.Command) {
cmdTUFInit.Flags().BoolVarP(&t.autoPublish, "publish", "p", false, htAutoPublish)
cmd.AddCommand(cmdTUFInit)

cmdStatus := cmdTUFStatusTemplate.ToCommand(t.tufStatus)
cmdStatus.Flags().IntSliceVarP(&t.deleteIdx, "unstage", "u", nil, "Numbers of changes to delete, as shown in status list")
cmdStatus.Flags().BoolVar(&t.reset, "reset", false, "Reset the changelist for the GUN by deleting all pending changes")
cmd.AddCommand(cmdStatus)
cmd.AddCommand(cmdTUFStatusTemplate.ToCommand(t.tufStatus))

cmdReset := cmdTUFResetTemplate.ToCommand(t.tufReset)
cmdReset.Flags().IntSliceVarP(&t.deleteIdx, "number", "n", nil, "Numbers of specific changes to exclusively reset, as shown in status list")
cmdReset.Flags().BoolVar(&t.resetAll, "all", false, "Reset all changes shown in the status list")
cmd.AddCommand(cmdReset)

cmd.AddCommand(cmdTUFPublishTemplate.ToCommand(t.tufPublish))
cmd.AddCommand(cmdTUFLookupTemplate.ToCommand(t.tufLookup))
Expand Down Expand Up @@ -553,14 +561,6 @@ func (t *tufCommander) tufStatus(cmd *cobra.Command, args []string) error {
return err
}

if t.reset {
return cl.Clear(t.archiveChangelist)
}

if len(t.deleteIdx) > 0 {
return cl.Remove(t.deleteIdx)
}

if len(cl.List()) == 0 {
cmd.Printf("No unpublished changes for %s\n", gun)
return nil
Expand All @@ -586,6 +586,44 @@ func (t *tufCommander) tufStatus(cmd *cobra.Command, args []string) error {
return nil
}

func (t *tufCommander) tufReset(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
cmd.Usage()
return fmt.Errorf("Must specify a GUN")
}
if !t.resetAll && len(t.deleteIdx) < 1 {
cmd.Usage()
return fmt.Errorf("Must specify changes to reset with -n or the --all flag")
}

config, err := t.configGetter()
if err != nil {
return err
}
gun := args[0]

trustPin, err := getTrustPinning(config)
if err != nil {
return err
}

nRepo, err := notaryclient.NewNotaryRepository(
config.GetString("trust_dir"), gun, getRemoteTrustServer(config), nil, t.retriever, trustPin)
if err != nil {
return err
}

cl, err := nRepo.GetChangelist()
if err != nil {
return err
}

if t.resetAll {
return cl.Clear(t.archiveChangelist)
}
return cl.Remove(t.deleteIdx)
}

func (t *tufCommander) tufPublish(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
cmd.Usage()
Expand Down
11 changes: 6 additions & 5 deletions cmd/notary/tuf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,9 @@ func TestStatusUnstageAndReset(t *testing.T) {
},
}

tc.reset = true

// run a reset with an empty changelist and make sure it succeeds
err := tc.tufStatus(&cobra.Command{}, []string{"gun"})
tc.resetAll = true
err := tc.tufReset(&cobra.Command{}, []string{"gun"})
require.NoError(t, err)

// add some targets
Expand All @@ -163,7 +162,7 @@ func TestStatusUnstageAndReset(t *testing.T) {
require.Contains(t, out, "test3")
require.Contains(t, out, "test4")

_, err = runCommand(t, tempBaseDir, "status", "gun", "--unstage", "-1,1,3,10")
_, err = runCommand(t, tempBaseDir, "reset", "gun", "-n", "-1,1,3,10")
require.NoError(t, err)

out, err = runCommand(t, tempBaseDir, "status", "gun")
Expand All @@ -173,7 +172,7 @@ func TestStatusUnstageAndReset(t *testing.T) {
require.Contains(t, out, "test3")
require.NotContains(t, out, "test4")

_, err = runCommand(t, tempBaseDir, "status", "gun", "--reset")
_, err = runCommand(t, tempBaseDir, "reset", "gun", "--all")
require.NoError(t, err)

out, err = runCommand(t, tempBaseDir, "status", "gun")
Expand Down Expand Up @@ -206,6 +205,8 @@ func TestGetTrustPinningErrors(t *testing.T) {
},
}
require.Error(t, tc.tufStatus(&cobra.Command{}, []string{"gun"}))
tc.resetAll = true
require.Error(t, tc.tufReset(&cobra.Command{}, []string{"gun"}))
require.Error(t, tc.tufDeleteGUN(&cobra.Command{}, []string{"gun"}))
require.Error(t, tc.tufInit(&cobra.Command{}, []string{"gun"}))
require.Error(t, tc.tufPublish(&cobra.Command{}, []string{"gun"}))
Expand Down
8 changes: 4 additions & 4 deletions docs/command_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ $ notary publish <GUN>
The Notary CLI client stages changes before publishing them to the server.
These changes are staged locally in files such that the client can request the latest updates from the notary server, attempt to apply the staged changes on top of the new updates (like a `git rebase`), and then finally publish if the changes are still valid.

You can manage the changes that are staged by running:
You can view staged changes with `notary status` and unstage them with `notary reset`:

```bash
# Check what changes are staged
$ notary status <GUN>

# Unstage a specific change
$ notary status <GUN> --unstage 0
$ notary reset <GUN> -n 0

# Alternatively, unstage all changes
$ notary status <GUN> --reset
# Alternatively, reset all changes
$ notary reset <GUN> --all
```

When you're ready to publish your changes to the Notary server, run:
Expand Down
13 changes: 7 additions & 6 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ $ notary -s https://notary.docker.io -d ~/.docker/trust publish docker.io/libra

Note that each row in the status has a number associated with it, found in the first
column. This number can be used to remove individual changes from the changelist if
they are no longer desired. This is done using the `--unstage` flag:
they are no longer desired. This is done using the `reset` command:

```
$ notary -d ~/.docker/trust status docker.io/library/alpine
Expand All @@ -154,7 +154,8 @@ Unpublished changes for docker.io/library/alpine:
\- ------ ----- ---- ----
0 delete targets target 2.6
1 create targets target 3.0
$ notary -d ~/.docker/trust status docker.io/library/alpine --unstage 0

$ notary -d ~/.docker/trust reset docker.io/library/alpine -n 0
$ notary -d ~/.docker/trust status docker.io/library/alpine
Unpublished changes for docker.io/library/alpine:

Expand All @@ -164,13 +165,13 @@ Unpublished changes for docker.io/library/alpine:
```

Pay close attention to how the indices are updated as changes are removed. You may
pass multiple `--unstage` flags with multiple indices in a single invocation of the
`status` subcommand and they will all be handled correctly within that invocation. Between
pass multiple `-n` flags with multiple indices in a single invocation of the
`reset` subcommand and they will all be handled correctly within that invocation. Between
invocations however, you should list the changes again to check which indices you want
to remove.

It is also possible to completely clear all pending changes by passing the `--reset`
to the `status` subcommand. This deletes all pending changes for the specified GUN.
It is also possible to completely clear all pending changes by passing the `--all` flag
to the `reset` subcommand. This deletes all pending changes for the specified GUN.

## Configure the client

Expand Down