← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/maas/generate-enlistment-pxe into lp:maas

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/generate-enlistment-pxe into lp:maas.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/generate-enlistment-pxe/+merge/111053

This is needed to allow the new script for importing boot images to create corresponding PXE configs for enlisting new nodes.  The “default” PXE config for an architecture will tell a node to register itself with a MAAS.  The import script will invoke the new command.

As originally discussed with Raphaël, I wanted the command to write the config file to stdout so as to decouple the file's location from its contents.  The command could produce the file and the script could put it in place.  But that turned out not to work very well since PXEConfig already writes the files directly into the /var/lib/tftproot/ tree.  Thus I had to do the same — which does give rise to a short window where the file will be incomplete or empty, but we've decided to treat boots concurrent with script runs as a low priority.  For testing I override the /var/lib/tftpboot location with a temporary directory of my own making.

One thing that's not very nice yet is generation of kernel options.  We'll have to systematize that and get some reuse between various kinds of configs, but we're not quite at a point where we have a place to do that yet.  In the interest of small branches I'm doing it all inline for now.  Based on what I've seen from the existing import scripts, and help from Daviey and roaksoax, the result looks similar to what we get from Cobbler — but we should probably treat them as bogus for now.  We have no idea yet where the iSCSI stuff should point to, for instance.

Daviey tells me that enlistment should use the kernel and initrd from the install image, so that's what this code does.  No need for a separate “enlistment” kernel.


Jeroen
-- 
https://code.launchpad.net/~jtv/maas/generate-enlistment-pxe/+merge/111053
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/generate-enlistment-pxe into lp:maas.
=== added file 'src/maasserver/management/commands/generate_enlistment_pxe.py'
--- src/maasserver/management/commands/generate_enlistment_pxe.py	1970-01-01 00:00:00 +0000
+++ src/maasserver/management/commands/generate_enlistment_pxe.py	2012-06-19 16:22:22 +0000
@@ -0,0 +1,68 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Django command: generate a PXE configuration file for node enlistment.
+
+Produces the "default" PXE configuration that we provide to nodes that
+MAAS is not yet aware of.  A node that netboots using this configuration
+will then register itself with the MAAS.
+"""
+
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
+
+__metaclass__ = type
+__all__ = [
+    'Command',
+    ]
+
+
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from provisioningserver.pxe.pxeconfig import PXEConfig
+
+
+class Command(BaseCommand):
+    """Print out enlistment PXE config."""
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--arch', dest='arch', default=None,
+            help="Main system architecture to generate config for."),
+        make_option(
+            '--subarch', dest='arch', default='generic',
+            help="Sub-architecture of the main architecture."),
+        make_option(
+            '--release', dest='release', default=None,
+            help="Ubuntu release to run when enlisting nodes."),
+        )
+
+    def handle(self, arch=None, subarch='generic', release=None, **kwargs):
+        image_path = '/maas/%s/%s/%s/install' % (arch, subarch, release)
+        # TODO: This needs to go somewhere more appropriate, and
+        # probably contain more appropriate options.
+        kernel_opts = ' '.join([
+            # Default kernel options (similar to those used by Cobbler):
+            'initrd=%s' % '/'.join([image_path, 'initrd.gz']),
+            'ksdevice=bootif',
+            'lang=  text ',
+            'hostname=%s-%s' % (release, arch),
+            'domain=local.lan',
+            'suite=%s' % release,
+
+            # MAAS-specific options:
+            'priority=critical',
+            'local=en_US',
+            'netcfg/choose_interface=auto',
+            ])
+        template_args = {
+            'menutitle': "Enlisting with MAAS",
+            # Enlistment uses the same kernel as installation.
+            'kernelimage': '/'.join([image_path, 'linux']),
+            'append': kernel_opts,
+        }
+        PXEConfig(arch, subarch).write_config(**template_args)

=== added file 'src/maasserver/tests/test_commands_generate_enlistment_pxe.py'
--- src/maasserver/tests/test_commands_generate_enlistment_pxe.py	1970-01-01 00:00:00 +0000
+++ src/maasserver/tests/test_commands_generate_enlistment_pxe.py	2012-06-19 16:22:22 +0000
@@ -0,0 +1,41 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for the generate-enlistment-pxe command."""
+
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
+
+__metaclass__ = type
+__all__ = []
+
+import os.path
+
+from django.core.management import call_command
+from maasserver.enum import ARCHITECTURE_CHOICES
+from maasserver.testing.factory import factory
+from maasserver.testing.testcase import TestCase
+from provisioningserver.pxe.pxeconfig import PXEConfig
+
+
+class TestGenerateEnlistmentPXE(TestCase):
+
+    def test_generates_default_pxe_config(self):
+        arch = factory.getRandomChoice(ARCHITECTURE_CHOICES)
+        release = 'precise'
+        tftpdir = self.make_dir()
+        self.patch(PXEConfig, 'target_basedir', tftpdir)
+        call_command('generate_enlistment_pxe', arch=arch, release=release)
+        # This produces a "default" PXE config file in the right place.
+        # It refers to the kernel and initrd for the requested
+        # architecture and release.
+        result_path = os.path.join(
+            tftpdir, arch, 'generic', 'pxelinux.cfg', 'default')
+        with open(result_path) as result_file:
+            contents = result_file.read()
+        self.assertIn(
+            '/'.join(['/maas', arch, 'generic', release, 'install', 'linux']),
+            contents)