*: combine etcdctl and etcdctlv3

This commit is contained in:
Xiang Li
2016-03-28 10:49:03 -07:00
parent 83ada7232a
commit 87d9f06a45
57 changed files with 108 additions and 67 deletions

View File

@ -1,5 +1,4 @@
# Use goreman to run `go get github.com/mattn/goreman` # Use goreman to run `go get github.com/mattn/goreman`
# etcd1 is the default client server for etcdctlv3 commands
etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof

1
build
View File

@ -32,4 +32,3 @@ fi
# Static compilation is useful when etcd is run in a container # Static compilation is useful when etcd is run in a container
CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "-s -X ${REPO_PATH}/version.GitSHA${LINK_OPERATOR}${GIT_SHA}" -o bin/etcd ${REPO_PATH} CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "-s -X ${REPO_PATH}/version.GitSHA${LINK_OPERATOR}${GIT_SHA}" -o bin/etcd ${REPO_PATH}
CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "-s" -o bin/etcdctl ${REPO_PATH}/etcdctl CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "-s" -o bin/etcdctl ${REPO_PATH}/etcdctl
CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "-s" -o bin/etcdctlv3 ${REPO_PATH}/etcdctlv3

View File

@ -15,11 +15,11 @@
package e2e package e2e
import ( import (
"os"
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/coreos/etcd/pkg/fileutil"
"github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/pkg/testutil"
) )
@ -58,8 +58,10 @@ func TestCtlV3SetPeerTLSQuorum(t *testing.T) {
func testCtlV3Set(t *testing.T, cfg *etcdProcessClusterConfig, dialTimeout time.Duration, quorum bool) { func testCtlV3Set(t *testing.T, cfg *etcdProcessClusterConfig, dialTimeout time.Duration, quorum bool) {
defer testutil.AfterTest(t) defer testutil.AfterTest(t)
os.Setenv("ETCDCTL_API", "3")
epc := setupCtlV3Test(t, cfg, quorum) epc := setupCtlV3Test(t, cfg, quorum)
defer func() { defer func() {
os.Unsetenv("ETCDCTL_API")
if errC := epc.Close(); errC != nil { if errC := epc.Close(); errC != nil {
t.Fatalf("error closing etcd processes (%v)", errC) t.Fatalf("error closing etcd processes (%v)", errC)
} }
@ -108,7 +110,7 @@ func ctlV3PrefixArgs(clus *etcdProcessCluster, dialTimeout time.Duration) []stri
} }
endpoints = strings.Join(es, ",") endpoints = strings.Join(es, ",")
} }
cmdArgs := []string{"../bin/etcdctlv3", "--endpoints", endpoints, "--dial-timeout", dialTimeout.String()} cmdArgs := []string{"../bin/etcdctl", "--endpoints", endpoints, "--dial-timeout", dialTimeout.String()}
if clus.cfg.clientTLS == clientTLS { if clus.cfg.clientTLS == clientTLS {
cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath) cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
} }
@ -129,14 +131,8 @@ func ctlV3Get(clus *etcdProcessCluster, key, value string, dialTimeout time.Dura
return spawnWithExpectedString(cmdArgs, key) return spawnWithExpectedString(cmdArgs, key)
} }
func mustCtlV3(t *testing.T) {
if !fileutil.Exist("../bin/etcdctlv3") {
t.Fatalf("could not find etcdctlv3 binary")
}
}
func setupCtlV3Test(t *testing.T, cfg *etcdProcessClusterConfig, quorum bool) *etcdProcessCluster { func setupCtlV3Test(t *testing.T, cfg *etcdProcessClusterConfig, quorum bool) *etcdProcessCluster {
mustCtlV3(t) mustEtcdctl(t)
if !quorum { if !quorum {
cfg = configStandalone(*cfg) cfg = configStandalone(*cfg)
} }

View File

@ -1,6 +1,8 @@
etcdctl etcdctl
======== ========
TODO: merge into README.md.
## Commands ## Commands
### PUT [options] \<key\> \<value\> ### PUT [options] \<key\> \<value\>
@ -277,7 +279,7 @@ bar
### LOCK \<lockname\> ### LOCK \<lockname\>
LOCK acquires a distributed named mutex with a given name. Once the lock is acquired, it will be held until etcdctlv3 is terminated. LOCK acquires a distributed named mutex with a given name. Once the lock is acquired, it will be held until etcdctl is terminated.
#### Return value #### Return value

70
etcdctl/ctlv2/ctl.go Normal file
View File

@ -0,0 +1,70 @@
// 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 ctlv2 contains the main entry point for the etcdctl for v2 API.
package ctlv2
import (
"os"
"time"
"github.com/codegangsta/cli"
"github.com/coreos/etcd/etcdctl/ctlv2/command"
"github.com/coreos/etcd/version"
)
func Start() {
app := cli.NewApp()
app.Name = "etcdctl"
app.Version = version.Version
app.Usage = "A simple command line client for etcd."
app.Flags = []cli.Flag{
cli.BoolFlag{Name: "debug", Usage: "output cURL commands which can be used to reproduce the request"},
cli.BoolFlag{Name: "no-sync", Usage: "don't synchronize cluster information before sending request"},
cli.StringFlag{Name: "output, o", Value: "simple", Usage: "output response in the given format (`simple`, `extended` or `json`)"},
cli.StringFlag{Name: "discovery-srv, D", Usage: "domain name to query for SRV records describing cluster endpoints"},
cli.StringFlag{Name: "peers, C", Value: "", Usage: "DEPRECATED - \"--endpoints\" should be used instead"},
cli.StringFlag{Name: "endpoint", Value: "", Usage: "DEPRECATED - \"--endpoints\" should be used instead"},
cli.StringFlag{Name: "endpoints", Value: "", Usage: "a comma-delimited list of machine addresses in the cluster (default: \"http://127.0.0.1:2379,http://127.0.0.1:4001\")"},
cli.StringFlag{Name: "cert-file", Value: "", Usage: "identify HTTPS client using this SSL certificate file"},
cli.StringFlag{Name: "key-file", Value: "", Usage: "identify HTTPS client using this SSL key file"},
cli.StringFlag{Name: "ca-file", Value: "", Usage: "verify certificates of HTTPS-enabled servers using this CA bundle"},
cli.StringFlag{Name: "username, u", Value: "", Usage: "provide username[:password] and prompt if password is not supplied."},
cli.DurationFlag{Name: "timeout", Value: time.Second, Usage: "connection timeout per request"},
cli.DurationFlag{Name: "total-timeout", Value: 5 * time.Second, Usage: "timeout for the command execution (except watch)"},
}
app.Commands = []cli.Command{
command.NewBackupCommand(),
command.NewClusterHealthCommand(),
command.NewMakeCommand(),
command.NewMakeDirCommand(),
command.NewRemoveCommand(),
command.NewRemoveDirCommand(),
command.NewGetCommand(),
command.NewLsCommand(),
command.NewSetCommand(),
command.NewSetDirCommand(),
command.NewUpdateCommand(),
command.NewUpdateDirCommand(),
command.NewWatchCommand(),
command.NewExecWatchCommand(),
command.NewMemberCommand(),
command.NewImportSnapCommand(),
command.NewUserCommands(),
command.NewRoleCommands(),
command.NewAuthCommands(),
}
app.Run(os.Args)
}

View File

@ -25,7 +25,7 @@ import (
func NewVersionCommand() *cobra.Command { func NewVersionCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "version", Use: "version",
Short: "Print the version of etcdctlv3.", Short: "Print the version of etcdctl.",
Run: versionCommandFunc, Run: versionCommandFunc,
} }
} }

View File

@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// etcdctlv3 is a command line application that utilizes v3 API. // Package ctlv3 contains the main entry point for the etcdctl for v3 API.
package main package ctlv3
import ( import (
"text/tabwriter" "text/tabwriter"
"time" "time"
"github.com/coreos/etcd/etcdctlv3/command" "github.com/coreos/etcd/etcdctl/ctlv3/command"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( const (
cliName = "etcdctlv3" cliName = "etcdctl"
cliDescription = "A simple command line client for etcd3." cliDescription = "A simple command line client for etcd3."
defaultDialTimeout = 2 * time.Second defaultDialTimeout = 2 * time.Second
@ -40,7 +40,7 @@ var (
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: cliName, Use: cliName,
Short: cliDescription, Short: cliDescription,
SuggestFor: []string{"etcctlv3", "etcdcltv3", "etlctlv3"}, SuggestFor: []string{"etcdctl"},
} }
) )
@ -85,7 +85,7 @@ func init() {
cobra.EnablePrefixMatching = true cobra.EnablePrefixMatching = true
} }
func main() { func Start() {
rootCmd.SetUsageFunc(usageFunc) rootCmd.SetUsageFunc(usageFunc)
// Make help just show the usage // Make help just show the usage

View File

@ -14,7 +14,7 @@
// copied from https://github.com/coreos/rkt/blob/master/rkt/help.go // copied from https://github.com/coreos/rkt/blob/master/rkt/help.go
package main package ctlv3
import ( import (
"bytes" "bytes"

View File

@ -1,4 +1,4 @@
// Copyright 2015 CoreOS, Inc. // Copyright 2016 CoreOS, Inc.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -16,55 +16,31 @@
package main package main
import ( import (
"fmt"
"os" "os"
"time"
"github.com/codegangsta/cli" "github.com/coreos/etcd/etcdctl/ctlv2"
"github.com/coreos/etcd/etcdctl/command" "github.com/coreos/etcd/etcdctl/ctlv3"
"github.com/coreos/etcd/version" )
const (
apiEnv = "ETCDCTL_API"
) )
func main() { func main() {
app := cli.NewApp() apiv := os.Getenv(apiEnv)
app.Name = "etcdctl" // unset apiEnv to avoid side-effect for future env and flag parsing.
app.Version = version.Version os.Unsetenv(apiv)
app.Usage = "A simple command line client for etcd." if len(apiv) == 0 || apiv == "2" {
app.Flags = []cli.Flag{ ctlv2.Start()
cli.BoolFlag{Name: "debug", Usage: "output cURL commands which can be used to reproduce the request"}, return
cli.BoolFlag{Name: "no-sync", Usage: "don't synchronize cluster information before sending request"},
cli.StringFlag{Name: "output, o", Value: "simple", Usage: "output response in the given format (`simple`, `extended` or `json`)"},
cli.StringFlag{Name: "discovery-srv, D", Usage: "domain name to query for SRV records describing cluster endpoints"},
cli.StringFlag{Name: "peers, C", Value: "", Usage: "DEPRECATED - \"--endpoints\" should be used instead"},
cli.StringFlag{Name: "endpoint", Value: "", Usage: "DEPRECATED - \"--endpoints\" should be used instead"},
cli.StringFlag{Name: "endpoints", Value: "", Usage: "a comma-delimited list of machine addresses in the cluster (default: \"http://127.0.0.1:2379,http://127.0.0.1:4001\")"},
cli.StringFlag{Name: "cert-file", Value: "", Usage: "identify HTTPS client using this SSL certificate file"},
cli.StringFlag{Name: "key-file", Value: "", Usage: "identify HTTPS client using this SSL key file"},
cli.StringFlag{Name: "ca-file", Value: "", Usage: "verify certificates of HTTPS-enabled servers using this CA bundle"},
cli.StringFlag{Name: "username, u", Value: "", Usage: "provide username[:password] and prompt if password is not supplied."},
cli.DurationFlag{Name: "timeout", Value: time.Second, Usage: "connection timeout per request"},
cli.DurationFlag{Name: "total-timeout", Value: 5 * time.Second, Usage: "timeout for the command execution (except watch)"},
}
app.Commands = []cli.Command{
command.NewBackupCommand(),
command.NewClusterHealthCommand(),
command.NewMakeCommand(),
command.NewMakeDirCommand(),
command.NewRemoveCommand(),
command.NewRemoveDirCommand(),
command.NewGetCommand(),
command.NewLsCommand(),
command.NewSetCommand(),
command.NewSetDirCommand(),
command.NewUpdateCommand(),
command.NewUpdateDirCommand(),
command.NewWatchCommand(),
command.NewExecWatchCommand(),
command.NewMemberCommand(),
command.NewImportSnapCommand(),
command.NewUserCommands(),
command.NewRoleCommands(),
command.NewAuthCommands(),
} }
app.Run(os.Args) if apiv == "3" {
ctlv3.Start()
return
}
fmt.Fprintln(os.Stderr, "unsupported API version", apiv)
os.Exit(1)
} }

View File

@ -1 +0,0 @@
etcdctlv3

2
test
View File

@ -17,7 +17,7 @@ GO_BUILD_FLAGS=-a
source ./build source ./build
# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt. # Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt.
TESTABLE_AND_FORMATTABLE="client clientv3 discovery error etcdctl/command etcdmain etcdserver etcdserver/auth etcdserver/etcdhttp etcdserver/etcdhttp/httptypes pkg/fileutil pkg/flags pkg/idutil pkg/ioutil pkg/netutil pkg/osutil pkg/pbutil pkg/types pkg/transport pkg/wait proxy raft snap storage storage/backend store version wal" TESTABLE_AND_FORMATTABLE="client clientv3 discovery error etcdctl/ctlv2 etcdctl/ctlv3 etcdmain etcdserver etcdserver/auth etcdserver/etcdhttp etcdserver/etcdhttp/httptypes pkg/fileutil pkg/flags pkg/idutil pkg/ioutil pkg/netutil pkg/osutil pkg/pbutil pkg/types pkg/transport pkg/wait proxy raft snap storage storage/backend store version wal"
# TODO: add it to race testing when the issue is resolved # TODO: add it to race testing when the issue is resolved
# https://github.com/golang/go/issues/9946 # https://github.com/golang/go/issues/9946
NO_RACE_TESTABLE="rafthttp" NO_RACE_TESTABLE="rafthttp"