Use a .new temp file while gathering info, only move it into place on success
This commit is contained in:
33
src/ssh.go
33
src/ssh.go
@ -209,29 +209,34 @@ func (rb *RouterBackup) BackupCommands(commands []string, outputDir string) erro
|
||||
}
|
||||
|
||||
filename := rb.hostname
|
||||
filepath := filepath.Join(outputDir, filename)
|
||||
finalPath := filepath.Join(outputDir, filename)
|
||||
tempPath := finalPath + ".new"
|
||||
|
||||
// Truncate file at start
|
||||
file, err := os.Create(filepath)
|
||||
// Create temporary file
|
||||
file, err := os.Create(tempPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file %s: %v", filepath, err)
|
||||
return fmt.Errorf("failed to create temporary file %s: %v", tempPath, err)
|
||||
}
|
||||
file.Close()
|
||||
|
||||
successCount := 0
|
||||
hasErrors := false
|
||||
|
||||
for i, command := range commands {
|
||||
fmt.Printf("Running command %d/%d: %s\n", i+1, len(commands), command)
|
||||
output, err := rb.RunCommand(command)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error executing '%s': %v\n", command, err)
|
||||
hasErrors = true
|
||||
continue
|
||||
}
|
||||
|
||||
// Append to file
|
||||
file, err := os.OpenFile(filepath, os.O_APPEND|os.O_WRONLY, 0644)
|
||||
// Append to temporary file
|
||||
file, err := os.OpenFile(tempPath, os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to open file for writing: %v\n", err)
|
||||
hasErrors = true
|
||||
continue
|
||||
}
|
||||
|
||||
@ -243,9 +248,21 @@ func (rb *RouterBackup) BackupCommands(commands []string, outputDir string) erro
|
||||
}
|
||||
|
||||
fmt.Printf("Summary: %d/%d commands successful\n", successCount, len(commands))
|
||||
if successCount > 0 {
|
||||
fmt.Printf("Output saved to %s\n", filepath)
|
||||
|
||||
if hasErrors || successCount == 0 {
|
||||
// Remove .new suffix and log error
|
||||
if err := os.Remove(tempPath); err != nil {
|
||||
fmt.Printf("Failed to remove temporary file %s: %v\n", tempPath, err)
|
||||
}
|
||||
return fmt.Errorf("device backup incomplete due to command failures")
|
||||
}
|
||||
|
||||
// All commands succeeded, move file into place atomically
|
||||
if err := os.Rename(tempPath, finalPath); err != nil {
|
||||
return fmt.Errorf("failed to move temporary file to final location: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Output saved to %s\n", finalPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user