@@ -3,8 +3,11 @@ package client
3
3
import (
4
4
"bufio"
5
5
"fmt"
6
+ "os"
7
+ "os/signal"
6
8
"regexp"
7
9
"strconv"
10
+ "syscall"
8
11
"time"
9
12
10
13
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -51,11 +54,11 @@ func (d *DiagnosticPod) CanRun() (bool, error) {
51
54
// Check is part of the Diagnostic interface; it runs the actual diagnostic logic
52
55
func (d * DiagnosticPod ) Check () types.DiagnosticResult {
53
56
r := types .NewDiagnosticResult ("DiagnosticPod" )
54
- d .runDiagnosticPod (nil , r )
57
+ d .runDiagnosticPod (r )
55
58
return r
56
59
}
57
60
58
- func (d * DiagnosticPod ) runDiagnosticPod (service * kapi. Service , r types.DiagnosticResult ) {
61
+ func (d * DiagnosticPod ) runDiagnosticPod (r types.DiagnosticResult ) {
59
62
loglevel := d .Level
60
63
if loglevel > 2 {
61
64
loglevel = 2 // need to show summary at least
@@ -78,14 +81,33 @@ func (d *DiagnosticPod) runDiagnosticPod(service *kapi.Service, r types.Diagnost
78
81
r .Error ("DCli2001" , err , fmt .Sprintf ("Creating diagnostic pod with image %s failed. Error: (%[2]T) %[2]v" , imageName , err ))
79
82
return
80
83
}
81
- defer func () { // delete what we created, or notify that we couldn't
82
- zero := int64 (0 )
83
- delOpts := metav1.DeleteOptions {TypeMeta : pod .TypeMeta , GracePeriodSeconds : & zero }
84
- if err := d .KubeClient .Core ().Pods (d .Namespace ).Delete (pod .ObjectMeta .Name , & delOpts ); err != nil {
85
- r .Error ("DCl2002" , err , fmt .Sprintf ("Deleting diagnostic pod '%s' failed. Error: %s" , pod .ObjectMeta .Name , fmt .Sprintf ("(%T) %[1]s" , err )))
86
- }
84
+
85
+ // Jump straight to clean up if there is an interrupt/terminate signal while running diagnostic
86
+ done := make (chan bool , 1 )
87
+ sig := make (chan os.Signal , 1 )
88
+ signal .Notify (sig , os .Interrupt , syscall .SIGTERM )
89
+ go func () {
90
+ <- sig
91
+ r .Warn ("DCli2014" , nil , "Interrupt received; aborting diagnostic." )
92
+ done <- true
87
93
}()
88
- pod , err = d .KubeClient .Core ().Pods (d .Namespace ).Get (pod .ObjectMeta .Name , metav1.GetOptions {}) // status is filled in post-create
94
+ go func () {
95
+ d .processDiagnosticPodResults (pod , imageName , r )
96
+ done <- true
97
+ }()
98
+
99
+ <- done
100
+ signal .Stop (sig )
101
+ // delete what we created, or notify that we couldn't
102
+ zero := int64 (0 )
103
+ delOpts := metav1.DeleteOptions {TypeMeta : pod .TypeMeta , GracePeriodSeconds : & zero }
104
+ if err := d .KubeClient .Core ().Pods (d .Namespace ).Delete (pod .ObjectMeta .Name , & delOpts ); err != nil {
105
+ r .Error ("DCl2002" , err , fmt .Sprintf ("Deleting diagnostic pod '%s' failed. Error: %s" , pod .ObjectMeta .Name , fmt .Sprintf ("(%T) %[1]s" , err )))
106
+ }
107
+ }
108
+
109
+ func (d * DiagnosticPod ) processDiagnosticPodResults (protoPod * kapi.Pod , imageName string , r types.DiagnosticResult ) {
110
+ pod , err := d .KubeClient .Core ().Pods (d .Namespace ).Get (protoPod .ObjectMeta .Name , metav1.GetOptions {}) // status is filled in post-create
89
111
if err != nil {
90
112
r .Error ("DCli2003" , err , fmt .Sprintf ("Retrieving the diagnostic pod definition failed. Error: (%T) %[1]v" , err ))
91
113
return
0 commit comments