improve cluster handling via struct and add --all flag to commands

This commit is contained in:
iwilltry42 2019-04-09 09:16:09 +02:00
parent 7d97744c79
commit 476e3de625
2 changed files with 121 additions and 32 deletions

View File

@ -12,6 +12,12 @@ import (
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
) )
type cluster struct {
name string
image string
status string
}
// createDirIfNotExists checks for the existence of a directory and creates it along with all required parents if not. // createDirIfNotExists checks for the existence of a directory and creates it along with all required parents if not.
// It returns an error if the directory (or parents) couldn't be created and nil if it worked fine or if the path already exists. // It returns an error if the directory (or parents) couldn't be created and nil if it worked fine or if the path already exists.
func createDirIfNotExists(path string) error { func createDirIfNotExists(path string) error {
@ -50,30 +56,30 @@ func getClusterDir(name string) (string, error) {
// printClusters prints the names of existing clusters // printClusters prints the names of existing clusters
func printClusters(all bool) { func printClusters(all bool) {
clusters, err := getClusters() clusterNames, err := getClusterNames()
if err != nil { if err != nil {
log.Fatalf("ERROR: Couldn't list clusters -> %+v", err) log.Fatalf("ERROR: Couldn't list clusters -> %+v", err)
} }
docker, err := dockerClient.NewEnvClient() if len(clusterNames) == 0 {
if err != nil { log.Printf("No clusters found!")
log.Printf("WARNING: couldn't get docker info -> %+v", err) return
} }
table := tablewriter.NewWriter(os.Stdout) table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"NAME", "IMAGE", "STATUS"}) table.SetHeader([]string{"NAME", "IMAGE", "STATUS"})
for _, cluster := range clusters { for _, clusterName := range clusterNames {
containerInfo, _ := docker.ContainerInspect(context.Background(), cluster) cluster, _ := getCluster(clusterName)
clusterData := []string{cluster, containerInfo.Config.Image, containerInfo.ContainerJSONBase.State.Status} clusterData := []string{cluster.name, cluster.image, cluster.status}
if containerInfo.ContainerJSONBase.State.Status == "running" || all { if cluster.status == "running" || all {
table.Append(clusterData) table.Append(clusterData)
} }
} }
table.Render() table.Render()
} }
// getClusters returns a list of cluster names which are folder names in the config directory // getClusterNames returns a list of cluster names which are folder names in the config directory
func getClusters() ([]string, error) { func getClusterNames() ([]string, error) {
homeDir, err := homedir.Dir() homeDir, err := homedir.Dir()
if err != nil { if err != nil {
log.Printf("ERROR: Couldn't get user's home directory") log.Printf("ERROR: Couldn't get user's home directory")
@ -93,3 +99,26 @@ func getClusters() ([]string, error) {
} }
return clusters, nil return clusters, nil
} }
// getCluster creates a cluster struct with populated information fields
func getCluster(name string) (cluster, error) {
cluster := cluster{
name: name,
image: "UNKNOWN",
status: "UNKNOWN",
}
docker, err := dockerClient.NewEnvClient()
if err != nil {
log.Printf("ERROR: couldn't create docker client -> %+v", err)
return cluster, err
}
containerInfo, err := docker.ContainerInspect(context.Background(), cluster.name)
if err != nil {
log.Printf("WARNING: couldn't get docker info for [%s] -> %+v", cluster.name, err)
} else {
cluster.image = containerInfo.Config.Image
cluster.status = containerInfo.ContainerJSONBase.State.Status
}
return cluster, nil
}

104
main.go
View File

@ -52,44 +52,104 @@ kubectl cluster-info`, os.Args[0], c.String("name"))
// deleteCluster removes the cluster container and its cluster directory // deleteCluster removes the cluster container and its cluster directory
func deleteCluster(c *cli.Context) error { func deleteCluster(c *cli.Context) error {
cmd := "docker" cmd := "docker"
args := []string{"rm", c.String("name")} args := []string{"rm"}
log.Printf("Deleting cluster [%s]", c.String("name")) clusters := []string{}
if err := run(true, cmd, args...); err != nil {
log.Printf("WARNING: couldn't delete cluster [%s], trying a force remove now.", c.String("name")) // operate on one or all clusters
args = append(args, "-f") if !c.Bool("all") {
if err := run(true, cmd, args...); err != nil { clusters = append(clusters, c.String("name"))
log.Fatalf("FAILURE: couldn't delete cluster [%s] -> %+v", c.String("name"), err) } else {
return err clusterList, err := getClusterNames()
if err != nil {
log.Fatalf("ERROR: `--all` specified, but no clusters were found.")
} }
clusters = append(clusters, clusterList...)
} }
deleteClusterDir(c.String("name"))
log.Printf("SUCCESS: deleted cluster [%s]", c.String("name")) // remove clusters one by one instead of appending all names to the docker command
// this allows for more granular error handling and logging
for _, cluster := range clusters {
log.Printf("Removing cluster [%s]", cluster)
args = append(args, cluster)
if err := run(true, cmd, args...); err != nil {
log.Printf("WARNING: couldn't delete cluster [%s], trying a force remove now.", cluster)
args = args[:len(args)-1] // pop last element from list (name of cluster)
args = append(args, "-f", cluster)
if err := run(true, cmd, args...); err != nil {
log.Printf("FAILURE: couldn't delete cluster [%s] -> %+v", cluster, err)
}
args = args[:len(args)-1] // pop last element from list (-f flag)
}
deleteClusterDir(cluster)
log.Printf("SUCCESS: removed cluster [%s]", cluster)
args = args[:len(args)-1] // pop last element from list (name of last cluster)
}
return nil return nil
} }
// stopCluster stops a running cluster container (restartable) // stopCluster stops a running cluster container (restartable)
func stopCluster(c *cli.Context) error { func stopCluster(c *cli.Context) error {
cmd := "docker" cmd := "docker"
args := []string{"stop", c.String("name")} args := []string{"stop"}
log.Printf("Stopping cluster [%s]", c.String("name")) clusters := []string{}
if err := run(true, cmd, args...); err != nil {
log.Fatalf("FAILURE: couldn't stop cluster [%s] -> %+v", c.String("name"), err) // operate on one or all clusters
return err if !c.Bool("all") {
clusters = append(clusters, c.String("name"))
} else {
clusterList, err := getClusterNames()
if err != nil {
log.Fatalf("ERROR: `--all` specified, but no clusters were found.")
}
clusters = append(clusters, clusterList...)
} }
log.Printf("SUCCESS: stopped cluster [%s]", c.String("name"))
// stop clusters one by one instead of appending all names to the docker command
// this allows for more granular error handling and logging
for _, cluster := range clusters {
log.Printf("Starting cluster [%s]", cluster)
args = append(args, cluster)
if err := run(true, cmd, args...); err != nil {
log.Printf("FAILURE: couldn't stop cluster [%s] -> %+v", cluster, err)
}
log.Printf("SUCCESS: stopped cluster [%s]", cluster)
args = args[:len(args)-1] // pop last element from list (name of last cluster)
}
return nil return nil
} }
// startCluster starts a stopped cluster container // startCluster starts a stopped cluster container
func startCluster(c *cli.Context) error { func startCluster(c *cli.Context) error {
cmd := "docker" cmd := "docker"
args := []string{"start", c.String("name")} args := []string{"start"}
log.Printf("Starting cluster [%s]", c.String("name")) clusters := []string{}
if err := run(true, cmd, args...); err != nil {
log.Fatalf("FAILURE: couldn't start cluster [%s] -> %+v", c.String("name"), err) // operate on one or all clusters
return err if !c.Bool("all") {
clusters = append(clusters, c.String("name"))
} else {
clusterList, err := getClusterNames()
if err != nil {
log.Fatalf("ERROR: `--all` specified, but no clusters were found.")
}
clusters = append(clusters, clusterList...)
} }
log.Printf("SUCCESS: started cluster [%s]", c.String("name"))
// start clusters one by one instead of appending all names to the docker command
// this allows for more granular error handling and logging
for _, cluster := range clusters {
log.Printf("Starting cluster [%s]", cluster)
args = append(args, cluster)
if err := run(true, cmd, args...); err != nil {
log.Printf("FAILURE: couldn't start cluster [%s] -> %+v", cluster, err)
}
log.Printf("SUCCESS: started cluster [%s]", cluster)
args = args[:len(args)-1] // pop last element from list (name of last cluster)
}
return nil return nil
} }