diff --git a/go.mod b/go.mod index 268098466f1..c9e3b04fa4b 100644 --- a/go.mod +++ b/go.mod @@ -99,7 +99,7 @@ require ( github.com/urfave/negroni v1.0.0 // indirect github.com/vishvananda/netlink v1.1.0 github.com/vmware/govmomi v0.20.3 - go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 + go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 @@ -414,7 +414,7 @@ replace ( github.com/xlab/handysort => github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 github.com/xordataexchange/crypt => github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 go.etcd.io/bbolt => go.etcd.io/bbolt v1.3.3 - go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 // e694b7bb0875 is the SHA for git tag v3.4.7 + go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f // 54ba9589114f is the SHA for git tag v3.4.9 go.mongodb.org/mongo-driver => go.mongodb.org/mongo-driver v1.1.2 go.opencensus.io => go.opencensus.io v0.22.2 go.uber.org/atomic => go.uber.org/atomic v1.4.0 diff --git a/go.sum b/go.sum index ad2429327cf..23cecedcc4d 100644 --- a/go.sum +++ b/go.sum @@ -465,8 +465,8 @@ github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSf github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 h1:C7kWARE8r64ppRadl40yfNo6pag+G6ocvGU2xZ6yNes= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f h1:pBCD+Z7cy5WPTq+R6MmJJvDRpn88cp7bmTypBsn91g4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= diff --git a/staging/src/k8s.io/apiextensions-apiserver/go.mod b/staging/src/k8s.io/apiextensions-apiserver/go.mod index e951f0068a6..967e9c36107 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/go.mod +++ b/staging/src/k8s.io/apiextensions-apiserver/go.mod @@ -18,7 +18,7 @@ require ( github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.4.0 - go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 + go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f google.golang.org/grpc v1.26.0 gopkg.in/yaml.v2 v2.2.8 k8s.io/api v0.0.0 diff --git a/staging/src/k8s.io/apiextensions-apiserver/go.sum b/staging/src/k8s.io/apiextensions-apiserver/go.sum index b7f5ba3c91f..21dfecdff82 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/go.sum +++ b/staging/src/k8s.io/apiextensions-apiserver/go.sum @@ -382,8 +382,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 h1:C7kWARE8r64ppRadl40yfNo6pag+G6ocvGU2xZ6yNes= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f h1:pBCD+Z7cy5WPTq+R6MmJJvDRpn88cp7bmTypBsn91g4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA= @@ -503,7 +503,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/staging/src/k8s.io/apiserver/go.mod b/staging/src/k8s.io/apiserver/go.mod index 84001ab7785..2f883224e99 100644 --- a/staging/src/k8s.io/apiserver/go.mod +++ b/staging/src/k8s.io/apiserver/go.mod @@ -30,7 +30,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.4.0 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect - go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 + go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f go.uber.org/atomic v1.4.0 // indirect go.uber.org/zap v1.10.0 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 diff --git a/staging/src/k8s.io/apiserver/go.sum b/staging/src/k8s.io/apiserver/go.sum index 9d99d8ffe97..18d8a88908d 100644 --- a/staging/src/k8s.io/apiserver/go.sum +++ b/staging/src/k8s.io/apiserver/go.sum @@ -295,8 +295,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 h1:C7kWARE8r64ppRadl40yfNo6pag+G6ocvGU2xZ6yNes= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f h1:pBCD+Z7cy5WPTq+R6MmJJvDRpn88cp7bmTypBsn91g4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -405,7 +405,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/staging/src/k8s.io/kube-aggregator/go.sum b/staging/src/k8s.io/kube-aggregator/go.sum index 53da37a303f..a4ea118d162 100644 --- a/staging/src/k8s.io/kube-aggregator/go.sum +++ b/staging/src/k8s.io/kube-aggregator/go.sum @@ -328,8 +328,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 h1:C7kWARE8r64ppRadl40yfNo6pag+G6ocvGU2xZ6yNes= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f h1:pBCD+Z7cy5WPTq+R6MmJJvDRpn88cp7bmTypBsn91g4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -441,7 +441,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/staging/src/k8s.io/legacy-cloud-providers/go.sum b/staging/src/k8s.io/legacy-cloud-providers/go.sum index 2bf2f3cccf3..404810f63e6 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/go.sum +++ b/staging/src/k8s.io/legacy-cloud-providers/go.sum @@ -301,7 +301,7 @@ github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= @@ -412,7 +412,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/staging/src/k8s.io/sample-apiserver/go.sum b/staging/src/k8s.io/sample-apiserver/go.sum index 36d7b2ba83c..d80906ff6c6 100644 --- a/staging/src/k8s.io/sample-apiserver/go.sum +++ b/staging/src/k8s.io/sample-apiserver/go.sum @@ -325,8 +325,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 h1:C7kWARE8r64ppRadl40yfNo6pag+G6ocvGU2xZ6yNes= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f h1:pBCD+Z7cy5WPTq+R6MmJJvDRpn88cp7bmTypBsn91g4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -438,7 +438,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/vendor/go.etcd.io/etcd/auth/BUILD b/vendor/go.etcd.io/etcd/auth/BUILD index 67b4e7e05a5..1f00bba7213 100644 --- a/vendor/go.etcd.io/etcd/auth/BUILD +++ b/vendor/go.etcd.io/etcd/auth/BUILD @@ -5,6 +5,7 @@ go_library( srcs = [ "doc.go", "jwt.go", + "metrics.go", "nop.go", "options.go", "range_perm_cache.go", @@ -17,6 +18,7 @@ go_library( deps = [ "//vendor/github.com/coreos/pkg/capnslog:go_default_library", "//vendor/github.com/dgrijalva/jwt-go:go_default_library", + "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", "//vendor/go.etcd.io/etcd/auth/authpb:go_default_library", "//vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes:go_default_library", "//vendor/go.etcd.io/etcd/etcdserver/etcdserverpb:go_default_library", diff --git a/vendor/go.etcd.io/etcd/auth/metrics.go b/vendor/go.etcd.io/etcd/auth/metrics.go new file mode 100644 index 00000000000..fe0d28e22d5 --- /dev/null +++ b/vendor/go.etcd.io/etcd/auth/metrics.go @@ -0,0 +1,42 @@ +// Copyright 2015 The etcd Authors +// +// 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 auth + +import ( + "github.com/prometheus/client_golang/prometheus" + "sync" +) + +var ( + currentAuthRevision = prometheus.NewGaugeFunc(prometheus.GaugeOpts{ + Namespace: "etcd_debugging", + Subsystem: "auth", + Name: "revision", + Help: "The current revision of auth store.", + }, + func() float64 { + reportCurrentAuthRevMu.RLock() + defer reportCurrentAuthRevMu.RUnlock() + return reportCurrentAuthRev() + }, + ) + // overridden by auth store initialization + reportCurrentAuthRevMu sync.RWMutex + reportCurrentAuthRev = func() float64 { return 0 } +) + +func init() { + prometheus.MustRegister(currentAuthRevision) +} diff --git a/vendor/go.etcd.io/etcd/auth/store.go b/vendor/go.etcd.io/etcd/auth/store.go index 3c153622934..bf3e474bf80 100644 --- a/vendor/go.etcd.io/etcd/auth/store.go +++ b/vendor/go.etcd.io/etcd/auth/store.go @@ -94,6 +94,9 @@ type AuthenticateParamIndex struct{} // AuthenticateParamSimpleTokenPrefix is used for a key of context in the parameters of Authenticate() type AuthenticateParamSimpleTokenPrefix struct{} +// saveConsistentIndexFunc is used to sync consistentIndex to backend, now reusing store.saveIndex +type saveConsistentIndexFunc func(tx backend.BatchTx) + // AuthStore defines auth storage interface. type AuthStore interface { // AuthEnable turns on the authentication feature @@ -186,6 +189,9 @@ type AuthStore interface { // HasRole checks that user has role HasRole(user, role string) bool + + // SetConsistentIndexSyncer sets consistentIndex syncer + SetConsistentIndexSyncer(syncer saveConsistentIndexFunc) } type TokenProvider interface { @@ -209,10 +215,14 @@ type authStore struct { rangePermCache map[string]*unifiedRangePermissions // username -> unifiedRangePermissions - tokenProvider TokenProvider - bcryptCost int // the algorithm cost / strength for hashing auth passwords + tokenProvider TokenProvider + syncConsistentIndex saveConsistentIndexFunc + bcryptCost int // the algorithm cost / strength for hashing auth passwords } +func (as *authStore) SetConsistentIndexSyncer(syncer saveConsistentIndexFunc) { + as.syncConsistentIndex = syncer +} func (as *authStore) AuthEnable() error { as.enabledMu.Lock() defer as.enabledMu.Unlock() @@ -269,6 +279,7 @@ func (as *authStore) AuthDisable() { tx.Lock() tx.UnsafePut(authBucketName, enableFlagKey, authDisabled) as.commitRevision(tx) + as.saveConsistentIndex(tx) tx.Unlock() b.ForceCommit() @@ -335,17 +346,27 @@ func (as *authStore) CheckPassword(username, password string) (uint64, error) { return 0, ErrAuthNotEnabled } - tx := as.be.BatchTx() - tx.Lock() - defer tx.Unlock() + var user *authpb.User + // CompareHashAndPassword is very expensive, so we use closures + // to avoid putting it in the critical section of the tx lock. + revision, err := func() (uint64, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() - user := getUser(as.lg, tx, username) - if user == nil { - return 0, ErrAuthFailed - } + user = getUser(as.lg, tx, username) + if user == nil { + return 0, ErrAuthFailed + } - if user.Options != nil && user.Options.NoPassword { - return 0, ErrAuthFailed + if user.Options != nil && user.Options.NoPassword { + return 0, ErrAuthFailed + } + + return getRevision(tx), nil + }() + if err != nil { + return 0, err } if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil { @@ -356,7 +377,7 @@ func (as *authStore) CheckPassword(username, password string) (uint64, error) { } return 0, ErrAuthFailed } - return getRevision(tx), nil + return revision, nil } func (as *authStore) Recover(be backend.Backend) { @@ -430,6 +451,7 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, putUser(as.lg, tx, newUser) as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info("added a user", zap.String("user-name", r.Name)) @@ -461,6 +483,7 @@ func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDelete delUser(tx, r.Name) as.commitRevision(tx) + as.saveConsistentIndex(tx) as.invalidateCachedPerm(r.Name) as.tokenProvider.invalidateUser(r.Name) @@ -513,6 +536,7 @@ func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*p putUser(as.lg, tx, updatedUser) as.commitRevision(tx) + as.saveConsistentIndex(tx) as.invalidateCachedPerm(r.Name) as.tokenProvider.invalidateUser(r.Name) @@ -569,6 +593,7 @@ func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUser as.invalidateCachedPerm(r.User) as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info( @@ -655,6 +680,7 @@ func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUs as.invalidateCachedPerm(r.Name) as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info( @@ -729,6 +755,7 @@ func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) as.clearCachedPerm() as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info( @@ -788,6 +815,7 @@ func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDelete } as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info("deleted a role", zap.String("role-name", r.Role)) @@ -818,6 +846,7 @@ func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, putRole(as.lg, tx, newRole) as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info("created a role", zap.String("role-name", r.Name)) @@ -881,6 +910,7 @@ func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) ( as.clearCachedPerm() as.commitRevision(tx) + as.saveConsistentIndex(tx) if as.lg != nil { as.lg.Info( @@ -904,8 +934,21 @@ func (as *authStore) isOpPermitted(userName string, revision uint64, key, rangeE if revision == 0 { return ErrUserEmpty } - - if revision < as.Revision() { + rev := as.Revision() + if revision < rev { + if as.lg != nil { + as.lg.Warn("request auth revision is less than current node auth revision", + zap.Uint64("current node auth revision", rev), + zap.Uint64("request auth revision", revision), + zap.ByteString("request key", key), + zap.Error(ErrAuthOldRevision)) + } else { + plog.Warningf("request auth revision is less than current node auth revision,"+ + "current node auth revision is %d,"+ + "request auth revision is %d,"+ + "request key is %s, "+ + "err is %v", rev, revision, key, ErrAuthOldRevision) + } return ErrAuthOldRevision } @@ -1145,6 +1188,8 @@ func NewAuthStore(lg *zap.Logger, be backend.Backend, tp TokenProvider, bcryptCo as.commitRevision(tx) } + as.setupMetricsReporter() + tx.Unlock() be.ForceCommit() @@ -1419,3 +1464,23 @@ func (as *authStore) HasRole(user, role string) bool { func (as *authStore) BcryptCost() int { return as.bcryptCost } + +func (as *authStore) saveConsistentIndex(tx backend.BatchTx) { + if as.syncConsistentIndex != nil { + as.syncConsistentIndex(tx) + } else { + if as.lg != nil { + as.lg.Error("failed to save consistentIndex,syncConsistentIndex is nil") + } else { + plog.Error("failed to save consistentIndex,syncConsistentIndex is nil") + } + } +} + +func (as *authStore) setupMetricsReporter() { + reportCurrentAuthRevMu.Lock() + reportCurrentAuthRev = func() float64 { + return float64(as.Revision()) + } + reportCurrentAuthRevMu.Unlock() +} diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go index 9e043789c8d..f4b941d6529 100644 --- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go +++ b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go @@ -34,6 +34,6 @@ func (ep *errPicker) String() string { return ep.p.String() } -func (ep *errPicker) Pick(context.Context, balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { +func (ep *errPicker) Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error) { return nil, nil, ep.err } diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go index 1b8b2857378..e3971ecc421 100644 --- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go +++ b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go @@ -52,7 +52,7 @@ type rrBalanced struct { func (rb *rrBalanced) String() string { return rb.p.String() } // Pick is called for every client request. -func (rb *rrBalanced) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { +func (rb *rrBalanced) Pick(ctx context.Context, opts balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error) { rb.mu.RLock() n := len(rb.scs) rb.mu.RUnlock() diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go b/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go index 864b5df6426..2837bd4180b 100644 --- a/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go +++ b/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go @@ -111,7 +111,7 @@ func (e *ResolverGroup) Close() { } // Build creates or reuses an etcd resolver for the etcd cluster name identified by the authority part of the target. -func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) { +func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { if len(target.Authority) < 1 { return nil, fmt.Errorf("'etcd' target scheme requires non-empty authority identifying etcd cluster being routed to") } @@ -179,7 +179,7 @@ func epsToAddrs(eps ...string) (addrs []resolver.Address) { return addrs } -func (*Resolver) ResolveNow(o resolver.ResolveNowOption) {} +func (*Resolver) ResolveNow(o resolver.ResolveNowOptions) {} func (r *Resolver) Close() { es, err := bldr.getResolverGroup(r.endpointID) diff --git a/vendor/go.etcd.io/etcd/clientv3/maintenance.go b/vendor/go.etcd.io/etcd/clientv3/maintenance.go index 744455a3b36..809b8a3b4ba 100644 --- a/vendor/go.etcd.io/etcd/clientv3/maintenance.go +++ b/vendor/go.etcd.io/etcd/clientv3/maintenance.go @@ -20,6 +20,7 @@ import ( "io" pb "go.etcd.io/etcd/etcdserver/etcdserverpb" + "go.uber.org/zap" "google.golang.org/grpc" ) @@ -68,6 +69,7 @@ type Maintenance interface { } type maintenance struct { + lg *zap.Logger dial func(endpoint string) (pb.MaintenanceClient, func(), error) remote pb.MaintenanceClient callOpts []grpc.CallOption @@ -75,6 +77,7 @@ type maintenance struct { func NewMaintenance(c *Client) Maintenance { api := &maintenance{ + lg: c.lg, dial: func(endpoint string) (pb.MaintenanceClient, func(), error) { conn, err := c.Dial(endpoint) if err != nil { @@ -93,6 +96,7 @@ func NewMaintenance(c *Client) Maintenance { func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance { api := &maintenance{ + lg: c.lg, dial: func(string) (pb.MaintenanceClient, func(), error) { return remote, func() {}, nil }, @@ -193,23 +197,32 @@ func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) { return nil, toErr(ctx, err) } + m.lg.Info("opened snapshot stream; downloading") pr, pw := io.Pipe() go func() { for { resp, err := ss.Recv() if err != nil { + switch err { + case io.EOF: + m.lg.Info("completed snapshot read; closing") + default: + m.lg.Warn("failed to receive from snapshot stream; closing", zap.Error(err)) + } pw.CloseWithError(err) return } - if resp == nil && err == nil { - break - } + + // can "resp == nil && err == nil" + // before we receive snapshot SHA digest? + // No, server sends EOF with an empty response + // after it sends SHA digest at the end + if _, werr := pw.Write(resp.Blob); werr != nil { pw.CloseWithError(werr) return } } - pw.Close() }() return &snapshotReadCloser{ctx: ctx, ReadCloser: pr}, nil } diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go index d0e0c81e209..0b05282c04f 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go +++ b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go @@ -239,8 +239,9 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - msgSize := m.Size() - receivedBytes.WithLabelValues(from).Add(float64(msgSize)) + msgSizeVal := m.Size() + msgSize := humanize.Bytes(uint64(msgSizeVal)) + receivedBytes.WithLabelValues(from).Add(float64(msgSizeVal)) if m.Type != raftpb.MsgSnap { if h.lg != nil { @@ -269,11 +270,11 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { zap.String("local-member-id", h.localID.String()), zap.String("remote-snapshot-sender-id", from), zap.Uint64("incoming-snapshot-index", m.Snapshot.Metadata.Index), - zap.Int("incoming-snapshot-message-size-bytes", msgSize), - zap.String("incoming-snapshot-message-size", humanize.Bytes(uint64(msgSize))), + zap.Int("incoming-snapshot-message-size-bytes", msgSizeVal), + zap.String("incoming-snapshot-message-size", msgSize), ) } else { - plog.Infof("receiving database snapshot [index:%d, from %s] ...", m.Snapshot.Metadata.Index, types.ID(m.From)) + plog.Infof("receiving database snapshot [index: %d, from: %s, raft message size: %s]", m.Snapshot.Metadata.Index, types.ID(m.From), msgSize) } // save incoming database snapshot. @@ -296,8 +297,10 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + dbSize := humanize.Bytes(uint64(n)) receivedBytes.WithLabelValues(from).Add(float64(n)) + downloadTook := time.Since(start) if h.lg != nil { h.lg.Info( "received and saved database snapshot", @@ -305,10 +308,11 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { zap.String("remote-snapshot-sender-id", from), zap.Uint64("incoming-snapshot-index", m.Snapshot.Metadata.Index), zap.Int64("incoming-snapshot-size-bytes", n), - zap.String("incoming-snapshot-size", humanize.Bytes(uint64(n))), + zap.String("incoming-snapshot-size", dbSize), + zap.String("download-took", downloadTook.String()), ) } else { - plog.Infof("received and saved database snapshot [index: %d, from: %s] successfully", m.Snapshot.Metadata.Index, types.ID(m.From)) + plog.Infof("successfully received and saved database snapshot [index: %d, from: %s, raft message size: %s, db size: %s, took: %s]", m.Snapshot.Metadata.Index, types.ID(m.From), msgSize, dbSize, downloadTook.String()) } if err := h.r.Process(context.TODO(), m); err != nil { diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go index 62efb0cdc3d..7105de188ae 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go +++ b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go @@ -78,16 +78,18 @@ func (s *snapshotSender) send(merged snap.Message) { u := s.picker.pick() req := createPostRequest(u, RaftSnapshotPrefix, body, "application/octet-stream", s.tr.URLs, s.from, s.cid) + snapshotTotalSizeVal := uint64(merged.TotalSize) + snapshotTotalSize := humanize.Bytes(snapshotTotalSizeVal) if s.tr.Logger != nil { s.tr.Logger.Info( "sending database snapshot", zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index), zap.String("remote-peer-id", to), zap.Int64("bytes", merged.TotalSize), - zap.String("size", humanize.Bytes(uint64(merged.TotalSize))), + zap.String("size", snapshotTotalSize), ) } else { - plog.Infof("start to send database snapshot [index: %d, to %s]...", m.Snapshot.Metadata.Index, types.ID(m.To)) + plog.Infof("start to send database snapshot [index: %d, to %s, size %s]...", m.Snapshot.Metadata.Index, types.ID(m.To), snapshotTotalSize) } snapshotSendInflights.WithLabelValues(to).Inc() @@ -104,7 +106,7 @@ func (s *snapshotSender) send(merged snap.Message) { zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index), zap.String("remote-peer-id", to), zap.Int64("bytes", merged.TotalSize), - zap.String("size", humanize.Bytes(uint64(merged.TotalSize))), + zap.String("size", snapshotTotalSize), zap.Error(err), ) } else { @@ -137,7 +139,7 @@ func (s *snapshotSender) send(merged snap.Message) { zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index), zap.String("remote-peer-id", to), zap.Int64("bytes", merged.TotalSize), - zap.String("size", humanize.Bytes(uint64(merged.TotalSize))), + zap.String("size", snapshotTotalSize), ) } else { plog.Infof("database snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To)) diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/BUILD b/vendor/go.etcd.io/etcd/etcdserver/api/snap/BUILD index 416b9a4fa3b..9b531a5b7cb 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/BUILD +++ b/vendor/go.etcd.io/etcd/etcdserver/api/snap/BUILD @@ -22,6 +22,7 @@ go_library( "//vendor/go.etcd.io/etcd/pkg/pbutil:go_default_library", "//vendor/go.etcd.io/etcd/raft:go_default_library", "//vendor/go.etcd.io/etcd/raft/raftpb:go_default_library", + "//vendor/go.etcd.io/etcd/wal/walpb:go_default_library", "//vendor/go.uber.org/zap:go_default_library", ], ) diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go index 409aed386b6..c5d6d6183c1 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go +++ b/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go @@ -22,16 +22,17 @@ import ( "os" "path/filepath" "sort" + "strconv" "strings" "time" + "github.com/coreos/pkg/capnslog" "go.etcd.io/etcd/etcdserver/api/snap/snappb" pioutil "go.etcd.io/etcd/pkg/ioutil" "go.etcd.io/etcd/pkg/pbutil" "go.etcd.io/etcd/raft" "go.etcd.io/etcd/raft/raftpb" - - "github.com/coreos/pkg/capnslog" + "go.etcd.io/etcd/wal/walpb" "go.uber.org/zap" ) @@ -108,21 +109,37 @@ func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error { return nil } +// Load returns the newest snapshot. func (s *Snapshotter) Load() (*raftpb.Snapshot, error) { + return s.loadMatching(func(*raftpb.Snapshot) bool { return true }) +} + +// LoadNewestAvailable loads the newest snapshot available that is in walSnaps. +func (s *Snapshotter) LoadNewestAvailable(walSnaps []walpb.Snapshot) (*raftpb.Snapshot, error) { + return s.loadMatching(func(snapshot *raftpb.Snapshot) bool { + m := snapshot.Metadata + for i := len(walSnaps) - 1; i >= 0; i-- { + if m.Term == walSnaps[i].Term && m.Index == walSnaps[i].Index { + return true + } + } + return false + }) +} + +// loadMatching returns the newest snapshot where matchFn returns true. +func (s *Snapshotter) loadMatching(matchFn func(*raftpb.Snapshot) bool) (*raftpb.Snapshot, error) { names, err := s.snapNames() if err != nil { return nil, err } var snap *raftpb.Snapshot for _, name := range names { - if snap, err = loadSnap(s.lg, s.dir, name); err == nil { - break + if snap, err = loadSnap(s.lg, s.dir, name); err == nil && matchFn(snap) { + return snap, nil } } - if err != nil { - return nil, ErrNoSnapshot - } - return snap, nil + return nil, ErrNoSnapshot } func loadSnap(lg *zap.Logger, dir, name string) (*raftpb.Snapshot, error) { @@ -226,7 +243,8 @@ func (s *Snapshotter) snapNames() ([]string, error) { if err != nil { return nil, err } - if err = s.cleanupSnapdir(names); err != nil { + names, err = s.cleanupSnapdir(names) + if err != nil { return nil, err } snaps := checkSuffix(s.lg, names) @@ -259,7 +277,7 @@ func checkSuffix(lg *zap.Logger, names []string) []string { // cleanupSnapdir removes any files that should not be in the snapshot directory: // - db.tmp prefixed files that can be orphaned by defragmentation -func (s *Snapshotter) cleanupSnapdir(filenames []string) error { +func (s *Snapshotter) cleanupSnapdir(filenames []string) (names []string, err error) { for _, filename := range filenames { if strings.HasPrefix(filename, "db.tmp") { if s.lg != nil { @@ -268,7 +286,50 @@ func (s *Snapshotter) cleanupSnapdir(filenames []string) error { plog.Infof("found orphaned defragmentation file; deleting: %s", filename) } if rmErr := os.Remove(filepath.Join(s.dir, filename)); rmErr != nil && !os.IsNotExist(rmErr) { - return fmt.Errorf("failed to remove orphaned defragmentation file %s: %v", filename, rmErr) + return nil, fmt.Errorf("failed to remove orphaned .snap.db file %s: %v", filename, rmErr) + } + continue + } + names = append(names, filename) + } + return names, nil +} + +func (s *Snapshotter) ReleaseSnapDBs(snap raftpb.Snapshot) error { + dir, err := os.Open(s.dir) + if err != nil { + return err + } + defer dir.Close() + filenames, err := dir.Readdirnames(-1) + if err != nil { + return err + } + for _, filename := range filenames { + if strings.HasSuffix(filename, ".snap.db") { + hexIndex := strings.TrimSuffix(filepath.Base(filename), ".snap.db") + index, err := strconv.ParseUint(hexIndex, 16, 64) + if err != nil { + if s.lg != nil { + s.lg.Warn("failed to parse index from filename", zap.String("path", filename), zap.String("error", err.Error())) + } else { + plog.Warningf("failed to parse index from filename: %s (%v)", filename, err) + } + continue + } + if index < snap.Metadata.Index { + if s.lg != nil { + s.lg.Warn("found orphaned .snap.db file; deleting", zap.String("path", filename)) + } else { + plog.Warningf("found orphaned .snap.db file; deleting: %s", filename) + } + if rmErr := os.Remove(filepath.Join(s.dir, filename)); rmErr != nil && !os.IsNotExist(rmErr) { + if s.lg != nil { + s.lg.Warn("failed to remove orphaned .snap.db file", zap.String("path", filename), zap.Error(rmErr)) + } else { + plog.Warningf("failed to remove orphaned .snap.db file: %s (%v)", filename, rmErr) + } + } } } } diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/BUILD b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/BUILD index f426496c5fc..923aa7ac85d 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/BUILD +++ b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/BUILD @@ -22,6 +22,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//vendor/github.com/coreos/pkg/capnslog:go_default_library", + "//vendor/github.com/dustin/go-humanize:go_default_library", "//vendor/github.com/gogo/protobuf/proto:go_default_library", "//vendor/github.com/grpc-ecosystem/go-grpc-middleware:go_default_library", "//vendor/github.com/grpc-ecosystem/go-grpc-prometheus:go_default_library", diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go index c51271ac0fe..8130adbf0ab 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go +++ b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go @@ -18,7 +18,9 @@ import ( "context" "crypto/sha256" "io" + "time" + "github.com/dustin/go-humanize" "go.etcd.io/etcd/auth" "go.etcd.io/etcd/etcdserver" "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes" @@ -98,6 +100,9 @@ func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRe return &pb.DefragmentResponse{}, nil } +// big enough size to hold >1 OS pages in the buffer +const snapshotSendBufferSize = 32 * 1024 + func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error { snap := ms.bg.Backend().Snapshot() pr, pw := io.Pipe() @@ -116,19 +121,46 @@ func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance pw.Close() }() - // send file data + // record SHA digest of snapshot data + // used for integrity checks during snapshot restore operation h := sha256.New() - br := int64(0) - buf := make([]byte, 32*1024) - sz := snap.Size() - for br < sz { + + // buffer just holds read bytes from stream + // response size is multiple of OS page size, fetched in boltdb + // e.g. 4*1024 + buf := make([]byte, snapshotSendBufferSize) + + sent := int64(0) + total := snap.Size() + size := humanize.Bytes(uint64(total)) + + start := time.Now() + if ms.lg != nil { + ms.lg.Info("sending database snapshot to client", + zap.Int64("total-bytes", total), + zap.String("size", size), + ) + } else { + plog.Infof("sending database snapshot to client %s [%d bytes]", size, total) + } + for total-sent > 0 { n, err := io.ReadFull(pr, buf) if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { return togRPCError(err) } - br += int64(n) + sent += int64(n) + + // if total is x * snapshotSendBufferSize. it is possible that + // resp.RemainingBytes == 0 + // resp.Blob == zero byte but not nil + // does this make server response sent to client nil in proto + // and client stops receiving from snapshot stream before + // server sends snapshot SHA? + // No, the client will still receive non-nil response + // until server closes the stream with EOF + resp := &pb.SnapshotResponse{ - RemainingBytes: uint64(sz - br), + RemainingBytes: uint64(total - sent), Blob: buf[:n], } if err = srv.Send(resp); err != nil { @@ -137,13 +169,34 @@ func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance h.Write(buf[:n]) } - // send sha + // send SHA digest for integrity checks + // during snapshot restore operation sha := h.Sum(nil) + + if ms.lg != nil { + ms.lg.Info("sending database sha256 checksum to client", + zap.Int64("total-bytes", total), + zap.Int("checksum-size", len(sha)), + ) + } else { + plog.Infof("sending database sha256 checksum to client [%d bytes]", len(sha)) + } + hresp := &pb.SnapshotResponse{RemainingBytes: 0, Blob: sha} if err := srv.Send(hresp); err != nil { return togRPCError(err) } + if ms.lg != nil { + ms.lg.Info("successfully sent database snapshot to client", + zap.Int64("total-bytes", total), + zap.String("size", size), + zap.String("took", humanize.Time(start)), + ) + } else { + plog.Infof("successfully sent database snapshot to client %s [%d bytes]", size, total) + } + return nil } diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go index f41cb6c0569..dcc4cc63700 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go +++ b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go @@ -259,9 +259,10 @@ func (sws *serverWatchStream) recvLoop() error { select { case sws.ctrlStream <- wr: + continue case <-sws.closec: + return nil } - return nil } filters := FiltersFromRequest(creq) diff --git a/vendor/go.etcd.io/etcd/etcdserver/apply.go b/vendor/go.etcd.io/etcd/etcdserver/apply.go index 822b5e32204..d98549dea5b 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/apply.go +++ b/vendor/go.etcd.io/etcd/etcdserver/apply.go @@ -116,6 +116,9 @@ func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResult { ar := &applyResult{} defer func(start time.Time) { warnOfExpensiveRequest(a.s.getLogger(), start, &pb.InternalRaftStringer{Request: r}, ar.resp, ar.err) + if ar.err != nil { + warnOfFailedRequest(a.s.getLogger(), start, &pb.InternalRaftStringer{Request: r}, ar.resp, ar.err) + } }(time.Now()) // call into a.s.applyV3.F instead of a.F so upper appliers can check individual calls diff --git a/vendor/go.etcd.io/etcd/etcdserver/backend.go b/vendor/go.etcd.io/etcd/etcdserver/backend.go index 01ba1925686..3eace1a33c6 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/backend.go +++ b/vendor/go.etcd.io/etcd/etcdserver/backend.go @@ -102,7 +102,7 @@ func openBackend(cfg ServerConfig) backend.Backend { // case, replace the db with the snapshot db sent by the leader. func recoverSnapshotBackend(cfg ServerConfig, oldbe backend.Backend, snapshot raftpb.Snapshot) (backend.Backend, error) { var cIndex consistentIndex - kv := mvcc.New(cfg.Logger, oldbe, &lease.FakeLessor{}, &cIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit}) + kv := mvcc.New(cfg.Logger, oldbe, &lease.FakeLessor{}, nil, &cIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit}) defer kv.Close() if snapshot.Metadata.Index <= kv.ConsistentIndex() { return oldbe, nil diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go index 199ee6244d5..6cbccc797c4 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -104,7 +104,9 @@ var RangeRequest_SortTarget_value = map[string]int32{ func (x RangeRequest_SortTarget) String() string { return proto.EnumName(RangeRequest_SortTarget_name, int32(x)) } -func (RangeRequest_SortTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1, 1} } +func (RangeRequest_SortTarget) EnumDescriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{1, 1} +} type Compare_CompareResult int32 diff --git a/vendor/go.etcd.io/etcd/etcdserver/raft.go b/vendor/go.etcd.io/etcd/etcdserver/raft.go index c0fe9790539..e7cf0729929 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/raft.go +++ b/vendor/go.etcd.io/etcd/etcdserver/raft.go @@ -231,12 +231,26 @@ func (r *raftNode) start(rh *raftReadyHandler) { r.transport.Send(r.processMessages(rd.Messages)) } + // Must save the snapshot file and WAL snapshot entry before saving any other entries or hardstate to + // ensure that recovery after a snapshot restore is possible. + if !raft.IsEmptySnap(rd.Snapshot) { + // gofail: var raftBeforeSaveSnap struct{} + if err := r.storage.SaveSnap(rd.Snapshot); err != nil { + if r.lg != nil { + r.lg.Fatal("failed to save Raft snapshot", zap.Error(err)) + } else { + plog.Fatalf("failed to save Raft snapshot %v", err) + } + } + // gofail: var raftAfterSaveSnap struct{} + } + // gofail: var raftBeforeSave struct{} if err := r.storage.Save(rd.HardState, rd.Entries); err != nil { if r.lg != nil { r.lg.Fatal("failed to save Raft hard state and entries", zap.Error(err)) } else { - plog.Fatalf("raft save state and entries error: %v", err) + plog.Fatalf("failed to save state and entries error: %v", err) } } if !raft.IsEmptyHardState(rd.HardState) { @@ -245,18 +259,22 @@ func (r *raftNode) start(rh *raftReadyHandler) { // gofail: var raftAfterSave struct{} if !raft.IsEmptySnap(rd.Snapshot) { - // gofail: var raftBeforeSaveSnap struct{} - if err := r.storage.SaveSnap(rd.Snapshot); err != nil { + // Force WAL to fsync its hard state before Release() releases + // old data from the WAL. Otherwise could get an error like: + // panic: tocommit(107) is out of range [lastIndex(84)]. Was the raft log corrupted, truncated, or lost? + // See https://github.com/etcd-io/etcd/issues/10219 for more details. + if err := r.storage.Sync(); err != nil { if r.lg != nil { - r.lg.Fatal("failed to save Raft snapshot", zap.Error(err)) + r.lg.Fatal("failed to sync Raft snapshot", zap.Error(err)) } else { - plog.Fatalf("raft save snapshot error: %v", err) + plog.Fatalf("failed to sync Raft snapshot %v", err) } } + // etcdserver now claim the snapshot has been persisted onto the disk notifyc <- struct{}{} - // gofail: var raftAfterSaveSnap struct{} + // gofail: var raftBeforeApplySnap struct{} r.raftStorage.ApplySnapshot(rd.Snapshot) if r.lg != nil { r.lg.Info("applied incoming Raft snapshot", zap.Uint64("snapshot-index", rd.Snapshot.Metadata.Index)) @@ -264,6 +282,15 @@ func (r *raftNode) start(rh *raftReadyHandler) { plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index) } // gofail: var raftAfterApplySnap struct{} + + if err := r.storage.Release(rd.Snapshot); err != nil { + if r.lg != nil { + r.lg.Fatal("failed to release Raft wal", zap.Error(err)) + } else { + plog.Fatalf("failed to release Raft wal %v", err) + } + } + // gofail: var raftAfterWALRelease struct{} } r.raftStorage.Append(rd.Entries) diff --git a/vendor/go.etcd.io/etcd/etcdserver/server.go b/vendor/go.etcd.io/etcd/etcdserver/server.go index 4db1998d6fc..fb98c05b7c6 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/server.go +++ b/vendor/go.etcd.io/etcd/etcdserver/server.go @@ -29,6 +29,10 @@ import ( "sync/atomic" "time" + "github.com/coreos/go-semver/semver" + "github.com/coreos/pkg/capnslog" + humanize "github.com/dustin/go-humanize" + "github.com/prometheus/client_golang/prometheus" "go.etcd.io/etcd/auth" "go.etcd.io/etcd/etcdserver/api" "go.etcd.io/etcd/etcdserver/api/membership" @@ -57,11 +61,6 @@ import ( "go.etcd.io/etcd/raft/raftpb" "go.etcd.io/etcd/version" "go.etcd.io/etcd/wal" - - "github.com/coreos/go-semver/semver" - "github.com/coreos/pkg/capnslog" - humanize "github.com/dustin/go-humanize" - "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" ) @@ -426,10 +425,19 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) { plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir()) } } - snapshot, err = ss.Load() + + // Find a snapshot to start/restart a raft node + walSnaps, serr := wal.ValidSnapshotEntries(cfg.Logger, cfg.WALDir()) + if serr != nil { + return nil, serr + } + // snapshot files can be orphaned if etcd crashes after writing them but before writing the corresponding + // wal log entries + snapshot, err = ss.LoadNewestAvailable(walSnaps) if err != nil && err != snap.ErrNoSnapshot { return nil, err } + if snapshot != nil { if err = st.Recovery(snapshot.Data); err != nil { if cfg.Logger != nil { @@ -540,7 +548,23 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) { CheckpointInterval: cfg.LeaseCheckpointInterval, ExpiredLeasesRetryInterval: srv.Cfg.ReqTimeout(), }) - srv.kv = mvcc.New(srv.getLogger(), srv.be, srv.lessor, &srv.consistIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit}) + + tp, err := auth.NewTokenProvider(cfg.Logger, cfg.AuthToken, + func(index uint64) <-chan struct{} { + return srv.applyWait.Wait(index) + }, + ) + if err != nil { + if cfg.Logger != nil { + cfg.Logger.Warn("failed to create token provider", zap.Error(err)) + } else { + plog.Warningf("failed to create token provider,err is %v", err) + } + return nil, err + } + srv.authStore = auth.NewAuthStore(srv.getLogger(), srv.be, tp, int(cfg.BcryptCost)) + + srv.kv = mvcc.New(srv.getLogger(), srv.be, srv.lessor, srv.authStore, &srv.consistIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit}) if beExist { kvindex := srv.kv.ConsistentIndex() // TODO: remove kvindex != 0 checking when we do not expect users to upgrade @@ -569,20 +593,6 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) { }() srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex()) - tp, err := auth.NewTokenProvider(cfg.Logger, cfg.AuthToken, - func(index uint64) <-chan struct{} { - return srv.applyWait.Wait(index) - }, - ) - if err != nil { - if cfg.Logger != nil { - cfg.Logger.Warn("failed to create token provider", zap.Error(err)) - } else { - plog.Errorf("failed to create token provider: %s", err) - } - return nil, err - } - srv.authStore = auth.NewAuthStore(srv.getLogger(), srv.be, tp, int(cfg.BcryptCost)) if num := cfg.AutoCompactionRetention; num != 0 { srv.compactor, err = v3compactor.New(cfg.Logger, cfg.AutoCompactionMode, num, srv.kv, srv) if err != nil { @@ -2368,8 +2378,7 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { plog.Panicf("unexpected create snapshot error %v", err) } } - // SaveSnap saves the snapshot and releases the locked wal files - // to the snapshot index. + // SaveSnap saves the snapshot to file and appends the corresponding WAL entry. if err = s.r.storage.SaveSnap(snap); err != nil { if lg != nil { lg.Panic("failed to save snapshot", zap.Error(err)) @@ -2385,6 +2394,13 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { } else { plog.Infof("saved snapshot at index %d", snap.Metadata.Index) } + if err = s.r.storage.Release(snap); err != nil { + if lg != nil { + lg.Panic("failed to release wal", zap.Error(err)) + } else { + plog.Panicf("failed to release wal %v", err) + } + } // When sending a snapshot, etcd will pause compaction. // After receives a snapshot, the slow follower needs to get all the entries right after diff --git a/vendor/go.etcd.io/etcd/etcdserver/storage.go b/vendor/go.etcd.io/etcd/etcdserver/storage.go index d57b6f9a58d..9a000b8da66 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/storage.go +++ b/vendor/go.etcd.io/etcd/etcdserver/storage.go @@ -36,6 +36,10 @@ type Storage interface { SaveSnap(snap raftpb.Snapshot) error // Close closes the Storage and performs finalization. Close() error + // Release releases the locked wal files older than the provided snapshot. + Release(snap raftpb.Snapshot) error + // Sync WAL + Sync() error } type storage struct { @@ -47,24 +51,37 @@ func NewStorage(w *wal.WAL, s *snap.Snapshotter) Storage { return &storage{w, s} } -// SaveSnap saves the snapshot to disk and release the locked -// wal files since they will not be used. +// SaveSnap saves the snapshot file to disk and writes the WAL snapshot entry. func (st *storage) SaveSnap(snap raftpb.Snapshot) error { walsnap := walpb.Snapshot{ Index: snap.Metadata.Index, Term: snap.Metadata.Term, } - err := st.WAL.SaveSnapshot(walsnap) + // save the snapshot file before writing the snapshot to the wal. + // This makes it possible for the snapshot file to become orphaned, but prevents + // a WAL snapshot entry from having no corresponding snapshot file. + err := st.Snapshotter.SaveSnap(snap) if err != nil { return err } - err = st.Snapshotter.SaveSnap(snap) - if err != nil { - return err - } - return st.WAL.ReleaseLockTo(snap.Metadata.Index) + // gofail: var raftBeforeWALSaveSnaphot struct{} + + return st.WAL.SaveSnapshot(walsnap) } +// Release releases resources older than the given snap and are no longer needed: +// - releases the locks to the wal files that are older than the provided wal for the given snap. +// - deletes any .snap.db files that are older than the given snap. +func (st *storage) Release(snap raftpb.Snapshot) error { + if err := st.WAL.ReleaseLockTo(snap.Metadata.Index); err != nil { + return err + } + return st.Snapshotter.ReleaseSnapDBs(snap) +} + +// readWAL reads the WAL at the given snap and returns the wal, its latest HardState and cluster ID, and all entries that appear +// after the position of the given snap in the WAL. +// The snap must have been previously saved to the WAL, or this call will panic. func readWAL(lg *zap.Logger, waldir string, snap walpb.Snapshot) (w *wal.WAL, id, cid types.ID, st raftpb.HardState, ents []raftpb.Entry) { var ( err error diff --git a/vendor/go.etcd.io/etcd/etcdserver/util.go b/vendor/go.etcd.io/etcd/etcdserver/util.go index fe5024ef00d..ece1c2ce086 100644 --- a/vendor/go.etcd.io/etcd/etcdserver/util.go +++ b/vendor/go.etcd.io/etcd/etcdserver/util.go @@ -111,6 +111,25 @@ func warnOfExpensiveRequest(lg *zap.Logger, now time.Time, reqStringer fmt.Strin warnOfExpensiveGenericRequest(lg, now, reqStringer, "", resp, err) } +func warnOfFailedRequest(lg *zap.Logger, now time.Time, reqStringer fmt.Stringer, respMsg proto.Message, err error) { + var resp string + if !isNil(respMsg) { + resp = fmt.Sprintf("size:%d", proto.Size(respMsg)) + } + d := time.Since(now) + if lg != nil { + lg.Warn( + "failed to apply request", + zap.Duration("took", d), + zap.String("request", reqStringer.String()), + zap.String("response", resp), + zap.Error(err), + ) + } else { + plog.Warningf("failed to apply request %q with response %q took (%v) to execute, err is %v", reqStringer.String(), resp, d, err) + } +} + func warnOfExpensiveReadOnlyTxnRequest(lg *zap.Logger, now time.Time, r *pb.TxnRequest, txnResponse *pb.TxnResponse, err error) { reqStringer := pb.NewLoggableTxnRequest(r) var resp string diff --git a/vendor/go.etcd.io/etcd/mvcc/BUILD b/vendor/go.etcd.io/etcd/mvcc/BUILD index 2a6148405ea..b92a07f6edd 100644 --- a/vendor/go.etcd.io/etcd/mvcc/BUILD +++ b/vendor/go.etcd.io/etcd/mvcc/BUILD @@ -27,6 +27,7 @@ go_library( "//vendor/github.com/coreos/pkg/capnslog:go_default_library", "//vendor/github.com/google/btree:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", + "//vendor/go.etcd.io/etcd/auth:go_default_library", "//vendor/go.etcd.io/etcd/lease:go_default_library", "//vendor/go.etcd.io/etcd/mvcc/backend:go_default_library", "//vendor/go.etcd.io/etcd/mvcc/mvccpb:go_default_library", diff --git a/vendor/go.etcd.io/etcd/mvcc/kvstore.go b/vendor/go.etcd.io/etcd/mvcc/kvstore.go index 997aaaf562c..6752038083a 100644 --- a/vendor/go.etcd.io/etcd/mvcc/kvstore.go +++ b/vendor/go.etcd.io/etcd/mvcc/kvstore.go @@ -163,14 +163,18 @@ func NewStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentI func (s *store) compactBarrier(ctx context.Context, ch chan struct{}) { if ctx == nil || ctx.Err() != nil { - s.mu.Lock() select { case <-s.stopc: default: + // fix deadlock in mvcc,for more information, please refer to pr 11817. + // s.stopc is only updated in restore operation, which is called by apply + // snapshot call, compaction and apply snapshot requests are serialized by + // raft, and do not happen at the same time. + s.mu.Lock() f := func(ctx context.Context) { s.compactBarrier(ctx, ch) } s.fifoSched.Schedule(f) + s.mu.Unlock() } - s.mu.Unlock() return } close(ch) diff --git a/vendor/go.etcd.io/etcd/mvcc/watchable_store.go b/vendor/go.etcd.io/etcd/mvcc/watchable_store.go index a51e5aa529b..72c6b8be4ba 100644 --- a/vendor/go.etcd.io/etcd/mvcc/watchable_store.go +++ b/vendor/go.etcd.io/etcd/mvcc/watchable_store.go @@ -15,6 +15,7 @@ package mvcc import ( + "go.etcd.io/etcd/auth" "sync" "time" @@ -69,11 +70,11 @@ type watchableStore struct { // cancel operations. type cancelFunc func() -func New(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter, cfg StoreConfig) ConsistentWatchableKV { - return newWatchableStore(lg, b, le, ig, cfg) +func New(lg *zap.Logger, b backend.Backend, le lease.Lessor, as auth.AuthStore, ig ConsistentIndexGetter, cfg StoreConfig) ConsistentWatchableKV { + return newWatchableStore(lg, b, le, as, ig, cfg) } -func newWatchableStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter, cfg StoreConfig) *watchableStore { +func newWatchableStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, as auth.AuthStore, ig ConsistentIndexGetter, cfg StoreConfig) *watchableStore { s := &watchableStore{ store: NewStore(lg, b, le, ig, cfg), victimc: make(chan struct{}, 1), @@ -87,6 +88,10 @@ func newWatchableStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig Co // use this store as the deleter so revokes trigger watch events s.le.SetRangeDeleter(func() lease.TxnDelete { return s.Write(traceutil.TODO()) }) } + if as != nil { + // TODO: encapsulating consistentindex into a separate package + as.SetConsistentIndexSyncer(s.store.saveIndex) + } s.wg.Add(2) go s.syncWatchersLoop() go s.syncVictimsLoop() diff --git a/vendor/go.etcd.io/etcd/version/version.go b/vendor/go.etcd.io/etcd/version/version.go index c2960bdd0de..ce2acaef1d6 100644 --- a/vendor/go.etcd.io/etcd/version/version.go +++ b/vendor/go.etcd.io/etcd/version/version.go @@ -26,7 +26,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "3.0.0" - Version = "3.4.7" + Version = "3.4.9" APIVersion = "unknown" // Git SHA Value will be set during build diff --git a/vendor/go.etcd.io/etcd/wal/wal.go b/vendor/go.etcd.io/etcd/wal/wal.go index f5aff3f1bc1..0451f94d058 100644 --- a/vendor/go.etcd.io/etcd/wal/wal.go +++ b/vendor/go.etcd.io/etcd/wal/wal.go @@ -532,6 +532,71 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. return metadata, state, ents, err } +// ValidSnapshotEntries returns all the valid snapshot entries in the wal logs in the given directory. +// Snapshot entries are valid if their index is less than or equal to the most recent committed hardstate. +func ValidSnapshotEntries(lg *zap.Logger, walDir string) ([]walpb.Snapshot, error) { + var snaps []walpb.Snapshot + var state raftpb.HardState + var err error + + rec := &walpb.Record{} + names, err := readWALNames(lg, walDir) + if err != nil { + return nil, err + } + + // open wal files in read mode, so that there is no conflict + // when the same WAL is opened elsewhere in write mode + rs, _, closer, err := openWALFiles(lg, walDir, names, 0, false) + if err != nil { + return nil, err + } + defer func() { + if closer != nil { + closer() + } + }() + + // create a new decoder from the readers on the WAL files + decoder := newDecoder(rs...) + + for err = decoder.decode(rec); err == nil; err = decoder.decode(rec) { + switch rec.Type { + case snapshotType: + var loadedSnap walpb.Snapshot + pbutil.MustUnmarshal(&loadedSnap, rec.Data) + snaps = append(snaps, loadedSnap) + case stateType: + state = mustUnmarshalState(rec.Data) + case crcType: + crc := decoder.crc.Sum32() + // current crc of decoder must match the crc of the record. + // do no need to match 0 crc, since the decoder is a new one at this case. + if crc != 0 && rec.Validate(crc) != nil { + return nil, ErrCRCMismatch + } + decoder.updateCRC(rec.Crc) + } + } + // We do not have to read out all the WAL entries + // as the decoder is opened in read mode. + if err != io.EOF && err != io.ErrUnexpectedEOF { + return nil, err + } + + // filter out any snaps that are newer than the committed hardstate + n := 0 + for _, s := range snaps { + if s.Index <= state.Commit { + snaps[n] = s + n++ + } + } + snaps = snaps[:n:n] + + return snaps, nil +} + // Verify reads through the given WAL and verifies that it is not corrupted. // It creates a new decoder to read through the records of the given WAL. // It does not conflict with any open WAL, but it is recommended not to @@ -728,6 +793,10 @@ func (w *WAL) sync() error { return err } +func (w *WAL) Sync() error { + return w.sync() +} + // ReleaseLockTo releases the locks, which has smaller index than the given index // except the largest one among them. // For example, if WAL is holding lock 1,2,3,4,5,6, ReleaseLockTo(4) will release diff --git a/vendor/modules.txt b/vendor/modules.txt index 9209bcb18aa..2be4490840a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -717,7 +717,7 @@ github.com/vmware/govmomi/vim25/xml github.com/xiang90/probing # go.etcd.io/bbolt v1.3.3 => go.etcd.io/bbolt v1.3.3 go.etcd.io/bbolt -# go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 => go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 +# go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f => go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f go.etcd.io/etcd/auth go.etcd.io/etcd/auth/authpb go.etcd.io/etcd/client