def test_disk_uuids(self): # Create a vm without a root disk and blank disk then attach another # persistent disk. Then verify that only the uuids of the # ephemeral and persistent disks are updated to match their cloud ids. vm_wrapper = VmWrapper(self.host_client) disk_id_root = new_id() disk_id_ephemeral = new_id() disk_id_persistent = new_id() image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(disk_id_root, self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(disk_id_ephemeral, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # create one persistent disk disk = Disk(disk_id_persistent, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) vm_wrapper.attach_disks(vm_id, [disk_id_persistent]) vim_vm = self.vim_client.get_vm(vm_id) disk_uuid_map = dict([(dev.backing.uuid, dev.backing.fileName) for dev in vim_vm.config.hardware.device if isinstance(dev, vim.vm.device.VirtualDisk)]) # Assert that the UUID assigned to the ephemeral and persistent disks # matches their ids for disk_id in (disk_id_ephemeral, disk_id_persistent): self.assertTrue(disk_id in disk_uuid_map and disk_id in disk_uuid_map[disk_id]) # Assert that no such assignment is done for link-clone root disk. self.assertFalse(disk_id_root in disk_uuid_map) vm_wrapper.detach_disks(vm_id, [disk_id_persistent]) vm_wrapper.delete(request=vm_wrapper.delete_request()) vm_wrapper.delete_disks([disk_id_persistent], validate=True)
def _sample_vm(self): flavor = Flavor(name="flavor", cost=[QuotaLineItem("a", "b", 1)]) disks = [ Disk(stable_uuid("%s-1" % id), flavor, False, False, 1, datastore=Datastore("ds1")), Disk(stable_uuid("%s-2" % id), flavor, False, False, 1, datastore=Datastore("ds2")), ] vm = Vm() vm.id = id vm.flavor = "flavor" vm.flavor_info = flavor vm.disks = disks vm.state = State().STARTED vm.datastore = Datastore("ds1") return vm
def create_resource(self, id): flavor = Flavor(name="flavor", cost=[QuotaLineItem("a", "b", 1)]) disks = [ Disk(stable_uuid("%s-1" % id), flavor, False, False, 1, datastore=Datastore("ds1")), Disk(stable_uuid("%s-2" % id), flavor, False, False, 1, datastore=Datastore("ds2")), ] vm = Vm() vm.id = id vm.flavor = "flavor" vm.flavor_info = flavor vm.state = State().STARTED vm.datastore = Datastore("ds1") resource = Resource(vm, disks) return resource
def test_attach_detach_disks(self): vm_wrapper = VmWrapper(self.host_client) # create a vm without disk reservation = vm_wrapper.place_and_reserve().reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # create 3 disks image = DiskImage("ttylinux", CloneType.FULL_COPY) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) ] for disk in disks: reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) # attach disks disk_ids = [disk.id for disk in disks] vm_wrapper.attach_disks(vm_id, disk_ids) # delete vm and disks vm_wrapper.delete(request=vm_wrapper.delete_request(), expect=Host.DeleteVmResultCode.OPERATION_NOT_ALLOWED) vm_wrapper.detach_disks(vm_id, disk_ids) vm_wrapper.delete(request=vm_wrapper.delete_request()) vm_wrapper.delete_disks([disk.id for disk in disks], validate=True)
def createVmResource(image): disk = Disk() disk.flavor = "some-disk-flavor" disk.id = str(uuid.uuid4()) disk.persistent = False disk.new_disk = True disk.capacity_gb = 0 disk.image = DiskImage() disk.image.id = image disk.image.clone_type = CloneType.COPY_ON_WRITE disk.flavor_info = Flavor() disk.flavor_info.name = "some-disk-flavor" disk.flavor_info.cost = [] vm = Vm() vm.id = str(uuid.uuid4()) vm.flavor = "some-vm-flavor" vm.state = State.STOPPED vm.flavor_info = Flavor() vm.flavor_info.name = "some-vm-flavor" vm.flavor_info.cost = [ QuotaLineItem("vm.cpu", "1", QuotaUnit.COUNT), QuotaLineItem("vm.memory", "0.5", QuotaUnit.GB) ] vm.disks = [disk] return vm
def createVmResource(image): disk = Disk() disk.flavor = "some-disk-flavor" disk.id = str(uuid.uuid1()) disk.persistent = False disk.new_disk = True disk.capacity_gb = 0 disk.image = DiskImage() disk.image.id = image disk.image.clone_type = CloneType.COPY_ON_WRITE disk.flavor_info = Flavor() disk.flavor_info.name = "some-disk-flavor" disk.flavor_info.cost = [] vm = Vm() vm.id = str(uuid.uuid1()) vm.flavor = "some-vm-flavor" vm.state = State.STOPPED vm.flavor_info = Flavor() vm.flavor_info.name = "some-vm-flavor" vm.flavor_info.cost = [ QuotaLineItem("vm.cpu", "1", QuotaUnit.COUNT), QuotaLineItem("vm.memory", "0.5", QuotaUnit.GB)] vm.disks = [disk] return vm
def createVmResource(image, network): disk = Disk() disk.flavor = "some-disk-flavor" disk.id = str(uuid.uuid4()) disk.persistent = False disk.new_disk = True disk.capacity_gb = 0 disk.image = DiskImage() disk.image.id = image disk.image.clone_type = CloneType.COPY_ON_WRITE disk.flavor_info = Flavor() disk.flavor_info.name = "some-disk-flavor" disk.flavor_info.cost = [] vm = Vm() vm.id = str(uuid.uuid4()) vm.flavor = "some-vm-flavor" vm.state = VmPowerState.STOPPED vm.flavor_info = Flavor() vm.flavor_info.name = "some-vm-flavor" vm.flavor_info.cost = [ QuotaLineItem("vm.cpu", "1", QuotaUnit.COUNT), QuotaLineItem("vm.memory", "0.5", QuotaUnit.GB), ] vm.disks = [disk] if network: vm.resource_constraints = [ResourceConstraint(ResourceConstraintType.NETWORK, [network])] return vm
def test_network(self): vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.FULL_COPY) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # create disk reservation = \ vm_wrapper.place_and_reserve(vm_disks=disks).reservation # create vm with network info specified ip = Ipv4Address("10.146.30.120", "255.255.255.0") ip2 = Ipv4Address("10.146.30.121", "255.255.255.0") # In a host simulator environment the vm network portgroup is # named differently. nic = [NicConnectionSpec("VM Network", ip), NicConnectionSpec("VM Network", ip2)] network = NetworkConnectionSpec(nic, "10.146.30.1") request = vm_wrapper.create_request(res_id=reservation, network=network) vm_id = vm_wrapper.create(request=request).vm.id response = vm_wrapper.get_network(vm_id=vm_id) self.assertEqual(len(response.network_info), 2) # delete the disk and the vm vm_wrapper.delete(request=vm_wrapper.delete_request())
def test_batch_get_resources(self): """Test that the agent can return resources in batch.""" vms = [] for _ in xrange(2): vm = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR) ] reservation = vm.place_and_reserve(vm_disks=disks).reservation request = vm.create_request(reservation) vm.create(request=request) vms.append((vm, disks)) request = GetResourcesRequest() response = rpc_call(self.host_client.get_resources, request) assert_that(response.result, is_(GetResourcesResultCode.OK)) assert_that(response.resources, has_len(2)) resources = {} for resource in response.resources: resources[resource.vm.id] = resource for vm, disks in vms: assert_that(resources, has_key(vm.id)) vm.delete(request=vm.delete_request())
def test_attach_detach_disks_vm_suspended(self): vm_wrapper = VmWrapper(self.host_client) # create a vm vm_id = vm_wrapper.create().vm.id # create a disk disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) # suspend vm and attach disk should fail vm_wrapper.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) vm_wrapper.power(Host.PowerVmOp.SUSPEND, Host.PowerVmOpResultCode.OK) vm_wrapper.attach_disks(vm_id, [disk.id], expect=Host.VmDiskOpResultCode.INVALID_VM_POWER_STATE) # resume vm and attach disk vm_wrapper.power(Host.PowerVmOp.RESUME, Host.PowerVmOpResultCode.OK) vm_wrapper.attach_disks(vm_id, [disk.id]) # suspend vm and detach disk should fail vm_wrapper.power(Host.PowerVmOp.SUSPEND, Host.PowerVmOpResultCode.OK) vm_wrapper.detach_disks(vm_id, [disk.id], expect=Host.VmDiskOpResultCode.INVALID_VM_POWER_STATE) # power off and detach disk vm_wrapper.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) vm_wrapper.detach_disks(vm_id, [disk.id]) # clean up vm_wrapper.delete_disks([disk.id]) vm_wrapper.delete()
def test_port_group(self): # create vm with network_name (port_group) but without ip vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.FULL_COPY) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # create disk reservation = \ vm_wrapper.place_and_reserve(vm_disks=disks).reservation # In a host simulator environment the vm network portgroup is # named differently. if self.agent_in_uwsim: nic = [NicConnectionSpec("Virtual Machine Network"), NicConnectionSpec("Virtual Machine Network")] else: nic = [NicConnectionSpec("VM Network"), NicConnectionSpec("VM Network")] network = NetworkConnectionSpec(nic, "10.146.30.1") request = vm_wrapper.create_request(res_id=reservation, network=network) vm_id = vm_wrapper.create(request=request).vm.id response = vm_wrapper.get_network(vm_id=vm_id) self.assertEqual(len(response.network_info), 2) # delete the disk and the vm vm_wrapper.delete(request=vm_wrapper.delete_request())
def test_place_on_datastore_tag(self): host_config_request = Host.GetConfigRequest() res = self.host_client.get_host_config(host_config_request) self.assertEqual(res.result, GetConfigResultCode.OK) datastores = res.hostConfig.datastores for datastore in datastores: tag = self._type_to_tag(datastore.type) if not tag: continue vm_wrapper = VmWrapper(self.host_client) # Test place disks with only datastore constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], []) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints) # Test place disks with datastore and datastore tag constraint disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.OK) # Test place disks with the wrong datastore tag for other_tag in self._other_tags(tag): disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, capacity_gb=0) resource_constraints = self._create_constraints([datastore.id], [other_tag]) vm_wrapper.place(vm_disks=[disk], vm_constraints=resource_constraints, expect=PlaceResultCode.NO_SUCH_RESOURCE)
def _place_request_with_params(self, ratio, min_fanout, max_fanout): place_params = PlaceParams() place_params.fanoutRatio = ratio place_params.minFanoutCount = min_fanout place_params.maxFanoutCount = max_fanout place_request = PlaceRequest(resource=Resource(Vm(), [Disk()]), leafSchedulerParams=place_params) return place_request
def _test_create_vm_with_ephemeral_disks(self, image_id, concurrent=False, new_client=False): if new_client: client = self.create_client() else: client = self.host_client vm_wrapper = VmWrapper(client) image = DiskImage(image_id, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) ] reservation = \ vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) response = vm_wrapper.create(request=request) assert_that(response.vm, not_none()) assert_that(response.vm.datastore, not_none()) assert_that(response.vm.datastore.id, not_none()) assert_that(response.vm.datastore.name, not_none()) rc = Host.PowerVmOpResultCode op = Host.PowerVmOp vm_wrapper.power(op.ON, rc.OK) vm_wrapper.power(op.OFF, rc.OK) vm_wrapper.delete(request=vm_wrapper.delete_request(disk_ids=[])) # This is to test the image doesn't go away with the delete request, # Otherwise this create vm request will fail. if not concurrent: # create the VM with new VM_ID vm_wrapper = VmWrapper(client) reservation = vm_wrapper.place_and_reserve( vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) vm_wrapper.delete(request=vm_wrapper.delete_request(disk_ids=[]))
def createDisksResource(): disk = Disk() disk.flavor = "some-disk-flavor" disk.id = str(uuid.uuid4()) disk.persistent = True disk.new_disk = True disk.capacity_gb = 2 disk.flavor_info = Flavor() disk.flavor_info.name = "some-disk-flavor" disk.flavor_info.cost = [] return [disk]
def createDisksResource(): disk = Disk() disk.flavor = "some-disk-flavor" disk.id = str(uuid.uuid1()) disk.persistent = True disk.new_disk = True disk.capacity_gb = 2 return [disk]
def test_create_disk_from_image(self): """Test that the agent can clone images""" vm = VmWrapper(self.host_client) tests = [ {"im": DiskImage("invalid", CloneType.FULL_COPY), "rc": CreateDiskResultCode.SYSTEM_ERROR}, {"im": None, "rc": CreateDiskResultCode.OK}, {"im": DiskImage("ttylinux", CloneType.FULL_COPY), "rc": CreateDiskResultCode.OK}, {"im": DiskImage("ttylinux", CloneType.COPY_ON_WRITE), "rc": CreateDiskResultCode.SYSTEM_ERROR}, ] for test in tests: disk = Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=test["im"], flavor_info=self.DEFAULT_DISK_FLAVOR) if disk.image is None: disk.capacity_gb = 1 else: disk.capacity_gb = 0 reservation = vm.place_and_reserve(disks=[disk]).reservation response = vm.create_disks([disk], reservation) if test["rc"] == CreateDiskResultCode.OK: assert_that(response.disk_errors, has_len(1)) assert_that(response.disk_errors, has_key(disk.id)) assert_that(response.disk_errors[disk.id].result, is_(test["rc"])) response = vm.delete_disks([disk.id]) assert_that(response.disk_errors, has_len(1)) assert_that(response.disk_errors, has_key(disk.id)) assert_that(response.disk_errors[disk.id].result, is_(DeleteDiskResultCode.OK)) else: assert_that(response.disk_errors, has_len(1)) assert_that(response.disk_errors, has_key(disk.id)) disk_error = response.disk_errors[disk.id] assert_that(disk_error.result, is_(test["rc"]))
def test_force_delete_vm(self): vm_wrapper = VmWrapper(self.host_client) # create a vm without disk reservation = vm_wrapper.place_and_reserve().reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # create 2 disks disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR) ] for disk in disks: reservation = vm_wrapper.place_and_reserve(disk=disk).reservation vm_wrapper.create_disk(disk, reservation, validate=True) # attach disks disk_ids = [disk.id for disk in disks] vm_wrapper.attach_disks(vm_id, disk_ids) # delete vm fails without force vm_wrapper.delete(request=vm_wrapper.delete_request(), expect=Host.DeleteVmResultCode.OPERATION_NOT_ALLOWED) # delete vm with force succeeds vm_wrapper.delete(request=vm_wrapper.delete_request(force=True)) for disk_id in disk_ids: vm_wrapper.get_disk(disk_id, expect_found=False)
def test_create_delete_disks(self): """Test that the agent can create and delete disks.""" vm = VmWrapper(self.host_client) rc = Host.CreateDisksResultCode disk_1 = new_id() disk_2 = new_id() disks = [ Disk(disk_1, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(disk_2, self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # Invalid reservation id vm.create_disks(disks, new_id(), expect=rc.INVALID_RESERVATION) # Valid disk flavor response = vm.place_and_reserve(disks=disks) reservation = response.reservation # Create 2 disks vm.create_disks(disks, reservation, validate=True) # Delete 2 disks: 1 - valid, 2 - valid disk_ids = [disk_1, disk_2] vm.delete_disks(disk_ids, validate=True) # Delete 2 disks: 1 - invalid (deleted), 2 - invalid (deleted) response = vm.delete_disks(disk_ids) assert_that(len(response.disk_errors), equal_to(2)) assert_that(response.disk_errors, has_key(disk_1)) assert_that(response.disk_errors[disk_1].result, is_(DeleteDiskResultCode.SYSTEM_ERROR)) assert_that(response.disk_errors, has_key(disk_2)) assert_that(response.disk_errors[disk_2].result, is_(DeleteDiskResultCode.SYSTEM_ERROR))
def test_get_image_info(self): datastore = self._find_configured_datastore_in_host_config() request = ImageInfoRequest(image_id="ttylinux", datastore_id=datastore.id) response = self.host_client.get_image_info(request) assert_that(response.result, is_(ImageInfoResultCode.OK)) assert_that(response.image_info.tombstone, is_(False)) if response.image_info.last_updated_time != NEVER_UPDATED: assert_that(response.image_info.last_updated_time, matches_regexp( self.REGEX_TIME) ) assert_that(response.image_info.created_time, matches_regexp( self.REGEX_TIME) ) assert_that(response.image_info.vm_ids, has_length( response.image_info.ref_count)) assert_that(response.image_info.type, is_(ImageType.CLOUD)) assert_that(response.image_info.replication, is_( ImageReplication.EAGER)) vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = \ vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) response = vm_wrapper.create(request=request) assert_that(response.vm, not_none()) request = ImageInfoRequest(image_id="ttylinux", datastore_id=datastore.id) response = self.host_client.get_image_info(request) assert_that(response.result, is_(ImageInfoResultCode.OK)) assert_that(response.image_info.tombstone, is_(False)) assert_that(len(response.image_info.vm_ids), is_(response.image_info.ref_count)) assert_that(response.image_info.vm_ids, has_length( response.image_info.ref_count)) vm_wrapper.delete(request=vm_wrapper.delete_request(disk_ids=[]))
def test_default_network(self): vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # create disk reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation # create vm without network info specified request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id result = vm_wrapper.get_network(vm_id=vm_id) assert_that(len(result.network_info), is_(1)) assert_that(result.network_info[0].network == "VM Network") # delete the disk and the vm vm_wrapper.delete(request=vm_wrapper.delete_request())
def _place_request(self): return PlaceRequest(resource=Resource(Vm(), [Disk()]))
def test_reserve_vm(self): disk_ids = ["disk_id_1", "disk_id_2", "disk_id_3"] datastore_ids = ["datastore_1", "datastore_2", "datastore_3"] disk_flavor = "disk_flavor_1" networks = ["net_1", "net_2"] vm_flavor = "vm_flavor_1" vm_id = "vm_id_1" def reserve_vm_validate(vm, disks): assert_that(vm) assert_that(not disks) assert_that(vm.id, equal_to(vm_id)) # Check VM placement vm_placement = vm.placement assert_that(vm_placement is not None) assert_that(vm_placement.type is ResourcePlacementType.VM) assert_that(vm_placement.resource_id, equal_to(vm_id)) assert_that(vm_placement.container_id, equal_to(datastore_ids[0])) # Check VM networks vm_networks = vm.networks assert_that(vm_networks is not None) assert_that(set(networks), equal_to(set(vm_networks))) disks = vm.disks assert_that(len(disks) is 3) disk_index = 0 for vm_disk in disks: assert_that(vm_disk.id, equal_to(disk_ids[disk_index])) assert_that(vm_disk.placement is not None) disk_placement = vm_disk.placement assert_that(disk_placement.type is ResourcePlacementType.DISK) assert_that(disk_placement.resource_id, equal_to(vm_disk.id)) assert_that(disk_placement.container_id, equal_to(datastore_ids[disk_index])) disk_index += 1 return "reservation_id" handler = HostHandler(MagicMock()) mocked_reserve = MagicMock() mocked_reserve.side_effect = reserve_vm_validate handler.hypervisor.placement_manager = MagicMock() handler.hypervisor.placement_manager.reserve = mocked_reserve placements = [] # Add VM placement info placement = ResourcePlacement() placement.type = ResourcePlacementType.VM placement.resource_id = vm_id placement.container_id = datastore_ids[0] placements.append(placement) # Add Network placement info : net_1 placement = ResourcePlacement() placement.type = ResourcePlacementType.NETWORK placement.resource_id = vm_id placement.container_id = networks[0] placements.append(placement) # Add Network placement info : net_2 placement = ResourcePlacement() placement.type = ResourcePlacementType.NETWORK placement.resource_id = vm_id placement.container_id = networks[1] placements.append(placement) # Add disks placement info index = 0 for disk_id in disk_ids: placement = ResourcePlacement() placement.type = ResourcePlacementType.DISK placement.container_id = datastore_ids[index] index += 1 placement.resource_id = disk_id placements.append(placement) placement_list = ResourcePlacementList(placements) disk_flavor_info = Flavor(name=disk_flavor, cost=[QuotaLineItem("size", "1", 1)]) disks = [] for disk_id in disk_ids: disk = Disk(id=disk_id, flavor=disk_flavor, persistent=True, new_disk=True, capacity_gb=2, flavor_info=disk_flavor_info) disks.append(disk) vm_flavor_info = Flavor(name=vm_flavor, cost=[QuotaLineItem("cpu", "1", 5)]) vm = Vm(vm_id, vm_flavor, State.STOPPED, None, None, disks, vm_flavor_info) request = ReserveRequest() request.generation = 1 request.resource = Resource(vm=vm, disks=None, placement_list=placement_list) response = handler.reserve(request) assert_that(response.result, equal_to(ReserveResultCode.OK)) # test reserve under entering-maintenance-mode and maintenance mode state = common.services.get(ServiceName.MODE) state.set_mode(MODE.ENTERING_MAINTENANCE) request = MagicMock() response = handler.reserve(request) assert_that(response.result, equal_to(ReserveResultCode.OPERATION_NOT_ALLOWED)) state.set_mode(MODE.MAINTENANCE) response = handler.reserve(request) assert_that(response.result, equal_to(ReserveResultCode.OPERATION_NOT_ALLOWED))
def test_reserve_disk(self, constraint_value, placement_id, expected): disk_id = "disk_id_1" disk_flavor = "disk_flavor_1" def reserve_disk_validate(vm, disks): assert_that(vm is None) assert isinstance(disks, list) assert_that(len(disks) is 1) disk = disks[0] assert isinstance(disk, HostDisk) assert_that(disk.id, equal_to(disk_id)) assert_that(disk.flavor.name, equal_to(disk_flavor)) reserve_constraints = disk.constraints if reserve_constraints: assert isinstance(reserve_constraints, list) assert_that(len(reserve_constraints) is 1) reserve_constraint = reserve_constraints[0] assert_that( reserve_constraint.type is ResourceConstraintType.DATASTORE ) assert_that(reserve_constraint.values, equal_to([ expected, ])) reserve_placement = disk.placement if reserve_placement: assert_that( reserve_placement.type is ResourcePlacementType.DISK) assert_that(reserve_placement.resource_id, equal_to(disk_id)) assert_that(reserve_placement.container_id, equal_to(expected)) return "reservation_id" handler = HostHandler(MagicMock()) mocked_reserve = MagicMock() mocked_reserve.side_effect = reserve_disk_validate handler.hypervisor.placement_manager = MagicMock() handler.hypervisor.placement_manager.reserve = mocked_reserve constraints = None placement_list = None if constraint_value: constraint = ResourceConstraint() constraint.values = [constraint_value] constraint.type = ResourceConstraintType.DATASTORE constraints = [constraint] if placement_id: placement = ResourcePlacement() placement.type = ResourcePlacementType.DISK placement.container_id = placement_id placement.resource_id = disk_id placement_list = ResourcePlacementList([placement]) flavor_info = Flavor(name=disk_flavor, cost=[QuotaLineItem("a", "b", 1)]) disk = Disk(id=disk_id, flavor=disk_flavor, persistent=True, new_disk=True, capacity_gb=2, flavor_info=flavor_info, resource_constraints=constraints) request = ReserveRequest() request.generation = 1 request.resource = Resource(vm=None, disks=[disk], placement_list=placement_list) response = handler.reserve(request) assert_that(response.result, equal_to(ReserveResultCode.OK))
def test_create_image_from_vm(self): """ Integration test for creating an image from a VM """ img_id = "test-new-im-from-vm-%s" % new_id() tmp_img_id = "-tmp-" + img_id tmp_image, ds = self._create_test_image(tmp_img_id) tmp_image_path = datastore_path(ds.id, "image_" + tmp_img_id) src_vmdk = vmdk_path(ds.id, tmp_img_id, IMAGE_FOLDER_NAME_PREFIX) vm_wrapper = VmWrapper(self.host_client) try: self._manage_disk(vim.VirtualDiskManager.DeleteVirtualDisk_Task, name=src_vmdk) except: logger.error("Error deleting vmdk when setting up tmp image %s" % src_vmdk, exc_info=True) raise dst_image = Image(img_id, ds) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) # VM in wrong state vm_wrapper.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) time.sleep(10) vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.INVALID_VM_POWER_STATE) vm_wrapper.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) time.sleep(10) # Happy case vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.OK) request = Host.GetImagesRequest(ds.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item(img_id)) # Issue another create call and it should fail as the source doesn't # exist. req = FinalizeImageRequest(image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path) response = self.host_client.finalize_image(req) self.assertEqual(response.result, FinalizeImageResultCode.IMAGE_NOT_FOUND) # Verify that we fail if the destination already exists. tmp_image, ds = self._create_test_image(tmp_img_id) vm_wrapper.create_image_from_vm( image_id=tmp_img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.IMAGE_ALREADY_EXIST) vm_wrapper.delete() # VM to create image from is gone. vm_wrapper.create_image_from_vm( image_id=img_id, datastore=ds.id, tmp_image_path=tmp_image_path, expect=Host.CreateImageFromVmResultCode.VM_NOT_FOUND) # Create a VM using the new image created vm_wrapper2 = VmWrapper(self.host_client) image = DiskImage(img_id, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), ] reservation = vm_wrapper2.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper2.create_request(res_id=reservation) vm_wrapper2.create(request=request) vm_wrapper2.power(Host.PowerVmOp.ON, Host.PowerVmOpResultCode.OK) vm_wrapper2.power(Host.PowerVmOp.OFF, Host.PowerVmOpResultCode.OK) vm_wrapper2.delete() # cleanup self._delete_image(dst_image)
def test_attach_cdrom(self): """ Tests attach iso code path. 1. Attach an iso to a non existent VM. Check correct error 2. Attach a non existent iso file to a valid VM. Check correct error 3. Attach a real iso if specified to a VM. Verify it succeeds. Test should pass the iso path as [datastore_name]/path/to/iso.iso """ if not self._remote_iso_file: raise SkipTest("ISO file on server not provided") si = self.get_service_instance() file_manager = si.RetrieveContent().fileManager iso_path = self._generate_new_iso_ds_path() iso_path_2 = self._generate_new_iso_ds_path() vm_wrapper = VmWrapper(self.host_client) image = DiskImage("ttylinux", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), "default", False, True, image=image, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), ] # Create disk and VM. reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_id = vm_wrapper.create(request=request).vm.id # Verify the result when the VM is not found. fake_id = str(uuid.uuid4()) vm_wrapper.attach_iso(fake_id, "/tmp/foo.iso", Host.AttachISOResultCode.VM_NOT_FOUND) # Verify the result when the the iso doesn't exist. vm_wrapper.attach_iso(vm_id, "/tmp/foo.iso", Host.AttachISOResultCode.SYSTEM_ERROR) self._make_new_iso_copy(file_manager, iso_path) self._make_new_iso_copy(file_manager, iso_path_2) # Doing enough attaches will indirectly verify that we do not grow the # device list on reattach. for i in xrange(3): # verify attach works vm_wrapper.attach_iso(vm_id, iso_path) # verify re-attach to another iso works vm_wrapper.attach_iso(vm_id, iso_path_2) vm_wrapper.power(Host.PowerVmOp.ON) # Verify reattach fails when vm is powered on. vm_wrapper.attach_iso(vm_id, iso_path, Host.AttachISOResultCode.ISO_ATTACHED_ERROR) vm_wrapper.power(Host.PowerVmOp.OFF) vm_wrapper.detach_iso(vm_id, True) vm_wrapper.attach_iso(vm_id, iso_path) vm_wrapper.detach_iso(vm_id, True) self.clear()
def test_start_image_scanner(self): """ Test image scanner. Make sure the idle images are reported correctly. """ datastore = self._find_configured_datastore_in_host_config() image_id_1 = new_id() dst_image_1, _ = self._create_test_image(image_id_1) image_id_2 = new_id() dst_image_2, _ = self._create_test_image(image_id_2) disk_image_2 = DiskImage(image_id_2, CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=disk_image_2, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=1, flavor_info=self.DEFAULT_DISK_FLAVOR), Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, True, True, capacity_gb=2, flavor_info=self.DEFAULT_DISK_FLAVOR) ] vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) vm_wrapper.create(request=request) logger.info("Image scan, Vm id: %s" % vm_wrapper.id) # Start image scanner start_scan_request = StartImageScanRequest() start_scan_request.datastore_id = datastore.id start_scan_request.scan_rate = 600 start_scan_request.timeout = 30 start_scan_response = self.host_client.start_image_scan( start_scan_request) self.assertEqual(start_scan_response.result, StartImageOperationResultCode.OK) self._get_and_check_inactive_images(datastore.id, image_id_1, True) get_inactive_images_response = self._get_and_check_inactive_images( datastore.id, image_id_2, False) # Start image sweeper start_sweep_request = StartImageSweepRequest() start_sweep_request.datastore_id = datastore.id start_sweep_request.image_descs = get_inactive_images_response.image_descs start_sweep_request.sweep_rate = 600 start_sweep_request.timeout = 30 start_sweep_request.grace_period = 0 start_sweep_response = self.host_client.start_image_sweep( start_sweep_request) self.assertEqual(start_sweep_response.result, StartImageOperationResultCode.OK) self._get_and_check_deleted_images(datastore.id, image_id_1, True) # cleanup vm_wrapper.delete() self._delete_image(dst_image_1, DeleteDirectoryResultCode.DIRECTORY_NOT_FOUND) self._delete_image(dst_image_2)
def test_copy_image_get_images(self): datastore = self._find_configured_datastore_in_host_config() assert_that(datastore, not_none()) # ttylinux is the default image that is copied to datastore1 # when agent starts src_image = Image("ttylinux", datastore) dst_image = Image("test-copy-image", datastore) # verify test-copy-image is not in datastore request = Host.GetImagesRequest(datastore.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item("ttylinux")) assert_that(response.image_ids, not(has_item("test-copy-image"))) image_number = len(response.image_ids) # Copy image request = Host.CopyImageRequest(src_image, dst_image) response = self.host_client.copy_image(request) assert_that(response.result, is_(CopyImageResultCode.OK)) # Copy image the second time should return DESTINATION_ALREADY_EXIST request = Host.CopyImageRequest(src_image, dst_image) response = self.host_client.copy_image(request) assert_that(response.result, is_(CopyImageResultCode.DESTINATION_ALREADY_EXIST)) # Verify test-copy-image is in datastore request = Host.GetImagesRequest(datastore.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item("ttylinux")) assert_that(response.image_ids, has_item("test-copy-image")) assert_that(response.image_ids, has_length(image_number + 1)) # Create VM image = DiskImage("test-copy-image", CloneType.COPY_ON_WRITE) disks = [ Disk(new_id(), self.DEFAULT_DISK_FLAVOR.name, False, True, image=image, capacity_gb=0, flavor_info=self.DEFAULT_DISK_FLAVOR), ] vm_wrapper = VmWrapper(self.host_client) reservation = vm_wrapper.place_and_reserve(vm_disks=disks).reservation request = vm_wrapper.create_request(res_id=reservation) response = vm_wrapper.create(request=request) assert_that(response.vm, not_none()) # Delete VM vm_wrapper.delete(request=vm_wrapper.delete_request(disk_ids=[])) # Verify test-copy-image is in datastore request = Host.GetImagesRequest(datastore.id) response = self.host_client.get_images(request) assert_that(response.result, is_(GetImagesResultCode.OK)) assert_that(response.image_ids, has_item("ttylinux")) assert_that(response.image_ids, has_item("test-copy-image")) assert_that(response.image_ids, has_length(image_number + 1)) # Copy image using datastore with name as id should succeed # This datastore object uses the datastore name as its id datastore.id = datastore.name dst_image2 = Image("test-copy-image2", datastore) request = Host.CopyImageRequest(src_image, dst_image2) response = self.host_client.copy_image(request) assert_that(response.result, is_(CopyImageResultCode.OK)) # Clean destination image self._delete_image(dst_image) self._delete_image(dst_image2)
def __init__(self, requests_file): self.requests = [] content = open(Universe.get_path(requests_file), 'r').read() requests = yaml.load(content) request_id = 1 disk_id = 1 if 'auto' in requests: requests = self.generate_requests(requests['auto']) for request in requests: place_request = PlaceRequest() resource = Resource() resource.disks = [] env_info = {} if 'vm' in request: resource.vm = Vm() # Make the vm id look like a uuid by zero-padding. Otherwise # reference counting doesn't work. resource.vm.id = "{0:032d}".format(request_id) resource.vm.state = State.STARTED flavor = Universe.vm_flavors[request['vm']['flavor']] resource.vm.flavor = flavor.name resource.vm.flavor_info = flavor.to_thrift() resource.vm.disks = [] if 'constraints' in request: constraints = [] for c in request['constraints']: constraint = ResourceConstraint() constraint.type = RCT._NAMES_TO_VALUES[c['type']] constraint.values = c['values'] if 'negative' in c: constraint.negative = c['negative'] else: constraint.negative = False constraints.append(constraint) if constraints: resource.vm.resource_constraints = constraints if 'load' in request['vm']: env_info['mem_load'] = request['vm']['load']['mem'] if 'disks' in request: for d in request['disks']: disk = Disk() flavor = Universe.ephemeral_disk_flavors[d['flavor']] disk.flavor = flavor.name disk.flavor_info = flavor.to_thrift() disk.id = str(disk_id) disk.persistent = False disk.new_disk = True disk.capacity_gb = 1024 # hard coded in FakeVmManager disk_id += 1 resource.vm.disks.append(disk) place_request.resource = resource tracing_info = TracingInfo() tracing_info.request_id = request_id place_request.tracing_info = tracing_info request_id += 1 self.requests.append(PsimVmRequest(place_request, env_info))