package backup import ( "context" "fmt" "log" "os" "os/exec" ) // RsyncStrategy implements the backup strategy using rsync type RsyncStrategy struct { Options string Destination Destination } // NewRsyncStrategy creates a new rsync strategy func NewRsyncStrategy(options string, destination Destination) *RsyncStrategy { return &RsyncStrategy{ Options: options, Destination: destination, } } // Execute performs the rsync backup func (s *RsyncStrategy) Execute(ctx context.Context, serviceName, directory string) error { log.Printf("Performing rsync backup for %s", serviceName) // Build rsync command dst := s.Destination sshKeyOption := "" // Without if dst.SSHKey != "" { sshKeyOption = fmt.Sprintf("-e 'ssh -i %s'", dst.SSHKey) } destination := fmt.Sprintf("%s:%s", dst.Host, dst.Path) rsyncCmd := fmt.Sprintf("rsync %s %s %s %s", s.Options, sshKeyOption, directory, destination) // Run rsync command log.Printf("Running: %s", rsyncCmd) cmd := exec.CommandContext(ctx, "sh", "-c", rsyncCmd) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }