diff --git a/test/integration/testpaths/testpath_storage_migration.py b/test/integration/testpaths/testpath_storage_migration.py index c487c3ef6917..3ef31f0cac78 100644 --- a/test/integration/testpaths/testpath_storage_migration.py +++ b/test/integration/testpaths/testpath_storage_migration.py @@ -34,17 +34,18 @@ list_volumes, list_virtual_machines, createChecksum, - compareChecksum + compareChecksum, list_storage_pools, list_clusters, list_hosts, validateList ) from marvin.codes import (PASS, - ZONETAG1, - CLUSTERTAG1) + ZONETAG1, + CLUSTERTAG1) from marvin.cloudstackAPI import (deleteVolume) +from marvin.sshClient import SshClient import time from threading import Thread @@ -70,7 +71,6 @@ def GetDestinationPool(self, return destinationPool - def MigrateRootVolume(self, vm, destinationPool, @@ -320,6 +320,7 @@ def tearDownClass(cls): cleanup_resources(cls.apiclient, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) + def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() @@ -335,7 +336,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced", "basic"],required_hardware="true") + @attr(tags=["advanced", "basic"], required_hardware="true") def test_01_migrate_root_and_data_disk_nonlive(self): """ Test migrate Volume (root and data disk) @@ -356,9 +357,9 @@ def test_01_migrate_root_and_data_disk_nonlive(self): In addition to this, Create snapshot of root and data disk after migration. - For root disk, create template from snapshot, + For root disk, create template from snapshot, deploy Vm and compare checksum - For data disk, Create volume from snapshot, + For data disk, Create volume from snapshot, attach to VM and compare checksum """ @@ -1084,7 +1085,7 @@ def test_01_migrate_root_and_data_disk_nonlive(self): ), None, "VM list should be empty") return - @attr(tags=["advanced", "basic"],required_hardware="true") + @attr(tags=["advanced", "basic"], required_hardware="true") def test_02_migration_nonlive_xenserver_supported(self): """ Test migrate Volume (root and data disk) for Hypervisor Xenserver @@ -1543,7 +1544,7 @@ def test_02_migration_nonlive_xenserver_supported(self): return - @attr(tags=["advanced", "basic"],required_hardware="true") + @attr(tags=["advanced", "basic"], required_hardware="true") def test_03_migrate_root_and_data_disk_nonlive_cwps_vmware(self): """ Test migrate Volume (root and data disk) @@ -2356,14 +2357,14 @@ def createDestroyVmJob(self, virtual_machine): except Exception as e: self.exceptionList.append(e) - @attr(tags=["advanced", "basic"],required_hardware="true") + @attr(tags=["advanced", "basic"], required_hardware="true") def test_01_migrate_data_disk_negative_test(self): """ Negative test cases # 1. Deploy a VM on cluster wide primary storage. # 2. Add some data to disks and create checksum # 3. Migrate root and data volume from cluster-to-cluster wide storage pool - # 4. While migration(ROOT disk) is in progress try following scenarios, + # 4. While migration(ROOT disk) is in progress try following scenarios, they should fail: I. Take snapshot of the disk II. Create Template from the volume @@ -2912,11 +2913,11 @@ def test_01_migrate_live(self): ), None, "Volume list should be empty") return + @unittest.skip( "Requires setup with 2 pods - Each pod having 2 clusters. \ Yet to be tested") - - @attr(tags=["advanced", "basic"],required_hardware="true") + @attr(tags=["advanced", "basic"], required_hardware="true") def test_02_migration_live_different_pods(self): """ Test migrate Volume (root and data disk) @@ -3394,10 +3395,11 @@ def test_02_migration_live_different_pods(self): self.apiclient, id=root_volume_cluster.id, ), None, "Volume list should be empty") - - return - def MigrateVmWithVolume(self,vm,destinationHost,volumes,pools): + return + + +def MigrateVmWithVolume(self, vm, destinationHost, volumes, pools): """ This method is used to migrate a vm and its volumes using migrate virtual machine with volume API INPUTS: @@ -3407,56 +3409,60 @@ def MigrateVmWithVolume(self,vm,destinationHost,volumes,pools): 4. pools -> list of destination pools """ vol_pool_map = {} - for vol,pool in zip(volumes,pools): - vol_pool_map.update({vol.id:pool.id}) + for vol, pool in zip(volumes, pools): + vol_pool_map.update({vol.id: pool.id}) vm.migrate_vm_with_volume( - self.apiclient, - hostid=destinationHost.id, - migrateto = vol_pool_map - ) + self.apiclient, + hostid=destinationHost.id, + migrateto=vol_pool_map + ) vm.getState( - self.apiclient, - "Running" - ) - #check for the VM's host and volume's storage post migration + self.apiclient, + "Running" + ) + # check for the VM's host and volume's storage post migration migrated_vm_response = list_virtual_machines(self.apiclient, id=vm.id) self.assertEqual( - isinstance(migrated_vm_response, list), - True, - "Check list virtual machines response for valid list" - ) + isinstance(migrated_vm_response, list), + True, + "Check list virtual machines response for valid list" + ) self.assertEqual( - migrated_vm_response[0].hostid, - destinationHost.id, - "VM did not migrate to a specified host" - ) + migrated_vm_response[0].hostid, + destinationHost.id, + "VM did not migrate to a specified host" + ) - for vol,pool in zip(volumes,pools): - migrated_volume_response = list_volumes(self.apiclient, virtualmachineid = migrated_vm_response[0].id, name=vol.name, listall = True) + for vol, pool in zip(volumes, pools): + migrated_volume_response = list_volumes( + self.apiclient, + virtualmachineid=migrated_vm_response[0].id, + name=vol.name, + listall=True) self.assertEqual( - isinstance(migrated_volume_response, list), - True, - "Check list virtual machines response for valid list" - ) + isinstance(migrated_volume_response, list), + True, + "Check list virtual machines response for valid list" + ) self.assertEqual( - migrated_volume_response[0].storageid, - pool.id, - "Volume did not migrate to a specified pool" - ) + migrated_volume_response[0].storageid, + pool.id, + "Volume did not migrate to a specified pool" + ) self.assertEqual( - str(migrated_volume_response[0].state).lower(), - 'ready', - "Check migrated volume is in Ready state" - ) + str(migrated_volume_response[0].state).lower(), + 'ready', + "Check migrated volume is in Ready state" + ) """ #Take VM snapshot to check data integrity try : vm_snapshot = VmSnapshot.create(self.apiclient, vmid = migrated_vm_response[0].id) except Exception as e: raise Exception("Warning: Exception during VM snapshot creation : %s" % e) - + #Delete the snapshot try : VmSnapshot.deleteVMSnapshot(self.apiclient, vmsnapshotid = vm_snapshot.id) @@ -3466,33 +3472,35 @@ def MigrateVmWithVolume(self,vm,destinationHost,volumes,pools): return migrated_vm_response[0] + def MigrateVm(self, vm, destinationHost): """ This method is to migrate a VM using migrate virtual machine API """ vm.migrate( - self.apiclient, - hostid=destinationHost.id, - ) + self.apiclient, + hostid=destinationHost.id, + ) vm.getState( - self.apiclient, - "Running" - ) - #check for the VM's host and volume's storage post migration + self.apiclient, + "Running" + ) + # check for the VM's host and volume's storage post migration migrated_vm_response = list_virtual_machines(self.apiclient, id=vm.id) self.assertEqual( - isinstance(migrated_vm_response, list), - True, - "Check list virtual machines response for valid list" - ) + isinstance(migrated_vm_response, list), + True, + "Check list virtual machines response for valid list" + ) self.assertEqual( - migrated_vm_response[0].hostid, - destinationHost.id, - "VM did not migrate to a specified host" - ) + migrated_vm_response[0].hostid, + destinationHost.id, + "VM did not migrate to a specified host" + ) return migrated_vm_response[0] + def get_destination_pools_hosts(self, vm): """ Get destination Pools for all volumes and destination Host for the VM @@ -3500,12 +3508,15 @@ def get_destination_pools_hosts(self, vm): """ destinationPools = [] - vol_list = list_volumes(self.apiclient, virtualmachineid=vm.id, listall=True) + vol_list = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + listall=True) # For each volume get destination pool for vol in vol_list: pool = GetDestinationPool(self, vol.storage, "CLUSTER") destinationPools.append(pool) - #Get destination host + # Get destination host destinationHost = self.GetDestinationHost(vm.hostid) return destinationHost, destinationPools, vol_list @@ -3521,37 +3532,54 @@ def check_files(self, vm, destinationHost): # Here we list all the volumes of the VM , then login to the destination host # and check for vmx and vmdk files in the storage - vm_volumes = list_volumes(self.apiclient, virtualmachineid = vm.id, listall=True) + vm_volumes = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + listall=True) print vm_volumes for vol in vm_volumes: - spool = list_storage_pools(self.apiclient, id=vol.storageid) + spool = list_storage_pools(self.apiclient, id=vol.storageid) split_path = spool[0].path.split("/") pool_path = split_path[2] - sshclient = SshClient(host = destinationHost.ipaddress, port = 22, user = "root", passwd = "freebsd") - pool_data_vmdk = sshclient.execute("ls /vmfs/volumes/" + pool_path + "/" + vm.instancename + "| grep vmdk") - pool_data_vmx = sshclient.execute("ls /vmfs/volumes/" + pool_path + "/" + vm.instancename + "| grep vmx") + sshclient = SshClient( + host=destinationHost.ipaddress, + port=22, + user="root", + passwd="freebsd") + pool_data_vmdk = sshclient.execute( + "ls /vmfs/volumes/" + + pool_path + + "/" + + vm.instancename + + "| grep vmdk") + pool_data_vmx = sshclient.execute( + "ls /vmfs/volumes/" + + pool_path + + "/" + + vm.instancename + + "| grep vmx") if(pool_data_vmx): vmx_file = vm.instancename + ".vmx" if vol.type == "ROOT": self.assertIn( - vmx_file, - pool_data_vmx, - "The VMX files are missing" - ) + vmx_file, + pool_data_vmx, + "The VMX files are missing" + ) if(pool_data_vmdk): vmdk_file1 = vol.path + ".vmdk" vmdk_file2 = vol.path + "-flat.vmdk" self.assertIn( - vmdk_file1, - pool_data_vmdk, - "The VMDK files are missing" - ) + vmdk_file1, + pool_data_vmdk, + "The VMDK files are missing" + ) self.assertIn( - vmdk_file2, - pool_data_vmdk, - "The VMDK flat files are missing" - ) + vmdk_file2, + pool_data_vmdk, + "The VMDK flat files are missing" + ) return @@ -3559,7 +3587,9 @@ class TestStorageLiveMigrationVmware(cloudstackTestCase): @classmethod def setUpClass(cls): - testClient = super(TestStorageLiveMigrationVmware, cls).getClsTestClient() + testClient = super( + TestStorageLiveMigrationVmware, + cls).getClsTestClient() cls.apiclient = testClient.getApiClient() cls.testdata = testClient.getParsedTestDataConfig() cls.hypervisor = cls.testClient.getHypervisorInfo() @@ -3582,39 +3612,45 @@ def setUpClass(cls): return # Get Hosts in the cluster and iscsi/vmfs storages for that cluster iscsi_pools = [] - try : - list_vmware_clusters = list_clusters(cls.apiclient, hypervisor="vmware") + try: + list_vmware_clusters = list_clusters( + cls.apiclient, + hypervisor="vmware") except Exception as e: cls.NoResource = True return assert validateList(list_vmware_clusters)[0] == PASS - if len(list_vmware_clusters) < 1 : + if len(list_vmware_clusters) < 1: cls.NoResource = True return - else : - for cluster in list_vmware_clusters : + else: + for cluster in list_vmware_clusters: try: - list_esx_hosts = list_hosts(cls.apiclient, clusterid = cluster.id) + list_esx_hosts = list_hosts( + cls.apiclient, + clusterid=cluster.id) except Exception as e: cls.NoResource = True return assert validateList(list_esx_hosts)[0] == PASS - if len(list_esx_hosts) > 1 : + if len(list_esx_hosts) > 1: try: - list_storage = list_storage_pools(cls.apiclient, clusterid = cluster.id) + list_storage = list_storage_pools( + cls.apiclient, + clusterid=cluster.id) except Exception as e: cls.NoResource = True return assert validateList(list_storage)[0] == PASS - for storage in list_storage : - if storage.type == "VMFS" : + for storage in list_storage: + if storage.type == "VMFS": iscsi_pools.append(storage) if len(iscsi_pools) > 1: my_cluster_id = cluster.id break - else : + else: iscsi_pools = [] - if len(iscsi_pools) < 2 : + if len(iscsi_pools) < 2: cls.NoResource = True return cls.hosts = list_esx_hosts @@ -3680,21 +3716,21 @@ def deploy_virtual_machine(self, service_offering_id, vm): Function to Deploy VMs """ virtual_machine = VirtualMachine.create( - self.apiclient, - self.testdata[vm], - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - serviceofferingid=service_offering_id, - templateid=self.template.id, + self.apiclient, + self.testdata[vm], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=service_offering_id, + templateid=self.template.id, ) virtual_machine.getState( - self.apiclient, - "Running" - ) + self.apiclient, + "Running" + ) return virtual_machine - + def GetDestinationHost(self, hostsToavoid): """ This method gives us the destination host to which VM will be migrated @@ -3706,52 +3742,69 @@ def GetDestinationHost(self, hostsToavoid): destinationHost = host break return destinationHost - - @attr(tags=["advanced", "basic", "vmware", "vmfs"], required_hardware="True") + @attr( + tags=[ + "advanced", + "basic", + "vmware", + "vmfs"], + required_hardware="True") def test_01_migrate_root_and_data_disk_live(self): """ Migrate VMs/Volumes on VMware with VMFS storage """ - #List clusters and check if they have multiple hosts - #and multiple storages - #check if they storages are VMFS type + # List clusters and check if they have multiple hosts + # and multiple storages + # check if they storages are VMFS type self.debug("---------------This is the test no 1--------------") """ Create a VM, live migrate the VM """ vm = "virtual_machine2" - virtual_machine_1 = self.deploy_virtual_machine(self.service_offering.id, vm) + virtual_machine_1 = self.deploy_virtual_machine( + self.service_offering.id, + vm) - #Get destination host + # Get destination host destinationHost = self.GetDestinationHost(virtual_machine_1.hostid) - #Migrate the VM + # Migrate the VM vm = MigrateVm(self, virtual_machine_1, destinationHost) - #self.check_files(vm,destinationHost) - + # self.check_files(vm,destinationHost) + self.debug("---------------This is the test no 2--------------") """ Migrate the ROOT Volume """ # Get ROOT volume and destination pool - vol_list = list_volumes(self.apiclient, virtualmachineid=vm.id, type="ROOT", listall=True) + vol_list = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + type="ROOT", + listall=True) root_vol = vol_list[0] destinationPool = GetDestinationPool(self, root_vol.storage, "CLUSTER") - #Migrate ROOT volume + # Migrate ROOT volume islive = True MigrateDataVolume(self, root_vol, destinationPool, islive) - check_files(self, vm ,destinationHost) - + check_files(self, vm, destinationHost) + self.debug("---------------This is the test no 3--------------") """ Migrate the VM and ROOT volume """ - #Get all volumes to be migrated - - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) + # Get all volumes to be migrated + + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) - check_files(self, vm,destinationHost) + check_files(self, vm, destinationHost) self.debug("---------------This is the test no 4--------------") """ @@ -3759,70 +3812,92 @@ def test_01_migrate_root_and_data_disk_live(self): """ data_disk_1 = Volume.create( - self.apiclient, - self.testdata["volume"], - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid, - diskofferingid=self.disk_offering.id - ) + self.apiclient, + self.testdata["volume"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.disk_offering.id + ) self.debug("Created volume with ID: %s" % data_disk_1.id) virtual_machine_1.attach_volume( - self.apiclient, - data_disk_1 - ) + self.apiclient, + data_disk_1 + ) - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) - check_files(self, vm,destinationHost) + check_files(self, vm, destinationHost) self.debug("---------------This is the test no 5--------------") """ Upload a Volume, Attach it to the VM, Migrate all the volumes and VM. """ - #upload a volume + # upload a volume self.testdata["configurableData"]["upload_volume"]["format"] = "OVA" - self.testdata["configurableData"]["upload_volume"]["url"] = "http://nfs1.lab.vmops.com/templates/burbank-systemvm-08012012.ova" + self.testdata["configurableData"]["upload_volume"][ + "url"] = "http://nfs1.lab.vmops.com/templates/burbank-systemvm-08012012.ova" upload_volume = Volume.upload( - self.apiclient, - self.testdata["configurableData"]["upload_volume"], - account= self.account.name, - domainid= self.domain.id, - zoneid= self.zone.id - ) + self.apiclient, + self.testdata["configurableData"]["upload_volume"], + account=self.account.name, + domainid=self.domain.id, + zoneid=self.zone.id + ) upload_volume.wait_for_upload(self.apiclient) virtual_machine_1.attach_volume( - self.apiclient, - upload_volume - ) - - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) - - check_files(self, vm,destinationHost) - + self.apiclient, + upload_volume + ) + + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) + + check_files(self, vm, destinationHost) + self.debug("---------------This is the test no 6--------------") """ Create snapshots on all the volumes, Migrate all the volumes and VM. """ - #Get ROOT Volume - vol_for_snap = list_volumes(self.apiclient, virtualmachineid=vm.id, listall=True) + # Get ROOT Volume + vol_for_snap = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + listall=True) for vol in vol_for_snap: snapshot = Snapshot.create( - self.apiclient, - volume_id = vol.id - ) + self.apiclient, + volume_id=vol.id + ) snapshot.validateState( - self.apiclient, - snapshotstate="backedup", - ) + self.apiclient, + snapshotstate="backedup", + ) # Migrate all volumes and VMs - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) check_files(self, vm, destinationHost) @@ -3831,14 +3906,20 @@ def test_01_migrate_root_and_data_disk_live(self): Resize the data volume , Migrate all the volumes and VM. """ data_disk_1.resize( - self.apiclient, - diskofferingid = self.resized_disk_offering.id - ) + self.apiclient, + diskofferingid=self.resized_disk_offering.id + ) # Migrate all volumes and VMs - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) - check_files(self, vm,destinationHost) + check_files(self, vm, destinationHost) self.debug("---------------This is the test no 8--------------") """ @@ -3846,13 +3927,18 @@ def test_01_migrate_root_and_data_disk_live(self): """ virtual_machine_1.restore(self.apiclient) virtual_machine_1.getState( - self.apiclient, - "Running" - ) + self.apiclient, + "Running" + ) # Migrate the VM and its volumes - destinationHost, destinationPools, vol_list = get_destination_pools_hosts(self, vm) - vm = MigrateVmWithVolume(self, virtual_machine_1, destinationHost, vol_list, destinationPools) - - check_files(self, vm,destinationHost) + destinationHost, destinationPools, vol_list = get_destination_pools_hosts( + self, vm) + vm = MigrateVmWithVolume( + self, + virtual_machine_1, + destinationHost, + vol_list, + destinationPools) + check_files(self, vm, destinationHost)