Skip to content

Commit

Permalink
feat: check client <> server version in some Talos commands
Browse files Browse the repository at this point in the history
Talos commands which are sensitive to resource API changes:

* `get`
* `edit`, `patch`
* `upgrade-k8s`

Commands with upcoming changes for actorID:

* `reboot`
* `reset`
* `shutdown`
* `upgrade`

Fixes #6101

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Aug 26, 2022
1 parent 446b0af commit cdd0f08
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cmd/talosctl/cmd/talos/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ or EDITOR environment variables, or fall back to 'vi' for Linux
or 'notepad' for Windows.`,
RunE: func(cmd *cobra.Command, args []string) error {
return WithClient(func(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

for _, node := range Nodes {
nodeCtx := client.WithNodes(ctx, node)
if err := helpers.ForEachResource(nodeCtx, c, nil, editFn(c), editCmdFlags.namespace, args...); err != nil {
Expand Down
4 changes: 4 additions & 0 deletions cmd/talosctl/cmd/talos/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ To get a list of all available resource definitions, issue 'talosctl get rd'`,
//nolint:gocyclo,cyclop
func getResources(args []string) func(ctx context.Context, c *client.Client) error {
return func(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

out, err := output.NewWriter(getCmdFlags.output)
if err != nil {
return err
Expand Down
4 changes: 4 additions & 0 deletions cmd/talosctl/cmd/talos/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ var patchCmd = &cobra.Command{
return err
}

if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

for _, node := range Nodes {
nodeCtx := client.WithNodes(ctx, node)
if err := helpers.ForEachResource(nodeCtx, c, nil, patchFn(c, patches), patchCmdFlags.namespace, args...); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions cmd/talosctl/cmd/talos/reboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/spf13/cobra"

"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/pkg/machinery/client"
)

Expand All @@ -36,6 +37,10 @@ var rebootCmd = &cobra.Command{
return fmt.Errorf("invalid reboot mode: %q", rebootCmdFlags.mode)
}

if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

if err := c.Reboot(ctx, opts...); err != nil {
return fmt.Errorf("error executing reboot: %s", err)
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/talosctl/cmd/talos/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/spf13/cobra"

"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/pkg/machinery/api/machine"
"github.com/talos-systems/talos/pkg/machinery/client"
)
Expand All @@ -28,6 +29,10 @@ var resetCmd = &cobra.Command{
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return WithClient(func(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

var systemPartitionsToWipe []*machine.ResetPartitionSpec

for _, label := range resetCmdFlags.systemLabelsToWipe {
Expand Down
5 changes: 5 additions & 0 deletions cmd/talosctl/cmd/talos/shutdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/spf13/cobra"

"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/pkg/machinery/client"
)

Expand All @@ -25,6 +26,10 @@ var shutdownCmd = &cobra.Command{
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return WithClient(func(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

if err := c.Shutdown(ctx, client.WithShutdownForce(shutdownCmdFlags.force)); err != nil {
return fmt.Errorf("error executing shutdown: %s", err)
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/talosctl/cmd/talos/upgrade-k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/spf13/cobra"

"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/pkg/cli"
"github.com/talos-systems/talos/pkg/cluster"
k8s "github.com/talos-systems/talos/pkg/cluster/kubernetes"
Expand Down Expand Up @@ -41,6 +42,10 @@ func init() {
}

func upgradeKubernetes(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

clientProvider := &cluster.ConfigClientProvider{
DefaultClient: c,
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/talosctl/cmd/talos/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/peer"

"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/pkg/cli"
"github.com/talos-systems/talos/pkg/machinery/client"
)
Expand Down Expand Up @@ -46,6 +47,10 @@ func init() {

func upgrade() error {
return WithClient(func(ctx context.Context, c *client.Client) error {
if err := helpers.ClientVersionCheck(ctx, c); err != nil {
return err
}

var remotePeer peer.Peer

// TODO: See if we can validate version and prevent starting upgrades to
Expand Down
37 changes: 37 additions & 0 deletions cmd/talosctl/pkg/talos/helpers/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ package helpers
import (
"context"
"fmt"
"os"
"strings"

hashiversion "github.com/hashicorp/go-version"
"google.golang.org/grpc/metadata"

"github.com/talos-systems/talos/pkg/machinery/api/common"
"github.com/talos-systems/talos/pkg/machinery/client"
"github.com/talos-systems/talos/pkg/version"
)

// FailIfMultiNodes checks if ctx contains multi-node request metadata.
Expand Down Expand Up @@ -40,3 +45,35 @@ func CheckErrors[T interface{ GetMetadata() *common.Metadata }](messages ...T) e

return err
}

// ClientVersionCheck verifies that client is not outdated vs. Talos version.
func ClientVersionCheck(ctx context.Context, c *client.Client) error {
// ignore the error, as we are only interested in the nodes which respond
serverVersions, _ := c.Version(ctx) //nolint:errcheck

clientVersion, err := hashiversion.NewVersion(version.NewVersion().Tag)
if err != nil {
return fmt.Errorf("error parsing client version: %w", err)
}

var warnings []string

for _, msg := range serverVersions.GetMessages() {
node := msg.GetMetadata().GetHostname()

serverVersion, err := hashiversion.NewVersion(msg.GetVersion().Tag)
if err != nil {
return fmt.Errorf("%s: error parsing server version: %w", node, err)
}

if serverVersion.Compare(clientVersion) > 0 {
warnings = append(warnings, fmt.Sprintf("%s: server version %s is newer than client version %s", node, serverVersion, clientVersion))
}
}

if warnings != nil {
fmt.Fprintf(os.Stderr, "WARNING: %s\n", strings.Join(warnings, ", "))
}

return nil
}
7 changes: 6 additions & 1 deletion pkg/cluster/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,12 +715,17 @@ func processes(ctx context.Context, options *BundleOptions) ([]byte, error) {
}

func summary(ctx context.Context, options *BundleOptions) ([]byte, error) {
var buf bytes.Buffer

fmt.Fprintln(&buf, "Client:")
version.WriteLongVersionFromExisting(&buf, version.NewVersion())

resp, err := options.Client.Version(ctx)
if err != nil {
return nil, err
}

var buf bytes.Buffer
fmt.Fprintln(&buf, "Server:")

for _, m := range resp.Messages {
version.WriteLongVersionFromExisting(&buf, m.Version)
Expand Down

0 comments on commit cdd0f08

Please sign in to comment.