autoupdater: use blang/semver (#3063)

This commit is contained in:
Michal Niewrzal 2019-09-20 07:22:40 -07:00 committed by Kaloyan Raev
parent 756d0ad2b5
commit 68d281db44
6 changed files with 125 additions and 22 deletions

View File

@ -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) {
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)
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)
}
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
}

View 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)
}
}

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "Version: v0.19.0"

Binary file not shown.

1
go.mod
View File

@ -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
View File

@ -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=