mirror of
https://github.com/octoleo/restic.git
synced 2024-11-28 15:56:37 +00:00
Allow cleanup handlers to filter the exit code
This commit is contained in:
parent
908f7441fe
commit
d768c1c3e4
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
var cleanupHandlers struct {
|
var cleanupHandlers struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
list []func() error
|
list []func(code int) (int, error)
|
||||||
done bool
|
done bool
|
||||||
ch chan os.Signal
|
ch chan os.Signal
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ func init() {
|
|||||||
// AddCleanupHandler adds the function f to the list of cleanup handlers so
|
// AddCleanupHandler adds the function f to the list of cleanup handlers so
|
||||||
// that it is executed when all the cleanup handlers are run, e.g. when SIGINT
|
// that it is executed when all the cleanup handlers are run, e.g. when SIGINT
|
||||||
// is received.
|
// is received.
|
||||||
func AddCleanupHandler(f func() error) {
|
func AddCleanupHandler(f func(code int) (int, error)) {
|
||||||
cleanupHandlers.Lock()
|
cleanupHandlers.Lock()
|
||||||
defer cleanupHandlers.Unlock()
|
defer cleanupHandlers.Unlock()
|
||||||
|
|
||||||
@ -36,22 +36,24 @@ func AddCleanupHandler(f func() error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunCleanupHandlers runs all registered cleanup handlers
|
// RunCleanupHandlers runs all registered cleanup handlers
|
||||||
func RunCleanupHandlers() {
|
func RunCleanupHandlers(code int) int {
|
||||||
cleanupHandlers.Lock()
|
cleanupHandlers.Lock()
|
||||||
defer cleanupHandlers.Unlock()
|
defer cleanupHandlers.Unlock()
|
||||||
|
|
||||||
if cleanupHandlers.done {
|
if cleanupHandlers.done {
|
||||||
return
|
return code
|
||||||
}
|
}
|
||||||
cleanupHandlers.done = true
|
cleanupHandlers.done = true
|
||||||
|
|
||||||
for _, f := range cleanupHandlers.list {
|
for _, f := range cleanupHandlers.list {
|
||||||
err := f()
|
var err error
|
||||||
|
code, err = f(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error in cleanup handler: %v\n", err)
|
Warnf("error in cleanup handler: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanupHandlers.list = nil
|
cleanupHandlers.list = nil
|
||||||
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanupHandler handles the SIGINT signals.
|
// CleanupHandler handles the SIGINT signals.
|
||||||
@ -75,6 +77,6 @@ func CleanupHandler(c <-chan os.Signal) {
|
|||||||
// Exit runs the cleanup handlers and then terminates the process with the
|
// Exit runs the cleanup handlers and then terminates the process with the
|
||||||
// given exit code.
|
// given exit code.
|
||||||
func Exit(code int) {
|
func Exit(code int) {
|
||||||
RunCleanupHandlers()
|
code = RunCleanupHandlers(code)
|
||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
@ -197,9 +197,9 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup := prepareCheckCache(opts, &gopts)
|
cleanup := prepareCheckCache(opts, &gopts)
|
||||||
AddCleanupHandler(func() error {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
cleanup()
|
cleanup()
|
||||||
return nil
|
return code, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(gopts)
|
||||||
|
@ -158,13 +158,13 @@ func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCleanupHandler(func() error {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
debug.Log("running umount cleanup handler for mount at %v", mountpoint)
|
debug.Log("running umount cleanup handler for mount at %v", mountpoint)
|
||||||
err := umount(mountpoint)
|
err := umount(mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("unable to umount (maybe already umounted or still in use?): %v\n", err)
|
Warnf("unable to umount (maybe already umounted or still in use?): %v\n", err)
|
||||||
}
|
}
|
||||||
return nil
|
return code, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
c, err := systemFuse.Mount(mountpoint, mountOptions...)
|
c, err := systemFuse.Mount(mountpoint, mountOptions...)
|
||||||
|
@ -97,11 +97,11 @@ var isReadingPassword bool
|
|||||||
func init() {
|
func init() {
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
globalOptions.ctx, cancel = context.WithCancel(context.Background())
|
globalOptions.ctx, cancel = context.WithCancel(context.Background())
|
||||||
AddCleanupHandler(func() error {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
// Must be called before the unlock cleanup handler to ensure that the latter is
|
// Must be called before the unlock cleanup handler to ensure that the latter is
|
||||||
// not blocked due to limited number of backend connections, see #1434
|
// not blocked due to limited number of backend connections, see #1434
|
||||||
cancel()
|
cancel()
|
||||||
return nil
|
return code, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
f := cmdRoot.PersistentFlags()
|
f := cmdRoot.PersistentFlags()
|
||||||
@ -199,20 +199,20 @@ func restoreTerminal() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCleanupHandler(func() error {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
// Restoring the terminal configuration while restic runs in the
|
// Restoring the terminal configuration while restic runs in the
|
||||||
// background, causes restic to get stopped on unix systems with
|
// background, causes restic to get stopped on unix systems with
|
||||||
// a SIGTTOU signal. Thus only restore the terminal settings if
|
// a SIGTTOU signal. Thus only restore the terminal settings if
|
||||||
// they might have been modified, which is the case while reading
|
// they might have been modified, which is the case while reading
|
||||||
// a password.
|
// a password.
|
||||||
if !isReadingPassword {
|
if !isReadingPassword {
|
||||||
return nil
|
return code, nil
|
||||||
}
|
}
|
||||||
err := checkErrno(term.Restore(fd, state))
|
err := checkErrno(term.Restore(fd, state))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err)
|
fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err)
|
||||||
}
|
}
|
||||||
return err
|
return code, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +84,9 @@ func runDebug() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if prof != nil {
|
if prof != nil {
|
||||||
AddCleanupHandler(func() error {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
prof.Stop()
|
prof.Stop()
|
||||||
return nil
|
return code, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ func unlockRepo(lock *restic.Lock) {
|
|||||||
debug.Log("unable to find lock %v in the global list of locks, ignoring", lock)
|
debug.Log("unable to find lock %v in the global list of locks, ignoring", lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unlockAll() error {
|
func unlockAll(code int) (int, error) {
|
||||||
globalLocks.Lock()
|
globalLocks.Lock()
|
||||||
defer globalLocks.Unlock()
|
defer globalLocks.Unlock()
|
||||||
|
|
||||||
@ -127,11 +127,11 @@ func unlockAll() error {
|
|||||||
for _, lock := range globalLocks.locks {
|
for _, lock := range globalLocks.locks {
|
||||||
if err := lock.Unlock(); err != nil {
|
if err := lock.Unlock(); err != nil {
|
||||||
debug.Log("error while unlocking: %v", err)
|
debug.Log("error while unlocking: %v", err)
|
||||||
return err
|
return code, err
|
||||||
}
|
}
|
||||||
debug.Log("successfully removed lock")
|
debug.Log("successfully removed lock")
|
||||||
}
|
}
|
||||||
globalLocks.locks = globalLocks.locks[:0]
|
globalLocks.locks = globalLocks.locks[:0]
|
||||||
|
|
||||||
return nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user