[arch-projects] [netctl] netctl, cloud-init, and systemd

Jouke Witteveen j.witteveen at gmail.com
Mon Jun 17 20:20:10 UTC 2019


On Mon, Jun 17, 2019 at 9:45 PM Erich Eckner via arch-projects
<arch-projects at archlinux.org> wrote:
> > In case you are not familiar with cloud-init, the idea is that you can
> > build a single OS image that runs cloud-init on boot, and cloud-init
> > will take care of such things as network configuration, so that the same
> > image will work regardless of the network setup you choose for the cloud
> > instance.
>
> Does cloud-init run before or after systemd? In other words: is it a
> systemd unit of some kind or is it rather an init daemon itself which
> chain-loads systemd?
>
> > The current cloud-init implementation for Arch uses netctl [3]. The
> > implementation is correct in such a way that it does indeed render the
> > right netctl profile(s) and enables them. However there is a problem:
> > they are not being started. AFAICT this is because cloud-init does this
> > while the systemd boot is already in process, and changing the
> > dependency graph (by adding new units) does not have any effect until
> > the next run (everything works right on second boot). Note that I even
> > tried having cloud-init run `systemd daemon-reload` after enabling the
> > units, but it didn't help either.
>
> Did you try cloud-init to issue "systemctl start $unitname.service"
> additionally to "systemctl enable $unitname.service"? This seems to me to
> be the right way.
>
> >
> > The reason I am posting this here is that this seems to be an issue due
> > to the particular way netctl use systemd units. Since you don't know the
> > names or the number of profiles (units) that will be generated during
> > image creation, you cannot enable them at that time. But doing so during
> > first boot does not seem to work.
>
> I would rather say it's due to the way, cloud-init uses systemd units: it
> enables them, but that's only relevant for successive boots, so it should
> rather enable and start them (systemd should still honor the dependencies
> of the units and postpone the start to the point where all of the
> dependencies are loaded, too).
>
> >
> > Just for comparison, if one were to use e.g. systemd-networkd instead,
> > you would just enable the systemd-networkd unit during image creation,
> > cloud-init could generate the appropriate config for any number of
> > devices, and when the unit starts it will do the right thing. Likewise
> > on other distros, e.g. Debian with /etc/network/interfaces or such.
> >
> > Now, from my point of view, there could be several approaches to solve
> this:
> >
> > 1. systemd supports updates of the dep graph during boot
> > 2. support such a use case in netctl
> > 3. change cloud-init to use systemd-networkd for Arch
> >
> > Let me quickly elaborate:
> >
> > 1. is intentionally not phrased as something to be done. It might
> > already be a thing, I just couldn't figure out how to do it. If someone
> > knows more about this, I would love to hear about it. If this works, it
> > would be the easiest solution. However, if it doesn't, I don't have my
> > hopes up high for this being added to systemd anytime soon.
>
> This would mean, if I "systemctl enable $some.service", it will be started
> right away, too - probably not, what systemd devs want (at least it's
> not, what systemd currently does).

`systemctl enable --now <SERVICE>` starts a service in addition to enabling it.

> >
> > 2. is the main reason I am writing this. Things that came to mind were
> > another special unit (netctl-all?), or even just a well-defined
> > interface to write devices into the state file, so that the plain netctl
> > unit would work. I would be very interested to hear how such a thing
> > sounds to you, the developers?
>
> There is currently netctl-auto at .service, but this requires to know the
> interfaces in advance. Maybe the netctl devs can consider adding another
> unit which is interface agnostic? "netctl-auto.service" maybe? (I'm not
> familiar with netctl's interna - maybe this is not possible at all)

Indeed, there are two more options to achieve what I think you want.
1. Use "netctl-ifplugd@<INTERFACE>", see also: netctl.special(7). This
requires ifplugd to be installed and takes all profiles for an
interface into consideration, so you don't need to know the name of
the profile in advance. Of course, you do need to know the name of the
interface.

2. Use "netctl(.service)", see also: netctl.special(7), and write the
profile name to "/var/lib/netctl/netctl.state". This only works if
cloud-init runs before systemd, or at least finishes before the netctl
service is started.

> > 3. Is of course an option, but would require quite a bit of work in
> > cloud-init. That work, if done right, might however at some point
> > benefit other distros, should they be using systemd-networkd as well.
> > The main reason I am also bringing this up that I was wondering if there
> > are possibly any plans to abandon netctl anyways at some point in favor
> > of distro-agnostic solutions (be it systemd-networkd or any other).

netctl is stable and I intend to keep maintaining it. It should work
without adaptations on any linux distribution that uses systemd.

Regards,
- Jouke


More information about the arch-projects mailing list