From 0d2c22455db629931755af4742499c43477287d2 Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Mon, 18 May 2020 12:57:59 +0200 Subject: [PATCH 1/6] Overall: use context.Context in top-level exported functions - package cluster: use context.Context as first function param in every exported function - package cmd: pass cmd.Context() to calls to package cluster exported functions --- cmd/create/createCluster.go | 6 +++--- cmd/create/createNode.go | 2 +- cmd/delete/deleteCluster.go | 8 ++++---- cmd/delete/deleteNode.go | 6 +++--- cmd/get/getCluster.go | 4 ++-- cmd/get/getKubeconfig.go | 4 ++-- cmd/get/getNode.go | 4 ++-- cmd/load/loadImage.go | 2 +- cmd/start/startCluster.go | 6 +++--- cmd/stop/stopCluster.go | 6 +++--- pkg/cluster/cluster.go | 14 +++++++------- pkg/cluster/kubeconfig.go | 27 ++++++++++++++------------- pkg/cluster/loadbalancer.go | 3 ++- pkg/cluster/node.go | 22 +++++++++++----------- pkg/tools/tools.go | 8 +++++--- 15 files changed, 63 insertions(+), 59 deletions(-) diff --git a/cmd/create/createCluster.go b/cmd/create/createCluster.go index 19d8f4ae..6474d382 100644 --- a/cmd/create/createCluster.go +++ b/cmd/create/createCluster.go @@ -64,7 +64,7 @@ func NewCmdCreateCluster() *cobra.Command { cluster := parseCreateClusterCmd(cmd, args, createClusterOpts) // check if a cluster with that name exists already - if _, err := k3dCluster.GetCluster(cluster, runtimes.SelectedRuntime); err == nil { + if _, err := k3dCluster.GetCluster(cmd.Context(), cluster, runtimes.SelectedRuntime); err == nil { log.Fatalf("Failed to create cluster '%s' because a cluster with that name already exists", cluster.Name) } @@ -77,7 +77,7 @@ func NewCmdCreateCluster() *cobra.Command { // rollback if creation failed log.Errorln(err) log.Errorln("Failed to create cluster >>> Rolling Back") - if err := k3dCluster.DeleteCluster(cluster, runtimes.SelectedRuntime); err != nil { + if err := k3dCluster.DeleteCluster(cmd.Context(), cluster, runtimes.SelectedRuntime); err != nil { log.Errorln(err) log.Fatalln("Cluster creation FAILED, also FAILED to rollback changes!") } @@ -87,7 +87,7 @@ func NewCmdCreateCluster() *cobra.Command { if updateKubeconfig { log.Debugf("Updating default kubeconfig with a new context for cluster %s", cluster.Name) - if _, err := k3dCluster.GetAndWriteKubeConfig(runtimes.SelectedRuntime, cluster, "", &k3dCluster.WriteKubeConfigOptions{UpdateExisting: true, OverwriteExisting: false, UpdateCurrentContext: false}); err != nil { + if _, err := k3dCluster.GetAndWriteKubeConfig(cmd.Context(), runtimes.SelectedRuntime, cluster, "", &k3dCluster.WriteKubeConfigOptions{UpdateExisting: true, OverwriteExisting: false, UpdateCurrentContext: false}); err != nil { log.Fatalln(err) } } diff --git a/cmd/create/createNode.go b/cmd/create/createNode.go index c179ccfc..030e6fe6 100644 --- a/cmd/create/createNode.go +++ b/cmd/create/createNode.go @@ -45,7 +45,7 @@ func NewCmdCreateNode() *cobra.Command { Run: func(cmd *cobra.Command, args []string) { nodes, cluster := parseCreateNodeCmd(cmd, args) for _, node := range nodes { - if err := k3dc.AddNodeToCluster(runtimes.SelectedRuntime, node, cluster); err != nil { + if err := k3dc.AddNodeToCluster(cmd.Context(), runtimes.SelectedRuntime, node, cluster); err != nil { log.Errorf("Failed to add node '%s' to cluster '%s'", node.Name, cluster.Name) log.Errorln(err) } diff --git a/cmd/delete/deleteCluster.go b/cmd/delete/deleteCluster.go index 2231e6f7..5bd3946c 100644 --- a/cmd/delete/deleteCluster.go +++ b/cmd/delete/deleteCluster.go @@ -48,11 +48,11 @@ func NewCmdDeleteCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.DeleteCluster(c, runtimes.SelectedRuntime); err != nil { + if err := cluster.DeleteCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { log.Fatalln(err) } log.Infoln("Removing cluster details from default kubeconfig") - if err := cluster.RemoveClusterFromDefaultKubeConfig(c); err != nil { + if err := cluster.RemoveClusterFromDefaultKubeConfig(cmd.Context(), c); err != nil { log.Warnln("Failed to remove cluster details from default kubeconfig") log.Warnln(err) } @@ -82,7 +82,7 @@ func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { if all, err := cmd.Flags().GetBool("all"); err != nil { log.Fatalln(err) } else if all { - clusters, err = cluster.GetClusters(runtimes.SelectedRuntime) + clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } @@ -94,7 +94,7 @@ func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(&k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/cmd/delete/deleteNode.go b/cmd/delete/deleteNode.go index 70e7193a..9ddf90eb 100644 --- a/cmd/delete/deleteNode.go +++ b/cmd/delete/deleteNode.go @@ -47,7 +47,7 @@ func NewCmdDeleteNode() *cobra.Command { log.Infoln("No nodes found") } else { for _, node := range nodes { - if err := cluster.DeleteNode(runtimes.SelectedRuntime, node); err != nil { + if err := cluster.DeleteNode(cmd.Context(), runtimes.SelectedRuntime, node); err != nil { log.Fatalln(err) } } @@ -75,7 +75,7 @@ func parseDeleteNodeCmd(cmd *cobra.Command, args []string) []*k3d.Node { if all, err := cmd.Flags().GetBool("all"); err != nil { log.Fatalln(err) } else if all { - nodes, err = cluster.GetNodes(runtimes.SelectedRuntime) + nodes, err = cluster.GetNodes(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } @@ -87,7 +87,7 @@ func parseDeleteNodeCmd(cmd *cobra.Command, args []string) []*k3d.Node { } for _, name := range args { - node, err := cluster.GetNode(&k3d.Node{Name: name}, runtimes.SelectedRuntime) + node, err := cluster.GetNode(cmd.Context(), &k3d.Node{Name: name}, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/cmd/get/getCluster.go b/cmd/get/getCluster.go index bbf11e4b..a3c8fba8 100644 --- a/cmd/get/getCluster.go +++ b/cmd/get/getCluster.go @@ -52,13 +52,13 @@ func NewCmdGetCluster() *cobra.Command { clusters, headersOff := parseGetClusterCmd(cmd, args) var existingClusters []*k3d.Cluster if clusters == nil { // Option a) no cluster name specified -> get all clusters - found, err := cluster.GetClusters(runtimes.SelectedRuntime) + found, err := cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } existingClusters = append(existingClusters, found...) } else { // Option b) cluster name specified -> get specific cluster - found, err := cluster.GetCluster(clusters, runtimes.SelectedRuntime) + found, err := cluster.GetCluster(cmd.Context(), clusters, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/cmd/get/getKubeconfig.go b/cmd/get/getKubeconfig.go index 29b191c3..2be6cc97 100644 --- a/cmd/get/getKubeconfig.go +++ b/cmd/get/getKubeconfig.go @@ -63,7 +63,7 @@ func NewCmdGetKubeconfig() *cobra.Command { // generate list of clusters if getKubeconfigFlags.all { - clusters, err = cluster.GetClusters(runtimes.SelectedRuntime) + clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } @@ -77,7 +77,7 @@ func NewCmdGetKubeconfig() *cobra.Command { errorGettingKubeconfig := false for _, c := range clusters { log.Debugf("Getting kubeconfig for cluster '%s'", c.Name) - if getKubeconfigFlags.output, err = cluster.GetAndWriteKubeConfig(runtimes.SelectedRuntime, c, getKubeconfigFlags.output, &writeKubeConfigOptions); err != nil { + if getKubeconfigFlags.output, err = cluster.GetAndWriteKubeConfig(cmd.Context(), runtimes.SelectedRuntime, c, getKubeconfigFlags.output, &writeKubeConfigOptions); err != nil { log.Errorln(err) errorGettingKubeconfig = true } diff --git a/cmd/get/getNode.go b/cmd/get/getNode.go index d8695356..26c0c823 100644 --- a/cmd/get/getNode.go +++ b/cmd/get/getNode.go @@ -50,13 +50,13 @@ func NewCmdGetNode() *cobra.Command { node, headersOff := parseGetNodeCmd(cmd, args) var existingNodes []*k3d.Node if node == nil { // Option a) no name specified -> get all nodes - found, err := cluster.GetNodes(runtimes.SelectedRuntime) + 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 - found, err := cluster.GetNode(node, runtimes.SelectedRuntime) + found, err := cluster.GetNode(cmd.Context(), node, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/cmd/load/loadImage.go b/cmd/load/loadImage.go index bb849171..9d0edb27 100644 --- a/cmd/load/loadImage.go +++ b/cmd/load/loadImage.go @@ -45,7 +45,7 @@ func NewCmdLoadImage() *cobra.Command { log.Debugf("Load images [%+v] from runtime [%s] into clusters [%+v]", runtimes.SelectedRuntime, images, clusters) for _, cluster := range clusters { log.Debugf("Loading images into '%s'", cluster.Name) - if err := tools.LoadImagesIntoCluster(runtimes.SelectedRuntime, images, &cluster, keepTarball); err != nil { + if err := tools.LoadImagesIntoCluster(cmd.Context(), runtimes.SelectedRuntime, images, &cluster, keepTarball); err != nil { log.Errorf("Failed to load images into cluster '%s'", cluster.Name) log.Errorln(err) } diff --git a/cmd/start/startCluster.go b/cmd/start/startCluster.go index c8086db9..6a15fb4c 100644 --- a/cmd/start/startCluster.go +++ b/cmd/start/startCluster.go @@ -46,7 +46,7 @@ func NewCmdStartCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.StartCluster(c, runtimes.SelectedRuntime); err != nil { + if err := cluster.StartCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { log.Fatalln(err) } } @@ -73,7 +73,7 @@ func parseStartClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { if all, err := cmd.Flags().GetBool("all"); err != nil { log.Fatalln(err) } else if all { - clusters, err = cluster.GetClusters(runtimes.SelectedRuntime) + clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } @@ -85,7 +85,7 @@ func parseStartClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(&k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/cmd/stop/stopCluster.go b/cmd/stop/stopCluster.go index 28def951..d4f2b397 100644 --- a/cmd/stop/stopCluster.go +++ b/cmd/stop/stopCluster.go @@ -46,7 +46,7 @@ func NewCmdStopCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.StopCluster(c, runtimes.SelectedRuntime); err != nil { + if err := cluster.StopCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { log.Fatalln(err) } } @@ -73,7 +73,7 @@ func parseStopClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { if all, err := cmd.Flags().GetBool("all"); err != nil { log.Fatalln(err) } else if all { - clusters, err = cluster.GetClusters(runtimes.SelectedRuntime) + clusters, err = cluster.GetClusters(cmd.Context(), runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } @@ -85,7 +85,7 @@ func parseStopClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(&k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) if err != nil { log.Fatalln(err) } diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 2527ba9e..fe571782 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -153,7 +153,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt // create node log.Infof("Creating node '%s'", node.Name) - if err := CreateNode(node, runtime); err != nil { + if err := CreateNode(ctx, node, runtime); err != nil { log.Errorln("Failed to create node") return err } @@ -305,7 +305,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt } cluster.Nodes = append(cluster.Nodes, lbNode) // append lbNode to list of cluster nodes, so it will be considered during rollback log.Infof("Creating LoadBalancer '%s'", lbNode.Name) - if err := CreateNode(lbNode, runtime); err != nil { + if err := CreateNode(ctx, lbNode, runtime); err != nil { log.Errorln("Failed to create loadbalancer") return err } @@ -317,7 +317,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt } // DeleteCluster deletes an existing cluster -func DeleteCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func DeleteCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { log.Infof("Deleting cluster '%s'", cluster.Name) log.Debugf("%+v", cluster) @@ -363,7 +363,7 @@ func DeleteCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { } // GetClusters returns a list of all existing clusters -func GetClusters(runtime k3drt.Runtime) ([]*k3d.Cluster, error) { +func GetClusters(ctx context.Context, runtime k3drt.Runtime) ([]*k3d.Cluster, error) { nodes, err := runtime.GetNodesByLabel(k3d.DefaultObjectLabels) if err != nil { log.Errorln("Failed to get clusters") @@ -437,7 +437,7 @@ func populateClusterFieldsFromLabels(cluster *k3d.Cluster) error { } // GetCluster returns an existing cluster with all fields and node lists populated -func GetCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) (*k3d.Cluster, error) { +func GetCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) (*k3d.Cluster, error) { // get nodes that belong to the selected cluster nodes, err := runtime.GetNodesByLabel(map[string]string{"k3d.cluster": cluster.Name}) if err != nil { @@ -471,7 +471,7 @@ func generateNodeName(cluster string, role k3d.Role, suffix int) string { } // StartCluster starts a whole cluster (i.e. all nodes of the cluster) -func StartCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func StartCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { log.Infof("Starting cluster '%s'", cluster.Name) failed := 0 @@ -508,7 +508,7 @@ func StartCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { } // StopCluster stops a whole cluster (i.e. all nodes of the cluster) -func StopCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func StopCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { log.Infof("Stopping cluster '%s'", cluster.Name) failed := 0 diff --git a/pkg/cluster/kubeconfig.go b/pkg/cluster/kubeconfig.go index 5209f22f..a71c9a4a 100644 --- a/pkg/cluster/kubeconfig.go +++ b/pkg/cluster/kubeconfig.go @@ -23,6 +23,7 @@ package cluster import ( "bytes" + "context" "fmt" "io/ioutil" "os" @@ -47,10 +48,10 @@ type WriteKubeConfigOptions struct { // 1. fetches the KubeConfig from the first master node retrieved for a given cluster // 2. modifies it by updating some fields with cluster-specific information // 3. writes it to the specified output -func GetAndWriteKubeConfig(runtime runtimes.Runtime, cluster *k3d.Cluster, output string, writeKubeConfigOptions *WriteKubeConfigOptions) (string, error) { +func GetAndWriteKubeConfig(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster, output string, writeKubeConfigOptions *WriteKubeConfigOptions) (string, error) { // get kubeconfig from cluster node - kubeconfig, err := GetKubeconfig(runtime, cluster) + kubeconfig, err := GetKubeconfig(ctx, runtime, cluster) if err != nil { return output, err } @@ -65,7 +66,7 @@ func GetAndWriteKubeConfig(runtime runtimes.Runtime, cluster *k3d.Cluster, outpu // simply write to the output, ignoring existing contents if writeKubeConfigOptions.OverwriteExisting || output == "-" { - return output, WriteKubeConfigToPath(kubeconfig, output) + return output, WriteKubeConfigToPath(ctx, kubeconfig, output) } // load config from existing file or fail if it has non-kubeconfig contents @@ -102,14 +103,14 @@ func GetAndWriteKubeConfig(runtime runtimes.Runtime, cluster *k3d.Cluster, outpu } // update existing kubeconfig, but error out if there are conflicting fields but we don't want to update them - return output, UpdateKubeConfig(kubeconfig, existingKubeConfig, output, writeKubeConfigOptions.UpdateExisting, writeKubeConfigOptions.UpdateCurrentContext) + return output, UpdateKubeConfig(ctx, kubeconfig, existingKubeConfig, output, writeKubeConfigOptions.UpdateExisting, writeKubeConfigOptions.UpdateCurrentContext) } // GetKubeconfig grabs the kubeconfig file from /output from a master node container, // modifies it by updating some fields with cluster-specific information // and returns a Config object for further processing -func GetKubeconfig(runtime runtimes.Runtime, cluster *k3d.Cluster) (*clientcmdapi.Config, error) { +func GetKubeconfig(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster) (*clientcmdapi.Config, error) { // get all master nodes for the selected cluster // TODO: getKubeconfig: we should make sure, that the master node we're trying to fetch from is actually running masterNodes, err := runtime.GetNodesByLabel(map[string]string{"k3d.cluster": cluster.Name, "k3d.role": string(k3d.MasterRole)}) @@ -199,7 +200,7 @@ func GetKubeconfig(runtime runtimes.Runtime, cluster *k3d.Cluster) (*clientcmdap } // WriteKubeConfigToPath takes a kubeconfig and writes it to some path, which can be '-' for os.Stdout -func WriteKubeConfigToPath(kubeconfig *clientcmdapi.Config, path string) error { +func WriteKubeConfigToPath(ctx context.Context, kubeconfig *clientcmdapi.Config, path string) error { var output *os.File defer output.Close() var err error @@ -234,7 +235,7 @@ func WriteKubeConfigToPath(kubeconfig *clientcmdapi.Config, path string) error { } // UpdateKubeConfig merges a new kubeconfig into an existing kubeconfig and returns the result -func UpdateKubeConfig(newKubeConfig *clientcmdapi.Config, existingKubeConfig *clientcmdapi.Config, outPath string, overwriteConflicting bool, updateCurrentContext bool) error { +func UpdateKubeConfig(ctx context.Context, newKubeConfig *clientcmdapi.Config, existingKubeConfig *clientcmdapi.Config, outPath string, overwriteConflicting bool, updateCurrentContext bool) error { log.Debugf("Merging new KubeConfig:\n%+v\n>>> into existing KubeConfig:\n%+v", newKubeConfig, existingKubeConfig) @@ -277,11 +278,11 @@ func UpdateKubeConfig(newKubeConfig *clientcmdapi.Config, existingKubeConfig *cl log.Debugf("Merged KubeConfig:\n%+v", existingKubeConfig) - return WriteKubeConfig(existingKubeConfig, outPath) + return WriteKubeConfig(ctx, existingKubeConfig, outPath) } // WriteKubeConfig writes a kubeconfig to a path atomically -func WriteKubeConfig(kubeconfig *clientcmdapi.Config, path string) error { +func WriteKubeConfig(ctx context.Context, kubeconfig *clientcmdapi.Config, path string) error { tempPath := fmt.Sprintf("%s.k3d_%s", path, time.Now().Format("20060102_150405.000000")) if err := clientcmd.WriteToFile(*kubeconfig, tempPath); err != nil { log.Errorf("Failed to write merged kubeconfig to temporary file '%s'", tempPath) @@ -319,7 +320,7 @@ func GetDefaultKubeConfigPath() (string, error) { } // RemoveClusterFromDefaultKubeConfig removes a cluster's details from the default kubeconfig -func RemoveClusterFromDefaultKubeConfig(cluster *k3d.Cluster) error { +func RemoveClusterFromDefaultKubeConfig(ctx context.Context, cluster *k3d.Cluster) error { defaultKubeConfigPath, err := GetDefaultKubeConfigPath() if err != nil { return err @@ -328,12 +329,12 @@ func RemoveClusterFromDefaultKubeConfig(cluster *k3d.Cluster) error { if err != nil { return err } - kubeconfig = RemoveClusterFromKubeConfig(cluster, kubeconfig) - return WriteKubeConfig(kubeconfig, defaultKubeConfigPath) + kubeconfig = RemoveClusterFromKubeConfig(ctx, cluster, kubeconfig) + return WriteKubeConfig(ctx, kubeconfig, defaultKubeConfigPath) } // RemoveClusterFromKubeConfig removes a cluster's details from a given kubeconfig -func RemoveClusterFromKubeConfig(cluster *k3d.Cluster, kubeconfig *clientcmdapi.Config) *clientcmdapi.Config { +func RemoveClusterFromKubeConfig(ctx context.Context, cluster *k3d.Cluster, kubeconfig *clientcmdapi.Config) *clientcmdapi.Config { clusterName := fmt.Sprintf("%s-%s", k3d.DefaultObjectNamePrefix, cluster.Name) contextName := fmt.Sprintf("%s-%s", k3d.DefaultObjectNamePrefix, cluster.Name) authInfoName := fmt.Sprintf("admin@%s-%s", k3d.DefaultObjectNamePrefix, cluster.Name) diff --git a/pkg/cluster/loadbalancer.go b/pkg/cluster/loadbalancer.go index ec4b0755..57ed95a0 100644 --- a/pkg/cluster/loadbalancer.go +++ b/pkg/cluster/loadbalancer.go @@ -22,6 +22,7 @@ THE SOFTWARE. package cluster import ( + "context" "fmt" "github.com/rancher/k3d/pkg/runtimes" @@ -30,7 +31,7 @@ import ( ) // AddMasterToLoadBalancer adds a new master node to the loadbalancer configuration -func AddMasterToLoadBalancer(runtime runtimes.Runtime, cluster *k3d.Cluster, newNode *k3d.Node) error { +func AddMasterToLoadBalancer(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster, newNode *k3d.Node) error { // find the LoadBalancer for the target cluster masterNodes := "" var loadbalancer *k3d.Node diff --git a/pkg/cluster/node.go b/pkg/cluster/node.go index 1deaaefc..4fc30f69 100644 --- a/pkg/cluster/node.go +++ b/pkg/cluster/node.go @@ -36,8 +36,8 @@ import ( ) // AddNodeToCluster adds a node to an existing cluster -func AddNodeToCluster(runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Cluster) error { - cluster, err := GetCluster(cluster, runtime) +func AddNodeToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Cluster) error { + cluster, err := GetCluster(ctx, cluster, runtime) if err != nil { log.Errorf("Failed to find specified cluster '%s'", cluster.Name) return err @@ -72,7 +72,7 @@ func AddNodeToCluster(runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Clu } // get node details - chosenNode, err = GetNode(chosenNode, runtime) + chosenNode, err = GetNode(ctx, chosenNode, runtime) if err != nil { return err } @@ -104,13 +104,13 @@ func AddNodeToCluster(runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Clu } } - if err := CreateNode(node, runtime); err != nil { + if err := CreateNode(ctx, node, runtime); err != nil { return err } // if it's a master node, then update the loadbalancer configuration to include it if node.Role == k3d.MasterRole { - if err := AddMasterToLoadBalancer(runtime, cluster, node); err != nil { + if err := AddMasterToLoadBalancer(ctx, runtime, cluster, node); err != nil { log.Errorln("Failed to add new master node to cluster loadbalancer") return err } @@ -120,16 +120,16 @@ func AddNodeToCluster(runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Clu } // CreateNodes creates a list of nodes -func CreateNodes(nodes []*k3d.Node, runtime runtimes.Runtime) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? +func CreateNodes(ctx context.Context, nodes []*k3d.Node, runtime runtimes.Runtime) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? for _, node := range nodes { - if err := CreateNode(node, runtime); err != nil { + if err := CreateNode(ctx, node, runtime); err != nil { log.Error(err) } } } // CreateNode creates a new containerized k3s node -func CreateNode(node *k3d.Node, runtime runtimes.Runtime) error { +func CreateNode(ctx context.Context, node *k3d.Node, runtime runtimes.Runtime) error { log.Debugf("Creating node from spec\n%+v", node) /* @@ -176,7 +176,7 @@ func CreateNode(node *k3d.Node, runtime runtimes.Runtime) error { } // DeleteNode deletes an existing node -func DeleteNode(runtime runtimes.Runtime, node *k3d.Node) error { +func DeleteNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) error { if err := runtime.DeleteNode(node); err != nil { log.Error(err) @@ -212,7 +212,7 @@ func patchMasterSpec(node *k3d.Node) error { } // GetNodes returns a list of all existing clusters -func GetNodes(runtime runtimes.Runtime) ([]*k3d.Node, error) { +func GetNodes(ctx context.Context, runtime runtimes.Runtime) ([]*k3d.Node, error) { nodes, err := runtime.GetNodesByLabel(k3d.DefaultObjectLabels) if err != nil { log.Errorln("Failed to get nodes") @@ -223,7 +223,7 @@ func GetNodes(runtime runtimes.Runtime) ([]*k3d.Node, error) { } // GetNode returns a node matching the specified node fields -func GetNode(node *k3d.Node, runtime runtimes.Runtime) (*k3d.Node, error) { +func GetNode(ctx context.Context, node *k3d.Node, runtime runtimes.Runtime) (*k3d.Node, error) { // get node node, err := runtime.GetNode(node) if err != nil { diff --git a/pkg/tools/tools.go b/pkg/tools/tools.go index 2ad393f0..e11c4cf2 100644 --- a/pkg/tools/tools.go +++ b/pkg/tools/tools.go @@ -22,6 +22,7 @@ THE SOFTWARE. package tools import ( + "context" "fmt" "sync" "time" @@ -34,8 +35,8 @@ import ( // LoadImagesIntoCluster starts up a k3d tools container for the selected cluster and uses it to export // images from the runtime to import them into the nodes of the selected cluster -func LoadImagesIntoCluster(runtime runtimes.Runtime, images []string, cluster *k3d.Cluster, keepTarball bool) error { - cluster, err := k3dc.GetCluster(cluster, runtime) +func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images []string, cluster *k3d.Cluster, keepTarball bool) error { + cluster, err := k3dc.GetCluster(ctx, cluster, runtime) if err != nil { log.Errorf("Failed to find the specified cluster") return err @@ -63,6 +64,7 @@ func LoadImagesIntoCluster(runtime runtimes.Runtime, images []string, cluster *k // create tools node to export images log.Infoln("Starting k3d-tools node...") toolsNode, err := startToolsNode( // TODO: re-use existing container + ctx, runtime, cluster, cluster.Network.Name, @@ -123,7 +125,7 @@ func LoadImagesIntoCluster(runtime runtimes.Runtime, images []string, cluster *k } // startToolsNode will start a new k3d tools container and connect it to the network of the chosen cluster -func startToolsNode(runtime runtimes.Runtime, cluster *k3d.Cluster, network string, volumes []string) (*k3d.Node, error) { +func startToolsNode(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster, network string, volumes []string) (*k3d.Node, error) { node := &k3d.Node{ Name: fmt.Sprintf("%s-%s-tools", k3d.DefaultObjectNamePrefix, cluster.Name), Image: k3d.DefaultToolsContainerImage, From 639daef7fb6900c6a562423e173fc8ca83146210 Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Tue, 26 May 2020 12:58:43 +0200 Subject: [PATCH 2/6] Reorder parameters - runtimes.Runtime should at max. the second function parameter (right after context.Context) --- cmd/create/createCluster.go | 6 +++--- cmd/delete/deleteCluster.go | 4 ++-- cmd/delete/deleteNode.go | 2 +- cmd/get/getCluster.go | 2 +- cmd/get/getNode.go | 2 +- cmd/load/loadImage.go | 2 +- cmd/start/startCluster.go | 4 ++-- cmd/stop/stopCluster.go | 4 ++-- pkg/cluster/cluster.go | 14 +++++++------- pkg/cluster/node.go | 14 +++++++------- pkg/tools/tools.go | 2 +- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cmd/create/createCluster.go b/cmd/create/createCluster.go index 6474d382..0b55e22b 100644 --- a/cmd/create/createCluster.go +++ b/cmd/create/createCluster.go @@ -64,7 +64,7 @@ func NewCmdCreateCluster() *cobra.Command { cluster := parseCreateClusterCmd(cmd, args, createClusterOpts) // check if a cluster with that name exists already - if _, err := k3dCluster.GetCluster(cmd.Context(), cluster, runtimes.SelectedRuntime); err == nil { + 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) } @@ -73,11 +73,11 @@ func NewCmdCreateCluster() *cobra.Command { log.Debugln("'--update-kubeconfig set: enabling wait-for-master") cluster.CreateClusterOpts.WaitForMaster = true } - if err := k3dCluster.CreateCluster(cmd.Context(), cluster, runtimes.SelectedRuntime); err != nil { + 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(), cluster, runtimes.SelectedRuntime); err != nil { + if err := k3dCluster.DeleteCluster(cmd.Context(), runtimes.SelectedRuntime, cluster); err != nil { log.Errorln(err) log.Fatalln("Cluster creation FAILED, also FAILED to rollback changes!") } diff --git a/cmd/delete/deleteCluster.go b/cmd/delete/deleteCluster.go index 5bd3946c..c1578a96 100644 --- a/cmd/delete/deleteCluster.go +++ b/cmd/delete/deleteCluster.go @@ -48,7 +48,7 @@ func NewCmdDeleteCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.DeleteCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { + if err := cluster.DeleteCluster(cmd.Context(), runtimes.SelectedRuntime, c); err != nil { log.Fatalln(err) } log.Infoln("Removing cluster details from default kubeconfig") @@ -94,7 +94,7 @@ func parseDeleteClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) if err != nil { log.Fatalln(err) } diff --git a/cmd/delete/deleteNode.go b/cmd/delete/deleteNode.go index 9ddf90eb..9a11ce3f 100644 --- a/cmd/delete/deleteNode.go +++ b/cmd/delete/deleteNode.go @@ -87,7 +87,7 @@ func parseDeleteNodeCmd(cmd *cobra.Command, args []string) []*k3d.Node { } for _, name := range args { - node, err := cluster.GetNode(cmd.Context(), &k3d.Node{Name: name}, runtimes.SelectedRuntime) + node, err := cluster.GetNode(cmd.Context(), runtimes.SelectedRuntime, &k3d.Node{Name: name}) if err != nil { log.Fatalln(err) } diff --git a/cmd/get/getCluster.go b/cmd/get/getCluster.go index a3c8fba8..ac72c546 100644 --- a/cmd/get/getCluster.go +++ b/cmd/get/getCluster.go @@ -58,7 +58,7 @@ func NewCmdGetCluster() *cobra.Command { } existingClusters = append(existingClusters, found...) } else { // Option b) cluster name specified -> get specific cluster - found, err := cluster.GetCluster(cmd.Context(), clusters, runtimes.SelectedRuntime) + found, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, clusters) if err != nil { log.Fatalln(err) } diff --git a/cmd/get/getNode.go b/cmd/get/getNode.go index 26c0c823..1cae1b46 100644 --- a/cmd/get/getNode.go +++ b/cmd/get/getNode.go @@ -56,7 +56,7 @@ func NewCmdGetNode() *cobra.Command { } existingNodes = append(existingNodes, found...) } else { // Option b) cluster name specified -> get specific cluster - found, err := cluster.GetNode(cmd.Context(), node, runtimes.SelectedRuntime) + found, err := cluster.GetNode(cmd.Context(), runtimes.SelectedRuntime, node) if err != nil { log.Fatalln(err) } diff --git a/cmd/load/loadImage.go b/cmd/load/loadImage.go index 9d0edb27..1551cffc 100644 --- a/cmd/load/loadImage.go +++ b/cmd/load/loadImage.go @@ -42,7 +42,7 @@ func NewCmdLoadImage() *cobra.Command { Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { images, clusters, keepTarball := parseLoadImageCmd(cmd, args) - log.Debugf("Load images [%+v] from runtime [%s] into clusters [%+v]", runtimes.SelectedRuntime, images, clusters) + log.Debugf("Load images [%+v] from runtime [%s] into clusters [%+v]", images, runtimes.SelectedRuntime, clusters) for _, cluster := range clusters { log.Debugf("Loading images into '%s'", cluster.Name) if err := tools.LoadImagesIntoCluster(cmd.Context(), runtimes.SelectedRuntime, images, &cluster, keepTarball); err != nil { diff --git a/cmd/start/startCluster.go b/cmd/start/startCluster.go index 6a15fb4c..bcc7cd03 100644 --- a/cmd/start/startCluster.go +++ b/cmd/start/startCluster.go @@ -46,7 +46,7 @@ func NewCmdStartCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.StartCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { + if err := cluster.StartCluster(cmd.Context(), runtimes.SelectedRuntime, c); err != nil { log.Fatalln(err) } } @@ -85,7 +85,7 @@ func parseStartClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) if err != nil { log.Fatalln(err) } diff --git a/cmd/stop/stopCluster.go b/cmd/stop/stopCluster.go index d4f2b397..81d93a18 100644 --- a/cmd/stop/stopCluster.go +++ b/cmd/stop/stopCluster.go @@ -46,7 +46,7 @@ func NewCmdStopCluster() *cobra.Command { log.Infoln("No clusters found") } else { for _, c := range clusters { - if err := cluster.StopCluster(cmd.Context(), c, runtimes.SelectedRuntime); err != nil { + if err := cluster.StopCluster(cmd.Context(), runtimes.SelectedRuntime, c); err != nil { log.Fatalln(err) } } @@ -85,7 +85,7 @@ func parseStopClusterCmd(cmd *cobra.Command, args []string) []*k3d.Cluster { } for _, name := range args { - cluster, err := cluster.GetCluster(cmd.Context(), &k3d.Cluster{Name: name}, runtimes.SelectedRuntime) + cluster, err := cluster.GetCluster(cmd.Context(), runtimes.SelectedRuntime, &k3d.Cluster{Name: name}) if err != nil { log.Fatalln(err) } diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index fe571782..b115bb93 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -39,7 +39,7 @@ import ( // CreateCluster creates a new cluster consisting of // - some containerized k3s nodes // - a docker network -func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) error { if cluster.CreateClusterOpts.Timeout > 0*time.Second { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, cluster.CreateClusterOpts.Timeout) @@ -153,7 +153,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt // create node log.Infof("Creating node '%s'", node.Name) - if err := CreateNode(ctx, node, runtime); err != nil { + if err := CreateNode(ctx, runtime, node); err != nil { log.Errorln("Failed to create node") return err } @@ -305,7 +305,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt } cluster.Nodes = append(cluster.Nodes, lbNode) // append lbNode to list of cluster nodes, so it will be considered during rollback log.Infof("Creating LoadBalancer '%s'", lbNode.Name) - if err := CreateNode(ctx, lbNode, runtime); err != nil { + if err := CreateNode(ctx, runtime, lbNode); err != nil { log.Errorln("Failed to create loadbalancer") return err } @@ -317,7 +317,7 @@ func CreateCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runt } // DeleteCluster deletes an existing cluster -func DeleteCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func DeleteCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) error { log.Infof("Deleting cluster '%s'", cluster.Name) log.Debugf("%+v", cluster) @@ -437,7 +437,7 @@ func populateClusterFieldsFromLabels(cluster *k3d.Cluster) error { } // GetCluster returns an existing cluster with all fields and node lists populated -func GetCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) (*k3d.Cluster, error) { +func GetCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) (*k3d.Cluster, error) { // get nodes that belong to the selected cluster nodes, err := runtime.GetNodesByLabel(map[string]string{"k3d.cluster": cluster.Name}) if err != nil { @@ -471,7 +471,7 @@ func generateNodeName(cluster string, role k3d.Role, suffix int) string { } // StartCluster starts a whole cluster (i.e. all nodes of the cluster) -func StartCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func StartCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) error { log.Infof("Starting cluster '%s'", cluster.Name) failed := 0 @@ -508,7 +508,7 @@ func StartCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runti } // StopCluster stops a whole cluster (i.e. all nodes of the cluster) -func StopCluster(ctx context.Context, cluster *k3d.Cluster, runtime k3drt.Runtime) error { +func StopCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) error { log.Infof("Stopping cluster '%s'", cluster.Name) failed := 0 diff --git a/pkg/cluster/node.go b/pkg/cluster/node.go index 4fc30f69..49a80422 100644 --- a/pkg/cluster/node.go +++ b/pkg/cluster/node.go @@ -37,7 +37,7 @@ import ( // AddNodeToCluster adds a node to an existing cluster func AddNodeToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Cluster) error { - cluster, err := GetCluster(ctx, cluster, runtime) + cluster, err := GetCluster(ctx, runtime, cluster) if err != nil { log.Errorf("Failed to find specified cluster '%s'", cluster.Name) return err @@ -72,7 +72,7 @@ func AddNodeToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N } // get node details - chosenNode, err = GetNode(ctx, chosenNode, runtime) + chosenNode, err = GetNode(ctx, runtime, chosenNode) if err != nil { return err } @@ -104,7 +104,7 @@ func AddNodeToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N } } - if err := CreateNode(ctx, node, runtime); err != nil { + if err := CreateNode(ctx, runtime, node); err != nil { return err } @@ -120,16 +120,16 @@ func AddNodeToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N } // CreateNodes creates a list of nodes -func CreateNodes(ctx context.Context, nodes []*k3d.Node, runtime runtimes.Runtime) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? +func CreateNodes(ctx context.Context, runtime runtimes.Runtime, nodes []*k3d.Node) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? for _, node := range nodes { - if err := CreateNode(ctx, node, runtime); err != nil { + if err := CreateNode(ctx, runtime, node); err != nil { log.Error(err) } } } // CreateNode creates a new containerized k3s node -func CreateNode(ctx context.Context, node *k3d.Node, runtime runtimes.Runtime) error { +func CreateNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) error { log.Debugf("Creating node from spec\n%+v", node) /* @@ -223,7 +223,7 @@ func GetNodes(ctx context.Context, runtime runtimes.Runtime) ([]*k3d.Node, error } // GetNode returns a node matching the specified node fields -func GetNode(ctx context.Context, node *k3d.Node, runtime runtimes.Runtime) (*k3d.Node, error) { +func GetNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) (*k3d.Node, error) { // get node node, err := runtime.GetNode(node) if err != nil { diff --git a/pkg/tools/tools.go b/pkg/tools/tools.go index e11c4cf2..e7c915e2 100644 --- a/pkg/tools/tools.go +++ b/pkg/tools/tools.go @@ -36,7 +36,7 @@ import ( // LoadImagesIntoCluster starts up a k3d tools container for the selected cluster and uses it to export // images from the runtime to import them into the nodes of the selected cluster func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images []string, cluster *k3d.Cluster, keepTarball bool) error { - cluster, err := k3dc.GetCluster(ctx, cluster, runtime) + cluster, err := k3dc.GetCluster(ctx, runtime, cluster) if err != nil { log.Errorf("Failed to find the specified cluster") return err From 434cf8e91dd048c446098c1f985e85a31b91e557 Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Tue, 26 May 2020 14:47:21 +0200 Subject: [PATCH 3/6] overall: pass context from top to bottom --- cmd/start/startNode.go | 2 +- cmd/stop/stopNode.go | 2 +- pkg/cluster/cluster.go | 22 +++++++------- pkg/cluster/kubeconfig.go | 4 +-- pkg/cluster/loadbalancer.go | 2 +- pkg/cluster/node.go | 10 +++--- pkg/runtimes/containerd/kubeconfig.go | 3 +- pkg/runtimes/containerd/network.go | 6 ++-- pkg/runtimes/containerd/node.go | 18 +++++------ pkg/runtimes/containerd/volume.go | 6 ++-- pkg/runtimes/docker/container.go | 9 ++---- pkg/runtimes/docker/kubeconfig.go | 5 ++- pkg/runtimes/docker/network.go | 9 ++---- pkg/runtimes/docker/node.go | 44 ++++++++++++--------------- pkg/runtimes/docker/translate.go | 3 +- pkg/runtimes/docker/volume.go | 6 ++-- pkg/runtimes/runtime.go | 27 ++++++++-------- pkg/tools/tools.go | 10 +++--- 18 files changed, 89 insertions(+), 99 deletions(-) diff --git a/cmd/start/startNode.go b/cmd/start/startNode.go index 179770d9..9afb2c97 100644 --- a/cmd/start/startNode.go +++ b/cmd/start/startNode.go @@ -40,7 +40,7 @@ func NewCmdStartNode() *cobra.Command { Run: func(cmd *cobra.Command, args []string) { log.Debugln("start node called") node := parseStartNodeCmd(cmd, args) - if err := runtimes.SelectedRuntime.StartNode(node); err != nil { + if err := runtimes.SelectedRuntime.StartNode(cmd.Context(), node); err != nil { log.Fatalln(err) } }, diff --git a/cmd/stop/stopNode.go b/cmd/stop/stopNode.go index be69f0a0..f47af9f3 100644 --- a/cmd/stop/stopNode.go +++ b/cmd/stop/stopNode.go @@ -41,7 +41,7 @@ func NewCmdStopNode() *cobra.Command { Run: func(cmd *cobra.Command, args []string) { log.Debugln("stop node called") node := parseStopNodeCmd(cmd, args) - if err := runtimes.SelectedRuntime.StopNode(node); err != nil { + if err := runtimes.SelectedRuntime.StopNode(cmd.Context(), node); err != nil { log.Fatalln(err) } }, diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index b115bb93..9ffb25ad 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -70,7 +70,7 @@ func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus } // create cluster network or use an existing one - networkID, networkExists, err := runtime.CreateNetworkIfNotPresent(cluster.Network.Name) + networkID, networkExists, err := runtime.CreateNetworkIfNotPresent(ctx, cluster.Network.Name) if err != nil { log.Errorln("Failed to create cluster network") return err @@ -98,7 +98,7 @@ func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus */ if !cluster.CreateClusterOpts.DisableImageVolume { imageVolumeName := fmt.Sprintf("%s-%s-images", k3d.DefaultObjectNamePrefix, cluster.Name) - if err := runtime.CreateVolume(imageVolumeName, map[string]string{"k3d.cluster": cluster.Name}); err != nil { + if err := runtime.CreateVolume(ctx, imageVolumeName, map[string]string{"k3d.cluster": cluster.Name}); err != nil { log.Errorln("Failed to create image volume '%s' for cluster '%s'", imageVolumeName, cluster.Name) return err } @@ -191,7 +191,7 @@ func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus default: } log.Debugln("Waiting for initializing master node...") - logreader, err := runtime.GetNodeLogs(cluster.InitNode) + logreader, err := runtime.GetNodeLogs(ctx, cluster.InitNode) if err != nil { if logreader != nil { logreader.Close() @@ -324,7 +324,7 @@ func DeleteCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus failed := 0 for _, node := range cluster.Nodes { - if err := runtime.DeleteNode(node); err != nil { + if err := runtime.DeleteNode(ctx, node); err != nil { log.Warningf("Failed to delete node '%s': Try to delete it manually", node.Name) failed++ continue @@ -335,7 +335,7 @@ func DeleteCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus if cluster.Network.Name != "" { if !cluster.Network.External { log.Infof("Deleting cluster network '%s'", cluster.Network.Name) - if err := runtime.DeleteNetwork(cluster.Network.Name); err != nil { + if err := runtime.DeleteNetwork(ctx, cluster.Network.Name); err != nil { if strings.HasSuffix(err.Error(), "active endpoints") { log.Warningf("Failed to delete cluster network '%s' because it's still in use: is there another cluster using it?", cluster.Network.Name) } else { @@ -350,7 +350,7 @@ func DeleteCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus // delete image volume if cluster.ImageVolume != "" { log.Infof("Deleting image volume '%s'", cluster.ImageVolume) - if err := runtime.DeleteVolume(cluster.ImageVolume); err != nil { + if err := runtime.DeleteVolume(ctx, cluster.ImageVolume); err != nil { log.Warningf("Failed to delete image volume '%s' of cluster '%s': Try to delete it manually", cluster.ImageVolume, cluster.Name) } } @@ -364,7 +364,7 @@ func DeleteCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus // GetClusters returns a list of all existing clusters func GetClusters(ctx context.Context, runtime k3drt.Runtime) ([]*k3d.Cluster, error) { - nodes, err := runtime.GetNodesByLabel(k3d.DefaultObjectLabels) + nodes, err := runtime.GetNodesByLabel(ctx, k3d.DefaultObjectLabels) if err != nil { log.Errorln("Failed to get clusters") return nil, err @@ -439,7 +439,7 @@ func populateClusterFieldsFromLabels(cluster *k3d.Cluster) error { // GetCluster returns an existing cluster with all fields and node lists populated func GetCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluster) (*k3d.Cluster, error) { // get nodes that belong to the selected cluster - nodes, err := runtime.GetNodesByLabel(map[string]string{"k3d.cluster": cluster.Name}) + nodes, err := runtime.GetNodesByLabel(ctx, map[string]string{"k3d.cluster": cluster.Name}) if err != nil { log.Errorf("Failed to get nodes for cluster '%s'", cluster.Name) } @@ -485,7 +485,7 @@ func StartCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clust } // start node - if err := runtime.StartNode(node); err != nil { + if err := runtime.StartNode(ctx, node); err != nil { log.Warningf("Failed to start node '%s': Try to start it manually", node.Name) failed++ continue @@ -495,7 +495,7 @@ func StartCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clust // start masterlb if masterlb != nil { log.Debugln("Starting masterlb...") - if err := runtime.StartNode(masterlb); err != nil { // FIXME: we could run into a nullpointer exception here + if err := runtime.StartNode(ctx, masterlb); err != nil { // FIXME: we could run into a nullpointer exception here log.Warningf("Failed to start masterlb '%s': Try to start it manually", masterlb.Name) failed++ } @@ -513,7 +513,7 @@ func StopCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Cluste failed := 0 for _, node := range cluster.Nodes { - if err := runtime.StopNode(node); err != nil { + if err := runtime.StopNode(ctx, node); err != nil { log.Warningf("Failed to stop node '%s': Try to stop it manually", node.Name) failed++ continue diff --git a/pkg/cluster/kubeconfig.go b/pkg/cluster/kubeconfig.go index a71c9a4a..5681f2d4 100644 --- a/pkg/cluster/kubeconfig.go +++ b/pkg/cluster/kubeconfig.go @@ -113,7 +113,7 @@ func GetAndWriteKubeConfig(ctx context.Context, runtime runtimes.Runtime, cluste func GetKubeconfig(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster) (*clientcmdapi.Config, error) { // get all master nodes for the selected cluster // TODO: getKubeconfig: we should make sure, that the master node we're trying to fetch from is actually running - masterNodes, err := runtime.GetNodesByLabel(map[string]string{"k3d.cluster": cluster.Name, "k3d.role": string(k3d.MasterRole)}) + masterNodes, err := runtime.GetNodesByLabel(ctx, map[string]string{"k3d.cluster": cluster.Name, "k3d.role": string(k3d.MasterRole)}) if err != nil { log.Errorln("Failed to get master nodes") return nil, err @@ -143,7 +143,7 @@ func GetKubeconfig(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.C chosenMaster = masterNodes[0] } // get the kubeconfig from the first master node - reader, err := runtime.GetKubeconfig(chosenMaster) + reader, err := runtime.GetKubeconfig(ctx, chosenMaster) if err != nil { log.Errorf("Failed to get kubeconfig from node '%s'", chosenMaster.Name) return nil, err diff --git a/pkg/cluster/loadbalancer.go b/pkg/cluster/loadbalancer.go index 57ed95a0..bd7442ed 100644 --- a/pkg/cluster/loadbalancer.go +++ b/pkg/cluster/loadbalancer.go @@ -50,7 +50,7 @@ func AddMasterToLoadBalancer(ctx context.Context, runtime runtimes.Runtime, clus log.Debugf("SERVERS=%s", masterNodes) command := fmt.Sprintf("SERVERS=%s %s", masterNodes, "confd -onetime -backend env && nginx -s reload") - if err := runtime.ExecInNode(loadbalancer, []string{"sh", "-c", command}); err != nil { + if err := runtime.ExecInNode(ctx, loadbalancer, []string{"sh", "-c", command}); err != nil { log.Errorln("Failed to update loadbalancer configuration") return err } diff --git a/pkg/cluster/node.go b/pkg/cluster/node.go index 49a80422..230d4ed4 100644 --- a/pkg/cluster/node.go +++ b/pkg/cluster/node.go @@ -168,7 +168,7 @@ func CreateNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) e /* * CREATION */ - if err := runtime.CreateNode(node); err != nil { + if err := runtime.CreateNode(ctx, node); err != nil { return err } @@ -178,7 +178,7 @@ func CreateNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) e // DeleteNode deletes an existing node func DeleteNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) error { - if err := runtime.DeleteNode(node); err != nil { + if err := runtime.DeleteNode(ctx, node); err != nil { log.Error(err) } return nil @@ -213,7 +213,7 @@ func patchMasterSpec(node *k3d.Node) error { // GetNodes returns a list of all existing clusters func GetNodes(ctx context.Context, runtime runtimes.Runtime) ([]*k3d.Node, error) { - nodes, err := runtime.GetNodesByLabel(k3d.DefaultObjectLabels) + nodes, err := runtime.GetNodesByLabel(ctx, k3d.DefaultObjectLabels) if err != nil { log.Errorln("Failed to get nodes") return nil, err @@ -225,7 +225,7 @@ func GetNodes(ctx context.Context, runtime runtimes.Runtime) ([]*k3d.Node, error // GetNode returns a node matching the specified node fields func GetNode(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node) (*k3d.Node, error) { // get node - node, err := runtime.GetNode(node) + node, err := runtime.GetNode(ctx, node) if err != nil { log.Errorf("Failed to get node '%s'", node.Name) } @@ -243,7 +243,7 @@ func WaitForNodeLogMessage(ctx context.Context, runtime runtimes.Runtime, node * } // read the logs - out, err := runtime.GetNodeLogs(node) + out, err := runtime.GetNodeLogs(ctx, node) if err != nil { if out != nil { out.Close() diff --git a/pkg/runtimes/containerd/kubeconfig.go b/pkg/runtimes/containerd/kubeconfig.go index 805ea5ee..2faa3e96 100644 --- a/pkg/runtimes/containerd/kubeconfig.go +++ b/pkg/runtimes/containerd/kubeconfig.go @@ -23,12 +23,13 @@ THE SOFTWARE. package containerd import ( + "context" "io" k3d "github.com/rancher/k3d/pkg/types" ) // GetKubeconfig grabs the kubeconfig from inside a k3d node -func (d Containerd) GetKubeconfig(node *k3d.Node) (io.ReadCloser, error) { +func (d Containerd) GetKubeconfig(ctx context.Context, node *k3d.Node) (io.ReadCloser, error) { return nil, nil } diff --git a/pkg/runtimes/containerd/network.go b/pkg/runtimes/containerd/network.go index 1caa532c..64634e64 100644 --- a/pkg/runtimes/containerd/network.go +++ b/pkg/runtimes/containerd/network.go @@ -21,12 +21,14 @@ THE SOFTWARE. */ package containerd +import "context" + // CreateNetworkIfNotPresent creates a new docker network -func (d Containerd) CreateNetworkIfNotPresent(name string) (string, bool, error) { +func (d Containerd) CreateNetworkIfNotPresent(ctx context.Context, name string) (string, bool, error) { return "", false, nil } // DeleteNetwork deletes a network -func (d Containerd) DeleteNetwork(ID string) error { +func (d Containerd) DeleteNetwork(ctx context.Context, ID string) error { return nil } diff --git a/pkg/runtimes/containerd/node.go b/pkg/runtimes/containerd/node.go index b1884f25..324efbf4 100644 --- a/pkg/runtimes/containerd/node.go +++ b/pkg/runtimes/containerd/node.go @@ -33,11 +33,10 @@ import ( ) // CreateNode creates a new k3d node -func (d Containerd) CreateNode(node *k3d.Node) error { +func (d Containerd) CreateNode(ctx context.Context, node *k3d.Node) error { log.Debugln("containerd.CreateNode...") // create containerd client - ctx := context.Background() clientOpts := []containerd.ClientOpt{ containerd.WithDefaultNamespace("k3d"), } @@ -77,9 +76,8 @@ func (d Containerd) CreateNode(node *k3d.Node) error { } // DeleteNode deletes an existing k3d node -func (d Containerd) DeleteNode(node *k3d.Node) error { +func (d Containerd) DeleteNode(ctx context.Context, node *k3d.Node) error { log.Debugln("containerd.DeleteNode...") - ctx := context.Background() clientOpts := []containerd.ClientOpt{ containerd.WithDefaultNamespace("k3d"), } @@ -103,30 +101,30 @@ func (d Containerd) DeleteNode(node *k3d.Node) error { } // StartNode starts an existing node -func (d Containerd) StartNode(node *k3d.Node) error { +func (d Containerd) StartNode(ctx context.Context, node *k3d.Node) error { return nil // TODO: fill } // StopNode stops an existing node -func (d Containerd) StopNode(node *k3d.Node) error { +func (d Containerd) StopNode(ctx context.Context, node *k3d.Node) error { return nil // TODO: fill } -func (d Containerd) GetNodesByLabel(labels map[string]string) ([]*k3d.Node, error) { +func (d Containerd) GetNodesByLabel(ctx context.Context, labels map[string]string) ([]*k3d.Node, error) { return nil, nil } // GetNode tries to get a node container by its name -func (d Containerd) GetNode(node *k3d.Node) (*k3d.Node, error) { +func (d Containerd) GetNode(ctx context.Context, node *k3d.Node) (*k3d.Node, error) { return nil, nil } // GetNodeLogs returns the logs from a given node -func (d Containerd) GetNodeLogs(node *k3d.Node) (io.ReadCloser, error) { +func (d Containerd) GetNodeLogs(ctx context.Context, node *k3d.Node) (io.ReadCloser, error) { return nil, nil } // ExecInNode execs a command inside a node -func (d Containerd) ExecInNode(node *k3d.Node, cmd []string) error { +func (d Containerd) ExecInNode(ctx context.Context, node *k3d.Node, cmd []string) error { return nil } diff --git a/pkg/runtimes/containerd/volume.go b/pkg/runtimes/containerd/volume.go index 7dc49dcf..8d647047 100644 --- a/pkg/runtimes/containerd/volume.go +++ b/pkg/runtimes/containerd/volume.go @@ -21,12 +21,14 @@ THE SOFTWARE. */ package containerd +import "context" + // CreateVolume creates a new named volume -func (d Containerd) CreateVolume(name string, labels map[string]string) error { +func (d Containerd) CreateVolume(ctx context.Context, name string, labels map[string]string) error { return nil } // DeleteVolume creates a new named volume -func (d Containerd) DeleteVolume(name string) error { +func (d Containerd) DeleteVolume(ctx context.Context, name string) error { return nil } diff --git a/pkg/runtimes/docker/container.go b/pkg/runtimes/docker/container.go index 9aab8faa..b397cf18 100644 --- a/pkg/runtimes/docker/container.go +++ b/pkg/runtimes/docker/container.go @@ -38,12 +38,11 @@ import ( ) // createContainer creates a new docker container from translated specs -func createContainer(dockerNode *NodeInDocker, name string) error { +func createContainer(ctx context.Context, dockerNode *NodeInDocker, name string) error { log.Debugf("Creating docker container with translated config\n%+v\n", dockerNode) // TODO: remove? // initialize docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -80,10 +79,9 @@ func createContainer(dockerNode *NodeInDocker, name string) error { } // removeContainer deletes a running container (like docker rm -f) -func removeContainer(ID string) error { +func removeContainer(ctx context.Context, ID string) error { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -135,9 +133,8 @@ func pullImage(ctx *context.Context, docker *client.Client, image string) error } -func getNodeContainer(node *k3d.Node) (*types.Container, error) { +func getNodeContainer(ctx context.Context, node *k3d.Node) (*types.Container, error) { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") diff --git a/pkg/runtimes/docker/kubeconfig.go b/pkg/runtimes/docker/kubeconfig.go index 6bdc16cd..ad7cc85d 100644 --- a/pkg/runtimes/docker/kubeconfig.go +++ b/pkg/runtimes/docker/kubeconfig.go @@ -32,8 +32,7 @@ import ( ) // GetKubeconfig grabs the kubeconfig from inside a k3d node -func (d Docker) GetKubeconfig(node *k3d.Node) (io.ReadCloser, error) { - ctx := context.Background() +func (d Docker) GetKubeconfig(ctx context.Context, node *k3d.Node) (io.ReadCloser, error) { docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -41,7 +40,7 @@ func (d Docker) GetKubeconfig(node *k3d.Node) (io.ReadCloser, error) { } defer docker.Close() - container, err := getNodeContainer(node) + container, err := getNodeContainer(ctx, node) if err != nil { return nil, err } diff --git a/pkg/runtimes/docker/network.go b/pkg/runtimes/docker/network.go index aacaeb05..63ccd6e7 100644 --- a/pkg/runtimes/docker/network.go +++ b/pkg/runtimes/docker/network.go @@ -34,10 +34,9 @@ import ( // CreateNetworkIfNotPresent creates a new docker network // @return: network name, exists, error -func (d Docker) CreateNetworkIfNotPresent(name string) (string, bool, error) { +func (d Docker) CreateNetworkIfNotPresent(ctx context.Context, name string) (string, bool, error) { // (0) create new docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -82,9 +81,8 @@ func (d Docker) CreateNetworkIfNotPresent(name string) (string, bool, error) { } // DeleteNetwork deletes a network -func (d Docker) DeleteNetwork(ID string) error { +func (d Docker) DeleteNetwork(ctx context.Context, ID string) error { // (0) create new docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -97,8 +95,7 @@ func (d Docker) DeleteNetwork(ID string) error { } // GetNetwork gets information about a network by its ID -func GetNetwork(ID string) (types.NetworkResource, error) { - ctx := context.Background() +func GetNetwork(ctx context.Context, ID string) (types.NetworkResource, error) { docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") diff --git a/pkg/runtimes/docker/node.go b/pkg/runtimes/docker/node.go index 840be3ef..5443aa99 100644 --- a/pkg/runtimes/docker/node.go +++ b/pkg/runtimes/docker/node.go @@ -37,7 +37,7 @@ import ( ) // CreateNode creates a new container -func (d Docker) CreateNode(node *k3d.Node) error { +func (d Docker) CreateNode(ctx context.Context, node *k3d.Node) error { // translate node spec to docker container specs dockerNode, err := TranslateNodeToContainer(node) @@ -47,7 +47,7 @@ func (d Docker) CreateNode(node *k3d.Node) error { } // create node - if err := createContainer(dockerNode, node.Name); err != nil { + if err := createContainer(ctx, dockerNode, node.Name); err != nil { log.Errorln("Failed to create k3d node") return err } @@ -56,16 +56,16 @@ func (d Docker) CreateNode(node *k3d.Node) error { } // DeleteNode deletes a node -func (d Docker) DeleteNode(nodeSpec *k3d.Node) error { +func (d Docker) DeleteNode(ctx context.Context, nodeSpec *k3d.Node) error { log.Debugln("docker.DeleteNode...") - return removeContainer(nodeSpec.Name) + return removeContainer(ctx, nodeSpec.Name) } // GetNodesByLabel returns a list of existing nodes -func (d Docker) GetNodesByLabel(labels map[string]string) ([]*k3d.Node, error) { +func (d Docker) GetNodesByLabel(ctx context.Context, labels map[string]string) ([]*k3d.Node, error) { // (0) get containers - containers, err := getContainersByLabel(labels) + containers, err := getContainersByLabel(ctx, labels) if err != nil { return nil, err } @@ -85,9 +85,8 @@ func (d Docker) GetNodesByLabel(labels map[string]string) ([]*k3d.Node, error) { } // StartNode starts an existing node -func (d Docker) StartNode(node *k3d.Node) error { +func (d Docker) StartNode(ctx context.Context, node *k3d.Node) error { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return fmt.Errorf("Failed to create docker client. %+v", err) @@ -95,7 +94,7 @@ func (d Docker) StartNode(node *k3d.Node) error { defer docker.Close() // get container which represents the node - nodeContainer, err := getNodeContainer(node) + nodeContainer, err := getNodeContainer(ctx, node) if err != nil { log.Errorf("Failed to get container for node '%s'", node.Name) return err @@ -116,9 +115,8 @@ func (d Docker) StartNode(node *k3d.Node) error { } // StopNode stops an existing node -func (d Docker) StopNode(node *k3d.Node) error { +func (d Docker) StopNode(ctx context.Context, node *k3d.Node) error { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return fmt.Errorf("Failed to create docker client. %+v", err) @@ -126,7 +124,7 @@ func (d Docker) StopNode(node *k3d.Node) error { defer docker.Close() // get container which represents the node - nodeContainer, err := getNodeContainer(node) + nodeContainer, err := getNodeContainer(ctx, node) if err != nil { log.Errorf("Failed to get container for node '%s'", node.Name) return err @@ -145,9 +143,8 @@ func (d Docker) StopNode(node *k3d.Node) error { return nil } -func getContainersByLabel(labels map[string]string) ([]types.Container, error) { +func getContainersByLabel(ctx context.Context, labels map[string]string) ([]types.Container, error) { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return nil, fmt.Errorf("Failed to create docker client. %+v", err) @@ -176,9 +173,8 @@ func getContainersByLabel(labels map[string]string) ([]types.Container, error) { } // getContainer details returns the containerjson with more details -func getContainerDetails(containerID string) (types.ContainerJSON, error) { +func getContainerDetails(ctx context.Context, containerID string) (types.ContainerJSON, error) { // (0) create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return types.ContainerJSON{}, fmt.Errorf("Failed to create docker client. %+v", err) @@ -196,14 +192,14 @@ func getContainerDetails(containerID string) (types.ContainerJSON, error) { } // GetNode tries to get a node container by its name -func (d Docker) GetNode(node *k3d.Node) (*k3d.Node, error) { - container, err := getNodeContainer(node) +func (d Docker) GetNode(ctx context.Context, node *k3d.Node) (*k3d.Node, error) { + container, err := getNodeContainer(ctx, node) if err != nil { log.Errorf("Failed to get container for node '%s'", node.Name) return nil, err } - containerDetails, err := getContainerDetails(container.ID) + containerDetails, err := getContainerDetails(ctx, container.ID) if err != nil { return nil, err } @@ -219,15 +215,14 @@ func (d Docker) GetNode(node *k3d.Node) (*k3d.Node, error) { } // GetNodeLogs returns the logs from a given node -func (d Docker) GetNodeLogs(node *k3d.Node) (io.ReadCloser, error) { +func (d Docker) GetNodeLogs(ctx context.Context, node *k3d.Node) (io.ReadCloser, error) { // get the container for the given node - container, err := getNodeContainer(node) + container, err := getNodeContainer(ctx, node) if err != nil { return nil, err } // create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -255,18 +250,17 @@ func (d Docker) GetNodeLogs(node *k3d.Node) (io.ReadCloser, error) { } // ExecInNode execs a command inside a node -func (d Docker) ExecInNode(node *k3d.Node, cmd []string) error { +func (d Docker) ExecInNode(ctx context.Context, node *k3d.Node, cmd []string) error { log.Debugf("Exec cmds '%+v' in node '%s'", cmd, node.Name) // get the container for the given node - container, err := getNodeContainer(node) + container, err := getNodeContainer(ctx, node) if err != nil { return err } // create docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") diff --git a/pkg/runtimes/docker/translate.go b/pkg/runtimes/docker/translate.go index 0020b14b..7f13be74 100644 --- a/pkg/runtimes/docker/translate.go +++ b/pkg/runtimes/docker/translate.go @@ -23,6 +23,7 @@ THE SOFTWARE. package docker import ( + "context" "fmt" "strings" @@ -92,7 +93,7 @@ func TranslateNodeToContainer(node *k3d.Node) (*NodeInDocker, error) { networkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ node.Network: {}, } - netInfo, err := GetNetwork(node.Network) + netInfo, err := GetNetwork(context.Background(), node.Network) if err != nil { log.Warnln("Failed to get network information") log.Warnln(err) diff --git a/pkg/runtimes/docker/volume.go b/pkg/runtimes/docker/volume.go index b64ece54..b1dfda0b 100644 --- a/pkg/runtimes/docker/volume.go +++ b/pkg/runtimes/docker/volume.go @@ -32,9 +32,8 @@ import ( ) // CreateVolume creates a new named volume -func (d Docker) CreateVolume(name string, labels map[string]string) error { +func (d Docker) CreateVolume(ctx context.Context, name string, labels map[string]string) error { // (0) create new docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") @@ -63,9 +62,8 @@ func (d Docker) CreateVolume(name string, labels map[string]string) error { } // DeleteVolume creates a new named volume -func (d Docker) DeleteVolume(name string) error { +func (d Docker) DeleteVolume(ctx context.Context, name string) error { // (0) create new docker client - ctx := context.Background() docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Errorln("Failed to create docker client") diff --git a/pkg/runtimes/runtime.go b/pkg/runtimes/runtime.go index 93997583..91da0e42 100644 --- a/pkg/runtimes/runtime.go +++ b/pkg/runtimes/runtime.go @@ -22,6 +22,7 @@ THE SOFTWARE. package runtimes import ( + "context" "fmt" "io" @@ -41,21 +42,21 @@ var Runtimes = map[string]Runtime{ // Runtime defines an interface that can be implemented for various container runtime environments (docker, containerd, etc.) type Runtime interface { - CreateNode(*k3d.Node) error - DeleteNode(*k3d.Node) error - GetNodesByLabel(map[string]string) ([]*k3d.Node, error) - GetNode(*k3d.Node) (*k3d.Node, error) - CreateNetworkIfNotPresent(name string) (string, bool, error) // @return NETWORK_NAME, EXISTS, ERROR - GetKubeconfig(*k3d.Node) (io.ReadCloser, error) - DeleteNetwork(ID string) error - StartNode(*k3d.Node) error - StopNode(*k3d.Node) error - CreateVolume(string, map[string]string) error - DeleteVolume(string) error + CreateNode(context.Context, *k3d.Node) error + DeleteNode(context.Context, *k3d.Node) error + GetNodesByLabel(context.Context, map[string]string) ([]*k3d.Node, error) + GetNode(context.Context, *k3d.Node) (*k3d.Node, error) + CreateNetworkIfNotPresent(context.Context, string) (string, bool, error) // @return NETWORK_NAME, EXISTS, ERROR + GetKubeconfig(context.Context, *k3d.Node) (io.ReadCloser, error) + DeleteNetwork(context.Context, string) error + StartNode(context.Context, *k3d.Node) error + StopNode(context.Context, *k3d.Node) error + CreateVolume(context.Context, string, map[string]string) error + DeleteVolume(context.Context, string) error GetRuntimePath() string // returns e.g. '/var/run/docker.sock' for a default docker setup - ExecInNode(*k3d.Node, []string) error + ExecInNode(context.Context, *k3d.Node, []string) error // DeleteContainer() error - GetNodeLogs(*k3d.Node) (io.ReadCloser, error) + GetNodeLogs(context.Context, *k3d.Node) (io.ReadCloser, error) } // GetRuntime checks, if a given name is represented by an implemented k3d runtime and returns it diff --git a/pkg/tools/tools.go b/pkg/tools/tools.go index e7c915e2..ddb8fdc4 100644 --- a/pkg/tools/tools.go +++ b/pkg/tools/tools.go @@ -79,7 +79,7 @@ func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images // save image to tarfile in shared volume log.Infoln("Saving images...") tarName := fmt.Sprintf("%s/k3d-%s-images-%s.tar", k3d.DefaultImageVolumeMountPath, cluster.Name, time.Now().Format("20060102150405")) // FIXME: change - if err := runtime.ExecInNode(toolsNode, append([]string{"./k3d-tools", "save-image", "-d", tarName}, images...)); err != nil { + if err := runtime.ExecInNode(ctx, toolsNode, append([]string{"./k3d-tools", "save-image", "-d", tarName}, images...)); err != nil { log.Errorf("Failed to save images in tools container for cluster '%s'", cluster.Name) return err } @@ -93,7 +93,7 @@ func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images importWaitgroup.Add(1) go func(node *k3d.Node, wg *sync.WaitGroup) { log.Infof("Importing images into node '%s'...", node.Name) - if err := runtime.ExecInNode(node, []string{"ctr", "image", "import", tarName}); err != nil { + if err := runtime.ExecInNode(ctx, node, []string{"ctr", "image", "import", tarName}); err != nil { log.Errorf("Failed to import images in node '%s'", node.Name) log.Errorln(err) } @@ -106,7 +106,7 @@ func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images // remove tarball if !keepTarball { log.Infoln("Removing the tarball...") - if err := runtime.ExecInNode(cluster.Nodes[0], []string{"rm", "-f", tarName}); err != nil { // TODO: do this in tools node (requires rm) + if err := runtime.ExecInNode(ctx, cluster.Nodes[0], []string{"rm", "-f", tarName}); err != nil { // TODO: do this in tools node (requires rm) log.Errorf("Failed to delete tarball '%s'", tarName) log.Errorln(err) } @@ -114,7 +114,7 @@ func LoadImagesIntoCluster(ctx context.Context, runtime runtimes.Runtime, images // delete tools container log.Infoln("Removing k3d-tools node...") - if err := runtime.DeleteNode(toolsNode); err != nil { + if err := runtime.DeleteNode(ctx, toolsNode); err != nil { log.Errorln("Failed to delete tools node '%s': Try to delete it manually", toolsNode.Name) } @@ -135,7 +135,7 @@ func startToolsNode(ctx context.Context, runtime runtimes.Runtime, cluster *k3d. Cmd: []string{}, Args: []string{"noop"}, } - if err := runtime.CreateNode(node); err != nil { + if err := runtime.CreateNode(ctx, node); err != nil { log.Errorf("Failed to create tools container for cluster '%s'", cluster.Name) return node, err } From f6c312256efa39bb07e65d594cea171f75299644 Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Tue, 26 May 2020 15:12:34 +0200 Subject: [PATCH 4/6] add names to error messages --- pkg/runtimes/docker/container.go | 4 ++-- pkg/runtimes/docker/node.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/runtimes/docker/container.go b/pkg/runtimes/docker/container.go index b397cf18..d2d189e2 100644 --- a/pkg/runtimes/docker/container.go +++ b/pkg/runtimes/docker/container.go @@ -57,12 +57,12 @@ func createContainer(ctx context.Context, dockerNode *NodeInDocker, name string) if err != nil { if client.IsErrNotFound(err) { if err := pullImage(&ctx, docker, dockerNode.ContainerConfig.Image); err != nil { - log.Errorln("Failed to create container") + log.Errorf("Failed to create container '%s'", name) return err } continue } - log.Errorln("Failed to create container") + log.Errorf("Failed to create container '%s'", name) return err } log.Debugln("Created container", resp.ID) diff --git a/pkg/runtimes/docker/node.go b/pkg/runtimes/docker/node.go index fc418a0c..9a82728c 100644 --- a/pkg/runtimes/docker/node.go +++ b/pkg/runtimes/docker/node.go @@ -48,7 +48,7 @@ func (d Docker) CreateNode(ctx context.Context, node *k3d.Node) error { // create node if err := createContainer(ctx, dockerNode, node.Name); err != nil { - log.Errorln("Failed to create k3d node") + log.Errorf("Failed to create node '%s'", node.Name) return err } From 7817054801b14f0f74f9b0dc02c6c6d5a51d552b Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Tue, 26 May 2020 17:15:20 +0200 Subject: [PATCH 5/6] do not use context pointer --- pkg/runtimes/docker/container.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/runtimes/docker/container.go b/pkg/runtimes/docker/container.go index d2d189e2..c83fc2e9 100644 --- a/pkg/runtimes/docker/container.go +++ b/pkg/runtimes/docker/container.go @@ -56,7 +56,7 @@ func createContainer(ctx context.Context, dockerNode *NodeInDocker, name string) resp, err = docker.ContainerCreate(ctx, &dockerNode.ContainerConfig, &dockerNode.HostConfig, &dockerNode.NetworkingConfig, name) if err != nil { if client.IsErrNotFound(err) { - if err := pullImage(&ctx, docker, dockerNode.ContainerConfig.Image); err != nil { + if err := pullImage(ctx, docker, dockerNode.ContainerConfig.Image); err != nil { log.Errorf("Failed to create container '%s'", name) return err } @@ -107,9 +107,9 @@ func removeContainer(ctx context.Context, ID string) error { } // pullImage pulls a container image and outputs progress if --verbose flag is set -func pullImage(ctx *context.Context, docker *client.Client, image string) error { +func pullImage(ctx context.Context, docker *client.Client, image string) error { - resp, err := docker.ImagePull(*ctx, image, types.ImagePullOptions{}) + resp, err := docker.ImagePull(ctx, image, types.ImagePullOptions{}) if err != nil { log.Errorf("Failed to pull image '%s'", image) return err From d3766a5a1e823e4523a34848b399ef3262f028fd Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Fri, 29 May 2020 12:33:22 +0200 Subject: [PATCH 6/6] createCluster: also wait for loadbalancer to be up and running before returning --- pkg/cluster/cluster.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 6aebf623..c51c8515 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -259,12 +259,6 @@ func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus } } - if err := waitForMasterWaitgroup.Wait(); err != nil { - log.Errorln("Failed to bring up all master nodes in time. Check the logs:") - log.Errorln(">>> ", err) - return fmt.Errorf("Failed to bring up cluster") - } - /* * Auxiliary Containers */ @@ -310,10 +304,25 @@ func CreateCluster(ctx context.Context, runtime k3drt.Runtime, cluster *k3d.Clus log.Errorln("Failed to create loadbalancer") return err } + if cluster.CreateClusterOpts.WaitForMaster { + waitForMasterWaitgroup.Go(func() error { + // TODO: avoid `level=fatal msg="starting kubernetes: preparing server: post join: a configuration change is already in progress (5)"` + // ... by scanning for this line in logs and restarting the container in case it appears + log.Debugf("Starting to wait for loadbalancer node '%s'", lbNode.Name) + return WaitForNodeLogMessage(ctx, runtime, lbNode, "start worker processes", time.Time{}) + }) + } } else { log.Infoln("Hostnetwork selected -> Skipping creation of Master LoadBalancer") } } + + if err := waitForMasterWaitgroup.Wait(); err != nil { + log.Errorln("Failed to bring up all master nodes (and loadbalancer) in time. Check the logs:") + log.Errorf(">>> %+v", err) + return fmt.Errorf("Failed to bring up cluster") + } + return nil }