Skip to content

feat: backup profiles (RFC 0010)#86

Merged
rmanibus merged 1 commit into
mainfrom
feat/backup-profile
Mar 15, 2026
Merged

feat: backup profiles (RFC 0010)#86
rmanibus merged 1 commit into
mainfrom
feat/backup-profile

Conversation

@rmanibus
Copy link
Copy Markdown
Contributor

@rmanibus rmanibus commented Mar 14, 2026

Summary

  • Implement backup profiles from RFC 0010 with a YAML-driven workflow.
  • Add reusable stores and auth entries and profile-aware backup execution.
  • Add new CLI surfaces for profile/auth/store management and documentation.

What Changes

  • Add profile config model + I/O APIs:
    • internal/engine/profiles.go
    • exported via client.go (LoadProfilesFile, SaveProfilesFile)
  • Add new CLI commands:
    • cloudstic profile {list,show,new}
    • cloudstic auth {new,list,show,login}
    • cloudstic store {list,show,new}
  • Extend backup command:
    • -profile <name>
    • -all-profiles
    • -auth-ref <name>
    • -profiles-file <path>
    • profile/store/auth merge + precedence behavior in cmd/cloudstic/cmd_backup.go
  • Add completion/help/docs updates:
    • cmd/cloudstic/completion.go
    • cmd/cloudstic/usage.go
    • docs/user-guide.md, README.md
  • Add RFC:
    • rfcs/0010-backup-profiles.md
    • index update in rfcs/README.md

Behavior Notes

  • Existing flag-based workflows remain supported.
  • -profile and -all-profiles are mutually exclusive.
  • -all-profiles runs enabled profiles sequentially and reports aggregate failure if any profile fails.
  • Secrets in profile store config use env-var indirection fields (*_env) rather than plaintext by default.

Testing

  • New tests added across profile/auth/store and backup profile behavior:
    • cmd/cloudstic/cmd_profile_test.go
    • cmd/cloudstic/cmd_auth_test.go
    • cmd/cloudstic/cmd_store_test.go
    • cmd/cloudstic/cmd_backup_profile_test.go
    • internal/engine/profiles_test.go

Tracking

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 14, 2026

@rmanibus rmanibus force-pushed the feat/backup-profile branch 3 times, most recently from c3d648e to 1425ca1 Compare March 15, 2026 09:27
@rmanibus rmanibus force-pushed the feat/backup-profile branch from 1425ca1 to 1ce7258 Compare March 15, 2026 09:35
@rmanibus rmanibus merged commit 432907f into main Mar 15, 2026
5 checks passed
@rmanibus rmanibus deleted the feat/backup-profile branch March 15, 2026 09:43
@rmanibus rmanibus changed the title feat: backup profile feat: backup profiles (RFC 0010) Mar 15, 2026
@rmanibus rmanibus added the enhancement New feature or request label Mar 15, 2026
@rmanibus rmanibus added this to the RFC 0010: Backup profiles milestone Mar 15, 2026
@rmanibus rmanibus linked an issue Mar 15, 2026 that may be closed by this pull request
@rmanibus rmanibus requested a review from Copilot March 16, 2026 08:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements RFC 0010 “backup profiles”: a YAML-driven configuration model for reusable stores/auth entries and named backup presets, with new CLI surfaces to manage them and profile-aware backup execution.

Changes:

  • Add ProfilesConfig YAML model + load/save APIs in internal/engine, exported via client.go.
  • Add new CLI commands: cloudstic {profile,auth,store} {list,show,new} plus auth login.
  • Extend cloudstic backup with -profile, -all-profiles, -auth-ref, -profiles-file, and profile-based merge/precedence behavior.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
rfcs/README.md Index RFC 0010 in the RFC catalog.
rfcs/0010-backup-profiles.md Add RFC detailing YAML schema, precedence rules, and CLI UX.
internal/engine/profiles.go Define YAML schema structs and implement load/save with normalization + atomic write.
internal/engine/profiles_test.go Add tests for config normalization and save/load round-trip.
client.go Re-export profile types and expose LoadProfilesFile / SaveProfilesFile on the public API.
pkg/store/s3.go Add S3 shared-config profile support via WithS3Profile + config.WithSharedConfigProfile.
pkg/source/gdrive.go Ensure token directory exists before writing Google token file.
pkg/source/onedrive.go Ensure token directory exists before writing OneDrive token file.
cmd/cloudstic/main.go Wire new top-level commands: profile, auth, store.
cmd/cloudstic/runner.go Add --no-prompt handling and early global-flag detection helper.
cmd/cloudstic/interactive.go Add shared interactive prompt helpers gated by --no-prompt.
cmd/cloudstic/flags.go Add global -profile, -profiles-file, -s3-profile and helper for detecting provided flags.
cmd/cloudstic/store.go Apply profile-based store overrides before opening store/client; gate prompts on --no-prompt; pass WithS3Profile.
cmd/cloudstic/cmd_backup.go Implement profile-aware backup execution, -all-profiles sequencing, auth-ref application, and default auth persistence.
cmd/cloudstic/cmd_backup_profile_test.go Add tests for profile/store/auth merge and precedence behavior in backup.
cmd/cloudstic/cmd_store.go Implement store list/show/new, including optional interactive encryption/setup.
cmd/cloudstic/cmd_store_test.go Add store command tests including encryption fields, validation, and missing-file behavior.
cmd/cloudstic/store_profile_test.go Add tests for applying profile store overrides to global flags.
cmd/cloudstic/cmd_profile.go Implement profile list/show/new with reference resolution and interactive selection flows.
cmd/cloudstic/cmd_profile_test.go Add tests for profile CRUD, reference validation, and display output.
cmd/cloudstic/cmd_auth.go Implement auth list/show/new/login with token path derivation and provider-specific behavior.
cmd/cloudstic/cmd_auth_test.go Add tests for auth CRUD/login flows and token path derivation.
cmd/cloudstic/cmd_init.go Respect --no-prompt during interactive init password prompting.
cmd/cloudstic/cmd_key.go Respect --no-prompt during password change prompting.
cmd/cloudstic/usage.go Update usage output to include new commands and flags (--no-prompt, profile/auth/store).
cmd/cloudstic/completion.go Extend bash/zsh/fish completions for new commands and flags.
cmd/cloudstic/completion_test.go Update completion tests for new commands/flags.
docs/user-guide.md Document profiles/auth/store commands, backup flags, and env var additions.
README.md Add a “Profiles” quickstart section and link to user guide.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}

if a.store != "" {
Comment on lines +498 to +504
uri, err := r.promptLine("Store URI (e.g. s3://bucket/path, local:/path, sftp://host/path)", "")
if err != nil {
return "", r.fail("Failed to read store URI: %v", err)
}
if uri == "" {
return "", r.fail("Store URI is required")
}
# skip flags and their values
case "${words[i]}" in
-store|-s3-endpoint|-s3-region|-s3-access-key|-s3-secret-key|-source-sftp-password|-source-sftp-key|-store-sftp-password|-store-sftp-key|-encryption-key|-password|-recovery-key|-kms-key-arn|-kms-region|-kms-endpoint|-source|-google-credentials|-google-token-file|-onedrive-client-id|-onedrive-token-file|-tag|-output|-keep-last|-keep-hourly|-keep-daily|-keep-weekly|-keep-monthly|-keep-yearly|-group-by|-account|-json)
-store|-profile|-profiles-file|-s3-endpoint|-s3-region|-s3-profile|-s3-access-key|-s3-secret-key|-source-sftp-password|-source-sftp-key|-store-sftp-password|-store-sftp-key|-encryption-key|-password|-recovery-key|-kms-key-arn|-kms-region|-kms-endpoint|-source|-all-profiles|-auth-ref|-google-credentials|-google-token-file|-onedrive-client-id|-onedrive-token-file|-tag|-output|-keep-last|-keep-hourly|-keep-daily|-keep-weekly|-keep-monthly|-keep-yearly|-group-by|-account|-json)
Comment on lines +392 to +435
func cloneGlobalFlags(src *globalFlags) *globalFlags {
clone := *src

store := *src.store
s3Endpoint := *src.s3Endpoint
s3Region := *src.s3Region
s3AccessKey := *src.s3AccessKey
s3SecretKey := *src.s3SecretKey
sourceSFTPPassword := *src.sourceSFTPPassword
sourceSFTPKey := *src.sourceSFTPKey
storeSFTPPassword := *src.storeSFTPPassword
storeSFTPKey := *src.storeSFTPKey
encryptionKey := *src.encryptionKey
password := *src.password
recoveryKey := *src.recoveryKey
kmsKeyARN := *src.kmsKeyARN
kmsRegion := *src.kmsRegion
kmsEndpoint := *src.kmsEndpoint
disablePackfile := *src.disablePackfile
prompt := *src.prompt
verbose := *src.verbose
quiet := *src.quiet
debug := *src.debug

clone.store = &store
clone.s3Endpoint = &s3Endpoint
clone.s3Region = &s3Region
clone.s3AccessKey = &s3AccessKey
clone.s3SecretKey = &s3SecretKey
clone.sourceSFTPPassword = &sourceSFTPPassword
clone.sourceSFTPKey = &sourceSFTPKey
clone.storeSFTPPassword = &storeSFTPPassword
clone.storeSFTPKey = &storeSFTPKey
clone.encryptionKey = &encryptionKey
clone.password = &password
clone.recoveryKey = &recoveryKey
clone.kmsKeyARN = &kmsKeyARN
clone.kmsRegion = &kmsRegion
clone.kmsEndpoint = &kmsEndpoint
clone.disablePackfile = &disablePackfile
clone.prompt = &prompt
clone.verbose = &verbose
clone.quiet = &quiet
clone.debug = &debug
"-profiles-file",
"-profile", "-all-profiles",
"-auth-ref",
"-auth-ref",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC 0010: Epic / Tracking issue for backup profiles

2 participants