Skip to content

Commit f5fb02c

Browse files
Merge pull request #531 from stevekuznetsov/skuznets/update-olm
OCPBUGS-17157: sync
2 parents d98ec8b + f41c684 commit f5fb02c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+579
-92
lines changed

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37
1414
github.com/onsi/ginkgo/v2 v2.9.5
1515
github.com/openshift/api v3.9.0+incompatible
16-
github.com/operator-framework/api v0.17.7
16+
github.com/operator-framework/api v0.17.8-0.20230803152844-704ae942c4a9
1717
github.com/operator-framework/operator-lifecycle-manager v0.0.0-00010101000000-000000000000
1818
github.com/operator-framework/operator-registry v1.27.1
1919
github.com/sirupsen/logrus v1.9.2
@@ -68,7 +68,7 @@ require (
6868
github.com/distribution/distribution v2.7.1+incompatible // indirect
6969
github.com/docker/cli v23.0.1+incompatible // indirect
7070
github.com/docker/distribution v2.8.2+incompatible // indirect
71-
github.com/docker/docker v23.0.1+incompatible // indirect
71+
github.com/docker/docker v23.0.3+incompatible // indirect
7272
github.com/docker/docker-credential-helpers v0.7.0 // indirect
7373
github.com/docker/go-connections v0.4.0 // indirect
7474
github.com/docker/go-metrics v0.0.1 // indirect

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy
185185
github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
186186
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d h1:jC8tT/S0OGx2cswpeUTn4gOIea8P08lD3VFQT0cOZ50=
187187
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
188-
github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY=
189-
github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
188+
github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
189+
github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
190190
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
191191
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
192192
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=

manifests/0000_50_olm_00-catalogsources.crd.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,13 @@ spec:
534534
topologyKey:
535535
description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.
536536
type: string
537+
memoryTarget:
538+
description: "MemoryTarget configures the $GOMEMLIMIT value for the gRPC catalog Pod. This is a soft memory limit for the server, which the runtime will attempt to meet but makes no guarantees that it will do so. If this value is set, the Pod will have the following modifications made to the container running the server: - the $GOMEMLIMIT environment variable will be set to this value in bytes - the memory request will be set to this value - the memory limit will be set to 200% of this value \n This field should be set if it's desired to reduce the footprint of a catalog server as much as possible, or if a catalog being served is very large and needs more than the default allocation. If your index image has a file- system cache, determine a good approximation for this value by doubling the size of the package cache at /tmp/cache/cache/packages.json in the index image. \n This field is best-effort; if unset, no default will be used and no Pod memory limit or $GOMEMLIMIT value will be set."
539+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
540+
anyOf:
541+
- type: integer
542+
- type: string
543+
x-kubernetes-int-or-string: true
537544
nodeSelector:
538545
description: NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node.
539546
type: object

staging/api/.github/workflows/go.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
- uses: codecov/codecov-action@v3
3434
with:
3535
files: cover.out
36-
fail_ci_if_error: true
3736
functionalities: fixes
3837

3938
go-apidiff:

staging/api/crds/operators.coreos.com_catalogsources.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,13 @@ spec:
532532
topologyKey:
533533
description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.
534534
type: string
535+
memoryTarget:
536+
description: "MemoryTarget configures the $GOMEMLIMIT value for the gRPC catalog Pod. This is a soft memory limit for the server, which the runtime will attempt to meet but makes no guarantees that it will do so. If this value is set, the Pod will have the following modifications made to the container running the server: - the $GOMEMLIMIT environment variable will be set to this value in bytes - the memory request will be set to this value - the memory limit will be set to 200% of this value \n This field should be set if it's desired to reduce the footprint of a catalog server as much as possible, or if a catalog being served is very large and needs more than the default allocation. If your index image has a file- system cache, determine a good approximation for this value by doubling the size of the package cache at /tmp/cache/cache/packages.json in the index image. \n This field is best-effort; if unset, no default will be used and no Pod memory limit or $GOMEMLIMIT value will be set."
537+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
538+
anyOf:
539+
- type: integer
540+
- type: string
541+
x-kubernetes-int-or-string: true
535542
nodeSelector:
536543
description: NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node.
537544
type: object

staging/api/crds/zz_defs.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/api/pkg/operators/v1alpha1/catalogsource_types.go

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/sirupsen/logrus"
99
corev1 "k8s.io/api/core/v1"
10+
"k8s.io/apimachinery/pkg/api/resource"
1011
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1112
"k8s.io/apimachinery/pkg/types"
1213
)
@@ -145,6 +146,21 @@ type GrpcPodConfig struct {
145146
// +kubebuilder:validation:Enum=legacy;restricted
146147
// +kubebuilder:default:=legacy
147148
SecurityContextConfig SecurityConfig `json:"securityContextConfig,omitempty"`
149+
150+
// MemoryTarget configures the $GOMEMLIMIT value for the gRPC catalog Pod. This is a soft memory limit for the server,
151+
// which the runtime will attempt to meet but makes no guarantees that it will do so. If this value is set, the Pod
152+
// will have the following modifications made to the container running the server:
153+
// - the $GOMEMLIMIT environment variable will be set to this value in bytes
154+
// - the memory request will be set to this value
155+
// - the memory limit will be set to 200% of this value
156+
//
157+
// This field should be set if it's desired to reduce the footprint of a catalog server as much as possible, or if
158+
// a catalog being served is very large and needs more than the default allocation. If your index image has a file-
159+
// system cache, determine a good approximation for this value by doubling the size of the package cache at
160+
// /tmp/cache/cache/packages.json in the index image.
161+
//
162+
// This field is best-effort; if unset, no default will be used and no Pod memory limit or $GOMEMLIMIT value will be set.
163+
MemoryTarget *resource.Quantity `json:"memoryTarget,omitempty"`
148164
}
149165

150166
// UpdateStrategy holds all the different types of catalog source update strategies

staging/api/pkg/operators/v1alpha1/clusterserviceversion.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,19 @@ func (c *ClusterServiceVersion) IsObsolete() bool {
120120

121121
// IsCopied returns true if the CSV has been copied and false otherwise.
122122
func (c *ClusterServiceVersion) IsCopied() bool {
123-
operatorNamespace, ok := c.GetAnnotations()[OperatorGroupNamespaceAnnotationKey]
124-
if c.Status.Reason == CSVReasonCopied || ok && c.GetNamespace() != operatorNamespace {
125-
return true
123+
return c.Status.Reason == CSVReasonCopied || IsCopied(c)
124+
}
125+
126+
func IsCopied(o metav1.Object) bool {
127+
annotations := o.GetAnnotations()
128+
if annotations != nil {
129+
operatorNamespace, ok := annotations[OperatorGroupNamespaceAnnotationKey]
130+
if ok && o.GetNamespace() != operatorNamespace {
131+
return true
132+
}
126133
}
127134

128-
if labels := c.GetLabels(); labels != nil {
135+
if labels := o.GetLabels(); labels != nil {
129136
if _, ok := labels[CopiedLabelKey]; ok {
130137
return true
131138
}

staging/api/pkg/operators/v1alpha1/clusterserviceversion_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,68 @@ func helperNewConditions(count int) []ClusterServiceVersionCondition {
430430

431431
return conditions
432432
}
433+
434+
func TestIsCopied(t *testing.T) {
435+
var testCases = []struct {
436+
name string
437+
input metav1.Object
438+
expected bool
439+
}{
440+
{
441+
name: "no labels or annotations",
442+
input: &metav1.ObjectMeta{},
443+
expected: false,
444+
},
445+
{
446+
name: "no labels, has annotations but missing operatorgroup namespace annotation",
447+
input: &metav1.ObjectMeta{
448+
Annotations: map[string]string{},
449+
},
450+
expected: false,
451+
},
452+
{
453+
name: "no labels, has operatorgroup namespace annotation matching self",
454+
input: &metav1.ObjectMeta{
455+
Namespace: "whatever",
456+
Annotations: map[string]string{
457+
"olm.operatorNamespace": "whatever",
458+
},
459+
},
460+
expected: false,
461+
},
462+
{
463+
name: "no labels, has operatorgroup namespace annotation not matching self",
464+
input: &metav1.ObjectMeta{
465+
Namespace: "whatever",
466+
Annotations: map[string]string{
467+
"olm.operatorNamespace": "other",
468+
},
469+
},
470+
expected: true,
471+
},
472+
{
473+
name: "no annotations, labels missing copied key",
474+
input: &metav1.ObjectMeta{
475+
Labels: map[string]string{},
476+
},
477+
expected: false,
478+
},
479+
{
480+
name: "no annotations, labels has copied key",
481+
input: &metav1.ObjectMeta{
482+
Labels: map[string]string{
483+
"olm.copiedFrom": "whatever",
484+
},
485+
},
486+
expected: true,
487+
},
488+
}
489+
490+
for _, testCase := range testCases {
491+
t.Run(testCase.name, func(t *testing.T) {
492+
if got, expected := IsCopied(testCase.input), testCase.expected; got != expected {
493+
t.Errorf("got %v, expected %v", got, expected)
494+
}
495+
})
496+
}
497+
}

staging/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/api/pkg/validation/internal/csv.go

+15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"encoding/json"
55
"fmt"
6+
"github.com/blang/semver/v4"
67
"io"
78
"reflect"
89
"strings"
@@ -45,6 +46,8 @@ func validateCSV(csv *v1alpha1.ClusterServiceVersion) errors.ManifestResult {
4546
result.Add(validateExamplesAnnotations(csv)...)
4647
// validate installModes
4748
result.Add(validateInstallModes(csv)...)
49+
// validate min Kubernetes version
50+
result.Add(validateMinKubeVersion(*csv)...)
4851
// check missing optional/mandatory fields.
4952
result.Add(checkFields(*csv)...)
5053
// validate case sensitive annotation names
@@ -240,3 +243,15 @@ func validateVersionKind(csv *v1alpha1.ClusterServiceVersion) (errs []errors.Err
240243
}
241244
return
242245
}
246+
247+
// validateMinKubeVersion checks format of spec.minKubeVersion field
248+
func validateMinKubeVersion(csv v1alpha1.ClusterServiceVersion) (errs []errors.Error) {
249+
if len(strings.TrimSpace(csv.Spec.MinKubeVersion)) == 0 {
250+
errs = append(errs, errors.WarnInvalidCSV(minKubeVersionWarnMessage, csv.GetName()))
251+
} else {
252+
if _, err := semver.Parse(csv.Spec.MinKubeVersion); err != nil {
253+
errs = append(errs, errors.ErrInvalidCSV(fmt.Sprintf("csv.Spec.MinKubeVersion has an invalid value: %s", csv.Spec.MinKubeVersion), csv.GetName()))
254+
}
255+
}
256+
return errs
257+
}

staging/api/pkg/validation/internal/csv_test.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import (
66
"path/filepath"
77
"testing"
88

9-
"github.com/ghodss/yaml"
109
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
10+
11+
"github.com/ghodss/yaml"
1112
"github.com/operator-framework/api/pkg/validation/errors"
1213
"k8s.io/apimachinery/pkg/runtime/schema"
1314
)
@@ -107,6 +108,16 @@ func TestValidateCSV(t *testing.T) {
107108
},
108109
filepath.Join("testdata", "correct.csv.olm.properties.annotation.yaml"),
109110
},
111+
{
112+
validatorFuncTest{
113+
description: "should fail when spec.minKubeVersion is not in semantic version format",
114+
wantErr: true,
115+
errors: []errors.Error{
116+
errors.ErrInvalidCSV(`csv.Spec.MinKubeVersion has an invalid value: 1.21`, "test-operator.v0.0.1"),
117+
},
118+
},
119+
filepath.Join("testdata", "invalid_min_kube_version.csv.yaml"),
120+
},
110121
}
111122

112123
for _, c := range cases {

staging/api/pkg/validation/internal/operatorhub.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func checkSpecMinKubeVersion(checks CSVChecks) CSVChecks {
240240
if len(strings.TrimSpace(checks.csv.Spec.MinKubeVersion)) == 0 {
241241
checks.warns = append(checks.warns, fmt.Errorf(minKubeVersionWarnMessage))
242242
} else {
243-
if _, err := semver.ParseTolerant(checks.csv.Spec.MinKubeVersion); err != nil {
243+
if _, err := semver.Parse(checks.csv.Spec.MinKubeVersion); err != nil {
244244
checks.errs = append(checks.errs, fmt.Errorf("csv.Spec.MinKubeVersion has an invalid value: %s", checks.csv.Spec.MinKubeVersion))
245245
}
246246
}

staging/api/pkg/validation/internal/operatorhub_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func TestCheckSpecMinKubeVersion(t *testing.T) {
218218
}{
219219
{
220220
name: "should work with a valid value",
221-
args: args{minKubeVersion: "1.16"},
221+
args: args{minKubeVersion: "1.16.0"},
222222
},
223223
{
224224
name: "should return a warning when the minKubeVersion is not informed ",

staging/api/pkg/validation/internal/testdata/badAnnotationNames.csv.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ metadata:
1414
alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
1515
description: etcd is a distributed key value store providing a reliable way to store data across a cluster of machines.
1616
spec:
17+
minKubeVersion: 1.21.0
1718
displayName: etcd
1819
description: |
1920
etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.

staging/api/pkg/validation/internal/testdata/badName.csv.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ metadata:
1111
alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
1212
description: etcd is a distributed key value store providing a reliable way to store data across a cluster of machines.
1313
spec:
14+
minKubeVersion: 1.21.0
1415
displayName: etcd
1516
description: something
1617
keywords: ['etcd', 'key value', 'database', 'coreos', 'open source']

staging/api/pkg/validation/internal/testdata/correct.csv.empty.example.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ metadata:
88
annotations:
99
"alm-examples": ""
1010
spec:
11+
minKubeVersion: 1.21.0
1112
version: 0.9.0
1213
installModes:
1314
- type: AllNamespaces

staging/api/pkg/validation/internal/testdata/correct.csv.olm.properties.annotation.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ metadata:
99
alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
1010
olm.properties: '[{"type": "foo", "value": "bar"}]'
1111
spec:
12+
minKubeVersion: 1.21.0
1213
version: 0.9.0
1314
installModes:
1415
- type: AllNamespaces

staging/api/pkg/validation/internal/testdata/correct.csv.with.conversion.webhook.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ metadata:
1111
alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
1212
description: etcd is a distributed key value store providing a reliable way to store data across a cluster of machines.
1313
spec:
14+
minKubeVersion: 1.21.0
1415
displayName: etcd
1516
description: |
1617
etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.

staging/api/pkg/validation/internal/testdata/correct.csv.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ metadata:
1111
alm-examples: '[{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]'
1212
description: etcd is a distributed key value store providing a reliable way to store data across a cluster of machines.
1313
spec:
14+
minKubeVersion: 1.21.0
1415
displayName: etcd
1516
description: |
1617
etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.

0 commit comments

Comments
 (0)