package cli import ( "context" "os" "git.eeqj.de/sneak/vaultik/internal/log" "git.eeqj.de/sneak/vaultik/internal/vaultik" "github.com/spf13/cobra" "go.uber.org/fx" ) // NewVerifyCommand creates the verify command func NewVerifyCommand() *cobra.Command { opts := &vaultik.VerifyOptions{} cmd := &cobra.Command{ Use: "verify ", Short: "Verify snapshot integrity", Long: `Verifies that all blobs referenced in a snapshot exist and optionally verifies their contents. Shallow verification (default): - Downloads and decompresses manifest - Checks existence of all blobs in S3 - Reports missing blobs Deep verification (--deep): - Downloads and decrypts database - Verifies blob lists match between manifest and database - Downloads, decrypts, and decompresses each blob - Verifies SHA256 hash of each chunk matches database - Ensures chunks are ordered correctly The command will fail immediately on any verification error and exit with non-zero status.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { snapshotID := args[0] // Use unified config resolution configPath, err := ResolveConfigPath() if err != nil { return err } // Use the app framework for all verification rootFlags := GetRootFlags() return RunWithApp(cmd.Context(), AppOptions{ ConfigPath: configPath, LogOptions: log.LogOptions{ Verbose: rootFlags.Verbose, Debug: rootFlags.Debug, }, Modules: []fx.Option{}, Invokes: []fx.Option{ fx.Invoke(func(v *vaultik.Vaultik, lc fx.Lifecycle) { lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { // Run the verify operation directly go func() { var err error if opts.Deep { err = v.RunDeepVerify(snapshotID, opts) } else { err = v.VerifySnapshot(snapshotID, false) } if err != nil { if err != context.Canceled { log.Error("Verification failed", "error", err) os.Exit(1) } } if err := v.Shutdowner.Shutdown(); err != nil { log.Error("Failed to shutdown", "error", err) } }() return nil }, OnStop: func(ctx context.Context) error { log.Debug("Stopping verify operation") v.Cancel() return nil }, }) }), }, }) }, } cmd.Flags().BoolVar(&opts.Deep, "deep", false, "Perform deep verification by downloading and verifying all blob contents") return cmd }