mirror of https://github.com/docker/docs.git
184 lines
4.0 KiB
Go
184 lines
4.0 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
"github.com/codegangsta/cli"
|
|
"github.com/docker/machine/libmachine"
|
|
"github.com/docker/machine/log"
|
|
)
|
|
|
|
// FilterOptions -
|
|
type FilterOptions struct {
|
|
SwarmName []string
|
|
DriverName []string
|
|
State []string
|
|
}
|
|
|
|
func cmdLs(c *cli.Context) {
|
|
quiet := c.Bool("quiet")
|
|
filters, err := parseFilters(c.StringSlice("filter"))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
provider := getDefaultProvider(c)
|
|
hostList, err := provider.List()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
hostList = filterHosts(hostList, filters)
|
|
|
|
// Just print out the names if we're being quiet
|
|
if quiet {
|
|
for _, host := range hostList {
|
|
fmt.Println(host.Name)
|
|
}
|
|
return
|
|
}
|
|
|
|
swarmMasters := make(map[string]string)
|
|
swarmInfo := make(map[string]string)
|
|
|
|
w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
|
|
fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL\tSWARM")
|
|
|
|
for _, host := range hostList {
|
|
swarmOptions := host.HostOptions.SwarmOptions
|
|
if swarmOptions.Master {
|
|
swarmMasters[swarmOptions.Discovery] = host.Name
|
|
}
|
|
|
|
if swarmOptions.Discovery != "" {
|
|
swarmInfo[host.Name] = swarmOptions.Discovery
|
|
}
|
|
}
|
|
|
|
items := libmachine.GetHostListItems(hostList)
|
|
|
|
sortHostListItemsByName(items)
|
|
|
|
for _, item := range items {
|
|
activeString := ""
|
|
if item.Active {
|
|
activeString = "*"
|
|
}
|
|
|
|
swarmInfo := ""
|
|
|
|
if item.SwarmOptions.Discovery != "" {
|
|
swarmInfo = swarmMasters[item.SwarmOptions.Discovery]
|
|
if item.SwarmOptions.Master {
|
|
swarmInfo = fmt.Sprintf("%s (master)", swarmInfo)
|
|
}
|
|
}
|
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n",
|
|
item.Name, activeString, item.DriverName, item.State, item.URL, swarmInfo)
|
|
}
|
|
|
|
w.Flush()
|
|
}
|
|
|
|
func parseFilters(filters []string) (FilterOptions, error) {
|
|
options := FilterOptions{}
|
|
for _, f := range filters {
|
|
kv := strings.SplitN(f, "=", 2)
|
|
key, value := kv[0], kv[1]
|
|
|
|
switch key {
|
|
case "swarm":
|
|
options.SwarmName = append(options.SwarmName, value)
|
|
case "driver":
|
|
options.DriverName = append(options.DriverName, value)
|
|
case "state":
|
|
options.State = append(options.State, value)
|
|
default:
|
|
return options, fmt.Errorf("Unsupported filter key '%s'", key)
|
|
}
|
|
}
|
|
return options, nil
|
|
}
|
|
|
|
func filterHosts(hosts []*libmachine.Host, filters FilterOptions) []*libmachine.Host {
|
|
if len(filters.SwarmName) == 0 &&
|
|
len(filters.DriverName) == 0 &&
|
|
len(filters.State) == 0 {
|
|
return hosts
|
|
}
|
|
|
|
filteredHosts := []*libmachine.Host{}
|
|
swarmMasters := getSwarmMasters(hosts)
|
|
|
|
for _, h := range hosts {
|
|
if filterHost(h, filters, swarmMasters) {
|
|
filteredHosts = append(filteredHosts, h)
|
|
}
|
|
}
|
|
return filteredHosts
|
|
}
|
|
|
|
func getSwarmMasters(hosts []*libmachine.Host) map[string]string {
|
|
swarmMasters := make(map[string]string)
|
|
for _, h := range hosts {
|
|
swarmOptions := h.HostOptions.SwarmOptions
|
|
if swarmOptions != nil && swarmOptions.Master {
|
|
swarmMasters[swarmOptions.Discovery] = h.Name
|
|
}
|
|
}
|
|
return swarmMasters
|
|
}
|
|
|
|
func filterHost(host *libmachine.Host, filters FilterOptions, swarmMasters map[string]string) bool {
|
|
swarmMatches := matchesSwarmName(host, filters.SwarmName, swarmMasters)
|
|
driverMatches := matchesDriverName(host, filters.DriverName)
|
|
stateMatches := matchesState(host, filters.State)
|
|
|
|
return swarmMatches && driverMatches && stateMatches
|
|
}
|
|
|
|
func matchesSwarmName(host *libmachine.Host, swarmNames []string, swarmMasters map[string]string) bool {
|
|
if len(swarmNames) == 0 {
|
|
return true
|
|
}
|
|
for _, n := range swarmNames {
|
|
if host.HostOptions.SwarmOptions != nil {
|
|
if n == swarmMasters[host.HostOptions.SwarmOptions.Discovery] {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func matchesDriverName(host *libmachine.Host, driverNames []string) bool {
|
|
if len(driverNames) == 0 {
|
|
return true
|
|
}
|
|
for _, n := range driverNames {
|
|
if host.DriverName == n {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func matchesState(host *libmachine.Host, states []string) bool {
|
|
if len(states) == 0 {
|
|
return true
|
|
}
|
|
for _, n := range states {
|
|
s, err := host.Driver.GetState()
|
|
if err != nil {
|
|
log.Warn(err)
|
|
}
|
|
if n == s.String() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|