error codes

This commit is contained in:
2022-04-12 21:37:35 +02:00
parent 4839c013b9
commit fe6c6f2373
5 changed files with 38 additions and 27 deletions

View File

@@ -122,13 +122,13 @@ func (b Backend) validate() error {
} }
options := ExecuteOptions{Envs: env} options := ExecuteOptions{Envs: env}
// Check if already initialized // Check if already initialized
_, err = ExecuteResticCommand(options, "snapshots") _, _, err = ExecuteResticCommand(options, "snapshots")
if err == nil { if err == nil {
return nil return nil
} else { } else {
// If not initialize // If not initialize
colors.Body.Printf("Initializing backend \"%s\"...\n", b.name) colors.Body.Printf("Initializing backend \"%s\"...\n", b.name)
out, err := ExecuteResticCommand(options, "init") _, out, err := ExecuteResticCommand(options, "init")
if flags.VERBOSE { if flags.VERBOSE {
colors.Faint.Println(out) colors.Faint.Println(out)
} }
@@ -142,7 +142,7 @@ func (b Backend) Exec(args []string) error {
return err return err
} }
options := ExecuteOptions{Envs: env} options := ExecuteOptions{Envs: env}
out, err := ExecuteResticCommand(options, args...) _, out, err := ExecuteResticCommand(options, args...)
if err != nil { if err != nil {
colors.Error.Println(out) colors.Error.Println(out)
return err return err
@@ -153,10 +153,10 @@ func (b Backend) Exec(args []string) error {
return nil return nil
} }
func (b Backend) ExecDocker(l Location, args []string) (string, error) { func (b Backend) ExecDocker(l Location, args []string) (int, string, error) {
env, err := b.getEnv() env, err := b.getEnv()
if err != nil { if err != nil {
return "", err return -1, "", err
} }
volume := l.From[0] volume := l.From[0]
options := ExecuteOptions{ options := ExecuteOptions{
@@ -188,20 +188,19 @@ func (b Backend) ExecDocker(l Location, args []string) (string, error) {
// No additional setup needed // No additional setup needed
case "rclone": case "rclone":
// Read host rclone config and mount it into the container // Read host rclone config and mount it into the container
configFile, err := ExecuteCommand(ExecuteOptions{Command: "rclone"}, "config", "file") code, configFile, err := ExecuteCommand(ExecuteOptions{Command: "rclone"}, "config", "file")
if err != nil { if err != nil {
return "", err return code, "", err
} }
splitted := strings.Split(strings.TrimSpace(configFile), "\n") splitted := strings.Split(strings.TrimSpace(configFile), "\n")
configFilePath := splitted[len(splitted)-1] configFilePath := splitted[len(splitted)-1]
docker = append(docker, "--volume", configFilePath+":"+"/root/.config/rclone/rclone.conf:ro") docker = append(docker, "--volume", configFilePath+":"+"/root/.config/rclone/rclone.conf:ro")
default: default:
return "", fmt.Errorf("Backend type \"%s\" is not supported as volume endpoint", b.Type) return -1, "", fmt.Errorf("Backend type \"%s\" is not supported as volume endpoint", b.Type)
} }
for key, value := range env { for key, value := range env {
docker = append(docker, "--env", key+"="+value) docker = append(docker, "--env", key+"="+value)
} }
docker = append(docker, "cupcakearmy/autorestic:"+VERSION, "-c", strings.Join(args, " ")) docker = append(docker, "cupcakearmy/autorestic:"+VERSION, "-c", strings.Join(args, " "))
out, err := ExecuteCommand(options, docker...) return ExecuteCommand(options, docker...)
return out, err
} }

View File

@@ -128,7 +128,7 @@ func InstallRestic() error {
} }
func upgradeRestic() error { func upgradeRestic() error {
out, err := internal.ExecuteCommand(internal.ExecuteOptions{ _, out, err := internal.ExecuteCommand(internal.ExecuteOptions{
Command: "restic", Command: "restic",
}, "self-update") }, "self-update")
colors.Faint.Println(out) colors.Faint.Println(out)

View File

@@ -104,7 +104,7 @@ func (l Location) ExecuteHooks(commands []string, options ExecuteOptions) error
colors.Secondary.Println("\nRunning hooks") colors.Secondary.Println("\nRunning hooks")
for _, command := range commands { for _, command := range commands {
colors.Body.Println("> " + command) colors.Body.Println("> " + command)
out, err := ExecuteCommand(options, "-c", command) _, out, err := ExecuteCommand(options, "-c", command)
if err != nil { if err != nil {
colors.Error.Println(out) colors.Error.Println(out)
return err return err
@@ -195,6 +195,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
Envs: env, Envs: env,
} }
var code int = 0
var out string var out string
switch t { switch t {
case TypeLocal: case TypeLocal:
@@ -206,7 +207,7 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
} }
cmd = append(cmd, path) cmd = append(cmd, path)
} }
out, err = ExecuteResticCommand(backupOptions, cmd...) code, out, err = ExecuteResticCommand(backupOptions, cmd...)
case TypeVolume: case TypeVolume:
ok := CheckIfVolumeExists(l.From[0]) ok := CheckIfVolumeExists(l.From[0])
if !ok { if !ok {
@@ -214,20 +215,25 @@ func (l Location) Backup(cron bool, specificBackend string) []error {
continue continue
} }
cmd = append(cmd, "/data") cmd = append(cmd, "/data")
out, err = backend.ExecDocker(l, cmd) code, out, err = backend.ExecDocker(l, cmd)
} }
// Extract metadata
md := metadata.ExtractMetadataFromBackupLog(out)
md.ExitCode = fmt.Sprint(code)
mdEnv := metadata.MakeEnvFromMetadata(&md)
for k, v := range mdEnv {
options.Envs[k+"_"+fmt.Sprint(i)] = v
options.Envs[k+"_"+strings.ToUpper(backend.name)] = v
}
// If error save it and continue
if err != nil { if err != nil {
colors.Error.Println(out) colors.Error.Println(out)
errors = append(errors, fmt.Errorf("%s@%s:\n%s%s", l.name, backend.name, out, err)) errors = append(errors, fmt.Errorf("%s@%s:\n%s%s", l.name, backend.name, out, err))
continue continue
} }
md := metadata.ExtractMetadataFromBackupLog(out)
mdEnv := metadata.MakeEnvFromMetadata(&md)
for k, v := range mdEnv {
options.Envs[k+"_"+fmt.Sprint(i)] = v
options.Envs[k+"_"+strings.ToUpper(backend.name)] = v
}
if flags.VERBOSE { if flags.VERBOSE {
colors.Faint.Println(out) colors.Faint.Println(out)
} }
@@ -276,7 +282,7 @@ func (l Location) Forget(prune bool, dry bool) error {
cmd = append(cmd, "--dry-run") cmd = append(cmd, "--dry-run")
} }
cmd = append(cmd, combineOptions("forget", l, backend)...) cmd = append(cmd, combineOptions("forget", l, backend)...)
out, err := ExecuteResticCommand(options, cmd...) _, out, err := ExecuteResticCommand(options, cmd...)
if flags.VERBOSE { if flags.VERBOSE {
colors.Faint.Println(out) colors.Faint.Println(out)
} }
@@ -348,7 +354,7 @@ func (l Location) Restore(to, from string, force bool, snapshot string, options
} }
err = backend.Exec(buildRestoreCommand(l, to, snapshot, options)) err = backend.Exec(buildRestoreCommand(l, to, snapshot, options))
case TypeVolume: case TypeVolume:
_, err = backend.ExecDocker(l, buildRestoreCommand(l, "/", snapshot, options)) _, _, err = backend.ExecDocker(l, buildRestoreCommand(l, "/", snapshot, options))
} }
if err != nil { if err != nil {
return err return err

View File

@@ -21,6 +21,7 @@ type BackupLogMetadata struct {
AddedSize string AddedSize string
Processed BackupLogMetadataProcessed Processed BackupLogMetadataProcessed
SnapshotID string SnapshotID string
ExitCode string
} }
type MetadatExtractor interface { type MetadatExtractor interface {
@@ -67,6 +68,7 @@ func MakeEnvFromMetadata(metadata *BackupLogMetadata) map[string]string {
env[prefix+"PROCESSED_FILES"] = metadata.Processed.Files env[prefix+"PROCESSED_FILES"] = metadata.Processed.Files
env[prefix+"PROCESSED_SIZE"] = metadata.Processed.Size env[prefix+"PROCESSED_SIZE"] = metadata.Processed.Size
env[prefix+"PROCESSED_DURATION"] = metadata.Processed.Duration env[prefix+"PROCESSED_DURATION"] = metadata.Processed.Duration
env[prefix+"EXIT_CODE"] = metadata.ExitCode
return env return env
} }

View File

@@ -28,7 +28,7 @@ type ExecuteOptions struct {
Dir string Dir string
} }
func ExecuteCommand(options ExecuteOptions, args ...string) (string, error) { func ExecuteCommand(options ExecuteOptions, args ...string) (int, string, error) {
cmd := exec.Command(options.Command, args...) cmd := exec.Command(options.Command, args...)
env := os.Environ() env := os.Environ()
for k, v := range options.Envs { for k, v := range options.Envs {
@@ -47,12 +47,16 @@ func ExecuteCommand(options ExecuteOptions, args ...string) (string, error) {
cmd.Stderr = &error cmd.Stderr = &error
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
return error.String(), err if exitError, ok := err.(*exec.ExitError); ok {
return exitError.ExitCode(), error.String(), err
} else {
return -1, error.String(), err
}
} }
return out.String(), nil return 0, out.String(), nil
} }
func ExecuteResticCommand(options ExecuteOptions, args ...string) (string, error) { func ExecuteResticCommand(options ExecuteOptions, args ...string) (int, string, error) {
options.Command = RESTIC_BIN options.Command = RESTIC_BIN
var c = GetConfig() var c = GetConfig()
var optionsAsString = getOptions(c.Global, "") var optionsAsString = getOptions(c.Global, "")
@@ -80,6 +84,6 @@ func CopyFile(from, to string) error {
} }
func CheckIfVolumeExists(volume string) bool { func CheckIfVolumeExists(volume string) bool {
_, err := ExecuteCommand(ExecuteOptions{Command: "docker"}, "volume", "inspect", volume) _, _, err := ExecuteCommand(ExecuteOptions{Command: "docker"}, "volume", "inspect", volume)
return err == nil return err == nil
} }