Skip to content

Commit

Permalink
feat(cli): check that client and server versions match
Browse files Browse the repository at this point in the history
  • Loading branch information
philwinder committed Aug 9, 2022
1 parent aa4c562 commit 89c1832
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 0 deletions.
11 changes: 11 additions & 0 deletions cmd/bacalhau/docker_run.go
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/bacalhau/pkg/executor"
"github.com/filecoin-project/bacalhau/pkg/ipfs"
jobutils "github.com/filecoin-project/bacalhau/pkg/job"
"github.com/filecoin-project/bacalhau/pkg/version"

"github.com/filecoin-project/bacalhau/pkg/system"
"github.com/filecoin-project/bacalhau/pkg/verifier"
Expand Down Expand Up @@ -147,6 +148,16 @@ func init() { //nolint:gochecknoinits // Using init in cobra command is idomatic
var dockerCmd = &cobra.Command{
Use: "docker",
Short: "Run a docker job on the network (see run subcommand)",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Check that the server version is compatible with the client version
serverVersion, _ := getAPIClient().Version(cmd.Context()) // Ok if this fails, version validation will skip
if err := ensureValidVersion(cmd.Context(), version.Get(), serverVersion); err != nil {
err = fmt.Errorf("version mismatch, please upgrade your client: %s", err)
log.Err(err)
return err
}
return nil
},
}

var dockerRunCmd = &cobra.Command{
Expand Down
15 changes: 15 additions & 0 deletions cmd/bacalhau/run.go
@@ -1,6 +1,10 @@
package bacalhau

import (
"fmt"

"github.com/filecoin-project/bacalhau/pkg/version"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

Expand All @@ -12,4 +16,15 @@ func init() {
var runCmd = &cobra.Command{
Use: "run",
Short: "Run a job on the network (see subcommands for supported flavors)",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Check that the server version is compatible with the client version
serverVersion, _ := getAPIClient().Version(cmd.Context()) // Ok if this fails, version validation will skip
if err := ensureValidVersion(cmd.Context(), version.Get(), serverVersion); err != nil {
err = fmt.Errorf("version mismatch, please upgrade your client: %s", err)
log.Err(err)
return err
}

return nil
},
}
33 changes: 33 additions & 0 deletions cmd/bacalhau/utils.go
Expand Up @@ -2,11 +2,14 @@ package bacalhau

import (
"bytes"
"context"
"fmt"
"os"
"testing"
"time"

"github.com/Masterminds/semver"
"github.com/filecoin-project/bacalhau/pkg/executor"
"github.com/filecoin-project/bacalhau/pkg/ipfs"
"github.com/filecoin-project/bacalhau/pkg/publicapi"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -60,6 +63,36 @@ func getAPIClient() *publicapi.APIClient {
return publicapi.NewAPIClient(fmt.Sprintf("http://%s:%d", apiHost, apiPort))
}

// ensureValidVersion checks that the server version is the same or less than the client version
func ensureValidVersion(ctx context.Context, clientVersion *executor.VersionInfo, serverVersion *executor.VersionInfo) error {
if clientVersion == nil {
log.Warn().Msg("Unable to parse nil client version, skipping version check")
return nil
}
if clientVersion.GitVersion == "v0.0.0-xxxxxxx" {
log.Info().Msg("Development version, skipping version check")
return nil
}
if serverVersion == nil {
log.Warn().Msg("Unable to parse nil server version, skipping version check")
return nil
}
c, err := semver.NewVersion(clientVersion.GitVersion)
if err != nil {
log.Warn().Err(err).Msg("Unable to parse client version, skipping version check")
return nil
}
s, err := semver.NewVersion(serverVersion.GitVersion)
if err != nil {
log.Warn().Err(err).Msg("Unable to parse server version, skipping version check")
return nil
}
if s.GreaterThan(c) {
return fmt.Errorf("server version %s is newer than client version %s", serverVersion.GitVersion, clientVersion.GitVersion)
}
return nil
}

func ExecuteTestCobraCommand(t *testing.T, root *cobra.Command, args ...string) (
c *cobra.Command, output string, err error) { //nolint:unparam // use of t is valuable here
buf := new(bytes.Buffer)
Expand Down
53 changes: 53 additions & 0 deletions cmd/bacalhau/utils_test.go
@@ -1,9 +1,12 @@
package bacalhau

import (
"context"
"testing"

"github.com/filecoin-project/bacalhau/pkg/executor"
"github.com/filecoin-project/bacalhau/pkg/job"
"github.com/filecoin-project/bacalhau/pkg/system"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -54,6 +57,56 @@ func (suite *UtilsSuite) TestSafeRegex() {
}
}

func (suite *UtilsSuite) TestVersionCheck() {
system.InitConfigForTesting(suite.T())

// OK: Normal operation
err := ensureValidVersion(context.TODO(), &executor.VersionInfo{
GitVersion: "v1.2.3",
}, &executor.VersionInfo{
GitVersion: "v1.2.3",
})
require.NoError(suite.T(), err)

// OK: Newer CLI version
err = ensureValidVersion(context.TODO(), &executor.VersionInfo{
GitVersion: "v1.2.3",
}, &executor.VersionInfo{
GitVersion: "v1.2.0",
})
require.NoError(suite.T(), err)

// OK: invalid semver
err = ensureValidVersion(context.TODO(), &executor.VersionInfo{
GitVersion: "not-a-sem-ver",
}, &executor.VersionInfo{
GitVersion: "v1.2.0",
})
require.NoError(suite.T(), err)

// OK: nil semver
err = ensureValidVersion(context.TODO(), nil, &executor.VersionInfo{
GitVersion: "v1.2.0",
})
require.NoError(suite.T(), err)

// OK: development version
err = ensureValidVersion(context.TODO(), &executor.VersionInfo{
GitVersion: "v0.0.0-xxxxxxx",
}, &executor.VersionInfo{
GitVersion: "v1.2.0",
})
require.NoError(suite.T(), err)

// NOT OK: server is newer
err = ensureValidVersion(context.TODO(), &executor.VersionInfo{
GitVersion: "v1.2.3",
}, &executor.VersionInfo{
GitVersion: "v1.2.4",
})
require.Error(suite.T(), err)
}

// In order for 'go test' to run this suite, we need to create
// a normal test function and pass our suite to suite.Run
func TestUtilsSuite(t *testing.T) {
Expand Down

0 comments on commit 89c1832

Please sign in to comment.