feat: check client <> server version in some Talos commands
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 <andrey.smirnov@talos-systems.com>
This commit is contained in:
parent
446b0af58b
commit
cdd0f08bc5
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
@ -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 {
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
@ -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,
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
@ -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
|
||||
|
@ -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.
|
||||
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user