Server autoinstall design questions

I’ve started implementing autoinstall for servers using the new installer machinery as discussed before. In the course of doing this I’ve inevitably run into a few bits of the design that were less than clear or perhaps just not thought through.

One is that the allowable config for configuring apt was way too simplistic. I’ve reworded it as you can see at https://wiki.ubuntu.com/FoundationsTeam/AutomatedServerInstalls/ConfigReference#apt to allow for things like adding PPAs.

The other one that I’ve bumped into is how multiple config files are handled. My design just says:

The autoinstall file can be provided in the following ways:

 * As /autoinstall.yaml in the initrd
 * As /autoinstall.yaml on the install media
 * As /autoinstall.yaml on a filesystem with label "autoinstall"
 * Via a http or https (or maybe tftp) URL on the kernel command line

But it doesn’t say anything about the order these are scanned or what happens if there is more than one. I think it makes sense to scan for configs in this order:

  1. As /autoinstall.yaml on the install media
  2. As /autoinstall.yaml in the initrd
  3. As /autoinstall.yaml on a filesystem with label “autoinstall”
  4. Via a http or https (or maybe tftp) URL on the kernel command line

and to merge later configs into earlier ones. This lets you do things like prepare an initrd to use with netbooting that provides almost all details but also pass a few extra bits of config via kernel command line.

The next question is how merging is done. curtin (the installer underlying subiquity) merges configs by merging mappings only. This works quite well but this would be awkward with one aspect of the current design: lists of commands like early-commands. Basically, merging one config into another could only replace the entire list of commands to run.

What curtin does to get around this is to have early-commands and similar be a mapping from arbitrary keys to lists of commands. When it’s time to run the commands it sorts the keys and runs each command from each list in order. This allows later configs to choose whether to supplement or overwrite commands specified by earlier configs.

That may well have made no sense :slight_smile: so I’ll try an example. Suppose /autoinstall.yaml contains this:

early-commands:
  10-base-cmds:
    - cmd1
    - cmd2

Then a config file supplied via kernel command line could contain this:

early-commands:
 11-cmds: # runs after commands from earlier config
   - cmd1
   - cmd2

or this:

early-commands:
  09-cmds: # runs before commands from earlier config
    - cmd1
    - cmd2

or this:

early-commands:
  10-base cmds: [] # suppresses commands from early config entirely

My feeling having written all this out is that we should switch how command lines are specified to match how curtin does it – the added flexibility seems worth the cost of making autoinstall.yaml files slightly more cluttered. But maybe someone wants to try to argue me out of that?

1 Like

On the overriding of settings over multiple layers, cloud-init also faced a similar challenge overriding vendor data with user data, so it might be worth considering that solution. https://cloudinit.readthedocs.io/en/latest/topics/vendordata.html has some of the details; in particular the use of #cloud-config-jsonp allows for very fine grained overriding.

I don’t have a strong opinion that this mechanism must be used or anything; I only intend to provide some more options to consider.

Given the fact that both configs are under the user’s control, I don’t think that level of complexity is required (or, at least, I hope not!)

I realised that the storage specification was missing some bits so I made this change to the spec: https://wiki.ubuntu.com/FoundationsTeam/AutomatedServerInstalls/ConfigReference?action=diff&rev1=40&rev2=41