curtin:xenial:amd64 Install custom kernel

  * MAAS does not give any possibility to install
    custom kernel version, via node definition
  * Add possilibility to define:
    - exact kernel version
    - few extra pkgs, to be installed during
      curtin stage
  Warning: in that case, global maas variable
    'maas_config:default_min|max_*_kernel:' will
    be ignored at all.

Change-Id: I89f4f656c5e02e1cb10d6a81905b4abd7d738d40
Closes-Bug: PROD-25084 (PROD:25084)
diff --git a/README.rst b/README.rst
index 98ad365..377f1d2 100644
--- a/README.rst
+++ b/README.rst
@@ -498,7 +498,11 @@
             filters: ['release~(xenial)', 'arch~(amd64)', 'subarch~(generic|hwe-16.04$|ga-16.04)']
           count: 1
 
-Usage of local deb repos
+Usage of local deb repos and curtin-based variables.
+
+Dict of variables ``curtin_vars:amd64:xenial: `` format, which will be passed only to:
+``/etc/maas/preseeds/curtin_userdata_amd64_generic_xenial`` accordingly.
+
 
 .. code-block:: yaml
 
@@ -520,6 +524,13 @@
         -----END PGP PUBLIC KEY BLOCK-----
       saltstack_repo_xenial: "deb [arch=amd64] http://${_param:local_repo_url}/ubuntu-xenial stable salt"
       saltstack_repo_trusty: "deb [arch=amd64] http://${_param:local_repo_url}/ubuntu-trusty stable salt"
+      curtin_vars:
+        amd64:
+          xenial:
+            # List of packages, to be installed directly in curtin stage.
+            extra_pkgs: [ "linux-headers-generic-hwe-16.04", "linux-image-extra-virtual-hwe-16.04" ]
+            # exact kernel pkgs name, to be passed into curtin stage.
+            kernel_package: 'linux-image-virtual-hwe-16.04'
 
 Single MAAS cluster service [multiple racks]
 
diff --git a/maas/files/curtin_userdata_amd64_generic_xenial b/maas/files/curtin_userdata_amd64_generic_xenial
index 82beaea..0af7280 100644
--- a/maas/files/curtin_userdata_amd64_generic_xenial
+++ b/maas/files/curtin_userdata_amd64_generic_xenial
@@ -1,5 +1,5 @@
 {%- from "maas/map.jinja" import cluster with context %}
-{% raw %}
+{%- raw %}
 #cloud-config
 debconf_selections:
  maas: |
@@ -18,6 +18,12 @@
 late_commands:
   maas: [wget, '--no-proxy', {{node_disable_pxe_url|escape.json}}, '--post-data', {{node_disable_pxe_data|escape.json}}, '-O', '/dev/null']
 {% endraw %}
+
+{%- if salt['pillar.get']('maas:cluster:curtin_vars:amd64:xenial:kernel_package') %}
+kernel:
+  package: {{ pillar.maas.cluster.curtin_vars.amd64.xenial.kernel_package }}
+{%- endif %}
+
 {%- if cluster.get('saltstack_repo_key', False) %}
   {% set salt_repo_key = salt['hashutil.base64_b64encode'](cluster.saltstack_repo_key) %}
   apt_00_set_gpg: ["curtin", "in-target", "--", "sh", "-c", "echo '{{salt_repo_key}}' | base64 -d | apt-key add -"]
@@ -27,8 +33,12 @@
 {%- else %}
   {%- set saltstack_repo = 'deb [arch=amd64] ' + cluster.saltstack_repo_xenial -%}
 {%- endif %}
+
   apt_01_set_repo: ["curtin", "in-target", "--", "sh", "-c", "echo '{{ saltstack_repo }}' >> /etc/apt/sources.list.d/mcp_saltstack.list"]
   apt_03_update: ["curtin", "in-target", "--", "apt-get", "update"]
+{%- if salt['pillar.get']('maas:cluster:curtin_vars:amd64:xenial:extra_pkgs') %}
+  apt_04_install_pkgs: ["curtin", "in-target", "--", "apt-get", "-y", "install", "{{ pillar.maas.cluster.curtin_vars.amd64.xenial.extra_pkgs|join(' ') }}"]
+{%- endif %}
   salt_01_install: ["curtin", "in-target", "--", "apt-get", "-y", "install", "salt-minion"]
   salt_02_hostname_set: ["curtin", "in-target", "--", "echo", "{% raw %}{{node.hostname}}{% endraw %}.{{pillar.linux.system.domain}}"]
   salt_03_hostname_get: ["curtin", "in-target", "--", "sh", "-c", "echo 'id: {% raw %}{{node.hostname}}{% endraw %}.{{pillar.linux.system.domain}}' >> /etc/salt/minion.d/minion.conf"]
@@ -52,3 +62,7 @@
   driver_07_update_initramfs: ["curtin", "in-target", "--", "update-initramfs", "-u"]
 {{endif}}
 {% endraw %}
+
+{#
+# vim: ft=jinja
+#}
diff --git a/tests/pillar/maas_region.sls b/tests/pillar/maas_region.sls
index a150389..d601e91 100644
--- a/tests/pillar/maas_region.sls
+++ b/tests/pillar/maas_region.sls
@@ -6,6 +6,13 @@
       port: 80
     role: master
     enable_iframe: True
+    cluster:
+      curtin_vars:
+        amd64:
+          xenial:
+            extra_pkgs: [ "curl", "wget" ]
+            #kernel_package: 'linux-image-virtual-hwe-16.04'
+            kernel_package: 'mc'
   region:
     enabled: true
     bind: