Compare commits
11 Commits
v3.5.0-bet
...
v3.0.0
Author | SHA1 | Date | |
---|---|---|---|
6f48bda7ac | |||
316534e09e | |||
3cecbdb464 | |||
62f11e43ee | |||
064c1585ee | |||
15300a1eb8 | |||
58dd047ee4 | |||
4b42ea6cd7 | |||
53c27ae621 | |||
269de67bde | |||
8bbccf1047 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@
|
||||
/hack/insta-discovery/.env
|
||||
*.test
|
||||
tools/functional-tester/docker/bin
|
||||
hack/tls-setup/certs
|
||||
|
@ -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:
|
||||
|
||||
- v3 auth API: expect to be stale in 3.1 release
|
||||
- etcd gateway: expect to be stable 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
|
||||
|
@ -8,7 +8,7 @@ In order to expose the etcd API to clients outside of Docker host, use the host
|
||||
|
||||
```
|
||||
# For each machine
|
||||
ETCD_VERSION=v3.0.0-beta.0
|
||||
ETCD_VERSION=v3.0.0
|
||||
TOKEN=my-etcd-token
|
||||
CLUSTER_STATE=new
|
||||
NAME_1=etcd-node-0
|
||||
|
@ -210,7 +210,7 @@ func ExampleKV_compact() {
|
||||
compRev := resp.Header.Revision // specify compact revision of your choice
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), requestTimeout)
|
||||
err = cli.Compact(ctx, compRev)
|
||||
_, err = cli.Compact(ctx, compRev)
|
||||
cancel()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -470,17 +470,17 @@ func TestKVCompactError(t *testing.T) {
|
||||
t.Fatalf("couldn't put 'foo' (%v)", err)
|
||||
}
|
||||
}
|
||||
err := kv.Compact(ctx, 6)
|
||||
_, err := kv.Compact(ctx, 6)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't compact 6 (%v)", err)
|
||||
}
|
||||
|
||||
err = kv.Compact(ctx, 6)
|
||||
_, err = kv.Compact(ctx, 6)
|
||||
if err != rpctypes.ErrCompacted {
|
||||
t.Fatalf("expected %v, got %v", rpctypes.ErrCompacted, err)
|
||||
}
|
||||
|
||||
err = kv.Compact(ctx, 100)
|
||||
_, err = kv.Compact(ctx, 100)
|
||||
if err != rpctypes.ErrFutureRev {
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
err = kv.Compact(ctx, 1000)
|
||||
_, err = kv.Compact(ctx, 1000)
|
||||
if err == nil || err != rpctypes.ErrFutureRev {
|
||||
t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev)
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ func TestWatchResumeCompacted(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := kv.Compact(context.TODO(), 3); err != nil {
|
||||
if _, err := kv.Compact(context.TODO(), 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -414,7 +414,7 @@ func TestWatchCompactRevision(t *testing.T) {
|
||||
w := clientv3.NewWatcher(clus.RandClient())
|
||||
defer w.Close()
|
||||
|
||||
if err := kv.Compact(context.TODO(), 4); err != nil {
|
||||
if _, err := kv.Compact(context.TODO(), 4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wch := w.Watch(context.Background(), "foo", clientv3.WithRev(2))
|
||||
|
@ -20,10 +20,11 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PutResponse pb.PutResponse
|
||||
GetResponse pb.RangeResponse
|
||||
DeleteResponse pb.DeleteRangeResponse
|
||||
TxnResponse pb.TxnResponse
|
||||
CompactResponse pb.CompactionResponse
|
||||
PutResponse pb.PutResponse
|
||||
GetResponse pb.RangeResponse
|
||||
DeleteResponse pb.DeleteRangeResponse
|
||||
TxnResponse pb.TxnResponse
|
||||
)
|
||||
|
||||
type KV interface {
|
||||
@ -47,7 +48,7 @@ type KV interface {
|
||||
Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
|
||||
|
||||
// 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 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)
|
||||
}
|
||||
|
||||
func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) error {
|
||||
if _, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest()); err != nil {
|
||||
return toErr(ctx, err)
|
||||
func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) {
|
||||
resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest())
|
||||
if err != nil {
|
||||
return nil, toErr(ctx, err)
|
||||
}
|
||||
return nil
|
||||
return (*CompactResponse)(resp), err
|
||||
}
|
||||
|
||||
func (kv *kv) Txn(ctx context.Context) Txn {
|
||||
|
@ -505,6 +505,7 @@ func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) {
|
||||
|
||||
// serveStream forwards watch responses from run() to the subscriber
|
||||
func (w *watchGrpcStream) serveStream(ws *watcherStream) {
|
||||
var closeErr error
|
||||
emptyWr := &WatchResponse{}
|
||||
wrs := []*WatchResponse{}
|
||||
resuming := false
|
||||
@ -569,13 +570,14 @@ func (w *watchGrpcStream) serveStream(ws *watcherStream) {
|
||||
}
|
||||
case <-w.donec:
|
||||
closing = true
|
||||
closeErr = w.closeErr
|
||||
case <-ws.initReq.ctx.Done():
|
||||
closing = true
|
||||
}
|
||||
}
|
||||
|
||||
// try to send off close error
|
||||
if w.closeErr != nil {
|
||||
if closeErr != nil {
|
||||
select {
|
||||
case ws.outc <- WatchResponse{closeErr: w.closeErr}:
|
||||
case <-w.donec:
|
||||
|
@ -497,25 +497,25 @@ ENDPOINT STATUS does not support protobuf encoded output.
|
||||
|
||||
```bash
|
||||
./etcdctl endpoint status
|
||||
127.0.0.1:2379, 8211f1d0f64f3269, 3.0.0-beta.0+git, 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:32379, fd422379fda50e48, 3.0.0-beta.0+git, 25 kB, true, 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, 25 kB, false, 2, 63
|
||||
127.0.0.1:32379, fd422379fda50e48, 3.0.0, 25 kB, true, 2, 63
|
||||
```
|
||||
|
||||
```bash
|
||||
./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
|
||||
./etcdctl -w table endpoint status
|
||||
+-----------------+------------------+------------------+---------+-----------+-----------+------------+
|
||||
| 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:22379 | 91bc3c398fb3c146 | 3.0.0-beta.0+git | 25 kB | false | 2 | 52 |
|
||||
| 127.0.0.1:32379 | fd422379fda50e48 | 3.0.0-beta.0+git | 25 kB | true | 2 | 52 |
|
||||
+-----------------+------------------+------------------+---------+-----------+-----------+------------+
|
||||
+-----------------+------------------+---------+---------+-----------+-----------+------------+
|
||||
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
|
||||
+-----------------+------------------+---------+---------+-----------+-----------+------------+
|
||||
| 127.0.0.1:2379 | 8211f1d0f64f3269 | 3.0.0 | 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 | 25 kB | true | 2 | 52 |
|
||||
+-----------------+------------------+---------+---------+-----------+-----------+------------+
|
||||
```
|
||||
|
||||
### LOCK \<lockname\>
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
func NewAlarmCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "alarm <subcommand>",
|
||||
Short: "alarm related command",
|
||||
Short: "Alarm related commands",
|
||||
}
|
||||
|
||||
ac.AddCommand(NewAlarmDisarmCommand())
|
||||
@ -37,7 +37,7 @@ func NewAlarmCommand() *cobra.Command {
|
||||
func NewAlarmDisarmCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "disarm",
|
||||
Short: "disarm all alarms",
|
||||
Short: "Disarms all alarms",
|
||||
Run: alarmDisarmCommandFunc,
|
||||
}
|
||||
return &cmd
|
||||
@ -60,7 +60,7 @@ func alarmDisarmCommandFunc(cmd *cobra.Command, args []string) {
|
||||
func NewAlarmListCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "list",
|
||||
Short: "list all alarms",
|
||||
Short: "Lists all alarms",
|
||||
Run: alarmListCommandFunc,
|
||||
}
|
||||
return &cmd
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
func NewAuthCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "auth <enable or disable>",
|
||||
Short: "Enable or disable authentication.",
|
||||
Short: "Enable or disable authentication",
|
||||
}
|
||||
|
||||
ac.AddCommand(newAuthEnableCommand())
|
||||
@ -36,7 +36,7 @@ func NewAuthCommand() *cobra.Command {
|
||||
func newAuthEnableCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "enable",
|
||||
Short: "enable authentication",
|
||||
Short: "Enables authentication",
|
||||
Run: authEnableCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ func authEnableCommandFunc(cmd *cobra.Command, args []string) {
|
||||
func newAuthDisableCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "disable",
|
||||
Short: "disable authentication",
|
||||
Short: "Disables authentication",
|
||||
Run: authDisableCommandFunc,
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ var compactPhysical bool
|
||||
func NewCompactionCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "compaction <revision>",
|
||||
Short: "Compaction compacts the event history in etcd.",
|
||||
Short: "Compacts the event history in etcd",
|
||||
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
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ func compactionCommandFunc(cmd *cobra.Command, args []string) {
|
||||
|
||||
c := mustClientFromCmd(cmd)
|
||||
ctx, cancel := commandCtx(cmd)
|
||||
cerr := c.Compact(ctx, rev, opts...)
|
||||
_, cerr := c.Compact(ctx, rev, opts...)
|
||||
cancel()
|
||||
if cerr != nil {
|
||||
ExitWithError(ExitError, cerr)
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
func NewDefragCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ var (
|
||||
func NewDelCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ var (
|
||||
func NewElectCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "elect <election-name> [proposal]",
|
||||
Short: "elect observes and participates in leader election",
|
||||
Short: "Observes and participates in leader election",
|
||||
Run: electCommandFunc,
|
||||
}
|
||||
cmd.Flags().BoolVarP(&electListen, "listen", "l", false, "observation mode")
|
||||
|
@ -28,8 +28,8 @@ import (
|
||||
// NewEndpointCommand returns the cobra command for "endpoint".
|
||||
func NewEndpointCommand() *cobra.Command {
|
||||
ec := &cobra.Command{
|
||||
Use: "endpoint",
|
||||
Short: "endpoint is used to check endpoints.",
|
||||
Use: "endpoint <subcommand>",
|
||||
Short: "Endpoint related commands",
|
||||
}
|
||||
|
||||
ec.AddCommand(newEpHealthCommand())
|
||||
@ -41,7 +41,7 @@ func NewEndpointCommand() *cobra.Command {
|
||||
func newEpHealthCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
return cmd
|
||||
@ -50,7 +50,7 @@ func newEpHealthCommand() *cobra.Command {
|
||||
func newEpStatusCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
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.
|
||||
The items in the lists are endpoint, ID, version, db size, is leader, raft term, raft index.
|
||||
`,
|
||||
|
@ -37,18 +37,18 @@ var (
|
||||
func NewGetCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
|
||||
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(&getSortTarget, "sort-by", "", "sort target; CREATE, KEY, MODIFY, VALUE, or VERSION")
|
||||
cmd.Flags().Int64Var(&getLimit, "limit", 0, "maximum number of results")
|
||||
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().Int64Var(&getRev, "rev", 0, "specify the kv revision")
|
||||
cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "get only the keys")
|
||||
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().Int64Var(&getLimit, "limit", 0, "Maximum number of results")
|
||||
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().Int64Var(&getRev, "rev", 0, "Specify the kv revision")
|
||||
cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "Get only the keys")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ import (
|
||||
// NewLeaseCommand returns the cobra command for "lease".
|
||||
func NewLeaseCommand() *cobra.Command {
|
||||
lc := &cobra.Command{
|
||||
Use: "lease",
|
||||
Short: "lease is used to manage leases.",
|
||||
Use: "lease <subcommand>",
|
||||
Short: "Lease related commands",
|
||||
}
|
||||
|
||||
lc.AddCommand(NewLeaseGrantCommand())
|
||||
@ -41,7 +41,7 @@ func NewLeaseCommand() *cobra.Command {
|
||||
func NewLeaseGrantCommand() *cobra.Command {
|
||||
lc := &cobra.Command{
|
||||
Use: "grant <ttl>",
|
||||
Short: "grant is used to create leases.",
|
||||
Short: "Creates leases",
|
||||
|
||||
Run: leaseGrantCommandFunc,
|
||||
}
|
||||
@ -73,7 +73,7 @@ func leaseGrantCommandFunc(cmd *cobra.Command, args []string) {
|
||||
func NewLeaseRevokeCommand() *cobra.Command {
|
||||
lc := &cobra.Command{
|
||||
Use: "revoke <leaseID>",
|
||||
Short: "revoke is used to revoke leases.",
|
||||
Short: "Revokes leases",
|
||||
|
||||
Run: leaseRevokeCommandFunc,
|
||||
}
|
||||
@ -105,7 +105,7 @@ func leaseRevokeCommandFunc(cmd *cobra.Command, args []string) {
|
||||
func NewLeaseKeepAliveCommand() *cobra.Command {
|
||||
lc := &cobra.Command{
|
||||
Use: "keep-alive <leaseID>",
|
||||
Short: "keep-alive is used to keep leases alive.",
|
||||
Short: "Keeps leases alive (renew)",
|
||||
|
||||
Run: leaseKeepAliveCommandFunc,
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
func NewLockCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: "lock <lockname>",
|
||||
Short: "lock acquires a named lock",
|
||||
Short: "Acquires a named lock",
|
||||
Run: lockCommandFunc,
|
||||
}
|
||||
return c
|
||||
|
@ -40,17 +40,17 @@ var (
|
||||
func NewMakeMirrorCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
|
||||
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?
|
||||
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(&mmcacert, "dest-cacert", "", "verify certificates of TLS enabled secure servers using this CA bundle")
|
||||
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(&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.
|
||||
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
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ var memberPeerURLs string
|
||||
// NewMemberCommand returns the cobra command for "member".
|
||||
func NewMemberCommand() *cobra.Command {
|
||||
mc := &cobra.Command{
|
||||
Use: "member",
|
||||
Short: "member is used to manage membership in an etcd cluster.",
|
||||
Use: "member <subcommand>",
|
||||
Short: "Membership related commands",
|
||||
}
|
||||
|
||||
mc.AddCommand(NewMemberAddCommand())
|
||||
@ -43,7 +43,7 @@ func NewMemberCommand() *cobra.Command {
|
||||
func NewMemberAddCommand() *cobra.Command {
|
||||
cc := &cobra.Command{
|
||||
Use: "add <memberName>",
|
||||
Short: "add is used to add a member into the cluster",
|
||||
Short: "Adds a member into the cluster",
|
||||
|
||||
Run: memberAddCommandFunc,
|
||||
}
|
||||
@ -57,7 +57,7 @@ func NewMemberAddCommand() *cobra.Command {
|
||||
func NewMemberRemoveCommand() *cobra.Command {
|
||||
cc := &cobra.Command{
|
||||
Use: "remove <memberID>",
|
||||
Short: "remove is used to remove a member from the cluster",
|
||||
Short: "Removes a member from the cluster",
|
||||
|
||||
Run: memberRemoveCommandFunc,
|
||||
}
|
||||
@ -69,7 +69,7 @@ func NewMemberRemoveCommand() *cobra.Command {
|
||||
func NewMemberUpdateCommand() *cobra.Command {
|
||||
cc := &cobra.Command{
|
||||
Use: "update <memberID>",
|
||||
Short: "update is used to update a member in the cluster",
|
||||
Short: "Updates a member in the cluster",
|
||||
|
||||
Run: memberUpdateCommandFunc,
|
||||
}
|
||||
@ -83,7 +83,7 @@ func NewMemberUpdateCommand() *cobra.Command {
|
||||
func NewMemberListCommand() *cobra.Command {
|
||||
cc := &cobra.Command{
|
||||
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.
|
||||
The items in the lists are ID, Status, Name, Peer Addrs, Client Addrs.
|
||||
`,
|
||||
|
@ -51,13 +51,13 @@ var (
|
||||
func NewMigrateCommand() *cobra.Command {
|
||||
mc := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
|
||||
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(&migrateTransformer, "transformer", "", "Path to the user-provided transformer program.")
|
||||
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(&migrateTransformer, "transformer", "", "Path to the user-provided transformer program")
|
||||
return mc
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,9 @@ var (
|
||||
func NewPutCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
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: `
|
||||
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.
|
||||
Insert '--' for workaround:
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
func NewRoleCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "role <subcommand>",
|
||||
Short: "role related command",
|
||||
Short: "Role related commands",
|
||||
}
|
||||
|
||||
ac.AddCommand(newRoleAddCommand())
|
||||
@ -42,7 +42,7 @@ func NewRoleCommand() *cobra.Command {
|
||||
func newRoleAddCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "add <role name>",
|
||||
Short: "add a new role",
|
||||
Short: "Adds a new role",
|
||||
Run: roleAddCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ func newRoleAddCommand() *cobra.Command {
|
||||
func newRoleDeleteCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "delete <role name>",
|
||||
Short: "delete a role",
|
||||
Short: "Deletes a role",
|
||||
Run: roleDeleteCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ func newRoleDeleteCommand() *cobra.Command {
|
||||
func newRoleGetCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "get <role name>",
|
||||
Short: "get detailed information of a role",
|
||||
Short: "Gets detailed information of a role",
|
||||
Run: roleGetCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -66,7 +66,7 @@ func newRoleGetCommand() *cobra.Command {
|
||||
func newRoleListCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "list up all roles",
|
||||
Short: "Lists all roles",
|
||||
Run: roleListCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ func newRoleListCommand() *cobra.Command {
|
||||
func newRoleGrantPermissionCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
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,
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ func newRoleGrantPermissionCommand() *cobra.Command {
|
||||
func newRoleRevokePermissionCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "revoke-permission <role name> <key> [endkey]",
|
||||
Short: "revoke a key from a role",
|
||||
Short: "Revokes a key from a role",
|
||||
Run: roleRevokePermissionCommandFunc,
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ var (
|
||||
// NewSnapshotCommand returns the cobra command for "snapshot".
|
||||
func NewSnapshotCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "snapshot",
|
||||
Short: "snapshot manages etcd node snapshots.",
|
||||
Use: "snapshot <subcommand>",
|
||||
Short: "Manages etcd node snapshots",
|
||||
}
|
||||
cmd.AddCommand(NewSnapshotSaveCommand())
|
||||
cmd.AddCommand(NewSnapshotRestoreCommand())
|
||||
@ -70,7 +70,7 @@ func NewSnapshotCommand() *cobra.Command {
|
||||
func NewSnapshotSaveCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
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,
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ func NewSnapshotSaveCommand() *cobra.Command {
|
||||
func newSnapshotStatusCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
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.
|
||||
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 {
|
||||
cmd := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
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(&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(&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().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(&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(&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)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ var (
|
||||
func NewTxnCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "txn [options]",
|
||||
Short: "Txn processes all the requests in one transaction.",
|
||||
Short: "Txn processes all the requests in one transaction",
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ var (
|
||||
func NewUserCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "user <subcommand>",
|
||||
Short: "user related command",
|
||||
Short: "User related commands",
|
||||
}
|
||||
|
||||
ac.AddCommand(newUserAddCommand())
|
||||
@ -52,11 +52,11 @@ var (
|
||||
func newUserAddCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "add <user name>",
|
||||
Short: "add a new user",
|
||||
Short: "Adds a new user",
|
||||
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
|
||||
}
|
||||
@ -64,7 +64,7 @@ func newUserAddCommand() *cobra.Command {
|
||||
func newUserDeleteCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "delete <user name>",
|
||||
Short: "delete a user",
|
||||
Short: "Deletes a user",
|
||||
Run: userDeleteCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -72,11 +72,11 @@ func newUserDeleteCommand() *cobra.Command {
|
||||
func newUserGetCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "get <user name>",
|
||||
Short: "get detailed information of a user",
|
||||
Short: "Gets detailed information of a user",
|
||||
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
|
||||
}
|
||||
@ -84,7 +84,7 @@ func newUserGetCommand() *cobra.Command {
|
||||
func newUserListCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "list up all users",
|
||||
Short: "Lists all users",
|
||||
Run: userListCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -92,11 +92,11 @@ func newUserListCommand() *cobra.Command {
|
||||
func newUserChangePasswordCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "passwd <user name>",
|
||||
Short: "change password of user",
|
||||
Short: "Changes password of user",
|
||||
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
|
||||
}
|
||||
@ -104,7 +104,7 @@ func newUserChangePasswordCommand() *cobra.Command {
|
||||
func newUserGrantRoleCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "grant-role <user name> <role name>",
|
||||
Short: "grant a role to a user",
|
||||
Short: "Grants a role to a user",
|
||||
Run: userGrantRoleCommandFunc,
|
||||
}
|
||||
}
|
||||
@ -112,7 +112,7 @@ func newUserGrantRoleCommand() *cobra.Command {
|
||||
func newUserRevokeRoleCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "revoke-role <user name> <role name>",
|
||||
Short: "revoke a role from a user",
|
||||
Short: "Revokes a role from a user",
|
||||
Run: userRevokeRoleCommandFunc,
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
func NewVersionCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version of etcdctl.",
|
||||
Short: "Prints the version of etcdctl",
|
||||
Run: versionCommandFunc,
|
||||
}
|
||||
}
|
||||
|
@ -35,13 +35,13 @@ var (
|
||||
func NewWatchCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
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,
|
||||
}
|
||||
|
||||
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().Int64Var(&watchRev, "rev", 0, "revision to start watching")
|
||||
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().Int64Var(&watchRev, "rev", 0, "Revision to start watching")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ all: cfssl ca req
|
||||
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/mattn/goreman
|
||||
|
||||
ca:
|
||||
mkdir -p certs
|
||||
|
@ -55,7 +55,7 @@ const (
|
||||
type Backend interface {
|
||||
BatchTx() BatchTx
|
||||
Snapshot() Snapshot
|
||||
Hash() (uint32, error)
|
||||
Hash(ignores map[IgnoreKey]struct{}) (uint32, error)
|
||||
// Size returns the current size of the backend.
|
||||
Size() int64
|
||||
Defrag() error
|
||||
@ -144,7 +144,12 @@ func (b *backend) Snapshot() Snapshot {
|
||||
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))
|
||||
|
||||
b.mu.RLock()
|
||||
@ -158,8 +163,11 @@ func (b *backend) Hash() (uint32, error) {
|
||||
}
|
||||
h.Write(next)
|
||||
b.ForEach(func(k, v []byte) error {
|
||||
h.Write(k)
|
||||
h.Write(v)
|
||||
bk := IgnoreKey{Bucket: string(next), Key: string(k)}
|
||||
if _, ok := ignores[bk]; !ok {
|
||||
h.Write(k)
|
||||
h.Write(v)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ func TestBackendDefrag(t *testing.T) {
|
||||
size := b.Size()
|
||||
|
||||
// shrink and check hash
|
||||
oh, err := b.Hash()
|
||||
oh, err := b.Hash(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -151,7 +151,7 @@ func TestBackendDefrag(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
nh, err := b.Hash()
|
||||
nh, err := b.Hash(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -320,7 +320,14 @@ func (s *store) Hash() (uint32, int64, error) {
|
||||
s.mu.Lock()
|
||||
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
|
||||
return h, rev, err
|
||||
}
|
||||
|
@ -593,13 +593,13 @@ type fakeBackend struct {
|
||||
tx *fakeBatchTx
|
||||
}
|
||||
|
||||
func (b *fakeBackend) BatchTx() backend.BatchTx { return b.tx }
|
||||
func (b *fakeBackend) Hash() (uint32, error) { return 0, nil }
|
||||
func (b *fakeBackend) Size() int64 { return 0 }
|
||||
func (b *fakeBackend) Snapshot() backend.Snapshot { return nil }
|
||||
func (b *fakeBackend) ForceCommit() {}
|
||||
func (b *fakeBackend) Defrag() error { return nil }
|
||||
func (b *fakeBackend) Close() error { return nil }
|
||||
func (b *fakeBackend) BatchTx() backend.BatchTx { return b.tx }
|
||||
func (b *fakeBackend) Hash(ignores map[backend.IgnoreKey]struct{}) (uint32, error) { return 0, nil }
|
||||
func (b *fakeBackend) Size() int64 { return 0 }
|
||||
func (b *fakeBackend) Snapshot() backend.Snapshot { return nil }
|
||||
func (b *fakeBackend) ForceCommit() {}
|
||||
func (b *fakeBackend) Defrag() error { return nil }
|
||||
func (b *fakeBackend) Close() error { return nil }
|
||||
|
||||
type indexGetResp struct {
|
||||
rev revision
|
||||
|
@ -143,7 +143,7 @@ func compactKV(clients []*v3.Client) {
|
||||
revToCompact := max(0, curRev-compactIndexDelta)
|
||||
for _, c := range clients {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
err := c.KV.Compact(ctx, revToCompact)
|
||||
_, err := c.KV.Compact(ctx, revToCompact)
|
||||
cancel()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
var (
|
||||
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
|
||||
MinClusterVersion = "2.3.0"
|
||||
Version = "3.0.0-beta.0+git"
|
||||
Version = "3.0.0"
|
||||
|
||||
// Git SHA Value will be set during build
|
||||
GitSHA = "Not provided (use ./build instead of go build)"
|
||||
|
Reference in New Issue
Block a user