← Back to team overview

cloud-init team mailing list archive

Re: Still struggling with systemd cycle

 

On 10/31/2016 04:03 PM, Scott Moser wrote:
> On Sat, 29 Oct 2016, Robert Schweikert wrote:
> 
>> Hi,
>>
>> All the cloud-init*.services use
>>
>> [Install]
>> WantedBy=cloud-init.target
>>
>> This implies that cloud-final.service needs to run before
>> cloud-init.target is completed.
> 
> That is correct.
> 
>> However, in the latest version in master we have for cloud-final.service
>>
>> After=multi-user.target
> 
> This was added / changed because of
>  https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1576692
> Basically, installation of packages that have non-"trivial" service
> dependencies fail during systemd boot. It doesnt seem like it is
> specifically a Ubuntu bug as any package installation could install
> systemd service files and the goal is to start the service at that point.
> (although i realize that might not be the case for rpm based distros)
> 
>> But in cloud-init.service we for example have
>>
>> Before=network-online.target
>>
>> and cloud-init.service is also part of the cloud-init.target as is
>> cloud-final.service. Thus the cloud-init.target has a requirement to run
>> before multi-user.target is reached (network-online.target is part of
>> multi-user.target) while also having a requirement to run after
>> multi-user.target is reached.
> 
> I do not think that is correct. cloud-init.service is WantedBy
> cloud-init.target.  But that just means if cloud-init.target is trying to
> be reached, that it will also try to start the cloud-init.service.  It
> does not imply any other ordering.

Well based on what I have observed, and my conclusion may be incorrect,
systemd complained about loops of multi-user.target needing
cloud-init.target and cloud-init.target needing multi-user.target. Then
there was another loop at a lower level where network configuration and
cloud-init.service formed a loop around basic.target.

Based on the error message I received and the data in the .service files
the error messages made sense and I found a "solution" that works for
me, more below.

> 
>> It appears to me that the systemd complaint is correct.
>>
>> Given that rc-local.service is a direct dependency for
>> multi-user.target, as shown in the diagram below (hoping that mail
>> servers and clients will not make too big of a mess with it) and we
>> already have
>>
>> After=rc-local.service
>>
>> and rc-local.service is probably one of the last things to run before
>> multi-user.target is reached it is probably save to drop
>>
>> After=multi-user.target
>>
>> from cloud-final.service.
> 
> I dont think it is.  It was really a pain.  Systemd ordering is painful.
> 
> I'm pretty sure nothing is actually *wrong* as cloud-init boots correctly
> and journalctl shows no broken loops on 16.04 and 16.10 at the moment.
> 
> I'm not saying its perfect. Just that I don't think its actually wrong.
> 

Well , maybe it's a systemd version difference between the distros, I
did get loop complaints and ended up with the following:

[Unit]
Description=Initial cloud-init job (metadata service crawler)
DefaultDependencies=no
Wants=cloud-init-local.service
Wants=local-fs.target
Wants=sshd-keygen.service
Wants=sshd.service
After=cloud-init-local.service
After=wicked.service
Requires=wicked.service
Before=network-online.target
Before=sshd-keygen.service
Before=sshd.service
Before=systemd-user-sessions.service
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cloud-init init
RemainAfterExit=yes
TimeoutSec=0

# Output needs to appear in instance console output
StandardOutput=journal+console

[Install]
WantedBy=cloud-init.target

-----------
[Unit]
Description=Initial cloud-init job (pre-networking)
DefaultDependencies=no
Wants=local-fs.target
Wants=network-pre.target
After=local-fs.target
Before=basic.target
Before=network-pre.target
Before=shutdown.target
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cloud-init init --local
ExecStart=/bin/touch /run/cloud-init/network-config-ready
RemainAfterExit=yes
TimeoutSec=0

# Output needs to appear in instance console output
StandardOutput=journal+console

[Install]
WantedBy=cloud-init.target

---------
[Unit]
Description=Execute cloud user/final scripts
After=cloud-config.service
After=network-online.target
After=rc-local.service
Before=systemd-logind.service
Wants=network-online.target cloud-config.service

[Service]
Type=oneshot
ExecStart=/usr/bin/cloud-init modules --mode=final
RemainAfterExit=yes
TimeoutSec=0
KillMode=process

# Output needs to appear in instance console output
StandardOutput=journal+console

[Install]
WantedBy=cloud-init.target

I have not tested all eventualities such as installing packages, but I
am finally back to the point where I have no systemd loops and can log
back into the system.

Key pieces are that I dropped

After=multi-user.target

in cloud-final.service as that creates a dependency of multi-user.target
on cloud-init.target, but of course cloud-init.target cannot be reached
until cloud-final.service has run.

I also dropped

Before=basic.target

in cloud-init.service as basic.target is needed by wicked.service (the
magic to configure the network) and thus one cannot have

After=wicked.service
Before=basic.target

together as that forms another loop.
-- 
Robert Schweikert                   MAY THE SOURCE BE WITH YOU
Public Cloud Architect                         LINUX
rjschwei@xxxxxxxx
IRC: robjo

Attachment: signature.asc
Description: OpenPGP digital signature


Follow ups

References