diff --git a/cmd/clusterctl/clusterdeployer/bootstrap/options.go b/cmd/clusterctl/clusterdeployer/bootstrap/options.go index c1444411db4b..6867276069cf 100644 --- a/cmd/clusterctl/clusterdeployer/bootstrap/options.go +++ b/cmd/clusterctl/clusterdeployer/bootstrap/options.go @@ -21,6 +21,7 @@ import "github.com/spf13/pflag" type Options struct { Type string Cleanup bool + TimeoutMachineReady int ExtraFlags []string KubeConfig string } @@ -28,6 +29,7 @@ type Options struct { func (o *Options) AddFlags(fs *pflag.FlagSet) { fs.StringVarP(&o.Type, "bootstrap-type", "", "none", "The cluster bootstrapper to use.") fs.BoolVarP(&o.Cleanup, "bootstrap-cluster-cleanup", "", true, "Whether to cleanup the bootstrap cluster after bootstrap.") + fs.IntVarP(&o.TimeoutMachineReady, "bootstrap-machine-ready-timeout", "", 30, "timeout (in minute) for the machine to be ready.") fs.StringVarP(&o.KubeConfig, "bootstrap-cluster-kubeconfig", "e", "", "Sets the bootstrap cluster to be an existing Kubernetes cluster.") fs.StringSliceVarP(&o.ExtraFlags, "bootstrap-flags", "", []string{}, "Command line flags to be passed to the chosen bootstrapper") } diff --git a/cmd/clusterctl/clusterdeployer/clusterclient/clusterclient.go b/cmd/clusterctl/clusterdeployer/clusterclient/clusterclient.go index 9bdd7a9fc9c5..8d010ba57b9c 100644 --- a/cmd/clusterctl/clusterdeployer/clusterclient/clusterclient.go +++ b/cmd/clusterctl/clusterdeployer/clusterclient/clusterclient.go @@ -50,7 +50,6 @@ const ( retryIntervalResourceDelete = 10 * time.Second timeoutKubectlApply = 15 * time.Minute timeoutResourceReady = 15 * time.Minute - timeoutMachineReady = 30 * time.Minute timeoutResourceDelete = 15 * time.Minute machineClusterLabelName = "cluster.k8s.io/cluster-name" ) @@ -63,7 +62,7 @@ type Client interface { CreateMachineClass(*clusterv1.MachineClass) error CreateMachineDeployments([]*clusterv1.MachineDeployment, string) error CreateMachineSets([]*clusterv1.MachineSet, string) error - CreateMachines([]*clusterv1.Machine, string) error + CreateMachines([]*clusterv1.Machine, string, time.Duration) error Delete(string) error DeleteClusters(string) error DeleteNamespace(string) error @@ -469,7 +468,7 @@ func (c *client) CreateMachineSets(machineSets []*clusterv1.MachineSet, namespac return nil } -func (c *client) CreateMachines(machines []*clusterv1.Machine, namespace string) error { +func (c *client) CreateMachines(machines []*clusterv1.Machine, namespace string, timeoutMachineReady time.Duration) error { var ( wg sync.WaitGroup errOnce sync.Once @@ -490,7 +489,7 @@ func (c *client) CreateMachines(machines []*clusterv1.Machine, namespace string) return } - if err := waitForMachineReady(c.clientSet, createdMachine); err != nil { + if err := waitForMachineReady(c.clientSet, createdMachine, timeoutMachineReady); err != nil { errOnce.Do(func() { gerr = err }) } }(machine) @@ -967,7 +966,7 @@ func waitForClusterResourceReady(cs clientset.Interface) error { }) } -func waitForMachineReady(cs clientset.Interface, machine *clusterv1.Machine) error { +func waitForMachineReady(cs clientset.Interface, machine *clusterv1.Machine, timeoutMachineReady time.Duration) error { err := util.PollImmediate(retryIntervalResourceReady, timeoutMachineReady, func() (bool, error) { klog.V(2).Infof("Waiting for Machine %v to become ready...", machine.Name) m, err := cs.ClusterV1alpha1().Machines(machine.Namespace).Get(machine.Name, metav1.GetOptions{}) diff --git a/cmd/clusterctl/clusterdeployer/clusterdeployer.go b/cmd/clusterctl/clusterdeployer/clusterdeployer.go index 73d17b3e09c5..942b6e2509a6 100644 --- a/cmd/clusterctl/clusterdeployer/clusterdeployer.go +++ b/cmd/clusterctl/clusterdeployer/clusterdeployer.go @@ -19,6 +19,7 @@ package clusterdeployer import ( "fmt" "strings" + "time" "github.com/pkg/errors" "k8s.io/klog" @@ -36,6 +37,7 @@ type ClusterDeployer struct { addonComponents string bootstrapComponents string cleanupBootstrapCluster bool + timeoutMachineReady time.Duration } func New( @@ -44,7 +46,8 @@ func New( providerComponents string, addonComponents string, bootstrapComponents string, - cleanupBootstrapCluster bool) *ClusterDeployer { + cleanupBootstrapCluster bool, + timeoutMachineReady int) *ClusterDeployer { return &ClusterDeployer{ bootstrapProvisioner: bootstrapProvisioner, clientFactory: clientFactory, @@ -52,6 +55,7 @@ func New( addonComponents: addonComponents, bootstrapComponents: bootstrapComponents, cleanupBootstrapCluster: cleanupBootstrapCluster, + timeoutMachineReady: timeoutMachineReady, } } @@ -90,7 +94,7 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster } klog.Infof("Creating control plane %v in namespace %q", controlPlaneMachine.Name, cluster.Namespace) - if err := phases.ApplyMachines(bootstrapClient, cluster.Namespace, []*clusterv1.Machine{controlPlaneMachine}); err != nil { + if err := phases.ApplyMachines(bootstrapClient, cluster.Namespace, []*clusterv1.Machine{controlPlaneMachine}, d.timeoutMachineReady); err != nil { return errors.Wrap(err, "unable to create control plane machine") } @@ -136,7 +140,7 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster } klog.Info("Creating node machines in target cluster.") - if err := phases.ApplyMachines(targetClient, cluster.Namespace, nodes); err != nil { + if err := phases.ApplyMachines(targetClient, cluster.Namespace, nodes, d.timeoutMachineReady); err != nil { return errors.Wrap(err, "unable to create node machines") } diff --git a/cmd/clusterctl/cmd/create_cluster.go b/cmd/clusterctl/cmd/create_cluster.go index a46bd4ef48f5..cadeb00fc5ea 100644 --- a/cmd/clusterctl/cmd/create_cluster.go +++ b/cmd/clusterctl/cmd/create_cluster.go @@ -18,6 +18,7 @@ package cmd import ( "io/ioutil" + "time" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -107,7 +108,8 @@ func RunCreate(co *CreateOptions) error { string(pc), string(ac), string(bc), - co.BootstrapFlags.Cleanup) + co.BootstrapFlags.Cleanup, + time.Duration(co.BootstrapFlags.TimeoutMachineReady) * time.Minute) return d.Create(c, m, pd, co.KubeconfigOutput, pcsFactory) } diff --git a/cmd/clusterctl/phases/applymachines.go b/cmd/clusterctl/phases/applymachines.go index ffc8f1af1425..c28a9a8c9de6 100644 --- a/cmd/clusterctl/phases/applymachines.go +++ b/cmd/clusterctl/phases/applymachines.go @@ -17,13 +17,15 @@ limitations under the License. package phases import ( + "time" + "github.com/pkg/errors" "k8s.io/klog" "sigs.k8s.io/cluster-api/cmd/clusterctl/clusterdeployer/clusterclient" clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" ) -func ApplyMachines(client clusterclient.Client, namespace string, machines []*clusterv1.Machine) error { +func ApplyMachines(client clusterclient.Client, namespace string, machines []*clusterv1.Machine, timeoutCreateMachines time.Duration) error { if namespace == "" { namespace = client.GetContextNamespace() } @@ -34,7 +36,7 @@ func ApplyMachines(client clusterclient.Client, namespace string, machines []*cl } klog.Infof("Creating machines in namespace %q", namespace) - if err := client.CreateMachines(machines, namespace); err != nil { + if err := client.CreateMachines(machines, namespace, timeoutCreateMachines); err != nil { return err }