← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~dimitern/maas/1.2-node-view-shows-kernel-params into lp:maas

 

Dimiter Naydenov has proposed merging lp:~dimitern/maas/1.2-node-view-shows-kernel-params into lp:maas with lp:~jameinel/maas/land-kernel-opts-in-trunk as a prerequisite.

Requested reviews:
  MAAS Maintainers (maas-maintainers)
Related bugs:
  Bug #1044503 in MAAS: "kernel command line is not easily customizable"
  https://bugs.launchpad.net/maas/+bug/1044503

For more details, see:
https://code.launchpad.net/~dimitern/maas/1.2-node-view-shows-kernel-params/+merge/133449

Adding UI for kernel parameters in node and tag views, as well as the settings page.

Resubmitted after merging  lp:~jameinel/maas/land-kernel-opts-in-trunk and now is targeting trunk, instead of 1.2.
-- 
https://code.launchpad.net/~dimitern/maas/1.2-node-view-shows-kernel-params/+merge/133449
Your team MAAS Maintainers is requested to review the proposed merge of lp:~dimitern/maas/1.2-node-view-shows-kernel-params into lp:maas.
=== modified file 'src/maasserver/forms.py'
--- src/maasserver/forms.py	2012-11-08 11:00:29 +0000
+++ src/maasserver/forms.py	2012-11-08 11:00:30 +0000
@@ -655,6 +655,13 @@
         self._load_initials()
 
 
+class GlobalKernelOptsForm(ConfigForm):
+    """Settings page, Global Kernel Parameters section."""
+    kernel_opts = forms.CharField(
+        label="Boot parameters to pass to the kernel by default",
+        required=False)
+
+
 hostname_error_msg = "Enter a valid hostname (e.g. host.example.com)."
 
 

=== modified file 'src/maasserver/static/css/components/blocks.css'
--- src/maasserver/static/css/components/blocks.css	2012-10-03 03:59:53 +0000
+++ src/maasserver/static/css/components/blocks.css	2012-11-08 11:00:30 +0000
@@ -82,3 +82,6 @@
 .size12 {
     width: 720px;
     }
+.size12 input {
+    width: 100%;
+    }

=== modified file 'src/maasserver/templates/maasserver/form_field.html'
--- src/maasserver/templates/maasserver/form_field.html	2012-08-03 16:36:26 +0000
+++ src/maasserver/templates/maasserver/form_field.html	2012-11-08 11:00:30 +0000
@@ -1,5 +1,5 @@
 {% load field_type %}
-<li class="{{ field.html_name }}{% if field.errors %} error{% endif %}">
+<li class="{{ field.html_name }}{% if css_class %} {{ css_class }}{% endif %}{% if field.errors %} error{% endif %}">
   <label for="id_{{ field.html_name }}">
     {% ifequal field|field_type "CheckboxInput" %}
       {{ field }}

=== modified file 'src/maasserver/templates/maasserver/node_view.html'
--- src/maasserver/templates/maasserver/node_view.html	2012-11-07 14:43:58 +0000
+++ src/maasserver/templates/maasserver/node_view.html	2012-11-08 11:00:30 +0000
@@ -85,6 +85,20 @@
           {% endif %}
       </span>
     </li>
+    {% if kernel_opts.value %}
+    <li class="block size10 first">
+      <h4>Kernel Parameters
+        {% if kernel_opts.is_global %}
+        - from: <a class="kernelopts-global-link" href="{% url 'settings' %}">Global Kernel Parameters</a>
+        {% elif kernel_opts.is_tag %}
+        - from tag: <span><a class="kernelopts-tag-link" href="{% url 'tag-view' kernel_opts.tag.name %}">{{ kernel_opts.tag.name }}</a></span>
+        {% endif %}
+      </h4>
+      <span id="node_kernel_opts">
+        {{ kernel_opts.value }}
+      </span>
+    </li>
+    {% endif %}
     {% if error_text %}
     <li class="block first">
       <h4>Error output</h4>

=== modified file 'src/maasserver/templates/maasserver/settings.html'
--- src/maasserver/templates/maasserver/settings.html	2012-11-06 16:47:23 +0000
+++ src/maasserver/templates/maasserver/settings.html	2012-11-08 11:00:30 +0000
@@ -125,6 +125,21 @@
       <div class="clear"></div>
     </div>
     <div class="divider"></div>
+    <div id="global_kernel_opts" class="block size7 first">
+      <h2>Global Kernel Parameters</h2>
+      <form action="{% url "settings" %}" method="post">
+        {% csrf_token %}
+        <ul>
+          {% with field=kernelopts_form.kernel_opts %}
+            {% include "maasserver/form_field.html" with css_class="size12" %}
+          {% endwith %}
+        </ul>
+        <input type="hidden" name="kernelopts_submit" value="1" />
+        <input type="submit" class="button right" value="Save" />
+      </form>
+      <div class="clear"></div>
+    </div>
+    <div class="divider"></div>
     <div id="maas_and_network" class="block size7 first">
       <h2>Network Configuration</h2>
       <form action="{% url "settings" %}" method="post">

=== modified file 'src/maasserver/templates/maasserver/tag_view.html'
--- src/maasserver/templates/maasserver/tag_view.html	2012-10-24 12:51:10 +0000
+++ src/maasserver/templates/maasserver/tag_view.html	2012-11-08 11:00:30 +0000
@@ -19,6 +19,12 @@
       <h4>Definition</h4>
       <span>{{ tag.definition }}</span>
     </li>
+    {% if tag.kernel_opts %}
+    <li class="kernel-opts-tag block size10">
+      <h4>Kernel Parameters</h4>
+      <span>{{ tag.kernel_opts }}</span>
+    </li>
+    {% endif %}
     {% if error_text %}
     <li class="block first">
       <h4>Error output</h4>

=== modified file 'src/maasserver/tests/test_views_nodes.py'
--- src/maasserver/tests/test_views_nodes.py	2012-11-08 10:11:03 +0000
+++ src/maasserver/tests/test_views_nodes.py	2012-11-08 11:00:30 +0000
@@ -39,6 +39,7 @@
     )
 from maasserver.forms import NodeActionForm
 from maasserver.models import (
+    Config,
     MACAddress,
     Node,
     )
@@ -440,6 +441,40 @@
         self.assertIn(
             reverse('mac-add', args=[node.system_id]), response.content)
 
+    def test_view_node_shows_global_kernel_params(self):
+        Config.objects.create(name='kernel_opts', value='--test param')
+        node = factory.make_node()
+        self.assertEqual(
+            node.get_effective_kernel_options(),
+            (None, "--test param", )
+        )
+
+        node_link = reverse('node-view', args=[node.system_id])
+        response = self.client.get(node_link)
+        doc = fromstring(response.content)
+        kernel_params = doc.cssselect('#node_kernel_opts')[0]
+        self.assertEqual('--test param', kernel_params.text.strip())
+
+        details_link = doc.cssselect('a.kernelopts-global-link')[0].get('href')
+        self.assertEqual(reverse('settings'), details_link)
+
+    def test_view_node_shows_tag_kernel_params(self):
+        tag = factory.make_tag(name='shiny', kernel_opts="--test params")
+        node = factory.make_node()
+        node.tags = [tag]
+        self.assertEqual(
+            (tag, '--test params',),
+            node.get_effective_kernel_options())
+
+        node_link = reverse('node-view', args=[node.system_id])
+        response = self.client.get(node_link)
+        doc = fromstring(response.content)
+        kernel_params = doc.cssselect('#node_kernel_opts')[0]
+        self.assertEqual('--test params', kernel_params.text.strip())
+
+        details_link = doc.cssselect('a.kernelopts-tag-link')[0].get('href')
+        self.assertEqual(reverse('tag-view', args=[tag.name]), details_link)
+
     def test_view_node_has_button_to_accept_enlistment_for_user(self):
         # A simple user can't see the button to enlist a declared node.
         node = factory.make_node(status=NODE_STATUS.DECLARED)

=== modified file 'src/maasserver/tests/test_views_settings.py'
--- src/maasserver/tests/test_views_settings.py	2012-11-08 06:34:48 +0000
+++ src/maasserver/tests/test_views_settings.py	2012-11-08 11:00:30 +0000
@@ -185,6 +185,21 @@
             choices + [['my.hostname.com', 'my.hostname.com']],
             new_choices)
 
+    def test_settings_kernelopts_POST(self):
+        new_kernel_opts = "--new='arg' --flag=1 other"
+        response = self.client.post(
+            reverse('settings'),
+            get_prefixed_form_data(
+                prefix='kernelopts',
+                data={
+                    'kernel_opts': new_kernel_opts,
+                }))
+
+        self.assertEqual(httplib.FOUND, response.status_code)
+        self.assertEqual(
+            new_kernel_opts,
+            Config.objects.get_config('kernel_opts'))
+
     def test_settings_contains_form_to_accept_all_nodegroups(self):
         factory.make_node_group(status=NODEGROUP_STATUS.PENDING),
         response = self.client.get(reverse('settings'))

=== modified file 'src/maasserver/tests/test_views_tags.py'
--- src/maasserver/tests/test_views_tags.py	2012-11-08 07:38:39 +0000
+++ src/maasserver/tests/test_views_tags.py	2012-11-08 11:00:30 +0000
@@ -89,6 +89,17 @@
         self.assertIn(node.hostname, content_text)
         self.assertNotIn(node2.hostname, content_text)
 
+    def test_view_tag_shows_kernel_params(self):
+        tag = factory.make_tag(kernel_opts='--test tag params')
+        node = factory.make_node()
+        node.tags = [tag]
+        tag_link = reverse('tag-view', args=[tag.name])
+        response = self.client.get(tag_link)
+        doc = fromstring(response.content)
+        kernel_opts = doc.cssselect('.kernel-opts-tag')[0].text_content()
+        self.assertIn('Kernel Parameters', kernel_opts)
+        self.assertIn(tag.kernel_opts, kernel_opts)
+
     def test_view_tag_paginates_nodes(self):
         """Listing of nodes with tag is split across multiple pages
 

=== modified file 'src/maasserver/views/nodes.py'
--- src/maasserver/views/nodes.py	2012-11-08 10:11:03 +0000
+++ src/maasserver/views/nodes.py	2012-11-08 11:00:30 +0000
@@ -56,6 +56,7 @@
 from maasserver.models import (
     MACAddress,
     Node,
+    Tag,
     )
 from maasserver.models.node import CONSTRAINTS_JUJU_MAP
 from maasserver.models.node_constraint_filter import constrain_nodes
@@ -247,6 +248,13 @@
             node.error if node.status == NODE_STATUS.FAILED_TESTS else None)
         context['status_text'] = (
             node.error if node.status != NODE_STATUS.FAILED_TESTS else None)
+        kernel_opts = node.get_effective_kernel_options()
+        context['kernel_opts'] = {
+            'is_global': kernel_opts[0] is None,
+            'is_tag': isinstance(kernel_opts[0], Tag),
+            'tag': kernel_opts[0],
+            'value': kernel_opts[1]
+            }
         return context
 
     def dispatch(self, *args, **kwargs):

=== modified file 'src/maasserver/views/settings.py'
--- src/maasserver/views/settings.py	2012-11-07 10:39:19 +0000
+++ src/maasserver/views/settings.py	2012-11-08 11:00:30 +0000
@@ -46,6 +46,7 @@
     MAASAndNetworkForm,
     NewUserCreationForm,
     UbuntuForm,
+    GlobalKernelOptsForm,
     )
 from maasserver.models import (
     NodeGroup,
@@ -177,6 +178,13 @@
     if response is not None:
         return response
 
+    # Process the Global Kernel Opts form.
+    kernelopts_form, response = process_form(
+        request, GlobalKernelOptsForm, reverse('settings'), 'kernelopts',
+        "Configuration updated.")
+    if response is not None:
+        return response
+
     # Process accept clusters en masse.
     if 'mass_accept_submit' in request.POST:
         number = NodeGroup.objects.accept_all_pending()
@@ -217,6 +225,7 @@
             'maas_and_network_form': maas_and_network_form,
             'commissioning_form': commissioning_form,
             'ubuntu_form': ubuntu_form,
+            'kernelopts_form': kernelopts_form,
         },
         context_instance=RequestContext(request))
 


Follow ups