Compare commits
54 Commits
dependabot
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
cea1e2ee12 | |||
2eb0e2d7d5 | |||
0c55ed7464 | |||
f7262d1a1b | |||
362477b077 | |||
ac66c2a013 | |||
3c79b2aca6 | |||
538162ad2a | |||
35f4a6c91a | |||
de090eb719 | |||
205c6f24ec | |||
08d799c4cc | |||
ac25ceeaee | |||
0644d5b099 | |||
5b572f1516 | |||
23da38c1cb | |||
cc9ca40470 | |||
48fa1b934f | |||
a05156fe99 | |||
a2721a30fa | |||
f7be2dfa17 | |||
4e986363a3 | |||
f7ff898fd6 | |||
67f17166bf | |||
f7e488dc92 | |||
2f03bbc5dd | |||
9590a02f94 | |||
51bd8bd4e8 | |||
5c476cc9e9 | |||
2cf112f3b9 | |||
a70fa9b471 | |||
ed01ee1e5e | |||
616c5a47de | |||
36b2523669 | |||
dfdffe48f9 | |||
68565c5ed7 | |||
c89ee6f120 | |||
8a7596304a | |||
d298130eb0 | |||
ef0a2903ce | |||
dc76bf4af2 | |||
e3324dd128 | |||
c230928240 | |||
1bfed3a0b6 | |||
0e8b9b2ef2 | |||
54822c47e9 | |||
f0d85826c9 | |||
9ffd2d51f3 | |||
fe61388dcf | |||
365a3cc7d1 | |||
3ab54f720f | |||
4c853774e6 | |||
f2d718e641 | |||
00ce0116c5 |
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@ -19,3 +19,8 @@ updates:
|
||||
interval: weekly
|
||||
allow:
|
||||
- dependency-type: all
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
|
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
uses: github/codeql-action/init@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
|
||||
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@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
uses: github/codeql-action/autobuild@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
uses: github/codeql-action/analyze@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
|
||||
|
2
.github/workflows/contrib.yaml
vendored
2
.github/workflows/contrib.yaml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
|
2
.github/workflows/coverage.yaml
vendored
2
.github/workflows/coverage.yaml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
|
6
.github/workflows/e2e-arm64.yaml
vendored
6
.github/workflows/e2e-arm64.yaml
vendored
@ -6,19 +6,17 @@ jobs:
|
||||
test:
|
||||
# this is to prevent the job to run at forked projects
|
||||
if: github.repository == 'etcd-io/etcd'
|
||||
runs-on: actuated-arm64-8cpu-32gb
|
||||
runs-on: actuated-arm64-8cpu-8gb
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- linux-arm64-e2e
|
||||
steps:
|
||||
- name: Collect Workflow Telemetry
|
||||
uses: catchpoint/workflow-telemetry-action@v1
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
|
2
.github/workflows/e2e.yaml
vendored
2
.github/workflows/e2e.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
|
4
.github/workflows/fuzzing.yaml
vendored
4
.github/workflows/fuzzing.yaml
vendored
@ -13,14 +13,14 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
|
||||
GOARCH=amd64 CPU=4 make fuzz
|
||||
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
if: failure()
|
||||
with:
|
||||
path: "${{env.TARGET_PATH}}/testdata/fuzz/**/*"
|
||||
|
2
.github/workflows/govuln.yaml
vendored
2
.github/workflows/govuln.yaml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
|
2
.github/workflows/grpcproxy.yaml
vendored
2
.github/workflows/grpcproxy.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
|
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- name: release
|
||||
|
4
.github/workflows/robustness-nightly.yaml
vendored
4
.github/workflows/robustness-nightly.yaml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
count: 80
|
||||
testTimeout: 200m
|
||||
artifactName: main-arm64
|
||||
runs-on: "['actuated-arm64-8cpu-32gb']"
|
||||
runs-on: "['actuated-arm64-8cpu-8gb']"
|
||||
release-35:
|
||||
uses: ./.github/workflows/robustness-template.yaml
|
||||
with:
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
count: 100
|
||||
testTimeout: 200m
|
||||
artifactName: release-35-arm64
|
||||
runs-on: "['actuated-arm64-8cpu-32gb']"
|
||||
runs-on: "['actuated-arm64-8cpu-8gb']"
|
||||
release-34:
|
||||
uses: ./.github/workflows/robustness-template.yaml
|
||||
with:
|
||||
|
6
.github/workflows/robustness-template.yaml
vendored
6
.github/workflows/robustness-template.yaml
vendored
@ -27,12 +27,10 @@ jobs:
|
||||
timeout-minutes: 210
|
||||
runs-on: ${{ fromJson(inputs.runs-on) }}
|
||||
steps:
|
||||
- name: Collect Workflow Telemetry
|
||||
uses: catchpoint/workflow-telemetry-action@v1
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- name: test-robustness
|
||||
@ -65,7 +63,7 @@ jobs:
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ inputs.artifactName }}
|
||||
|
2
.github/workflows/robustness.yaml
vendored
2
.github/workflows/robustness.yaml
vendored
@ -18,4 +18,4 @@ jobs:
|
||||
count: 12
|
||||
testTimeout: 30m
|
||||
artifactName: main-arm64
|
||||
runs-on: "['actuated-arm64-8cpu-32gb']"
|
||||
runs-on: "['actuated-arm64-8cpu-8gb']"
|
||||
|
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
@ -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@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
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@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
|
||||
uses: github/codeql-action/upload-sarif@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
2
.github/workflows/static-analysis.yaml
vendored
2
.github/workflows/static-analysis.yaml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- id: golangci_lint_version
|
||||
|
7
.github/workflows/tests-template.yaml
vendored
7
.github/workflows/tests-template.yaml
vendored
@ -26,12 +26,10 @@ jobs:
|
||||
- linux-${{ inputs.arch }}-unit-4-cpu
|
||||
- linux-386-unit-1-cpu
|
||||
steps:
|
||||
- name: Collect Workflow Telemetry
|
||||
uses: catchpoint/workflow-telemetry-action@v1
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
@ -68,7 +66,8 @@ jobs:
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
if: always()
|
||||
with:
|
||||
name: "${{ matrix.target }}"
|
||||
path: ./**/junit_*.xml
|
||||
|
2
.github/workflows/tests.yaml
vendored
2
.github/workflows/tests.yaml
vendored
@ -12,4 +12,4 @@ jobs:
|
||||
uses: ./.github/workflows/tests-template.yaml
|
||||
with:
|
||||
arch: arm64
|
||||
runs-on: actuated-arm64-8cpu-32gb
|
||||
runs-on: actuated-arm64-8cpu-8gb
|
||||
|
@ -4,6 +4,10 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
|
||||
|
||||
## v3.4.29 (tbd)
|
||||
|
||||
### etcd server
|
||||
- [Disable following HTTP redirects in peer communication](https://github.com/etcd-io/etcd/pull/17112)
|
||||
- [Add livez/readyz HTTP endpoints](https://github.com/etcd-io/etcd/pull/17128)
|
||||
|
||||
### Dependencies
|
||||
- Compile binaries using go [1.20.12](https://github.com/etcd-io/etcd/pull/17076).
|
||||
|
||||
|
@ -4,6 +4,11 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.5.12 (tbd)
|
||||
|
||||
### etcd server
|
||||
- [Add livez/readyz HTTP endpoints](https://github.com/etcd-io/etcd/pull/17039)
|
||||
|
||||
## v3.5.11 (2023-12-07)
|
||||
|
||||
### etcd server
|
||||
|
@ -1,5 +1,5 @@
|
||||
ARG ARCH=amd64
|
||||
FROM --platform=linux/${ARCH} gcr.io/distroless/static-debian12
|
||||
FROM --platform=linux/${ARCH} gcr.io/distroless/static-debian12@sha256:4a2c1a51ae5e10ec4758a0f981be3ce5d6ac55445828463fce8dff3a355e0b75
|
||||
|
||||
ADD etcd /usr/local/bin/
|
||||
ADD etcdctl /usr/local/bin/
|
||||
|
@ -9,6 +9,7 @@
|
||||
[](https://github.com/etcd-io/etcd/releases)
|
||||
[](https://github.com/etcd-io/etcd/blob/main/LICENSE)
|
||||
[](https://api.securityscorecards.dev/projects/github.com/etcd-io/etcd)
|
||||
<a href="https://actuated.dev/"><img alt="Arm CI sponsored by Actuated" src="https://docs.actuated.dev/images/actuated-badge.png" width="120px"></img></a>
|
||||
|
||||
**Note**: The `main` branch may be in an *unstable or even broken state* during development. For stable versions, see [releases][github-release].
|
||||
|
||||
|
@ -9,7 +9,7 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
google.golang.org/protobuf v1.31.0
|
||||
)
|
||||
|
||||
|
@ -64,8 +64,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -11,7 +11,7 @@ require (
|
||||
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.26.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
|
@ -91,8 +91,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -549,9 +549,12 @@ func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) {
|
||||
// deadlineLoop reaps any keep alive channels that have not received a response
|
||||
// within the lease TTL
|
||||
func (l *lessor) deadlineLoop() {
|
||||
timer := time.NewTimer(time.Second)
|
||||
defer timer.Stop()
|
||||
for {
|
||||
timer.Reset(time.Second)
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
case <-timer.C:
|
||||
case <-l.donec:
|
||||
return
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
Scripts and files which may be useful but aren't part of the core etcd project.
|
||||
|
||||
* [systemd](systemd) - an example unit file for deploying etcd on systemd-based distributions
|
||||
* [lock](lock) - example addressing the expired lease problem of distributed locking with etcd
|
||||
* [mixin](mixin) - customisable set of Grafana dashboard and Prometheus alerts for etcd
|
||||
* [raftexample](raftexample) - an example distributed key-value store using raft
|
||||
* [systemd](systemd) - an example unit file for deploying etcd on systemd-based distributions
|
||||
* [systemd/etcd3-multinode](systemd/etcd3-multinode) - multi-node cluster setup with systemd
|
||||
|
@ -15,7 +15,7 @@ require (
|
||||
go.etcd.io/etcd/pkg/v3 v3.6.0-alpha.0
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -116,8 +116,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -62,7 +62,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
@ -70,7 +70,7 @@ require (
|
||||
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/grpc v1.60.1 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
||||
)
|
||||
|
@ -101,8 +101,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
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/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
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=
|
||||
@ -135,16 +135,16 @@ 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/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U=
|
||||
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
6
go.mod
6
go.mod
@ -34,7 +34,7 @@ require (
|
||||
go.etcd.io/raft/v3 v3.0.0-20231012085229-7c3ed830bbb0
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
google.golang.org/protobuf v1.31.0
|
||||
)
|
||||
|
||||
@ -46,7 +46,7 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
@ -86,7 +86,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
|
16
go.sum
16
go.sum
@ -45,8 +45,8 @@ github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBD
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/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/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@ -177,8 +177,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
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/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@ -236,8 +236,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
@ -252,8 +252,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -11,7 +11,7 @@ require (
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
|
||||
go.uber.org/zap v1.26.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -40,8 +40,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -90,18 +90,22 @@ func bootstrap(cfg config.ServerConfig) (b *bootstrappedServer, err error) {
|
||||
bwal = bootstrapWALFromSnapshot(cfg, backend.snapshot)
|
||||
}
|
||||
|
||||
cfg.Logger.Info("bootstrapping cluster")
|
||||
cluster, err := bootstrapCluster(cfg, bwal, prt)
|
||||
if err != nil {
|
||||
backend.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger.Info("bootstrapping storage")
|
||||
s := bootstrapStorage(cfg, st, backend, bwal, cluster)
|
||||
|
||||
if err = cluster.Finalize(cfg, s); err != nil {
|
||||
backend.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger.Info("bootstrapping raft")
|
||||
raft := bootstrapRaft(cfg, cluster, s.wal)
|
||||
return &bootstrappedServer{
|
||||
prt: prt,
|
||||
|
@ -298,8 +298,10 @@ type EtcdServer struct {
|
||||
func NewServer(cfg config.ServerConfig) (srv *EtcdServer, err error) {
|
||||
b, err := bootstrap(cfg)
|
||||
if err != nil {
|
||||
cfg.Logger.Error("bootstrap failed", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
cfg.Logger.Info("bootstrap successfully")
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@ -392,8 +394,15 @@ func NewServer(cfg config.ServerConfig) (srv *EtcdServer, err error) {
|
||||
|
||||
if srv.Cfg.EnableLeaseCheckpoint {
|
||||
// setting checkpointer enables lease checkpoint feature.
|
||||
srv.lessor.SetCheckpointer(func(ctx context.Context, cp *pb.LeaseCheckpointRequest) {
|
||||
srv.lessor.SetCheckpointer(func(ctx context.Context, cp *pb.LeaseCheckpointRequest) error {
|
||||
if !srv.ensureLeadership() {
|
||||
srv.lg.Warn("Ignore the checkpoint request because current member isn't a leader",
|
||||
zap.Uint64("local-member-id", uint64(srv.MemberId())))
|
||||
return lease.ErrNotPrimary
|
||||
}
|
||||
|
||||
srv.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseCheckpoint: cp})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -842,7 +851,19 @@ func (s *EtcdServer) run() {
|
||||
|
||||
func (s *EtcdServer) revokeExpiredLeases(leases []*lease.Lease) {
|
||||
s.GoAttach(func() {
|
||||
// We shouldn't revoke any leases if current member isn't a leader,
|
||||
// because the operation should only be performed by the leader. When
|
||||
// the leader gets blocked on the raft loop, such as writing WAL entries,
|
||||
// it can't process any events or messages from raft. It may think it
|
||||
// is still the leader even the leader has already changed.
|
||||
// Refer to https://github.com/etcd-io/etcd/issues/15247
|
||||
lg := s.Logger()
|
||||
if !s.ensureLeadership() {
|
||||
lg.Warn("Ignore the lease revoking request because current member isn't a leader",
|
||||
zap.Uint64("local-member-id", uint64(s.MemberId())))
|
||||
return
|
||||
}
|
||||
|
||||
// Increases throughput of expired leases deletion process through parallelization
|
||||
c := make(chan struct{}, maxPendingRevokes)
|
||||
for _, curLease := range leases {
|
||||
@ -875,6 +896,29 @@ func (s *EtcdServer) revokeExpiredLeases(leases []*lease.Lease) {
|
||||
})
|
||||
}
|
||||
|
||||
// ensureLeadership checks whether current member is still the leader.
|
||||
func (s *EtcdServer) ensureLeadership() bool {
|
||||
lg := s.Logger()
|
||||
|
||||
ctx, cancel := context.WithTimeout(s.ctx, s.Cfg.ReqTimeout())
|
||||
defer cancel()
|
||||
if err := s.linearizableReadNotify(ctx); err != nil {
|
||||
lg.Warn("Failed to check current member's leadership",
|
||||
zap.Error(err))
|
||||
return false
|
||||
}
|
||||
|
||||
newLeaderId := s.raftStatus().Lead
|
||||
if newLeaderId != uint64(s.MemberId()) {
|
||||
lg.Warn("Current member isn't a leader",
|
||||
zap.Uint64("local-member-id", uint64(s.MemberId())),
|
||||
zap.Uint64("new-lead", newLeaderId))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Cleanup removes allocated objects by EtcdServer.NewServer in
|
||||
// situation that EtcdServer::Start was not called (that takes care of cleanup).
|
||||
func (s *EtcdServer) Cleanup() {
|
||||
@ -1975,7 +2019,9 @@ func removeNeedlessRangeReqs(txn *pb.TxnRequest) {
|
||||
// applyConfChange applies a ConfChange to the server. It is only
|
||||
// invoked with a ConfChange that has already passed through Raft
|
||||
func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.ConfState, shouldApplyV3 membership.ShouldApplyV3) (bool, error) {
|
||||
lg := s.Logger()
|
||||
if err := s.cluster.ValidateConfigurationChange(cc); err != nil {
|
||||
lg.Error("Validation on configuration change failed", zap.Bool("shouldApplyV3", bool(shouldApplyV3)), zap.Error(err))
|
||||
cc.NodeID = raft.None
|
||||
s.r.ApplyConfChange(cc)
|
||||
|
||||
@ -1988,7 +2034,6 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con
|
||||
return false, err
|
||||
}
|
||||
|
||||
lg := s.Logger()
|
||||
*confState = *s.r.ApplyConfChange(cc)
|
||||
s.beHooks.SetConfState(confState)
|
||||
switch cc.Type {
|
||||
|
@ -278,6 +278,16 @@ func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest)
|
||||
|
||||
func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error) {
|
||||
if s.isLeader() {
|
||||
// If s.isLeader() returns true, but we fail to ensure the current
|
||||
// member's leadership, there are a couple of possibilities:
|
||||
// 1. current member gets stuck on writing WAL entries;
|
||||
// 2. current member is in network isolation status;
|
||||
// 3. current member isn't a leader anymore (possibly due to #1 above).
|
||||
// In such case, we just return error to client, so that the client can
|
||||
// switch to another member to continue the lease keep-alive operation.
|
||||
if !s.ensureLeadership() {
|
||||
return -1, lease.ErrNotPrimary
|
||||
}
|
||||
if err := s.waitAppliedIndex(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -35,11 +35,11 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.21.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/crypto v0.16.0
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/net v0.19.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
|
@ -155,8 +155,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
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/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@ -210,8 +210,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
@ -226,8 +226,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -75,7 +75,7 @@ type RangeDeleter func() TxnDelete
|
||||
|
||||
// Checkpointer permits checkpointing of lease remaining TTLs to the consensus log. Defined here to
|
||||
// avoid circular dependency with mvcc.
|
||||
type Checkpointer func(ctx context.Context, lc *pb.LeaseCheckpointRequest)
|
||||
type Checkpointer func(ctx context.Context, lc *pb.LeaseCheckpointRequest) error
|
||||
|
||||
type LeaseID int64
|
||||
|
||||
@ -422,7 +422,9 @@ func (le *lessor) Renew(id LeaseID) (int64, error) {
|
||||
// By applying a RAFT entry only when the remainingTTL is already set, we limit the number
|
||||
// of RAFT entries written per lease to a max of 2 per checkpoint interval.
|
||||
if clearRemainingTTL {
|
||||
le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: []*pb.LeaseCheckpoint{{ID: int64(l.ID), Remaining_TTL: 0}}})
|
||||
if err := le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: []*pb.LeaseCheckpoint{{ID: int64(l.ID), Remaining_TTL: 0}}}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
le.mu.Lock()
|
||||
@ -656,7 +658,9 @@ func (le *lessor) checkpointScheduledLeases() {
|
||||
le.mu.Unlock()
|
||||
|
||||
if len(cps) != 0 {
|
||||
le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: cps})
|
||||
if err := le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: cps}); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(cps) < maxLeaseCheckpointBatchSize {
|
||||
return
|
||||
|
@ -269,10 +269,11 @@ func TestLessorRenewWithCheckpointer(t *testing.T) {
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
le := newLessor(lg, be, clusterLatest(), LessorConfig{MinLeaseTTL: minLeaseTTL})
|
||||
fakerCheckerpointer := func(ctx context.Context, cp *pb.LeaseCheckpointRequest) {
|
||||
fakerCheckerpointer := func(ctx context.Context, cp *pb.LeaseCheckpointRequest) error {
|
||||
for _, cp := range cp.GetCheckpoints() {
|
||||
le.Checkpoint(LeaseID(cp.GetID()), cp.GetRemaining_TTL())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
defer le.Stop()
|
||||
// Set checkpointer
|
||||
@ -556,7 +557,7 @@ func TestLessorCheckpointScheduling(t *testing.T) {
|
||||
defer le.Stop()
|
||||
le.minLeaseTTL = 1
|
||||
checkpointedC := make(chan struct{})
|
||||
le.SetCheckpointer(func(ctx context.Context, lc *pb.LeaseCheckpointRequest) {
|
||||
le.SetCheckpointer(func(ctx context.Context, lc *pb.LeaseCheckpointRequest) error {
|
||||
close(checkpointedC)
|
||||
if len(lc.Checkpoints) != 1 {
|
||||
t.Errorf("expected 1 checkpoint but got %d", len(lc.Checkpoints))
|
||||
@ -565,6 +566,7 @@ func TestLessorCheckpointScheduling(t *testing.T) {
|
||||
if c.Remaining_TTL != 1 {
|
||||
t.Errorf("expected checkpoint to be called with Remaining_TTL=%d but got %d", 1, c.Remaining_TTL)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
_, err := le.Grant(1, 2)
|
||||
if err != nil {
|
||||
|
@ -218,15 +218,10 @@ func TestPeriodicCheckDetectsCorruption(t *testing.T) {
|
||||
assert.NoError(t, err, "error on put")
|
||||
}
|
||||
|
||||
members, err := cc.MemberList(ctx, false)
|
||||
memberID, found, err := getMemberIdByName(ctx, cc, epc.Procs[0].Config().Name)
|
||||
assert.NoError(t, err, "error on member list")
|
||||
var memberID uint64
|
||||
for _, m := range members.Members {
|
||||
if m.Name == epc.Procs[0].Config().Name {
|
||||
memberID = m.ID
|
||||
}
|
||||
}
|
||||
assert.NotZero(t, memberID, "member not found")
|
||||
assert.Equal(t, found, true, "member not found")
|
||||
|
||||
epc.Procs[0].Stop()
|
||||
err = testutil.CorruptBBolt(datadir.ToBackendFileName(epc.Procs[0].Config().DataDirPath))
|
||||
assert.NoError(t, err)
|
||||
@ -263,14 +258,9 @@ func TestCompactHashCheckDetectCorruption(t *testing.T) {
|
||||
err = cc.Put(ctx, testutil.PickKey(int64(i)), fmt.Sprint(i), config.PutOptions{})
|
||||
assert.NoError(t, err, "error on put")
|
||||
}
|
||||
members, err := cc.MemberList(ctx, false)
|
||||
memberID, found, err := getMemberIdByName(ctx, cc, epc.Procs[0].Config().Name)
|
||||
assert.NoError(t, err, "error on member list")
|
||||
var memberID uint64
|
||||
for _, m := range members.Members {
|
||||
if m.Name == epc.Procs[0].Config().Name {
|
||||
memberID = m.ID
|
||||
}
|
||||
}
|
||||
assert.Equal(t, found, true, "member not found")
|
||||
|
||||
epc.Procs[0].Stop()
|
||||
err = testutil.CorruptBBolt(datadir.ToBackendFileName(epc.Procs[0].Config().DataDirPath))
|
||||
|
99
tests/e2e/ctl_v3_member_no_proxy_test.go
Normal file
99
tests/e2e/ctl_v3_member_no_proxy_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
//go:build !cluster_proxy
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.etcd.io/etcd/server/v3/etcdserver"
|
||||
"go.etcd.io/etcd/tests/v3/framework/e2e"
|
||||
"go.etcd.io/etcd/tests/v3/framework/testutils"
|
||||
)
|
||||
|
||||
func TestMemberReplace(t *testing.T) {
|
||||
e2e.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
epc, err := e2e.NewEtcdProcessCluster(ctx, t)
|
||||
require.NoError(t, err)
|
||||
defer epc.Close()
|
||||
|
||||
memberIdx := rand.Int() % len(epc.Procs)
|
||||
member := epc.Procs[memberIdx]
|
||||
memberName := member.Config().Name
|
||||
var endpoints []string
|
||||
for i := 1; i < len(epc.Procs); i++ {
|
||||
endpoints = append(endpoints, epc.Procs[(memberIdx+i)%len(epc.Procs)].EndpointsGRPC()...)
|
||||
}
|
||||
cc, err := e2e.NewEtcdctl(epc.Cfg.Client, endpoints)
|
||||
require.NoError(t, err)
|
||||
|
||||
memberID, found, err := getMemberIdByName(ctx, cc, memberName)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, found, true, "Member not found")
|
||||
|
||||
// Need to wait health interval for cluster to accept member changes
|
||||
time.Sleep(etcdserver.HealthInterval)
|
||||
|
||||
t.Logf("Removing member %s", memberName)
|
||||
_, err = cc.MemberRemove(ctx, memberID)
|
||||
require.NoError(t, err)
|
||||
_, found, err = getMemberIdByName(ctx, cc, memberName)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, found, false, "Expected member to be removed")
|
||||
for member.IsRunning() {
|
||||
err = member.Wait(ctx)
|
||||
if err != nil && !strings.Contains(err.Error(), "unexpected exit code") {
|
||||
t.Fatalf("member didn't exit as expected: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("Removing member %s data", memberName)
|
||||
err = os.RemoveAll(member.Config().DataDirPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Logf("Adding member %s back", memberName)
|
||||
removedMemberPeerUrl := member.Config().PeerURL.String()
|
||||
_, err = cc.MemberAdd(ctx, memberName, []string{removedMemberPeerUrl})
|
||||
require.NoError(t, err)
|
||||
err = patchArgs(member.Config().Args, "initial-cluster-state", "existing")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Sleep 100ms to bypass the known issue https://github.com/etcd-io/etcd/issues/16687.
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
t.Logf("Starting member %s", memberName)
|
||||
err = member.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
for {
|
||||
_, found, err := getMemberIdByName(ctx, cc, memberName)
|
||||
if err != nil || !found {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
@ -20,11 +20,13 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
v3rpc "go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
@ -450,3 +452,63 @@ func hasKVs(t *testing.T, ctl *e2e.EtcdctlV3, kvs []testutils.KV, currentRev int
|
||||
require.True(t, int64(currentRev) >= v.Kvs[0].ModRevision)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBreakConsistentIndexNewerThanSnapshot(t *testing.T) {
|
||||
e2e.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var snapshotCount uint64 = 50
|
||||
epc, err := e2e.NewEtcdProcessCluster(ctx, t,
|
||||
e2e.WithClusterSize(1),
|
||||
e2e.WithKeepDataDir(true),
|
||||
e2e.WithSnapshotCount(snapshotCount),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer epc.Close()
|
||||
member := epc.Procs[0]
|
||||
|
||||
t.Log("Stop member and copy out the db file to tmp directory")
|
||||
err = member.Stop()
|
||||
assert.NoError(t, err)
|
||||
dbPath := path.Join(member.Config().DataDirPath, "member", "snap", "db")
|
||||
tmpFile := path.Join(t.TempDir(), "db")
|
||||
err = copyFile(dbPath, tmpFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Log("Ensure snapshot there is a newer snapshot")
|
||||
err = member.Start(ctx)
|
||||
assert.NoError(t, err)
|
||||
generateSnapshot(t, snapshotCount, member.Etcdctl())
|
||||
_, err = member.Logs().ExpectWithContext(ctx, expect.ExpectedResponse{Value: "saved snapshot"})
|
||||
assert.NoError(t, err)
|
||||
err = member.Stop()
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Log("Start etcd with older db file")
|
||||
err = copyFile(tmpFile, dbPath)
|
||||
assert.NoError(t, err)
|
||||
err = member.Start(ctx)
|
||||
assert.Error(t, err)
|
||||
_, err = member.Logs().ExpectWithContext(ctx, expect.ExpectedResponse{Value: "failed to find database snapshot file (snap: snapshot file doesn't exist)"})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
f, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
w, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
if _, err = io.Copy(w, f); err != nil {
|
||||
return err
|
||||
}
|
||||
return w.Sync()
|
||||
}
|
||||
|
@ -122,3 +122,26 @@ func runCommandAndReadJsonOutput(args []string) (map[string]any, error) {
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func getMemberIdByName(ctx context.Context, c *e2e.EtcdctlV3, name string) (id uint64, found bool, err error) {
|
||||
resp, err := c.MemberList(ctx, false)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
for _, member := range resp.Members {
|
||||
if name == member.Name {
|
||||
return member.ID, true, nil
|
||||
}
|
||||
}
|
||||
return 0, false, nil
|
||||
}
|
||||
|
||||
func patchArgs(args []string, flag, newValue string) error {
|
||||
for i, arg := range args {
|
||||
if strings.Contains(arg, flag) {
|
||||
args[i] = fmt.Sprintf("--%s=%s", flag, newValue)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("--%s flag not found", flag)
|
||||
}
|
||||
|
157
tests/e2e/v3_lease_no_proxy_test.go
Normal file
157
tests/e2e/v3_lease_no_proxy_test.go
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
//go:build !cluster_proxy
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/tests/v3/framework/e2e"
|
||||
"go.etcd.io/etcd/tests/v3/framework/testutils"
|
||||
)
|
||||
|
||||
// TestLeaseRevoke_IgnoreOldLeader verifies that leases shouldn't be revoked
|
||||
// by old leader.
|
||||
// See the case 1 in https://github.com/etcd-io/etcd/issues/15247#issuecomment-1777862093.
|
||||
func TestLeaseRevoke_IgnoreOldLeader(t *testing.T) {
|
||||
testLeaseRevokeIssue(t, true)
|
||||
}
|
||||
|
||||
// TestLeaseRevoke_ClientSwitchToOtherMember verifies that leases shouldn't
|
||||
// be revoked by new leader.
|
||||
// See the case 2 in https://github.com/etcd-io/etcd/issues/15247#issuecomment-1777862093.
|
||||
func TestLeaseRevoke_ClientSwitchToOtherMember(t *testing.T) {
|
||||
testLeaseRevokeIssue(t, false)
|
||||
}
|
||||
|
||||
func testLeaseRevokeIssue(t *testing.T, connectToOneFollower bool) {
|
||||
e2e.BeforeTest(t)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
t.Log("Starting a new etcd cluster")
|
||||
epc, err := e2e.NewEtcdProcessCluster(ctx, t,
|
||||
e2e.WithClusterSize(3),
|
||||
e2e.WithGoFailEnabled(true),
|
||||
e2e.WithGoFailClientTimeout(40*time.Second),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
if errC := epc.Close(); errC != nil {
|
||||
t.Fatalf("error closing etcd processes (%v)", errC)
|
||||
}
|
||||
}()
|
||||
|
||||
leaderIdx := epc.WaitLeader(t)
|
||||
t.Logf("Leader index: %d", leaderIdx)
|
||||
|
||||
epsForNormalOperations := epc.Procs[(leaderIdx+2)%3].EndpointsGRPC()
|
||||
t.Logf("Creating a client for normal operations: %v", epsForNormalOperations)
|
||||
client, err := clientv3.New(clientv3.Config{Endpoints: epsForNormalOperations, DialTimeout: 3 * time.Second})
|
||||
require.NoError(t, err)
|
||||
defer client.Close()
|
||||
|
||||
var epsForLeaseKeepAlive []string
|
||||
if connectToOneFollower {
|
||||
epsForLeaseKeepAlive = epc.Procs[(leaderIdx+1)%3].EndpointsGRPC()
|
||||
} else {
|
||||
epsForLeaseKeepAlive = epc.EndpointsGRPC()
|
||||
}
|
||||
t.Logf("Creating a client for the leaseKeepAlive operation: %v", epsForLeaseKeepAlive)
|
||||
clientForKeepAlive, err := clientv3.New(clientv3.Config{Endpoints: epsForLeaseKeepAlive, DialTimeout: 3 * time.Second})
|
||||
require.NoError(t, err)
|
||||
defer clientForKeepAlive.Close()
|
||||
|
||||
resp, err := client.Status(ctx, epsForNormalOperations[0])
|
||||
require.NoError(t, err)
|
||||
oldLeaderId := resp.Leader
|
||||
|
||||
t.Log("Creating a new lease")
|
||||
leaseRsp, err := client.Grant(ctx, 20)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Log("Starting a goroutine to keep alive the lease")
|
||||
doneC := make(chan struct{})
|
||||
stopC := make(chan struct{})
|
||||
startC := make(chan struct{}, 1)
|
||||
go func() {
|
||||
defer close(doneC)
|
||||
|
||||
respC, kerr := clientForKeepAlive.KeepAlive(ctx, leaseRsp.ID)
|
||||
require.NoError(t, kerr)
|
||||
// ensure we have received the first response from the server
|
||||
<-respC
|
||||
startC <- struct{}{}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stopC:
|
||||
return
|
||||
case <-respC:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
t.Log("Wait for the keepAlive goroutine to get started")
|
||||
<-startC
|
||||
|
||||
t.Log("Trigger the failpoint to simulate stalled writing")
|
||||
err = epc.Procs[leaderIdx].Failpoints().SetupHTTP(ctx, "raftBeforeSave", `sleep("30s")`)
|
||||
require.NoError(t, err)
|
||||
|
||||
cctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
t.Logf("Waiting for a new leader to be elected, old leader index: %d, old leader ID: %d", leaderIdx, oldLeaderId)
|
||||
testutils.ExecuteUntil(cctx, t, func() {
|
||||
for {
|
||||
resp, err = client.Status(ctx, epsForNormalOperations[0])
|
||||
if err == nil && resp.Leader != oldLeaderId {
|
||||
t.Logf("A new leader has already been elected, new leader index: %d", resp.Leader)
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
})
|
||||
cancel()
|
||||
|
||||
t.Log("Writing a key/value pair")
|
||||
_, err = client.Put(ctx, "foo", "bar")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Log("Sleeping 30 seconds")
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
t.Log("Remove the failpoint 'raftBeforeSave'")
|
||||
err = epc.Procs[leaderIdx].Failpoints().DeactivateHTTP(ctx, "raftBeforeSave")
|
||||
require.NoError(t, err)
|
||||
|
||||
// By default, etcd tries to revoke leases every 7 seconds.
|
||||
t.Log("Sleeping 10 seconds")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
t.Log("Confirming the lease isn't revoked")
|
||||
leases, err := client.Leases(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(leases.Leases))
|
||||
|
||||
t.Log("Waiting for the keepAlive goroutine to exit")
|
||||
close(stopC)
|
||||
<-doneC
|
||||
}
|
@ -79,13 +79,10 @@ func (logOb *LogObserver) ExpectFunc(ctx context.Context, filter func(string) bo
|
||||
}
|
||||
|
||||
if len(res) >= count {
|
||||
break
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(res) >= count {
|
||||
return res, nil
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.21.0
|
||||
go.opentelemetry.io/proto/otlp v1.0.0
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/crypto v0.16.0
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/sync v0.4.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/grpc v1.60.1
|
||||
google.golang.org/protobuf v1.31.0
|
||||
)
|
||||
|
||||
|
12
tests/go.sum
12
tests/go.sum
@ -181,8 +181,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
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/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@ -240,8 +240,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
@ -256,8 +256,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
|
@ -350,7 +350,9 @@ func putAndWatch(t *testing.T, wctx *watchctx, key, val string) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchResumeInitRev(t *testing.T) {
|
||||
// TestWatchResumeAfterDisconnect tests watch resume after member disconnects then connects.
|
||||
// It ensures that correct events are returned corresponding to the start revision.
|
||||
func TestWatchResumeAfterDisconnect(t *testing.T) {
|
||||
integration2.BeforeTest(t)
|
||||
clus := integration2.NewCluster(t, &integration2.ClusterConfig{Size: 1, UseBridge: true})
|
||||
defer clus.Terminate(t)
|
||||
@ -367,7 +369,10 @@ func TestWatchResumeInitRev(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// watch from revision 1
|
||||
wch := clus.Client(0).Watch(context.Background(), "a", clientv3.WithRev(1), clientv3.WithCreatedNotify())
|
||||
// response for the create watch request, no events are in this response
|
||||
// the current revision of etcd should be 4
|
||||
if resp, ok := <-wch; !ok || resp.Header.Revision != 4 {
|
||||
t.Fatalf("got (%v, %v), expected create notification rev=4", resp, ok)
|
||||
}
|
||||
@ -389,12 +394,16 @@ func TestWatchResumeInitRev(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("unexpected watch close")
|
||||
}
|
||||
if len(resp.Events) == 0 {
|
||||
t.Fatal("expected event on watch")
|
||||
// Events should be put(a, 3) and put(a, 4)
|
||||
if len(resp.Events) != 2 {
|
||||
t.Fatal("expected two events on watch")
|
||||
}
|
||||
if string(resp.Events[0].Kv.Value) != "3" {
|
||||
t.Fatalf("expected value=3, got event %+v", resp.Events[0])
|
||||
}
|
||||
if string(resp.Events[1].Kv.Value) != "4" {
|
||||
t.Fatalf("expected value=4, got event %+v", resp.Events[1])
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("watch timed out")
|
||||
}
|
||||
|
@ -747,7 +747,7 @@ func TestV3LeaseFailover(t *testing.T) {
|
||||
|
||||
// send keep alive to old leader until the old leader starts
|
||||
// to drop lease request.
|
||||
var expectedExp time.Time
|
||||
expectedExp := time.Now().Add(5 * time.Second)
|
||||
for {
|
||||
if err = lac.Send(lreq); err != nil {
|
||||
break
|
||||
|
@ -52,7 +52,7 @@ gofail-disable: install-gofail
|
||||
|
||||
.PHONY: install-gofail
|
||||
install-gofail:
|
||||
cd tools/mod; go install go.etcd.io/gofail@${GOFAIL_VERSION}
|
||||
go install go.etcd.io/gofail@${GOFAIL_VERSION}
|
||||
|
||||
# Build previous releases for robustness tests
|
||||
|
||||
|
@ -155,7 +155,7 @@ func (t kubernetesTraffic) Write(ctx context.Context, kc *kubernetesClient, ids
|
||||
} else {
|
||||
choices := t.writeChoices
|
||||
if !nonUniqueWriteLimiter.Take() {
|
||||
choices = filterOutNonUniqueKuberntesWrites(t.writeChoices)
|
||||
choices = filterOutNonUniqueKubernetesWrites(t.writeChoices)
|
||||
}
|
||||
op := pickRandom(choices)
|
||||
switch op {
|
||||
@ -178,7 +178,7 @@ func (t kubernetesTraffic) Write(ctx context.Context, kc *kubernetesClient, ids
|
||||
return nil
|
||||
}
|
||||
|
||||
func filterOutNonUniqueKuberntesWrites(choices []choiceWeight[KubernetesRequestType]) (resp []choiceWeight[KubernetesRequestType]) {
|
||||
func filterOutNonUniqueKubernetesWrites(choices []choiceWeight[KubernetesRequestType]) (resp []choiceWeight[KubernetesRequestType]) {
|
||||
for _, choice := range choices {
|
||||
if choice.choice != KubernetesDelete {
|
||||
resp = append(resp, choice)
|
||||
|
@ -158,7 +158,7 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.4.5 // indirect
|
||||
github.com/prometheus/client_golang v1.17.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.4.0 // indirect
|
||||
@ -215,7 +215,7 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
@ -229,7 +229,7 @@ require (
|
||||
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/grpc v1.60.1 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect
|
||||
|
@ -532,8 +532,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM=
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
@ -718,8 +718,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1098,8 +1098,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
Reference in New Issue
Block a user