Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[openshift-4.4] Bug 1815637: bump etcd v3.3.19 #40

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
95095f8
etcdserver: Remove infinite loop in doSerialize
horkhe Oct 26, 2018
5a48217
etcdserver: remove auth validation loop
jingyih Feb 12, 2019
e1508f9
integration: disable TestV3AuthOldRevConcurrent
jingyih Oct 26, 2019
70853d6
Merge pull request #11378 from jingyih/automated-cherry-pick-of-#1021…
mitake Jan 25, 2020
b3d9e29
mvcc/backend: Delete orphaned db.tmp files before defrag
jpbetz Feb 12, 2020
b0a4038
Merge pull request #11623 from jpbetz/automated-cherry-pick-of-#11613…
wenjiaswe Feb 13, 2020
7b1a92c
mvcc/backend: check for nil boltOpenOptions
jingyih Feb 15, 2020
e21e355
Merge pull request #11632 from jingyih/automated-cherry-pick-of-#1163…
jingyih Feb 16, 2020
c58133b
etcdctl: fix member add command
jingyih Feb 19, 2020
eb1df6d
Merge pull request #11665 from jingyih/automated-cherry-pick-of-#1163…
spzala Mar 11, 2020
1228d6c
proxy/grpcproxy: add return on error for metrics handler
hexfusion Mar 13, 2020
30aaceb
etcdserver/api/etcdhttp: log server-side /health checks
gyuho Mar 18, 2020
6f7ee07
clientv3: embed api version in metadata
gyuho Mar 18, 2020
d9027ce
etcdserver/api/v3rpc: handle api version metadata, add metrics
gyuho Mar 18, 2020
f9c8920
version: 3.3.19
gyuho Mar 18, 2020
10d50e0
words: whitelist "hasleader"
gyuho Mar 18, 2020
07562e2
Revert "version: 3.3.19"
gyuho Mar 19, 2020
acb9746
version: 3.3.19
gyuho Mar 19, 2020
5088080
travis.yaml: use Go 1.12.12
gyuho Mar 19, 2020
cd200b4
Revert "version: 3.3.19"
gyuho Mar 19, 2020
a463bd5
words: whitelist "racey"
gyuho Mar 19, 2020
67da93f
version: 3.3.19
gyuho Mar 19, 2020
a0dea6c
version: openshift-v4.0
hexfusion Nov 29, 2018
591fe54
Dockerfile: add etcdctl
hexfusion Feb 20, 2019
7c7740d
Dockerfile.*: Fix "etcd is distributed" -> "etcd is a distributed"
wking Feb 7, 2019
9454789
Dockerfile: resolve issue where binary was not properly copied from b…
hexfusion Feb 20, 2019
776a510
OWNERS: add
hexfusion May 5, 2019
5cebeac
Dockerfile: set coreos org as canonical for release-3.3
hexfusion May 4, 2019
d0577f9
Dockerfile: bump golang to 1.11
hexfusion Jul 9, 2019
9ebb43b
Dockerfile: use build instead of make build
hexfusion Aug 29, 2019
3d88216
Dockerfile: bump golang 1.12
hexfusion Sep 23, 2019
b7641a7
add stub discovery-etcd-initial-cluster command
deads2k Feb 20, 2020
02f1808
build openshift tools with etcd
deads2k Feb 20, 2020
8cf43a7
codify the initial cluster check as golang code
deads2k Feb 20, 2020
8eaefdf
Archive data-dir if target member is unstarted
Feb 23, 2020
ab0737a
fix removed member name, unmask error
alaypatel07 Feb 27, 2020
c02fb94
If we weren't able to get client or get target member but memberDir e…
Feb 28, 2020
b44f57e
list all peers in initial-cluster
deads2k Mar 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
.git
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sudo: required
services: docker

go:
- 1.12.9
- 1.12.12

env:
- GO111MODULE=on
Expand All @@ -28,7 +28,7 @@ env:
matrix:
fast_finish: true
allow_failures:
- go: 1.12.9
- go: 1.12.12
env: TARGET=linux-386-unit

install:
Expand Down
2 changes: 2 additions & 0 deletions .words
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ healthcheck
iff
inflight
keepalive
hasleader
racey
keepalives
keyspace
linearization
Expand Down
20 changes: 20 additions & 0 deletions Dockerfile.openshift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM registry.svc.ci.openshift.org/openshift/release:golang-1.12 AS builder

WORKDIR /go/src/github.com/coreos/etcd

COPY . .

RUN ./build

# stage 2
FROM registry.svc.ci.openshift.org/openshift/origin-v4.0:base

ENTRYPOINT ["/usr/bin/etcd"]

COPY --from=builder /go/src/github.com/coreos/etcd/bin/etcd /usr/bin/
COPY --from=builder /go/src/github.com/coreos/etcd/bin/etcdctl /usr/bin/
COPY --from=builder /go/src/github.com/coreos/etcd/bin/discover-etcd-initial-cluster /usr/bin/

LABEL io.k8s.display-name="etcd server" \
io.k8s.description="etcd is a distributed key-value store which stores the persistent master state for Kubernetes and OpenShift." \
maintainer="Sam Batschelet <sbatsche@redhat.com>"
20 changes: 20 additions & 0 deletions Dockerfile.rhel
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM openshift/golang-builder:1.12 AS builder

WORKDIR /go/src/github.com/coreos/etcd

COPY . .

RUN ./build

# stage 2
FROM openshift/origin-base

ENTRYPOINT ["/usr/bin/etcd"]

COPY --from=builder /go/src/github.com/coreos/etcd/bin/etcd /usr/bin/
COPY --from=builder /go/src/github.com/coreos/etcd/bin/etcdctl /usr/bin/
COPY --from=builder /go/src/github.com/coreos/etcd/bin/discover-etcd-initial-cluster /usr/bin/

LABEL io.k8s.display-name="etcd server" \
io.k8s.description="etcd is a distributed key-value store which stores the persistent master state for Kubernetes and OpenShift." \
maintainer="Sam Batschelet <sbatsche@redhat.com>"
8 changes: 8 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
approvers:
- hexfusion
reviewers:
- deads2k
- crawford
- hexfusion
- smarterclayton
- wking
15 changes: 15 additions & 0 deletions build
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ etcd_build() {
-o "${out}/etcdctl" ${REPO_PATH}/etcdctl || return
}


openshift_tools_build() {
out="bin"
if [[ -n "${BINDIR}" ]]; then out="${BINDIR}"; fi
toggle_failpoints_default

# Static compilation is useful when etcd is run in a container. $GO_BUILD_FLAGS is OK
# shellcheck disable=SC2086
CGO_ENABLED=0 go build $GO_BUILD_FLAGS \
-installsuffix cgo \
-ldflags "$GO_LDFLAGS" \
-o "${out}/discover-etcd-initial-cluster" "github.com/coreos/etcd/openshift-tools/discover-etcd-initial-cluster" || return
}

tools_build() {
out="bin"
if [[ -n "${BINDIR}" ]]; then out="${BINDIR}"; fi
Expand Down Expand Up @@ -91,4 +105,5 @@ fi
# only build when called directly, not sourced
if echo "$0" | grep "build$" >/dev/null; then
etcd_build
openshift_tools_build
fi
8 changes: 0 additions & 8 deletions clientv3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import (
"google.golang.org/grpc/codes"
grpccredentials "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)

Expand Down Expand Up @@ -393,13 +392,6 @@ func (c *Client) dialWithBalancerCreds(ep string) grpccredentials.TransportCrede
return creds
}

// WithRequireLeader requires client requests to only succeed
// when the cluster has a leader.
func WithRequireLeader(ctx context.Context) context.Context {
md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
return metadata.NewOutgoingContext(ctx, md)
}

func newClient(cfg *Config) (*Client, error) {
if cfg == nil {
cfg = &Config{}
Expand Down
64 changes: 64 additions & 0 deletions clientv3/ctx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2020 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 clientv3

import (
"context"
"strings"

"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
"github.com/coreos/etcd/version"
"google.golang.org/grpc/metadata"
)

// WithRequireLeader requires client requests to only succeed
// when the cluster has a leader.
func WithRequireLeader(ctx context.Context) context.Context {
md, ok := metadata.FromOutgoingContext(ctx)
if !ok { // no outgoing metadata ctx key, create one
md = metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
return metadata.NewOutgoingContext(ctx, md)
}
copied := md.Copy() // avoid racey updates
// overwrite/add 'hasleader' key/value
metadataSet(copied, rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
return metadata.NewOutgoingContext(ctx, copied)
}

// embeds client version
func withVersion(ctx context.Context) context.Context {
md, ok := metadata.FromOutgoingContext(ctx)
if !ok { // no outgoing metadata ctx key, create one
md = metadata.Pairs(rpctypes.MetadataClientAPIVersionKey, version.APIVersion)
return metadata.NewOutgoingContext(ctx, md)
}
copied := md.Copy() // avoid racey updates
// overwrite/add version key/value
metadataSet(copied, rpctypes.MetadataClientAPIVersionKey, version.APIVersion)
return metadata.NewOutgoingContext(ctx, copied)
}

func metadataGet(md metadata.MD, k string) []string {
k = strings.ToLower(k)
return md[k]
}

func metadataSet(md metadata.MD, k string, vals ...string) {
if len(vals) == 0 {
return
}
k = strings.ToLower(k)
md[k] = vals
}
67 changes: 67 additions & 0 deletions clientv3/ctx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2020 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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 clientv3

import (
"context"
"reflect"
"testing"

"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
"github.com/coreos/etcd/version"
"google.golang.org/grpc/metadata"
)

func TestMetadataWithRequireLeader(t *testing.T) {
ctx := context.TODO()
md, ok := metadata.FromOutgoingContext(ctx)
if ok {
t.Fatal("expected no outgoing metadata ctx key")
}

// add a conflicting key with some other value
md = metadata.Pairs(rpctypes.MetadataRequireLeaderKey, "invalid")
// add a key, and expect not be overwritten
metadataSet(md, "hello", "1", "2")
ctx = metadata.NewOutgoingContext(ctx, md)

// expect overwrites but still keep other keys
ctx = WithRequireLeader(ctx)
md, ok = metadata.FromOutgoingContext(ctx)
if !ok {
t.Fatal("expected outgoing metadata ctx key")
}
if ss := metadataGet(md, rpctypes.MetadataRequireLeaderKey); !reflect.DeepEqual(ss, []string{rpctypes.MetadataHasLeader}) {
t.Fatalf("unexpected metadata for %q %v", rpctypes.MetadataRequireLeaderKey, ss)
}
if ss := metadataGet(md, "hello"); !reflect.DeepEqual(ss, []string{"1", "2"}) {
t.Fatalf("unexpected metadata for 'hello' %v", ss)
}
}

func TestMetadataWithClientAPIVersion(t *testing.T) {
ctx := withVersion(WithRequireLeader(context.TODO()))

md, ok := metadata.FromOutgoingContext(ctx)
if !ok {
t.Fatal("expected outgoing metadata ctx key")
}
if ss := metadataGet(md, rpctypes.MetadataRequireLeaderKey); !reflect.DeepEqual(ss, []string{rpctypes.MetadataHasLeader}) {
t.Fatalf("unexpected metadata for %q %v", rpctypes.MetadataRequireLeaderKey, ss)
}
if ss := metadataGet(md, rpctypes.MetadataClientAPIVersionKey); !reflect.DeepEqual(ss, []string{version.APIVersion}) {
t.Fatalf("unexpected metadata for %q %v", rpctypes.MetadataClientAPIVersionKey, ss)
}
}
2 changes: 2 additions & 0 deletions clientv3/retry_interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
func (c *Client) unaryClientInterceptor(logger *zap.Logger, optFuncs ...retryOption) grpc.UnaryClientInterceptor {
intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
ctx = withVersion(ctx)
grpcOpts, retryOpts := filterCallOptions(opts)
callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)
// short circuit for simplicity, and avoiding allocations.
Expand Down Expand Up @@ -103,6 +104,7 @@ func (c *Client) unaryClientInterceptor(logger *zap.Logger, optFuncs ...retryOpt
func (c *Client) streamClientInterceptor(logger *zap.Logger, optFuncs ...retryOption) grpc.StreamClientInterceptor {
intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
ctx = withVersion(ctx)
grpcOpts, retryOpts := filterCallOptions(opts)
callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)
// short circuit for simplicity, and avoiding allocations.
Expand Down
24 changes: 1 addition & 23 deletions etcdctl/ctlv3/command/member_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,30 +118,8 @@ func memberAddCommandFunc(cmd *cobra.Command, args []string) {
display.MemberAdd(*resp)

if _, ok := (display).(*simplePrinter); ok {
ctx, cancel = commandCtx(cmd)
listResp, err := cli.MemberList(ctx)
// make sure the member who served member list request has the latest member list.
syncedMemberSet := make(map[uint64]struct{})
syncedMemberSet[resp.Header.MemberId] = struct{}{} // the member who served member add is guaranteed to have the latest member list.
for {
if err != nil {
ExitWithError(ExitError, err)
}
if _, ok := syncedMemberSet[listResp.Header.MemberId]; ok {
break
}
// quorum get to sync cluster list
gresp, gerr := cli.Get(ctx, "_")
if gerr != nil {
ExitWithError(ExitError, err)
}
syncedMemberSet[gresp.Header.MemberId] = struct{}{}
listResp, err = cli.MemberList(ctx)
}
cancel()

conf := []string{}
for _, memb := range listResp.Members {
for _, memb := range resp.Members {
for _, u := range memb.PeerURLs {
n := memb.Name
if memb.ID == newID {
Expand Down
7 changes: 7 additions & 0 deletions etcdserver/api/etcdhttp/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func NewHealthHandler(hfunc func() Health) http.HandlerFunc {
if r.Method != http.MethodGet {
w.Header().Set("Allow", http.MethodGet)
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
plog.Warningf("/health error (status code %d)", http.StatusMethodNotAllowed)
return
}
h := hfunc()
Expand Down Expand Up @@ -97,11 +98,15 @@ func checkHealth(srv etcdserver.ServerV2) Health {
as := srv.Alarms()
if len(as) > 0 {
h.Health = "false"
for _, v := range as {
plog.Warningf("/health error due to an alarm %s", v.String())
}
}

if h.Health == "true" {
if uint64(srv.Leader()) == raft.None {
h.Health = "false"
plog.Warningf("/health error; no leader (status code %d)", http.StatusServiceUnavailable)
}
}

Expand All @@ -111,11 +116,13 @@ func checkHealth(srv etcdserver.ServerV2) Health {
cancel()
if err != nil {
h.Health = "false"
plog.Warningf("/health error; QGET failed %v (status code %d)", err, http.StatusServiceUnavailable)
}
}

if h.Health == "true" {
healthSuccess.Inc()
plog.Infof("/health OK (status code %d)", http.StatusOK)
} else {
healthFailed.Inc()
}
Expand Down
Loading