Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

fleetd: process dependencies in [Install] section #1523

Closed
wants to merge 1 commit into from

Conversation

kayrus
Copy link
Contributor

@kayrus kayrus commented Mar 30, 2016

resolves #1382

@kayrus kayrus self-assigned this Mar 30, 2016
@kayrus kayrus added this to the v0.13.0 milestone Mar 30, 2016
@kayrus
Copy link
Contributor Author

kayrus commented Mar 30, 2016

TODO:

  • write functional test [done]
  • write unit test [won't implement]

@@ -106,6 +106,13 @@ func (m *systemdUnitManager) Load(name string, u unit.UnitFile) error {
if err != nil {
return err
}
if u.HasReverseDependencies() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea was to try always enabling units on load? This kind of special-casing seems fragile, unnecessary, and confusing...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not posible to enable unit when it doesn't have Install section

Copy link
Contributor

@antrik antrik Mar 30, 2016 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if this section is empty or it has invalid data?

Copy link
Contributor

@antrik antrik Mar 30, 2016 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kayrus
Copy link
Contributor Author

kayrus commented Mar 30, 2016

Just tested this functionality and noticed few issues. Here is the input data:

wants@.service:

[Service]
ExecStart=/bin/bash -c "while true; do echo wants@%i.service unit file; sleep 1; done"

wanted@.service:

[Unit]
Before=wants@%i.service
BindsTo=wants@%i.service

[Service]
ExecStart=/bin/bash -c "while true; do echo wanted@%i.service unit file; sleep 1; done"

[Install]                                                                                                               
WantedBy=wants@%i.service                                                                                               

[X-Fleet]                                                                                                               
MachineOf=wants@%i.service

Issue 1

fleectl submit wanted@.service wants@.service
fleetctl start wants@1.service

In this case fleetd doesn't process WantedBy of the wanted@.service template. And if we would like to start wanted@1.service automatically, we have to load it first, i.e.:

fleectl submit wanted@.service wants@.service
fleetctl load wanted@1.service
fleetctl start wants@1.service

And here comes Issue 2:

Within this situation fleetd doesn't monitor the wanted@1.service status and it still has loaded state:

fleetctl list-unit-files
UNIT                    HASH    DSTATE          STATE           TARGET
wanted@.service         2797f9a inactive        inactive        -
wanted@1.service        2797f9a loaded          loaded          6ed03b01.../coreos1
wants@.service          038ee83 inactive        inactive        -
wants@1.service         038ee83 launched        launched        6ed03b01.../coreos1

But systemd status is correct:

systemctl status wanted@1.service                                                                      
● wanted@1.service                                                                                                      
   Loaded: loaded (/run/fleet/units/wanted@1.service; enabled-runtime; vendor preset: disabled)                         
   Active: active (running) since Wed 2016-03-30 16:52:54 UTC; 11min ago                                                
 Main PID: 17765 (bash)                                                                                                 
   CGroup: /system.slice/system-wanted.slice/wanted@1.service                                                           
           ├─17765 /bin/bash -c while true; do echo wanted@1.service unit file; sleep 1; done                           
           └─19108 sleep 1                                                                                              

Mar 30 17:03:50 coreos1 bash[17765]: wanted@1.service unit file                                                         
Mar 30 17:03:51 coreos1 bash[17765]: wanted@1.service unit file                                                         
Mar 30 17:03:52 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:53 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:54 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:55 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:56 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:57 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:58 coreos1 bash[17765]: wanted@1.service unit file
Mar 30 17:03:59 coreos1 bash[17765]: wanted@1.service unit file
systemctl list-dependencies --reverse wants@1.service
wants@1.service
● └─wanted@1.service

Should fleet monitor unit status on the systemd side? And what should it do when it will find that desired status doesn't correspond to the real state? Should fleetd change unit's state by itself (not by systemd)?

The answer to the last question could be as follows:

When wants@.service unit's state is being changed, fleetd should get all existing units, parse them, and figure out whether there is an additional dependency. If there is WantedBy and unit is not loaded - just ignore that. If there is RequiredBy and unit is not loaded - we have to load that unit first, and then change wants@.service unit's state.

Looks like this issue has lots pitfalls.

UPD: some fleet specific options (dependencies) were already discussed in #464

@kayrus
Copy link
Contributor Author

kayrus commented Mar 30, 2016

@jonboulle comments?

@antrik
Copy link
Contributor

antrik commented Mar 31, 2016

@kayrus I don't think your Issue 1 is actually a problem -- as far as I can see, it's perfectly in line with the conversation in #1382 .

As for Issue 2... This does sound like a problem -- but isn't it just the same when using Wants dependencies instead, which apparently already worked in the existing code base?...

@kayrus kayrus force-pushed the kayrus/install_section branch 2 times, most recently from 64ffe99 to 6753795 Compare April 4, 2016 19:35
@kayrus
Copy link
Contributor Author

kayrus commented Apr 4, 2016

@joshix @robszumski could you review documentation part?

MachineOf=my.service
```

Fleet will load and automatically enable unit above because it contains `[Install]` section. Systemd will create a `my.service.wants/my_discovery.service` symlink to the `my_discovery.service` unit file. And when you start `my.service`, systemd will start `my_discovery.service` independently on `my_discovery.service` desired state defined in fleet. This situation may casue confusion between `fleetctl list-units` and `systemd list-units` outputs. It is recommended to use `fleetctl status my_discovery.service` to get real unit status (`fleetctl status` just passes arguments to `systemctl status` command).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on "this may cause confusion between fleetctl list-units and systemctl list-units"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worries me and I'm starting to wonder if this is a bad idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to specifically define what "enable" means for the user, ie. starts on boot

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't suite fleet behavior. Because fleet stores unit files inside tmpfs and they will not be booted automatically using only systemd routines.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonboulle I agree that this is a problem -- but AIUI it's actually not a new problem: according to the discussion in #1382 , systemd was already handling dependencies expressed by "Wants" relationships even without enabling; it's just "WantedBy" that changes... So unless I'm missing something, enabling units doesn't fundamentally change the situation -- it only makes it manifest in another case. (Which was somewhat inconsistent before.)

AIUI, the issue should be mostly mitigated once fleet implements dependencies such as X-Requires etc. -- though I guess it might be worthwhile to look into the inconsistency problem regardless. But I really think this is a separate issue.

@kayrus kayrus force-pushed the kayrus/install_section branch 2 times, most recently from 0d4e50e to 8ee465e Compare April 7, 2016 14:24
@kayrus kayrus changed the title [WIP] fleetd: process dependencies in [Install] section fleetd: process dependencies in [Install] section Apr 7, 2016
@kayrus
Copy link
Contributor Author

kayrus commented Apr 7, 2016

Updated tests. Now semaphoreci works.
I've removed failed golang 1.4.3 test in #1535


// Verify that discovery.service unit is stopped
timeout, err := util.WaitForState(
func() bool { return checkInactiveState() },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to wrap it in closure like that -- you can just pass checkInactiveState directly.

@@ -57,6 +57,35 @@ To use instance units, simply create a unit file whose name matches the `<name>@

When working with instance units, it is strongly recommended that all units be _entirely homogenous_. This means that any unit created as, say, `foo@1.service`, should be created only from the unit named `foo@.service`. This homogeneity will be enforced by the fleet API in future.

## Definition of the Install Section

Unit files which have `[Install]` section will be automatically enabled by fleet. This means that states of such unit files may not be tracked by fleet. For example you have loaded `my.service` unit file:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/which have/which have an/
s/states/the states/
s/may not/cannot/
"For example, assume we have loaded this my.service unit file:"

ExecStart=/bin/bash -c "while true; do echo my.service unit file; sleep 1; done"
```

and then loaded additional [sidekick][sidekick] discovery unit `my_discovery.service`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/additional/an additional/

@joshix
Copy link
Contributor

joshix commented Apr 12, 2016

docs LGTM for purpose

if stdout, stderr, err := cluster.Fleetctl(m0, "--strict-host-key-checking=false", "ssh", machine, "uptime"); err != nil {
t.Fatalf("Unable to SSH into fleet machine: \nstdout: %s\nstderr: %s\nerr: %v", stdout, stderr, err)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to check this here? We have separate tests for this?...

return true
} else {
return false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need an if here: the comparison already produces a bool...

@kayrus
Copy link
Contributor Author

kayrus commented Apr 19, 2016

@antrik updated.

@antrik
Copy link
Contributor

antrik commented Apr 19, 2016

Looks good to me now :-)

@jonboulle jonboulle modified the milestones: v1.0.0, v0.13.0 May 18, 2016
@jonboulle
Copy link
Contributor

Punting this to the next milestone as @kayrus thinks it should be reconsidered (?) but is afk

@dongsupark
Copy link
Contributor

This PR looks good to me.

Besides I had to think about a couple of open questions:

  • Unit states from "fleetctl list-units" do not match with those from "systemctl list-units"
    ** : That's not a new issue, as addressed by Unit does not automatically start Required units #464. In the future we might need to implement X-Requires to avoid the inconsistency.
  • We have not merged this one, in order to avoid potential conflicts with other PRs like unit state caches (now obsolete) or gRPC (still pending). Though as far as I can tell, gRPC PR doesn't seem to have anything to do with the Install section.

So I think I'll merge this one, probably some time in August.

@dongsupark
Copy link
Contributor

Closed via #1655

@dongsupark dongsupark closed this Aug 8, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WantedBy doesn't lead to starting service
7 participants