Compare commits

...

875 Commits

Author SHA1 Message Date
Benjamin Wang f84fb66cbe
Merge pull request #20324 from hwdef/changelog-35-34-go12311
CHANGELOG(3.4,3.5): Add Go 1.23.11 note
2025-07-11 10:39:50 +01:00
Benjamin Wang 8ff509c137
Merge pull request #20323 from jmhbnz/changelog
Update changelog and instructions following v3.6.2 release
2025-07-11 09:44:35 +01:00
Marek Siarkowicz 24b5ac7f90
Merge pull request #20317 from joshjms/antithesis-add-etcd-server-config
[Antithesis] Add randomization of etcd server configurations
2025-07-10 21:22:58 +02:00
joshjms 045930b783 antithesis: Add etcd server configs
Add the small values for ETCD_SNAPSHOT_CATCHUP_ENTRIES, ETCD_SNAPSHOT_COUNT, and ETCD_COMPACTION_BATCH_LIMIT for etcd servers in Antithesis.

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-07-11 02:22:48 +08:00
Fu Wei 4c46235bb8
Merge pull request #20325 from AwesomePatrol/add-otel-spans-to-range-and-txn
Add OpenTelemetry Spans to Range and Txn
2025-07-10 13:39:43 -04:00
Aleksander Mistewicz bf5f9af3ee Update tracing integration tests to verify creation of new Spans
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-10 15:33:43 +02:00
Aleksander Mistewicz a291faad71 Add OTEL tracing to Range and Txn
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-10 15:33:43 +02:00
hwdef fb303a8360 CHANGELOG(3.4,3.5): Add Go 1.23.11 note
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-07-10 17:24:12 +08:00
James Blair a8a97a5d9c
Correct instructions for GitHub release checkboxes.
Signed-off-by: James Blair <mail@jamesblair.net>
2025-07-10 20:59:23 +12:00
James Blair b8693fb17a
Add release date for v3.6.2 to CHANGELOG-3.6.md.
Signed-off-by: James Blair <mail@jamesblair.net>
2025-07-10 20:58:23 +12:00
Benjamin Wang 5af30121bf
Merge pull request #20308 from ArkaSaha30/deps_mgmt_7_07_25
[2025-07-07] Manual Dependency Bump
2025-07-10 09:42:42 +01:00
Benjamin Wang 87172a157e
Merge pull request #20319 from ivanvc/changelog-3.6-go-1.23.11
CHANGELOG(3.6): Go 1.23.11 entry
2025-07-10 09:13:32 +01:00
Ivan Valdes 40f4ea8c48
CHANGELOG(3.6): Go 1.23.11 entry
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-07-09 21:17:22 -10:00
Marek Siarkowicz e53bad4fdc
Merge pull request #20310 from apullo777/fix-waitgroup
cache: fix waitGroup goroutine registration
2025-07-09 17:25:31 +02:00
Peter Chang 625333c8bd cache: fix waitGroup goroutine registration
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-09 11:45:44 +00:00
Marek Siarkowicz 233021b2d7
Merge pull request #20274 from apullo777/fix-atomic-watch
cache: batch events with identical revision into one watch response
2025-07-08 16:23:39 +02:00
Peter Chang 5dde6104e0 cache: batch events with identical revision into one watch response
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-08 13:41:21 +00:00
Fu Wei 2f5a091512
Merge pull request #20309 from AwesomePatrol/move-ensure-trace-to-utiltracing
Move EnsureTrace to traceutil
2025-07-08 08:32:58 -04:00
ArkaSaha30 e8090a2c73
dependency: bump sigs.k8s.io/yaml from 1.4.0 to 1.5.0
This commit will bump sigs.k8s.io/yaml from 1.4.0 to 1.5.0
Also, add indirect dependency of go.yaml.in/yaml/v2@v2.4.2

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-08 17:19:12 +05:30
ArkaSaha30 2356ac2b8b
dependency: bump github.com/olekukonko/tablewriter from 1.0.7 to 1.0.8
This commit will bump github.com/olekukonko/tablewriter from 1.0.7 to 1.0.8

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-08 16:02:20 +05:30
ArkaSaha30 4993175bf2
dependency: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc from 1.36.0 to 1.37.0
This commit will bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc from 1.36.0 to 1.37.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-08 15:47:41 +05:30
Marek Siarkowicz 4e3e13eac9
Merge pull request #20296 from AwesomePatrol/fix-genproto-import-in-cache
Fix wrong import of google.golang.org/genproto in cache module
2025-07-08 12:11:30 +02:00
Aleksander Mistewicz 798c983dd8 Make traceutil.New private as traceutil.EnsureTrace is a better option
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-08 12:08:24 +02:00
Aleksander Mistewicz ea627c79e2 Use traceutil.EnsureTrace instead of traceutil.New
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-08 12:08:24 +02:00
Aleksander Mistewicz a110ee35b8 Move ensureTrace to traceutil package
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-08 11:59:02 +02:00
Aleksander Mistewicz e3e5a84307 Fix wrong import of google.golang.org/genproto in cache module
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-08 11:28:59 +02:00
Marek Siarkowicz 02a4c53e59
Merge pull request #20297 from apullo777/move-integration-tests
cache: refactor cache_test.go (cache/ -> tests/integration/)
2025-07-08 11:07:33 +02:00
Peter Chang 033b9e270d cache: refactor cache_test.go (cache/ -> tests/integration/)
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-08 10:25:23 +02:00
Marek Siarkowicz 3fbf1bbf51
Merge pull request #20305 from AwesomePatrol/fix-yamllint-errors
Fix yamllint errors
2025-07-08 10:10:33 +02:00
Aleksander Mistewicz 61c62abc54 Fix yamllint errors
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-08 09:49:12 +02:00
Marek Siarkowicz 075509c848
Merge pull request #20295 from serathius/document-20221
Document #20221 in robustness track record
2025-07-07 14:14:16 +02:00
Marek Siarkowicz a93551f8b2
Merge pull request #20181 from AwesomePatrol/test-for-contract-usage
Add Kubernetes API coverage test consuming traces
2025-07-07 13:51:27 +02:00
Aleksander Mistewicz 587388fb3d Print call stats for API coverage test in a nice table
Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-07 13:44:05 +02:00
Marek Siarkowicz 0d66443de9 Document #20221 in robustness track record
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-07-07 13:31:44 +02:00
Marek Siarkowicz 85b7dd4693
Merge pull request #20292 from serathius/flakes
Prevent flakes with TestWatchRestore
2025-07-07 12:17:25 +02:00
Marek Siarkowicz 9671fb369c Prevent flakes with TestWatchRestore
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-07-07 11:24:24 +02:00
Aleksander Mistewicz dc7d95e243 Split test into subtests by method name
It makes it easier to know what methods were used from the tests
outputs.

Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-07 10:10:01 +02:00
Aleksander Mistewicz b883f0dd11 Use already imported library instead
All tools needed to process traces are already available in etcd/tests.

Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-07 10:10:01 +02:00
Aleksander Mistewicz f1a6777ec1 Add Kubernetes API coverage test consuming traces
It pulls a file from testdata with traces collected by Jaeger and then
iterates over them in order to group them by Etcd gRPC method used.

Signed-off-by: Aleksander Mistewicz <amistewicz@google.com>
2025-07-07 10:10:01 +02:00
James Blair fe91daaf83
Merge pull request #20287 from ivanvc/changelog-3.6-bbolt-1.4.2
CHANGELOG(3.6): Add bbolt 1.4.2 entry
2025-07-06 21:05:02 +12:00
Ivan Valdes e4176d9859
CHANGELOG(3.6): Add bbolt 1.4.2 entry
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-07-05 23:21:18 -07:00
Marek Siarkowicz f10ebf6f9d
Merge pull request #20285 from apullo777/remove-afterRev
cache: remove AfterRev entry predicate
2025-07-05 00:21:15 +02:00
Marek Siarkowicz 26c08aab1f
Merge pull request #20284 from apullo777/rename-peekLatest
cache: refactor PeekLatest/PeekOldest
2025-07-04 23:32:34 +02:00
Peter Chang 345f4f895c cache: remove AfterRev entry predicate
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-04 20:58:36 +00:00
Peter Chang aea7741e19 cache: refactor PeekLatest/PeekOldest
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-04 20:38:51 +00:00
Marek Siarkowicz 9fb8c3685f
Merge pull request #20281 from serathius/watch-restore-future
Avoid lowering revision of watchers in the future after restore
2025-07-04 17:32:23 +02:00
Marek Siarkowicz cf0369e4ad Avoid lowering revision of watchers in the future after restore
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-07-04 15:09:46 +02:00
Benjamin Wang 44a094a20a
Merge pull request #19988 from ahrtr/review_policy_20250520
Add review policy
2025-07-04 10:40:59 +01:00
Marek Siarkowicz 866bc0717c
Merge pull request #20160 from apullo777/cache-mvp
cache: implement MVP watch demux
2025-07-03 13:53:56 +02:00
Peter Chang 2c311cc948 cache: implement MVP watch demux
Signed-off-by: Peter Chang <peter.yaochen.chang@gmail.com>
2025-07-03 13:03:43 +02:00
Benjamin Wang 4b9846924e
Merge pull request #20261 from ArkaSaha30/deps_mgmt_30_06_25
[2025-06-30] Manual Dependency Bump
2025-07-03 10:43:52 +01:00
Marek Siarkowicz a15cd5e0ac
Merge pull request #20141 from joshjms/antithesis-config-dir
Move docker-compose.yml and Dockerfile.config to config directory
2025-07-03 09:24:06 +02:00
Benjamin Wang 721ba5bc24
Merge pull request #20266 from Elbehery/20250702_remove_existFileOrDir_func
chore(client): remove existFileOrDir funce
2025-07-02 18:29:43 +01:00
Benjamin Wang 2e242a63fb
Merge pull request #20248 from Elbehery/20250630_etcdutl_remove_readme
chore(tools): Mark etcd-dump-db as deprecated
2025-07-02 15:34:19 +01:00
Mustafa Elbehery 046b064728 chore(tools): Mark etcd-dump-db as deprecated
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-07-02 15:23:05 +02:00
Mustafa Elbehery e4bf5e0ba7 chore(client): remove existFileOrDir func
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-07-02 13:13:37 +02:00
Benjamin Wang df8d67ae82
Merge pull request #20244 from ahrtr/20250630_etcdutl_iterate_bucket
Migrate the etcd-dump-db commands into etcdutl
2025-07-02 10:17:02 +01:00
ArkaSaha30 361312435e
dependency: bump go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc from 0.61.0 to 0.62.0
This commit will bump go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc from 0.61.0 to 0.62.0
Also, bumps go.opentelemetry.io/otel/metric from 1.36.0 to 1.37.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-02 11:17:52 +05:30
joshjms 763a5fd3c1 antithesis: Move docker compose yml files and config Dockerfile to config directory
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-07-02 08:54:35 +08:00
Benjamin Wang 7a79b05f7d Migrate etcd-dump-db commands into etcdutl
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-07-01 12:49:19 +01:00
ArkaSaha30 9092857864
dependency: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace from 1.36.0 to 1.37.0
This commit will bump go.opentelemetry.io/otel/exporters/otlp/otlptrace from 1.36.0 to 1.37.0
Also bumps indirect dependency,
- github.com/go-logr/logr v1.4.2 to v1.4.3

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-01 15:30:48 +05:30
ArkaSaha30 6792656b74
dependency: bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.26.3 to 2.27.1
This commit will bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.26.3 to 2.27.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-01 15:27:29 +05:30
James Blair eabcedf785
Merge pull request #20251 from etcd-io/dependabot/github_actions/github/codeql-action-3.29.2
build(deps): bump github/codeql-action from 3.29.0 to 3.29.2
2025-07-01 21:54:46 +12:00
ArkaSaha30 39fb26d031
dependency: bump github.com/google/yamlfmt from 0.17.0 to 0.17.2
This commit will bump github.com/google/yamlfmt from 0.17.0 to 0.17.2

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-01 15:21:18 +05:30
ArkaSaha30 3ea0a5e4ff
dependency: bump github.com/alexfalkowski/gocovmerge from 1.9.0 to 1.11.0
This commit will bump github.com/alexfalkowski/gocovmerge from 1.9.0 to 1.11.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-07-01 15:13:33 +05:30
Benjamin Wang 0199ccabe0
Merge pull request #19469 from kstrifonoff/fix-hex-json-printer
etcdctl: fix json output
2025-07-01 09:34:41 +01:00
dependabot[bot] 36d8f5465f
build(deps): bump github/codeql-action from 3.29.0 to 3.29.2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.29.0 to 3.29.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](ce28f5bb42...181d5eefc2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 20:21:16 +00:00
James Blair d5537ec250
Merge pull request #20237 from ArkaSaha30/deps_mgmt_23_06_25
[2025-06-23] Manual Dependency Bump
2025-07-01 08:04:26 +12:00
Marek Siarkowicz 674260e85d
Merge pull request #20240 from serathius/robustness-progress
Disable progress notify validation until we can guarantee response
2025-06-30 15:33:48 +02:00
Marek Siarkowicz b51415c3f6 Disable progress notify validation until we can guarantee response
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-30 12:07:44 +02:00
Kirill Trifonov b42b5f9d32 add new method
minor refactoring
add unit tests

Signed-off-by: Kirill Trifonov <kstrifonoff@gmail.com>
2025-06-29 07:44:11 +02:00
ArkaSaha30 ab2cb8dcdb
dependency: bump go.etcd.io/bbolt from v1.4.1 to v1.4.2
This commit will bump go.etcd.io/bbolt from v1.4.1 to v1.4.2

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 01:37:55 +05:30
ArkaSaha30 c9e373db43
dependency: bump github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus from 1.0.1 to 1.1.0
This commit will bump github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus from 1.0.1 to 1.1.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 01:37:54 +05:30
ArkaSaha30 b013138901
depenendcy: bump github.com/prometheus/common from 0.64.0 to 0.65.0
This commit will bump github.com/prometheus/common from 0.64.0 to 0.65.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 01:37:54 +05:30
ArkaSaha30 d80924d3af
dependency: bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.26.3 to 2.27.0
This commit will bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.26.3 to 2.27.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 01:36:42 +05:30
ArkaSaha30 3773a3b064
dependency: bump gotest.tools/gotestsum from 1.12.2 to 1.12.3
This commit will bump gotest.tools/gotestsum from 1.12.2 to 1.12.3

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 00:48:03 +05:30
Benjamin Wang d744c19762
Merge pull request #20225 from ahrtr/20250625_watch_verify
Add verification to verify the watch response have a bigger revision than minRev
2025-06-27 20:15:55 +01:00
ArkaSaha30 ee6d86f9b3
dependency: bump github.com/google/yamlfmt from 0.17.0 to 0.17.1
This commit will bump github.com/google/yamlfmt from 0.17.0 to 0.17.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-28 00:24:06 +05:30
Fu Wei 762582c48c
Merge pull request #20195 from serathius/robustness-split-step
Split model Step function
2025-06-27 10:36:19 -04:00
Fu Wei e08120e696
Merge pull request #20196 from serathius/robustness-split-model
Split model types into types.go file
2025-06-27 10:18:09 -04:00
Benjamin Wang 015d7c5704 Add verification to verify the watch response have a bigger revision than minRev
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-27 12:51:03 +01:00
Marek Siarkowicz 1a2efc3c47
Merge pull request #20229 from serathius/skip-future-progress-notification
Skip sending progress notification for watch with starting revision in the future
2025-06-27 12:12:03 +02:00
Marek Siarkowicz 973847aa24 Skip sending progress notification for watch with starting revision in the future
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-27 10:01:16 +02:00
Fu Wei bc47e77116
Merge pull request #20194 from serathius/robustness-visualize-non-linearizable
Add non-linearizable requests to visualization
2025-06-26 14:53:14 -04:00
Marek Siarkowicz 795cca9bc3
Merge pull request #20226 from serathius/antithesis-fix-working-dir
Fix working dir for building antithesis client image
2025-06-26 11:17:38 +02:00
Marek Siarkowicz 084394a17a Fix working dir for building antithesis client image
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-26 10:25:00 +02:00
Marek Siarkowicz a8c4903b70
Merge pull request #20219 from joshjms/antithesis-single-node-config
[Antithesis] Fix building the client image
2025-06-26 08:46:26 +02:00
joshjms b3b0fdc513 .github/workflows: Add CFG_NODE_COUNT env for build-and-push-and-test job
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-06-26 13:44:17 +08:00
James Blair dc7fe2a94e
Merge pull request #20203 from jmhbnz/main
Update etcd OWNERS
2025-06-26 07:20:54 +12:00
James Blair 9e4c432bb0
Merge pull request #20215 from ahrtr/20250624_security
Use security@etcd.io to receive any CVE report
2025-06-25 09:08:32 +12:00
Marek Siarkowicz fd8d737838
Merge pull request #20216 from joshjms/antithesis-single-node-config
Add single node cluster config to Antithesis tests in Github Actions
2025-06-24 22:43:40 +02:00
joshjms 6f8ef3cc30 .github/workflows: Add CFG_NODE_COUNT env for build-and-push-and-test job
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-06-24 23:15:50 +08:00
Marek Siarkowicz c6804c8d8c
Merge pull request #20173 from nwnt/nwnt/add-client-connecting-all
Refactor and add connect all client
2025-06-24 16:39:09 +02:00
Marek Siarkowicz cc240d6c08
Merge pull request #20151 from kishen-v/benchmark-perfdash
Add support to generate JSON report to the benchmark tool
2025-06-24 16:37:40 +02:00
Kishen Viswanathan 955f94cf65 Address review comments
Signed-off-by: Kishen Viswanathan <kishen.viswanathan@ibm.com>
2025-06-24 19:19:09 +05:30
Nont 500642c0b6 Add connect all client
Signed-off-by: Nont <nont@duck.com>
2025-06-24 07:50:23 -05:00
Benjamin Wang 0458e119a7 Use security@etcd.io to receive any CVE report
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-24 11:49:24 +01:00
James Blair fb7e3f2460
Merge pull request #20208 from etcd-io/dependabot/docker/distroless/static-debian12-b7b9a6953e7bed6baaf37329331051d7bdc1b99c885f6dbeb72d75b1baad54f9
build(deps): bump distroless/static-debian12 from `d9f9472` to `b7b9a69`
2025-06-24 10:22:15 +12:00
dependabot[bot] 3dfa3e3b5a
build(deps): bump distroless/static-debian12 from `d9f9472` to `b7b9a69`
Bumps distroless/static-debian12 from `d9f9472` to `b7b9a69`.

---
updated-dependencies:
- dependency-name: distroless/static-debian12
  dependency-version: b7b9a6953e7bed6baaf37329331051d7bdc1b99c885f6dbeb72d75b1baad54f9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-23 18:52:10 +00:00
James Blair 33a458068d
Update etcd OWNERS.
- Adopt emeritus_approvers in OWNERS.
- Move wenjiaswe to emeritus.

Signed-off-by: James Blair <mail@jamesblair.net>
2025-06-23 20:13:20 +12:00
Marek Siarkowicz 32eeee612e
Merge pull request #20175 from nwnt/nwnt/refactor-recording-client-mgmt
Refactor recording client management
2025-06-23 09:35:20 +02:00
Nont ae8a57fb76 Refactor recording client management
Signed-off-by: Nont <nont@duck.com>
2025-06-22 10:19:54 -05:00
Benjamin Wang 511f795e1b
Merge pull request #20185 from xiaoxiangirl/main
refactor: use slices.Contains to simplify code
2025-06-22 15:03:00 +01:00
James Blair 4cd8c08e6e
Merge pull request #19976 from joshjms/dry-run-release-docs
Add dry run instruction for release
2025-06-22 18:07:56 +12:00
Marek Siarkowicz 87a2ed37ab Split model Step function
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-20 13:06:33 +02:00
Marek Siarkowicz 2129bbf9e9 Split model types into types.go file
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-20 13:02:46 +02:00
Marek Siarkowicz f4ecf54482
Merge pull request #20193 from serathius/robustness-future-rev
Treat future revision as client error
2025-06-20 12:43:22 +02:00
Marek Siarkowicz eab99c53bf Add non-linearizable requests to visualization
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-20 12:07:53 +02:00
Marek Siarkowicz 86fa2e0991
Merge pull request #20176 from joshjms/antithesis-config-cluster-size-1
[Antithesis] Configuration for 1 node cluster
2025-06-19 17:55:53 +02:00
Marek Siarkowicz be6e482948 Treat future revision as client error
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-19 17:39:36 +02:00
xiaoxiangirl 745f31c12d refactor: use slices.Contains to simplify code
Signed-off-by: xiaoxiangirl <caojiaqiao@outlook.com>
2025-06-18 17:13:29 +08:00
James Blair 5dfd6e05a4
Merge pull request #20179 from Elbehery/20250617-add-gci-formatter
chore(CI): add gci formatter
2025-06-18 21:01:09 +12:00
joshjms d4a1798487 antithesis: Configuration for 1 node cluster
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-06-17 21:50:55 +08:00
Mustafa Elbehery b64a02a5a5 chore(CI): add gci formatter
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-06-17 14:01:59 +02:00
Benjamin Wang 52ce705dc7
Merge pull request #20178 from etcd-io/dependabot/github_actions/github/codeql-action-3.29.0
build(deps): bump github/codeql-action from 3.28.19 to 3.29.0
2025-06-17 09:36:18 +01:00
Benjamin Wang fba53f1034
Merge pull request #20177 from kstrifonoff/refactor/json-printer-writer
etcdctl: refactor json printing to support custom writers
2025-06-16 21:02:55 +01:00
dependabot[bot] 88d7e777f8
build(deps): bump github/codeql-action from 3.28.19 to 3.29.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.19 to 3.29.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fca7ace96b...ce28f5bb42)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-16 18:25:18 +00:00
Kirill Trifonov e6be3f3723 * add writer to printer
Signed-off-by: Kirill Trifonov <kstrifonoff@gmail.com>
2025-06-16 00:18:08 +02:00
James Blair c68e3f4275
Merge pull request #20174 from hwdef/changelog-35-36-go12310
CHANGELOG(3.4,3.5): Add Go 1.23.10 note
2025-06-16 08:47:56 +12:00
Marek Siarkowicz db4dfbde2b
Merge pull request #20169 from nwnt/nwnt/persist-expect-uniquerevision
Make Report Persist Traffic Detail
2025-06-15 12:53:21 +02:00
hwdef d61b803d3b CHANGELOG(3.4,3.5): Add Go 1.23.10 note
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-06-15 17:19:21 +08:00
Nont 4f2ede9638 Make Report Persist Traffic Detail
Signed-off-by: Nont <nont@duck.com>
2025-06-13 22:59:18 -05:00
Marek Siarkowicz d37ff81bbb
Merge pull request #20161 from serathius/antithesis-remove-defrag
Remove defragment requests from linearization
2025-06-12 21:01:08 +02:00
Benjamin Wang b6a4e35319
Merge pull request #20163 from hwdef/bump-go-1244
[main] Bump Go to 1.24.4
2025-06-12 11:09:15 +01:00
Benjamin Wang 9bc99b1634
Merge pull request #20033 from ahrtr/20250527_transparency
Update the Decision-making process and transparency
2025-06-12 11:05:47 +01:00
hwdef cc29bc0391 chore(main): Bump Go to 1.24.4
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-06-12 16:09:38 +08:00
Marek Siarkowicz 2e3c87e413
Merge pull request #20149 from nwnt/nwnt/add-k8s-traffic-type
Add Kubernetes Traffic Type
2025-06-12 09:08:55 +02:00
Marek Siarkowicz dcaddc60c2 Remove defragment requests from linearization
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-12 08:58:41 +02:00
Nont 6aaf32b661 Add Kubernetes Traffic Type
Signed-off-by: Nont <nont@duck.com>
2025-06-11 22:03:54 -05:00
Benjamin Wang f6d6111eca
Merge pull request #20156 from ArkaSaha30/deps_mgmt_10_06_25
[2025-06-09] Manual Dependency Bump
2025-06-11 17:28:03 +01:00
ArkaSaha30 3303c356d0
dependency: bump github.com/alexfalkowski/gocovmerge from 1.8.0 to 1.9.0
This commit will bump bump github.com/alexfalkowski/gocovmerge from 1.8.0 to 1.9.0
also bumps golang.org/x/net from 0.40.0 to 0.41.0 as a dependency of github.com/alexfalkowski/gocovmerge

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-10 22:19:17 +05:30
Benjamin Wang 8142396ae8
Merge pull request #20155 from ahrtr/20250610_changelog_3.6.2
Update 3.6.2 changelog to cover bumping bbolt to 1.4.1
2025-06-10 17:21:29 +01:00
Benjamin Wang 40393403a5
Merge pull request #20153 from ahrtr/20250610_bbolt_1.4.1
Bump bbolt to v1.4.1
2025-06-10 17:21:00 +01:00
Benjamin Wang abf23ea86c Update 3.6.2 changelog to cover bumping bbolt to 1.4.1
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-10 15:15:38 +01:00
Benjamin Wang b11ab1d0cb Bump bbolt to v1.4.1
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-10 15:09:02 +01:00
Kishen Viswanathan 9f5ba66961 Add support to generate JSON report to the benchmark tool
Signed-off-by: Kishen Viswanathan <kishen.viswanathan@ibm.com>
2025-06-10 18:10:41 +05:30
Marek Siarkowicz 1e357cfc90
Merge pull request #20150 from serathius/antithesis-defrag
Fix handling defrag in antithesis tests
2025-06-10 13:42:22 +02:00
ArkaSaha30 1432e63f49
dependency: bump google.golang.org/grpc from 1.72.2 to 1.73.0
This commit will bump google.golang.org/grpc from 1.72.2 to 1.73.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-10 15:38:11 +05:30
Marek Siarkowicz bfbf25ca04 Fix handling defrag in antithesis tests
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-10 11:51:09 +02:00
ArkaSaha30 91d931ad08
dependency: bump golang.org/x/time from 0.11.0 to 0.12.0
This commit will bump golang.org/x/time from 0.11.0 to 0.12.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-10 14:59:59 +05:30
Benjamin Wang 989dd8e9a9 Update etcd governance to link to SIG-etcd governance
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-10 10:28:22 +01:00
Benjamin Wang 6d60b4c850
Merge pull request #20144 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.19
build(deps): bump github/codeql-action from 3.28.18 to 3.28.19
2025-06-10 10:05:05 +01:00
ArkaSaha30 7847848865
dependency: bump golang.org/x/crypto from 0.38.0 to 0.39.0
This commit will bump golang.org/x/crypto from 0.38.0 to 0.39.0
Also bumps golang.org/x/text from 0.25.0 to 0.26.0 as a dependent of golang.org/x/crypto

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-10 14:27:17 +05:30
Marek Siarkowicz a091a6d716
Merge pull request #20140 from nwnt/nwnt/add-defragment-to-antithesis
Add defragment support
2025-06-10 10:35:04 +02:00
Nont 85191bd75b Add defragment support
Signed-off-by: Nont <nont@duck.com>
2025-06-09 13:17:54 -05:00
dependabot[bot] dc80204eef
build(deps): bump github/codeql-action from 3.28.18 to 3.28.19
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.18 to 3.28.19.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](ff0a06e83c...fca7ace96b)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 17:38:28 +00:00
Benjamin Wang 5074f65cb6
Merge pull request #20138 from varunu28/watch-code-cleanup
client: Cleanup unnecessary null check from watcher
2025-06-09 14:32:01 +01:00
varunu28 04e31213b4 client: Cleanup unnecessary null check from watcher
Signed-off-by: varunu28 <varun.u28@gmail.com>
2025-06-07 12:20:46 -07:00
Fu Wei 780aef5f6e
Merge pull request #20130 from serathius/robustness-describe-truncate 2025-06-07 08:07:30 -04:00
Fu Wei 57c01974ea
Merge pull request #20131 from serathius/robustness-lease-ignore 2025-06-07 08:04:40 -04:00
James Blair 843658f16c
Merge pull request #20135 from ivanvc/changelog-release-3.6.1-date
CHANGELOG(3.6): Set v3.6.1 release date
2025-06-07 10:36:22 +12:00
Ivan Valdes 707bc6fbc0
CHANGELOG(3.6): Set v3.6.1 release date
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-06-06 13:33:18 -07:00
Benjamin Wang 7dd65ecd1c
Merge pull request #20134 from ivanvc/changlog-3.6-go-1.23.10
CHANGELOG(3.6): Add Go 1.23.10 note
2025-06-06 20:19:10 +01:00
Ivan Valdes 3154df0d4d
CHANGELOG(3.6): Add Go 1.23.10 note
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-06-06 11:21:30 -07:00
Fu Wei b8d1accc7d
Merge pull request #20124 from serathius/antithesis-ternary
Introduce Result struct to represent ternary result: success, failure unknown
2025-06-06 14:16:34 -04:00
Marek Siarkowicz 2e455e5680 Ignore leases from failed requests greatly reducing linearization search space
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-06 10:47:59 +02:00
Marek Siarkowicz 58d65781e8 Describe should sort and truncate after 3 to avoid huge files
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-06 10:42:42 +02:00
Benjamin Wang 84caef6ac8
Merge pull request #20127 from ivanvc/improve-tests-latest-version-log-message
Improve latest version log message
2025-06-06 07:43:33 +01:00
James Blair c58c0bd1c6
Merge pull request #20125 from purpleidea/bug/docs-links
readme: Fix broken docs link and add new ones
2025-06-06 08:04:51 +12:00
Ivan Valdes 50e0672184
Improve latest version log message
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-06-05 12:00:50 -07:00
James Shubin 87d3908208 readme: Fix broken docs link and add new ones
The current links point to the old v3.3 docs which aren't relevant
anymore. This also adds simple links to the current docs.

This fixes https://github.com/etcd-io/etcd/issues/19645

Signed-off-by: James Shubin <james@shubin.ca>
2025-06-05 14:56:37 -04:00
Marek Siarkowicz df4a65acb7 Introduce Result struct to represent ternary result: success, failure, unknown
This allows to properly pass error message to antithesis assertion, and
allows to avoid marking assertion success if the validation didn't run.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-05 20:15:52 +02:00
Fu Wei bbe99cecb6
Merge pull request #20122 from ahrtr/20250605_changelog
Update 3.6 changelog to cover the 'etcdctl endpoint health' fix
2025-06-05 10:32:37 -04:00
Marek Siarkowicz 3be967f201
Merge pull request #20123 from nwnt/nwnt/add-the-rest-of-traffic
Add the rest of the traffic to antithesis
2025-06-05 15:20:22 +02:00
Nont 37209aed8b Add the rest of the traffic to antithesis
Signed-off-by: Nont <nont@duck.com>
2025-06-05 07:52:12 -05:00
Benjamin Wang 5b11ed4622 Update 3.6 changelog to cover the 'etcdctl endpoint health' fix
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-05 12:52:58 +01:00
Benjamin Wang 1934e1126c
Merge pull request #20120 from ahrtr/20250605_ep_health
Update 'endpoint health' command to avoid calling `flags.SetPflagsFromEnv` multiple times
2025-06-05 12:46:47 +01:00
Benjamin Wang 58dadb1f1d Update 'endpoint health' command to avoid calling flags.SetPflagsFromEnv multiple times
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-05 11:00:07 +01:00
Benjamin Wang ea5b6030a6
Merge pull request #20114 from ahrtr/20250603_changelog
Update changelog to cover v2discovery and client/v2 removals
2025-06-04 16:28:57 +01:00
Benjamin Wang fa7b780498
Merge pull request #20117 from ahrtr/20250604_clientv2
Remove `client/internal/v2`
2025-06-04 16:28:46 +01:00
Benjamin Wang d4f85e58a3 Cleanup client/internal/v2 from scripts, go.mod/go.sum files, bom and codecov.yml
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-04 14:20:51 +01:00
Benjamin Wang 93d4e087c7 Update changelog to cover v2discovery and client/v2 removals
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-04 13:54:07 +01:00
Benjamin Wang 10fbccbd39 Remove client/internal/v2
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-04 13:26:23 +01:00
James Blair a756eaf122
Merge pull request #20108 from ArkaSaha30/deps_mgmt_03_06_25
[2025-06-02] Manual Dependency Bump
2025-06-04 22:11:02 +12:00
Benjamin Wang ab267ab803
Merge pull request #20109 from ahrtr/20250601_v2discovery
Remove v2discovery
2025-06-04 11:04:40 +01:00
Benjamin Wang 47ac8bdf22 Remove v2discovery
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-03 15:58:00 +01:00
Benjamin Wang 3f9f0745ca
Merge pull request #20111 from ahrtr/20250603_discovery_ep
Verify that the discovery endpoint isn't empty
2025-06-03 15:54:54 +01:00
Benjamin Wang abab2cdfa8 Verify that the discovery endpoint isn't empty
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-03 14:29:14 +01:00
Benjamin Wang 02b4add11d
Merge pull request #20100 from ahrtr/20250602_update_discovery
Update `--discovery` related test cases to use v3discovery flags
2025-06-03 11:57:57 +01:00
Benjamin Wang d8c3007ca6
Merge pull request #20096 from kjgorman/changelog-19577
CHANGELOG: add backport fix notes for #19577
2025-06-03 09:37:54 +01:00
ArkaSaha30 f89b3ae183
dependency: bump github.com/olekukonko/tablewriter from 1.0.6 to 1.0.7
This commit will bump github.com/olekukonko/tablewriter from 1.0.6 to 1.0.7

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-03 12:58:58 +05:30
ArkaSaha30 66ba3990ab
dependency: bump go.opentelemetry.io/proto/otlp from 1.6.0 to 1.7.0
This commit will bump go.opentelemetry.io/proto/otlp from 1.6.0 to 1.7.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-06-03 12:58:43 +05:30
Benjamin Wang 4d32b9ab73
Merge pull request #20102 from etcd-io/dependabot/github_actions/docker/build-push-action-6.18.0
build(deps): bump docker/build-push-action from 6.17.0 to 6.18.0
2025-06-02 20:44:53 +01:00
Benjamin Wang 7e467f7e19
Merge pull request #20101 from etcd-io/dependabot/github_actions/ossf/scorecard-action-2.4.2
build(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2
2025-06-02 20:44:31 +01:00
Marek Siarkowicz 2553e66210
Merge pull request #20090 from nwnt/nwnt/fix-instrumentation
Use official build process for instrumentation
2025-06-02 20:54:35 +02:00
dependabot[bot] 154995c5ad
build(deps): bump docker/build-push-action from 6.17.0 to 6.18.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](1dc7386353...263435318d)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 17:59:35 +00:00
dependabot[bot] 32c7792f48
build(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](f49aabe0b5...05b42c6244)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 17:42:18 +00:00
Benjamin Wang 1bd07cd2af Update -discovery related test cases to use v3discovery flags
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-06-02 17:32:15 +01:00
Nont 2e5a835689 Use official build process for instrumentation
Signed-off-by: Nont <nont@duck.com>
2025-06-02 10:57:32 -05:00
Marek Siarkowicz 54ddc02b94
Merge pull request #20092 from serathius/antithesis-fix-docker-compose
Fix templating docker-compose to reference the correct tags
2025-06-02 10:10:27 +02:00
Kieran Gorman ba585ea26c CHANGELOG: add backport fix notes for #19577
Adds each fix PR for previous release branches.

Signed-off-by: Kieran Gorman <kieran@kjgorman.com>
2025-06-02 08:10:15 +01:00
Benjamin Wang 22f8d56ca7
Merge pull request #20089 from Elbehery/20250530-address-usetesting-issues-linter
chore(test): Re-enable usetesting linter
2025-06-01 21:18:12 +01:00
Mustafa Elbehery 7c651c43c2 chore(test): Re-enable usetesting linter
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-06-01 19:33:45 +02:00
Benjamin Wang a6c57a791b
Merge pull request #20095 from Elbehery/20250601-address-usetesting-issues-clientV3
chore(clientV3): address Go usetesting for clientV3
2025-06-01 18:17:07 +01:00
Mustafa Elbehery 90f398fe00 chore(clientV3): address Go usetesting for clientV3
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-06-01 17:42:01 +02:00
Benjamin Wang 0c19ee442c
Merge pull request #20094 from ivanvc/address-usetesting-issues
tests/integration: address usetesting issues
2025-06-01 16:17:19 +01:00
Marek Siarkowicz f989f2361c
Merge pull request #20050 from joshjms/robustness-list-request-antithesis-traffic
Add List requests to Antithesis traffic
2025-06-01 16:53:06 +02:00
Ivan Valdes 1fbf7a77c0
tests/integration: address usetesting issues
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-06-01 07:15:56 -07:00
Benjamin Wang 029f02cf0d
Merge pull request #20088 from Elbehery/20250530-address-usetesting-issues-clientV3
chore(test): address Go usetesting for `clientV3`
2025-06-01 14:26:04 +01:00
Benjamin Wang 2aa01b6cc3
Merge pull request #20087 from Elbehery/20250530-address-usetesting-issues-v3_lease_test
chore(test): address Go usetesting for `v3_lease_test`
2025-06-01 14:25:39 +01:00
Benjamin Wang ba8f9fffb9
Merge pull request #20086 from Elbehery/20250530-address-usetesting-issues-v3_grpc_test
chore(test): address Go usetesting for `v3_grpc_test`
2025-06-01 14:25:18 +01:00
Benjamin Wang 97b2845f37
Merge pull request #20085 from Elbehery/20250530-address-usetesting-issues-v3_auth_test
chore(test): address Go usetesting for `v3_auth_test`
2025-06-01 14:24:58 +01:00
Marek Siarkowicz be1e58af99
Merge pull request #20053 from joshjms/robustness-key-window
Sync keys in keystore on list request response
2025-06-01 14:49:38 +02:00
Marek Siarkowicz fe1393cac0 Fix templating docker-compose to reference the correct tags
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-06-01 12:45:45 +02:00
Marek Siarkowicz 6651d64e22
Merge pull request #20091 from serathius/antithesis-fix-makefile
Fix antithesis makefile target
2025-06-01 11:47:25 +02:00
James Blair 9707af3b23
Merge pull request #20073 from ahrtr/20250530_changelog
Update changelog-3.6 to cover to fixes for 3.6.1
2025-06-01 12:28:06 +12:00
Benjamin Wang 142cdbfc5f
Merge pull request #20084 from Elbehery/20250530-address-usetesting-issues-watch_test
chore(test): address Go usetesting for `watch_test`
2025-05-31 18:50:35 +01:00
Benjamin Wang d5b71e7eeb
Merge pull request #20083 from Elbehery/20250530-address-usetesting-issues-leasing_test
chore(test): address Go usetesting for `leasing_test`
2025-05-31 18:50:20 +01:00
Mustafa Elbehery fb5b53495b chore(test): address Go usetesting for `clientV3`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 19:03:22 +02:00
joshjms 7a576bfaab robustness: Sync keys in keystore on list request response
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-06-01 00:13:28 +08:00
Marek Siarkowicz d465a15dc3 Fix antithesis makefile target
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-31 14:14:03 +02:00
Marek Siarkowicz 03c0f758ce
Merge pull request #20049 from nwnt/nwnt/allow-running-concurrent-tests
Fix multi-version concurrent tests
2025-05-31 14:11:24 +02:00
James Blair de65862cc2
Merge pull request #20082 from Elbehery/20250530-address-usetesting-issues-lease_test
chore(test): address usetesting issues in `lease_test.go`
2025-05-31 21:22:57 +12:00
Benjamin Wang b431e05e5e
Merge pull request #20080 from Elbehery/20250530-address-usetesting-issues-connectivity
chore(test): address Go usetesting for `connectivity`
2025-05-31 08:49:42 +01:00
Benjamin Wang 98ab934211
Merge pull request #20079 from Elbehery/20250530-address-usetesting-issues-concurrency
chore(test): address Go usetesting for `concurrency`
2025-05-31 08:49:13 +01:00
Benjamin Wang 3d3fcc6942
Merge pull request #20081 from Elbehery/20250530-address-usetesting-issues-experimental
chore(test): address Go usetesting for `experimental`
2025-05-31 08:45:44 +01:00
Nont 41d6379e84 Fix multi-version concurrent tests
Signed-off-by: Nont <nont@duck.com>
2025-05-30 22:11:35 -05:00
Mustafa Elbehery 6bbbca8a21 chore(test): address Go usetesting for `v3_auth_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 04:32:00 +02:00
Mustafa Elbehery 09fb9576cc chore(test): address Go usetesting for `watch_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 04:30:47 +02:00
Mustafa Elbehery bbb2db6435 chore(test): address Go usetesting for `leasing_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 04:30:11 +02:00
Mustafa Elbehery e97ebb9364 chore(test): address Go usetesting for `connectivity`.
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 04:29:02 +02:00
Mustafa Elbehery b0f4b1c737 chore(test): address Go usetesting for `v3_lease_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 01:37:47 +02:00
Mustafa Elbehery 84ed1cd100 chore(test): address Go usetesting for `v3_grpc_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 01:36:11 +02:00
Mustafa Elbehery edb9abda4c chore(test): address Go usetesting for `lease_test`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 01:16:53 +02:00
Mustafa Elbehery 9b09800633 chore(test): address Go usetesting for `experimental`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 00:55:56 +02:00
Mustafa Elbehery e6769d7724 chore(test): address Go usetesting for `concurrency`
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-31 00:42:48 +02:00
Benjamin Wang 2d10b4cbb6 Update changelog-3.6 to cover to fixes for 3.6.1
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-30 23:01:44 +01:00
Benjamin Wang f23c9d7fd3
Merge pull request #20055 from ahrtr/20250529_force_new_cluster_sync
Fix the issue that `--force-new-cluster` can't remove all other members in a corner case
2025-05-30 22:30:16 +01:00
Benjamin Wang 193189637e
Merge pull request #20070 from ivanvc/address-usetesting-issues
tests/common: address Go 1.24 usetesting issues
2025-05-30 19:02:09 +01:00
Marek Siarkowicz c272adec29
Merge pull request #20056 from serathius/cache-directory
Setup directory for cache
2025-05-30 19:52:45 +02:00
Benjamin Wang ec416efcc2 Initialize Commit Index = max(consistent_index, CommitIndex) on bootstrap if --force-new-cluster set
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-30 18:45:43 +01:00
Ivan Valdes ecfea37975
tests/common: address Go 1.24 usetesting issues
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-05-30 10:03:08 -07:00
Benjamin Wang f598a198e9 Add an e2e test to reproduce the issue that --force-new-cluster can't remove all members in a corner case
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-30 17:07:08 +01:00
Marek Siarkowicz b6167b7c5d
Merge pull request #19808 from serathius/refactor-executeRange
Split executeRange function
2025-05-30 16:46:54 +02:00
Marek Siarkowicz b6616c25dc Setup directory for cache
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-30 16:27:15 +02:00
Marek Siarkowicz b2008781b6
Merge pull request #20068 from serathius/license
Fix LICENSE file
2025-05-30 16:03:27 +02:00
Marek Siarkowicz 020077d520 Fix LICENSE file
Provide date based on file creation date

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-30 12:58:01 +02:00
Marek Siarkowicz 61126b9fd1
Merge pull request #20054 from serathius/antithesis-source
Set antithesis source to keep separate failure history for runs from different branches
2025-05-30 11:45:55 +02:00
Benjamin Wang b5e397922b
Merge pull request #20062 from ivanvc/address-usetesting-issues
tests/e2e: address usetesting issues
2025-05-30 09:53:16 +01:00
Marek Siarkowicz 28d6ed75bc
Merge pull request #20061 from nwnt/nwnt/add-compaction-test
Add test compaction
2025-05-30 10:31:07 +02:00
Ivan Valdes 0a93a28e7a
tests/e2e: address usetesting issues
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-05-29 22:12:15 -07:00
Nont 76d18dc936 Add test compaction
Signed-off-by: Nont <nont@duck.com>
2025-05-29 23:18:40 -05:00
Benjamin Wang c904edc174
Merge pull request #19760 from SalehBorhani/main
Add Support for Unix Socket endpoints
2025-05-29 16:11:36 +01:00
Marek Siarkowicz 3f8df6d6b1 Set antithesis source to keep separate failure history for runs from different branches
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-29 15:27:07 +02:00
Marek Siarkowicz 5e4ae51ed4
Merge pull request #20048 from serathius/antithesis-makefile
Simplify Makefile by removing set-version-* targets
2025-05-29 13:22:20 +02:00
borhanisaleh6 b039448e2f
fix: add support for connecting via Unix sockets
Signed-off-by: borhanisaleh6 <borhanisaleh6@gmail.com>
2025-05-29 11:12:31 +03:30
joshjms f1a4f10324 robustness: Add list requests to antithesis traffic
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-29 15:14:11 +08:00
Fu Wei 929ac02dbe
Merge pull request #20026 from ahrtr/20250526_v2store_member
Add protection on `PromoteMember` and `UpdateRaftAttributes`
2025-05-28 23:52:06 -04:00
Marek Siarkowicz bfd476f7c3 Simplify Makefile by removing set-version-* targets
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-28 23:07:19 +02:00
Marek Siarkowicz 18d30da95c
Merge pull request #20040 from henrybear327/antithesis/instrumentor
[Antithesis] Enable Antithesis Instrumentor for etcd server
2025-05-28 23:04:45 +02:00
Chun-Hung Tseng 74fa9d7d94 [Antithesis] Enable Antithesis Instrumentor for etcd server
Reference:
- https://github.com/etcd-io/etcd/issues/19786

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-05-28 22:50:54 +02:00
Benjamin Wang 90722adaa1
Merge pull request #20045 from dims/add-changelog-for-deprecated-removed-otelgrpc-api
Add changelog for deprecated/removed otelgrpc API
2025-05-28 21:31:52 +01:00
Davanum Srinivas c84b416f84
Add changelog for deprecated/removed otelgrpc API
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-28 10:47:27 -04:00
Benjamin Wang 69f0771c87 Add protection on PromoteMember and UpdateRaftAttributes
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-28 13:41:32 +01:00
Benjamin Wang d4dda0a1c8 Add an e2e test to reproduce the promote member panicking issue when forcibly create one-member cluster
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-28 13:41:12 +01:00
Benjamin Wang b3b9e986e0
Merge pull request #20039 from henrybear327/dependencies/25_05_28
[2025-05-28] Bump dependency updates identified by dependabot
2025-05-28 09:05:17 +01:00
Chun-Hung Tseng 3057ae1160 dependency: bump google.golang.org/grpc from 1.72.1 to 1.72.2
Reference:
- https://github.com/etcd-io/etcd/pull/20027

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-05-28 09:08:26 +02:00
Chun-Hung Tseng 45f4ab7953 dependency: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc from 1.35.0 to 1.36.0 and google.golang.org/genproto/googleapis/api from 0.0.0-20250428153025-10db94c68c34 to 0.0.0-20250519155744-55703ea1f237
Reference:
- https://github.com/etcd-io/etcd/pull/20028

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-05-28 09:08:26 +02:00
Chun-Hung Tseng 918e182209 dependency: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace from 1.35.0 to 1.36.0
Reference:
- https://github.com/etcd-io/etcd/pull/20029

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-05-28 07:41:23 +02:00
Chun-Hung Tseng 0fb9499f8b dependency: bump github.com/google/yamlfmt from 0.16.0 to 0.17.0
Reference:
- https://github.com/etcd-io/etcd/pull/20030

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-05-28 07:41:23 +02:00
Benjamin Wang 0e40709eac
Merge pull request #20008 from ivanvc/bump-tablewriter-to-1.0.6
dependency: bump github.com/olekukonko/tablewriter from 0.0.5 to 1.0.6
2025-05-27 20:32:09 +01:00
Marek Siarkowicz ae01ad849a
Merge pull request #20032 from serathius/antithesis-keypool-size
Fix number of operations is more than the key pool size
2025-05-27 11:56:31 +02:00
Marek Siarkowicz c36d8a7d78 Fix number of operations is more than the key pool size
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-27 11:40:17 +02:00
Marek Siarkowicz d8ca9eb39d
Merge pull request #20031 from serathius/antithesis-main
Fix name of main target for antithesis testing
2025-05-27 10:32:07 +02:00
Marek Siarkowicz 7aa8288130 Fix name of main target for antithesis testing
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-27 10:18:12 +02:00
Marek Siarkowicz 6115db53a8
Merge pull request #20013 from nwnt/nwnt/test-multiple-etcd-releases
Allow testing multiple etcd releases
2025-05-27 10:04:41 +02:00
Nont d9651182f7 Allow testing multiple etcd releases
Signed-off-by: Nont <nont@duck.com>
2025-05-27 09:31:05 +02:00
Benjamin Wang d9f4f8118c
Merge pull request #20025 from dims/add-changelog-for-otelgrpc-to-v0.61.0
Add changelog for otelgrpc to v0.61.0
2025-05-26 18:13:07 +01:00
Davanum Srinivas 14e33a817f
Add changelog for otelgrpc to v0.61.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-26 12:07:36 -04:00
Fu Wei 629741db60
Merge pull request #20020 from serathius/robustness-duplicate-delete
Handle duplicate key delete in one TXN
2025-05-26 12:01:32 -04:00
Benjamin Wang b7db5568f4
Merge pull request #20017 from dims/update-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc-to-v0.61.0
Update go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc to v0.61.0
2025-05-26 09:24:22 +01:00
Marek Siarkowicz 9349b23f0f
Merge pull request #20002 from joshjms/robustness-key-window
Add key window to achieve unique keys for delete operations
2025-05-25 13:25:32 +02:00
joshjms 225269df69 robustness: Add key store to achieve unique keys for delete operations
The issue is that the same keys are often reused for delete operations (i.e. key0-key9). This slows down linearization. The key store allows the clients to maintain a pool of keys which can be rotated probabilistically during delete operations.

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-25 17:09:06 +08:00
Benjamin Wang fb5bc004e7
Merge pull request #20019 from ahrtr/robust_test_20250524
Remove prefix `--experimental-` instead of `--experimental` from flag
2025-05-25 08:45:00 +01:00
Marek Siarkowicz 823556cfe4 Handle duplicate key delete in one TXN
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-24 21:08:04 +02:00
Benjamin Wang 96e40b27d2 Remove the prefix '--experimental-' instead of '--experimental' from flag
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-24 19:40:30 +01:00
Davanum Srinivas 61375682c2
refactor to reuse a single harness for both unary and stream tests
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-24 10:34:50 -07:00
Davanum Srinivas 7728d8fc8e
fix test
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-24 10:06:02 -07:00
Davanum Srinivas 15612bd968
add a new test for tracing with Stream RPC calls
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-24 09:02:18 -07:00
Benjamin Wang ebcfdd0185
Merge pull request #20015 from redwrasse/redwrasse/update-docs-ivt-splits
adt: update docstrings for IntervalTree.Insert and IntervalTree.find
2025-05-23 20:13:35 +01:00
Marek Siarkowicz 3a3962442e
Merge pull request #19695 from serathius/assume-v2
Assume v2 store is always not nil
2025-05-23 21:04:25 +02:00
Davanum Srinivas 457c2186a6
update go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc to v0.61.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2025-05-23 12:03:43 -07:00
Marek Siarkowicz 2a225549c8 Assume v2 store is always not nil
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-23 20:08:24 +02:00
redwrasse c604bfdf44 adt: update docstrings for IntervalTree.Insert and IntervalTree.find
to reflect modified algorithms.

Signed-off-by: redwrasse <mail@redwrasse.io>
2025-05-23 09:57:17 -07:00
Benjamin Wang 622a0100d8
Merge pull request #20001 from ahrtr/robustness_test_20250521
Converts between experimental and non-experimental flags in downgrade & upgrade robustness & e2e test
2025-05-23 15:42:32 +01:00
Benjamin Wang 8859f41bf7 convert the flags in downgrade & upgrade e2e test
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-23 14:08:51 +01:00
Benjamin Wang c0132db604 Add review policy
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-23 12:43:56 +01:00
Benjamin Wang 6e2be32266
Merge pull request #20016 from ahrtr/patchargs_20250523
Move parseArgs into e2e framework
2025-05-23 11:34:09 +01:00
Benjamin Wang 256bfd25d4
Merge pull request #20010 from silentred/remove-sync-ticker
remove deprecated SyncTicker in EtcdServer
2025-05-23 11:08:49 +01:00
Benjamin Wang 6c807b30f2 Move parseArgs into e2e framework
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-23 10:40:59 +01:00
shenmu.wy e7b3aa738f remove deprecated SyncTicker in EtcdServer
Signed-off-by: shenmu.wy <shenmu.wy@antfin.com>
2025-05-23 17:08:56 +08:00
Marek Siarkowicz 55ee50089f
Merge pull request #20014 from nwnt/nwnt/add-putwithlease-traffic
Add PutWithLease traffic
2025-05-23 09:31:20 +02:00
Benjamin Wang 1f7fdc39a6
Merge pull request #20012 from ivanvc/changelog-main-go-1.24.3
CHANGELOG(3.7): Amend the pull request number for Go 1.24.3
2025-05-23 07:31:26 +01:00
Nont c4f3290322 Add PutWithLease traffic
Signed-off-by: Nont <nont@duck.com>
2025-05-22 22:16:57 -05:00
Ivan Valdes e2fcdeccdb
CHANGELOG(3.7): Amend the pull request number for Go 1.24.3
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-05-22 15:14:11 -07:00
Marek Siarkowicz 0167cb3075
Merge pull request #19994 from nwnt/nwnt/add-multioptxn-traffic
Add MultiOpTxn traffic for anti-thesis
2025-05-22 14:43:38 +02:00
Benjamin Wang c849507a38
Merge pull request #20000 from ahrtr/changelog_3.7_20250521
Update 3.7 changelog to cover two changes
2025-05-22 11:00:27 +01:00
Benjamin Wang ed4b331c62
Merge pull request #19996 from joshjms/deps_mgmt_21_05_25
[2025-05-21] Manual Dependency Bump
2025-05-22 09:49:08 +01:00
Benjamin Wang 27bfe80df3 Update 3.7 changelog to cover two changes
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-22 09:46:49 +01:00
Ivan Valdes 4312b20009
dependency: bump github.com/olekukonko/tablewriter from 0.0.5 to 1.0.6
* Updates changes to version 1.0.x API to build tables.
* Updates the bill of materials.

Dependabot pull request: https://github.com/etcd-io/etcd/pull/19978

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-05-21 23:54:19 -07:00
Marek Siarkowicz 0287b75950
Merge pull request #19999 from serathius/robustness-stop-patching-watch
Stop using watch for determining response end time
2025-05-21 16:49:05 +02:00
Benjamin Wang a119975319
Merge pull request #19768 from redwrasse/redwrasse/interval-tree-left-right-split
adt: split interval tree by right endpoint on matched left endpoints
2025-05-21 13:07:15 +01:00
Marek Siarkowicz a4dc023d65 Stop using watch for determining response end time
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-21 13:34:08 +02:00
Benjamin Wang 2ba6ba7dcc
Merge pull request #19991 from ahrtr/release_test_20250520
Update test-release target
2025-05-21 10:32:17 +01:00
Marek Siarkowicz be2c3ca801
Merge pull request #19995 from nwnt/nwnt/measure-traffic
Measure traffic during test
2025-05-21 10:05:37 +02:00
joshjms 4119b58e69 dependency: bump github.com/prometheus/common from 0.63.0 to 0.64.0
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-21 11:12:17 +08:00
joshjms 558e48f155 dependency: bump google.golang.org/grpc from 1.72.0 to 1.72.1
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-21 11:12:09 +08:00
Nont fc0e79492c Measure traffic during test
Signed-off-by: Nont <nont@duck.com>
2025-05-20 22:05:17 -05:00
Nont ce21dd5db2 Add MultiOpTxn traffic
Signed-off-by: Nont <nont@duck.com>
2025-05-20 21:45:36 -05:00
Marek Siarkowicz 882713c4b6
Merge pull request #19989 from nwnt/nwnt/add-delete-traffic
Add delete traffic for antithesis
2025-05-20 23:52:20 +02:00
Benjamin Wang 4f45c346ba
Merge pull request #19959 from ahrtr/20250516_clean_experimental_flags
Cleanup the deprecated experimental flags
2025-05-20 20:27:00 +01:00
Benjamin Wang f2f647682f Update test-release target
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-20 19:04:10 +01:00
Benjamin Wang 56254468f2 Cleanup experimental flags for e2e and robustness test
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-20 18:50:10 +01:00
Benjamin Wang 73fdbfe848 Cleanup the deprecated experimental flags for etcdserver
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-20 18:48:03 +01:00
Benjamin Wang f19aca6858
Merge pull request #19961 from ahrtr/20250516_37
Bump version to 3.7
2025-05-20 18:43:06 +01:00
Benjamin Wang 0b68c64527 Fix integration & e2e test failures
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-20 17:18:40 +01:00
Benjamin Wang 4800faaf70 Fix unit test failures
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-20 17:18:34 +01:00
Nont c675eef4c7 Add delete traffic for antithesis
Signed-off-by: Nont <nont@duck.com>
2025-05-20 07:58:57 -05:00
Benjamin Wang a029b090cb
Merge pull request #19986 from hwdef/exempt-help-wanted
stale action: exempt help wanted label for stale action
2025-05-20 10:04:32 +01:00
Marek Siarkowicz d68eac5a37
Merge pull request #19975 from nwnt/nwnt/move-validation-to-finally-driver
Move validation to separate finally driver
2025-05-20 10:12:43 +02:00
hwdef d545dfd4e6 exempt help wanted label for stale action
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-05-20 15:39:13 +08:00
Marek Siarkowicz 9410e64a42
Merge pull request #19985 from nwnt/nwnt/add-stale-list-traffic
Add Stale List traffic for antithesis
2025-05-20 09:19:38 +02:00
Marek Siarkowicz dbf884e422
Merge pull request #19970 from serathius/antithesis-single-observer
Allow case where only one member observed all requests
2025-05-20 09:15:23 +02:00
Nont 32c4fbfba7 Move validation to separate finally driver
Signed-off-by: Nont <nont@duck.com>
2025-05-19 22:36:21 -05:00
Nont 216328bb31 Add Stale List traffic for antithesis
Signed-off-by: Nont <nont@duck.com>
2025-05-19 18:03:35 -05:00
Benjamin Wang 4c65b6eb41
Merge pull request #19982 from etcd-io/dependabot/github_actions/docker/build-push-action-6.17.0
build(deps): bump docker/build-push-action from 6.16.0 to 6.17.0
2025-05-19 22:43:55 +01:00
Benjamin Wang d1bf06c60d
Merge pull request #19979 from etcd-io/dependabot/docker/distroless/static-debian12-d9f9472a8f4541368192d714a995eb1a99bab1f7071fc8bde261d7eda3b667d8
build(deps): bump distroless/static-debian12 from `3d0f463` to `d9f9472`
2025-05-19 22:43:10 +01:00
Benjamin Wang 47c840533d
Merge pull request #19983 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.18
build(deps): bump github/codeql-action from 3.28.17 to 3.28.18
2025-05-19 22:42:47 +01:00
Marek Siarkowicz 2e99e46f5a Allow case where only one member observed all requests
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-19 21:42:13 +02:00
Marek Siarkowicz cb40b4e226
Merge pull request #19977 from joshjms/robustness-make-reports-easier-to-read
Make visualization more compact
2025-05-19 20:37:51 +02:00
dependabot[bot] be8f09a9dc
build(deps): bump github/codeql-action from 3.28.17 to 3.28.18
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.17 to 3.28.18.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](60168efe1c...ff0a06e83c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 18:06:52 +00:00
dependabot[bot] 19908558c9
build(deps): bump docker/build-push-action from 6.16.0 to 6.17.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.16.0 to 6.17.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](14487ce63c...1dc7386353)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 18:06:10 +00:00
dependabot[bot] 1280c5bf73
build(deps): bump distroless/static-debian12 from `3d0f463` to `d9f9472`
Bumps distroless/static-debian12 from `3d0f463` to `d9f9472`.

---
updated-dependencies:
- dependency-name: distroless/static-debian12
  dependency-version: d9f9472a8f4541368192d714a995eb1a99bab1f7071fc8bde261d7eda3b667d8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 17:40:15 +00:00
joshjms d3478bfcc6 Make visualization more compact
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-20 00:50:05 +08:00
Benjamin Wang afbb3b437c Bump version to 3.7
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-19 17:08:39 +01:00
joshjms e5572b2b6f docs: add dry run instruction for release
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-19 20:17:56 +08:00
Marek Siarkowicz 14448c52f5
Merge pull request #19972 from nwnt/nwnt/add-stale-get-traffic
Add StaleGet traffic for antithesis
2025-05-19 09:29:41 +02:00
Nont cdc0f9e6d2 Add StaleGet traffic for antithesis
Signed-off-by: Nont <nont@duck.com>
2025-05-18 12:57:26 -05:00
Marek Siarkowicz 592c195ae2
Merge pull request #19965 from serathius/antithesis-empty-history
Allow empty member histories from all three members
2025-05-17 15:41:31 +02:00
Marek Siarkowicz c47a2916be
Merge pull request #19966 from serathius/antithesis-race
Prevent exiting before watch closes
2025-05-17 15:40:36 +02:00
Marek Siarkowicz e7dd2aca55 Prevent exiting before watch closes
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 14:29:29 +02:00
Marek Siarkowicz 08864da0ab Allow empty member histories from all three members
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 14:26:32 +02:00
Marek Siarkowicz c6dd1c552f
Merge pull request #19968 from serathius/antithesis-watch-error
Fix error handling in watch
2025-05-17 14:25:59 +02:00
Marek Siarkowicz 9564549df4 Fix error handling in watch
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 13:54:30 +02:00
Marek Siarkowicz 4ff8b06dab
Merge pull request #19967 from serathius/antithesis-fix-no-reports
Fix missing KV reports in antithesis
2025-05-17 12:31:36 +02:00
Marek Siarkowicz 8a64f7a810 Fix missing KV reports in antithesis
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 12:22:43 +02:00
Marek Siarkowicz a7d1fd5ca8
Merge pull request #19964 from serathius/antithesis-fetch
Fetch branch when building antithesis image
2025-05-17 10:30:17 +02:00
Marek Siarkowicz ff6d645779 Fetch branch when building antithesis image
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 10:27:44 +02:00
Marek Siarkowicz a460abc7f9
Merge pull request #19963 from serathius/antithesis-fix-build
Fix building antithesis etcd image
2025-05-17 10:16:41 +02:00
Marek Siarkowicz 61489056d5 Fix building antithesis etcd image
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-17 10:14:57 +02:00
Marek Siarkowicz 690f315b9e
Merge pull request #19946 from nwnt/nwnt/antithesis-add-watch-requests
[Antithesis] Add support for watch requests
2025-05-17 10:05:51 +02:00
Marek Siarkowicz fd0599461e
Merge pull request #19956 from nwnt/nwnt/dedicated-etcd-image
Build dedicated etcd image for antithesis
2025-05-17 09:57:16 +02:00
Marek Siarkowicz d564fb9699
Merge pull request #19960 from serathius/antithesis-skip-uncommited
Allow observing inconsistent WAL entries on one of the members
2025-05-17 09:52:15 +02:00
Nont 4a611b631d [Antithesis] Add support for watch requests
Signed-off-by: Nont <nont@duck.com>
2025-05-17 00:37:38 -05:00
Nont d40a5946d1 Build dedicated etcd image for antithesis
Signed-off-by: Nont <nont@duck.com>
2025-05-16 22:30:46 -05:00
Marek Siarkowicz a426b0fc9a Allow observing inconsistent WAL entries on one of the members
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-16 18:32:31 +02:00
Marek Siarkowicz b90252f859 Test persistent request creation based on merging WAL
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-16 18:30:45 +02:00
Marek Siarkowicz b605213c05
Merge pull request #19957 from serathius/antithesis-endpoint
Fix etcd endpoint in antithesis testing
2025-05-16 11:15:56 +02:00
Marek Siarkowicz 68230c1482
Merge pull request #19698 from serathius/v3-assume
Assume v3 store is always not nil
2025-05-16 11:05:42 +02:00
Marek Siarkowicz 750618c2e3 Fix etcd endpoint in antithesis testing
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-16 10:37:43 +02:00
Benjamin Wang f206a8a579
Merge pull request #19955 from k8s-infra-cherrypick-robot/cherry-pick-19951-to-main
[main] Update release script to exactly match the target tag
2025-05-16 07:56:43 +01:00
Benjamin Wang 7770640d66 Update release script to exactly match the target tag
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-15 19:56:47 +00:00
Benjamin Wang a54e7e00c8
Merge pull request #19952 from joshjms/changelog-3.6
Update for release v3.6.0
2025-05-15 20:51:43 +01:00
joshjms 6becfe6461 changelog: update for release v3.6.0
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-16 03:48:05 +08:00
Marek Siarkowicz 5e9a6ef1ad
Merge pull request #19949 from serathius/antithesis-panic
Don't panic if could not read the persisted requests
2025-05-15 19:35:58 +02:00
Marek Siarkowicz 452f0a1f10 Don't panic if could not read the persisted requests
Validation works without persisted requests, it will just take longer.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-15 18:24:29 +02:00
Marek Siarkowicz ecd8a37e81
Merge pull request #19947 from amosehiguese/issue-13715
[Integration Test]: Add test for panic-free removal of non-existent members
2025-05-15 14:14:22 +02:00
amosehiguese 67dae5b26e [Integration Test]: Add test for panic-free removal of non-existent members
This test verifies that etcd no longer panics when restarting after
removing a member that was already removed from the cluster.

addresses: issue #13715

Signed-off-by: amosehiguese <amosehiguese@gmail.com>
2025-05-15 09:53:42 +00:00
Marek Siarkowicz 73f440bf3f
Merge pull request #19945 from joshjms/robustness-test-release-3.6
Add test-robustness-release-3.6 Makefile target
2025-05-15 10:24:25 +02:00
Benjamin Wang 8f155a3999
Merge pull request #19458 from 1911860538/feat/storage-util
chore: remove unused and deprecated func `GetEffectiveNodeIdsFromWalEntries`
2025-05-15 09:20:31 +01:00
joshjms a87600eeb2 Add test-robustness-release-3.6 Makefile target
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-15 15:52:54 +08:00
Marek Siarkowicz 0c43c4b868
Merge pull request #19939 from serathius/antithesis-fixes
Antithesis fixes
2025-05-14 14:56:57 +02:00
Marek Siarkowicz 4cdcaa069c Disable other validations when linearization failed
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-14 14:12:58 +02:00
Marek Siarkowicz a7d8b942e2 Revert "[Antithesis] Remove Go version from Dockerfile"
This reverts commit be23337121.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-14 14:05:42 +02:00
Marek Siarkowicz 7c4e448717
Merge pull request #19915 from nwnt/nwnt/dump-robustness-report
[Antithesis] dump result to robustness report
2025-05-14 13:48:15 +02:00
Marek Siarkowicz 41fd9ad055 Small fixes in creating, copying and removing data directory
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-14 13:09:10 +02:00
Nont 9be7d684a8 [Antithesis] dump result to robustness report
Signed-off-by: Nont <nont@duck.com>
2025-05-14 12:54:39 +02:00
James Blair 67738de788
Merge pull request #19936 from joshjms/deps_mgmt_14_05_25
[2025-05-14] Manual Dependency Bump
2025-05-14 22:46:21 +12:00
Marek Siarkowicz 094a4adfd6
Merge pull request #19937 from nwnt/nwnt/remove-default-go-version
[Antithesis] Remove Go version from Dockerfile
2025-05-14 10:41:53 +02:00
Marek Siarkowicz 11452157c1
Merge pull request #19600 from kjgorman/mvcc-double-decrement-watcher-gauge
mvcc: avoid double decrement of watcher gauge on close/cancel race
2025-05-14 10:33:23 +02:00
joshjms f27a4d5b7f dependency: bump github.com/alexfalkowski/gocovmerge from 1.7.0 to 1.8.0 in /tools/mod
PR: https://github.com/etcd-io/etcd/pull/19930

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-14 11:44:25 +08:00
joshjms d1aae3164a dependency: bump gotest.tools/gotestsum from 1.12.1 to 1.12.2 in /tools/mod
PR: https://github.com/etcd-io/etcd/pull/19929

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-14 11:44:25 +08:00
joshjms 92092f19a4 dependency: bump golang.org/x/net from 0.39.0 to 0.40.0
PR: https://github.com/etcd-io/etcd/pull/19927

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-14 11:44:21 +08:00
joshjms dcd9f98f5a dependency: bump golang.org/x/crypto from 0.37.0 to 0.38.0
PR: https://github.com/etcd-io/etcd/pull/19925

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-14 11:35:05 +08:00
Nont be23337121 [Antithesis] Remove Go version from Dockerfile
This ensure we use the latest, same version of
Go as the etcd project

Signed-off-by: Nont <nont@duck.com>
2025-05-13 22:25:49 -05:00
Marek Siarkowicz 6d5eb7b5fc
Merge pull request #19933 from joshjms/robustness-make-reports-easier-to-read
robustness: improved visualization for EtcdState and WatchOperation
2025-05-13 13:05:06 +02:00
joshjms 3546091fdf robustness: improved visualization for EtcdState and WatchOperation
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-13 17:53:37 +08:00
Benjamin Wang 56bc42a65f
Merge pull request #19932 from hwdef/remove-probot-stale
remove stale probot, and replace it with stale action
2025-05-13 10:09:47 +01:00
hwdef 1399c066e0 remove stale probot, and replace it with stale action
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-05-13 15:43:38 +08:00
James Blair 276839a2e4
Merge pull request #19910 from Elbehery/2025010-changelog-release-3.4-go-1.23.9
CHANGELOG(3.4): add Go 1.23.9 entry
2025-05-13 13:47:02 +12:00
James Blair bbba58b64e
Merge pull request #19928 from etcd-io/dependabot/github_actions/actions/setup-go-5.5.0
build(deps): bump actions/setup-go from 5.4.0 to 5.5.0
2025-05-13 13:46:01 +12:00
Mustafa Elbehery 5363cc6a5c CHANGELOG(3.4): add Go 1.23.9 entry
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-13 01:40:17 +02:00
Marek Siarkowicz 7a979db6d1
Merge pull request #19931 from serathius/antithesis-assertion-timeout
Move linearization timeout and other validations to separate assertions
2025-05-12 20:57:46 +02:00
Marek Siarkowicz 102efd7bd6 Move linearization timeout and other validations to separate assertions
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-12 20:20:17 +02:00
dependabot[bot] 626e638d77
build(deps): bump actions/setup-go from 5.4.0 to 5.5.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](0aaccfd150...d35c59abb0)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 17:52:59 +00:00
Benjamin Wang bcf4deee68
Merge pull request #19908 from Elbehery/2025010-bump-go1.24.3-main
[main] Bump Go to 1.24.3
2025-05-12 09:37:07 +01:00
James Blair 2044e24503
Merge pull request #19914 from shivamgcodes/update_3.6_CHANGELOG
listed removed flags in v3.6.0-rc.3
2025-05-12 10:38:44 +12:00
James Blair 47de6a90fc
Merge pull request #19909 from Elbehery/2025010-changelog-release-3.5-go-1.23.9
CHANGELOG(3.5): add Go 1.23.9 entry
2025-05-12 09:27:13 +12:00
Marek Siarkowicz ed9aa56f02
Merge pull request #19918 from serathius/robustness-avoid-copy
Avoid copying state for read requests
2025-05-11 14:00:24 +02:00
Marek Siarkowicz 207d9f7663
Merge pull request #19916 from serathius/robustness-list
After failed request fallback to LIST
2025-05-11 13:58:15 +02:00
Marek Siarkowicz 0b4b31f346
Merge pull request #19912 from serathius/robustness-runtime
Avoid encoding to Json to reduce overhead
2025-05-11 13:55:30 +02:00
Marek Siarkowicz 567e9a76cb
Merge pull request #19917 from serathius/robustness-benchmark
Add benchmark for linearization
2025-05-11 13:54:38 +02:00
Marek Siarkowicz 9045ef9122 Avoid copying state for read requests
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-11 12:59:39 +02:00
shivamgcodes 7085d3a1b4 listed removed flags in v3.6.0-rc.3
Signed-off-by: shivamgcodes <shivamguptaxia2@gmail.com>

moved removed flags to v3.6-rc.0

Signed-off-by: shivamgcodes <shivamguptaxia2@gmail.com>

minor change

Signed-off-by: shivamgcodes <shivamguptaxia2@gmail.com>

final

Signed-off-by: shivamgcodes <shivamguptaxia2@gmail.com>
2025-05-11 15:59:56 +05:30
Marek Siarkowicz 7b011cbb2f Avoid encoding to Json to reduce overhead
│  old.bench   │              new.bench              │
                                                      │    sec/op    │   sec/op     vs base                │
ValidateLinearizableOperations/Successes-14             13.493m ± 4%   3.658m ± 3%  -72.89% (p=0.000 n=10)
ValidateLinearizableOperations/AllFailures-14           10.663m ± 1%   1.539m ± 6%  -85.57% (p=0.000 n=10)
ValidateLinearizableOperations/PutFailuresWithRead-14    9.742m ± 2%   1.365m ± 1%  -85.99% (p=0.000 n=10)
geomean                                                  11.19m        1.973m       -82.37%

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-11 12:14:10 +02:00
Marek Siarkowicz ddd5f68b8e Add benchmark for linearization
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-11 11:57:15 +02:00
Marek Siarkowicz c34c6b3c0e
Merge pull request #19902 from serathius/antithesis-runtime-15s
Reduce runtime of antithesis tests to 15s
2025-05-11 10:47:33 +02:00
Marek Siarkowicz d794d9a54e After failed request fallback to LIST
This should help revovery from failed Put requests.
LIST will read all keys allowing us identify if requests previous write
succeeded, thus making linearization cheaper.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-11 10:08:04 +02:00
Marek Siarkowicz aac5a97aa7 Reduce runtime of antithesis tests to 15s
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-11 10:03:02 +02:00
James Blair 26d212dd36
Merge pull request #19891 from Elbehery/20250508-export-user-passwd-error
feat(client/v3): export username/password error
2025-05-11 12:23:49 +12:00
Mustafa Elbehery 9aae00c0fd chore(main): Bump Go to 1.24.3
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-10 12:33:01 +02:00
Mustafa Elbehery bce900db12 CHANGELOG(3.5): add Go 1.23.9 entry
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-10 09:14:09 +02:00
Marek Siarkowicz 8f69168578
Merge pull request #19907 from serathius/antithesis-validate-persisted-requests
Disable validation of assumption for persisted requests
2025-05-10 01:23:13 +02:00
Marek Siarkowicz 358d245a45 Disable validation of assumption for persisted requests
With Antithesis tests we no longer have guarantee of any requests
passing.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-10 00:51:54 +02:00
Marek Siarkowicz 216ce8f465
Merge pull request #19906 from serathius/antithesis-ubuntu
Add ubuntu image to antithesis configuration
2025-05-10 00:38:45 +02:00
Marek Siarkowicz e4ee974bed Add ubuntu image to antithesis configuration
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-10 00:22:42 +02:00
Marek Siarkowicz da989fe183
Merge pull request #19889 from nwnt/nwnt/antithesis-access-etcd-wal
[Antithesis] Get access to etcd data directory
2025-05-09 23:12:06 +02:00
Marek Siarkowicz 270f6a9522 Add clean command to allow running the test multiple times
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-09 22:06:52 +02:00
Nont 24e0999e4f [Antithesis] store validation on host volume
Signed-off-by: Nont <nont@duck.com>
2025-05-09 22:01:37 +02:00
Nont 9704426df6 [Antithesis] Get access to etcd data directory
Signed-off-by: Nont <nont@duck.com>
2025-05-09 21:45:25 +02:00
Marek Siarkowicz 3fb4ecd0ba
Merge pull request #19903 from serathius/antithesis-check-database-after
Move counting time after we confirm that database is empty
2025-05-09 20:07:13 +02:00
Marek Siarkowicz 5a6ffdc0bb Move counting time after we confirm that database is empty
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-09 19:49:05 +02:00
Mustafa Elbehery cd42de79da fix: export username/password error
Signed-off-by: Mustafa Elbehery <melbeher@redhat.com>
2025-05-09 16:53:35 +02:00
Marek Siarkowicz 49767381e8
Merge pull request #19898 from subrajeet-maharana/antithesis-always-assertion
antithesis: replaced Reachable/Unreachable assertion with Always
2025-05-09 14:04:42 +02:00
subrajeet-maharana be396789db antithesis: replaced Reachable/Unreachable assertion with Always
Signed-off-by: subrajeet-maharana <subrajeet.info@gmail.com>

Update tests/antithesis/test-template/robustness/main.go

Co-authored-by: Marek Siarkowicz <marek.siarkowicz@protonmail.com>

Update tests/antithesis/test-template/robustness/main.go

Co-authored-by: Marek Siarkowicz <marek.siarkowicz@protonmail.com>
Signed-off-by: subrajeet-maharana <subrajeet.info@gmail.com>
2025-05-09 16:07:07 +05:30
James Blair 03177c1a3a
Merge pull request #19894 from joshjms/patch-1
Update v3.6.0-rc.5 release date
2025-05-09 18:33:17 +12:00
Joshua James b5ef870433 Update v3.6.0-rc.5 release date
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-09 03:45:32 +08:00
Marek Siarkowicz 4a8827b1e9
Merge pull request #19892 from serathius/fault-injection
Allow retryable check of database empty and enable failure injection in Antithesis
2025-05-08 21:23:43 +02:00
Marek Siarkowicz 80b550f42d Allow retryable check of database empty and enable failure injection in Antithesis
In Antithesis we don't have control of failure injection. So we don't
have guarantee that the first request will pass.

Changing first request to read fixes the issue of first request not being retryable.
Changing the test name prefix to "singleton_driver_" enables antithesis
fault injection.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-08 20:47:44 +02:00
Marek Siarkowicz b6de745906
Merge pull request #19888 from nwnt/nwnt/document-running-antithesis-validation
[Antithesis] Document running validation
2025-05-08 10:10:52 +02:00
Marek Siarkowicz fa80bbda68
Merge pull request #19887 from nwnt/nwnt/run-validation-locally
Allow running antithesis tests locally
2025-05-08 09:46:07 +02:00
Nont 6e0213be06 [Antithesis] Document running validation
Signed-off-by: Nont <nont@duck.com>
2025-05-07 20:12:20 -05:00
Nont 2ff63aa9e5 Allow running antithesis tests locally
Signed-off-by: Nont <nont@duck.com>
2025-05-07 19:56:21 -05:00
James Blair cd2a292431
Merge pull request #19886 from siyuanfoundation/doc-release
doc: add example PR of kubernetes/org for release.
2025-05-08 12:50:41 +12:00
Siyuan Zhang 11809a312e doc: add example PR of kubernetes/org for release.
Signed-off-by: Siyuan Zhang <sizhang@google.com>
2025-05-07 16:53:39 -07:00
Marek Siarkowicz 297e9d1d58
Merge pull request #19879 from serathius/close-channel
Fix repeated closure of channel
2025-05-07 19:55:16 +02:00
Marek Siarkowicz a6b9029d4a Fix repeated closure of channel
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-07 19:45:05 +02:00
Marek Siarkowicz 1158c17d4f
Merge pull request #19878 from serathius/antithesis-first
Use first_ command type to ensure antithesis runs robustness tests only once
2025-05-07 18:51:14 +02:00
Marek Siarkowicz c3f7b11a86 Use first_ command type to ensure antithesis runs robustness tests only once
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-07 18:48:11 +02:00
Marek Siarkowicz dc310f2d32
Merge pull request #19876 from serathius/command-type
Fix antithesis driver command type
2025-05-07 16:50:20 +02:00
Marek Siarkowicz 7530a65c31 Fix antithesis driver command type
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-07 16:49:44 +02:00
Marek Siarkowicz baa7ed90f5
Merge pull request #19873 from serathius/validation
[Antithesis] Validate history collected by recording client
2025-05-07 14:40:15 +02:00
Abdur Rehman 9284ac347d validate history collected by recording client
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-05-07 13:43:38 +02:00
James Blair aedae3a4fa
Merge pull request #19869 from ivanvc/changelog-release-3.6-go-1.23.9
CHANGELOG(3.6): add Go 1.23.9 entry
2025-05-07 19:01:27 +12:00
Benjamin Wang d4b56bdebd
Merge pull request #19864 from joshjms/deps_mgmt_06_05_25
[2025-05-06] Manual Dependency Bump
2025-05-07 07:45:31 +01:00
Benjamin Wang 822b5aad78
Merge pull request #19862 from hwdef/update-release-notes-tpl
release: Fix the tar unzip command,  avoid permissions issues
2025-05-07 07:43:56 +01:00
Benjamin Wang 51954f7e85
Merge pull request #19859 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.17
build(deps): bump github/codeql-action from 3.28.16 to 3.28.17
2025-05-07 07:43:24 +01:00
Ivan Valdes 7a58009841
CHANGELOG(3.6): add Go 1.23.9 entry
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-05-06 22:59:52 -07:00
joshjms e3a2e1f438 dependency: bump go.opentelemetry.io/proto/otlp from 1.5.0 to 1.6.0
PR: https://github.com/etcd-io/etcd/pull/19858

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-07 09:58:54 +08:00
joshjms 94c632c464 dependency: bump golang.org/x/sys from 0.32.0 to 0.33.0
PR: https://github.com/etcd-io/etcd/pull/19861

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-07 09:58:43 +08:00
Benjamin Wang 8e28df0496
Merge pull request #19865 from ahrtr/roadmap_range_stream_20250506
Update roadmap to add range stream stream feature in v3.7
2025-05-06 19:25:51 +01:00
Benjamin Wang 1cc7eedca4 Update roadmap to add range stream stream feature in v3.7
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-06 15:38:21 +01:00
Marek Siarkowicz 6e1d8153ac
Merge pull request #16803 from mcrute/client-supports-jwt
clientv3: allow setting JWT directly
2025-05-06 09:14:50 +02:00
hwdef dbb76f3fcd Fix the tar unzip command, adding the --no-same-owner option to avoid permissions issues
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-05-06 15:06:39 +08:00
Fu Wei b2f243c59b
Merge pull request #19857 from ahrtr/dep_20250505
Update dependency management guide
2025-05-05 13:28:58 -07:00
dependabot[bot] efe7f8158c
build(deps): bump github/codeql-action from 3.28.16 to 3.28.17
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.16 to 3.28.17.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](28deaeda66...60168efe1c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 17:57:34 +00:00
Mike Crute 24b9a32c03 test: validate direct JWT passing and acceptance
Signed-off-by: Mike Crute <mike@crute.us>
2025-05-05 10:26:54 -07:00
Mike Crute c70cb53fe7 etcdclt: support passing JWT auth token
Signed-off-by: Mike Crute <mike@crute.us>
2025-05-05 10:26:20 -07:00
Mike Crute ab2248ae25 clientv3: allow setting JWT directly
etcd supports using signed JWTs in a verify-only mode where the server
has access to only a public key and therefore can not create tokens but
can validate them. For this to work a client must not call Authenticate
and must instead submit a pre-signed JWT with their request. The server
will validate this token, extract the username from it, and may allow
the client access.

This change allows setting the JWT directly and not setting a username
and password. If a JWT is provided the client will no longer call
Authenticate, which would not work anyhow. It also provides a public
method UpdateAuthToken to allow a user of the client to update their
auth token, for example, if it expires.

In this flow all token lifecycle management is handled outside of the
client as a concern of the client user.

Signed-off-by: Mike Crute <mike@crute.us>
2025-05-05 10:26:19 -07:00
Fu Wei 7f8da618e5
Merge pull request #19847 from amosehiguese/update-changelog
chore(CHANGELOG): update v3.5 and v3.6 changelog to reflect Endpoint.Metadata deprecation
2025-05-05 10:16:30 -07:00
Marek Siarkowicz 158b9e0d46
Merge pull request #19852 from nwnt/nwnt/use-robustness-traffic-gen
Use robustness traffic generation
2025-05-05 16:07:06 +02:00
Benjamin Wang 994cebcbbd Update dependency management guide
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-05-05 14:58:50 +01:00
Marek Siarkowicz 3860239a9b Refactor antithesis robustness main
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-05-05 10:58:17 +02:00
Nont 15850236b3 Use robustness traffic generation
Signed-off-by: Nont <nont@duck.com>
2025-05-05 10:35:19 +02:00
Marek Siarkowicz eae9a91a20
Merge pull request #19849 from nwnt/nwnt/clean-up-delete_keys
Rename delete_keys to robustness
2025-05-04 12:13:09 +02:00
James Blair 1ab5ed13a2
Merge pull request #19753 from joshjms/add-read-changelog-directive
Add instruction to change golang version when building image
2025-05-03 22:35:43 +12:00
Benjamin Wang 4ad65d9d7c
Merge pull request #19843 from siyuanfoundation/tracing
remove DistributedTracing from feature gate list.
2025-05-01 19:35:22 +01:00
Benjamin Wang 15e8ec7524
Merge pull request #19821 from ivanvc/update-indirect-dependencies
Bump indirect dependencies required to add Trivy tool dependency
2025-05-01 16:34:42 +01:00
Nont 29419f7c37 Rename delete_keys to robustness
also rename main package go files to main.go

Signed-off-by: Nont <nont@duck.com>
2025-05-01 09:06:23 -05:00
Benjamin Wang 7a43280da7
Merge pull request #19833 from fuweid/fix-19832
tests/integration: deflaky TestMaintenanceSnapshotTimeout
2025-05-01 14:15:53 +01:00
Benjamin Wang 07c6977011
Merge pull request #19848 from joshjms/add-test-release-tests-makefile-target
fix: test-release checks
2025-05-01 13:23:16 +01:00
Wei Fu 90e17d8b43 tests/integration: deflaky TestMaintenanceSnapshotTimeout
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-05-01 13:01:12 +01:00
amosehiguese 965603e2de chore(CHANGELOG): update v3.5 and v3.6 changelog to reflect Endpoint.Metadata
deprecation

Signed-off-by: amosehiguese <amosehiguese@gmail.com>
2025-05-01 08:52:12 +00:00
joshjms c940bf55bf fix: test-release
Address reviews in #19815

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-05-01 07:55:22 +08:00
James Blair d610b0431b
Merge pull request #19815 from joshjms/add-test-release-tests-makefile-target
Add test-release-tests Makefile target
2025-05-01 09:24:19 +12:00
James Blair f5bc7615ed
Merge pull request #19836 from ivanvc/upload-partial-coverage-reports
make: upload partial coverage reports
2025-05-01 08:32:00 +12:00
Siyuan Zhang b1e76801e7 remove DistributedTracing from feature gate list.
Because the feature is not feature gated.

Signed-off-by: Siyuan Zhang <sizhang@google.com>
2025-04-30 13:17:09 -07:00
Benjamin Wang 0a0fde11ac
Merge pull request #19825 from amosehiguese/issue/19706
chore(client/v3/naming): deprecate Metadata field in Endpoint struct
2025-04-30 20:34:58 +01:00
Benjamin Wang c590dd6c58
Merge pull request #19837 from miancheng7/updatechangelog
Update changelog to include fix for compaction pause duration metric
2025-04-30 18:38:53 +01:00
Miancheng Lin a5834f89bb Update changelog to include fix for compaction pause duration metric
Signed-off-by: Miancheng Lin <iml@amazon.com>
2025-04-30 09:36:05 -07:00
amosehiguese 28d10d35c0 chore(client/v3/naming): deprecate Metadata field in Endpoint struct
issue: #19706

Signed-off-by: amosehiguese <amosehiguese@gmail.com>
2025-04-30 16:15:57 +00:00
Marek Siarkowicz 43a43f3229
Merge pull request #19834 from abdurrehman107/abdur-rehman/antithesis-pr-5
Antithesis: Use RecordingClient from robustness tests
2025-04-30 09:06:47 +02:00
joshjms 64cd6b643b Add test-release-tests Makefile target
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-30 11:07:19 +08:00
Abdur Rehman 1ba42cedaa Use RecordingClient from robustness tests
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-04-30 03:28:26 +05:00
Fu Wei 8da854dc69
Merge pull request #19817 from etcd-io/dependabot/github_actions/docker/build-push-action-6.16.0
build(deps): bump docker/build-push-action from 6.15.0 to 6.16.0
2025-04-29 15:08:17 -04:00
Ivan Valdes 8f63a8d6d8
make: upload partial coverage reports
In the case of workflow failures (i.e., flaky tests), we still should
upload a partial coverage report to avoid lagging reports on the stable
branches.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-04-29 11:02:54 -07:00
Marek Siarkowicz 28546faaab Split executeRange function
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-29 19:14:57 +02:00
Marek Siarkowicz e4fb13d93a
Merge pull request #19826 from serathius/refactor-txn-files
Split other methods in txn into separate files
2025-04-29 19:09:50 +02:00
Marek Siarkowicz 88bba4d86e
Merge pull request #19813 from serathius/refactor-membership-apply
Simplify apply by handling membership apply through the same applyV3 stack
2025-04-29 18:51:49 +02:00
Marek Siarkowicz ef211761b3 Split other methods in txn into separate files
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-29 18:08:41 +02:00
Marek Siarkowicz 1a3a5a491e
Merge pull request #19811 from serathius/refactor-check-put
Refactor checking put request
2025-04-29 18:02:44 +02:00
Marek Siarkowicz a28659010f Simplify apply by handling membership apply through the same applyV3 stack
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-29 17:57:50 +02:00
Marek Siarkowicz 881cce9943 Refactor checking put request
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-29 17:00:19 +02:00
Marek Siarkowicz 021aece959
Merge pull request #19824 from serathius/antithesis-dockerfile
Fix antithesis docker file removing distroless layer.
2025-04-29 16:41:08 +02:00
Fu Wei d3f49a1334
Merge pull request #19818 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.16
build(deps): bump github/codeql-action from 3.28.15 to 3.28.16
2025-04-29 10:24:10 -04:00
Marek Siarkowicz dd14d92af7
Merge pull request #19812 from serathius/refactor-applier-options
Extract applier options to simplify passing arguments
2025-04-29 16:11:31 +02:00
Marek Siarkowicz e80f3258d4 Fix antithesis docker file removing distroless image.
As antithesis requires CGO we cannot compile binary staticly.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-29 12:43:33 +02:00
dependabot[bot] e271b78223
build(deps): bump docker/build-push-action from 6.15.0 to 6.16.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.15.0 to 6.16.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](471d1dc4e0...14487ce63c)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-29 09:18:36 +00:00
Marek Siarkowicz 2310515a91
Merge pull request #19797 from nwnt/nwnt/consolidate-mod-files
Consolidate to tests's go.mod
2025-04-29 11:17:39 +02:00
Benjamin Wang 51e38f43eb
Merge pull request #19748 from amosehiguese/test/19499-flaky-testperiodichourly
fix(server/etcdserver/api/v3compactor): fix flaky TestPeriodicHourly and others with Retry Mechanism
2025-04-29 10:12:20 +01:00
Nont 3cf32c009c Consolidate to tests's go.mod
Also adjust the dockerfile and create a Makefile.

The dockerfile assumes project root as its build context.

Signed-off-by: Nont <nont@duck.com>
2025-04-29 10:16:03 +02:00
Marek Siarkowicz e70740be45
Merge pull request #19801 from redwrasse/redwrasse/ivl-tree-find-tests
adt: add tests for IntervalTree.Find()
2025-04-29 10:02:17 +02:00
Marek Siarkowicz 8ca65f523d
Merge pull request #19820 from nwnt/nwnt/fix-lint-and-rename-antithesis
[Antithesis] Fix lint and rename Dockerfile
2025-04-29 10:00:41 +02:00
Ivan Valdes 4d698b3dd2
Bump indirect dependencies
Required to add Trivy as a tool dependency.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-04-28 21:00:42 -07:00
Nont c3d7b2a316 [Antithesis] Fix lint and rename Dockerfile
Signed-off-by: Nont <nont@duck.com>
2025-04-28 21:37:34 -05:00
redwrasse abf043919b adt: more comprehensive tests for IntervalTree.Find
Signed-off-by: redwrasse <mail@redwrasse.io>
2025-04-28 16:47:36 -07:00
Benjamin Wang a4bbb46b86
Merge pull request #19814 from hwdef/update-roadmap
docs: update v3.6.0 roadmap
2025-04-28 22:00:26 +01:00
dependabot[bot] 2876a4ece5
build(deps): bump github/codeql-action from 3.28.15 to 3.28.16
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.15 to 3.28.16.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](45775bd823...28deaeda66)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 18:10:35 +00:00
Benjamin Wang 9d246198b5
Merge pull request #19803 from ivanvc/featuregate-return-exported-interface
pkg/featuregate: Return MutableFeatureGate interface in New function
2025-04-28 18:20:27 +01:00
hwdef 799f07bfff update v3.6.0 roadmap
Signed-off-by: hwdef <hwdefcom@outlook.com>
2025-04-28 16:25:30 +08:00
Benjamin Wang 21a976e9e2
Merge pull request #19343 from aladesawe/server-membership-unexported-return
Disable revive on NewMembershipBackend to fix unexported-return
2025-04-27 10:39:34 +01:00
Benjamin Wang da2837c54a
Merge pull request #19792 from joshjms/deps_mgmt_21_04_25
[2025-04-24] Manual Dependency Bump
2025-04-27 10:25:19 +01:00
Marek Siarkowicz de5e4a5281 Assume v3 store is always not nil
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-26 19:39:27 +02:00
Marek Siarkowicz cfb58eea7d Extract applier options to simplify passing arguments
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-26 18:06:41 +02:00
Marek Siarkowicz cc90010466
Merge pull request #19807 from serathius/refactor-txn
Extract ensureTrace function
2025-04-26 16:25:11 +02:00
Marek Siarkowicz 6608dfb2a5 Extract ensureTrace function
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-26 15:24:43 +02:00
Ivan Valdes 491199f4f0
pkg/featuregate: Return MutableFeatureGate interface in New function
Avoid returning an unexported struct in the exported New function,
instead return the MutableFeatureGate interface.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-04-25 23:14:09 -07:00
Fu Wei aa8238f511
Merge pull request #19608 from miancheng7/e2etestforissue19406
Add e2e test to reproduce issue #19406
2025-04-25 20:00:35 -04:00
redwrasse 1fa4e01ad6 adt: add tests for IntervalTree.Find()
Signed-off-by: redwrasse <mail@redwrasse.io>
2025-04-25 14:18:35 -07:00
James Blair f5dbde1d19
Merge pull request #19789 from ahrtr/changelog_20250423
Update changelog to cover the deprecating resolver.State.Addresses
2025-04-25 20:57:36 +12:00
Benjamin Wang 4fec4ca20c Update changelog to cover the deprecating resolver.State.Addresses
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-04-24 14:27:27 +01:00
Marek Siarkowicz c6ae58ee8d
Merge pull request #19781 from abdurrehman107/abdur-rehman/antithesis-itegration-pr-4
Antithesis Integration: Convert entrypoint from python to Go
2025-04-24 15:10:35 +02:00
Abdur Rehman 0ee26e9438 Convert entrypoint from python to Go
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-04-24 17:15:24 +05:00
Marek Siarkowicz bf27b54f43
Merge pull request #19794 from joshjms/change-hr-in-md
Change <hr> occurrences to `---` in Markdown files
2025-04-24 13:13:16 +02:00
joshjms 035631f511 Disable MD041
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-24 18:06:56 +08:00
joshjms b3bcfe802e Replace all instances of <hr> in markdown files with ---
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-24 17:47:05 +08:00
joshjms fa38b54dd5 Add defer-recover block to prevent panic when cc is nil
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-24 17:21:50 +08:00
joshjms f35125b31f dependency: bump google.golang.org/grpc from 1.71.1 to 1.72.0
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-24 17:21:40 +08:00
Marek Siarkowicz 6b87e2cb68
Merge pull request #19790 from henrybear327/antithesis/merge_workflow
[Robustness test] Merge Antithesis Github workflows
2025-04-24 09:41:38 +02:00
Chun-Hung Tseng 0392f5470d [Robustness test] Merge Antithesis Github workflows
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-23 22:23:57 +02:00
Benjamin Wang 8f933a5b58
Merge pull request #19780 from ahrtr/state_addr_20250422
Replace `resolver.State.Addresses` with `resolver.State.Endpoint.Addresses`
2025-04-23 10:10:31 +01:00
Marek Siarkowicz 27ff3ecfc3
Merge pull request #19271 from mmorel-35/golangci-lint/thelper
chore: enable thelper linter
2025-04-23 10:46:24 +02:00
Matthieu MOREL ca818927c2 chore: enable thelper linter
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-04-23 07:11:48 +02:00
Benjamin Wang 09f897de4d Replace resolver.State.Addresses with resolver.State.Endpoint.Addresses
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-04-22 15:26:41 +01:00
Marek Siarkowicz 028f107327
Merge pull request #19779 from joshjms/catch-slice-out-of-range
Catch ErrSliceOutOfRange error
2025-04-22 15:33:52 +02:00
joshjms 0a9c51210b Catch ErrSliceOutOfRange error
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-22 19:47:24 +08:00
James Blair dd23499144
Merge pull request #19030 from ivanvc/add-rw-heatmaps-line-chart
Add rw benchmark line chart
2025-04-22 23:14:42 +12:00
Marek Siarkowicz 7f51b1bf3b
Merge pull request #19757 from mmorel-35/testifylint@1.6.1
chore: fix testifylint new issues
2025-04-22 12:35:15 +02:00
Benjamin Wang 638b410173
Merge pull request #19762 from miancheng7/fixCompactionPauseMetric
emit compaction pause duration metric in every compaction batch
2025-04-21 09:20:46 +01:00
Miancheng Lin 818dec3f2f emit compaction pause duration metric in every compaction batch
Previously, the compaction pause duration metric was skipped if the number
of keys was smaller than `batchNum`, leading to gaps in monitoring data.
This change ensures the metric is emitted for every batch, regardless of
key count.

Signed-off-by: Miancheng Lin <iml@amazon.com>
2025-04-20 14:43:29 -07:00
redwrasse 21515e1454 adt: further split interval tree by right endpoint on matched left endpoints, to improve find() performance
Signed-off-by: redwrasse <mail@redwrasse.io>
2025-04-20 08:50:31 -07:00
Marek Siarkowicz 061e59aef2
Merge pull request #19767 from abdurrehman107/abdur-rehman/antithesis-itegration-pr-3
Add Antithesis package imports
2025-04-20 13:44:13 +02:00
Abdur Rehman 5ac6079c80 Add Antithesis package imports
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-04-20 14:16:29 +05:00
Marek Siarkowicz aa2a025f7b
Merge pull request #19765 from abdurrehman107/abdur-rehman/antithesis-integration-pr-2
Create Go client for robustness test foundation with etcd health checks
2025-04-19 12:02:29 +02:00
Abdur Rehman ca6f942723 Create Go client for robustness test foundation with etcd health checks
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-04-19 13:58:22 +05:00
Marek Siarkowicz 58086dadeb
Merge pull request #19764 from henrybear327/antithesis/fix_workflow
[Rubustness Test] Rename suffix yaml to yml
2025-04-18 11:00:35 +02:00
Chun-Hung Tseng 916b5a941e [Rubustness Test] Rename suffix yaml to yml
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-18 08:56:42 +00:00
Matthieu MOREL 0b9d021403 chore: fix testifylint new issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-04-18 08:18:18 +00:00
Marek Siarkowicz 4585ee9280
Merge pull request #19763 from henrybear327/antithesis/fix_workflow
[Robustness Test] Fix Dockerfile.config
2025-04-18 09:28:52 +02:00
Chun-Hung Tseng ff151eea12 [Robustness Test] Fix Dockerfile.config
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-18 09:28:09 +02:00
Miancheng Lin 03839c99c7 Add e2e test to reproduce issue #19406
Signed-off-by: Miancheng Lin <iml@amazon.com>
2025-04-17 21:01:23 -07:00
Marek Siarkowicz be71a86f7f
Merge pull request #19750 from henrybear327/antithesis/workflow
[Robustness Test] Add antithesis nightly workflow
2025-04-17 21:04:27 +02:00
Chun-Hung Tseng 59c2581a14 [Robustness Test] Add antithesis nightly workflow
Reference:
- https://github.com/etcd-io/etcd/issues/19299

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-17 18:36:06 +00:00
joshjms 08c09be0bb docs: add example to change golang version
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-17 22:03:06 +08:00
Benjamin Wang ddeaba726c
Merge pull request #19755 from ivanvc/changelog-3.6-etcdutl-snapshot-save
CHAGELOG-3.6: Remove `etcdutl snapshot save` removal note
2025-04-17 08:50:13 +01:00
Benjamin Wang 4591695bf1
Merge pull request #19754 from henrybear327/dependency/25_04_16
[2025-04-16] Bump dependency updates identified by dependabot
2025-04-17 08:36:56 +01:00
Chun-Hung Tseng 4443221dc4 dependency: bump github.com/prometheus/client_model from 0.6.1 to 0.6.2
Reference:
- https://github.com/etcd-io/etcd/pull/19742

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-17 06:28:20 +00:00
Chun-Hung Tseng 8318e06fdf dependency: bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0
Reference:
- https://github.com/etcd-io/etcd/pull/19744

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-17 06:28:20 +00:00
Ivan Valdes 84d8924822
CHAGELOG-3.6: Remove `etcdutl snapshot save` removal note
`etcdutl snapshot save` never made it to v3.5, so there's no need to
list it as a deprecation/removal.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-04-16 16:15:55 -07:00
Chun-Hung Tseng 2d4fd6747b dependency: bump github.com/alexfalkowski/gocovmerge from 1.6.0 to 1.7.0
Reference:
- https://github.com/etcd-io/etcd/pull/19745

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-16 18:25:04 +00:00
Chun-Hung Tseng 833b2c4263 dependency: bump golang.org/x/net from 0.38.0 to 0.39.0
Reference:
- https://github.com/etcd-io/etcd/pull/19743

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-16 18:25:04 +00:00
Fu Wei b90c5bce98
Merge pull request #19749 from fuweid/update-release-date
CHANGELOG: update items with release date
2025-04-15 17:54:44 -04:00
Wei Fu d4db4386a8 CHANGELOG: update items with release date
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-04-15 16:58:08 -04:00
amosehiguese 650232cd64 fix(server/etcdserver/api/v3compactor): fix flaky TestPeriodicHourly with retry mechanism
This commit fixes the flaky TestPeriodicHourly test (issue #19499) and similar
test cases by introducing an exponential backoff retry mechanism for waiting
on actions rather than relying on a fixed timeout.

The root cause of the flakiness was timing inconsistencies in CI environments,
where actions sometimes take slightly longer than the expected 10ms timeout
set when creating a compactable object.

The new waitWithRetry function attempts to get the expected actions multiple
times with exponentially increasing wait periods (10ms, 20ms, 40ms, etc.)
before ultimately failing.

The solution was verified by reproducing the issue with an artificial
delay and stress-testing the fix with 1000 consecutive runs.

The following test functions were updated to use the new retry mechanism:
- TestPeriodicHourly
- TestPeriodicMinutes
- TestPeriodicPause
- TestPeriodicSkipRevNotChange

Fixes #19499

Signed-off-by: amosehiguese <amosehiguese@gmail.com>
2025-04-15 16:04:31 +00:00
James Blair d3cebaec93
Merge pull request #19746 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.15
build(deps): bump github/codeql-action from 3.28.14 to 3.28.15
2025-04-15 10:09:24 +12:00
dependabot[bot] 1c77c1480e
build(deps): bump github/codeql-action from 3.28.14 to 3.28.15
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.14 to 3.28.15.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fc7e4a0fa0...45775bd823)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 18:01:35 +00:00
Marek Siarkowicz 4b7e512a66
Merge pull request #19739 from abdurrehman107/abdur-rehman/antithesis-integration
Antithesis Integration: Move Antithesis demo to etcd repo
2025-04-14 17:15:58 +02:00
Abdur Rehman a730bbda20 Move Antithesis demo to etcd repo
Signed-off-by: Abdur Rehman <razashahid107@gmail.com>
2025-04-14 19:29:57 +05:00
Benjamin Wang 5a8fba4660
Merge pull request #19738 from joshjms/main
K8s bump etcd version guide
2025-04-12 13:29:51 +01:00
joshjms 86ab134ed3 add current versioning rule
Clarified according to https://github.com/etcd-io/etcd/pull/19717#issuecomment-2789183940

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-11 19:16:39 +08:00
Benjamin Wang 282cc69b2d
Merge pull request #19717 from joshjms/update-etcd-steps
Summarize steps to update etcd version in Kubernetes
2025-04-11 09:18:55 +01:00
Benjamin Wang c5a5afda65
Merge pull request #19735 from joshjms/markdown-lint-config
Remove required headings rule in markdown checker
2025-04-10 21:03:25 +01:00
joshjms 3f524812e1 fix: remove required headings
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-11 02:38:01 +08:00
joshjms 0cec47ad42 docs: Summarize steps to update etcd version in Kubernetes
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-04-11 02:36:12 +08:00
James Blair 0ad7ea497c
Merge pull request #19718 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.14
build(deps): bump github/codeql-action from 3.28.13 to 3.28.14
2025-04-10 08:40:44 +12:00
Marek Siarkowicz 3a2e497d00
Merge pull request #19681 from serathius/robustness-merge-categorization
Merge operation categorization into one function
2025-04-09 15:44:54 +02:00
Marek Siarkowicz e9fcb41983
Merge pull request #19733 from henrybear327/robustness/address_9680_comments
[Robustness] Improve HashKV check comments
2025-04-09 11:37:14 +02:00
Chun-Hung Tseng 898f33ffac [Robustness] Improve HashKV check comments
Reference:
- https://github.com/etcd-io/etcd/pull/19680

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-09 10:38:15 +02:00
James Blair 0ff4a1a2a2
Merge pull request #19728 from henrybear327/docs/release_note_go_upgrade
Update release note for bumping Go to 1.23.8/1.24.2
2025-04-09 08:34:51 +12:00
Fu Wei 8949669ff8
Merge pull request #19729 from henrybear327/dependencies/25_04_08 2025-04-08 09:39:50 -04:00
Chun-Hung Tseng b0958f620a bump google.golang.org/grpc from 1.71.0 to 1.71.1
Reference:
- https://github.com/etcd-io/etcd/pull/19720

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-08 08:57:40 +02:00
Chun-Hung Tseng 3084319165 bump golang.org/x/crypto from 0.36.0 to 0.37.0, bump golang.org/x/sys from 0.31.0 to 0.32.0, bump golang.org/x/text from 0.23.0 to 0.24.0, and bump golang.org/x/sys from 0.31.0 to 0.32.0
Because bumping golang.org/x/crypto will also bump golang.org/x/sys,
golang.org/x/text, and golang.org/x/sys. Thus, these 4 are done in the
same PR.

Reference:
- https://github.com/etcd-io/etcd/pull/19719
- https://github.com/etcd-io/etcd/pull/19721
- https://github.com/etcd-io/etcd/pull/19722

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-08 08:57:40 +02:00
Chun-Hung Tseng 25889c08c1 Update release note for bumping Go to 1.23.8/1.24.2
Reference:
- https://github.com/etcd-io/etcd/issues/19713

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-08 08:47:01 +02:00
Fu Wei 4b76a9d4c6
Merge pull request #19723 from henrybear327/go/1.24.2
[main] Bump Go to 1.24.2
2025-04-07 17:45:38 -04:00
Chun-Hung Tseng 928581eae2 [main] Bump Go to 1.24.2
Reference:
- https://github.com/etcd-io/etcd/issues/19713

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-04-07 22:20:27 +02:00
dependabot[bot] 5ec2b2cbc6
build(deps): bump github/codeql-action from 3.28.13 to 3.28.14
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.13 to 3.28.14.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1b549b9259...fc7e4a0fa0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 18:05:04 +00:00
Benjamin Wang 3b66c82934
Merge pull request #19684 from siyuanfoundation/tool
[tools] Add option to dump range of entries.
2025-04-07 12:02:49 +01:00
James Blair fbaf89bfcf
Merge pull request #19666 from joshjms/fix-markdown-lint
markdown lint job: set ETCD_ROOT_DIR to root directory of git repository
2025-04-06 20:41:03 +12:00
Benjamin Wang d4868711e2
Merge pull request #19709 from ivanvc/dependencies-20250406
[2025-04-04] Manual Dependency Bump
2025-04-04 20:30:55 +01:00
Benjamin Wang dbf444ca96
Merge pull request #19708 from ahrtr/rc4_20250404
Update 3.6 changelog to cover the membership validation update
2025-04-04 20:30:22 +01:00
Benjamin Wang ab98cddd30 Update 3.6 changelog to cover the membership validation update
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-04-04 19:20:58 +01:00
Ivan Valdes ad13c0dac1
dependency: golang.org/x/net from v0.37.0 to v0.38.0
Bumps dependency based on dependabot's pull request:
https://github.com/etcd-io/etcd/pull/19696.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-04-04 09:32:00 +01:00
James Blair d6416b8773
Merge pull request #19685 from Dogacel/dogac/fix-macos-bom-issue
Fix "make verify" failing in MacOS due to BOM file verification.
2025-04-04 09:07:44 +13:00
Benjamin Wang 03b253714d
Merge pull request #19694 from serathius/v2-validation
Switch to validating v3 when v2 and v3 are synchronized
2025-04-03 11:02:04 +01:00
Siyuan Zhang ba600b25c2 Add option to dump a range of entries.
Signed-off-by: Siyuan Zhang <sizhang@google.com>
2025-04-01 08:56:52 -07:00
Marek Siarkowicz aa2472e617 Switch to validating v3 when v2 and v3 are synchronized
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-01 12:27:15 +02:00
James Blair 7351ab86c0
Merge pull request #19697 from etcd-io/dependabot/docker/distroless/static-debian12-3d0f463de06b7ddff27684ec3bfd0b54a425149d0f8685308b1fdf297b0265e9
build(deps): bump distroless/static-debian12 from `3f2b64e` to `3d0f463`
2025-04-01 22:36:55 +13:00
Fu Wei df935aa3b4
Merge pull request #19699 from serathius/hash-revision
Disable comparing hashRevision as it doesn't make sense and it's not implemented for etcd < 3.6
2025-03-31 21:46:37 -04:00
Marek Siarkowicz 9f6a829815 Disable comparing hashRevision as it doesn't make sense and it's not implemented for etcd < 3.6
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-04-01 01:30:51 +02:00
dependabot[bot] aac61b5f4f
build(deps): bump distroless/static-debian12 from `3f2b64e` to `3d0f463`
Bumps distroless/static-debian12 from `3f2b64e` to `3d0f463`.

---
updated-dependencies:
- dependency-name: distroless/static-debian12
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 18:08:57 +00:00
Marek Siarkowicz 37eaafa5a7
Merge pull request #19680 from henrybear327/issue/18386_end_of_test_check_case_1
[Robustness Test] Add HashKV check to robustness test
2025-03-30 19:56:36 +02:00
Chun-Hung Tseng a203755b3c Add HashKV check to robustness test
This PR adds only the end-of-test check only.

Reference:
- https://github.com/etcd-io/etcd/issues/18386

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-29 23:07:56 +01:00
James Blair 839985d96e
Merge pull request #19155 from mmorel-35/revive/unnecessary-stmt
chore: enable unnecessary-stmt rule from revive
2025-03-30 07:49:09 +13:00
Benjamin Wang ccec08989f
Merge pull request #19659 from etcd-io/dependabot/github_actions/actions/upload-artifact-4.6.2
build(deps): bump actions/upload-artifact from 4.6.1 to 4.6.2
2025-03-29 07:06:26 +00:00
James Blair eb7662d6cb
Merge pull request #19688 from ivanvc/release-note-golang.org-x-net-0.38.0-upgrade
CHANGELOG: Add missing entries in v3.6.0-rc.3 and v3.5.21
2025-03-29 09:06:35 +13:00
Ivan Valdes 43bbbbfc0b
CHANGELOG: Add entries in v3.6.0-rc.3 and v3.5.21
* Set release date
* Add missing entries for v3.5.21: #19686.
* Add v3.6.0-rc.3 missing entries: #19560, #19562, #19687.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-28 12:03:58 -07:00
Doğaç Eldenk cad737b595 Fix "make verify" failing in MacOS due to BOM file verification.
Signed-off-by: Doğaç Eldenk <dogacel@gmail.com>
2025-03-27 11:44:19 -05:00
Benjamin Wang b8762ac6ed
Merge pull request #19677 from ArkaSaha30/deps_mgmt_24_03_25
[2025-03-24] Manual Dependency Bump
2025-03-27 15:00:10 +00:00
Marek Siarkowicz 6caa1ecd0b Merge operation categorization into one function
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-03-27 13:09:44 +01:00
Marek Siarkowicz c983744ac2
Merge pull request #19669 from henrybear327/issue/19579_follow_up_2
[Robustness test] Preserve return time for failed requests
2025-03-27 12:49:41 +01:00
Chun-Hung Tseng eaeea10e7f [Robustness test] Preserve return time for failed requests
Reference:
- https://github.com/etcd-io/etcd/issues/19579
- https://github.com/etcd-io/etcd/pull/19651#discussion_r2011549432
- https://github.com/etcd-io/etcd/pull/19669#discussion_r2013777795
- https://github.com/etcd-io/etcd/pull/19669#discussion_r2014694994

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-27 11:38:25 +01:00
Marek Siarkowicz 022688bc6d
Merge pull request #19679 from serathius/robustness-non-infinite
Pass a non-infinite returnTime in history patching tests
2025-03-27 11:35:27 +01:00
Marek Siarkowicz 1cf63f1899 Pass a non-infinite returnTime in history patching tests
Since we use MaxInt64 to represent infinite for failed transactions,
there is no need to provide some infinite ourselves. We can just pass
returnTime observed by client and expect it will be set to infinite
during preparation step.

Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-03-27 09:25:06 +01:00
Benjamin Wang 0fbac24b29
Merge pull request #19676 from ivanvc/fix-codecov-pull-request-report
codecov: set commit sha for merges
2025-03-27 07:02:47 +00:00
ArkaSaha30 fe44a4bb81
dependency: bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2
This commit will bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-27 09:27:53 +05:30
ArkaSaha30 c19290acc7
dependency: bump github.com/prometheus/common from 0.62.0 to 0.63.0
This commit will bump github.com/prometheus/common from 0.62.0 to 0.63.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-27 09:27:45 +05:30
ArkaSaha30 375a71a520
dependency: bump google.golang.org/protobuf from 1.36.5 to 1.36.6
This commit will bump google.golang.org/protobuf from 1.36.5 to 1.36.6

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-27 09:27:35 +05:30
ArkaSaha30 c065b833f4
dependency: bump go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc from 0.59.0 to 0.60.0
This commit will bump go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc from 0.59.0 to 0.60.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-27 09:27:25 +05:30
ArkaSaha30 924a2e68c8
dependency: bump github.com/golangci/golangci-lint from 1.64.7 to 1.64.8
This commit will bump github.com/golangci/golangci-lint from 1.64.7 to 1.64.8

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-27 09:27:14 +05:30
Fu Wei afe2641a46
Merge pull request #19672 from ahrtr/changelog_clientv2_20250326 2025-03-26 21:15:02 -04:00
Ivan Valdes 02d62f69a3
codecov: set commit sha for merges
This is required to upload a Codecov report in a Prow post submit job.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-26 15:25:30 -07:00
Benjamin Wang d1f080129f Update 3.6 changelog to cover the moving client/v2 change
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-26 19:37:17 +00:00
Marek Siarkowicz 2733667894
Merge pull request #19668 from henrybear327/issue/19579_follow_up
[Robustness test] Improve append history checks
2025-03-26 13:05:37 +01:00
Chun-Hung Tseng e2b37cfae8 [Robustness test] improve append history checks
Reference:
- https://github.com/etcd-io/etcd/pull/19651#discussion_r2011549432

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-26 10:44:26 +01:00
joshjms c80e61792e markdown-lint: set line length checking to false
Add newline at the end of file

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-03-26 10:15:58 +08:00
joshjms 2514f03944 set ETCD_ROOT_DIR to root directory of git repository
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-03-26 10:15:58 +08:00
Benjamin Wang dedbb5160d
Merge pull request #19664 from ivanvc/changelog-github.com-golang-jwt-jwt
CHANGELOG: add note regarding github.com/golang-jwt/jwt version bump
2025-03-25 09:15:16 +00:00
Benjamin Wang 35d56cce0f
Merge pull request #19661 from etcd-io/dependabot/github_actions/actions/setup-go-5.4.0
build(deps): bump actions/setup-go from 5.3.0 to 5.4.0
2025-03-25 09:14:28 +00:00
Benjamin Wang 5c7b322817
Merge pull request #19660 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.13
build(deps): bump github/codeql-action from 3.28.11 to 3.28.13
2025-03-25 09:14:00 +00:00
Marek Siarkowicz dc56041835
Merge pull request #19651 from henrybear327/issue/19579_simple_fix
Patch the return time with MaxInt64 in robustness test
2025-03-25 09:32:22 +01:00
Benjamin Wang dfb9df419c
Merge pull request #19599 from Dogacel/dogac/fix-local-setup
development: fix 'make verify' errors in OSX
2025-03-25 07:47:13 +00:00
Ivan Valdes 3b9ee9bb2c
CHANGELOG: add note regarding github.com/golang-jwt/jwt version bump
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-24 17:08:21 -07:00
Chun-Hung Tseng 5ee55a69e0 Patch the return time with MaxInt64 in robustness test
Reference:
- https://github.com/etcd-io/etcd/issues/19579

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
Co-authored-by: Marek Siarkowicz <marek.siarkowicz@protonmail.com>
2025-03-25 00:53:56 +01:00
dependabot[bot] d6d6769afb
build(deps): bump actions/setup-go from 5.3.0 to 5.4.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](f111f3307d...0aaccfd150)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 18:40:17 +00:00
dependabot[bot] 26d537b33f
build(deps): bump github/codeql-action from 3.28.11 to 3.28.13
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.11 to 3.28.13.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](6bb031afdd...1b549b9259)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 18:39:28 +00:00
dependabot[bot] 92f8fa367a
build(deps): bump actions/upload-artifact from 4.6.1 to 4.6.2
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](4cec3d8aa0...ea165f8d65)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 18:39:01 +00:00
Benjamin Wang 1db0fc5818
Merge pull request #19616 from mmorel-35/testifier/tests/integration
chore: use testify instead of testing in tests/integration
2025-03-24 15:57:36 +00:00
Benjamin Wang baeb60ab82
Merge pull request #19634 from fuweid/introduce-new-way-to-setup-cluster
e2e: add upgrade test for clusters set up by promoted members
2025-03-24 15:45:46 +00:00
Benjamin Wang 473a5ffa05
Merge pull request #19650 from ahrtr/changelog_learner_20250324
Update 3.6 changelog for the fix to auto sync member in v3store
2025-03-24 15:09:39 +00:00
Wei Fu 211f9e52cb e2e: add upgrade test for clusters set up by promoted members
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-03-24 09:48:40 -04:00
Benjamin Wang f4a08f77d4 update 3.6 changelog for the fix to auto sync member in v3store
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-24 12:13:48 +00:00
Benjamin Wang 6b76999f51
Merge pull request #19639 from ivanvc/release-notes-set-3.5.20-date
CHANGELOG-3.5: Set v3.5.20 release date
2025-03-22 16:08:45 +00:00
Fu Wei 9c7ffc32f0
Merge pull request #19631 from joshjms/split-test-lib
Split `scripts/test_lib.sh`
2025-03-22 22:00:13 +08:00
Benjamin Wang fd4fc82d40
Merge pull request #19640 from ahrtr/cv_20250321
Returns the string representation of the `ClusterVersion`
2025-03-22 07:48:13 +00:00
Benjamin Wang ee2f4e0e9b return the string representative of the CurrentVersion value
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-21 22:00:06 +00:00
Ivan Valdes e55e55b1bb
CHANGELOG-3.5: Set v3.5.20 release date
Add entries from pull requests that were released.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-21 13:25:31 -07:00
Doğaç Eldenk a36e5bdfac development: fix 'make validate' errors in OSX
Currently local development workflow suggests running 'make verify' to
verify all checks pass before comitting. However, currently this check
fails in the main branch. Updated "scripts/test.sh" to download tools
"crawford/marker" and "koalaman/shellcheck" for the host OS and
architecture. Previously ARM MacOS devices were having errors while
running make verify because downloaded version of shellcheck was for
linux x86_64 architecture.

Signed-off-by: Doğaç Eldenk <dogacel@gmail.com>
2025-03-21 13:36:26 -05:00
Benjamin Wang 5e272463f7
Merge pull request #19637 from ahrtr/upgrade_refactor_20250321
minor refactor DowngradeUpgradeMembersByID to not block on waiting fo…
2025-03-21 18:33:04 +00:00
Benjamin Wang 29878cf735 minor refactor DowngradeUpgradeMembersByID to not block on waiting for member to be ready
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-21 17:09:02 +00:00
Benjamin Wang dc45df0cad
Merge pull request #19424 from ivanvc/remove-codecov-github-workflow
github/workflows: remove coverage workflow
2025-03-21 07:55:28 +00:00
Benjamin Wang fb53c4a376
Merge pull request #19625 from siyuanfoundation/doc
doc: update feature development guide.
2025-03-20 18:27:25 +00:00
joshjms 343b14ba06 source test_utils.sh
Signed-off-by: joshjms <joshjms1607@gmail.com>

fix: update comments

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-03-20 10:34:59 +08:00
joshjms cd077a806d refactor: split test_lib.sh into test_utils.sh for basic functionalities and test_lib.sh
Signed-off-by: joshjms <joshjms1607@gmail.com>

fix shell scripts

Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-03-20 10:34:59 +08:00
James Blair 53b88df4a7
Merge pull request #19632 from ArkaSaha30/deps_mgmt_17_03_25
[2025-03-17] Manual Dependency Bump
2025-03-20 09:06:30 +13:00
ArkaSaha30 495176a033
dependency: bump gotest.tools/gotestsum from 1.12.0 to 1.12.1
This commit will bump gotest.tools/gotestsum from 1.12.0 to 1.12.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-19 23:05:57 +05:30
ArkaSaha30 dd233b46cd
dependency: bump github.com/golangci/golangci-lint from 1.64.6 to 1.64.7
This commit will bump github.com/golangci/golangci-lint from 1.64.6 to 1.64.7

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-19 23:01:04 +05:30
ArkaSaha30 4ea0bb6e46
dependency: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc from 1.34.0 to 1.35.0
This commit will bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc from 1.34.0 to 1.35.0
Also, it bumps indirect dependency: go.opentelemetry.io/otel/exporters/otlp/otlptrace from 1.34.0 to 1.35.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-19 22:58:07 +05:30
ArkaSaha30 bb855eb570
dependency: bump golang.org/x/time from 0.10.0 to 0.11.0
This commit will bump golang.org/x/time from 0.10.0 to 0.11.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-19 22:42:14 +05:30
ArkaSaha30 2e568f6ff6
dependency: bump google.golang.org/grpc from 1.70.0 to 1.71.0
This commit will bump google.golang.org/grpc from 1.70.0 to 1.71.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-19 22:30:05 +05:30
Fu Wei 4aee7f109b
Merge pull request #19628 from henrybear327/devcontainer/drop-dev
Use go:1.24-bookworm for devcontainer
2025-03-20 00:08:25 +08:00
Chun-Hung Tseng 5eac5996f7 Use go:1.24-bookworm for devcontainer
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-19 08:10:52 +01:00
Siyuan Zhang 3a6b064da3 doc: update feature development guide.
Signed-off-by: Siyuan Zhang <sizhang@google.com>
2025-03-18 08:40:55 -07:00
Benjamin Wang 040e5ed65c
Merge pull request #19585 from ArkaSaha30/deps_mgmt_10_03_25
[2025-02-10] Manual Dependency Bump
2025-03-17 07:41:32 +00:00
Marek Siarkowicz b988791c8e
Merge pull request #19594 from ivanvc/rename-robustness-makefile
test/robustness: rename makefile.mk to Makefile
2025-03-16 12:59:27 +01:00
Marek Siarkowicz 2555efddbf
Merge pull request #19610 from henrybear327/robustness/fix_typo
Fix wrong error message in `loadKeyValueOperations`
2025-03-16 12:51:12 +01:00
Matthieu MOREL d05b8b7611 chore: use testify instead of testing in tests/integration
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-15 19:29:30 +01:00
Chun-Hung Tseng b692041b69 Fix wrong error message in `loadKeyValueOperations`
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-15 13:33:13 +01:00
Marek Siarkowicz f07e2ae4ed
Merge pull request #19609 from henrybear327/robustness/improve_readme
Update the robustness test README
2025-03-15 13:16:27 +01:00
Chun-Hung Tseng 49b4137746 Update the robustness test README
- wordsmithing
- fix broken links

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-15 10:42:03 +01:00
ArkaSaha30 40f21b203b
dependency: bump github.com/anishathalye/porcupine from v1.0.0 to v1.0.2
This commit will bump github.com/anishathalye/porcupine from v1.0.0 to v1.0.2

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-15 13:32:25 +05:30
Benjamin Wang a2eedb9093
Merge pull request #19582 from henrybear327/ci/update-devcontainer-1.24
Bump devcontainer version to 1.24
2025-03-15 07:43:52 +00:00
Benjamin Wang 5122d43d87
Merge pull request #19596 from mmorel-35/usetesting/tests/robustness
tests/robustness: address Go 1.24 usetesting issues
2025-03-14 17:30:04 +00:00
Benjamin Wang d100da7431
Merge pull request #19595 from mmorel-35/usetesting/tests/framework
tests/framework: address Go 1.24 usetesting issues
2025-03-14 17:29:51 +00:00
Benjamin Wang e31514dc84
Merge pull request #19593 from mmorel-35/usetesting/tests/e2e
tests/e2e: address Go 1.24 usetesting issues
2025-03-14 17:29:38 +00:00
Benjamin Wang 630fb0a43b
Merge pull request #19592 from mmorel-35/usetesting/tests/common
tests/common:  address Go 1.24 usetesting issues
2025-03-14 17:29:23 +00:00
Benjamin Wang c571cff478
Merge pull request #19591 from mmorel-35/usetesting/etcdutl
etcdutl: address Go 1.24 usetesting issues
2025-03-14 17:29:12 +00:00
Ivan Valdes be3eee2597
test/robustness: rename makefile.mk to Makefile
Allow to execute make targets from the tests/robustness directory.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-14 09:44:03 -07:00
Benjamin Wang 82a3e6fe27
Merge pull request #19603 from ahrtr/changelog_etcdctl_20250314
Update 3.5 changelog to cover the member promotion command not suppor…
2025-03-14 14:38:57 +00:00
Benjamin Wang c2701197fb Update 3.5 changelog to cover the member promotion command not support json output issue
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-14 13:03:06 +00:00
ArkaSaha30 aedecad09f
dependency: bump github.com/prometheus/client_golang from 1.21.0 to 1.21.1
This commit will bump github.com/prometheus/client_golang from 1.21.0 to 1.21.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-14 15:34:42 +05:30
ArkaSaha30 5eeacec087
dependency: bump github.com/alexfalkowski/gocovmerge from 1.4.0 to 1.6.0
This commit will bump github.com/alexfalkowski/gocovmerge from 1.4.0 to 1.6.0
As an indirect dependency it also bumps,
- golang.org/x/crypto from 0.35.0 to 0.36.0
- golang.org/x/net from 0.36.0 to 0.37.0
- golang.org/x/sync from 0.11.0 to 0.12.0
- golang.org/x/text from 0.22.0 to 0.23.0
- golang.org/x/mod from 0.23.0 to 0.24.0
- golang.org/x/term from 0.29.0 to 0.30.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-14 15:34:42 +05:30
ArkaSaha30 41cc8cd3f7
dependency: bump honnef.co/go/tools from 0.6.0 to 0.6.1
This commit will bump honnef.co/go/tools from 0.6.0 to 0.6.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-14 15:34:42 +05:30
ArkaSaha30 a72780654d
dependency: bump go.opentelemetry.io/otel/sdk from 1.34.0 to 1.35.0
This commit will bump go.opentelemetry.io/otel/sdk from 1.34.0 to 1.35.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-14 15:34:42 +05:30
ArkaSaha30 75742cf025
dependency: bump golang.org/x/sys from 0.30.0 to 0.31.0
This commit will bump golang.org/x/sys from 0.30.0 to 0.31.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-14 15:34:29 +05:30
Kieran Gorman 395a03843d mvcc: avoid double decrement of watcher gauge on close/cancel race
This occurs specifically when the watch is for a compacted revision, as there's
a possible interleaving of cancel/close that invokes the `cancelWatch` function
twice.

It's fairly difficult to provoke the race condition but it is possible to
observe on `main` the racing test can fail with a negative gauge:

```
$ go test ./...  -run TestNewWatcherCountGauge/compacted_watch,_close/cancel_race
--- FAIL: TestNewWatcherCountGauge (0.34s)
    watchable_store_test.go:86:  # HELP etcd_debugging_mvcc_watcher_total Total number of watchers.
         # TYPE etcd_debugging_mvcc_watcher_total gauge
        -etcd_debugging_mvcc_watcher_total -1
        +etcd_debugging_mvcc_watcher_total 0

FAIL
FAIL    go.etcd.io/etcd/server/v3/storage/mvcc  0.830s
?       go.etcd.io/etcd/server/v3/storage/mvcc/testutil [no test files]
FAIL
```

It seems as though it is partially expected for the cancel function to be
invoked multiple times and to handle that safely (i.e., the existing `ch == nil`
check) - the bug here is that in the `if/else if` branches it comes "too late",
and multiple invocations where `wa.compacted` is true will both decrement the
counter. Shifting the case up one ensures that we can't follow that decrement
branch multiple times.

In fact, it seems logically more sensible to put this `wa.ch == nil` case
_first_, as a guard for the function being invoked multiple times, but moving i
before the sync/unsynced watch set delete functions could have a greater
inadvertent functional impact (i.e., if we never deleted cancelled watches from
these sets it would presumably introduce a leak), so from an abundance of
caution I've made the smallest change I think will fix my issue.

Signed-off-by: Kieran Gorman <kieran@kjgorman.com>
2025-03-14 10:01:16 +00:00
Benjamin Wang 8b4c2cc11e
Merge pull request #19590 from mmorel-35/usetesting/server
server: address Go 1.24 usetesting issues
2025-03-14 09:24:35 +00:00
Benjamin Wang ce5620760b
Merge pull request #19589 from mmorel-35/usetesting/client
client: address Go 1.24 usetesting issues
2025-03-14 09:24:07 +00:00
Benjamin Wang a5bef1b837
Merge pull request #19572 from ahrtr/new_approver_20250311
Nominate @fuweid as a new approver
2025-03-13 22:07:02 +00:00
Matthieu MOREL d87cb88d57 tests/common: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 22:03:50 +01:00
Matthieu MOREL 175f18ee8e tests/framework: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 20:18:20 +01:00
Matthieu MOREL b92073d1cb tests/e2e: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 20:16:52 +01:00
Matthieu MOREL 2717859dab tests/robustness: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 20:11:57 +01:00
Matthieu MOREL 6c69b1a709 etcdutl: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 19:59:09 +01:00
Matthieu MOREL dc6db52c34 server: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 19:53:48 +01:00
Matthieu MOREL 3e207cfda0 client: address Go 1.24 usetesting issues
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-13 19:48:50 +01:00
ArkaSaha30 a3b17f5ba8
dependency: bump go.opentelemetry.io/otel from 1.34.0 to 1.35.0
This commit will bump go.opentelemetry.io/otel from 1.34.0 to 1.35.0
Also bumps,
- go.opentelemetry.io/otel/trace from 1.34.0 to 1.35.0
- go.opentelemetry.io/otel/metric from 1.34.0 to 1.35.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-13 14:45:35 +05:30
James Blair 05d57531e4
Merge pull request #19576 from ivanvc/client-pkg-go-1.24-usetesting-errors
client/pkg: address Go 1.24 usetesting issues
2025-03-13 20:20:02 +13:00
James Blair 6984bbe731
Merge pull request #19575 from ivanvc/pkg-go-1.24-usetesting-errors
pkg: address Go 1.24 usetesting issues
2025-03-13 20:19:42 +13:00
Chun-Hung Tseng 5eca42b3cf Bump devcontainer version to 1.24
According to the available image tag list [2],
the images for go 1.24 are all prefixed with
`dev-`. Thus, we are using the `dev-` prefixed
image version for now.

Reference:
[1] etcd-io#19524
[2] https://mcr.microsoft.com/v2/devcontainers/go/tags/list

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-03-12 21:43:39 +00:00
James Blair f4c40b7fd0
Merge pull request #19425 from Zanda256/tooling_markdown_lint
Tooling for markdown linting
2025-03-13 09:47:09 +13:00
Ivan Valdes 3f20b705fe
client/pkg: address Go 1.24 usetesting issues
Use the test package's provided Chdir function. Therefore, it's not
required to evaluate an error (it doesn't return one) or change
directories at the end.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-11 17:35:54 -07:00
Ivan Valdes 619d949b8d
pkg: address Go 1.24 usetesting issues
Replace Contexts with the one provided by the test package.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-11 16:50:13 -07:00
Benjamin Wang 4804c48d8b Nominate @fuweid as a new approver
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-11 09:57:02 +00:00
James Blair ffb6ff9acf
Merge pull request #19564 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.11
build(deps): bump github/codeql-action from 3.28.10 to 3.28.11
2025-03-11 17:40:30 +13:00
dependabot[bot] 6635bf633e
build(deps): bump github/codeql-action from 3.28.10 to 3.28.11
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.10 to 3.28.11.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](b56ba49b26...6bb031afdd)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 18:02:53 +00:00
Marek Siarkowicz 3c916bb258
Merge pull request #19554 from rsafonseca/fix_proxy_bug
fix: grpcproxy can get stuck in and endless loop causing high cpu usage
2025-03-10 10:17:08 +01:00
Benjamin Wang dc09500b8f
Merge pull request #19555 from ivanvc/remove-experimental-max-learners
server: remove ExperimentalMaxLearners
2025-03-10 09:16:24 +00:00
Matthieu MOREL d0dda55867 chore: enable unnecessary-stmt rule from revive
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-03-09 19:26:16 +01:00
Ivan Valdes 06edd83d28
server: remove ExperimentalMaxLearners
ExperimentalMaxLearners was introduced in v3.6, so there's no need to
worry about deprecating, it can be migrated straight into a FeatureGate.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-07 22:22:43 -08:00
Sekiranda f4e1d0e1bc
Add marckdowncli linting script, config file and makefile target to enable markdown linting
Signed-off-by: Sekiranda <sekirandahamza@gmail.com>
2025-03-07 16:35:02 +03:00
Marek Siarkowicz d0b8863552
Merge pull request #19552 from serathius/robustness-client-put-count
Use clientPutCount instead of persistedPutCount as not all client requests are persisted
2025-03-07 14:03:38 +01:00
Rafael da Fonseca 85d90d9dd9 fix: grpcproxy can get stuck in and endless loop causing high cpu usage
Signed-off-by: Rafael da Fonseca <rafael.fonseca@wildlifestudios.com>
2025-03-07 11:11:59 +00:00
Marek Siarkowicz 890990c32c Use clientPutCount instead of persistedPutCount as not all client requests are persisted
Signed-off-by: Marek Siarkowicz <siarkowicz@google.com>
2025-03-07 10:52:54 +01:00
Marek Siarkowicz 22b5b78530
Merge pull request #19383 from joshuazh-x/issue-19303
fix: skip duplicated puts when calculating put return time
2025-03-07 10:35:15 +01:00
Marek Siarkowicz 9f1709e015
Merge pull request #19546 from ivanvc/use-go-mod-instead-of-go-list-in-release-scripts
scripts/release: Use `go mod` instead of `go list`
2025-03-06 11:59:08 +01:00
Benjamin Wang 8e4de789e5
Merge pull request #19440 from ivanvc/bump-go-to-1.24.0
Bump go toolchain to 1.24.1
2025-03-06 07:51:04 +00:00
Ivan Valdes 7e66d3a9fc
scripts/release: Use `go mod` instead of `go list`
Replace `go list -m` with `go mod edit -json`, as the latter can return
the same information. This will be helpful when the project migrates to
using a Go workspace, as it will return the current module defined in
go.mod rather than all the modules from the current directory (using a
workspace, the top-level go.mod will return all the child modules from
the repository).

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 22:50:15 -08:00
James Blair 930bf4c41b
Merge pull request #19543 from ivanvc/update-changelog-v3.5.19-v3.6.0-rc.2
Update changelog with v3.5.19 v3.6.0-rc.2 release dates
2025-03-06 19:18:07 +13:00
Ivan Valdes 5dea90cc95
CHANGELOG: Set v3.6.0-rc.2 release date
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 11:57:09 -08:00
Ivan Valdes b88df6ea53
CHANGELOG: Set v3.5.19 release date
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 11:56:54 -08:00
Benjamin Wang f0a1ec501b
Merge pull request #19538 from fuweid/deflaky-TestCompactionHash-in-integration
deflakey: TestCompactionHash in integration
2025-03-05 18:56:07 +00:00
Ivan Valdes 7456d52dab
Disable usetesting linter
The linter fails with several warnings from new Go 1.24 functions. Due
to the amount of changed lines, it will be better to address them in
several follow-up pull requests.

> 146 files changed, 1157 insertions(+), 1212 deletions(-)

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 09:06:14 -08:00
Ivan Valdes 31650ab0c8
server: Fix TestLogRotation error message in Go 1.24
The embedded structure is now also part of the log message. The failure
from the tests is the following:

--- FAIL: TestLogRotation (0.00s)
    --- FAIL: TestLogRotation/invalid_logger_config (0.00s)
        config_test.go:868: test "invalid logger config", expected
        error: invalid log rotation config: json: cannot unmarshal
               bool into Go struct field logRotationConfig.maxsize
               of type int,
        got: invalid log rotation config: json: cannot unmarshal
             bool into Go struct field logRotationConfig.Logger.maxsize
             of type int
FAIL

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 09:05:57 -08:00
Ivan Valdes 028773129a
Bump go toolchain to 1.24.1
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-05 09:00:05 -08:00
Wei Fu b58e9f522f deflakey: TestCompactionHash in integration
We should use WithCompactPhysical to wait for compaction to finish,
because 50ms sleep can't guarantee compaction is done.

Based on the log, the defragment is finished before compaction, which is
not expected. This patch is to make sure compaction should be finished
before assertation.

```
=========================== defragment ==============
    logger.go:146: 2025-02-27T07:57:18.652Z	INFO	m0	finished defragment	{"member": "m0"}
=====================================================

    logger.go:146: 2025-02-27T07:57:18.652Z	INFO	m0	grpc service status changed	{"member": "m0", "service": "", "status": "SERVING"}
    logger.go:146: 2025-02-27T07:57:18.653Z	INFO	grpc	[[core] [Channel #1457]Channel Connectivity change to SHUTDOWN]
    logger.go:146: 2025-02-27T07:57:18.653Z	INFO	grpc	[[core] [Channel #1457]Closing the name resolver]
    logger.go:146: 2025-02-27T07:57:18.653Z	INFO	grpc	[[core] [Channel #1457]ccBalancerWrapper: closing]
    logger.go:146: 2025-02-27T07:57:18.653Z	INFO	grpc	[[core] [Channel #1457 SubChannel #1458]Subchannel Connectivity change to SHUTDOWN]
    logger.go:146: 2025-02-27T07:57:18.653Z	INFO	grpc	[[core] [Channel #1457 SubChannel #1458]Subchannel deleted]
    logger.go:146: 2025-02-27T07:57:18.654Z	INFO	grpc	[[transport] [client-transport 0xc00237bd48] Closing: rpc error: code = Canceled desc = grpc: the client connection is closing]
    logger.go:146: 2025-02-27T07:57:18.654Z	INFO	grpc	[[transport] [client-transport 0xc00237bd48] loopyWriter exiting with error: rpc error: code = Canceled desc = grpc: the client connection is closing]
    logger.go:146: 2025-02-27T07:57:18.654Z	INFO	grpc	[[transport] [server-transport 0xc0006bb520] Closing: EOF]
    logger.go:146: 2025-02-27T07:57:18.654Z	INFO	grpc	[[core] [Channel #1457]Channel deleted]
    logger.go:146: 2025-02-27T07:57:18.654Z	INFO	grpc	[[transport] [server-transport 0xc0006bb520] loopyWriter exiting with error: transport closed by client]
    hash.go:82:
        	Error Trace:	/home/prow/go/src/github.com/etcd-io/etcd/server/storage/mvcc/testutil/hash.go:82
        	            				/home/prow/go/src/github.com/etcd-io/etcd/server/storage/mvcc/testutil/hash.go:44
        	Error:      	Not equal:
        	            	expected: testutil.KeyValueHash{Hash:0x94694091, CompactRevision:1278, Revision:2507}
        	            	actual  : testutil.KeyValueHash{Hash:0x58af47dc, CompactRevision:2488, Revision:2507}

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -1,4 +1,4 @@
        	            	 (testutil.KeyValueHash) {
        	            	- Hash: (uint32) 2489925777,
        	            	- CompactRevision: (int64) 1278,
        	            	+ Hash: (uint32) 1487882204,
        	            	+ CompactRevision: (int64) 2488,
        	            	  Revision: (int64) 2507
        	Test:       	TestCompactionHash
        	Messages:   	hashes do not match on rev 2488
    cluster.go:1423: ========= Cluster termination started =====================
    logger.go:146: 2025-02-27T07:57:18.655Z	INFO	grpc	[[core] [Channel #1377]Channel Connectivity change to SHUTDOWN]
    logger.go:146: 2025-02-27T07:57:18.655Z	INFO	grpc	[[core] [Channel #1377]Closing the name resolver]
    logger.go:146: 2025-02-27T07:57:18.655Z	INFO	grpc	[[core] [Channel #1377]ccBalancerWrapper: closing]
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	grpc	[[core] [Channel #1377 SubChannel #1378]Subchannel Connectivity change to SHUTDOWN]
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	grpc	[[core] [Channel #1377 SubChannel #1378]Subchannel deleted]
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	grpc	[[transport] [client-transport 0xc0025f2248] Closing: rpc error: code = Canceled desc = grpc: the client connection is closing]
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	grpc	[[transport] [client-transport 0xc0025f2248] loopyWriter exiting with error: rpc error: code = Canceled desc = grpc: the client connection is closing]
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	grpc	[[transport] [server-transport 0xc000b56ea0] Closing: EOF]

=========================== compaction ==============
    logger.go:146: 2025-02-27T07:57:18.656Z	INFO	m0	finished scheduled compaction	{"member": "m0", "compact-revision": 2488, "took": "129.590742ms", "hash": 2489925777, "current-db-size-bytes": 40960, "current-db-size": "41 kB", "current-db-size-in-use-bytes": 40960, "current-db-size-in-use": "41 kB"}
=====================================================
```

Fixes: #19497

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-03-05 11:56:36 -05:00
James Blair 316991e8d1
Merge pull request #19523 from ArkaSaha30/deps_mgmt_5_2_25
[2025-02-03] Manual Dependency Bump
2025-03-05 23:32:30 +13:00
ArkaSaha30 31ff0a9cc8
dependency: bump github.com/rogpeppe/go-internal from v1.13.1 to v1.14.1
This commit will bump inderect dependency(of github.com/golangci/golangci-lint)  github.com/rogpeppe/go-internal from v1.13.1 to v1.14.1

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:52 +05:30
ArkaSaha30 b9ceba8c9f
dependency: bump golang.org/x/net from v0.35.0 to v0.36.0
This commit will bump dependency golang.org/x/net from v0.35.0 to v0.36.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:52 +05:30
ArkaSaha30 5da0dc0091
dependency: bump github.com/golangci/golangci-lint from 1.64.5 to 1.64.6
This commit will bump dependency github.com/golangci/golangci-lint from 1.64.5 to 1.64.6

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:52 +05:30
ArkaSaha30 04710062d1
dependency: bump github.com/prometheus/client_golang from 1.20.5 to 1.21.0
This commit will bump dependency github.com/prometheus/client_golang from 1.20.5 to 1.21.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:52 +05:30
ArkaSaha30 7c866508ef
dependency: bump github.com/klauspost/compress from 1.17.9 to 1.18.0
This commit will bump dependency github.com/klauspost/compress from 1.17.9 to 1.18.0
which is an indirect dependency of the direct dependency: github.com/prometheus/client_golang

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:52 +05:30
ArkaSaha30 fa3dca3f41
dependency: bump github.com/google/go-cmp from 0.6.0 to 0.7.0
This commit will bump dependency github.com/google/go-cmp from 0.6.0 to 0.7.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:43 +05:30
ArkaSaha30 a9b24c6523
dependency: bump golang.org/x/crypto from 0.33.0 to 0.35.0
This commit will bump dependency golang.org/x/crypto from 0.33.0 to 0.35.0

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:42 +05:30
ArkaSaha30 ceb11b7ce9
dependency: bump github.com/cheggaaa/pb/v3 from 3.1.6 to 3.1.7
This commit will bump dependency github.com/cheggaaa/pb/v3 from 3.1.6 to 3.1.7

Signed-off-by: ArkaSaha30 <arkasaha30@gmail.com>
2025-03-05 13:10:42 +05:30
Benjamin Wang e69f9c78ac
Merge pull request #19532 from ivanvc/update-changelog
Update CHANGELOGs with recent merged pull requests
2025-03-05 07:13:30 +00:00
Benjamin Wang bf9d6f588c
Merge pull request #19520 from ivanvc/add-verity-released-assets-github-workflow
Add verify release assets GitHub workflow
2025-03-05 07:09:26 +00:00
Ivan Valdes fa9233bbbc
Update CHANGELOGs with recent merged pull requests
Include notes from:

v3.4:
- #19529
- #19533

v3.5:
- #19528
- #19530

v3.6:
- #19495
- #19527
- #19531
- #19522

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-04 21:29:06 -08:00
Ivan Valdes 215ab98a5f
Add verify released binary assets GitHub workflow
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-03-04 15:23:02 -08:00
Benjamin Wang 3d381537cc
Merge pull request #19521 from ahrtr/curl_watch_20250304
Fix the issue of etcdserver crashing on receiving REST watch stream requests
2025-03-04 19:52:50 +00:00
Benjamin Wang d23b0785c1 ensure google.golang.org/genproto/googleapis/rpc version consistent
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-04 18:14:13 +00:00
Benjamin Wang 9fcb5f6ae4 re-generate api/etcdserverpb/gw/rpc.pb.gw.go
Executed ./scripts/genproto.sh

Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-04 18:08:28 +00:00
Benjamin Wang e2459c0323 Bump grpc-gateway to v2.26.3
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-04 18:00:03 +00:00
Benjamin Wang 65691111dc Create an e2e test to reproduce the issue of etcdserver crashing on REST watch requests
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-03-04 14:00:25 +00:00
Benjamin Wang 2f15f0859f
Merge pull request #19517 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.10
build(deps): bump github/codeql-action from 3.28.9 to 3.28.10
2025-03-04 13:19:27 +00:00
Benjamin Wang 4523ff77c9
Merge pull request #19518 from etcd-io/dependabot/github_actions/ossf/scorecard-action-2.4.1
build(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.1
2025-03-04 13:13:28 +00:00
Benjamin Wang edfb9b7565
Merge pull request #19519 from etcd-io/dependabot/github_actions/actions/upload-artifact-4.6.1
build(deps): bump actions/upload-artifact from 4.6.0 to 4.6.1
2025-03-04 13:12:54 +00:00
dependabot[bot] 7c7f69e35a
build(deps): bump actions/upload-artifact from 4.6.0 to 4.6.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](65c4c4a1dd...4cec3d8aa0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 17:45:21 +00:00
dependabot[bot] 25d8e7fb40
build(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.1
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](62b2cac7ed...f49aabe0b5)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 17:45:18 +00:00
dependabot[bot] f9c68849ab
build(deps): bump github/codeql-action from 3.28.9 to 3.28.10
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.9 to 3.28.10.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](9e8d0789d4...b56ba49b26)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 17:45:14 +00:00
Benjamin Wang 4ef3b376b7
Merge pull request #19358 from ivanvc/remove-release-tests-workflow
github workflows: remove release tests
2025-03-03 09:38:36 +00:00
Benjamin Wang e99f20a639
Merge pull request #19504 from tcchawla/fix-19500
tests: deflakey TestLeaseGrantKeepAliveOnce
2025-03-03 09:36:10 +00:00
tcchawla 3e43e4594e tests: deflakey TestLeaseGrantKeepAliveOnce
Signed-off-by: tcchawla <tc.chawla2000@gmail.com>
2025-03-02 16:53:54 +05:30
Ivan Valdes 4ce48cea70
Enable uploading coverage report from Prow
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-28 17:18:44 -08:00
Ivan Valdes b16bd864ef
tools: Implement rw-benchmark line charts
Add a new line chart to plot the results from the rw-benchmarks.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-28 16:24:04 -08:00
Ivan Valdes ed975c2677
github workflows: remove release tests
This workflow has already been migrated to the prow infrastructure as a
presubmit job.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-27 23:45:32 -08:00
Benjamin Wang 3a2cece119
Merge pull request #19502 from ah8ad3/changelog_v3.7
Add change log 3.7
2025-02-28 07:31:49 +00:00
Ahmad Zolfaghari a6b3c93cb4 Add UsageFunc to deprecation section in 3.7 changelog.
Signed-off-by: Ahmad Zolfaghari <ah8ad3@gmail.com>
2025-02-27 20:29:16 +03:30
Benjamin Wang 5c147c0144
Merge pull request #19498 from ashikjm/typo-fix
etcdserver: Fixing minor typos in v3election.proto and rpc.proto
2025-02-27 15:47:30 +00:00
Benjamin Wang 9b31bdc7a8
Merge pull request #19496 from ivanvc/remove-grpcproxy-workflows
github/workflows: delete grpcproxy workflow
2025-02-27 14:50:20 +00:00
Marek Siarkowicz ac064e860c
Merge pull request #19470 from beforetech/main
refactor: use a more straightforward return value
2025-02-27 13:39:58 +01:00
Benjamin Wang b9298ed950
Merge pull request #18356 from ah8ad3/move-cobra-from-pkg
etcdctl: move cobra helper of etcdctl from main pkg to etcdctl pkg
2025-02-27 12:21:40 +00:00
Ashik J M f5409c4227 etcdserver: Fixing minor typos in v3election.proto and rpc.proto
Signed-off-by: Ashik J M <ashikjm@gmail.com>
2025-02-27 17:50:02 +05:30
ah8ad3 d42b0434a6 Copy cobra helper of etcdctl from main pkg to etcdctl pkg and add a deprecation note for UsageFunc.
Signed-off-by: ah8ad3 <ah8ad3@gmail.com>
2025-02-27 14:46:43 +03:30
Benjamin Wang a423349c07
Merge pull request #19488 from mmorel-35/golangci-lint/usetesting
chore: use usetesting instead of tenv
2025-02-27 07:50:17 +00:00
Ivan Valdes b1ecb206b4
github/workflows: delete grpcproxy workflow
This job is already running on the Prow infrastructure.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-26 22:26:24 -08:00
Benjamin Wang 49fbd1ef95
Merge pull request #19452 from gangli113/featuregate
Add prometheus metric for server feature gate
2025-02-26 21:34:11 +00:00
Gang Li d76671ca80 add prometheus metric
Signed-off-by: Gang Li <ganglica@google.com>
Signed-off-by: Gang Li <gangligit@gmail.com>
2025-02-26 10:37:08 -08:00
Benjamin Wang 6ecb6fba34
Merge pull request #19486 from ivanvc/address-govet-1.24-errors
Address Go 1.24 govet errors
2025-02-26 12:17:21 +00:00
Matthieu MOREL a8d8c1887f chore: use usetesting instead of tenv
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-02-26 07:54:22 +01:00
Ivan Valdes 16b1460b5d
Address Go 1.24 govet errors
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-25 17:10:56 -08:00
Benjamin Wang 47e764fd6b
Merge pull request #19484 from jmhbnz/main
Add release date for `v3.4.36` and `v3.6.0-rc.1`
2025-02-25 20:57:00 +00:00
James Blair 99683d59ac
Add release date for v3.6.0-rc.1.
Signed-off-by: James Blair <mail@jamesblair.net>
2025-02-26 08:59:38 +13:00
James Blair db2213b70a
Add release date for v3.4.36.
Signed-off-by: James Blair <mail@jamesblair.net>
2025-02-26 08:59:11 +13:00
Benjamin Wang 66748c0d46
Merge pull request #19463 from ivanvc/use-go-mod-in-deps-check
scripts: Use go mod instead of go list to get dependencies
2025-02-25 19:37:06 +00:00
Benjamin Wang 3763a67606
Merge pull request #19479 from ivanvc/release-note-CVE-2025-22869
changelog: add note from CVE-2025-22869
2025-02-25 18:26:20 +00:00
Benjamin Wang 4a9ab7c380
Merge pull request #19473 from ahrtr/test_lease_20250224
Fix flaky `TestLeaseKeepAliveOneSecond`
2025-02-25 18:23:06 +00:00
Benjamin Wang 78a7ca618e
Merge pull request #19466 from henrybear327/dependency/2025_02_22
[2025-02-22] Bump dependency updates identified by dependabot
2025-02-25 18:00:53 +00:00
Ivan Valdes 48fcef5b47
changelog: add note from CVE-2025-22869
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-25 09:28:53 -08:00
Chun-Hung Tseng 6784151a1b dependency: bump github.com/golangci/golangci-lint from 1.63.4 to 1.64.5
Reference:
- https://github.com/etcd-io/etcd/pull/19435

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-25 14:01:36 +00:00
Chun-Hung Tseng df26009e75 dependency: bump github.com/alexfalkowski/gocovmerge from 1.3.18 to 1.4.0
Reference:
- https://github.com/etcd-io/etcd/pull/19436

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-25 14:01:36 +00:00
Chun-Hung Tseng 5e89197c28 dependency: bump honnef.co/go/tools from 0.5.1 to 0.6.0 and bump golang.org/x/net from 0.34.0 to 0.35.0
Reference:
- https://github.com/etcd-io/etcd/pull/19434
= https://github.com/etcd-io/etcd/pull/19437

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-25 14:01:35 +00:00
Chun-Hung Tseng f1af8b9e92 dependency: bump github.com/spf13/cobra from 1.8.1 to 1.9.1
Reference:
- https://github.com/etcd-io/etcd/pull/19438

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-25 14:01:35 +00:00
Benjamin Wang 8e44d3ac65
Merge pull request #19476 from fuweid/fix-17504
tests: deflakey TestLeaseGrantTimeToLiveExpired
2025-02-25 09:40:19 +00:00
Benjamin Wang 6d66d828b4
Merge pull request #19475 from henrybear327/ci/address_linter_issues
Address issues reported by golangci-lint after bumping the version to v1.64.5
2025-02-25 08:01:14 +00:00
Benjamin Wang 628435abdb
Merge pull request #19474 from fuweid/update-36-changelog
CHANGELOG: update 3.6 changelog with DowngradeInfo
2025-02-25 07:58:44 +00:00
Wei Fu c81fb870bb tests: deflakey TestLeaseGrantTimeToLiveExpired
The following change can reproduce the issue #17504 by
`TESTCASE=TestLeaseGrantTimeToLiveExpired/PeerAutoTLS make test-e2e`. We
can retry it to reduce flakey possibility, if there is leader change.

```diff
diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go
index afb27c330..dea8459dc 100644
--- a/tests/common/lease_test.go
+++ b/tests/common/lease_test.go
@@ -16,6 +16,7 @@ package common

 import (
        "context"
+       "sync"
        "testing"
        "time"

@@ -139,6 +140,18 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) {
                                require.NoError(t, err)
                                require.Equal(t, int64(1), getResp.Count)

+                               var wg sync.WaitGroup
+                               defer wg.Wait()
+
+                               wg.Add(1)
+                               go func() {
+                                       defer wg.Done()
+                                       time.Sleep(1000 * time.Millisecond)
+                                       clus.(interface {
+                                               MoveLeader(ctx context.Context, t testing.TB, i int) error
+                                       }).MoveLeader(ctx, t, (clus.WaitLeader(t)+1)%len(clus.Members()))
+                               }()
+
                                time.Sleep(3 * time.Second)

                                ttlResp, err := cc.TimeToLive(ctx, leaseResp.ID, config.LeaseOption{})

```

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-24 18:09:06 -05:00
Benjamin Wang 498bbc5982
Merge pull request #19472 from etcd-io/wenjiaswe-patch-2
Add release team leads and additional release team members
2025-02-24 21:47:03 +00:00
Chun-Hung Tseng 43df62f6b9 Address issues reported by golangci-lint after bumping the version to v1.64.5
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-24 21:35:34 +00:00
Wei Fu a081904832 CHANGELOG: update 3.6 changelog with DowngradeInfo
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-24 16:15:57 -05:00
Benjamin Wang 4cef06bad9 Fix flaky TestLeaseKeepAliveSeconds
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-24 14:23:36 +00:00
Wenjia d83346bfe7
Add release leads and additional team members.
Thanks to @jmhbnz and @ivanvc 's long time leadership in the release team, adding them as official leads.

Also adding @siyuanfoundation and @fuweid as additional team members. 

Thanks everyone for your contribution!
2025-02-23 22:05:26 -08:00
beforetech f954f76012 refactor: use a more straightforward return value
Signed-off-by: beforetech <mail@before.tech>
2025-02-23 23:36:06 +08:00
Benjamin Wang 022b9b22cf
Merge pull request #19446 from ashikjm/18267-issue
etcdserver: Update description for count field in the RangeResponse message
2025-02-23 09:28:48 +00:00
Benjamin Wang d52bd901b4
Merge pull request #19461 from fuweid/fix-downgrade-issue
deflake: TestDowngradeCancellationAfterDowngrading1InClusterOf3
2025-02-22 15:37:46 +00:00
Wei Fu 2de17bd396 deflake: TestDowngradeCancellationAfterDowngrading1InClusterOf3
Fixes: 65159a2b96 (*: Update cases related to Downgrade)

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-22 08:22:17 -05:00
Ivan Valdes cbc14d78e6
scripts: Use go mod instead of go list to get dependencies
Replace `go list -m` with `go mod edit -json`, as the latter can return
the same information. This will be helpful when the project migrates to
using a Go workspace, as it will return the current module defined in
go.mod rather than all the modules from the current directory (using a
workspace, the top-level go.mod will return all the child modules from
the repository).

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-21 20:48:15 -08:00
Benjamin Wang ac7d3e9335
Merge pull request #19451 from fuweid/add-downgrade-status
*: support DowngradeInfo field in maintenence.Status API
2025-02-21 21:02:20 +00:00
Wei Fu 65159a2b96 *: Update cases related to Downgrade
1. Update DowngradeUpgradeMembersByID

If it's downgrading process, the desire version of cluster should be
target one.
If it's upgrading process, the desire version of cluster should be
determined by mininum binary version of members.

2. Remove AssertProcessLogs from DowngradeEnable

The log message "The server is ready to downgrade" appears only when the storage
version monitor detects a mismatch between the cluster and storage versions.

If traffic is insufficient to trigger a commit or if an auto-commit occurs right
after reading the storage version, the monitor may fail to update it, leading
to errors like:

```bash
"msg":"failed to update storage version","cluster-version":"3.6.0",
"error":"cannot detect storage schema version: missing confstate information"
```

Given this, we should remove the AssertProcessLogs statement.

Similar to #19313

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-21 13:45:41 -05:00
Wei Fu 091b6ed718 etcdctl: support downgrade info in endpoint command
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-21 11:50:25 -05:00
Ashik J M 97c63c9fde etcdserver: Update description for count field in the RangeResponse message
To highlight that it doesn't honour the limit and filters (Min or Max, Create or Modify, Revisions)

Signed-off-by: Ashik J M <ashikjm@gmail.com>
2025-02-21 21:05:26 +05:30
huangzw 8ce740cb26 chore: adjust import order
Signed-off-by: huangzw <huangzw@2345.com>
2025-02-21 17:07:17 +08:00
huangzw 1c7f0062fc chore: adjust import order
Signed-off-by: huangzw <huangzw@2345.com>
2025-02-21 15:52:48 +08:00
huangzw 68c2fae46a chore: remove unused and deprecated func `GetEffectiveNodeIdsFromWalEntries`
Signed-off-by: huangzw <huangzw@2345.com>
2025-02-21 15:50:11 +08:00
Joshua Zhang 6f86f4fbb0 fix: skip duplicated puts when calculating put return time
Signed-off-by: Joshua Zhang <joshua.x.zhang@gmail.com>
2025-02-21 03:25:23 +00:00
adeyemi f312736892 Disable revive for NewMembershipBackend to fix unexported-return
Signed-off-by: adeyemi <adeyemi.aladesawe@gmail.com>
2025-02-20 10:30:15 -08:00
Benjamin Wang 49f34c9751
Merge pull request #19340 from aladesawe/server-apply-unexported-return
Rename `applierMembership` to `ApplierMembership` to fix the `unexported-return` lint error
2025-02-20 09:28:54 +00:00
Benjamin Wang 82c371a471
Merge pull request #19341 from aladesawe/server-storage-recorder-unexported-return
Rename `storageRecorder` to `StorageRecorder` to fix `unexported-return` lint error
2025-02-20 09:28:27 +00:00
Benjamin Wang a29b97ab8c
Merge pull request #19450 from jmhbnz/main
Simplify release permissions process
2025-02-20 08:39:32 +00:00
Wei Fu 8575de3bab v3rpc: add DowngradeInfo in status API
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-19 17:18:08 -05:00
Wei Fu 9d57554c4c proto: add DowngradeProcessInfo in statusResponse
Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-02-19 17:17:59 -05:00
James Blair cf6f4fbb94
Simplify release permissions process.
Signed-off-by: James Blair <mail@jamesblair.net>
2025-02-20 08:16:53 +13:00
Benjamin Wang ef65923cf7
Merge pull request #19431 from joshjms/main
Update CHANGELOG for version bump to go 1.23.6
2025-02-19 08:01:24 +00:00
Benjamin Wang deb9178089
Merge pull request #19342 from aladesawe/server-alarm-unexported-return
Move interface `AlarmBackend` from `server/etcdserver/api/v3alarm` to `server/storage/schema` to fix the `unexported-return` lint error
2025-02-18 17:58:03 +00:00
Marek Siarkowicz 1e3710a90f
Merge pull request #19432 from 1911860538/feat/server-lease
perf: use RLock in Demoted method for read-only access to expiry
2025-02-18 09:14:20 +01:00
huangzw e10f01edfe perf: use RLock in Demoted method for read-only access to expiry
Signed-off-by: huangzw <huangzw@2345.com>
2025-02-17 16:09:34 +08:00
joshjms d86775c276 changelog: update entries for v3.4.36 and v3.5.19 to reflect 1.23.6 update
Signed-off-by: joshjms <joshjms1607@gmail.com>
2025-02-17 14:44:14 +08:00
adeyemi e37cdc66c4 Rename applierMembership struct to fix unexported-return
Signed-off-by: adeyemi <adeyemi.aladesawe@gmail.com>
2025-02-16 21:35:18 -08:00
adeyemi 6f27da2aee Move AlarmBackend interface to fix unexported-return
Signed-off-by: adeyemi <adeyemi.aladesawe@gmail.com>
2025-02-16 21:22:53 -08:00
adeyemi c0c9f7c344 Create an StorageRecorder interface to fix unexported-return
Signed-off-by: adeyemi <adeyemi.aladesawe@gmail.com>
2025-02-16 21:02:19 -08:00
Benjamin Wang eb7607bd8b
Merge pull request #19421 from ivanvc/remove-contrib-mixin-github-workflow
github/workflows: remove contrib workflow
2025-02-16 16:05:43 +00:00
Marek Siarkowicz c86bb08fa9
Merge pull request #19422 from ivanvc/remove-fuzzing-github-workflow
github/workflows: remove fuzzing workflow.
2025-02-16 12:06:09 +01:00
Ivan Valdes 189eb92e3c
github/workflows: remove coverage workflow
This workflow has already been migrated to the Prow infrastructure.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-15 14:47:43 -08:00
Ivan Valdes c733872ea3
github/workflows: remove fuzzing workflow.
This job is already running in the Prow infrastructure.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-14 14:13:23 -08:00
Ivan Valdes 0bbc42a3de
github/workflows: remove contrib workflow
This job is already running in the Prow infrastructure.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-14 14:10:02 -08:00
Benjamin Wang 14cf6694e9
Merge pull request #19418 from ivanvc/fix-release-script-prerelease-github-template-release
Fix release script prerelease GitHub template release
2025-02-14 19:20:32 +00:00
Ivan Valdes 5c9db9c840
scripts/release: fix typo in "flag"
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-14 09:23:08 -08:00
Ivan Valdes b1e513cfe9
scripts/release: fix getting version minor for prereleases
The GitHub release templates had the wrong version minor when there's a
prerelease part in the version (i.e., v3.6.0-rc.0). It cut until the
last dot, leaving a wrong minor version (i.e., v3.6.0-rc).

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-14 09:23:06 -08:00
Ivan Valdes 8c52b414f3
CHANGELOG-3.6: Set v3.6.0-rc.0 release date
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-13 12:36:25 -08:00
Benjamin Wang 91762ccd4f
Merge pull request #19413 from henrybear327/feat/add_flag
Migrate --experimental-set-member-localaddr to using feature flag
2025-02-13 17:08:06 +00:00
Chun-Hung Tseng 5fa8c1f6b8 Migrate --experimental-set-member-localaddr to using feature flag
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
Co-authored-by: Benjamin Wang <benjamin.wang@broadcom.com>
2025-02-13 16:02:10 +00:00
Marek Siarkowicz 865ed4a0b6
Merge pull request #19412 from ahrtr/changelog_20250213
Add the fix of the performance regression due to uncertain compaction…
2025-02-13 13:31:30 +01:00
Benjamin Wang fb2cdc31c7 Add the fix of the performance regression due to uncertain compaction sleep interval
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-13 11:03:09 +00:00
Benjamin Wang 3bd966d6b5
Merge pull request #19410 from ahrtr/compact_20250213
Fix a performance regression due to uncertain compaction sleep interval
2025-02-13 10:36:58 +00:00
Benjamin Wang de10fd6565 Fix a peformance regression due to uncertain compaction sleep interval
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-13 09:40:04 +00:00
Benjamin Wang 075fb1058a
Merge pull request #19407 from ivanvc/changelog-3.6-19403-deprecation
CHANGELOG-3.6: Add note from #19404
2025-02-13 07:55:18 +00:00
Benjamin Wang b77a28cbb5
Merge pull request #19408 from ivanvc/more-v3.6-deprecation-comments
Fix more v3.6 deprecation comments
2025-02-13 07:51:33 +00:00
Ivan Valdes 8af64f886c
CHANGELOG-3.6: Add note from #19404
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 17:06:16 -08:00
Ivan Valdes 9c30af2ff5
Standardize help deprecated messages
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 16:29:40 -08:00
Ivan Valdes eea79ca9a5
Properly deprecate ExperimentalInitialCorruptCheck
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 16:14:34 -08:00
Ivan Valdes fe81901c74
Properly deprecate ExperimentalStopGRPCServiceOnDefrag
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 16:03:07 -08:00
Ivan Valdes e37615a483
Properly deprecate ExperimentalTxnModeWriteWithSharedBuffer
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 15:57:57 -08:00
Benjamin Wang 7073c4140f
Merge pull request #19403 from ivanvc/remove-server-deprecated-new-zap-core-logger-builder
server: Remove deprecated NewZapCoreLoggerBuilder
2025-02-12 21:22:52 +00:00
Ivan Valdes 8b99f8e025
server/embed: Remove deprecated NewZapCoreLoggerBuilder
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 11:20:50 -08:00
Benjamin Wang dd6791c560
Merge pull request #19401 from ivanvc/fix-deprecation-notices
Fix v3.6 deprecation notices
2025-02-12 19:10:47 +00:00
Ivan Valdes 1f4b3cdf52
Fix deprecation comments in server/features
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 10:05:52 -08:00
Ivan Valdes 7ba8929e7b
Fix deprecation comments in server/embed
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 10:05:03 -08:00
Ivan Valdes 95efe44ae0
Fix rpctypes.ErrClusterIdMismatch deprecation comment
It was pointing to ErrGRPCClusterIDMismatch rather than
ErrClusterIDMismatch.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-12 10:02:33 -08:00
Benjamin Wang f30cbaac11
Merge pull request #19398 from ahrtr/downgrade_test_20250212
[test] Correct the expected version in downgrade test case
2025-02-12 15:56:47 +00:00
Benjamin Wang 57dc6f375a Correct the expected version in downgrade test case
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-12 11:02:48 +00:00
Marek Siarkowicz c0e7e8c873
Merge pull request #19370 from shashwat010/visualize
Remove passing of anonymous visualize function
2025-02-12 10:45:14 +01:00
shashwat-jain 5414dbab4a Merge remote-tracking branch 'etcd/main' into visualize 2025-02-12 11:36:26 +05:30
shashwat-jain 1709422e21 Remove passing of anonymous visualize function
Signed-off-by: shashwat-jain <shashwat.jain@salesforce.com>
2025-02-12 11:26:10 +05:30
Benjamin Wang fefce5498f
Merge pull request #19386 from ivanvc/release-3.4-changelog-19197
CHANGELOG-3.4: Add entry from #19197
2025-02-11 22:13:03 +00:00
Benjamin Wang 0dfc7ab52c
Merge pull request #19388 from ahrtr/refactor_20250211
Minor refacotr on the e2e test framework
2025-02-11 22:00:27 +00:00
Benjamin Wang 5703e6b387 Minor refacotr on the e2e test framework
Also resolved the review comment in https://github.com/etcd-io/etcd/pull/19352

Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-11 20:32:21 +00:00
Benjamin Wang 53d44f0f9c
Merge pull request #19352 from ajaysundark/migrate-experimental-snapshot-catch-up-entries
migrate experimental-snapshot-catchup-entries flag to snapshot-catchup-entries
2025-02-11 20:15:17 +00:00
Ajay Sundar Karuppasamy 5802231328 migrate experimental-snapshot-catchup-entries flag to snapshot-catchup-entries
Signed-off-by: Ajay Sundar Karuppasamy <ajaysundar@google.com>
2025-02-11 19:17:17 +00:00
Benjamin Wang f197f44537
Merge pull request #19385 from ahrtr/tracing_20250211
Migrate experimental distributed tracing flags to non-experimental flags
2025-02-11 18:04:28 +00:00
Ivan Valdes b746159a22
CHANGELOG-3.4: Add entry from #19197
Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-11 09:32:01 -08:00
Benjamin Wang a9b8cba602 Migrate experimental distributed tracing flags to non-experimental flags
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
2025-02-11 15:29:16 +00:00
Benjamin Wang 1ea4f435cc
Merge pull request #19381 from henrybear327/dependency/2025_02_10
[2025-02-10] Bump dependency updates identified by dependabot
2025-02-11 07:50:59 +00:00
Benjamin Wang ad3301099a
Merge pull request #19350 from aladesawe/server-wal-version-unexported-return
Migrate WALVersion to fix unexported-return of walVersion
2025-02-10 21:42:13 +00:00
Benjamin Wang fa2926adb0
Merge pull request #19375 from etcd-io/dependabot/github_actions/github/codeql-action-3.28.9
build(deps): bump github/codeql-action from 3.28.8 to 3.28.9
2025-02-10 21:27:41 +00:00
Chun-Hung Tseng 04cce9759b dependency: bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.26.0 to 2.26.1, bump google.golang.org/genproto/googleapis/rpc from v0.0.0-20250115164207-1a7da9e5054f to v0.0.0-20250204164813-702378808489, and google.golang.org/protobuf from v1.36.4 to v1.36.5
Reference:
- https://github.com/etcd-io/etcd/pull/19374
- https://github.com/etcd-io/etcd/pull/19380

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Chun-Hung Tseng b31311ebb0 dependency: bump golang.org/x/crypto from 0.32.0 to 0.33.0 and bump golang.org/x/text from 0.21.0 to 0.22.0
Reference:
- https://github.com/etcd-io/etcd/pull/19378
- https://github.com/etcd-io/etcd/pull/19379

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Chun-Hung Tseng 2cffac9916 dependency: bump golang.org/x/time from 0.9.0 to 0.10.0
Reference:
- https://github.com/etcd-io/etcd/pull/19377

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Chun-Hung Tseng ab88026649 dependency: bump golang.org/x/sys from 0.29.0 to 0.30.0
Reference:
- https://github.com/etcd-io/etcd/pull/19376

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Chun-Hung Tseng 2908d45333 dependency: bump gotest.tools/v3 from 3.5.1 to 3.5.2
Reference:
- https://github.com/etcd-io/etcd/pull/19373

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Chun-Hung Tseng 948a464f16 dependency: bump github.com/google/yamlfmt from 0.15.0 to 0.16.0
Reference:
- https://github.com/etcd-io/etcd/pull/19372

Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
2025-02-10 21:20:45 +00:00
Marek Siarkowicz e499f01400
Merge pull request #19364 from ivanvc/improve-coverage-upload
codecov: improve coverage upload
2025-02-10 20:01:40 +01:00
dependabot[bot] 097be8cff3
build(deps): bump github/codeql-action from 3.28.8 to 3.28.9
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.8 to 3.28.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](dd746615b3...9e8d0789d4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 17:44:33 +00:00
Benjamin Wang 38bb52acd3
Merge pull request #19367 from henrybear327/e2e/fix_downgrade_node_election_log
Fix a log formatting bug in the e2e downgrade tests
2025-02-10 11:51:41 +00:00
Chun-Hung Tseng 89dd13f93b Fix a log formatting bug in the e2e downgrade tests
Signed-off-by: Chun-Hung Tseng <henrytseng@google.com>
Co-authored-by: Benjamin Wang <benjamin.wang@broadcom.com>
2025-02-10 10:44:25 +00:00
adeyemi 94758c1760 Migrate WALVersion, and reuse in schema.go
Signed-off-by: adeyemi <adeyemi.aladesawe@gmail.com>
2025-02-07 17:48:10 -08:00
Ivan Valdes 6c866548dc
codecov: improve coverage upload
Align running the code coverage upload with other workflows by
executing it from a Makefile target.

Update the current GitHub workflow to call this new target.

Signed-off-by: Ivan Valdes <ivan@vald.es>
2025-02-07 14:21:26 -08:00
480 changed files with 15135 additions and 15522 deletions

View File

@ -3,7 +3,7 @@
{
"name": "Go",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/go:1.23-bookworm",
"image": "mcr.microsoft.com/devcontainers/go:1.24-bookworm",
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},

View File

@ -10,7 +10,7 @@ body:
label: Bug report criteria
description: Please confirm this bug report meets the following criteria.
options:
- label: This bug report is not security related, security issues should be disclosed privately via [etcd maintainers](mailto:etcd-maintainers@googlegroups.com).
- label: This bug report is not security related, security issues should be disclosed privately via security@etcd.io.
- label: This is not a support request or question, support requests or questions should be raised in the etcd [discussion forums](https://github.com/etcd-io/etcd/discussions).
- label: You have read the etcd [bug reporting guidelines](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/reporting_bugs.md).
- label: Existing open issues along with etcd [frequently asked questions](https://etcd.io/docs/latest/faq) have been checked and this is not a duplicate.

56
.github/stale.yml vendored
View File

@ -1,56 +0,0 @@
---
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 90
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 21
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- "stage/tracked"
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

106
.github/workflows/antithesis-test.yml vendored Normal file
View File

@ -0,0 +1,106 @@
---
name: Build and trigger Antithesis exploration
on:
# Disabled as discussed in https://github.com/etcd-io/etcd/pull/19750#issuecomment-2809840402
# pull_request:
# branches: [main]
# schedule:
# - cron: "0 0 * * *" # run every day at midnight
workflow_dispatch:
inputs:
test:
description: 'Test name'
required: false
default: 'etcd nightly antithesis run'
type: string
duration:
description: 'Duration (exploration hours)'
required: true
type: int
default: 12
description:
description: 'Description (avoid quotes, please!)'
required: true
type: string
default: "etcd nightly antithesis run"
etcd_ref:
description: 'etcd version to build etcd-server from'
required: false
type: string
default: 'release-3.5'
email:
description: 'Additional email notification recipient (separate with ;)'
required: true
type: string
default: ""
cfg_node_count:
description: 'Number of nodes in the etcd cluster'
required: false
type: int
default: 3
# Declare default permissions as read only.
permissions: read-all
env:
REGISTRY: us-central1-docker.pkg.dev
REPOSITORY: molten-verve-216720/linuxfoundation-repository
jobs:
build-and-push-and-test:
runs-on: ubuntu-latest
environment: Antithesis
env:
CFG_NODE_COUNT: ${{ inputs.cfg_node_count }}
steps:
- name: Checkout the code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Antithesis Docker Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ${{ env.REGISTRY }}
username: _json_key
password: ${{ secrets.ANTITHESIS_CONTAINER_REGISTRY_TOKEN }}
- name: Build and push config image
working-directory: ./tests/antithesis
run: |
make antithesis-build-config-image IMAGE_TAG=${{ inputs.etcd_ref }}_${{ github.sha }}
export IMAGE="${{ env.REGISTRY }}/${{ env.REPOSITORY }}/etcd-config:${{ inputs.etcd_ref }}_${{ github.sha }}"
docker tag etcd-config:latest $IMAGE
docker push $IMAGE
- name: Build and push client image
working-directory: ./tests/antithesis
run: |
make antithesis-build-client-docker-image
export IMAGE="${{ env.REGISTRY }}/${{ env.REPOSITORY }}/etcd-client:${{ inputs.etcd_ref }}_${{ github.sha }}"
docker tag etcd-client:latest $IMAGE
docker push $IMAGE
- name: Build and push etcd image
working-directory: ./tests/antithesis
run: |
make antithesis-build-etcd-image REF=${{ inputs.etcd_ref }}
export IMAGE="${{ env.REGISTRY }}/${{ env.REPOSITORY }}/etcd-server:${{ inputs.etcd_ref }}_${{ github.sha }}"
docker tag etcd-server:latest $IMAGE
docker push $IMAGE
- name: Run Antithesis Tests
uses: antithesishq/antithesis-trigger-action@b7d0c9d1d9316bd4de73a44144c56636ea3a64ba # main commit on Mar 13, 2025
with:
notebook_name: etcd
tenant: linuxfoundation
username: ${{ secrets.ANTITHESIS_WEBHOOK_USERNAME }}
password: ${{ secrets.ANTITHESIS_WEBHOOK_PASSWORD }}
github_token: ${{ secrets.GH_PAT }}
config_image: us-central1-docker.pkg.dev/molten-verve-216720/linuxfoundation-repository/etcd-config:${{ inputs.etcd_ref }}_${{ github.sha }}
images: us-central1-docker.pkg.dev/molten-verve-216720/linuxfoundation-repository/etcd-client:${{ inputs.etcd_ref }}_${{ github.sha }};us-central1-docker.pkg.dev/molten-verve-216720/linuxfoundation-repository/etcd-server:${{ inputs.etcd_ref }}_${{ github.sha }};docker.io/library/ubuntu:latest;us-central1-docker.pkg.dev/molten-verve-216720/linuxfoundation-repository/etcd-config:${{ inputs.etcd_ref }}_${{ github.sha }}
description: ${{ inputs.description }}
email_recipients: ${{ inputs.email }}
test_name: ${{ inputs.test }}
additional_parameters: |-
custom.duration = ${{ inputs.duration }}
antithesis.source = ${{ inputs.etcd_ref }}

View File

@ -40,7 +40,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
@ -50,6 +50,6 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
uses: github/codeql-action/autobuild@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2

View File

@ -1,18 +0,0 @@
---
name: Test contrib/mixin
on: [push, pull_request]
permissions: read-all
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- run: |
set -euo pipefail
make -C contrib/mixin tools test

View File

@ -1,34 +0,0 @@
---
name: Coverage
on: [push, pull_request]
permissions: read-all
jobs:
coverage:
# this is to prevent the job to run at forked projects
if: github.repository == 'etcd-io/etcd'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- linux-amd64-coverage
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- env:
TARGET: ${{ matrix.target }}
run: |
mkdir "${TARGET}"
case "${TARGET}" in
linux-amd64-coverage)
GOARCH=amd64 ./scripts/codecov_upload.sh
;;
*)
echo "Failed to find target"
exit 1
;;
esac

View File

@ -1,26 +0,0 @@
---
name: Fuzzing v3rpc
on: [push, pull_request]
permissions: read-all
jobs:
fuzzing:
runs-on: ubuntu-latest
strategy:
fail-fast: false
env:
TARGET_PATH: ./server/etcdserver/api/v3rpc
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- run: |
set -euo pipefail
GOARCH=amd64 CPU=4 make fuzz
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
if: failure()
with:
path: "${{env.TARGET_PATH}}/testdata/fuzz/**/*"

View File

@ -1,38 +0,0 @@
---
name: grpcProxy-tests
on: [push, pull_request]
permissions: read-all
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- linux-amd64-grpcproxy-integration
- linux-amd64-grpcproxy-e2e
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- env:
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
echo "${TARGET}"
case "${TARGET}" in
linux-amd64-grpcproxy-integration)
GOOS=linux GOARCH=amd64 CPU=4 make test-grpcproxy-integration
;;
linux-amd64-grpcproxy-e2e)
GOOS=linux GOARCH=amd64 CPU=4 make test-grpcproxy-e2e
;;
*)
echo "Failed to find target"
exit 1
;;
esac

View File

@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- env:

View File

@ -1,77 +0,0 @@
---
name: Release
on: [push, pull_request]
permissions: read-all
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- id: goversion
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.goversion.outputs.goversion }}
- name: release
run: |
set -euo pipefail
git config --global user.email "github-action@etcd.io"
git config --global user.name "Github Action"
gpg --batch --gen-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: Github Action
Name-Email: github-action@etcd.io
Expire-Date: 0
EOF
DRY_RUN=true ./scripts/release.sh --no-upload --no-docker-push --no-gh-release --in-place 3.6.99
- name: test-image
run: |
VERSION=3.6.99 ./scripts/test_images.sh
- name: save-image
run: |
docker image save -o /tmp/etcd-img.tar gcr.io/etcd-development/etcd
- name: upload-image
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: etcd-img
path: /tmp/etcd-img.tar
retention-days: 1
trivy-scan:
needs: main
strategy:
fail-fast: false
matrix:
platforms: [amd64, arm64, ppc64le, s390x]
permissions:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
runs-on: ubuntu-latest
steps:
- name: get-image
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: etcd-img
path: /tmp
- name: load-image
run: |
docker load < /tmp/etcd-img.tar
- name: trivy-scan
uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0
with:
image-ref: 'gcr.io/etcd-development/etcd:v3.6.99-${{ matrix.platforms }}'
severity: 'CRITICAL,HIGH'
format: 'sarif'
output: 'trivy-results-${{ matrix.platforms }}.sarif'
env:
# Use AWS' ECR mirror for the trivy-db image, as GitHub's Container
# Registry is returning a TOOMANYREQUESTS error.
# Ref: https://github.com/aquasecurity/trivy-action/issues/389
TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
- name: upload scan results
uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
with:
sarif_file: 'trivy-results-${{ matrix.platforms }}.sarif'

View File

@ -28,7 +28,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with:
results_file: results.sarif
results_format: sarif
@ -42,7 +42,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@ -50,6 +50,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
sarif_file: results.sarif

30
.github/workflows/stale.yaml vendored Normal file
View File

@ -0,0 +1,30 @@
---
name: Mark and close stale issues and PRs
on:
schedule:
- cron: '0 0 * * *'
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 #v9.1.0
with:
days-until-stale: 90
days-until-close: 21
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-labels: 'stage/tracked,help wanted'
exempt-projects: false
exempt-milestones: false
exempt-assignees: false
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions.'
close-issue-message: ''
close-pr-message: ''
operations-per-run: 30

View File

@ -0,0 +1,44 @@
---
name: Verify released binary assets
permissions: read-all
on:
release:
types: [published]
jobs:
verify-assets:
name: Verify released binary assets
runs-on: ubuntu-latest
steps:
- name: Verify binary assets
env:
GH_TOKEN: ${{ github.token }}
RELEASE: ${{ github.event.release.tag_name }}
REPOSITORY: ${{ github.repository }}
run: |
mkdir github-assets
pushd github-assets
gh --repo "${REPOSITORY}" release download "${RELEASE}"
test_assets() {
if [ "$(wc -l <SHA256SUMS)" != "$(find . -name 'etcd-*' | wc -l)" ]; then
echo "::error:: Invalid number of assets"
exit 1
fi
sha256sum -c SHA256SUMS
}
test_assets
popd
mkdir google-assets
for file in github-assets/*; do
file=$(basename "${file}")
echo "Downloading ${file} from Google..."
curl "https://storage.googleapis.com/etcd/${RELEASE}/${file}" \
--fail \
-o "google-assets/${file}"
done
pushd google-assets
test_assets

View File

@ -1 +1 @@
1.23.6
1.24.4

View File

@ -1,6 +1,6 @@
<hr>
---
## [v2.3.8](https://github.com/etcd-io/etcd/releases/tag/v2.3.8) (2017-02-17)
@ -12,5 +12,5 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v2.3.7...v2.3.8).
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---

View File

@ -1,6 +1,6 @@
<hr>
---
## [v3.0.16](https://github.com/etcd-io/etcd/releases/tag/v3.0.16) (2016-11-13)
@ -14,7 +14,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.15...v3.0.16) an
- Compile with [*Go 1.6.4*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.15](https://github.com/etcd-io/etcd/releases/tag/v3.0.15) (2016-11-11)
@ -32,7 +32,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.14...v3.0.15) an
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.14](https://github.com/etcd-io/etcd/releases/tag/v3.0.14) (2016-11-04)
@ -50,7 +50,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.13...v3.0.14) an
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.13](https://github.com/etcd-io/etcd/releases/tag/v3.0.13) (2016-10-24)
@ -64,7 +64,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.12...v3.0.13) an
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.12](https://github.com/etcd-io/etcd/releases/tag/v3.0.12) (2016-10-07)
@ -78,7 +78,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.11...v3.0.12) an
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.11](https://github.com/etcd-io/etcd/releases/tag/v3.0.11) (2016-10-07)
@ -98,7 +98,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.10...v3.0.11) an
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.10](https://github.com/etcd-io/etcd/releases/tag/v3.0.10) (2016-09-23)
@ -112,7 +112,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.9...v3.0.10) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.9](https://github.com/etcd-io/etcd/releases/tag/v3.0.9) (2016-09-15)
@ -130,7 +130,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.8...v3.0.9) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.8](https://github.com/etcd-io/etcd/releases/tag/v3.0.8) (2016-09-09)
@ -148,7 +148,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.7...v3.0.8) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.7](https://github.com/etcd-io/etcd/releases/tag/v3.0.7) (2016-08-31)
@ -166,7 +166,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.6...v3.0.7) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.6](https://github.com/etcd-io/etcd/releases/tag/v3.0.6) (2016-08-19)
@ -180,7 +180,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.5...v3.0.6) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.5](https://github.com/etcd-io/etcd/releases/tag/v3.0.5) (2016-08-19)
@ -198,7 +198,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.4...v3.0.5) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.4](https://github.com/etcd-io/etcd/releases/tag/v3.0.4) (2016-07-27)
@ -221,7 +221,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.3...v3.0.4) and
- Compile with [*Go 1.6.3*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.3](https://github.com/etcd-io/etcd/releases/tag/v3.0.3) (2016-07-15)
@ -241,7 +241,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.2...v3.0.3) and
- Compile with [*Go 1.6.2*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.2](https://github.com/etcd-io/etcd/releases/tag/v3.0.2) (2016-07-08)
@ -259,7 +259,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.1...v3.0.2) and
- Compile with [*Go 1.6.2*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.1](https://github.com/etcd-io/etcd/releases/tag/v3.0.1) (2016-07-01)
@ -273,7 +273,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.0.0...v3.0.1) and
- Compile with [*Go 1.6.2*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---
## [v3.0.0](https://github.com/etcd-io/etcd/releases/tag/v3.0.0) (2016-06-30)
@ -287,5 +287,5 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v2.3.0...v3.0.0) and
- Compile with [*Go 1.6.2*](https://golang.org/doc/devel/release.html#go1.6).
<hr>
---

View File

@ -2,7 +2,7 @@
Previous change logs can be found at [CHANGELOG-3.0](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.0.md).
<hr>
---
## [v3.1.21](https://github.com/etcd-io/etcd/releases/tag/v3.1.21) (2019-TBD)
@ -23,7 +23,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Fix bug where [db_compaction_total_duration_milliseconds metric incorrectly measured duration as 0](https://github.com/etcd-io/etcd/pull/10646).
<hr>
---
## [v3.1.20](https://github.com/etcd-io/etcd/releases/tag/v3.1.20) (2018-10-10)
@ -69,7 +69,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.19](https://github.com/etcd-io/etcd/releases/tag/v3.1.19) (2018-07-24)
@ -115,7 +115,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.18](https://github.com/etcd-io/etcd/releases/tag/v3.1.18) (2018-06-15)
@ -138,7 +138,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.17](https://github.com/etcd-io/etcd/releases/tag/v3.1.17) (2018-06-06)
@ -159,7 +159,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.16...v3.1.17) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.16](https://github.com/etcd-io/etcd/releases/tag/v3.1.16) (2018-05-31)
@ -179,7 +179,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.15...v3.1.16) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.15](https://github.com/etcd-io/etcd/releases/tag/v3.1.15) (2018-05-09)
@ -199,7 +199,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.14...v3.1.15) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.14](https://github.com/etcd-io/etcd/releases/tag/v3.1.14) (2018-04-24)
@ -233,7 +233,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.13](https://github.com/etcd-io/etcd/releases/tag/v3.1.13) (2018-03-29)
@ -261,7 +261,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.12](https://github.com/etcd-io/etcd/releases/tag/v3.1.12) (2018-03-08)
@ -284,7 +284,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.11...v3.1.12) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.11](https://github.com/etcd-io/etcd/releases/tag/v3.1.11) (2017-11-28)
@ -303,7 +303,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.10...v3.1.11) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.1.10](https://github.com/etcd-io/etcd/releases/tag/v3.1.10) (2017-07-14)
@ -323,7 +323,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.9...v3.1.10) and
- Fix panic on `net/http.CloseNotify`
<hr>
---
## [v3.1.9](https://github.com/etcd-io/etcd/releases/tag/v3.1.9) (2017-06-09)
@ -341,7 +341,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.8...v3.1.9) and
- Compile with [*Go 1.7.6*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.8](https://github.com/etcd-io/etcd/releases/tag/v3.1.8) (2017-05-19)
@ -355,7 +355,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.7...v3.1.8) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.7](https://github.com/etcd-io/etcd/releases/tag/v3.1.7) (2017-04-28)
@ -369,7 +369,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.6...v3.1.7) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.6](https://github.com/etcd-io/etcd/releases/tag/v3.1.6) (2017-04-19)
@ -388,7 +388,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.5...v3.1.6) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.5](https://github.com/etcd-io/etcd/releases/tag/v3.1.5) (2017-03-27)
@ -411,7 +411,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.4...v3.1.5) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.4](https://github.com/etcd-io/etcd/releases/tag/v3.1.4) (2017-03-22)
@ -425,7 +425,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.3...v3.1.4) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.3](https://github.com/etcd-io/etcd/releases/tag/v3.1.3) (2017-03-10)
@ -452,7 +452,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.2...v3.1.3) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.2](https://github.com/etcd-io/etcd/releases/tag/v3.1.2) (2017-02-24)
@ -474,7 +474,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.1...v3.1.2) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.1](https://github.com/etcd-io/etcd/releases/tag/v3.1.1) (2017-02-17)
@ -488,7 +488,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.1.0...v3.1.1) and
- Compile with [*Go 1.7.5*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---
## [v3.1.0](https://github.com/etcd-io/etcd/releases/tag/v3.1.0) (2017-01-20)
@ -570,5 +570,5 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.7.4*](https://golang.org/doc/devel/release.html#go1.7).
<hr>
---

View File

@ -5,7 +5,7 @@ Previous change logs can be found at [CHANGELOG-3.1](https://github.com/etcd-io/
## v3.2.33 (TBD)
<hr>
---
## [v3.2.32](https://github.com/etcd-io/etcd/releases/tag/v3.2.32) (2021-03-28)
See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.31...v3.2.32) and [v3.2 upgrade guide](https://etcd.io/docs/latest/upgrades/upgrade_3_2/) for any breaking changes.
@ -23,7 +23,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.31...v3.2.32) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.2.31](https://github.com/etcd-io/etcd/releases/tag/v3.2.31) (2020-08-18)
@ -49,7 +49,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.30...v3.2.31) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.2.30](https://github.com/etcd-io/etcd/releases/tag/v3.2.30) (2020-04-01)
@ -69,7 +69,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.29...v3.2.30) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.2.29](https://github.com/etcd-io/etcd/releases/tag/v3.2.29) (2020-03-18)
@ -97,7 +97,7 @@ See [List of metrics](https://github.com/etcd-io/etcd/tree/main/Documentation/me
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.28](https://github.com/etcd-io/etcd/releases/tag/v3.2.28) (2019-11-10)
@ -125,7 +125,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.27](https://github.com/etcd-io/etcd/releases/tag/v3.2.27) (2019-09-17)
@ -161,7 +161,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.26](https://github.com/etcd-io/etcd/releases/tag/v3.2.26) (2019-01-11)
@ -183,7 +183,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.25...v3.2.26) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.25](https://github.com/etcd-io/etcd/releases/tag/v3.2.25) (2018-10-10)
@ -230,7 +230,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.24](https://github.com/etcd-io/etcd/releases/tag/v3.2.24) (2018-07-24)
@ -286,7 +286,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.23](https://github.com/etcd-io/etcd/releases/tag/v3.2.23) (2018-06-15)
@ -317,7 +317,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.22](https://github.com/etcd-io/etcd/releases/tag/v3.2.22) (2018-06-06)
@ -339,7 +339,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.21...v3.2.22) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.21](https://github.com/etcd-io/etcd/releases/tag/v3.2.21) (2018-05-31)
@ -360,7 +360,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.20...v3.2.21) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.20](https://github.com/etcd-io/etcd/releases/tag/v3.2.20) (2018-05-09)
@ -380,7 +380,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.19...v3.2.20) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.19](https://github.com/etcd-io/etcd/releases/tag/v3.2.19) (2018-04-24)
@ -423,7 +423,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.18](https://github.com/etcd-io/etcd/releases/tag/v3.2.18) (2018-03-29)
@ -451,7 +451,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.17](https://github.com/etcd-io/etcd/releases/tag/v3.2.17) (2018-03-08)
@ -481,7 +481,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.16...v3.2.17) an
- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.16](https://github.com/etcd-io/etcd/releases/tag/v3.2.16) (2018-02-12)
@ -504,7 +504,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.15...v3.2.16) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.15](https://github.com/etcd-io/etcd/releases/tag/v3.2.15) (2018-01-22)
@ -523,7 +523,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.14...v3.2.15) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.14](https://github.com/etcd-io/etcd/releases/tag/v3.2.14) (2018-01-11)
@ -545,7 +545,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.13...v3.2.14) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.13](https://github.com/etcd-io/etcd/releases/tag/v3.2.13) (2018-01-02)
@ -564,7 +564,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.12...v3.2.13) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.12](https://github.com/etcd-io/etcd/releases/tag/v3.2.12) (2017-12-20)
@ -596,7 +596,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.11...v3.2.12) an
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.11](https://github.com/etcd-io/etcd/releases/tag/v3.2.11) (2017-12-05)
@ -629,7 +629,7 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.10](https://github.com/etcd-io/etcd/releases/tag/v3.2.10) (2017-11-16)
@ -663,7 +663,7 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.8.5*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.9](https://github.com/etcd-io/etcd/releases/tag/v3.2.9) (2017-10-06)
@ -685,7 +685,7 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.8.4*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.8](https://github.com/etcd-io/etcd/releases/tag/v3.2.8) (2017-09-29)
@ -707,7 +707,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.7...v3.2.8) and
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.7](https://github.com/etcd-io/etcd/releases/tag/v3.2.7) (2017-09-01)
@ -730,7 +730,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.6...v3.2.7) and
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.6](https://github.com/etcd-io/etcd/releases/tag/v3.2.6) (2017-08-21)
@ -758,7 +758,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.5](https://github.com/etcd-io/etcd/releases/tag/v3.2.5) (2017-08-04)
@ -798,7 +798,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.4](https://github.com/etcd-io/etcd/releases/tag/v3.2.4) (2017-07-19)
@ -820,7 +820,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.3...v3.2.4) and
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.3](https://github.com/etcd-io/etcd/releases/tag/v3.2.3) (2017-07-14)
@ -843,7 +843,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.2.2...v3.2.3) and
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.2](https://github.com/etcd-io/etcd/releases/tag/v3.2.2) (2017-07-07)
@ -879,7 +879,7 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.1](https://github.com/etcd-io/etcd/releases/tag/v3.2.1) (2017-06-23)
@ -909,7 +909,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---
## [v3.2.0](https://github.com/etcd-io/etcd/releases/tag/v3.2.0) (2017-06-09)
@ -1017,5 +1017,5 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Compile with [*Go 1.8.3*](https://golang.org/doc/devel/release.html#go1.8).
<hr>
---

View File

@ -2,7 +2,7 @@
Previous change logs can be found at [CHANGELOG-3.2](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.2.md).
<hr>
---
## v3.3.27 (2021-10-15)
@ -16,7 +16,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.26...v3.3.27) an
- [CVE-2019-9893](https://nvd.nist.gov/vuln/detail/CVE-2019-9893): incorrect syscall argument generation in libseccomp
- [CVE-2021-36159](https://nvd.nist.gov/vuln/detail/CVE-2021-36159): libfetch in apk-tools mishandles numeric strings in FTP and HTTP protocols to allow out of bound reads.
<hr>
---
## v3.3.26 (2021-10-03)
@ -34,7 +34,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.25...v3.3.26) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## v3.3.25 (2020-08-24)
@ -68,7 +68,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.23...v3.3.24) an
<hr>
---
@ -96,7 +96,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.22...v3.3.23) an
<hr>
---
## [v3.3.22](https://github.com/etcd-io/etcd/releases/tag/v3.3.22) (2020-05-20)
@ -113,7 +113,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.21...v3.3.22) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.3.21](https://github.com/etcd-io/etcd/releases/tag/v3.3.21) (2020-05-18)
@ -150,7 +150,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.20...v3.3.21) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.3.20](https://github.com/etcd-io/etcd/releases/tag/v3.3.20) (2020-04-01)
@ -170,7 +170,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.19...v3.3.20) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.3.19](https://github.com/etcd-io/etcd/releases/tag/v3.3.19) (2020-03-18)
@ -206,7 +206,7 @@ See [List of metrics](https://github.com/etcd-io/etcd/tree/main/Documentation/me
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.3.18](https://github.com/etcd-io/etcd/releases/tag/v3.3.18) (2019-11-26)
@ -227,7 +227,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Now, etcd makes sure the purge file loop exits before server signals stop of the raft node.
<hr>
---
## [v3.3.17](https://github.com/etcd-io/etcd/releases/tag/v3.3.17) (2019-10-11)
@ -241,7 +241,7 @@ This release replaces 3.3.16.
Due to the etcd 3.3.16 release being incorrectly released (see details below), please use this release instead.
<hr>
---
## [v3.3.16](https://github.com/etcd-io/etcd/releases/tag/v3.3.16) (2019-10-10)
@ -290,7 +290,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Fix ["1.16: etcd client does not parse IPv6 addresses correctly when members are joining" (kubernetes#83550)](https://github.com/kubernetes/kubernetes/issues/83550).
<hr>
---
## [v3.3.15](https://github.com/etcd-io/etcd/releases/tag/v3.3.15) (2019-08-19)
@ -313,7 +313,7 @@ NOTE: This patch release had to include some new features from 3.4, while trying
- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes.
<hr>
---
## [v3.3.14](https://github.com/etcd-io/etcd/releases/tag/v3.3.14) (2019-08-16)
@ -416,7 +416,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes.
<hr>
---
## [v3.3.13](https://github.com/etcd-io/etcd/releases/tag/v3.3.13) (2019-05-02)
@ -456,7 +456,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.10.8*](https://golang.org/doc/devel/release.html#go1.10).
<hr>
---
## [v3.3.12](https://github.com/etcd-io/etcd/releases/tag/v3.3.12) (2019-02-07)
@ -474,7 +474,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.11...v3.3.12) an
- Compile with [*Go 1.10.8*](https://golang.org/doc/devel/release.html#go1.10).
<hr>
---
## [v3.3.11](https://github.com/etcd-io/etcd/releases/tag/v3.3.11) (2019-01-11)
@ -496,7 +496,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.10...v3.3.11) an
- Compile with [*Go 1.10.7*](https://golang.org/doc/devel/release.html#go1.10).
<hr>
---
## [v3.3.10](https://github.com/etcd-io/etcd/releases/tag/v3.3.10) (2018-10-10)
@ -542,7 +542,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.10.4*](https://golang.org/doc/devel/release.html#go1.10).
<hr>
---
## [v3.3.9](https://github.com/etcd-io/etcd/releases/tag/v3.3.9) (2018-07-24)
@ -597,7 +597,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.10.3*](https://golang.org/doc/devel/release.html#go1.10).
<hr>
---
## [v3.3.8](https://github.com/etcd-io/etcd/releases/tag/v3.3.8) (2018-06-15)
@ -619,7 +619,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.7...v3.3.8) and
- Compile with [*Go 1.9.7*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.7](https://github.com/etcd-io/etcd/releases/tag/v3.3.7) (2018-06-06)
@ -645,7 +645,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.6...v3.3.7) and
- Compile with [*Go 1.9.6*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.6](https://github.com/etcd-io/etcd/releases/tag/v3.3.6) (2018-05-31)
@ -668,7 +668,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.5...v3.3.6) and
- Compile with [*Go 1.9.6*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.5](https://github.com/etcd-io/etcd/releases/tag/v3.3.5) (2018-05-09)
@ -687,7 +687,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.4...v3.3.5) and
- Compile with [*Go 1.9.6*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.4](https://github.com/etcd-io/etcd/releases/tag/v3.3.4) (2018-04-24)
@ -735,7 +735,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.9.5*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.3](https://github.com/etcd-io/etcd/releases/tag/v3.3.3) (2018-03-29)
@ -772,7 +772,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.9.5*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.2](https://github.com/etcd-io/etcd/releases/tag/v3.3.2) (2018-03-08)
@ -805,7 +805,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.1...v3.3.2) and
- Compile with [*Go 1.9.4*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.1](https://github.com/etcd-io/etcd/releases/tag/v3.3.1) (2018-02-12)
@ -833,7 +833,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.3.0...v3.3.1) and
- Compile with [*Go 1.9.4*](https://golang.org/doc/devel/release.html#go1.9).
<hr>
---
## [v3.3.0](https://github.com/etcd-io/etcd/releases/tag/v3.3.0) (2018-02-01)
@ -1117,5 +1117,5 @@ See [security doc](https://etcd.io/docs/latest/op-guide/security/) for more deta
- Deprecate [`golang.org/x/net/context`](https://github.com/etcd-io/etcd/pull/8511).
<hr>
---

View File

@ -2,9 +2,30 @@
Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.3.md).
<hr>
---
## v3.4.36 (TBC)
## v3.4.38 (TBC)
### etcd server
- Fix [mvcc: avoid double decrement of watcher gauge on close/cancel race](https://github.com/etcd-io/etcd/pull/20065)
- Fix [Watch on future revision returns old events or notifications](https://github.com/etcd-io/etcd/pull/20291)
### Dependencies
- Compile binaries using [go 1.23.11](https://github.com/etcd-io/etcd/pull/20322).
---
## v3.4.37 (2025-04-15)
### Dependencies
- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19529).
- Compile binaries using [go 1.23.8](https://github.com/etcd-io/etcd/pull/19726)
---
## v3.4.36 (2025-02-25)
### etcd server
- [Avoid deadlock in etcd.Close when stopping during bootstrapping](https://github.com/etcd-io/etcd/pull/19166)
@ -14,9 +35,11 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Fix [runtime panic that occurs when KeepAlive is called with a Context implemented by an uncomparable type](https://github.com/etcd-io/etcd/pull/18936)
### Dependencies
- Compile binaries using [go 1.22.12](https://github.com/etcd-io/etcd/pull/19337)
- Compile binaries using [go 1.23.6](https://github.com/etcd-io/etcd/pull/19429)
- Bump golang.org/x/crypto to v0.35.0 to address [CVE-2024-45337](https://github.com/etcd-io/etcd/pull/19197) and [CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19477).
- Bump golang.org/x/net to v0.34.0 to address [CVE-2024-45338](https://github.com/etcd-io/etcd/pull/19197).
<hr>
---
## v3.4.35 (2024-11-12)
@ -28,7 +51,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.22.9](https://github.com/etcd-io/etcd/pull/18850).
<hr>
---
## v3.4.34 (2024-09-11)
@ -43,7 +66,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Compile binaries using [go 1.22.7](https://github.com/etcd-io/etcd/pull/18549).
- Upgrade [bbolt to 1.3.11](https://github.com/etcd-io/etcd/pull/18488).
<hr>
---
## v3.4.33 (2024-06-13)
@ -54,7 +77,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Compile binaries using go [1.21.11](https://github.com/etcd-io/etcd/pull/18130).
- Upgrade [bbolt to 1.3.10](https://github.com/etcd-io/etcd/pull/17945).
<hr>
---
## v3.4.32 (2024-04-25)
@ -73,7 +96,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.21.9](https://github.com/etcd-io/etcd/pull/17709).
<hr>
---
## v3.4.31 (2024-03-21)
@ -96,7 +119,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Others
- [Make CGO_ENABLED configurable](https://github.com/etcd-io/etcd/pull/17422).
<hr>
---
## v3.4.30 (2024-01-31)
@ -107,7 +130,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Compile binaries using go [1.20.13](https://github.com/etcd-io/etcd/pull/17276).
- Upgrade [golang.org/x/crypto to v0.17+ to address CVE-2023-48795](https://github.com/etcd-io/etcd/pull/17347).
<hr>
---
## v3.4.29 (2024-01-09)
@ -121,7 +144,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Dependencies
- Compile binaries using go [1.20.12](https://github.com/etcd-io/etcd/pull/17076).
<hr>
---
## v3.4.28 (2023-11-23)
@ -143,7 +166,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Upgrade [bbolt to 1.3.8](https://github.com/etcd-io/etcd/pull/16834).
- Upgrade gRPC to 1.58.3 in https://github.com/etcd-io/etcd/pull/16997 and https://github.com/etcd-io/etcd/pull/16999. Note that gRPC server will reject requests with connection header (refer to https://github.com/grpc/grpc-go/pull/4803).
<hr>
---
## v3.4.27 (2023-07-11)
@ -158,7 +181,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.19.10](https://github.com/etcd-io/etcd/pull/16038).
<hr>
---
## v3.4.26 (2023-05-12)
@ -169,7 +192,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.19.9](https://github.com/etcd-io/etcd/pull/15823)
<hr>
---
## v3.4.25 (2023-04-14)
@ -196,7 +219,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Docker image
- Fix [etcd docker images all tagged with amd64 architecture](https://github.com/etcd-io/etcd/pull/15681)
<hr>
---
## v3.4.24 (2023-02-16)
@ -218,7 +241,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Docker image
- Updated [base image from base-debian11 to static-debian11 and removed dependency on busybox](https://github.com/etcd-io/etcd/pull/15038).
<hr>
---
## v3.4.23 (2022-12-21)
@ -237,7 +260,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### Docker image
- Use [distroless base image](https://github.com/etcd-io/etcd/pull/15017) to address critical Vulnerabilities.
<hr>
---
## v3.4.22 (2022-11-02)
@ -256,7 +279,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
### etcd grpc-proxy
- Add [`etcd grpc-proxy start --listen-cipher-suites`](https://github.com/etcd-io/etcd/pull/14601) flag to support adding configurable cipher list.
<hr>
---
## v3.4.21 (2022-09-15)
@ -269,7 +292,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Fix [etcdctl move-leader may fail for multiple endpoints](https://github.com/etcd-io/etcd/pull/14441)
<hr>
---
## v3.4.20 (2022-08-06)
@ -289,7 +312,7 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
- Fix [Grant lease with negative ID can possibly cause db out of sync](https://github.com/etcd-io/etcd/pull/14239)
- Fix [Allow non mutating requests pass through quotaKVServer when NOSPACE](https://github.com/etcd-io/etcd/pull/14254)
<hr>
---
## v3.4.19 (2022-07-12)
@ -317,7 +340,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.18...v3.4.19) an
- Compile with [Go 1.16+](https://go.dev/doc/devel/release#go1.16).
- etcd uses [go modules](https://github.com/etcd-io/etcd/pull/14136) (instead of vendor dir) to track dependencies.
<hr>
---
## v3.4.18 (2021-10-15)
@ -337,7 +360,7 @@ See [List of metrics](https://etcd.io/docs/latest/metrics/) for all metrics per
- [CVE-2019-9893](https://nvd.nist.gov/vuln/detail/CVE-2019-9893): incorrect syscall argument generation in libseccomp
- [CVE-2021-36159](https://nvd.nist.gov/vuln/detail/CVE-2021-36159): libfetch in apk-tools mishandles numeric strings in FTP and HTTP protocols to allow out of bound reads.
<hr>
---
## v3.4.17 (2021-10-03)
@ -359,7 +382,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.16...v3.4.17) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## v3.4.16 (2021-05-11)
@ -381,7 +404,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.15...v3.4.16) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.15](https://github.com/etcd-io/etcd/releases/tag/v3.4.15) (2021-02-26)
@ -406,7 +429,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.14...v3.4.15) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.14](https://github.com/etcd-io/etcd/releases/tag/v3.4.14) (2020-11-25)
@ -436,7 +459,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.13...v3.4.14) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.13](https://github.com/etcd-io/etcd/releases/tag/v3.4.13) (2020-8-24)
@ -452,7 +475,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.12...v3.4.13) an
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.12](https://github.com/etcd-io/etcd/releases/tag/v3.4.12) (2020-08-19)
@ -470,7 +493,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.11...v3.4.12) an
<hr>
---
@ -504,7 +527,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.10...v3.4.11) an
<hr>
---
@ -533,7 +556,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.9...v3.4.10) and
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.9](https://github.com/etcd-io/etcd/releases/tag/v3.4.9) (2020-05-20)
@ -550,7 +573,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.8...v3.4.9) and
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.8](https://github.com/etcd-io/etcd/releases/tag/v3.4.8) (2020-05-18)
@ -587,7 +610,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.7...v3.4.8) and
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.7](https://github.com/etcd-io/etcd/releases/tag/v3.4.7) (2020-04-01)
@ -611,7 +634,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.6...v3.4.7) and
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.6](https://github.com/etcd-io/etcd/releases/tag/v3.4.6) (2020-03-29)
@ -629,7 +652,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.5...v3.4.6) and
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.5](https://github.com/etcd-io/etcd/releases/tag/v3.4.5) (2020-03-18)
@ -666,7 +689,7 @@ See [List of metrics](https://etcd.io/docs/latest/metrics/) for all metrics per
- Compile with [*Go 1.12.17*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.4](https://github.com/etcd-io/etcd/releases/tag/v3.4.4) (2020-02-24)
@ -699,7 +722,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Fix bug where [some auth related messages are logged at wrong level](https://github.com/etcd-io/etcd/pull/11586)
<hr>
---
## [v3.4.3](https://github.com/etcd-io/etcd/releases/tag/v3.4.3) (2019-10-24)
@ -721,7 +744,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.12.12*](https://golang.org/doc/devel/release.html#go1.12).
<hr>
---
## [v3.4.2](https://github.com/etcd-io/etcd/releases/tag/v3.4.2) (2019-10-11)
@ -750,7 +773,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.4.1...v3.4.2) and
- Fix ["1.16: etcd client does not parse IPv6 addresses correctly when members are joining" (kubernetes#83550)](https://github.com/kubernetes/kubernetes/issues/83550).
<hr>
---
## [v3.4.1](https://github.com/etcd-io/etcd/releases/tag/v3.4.1) (2019-09-17)
@ -786,7 +809,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- Compile with [*Go 1.12.9*](https://golang.org/doc/devel/release.html#go1.12) including [*Go 1.12.8*](https://groups.google.com/d/msg/golang-announce/65QixT3tcmg/DrFiG6vvCwAJ) security fixes.
<hr>
---
## v3.4.0 (2019-08-30)
@ -1391,5 +1414,5 @@ Note: **v3.5 will deprecate `etcd --log-package-levels` flag for `capnslog`**; `
- [Rebase etcd image from Alpine to Debian](https://github.com/etcd-io/etcd/pull/10805) to improve security and maintenance effort for etcd release.
<hr>
---

View File

@ -1,20 +1,69 @@
Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.4.md).
<hr>
## v3.5.19 (TBC)
---
## v3.5.22 (TBC)
### etcd server
- Fix [the compaction pause duration metric is not emitted for every compaction batch](https://github.com/etcd-io/etcd/pull/19771)
- Fix [mvcc: avoid double decrement of watcher gauge on close/cancel race](https://github.com/etcd-io/etcd/pull/20066)
- Fix [Watch on future revision returns old events or notifications](https://github.com/etcd-io/etcd/pull/20290)
### Package `clientv3`
- [Replace `resolver.State.Addresses` with `resolver.State.Endpoint.Addresses`](https://github.com/etcd-io/etcd/pull/19783).
- [Deprecated the Metadata field in the Endpoint struct from the client/v3/naming/endpoints package](https://github.com/etcd-io/etcd/pull/19846).
### Dependencies
- Compile binaries using [go 1.23.11](https://github.com/etcd-io/etcd/pull/20321)
---
## v3.5.21 (2025-03-27)
### Dependencies
- Bump [github.com/golang-jwt/jwt/v4 from 4.5.1 to 4.5.2 to address CVE-2025-30204](https://github.com/etcd-io/etcd/pull/19646).
- Bump [bump golang.org/x/net from v0.36.0 to v0.38.0 to address CVE-2025-22870 and CVE-2025-22872](https://github.com/etcd-io/etcd/pull/19686).
---
## v3.5.20 (2025-03-21)
### etcd server
- Fix [the learner promotion changes not being persisted into v3store (bbolt)](https://github.com/etcd-io/etcd/pull/19563)
- Update [the RLock in Demoted method for read-only access to expiry](https://github.com/etcd-io/etcd/pull/19445)
### etcdctl
- Fix [command `etcdctl member promote` doesn't support json output](https://github.com/etcd-io/etcd/pull/19602)
### etcd grpc-proxy
- Fix [grpcproxy can get stuck in and endless loop causing high CPU usage](https://github.com/etcd-io/etcd/pull/19562)
---
## v3.5.19 (2025-03-05)
### etcd server
- Backport [add learner status check to readyz endpoint](https://github.com/etcd-io/etcd/pull/19280).
- Fix [performance regression due to uncertain compaction sleep interval](https://github.com/etcd-io/etcd/pull/19405).
### `tools/benchmark`
- Backport [add mixed read-write performance evaluation scripts](https://github.com/etcd-io/etcd/pull/19275).
### Dependencies
- Compile binaries using [go 1.22.12](https://github.com/etcd-io/etcd/pull/19336).
- Compile binaries using [go 1.23.7](https://github.com/etcd-io/etcd/pull/19528).
- Bump [golang.org/x/crypto to v0.35.0 to address CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19478).
- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19530).
<hr>
---
## v3.5.18 (2025-01-24)
@ -38,7 +87,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Bump [golang.org/x/crypto to 0.32.0 to address CVE-2024-45337](https://github.com/etcd-io/etcd/pull/19154).
- Bump [golang.org/x/net to 0.34.0 to address CVE-2024-45338](https://github.com/etcd-io/etcd/pull/19158).
<hr>
---
## v3.5.17 (2024-11-12)
@ -51,7 +100,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.22.9](https://github.com/etcd-io/etcd/pull/18849).
<hr>
---
## v3.5.16 (2024-09-10)
@ -64,7 +113,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Compile binaries using [go 1.22.7](https://github.com/etcd-io/etcd/pull/18550).
- Upgrade [bbolt to v1.3.11](https://github.com/etcd-io/etcd/pull/18489).
<hr>
---
## v3.5.15 (2024-07-19)
@ -103,7 +152,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Compile binaries using [go 1.21.10](https://github.com/etcd-io/etcd/pull/17980).
- Upgrade [bbolt to v1.3.10](https://github.com/etcd-io/etcd/pull/17943).
<hr>
---
## v3.5.13 (2024-03-29)
@ -132,7 +181,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
### Others
- [Make CGO_ENABLED configurable](https://github.com/etcd-io/etcd/pull/17421).
<hr>
---
## v3.5.12 (2024-01-31)
@ -159,7 +208,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Compile binaries using [go 1.20.12](https://github.com/etcd-io/etcd/pull/17077)
- Fix [CVE-2023-47108](https://github.com/advisories/GHSA-8pgv-569h-w5rw) by [bumping go.opentelemetry.io/otel to 1.20.0 and go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc to 0.46.0](https://github.com/etcd-io/etcd/pull/16946).
<hr>
---
## v3.5.10 (2023-10-27)
@ -190,7 +239,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Upgrade gRPC to 1.58.3 in https://github.com/etcd-io/etcd/pull/16625, https://github.com/etcd-io/etcd/pull/16781 and https://github.com/etcd-io/etcd/pull/16790. Note that gRPC server will reject requests with connection header (refer to https://github.com/grpc/grpc-go/pull/4803).
- Upgrade [bbolt to v1.3.8](https://github.com/etcd-io/etcd/pull/16833)
<hr>
---
## v3.5.9 (2023-05-11)
@ -200,7 +249,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
### Dependencies
- Compile binaries using [go 1.19.9](https://github.com/etcd-io/etcd/pull/15822).
<hr>
---
## v3.5.8 (2023-04-13)
@ -233,7 +282,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- [Remove nsswitch.conf from docker image](https://github.com/etcd-io/etcd/pull/15161)
- Fix [etcd docker images all tagged with amd64 architecture](https://github.com/etcd-io/etcd/pull/15612)
<hr>
---
## v3.5.7 (2023-01-20)
@ -256,7 +305,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- Use [distroless base image](https://github.com/etcd-io/etcd/pull/15016) to address critical Vulnerabilities.
- Updated [base image from base-debian11 to static-debian11 and removed dependency on busybox](https://github.com/etcd-io/etcd/pull/15037).
<hr>
---
## v3.5.6 (2022-11-21)
@ -276,7 +325,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
### etcd grpc-proxy
- Add [`etcd grpc-proxy start --listen-cipher-suites`](https://github.com/etcd-io/etcd/pull/14500) flag to support adding configurable cipher list.
<hr>
---
## v3.5.5 (2022-09-15)
@ -311,7 +360,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- [Bump golang.org/x/crypto to latest version](https://github.com/etcd-io/etcd/pull/13996) to address [CVE-2022-27191](https://github.com/advisories/GHSA-8c26-wmh5-6g9v).
- [Bump OpenTelemetry to 1.0.1 and gRPC to 1.41.0](https://github.com/etcd-io/etcd/pull/14312).
<hr>
---
## v3.5.4 (2022-04-24)
@ -323,7 +372,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- [Revert the change of trimming the trailing dot from SRV.Target](https://github.com/etcd-io/etcd/pull/13950) returned by DNS lookup
<hr>
---
## v3.5.3 (2022-04-13)
@ -344,7 +393,7 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
- [Always print the raft_term in decimal](https://github.com/etcd-io/etcd/pull/13727) when displaying member list in json.
<hr>
---
## [v3.5.2](https://github.com/etcd-io/etcd/releases/tag/v3.5.2) (2022-02-01)
@ -357,7 +406,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.1...v3.5.2) and
- Fix [assertion failed due to tx closed when recovering v3 backend from a snapshot db](https://github.com/etcd-io/etcd/pull/13501)
- Fix [segmentation violation(SIGSEGV) error due to premature unlocking of watchableStore](https://github.com/etcd-io/etcd/pull/13541)
<hr>
---
## [v3.5.1](https://github.com/etcd-io/etcd/releases/tag/v3.5.1) (2021-10-15)
@ -384,7 +433,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.5.1) and
- [CVE-2019-9893](https://nvd.nist.gov/vuln/detail/CVE-2019-9893): incorrect syscall argument generation in libseccomp
- [CVE-2021-36159](https://nvd.nist.gov/vuln/detail/CVE-2021-36159): libfetch in apk-tools mishandles numeric strings in FTP and HTTP protocols to allow out of bound reads.
<hr>
---
## v3.5.0 (2021-06)
@ -681,5 +730,5 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.
- The etcd team has added, a well defined and openly discussed, project [governance](https://github.com/etcd-io/etcd/pull/11175).
<hr>
---

View File

@ -2,9 +2,130 @@
Previous change logs can be found at [CHANGELOG-3.5](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.5.md).
<hr>
---
## v3.6.0 (TBD)
## v3.6.3 (TBD)
---
## v3.6.2 (2025-07-09)
### etcd server
- Fix [Watch on future revision returns old events or notifications](https://github.com/etcd-io/etcd/pull/20286)
### Dependencies
- [Bump bbolt to v1.4.2](https://github.com/etcd-io/etcd/pull/20267)
- Compile binaries using [go 1.23.11](https://github.com/etcd-io/etcd/pull/20314).
---
## v3.6.1 (2025-06-06)
### etcd server
- [Replaced the deprecated/removed `UnaryServerInterceptor` and `StreamServerInterceptor` in otelgrpc with `NewServerHandler`](https://github.com/etcd-io/etcd/pull/20043)
- [Add protection on `PromoteMember` and `UpdateRaftAttributes` to prevent panicking](https://github.com/etcd-io/etcd/pull/20051)
- [Fix the issue that `--force-new-cluster` can't remove all other members in a corner case](https://github.com/etcd-io/etcd/pull/20071)
- Fix [mvcc: avoid double decrement of watcher gauge on close/cancel race](https://github.com/etcd-io/etcd/pull/20067)
- [Add validation to ensure there is no empty v3discovery endpoint](https://github.com/etcd-io/etcd/pull/20113)
### etcdctl
- Fix [command `etcdctl endpoint health` doesn't work when options are set via environment variables](https://github.com/etcd-io/etcd/pull/20121)
### Dependencies
- Compile binaries using [go 1.23.10](https://github.com/etcd-io/etcd/pull/20128).
---
## v3.6.0 (2025-05-15)
There isn't any production code change since v3.6.0-rc.5.
---
## v3.6.0-rc.5 (2025-05-08)
### etcd server
- Fix [the compaction pause duration metric is not emitted for every compaction batch](https://github.com/etcd-io/etcd/pull/19770)
### Package `clientv3`
- [Replace `resolver.State.Addresses` with `resolver.State.Endpoint.Addresses`](https://github.com/etcd-io/etcd/pull/19782).
- [Deprecated the Metadata field in the Endpoint struct from the client/v3/naming/endpoints package](https://github.com/etcd-io/etcd/pull/19842).
### Dependencies
- Compile binaries using [go 1.23.9](https://github.com/etcd-io/etcd/pull/19867).
---
## v3.6.0-rc.4 (2025-04-15)
### etcd server
- [Switch to validating v3 when v2 and v3 are synchronized](https://github.com/etcd-io/etcd/pull/19703).
### Dependencies
- Compile binaries using [go 1.23.8](https://github.com/etcd-io/etcd/pull/19724)
---
## v3.6.0-rc.3 (2025-03-27)
### etcd server
- [Auto sync members in v3store for the issues which have already been affected by #19557](https://github.com/etcd-io/etcd/pull/19636).
- [Move `client/internal/v2` into `server/internel/clientv2`](https://github.com/etcd-io/etcd/pull/19673).
- [Replace ExperimentalMaxLearners with a Feature Gate](https://github.com/etcd-io/etcd/pull/19560).
### etcd grpc-proxy
- Fix [grpcproxy can get stuck in and endless loop causing high CPU usage](https://github.com/etcd-io/etcd/pull/19562)
### Dependencies
- Bump [github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2 to address CVE-2025-30204](https://github.com/etcd-io/etcd/pull/19647).
- Bump [bump golang.org/x/net from v0.37.0 to v0.38.0 to address CVE-2025-22872](https://github.com/etcd-io/etcd/pull/19687).
---
## v3.6.0-rc.2 (2025-03-05)
### etcd server
- Add [Prometheus metric to query server feature gates](https://github.com/etcd-io/etcd/pull/19495).
### Dependencies
- Compile binaries using [go 1.23.7](https://github.com/etcd-io/etcd/pull/19527).
- Bump [golang.org/x/net to v0.36.0 to address CVE-2025-22870](https://github.com/etcd-io/etcd/pull/19531).
- Bump [github.com/grpc-ecosystem/grpc-gateway/v2 to v2.26.3 to fix the issue of etcdserver crashing on receiving REST watch stream requests](https://github.com/etcd-io/etcd/pull/19522).
---
## v3.6.0-rc.1 (2025-02-25)
### etcdctl v3
- Add [`DowngradeInfo` in result of endpoint status](https://github.com/etcd-io/etcd/pull/19471)
### etcd server
- Add [`DowngradeInfo` to endpoint status response](https://github.com/etcd-io/etcd/pull/19471)
### Dependencies
- Bump [golang.org/x/crypto to v0.35.0 to address CVE-2025-22869](https://github.com/etcd-io/etcd/pull/19480).
---
## v3.6.0-rc.0 (2025-02-13)
See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
@ -15,6 +136,19 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
- `etcdctl` will sleep(2s) in case of range delete without `--range` flag. See [pull/13747](https://github.com/etcd-io/etcd/pull/13747)
- Applications which depend on etcd v3.6 packages must be built with go version >= v1.18.
#### Flags Removed
- The following flags have been removed:
- `--enable-v2`
- `--experimental-enable-v2v3`
- `--proxy`
- `--proxy-failure-wait`
- `--proxy-refresh-interval`
- `--proxy-dial-timeout`
- `--proxy-write-timeout`
- `--proxy-read-timeout`
### Deprecations
- Deprecated [V2 discovery](https://etcd.io/docs/v3.5/dev-internal/discovery_protocol/).
@ -22,8 +156,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
- Removed [etcdctl defrag --data-dir](https://github.com/etcd-io/etcd/pull/13793).
- Removed [etcdctl snapshot status](https://github.com/etcd-io/etcd/pull/13809).
- Removed [etcdctl snapshot restore](https://github.com/etcd-io/etcd/pull/13809).
- Removed [etcdutl snapshot save](https://github.com/etcd-io/etcd/pull/13809).
- Removed [NewZapCoreLoggerBuilder in server/embed](https://github.com/etcd-io/etcd/pull/19404)
### etcdctl v3
@ -78,7 +211,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
- Decreased [`--snapshot-count` default value from 100,000 to 10,000](https://github.com/etcd-io/etcd/pull/15408)
- Add [`etcd --tls-min-version --tls-max-version`](https://github.com/etcd-io/etcd/pull/15156) to enable support for TLS 1.3.
- Add [quota to endpoint status response](https://github.com/etcd-io/etcd/pull/17877)
- Add ['etcd --experimental-set-member-localaddr'](https://github.com/etcd-io/etcd/pull/17661) to enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer.
- Add [feature gate `SetMemberLocalAddr`](https://github.com/etcd-io/etcd/pull/19413) to [enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer]((https://github.com/etcd-io/etcd/pull/17661))
- Add [Support multiple values for allowed client and peer TLS identities](https://github.com/etcd-io/etcd/pull/18015)
- Add [`embed.Config.GRPCAdditionalServerOptions`](https://github.com/etcd-io/etcd/pull/14066) to support updating the default internal gRPC configuration for embedded use cases.
@ -110,4 +243,4 @@ See [List of metrics](https://etcd.io/docs/latest/metrics/) for all metrics per
- [Upgrade grpc-gateway from v1 to v2](https://github.com/etcd-io/etcd/pull/16595).
- [Switch from grpc-ecosystem/go-grpc-prometheus to grpc-ecosystem/go-grpc-middleware/providers/prometheus](https://github.com/etcd-io/etcd/pull/19195).
<hr>
---

View File

@ -0,0 +1,29 @@
Previous change logs can be found at [CHANGELOG-3.6](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.6.md).
---
## v3.7.0 (TBD)
### Breaking Changes
- [Removed all deprecated experimental flags](https://github.com/etcd-io/etcd/pull/19959)
- [Removed v2discovery](https://github.com/etcd-io/etcd/pull/20109)
- [Removed client/v2](https://github.com/etcd-io/etcd/pull/20117)
### etcd server
- [Update go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc to v0.61.0 and replaced the deprecated `UnaryServerInterceptor` and `StreamServerInterceptor` with `NewServerHandler`](https://github.com/etcd-io/etcd/pull/20017)
- [Add Support for Unix Socket endpoints](https://github.com/etcd-io/etcd/pull/19760)
### Package `pkg`
- [Optimize find performance by splitting intervals with the same left endpoint by their right endpoints](https://github.com/etcd-io/etcd/pull/19768)
### Dependencies
- Compile binaries using [go 1.24.4](https://github.com/etcd-io/etcd/pull/20163)
### Deprecations
- Deprecated [UsageFunc in pkg/cobrautl](https://github.com/etcd-io/etcd/pull/18356).

View File

@ -2,7 +2,7 @@
Previous change logs can be found at [CHANGELOG-3.x](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.x.md).
<hr>
---
## v4.0.0 (TBD)
@ -40,5 +40,5 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v4.0.0) and
- Require [*Go 2*](https://blog.golang.org/go2draft).
<hr>
---

View File

@ -1,5 +1,5 @@
ARG ARCH=amd64
FROM --platform=linux/${ARCH} gcr.io/distroless/static-debian12@sha256:3f2b64ef97bd285e36132c684e6b2ae8f2723293d09aae046196cca64251acac
FROM --platform=linux/${ARCH} gcr.io/distroless/static-debian12@sha256:b7b9a6953e7bed6baaf37329331051d7bdc1b99c885f6dbeb72d75b1baad54f9
ADD etcd /usr/local/bin/
ADD etcdctl /usr/local/bin/

View File

@ -0,0 +1,191 @@
# Bump etcd Version in Kubernetes
This guide will walk through the update of etcd in Kubernetes to a new version (`kubernetes/kubernetes` repository).
> Currently we bump etcd v3.5.x for K8s release-1.33 and lower versions, and we bump etcd v3.6.x for K8s release-1.34 and higher versions.
You can use this [issue](https://github.com/kubernetes/kubernetes/issues/131101) as a reference when updating the etcd version in Kubernetes.
Bumping the etcd version in Kubernetes consists of two steps.
* Bump etcd client SDK
* Bump etcd image
> The commented lines in this document signifies the line to be changed
## Bump etcd client SDK
> Reference: [link](https://github.com/kubernetes/kubernetes/pull/131103)
You can refer to the guide [here](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/vendor.md) under the **Adding or updating a dependency** section.
1. Get all the etcd modules used in Kubernetes.
```bash
$ grep 'go.etcd.io/etcd/' go.mod | awk '{print $1}'
go.etcd.io/etcd/api/v3
go.etcd.io/etcd/client/pkg/v3
go.etcd.io/etcd/client/v3
go.etcd.io/etcd/client/v2
go.etcd.io/etcd/pkg/v3
go.etcd.io/etcd/raft/v3
go.etcd.io/etcd/server/v3
```
2. For each module, in the root directory of the `kubernetes/kubernetes` repository, fetch the new version in `go.mod` using the following command (using `client/v3` as an example):
```bash
hack/pin-dependency.sh go.etcd.io/etcd/client/v3 NEW_VERSION
```
3. Rebuild the `vendor` directory and update the `go.mod` files for all staging repositories using the command below. This automatically updates the licenses.
```bash
hack/update-vendor.sh
```
4. Check if the new dependency requires newer versions of existing dependencies we have pinned. You can check this by:
* Running `hack/lint-dependencies.sh` against your branch and against `master` and comparing the results.
* Checking if any new `replace` directives were added to `go.mod` files of components inside the staging directory.
## Bump etcd image
### Build etcd image
> Reference: [link 1](https://github.com/kubernetes/kubernetes/pull/131105) [link 2](https://github.com/kubernetes/kubernetes/pull/131126)
1. In `build/dependencies.yaml`, update the `version` of `etcd-image` to the new version. Update `golang: etcd release version` if necessary.
```yaml
- name: "etcd-image"
# version: 3.5.17
version: 3.5.21
refPaths:
- path: cluster/images/etcd/Makefile
match: BUNDLED_ETCD_VERSIONS\?|
---
- name: "golang: etcd release version"
# version: 1.22.9
version: 1.23.7 # https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.6.md
```
2. In `cluster/images/etcd/Makefile`, include the new version in `BUNDLED_ETCD_VERSIONS` and update the `LATEST_ETCD_VERSION` as well (the image tag will be generated from the `LATEST_ETCD_VERSION`). Update `GOLANG_VERSION` according to the version used to compile that release version (`"golang: etcd release version"` in step 1).
```Makefile
# BUNDLED_ETCD_VERSIONS?=3.4.18 3.5.17
BUNDLED_ETCD_VERSIONS?=3.4.18 3.5.21
# LATEST_ETCD_VERSION?=3.5.17
LATEST_ETCD_VERSION?=3.5.21
# GOLANG_VERSION := 1.22.9
GOLANG_VERSION := 1.23.7
```
3. In `cluster/images/etcd/migrate/options.go`, include the new version in the `supportedEtcdVersions` slice.
```go
var (
// supportedEtcdVersions = []string{"3.4.18", "3.5.17"}
supportedEtcdVersions = []string{"3.4.18", "3.5.21"}
)
```
### Publish etcd image
> Reference: [link](https://github.com/kubernetes/k8s.io/pull/7957)
1. When the previous step is merged, a post-commit job will run to build the image. You can find the newly built image in the [registry](https://gcr.io/k8s-staging-etcd/etcd).
2. Locate the newly built image and copy its SHA256 digest.
3. Inside the `kubernetes/k8s.io` repository, in `registry.k8s.io/images/k8s-staging-etcd/images.yaml`, create a new entry for the desired version and copy the SHA256 digest.
```yaml
"sha256:b4a9e4a7e1cf08844c7c4db6a19cab380fbf0aad702b8c01e578e9543671b9f9": ["3.5.17-0"]
# ADD:
"sha256:d58c035df557080a27387d687092e3fc2b64c6d0e3162dc51453a115f847d121": ["3.5.21-0"]
```
### Update to use the new etcd image
> Reference: [link](https://github.com/kubernetes/kubernetes/pull/131144)
1. In `build/dependencies.yaml`, change the `version` of `etcd` to the new version.
```yaml
# etcd
- name: "etcd"
# version: 3.5.17
version: 3.5.21
refPaths:
- path: cluster/gce/manifests/etcd.manifest
match: etcd_docker_tag|etcd_version
```
2. In `cluster/gce/manifests/etcd.manifest`, change the image tag to the new image tag and `TARGET_VERSION` to the new version.
```manifest
// "image": "{{ pillar.get('etcd_docker_repository', 'registry.k8s.io/etcd') }}:{{ pillar.get('etcd_docker_tag', '3.5.17-0') }}",
"image": "{{ pillar.get('etcd_docker_repository', 'registry.k8s.io/etcd') }}:{{ pillar.get('etcd_docker_tag', '3.5.21-0') }}",
---
{ "name": "TARGET_VERSION",
// "value": "{{ pillar.get('etcd_version', '3.5.17') }}"
"value": "{{ pillar.get('etcd_version', '3.5.21') }}"
},
```
3. In `cluster/gce/upgrade-aliases.sh`, update the exports for `ETCD_IMAGE` to the new image tag and `ETCD_VERSION` to the new version.
```sh
# export ETCD_IMAGE=3.5.17-0
export ETCD_IMAGE=3.5.21-0
# export ETCD_VERSION=3.5.17
export ETCD_VERSION=3.5.21
```
4. In `cmd/kubeadm/app/constants/constants.go`, change the `DefaultEtcdVersion` to the new version. In the same file, update `SupportedEtcdVersion` accordingly.
```go
// DefaultEtcdVersion = "3.5.17-0"
DefaultEtcdVersion = "3.5.21-0"
---
SupportedEtcdVersion = map[uint8]string{
// 30: "3.5.17-0",
// 31: "3.5.17-0",
// 32: "3.5.17-0",
// 33: "3.5.17-0",
30: "3.5.21-0",
31: "3.5.21-0",
32: "3.5.21-0",
33: "3.5.21-0",
}
```
5. In `hack/lib/etcd.sh`, update the `ETCD_VERSION`.
```sh
# ETCD_VERSION=${ETCD_VERSION:-3.5.17}
ETCD_VERSION=${ETCD_VERSION:-3.5.21}
```
6. In `staging/src/k8s.io/sample-apiserver/artifacts/example/deployment.yaml`, update the etcd image used.
```yaml
- name: etcd
# image: gcr.io/etcd-development/etcd:v3.5.17
image: gcr.io/etcd-development/etcd:v3.5.21
```
7. In `test/utils/image/manifest.go`, update the etcd image tag.
```go
// configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.17-0"}
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.21-0"}
```

View File

@ -147,11 +147,11 @@ References:
[bbolt](https://github.com/etcd-io/bbolt) and [raft](https://github.com/etcd-io/raft) are two core dependencies of etcd.
Both etcd 3.4.x and 3.5.x depend on bbolt 1.3.x, and etcd 3.6.x (`main` branch) depends on bbolt 1.4.x.
Both etcd 3.4.x and 3.5.x depend on bbolt 1.3.x, and etcd 3.6.x depends on bbolt 1.4.x.
raft is included in the etcd repository for release-3.4 and release-3.5 branches, so etcd 3.4.x and 3.5.x do not depend on any
external raft module. We moved raft into [a separate repository](https://github.com/etcd-io/raft) starting from 3.6 (`main` branch), and the first raft
release will be v3.6.0, so etcd 3.6.x will depend on raft 3.6.x.
external raft module. We moved raft into [a separate repository](https://github.com/etcd-io/raft) starting from 3.6, and the first raft
release is v3.6.0, so etcd 3.6.0 depends on raft v3.6.0.
Please see the table below:

View File

@ -4,80 +4,84 @@ This document provides an overview of etcd features and general development guid
## Overview
The etcd features fall into three stages, experimental, stable, and unsafe.
The etcd features fall into three stages: Alpha, Beta, and GA.
### Experimental
### Alpha
Any new feature is usually added as an experimental feature. An experimental feature is characterized as below:
Any new feature is usually added as an Alpha feature. An Alpha feature is characterized as below:
- Might be buggy due to a lack of user testing. Enabling the feature may not work as expected.
- Disabled by default when added initially.
- Disabled by default.
- Support for such a feature may be dropped at any time without notice
- Feature-related issues may be given lower priorities.
- It can be removed in the next minor or major release without following the feature deprecation policy unless it graduates to a stable future.
- It can be removed in the next minor or major release without following the feature deprecation policy unless it graduates to a more stable stage.
### Stable
### Beta
A stable feature is characterized as below:
A Beta feature is characterized as below:
- Supported as part of the supported releases of etcd.
- May be enabled by default.
- Enabled by default.
- Discontinuation of support must follow the feature deprecation policy.
### Unsafe
### GA
Unsafe features are rare and listed under the `Unsafe feature:` section in the etcd usage documentation. By default, they are disabled. They should be used with caution following documentation. An unsafe feature can be removed in the next minor or major release without following the feature deprecation policy.
A GA feature is characterized as below:
- Supported as part of the supported releases of etcd.
- Always enabled; you cannot disable it. The corresponding feature gate is no longer needed.
- Discontinuation of support must follow the feature deprecation policy.
## Development Guidelines
### Adding a new feature
Any new enhancements to the etcd are typically added as an experimental feature. The general development requirements are listed below. They can be somewhat flexible depending on the scope of the feature and review discussions and will evolve over time.
- Open an issue
Any new enhancements to the etcd are typically added as an Alpha feature.
etcd follows the Kubernetes [KEP process](https://github.com/kubernetes/enhancements/blob/master/keps/sig-architecture/0000-kep-process/README.md) for new enhancements. The general development requirements are listed below. They can be somewhat flexible depending on the scope of the feature and review discussions and will evolve over time.
- Open a [KEP](https://github.com/kubernetes/enhancements/issues) issue
- It must provide a clear need for the proposed feature.
- It should list development work items as checkboxes. There must be one work item towards future graduation to a stable future.
- Label the issue with `type/feature` and `experimental`.
- It should list development work items as checkboxes. There must be one work item towards future graduation to Beta.
- Label the issue with `/sig etcd`.
- Keep the issue open for tracking purposes until a decision is made on graduation.
- Open a Pull Request (PR)
- Open a [KEP](https://github.com/kubernetes/enhancements) Pull Request (PR).
- The KEP template can be simplified for etcd.
- It must provide clear graduation criteria for each stage.
- The KEP doc should reside in [keps/sig-etcd](https://github.com/kubernetes/enhancements/tree/master/keps/sig-etcd/)
- Open Pull Requests (PRs) in [etcd](https://github.com/etcd-io/etcd)
- Provide unit tests. Integration tests are also recommended as possible.
- Provide robust e2e test coverage. If the feature being added is complicated or quickly needed, maintainers can decide to go with e2e tests for basic coverage initially and have robust coverage added at a later time before the feature graduation to the stable feature.
- Provide logs for proper debugging.
- Provide metrics and benchmarks as needed.
- The Feature should be disabled by default.
- Any configuration flags related to the implementation of the feature must be prefixed with `experimental` e.g. `--experimental-feature-name`.
- Add an Alpha [feature gate](https://etcd.io/docs/v3.6/feature-gates/).
- Any code changes or configuration flags related to the implementation of the feature must be gated with the feature gate e.g. `if cfg.ServerFeatureGate.Enabled(features.FeatureName)`.
- Add a CHANGELOG entry.
- At least two maintainers must approve feature requirements and related code changes.
- At least two maintainers must approve the KEP and related code changes.
### Graduating an Experimental feature to Stable
### Graduating a feature to the next stage
It is important that experimental features don't get stuck in that stage. They should be revisited and moved to the stable stage following the graduation steps as described here.
#### Locate graduation candidate
Decide if an experimental feature is ready for graduation to the stable stage.
- Find the issue that was used to enable the experimental feature initially. One way to find such issues is to search for issues with `type/feature` and `experimental` labels.
- Fix any known open issues against the feature.
- Make sure the feature was enabled for at least one previous release. Check the PR(s) reference from the issue to see when the feature-related code changes were merged.
It is important that features don't get stuck in one stage. They should be revisited and moved to the next stage once they meet the graduation criteria listed in the KEP. A feature should stay at one stage for at least one release before being promoted.
#### Provide implementation
If an experimental feature is found ready for graduation to the stable stage, open a Pull Request (PR) with the following changes.
- Add robust e2e tests if not already provided.
- Add a new stable feature flag identical to the experimental feature flag but without the `--experimental` prefix.
- Deprecate the experimental feature following the [feature deprecation policy](#Deprecating-a-feature).
- Implementation must ensure that both the graduated and deprecated experimental feature flags work as expected. Note that both these flags will co-exist for the timeframe described in the feature deprecation policy.
- Enable the graduated feature by default if needed.
If a feature is found ready for graduation to the next stage, open a Pull Request (PR) with the following changes.
- Update the feature `PreRelease` stage in `server/features/etcd_features.go`.
- Update the status in the original KEP issue.
At least two maintainers must approve the work. Patch releases should not be considered for graduation.
### Deprecating a feature
#### Experimental
An experimental feature deprecates when it graduates to the stable stage.
- Add a deprecation message in the documentation of the experimental feature with a recommendation to use a related stable feature. e.g. `DEPRECATED. Use <feature-name> instead.`
- Add a `deprecated` label in the issue that was initially used to enable the experimental feature.
#### Alpha
Alpha features can be removed without going through the deprecation process.
- Remove the feature gate in `server/features/etcd_features.go`, and clean up all relevant code.
- Close the original KEP issue with reasons to drop the feature.
#### Stable
As the project evolves, a stable feature may sometimes need to be deprecated and removed. Such a situation should be handled using the steps below:
- Create an issue for tracking purposes.
- Add a deprecation message in the feature usage documentation before a planned release for feature deprecation. e.g. `To be deprecated in <release>.`. If a new feature replaces the `To be deprecated` feature, then also provide a message saying so. e.g. `Use <feature-name> instead.`.
- Deprecate the feature in the planned release with a message as part of the feature usage documentation. e.g. `DEPRECATED`. If a new feature replaces the deprecated feature, then also provide a message saying so. e.g. `DEPRECATED. Use <feature-name> instead.`.
- Add a `deprecated` label in the related issue.
#### Beta and GA
As the project evolves, a Beta/GA feature may sometimes need to be deprecated and removed. Such a situation should be handled using the steps below:
Remove the deprecated feature in the following release. Close any related issue(s). At least two maintainers must approve the work. Patch releases should not be considered for deprecation.
- A Beta/GA feature can only be deprecated after at least 2 minor or major releases.
- Update original KEP issue if it has not been closed or create a new etcd issue with reasons and steps to deprecate the feature.
- Add the feature deprecation documentation in the release notes and feature gates documentation of the next minor/major release.
- In the next minor/major release, set the feature gate to `{Default: false, PreRelease: featuregate.Deprecated, LockedToDefault: false}` in `server/features/etcd_features.go`. Deprecated feature gates must respond with a warning when used.
- If the feature has GAed, and the original gated codes has been cleaned up, add the disablement codes back with the feature gate.
- In the minor/major release after the next, set the feature gate to `{Default: false, PreRelease: featuregate.Deprecated, LockedToDefault: true}` in `server/features/etcd_features.go`, and start cleaning the code.
At least two maintainers must approve the work. Patch releases should not be considered for deprecation.

View File

@ -6,15 +6,17 @@ The procedure includes some manual steps for sanity checking, but it can probabl
## Release management
The following pool of release candidates manages the release of each etcd major/minor version as well as manages patches
Under the leadership of **James Blair** [@jmhbnz](https://github.com/jmhbnz) and **Ivan Valdes Castillo** [@ivanvc](https://github.com/ivanvc), the following pool of release candidates manages the release of each etcd major/minor version as well as manages patches
to each stable release branch. They are responsible for communicating the timelines and status of each release and
for ensuring the stability of the release branch.
- Benjamin Wang [@ahrtr](https://github.com/ahrtr)
- Fu Wei [@fuweid](https://github.com/fuweid)
- James Blair [@jmhbnz](https://github.com/jmhbnz)
- Ivan Valdes Castillo [@ivanvc](https://github.com/ivanvc)
- Marek Siarkowicz [@serathius](https://github.com/serathius)
- Sahdev Zala [@spzala](https://github.com/spzala)
- Wenjia Zhang [@wenjiaswe](https://github.com/wenjiaswe)
- Siyuan Zhang [@siyuanfoundation](https://github.com/siyuanfoundation)
All release version numbers follow the format of [semantic versioning 2.0.0](http://semver.org/).
@ -68,10 +70,14 @@ which don't need to be executed before releasing each version.
### Release steps
At least one day before the release:
1. Raise an issue to publish the release plan, e.g. [issues/17350](https://github.com/etcd-io/etcd/issues/17350).
2. Raise a `kubernetes/org` pull request to temporarily elevate permissions for the GitHub release team.
3. Once permissions are elevated, temporarily relax [branch protections](https://github.com/etcd-io/etcd/settings/branches) to allow pushing changes directly to `release-*` branches in GitHub.
4. Verify you can pass the authentication to the image registries,
2. Raise a `kubernetes/org` pull request ([example PR](https://github.com/kubernetes/org/pull/5582)) to ensure members of the release team are added to the [release github team](https://github.com/orgs/etcd-io/teams/release-etcd).
On the day of the release:
1. Verify you can pass the authentication to the image registries,
- `docker login gcr.io`
- `docker login quay.io`
- If the release person doesn't have access to 1password, one of the owners (@ahrtr, @ivanvc, @jmhbnz, @serathius) needs to share the password with them per [this guide](https://support.1password.com/share-items/). See rough steps below,
@ -80,45 +86,52 @@ which don't need to be executed before releasing each version.
- Select `Password of quay.io`.
- Click `Share` on the top right, and set expiration as `1 hour` and only available to the release person using his/her email.
- Click `Copy Link` then send the link to the release person via slack or email.
5. Clone the etcd repository and checkout the target branch,
2. Clone the etcd repository and checkout the target branch,
- `git clone --branch release-3.X git@github.com:etcd-io/etcd.git`
6. Run the release script under the repository's root directory, replacing `${VERSION}` with a value without the `v` prefix, i.e. `3.5.13`.
3. Run the release script under the repository's root directory, replacing `${VERSION}` with a value without the `v` prefix, i.e. `3.5.13`.
- `DRY_RUN=false ./scripts/release.sh ${VERSION}`
- **NOTE:** When doing a pre-release (i.e., a version from the main branch, 3.6.0-alpha.2), you will need to explicitly set the branch to main:
```
```bash
DRY_RUN=false BRANCH=main ./scripts/release.sh ${VERSION}
```
It generates all release binaries under the directory `/tmp/etcd-release-${VERSION}/etcd/release/` and images. Binaries are pushed to the Google Cloud bucket
under project `etcd-development`, and images are pushed to `quay.io` and `gcr.io`.
7. Publish the release page on GitHub
- It is advisable to do a dry run before the actual release. This will create a `/tmp` directory. Do **NOT** forget to remove this directory before the actual release.
```bash
DRY_RUN=true BRANCH=${BRANCH} ./scripts/release.sh ${VERSION}
```
4. Publish the release page on GitHub
- Open the **draft** release URL shown by the release script
- Click the pen button at the top right to edit the release
- Review that it looks correct, reviewing that the bottom checkboxes are checked depending on the
release version (v3.4 no checkboxes, v3.5 has the set as latest release checkbox checked,
v3.6 has the set as pre-release checkbox checked)
release version (v3.4 & v3.5 no checkboxes, v3.6 has the set as latest release checkbox checked,
v3.7 has the set as pre-release checkbox checked)
- Then, publish the release
8. Announce to the etcd-dev googlegroup
5. Announce to the etcd-dev googlegroup
Follow the format of previous release emails sent to etcd-dev@googlegroups.com, see an example below. After sending out the email, ask one of the mailing list maintainers to approve the email from the pending list. Additionally, label the release email as `Release`.
```text
Hello,
```text
Hello,
etcd v3.4.30 is now public!
etcd v3.4.30 is now public!
https://github.com/etcd-io/etcd/releases/tag/v3.4.30
https://github.com/etcd-io/etcd/releases/tag/v3.4.30
Thanks to everyone who contributed to the release!
Thanks to everyone who contributed to the release!
etcd team
```
etcd team
```
9. Update the changelog to reflect the correct release date.
10. Paste the release link to the issue raised in Step 1 and close the issue.
11. Restore standard branch protection settings and raise a follow-up `kubernetes/org` pull request to return to least privilege permissions.
12. Crease a new stable branch through `git push origin release-${VERSION_MAJOR}.${VERSION_MINOR}` if this is a new major or minor stable release.
13. Re-generate a new password for quay.io if needed (e.g. shared to a contributor who isn't in the release team, and we should rotate the password at least once every 3 months).
6. Update the changelog to reflect the correct release date.
7. Paste the release link to the issue raised in Step 1 and close the issue.
8. Raise a follow-up `kubernetes/org` pull request to return the GitHub release team to empty, least privilege state.
9. Crease a new stable branch through `git push origin release-${VERSION_MAJOR}.${VERSION_MINOR}` if this is a new major or minor stable release.
10. Re-generate a new password for quay.io if needed (e.g. shared to a contributor who isn't in the release team, and we should rotate the password at least once every 3 months).
#### Release known issues

View File

@ -12,18 +12,18 @@ Each item has an assigned priority. Refer to [priority definitions](https://gith
For a full list of tasks in `v3.6.0`, please see [milestone etcd-v3.6](https://github.com/etcd-io/etcd/milestone/38).
| Title | Priority | Status | Note |
|--------------------------------------------------------------------------------------------------------------------|----------|-------------|--------------------------------------------------------------------------------------------------------------|
| [Support downgrade](https://github.com/etcd-io/etcd/issues/11716) | priority/important-soon | In progress | etcd will support downgrade starting from 3.6.0. But it will also support offline downgrade from 3.5 to 3.4. |
| [StoreV2 deprecation](https://github.com/etcd-io/etcd/issues/12913) | priority/important-soon | In progress | This task will be covered in both 3.6 and 3.7. |
| [Release raft 3.6.0](https://github.com/etcd-io/raft/issues/89) | priority/important-soon | Not started | etcd 3.6.0 will depends on raft 3.6.0 |
| [Release bbolt 1.4.0](https://github.com/etcd-io/bbolt/issues/553) | priority/important-soon | Not started | etcd 3.6.0 will depends on bbolt 1.4.0 |
| [Support /livez and /readyz endpoints](https://github.com/etcd-io/etcd/issues/16007) | priority/important-longterm | In progress | It provides clearer APIs, and can also work around the stalled writes issue |
| Title | Priority | Status | Note |
|--------------------------------------------------------------------------------------------------------------------|-----------------------------|-------------|--------------------------------------------------------------------------------------------------------------|
| [Support downgrade](https://github.com/etcd-io/etcd/issues/11716) | priority/important-soon | In progress | etcd will support downgrade starting from 3.6.0. But it will also support offline downgrade from 3.5 to 3.4. |
| [StoreV2 deprecation](https://github.com/etcd-io/etcd/issues/12913) | priority/important-soon | In progress | This task will be covered in both 3.6 and 3.7. |
| [Release raft 3.6.0](https://github.com/etcd-io/raft/issues/89) | priority/important-soon | Completed | etcd 3.6.0 will depends on raft 3.6.0 |
| [Release bbolt 1.4.0](https://github.com/etcd-io/bbolt/issues/553) | priority/important-soon | Completed | etcd 3.6.0 will depends on bbolt 1.4.0 |
| [Support /livez and /readyz endpoints](https://github.com/etcd-io/etcd/issues/16007) | priority/important-longterm | Completed | It provides clearer APIs, and can also work around the stalled writes issue |
| [Bump gRPC](https://github.com/etcd-io/etcd/issues/16290) | priority/important-longterm | Completed | It isn't guaranteed to be resolved in 3.6, and might be postponed to 3.7 depending on the effort and risk. |
| [Deprecate grpc-gateway or bump it](https://github.com/etcd-io/etcd/issues/14499) | priority/important-longterm | Completed | It isn't guaranteed to be resolved in 3.6, and might be postponed to 3.7 depending on the effort and risk. |
| [bbolt: Add logger into bbolt](https://github.com/etcd-io/bbolt/issues/509) | priority/important-longterm | Completed | It's important to diagnose bbolt issues |
| [bbolt: Add surgery commands](https://github.com/etcd-io/bbolt/issues/370) | priority/important-longterm | Completed | Surgery commands are important for fixing corrupted db files |
| [Evaluate and (Gradulate or deprecate/remove) experimental features](https://github.com/etcd-io/etcd/issues/16292) | priority/backlog | Not started | This task will be covered in both 3.6 and 3.7. |
| [Evaluate and (Gradulate or deprecate/remove) experimental features](https://github.com/etcd-io/etcd/issues/16292) | priority/backlog | Not started | This task will be covered in both 3.6 and 3.7. |
## v3.7.0
@ -32,8 +32,9 @@ For a full list of tasks in `v3.7.0`, please see [milestone etcd-v3.7](https://g
| Title | Priority | Note |
|-------------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------|
| [StoreV2 deprecation](https://github.com/etcd-io/etcd/issues/12913) | P0 | Finish the remaining tasks 3.7. |
| [Support range stream](https://github.com/etcd-io/etcd/issues/12342) | P0 | to be investigated & discussed. |
| [Refactor lease: Lease might be revoked by mistake by old leader](https://github.com/etcd-io/etcd/issues/15247) | P1 | to be investigated & discussed |
| [Integrate raft's new feature (async write) into etcd](https://github.com/etcd-io/etcd/issues/16291) | P1 | It should improve the performance |
| [Integrate raft's new feature (async write) into etcd](https://github.com/etcd-io/etcd/issues/16291) | P1 | It should improve the performance |
| [bbolt: Support customizing the bbolt rebalance threshold](https://github.com/etcd-io/bbolt/issues/422) | P2 | It may get rid of etcd's defragmentation. Both bbolt and etcd need to be changed. |
| [Evaluate and (graduate or deprecate/remove) experimental features](https://github.com/etcd-io/etcd/issues/16292) | P2 | Finish the remaining tasks 3.7. |

View File

@ -14,7 +14,7 @@ Following are a few example searches on PR for convenience:
## Scope
These guidelines serve as a primary document for managing PRs in `etcd`. Everyone is welcome to help manage PRs but the work and responsibilities discussed in this document are created with `etcd` maintainers and active contributors in mind.
These guidelines serve as a primary document for managing PRs and review policy in `etcd`. Everyone is welcome to help manage PRs but the work and responsibilities discussed in this document are created with `etcd` maintainers and active contributors in mind.
## Ensure tests are run
@ -30,3 +30,32 @@ Reviewers are responsive in a timely fashion, but considering everyone is busy,
## Verify important labels are in place
Make sure that appropriate reviewers are added to the PR. Also, make sure that a milestone is identified. If any of these or other important labels are missing, add them. If a correct label cannot be decided, leave a comment for the maintainers to do so as needed.
## Review policy
To ensure code quality and shared ownership, this review policy applies to all pull requests (PRs).
### Default rule
PRs should get at least two approvals (/lgtm or GitHub review approval) before merging.
Notes:
* Approvals should come from a maintainer, reviewer, or submodule owner familiar with the relevant code or area.
* If theres disagreement, maintainers should discuss and agree before merging.
### Exceptions for Less Impactful PRs
For low-risk changes — such as:
* CI workflows
* Documentation
* Comments
The rule can be relaxed:
* One approval is generally enough.
However:
* If the author is a maintainer, they should still get approval from another maintainer, reviewer, or submodule owner, even for minor changes.

View File

@ -2135,6 +2135,19 @@
}
}
},
"etcdserverpbDowngradeInfo": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "enabled indicates whether the cluster is enabled to downgrade."
},
"targetVersion": {
"type": "string",
"description": "targetVersion is the target downgrade version."
}
}
},
"etcdserverpbDowngradeRequest": {
"type": "object",
"properties": {
@ -2689,7 +2702,7 @@
"count": {
"type": "string",
"format": "int64",
"description": "count is set to the number of keys within the range when requested."
"description": "count is set to the actual number of keys within the range when requested.\nUnlike Kvs, it is unaffected by limits and filters (e.g., Min/Max, Create/Modify, Revisions)\nand reflects the full count within the specified range."
}
}
},
@ -2834,12 +2847,16 @@
},
"storageVersion": {
"type": "string",
"description": "storageVersion is the version of the db file. It might be get updated with delay in relationship to the target cluster version."
"description": "storageVersion is the version of the db file. It might be updated with delay in relationship to the target cluster version."
},
"dbSizeQuota": {
"type": "string",
"format": "int64",
"title": "dbSizeQuota is the configured etcd storage quota in bytes (the value passed to etcd instance by flag --quota-backend-bytes)"
},
"downgradeInfo": {
"$ref": "#/definitions/etcdserverpbDowngradeInfo",
"description": "downgradeInfo indicates if there is downgrade process."
}
}
},

View File

@ -318,7 +318,7 @@
"name": {
"type": "string",
"format": "byte",
"description": "name is the election identifier that correponds to the leadership key."
"description": "name is the election identifier that corresponds to the leadership key."
},
"key": {
"type": "string",

View File

@ -36,7 +36,12 @@ weeks inactive voting period and as long as two maintainers are on board.
Changes in project governance could be initiated by opening a GitHub PR.
## SIG-etcd Governance
[SIG-etcd Governance] is documented in the Kubernetes/community repository.
[community membership]: /Documentation/contributor-guide/community-membership.md
[Code of Conduct]: /code-of-conduct.md
[contributor guide]: /CONTRIBUTING.md
[maintainers]: /OWNERS
[SIG-etcd Governance]: https://github.com/kubernetes/community/blob/master/sig-etcd/charter.md#deviations-from-sig-governance

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2013 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.

View File

@ -1,6 +1,8 @@
REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
.PHONY: all
all: build
include tests/robustness/makefile.mk
include $(REPOSITORY_ROOT)/tests/robustness/Makefile
.PHONY: build
build:
@ -54,10 +56,26 @@ test-grpcproxy-e2e: build
test-e2e-release: build
PASSES="release e2e" ./scripts/test.sh $(GO_TEST_FLAGS)
# When we release the first 3.7.0-alpha.0, we can remove `VERSION="3.7.99"` below.
.PHONY: test-release
test-release:
PASSES="release_tests" VERSION="3.7.99" ./scripts/test.sh $(GO_TEST_FLAGS)
.PHONY: test-robustness
test-robustness:
PASSES="robustness" ./scripts/test.sh $(GO_TEST_FLAGS)
.PHONY: test-coverage
test-coverage:
COVERDIR=covdir PASSES="build cov" ./scripts/test.sh $(GO_TEST_FLAGS)
.PHONY: upload-coverage-report
upload-coverage-report:
return_code=0; \
$(MAKE) test-coverage || return_code=$$?; \
COVERDIR=covdir ./scripts/codecov_upload.sh; \
exit $$return_code
.PHONY: fuzz
fuzz:
./scripts/fuzzing.sh
@ -210,3 +228,7 @@ verify-go-versions:
.PHONY: sync-toolchain-directive
sync-toolchain-directive:
./scripts/sync_go_toolchain_directive.sh
.PHONY: markdown-diff-lint
markdown-diff-lint:
./scripts/markdown_diff_lint.sh

16
OWNERS
View File

@ -2,11 +2,23 @@
approvers:
- ahrtr # Benjamin Wang <benjamin.ahrtr@gmail.com> <benjamin.wang@broadcom.com>
- fuweid # Wei Fu <fuweid89@gmail.com>
- jmhbnz # James Blair <jablair@redhat.com> <mail@jamesblair.net>
- serathius # Marek Siarkowicz <siarkowicz@google.com> <marek.siarkowicz@gmail.com>
- spzala # Sahdev Zala <spzala@us.ibm.com>
- wenjiaswe # Wenjia Zhang <wenjiazhang@google.com> <wenjia.swe@gmail.com>
reviewers:
- fuweid # Wei Fu <fuweid89@gmail.com>
- ivanvc # Ivan Valdes <ivan@vald.es>
- siyuanfoundation # Siyuan Zhang <sizhang@google.com> <physicsbug@gmail.com>
emeritus_approvers:
- bdarnell # Ben Darnell <ben@bendarnell.com>
- fanminshi # Fanmin Shi <fanmin.shi@gmail.com>
- gyuho # Gyuho Lee <gyuhox@gmail.com>
- hexfusion # Sam Batschelet <sbatsche@redhat.com>
- heyitsanthony # Anthony Romano <romanoanthony061@gmail.com>
- jingyih # Jingyi Hu <jingyih@google.com>
- jpbetz # Joe Betz <jpbetz@google.com>
- mitake # Hitoshi Mitake <h.mitake@gmail.com>
- philips # Brandon Philips <brandon@ifup.org>
- ptabor # Piotr Tabor <piotr.tabor@gmail.com>
- wenjiaswe # Wenjia Zhang <wenjiazhang@google.com> <wenjia.swe@gmail.com>
- xiang90 # Xiang Li <xiangli.cs@gmail.com>

View File

@ -5,7 +5,7 @@
[![Tests](https://github.com/etcd-io/etcd/actions/workflows/tests.yaml/badge.svg)](https://github.com/etcd-io/etcd/actions/workflows/tests.yaml)
[![codeql-analysis](https://github.com/etcd-io/etcd/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/etcd-io/etcd/actions/workflows/codeql-analysis.yml)
[![Docs](https://img.shields.io/badge/docs-latest-green.svg)](https://etcd.io/docs)
[![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/etcd-io/etcd)
[![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godocs.io/go.etcd.io/etcd/v3)
[![Releases](https://img.shields.io/github/release/etcd-io/etcd/all.svg?style=flat-square)](https://github.com/etcd-io/etcd/releases)
[![LICENSE](https://img.shields.io/github/license/etcd-io/etcd.svg?style=flat-square)](https://github.com/etcd-io/etcd/blob/main/LICENSE)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/etcd-io/etcd/badge)](https://scorecard.dev/viewer/?uri=github.com/etcd-io/etcd)
@ -42,6 +42,18 @@ See [etcdctl][etcdctl] for a simple command line client.
[vulcand]: https://github.com/vulcand/vulcand
[etcdctl]: https://github.com/etcd-io/etcd/tree/main/etcdctl
## Documentation
The most common API documentation you'll need can be found here:
* [go.etcd.io/etcd/api/v3](https://godocs.io/go.etcd.io/etcd/api/v3)
* [go.etcd.io/etcd/client/pkg/v3](https://godocs.io/go.etcd.io/etcd/client/pkg/v3)
* [go.etcd.io/etcd/client/v3](https://godocs.io/go.etcd.io/etcd/client/v3)
* [go.etcd.io/etcd/etcdctl/v3](https://godocs.io/go.etcd.io/etcd/etcdctl/v3)
* [go.etcd.io/etcd/pkg/v3](https://godocs.io/go.etcd.io/etcd/pkg/v3)
* [go.etcd.io/etcd/raft/v3](https://godocs.io/go.etcd.io/etcd/raft/v3)
* [go.etcd.io/etcd/server/v3](https://godocs.io/go.etcd.io/etcd/server/v3)
## Maintainers
[Maintainers](OWNERS) strive to shape an inclusive open source project culture where users are heard and contributors feel respected and empowered. Maintainers aim to build productive relationships across different companies and disciplines. Read more about [Maintainers role and responsibilities](Documentation/contributor-guide/community-membership.md#maintainers).
@ -186,19 +198,7 @@ See [PR management](https://github.com/etcd-io/etcd/blob/main/Documentation/cont
## etcd Emeritus Maintainers
These emeritus maintainers dedicated a part of their career to etcd and reviewed code, triaged bugs and pushed the project forward over a substantial period of time. Their contribution is greatly appreciated.
* Fanmin Shi
* Anthony Romano
* Brandon Philips
* Joe Betz
* Gyuho Lee
* Jingyi Hu
* Xiang Li
* Ben Darnell
* Sam Batschelet
* Piotr Tabor
* Hitoshi Mitake
etcd [emeritus maintainers](OWNERS) dedicated a part of their career to etcd and reviewed code, triaged bugs and pushed the project forward over a substantial period of time. Their contribution is greatly appreciated.
### License

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2020 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.

View File

@ -46,6 +46,9 @@ func request_KV_Range_0(ctx context.Context, marshaler runtime.Marshaler, client
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Range(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -70,6 +73,9 @@ func request_KV_Put_0(ctx context.Context, marshaler runtime.Marshaler, client e
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Put(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -94,6 +100,9 @@ func request_KV_DeleteRange_0(ctx context.Context, marshaler runtime.Marshaler,
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.DeleteRange(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -118,6 +127,9 @@ func request_KV_Txn_0(ctx context.Context, marshaler runtime.Marshaler, client e
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Txn(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -142,6 +154,9 @@ func request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler, clie
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Compact(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -158,14 +173,12 @@ func local_request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler
return protov1.MessageV2(msg), metadata, err
}
func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, chan error, error) {
func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, error) {
var metadata runtime.ServerMetadata
errChan := make(chan error, 1)
stream, err := client.Watch(ctx)
if err != nil {
grpclog.Errorf("Failed to start streaming: %v", err)
close(errChan)
return nil, metadata, errChan, err
return nil, metadata, err
}
dec := marshaler.NewDecoder(req.Body)
handleSend := func() error {
@ -185,10 +198,8 @@ func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, cli
return nil
}
go func() {
defer close(errChan)
for {
if err := handleSend(); err != nil {
errChan <- err
break
}
}
@ -199,10 +210,10 @@ func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, cli
header, err := stream.Header()
if err != nil {
grpclog.Errorf("Failed to get header from client: %v", err)
return nil, metadata, errChan, err
return nil, metadata, err
}
metadata.HeaderMD = header
return stream, metadata, errChan, nil
return stream, metadata, nil
}
func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
@ -213,6 +224,9 @@ func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseGrant(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -237,6 +251,9 @@ func request_Lease_LeaseRevoke_0(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -261,6 +278,9 @@ func request_Lease_LeaseRevoke_1(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -277,14 +297,12 @@ func local_request_Lease_LeaseRevoke_1(ctx context.Context, marshaler runtime.Ma
return protov1.MessageV2(msg), metadata, err
}
func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, chan error, error) {
func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, error) {
var metadata runtime.ServerMetadata
errChan := make(chan error, 1)
stream, err := client.LeaseKeepAlive(ctx)
if err != nil {
grpclog.Errorf("Failed to start streaming: %v", err)
close(errChan)
return nil, metadata, errChan, err
return nil, metadata, err
}
dec := marshaler.NewDecoder(req.Body)
handleSend := func() error {
@ -304,10 +322,8 @@ func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marsh
return nil
}
go func() {
defer close(errChan)
for {
if err := handleSend(); err != nil {
errChan <- err
break
}
}
@ -318,10 +334,10 @@ func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marsh
header, err := stream.Header()
if err != nil {
grpclog.Errorf("Failed to get header from client: %v", err)
return nil, metadata, errChan, err
return nil, metadata, err
}
metadata.HeaderMD = header
return stream, metadata, errChan, nil
return stream, metadata, nil
}
func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
@ -332,6 +348,9 @@ func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Mars
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -356,6 +375,9 @@ func request_Lease_LeaseTimeToLive_1(ctx context.Context, marshaler runtime.Mars
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -380,6 +402,9 @@ func request_Lease_LeaseLeases_0(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseLeases(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -404,6 +429,9 @@ func request_Lease_LeaseLeases_1(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.LeaseLeases(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -428,6 +456,9 @@ func request_Cluster_MemberAdd_0(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MemberAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -452,6 +483,9 @@ func request_Cluster_MemberRemove_0(ctx context.Context, marshaler runtime.Marsh
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MemberRemove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -476,6 +510,9 @@ func request_Cluster_MemberUpdate_0(ctx context.Context, marshaler runtime.Marsh
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MemberUpdate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -500,6 +537,9 @@ func request_Cluster_MemberList_0(ctx context.Context, marshaler runtime.Marshal
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MemberList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -524,6 +564,9 @@ func request_Cluster_MemberPromote_0(ctx context.Context, marshaler runtime.Mars
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MemberPromote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -548,6 +591,9 @@ func request_Maintenance_Alarm_0(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Alarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -572,6 +618,9 @@ func request_Maintenance_Status_0(ctx context.Context, marshaler runtime.Marshal
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -596,6 +645,9 @@ func request_Maintenance_Defragment_0(ctx context.Context, marshaler runtime.Mar
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Defragment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -620,6 +672,9 @@ func request_Maintenance_Hash_0(ctx context.Context, marshaler runtime.Marshaler
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Hash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -644,6 +699,9 @@ func request_Maintenance_HashKV_0(ctx context.Context, marshaler runtime.Marshal
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.HashKV(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -668,6 +726,9 @@ func request_Maintenance_Snapshot_0(ctx context.Context, marshaler runtime.Marsh
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
stream, err := client.Snapshot(ctx, &protoReq)
if err != nil {
return nil, metadata, err
@ -688,6 +749,9 @@ func request_Maintenance_MoveLeader_0(ctx context.Context, marshaler runtime.Mar
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.MoveLeader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -712,6 +776,9 @@ func request_Maintenance_Downgrade_0(ctx context.Context, marshaler runtime.Mars
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Downgrade(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -736,6 +803,9 @@ func request_Auth_AuthEnable_0(ctx context.Context, marshaler runtime.Marshaler,
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.AuthEnable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -760,6 +830,9 @@ func request_Auth_AuthDisable_0(ctx context.Context, marshaler runtime.Marshaler
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.AuthDisable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -784,6 +857,9 @@ func request_Auth_AuthStatus_0(ctx context.Context, marshaler runtime.Marshaler,
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.AuthStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -808,6 +884,9 @@ func request_Auth_Authenticate_0(ctx context.Context, marshaler runtime.Marshale
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -832,6 +911,9 @@ func request_Auth_UserAdd_0(ctx context.Context, marshaler runtime.Marshaler, cl
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -856,6 +938,9 @@ func request_Auth_UserGet_0(ctx context.Context, marshaler runtime.Marshaler, cl
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -880,6 +965,9 @@ func request_Auth_UserList_0(ctx context.Context, marshaler runtime.Marshaler, c
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -904,6 +992,9 @@ func request_Auth_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler,
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -928,6 +1019,9 @@ func request_Auth_UserChangePassword_0(ctx context.Context, marshaler runtime.Ma
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserChangePassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -952,6 +1046,9 @@ func request_Auth_UserGrantRole_0(ctx context.Context, marshaler runtime.Marshal
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserGrantRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -976,6 +1073,9 @@ func request_Auth_UserRevokeRole_0(ctx context.Context, marshaler runtime.Marsha
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.UserRevokeRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1000,6 +1100,9 @@ func request_Auth_RoleAdd_0(ctx context.Context, marshaler runtime.Marshaler, cl
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1024,6 +1127,9 @@ func request_Auth_RoleGet_0(ctx context.Context, marshaler runtime.Marshaler, cl
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1048,6 +1154,9 @@ func request_Auth_RoleList_0(ctx context.Context, marshaler runtime.Marshaler, c
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1072,6 +1181,9 @@ func request_Auth_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler,
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1096,6 +1208,9 @@ func request_Auth_RoleGrantPermission_0(ctx context.Context, marshaler runtime.M
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleGrantPermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -1120,6 +1235,9 @@ func request_Auth_RoleRevokePermission_0(ctx context.Context, marshaler runtime.
if err := marshaler.NewDecoder(req.Body).Decode(protov1.MessageV2(&protoReq)); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.RoleRevokePermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return protov1.MessageV2(msg), metadata, err
}
@ -2221,20 +2339,12 @@ func RegisterWatchHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, reqErrChan, err := request_Watch_Watch_0(annotatedContext, inboundMarshaler, client, req, pathParams)
resp, md, err := request_Watch_Watch_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
go func() {
for err := range reqErrChan {
if err != nil && !errors.Is(err, io.EOF) {
runtime.HTTPStreamError(annotatedContext, mux, outboundMarshaler, w, req, err)
}
}
}()
forward_Watch_Watch_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) {
m1, err := resp.Recv()
return protov1.MessageV2(m1), err
@ -2347,20 +2457,12 @@ func RegisterLeaseHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, reqErrChan, err := request_Lease_LeaseKeepAlive_0(annotatedContext, inboundMarshaler, client, req, pathParams)
resp, md, err := request_Lease_LeaseKeepAlive_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
go func() {
for err := range reqErrChan {
if err != nil && !errors.Is(err, io.EOF) {
runtime.HTTPStreamError(annotatedContext, mux, outboundMarshaler, w, req, err)
}
}
}()
forward_Lease_LeaseKeepAlive_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) {
m1, err := resp.Recv()
return protov1.MessageV2(m1), err

File diff suppressed because it is too large Load Diff

View File

@ -507,7 +507,9 @@ message RangeResponse {
repeated mvccpb.KeyValue kvs = 2;
// more indicates if there are more keys to return in the requested range.
bool more = 3;
// count is set to the number of keys within the range when requested.
// count is set to the actual number of keys within the range when requested.
// Unlike Kvs, it is unaffected by limits and filters (e.g., Min/Max, Create/Modify, Revisions)
// and reflects the full count within the specified range.
int64 count = 4;
}
@ -1194,10 +1196,19 @@ message StatusResponse {
int64 dbSizeInUse = 9 [(versionpb.etcd_version_field)="3.4"];
// isLearner indicates if the member is raft learner.
bool isLearner = 10 [(versionpb.etcd_version_field)="3.4"];
// storageVersion is the version of the db file. It might be get updated with delay in relationship to the target cluster version.
// storageVersion is the version of the db file. It might be updated with delay in relationship to the target cluster version.
string storageVersion = 11 [(versionpb.etcd_version_field)="3.6"];
// dbSizeQuota is the configured etcd storage quota in bytes (the value passed to etcd instance by flag --quota-backend-bytes)
int64 dbSizeQuota = 12 [(versionpb.etcd_version_field)="3.6"];
// downgradeInfo indicates if there is downgrade process.
DowngradeInfo downgradeInfo = 13 [(versionpb.etcd_version_field)="3.6"];
}
message DowngradeInfo {
// enabled indicates whether the cluster is enabled to downgrade.
bool enabled = 1;
// targetVersion is the target downgrade version.
string targetVersion = 2;
}
message AuthEnableRequest {

View File

@ -1,30 +1,30 @@
module go.etcd.io/etcd/api/v3
go 1.23
go 1.24
toolchain go1.23.6
toolchain go1.24.4
require (
github.com/coreos/go-semver v0.3.1
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1
github.com/stretchr/testify v1.10.0
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f
google.golang.org/grpc v1.70.0
google.golang.org/protobuf v1.36.4
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
google.golang.org/grpc v1.73.0
google.golang.org/protobuf v1.36.6
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -1,47 +1,47 @@
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -51,20 +51,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@ -73,14 +73,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View File

@ -212,7 +212,7 @@ var (
ErrInvalidAuthMgmt = Error(ErrGRPCInvalidAuthMgmt)
ErrClusterIDMismatch = Error(ErrGRPCClusterIDMismatch)
//revive:disable:var-naming
// Deprecated: Please use ErrGRPCClusterIDMismatch.
// Deprecated: Please use ErrClusterIDMismatch.
ErrClusterIdMismatch = ErrClusterIDMismatch
//revive:enable:var-naming

View File

@ -26,7 +26,7 @@ import (
var (
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
MinClusterVersion = "3.0.0"
Version = "3.6.0-alpha.0"
Version = "3.7.0-alpha.0"
APIVersion = "unknown"
// Git SHA Value will be set during build
@ -43,6 +43,7 @@ var (
V3_5 = semver.Version{Major: 3, Minor: 5}
V3_6 = semver.Version{Major: 3, Minor: 6}
V3_7 = semver.Version{Major: 3, Minor: 7}
V3_8 = semver.Version{Major: 3, Minor: 8}
V4_0 = semver.Version{Major: 4, Minor: 0}
// AllVersions keeps all the versions in ascending order.

View File

@ -10,6 +10,15 @@
},
{
"project": "github.com/anishathalye/porcupine",
"licenses": [
{
"type": "MIT License",
"confidence": 0.96875
}
]
},
{
"project": "github.com/antithesishq/antithesis-sdk-go",
"licenses": [
{
"type": "MIT License",
@ -36,7 +45,7 @@
]
},
{
"project": "github.com/cenkalti/backoff/v4",
"project": "github.com/cenkalti/backoff/v5",
"licenses": [
{
"type": "MIT License",
@ -260,33 +269,6 @@
}
]
},
{
"project": "github.com/klauspost/compress",
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 0.9376299376299376
}
]
},
{
"project": "github.com/klauspost/compress/internal/snapref",
"licenses": [
{
"type": "BSD 3-clause \"New\" or \"Revised\" License",
"confidence": 0.9663865546218487
}
]
},
{
"project": "github.com/klauspost/compress/zstd/internal/xxhash",
"licenses": [
{
"type": "MIT License",
"confidence": 1
}
]
},
{
"project": "github.com/mattn/go-colorable",
"licenses": [
@ -323,6 +305,24 @@
}
]
},
{
"project": "github.com/olekukonko/errors",
"licenses": [
{
"type": "MIT License",
"confidence": 1
}
]
},
{
"project": "github.com/olekukonko/ll",
"licenses": [
{
"type": "MIT License",
"confidence": 1
}
]
},
{
"project": "github.com/olekukonko/tablewriter",
"licenses": [
@ -472,7 +472,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -481,16 +481,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
}
]
},
{
"project": "go.etcd.io/etcd/client/v2",
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -499,7 +490,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -508,7 +499,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -517,7 +508,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -526,7 +517,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -535,7 +526,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -544,7 +535,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -553,7 +544,7 @@
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
"confidence": 0.9988925802879292
}
]
},
@ -674,6 +665,19 @@
}
]
},
{
"project": "go.yaml.in/yaml/v2",
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
},
{
"type": "MIT License",
"confidence": 0.8975609756097561
}
]
},
{
"project": "golang.org/x/crypto",
"licenses": [
@ -782,15 +786,6 @@
}
]
},
{
"project": "sigs.k8s.io/json",
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 0.9617021276595744
}
]
},
{
"project": "sigs.k8s.io/yaml",
"licenses": [
@ -803,18 +798,5 @@
"confidence": 1
}
]
},
{
"project": "sigs.k8s.io/yaml/goyaml.v2",
"licenses": [
{
"type": "Apache License 2.0",
"confidence": 1
},
{
"type": "MIT License",
"confidence": 0.8975609756097561
}
]
}
]

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2020 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.

4
cache/OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
# See the OWNERS docs at https://go.k8s.io/owners
labels:
- area/cache

3
cache/README.md vendored Normal file
View File

@ -0,0 +1,3 @@
# etcd cache
Experimental etcd client cache library.

228
cache/cache.go vendored Normal file
View File

@ -0,0 +1,228 @@
// Copyright 2025 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 cache
import (
"context"
"errors"
"fmt"
"strings"
"sync"
"time"
rpctypes "go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
clientv3 "go.etcd.io/etcd/client/v3"
)
// TODO: add gap-free replay for arbitrary startRevs and drop this guard.
var ErrUnsupportedWatch = errors.New("cache: unsupported watch parameters")
// Cache buffers a single etcd Watch for a given keyprefix and fanouts local watchers.
type Cache struct {
prefix string // prefix is the key-prefix this shard is responsible for ("" = root).
cfg Config // immutable runtime configuration
watcher clientv3.Watcher
demux *demux // demux fans incoming events out to active watchers and manages resync.
ready chan struct{}
stop context.CancelFunc
waitGroup sync.WaitGroup
internalCtx context.Context
}
// watchCtx collects all the knobs that both serveWatchEvents and watchRetryLoop need.
type watchCtx struct {
cache *Cache
backoffStart time.Duration
backoffMax time.Duration
onFirstResponse func() // callback to fire once on first upstream response
}
// New builds a cache shard that watches only the requested prefix.
// For the root cache pass "".
func New(watcher clientv3.Watcher, prefix string, opts ...Option) (*Cache, error) {
cfg := defaultConfig()
for _, opt := range opts {
opt(&cfg)
}
if cfg.HistoryWindowSize <= 0 {
return nil, fmt.Errorf("invalid HistoryWindowSize %d (must be > 0)", cfg.HistoryWindowSize)
}
internalCtx, cancel := context.WithCancel(context.Background())
cache := &Cache{
prefix: prefix,
cfg: cfg,
watcher: watcher,
ready: make(chan struct{}),
stop: cancel,
internalCtx: internalCtx,
}
cache.demux = NewDemux(internalCtx, &cache.waitGroup, cfg.HistoryWindowSize, cfg.ResyncInterval)
cache.waitGroup.Add(1)
go func() {
defer cache.waitGroup.Done()
readyOnce := sync.Once{}
watchCtx := &watchCtx{
cache: cache,
backoffStart: cfg.InitialBackoff,
backoffMax: cfg.MaxBackoff,
onFirstResponse: func() { readyOnce.Do(func() { close(cache.ready) }) },
}
serveWatchEvents(internalCtx, watchCtx)
}()
return cache, nil
}
// Watch registers a cache-backed watcher for a given key or prefix.
// It returns a WatchChan that streams WatchResponses containing events.
func (c *Cache) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
select {
case <-c.ready:
case <-ctx.Done():
emptyWatchChan := make(chan clientv3.WatchResponse)
close(emptyWatchChan)
return emptyWatchChan
}
op := clientv3.OpGet(key, opts...)
startRev := op.Rev()
// TODO: Support watch on subprefix and single key & arbitrary startRev support once we guarantee gap-free replay.
if key != c.prefix || !clientv3.IsOptsWithPrefix(opts) || startRev != 0 {
responseChan := make(chan clientv3.WatchResponse, 1)
responseChan <- clientv3.WatchResponse{Canceled: true}
close(responseChan)
return responseChan
}
w := newWatcher(c.cfg.PerWatcherBufferSize, func(k []byte) bool { return strings.HasPrefix(string(k), key) })
c.demux.Register(w, startRev)
responseChan := make(chan clientv3.WatchResponse)
c.waitGroup.Add(1)
go func() {
defer c.waitGroup.Done()
defer close(responseChan)
defer c.demux.Unregister(w)
for {
select {
case <-ctx.Done():
return
case <-c.internalCtx.Done():
return
case events, ok := <-w.eventQueue:
if !ok {
return
}
select {
case <-ctx.Done():
return
case <-c.internalCtx.Done():
return
case responseChan <- clientv3.WatchResponse{Events: events}:
}
}
}
}()
return responseChan
}
// Ready reports whether the cache has finished its initial load.
func (c *Cache) Ready() bool {
select {
case <-c.ready:
return true
default:
return false
}
}
// WaitReady blocks until the cache is ready or the ctx is cancelled.
func (c *Cache) WaitReady(ctx context.Context) error {
select {
case <-c.ready:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
// Close cancels the private context and blocks until all goroutines return.
func (c *Cache) Close() {
c.stop()
c.waitGroup.Wait()
}
func serveWatchEvents(ctx context.Context, watchCtx *watchCtx) {
backoff := watchCtx.backoffStart
for {
opts := []clientv3.OpOption{
clientv3.WithPrefix(),
clientv3.WithProgressNotify(),
clientv3.WithCreatedNotify(),
}
if oldestRev := watchCtx.cache.demux.PeekOldest(); oldestRev != 0 {
opts = append(opts,
clientv3.WithRev(oldestRev+1))
}
watchCh := watchCtx.cache.watcher.Watch(ctx, watchCtx.cache.prefix, opts...)
if err := readWatchChannel(watchCh, watchCtx.cache, watchCtx.cache.demux, watchCtx.onFirstResponse); err == nil {
return
}
select {
case <-ctx.Done():
return
case <-time.After(backoff):
}
if backoff < watchCtx.backoffMax {
backoff *= 2
}
}
}
// readWatchChannel reads an etcd Watch stream into History and enqueueCh, returning nil on cancel or first error.
func readWatchChannel(
watchChan clientv3.WatchChan,
cache *Cache,
demux *demux,
onFirstResponse func(),
) error {
for resp := range watchChan {
onFirstResponse()
if err := resp.Err(); err != nil {
if errors.Is(err, rpctypes.ErrCompacted) {
select {
case <-cache.ready:
// TODO: Reinitialize cache.ready safely; current direct channel assignment can race with concurrent watchers
cache.ready = make(chan struct{})
default:
}
demux.Purge()
}
return err
}
demux.Broadcast(resp.Events)
}
return nil
}

65
cache/config.go vendored Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2025 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 cache
import "time"
type Config struct {
// PerWatcherBufferSize caps each watchers buffered channel.
// Bigger values tolerate brief client slow-downs at the cost of extra memory.
PerWatcherBufferSize int
// HistoryWindowSize is the max events kept in memory for replay.
// It defines how far back the cache can replay events to lagging watchers
HistoryWindowSize int
// ResyncInterval controls how often the demux attempts to catch a lagging watcher up by replaying events from History.
ResyncInterval time.Duration
// InitialBackoff is the first delay to wait before retrying an upstream etcd Watch after it ends with an error.
InitialBackoff time.Duration
// MaxBackoff caps the exponential back-off between successive upstream watch retries.
MaxBackoff time.Duration
}
// TODO: tune via performance/load tests.
func defaultConfig() Config {
return Config{
PerWatcherBufferSize: 10,
HistoryWindowSize: 2048,
ResyncInterval: 50 * time.Millisecond,
InitialBackoff: 50 * time.Millisecond,
MaxBackoff: 2 * time.Second,
}
}
type Option func(*Config)
func WithPerWatcherBufferSize(n int) Option {
return func(c *Config) { c.PerWatcherBufferSize = n }
}
func WithHistoryWindowSize(n int) Option {
return func(c *Config) { c.HistoryWindowSize = n }
}
func WithResyncInterval(d time.Duration) Option {
return func(c *Config) { c.ResyncInterval = d }
}
func WithInitialBackoff(d time.Duration) Option {
return func(c *Config) { c.InitialBackoff = d }
}
func WithMaxBackoff(d time.Duration) Option {
return func(c *Config) { c.MaxBackoff = d }
}

185
cache/demux.go vendored Normal file
View File

@ -0,0 +1,185 @@
// Copyright 2025 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 cache
import (
"context"
"sync"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
)
type demux struct {
mu sync.RWMutex
// activeWatchers & laggingWatchers hold the first revision the watcher still needs (nextRev).
activeWatchers map[*watcher]int64
laggingWatchers map[*watcher]int64
history *ringBuffer
resyncInterval time.Duration
}
func NewDemux(ctx context.Context, wg *sync.WaitGroup, historyWindowSize int, resyncInterval time.Duration) *demux {
d := newDemux(historyWindowSize, resyncInterval)
wg.Add(1)
go func() {
defer wg.Done()
d.resyncLoop(ctx)
}()
return d
}
func newDemux(historyWindowSize int, resyncInterval time.Duration) *demux {
return &demux{
activeWatchers: make(map[*watcher]int64),
laggingWatchers: make(map[*watcher]int64),
history: newRingBuffer(historyWindowSize),
resyncInterval: resyncInterval,
}
}
// resyncLoop periodically tries to catch lagging watchers up by replaying events from History.
func (d *demux) resyncLoop(ctx context.Context) {
timer := time.NewTimer(d.resyncInterval)
defer timer.Stop()
for {
select {
case <-ctx.Done():
return
case <-timer.C:
d.resyncLaggingWatchers()
timer.Reset(d.resyncInterval)
}
}
}
func (d *demux) Register(w *watcher, startingRev int64) {
d.mu.Lock()
defer d.mu.Unlock()
latestRev := d.history.PeekLatest()
// Special case: 0 means “newest”.
if startingRev == 0 {
if latestRev == 0 {
d.activeWatchers[w] = 0
return
}
startingRev = latestRev + 1
}
if startingRev <= latestRev {
d.laggingWatchers[w] = startingRev
} else {
d.activeWatchers[w] = startingRev
}
}
func (d *demux) Unregister(w *watcher) {
func() {
d.mu.Lock()
defer d.mu.Unlock()
delete(d.activeWatchers, w)
delete(d.laggingWatchers, w)
}()
w.Stop()
}
func (d *demux) Broadcast(events []*clientv3.Event) {
if len(events) == 0 {
return
}
d.mu.Lock()
defer d.mu.Unlock()
d.history.Append(events)
lastRev := events[len(events)-1].Kv.ModRevision
for w, nextRev := range d.activeWatchers {
start := len(events)
for i, ev := range events {
if ev.Kv.ModRevision >= nextRev {
start = i
break
}
}
if start == len(events) {
continue
}
if !w.enqueueEvent(events[start:]) { // overflow → lagging
d.laggingWatchers[w] = nextRev
delete(d.activeWatchers, w)
} else {
d.activeWatchers[w] = lastRev + 1
}
}
}
// Purge is called when etcd compaction invalidates our cached history, so clients should resubscribe.
func (d *demux) Purge() {
d.mu.Lock()
defer d.mu.Unlock()
d.history.RebaseHistory()
for w := range d.activeWatchers {
w.Stop()
}
for w := range d.laggingWatchers {
w.Stop()
}
d.activeWatchers = make(map[*watcher]int64)
d.laggingWatchers = make(map[*watcher]int64)
}
func (d *demux) resyncLaggingWatchers() {
d.mu.Lock()
defer d.mu.Unlock()
oldestRev := d.history.PeekOldest()
for w, nextRev := range d.laggingWatchers {
if oldestRev != 0 && nextRev < oldestRev {
w.Stop()
delete(d.laggingWatchers, w)
continue
}
// TODO: re-enable keypredicate in Filter when nonzero startRev or performance tuning is needed
missed := d.history.Filter(nextRev)
enqueueFailed := false
for _, eventBatch := range missed {
if !w.enqueueEvent(eventBatch) { // buffer overflow: watcher still lagging
enqueueFailed = true
break
}
nextRev = eventBatch[0].Kv.ModRevision + 1
}
if !enqueueFailed {
delete(d.laggingWatchers, w)
d.activeWatchers[w] = nextRev
} else {
d.laggingWatchers[w] = nextRev
}
}
}
func (d *demux) PeekOldest() int64 {
d.mu.RLock()
defer d.mu.RUnlock()
return d.history.PeekOldest()
}

165
cache/demux_test.go vendored Normal file
View File

@ -0,0 +1,165 @@
// Copyright 2025 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 cache
import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"go.etcd.io/etcd/api/v3/mvccpb"
clientv3 "go.etcd.io/etcd/client/v3"
)
func TestBroadcastBatching(t *testing.T) {
tests := []struct {
name string
input []int64
wantRevs []int64
wantSizes []int
}{
{
name: "two groups",
input: []int64{14, 14, 15, 15, 15},
wantRevs: []int64{14},
wantSizes: []int{5},
},
{
name: "single group",
input: []int64{7, 7, 7},
wantRevs: []int64{7},
wantSizes: []int{3},
},
{
name: "all distinct",
input: []int64{1, 2, 3},
wantRevs: []int64{1},
wantSizes: []int{3},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
d := newDemux(16, 10*time.Millisecond)
w := newWatcher(len(tt.input)+1, nil)
d.Register(w, 0)
d.Broadcast(eventRevs(tt.input...))
gotRevs, gotSizes := readBatches(t, w, len(tt.wantRevs))
if diff := cmp.Diff(tt.wantRevs, gotRevs); diff != "" {
t.Fatalf("revision mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tt.wantSizes, gotSizes); diff != "" {
t.Fatalf("batch size mismatch (-want +got):\n%s", diff)
}
})
}
}
func TestSlowWatcherResync(t *testing.T) {
tests := []struct {
name string
input []int64
wantInitialRevs []int64
wantInitialSizes []int
wantResyncRevs []int64
wantResyncSizes []int
}{
{
name: "single event overflow",
input: []int64{1, 2, 3},
wantInitialRevs: []int64{1},
wantInitialSizes: []int{3},
wantResyncRevs: []int64{},
wantResyncSizes: []int{},
},
{
name: "multi events batch overflow",
input: []int64{10, 10, 11, 12, 12},
wantInitialRevs: []int64{10},
wantInitialSizes: []int{5},
wantResyncRevs: []int64{},
wantResyncSizes: []int{},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
d := newDemux(16, 10*time.Millisecond)
w := newWatcher(1, nil)
d.Register(w, 0)
d.Broadcast(eventRevs(tt.input...))
gotInitRevs, gotInitSizes := readBatches(t, w, len(tt.wantInitialRevs))
if diff := cmp.Diff(tt.wantInitialRevs, gotInitRevs); diff != "" {
t.Fatalf("initial revs mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tt.wantInitialSizes, gotInitSizes); diff != "" {
t.Fatalf("initial batch sizes mismatch (-want +got):\n%s", diff)
}
gotRevs, gotSizes := make([]int64, 0, len(tt.wantResyncRevs)), make([]int, 0, len(tt.wantResyncRevs))
for len(gotRevs) < len(tt.wantResyncRevs) {
d.resyncLaggingWatchers()
revs, sizes := readBatches(t, w, 1)
gotRevs = append(gotRevs, revs...)
gotSizes = append(gotSizes, sizes...)
}
if diff := cmp.Diff(tt.wantResyncRevs, gotRevs); diff != "" {
t.Fatalf("resync revs mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tt.wantResyncSizes, gotSizes); diff != "" {
t.Fatalf("resync batch sizes mismatch (-want +got):\n%s", diff)
}
})
}
}
func eventRevs(revs ...int64) []*clientv3.Event {
events := make([]*clientv3.Event, 0, len(revs))
for _, r := range revs {
kv := &mvccpb.KeyValue{
Key: []byte("k"),
Value: []byte("v"),
ModRevision: r,
}
events = append(events, &clientv3.Event{
Type: clientv3.EventTypePut,
Kv: kv,
})
}
return events
}
func readBatches(t *testing.T, w *watcher, n int) (revs []int64, sizes []int) {
t.Helper()
timeout := time.After(2 * time.Second)
for len(revs) < n {
select {
case batch := <-w.eventQueue:
revs = append(revs, batch[0].Kv.ModRevision)
sizes = append(sizes, len(batch))
case <-timeout:
t.Fatalf("timed out waiting for %d batches; got %d", n, len(revs))
}
}
return revs, sizes
}

36
cache/go.mod vendored Normal file
View File

@ -0,0 +1,36 @@
module go.etcd.io/etcd/cache/v3
go 1.24
toolchain go1.24.4
require (
github.com/google/go-cmp v0.7.0
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
go.etcd.io/etcd/client/v3 v3.6.0-alpha.0
)
require (
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
)
replace (
go.etcd.io/etcd/api/v3 => ../api
go.etcd.io/etcd/client/pkg/v3 => ../client/pkg
go.etcd.io/etcd/client/v3 => ../client/v3
)

107
cache/go.sum vendored Normal file
View File

@ -0,0 +1,107 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,4 +1,4 @@
// Copyright 2015 The etcd Authors
// Copyright 2025 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.
@ -12,26 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package client
package cache
import "fmt"
type Prefix string
type ClusterError struct {
Errors []error
}
func (ce *ClusterError) Error() string {
s := ErrClusterUnavailable.Error()
for i, e := range ce.Errors {
s += fmt.Sprintf("; error #%d: %s\n", i, e)
func (prefix Prefix) Match(key []byte) bool {
if prefix == "" {
return true
}
return s
}
func (ce *ClusterError) Detail() string {
s := ""
for i, e := range ce.Errors {
s += fmt.Sprintf("error #%d: %s\n", i, e)
}
return s
prefixLen := len(prefix)
return len(key) >= prefixLen && string(key[:prefixLen]) == string(prefix)
}

115
cache/ringbuffer.go vendored Normal file
View File

@ -0,0 +1,115 @@
// Copyright 2025 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 cache
import (
"fmt"
clientv3 "go.etcd.io/etcd/client/v3"
)
type ringBuffer struct {
buffer []batch
// head is the index immediately after the last non-empty entry in the buffer (i.e., the next write position).
head, tail, size int
}
// batch groups all events that share one ModRevision.
type batch struct {
rev int64
events []*clientv3.Event
}
type KeyPredicate = func([]byte) bool
func newRingBuffer(capacity int) *ringBuffer {
// assume capacity > 0 validated by Cache
return &ringBuffer{
buffer: make([]batch, capacity),
}
}
func (r *ringBuffer) Append(events []*clientv3.Event) {
start := 0
for end := 1; end < len(events); end++ {
if events[end].Kv.ModRevision != events[start].Kv.ModRevision {
r.append(batch{
rev: events[start].Kv.ModRevision,
events: events[start:end],
})
start = end
}
}
if start < len(events) {
r.append(batch{
rev: events[start].Kv.ModRevision,
events: events[start:],
})
}
}
func (r *ringBuffer) append(b batch) {
if len(b.events) == 0 {
return
}
if r.size == len(r.buffer) {
r.tail = (r.tail + 1) % len(r.buffer)
} else {
r.size++
}
r.buffer[r.head] = b
r.head = (r.head + 1) % len(r.buffer)
}
// Filter returns all events in the buffer whose ModRevision is >= minRev.
// TODO: use binary search on the ring buffer to locate the first entry >= nextRev instead of a full scan
func (r *ringBuffer) Filter(minRev int64) (eventBatches [][]*clientv3.Event) {
eventBatches = make([][]*clientv3.Event, 0, r.size)
for n, i := 0, r.tail; n < r.size; n, i = n+1, (i+1)%len(r.buffer) {
eventBatch := r.buffer[i]
if eventBatch.events == nil {
panic(fmt.Sprintf("ringBuffer.Filter: unexpected nil eventBatch at index %d", i))
}
if eventBatch.rev >= minRev {
eventBatches = append(eventBatches, eventBatch.events)
}
}
return eventBatches
}
// PeekLatest returns the most recently-appended event (or nil if empty).
func (r *ringBuffer) PeekLatest() int64 {
if r.size == 0 {
return 0
}
idx := (r.head - 1 + len(r.buffer)) % len(r.buffer)
return r.buffer[idx].rev
}
// PeekOldest returns the oldest event currently stored (or nil if empty).
func (r *ringBuffer) PeekOldest() int64 {
if r.size == 0 {
return 0
}
return r.buffer[r.tail].rev
}
func (r *ringBuffer) RebaseHistory() {
r.head, r.tail, r.size = 0, 0, 0
for i := range r.buffer {
r.buffer[i] = batch{}
}
}

308
cache/ringbuffer_test.go vendored Normal file
View File

@ -0,0 +1,308 @@
// Copyright 2025 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 cache
import (
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
"go.etcd.io/etcd/api/v3/mvccpb"
clientv3 "go.etcd.io/etcd/client/v3"
)
func TestPeekLatestAndOldest(t *testing.T) {
tests := []struct {
name string
capacity int
revs []int64
wantLatestRev int64
wantOldestRev int64
}{
{
name: "empty_buffer",
capacity: 4,
revs: nil,
wantLatestRev: 0,
wantOldestRev: 0,
},
{
name: "single_element",
capacity: 8,
revs: []int64{1},
wantLatestRev: 1,
wantOldestRev: 1,
},
{
name: "ascending_fill",
capacity: 4,
revs: []int64{1, 2, 3, 4},
wantLatestRev: 4,
wantOldestRev: 1,
},
{
name: "overwrite_when_full",
capacity: 3,
revs: []int64{5, 6, 7, 8},
wantLatestRev: 8,
wantOldestRev: 6,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
rb := newRingBuffer(tt.capacity)
for _, r := range tt.revs {
batch, err := makeEventBatch(r, "k", 1)
if err != nil {
t.Fatalf("makeEventBatch(%d, k, 1) failed: %v", r, err)
}
rb.Append(batch)
}
latestRev := rb.PeekLatest()
oldestRev := rb.PeekOldest()
gotLatestRev := latestRev
gotOldestRev := oldestRev
if tt.wantLatestRev != gotLatestRev {
t.Fatalf("PeekLatest()=%d, want=%d", gotLatestRev, tt.wantLatestRev)
}
if tt.wantOldestRev != gotOldestRev {
t.Fatalf("PeekOldest()=%d, want=%d", gotOldestRev, tt.wantOldestRev)
}
})
}
}
func TestFilter(t *testing.T) {
tests := []struct {
name string
capacity int
revs []int64
minRev int64
wantFilteredRevs []int64
wantLatestRev int64
}{
{
name: "no_filter",
capacity: 5,
revs: []int64{1, 2, 3},
minRev: 0,
wantFilteredRevs: []int64{1, 2, 3},
wantLatestRev: 3,
},
{
name: "partial_match",
capacity: 5,
revs: []int64{10, 11, 12, 13},
minRev: 12,
wantFilteredRevs: []int64{12, 13},
wantLatestRev: 13,
},
{
name: "filter_when_full",
capacity: 3,
revs: []int64{20, 21, 22, 23, 24},
minRev: 23,
wantFilteredRevs: []int64{23, 24},
wantLatestRev: 24,
},
{
name: "none_match",
capacity: 4,
revs: []int64{30, 31},
minRev: 100,
wantFilteredRevs: []int64{},
wantLatestRev: 31,
},
{
name: "empty_buffer",
capacity: 3,
revs: nil,
minRev: 0,
wantFilteredRevs: []int64{},
wantLatestRev: 0,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
rb := newRingBuffer(tt.capacity)
for _, r := range tt.revs {
batch, err := makeEventBatch(r, "k", 11)
if err != nil {
t.Fatalf("makeEventBatch(%d, k, 11) failed: %v", r, err)
}
rb.Append(batch)
}
gotBatches := rb.Filter(tt.minRev)
gotRevs := make([]int64, len(gotBatches))
for i, b := range gotBatches {
gotRevs[i] = b[0].Kv.ModRevision
}
if diff := cmp.Diff(tt.wantFilteredRevs, gotRevs); diff != "" {
t.Fatalf("Filter() revisions mismatch (-want +got):\n%s", diff)
}
})
}
}
func TestAtomicOrdered(t *testing.T) {
tests := []struct {
name string
capacity int
inputs []struct {
rev int64
key string
size int
}
wantRev []int64
wantSize []int
}{
{
name: "unfiltered",
capacity: 5,
inputs: []struct {
rev int64
key string
size int
}{
{5, "a", 1},
{10, "b", 3},
{15, "c", 7},
{20, "d", 11},
},
wantRev: []int64{5, 10, 15, 20},
wantSize: []int{1, 3, 7, 11},
},
{
name: "across_wrap",
capacity: 3,
inputs: []struct {
rev int64
key string
size int
}{
{1, "a", 2},
{2, "b", 1},
{3, "c", 3},
{4, "d", 7},
},
wantRev: []int64{2, 3, 4},
wantSize: []int{1, 3, 7},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
rb := newRingBuffer(tt.capacity)
for _, in := range tt.inputs {
batch, err := makeEventBatch(in.rev, in.key, in.size)
if err != nil {
t.Fatalf("makeEventBatch(%d, k, 1) failed: %v", in.rev, err)
}
rb.Append(batch)
}
gotBatches := rb.Filter(0)
if len(gotBatches) != len(tt.wantRev) {
t.Fatalf("len(got) = %d, want %d", len(gotBatches), len(tt.wantRev))
}
for i, b := range gotBatches {
if b[0].Kv.ModRevision != tt.wantRev[i] {
t.Errorf("at idx %d: rev = %d, want %d", i, b[0].Kv.ModRevision, tt.wantRev[i])
}
if batchSize := len(b); batchSize != tt.wantSize[i] {
t.Errorf("at rev %d: events.len = %d, want %d", b[0].Kv.ModRevision, batchSize, tt.wantSize[i])
}
}
})
}
}
func TestRebaseHistory(t *testing.T) {
tests := []struct {
name string
revs []int64
}{
{
name: "rebase_empty_buffer",
revs: nil,
},
{
name: "rebase_after_data",
revs: []int64{7, 8, 9},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
rb := newRingBuffer(4)
for _, r := range tt.revs {
batch, err := makeEventBatch(r, "k", 1)
if err != nil {
t.Fatalf("makeEventBatch(%d, k, 1) failed: %v", r, err)
}
rb.Append(batch)
}
rb.RebaseHistory()
oldestRev := rb.PeekOldest()
latestRev := rb.PeekLatest()
if oldestRev != 0 {
t.Fatalf("PeekOldest()=%d, want=%d", oldestRev, 0)
}
if latestRev != 0 {
t.Fatalf("PeekLatest()=%d, want=%d", latestRev, 0)
}
batches := rb.Filter(0)
if len(batches) != 0 {
t.Fatalf("Filter() len(events)=%d, want=%d", len(batches), 0)
}
})
}
}
func makeEventBatch(rev int64, key string, batchSize int) ([]*clientv3.Event, error) {
if batchSize < 0 {
return nil, fmt.Errorf("invalid batchSize %d", batchSize)
}
events := make([]*clientv3.Event, batchSize)
for i := range events {
events[i] = &clientv3.Event{
Kv: &mvccpb.KeyValue{
Key: []byte(fmt.Sprintf("%s-%d", key, i)),
ModRevision: rev,
},
}
}
return events, nil
}

70
cache/watcher.go vendored Normal file
View File

@ -0,0 +1,70 @@
// Copyright 2025 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 cache
import (
"sync/atomic"
clientv3 "go.etcd.io/etcd/client/v3"
)
// watcher holds one clients buffered stream of events.
type watcher struct {
eventQueue chan []*clientv3.Event
keyPred KeyPredicate
stopped int32
done chan struct{} // closed together with Stop()
}
func newWatcher(bufSize int, pred KeyPredicate) *watcher {
return &watcher{
eventQueue: make(chan []*clientv3.Event, bufSize),
keyPred: pred,
done: make(chan struct{}),
}
}
// true -> events delivered (or filtered/duplicate)
// false -> buffer full (caller should mark watcher “lagging”)
func (w *watcher) enqueueEvent(eventBatch []*clientv3.Event) bool {
if w.keyPred != nil {
filtered := make([]*clientv3.Event, 0, len(eventBatch))
for _, event := range eventBatch {
if w.keyPred(event.Kv.Key) {
filtered = append(filtered, event)
}
}
if len(filtered) == 0 {
return true
}
eventBatch = filtered
}
select {
case w.eventQueue <- eventBatch:
return true
default:
return false
}
}
// Stop closes the event channel atomically.
func (w *watcher) Stop() {
if atomic.CompareAndSwapInt32(&w.stopped, 0, 1) {
close(w.eventQueue)
close(w.done)
}
}
func (w *watcher) Done() <-chan struct{} { return w.done }

View File

@ -1,113 +0,0 @@
# etcd/client
etcd/client is the Go client library for etcd.
[![GoDoc](https://godoc.org/go.etcd.io/etcd/client?status.png)](https://godoc.org/go.etcd.io/etcd/client)
For full compatibility, it is recommended to install released versions of clients using go modules.
## Install
```bash
go get go.etcd.io/etcd/v3/client
```
## Usage
```go
package main
import (
"context"
"log"
"time"
"go.etcd.io/etcd/v3/client"
)
func main() {
cfg := client.Config{
Endpoints: []string{"http://127.0.0.1:2379"},
Transport: client.DefaultTransport,
// set timeout per request to fail fast when the target endpoint is unavailable
HeaderTimeoutPerRequest: time.Second,
}
c, err := client.New(cfg)
if err != nil {
log.Fatal(err)
}
kapi := client.NewKeysAPI(c)
// set "/foo" key with "bar" value
log.Print("Setting '/foo' key with 'bar' value")
resp, err := kapi.Set(context.Background(), "/foo", "bar", nil)
if err != nil {
log.Fatal(err)
} else {
// print common key info
log.Printf("Set is done. Metadata is %q\n", resp)
}
// get "/foo" key's value
log.Print("Getting '/foo' key value")
resp, err = kapi.Get(context.Background(), "/foo", nil)
if err != nil {
log.Fatal(err)
} else {
// print common key info
log.Printf("Get is done. Metadata is %q\n", resp)
// print value
log.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value)
}
}
```
## Error Handling
etcd client might return three types of errors.
- context error
Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered.
- cluster error
Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned.
- response error
If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error.
Here is the example code to handle client errors:
```go
cfg := client.Config{Endpoints: []string{"http://etcd1:2379","http://etcd2:2379","http://etcd3:2379"}}
c, err := client.New(cfg)
if err != nil {
log.Fatal(err)
}
kapi := client.NewKeysAPI(c)
resp, err := kapi.Set(ctx, "test", "bar", nil)
if err != nil {
var cerr *client.ClusterError
if errors.Is(err, context.Canceled) {
// ctx is canceled by another routine
} else if errors.Is(err, context.DeadlineExceeded) {
// ctx is attached with a deadline and it exceeded
} else if errors.As(err, &cerr) {
// process (cerr.Errors)
} else {
// bad cluster endpoints, which are not etcd servers
}
}
```
## Caveat
1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process.
2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened.
3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention.
4. etcd/client cannot detect whether a member is healthy with watches and non-quorum read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. Instead, users can either issue quorum read requests or monitor the /health endpoint for member health information.

View File

@ -1,236 +0,0 @@
// 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 client
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/url"
)
type Role struct {
Role string `json:"role"`
Permissions Permissions `json:"permissions"`
Grant *Permissions `json:"grant,omitempty"`
Revoke *Permissions `json:"revoke,omitempty"`
}
type Permissions struct {
KV rwPermission `json:"kv"`
}
type rwPermission struct {
Read []string `json:"read"`
Write []string `json:"write"`
}
type PermissionType int
const (
ReadPermission PermissionType = iota
WritePermission
ReadWritePermission
)
// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to
// interact with etcd's role creation and modification features.
func NewAuthRoleAPI(c Client) AuthRoleAPI {
return &httpAuthRoleAPI{
client: c,
}
}
type AuthRoleAPI interface {
// AddRole adds a role.
AddRole(ctx context.Context, role string) error
// RemoveRole removes a role.
RemoveRole(ctx context.Context, role string) error
// GetRole retrieves role details.
GetRole(ctx context.Context, role string) (*Role, error)
// GrantRoleKV grants a role some permission prefixes for the KV store.
GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
// RevokeRoleKV revokes some permission prefixes for a role on the KV store.
RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
// ListRoles lists roles.
ListRoles(ctx context.Context) ([]string, error)
}
type httpAuthRoleAPI struct {
client httpClient
}
type authRoleAPIAction struct {
verb string
name string
role *Role
}
type authRoleAPIList struct{}
func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "roles", "")
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
req.Header.Set("Content-Type", "application/json")
return req
}
func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "roles", l.name)
if l.role == nil {
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
}
b, err := json.Marshal(l.role)
if err != nil {
panic(err)
}
body := bytes.NewReader(b)
req, _ := http.NewRequest(l.verb, u.String(), body)
req.Header.Set("Content-Type", "application/json")
return req
}
func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
resp, body, err := r.client.Do(ctx, &authRoleAPIList{})
if err != nil {
return nil, err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
return nil, err
}
var roleList struct {
Roles []Role `json:"roles"`
}
if err = json.Unmarshal(body, &roleList); err != nil {
return nil, err
}
ret := make([]string, 0, len(roleList.Roles))
for _, r := range roleList.Roles {
ret = append(ret, r.Role)
}
return ret, nil
}
func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error {
role := &Role{
Role: rolename,
}
return r.addRemoveRole(ctx, &authRoleAPIAction{
verb: http.MethodPut,
name: rolename,
role: role,
})
}
func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
return r.addRemoveRole(ctx, &authRoleAPIAction{
verb: http.MethodDelete,
name: rolename,
})
}
func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error {
resp, body, err := r.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return err
}
return sec
}
return nil
}
func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
return r.modRole(ctx, &authRoleAPIAction{
verb: http.MethodGet,
name: rolename,
})
}
func buildRWPermission(prefixes []string, permType PermissionType) rwPermission {
var out rwPermission
switch permType {
case ReadPermission:
out.Read = prefixes
case WritePermission:
out.Write = prefixes
case ReadWritePermission:
out.Read = prefixes
out.Write = prefixes
}
return out
}
func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
rwp := buildRWPermission(prefixes, permType)
role := &Role{
Role: rolename,
Grant: &Permissions{
KV: rwp,
},
}
return r.modRole(ctx, &authRoleAPIAction{
verb: http.MethodPut,
name: rolename,
role: role,
})
}
func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
rwp := buildRWPermission(prefixes, permType)
role := &Role{
Role: rolename,
Revoke: &Permissions{
KV: rwp,
},
}
return r.modRole(ctx, &authRoleAPIAction{
verb: http.MethodPut,
name: rolename,
role: role,
})
}
func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) {
resp, body, err := r.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec authError
err = json.Unmarshal(body, &sec)
if err != nil {
return nil, err
}
return nil, sec
}
var role Role
if err = json.Unmarshal(body, &role); err != nil {
return nil, err
}
return &role, nil
}

View File

@ -1,317 +0,0 @@
// 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 client
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/url"
"path"
)
var defaultV2AuthPrefix = "/v2/auth"
type User struct {
User string `json:"user"`
Password string `json:"password,omitempty"`
Roles []string `json:"roles"`
Grant []string `json:"grant,omitempty"`
Revoke []string `json:"revoke,omitempty"`
}
// userListEntry is the user representation given by the server for ListUsers
type userListEntry struct {
User string `json:"user"`
Roles []Role `json:"roles"`
}
type UserRoles struct {
User string `json:"user"`
Roles []Role `json:"roles"`
}
func v2AuthURL(ep url.URL, action string, name string) *url.URL {
if name != "" {
ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name)
return &ep
}
ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action)
return &ep
}
// NewAuthAPI constructs a new AuthAPI that uses HTTP to
// interact with etcd's general auth features.
func NewAuthAPI(c Client) AuthAPI {
return &httpAuthAPI{
client: c,
}
}
type AuthAPI interface {
// Enable auth.
Enable(ctx context.Context) error
// Disable auth.
Disable(ctx context.Context) error
}
type httpAuthAPI struct {
client httpClient
}
func (s *httpAuthAPI) Enable(ctx context.Context) error {
return s.enableDisable(ctx, &authAPIAction{http.MethodPut})
}
func (s *httpAuthAPI) Disable(ctx context.Context) error {
return s.enableDisable(ctx, &authAPIAction{http.MethodDelete})
}
func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error {
resp, body, err := s.client.Do(ctx, req)
if err != nil {
return err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec authError
err = json.Unmarshal(body, &sec)
if err != nil {
return err
}
return sec
}
return nil
}
type authAPIAction struct {
verb string
}
func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "enable", "")
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
}
type authError struct {
Message string `json:"message"`
Code int `json:"-"`
}
func (e authError) Error() string {
return e.Message
}
// NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to
// interact with etcd's user creation and modification features.
func NewAuthUserAPI(c Client) AuthUserAPI {
return &httpAuthUserAPI{
client: c,
}
}
type AuthUserAPI interface {
// AddUser adds a user.
AddUser(ctx context.Context, username string, password string) error
// RemoveUser removes a user.
RemoveUser(ctx context.Context, username string) error
// GetUser retrieves user details.
GetUser(ctx context.Context, username string) (*User, error)
// GrantUser grants a user some permission roles.
GrantUser(ctx context.Context, username string, roles []string) (*User, error)
// RevokeUser revokes some permission roles from a user.
RevokeUser(ctx context.Context, username string, roles []string) (*User, error)
// ChangePassword changes the user's password.
ChangePassword(ctx context.Context, username string, password string) (*User, error)
// ListUsers lists the users.
ListUsers(ctx context.Context) ([]string, error)
}
type httpAuthUserAPI struct {
client httpClient
}
type authUserAPIAction struct {
verb string
username string
user *User
}
type authUserAPIList struct{}
func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "users", "")
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
req.Header.Set("Content-Type", "application/json")
return req
}
func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "users", l.username)
if l.user == nil {
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
}
b, err := json.Marshal(l.user)
if err != nil {
panic(err)
}
body := bytes.NewReader(b)
req, _ := http.NewRequest(l.verb, u.String(), body)
req.Header.Set("Content-Type", "application/json")
return req
}
func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) {
resp, body, err := u.client.Do(ctx, &authUserAPIList{})
if err != nil {
return nil, err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec authError
err = json.Unmarshal(body, &sec)
if err != nil {
return nil, err
}
return nil, sec
}
var userList struct {
Users []userListEntry `json:"users"`
}
if err = json.Unmarshal(body, &userList); err != nil {
return nil, err
}
ret := make([]string, 0, len(userList.Users))
for _, u := range userList.Users {
ret = append(ret, u.User)
}
return ret, nil
}
func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error {
user := &User{
User: username,
Password: password,
}
return u.addRemoveUser(ctx, &authUserAPIAction{
verb: http.MethodPut,
username: username,
user: user,
})
}
func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username string) error {
return u.addRemoveUser(ctx, &authUserAPIAction{
verb: http.MethodDelete,
username: username,
})
}
func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAction) error {
resp, body, err := u.client.Do(ctx, req)
if err != nil {
return err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec authError
err = json.Unmarshal(body, &sec)
if err != nil {
return err
}
return sec
}
return nil
}
func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string) (*User, error) {
return u.modUser(ctx, &authUserAPIAction{
verb: http.MethodGet,
username: username,
})
}
func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) {
user := &User{
User: username,
Grant: roles,
}
return u.modUser(ctx, &authUserAPIAction{
verb: http.MethodPut,
username: username,
user: user,
})
}
func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) {
user := &User{
User: username,
Revoke: roles,
}
return u.modUser(ctx, &authUserAPIAction{
verb: http.MethodPut,
username: username,
user: user,
})
}
func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) {
user := &User{
User: username,
Password: password,
}
return u.modUser(ctx, &authUserAPIAction{
verb: http.MethodPut,
username: username,
user: user,
})
}
func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) (*User, error) {
resp, body, err := u.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec authError
err = json.Unmarshal(body, &sec)
if err != nil {
return nil, err
}
return nil, sec
}
var user User
if err = json.Unmarshal(body, &user); err != nil {
var userR UserRoles
if urerr := json.Unmarshal(body, &userR); urerr != nil {
return nil, err
}
user.User = userR.User
for _, r := range userR.Roles {
user.Roles = append(user.Roles, r.Role)
}
}
return &user, nil
}

View File

@ -1,18 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// borrowed from golang/net/context/ctxhttp/cancelreq.go
package client
import "net/http"
func requestCanceler(req *http.Request) func() {
ch := make(chan struct{})
req.Cancel = ch
return func() {
close(ch)
}
}

View File

@ -1,719 +0,0 @@
// 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 client
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"math/rand"
"net"
"net/http"
"net/url"
"sort"
"strconv"
"sync"
"time"
"go.etcd.io/etcd/api/v3/version"
)
var (
ErrNoEndpoints = errors.New("client: no endpoints available")
ErrTooManyRedirects = errors.New("client: too many redirects")
ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured")
ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available")
errTooManyRedirectChecks = errors.New("client: too many redirect checks")
// oneShotCtxValue is set on a context using WithValue(&oneShotValue) so
// that Do() will not retry a request
oneShotCtxValue any
)
var DefaultRequestTimeout = 5 * time.Second
var DefaultTransport CancelableTransport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
}
type EndpointSelectionMode int
const (
// EndpointSelectionRandom is the default value of the 'SelectionMode'.
// As the name implies, the client object will pick a node from the members
// of the cluster in a random fashion. If the cluster has three members, A, B,
// and C, the client picks any node from its three members as its request
// destination.
EndpointSelectionRandom EndpointSelectionMode = iota
// If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader',
// requests are sent directly to the cluster leader. This reduces
// forwarding roundtrips compared to making requests to etcd followers
// who then forward them to the cluster leader. In the event of a leader
// failure, however, clients configured this way cannot prioritize among
// the remaining etcd followers. Therefore, when a client sets 'SelectionMode'
// to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to
// maintain its knowledge of current cluster state.
//
// This mode should be used with Client.AutoSync().
EndpointSelectionPrioritizeLeader
)
type Config struct {
// Endpoints defines a set of URLs (schemes, hosts and ports only)
// that can be used to communicate with a logical etcd cluster. For
// example, a three-node cluster could be provided like so:
//
// Endpoints: []string{
// "http://node1.example.com:2379",
// "http://node2.example.com:2379",
// "http://node3.example.com:2379",
// }
//
// If multiple endpoints are provided, the Client will attempt to
// use them all in the event that one or more of them are unusable.
//
// If Client.Sync is ever called, the Client may cache an alternate
// set of endpoints to continue operation.
Endpoints []string
// Transport is used by the Client to drive HTTP requests. If not
// provided, DefaultTransport will be used.
Transport CancelableTransport
// CheckRedirect specifies the policy for handling HTTP redirects.
// If CheckRedirect is not nil, the Client calls it before
// following an HTTP redirect. The sole argument is the number of
// requests that have already been made. If CheckRedirect returns
// an error, Client.Do will not make any further requests and return
// the error back it to the caller.
//
// If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests.
CheckRedirect CheckRedirectFunc
// Username specifies the user credential to add as an authorization header
Username string
// Password is the password for the specified user to add as an authorization header
// to the request.
Password string
// HeaderTimeoutPerRequest specifies the time limit to wait for response
// header in a single request made by the Client. The timeout includes
// connection time, any redirects, and header wait time.
//
// For non-watch GET request, server returns the response body immediately.
// For PUT/POST/DELETE request, server will attempt to commit request
// before responding, which is expected to take `100ms + 2 * RTT`.
// For watch request, server returns the header immediately to notify Client
// watch start. But if server is behind some kind of proxy, the response
// header may be cached at proxy, and Client cannot rely on this behavior.
//
// Especially, wait request will ignore this timeout.
//
// One API call may send multiple requests to different etcd servers until it
// succeeds. Use context of the API to specify the overall timeout.
//
// A HeaderTimeoutPerRequest of zero means no timeout.
HeaderTimeoutPerRequest time.Duration
// SelectionMode is an EndpointSelectionMode enum that specifies the
// policy for choosing the etcd cluster node to which requests are sent.
SelectionMode EndpointSelectionMode
}
func (cfg *Config) transport() CancelableTransport {
if cfg.Transport == nil {
return DefaultTransport
}
return cfg.Transport
}
func (cfg *Config) checkRedirect() CheckRedirectFunc {
if cfg.CheckRedirect == nil {
return DefaultCheckRedirect
}
return cfg.CheckRedirect
}
// CancelableTransport mimics net/http.Transport, but requires that
// the object also support request cancellation.
type CancelableTransport interface {
http.RoundTripper
CancelRequest(req *http.Request)
}
type CheckRedirectFunc func(via int) error
// DefaultCheckRedirect follows up to 10 redirects, but no more.
var DefaultCheckRedirect CheckRedirectFunc = func(via int) error {
if via > 10 {
return ErrTooManyRedirects
}
return nil
}
type Client interface {
// Sync updates the internal cache of the etcd cluster's membership.
Sync(context.Context) error
// AutoSync periodically calls Sync() every given interval.
// The recommended sync interval is 10 seconds to 1 minute, which does
// not bring too much overhead to server and makes client catch up the
// cluster change in time.
//
// The example to use it:
//
// for {
// err := client.AutoSync(ctx, 10*time.Second)
// if err == context.DeadlineExceeded || err == context.Canceled {
// break
// }
// log.Print(err)
// }
AutoSync(context.Context, time.Duration) error
// Endpoints returns a copy of the current set of API endpoints used
// by Client to resolve HTTP requests. If Sync has ever been called,
// this may differ from the initial Endpoints provided in the Config.
Endpoints() []string
// SetEndpoints sets the set of API endpoints used by Client to resolve
// HTTP requests. If the given endpoints are not valid, an error will be
// returned
SetEndpoints(eps []string) error
// GetVersion retrieves the current etcd server and cluster version
GetVersion(ctx context.Context) (*version.Versions, error)
httpClient
}
func New(cfg Config) (Client, error) {
c := &httpClusterClient{
clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest),
rand: rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
selectionMode: cfg.SelectionMode,
}
if cfg.Username != "" {
c.credentials = &credentials{
username: cfg.Username,
password: cfg.Password,
}
}
if err := c.SetEndpoints(cfg.Endpoints); err != nil {
return nil, err
}
return c, nil
}
type httpClient interface {
Do(context.Context, httpAction) (*http.Response, []byte, error)
}
func newHTTPClientFactory(tr CancelableTransport, cr CheckRedirectFunc, headerTimeout time.Duration) httpClientFactory {
return func(ep url.URL) httpClient {
return &redirectFollowingHTTPClient{
checkRedirect: cr,
client: &simpleHTTPClient{
transport: tr,
endpoint: ep,
headerTimeout: headerTimeout,
},
}
}
}
type credentials struct {
username string
password string
}
type httpClientFactory func(url.URL) httpClient
type httpAction interface {
HTTPRequest(url.URL) *http.Request
}
type httpClusterClient struct {
clientFactory httpClientFactory
endpoints []url.URL
pinned int
credentials *credentials
sync.RWMutex
rand *rand.Rand
selectionMode EndpointSelectionMode
}
func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps []url.URL) (string, error) {
ceps := make([]url.URL, len(eps))
copy(ceps, eps)
// To perform a lookup on the new endpoint list without using the current
// client, we'll copy it
clientCopy := &httpClusterClient{
clientFactory: c.clientFactory,
credentials: c.credentials,
rand: c.rand,
pinned: 0,
endpoints: ceps,
}
mAPI := NewMembersAPI(clientCopy)
leader, err := mAPI.Leader(ctx)
if err != nil {
return "", err
}
if len(leader.ClientURLs) == 0 {
return "", ErrNoLeaderEndpoint
}
return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs?
}
func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, error) {
if len(eps) == 0 {
return []url.URL{}, ErrNoEndpoints
}
neps := make([]url.URL, len(eps))
for i, ep := range eps {
u, err := url.Parse(ep)
if err != nil {
return []url.URL{}, err
}
neps[i] = *u
}
return neps, nil
}
func (c *httpClusterClient) SetEndpoints(eps []string) error {
neps, err := c.parseEndpoints(eps)
if err != nil {
return err
}
c.Lock()
defer c.Unlock()
c.endpoints = shuffleEndpoints(c.rand, neps)
// We're not doing anything for PrioritizeLeader here. This is
// due to not having a context meaning we can't call getLeaderEndpoint
// However, if you're using PrioritizeLeader, you've already been told
// to regularly call sync, where we do have a ctx, and can figure the
// leader. PrioritizeLeader is also quite a loose guarantee, so deal
// with it
c.pinned = 0
return nil
}
func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
action := act
c.RLock()
leps := len(c.endpoints)
eps := make([]url.URL, leps)
n := copy(eps, c.endpoints)
pinned := c.pinned
if c.credentials != nil {
action = &authedAction{
act: act,
credentials: *c.credentials,
}
}
c.RUnlock()
if leps == 0 {
return nil, nil, ErrNoEndpoints
}
if leps != n {
return nil, nil, errors.New("unable to pick endpoint: copy failed")
}
var resp *http.Response
var body []byte
var err error
cerr := &ClusterError{}
isOneShot := ctx.Value(&oneShotCtxValue) != nil
for i := pinned; i < leps+pinned; i++ {
k := i % leps
hc := c.clientFactory(eps[k])
resp, body, err = hc.Do(ctx, action)
if err != nil {
cerr.Errors = append(cerr.Errors, err)
if errors.Is(err, ctx.Err()) {
return nil, nil, ctx.Err()
}
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return nil, nil, err
}
} else if resp.StatusCode/100 == 5 {
switch resp.StatusCode {
case http.StatusInternalServerError, http.StatusServiceUnavailable:
// TODO: make sure this is a no leader response
cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s has no leader", eps[k].String()))
default:
cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode)))
}
err = cerr.Errors[0]
}
if err != nil {
if !isOneShot {
continue
}
c.Lock()
c.pinned = (k + 1) % leps
c.Unlock()
return nil, nil, err
}
if k != pinned {
c.Lock()
c.pinned = k
c.Unlock()
}
return resp, body, nil
}
return nil, nil, cerr
}
func (c *httpClusterClient) Endpoints() []string {
c.RLock()
defer c.RUnlock()
eps := make([]string, len(c.endpoints))
for i, ep := range c.endpoints {
eps[i] = ep.String()
}
return eps
}
func (c *httpClusterClient) Sync(ctx context.Context) error {
mAPI := NewMembersAPI(c)
ms, err := mAPI.List(ctx)
if err != nil {
return err
}
var eps []string
for _, m := range ms {
eps = append(eps, m.ClientURLs...)
}
neps, err := c.parseEndpoints(eps)
if err != nil {
return err
}
npin := 0
switch c.selectionMode {
case EndpointSelectionRandom:
c.RLock()
eq := endpointsEqual(c.endpoints, neps)
c.RUnlock()
if eq {
return nil
}
// When items in the endpoint list changes, we choose a new pin
neps = shuffleEndpoints(c.rand, neps)
case EndpointSelectionPrioritizeLeader:
nle, err := c.getLeaderEndpoint(ctx, neps)
if err != nil {
return ErrNoLeaderEndpoint
}
for i, n := range neps {
if n.String() == nle {
npin = i
break
}
}
default:
return fmt.Errorf("invalid endpoint selection mode: %d", c.selectionMode)
}
c.Lock()
defer c.Unlock()
c.endpoints = neps
c.pinned = npin
return nil
}
func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
err := c.Sync(ctx)
if err != nil {
return err
}
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
}
}
}
func (c *httpClusterClient) GetVersion(ctx context.Context) (*version.Versions, error) {
act := &getAction{Prefix: "/version"}
resp, body, err := c.Do(ctx, act)
if err != nil {
return nil, err
}
switch resp.StatusCode {
case http.StatusOK:
if len(body) == 0 {
return nil, ErrEmptyBody
}
var vresp version.Versions
if err := json.Unmarshal(body, &vresp); err != nil {
return nil, ErrInvalidJSON
}
return &vresp, nil
default:
var etcdErr Error
if err := json.Unmarshal(body, &etcdErr); err != nil {
return nil, ErrInvalidJSON
}
return nil, etcdErr
}
}
type roundTripResponse struct {
resp *http.Response
err error
}
type simpleHTTPClient struct {
transport CancelableTransport
endpoint url.URL
headerTimeout time.Duration
}
// ErrNoRequest indicates that the HTTPRequest object could not be found
// or was nil. No processing could continue.
var ErrNoRequest = errors.New("no HTTPRequest was available")
func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
req := act.HTTPRequest(c.endpoint)
if req == nil {
return nil, nil, ErrNoRequest
}
if err := printcURL(req); err != nil {
return nil, nil, err
}
isWait := false
if req.URL != nil {
ws := req.URL.Query().Get("wait")
if len(ws) != 0 {
var err error
isWait, err = strconv.ParseBool(ws)
if err != nil {
return nil, nil, fmt.Errorf("wrong wait value %s (%w for %+v)", ws, err, req)
}
}
}
var hctx context.Context
var hcancel context.CancelFunc
if !isWait && c.headerTimeout > 0 {
hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout)
} else {
hctx, hcancel = context.WithCancel(ctx)
}
defer hcancel()
reqcancel := requestCanceler(req)
rtchan := make(chan roundTripResponse, 1)
go func() {
resp, err := c.transport.RoundTrip(req)
rtchan <- roundTripResponse{resp: resp, err: err}
close(rtchan)
}()
var resp *http.Response
var err error
select {
case rtresp := <-rtchan:
resp, err = rtresp.resp, rtresp.err
case <-hctx.Done():
// cancel and wait for request to actually exit before continuing
reqcancel()
rtresp := <-rtchan
resp = rtresp.resp
switch {
case ctx.Err() != nil:
err = ctx.Err()
case hctx.Err() != nil:
err = fmt.Errorf("client: endpoint %s exceeded header timeout", c.endpoint.String())
default:
panic("failed to get error from context")
}
}
// always check for resp nil-ness to deal with possible
// race conditions between channels above
defer func() {
if resp != nil {
resp.Body.Close()
}
}()
if err != nil {
return nil, nil, err
}
var body []byte
done := make(chan struct{})
go func() {
body, err = io.ReadAll(resp.Body)
done <- struct{}{}
}()
select {
case <-ctx.Done():
if resp != nil {
resp.Body.Close()
}
<-done
return nil, nil, ctx.Err()
case <-done:
}
return resp, body, err
}
type authedAction struct {
act httpAction
credentials credentials
}
func (a *authedAction) HTTPRequest(url url.URL) *http.Request {
r := a.act.HTTPRequest(url)
r.SetBasicAuth(a.credentials.username, a.credentials.password)
return r
}
type redirectFollowingHTTPClient struct {
client httpClient
checkRedirect CheckRedirectFunc
}
func (r *redirectFollowingHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
next := act
for i := 0; i < 100; i++ {
if i > 0 {
if err := r.checkRedirect(i); err != nil {
return nil, nil, err
}
}
resp, body, err := r.client.Do(ctx, next)
if err != nil {
return nil, nil, err
}
if resp.StatusCode/100 == 3 {
hdr := resp.Header.Get("Location")
if hdr == "" {
return nil, nil, errors.New("location header not set")
}
loc, err := url.Parse(hdr)
if err != nil {
return nil, nil, fmt.Errorf("location header not valid URL: %s", hdr)
}
next = &redirectedHTTPAction{
action: act,
location: *loc,
}
continue
}
return resp, body, nil
}
return nil, nil, errTooManyRedirectChecks
}
type redirectedHTTPAction struct {
action httpAction
location url.URL
}
func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request {
orig := r.action.HTTPRequest(ep)
orig.URL = &r.location
return orig
}
func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL {
// copied from Go 1.9<= rand.Rand.Perm
n := len(eps)
p := make([]int, n)
for i := 0; i < n; i++ {
j := r.Intn(i + 1)
p[i] = p[j]
p[j] = i
}
neps := make([]url.URL, n)
for i, k := range p {
neps[i] = eps[k]
}
return neps
}
func endpointsEqual(left, right []url.URL) bool {
if len(left) != len(right) {
return false
}
sLeft := make([]string, len(left))
sRight := make([]string, len(right))
for i, l := range left {
sLeft[i] = l.String()
}
for i, r := range right {
sRight[i] = r.String()
}
sort.Strings(sLeft)
sort.Strings(sRight)
for i := range sLeft {
if sLeft[i] != sRight[i] {
return false
}
}
return true
}

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
// 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 client
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
var cURLDebug = false
func EnablecURLDebug() {
cURLDebug = true
}
func DisablecURLDebug() {
cURLDebug = false
}
// printcURL prints the cURL equivalent request to stderr.
// It returns an error if the body of the request cannot
// be read.
// The caller MUST cancel the request if there is an error.
func printcURL(req *http.Request) error {
if !cURLDebug {
return nil
}
var (
command string
b []byte
err error
)
if req.URL != nil {
command = fmt.Sprintf("curl -X %s %s", req.Method, req.URL.String())
}
if req.Body != nil {
b, err = io.ReadAll(req.Body)
if err != nil {
return err
}
command += fmt.Sprintf(" -d %q", string(b))
}
fmt.Fprintf(os.Stderr, "cURL Command: %q\n", command)
// reset body
body := bytes.NewBuffer(b)
req.Body = io.NopCloser(body)
return nil
}

View File

@ -1,40 +0,0 @@
// 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 client
import (
"go.etcd.io/etcd/client/pkg/v3/srv"
)
// Discoverer is an interface that wraps the Discover method.
type Discoverer interface {
// Discover looks up the etcd servers for the domain.
Discover(domain string, serviceName string) ([]string, error)
}
type srvDiscover struct{}
// NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records.
func NewSRVDiscover() Discoverer {
return &srvDiscover{}
}
func (d *srvDiscover) Discover(domain string, serviceName string) ([]string, error) {
srvs, err := srv.GetClient("etcd-client", domain, serviceName)
if err != nil {
return nil, err
}
return srvs.Endpoints, nil
}

View File

@ -1,72 +0,0 @@
// 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 client provides bindings for the etcd APIs.
Create a Config and exchange it for a Client:
import (
"net/http"
"context"
"go.etcd.io/etcd/client/v2"
)
cfg := client.Config{
Endpoints: []string{"http://127.0.0.1:2379"},
Transport: DefaultTransport,
}
c, err := client.New(cfg)
if err != nil {
// handle error
}
Clients are safe for concurrent use by multiple goroutines.
Create a KeysAPI using the Client, then use it to interact with etcd:
kAPI := client.NewKeysAPI(c)
// create a new key /foo with the value "bar"
_, err = kAPI.Create(context.Background(), "/foo", "bar")
if err != nil {
// handle error
}
// delete the newly created key only if the value is still "bar"
_, err = kAPI.Delete(context.Background(), "/foo", &DeleteOptions{PrevValue: "bar"})
if err != nil {
// handle error
}
Use a custom context to set timeouts on your operations:
import "time"
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// set a new key, ignoring its previous state
_, err := kAPI.Set(ctx, "/ping", "pong", nil)
if err != nil {
if err == context.DeadlineExceeded {
// request took longer than 5s
} else {
// handle error
}
}
*/
package client

View File

@ -1,34 +0,0 @@
module go.etcd.io/etcd/client/v2
go 1.23
toolchain go1.23.6
require (
github.com/stretchr/testify v1.10.0
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6
)
require (
github.com/coreos/go-semver v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (
go.etcd.io/etcd/api/v3 => ./../../../api
go.etcd.io/etcd/client/pkg/v3 => ./../../pkg
)
// Bad imports are sometimes causing attempts to pull that code.
// This makes the error more explicit.
replace (
go.etcd.io/etcd => ./FORBIDDEN_DEPENDENCY
go.etcd.io/etcd/pkg/v3 => ./FORBIDDED_DEPENDENCY
go.etcd.io/etcd/tests/v3 => ./FORBIDDEN_DEPENDENCY
go.etcd.io/etcd/v3 => ./FORBIDDEN_DEPENDENCY
)

View File

@ -1,22 +0,0 @@
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=

View File

@ -1,678 +0,0 @@
// 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 client
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"time"
kjson "sigs.k8s.io/json"
"go.etcd.io/etcd/client/pkg/v3/pathutil"
)
const (
ErrorCodeKeyNotFound = 100
ErrorCodeTestFailed = 101
ErrorCodeNotFile = 102
ErrorCodeNotDir = 104
ErrorCodeNodeExist = 105
ErrorCodeRootROnly = 107
ErrorCodeDirNotEmpty = 108
ErrorCodeUnauthorized = 110
ErrorCodePrevValueRequired = 201
ErrorCodeTTLNaN = 202
ErrorCodeIndexNaN = 203
ErrorCodeInvalidField = 209
ErrorCodeInvalidForm = 210
ErrorCodeRaftInternal = 300
ErrorCodeLeaderElect = 301
ErrorCodeWatcherCleared = 400
ErrorCodeEventIndexCleared = 401
)
type Error struct {
Code int `json:"errorCode"`
Message string `json:"message"`
Cause string `json:"cause"`
Index uint64 `json:"index"`
}
func (e Error) Error() string {
return fmt.Sprintf("%v: %v (%v) [%v]", e.Code, e.Message, e.Cause, e.Index)
}
var (
ErrInvalidJSON = errors.New("client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint")
ErrEmptyBody = errors.New("client: response body is empty")
)
// PrevExistType is used to define an existence condition when setting
// or deleting Nodes.
type PrevExistType string
const (
PrevIgnore = PrevExistType("")
PrevExist = PrevExistType("true")
PrevNoExist = PrevExistType("false")
)
var defaultV2KeysPrefix = "/v2/keys"
// NewKeysAPI builds a KeysAPI that interacts with etcd's key-value
// API over HTTP.
func NewKeysAPI(c Client) KeysAPI {
return NewKeysAPIWithPrefix(c, defaultV2KeysPrefix)
}
// NewKeysAPIWithPrefix acts like NewKeysAPI, but allows the caller
// to provide a custom base URL path. This should only be used in
// very rare cases.
func NewKeysAPIWithPrefix(c Client, p string) KeysAPI {
return &httpKeysAPI{
client: c,
prefix: p,
}
}
type KeysAPI interface {
// Get retrieves a set of Nodes from etcd
Get(ctx context.Context, key string, opts *GetOptions) (*Response, error)
// Set assigns a new value to a Node identified by a given key. The caller
// may define a set of conditions in the SetOptions. If SetOptions.Dir=true
// then value is ignored.
Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error)
// Delete removes a Node identified by the given key, optionally destroying
// all of its children as well. The caller may define a set of required
// conditions in an DeleteOptions object.
Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error)
// Create is an alias for Set w/ PrevExist=false
Create(ctx context.Context, key, value string) (*Response, error)
// CreateInOrder is used to atomically create in-order keys within the given directory.
CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error)
// Update is an alias for Set w/ PrevExist=true
Update(ctx context.Context, key, value string) (*Response, error)
// Watcher builds a new Watcher targeted at a specific Node identified
// by the given key. The Watcher may be configured at creation time
// through a WatcherOptions object. The returned Watcher is designed
// to emit events that happen to a Node, and optionally to its children.
Watcher(key string, opts *WatcherOptions) Watcher
}
type WatcherOptions struct {
// AfterIndex defines the index after-which the Watcher should
// start emitting events. For example, if a value of 5 is
// provided, the first event will have an index >= 6.
//
// Setting AfterIndex to 0 (default) means that the Watcher
// should start watching for events starting at the current
// index, whatever that may be.
AfterIndex uint64
// Recursive specifies whether or not the Watcher should emit
// events that occur in children of the given keyspace. If set
// to false (default), events will be limited to those that
// occur for the exact key.
Recursive bool
}
type CreateInOrderOptions struct {
// TTL defines a period of time after-which the Node should
// expire and no longer exist. Values <= 0 are ignored. Given
// that the zero-value is ignored, TTL cannot be used to set
// a TTL of 0.
TTL time.Duration
}
type SetOptions struct {
// PrevValue specifies what the current value of the Node must
// be in order for the Set operation to succeed.
//
// Leaving this field empty means that the caller wishes to
// ignore the current value of the Node. This cannot be used
// to compare the Node's current value to an empty string.
//
// PrevValue is ignored if Dir=true
PrevValue string
// PrevIndex indicates what the current ModifiedIndex of the
// Node must be in order for the Set operation to succeed.
//
// If PrevIndex is set to 0 (default), no comparison is made.
PrevIndex uint64
// PrevExist specifies whether the Node must currently exist
// (PrevExist) or not (PrevNoExist). If the caller does not
// care about existence, set PrevExist to PrevIgnore, or simply
// leave it unset.
PrevExist PrevExistType
// TTL defines a period of time after-which the Node should
// expire and no longer exist. Values <= 0 are ignored. Given
// that the zero-value is ignored, TTL cannot be used to set
// a TTL of 0.
TTL time.Duration
// Refresh set to true means a TTL value can be updated
// without firing a watch or changing the node value. A
// value must not be provided when refreshing a key.
Refresh bool
// Dir specifies whether or not this Node should be created as a directory.
Dir bool
// NoValueOnSuccess specifies whether the response contains the current value of the Node.
// If set, the response will only contain the current value when the request fails.
NoValueOnSuccess bool
}
type GetOptions struct {
// Recursive defines whether or not all children of the Node
// should be returned.
Recursive bool
// Sort instructs the server whether or not to sort the Nodes.
// If true, the Nodes are sorted alphabetically by key in
// ascending order (A to z). If false (default), the Nodes will
// not be sorted and the ordering used should not be considered
// predictable.
Sort bool
// Quorum specifies whether it gets the latest committed value that
// has been applied in quorum of members, which ensures external
// consistency (or linearizability).
Quorum bool
}
type DeleteOptions struct {
// PrevValue specifies what the current value of the Node must
// be in order for the Delete operation to succeed.
//
// Leaving this field empty means that the caller wishes to
// ignore the current value of the Node. This cannot be used
// to compare the Node's current value to an empty string.
PrevValue string
// PrevIndex indicates what the current ModifiedIndex of the
// Node must be in order for the Delete operation to succeed.
//
// If PrevIndex is set to 0 (default), no comparison is made.
PrevIndex uint64
// Recursive defines whether or not all children of the Node
// should be deleted. If set to true, all children of the Node
// identified by the given key will be deleted. If left unset
// or explicitly set to false, only a single Node will be
// deleted.
Recursive bool
// Dir specifies whether or not this Node should be removed as a directory.
Dir bool
}
type Watcher interface {
// Next blocks until an etcd event occurs, then returns a Response
// representing that event. The behavior of Next depends on the
// WatcherOptions used to construct the Watcher. Next is designed to
// be called repeatedly, each time blocking until a subsequent event
// is available.
//
// If the provided context is cancelled, Next will return a non-nil
// error. Any other failures encountered while waiting for the next
// event (connection issues, deserialization failures, etc) will
// also result in a non-nil error.
Next(context.Context) (*Response, error)
}
type Response struct {
// Action is the name of the operation that occurred. Possible values
// include get, set, delete, update, create, compareAndSwap,
// compareAndDelete and expire.
Action string `json:"action"`
// Node represents the state of the relevant etcd Node.
Node *Node `json:"node"`
// PrevNode represents the previous state of the Node. PrevNode is non-nil
// only if the Node existed before the action occurred and the action
// caused a change to the Node.
PrevNode *Node `json:"prevNode"`
// Index holds the cluster-level index at the time the Response was generated.
// This index is not tied to the Node(s) contained in this Response.
Index uint64 `json:"-"`
// ClusterID holds the cluster-level ID reported by the server. This
// should be different for different etcd clusters.
ClusterID string `json:"-"`
}
type Node struct {
// Key represents the unique location of this Node (e.g. "/foo/bar").
Key string `json:"key"`
// Dir reports whether node describes a directory.
Dir bool `json:"dir,omitempty"`
// Value is the current data stored on this Node. If this Node
// is a directory, Value will be empty.
Value string `json:"value"`
// Nodes holds the children of this Node, only if this Node is a directory.
// This slice of will be arbitrarily deep (children, grandchildren, great-
// grandchildren, etc.) if a recursive Get or Watch request were made.
Nodes Nodes `json:"nodes"`
// CreatedIndex is the etcd index at-which this Node was created.
CreatedIndex uint64 `json:"createdIndex"`
// ModifiedIndex is the etcd index at-which this Node was last modified.
ModifiedIndex uint64 `json:"modifiedIndex"`
// Expiration is the server side expiration time of the key.
Expiration *time.Time `json:"expiration,omitempty"`
// TTL is the time to live of the key in second.
TTL int64 `json:"ttl,omitempty"`
}
func (n *Node) String() string {
return fmt.Sprintf("{Key: %s, CreatedIndex: %d, ModifiedIndex: %d, TTL: %d}", n.Key, n.CreatedIndex, n.ModifiedIndex, n.TTL)
}
// TTLDuration returns the Node's TTL as a time.Duration object
func (n *Node) TTLDuration() time.Duration {
return time.Duration(n.TTL) * time.Second
}
type Nodes []*Node
// interfaces for sorting
func (ns Nodes) Len() int { return len(ns) }
func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key }
func (ns Nodes) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] }
type httpKeysAPI struct {
client httpClient
prefix string
}
func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions) (*Response, error) {
act := &setAction{
Prefix: k.prefix,
Key: key,
Value: val,
}
if opts != nil {
act.PrevValue = opts.PrevValue
act.PrevIndex = opts.PrevIndex
act.PrevExist = opts.PrevExist
act.TTL = opts.TTL
act.Refresh = opts.Refresh
act.Dir = opts.Dir
act.NoValueOnSuccess = opts.NoValueOnSuccess
}
doCtx := ctx
if act.PrevExist == PrevNoExist {
doCtx = context.WithValue(doCtx, &oneShotCtxValue, &oneShotCtxValue)
}
resp, body, err := k.client.Do(doCtx, act)
if err != nil {
return nil, err
}
return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
}
func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*Response, error) {
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist})
}
func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val string, opts *CreateInOrderOptions) (*Response, error) {
act := &createInOrderAction{
Prefix: k.prefix,
Dir: dir,
Value: val,
}
if opts != nil {
act.TTL = opts.TTL
}
resp, body, err := k.client.Do(ctx, act)
if err != nil {
return nil, err
}
return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
}
func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) {
return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist})
}
func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error) {
act := &deleteAction{
Prefix: k.prefix,
Key: key,
}
if opts != nil {
act.PrevValue = opts.PrevValue
act.PrevIndex = opts.PrevIndex
act.Dir = opts.Dir
act.Recursive = opts.Recursive
}
doCtx := context.WithValue(ctx, &oneShotCtxValue, &oneShotCtxValue)
resp, body, err := k.client.Do(doCtx, act)
if err != nil {
return nil, err
}
return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
}
func (k *httpKeysAPI) Get(ctx context.Context, key string, opts *GetOptions) (*Response, error) {
act := &getAction{
Prefix: k.prefix,
Key: key,
}
if opts != nil {
act.Recursive = opts.Recursive
act.Sorted = opts.Sort
act.Quorum = opts.Quorum
}
resp, body, err := k.client.Do(ctx, act)
if err != nil {
return nil, err
}
return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
}
func (k *httpKeysAPI) Watcher(key string, opts *WatcherOptions) Watcher {
act := waitAction{
Prefix: k.prefix,
Key: key,
}
if opts != nil {
act.Recursive = opts.Recursive
if opts.AfterIndex > 0 {
act.WaitIndex = opts.AfterIndex + 1
}
}
return &httpWatcher{
client: k.client,
nextWait: act,
}
}
type httpWatcher struct {
client httpClient
nextWait waitAction
}
func (hw *httpWatcher) Next(ctx context.Context) (*Response, error) {
for {
httpresp, body, err := hw.client.Do(ctx, &hw.nextWait)
if err != nil {
return nil, err
}
resp, err := unmarshalHTTPResponse(httpresp.StatusCode, httpresp.Header, body)
if err != nil {
if errors.Is(err, ErrEmptyBody) {
continue
}
return nil, err
}
hw.nextWait.WaitIndex = resp.Node.ModifiedIndex + 1
return resp, nil
}
}
// v2KeysURL forms a URL representing the location of a key.
// The endpoint argument represents the base URL of an etcd
// server. The prefix is the path needed to route from the
// provided endpoint's path to the root of the keys API
// (typically "/v2/keys").
func v2KeysURL(ep url.URL, prefix, key string) *url.URL {
// We concatenate all parts together manually. We cannot use
// path.Join because it does not reserve trailing slash.
// We call CanonicalURLPath to further cleanup the path.
if prefix != "" && prefix[0] != '/' {
prefix = "/" + prefix
}
if key != "" && key[0] != '/' {
key = "/" + key
}
ep.Path = pathutil.CanonicalURLPath(ep.Path + prefix + key)
return &ep
}
type getAction struct {
Prefix string
Key string
Recursive bool
Sorted bool
Quorum bool
}
func (g *getAction) HTTPRequest(ep url.URL) *http.Request {
u := v2KeysURL(ep, g.Prefix, g.Key)
params := u.Query()
params.Set("recursive", strconv.FormatBool(g.Recursive))
params.Set("sorted", strconv.FormatBool(g.Sorted))
params.Set("quorum", strconv.FormatBool(g.Quorum))
u.RawQuery = params.Encode()
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
return req
}
type waitAction struct {
Prefix string
Key string
WaitIndex uint64
Recursive bool
}
func (w *waitAction) HTTPRequest(ep url.URL) *http.Request {
u := v2KeysURL(ep, w.Prefix, w.Key)
params := u.Query()
params.Set("wait", "true")
params.Set("waitIndex", strconv.FormatUint(w.WaitIndex, 10))
params.Set("recursive", strconv.FormatBool(w.Recursive))
u.RawQuery = params.Encode()
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
return req
}
type setAction struct {
Prefix string
Key string
Value string
PrevValue string
PrevIndex uint64
PrevExist PrevExistType
TTL time.Duration
Refresh bool
Dir bool
NoValueOnSuccess bool
}
func (a *setAction) HTTPRequest(ep url.URL) *http.Request {
u := v2KeysURL(ep, a.Prefix, a.Key)
params := u.Query()
form := url.Values{}
// we're either creating a directory or setting a key
if a.Dir {
params.Set("dir", strconv.FormatBool(a.Dir))
} else {
// These options are only valid for setting a key
if a.PrevValue != "" {
params.Set("prevValue", a.PrevValue)
}
form.Add("value", a.Value)
}
// Options which apply to both setting a key and creating a dir
if a.PrevIndex != 0 {
params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
}
if a.PrevExist != PrevIgnore {
params.Set("prevExist", string(a.PrevExist))
}
if a.TTL > 0 {
form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
}
if a.Refresh {
form.Add("refresh", "true")
}
if a.NoValueOnSuccess {
params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess))
}
u.RawQuery = params.Encode()
body := strings.NewReader(form.Encode())
req, _ := http.NewRequest(http.MethodPut, u.String(), body)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req
}
type deleteAction struct {
Prefix string
Key string
PrevValue string
PrevIndex uint64
Dir bool
Recursive bool
}
func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
u := v2KeysURL(ep, a.Prefix, a.Key)
params := u.Query()
if a.PrevValue != "" {
params.Set("prevValue", a.PrevValue)
}
if a.PrevIndex != 0 {
params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
}
if a.Dir {
params.Set("dir", "true")
}
if a.Recursive {
params.Set("recursive", "true")
}
u.RawQuery = params.Encode()
req, _ := http.NewRequest(http.MethodDelete, u.String(), nil)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req
}
type createInOrderAction struct {
Prefix string
Dir string
Value string
TTL time.Duration
}
func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request {
u := v2KeysURL(ep, a.Prefix, a.Dir)
form := url.Values{}
form.Add("value", a.Value)
if a.TTL > 0 {
form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
}
body := strings.NewReader(form.Encode())
req, _ := http.NewRequest(http.MethodPost, u.String(), body)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req
}
func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
switch code {
case http.StatusOK, http.StatusCreated:
if len(body) == 0 {
return nil, ErrEmptyBody
}
res, err = unmarshalSuccessfulKeysResponse(header, body)
default:
err = unmarshalFailedKeysResponse(body)
}
return res, err
}
func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) {
var res Response
err := kjson.UnmarshalCaseSensitivePreserveInts(body, &res)
if err != nil {
return nil, ErrInvalidJSON
}
if header.Get("X-Etcd-Index") != "" {
res.Index, err = strconv.ParseUint(header.Get("X-Etcd-Index"), 10, 64)
if err != nil {
return nil, err
}
}
res.ClusterID = header.Get("X-Etcd-Cluster-ID")
return &res, nil
}
func unmarshalFailedKeysResponse(body []byte) error {
var etcdErr Error
if err := json.Unmarshal(body, &etcdErr); err != nil {
return ErrInvalidJSON
}
return etcdErr
}

View File

@ -1,87 +0,0 @@
// 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 client
import (
"encoding/json"
"net/http"
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func createTestNode(size int) *Node {
return &Node{
Key: strings.Repeat("a", 30),
Value: strings.Repeat("a", size),
CreatedIndex: 123456,
ModifiedIndex: 123456,
TTL: 123456789,
}
}
func createTestNodeWithChildren(children, size int) *Node {
node := createTestNode(size)
for i := 0; i < children; i++ {
node.Nodes = append(node.Nodes, createTestNode(size))
}
return node
}
func createTestResponse(children, size int) *Response {
return &Response{
Action: "aaaaa",
Node: createTestNodeWithChildren(children, size),
PrevNode: nil,
}
}
func benchmarkResponseUnmarshalling(b *testing.B, children, size int) {
b.Helper()
header := http.Header{}
header.Add("X-Etcd-Index", "123456")
response := createTestResponse(children, size)
body, err := json.Marshal(response)
require.NoError(b, err)
b.ResetTimer()
newResponse := new(Response)
for i := 0; i < b.N; i++ {
if newResponse, err = unmarshalSuccessfulKeysResponse(header, body); err != nil {
b.Errorf("error unmarshalling response (%v)", err)
}
}
if !reflect.DeepEqual(response.Node, newResponse.Node) {
b.Errorf("Unexpected difference in a parsed response: \n%+v\n%+v", response, newResponse)
}
}
func BenchmarkSmallResponseUnmarshal(b *testing.B) {
benchmarkResponseUnmarshalling(b, 30, 20)
}
func BenchmarkManySmallResponseUnmarshal(b *testing.B) {
benchmarkResponseUnmarshalling(b, 3000, 20)
}
func BenchmarkMediumResponseUnmarshal(b *testing.B) {
benchmarkResponseUnmarshalling(b, 300, 200)
}
func BenchmarkLargeResponseUnmarshal(b *testing.B) {
benchmarkResponseUnmarshalling(b, 3000, 2000)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,303 +0,0 @@
// 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 client
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"path"
"go.etcd.io/etcd/client/pkg/v3/types"
)
var (
defaultV2MembersPrefix = "/v2/members"
defaultLeaderSuffix = "/leader"
)
type Member struct {
// ID is the unique identifier of this Member.
ID string `json:"id"`
// Name is a human-readable, non-unique identifier of this Member.
Name string `json:"name"`
// PeerURLs represents the HTTP(S) endpoints this Member uses to
// participate in etcd's consensus protocol.
PeerURLs []string `json:"peerURLs"`
// ClientURLs represents the HTTP(S) endpoints on which this Member
// serves its client-facing APIs.
ClientURLs []string `json:"clientURLs"`
}
type memberCollection []Member
func (c *memberCollection) UnmarshalJSON(data []byte) error {
d := struct {
Members []Member
}{}
if err := json.Unmarshal(data, &d); err != nil {
return err
}
if d.Members == nil {
*c = make([]Member, 0)
return nil
}
*c = d.Members
return nil
}
type memberCreateOrUpdateRequest struct {
PeerURLs types.URLs
}
func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) {
s := struct {
PeerURLs []string `json:"peerURLs"`
}{
PeerURLs: make([]string, len(m.PeerURLs)),
}
for i, u := range m.PeerURLs {
s.PeerURLs[i] = u.String()
}
return json.Marshal(&s)
}
// NewMembersAPI constructs a new MembersAPI that uses HTTP to
// interact with etcd's membership API.
func NewMembersAPI(c Client) MembersAPI {
return &httpMembersAPI{
client: c,
}
}
type MembersAPI interface {
// List enumerates the current cluster membership.
List(ctx context.Context) ([]Member, error)
// Add instructs etcd to accept a new Member into the cluster.
Add(ctx context.Context, peerURL string) (*Member, error)
// Remove demotes an existing Member out of the cluster.
Remove(ctx context.Context, mID string) error
// Update instructs etcd to update an existing Member in the cluster.
Update(ctx context.Context, mID string, peerURLs []string) error
// Leader gets current leader of the cluster
Leader(ctx context.Context) (*Member, error)
}
type httpMembersAPI struct {
client httpClient
}
func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) {
req := &membersAPIActionList{}
resp, body, err := m.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
return nil, err
}
var mCollection memberCollection
if err := json.Unmarshal(body, &mCollection); err != nil {
return nil, err
}
return mCollection, nil
}
func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) {
urls, err := types.NewURLs([]string{peerURL})
if err != nil {
return nil, err
}
req := &membersAPIActionAdd{peerURLs: urls}
resp, body, err := m.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusCreated, http.StatusConflict); err != nil {
return nil, err
}
if resp.StatusCode != http.StatusCreated {
var merr membersError
if err := json.Unmarshal(body, &merr); err != nil {
return nil, err
}
return nil, merr
}
var memb Member
if err := json.Unmarshal(body, &memb); err != nil {
return nil, err
}
return &memb, nil
}
func (m *httpMembersAPI) Update(ctx context.Context, memberID string, peerURLs []string) error {
urls, err := types.NewURLs(peerURLs)
if err != nil {
return err
}
req := &membersAPIActionUpdate{peerURLs: urls, memberID: memberID}
resp, body, err := m.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusNotFound, http.StatusConflict); err != nil {
return err
}
if resp.StatusCode != http.StatusNoContent {
var merr membersError
if err := json.Unmarshal(body, &merr); err != nil {
return err
}
return merr
}
return nil
}
func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error {
req := &membersAPIActionRemove{memberID: memberID}
resp, _, err := m.client.Do(ctx, req)
if err != nil {
return err
}
return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone)
}
func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) {
req := &membersAPIActionLeader{}
resp, body, err := m.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
return nil, err
}
var leader Member
if err := json.Unmarshal(body, &leader); err != nil {
return nil, err
}
return &leader, nil
}
type membersAPIActionList struct{}
func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
return req
}
type membersAPIActionRemove struct {
memberID string
}
func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
u.Path = path.Join(u.Path, d.memberID)
req, _ := http.NewRequest(http.MethodDelete, u.String(), nil)
return req
}
type membersAPIActionAdd struct {
peerURLs types.URLs
}
func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
b, _ := json.Marshal(&m)
req, _ := http.NewRequest(http.MethodPost, u.String(), bytes.NewReader(b))
req.Header.Set("Content-Type", "application/json")
return req
}
type membersAPIActionUpdate struct {
memberID string
peerURLs types.URLs
}
func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
u.Path = path.Join(u.Path, a.memberID)
b, _ := json.Marshal(&m)
req, _ := http.NewRequest(http.MethodPut, u.String(), bytes.NewReader(b))
req.Header.Set("Content-Type", "application/json")
return req
}
func assertStatusCode(got int, want ...int) (err error) {
for _, w := range want {
if w == got {
return nil
}
}
return fmt.Errorf("unexpected status code %d", got)
}
type membersAPIActionLeader struct{}
func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
u.Path = path.Join(u.Path, defaultLeaderSuffix)
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
return req
}
// v2MembersURL add the necessary path to the provided endpoint
// to route requests to the default v2 members API.
func v2MembersURL(ep url.URL) *url.URL {
ep.Path = path.Join(ep.Path, defaultV2MembersPrefix)
return &ep
}
type membersError struct {
Message string `json:"message"`
Code int `json:"-"`
}
func (e membersError) Error() string {
return e.Message
}

View File

@ -1,594 +0,0 @@
// 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 client
import (
"context"
"encoding/json"
"errors"
"net/http"
"net/url"
"reflect"
"testing"
"github.com/stretchr/testify/require"
"go.etcd.io/etcd/client/pkg/v3/types"
)
func TestMembersAPIActionList(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionList{}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members",
}
got := *act.HTTPRequest(ep)
err := assertRequest(got, http.MethodGet, wantURL, http.Header{}, nil)
if err != nil {
t.Error(err.Error())
}
}
func TestMembersAPIActionAdd(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionAdd{
peerURLs: types.URLs([]url.URL{
{Scheme: "https", Host: "127.0.0.1:8081"},
{Scheme: "http", Host: "127.0.0.1:8080"},
}),
}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members",
}
wantHeader := http.Header{
"Content-Type": []string{"application/json"},
}
wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`)
got := *act.HTTPRequest(ep)
err := assertRequest(got, http.MethodPost, wantURL, wantHeader, wantBody)
if err != nil {
t.Error(err.Error())
}
}
func TestMembersAPIActionUpdate(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionUpdate{
memberID: "0xabcd",
peerURLs: types.URLs([]url.URL{
{Scheme: "https", Host: "127.0.0.1:8081"},
{Scheme: "http", Host: "127.0.0.1:8080"},
}),
}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members/0xabcd",
}
wantHeader := http.Header{
"Content-Type": []string{"application/json"},
}
wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`)
got := *act.HTTPRequest(ep)
err := assertRequest(got, http.MethodPut, wantURL, wantHeader, wantBody)
if err != nil {
t.Error(err.Error())
}
}
func TestMembersAPIActionRemove(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionRemove{memberID: "XXX"}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members/XXX",
}
got := *act.HTTPRequest(ep)
err := assertRequest(got, http.MethodDelete, wantURL, http.Header{}, nil)
if err != nil {
t.Error(err.Error())
}
}
func TestMembersAPIActionLeader(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionLeader{}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members/leader",
}
got := *act.HTTPRequest(ep)
err := assertRequest(got, http.MethodGet, wantURL, http.Header{}, nil)
if err != nil {
t.Error(err.Error())
}
}
func TestAssertStatusCode(t *testing.T) {
if err := assertStatusCode(404, 400); err == nil {
t.Errorf("assertStatusCode failed to detect conflict in 400 vs 404")
}
if err := assertStatusCode(404, 400, 404); err != nil {
t.Errorf("assertStatusCode found conflict in (404,400) vs 400: %v", err)
}
}
func TestV2MembersURL(t *testing.T) {
got := v2MembersURL(url.URL{
Scheme: "http",
Host: "foo.example.com:4002",
Path: "/pants",
})
want := &url.URL{
Scheme: "http",
Host: "foo.example.com:4002",
Path: "/pants/v2/members",
}
require.Truef(t, reflect.DeepEqual(want, got), "v2MembersURL got %#v, want %#v", got, want)
}
func TestMemberUnmarshal(t *testing.T) {
tests := []struct {
body []byte
wantMember Member
wantError bool
}{
// no URLs, just check ID & Name
{
body: []byte(`{"id": "c", "name": "dungarees"}`),
wantMember: Member{ID: "c", Name: "dungarees", PeerURLs: nil, ClientURLs: nil},
},
// both client and peer URLs
{
body: []byte(`{"peerURLs": ["http://127.0.0.1:2379"], "clientURLs": ["http://127.0.0.1:2379"]}`),
wantMember: Member{
PeerURLs: []string{
"http://127.0.0.1:2379",
},
ClientURLs: []string{
"http://127.0.0.1:2379",
},
},
},
// multiple peer URLs
{
body: []byte(`{"peerURLs": ["http://127.0.0.1:2379", "https://example.com"]}`),
wantMember: Member{
PeerURLs: []string{
"http://127.0.0.1:2379",
"https://example.com",
},
ClientURLs: nil,
},
},
// multiple client URLs
{
body: []byte(`{"clientURLs": ["http://127.0.0.1:2379", "https://example.com"]}`),
wantMember: Member{
PeerURLs: nil,
ClientURLs: []string{
"http://127.0.0.1:2379",
"https://example.com",
},
},
},
// invalid JSON
{
body: []byte(`{"peerU`),
wantError: true,
},
}
for i, tt := range tests {
got := Member{}
err := json.Unmarshal(tt.body, &got)
if tt.wantError != (err != nil) {
t.Errorf("#%d: want error %t, got %v", i, tt.wantError, err)
continue
}
if !reflect.DeepEqual(tt.wantMember, got) {
t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.wantMember, got)
}
}
}
func TestMemberCollectionUnmarshalFail(t *testing.T) {
mc := &memberCollection{}
if err := mc.UnmarshalJSON([]byte(`{`)); err == nil {
t.Errorf("got nil error")
}
}
func TestMemberCollectionUnmarshal(t *testing.T) {
tests := []struct {
body []byte
want memberCollection
}{
{
body: []byte(`{}`),
want: memberCollection([]Member{}),
},
{
body: []byte(`{"members":[]}`),
want: memberCollection([]Member{}),
},
{
body: []byte(`{"members":[{"id":"2745e2525fce8fe","peerURLs":["http://127.0.0.1:7003"],"name":"node3","clientURLs":["http://127.0.0.1:4003"]},{"id":"42134f434382925","peerURLs":["http://127.0.0.1:2380","http://127.0.0.1:7001"],"name":"node1","clientURLs":["http://127.0.0.1:2379","http://127.0.0.1:4001"]},{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"],"name":"node2","clientURLs":["http://127.0.0.1:4002"]}]}`),
want: memberCollection(
[]Member{
{
ID: "2745e2525fce8fe",
Name: "node3",
PeerURLs: []string{
"http://127.0.0.1:7003",
},
ClientURLs: []string{
"http://127.0.0.1:4003",
},
},
{
ID: "42134f434382925",
Name: "node1",
PeerURLs: []string{
"http://127.0.0.1:2380",
"http://127.0.0.1:7001",
},
ClientURLs: []string{
"http://127.0.0.1:2379",
"http://127.0.0.1:4001",
},
},
{
ID: "94088180e21eb87b",
Name: "node2",
PeerURLs: []string{
"http://127.0.0.1:7002",
},
ClientURLs: []string{
"http://127.0.0.1:4002",
},
},
},
),
},
}
for i, tt := range tests {
var got memberCollection
err := json.Unmarshal(tt.body, &got)
if err != nil {
t.Errorf("#%d: unexpected error: %v", i, err)
continue
}
if !reflect.DeepEqual(tt.want, got) {
t.Errorf("#%d: incorrect output: want=%#v, got=%#v", i, tt.want, got)
}
}
}
func TestMemberCreateRequestMarshal(t *testing.T) {
req := memberCreateOrUpdateRequest{
PeerURLs: types.URLs([]url.URL{
{Scheme: "http", Host: "127.0.0.1:8081"},
{Scheme: "https", Host: "127.0.0.1:8080"},
}),
}
want := []byte(`{"peerURLs":["http://127.0.0.1:8081","https://127.0.0.1:8080"]}`)
got, err := json.Marshal(&req)
require.NoErrorf(t, err, "Marshal returned unexpected err")
require.Truef(t, reflect.DeepEqual(want, got), "Failed to marshal memberCreateRequest: want=%s, got=%s", want, got)
}
func TestHTTPMembersAPIAddSuccess(t *testing.T) {
wantAction := &membersAPIActionAdd{
peerURLs: types.URLs([]url.URL{
{Scheme: "http", Host: "127.0.0.1:7002"},
}),
}
mAPI := &httpMembersAPI{
client: &actionAssertingHTTPClient{
t: t,
act: wantAction,
resp: http.Response{
StatusCode: http.StatusCreated,
},
body: []byte(`{"id":"94088180e21eb87b","peerURLs":["http://127.0.0.1:7002"]}`),
},
}
wantResponseMember := &Member{
ID: "94088180e21eb87b",
PeerURLs: []string{"http://127.0.0.1:7002"},
}
m, err := mAPI.Add(context.Background(), "http://127.0.0.1:7002")
if err != nil {
t.Errorf("got non-nil err: %#v", err)
}
if !reflect.DeepEqual(wantResponseMember, m) {
t.Errorf("incorrect Member: want=%#v got=%#v", wantResponseMember, m)
}
}
func TestHTTPMembersAPIAddError(t *testing.T) {
okPeer := "http://example.com:2379"
tests := []struct {
peerURL string
client httpClient
// if wantErr == nil, assert that the returned error is non-nil
// if wantErr != nil, assert that the returned error matches
wantErr error
}{
// malformed peer URL
{
peerURL: ":",
},
// generic httpClient failure
{
peerURL: okPeer,
client: &staticHTTPClient{err: errors.New("fail")},
},
// unrecognized HTTP status code
{
peerURL: okPeer,
client: &staticHTTPClient{
resp: http.Response{StatusCode: http.StatusTeapot},
},
},
// unmarshal body into membersError on StatusConflict
{
peerURL: okPeer,
client: &staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusConflict,
},
body: []byte(`{"message":"fail!"}`),
},
wantErr: membersError{Message: "fail!"},
},
// fail to unmarshal body on StatusConflict
{
peerURL: okPeer,
client: &staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusConflict,
},
body: []byte(`{"`),
},
},
// fail to unmarshal body on StatusCreated
{
peerURL: okPeer,
client: &staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusCreated,
},
body: []byte(`{"id":"XX`),
},
},
}
for i, tt := range tests {
mAPI := &httpMembersAPI{client: tt.client}
m, err := mAPI.Add(context.Background(), tt.peerURL)
if err == nil {
t.Errorf("#%d: got nil err", i)
}
if tt.wantErr != nil && !reflect.DeepEqual(tt.wantErr, err) {
t.Errorf("#%d: incorrect error: want=%#v got=%#v", i, tt.wantErr, err)
}
if m != nil {
t.Errorf("#%d: got non-nil Member", i)
}
}
}
func TestHTTPMembersAPIRemoveSuccess(t *testing.T) {
wantAction := &membersAPIActionRemove{
memberID: "94088180e21eb87b",
}
mAPI := &httpMembersAPI{
client: &actionAssertingHTTPClient{
t: t,
act: wantAction,
resp: http.Response{
StatusCode: http.StatusNoContent,
},
},
}
if err := mAPI.Remove(context.Background(), "94088180e21eb87b"); err != nil {
t.Errorf("got non-nil err: %#v", err)
}
}
func TestHTTPMembersAPIRemoveFail(t *testing.T) {
tests := []httpClient{
// generic error
&staticHTTPClient{
err: errors.New("fail"),
},
// unexpected HTTP status code
&staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusInternalServerError,
},
},
}
for i, tt := range tests {
mAPI := &httpMembersAPI{client: tt}
if err := mAPI.Remove(context.Background(), "94088180e21eb87b"); err == nil {
t.Errorf("#%d: got nil err", i)
}
}
}
func TestHTTPMembersAPIListSuccess(t *testing.T) {
wantAction := &membersAPIActionList{}
mAPI := &httpMembersAPI{
client: &actionAssertingHTTPClient{
t: t,
act: wantAction,
resp: http.Response{
StatusCode: http.StatusOK,
},
body: []byte(`{"members":[{"id":"94088180e21eb87b","name":"node2","peerURLs":["http://127.0.0.1:7002"],"clientURLs":["http://127.0.0.1:4002"]}]}`),
},
}
wantResponseMembers := []Member{
{
ID: "94088180e21eb87b",
Name: "node2",
PeerURLs: []string{"http://127.0.0.1:7002"},
ClientURLs: []string{"http://127.0.0.1:4002"},
},
}
m, err := mAPI.List(context.Background())
if err != nil {
t.Errorf("got non-nil err: %#v", err)
}
if !reflect.DeepEqual(wantResponseMembers, m) {
t.Errorf("incorrect Members: want=%#v got=%#v", wantResponseMembers, m)
}
}
func TestHTTPMembersAPIListError(t *testing.T) {
tests := []httpClient{
// generic httpClient failure
&staticHTTPClient{err: errors.New("fail")},
// unrecognized HTTP status code
&staticHTTPClient{
resp: http.Response{StatusCode: http.StatusTeapot},
},
// fail to unmarshal body on StatusOK
&staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusOK,
},
body: []byte(`[{"id":"XX`),
},
}
for i, tt := range tests {
mAPI := &httpMembersAPI{client: tt}
ms, err := mAPI.List(context.Background())
if err == nil {
t.Errorf("#%d: got nil err", i)
}
if ms != nil {
t.Errorf("#%d: got non-nil Member slice", i)
}
}
}
func TestHTTPMembersAPILeaderSuccess(t *testing.T) {
wantAction := &membersAPIActionLeader{}
mAPI := &httpMembersAPI{
client: &actionAssertingHTTPClient{
t: t,
act: wantAction,
resp: http.Response{
StatusCode: http.StatusOK,
},
body: []byte(`{"id":"94088180e21eb87b","name":"node2","peerURLs":["http://127.0.0.1:7002"],"clientURLs":["http://127.0.0.1:4002"]}`),
},
}
wantResponseMember := &Member{
ID: "94088180e21eb87b",
Name: "node2",
PeerURLs: []string{"http://127.0.0.1:7002"},
ClientURLs: []string{"http://127.0.0.1:4002"},
}
m, err := mAPI.Leader(context.Background())
if err != nil {
t.Errorf("err = %v, want %v", err, nil)
}
if !reflect.DeepEqual(wantResponseMember, m) {
t.Errorf("incorrect member: member = %v, want %v", wantResponseMember, m)
}
}
func TestHTTPMembersAPILeaderError(t *testing.T) {
tests := []httpClient{
// generic httpClient failure
&staticHTTPClient{err: errors.New("fail")},
// unrecognized HTTP status code
&staticHTTPClient{
resp: http.Response{StatusCode: http.StatusTeapot},
},
// fail to unmarshal body on StatusOK
&staticHTTPClient{
resp: http.Response{
StatusCode: http.StatusOK,
},
body: []byte(`[{"id":"XX`),
},
}
for i, tt := range tests {
mAPI := &httpMembersAPI{client: tt}
m, err := mAPI.Leader(context.Background())
if err == nil {
t.Errorf("#%d: err = nil, want not nil", i)
}
if m != nil {
t.Errorf("member slice = %v, want nil", m)
}
}
}

View File

@ -1,48 +0,0 @@
// Copyright 2016 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 client
import (
"errors"
"regexp"
)
var (
roleNotFoundRegExp *regexp.Regexp
userNotFoundRegExp *regexp.Regexp
)
func init() {
roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.")
userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.")
}
// IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound.
func IsKeyNotFound(err error) bool {
var cErr Error
return errors.As(err, &cErr) && cErr.Code == ErrorCodeKeyNotFound
}
// IsRoleNotFound returns true if the error means role not found of v2 API.
func IsRoleNotFound(err error) bool {
var ae authError
return errors.As(err, &ae) && roleNotFoundRegExp.MatchString(ae.Message)
}
// IsUserNotFound returns true if the error means user not found of v2 API.
func IsUserNotFound(err error) bool {
var ae authError
return errors.As(err, &ae) && userNotFoundRegExp.MatchString(ae.Message)
}

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2020 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.

View File

@ -23,7 +23,7 @@ import (
)
func TestLockAndUnlock(t *testing.T) {
f, err := os.CreateTemp("", "lock")
f, err := os.CreateTemp(t.TempDir(), "lock")
require.NoError(t, err)
f.Close()
defer func() {

View File

@ -1,21 +1,21 @@
module go.etcd.io/etcd/client/pkg/v3
go 1.23
go 1.24
toolchain go1.23.6
toolchain go1.24.4
require (
github.com/coreos/go-systemd/v22 v22.5.0
github.com/stretchr/testify v1.10.0
go.uber.org/zap v1.27.0
golang.org/x/sys v0.29.0
golang.org/x/sys v0.33.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@ -1,8 +1,8 @@
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@ -12,11 +12,11 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -25,8 +25,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View File

@ -19,9 +19,6 @@ import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.etcd.io/etcd/client/pkg/v3/verify"
)
@ -31,15 +28,12 @@ func BeforeTest(tb testing.TB) {
revertVerifyFunc := verify.EnableAllVerifications()
path, err := os.Getwd()
require.NoError(tb, err)
tempDir := tb.TempDir()
require.NoError(tb, os.Chdir(tempDir))
tb.Chdir(tempDir)
tb.Logf("Changing working directory to: %s", tempDir)
tb.Cleanup(func() {
revertVerifyFunc()
assert.NoError(tb, os.Chdir(path))
})
}

View File

@ -47,7 +47,6 @@ func NewURLs(strs []string) (URLs, error) {
return nil, fmt.Errorf("URL must not contain a path: %s", in)
}
case "unix", "unixs":
break
default:
return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in)
}

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2020 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.

View File

@ -43,6 +43,7 @@ import (
var (
ErrNoAvailableEndpoints = errors.New("etcdclient: no available endpoints")
ErrOldCluster = errors.New("etcdclient: old cluster version")
ErrMutuallyExclusiveCfg = errors.New("Username/Password and Token configurations are mutually exclusive")
)
// Client provides and manages an etcd v3 client session.
@ -69,7 +70,10 @@ type Client struct {
// Username is a user name for authentication.
Username string
// Password is a password for authentication.
Password string
Password string
// Token is a JWT used for authentication instead of a password.
Token string
authTokenBundle credentials.PerRPCCredentialsBundle
callOpts []grpc.CallOption
@ -288,6 +292,11 @@ func (c *Client) Dial(ep string) (*grpc.ClientConn, error) {
func (c *Client) getToken(ctx context.Context) error {
var err error // return last error in a case of fail
if c.Token != "" {
c.authTokenBundle.UpdateAuthToken(c.Token)
return nil
}
if c.Username == "" || c.Password == "" {
return nil
}
@ -376,6 +385,10 @@ func newClient(cfg *Config) (*Client, error) {
creds = credentials.NewTransportCredential(cfg.TLS)
}
if cfg.Token != "" && (cfg.Username != "" || cfg.Password != "") {
return nil, ErrMutuallyExclusiveCfg
}
// use a temporary skeleton client to bootstrap first connection
baseCtx := context.TODO()
if cfg.Context != nil {
@ -414,6 +427,12 @@ func newClient(cfg *Config) (*Client, error) {
client.Password = cfg.Password
client.authTokenBundle = credentials.NewPerRPCCredentialBundle()
}
if cfg.Token != "" {
client.Token = cfg.Token
client.authTokenBundle = credentials.NewPerRPCCredentialBundle()
}
if cfg.MaxCallSendMsgSize > 0 || cfg.MaxCallRecvMsgSize > 0 {
if cfg.MaxCallRecvMsgSize > 0 && cfg.MaxCallSendMsgSize > cfg.MaxCallRecvMsgSize {
return nil, fmt.Errorf("gRPC message recv limit (%d bytes) must be greater than send limit (%d bytes)", cfg.MaxCallRecvMsgSize, cfg.MaxCallSendMsgSize)

View File

@ -196,18 +196,18 @@ func TestBackoffJitterFraction(t *testing.T) {
func TestIsHaltErr(t *testing.T) {
assert.Truef(t,
isHaltErr(context.TODO(), errors.New("etcdserver: some etcdserver error")),
isHaltErr(t.Context(), errors.New("etcdserver: some etcdserver error")),
"error created by errors.New should be unavailable error",
)
assert.Falsef(t,
isHaltErr(context.TODO(), rpctypes.ErrGRPCStopped),
isHaltErr(t.Context(), rpctypes.ErrGRPCStopped),
`error "%v" should not be halt error`, rpctypes.ErrGRPCStopped,
)
assert.Falsef(t,
isHaltErr(context.TODO(), rpctypes.ErrGRPCNoLeader),
isHaltErr(t.Context(), rpctypes.ErrGRPCNoLeader),
`error "%v" should not be halt error`, rpctypes.ErrGRPCNoLeader,
)
ctx, cancel := context.WithCancel(context.TODO())
ctx, cancel := context.WithCancel(t.Context())
assert.Falsef(t,
isHaltErr(ctx, nil),
"no error and active context should be halt error",
@ -221,18 +221,18 @@ func TestIsHaltErr(t *testing.T) {
func TestIsUnavailableErr(t *testing.T) {
assert.Falsef(t,
isUnavailableErr(context.TODO(), errors.New("etcdserver: some etcdserver error")),
isUnavailableErr(t.Context(), errors.New("etcdserver: some etcdserver error")),
"error created by errors.New should not be unavailable error",
)
assert.Truef(t,
isUnavailableErr(context.TODO(), rpctypes.ErrGRPCStopped),
isUnavailableErr(t.Context(), rpctypes.ErrGRPCStopped),
`error "%v" should be unavailable error`, rpctypes.ErrGRPCStopped,
)
assert.Falsef(t,
isUnavailableErr(context.TODO(), rpctypes.ErrGRPCNotCapable),
isUnavailableErr(t.Context(), rpctypes.ErrGRPCNotCapable),
"error %v should not be unavailable error", rpctypes.ErrGRPCNotCapable,
)
ctx, cancel := context.WithCancel(context.TODO())
ctx, cancel := context.WithCancel(t.Context())
assert.Falsef(t,
isUnavailableErr(ctx, nil),
"no error and active context should not be unavailable error",
@ -245,7 +245,7 @@ func TestIsUnavailableErr(t *testing.T) {
}
func TestCloseCtxClient(t *testing.T) {
ctx := context.Background()
ctx := t.Context()
c := NewCtxClient(ctx)
err := c.Close()
// Close returns ctx.toErr, a nil error means an open Done channel
@ -255,7 +255,7 @@ func TestCloseCtxClient(t *testing.T) {
}
func TestWithLogger(t *testing.T) {
ctx := context.Background()
ctx := t.Context()
c := NewCtxClient(ctx)
if c.lg == nil {
t.Errorf("unexpected nil in *zap.Logger")
@ -268,7 +268,7 @@ func TestWithLogger(t *testing.T) {
}
func TestZapWithLogger(t *testing.T) {
ctx := context.Background()
ctx := t.Context()
lg := zap.NewNop()
c := NewCtxClient(ctx, WithZapLogger(lg))
@ -317,6 +317,75 @@ func TestAuthTokenBundleNoOverwrite(t *testing.T) {
}
}
func TestNewWithOnlyJWT(t *testing.T) {
// This call in particular changes working directory to the tmp dir of
// the test. The `etcd-auth-test:1` can be created in local directory,
// not exceeding the longest allowed path on OsX.
testutil.BeforeTest(t)
// Create a mock AuthServer to handle Authenticate RPCs.
lis, err := net.Listen("unix", "etcd-auth-test:1")
if err != nil {
t.Fatal(err)
}
defer lis.Close()
addr := "unix://" + lis.Addr().String()
srv := grpc.NewServer()
// Having a token removes the need to ever call Authenticate on the
// server. If that happens then this will cause a connection failure.
etcdserverpb.RegisterAuthServer(srv, mockFailingAuthServer{})
go srv.Serve(lis)
defer srv.Stop()
c, err := NewClient(t, Config{
DialTimeout: 5 * time.Second,
Endpoints: []string{addr},
Token: "foo",
})
if err != nil {
t.Fatal(err)
}
defer c.Close()
meta, err := c.authTokenBundle.PerRPCCredentials().GetRequestMetadata(t.Context(), "")
if err != nil {
t.Errorf("Error building request metadata: %s", err)
}
if tok, ok := meta[rpctypes.TokenFieldNameGRPC]; !ok {
t.Error("Token was not successfuly set in the auth bundle")
} else if tok != "foo" {
t.Errorf("Incorrect token set in auth bundle, got '%s', expected 'foo'", tok)
}
}
func TestNewOnlyJWTExclusivity(t *testing.T) {
testutil.BeforeTest(t)
// Create a mock AuthServer to handle Authenticate RPCs.
lis, err := net.Listen("unix", "etcd-auth-test:1")
if err != nil {
t.Fatal(err)
}
defer lis.Close()
addr := "unix://" + lis.Addr().String()
srv := grpc.NewServer()
// Having a token removes the need to ever call Authenticate on the
// server. If that happens then this will cause a connection failure.
etcdserverpb.RegisterAuthServer(srv, mockFailingAuthServer{})
go srv.Serve(lis)
defer srv.Stop()
_, err = NewClient(t, Config{
DialTimeout: 5 * time.Second,
Endpoints: []string{addr},
Token: "foo",
Username: "user",
Password: "pass",
})
require.ErrorIs(t, ErrMutuallyExclusiveCfg, err)
}
func TestSyncFiltersMembers(t *testing.T) {
c, _ := NewClient(t, Config{Endpoints: []string{"http://254.0.0.1:12345"}})
defer c.Close()
@ -327,7 +396,7 @@ func TestSyncFiltersMembers(t *testing.T) {
{ID: 2, Name: "isStartedAndNotLearner", ClientURLs: []string{"http://254.0.0.3:12345"}, IsLearner: false},
},
}
c.Sync(context.Background())
c.Sync(t.Context())
endpoints := c.Endpoints()
if len(endpoints) != 1 || endpoints[0] != "http://254.0.0.3:12345" {
@ -421,7 +490,7 @@ func TestClientRejectOldCluster(t *testing.T) {
endpointToVersion[tt.endpoints[j]] = tt.versions[j]
}
c := &Client{
ctx: context.Background(),
ctx: t.Context(),
endpoints: tt.endpoints,
epMu: new(sync.RWMutex),
Maintenance: &mockMaintenance{
@ -476,6 +545,14 @@ func (mm mockMaintenance) Downgrade(ctx context.Context, action DowngradeAction,
return nil, nil
}
type mockFailingAuthServer struct {
*etcdserverpb.UnimplementedAuthServer
}
func (mockFailingAuthServer) Authenticate(context.Context, *etcdserverpb.AuthenticateRequest) (*etcdserverpb.AuthenticateResponse, error) {
return nil, errors.New("this auth server always fails")
}
type mockAuthServer struct {
*etcdserverpb.UnimplementedAuthServer
}

View File

@ -66,6 +66,9 @@ type Config struct {
// Password is a password for authentication.
Password string `json:"password"`
// Token is a JWT used for authentication instead of a password.
Token string `json:"token"`
// RejectOldCluster when set will refuse to create a client against an outdated cluster.
RejectOldCluster bool `json:"reject-old-cluster"`
@ -130,6 +133,7 @@ type SecureConfig struct {
type AuthConfig struct {
Username string `json:"username"`
Password string `json:"password"`
Token string `json:"token"`
}
func (cs *ConfigSpec) Clone() *ConfigSpec {
@ -157,7 +161,7 @@ func (cs *ConfigSpec) Clone() *ConfigSpec {
}
func (cfg AuthConfig) Empty() bool {
return cfg.Username == "" && cfg.Password == ""
return cfg.Username == "" && cfg.Password == "" && cfg.Token == ""
}
// NewClientConfig creates a Config based on the provided ConfigSpec.
@ -180,6 +184,7 @@ func NewClientConfig(confSpec *ConfigSpec, lg *zap.Logger) (*Config, error) {
if confSpec.Auth != nil {
cfg.Username = confSpec.Auth.Username
cfg.Password = confSpec.Auth.Password
cfg.Token = confSpec.Auth.Token
}
return cfg, nil

View File

@ -71,6 +71,25 @@ func TestNewClientConfig(t *testing.T) {
Password: "changeme",
},
},
{
name: "JWT specified",
spec: ConfigSpec{
Endpoints: []string{"http://192.168.0.12:2379"},
DialTimeout: 1 * time.Second,
KeepAliveTime: 4 * time.Second,
KeepAliveTimeout: 6 * time.Second,
Auth: &AuthConfig{
Token: "test",
},
},
expectedConf: Config{
Endpoints: []string{"http://192.168.0.12:2379"},
DialTimeout: 1 * time.Second,
DialKeepAliveTime: 4 * time.Second,
DialKeepAliveTimeout: 6 * time.Second,
Token: "test",
},
},
{
name: "default secure transport",
spec: ConfigSpec{

View File

@ -15,7 +15,6 @@
package credentials
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
@ -25,7 +24,7 @@ import (
func TestUpdateAuthToken(t *testing.T) {
bundle := NewPerRPCCredentialBundle()
ctx := context.TODO()
ctx := t.Context()
metadataBeforeUpdate, _ := bundle.PerRPCCredentials().GetRequestMetadata(ctx)
assert.Empty(t, metadataBeforeUpdate)

View File

@ -15,7 +15,6 @@
package clientv3
import (
"context"
"reflect"
"testing"
@ -27,7 +26,7 @@ import (
)
func TestMetadataWithRequireLeader(t *testing.T) {
ctx := context.TODO()
ctx := t.Context()
_, ok := metadata.FromOutgoingContext(ctx)
require.Falsef(t, ok, "expected no outgoing metadata ctx key")
@ -48,7 +47,7 @@ func TestMetadataWithRequireLeader(t *testing.T) {
}
func TestMetadataWithClientAPIVersion(t *testing.T) {
ctx := withVersion(WithRequireLeader(context.TODO()))
ctx := withVersion(WithRequireLeader(t.Context()))
md, ok := metadata.FromOutgoingContext(ctx)
require.Truef(t, ok, "expected outgoing metadata ctx key")

View File

@ -1,46 +1,47 @@
module go.etcd.io/etcd/client/v3
go 1.23
go 1.24
toolchain go1.23.6
toolchain go1.24.4
require (
github.com/coreos/go-semver v0.3.1
github.com/dustin/go-humanize v1.0.1
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1
github.com/prometheus/client_golang v1.20.5
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0
github.com/prometheus/client_golang v1.22.0
github.com/stretchr/testify v1.10.0
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
go.uber.org/zap v1.27.0
google.golang.org/grpc v1.70.0
sigs.k8s.io/yaml v1.4.0
google.golang.org/grpc v1.73.0
sigs.k8s.io/yaml v1.5.0
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/protobuf v1.36.4 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -6,12 +6,12 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@ -19,21 +19,20 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -42,40 +41,44 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -85,20 +88,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@ -107,18 +110,18 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=

View File

@ -60,16 +60,28 @@ func (r *EtcdManualResolver) SetEndpoints(endpoints []string) {
}
func (r EtcdManualResolver) updateState() {
if r.CC != nil {
addresses := make([]resolver.Address, len(r.endpoints))
if getCC(r) != nil {
eps := make([]resolver.Endpoint, len(r.endpoints))
for i, ep := range r.endpoints {
addr, serverName := endpoint.Interpret(ep)
addresses[i] = resolver.Address{Addr: addr, ServerName: serverName}
eps[i] = resolver.Endpoint{Addresses: []resolver.Address{
{Addr: addr, ServerName: serverName},
}}
}
state := resolver.State{
Addresses: addresses,
Endpoints: eps,
ServiceConfig: r.serviceConfig,
}
r.UpdateState(state)
}
}
func getCC(r EtcdManualResolver) (cc resolver.ClientConn) {
defer func() {
if rec := recover(); rec != nil {
cc = nil
}
}()
return r.CC()
}

View File

@ -134,7 +134,7 @@ func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*C
if err != nil {
return nil, ContextError(ctx, err)
}
return (*CompactResponse)(resp), err
return (*CompactResponse)(resp), nil
}
func (kv *kv) Txn(ctx context.Context) Txn {

View File

@ -32,6 +32,8 @@ type Endpoint struct {
// Metadata is the information associated with Addr, which may be used
// to make load balancing decision.
// Since etcd 3.1
//
// Deprecated: The field is deprecated and will be removed in 3.7.
Metadata any
}

View File

@ -100,22 +100,26 @@ func (r *resolver) watch() {
}
}
addrs := convertToGRPCAddress(allUps)
r.cc.UpdateState(gresolver.State{Addresses: addrs})
eps := convertToGRPCEndpoint(allUps)
r.cc.UpdateState(gresolver.State{Endpoints: eps})
}
}
}
func convertToGRPCAddress(ups map[string]*endpoints.Update) []gresolver.Address {
var addrs []gresolver.Address
func convertToGRPCEndpoint(ups map[string]*endpoints.Update) []gresolver.Endpoint {
var eps []gresolver.Endpoint
for _, up := range ups {
addr := gresolver.Address{
Addr: up.Endpoint.Addr,
Metadata: up.Endpoint.Metadata,
ep := gresolver.Endpoint{
Addresses: []gresolver.Address{
{
Addr: up.Endpoint.Addr,
Metadata: up.Endpoint.Metadata,
},
},
}
addrs = append(addrs, addr)
eps = append(eps, ep)
}
return addrs
return eps
}
// ResolveNow is a no-op here.

View File

@ -76,7 +76,7 @@ func TestKvOrdering(t *testing.T) {
tt.prevRev,
sync.RWMutex{},
}
res, err := kv.Get(context.TODO(), "mockKey")
res, err := kv.Get(t.Context(), "mockKey")
if err != nil {
t.Errorf("#%d: expected response %+v, got error %+v", i, tt.response, err)
}
@ -131,9 +131,9 @@ func TestTxnOrdering(t *testing.T) {
sync.RWMutex{},
}
txn := &txnOrdering{
kv.Txn(context.Background()),
kv.Txn(t.Context()),
kv,
context.Background(),
t.Context(),
sync.Mutex{},
[]clientv3.Cmp{},
[]clientv3.Op{},

View File

@ -351,11 +351,11 @@ func isContextError(err error) bool {
func contextErrToGRPCErr(err error) error {
switch {
case errors.Is(err, context.DeadlineExceeded):
return status.Errorf(codes.DeadlineExceeded, err.Error())
return status.Error(codes.DeadlineExceeded, err.Error())
case errors.Is(err, context.Canceled):
return status.Errorf(codes.Canceled, err.Error())
return status.Error(codes.Canceled, err.Error())
default:
return status.Errorf(codes.Unknown, err.Error())
return status.Error(codes.Unknown, err.Error())
}
}

View File

@ -15,7 +15,6 @@
package clientv3
import (
"context"
"testing"
"time"
@ -44,7 +43,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).If(cmp).If(cmp)
kv.Txn(t.Context()).If(cmp).If(cmp)
},
err: "cannot call If twice!",
@ -52,7 +51,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).Then(op).If(cmp)
kv.Txn(t.Context()).Then(op).If(cmp)
},
err: "cannot call If after Then!",
@ -60,7 +59,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).Else(op).If(cmp)
kv.Txn(t.Context()).Else(op).If(cmp)
},
err: "cannot call If after Else!",
@ -68,7 +67,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).Then(op).Then(op)
kv.Txn(t.Context()).Then(op).Then(op)
},
err: "cannot call Then twice!",
@ -76,7 +75,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).Else(op).Then(op)
kv.Txn(t.Context()).Else(op).Then(op)
},
err: "cannot call Then after Else!",
@ -84,7 +83,7 @@ func TestTxnPanics(t *testing.T) {
{
f: func(errc chan string) {
defer df(errc)
kv.Txn(context.TODO()).Else(op).Else(op)
kv.Txn(t.Context()).Else(op).Else(op)
},
err: "cannot call Else twice!",

Some files were not shown because too many files have changed in this diff Show More