Пример #1
0
    def test_get_url(self):
        driver = lxd_module.LXDPodDriver()
        context = {"power_address": factory.make_hostname()}

        # Test ip adds protocol and port
        self.assertEqual(
            join("https://", "%s:%d" % (context["power_address"], 8443)),
            driver.get_url(context),
        )

        # Test ip:port adds protocol
        context["power_address"] += ":1234"
        self.assertEqual(
            join("https://", "%s" % context["power_address"]),
            driver.get_url(context),
        )

        # Test protocol:ip adds port
        context["power_address"] = join("https://", factory.make_hostname())
        self.assertEqual(
            "%s:%d" % (context.get("power_address"), 8443),
            driver.get_url(context),
        )

        # Test protocol:ip:port doesn't do anything
        context["power_address"] += ":1234"
        self.assertEqual(context.get("power_address"), driver.get_url(context))
Пример #2
0
 def test_power_query(self):
     context = self.make_parameters_context()
     driver = lxd_module.LXDPodDriver()
     mock_machine = self.patch(driver, "get_machine").return_value
     mock_machine.status_code = 103
     state = yield driver.power_query(None, context)
     self.assertThat(state, Equals("on"))
Пример #3
0
    def test_get_discovered_pod_storage_pool(self):
        driver = lxd_module.LXDPodDriver()
        mock_storage_pool = Mock()
        mock_storage_pool.name = factory.make_name("pool")
        mock_storage_pool.driver = "dir"
        mock_storage_pool.config = {
            "size": "61203283968",
            "source": "/home/chb/mnt/l2/disks/default.img",
            "volume.size": "0",
            "zfs.pool_name": "default",
        }
        mock_resources = Mock()
        mock_resources.space = {"used": 207111192576, "total": 306027577344}
        mock_storage_pool.resources.get.return_value = mock_resources
        discovered_pod_storage_pool = (
            yield driver.get_discovered_pod_storage_pool(mock_storage_pool))

        self.assertEquals(mock_storage_pool.name,
                          discovered_pod_storage_pool.id)
        self.assertEquals(mock_storage_pool.name,
                          discovered_pod_storage_pool.name)
        self.assertEquals(
            mock_storage_pool.config["source"],
            discovered_pod_storage_pool.path,
        )
        self.assertEquals(mock_storage_pool.driver,
                          discovered_pod_storage_pool.type)
        self.assertEquals(mock_resources.space["total"],
                          discovered_pod_storage_pool.storage)
Пример #4
0
 def test_get_usable_storage_pool_filters_on_default_pool_name_raises_invalid(
     self, ):
     driver = lxd_module.LXDPodDriver()
     pools = [
         Mock(
             **{
                 "resources.get.return_value":
                 Mock(space={
                     "total": 2**i * 2048,
                     "used": 2 * i * 1500
                 })
             }) for i in range(3)
     ]
     # Override name attribute on Mock and calculate the available
     for pool in pools:
         type(pool).name = PropertyMock(
             return_value=factory.make_name("pool_name"))
     disk = RequestedMachineBlockDevice(size=2048 + 1, tags=[])
     self.assertRaises(
         PodInvalidResources,
         driver.get_usable_storage_pool,
         disk,
         pools,
         pools[0].name,
     )
Пример #5
0
 def test_power_off(self):
     context = self.make_parameters_context()
     driver = lxd_module.LXDPodDriver()
     mock_machine = self.patch(driver, "get_machine").return_value
     mock_machine.status_code = 103
     yield driver.power_off(None, context)
     self.assertThat(mock_machine.stop, MockCalledOnceWith())
Пример #6
0
    def test_decompose(self):
        pod_id = factory.make_name("pod_id")
        context = self.make_parameters_context()
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(driver, "get_client")
        client = Client.return_value
        mock_machine = Mock()
        client.virtual_machines.get.return_value = mock_machine
        empty_hints = yield driver.decompose(pod_id, context)

        self.assertThat(mock_machine.stop, MockCalledOnceWith())
        self.assertThat(mock_machine.delete, MockCalledOnceWith(wait=True))
        self.assertThat(
            empty_hints,
            MatchesAll(
                IsInstance(DiscoveredPodHints),
                MatchesStructure(
                    cores=Equals(-1),
                    cpu_speed=Equals(-1),
                    memory=Equals(-1),
                    local_storage=Equals(-1),
                    local_disks=Equals(-1),
                    iscsi_storage=Equals(-1),
                ),
            ),
        )
Пример #7
0
 def test_power_query_raises_error_on_unknown_state(self):
     context = self.make_parameters_context()
     pod_id = factory.make_name("pod_id")
     driver = lxd_module.LXDPodDriver()
     mock_machine = self.patch(driver, "get_machine").return_value
     mock_machine.status_code = 106
     error_msg = f"Pod {pod_id}: Unknown power status code: {mock_machine.status_code}"
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.power_query(pod_id, context)
Пример #8
0
 def test_get_client_raises_error_when_cannot_connect(self):
     context = self.make_parameters_context()
     pod_id = factory.make_name("pod_id")
     Client = self.patch(lxd_module, "Client")
     Client.side_effect = lxd_module.ClientConnectionFailed()
     driver = lxd_module.LXDPodDriver()
     error_msg = f"Pod {pod_id}: Failed to connect to the LXD REST API."
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.get_client(pod_id, context)
Пример #9
0
 def test_get_machine(self):
     context = self.make_parameters_context()
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(driver, "get_client")
     client = Client.return_value
     mock_machine = Mock()
     client.virtual_machines.get.return_value = mock_machine
     returned_machine = yield driver.get_machine(None, context)
     self.assertThat(Client, MockCalledOnceWith(None, context))
     self.assertEquals(mock_machine, returned_machine)
Пример #10
0
 def test_get_machine_raises_error_when_machine_not_found(self):
     context = self.make_parameters_context()
     pod_id = factory.make_name("pod_id")
     instance_name = context.get("instance_name")
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(driver, "get_client")
     client = Client.return_value
     client.virtual_machines.get.side_effect = lxd_module.NotFound("Error")
     error_msg = f"Pod {pod_id}: LXD VM {instance_name} not found."
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.get_machine(pod_id, context)
Пример #11
0
 def test_discover_requires_client_to_have_vm_support(self):
     context = self.make_parameters_context()
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     client.has_api_extension.return_value = False
     error_msg = "Please upgrade your LXD host to *."
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield ensureDeferred(driver.discover(None, context))
     self.assertThat(client.has_api_extension,
                     MockCalledOnceWith("virtual-machines"))
Пример #12
0
 def test_get_client_raises_error_when_not_trusted_and_no_password(self):
     context = self.make_parameters_context()
     context["password"] = None
     pod_id = factory.make_name("pod_id")
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     client.trusted = False
     driver = lxd_module.LXDPodDriver()
     error_msg = f"Pod {pod_id}: Certificate is not trusted and no password was given."
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.get_client(pod_id, context)
Пример #13
0
 def test_get_client_raises_error_when_cannot_connect(self):
     context = self.make_parameters_context()
     pod_id = factory.make_name("pod_id")
     Client = self.patch(lxd_module, "Client")
     Client.side_effect = lxd_module.ClientConnectionFailed()
     # Getting the cert tuple can cause a certificate to be generated which
     # can be slow but isn't needed for this test.
     self.patch(maas_certificates, "get_maas_cert_tuple")
     driver = lxd_module.LXDPodDriver()
     error_msg = f"Pod {pod_id}: Failed to connect to the LXD REST API."
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.get_client(pod_id, context)
Пример #14
0
 def test_compose_errors_if_not_default_or_maas_profile(self):
     pod_id = factory.make_name("pod_id")
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(driver, "get_client")
     client = Client.return_value
     client.profiles.get.side_effect = [
         lxd_module.NotFound("Error"),
         lxd_module.NotFound("Error"),
     ]
     error_msg = (f"Pod {pod_id}: MAAS needs LXD to have either a 'maas' "
                  "profile or a 'default' profile, defined.")
     with ExpectedException(lxd_module.LXDPodError, error_msg):
         yield driver.compose(pod_id, {}, None)
Пример #15
0
    def test_get_discovered_machine_sets_power_state_to_unknown_for_unknown(
        self, ):
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(lxd_module, "Client")
        client = Client.return_value
        mock_machine = Mock()
        mock_machine.name = factory.make_name("machine")
        mock_machine.architecture = "x86_64"
        expanded_config = {
            "limits.cpu": "2",
            "limits.memory": "1024",
            "volatile.eth0.hwaddr": "00:16:3e:78:be:04",
            "volatile.eth1.hwaddr": "00:16:3e:f9:fc:cb",
        }
        expanded_devices = {
            "eth0": {
                "name": "eth0",
                "nictype": "bridged",
                "parent": "lxdbr0",
                "type": "nic",
            },
            "eth1": {
                "name": "eth1",
                "nictype": "bridged",
                "parent": "virbr1",
                "type": "nic",
            },
            "root": {
                "path": "/",
                "pool": "default",
                "type": "disk"
            },
        }
        mock_machine.expanded_config = expanded_config
        mock_machine.expanded_devices = expanded_devices
        mock_machine.status_code = 100
        mock_storage_pool = Mock()
        mock_storage_pool.name = "default"
        mock_storage_pool_resources = Mock()
        mock_storage_pool_resources.space = {
            "used": 207111192576,
            "total": 306027577344,
        }
        mock_storage_pool.resources.get.return_value = (
            mock_storage_pool_resources)
        mock_machine.storage_pools.get.return_value = mock_storage_pool
        discovered_machine = yield ensureDeferred(
            driver.get_discovered_machine(client, mock_machine,
                                          [mock_storage_pool]))

        self.assertEquals("unknown", discovered_machine.power_state)
Пример #16
0
 def test_discover(self):
     context = self.make_parameters_context()
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     client.has_api_extension.return_value = True
     name = factory.make_name("hostname")
     client.host_info = {
         "environment": {
             "architectures": ["x86_64", "i686"],
             "kernel_architecture": "x86_64",
             "server_name": name,
         }
     }
     mac_address = factory.make_mac_address()
     client.resources = {
         "network": {
             "cards": [{
                 "ports": [{
                     "address": mac_address
                 }]
             }]
         }
     }
     discovered_pod = yield ensureDeferred(driver.discover(None, context))
     self.assertItemsEqual(["amd64/generic"], discovered_pod.architectures)
     self.assertEquals(name, discovered_pod.name)
     self.assertItemsEqual([mac_address], discovered_pod.mac_addresses)
     self.assertEquals(-1, discovered_pod.cores)
     self.assertEquals(-1, discovered_pod.cpu_speed)
     self.assertEquals(-1, discovered_pod.memory)
     self.assertEquals(0, discovered_pod.local_storage)
     self.assertEquals(-1, discovered_pod.local_disks)
     self.assertEquals(-1, discovered_pod.iscsi_storage)
     self.assertEquals(-1, discovered_pod.hints.cores)
     self.assertEquals(-1, discovered_pod.hints.cpu_speed)
     self.assertEquals(-1, discovered_pod.hints.local_storage)
     self.assertEquals(-1, discovered_pod.hints.local_disks)
     self.assertEquals(-1, discovered_pod.hints.iscsi_storage)
     self.assertItemsEqual(
         [
             Capabilities.COMPOSABLE,
             Capabilities.DYNAMIC_LOCAL_STORAGE,
             Capabilities.OVER_COMMIT,
             Capabilities.STORAGE_POOLS,
         ],
         discovered_pod.capabilities,
     )
     self.assertItemsEqual([], discovered_pod.machines)
     self.assertItemsEqual([], discovered_pod.tags)
     self.assertItemsEqual([], discovered_pod.storage_pools)
Пример #17
0
    def test_decompose_on_stopped_instance(self):
        pod_id = factory.make_name("pod_id")
        context = self.make_parameters_context()
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(driver, "get_client")
        client = Client.return_value
        mock_machine = Mock()
        # Simulate the case where the VM is already stopped
        mock_machine.status_code = 102  # 102 - Stopped
        client.virtual_machines.get.return_value = mock_machine
        yield driver.decompose(pod_id, context)

        mock_machine.stop.assert_not_called()
        mock_machine.delete.assert_called_once_with(wait=True)
Пример #18
0
 def test_get_hugepages_info_int_value_as_bool(self):
     driver = lxd_module.LXDPodDriver()
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     mock_machine = Mock()
     mock_machine.name = factory.make_name("machine")
     mock_machine.architecture = "x86_64"
     expanded_config = {
         "limits.memory.hugepages": "1",
     }
     mock_machine.expanded_config = expanded_config
     mock_machine.expanded_devices = {}
     discovered_machine = yield ensureDeferred(
         driver.get_discovered_machine(client, mock_machine, []))
     self.assertTrue(discovered_machine.hugepages_backed)
Пример #19
0
 def test_get_client(self):
     context = self.make_parameters_context()
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     client.has_api_extension.return_value = True
     client.trusted = False
     driver = lxd_module.LXDPodDriver()
     endpoint = driver.get_url(context)
     returned_client = yield driver.get_client(None, context)
     self.assertThat(
         Client,
         MockCalledOnceWith(
             endpoint=endpoint,
             cert=(MAAS_CERTIFICATE, MAAS_PRIVATE_KEY),
             verify=False,
         ),
     )
     self.assertThat(client.authenticate,
                     MockCalledOnceWith(context["password"]))
     self.assertEquals(client, returned_client)
Пример #20
0
 def test_get_usable_storage_pool_filters_on_disk_tags(self):
     driver = lxd_module.LXDPodDriver()
     pools = [
         Mock(
             **{
                 "resources.get.return_value":
                 Mock(space={
                     "total": 2**i * 2048,
                     "used": 2 * i * 1500
                 })
             }) for i in range(3)
     ]
     # Override name attribute on Mock and calculate the available
     for pool in pools:
         type(pool).name = PropertyMock(
             return_value=factory.make_name("pool_name"))
     selected_pool = pools[1]
     disk = RequestedMachineBlockDevice(size=1024,
                                        tags=[selected_pool.name])
     self.assertEqual(pools[1].name,
                      driver.get_usable_storage_pool(disk, pools))
Пример #21
0
 def test_get_commissioning_data(self):
     driver = lxd_module.LXDPodDriver()
     context = self.make_parameters_context()
     Client = self.patch(lxd_module, "Client")
     client = Client.return_value
     client.resources = {
         factory.make_name("rkey"): factory.make_name("rvalue")
     }
     client.host_info = {
         factory.make_name("hkey"): factory.make_name("hvalue")
     }
     commissioning_data = yield driver.get_commissioning_data(1, context)
     self.assertDictEqual(
         {
             LXD_OUTPUT_NAME: {
                 **client.host_info,
                 "resources": client.resources,
             }
         },
         commissioning_data,
     )
Пример #22
0
    def test_get_commissioning_data(self):
        driver = lxd_module.LXDPodDriver()
        context = self.make_parameters_context()
        Client = self.patch(lxd_module, "Client")
        client = Client.return_value
        client.resources = {
            factory.make_name("rkey"): factory.make_name("rvalue")
        }
        client.host_info = {
            factory.make_name("hkey"): factory.make_name("hvalue")
        }

        def mock_iface(name, mac):
            iface = Mock()
            iface.state.return_value = {"hwaddr": mac}
            iface.configure_mock(name=name)
            return iface

        client.networks.all.return_value = [
            mock_iface("eth0", "aa:bb:cc:dd:ee:ff"),
            mock_iface("eth1", "ff:ee:dd:cc:bb:aa"),
        ]
        commissioning_data = yield driver.get_commissioning_data(1, context)
        self.assertDictEqual(
            {
                LXD_OUTPUT_NAME: {
                    **client.host_info,
                    "resources": client.resources,
                    "networks": {
                        "eth0": {
                            "hwaddr": "aa:bb:cc:dd:ee:ff"
                        },
                        "eth1": {
                            "hwaddr": "ff:ee:dd:cc:bb:aa"
                        },
                    },
                }
            },
            commissioning_data,
        )
Пример #23
0
 def test_get_usable_storage_pool(self):
     driver = lxd_module.LXDPodDriver()
     pools = [
         Mock(
             **{
                 "resources.get.return_value":
                 Mock(space={
                     "total": 2**i * 2048,
                     "used": 2 * i * 1500
                 })
             }) for i in range(3)
     ]
     # Override name attribute on Mock and calculate the available
     for pool in pools:
         type(pool).name = PropertyMock(
             return_value=factory.make_name("pool_name"))
     disk = RequestedMachineBlockDevice(
         size=2048,  # Only the first pool will have this availability.
         tags=[],
     )
     self.assertEqual(pools[0].name,
                      driver.get_usable_storage_pool(disk, pools))
Пример #24
0
    def test_get_discovered_machine(self):
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(lxd_module, "Client")
        client = Client.return_value
        mock_machine = Mock()
        mock_machine.name = factory.make_name("machine")
        mock_machine.architecture = "x86_64"
        expanded_config = {
            "limits.cpu": "2",
            "limits.memory": "1024MiB",
            "volatile.eth0.hwaddr": "00:16:3e:78:be:04",
            "volatile.eth1.hwaddr": "00:16:3e:f9:fc:cb",
            "volatile.eth2.hwaddr": "00:16:3e:f9:fc:cc",
        }
        expanded_devices = {
            "eth0": {
                "name": "eth0",
                "network": "lxdbr0",
                "type": "nic",
            },
            "eth1": {
                "name": "eth1",
                "nictype": "bridged",
                "parent": "br1",
                "type": "nic",
            },
            "eth2": {
                "name": "eth2",
                "nictype": "macvlan",
                "parent": "eno2",
                "type": "nic",
            },
            # SR-IOV devices created by MAAS have an explicit MAC set on
            # the device, so that it knows what the MAC will be.
            "eth3": {
                "name": "eth3",
                "hwaddr": "00:16:3e:f9:fc:dd",
                "nictype": "sriov",
                "parent": "eno3",
                "type": "nic",
            },
            "eth4": {
                "name": "eth4",
                "hwaddr": "00:16:3e:f9:fc:ee",
                "nictype": "sriov",
                "parent": "eno3",
                "vlan": "33",
                "type": "nic",
            },
            # An interface not created by MAAS, thus lacking an explicit
            # MAC.
            "eth5": {
                "name": "eth5",
                "nictype": "sriov",
                "parent": "eno3",
                "vlan": "44",
                "type": "nic",
            },
            "root": {
                "path": "/",
                "pool": "default",
                "type": "disk",
                "size": "20GB",
            },
        }
        mock_machine.expanded_config = expanded_config
        mock_machine.expanded_devices = expanded_devices
        mock_machine.status_code = 102
        mock_storage_pool = Mock()
        mock_storage_pool.name = "default"
        mock_storage_pool_resources = Mock()
        mock_storage_pool_resources.space = {
            "used": 207111192576,
            "total": 306027577344,
        }
        mock_storage_pool.resources.get.return_value = (
            mock_storage_pool_resources)
        mock_machine.storage_pools.get.return_value = mock_storage_pool
        mock_network = Mock()
        mock_network.type = "bridge"
        mock_network.name = "lxdbr0"
        client.networks.get.return_value = mock_network
        discovered_machine = yield ensureDeferred(
            driver.get_discovered_machine(client, mock_machine,
                                          [mock_storage_pool]))

        self.assertEqual(mock_machine.name, discovered_machine.hostname)
        self.assertEqual("uefi", discovered_machine.bios_boot_method)

        self.assertEqual(
            kernel_to_debian_architecture(mock_machine.architecture),
            discovered_machine.architecture,
        )
        self.assertEqual(
            lxd_module.LXD_VM_POWER_STATE[mock_machine.status_code],
            discovered_machine.power_state,
        )
        self.assertEqual(2, discovered_machine.cores)
        self.assertEqual(1024, discovered_machine.memory)
        self.assertEqual(
            mock_machine.name,
            discovered_machine.power_parameters["instance_name"],
        )
        self.assertEqual(
            discovered_machine.block_devices[0],
            DiscoveredMachineBlockDevice(
                model="QEMU HARDDISK",
                serial="lxd_root",
                id_path="/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_root",
                size=20 * 1000**3,
                block_size=512,
                tags=[],
                type="physical",
                storage_pool=expanded_devices["root"]["pool"],
                iscsi_target=None,
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[0],
            DiscoveredMachineInterface(
                mac_address=expanded_config["volatile.eth0.hwaddr"],
                vid=0,
                tags=[],
                boot=True,
                attach_type=InterfaceAttachType.BRIDGE,
                attach_name="lxdbr0",
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[1],
            DiscoveredMachineInterface(
                mac_address=expanded_config["volatile.eth1.hwaddr"],
                vid=0,
                tags=[],
                boot=False,
                attach_type=InterfaceAttachType.BRIDGE,
                attach_name="br1",
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[2],
            DiscoveredMachineInterface(
                mac_address=expanded_config["volatile.eth2.hwaddr"],
                vid=0,
                tags=[],
                boot=False,
                attach_type=InterfaceAttachType.MACVLAN,
                attach_name="eno2",
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[3],
            DiscoveredMachineInterface(
                mac_address=expanded_devices["eth3"]["hwaddr"],
                vid=0,
                tags=[],
                boot=False,
                attach_type=InterfaceAttachType.SRIOV,
                attach_name="eno3",
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[4],
            DiscoveredMachineInterface(
                mac_address=expanded_devices["eth4"]["hwaddr"],
                vid=33,
                tags=[],
                boot=False,
                attach_type=InterfaceAttachType.SRIOV,
                attach_name="eno3",
            ),
        )
        self.assertEqual(
            discovered_machine.interfaces[5],
            DiscoveredMachineInterface(
                mac_address=None,
                vid=44,
                tags=[],
                boot=False,
                attach_type=InterfaceAttachType.SRIOV,
                attach_name="eno3",
            ),
        )
        self.assertItemsEqual([], discovered_machine.tags)
        self.assertFalse(discovered_machine.hugepages_backed)
        self.assertEqual(discovered_machine.pinned_cores, [])
Пример #25
0
 def test_missing_packages(self):
     driver = lxd_module.LXDPodDriver()
     missing = driver.detect_missing_packages()
     self.assertItemsEqual([], missing)
Пример #26
0
    def test_compose_multiple_interface_constraints(self):
        pod_id = factory.make_name("pod_id")
        context = self.make_parameters_context()
        request = make_requested_machine()
        request.interfaces = [
            RequestedMachineInterface(
                ifname=factory.make_name("ifname"),
                attach_name=factory.make_name("bridge_name"),
                attach_type="bridge",
                attach_options=None,
            ) for _ in range(3)
        ]
        # LXD uses 'bridged' while MAAS uses 'bridge' so convert
        # the nictype as this is what we expect from LXDPodDriver.compose.
        expected_interfaces = [{
            "name": request.interfaces[i].ifname,
            "parent": request.interfaces[i].attach_name,
            "nictype": "bridged",
            "type": "nic",
        } for i in range(3)]
        expected_interfaces[0]["boot.priority"] = "1"
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(driver, "get_client")
        client = Client.return_value
        mock_profile = Mock()
        mock_profile.name = random.choice(["maas", "default"])
        profile_devices = {
            "eth0": {
                "name": "eth0",
                "nictype": "bridged",
                "parent": "lxdbr0",
                "type": "nic",
            },
            "eth1": {
                "boot.priority": "1",
                "name": "eth1",
                "nictype": "bridged",
                "parent": "virbr1",
                "type": "nic",
            },
            "root": {
                "boot.priority": "0",
                "path": "/",
                "pool": "default",
                "type": "disk",
                "size": "20GB",
            },
        }
        mock_profile.devices = profile_devices
        client.profiles.get.return_value = mock_profile
        mock_storage_pools = Mock()
        client.storage_pools.all.return_value = mock_storage_pools
        mock_get_usable_storage_pool = self.patch(driver,
                                                  "get_usable_storage_pool")
        usable_pool = factory.make_name("pool")
        mock_get_usable_storage_pool.return_value = usable_pool
        mock_get_best_nic_from_profile = self.patch(
            driver, "get_best_nic_from_profile")
        mock_get_best_nic_from_profile.return_value = (
            "eth1",
            profile_devices["eth1"],
        )
        mock_machine = Mock()
        client.virtual_machines.create.return_value = mock_machine
        mock_get_discovered_machine = self.patch(driver,
                                                 "get_discovered_machine")
        mock_get_discovered_machine.side_effect = async_succeed(
            sentinel.discovered_machine)
        definition = {
            "name": request.hostname,
            "architecture":
            debian_to_kernel_architecture(request.architecture),
            "config": {
                "limits.cpu": str(request.cores),
                "limits.memory": str(request.memory * 1024**2),
                "security.secureboot": "false",
            },
            "profiles": [mock_profile.name],
            "source": {
                "type": "none"
            },
            "devices": {
                "root": {
                    "path": "/",
                    "type": "disk",
                    "pool": usable_pool,
                    "size": str(request.block_devices[0].size),
                    "boot.priority": "0",
                },
                expected_interfaces[0]["name"]: expected_interfaces[0],
                expected_interfaces[1]["name"]: expected_interfaces[1],
                expected_interfaces[2]["name"]: expected_interfaces[2],
                "eth1": {
                    "type": "none"
                },
                "eth0": {
                    "type": "none"
                },
            },
        }

        discovered_machine, empty_hints = yield driver.compose(
            pod_id, context, request)
        self.assertThat(
            client.virtual_machines.create,
            MockCalledOnceWith(definition, wait=True),
        )
        self.assertEquals(sentinel.discovered_machine, discovered_machine)
        self.assertThat(
            empty_hints,
            MatchesAll(
                IsInstance(DiscoveredPodHints),
                MatchesStructure(
                    cores=Equals(-1),
                    cpu_speed=Equals(-1),
                    memory=Equals(-1),
                    local_storage=Equals(-1),
                    local_disks=Equals(-1),
                    iscsi_storage=Equals(-1),
                ),
            ),
        )
Пример #27
0
    def test_get_discovered_machine(self):
        driver = lxd_module.LXDPodDriver()
        Client = self.patch(lxd_module, "Client")
        client = Client.return_value
        mock_machine = Mock()
        mock_machine.name = factory.make_name("machine")
        mock_machine.architecture = "x86_64"
        expanded_config = {
            "limits.cpu": "2",
            "limits.memory": "1024MiB",
            "volatile.eth0.hwaddr": "00:16:3e:78:be:04",
            "volatile.eth1.hwaddr": "00:16:3e:f9:fc:cb",
        }
        expanded_devices = {
            "eth0": {
                "name": "eth0",
                "nictype": "bridged",
                "parent": "lxdbr0",
                "type": "nic",
            },
            "eth1": {
                "name": "eth1",
                "nictype": "bridged",
                "parent": "virbr1",
                "type": "nic",
            },
            "root": {
                "path": "/",
                "pool": "default",
                "type": "disk",
                "size": "20GB",
            },
        }
        mock_machine.expanded_config = expanded_config
        mock_machine.expanded_devices = expanded_devices
        mock_machine.status_code = 102
        mock_storage_pool = Mock()
        mock_storage_pool.name = "default"
        mock_storage_pool_resources = Mock()
        mock_storage_pool_resources.space = {
            "used": 207111192576,
            "total": 306027577344,
        }
        mock_storage_pool.resources.get.return_value = (
            mock_storage_pool_resources
        )
        mock_machine.storage_pools.get.return_value = mock_storage_pool
        discovered_machine = yield driver.get_discovered_machine(
            client, mock_machine, [mock_storage_pool]
        )

        self.assertEquals(mock_machine.name, discovered_machine.hostname)

        self.assertEquals(
            kernel_to_debian_architecture(mock_machine.architecture),
            discovered_machine.architecture,
        )
        self.assertEquals(
            lxd_module.LXD_VM_POWER_STATE[mock_machine.status_code],
            discovered_machine.power_state,
        )
        self.assertEquals(2, discovered_machine.cores)
        self.assertEquals(1024, discovered_machine.memory)
        self.assertEquals(
            mock_machine.name,
            discovered_machine.power_parameters["instance_name"],
        )
        self.assertThat(
            discovered_machine.block_devices[0],
            MatchesStructure.byEquality(
                model="QEMU HARDDISK",
                serial="lxd_root",
                id_path="/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_root",
                size=20 * 1000 ** 3,
                block_size=512,
                tags=[],
                type="physical",
                storage_pool=expanded_devices["root"]["pool"],
                iscsi_target=None,
            ),
        )
        self.assertThat(
            discovered_machine.interfaces[0],
            MatchesStructure.byEquality(
                mac_address=expanded_config["volatile.eth0.hwaddr"],
                vid=0,
                tags=[],
                boot=True,
                attach_type=expanded_devices["eth0"]["nictype"],
                attach_name="eth0",
            ),
        )
        self.assertThat(
            discovered_machine.interfaces[1],
            MatchesStructure.byEquality(
                mac_address=expanded_config["volatile.eth1.hwaddr"],
                vid=0,
                tags=[],
                boot=False,
                attach_type=expanded_devices["eth1"]["nictype"],
                attach_name="eth1",
            ),
        )
        self.assertItemsEqual([], discovered_machine.tags)