diff --git a/autoinstall-schema.json b/autoinstall-schema.json
index c24fbacb..1eeb92c6 100644
--- a/autoinstall-schema.json
+++ b/autoinstall-schema.json
@@ -72,6 +72,31 @@
},
"additionalProperties": false
},
+ "kernel": {
+ "type": "object",
+ "properties": {
+ "package": {
+ "type": "string"
+ },
+ "flavor": {
+ "type": "string"
+ }
+ },
+ "oneOf": [
+ {
+ "type": "object",
+ "required": [
+ "package"
+ ]
+ },
+ {
+ "type": "object",
+ "required": [
+ "flavor"
+ ]
+ }
+ ]
+ },
"keyboard": {
"type": "object",
"properties": {
diff --git a/subiquity/models/kernel.py b/subiquity/models/kernel.py
new file mode 100644
index 00000000..fb8a978d
--- /dev/null
+++ b/subiquity/models/kernel.py
@@ -0,0 +1,26 @@
+# Copyright 2021 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+class KernelModel:
+
+ metapkg_name = None
+
+ def render(self):
+ return {
+ 'kernel': {
+ 'package': self.metapkg_name,
+ },
+ }
diff --git a/subiquity/models/subiquity.py b/subiquity/models/subiquity.py
index d45ed447..acb1d858 100644
--- a/subiquity/models/subiquity.py
+++ b/subiquity/models/subiquity.py
@@ -30,6 +30,7 @@ from subiquitycore.utils import run_command
from .filesystem import FilesystemModel
from .identity import IdentityModel
+from .kernel import KernelModel
from .keyboard import KeyboardModel
from .locale import LocaleModel
from .mirror import MirrorModel
@@ -69,6 +70,7 @@ ff02::2 ip6-allrouters
INSTALL_MODEL_NAMES = [
"debconf_selections",
"filesystem",
+ "kernel",
"keyboard",
"mirror",
"network",
@@ -110,6 +112,7 @@ class SubiquityModel:
self.debconf_selections = DebconfSelectionsModel()
self.filesystem = FilesystemModel()
self.identity = IdentityModel()
+ self.kernel = KernelModel()
self.keyboard = KeyboardModel(self.root)
self.locale = LocaleModel()
self.mirror = MirrorModel()
@@ -351,12 +354,4 @@ class SubiquityModel:
log.debug("merging config from %s", model)
merge_config(config, model.render())
- mp_file = os.path.join(self.root, "run/kernel-meta-package")
- if os.path.exists(mp_file):
- with open(mp_file) as fp:
- kernel_package = fp.read().strip()
- config['kernel'] = {
- 'package': kernel_package,
- }
-
return config
diff --git a/subiquity/server/controllers/__init__.py b/subiquity/server/controllers/__init__.py
index 8a3985d9..2a6c54d6 100644
--- a/subiquity/server/controllers/__init__.py
+++ b/subiquity/server/controllers/__init__.py
@@ -19,6 +19,7 @@ from .filesystem import FilesystemController
from .identity import IdentityController
from .install import InstallController
from .keyboard import KeyboardController
+from .kernel import KernelController
from .locale import LocaleController
from .mirror import MirrorController
from .network import NetworkController
@@ -40,6 +41,7 @@ __all__ = [
'FilesystemController',
'IdentityController',
'InstallController',
+ 'KernelController',
'KeyboardController',
'LateController',
'LocaleController',
diff --git a/subiquity/server/controllers/kernel.py b/subiquity/server/controllers/kernel.py
new file mode 100644
index 00000000..940e0294
--- /dev/null
+++ b/subiquity/server/controllers/kernel.py
@@ -0,0 +1,82 @@
+# Copyright 2021 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import os
+
+from subiquitycore.lsb_release import lsb_release
+
+from subiquity.server.controller import NonInteractiveController
+
+
+class KernelController(NonInteractiveController):
+
+ model_name = autoinstall_key = "kernel"
+ autoinstall_default = None
+ autoinstall_schema = {
+ "type": "object",
+ "properties": {
+ "package": {"type": "string"},
+ "flavor": {"type": "string"},
+ },
+ "oneOf": [
+ {
+ "type": "object",
+ "required": ["package"],
+ },
+ {
+ "type": "object",
+ "required": ["flavor"],
+ }
+ ],
+ }
+
+ def start(self):
+ mp_file = os.path.join(
+ self.app.base_model.root,
+ "run/kernel-meta-package")
+ if os.path.exists(mp_file):
+ with open(mp_file) as fp:
+ kernel_package = fp.read().strip()
+ self.model.metapkg_name = kernel_package
+ elif self.model.metapkg_name is None:
+ self.model.metapkg_name = 'linux-generic'
+
+ def load_autoinstall_data(self, data):
+ if data is None:
+ return
+ package = data.get('package')
+ flavor = data.get('flavor')
+ if package is None:
+ if flavor is None or flavor == 'generic':
+ package = 'linux-generic'
+ else:
+ if flavor is None:
+ package = 'generic'
+ else:
+ if flavor == 'hwe':
+ flavor = 'generic-hwe'
+ # Should check this package exists really but
+ # that's a bit tricky until we get cleverer about
+ # the apt config in general.
+ package = 'linux-{flavor}-{release}'.format(
+ flavor=flavor, release=lsb_release()['release'])
+ self.model.metapkg_name = package
+
+ def make_autoinstall(self):
+ return {
+ 'kernel': {
+ 'package': self.model.metapkg_name,
+ },
+ }
diff --git a/subiquity/server/server.py b/subiquity/server/server.py
index dbc9f44a..93acceae 100644
--- a/subiquity/server/server.py
+++ b/subiquity/server/server.py
@@ -178,6 +178,7 @@ class SubiquityServer(Application):
"Debconf",
"Locale",
"Refresh",
+ "Kernel",
"Keyboard",
"Zdev",
"Network",