[Nix-dev] How to get rid of systemd (was: Modifying the init system (introducing S6 supervision suite))

Ertugrul Söylemez ertesx at gmx.de
Sat Dec 27 18:29:37 CET 2014


Hi Nicolas,

>> I think as a first step to get rid of systemd and gain a much more
>> sensible services model as well we should move away from NixOS
>> modules for services.
>
> The module system is made in such a way that one can build on top of
> the work of the other without having any computer scientist knowledge.

I hope you realise that my proposal makes everything *simpler* both for
module/service writers and configuration authors.  Services will be
simpler and less tedious to write (simple functions).  They will compose
naturally.  The algebraic part is *design* and perhaps terminology.  It
enables *those who want* to exploit the additional structure especially
for equational reasoning and containerisation, but understanding
abstract algebra is in no way a requirement for the regular NixOS user.

Let me respond to your objection anyway:  If we can have a configuration
DSL that gives us a major benefit, including much simpler modules,
provable safety, full automation of tedious tasks, etc., then I'm sorry
for the "I don't want to learn something new" cavemen, but I'm more than
happy to leave them far behind.  Exploring and using new ideas require
acquiring new knowledge from time to time.  NixOS itself is a great
example of this.

One thing I'd like to see *by default* in NixOS is containerisation,
even for the regular desktop user who only uses Firefox and LibreOffice,
in the spirit of Qubes OS.  It's technically possible, supported by
Linux by and does not require setup.  This is the motivating purpose for
my proposal.  Let me give you a very compelling example:

    services =
        withBridge bridgeConfig (br:
            container (nginx ... <> openssh ...) <>
            container (openvpn ... br ...)) <>
        openssh ...

This simple configuration would define a whole network of containerised
applications.


> This is also the reason why I am pushing to abolish "functions" as
> option definitions.  Most of the time if you want to use a function,
> you can express it as a set of input (option declaration) which are
> being processed to provide a lower level of abstraction given by
> another module (option definitions).

Perhaps NixOS with its *functional* package management and *functional*
configuration language is just the wrong distribution for you. ;) </joke>

Jokes aside, when a function makes sense, I go for it, because functions
make things simpler.  Please stop pushing that way.  For those who
aren't programmers, functions are just syntax anyway.


> The module system does not prevent us from doing anything, it provides
> a new way of formatting which makes things declarative and extensible.

I won't go as far as to argue that "declarative" is a meaningless term.
Also I'm not sure what you mean by "formatting" (syntax?).

The extensibility of the current module system is limited in the same
way global variables limit the extensibility of a program.  Everything
is global, and every module can affect every other module in completely
unrestricted and unpredictable ways.  Any kind of data feedback requires
something you would classify as "computer scientist knowledge"
(least-defined fixed points of nonstrict recursive functions).

Again, this has bitten me in the past.  There is no way to reason about
your configuration other than to look into the resulting derivation.
This is a bad situation.  The more modules and options we get, the more
difficult it will get to keep everything together.


> If a module does not serve what you expect, you can always write
> another module and use it instead of the previous one.  Having
> multiple instances of a service is an issue with the module, not a
> limitation in the module system.

I guess we have very different philosophical views, so it is difficult
to communicate the advantage of my proposal to you without actually
implementing a prototype.

I admit that to a non-FP programmer the concept I propose must look very
similar to what we have today except that you can add the same service
multiple times.  The advantage is only apparent when you start ot use
the functional and algebraic features.  Otherwise all that changes is
that the syntax becomes simpler (still a small benefit though).


>> Being able to reason about the resulting system is very important.
>
> Have you tried nixos-option ?

This question suggests that you are unfamiliar with equational
reasoning.  To answer your question: Yes, I'm aware of nixos-option, and
it's orthogonal to the issue I'm raising.

Also I should point out explicitly that I'm not proposing to replace the
module system.  I'm proposing not to use the module system for services.
If my proposal works as intended and finds acceptance we will quickly
find other things that would benefit from this, for example the network
configuration.


>> I would prefer and do propose an algebraic solution (view services as
>> a toolbox from which you can pick the services you want and compose
>> them together).  A services configuration then might look like this:
>>
>>     services =
>>         bitlbee { port = 10000; stateDir = "/var/lib/bitlbee1"; } <>
>>         bitlbee { port = 10001; stateDir = "/var/lib/bitlbee2"; } <>
>>         nginx { httpConfig = "..."; } <>
>>         postfix { postMasterAlias = "blah"; }
>
> First, unamed instance are not modular. This is why we are moving away
> from types.listOf and that the suggested alternative is a backward
> compatible version named types.loaOf (list or attribute set of).

I'm sorry, but I don't understand what you mean.  Also I don't
understand why you would want to remove `types.listOf`.  The
`boot.kernelModules` option is a set of strings.  It would be completely
stupid to require a name for every item.

The underlying concept of types that require type arguments is well
known.  In the context of a non-static language like Nix one term I have
heard is that of *contracts*.  There is a good introduction to
[contracts] for JavaScript.  Since JS and Nix are very similar, it can
and has been translated to Nix almost verbatim (types.*).

[contracts]: https://www.youtube.com/watch?v=-FkgOHvNAU8


> Second, I see 2 additional concepts and I do not think I would be able
> to explain these to my grand-mother, Can you?

If your grandmother is a NixOS sysadmin and understands how to use a
text editor, then probably yes.  Otherwise it's irrelevant.

However, if your grandmother can set up services right now, she won't
have difficulty setting up services after the change.  It will just be a
slightly different syntax.


> I think what you are trying to express can be done with the module
> system, maybe you can try to make a prototype using the module system
> and a new top-level "system-proto" option which is declaring submodule
> for every service that you want to declare.  Maybe we can learn
> something from this experiment, in order to better design future
> services.

Up to the `services` option everything stays the same.  At some point in
the near future I will probably be *forced* to write a prototype anyway,
because some of the things I want to do are impossible or very tedious
and unreliable with the current module-based services infrastructure.
I'm doing a lot with containers.

The good news:  There is no need to rewrite everything at once.  We can
start with a few experimental services, and if it works we can migrate
everything else.


> In any cases, I do not think we want to switch to something without
> having a working prototype to experiment with.  Do not take that
> personally, this was also the case with the module system [1].

No worries.  This is a technical discussion. =)

But I'd like to ask you to view me as part of the community, i.e. the
"we" you're referring to that seems to exclude me.  Even though my name
probably doesn't come up very often I'm a NixOS user and contributor
since 2011.


Greets,
Ertugrul


More information about the nix-dev mailing list