Compare commits
237 Commits
serathius-
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
![]() |
83bee0a8c7 | ||
![]() |
9c659eb4e0 | ||
![]() |
1420292b10 | ||
![]() |
1663600bec | ||
![]() |
09b9f889e7 | ||
![]() |
bb155a6629 | ||
![]() |
812fce2c7e | ||
![]() |
b7e7811ba4 | ||
![]() |
b92d099360 | ||
![]() |
5e7349b44c | ||
![]() |
43b2477c28 | ||
![]() |
f140cc14b3 | ||
![]() |
96987d8b5e | ||
![]() |
6f2a5b710f | ||
![]() |
57258759c6 | ||
![]() |
ea3255b477 | ||
![]() |
8de14bd36e | ||
![]() |
fb16bca44a | ||
![]() |
2791422f77 | ||
![]() |
8c483f31ad | ||
![]() |
90cbadc660 | ||
![]() |
32ea42b51c | ||
![]() |
cb3730a30f | ||
![]() |
34cbf4cd6f | ||
![]() |
84a9af17cc | ||
![]() |
7d27e33a12 | ||
![]() |
899a51e110 | ||
![]() |
6979318108 | ||
![]() |
974655e02c | ||
![]() |
da49157b20 | ||
![]() |
7bbc738ec4 | ||
![]() |
a081d52bd4 | ||
![]() |
a268a67e45 | ||
![]() |
455c0c6b81 | ||
![]() |
3a8c6d749f | ||
![]() |
06350aba43 | ||
![]() |
7444985cab | ||
![]() |
74bb688ece | ||
![]() |
cdff0b3a31 | ||
![]() |
09921806af | ||
![]() |
a6ab774458 | ||
![]() |
b366cda70f | ||
![]() |
c104a4d01b | ||
![]() |
20c4247d2c | ||
![]() |
03c9e71b49 | ||
![]() |
61736c329d | ||
![]() |
00b4156080 | ||
![]() |
693f25d6b9 | ||
![]() |
a6f51651ca | ||
![]() |
f410c6e6df | ||
![]() |
53af854871 | ||
![]() |
f91f6d8414 | ||
![]() |
eb56d86e40 | ||
![]() |
b80fb0a1ce | ||
![]() |
dffc35e421 | ||
![]() |
e6c8bf82e0 | ||
![]() |
a708bed336 | ||
![]() |
798d2b7923 | ||
![]() |
75229f7e39 | ||
![]() |
6c5fde5138 | ||
![]() |
b9e30bf878 | ||
![]() |
caee53237e | ||
![]() |
b2c39fc8e6 | ||
![]() |
dcc4c1efb0 | ||
![]() |
faf5945603 | ||
![]() |
3d40ee69bb | ||
![]() |
0f32b588be | ||
![]() |
dfbe2038f3 | ||
![]() |
d3e43d4de6 | ||
![]() |
fe24da8c67 | ||
![]() |
64b11ef8b0 | ||
![]() |
caf9a0dadd | ||
![]() |
cdbc2c1f5d | ||
![]() |
4a2fdb8ba8 | ||
![]() |
41b5e21748 | ||
![]() |
337164ba4a | ||
![]() |
8cb3fab8d9 | ||
![]() |
b46dc0a1e4 | ||
![]() |
3b7e1223ab | ||
![]() |
8da2a5bf46 | ||
![]() |
004195bb6e | ||
![]() |
a9864d4edb | ||
![]() |
53b23d32db | ||
![]() |
41446dbad9 | ||
![]() |
5773d94c22 | ||
![]() |
8f887d3a79 | ||
![]() |
0073fd4225 | ||
![]() |
ea47d5bec7 | ||
![]() |
b1df8c468f | ||
![]() |
98ebb67777 | ||
![]() |
59b8522687 | ||
![]() |
42e2c9d4c9 | ||
![]() |
bd5d0a5bbb | ||
![]() |
904e5072d6 | ||
![]() |
8b5ec05ede | ||
![]() |
ef9b6a6280 | ||
![]() |
7cc98e6392 | ||
![]() |
b0b922cd71 | ||
![]() |
bf903e5007 | ||
![]() |
3413f2e08d | ||
![]() |
16bf0f6641 | ||
![]() |
09b8673200 | ||
![]() |
08a4cd46fe | ||
![]() |
e11dee6498 | ||
![]() |
cdd9846b56 | ||
![]() |
82fc4258a7 | ||
![]() |
b365f3cda4 | ||
![]() |
ef91e8ae78 | ||
![]() |
4418e793a0 | ||
![]() |
9e1e378e9e | ||
![]() |
24b3ae9a17 | ||
![]() |
04346e870f | ||
![]() |
67c272e8ba | ||
![]() |
a4f8f56496 | ||
![]() |
2efecd1978 | ||
![]() |
4872b679a5 | ||
![]() |
b2ee9887d1 | ||
![]() |
a0063d76e7 | ||
![]() |
4153ecb93b | ||
![]() |
bdfa70d02b | ||
![]() |
8c715f8a40 | ||
![]() |
820bcddc6d | ||
![]() |
1eb1b6ca69 | ||
![]() |
fbc34d1222 | ||
![]() |
633e2dcc26 | ||
![]() |
befb283cca | ||
![]() |
51a26f8d58 | ||
![]() |
523a961453 | ||
![]() |
0c919dc212 | ||
![]() |
19ec574f45 | ||
![]() |
7e161d5664 | ||
![]() |
a708e94749 | ||
![]() |
75b09410e5 | ||
![]() |
f3c9db9c46 | ||
![]() |
efcbd95f71 | ||
![]() |
6429f47631 | ||
![]() |
112aad1ea7 | ||
![]() |
9b10f20004 | ||
![]() |
9683b7912a | ||
![]() |
5a5b5a1c5d | ||
![]() |
1798730cd8 | ||
![]() |
29f9d06527 | ||
![]() |
4675e5c6a3 | ||
![]() |
6e53792568 | ||
![]() |
0efa1c19ef | ||
![]() |
911c40a347 | ||
![]() |
05ed91d76d | ||
![]() |
2df32102ca | ||
![]() |
ca221208d2 | ||
![]() |
c338882d7a | ||
![]() |
14f21a124e | ||
![]() |
012b429f14 | ||
![]() |
ffbaac8305 | ||
![]() |
52dfd4bbed | ||
![]() |
2bf495d93b | ||
![]() |
c846b087db | ||
![]() |
2fd86a12a9 | ||
![]() |
941d760e42 | ||
![]() |
ffe41987f9 | ||
![]() |
09ae3a641c | ||
![]() |
2a0c989662 | ||
![]() |
3d9890ff0e | ||
![]() |
831ce4c3cf | ||
![]() |
d0ca536283 | ||
![]() |
67ec1a4d30 | ||
![]() |
fa7067d0d8 | ||
![]() |
e9900f6fff | ||
![]() |
db07ec9561 | ||
![]() |
9878b134eb | ||
![]() |
9a922091ed | ||
![]() |
962e15038e | ||
![]() |
d77c618e6a | ||
![]() |
05b663fbe8 | ||
![]() |
e3db9dc616 | ||
![]() |
165a76b506 | ||
![]() |
5d1130f8d8 | ||
![]() |
1c455d4993 | ||
![]() |
2bb9930ffa | ||
![]() |
dd248518d1 | ||
![]() |
3f5ad36039 | ||
![]() |
7f6d0d04ac | ||
![]() |
f31d0eafb9 | ||
![]() |
b404d25d84 | ||
![]() |
a7344da7d3 | ||
![]() |
d81d3c3487 | ||
![]() |
c863f1f8c0 | ||
![]() |
1e479f8c3c | ||
![]() |
aa373e54df | ||
![]() |
ad20230e07 | ||
![]() |
f6161673af | ||
![]() |
b7ad0382ad | ||
![]() |
3024d9461d | ||
![]() |
b14b468661 | ||
![]() |
a0cffb6a1f | ||
![]() |
0cd1b7beaa | ||
![]() |
0a7dd2186b | ||
![]() |
bb057ddae6 | ||
![]() |
767b59f0b0 | ||
![]() |
ac61b36e06 | ||
![]() |
7c68be4cf3 | ||
![]() |
249c0d71d4 | ||
![]() |
40f71ef3c6 | ||
![]() |
79eabc1cbf | ||
![]() |
92366a5338 | ||
![]() |
08d25b2e3e | ||
![]() |
8a17ed10bd | ||
![]() |
d10cabd3f9 | ||
![]() |
58ec96a6ce | ||
![]() |
b75499437b | ||
![]() |
e9b1a0e70f | ||
![]() |
cfe154209c | ||
![]() |
2c16812841 | ||
![]() |
9b5680c5f1 | ||
![]() |
ecb64030fb | ||
![]() |
b84e4273f7 | ||
![]() |
3ef5985bcd | ||
![]() |
c9998a7e63 | ||
![]() |
5021cd924c | ||
![]() |
bb060586ce | ||
![]() |
49b59cc8e5 | ||
![]() |
4785f5a7ba | ||
![]() |
b089474b01 | ||
![]() |
4c4bd63fa1 | ||
![]() |
0deaec0e4f | ||
![]() |
7462c61b31 | ||
![]() |
b9533ca98b | ||
![]() |
09d053e035 | ||
![]() |
46ab121cb7 | ||
![]() |
b052092297 | ||
![]() |
7450cd886d | ||
![]() |
cd24847086 | ||
![]() |
81fccc13da | ||
![]() |
c7d81acaf0 | ||
![]() |
6d11f8ceb5 | ||
![]() |
26fdf46001 | ||
![]() |
c9b368119e | ||
![]() |
975854f07f |
156
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
156
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,92 +1,102 @@
|
||||
---
|
||||
name: Bug Report
|
||||
description: Report a bug encountered while operating Etcd
|
||||
description: Report a bug encountered while operating etcd
|
||||
labels:
|
||||
- type/bug
|
||||
- type/bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/reporting_bugs.md
|
||||
If this matter is security related, please disclose it privately via security@etcd.io.
|
||||
Please fill the form below and provide as much information as possible.
|
||||
Not doing so may result in your bug not being addressed in a timely manner.
|
||||
- type: checkboxes
|
||||
id: confirmations
|
||||
attributes:
|
||||
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 security@etcd.io.
|
||||
- label: This is not a support request, support requests 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.
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What happened?
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill the form below and provide as much information as possible.
|
||||
Not doing so may result in your bug not being addressed in a timely manner.
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What happened?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: How can we reproduce it (as minimally and precisely as possible)?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Anything else we need to know?
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: How can we reproduce it (as minimally and precisely as possible)?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: etcdVersion
|
||||
attributes:
|
||||
label: Etcd version (please run commands below)
|
||||
value: |
|
||||
<details>
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Anything else we need to know?
|
||||
|
||||
```console
|
||||
$ etcd --version
|
||||
# paste output here
|
||||
- type: textarea
|
||||
id: etcdVersion
|
||||
attributes:
|
||||
label: Etcd version (please run commands below)
|
||||
value: |
|
||||
<details>
|
||||
|
||||
$ etcdctl version
|
||||
# paste output here
|
||||
```
|
||||
```console
|
||||
$ etcd --version
|
||||
# paste output here
|
||||
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
$ etcdctl version
|
||||
# paste output here
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Etcd configuration (command line flags or environment variables)
|
||||
value: |
|
||||
<details>
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
|
||||
# paste your configuration here
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Etcd configuration (command line flags or environment variables)
|
||||
value: |
|
||||
<details>
|
||||
|
||||
</details>
|
||||
# paste your configuration here
|
||||
|
||||
- type: textarea
|
||||
id: etcdDebugInformation
|
||||
attributes:
|
||||
label: Etcd debug information (please run commands below, feel free to obfuscate the IP address or FQDN in the output)
|
||||
value: |
|
||||
<details>
|
||||
</details>
|
||||
|
||||
```console
|
||||
$ etcdctl member list -w table
|
||||
# paste output here
|
||||
- type: textarea
|
||||
id: etcdDebugInformation
|
||||
attributes:
|
||||
label: Etcd debug information (please run commands below, feel free to obfuscate the IP address or FQDN in the output)
|
||||
value: |
|
||||
<details>
|
||||
|
||||
$ etcdctl --endpoints=<member list> endpoint status -w table
|
||||
# paste output here
|
||||
```
|
||||
```console
|
||||
$ etcdctl member list -w table
|
||||
# paste output here
|
||||
|
||||
</details>
|
||||
$ etcdctl --endpoints=<member list> endpoint status -w table
|
||||
# paste output here
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
</details>
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: Shell
|
||||
|
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,6 @@
|
||||
---
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Question
|
||||
url: https://github.com/etcd-io/etcd/discussions
|
||||
about: Question relating to Etcd
|
||||
- name: Question
|
||||
url: https://github.com/etcd-io/etcd/discussions
|
||||
about: Question relating to Etcd
|
||||
|
27
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
27
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,18 +1,19 @@
|
||||
---
|
||||
name: Feature request
|
||||
description: Provide idea for a new feature
|
||||
labels:
|
||||
- type/feature
|
||||
- type/feature
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: What would you like to be added?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: What would you like to be added?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: Why is this needed?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: Why is this needed?
|
||||
validations:
|
||||
required: true
|
||||
|
49
.github/ISSUE_TEMPLATE/membership-request.yml
vendored
49
.github/ISSUE_TEMPLATE/membership-request.yml
vendored
@@ -1,30 +1,31 @@
|
||||
---
|
||||
name: Membership nomination
|
||||
description: Nominate new etcd members
|
||||
labels:
|
||||
- area/community
|
||||
- area/community
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Who would you like to nominate?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- id: requirements
|
||||
type: checkboxes
|
||||
attributes:
|
||||
label: Requirements
|
||||
options:
|
||||
- label: I have reviewed the [community membership guidelines](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/community-membership.md)
|
||||
required: true
|
||||
- label: The members are actively contributing to 1 or more etcd subprojects
|
||||
required: true
|
||||
- label: The members are being sponsored by two current reviewers or a current maintainer.
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Who would you like to nominate?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: How do the new members meet the regular active contribution requirements?
|
||||
validations:
|
||||
required: true
|
||||
- id: requirements
|
||||
type: checkboxes
|
||||
attributes:
|
||||
label: Requirements
|
||||
options:
|
||||
- label: I have reviewed the [community membership guidelines](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/community-membership.md)
|
||||
required: true
|
||||
- label: The members are actively contributing to 1 or more etcd subprojects
|
||||
required: true
|
||||
- label: The members are being sponsored by two current reviewers or a current maintainer.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: How do the new members meet the regular active contribution requirements?
|
||||
validations:
|
||||
required: true
|
||||
|
51
.github/ISSUE_TEMPLATE/test-flake.yml
vendored
51
.github/ISSUE_TEMPLATE/test-flake.yml
vendored
@@ -1,33 +1,34 @@
|
||||
---
|
||||
name: Flaking Test
|
||||
description: Report flaky tests
|
||||
labels:
|
||||
- type/flake
|
||||
- type/flake
|
||||
body:
|
||||
- type: textarea
|
||||
id: workflows
|
||||
attributes:
|
||||
label: Which github workflows are flaking?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: workflows
|
||||
attributes:
|
||||
label: Which github workflows are flaking?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: tests
|
||||
attributes:
|
||||
label: Which tests are flaking?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: tests
|
||||
attributes:
|
||||
label: Which tests are flaking?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: link
|
||||
attributes:
|
||||
label: Github Action link
|
||||
- type: input
|
||||
id: link
|
||||
attributes:
|
||||
label: Github Action link
|
||||
|
||||
- type: textarea
|
||||
id: reason
|
||||
attributes:
|
||||
label: Reason for failure (if possible)
|
||||
- type: textarea
|
||||
id: reason
|
||||
attributes:
|
||||
label: Reason for failure (if possible)
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Anything else we need to know?
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Anything else we need to know?
|
||||
|
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
@@ -10,11 +11,11 @@ updates:
|
||||
schedule:
|
||||
interval: weekly
|
||||
allow:
|
||||
- dependency-type: all
|
||||
- dependency-type: all
|
||||
|
||||
- package-ecosystem: gomod
|
||||
directory: /tools/mod # Not linked from /go.mod
|
||||
schedule:
|
||||
interval: weekly
|
||||
allow:
|
||||
- dependency-type: all
|
||||
- dependency-type: all
|
||||
|
7
.github/stale.yml
vendored
7
.github/stale.yml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
@@ -27,11 +28,7 @@ exemptAssignees: false
|
||||
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.
|
||||
|
||||
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.
|
||||
|
12
.github/workflows/build.yaml
vendored
12
.github/workflows/build.yaml
vendored
@@ -1,13 +1,11 @@
|
||||
---
|
||||
name: Build
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -22,10 +20,12 @@ jobs:
|
||||
- linux-ppc64le
|
||||
- linux-s390x
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
|
60
.github/workflows/codeql-analysis.yml
vendored
60
.github/workflows/codeql-analysis.yml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
@@ -10,18 +11,15 @@
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, release-3.4, release-3.5, release-3.6 ]
|
||||
branches: [main, release-3.4, release-3.5, release-3.6]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '20 14 * * 5'
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
@@ -30,44 +28,28 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'go' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
language: ['go']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# 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.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# 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@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # v2.3.0
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
|
||||
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.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
languages: ${{ matrix.language }}
|
||||
# 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@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
|
||||
|
20
.github/workflows/contrib.yaml
vendored
20
.github/workflows/contrib.yaml
vendored
@@ -1,18 +1,18 @@
|
||||
---
|
||||
name: Test contrib/mixin
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
|
||||
make -C contrib/mixin tools test
|
||||
make -C contrib/mixin tools test
|
||||
|
42
.github/workflows/coverage.yaml
vendored
42
.github/workflows/coverage.yaml
vendored
@@ -1,32 +1,32 @@
|
||||
---
|
||||
name: Coverage
|
||||
on: [push]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- linux-amd64-coverage
|
||||
- linux-amd64-coverage
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.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
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
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
|
||||
|
55
.github/workflows/e2e-arm64.yaml
vendored
55
.github/workflows/e2e-arm64.yaml
vendored
@@ -1,40 +1,45 @@
|
||||
---
|
||||
name: E2E-arm64
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * *' # runs daily at 1am.
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
# this is to prevent the job to run at forked projects
|
||||
if: github.repository == 'etcd-io/etcd'
|
||||
runs-on: [Linux, ARM64]
|
||||
needs: goversion
|
||||
runs-on: [self-hosted, Linux, ARM64]
|
||||
container: golang:1.19-bullseye
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
target:
|
||||
- linux-arm64-e2e
|
||||
- linux-arm64-e2e
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
ref: main
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
# https://github.com/actions/checkout/issues/1169
|
||||
- run: git config --system --add safe.directory '*'
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
echo "${TARGET}"
|
||||
case "${TARGET}" in
|
||||
linux-arm64-e2e)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e-release
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "${TARGET}"
|
||||
case "${TARGET}" in
|
||||
linux-arm64-e2e)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e-release
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
54
.github/workflows/e2e.yaml
vendored
54
.github/workflows/e2e.yaml
vendored
@@ -1,39 +1,39 @@
|
||||
---
|
||||
name: E2E
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
target:
|
||||
- linux-amd64-e2e
|
||||
- linux-386-e2e
|
||||
- linux-amd64-e2e
|
||||
- linux-386-e2e
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
echo "${TARGET}"
|
||||
case "${TARGET}" in
|
||||
linux-amd64-e2e)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e-release
|
||||
;;
|
||||
linux-386-e2e)
|
||||
GOOS=linux GOARCH=386 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "${TARGET}"
|
||||
case "${TARGET}" in
|
||||
linux-amd64-e2e)
|
||||
VERBOSE=1 GOOS=linux GOARCH=amd64 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e-release
|
||||
;;
|
||||
linux-386-e2e)
|
||||
VERBOSE=1 GOOS=linux GOARCH=386 CPU=4 EXPECT_DEBUG=true RACE=true make test-e2e
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
28
.github/workflows/fuzzing.yaml
vendored
28
.github/workflows/fuzzing.yaml
vendored
@@ -1,26 +1,26 @@
|
||||
---
|
||||
name: Fuzzing v3rpc
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: false
|
||||
env:
|
||||
TARGET_PATH: ./server/etcdserver/api/v3rpc
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
|
||||
GOARCH=amd64 CPU=4 make fuzz
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: failure()
|
||||
with:
|
||||
path: "${{env.TARGET_PATH}}/testdata/fuzz/**/*"
|
||||
GOARCH=amd64 CPU=4 make fuzz
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: failure()
|
||||
with:
|
||||
path: "${{env.TARGET_PATH}}/testdata/fuzz/**/*"
|
||||
|
22
.github/workflows/go-version.yaml
vendored
22
.github/workflows/go-version.yaml
vendored
@@ -1,22 +0,0 @@
|
||||
name: Go version setup
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.19.8"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
goversion:
|
||||
value: ${{ jobs.version.outputs.goversion }}
|
||||
|
||||
jobs:
|
||||
version:
|
||||
name: Set Go version variable for all the workflows
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
goversion: ${{ steps.step1.outputs.goversion }}
|
||||
steps:
|
||||
- id: step1
|
||||
run: |
|
||||
echo "Go Version: $GO_VERSION"
|
||||
echo "goversion=$GO_VERSION" >> $GITHUB_OUTPUT
|
12
.github/workflows/govuln.yaml
vendored
12
.github/workflows/govuln.yaml
vendored
@@ -1,17 +1,17 @@
|
||||
---
|
||||
name: Go Vulnerability Checker
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- run: |
|
||||
set -euo pipefail
|
||||
|
53
.github/workflows/grpcproxy.yaml
vendored
53
.github/workflows/grpcproxy.yaml
vendored
@@ -1,39 +1,38 @@
|
||||
---
|
||||
name: grpcProxy-tests
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
target:
|
||||
- linux-amd64-grpcproxy-integration
|
||||
- linux-amd64-grpcproxy-e2e
|
||||
- linux-amd64-grpcproxy-integration
|
||||
- linux-amd64-grpcproxy-e2e
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
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 RACE=true make test-grpcproxy-integration
|
||||
;;
|
||||
linux-amd64-grpcproxy-e2e)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 RACE=true make test-grpcproxy-e2e
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "${TARGET}"
|
||||
case "${TARGET}" in
|
||||
linux-amd64-grpcproxy-integration)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 RACE=true make test-grpcproxy-integration
|
||||
;;
|
||||
linux-amd64-grpcproxy-e2e)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 RACE=true make test-grpcproxy-e2e
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
17
.github/workflows/measure-test-flakiness.yaml
vendored
17
.github/workflows/measure-test-flakiness.yaml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Measure Test Flakiness
|
||||
|
||||
on:
|
||||
@@ -11,12 +12,12 @@ jobs:
|
||||
name: Measure Test Flakiness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
./scripts/measure-test-flakiness.sh
|
||||
make bin/etcd-test-analyzer
|
||||
bin/etcd-test-analyzer run -token $GITHUB_TOKEN -max-age=168h -workflow Tests -branch main
|
||||
./scripts/measure-test-flakiness.sh
|
||||
make bin/etcd-test-analyzer
|
||||
bin/etcd-test-analyzer run -token $GITHUB_TOKEN -max-age=168h -workflow Tests -branch main
|
||||
|
52
.github/workflows/release.yaml
vendored
52
.github/workflows/release.yaml
vendored
@@ -1,34 +1,34 @@
|
||||
---
|
||||
name: Release
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- name: release
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
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 --in-place 3.6.99
|
||||
- name: test-image
|
||||
run: |
|
||||
VERSION=3.6.99 ./scripts/test_images.sh
|
||||
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 --in-place 3.6.99
|
||||
- name: test-image
|
||||
run: |
|
||||
VERSION=3.6.99 ./scripts/test_images.sh
|
||||
|
9
.github/workflows/robustness-nightly.yaml
vendored
9
.github/workflows/robustness-nightly.yaml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Robustness Nightly
|
||||
permissions: read-all
|
||||
on:
|
||||
@@ -14,6 +15,14 @@ jobs:
|
||||
count: 100
|
||||
testTimeout: 200m
|
||||
artifactName: main
|
||||
main-arm64:
|
||||
uses: ./.github/workflows/robustness-template-arm64.yaml
|
||||
with:
|
||||
etcdBranch: main
|
||||
count: 100
|
||||
testTimeout: 200m
|
||||
artifactName: main-arm64
|
||||
runs-on: "['self-hosted', 'Linux', 'ARM64']"
|
||||
release-35:
|
||||
uses: ./.github/workflows/robustness-template.yaml
|
||||
with:
|
||||
|
72
.github/workflows/robustness-template-arm64.yaml
vendored
Normal file
72
.github/workflows/robustness-template-arm64.yaml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
name: Reusable Robustness Workflow
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
etcdBranch:
|
||||
required: true
|
||||
type: string
|
||||
count:
|
||||
required: true
|
||||
type: number
|
||||
testTimeout:
|
||||
required: false
|
||||
type: string
|
||||
default: '30m'
|
||||
artifactName:
|
||||
required: true
|
||||
type: string
|
||||
runs-on:
|
||||
required: false
|
||||
type: string
|
||||
default: "['ubuntu-latest']"
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 210
|
||||
runs-on: ${{ fromJson(inputs.runs-on) }}
|
||||
container: golang:1.19-bullseye
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
# https://github.com/actions/checkout/issues/1169
|
||||
- run: git config --system --add safe.directory '*'
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- name: test-robustness
|
||||
env:
|
||||
ETCD_BRANCH: "${{ inputs.etcdBranch }}"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
# Use --failfast to avoid overriding report generated by failed test
|
||||
GO_TEST_FLAGS="-v --count ${{ inputs.count }} --timeout ${{ inputs.testTimeout }} --failfast --run TestRobustness"
|
||||
case "${ETCD_BRANCH}" in
|
||||
release-3.5)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.5
|
||||
;;
|
||||
release-3.4)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.4
|
||||
;;
|
||||
main)
|
||||
make gofail-enable
|
||||
make build
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target ${ETCD_BRANCH}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ inputs.artifactName }}
|
||||
path: /tmp/results/*
|
79
.github/workflows/robustness-template.yaml
vendored
79
.github/workflows/robustness-template.yaml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Reusable Robustness Workflow
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -15,46 +16,50 @@ on:
|
||||
artifactName:
|
||||
required: true
|
||||
type: string
|
||||
runs-on:
|
||||
required: false
|
||||
type: string
|
||||
default: "['ubuntu-latest']"
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
timeout-minutes: 210
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
runs-on: ${{ fromJson(inputs.runs-on) }}
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- name: test-robustness
|
||||
env:
|
||||
ETCD_BRANCH: "${{ inputs.etcdBranch }}"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- name: test-robustness
|
||||
env:
|
||||
ETCD_BRANCH: "${{ inputs.etcdBranch }}"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
# Use --failfast to avoid overriding report generated by failed test
|
||||
GO_TEST_FLAGS="-v --count ${{ inputs.count }} --timeout ${{ inputs.testTimeout }} --failfast --run TestRobustness"
|
||||
case "${ETCD_BRANCH}" in
|
||||
release-3.5)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.5
|
||||
;;
|
||||
release-3.4)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.4
|
||||
;;
|
||||
main)
|
||||
make gofail-enable
|
||||
make build
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target ${ETCD_BRANCH}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ inputs.artifactName }}
|
||||
path: /tmp/results/*
|
||||
# Use --failfast to avoid overriding report generated by failed test
|
||||
GO_TEST_FLAGS="-v --count ${{ inputs.count }} --timeout ${{ inputs.testTimeout }} --failfast --run TestRobustness"
|
||||
case "${ETCD_BRANCH}" in
|
||||
release-3.5)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.5
|
||||
;;
|
||||
release-3.4)
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness-release-3.4
|
||||
;;
|
||||
main)
|
||||
make gofail-enable
|
||||
make build
|
||||
EXPECT_DEBUG=true GO_TEST_FLAGS=${GO_TEST_FLAGS} RESULTS_DIR=/tmp/results make test-robustness
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target ${ETCD_BRANCH}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ inputs.artifactName }}
|
||||
path: /tmp/results/*
|
||||
|
1
.github/workflows/robustness.yaml
vendored
1
.github/workflows/robustness.yaml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Robustness
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
|
9
.github/workflows/scorecards.yml
vendored
9
.github/workflows/scorecards.yml
vendored
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Scorecards supply-chain security
|
||||
on:
|
||||
# Only the default branch is supported.
|
||||
@@ -5,7 +6,7 @@ on:
|
||||
schedule:
|
||||
- cron: '45 1 * * 0'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
branches: ["main"]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
@@ -22,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3.0.0
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # tag=v3.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -46,9 +47,9 @@ jobs:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@b2c19fb9a2a485599ccf4ed5d65527d94bc57226 # tag=v1.0.26
|
||||
uses: github/codeql-action/upload-sarif@83f0fe6c4988d98a455712a27f0255212bba9bd4 # tag=v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
17
.github/workflows/static-analysis.yaml
vendored
17
.github/workflows/static-analysis.yaml
vendored
@@ -1,23 +1,24 @@
|
||||
---
|
||||
name: Static Analysis
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 # v3.4.0
|
||||
uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # v3.6.0
|
||||
with:
|
||||
version: v1.49.0
|
||||
args: --config tools/.golangci.yaml
|
||||
- name: protoc
|
||||
uses: arduino/setup-protoc@64c0c85d18e984422218383b81c52f8b077404d3 # v1.1.2
|
||||
uses: arduino/setup-protoc@149f6c87b92550901b26acd1632e11c3662e381f # v1.3.0
|
||||
with:
|
||||
version: '3.14.0'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
90
.github/workflows/tests-arm64.yaml
vendored
90
.github/workflows/tests-arm64.yaml
vendored
@@ -1,56 +1,62 @@
|
||||
---
|
||||
name: Tests-arm64
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *' # runs daily at 1:30 am.
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
# this is to prevent the job to run at forked projects
|
||||
if: github.repository == 'etcd-io/etcd'
|
||||
runs-on: [Linux, ARM64]
|
||||
needs: goversion
|
||||
runs-on: [self-hosted, Linux, ARM64]
|
||||
container: golang:1.19-bullseye
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- linux-arm64-integration-1-cpu
|
||||
- linux-arm64-integration-2-cpu
|
||||
- linux-arm64-integration-4-cpu
|
||||
- linux-arm64-unit-4-cpu-race
|
||||
- linux-arm64-integration-1-cpu
|
||||
- linux-arm64-integration-2-cpu
|
||||
- linux-arm64-integration-4-cpu
|
||||
- linux-arm64-unit-4-cpu-race
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
ref: main
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
# https://github.com/actions/checkout/issues/1169
|
||||
- run: git config --system --add safe.directory '*'
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
mkdir "${TARGET}"
|
||||
export JUNIT_REPORT_DIR=$(realpath ${TARGET})
|
||||
case "${TARGET}" in
|
||||
linux-arm64-integration-1-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=1 make test-integration
|
||||
;;
|
||||
linux-arm64-integration-2-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=2 make test-integration
|
||||
;;
|
||||
linux-arm64-integration-4-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 make test-integration
|
||||
;;
|
||||
linux-arm64-unit-4-cpu-race)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 RACE=true GO_TEST_FLAGS='-p=2' make test-unit
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: always()
|
||||
with:
|
||||
path: ./**/junit_*.xml
|
||||
mkdir "${TARGET}"
|
||||
export JUNIT_REPORT_DIR=$(realpath ${TARGET})
|
||||
case "${TARGET}" in
|
||||
linux-arm64-integration-1-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=1 make test-integration
|
||||
;;
|
||||
linux-arm64-integration-2-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=2 make test-integration
|
||||
;;
|
||||
linux-arm64-integration-4-cpu)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 make test-integration
|
||||
;;
|
||||
linux-arm64-unit-4-cpu-race)
|
||||
GOOS=linux GOARCH=arm64 CPU=4 RACE=true GO_TEST_FLAGS='-p=2' make test-unit
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: always()
|
||||
with:
|
||||
path: ./**/junit_*.xml
|
||||
|
88
.github/workflows/tests.yaml
vendored
88
.github/workflows/tests.yaml
vendored
@@ -1,56 +1,56 @@
|
||||
---
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
permissions: read-all
|
||||
jobs:
|
||||
goversion:
|
||||
uses: ./.github/workflows/go-version.yaml
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goversion
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- linux-amd64-integration-1-cpu
|
||||
- linux-amd64-integration-2-cpu
|
||||
- linux-amd64-integration-4-cpu
|
||||
- linux-amd64-unit-4-cpu-race
|
||||
- linux-386-unit-1-cpu
|
||||
- linux-amd64-integration-1-cpu
|
||||
- linux-amd64-integration-2-cpu
|
||||
- linux-amd64-integration-4-cpu
|
||||
- linux-amd64-unit-4-cpu-race
|
||||
- linux-386-unit-1-cpu
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
|
||||
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
|
||||
with:
|
||||
go-version: ${{ needs.goversion.outputs.goversion }}
|
||||
- run: date
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- id: goversion
|
||||
run: echo "goversion=$(cat .go-version)" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
|
||||
with:
|
||||
go-version: ${{ steps.goversion.outputs.goversion }}
|
||||
- env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
go clean -testcache
|
||||
|
||||
mkdir "${TARGET}"
|
||||
export JUNIT_REPORT_DIR=$(realpath ${TARGET})
|
||||
case "${TARGET}" in
|
||||
linux-amd64-integration-1-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=1 make test-integration
|
||||
;;
|
||||
linux-amd64-integration-2-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=2 make test-integration
|
||||
;;
|
||||
linux-amd64-integration-4-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 make test-integration
|
||||
;;
|
||||
linux-amd64-unit-4-cpu-race)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 RACE=true GO_TEST_FLAGS='-p=2' make test-unit
|
||||
;;
|
||||
linux-386-unit-1-cpu)
|
||||
GOOS=linux GOARCH=386 CPU=1 GO_TEST_FLAGS='-p=4' make test-unit
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: always()
|
||||
with:
|
||||
path: ./**/junit_*.xml
|
||||
mkdir "${TARGET}"
|
||||
export JUNIT_REPORT_DIR=$(realpath ${TARGET})
|
||||
case "${TARGET}" in
|
||||
linux-amd64-integration-1-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=1 make test-integration
|
||||
;;
|
||||
linux-amd64-integration-2-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=2 make test-integration
|
||||
;;
|
||||
linux-amd64-integration-4-cpu)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 make test-integration
|
||||
;;
|
||||
linux-amd64-unit-4-cpu-race)
|
||||
GOOS=linux GOARCH=amd64 CPU=4 RACE=true GO_TEST_FLAGS='-p=2' make test-unit
|
||||
;;
|
||||
linux-386-unit-1-cpu)
|
||||
GOOS=linux GOARCH=386 CPU=1 GO_TEST_FLAGS='-p=4' make test-unit
|
||||
;;
|
||||
*)
|
||||
echo "Failed to find target"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
if: always()
|
||||
with:
|
||||
path: ./**/junit_*.xml
|
||||
|
1
.go-version
Normal file
1
.go-version
Normal file
@@ -0,0 +1 @@
|
||||
1.19.10
|
@@ -4,6 +4,22 @@ Previous change logs can be found at [CHANGELOG-3.3](https://github.com/etcd-io/
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.4.27 (tbd)
|
||||
|
||||
### etcd server
|
||||
- Fix [corruption check may get a `ErrCompacted` error when server has just been compacted](https://github.com/etcd-io/etcd/pull/16047)
|
||||
|
||||
## v3.4.26 (2023-05-12)
|
||||
|
||||
### etcd server
|
||||
- Fix [LeaseTimeToLive API may return keys to clients which have no read permission on the keys](https://github.com/etcd-io/etcd/pull/15814).
|
||||
|
||||
|
||||
### Dependencies
|
||||
- Compile binaries using [go 1.19.9](https://github.com/etcd-io/etcd/pull/15823)
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.4.25 (2023-04-14)
|
||||
|
||||
### etcd server
|
||||
|
@@ -4,6 +4,26 @@ Previous change logs can be found at [CHANGELOG-3.4](https://github.com/etcd-io/
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.5.10 (tbd)
|
||||
|
||||
### etcd server
|
||||
- Fix [corruption check may get a `ErrCompacted` error when server has just been compacted](https://github.com/etcd-io/etcd/pull/16048)
|
||||
|
||||
### etcd grpc-proxy
|
||||
- Fix [Memberlist results not updated when proxy node down](https://github.com/etcd-io/etcd/pull/15907).
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.5.9 (2023-05-11)
|
||||
|
||||
### etcd server
|
||||
- Fix [LeaseTimeToLive API may return keys to clients which have no read permission on the keys](https://github.com/etcd-io/etcd/pull/15815).
|
||||
|
||||
### Dependencies
|
||||
- Compile binaries using [go 1.19.9](https://github.com/etcd-io/etcd/pull/15822).
|
||||
|
||||
<hr>
|
||||
|
||||
## v3.5.8 (2023-04-13)
|
||||
|
||||
### etcd server
|
||||
|
@@ -112,8 +112,19 @@ depend on to make decisions in the best interest of the project in a consistent
|
||||
- Initiating, contributing and resolving discussions (emails, GitHub issues, meetings)
|
||||
- Identifying subtle or complex issues in designs and implementation PRs
|
||||
- Directly contributed to the project through implementation and / or review
|
||||
- Subscribed to [etcd-maintainers@googlegroups.com]
|
||||
- Elected by supermajority of active maintainers.
|
||||
- Sponsored by two active maintainers and elected by supermajority
|
||||
- Sponsors must be from multiple member companies to demonstrate integration across community.
|
||||
- To become a maintainer send an email with your candidacy to [etcd-maintainers-private@googlegroups.com]
|
||||
- Ensure your sponsors are @mentioned on the email
|
||||
- Include a list of contributions representative of your work on the project.
|
||||
- Existing maintainers vote will privately and respond to the email with either acceptance or with feedback for suggested improvement.
|
||||
- With your membership approved you are expected to:
|
||||
- Open a PR and add an entry to the [MAINTAINERS] file
|
||||
- Subscribe to [etcd-maintainers@googlegroups.com] and [etcd-maintainers-private@googlegroups.com]
|
||||
- Request to join to [etcd-maintainer teams of etcd organization of GitHub](https://github.com/orgs/etcd-io/teams/maintainers-etcd)
|
||||
- Request to join to the private slack channel for etcd maintainers on [kubernetes slack](http://slack.kubernetes.io/)
|
||||
- Request access to etcd-development GCP project where we publish releases
|
||||
- Request access to passwords shared between maintainers
|
||||
|
||||
### Responsibilities and privileges
|
||||
|
||||
|
@@ -8,6 +8,7 @@ Dependency management
|
||||
- [Steps to bump a dependency](#steps-to-bump-a-dependency)
|
||||
- [Indirect dependencies](#indirect-dependencies)
|
||||
- [About gRPC](#about-grpc)
|
||||
- [Rotation worksheet](#rotation-worksheet)
|
||||
- **[Stable branches](#stable-branches)**
|
||||
|
||||
# Main branch
|
||||
@@ -36,6 +37,7 @@ in the following order,
|
||||
- go.etcd.io/etcd/tests/v3
|
||||
- go.etcd.io/etcd/v3
|
||||
- go.etcd.io/etcd/tools/v3
|
||||
For more details about etcd Golang modules, please check https://etcd.io/docs/next/dev-internal/modules/
|
||||
|
||||
Note the module `go.etcd.io/etcd/tools/v3` doesn't depend on any other modules, nor by any other modules, so it doesn't matter when to bump dependencies for it.
|
||||
|
||||
@@ -43,7 +45,7 @@ Note the module `go.etcd.io/etcd/tools/v3` doesn't depend on any other modules,
|
||||
Use the `github.com/spf13/cobra` as an example, follow steps below to bump it from 1.6.1 to 1.7.0 for module `go.etcd.io/etcd/etcdctl/v3`,
|
||||
```
|
||||
$ cd ${ETCD_ROOT_DIR}/etcdctl
|
||||
$ go get github.com/spf13/cobra@1.7.0
|
||||
$ go get github.com/spf13/cobra@v1.7.0
|
||||
$ go mod tidy
|
||||
$ cd ..
|
||||
$ ./scripts/fix.sh
|
||||
@@ -75,12 +77,24 @@ For mixed cases, in which some modules directly while others indirectly depend o
|
||||
We should try to follow the first way, and temporarily fall back to the second one if we run into any issue on the first way. Eventually we
|
||||
should fix the issue and ensure all modules depend on the same version of the dependency.
|
||||
|
||||
## About gRPC
|
||||
## Known incompatible dependency updates
|
||||
|
||||
### arduino/setup-protoc
|
||||
Please refer to [build(deps): bump arduino/setup-protoc from 1.3.0 to 2.0.0](https://github.com/etcd-io/etcd/pull/16016)
|
||||
|
||||
### About gRPC
|
||||
There is a compatible issue between etcd and gRPC 1.52.0, and there is a pending PR [pull/15131](https://github.com/etcd-io/etcd/pull/15131).
|
||||
|
||||
The plan is to remove the dependency on some grpc-go's experimental API firstly, afterwards try to bump it again. Please get more details in
|
||||
[issues/15145](https://github.com/etcd-io/etcd/issues/15145).
|
||||
|
||||
`go.opentelemetry.io/otel` version update is indirectly blocked due to this gRPC issue. Please get more details in [pull/15810](https://github.com/etcd-io/etcd/pull/15810).
|
||||
|
||||
## Rotation worksheet
|
||||
The dependabot scheduling interval is weekly; it means dependabot will automatically raise a bunch of PRs per week.
|
||||
Usually human intervention is required each time. We have a [rotation worksheet](https://docs.google.com/spreadsheets/d/1DDWzbcOx1p32MhyelaPZ_SfYtAD6xRsrtGRZ9QXPOyQ/edit#gid=0),
|
||||
and everyone is welcome to participate; you just need to register your name in the worksheet.
|
||||
|
||||
# Stable branches
|
||||
Usually we don't proactively bump dependencies for stable releases unless there are any CVEs or bugs that affect etcd.
|
||||
|
||||
|
@@ -4,43 +4,177 @@
|
||||
|
||||
Speed up issue management.
|
||||
|
||||
The `etcd` issues are listed at https://github.com/etcd-io/etcd/issues
|
||||
and are identified with labels. For example, an issue that is identified
|
||||
as a bug will eventually be set to label `area/bug`. New issues will
|
||||
start out without any labels, but typically `etcd` maintainers and active contributors
|
||||
add labels based on their findings. The detailed list of labels can be found at
|
||||
https://github.com/kubernetes/kubernetes/labels
|
||||
The `etcd` issues are listed at <https://github.com/etcd-io/etcd/issues> and are identified with labels. For example, an issue that is identified as a bug will be set to label `type/bug`.
|
||||
|
||||
Following are few predetermined searches on issues for convenience:
|
||||
* [Bugs](https://github.com/etcd-io/etcd/labels/area%2Fbug)
|
||||
* [Help Wanted](https://github.com/etcd-io/etcd/labels/Help%20Wanted)
|
||||
* [Longest untriaged issues](https://github.com/etcd-io/etcd/issues?utf8=%E2%9C%93&q=is%3Aopen+sort%3Aupdated-asc+)
|
||||
The etcd project uses labels to indicate common attributes such as `area`, `type` and `priority` of incoming issues.
|
||||
|
||||
New issues will often start out without any labels, but typically `etcd` maintainers, reviewers and members will add labels by following these triage guidelines. The detailed list of labels can be found at <https://github.com/etcd-io/etcd/labels>.
|
||||
|
||||
## Scope
|
||||
|
||||
These guidelines serves as a primary document for triaging an incoming issues in
|
||||
`etcd`. Everyone is welcome to help manage issues and PRs but the work and responsibilities discussed in this document are created with `etcd` maintainers and active contributors in mind.
|
||||
This document serves as the primary guidelines for triaging incoming issues in `etcd`.
|
||||
|
||||
## Validate if an issue is a bug
|
||||
All contributors are encouraged and welcome to help manage issues which will help reduce burden on project maintainers, though the work and responsibilities discussed in this document are created with `etcd` project reviewers and members in mind as these individuals will have triage access to the etcd project which is a requirement for actions like applying labels or closing issues.
|
||||
|
||||
Validate if the issue is indeed a bug. If not, add a comment with findings and close trivial issue. For non-trivial issue, wait to hear back from issue reporter and see if there is any objection. If issue reporter does not reply in 30 days, close the issue. If the problem can not be reproduced or require more information, leave a comment for the issue reporter.
|
||||
Refer to [etcd community membership](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/community-membership.md) for guidance on becoming and etcd project member or reviewer.
|
||||
|
||||
## Inactive issues
|
||||
## Step 1 - Find an issue to triage
|
||||
|
||||
Issues that lack enough information from the issue reporter should be closed if issue reporter do not provide information in 60 days.
|
||||
To get started you can use the following recommended issue searches to identify issues that are in need of triage:
|
||||
|
||||
## Duplicate issues
|
||||
* [Issues that have no labels](https://github.com/etcd-io/etcd/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated+no%3Alabel)
|
||||
* [Issues created recently](https://github.com/etcd-io/etcd/issues?q=is%3Aissue+is%3Aopen+)
|
||||
* [Issues not assigned but linked pr](https://github.com/etcd-io/etcd/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee+linked%3Apr)
|
||||
* [Issues with no comments](https://github.com/etcd-io/etcd/issues?q=is%3Aopen+is%3Aissue+comments%3A0+)
|
||||
* [Issues with help wanted](https://github.com/etcd-io/etcd/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+)
|
||||
|
||||
If an issue is a duplicate, add a comment stating so along with a reference for the original issue and close it.
|
||||
## Step 2 - Check the issue is valid
|
||||
|
||||
## Issues that don't belong to etcd
|
||||
Before we start adding labels or trying to work out a priority, our first triage step needs to be working out if the issue actually belongs to the etcd project and is not a duplicate.
|
||||
|
||||
Sometime issues are reported that actually belongs to other projects that `etcd` use. For example, `grpc` or `golang` issues. Such issues should be addressed by asking reporter to open issues in appropriate other project. Close the issue unless a maintainer and issue reporter see a need to keep it open for tracking purpose.
|
||||
### Issues that don't belong to etcd
|
||||
|
||||
## Verify important labels are in place
|
||||
Sometime issues are reported that actually belongs to other projects that `etcd` use. For example, `grpc` or `golang` issues. Such issues should be addressed by asking reporter to open issues in appropriate other project.
|
||||
|
||||
Make sure that issue has label on areas it belongs to, proper assignees are added and milestone is identified. If any of these labels are missing, add one. If labels can not be assigned due to limited privilege or correct label can not be decided, that’s fine, contact maintainers if needed.
|
||||
These issues can generally be closed unless a maintainer and issue reporter see a need to keep it open for tracking purpose. If you have triage permissions please close it, alternatively mention the @etcd-io/members group to request a member with triage access close the issue.
|
||||
|
||||
## Poke issue owner if needed
|
||||
### Duplicate issues
|
||||
|
||||
If an issue owned by a developer has no PR created in 30 days, contact the issue owner and ask for a PR or to release ownership if needed.
|
||||
If an issue is a duplicate, add a comment stating so along with a reference for the original issue and if you have triage permissions please close it, alternatively mention the @etcd-io/members group to request a member with triage access close the issue.
|
||||
|
||||
## Step 3 - Apply the appropriate type label
|
||||
|
||||
Adding a `type` label to an issue helps create visibility on the health of the project and helps contributors identify potential priorities, i.e. addressing existing bugs or test flakes before implementing new features.
|
||||
|
||||
### Support requests
|
||||
|
||||
As a general rule the focus for etcd support is to address common themes in a broad way that helps all users, i.e. through channels like known issues, frequently asked questions and high quality documentation. To make the best use of project members time we should avoid providing 1:1 support if a broad approach is available.
|
||||
|
||||
Some people mistakenly use our GitHub bug report or feature request templates to file support requests. Usually they are asking for help operating or configuring some aspect of etcd. Support requests for etcd should instead be raised as [discussions](https://github.com/etcd-io/etcd/discussions).
|
||||
|
||||
Common types of support requests are:
|
||||
|
||||
1. Questions about configuring or operating existing well documented etcd features, for example <https://github.com/etcd-io/etcd/issues/15945>. Note - If an existing feature is not well documented please apply the `area/documentation` label and propose documentation improvements that would prevent future users from stumbling on the problem again.
|
||||
|
||||
2. Bug reports or questions about unspported versions of etcd, for example <https://github.com/etcd-io/etcd/issues/15796>. When responding to these issues please refer to our [supported versions documentation](https://etcd.io/docs/latest/op-guide/versioning) and encourage the reporter to upgrade to a recent patch release of a supported version as soon as possible. We should limit the effort supporting users that do not make the effort to run a supported version of etcd or ensure their version is patched.
|
||||
|
||||
3. Bug reports that do not provide a complete list of steps to reproduce issue and/or contributors are not able to reproduce the issue, for example <https://github.com/etcd-io/etcd/issues/15740>. We should limit the effort we put into reproducing issues ourselves and motivate users to provide necessary information to accept the bug report.
|
||||
|
||||
4. General questions that are filed using feature request or bug report issue templates, for example <https://github.com/etcd-io/etcd/issues/15914>. Note - These types of requests may surface good additions to our [frequently asked questions](https://etcd.io/docs/v3.5/faq).
|
||||
|
||||
If you identify that an issue is a support request please:
|
||||
|
||||
1. Add the `type/support` or `type/question` label.
|
||||
|
||||
2. Add the following comment to inform the issue creator that discussions should be used instead and that this issue will be converted to a discussion.
|
||||
|
||||
> Thank you for your question, this support issue will be moved to our [Discussion Forums](https://github.com/etcd-io/etcd/discussions).
|
||||
>
|
||||
> We are trying to consolidate the channels to which questions for help/support are posted so that we can improve our efficiency in responding to your requests, and to make it easier for you to find answers to frequently asked questions and how to address common use cases.
|
||||
>
|
||||
> We regularly see messages posted in multiple forums, with the full response thread only in one place or, worse, spread across multiple forums. Also, the large volume of support issues on GitHub is making it difficult for us to use issues to identify real bugs.
|
||||
>
|
||||
> Members of the etcd community use Discussion Forums to field support requests. Before posting a new question, please search these for answers to similar questions, and also familiarize yourself with:
|
||||
>
|
||||
> 1. [user documentation](https://etcd.io/docs/latest)
|
||||
> 2. [frequently asked questions](https://etcd.io/docs/v3.5/faq)
|
||||
>
|
||||
> Again, thanks for using etcd and raising this question.
|
||||
>
|
||||
> The etcd team
|
||||
|
||||
3. Finally, click `Convert to discussion` on the right hand panel, selecting the appropriate discussion category.
|
||||
|
||||
### Bug reports
|
||||
|
||||
If an issue has been raised as a bug it should already have the `type/bug` label, however if this is missing for an issue you determine to be a bug please add the label manually.
|
||||
|
||||
The next step is to validate if the issue is indeed a bug. If not, add a comment with findings and close trivial issue. For non-trivial issue, wait to hear back from issue reporter and see if there is any objection. If issue reporter does not reply in 30 days, close the issue.
|
||||
|
||||
If the problem can not be reproduced or requires more information, leave a comment for the issue reporter as soon as possible while the issue will be fresh for the issue reporter.
|
||||
|
||||
### Feature requests
|
||||
|
||||
New feature requests should be created via the etcd feature request template and in theory already have the `type/feature` label, however if this is missing for an issue you determine to be a feature please add the label manually.
|
||||
|
||||
### Test flakes
|
||||
|
||||
Test flakes are a specific type of bug that the etcd project tracks seperately as these are a priority to address. These should be created via the test flake template and in theory already have the `type/flake` label, however if this is missing for an issue you determine to be related to a flaking test please add the label manually.
|
||||
|
||||
## Step 4 - Define the areas impacted
|
||||
|
||||
Adding an `area` label to an issue helps create visibility on which areas of the etcd project require attention and helps contributors find issues to work on relating to their particular skills or knowledge of the etcd codebase.
|
||||
|
||||
If an issue crosses multiple domains please add additional `area` labels to reflect that.
|
||||
|
||||
Below is a brief summary of the area labels in active use by the etcd project along with any notes on their use:
|
||||
|
||||
| Label | Notes |
|
||||
| --- | --- |
|
||||
| area/external | Tracking label for issues raised that are external to etcd. |
|
||||
| area/community | |
|
||||
| area/raft | |
|
||||
| area/clientv3 | |
|
||||
| area/performance | |
|
||||
| area/security | |
|
||||
| area/tls | |
|
||||
| area/auth | |
|
||||
| area/etcdctl | |
|
||||
| area/etcdutl | |
|
||||
| area/contrib | Not to be confused with `area/community` this label is specifically used for issues relating to community maintained scripts or files in the `contrib/` directory which aren't part of the core etcd project. |
|
||||
| area/documentation | |
|
||||
| area/tooling | Generally used in relation to the third party / external utilities or tools that are used in various stages of the etcd build, test or release process, for example tooling to create sboms. |
|
||||
| area/testing | |
|
||||
| area/robustness-testing | |
|
||||
|
||||
## Step 5 - Prioritise the issue
|
||||
|
||||
Placeholder.
|
||||
|
||||
## Step 6 - Support new contributors
|
||||
|
||||
As part of the `etcd` triage process once the `kind` and `area` have been determined, please consider if the issue would be suitable for a less experienced contributor. The `good first issue` label is a subset of the `help wanted` label, indicating that members have committed to providing extra assistance for new contributors. All `good first issue` items also have the `help wanted` label.
|
||||
|
||||
### Help wanted
|
||||
|
||||
Items marked with the `help wanted` label need to ensure that they meet these criteria:
|
||||
|
||||
* **Low Barrier to Entry** - It should be easy for new contributors.
|
||||
|
||||
* **Clear** - The task is agreed upon and does not require further discussions in the community.
|
||||
|
||||
* **Goldilocks priority** - The priority should not be so high that a core contributor should do it, but not too low that it isn’t useful enough for a core contributor to spend time reviewing it, answering questions, helping get it into a release, etc.
|
||||
|
||||
### Good first issue
|
||||
|
||||
Items marked with `good first issue` are intended for first-time contributors. It indicates that members will keep an eye out for these pull requests and shepherd it through our processes.
|
||||
|
||||
New contributors should not be left to find an approver, ping for reviews, decipher test commands, or identify that their build failed due to a flake. It is important to make new contributors feel welcome and valued. We should assure them that they will have an extra level of help with their first contribution.
|
||||
|
||||
After a contributor has successfully completed one or two `good first issue` items, they should be ready to move on to `help wanted` items.
|
||||
|
||||
* **No Barrier to Entry** - The task is something that a new contributor can tackle without advanced setup or domain knowledge.
|
||||
|
||||
* **Solution Explained** - The recommended solution is clearly described in the issue.
|
||||
|
||||
* **Gives Examples** - Link to examples of similar implementations so new contributors have a reference guide for their changes.
|
||||
|
||||
* **Identifies Relevant Code** - The relevant code and tests to be changed should be linked in the issue.
|
||||
|
||||
* **Ready to Test** - There should be existing tests that can be modified, or existing test cases fit to be copied. If the area of code doesn’t have tests, before labeling the issue, add a test fixture. This prep often makes a great help wanted task!
|
||||
|
||||
## Step 7 - Follow up
|
||||
|
||||
Once initial triage has been completed, issues need to be re-evaluated over time to ensure they don't become stale incorrectly.
|
||||
|
||||
### Track important issues
|
||||
|
||||
If an issue is at risk of being closed by stale bot in future, but is an important issuefor the etcd project, then please apply the `stage/tracked` label and remove any `stale` labels that exist. This will ensure the project does not lose sight of the issue.
|
||||
|
||||
### Close incomplete issues
|
||||
|
||||
Issues that lack enough information from the issue reporter should be closed if issue reporter do not provide information in 30 days. Issues can always be re-opened at a later date if new information is provided.
|
||||
|
||||
### Check for incomplete work
|
||||
|
||||
If an issue owned by a developer has no pull request created in 30 days, contact the issue owner and kindly ask about the status of their work, or to release ownership on the issue if needed.
|
||||
|
68
Documentation/infra-guide/arm64-infra.md
Normal file
68
Documentation/infra-guide/arm64-infra.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# etcd arm64 test infrastructure
|
||||
|
||||
## Infrastructure summary
|
||||
|
||||
All etcd project pipelines run via github actions. The etcd project currently maintains dedicated infrastructure for running `arm64` continuous integration testing. This is required because currently github actions runner virtual machines are only offered as `x64`.
|
||||
|
||||
The infrastructure consists of two `c3.large.arm` bare metal servers kindly provided by [Equinix Metal](https://www.equinix.com/) via the [CNCF Community Infrastructure Lab].
|
||||
|
||||
| Hostname | IP | Operating System | Region |
|
||||
|-------------------------------|----------------|--------------------|---------------|
|
||||
| etcd-c3-large-arm64-runner-01 | 86.109.7.233 | Ubuntu 22.04.1 LTS | Washington DC |
|
||||
| etcd-c3-large-arm64-runner-02 | 147.28.151.226 | Ubuntu 22.04.1 LTS | Washington DC |
|
||||
|
||||
## Infrastructure support
|
||||
|
||||
The etcd project aims to self manage and resolve issues with project infrastructure internally where possible, however if situations emerge where we need to engage support from Equinix Metal we can open an issue under the [CNCF Community Infrastructure Lab] project or contact the [Equinix Metal support team](https://deploy.equinix.com/support). If the situation is urgent contact @vielmetti directly who can provide further assistance or escalation points.
|
||||
|
||||
## Granting infrastructure access
|
||||
|
||||
Etcd arm64 test infrastructure access is closely controlled to ensure the infrastructure is secure and protect the integrity of the etcd project.
|
||||
|
||||
Access to the infrastructure is defined by the infra admins table below:
|
||||
|
||||
| Name | Github | K8s Slack | Email |
|
||||
|---------------------------|----------------|--------------------|--------------------|
|
||||
| Marek Siarkowicz | @serathius | @ Serathius | Ref MAINTAINERS.md |
|
||||
| Benjamin Wang | @ahrtr | @ Benjamin Wang | Ref MAINTAINERS.md |
|
||||
| Davanum Srinivas | @dimns | @ Dims | davanum@gmail.com |
|
||||
| Chao Chen | @chaochn47 | @ Chao Chen | chaochn@amazon.com |
|
||||
| James Blair | @jmhbnz | @ James Blair | etcd@jamma.life |
|
||||
|
||||
Individuals in this table are granted access to the infrastructure in two ways:
|
||||
|
||||
### 1. Equinix metal web console access
|
||||
|
||||
An etcd project exists under the CNCF organisation in the Equinix Metal web console. The direct url to the etcd console is <https://console.equinix.com/projects/1b8c1eb7-983c-4b40-97e0-e317406e232e>.
|
||||
|
||||
When a new person is added to the infra admins table, an existing member or etcd maintainer should raise an issue in the [CNCF Community Infrastructure Labs](https://github.com/cncf/cluster/issues) to ensure they are granted web console access.
|
||||
|
||||
### 2. Server ssh access
|
||||
|
||||
Infra admins can ssh directly to the servers with a dedicated user account for each person, usernames are based on github handles for easy recognition in logs. These infra admins will be able to elevate to the `root` user when necessary via `sudo`.
|
||||
|
||||
Access to machines via ssh is strictly via individual ssh key based authentication, and is not permitted directly to the `root` user. Password authentication is never to be used for etcd infrastructure ssh authentication.
|
||||
|
||||
When a new member is added to the infra admins table, and existing member with ssh access should complete the following actions on all etcd servers:
|
||||
|
||||
- create the new user via `sudo adduser <username>`.
|
||||
- add their public key to `/home/<username>/.ssh/authorized_keys` file. Note: Public keys are to be retrieved via github only, example: <https://github.com/jmhbnz.keys>.
|
||||
- add the new user to machine sudoers file via `usermod -aG sudo <username>`.
|
||||
|
||||
## Revoking infrastructure access
|
||||
|
||||
When a member is removed from the infra admins table existing members must review servers and ensure their user access to etcd infrastructure is revoked by removing the members `/home/<username>/.ssh/authorized_keys` entries.
|
||||
|
||||
Note: When revoking access do not delete a user or their home directory from servers, as access may need to be reinstated in future.
|
||||
|
||||
### Regular access review
|
||||
|
||||
On a regular at least quarterly basis members of the infra admins team are responsible for verifying that no unneccessary infrastructure access exists by reviewing membership of the table above and existing server access.
|
||||
|
||||
## Provisioning new machines
|
||||
|
||||
If the etcd project needs new `arm64` infrastructure we can open an issue with the [CNCF Community Infrastructure Lab]. An example etcd request is [here](https://github.com/cncf/cluster/issues/227).
|
||||
|
||||
Note: `arm64` compute capacity is not currently available in all regions, this can be checked with [metal-cli](https://github.com/equinix/metal-cli) `metal capacity get | grep arm`.
|
||||
|
||||
[CNCF Community Infrastructure Lab]: https://github.com/cncf/cluster/issues
|
@@ -1,6 +1,6 @@
|
||||
# The official list of maintainers and reviewers for the project maintenance.
|
||||
#
|
||||
# Refer to the GOVERNANCE.md for description of the roles.
|
||||
# Refer to the https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/community-membership.md for description of the roles.
|
||||
#
|
||||
# Names should be added to this file like so:
|
||||
# Individual's name <submission email address> (@GITHUB_HANDLE) pkg:*
|
||||
@@ -11,8 +11,8 @@
|
||||
# MAINTAINERS
|
||||
Benjamin Wang <wachao@vmware.com> (ahrtr@) pkg:*
|
||||
Hitoshi Mitake <h.mitake@gmail.com> (@mitake) pkg:*
|
||||
Marek Siarkowicz <marek.siarkowicz@gmail.com> (@serathius) pkg:*
|
||||
Piotr Tabor <ptab@google.com> (@ptabor) pkg:*
|
||||
Marek Siarkowicz <siarkowicz@google.com> <marek.siarkowicz@gmail.com> (@serathius) pkg:*
|
||||
Piotr Tabor <piotr.tabor@gmail.com> (@ptabor) pkg:*
|
||||
Sahdev Zala <spzala@us.ibm.com> (@spzala) pkg:*
|
||||
|
||||
# REVIEWERS
|
||||
|
29
Makefile
29
Makefile
@@ -64,8 +64,8 @@ fuzz:
|
||||
|
||||
verify: verify-gofmt verify-bom verify-lint verify-dep verify-shellcheck verify-goword \
|
||||
verify-govet verify-license-header verify-receiver-name verify-mod-tidy verify-shellcheck \
|
||||
verify-shellws verify-proto-annotations verify-genproto verify-goimport
|
||||
fix: fix-bom fix-lint
|
||||
verify-shellws verify-proto-annotations verify-genproto verify-goimport verify-yamllint
|
||||
fix: fix-goimports fix-bom fix-lint fix-yamllint
|
||||
./scripts/fix.sh
|
||||
|
||||
.PHONY: verify-gofmt
|
||||
@@ -76,7 +76,7 @@ verify-gofmt:
|
||||
verify-bom:
|
||||
PASSES="bom" ./scripts/test.sh
|
||||
|
||||
.PHONY: update-bom
|
||||
.PHONY: fix-bom
|
||||
fix-bom:
|
||||
./scripts/updatebom.sh
|
||||
|
||||
@@ -86,11 +86,11 @@ verify-dep:
|
||||
|
||||
.PHONY: verify-lint
|
||||
verify-lint:
|
||||
golangci-lint run
|
||||
golangci-lint run --config tools/.golangci.yaml
|
||||
|
||||
.PHONY: update-lint
|
||||
.PHONY: fix-lint
|
||||
fix-lint:
|
||||
golangci-lint run --fix
|
||||
golangci-lint run --config tools/.golangci.yaml --fix
|
||||
|
||||
.PHONY: verify-shellcheck
|
||||
verify-shellcheck:
|
||||
@@ -132,6 +132,23 @@ verify-genproto:
|
||||
verify-goimport:
|
||||
PASSES="goimport" ./scripts/test.sh
|
||||
|
||||
.PHONY: fix-goimports
|
||||
fix-goimports:
|
||||
./scripts/fix-goimports.sh
|
||||
|
||||
.PHONY: verify-yamllint
|
||||
verify-yamllint:
|
||||
yamllint --config-file tools/.yamllint .
|
||||
|
||||
YAMLFMT_VERSION = $(shell cd tools/mod && go list -m -f '{{.Version}}' github.com/google/yamlfmt)
|
||||
|
||||
.PHONY: fix-yamllint
|
||||
fix-yamllint:
|
||||
ifeq (, $(shell which yamlfmt))
|
||||
$(shell go install github.com/google/yamlfmt/cmd/yamlfmt@$(YAMLFMT_VERSION))
|
||||
endif
|
||||
yamlfmt -conf tools/.yamlfmt .
|
||||
|
||||
# Cleanup
|
||||
|
||||
clean:
|
||||
|
19
Procfile
19
Procfile
@@ -6,4 +6,21 @@ etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --adve
|
||||
etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
|
||||
#proxy: bin/etcd grpc-proxy start --endpoints=127.0.0.1:2379,127.0.0.1:22379,127.0.0.1:32379 --listen-addr=127.0.0.1:23790 --advertise-client-url=127.0.0.1:23790 --enable-pprof
|
||||
|
||||
# A learner node can be started using Procfile.learner
|
||||
# A learner node can be started using the below Procfile.learner (uncomment and run)
|
||||
|
||||
# Use goreman to run `go install github.com/mattn/goreman@latest`
|
||||
|
||||
# 1. Start the cluster using Procfile
|
||||
# 2. Add learner node to the cluster
|
||||
# % etcdctl member add infra4 --peer-urls="http://127.0.0.1:42380" --learner=true
|
||||
|
||||
# 3. Start learner node with goreman
|
||||
# Change the path of bin/etcd if etcd is located elsewhere
|
||||
|
||||
# uncomment below to setup
|
||||
|
||||
# etcd4: bin/etcd --name infra4 --listen-client-urls http://127.0.0.1:42379 --advertise-client-urls http://127.0.0.1:42379 --listen-peer-urls http://127.0.0.1:42380 --initial-advertise-peer-urls http://127.0.0.1:42380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra4=http://127.0.0.1:42380,infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state existing --enable-pprof --logger=zap --log-outputs=stderr
|
||||
|
||||
# 4. The learner node can be promoted to voting member by the command
|
||||
# % etcdctl member promote <memberid>
|
||||
|
||||
|
@@ -1,12 +0,0 @@
|
||||
# Use goreman to run `go install github.com/mattn/goreman@latest`
|
||||
|
||||
# 1. Start the cluster using Procfile
|
||||
# 2. Add learner node to the cluster
|
||||
# % etcdctl member add infra4 --peer-urls="http://127.0.0.1:42380" --learner=true
|
||||
|
||||
# 3. Start learner node with goreman
|
||||
# Change the path of bin/etcd if etcd is located elsewhere
|
||||
etcd4: bin/etcd --name infra4 --listen-client-urls http://127.0.0.1:42379 --advertise-client-urls http://127.0.0.1:42379 --listen-peer-urls http://127.0.0.1:42380 --initial-advertise-peer-urls http://127.0.0.1:42380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra4=http://127.0.0.1:42380,infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state existing --enable-pprof --logger=zap --log-outputs=stderr
|
||||
|
||||
# 4. The learner node can be promoted to voting member by the command
|
||||
# % etcdctl member promote <memberid>
|
@@ -1,7 +0,0 @@
|
||||
# Use goreman to run `go install github.com/mattn/goreman@latest`
|
||||
# Change the path of bin/etcd if etcd is located elsewhere
|
||||
etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
# in future, use proxy to listen on 2379
|
||||
#proxy: bin/etcd --name infra-proxy1 --proxy=on --listen-client-urls http://127.0.0.1:2378 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --enable-pprof
|
32
README.md
32
README.md
@@ -51,7 +51,6 @@ The easiest way to get etcd is to use one of the pre-built release binaries whic
|
||||
For more installation guides, please check out [play.etcd.io](http://play.etcd.io) and [operating etcd](https://etcd.io/docs/latest/op-guide).
|
||||
|
||||
[github-release]: https://github.com/etcd-io/etcd/releases
|
||||
[branch-management]: https://etcd.io/docs/latest/branch_management
|
||||
|
||||
### Running etcd
|
||||
|
||||
@@ -74,15 +73,15 @@ This will bring up etcd listening on port 2379 for client communication and on p
|
||||
|
||||
Next, let's set a single key, and then retrieve it:
|
||||
|
||||
```
|
||||
```bash
|
||||
etcdctl put mykey "this is awesome"
|
||||
etcdctl get mykey
|
||||
```
|
||||
|
||||
etcd is now running and serving client requests. For more, please check out:
|
||||
|
||||
- [Interactive etcd playground](http://play.etcd.io)
|
||||
- [Animated quick demo](https://etcd.io/docs/latest/demo)
|
||||
* [Interactive etcd playground](http://play.etcd.io)
|
||||
* [Animated quick demo](https://etcd.io/docs/latest/demo)
|
||||
|
||||
### etcd TCP ports
|
||||
|
||||
@@ -120,13 +119,14 @@ go get go.etcd.io/etcd/client/v3
|
||||
|
||||
Now it's time to dig into the full etcd API and other guides.
|
||||
|
||||
- Read the full [documentation][].
|
||||
- Explore the full gRPC [API][].
|
||||
- Set up a [multi-machine cluster][clustering].
|
||||
- Learn the [config format, env variables and flags][configuration].
|
||||
- Find [language bindings and tools][integrations].
|
||||
- Use TLS to [secure an etcd cluster][security].
|
||||
- [Tune etcd][tuning].
|
||||
* Read the full [documentation].
|
||||
* Review etcd [frequently asked questions].
|
||||
* Explore the full gRPC [API].
|
||||
* Set up a [multi-machine cluster][clustering].
|
||||
* Learn the [config format, env variables and flags][configuration].
|
||||
* Find [language bindings and tools][integrations].
|
||||
* Use TLS to [secure an etcd cluster][security].
|
||||
* [Tune etcd][tuning].
|
||||
|
||||
[documentation]: https://etcd.io/docs/latest
|
||||
[api]: https://etcd.io/docs/latest/learning/api
|
||||
@@ -138,9 +138,9 @@ Now it's time to dig into the full etcd API and other guides.
|
||||
|
||||
## Contact
|
||||
|
||||
- Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
|
||||
- Slack: [#etcd](https://kubernetes.slack.com/messages/C3HD8ARJ5/details/) channel on Kubernetes ([get an invite](http://slack.kubernetes.io/))
|
||||
- [Community meetings](#Community-meetings)
|
||||
* Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
|
||||
* Slack: [#etcd](https://kubernetes.slack.com/messages/C3HD8ARJ5/details/) channel on Kubernetes ([get an invite](http://slack.kubernetes.io/))
|
||||
* [Community meetings](#community-meetings)
|
||||
|
||||
### Community meetings
|
||||
|
||||
@@ -167,7 +167,9 @@ Please refer to [community-membership.md](Documentation/contributor-guide/commun
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
See [reporting bugs](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/reporting_bugs.md) for details about reporting any issues.
|
||||
See [reporting bugs](https://github.com/etcd-io/etcd/blob/main/Documentation/contributor-guide/reporting_bugs.md) for details about reporting any issues. Before opening an issue please check it is not covered in our [frequently asked questions].
|
||||
|
||||
[frequently asked questions]: https://etcd.io/docs/latest/faq
|
||||
|
||||
## Reporting a security vulnerability
|
||||
|
||||
|
@@ -7,7 +7,7 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1
|
||||
google.golang.org/grpc v1.51.0
|
||||
)
|
||||
@@ -15,9 +15,9 @@ require (
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
21
api/go.sum
21
api/go.sum
@@ -58,13 +58,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
@@ -88,8 +84,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -106,14 +102,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -162,7 +158,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@@ -12,7 +12,7 @@ require (
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.8.2 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
@@ -1,6 +1,5 @@
|
||||
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.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
@@ -10,17 +9,11 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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=
|
||||
|
@@ -4,9 +4,9 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/sys v0.7.0
|
||||
golang.org/x/sys v0.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@@ -10,13 +10,9 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
@@ -24,10 +20,9 @@ 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.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -15,8 +15,8 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ID represents a generic identifier which is canonically
|
||||
@@ -42,7 +42,7 @@ func (p IDSlice) Less(i, j int) bool { return uint64(p[i]) < uint64(p[j]) }
|
||||
func (p IDSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
func (p IDSlice) String() string {
|
||||
var b bytes.Buffer
|
||||
var b strings.Builder
|
||||
if p.Len() > 0 {
|
||||
b.WriteString(p[0].String())
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ go 1.19
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/prometheus/client_golang v1.15.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
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.24.0
|
||||
@@ -27,15 +27,14 @@ require (
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.43.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
@@ -40,7 +40,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -75,28 +74,23 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
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.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
|
||||
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
|
||||
github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
@@ -127,8 +121,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -145,14 +139,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -202,7 +196,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@@ -45,7 +45,7 @@ func hasChecksum(n int64) bool {
|
||||
// selected node, and saved snapshot is the point-in-time state of
|
||||
// the selected node.
|
||||
// Etcd <v3.6 will return "" as version.
|
||||
func SaveWithVersion(ctx context.Context, lg *zap.Logger, cfg clientv3.Config, dbPath string) (version string, err error) {
|
||||
func SaveWithVersion(ctx context.Context, lg *zap.Logger, cfg clientv3.Config, dbPath string) (string, error) {
|
||||
cfg.Logger = lg.Named("client")
|
||||
if len(cfg.Endpoints) != 1 {
|
||||
return "", fmt.Errorf("snapshot must be requested to one selected node, not multiple %v", cfg.Endpoints)
|
||||
@@ -91,7 +91,7 @@ func SaveWithVersion(ctx context.Context, lg *zap.Logger, cfg clientv3.Config, d
|
||||
zap.String("endpoint", cfg.Endpoints[0]),
|
||||
zap.String("size", humanize.Bytes(uint64(size))),
|
||||
zap.Duration("took", time.Since(start)),
|
||||
zap.String("etcd-version", version),
|
||||
zap.String("etcd-version", resp.Version),
|
||||
)
|
||||
|
||||
if err = os.Rename(partpath, dbPath); err != nil {
|
||||
|
25
codecov.yml
25
codecov.yml
@@ -1,17 +1,16 @@
|
||||
---
|
||||
codecov:
|
||||
token: "6040de41-c073-4d6f-bbf8-d89256ef31e1"
|
||||
token: 6040de41-c073-4d6f-bbf8-d89256ef31e1
|
||||
disable_default_path_fixes: true
|
||||
|
||||
fixes:
|
||||
- "go.etcd.io/etcd/api/v3/::api/"
|
||||
- "go.etcd.io/etcd/client/v3/::client/v3/"
|
||||
- "go.etcd.io/etcd/client/v2/::client/v2/"
|
||||
- "go.etcd.io/etcd/etcdctl/v3/::etcdctl/"
|
||||
- "go.etcd.io/etcd/pkg/v3/::pkg/"
|
||||
- "go.etcd.io/etcd/server/v3/::server/"
|
||||
|
||||
- go.etcd.io/etcd/api/v3/::api/
|
||||
- go.etcd.io/etcd/client/v3/::client/v3/
|
||||
- go.etcd.io/etcd/client/v2/::client/v2/
|
||||
- go.etcd.io/etcd/etcdctl/v3/::etcdctl/
|
||||
- go.etcd.io/etcd/pkg/v3/::pkg/
|
||||
- go.etcd.io/etcd/server/v3/::server/
|
||||
ignore:
|
||||
- "**/*.pb.go"
|
||||
- "**/*.pb.gw.go"
|
||||
- "tests/**/*"
|
||||
- "go.etcd.io/etcd/tests/**/*"
|
||||
- '**/*.pb.go'
|
||||
- '**/*.pb.gw.go'
|
||||
- tests/**/*
|
||||
- go.etcd.io/etcd/tests/**/*
|
||||
|
@@ -1,17 +1,15 @@
|
||||
rule_files:
|
||||
- manifests/etcd-prometheusRules.yaml
|
||||
|
||||
---
|
||||
rule_files: [manifests/etcd-prometheusRules.yaml]
|
||||
evaluation_interval: 1m
|
||||
|
||||
tests:
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'up{job="etcd",instance="10.10.10.0"}'
|
||||
values: '1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0'
|
||||
- series: 'up{job="etcd",instance="10.10.10.1"}'
|
||||
values: '1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0'
|
||||
- series: 'up{job="etcd",instance="10.10.10.2"}'
|
||||
values: '1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: up{job="etcd",instance="10.10.10.0"}
|
||||
values: 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
|
||||
- series: up{job="etcd",instance="10.10.10.1"}
|
||||
values: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
|
||||
- series: up{job="etcd",instance="10.10.10.2"}
|
||||
values: 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
alert_rule_test:
|
||||
- eval_time: 3m
|
||||
alertname: etcdInsufficientMembers
|
||||
@@ -27,7 +25,7 @@ tests:
|
||||
severity: critical
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": members are down (3).'
|
||||
summary: 'etcd cluster members are down.'
|
||||
summary: etcd cluster members are down.
|
||||
- eval_time: 7m
|
||||
alertname: etcdInsufficientMembers
|
||||
- eval_time: 11m
|
||||
@@ -38,7 +36,7 @@ tests:
|
||||
severity: critical
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": insufficient members (1).'
|
||||
summary: 'etcd cluster has insufficient number of members.'
|
||||
summary: etcd cluster has insufficient number of members.
|
||||
- eval_time: 15m
|
||||
alertname: etcdInsufficientMembers
|
||||
exp_alerts:
|
||||
@@ -47,16 +45,15 @@ tests:
|
||||
severity: critical
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": insufficient members (0).'
|
||||
summary: 'etcd cluster has insufficient number of members.'
|
||||
|
||||
summary: etcd cluster has insufficient number of members.
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'up{job="etcd",instance="10.10.10.0"}'
|
||||
values: '1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0'
|
||||
- series: 'up{job="etcd",instance="10.10.10.1"}'
|
||||
values: '1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: 'up{job="etcd",instance="10.10.10.2"}'
|
||||
values: '1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: up{job="etcd",instance="10.10.10.0"}
|
||||
values: 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
|
||||
- series: up{job="etcd",instance="10.10.10.1"}
|
||||
values: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
- series: up{job="etcd",instance="10.10.10.2"}
|
||||
values: 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
alert_rule_test:
|
||||
- eval_time: 14m
|
||||
alertname: etcdMembersDown
|
||||
@@ -66,16 +63,15 @@ tests:
|
||||
severity: critical
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": members are down (3).'
|
||||
summary: 'etcd cluster members are down.'
|
||||
|
||||
summary: etcd cluster members are down.
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'up{job="etcd",instance="10.10.10.0"}'
|
||||
values: '1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0'
|
||||
- series: 'up{job="etcd",instance="10.10.10.1"}'
|
||||
values: '1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0'
|
||||
- series: 'etcd_network_peer_sent_failures_total{To="member-1",job="etcd",endpoint="test"}'
|
||||
values: '0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18'
|
||||
- series: up{job="etcd",instance="10.10.10.0"}
|
||||
values: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
|
||||
- series: up{job="etcd",instance="10.10.10.1"}
|
||||
values: 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
|
||||
- series: etcd_network_peer_sent_failures_total{To="member-1",job="etcd",endpoint="test"}
|
||||
values: 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||
alert_rule_test:
|
||||
- eval_time: 13m
|
||||
alertname: etcdMembersDown
|
||||
@@ -85,16 +81,15 @@ tests:
|
||||
severity: critical
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": members are down (1).'
|
||||
summary: 'etcd cluster members are down.'
|
||||
|
||||
summary: etcd cluster members are down.
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.0"}'
|
||||
values: '0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.1"}'
|
||||
values: '0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.2"}'
|
||||
values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.0"}
|
||||
values: 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.1"}
|
||||
values: 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.2"}
|
||||
values: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
alert_rule_test:
|
||||
- eval_time: 10m
|
||||
alertname: etcdHighNumberOfLeaderChanges
|
||||
@@ -104,61 +99,59 @@ tests:
|
||||
severity: warning
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": 4 leader changes within the last 15 minutes. Frequent elections may be a sign of insufficient resources, high network latency, or disruptions by other components and should be investigated.'
|
||||
summary: 'etcd cluster has high number of leader changes.'
|
||||
summary: etcd cluster has high number of leader changes.
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.0"}'
|
||||
values: '0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.1"}'
|
||||
values: '0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: 'etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.2"}'
|
||||
values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.0"}
|
||||
values: 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.1"}
|
||||
values: 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
- series: etcd_server_leader_changes_seen_total{job="etcd",instance="10.10.10.2"}
|
||||
values: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
alert_rule_test:
|
||||
- eval_time: 10m
|
||||
alertname: etcdHighNumberOfLeaderChanges
|
||||
exp_alerts:
|
||||
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.0"}'
|
||||
values: '0+8192x240'
|
||||
- series: 'etcd_server_quota_backend_bytes{job="etcd",instance="10.10.10.0"}'
|
||||
values: '524288+0x240'
|
||||
- series: 'etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.1"}'
|
||||
values: '0+1024x240'
|
||||
- series: 'etcd_server_quota_backend_bytes{job="etcd",instance="10.10.10.1"}'
|
||||
values: '524288+0x240'
|
||||
- series: etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.0"}
|
||||
values: 0+8192x240
|
||||
- series: etcd_server_quota_backend_bytes{job="etcd",instance="10.10.10.0"}
|
||||
values: 524288+0x240
|
||||
- series: etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.1"}
|
||||
values: 0+1024x240
|
||||
- series: etcd_server_quota_backend_bytes{job="etcd",instance="10.10.10.1"}
|
||||
values: 524288+0x240
|
||||
alert_rule_test:
|
||||
- eval_time: 11m
|
||||
alertname: etcdExcessiveDatabaseGrowth
|
||||
exp_alerts:
|
||||
- exp_labels:
|
||||
instance: '10.10.10.0'
|
||||
instance: 10.10.10.0
|
||||
job: etcd
|
||||
severity: warning
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": Predicting running out of disk space in the next four hours, based on write observations within the past four hours on etcd instance 10.10.10.0, please check as it might be disruptive.'
|
||||
summary: 'etcd cluster database growing very fast.'
|
||||
|
||||
summary: etcd cluster database growing very fast.
|
||||
- interval: 1m
|
||||
input_series:
|
||||
- series: 'etcd_mvcc_db_total_size_in_use_in_bytes{job="etcd",instance="10.10.10.0"}'
|
||||
values: '300000000+0x10'
|
||||
- series: 'etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.0"}'
|
||||
values: '1000000000+0x10'
|
||||
- series: 'etcd_mvcc_db_total_size_in_use_in_bytes{job="etcd",instance="10.10.10.1"}'
|
||||
values: '700000000+0x10'
|
||||
- series: 'etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.1"}'
|
||||
values: '1000000000+0x10'
|
||||
- series: etcd_mvcc_db_total_size_in_use_in_bytes{job="etcd",instance="10.10.10.0"}
|
||||
values: 300000000+0x10
|
||||
- series: etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.0"}
|
||||
values: 1000000000+0x10
|
||||
- series: etcd_mvcc_db_total_size_in_use_in_bytes{job="etcd",instance="10.10.10.1"}
|
||||
values: 700000000+0x10
|
||||
- series: etcd_mvcc_db_total_size_in_bytes{job="etcd",instance="10.10.10.1"}
|
||||
values: 1000000000+0x10
|
||||
alert_rule_test:
|
||||
- eval_time: 11m
|
||||
alertname: etcdDatabaseHighFragmentationRatio
|
||||
exp_alerts:
|
||||
- exp_labels:
|
||||
instance: '10.10.10.0'
|
||||
instance: 10.10.10.0
|
||||
job: etcd
|
||||
severity: warning
|
||||
exp_annotations:
|
||||
description: 'etcd cluster "etcd": database size in use on instance 10.10.10.0 is 30% of the actual allocated disk space, please run defragmentation (e.g. etcdctl defrag) to retrieve the unused fragmented disk space.'
|
||||
runbook_url: https://etcd.io/docs/v3.5/op-guide/maintenance/#defragmentation
|
||||
summary: 'etcd database size in use is less than 50% of the actual allocated storage.'
|
||||
summary: etcd database size in use is less than 50% of the actual allocated storage.
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/snap"
|
||||
@@ -63,7 +64,7 @@ func (s *kvstore) Lookup(key string) (string, bool) {
|
||||
}
|
||||
|
||||
func (s *kvstore) Propose(k string, v string) {
|
||||
var buf bytes.Buffer
|
||||
var buf strings.Builder
|
||||
if err := gob.NewEncoder(&buf).Encode(kv{k, v}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@@ -57,7 +57,8 @@ discovery-proxy:
|
||||
# DNS domain used to bootstrap initial cluster.
|
||||
discovery-srv:
|
||||
|
||||
# Initial cluster configuration for bootstrapping.
|
||||
# Comma separated string of initial cluster configuration for bootstrapping.
|
||||
# Example: initial-cluster: "infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380"
|
||||
initial-cluster:
|
||||
|
||||
# Initial cluster token for the etcd cluster during bootstrap.
|
||||
|
@@ -76,7 +76,7 @@ func newEpHashKVCommand() *cobra.Command {
|
||||
Short: "Prints the KV history hash for each endpoint in --endpoints",
|
||||
Run: epHashKVCommandFunc,
|
||||
}
|
||||
hc.PersistentFlags().Int64Var(&epHashKVRev, "rev", 0, "maximum revision to hash (default: all revisions)")
|
||||
hc.PersistentFlags().Int64Var(&epHashKVRev, "rev", 0, "maximum revision to hash (default: latest revision)")
|
||||
return hc
|
||||
}
|
||||
|
||||
|
@@ -15,11 +15,11 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
@@ -58,7 +58,7 @@ func printJSON(v interface{}) {
|
||||
}
|
||||
|
||||
func printMemberListWithHexJSON(r clientv3.MemberListResponse) {
|
||||
var buffer bytes.Buffer
|
||||
var buffer strings.Builder
|
||||
var b []byte
|
||||
buffer.WriteString("{\"header\":{\"cluster_id\":\"")
|
||||
b = strconv.AppendUint(nil, r.Header.ClusterId, 16)
|
||||
|
@@ -34,9 +34,9 @@ require (
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
)
|
||||
|
@@ -88,10 +88,10 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
@@ -106,7 +106,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
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/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
@@ -137,8 +137,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -156,14 +156,14 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@@ -49,9 +49,9 @@ require (
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/prometheus/client_golang v1.15.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/client_golang v1.15.1 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.43.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
@@ -63,10 +63,10 @@ require (
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/goleak v1.1.12 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.8.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
|
@@ -52,7 +52,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -96,13 +95,13 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
|
||||
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
|
||||
github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@@ -116,7 +115,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -146,8 +145,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
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=
|
||||
@@ -167,11 +166,11 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -187,14 +186,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
16
go.mod
16
go.mod
@@ -20,7 +20,7 @@ require (
|
||||
github.com/coreos/go-semver v0.3.1
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
|
||||
@@ -69,9 +69,9 @@ require (
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.15.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/client_golang v1.15.1 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.43.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
@@ -90,10 +90,10 @@ require (
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.8.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
40
go.sum
40
go.sum
@@ -229,13 +229,13 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
|
||||
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
|
||||
github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@@ -257,18 +257,14 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
@@ -322,8 +318,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
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=
|
||||
@@ -392,8 +388,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -406,7 +402,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -418,7 +414,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -459,8 +455,8 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -469,8 +465,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@@ -1,18 +1,17 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: etcd-client
|
||||
spec:
|
||||
ports:
|
||||
- name: etcd-client-port
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: etcd-client-port
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
selector:
|
||||
app: etcd
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -22,35 +21,33 @@ metadata:
|
||||
name: etcd0
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd0
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd0:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd0:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd0
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd0
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd0:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd0:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd0
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
restartPolicy: Always
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -59,19 +56,17 @@ metadata:
|
||||
name: etcd0
|
||||
spec:
|
||||
ports:
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
selector:
|
||||
etcd_node: etcd0
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -81,35 +76,33 @@ metadata:
|
||||
name: etcd1
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd1
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd1:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd1:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd1
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd1
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd1:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd1:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd1
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
restartPolicy: Always
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -118,19 +111,17 @@ metadata:
|
||||
name: etcd1
|
||||
spec:
|
||||
ports:
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
selector:
|
||||
etcd_node: etcd1
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -140,35 +131,33 @@ metadata:
|
||||
name: etcd2
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd2
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd2:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd2:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd2
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
- command:
|
||||
- /usr/local/bin/etcd
|
||||
- --name
|
||||
- etcd2
|
||||
- --initial-advertise-peer-urls
|
||||
- http://etcd2:2380
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --listen-client-urls
|
||||
- http://0.0.0.0:2379
|
||||
- --advertise-client-urls
|
||||
- http://etcd2:2379
|
||||
- --initial-cluster
|
||||
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
image: quay.io/coreos/etcd:latest
|
||||
name: etcd2
|
||||
ports:
|
||||
- containerPort: 2379
|
||||
name: client
|
||||
protocol: TCP
|
||||
- containerPort: 2380
|
||||
name: server
|
||||
protocol: TCP
|
||||
restartPolicy: Always
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -177,13 +166,13 @@ metadata:
|
||||
name: etcd2
|
||||
spec:
|
||||
ports:
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
- name: client
|
||||
port: 2379
|
||||
protocol: TCP
|
||||
targetPort: 2379
|
||||
- name: server
|
||||
port: 2380
|
||||
protocol: TCP
|
||||
targetPort: 2380
|
||||
selector:
|
||||
etcd_node: etcd2
|
||||
|
@@ -1,3 +1,4 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -6,17 +7,17 @@ metadata:
|
||||
name: vulcand
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /go/bin/vulcand
|
||||
- -apiInterface=0.0.0.0
|
||||
- --etcd=http://etcd-client:2379
|
||||
image: mailgun/vulcand:v0.8.0-beta.2
|
||||
name: vulcand
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
name: api
|
||||
protocol: TCP
|
||||
- containerPort: 8082
|
||||
name: server
|
||||
protocol: TCP
|
||||
- command:
|
||||
- /go/bin/vulcand
|
||||
- -apiInterface=0.0.0.0
|
||||
- --etcd=http://etcd-client:2379
|
||||
image: mailgun/vulcand:v0.8.0-beta.2
|
||||
name: vulcand
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
name: api
|
||||
protocol: TCP
|
||||
- containerPort: 8082
|
||||
name: server
|
||||
protocol: TCP
|
||||
restartPolicy: Always
|
||||
|
@@ -17,7 +17,6 @@
|
||||
package cobrautl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -103,7 +102,7 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
|
||||
func etcdFlagUsages(flagSet *pflag.FlagSet) string {
|
||||
x := new(bytes.Buffer)
|
||||
x := new(strings.Builder)
|
||||
|
||||
flagSet.VisitAll(func(flag *pflag.Flag) {
|
||||
if len(flag.Deprecated) > 0 {
|
||||
|
@@ -8,7 +8,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0
|
||||
go.uber.org/zap v1.24.0
|
||||
google.golang.org/grpc v1.51.0
|
||||
@@ -22,9 +22,9 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
21
pkg/go.sum
21
pkg/go.sum
@@ -69,14 +69,10 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
@@ -99,8 +95,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -114,14 +110,14 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -165,7 +161,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@@ -15,12 +15,12 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -119,7 +119,7 @@ func (sp *secondPoints) getTimeSeries() TimeSeries {
|
||||
}
|
||||
|
||||
func (t TimeSeries) String() string {
|
||||
buf := new(bytes.Buffer)
|
||||
buf := new(strings.Builder)
|
||||
wr := csv.NewWriter(buf)
|
||||
if err := wr.Write([]string{"UNIX-SECOND", "MIN-LATENCY-MS", "AVG-LATENCY-MS", "MAX-LATENCY-MS", "AVG-THROUGHPUT"}); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@@ -16,10 +16,10 @@
|
||||
package traceutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -44,7 +44,7 @@ func writeFields(fields []Field) string {
|
||||
if len(fields) == 0 {
|
||||
return ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
var buf strings.Builder
|
||||
buf.WriteString("{")
|
||||
for _, f := range fields {
|
||||
buf.WriteString(f.format())
|
||||
|
28
scripts/fix-goimports.sh
Executable file
28
scripts/fix-goimports.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source ./scripts/test_lib.sh
|
||||
|
||||
ROOTDIR=$(pwd)
|
||||
|
||||
# To fix according to newer version of go:
|
||||
# go get golang.org/dl/gotip
|
||||
# gotip download
|
||||
# GO_CMD="gotip"
|
||||
GO_CMD="go"
|
||||
|
||||
ROOTDIR=$(pwd)
|
||||
|
||||
function go_imports_fix {
|
||||
GOFILES=$(run ${GO_CMD} list --f "{{with \$d:=.}}{{range .GoFiles}}{{\$d.Dir}}/{{.}}{{\"\n\"}}{{end}}{{end}}" ./...)
|
||||
TESTGOFILES=$(run ${GO_CMD} list --f "{{with \$d:=.}}{{range .TestGoFiles}}{{\$d.Dir}}/{{.}}{{\"\n\"}}{{end}}{{end}}" ./...)
|
||||
cd "${ROOTDIR}/tools/mod"
|
||||
echo "${GOFILES}" "${TESTGOFILES}" | grep -v '.gw.go' | grep -v '.pb.go' | xargs -n 100 go run golang.org/x/tools/cmd/goimports -w -local go.etcd.io
|
||||
}
|
||||
|
||||
log_callout -e "\\nFixing goimports for you...\n"
|
||||
|
||||
run_for_modules go_imports_fix || exit 2
|
||||
|
||||
log_success -e "\\nSUCCESS: goimports are fixed :)"
|
@@ -8,8 +8,6 @@ go mod tidy
|
||||
source ./scripts/test_lib.sh
|
||||
source ./scripts/updatebom.sh
|
||||
|
||||
ROOTDIR=$(pwd)
|
||||
|
||||
# To fix according to newer version of go:
|
||||
# go get golang.org/dl/gotip
|
||||
# gotip download
|
||||
@@ -31,20 +29,11 @@ function bash_ws_fix {
|
||||
find ./ -name '*.sh.bak' -print0 | xargs -0 rm
|
||||
}
|
||||
|
||||
function go_imports_fix {
|
||||
GOFILES=$(run ${GO_CMD} list --f "{{with \$d:=.}}{{range .GoFiles}}{{\$d.Dir}}/{{.}}{{\"\n\"}}{{end}}{{end}}" ./...)
|
||||
TESTGOFILES=$(run ${GO_CMD} list --f "{{with \$d:=.}}{{range .TestGoFiles}}{{\$d.Dir}}/{{.}}{{\"\n\"}}{{end}}{{end}}" ./...)
|
||||
cd "${ROOTDIR}/tools/mod"
|
||||
echo "${GOFILES}" "${TESTGOFILES}" | grep -v '.gw.go' | grep -v '.pb.go' | xargs -n 100 go run golang.org/x/tools/cmd/goimports -w -local go.etcd.io
|
||||
}
|
||||
|
||||
log_callout -e "\\nFixing etcd code for you...\n"
|
||||
|
||||
run_for_modules mod_tidy_fix || exit 2
|
||||
run_for_modules run ${GO_CMD} fmt || exit 2
|
||||
run_for_module tests bom_fix || exit 2
|
||||
log_callout "Fixing goimports..."
|
||||
run_for_modules go_imports_fix || exit 2
|
||||
bash_ws_fix || exit 2
|
||||
|
||||
|
||||
|
@@ -112,10 +112,10 @@ main() {
|
||||
# Check go version.
|
||||
log_callout "Check go version"
|
||||
local go_version current_go_version
|
||||
go_version="go$(grep -oP '(?<=GO_VERSION:\s")[^"]*' .github/workflows/go-version.yaml | tr -d ' ')"
|
||||
go_version="go$(cat .go-version)"
|
||||
current_go_version=$(go version | awk '{ print $3 }')
|
||||
if [[ "${current_go_version}" != "${go_version}" ]]; then
|
||||
log_error "Current go version is ${current_go_version}, but etcd ${RELEASE_VERSION} requires ${go_version} (see .github/workflows/build.yaml)."
|
||||
log_error "Current go version is ${current_go_version}, but etcd ${RELEASE_VERSION} requires ${go_version} (see .go-version)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@@ -26,6 +26,9 @@
|
||||
# $ PASSES=unit PKG=./wal TESTCASE="\bTestNew\b" TIMEOUT=1m ./scripts/test.sh
|
||||
# $ PASSES=integration PKG=./client/integration TESTCASE="\bTestV2NoRetryEOF\b" TIMEOUT=1m ./scripts/test.sh
|
||||
#
|
||||
# KEEP_GOING_SUITE must be set to true to keep going with the next suite execution, passed to PASSES variable when there is a failure
|
||||
# in a particular suite.
|
||||
# KEEP_GOING_MODULE must be set to true to keep going with execution when there is failure in any module.
|
||||
#
|
||||
# Run code coverage
|
||||
# COVERDIR must either be a absolute path or a relative path to the etcd root
|
||||
@@ -55,6 +58,7 @@ if [ -n "${OUTPUT_FILE}" ]; then
|
||||
fi
|
||||
|
||||
PASSES=${PASSES:-"gofmt bom dep build unit"}
|
||||
KEEP_GOING_SUITE=${KEEP_GOING_SUITE:-false}
|
||||
PKG=${PKG:-}
|
||||
SHELLCHECK_VERSION=${SHELLCHECK_VERSION:-"v0.8.0"}
|
||||
|
||||
@@ -646,16 +650,30 @@ function run_pass {
|
||||
shift 1
|
||||
log_callout -e "\\n'${pass}' started at $(date)"
|
||||
if "${pass}_pass" "$@" ; then
|
||||
log_success "'${pass}' completed at $(date)"
|
||||
log_success "'${pass}' PASSED and completed at $(date)"
|
||||
return 0
|
||||
else
|
||||
log_error "FAIL: '${pass}' failed at $(date)"
|
||||
exit 255
|
||||
log_error "FAIL: '${pass}' FAILED at $(date)"
|
||||
if [ "$KEEP_GOING_SUITE" = true ]; then
|
||||
return 2
|
||||
else
|
||||
exit 255
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
log_callout "Starting at: $(date)"
|
||||
fail_flag=false
|
||||
for pass in $PASSES; do
|
||||
run_pass "${pass}" "${@}"
|
||||
if run_pass "${pass}" "${@}"; then
|
||||
continue
|
||||
else
|
||||
fail_flag=true
|
||||
fi
|
||||
done
|
||||
if [ "$fail_flag" = true ]; then
|
||||
log_error "There was FAILURE in the test suites ran. Look above log detail"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
log_success "SUCCESS"
|
||||
|
@@ -203,11 +203,25 @@ function modules_exp() {
|
||||
# run given command across all modules and packages
|
||||
# (unless the set is limited using ${PKG} or / ${USERMOD})
|
||||
function run_for_modules {
|
||||
KEEP_GOING_MODULE=${KEEP_GOING_MODULE:-false}
|
||||
local pkg="${PKG:-./...}"
|
||||
local fail_mod=false
|
||||
if [ -z "${USERMOD:-}" ]; then
|
||||
for m in $(module_dirs); do
|
||||
run_for_module "${m}" "$@" "${pkg}" || return "$?"
|
||||
if run_for_module "${m}" "$@" "${pkg}"; then
|
||||
continue
|
||||
else
|
||||
if [ "$KEEP_GOING_MODULE" = false ]; then
|
||||
log_error "There was a Failure in module ${m}, aborting..."
|
||||
return 1
|
||||
fi
|
||||
log_error "There was a Failure in module ${m}, keep going..."
|
||||
fail_mod=true
|
||||
fi
|
||||
done
|
||||
if [ "$fail_mod" = true ]; then
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
run_for_module "${USERMOD}" "$@" "${pkg}" || return "$?"
|
||||
fi
|
||||
@@ -293,7 +307,7 @@ function go_test {
|
||||
junit_filename_prefix=$(junitFilenamePrefix)
|
||||
|
||||
if [ "${VERBOSE:-}" == "1" ]; then
|
||||
goTestFlags="-v"
|
||||
goTestFlags="-v "
|
||||
fi
|
||||
|
||||
# Expanding patterns (like ./...) into list of packages
|
||||
@@ -308,6 +322,10 @@ function go_test {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${mode}" == "fail_fast" ]; then
|
||||
goTestFlags+="-failfast "
|
||||
fi
|
||||
|
||||
local failures=""
|
||||
|
||||
# execution of tests against packages:
|
||||
|
@@ -68,6 +68,7 @@ const (
|
||||
DefaultGRPCKeepAliveTimeout = 20 * time.Second
|
||||
DefaultDowngradeCheckTime = 5 * time.Second
|
||||
DefaultWaitClusterReadyTimeout = 5 * time.Second
|
||||
DefaultAutoCompactionMode = "periodic"
|
||||
|
||||
DefaultDiscoveryDialTimeout = 2 * time.Second
|
||||
DefaultDiscoveryRequestTimeOut = 5 * time.Second
|
||||
@@ -546,6 +547,8 @@ func NewConfig() *Config {
|
||||
Auth: &clientv3.AuthConfig{},
|
||||
},
|
||||
},
|
||||
|
||||
AutoCompactionMode: DefaultAutoCompactionMode,
|
||||
}
|
||||
cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
|
||||
return cfg
|
||||
@@ -772,8 +775,9 @@ func (cfg *Config) Validate() error {
|
||||
}
|
||||
|
||||
switch cfg.AutoCompactionMode {
|
||||
case "":
|
||||
case CompactorModeRevision, CompactorModePeriodic:
|
||||
case "":
|
||||
return errors.New("undefined auto-compaction-mode")
|
||||
default:
|
||||
return fmt.Errorf("unknown auto-compaction-mode %q", cfg.AutoCompactionMode)
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.etcd.io/etcd/client/pkg/v3/srv"
|
||||
"go.etcd.io/etcd/client/pkg/v3/transport"
|
||||
@@ -202,6 +203,11 @@ func TestAutoCompactionModeParse(t *testing.T) {
|
||||
// err mode
|
||||
{"errmode", "1", false, 0},
|
||||
{"errmode", "1h", false, time.Hour},
|
||||
// empty mode
|
||||
{"", "1", true, 0},
|
||||
{"", "1h", false, time.Hour},
|
||||
{"", "a", true, 0},
|
||||
{"", "-1", true, 0},
|
||||
}
|
||||
|
||||
hasErr := func(err error) bool {
|
||||
@@ -507,3 +513,10 @@ func TestTLSVersionMinMax(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUndefinedAutoCompactionModeValidate(t *testing.T) {
|
||||
cfg := *NewConfig()
|
||||
cfg.AutoCompactionMode = ""
|
||||
err := cfg.Validate()
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ package embed
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
defaultLog "log"
|
||||
@@ -629,10 +630,10 @@ func configureClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err erro
|
||||
for _, u := range append(cfg.ListenClientUrls, cfg.ListenClientHttpUrls...) {
|
||||
if u.Scheme == "http" || u.Scheme == "unix" {
|
||||
if !cfg.ClientTLSInfo.Empty() {
|
||||
cfg.logger.Warn("scheme is HTTP while key and cert files are present; ignoring key and cert files", zap.String("client-url", u.String()))
|
||||
cfg.logger.Warn("scheme is http or unix while key and cert files are present; ignoring key and cert files", zap.String("client-url", u.String()))
|
||||
}
|
||||
if cfg.ClientTLSInfo.ClientCertAuth {
|
||||
cfg.logger.Warn("scheme is HTTP while --client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("client-url", u.String()))
|
||||
cfg.logger.Warn("scheme is http or unix while --client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("client-url", u.String()))
|
||||
}
|
||||
}
|
||||
if (u.Scheme == "https" || u.Scheme == "unixs") && cfg.ClientTLSInfo.Empty() {
|
||||
@@ -887,6 +888,8 @@ func parseCompactionRetention(mode, retention string) (ret time.Duration, err er
|
||||
ret = time.Duration(int64(h))
|
||||
case CompactorModePeriodic:
|
||||
ret = time.Duration(int64(h)) * time.Hour
|
||||
case "":
|
||||
return 0, errors.New("--auto-compaction-mode is undefined")
|
||||
}
|
||||
} else {
|
||||
// periodic compaction
|
||||
|
@@ -256,6 +256,10 @@ Experimental feature:
|
||||
Enable to check data corruption before serving any client/peer traffic.
|
||||
--experimental-corrupt-check-time '0s'
|
||||
Duration of time between cluster corruption check passes.
|
||||
--experimental-compact-hash-check-enabled 'false'
|
||||
Enable leader to periodically check followers compaction hashes.
|
||||
--experimental-compact-hash-check-time '1m'
|
||||
Duration of time between leader checks followers compaction hashes.
|
||||
--experimental-enable-lease-checkpoint 'false'
|
||||
ExperimentalEnableLeaseCheckpoint enables primary lessor to persist lease remainingTTL to prevent indefinite auto-renewal of long lived leases.
|
||||
--experimental-compaction-batch-limit 1000
|
||||
|
@@ -35,13 +35,11 @@ func discoverEndpoints(lg *zap.Logger, dns string, ca string, insecure bool, ser
|
||||
}
|
||||
endpoints := srvs.Endpoints
|
||||
|
||||
if lg != nil {
|
||||
lg.Info(
|
||||
"discovered cluster from SRV",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
}
|
||||
lg.Info(
|
||||
"discovered cluster from SRV",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
|
||||
if insecure {
|
||||
return *srvs
|
||||
@@ -52,32 +50,26 @@ func discoverEndpoints(lg *zap.Logger, dns string, ca string, insecure bool, ser
|
||||
ServerName: dns,
|
||||
}
|
||||
|
||||
if lg != nil {
|
||||
lg.Info(
|
||||
"validating discovered SRV endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
}
|
||||
lg.Info(
|
||||
"validating discovered SRV endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
|
||||
endpoints, err = transport.ValidateSecureEndpoints(tlsInfo, endpoints)
|
||||
if err != nil {
|
||||
if lg != nil {
|
||||
lg.Warn(
|
||||
"failed to validate discovered endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
lg.Warn(
|
||||
"failed to validate discovered endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
zap.Error(err),
|
||||
)
|
||||
} else {
|
||||
if lg != nil {
|
||||
lg.Info(
|
||||
"using validated discovered SRV endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
}
|
||||
lg.Info(
|
||||
"using validated discovered SRV endpoints",
|
||||
zap.String("srv-server", dns),
|
||||
zap.Strings("endpoints", endpoints),
|
||||
)
|
||||
}
|
||||
|
||||
// map endpoints back to SRVClients struct with SRV data
|
||||
|
@@ -15,7 +15,6 @@
|
||||
package membership
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
@@ -215,7 +214,7 @@ func (c *RaftCluster) ClientURLs() []string {
|
||||
func (c *RaftCluster) String() string {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
b := &bytes.Buffer{}
|
||||
b := &strings.Builder{}
|
||||
fmt.Fprintf(b, "{ClusterID:%s ", c.cid)
|
||||
var ms []string
|
||||
for _, m := range c.members {
|
||||
|
@@ -125,16 +125,27 @@ func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevoke
|
||||
func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
|
||||
l := aa.lessor.Lookup(leaseID)
|
||||
if l != nil {
|
||||
for _, key := range l.Keys() {
|
||||
if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return aa.checkLeasePutsKeys(l)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aa *authApplierV3) checkLeasePutsKeys(l *lease.Lease) error {
|
||||
// early return for most-common scenario of either disabled auth or admin user.
|
||||
// IsAdminPermitted also checks whether auth is enabled
|
||||
if err := aa.as.IsAdminPermitted(&aa.authInfo); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, key := range l.Keys() {
|
||||
if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aa *authApplierV3) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
|
||||
err := aa.as.IsAdminPermitted(&aa.authInfo)
|
||||
if err != nil && r.Name != aa.authInfo.Username {
|
||||
|
124
server/etcdserver/apply/apply_auth_test.go
Normal file
124
server/etcdserver/apply/apply_auth_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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.
|
||||
|
||||
package apply
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
betesting "go.etcd.io/etcd/server/v3/storage/backend/testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"go.etcd.io/etcd/server/v3/storage/schema"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/authpb"
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/server/v3/auth"
|
||||
"go.etcd.io/etcd/server/v3/lease"
|
||||
)
|
||||
|
||||
func TestCheckLeasePutsKeys(t *testing.T) {
|
||||
lg := zaptest.NewLogger(t)
|
||||
|
||||
b, _ := betesting.NewDefaultTmpBackend(t)
|
||||
defer betesting.Close(t, b)
|
||||
|
||||
simpleTokenTTLDefault := 300 * time.Second
|
||||
tokenTypeSimple := "simple"
|
||||
dummyIndexWaiter := func(index uint64) <-chan struct{} {
|
||||
ch := make(chan struct{}, 1)
|
||||
go func() {
|
||||
ch <- struct{}{}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
tp, _ := auth.NewTokenProvider(zaptest.NewLogger(t), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
|
||||
as := auth.NewAuthStore(lg, schema.NewAuthBackend(lg, b), tp, bcrypt.MinCost)
|
||||
|
||||
aa := authApplierV3{as: as}
|
||||
assert.NoError(t, aa.checkLeasePutsKeys(lease.NewLease(lease.LeaseID(1), 3600)), "auth is disabled, should allow puts")
|
||||
assert.NoError(t, enableAuthAndCreateRoot(aa.as), "error while enabling auth")
|
||||
aa.authInfo = auth.AuthInfo{Username: "root"}
|
||||
assert.NoError(t, aa.checkLeasePutsKeys(lease.NewLease(lease.LeaseID(1), 3600)), "auth is enabled, should allow puts for root")
|
||||
|
||||
l := lease.NewLease(lease.LeaseID(1), 3600)
|
||||
l.SetLeaseItem(lease.LeaseItem{Key: "a"})
|
||||
aa.authInfo = auth.AuthInfo{Username: "bob", Revision: 0}
|
||||
assert.ErrorIs(t, aa.checkLeasePutsKeys(l), auth.ErrUserEmpty, "auth is enabled, should not allow bob, non existing at rev 0")
|
||||
aa.authInfo = auth.AuthInfo{Username: "bob", Revision: 1}
|
||||
assert.ErrorIs(t, aa.checkLeasePutsKeys(l), auth.ErrAuthOldRevision, "auth is enabled, old revision")
|
||||
|
||||
aa.authInfo = auth.AuthInfo{Username: "bob", Revision: aa.as.Revision()}
|
||||
assert.ErrorIs(t, aa.checkLeasePutsKeys(l), auth.ErrPermissionDenied, "auth is enabled, bob does not have permissions, bob does not exist")
|
||||
_, err := aa.as.UserAdd(&pb.AuthUserAddRequest{Name: "bob", Options: &authpb.UserAddOptions{NoPassword: true}})
|
||||
assert.NoError(t, err, "bob should be added without error")
|
||||
aa.authInfo = auth.AuthInfo{Username: "bob", Revision: aa.as.Revision()}
|
||||
assert.ErrorIs(t, aa.checkLeasePutsKeys(l), auth.ErrPermissionDenied, "auth is enabled, bob exists yet does not have permissions")
|
||||
|
||||
// allow bob to access "a"
|
||||
_, err = aa.as.RoleAdd(&pb.AuthRoleAddRequest{Name: "bobsrole"})
|
||||
assert.NoError(t, err, "bobsrole should be added without error")
|
||||
_, err = aa.as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
|
||||
Name: "bobsrole",
|
||||
Perm: &authpb.Permission{
|
||||
PermType: authpb.READWRITE,
|
||||
Key: []byte("a"),
|
||||
RangeEnd: nil,
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err, "bobsrole should be granted permissions without error")
|
||||
_, err = aa.as.UserGrantRole(&pb.AuthUserGrantRoleRequest{
|
||||
User: "bob",
|
||||
Role: "bobsrole",
|
||||
})
|
||||
assert.NoError(t, err, "bob should be granted bobsrole without error")
|
||||
|
||||
aa.authInfo = auth.AuthInfo{Username: "bob", Revision: aa.as.Revision()}
|
||||
assert.NoError(t, aa.checkLeasePutsKeys(l), "bob should be able to access key 'a'")
|
||||
|
||||
}
|
||||
|
||||
func enableAuthAndCreateRoot(as auth.AuthStore) error {
|
||||
_, err := as.UserAdd(&pb.AuthUserAddRequest{
|
||||
Name: "root",
|
||||
HashedPassword: encodePassword("root"),
|
||||
Options: &authpb.UserAddOptions{NoPassword: false}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: "root"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "root", Role: "root"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return as.AuthEnable()
|
||||
}
|
||||
|
||||
func encodePassword(s string) string {
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(s), bcrypt.MinCost)
|
||||
return base64.StdEncoding.EncodeToString(hashedPassword)
|
||||
}
|
@@ -86,7 +86,6 @@ func (h hasherAdapter) TriggerCorruptAlarm(memberID types.ID) {
|
||||
// before serving any peer/client traffic. Only mismatch when hashes
|
||||
// are different at requested revision, with same compact revision.
|
||||
func (cm *corruptionChecker) InitialCheck() error {
|
||||
|
||||
cm.lg.Info(
|
||||
"starting initial corruption check",
|
||||
zap.String("local-member-id", cm.hasher.MemberId().String()),
|
||||
@@ -260,7 +259,7 @@ func (cm *corruptionChecker) PeriodicCheck() error {
|
||||
// have different hashes.
|
||||
//
|
||||
// We might miss opportunity to perform the check if the compaction is still
|
||||
// ongoing on one of the members or it was unresponsive. In such situation the
|
||||
// ongoing on one of the members, or it was unresponsive. In such situation the
|
||||
// method still passes without raising alarm.
|
||||
func (cm *corruptionChecker) CompactHashCheck() {
|
||||
cm.lg.Info("starting compact hash check",
|
||||
@@ -269,12 +268,13 @@ func (cm *corruptionChecker) CompactHashCheck() {
|
||||
)
|
||||
hashes := cm.uncheckedRevisions()
|
||||
// Assume that revisions are ordered from largest to smallest
|
||||
for _, hash := range hashes {
|
||||
for i, hash := range hashes {
|
||||
peers := cm.hasher.PeerHashByRev(hash.Revision)
|
||||
if len(peers) == 0 {
|
||||
continue
|
||||
}
|
||||
if cm.checkPeerHashes(hash, peers) {
|
||||
cm.lg.Info("finished compaction hash check", zap.Int("number-of-hashes-checked", i+1))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -1202,8 +1202,8 @@ func (s *EtcdServer) MoveLeader(ctx context.Context, lead, transferee uint64) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// TransferLeadership transfers the leader to the chosen transferee.
|
||||
func (s *EtcdServer) TransferLeadership() error {
|
||||
// TryTransferLeadershipOnShutdown transfers the leader to the chosen transferee. It is only used in server graceful shutdown.
|
||||
func (s *EtcdServer) TryTransferLeadershipOnShutdown() error {
|
||||
lg := s.Logger()
|
||||
if !s.isLeader() {
|
||||
lg.Info(
|
||||
@@ -1253,7 +1253,7 @@ func (s *EtcdServer) HardStop() {
|
||||
// Do and Process cannot be called after Stop has been invoked.
|
||||
func (s *EtcdServer) Stop() {
|
||||
lg := s.Logger()
|
||||
if err := s.TransferLeadership(); err != nil {
|
||||
if err := s.TryTransferLeadershipOnShutdown(); err != nil {
|
||||
lg.Warn("leadership transfer failed", zap.String("local-member-id", s.MemberId().String()), zap.Error(err))
|
||||
}
|
||||
s.HardStop()
|
||||
|
@@ -317,7 +317,32 @@ func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, e
|
||||
return -1, errors.ErrCanceled
|
||||
}
|
||||
|
||||
func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
|
||||
func (s *EtcdServer) checkLeaseTimeToLive(ctx context.Context, leaseID lease.LeaseID) (uint64, error) {
|
||||
rev := s.AuthStore().Revision()
|
||||
if !s.AuthStore().IsAuthEnabled() {
|
||||
return rev, nil
|
||||
}
|
||||
authInfo, err := s.AuthInfoFromCtx(ctx)
|
||||
if err != nil {
|
||||
return rev, err
|
||||
}
|
||||
if authInfo == nil {
|
||||
return rev, auth.ErrUserEmpty
|
||||
}
|
||||
|
||||
l := s.lessor.Lookup(leaseID)
|
||||
if l != nil {
|
||||
for _, key := range l.Keys() {
|
||||
if err := s.AuthStore().IsRangePermitted(authInfo, []byte(key), []byte{}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rev, nil
|
||||
}
|
||||
|
||||
func (s *EtcdServer) leaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
|
||||
if s.isLeader() {
|
||||
if err := s.waitAppliedIndex(); err != nil {
|
||||
return nil, err
|
||||
@@ -367,6 +392,30 @@ func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveR
|
||||
return nil, errors.ErrCanceled
|
||||
}
|
||||
|
||||
func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
|
||||
var rev uint64
|
||||
var err error
|
||||
if r.Keys {
|
||||
// check RBAC permission only if Keys is true
|
||||
rev, err = s.checkLeaseTimeToLive(ctx, lease.LeaseID(r.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := s.leaseTimeToLive(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.Keys {
|
||||
if s.AuthStore().IsAuthEnabled() && rev != s.AuthStore().Revision() {
|
||||
return nil, auth.ErrAuthOldRevision
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *EtcdServer) newHeader() *pb.ResponseHeader {
|
||||
return &pb.ResponseHeader{
|
||||
ClusterId: uint64(s.cluster.ID()),
|
||||
|
@@ -15,11 +15,11 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/jonboulle/clockwork v0.4.0
|
||||
github.com/prometheus/client_golang v1.15.0
|
||||
github.com/prometheus/client_model v0.3.0
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/prometheus/client_model v0.4.0
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
@@ -35,8 +35,8 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.14.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/net v0.9.0
|
||||
golang.org/x/crypto v0.10.0
|
||||
golang.org/x/net v0.11.0
|
||||
golang.org/x/time v0.3.0
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1
|
||||
google.golang.org/grpc v1.51.0
|
||||
@@ -58,7 +58,7 @@ require (
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/common v0.43.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
@@ -68,8 +68,8 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
||||
|
@@ -192,13 +192,13 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
|
||||
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
|
||||
github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@@ -217,17 +217,13 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
@@ -279,8 +275,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
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=
|
||||
@@ -340,15 +336,15 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -389,8 +385,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -398,8 +394,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@@ -39,6 +39,15 @@ type Lease struct {
|
||||
revokec chan struct{}
|
||||
}
|
||||
|
||||
func NewLease(id LeaseID, ttl int64) *Lease {
|
||||
return &Lease{
|
||||
ID: id,
|
||||
ttl: ttl,
|
||||
itemSet: make(map[LeaseItem]struct{}),
|
||||
revokec: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Lease) expired() bool {
|
||||
return l.Remaining() <= 0
|
||||
}
|
||||
@@ -56,6 +65,13 @@ func (l *Lease) TTL() int64 {
|
||||
return l.ttl
|
||||
}
|
||||
|
||||
// SetLeaseItem sets the given lease item, this func is thread-safe
|
||||
func (l *Lease) SetLeaseItem(item LeaseItem) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.itemSet[item] = struct{}{}
|
||||
}
|
||||
|
||||
// getRemainingTTL returns the last checkpointed remaining TTL of the lease.
|
||||
func (l *Lease) getRemainingTTL() int64 {
|
||||
if l.remainingTTL > 0 {
|
||||
|
@@ -279,12 +279,7 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) {
|
||||
|
||||
// TODO: when lessor is under high load, it should give out lease
|
||||
// with longer TTL to reduce renew load.
|
||||
l := &Lease{
|
||||
ID: id,
|
||||
ttl: ttl,
|
||||
itemSet: make(map[LeaseItem]struct{}),
|
||||
revokec: make(chan struct{}),
|
||||
}
|
||||
l := NewLease(id, ttl)
|
||||
|
||||
if l.ttl < le.minLeaseTTL {
|
||||
l.ttl = le.minLeaseTTL
|
||||
|
@@ -113,9 +113,9 @@ func (cp *clusterProxy) monitor(wa endpoints.WatchChannel) {
|
||||
for _, up := range updates {
|
||||
switch up.Op {
|
||||
case endpoints.Add:
|
||||
cp.umap[up.Endpoint.Addr] = up.Endpoint
|
||||
cp.umap[up.Key] = up.Endpoint
|
||||
case endpoints.Delete:
|
||||
delete(cp.umap, up.Endpoint.Addr)
|
||||
delete(cp.umap, up.Key)
|
||||
}
|
||||
}
|
||||
cp.umu.Unlock()
|
||||
@@ -139,12 +139,12 @@ func (cp *clusterProxy) membersFromUpdates() ([]*pb.Member, error) {
|
||||
cp.umu.RLock()
|
||||
defer cp.umu.RUnlock()
|
||||
mbs := make([]*pb.Member, 0, len(cp.umap))
|
||||
for addr, upt := range cp.umap {
|
||||
for _, upt := range cp.umap {
|
||||
m, err := decodeMeta(fmt.Sprint(upt.Metadata))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mbs = append(mbs, &pb.Member{Name: m.Name, ClientURLs: []string{addr}})
|
||||
mbs = append(mbs, &pb.Member{Name: m.Name, ClientURLs: []string{upt.Addr}})
|
||||
}
|
||||
return mbs, nil
|
||||
}
|
||||
|
@@ -69,10 +69,12 @@ func registerSession(lg *zap.Logger, c *clientv3.Client, prefix string, addr str
|
||||
|
||||
em, err := endpoints.NewManager(c, prefix)
|
||||
if err != nil {
|
||||
ss.Close()
|
||||
return nil, err
|
||||
}
|
||||
endpoint := endpoints.Endpoint{Addr: addr, Metadata: getMeta()}
|
||||
if err = em.AddEndpoint(c.Ctx(), prefix+"/"+addr, endpoint, clientv3.WithLease(ss.Lease())); err != nil {
|
||||
ss.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@@ -76,9 +76,12 @@ func OpenBackend(cfg config.ServerConfig, hooks backend.Hooks) backend.Backend {
|
||||
beOpened <- newBackend(cfg, hooks)
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
cfg.Logger.Info("opened backend db", zap.String("path", fn), zap.Duration("took", time.Since(now)))
|
||||
}()
|
||||
|
||||
select {
|
||||
case be := <-beOpened:
|
||||
cfg.Logger.Info("opened backend db", zap.String("path", fn), zap.Duration("took", time.Since(now)))
|
||||
return be
|
||||
|
||||
case <-time.After(10 * time.Second):
|
||||
|
@@ -86,7 +86,12 @@ type KeyValueHash struct {
|
||||
}
|
||||
|
||||
type HashStorage interface {
|
||||
// Hash computes the hash of the KV's backend.
|
||||
// Hash computes the hash of the whole backend keyspace,
|
||||
// including key, lease, and other buckets in storage.
|
||||
// This is designed for testing ONLY!
|
||||
// Do not rely on this in production with ongoing transactions,
|
||||
// since Hash operation does not hold MVCC locks.
|
||||
// Use "HashByRev" method instead for "key" bucket consistency checks.
|
||||
Hash() (hash uint32, revision int64, err error)
|
||||
|
||||
// HashByRev computes the hash of all MVCC revisions up to a given revision.
|
||||
|
@@ -225,7 +225,17 @@ func (s *store) updateCompactRev(rev int64) (<-chan struct{}, int64, error) {
|
||||
return nil, compactMainRev, nil
|
||||
}
|
||||
|
||||
func (s *store) compact(trace *traceutil.Trace, rev, prevCompactRev int64) (<-chan struct{}, error) {
|
||||
// checkPrevCompactionCompleted checks whether the previous scheduled compaction is completed.
|
||||
func (s *store) checkPrevCompactionCompleted() bool {
|
||||
tx := s.b.ReadTx()
|
||||
tx.Lock()
|
||||
defer tx.Unlock()
|
||||
scheduledCompact, scheduledCompactFound := UnsafeReadScheduledCompact(tx)
|
||||
finishedCompact, finishedCompactFound := UnsafeReadFinishedCompact(tx)
|
||||
return scheduledCompact == finishedCompact && scheduledCompactFound == finishedCompactFound
|
||||
}
|
||||
|
||||
func (s *store) compact(trace *traceutil.Trace, rev, prevCompactRev int64, prevCompactionCompleted bool) (<-chan struct{}, error) {
|
||||
ch := make(chan struct{})
|
||||
j := schedule.NewJob("kvstore_compact", func(ctx context.Context) {
|
||||
if ctx.Err() != nil {
|
||||
@@ -238,7 +248,13 @@ func (s *store) compact(trace *traceutil.Trace, rev, prevCompactRev int64) (<-ch
|
||||
s.compactBarrier(context.TODO(), ch)
|
||||
return
|
||||
}
|
||||
s.hashes.Store(hash)
|
||||
// Only store the hash value if the previous hash is completed, i.e. this compaction
|
||||
// hashes every revision from last compaction. For more details, see #15919.
|
||||
if prevCompactionCompleted {
|
||||
s.hashes.Store(hash)
|
||||
} else {
|
||||
s.lg.Info("previous compaction was interrupted, skip storing compaction hash value")
|
||||
}
|
||||
close(ch)
|
||||
})
|
||||
|
||||
@@ -248,17 +264,18 @@ func (s *store) compact(trace *traceutil.Trace, rev, prevCompactRev int64) (<-ch
|
||||
}
|
||||
|
||||
func (s *store) compactLockfree(rev int64) (<-chan struct{}, error) {
|
||||
prevCompactionCompleted := s.checkPrevCompactionCompleted()
|
||||
ch, prevCompactRev, err := s.updateCompactRev(rev)
|
||||
if err != nil {
|
||||
return ch, err
|
||||
}
|
||||
|
||||
return s.compact(traceutil.TODO(), rev, prevCompactRev)
|
||||
return s.compact(traceutil.TODO(), rev, prevCompactRev, prevCompactionCompleted)
|
||||
}
|
||||
|
||||
func (s *store) Compact(trace *traceutil.Trace, rev int64) (<-chan struct{}, error) {
|
||||
s.mu.Lock()
|
||||
|
||||
prevCompactionCompleted := s.checkPrevCompactionCompleted()
|
||||
ch, prevCompactRev, err := s.updateCompactRev(rev)
|
||||
trace.Step("check and update compact revision")
|
||||
if err != nil {
|
||||
@@ -267,7 +284,7 @@ func (s *store) Compact(trace *traceutil.Trace, rev int64) (<-chan struct{}, err
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
return s.compact(trace, rev, prevCompactRev)
|
||||
return s.compact(trace, rev, prevCompactRev, prevCompactionCompleted)
|
||||
}
|
||||
|
||||
func (s *store) Commit() {
|
||||
|
@@ -338,6 +338,8 @@ func TestStoreCompact(t *testing.T) {
|
||||
fi.indexCompactRespc <- map[revision]struct{}{{1, 0}: {}}
|
||||
key1 := newTestKeyBytes(lg, revision{1, 0}, false)
|
||||
key2 := newTestKeyBytes(lg, revision{2, 0}, false)
|
||||
b.tx.rangeRespc <- rangeResp{[][]byte{}, [][]byte{}}
|
||||
b.tx.rangeRespc <- rangeResp{[][]byte{}, [][]byte{}}
|
||||
b.tx.rangeRespc <- rangeResp{[][]byte{key1, key2}, [][]byte{[]byte("alice"), []byte("bob")}}
|
||||
|
||||
s.Compact(traceutil.TODO(), 3)
|
||||
@@ -349,6 +351,8 @@ func TestStoreCompact(t *testing.T) {
|
||||
end := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(end, uint64(4))
|
||||
wact := []testutil.Action{
|
||||
{Name: "range", Params: []interface{}{schema.Meta, schema.ScheduledCompactKeyName, []uint8(nil), int64(0)}},
|
||||
{Name: "range", Params: []interface{}{schema.Meta, schema.FinishedCompactKeyName, []uint8(nil), int64(0)}},
|
||||
{Name: "put", Params: []interface{}{schema.Meta, schema.ScheduledCompactKeyName, newTestRevBytes(revision{3, 0})}},
|
||||
{Name: "range", Params: []interface{}{schema.Key, make([]byte, 17), end, int64(10000)}},
|
||||
{Name: "delete", Params: []interface{}{schema.Key, key2}},
|
||||
|
@@ -89,8 +89,8 @@ func DefaultIgnores(bucket, key []byte) bool {
|
||||
// consistent index & term might be changed due to v2 internal sync, which
|
||||
// is not controllable by the user.
|
||||
// storage version might change after wal snapshot and is not controller by user.
|
||||
return bytes.Compare(bucket, Meta.Name()) == 0 &&
|
||||
(bytes.Compare(key, MetaTermKeyName) == 0 || bytes.Compare(key, MetaConsistentIndexKeyName) == 0 || bytes.Compare(key, MetaStorageVersionName) == 0)
|
||||
return bytes.Equal(bucket, Meta.Name()) &&
|
||||
(bytes.Equal(key, MetaTermKeyName) || bytes.Equal(key, MetaConsistentIndexKeyName) || bytes.Equal(key, MetaStorageVersionName))
|
||||
}
|
||||
|
||||
func BackendMemberKey(id types.ID) []byte {
|
||||
|
@@ -28,8 +28,9 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var defaultAuthToken = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=1s",
|
||||
mustAbsPath("../fixtures/server.crt"), mustAbsPath("../fixtures/server.key.insecure"))
|
||||
var tokenTTL = time.Second
|
||||
var defaultAuthToken = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=%s",
|
||||
mustAbsPath("../fixtures/server.crt"), mustAbsPath("../fixtures/server.key.insecure"), tokenTTL)
|
||||
|
||||
const (
|
||||
PermissionDenied = "etcdserver: permission denied"
|
||||
@@ -736,6 +737,121 @@ func TestAuthRoleList(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAuthJWTExpire(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
// wait an expiration of my JWT token
|
||||
<-time.After(3 * tokenTTL)
|
||||
|
||||
// e2e test will generate a new token while
|
||||
// integration test that re-uses the same etcd client will refresh the token on server failure.
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthRevisionConsistency ensures auth revision is the same after member restarts
|
||||
func TestAuthRevisionConsistency(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{}, []authUser{rootUser}), "failed to enable auth")
|
||||
rootAuthClient := testutils.MustClient(clus.Client(WithAuth(rootUserName, rootPassword)))
|
||||
|
||||
// add user
|
||||
_, err := rootAuthClient.UserAdd(ctx, testUserName, testPassword, config.UserAddOptions{})
|
||||
require.NoError(t, err)
|
||||
// delete the same user
|
||||
_, err = rootAuthClient.UserDelete(ctx, testUserName)
|
||||
require.NoError(t, err)
|
||||
|
||||
// get node0 auth revision
|
||||
aresp, err := rootAuthClient.AuthStatus(ctx)
|
||||
require.NoError(t, err)
|
||||
oldAuthRevision := aresp.AuthRevision
|
||||
|
||||
// restart the node
|
||||
clus.Members()[0].Stop()
|
||||
require.NoError(t, clus.Members()[0].Start(ctx))
|
||||
|
||||
aresp2, err := rootAuthClient.AuthStatus(ctx)
|
||||
require.NoError(t, err)
|
||||
newAuthRevision := aresp2.AuthRevision
|
||||
|
||||
require.Equal(t, oldAuthRevision, newAuthRevision)
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthTestCacheReload ensures permissions are persisted and will be reloaded after member restarts
|
||||
func TestAuthTestCacheReload(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
// create foo since that is within the permission set
|
||||
// expectation is to succeed
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
|
||||
// restart the node
|
||||
clus.Members()[0].Stop()
|
||||
require.NoError(t, clus.Members()[0].Start(ctx))
|
||||
|
||||
// nothing has changed, but it fails without refreshing cache after restart
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar2", config.PutOptions{}))
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthLeaseTimeToLive gated lease time to live with RBAC control
|
||||
func TestAuthLeaseTimeToLive(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
gresp, err := testUserAuthClient.Grant(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
leaseID := gresp.ID
|
||||
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{LeaseID: leaseID}))
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: true})
|
||||
require.NoError(t, err)
|
||||
|
||||
rootAuthClient := testutils.MustClient(clus.Client(WithAuth(rootUserName, rootPassword)))
|
||||
require.NoError(t, rootAuthClient.Put(ctx, "bar", "foo", config.PutOptions{LeaseID: leaseID}))
|
||||
|
||||
// the lease is attached to bar, which test-user cannot access
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: true})
|
||||
require.Errorf(t, err, "test-user must not be able to access to the lease, because it's attached to the key bar")
|
||||
|
||||
// without --keys, access should be allowed
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: false})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func mustAbsPath(path string) string {
|
||||
abs, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
|
@@ -124,7 +124,7 @@ func TestKVDelete(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
for _, tc := range clusterTestCases() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(tc.config))
|
||||
defer clus.Close()
|
||||
|
@@ -30,19 +30,30 @@ import (
|
||||
"go.etcd.io/etcd/api/v3/version"
|
||||
"go.etcd.io/etcd/client/pkg/v3/fileutil"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/snap"
|
||||
"go.etcd.io/etcd/server/v3/storage/datadir"
|
||||
"go.etcd.io/etcd/tests/v3/framework/config"
|
||||
"go.etcd.io/etcd/tests/v3/framework/e2e"
|
||||
"go.etcd.io/etcd/tests/v3/framework/testutils"
|
||||
)
|
||||
|
||||
func TestDowngradeUpgradeClusterOf1(t *testing.T) {
|
||||
testDowngradeUpgrade(t, 1)
|
||||
testDowngradeUpgrade(t, 1, false)
|
||||
}
|
||||
|
||||
func TestDowngradeUpgradeClusterOf3(t *testing.T) {
|
||||
testDowngradeUpgrade(t, 3)
|
||||
testDowngradeUpgrade(t, 3, false)
|
||||
}
|
||||
|
||||
func testDowngradeUpgrade(t *testing.T, clusterSize int) {
|
||||
func TestDowngradeUpgradeClusterOf1WithSnapshot(t *testing.T) {
|
||||
testDowngradeUpgrade(t, 1, true)
|
||||
}
|
||||
|
||||
func TestDowngradeUpgradeClusterOf3WithSnapshot(t *testing.T) {
|
||||
testDowngradeUpgrade(t, 3, true)
|
||||
}
|
||||
|
||||
func testDowngradeUpgrade(t *testing.T, clusterSize int, triggerSnapshot bool) {
|
||||
currentEtcdBinary := e2e.BinPath.Etcd
|
||||
lastReleaseBinary := e2e.BinPath.EtcdLastRelease
|
||||
if !fileutil.Exist(lastReleaseBinary) {
|
||||
@@ -68,7 +79,8 @@ func testDowngradeUpgrade(t *testing.T, clusterSize int) {
|
||||
e2e.BeforeTest(t)
|
||||
|
||||
t.Logf("Create cluster with version %s", currentVersionStr)
|
||||
epc := newCluster(t, clusterSize)
|
||||
var snapshotCount uint64 = 10
|
||||
epc := newCluster(t, clusterSize, snapshotCount)
|
||||
for i := 0; i < len(epc.Procs); i++ {
|
||||
validateVersion(t, epc.Cfg, epc.Procs[i], version.Versions{
|
||||
Cluster: currentVersionStr,
|
||||
@@ -77,6 +89,11 @@ func testDowngradeUpgrade(t *testing.T, clusterSize int) {
|
||||
})
|
||||
}
|
||||
t.Logf("Cluster created")
|
||||
if triggerSnapshot {
|
||||
t.Logf("Generating snapshot")
|
||||
generateSnapshot(t, snapshotCount, epc)
|
||||
}
|
||||
bm, bkv := getMembersAndKeys(t, epc)
|
||||
|
||||
t.Logf("etcdctl downgrade enable %s", lastVersionStr)
|
||||
downgradeEnable(t, epc, lastVersion)
|
||||
@@ -109,6 +126,10 @@ func testDowngradeUpgrade(t *testing.T, clusterSize int) {
|
||||
}
|
||||
|
||||
t.Log("Downgrade complete")
|
||||
am, akv := getMembersAndKeys(t, epc)
|
||||
assert.Equal(t, bkv.Kvs, akv.Kvs)
|
||||
assert.Equal(t, bm.Members, am.Members)
|
||||
|
||||
t.Logf("Starting upgrade process to %q", currentVersionStr)
|
||||
for i := 0; i < len(epc.Procs); i++ {
|
||||
t.Logf("Upgrading member %d", i)
|
||||
@@ -130,9 +151,10 @@ func testDowngradeUpgrade(t *testing.T, clusterSize int) {
|
||||
t.Log("Upgrade complete")
|
||||
}
|
||||
|
||||
func newCluster(t *testing.T, clusterSize int) *e2e.EtcdProcessCluster {
|
||||
func newCluster(t *testing.T, clusterSize int, snapshotCount uint64) *e2e.EtcdProcessCluster {
|
||||
epc, err := e2e.NewEtcdProcessCluster(context.TODO(), t,
|
||||
e2e.WithClusterSize(clusterSize),
|
||||
e2e.WithSnapshotCount(snapshotCount),
|
||||
e2e.WithKeepDataDir(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -155,8 +177,7 @@ func startEtcd(t *testing.T, ep e2e.EtcdProcess, execPath string) {
|
||||
}
|
||||
|
||||
func downgradeEnable(t *testing.T, epc *e2e.EtcdProcessCluster, ver *semver.Version) {
|
||||
c, err := e2e.NewEtcdctl(epc.Cfg.Client, epc.EndpointsGRPC())
|
||||
assert.NoError(t, err)
|
||||
c := epc.Etcdctl()
|
||||
testutils.ExecuteWithTimeout(t, 20*time.Second, func() {
|
||||
err := c.DowngradeEnable(context.TODO(), ver.String())
|
||||
if err != nil {
|
||||
@@ -245,3 +266,45 @@ func getMemberVersionByCurl(cfg *e2e.EtcdProcessClusterConfig, member e2e.EtcdPr
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func generateSnapshot(t *testing.T, snapshotCount uint64, epc *e2e.EtcdProcessCluster) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
cc, err := e2e.NewEtcdctl(epc.Cfg.Client, epc.EndpointsGRPC())
|
||||
assert.NoError(t, err)
|
||||
|
||||
var i uint64
|
||||
t.Logf("Adding keys")
|
||||
for i = 0; i < snapshotCount*3; i++ {
|
||||
err := cc.Put(ctx, fmt.Sprintf("%d", i), "1", config.PutOptions{})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
verifySnapshot(t, epc)
|
||||
}
|
||||
|
||||
func verifySnapshot(t *testing.T, epc *e2e.EtcdProcessCluster) {
|
||||
for i := range epc.Procs {
|
||||
t.Logf("Verifying snapshot for member %d", i)
|
||||
ss := snap.New(epc.Cfg.Logger, datadir.ToSnapDir(epc.Procs[i].Config().DataDirPath))
|
||||
_, err := ss.Load()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
t.Logf("All members have a valid snapshot")
|
||||
}
|
||||
|
||||
func getMembersAndKeys(t *testing.T, epc *e2e.EtcdProcessCluster) (*clientv3.MemberListResponse, *clientv3.GetResponse) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
cc, err := e2e.NewEtcdctl(epc.Cfg.Client, epc.EndpointsGRPC())
|
||||
assert.NoError(t, err)
|
||||
|
||||
kvs, err := cc.Get(ctx, "", config.GetOptions{Prefix: true})
|
||||
assert.NoError(t, err)
|
||||
|
||||
members, err := cc.MemberList(ctx, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
return members, kvs
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
@@ -116,9 +117,7 @@ func TestPeriodicCheckDetectsCorruption(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
cc, err := e2e.NewEtcdctl(epc.Cfg.Client, epc.EndpointsGRPC())
|
||||
assert.NoError(t, err)
|
||||
|
||||
cc := epc.Etcdctl()
|
||||
for i := 0; i < 10; i++ {
|
||||
err := cc.Put(ctx, testutil.PickKey(int64(i)), fmt.Sprint(i), config.PutOptions{})
|
||||
assert.NoError(t, err, "error on put")
|
||||
@@ -164,9 +163,7 @@ func TestCompactHashCheckDetectCorruption(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
cc, err := e2e.NewEtcdctl(epc.Cfg.Client, epc.EndpointsGRPC())
|
||||
assert.NoError(t, err)
|
||||
|
||||
cc := epc.Etcdctl()
|
||||
for i := 0; i < 10; i++ {
|
||||
err := cc.Put(ctx, testutil.PickKey(int64(i)), fmt.Sprint(i), config.PutOptions{})
|
||||
assert.NoError(t, err, "error on put")
|
||||
@@ -193,3 +190,80 @@ func TestCompactHashCheckDetectCorruption(t *testing.T) {
|
||||
assert.NoError(t, err, "error on alarm list")
|
||||
assert.Equal(t, []*etcdserverpb.AlarmMember{{Alarm: etcdserverpb.AlarmType_CORRUPT, MemberID: memberID}}, alarmResponse.Alarms)
|
||||
}
|
||||
|
||||
func TestCompactHashCheckDetectCorruptionInterrupt(t *testing.T) {
|
||||
checkTime := time.Second
|
||||
e2e.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
slowCompactionNodeIndex := 1
|
||||
|
||||
// Start a new cluster, with compact hash check enabled.
|
||||
t.Log("creating a new cluster with 3 nodes...")
|
||||
|
||||
dataDirPath := t.TempDir()
|
||||
cfg := e2e.NewConfig(
|
||||
e2e.WithKeepDataDir(true),
|
||||
e2e.WithCompactHashCheckEnabled(true),
|
||||
e2e.WithCompactHashCheckTime(checkTime),
|
||||
e2e.WithClusterSize(3),
|
||||
e2e.WithDataDirPath(dataDirPath),
|
||||
e2e.WithLogLevel("info"),
|
||||
)
|
||||
epc, err := e2e.InitEtcdProcessCluster(t, cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assign a node a very slow compaction speed, so that its compaction can be interrupted.
|
||||
err = epc.UpdateProcOptions(slowCompactionNodeIndex, t,
|
||||
e2e.WithCompactionBatchLimit(1),
|
||||
e2e.WithCompactionSleepInterval(1*time.Hour),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
epc, err = e2e.StartEtcdProcessCluster(ctx, epc, cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if errC := epc.Close(); errC != nil {
|
||||
t.Fatalf("error closing etcd processes (%v)", errC)
|
||||
}
|
||||
})
|
||||
|
||||
// Put 10 identical keys to the cluster, so that the compaction will drop some stale values.
|
||||
t.Log("putting 10 values to the identical key...")
|
||||
cc := epc.Etcdctl()
|
||||
for i := 0; i < 10; i++ {
|
||||
err := cc.Put(ctx, "key", fmt.Sprint(i), config.PutOptions{})
|
||||
require.NoError(t, err, "error on put")
|
||||
}
|
||||
|
||||
t.Log("compaction started...")
|
||||
_, err = cc.Compact(ctx, 5, config.CompactOption{})
|
||||
|
||||
err = epc.Procs[slowCompactionNodeIndex].Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = epc.UpdateProcOptions(slowCompactionNodeIndex, t)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Logf("restart proc %d to interrupt its compaction...", slowCompactionNodeIndex)
|
||||
err = epc.Procs[slowCompactionNodeIndex].Restart(ctx)
|
||||
|
||||
// Wait until the node finished compaction and the leader finished compaction hash check
|
||||
_, err = epc.Procs[slowCompactionNodeIndex].Logs().ExpectWithContext(ctx, "finished scheduled compaction")
|
||||
require.NoError(t, err, "can't get log indicating finished scheduled compaction")
|
||||
|
||||
leaderIndex := epc.WaitLeader(t)
|
||||
_, err = epc.Procs[leaderIndex].Logs().ExpectWithContext(ctx, "finished compaction hash check")
|
||||
require.NoError(t, err, "can't get log indicating finished compaction hash check")
|
||||
|
||||
alarmResponse, err := cc.AlarmList(ctx)
|
||||
require.NoError(t, err, "error on alarm list")
|
||||
for _, alarm := range alarmResponse.Alarms {
|
||||
if alarm.Alarm == etcdserverpb.AlarmType_CORRUPT {
|
||||
t.Fatal("there should be no corruption after resuming the compaction, but corruption detected")
|
||||
}
|
||||
}
|
||||
t.Log("no corruption detected.")
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user