From 6b65a495b1ca9b3ce7fbad9074b4084eb19c9393 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 20 Jan 2024 18:12:36 +0100 Subject: [PATCH] backup/restore: fix termstatus initialization The termstatus must only be canceled once the command has returned. Otherwise output may be lost when the context gets canceled. --- cmd/restic/cmd_backup.go | 2 +- cmd/restic/cmd_restore.go | 2 +- cmd/restic/termstatus.go | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index 0596ee918..2ea2a4ec5 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -54,7 +54,7 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea }, DisableAutoGenTag: true, RunE: func(cmd *cobra.Command, args []string) error { - term, cancel := setupTermstatus(cmd.Context()) + term, cancel := setupTermstatus() defer cancel() return runBackup(cmd.Context(), backupOptions, globalOptions, term, args) }, diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index b5c62fdea..1208d30eb 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -37,7 +37,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er `, DisableAutoGenTag: true, RunE: func(cmd *cobra.Command, args []string) error { - term, cancel := setupTermstatus(cmd.Context()) + term, cancel := setupTermstatus() defer cancel() return runRestore(cmd.Context(), restoreOptions, globalOptions, term, args) }, diff --git a/cmd/restic/termstatus.go b/cmd/restic/termstatus.go index e39054427..cf3cd82ee 100644 --- a/cmd/restic/termstatus.go +++ b/cmd/restic/termstatus.go @@ -13,13 +13,14 @@ import ( // // Expected usage: // ``` -// term, cancel := setupTermstatus(ctx) +// term, cancel := setupTermstatus() // defer cancel() // // do stuff // ``` -func setupTermstatus(ctx context.Context) (*termstatus.Terminal, func()) { +func setupTermstatus() (*termstatus.Terminal, func()) { var wg sync.WaitGroup - cancelCtx, cancel := context.WithCancel(ctx) + // only shutdown once cancel is called to ensure that no output is lost + cancelCtx, cancel := context.WithCancel(context.Background()) term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet) wg.Add(1)