@@ -3,6 +3,7 @@ package lib
3
3
import (
4
4
"bytes"
5
5
"context"
6
+ "fmt"
6
7
"log"
7
8
"regexp"
8
9
"strings"
@@ -33,7 +34,7 @@ func GetVeleroClient() (veleroClientset.Interface, error) {
33
34
}
34
35
35
36
// https://github.com/vmware-tanzu/velero/blob/11bfe82342c9f54c63f40d3e97313ce763b446f2/pkg/cmd/cli/backup/describe.go#L77-L111
36
- func DescribeBackup (ocClient client.Client , backup velero.Backup ) string {
37
+ func DescribeBackup (ocClient client.Client , backup velero.Backup ) ( backupDescription string ) {
37
38
err := ocClient .Get (context .Background (), client.ObjectKey {
38
39
Namespace : backup .Namespace ,
39
40
Name : backup .Name ,
@@ -75,7 +76,15 @@ func DescribeBackup(ocClient client.Client, backup velero.Backup) string {
75
76
log .Printf ("error getting VolumeSnapshotContent objects for backup %s: %v\n " , backup .Name , err )
76
77
}
77
78
}
78
-
79
+ // output.DescribeBackup is a helper function from velero CLI that attempts to download logs for a backup.
80
+ // if a backup failed, this function may panic. Recover from the panic and return string of backup object
81
+ defer func () {
82
+ if r := recover (); r != nil {
83
+ log .Printf ("Recovered from panic in DescribeBackup: %v\n " , r )
84
+ log .Print ("returning backup object instead" )
85
+ backupDescription = fmt .Sprint (backup )
86
+ }
87
+ }()
79
88
return output .DescribeBackup (context .Background (), ocClient , & backup , deleteRequestList .Items , podVolumeBackupList .Items , vscList .Items , details , veleroClient , insecureSkipTLSVerify , caCertFile )
80
89
}
81
90
@@ -104,25 +113,36 @@ func DescribeRestore(ocClient client.Client, restore velero.Restore) string {
104
113
return output .DescribeRestore (context .Background (), ocClient , & restore , podvolumeRestoreList .Items , details , veleroClient , insecureSkipTLSVerify , caCertFile )
105
114
}
106
115
107
- func BackupLogs (ocClient client.Client , backup velero.Backup ) string {
116
+ func BackupLogs (ocClient client.Client , backup velero.Backup ) ( backupLogs string ) {
108
117
insecureSkipTLSVerify := true
109
118
caCertFile := ""
110
119
// new io.Writer that store the logs in a string
111
120
logs := & bytes.Buffer {}
112
121
// new io.Writer that store the logs in a string
113
-
122
+ // if a backup failed, this function may panic. Recover from the panic and return container logs
123
+ defer func () {
124
+ if r := recover (); r != nil {
125
+ backupLogs = recoverFromPanicLogs (backup .Namespace , r , "BackupLogs" )
126
+
127
+ }
128
+ }()
114
129
downloadrequest .Stream (context .Background (), ocClient , backup .Namespace , backup .Name , velero .DownloadTargetKindBackupLog , logs , time .Minute , insecureSkipTLSVerify , caCertFile )
115
130
116
131
return logs .String ()
117
132
}
118
133
119
- func RestoreLogs (ocClient client.Client , restore velero.Restore ) string {
134
+ func RestoreLogs (ocClient client.Client , restore velero.Restore ) ( restoreLogs string ) {
120
135
insecureSkipTLSVerify := true
121
136
caCertFile := ""
122
137
// new io.Writer that store the logs in a string
123
138
logs := & bytes.Buffer {}
124
139
// new io.Writer that store the logs in a string
125
-
140
+ // if a backup failed, this function may panic. Recover from the panic and return container logs
141
+ defer func () {
142
+ if r := recover (); r != nil {
143
+ restoreLogs = recoverFromPanicLogs (restore .Namespace , r , "RestoreLogs" )
144
+ }
145
+ }()
126
146
downloadrequest .Stream (context .Background (), ocClient , restore .Namespace , restore .Name , velero .DownloadTargetKindRestoreLog , logs , time .Minute , insecureSkipTLSVerify , caCertFile )
127
147
128
148
return logs .String ()
@@ -136,6 +156,16 @@ var errorIgnorePatterns = []string{
136
156
"blob unknown" ,
137
157
}
138
158
159
+ func recoverFromPanicLogs (veleroNamespace string , panicReason interface {}, panicFrom string ) string {
160
+ log .Printf ("Recovered from panic in %s: %v\n " , panicFrom , panicReason )
161
+ log .Print ("returning container logs instead" )
162
+ containerLogs , err := GetVeleroContainerLogs (veleroNamespace )
163
+ if err != nil {
164
+ log .Printf ("error getting container logs: %v\n " , err )
165
+ }
166
+ return containerLogs
167
+ }
168
+
139
169
func BackupErrorLogs (ocClient client.Client , backup velero.Backup ) []string {
140
170
bl := BackupLogs (ocClient , backup )
141
171
errorRegex , err := regexp .Compile ("error|Error" )
0 commit comments