@@ -11,6 +11,8 @@ import (
1111 "github.com/mitchellh/go-wordwrap"
1212 corev1 "k8s.io/api/core/v1"
1313 "sigs.k8s.io/controller-runtime/pkg/client"
14+
15+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1416)
1517
1618type HelmReleaseCheck struct {
@@ -43,17 +45,21 @@ func (d *HelmReleaseCheck) Run() *Result {
4345 // the order of processing is important as we prioritize the status messages
4446 type handler struct {
4547 regex * regexp.Regexp
46- fn func (res * Result , matches []string )
48+ fn func (name string , res * Result , matches []string )
4749 }
4850
4951 handlers := []handler {
52+ {
53+ regex : regexp .MustCompile ("Helm install failed: timed out waiting for the condition" ),
54+ fn : handleHelmInstallTimeoutError ,
55+ },
5056 {
5157 regex : regexp .MustCompile ("Helm test failed: pod (?P<podName>.*) failed" ),
5258 fn : handeHelmTestError ,
5359 },
5460 {
5561 regex : regexp .MustCompile ("(install retries exhausted|upgrade retries exhausted|Helm install failed|Helm upgrade failed).*" ),
56- fn : func (res * Result , matches []string ) {
62+ fn : func (name string , res * Result , matches []string ) {
5763 res .Status = prettify (matches [0 ])
5864 res .IsError = true
5965 res .IsOkay = false
@@ -65,7 +71,7 @@ func (d *HelmReleaseCheck) Run() *Result {
6571 },
6672 {
6773 regex : regexp .MustCompile ("Release reconciliation succeeded" ),
68- fn : func (res * Result , matches []string ) {
74+ fn : func (name string , res * Result , matches []string ) {
6975 res .Status = prettify (matches [0 ])
7076 res .IsError = false
7177 res .IsOkay = true
@@ -79,7 +85,7 @@ func (d *HelmReleaseCheck) Run() *Result {
7985 for _ , condition := range hr .GetConditions () {
8086 matches := curHandler .regex .FindStringSubmatch (condition .Message )
8187 if matches != nil {
82- curHandler .fn (result , matches )
88+ curHandler .fn (hr . Name , result , matches )
8389 return result
8490 }
8591 }
@@ -89,7 +95,7 @@ func (d *HelmReleaseCheck) Run() *Result {
8995}
9096
9197// handeHelmTestError ...
92- func handeHelmTestError (res * Result , matches []string ) {
98+ func handeHelmTestError (name string , res * Result , matches []string ) {
9399
94100 // It seems controller-runtime does not allow to access the logs.
95101 // Use kubectl directly for the moment.
@@ -100,36 +106,47 @@ func handeHelmTestError(res *Result, matches []string) {
100106 log = fmt .Sprintf ("couldn't get pod logs: %s" , err )
101107 }
102108
103- // Do some easy formatting for the moment.
104- // We should definitely look for some package doing the job in the end.
105- const replacement = "\n > "
106- var replacer = strings .NewReplacer (
107- "\r \n " , replacement ,
108- "\r " , replacement ,
109- "\n " , replacement ,
110- "\v " , replacement ,
111- "\f " , replacement ,
112- "\u0085 " , replacement ,
113- "\u2028 " , replacement ,
114- "\u2029 " , replacement ,
115- )
116-
117- newline := "\n > "
118- res .Status = matches [0 ] + newline + replacer .Replace (wordwrap .WrapString (strings .TrimSpace (log ), 100 ))
119-
109+ res .Status = matches [0 ] + indent (wordwrap .WrapString (strings .TrimSpace (log ), 100 ), 4 )
120110 res .IsError = true
121111 res .IsOkay = false
122112}
123113
124- func handleHelmChartError (res * Result , matches []string ) {
114+ func handleHelmInstallTimeoutError (name string , res * Result , matches []string ) {
115+
116+ // implement further checks here by adding other cases
117+ // todo: define a cleaner interface for this process
118+ switch name {
119+ case "internal-gardenlet" :
120+ test , _ := KubeClientGo .CoreV1 ().Pods ("garden" ).List (context .Background (), metav1.ListOptions {
121+ LabelSelector : "role=gardenlet,app=gardener" ,
122+ })
123+ var log string
124+ for _ , pod := range test .Items {
125+ logs , _ := KubeClientGo .CoreV1 ().Pods (pod .Namespace ).GetLogs (pod .Name , & corev1.PodLogOptions {}).Do (context .Background ()).Raw ()
126+ if ! strings .Contains (log , string (logs )) {
127+ log += "\n " + string (logs )
128+ }
129+ }
130+
131+ res .Status = matches [0 ] + indent (wordwrap .WrapString (strings .TrimSpace (log ), 100 ), 4 )
132+ res .IsError = true
133+ res .IsOkay = false
134+ default :
135+ res .Status = prettify (matches [0 ])
136+ res .IsError = true
137+ res .IsOkay = false
138+ }
139+ }
140+
141+ func handleHelmChartError (name string , res * Result , matches []string ) {
125142 namespace := matches [1 ]
126- name := matches [2 ]
143+ podName := matches [2 ]
127144
128145 hc := & sourcev1.HelmChart {}
129146
130147 err := KubeClient .Get (context .Background (), client.ObjectKey {
131148 Namespace : namespace ,
132- Name : name ,
149+ Name : podName ,
133150 }, hc )
134151
135152 status := matches [0 ]
@@ -150,3 +167,25 @@ func prettify(message string) string {
150167 newline := "\n > "
151168 return strings .Replace (message , ": " , newline , - 1 )
152169}
170+
171+ // indent ...
172+ func indent (in string , n int ) string {
173+
174+ // Do some easy formatting for the moment.
175+ // We should definitely look for some package doing the job in the end.
176+ in = "\n " + in
177+ var replacement = "\n " + strings .Repeat (" " , n ) + "> "
178+ var replacer = strings .NewReplacer (
179+ "\r \n " , replacement ,
180+ "\r " , replacement ,
181+ "\n " , replacement ,
182+ "\v " , replacement ,
183+ "\f " , replacement ,
184+ "\u0085 " , replacement ,
185+ "\u2028 " , replacement ,
186+ "\u2029 " , replacement ,
187+ )
188+
189+ return replacer .Replace (in )
190+
191+ }
0 commit comments