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.
|
||||
|
||||
|
||||
## 🛡️ 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
|
||||
|
||||
<div align="center">
|
||||
|
||||
@@ -125,3 +125,29 @@ func (r *Repository) findBackupFiles(dir string) ([]os.FileInfo, error) {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return fmt.Errorf("failed to create backup: %w", err)
|
||||
}
|
||||
|
||||
@@ -23,10 +23,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MaxBackups = 10
|
||||
TempSuffix = ".tmp"
|
||||
BackupSuffix = "lazyssh.backup"
|
||||
SSHConfigPerms = 0o600
|
||||
MaxBackups = 10
|
||||
TempSuffix = ".tmp"
|
||||
BackupSuffix = "lazyssh.backup"
|
||||
SSHConfigPerms = 0o600
|
||||
OriginalBackupName = "config.original.backup"
|
||||
)
|
||||
|
||||
// filterServers filters servers based on the query string.
|
||||
|
||||
Reference in New Issue
Block a user