-
Notifications
You must be signed in to change notification settings - Fork 785
/
daemonset.go
90 lines (76 loc) · 2.82 KB
/
daemonset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"time"
"net/http"
"github.com/hashicorp/go-retryablehttp"
)
// Partial structure of a Kubernetes DaemonSet object. Note that we want to use
// the non-optional fields of the Status struct only to ensure this is a robust
// implementation.
//
// ref: https://github.com/kubernetes/kubernetes/blob/e23d83eead3b5ae57731afb0209f4a2aaa4009dd/pkg/apis/apps/types.go#L590
type DaemonSet struct {
Kind string `json:"kind"`
Status struct {
// The number of nodes that are running at least 1
// daemon pod and are supposed to run the daemon pod.
CurrentNumberScheduled int `json:"currentNumberScheduled"`
// The number of nodes that are running the daemon pod, but are
// not supposed to run the daemon pod.
DesiredNumberScheduled int `json:"desiredNumberScheduled"`
// The number of nodes that should be running the daemon pod and have one
// or more of the daemon pod running and ready.
NumberReady int `json:"numberReady"`
} `json:"status"`
}
// Return a *DaemonSet and the relevant state its in
func getDaemonSet(transportPtr *http.Transport, server string, headers map[string]string, namespace string, daemonSet string) (*DaemonSet, error) {
// Rather than die on startup if the first request fails, retry a few times with backoff before giving up
// This can happen if we're e.g. waiting for a service mesh to come up and is generally a good idea.
client := retryablehttp.NewClient()
client.RetryMax = 5
client.RetryWaitMin = time.Duration(5)*time.Second
client.HTTPClient.Transport = transportPtr
url := server + "/apis/apps/v1/namespaces/" + namespace + "/daemonsets/" + daemonSet
req, err := retryablehttp.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Add(k, v)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
ds := &DaemonSet{}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
err = json.Unmarshal(data, &ds)
if ds.Kind != "DaemonSet" {
// Something went wrong!
return nil, fmt.Errorf(fmt.Sprintf("Can not parse API response as DaemonSet: %s", string(data)))
}
return ds, err
}
// Return a bool indicating if the provided DaemonSet's _currently_ scheduled
// pods (which does the image pulling) are ready, or in the case of a
// strictCheck, if the _desired_ number of scheduled pods are ready.
func areDaemonSetPodsReady(ds *DaemonSet, waitForPodsToSchedule bool) bool {
current := ds.Status.CurrentNumberScheduled
desired := ds.Status.DesiredNumberScheduled
ready := ds.Status.NumberReady
log.Printf("%d image puller pods are ready out of the %d currently scheduled and %d desired number scheduled.", ready, current, desired)
if waitForPodsToSchedule {
return ready == desired
} else {
return ready >= current
}
}