launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #08964
[Merge] lp:~rvb/maas/preseed-templates into lp:maas
Raphaël Badin has proposed merging lp:~rvb/maas/preseed-templates into lp:maas with lp:~rvb/maas/preseed-customisation as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~rvb/maas/preseed-templates/+merge/111049
This branch adds the Tempita-based preseed templates.
= Pre-imp =
This is part of the plan which was devised last week with Gavin (see http://bit.ly/KXW5ZU for details) and I've had a pre-imp call with Jeroen about this.
= Notes =
The new templates are in contrib/preseeds_v2 for now. When we will be ready to ditch the old templates (in contrib/preseeds and contrib/snippets), we will just "rm -rf contrib/preseeds contrib/snippets && mv contrib/preseeds_v2 contrib/preseeds and update src/maas/development.py:PRESEED_TEMPLATE_LOCATIONS.
The preseed templates files (contrib/preseeds_v2/preseed_master, contrib/preseeds_v2/enlist, contrib/preseeds_v2/commissioning and contrib/preseeds_v2/generic) are simply the existing cobbler preseed templates/snippets converted to a Tempita format. Note that I've used Tempita's inheritance mechanism to create a master template with all the boilerplate stuff. The 'generic' template inherits from it.
In get_preseed_context, the value of context['node_disable_pxe_url'] is the empty string for now. It will need to point to an anonymous version of the metadata API method that we already have to turn netboot off for the node in question. That will be done in another branch.
I've also changed get_preseed_filenames to allow an empty prefix to be passed. This is nothing more than a small improvement: if you want to create a preseed template for all the nodes with architecture 'myarch', you'll need to create a template file named 'myarch' (rather than _myarch).
--
https://code.launchpad.net/~rvb/maas/preseed-templates/+merge/111049
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/maas/preseed-templates into lp:maas.
=== added directory 'contrib/preseeds_v2'
=== added file 'contrib/preseeds_v2/commissioning'
--- contrib/preseeds_v2/commissioning 1970-01-01 00:00:00 +0000
+++ contrib/preseeds_v2/commissioning 2012-06-19 16:19:20 +0000
@@ -0,0 +1,2 @@
+{{preseed_data}}
+cloud-init cloud-init/local-cloud-config string manage_etc_hosts: localhost
=== added file 'contrib/preseeds_v2/enlist'
--- contrib/preseeds_v2/enlist 1970-01-01 00:00:00 +0000
+++ contrib/preseeds_v2/enlist 2012-06-19 16:19:20 +0000
@@ -0,0 +1,9 @@
+d-i preseed/early_command string anna-install maas-enlist-udeb
+d-i maas-enlist/skip-maas-discover boolean true
+d-i maas-enlist/maas-server-address string {{server_host}}
+d-i maas-enlist/host-name string
+
+d-i mirror/country string manual
+d-i mirror/http/hostname string archive.ubuntu.com
+d-i mirror/http/directory string /ubuntu
+d-i mirror/http/proxy string http://{{server_host}}:8000/
=== added file 'contrib/preseeds_v2/generic'
--- contrib/preseeds_v2/generic 1970-01-01 00:00:00 +0000
+++ contrib/preseeds_v2/generic 2012-06-19 16:19:20 +0000
@@ -0,0 +1,24 @@
+{{inherit "preseed_master"}}
+{{def proxy}}
+d-i mirror/country string manual
+d-i mirror/http/hostname string archive.ubuntu.com
+d-i mirror/http/directory string /ubuntu
+d-i mirror/http/proxy string http://{{server_host}}:8000/
+{{enddef}}
+
+{{def client_packages}}
+d-i pkgsel/include string cloud-init openssh-server python-software-properties vim avahi-daemon server^
+{{enddef}}
+
+{{def preseed}}
+{{preseed_data}}
+cloud-init cloud-init/local-cloud-config string manage_etc_hosts: localhost
+{{enddef}}
+
+{{def post_scripts}}
+# Executes late command and disables PXE.
+d-i preseed/late_command string true && \
+ in-target sh -c 'f=$1; shift; echo $0 > $f && chmod 0440 $f $*' 'ubuntu ALL=(ALL) NOPASSWD: ALL' /etc/sudoers.d/maas && \
+ wget "{{node_disable_pxe_url}}" -O /dev/null && \
+ true
+{{enddef}}
=== added file 'contrib/preseeds_v2/preseed_master'
--- contrib/preseeds_v2/preseed_master 1970-01-01 00:00:00 +0000
+++ contrib/preseeds_v2/preseed_master 2012-06-19 16:19:20 +0000
@@ -0,0 +1,90 @@
+# MAAS - Ubuntu Server Installation
+# * Minimal install
+# * Cloud-init for bare-metal
+# * maas_preseed snippet is expanded to provide cloud-init preseed data
+
+# Locale
+d-i debian-installer/locale string en_US.UTF-8
+
+# No splash
+d-i debian-installer/splash boolean false
+
+# Keyboard layout
+d-i console-setup/ask_detect boolean false
+d-i console-setup/layoutcode string us
+d-i console-setup/variantcode string
+
+# Network configuration
+d-i netcfg/get_nameservers string
+d-i netcfg/get_ipaddress string
+d-i netcfg/get_netmask string 255.255.255.0
+d-i netcfg/get_gateway string
+d-i netcfg/confirm_static boolean true
+
+# Local clock (set to UTC and use ntp)
+d-i clock-setup/utc boolean true
+d-i clock-setup/ntp boolean true
+d-i clock-setup/ntp-server string ntp.ubuntu.com
+
+# Partitioning
+d-i partman/early_command string debconf-set partman-auto/disk `list-devices disk | head -n1`
+d-i partman-iscsi/mainmenu string finish
+d-i partman-auto/method string regular
+d-i partman-lvm/device_remove_lvm boolean true
+d-i partman-lvm/confirm boolean true
+d-i partman/confirm_write_new_label boolean true
+d-i partman/choose_partition select Finish partitioning and write changes to disk
+d-i partman/confirm boolean true
+d-i partman/confirm_nooverwrite boolean true
+d-i partman/default_filesystem string ext4
+
+# Use server kernel
+d-i base-installer/kernel/image string linux-server
+
+# User Setup
+d-i passwd/root-login boolean false
+d-i passwd/make-user boolean true
+d-i passwd/user-fullname string ubuntu
+d-i passwd/username string ubuntu
+d-i passwd/user-password-crypted password !
+d-i passwd/user-uid string
+d-i user-setup/allow-password-weak boolean false
+d-i user-setup/encrypt-home boolean false
+d-i passwd/user-default-groups string adm cdrom dialout lpadmin plugdev sambashare
+
+# APT
+{{self.proxy}}
+
+# By default the installer requires that repositories be authenticated
+# using a known gpg key. This setting can be used to disable that
+# authentication. Warning: Insecure, not recommended.
+d-i debian-installer/allow_unauthenticated string false
+
+# Lang
+d-i pkgsel/language-packs multiselect en
+d-i pkgsel/update-policy select none
+d-i pkgsel/updatedb boolean true
+
+# Boot-loader
+d-i grub-installer/skip boolean false
+d-i lilo-installer/skip boolean false
+d-i grub-installer/only_debian boolean true
+d-i grub-installer/with_other_os boolean true
+d-i finish-install/keep-consoles boolean false
+d-i finish-install/reboot_in_progress note
+
+# Eject cdrom
+d-i cdrom-detect/eject boolean true
+
+# Do not halt/poweroff after install
+d-i debian-installer/exit/halt boolean false
+d-i debian-installer/exit/poweroff boolean false
+
+# maas client packages
+{{self.client_packages}}
+
+# maas preseed
+{{self.preseed}}
+
+# Post scripts.
+{{self.post_scripts}}
=== modified file 'src/maas/development.py'
--- src/maas/development.py 2012-06-19 16:19:20 +0000
+++ src/maas/development.py 2012-06-19 16:19:20 +0000
@@ -86,7 +86,7 @@
# Use in-branch preseed templates.
PRESEED_TEMPLATE_LOCATIONS = (
abspath("etc/preseeds"),
- abspath("contrib/preseeds"),
+ abspath("contrib/preseeds_v2"),
)
# Allow the user to override settings in maas_local_settings.
=== modified file 'src/maasserver/preseed.py'
--- src/maasserver/preseed.py 2012-06-19 16:19:20 +0000
+++ src/maasserver/preseed.py 2012-06-19 16:19:20 +0000
@@ -13,8 +13,11 @@
__all__ = []
from os.path import join
+from urlparse import urlparse
from django.conf import settings
+from maasserver.models import Config
+from maasserver.provisioning import compose_preseed
import tempita
@@ -22,7 +25,7 @@
# XXX: rvb 2012-06-14 bug=1013146: 'precise' is hardcoded here.
-def get_preseed_filenames(node, prefix, release='precise', default=False):
+def get_preseed_filenames(node, prefix='', release='precise', default=False):
"""List possible preseed template filenames for the given node.
:param node: The node to return template preseed filenames for.
@@ -46,7 +49,10 @@
'generic'
"""
arch = split_subarch(node.architecture)
- elements = [prefix] + arch + [release, node.hostname]
+ elements = []
+ if prefix != '':
+ elements.append(prefix)
+ elements.extend(arch + [release, node.hostname])
while elements:
yield compose_filename(elements)
elements.pop()
@@ -120,3 +126,45 @@
content, name=filepath, get_template=get_template)
return get_template(prefix, None, default=True)
+
+
+def get_maas_server_host():
+ """Return MAAS' server name."""
+ maas_url = Config.objects.get_config('maas_url')
+ return urlparse(maas_url).netloc.split(':')[0]
+
+
+# XXX: rvb 2012-06-19 bug=1013146: 'precise' is hardcoded here.
+def get_preseed_context(node, release="precise"):
+ """Return the context dictionary to be used to render preseed templates
+ for this node.
+
+ :param node: See `get_preseed_filenames`.
+ :param prefix: See `get_preseed_filenames`.
+ :param release: See `get_preseed_filenames`.
+ :return: The context dictionary.
+ :rtype: dict.
+ """
+ server_host = ''
+ return {
+ 'node': node,
+ 'release': release,
+ 'server_host': server_host,
+ 'preseed_data': compose_preseed(node),
+ 'node_disable_pxe_url': '', # TODO.
+ }
+
+
+# XXX: rvb 2012-06-19 bug=1013146: 'precise' is hardcoded here.
+def render_preseed(node, prefix, release="precise"):
+ """Find and load a `PreseedTemplate` for the given node.
+
+ :param node: See `get_preseed_filenames`.
+ :param prefix: See `get_preseed_filenames`.
+ :param release: See `get_preseed_filenames`.
+ :return: The rendered preseed string.
+ :rtype: basestring.
+ """
+ template = load_preseed_template(node, prefix, release)
+ context = get_preseed_context(node, release)
+ return template.substitute(**context)
=== modified file 'src/maasserver/tests/test_preseed.py'
--- src/maasserver/tests/test_preseed.py 2012-06-19 16:19:20 +0000
+++ src/maasserver/tests/test_preseed.py 2012-06-19 16:19:20 +0000
@@ -15,12 +15,16 @@
import os
from django.conf import settings
+from maasserver.models import Config
from maasserver.preseed import (
GENERIC_FILENAME,
+ get_maas_server_host,
+ get_preseed_context,
get_preseed_filenames,
get_preseed_template,
load_preseed_template,
PreseedTemplate,
+ render_preseed,
split_subarch,
TemplateNotFoundError,
)
@@ -82,6 +86,18 @@
],
list(get_preseed_filenames(node, prefix, release, default=True)))
+ def test_get_preseed_filenames_supports_empty_prefix(self):
+ hostname = factory.getRandomString()
+ release = factory.getRandomString()
+ node = factory.make_node(hostname=hostname)
+ self.assertSequenceEqual(
+ [
+ '%s_%s_%s' % (node.architecture, release, hostname),
+ '%s_%s' % (node.architecture, release),
+ '%s' % node.architecture,
+ ],
+ list(get_preseed_filenames(node, '', release)))
+
def test_get_preseed_filenames_returns_list_without_default(self):
# If default=False is passed to get_preseed_filenames, the
# returned list won't include the default template name as a
@@ -264,3 +280,52 @@
template = load_preseed_template(node, prefix)
self.assertRaises(
TemplateNotFoundError, template.substitute)
+
+
+class TestGetMAASServerHost(TestCase):
+ """Tests for `get_maas_server_host`."""
+
+ def test_get_maas_server_host_returns_host(self):
+ Config.objects.set_config('maas_url', 'http://example.com/path')
+ self.assertEqual('example.com', get_maas_server_host())
+
+ def test_get_maas_server_host_strips_out_port(self):
+ Config.objects.set_config(
+ 'maas_url', 'http://example.com:%d' % factory.getRandomPort())
+ self.assertEqual('example.com', get_maas_server_host())
+
+
+class TestPreseedContext(TestCase):
+ """Tests for `get_preseed_context`."""
+
+ def test_get_preseed_context_contains_keys(self):
+ node = factory.make_node()
+ release = factory.getRandomString()
+ context = get_preseed_context(node, release)
+ self.assertItemsEqual(
+ ['node', 'release', 'server_host', 'preseed_data',
+ 'node_disable_pxe_url'],
+ context)
+
+
+class TestRenderPreseed(TestCase):
+ """Tests for `render_preseed`.
+
+ These tests check that the templates render (i.e. that no variable is
+ missing) and 'look right'.
+ """
+
+ def test_render_default_preseed(self):
+ node = factory.make_node()
+ preseed = render_preseed(node, factory.getRandomString(), "precise")
+ self.assertIn('preseed/late_command', preseed)
+
+ def test_render_enlist_preseed(self):
+ node = factory.make_node()
+ preseed = render_preseed(node, 'enlist', "precise")
+ self.assertIn('maas-enlist-udeb', preseed)
+
+ def test_render_commissioning_preseed(self):
+ node = factory.make_node()
+ preseed = render_preseed(node, 'commissioning', "precise")
+ self.assertIn('cloud-init', preseed)