Skip to content

Commit e559f21

Browse files
authored
[Feature] Requests timeout (#705)
1 parent 124749d commit e559f21

File tree

124 files changed

+1735
-881
lines changed

Some content is hidden

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

124 files changed

+1735
-881
lines changed

go.sum

Lines changed: 30 additions & 0 deletions
Large diffs are not rendered by default.

main.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Ewout Prangsma
21+
// Author Tomasz Mielech
2122
//
2223

2324
package main
@@ -32,6 +33,8 @@ import (
3233
"strings"
3334
"time"
3435

36+
"github.com/arangodb/kube-arangodb/pkg/util/arangod"
37+
3538
"github.com/arangodb/kube-arangodb/pkg/operator/scope"
3639

3740
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
@@ -114,6 +117,10 @@ var (
114117
singleMode bool
115118
scope string
116119
}
120+
timeouts struct {
121+
k8s time.Duration
122+
arangoD time.Duration
123+
}
117124
chaosOptions struct {
118125
allowed bool
119126
}
@@ -143,7 +150,8 @@ func init() {
143150
f.BoolVar(&chaosOptions.allowed, "chaos.allowed", false, "Set to allow chaos in deployments. Only activated when allowed and enabled in deployment")
144151
f.BoolVar(&operatorOptions.singleMode, "mode.single", false, "Enable single mode in Operator. WARNING: There should be only one replica of Operator, otherwise Operator can take unexpected actions")
145152
f.StringVar(&operatorOptions.scope, "scope", scope.DefaultScope.String(), "Define scope on which Operator works. Legacy - pre 1.1.0 scope with limited cluster access")
146-
153+
f.DurationVar(&timeouts.k8s, "timeout.k8s", time.Second*3, "The request timeout to the kubernetes")
154+
f.DurationVar(&timeouts.arangoD, "timeout.arangod", time.Second*10, "The request timeout to the ArangoDB")
147155
features.Init(&cmdMain)
148156
}
149157

@@ -168,6 +176,8 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
168176
ip := os.Getenv(constants.EnvOperatorPodIP)
169177

170178
deploymentApi.DefaultImage = operatorOptions.arangoImage
179+
k8sutil.SetRequestTimeout(timeouts.k8s)
180+
arangod.SetRequestTimeout(timeouts.arangoD)
171181

172182
// Prepare log service
173183
var err error

pkg/backup/handlers/arango/backup/arango_client_impl.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Lars Maier
21+
// Author Tomasz Mielech
2122
//
2223

2324
package backup
@@ -128,9 +129,10 @@ func (ac *arangoClientBackupImpl) Get(backupID driver.BackupID) (driver.BackupMe
128129
}
129130
}
130131

131-
func (ac *arangoClientBackupImpl) getCredentialsFromSecret(secretName string) (interface{}, error) {
132-
133-
token, err := k8sutil.GetTokenSecret(ac.kubecli.CoreV1().Secrets(ac.backup.Namespace), secretName)
132+
func (ac *arangoClientBackupImpl) getCredentialsFromSecret(ctx context.Context, secretName string) (interface{}, error) {
133+
ctxChild, cancel := context.WithTimeout(ctx, k8sutil.GetRequestTimeout())
134+
defer cancel()
135+
token, err := k8sutil.GetTokenSecret(ctxChild, ac.kubecli.CoreV1().Secrets(ac.backup.Namespace), secretName)
134136
if err != nil {
135137
return nil, err
136138
}
@@ -152,7 +154,7 @@ func (ac *arangoClientBackupImpl) Upload(backupID driver.BackupID) (driver.Backu
152154
return "", errors.Newf("upload was called but no upload spec was given")
153155
}
154156

155-
cred, err := ac.getCredentialsFromSecret(uploadSpec.CredentialsSecretName)
157+
cred, err := ac.getCredentialsFromSecret(ctx, uploadSpec.CredentialsSecretName)
156158
if err != nil {
157159
return "", err
158160
}
@@ -169,7 +171,7 @@ func (ac *arangoClientBackupImpl) Download(backupID driver.BackupID) (driver.Bac
169171
return "", errors.Newf("Download was called but not download spec was given")
170172
}
171173

172-
cred, err := ac.getCredentialsFromSecret(downloadSpec.CredentialsSecretName)
174+
cred, err := ac.getCredentialsFromSecret(ctx, downloadSpec.CredentialsSecretName)
173175
if err != nil {
174176
return "", err
175177
}

pkg/deployment/access_package.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Ewout Prangsma
21+
// Author Tomasz Mielech
2122
//
2223

2324
package deployment
@@ -46,7 +47,7 @@ const (
4647

4748
// createAccessPackages creates a arangosync access packages specified
4849
// in spec.sync.externalAccess.accessPackageSecretNames.
49-
func (d *Deployment) createAccessPackages() error {
50+
func (d *Deployment) createAccessPackages(ctx context.Context) error {
5051
log := d.deps.Log
5152
spec := d.apiObject.Spec
5253
secrets := d.deps.KubeCli.CoreV1().Secrets(d.GetNamespace())
@@ -60,13 +61,15 @@ func (d *Deployment) createAccessPackages() error {
6061
apNameMap := make(map[string]struct{})
6162
for _, apSecretName := range spec.Sync.ExternalAccess.AccessPackageSecretNames {
6263
apNameMap[apSecretName] = struct{}{}
63-
if err := d.ensureAccessPackage(apSecretName); err != nil {
64+
if err := d.ensureAccessPackage(ctx, apSecretName); err != nil {
6465
return errors.WithStack(err)
6566
}
6667
}
6768

6869
// Remove all access packages that we did build, but are no longer needed
69-
secretList, err := secrets.List(context.Background(), metav1.ListOptions{})
70+
ctxChild, cancel := context.WithTimeout(ctx, k8sutil.GetRequestTimeout())
71+
defer cancel()
72+
secretList, err := secrets.List(ctxChild, metav1.ListOptions{})
7073
if err != nil {
7174
log.Debug().Err(err).Msg("Failed to list secrets")
7275
return errors.WithStack(err)
@@ -77,9 +80,12 @@ func (d *Deployment) createAccessPackages() error {
7780
// Secret is an access package
7881
if _, wanted := apNameMap[secret.GetName()]; !wanted {
7982
// We found an obsolete access package secret. Remove it.
80-
if err := secrets.Delete(context.Background(), secret.GetName(), metav1.DeleteOptions{
81-
Preconditions: &metav1.Preconditions{UID: &secret.UID},
82-
}); err != nil && !k8sutil.IsNotFound(err) {
83+
err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error {
84+
return secrets.Delete(ctxChild, secret.GetName(), metav1.DeleteOptions{
85+
Preconditions: &metav1.Preconditions{UID: &secret.UID},
86+
})
87+
})
88+
if err != nil && !k8sutil.IsNotFound(err) {
8389
// Not serious enough to stop everything now, just log and create an event
8490
log.Warn().Err(err).Msg("Failed to remove obsolete access package secret")
8591
d.CreateEvent(k8sutil.NewErrorEvent("Access Package cleanup failed", err, d.apiObject))
@@ -98,28 +104,37 @@ func (d *Deployment) createAccessPackages() error {
98104

99105
// ensureAccessPackage creates an arangosync access package with given name
100106
// it is does not already exist.
101-
func (d *Deployment) ensureAccessPackage(apSecretName string) error {
107+
func (d *Deployment) ensureAccessPackage(ctx context.Context, apSecretName string) error {
102108
log := d.deps.Log
103109
ns := d.GetNamespace()
104110
secrets := d.deps.KubeCli.CoreV1().Secrets(ns)
105111
spec := d.apiObject.Spec
106112

107-
if _, err := secrets.Get(context.Background(), apSecretName, metav1.GetOptions{}); err == nil {
113+
err := k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error {
114+
_, err := secrets.Get(ctxChild, apSecretName, metav1.GetOptions{})
115+
return err
116+
})
117+
if err == nil {
108118
// Secret already exists
109119
return nil
120+
} else if !k8sutil.IsNotFound(err) {
121+
log.Debug().Err(err).Str("name", apSecretName).Msg("Failed to get arangosync access package secret")
122+
return errors.WithStack(err)
110123
}
111124

112125
// Fetch client authentication CA
113126
clientAuthSecretName := spec.Sync.Authentication.GetClientCASecretName()
114-
clientAuthCert, clientAuthKey, _, err := k8sutil.GetCASecret(secrets, clientAuthSecretName, nil)
127+
ctxChild, cancel := context.WithTimeout(ctx, k8sutil.GetRequestTimeout())
128+
defer cancel()
129+
clientAuthCert, clientAuthKey, _, err := k8sutil.GetCASecret(ctxChild, secrets, clientAuthSecretName, nil)
115130
if err != nil {
116131
log.Debug().Err(err).Msg("Failed to get client-auth CA secret")
117132
return errors.WithStack(err)
118133
}
119134

120135
// Fetch TLS CA public key
121136
tlsCASecretName := spec.Sync.TLS.GetCASecretName()
122-
tlsCACert, err := k8sutil.GetCACertficateSecret(secrets, tlsCASecretName)
137+
tlsCACert, err := k8sutil.GetCACertficateSecret(ctx, secrets, tlsCASecretName)
123138
if err != nil {
124139
log.Debug().Err(err).Msg("Failed to get TLS CA secret")
125140
return errors.WithStack(err)
@@ -205,7 +220,11 @@ func (d *Deployment) ensureAccessPackage(apSecretName string) error {
205220
}
206221
// Attach secret to owner
207222
secret.SetOwnerReferences(append(secret.GetOwnerReferences(), d.apiObject.AsOwner()))
208-
if _, err := secrets.Create(context.Background(), secret, metav1.CreateOptions{}); err != nil {
223+
err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error {
224+
_, err := secrets.Create(ctxChild, secret, metav1.CreateOptions{})
225+
return err
226+
})
227+
if err != nil {
209228
// Failed to create secret
210229
log.Debug().Err(err).Str("secret-name", apSecretName).Msg("Failed to create access package Secret")
211230
return errors.WithStack(err)

pkg/deployment/chaos/context.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,11 +18,14 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Ewout Prangsma
21+
// Author Tomasz Mielech
2122
//
2223

2324
package chaos
2425

2526
import (
27+
"context"
28+
2629
v1 "k8s.io/api/core/v1"
2730

2831
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
@@ -34,7 +37,7 @@ type Context interface {
3437
GetSpec() api.DeploymentSpec
3538
// DeletePod deletes a pod with given name in the namespace
3639
// of the deployment. If the pod does not exist, the error is ignored.
37-
DeletePod(podName string) error
40+
DeletePod(ctx context.Context, podName string) error
3841
// GetOwnedPods returns a list of all pods owned by the deployment.
39-
GetOwnedPods() ([]v1.Pod, error)
42+
GetOwnedPods(ctx context.Context) ([]v1.Pod, error)
4043
}

pkg/deployment/chaos/monkey.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,11 +18,13 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Ewout Prangsma
21+
// Author Tomasz Mielech
2122
//
2223

2324
package chaos
2425

2526
import (
27+
"context"
2628
"math/rand"
2729
"time"
2830

@@ -50,14 +52,17 @@ func NewMonkey(log zerolog.Logger, context Context) *Monkey {
5052

5153
// Run the monkey until the given channel is closed.
5254
func (m Monkey) Run(stopCh <-chan struct{}) {
55+
ctx, cancel := context.WithCancel(context.Background())
56+
defer cancel()
57+
5358
for {
5459
spec := m.context.GetSpec()
5560
if spec.Chaos.IsEnabled() {
5661
// Gamble to set if we must introduce chaos
5762
chance := float64(spec.Chaos.GetKillPodProbability()) / 100.0
5863
if rand.Float64() < chance {
5964
// Let's introduce pod chaos
60-
if err := m.killRandomPod(); err != nil {
65+
if err := m.killRandomPod(ctx); err != nil {
6166
log.Info().Err(err).Msg("Failed to kill random pod")
6267
}
6368
}
@@ -74,8 +79,8 @@ func (m Monkey) Run(stopCh <-chan struct{}) {
7479
}
7580

7681
// killRandomPod fetches all owned pods and tries to kill one.
77-
func (m Monkey) killRandomPod() error {
78-
pods, err := m.context.GetOwnedPods()
82+
func (m Monkey) killRandomPod(ctx context.Context) error {
83+
pods, err := m.context.GetOwnedPods(ctx)
7984
if err != nil {
8085
return errors.WithStack(err)
8186
}
@@ -85,7 +90,7 @@ func (m Monkey) killRandomPod() error {
8590
}
8691
p := pods[rand.Intn(len(pods))]
8792
m.log.Info().Str("pod-name", p.GetName()).Msg("Killing pod")
88-
if err := m.context.DeletePod(p.GetName()); err != nil {
93+
if err := m.context.DeletePod(ctx, p.GetName()); err != nil {
8994
return errors.WithStack(err)
9095
}
9196
return nil

pkg/deployment/cleanup.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -18,33 +18,38 @@
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
2020
// Author Ewout Prangsma
21+
// Author Tomasz Mielech
2122
//
2223

2324
package deployment
2425

2526
import (
2627
"context"
2728

29+
core "k8s.io/api/core/v1"
30+
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
2832
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
2933
"github.com/arangodb/kube-arangodb/pkg/util"
3034
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
3135
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
32-
core "k8s.io/api/core/v1"
33-
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
3436
)
3537

3638
// removePodFinalizers removes all finalizers from all pods owned by us.
37-
func (d *Deployment) removePodFinalizers(cachedStatus inspectorInterface.Inspector) error {
39+
func (d *Deployment) removePodFinalizers(ctx context.Context, cachedStatus inspectorInterface.Inspector) error {
3840
log := d.deps.Log
3941
kubecli := d.GetKubeCli()
4042

4143
if err := cachedStatus.IteratePods(func(pod *core.Pod) error {
42-
if err := k8sutil.RemovePodFinalizers(log, kubecli, pod, pod.GetFinalizers(), true); err != nil {
44+
if err := k8sutil.RemovePodFinalizers(ctx, log, kubecli, pod, pod.GetFinalizers(), true); err != nil {
4345
log.Warn().Err(err).Msg("Failed to remove pod finalizers")
4446
return err
4547
}
4648

47-
if err := kubecli.CoreV1().Pods(pod.GetNamespace()).Delete(context.Background(), pod.GetName(), meta.DeleteOptions{
49+
ctxChild, cancel := context.WithTimeout(ctx, k8sutil.GetRequestTimeout())
50+
defer cancel()
51+
52+
if err := kubecli.CoreV1().Pods(pod.GetNamespace()).Delete(ctxChild, pod.GetName(), meta.DeleteOptions{
4853
GracePeriodSeconds: util.NewInt64(1),
4954
}); err != nil {
5055
if !k8sutil.IsNotFound(err) {
@@ -61,12 +66,12 @@ func (d *Deployment) removePodFinalizers(cachedStatus inspectorInterface.Inspect
6166
}
6267

6368
// removePVCFinalizers removes all finalizers from all PVCs owned by us.
64-
func (d *Deployment) removePVCFinalizers(cachedStatus inspectorInterface.Inspector) error {
69+
func (d *Deployment) removePVCFinalizers(ctx context.Context, cachedStatus inspectorInterface.Inspector) error {
6570
log := d.deps.Log
6671
kubecli := d.GetKubeCli()
6772

6873
if err := cachedStatus.IteratePersistentVolumeClaims(func(pvc *core.PersistentVolumeClaim) error {
69-
if err := k8sutil.RemovePVCFinalizers(log, kubecli, pvc, pvc.GetFinalizers(), true); err != nil {
74+
if err := k8sutil.RemovePVCFinalizers(ctx, log, kubecli, pvc, pvc.GetFinalizers(), true); err != nil {
7075
log.Warn().Err(err).Msg("Failed to remove PVC finalizers")
7176
return err
7277
}

0 commit comments

Comments
 (0)