mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-19 05:31:14 +02:00
fix: provide peer remote address for 'NODE': as default in osctl
This change is pretty mechanical, just wrap every API so that remote peer address is used as default for `resp.Metadata.Hostname`. This makes `NODE:` non-empty in all the API calls. Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
parent
43e6703b8b
commit
fc52025490
@ -14,7 +14,9 @@ import (
|
||||
|
||||
criconstants "github.com/containerd/cri/pkg/constants"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
"github.com/talos-systems/talos/api/common"
|
||||
osapi "github.com/talos-systems/talos/api/os"
|
||||
@ -50,20 +52,24 @@ var containersCmd = &cobra.Command{
|
||||
md := metadata.New(make(map[string]string))
|
||||
md.Set("targets", target...)
|
||||
|
||||
reply, err := c.Containers(metadata.NewOutgoingContext(globalCtx, md), namespace, driver)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Containers(metadata.NewOutgoingContext(globalCtx, md), namespace, driver, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting process list: %s", err)
|
||||
}
|
||||
|
||||
containerRender(reply)
|
||||
containerRender(&remotePeer, reply)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func containerRender(reply *osapi.ContainersReply) {
|
||||
func containerRender(remotePeer *peer.Peer, reply *osapi.ContainersReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tNAMESPACE\tID\tIMAGE\tPID\tSTATUS")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, rep := range reply.Response {
|
||||
resp := rep
|
||||
sort.Slice(resp.Containers,
|
||||
@ -78,7 +84,7 @@ func containerRender(reply *osapi.ContainersReply) {
|
||||
display = "└─ " + display
|
||||
}
|
||||
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
networkapi "github.com/talos-systems/talos/api/network"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -29,22 +31,26 @@ var interfacesCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
setupClient(func(c *client.Client) {
|
||||
reply, err := c.Interfaces(globalCtx)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Interfaces(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting interfaces: %s", err)
|
||||
}
|
||||
|
||||
intersRender(reply)
|
||||
intersRender(&remotePeer, reply)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func intersRender(reply *networkapi.InterfacesReply) {
|
||||
func intersRender(remotePeer *peer.Peer, reply *networkapi.InterfacesReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tINDEX\tNAME\tMAC\tMTU\tADDRESS")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
osapi "github.com/talos-systems/talos/api/os"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -32,26 +34,30 @@ var memoryCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
setupClient(func(c *client.Client) {
|
||||
reply, err := c.Memory(globalCtx)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Memory(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting memory stats: %s", err)
|
||||
}
|
||||
|
||||
if verbose {
|
||||
verboseRender(reply)
|
||||
verboseRender(&remotePeer, reply)
|
||||
} else {
|
||||
briefRender(reply)
|
||||
briefRender(&remotePeer, reply)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func briefRender(reply *osapi.MemInfoReply) {
|
||||
func briefRender(remotePeer *peer.Peer, reply *osapi.MemInfoReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tTOTAL\tUSED\tFREE\tSHARED\tBUFFERS\tCACHE\tAVAILABLE")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
@ -73,13 +79,18 @@ func briefRender(reply *osapi.MemInfoReply) {
|
||||
helpers.Should(w.Flush())
|
||||
}
|
||||
|
||||
func verboseRender(reply *osapi.MemInfoReply) {
|
||||
func verboseRender(remotePeer *peer.Peer, reply *osapi.MemInfoReply) {
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
// Dump as /proc/meminfo
|
||||
for _, resp := range reply.Response {
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
fmt.Printf("%s: %s\n", "NODE", resp.Metadata.Hostname)
|
||||
node = resp.Metadata.Hostname
|
||||
}
|
||||
|
||||
fmt.Printf("%s: %s\n", "NODE", node)
|
||||
fmt.Printf("%s: %d %s\n", "MemTotal", resp.Meminfo.Memtotal, "kB")
|
||||
fmt.Printf("%s: %d %s\n", "MemFree", resp.Meminfo.Memfree, "kB")
|
||||
fmt.Printf("%s: %d %s\n", "MemAvailable", resp.Meminfo.Memavailable, "kB")
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
machineapi "github.com/talos-systems/talos/api/machine"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -31,15 +33,24 @@ var mountsCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
setupClient(func(c *client.Client) {
|
||||
mountsRender(c.Mounts(globalCtx))
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Mounts(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting interfaces: %s", err)
|
||||
}
|
||||
|
||||
mountsRender(&remotePeer, reply)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func mountsRender(reply *machineapi.MountsReply, err error) {
|
||||
func mountsRender(remotePeer *peer.Peer, reply *machineapi.MountsReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tFILESYSTEM\tSIZE(GB)\tUSED(GB)\tAVAILABLE(GB)\tPERCENT USED\tMOUNTED ON")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
for _, r := range resp.Stats {
|
||||
percentAvailable := 100.0 - 100.0*(float64(r.Available)/float64(r.Size))
|
||||
@ -48,7 +59,7 @@ func mountsRender(reply *machineapi.MountsReply, err error) {
|
||||
continue
|
||||
}
|
||||
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -20,7 +20,9 @@ import (
|
||||
"github.com/ryanuber/columnize"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
osapi "github.com/talos-systems/talos/api/os"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -182,7 +184,9 @@ var cpu = func(p1, p2 *osapi.Process) bool {
|
||||
|
||||
//nolint: gocyclo
|
||||
func processesOutput(ctx context.Context, c *client.Client) (output string, err error) {
|
||||
reply, err := c.Processes(ctx)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Processes(ctx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
// TODO: Figure out how to expose errors to client without messing
|
||||
// up display
|
||||
@ -191,6 +195,8 @@ func processesOutput(ctx context.Context, c *client.Client) (output string, err
|
||||
return output, nil
|
||||
}
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
s := []string{}
|
||||
|
||||
s = append(s, "NODE | PID | STATE | THREADS | CPU-TIME | VIRTMEM | RESMEM | COMMAND")
|
||||
@ -217,7 +223,7 @@ func processesOutput(ctx context.Context, c *client.Client) (output string, err
|
||||
args = p.Args
|
||||
}
|
||||
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -200,9 +200,15 @@ func remotePeer(ctx context.Context) (peerHost string) {
|
||||
|
||||
remote, ok := peer.FromContext(ctx)
|
||||
if ok {
|
||||
peerHost = remote.Addr.String()
|
||||
peerHost, _, _ = net.SplitHostPort(peerHost) //nolint: errcheck
|
||||
peerHost = addrFromPeer(remote)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func addrFromPeer(remote *peer.Peer) (peerHost string) {
|
||||
peerHost = remote.Addr.String()
|
||||
peerHost, _, _ = net.SplitHostPort(peerHost) //nolint: errcheck
|
||||
|
||||
return peerHost
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
networkapi "github.com/talos-systems/talos/api/network"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -29,22 +31,25 @@ var routesCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
setupClient(func(c *client.Client) {
|
||||
reply, err := c.Routes(globalCtx)
|
||||
var remotePeer peer.Peer
|
||||
reply, err := c.Routes(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting routes: %s", err)
|
||||
}
|
||||
|
||||
routesRender(reply)
|
||||
routesRender(&remotePeer, reply)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func routesRender(reply *networkapi.RoutesReply) {
|
||||
func routesRender(remotePeer *peer.Peer, reply *networkapi.RoutesReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tINTERFACE\tDESTINATION\tGATEWAY\tMETRIC")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
var node string
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
machineapi "github.com/talos-systems/talos/api/machine"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -63,7 +65,9 @@ With actions 'start', 'stop', 'restart', service state is updated respectively.`
|
||||
}
|
||||
|
||||
func serviceList(c *client.Client) {
|
||||
reply, err := c.ServiceList(globalCtx)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.ServiceList(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error listing services: %s", err)
|
||||
}
|
||||
@ -71,11 +75,13 @@ func serviceList(c *client.Client) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tSERVICE\tSTATE\tHEALTH\tLAST CHANGE\tLAST EVENT")
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
for _, s := range resp.Services {
|
||||
svc := serviceInfoWrapper{s}
|
||||
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
@ -89,49 +95,44 @@ func serviceList(c *client.Client) {
|
||||
}
|
||||
|
||||
func serviceInfo(c *client.Client, id string) {
|
||||
reply, err := c.ServiceInfo(globalCtx, id)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
services, err := c.ServiceInfo(globalCtx, id, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error listing services: %s", err)
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
|
||||
services := make([]*machineapi.ServiceInfo, 0, len(reply.Response))
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
for _, svc := range resp.Services {
|
||||
if svc.Id == id {
|
||||
services = append(services, svc)
|
||||
for _, s := range services {
|
||||
node := ""
|
||||
for _, s := range services {
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
}
|
||||
if s.Metadata != nil {
|
||||
node = s.Metadata.Hostname
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "NODE\t%s\n", node)
|
||||
fmt.Fprintf(w, "NODE\t%s\n", node)
|
||||
|
||||
svc := serviceInfoWrapper{s}
|
||||
fmt.Fprintf(w, "ID\t%s\n", svc.Id)
|
||||
fmt.Fprintf(w, "STATE\t%s\n", svc.State)
|
||||
fmt.Fprintf(w, "HEALTH\t%s\n", svc.HealthStatus())
|
||||
svc := serviceInfoWrapper{s.Service}
|
||||
fmt.Fprintf(w, "ID\t%s\n", svc.Id)
|
||||
fmt.Fprintf(w, "STATE\t%s\n", svc.State)
|
||||
fmt.Fprintf(w, "HEALTH\t%s\n", svc.HealthStatus())
|
||||
|
||||
if svc.Health.LastMessage != "" {
|
||||
fmt.Fprintf(w, "LAST HEALTH MESSAGE\t%s\n", svc.Health.LastMessage)
|
||||
}
|
||||
if svc.Health.LastMessage != "" {
|
||||
fmt.Fprintf(w, "LAST HEALTH MESSAGE\t%s\n", svc.Health.LastMessage)
|
||||
}
|
||||
|
||||
label := "EVENTS"
|
||||
label := "EVENTS"
|
||||
|
||||
for i := range svc.Events.Events {
|
||||
event := svc.Events.Events[len(svc.Events.Events)-1-i]
|
||||
for i := range svc.Events.Events {
|
||||
event := svc.Events.Events[len(svc.Events.Events)-1-i]
|
||||
|
||||
// nolint: errcheck
|
||||
ts, _ := ptypes.Timestamp(event.Ts)
|
||||
fmt.Fprintf(w, "%s\t[%s]: %s (%s ago)\n", label, event.State, event.Msg, time.Since(ts).Round(time.Second))
|
||||
label = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
// nolint: errcheck
|
||||
ts, _ := ptypes.Timestamp(event.Ts)
|
||||
fmt.Fprintf(w, "%s\t[%s]: %s (%s ago)\n", label, event.State, event.Msg, time.Since(ts).Round(time.Second))
|
||||
label = ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,16 +144,20 @@ func serviceInfo(c *client.Client, id string) {
|
||||
}
|
||||
|
||||
func serviceStart(c *client.Client, id string) {
|
||||
reply, err := c.ServiceStart(globalCtx, id)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.ServiceStart(globalCtx, id, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error starting service: %s", err)
|
||||
}
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tRESPONSE")
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
@ -165,16 +170,20 @@ func serviceStart(c *client.Client, id string) {
|
||||
}
|
||||
|
||||
func serviceStop(c *client.Client, id string) {
|
||||
reply, err := c.ServiceStop(globalCtx, id)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.ServiceStop(globalCtx, id, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error starting service: %s", err)
|
||||
}
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tRESPONSE")
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
@ -187,16 +196,20 @@ func serviceStop(c *client.Client, id string) {
|
||||
}
|
||||
|
||||
func serviceRestart(c *client.Client, id string) {
|
||||
reply, err := c.ServiceRestart(globalCtx, id)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.ServiceRestart(globalCtx, id, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error starting service: %s", err)
|
||||
}
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tRESPONSE")
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -14,7 +14,9 @@ import (
|
||||
|
||||
criconstants "github.com/containerd/cri/pkg/constants"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
"github.com/talos-systems/talos/api/common"
|
||||
osapi "github.com/talos-systems/talos/api/os"
|
||||
@ -47,21 +49,26 @@ var statsCmd = &cobra.Command{
|
||||
}
|
||||
md := metadata.New(make(map[string]string))
|
||||
md.Set("targets", target...)
|
||||
reply, err := c.Stats(metadata.NewOutgoingContext(globalCtx, md), namespace, driver)
|
||||
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Stats(metadata.NewOutgoingContext(globalCtx, md), namespace, driver, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting stats: %s", err)
|
||||
}
|
||||
|
||||
statsRender(reply)
|
||||
statsRender(&remotePeer, reply)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
func statsRender(reply *osapi.StatsReply) {
|
||||
func statsRender(remotePeer *peer.Peer, reply *osapi.StatsReply) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
|
||||
fmt.Fprintln(w, "NODE\tNAMESPACE\tID\tMEMORY(MB)\tCPU")
|
||||
|
||||
defaultNode := addrFromPeer(remotePeer)
|
||||
|
||||
for _, rep := range reply.Response {
|
||||
resp := rep
|
||||
sort.Slice(resp.Stats,
|
||||
@ -76,7 +83,7 @@ func statsRender(reply *osapi.StatsReply) {
|
||||
display = "└─ " + display
|
||||
}
|
||||
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
timeapi "github.com/talos-systems/talos/api/time"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -30,14 +32,18 @@ var timeCmd = &cobra.Command{
|
||||
helpers.Fatalf("failed to parse check flag: %w", err)
|
||||
}
|
||||
|
||||
var reply *timeapi.TimeReply
|
||||
var (
|
||||
reply *timeapi.TimeReply
|
||||
remotePeer peer.Peer
|
||||
)
|
||||
|
||||
if server == "" {
|
||||
reply, err = c.Time(globalCtx)
|
||||
reply, err = c.Time(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error fetching time: %s", err)
|
||||
}
|
||||
} else {
|
||||
reply, err = c.TimeCheck(globalCtx, server)
|
||||
reply, err = c.TimeCheck(globalCtx, server, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error fetching time: %s", err)
|
||||
}
|
||||
@ -46,9 +52,11 @@ var timeCmd = &cobra.Command{
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tNTP-SERVER\tLOCAL-TIME\tREMOTE-TIME")
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
var localtime, remotetime time.Time
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
machineapi "github.com/talos-systems/talos/api/machine"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
@ -37,14 +39,15 @@ func init() {
|
||||
|
||||
func upgrade() {
|
||||
var (
|
||||
err error
|
||||
reply *machineapi.UpgradeReply
|
||||
err error
|
||||
reply *machineapi.UpgradeReply
|
||||
remotePeer peer.Peer
|
||||
)
|
||||
|
||||
setupClient(func(c *client.Client) {
|
||||
// TODO: See if we can validate version and prevent starting upgrades to
|
||||
// an unknown version
|
||||
reply, err = c.Upgrade(globalCtx, upgradeImage)
|
||||
reply, err = c.Upgrade(globalCtx, upgradeImage, grpc.Peer(&remotePeer))
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@ -54,8 +57,10 @@ func upgrade() {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "NODE\tACK\tSTARTED")
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := ""
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
node = resp.Metadata.Hostname
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client"
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/helpers"
|
||||
@ -45,15 +47,24 @@ var versionCmd = &cobra.Command{
|
||||
|
||||
fmt.Println("Server:")
|
||||
setupClient(func(c *client.Client) {
|
||||
reply, err := c.Version(globalCtx)
|
||||
var remotePeer peer.Peer
|
||||
|
||||
reply, err := c.Version(globalCtx, grpc.Peer(&remotePeer))
|
||||
if err != nil {
|
||||
helpers.Fatalf("error getting version: %s", err)
|
||||
}
|
||||
|
||||
defaultNode := addrFromPeer(&remotePeer)
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
node := defaultNode
|
||||
|
||||
if resp.Metadata != nil {
|
||||
fmt.Printf("\t%s: %s\n", "NODE", resp.Metadata.Hostname)
|
||||
node = resp.Metadata.Hostname
|
||||
}
|
||||
|
||||
fmt.Printf("\t%s: %s\n", "NODE", node)
|
||||
|
||||
version.PrintLongVersionFromExisting(resp.Version)
|
||||
}
|
||||
})
|
||||
|
@ -207,27 +207,34 @@ func (c *Client) Kubeconfig(ctx context.Context) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Stats implements the proto.OSClient interface.
|
||||
func (c *Client) Stats(ctx context.Context, namespace string, driver common.ContainerDriver) (reply *osapi.StatsReply, err error) {
|
||||
reply, err = c.client.Stats(ctx, &osapi.StatsRequest{
|
||||
Namespace: namespace,
|
||||
Driver: driver,
|
||||
})
|
||||
func (c *Client) Stats(ctx context.Context, namespace string, driver common.ContainerDriver, callOptions ...grpc.CallOption) (reply *osapi.StatsReply, err error) {
|
||||
reply, err = c.client.Stats(
|
||||
ctx, &osapi.StatsRequest{
|
||||
Namespace: namespace,
|
||||
Driver: driver,
|
||||
},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Containers implements the proto.OSClient interface.
|
||||
func (c *Client) Containers(ctx context.Context, namespace string, driver common.ContainerDriver) (reply *osapi.ContainersReply, err error) {
|
||||
reply, err = c.client.Containers(ctx, &osapi.ContainersRequest{
|
||||
Namespace: namespace,
|
||||
Driver: driver,
|
||||
})
|
||||
func (c *Client) Containers(ctx context.Context, namespace string, driver common.ContainerDriver, callOptions ...grpc.CallOption) (reply *osapi.ContainersReply, err error) {
|
||||
reply, err = c.client.Containers(
|
||||
ctx,
|
||||
&osapi.ContainersRequest{
|
||||
Namespace: namespace,
|
||||
Driver: driver,
|
||||
},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Restart implements the proto.OSClient interface.
|
||||
func (c *Client) Restart(ctx context.Context, namespace string, driver common.ContainerDriver, id string) (err error) {
|
||||
func (c *Client) Restart(ctx context.Context, namespace string, driver common.ContainerDriver, id string, callOptions ...grpc.CallOption) (err error) {
|
||||
_, err = c.client.Restart(ctx, &osapi.RestartRequest{
|
||||
Id: id,
|
||||
Namespace: namespace,
|
||||
@ -272,33 +279,69 @@ func (c *Client) Logs(ctx context.Context, namespace string, driver common.Conta
|
||||
}
|
||||
|
||||
// Version implements the proto.OSClient interface.
|
||||
func (c *Client) Version(ctx context.Context) (*machineapi.VersionReply, error) {
|
||||
return c.MachineClient.Version(ctx, &empty.Empty{})
|
||||
func (c *Client) Version(ctx context.Context, callOptions ...grpc.CallOption) (reply *machineapi.VersionReply, err error) {
|
||||
reply, err = c.MachineClient.Version(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Routes implements the networkdproto.NetworkClient interface.
|
||||
func (c *Client) Routes(ctx context.Context) (*networkapi.RoutesReply, error) {
|
||||
return c.NetworkClient.Routes(ctx, &empty.Empty{})
|
||||
func (c *Client) Routes(ctx context.Context, callOptions ...grpc.CallOption) (reply *networkapi.RoutesReply, err error) {
|
||||
reply, err = c.NetworkClient.Routes(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Interfaces implements the proto.OSClient interface.
|
||||
func (c *Client) Interfaces(ctx context.Context) (*networkapi.InterfacesReply, error) {
|
||||
return c.NetworkClient.Interfaces(ctx, &empty.Empty{})
|
||||
func (c *Client) Interfaces(ctx context.Context, callOptions ...grpc.CallOption) (reply *networkapi.InterfacesReply, err error) {
|
||||
reply, err = c.NetworkClient.Interfaces(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Processes implements the proto.OSClient interface.
|
||||
func (c *Client) Processes(ctx context.Context) (reply *osapi.ProcessesReply, err error) {
|
||||
return c.client.Processes(ctx, &empty.Empty{})
|
||||
func (c *Client) Processes(ctx context.Context, callOptions ...grpc.CallOption) (reply *osapi.ProcessesReply, err error) {
|
||||
reply, err = c.client.Processes(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Memory implements the proto.OSClient interface.
|
||||
func (c *Client) Memory(ctx context.Context) (*osapi.MemInfoReply, error) {
|
||||
return c.client.Memory(ctx, &empty.Empty{})
|
||||
func (c *Client) Memory(ctx context.Context, callOptions ...grpc.CallOption) (reply *osapi.MemInfoReply, err error) {
|
||||
reply, err = c.client.Memory(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Mounts implements the proto.OSClient interface.
|
||||
func (c *Client) Mounts(ctx context.Context) (*machineapi.MountsReply, error) {
|
||||
return c.MachineClient.Mounts(ctx, &empty.Empty{})
|
||||
func (c *Client) Mounts(ctx context.Context, callOptions ...grpc.CallOption) (reply *machineapi.MountsReply, err error) {
|
||||
reply, err = c.MachineClient.Mounts(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// LS implements the proto.OSClient interface.
|
||||
@ -320,46 +363,117 @@ func (c *Client) CopyOut(ctx context.Context, rootPath string) (io.Reader, <-cha
|
||||
|
||||
// Upgrade initiates a Talos upgrade ... and implements the proto.OSClient
|
||||
// interface
|
||||
func (c *Client) Upgrade(ctx context.Context, image string) (*machineapi.UpgradeReply, error) {
|
||||
return c.MachineClient.Upgrade(ctx, &machineapi.UpgradeRequest{Image: image})
|
||||
func (c *Client) Upgrade(ctx context.Context, image string, callOptions ...grpc.CallOption) (reply *machineapi.UpgradeReply, err error) {
|
||||
reply, err = c.MachineClient.Upgrade(
|
||||
ctx,
|
||||
&machineapi.UpgradeRequest{Image: image},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceList returns list of services with their state
|
||||
func (c *Client) ServiceList(ctx context.Context) (*machineapi.ServiceListReply, error) {
|
||||
return c.MachineClient.ServiceList(ctx, &empty.Empty{})
|
||||
func (c *Client) ServiceList(ctx context.Context, callOptions ...grpc.CallOption) (reply *machineapi.ServiceListReply, err error) {
|
||||
reply, err = c.MachineClient.ServiceList(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceInfo provides info about a service and node metadata
|
||||
type ServiceInfo struct {
|
||||
Metadata *common.ResponseMetadata
|
||||
Service *machineapi.ServiceInfo
|
||||
}
|
||||
|
||||
// ServiceInfo returns info about a single service
|
||||
//
|
||||
// This is implemented via service list API, as we don't have many services
|
||||
// If service with given id is not registered, function returns nil
|
||||
func (c *Client) ServiceInfo(ctx context.Context, id string) (*machineapi.ServiceListReply, error) {
|
||||
return c.MachineClient.ServiceList(ctx, &empty.Empty{})
|
||||
func (c *Client) ServiceInfo(ctx context.Context, id string, callOptions ...grpc.CallOption) (services []ServiceInfo, err error) {
|
||||
var reply *machineapi.ServiceListReply
|
||||
|
||||
reply, err = c.MachineClient.ServiceList(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, resp := range reply.Response {
|
||||
for _, svc := range resp.Services {
|
||||
if svc.Id == id {
|
||||
services = append(services, ServiceInfo{
|
||||
Metadata: resp.Metadata,
|
||||
Service: svc,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceStart starts a service.
|
||||
func (c *Client) ServiceStart(ctx context.Context, id string) (*machineapi.ServiceStartReply, error) {
|
||||
return c.MachineClient.ServiceStart(ctx, &machineapi.ServiceStartRequest{Id: id})
|
||||
func (c *Client) ServiceStart(ctx context.Context, id string, callOptions ...grpc.CallOption) (reply *machineapi.ServiceStartReply, err error) {
|
||||
reply, err = c.MachineClient.ServiceStart(
|
||||
ctx,
|
||||
&machineapi.ServiceStartRequest{Id: id},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceStop stops a service.
|
||||
func (c *Client) ServiceStop(ctx context.Context, id string) (*machineapi.ServiceStopReply, error) {
|
||||
return c.MachineClient.ServiceStop(ctx, &machineapi.ServiceStopRequest{Id: id})
|
||||
func (c *Client) ServiceStop(ctx context.Context, id string, callOptions ...grpc.CallOption) (reply *machineapi.ServiceStopReply, err error) {
|
||||
reply, err = c.MachineClient.ServiceStop(
|
||||
ctx,
|
||||
&machineapi.ServiceStopRequest{Id: id},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceRestart restarts a service.
|
||||
func (c *Client) ServiceRestart(ctx context.Context, id string) (*machineapi.ServiceRestartReply, error) {
|
||||
return c.MachineClient.ServiceRestart(ctx, &machineapi.ServiceRestartRequest{Id: id})
|
||||
func (c *Client) ServiceRestart(ctx context.Context, id string, callOptions ...grpc.CallOption) (reply *machineapi.ServiceRestartReply, err error) {
|
||||
reply, err = c.MachineClient.ServiceRestart(
|
||||
ctx,
|
||||
&machineapi.ServiceRestartRequest{Id: id},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Time returns the time
|
||||
func (c *Client) Time(ctx context.Context) (*timeapi.TimeReply, error) {
|
||||
return c.TimeClient.Time(ctx, &empty.Empty{})
|
||||
func (c *Client) Time(ctx context.Context, callOptions ...grpc.CallOption) (reply *timeapi.TimeReply, err error) {
|
||||
reply, err = c.TimeClient.Time(
|
||||
ctx,
|
||||
&empty.Empty{},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// TimeCheck returns the time compared to the specified ntp server
|
||||
func (c *Client) TimeCheck(ctx context.Context, server string) (*timeapi.TimeReply, error) {
|
||||
return c.TimeClient.TimeCheck(ctx, &timeapi.TimeRequest{Server: server})
|
||||
func (c *Client) TimeCheck(ctx context.Context, server string, callOptions ...grpc.CallOption) (reply *timeapi.TimeReply, err error) {
|
||||
reply, err = c.TimeClient.TimeCheck(
|
||||
ctx,
|
||||
&timeapi.TimeRequest{Server: server},
|
||||
callOptions...,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Read reads a file.
|
||||
|
Loading…
x
Reference in New Issue
Block a user