-
Notifications
You must be signed in to change notification settings - Fork 1
/
upgrade.go
85 lines (69 loc) · 2.48 KB
/
upgrade.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package cosmovisor
import (
"errors"
"fmt"
"os"
"runtime"
"cosmossdk.io/log"
"cosmossdk.io/x/upgrade/plan"
upgradetypes "cosmossdk.io/x/upgrade/types"
)
// UpgradeBinary 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 UpgradeBinary(logger log.Logger, cfg *Config, p upgradetypes.Plan) error {
// simplest case is to switch the link
err := plan.EnsureBinary(cfg.UpgradeBin(p.Name))
if err == nil {
// we have the binary - do it
return cfg.SetCurrentUpgrade(p)
}
// if auto-download is disabled, we fail
if !cfg.AllowDownloadBinaries {
return fmt.Errorf("binary not present, downloading disabled: %w", err)
}
// if the dir is there already, don't download either
switch fi, err := os.Stat(cfg.UpgradeDir(p.Name)); {
case fi != nil: // The directory exists, do not overwrite.
return errors.New("upgrade dir already exists, won't overwrite")
case os.IsNotExist(err): // In this case the directory doesn't exist, continue below.
// Do nothing and we shall download the binary down below.
default: // Otherwise an unexpected error
return fmt.Errorf("unhandled error: %w", err)
}
upgradeInfo, err := plan.ParseInfo(p.Info, plan.ParseOptionEnforceChecksum(cfg.DownloadMustHaveChecksum))
if err != nil {
return fmt.Errorf("cannot parse upgrade info: %w", err)
}
if err := upgradeInfo.ValidateFull(cfg.Name); err != nil {
return fmt.Errorf("invalid binaries: %w", err)
}
url, err := GetBinaryURL(upgradeInfo.Binaries)
if err != nil {
return err
}
// If not there, then we try to download it... maybe
logger.Info("no upgrade binary found, beginning to download it")
if err := plan.DownloadUpgrade(cfg.UpgradeDir(p.Name), url, cfg.Name); err != nil {
return fmt.Errorf("cannot download binary. %w", err)
}
logger.Info("downloading binary complete")
// and then set the binary again
if err := plan.EnsureBinary(cfg.UpgradeBin(p.Name)); err != nil {
return fmt.Errorf("downloaded binary doesn't check out: %w", err)
}
return cfg.SetCurrentUpgrade(p)
}
func GetBinaryURL(binaries plan.BinaryDownloadURLMap) (string, error) {
url, ok := binaries[OSArch()]
if !ok {
url, ok = binaries["any"]
}
if !ok {
return "", fmt.Errorf("cannot find binary for os/arch: neither %s, nor any", OSArch())
}
return url, nil
}
func OSArch() string {
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
}