Disabling console-conf from gadget or core config option

Some headless images that use a system-user assertion and ship a netplan config do not want to run console-conf. To do this we need to inject (touch) an empty file /var/lib/console-conf/complete that prevents console-conf from starting.

To avoid that people manually (or by script) modify the image by injecting this file into the /writable partition, there should be a possibility to set a gadget cofiguration option to disable console-conf, so it could be defined as a “default” in gadget.yaml instead of hacking the image.

6 Likes

The idea sounds fine.

@mvo Is that a service that integrates cleanly with systemd, or does it need anything else in terms of configuration? If it’s really just a systemd service, then perhaps a “service.console-conf.disable” setting similar to the others we have would be okay.

This feels slightly less ideal in this case, because it’s not just a third-party service. This is an integral part of the initial experience of core devices, and so tastes like something that would deserve some better handling in terms of configuration.

But perhaps that’s okay for now, as we can always do something else as well later, without breaking compatibility.

@mvo If we indeed need to drop files or something, in addition to configuring systemd, let’s please talk and see what to do instead of adding another edge case to the “service” handling logic.

I looked at this today. While console-conf is using systemd services it seems it is not entirely straightforward to disable this way because it is using template service files (console-conf@.service) which are started from the getty@.service files for each tty (and the serial ttys). The console-conf@.service has a ConditionPathExists=!/var/lib/console-conf/complete which will prevent all of the units from running.

The fact that it is a template means there is no systemctl stop console-conf@.service that can be used to stop the services, they need to be stopped/disabled/masked for each tty individually. But even with that done the regular getty will not start on the ttys because getty@.service has a ExecStartPre= line to start console-conf and if that is masked this generates a failure. So the getty unit is considered failed and does not come up.

Maybe @mwhudson has some further ideas how to disable the console-conf service via systemd directly in a clean way. If not it looks like the write/remove of the /var/lib/console-conf/complete file might be our best option.

I looked a bit deeper, refactoring the code in the core config is straightforward https://github.com/snapcore/snapd/compare/master...mvo5:console-conf-disable?expand=1 but there is a race here if we drop the stamp file during firstboot.

AFICT console-conf will start before/in-parallel with snapd which means the complete file will not be there and all instances of console-conf will have to be found and stopped via the core config handling code. It also means there will be a window when console-conf is available during first-boot even if it is disabled via a config option (not sure if that can be exploited though). Looks a bit like a rabbit hole right now :confused:

Since this is done at image creation would it e possible for the disable option to be done when the image creation is done? The timing would be similar to the current workaround of just placing the file, but it would no longer involve the explicit image modification.

It’s been a while since I looked at all this stuff but I think creating the stamp file is going to be the easiest way to disable console-conf although as you noticed there is a heap of race condition fun around in this area. I’m a bit better at systemd that I was when I wrote the current version of the stuff so I might be able to come up with something more elegant now.

I had actually thought about badgering you guys for a systemd service that would wait until snapd startup had completed for a totally unrelated reason but I worked around that. If you added something like that, I think console-conf would be able to order itself after that to avoid the race.

so this has finally been fixed by an image build time option in ubuntu-image. you can now use the --disable-console-conf option during image build and console-conf will be disabled in your image.

Note that there is actually now a system configuration option you can set in your gadget to disable console-conf,

defaults:
  system:
    service:
      console-conf:
        disable: true

This option only works when set from a gadget, it does not work to set dynamically at runtime with snap set.

1 Like

I cannot make it work for uc20. I built the gadget snap file with the above codes in gadget.yaml file. It is verified after unsquash the new gadget snap file. Interestingly, the gadget file in the image under /snap/gadget-name/current/meta/gadget.yaml doesn’t have the above codes and the console-conf is not disabled. I uploaded the new gadget snap file and released it to the correct channel/track. Is the gadget file updated during booting?

config default are only applied on first boot, you need to build a fresh image with that gadget …

sorry, forgot to mention, I built a new image with the new gadget with the above codes, but it didn’t work.

ah, sorry, i misunderstood the question about updating …

1 Like

What grade of model are you using for your image and how are you invoking ubuntu-image ?

I think the issue is in the gadget or the image. The image is using 25 revision but I released 27 to the channel/track:

total 0
drwxr-xr-x 4 root root 169 Mar 25 13:55 25
lrwxrwxrwx 1 root root 2 Mar 28 13:22 current -> 25

The outputs of snap info:

20/edge: 1 2021-03-28 (27) 1MB -
installed: 1 (25) 1MB gadget

and your model assertion points to that channel for this snap ?

I used grade: dangerous for core20. The ubuntu-image command:

ubuntu-image snap --image-size sizeM --snap core18=latest/stable --snap docker=latest/stable -O vm-img

core18 is also used for docker is based on it.

You need to rebuild your gadget and then provide it with --snap <your-gadget-snap> too

Yes, as below:

default-channel: 20/edge
id: ID
name: NAME
type: gadget

hmm, i wouldnt see why this would install rev 25 then … perhaps ian has an idea …
(you did re-sign your assertion properly after changing it i assume ?)