Compare commits

...

11 Commits

Author SHA1 Message Date
6f48bda7ac version: bump to v3.0.0 2016-06-30 10:04:59 -07:00
316534e09e *: remove beta from docs 2016-06-30 10:04:34 -07:00
3cecbdb464 hack: install goreman in tls-setup example 2016-06-30 09:33:19 -07:00
62f11e43ee hack: add tls-setup example generated certs to gitignore 2016-06-30 09:33:12 -07:00
064c1585ee Merge pull request #5822 from raoofm/patch-9
Doc: fix typo in dev-guide.md
2016-06-30 09:06:32 -07:00
15300a1eb8 Doc: fix typo in dev-guide.md 2016-06-30 10:36:50 -04:00
58dd047ee4 ctlv3: make flags, commands formats consistent
1. Capitalize first letter
2. Remove period at the end

(followed the pattern in linux coreutil man page)
2016-06-29 16:16:56 -07:00
4b42ea6cd7 clientv3: only use closeErr on watch when donec is closed
Fixes #5800
2016-06-28 17:48:44 -07:00
53c27ae621 benchmark: fix Compact request 2016-06-28 14:15:32 -07:00
269de67bde mvcc: do not hash consistent index 2016-06-28 12:29:36 -07:00
8bbccf1047 clientv3, ctl3, clientv3/integration: add compact response to compact 2016-06-28 12:29:32 -07:00
36 changed files with 154 additions and 133 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@
/hack/insta-discovery/.env /hack/insta-discovery/.env
*.test *.test
tools/functional-tester/docker/bin tools/functional-tester/docker/bin
hack/tls-setup/certs

View File

@ -4,5 +4,5 @@ For the most part, the etcd project is stable, but we are still moving fast! We
## The current experimental API/features are: ## The current experimental API/features are:
- v3 auth API: expect to be stale in 3.1 release - v3 auth API: expect to be stable in 3.1 release
- etcd gateway: expect to be stable in 3.1 release - etcd gateway: expect to be stable in 3.1 release

View File

@ -8,7 +8,7 @@ In order to expose the etcd API to clients outside of Docker host, use the host
``` ```
# For each machine # For each machine
ETCD_VERSION=v3.0.0-beta.0 ETCD_VERSION=v3.0.0
TOKEN=my-etcd-token TOKEN=my-etcd-token
CLUSTER_STATE=new CLUSTER_STATE=new
NAME_1=etcd-node-0 NAME_1=etcd-node-0

View File

@ -210,7 +210,7 @@ func ExampleKV_compact() {
compRev := resp.Header.Revision // specify compact revision of your choice compRev := resp.Header.Revision // specify compact revision of your choice
ctx, cancel = context.WithTimeout(context.Background(), requestTimeout) ctx, cancel = context.WithTimeout(context.Background(), requestTimeout)
err = cli.Compact(ctx, compRev) _, err = cli.Compact(ctx, compRev)
cancel() cancel()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -470,17 +470,17 @@ func TestKVCompactError(t *testing.T) {
t.Fatalf("couldn't put 'foo' (%v)", err) t.Fatalf("couldn't put 'foo' (%v)", err)
} }
} }
err := kv.Compact(ctx, 6) _, err := kv.Compact(ctx, 6)
if err != nil { if err != nil {
t.Fatalf("couldn't compact 6 (%v)", err) t.Fatalf("couldn't compact 6 (%v)", err)
} }
err = kv.Compact(ctx, 6) _, err = kv.Compact(ctx, 6)
if err != rpctypes.ErrCompacted { if err != rpctypes.ErrCompacted {
t.Fatalf("expected %v, got %v", rpctypes.ErrCompacted, err) t.Fatalf("expected %v, got %v", rpctypes.ErrCompacted, err)
} }
err = kv.Compact(ctx, 100) _, err = kv.Compact(ctx, 100)
if err != rpctypes.ErrFutureRev { if err != rpctypes.ErrFutureRev {
t.Fatalf("expected %v, got %v", rpctypes.ErrFutureRev, err) t.Fatalf("expected %v, got %v", rpctypes.ErrFutureRev, err)
} }
@ -501,11 +501,11 @@ func TestKVCompact(t *testing.T) {
} }
} }
err := kv.Compact(ctx, 7) _, err := kv.Compact(ctx, 7)
if err != nil { if err != nil {
t.Fatalf("couldn't compact kv space (%v)", err) t.Fatalf("couldn't compact kv space (%v)", err)
} }
err = kv.Compact(ctx, 7) _, err = kv.Compact(ctx, 7)
if err == nil || err != rpctypes.ErrCompacted { if err == nil || err != rpctypes.ErrCompacted {
t.Fatalf("error got %v, want %v", err, rpctypes.ErrCompacted) t.Fatalf("error got %v, want %v", err, rpctypes.ErrCompacted)
} }
@ -525,7 +525,7 @@ func TestKVCompact(t *testing.T) {
t.Fatalf("wchan got %v, expected closed", wr) t.Fatalf("wchan got %v, expected closed", wr)
} }
err = kv.Compact(ctx, 1000) _, err = kv.Compact(ctx, 1000)
if err == nil || err != rpctypes.ErrFutureRev { if err == nil || err != rpctypes.ErrFutureRev {
t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev) t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev)
} }

View File

@ -375,7 +375,7 @@ func TestWatchResumeCompacted(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
if err := kv.Compact(context.TODO(), 3); err != nil { if _, err := kv.Compact(context.TODO(), 3); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -414,7 +414,7 @@ func TestWatchCompactRevision(t *testing.T) {
w := clientv3.NewWatcher(clus.RandClient()) w := clientv3.NewWatcher(clus.RandClient())
defer w.Close() defer w.Close()
if err := kv.Compact(context.TODO(), 4); err != nil { if _, err := kv.Compact(context.TODO(), 4); err != nil {
t.Fatal(err) t.Fatal(err)
} }
wch := w.Watch(context.Background(), "foo", clientv3.WithRev(2)) wch := w.Watch(context.Background(), "foo", clientv3.WithRev(2))

View File

@ -20,10 +20,11 @@ import (
) )
type ( type (
PutResponse pb.PutResponse CompactResponse pb.CompactionResponse
GetResponse pb.RangeResponse PutResponse pb.PutResponse
DeleteResponse pb.DeleteRangeResponse GetResponse pb.RangeResponse
TxnResponse pb.TxnResponse DeleteResponse pb.DeleteRangeResponse
TxnResponse pb.TxnResponse
) )
type KV interface { type KV interface {
@ -47,7 +48,7 @@ type KV interface {
Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
// Compact compacts etcd KV history before the given rev. // Compact compacts etcd KV history before the given rev.
Compact(ctx context.Context, rev int64, opts ...CompactOption) error Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)
// Do applies a single Op on KV without a transaction. // Do applies a single Op on KV without a transaction.
// Do is useful when declaring operations to be issued at a later time // Do is useful when declaring operations to be issued at a later time
@ -98,11 +99,12 @@ func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*Delete
return r.del, toErr(ctx, err) return r.del, toErr(ctx, err)
} }
func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) error { func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) {
if _, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest()); err != nil { resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest())
return toErr(ctx, err) if err != nil {
return nil, toErr(ctx, err)
} }
return nil return (*CompactResponse)(resp), err
} }
func (kv *kv) Txn(ctx context.Context) Txn { func (kv *kv) Txn(ctx context.Context) Txn {

View File

@ -505,6 +505,7 @@ func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) {
// serveStream forwards watch responses from run() to the subscriber // serveStream forwards watch responses from run() to the subscriber
func (w *watchGrpcStream) serveStream(ws *watcherStream) { func (w *watchGrpcStream) serveStream(ws *watcherStream) {
var closeErr error
emptyWr := &WatchResponse{} emptyWr := &WatchResponse{}
wrs := []*WatchResponse{} wrs := []*WatchResponse{}
resuming := false resuming := false
@ -569,13 +570,14 @@ func (w *watchGrpcStream) serveStream(ws *watcherStream) {
} }
case <-w.donec: case <-w.donec:
closing = true closing = true
closeErr = w.closeErr
case <-ws.initReq.ctx.Done(): case <-ws.initReq.ctx.Done():
closing = true closing = true
} }
} }
// try to send off close error // try to send off close error
if w.closeErr != nil { if closeErr != nil {
select { select {
case ws.outc <- WatchResponse{closeErr: w.closeErr}: case ws.outc <- WatchResponse{closeErr: w.closeErr}:
case <-w.donec: case <-w.donec:

View File

@ -497,25 +497,25 @@ ENDPOINT STATUS does not support protobuf encoded output.
```bash ```bash
./etcdctl endpoint status ./etcdctl endpoint status
127.0.0.1:2379, 8211f1d0f64f3269, 3.0.0-beta.0+git, 25 kB, false, 2, 63 127.0.0.1:2379, 8211f1d0f64f3269, 3.0.0, 25 kB, false, 2, 63
127.0.0.1:22379, 91bc3c398fb3c146, 3.0.0-beta.0+git, 25 kB, false, 2, 63 127.0.0.1:22379, 91bc3c398fb3c146, 3.0.0, 25 kB, false, 2, 63
127.0.0.1:32379, fd422379fda50e48, 3.0.0-beta.0+git, 25 kB, true, 2, 63 127.0.0.1:32379, fd422379fda50e48, 3.0.0, 25 kB, true, 2, 63
``` ```
```bash ```bash
./etcdctl -w json endpoint status ./etcdctl -w json endpoint status
[{"Endpoint":"127.0.0.1:2379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":9372538179322589801,"revision":2,"raft_term":2},"version":"2.3.0+git","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}},{"Endpoint":"127.0.0.1:22379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":10501334649042878790,"revision":2,"raft_term":2},"version":"2.3.0+git","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}},{"Endpoint":"127.0.0.1:32379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":18249187646912138824,"revision":2,"raft_term":2},"version":"2.3.0+git","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}}] [{"Endpoint":"127.0.0.1:2379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":9372538179322589801,"revision":2,"raft_term":2},"version":"3.0.0","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}},{"Endpoint":"127.0.0.1:22379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":10501334649042878790,"revision":2,"raft_term":2},"version":"3.0.0","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}},{"Endpoint":"127.0.0.1:32379","Status":{"header":{"cluster_id":17237436991929493444,"member_id":18249187646912138824,"revision":2,"raft_term":2},"version":"3.0.0","dbSize":24576,"leader":18249187646912138824,"raftIndex":32623,"raftTerm":2}}]
``` ```
```bash ```bash
./etcdctl -w table endpoint status ./etcdctl -w table endpoint status
+-----------------+------------------+------------------+---------+-----------+-----------+------------+ +-----------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+-----------------+------------------+------------------+---------+-----------+-----------+------------+ +-----------------+------------------+---------+---------+-----------+-----------+------------+
| 127.0.0.1:2379 | 8211f1d0f64f3269 | 3.0.0-beta.0+git | 25 kB | false | 2 | 52 | | 127.0.0.1:2379 | 8211f1d0f64f3269 | 3.0.0 | 25 kB | false | 2 | 52 |
| 127.0.0.1:22379 | 91bc3c398fb3c146 | 3.0.0-beta.0+git | 25 kB | false | 2 | 52 | | 127.0.0.1:22379 | 91bc3c398fb3c146 | 3.0.0 | 25 kB | false | 2 | 52 |
| 127.0.0.1:32379 | fd422379fda50e48 | 3.0.0-beta.0+git | 25 kB | true | 2 | 52 | | 127.0.0.1:32379 | fd422379fda50e48 | 3.0.0 | 25 kB | true | 2 | 52 |
+-----------------+------------------+------------------+---------+-----------+-----------+------------+ +-----------------+------------------+---------+---------+-----------+-----------+------------+
``` ```
### LOCK \<lockname\> ### LOCK \<lockname\>

View File

@ -25,7 +25,7 @@ import (
func NewAlarmCommand() *cobra.Command { func NewAlarmCommand() *cobra.Command {
ac := &cobra.Command{ ac := &cobra.Command{
Use: "alarm <subcommand>", Use: "alarm <subcommand>",
Short: "alarm related command", Short: "Alarm related commands",
} }
ac.AddCommand(NewAlarmDisarmCommand()) ac.AddCommand(NewAlarmDisarmCommand())
@ -37,7 +37,7 @@ func NewAlarmCommand() *cobra.Command {
func NewAlarmDisarmCommand() *cobra.Command { func NewAlarmDisarmCommand() *cobra.Command {
cmd := cobra.Command{ cmd := cobra.Command{
Use: "disarm", Use: "disarm",
Short: "disarm all alarms", Short: "Disarms all alarms",
Run: alarmDisarmCommandFunc, Run: alarmDisarmCommandFunc,
} }
return &cmd return &cmd
@ -60,7 +60,7 @@ func alarmDisarmCommandFunc(cmd *cobra.Command, args []string) {
func NewAlarmListCommand() *cobra.Command { func NewAlarmListCommand() *cobra.Command {
cmd := cobra.Command{ cmd := cobra.Command{
Use: "list", Use: "list",
Short: "list all alarms", Short: "Lists all alarms",
Run: alarmListCommandFunc, Run: alarmListCommandFunc,
} }
return &cmd return &cmd

View File

@ -24,7 +24,7 @@ import (
func NewAuthCommand() *cobra.Command { func NewAuthCommand() *cobra.Command {
ac := &cobra.Command{ ac := &cobra.Command{
Use: "auth <enable or disable>", Use: "auth <enable or disable>",
Short: "Enable or disable authentication.", Short: "Enable or disable authentication",
} }
ac.AddCommand(newAuthEnableCommand()) ac.AddCommand(newAuthEnableCommand())
@ -36,7 +36,7 @@ func NewAuthCommand() *cobra.Command {
func newAuthEnableCommand() *cobra.Command { func newAuthEnableCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "enable", Use: "enable",
Short: "enable authentication", Short: "Enables authentication",
Run: authEnableCommandFunc, Run: authEnableCommandFunc,
} }
} }
@ -60,7 +60,7 @@ func authEnableCommandFunc(cmd *cobra.Command, args []string) {
func newAuthDisableCommand() *cobra.Command { func newAuthDisableCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "disable", Use: "disable",
Short: "disable authentication", Short: "Disables authentication",
Run: authDisableCommandFunc, Run: authDisableCommandFunc,
} }
} }

View File

@ -28,10 +28,10 @@ var compactPhysical bool
func NewCompactionCommand() *cobra.Command { func NewCompactionCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "compaction <revision>", Use: "compaction <revision>",
Short: "Compaction compacts the event history in etcd.", Short: "Compacts the event history in etcd",
Run: compactionCommandFunc, Run: compactionCommandFunc,
} }
cmd.Flags().BoolVar(&compactPhysical, "physical", false, "'true' to wait for compaction to physically remove all old revisions.") cmd.Flags().BoolVar(&compactPhysical, "physical", false, "'true' to wait for compaction to physically remove all old revisions")
return cmd return cmd
} }
@ -53,7 +53,7 @@ func compactionCommandFunc(cmd *cobra.Command, args []string) {
c := mustClientFromCmd(cmd) c := mustClientFromCmd(cmd)
ctx, cancel := commandCtx(cmd) ctx, cancel := commandCtx(cmd)
cerr := c.Compact(ctx, rev, opts...) _, cerr := c.Compact(ctx, rev, opts...)
cancel() cancel()
if cerr != nil { if cerr != nil {
ExitWithError(ExitError, cerr) ExitWithError(ExitError, cerr)

View File

@ -25,7 +25,7 @@ import (
func NewDefragCommand() *cobra.Command { func NewDefragCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "defrag", Use: "defrag",
Short: "defrag defragments the storage of the etcd members with given endpoints.", Short: "Defragments the storage of the etcd members with given endpoints",
Run: defragCommandFunc, Run: defragCommandFunc,
} }
} }

View File

@ -29,7 +29,7 @@ var (
func NewDelCommand() *cobra.Command { func NewDelCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "del [options] <key> [range_end]", Use: "del [options] <key> [range_end]",
Short: "Removes the specified key or range of keys [key, range_end).", Short: "Removes the specified key or range of keys [key, range_end)",
Run: delCommandFunc, Run: delCommandFunc,
} }

View File

@ -33,7 +33,7 @@ var (
func NewElectCommand() *cobra.Command { func NewElectCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "elect <election-name> [proposal]", Use: "elect <election-name> [proposal]",
Short: "elect observes and participates in leader election", Short: "Observes and participates in leader election",
Run: electCommandFunc, Run: electCommandFunc,
} }
cmd.Flags().BoolVarP(&electListen, "listen", "l", false, "observation mode") cmd.Flags().BoolVarP(&electListen, "listen", "l", false, "observation mode")

View File

@ -28,8 +28,8 @@ import (
// NewEndpointCommand returns the cobra command for "endpoint". // NewEndpointCommand returns the cobra command for "endpoint".
func NewEndpointCommand() *cobra.Command { func NewEndpointCommand() *cobra.Command {
ec := &cobra.Command{ ec := &cobra.Command{
Use: "endpoint", Use: "endpoint <subcommand>",
Short: "endpoint is used to check endpoints.", Short: "Endpoint related commands",
} }
ec.AddCommand(newEpHealthCommand()) ec.AddCommand(newEpHealthCommand())
@ -41,7 +41,7 @@ func NewEndpointCommand() *cobra.Command {
func newEpHealthCommand() *cobra.Command { func newEpHealthCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "health", Use: "health",
Short: "health checks the healthiness of endpoints specified in `--endpoints` flag", Short: "Checks the healthiness of endpoints specified in `--endpoints` flag",
Run: epHealthCommandFunc, Run: epHealthCommandFunc,
} }
return cmd return cmd
@ -50,7 +50,7 @@ func newEpHealthCommand() *cobra.Command {
func newEpStatusCommand() *cobra.Command { func newEpStatusCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "status", Use: "status",
Short: "status prints out the status of endpoints specified in `--endpoints` flag", Short: "Prints out the status of endpoints specified in `--endpoints` flag",
Long: `When --write-out is set to simple, this command prints out comma-separated status lists for each endpoint. Long: `When --write-out is set to simple, this command prints out comma-separated status lists for each endpoint.
The items in the lists are endpoint, ID, version, db size, is leader, raft term, raft index. The items in the lists are endpoint, ID, version, db size, is leader, raft term, raft index.
`, `,

View File

@ -37,18 +37,18 @@ var (
func NewGetCommand() *cobra.Command { func NewGetCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get [options] <key> [range_end]", Use: "get [options] <key> [range_end]",
Short: "Get gets the key or a range of keys.", Short: "Gets the key or a range of keys",
Run: getCommandFunc, Run: getCommandFunc,
} }
cmd.Flags().StringVar(&getConsistency, "consistency", "l", "Linearizable(l) or Serializable(s)") cmd.Flags().StringVar(&getConsistency, "consistency", "l", "Linearizable(l) or Serializable(s)")
cmd.Flags().StringVar(&getSortOrder, "order", "", "order of results; ASCEND or DESCEND") cmd.Flags().StringVar(&getSortOrder, "order", "", "Order of results; ASCEND or DESCEND")
cmd.Flags().StringVar(&getSortTarget, "sort-by", "", "sort target; CREATE, KEY, MODIFY, VALUE, or VERSION") cmd.Flags().StringVar(&getSortTarget, "sort-by", "", "Sort target; CREATE, KEY, MODIFY, VALUE, or VERSION")
cmd.Flags().Int64Var(&getLimit, "limit", 0, "maximum number of results") cmd.Flags().Int64Var(&getLimit, "limit", 0, "Maximum number of results")
cmd.Flags().BoolVar(&getPrefix, "prefix", false, "get keys with matching prefix") cmd.Flags().BoolVar(&getPrefix, "prefix", false, "Get keys with matching prefix")
cmd.Flags().BoolVar(&getFromKey, "from-key", false, "get keys that are greater than or equal to the given key") cmd.Flags().BoolVar(&getFromKey, "from-key", false, "Get keys that are greater than or equal to the given key")
cmd.Flags().Int64Var(&getRev, "rev", 0, "specify the kv revision") cmd.Flags().Int64Var(&getRev, "rev", 0, "Specify the kv revision")
cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "get only the keys") cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "Get only the keys")
return cmd return cmd
} }

View File

@ -26,8 +26,8 @@ import (
// NewLeaseCommand returns the cobra command for "lease". // NewLeaseCommand returns the cobra command for "lease".
func NewLeaseCommand() *cobra.Command { func NewLeaseCommand() *cobra.Command {
lc := &cobra.Command{ lc := &cobra.Command{
Use: "lease", Use: "lease <subcommand>",
Short: "lease is used to manage leases.", Short: "Lease related commands",
} }
lc.AddCommand(NewLeaseGrantCommand()) lc.AddCommand(NewLeaseGrantCommand())
@ -41,7 +41,7 @@ func NewLeaseCommand() *cobra.Command {
func NewLeaseGrantCommand() *cobra.Command { func NewLeaseGrantCommand() *cobra.Command {
lc := &cobra.Command{ lc := &cobra.Command{
Use: "grant <ttl>", Use: "grant <ttl>",
Short: "grant is used to create leases.", Short: "Creates leases",
Run: leaseGrantCommandFunc, Run: leaseGrantCommandFunc,
} }
@ -73,7 +73,7 @@ func leaseGrantCommandFunc(cmd *cobra.Command, args []string) {
func NewLeaseRevokeCommand() *cobra.Command { func NewLeaseRevokeCommand() *cobra.Command {
lc := &cobra.Command{ lc := &cobra.Command{
Use: "revoke <leaseID>", Use: "revoke <leaseID>",
Short: "revoke is used to revoke leases.", Short: "Revokes leases",
Run: leaseRevokeCommandFunc, Run: leaseRevokeCommandFunc,
} }
@ -105,7 +105,7 @@ func leaseRevokeCommandFunc(cmd *cobra.Command, args []string) {
func NewLeaseKeepAliveCommand() *cobra.Command { func NewLeaseKeepAliveCommand() *cobra.Command {
lc := &cobra.Command{ lc := &cobra.Command{
Use: "keep-alive <leaseID>", Use: "keep-alive <leaseID>",
Short: "keep-alive is used to keep leases alive.", Short: "Keeps leases alive (renew)",
Run: leaseKeepAliveCommandFunc, Run: leaseKeepAliveCommandFunc,
} }

View File

@ -29,7 +29,7 @@ import (
func NewLockCommand() *cobra.Command { func NewLockCommand() *cobra.Command {
c := &cobra.Command{ c := &cobra.Command{
Use: "lock <lockname>", Use: "lock <lockname>",
Short: "lock acquires a named lock", Short: "Acquires a named lock",
Run: lockCommandFunc, Run: lockCommandFunc,
} }
return c return c

View File

@ -40,17 +40,17 @@ var (
func NewMakeMirrorCommand() *cobra.Command { func NewMakeMirrorCommand() *cobra.Command {
c := &cobra.Command{ c := &cobra.Command{
Use: "make-mirror [options] <destination>", Use: "make-mirror [options] <destination>",
Short: "make-mirror makes a mirror at the destination etcd cluster", Short: "Makes a mirror at the destination etcd cluster",
Run: makeMirrorCommandFunc, Run: makeMirrorCommandFunc,
} }
c.Flags().StringVar(&mmprefix, "prefix", "", "the key-value prefix to mirror") c.Flags().StringVar(&mmprefix, "prefix", "", "Key-value prefix to mirror")
// TODO: add dest-prefix to mirror a prefix to a different prefix in the destination cluster? // TODO: add dest-prefix to mirror a prefix to a different prefix in the destination cluster?
c.Flags().StringVar(&mmcert, "dest-cert", "", "identify secure client using this TLS certificate file for the destination cluster") c.Flags().StringVar(&mmcert, "dest-cert", "", "Identify secure client using this TLS certificate file for the destination cluster")
c.Flags().StringVar(&mmkey, "dest-key", "", "identify secure client using this TLS key file") c.Flags().StringVar(&mmkey, "dest-key", "", "Identify secure client using this TLS key file")
c.Flags().StringVar(&mmcacert, "dest-cacert", "", "verify certificates of TLS enabled secure servers using this CA bundle") c.Flags().StringVar(&mmcacert, "dest-cacert", "", "Verify certificates of TLS enabled secure servers using this CA bundle")
// TODO: secure by default when etcd enables secure gRPC by default. // TODO: secure by default when etcd enables secure gRPC by default.
c.Flags().BoolVar(&mminsecureTr, "dest-insecure-transport", true, "disable transport security for client connections") c.Flags().BoolVar(&mminsecureTr, "dest-insecure-transport", true, "Disable transport security for client connections")
return c return c
} }

View File

@ -27,8 +27,8 @@ var memberPeerURLs string
// NewMemberCommand returns the cobra command for "member". // NewMemberCommand returns the cobra command for "member".
func NewMemberCommand() *cobra.Command { func NewMemberCommand() *cobra.Command {
mc := &cobra.Command{ mc := &cobra.Command{
Use: "member", Use: "member <subcommand>",
Short: "member is used to manage membership in an etcd cluster.", Short: "Membership related commands",
} }
mc.AddCommand(NewMemberAddCommand()) mc.AddCommand(NewMemberAddCommand())
@ -43,7 +43,7 @@ func NewMemberCommand() *cobra.Command {
func NewMemberAddCommand() *cobra.Command { func NewMemberAddCommand() *cobra.Command {
cc := &cobra.Command{ cc := &cobra.Command{
Use: "add <memberName>", Use: "add <memberName>",
Short: "add is used to add a member into the cluster", Short: "Adds a member into the cluster",
Run: memberAddCommandFunc, Run: memberAddCommandFunc,
} }
@ -57,7 +57,7 @@ func NewMemberAddCommand() *cobra.Command {
func NewMemberRemoveCommand() *cobra.Command { func NewMemberRemoveCommand() *cobra.Command {
cc := &cobra.Command{ cc := &cobra.Command{
Use: "remove <memberID>", Use: "remove <memberID>",
Short: "remove is used to remove a member from the cluster", Short: "Removes a member from the cluster",
Run: memberRemoveCommandFunc, Run: memberRemoveCommandFunc,
} }
@ -69,7 +69,7 @@ func NewMemberRemoveCommand() *cobra.Command {
func NewMemberUpdateCommand() *cobra.Command { func NewMemberUpdateCommand() *cobra.Command {
cc := &cobra.Command{ cc := &cobra.Command{
Use: "update <memberID>", Use: "update <memberID>",
Short: "update is used to update a member in the cluster", Short: "Updates a member in the cluster",
Run: memberUpdateCommandFunc, Run: memberUpdateCommandFunc,
} }
@ -83,7 +83,7 @@ func NewMemberUpdateCommand() *cobra.Command {
func NewMemberListCommand() *cobra.Command { func NewMemberListCommand() *cobra.Command {
cc := &cobra.Command{ cc := &cobra.Command{
Use: "list", Use: "list",
Short: "list is used to list all members in the cluster", Short: "Lists all members in the cluster",
Long: `When --write-out is set to simple, this command prints out comma-separated member lists for each endpoint. Long: `When --write-out is set to simple, this command prints out comma-separated member lists for each endpoint.
The items in the lists are ID, Status, Name, Peer Addrs, Client Addrs. The items in the lists are ID, Status, Name, Peer Addrs, Client Addrs.
`, `,

View File

@ -51,13 +51,13 @@ var (
func NewMigrateCommand() *cobra.Command { func NewMigrateCommand() *cobra.Command {
mc := &cobra.Command{ mc := &cobra.Command{
Use: "migrate", Use: "migrate",
Short: "migrates keys in a v2 store to a mvcc store", Short: "Migrates keys in a v2 store to a mvcc store",
Run: migrateCommandFunc, Run: migrateCommandFunc,
} }
mc.Flags().StringVar(&migrateDatadir, "data-dir", "", "Path to the data directory.") mc.Flags().StringVar(&migrateDatadir, "data-dir", "", "Path to the data directory")
mc.Flags().StringVar(&migrateWALdir, "wal-dir", "", "Path to the WAL directory.") mc.Flags().StringVar(&migrateWALdir, "wal-dir", "", "Path to the WAL directory")
mc.Flags().StringVar(&migrateTransformer, "transformer", "", "Path to the user-provided transformer program.") mc.Flags().StringVar(&migrateTransformer, "transformer", "", "Path to the user-provided transformer program")
return mc return mc
} }

View File

@ -31,9 +31,9 @@ var (
func NewPutCommand() *cobra.Command { func NewPutCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "put [options] <key> <value> (<value> can also be given from stdin)", Use: "put [options] <key> <value> (<value> can also be given from stdin)",
Short: "Put puts the given key into the store.", Short: "Puts the given key into the store",
Long: ` Long: `
Put puts the given key into the store. Puts the given key into the store.
When <value> begins with '-', <value> is interpreted as a flag. When <value> begins with '-', <value> is interpreted as a flag.
Insert '--' for workaround: Insert '--' for workaround:

View File

@ -26,7 +26,7 @@ import (
func NewRoleCommand() *cobra.Command { func NewRoleCommand() *cobra.Command {
ac := &cobra.Command{ ac := &cobra.Command{
Use: "role <subcommand>", Use: "role <subcommand>",
Short: "role related command", Short: "Role related commands",
} }
ac.AddCommand(newRoleAddCommand()) ac.AddCommand(newRoleAddCommand())
@ -42,7 +42,7 @@ func NewRoleCommand() *cobra.Command {
func newRoleAddCommand() *cobra.Command { func newRoleAddCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "add <role name>", Use: "add <role name>",
Short: "add a new role", Short: "Adds a new role",
Run: roleAddCommandFunc, Run: roleAddCommandFunc,
} }
} }
@ -50,7 +50,7 @@ func newRoleAddCommand() *cobra.Command {
func newRoleDeleteCommand() *cobra.Command { func newRoleDeleteCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "delete <role name>", Use: "delete <role name>",
Short: "delete a role", Short: "Deletes a role",
Run: roleDeleteCommandFunc, Run: roleDeleteCommandFunc,
} }
} }
@ -58,7 +58,7 @@ func newRoleDeleteCommand() *cobra.Command {
func newRoleGetCommand() *cobra.Command { func newRoleGetCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "get <role name>", Use: "get <role name>",
Short: "get detailed information of a role", Short: "Gets detailed information of a role",
Run: roleGetCommandFunc, Run: roleGetCommandFunc,
} }
} }
@ -66,7 +66,7 @@ func newRoleGetCommand() *cobra.Command {
func newRoleListCommand() *cobra.Command { func newRoleListCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "list", Use: "list",
Short: "list up all roles", Short: "Lists all roles",
Run: roleListCommandFunc, Run: roleListCommandFunc,
} }
} }
@ -74,7 +74,7 @@ func newRoleListCommand() *cobra.Command {
func newRoleGrantPermissionCommand() *cobra.Command { func newRoleGrantPermissionCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "grant-permission <role name> <permission type> <key> [endkey]", Use: "grant-permission <role name> <permission type> <key> [endkey]",
Short: "grant a key to a role", Short: "Grants a key to a role",
Run: roleGrantPermissionCommandFunc, Run: roleGrantPermissionCommandFunc,
} }
} }
@ -82,7 +82,7 @@ func newRoleGrantPermissionCommand() *cobra.Command {
func newRoleRevokePermissionCommand() *cobra.Command { func newRoleRevokePermissionCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "revoke-permission <role name> <key> [endkey]", Use: "revoke-permission <role name> <key> [endkey]",
Short: "revoke a key from a role", Short: "Revokes a key from a role",
Run: roleRevokePermissionCommandFunc, Run: roleRevokePermissionCommandFunc,
} }
} }

View File

@ -58,8 +58,8 @@ var (
// NewSnapshotCommand returns the cobra command for "snapshot". // NewSnapshotCommand returns the cobra command for "snapshot".
func NewSnapshotCommand() *cobra.Command { func NewSnapshotCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "snapshot", Use: "snapshot <subcommand>",
Short: "snapshot manages etcd node snapshots.", Short: "Manages etcd node snapshots",
} }
cmd.AddCommand(NewSnapshotSaveCommand()) cmd.AddCommand(NewSnapshotSaveCommand())
cmd.AddCommand(NewSnapshotRestoreCommand()) cmd.AddCommand(NewSnapshotRestoreCommand())
@ -70,7 +70,7 @@ func NewSnapshotCommand() *cobra.Command {
func NewSnapshotSaveCommand() *cobra.Command { func NewSnapshotSaveCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "save <filename>", Use: "save <filename>",
Short: "save stores an etcd node backend snapshot to a given file.", Short: "Stores an etcd node backend snapshot to a given file",
Run: snapshotSaveCommandFunc, Run: snapshotSaveCommandFunc,
} }
} }
@ -78,7 +78,7 @@ func NewSnapshotSaveCommand() *cobra.Command {
func newSnapshotStatusCommand() *cobra.Command { func newSnapshotStatusCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "status <filename>", Use: "status <filename>",
Short: "status gets backend snapshot status of a given file.", Short: "Gets backend snapshot status of a given file",
Long: `When --write-out is set to simple, this command prints out comma-separated status lists for each endpoint. Long: `When --write-out is set to simple, this command prints out comma-separated status lists for each endpoint.
The items in the lists are hash, revision, total keys, total size. The items in the lists are hash, revision, total keys, total size.
`, `,
@ -89,15 +89,15 @@ The items in the lists are hash, revision, total keys, total size.
func NewSnapshotRestoreCommand() *cobra.Command { func NewSnapshotRestoreCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "restore <filename>", Use: "restore <filename>",
Short: "restore an etcd member snapshot to an etcd directory", Short: "Restores an etcd member snapshot to an etcd directory",
Run: snapshotRestoreCommandFunc, Run: snapshotRestoreCommandFunc,
} }
cmd.Flags().StringVar(&restoreDataDir, "data-dir", "", "Path to the data directory.") cmd.Flags().StringVar(&restoreDataDir, "data-dir", "", "Path to the data directory")
cmd.Flags().StringVar(&restoreCluster, "initial-cluster", initialClusterFromName(defaultName), "Initial cluster configuration for restore bootstrap.") cmd.Flags().StringVar(&restoreCluster, "initial-cluster", initialClusterFromName(defaultName), "Initial cluster configuration for restore bootstrap")
cmd.Flags().StringVar(&restoreClusterToken, "initial-cluster-token", "etcd-cluster", "Initial cluster token for the etcd cluster during restore bootstrap.") cmd.Flags().StringVar(&restoreClusterToken, "initial-cluster-token", "etcd-cluster", "Initial cluster token for the etcd cluster during restore bootstrap")
cmd.Flags().StringVar(&restorePeerURLs, "initial-advertise-peer-urls", defaultInitialAdvertisePeerURLs, "List of this member's peer URLs to advertise to the rest of the cluster.") cmd.Flags().StringVar(&restorePeerURLs, "initial-advertise-peer-urls", defaultInitialAdvertisePeerURLs, "List of this member's peer URLs to advertise to the rest of the cluster")
cmd.Flags().StringVar(&restoreName, "name", defaultName, "Human-readable name for this member.") cmd.Flags().StringVar(&restoreName, "name", defaultName, "Human-readable name for this member")
cmd.Flags().BoolVar(&skipHashCheck, "skip-hash-check", false, "Ignore snapshot integrity hash value (required if copied from data directory).") cmd.Flags().BoolVar(&skipHashCheck, "skip-hash-check", false, "Ignore snapshot integrity hash value (required if copied from data directory)")
return cmd return cmd
} }

View File

@ -34,10 +34,10 @@ var (
func NewTxnCommand() *cobra.Command { func NewTxnCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "txn [options]", Use: "txn [options]",
Short: "Txn processes all the requests in one transaction.", Short: "Txn processes all the requests in one transaction",
Run: txnCommandFunc, Run: txnCommandFunc,
} }
cmd.Flags().BoolVarP(&txnInteractive, "interactive", "i", false, "input transaction in interactive mode") cmd.Flags().BoolVarP(&txnInteractive, "interactive", "i", false, "Input transaction in interactive mode")
return cmd return cmd
} }

View File

@ -31,7 +31,7 @@ var (
func NewUserCommand() *cobra.Command { func NewUserCommand() *cobra.Command {
ac := &cobra.Command{ ac := &cobra.Command{
Use: "user <subcommand>", Use: "user <subcommand>",
Short: "user related command", Short: "User related commands",
} }
ac.AddCommand(newUserAddCommand()) ac.AddCommand(newUserAddCommand())
@ -52,11 +52,11 @@ var (
func newUserAddCommand() *cobra.Command { func newUserAddCommand() *cobra.Command {
cmd := cobra.Command{ cmd := cobra.Command{
Use: "add <user name>", Use: "add <user name>",
Short: "add a new user", Short: "Adds a new user",
Run: userAddCommandFunc, Run: userAddCommandFunc,
} }
cmd.Flags().BoolVar(&passwordInteractive, "interactive", true, "read password from stdin instead of interactive terminal") cmd.Flags().BoolVar(&passwordInteractive, "interactive", true, "Read password from stdin instead of interactive terminal")
return &cmd return &cmd
} }
@ -64,7 +64,7 @@ func newUserAddCommand() *cobra.Command {
func newUserDeleteCommand() *cobra.Command { func newUserDeleteCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "delete <user name>", Use: "delete <user name>",
Short: "delete a user", Short: "Deletes a user",
Run: userDeleteCommandFunc, Run: userDeleteCommandFunc,
} }
} }
@ -72,11 +72,11 @@ func newUserDeleteCommand() *cobra.Command {
func newUserGetCommand() *cobra.Command { func newUserGetCommand() *cobra.Command {
cmd := cobra.Command{ cmd := cobra.Command{
Use: "get <user name>", Use: "get <user name>",
Short: "get detailed information of a user", Short: "Gets detailed information of a user",
Run: userGetCommandFunc, Run: userGetCommandFunc,
} }
cmd.Flags().BoolVar(&userShowDetail, "detail", false, "show permissions of roles granted to the user") cmd.Flags().BoolVar(&userShowDetail, "detail", false, "Show permissions of roles granted to the user")
return &cmd return &cmd
} }
@ -84,7 +84,7 @@ func newUserGetCommand() *cobra.Command {
func newUserListCommand() *cobra.Command { func newUserListCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "list", Use: "list",
Short: "list up all users", Short: "Lists all users",
Run: userListCommandFunc, Run: userListCommandFunc,
} }
} }
@ -92,11 +92,11 @@ func newUserListCommand() *cobra.Command {
func newUserChangePasswordCommand() *cobra.Command { func newUserChangePasswordCommand() *cobra.Command {
cmd := cobra.Command{ cmd := cobra.Command{
Use: "passwd <user name>", Use: "passwd <user name>",
Short: "change password of user", Short: "Changes password of user",
Run: userChangePasswordCommandFunc, Run: userChangePasswordCommandFunc,
} }
cmd.Flags().BoolVar(&passwordInteractive, "interactive", true, "if true, read password from stdin instead of interactive terminal") cmd.Flags().BoolVar(&passwordInteractive, "interactive", true, "If true, read password from stdin instead of interactive terminal")
return &cmd return &cmd
} }
@ -104,7 +104,7 @@ func newUserChangePasswordCommand() *cobra.Command {
func newUserGrantRoleCommand() *cobra.Command { func newUserGrantRoleCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "grant-role <user name> <role name>", Use: "grant-role <user name> <role name>",
Short: "grant a role to a user", Short: "Grants a role to a user",
Run: userGrantRoleCommandFunc, Run: userGrantRoleCommandFunc,
} }
} }
@ -112,7 +112,7 @@ func newUserGrantRoleCommand() *cobra.Command {
func newUserRevokeRoleCommand() *cobra.Command { func newUserRevokeRoleCommand() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "revoke-role <user name> <role name>", Use: "revoke-role <user name> <role name>",
Short: "revoke a role from a user", Short: "Revokes a role from a user",
Run: userRevokeRoleCommandFunc, Run: userRevokeRoleCommandFunc,
} }
} }

View File

@ -26,7 +26,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 etcdctl.", Short: "Prints the version of etcdctl",
Run: versionCommandFunc, Run: versionCommandFunc,
} }
} }

View File

@ -35,13 +35,13 @@ var (
func NewWatchCommand() *cobra.Command { func NewWatchCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "watch [options] [key or prefix] [range_end]", Use: "watch [options] [key or prefix] [range_end]",
Short: "Watch watches events stream on keys or prefixes.", Short: "Watches events stream on keys or prefixes",
Run: watchCommandFunc, Run: watchCommandFunc,
} }
cmd.Flags().BoolVarP(&watchInteractive, "interactive", "i", false, "interactive mode") cmd.Flags().BoolVarP(&watchInteractive, "interactive", "i", false, "Interactive mode")
cmd.Flags().BoolVar(&watchPrefix, "prefix", false, "watch on a prefix if prefix is set") cmd.Flags().BoolVar(&watchPrefix, "prefix", false, "Watch on a prefix if prefix is set")
cmd.Flags().Int64Var(&watchRev, "rev", 0, "revision to start watching") cmd.Flags().Int64Var(&watchRev, "rev", 0, "Revision to start watching")
return cmd return cmd
} }

View File

@ -8,6 +8,7 @@ all: cfssl ca req
cfssl: cfssl:
go get -u -tags nopkcs11 github.com/cloudflare/cfssl/cmd/cfssl go get -u -tags nopkcs11 github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson go get -u github.com/cloudflare/cfssl/cmd/cfssljson
go get -u github.com/mattn/goreman
ca: ca:
mkdir -p certs mkdir -p certs

View File

@ -55,7 +55,7 @@ const (
type Backend interface { type Backend interface {
BatchTx() BatchTx BatchTx() BatchTx
Snapshot() Snapshot Snapshot() Snapshot
Hash() (uint32, error) Hash(ignores map[IgnoreKey]struct{}) (uint32, error)
// Size returns the current size of the backend. // Size returns the current size of the backend.
Size() int64 Size() int64
Defrag() error Defrag() error
@ -144,7 +144,12 @@ func (b *backend) Snapshot() Snapshot {
return &snapshot{tx} return &snapshot{tx}
} }
func (b *backend) Hash() (uint32, error) { type IgnoreKey struct {
Bucket string
Key string
}
func (b *backend) Hash(ignores map[IgnoreKey]struct{}) (uint32, error) {
h := crc32.New(crc32.MakeTable(crc32.Castagnoli)) h := crc32.New(crc32.MakeTable(crc32.Castagnoli))
b.mu.RLock() b.mu.RLock()
@ -158,8 +163,11 @@ func (b *backend) Hash() (uint32, error) {
} }
h.Write(next) h.Write(next)
b.ForEach(func(k, v []byte) error { b.ForEach(func(k, v []byte) error {
h.Write(k) bk := IgnoreKey{Bucket: string(next), Key: string(k)}
h.Write(v) if _, ok := ignores[bk]; !ok {
h.Write(k)
h.Write(v)
}
return nil return nil
}) })
} }

View File

@ -141,7 +141,7 @@ func TestBackendDefrag(t *testing.T) {
size := b.Size() size := b.Size()
// shrink and check hash // shrink and check hash
oh, err := b.Hash() oh, err := b.Hash(nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -151,7 +151,7 @@ func TestBackendDefrag(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
nh, err := b.Hash() nh, err := b.Hash(nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -320,7 +320,14 @@ func (s *store) Hash() (uint32, int64, error) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
h, err := s.b.Hash() // ignore hash consistent index field for now.
// consistent index might be changed due to v2 internal sync, which
// is not controllable by the user.
ignores := make(map[backend.IgnoreKey]struct{})
bk := backend.IgnoreKey{Bucket: string(metaBucketName), Key: string(consistentIndexKeyName)}
ignores[bk] = struct{}{}
h, err := s.b.Hash(ignores)
rev := s.currentRev.main rev := s.currentRev.main
return h, rev, err return h, rev, err
} }

View File

@ -593,13 +593,13 @@ type fakeBackend struct {
tx *fakeBatchTx tx *fakeBatchTx
} }
func (b *fakeBackend) BatchTx() backend.BatchTx { return b.tx } func (b *fakeBackend) BatchTx() backend.BatchTx { return b.tx }
func (b *fakeBackend) Hash() (uint32, error) { return 0, nil } func (b *fakeBackend) Hash(ignores map[backend.IgnoreKey]struct{}) (uint32, error) { return 0, nil }
func (b *fakeBackend) Size() int64 { return 0 } func (b *fakeBackend) Size() int64 { return 0 }
func (b *fakeBackend) Snapshot() backend.Snapshot { return nil } func (b *fakeBackend) Snapshot() backend.Snapshot { return nil }
func (b *fakeBackend) ForceCommit() {} func (b *fakeBackend) ForceCommit() {}
func (b *fakeBackend) Defrag() error { return nil } func (b *fakeBackend) Defrag() error { return nil }
func (b *fakeBackend) Close() error { return nil } func (b *fakeBackend) Close() error { return nil }
type indexGetResp struct { type indexGetResp struct {
rev revision rev revision

View File

@ -143,7 +143,7 @@ func compactKV(clients []*v3.Client) {
revToCompact := max(0, curRev-compactIndexDelta) revToCompact := max(0, curRev-compactIndexDelta)
for _, c := range clients { for _, c := range clients {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
err := c.KV.Compact(ctx, revToCompact) _, err := c.KV.Compact(ctx, revToCompact)
cancel() cancel()
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -29,7 +29,7 @@ import (
var ( var (
// MinClusterVersion is the min cluster version this etcd binary is compatible with. // MinClusterVersion is the min cluster version this etcd binary is compatible with.
MinClusterVersion = "2.3.0" MinClusterVersion = "2.3.0"
Version = "3.0.0-beta.0+git" Version = "3.0.0"
// Git SHA Value will be set during build // Git SHA Value will be set during build
GitSHA = "Not provided (use ./build instead of go build)" GitSHA = "Not provided (use ./build instead of go build)"