|
|
|
@ -87,7 +87,7 @@ func getClusterDir(name string) (string, error) { |
|
|
|
|
|
|
|
|
|
// printClusters prints the names of existing clusters
|
|
|
|
|
func printClusters(all bool) { |
|
|
|
|
clusters, err := getClusters() |
|
|
|
|
clusters, err := getClusters(true, "") |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("ERROR: Couldn't list clusters\n%+v", err) |
|
|
|
|
} |
|
|
|
@ -100,7 +100,7 @@ func printClusters(all bool) { |
|
|
|
|
table.SetAlignment(tablewriter.ALIGN_CENTER) |
|
|
|
|
table.SetHeader([]string{"NAME", "IMAGE", "STATUS", "WORKERS"}) |
|
|
|
|
|
|
|
|
|
tableEmpty := true; |
|
|
|
|
tableEmpty := true |
|
|
|
|
|
|
|
|
|
for _, cluster := range clusters { |
|
|
|
|
workersRunning := 0 |
|
|
|
@ -123,7 +123,7 @@ func printClusters(all bool) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Classify cluster state: Running, Stopped or Abnormal
|
|
|
|
|
func getClusterStatus(server types.Container, workers []types.Container) (string) { |
|
|
|
|
func getClusterStatus(server types.Container, workers []types.Container) string { |
|
|
|
|
// The cluster is in the abnromal state when server state and the worker
|
|
|
|
|
// states don't agree.
|
|
|
|
|
for _, w := range workers { |
|
|
|
@ -133,17 +133,19 @@ func getClusterStatus(server types.Container, workers []types.Container) (string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch server.State { |
|
|
|
|
case "exited": // All containers in this state are most likely
|
|
|
|
|
// as the result of running the "k3d stop" command.
|
|
|
|
|
case "exited": // All containers in this state are most likely
|
|
|
|
|
// as the result of running the "k3d stop" command.
|
|
|
|
|
return "stopped" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return server.State |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// getClusters uses the docker API to get existing clusters and compares that with the list of cluster directories
|
|
|
|
|
func getClusters() (map[string]cluster, error) { |
|
|
|
|
// When 'all' is true, 'cluster' contains all clusters found from the docker daemon
|
|
|
|
|
// When 'all' is false, 'cluster' contains up to one cluster whose name matches 'name'. 'cluster' can
|
|
|
|
|
// be empty if no matching cluster is found.
|
|
|
|
|
func getClusters(all bool, name string) (map[string]cluster, error) { |
|
|
|
|
ctx := context.Background() |
|
|
|
|
docker, err := client.NewEnvClient() |
|
|
|
|
if err != nil { |
|
|
|
@ -172,40 +174,41 @@ func getClusters() (map[string]cluster, error) { |
|
|
|
|
|
|
|
|
|
// for all servers created by k3d, get workers and cluster information
|
|
|
|
|
for _, server := range k3dServers { |
|
|
|
|
filters.Add("label", fmt.Sprintf("cluster=%s", server.Labels["cluster"])) |
|
|
|
|
clusterName := server.Labels["cluster"] |
|
|
|
|
|
|
|
|
|
// get workers
|
|
|
|
|
workers, err := docker.ContainerList(ctx, types.ContainerListOptions{ |
|
|
|
|
All: true, |
|
|
|
|
Filters: filters, |
|
|
|
|
}) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("WARNING: couldn't get worker containers for cluster %s\n%+v", clusterName, err) |
|
|
|
|
} |
|
|
|
|
// Skip the cluster if we don't want all of them, and
|
|
|
|
|
// the cluster name does not match.
|
|
|
|
|
if all || name == clusterName { |
|
|
|
|
|
|
|
|
|
// save cluster information
|
|
|
|
|
serverPorts := []string{} |
|
|
|
|
for _, port := range server.Ports { |
|
|
|
|
serverPorts = append(serverPorts, strconv.Itoa(int(port.PublicPort))) |
|
|
|
|
} |
|
|
|
|
clusters[clusterName] = cluster{ |
|
|
|
|
name: clusterName, |
|
|
|
|
image: server.Image, |
|
|
|
|
status: getClusterStatus(server, workers), |
|
|
|
|
serverPorts: serverPorts, |
|
|
|
|
server: server, |
|
|
|
|
workers: workers, |
|
|
|
|
// Add the cluster
|
|
|
|
|
filters.Add("label", fmt.Sprintf("cluster=%s", clusterName)) |
|
|
|
|
|
|
|
|
|
// get workers
|
|
|
|
|
workers, err := docker.ContainerList(ctx, types.ContainerListOptions{ |
|
|
|
|
All: true, |
|
|
|
|
Filters: filters, |
|
|
|
|
}) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("WARNING: couldn't get worker containers for cluster %s\n%+v", clusterName, err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// save cluster information
|
|
|
|
|
serverPorts := []string{} |
|
|
|
|
for _, port := range server.Ports { |
|
|
|
|
serverPorts = append(serverPorts, strconv.Itoa(int(port.PublicPort))) |
|
|
|
|
} |
|
|
|
|
clusters[clusterName] = cluster{ |
|
|
|
|
name: clusterName, |
|
|
|
|
image: server.Image, |
|
|
|
|
status: getClusterStatus(server, workers), |
|
|
|
|
serverPorts: serverPorts, |
|
|
|
|
server: server, |
|
|
|
|
workers: workers, |
|
|
|
|
} |
|
|
|
|
// clear label filters before searching for next cluster
|
|
|
|
|
filters.Del("label", fmt.Sprintf("cluster=%s", clusterName)) |
|
|
|
|
} |
|
|
|
|
// clear label filters before searching for next cluster
|
|
|
|
|
filters.Del("label", fmt.Sprintf("cluster=%s", clusterName)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return clusters, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// getCluster creates a cluster struct with populated information fields
|
|
|
|
|
func getCluster(name string) (cluster, error) { |
|
|
|
|
clusters, err := getClusters() |
|
|
|
|
return clusters[name], err |
|
|
|
|
} |
|
|
|
|