From 344be864de8338d230e3242237026ef2d359b666 Mon Sep 17 00:00:00 2001 From: yaruwangway <69694322+yaruwangway@users.noreply.github.com> Date: Tue, 4 Jan 2022 15:25:45 +0100 Subject: [PATCH] feat: add backup path (#10649) ## Description Closes: #10533 Cosmovisor can cause problems related to disk space when they try backing up, not enough space might fail the node. A new feature is added to allow user to set a backup path, which can be separated from the node-home directory. A new env var `DAEMON_BACKUP_DIR` is added. If `DAEMON_BACKUP_DIR` is set, backups will go there instead of `DAEMON_HOME`. - [x] add custom data backup dir - [x] add tests --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- cosmovisor/CHANGELOG.md | 2 +- cosmovisor/args.go | 40 +++++++++-- cosmovisor/args_test.go | 147 +++++++++++++++++++++++++--------------- cosmovisor/process.go | 2 +- 4 files changed, 129 insertions(+), 62 deletions(-) diff --git a/cosmovisor/CHANGELOG.md b/cosmovisor/CHANGELOG.md index 0504d4be12..ce3e201d25 100644 --- a/cosmovisor/CHANGELOG.md +++ b/cosmovisor/CHANGELOG.md @@ -39,7 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features + [\#10285](https://github.com/cosmos/cosmos-sdk/pull/10316) Added `run` action. - ++ [\#10533](https://github.com/cosmos/cosmos-sdk/pull/10649) Added environmental variable `DAEMON_BACKUP_DIR` to allow node to set a custom backup directory. ### Deprecated + [\#10285](https://github.com/cosmos/cosmos-sdk/pull/10316) Running `cosmovisor` without the `run` argument. diff --git a/cosmovisor/args.go b/cosmovisor/args.go index b58e4f7c14..f3643cdbdb 100644 --- a/cosmovisor/args.go +++ b/cosmovisor/args.go @@ -25,15 +25,16 @@ const ( EnvDownloadBin = "DAEMON_ALLOW_DOWNLOAD_BINARIES" EnvRestartUpgrade = "DAEMON_RESTART_AFTER_UPGRADE" EnvSkipBackup = "UNSAFE_SKIP_BACKUP" + EnvDataBackupPath = "DAEMON_DATA_BACKUP_DIR" EnvInterval = "DAEMON_POLL_INTERVAL" EnvPreupgradeMaxRetries = "DAEMON_PREUPGRADE_MAX_RETRIES" ) const ( - rootName = "cosmovisor" - genesisDir = "genesis" - upgradesDir = "upgrades" - currentLink = "current" + rootName = "cosmovisor" + genesisDir = "genesis" + upgradesDir = "upgrades" + currentLink = "current" ) // must be the same as x/upgrade/types.UpgradeInfoFilename @@ -47,6 +48,7 @@ type Config struct { RestartAfterUpgrade bool PollInterval time.Duration UnsafeSkipBackup bool + DataBackupPath string PreupgradeMaxRetries int // currently running upgrade @@ -129,8 +131,13 @@ func (cfg *Config) CurrentBin() (string, error) { func GetConfigFromEnv() (*Config, error) { var errs []error cfg := &Config{ - Home: os.Getenv(EnvHome), - Name: os.Getenv(EnvName), + Home: os.Getenv(EnvHome), + Name: os.Getenv(EnvName), + DataBackupPath: os.Getenv(EnvDataBackupPath), + } + + if cfg.DataBackupPath == "" { + cfg.DataBackupPath = cfg.Home } var err error @@ -213,6 +220,25 @@ func (cfg *Config) validate() []error { } } + // check the DataBackupPath + if cfg.UnsafeSkipBackup == true { + return errs + } + // if UnsafeSkipBackup is false, check if the DataBackupPath valid + switch { + case cfg.DataBackupPath == "": + errs = append(errs, errors.New(EnvDataBackupPath + " must not be empty")) + case !filepath.IsAbs(cfg.DataBackupPath): + errs = append(errs, errors.New(cfg.DataBackupPath + " must be an absolute path")) + default: + switch info, err := os.Stat(cfg.DataBackupPath); { + case err != nil: + errs = append(errs, fmt.Errorf("%q must be a valid directory: %w", cfg.DataBackupPath, err)) + case !info.IsDir(): + errs = append(errs, fmt.Errorf("%q must be a valid directory", cfg.DataBackupPath)) + } + } + return errs } @@ -305,6 +331,7 @@ func (cfg Config) DetailString() string { {EnvRestartUpgrade, fmt.Sprintf("%t", cfg.RestartAfterUpgrade)}, {EnvInterval, fmt.Sprintf("%s", cfg.PollInterval)}, {EnvSkipBackup, fmt.Sprintf("%t", cfg.UnsafeSkipBackup)}, + {EnvDataBackupPath, cfg.DataBackupPath}, {EnvPreupgradeMaxRetries, fmt.Sprintf("%d", cfg.PreupgradeMaxRetries)}, } derivedEntries := []struct{ name, value string }{ @@ -312,6 +339,7 @@ func (cfg Config) DetailString() string { {"Upgrade Dir", cfg.BaseUpgradeDir()}, {"Genesis Bin", cfg.GenesisBin()}, {"Monitored File", cfg.UpgradeInfoFilePath()}, + {"Data Backup Dir", cfg.DataBackupPath}, } var sb strings.Builder diff --git a/cosmovisor/args_test.go b/cosmovisor/args_test.go index 069050a1aa..67226df6dc 100644 --- a/cosmovisor/args_test.go +++ b/cosmovisor/args_test.go @@ -32,6 +32,7 @@ type cosmovisorEnv struct { DownloadBin string RestartUpgrade string SkipBackup string + DataBackupPath string Interval string PreupgradeMaxRetries string } @@ -44,6 +45,7 @@ func (c cosmovisorEnv) ToMap() map[string]string { EnvDownloadBin: c.DownloadBin, EnvRestartUpgrade: c.RestartUpgrade, EnvSkipBackup: c.SkipBackup, + EnvDataBackupPath: c.DataBackupPath, EnvInterval: c.Interval, EnvPreupgradeMaxRetries: c.PreupgradeMaxRetries, } @@ -62,6 +64,8 @@ func (c *cosmovisorEnv) Set(envVar, envVal string) { c.RestartUpgrade = envVal case EnvSkipBackup: c.SkipBackup = envVal + case EnvDataBackupPath: + c.DataBackupPath = envVal case EnvInterval: c.Interval = envVal case EnvPreupgradeMaxRetries: @@ -145,6 +149,7 @@ func (s *argsTestSuite) TestConfigPaths() { } // Test validate +// add more test in test validate func (s *argsTestSuite) TestValidate() { relPath := filepath.Join("testdata", "validate") absPath, err := filepath.Abs(relPath) @@ -158,11 +163,27 @@ func (s *argsTestSuite) TestValidate() { valid bool }{ "happy": { - cfg: Config{Home: absPath, Name: "bind"}, + cfg: Config{Home: absPath, Name: "bind", DataBackupPath: absPath}, valid: true, }, "happy with download": { - cfg: Config{Home: absPath, Name: "bind", AllowDownloadBinaries: true}, + cfg: Config{Home: absPath, Name: "bind", AllowDownloadBinaries: true, DataBackupPath: absPath}, + valid: true, + }, + "happy with skip data backup": { + cfg: Config{Home: absPath, Name: "bind", UnsafeSkipBackup: true, DataBackupPath: absPath}, + valid: true, + }, + "happy with skip data backup and empty data backup path": { + cfg: Config{Home: absPath, Name: "bind", UnsafeSkipBackup: true, DataBackupPath: ""}, + valid: true, + }, + "happy with skip data backup and no such data backup path dir": { + cfg: Config{Home: absPath, Name: "bind", UnsafeSkipBackup: true, DataBackupPath: filepath.FromSlash("/no/such/dir")}, + valid: true, + }, + "happy with skip data backup and relative data backup path": { + cfg: Config{Home: absPath, Name: "bind", UnsafeSkipBackup: true, DataBackupPath: relPath}, valid: true, }, "missing home": { @@ -173,7 +194,7 @@ func (s *argsTestSuite) TestValidate() { cfg: Config{Home: absPath}, valid: false, }, - "relative path": { + "relative home path": { cfg: Config{Home: relPath, Name: "bind"}, valid: false, }, @@ -181,10 +202,22 @@ func (s *argsTestSuite) TestValidate() { cfg: Config{Home: testdata, Name: "bind"}, valid: false, }, - "no such dir": { + "no such home dir": { cfg: Config{Home: filepath.FromSlash("/no/such/dir"), Name: "bind"}, valid: false, }, + "empty data backup path": { + cfg: Config{Home: absPath, Name: "bind", DataBackupPath: ""}, + valid: false, + }, + "no such data backup path dir": { + cfg: Config{Home: absPath, Name: "bind", DataBackupPath: filepath.FromSlash("/no/such/dir")}, + valid: false, + }, + "relative data backup path": { + cfg: Config{Home: absPath, Name: "bind", DataBackupPath: relPath}, + valid: false, + }, } for _, tc := range cases { @@ -202,7 +235,7 @@ func (s *argsTestSuite) TestEnsureBin() { absPath, err := filepath.Abs(relPath) s.Require().NoError(err) - cfg := Config{Home: absPath, Name: "dummyd"} + cfg := Config{Home: absPath, Name: "dummyd", DataBackupPath: absPath} s.Require().Len(cfg.validate(), 0, "validation errors") s.Require().NoError(EnsureBinary(cfg.GenesisBin())) @@ -275,6 +308,7 @@ func (s *argsTestSuite) TestDetailString() { restartAfterUpgrade := true pollInterval := 406 * time.Millisecond unsafeSkipBackup := false + dataBackupPath := "/home" preupgradeMaxRetries := 8 cfg := &Config{ Home: home, @@ -283,6 +317,7 @@ func (s *argsTestSuite) TestDetailString() { RestartAfterUpgrade: restartAfterUpgrade, PollInterval: pollInterval, UnsafeSkipBackup: unsafeSkipBackup, + DataBackupPath: dataBackupPath, PreupgradeMaxRetries: preupgradeMaxRetries, } @@ -294,12 +329,14 @@ func (s *argsTestSuite) TestDetailString() { fmt.Sprintf("%s: %t", EnvRestartUpgrade, restartAfterUpgrade), fmt.Sprintf("%s: %s", EnvInterval, pollInterval), fmt.Sprintf("%s: %t", EnvSkipBackup, unsafeSkipBackup), + fmt.Sprintf("%s: %s", EnvDataBackupPath, home), fmt.Sprintf("%s: %d", EnvPreupgradeMaxRetries, preupgradeMaxRetries), "Derived Values:", fmt.Sprintf("Root Dir: %s", home), fmt.Sprintf("Upgrade Dir: %s", home), fmt.Sprintf("Genesis Bin: %s", home), fmt.Sprintf("Monitored File: %s", home), + fmt.Sprintf("Data Backup Dir: %s", home), } actual := cfg.DetailString() @@ -317,7 +354,7 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { absPath, perr := filepath.Abs(relPath) s.Require().NoError(perr) - newConfig := func(home, name string, downloadBin, restartUpgrade, skipBackup bool, interval, preupgradeMaxRetries int) *Config { + newConfig := func(home, name, dataBackupPath string, downloadBin, restartUpgrade, skipBackup bool, interval, preupgradeMaxRetries int) *Config { return &Config{ Home: home, Name: name, @@ -325,6 +362,7 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { RestartAfterUpgrade: restartUpgrade, PollInterval: time.Millisecond * time.Duration(interval), UnsafeSkipBackup: skipBackup, + DataBackupPath: dataBackupPath, PreupgradeMaxRetries: preupgradeMaxRetries, } } @@ -335,160 +373,160 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { expectedCfg *Config expectedErrCount int }{ - // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvInterval, EnvPreupgradeMaxRetries + // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvDataBackupPath, EnvDataBackupPath, EnvInterval, EnvPreupgradeMaxRetries { name: "all bad", - envVals: cosmovisorEnv{"", "", "bad", "bad", "bad", "bad", "bad"}, + envVals: cosmovisorEnv{"", "", "bad", "bad", "bad", "", "bad", "bad"}, expectedCfg: nil, - expectedErrCount: 7, + expectedErrCount: 8, }, { name: "all good", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, true, 303, 1), expectedErrCount: 0, }, { name: "nothing set", - envVals: cosmovisorEnv{"", "", "", "", "", "", ""}, + envVals: cosmovisorEnv{"", "", "", "", "", "", "", ""}, expectedCfg: nil, - expectedErrCount: 2, + expectedErrCount: 3, }, // Note: Home and Name tests are done in TestValidate { name: "download bin bad", - envVals: cosmovisorEnv{absPath, "testname", "bad", "false", "true", "303", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "bad", "false", "true", "", "303", "1"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "download bin not set", - envVals: cosmovisorEnv{absPath, "testname", "", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", false, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, true, 303, 1), expectedErrCount: 0, }, { name: "download bin true", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, true, 303, 1), expectedErrCount: 0, }, { name: "download bin false", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", false, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, true, 303, 1), expectedErrCount: 0, }, - // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvInterval, EnvPreupgradeMaxRetries + // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvDataBackupPath, EnvInterval, EnvPreupgradeMaxRetries { name: "restart upgrade bad", - envVals: cosmovisorEnv{absPath, "testname", "true", "bad", "true", "303", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "true", "bad", "true", "", "303", "1"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart upgrade not set", - envVals: cosmovisorEnv{absPath, "testname", "true", "", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, true, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, true, true, 303, 1), expectedErrCount: 0, }, { name: "restart upgrade true", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, true, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, true, true, 303, 1), expectedErrCount: 0, }, { name: "restart upgrade true", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, true, 303, 1), expectedErrCount: 0, }, - // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvInterval, EnvPreupgradeMaxRetries + // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvDataBackupPath, EnvInterval, EnvPreupgradeMaxRetries { name: "skip unsafe backups bad", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "bad", "303", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "bad", "", "303", "1"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "skip unsafe backups not set", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, false, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, false, 303, 1), expectedErrCount: 0, }, { name: "skip unsafe backups true", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, true, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "true", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, true, 303, 1), expectedErrCount: 0, }, { name: "skip unsafe backups false", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "false", "303", "1"}, - expectedCfg: newConfig(absPath, "testname", true, false, false, 303, 1), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "false", "", "303", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, true, false, false, 303, 1), expectedErrCount: 0, }, - // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvInterval, EnvPreupgradeMaxRetries + // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvDataBackupPath, EnvInterval, EnvPreupgradeMaxRetries { name: "poll interval bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "bad", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "bad", "1"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "poll interval 0", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "0", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "0", "1"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "poll interval not set", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "1"}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 300, 1), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 300, 1), expectedErrCount: 0, }, { name: "poll interval 987", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "987", "1"}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 987, 1), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "987", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 987, 1), expectedErrCount: 0, }, { name: "poll interval 1s", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "1s", "1"}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 1000, 1), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "1s", "1"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 1000, 1), expectedErrCount: 0, }, { name: "poll interval -3m", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "-3m", "1"}, + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "-3m", "1"}, expectedCfg: nil, expectedErrCount: 1, }, - // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvInterval, EnvPreupgradeMaxRetries + // EnvHome, EnvName, EnvDownloadBin, EnvRestartUpgrade, EnvSkipBackup, EnvDataBackupPath, EnvInterval, EnvPreupgradeMaxRetries { name: "prepupgrade max retries bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "406", "bad"}, + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "406", "bad"}, expectedCfg: nil, expectedErrCount: 1, }, { name: "prepupgrade max retries 0", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "406", "0"}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 406, 0), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "406", "0"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 406, 0), expectedErrCount: 0, }, { name: "prepupgrade max retries not set", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "406", ""}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 406, 0), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "406", ""}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 406, 0), expectedErrCount: 0, }, { name: "prepupgrade max retries 5", - envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "406", "5"}, - expectedCfg: newConfig(absPath, "testname", false, false, false, 406, 5), + envVals: cosmovisorEnv{absPath, "testname", "false", "false", "false", "", "406", "5"}, + expectedCfg: newConfig(absPath, "testname", absPath, false, false, false, 406, 5), expectedErrCount: 0, }, } @@ -521,6 +559,7 @@ func (s *argsTestSuite) TestLogConfigOrError() { RestartAfterUpgrade: true, PollInterval: 999, UnsafeSkipBackup: false, + DataBackupPath: "/no/place/like/it", PreupgradeMaxRetries: 20, } errNormal := fmt.Errorf("this is a single error") diff --git a/cosmovisor/process.go b/cosmovisor/process.go index 8c2d10104d..0f57940553 100644 --- a/cosmovisor/process.go +++ b/cosmovisor/process.go @@ -131,7 +131,7 @@ func doBackup(cfg *Config) error { // a destination directory, Format YYYY-MM-DD st := time.Now() stStr := fmt.Sprintf("%d-%d-%d", st.Year(), st.Month(), st.Day()) - dst := filepath.Join(cfg.Home, fmt.Sprintf("data"+"-backup-%s", stStr)) + dst := filepath.Join(cfg.DataBackupPath, fmt.Sprintf("data"+"-backup-%s", stStr)) Logger.Info().Time("backup start time", st).Msg("starting to take backup of data directory")