From b25fea3bea14989996980ac48f4868c411bbdf3a Mon Sep 17 00:00:00 2001 From: Brad Koehn Date: Mon, 3 Feb 2020 13:49:23 -0600 Subject: [PATCH] properly handle empty restic stdout during progress updates (#2231) * properly handle empty restic stdout during progress updates Signed-off-by: Brad Koehn --- pkg/restic/exec_commands.go | 27 ++++++++++++++++----------- pkg/restic/exec_commands_test.go | 12 +++++++----- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/pkg/restic/exec_commands.go b/pkg/restic/exec_commands.go index db2394ea6..9d640ac04 100644 --- a/pkg/restic/exec_commands.go +++ b/pkg/restic/exec_commands.go @@ -97,18 +97,20 @@ func RunBackup(backupCmd *Command, log logrus.FieldLogger, updateFunc func(veler select { case <-ticker.C: lastLine := getLastLine(stdoutBuf.Bytes()) - stat, err := decodeBackupStatusLine(lastLine) - if err != nil { - log.WithError(err).Errorf("error getting restic backup progress") - } + if len(lastLine) > 0 { + stat, err := decodeBackupStatusLine(lastLine) + if err != nil { + log.WithError(err).Errorf("error getting restic backup progress") + } - // if the line contains a non-empty bytes_done field, we can update the - // caller with the progress - if stat.BytesDone != 0 { - updateFunc(velerov1api.PodVolumeOperationProgress{ - TotalBytes: stat.TotalBytes, - BytesDone: stat.BytesDone, - }) + // if the line contains a non-empty bytes_done field, we can update the + // caller with the progress + if stat.BytesDone != 0 { + updateFunc(velerov1api.PodVolumeOperationProgress{ + TotalBytes: stat.TotalBytes, + BytesDone: stat.BytesDone, + }) + } } case <-quit: ticker.Stop() @@ -153,6 +155,9 @@ func decodeBackupStatusLine(lastLine []byte) (backupStatusLine, error) { // have a newline at the end of it, so this returns the substring between the // last two newlines. func getLastLine(b []byte) []byte { + if b == nil || len(b) == 0 { + return []byte("") + } // subslice the byte array to ignore the newline at the end of the string lastNewLineIdx := bytes.LastIndex(b[:len(b)-1], []byte("\n")) return b[lastNewLineIdx+1 : len(b)-1] diff --git a/pkg/restic/exec_commands_test.go b/pkg/restic/exec_commands_test.go index b3bd5174a..0353f3e2c 100644 --- a/pkg/restic/exec_commands_test.go +++ b/pkg/restic/exec_commands_test.go @@ -65,15 +65,17 @@ func Test_getSummaryLine(t *testing.T) { func Test_getLastLine(t *testing.T) { tests := []struct { - output string + output []byte want string }{ - {`last line -`, "last line"}, - {`first line + {[]byte(`last line +`), "last line"}, + {[]byte(`first line second line third line -`, "third line"}, +`), "third line"}, + {[]byte(""), ""}, + {nil, ""}, } for _, tt := range tests { t.Run(tt.want, func(t *testing.T) {