-
Notifications
You must be signed in to change notification settings - Fork 53
/
status.go
122 lines (111 loc) · 2.72 KB
/
status.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package cliutil
import (
"context"
"time"
"github.com/ttacon/chalk"
"github.com/vbauerster/mpb/v7"
"github.com/vbauerster/mpb/v7/decor"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type StatusObject interface {
client.Object
GetState() string
GetConditions() []string
}
func WaitAndDisplayStatus(
ctx context.Context,
timeout time.Duration,
k8sClient client.Client,
obj StatusObject,
) error {
waitCtx, ca := context.WithTimeout(ctx, timeout)
defer ca()
p := mpb.New()
waitingSpinner := p.AddSpinner(1,
mpb.AppendDecorators(
decor.OnComplete(decor.Name(chalk.Bold.TextStyle("Waiting for resource to become ready..."), decor.WCSyncSpaceR),
chalk.Bold.TextStyle("Done."),
),
),
mpb.BarFillerMiddleware(
CheckBarFiller(waitCtx, func(c context.Context) bool {
return waitCtx.Err() == nil
})),
mpb.BarWidth(1),
)
conds := map[string]*mpb.Bar{}
go func() {
<-waitCtx.Done()
waitingSpinner.Increment()
}()
wait.PollImmediateUntil(500*time.Millisecond, func() (done bool, err error) {
err = k8sClient.Get(waitCtx, client.ObjectKeyFromObject(obj), obj)
if client.IgnoreNotFound(err) != nil {
return false, err
}
state := obj.GetState()
conditions := obj.GetConditions()
if state == "Ready" {
waitingSpinner.Increment()
done = true
for _, v := range conds {
v.Increment()
}
}
for _, cond := range conditions {
if _, ok := conds[cond]; !ok {
conds[cond] = p.AddSpinner(1,
mpb.AppendDecorators(
func(cond string) decor.Decorator {
done := false
var doneText string
return decor.Any(func(s decor.Statistics) string {
if done {
return doneText
}
if s.Completed || waitCtx.Err() != nil {
done = true
if waitCtx.Err() == nil {
doneText = chalk.Bold.TextStyle(chalk.Green.Color("[Done] ")) + chalk.Italic.TextStyle(cond)
} else {
doneText = chalk.Bold.TextStyle(chalk.Red.Color("[Timed Out] ")) + chalk.Italic.TextStyle(cond)
}
return doneText
}
return chalk.Bold.TextStyle(chalk.Blue.Color(cond))
}, decor.WCSyncSpaceR)
}(cond),
),
mpb.BarFillerMiddleware(
CheckBarFiller(waitCtx, func(c context.Context) bool {
return waitCtx.Err() == nil
}),
),
mpb.BarWidth(1),
)
go func(cond string) {
<-waitCtx.Done()
if !conds[cond].Completed() {
conds[cond].Increment()
}
}(cond)
}
}
for k, v := range conds {
found := false
for _, cond := range conditions {
if k == cond {
found = true
break
}
}
if !found {
v.Increment()
}
}
return done, nil
}, waitCtx.Done())
p.Wait()
return nil
}