Merge pull request #328 from rancher/feature/node-status

[Feature] Node Status
pull/335/head
Thorsten Klein 4 years ago committed by GitHub
commit b029655c8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      cmd/cluster/clusterList.go
  2. 4
      cmd/node/nodeList.go
  3. 56
      pkg/runtimes/docker/node.go
  4. 7
      pkg/runtimes/docker/translate.go
  5. 27
      pkg/types/types.go

@ -116,14 +116,14 @@ func PrintClusters(clusters []*k3d.Cluster, flags clusterFlags) {
k3cluster.SortClusters(clusters)
for _, cluster := range clusters {
serverCount := cluster.ServerCount()
agentCount := cluster.AgentCount()
serverCount, serversRunning := cluster.ServerCountRunning()
agentCount, agentsRunning := cluster.AgentCountRunning()
hasLB := cluster.HasLoadBalancer()
if flags.token {
fmt.Fprintf(tabwriter, "%s\t%d\t%d\t%t\t%s\n", cluster.Name, serverCount, agentCount, hasLB, cluster.Token)
fmt.Fprintf(tabwriter, "%s\t%d/%d\t%d/%d\t%t\t%s\n", cluster.Name, serversRunning, serverCount, agentsRunning, agentCount, hasLB, cluster.Token)
} else {
fmt.Fprintf(tabwriter, "%s\t%d\t%d\t%t\n", cluster.Name, serverCount, agentCount, hasLB)
fmt.Fprintf(tabwriter, "%s\t%d/%d\t%d/%d\t%t\n", cluster.Name, serversRunning, serverCount, agentsRunning, agentCount, hasLB)
}
}
}

@ -106,7 +106,7 @@ func printNodes(nodes []*k3d.Node, headersOff bool) {
defer tabwriter.Flush()
if !headersOff {
headers := []string{"NAME", "ROLE", "CLUSTER"} // TODO: add status
headers := []string{"NAME", "ROLE", "CLUSTER", "STATUS"}
_, err := fmt.Fprintf(tabwriter, "%s\n", strings.Join(headers, "\t"))
if err != nil {
log.Fatalln("Failed to print headers")
@ -118,6 +118,6 @@ func printNodes(nodes []*k3d.Node, headersOff bool) {
})
for _, node := range nodes {
fmt.Fprintf(tabwriter, "%s\t%s\t%s\n", strings.TrimPrefix(node.Name, "/"), string(node.Role), node.Labels[k3d.LabelClusterName])
fmt.Fprintf(tabwriter, "%s\t%s\t%s\t%s\n", strings.TrimPrefix(node.Name, "/"), string(node.Role), node.Labels[k3d.LabelClusterName], node.State.Status)
}
}

@ -72,9 +72,21 @@ func (d Docker) GetNodesByLabel(ctx context.Context, labels map[string]string) (
// (1) convert them to node structs
nodes := []*k3d.Node{}
for _, container := range containers {
node, err := TranslateContainerToNode(&container)
var node *k3d.Node
var err error
containerDetails, err := getContainerDetails(ctx, container.ID)
if err != nil {
return nil, err
log.Warnf("Failed to get details for container %s", container.Names[0])
node, err = TranslateContainerToNode(&container)
if err != nil {
return nil, err
}
} else {
node, err = TranslateContainerDetailsToNode(containerDetails)
if err != nil {
return nil, err
}
}
nodes = append(nodes, node)
}
@ -212,6 +224,46 @@ func (d Docker) GetNode(ctx context.Context, node *k3d.Node) (*k3d.Node, error)
}
// GetNodeStatus returns the status of a node (Running, Started, etc.)
func (d Docker) GetNodeStatus(ctx context.Context, node *k3d.Node) (bool, string, error) {
stateString := ""
running := false
// get the container for the given node
container, err := getNodeContainer(ctx, node)
if err != nil {
return running, stateString, err
}
// create docker client
docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
log.Errorln("Failed to create docker client")
return running, stateString, err
}
defer docker.Close()
containerInspectResponse, err := docker.ContainerInspect(ctx, container.ID)
if err != nil {
return running, stateString, err
}
running = containerInspectResponse.ContainerJSONBase.State.Running
stateString = containerInspectResponse.ContainerJSONBase.State.Status
return running, stateString, nil
}
// NodeIsRunning tells the caller if a given node is in "running" state
func (d Docker) NodeIsRunning(ctx context.Context, node *k3d.Node) (bool, error) {
isRunning, _, err := d.GetNodeStatus(ctx, node)
if err != nil {
return false, err
}
return isRunning, nil
}
// GetNodeLogs returns the logs from a given node
func (d Docker) GetNodeLogs(ctx context.Context, node *k3d.Node, since time.Time) (io.ReadCloser, error) {
// get the container for the given node

@ -175,6 +175,12 @@ func TranslateContainerDetailsToNode(containerDetails types.ContainerJSON) (*k3d
}
}
// status
nodeState := k3d.NodeState{
Running: containerDetails.ContainerJSONBase.State.Running,
Status: containerDetails.ContainerJSONBase.State.Status,
}
node := &k3d.Node{
Name: strings.TrimPrefix(containerDetails.Name, "/"), // container name with leading '/' cut off
Role: k3d.NodeRoles[containerDetails.Config.Labels[k3d.LabelRole]],
@ -189,6 +195,7 @@ func TranslateContainerDetailsToNode(containerDetails types.ContainerJSON) (*k3d
Network: clusterNetwork,
ServerOpts: serverOpts,
AgentOpts: k3d.AgentOpts{},
State: nodeState,
}
return node, nil
}

@ -181,26 +181,34 @@ type Cluster struct {
ImageVolume string `yaml:"image_volume" json:"imageVolume,omitempty"`
}
// ServerCount return number of server node into cluster
func (c *Cluster) ServerCount() int {
// ServerCountRunning returns the number of server nodes running in the cluster and the total number
func (c *Cluster) ServerCountRunning() (int, int) {
serverCount := 0
serversRunning := 0
for _, node := range c.Nodes {
if node.Role == ServerRole {
serverCount++
if node.State.Running {
serversRunning++
}
}
}
return serverCount
return serverCount, serversRunning
}
// AgentCount return number of agent node into cluster
func (c *Cluster) AgentCount() int {
// AgentCountRunning returns the number of agent nodes running in the cluster and the total number
func (c *Cluster) AgentCountRunning() (int, int) {
agentCount := 0
agentsRunning := 0
for _, node := range c.Nodes {
if node.Role == AgentRole {
agentCount++
if node.State.Running {
agentsRunning++
}
}
}
return agentCount
return agentCount, agentsRunning
}
// HasLoadBalancer returns true if cluster has a loadbalancer node
@ -228,6 +236,7 @@ type Node struct {
Network string // filled automatically
ServerOpts ServerOpts `yaml:"server_opts" json:"serverOpts,omitempty"`
AgentOpts AgentOpts `yaml:"agent_opts" json:"agentOpts,omitempty"`
State NodeState // filled automatically
}
// ServerOpts describes some additional server role specific opts
@ -259,3 +268,9 @@ type AgentOpts struct{}
func GetDefaultObjectName(name string) string {
return fmt.Sprintf("%s-%s", DefaultObjectNamePrefix, name)
}
// NodeState describes the current state of a node
type NodeState struct {
Running bool
Status string
}

Loading…
Cancel
Save