github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/cmd/version.go (about)

     1  package cmd
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/spf13/cobra"
     9  	"google.golang.org/grpc/codes"
    10  	"google.golang.org/grpc/status"
    11  	empty "google.golang.org/protobuf/types/known/emptypb"
    12  
    13  	"github.com/telepresenceio/telepresence/rpc/v2/common"
    14  	daemonRpc "github.com/telepresenceio/telepresence/rpc/v2/daemon"
    15  	"github.com/telepresenceio/telepresence/rpc/v2/manager"
    16  	"github.com/telepresenceio/telepresence/v2/pkg/client"
    17  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/ann"
    18  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/connect"
    19  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/daemon"
    20  	"github.com/telepresenceio/telepresence/v2/pkg/client/socket"
    21  	"github.com/telepresenceio/telepresence/v2/pkg/ioutil"
    22  )
    23  
    24  func version() *cobra.Command {
    25  	return &cobra.Command{
    26  		Use:  "version",
    27  		Args: cobra.NoArgs,
    28  
    29  		Short: "Show version",
    30  		RunE:  printVersion,
    31  		Annotations: map[string]string{
    32  			ann.UserDaemon:        ann.Optional,
    33  			ann.UpdateCheckFormat: ann.Tel2,
    34  		},
    35  	}
    36  }
    37  
    38  func addDaemonVersions(ctx context.Context, kvf *ioutil.KeyValueFormatter) {
    39  	remote := false
    40  	userD := daemon.GetUserClient(ctx)
    41  	if userD != nil {
    42  		remote = userD.Containerized()
    43  	}
    44  
    45  	if !remote {
    46  		version, err := daemonVersion(ctx)
    47  		switch {
    48  		case err == nil:
    49  			kvf.Add(version.Name, version.Version)
    50  		case err == connect.ErrNoRootDaemon:
    51  			kvf.Add("Root Daemon", "not running")
    52  		default:
    53  			kvf.Add("Root Daemon", fmt.Sprintf("error: %v", err))
    54  		}
    55  	}
    56  
    57  	if userD != nil {
    58  		vi, err := userD.Version(ctx, &empty.Empty{})
    59  		if err == nil {
    60  			kvf.Add(vi.Name, vi.Version)
    61  			vi, err = managerVersion(ctx)
    62  			switch {
    63  			case err == nil:
    64  				kvf.Add(vi.Name, vi.Version)
    65  				af, err := trafficAgentFQN(ctx)
    66  				switch status.Code(err) {
    67  				case codes.OK:
    68  					kvf.Add("Traffic Agent", af.FQN)
    69  				case codes.Unimplemented:
    70  					kvf.Add("Traffic Agent", "not reported by traffic-manager")
    71  				case codes.Unavailable:
    72  					kvf.Add("Traffic Agent", "not currently available")
    73  				default:
    74  					kvf.Add("Traffic Agent", fmt.Sprintf("error: %v", err))
    75  				}
    76  			case status.Code(err) == codes.Unavailable:
    77  				kvf.Add("Traffic Manager", "not connected")
    78  			default:
    79  				kvf.Add("Traffic Manager", fmt.Sprintf("error: %v", err))
    80  			}
    81  		} else {
    82  			kvf.Add("User Daemon", fmt.Sprintf("error: %v", err))
    83  		}
    84  	} else {
    85  		kvf.Add("User Daemon", "not running")
    86  	}
    87  }
    88  
    89  func printVersion(cmd *cobra.Command, _ []string) error {
    90  	kvf := ioutil.DefaultKeyValueFormatter()
    91  	kvf.Add(client.DisplayName, client.Version())
    92  
    93  	var mdErr daemon.MultipleDaemonsError
    94  	err := connect.InitCommand(cmd)
    95  	if err != nil {
    96  		if !errors.As(err, &mdErr) {
    97  			return err
    98  		}
    99  	}
   100  	ctx := cmd.Context()
   101  
   102  	if len(mdErr) > 0 {
   103  		for _, info := range mdErr {
   104  			subKvf := &ioutil.KeyValueFormatter{
   105  				Indent:    kvf.Indent,
   106  				Separator: kvf.Separator,
   107  			}
   108  			ud, err := connect.ExistingDaemon(ctx, info)
   109  			if err != nil {
   110  				subKvf.Add("User Daemon", fmt.Sprintf("error: %v", err))
   111  			}
   112  			addDaemonVersions(daemon.WithUserClient(ctx, ud), subKvf)
   113  			kvf.Add("Connection "+ud.DaemonID.Name, "\n"+subKvf.String())
   114  			ud.Conn.Close()
   115  		}
   116  	} else {
   117  		addDaemonVersions(ctx, kvf)
   118  	}
   119  
   120  	kvf.Println(cmd.OutOrStdout())
   121  	return nil
   122  }
   123  
   124  func daemonVersion(ctx context.Context) (*common.VersionInfo, error) {
   125  	if conn, err := socket.Dial(ctx, socket.RootDaemonPath(ctx)); err == nil {
   126  		defer conn.Close()
   127  		return daemonRpc.NewDaemonClient(conn).Version(ctx, &empty.Empty{})
   128  	}
   129  	return nil, connect.ErrNoRootDaemon
   130  }
   131  
   132  func managerVersion(ctx context.Context) (*common.VersionInfo, error) {
   133  	if userD := daemon.GetUserClient(ctx); userD != nil {
   134  		return userD.TrafficManagerVersion(ctx, &empty.Empty{})
   135  	}
   136  	return nil, connect.ErrNoUserDaemon
   137  }
   138  
   139  func trafficAgentFQN(ctx context.Context) (*manager.AgentImageFQN, error) {
   140  	if userD := daemon.GetUserClient(ctx); userD != nil {
   141  		return userD.AgentImageFQN(ctx, &empty.Empty{})
   142  	}
   143  	return nil, connect.ErrNoUserDaemon
   144  }