mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2026-04-02 11:55:23 +00:00
error codes
This commit is contained in:
@@ -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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user