fix(cosmovisor): let cosmovisor version return a valid json (#11731)

This commit is contained in:
Julien Robert 2022-04-26 23:25:02 +02:00 committed by GitHub
parent 1d8a878728
commit 019444ae43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 208 additions and 89 deletions

View File

@ -37,6 +37,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
<!-- NOTE: when creating a new release, update cosmovisor/cmd/cosmovisor/cmd/version.go:Version -->
* [\#11731](https://github.com/cosmos/cosmos-sdk/pull/11731) `cosmovisor version --json` returns the cosmovisor version and the result of `simd --output json --long` in one JSON object.
## v1.1.0 2022-10-02
### Features

View File

@ -11,11 +11,10 @@ import (
"strings"
"time"
"github.com/rs/zerolog"
cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/rs/zerolog"
)
// environment variable names
@ -184,11 +183,11 @@ func GetConfigFromEnv() (*Config, error) {
}
// LogConfigOrError logs either the config details or the error.
func LogConfigOrError(logger zerolog.Logger, cfg *Config, err error) {
func LogConfigOrError(logger *zerolog.Logger, cfg *Config, err error) {
if cfg == nil && err == nil {
return
}
logger.Info().Msg("Configuration:")
logger.Info().Msg("configuration:")
switch {
case err != nil:
cverrors.LogErrors(logger, "configuration errors found", err)
@ -227,9 +226,9 @@ func (cfg *Config) validate() []error {
// if UnsafeSkipBackup is false, check if the DataBackupPath valid
switch {
case cfg.DataBackupPath == "":
errs = append(errs, errors.New(EnvDataBackupPath + " must not be empty"))
errs = append(errs, fmt.Errorf("%s must not be empty", EnvDataBackupPath))
case !filepath.IsAbs(cfg.DataBackupPath):
errs = append(errs, errors.New(cfg.DataBackupPath + " must be an absolute path"))
errs = append(errs, fmt.Errorf("%s must be an absolute path", cfg.DataBackupPath))
default:
switch info, err := os.Stat(cfg.DataBackupPath); {
case err != nil:
@ -281,9 +280,9 @@ func (cfg *Config) SetCurrentUpgrade(u upgradetypes.Plan) error {
return f.Close()
}
func (cfg *Config) UpgradeInfo() upgradetypes.Plan {
func (cfg *Config) UpgradeInfo() (upgradetypes.Plan, error) {
if cfg.currentUpgrade.Name != "" {
return cfg.currentUpgrade
return cfg.currentUpgrade, nil
}
filename := filepath.Join(cfg.Root(), currentLink, upgradekeeper.UpgradeInfoFileName)
@ -300,12 +299,11 @@ func (cfg *Config) UpgradeInfo() upgradetypes.Plan {
goto returnError
}
cfg.currentUpgrade = u
return cfg.currentUpgrade
return cfg.currentUpgrade, nil
returnError:
Logger.Error().Err(err).Str("filename", filename).Msg("failed to read")
cfg.currentUpgrade.Name = "_"
return cfg.currentUpgrade
return cfg.currentUpgrade, fmt.Errorf("failed to read %q: %w", filename, err)
}
// checks and validates env option

View File

@ -570,9 +570,10 @@ func (s *argsTestSuite) TestLogConfigOrError() {
}
errMulti := errors.FlattenErrors(errs...)
makeTestLogger := func(testName string, out io.Writer) zerolog.Logger {
makeTestLogger := func(testName string, out io.Writer) *zerolog.Logger {
output := zerolog.ConsoleWriter{Out: out, TimeFormat: time.Kitchen, NoColor: true}
return zerolog.New(output).With().Str("test", testName).Timestamp().Logger()
logger := zerolog.New(output).With().Str("test", testName).Timestamp().Logger()
return &logger
}
tests := []struct {

View File

@ -17,9 +17,11 @@ func ShouldGiveHelp(arg string) bool {
}
// DoHelp outputs help text
func DoHelp() {
func DoHelp() error {
// Not using the logger for this output because the header and footer look weird for help text.
fmt.Println(GetHelpText())
return nil
}
// GetHelpText creates the help text multi-line string.

View File

@ -3,30 +3,34 @@ package cmd
import (
"strings"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"github.com/rs/zerolog"
)
// RunCosmovisorCommand executes the desired cosmovisor command.
func RunCosmovisorCommand(args []string) error {
func RunCosmovisorCommand(logger *zerolog.Logger, args []string) error {
arg0 := ""
if len(args) > 0 {
arg0 = strings.TrimSpace(args[0])
}
switch {
case IsVersionCommand(arg0):
return PrintVersion()
return PrintVersion(logger, args[1:])
case ShouldGiveHelp(arg0):
DoHelp()
return nil
return DoHelp()
case IsRunCommand(arg0):
return Run(args[1:])
return Run(logger, args[1:])
}
warnRun := func() {
cosmovisor.Logger.Warn().Msg("Use of cosmovisor without the 'run' command is deprecated. Use: cosmovisor run [args]")
logger.Warn().Msg("use of cosmovisor without the 'run' command is deprecated. Use: cosmovisor run [args]")
}
warnRun()
defer warnRun()
return Run(args)
return Run(logger, args)
}
// isOneOf returns true if the given arg equals one of the provided options (ignoring case).

View File

@ -1,9 +1,8 @@
package cmd
import (
"os"
"github.com/cosmos/cosmos-sdk/cosmovisor"
"github.com/rs/zerolog"
)
// RunArgs are the strings that indicate a cosmovisor run command.
@ -15,24 +14,30 @@ func IsRunCommand(arg string) bool {
}
// Run runs the configured program with the given args and monitors it for upgrades.
func Run(args []string) error {
func Run(logger *zerolog.Logger, args []string, options ...RunOption) error {
cfg, err := cosmovisor.GetConfigFromEnv()
if err != nil {
return err
}
launcher, err := cosmovisor.NewLauncher(cfg)
runCfg := DefaultRunConfig
for _, opt := range options {
opt(&runCfg)
}
launcher, err := cosmovisor.NewLauncher(logger, cfg)
if err != nil {
return err
}
doUpgrade, err := launcher.Run(args, os.Stdout, os.Stderr)
doUpgrade, err := launcher.Run(args, runCfg.StdOut, runCfg.StdErr)
// if RestartAfterUpgrade, we launch after a successful upgrade (only condition LaunchProcess returns nil)
for cfg.RestartAfterUpgrade && err == nil && doUpgrade {
cosmovisor.Logger.Info().Str("app", cfg.Name).Msg("upgrade detected, relaunching")
doUpgrade, err = launcher.Run(args, os.Stdout, os.Stderr)
logger.Info().Str("app", cfg.Name).Msg("upgrade detected, relaunching")
doUpgrade, err = launcher.Run(args, runCfg.StdOut, runCfg.StdErr)
}
if doUpgrade && err == nil {
cosmovisor.Logger.Info().Msg("upgrade detected, DAEMON_RESTART_AFTER_UPGRADE is off. Verify new upgrade and start cosmovisor again.")
logger.Info().Msg("upgrade detected, DAEMON_RESTART_AFTER_UPGRADE is off. Verify new upgrade and start cosmovisor again.")
}
return err

View File

@ -0,0 +1,34 @@
package cmd
import (
"io"
"os"
)
// DefaultRunConfig defintes a default RunConfig that writes to os.Stdout and os.Stderr
var DefaultRunConfig = RunConfig{
StdOut: os.Stdout,
StdErr: os.Stderr,
}
// RunConfig defines the configuration for running a command
type RunConfig struct {
StdOut io.Writer
StdErr io.Writer
}
type RunOption func(*RunConfig)
// StdOutRunOption sets the StdOut writer for the Run command
func StdOutRunOption(w io.Writer) RunOption {
return func(cfg *RunConfig) {
cfg.StdOut = w
}
}
// SdErrRunOption sets the StdErr writer for the Run command
func StdErrRunOption(w io.Writer) RunOption {
return func(cfg *RunConfig) {
cfg.StdErr = w
}
}

View File

@ -1,19 +1,24 @@
package cmd
import (
"encoding/json"
"fmt"
"os"
"strings"
"time"
cverrors "github.com/cosmos/cosmos-sdk/cosmovisor/errors"
"github.com/rs/zerolog"
)
// Version represents Cosmovisor version value. Overwritten during build
var Version = "1.1.0"
// VersionArgs is the strings that indicate a cosmovisor version command.
var VersionArgs = []string{"version", "--version"}
var (
// FlagJSON formats the output in json
FlagJSON = "--json"
// Version represents Cosmovisor version value. Overwritten during build
Version = "1.1.0"
// VersionArgs is the strings that indicate a cosmovisor version command.
VersionArgs = []string{"version", "--version"}
)
// IsVersionCommand checks if the given args indicate that the version is being requested.
func IsVersionCommand(arg string) bool {
@ -21,16 +26,63 @@ func IsVersionCommand(arg string) bool {
}
// PrintVersion prints the cosmovisor version.
func PrintVersion() error {
func PrintVersion(logger *zerolog.Logger, args []string) error {
for _, arg := range args {
if strings.Contains(arg, FlagJSON) {
return printVersionJSON(logger, args)
}
}
return printVersion(logger, args)
}
func printVersion(logger *zerolog.Logger, args []string) error {
fmt.Println("Cosmovisor Version: ", Version)
if err := Run([]string{"version"}); err != nil {
// Check the config and output details or any errors.
// Not using the cosmovisor.Logger in order to ignore any level it might have set,
// and also to not have any of the extra parameters in the output.
output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.Kitchen}
logger := zerolog.New(output).With().Timestamp().Logger()
cverrors.LogErrors(logger, "Can't run APP version", err)
if err := Run(logger, append([]string{"version"}, args...)); err != nil {
handleRunVersionFailure(err)
}
return nil
}
func printVersionJSON(logger *zerolog.Logger, args []string) error {
buf := new(strings.Builder)
// disable logger
l := logger.Level(zerolog.Disabled)
logger = &l
if err := Run(
logger,
[]string{"version", "--long", "--output", "json"},
StdOutRunOption(buf),
); err != nil {
handleRunVersionFailure(err)
}
out, err := json.Marshal(struct {
Version string `json:"cosmovisor_version"`
AppVersion json.RawMessage `json:"app_version"`
}{
Version: Version,
AppVersion: json.RawMessage(buf.String()),
})
if err != nil {
l := logger.Level(zerolog.TraceLevel)
logger = &l
return fmt.Errorf("Can't print version output, expected valid json from APP, got: %s - %w", buf.String(), err)
}
fmt.Println(string(out))
return nil
}
func handleRunVersionFailure(err error) {
// Check the config and output details or any errors.
// Not using the cosmovisor.Logger in order to ignore any level it might have set,
// and also to not have any of the extra parameters in the output.
output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.Kitchen}
logger := zerolog.New(output).With().Timestamp().Logger()
cverrors.LogErrors(&logger, "Can't run APP version", err)
}

View File

@ -9,9 +9,9 @@ import (
)
func main() {
cosmovisor.SetupLogging()
if err := cmd.RunCosmovisorCommand(os.Args[1:]); err != nil {
cverrors.LogErrors(cosmovisor.Logger, "", err)
logger := cosmovisor.NewLogger()
if err := cmd.RunCosmovisorCommand(logger, os.Args[1:]); err != nil {
cverrors.LogErrors(logger, "", err)
os.Exit(1)
}
}

View File

@ -70,7 +70,7 @@ func (e MultiError) String() string {
return e.Error()
}
func LogErrors(logger zerolog.Logger, msg string, err error) {
func LogErrors(logger *zerolog.Logger, msg string, err error) {
switch err := err.(type) {
case *MultiError:
if msg != "" {

View File

@ -7,9 +7,8 @@ import (
"github.com/rs/zerolog"
)
var Logger zerolog.Logger
func SetupLogging() {
func NewLogger() *zerolog.Logger {
output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.Kitchen}
Logger = zerolog.New(output).With().Str("module", "cosmovisor").Timestamp().Logger()
logger := zerolog.New(output).With().Str("module", "cosmovisor").Timestamp().Logger()
return &logger
}

View File

@ -14,18 +14,24 @@ import (
"time"
"github.com/otiai10/copy"
"github.com/rs/zerolog"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
type Launcher struct {
cfg *Config
fw *fileWatcher
logger *zerolog.Logger
cfg *Config
fw *fileWatcher
}
func NewLauncher(cfg *Config) (Launcher, error) {
fw, err := newUpgradeFileWatcher(cfg.UpgradeInfoFilePath(), cfg.PollInterval)
return Launcher{cfg, fw}, err
func NewLauncher(logger *zerolog.Logger, cfg *Config) (Launcher, error) {
fw, err := newUpgradeFileWatcher(logger, cfg.UpgradeInfoFilePath(), cfg.PollInterval)
if err != nil {
return Launcher{}, err
}
return Launcher{logger: logger, cfg: cfg, fw: fw}, nil
}
// Run launches the app in a subprocess and returns when the subprocess (app)
@ -40,7 +46,8 @@ func (l Launcher) Run(args []string, stdout, stderr io.Writer) (bool, error) {
if err := EnsureBinary(bin); err != nil {
return false, fmt.Errorf("current binary is invalid: %w", err)
}
Logger.Info().Str("path", bin).Strs("args", args).Msg("running app")
l.logger.Info().Str("path", bin).Strs("args", args).Msg("running app")
cmd := exec.Command(bin, args...)
cmd.Stdout = stdout
cmd.Stderr = stderr
@ -53,7 +60,7 @@ func (l Launcher) Run(args []string, stdout, stderr io.Writer) (bool, error) {
go func() {
sig := <-sigs
if err := cmd.Process.Signal(sig); err != nil {
Logger.Fatal().Err(err).Str("bin", bin).Msg("terminated")
l.logger.Fatal().Err(err).Str("bin", bin).Msg("terminated")
}
}()
@ -63,16 +70,16 @@ func (l Launcher) Run(args []string, stdout, stderr io.Writer) (bool, error) {
}
if !IsSkipUpgradeHeight(args, l.fw.currentInfo) {
if err := doBackup(l.cfg); err != nil {
if err := l.doBackup(); err != nil {
return false, err
}
if err = doPreUpgrade(l.cfg); err != nil {
if err = l.doPreUpgrade(); err != nil {
return false, err
}
}
return true, DoUpgrade(l.cfg, l.fw.currentInfo)
return true, DoUpgrade(l.logger, l.cfg, l.fw.currentInfo)
}
// WaitForUpgradeOrExit checks upgrade plan file created by the app.
@ -83,7 +90,11 @@ func (l Launcher) Run(args []string, stdout, stderr io.Writer) (bool, error) {
// It returns (false, nil) if the process exited normally without triggering an upgrade. This is very unlikely
// to happened with "start" but may happened with short-lived commands like `gaiad export ...`
func (l Launcher) WaitForUpgradeOrExit(cmd *exec.Cmd) (bool, error) {
currentUpgrade := l.cfg.UpgradeInfo()
currentUpgrade, err := l.cfg.UpgradeInfo()
if err != nil {
l.logger.Error().Err(err)
}
var cmdDone = make(chan error)
go func() {
cmdDone <- cmd.Wait()
@ -92,7 +103,7 @@ func (l Launcher) WaitForUpgradeOrExit(cmd *exec.Cmd) (bool, error) {
select {
case <-l.fw.MonitorUpdate(currentUpgrade):
// upgrade - kill the process and restart
Logger.Info().Msg("Daemon shutting down in an attempt to restart")
l.logger.Info().Msg("daemon shutting down in an attempt to restart")
_ = cmd.Process.Kill()
case err := <-cmdDone:
l.fw.Stop()
@ -109,12 +120,12 @@ func (l Launcher) WaitForUpgradeOrExit(cmd *exec.Cmd) (bool, error) {
return true, nil
}
func doBackup(cfg *Config) error {
func (l Launcher) doBackup() error {
// take backup if `UNSAFE_SKIP_BACKUP` is not set.
if !cfg.UnsafeSkipBackup {
if !l.cfg.UnsafeSkipBackup {
// check if upgrade-info.json is not empty.
var uInfo upgradetypes.Plan
upgradeInfoFile, err := os.ReadFile(filepath.Join(cfg.Home, "data", "upgrade-info.json"))
upgradeInfoFile, err := os.ReadFile(filepath.Join(l.cfg.Home, "data", "upgrade-info.json"))
if err != nil {
return fmt.Errorf("error while reading upgrade-info.json: %w", err)
}
@ -131,12 +142,12 @@ 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.DataBackupPath, fmt.Sprintf("data"+"-backup-%s", stStr))
dst := filepath.Join(l.cfg.DataBackupPath, fmt.Sprintf("data"+"-backup-%s", stStr))
Logger.Info().Time("backup start time", st).Msg("starting to take backup of data directory")
l.logger.Info().Time("backup start time", st).Msg("starting to take backup of data directory")
// copy the $DAEMON_HOME/data to a backup dir
err = copy.Copy(filepath.Join(cfg.Home, "data"), dst)
err = copy.Copy(filepath.Join(l.cfg.Home, "data"), dst)
if err != nil {
return fmt.Errorf("error while taking data backup: %w", err)
@ -144,7 +155,7 @@ func doBackup(cfg *Config) error {
// backup is done, lets check endtime to calculate total time taken for backup process
et := time.Now()
Logger.Info().Str("backup saved at", dst).Time("backup completion time", et).TimeDiff("time taken to complete backup", et, st).Msg("backup completed")
l.logger.Info().Str("backup saved at", dst).Time("backup completion time", et).TimeDiff("time taken to complete backup", et, st).Msg("backup completed")
}
return nil
@ -152,38 +163,39 @@ func doBackup(cfg *Config) error {
// doPreUpgrade runs the pre-upgrade command defined by the application and handles respective error codes
// cfg contains the cosmovisor config from env var
func doPreUpgrade(cfg *Config) error {
func (l *Launcher) doPreUpgrade() error {
counter := 0
for {
if counter > cfg.PreupgradeMaxRetries {
return fmt.Errorf("pre-upgrade command failed. reached max attempt of retries - %d", cfg.PreupgradeMaxRetries)
if counter > l.cfg.PreupgradeMaxRetries {
return fmt.Errorf("pre-upgrade command failed. reached max attempt of retries - %d", l.cfg.PreupgradeMaxRetries)
}
err := executePreUpgradeCmd(cfg)
err := l.executePreUpgradeCmd()
counter += 1
if err != nil {
if err.(*exec.ExitError).ProcessState.ExitCode() == 1 {
Logger.Info().Msg("pre-upgrade command does not exist. continuing the upgrade.")
l.logger.Info().Msg("pre-upgrade command does not exist. continuing the upgrade.")
return nil
}
if err.(*exec.ExitError).ProcessState.ExitCode() == 30 {
return fmt.Errorf("pre-upgrade command failed : %w", err)
}
if err.(*exec.ExitError).ProcessState.ExitCode() == 31 {
Logger.Error().Err(err).Int("attempt", counter).Msg("pre-upgrade command failed. retrying")
l.logger.Error().Err(err).Int("attempt", counter).Msg("pre-upgrade command failed. retrying")
continue
}
}
fmt.Println("pre-upgrade successful. continuing the upgrade.")
l.logger.Info().Msg("pre-upgrade successful. continuing the upgrade.")
return nil
}
}
// executePreUpgradeCmd runs the pre-upgrade command defined by the application
// cfg contains the cosmosvisor config from the env vars
func executePreUpgradeCmd(cfg *Config) error {
bin, err := cfg.CurrentBin()
func (l *Launcher) executePreUpgradeCmd() error {
bin, err := l.cfg.CurrentBin()
if err != nil {
return err
}

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux
package cosmovisor_test
@ -28,6 +29,7 @@ func (s *processTestSuite) TestLaunchProcess() {
require := s.Require()
home := copyTestData(s.T(), "validate")
cfg := &cosmovisor.Config{Home: home, Name: "dummyd", PollInterval: 20, UnsafeSkipBackup: true}
logger := cosmovisor.NewLogger()
// should run the genesis binary and produce expected output
var stdout, stderr = NewBuffer(), NewBuffer()
@ -35,10 +37,11 @@ func (s *processTestSuite) TestLaunchProcess() {
require.NoError(err)
require.Equal(cfg.GenesisBin(), currentBin)
launcher, err := cosmovisor.NewLauncher(cfg)
launcher, err := cosmovisor.NewLauncher(logger, cfg)
require.NoError(err)
upgradeFile := cfg.UpgradeInfoFilePath()
args := []string{"foo", "bar", "1234", upgradeFile}
doUpgrade, err := launcher.Run(args, stdout, stderr)
require.NoError(err)
@ -77,6 +80,7 @@ func (s *processTestSuite) TestLaunchProcessWithDownloads() {
require := s.Require()
home := copyTestData(s.T(), "download")
cfg := &cosmovisor.Config{Home: home, Name: "autod", AllowDownloadBinaries: true, PollInterval: 100, UnsafeSkipBackup: true}
logger := cosmovisor.NewLogger()
upgradeFilename := cfg.UpgradeInfoFilePath()
// should run the genesis binary and produce expected output
@ -84,7 +88,7 @@ func (s *processTestSuite) TestLaunchProcessWithDownloads() {
require.NoError(err)
require.Equal(cfg.GenesisBin(), currentBin)
launcher, err := cosmovisor.NewLauncher(cfg)
launcher, err := cosmovisor.NewLauncher(logger, cfg)
require.NoError(err)
var stdout, stderr = NewBuffer(), NewBuffer()

View File

@ -10,9 +10,12 @@ import (
"time"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/rs/zerolog"
)
type fileWatcher struct {
logger *zerolog.Logger
// full path to a watched file
filename string
interval time.Duration
@ -26,7 +29,7 @@ type fileWatcher struct {
initialized bool
}
func newUpgradeFileWatcher(filename string, interval time.Duration) (*fileWatcher, error) {
func newUpgradeFileWatcher(logger *zerolog.Logger, filename string, interval time.Duration) (*fileWatcher, error) {
if filename == "" {
return nil, errors.New("filename undefined")
}
@ -44,6 +47,7 @@ func newUpgradeFileWatcher(filename string, interval time.Duration) (*fileWatche
}
return &fileWatcher{
logger: logger,
filename: filenameAbs,
interval: interval,
currentInfo: upgradetypes.Plan{},
@ -106,7 +110,7 @@ func (fw *fileWatcher) CheckUpdate(currentUpgrade upgradetypes.Plan) bool {
info, err := parseUpgradeInfoFile(fw.filename)
if err != nil {
Logger.Fatal().Err(err).Msg("failed to parse upgrade info file")
fw.logger.Fatal().Err(err).Msg("failed to parse upgrade info file")
return false
}

View File

@ -6,7 +6,7 @@ echo 'ERROR: UPGRADE "chain2" NEEDED at height: 49: zip_binary'
# create upgrade info
# this info contains directly information about binaries (in chain2->chain3 update we test with info containing a link to the file with an address for the new chain binary)
echo '{"name":"chain2","height":49,"info":"{\"binaries\":{\"linux/amd64\":\"https://github.com/cosmos/cosmos-sdk/raw/main/cosmovisor/testdata/repo/chain2-zip_bin/autod.zip?checksum=sha256:e2e178953d176196dcf736afa821121b259697ab4df90582044c313bcae48f13\"}}"}' >$3
echo '{"name":"chain2","height":49,"info":"{\"binaries\":{\"linux/amd64\":\"https://github.com/cosmos/cosmos-sdk/raw/main/cosmovisor/testdata/repo/chain2-zip_bin/autod.zip?checksum=sha256:b30cf0b1a3e46ac9587cc4d7b102eb796e39e3e0dfa3f8ca6e163fc1b1e913ca\"}}"}' >$3
sleep 0.1
echo Never should be printed!!!

View File

@ -13,12 +13,13 @@ import (
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/hashicorp/go-getter"
"github.com/otiai10/copy"
"github.com/rs/zerolog"
)
// DoUpgrade will be called after the log message has been parsed and the process has terminated.
// We can now make any changes to the underlying directory without interference and leave it
// in a state, so we can make a proper restart
func DoUpgrade(cfg *Config, info upgradetypes.Plan) error {
func DoUpgrade(logger *zerolog.Logger, cfg *Config, info upgradetypes.Plan) error {
// Simplest case is to switch the link
err := EnsureBinary(cfg.UpgradeBin(info.Name))
if err == nil {
@ -36,11 +37,11 @@ func DoUpgrade(cfg *Config, info upgradetypes.Plan) error {
}
// If not there, then we try to download it... maybe
Logger.Info().Msg("No upgrade binary found, beginning to download it")
logger.Info().Msg("no upgrade binary found, beginning to download it")
if err := DownloadBinary(cfg, info); err != nil {
return fmt.Errorf("cannot download binary. %w", err)
}
Logger.Info().Msg("Downloading binary complete")
logger.Info().Msg("downloading binary complete")
// and then set the binary again
if err := EnsureBinary(cfg.UpgradeBin(info.Name)); err != nil {

View File

@ -95,6 +95,7 @@ func (s *upgradeTestSuite) assertCurrentLink(cfg cosmovisor.Config, target strin
func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() {
home := copyTestData(s.T(), "validate")
cfg := &cosmovisor.Config{Home: home, Name: "dummyd", AllowDownloadBinaries: true}
logger := cosmovisor.NewLogger()
currentBin, err := cfg.CurrentBin()
s.Require().NoError(err)
@ -104,7 +105,7 @@ func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() {
// do upgrade ignores bad files
for _, name := range []string{"missing", "nobin", "noexec"} {
info := upgradetypes.Plan{Name: name}
err = cosmovisor.DoUpgrade(cfg, info)
err = cosmovisor.DoUpgrade(logger, cfg, info)
s.Require().Error(err, name)
currentBin, err := cfg.CurrentBin()
s.Require().NoError(err)
@ -115,7 +116,7 @@ func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() {
for _, upgrade := range []string{"chain2", "chain3"} {
// now set it to a valid upgrade and make sure CurrentBin is now set properly
info := upgradetypes.Plan{Name: upgrade}
err = cosmovisor.DoUpgrade(cfg, info)
err = cosmovisor.DoUpgrade(logger, cfg, info)
s.Require().NoError(err)
// we should see current point to the new upgrade dir
upgradeBin := cfg.UpgradeBin(upgrade)