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)
Beispiel #2
0
    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
Beispiel #3
0
    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)
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
    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()
Beispiel #11
0
    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)
Beispiel #13
0
 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
Beispiel #14
0
    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=[]))
Beispiel #15
0
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]
Beispiel #16
0
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]
Beispiel #17
0
    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)
Beispiel #19
0
    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))
Beispiel #20
0
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]
Beispiel #21
0
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]
Beispiel #22
0
    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()]))
Beispiel #25
0
    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))
Beispiel #26
0
    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)
Beispiel #31
0
    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))
Beispiel #32
0
    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))