From eeb1aa5388693c8e6b693cb3941045588080ee69 Mon Sep 17 00:00:00 2001 From: Aneesh Nireshwalia <99904+aneesh-n@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:52:26 -0700 Subject: [PATCH] Add ability to report warnings to terminal Report warnings to terminal when unrecognized generic attributes are found in the repository. --- cmd/restic/cmd_restore.go | 3 +++ internal/restic/node.go | 20 ++++++++++---------- internal/restic/node_aix.go | 4 ++-- internal/restic/node_netbsd.go | 4 ++-- internal/restic/node_openbsd.go | 4 ++-- internal/restic/node_test.go | 2 +- internal/restic/node_windows.go | 4 ++-- internal/restic/node_xattr.go | 4 ++-- internal/restorer/restorer.go | 3 ++- 9 files changed, 26 insertions(+), 22 deletions(-) diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index 37d304672..58f257541 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -178,6 +178,9 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions, totalErrors++ return nil } + res.Warn = func(message string) { + msg.E("Warning: %s\n", message) + } excludePatterns := filter.ParsePatterns(opts.Exclude) insensitiveExcludePatterns := filter.ParsePatterns(opts.InsensitiveExclude) diff --git a/internal/restic/node.go b/internal/restic/node.go index 44ca52b0c..cbe9ef363 100644 --- a/internal/restic/node.go +++ b/internal/restic/node.go @@ -224,8 +224,8 @@ func (node *Node) CreateAt(ctx context.Context, path string, repo BlobLoader) er } // RestoreMetadata restores node metadata -func (node Node) RestoreMetadata(path string) error { - err := node.restoreMetadata(path) +func (node Node) RestoreMetadata(path string, warn func(msg string)) error { + err := node.restoreMetadata(path, warn) if err != nil { debug.Log("restoreMetadata(%s) error %v", path, err) } @@ -233,7 +233,7 @@ func (node Node) RestoreMetadata(path string) error { return err } -func (node Node) restoreMetadata(path string) error { +func (node Node) restoreMetadata(path string, warn func(msg string)) error { var firsterr error if err := lchown(path, int(node.UID), int(node.GID)); err != nil { @@ -261,7 +261,7 @@ func (node Node) restoreMetadata(path string) error { } } - if err := node.restoreGenericAttributes(path); err != nil { + if err := node.restoreGenericAttributes(path, warn); err != nil { debug.Log("error restoring generic attributes for %v: %v", path, err) if firsterr != nil { firsterr = err @@ -766,14 +766,14 @@ func (node *Node) fillTimes(stat *statT) { } // HandleUnknownGenericAttributesFound is used for handling and distinguing between scenarios related to future versions and cross-OS repositories -func HandleUnknownGenericAttributesFound(unknownAttribs []GenericAttributeType) { +func HandleUnknownGenericAttributesFound(unknownAttribs []GenericAttributeType, warn func(msg string)) { for _, unknownAttrib := range unknownAttribs { - handleUnknownGenericAttributeFound(unknownAttrib) + handleUnknownGenericAttributeFound(unknownAttrib, warn) } } // handleUnknownGenericAttributeFound is used for handling and distinguing between scenarios related to future versions and cross-OS repositories -func handleUnknownGenericAttributeFound(genericAttributeType GenericAttributeType) { +func handleUnknownGenericAttributeFound(genericAttributeType GenericAttributeType, warn func(msg string)) { if checkGenericAttributeNameNotHandledAndPut(genericAttributeType) { // Print the unique error only once for a given execution os, exists := genericAttributesForOS[genericAttributeType] @@ -784,7 +784,7 @@ func handleUnknownGenericAttributeFound(genericAttributeType GenericAttributeTyp debug.Log("Ignoring a generic attribute found in the repository: %s which may not be compatible with your OS. Compatible OS: %s", genericAttributeType, os) } else { // If genericAttributesForOS in node.go does not know about this attribute, then the repository may have been created by a newer version which has a newer GenericAttributeType. - debug.Log("Found an unrecognized generic attribute in the repository: %s. You may need to upgrade to latest version of restic.", genericAttributeType) + warn(fmt.Sprintf("Found an unrecognized generic attribute in the repository: %s. You may need to upgrade to latest version of restic.", genericAttributeType)) } } } @@ -792,9 +792,9 @@ func handleUnknownGenericAttributeFound(genericAttributeType GenericAttributeTyp // handleAllUnknownGenericAttributesFound performs validations for all generic attributes in the node. // This is not used on windows currently because windows has handling for generic attributes. // nolint:unused -func (node Node) handleAllUnknownGenericAttributesFound() error { +func (node Node) handleAllUnknownGenericAttributesFound(warn func(msg string)) error { for name := range node.GenericAttributes { - handleUnknownGenericAttributeFound(name) + handleUnknownGenericAttributeFound(name, warn) } return nil } diff --git a/internal/restic/node_aix.go b/internal/restic/node_aix.go index 4d8c248de..def46bd60 100644 --- a/internal/restic/node_aix.go +++ b/internal/restic/node_aix.go @@ -39,8 +39,8 @@ func Setxattr(path, name string, data []byte) error { } // restoreGenericAttributes is no-op on AIX. -func (node *Node) restoreGenericAttributes(_ string) error { - return node.handleAllUnknownGenericAttributesFound() +func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { + return node.handleAllUnknownGenericAttributesFound(warn) } // fillGenericAttributes is a no-op on AIX. diff --git a/internal/restic/node_netbsd.go b/internal/restic/node_netbsd.go index be4afa3ae..1a47299be 100644 --- a/internal/restic/node_netbsd.go +++ b/internal/restic/node_netbsd.go @@ -29,8 +29,8 @@ func Setxattr(path, name string, data []byte) error { } // restoreGenericAttributes is no-op on netbsd. -func (node *Node) restoreGenericAttributes(_ string) error { - return node.handleAllUnknownGenericAttributesFound() +func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { + return node.handleAllUnknownGenericAttributesFound(warn) } // fillGenericAttributes is a no-op on netbsd. diff --git a/internal/restic/node_openbsd.go b/internal/restic/node_openbsd.go index bfff8f8aa..e60eb9dc8 100644 --- a/internal/restic/node_openbsd.go +++ b/internal/restic/node_openbsd.go @@ -29,8 +29,8 @@ func Setxattr(path, name string, data []byte) error { } // restoreGenericAttributes is no-op on openbsd. -func (node *Node) restoreGenericAttributes(_ string) error { - return node.handleAllUnknownGenericAttributesFound() +func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { + return node.handleAllUnknownGenericAttributesFound(warn) } // fillGenericAttributes is a no-op on openbsd. diff --git a/internal/restic/node_test.go b/internal/restic/node_test.go index c2c7306b7..d9fa02ac8 100644 --- a/internal/restic/node_test.go +++ b/internal/restic/node_test.go @@ -218,7 +218,7 @@ func TestNodeRestoreAt(t *testing.T) { nodePath = filepath.Join(tempdir, test.Name) } rtest.OK(t, test.CreateAt(context.TODO(), nodePath, nil)) - rtest.OK(t, test.RestoreMetadata(nodePath)) + rtest.OK(t, test.RestoreMetadata(nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) })) if test.Type == "dir" { rtest.OK(t, test.RestoreTimestamps(nodePath)) diff --git a/internal/restic/node_windows.go b/internal/restic/node_windows.go index a2b8c75e5..5875c3ccd 100644 --- a/internal/restic/node_windows.go +++ b/internal/restic/node_windows.go @@ -118,7 +118,7 @@ func (s statT) ctim() syscall.Timespec { } // restoreGenericAttributes restores generic attributes for Windows -func (node Node) restoreGenericAttributes(path string) (err error) { +func (node Node) restoreGenericAttributes(path string, warn func(msg string)) (err error) { if len(node.GenericAttributes) == 0 { return nil } @@ -138,7 +138,7 @@ func (node Node) restoreGenericAttributes(path string) (err error) { } } - HandleUnknownGenericAttributesFound(unknownAttribs) + HandleUnknownGenericAttributesFound(unknownAttribs, warn) return errors.CombineErrors(errs...) } diff --git a/internal/restic/node_xattr.go b/internal/restic/node_xattr.go index 826b8b74a..0b2d5d552 100644 --- a/internal/restic/node_xattr.go +++ b/internal/restic/node_xattr.go @@ -50,8 +50,8 @@ func handleXattrErr(err error) error { } // restoreGenericAttributes is no-op. -func (node *Node) restoreGenericAttributes(_ string) error { - return node.handleAllUnknownGenericAttributesFound() +func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { + return node.handleAllUnknownGenericAttributesFound(warn) } // fillGenericAttributes is a no-op. diff --git a/internal/restorer/restorer.go b/internal/restorer/restorer.go index 3f4fb32e3..0aeb636d0 100644 --- a/internal/restorer/restorer.go +++ b/internal/restorer/restorer.go @@ -24,6 +24,7 @@ type Restorer struct { progress *restoreui.Progress Error func(location string, err error) error + Warn func(message string) SelectFilter func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) } @@ -178,7 +179,7 @@ func (res *Restorer) restoreNodeTo(ctx context.Context, node *restic.Node, targe func (res *Restorer) restoreNodeMetadataTo(node *restic.Node, target, location string) error { debug.Log("restoreNodeMetadata %v %v %v", node.Name, target, location) - err := node.RestoreMetadata(target) + err := node.RestoreMetadata(target, res.Warn) if err != nil { debug.Log("node.RestoreMetadata(%s) error %v", target, err) }