mirror of
https://github.com/Adembc/lazyssh.git
synced 2026-07-14 12:13:34 +02:00
feat: backup the original file before manage it by lazyssh (#49)
This commit is contained in:
@@ -53,6 +53,14 @@ It is simply a UI/TUI wrapper around your existing `~/.ssh/config` file.
|
|||||||
- File permissions on your SSH config are preserved to ensure security.
|
- File permissions on your SSH config are preserved to ensure security.
|
||||||
|
|
||||||
|
|
||||||
|
## 🛡️ Config Safety: Non‑destructive writes and backups
|
||||||
|
|
||||||
|
- Non‑destructive edits: lazyssh only writes the minimal required changes to your ~/.ssh/config. It uses a parser that preserves existing comments, spacing, order, and any settings it didn’t touch. Your handcrafted comments and formatting remain intact.
|
||||||
|
- Atomic writes: updates are written to a temporary file and then atomically renamed over the original, minimizing the risk of partial writes.
|
||||||
|
- Backups:
|
||||||
|
- One‑time original backup: before lazyssh makes its first change, it creates a single snapshot named config.original.backup beside your SSH config. If this file is present, it will never be recreated or overwritten.
|
||||||
|
- Rolling backups: on every subsequent save, lazyssh also creates a timestamped backup named like: ~/.ssh/config-<timestamp>-lazyssh.backup. The app keeps at most 10 of these backups, automatically removing the oldest ones.
|
||||||
|
|
||||||
## 📷 Screenshots
|
## 📷 Screenshots
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|||||||
@@ -125,3 +125,29 @@ func (r *Repository) findBackupFiles(dir string) ([]os.FileInfo, error) {
|
|||||||
|
|
||||||
return backupFiles, nil
|
return backupFiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createOriginalBackupIfNeeded creates a one-time original backup of the current SSH config.
|
||||||
|
func (r *Repository) createOriginalBackupIfNeeded() error {
|
||||||
|
// If no SSH config file, nothing to do.
|
||||||
|
if _, err := r.fileSystem.Stat(r.configPath); os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("failed to check if config file exists: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configDir := filepath.Dir(r.configPath)
|
||||||
|
originalBackupPath := filepath.Join(configDir, OriginalBackupName)
|
||||||
|
|
||||||
|
if _, err := r.fileSystem.Stat(originalBackupPath); err == nil {
|
||||||
|
return nil
|
||||||
|
} else if !r.fileSystem.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("failed to check if original backup exists: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.copyFile(r.configPath, originalBackupPath); err != nil {
|
||||||
|
return fmt.Errorf("failed to create original backup: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.logger.Infof("Created original backup: %s", originalBackupPath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ func (r *Repository) saveConfig(cfg *ssh_config.Config) error {
|
|||||||
return fmt.Errorf("failed to write config to temporary file: %w", err)
|
return fmt.Errorf("failed to write config to temporary file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure a one-time original backup exists before any modifications managed by lazyssh.
|
||||||
|
if err := r.createOriginalBackupIfNeeded(); err != nil {
|
||||||
|
return fmt.Errorf("failed to create original backup: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := r.createBackup(); err != nil {
|
if err := r.createBackup(); err != nil {
|
||||||
return fmt.Errorf("failed to create backup: %w", err)
|
return fmt.Errorf("failed to create backup: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MaxBackups = 10
|
MaxBackups = 10
|
||||||
TempSuffix = ".tmp"
|
TempSuffix = ".tmp"
|
||||||
BackupSuffix = "lazyssh.backup"
|
BackupSuffix = "lazyssh.backup"
|
||||||
SSHConfigPerms = 0o600
|
SSHConfigPerms = 0o600
|
||||||
|
OriginalBackupName = "config.original.backup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// filterServers filters servers based on the query string.
|
// filterServers filters servers based on the query string.
|
||||||
|
|||||||
Reference in New Issue
Block a user