Merge pull request #5 from iwilltry42/development
Tested changes and improved error logs
This commit is contained in:
commit
45eb460f72
12
Makefile
12
Makefile
@ -4,21 +4,27 @@ SHELL := /bin/bash
|
|||||||
TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 windows/amd64
|
TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 windows/amd64
|
||||||
TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256
|
TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256
|
||||||
|
|
||||||
|
# get git tag
|
||||||
|
GIT_TAG := $(shell git describe --tags)
|
||||||
|
ifeq ($(GIT_TAG),)
|
||||||
|
GIT_TAG := $(shell git describe --always)
|
||||||
|
endif
|
||||||
|
|
||||||
# Go options
|
# Go options
|
||||||
GO ?= go
|
GO ?= go
|
||||||
PKG := $(shell go mod vendor)
|
PKG := $(shell go mod vendor)
|
||||||
TAGS :=
|
TAGS :=
|
||||||
TESTS := .
|
TESTS := .
|
||||||
TESTFLAGS :=
|
TESTFLAGS :=
|
||||||
LDFLAGS := -w -s
|
LDFLAGS := -w -s -X github.com/iwilltry42/k3d-go/version.Version=${GIT_TAG}
|
||||||
GOFLAGS :=
|
GOFLAGS :=
|
||||||
BINDIR := $(CURDIR)/bin
|
BINDIR := $(CURDIR)/bin
|
||||||
BINARIES := k3d
|
BINARIES := k3d
|
||||||
|
|
||||||
export GO111MODULE=on
|
export GO111MODULE=on
|
||||||
|
|
||||||
# go source files, ignore vendor directory
|
# go source files, ignore vendor directory
|
||||||
SRC = $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
SRC = $(shell find . -type f -name '*.go' -not -path "./*/*")
|
||||||
|
|
||||||
.PHONY: all build build-cross clean fmt simplify check
|
.PHONY: all build build-cross clean fmt simplify check
|
||||||
|
|
||||||
|
217
cli/commands.go
Normal file
217
cli/commands.go
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
package run
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CheckTools checks if the installed tools work correctly
|
||||||
|
func CheckTools(c *cli.Context) error {
|
||||||
|
log.Print("Checking docker...")
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{"version"}
|
||||||
|
if err := runCommand(true, cmd, args...); err != nil {
|
||||||
|
return fmt.Errorf("ERROR: checking docker failed\n%+v", err)
|
||||||
|
}
|
||||||
|
log.Println("SUCCESS: Checking docker succeeded")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateCluster creates a new single-node cluster container and initializes the cluster directory
|
||||||
|
func CreateCluster(c *cli.Context) error {
|
||||||
|
if c.IsSet("timeout") && !c.IsSet("wait") {
|
||||||
|
return errors.New("Cannot use --timeout flag without --wait flag")
|
||||||
|
}
|
||||||
|
port := fmt.Sprintf("%s:%s", c.String("port"), c.String("port"))
|
||||||
|
image := fmt.Sprintf("rancher/k3s:%s", c.String("version"))
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{
|
||||||
|
"run",
|
||||||
|
"--name", c.String("name"),
|
||||||
|
"-e", "K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml",
|
||||||
|
"--publish", port,
|
||||||
|
"--privileged",
|
||||||
|
}
|
||||||
|
extraArgs := []string{}
|
||||||
|
if c.IsSet("volume") {
|
||||||
|
extraArgs = append(extraArgs, "--volume", c.String("volume"))
|
||||||
|
}
|
||||||
|
if len(extraArgs) > 0 {
|
||||||
|
args = append(args, extraArgs...)
|
||||||
|
}
|
||||||
|
args = append(args,
|
||||||
|
"-d",
|
||||||
|
image,
|
||||||
|
"server", // cmd
|
||||||
|
"--https-listen-port", c.String("port"), //args
|
||||||
|
)
|
||||||
|
log.Printf("Creating cluster [%s]", c.String("name"))
|
||||||
|
if err := runCommand(true, cmd, args...); err != nil {
|
||||||
|
return fmt.Errorf("ERROR: couldn't create cluster [%s]\n%+v", c.String("name"), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
timeout := time.Duration(c.Int("timeout")) * time.Second
|
||||||
|
for c.IsSet("wait") {
|
||||||
|
if timeout != 0 && !time.Now().After(start.Add(timeout)) {
|
||||||
|
err := DeleteCluster(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return errors.New("Cluster creation exceeded specified timeout")
|
||||||
|
}
|
||||||
|
cmd := "docker"
|
||||||
|
args = []string{
|
||||||
|
"logs",
|
||||||
|
c.String("name"),
|
||||||
|
}
|
||||||
|
prog := exec.Command(cmd, args...)
|
||||||
|
output, err := prog.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if strings.Contains(string(output), "Running kubelet") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
createClusterDir(c.String("name"))
|
||||||
|
log.Printf("SUCCESS: created cluster [%s]", c.String("name"))
|
||||||
|
log.Printf(`You can now use the cluster with:
|
||||||
|
|
||||||
|
export KUBECONFIG="$(%s get-kubeconfig --name='%s')"
|
||||||
|
kubectl cluster-info`, os.Args[0], c.String("name"))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCluster removes the cluster container and its cluster directory
|
||||||
|
func DeleteCluster(c *cli.Context) error {
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{"rm"}
|
||||||
|
clusters := []string{}
|
||||||
|
|
||||||
|
// operate on one or all clusters
|
||||||
|
if !c.Bool("all") {
|
||||||
|
clusters = append(clusters, c.String("name"))
|
||||||
|
} else {
|
||||||
|
clusterList, err := getClusterNames()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ERROR: `--all` specified, but no clusters were found\n%+v", err)
|
||||||
|
}
|
||||||
|
clusters = append(clusters, clusterList...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 := runCommand(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 := runCommand(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
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopCluster stops a running cluster container (restartable)
|
||||||
|
func StopCluster(c *cli.Context) error {
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{"stop"}
|
||||||
|
clusters := []string{}
|
||||||
|
|
||||||
|
// operate on one or all clusters
|
||||||
|
if !c.Bool("all") {
|
||||||
|
clusters = append(clusters, c.String("name"))
|
||||||
|
} else {
|
||||||
|
clusterList, err := getClusterNames()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ERROR: `--all` specified, but no clusters were found\n%+v", err)
|
||||||
|
}
|
||||||
|
clusters = append(clusters, clusterList...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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("Stopping cluster [%s]", cluster)
|
||||||
|
args = append(args, cluster)
|
||||||
|
if err := runCommand(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
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartCluster starts a stopped cluster container
|
||||||
|
func StartCluster(c *cli.Context) error {
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{"start"}
|
||||||
|
clusters := []string{}
|
||||||
|
|
||||||
|
// operate on one or all clusters
|
||||||
|
if !c.Bool("all") {
|
||||||
|
clusters = append(clusters, c.String("name"))
|
||||||
|
} else {
|
||||||
|
clusterList, err := getClusterNames()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ERROR: `--all` specified, but no clusters were found\n%+v", err)
|
||||||
|
}
|
||||||
|
clusters = append(clusters, clusterList...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 := runCommand(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
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListClusters prints a list of created clusters
|
||||||
|
func ListClusters(c *cli.Context) error {
|
||||||
|
printClusters(c.Bool("all"))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKubeConfig grabs the kubeconfig from the running cluster and prints the path to stdout
|
||||||
|
func GetKubeConfig(c *cli.Context) error {
|
||||||
|
sourcePath := fmt.Sprintf("%s:/output/kubeconfig.yaml", c.String("name"))
|
||||||
|
destPath, _ := getClusterDir(c.String("name"))
|
||||||
|
cmd := "docker"
|
||||||
|
args := []string{"cp", sourcePath, destPath}
|
||||||
|
if err := runCommand(false, cmd, args...); err != nil {
|
||||||
|
return fmt.Errorf("ERROR: Couldn't get kubeconfig for cluster [%s]\n%+v", c.String("name"), err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", path.Join(destPath, "kubeconfig.yaml"))
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package run
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -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
|
||||||
|
}
|
18
cli/run.go
Normal file
18
cli/run.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package run
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
// runCommand accepts the name and args and runs the specified command
|
||||||
|
func runCommand(verbose bool, name string, args ...string) error {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Running command: %+v", append([]string{name}, args...))
|
||||||
|
}
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
171
main.go
171
main.go
@ -1,118 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
|
"github.com/iwilltry42/k3d-go/cli"
|
||||||
|
"github.com/iwilltry42/k3d-go/version"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// createCluster creates a new single-node cluster container and initializes the cluster directory
|
|
||||||
func createCluster(c *cli.Context) error {
|
|
||||||
createClusterDir(c.String("name"))
|
|
||||||
port := fmt.Sprintf("%s:%s", c.String("port"), c.String("port"))
|
|
||||||
image := fmt.Sprintf("rancher/k3s:%s", c.String("version"))
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{
|
|
||||||
"run",
|
|
||||||
"--name", c.String("name"),
|
|
||||||
"-e", "K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml",
|
|
||||||
"--publish", port,
|
|
||||||
"--privileged",
|
|
||||||
}
|
|
||||||
extraArgs := []string{}
|
|
||||||
if c.IsSet("volume") {
|
|
||||||
extraArgs = append(extraArgs, "--volume", c.String("volume"))
|
|
||||||
}
|
|
||||||
if len(extraArgs) > 0 {
|
|
||||||
args = append(args, extraArgs...)
|
|
||||||
}
|
|
||||||
args = append(args,
|
|
||||||
"-d",
|
|
||||||
image,
|
|
||||||
"server", // cmd
|
|
||||||
"--https-listen-port", c.String("port"), //args
|
|
||||||
)
|
|
||||||
log.Printf("Creating cluster [%s]", c.String("name"))
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("FAILURE: couldn't create cluster [%s] -> %+v", c.String("name"), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("SUCCESS: created cluster [%s]", c.String("name"))
|
|
||||||
log.Printf(`You can now use the cluster with:
|
|
||||||
|
|
||||||
export KUBECONFIG="$(%s get-kubeconfig --name='%s')"
|
|
||||||
kubectl cluster-info`, os.Args[0], c.String("name"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// deleteCluster removes the cluster container and its cluster directory
|
|
||||||
func deleteCluster(c *cli.Context) error {
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{"rm", c.String("name")}
|
|
||||||
log.Printf("Deleting cluster [%s]", c.String("name"))
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Printf("WARNING: couldn't delete cluster [%s], trying a force remove now.", c.String("name"))
|
|
||||||
args = append(args, "-f")
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("FAILURE: couldn't delete cluster [%s] -> %+v", c.String("name"), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deleteClusterDir(c.String("name"))
|
|
||||||
log.Printf("SUCCESS: deleted cluster [%s]", c.String("name"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// stopCluster stops a running cluster container (restartable)
|
|
||||||
func stopCluster(c *cli.Context) error {
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{"stop", c.String("name")}
|
|
||||||
log.Printf("Stopping cluster [%s]", c.String("name"))
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("FAILURE: couldn't stop cluster [%s] -> %+v", c.String("name"), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("SUCCESS: stopped cluster [%s]", c.String("name"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// startCluster starts a stopped cluster container
|
|
||||||
func startCluster(c *cli.Context) error {
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{"start", c.String("name")}
|
|
||||||
log.Printf("Starting cluster [%s]", c.String("name"))
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("FAILURE: couldn't start cluster [%s] -> %+v", c.String("name"), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("SUCCESS: started cluster [%s]", c.String("name"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// listClusters prints a list of created clusters
|
|
||||||
func listClusters(c *cli.Context) error {
|
|
||||||
printClusters(c.Bool("all"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getKubeConfig grabs the kubeconfig from the running cluster and prints the path to stdout
|
|
||||||
func getKubeConfig(c *cli.Context) error {
|
|
||||||
sourcePath := fmt.Sprintf("%s:/output/kubeconfig.yaml", c.String("name"))
|
|
||||||
destPath, _ := getClusterDir(c.String("name"))
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{"cp", sourcePath, destPath}
|
|
||||||
if err := run(false, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("FAILURE: couldn't get kubeconfig for cluster [%s] -> %+v", c.String("name"), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("%s\n", path.Join(destPath, "kubeconfig.yaml"))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// main represents the CLI application
|
// main represents the CLI application
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
@ -120,7 +16,7 @@ func main() {
|
|||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Name = "k3d"
|
app.Name = "k3d"
|
||||||
app.Usage = "Run k3s in Docker!"
|
app.Usage = "Run k3s in Docker!"
|
||||||
app.Version = "v0.1.1"
|
app.Version = version.GetVersion()
|
||||||
app.Authors = []cli.Author{
|
app.Authors = []cli.Author{
|
||||||
cli.Author{
|
cli.Author{
|
||||||
Name: "iwilltry42",
|
Name: "iwilltry42",
|
||||||
@ -135,17 +31,7 @@ func main() {
|
|||||||
Name: "check-tools",
|
Name: "check-tools",
|
||||||
Aliases: []string{"ct"},
|
Aliases: []string{"ct"},
|
||||||
Usage: "Check if docker is running",
|
Usage: "Check if docker is running",
|
||||||
Action: func(c *cli.Context) error {
|
Action: run.CheckTools,
|
||||||
log.Print("Checking docker...")
|
|
||||||
cmd := "docker"
|
|
||||||
args := []string{"version"}
|
|
||||||
if err := run(true, cmd, args...); err != nil {
|
|
||||||
log.Fatalf("Checking docker: FAILED")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Println("Checking docker: SUCCESS")
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// create creates a new k3s cluster in a container
|
// create creates a new k3s cluster in a container
|
||||||
@ -160,7 +46,7 @@ func main() {
|
|||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "volume, v",
|
Name: "volume, v",
|
||||||
Usage: "Mount a volume into the cluster node (Docker notation: `source:destination`",
|
Usage: "Mount a volume into the cluster node (Docker notation: `source:destination`)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
@ -172,8 +58,17 @@ func main() {
|
|||||||
Value: 6443,
|
Value: 6443,
|
||||||
Usage: "Set a port on which the ApiServer will listen",
|
Usage: "Set a port on which the ApiServer will listen",
|
||||||
},
|
},
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "timeout, t",
|
||||||
|
Value: 0,
|
||||||
|
Usage: "Set the timeout value when --wait flag is set",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "wait, w",
|
||||||
|
Usage: "Wait for the cluster to come up",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: createCluster,
|
Action: run.CreateCluster,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// delete deletes an existing k3s cluster (remove container and cluster directory)
|
// delete deletes an existing k3s cluster (remove container and cluster directory)
|
||||||
@ -186,8 +81,12 @@ func main() {
|
|||||||
Value: "k3s_default",
|
Value: "k3s_default",
|
||||||
Usage: "name of the cluster",
|
Usage: "name of the cluster",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all, a",
|
||||||
|
Usage: "delete all existing clusters (this ignores the --name/-n flag)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: deleteCluster,
|
Action: run.DeleteCluster,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// stop stopy a running cluster (its container) so it's restartable
|
// stop stopy a running cluster (its container) so it's restartable
|
||||||
@ -199,8 +98,12 @@ func main() {
|
|||||||
Value: "k3s_default",
|
Value: "k3s_default",
|
||||||
Usage: "name of the cluster",
|
Usage: "name of the cluster",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all, a",
|
||||||
|
Usage: "stop all running clusters (this ignores the --name/-n flag)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: stopCluster,
|
Action: run.StopCluster,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// start restarts a stopped cluster container
|
// start restarts a stopped cluster container
|
||||||
@ -212,8 +115,12 @@ func main() {
|
|||||||
Value: "k3s_default",
|
Value: "k3s_default",
|
||||||
Usage: "name of the cluster",
|
Usage: "name of the cluster",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all, a",
|
||||||
|
Usage: "start all stopped clusters (this ignores the --name/-n flag)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: startCluster,
|
Action: run.StartCluster,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// list prints a list of created clusters
|
// list prints a list of created clusters
|
||||||
@ -226,7 +133,7 @@ func main() {
|
|||||||
Usage: "also show non-running clusters",
|
Usage: "also show non-running clusters",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: listClusters,
|
Action: run.ListClusters,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// get-kubeconfig grabs the kubeconfig from the cluster and prints the path to it
|
// get-kubeconfig grabs the kubeconfig from the cluster and prints the path to it
|
||||||
@ -238,8 +145,12 @@ func main() {
|
|||||||
Value: "k3s_default",
|
Value: "k3s_default",
|
||||||
Usage: "name of the cluster",
|
Usage: "name of the cluster",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all, a",
|
||||||
|
Usage: "get kubeconfig for all clusters (this ignores the --name/-n flag)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: getKubeConfig,
|
Action: run.GetKubeConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,13 +160,3 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(verbose bool, name string, args ...string) error {
|
|
||||||
if verbose {
|
|
||||||
log.Printf("Running command: %+v", append([]string{name}, args...))
|
|
||||||
}
|
|
||||||
cmd := exec.Command(name, args...)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
|
12
version/version.go
Normal file
12
version/version.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package version
|
||||||
|
|
||||||
|
// Version is the string that contains version
|
||||||
|
var Version string
|
||||||
|
|
||||||
|
// GetVersion returns the version for cli, it gets it from "git describe --tags" or returns "dev" when doing simple go build
|
||||||
|
func GetVersion() string {
|
||||||
|
if len(Version) == 0 {
|
||||||
|
return "dev"
|
||||||
|
}
|
||||||
|
return Version
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user