Skip to content

Commit 46b519a

Browse files
authored
[Bugfix] Fix LocalStorage WaitForFirstConsumer mode (#1219)
1 parent a9f82d2 commit 46b519a

File tree

17 files changed

+716
-103
lines changed

17 files changed

+716
-103
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- (Feature) Add tolerations runtime rotation
88
- (Feature) Promote Version Check Feature
99
- (Bugfix) Ensure PDBs Consistency
10+
- (Bugfix) Fix LocalStorage WaitForFirstConsumer mode
1011

1112
## [1.2.22](https://github.com/arangodb/kube-arangodb/tree/1.2.22) (2022-12-13)
1213
- (Bugfix) Do not manage ports in managed ExternalAccess mode

chart/kube-arangodb/templates/storage-operator/cluster-role.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ rules:
2020
verbs: ["get", "list", "watch"]
2121
- apiGroups: [""]
2222
resources: ["namespaces", "nodes"]
23-
verbs: ["get", "list"]
23+
verbs: ["get", "list", "watch"]
2424
- apiGroups: ["storage.k8s.io"]
2525
resources: ["storageclasses"]
2626
verbs: ["*"]

chart/kube-arangodb/templates/storage-operator/role.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ metadata:
1515
rules:
1616
- apiGroups: [""]
1717
resources: ["pods"]
18-
verbs: ["get", "update"]
18+
verbs: ["get", "update", "watch", "list"]
1919
- apiGroups: [""]
2020
resources: ["secrets"]
2121
verbs: ["get"]

pkg/apis/storage/v1alpha/local_storage_spec.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ package v1alpha
2323
import (
2424
"strings"
2525

26+
core "k8s.io/api/core/v1"
27+
2628
"github.com/arangodb/kube-arangodb/pkg/util/errors"
2729
)
2830

@@ -32,6 +34,7 @@ type LocalStorageSpec struct {
3234
StorageClass StorageClassSpec `json:"storageClass"`
3335
LocalPath []string `json:"localPath,omitempty"`
3436

37+
Tolerations []core.Toleration `json:"tolerations,omitempty"`
3538
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
3639
Privileged *bool `json:"privileged,omitempty"`
3740

pkg/apis/storage/v1alpha/zz_generated.deepcopy.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/generated/clientset/versioned/fake/register.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/generated/clientset/versioned/scheme/register.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/storage/clients.go

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,51 @@ package storage
2323
import (
2424
"context"
2525
"fmt"
26+
"time"
2627

2728
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner"
2829
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner/client"
2930
"github.com/arangodb/kube-arangodb/pkg/util/errors"
3031
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
3132
)
3233

34+
type Clients map[string]provisioner.API
35+
36+
func (c Clients) Copy() Clients {
37+
r := make(Clients, len(c))
38+
39+
for k, v := range c {
40+
r[k] = v
41+
}
42+
43+
return r
44+
}
45+
46+
func (c Clients) Filter(f func(node string, client provisioner.API) bool) Clients {
47+
r := make(Clients, len(c))
48+
49+
for k, v := range c {
50+
if f(k, v) {
51+
r[k] = v
52+
}
53+
}
54+
55+
return r
56+
}
57+
58+
func (c Clients) Keys() []string {
59+
r := make([]string, 0, len(c))
60+
61+
for k := range c {
62+
r = append(r, k)
63+
}
64+
65+
return r
66+
}
67+
3368
// createProvisionerClients creates a list of clients for all known
3469
// provisioners.
35-
func (ls *LocalStorage) createProvisionerClients() ([]provisioner.API, error) {
70+
func (ls *LocalStorage) createProvisionerClients(ctx context.Context) (Clients, error) {
3671
// Find provisioner endpoints
3772
ns := ls.apiObject.GetNamespace()
3873
listOptions := k8sutil.LocalStorageListOpt(ls.apiObject.GetName(), roleProvisioner)
@@ -46,31 +81,38 @@ func (ls *LocalStorage) createProvisionerClients() ([]provisioner.API, error) {
4681
return nil, nil
4782
}
4883
// Create clients for endpoints
49-
clients := make([]provisioner.API, len(addrs))
50-
for i, addr := range addrs {
51-
var err error
52-
clients[i], err = client.New(fmt.Sprintf("http://%s", addr))
84+
clients := make(map[string]provisioner.API, len(addrs))
85+
for _, addr := range addrs {
86+
c, err := client.New(fmt.Sprintf("http://%s", addr))
5387
if err != nil {
5488
return nil, errors.WithStack(err)
5589
}
90+
91+
if info, err := ls.fetchClientNodeInfo(ctx, c); err == nil {
92+
clients[info.NodeName] = c
93+
}
5694
}
5795
return clients, nil
5896
}
5997

98+
func (ls *LocalStorage) fetchClientNodeInfo(ctx context.Context, c provisioner.API) (provisioner.NodeInfo, error) {
99+
nctx, cancel := context.WithTimeout(ctx, 3*time.Second)
100+
defer cancel()
101+
return c.GetNodeInfo(nctx)
102+
}
103+
60104
// GetClientByNodeName looks for a client that serves the given node name.
61105
// Returns an error if no such client is found.
62-
func (ls *LocalStorage) GetClientByNodeName(nodeName string) (provisioner.API, error) {
63-
clients, err := ls.createProvisionerClients()
106+
func (ls *LocalStorage) GetClientByNodeName(ctx context.Context, nodeName string) (provisioner.API, error) {
107+
clients, err := ls.createProvisionerClients(ctx)
64108
if err != nil {
65109
return nil, errors.WithStack(err)
66110
}
67111

68112
// Find matching client
69-
for _, c := range clients {
70-
ctx := context.Background()
71-
if info, err := c.GetNodeInfo(ctx); err == nil && info.NodeName == nodeName {
72-
return c, nil
73-
}
113+
if c, ok := clients[nodeName]; ok {
114+
return c, nil
74115
}
116+
75117
return nil, errors.WithStack(errors.Newf("No client found for node name '%s'", nodeName))
76118
}

pkg/storage/daemon_set.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func (ls *LocalStorage) ensureDaemonSet(apiObject *api.ArangoLocalStorage) error
9494
NodeSelector: apiObject.Spec.NodeSelector,
9595
ImagePullSecrets: ls.imagePullSecrets,
9696
Priority: apiObject.Spec.PodCustomization.GetPriority(),
97+
Tolerations: apiObject.Spec.Tolerations,
9798
},
9899
},
99100
}
@@ -153,6 +154,7 @@ func (ls *LocalStorage) ensureDaemonSet(apiObject *api.ArangoLocalStorage) error
153154
// Update it
154155
current.Spec = dsSpec
155156
if _, err := ls.deps.Client.Kubernetes().AppsV1().DaemonSets(ns).Update(context.Background(), current, meta.UpdateOptions{}); kerrors.IsConflict(err) && attempt < 10 {
157+
ls.log.Err(err).Debug("failed to patch DaemonSet spec")
156158
// Failed to update, try again
157159
continue
158160
} else if err != nil {

pkg/storage/local_storage.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,11 @@ func (ls *LocalStorage) run() {
259259
}
260260
if createNow {
261261
ctx := context.Background()
262-
if err := ls.createPVs(ctx, ls.apiObject, unboundPVCs); err != nil {
262+
if retry, err := ls.createPVs(ctx, ls.apiObject, unboundPVCs); err != nil {
263263
hasError = true
264264
ls.createEvent(k8sutil.NewErrorEvent("PV creation failed", err, ls.apiObject))
265+
} else if retry {
266+
inspectionInterval = minInspectionInterval
265267
}
266268
}
267269
}

0 commit comments

Comments
 (0)