Merge pull request #1803 from Chris-Peterson444/kernel-autoinstall-file

Allow for specifying the autoinstall file over the kernel command line
This commit is contained in:
Chris Peterson 2023-09-21 13:45:29 -07:00 committed by GitHub
commit 4010f0ad5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 31 deletions

View File

@ -78,24 +78,47 @@ Autoinstall on the install media
Another option for supplying autoinstall to the Ubuntu installer is to place a
file named :code:`autoinstall.yaml` on the install media itself.
There are two potential locations for the :code:`autoinstall.yaml` file:
* At the root of the "CD-ROM". When you write the installation ISO to a USB
Flash Drive, this can be done by copying the :code:`autoinstall.yaml` to the
partition containing the contents of the ISO - i.e.,
in the directory containing the ``casper`` sub-directory.
* On the rootfs of the installation system - this option will typically
require modifying the installation ISO and is not suggested, but is
supported.
There are two potential locations that subiquity will check for the
:code:`autoinstall.yaml` file:
Directly specifying autoinstall as a :code:`autoinstall.yaml` file does not
require a :code:`#cloud-config` header, and does not use a top level
``autoinstall:`` key. The autoinstall directives are placed at the top
level. For example:
* At the root of the "CD-ROM". When you write the installation ISO to a USB
Flash Drive, this can be done by copying the :code:`autoinstall.yaml` to the
partition containing the contents of the ISO - i.e.,
in the directory containing the ``casper`` sub-directory.
* On the rootfs of the installation system - this option will typically
require modifying the installation ISO and is not suggested, but is
supported.
.. code-block:: yaml
Alternatively, you can pass the location of the autoinstall file on the kernel
command line via the :code:`subiquity.autoinstallpath` parameter, where the
path is relative to the rootfs of the installation system. For example:
version: 1
....
* :code:`subiquity.autoinstallpath=path/to/autoinstall.yaml`
.. note::
Directly specifying autoinstall as a :code:`autoinstall.yaml` file does not
require a :code:`#cloud-config` header, and does not use a top level
``autoinstall:`` key. The autoinstall directives are placed at the top
level. For example:
.. code-block:: yaml
version: 1
....
Order precedence of the autoinstall locations
======================================
Since there are many ways to specify the autoinstall file, it may happen that
multiple locations are specified at once. Subiquity will look for the
autoinstall file in the following order and pick the first existing one:
1. Kernel command line
2. Root of the installation system
3. Cloud Config
4. Root of the CD-ROM (ISO)
Cloud-init and autoinstall interaction

View File

@ -574,10 +574,11 @@ class SubiquityServer(Application):
def select_autoinstall(self):
# precedence
# 1. autoinstall at root of drive
# 2. command line argument autoinstall
# 3. autoinstall supplied by cloud config
# 4. autoinstall baked into the iso, found at /cdrom/autoinstall.yaml
# 1. command line argument autoinstall
# 2. kernel command line argument subiquity.autoinstallpath
# 3. autoinstall at root of drive
# 4. autoinstall supplied by cloud config
# 5. autoinstall baked into the iso, found at /cdrom/autoinstall.yaml
# if opts.autoinstall is set and empty, that means
# autoinstall has been explicitly disabled.
@ -588,9 +589,12 @@ class SubiquityServer(Application):
):
raise Exception(f"Autoinstall argument {self.opts.autoinstall} not found")
kernel_install_path = self.kernel_cmdline.get("subiquity.autoinstallpath", None)
locations = (
self.base_relative(root_autoinstall_path),
self.opts.autoinstall,
kernel_install_path,
self.base_relative(root_autoinstall_path),
self.base_relative(cloud_autoinstall_path),
self.base_relative(iso_autoinstall_path),
)

View File

@ -54,31 +54,46 @@ class TestAutoinstallLoad(SubiTestCase):
return path
def test_autoinstall_disabled(self):
self.server.opts.autoinstall = ""
self.server.kernel_cmdline = {"subiquity.autoinstallpath": "kernel"}
self.create(root_autoinstall_path, "root")
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
self.server.opts.autoinstall = ""
self.assertIsNone(self.server.select_autoinstall())
def test_root_wins(self):
root = self.create(root_autoinstall_path, "root")
autoinstall = self.create(self.path("arg.autoinstall.yaml"), "arg")
self.server.opts.autoinstall = autoinstall
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
self.assertEqual(root, self.server.select_autoinstall())
self.assert_contents(root, "root")
def test_arg_wins(self):
root = self.path(root_autoinstall_path)
arg = self.create(self.path("arg.autoinstall.yaml"), "arg")
self.server.opts.autoinstall = arg
kernel = self.create(self.path("kernel.autoinstall.yaml"), "kernel")
self.server.kernel_cmdline = {"subiquity.autoinstallpath": kernel}
root = self.create(root_autoinstall_path, "root")
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
self.assertEqual(root, self.server.select_autoinstall())
self.assert_contents(root, "arg")
def test_kernel_wins(self):
self.server.opts.autoinstall = None
kernel = self.create(self.path("kernel.autoinstall.yaml"), "kernel")
self.server.kernel_cmdline = {"subiquity.autoinstallpath": kernel}
root = self.create(root_autoinstall_path, "root")
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
self.assertEqual(root, self.server.select_autoinstall())
self.assert_contents(root, "kernel")
def test_root_wins(self):
self.server.opts.autoinstall = None
self.server.kernel_cmdline = {}
root = self.create(root_autoinstall_path, "root")
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
self.assertEqual(root, self.server.select_autoinstall())
self.assert_contents(root, "root")
def test_cloud_wins(self):
self.server.opts.autoinstall = None
self.server.kernel_cmdline = {}
root = self.path(root_autoinstall_path)
self.create(cloud_autoinstall_path, "cloud")
self.create(iso_autoinstall_path, "iso")
@ -86,7 +101,10 @@ class TestAutoinstallLoad(SubiTestCase):
self.assert_contents(root, "cloud")
def test_iso_wins(self):
self.server.opts.autoinstall = None
self.server.kernel_cmdline = {}
root = self.path(root_autoinstall_path)
# No cloud config file
self.create(iso_autoinstall_path, "iso")
self.assertEqual(root, self.server.select_autoinstall())
self.assert_contents(root, "iso")