def load_builtin_scripts(): for script in BUILTIN_SCRIPTS: if script.inject_file: with open(script.inject_path, "r") as f: script.substitutes["inject_file"] = f.read() script_content = tempita.Template.from_filename( script.script_path, encoding="utf-8" ) script_content = script_content.substitute( {"name": script.name, **script.substitutes} ) try: script_in_db = Script.objects.get(name=script.name) except Script.DoesNotExist: form = ScriptForm( data={ "script": script_content, "comment": "Created by maas-%s" % get_maas_version(), } ) # Form validation should never fail as these are the scripts which # ship with MAAS. If they ever do this will be cause by unit tests. if not form.is_valid(): raise Exception("%s: %s" % (script.name, form.errors)) script_in_db = form.save(commit=False) script_in_db.default = True script_in_db.save() else: if script_in_db.script.data != script_content: # Don't add back old versions of a script. This prevents two # connected regions with different versions of a script from # fighting with eachother. no_update = False for vtf in script_in_db.script.previous_versions(): if vtf.data == script_content: # Don't update anything if we detect we have an old # version of the builtin scripts no_update = True break if no_update: continue form = ScriptForm( instance=script_in_db, data={ "script": script_content, "comment": "Updated by maas-%s" % get_maas_version(), }, edit_default=True, ) # Form validation should never fail as these are the scripts # which ship with MAAS. If they ever do this will be cause by # unit tests. if not form.is_valid(): raise Exception("%s: %s" % (script.name, form.errors)) script_in_db = form.save(commit=False) script_in_db.default = True script_in_db.save()
def test_update_script(self): load_builtin_scripts() update_script_values = random.choice(BUILTIN_SCRIPTS) script = Script.objects.get(name=update_script_values.name) # Fields which we can update script.description = factory.make_string() script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES) script.destructive = not script.destructive # Put fake old data in to simulate updating a script. old_script = VersionedTextFile.objects.create( data=factory.make_string()) script.script = old_script # User changeable fields. user_tags = [factory.make_name('tag') for _ in range(3)] script.tags = copy.deepcopy(user_tags) user_timeout = timedelta(random.randint(0, 1000)) script.timeout = user_timeout script.save() load_builtin_scripts() script = reload_object(script) self.assertEquals(update_script_values.name, script.name) self.assertEquals(update_script_values.title, script.title) self.assertEquals(update_script_values.description, script.description) self.assertEquals("Updated by maas-%s" % get_maas_version(), script.script.comment) self.assertEquals(update_script_values.script_type, script.script_type) self.assertEquals(update_script_values.destructive, script.destructive) self.assertEquals(old_script, script.script.previous_version) if script.destructive: user_tags.append('destructive') self.assertEquals(user_tags, script.tags) self.assertEquals(user_timeout, script.timeout) self.assertTrue(script.default)
def register( self, system_id, hostname, interfaces, url, nodegroup_uuid=None, beacon_support=False, version=None, ): # Hold off on fabric creation if the remote controller # supports beacons; it will happen later when UpdateInterfaces is # called. create_fabrics = False if beacon_support else True result = yield self._register( system_id, hostname, interfaces, url, nodegroup_uuid=nodegroup_uuid, create_fabrics=create_fabrics, version=version, ) if beacon_support: # The remote supports beaconing, so acknowledge that. result["beacon_support"] = True if version: # The remote supports version checking, so reply to that. result["version"] = get_maas_version() return result
def get_sys_info(): """Return basic system information in a dictionary.""" os_release = get_os_release() if "ID" in os_release: osystem = os_release["ID"] elif "NAME" in os_release: osystem = os_release["NAME"] else: osystem = "" if "UBUNTU_CODENAME" in os_release: distro_series = os_release["UBUNTU_CODENAME"] elif "VERSION_ID" in os_release: distro_series = os_release["VERSION_ID"] else: distro_series = "" result = { "hostname": socket.gethostname().split(".")[0], "architecture": get_architecture(), "osystem": osystem, "distro_series": distro_series, "maas_version": get_maas_version(), # In MAAS 2.3+, the NetworksMonitoringService is solely responsible for # interface update, because interface updates need to include beaconing # data. The key and empty dictionary are necessary for backward # compatibility; the region will ignore the empty dictionary in # _process_sys_info(). "interfaces": {}, } return result
def get_sys_info(): """Return basic system information in a dictionary.""" os_release = get_os_release() if 'ID' in os_release: osystem = os_release['ID'] elif 'NAME' in os_release: osystem = os_release['NAME'] else: osystem = '' if 'UBUNTU_CODENAME' in os_release: distro_series = os_release['UBUNTU_CODENAME'] elif 'VERSION_ID' in os_release: distro_series = os_release['VERSION_ID'] else: distro_series = '' result = { 'hostname': socket.gethostname().split('.')[0], 'architecture': get_architecture(), 'osystem': osystem, 'distro_series': distro_series, 'maas_version': get_maas_version(), # In MAAS 2.3+, the NetworksMonitoringService is solely responsible for # interface update, because interface updates need to include beaconing # data. The key and empty dictionary are necessary for backward # compatibility; the region will ignore the empty dictionary in # _process_sys_info(). 'interfaces': {} } return result
def test__calls_get_version_from_apt(self): mock_apt = self.patch(version, "get_version_from_apt") mock_apt.return_value = sentinel.version self.expectThat(version.get_maas_version(), Is(sentinel.version)) self.expectThat( mock_apt, MockCalledOnceWith(version.RACK_PACKAGE_NAME, version.REGION_PACKAGE_NAME))
def notification_available(notification_version, maas_version=None): current_version = version.get_version_tuple(maas_version or version.get_maas_version()) log.debug(f"Current MAAS version: {repr(current_version)}") log.debug(f"Notification version: {notification_version}") notification_version_tuple = version.get_version_tuple( notification_version) return notification_version_tuple > current_version
def test_register_acks_version(self): yield self.installFakeRegion() rack_controller = yield deferToDatabase(factory.make_RackController) protocol = self.make_Region() protocol.transport = MagicMock() response = yield call_responder( protocol, RegisterRackController, { "system_id": rack_controller.system_id, "hostname": rack_controller.hostname, "interfaces": {}, "version": "2.3", }) self.assertThat(response['version'], Equals(get_maas_version()))
def load_builtin_scripts(): for script in BUILTIN_SCRIPTS: script_content = read_text_file(script.script_path) try: script_in_db = Script.objects.get(name=script.name) except Script.DoesNotExist: Script.objects.create(name=script.name, title=script.title, description=script.description, tags=script.tags, script_type=script.script_type, script=script_content, comment="Created by maas-%s" % get_maas_version(), timeout=script.timeout, destructive=script.destructive, default=True) else: if script_in_db.script.data != script_content: # Don't add back old versions of a script. This prevents two # connected regions with different versions of a script from # fighting with eachother. no_update = False for vtf in script_in_db.script.previous_versions(): if vtf.data == script_content: # Don't update anything if we detect we have an old # version of the builtin scripts no_update = True break if no_update: continue script_in_db.script = script_in_db.script.update( script_content, "Updated by maas-%s" % get_maas_version()) script_in_db.title = script.title script_in_db.description = script.description script_in_db.script_type = script.script_type script_in_db.destructive = script.destructive script_in_db.save()
def test_update_script(self): load_builtin_scripts() update_script_values = random.choice(BUILTIN_SCRIPTS) script = Script.objects.get(name=update_script_values.name) # Fields which we can update orig_title = script.title orig_description = script.description orig_script_type = script.script_type orig_results = script.results orig_parameters = script.parameters script.title = factory.make_string() script.description = factory.make_string() script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES) script.results = [factory.make_name("result")] script.script.parameters = { factory.make_name("param"): { "type": "storage" } } # Put fake old data in to simulate updating a script. old_script = VersionedTextFile.objects.create( data=factory.make_string()) script.script = old_script # User changeable fields. user_tags = [factory.make_name("tag") for _ in range(3)] script.tags = copy.deepcopy(user_tags) user_timeout = timedelta(random.randint(0, 1000)) script.timeout = user_timeout script.save() load_builtin_scripts() script = reload_object(script) self.assertEquals(orig_title, script.title, script.name) self.assertEquals(orig_description, script.description, script.name) self.assertEquals(orig_script_type, script.script_type, script.name) self.assertDictEqual(orig_results, script.results, script.name) self.assertDictEqual(orig_parameters, script.parameters, script.name) self.assertThat(script.tags, ContainsAll(user_tags)) self.assertEquals(user_timeout, script.timeout) self.assertEquals(old_script, script.script.previous_version) self.assertEquals("Updated by maas-%s" % get_maas_version(), script.script.comment) self.assertTrue(script.default)
def test_creates_scripts(self): load_builtin_scripts() for script in BUILTIN_SCRIPTS: script_in_db = Script.objects.get(name=script.name) self.assertEquals(script.title, script_in_db.title) self.assertEquals(script.description, script_in_db.description) self.assertEquals("Created by maas-%s" % get_maas_version(), script_in_db.script.comment) self.assertItemsEqual(script.tags, script_in_db.tags) self.assertEquals(script.script_type, script_in_db.script_type) self.assertEquals(script.timeout, script_in_db.timeout) self.assertEquals(script.destructive, script_in_db.destructive) self.assertTrue(script_in_db.default)
def test_get_sys_info_empty(self): hostname = factory.make_hostname() architecture = factory.make_name('architecture') self.patch(refresh.socket, 'gethostname').return_value = hostname self.patch_autospec(refresh, 'get_os_release').return_value = {} self.patch_autospec( refresh, 'get_architecture').return_value = architecture self.assertThat({ 'hostname': hostname, 'architecture': architecture, 'osystem': '', 'distro_series': '', 'maas_version': get_maas_version(), 'interfaces': {}, }, Equals(refresh.get_sys_info()))
def test_creates_scripts(self): load_builtin_scripts() for script in BUILTIN_SCRIPTS: script_in_db = Script.objects.get(name=script.name) # While MAAS allows user scripts to leave these fields blank, # builtin scripts should always have values. self.assertTrue(script_in_db.title, script.name) self.assertTrue(script_in_db.description, script.name) self.assertTrue(script_in_db.script.data, script.name) self.assertThat(script_in_db.tags, Not(Equals([])), script.name) # These values should always be set by the script loader. self.assertEquals("Created by maas-%s" % get_maas_version(), script_in_db.script.comment, script.name) self.assertTrue(script_in_db.default, script.name)
def test_get_sys_info_empty(self): hostname = factory.make_hostname() architecture = factory.make_name("architecture") self.patch(refresh.socket, "gethostname").return_value = hostname self.patch_autospec(refresh, "get_os_release").return_value = {} self.patch_autospec(refresh, "get_architecture").return_value = architecture self.assertThat( { "hostname": hostname, "architecture": architecture, "osystem": "", "distro_series": "", "maas_version": get_maas_version(), "interfaces": {}, }, Equals(refresh.get_sys_info()), )
def test_get_sys_info_alt(self): hostname = factory.make_hostname() osystem = factory.make_name('name') distro_series = factory.make_name('version_id') architecture = factory.make_name('architecture') self.patch(refresh.socket, 'gethostname').return_value = hostname self.patch_autospec(refresh, 'get_os_release').return_value = { 'NAME': osystem, 'VERSION_ID': distro_series, } self.patch_autospec( refresh, 'get_architecture').return_value = architecture self.assertThat({ 'hostname': hostname, 'architecture': architecture, 'osystem': osystem, 'distro_series': distro_series, 'maas_version': get_maas_version(), 'interfaces': {}, }, Equals(refresh.get_sys_info()))
def test_get_sys_info_alt(self): hostname = factory.make_hostname() osystem = factory.make_name("name") distro_series = factory.make_name("version_id") architecture = factory.make_name("architecture") self.patch(refresh.socket, "gethostname").return_value = hostname self.patch_autospec(refresh, "get_os_release").return_value = { "NAME": osystem, "VERSION_ID": distro_series, } self.patch_autospec(refresh, "get_architecture").return_value = architecture self.assertThat( { "hostname": hostname, "architecture": architecture, "osystem": osystem, "distro_series": distro_series, "maas_version": get_maas_version(), "interfaces": {}, }, Equals(refresh.get_sys_info()), )
def test__uses_snappy_get_snap_version(self): self.patch(snappy, 'running_in_snap').return_value = True self.patch(snappy, 'get_snap_version').return_value = sentinel.version self.assertEqual(sentinel.version, version.get_maas_version())
def test_update_doesnt_revert_script(self): load_builtin_scripts() update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2) update_script_values = BUILTIN_SCRIPTS[update_script_index] script = Script.objects.get(name=update_script_values.name) # Put fake new data in to simulate another MAAS region updating # to a newer version. new_script = factory.make_string() script.script = script.script.update(new_script) # Fake user updates user_tags = [factory.make_name("tag") for _ in range(3)] script.tags = user_tags user_timeout = timedelta(random.randint(0, 1000)) script.timeout = user_timeout script.save() # Test that subsequent scripts still get updated second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1] second_script = Script.objects.get( name=second_update_script_values.name) # Put fake old data in to simulate updating a script. orig_title = second_script.title orig_description = second_script.description orig_script_type = second_script.script_type orig_results = second_script.results orig_parameters = second_script.parameters second_script.title = factory.make_string() second_script.description = factory.make_string() second_script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES) second_script.results = [factory.make_name("result")] second_script.script.parameters = { factory.make_name("param"): { "type": "storage" } } # Put fake old data in to simulate updating a script. old_script = VersionedTextFile.objects.create( data=factory.make_string()) second_script.script = old_script second_script.save() load_builtin_scripts() script = reload_object(script) self.assertEquals(update_script_values.name, script.name) self.assertEquals(new_script, script.script.data) self.assertTrue(min([tag in script.tags for tag in user_tags])) self.assertEquals(user_timeout, script.timeout) self.assertTrue(script.default) second_script = reload_object(second_script) self.assertEquals(orig_title, second_script.title) self.assertEquals(orig_description, second_script.description) self.assertEquals(orig_script_type, second_script.script_type) self.assertDictEqual(orig_results, second_script.results) self.assertDictEqual(orig_parameters, second_script.parameters) self.assertEquals(old_script, second_script.script.previous_version) self.assertEquals( "Updated by maas-%s" % get_maas_version(), second_script.script.comment, ) self.assertTrue(second_script.default)