@@ -23,15 +23,24 @@ import (
23
23
"strings"
24
24
"time"
25
25
26
+ "github.com/sirupsen/logrus"
27
+
28
+ "github.com/GoogleContainerTools/skaffold/pkg/diag"
29
+ "github.com/GoogleContainerTools/skaffold/pkg/diag/validator"
30
+ "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
26
31
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubectl"
27
32
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext"
33
+ "github.com/GoogleContainerTools/skaffold/proto"
28
34
)
29
35
30
36
const (
31
- deploymentType = "deployment"
32
- rollOutSuccess = "successfully rolled out"
33
- connectionErrMsg = "Unable to connect to the server"
34
- killedErrMsg = "signal: killed"
37
+ deploymentType = "deployment"
38
+ rollOutSuccess = "successfully rolled out"
39
+ connectionErrMsg = "Unable to connect to the server"
40
+ killedErrMsg = "signal: killed"
41
+ defaultPodCheckDeadline = 30 * time .Second
42
+ tabHeader = " -"
43
+ tab = " "
35
44
)
36
45
37
46
var (
@@ -40,20 +49,26 @@ var (
40
49
)
41
50
42
51
type Deployment struct {
43
- name string
44
- namespace string
45
- rType string
46
- status Status
47
- done bool
48
- deadline time.Duration
52
+ name string
53
+ namespace string
54
+ rType string
55
+ status Status
56
+ done bool
57
+ deadline time.Duration
58
+ pods map [string ]validator.Resource
59
+ podValidator diag.Diagnose
49
60
}
50
61
51
62
func (d * Deployment ) Deadline () time.Duration {
52
63
return d .deadline
53
64
}
54
65
55
66
func (d * Deployment ) UpdateStatus (details string , err error ) {
56
- updated := newStatus (details , err )
67
+ errCode := proto .StatusCode_STATUSCHECK_SUCCESS
68
+ if err != nil {
69
+ errCode = proto .StatusCode_STATUSCHECK_UNKNOWN
70
+ }
71
+ updated := newStatus (details , errCode , err )
57
72
if d .status .Equal (updated ) {
58
73
d .status .changed = false
59
74
return
@@ -67,14 +82,20 @@ func (d *Deployment) UpdateStatus(details string, err error) {
67
82
68
83
func NewDeployment (name string , ns string , deadline time.Duration ) * Deployment {
69
84
return & Deployment {
70
- name : name ,
71
- namespace : ns ,
72
- rType : deploymentType ,
73
- status : newStatus ("" , nil ),
74
- deadline : deadline ,
85
+ name : name ,
86
+ namespace : ns ,
87
+ rType : deploymentType ,
88
+ status : newStatus ("" , proto .StatusCode_STATUSCHECK_UNKNOWN , nil ),
89
+ deadline : deadline ,
90
+ podValidator : diag .New (nil ),
75
91
}
76
92
}
77
93
94
+ func (d * Deployment ) WithValidator (pd diag.Diagnose ) * Deployment {
95
+ d .podValidator = pd
96
+ return d
97
+ }
98
+
78
99
func (d * Deployment ) CheckStatus (ctx context.Context , runCtx * runcontext.RunContext ) {
79
100
kubeCtl := kubectl .NewFromRunContext (runCtx )
80
101
@@ -91,6 +112,9 @@ func (d *Deployment) CheckStatus(ctx context.Context, runCtx *runcontext.RunCont
91
112
}
92
113
93
114
d .UpdateStatus (details , err )
115
+ if err := d .fetchPods (ctx ); err != nil {
116
+ logrus .Debugf ("pod statuses could be fetched this time due to %s" , err )
117
+ }
94
118
}
95
119
96
120
func (d * Deployment ) String () string {
@@ -113,12 +137,26 @@ func (d *Deployment) IsStatusCheckComplete() bool {
113
137
return d .done
114
138
}
115
139
140
+ // This returns a string representing deployment status along with tab header
141
+ // e.g.
142
+ // - testNs:deployment/leeroy-app: waiting for rollout to complete. (1/2) pending
143
+ // - testNs:pod/leeroy-app-xvbg : error pulling container image
116
144
func (d * Deployment ) ReportSinceLastUpdated () string {
117
145
if d .status .reported && ! d .status .changed {
118
146
return ""
119
147
}
120
148
d .status .reported = true
121
- return fmt .Sprintf ("%s: %s" , d , d .status )
149
+ if d .status .String () == "" {
150
+ return ""
151
+ }
152
+ var result strings.Builder
153
+ result .WriteString (fmt .Sprintf ("%s %s: %s" , tabHeader , d , d .status ))
154
+ for _ , p := range d .pods {
155
+ if p .Error () != nil {
156
+ result .WriteString (fmt .Sprintf ("%s %s %s: %s\n " , tab , tabHeader , p , p .Error ()))
157
+ }
158
+ }
159
+ return result .String ()
122
160
}
123
161
124
162
func (d * Deployment ) cleanupStatus (msg string ) string {
@@ -148,3 +186,28 @@ func isErrAndNotRetryAble(err error) bool {
148
186
}
149
187
return err != ErrKubectlConnection
150
188
}
189
+
190
+ func (d * Deployment ) fetchPods (ctx context.Context ) error {
191
+ timeoutContext , cancel := context .WithTimeout (ctx , defaultPodCheckDeadline )
192
+ defer cancel ()
193
+ pods , err := d .podValidator .Run (timeoutContext )
194
+ if err != nil {
195
+ return err
196
+ }
197
+
198
+ newPods := map [string ]validator.Resource {}
199
+ d .status .changed = false
200
+ for _ , p := range pods {
201
+ originalPod , ok := d .pods [p .String ()]
202
+ if ! ok {
203
+ d .status .changed = true
204
+ event .ResourceStatusCheckEventCompleted (p .String (), p .Error ())
205
+ } else if originalPod .StatusCode != p .StatusCode {
206
+ d .status .changed = true
207
+ event .ResourceStatusCheckEventCompleted (p .String (), p .Error ())
208
+ }
209
+ newPods [p .String ()] = p
210
+ }
211
+ d .pods = newPods
212
+ return nil
213
+ }
0 commit comments