From 26682b663da84f02cbcd8f4b15534b863113e7ae Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 2 Jun 2015 19:01:41 -0700 Subject: [PATCH 1/3] etcdctl: cleanup etcdctl exit code --- etcdctl/command/cluster_health.go | 6 +++--- etcdctl/command/error.go | 10 +++++----- etcdctl/command/handle.go | 6 +++--- etcdctl/command/import_snap_command.go | 10 +++++----- etcdctl/command/watch_command.go | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/etcdctl/command/cluster_health.go b/etcdctl/command/cluster_health.go index fb94afb90..e62e801f5 100644 --- a/etcdctl/command/cluster_health.go +++ b/etcdctl/command/cluster_health.go @@ -27,11 +27,11 @@ func NewClusterHealthCommand() cli.Command { func handleClusterHealth(c *cli.Context) { endpoints, err := getEndpoints(c) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } tr, err := getTransport(c) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } client := etcd.NewClient(endpoints) @@ -42,7 +42,7 @@ func handleClusterHealth(c *cli.Context) { } if ok := client.SyncCluster(); !ok { - handleError(FailedToConnectToHost, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) + handleError(ExitBadConnection, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) } // do we have a leader? diff --git a/etcdctl/command/error.go b/etcdctl/command/error.go index 00e33f774..a43ff9b91 100644 --- a/etcdctl/command/error.go +++ b/etcdctl/command/error.go @@ -20,11 +20,11 @@ import ( ) const ( - SUCCESS = iota - MalformedEtcdctlArguments - FailedToConnectToHost - FailedToAuth - ErrorFromEtcd + ExitSuccess = iota + ExitBadArgs + ExitBadConnection + ExitBadAuth + ExitServerError ) func handleError(code int, err error) { diff --git a/etcdctl/command/handle.go b/etcdctl/command/handle.go index 4be649c2e..086dfbc71 100644 --- a/etcdctl/command/handle.go +++ b/etcdctl/command/handle.go @@ -60,7 +60,7 @@ func rawhandle(c *cli.Context, fn handlerFunc) (*etcd.Response, error) { // Sync cluster. if !c.GlobalBool("no-sync") { if ok := client.SyncCluster(); !ok { - handleError(FailedToConnectToHost, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) + handleError(ExitBadConnection, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) } } @@ -79,7 +79,7 @@ func handlePrint(c *cli.Context, fn handlerFunc, pFn printFunc) { // Print error and exit, if necessary. if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } if resp != nil && pFn != nil { @@ -92,7 +92,7 @@ func handleContextualPrint(c *cli.Context, fn handlerFunc, pFn contextualPrintFu resp, err := rawhandle(c, fn) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } if resp != nil && pFn != nil { diff --git a/etcdctl/command/import_snap_command.go b/etcdctl/command/import_snap_command.go index 859ad9d56..980e033c8 100644 --- a/etcdctl/command/import_snap_command.go +++ b/etcdctl/command/import_snap_command.go @@ -53,11 +53,11 @@ func handleImportSnap(c *cli.Context) { endpoints, err := getEndpoints(c) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } tr, err := getTransport(c) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } wg := &sync.WaitGroup{} @@ -73,7 +73,7 @@ func handleImportSnap(c *cli.Context) { } if ok := client.SyncCluster(); !ok { - handleError(FailedToConnectToHost, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) + handleError(ExitBadConnection, errors.New("cannot sync with the cluster using endpoints "+strings.Join(endpoints, ", "))) } wg.Add(1) go runSet(client, setc, wg) @@ -81,7 +81,7 @@ func handleImportSnap(c *cli.Context) { all, err := st.Get("/", true, true) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } n := copyKeys(all.Node, setc) @@ -89,7 +89,7 @@ func handleImportSnap(c *cli.Context) { for _, h := range hiddens { allh, err := st.Get(h, true, true) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } n += copyKeys(allh.Node, setc) } diff --git a/etcdctl/command/watch_command.go b/etcdctl/command/watch_command.go index fad4ba174..fa987c826 100644 --- a/etcdctl/command/watch_command.go +++ b/etcdctl/command/watch_command.go @@ -86,7 +86,7 @@ func watchCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, erro resp, err = client.Watch(key, uint64(index), recursive, nil, nil) if err != nil { - handleError(ErrorFromEtcd, err) + handleError(ExitServerError, err) } if err != nil { From 079e7c10a0b91a2ee5b82a9ef995bf24e764ee86 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 2 Jun 2015 19:29:05 -0700 Subject: [PATCH 2/3] etcdctl: move format to format.go --- etcdctl/command/format.go | 74 +++++++++++++++++++++++++++++++++++++++ etcdctl/command/handle.go | 52 --------------------------- 2 files changed, 74 insertions(+), 52 deletions(-) create mode 100644 etcdctl/command/format.go diff --git a/etcdctl/command/format.go b/etcdctl/command/format.go new file mode 100644 index 000000000..9983df26d --- /dev/null +++ b/etcdctl/command/format.go @@ -0,0 +1,74 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package command + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/coreos/go-etcd/etcd" +) + +// printKey writes the etcd response to STDOUT in the given format. +func printKey(resp *etcd.Response, format string) { + // printKey is only for keys, error on directories + if resp.Node.Dir == true { + fmt.Fprintln(os.Stderr, fmt.Sprintf("Cannot print key [%s: Is a directory]", resp.Node.Key)) + os.Exit(1) + } + printKeyOnly(resp, format) +} + +// printAll prints the etcd response in the given format in its best efforts. +func printAll(resp *etcd.Response, format string) { + if resp.Node.Dir == true { + return + } + printKeyOnly(resp, format) +} + +// printKeyOnly only supports to print key correctly. +func printKeyOnly(resp *etcd.Response, format string) { + // Format the result. + switch format { + case "simple": + fmt.Println(resp.Node.Value) + case "extended": + // Extended prints in a rfc2822 style format + fmt.Println("Key:", resp.Node.Key) + fmt.Println("Created-Index:", resp.Node.CreatedIndex) + fmt.Println("Modified-Index:", resp.Node.ModifiedIndex) + + if resp.PrevNode != nil { + fmt.Println("PrevNode.Value:", resp.PrevNode.Value) + } + + fmt.Println("TTL:", resp.Node.TTL) + fmt.Println("Etcd-Index:", resp.EtcdIndex) + fmt.Println("Raft-Index:", resp.RaftIndex) + fmt.Println("Raft-Term:", resp.RaftTerm) + fmt.Println("") + fmt.Println(resp.Node.Value) + case "json": + b, err := json.Marshal(resp) + if err != nil { + panic(err) + } + fmt.Println(string(b)) + default: + fmt.Fprintln(os.Stderr, "Unsupported output format:", format) + } +} diff --git a/etcdctl/command/handle.go b/etcdctl/command/handle.go index 086dfbc71..9dd614701 100644 --- a/etcdctl/command/handle.go +++ b/etcdctl/command/handle.go @@ -15,7 +15,6 @@ package command import ( - "encoding/json" "errors" "fmt" "os" @@ -114,54 +113,3 @@ func handleKey(c *cli.Context, fn handlerFunc) { func handleAll(c *cli.Context, fn handlerFunc) { handlePrint(c, fn, printAll) } - -// printKey writes the etcd response to STDOUT in the given format. -func printKey(resp *etcd.Response, format string) { - // printKey is only for keys, error on directories - if resp.Node.Dir == true { - fmt.Fprintln(os.Stderr, fmt.Sprintf("Cannot print key [%s: Is a directory]", resp.Node.Key)) - os.Exit(1) - } - printKeyOnly(resp, format) -} - -// printAll prints the etcd response in the given format in its best efforts. -func printAll(resp *etcd.Response, format string) { - if resp.Node.Dir == true { - return - } - printKeyOnly(resp, format) -} - -// printKeyOnly only supports to print key correctly. -func printKeyOnly(resp *etcd.Response, format string) { - // Format the result. - switch format { - case "simple": - fmt.Println(resp.Node.Value) - case "extended": - // Extended prints in a rfc2822 style format - fmt.Println("Key:", resp.Node.Key) - fmt.Println("Created-Index:", resp.Node.CreatedIndex) - fmt.Println("Modified-Index:", resp.Node.ModifiedIndex) - - if resp.PrevNode != nil { - fmt.Println("PrevNode.Value:", resp.PrevNode.Value) - } - - fmt.Println("TTL:", resp.Node.TTL) - fmt.Println("Etcd-Index:", resp.EtcdIndex) - fmt.Println("Raft-Index:", resp.RaftIndex) - fmt.Println("Raft-Term:", resp.RaftTerm) - fmt.Println("") - fmt.Println(resp.Node.Value) - case "json": - b, err := json.Marshal(resp) - if err != nil { - panic(err) - } - fmt.Println(string(b)) - default: - fmt.Fprintln(os.Stderr, "Unsupported output format:", format) - } -} From f0edf06b6dddec8cefc52f0b799713db6e3e1b35 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 2 Jun 2015 19:44:26 -0700 Subject: [PATCH 3/3] etcdctl: minor cleanup --- etcdctl/command/format.go | 2 +- etcdctl/command/get_command.go | 2 +- etcdctl/command/mk_command.go | 4 ++-- etcdctl/command/mkdir_command.go | 2 +- etcdctl/command/rm_command.go | 2 +- etcdctl/command/rmdir_command.go | 2 +- etcdctl/command/set_command.go | 7 +++---- etcdctl/command/util.go | 1 - 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/etcdctl/command/format.go b/etcdctl/command/format.go index 9983df26d..f5fb872ae 100644 --- a/etcdctl/command/format.go +++ b/etcdctl/command/format.go @@ -19,7 +19,7 @@ import ( "fmt" "os" - "github.com/coreos/go-etcd/etcd" + "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd" ) // printKey writes the etcd response to STDOUT in the given format. diff --git a/etcdctl/command/get_command.go b/etcdctl/command/get_command.go index 482649fc8..beb391eed 100644 --- a/etcdctl/command/get_command.go +++ b/etcdctl/command/get_command.go @@ -55,7 +55,7 @@ func printGet(resp *etcd.Response, format string) { // getCommandFunc executes the "get" command. func getCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] sorted := c.Bool("sort") diff --git a/etcdctl/command/mk_command.go b/etcdctl/command/mk_command.go index a2002eb30..95d9b3a40 100644 --- a/etcdctl/command/mk_command.go +++ b/etcdctl/command/mk_command.go @@ -39,12 +39,12 @@ func NewMakeCommand() cli.Command { // makeCommandFunc executes the "make" command. func makeCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] value, err := argOrStdin(c.Args(), os.Stdin, 1) if err != nil { - return nil, errors.New("Value required") + return nil, errors.New("value required") } ttl := c.Int("ttl") diff --git a/etcdctl/command/mkdir_command.go b/etcdctl/command/mkdir_command.go index 278efc0bf..d86b0eebb 100644 --- a/etcdctl/command/mkdir_command.go +++ b/etcdctl/command/mkdir_command.go @@ -38,7 +38,7 @@ func NewMakeDirCommand() cli.Command { // makeDirCommandFunc executes the "mkdir" command. func makeDirCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] ttl := c.Int("ttl") diff --git a/etcdctl/command/rm_command.go b/etcdctl/command/rm_command.go index 80a0158a1..c754d4ce0 100644 --- a/etcdctl/command/rm_command.go +++ b/etcdctl/command/rm_command.go @@ -41,7 +41,7 @@ func NewRemoveCommand() cli.Command { // removeCommandFunc executes the "rm" command. func removeCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] recursive := c.Bool("recursive") diff --git a/etcdctl/command/rmdir_command.go b/etcdctl/command/rmdir_command.go index 487c0b8c3..2b63407fb 100644 --- a/etcdctl/command/rmdir_command.go +++ b/etcdctl/command/rmdir_command.go @@ -35,7 +35,7 @@ func NewRemoveDirCommand() cli.Command { // removeDirCommandFunc executes the "rmdir" command. func removeDirCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] diff --git a/etcdctl/command/set_command.go b/etcdctl/command/set_command.go index 365d6c4d2..118379624 100644 --- a/etcdctl/command/set_command.go +++ b/etcdctl/command/set_command.go @@ -41,12 +41,12 @@ func NewSetCommand() cli.Command { // setCommandFunc executes the "set" command. func setCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) { if len(c.Args()) == 0 { - return nil, errors.New("Key required") + return nil, errors.New("key required") } key := c.Args()[0] value, err := argOrStdin(c.Args(), os.Stdin, 1) if err != nil { - return nil, errors.New("Value required") + return nil, errors.New("value required") } ttl := c.Int("ttl") @@ -55,7 +55,6 @@ func setCommandFunc(c *cli.Context, client *etcd.Client) (*etcd.Response, error) if prevValue == "" && prevIndex == 0 { return client.Set(key, value, uint64(ttl)) - } else { - return client.CompareAndSwap(key, value, uint64(ttl), prevValue, uint64(prevIndex)) } + return client.CompareAndSwap(key, value, uint64(ttl), prevValue, uint64(prevIndex)) } diff --git a/etcdctl/command/util.go b/etcdctl/command/util.go index 7ffb80554..a9cc403ec 100644 --- a/etcdctl/command/util.go +++ b/etcdctl/command/util.go @@ -111,5 +111,4 @@ func getTransport(c *cli.Context) (*http.Transport, error) { KeyFile: keyfile, } return transport.NewTransport(tls) - }