Beispiel #1
0
 def get_pod_resources(self):
     """Get the pod resources."""
     discovered_pod = DiscoveredPod(architectures=[],
                                    cores=0,
                                    cpu_speed=0,
                                    memory=0,
                                    local_storage=0,
                                    hints=DiscoveredPodHints(
                                        cores=0,
                                        cpu_speed=0,
                                        memory=0,
                                        local_storage=0))
     discovered_pod.architectures = [self.get_pod_arch()]
     discovered_pod.capabilities = [
         Capabilities.COMPOSABLE,
         Capabilities.DYNAMIC_LOCAL_STORAGE,
         Capabilities.OVER_COMMIT,
         Capabilities.STORAGE_POOLS,
     ]
     discovered_pod.cores = self.get_pod_cpu_count()
     discovered_pod.cpu_speed = self.get_pod_cpu_speed()
     discovered_pod.memory = self.get_pod_memory()
     discovered_pod.storage_pools = self.get_pod_storage_pools()
     discovered_pod.local_storage = sum(
         pool.storage for pool in discovered_pod.storage_pools)
     return discovered_pod
Beispiel #2
0
 def fake_pod_discovery(self):
     discovered_pod = DiscoveredPod(
         architectures=["amd64/generic"],
         cores=random.randint(2, 4),
         memory=random.randint(1024, 4096),
         local_storage=random.randint(1024, 1024 * 1024),
         cpu_speed=random.randint(2048, 4048),
         hints=DiscoveredPodHints(
             cores=random.randint(2, 4),
             memory=random.randint(1024, 4096),
             local_storage=random.randint(1024, 1024 * 1024),
             cpu_speed=random.randint(2048, 4048),
         ),
     )
     discovered_rack_1 = factory.make_RackController()
     discovered_rack_2 = factory.make_RackController()
     failed_rack = factory.make_RackController()
     self.patch(pods, "discover_pod").return_value = succeed((
         {
             discovered_rack_1.system_id: discovered_pod,
             discovered_rack_2.system_id: discovered_pod,
         },
         {
             failed_rack.system_id: factory.make_exception()
         },
     ))
Beispiel #3
0
    def test__calls_DiscoverPod_on_all_clients(self):
        rack_ids = [factory.make_name("system_id") for _ in range(3)]
        pod = DiscoveredPod(
            architectures=["amd64/generic"],
            cores=random.randint(1, 8),
            cpu_speed=random.randint(1000, 3000),
            memory=random.randint(1024, 4096),
            local_storage=random.randint(500, 1000),
            hints=DiscoveredPodHints(
                cores=random.randint(1, 8),
                cpu_speed=random.randint(1000, 3000),
                memory=random.randint(1024, 4096),
                local_storage=random.randint(500, 1000),
            ),
        )
        clients = []
        for rack_id in rack_ids:
            client = Mock()
            client.ident = rack_id
            client.return_value = succeed({"pod": pod})
            clients.append(client)

        self.patch(pods_module, "getAllClients").return_value = clients
        discovered = yield discover_pod(factory.make_name("pod"), {})
        self.assertEquals(({rack_id: pod
                            for rack_id in rack_ids}, {}), discovered)
Beispiel #4
0
 def fake_pod_discovery(self):
     discovered_pod = DiscoveredPod(
         architectures=['amd64/generic'],
         cores=random.randint(2, 4), memory=random.randint(1024, 4096),
         local_storage=random.randint(1024, 1024 * 1024),
         cpu_speed=random.randint(2048, 4048),
         hints=DiscoveredPodHints(
             cores=random.randint(2, 4), memory=random.randint(1024, 4096),
             local_storage=random.randint(1024, 1024 * 1024),
             cpu_speed=random.randint(2048, 4048)),
         storage_pools=[
             DiscoveredPodStoragePool(
                 id=factory.make_name('pool_id'),
                 name=factory.make_name('name'),
                 type=factory.make_name('type'),
                 path='/var/lib/path/%s' % factory.make_name('path'),
                 storage=random.randint(1024, 1024 * 1024),
             )
             for _ in range(3)
         ])
     discovered_rack_1 = factory.make_RackController()
     discovered_rack_2 = factory.make_RackController()
     failed_rack = factory.make_RackController()
     self.patch(pods_module, "discover_pod").return_value = ({
         discovered_rack_1.system_id: discovered_pod,
         discovered_rack_2.system_id: discovered_pod,
     }, {
         failed_rack.system_id: factory.make_exception(),
     })
     return (
         discovered_pod,
         [discovered_rack_1, discovered_rack_2],
         [failed_rack])
Beispiel #5
0
    def test_returns_discovered_pod_and_errors(self):
        pod_type = factory.make_name("pod")
        pod = DiscoveredPod(
            architectures=["amd64/generic"],
            cores=random.randint(1, 8),
            cpu_speed=random.randint(1000, 3000),
            memory=random.randint(1024, 4096),
            local_storage=random.randint(500, 1000),
            hints=DiscoveredPodHints(
                cores=random.randint(1, 8),
                cpu_speed=random.randint(1000, 3000),
                memory=random.randint(1024, 4096),
                local_storage=random.randint(500, 1000),
            ),
        )

        clients = []
        client = Mock()
        error_rack_id = factory.make_name("system_id")
        client.ident = error_rack_id
        exception = UnknownPodType(pod_type)
        client.return_value = fail(exception)
        clients.append(client)

        valid_rack_id = factory.make_name("system_id")
        client = Mock()
        client.ident = valid_rack_id
        client.return_value = succeed({"pod": pod})
        clients.append(client)

        self.patch(pods_module, "getAllClients").return_value = clients
        discovered = yield discover_pod(pod_type, {})
        self.assertEqual(
            ({valid_rack_id: pod}, {error_rack_id: exception}), discovered
        )
Beispiel #6
0
    def discover(self, pod_id, context):
        """Discover all Pod host resources."""
        client = yield self.get_client(pod_id, context)
        if not client.has_api_extension("virtual-machines"):
            raise LXDError(
                "Please upgrade your LXD host to 3.19+ for virtual machine support."
            )
        resources = yield deferToThread(lambda: client.resources)

        mac_addresses = []
        for card in resources["network"]["cards"]:
            for port in card["ports"]:
                mac_addresses.append(port["address"])

        # After the region creates the Pod object it will sync LXD commissioning
        # data for all hardware information.
        return DiscoveredPod(
            architectures=[
                kernel_to_debian_architecture(arch)
                for arch in client.host_info["environment"]["architectures"]
            ],
            name=client.host_info["environment"]["server_name"],
            mac_addresses=mac_addresses,
            capabilities=[
                Capabilities.COMPOSABLE,
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.OVER_COMMIT,
                Capabilities.STORAGE_POOLS,
            ],
        )
Beispiel #7
0
class TestDiscoveredPod(MAASTestCase):

    example = DiscoveredPod(
        architectures=['amd64/generic'],
        cores=random.randint(1, 8), cpu_speed=random.randint(1000, 3000),
        memory=random.randint(1024, 8192), local_storage=0,
        hints=DiscoveredPodHints(
            cores=random.randint(1, 8),
            cpu_speed=random.randint(1000, 2000),
            memory=random.randint(1024, 8192), local_storage=0),
        machines=[])

    def test_round_trip(self):
        argument = arguments.AmpDiscoveredPod()
        encoded = argument.toString(self.example)
        self.assertThat(encoded, IsInstance(bytes))
        decoded = argument.fromString(encoded)
        self.assertThat(decoded, Equals(self.example))
Beispiel #8
0
 def test_handles_driver_resolving_to_DiscoveredPod(self):
     fake_driver = MagicMock()
     fake_driver.name = factory.make_name("pod")
     discovered_pod = DiscoveredPod(
         architectures=['amd64/generic'],
         cores=random.randint(1, 8),
         cpu_speed=random.randint(1000, 3000),
         memory=random.randint(1024, 8192),
         local_storage=0,
         hints=DiscoveredPodHints(cores=random.randint(1, 8),
                                  cpu_speed=random.randint(1000, 2000),
                                  memory=random.randint(1024, 8192),
                                  local_storage=0),
         machines=[])
     fake_driver.discover.return_value = succeed(discovered_pod)
     self.patch(PodDriverRegistry, "get_item").return_value = fake_driver
     result = yield pods.discover_pod(fake_driver.name, {})
     self.assertEquals({
         "pod": discovered_pod,
     }, result)
Beispiel #9
0
 def test_pod_fromdict(self):
     hostname = factory.make_name("hostname")
     cores = random.randint(1, 8)
     cpu_speed = random.randint(1000, 2000)
     memory = random.randint(4096, 8192)
     local_storage = random.randint(4096, 8192)
     iscsi_storage = random.randint(4096, 8192)
     hints = dict(
         cores=random.randint(1, 8),
         cpu_speed=random.randint(1000, 2000),
         memory=random.randint(4096, 8192),
         local_storage=random.randint(4096, 8192),
         iscsi_storage=random.randint(4096, 8192),
     )
     machines_data = []
     for _ in range(3):
         cores = random.randint(1, 8)
         cpu_speed = random.randint(1000, 2000)
         memory = random.randint(4096, 8192)
         interfaces = [
             dict(mac_address=factory.make_mac_address()) for _ in range(3)
         ]
         block_devices = [
             dict(
                 model=factory.make_name("model"),
                 serial=factory.make_name("serial"),
                 size=random.randint(512, 1024),
             ) for _ in range(3)
         ]
         for _ in range(3):
             block_devices.append(
                 dict(
                     model=None,
                     serial=None,
                     size=random.randint(512, 1024),
                     type=BlockDeviceType.ISCSI,
                     iscsi_target=self.make_iscsi_target(),
                 ))
         machines_data.append(
             dict(
                 hostname=hostname,
                 architecture="amd64/generic",
                 cores=cores,
                 cpu_speed=cpu_speed,
                 memory=memory,
                 interfaces=interfaces,
                 block_devices=block_devices,
             ))
     pod_data = dict(
         architectures=["amd64/generic"],
         cores=cores,
         cpu_speed=cpu_speed,
         memory=memory,
         local_storage=local_storage,
         iscsi_storage=iscsi_storage,
         hints=hints,
         machines=machines_data,
     )
     pod = DiscoveredPod.fromdict(pod_data)
     self.assertThat(pod, IsInstance(DiscoveredPod))
     self.assertThat(
         pod,
         MatchesStructure(
             architectures=Equals(["amd64/generic"]),
             cores=Equals(cores),
             cpu_speed=Equals(cpu_speed),
             memory=Equals(memory),
             local_storage=Equals(local_storage),
             iscsi_storage=Equals(iscsi_storage),
             hints=MatchesAll(
                 IsInstance(DiscoveredPodHints),
                 MatchesStructure(
                     cores=Equals(hints["cores"]),
                     cpu_speed=Equals(hints["cpu_speed"]),
                     memory=Equals(hints["memory"]),
                     local_storage=Equals(hints["local_storage"]),
                     iscsi_storage=Equals(hints["iscsi_storage"]),
                 ),
             ),
             machines=MatchesListwise([
                 MatchesAll(
                     IsInstance(DiscoveredMachine),
                     MatchesStructure(
                         architecture=Equals("amd64/generic"),
                         cores=Equals(machine["cores"]),
                         cpu_speed=Equals(machine["cpu_speed"]),
                         memory=Equals(machine["memory"]),
                         interfaces=MatchesListwise([
                             MatchesAll(
                                 IsInstance(DiscoveredMachineInterface),
                                 MatchesStructure(
                                     mac_address=Equals(
                                         interface["mac_address"]),
                                     vid=Equals(-1),
                                     tags=Equals([]),
                                 ),
                             ) for interface in machine["interfaces"]
                         ]),
                         block_devices=MatchesListwise([
                             MatchesAll(
                                 IsInstance(DiscoveredMachineBlockDevice),
                                 MatchesStructure(
                                     model=Equals(block_device["model"]),
                                     serial=Equals(block_device["serial"]),
                                     size=Equals(block_device["size"]),
                                     block_size=Equals(512),
                                     tags=Equals([]),
                                     type=Equals(BlockDeviceType.PHYSICAL),
                                 ),
                             ) for block_device in machine["block_devices"]
                             if "type" not in block_device
                         ] + [
                             MatchesAll(
                                 IsInstance(DiscoveredMachineBlockDevice),
                                 MatchesStructure(
                                     model=Is(None),
                                     serial=Is(None),
                                     size=Equals(block_device["size"]),
                                     block_size=Equals(512),
                                     tags=Equals([]),
                                     type=Equals(BlockDeviceType.ISCSI),
                                     iscsi_target=Equals(
                                         block_device["iscsi_target"]),
                                 ),
                             ) for block_device in machine["block_devices"]
                             if "type" in block_device
                         ]),
                     ),
                 ) for machine in machines_data
             ]),
         ),
     )
Beispiel #10
0
 def test_pod_asdict(self):
     hostname = factory.make_name("hostname")
     cores = random.randint(1, 8)
     cpu_speed = random.randint(1000, 2000)
     memory = random.randint(4096, 8192)
     local_storage = random.randint(4096, 8192)
     local_disks = random.randint(1, 8)
     iscsi_storage = random.randint(4096, 8192)
     hints = DiscoveredPodHints(
         cores=random.randint(1, 8),
         cpu_speed=random.randint(1000, 2000),
         memory=random.randint(4096, 8192),
         local_storage=random.randint(4096, 8192),
         local_disks=random.randint(1, 8),
         iscsi_storage=random.randint(4096, 8192),
     )
     machines = []
     tags = [factory.make_name("tag") for _ in range(3)]
     storage_pools = [
         DiscoveredPodStoragePool(
             id=factory.make_name("id"),
             name=factory.make_name("name"),
             storage=random.randint(4096, 8192),
             type="dir",
             path="/var/%s" % factory.make_name("dir"),
         ) for _ in range(3)
     ]
     for _ in range(3):
         cores = random.randint(1, 8)
         cpu_speed = random.randint(1000, 2000)
         memory = random.randint(4096, 8192)
         power_state = factory.make_name("unknown")
         power_parameters = {"power_id": factory.make_name("power_id")}
         interfaces = [
             DiscoveredMachineInterface(
                 mac_address=factory.make_mac_address()) for _ in range(3)
         ]
         block_devices = [
             DiscoveredMachineBlockDevice(
                 model=factory.make_name("model"),
                 serial=factory.make_name("serial"),
                 size=random.randint(512, 1024),
                 id_path=factory.make_name("/dev/vda"),
             ) for _ in range(3)
         ]
         for _ in range(3):
             block_devices.append(
                 DiscoveredMachineBlockDevice(
                     model=None,
                     serial=None,
                     size=random.randint(512, 1024),
                     type=BlockDeviceType.ISCSI,
                     iscsi_target=self.make_iscsi_target(),
                     storage_pool=factory.make_name("pool"),
                 ))
         tags = [factory.make_name("tag") for _ in range(3)]
         machines.append(
             DiscoveredMachine(
                 hostname=hostname,
                 architecture="amd64/generic",
                 cores=cores,
                 cpu_speed=cpu_speed,
                 memory=memory,
                 power_state=power_state,
                 power_parameters=power_parameters,
                 interfaces=interfaces,
                 block_devices=block_devices,
                 tags=tags,
             ))
     pod = DiscoveredPod(
         architectures=["amd64/generic"],
         cores=cores,
         cpu_speed=cpu_speed,
         memory=memory,
         local_storage=local_storage,
         local_disks=local_disks,
         iscsi_storage=iscsi_storage,
         hints=hints,
         machines=machines,
         tags=tags,
         storage_pools=storage_pools,
     )
     self.assertThat(
         pod.asdict(),
         MatchesDict({
             "architectures":
             Equals(["amd64/generic"]),
             "name":
             Equals(None),
             "cores":
             Equals(cores),
             "cpu_speed":
             Equals(cpu_speed),
             "memory":
             Equals(memory),
             "local_storage":
             Equals(local_storage),
             "local_disks":
             Equals(local_disks),
             "iscsi_storage":
             Equals(iscsi_storage),
             "mac_addresses":
             Equals([]),
             "capabilities":
             Equals(pod.capabilities),
             "hints":
             MatchesDict({
                 "cores": Equals(hints.cores),
                 "cpu_speed": Equals(hints.cpu_speed),
                 "memory": Equals(hints.memory),
                 "local_storage": Equals(hints.local_storage),
                 "local_disks": Equals(hints.local_disks),
                 "iscsi_storage": Equals(hints.iscsi_storage),
             }),
             "machines":
             MatchesListwise([
                 MatchesDict({
                     "hostname":
                     Equals(machine.hostname),
                     "architecture":
                     Equals("amd64/generic"),
                     "cores":
                     Equals(machine.cores),
                     "cpu_speed":
                     Equals(machine.cpu_speed),
                     "memory":
                     Equals(machine.memory),
                     "power_state":
                     Equals(machine.power_state),
                     "power_parameters":
                     Equals(machine.power_parameters),
                     "interfaces":
                     MatchesListwise([
                         MatchesDict({
                             "mac_address":
                             Equals(interface.mac_address),
                             "vid":
                             Equals(interface.vid),
                             "tags":
                             Equals(interface.tags),
                             "boot":
                             Equals(False),
                             "attach_type":
                             Is(None),
                             "attach_name":
                             Is(None),
                         }) for interface in machine.interfaces
                     ]),
                     "block_devices":
                     MatchesListwise([
                         MatchesDict({
                             "model":
                             Equals(block_device.model),
                             "serial":
                             Equals(block_device.serial),
                             "size":
                             Equals(block_device.size),
                             "block_size":
                             Equals(block_device.block_size),
                             "tags":
                             Equals(block_device.tags),
                             "id_path":
                             Equals(block_device.id_path),
                             "type":
                             Equals(block_device.type),
                             "iscsi_target":
                             Equals(block_device.iscsi_target),
                             "storage_pool":
                             Equals(block_device.storage_pool),
                         }) for block_device in machine.block_devices
                     ]),
                     "tags":
                     Equals(machine.tags),
                 }) for machine in machines
             ]),
             "tags":
             Equals(tags),
             "storage_pools":
             MatchesListwise([
                 MatchesDict({
                     "id": Equals(pool.id),
                     "name": Equals(pool.name),
                     "storage": Equals(pool.storage),
                     "type": Equals(pool.type),
                     "path": Equals(pool.path),
                 }) for pool in storage_pools
             ]),
         }),
     )
Beispiel #11
0
 def test_pod(self):
     hostname = factory.make_name("hostname")
     cores = random.randint(1, 8)
     cpu_speed = random.randint(1000, 2000)
     memory = random.randint(4096, 8192)
     local_storage = random.randint(4096, 8192)
     iscsi_storage = random.randint(4096, 8192)
     hints = DiscoveredPodHints(
         cores=random.randint(1, 8),
         cpu_speed=random.randint(1000, 2000),
         memory=random.randint(4096, 8192),
         local_storage=random.randint(4096, 8192),
         iscsi_storage=random.randint(4096, 8192),
     )
     machines = []
     for _ in range(3):
         cores = random.randint(1, 8)
         cpu_speed = random.randint(1000, 2000)
         memory = random.randint(4096, 8192)
         power_state = factory.make_name("unknown")
         power_parameters = {"power_id": factory.make_name("power_id")}
         interfaces = [
             DiscoveredMachineInterface(
                 mac_address=factory.make_mac_address()) for _ in range(3)
         ]
         block_devices = [
             DiscoveredMachineBlockDevice(
                 model=factory.make_name("model"),
                 serial=factory.make_name("serial"),
                 size=random.randint(512, 1024),
             ) for _ in range(3)
         ]
         for _ in range(3):
             block_devices.append(
                 DiscoveredMachineBlockDevice(
                     model=None,
                     serial=None,
                     size=random.randint(512, 1024),
                     type=BlockDeviceType.ISCSI,
                     iscsi_target=self.make_iscsi_target(),
                 ))
         tags = [factory.make_name("tag") for _ in range(3)]
         machines.append(
             DiscoveredMachine(
                 hostname=hostname,
                 architecture="amd64/generic",
                 cores=cores,
                 cpu_speed=cpu_speed,
                 memory=memory,
                 power_state=power_state,
                 power_parameters=power_parameters,
                 interfaces=interfaces,
                 block_devices=block_devices,
                 tags=tags,
             ))
     pod = DiscoveredPod(
         architectures=["amd64/generic"],
         cores=cores,
         cpu_speed=cpu_speed,
         memory=memory,
         local_storage=local_storage,
         iscsi_storage=iscsi_storage,
         hints=hints,
         machines=machines,
     )
     self.assertEquals(cores, pod.cores)
     self.assertEquals(cpu_speed, pod.cpu_speed)
     self.assertEquals(memory, pod.memory)
     self.assertEquals(local_storage, pod.local_storage)
     self.assertEquals(iscsi_storage, pod.iscsi_storage)
     self.assertEquals(machines, pod.machines)
Beispiel #12
0
    def _discover(self, client: Client, pod_id: int, context: dict):
        self._check_required_extensions(client)

        if not client.trusted:
            # return empty information as the client is not authenticated and
            # gathering other info requires auth.
            return DiscoveredPod()

        self._ensure_project(client)

        environment = client.host_info["environment"]
        # After the region creates the Pod object it will sync LXD commissioning
        # data for all hardware information.
        discovered_pod = DiscoveredPod(
            # client.host_info["environment"]["architectures"] reports all the
            # architectures the host CPU supports, not the architectures LXD
            # supports. On x86_64 LXD reports [x86_64, i686] however LXD does
            # not currently support VMs on i686. The LXD API currently does not
            # have a way to query which architectures are usable for VMs. The
            # safest bet is to just use the kernel_architecture.
            architectures=[
                kernel_to_debian_architecture(
                    environment["kernel_architecture"])
            ],
            name=environment["server_name"],
            version=environment["server_version"],
            capabilities=[
                Capabilities.COMPOSABLE,
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.OVER_COMMIT,
                Capabilities.STORAGE_POOLS,
            ],
        )

        # Discover networks. "unknown" interfaces are considered too to match
        # ethernets in containers.
        networks_state = [
            net.state() for net in client.networks.all()
            if net.type in ("unknown", "physical")
        ]
        discovered_pod.mac_addresses = list(
            {state.hwaddr
             for state in networks_state if state.hwaddr})

        # Discover storage pools.
        storage_pools = client.storage_pools.all()
        if not storage_pools:
            raise LXDPodError(
                "No storage pools exists.  Please create a storage pool in LXD."
            )
        pools = []
        local_storage = 0
        for storage_pool in storage_pools:
            discovered_storage_pool = self._get_discovered_pod_storage_pool(
                storage_pool)
            local_storage += discovered_storage_pool.storage
            pools.append(discovered_storage_pool)
        discovered_pod.storage_pools = pools
        discovered_pod.local_storage = local_storage

        # Discover VMs.
        host_cpu_speed = lxd_cpu_speed(client.resources)
        projects = [project.name for project in client.projects.all()]
        machines = []
        for project in projects:
            with self._get_client(pod_id, context,
                                  project=project) as project_cli:
                for virtual_machine in project_cli.virtual_machines.all():
                    discovered_machine = self._get_discovered_machine(
                        project_cli,
                        virtual_machine,
                        storage_pools=discovered_pod.storage_pools,
                    )
                    discovered_machine.cpu_speed = host_cpu_speed
                    machines.append(discovered_machine)
        discovered_pod.machines = machines

        return discovered_pod
Beispiel #13
0
    def fromString(self, inString):
        # Circular imports.
        from provisioningserver.drivers.pod import DiscoveredPod

        data = super(AmpDiscoveredPod, self).fromString(inString)
        return DiscoveredPod.fromdict(data)
Beispiel #14
0
    async def discover(self, pod_id, context):
        """Discover all Pod host resources."""
        # Connect to the Pod and make sure it is valid.
        client = await self.get_client(pod_id, context)
        if not client.has_api_extension("virtual-machines"):
            raise LXDPodError(
                "Please upgrade your LXD host to 3.19+ for virtual machine support."
            )
        resources = await deferToThread(lambda: client.resources)

        mac_addresses = []
        for card in resources["network"]["cards"]:
            for port in card["ports"]:
                mac_addresses.append(port["address"])

        # After the region creates the Pod object it will sync LXD commissioning
        # data for all hardware information.
        discovered_pod = DiscoveredPod(
            # client.host_info["environment"]["architectures"] reports all the
            # architectures the host CPU supports, not the architectures LXD
            # supports. On x86_64 LXD reports [x86_64, i686] however LXD does
            # not currently support VMs on i686. The LXD API currently does not
            # have a way to query which architectures are usable for VMs. The
            # safest bet is to just use the kernel_architecture.
            architectures=[
                kernel_to_debian_architecture(
                    client.host_info["environment"]["kernel_architecture"])
            ],
            name=client.host_info["environment"]["server_name"],
            mac_addresses=mac_addresses,
            capabilities=[
                Capabilities.COMPOSABLE,
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.OVER_COMMIT,
                Capabilities.STORAGE_POOLS,
            ],
        )

        # Check that we have at least one storage pool.
        # If not, user should be warned that they need to create one.
        storage_pools = await deferToThread(client.storage_pools.all)
        if not storage_pools:
            raise LXDPodError(
                "No storage pools exists.  Please create a storage pool in LXD."
            )

        # Discover Storage Pools.
        pools = []
        storage_pools = await deferToThread(client.storage_pools.all)
        local_storage = 0
        for storage_pool in storage_pools:
            discovered_storage_pool = self.get_discovered_pod_storage_pool(
                storage_pool)
            local_storage += discovered_storage_pool.storage
            pools.append(discovered_storage_pool)
        discovered_pod.storage_pools = pools
        discovered_pod.local_storage = local_storage

        # Discover VMs.
        machines = []
        virtual_machines = await deferToThread(client.virtual_machines.all)
        for virtual_machine in virtual_machines:
            discovered_machine = await self.get_discovered_machine(
                client,
                virtual_machine,
                storage_pools=discovered_pod.storage_pools,
            )
            discovered_machine.cpu_speed = lxd_cpu_speed(resources)
            machines.append(discovered_machine)
        discovered_pod.machines = machines

        # Return the DiscoveredPod.
        return discovered_pod
Beispiel #15
0
    def discover(self, pod_id: int, context: dict):
        """Discover all Pod host resources."""
        # Connect to the Pod and make sure it is valid.
        client = self._get_client(pod_id, context)
        if not client.has_api_extension("virtual-machines"):
            raise LXDPodError(
                "Please upgrade your LXD host to 3.19+ for virtual machine support."
            )

        self._ensure_project(client)

        # get MACs for host interfaces. "unknown" interfaces are considered too
        # to match ethernets in containers
        networks_state = [
            net.state() for net in client.networks.all()
            if net.type in ("unknown", "physical")
        ]
        mac_addresses = list(
            {state.hwaddr
             for state in networks_state if state.hwaddr})

        environment = client.host_info["environment"]
        # After the region creates the Pod object it will sync LXD commissioning
        # data for all hardware information.
        discovered_pod = DiscoveredPod(
            # client.host_info["environment"]["architectures"] reports all the
            # architectures the host CPU supports, not the architectures LXD
            # supports. On x86_64 LXD reports [x86_64, i686] however LXD does
            # not currently support VMs on i686. The LXD API currently does not
            # have a way to query which architectures are usable for VMs. The
            # safest bet is to just use the kernel_architecture.
            architectures=[
                kernel_to_debian_architecture(
                    environment["kernel_architecture"])
            ],
            name=environment["server_name"],
            version=environment["server_version"],
            mac_addresses=mac_addresses,
            capabilities=[
                Capabilities.COMPOSABLE,
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.OVER_COMMIT,
                Capabilities.STORAGE_POOLS,
            ],
        )

        # Check that we have at least one storage pool.
        # If not, user should be warned that they need to create one.
        storage_pools = client.storage_pools.all()
        if not storage_pools:
            raise LXDPodError(
                "No storage pools exists.  Please create a storage pool in LXD."
            )

        # Discover Storage Pools.
        pools = []
        local_storage = 0
        for storage_pool in storage_pools:
            discovered_storage_pool = self._get_discovered_pod_storage_pool(
                storage_pool)
            local_storage += discovered_storage_pool.storage
            pools.append(discovered_storage_pool)
        discovered_pod.storage_pools = pools
        discovered_pod.local_storage = local_storage

        host_cpu_speed = lxd_cpu_speed(client.resources)

        # Discover VMs.
        projects = [project.name for project in client.projects.all()]
        machines = []
        for project in projects:
            project_cli = self._get_client(pod_id, context, project=project)
            for virtual_machine in project_cli.virtual_machines.all():
                discovered_machine = self._get_discovered_machine(
                    project_cli,
                    virtual_machine,
                    storage_pools=discovered_pod.storage_pools,
                )
                discovered_machine.cpu_speed = host_cpu_speed
                machines.append(discovered_machine)
        discovered_pod.machines = machines

        # Return the DiscoveredPod.
        return discovered_pod