def render_enlistment_preseed(request, prefix, osystem="", release="", rack_controller=None): """Return the enlistment preseed. :param prefix: See `get_preseed_filenames`. :param osystem: See `get_preseed_filenames`. :param release: See `get_preseed_filenames`. :param rack_controller: The rack controller used to generate the preseed. :return: The rendered preseed string. :rtype: unicode. """ template = load_preseed_template(None, prefix, osystem, release) context = get_preseed_context(request, osystem, release, rack_controller=rack_controller) context["preseed_data"] = compose_enlistment_preseed( request, rack_controller, context) # Render the snippets in the main template. snippets = get_snippet_context() snippets.update(context) return template.substitute(**snippets).encode("utf-8")
def test_get_snippet_context(self): contents = factory.make_string() snippets_dir = self.make_dir() factory.make_file(snippets_dir, "snippet.py", contents=contents) snippets = get_snippet_context(snippets_dir=snippets_dir) self.assertItemsEqual(["base_user_data_sh", "snippet_py"], snippets.keys()) self.assertEqual(contents, snippets["snippet_py"])
def generate_user_data( node, userdata_template_file, extra_context=None, rack_controller=None, request=None, ): """Produce a user_data script for use by an ephemeral environment. The main template file contains references to so-called ``snippets'' which are read in here, and substituted. In addition, the regular preseed context variables are available (such as 'http_proxy'). The final result is a MIME multipart message that consists of a 'cloud-config' part and an 'x-shellscript' part. This allows maximum flexibility with cloud-init as we read in a template 'user_data_config.template' to set cloud-init configs before the script is run. :rtype: `bytes` """ # Enlisting machines will not have a node object or an assoicated # rack controller if the subnet is unknown to MAAS or MAAS does not # control DHCP on the VLAN(see find_rack_controller in maasserver.utils) if rack_controller is None and node is not None: rack_controller = node.get_boot_rack_controller() userdata_template = tempita.Template.from_filename(userdata_template_file, encoding=ENCODING) # The preseed context is a dict containing various configs that the # templates can use. if request is None: server_url = absolute_reverse("machines_handler") else: server_url = request.build_absolute_uri(reverse("machines_handler")) configs = Config.objects.get_configs(["maas_auto_ipmi_user"]) preseed_context = { "node": node, "server_url": server_url, "maas_ipmi_user": configs["maas_auto_ipmi_user"], } # Render the snippets in the main template. snippets = get_snippet_context(encoding=ENCODING) snippets.update(preseed_context) if extra_context is not None: snippets.update(extra_context) userdata = userdata_template.substitute(snippets).encode(ENCODING) data_part = MIMEText(userdata, "x-shellscript", ENCODING) data_part.add_header("Content-Disposition", 'attachment; filename="user_data.sh"') combined = MIMEMultipart() combined.attach(data_part) return combined.as_bytes()
def generate_user_data(node, userdata_template_file, extra_context=None): """Produce a user_data script for use by an ephemeral environment. The main template file contains references to so-called ``snippets'' which are read in here, and substituted. In addition, the regular preseed context variables are available (such as 'http_proxy'). The final result is a MIME multipart message that consists of a 'cloud-config' part and an 'x-shellscript' part. This allows maximum flexibility with cloud-init as we read in a template 'user_data_config.template' to set cloud-init configs before the script is run. :rtype: `bytes` """ # Avoid circular dependencies. from maasserver.preseed import get_preseed_context userdata_template = tempita.Template.from_filename( userdata_template_file, encoding=ENCODING) # The preseed context is a dict containing various configs that the # templates can use. preseed_context = get_preseed_context( rack_controller=node.get_boot_rack_controller()) preseed_context['node'] = node # Render the snippets in the main template. snippets = get_snippet_context(encoding=ENCODING) snippets.update(preseed_context) if extra_context is not None: snippets.update(extra_context) userdata = userdata_template.substitute(snippets).encode(ENCODING) data_part = MIMEText(userdata, 'x-shellscript', ENCODING) data_part.add_header( 'Content-Disposition', 'attachment; filename="user_data.sh"') combined = MIMEMultipart() combined.attach(data_part) return combined.as_bytes()
def render_enlistment_preseed(prefix, osystem='', release='', rack_controller=None, default_region_ip=None): """Return the enlistment preseed. :param prefix: See `get_preseed_filenames`. :param osystem: See `get_preseed_filenames`. :param release: See `get_preseed_filenames`. :param rack_controller: The rack controller used to generate the preseed. :return: The rendered preseed string. :rtype: unicode. """ template = load_preseed_template(None, prefix, osystem, release) context = get_preseed_context(osystem, release, rack_controller=rack_controller, default_region_ip=default_region_ip) # Render the snippets in the main template. snippets = get_snippet_context() snippets.update(context) return template.substitute(**snippets).encode("utf-8")
def test_get_snippet_always_contains_base_user_data(self): snippets_dir = self.make_dir() self.assertItemsEqual( ["base_user_data_sh"], get_snippet_context(snippets_dir=snippets_dir).keys(), )