mirror of https://github.com/docker/docs.git
Allow custom format for ls
Signed-off-by: David Gageot <david@gageot.net>
This commit is contained in:
parent
c64af2918e
commit
adc60712c8
|
@ -214,6 +214,9 @@ var Commands = []cli.Command{
|
|||
Action: fatalOnError(cmdKill),
|
||||
},
|
||||
{
|
||||
Name: "ls",
|
||||
Usage: "List machines",
|
||||
Action: fatalOnError(cmdLs),
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "quiet, q",
|
||||
|
@ -229,10 +232,11 @@ var Commands = []cli.Command{
|
|||
Usage: fmt.Sprintf("Timeout in seconds, default to %s", stateTimeoutDuration),
|
||||
Value: lsDefaultTimeout,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format, f",
|
||||
Usage: "Pretty-print machines using a Go template",
|
||||
},
|
||||
},
|
||||
Name: "ls",
|
||||
Usage: "List machines",
|
||||
Action: fatalOnError(cmdLs),
|
||||
},
|
||||
{
|
||||
Name: "regenerate-certs",
|
||||
|
|
|
@ -11,6 +11,8 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"io"
|
||||
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/docker/machine/libmachine/engine"
|
||||
|
@ -23,11 +25,14 @@ import (
|
|||
"github.com/skarademir/naturalsort"
|
||||
)
|
||||
|
||||
const lsDefaultTimeout = 10
|
||||
const (
|
||||
lsDefaultTimeout = 10
|
||||
tableFormatKey = "table"
|
||||
lsDefaultFormat = "table {{ .Name }}\t{{ .Active }}\t{{ .DriverName}}\t{{ .State }}\t{{ .URL }}\t{{ .Swarm }}\t{{ .DockerVersion }}\t{{ .Error}}"
|
||||
)
|
||||
|
||||
var (
|
||||
stateTimeoutDuration = lsDefaultTimeout * time.Second
|
||||
defaultLsTemplate = "{{ .Name }}\t{{ .Active }}\t{{ .DriverName}}\t{{ .State }}\t{{ .URL }}\t{{ .Swarm }}\t{{ .DockerVersion }}\t{{ .Error}}"
|
||||
)
|
||||
|
||||
// FilterOptions -
|
||||
|
@ -54,11 +59,25 @@ type HostListItem struct {
|
|||
DockerVersion string
|
||||
}
|
||||
|
||||
type Headers struct {
|
||||
Name string
|
||||
Active string
|
||||
ActiveHost string
|
||||
ActiveSwarm string
|
||||
DriverName string
|
||||
State string
|
||||
URL string
|
||||
SwarmOptions string
|
||||
Swarm string
|
||||
EngineOptions string
|
||||
Error string
|
||||
DockerVersion string
|
||||
}
|
||||
|
||||
func cmdLs(c CommandLine, api libmachine.API) error {
|
||||
stateTimeoutDuration = time.Duration(c.Int("timeout")) * time.Second
|
||||
log.Debugf("ls timeout set to %s", stateTimeoutDuration)
|
||||
|
||||
quiet := c.Bool("quiet")
|
||||
filters, err := parseFilters(c.StringSlice("filter"))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -72,27 +91,52 @@ func cmdLs(c CommandLine, api libmachine.API) error {
|
|||
hostList = filterHosts(hostList, filters)
|
||||
|
||||
// Just print out the names if we're being quiet
|
||||
if quiet {
|
||||
if c.Bool("quiet") {
|
||||
for _, host := range hostList {
|
||||
fmt.Println(host.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
t := template.New("lsConfig")
|
||||
template, err := t.Parse(defaultLsTemplate + "\n")
|
||||
template, table, err := parseFormat(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var w io.Writer
|
||||
if table {
|
||||
tabWriter := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
|
||||
defer tabWriter.Flush()
|
||||
|
||||
w = tabWriter
|
||||
|
||||
headers := &Headers{
|
||||
Name: "NAME",
|
||||
Active: "ACTIVE",
|
||||
ActiveHost: "DRIVER",
|
||||
ActiveSwarm: "STATE",
|
||||
DriverName: "URL",
|
||||
State: "STATE",
|
||||
URL: "URL",
|
||||
SwarmOptions: "SWARM_OPTIONS",
|
||||
Swarm: "SWARM",
|
||||
EngineOptions: "ENGINE_OPTIONS",
|
||||
Error: "ERRORS",
|
||||
DockerVersion: "DOCKER",
|
||||
}
|
||||
|
||||
if err := template.Execute(w, headers); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
w = os.Stdout
|
||||
}
|
||||
|
||||
items := getHostListItems(hostList, hostInError)
|
||||
|
||||
swarmMasters := make(map[string]string)
|
||||
swarmInfo := make(map[string]string)
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
|
||||
defer w.Flush()
|
||||
|
||||
fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL\tSWARM\tDOCKER\tERRORS")
|
||||
|
||||
for _, host := range hostList {
|
||||
if host.HostOptions != nil {
|
||||
swarmOptions := host.HostOptions.SwarmOptions
|
||||
|
@ -106,7 +150,6 @@ func cmdLs(c CommandLine, api libmachine.API) error {
|
|||
}
|
||||
}
|
||||
|
||||
items := getHostListItems(hostList, hostInError)
|
||||
for _, item := range items {
|
||||
swarmColumn := ""
|
||||
if item.SwarmOptions != nil && item.SwarmOptions.Discovery != "" {
|
||||
|
@ -125,6 +168,31 @@ func cmdLs(c CommandLine, api libmachine.API) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseFormat(format string) (*template.Template, bool, error) {
|
||||
table := false
|
||||
finalFormat := format
|
||||
|
||||
if finalFormat == "" {
|
||||
finalFormat = lsDefaultFormat
|
||||
}
|
||||
|
||||
if strings.HasPrefix(finalFormat, tableFormatKey) {
|
||||
table = true
|
||||
finalFormat = finalFormat[len(tableFormatKey):]
|
||||
}
|
||||
|
||||
finalFormat = strings.Trim(finalFormat, " ")
|
||||
r := strings.NewReplacer(`\t`, "\t", `\n`, "\n")
|
||||
finalFormat = r.Replace(finalFormat)
|
||||
|
||||
template, err := template.New("").Parse(finalFormat + "\n")
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return template, table, nil
|
||||
}
|
||||
|
||||
func parseFilters(filters []string) (FilterOptions, error) {
|
||||
options := FilterOptions{}
|
||||
for _, f := range filters {
|
||||
|
|
|
@ -96,7 +96,7 @@ _docker_machine_ls() {
|
|||
COMPREPLY=()
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--quiet --filter --timeout --help" -- "${cur}"))
|
||||
COMPREPLY=($(compgen -W "--quiet --filter --format --timeout --help" -- "${cur}"))
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
|
@ -16,9 +16,10 @@ parent="smn_machine_subcmds"
|
|||
|
||||
Options:
|
||||
|
||||
--quiet, -q Enable quiet mode
|
||||
--filter [--filter option --filter option] Filter output based on conditions provided
|
||||
--timeout, -t Timeout in seconds, default to 10s
|
||||
--quiet, -q Enable quiet mode
|
||||
--filter [--filter option --filter option] Filter output based on conditions provided
|
||||
--timeout, -t Timeout in seconds, default to 10s
|
||||
--format, -f Pretty-print machines using a Go template
|
||||
|
||||
## Timeout
|
||||
|
||||
|
@ -47,6 +48,42 @@ The currently supported filters are:
|
|||
- name (Machine name returned by driver, supports [golang style](https://github.com/google/re2/wiki/Syntax) regular expressions)
|
||||
- label (Machine created with `--engine-label` option, can be filtered with `label=<key>[=<value>]`)
|
||||
|
||||
## Formatting
|
||||
|
||||
The formatting option (`--format`) will pretty-print machines using a Go template.
|
||||
|
||||
Valid placeholders for the Go template are listed below:
|
||||
|
||||
| Placeholder | Description |
|
||||
| -------------- | ---------------------------------------- |
|
||||
| .Name | Machine name |
|
||||
| .Active | Is the machine active? |
|
||||
| .ActiveHost | Is the machine an active non-swarm host? |
|
||||
| .ActiveSwarm | Is the machine an active swarm master? |
|
||||
| .DriverName | Driver name |
|
||||
| .State | Machine state (running, stopped...) |
|
||||
| .URL | Machine URL |
|
||||
| .Swarm | Machine swarm name |
|
||||
| .Error | Machine errors |
|
||||
| .DockerVersion | Docker Daemon version |
|
||||
|
||||
When using the `--format` option, the `ls` command will either output the data exactly as the template declares or,
|
||||
when using the table directive, will include column headers as well.
|
||||
|
||||
The following example uses a template without headers and outputs the `Name` and `Driver` entries separated by a colon
|
||||
for all running machines:
|
||||
|
||||
$ docker-machine ls --format "{{.Name}}: {{.DriverName}}"
|
||||
default: virtualbox
|
||||
ec2: amazonec2
|
||||
|
||||
To list all machine names with their driver in a table format you can use:
|
||||
|
||||
$ docker-machine ls --format "table {{.Name}}: {{.DriverName}}"
|
||||
NAME DRIVER
|
||||
default virtualbox
|
||||
ec2 amazonec2
|
||||
|
||||
## Examples
|
||||
|
||||
$ docker-machine ls
|
||||
|
|
|
@ -165,3 +165,27 @@ bootstrap_swarm () {
|
|||
[[ ${lines[1]} == "testswarm2" ]]
|
||||
[[ ${lines[2]} == "testswarm3" ]]
|
||||
}
|
||||
|
||||
@test "ls: format on driver 'machine ls --format '{{ .DriverName }}'" {
|
||||
run machine ls --format '{{ .DriverName }}'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ${#lines[@]} == 5 ]]
|
||||
[[ ${lines[0]} =~ "none" ]]
|
||||
[[ ${lines[1]} =~ "none" ]]
|
||||
[[ ${lines[2]} =~ "none" ]]
|
||||
[[ ${lines[3]} =~ "none" ]]
|
||||
[[ ${lines[4]} =~ "none" ]]
|
||||
}
|
||||
|
||||
|
||||
@test "ls: format on name and driver 'machine ls --format 'table {{ .Name}}: {{ .DriverName }}'" {
|
||||
run machine ls --format 'table {{ .Name}}: {{ .DriverName }}'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ${#lines[@]} == 6 ]]
|
||||
[[ ${lines[1]} =~ "testmachine: none" ]]
|
||||
[[ ${lines[2]} =~ "testmachine2: none" ]]
|
||||
[[ ${lines[3]} =~ "testmachine3: none" ]]
|
||||
[[ ${lines[4]} =~ "testmachine4: none" ]]
|
||||
[[ ${lines[5]} =~ "testmachine5: none" ]]
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue