mirror of
https://github.com/octoleo/restic.git
synced 2024-11-21 20:35:12 +00:00
Remove all usages of the global command-specific options
Now, every command uses an options struct, which is passed to the run* function by the command.RunE method.
This commit is contained in:
parent
6696195f38
commit
66103aea3d
@ -633,7 +633,7 @@ func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, ter
|
|||||||
wg.Go(func() error { return sc.Scan(cancelCtx, targets) })
|
wg.Go(func() error { return sc.Scan(cancelCtx, targets) })
|
||||||
}
|
}
|
||||||
|
|
||||||
arch := archiver.New(repo, targetFS, archiver.Options{ReadConcurrency: backupOptions.ReadConcurrency})
|
arch := archiver.New(repo, targetFS, archiver.Options{ReadConcurrency: opts.ReadConcurrency})
|
||||||
arch.SelectByName = selectByNameFilter
|
arch.SelectByName = selectByNameFilter
|
||||||
arch.Select = selectFilter
|
arch.Select = selectFilter
|
||||||
arch.WithAtime = opts.WithAtime
|
arch.WithAtime = opts.WithAtime
|
||||||
|
@ -52,19 +52,23 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var tryRepair bool
|
type DebugExamineOptions struct {
|
||||||
var repairByte bool
|
TryRepair bool
|
||||||
var extractPack bool
|
RepairByte bool
|
||||||
var reuploadBlobs bool
|
ExtractPack bool
|
||||||
|
ReuploadBlobs bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var debugExamineOpts DebugExamineOptions
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdRoot.AddCommand(cmdDebug)
|
cmdRoot.AddCommand(cmdDebug)
|
||||||
cmdDebug.AddCommand(cmdDebugDump)
|
cmdDebug.AddCommand(cmdDebugDump)
|
||||||
cmdDebug.AddCommand(cmdDebugExamine)
|
cmdDebug.AddCommand(cmdDebugExamine)
|
||||||
cmdDebugExamine.Flags().BoolVar(&extractPack, "extract-pack", false, "write blobs to the current directory")
|
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.ExtractPack, "extract-pack", false, "write blobs to the current directory")
|
||||||
cmdDebugExamine.Flags().BoolVar(&reuploadBlobs, "reupload-blobs", false, "reupload blobs to the repository")
|
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.ReuploadBlobs, "reupload-blobs", false, "reupload blobs to the repository")
|
||||||
cmdDebugExamine.Flags().BoolVar(&tryRepair, "try-repair", false, "try to repair broken blobs with single bit flips")
|
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.TryRepair, "try-repair", false, "try to repair broken blobs with single bit flips")
|
||||||
cmdDebugExamine.Flags().BoolVar(&repairByte, "repair-byte", false, "try to repair broken blobs by trying bytes")
|
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.RepairByte, "repair-byte", false, "try to repair broken blobs by trying bytes")
|
||||||
}
|
}
|
||||||
|
|
||||||
func prettyPrintJSON(wr io.Writer, item interface{}) error {
|
func prettyPrintJSON(wr io.Writer, item interface{}) error {
|
||||||
@ -196,7 +200,7 @@ var cmdDebugExamine = &cobra.Command{
|
|||||||
Short: "Examine a pack file",
|
Short: "Examine a pack file",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runDebugExamine(cmd.Context(), globalOptions, args)
|
return runDebugExamine(cmd.Context(), globalOptions, debugExamineOpts, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +319,7 @@ func decryptUnsigned(ctx context.Context, k *crypto.Key, buf []byte) []byte {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, list []restic.Blob) error {
|
func loadBlobs(ctx context.Context, opts DebugExamineOptions, repo restic.Repository, packID restic.ID, list []restic.Blob) error {
|
||||||
dec, err := zstd.NewReader(nil)
|
dec, err := zstd.NewReader(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -328,7 +332,7 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
|
|||||||
|
|
||||||
wg, ctx := errgroup.WithContext(ctx)
|
wg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
if reuploadBlobs {
|
if opts.ReuploadBlobs {
|
||||||
repo.StartPackUploader(ctx, wg)
|
repo.StartPackUploader(ctx, wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,8 +360,8 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
|
|||||||
filePrefix := ""
|
filePrefix := ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error decrypting blob: %v\n", err)
|
Warnf("error decrypting blob: %v\n", err)
|
||||||
if tryRepair || repairByte {
|
if opts.TryRepair || opts.RepairByte {
|
||||||
plaintext = tryRepairWithBitflip(ctx, key, buf, repairByte)
|
plaintext = tryRepairWithBitflip(ctx, key, buf, opts.RepairByte)
|
||||||
}
|
}
|
||||||
if plaintext != nil {
|
if plaintext != nil {
|
||||||
outputPrefix = "repaired "
|
outputPrefix = "repaired "
|
||||||
@ -391,13 +395,13 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
|
|||||||
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID matches\n", outputPrefix, len(plaintext), id)
|
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID matches\n", outputPrefix, len(plaintext), id)
|
||||||
prefix = "correct-"
|
prefix = "correct-"
|
||||||
}
|
}
|
||||||
if extractPack {
|
if opts.ExtractPack {
|
||||||
err = storePlainBlob(id, filePrefix+prefix, plaintext)
|
err = storePlainBlob(id, filePrefix+prefix, plaintext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if reuploadBlobs {
|
if opts.ReuploadBlobs {
|
||||||
_, _, _, err := repo.SaveBlob(ctx, blob.Type, plaintext, id, true)
|
_, _, _, err := repo.SaveBlob(ctx, blob.Type, plaintext, id, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -406,7 +410,7 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if reuploadBlobs {
|
if opts.ReuploadBlobs {
|
||||||
return repo.Flush(ctx)
|
return repo.Flush(ctx)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -437,7 +441,7 @@ func storePlainBlob(id restic.ID, prefix string, plain []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) error {
|
func runDebugExamine(ctx context.Context, gopts GlobalOptions, opts DebugExamineOptions, args []string) error {
|
||||||
repo, err := OpenRepository(ctx, gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -476,7 +480,7 @@ func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
err := examinePack(ctx, repo, id)
|
err := examinePack(ctx, opts, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -487,7 +491,7 @@ func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) error {
|
func examinePack(ctx context.Context, opts DebugExamineOptions, repo restic.Repository, id restic.ID) error {
|
||||||
Printf("examine %v\n", id)
|
Printf("examine %v\n", id)
|
||||||
|
|
||||||
h := backend.Handle{
|
h := backend.Handle{
|
||||||
@ -524,7 +528,7 @@ func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) erro
|
|||||||
|
|
||||||
checkPackSize(blobs, fi.Size)
|
checkPackSize(blobs, fi.Size)
|
||||||
|
|
||||||
err = loadBlobs(ctx, repo, id, blobs)
|
err = loadBlobs(ctx, opts, repo, id, blobs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
} else {
|
} else {
|
||||||
@ -542,7 +546,7 @@ func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) erro
|
|||||||
checkPackSize(blobs, fi.Size)
|
checkPackSize(blobs, fi.Size)
|
||||||
|
|
||||||
if !blobsLoaded {
|
if !blobsLoaded {
|
||||||
return loadBlobs(ctx, repo, id, blobs)
|
return loadBlobs(ctx, opts, repo, id, blobs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -401,7 +401,7 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
|
|||||||
|
|
||||||
c := &Comparer{
|
c := &Comparer{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
opts: diffOptions,
|
opts: opts,
|
||||||
printChange: func(change *Change) {
|
printChange: func(change *Change) {
|
||||||
Printf("%-5s%v\n", change.Modifier, change.Path)
|
Printf("%-5s%v\n", change.Modifier, change.Path)
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runForget(cmd.Context(), forgetOptions, globalOptions, args)
|
return runForget(cmd.Context(), forgetOptions, forgetPruneOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +98,7 @@ type ForgetOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var forgetOptions ForgetOptions
|
var forgetOptions ForgetOptions
|
||||||
|
var forgetPruneOptions PruneOptions
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdRoot.AddCommand(cmdForget)
|
cmdRoot.AddCommand(cmdForget)
|
||||||
@ -132,7 +133,7 @@ func init() {
|
|||||||
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
|
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
|
||||||
|
|
||||||
f.SortFlags = false
|
f.SortFlags = false
|
||||||
addPruneOptions(cmdForget)
|
addPruneOptions(cmdForget, &forgetPruneOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyForgetOptions(opts *ForgetOptions) error {
|
func verifyForgetOptions(opts *ForgetOptions) error {
|
||||||
@ -151,7 +152,7 @@ func verifyForgetOptions(opts *ForgetOptions) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runForget(ctx context.Context, opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOptions, gopts GlobalOptions, args []string) error {
|
||||||
err := verifyForgetOptions(&opts)
|
err := verifyForgetOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -9,5 +9,8 @@ import (
|
|||||||
|
|
||||||
func testRunForget(t testing.TB, gopts GlobalOptions, args ...string) {
|
func testRunForget(t testing.TB, gopts GlobalOptions, args ...string) {
|
||||||
opts := ForgetOptions{}
|
opts := ForgetOptions{}
|
||||||
rtest.OK(t, runForget(context.TODO(), opts, gopts, args))
|
pruneOpts := PruneOptions{
|
||||||
|
MaxUnused: "5%",
|
||||||
|
}
|
||||||
|
rtest.OK(t, runForget(context.TODO(), opts, pruneOpts, gopts, args))
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: runGenerate,
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return runGenerate(genOpts, args)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type generateOptions struct {
|
type generateOptions struct {
|
||||||
@ -90,48 +92,48 @@ func writePowerShellCompletion(file string) error {
|
|||||||
return cmdRoot.GenPowerShellCompletionFile(file)
|
return cmdRoot.GenPowerShellCompletionFile(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runGenerate(_ *cobra.Command, args []string) error {
|
func runGenerate(opts generateOptions, args []string) error {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return errors.Fatal("the generate command expects no arguments, only options - please see `restic help generate` for usage and flags")
|
return errors.Fatal("the generate command expects no arguments, only options - please see `restic help generate` for usage and flags")
|
||||||
}
|
}
|
||||||
|
|
||||||
if genOpts.ManDir != "" {
|
if opts.ManDir != "" {
|
||||||
err := writeManpages(genOpts.ManDir)
|
err := writeManpages(opts.ManDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if genOpts.BashCompletionFile != "" {
|
if opts.BashCompletionFile != "" {
|
||||||
err := writeBashCompletion(genOpts.BashCompletionFile)
|
err := writeBashCompletion(opts.BashCompletionFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if genOpts.FishCompletionFile != "" {
|
if opts.FishCompletionFile != "" {
|
||||||
err := writeFishCompletion(genOpts.FishCompletionFile)
|
err := writeFishCompletion(opts.FishCompletionFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if genOpts.ZSHCompletionFile != "" {
|
if opts.ZSHCompletionFile != "" {
|
||||||
err := writeZSHCompletion(genOpts.ZSHCompletionFile)
|
err := writeZSHCompletion(opts.ZSHCompletionFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if genOpts.PowerShellCompletionFile != "" {
|
if opts.PowerShellCompletionFile != "" {
|
||||||
err := writePowerShellCompletion(genOpts.PowerShellCompletionFile)
|
err := writePowerShellCompletion(opts.PowerShellCompletionFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var empty generateOptions
|
var empty generateOptions
|
||||||
if genOpts == empty {
|
if opts == empty {
|
||||||
return errors.Fatal("nothing to do, please specify at least one output file/dir")
|
return errors.Fatal("nothing to do, please specify at least one output file/dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,23 +29,25 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runKey(cmd.Context(), globalOptions, args)
|
return runKey(cmd.Context(), globalOptions, keyOpts, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
type KeyOptions struct {
|
||||||
newPasswordFile string
|
NewPasswordFile string
|
||||||
keyUsername string
|
Username string
|
||||||
keyHostname string
|
Hostname string
|
||||||
)
|
}
|
||||||
|
|
||||||
|
var keyOpts KeyOptions
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdRoot.AddCommand(cmdKey)
|
cmdRoot.AddCommand(cmdKey)
|
||||||
|
|
||||||
flags := cmdKey.Flags()
|
flags := cmdKey.Flags()
|
||||||
flags.StringVarP(&newPasswordFile, "new-password-file", "", "", "`file` from which to read the new password")
|
flags.StringVarP(&keyOpts.NewPasswordFile, "new-password-file", "", "", "`file` from which to read the new password")
|
||||||
flags.StringVarP(&keyUsername, "user", "", "", "the username for new keys")
|
flags.StringVarP(&keyOpts.Username, "user", "", "", "the username for new keys")
|
||||||
flags.StringVarP(&keyHostname, "host", "", "", "the hostname for new keys")
|
flags.StringVarP(&keyOpts.Hostname, "host", "", "", "the hostname for new keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions) error {
|
func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions) error {
|
||||||
@ -105,7 +107,7 @@ func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions
|
|||||||
// testKeyNewPassword is used to set a new password during integration testing.
|
// testKeyNewPassword is used to set a new password during integration testing.
|
||||||
var testKeyNewPassword string
|
var testKeyNewPassword string
|
||||||
|
|
||||||
func getNewPassword(gopts GlobalOptions) (string, error) {
|
func getNewPassword(gopts GlobalOptions, newPasswordFile string) (string, error) {
|
||||||
if testKeyNewPassword != "" {
|
if testKeyNewPassword != "" {
|
||||||
return testKeyNewPassword, nil
|
return testKeyNewPassword, nil
|
||||||
}
|
}
|
||||||
@ -124,13 +126,13 @@ func getNewPassword(gopts GlobalOptions) (string, error) {
|
|||||||
"enter password again: ")
|
"enter password again: ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func addKey(ctx context.Context, repo *repository.Repository, gopts GlobalOptions) error {
|
func addKey(ctx context.Context, repo *repository.Repository, gopts GlobalOptions, opts KeyOptions) error {
|
||||||
pw, err := getNewPassword(gopts)
|
pw, err := getNewPassword(gopts, opts.NewPasswordFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := repository.AddKey(ctx, repo, pw, keyUsername, keyHostname, repo.Key())
|
id, err := repository.AddKey(ctx, repo, pw, opts.Username, opts.Hostname, repo.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("creating new key failed: %v\n", err)
|
return errors.Fatalf("creating new key failed: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -160,8 +162,8 @@ func deleteKey(ctx context.Context, repo *repository.Repository, id restic.ID) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func changePassword(ctx context.Context, repo *repository.Repository, gopts GlobalOptions) error {
|
func changePassword(ctx context.Context, repo *repository.Repository, gopts GlobalOptions, newPasswordFile string) error {
|
||||||
pw, err := getNewPassword(gopts)
|
pw, err := getNewPassword(gopts, newPasswordFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -201,7 +203,7 @@ func switchToNewKeyAndRemoveIfBroken(ctx context.Context, repo *repository.Repos
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
|
func runKey(ctx context.Context, gopts GlobalOptions, opts KeyOptions, args []string) error {
|
||||||
if len(args) < 1 || (args[0] == "remove" && len(args) != 2) || (args[0] != "remove" && len(args) != 1) {
|
if len(args) < 1 || (args[0] == "remove" && len(args) != 2) || (args[0] != "remove" && len(args) != 1) {
|
||||||
return errors.Fatal("wrong number of arguments")
|
return errors.Fatal("wrong number of arguments")
|
||||||
}
|
}
|
||||||
@ -230,7 +232,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return addKey(ctx, repo, gopts)
|
return addKey(ctx, repo, gopts, opts)
|
||||||
case "remove":
|
case "remove":
|
||||||
lock, ctx, err := lockRepoExclusive(ctx, repo, gopts.RetryLock, gopts.JSON)
|
lock, ctx, err := lockRepoExclusive(ctx, repo, gopts.RetryLock, gopts.JSON)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
@ -251,7 +253,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return changePassword(ctx, repo, gopts)
|
return changePassword(ctx, repo, gopts, opts.NewPasswordFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
func testRunKeyListOtherIDs(t testing.TB, gopts GlobalOptions) []string {
|
func testRunKeyListOtherIDs(t testing.TB, gopts GlobalOptions) []string {
|
||||||
buf, err := withCaptureStdout(func() error {
|
buf, err := withCaptureStdout(func() error {
|
||||||
return runKey(context.TODO(), gopts, []string{"list"})
|
return runKey(context.TODO(), gopts, KeyOptions{}, []string{"list"})
|
||||||
})
|
})
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
@ -36,21 +36,20 @@ func testRunKeyAddNewKey(t testing.TB, newPassword string, gopts GlobalOptions)
|
|||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runKey(context.TODO(), gopts, []string{"add"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, KeyOptions{}, []string{"add"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
|
func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
|
||||||
testKeyNewPassword = "john's geheimnis"
|
testKeyNewPassword = "john's geheimnis"
|
||||||
defer func() {
|
defer func() {
|
||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
keyUsername = ""
|
|
||||||
keyHostname = ""
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, cmdKey.Flags().Parse([]string{"--user=john", "--host=example.com"}))
|
|
||||||
|
|
||||||
t.Log("adding key for john@example.com")
|
t.Log("adding key for john@example.com")
|
||||||
rtest.OK(t, runKey(context.TODO(), gopts, []string{"add"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, KeyOptions{
|
||||||
|
Username: "john",
|
||||||
|
Hostname: "example.com",
|
||||||
|
}, []string{"add"}))
|
||||||
|
|
||||||
repo, err := OpenRepository(context.TODO(), gopts)
|
repo, err := OpenRepository(context.TODO(), gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
@ -67,13 +66,13 @@ func testRunKeyPasswd(t testing.TB, newPassword string, gopts GlobalOptions) {
|
|||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runKey(context.TODO(), gopts, []string{"passwd"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, KeyOptions{}, []string{"passwd"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunKeyRemove(t testing.TB, gopts GlobalOptions, IDs []string) {
|
func testRunKeyRemove(t testing.TB, gopts GlobalOptions, IDs []string) {
|
||||||
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
|
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
|
||||||
for _, id := range IDs {
|
for _, id := range IDs {
|
||||||
rtest.OK(t, runKey(context.TODO(), gopts, []string{"remove", id}))
|
rtest.OK(t, runKey(context.TODO(), gopts, KeyOptions{}, []string{"remove", id}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ func TestKeyAddRemove(t *testing.T) {
|
|||||||
|
|
||||||
env.gopts.password = passwordList[len(passwordList)-1]
|
env.gopts.password = passwordList[len(passwordList)-1]
|
||||||
t.Logf("testing access with last password %q\n", env.gopts.password)
|
t.Logf("testing access with last password %q\n", env.gopts.password)
|
||||||
rtest.OK(t, runKey(context.TODO(), env.gopts, []string{"list"}))
|
rtest.OK(t, runKey(context.TODO(), env.gopts, KeyOptions{}, []string{"list"}))
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
|
|
||||||
testRunKeyAddNewKeyUserHost(t, env.gopts)
|
testRunKeyAddNewKeyUserHost(t, env.gopts)
|
||||||
@ -131,15 +130,15 @@ func TestKeyProblems(t *testing.T) {
|
|||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err := runKey(context.TODO(), env.gopts, []string{"passwd"})
|
err := runKey(context.TODO(), env.gopts, KeyOptions{}, []string{"passwd"})
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
rtest.Assert(t, err != nil, "expected passwd change to fail")
|
rtest.Assert(t, err != nil, "expected passwd change to fail")
|
||||||
|
|
||||||
err = runKey(context.TODO(), env.gopts, []string{"add"})
|
err = runKey(context.TODO(), env.gopts, KeyOptions{}, []string{"add"})
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
rtest.Assert(t, err != nil, "expected key adding to fail")
|
rtest.Assert(t, err != nil, "expected key adding to fail")
|
||||||
|
|
||||||
t.Logf("testing access with initial password %q\n", env.gopts.password)
|
t.Logf("testing access with initial password %q\n", env.gopts.password)
|
||||||
rtest.OK(t, runKey(context.TODO(), env.gopts, []string{"list"}))
|
rtest.OK(t, runKey(context.TODO(), env.gopts, KeyOptions{}, []string{"list"}))
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runList(cmd.Context(), cmd, globalOptions, args)
|
return runList(cmd.Context(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,9 +31,9 @@ func init() {
|
|||||||
cmdRoot.AddCommand(cmdList)
|
cmdRoot.AddCommand(cmdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runList(ctx context.Context, cmd *cobra.Command, gopts GlobalOptions, args []string) error {
|
func runList(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.Fatal("type not specified, usage: " + cmd.Use)
|
return errors.Fatal("type not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(ctx, gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func testRunList(t testing.TB, tpe string, opts GlobalOptions) restic.IDs {
|
func testRunList(t testing.TB, tpe string, opts GlobalOptions) restic.IDs {
|
||||||
buf, err := withCaptureStdout(func() error {
|
buf, err := withCaptureStdout(func() error {
|
||||||
return runList(context.TODO(), cmdList, opts, []string{tpe})
|
return runList(context.TODO(), opts, []string{tpe})
|
||||||
})
|
})
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
return parseIDsFromReader(t, buf)
|
return parseIDsFromReader(t, buf)
|
||||||
|
@ -210,7 +210,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
Verbosef("%v filtered by %v:\n", sn, dirs)
|
Verbosef("%v filtered by %v:\n", sn, dirs)
|
||||||
}
|
}
|
||||||
printNode = func(path string, node *restic.Node) {
|
printNode = func(path string, node *restic.Node) {
|
||||||
Printf("%s\n", formatNode(path, node, lsOptions.ListLong, lsOptions.HumanReadable))
|
Printf("%s\n", formatNode(path, node, opts.ListLong, opts.HumanReadable))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ func init() {
|
|||||||
f := cmdPrune.Flags()
|
f := cmdPrune.Flags()
|
||||||
f.BoolVarP(&pruneOptions.DryRun, "dry-run", "n", false, "do not modify the repository, just print what would be done")
|
f.BoolVarP(&pruneOptions.DryRun, "dry-run", "n", false, "do not modify the repository, just print what would be done")
|
||||||
f.StringVarP(&pruneOptions.UnsafeNoSpaceRecovery, "unsafe-recover-no-free-space", "", "", "UNSAFE, READ THE DOCUMENTATION BEFORE USING! Try to recover a repository stuck with no free space. Do not use without trying out 'prune --max-repack-size 0' first.")
|
f.StringVarP(&pruneOptions.UnsafeNoSpaceRecovery, "unsafe-recover-no-free-space", "", "", "UNSAFE, READ THE DOCUMENTATION BEFORE USING! Try to recover a repository stuck with no free space. Do not use without trying out 'prune --max-repack-size 0' first.")
|
||||||
addPruneOptions(cmdPrune)
|
addPruneOptions(cmdPrune, &pruneOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPruneOptions(c *cobra.Command) {
|
func addPruneOptions(c *cobra.Command, pruneOptions *PruneOptions) {
|
||||||
f := c.Flags()
|
f := c.Flags()
|
||||||
f.StringVar(&pruneOptions.MaxUnused, "max-unused", "5%", "tolerate given `limit` of unused data (absolute value in bytes with suffixes k/K, m/M, g/G, t/T, a value in % or the word 'unlimited')")
|
f.StringVar(&pruneOptions.MaxUnused, "max-unused", "5%", "tolerate given `limit` of unused data (absolute value in bytes with suffixes k/K, m/M, g/G, t/T, a value in % or the word 'unlimited')")
|
||||||
f.StringVar(&pruneOptions.MaxRepackSize, "max-repack-size", "", "maximum `size` to repack (allowed suffixes: k/K, m/M, g/G, t/T)")
|
f.StringVar(&pruneOptions.MaxRepackSize, "max-repack-size", "", "maximum `size` to repack (allowed suffixes: k/K, m/M, g/G, t/T)")
|
||||||
|
@ -81,7 +81,10 @@ func testRunForgetJSON(t testing.TB, gopts GlobalOptions, args ...string) {
|
|||||||
DryRun: true,
|
DryRun: true,
|
||||||
Last: 1,
|
Last: 1,
|
||||||
}
|
}
|
||||||
return runForget(context.TODO(), opts, gopts, args)
|
pruneOpts := PruneOptions{
|
||||||
|
MaxUnused: "5%",
|
||||||
|
}
|
||||||
|
return runForget(context.TODO(), opts, pruneOpts, gopts, args)
|
||||||
})
|
})
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user