def test_machine(self): hostname = factory.make_name("hostname") cores = random.randint(1, 8) cpu_speed = random.randint(1000, 2000) memory = random.randint(4096, 8192) interfaces = [RequestedMachineInterface() for _ in range(3)] block_devices = [ RequestedMachineBlockDevice( size=random.randint(512, 1024), tags=[factory.make_name("tag") for _ in range(3)], ) for _ in range(3) ] machine = RequestedMachine( hostname=hostname, architecture="amd64/generic", cores=cores, cpu_speed=cpu_speed, memory=memory, interfaces=interfaces, block_devices=block_devices, ) self.assertEquals(hostname, machine.hostname) self.assertEquals(cores, machine.cores) self.assertEquals(cpu_speed, machine.cpu_speed) self.assertEquals(memory, machine.memory) self.assertEquals(interfaces, machine.interfaces) self.assertEquals(block_devices, machine.block_devices)
def get_requested_machine(self): """Return the `RequestedMachine`.""" block_devices = [] storage_constraints = get_storage_constraints_from_string( self.get_value_for('storage')) for _, size, tags in storage_constraints: if tags is None: tags = [] block_devices.append( RequestedMachineBlockDevice(size=size, tags=tags)) interfaces_label_map = self.get_value_for('interfaces') if interfaces_label_map is not None: requested_machine_interfaces = ( self._get_requested_machine_interfaces_via_constraints( interfaces_label_map)) else: requested_machine_interfaces = [RequestedMachineInterface()] return RequestedMachine( hostname=self.get_value_for('hostname'), architecture=self.get_value_for('architecture'), cores=self.get_value_for('cores'), memory=self.get_value_for('memory'), cpu_speed=self.get_value_for('cpu_speed'), block_devices=block_devices, interfaces=requested_machine_interfaces)
def get_requested_machine_interface_by_interface(self, interface): if interface.type == INTERFACE_TYPE.BRIDGE: rmi = RequestedMachineInterface( attach_name=interface.name, attach_type=InterfaceAttachType.BRIDGE) else: attach_options = self.pod.default_macvlan_mode if not attach_options: # Default macvlan mode is 'bridge' if not specified, since that # provides the best chance for connectivity. attach_options = MACVLAN_MODE.BRIDGE rmi = RequestedMachineInterface( attach_name=interface.name, attach_type=InterfaceAttachType.MACVLAN, attach_options=attach_options) return rmi
def get_requested_machine(self, known_host_interfaces): """Return the `RequestedMachine`.""" block_devices = [] storage_constraints = get_storage_constraints_from_string( self.get_value_for("storage")) for _, size, tags in storage_constraints: if tags is None: tags = [] block_devices.append( RequestedMachineBlockDevice(size=size, tags=tags)) interfaces_label_map = self.get_value_for("interfaces") if interfaces_label_map is not None: requested_machine_interfaces = self._get_requested_machine_interfaces_via_constraints( interfaces_label_map) else: requested_machine_interfaces = [RequestedMachineInterface()] return RequestedMachine( hostname=self.get_value_for("hostname"), architecture=self.get_value_for("architecture"), cores=self.get_value_for("cores"), memory=self.get_value_for("memory"), cpu_speed=self.get_value_for("cpu_speed"), block_devices=block_devices, interfaces=requested_machine_interfaces, known_host_interfaces=known_host_interfaces, )
def get_requested_machine(self, known_host_interfaces): """Return the `RequestedMachine`.""" block_devices = [] storage_constraints = get_storage_constraints_from_string( self.get_value_for("storage")) # LXD Pods currently only support one block device. if self.pod.power_type == "lxd" and len(storage_constraints) > 1: raise PodProblem( "LXD Pod virtual machines currently only support one block device." ) for _, size, tags in storage_constraints: if tags is None: tags = [] block_devices.append( RequestedMachineBlockDevice(size=size, tags=tags)) interfaces_label_map = self.get_value_for("interfaces") if interfaces_label_map is not None: requested_machine_interfaces = self._get_requested_machine_interfaces_via_constraints( interfaces_label_map) else: requested_machine_interfaces = [RequestedMachineInterface()] return RequestedMachine( hostname=self.get_value_for("hostname"), architecture=self.get_value_for("architecture"), cores=self.get_value_for("cores"), memory=self.get_value_for("memory"), cpu_speed=self.get_value_for("cpu_speed"), block_devices=block_devices, interfaces=requested_machine_interfaces, known_host_interfaces=known_host_interfaces, )
def make_requested_machine(self): return RequestedMachine( hostname=factory.make_name('hostname'), architecture='amd64/generic', cores=random.randint(1, 8), cpu_speed=random.randint(1000, 3000), memory=random.randint(1024, 8192), block_devices=[ RequestedMachineBlockDevice(size=random.randint(8, 16)) ], interfaces=[RequestedMachineInterface()])
def get_requested_machine_interface_by_interface(self, interface, known_host_interfaces): [host_interface] = [ known_interface for known_interface in known_host_interfaces if interface.name == known_interface.ifname ] rmi = RequestedMachineInterface( attach_name=host_interface.attach_name, attach_type=host_interface.attach_type, attach_vlan=host_interface.attach_vlan, ) if rmi.attach_type == InterfaceAttachType.MACVLAN: attach_options = self.pod.default_macvlan_mode if not attach_options: # Default macvlan mode is 'bridge' if not specified, since that # provides the best chance for connectivity. attach_options = MACVLAN_MODE.BRIDGE rmi.attach_options = attach_options return rmi
def test_machine_asdict(self): hostname = factory.make_name('hostname') cores = random.randint(1, 8) cpu_speed = random.randint(1000, 2000) memory = random.randint(4096, 8192) interfaces = [RequestedMachineInterface() for _ in range(3)] block_devices = [ RequestedMachineBlockDevice( size=random.randint(512, 1024), tags=[factory.make_name('tag') for _ in range(3)]) for _ in range(3) ] machine = RequestedMachine(hostname=hostname, architecture='amd64/generic', cores=cores, cpu_speed=cpu_speed, memory=memory, interfaces=interfaces, block_devices=block_devices) self.assertThat( machine.asdict(), MatchesDict({ "hostname": Equals(hostname), "architecture": Equals("amd64/generic"), "cores": Equals(cores), "cpu_speed": Equals(cpu_speed), "memory": Equals(memory), "interfaces": MatchesListwise([ MatchesDict({ "attach_name": Equals(interface.attach_name), "attach_type": Equals(interface.attach_type), "attach_options": Equals(interface.attach_options), }) for interface in interfaces ]), "block_devices": MatchesListwise([ MatchesDict({ "size": Equals(block_device.size), "tags": Equals(block_device.tags), }) for block_device in block_devices ]), }))
def make_requested_machine(): block_devices = [ RequestedMachineBlockDevice(size=random.randint(1024**3, 4 * 1024**3)) ] interfaces = [RequestedMachineInterface()] return RequestedMachine( hostname=factory.make_name("hostname"), architecture="amd64/generic", cores=random.randint(2, 4), memory=random.randint(1024, 4096), cpu_speed=random.randint(2000, 3000), block_devices=block_devices, interfaces=interfaces, )
def test_macvlan(self): interface = RequestedMachineInterface( ifname=factory.make_name("ifname"), attach_name=factory.make_name("bridge_name"), attach_type=InterfaceAttachType.MACVLAN, ) device = lxd_module.get_lxd_nic_device(interface) self.assertEqual( { "name": interface.ifname, "parent": interface.attach_name, "nictype": "macvlan", "type": "nic", }, device, )
def test_sriov(self): interface = RequestedMachineInterface( ifname=factory.make_name("ifname"), attach_name=factory.make_name("sriov"), attach_type=InterfaceAttachType.SRIOV, ) generated_mac_address = generate_mac_address() mock_generate_mac = self.patch(lxd_module, "generate_mac_address") mock_generate_mac.return_value = generated_mac_address device = lxd_module.get_lxd_nic_device(interface) self.assertEqual( { "name": interface.ifname, "hwaddr": generated_mac_address, "parent": interface.attach_name, "nictype": "sriov", "type": "nic", }, device, )
def get_requested_machine(self): """Return the `RequestedMachine`.""" # XXX blake_r 2017-04-04: Interfaces are hard coded at the # moment. Will be extended later. block_devices = [] constraints = get_storage_constraints_from_string( self.get_value_for('storage')) for _, size, tags in constraints: if tags is None: tags = [] block_devices.append( RequestedMachineBlockDevice(size=size, tags=tags)) return RequestedMachine( hostname=self.get_value_for('hostname'), architecture=self.get_value_for('architecture'), cores=self.get_value_for('cores'), memory=self.get_value_for('memory'), cpu_speed=self.get_value_for('cpu_speed'), block_devices=block_devices, interfaces=[RequestedMachineInterface()])
class TestRequestedMachine(MAASTestCase): example = RequestedMachine( hostname=factory.make_name("hostname"), architecture="amd64/generic", cores=random.randint(1, 8), cpu_speed=random.randint(1000, 2000), memory=random.randint(1024, 8192), interfaces=[RequestedMachineInterface() for _ in range(3)], block_devices=[ RequestedMachineBlockDevice(size=random.randint(512, 1024)) for _ in range(3) ], ) def test_round_trip(self): argument = arguments.AmpRequestedMachine() encoded = argument.toString(self.example) self.assertThat(encoded, IsInstance(bytes)) decoded = argument.fromString(encoded) self.assertThat(decoded, Equals(self.example))
def test_machine_without_cpu_speed(self): hostname = factory.make_name('hostname') cores = random.randint(1, 8) memory = random.randint(4096, 8192) interfaces = [RequestedMachineInterface() for _ in range(3)] block_devices = [ RequestedMachineBlockDevice(size=random.randint(512, 1024)) for _ in range(3) ] machine = RequestedMachine(hostname=hostname, architecture='amd64/generic', cores=cores, cpu_speed=None, memory=memory, interfaces=interfaces, block_devices=block_devices) self.assertEquals(hostname, machine.hostname) self.assertEquals(cores, machine.cores) self.assertIsNone(machine.cpu_speed) self.assertEquals(memory, machine.memory) self.assertEquals(interfaces, machine.interfaces) self.assertEquals(block_devices, machine.block_devices)
def test_machine_asdict(self): hostname = factory.make_name("hostname") cores = random.randint(1, 8) cpu_speed = random.randint(1000, 2000) memory = random.randint(4096, 8192) interfaces = [RequestedMachineInterface() for _ in range(3)] known_host_interfaces = [KnownHostInterface() for _ in range(3)] block_devices = [ RequestedMachineBlockDevice( size=random.randint(512, 1024), tags=[factory.make_name("tag") for _ in range(3)], ) for _ in range(3) ] machine = RequestedMachine( hostname=hostname, architecture="amd64/generic", cores=cores, cpu_speed=cpu_speed, memory=memory, interfaces=interfaces, known_host_interfaces=known_host_interfaces, block_devices=block_devices, ) self.assertThat( machine.asdict(), MatchesDict({ "hostname": Equals(hostname), "architecture": Equals("amd64/generic"), "cores": Equals(cores), "cpu_speed": Equals(cpu_speed), "memory": Equals(memory), "interfaces": MatchesListwise([ MatchesDict({ "ifname": Is(None), "requested_ips": Equals([]), "ip_mode": Is(None), "attach_name": Equals(interface.attach_name), "attach_type": Equals(interface.attach_type), "attach_options": Equals(interface.attach_options), }) for interface in interfaces ]), "known_host_interfaces": MatchesListwise([ MatchesDict({ "ifname": Equals(known_host_interface.ifname), "attach_type": Equals(known_host_interface.attach_type), "dhcp_enabled": Equals(False), }) for known_host_interface in known_host_interfaces ]), "block_devices": MatchesListwise([ MatchesDict({ "size": Equals(block_device.size), "tags": Equals(block_device.tags), }) for block_device in block_devices ]), }), )
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), ), ), )