{versioncontrol,internal/version,cmd/*}: refactor version control (#3253)

This commit is contained in:
Bryan White 2019-10-20 09:56:23 +02:00 committed by GitHub
parent f65801309c
commit 243ba1cb17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 397 additions and 184 deletions

View File

@ -11,7 +11,7 @@ import (
"os"
"path/filepath"
base58 "github.com/jbenet/go-base58"
"github.com/jbenet/go-base58"
"github.com/minio/cli"
minio "github.com/minio/minio/cmd"
"github.com/spf13/cobra"
@ -21,6 +21,7 @@ import (
"storj.io/storj/cmd/internal/wizard"
"storj.io/storj/internal/fpath"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
libuplink "storj.io/storj/lib/uplink"
"storj.io/storj/pkg/cfgstruct"
"storj.io/storj/pkg/miniogw"
@ -38,7 +39,7 @@ type GatewayFlags struct {
uplink.Config
Version version.Config
Version checker.Config
}
var (
@ -140,7 +141,7 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
zap.S().Warn("Failed to initialize telemetry batcher: ", err)
}
err = version.CheckProcessVersion(ctx, zap.L(), runCfg.Version, version.Build, "Gateway")
err = checker.CheckProcessVersion(ctx, zap.L(), runCfg.Version, version.Build, "Gateway")
if err != nil {
return err
}

View File

@ -17,6 +17,7 @@ import (
"storj.io/storj/certificate/certificateclient"
"storj.io/storj/internal/fpath"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/cfgstruct"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/peertls/extensions"
@ -63,7 +64,7 @@ var (
// TODO: ideally the default is the latest version; can't interpolate struct tags
IdentityVersion uint `default:"0" help:"identity version to use when creating an identity or CA"`
Version version.Config
Version checker.Config
}
identityDir, configDir string
@ -90,7 +91,7 @@ func serviceDirectory(serviceName string) string {
func cmdNewService(cmd *cobra.Command, args []string) error {
ctx, _ := process.Ctx(cmd)
err := version.CheckProcessVersion(ctx, zap.L(), config.Version, version.Build, "Identity")
err := checker.CheckProcessVersion(ctx, zap.L(), config.Version, version.Build, "Identity")
if err != nil {
return err
}
@ -152,7 +153,7 @@ func cmdNewService(cmd *cobra.Command, args []string) error {
func cmdAuthorize(cmd *cobra.Command, args []string) (err error) {
ctx, _ := process.Ctx(cmd)
err = version.CheckProcessVersion(ctx, zap.L(), config.Version, version.Build, "Identity")
err = checker.CheckProcessVersion(ctx, zap.L(), config.Version, version.Build, "Identity")
if err != nil {
return err
}

View File

@ -8,7 +8,6 @@ import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
@ -29,7 +28,7 @@ import (
"github.com/zeebo/errs"
"storj.io/storj/internal/sync2"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
)
var (
@ -56,7 +55,7 @@ var (
interval string
versionURL string
binaryLocation string
snServiceName string
serviceName string
logPath string
)
@ -67,7 +66,7 @@ func init() {
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")
runCmd.Flags().StringVar(&snServiceName, "service-name", "storagenode", "storage node OS service name")
runCmd.Flags().StringVar(&serviceName, "service-name", "storagenode", "storage node OS service name")
runCmd.Flags().StringVar(&logPath, "log", "", "path to log file, if empty standard output will be used")
}
@ -97,74 +96,6 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
cancel()
}()
update := func(ctx context.Context) (err error) {
currentVersion, err := binaryVersion(binaryLocation)
if err != nil {
return err
}
log.Println("downloading versions from", versionURL)
suggestedVersion, downloadURL, err := suggestedVersion()
if err != nil {
return err
}
downloadURL = strings.Replace(downloadURL, "{os}", runtime.GOOS, 1)
downloadURL = strings.Replace(downloadURL, "{arch}", runtime.GOARCH, 1)
if currentVersion.Compare(suggestedVersion) < 0 {
tempArchive, err := ioutil.TempFile(os.TempDir(), "storagenode")
if err != nil {
return errs.New("cannot create temporary archive: %v", err)
}
defer func() { err = errs.Combine(err, os.Remove(tempArchive.Name())) }()
log.Println("start downloading", downloadURL, "to", tempArchive.Name())
err = downloadArchive(ctx, tempArchive, downloadURL)
if err != nil {
return err
}
log.Println("finished downloading", downloadURL, "to", tempArchive.Name())
extension := filepath.Ext(binaryLocation)
if extension != "" {
extension = "." + extension
}
dir := filepath.Dir(binaryLocation)
backupExec := filepath.Join(dir, "storagenode.old."+currentVersion.String()+extension)
if err = os.Rename(binaryLocation, backupExec); err != nil {
return err
}
err = unpackBinary(ctx, tempArchive.Name(), binaryLocation)
if err != nil {
return err
}
downloadedVersion, err := binaryVersion(binaryLocation)
if err != nil {
return err
}
if suggestedVersion.Compare(downloadedVersion) != 0 {
return errs.New("invalid version downloaded: wants %s got %s", suggestedVersion.String(), downloadedVersion.String())
}
log.Println("restarting service", snServiceName)
err = restartSNService(snServiceName)
if err != nil {
return errs.New("unable to restart service: %v", err)
}
log.Println("service", snServiceName, "restarted successfully")
// TODO remove old binary ??
} else {
log.Println("storage node version is up to date")
}
return nil
}
loopInterval, err := time.ParseDuration(interval)
if err != nil {
return errs.New("unable to parse interval parameter: %v", err)
@ -190,6 +121,90 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
return nil
}
// TODO: refactor
func update(ctx context.Context) (err error) {
// TODO: use config struct binding
clientConfig := checker.ClientConfig{
ServerAddress: versionURL,
RequestTimeout: time.Minute,
}
client := checker.New(clientConfig)
currentVersion, err := binaryVersion(binaryLocation)
if err != nil {
return err
}
log.Println("downloading versions from", versionURL)
process, err := client.Process(ctx, serviceName)
if err != nil {
return err
}
downloadURL := process.Suggested.URL
downloadURL = strings.Replace(downloadURL, "{os}", runtime.GOOS, 1)
downloadURL = strings.Replace(downloadURL, "{arch}", runtime.GOARCH, 1)
// TODO: check rollout
suggestedVersion, err := semver.Parse(process.Suggested.Version)
if err != nil {
return checker.Error.Wrap(err)
}
if currentVersion.Compare(suggestedVersion) < 0 {
tempArchive, err := ioutil.TempFile(os.TempDir(), serviceName)
if err != nil {
return errs.New("cannot create temporary archive: %v", err)
}
defer func() { err = errs.Combine(err, os.Remove(tempArchive.Name())) }()
log.Println("start downloading", downloadURL, "to", tempArchive.Name())
err = downloadArchive(ctx, tempArchive, downloadURL)
if err != nil {
return err
}
log.Println("finished downloading", downloadURL, "to", tempArchive.Name())
extension := filepath.Ext(binaryLocation)
if extension != "" {
extension = "." + extension
}
dir := filepath.Dir(binaryLocation)
backupExec := filepath.Join(dir, serviceName+".old."+currentVersion.String()+extension)
if err = os.Rename(binaryLocation, backupExec); err != nil {
return err
}
err = unpackBinary(ctx, tempArchive.Name(), binaryLocation)
if err != nil {
return err
}
downloadedVersion, err := binaryVersion(binaryLocation)
if err != nil {
return err
}
if suggestedVersion.Compare(downloadedVersion) != 0 {
return errs.New("invalid version downloaded: wants %s got %s", suggestedVersion.String(), downloadedVersion.String())
}
log.Println("restarting service", serviceName)
err = restartSNService(serviceName)
if err != nil {
return errs.New("unable to restart service: %v", err)
}
log.Println("service", serviceName, "restarted successfully")
// TODO remove old binary ??
} else {
log.Printf("%s version is up to date\n", serviceName)
}
return nil
}
func binaryVersion(location string) (semver.Version, error) {
out, err := exec.Command(location, "version").Output()
if err != nil {
@ -211,32 +226,6 @@ func binaryVersion(location string) (semver.Version, error) {
return semver.Version{}, errs.New("unable to determine binary version")
}
func suggestedVersion() (ver semver.Version, url string, err error) {
resp, err := http.Get(versionURL)
if err != nil {
return ver, url, err
}
defer func() { err = errs.Combine(err, resp.Body.Close()) }()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ver, url, err
}
var response version.AllowedVersions
err = json.Unmarshal(body, &response)
if err != nil {
return ver, url, err
}
suggestedVersion := response.Processes.Storagenode.Suggested
ver, err = semver.Make(suggestedVersion.Version)
if err != nil {
return ver, url, err
}
return ver, suggestedVersion.URL, nil
}
func downloadArchive(ctx context.Context, file io.Writer, url string) (err error) {
resp, err := http.Get(url)
if err != nil {

View File

@ -17,6 +17,7 @@ import (
"storj.io/storj/internal/fpath"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
libuplink "storj.io/storj/lib/uplink"
"storj.io/storj/pkg/cfgstruct"
"storj.io/storj/pkg/process"
@ -29,7 +30,7 @@ type UplinkFlags struct {
NonInteractive bool `help:"disable interactive mode" default:"false" setup:"true"`
uplink.Config
Version version.Config
Version checker.Config
}
var (
@ -86,7 +87,7 @@ func (cliCfg *UplinkFlags) NewUplink(ctx context.Context) (*libuplink.Uplink, er
// GetProject returns a *libuplink.Project for interacting with a specific project
func (cliCfg *UplinkFlags) GetProject(ctx context.Context) (_ *libuplink.Project, err error) {
err = version.CheckProcessVersion(ctx, zap.L(), cliCfg.Version, version.Build, "Uplink")
err = checker.CheckProcessVersion(ctx, zap.L(), cliCfg.Version, version.Build, "Uplink")
if err != nil {
return nil, err
}

View File

@ -18,6 +18,7 @@ import (
"storj.io/storj/internal/errs2"
"storj.io/storj/internal/memory"
"storj.io/storj/internal/version"
vc_checker "storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/peertls/extensions"
"storj.io/storj/pkg/peertls/tlsopts"
@ -65,7 +66,7 @@ type SatelliteSystem struct {
Server *server.Server
Version *version.Service
Version *vc_checker.Service
Contact struct {
Service *contact.Service

View File

@ -10,6 +10,7 @@ import (
"time"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/versioncontrol"
)
@ -59,10 +60,12 @@ func (planet *Planet) NewVersionInfo() version.Info {
}
// NewVersionConfig returns the Version Config for this planet with tuned metrics.
func (planet *Planet) NewVersionConfig() version.Config {
return version.Config{
ServerAddress: fmt.Sprintf("http://%s/", planet.VersionControl.Addr()),
RequestTimeout: time.Second * 15,
func (planet *Planet) NewVersionConfig() checker.Config {
config := checker.Config{
CheckInterval: time.Minute * 5,
}
config.ServerAddress = fmt.Sprintf("http://%s/", planet.VersionControl.Addr())
config.RequestTimeout = time.Second * 15
return config
}

View File

@ -0,0 +1,124 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package checker
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
"reflect"
"strings"
"time"
"github.com/zeebo/errs"
"gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/internal/version"
)
var (
mon = monkit.Package()
// Error is the error class for version control client errors.
Error = errs.Class("version control client error")
)
// ClientConfig is the config struct for the version control client.
type ClientConfig struct {
ServerAddress string `help:"server address to check its version against" default:"https://version.storj.io"`
RequestTimeout time.Duration `help:"Request timeout for version checks" default:"0h1m0s"`
}
// Client defines helper methods for using version control server response data.
//
// architecture: Client
type Client struct {
config ClientConfig
}
// New constructs a new verson control server client.
func New(config ClientConfig) *Client {
return &Client{
config: config,
}
}
// All handles the HTTP request to gather the latest version information.
func (client *Client) All(ctx context.Context) (ver version.AllowedVersions, err error) {
defer mon.Task()(&ctx)(&err)
// Tune Client to have a custom Timeout (reduces hanging software)
httpClient := http.Client{
Timeout: client.config.RequestTimeout,
}
// New Request that used the passed in context
req, err := http.NewRequestWithContext(ctx, http.MethodGet, client.config.ServerAddress, nil)
if err != nil {
return version.AllowedVersions{}, Error.Wrap(err)
}
resp, err := httpClient.Do(req)
if err != nil {
return version.AllowedVersions{}, Error.Wrap(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return version.AllowedVersions{}, Error.Wrap(err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return version.AllowedVersions{}, Error.New("non-success http status code: %d; body: %s\n", resp.StatusCode, body)
}
err = json.NewDecoder(bytes.NewReader(body)).Decode(&ver)
return ver, Error.Wrap(err)
}
// OldMinimum returns the version with the given name at the root-level of the version control response.
// NB: This will be deprecated eventually in favor of what is currently the `processes` root-level object.
func (client *Client) OldMinimum(ctx context.Context, serviceName string) (ver version.SemVer, err error) {
defer mon.Task()(&ctx, serviceName)(&err)
versions, err := client.All(ctx)
if err != nil {
return version.SemVer{}, err
}
r := reflect.ValueOf(&versions)
f := reflect.Indirect(r).FieldByName(serviceName).Interface()
result, ok := f.(version.SemVer)
if !ok {
return version.SemVer{}, Error.New("invalid process name: %s", serviceName)
}
return result, nil
}
// Process returns the version info for the named process from the version control server response.
func (client *Client) Process(ctx context.Context, processName string) (process version.Process, err error) {
defer mon.Task()(&ctx, processName)(&err)
versions, err := client.All(ctx)
if err != nil {
return version.Process{}, err
}
processesValue := reflect.ValueOf(versions.Processes)
field := processesValue.FieldByName(strings.Title(processName))
processNameErr := Error.New("invalid process name: %s\n", processName)
if field == (reflect.Value{}) {
return version.Process{}, processNameErr
}
process, ok := field.Interface().(version.Process)
if !ok {
return version.Process{}, processNameErr
}
return process, nil
}

View File

@ -0,0 +1,127 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package checker_test
import (
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
"storj.io/storj/internal/testcontext"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/versioncontrol"
)
func TestClient_All(t *testing.T) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
peer := newTestPeer(t, ctx)
defer ctx.Check(peer.Close)
clientConfig := checker.ClientConfig{
ServerAddress: "http://" + peer.Addr(),
RequestTimeout: 0,
}
client := checker.New(clientConfig)
versions, err := client.All(ctx)
require.NoError(t, err)
processesValue := reflect.ValueOf(&versions.Processes)
fieldCount := reflect.Indirect(processesValue).NumField()
for i := 0; i < fieldCount; i++ {
field := reflect.Indirect(processesValue).Field(i)
versionString := fmt.Sprintf("v%d.%d.%d", i+1, i+2, i+3)
process, ok := field.Interface().(version.Process)
require.True(t, ok)
require.Equal(t, versionString, process.Minimum.Version)
require.Equal(t, versionString, process.Suggested.Version)
}
}
func TestClient_Process(t *testing.T) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
peer := newTestPeer(t, ctx)
defer ctx.Check(peer.Close)
clientConfig := checker.ClientConfig{
ServerAddress: "http://" + peer.Addr(),
RequestTimeout: 0,
}
client := checker.New(clientConfig)
processesType := reflect.TypeOf(version.Processes{})
fieldCount := processesType.NumField()
for i := 0; i < fieldCount; i++ {
field := processesType.Field(i)
expectedVersionStr := fmt.Sprintf("v%d.%d.%d", i+1, i+2, i+3)
process, err := client.Process(ctx, field.Name)
require.NoError(t, err)
require.Equal(t, expectedVersionStr, process.Minimum.Version)
require.Equal(t, expectedVersionStr, process.Suggested.Version)
}
}
func newTestPeer(t *testing.T, ctx *testcontext.Context) *versioncontrol.Peer {
t.Helper()
testVersions := newTestVersions(t)
serverConfig := &versioncontrol.Config{
Address: "127.0.0.1:0",
Versions: versioncontrol.ServiceVersions{
Satellite: "v0.0.1",
Storagenode: "v0.0.1",
Uplink: "v0.0.1",
Gateway: "v0.0.1",
Identity: "v0.0.1",
},
Binary: testVersions,
}
peer, err := versioncontrol.New(zaptest.NewLogger(t), serverConfig)
require.NoError(t, err)
ctx.Go(func() error {
return peer.Run(ctx)
})
return peer
}
func newTestVersions(t *testing.T) (versions versioncontrol.Versions) {
t.Helper()
versionsValue := reflect.ValueOf(&versions)
versionsElem := versionsValue.Elem()
fieldCount := versionsElem.NumField()
for i := 0; i < fieldCount; i++ {
field := versionsElem.Field(i)
versionString := fmt.Sprintf("v%d.%d.%d", i+1, i+2, i+3)
binary := versioncontrol.Binary{
Minimum: versioncontrol.Version{
Version: versionString,
},
Suggested: versioncontrol.Version{
Version: versionString,
},
}
field.Set(reflect.ValueOf(binary))
}
return versions
}

View File

@ -1,26 +1,25 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package version
package checker
import (
"context"
"encoding/json"
"fmt"
"net/http"
"reflect"
"sync"
"time"
"go.uber.org/zap"
"storj.io/storj/internal/sync2"
"storj.io/storj/internal/version"
)
// Config contains the necessary Information to check the Software Version
type Config struct {
ServerAddress string `help:"server address to check its version against" default:"https://version.storj.io"`
RequestTimeout time.Duration `help:"Request timeout for version checks" default:"0h1m0s"`
ClientConfig
CheckInterval time.Duration `help:"Interval to check the version" default:"0h15m0s"`
}
@ -30,7 +29,8 @@ type Config struct {
type Service struct {
log *zap.Logger
config Config
info Info
client *Client
info version.Info
service string
Loop *sync2.Cycle
@ -41,10 +41,11 @@ type Service struct {
}
// NewService creates a Version Check Client with default configuration
func NewService(log *zap.Logger, config Config, info Info, service string) (client *Service) {
func NewService(log *zap.Logger, config Config, info version.Info, service string) (client *Service) {
return &Service{
log: log,
config: config,
client: New(config.ClientConfig),
info: info,
service: service,
Loop: sync2.NewCycle(config.CheckInterval),
@ -63,7 +64,7 @@ func (srv *Service) CheckVersion(ctx context.Context) (err error) {
// CheckProcessVersion is not meant to be used for peers but is meant to be
// used for other utilities
func CheckProcessVersion(ctx context.Context, log *zap.Logger, config Config, info Info, service string) (err error) {
func CheckProcessVersion(ctx context.Context, log *zap.Logger, config Config, info version.Info, service string) (err error) {
defer mon.Task()(&ctx)(&err)
return NewService(log, config, info, service).CheckVersion(ctx)
}
@ -106,14 +107,13 @@ func (srv *Service) checkVersion(ctx context.Context) (allowed bool) {
return true
}
accepted, err := srv.queryVersionFromControlServer(ctx)
minimum, err := srv.client.OldMinimum(ctx, srv.service)
if err != nil {
// Log about the error, but dont crash the service and allow further operation
srv.log.Sugar().Errorf("Failed to do periodic version check: %s", err.Error())
return true
}
minimum := getFieldString(&accepted, srv.service)
srv.log.Sugar().Debugf("allowed minimum version from control server is: %s", minimum.String())
if minimum.String() == "" {
@ -128,38 +128,6 @@ func (srv *Service) checkVersion(ctx context.Context) (allowed bool) {
return false
}
// isAcceptedVersion compares and checks if the passed version is greater/equal than the minimum required version
func isAcceptedVersion(test SemVer, target SemVer) bool {
return test.Major > target.Major || (test.Major == target.Major && (test.Minor > target.Minor || (test.Minor == target.Minor && test.Patch >= target.Patch)))
}
// QueryVersionFromControlServer handles the HTTP request to gather the allowed and latest version information
func (srv *Service) queryVersionFromControlServer(ctx context.Context) (ver AllowedVersions, err error) {
defer mon.Task()(&ctx)(&err)
// Tune Client to have a custom Timeout (reduces hanging software)
client := http.Client{
Timeout: srv.config.RequestTimeout,
}
// New Request that used the passed in context
req, err := http.NewRequest("GET", srv.config.ServerAddress, nil)
if err != nil {
return AllowedVersions{}, err
}
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
return AllowedVersions{}, err
}
defer func() { _ = resp.Body.Close() }()
err = json.NewDecoder(resp.Body).Decode(&ver)
return ver, err
}
// DebugHandler implements version info endpoint.
type DebugHandler struct {
log *zap.Logger
@ -172,7 +140,7 @@ func NewDebugHandler(log *zap.Logger) *DebugHandler {
// ServeHTTP returns a json representation of the current version information for the binary.
func (server *DebugHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
j, err := Build.Marshal()
j, err := version.Build.Marshal()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
@ -187,12 +155,7 @@ func (server *DebugHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
func getFieldString(array *AllowedVersions, field string) SemVer {
r := reflect.ValueOf(array)
f := reflect.Indirect(r).FieldByName(field).Interface()
result, ok := f.(SemVer)
if ok {
return result
}
return SemVer{}
// isAcceptedVersion compares and checks if the passed version is greater/equal than the minimum required version
func isAcceptedVersion(test version.SemVer, target version.SemVer) bool {
return test.Major > target.Major || (test.Major == target.Major && (test.Minor > target.Minor || (test.Minor == target.Minor && test.Patch >= target.Patch)))
}

View File

@ -13,7 +13,6 @@ import (
"time"
"github.com/zeebo/errs"
"gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/pb"
)
@ -26,8 +25,6 @@ const (
)
var (
mon = monkit.Package()
// VerError is the error class for version-related errors.
VerError = errs.Class("version error")

View File

@ -12,10 +12,10 @@ import (
"strings"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
"gopkg.in/spacemonkeygo/monkit.v2"
"gopkg.in/spacemonkeygo/monkit.v2/present"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
)
var (
@ -36,7 +36,7 @@ func initDebug(logger *zap.Logger, r *monkit.Registry) (err error) {
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
mux.Handle("/version/", http.StripPrefix("/version", version.NewDebugHandler(logger.Named("version"))))
mux.Handle("/version/", http.StripPrefix("/version", checker.NewDebugHandler(logger.Named("version"))))
mux.Handle("/mon/", http.StripPrefix("/mon", present.HTTP(r)))
mux.HandleFunc("/metrics", prometheus)
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {

View File

@ -17,6 +17,7 @@ import (
"storj.io/storj/internal/post"
"storj.io/storj/internal/post/oauth2"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/auth/grpcauth"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/pb"
@ -55,7 +56,7 @@ type API struct {
Dialer rpc.Dialer
Server *server.Server
Version *version.Service
Version *checker.Service
Contact struct {
Service *contact.Service
@ -139,7 +140,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB, pointerDB metai
peer.Log.Sugar().Debugf("Binary Version: %s with CommitHash %s, built at %s as Release %v",
versionInfo.Version.String(), versionInfo.CommitHash, versionInfo.Timestamp.String(), versionInfo.Release)
}
peer.Version = version.NewService(log.Named("version"), config.Version, versionInfo, "Satellite")
peer.Version = checker.NewService(log.Named("version"), config.Version, versionInfo, "Satellite")
}
{ // setup listener and server

View File

@ -18,6 +18,7 @@ import (
"storj.io/storj/internal/post"
"storj.io/storj/internal/post/oauth2"
"storj.io/storj/internal/version"
version_checker "storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/auth/grpcauth"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/pb"
@ -134,7 +135,7 @@ type Config struct {
Marketing marketingweb.Config
Version version.Config
Version version_checker.Config
GracefulExit gracefulexit.Config
@ -154,7 +155,7 @@ type Peer struct {
Server *server.Server
Version *version.Service
Version *version_checker.Service
// services and endpoints
Contact struct {
@ -264,7 +265,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, pointerDB metainfo
peer.Log.Sugar().Debugf("Binary Version: %s with CommitHash %s, built at %s as Release %v",
versionInfo.Version.String(), versionInfo.CommitHash, versionInfo.Timestamp.String(), versionInfo.Release)
}
peer.Version = version.NewService(log.Named("version"), config.Version, versionInfo, "Satellite")
peer.Version = version_checker.NewService(log.Named("version"), config.Version, versionInfo, "Satellite")
}
{ // setup listener and server

View File

@ -14,6 +14,7 @@ import (
"storj.io/storj/internal/date"
"storj.io/storj/internal/memory"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/storj"
"storj.io/storj/storagenode/bandwidth"
"storj.io/storj/storagenode/contact"
@ -42,7 +43,7 @@ type Service struct {
pieceStore *pieces.Store
contact *contact.Service
version *version.Service
version *checker.Service
pingStats *contact.PingStats
allocatedBandwidth memory.Size
@ -54,7 +55,7 @@ type Service struct {
}
// NewService returns new instance of Service.
func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Store, version *version.Service,
func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Store, version *checker.Service,
allocatedBandwidth, allocatedDiskSpace memory.Size, walletAddress string, versionInfo version.Info, trust *trust.Pool,
reputationDB reputation.DB, storageUsageDB storageusage.DB, pingStats *contact.PingStats, contact *contact.Service) (*Service, error) {
if log == nil {

View File

@ -15,6 +15,7 @@ import (
"storj.io/storj/internal/errs2"
"storj.io/storj/internal/version"
"storj.io/storj/internal/version/checker"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/peertls/extensions"
@ -91,7 +92,7 @@ type Config struct {
Console consoleserver.Config
Version version.Config
Version checker.Config
Bandwidth bandwidth.Config
@ -116,7 +117,7 @@ type Peer struct {
Server *server.Server
Version *version.Service
Version *checker.Service
// services and endpoints
// TODO: similar grouping to satellite.Peer
@ -179,7 +180,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
peer.Log.Sugar().Debugf("Binary Version: %s with CommitHash %s, built at %s as Release %v",
versionInfo.Version.String(), versionInfo.CommitHash, versionInfo.Timestamp.String(), versionInfo.Release)
}
peer.Version = version.NewService(log.Named("version"), config.Version, versionInfo, "Storagenode")
peer.Version = checker.NewService(log.Named("version"), config.Version, versionInfo, "Storagenode")
}
{ // setup listener and server

View File

@ -78,6 +78,8 @@ type Rollout struct {
}
// Peer is the representation of a VersionControl Server.
//
// architecture: Peer
type Peer struct {
// core dependencies
Log *zap.Logger
@ -227,7 +229,7 @@ func (versions Versions) ValidateRollouts(log *zap.Logger) error {
value := reflect.ValueOf(versions)
fieldCount := value.NumField()
validationErrs := errs.Group{}
for i := 1; i < fieldCount; i++ {
for i := 0; i < fieldCount; i++ {
binary, ok := value.Field(i).Interface().(Binary)
if !ok {
log.Warn("non-binary field in versions config struct", zap.String("field name", value.Type().Field(i).Name))

View File

@ -93,10 +93,10 @@ func TestPeer_Run(t *testing.T) {
fieldCount := versionsType.NumField()
// test invalid rollout for each binary
for i := 1; i < fieldCount; i++ {
for i := 0; i < fieldCount; i++ {
versions := versioncontrol.Versions{}
versionsValue := reflect.ValueOf(&versions)
field := reflect.Indirect(versionsValue).Field(i)
field := versionsValue.Elem().Field(i)
binary := versioncontrol.Binary{
Rollout: versioncontrol.Rollout{
@ -127,7 +127,7 @@ func TestPeer_Run_error(t *testing.T) {
fieldCount := versionsType.NumField()
// test invalid rollout for each binary
for i := 1; i < fieldCount; i++ {
for i := 0; i < fieldCount; i++ {
versions := versioncontrol.Versions{}
versionsValue := reflect.ValueOf(&versions)
field := reflect.Indirect(versionsValue).Field(i)