This commit represents a significant architectural overhaul of vaultik: Database Schema Changes: - Switch files table to use UUID primary keys instead of path-based keys - Add UUID primary keys to blobs table for immediate chunk association - Update all foreign key relationships to use UUIDs - Add comprehensive schema documentation in DATAMODEL.md - Add SQLite busy timeout handling for concurrent operations Streaming and Performance Improvements: - Implement true streaming blob packing without intermediate storage - Add streaming chunk processing to reduce memory usage - Improve progress reporting with real-time metrics - Add upload metrics tracking in new uploads table CLI Refactoring: - Restructure CLI to use subcommands: snapshot create/list/purge/verify - Add store info command for S3 configuration display - Add custom duration parser supporting days/weeks/months/years - Remove old backup.go in favor of enhanced snapshot.go - Add --cron flag for silent operation Configuration Changes: - Remove unused index_prefix configuration option - Add support for snapshot pruning retention policies - Improve configuration validation and error messages Testing Improvements: - Add comprehensive repository tests with edge cases - Add cascade delete debugging tests - Fix concurrent operation tests to use SQLite busy timeout - Remove tolerance for SQLITE_BUSY errors in tests Documentation: - Add MIT LICENSE file - Update README with new command structure - Add comprehensive DATAMODEL.md explaining database schema - Update DESIGN.md with UUID-based architecture Other Changes: - Add test-config.yml for testing - Update Makefile with better test output formatting - Fix various race conditions in concurrent operations - Improve error handling throughout
80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// RootFlags holds global flags that apply to all commands.
|
|
// These flags are defined on the root command and inherited by all subcommands.
|
|
type RootFlags struct {
|
|
ConfigPath string
|
|
Verbose bool
|
|
Debug bool
|
|
}
|
|
|
|
var rootFlags RootFlags
|
|
|
|
// NewRootCommand creates the root cobra command for the vaultik CLI.
|
|
// It sets up the command structure, global flags, and adds all subcommands.
|
|
// This is the main entry point for the CLI command hierarchy.
|
|
func NewRootCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "vaultik",
|
|
Short: "Secure incremental backup tool with asymmetric encryption",
|
|
Long: `vaultik is a secure incremental backup daemon that encrypts data using age
|
|
public keys and uploads to S3-compatible storage. No private keys are needed
|
|
on the source system.`,
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
// Add global flags
|
|
cmd.PersistentFlags().StringVar(&rootFlags.ConfigPath, "config", "", "Path to config file (default: $VAULTIK_CONFIG or /etc/vaultik/config.yml)")
|
|
cmd.PersistentFlags().BoolVarP(&rootFlags.Verbose, "verbose", "v", false, "Enable verbose output")
|
|
cmd.PersistentFlags().BoolVar(&rootFlags.Debug, "debug", false, "Enable debug output")
|
|
|
|
// Add subcommands
|
|
cmd.AddCommand(
|
|
NewRestoreCommand(),
|
|
NewPruneCommand(),
|
|
NewVerifyCommand(),
|
|
NewFetchCommand(),
|
|
NewStoreCommand(),
|
|
NewSnapshotCommand(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
// GetRootFlags returns the global flags that were parsed from the command line.
|
|
// This allows subcommands to access global flag values like verbosity and config path.
|
|
func GetRootFlags() RootFlags {
|
|
return rootFlags
|
|
}
|
|
|
|
// ResolveConfigPath resolves the config file path from flags, environment, or default.
|
|
// It checks in order: 1) --config flag, 2) VAULTIK_CONFIG environment variable,
|
|
// 3) default location /etc/vaultik/config.yml. Returns an error if no valid
|
|
// config file can be found through any of these methods.
|
|
func ResolveConfigPath() (string, error) {
|
|
// First check global flag
|
|
if rootFlags.ConfigPath != "" {
|
|
return rootFlags.ConfigPath, nil
|
|
}
|
|
|
|
// Then check environment variable
|
|
if envPath := os.Getenv("VAULTIK_CONFIG"); envPath != "" {
|
|
return envPath, nil
|
|
}
|
|
|
|
// Finally check default location
|
|
defaultPath := "/etc/vaultik/config.yml"
|
|
if _, err := os.Stat(defaultPath); err == nil {
|
|
return defaultPath, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("no config file specified, VAULTIK_CONFIG not set, and %s not found", defaultPath)
|
|
}
|