initialize proper timeout flag
This commit is contained in:
parent
d8eb206e44
commit
80d1c5c2de
@ -25,6 +25,7 @@ package create
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -50,11 +51,17 @@ func NewCmdCreateCluster() *cobra.Command {
|
|||||||
Long: `Create a new k3s cluster with containerized nodes (k3s in docker).`,
|
Long: `Create a new k3s cluster with containerized nodes (k3s in docker).`,
|
||||||
Args: cobra.RangeArgs(0, 1), // exactly one cluster name can be set (default: k3d.DefaultClusterName)
|
Args: cobra.RangeArgs(0, 1), // exactly one cluster name can be set (default: k3d.DefaultClusterName)
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// parse args and flags
|
||||||
cluster := parseCreateClusterCmd(cmd, args, createClusterOpts)
|
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(cluster, runtimes.SelectedRuntime); err == nil {
|
||||||
log.Fatalf("Failed to create cluster '%s' because a cluster with that name already exists", cluster.Name)
|
log.Fatalf("Failed to create cluster '%s' because a cluster with that name already exists", cluster.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create cluster
|
||||||
if err := k3dCluster.CreateCluster(cluster, runtimes.SelectedRuntime); err != nil {
|
if err := k3dCluster.CreateCluster(cluster, runtimes.SelectedRuntime); err != nil {
|
||||||
|
// rollback if creation failed
|
||||||
log.Errorln(err)
|
log.Errorln(err)
|
||||||
log.Errorln("Failed to create cluster >>> Rolling Back")
|
log.Errorln("Failed to create cluster >>> Rolling Back")
|
||||||
if err := k3dCluster.DeleteCluster(cluster, runtimes.SelectedRuntime); err != nil {
|
if err := k3dCluster.DeleteCluster(cluster, runtimes.SelectedRuntime); err != nil {
|
||||||
@ -63,6 +70,8 @@ func NewCmdCreateCluster() *cobra.Command {
|
|||||||
}
|
}
|
||||||
log.Fatalln("Cluster creation FAILED, all changes have been rolled back!")
|
log.Fatalln("Cluster creation FAILED, all changes have been rolled back!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print information on how to use the cluster with kubectl
|
||||||
log.Infof("Cluster '%s' created successfully. You can now use it like this:", cluster.Name)
|
log.Infof("Cluster '%s' created successfully. You can now use it like this:", cluster.Name)
|
||||||
fmt.Printf("export KUBECONFIG=$(%s get kubeconfig %s)\n", os.Args[0], cluster.Name)
|
fmt.Printf("export KUBECONFIG=$(%s get kubeconfig %s)\n", os.Args[0], cluster.Name)
|
||||||
fmt.Println("kubectl cluster-info")
|
fmt.Println("kubectl cluster-info")
|
||||||
@ -80,7 +89,8 @@ func NewCmdCreateCluster() *cobra.Command {
|
|||||||
cmd.Flags().String("secret", "", "Specify a cluster secret. By default, we generate one.")
|
cmd.Flags().String("secret", "", "Specify a cluster secret. 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("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().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().IntVar(&createClusterOpts.WaitForMaster, "wait", -1, "Wait for a specified amount of time (seconds >= 0, where 0 means forever) for the master(s) to be ready or timeout and rollback before returning")
|
cmd.Flags().BoolVar(&createClusterOpts.WaitForMaster, "wait", false, "Wait for 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.")
|
||||||
|
|
||||||
/* Image Importing */
|
/* Image Importing */
|
||||||
cmd.Flags().BoolVar(&createClusterOpts.DisableImageVolume, "no-image-volume", false, "Disable the creation of a volume for importing images")
|
cmd.Flags().BoolVar(&createClusterOpts.DisableImageVolume, "no-image-volume", false, "Disable the creation of a volume for importing images")
|
||||||
@ -167,9 +177,9 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string, createClusterOpts
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --wait
|
// --timeout
|
||||||
if cmd.Flags().Changed("wait") && createClusterOpts.WaitForMaster < 0 {
|
if cmd.Flags().Changed("timeout") && createClusterOpts.Timeout <= 0*time.Second {
|
||||||
log.Fatalln("Value of '--wait' can't be less than 0")
|
log.Fatalln("--timeout DURATION must be >= 1s")
|
||||||
}
|
}
|
||||||
|
|
||||||
// --api-port
|
// --api-port
|
||||||
|
|||||||
@ -23,6 +23,7 @@ package cluster
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -40,6 +41,11 @@ import (
|
|||||||
// - a docker network
|
// - a docker network
|
||||||
func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
|
func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
|
||||||
|
|
||||||
|
log.Debugf("Cluster creation will timeout after %s at %s", cluster.CreateClusterOpts.Timeout, time.Now().Add(cluster.CreateClusterOpts.Timeout))
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), cluster.CreateClusterOpts.Timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Network
|
* Network
|
||||||
*/
|
*/
|
||||||
@ -212,14 +218,14 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// asynchronously wait for this master node to be ready (by checking the logs for a specific log mesage)
|
// asynchronously wait for this master node to be ready (by checking the logs for a specific log mesage)
|
||||||
if node.Role == k3d.MasterRole && cluster.CreateClusterOpts.WaitForMaster >= 0 {
|
if node.Role == k3d.MasterRole && cluster.CreateClusterOpts.Timeout >= time.Second {
|
||||||
waitForMasterWaitgroup.Add(1)
|
waitForMasterWaitgroup.Add(1)
|
||||||
go func(masterNode *k3d.Node) {
|
go func(masterNode *k3d.Node) {
|
||||||
// TODO: avoid `level=fatal msg="starting kubernetes: preparing server: post join: a configuration change is already in progress (5)"`
|
// 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
|
// ... by scanning for this line in logs and restarting the container in case it appears
|
||||||
log.Debugf("Starting to wait for master node '%s'", masterNode.Name)
|
log.Debugf("Starting to wait for master node '%s'", masterNode.Name)
|
||||||
// TODO: it may be better to give endtime=starttime+timeout here so that there is no difference between the instances (go func may be called with a few (milli-)seconds difference)
|
// TODO: it may be better to give endtime=starttime+timeout here so that there is no difference between the instances (go func may be called with a few (milli-)seconds difference)
|
||||||
err := WaitForNodeLogMessage(runtime, masterNode, "Wrote kubeconfig", (time.Duration(cluster.CreateClusterOpts.WaitForMaster) * time.Second))
|
err := WaitForNodeLogMessage(runtime, masterNode, "Wrote kubeconfig", (time.Duration(cluster.CreateClusterOpts.Timeout) * time.Second))
|
||||||
waitForMasterErrChan <- err
|
waitForMasterErrChan <- err
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Debugf("Master Node '%s' ready", masterNode.Name)
|
log.Debugf("Master Node '%s' ready", masterNode.Name)
|
||||||
@ -229,7 +235,7 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// block until all masters are ready (if --wait was set) and collect errors if not
|
// block until all masters are ready (if --wait was set) and collect errors if not
|
||||||
if cluster.CreateClusterOpts.WaitForMaster >= 0 {
|
if cluster.CreateClusterOpts.Timeout >= time.Second {
|
||||||
errs := []error{}
|
errs := []error{}
|
||||||
go func() {
|
go func() {
|
||||||
for elem := range waitForMasterErrChan {
|
for elem := range waitForMasterErrChan {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultClusterName specifies the default name used for newly created clusters
|
// DefaultClusterName specifies the default name used for newly created clusters
|
||||||
@ -97,7 +98,8 @@ const DefaultAPIHost = "0.0.0.0"
|
|||||||
// CreateClusterOpts describe a set of options one can set when creating a cluster
|
// CreateClusterOpts describe a set of options one can set when creating a cluster
|
||||||
type CreateClusterOpts struct {
|
type CreateClusterOpts struct {
|
||||||
DisableImageVolume bool
|
DisableImageVolume bool
|
||||||
WaitForMaster int
|
WaitForMaster bool
|
||||||
|
Timeout time.Duration
|
||||||
K3sServerArgs []string
|
K3sServerArgs []string
|
||||||
K3sAgentArgs []string
|
K3sAgentArgs []string
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user