2014-04-27 22:00:15 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-05-01 08:09:24 +00:00
|
|
|
"bufio"
|
|
|
|
"bytes"
|
2015-07-12 20:10:01 +00:00
|
|
|
"fmt"
|
2017-05-01 08:09:24 +00:00
|
|
|
"log"
|
2016-08-03 18:29:08 +00:00
|
|
|
"os"
|
2017-06-11 12:17:44 +00:00
|
|
|
"runtime"
|
2016-08-21 15:46:23 +00:00
|
|
|
|
2017-07-23 12:21:03 +00:00
|
|
|
"github.com/restic/restic/internal/debug"
|
|
|
|
"github.com/restic/restic/internal/options"
|
2017-07-24 15:42:25 +00:00
|
|
|
"github.com/restic/restic/internal/restic"
|
2017-07-23 12:21:03 +00:00
|
|
|
|
2016-09-17 10:36:05 +00:00
|
|
|
"github.com/spf13/cobra"
|
2016-09-01 20:17:37 +00:00
|
|
|
|
2017-07-23 12:21:03 +00:00
|
|
|
"github.com/restic/restic/internal/errors"
|
2014-04-27 22:00:15 +00:00
|
|
|
)
|
|
|
|
|
2016-09-17 10:36:05 +00:00
|
|
|
// cmdRoot is the base command when no other command has been specified.
|
|
|
|
var cmdRoot = &cobra.Command{
|
|
|
|
Use: "restic",
|
|
|
|
Short: "backup and restore files",
|
|
|
|
Long: `
|
|
|
|
restic is a backup program which allows saving multiple revisions of files and
|
|
|
|
directories in an encrypted repository stored on different backends.
|
|
|
|
`,
|
2017-01-02 18:14:22 +00:00
|
|
|
SilenceErrors: true,
|
|
|
|
SilenceUsage: true,
|
2017-01-22 18:10:32 +00:00
|
|
|
|
2017-01-23 16:52:26 +00:00
|
|
|
PersistentPreRunE: func(*cobra.Command, []string) error {
|
2017-03-25 14:33:52 +00:00
|
|
|
// parse extended options
|
|
|
|
opts, err := options.Parse(globalOptions.Options)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
globalOptions.extended = opts
|
|
|
|
|
2017-07-24 21:01:16 +00:00
|
|
|
pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD")
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err)
|
|
|
|
Exit(1)
|
|
|
|
}
|
|
|
|
globalOptions.password = pwd
|
|
|
|
|
2017-03-25 14:33:52 +00:00
|
|
|
// run the debug functions for all subcommands (if build tag "debug" is
|
|
|
|
// enabled)
|
|
|
|
if err := runDebug(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2017-01-23 16:52:26 +00:00
|
|
|
},
|
|
|
|
PersistentPostRun: func(*cobra.Command, []string) {
|
|
|
|
shutdownDebug()
|
2017-01-22 18:10:32 +00:00
|
|
|
},
|
2016-09-17 10:36:05 +00:00
|
|
|
}
|
|
|
|
|
2017-05-01 08:09:24 +00:00
|
|
|
var logBuffer = bytes.NewBuffer(nil)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// install custom global logger into a buffer, if an error occurs
|
|
|
|
// we can show the logs
|
|
|
|
log.SetOutput(logBuffer)
|
|
|
|
}
|
|
|
|
|
2014-04-27 22:00:15 +00:00
|
|
|
func main() {
|
2016-09-27 20:35:08 +00:00
|
|
|
debug.Log("main %#v", os.Args)
|
2017-06-11 12:17:44 +00:00
|
|
|
debug.Log("restic %s, compiled with %v on %v/%v",
|
|
|
|
version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
2016-09-17 10:36:05 +00:00
|
|
|
err := cmdRoot.Execute()
|
2016-08-28 20:19:48 +00:00
|
|
|
|
|
|
|
switch {
|
|
|
|
case restic.IsAlreadyLocked(errors.Cause(err)):
|
|
|
|
fmt.Fprintf(os.Stderr, "%v\nthe `unlock` command can be used to remove stale locks\n", err)
|
2016-09-01 20:17:37 +00:00
|
|
|
case errors.IsFatal(errors.Cause(err)):
|
2016-08-28 20:19:48 +00:00
|
|
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
|
|
case err != nil:
|
2016-08-21 16:07:13 +00:00
|
|
|
fmt.Fprintf(os.Stderr, "%+v\n", err)
|
2017-05-01 08:09:24 +00:00
|
|
|
|
|
|
|
if logBuffer.Len() > 0 {
|
|
|
|
fmt.Fprintf(os.Stderr, "also, the following messages were logged by a library:\n")
|
|
|
|
sc := bufio.NewScanner(logBuffer)
|
|
|
|
for sc.Scan() {
|
|
|
|
fmt.Fprintln(os.Stderr, sc.Text())
|
|
|
|
}
|
|
|
|
}
|
2016-01-17 15:59:03 +00:00
|
|
|
}
|
|
|
|
|
2016-12-28 09:53:31 +00:00
|
|
|
var exitCode int
|
2014-09-23 20:39:12 +00:00
|
|
|
if err != nil {
|
2016-12-28 09:53:31 +00:00
|
|
|
exitCode = 1
|
2014-04-27 22:00:15 +00:00
|
|
|
}
|
2016-12-28 09:53:31 +00:00
|
|
|
|
|
|
|
Exit(exitCode)
|
2014-04-27 22:00:15 +00:00
|
|
|
}
|