def test_returns_boot_images_matching_subarches_in_boot_resources(self): rack = factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) params = self.make_boot_images() param = params.pop() subarches = [factory.make_name("subarch") for _ in range(3)] resource_name = "%s/%s" % (param["osystem"], param["release"]) resource_arch = "%s/%s" % ( param["architecture"], param["subarchitecture"], ) resource = factory.make_BootResource( rtype=BOOT_RESOURCE_TYPE.SYNCED, name=resource_name, architecture=resource_arch, ) extra = resource.extra.copy() extra["subarches"] = ",".join(subarches) resource.extra = extra resource.save() subarch = subarches.pop() self.assertItemsEqual( self.make_rpc_boot_images(param), get_boot_images_for( rack, param["osystem"], param["architecture"], subarch, param["release"], ), )
def test_compose_preseed_with_osystem_compose_preseed(self): os_name = factory.make_name("os") osystem = make_osystem(self, os_name, [BOOT_IMAGE_PURPOSE.XINSTALL]) compose_preseed_orig = osystem.compose_preseed compose_preseed_mock = self.patch(osystem, "compose_preseed") compose_preseed_mock.side_effect = compose_preseed_orig rack_controller = factory.make_RackController(url="") node = factory.make_Node(interface=True, osystem=os_name, status=NODE_STATUS.READY) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) token = NodeKey.objects.get_token_for_node(node) request = make_HttpRequest() expected_url = request.build_absolute_uri(reverse("curtin-metadata")) compose_preseed(request, PRESEED_TYPE.CURTIN, node) self.assertThat( compose_preseed_mock, MockCalledOnceWith( PRESEED_TYPE.CURTIN, (node.system_id, node.hostname), (token.consumer.key, token.key, token.secret), expected_url, ), )
def test_compose_preseed_with_curtin_installer(self): rack_controller = factory.make_RackController(url="") node = factory.make_Node(interface=True, status=NODE_STATUS.DEPLOYING) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) request = make_HttpRequest() expected_apt_proxy = get_apt_proxy(request, node.get_boot_rack_controller()) preseed = yaml.safe_load( compose_preseed(request, PRESEED_TYPE.CURTIN, node)) self.assertIn("datasource", preseed) self.assertIn("MAAS", preseed["datasource"]) self.assertThat( preseed["datasource"]["MAAS"], KeysEqual("metadata_url", "consumer_key", "token_key", "token_secret"), ) self.assertDictEqual( { "delay": "now", "mode": "reboot", "timeout": 1800, "condition": "test ! -e /tmp/block-reboot", }, preseed["power_state"], ) self.assertEqual( request.build_absolute_uri(reverse("curtin-metadata")), preseed["datasource"]["MAAS"]["metadata_url"], ) self.assertAptConfig(preseed, expected_apt_proxy)
def test_compose_preseed_with_osystem_compose_preseed(self): os_name = factory.make_name('os') osystem = make_osystem(self, os_name, [BOOT_IMAGE_PURPOSE.XINSTALL]) make_usable_osystem(self, os_name) compose_preseed_orig = osystem.compose_preseed compose_preseed_mock = self.patch(osystem, 'compose_preseed') compose_preseed_mock.side_effect = compose_preseed_orig rack_controller = factory.make_RackController(url='') node = factory.make_Node(interface=True, osystem=os_name, status=NODE_STATUS.READY) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) token = NodeKey.objects.get_token_for_node(node) region_ip = factory.make_ip_address() expected_url = absolute_reverse('curtin-metadata', default_region_ip=region_ip) compose_preseed(PRESEED_TYPE.CURTIN, node, default_region_ip=region_ip) self.assertThat( compose_preseed_mock, MockCalledOnceWith(PRESEED_TYPE.CURTIN, (node.system_id, node.hostname), (token.consumer.key, token.key, token.secret), expected_url))
def test_compose_preseed_with_curtin_installer(self): rack_controller = factory.make_RackController(url='') node = factory.make_Node(interface=True, status=NODE_STATUS.DEPLOYING) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) request = make_HttpRequest() expected_apt_proxy = get_apt_proxy(request, node.get_boot_rack_controller()) preseed = yaml.safe_load( compose_preseed(request, PRESEED_TYPE.CURTIN, node)) self.assertIn('datasource', preseed) self.assertIn('MAAS', preseed['datasource']) self.assertThat( preseed['datasource']['MAAS'], KeysEqual('metadata_url', 'consumer_key', 'token_key', 'token_secret')) self.assertDictEqual( { 'delay': 'now', 'mode': 'reboot', 'timeout': 1800, 'condition': 'test ! -e /tmp/block-reboot', }, preseed['power_state']) self.assertEqual( request.build_absolute_uri(reverse('curtin-metadata')), preseed['datasource']['MAAS']['metadata_url']) self.assertAptConfig(preseed, expected_apt_proxy)
def test_fixes_custom_osystem_release_titles(self): factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) releases = [factory.make_name("release") for _ in range(3)] os_releases = [{ "name": release, "title": release } for release in releases] for release in releases: factory.make_BootResource( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=release, architecture=make_usable_architecture(self), extra={"title": release.upper()}) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") example = { "osystems": [{ "name": "custom", "releases": os_releases }] } callRemote.return_value = succeed(example) releases_with_titles = [{ "name": release, "title": release.upper() } for release in releases] self.assertItemsEqual([{ "name": "custom", "releases": releases_with_titles }], gen_all_known_operating_systems())
def test_compose_preseed_for_curtin_and_trusty_aptsources(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() rack_controller = factory.make_RackController() node = factory.make_Node( interface=True, status=NODE_STATUS.READY, osystem="ubuntu", distro_series="trusty", ) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) request = make_HttpRequest() apt_proxy = get_apt_proxy(request, node.get_boot_rack_controller()) preseed = yaml.safe_load( compose_preseed(request, PRESEED_TYPE.CURTIN, node)) self.assertIn("apt_sources", preseed) self.assertEqual(apt_proxy, preseed["apt_proxy"]) self.assertSystemInfo(preseed)
def test_returns_True_with_one_cluster(self): # The Windows driver is known accept a license key in the format of # 00000-00000-00000-00000-00000. factory.make_RackController() key = "00000-00000-00000-00000-00000" self.useFixture(RunningClusterRPCFixture()) is_valid = validate_license_key("windows", "win2012", key) self.assertTrue(is_valid)
def test_yields_oses_known_to_a_cluster(self): # The operating systems known to a single node are returned. factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) osystems = gen_all_known_operating_systems() self.assertIsInstance(osystems, Iterator) osystems = list(osystems) self.assertThat(osystems, Not(HasLength(0))) self.assertThat(osystems, AllMatch(IsInstance(dict)))
def test_yields_oses_known_to_multiple_clusters(self): factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) osystems = gen_all_known_operating_systems() self.assertIsInstance(osystems, Iterator) osystems = list(osystems) self.assertThat(osystems, Not(HasLength(0))) self.assertThat(osystems, AllMatch(IsInstance(dict)))
def test_returns_boot_images_matching_subarchitecture(self): rack = factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) params = self.make_boot_images() param = params.pop() self.assertItemsEqual( self.make_rpc_boot_images(param), get_boot_images_for(rack, param['osystem'], param['architecture'], param['subarchitecture'], param['release']))
def test_returns_None_if_title_is_blank(self): factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") example = {"title": ""} callRemote.return_value = succeed(example) self.assertIsNone(get_os_release_title("bogus-os", "bogus-release"))
def test_returns_False_when_all_clusters_return_False(self): factory.make_RackController() factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") callRemote.return_value = succeed({"running": False}) self.assertFalse(is_import_boot_images_running())
def test_returns_empty_list_when_all_clusters_fail(self): factory.make_RackController() factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") callRemote.side_effect = ZeroDivisionError() self.assertItemsEqual([], self.get())
def test_returns_boot_images_for_one_cluster(self): factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) purposes = ['install', 'commissioning', 'xinstall'] params = [make_boot_image_storage_params() for _ in range(3)] for param in params: make_image_dir(param, self.tftp_root) test_tftppath.make_osystem(self, param['osystem'], purposes) self.assertItemsEqual([ make_image(param, purpose) for param in params for purpose in purposes ], self.get())
def test_returns_False_when_all_clusters_fail(self): factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): # All clients raise an exception. callRemote = self.patch(client._conn, "callRemote") callRemote.side_effect = ZeroDivisionError() is_valid = validate_license_key("windows", "win2012", factory.make_name("key")) self.assertFalse(is_valid)
def test_propagates_NoSuchOperatingSystem(self): rack = factory.make_RackController() node = factory.make_Node(interface=True, osystem=factory.make_name("foo")) boot_interface = node.get_boot_interface() boot_interface.vlan.dhcp_on = True boot_interface.vlan.primary_rack = rack boot_interface.vlan.save() self.useFixture(RunningClusterRPCFixture()) self.assertRaises(NoSuchOperatingSystem, get_preseed_data, PRESEED_TYPE.CURTIN, node, token=NodeKey.objects.get_token_for_node(node), metadata_url=factory.make_url())
def test_only_yields_os_once(self): # Duplicate OSes that exactly match are suppressed. Typically # every cluster will have several (or all) OSes in common. factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) counter = Counter(osystem["name"] for osystem in gen_all_known_operating_systems()) def get_count(item): name, count = item return count self.assertThat(counter.items(), AllMatch(AfterPreprocessing(get_count, Equals(1))))
def test_propagates_NotImplementedError(self): # The Windows driver is known to *not* provide custom preseed # data when using Curtin. rack = factory.make_RackController() node = factory.make_Node(interface=True, osystem="windows") boot_interface = node.get_boot_interface() boot_interface.vlan.dhcp_on = True boot_interface.vlan.primary_rack = rack boot_interface.vlan.save() self.useFixture(RunningClusterRPCFixture()) self.assertRaises(NotImplementedError, get_preseed_data, PRESEED_TYPE.CURTIN, node, token=NodeKey.objects.get_token_for_node(node), metadata_url=factory.make_url())
def test_compose_preseed_with_curtin_installer_skips_apt_proxy(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() rack_controller = factory.make_RackController() node = factory.make_Node(interface=True, status=NODE_STATUS.READY) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) Config.objects.set_config("enable_http_proxy", False) preseed = yaml.safe_load(compose_preseed(PRESEED_TYPE.CURTIN, node)) self.assertNotIn('apt_proxy', preseed)
def test_returns_boot_images(self): rack_controller = factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) purposes = ["install", "commissioning", "xinstall"] params = [make_boot_image_storage_params() for _ in range(3)] for param in params: make_image_dir(param, self.tftp_root) test_tftppath.make_osystem(self, param["osystem"], purposes) self.assertItemsEqual( [ make_image(param, purpose) for param in params for purpose in purposes ], get_boot_images(rack_controller), )
def test_os_data_is_passed_through_unmolested(self): factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) example = { "osystems": [{ "name": factory.make_name("name"), "foo": factory.make_name("foo"), "bar": factory.make_name("bar"), }] } for client in getAllClients(): callRemote = self.patch(client._conn, "callRemote") callRemote.return_value = succeed(example) self.assertItemsEqual(example["osystems"], gen_all_known_operating_systems())
def test_returns_True_when_one_cluster_returns_True(self): factory.make_RackController() factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") if index == 0: # The first client returns all False. callRemote.return_value = succeed({"running": False}) else: # All clients but the first return True. callRemote.return_value = succeed({"running": True}) self.assertTrue(is_import_boot_images_running())
def test_returns_preseed_data(self): # The Windows driver is known to provide custom preseed data. rack = factory.make_RackController() node = factory.make_Node(interface=True, osystem="windows") boot_interface = node.get_boot_interface() boot_interface.vlan.dhcp_on = True boot_interface.vlan.primary_rack = rack boot_interface.vlan.save() self.useFixture(RunningClusterRPCFixture()) preseed_data = get_preseed_data( PRESEED_TYPE.COMMISSIONING, node, token=NodeKey.objects.get_token_for_node(node), metadata_url=factory.make_url()) self.assertThat(preseed_data, IsInstance(dict)) self.assertNotIn("data", preseed_data) self.assertThat(preseed_data, Not(HasLength(0)))
def test_ignores_failures_when_talking_to_clusters(self): factory.make_RackController() factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") if index == 0: # The first client returns True. callRemote.return_value = succeed({"running": True}) else: # All clients but the first raise an exception. callRemote.side_effect = ZeroDivisionError() self.assertTrue(is_import_boot_images_running())
def test_compose_preseed_for_curtin_xenial_not_aptsources(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() rack_controller = factory.make_RackController() node = factory.make_Node(interface=True, status=NODE_STATUS.READY, osystem='ubuntu', distro_series='xenial') nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) preseed = yaml.safe_load(compose_preseed(PRESEED_TYPE.CURTIN, node)) self.assertNotIn('apt_sources', preseed)
def test_ignores_failures_when_talking_to_clusters(self): factory.make_RackController() factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) images = [make_rpc_boot_image() for _ in range(3)] clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") if index == 0: # The first client returns correct image information. callRemote.return_value = succeed({"images": images}) else: # All clients but the first raise an exception. callRemote.side_effect = ZeroDivisionError() self.assertItemsEqual(images, self.get())
def test_compose_preseed_propagates_NoSuchOperatingSystem(self): # If the cluster controller replies that the node's OS is not known to # it, compose_preseed() simply passes the exception up. os_name = factory.make_name('os') osystem = make_osystem(self, os_name, [BOOT_IMAGE_PURPOSE.XINSTALL]) compose_preseed_mock = self.patch(osystem, 'compose_preseed') compose_preseed_mock.side_effect = NoSuchOperatingSystem rack_controller = factory.make_RackController() node = factory.make_Node(interface=True, osystem=os_name, status=NODE_STATUS.READY) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) self.assertRaises(NoSuchOperatingSystem, compose_preseed, make_HttpRequest(), PRESEED_TYPE.CURTIN, node)
def test_returns_True_when_only_one_cluster_returns_True_others_fail(self): # The Windows driver is known accept a license key in the format of # 00000-00000-00000-00000-00000. factory.make_RackController() factory.make_RackController() self.useFixture(RunningClusterRPCFixture()) clients = getAllClients() for index, client in enumerate(clients): callRemote = self.patch(client._conn, "callRemote") if index == 0: # The first client returns True. callRemote.return_value = succeed({"is_valid": True}) else: # All clients but the first raise an exception. callRemote.side_effect = ZeroDivisionError() is_valid = validate_license_key("windows", "win2012", factory.make_name("key")) self.assertTrue(is_valid)
def test_compose_preseed_for_curtin_not_packages(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() rack_controller = factory.make_RackController() node = factory.make_Node( interface=True, status=NODE_STATUS.DEPLOYING, osystem="ubuntu", distro_series="xenial", ) nic = node.get_boot_interface() nic.vlan.dhcp_on = True nic.vlan.primary_rack = rack_controller nic.vlan.save() self.useFixture(RunningClusterRPCFixture()) request = make_HttpRequest() preseed = yaml.safe_load( compose_preseed(request, PRESEED_TYPE.CURTIN, node)) self.assertNotIn("packages", preseed)