-
Notifications
You must be signed in to change notification settings - Fork 1
Backup System
The Backup System has been completely overhauled in version 4.x, introducing "Backup System v2", or, just "Backup system" now. This new system offers improved performance, a cleaner architecture, and enhanced features. This system is designed to manage game save backups with advanced retention policies and secure storage.
Important
The Backup Manager was overhauled once again in v5, dropping support for the preterrain save trio. If you want to play an older version of Stationeers, use an older version of SSUI. Feel free to ask away on the SSUI Discord
- Architecture Overview
- Core Components
- Backup Process
- Retention Policy
- API Reference
- Important Notes on Filesystem Support
- Integration Guide
- Configuration
The Backup System v3 is built with a modular architecture that separates concerns into distinct components:
- BackupManager: The central component that coordinates all backup operations.
- File Watcher: Monitors backup directories for changes and triggers backup processing.
- HTTP API: Provides RESTful endpoints for backup management.
The system handles two types of backup directories:
- Backup Directory: Where the game saves backups initially.
- Safe Backup Directory: Where copies are stored with retention policies applied.
The BackupManager is the central controller for backup operations. It:
- Initializes the backup system with appropriate configuration
- Starts and manages background monitoring processes
- Coordinates backup and restore operations
- Applies retention policies through the cleanup process
type BackupManager struct {
config BackupConfig
mu sync.Mutex
watcher *fsWatcher
ctx context. Context
cancel context.CancelFunc
}Each BackupManager instance is independent with its own configuration, making it possible to manage multiple game worlds (or games..Am I onto something?!) in the future.
The system uses fsnotify to monitor for new backup files. When a new backup file is detected, it:
- Validates the file format
- Waits a configurable delay to ensure the file is fully written
- Copies the file to the safe backup directory
func (m *BackupManager) watchBackups() {
// Monitors for new backup files and processes them
}This feature was removed
The backup process follows this workflow:
- Game creates backup files in the primary backup directory
- File watcher detects new backup files
- After a delay of 30 seconds, the detected save file is copied to the safe backup directory
The backup system exposes RESTful API endpoints for management:
GET /api/v2/backups?limit={limit}
- Description: Returns a list of available backups
-
Parameters:
-
limit(optional): Maximum number of backups to return
-
- Response: JSON array of backup groups with metadata
GET /api/v2/backups/restore?index={index}
- Description: Restores a backup with the specified index
-
Parameters:
-
index(required): Index of the backup to restore
-
- Response: Success/error message
All API endpoints are protected by JWT Cookie authentication. Clients must:
- Authenticate using
/auth/login - Include the JWT Cookie in subsequent requests
- NFS v1/v2 (Network File System) mounts
- SMB/CIFS (Windows file sharing) mounts
- NFS v3/v4 (Network File System) mounts
- ZFS, might be slow with caching & make life harder but works™
- any block level storage (iSCSI, Fibre channel, plain old ext4)
The system relies on fsnotify for filesystem monitoring, which cannot:
- Force cache refreshes on network filesystems
- Guarantee consistent event notifications across network storage
- Ensure real-time synchronization between write operations and filesystem events
When using network filesystems:
- New backups might not be immediately detected
- File existence checks may return inconsistent results
- Users might not see backups that actually exist due to delayed filesystem event propagation
For reliable backup operations, use local storage or block-level network storage (iSCSI, Fibre Channel) that presents as a local block device to the operating system. If you require network level storage backups, we recommend using rsync.
The system provides a global singleton instance for easy integration:
// Initialize the manager
backupConfig := backupsv2.GetBackupConfig()
err := backupsv2.InitGlobalBackupManager(backupConfig)
// Use the manager throughout your application
backups, err := backupsv2.GlobalBackupManager.ListBackups(10)This is not needed and not used in the current state of this Software. For more advanced use cases, we can create custom instances too:
config := backupsv2.BackupConfig{
WorldName: "MyWorld",
BackupDir: "./saves/MyWorld/Backup",
SafeBackupDir: "./saves/MyWorld/Safebackups",
WaitTime: 30 * time.Second,
RetentionPolicy: backupsv2.RetentionPolicy{
KeepLastN: 10,
KeepDailyFor: 30 * 24 * time.Hour,
KeepWeeklyFor: 90 * 24 * time.Hour,
KeepMonthlyFor: 365 * 24 * time.Hour,
CleanupInterval: 1 * time.Hour,
},
}
manager := backupsv2.NewBackupManager(config)
if err := manager.Initialize(); err != nil {
// Handle error
}
if err := manager.Start(); err != nil {
// Handle error
As Start calls the cleanup go routines too, be careful with "Starting" a new Manager. Initializing it is generally fine.
}
// Don't forget to shut down when done
defer manager.Shutdown()The default configuration can be obtained through GetBackupConfig():
func GetBackupConfig() BackupConfig {
backupDir := filepath.Join("./saves/" + config.WorldName + "/Backup")
safeBackupDir := filepath.Join("./saves/" + config.WorldName + "/Safebackups")
return BackupConfig{
WorldName: config.GetSaveName(),
BackupDir: config.GetConfiguredBackupDir(),
SafeBackupDir: config.GetConfiguredSafeBackupDir(),
WaitTime: 30 * time.Second, // not sure why we are not using config.BackupWaitTime here, but ill not touch it in this commit (config rework)
RetentionPolicy: RetentionPolicy{
KeepLastN: config.GetBackupKeepLastN(),
KeepDailyFor: config.GetBackupKeepDailyFor(),
KeepWeeklyFor: config.GetBackupKeepWeeklyFor(),
KeepMonthlyFor: config.GetBackupKeepMonthlyFor(),
CleanupInterval: config.GetBackupCleanupInterval(),
},
Identifier: bmIdentifier,
}Key configuration options:
| Option | Description | Default |
|---|---|---|
| WorldName | Name of the game world | From global config |
| BackupDir | Primary backup directory | ./saves/{WorldName}/Backup |
| SafeBackupDir | Safe storage directory | ./saves/{WorldName}/Safebackups |
| WaitTime | Delay before processing new backups | 30 seconds |
This documentation is intended for developers. For end-user documentation, please refer to the main wiki.