mirror of
https://github.com/jkl1337/duplicacy.git
synced 2026-01-02 03:34:39 -06:00
Refactor the BackupManager options interface some more
- Move the pref based (repository associated) options back to init of the backup manager. This is still a bit of an unholy mess but the existing setup is a little insane. There are mostly runtime associated settings, like revision, tag, thread count, quick mode, show stats. Then there are the more fuzzy ones, like allow failures, patterns. However something like set-owner, mostly likely that's going to be static for a "repository", same with exclude by attribute. In any event things that make sense to be associated with the repository preferences will stay in a backup mananger initialization time options structure, and no more growing of the arguments list - go doesn't look good there. RestoreOptions for the more ephemeral run associated settings. The Backup routine with it's large argument list stays for now, but will get revamped if anything new gets added.
This commit is contained in:
@@ -22,9 +22,7 @@ import (
|
||||
|
||||
"github.com/gilbertchen/cli"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/gilbertchen/duplicacy/src"
|
||||
duplicacy "github.com/gilbertchen/duplicacy/src"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -316,7 +314,7 @@ func configRepository(context *cli.Context, init bool) {
|
||||
// write real path into .duplicacy file inside repository
|
||||
duplicacyFileName := path.Join(repository, duplicacy.DUPLICACY_FILE)
|
||||
d1 := []byte(preferencePath)
|
||||
err = ioutil.WriteFile(duplicacyFileName, d1, 0644)
|
||||
err = os.WriteFile(duplicacyFileName, d1, 0644)
|
||||
if err != nil {
|
||||
duplicacy.LOG_ERROR("REPOSITORY_PATH", "Failed to write %s file inside repository %v", duplicacyFileName, err)
|
||||
return
|
||||
@@ -705,7 +703,7 @@ func changePassword(context *cli.Context) {
|
||||
}
|
||||
|
||||
configPath := path.Join(duplicacy.GetDuplicacyPreferencePath(), "config")
|
||||
err = ioutil.WriteFile(configPath, description, 0600)
|
||||
err = os.WriteFile(configPath, description, 0600)
|
||||
if err != nil {
|
||||
duplicacy.LOG_ERROR("CONFIG_SAVE", "Failed to save the old config to %s: %v", configPath, err)
|
||||
return
|
||||
@@ -789,7 +787,12 @@ func backupRepository(context *cli.Context) {
|
||||
uploadRateLimit := context.Int("limit-rate")
|
||||
enumOnly := context.Bool("enum-only")
|
||||
storage.SetRateLimits(0, uploadRateLimit)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, preference.NobackupFile, preference.FiltersFile, preference.ExcludeByAttribute)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password,
|
||||
&duplicacy.BackupManagerOptions{
|
||||
NoBackupFile: preference.NobackupFile,
|
||||
FiltersFile: preference.FiltersFile,
|
||||
ExcludeByAttribute: preference.ExcludeByAttribute,
|
||||
})
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
backupManager.SetupSnapshotCache(preference.Name)
|
||||
@@ -850,20 +853,6 @@ func restoreRepository(context *cli.Context) {
|
||||
password = duplicacy.GetPassword(*preference, "password", "Enter storage password:", false, false)
|
||||
}
|
||||
|
||||
options := duplicacy.RestoreOptions{
|
||||
InPlace: true,
|
||||
QuickMode: !context.Bool("hash"),
|
||||
Overwrite: context.Bool("overwrite"),
|
||||
DeleteMode: context.Bool("delete"),
|
||||
SetOwner: !context.Bool("ignore-owner"),
|
||||
ShowStatistics: context.Bool("stats"),
|
||||
AllowFailures: context.Bool("persist"),
|
||||
ExcludeXattrs: preference.ExcludeXattrs,
|
||||
NormalizeXattrs: preference.NormalizeXattrs,
|
||||
IncludeSpecials: preference.IncludeSpecials,
|
||||
FileFlagsMask: uint32(preference.FileFlagsMask),
|
||||
}
|
||||
|
||||
var patterns []string
|
||||
for _, pattern := range context.Args() {
|
||||
|
||||
@@ -880,20 +869,45 @@ func restoreRepository(context *cli.Context) {
|
||||
patterns = append(patterns, pattern)
|
||||
}
|
||||
|
||||
options.Patterns = duplicacy.ProcessFilterLines(patterns, make([]string, 0))
|
||||
patterns = duplicacy.ProcessFilterLines(patterns, make([]string, 0))
|
||||
|
||||
duplicacy.LOG_DEBUG("REGEX_DEBUG", "There are %d compiled regular expressions stored", len(duplicacy.RegexMap))
|
||||
|
||||
duplicacy.LOG_INFO("SNAPSHOT_FILTER", "Loaded %d include/exclude pattern(s)", len(patterns))
|
||||
|
||||
storage.SetRateLimits(context.Int("limit-rate"), 0)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, preference.NobackupFile, preference.FiltersFile, preference.ExcludeByAttribute)
|
||||
|
||||
excludeOwner := preference.ExcludeOwner
|
||||
// TODO: for backward compat, eventually make them all overridable?
|
||||
if context.IsSet("ignore-owner") {
|
||||
excludeOwner = context.Bool("ignore-owner")
|
||||
}
|
||||
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password,
|
||||
&duplicacy.BackupManagerOptions{
|
||||
NoBackupFile: preference.NobackupFile,
|
||||
FiltersFile: preference.FiltersFile,
|
||||
ExcludeByAttribute: preference.ExcludeByAttribute,
|
||||
SetOwner: excludeOwner,
|
||||
ExcludeXattrs: preference.ExcludeXattrs,
|
||||
NormalizeXattrs: preference.NormalizeXattrs,
|
||||
IncludeSpecials: preference.IncludeSpecials,
|
||||
FileFlagsMask: uint32(preference.FileFlagsMask),
|
||||
})
|
||||
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
loadRSAPrivateKey(context.String("key"), context.String("key-passphrase"), preference, backupManager, false)
|
||||
|
||||
backupManager.SetupSnapshotCache(preference.Name)
|
||||
failed := backupManager.Restore(repository, revision, options)
|
||||
failed := backupManager.Restore(repository, revision, &duplicacy.RestoreOptions{
|
||||
InPlace: true,
|
||||
QuickMode: !context.Bool("hash"),
|
||||
Overwrite: context.Bool("overwrite"),
|
||||
DeleteMode: context.Bool("delete"),
|
||||
ShowStatistics: context.Bool("stats"),
|
||||
AllowFailures: context.Bool("persist"),
|
||||
})
|
||||
if failed > 0 {
|
||||
duplicacy.LOG_ERROR("RESTORE_FAIL", "%d file(s) were not restored correctly", failed)
|
||||
return
|
||||
@@ -933,7 +947,8 @@ func listSnapshots(context *cli.Context) {
|
||||
tag := context.String("t")
|
||||
revisions := getRevisions(context)
|
||||
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", preference.ExcludeByAttribute)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password,
|
||||
&duplicacy.BackupManagerOptions{ExcludeByAttribute: preference.ExcludeByAttribute})
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
id := preference.SnapshotID
|
||||
@@ -989,7 +1004,7 @@ func checkSnapshots(context *cli.Context) {
|
||||
tag := context.String("t")
|
||||
revisions := getRevisions(context)
|
||||
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", false)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, nil)
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
loadRSAPrivateKey(context.String("key"), context.String("key-passphrase"), preference, backupManager, false)
|
||||
@@ -1049,8 +1064,7 @@ func printFile(context *cli.Context) {
|
||||
snapshotID = context.String("id")
|
||||
}
|
||||
|
||||
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", false)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, nil)
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
loadRSAPrivateKey(context.String("key"), context.String("key-passphrase"), preference, backupManager, false)
|
||||
@@ -1108,7 +1122,7 @@ func diff(context *cli.Context) {
|
||||
}
|
||||
|
||||
compareByHash := context.Bool("hash")
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", false)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, nil)
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
loadRSAPrivateKey(context.String("key"), context.String("key-passphrase"), preference, backupManager, false)
|
||||
@@ -1153,7 +1167,7 @@ func showHistory(context *cli.Context) {
|
||||
|
||||
revisions := getRevisions(context)
|
||||
showLocalHash := context.Bool("hash")
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", false)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, nil)
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
backupManager.SetupSnapshotCache(preference.Name)
|
||||
@@ -1216,7 +1230,7 @@ func pruneSnapshots(context *cli.Context) {
|
||||
os.Exit(ArgumentExitCode)
|
||||
}
|
||||
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, "", "", false)
|
||||
backupManager := duplicacy.CreateBackupManager(preference.SnapshotID, storage, repository, password, nil)
|
||||
duplicacy.SavePassword(*preference, "password", password)
|
||||
|
||||
backupManager.SetupSnapshotCache(preference.Name)
|
||||
@@ -1261,7 +1275,7 @@ func copySnapshots(context *cli.Context) {
|
||||
sourcePassword = duplicacy.GetPassword(*source, "password", "Enter source storage password:", false, false)
|
||||
}
|
||||
|
||||
sourceManager := duplicacy.CreateBackupManager(source.SnapshotID, sourceStorage, repository, sourcePassword, "", "", false)
|
||||
sourceManager := duplicacy.CreateBackupManager(source.SnapshotID, sourceStorage, repository, sourcePassword, nil)
|
||||
sourceManager.SetupSnapshotCache(source.Name)
|
||||
duplicacy.SavePassword(*source, "password", sourcePassword)
|
||||
|
||||
@@ -1296,7 +1310,7 @@ func copySnapshots(context *cli.Context) {
|
||||
destinationStorage.SetRateLimits(0, context.Int("upload-limit-rate"))
|
||||
|
||||
destinationManager := duplicacy.CreateBackupManager(destination.SnapshotID, destinationStorage, repository,
|
||||
destinationPassword, "", "", false)
|
||||
destinationPassword, nil)
|
||||
duplicacy.SavePassword(*destination, "password", destinationPassword)
|
||||
destinationManager.SetupSnapshotCache(destination.Name)
|
||||
|
||||
@@ -1570,7 +1584,6 @@ func main() {
|
||||
Usage: "the maximum number of entries kept in memory (defaults to 1M)",
|
||||
Argument: "<number>",
|
||||
},
|
||||
|
||||
},
|
||||
Usage: "Save a snapshot of the repository to the storage",
|
||||
ArgsUsage: " ",
|
||||
|
||||
@@ -33,15 +33,21 @@ type BackupManager struct {
|
||||
snapshotCache *FileStorage // for copies of chunks needed by snapshots
|
||||
|
||||
config *Config // contains a number of options
|
||||
|
||||
nobackupFile string // don't backup directory when this file name is found
|
||||
filtersFile string // the path to the filters file
|
||||
excludeByAttribute bool // don't backup file based on file attribute
|
||||
options BackupManagerOptions
|
||||
|
||||
cachePath string
|
||||
}
|
||||
|
||||
type BackupOptions struct {
|
||||
type BackupManagerOptions struct {
|
||||
NoBackupFile string // don't backup directory when this file name is found
|
||||
FiltersFile string // the path to the filters file
|
||||
ExcludeByAttribute bool // don't backup file based on file attribute
|
||||
SetOwner bool
|
||||
ExcludeXattrs bool
|
||||
NormalizeXattrs bool
|
||||
IncludeFileFlags bool
|
||||
IncludeSpecials bool
|
||||
FileFlagsMask uint32
|
||||
}
|
||||
|
||||
type RestoreOptions struct {
|
||||
@@ -51,13 +57,8 @@ type RestoreOptions struct {
|
||||
QuickMode bool
|
||||
Overwrite bool
|
||||
DeleteMode bool
|
||||
SetOwner bool
|
||||
ShowStatistics bool
|
||||
AllowFailures bool
|
||||
ExcludeXattrs bool
|
||||
NormalizeXattrs bool
|
||||
IncludeSpecials bool
|
||||
FileFlagsMask uint32
|
||||
}
|
||||
|
||||
func (manager *BackupManager) SetDryRun(dryRun bool) {
|
||||
@@ -71,7 +72,8 @@ func (manager *BackupManager) SetCompressionLevel(level int) {
|
||||
// CreateBackupManager creates a backup manager using the specified 'storage'. 'snapshotID' is a unique id to
|
||||
// identify snapshots created for this repository. 'top' is the top directory of the repository. 'password' is the
|
||||
// master key which can be nil if encryption is not enabled.
|
||||
func CreateBackupManager(snapshotID string, storage Storage, top string, password string, nobackupFile string, filtersFile string, excludeByAttribute bool) *BackupManager {
|
||||
func CreateBackupManager(snapshotID string, storage Storage, top string, password string,
|
||||
options *BackupManagerOptions) *BackupManager {
|
||||
|
||||
config, _, err := DownloadConfig(storage, password)
|
||||
if err != nil {
|
||||
@@ -92,12 +94,10 @@ func CreateBackupManager(snapshotID string, storage Storage, top string, passwor
|
||||
SnapshotManager: snapshotManager,
|
||||
|
||||
config: config,
|
||||
|
||||
nobackupFile: nobackupFile,
|
||||
|
||||
filtersFile: filtersFile,
|
||||
|
||||
excludeByAttribute: excludeByAttribute,
|
||||
options: *options,
|
||||
}
|
||||
if options != nil {
|
||||
backupManager.options = *options
|
||||
}
|
||||
|
||||
if IsDebugging() {
|
||||
@@ -170,7 +170,7 @@ func (manager *BackupManager) Backup(top string, quickMode bool, threads int, ta
|
||||
LOG_INFO("BACKUP_KEY", "RSA encryption is enabled")
|
||||
}
|
||||
|
||||
if manager.excludeByAttribute {
|
||||
if manager.options.ExcludeByAttribute {
|
||||
LOG_INFO("BACKUP_EXCLUDE", "Exclude files with no-backup attributes")
|
||||
}
|
||||
|
||||
@@ -255,7 +255,8 @@ func (manager *BackupManager) Backup(top string, quickMode bool, threads int, ta
|
||||
go func() {
|
||||
// List local files
|
||||
defer CatchLogException()
|
||||
localSnapshot.ListLocalFiles(shadowTop, manager.nobackupFile, manager.filtersFile, manager.excludeByAttribute, localListingChannel, &skippedDirectories, &skippedFiles)
|
||||
localSnapshot.ListLocalFiles(shadowTop, manager.options.NoBackupFile, manager.options.FiltersFile,
|
||||
manager.options.ExcludeByAttribute, localListingChannel, &skippedDirectories, &skippedFiles)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
@@ -642,7 +643,7 @@ func (manager *BackupManager) Backup(top string, quickMode bool, threads int, ta
|
||||
// Restore downloads the specified snapshot, compares it with what's on the repository, and then downloads
|
||||
// files that are different.'QuickMode' will bypass files with unchanged sizes and timestamps. 'DeleteMode' will
|
||||
// remove local files that don't exist in the snapshot. 'Patterns' is used to include/exclude certain files.
|
||||
func (manager *BackupManager) Restore(top string, revision int, options RestoreOptions) int {
|
||||
func (manager *BackupManager) Restore(top string, revision int, options *RestoreOptions) int {
|
||||
if options.Threads < 1 {
|
||||
options.Threads = 1
|
||||
}
|
||||
@@ -653,10 +654,10 @@ func (manager *BackupManager) Restore(top string, revision int, options RestoreO
|
||||
allowFailures := options.AllowFailures
|
||||
|
||||
metadataOptions := RestoreMetadataOptions{
|
||||
SetOwner: options.SetOwner,
|
||||
ExcludeXattrs: options.ExcludeXattrs,
|
||||
NormalizeXattrs: options.NormalizeXattrs,
|
||||
FileFlagsMask: options.FileFlagsMask,
|
||||
SetOwner: manager.options.SetOwner,
|
||||
ExcludeXattrs: manager.options.ExcludeXattrs,
|
||||
NormalizeXattrs: manager.options.NormalizeXattrs,
|
||||
FileFlagsMask: manager.options.FileFlagsMask,
|
||||
}
|
||||
|
||||
startTime := time.Now().Unix()
|
||||
@@ -715,7 +716,8 @@ func (manager *BackupManager) Restore(top string, revision int, options RestoreO
|
||||
go func() {
|
||||
// List local files
|
||||
defer CatchLogException()
|
||||
localSnapshot.ListLocalFiles(top, manager.nobackupFile, manager.filtersFile, manager.excludeByAttribute, localListingChannel, nil, nil)
|
||||
localSnapshot.ListLocalFiles(top, manager.options.NoBackupFile, manager.options.FiltersFile,
|
||||
manager.options.ExcludeByAttribute, localListingChannel, nil, nil)
|
||||
}()
|
||||
|
||||
remoteSnapshot := manager.SnapshotManager.DownloadSnapshot(manager.snapshotID, revision)
|
||||
@@ -857,12 +859,12 @@ func (manager *BackupManager) Restore(top string, revision int, options RestoreO
|
||||
return 0
|
||||
}
|
||||
}
|
||||
err = remoteEntry.RestoreEarlyDirFlags(fullPath, options.FileFlagsMask)
|
||||
err = remoteEntry.RestoreEarlyDirFlags(fullPath, manager.options.FileFlagsMask)
|
||||
if err != nil {
|
||||
LOG_WARN("DOWNLOAD_FLAGS", "Failed to set early file flags on %s: %v", fullPath, err)
|
||||
}
|
||||
directoryEntries = append(directoryEntries, remoteEntry)
|
||||
} else if remoteEntry.IsSpecial() && options.IncludeSpecials {
|
||||
} else if remoteEntry.IsSpecial() && manager.options.IncludeSpecials {
|
||||
if stat, _ := os.Lstat(fullPath); stat != nil {
|
||||
if remoteEntry.IsSameSpecial(stat) {
|
||||
remoteEntry.RestoreMetadata(fullPath, nil, metadataOptions)
|
||||
|
||||
@@ -251,21 +251,20 @@ func TestBackupManager(t *testing.T) {
|
||||
time.Sleep(time.Duration(delay) * time.Second)
|
||||
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
backupManager := CreateBackupManager("host1", storage, testDir, password, "", "", false)
|
||||
backupManager := CreateBackupManager("host1", storage, testDir, password, nil)
|
||||
backupManager.SetupSnapshotCache("default")
|
||||
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
backupManager.Backup(testDir+"/repository1" /*quickMode=*/, true, threads, "first", false, false, 0, false, 1024, 1024)
|
||||
time.Sleep(time.Duration(delay) * time.Second)
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles := backupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles := backupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: false,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
@@ -292,14 +291,13 @@ func TestBackupManager(t *testing.T) {
|
||||
backupManager.Backup(testDir+"/repository1" /*quickMode=*/, true, threads, "second", false, false, 0, false, 1024, 1024)
|
||||
time.Sleep(time.Duration(delay) * time.Second)
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = backupManager.Restore(testDir+"/repository2", 2, RestoreOptions{
|
||||
failedFiles = backupManager.Restore(testDir+"/repository2", 2, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: true,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
@@ -330,14 +328,13 @@ func TestBackupManager(t *testing.T) {
|
||||
createRandomFile(testDir+"/repository2/dir5/file5", 100)
|
||||
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = backupManager.Restore(testDir+"/repository2", 3, RestoreOptions{
|
||||
failedFiles = backupManager.Restore(testDir+"/repository2", 3, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: true,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
@@ -367,14 +364,13 @@ func TestBackupManager(t *testing.T) {
|
||||
os.Remove(testDir + "/repository1/file2")
|
||||
os.Remove(testDir + "/repository1/dir1/file3")
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
failedFiles = backupManager.Restore(testDir+"/repository1", 3, RestoreOptions{
|
||||
failedFiles = backupManager.Restore(testDir+"/repository1", 3, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: []string{"+file2", "+dir1/file3", "-*"},
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
@@ -564,7 +560,7 @@ func TestPersistRestore(t *testing.T) {
|
||||
|
||||
// do unencrypted backup
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
unencBackupManager := CreateBackupManager("host1", unencStorage, testDir, "", "", "", false)
|
||||
unencBackupManager := CreateBackupManager("host1", unencStorage, testDir, "", nil)
|
||||
unencBackupManager.SetupSnapshotCache("default")
|
||||
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
@@ -573,7 +569,7 @@ func TestPersistRestore(t *testing.T) {
|
||||
|
||||
// do encrypted backup
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
encBackupManager := CreateBackupManager("host1", storage, testDir, password, "", "", false)
|
||||
encBackupManager := CreateBackupManager("host1", storage, testDir, password, nil)
|
||||
encBackupManager.SetupSnapshotCache("default")
|
||||
|
||||
SetDuplicacyPreferencePath(testDir + "/repository1/.duplicacy")
|
||||
@@ -651,14 +647,13 @@ func TestPersistRestore(t *testing.T) {
|
||||
|
||||
// test restore all uncorrupted to repository3
|
||||
SetDuplicacyPreferencePath(testDir + "/repository3/.duplicacy")
|
||||
failedFiles := unencBackupManager.Restore(testDir+"/repository3", 1, RestoreOptions{
|
||||
failedFiles := unencBackupManager.Restore(testDir+"/repository3", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
@@ -706,14 +701,13 @@ func TestPersistRestore(t *testing.T) {
|
||||
// test restore corrupted, inPlace = true, corrupted files will have hash failures
|
||||
os.RemoveAll(testDir + "/repository2")
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
@@ -724,14 +718,13 @@ func TestPersistRestore(t *testing.T) {
|
||||
|
||||
os.RemoveAll(testDir + "/repository2")
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
@@ -744,14 +737,13 @@ func TestPersistRestore(t *testing.T) {
|
||||
// test restore corrupted, inPlace = false, corrupted files will be missing
|
||||
os.RemoveAll(testDir + "/repository2")
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: false,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
@@ -762,14 +754,13 @@ func TestPersistRestore(t *testing.T) {
|
||||
|
||||
os.RemoveAll(testDir + "/repository2")
|
||||
SetDuplicacyPreferencePath(testDir + "/repository2/.duplicacy")
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: false,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
@@ -782,27 +773,25 @@ func TestPersistRestore(t *testing.T) {
|
||||
// with overwrite=true, corrupted file1 from unenc will be restored correctly from enc
|
||||
// the latter will not touch the existing file3 with correct hash
|
||||
os.RemoveAll(testDir + "/repository2")
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: false,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
assertRestoreFailures(t, failedFiles, 1)
|
||||
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, RestoreOptions{
|
||||
failedFiles = encBackupManager.Restore(testDir+"/repository2", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
@@ -812,28 +801,26 @@ func TestPersistRestore(t *testing.T) {
|
||||
// restore to repository3, with overwrite and allowFailures (true/false), quickMode = false (use hashes)
|
||||
// should always succeed as uncorrupted files already exist with correct hash, so these will be ignored
|
||||
SetDuplicacyPreferencePath(testDir + "/repository3/.duplicacy")
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository3", 1, RestoreOptions{
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository3", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: false,
|
||||
})
|
||||
assertRestoreFailures(t, failedFiles, 0)
|
||||
checkAllUncorrupted("/repository3")
|
||||
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository3", 1, RestoreOptions{
|
||||
failedFiles = unencBackupManager.Restore(testDir+"/repository3", 1, &RestoreOptions{
|
||||
Threads: threads,
|
||||
Patterns: nil,
|
||||
InPlace: true,
|
||||
QuickMode: false,
|
||||
Overwrite: true,
|
||||
DeleteMode: false,
|
||||
SetOwner: false,
|
||||
ShowStatistics: false,
|
||||
AllowFailures: true,
|
||||
})
|
||||
|
||||
@@ -50,6 +50,7 @@ type Preference struct {
|
||||
NobackupFile string `json:"nobackup_file"`
|
||||
Keys map[string]string `json:"keys"`
|
||||
FiltersFile string `json:"filters"`
|
||||
ExcludeOwner bool `json:"exclude_owner"`
|
||||
ExcludeByAttribute bool `json:"exclude_by_attribute"`
|
||||
ExcludeXattrs bool `json:"exclude_xattrs"`
|
||||
NormalizeXattrs bool `json:"normalize_xattrs"`
|
||||
|
||||
Reference in New Issue
Block a user