mirror of https://github.com/docker/cli.git
Merge pull request #885 from thaJeztah/node-engine-version
Add Engine version to docker node ls
This commit is contained in:
commit
1e8530bc34
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultNodeTableFormat = "table {{.ID}} {{if .Self}}*{{else}} {{ end }}\t{{.Hostname}}\t{{.Status}}\t{{.Availability}}\t{{.ManagerStatus}}"
|
defaultNodeTableFormat = "table {{.ID}} {{if .Self}}*{{else}} {{ end }}\t{{.Hostname}}\t{{.Status}}\t{{.Availability}}\t{{.ManagerStatus}}\t{{.EngineVersion}}"
|
||||||
nodeInspectPrettyTemplate Format = `ID: {{.ID}}
|
nodeInspectPrettyTemplate Format = `ID: {{.ID}}
|
||||||
{{- if .Name }}
|
{{- if .Name }}
|
||||||
Name: {{.Name}}
|
Name: {{.Name}}
|
||||||
|
@ -75,6 +75,7 @@ TLS Info:
|
||||||
hostnameHeader = "HOSTNAME"
|
hostnameHeader = "HOSTNAME"
|
||||||
availabilityHeader = "AVAILABILITY"
|
availabilityHeader = "AVAILABILITY"
|
||||||
managerStatusHeader = "MANAGER STATUS"
|
managerStatusHeader = "MANAGER STATUS"
|
||||||
|
engineVersionHeader = "ENGINE VERSION"
|
||||||
tlsStatusHeader = "TLS STATUS"
|
tlsStatusHeader = "TLS STATUS"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -115,6 +116,7 @@ func NodeWrite(ctx Context, nodes []swarm.Node, info types.Info) error {
|
||||||
"Status": statusHeader,
|
"Status": statusHeader,
|
||||||
"Availability": availabilityHeader,
|
"Availability": availabilityHeader,
|
||||||
"ManagerStatus": managerStatusHeader,
|
"ManagerStatus": managerStatusHeader,
|
||||||
|
"EngineVersion": engineVersionHeader,
|
||||||
"TLSStatus": tlsStatusHeader,
|
"TLSStatus": tlsStatusHeader,
|
||||||
}
|
}
|
||||||
nodeCtx := nodeContext{}
|
nodeCtx := nodeContext{}
|
||||||
|
@ -176,6 +178,10 @@ func (c *nodeContext) TLSStatus() string {
|
||||||
return "Needs Rotation"
|
return "Needs Rotation"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *nodeContext) EngineVersion() string {
|
||||||
|
return c.n.Description.Engine.EngineVersion
|
||||||
|
}
|
||||||
|
|
||||||
// NodeInspectWrite renders the context for a list of nodes
|
// NodeInspectWrite renders the context for a list of nodes
|
||||||
func NodeInspectWrite(ctx Context, refs []string, getRef inspect.GetRefFunc) error {
|
func NodeInspectWrite(ctx Context, refs []string, getRef inspect.GetRefFunc) error {
|
||||||
if ctx.Format != nodeInspectPrettyTemplate {
|
if ctx.Format != nodeInspectPrettyTemplate {
|
||||||
|
|
|
@ -74,10 +74,10 @@ func TestNodeContextWrite(t *testing.T) {
|
||||||
// Table format
|
// Table format
|
||||||
{
|
{
|
||||||
context: Context{Format: NewNodeFormat("table", false)},
|
context: Context{Format: NewNodeFormat("table", false)},
|
||||||
expected: `ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
|
expected: `ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
|
||||||
nodeID1 foobar_baz Foo Drain Leader
|
nodeID1 foobar_baz Foo Drain Leader 18.03.0-ce
|
||||||
nodeID2 foobar_bar Bar Active Reachable
|
nodeID2 foobar_bar Bar Active Reachable 1.2.3
|
||||||
nodeID3 foobar_boo Boo Active ` + "\n", // (to preserve whitespace)
|
nodeID3 foobar_boo Boo Active ` + "\n", // (to preserve whitespace)
|
||||||
clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}},
|
clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -172,6 +172,7 @@ foobar_boo Unknown
|
||||||
Description: swarm.NodeDescription{
|
Description: swarm.NodeDescription{
|
||||||
Hostname: "foobar_baz",
|
Hostname: "foobar_baz",
|
||||||
TLSInfo: swarm.TLSInfo{TrustRoot: "no"},
|
TLSInfo: swarm.TLSInfo{TrustRoot: "no"},
|
||||||
|
Engine: swarm.EngineDescription{EngineVersion: "18.03.0-ce"},
|
||||||
},
|
},
|
||||||
Status: swarm.NodeStatus{State: swarm.NodeState("foo")},
|
Status: swarm.NodeStatus{State: swarm.NodeState("foo")},
|
||||||
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("drain")},
|
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("drain")},
|
||||||
|
@ -182,6 +183,7 @@ foobar_boo Unknown
|
||||||
Description: swarm.NodeDescription{
|
Description: swarm.NodeDescription{
|
||||||
Hostname: "foobar_bar",
|
Hostname: "foobar_bar",
|
||||||
TLSInfo: swarm.TLSInfo{TrustRoot: "hi"},
|
TLSInfo: swarm.TLSInfo{TrustRoot: "hi"},
|
||||||
|
Engine: swarm.EngineDescription{EngineVersion: "1.2.3"},
|
||||||
},
|
},
|
||||||
Status: swarm.NodeStatus{State: swarm.NodeState("bar")},
|
Status: swarm.NodeStatus{State: swarm.NodeState("bar")},
|
||||||
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("active")},
|
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("active")},
|
||||||
|
@ -215,17 +217,17 @@ func TestNodeContextWriteJSON(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
expected: []map[string]interface{}{
|
expected: []map[string]interface{}{
|
||||||
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
|
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "1.2.3"},
|
||||||
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
|
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": ""},
|
||||||
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
|
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
|
||||||
},
|
},
|
||||||
info: types.Info{},
|
info: types.Info{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expected: []map[string]interface{}{
|
expected: []map[string]interface{}{
|
||||||
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Ready"},
|
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Ready", "EngineVersion": "1.2.3"},
|
||||||
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation"},
|
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation", "EngineVersion": ""},
|
||||||
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
|
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
|
||||||
},
|
},
|
||||||
info: types.Info{
|
info: types.Info{
|
||||||
Swarm: swarm.Info{
|
Swarm: swarm.Info{
|
||||||
|
@ -240,9 +242,9 @@ func TestNodeContextWriteJSON(t *testing.T) {
|
||||||
|
|
||||||
for _, testcase := range cases {
|
for _, testcase := range cases {
|
||||||
nodes := []swarm.Node{
|
nodes := []swarm.Node{
|
||||||
{ID: "nodeID1", Description: swarm.NodeDescription{Hostname: "foobar_baz", TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}},
|
{ID: "nodeID1", Description: swarm.NodeDescription{Hostname: "foobar_baz", TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}, Engine: swarm.EngineDescription{EngineVersion: "1.2.3"}}},
|
||||||
{ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar", TLSInfo: swarm.TLSInfo{TrustRoot: "no"}}},
|
{ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar", TLSInfo: swarm.TLSInfo{TrustRoot: "no"}}},
|
||||||
{ID: "nodeID3", Description: swarm.NodeDescription{Hostname: "foobar_boo"}},
|
{ID: "nodeID3", Description: swarm.NodeDescription{Hostname: "foobar_boo", Engine: swarm.EngineDescription{EngineVersion: "18.03.0-ce"}}},
|
||||||
}
|
}
|
||||||
out := bytes.NewBufferString("")
|
out := bytes.NewBufferString("")
|
||||||
err := NodeWrite(Context{Format: "{{json .}}", Output: out}, nodes, testcase.info)
|
err := NodeWrite(Context{Format: "{{json .}}", Output: out}, nodes, testcase.info)
|
||||||
|
|
|
@ -56,8 +56,8 @@ func TestNodeList(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{
|
return []swarm.Node{
|
||||||
*Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader())),
|
*Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader()), EngineVersion(".")),
|
||||||
*Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager()),
|
*Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager(), EngineVersion("18.03.0-ce")),
|
||||||
*Node(NodeID("nodeID3"), Hostname("node-1-foo")),
|
*Node(NodeID("nodeID3"), Hostname("node-1-foo")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
|
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
|
||||||
nodeID3 node-1-foo Ready Active
|
nodeID3 node-1-foo Ready Active 1.13.0
|
||||||
nodeID1 * node-2-foo Ready Active Leader
|
nodeID1 * node-2-foo Ready Active Leader .
|
||||||
nodeID2 node-10-foo Ready Active Reachable
|
nodeID2 node-10-foo Ready Active Reachable 18.03.0-ce
|
||||||
|
|
|
@ -146,6 +146,7 @@ Placeholder | Description
|
||||||
`.Availability` | Node availability ("active", "pause", or "drain")
|
`.Availability` | Node availability ("active", "pause", or "drain")
|
||||||
`.ManagerStatus` | Manager status of the node
|
`.ManagerStatus` | Manager status of the node
|
||||||
`.TLSStatus` | TLS status of the node ("Ready", or "Needs Rotation" has TLS certificate signed by an old CA)
|
`.TLSStatus` | TLS status of the node ("Ready", or "Needs Rotation" has TLS certificate signed by an old CA)
|
||||||
|
`.EngineVersion` | Engine version
|
||||||
|
|
||||||
When using the `--format` option, the `node ls` command will either
|
When using the `--format` option, the `node ls` command will either
|
||||||
output the data exactly as the template declares or, when using the
|
output the data exactly as the template declares or, when using the
|
||||||
|
|
|
@ -125,3 +125,10 @@ func ManagerStatus(managerStatusBuilders ...func(*swarm.ManagerStatus)) *swarm.M
|
||||||
|
|
||||||
return managerStatus
|
return managerStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EngineVersion sets the node's engine version
|
||||||
|
func EngineVersion(version string) func(*swarm.Node) {
|
||||||
|
return func(node *swarm.Node) {
|
||||||
|
node.Description.Engine.EngineVersion = version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue