autoupdater: use blang/semver (#3063)
This commit is contained in:
parent
756d0ad2b5
commit
68d281db44
@ -24,6 +24,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/zeebo/errs"
|
||||
|
||||
@ -62,7 +63,7 @@ var (
|
||||
func init() {
|
||||
rootCmd.AddCommand(runCmd)
|
||||
|
||||
runCmd.Flags().StringVar(&interval, "interval", "06h", "interval for checking the new version")
|
||||
runCmd.Flags().StringVar(&interval, "interval", "06h", "interval for checking the new version, 0 or less value will execute version check only once")
|
||||
runCmd.Flags().StringVar(&versionURL, "version-url", "https://version.storj.io/release/", "version server URL")
|
||||
runCmd.Flags().StringVar(&binaryLocation, "binary-location", "storagenode.exe", "the storage node executable binary location")
|
||||
|
||||
@ -71,13 +72,14 @@ func init() {
|
||||
}
|
||||
|
||||
func cmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||
if logPath != "" {
|
||||
logFile, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return errs.New("error opening log file: %v", err)
|
||||
}
|
||||
defer func() { err = errs.Combine(err, logFile.Close()) }()
|
||||
|
||||
log.SetOutput(logFile)
|
||||
}
|
||||
|
||||
if !fileExists(binaryLocation) {
|
||||
return errs.New("unable to find storage node executable binary")
|
||||
@ -95,13 +97,6 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||
cancel()
|
||||
}()
|
||||
|
||||
loopInterval, err := time.ParseDuration(interval)
|
||||
if err != nil {
|
||||
return errs.New("unable to parse interval parameter: %v", err)
|
||||
}
|
||||
|
||||
loop := sync2.NewCycle(loopInterval)
|
||||
|
||||
update := func(ctx context.Context) (err error) {
|
||||
currentVersion, err := binaryVersion(binaryLocation)
|
||||
if err != nil {
|
||||
@ -170,23 +165,35 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = loop.Run(ctx, func(ctx context.Context) (err error) {
|
||||
loopInterval, err := time.ParseDuration(interval)
|
||||
if err != nil {
|
||||
return errs.New("unable to parse interval parameter: %v", err)
|
||||
}
|
||||
|
||||
loopFunc := func(ctx context.Context) (err error) {
|
||||
if err := update(ctx); err != nil {
|
||||
// don't finish loop in case of error just wait for another execution
|
||||
log.Println(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
if loopInterval <= 0 {
|
||||
err = loopFunc(ctx)
|
||||
} else {
|
||||
loop := sync2.NewCycle(loopInterval)
|
||||
err = loop.Run(ctx, loopFunc)
|
||||
}
|
||||
if err != context.Canceled {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func binaryVersion(location string) (version.SemVer, error) {
|
||||
func binaryVersion(location string) (semver.Version, error) {
|
||||
out, err := exec.Command(location, "version").Output()
|
||||
if err != nil {
|
||||
return version.SemVer{}, err
|
||||
return semver.Version{}, err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(out))
|
||||
@ -194,13 +201,17 @@ func binaryVersion(location string) (version.SemVer, error) {
|
||||
line := scanner.Text()
|
||||
prefix := "Version: "
|
||||
if strings.HasPrefix(line, prefix) {
|
||||
return version.NewSemVer(line[len(prefix):])
|
||||
line = line[len(prefix):]
|
||||
if strings.HasPrefix(line, "v") {
|
||||
line = line[1:]
|
||||
}
|
||||
return semver.Make(line)
|
||||
}
|
||||
}
|
||||
return version.SemVer{}, errs.New("unable to determine binary version")
|
||||
return semver.Version{}, errs.New("unable to determine binary version")
|
||||
}
|
||||
|
||||
func suggestedVersion() (ver version.SemVer, url string, err error) {
|
||||
func suggestedVersion() (ver semver.Version, url string, err error) {
|
||||
resp, err := http.Get(versionURL)
|
||||
if err != nil {
|
||||
return ver, url, err
|
||||
@ -219,7 +230,7 @@ func suggestedVersion() (ver version.SemVer, url string, err error) {
|
||||
}
|
||||
|
||||
suggestedVersion := response.Processes.Storagenode.Suggested
|
||||
ver, err = version.NewSemVer(suggestedVersion.Version)
|
||||
ver, err = semver.Make(suggestedVersion.Version)
|
||||
if err != nil {
|
||||
return ver, url, err
|
||||
}
|
||||
|
87
cmd/storagenode-updater/main_test.go
Normal file
87
cmd/storagenode-updater/main_test.go
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package main_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"storj.io/storj/internal/testcontext"
|
||||
"storj.io/storj/versioncontrol"
|
||||
)
|
||||
|
||||
func TestAutoUpdater(t *testing.T) {
|
||||
ctx := testcontext.New(t)
|
||||
defer ctx.Cleanup()
|
||||
|
||||
content, err := ioutil.ReadFile("testdata/fake-storagenode")
|
||||
require.NoError(t, err)
|
||||
|
||||
tmpExec := ctx.File("storagenode")
|
||||
err = ioutil.WriteFile(tmpExec, content, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
var mux http.ServeMux
|
||||
content, err = ioutil.ReadFile("testdata/fake-storagenode.zip")
|
||||
require.NoError(t, err)
|
||||
mux.HandleFunc("/download", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := w.Write(content)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
|
||||
ts := httptest.NewServer(&mux)
|
||||
defer ts.Close()
|
||||
|
||||
config := &versioncontrol.Config{
|
||||
Address: "127.0.0.1:0",
|
||||
Versions: versioncontrol.ServiceVersions{
|
||||
Bootstrap: "v0.0.1",
|
||||
Satellite: "v0.0.1",
|
||||
Storagenode: "v0.0.1",
|
||||
Uplink: "v0.0.1",
|
||||
Gateway: "v0.0.1",
|
||||
Identity: "v0.0.1",
|
||||
},
|
||||
Binary: versioncontrol.Versions{
|
||||
Storagenode: versioncontrol.Binary{
|
||||
Suggested: versioncontrol.Version{
|
||||
Version: "0.19.5",
|
||||
URL: ts.URL + "/download",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
peer, err := versioncontrol.New(zaptest.NewLogger(t), config)
|
||||
require.NoError(t, err)
|
||||
ctx.Go(func() error {
|
||||
return peer.Run(ctx)
|
||||
})
|
||||
defer ctx.Check(peer.Close)
|
||||
|
||||
args := make([]string, 0)
|
||||
args = append(args, "run")
|
||||
args = append(args, "main.go")
|
||||
args = append(args, "run")
|
||||
args = append(args, "--version-url")
|
||||
args = append(args, "http://"+peer.Addr())
|
||||
args = append(args, "--binary-location")
|
||||
args = append(args, tmpExec)
|
||||
args = append(args, "--interval")
|
||||
args = append(args, "0")
|
||||
|
||||
out, err := exec.Command("go", args...).CombinedOutput()
|
||||
assert.NoError(t, err)
|
||||
|
||||
result := string(out)
|
||||
if !assert.Contains(t, result, "restarted successfully") {
|
||||
t.Log(result)
|
||||
}
|
||||
}
|
2
cmd/storagenode-updater/testdata/fake-storagenode
vendored
Executable file
2
cmd/storagenode-updater/testdata/fake-storagenode
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
echo "Version: v0.19.0"
|
BIN
cmd/storagenode-updater/testdata/fake-storagenode.zip
vendored
Normal file
BIN
cmd/storagenode-updater/testdata/fake-storagenode.zip
vendored
Normal file
Binary file not shown.
1
go.mod
1
go.mod
@ -25,6 +25,7 @@ require (
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 // indirect
|
||||
github.com/alicebob/miniredis v0.0.0-20180911162847-3657542c8629
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/cheggaaa/pb v1.0.5-0.20160713104425-73ae1d68fe0b // indirect
|
||||
github.com/cheggaaa/pb/v3 v3.0.1
|
||||
|
2
go.sum
2
go.sum
@ -31,6 +31,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
|
Loading…
Reference in New Issue
Block a user