diff --git a/k8s/migration/pkg/constants/constants.go b/k8s/migration/pkg/constants/constants.go index 706b6244f..6e0b96fdb 100644 --- a/k8s/migration/pkg/constants/constants.go +++ b/k8s/migration/pkg/constants/constants.go @@ -186,6 +186,12 @@ const ( // VMActiveWaitRetryLimit is the number of retries to wait for vm to become active VMActiveWaitRetryLimit = 15 + // VolumeAvailableWaitIntervalSeconds is the interval to wait for volume to become available + VolumeAvailableWaitIntervalSeconds = 5 + + // VolumeAvailableWaitRetryLimit is the number of retries to wait for volume to become available + VolumeAvailableWaitRetryLimit = 15 + // DefaultMigrationMethod is the default migration method DefaultMigrationMethod = "hot" @@ -195,6 +201,9 @@ const ( // CleanupVolumesAfterConvertFailure is the default value for cleanup volumes after convert failure CleanupVolumesAfterConvertFailure = true + // PopulateVMwareMachineFlavors is the default value for populate vmware machine flavors + PopulateVMwareMachineFlavors = true + // VjailbreakSettingsConfigMapName is the name of the vjailbreak settings configmap VjailbreakSettingsConfigMapName = "vjailbreak-settings" ) diff --git a/k8s/migration/pkg/utils/settings.go b/k8s/migration/pkg/utils/settings.go index 54dd3f0b0..36127aeff 100644 --- a/k8s/migration/pkg/utils/settings.go +++ b/k8s/migration/pkg/utils/settings.go @@ -21,6 +21,10 @@ type VjailbreakSettings struct { VMActiveWaitIntervalSeconds int // VMActiveWaitRetryLimit is the number of retries to wait for VM to become active VMActiveWaitRetryLimit int + // VolumeAvailableWaitIntervalSeconds is the interval to wait for volume to become available + VolumeAvailableWaitIntervalSeconds int + // VolumeAvailableWaitRetryLimit is the number of retries to wait for volume to become available + VolumeAvailableWaitRetryLimit int // DefaultMigrationMethod is the default migration method (hot/cold) DefaultMigrationMethod string // VCenterScanConcurrencyLimit is the max number of vms to scan at the same time @@ -63,37 +67,47 @@ func GetVjailbreakSettings(ctx context.Context, k8sClient client.Client) (*Vjail } if vjailbreakSettingsCM.Data["CHANGED_BLOCKS_COPY_ITERATION_THRESHOLD"] == "" { - vjailbreakSettingsCM.Data["CHANGED_BLOCKS_COPY_ITERATION_THRESHOLD"] = "20" + vjailbreakSettingsCM.Data["CHANGED_BLOCKS_COPY_ITERATION_THRESHOLD"] = strconv.Itoa(constants.ChangedBlocksCopyIterationThreshold) } if vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_INTERVAL_SECONDS"] == "" { - vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_INTERVAL_SECONDS"] = "20" + vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_INTERVAL_SECONDS"] = strconv.Itoa(constants.VMActiveWaitIntervalSeconds) } if vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"] == "" { - vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"] = "15" + vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"] = strconv.Itoa(constants.VMActiveWaitRetryLimit) + } + + if vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"] == "" { + vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"] = strconv.Itoa(constants.VolumeAvailableWaitIntervalSeconds) + } + + if vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"] == "" { + vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"] = strconv.Itoa(constants.VolumeAvailableWaitRetryLimit) } if vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"] == "" { - vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"] = "hot" + vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"] = constants.DefaultMigrationMethod } if vjailbreakSettingsCM.Data["VCENTER_SCAN_CONCURRENCY_LIMIT"] == "" { - vjailbreakSettingsCM.Data["VCENTER_SCAN_CONCURRENCY_LIMIT"] = "10" + vjailbreakSettingsCM.Data["VCENTER_SCAN_CONCURRENCY_LIMIT"] = strconv.Itoa(constants.VCenterScanConcurrencyLimit) } if vjailbreakSettingsCM.Data["CLEANUP_VOLUMES_AFTER_CONVERT_FAILURE"] == "" { - vjailbreakSettingsCM.Data["CLEANUP_VOLUMES_AFTER_CONVERT_FAILURE"] = "false" + vjailbreakSettingsCM.Data["CLEANUP_VOLUMES_AFTER_CONVERT_FAILURE"] = strconv.FormatBool(constants.CleanupVolumesAfterConvertFailure) } if vjailbreakSettingsCM.Data["POPULATE_VMWARE_MACHINE_FLAVORS"] == "" { - vjailbreakSettingsCM.Data["POPULATE_VMWARE_MACHINE_FLAVORS"] = trueString + vjailbreakSettingsCM.Data["POPULATE_VMWARE_MACHINE_FLAVORS"] = strconv.FormatBool(constants.PopulateVMwareMachineFlavors) } return &VjailbreakSettings{ ChangedBlocksCopyIterationThreshold: atoi(vjailbreakSettingsCM.Data["CHANGED_BLOCKS_COPY_ITERATION_THRESHOLD"]), VMActiveWaitIntervalSeconds: atoi(vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_INTERVAL_SECONDS"]), VMActiveWaitRetryLimit: atoi(vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"]), + VolumeAvailableWaitIntervalSeconds: atoi(vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"]), + VolumeAvailableWaitRetryLimit: atoi(vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"]), DefaultMigrationMethod: vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"], VCenterScanConcurrencyLimit: atoi(vjailbreakSettingsCM.Data["VCENTER_SCAN_CONCURRENCY_LIMIT"]), CleanupVolumesAfterConvertFailure: vjailbreakSettingsCM.Data["CLEANUP_VOLUMES_AFTER_CONVERT_FAILURE"] == "true", @@ -104,12 +118,14 @@ func GetVjailbreakSettings(ctx context.Context, k8sClient client.Client) (*Vjail // getDefaultSettings returns default vjailbreak settings func getDefaultSettings() *VjailbreakSettings { return &VjailbreakSettings{ - ChangedBlocksCopyIterationThreshold: 20, - VMActiveWaitIntervalSeconds: 20, - VMActiveWaitRetryLimit: 15, - DefaultMigrationMethod: "hot", - VCenterScanConcurrencyLimit: 10, - CleanupVolumesAfterConvertFailure: false, - PopulateVMwareMachineFlavors: true, + ChangedBlocksCopyIterationThreshold: constants.ChangedBlocksCopyIterationThreshold, + VMActiveWaitIntervalSeconds: constants.VMActiveWaitIntervalSeconds, + VMActiveWaitRetryLimit: constants.VMActiveWaitRetryLimit, + VolumeAvailableWaitIntervalSeconds: constants.VolumeAvailableWaitIntervalSeconds, + VolumeAvailableWaitRetryLimit: constants.VolumeAvailableWaitRetryLimit, + DefaultMigrationMethod: constants.DefaultMigrationMethod, + VCenterScanConcurrencyLimit: constants.VCenterScanConcurrencyLimit, + CleanupVolumesAfterConvertFailure: constants.CleanupVolumesAfterConvertFailure, + PopulateVMwareMachineFlavors: constants.PopulateVMwareMachineFlavors, } } diff --git a/v2v-helper/go.mod b/v2v-helper/go.mod index 704181cb4..2edb89f64 100644 --- a/v2v-helper/go.mod +++ b/v2v-helper/go.mod @@ -7,7 +7,7 @@ require ( github.com/gophercloud/gophercloud v1.14.1 github.com/hashicorp/go-retryablehttp v0.7.7 github.com/pkg/errors v0.9.1 - github.com/platform9/vjailbreak/k8s/migration v0.0.0-20250718102048-de8740c10909 + github.com/platform9/vjailbreak/k8s/migration v0.0.0-20250904115639-c2134e9ef3b9 github.com/prometheus-community/pro-bing v0.4.1 github.com/stretchr/testify v1.10.0 github.com/vmware/govmomi v0.51.0 diff --git a/v2v-helper/main.go b/v2v-helper/main.go index 9b991bfec..980b35c72 100644 --- a/v2v-helper/main.go +++ b/v2v-helper/main.go @@ -49,7 +49,6 @@ func main() { <-ackChan } utils.PrintLog(msg) - return } client, err := utils.GetInclusterClient() @@ -93,6 +92,7 @@ func main() { if err != nil { handleError(fmt.Sprintf("Failed to validate OpenStack connection: %v", err)) } + openstackclients.K8sClient = client utils.PrintLog("Connected to OpenStack") // Get thumbprint diff --git a/v2v-helper/openstack/openstackops.go b/v2v-helper/openstack/openstackops.go index 9c344db83..cca639b50 100644 --- a/v2v-helper/openstack/openstackops.go +++ b/v2v-helper/openstack/openstackops.go @@ -138,6 +138,7 @@ func validateOpenStack(insecure bool) (*migrateutils.OpenStackClients, error) { BlockStorageClient: blockStorageClient, ComputeClient: computeClient, NetworkingClient: networkingClient, + K8sClient: nil, }, nil } diff --git a/v2v-helper/pkg/constants/constants.go b/v2v-helper/pkg/constants/constants.go index 6fd479740..5eac5acd8 100644 --- a/v2v-helper/pkg/constants/constants.go +++ b/v2v-helper/pkg/constants/constants.go @@ -113,6 +113,12 @@ echo "$(date '+%Y-%m-%d %H:%M:%S') - Network fix script completed" >> "$LOG_FILE // VMActiveWaitRetryLimit is the number of retries to wait for vm to become active VMActiveWaitRetryLimit = 15 + // VolumeAvailableWaitIntervalSeconds is the interval to wait for volume to become available + VolumeAvailableWaitIntervalSeconds = 5 + + // VolumeAvailableWaitRetryLimit is the number of retries to wait for volume to become available + VolumeAvailableWaitRetryLimit = 15 + // DefaultMigrationMethod is the default migration method DefaultMigrationMethod = "hot" diff --git a/v2v-helper/pkg/utils/migrateutils/openstackopsutils.go b/v2v-helper/pkg/utils/migrateutils/openstackopsutils.go index 4adc20a6c..5cd8715a4 100644 --- a/v2v-helper/pkg/utils/migrateutils/openstackopsutils.go +++ b/v2v-helper/pkg/utils/migrateutils/openstackopsutils.go @@ -1,6 +1,7 @@ package migrateutils import ( + "context" "encoding/json" "fmt" "io" @@ -17,6 +18,7 @@ import ( "github.com/platform9/vjailbreak/v2v-helper/pkg/constants" "github.com/platform9/vjailbreak/v2v-helper/pkg/utils" "github.com/platform9/vjailbreak/v2v-helper/vm" + "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" @@ -36,6 +38,7 @@ type OpenStackClients struct { BlockStorageClient *gophercloud.ServiceClient ComputeClient *gophercloud.ServiceClient NetworkingClient *gophercloud.ServiceClient + K8sClient client.Client } type OpenStackMetadata struct { @@ -129,7 +132,12 @@ func (osclient *OpenStackClients) DeleteVolume(volumeID string) error { } func (osclient *OpenStackClients) WaitForVolume(volumeID string) error { - for i := 0; i < constants.MaxIntervalCount; i++ { + // Get vjailbreak settings + vjailbreakSettings, err := utils.GetVjailbreakSettings(context.Background(), osclient.K8sClient) + if err != nil { + return errors.Wrap(err, "failed to get vjailbreak settings") + } + for i := 0; i < vjailbreakSettings.VolumeAvailableWaitRetryLimit; i++ { volume, err := volumes.Get(osclient.BlockStorageClient, volumeID).Extract() if err != nil { return fmt.Errorf("failed to get volume: %s", err) @@ -162,9 +170,9 @@ func (osclient *OpenStackClients) WaitForVolume(volumeID string) error { return nil } fmt.Printf("Volume %s is still attached to server retrying %d times\n", volumeID, i) - time.Sleep(5 * time.Second) // Wait for 5 seconds before checking again + time.Sleep(time.Duration(vjailbreakSettings.VolumeAvailableWaitIntervalSeconds) * time.Second) // Wait for 5 seconds before checking again } - return fmt.Errorf("volume did not become available within %d seconds", constants.MaxIntervalCount*5) + return fmt.Errorf("volume did not become available within %d seconds", vjailbreakSettings.VolumeAvailableWaitRetryLimit*vjailbreakSettings.VolumeAvailableWaitIntervalSeconds) } func (osclient *OpenStackClients) AttachVolumeToVM(volumeID string) error { @@ -173,7 +181,11 @@ func (osclient *OpenStackClients) AttachVolumeToVM(volumeID string) error { return fmt.Errorf("failed to get instance ID: %s", err) } - for i := 0; i < constants.MaxIntervalCount; i++ { + vjailbreakSettings, err := utils.GetVjailbreakSettings(context.Background(), osclient.K8sClient) + if err != nil { + return errors.Wrap(err, "failed to get vjailbreak settings") + } + for i := 0; i < vjailbreakSettings.VolumeAvailableWaitRetryLimit; i++ { _, err = volumeattach.Create(osclient.ComputeClient, instanceID, volumeattach.CreateOpts{ VolumeID: volumeID, DeleteOnTermination: false, @@ -182,7 +194,7 @@ func (osclient *OpenStackClients) AttachVolumeToVM(volumeID string) error { err = nil break } - time.Sleep(5 * time.Second) // Wait for 5 seconds before checking again + time.Sleep(time.Duration(vjailbreakSettings.VolumeAvailableWaitIntervalSeconds) * time.Second) // Wait for 5 seconds before checking again } if err != nil { return fmt.Errorf("failed to attach volume to VM: %s", err) diff --git a/v2v-helper/pkg/utils/types.go b/v2v-helper/pkg/utils/types.go index 497d9a104..e815668b5 100644 --- a/v2v-helper/pkg/utils/types.go +++ b/v2v-helper/pkg/utils/types.go @@ -8,4 +8,6 @@ type VjailbreakSettings struct { VCenterScanConcurrencyLimit int CleanupVolumesAfterConvertFailure bool PopulateVMwareMachineFlavors bool + VolumeAvailableWaitIntervalSeconds int + VolumeAvailableWaitRetryLimit int } diff --git a/v2v-helper/pkg/utils/utils.go b/v2v-helper/pkg/utils/utils.go index 99ed5208b..f3171a31b 100644 --- a/v2v-helper/pkg/utils/utils.go +++ b/v2v-helper/pkg/utils/utils.go @@ -131,6 +131,8 @@ func GetVjailbreakSettings(ctx context.Context, k8sClient client.Client) (*Vjail VCenterScanConcurrencyLimit: constants.VCenterScanConcurrencyLimit, CleanupVolumesAfterConvertFailure: constants.CleanupVolumesAfterConvertFailure, PopulateVMwareMachineFlavors: constants.PopulateVMwareMachineFlavors, + VolumeAvailableWaitIntervalSeconds: constants.VolumeAvailableWaitIntervalSeconds, + VolumeAvailableWaitRetryLimit: constants.VolumeAvailableWaitRetryLimit, }, nil } @@ -146,6 +148,14 @@ func GetVjailbreakSettings(ctx context.Context, k8sClient client.Client) (*Vjail vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"] = strconv.Itoa(constants.VMActiveWaitRetryLimit) } + if vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"] == "" { + vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"] = strconv.Itoa(constants.VolumeAvailableWaitIntervalSeconds) + } + + if vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"] == "" { + vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"] = strconv.Itoa(constants.VolumeAvailableWaitRetryLimit) + } + if vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"] == "" { vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"] = constants.DefaultMigrationMethod } @@ -166,6 +176,8 @@ func GetVjailbreakSettings(ctx context.Context, k8sClient client.Client) (*Vjail ChangedBlocksCopyIterationThreshold: atoi(vjailbreakSettingsCM.Data["CHANGED_BLOCKS_COPY_ITERATION_THRESHOLD"]), VMActiveWaitIntervalSeconds: atoi(vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_INTERVAL_SECONDS"]), VMActiveWaitRetryLimit: atoi(vjailbreakSettingsCM.Data["VM_ACTIVE_WAIT_RETRY_LIMIT"]), + VolumeAvailableWaitIntervalSeconds: atoi(vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_INTERVAL_SECONDS"]), + VolumeAvailableWaitRetryLimit: atoi(vjailbreakSettingsCM.Data["VOLUME_AVAILABLE_WAIT_RETRY_LIMIT"]), DefaultMigrationMethod: vjailbreakSettingsCM.Data["DEFAULT_MIGRATION_METHOD"], VCenterScanConcurrencyLimit: atoi(vjailbreakSettingsCM.Data["VCENTER_SCAN_CONCURRENCY_LIMIT"]), CleanupVolumesAfterConvertFailure: vjailbreakSettingsCM.Data["CLEANUP_VOLUMES_AFTER_CONVERT_FAILURE"] == "true",