diff --git a/cloud/scope/client.go b/cloud/scope/client.go index e938051e9..6201247d2 100644 --- a/cloud/scope/client.go +++ b/cloud/scope/client.go @@ -28,6 +28,7 @@ type LinodeInstanceClient interface { CreateInstanceDisk(ctx context.Context, linodeID int, opts linodego.InstanceDiskCreateOptions) (*linodego.InstanceDisk, error) GetInstance(ctx context.Context, linodeID int) (*linodego.Instance, error) DeleteInstance(ctx context.Context, linodeID int) error + WaitForInstanceDiskStatus(ctx context.Context, instanceID int, diskID int, status linodego.DiskStatus, timeoutSeconds int) (*linodego.InstanceDisk, error) } // LinodeVPCClient defines the methods that a Linode client must have to interact with Linode's VPC service. diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index 125e93980..adf8495f3 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -50,7 +50,10 @@ import ( ) // default etcd Disk size in MB -const defaultEtcdDiskSize = 10240 +const ( + defaultEtcdDiskSize = 10240 + defaultResizeTimeoutSeconds = 30 +) var skippedMachinePhases = map[string]bool{ string(clusterv1.MachinePhasePending): true, @@ -342,6 +345,13 @@ func (r *LinodeMachineReconciler) configureDisksControlPlane( return err } + // wait for the disk to resize + _, err = machineScope.LinodeClient.WaitForInstanceDiskStatus(ctx, linodeInstanceID, rootDiskID, linodego.DiskReady, defaultResizeTimeoutSeconds) + if err != nil { + logger.Error(err, fmt.Sprintf("Failed to resize root disk within resize timeout of %d seconds", defaultResizeTimeoutSeconds)) + + return err + } // create the etcd disk _, err = machineScope.LinodeClient.CreateInstanceDisk( diff --git a/mock/client.go b/mock/client.go index 4cef98d31..ca767a100 100644 --- a/mock/client.go +++ b/mock/client.go @@ -294,6 +294,21 @@ func (mr *MockLinodeMachineClientMockRecorder) ResizeInstanceDisk(ctx, linodeID, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResizeInstanceDisk", reflect.TypeOf((*MockLinodeMachineClient)(nil).ResizeInstanceDisk), ctx, linodeID, diskID, size) } +// WaitForInstanceDiskStatus mocks base method. +func (m *MockLinodeMachineClient) WaitForInstanceDiskStatus(ctx context.Context, instanceID, diskID int, status linodego.DiskStatus, timeoutSeconds int) (*linodego.InstanceDisk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitForInstanceDiskStatus", ctx, instanceID, diskID, status, timeoutSeconds) + ret0, _ := ret[0].(*linodego.InstanceDisk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WaitForInstanceDiskStatus indicates an expected call of WaitForInstanceDiskStatus. +func (mr *MockLinodeMachineClientMockRecorder) WaitForInstanceDiskStatus(ctx, instanceID, diskID, status, timeoutSeconds any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForInstanceDiskStatus", reflect.TypeOf((*MockLinodeMachineClient)(nil).WaitForInstanceDiskStatus), ctx, instanceID, diskID, status, timeoutSeconds) +} + // MockLinodeInstanceClient is a mock of LinodeInstanceClient interface. type MockLinodeInstanceClient struct { ctrl *gomock.Controller @@ -464,6 +479,21 @@ func (mr *MockLinodeInstanceClientMockRecorder) ResizeInstanceDisk(ctx, linodeID return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResizeInstanceDisk", reflect.TypeOf((*MockLinodeInstanceClient)(nil).ResizeInstanceDisk), ctx, linodeID, diskID, size) } +// WaitForInstanceDiskStatus mocks base method. +func (m *MockLinodeInstanceClient) WaitForInstanceDiskStatus(ctx context.Context, instanceID, diskID int, status linodego.DiskStatus, timeoutSeconds int) (*linodego.InstanceDisk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitForInstanceDiskStatus", ctx, instanceID, diskID, status, timeoutSeconds) + ret0, _ := ret[0].(*linodego.InstanceDisk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WaitForInstanceDiskStatus indicates an expected call of WaitForInstanceDiskStatus. +func (mr *MockLinodeInstanceClientMockRecorder) WaitForInstanceDiskStatus(ctx, instanceID, diskID, status, timeoutSeconds any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForInstanceDiskStatus", reflect.TypeOf((*MockLinodeInstanceClient)(nil).WaitForInstanceDiskStatus), ctx, instanceID, diskID, status, timeoutSeconds) +} + // MockLinodeVPCClient is a mock of LinodeVPCClient interface. type MockLinodeVPCClient struct { ctrl *gomock.Controller