mirror of https://github.com/k3d-io/k3d
parent
9c65d7bac6
commit
594ead1428
@ -1,53 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package create |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdCreate returns a new cobra command
|
|
||||||
func NewCmdCreate() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "create", |
|
||||||
Short: "Create a resource [cluster, node].", |
|
||||||
Long: `Create a resource [cluster, node].`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdCreateCluster()) |
|
||||||
cmd.AddCommand(NewCmdCreateNode()) |
|
||||||
|
|
||||||
// add flags
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,408 +0,0 @@ |
|||||||
/*Package create ... |
|
||||||
|
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package create |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
"runtime" |
|
||||||
"time" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
cliutil "github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
k3dCluster "github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/rancher/k3d/v3/version" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
const createClusterDescription = ` |
|
||||||
Create a new k3s cluster with containerized nodes (k3s in docker). |
|
||||||
Every cluster will consist of at least 2 containers: |
|
||||||
- 1 master node container (k3s) |
|
||||||
- 1 loadbalancer container as the entrypoint to the cluster (nginx) |
|
||||||
` |
|
||||||
|
|
||||||
// NewCmdCreateCluster returns a new cobra command
|
|
||||||
func NewCmdCreateCluster() *cobra.Command { |
|
||||||
|
|
||||||
createClusterOpts := &k3d.CreateClusterOpts{} |
|
||||||
var updateKubeconfig, updateCurrentContext bool |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "cluster NAME", |
|
||||||
Short: "Create a new k3s cluster in docker", |
|
||||||
Long: createClusterDescription, |
|
||||||
Args: cobra.RangeArgs(0, 1), // exactly one cluster name can be set (default: k3d.DefaultClusterName)
|
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
// parse args and flags
|
|
||||||
cluster := parseCreateClusterCmd(cmd, args, createClusterOpts) |
|
||||||
|
|
||||||
// check if a cluster with that name exists already
|
|
||||||
if _, err := k3dCluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, cluster); err == nil { |
|
||||||
log.Fatalf("Failed to create cluster '%s' because a cluster with that name already exists", cluster.Name) |
|
||||||
} |
|
||||||
|
|
||||||
// create cluster
|
|
||||||
if updateKubeconfig || updateCurrentContext { |
|
||||||
log.Debugln("'--update-kubeconfig set: enabling wait-for-master") |
|
||||||
cluster.CreateClusterOpts.WaitForMaster = true |
|
||||||
} |
|
||||||
if err := k3dCluster.CreateCluster(cmd.Context(), runtimes.SelectedRuntime, cluster); err != nil { |
|
||||||
// rollback if creation failed
|
|
||||||
log.Errorln(err) |
|
||||||
log.Errorln("Failed to create cluster >>> Rolling Back") |
|
||||||
if err := k3dCluster.DeleteCluster(cmd.Context(), runtimes.SelectedRuntime, cluster); err != nil { |
|
||||||
log.Errorln(err) |
|
||||||
log.Fatalln("Cluster creation FAILED, also FAILED to rollback changes!") |
|
||||||
} |
|
||||||
log.Fatalln("Cluster creation FAILED, all changes have been rolled back!") |
|
||||||
} |
|
||||||
log.Infof("Cluster '%s' created successfully!", cluster.Name) |
|
||||||
|
|
||||||
if updateKubeconfig || updateCurrentContext { |
|
||||||
log.Debugf("Updating default kubeconfig with a new context for cluster %s", cluster.Name) |
|
||||||
if _, err := k3dCluster.GetAndWriteKubeConfig(cmd.Context(), runtimes.SelectedRuntime, cluster, "", &k3dCluster.WriteKubeConfigOptions{UpdateExisting: true, OverwriteExisting: false, UpdateCurrentContext: updateCurrentContext}); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// print information on how to use the cluster with kubectl
|
|
||||||
log.Infoln("You can now use it like this:") |
|
||||||
if updateKubeconfig && !updateCurrentContext { |
|
||||||
fmt.Printf("kubectl config use-context %s\n", fmt.Sprintf("%s-%s", k3d.DefaultObjectNamePrefix, cluster.Name)) |
|
||||||
} else if !updateCurrentContext { |
|
||||||
if runtime.GOOS == "windows" { |
|
||||||
fmt.Printf("$env:KUBECONFIG=(%s get kubeconfig %s)\n", os.Args[0], cluster.Name) |
|
||||||
} else { |
|
||||||
fmt.Printf("export KUBECONFIG=$(%s get kubeconfig %s)\n", os.Args[0], cluster.Name) |
|
||||||
} |
|
||||||
} |
|
||||||
fmt.Println("kubectl cluster-info") |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
/********* |
|
||||||
* Flags * |
|
||||||
*********/ |
|
||||||
cmd.Flags().StringP("api-port", "a", "random", "Specify the Kubernetes API server port exposed on the LoadBalancer (Format: `--api-port [HOST:]HOSTPORT`)\n - Example: `k3d create -m 3 -a 0.0.0.0:6550`") |
|
||||||
cmd.Flags().IntP("masters", "m", 1, "Specify how many masters you want to create") |
|
||||||
cmd.Flags().IntP("workers", "w", 0, "Specify how many workers you want to create") |
|
||||||
cmd.Flags().StringP("image", "i", fmt.Sprintf("%s:%s", k3d.DefaultK3sImageRepo, version.GetK3sVersion(false)), "Specify k3s image that you want to use for the nodes") |
|
||||||
cmd.Flags().String("network", "", "Join an existing network") |
|
||||||
cmd.Flags().String("token", "", "Specify a cluster token. By default, we generate one.") |
|
||||||
cmd.Flags().StringArrayP("volume", "v", nil, "Mount volumes into the nodes (Format: `--volume [SOURCE:]DEST[@NODEFILTER[;NODEFILTER...]]`\n - Example: `k3d create -w 2 -v /my/path@worker[0,1] -v /tmp/test:/tmp/other@master[0]`") |
|
||||||
cmd.Flags().StringArrayP("port", "p", nil, "Map ports from the node containers to the host (Format: `[HOST:][HOSTPORT:]CONTAINERPORT[/PROTOCOL][@NODEFILTER]`)\n - Example: `k3d create -w 2 -p 8080:80@worker[0] -p 8081@worker[1]`") |
|
||||||
cmd.Flags().BoolVar(&createClusterOpts.WaitForMaster, "wait", true, "Wait for the master(s) to be ready before returning. Use '--timeout DURATION' to not wait forever.") |
|
||||||
cmd.Flags().DurationVar(&createClusterOpts.Timeout, "timeout", 0*time.Second, "Rollback changes if cluster couldn't be created in specified duration.") |
|
||||||
cmd.Flags().BoolVar(&updateKubeconfig, "update-kubeconfig", false, "Directly update the default kubeconfig with the new cluster's context") |
|
||||||
cmd.Flags().BoolVar(&updateCurrentContext, "switch", false, "Directly switch the default kubeconfig's current-context to the new cluster's context (implies --update-kubeconfig)") |
|
||||||
cmd.Flags().BoolVar(&createClusterOpts.DisableLoadBalancer, "no-lb", false, "Disable the creation of a LoadBalancer in front of the master nodes") |
|
||||||
|
|
||||||
/* Image Importing */ |
|
||||||
cmd.Flags().BoolVar(&createClusterOpts.DisableImageVolume, "no-image-volume", false, "Disable the creation of a volume for importing images") |
|
||||||
|
|
||||||
/* Multi Master Configuration */ |
|
||||||
|
|
||||||
// multi-master - datastore
|
|
||||||
// TODO: implement multi-master setups with external data store
|
|
||||||
// cmd.Flags().String("datastore-endpoint", "", "[WIP] Specify external datastore endpoint (e.g. for multi master clusters)")
|
|
||||||
/* |
|
||||||
cmd.Flags().String("datastore-network", "", "Specify container network where we can find the datastore-endpoint (add a connection)") |
|
||||||
|
|
||||||
// TODO: set default paths and hint, that one should simply mount the files using --volume flag
|
|
||||||
cmd.Flags().String("datastore-cafile", "", "Specify external datastore's TLS Certificate Authority (CA) file") |
|
||||||
cmd.Flags().String("datastore-certfile", "", "Specify external datastore's TLS certificate file'") |
|
||||||
cmd.Flags().String("datastore-keyfile", "", "Specify external datastore's TLS key file'") |
|
||||||
*/ |
|
||||||
|
|
||||||
/* k3s */ |
|
||||||
cmd.Flags().StringArrayVar(&createClusterOpts.K3sServerArgs, "k3s-server-arg", nil, "Additional args passed to the `k3s server` command on master nodes (new flag per arg)") |
|
||||||
cmd.Flags().StringArrayVar(&createClusterOpts.K3sAgentArgs, "k3s-agent-arg", nil, "Additional args passed to the `k3s agent` command on worker nodes (new flag per arg)") |
|
||||||
|
|
||||||
/* Subcommands */ |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseCreateClusterCmd parses the command input into variables required to create a cluster
|
|
||||||
func parseCreateClusterCmd(cmd *cobra.Command, args []string, createClusterOpts *k3d.CreateClusterOpts) *k3d.Cluster { |
|
||||||
|
|
||||||
/******************************** |
|
||||||
* Parse and validate arguments * |
|
||||||
********************************/ |
|
||||||
|
|
||||||
clustername := k3d.DefaultClusterName |
|
||||||
if len(args) != 0 { |
|
||||||
clustername = args[0] |
|
||||||
} |
|
||||||
if err := cluster.CheckName(clustername); err != nil { |
|
||||||
log.Fatal(err) |
|
||||||
} |
|
||||||
|
|
||||||
/**************************** |
|
||||||
* Parse and validate flags * |
|
||||||
****************************/ |
|
||||||
|
|
||||||
// --image
|
|
||||||
image, err := cmd.Flags().GetString("image") |
|
||||||
if err != nil { |
|
||||||
log.Errorln("No image specified") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
if image == "latest" { |
|
||||||
image = version.GetK3sVersion(true) |
|
||||||
} |
|
||||||
|
|
||||||
// --masters
|
|
||||||
masterCount, err := cmd.Flags().GetInt("masters") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// --workers
|
|
||||||
workerCount, err := cmd.Flags().GetInt("workers") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// --network
|
|
||||||
networkName, err := cmd.Flags().GetString("network") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
network := k3d.ClusterNetwork{} |
|
||||||
if networkName != "" { |
|
||||||
network.Name = networkName |
|
||||||
network.External = true |
|
||||||
} |
|
||||||
if networkName == "host" && (masterCount+workerCount) > 1 { |
|
||||||
log.Fatalln("Can only run a single node in hostnetwork mode") |
|
||||||
} |
|
||||||
|
|
||||||
// --token
|
|
||||||
token, err := cmd.Flags().GetString("token") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// --timeout
|
|
||||||
if cmd.Flags().Changed("timeout") && createClusterOpts.Timeout <= 0*time.Second { |
|
||||||
log.Fatalln("--timeout DURATION must be >= 1s") |
|
||||||
} |
|
||||||
|
|
||||||
// --api-port
|
|
||||||
apiPort, err := cmd.Flags().GetString("api-port") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// parse the port mapping
|
|
||||||
exposeAPI, err := cliutil.ParseAPIPort(apiPort) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
if exposeAPI.Host == "" { |
|
||||||
exposeAPI.Host = k3d.DefaultAPIHost |
|
||||||
} |
|
||||||
if exposeAPI.HostIP == "" { |
|
||||||
exposeAPI.HostIP = k3d.DefaultAPIHost |
|
||||||
} |
|
||||||
if networkName == "host" { |
|
||||||
// in hostNetwork mode, we're not going to map a hostport. Here it should always use 6443.
|
|
||||||
// Note that hostNetwork mode is super inflexible and since we don't change the backend port (on the container), it will only be one hostmode cluster allowed.
|
|
||||||
exposeAPI.Port = k3d.DefaultAPIPort |
|
||||||
} |
|
||||||
|
|
||||||
// --volume
|
|
||||||
volumeFlags, err := cmd.Flags().GetStringArray("volume") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// volumeFilterMap will map volume mounts to applied node filters
|
|
||||||
volumeFilterMap := make(map[string][]string, 1) |
|
||||||
for _, volumeFlag := range volumeFlags { |
|
||||||
|
|
||||||
// split node filter from the specified volume
|
|
||||||
volume, filters, err := cliutil.SplitFiltersFromFlag(volumeFlag) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// validate the specified volume mount and return it in SRC:DEST format
|
|
||||||
volume, err = cliutil.ValidateVolumeMount(runtimes.SelectedRuntime, volume) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// create new entry or append filter to existing entry
|
|
||||||
if _, exists := volumeFilterMap[volume]; exists { |
|
||||||
volumeFilterMap[volume] = append(volumeFilterMap[volume], filters...) |
|
||||||
} else { |
|
||||||
volumeFilterMap[volume] = filters |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// --port
|
|
||||||
portFlags, err := cmd.Flags().GetStringArray("port") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
portFilterMap := make(map[string][]string, 1) |
|
||||||
for _, portFlag := range portFlags { |
|
||||||
// split node filter from the specified volume
|
|
||||||
portmap, filters, err := cliutil.SplitFiltersFromFlag(portFlag) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
if len(filters) > 1 { |
|
||||||
log.Fatalln("Can only apply a Portmap to one node") |
|
||||||
} |
|
||||||
|
|
||||||
// the same portmapping can't be applied to multiple nodes
|
|
||||||
|
|
||||||
// validate the specified volume mount and return it in SRC:DEST format
|
|
||||||
portmap, err = cliutil.ValidatePortMap(portmap) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// create new entry or append filter to existing entry
|
|
||||||
if _, exists := portFilterMap[portmap]; exists { |
|
||||||
log.Fatalln("Same Portmapping can not be used for multiple nodes") |
|
||||||
} else { |
|
||||||
portFilterMap[portmap] = filters |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
log.Debugf("PortFilterMap: %+v", portFilterMap) |
|
||||||
|
|
||||||
/******************** |
|
||||||
* * |
|
||||||
* generate cluster * |
|
||||||
* * |
|
||||||
********************/ |
|
||||||
|
|
||||||
cluster := &k3d.Cluster{ |
|
||||||
Name: clustername, |
|
||||||
Network: network, |
|
||||||
Token: token, |
|
||||||
CreateClusterOpts: createClusterOpts, |
|
||||||
ExposeAPI: exposeAPI, |
|
||||||
} |
|
||||||
|
|
||||||
// generate list of nodes
|
|
||||||
cluster.Nodes = []*k3d.Node{} |
|
||||||
|
|
||||||
// MasterLoadBalancer
|
|
||||||
if !createClusterOpts.DisableLoadBalancer { |
|
||||||
cluster.MasterLoadBalancer = &k3d.Node{ |
|
||||||
Role: k3d.LoadBalancerRole, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/**************** |
|
||||||
* Master Nodes * |
|
||||||
****************/ |
|
||||||
|
|
||||||
for i := 0; i < masterCount; i++ { |
|
||||||
node := k3d.Node{ |
|
||||||
Role: k3d.MasterRole, |
|
||||||
Image: image, |
|
||||||
Args: createClusterOpts.K3sServerArgs, |
|
||||||
MasterOpts: k3d.MasterOpts{}, |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: by default, we don't expose an API port: should we change that?
|
|
||||||
// -> if we want to change that, simply add the exposeAPI struct here
|
|
||||||
|
|
||||||
// first master node will be init node if we have more than one master specified but no external datastore
|
|
||||||
if i == 0 && masterCount > 1 { |
|
||||||
node.MasterOpts.IsInit = true |
|
||||||
cluster.InitNode = &node |
|
||||||
} |
|
||||||
|
|
||||||
// append node to list
|
|
||||||
cluster.Nodes = append(cluster.Nodes, &node) |
|
||||||
} |
|
||||||
|
|
||||||
/**************** |
|
||||||
* Worker Nodes * |
|
||||||
****************/ |
|
||||||
|
|
||||||
for i := 0; i < workerCount; i++ { |
|
||||||
node := k3d.Node{ |
|
||||||
Role: k3d.WorkerRole, |
|
||||||
Image: image, |
|
||||||
Args: createClusterOpts.K3sAgentArgs, |
|
||||||
} |
|
||||||
|
|
||||||
cluster.Nodes = append(cluster.Nodes, &node) |
|
||||||
} |
|
||||||
|
|
||||||
// append volumes
|
|
||||||
for volume, filters := range volumeFilterMap { |
|
||||||
nodes, err := cliutil.FilterNodes(cluster.Nodes, filters) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
for _, node := range nodes { |
|
||||||
node.Volumes = append(node.Volumes, volume) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// append ports
|
|
||||||
nodeCount := masterCount + workerCount |
|
||||||
nodeList := cluster.Nodes |
|
||||||
if !createClusterOpts.DisableLoadBalancer { |
|
||||||
nodeCount++ |
|
||||||
nodeList = append(nodeList, cluster.MasterLoadBalancer) |
|
||||||
} |
|
||||||
for portmap, filters := range portFilterMap { |
|
||||||
if len(filters) == 0 && (nodeCount) > 1 { |
|
||||||
log.Fatalf("Malformed portmapping '%s' lacks a node filter, but there is more than one node (including the loadbalancer, if there is any).", portmap) |
|
||||||
} |
|
||||||
nodes, err := cliutil.FilterNodes(nodeList, filters) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
for _, node := range nodes { |
|
||||||
node.Ports = append(node.Ports, portmap) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/********************** |
|
||||||
* Utility Containers * |
|
||||||
**********************/ |
|
||||||
// ...
|
|
||||||
|
|
||||||
return cluster |
|
||||||
} |
|
@ -1,133 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package create |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"time" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
k3dc "github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/rancher/k3d/v3/version" |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdCreateNode returns a new cobra command
|
|
||||||
func NewCmdCreateNode() *cobra.Command { |
|
||||||
|
|
||||||
createNodeOpts := k3d.CreateNodeOpts{} |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "node NAME", |
|
||||||
Short: "Create a new k3s node in docker", |
|
||||||
Long: `Create a new containerized k3s node (k3s in docker).`, |
|
||||||
Args: cobra.ExactArgs(1), // exactly one name accepted // TODO: if not specified, inherit from cluster that the node shall belong to, if that is specified
|
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
nodes, cluster := parseCreateNodeCmd(cmd, args) |
|
||||||
if err := k3dc.AddNodesToCluster(cmd.Context(), runtimes.SelectedRuntime, nodes, cluster, createNodeOpts); err != nil { |
|
||||||
log.Errorf("Failed to add nodes to cluster '%s'", cluster.Name) |
|
||||||
log.Errorln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().Int("replicas", 1, "Number of replicas of this node specification.") |
|
||||||
cmd.Flags().String("role", string(k3d.WorkerRole), "Specify node role [master, worker]") |
|
||||||
if err := cmd.RegisterFlagCompletionFunc("role", util.ValidArgsNodeRoles); err != nil { |
|
||||||
log.Fatalln("Failed to register flag completion for '--role'", err) |
|
||||||
} |
|
||||||
cmd.Flags().StringP("cluster", "c", k3d.DefaultClusterName, "Select the cluster that the node shall connect to.") |
|
||||||
if err := cmd.MarkFlagRequired("cluster"); err != nil { |
|
||||||
log.Fatalln("Failed to mark required flag '--cluster'") |
|
||||||
} |
|
||||||
if err := cmd.RegisterFlagCompletionFunc("cluster", util.ValidArgsAvailableClusters); err != nil { |
|
||||||
log.Fatalln("Failed to register flag completion for '--cluster'", err) |
|
||||||
} |
|
||||||
|
|
||||||
cmd.Flags().StringP("image", "i", fmt.Sprintf("%s:%s", k3d.DefaultK3sImageRepo, version.GetK3sVersion(false)), "Specify k3s image used for the node(s)") |
|
||||||
|
|
||||||
cmd.Flags().BoolVar(&createNodeOpts.Wait, "wait", false, "Wait for the node(s) to be ready before returning.") |
|
||||||
cmd.Flags().DurationVar(&createNodeOpts.Timeout, "timeout", 0*time.Second, "Maximum waiting time for '--wait' before canceling/returning.") |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseCreateNodeCmd parses the command input into variables required to create a cluster
|
|
||||||
func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, *k3d.Cluster) { |
|
||||||
|
|
||||||
// --replicas
|
|
||||||
replicas, err := cmd.Flags().GetInt("replicas") |
|
||||||
if err != nil { |
|
||||||
log.Errorln("No replica count specified") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// --role
|
|
||||||
roleStr, err := cmd.Flags().GetString("role") |
|
||||||
if err != nil { |
|
||||||
log.Errorln("No node role specified") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
if _, ok := k3d.NodeRoles[roleStr]; !ok { |
|
||||||
log.Fatalf("Unknown node role '%s'\n", roleStr) |
|
||||||
} |
|
||||||
role := k3d.NodeRoles[roleStr] |
|
||||||
|
|
||||||
// --image
|
|
||||||
image, err := cmd.Flags().GetString("image") |
|
||||||
if err != nil { |
|
||||||
log.Errorln("No image specified") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// --cluster
|
|
||||||
clusterName, err := cmd.Flags().GetString("cluster") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
cluster := &k3d.Cluster{ |
|
||||||
Name: clusterName, |
|
||||||
} |
|
||||||
|
|
||||||
// generate list of nodes
|
|
||||||
nodes := []*k3d.Node{} |
|
||||||
for i := 0; i < replicas; i++ { |
|
||||||
node := &k3d.Node{ |
|
||||||
Name: fmt.Sprintf("%s-%s-%d", k3d.DefaultObjectNamePrefix, args[0], i), |
|
||||||
Role: role, |
|
||||||
Image: image, |
|
||||||
Labels: map[string]string{ |
|
||||||
k3d.LabelRole: roleStr, |
|
||||||
}, |
|
||||||
} |
|
||||||
nodes = append(nodes, node) |
|
||||||
} |
|
||||||
|
|
||||||
return nodes, cluster |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package delete |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdDelete returns a new cobra command
|
|
||||||
func NewCmdDelete() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "delete", |
|
||||||
Short: "Delete a resource [cluster, node].", |
|
||||||
Long: `Delete a resource [cluster, node].`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdDeleteCluster()) |
|
||||||
cmd.AddCommand(NewCmdDeleteNode()) |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,105 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package delete |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdDeleteCluster returns a new cobra command
|
|
||||||
func NewCmdDeleteCluster() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "cluster (NAME | --all)", |
|
||||||
Short: "Delete a cluster.", |
|
||||||
Long: `Delete a cluster.`, |
|
||||||
Args: cobra.MinimumNArgs(0), // 0 or n arguments; 0 only if --all is set
|
|
||||||
ValidArgsFunction: util.ValidArgsAvailableClusters, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
clusters := parseDeleteClusterCmd(cmd, args) |
|
||||||
|
|
||||||
if len(clusters) == 0 { |
|
||||||
log.Infoln("No clusters found") |
|
||||||
} else { |
|
||||||
for _, c := range clusters { |
|
||||||
if err := cluster.DeleteCluster(cmd.Context(), runtimes.SelectedRuntime, c); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
log.Infoln("Removing cluster details from default kubeconfig") |
|
||||||
if err := cluster.RemoveClusterFromDefaultKubeConfig(cmd.Context(), c); err != nil { |
|
||||||
log.Warnln("Failed to remove cluster details from default kubeconfig") |
|
||||||
log.Warnln(err) |
|
||||||
} |
|
||||||
|
|
||||||
log.Infof("Successfully deleted cluster %s!", c.Name) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().BoolP("all", "a", false, "Delete all existing clusters") |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseDeleteClusterCmd parses the command input into variables required to delete clusters
|
|
||||||
func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { |
|
||||||
|
|
||||||
// --all
|
|
||||||
var clusters []*k3d.Cluster |
|
||||||
|
|
||||||
if all, err := cmd.Flags().GetBool("all"); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} else if all { |
|
||||||
clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
return clusters |
|
||||||
} |
|
||||||
|
|
||||||
if len(args) < 1 { |
|
||||||
log.Fatalln("Expecting at least one cluster name if `--all` is not set") |
|
||||||
} |
|
||||||
|
|
||||||
for _, name := range args { |
|
||||||
cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters = append(clusters, cluster) |
|
||||||
} |
|
||||||
|
|
||||||
return clusters |
|
||||||
} |
|
@ -1,97 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package delete |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdDeleteNode returns a new cobra command
|
|
||||||
func NewCmdDeleteNode() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "node (NAME | --all)", |
|
||||||
Short: "Delete a node.", |
|
||||||
Long: `Delete a node.`, |
|
||||||
Args: cobra.MinimumNArgs(1), // at least one node has to be specified
|
|
||||||
ValidArgsFunction: util.ValidArgsAvailableNodes, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
|
|
||||||
nodes := parseDeleteNodeCmd(cmd, args) |
|
||||||
|
|
||||||
if len(nodes) == 0 { |
|
||||||
log.Infoln("No nodes found") |
|
||||||
} else { |
|
||||||
for _, node := range nodes { |
|
||||||
if err := cluster.DeleteNode(cmd.Context(), runtimes.SelectedRuntime, node); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().BoolP("all", "a", false, "Delete all existing clusters") |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseDeleteNodeCmd parses the command input into variables required to delete nodes
|
|
||||||
func parseDeleteNodeCmd(cmd *cobra.Command, args []string) []*k3d.Node { |
|
||||||
|
|
||||||
// --all
|
|
||||||
var nodes []*k3d.Node |
|
||||||
|
|
||||||
if all, err := cmd.Flags().GetBool("all"); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} else if all { |
|
||||||
nodes, err = cluster.GetNodes(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
return nodes |
|
||||||
} |
|
||||||
|
|
||||||
if len(args) < 1 { |
|
||||||
log.Fatalln("Expecting at least one node name if `--all` is not set") |
|
||||||
} |
|
||||||
|
|
||||||
for _, name := range args { |
|
||||||
node, err := cluster.GetNode(cmd.Context(), runtimes.SelectedRuntime, &k3d.Node{Name: name}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
nodes = append(nodes, node) |
|
||||||
} |
|
||||||
|
|
||||||
return nodes |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package get |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdGet returns a new cobra command
|
|
||||||
func NewCmdGet() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "get", |
|
||||||
Short: "Get a resource [cluster, node, kubeconfig].", |
|
||||||
Long: `Get a resource [cluster, node, kubeconfig].`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdGetCluster()) |
|
||||||
cmd.AddCommand(NewCmdGetNode()) |
|
||||||
cmd.AddCommand(NewCmdGetKubeconfig()) |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,128 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package get |
|
||||||
|
|
||||||
import ( |
|
||||||
"context" |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
"strings" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
k3cluster "github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/liggitt/tabwriter" |
|
||||||
) |
|
||||||
|
|
||||||
// TODO : deal with --all flag to manage differentiate started cluster and stopped cluster like `docker ps` and `docker ps -a`
|
|
||||||
type clusterFlags struct { |
|
||||||
noHeader bool |
|
||||||
token bool |
|
||||||
} |
|
||||||
|
|
||||||
// NewCmdGetCluster returns a new cobra command
|
|
||||||
func NewCmdGetCluster() *cobra.Command { |
|
||||||
|
|
||||||
clusterFlags := clusterFlags{} |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "cluster [NAME [NAME...]]", |
|
||||||
Aliases: []string{"clusters"}, |
|
||||||
Short: "Get cluster(s)", |
|
||||||
Long: `Get cluster(s).`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
clusters := buildClusterList(cmd.Context(), args) |
|
||||||
PrintClusters(clusters, clusterFlags) |
|
||||||
}, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableClusters, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().BoolVar(&clusterFlags.noHeader, "no-headers", false, "Disable headers") |
|
||||||
cmd.Flags().BoolVar(&clusterFlags.token, "token", false, "Print k3s cluster token") |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
func buildClusterList(ctx context.Context, args []string) []*k3d.Cluster { |
|
||||||
var clusters []*k3d.Cluster |
|
||||||
var err error |
|
||||||
|
|
||||||
if len(args) == 0 { |
|
||||||
// cluster name not specified : get all clusters
|
|
||||||
clusters, err = k3cluster.GetClusters(ctx, runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} else { |
|
||||||
for _, clusterName := range args { |
|
||||||
// cluster name specified : get specific cluster
|
|
||||||
retrievedCluster, err := k3cluster.GetCluster(ctx, runtimes.SelectedRuntime, &k3d.Cluster{Name: clusterName}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters = append(clusters, retrievedCluster) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return clusters |
|
||||||
} |
|
||||||
|
|
||||||
// PrintPrintClusters : display list of cluster
|
|
||||||
func PrintClusters(clusters []*k3d.Cluster, flags clusterFlags) { |
|
||||||
|
|
||||||
tabwriter := tabwriter.NewWriter(os.Stdout, 6, 4, 3, ' ', tabwriter.RememberWidths) |
|
||||||
defer tabwriter.Flush() |
|
||||||
|
|
||||||
if !flags.noHeader { |
|
||||||
headers := []string{"NAME", "MASTERS", "WORKERS"} // TODO: getCluster: add status column
|
|
||||||
if flags.token { |
|
||||||
headers = append(headers, "TOKEN") |
|
||||||
} |
|
||||||
_, err := fmt.Fprintf(tabwriter, "%s\n", strings.Join(headers, "\t")) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln("Failed to print headers") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
k3cluster.SortClusters(clusters) |
|
||||||
|
|
||||||
for _, cluster := range clusters { |
|
||||||
masterCount := cluster.MasterCount() |
|
||||||
workerCount := cluster.WorkerCount() |
|
||||||
|
|
||||||
if flags.token { |
|
||||||
fmt.Fprintf(tabwriter, "%s\t%d\t%d\t%s\n", cluster.Name, masterCount, workerCount, cluster.Token) |
|
||||||
} else { |
|
||||||
fmt.Fprintf(tabwriter, "%s\t%d\t%d\n", cluster.Name, masterCount, workerCount) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,116 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package get |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
"k8s.io/client-go/tools/clientcmd" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
type getKubeconfigFlags struct { |
|
||||||
all bool |
|
||||||
output string |
|
||||||
} |
|
||||||
|
|
||||||
// NewCmdGetKubeconfig returns a new cobra command
|
|
||||||
func NewCmdGetKubeconfig() *cobra.Command { |
|
||||||
|
|
||||||
writeKubeConfigOptions := cluster.WriteKubeConfigOptions{} |
|
||||||
|
|
||||||
getKubeconfigFlags := getKubeconfigFlags{} |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "kubeconfig [CLUSTER [CLUSTER [...]] | --all]", // TODO: getKubeconfig: allow more than one cluster name or even --all
|
|
||||||
Short: "Get kubeconfig", |
|
||||||
Long: `Get kubeconfig.`, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableClusters, |
|
||||||
Args: func(cmd *cobra.Command, args []string) error { |
|
||||||
if (len(args) < 1 && !getKubeconfigFlags.all) || (len(args) > 0 && getKubeconfigFlags.all) { |
|
||||||
return fmt.Errorf("Need to specify one or more cluster names *or* set `--all` flag") |
|
||||||
} |
|
||||||
return nil |
|
||||||
}, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
var clusters []*k3d.Cluster |
|
||||||
var err error |
|
||||||
|
|
||||||
// generate list of clusters
|
|
||||||
if getKubeconfigFlags.all { |
|
||||||
clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} else { |
|
||||||
for _, clusterName := range args { |
|
||||||
retrievedCluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: clusterName}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters = append(clusters, retrievedCluster) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// get kubeconfigs from all clusters
|
|
||||||
errorGettingKubeconfig := false |
|
||||||
for _, c := range clusters { |
|
||||||
log.Debugf("Getting kubeconfig for cluster '%s'", c.Name) |
|
||||||
if getKubeconfigFlags.output, err = cluster.GetAndWriteKubeConfig(cmd.Context(), runtimes.SelectedRuntime, c, getKubeconfigFlags.output, &writeKubeConfigOptions); err != nil { |
|
||||||
log.Errorln(err) |
|
||||||
errorGettingKubeconfig = true |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// only print kubeconfig file path if output is not stdout ("-")
|
|
||||||
if getKubeconfigFlags.output != "-" { |
|
||||||
fmt.Println(getKubeconfigFlags.output) |
|
||||||
} |
|
||||||
|
|
||||||
// return with non-zero exit code, if there was an error for one of the clusters
|
|
||||||
if errorGettingKubeconfig { |
|
||||||
os.Exit(1) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().StringVarP(&getKubeconfigFlags.output, "output", "o", "", fmt.Sprintf("Define output [ - | FILE ] (default from $KUBECONFIG or %s", clientcmd.RecommendedHomeFile)) |
|
||||||
if err := cmd.MarkFlagFilename("output"); err != nil { |
|
||||||
log.Fatalln("Failed to mark flag --output as filename") |
|
||||||
} |
|
||||||
cmd.Flags().BoolVarP(&writeKubeConfigOptions.UpdateExisting, "update", "u", true, "Update conflicting fields in existing KubeConfig") |
|
||||||
cmd.Flags().BoolVarP(&writeKubeConfigOptions.UpdateCurrentContext, "switch", "s", false, "Switch to new context") |
|
||||||
cmd.Flags().BoolVar(&writeKubeConfigOptions.OverwriteExisting, "overwrite", false, "[Careful!] Overwrite existing file, ignoring its contents") |
|
||||||
cmd.Flags().BoolVarP(&getKubeconfigFlags.all, "all", "a", false, "Get kubeconfigs from all existing clusters") |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,123 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package get |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
"sort" |
|
||||||
"strings" |
|
||||||
|
|
||||||
"github.com/liggitt/tabwriter" |
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdGetNode returns a new cobra command
|
|
||||||
func NewCmdGetNode() *cobra.Command { |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "node [NAME [NAME...]]", |
|
||||||
Aliases: []string{"nodes"}, |
|
||||||
Short: "Get node(s)", |
|
||||||
Long: `Get node(s).`, |
|
||||||
Args: cobra.MinimumNArgs(0), // 0 or more; 0 = all
|
|
||||||
ValidArgsFunction: util.ValidArgsAvailableNodes, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
nodes, headersOff := parseGetNodeCmd(cmd, args) |
|
||||||
var existingNodes []*k3d.Node |
|
||||||
if len(nodes) == 0 { // Option a) no name specified -> get all nodes
|
|
||||||
found, err := cluster.GetNodes(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
existingNodes = append(existingNodes, found...) |
|
||||||
} else { // Option b) cluster name specified -> get specific cluster
|
|
||||||
for _, node := range nodes { |
|
||||||
found, err := cluster.GetNode(cmd.Context(), runtimes.SelectedRuntime, node) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
existingNodes = append(existingNodes, found) |
|
||||||
} |
|
||||||
} |
|
||||||
// print existing clusters
|
|
||||||
printNodes(existingNodes, headersOff) |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().Bool("no-headers", false, "Disable headers") |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
func parseGetNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, bool) { |
|
||||||
// --no-headers
|
|
||||||
headersOff, err := cmd.Flags().GetBool("no-headers") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
|
|
||||||
// Args = node name
|
|
||||||
if len(args) == 0 { |
|
||||||
return nil, headersOff |
|
||||||
} |
|
||||||
|
|
||||||
nodes := []*k3d.Node{} |
|
||||||
for _, name := range args { |
|
||||||
nodes = append(nodes, &k3d.Node{Name: name}) |
|
||||||
} |
|
||||||
|
|
||||||
return nodes, headersOff |
|
||||||
} |
|
||||||
|
|
||||||
func printNodes(nodes []*k3d.Node, headersOff bool) { |
|
||||||
|
|
||||||
tabwriter := tabwriter.NewWriter(os.Stdout, 6, 4, 3, ' ', tabwriter.RememberWidths) |
|
||||||
defer tabwriter.Flush() |
|
||||||
|
|
||||||
if !headersOff { |
|
||||||
headers := []string{"NAME", "ROLE", "CLUSTER"} // TODO: add status
|
|
||||||
_, err := fmt.Fprintf(tabwriter, "%s\n", strings.Join(headers, "\t")) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln("Failed to print headers") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sort.Slice(nodes, func(i, j int) bool { |
|
||||||
return nodes[i].Name < nodes[j].Name |
|
||||||
}) |
|
||||||
|
|
||||||
for _, node := range nodes { |
|
||||||
fmt.Fprintf(tabwriter, "%s\t%s\t%s\n", strings.TrimPrefix(node.Name, "/"), string(node.Role), node.Labels[k3d.LabelClusterName]) |
|
||||||
} |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package load |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdLoad returns a new cobra command
|
|
||||||
func NewCmdLoad() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "load", |
|
||||||
Short: "Load a resource [image] into a cluster.", |
|
||||||
Long: `Load a resource [image] into a cluster.`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdLoadImage()) |
|
||||||
|
|
||||||
// add flags
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,97 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package load |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
"github.com/rancher/k3d/v3/pkg/tools" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdLoadImage returns a new cobra command
|
|
||||||
func NewCmdLoadImage() *cobra.Command { |
|
||||||
|
|
||||||
loadImageOpts := k3d.LoadImageOpts{} |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "image [IMAGE | ARCHIVE [IMAGE | ARCHIVE...]]", |
|
||||||
Short: "Load an image from docker into a k3d cluster.", |
|
||||||
Long: `Load an image from docker into a k3d cluster.`, |
|
||||||
Aliases: []string{"images"}, |
|
||||||
Args: cobra.MinimumNArgs(1), |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
images, clusters := parseLoadImageCmd(cmd, args) |
|
||||||
log.Debugf("Load images [%+v] from runtime [%s] into clusters [%+v]", images, runtimes.SelectedRuntime, clusters) |
|
||||||
for _, cluster := range clusters { |
|
||||||
log.Infof("Loading images into '%s'", cluster.Name) |
|
||||||
if err := tools.LoadImagesIntoCluster(cmd.Context(), runtimes.SelectedRuntime, images, &cluster, loadImageOpts); err != nil { |
|
||||||
log.Errorf("Failed to load images into cluster '%s'", cluster.Name) |
|
||||||
log.Errorln(err) |
|
||||||
} |
|
||||||
} |
|
||||||
log.Info("DONE") |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
/********* |
|
||||||
* Flags * |
|
||||||
*********/ |
|
||||||
cmd.Flags().StringArrayP("cluster", "c", []string{k3d.DefaultClusterName}, "Select clusters to load the image to.") |
|
||||||
if err := cmd.RegisterFlagCompletionFunc("cluster", util.ValidArgsAvailableClusters); err != nil { |
|
||||||
log.Fatalln("Failed to register flag completion for '--cluster'", err) |
|
||||||
} |
|
||||||
|
|
||||||
cmd.Flags().BoolVarP(&loadImageOpts.KeepTar, "keep-tarball", "k", false, "Do not delete the tarball containing the saved images from the shared volume") |
|
||||||
|
|
||||||
/* Subcommands */ |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseLoadImageCmd parses the command input into variables required to create a cluster
|
|
||||||
func parseLoadImageCmd(cmd *cobra.Command, args []string) ([]string, []k3d.Cluster) { |
|
||||||
|
|
||||||
// --cluster
|
|
||||||
clusterNames, err := cmd.Flags().GetStringArray("cluster") |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters := []k3d.Cluster{} |
|
||||||
for _, clusterName := range clusterNames { |
|
||||||
clusters = append(clusters, k3d.Cluster{Name: clusterName}) |
|
||||||
} |
|
||||||
|
|
||||||
// images
|
|
||||||
images := args |
|
||||||
if len(images) == 0 { |
|
||||||
log.Fatalln("No images specified!") |
|
||||||
} |
|
||||||
|
|
||||||
return images, clusters |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package start |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStart returns a new cobra command
|
|
||||||
func NewCmdStart() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "start", |
|
||||||
Short: "Start a resource [cluster, node].", |
|
||||||
Long: `Start a resource [cluster, node].`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdStartCluster()) |
|
||||||
cmd.AddCommand(NewCmdStartNode()) |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,102 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package start |
|
||||||
|
|
||||||
import ( |
|
||||||
"time" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
"github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStartCluster returns a new cobra command
|
|
||||||
func NewCmdStartCluster() *cobra.Command { |
|
||||||
|
|
||||||
startClusterOpts := types.StartClusterOpts{} |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "cluster (NAME [NAME...] | --all)", |
|
||||||
Short: "Start an existing k3d cluster", |
|
||||||
Long: `Start an existing k3d cluster`, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableClusters, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
clusters := parseStartClusterCmd(cmd, args) |
|
||||||
if len(clusters) == 0 { |
|
||||||
log.Infoln("No clusters found") |
|
||||||
} else { |
|
||||||
for _, c := range clusters { |
|
||||||
if err := cluster.StartCluster(cmd.Context(), runtimes.SelectedRuntime, c, startClusterOpts); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().BoolP("all", "a", false, "Start all existing clusters") |
|
||||||
cmd.Flags().BoolVar(&startClusterOpts.WaitForMaster, "wait", false, "Wait for the master(s) (and loadbalancer) to be ready before returning.") |
|
||||||
cmd.Flags().DurationVar(&startClusterOpts.Timeout, "timeout", 0*time.Second, "Maximum waiting time for '--wait' before canceling/returning.") |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseStartClusterCmd parses the command input into variables required to start clusters
|
|
||||||
func parseStartClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { |
|
||||||
// --all
|
|
||||||
var clusters []*k3d.Cluster |
|
||||||
|
|
||||||
if all, err := cmd.Flags().GetBool("all"); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} else if all { |
|
||||||
clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
return clusters |
|
||||||
} |
|
||||||
|
|
||||||
if len(args) < 1 { |
|
||||||
log.Fatalln("Expecting at least one cluster name if `--all` is not set") |
|
||||||
} |
|
||||||
|
|
||||||
for _, name := range args { |
|
||||||
cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters = append(clusters, cluster) |
|
||||||
} |
|
||||||
|
|
||||||
return clusters |
|
||||||
} |
|
@ -1,62 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package start |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStartNode returns a new cobra command
|
|
||||||
func NewCmdStartNode() *cobra.Command { |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "node NAME", // TODO: startNode: allow one or more names or --all
|
|
||||||
Short: "Start an existing k3d node", |
|
||||||
Long: `Start an existing k3d node.`, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableNodes, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
node := parseStartNodeCmd(cmd, args) |
|
||||||
if err := runtimes.SelectedRuntime.StartNode(cmd.Context(), node); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseStartNodeCmd parses the command input into variables required to start a node
|
|
||||||
func parseStartNodeCmd(cmd *cobra.Command, args []string) *k3d.Node { |
|
||||||
// node name // TODO: startNode: allow node filters, e.g. `k3d start nodes mycluster@worker` to start all worker nodes of cluster 'mycluster'
|
|
||||||
if len(args) == 0 || len(args[0]) == 0 { |
|
||||||
log.Fatalln("No node name given") |
|
||||||
} |
|
||||||
|
|
||||||
return &k3d.Node{Name: args[0]} |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package stop |
|
||||||
|
|
||||||
import ( |
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
|
|
||||||
"github.com/spf13/cobra" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStop returns a new cobra command
|
|
||||||
func NewCmdStop() *cobra.Command { |
|
||||||
|
|
||||||
// create new cobra command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "stop", |
|
||||||
Short: "Stop a resource [cluster, node].", |
|
||||||
Long: `Stop a resource [cluster, node].`, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
if err := cmd.Help(); err != nil { |
|
||||||
log.Errorln("Couldn't get help text") |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
cmd.AddCommand(NewCmdStopCluster()) |
|
||||||
cmd.AddCommand(NewCmdStopNode()) |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
@ -1,95 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package stop |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/cluster" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStopCluster returns a new cobra command
|
|
||||||
func NewCmdStopCluster() *cobra.Command { |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "cluster (NAME [NAME...] | --all)", |
|
||||||
Short: "Stop an existing k3d cluster", |
|
||||||
Long: `Stop an existing k3d cluster.`, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableClusters, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
clusters := parseStopClusterCmd(cmd, args) |
|
||||||
if len(clusters) == 0 { |
|
||||||
log.Infoln("No clusters found") |
|
||||||
} else { |
|
||||||
for _, c := range clusters { |
|
||||||
if err := cluster.StopCluster(cmd.Context(), runtimes.SelectedRuntime, c); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// add flags
|
|
||||||
cmd.Flags().BoolP("all", "a", false, "Start all existing clusters") |
|
||||||
|
|
||||||
// add subcommands
|
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseStopClusterCmd parses the command input into variables required to start clusters
|
|
||||||
func parseStopClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { |
|
||||||
// --all
|
|
||||||
var clusters []*k3d.Cluster |
|
||||||
|
|
||||||
if all, err := cmd.Flags().GetBool("all"); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} else if all { |
|
||||||
clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
return clusters |
|
||||||
} |
|
||||||
|
|
||||||
if len(args) < 1 { |
|
||||||
log.Fatalln("Expecting at least one cluster name if `--all` is not set") |
|
||||||
} |
|
||||||
|
|
||||||
for _, name := range args { |
|
||||||
cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) |
|
||||||
if err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
clusters = append(clusters, cluster) |
|
||||||
} |
|
||||||
|
|
||||||
return clusters |
|
||||||
} |
|
@ -1,63 +0,0 @@ |
|||||||
/* |
|
||||||
Copyright © 2020 The k3d Author(s) |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||||
of this software and associated documentation files (the "Software"), to deal |
|
||||||
in the Software without restriction, including without limitation the rights |
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the Software is |
|
||||||
furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in |
|
||||||
all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||||
THE SOFTWARE. |
|
||||||
*/ |
|
||||||
package stop |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/rancher/k3d/v3/cmd/util" |
|
||||||
"github.com/rancher/k3d/v3/pkg/runtimes" |
|
||||||
"github.com/spf13/cobra" |
|
||||||
|
|
||||||
k3d "github.com/rancher/k3d/v3/pkg/types" |
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus" |
|
||||||
) |
|
||||||
|
|
||||||
// NewCmdStopNode returns a new cobra command
|
|
||||||
func NewCmdStopNode() *cobra.Command { |
|
||||||
|
|
||||||
// create new command
|
|
||||||
cmd := &cobra.Command{ |
|
||||||
Use: "node NAME", // TODO: stopNode: allow one or more names or --all",
|
|
||||||
Short: "Stop an existing k3d node", |
|
||||||
Long: `Stop an existing k3d node.`, |
|
||||||
ValidArgsFunction: util.ValidArgsAvailableNodes, |
|
||||||
Run: func(cmd *cobra.Command, args []string) { |
|
||||||
node := parseStopNodeCmd(cmd, args) |
|
||||||
if err := runtimes.SelectedRuntime.StopNode(cmd.Context(), node); err != nil { |
|
||||||
log.Fatalln(err) |
|
||||||
} |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
// done
|
|
||||||
return cmd |
|
||||||
} |
|
||||||
|
|
||||||
// parseStopNodeCmd parses the command input into variables required to stop a node
|
|
||||||
func parseStopNodeCmd(cmd *cobra.Command, args []string) *k3d.Node { |
|
||||||
// node name // TODO: allow node filters, e.g. `k3d stop nodes mycluster@worker` to stop all worker nodes of cluster 'mycluster'
|
|
||||||
if len(args) == 0 || len(args[0]) == 0 { |
|
||||||
log.Fatalln("No node name given") |
|
||||||
} |
|
||||||
|
|
||||||
return &k3d.Node{Name: args[0]} |
|
||||||
} |
|
Loading…
Reference in new issue