Expose a more consistent subset of systemd's service directives

The idea there isn’t being different just for the sake of being different. In many cases we kept the pristine names of systemd, as for example in the socket activation feature that we’re implementing support for we’ll have listen-stream. It wouldn’t be my first choice of terminology, but we preserved it precisely to help mapping between the two worlds.

But the case here is different, in the sense that systemd has very poorly designed terminology around those ideas. Just consider:

  • Requires
  • Wants
  • BindsTo
  • PartOf
  • PropagateReloadTo
  • ReloadPropagatedFrom

All of these are essentially about starting and stopping services on certain events. Yet, we have mixed up the ideas of binding, parts, propagation, soft and hard dependencies, and so on. And this is not only very confusing, but it also burns down terminology in the sense that once we have a part-of term in the stanza with a given meaning, for example, a proper design needs to burn the term because we don’t want multiple uses of that next to each other.

Those terms are also not self-describing, and I commonly see experienced people digging down in the documentation to re-learn what they mean, even for the better cases such as Requires. See for example this question on stackexchange which was viewed six thousand times since it was asked 11 months ago. There are many of those.

So… here is a proposal:

Let’s start with a small set of options that covers the common cases we know about in terms of inter-dependency between services. Some good candidates we discussed:

  • starts-with: <other> | [<other>, …]
  • stops-with: <other> | [<other>, …]
  • runs-with: <other> | [<other>, …]

Update: As noted much later below, it’s been a while but I’ve been thinking of “starts-with” and “stops-with” for reasons unrelated to snapd, and we’ve settled for “requires” as the term, as it makes the directionality of the dependency clear, and the implied semantics are easier to grasp.

The first two will be appropriately mapped to Requires, Wants, or PartOf as appropriate to obtain the intended semantics. The last one, runs-with, leverages BindsTo, which unfortunately is the only option that includes the idea of exiting together with another service’s self-termination. Wasn’t for that, we might also have an independent exits-with option.

Then, as a follow up step, let’s look into how to properly map the support for targets into snaps in a way that is both safe and convenient. We probably won’t need new terminology for that, other than perhaps something to define the targets themselves. We do need to consider the issue of confined interaction with the system, and whether we want snaps to operate on a global namespace or individual namespace, and if global, how maintain sanity on that namespace.

In either case, from what I understand on your description, all of those issues are points we want to make work, so thanks for engaging with us and let’s push it forward.

1 Like