Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions backup/cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ import (
"github.com/spf13/cobra"
)

func executeSyncJobs(cfg internal.Config, simulate bool) {
func getLogPath(create bool) string {
logPath := fmt.Sprintf("logs/sync-%s", time.Now().Format("2006-01-02T15-04-05"))

if err := os.MkdirAll(logPath, 0755); err != nil {
log.Fatalf("Failed to create log directory: %v", err)
if create {
if err := os.MkdirAll(logPath, 0755); err != nil {
log.Fatalf("Failed to create log directory: %v", err)
}
}
return logPath
}

func executeSyncJobs(cfg internal.Config, simulate bool) {
logPath := getLogPath(true)

overallLogPath := fmt.Sprintf("%s/summary.log", logPath)
overallLogFile, err := os.OpenFile(overallLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
Expand All @@ -28,23 +34,17 @@ func executeSyncJobs(cfg internal.Config, simulate bool) {

for _, job := range cfg.Jobs {
jobLogPath := fmt.Sprintf("%s/job-%s.log", logPath, job.Name)
logFile, err := os.OpenFile(jobLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
overallLogger.Printf("ERROR [%s]: Failed to create job log file: %v", job.Name, err)
continue
}
defer logFile.Close()
jobLogger := log.New(logFile, "", log.LstdFlags)

status := internal.ExecuteJob(job, simulate, false, jobLogger)
status := internal.ExecuteJob(job, simulate, false, jobLogPath)
overallLogger.Printf("STATUS [%s]: %s", job.Name, status)
fmt.Printf("Status [%s]: %s\n", job.Name, status)
}
}

func listCommands(cfg internal.Config, simulate bool) {
func listCommands(cfg internal.Config) {
logPath := getLogPath(false)
for _, job := range cfg.Jobs {
internal.ExecuteJob(job, simulate, true, nil)
jobLogPath := fmt.Sprintf("%s/job-%s.log", logPath, job.Name)
internal.ExecuteJob(job, false, true, jobLogPath)
}
}

Expand All @@ -71,7 +71,7 @@ var listCmd = &cobra.Command{
Short: "List the commands that will be executed",
Run: func(cmd *cobra.Command, args []string) {
cfg := loadResolvedConfig(configPath)
listCommands(cfg, true)
listCommands(cfg)
},
}

Expand Down
22 changes: 8 additions & 14 deletions backup/internal/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package internal

import (
"fmt"
"log"
"os/exec"
"strings"
)

var execCommand = exec.Command

func buildRsyncCmd(job Job, simulate bool) []string {
args := []string{"-aiv", "--info=progress2"}
func buildRsyncCmd(job Job, simulate bool, logPath string) []string {
args := []string{"-aiv", "--stats"}
if job.Delete == nil || *job.Delete {
args = append(args, "--delete")
}
if logPath != "" {
args = append(args, fmt.Sprintf("--log-file=%s", logPath))
}
for _, excl := range job.Exclusions {
args = append(args, fmt.Sprintf("--exclude=%s", excl))
}
Expand All @@ -24,15 +26,12 @@ func buildRsyncCmd(job Job, simulate bool) []string {
return args
}

func ExecuteJob(job Job, simulate bool, show bool, logger *log.Logger) string {
func ExecuteJob(job Job, simulate bool, show bool, logPath string) string {
if job.Enabled != nil && !*job.Enabled {
if logger != nil {
logger.Printf("SKIPPED [%s]: Job is disabled", job.Name)
}
return "SKIPPED"
}

args := buildRsyncCmd(job, simulate)
args := buildRsyncCmd(job, simulate, logPath)
fmt.Printf("Job: %s\n", job.Name)
fmt.Printf("Command: rsync %s\n", strings.Join(args, " "))

Expand All @@ -42,14 +41,9 @@ func ExecuteJob(job Job, simulate bool, show bool, logger *log.Logger) string {

cmd := execCommand("rsync", args...)
out, err := cmd.CombinedOutput()
fmt.Printf("Output:\n%s\n", string(out))
if err != nil {
if logger != nil {
logger.Printf("ERROR [%s]: %v\nOutput: %s", job.Name, err, string(out))
}
return "FAILURE"
}
if logger != nil {
logger.Printf("SUCCESS [%s]: %s", job.Name, string(out))
}
return "SUCCESS"
}
34 changes: 9 additions & 25 deletions backup/internal/job_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package internal

import (
"bytes"
"log"
"os/exec"
"strings"
"testing"
Expand Down Expand Up @@ -40,11 +38,10 @@ func TestBuildRsyncCmd(t *testing.T) {
Delete: nil,
Exclusions: []string{"*.tmp", "node_modules/"},
}
simulate := true
args := buildRsyncCmd(job, simulate)
args := buildRsyncCmd(job, true, "")

expectedArgs := []string{
"--dry-run", "-aiv", "--info=progress2", "--delete",
"--dry-run", "-aiv", "--stats", "--delete",
"--exclude=*.tmp", "--exclude=node_modules/",
"/home/user/Music/", "/target/user/music/home",
}
Expand All @@ -63,9 +60,8 @@ func TestExecuteJob(t *testing.T) {
Exclusions: []string{"*.tmp"},
}
simulate := true
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)

status := ExecuteJob(job, simulate, false, logger)
status := ExecuteJob(job, simulate, false, "")
if status != "SUCCESS" {
t.Errorf("Expected status SUCCESS, got %s", status)
}
Expand All @@ -77,7 +73,7 @@ func TestExecuteJob(t *testing.T) {
Enabled: boolPtr(false),
}

status = ExecuteJob(disabledJob, simulate, false, logger)
status = ExecuteJob(disabledJob, simulate, false, "")
if status != "SKIPPED" {
t.Errorf("Expected status SKIPPED, got %s", status)
}
Expand All @@ -89,7 +85,7 @@ func TestExecuteJob(t *testing.T) {
Target: "/mnt/backup1/invalid/",
}

status = ExecuteJob(invalidJob, false, false, logger)
status = ExecuteJob(invalidJob, false, false, "")
if status != "FAILURE" {
t.Errorf("Expected status FAILURE, got %s", status)
}
Expand All @@ -102,10 +98,7 @@ func TestJobSkippedEnabledTrue(t *testing.T) {
Target: "/mnt/backup1/test/",
Enabled: boolPtr(true),
}
simulate := true
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)

status := ExecuteJob(job, simulate, false, logger)
status := ExecuteJob(job, true, false, "")
if status != "SUCCESS" {
t.Errorf("Expected status SUCCESS, got %s", status)
}
Expand All @@ -118,10 +111,7 @@ func TestJobSkippedEnabledFalse(t *testing.T) {
Target: "/mnt/backup1/disabled/",
Enabled: boolPtr(false),
}
simulate := true
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)

status := ExecuteJob(disabledJob, simulate, false, logger)
status := ExecuteJob(disabledJob, true, false, "")
if status != "SKIPPED" {
t.Errorf("Expected status SKIPPED, got %s", status)
}
Expand All @@ -133,10 +123,7 @@ func TestJobSkippedEnabledOmitted(t *testing.T) {
Source: "/home/omitted/",
Target: "/mnt/backup1/omitted/",
}
simulate := true
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)

status := ExecuteJob(job, simulate, false, logger)
status := ExecuteJob(job, true, false, "")
if status != "SUCCESS" {
t.Errorf("Expected status SUCCESS, got %s", status)
}
Expand All @@ -153,10 +140,7 @@ func TestExecuteJobWithMockedRsync(t *testing.T) {
Delete: nil,
Exclusions: []string{"*.tmp"},
}
simulate := true
logger := log.New(&bytes.Buffer{}, "", log.LstdFlags)

status := ExecuteJob(job, simulate, false, logger)
status := ExecuteJob(job, true, false, "")

if status != "SUCCESS" {
t.Errorf("Expected status SUCCESS, got %s", status)
Expand Down