mbox series

[bug#54811,0/3] Support socket activation in 'guix publish' and 'guix-daemon'

Message ID 20220409091246.6979-1-ludo@gnu.org
Headers show
Series Support socket activation in 'guix publish' and 'guix-daemon' | expand

Message

Ludovic Courtès April 9, 2022, 9:12 a.m. UTC
Hello!

Now that we have this fancy new Shepherd, we can have our daemons
started lazily via “socket activation” like all the cool kids have
been doing.  :-)

Next steps: update the ‘guix’ package, update the .service files,
and update (gnu services base) (I’m not entirely sure we can start
‘guix-daemon’ via socket activation though due to the container
shenanigans in there.)

Thoughts?

Ludo’.

Ludovic Courtès (3):
  publish: Use SRFI-71 instead of SRFI-11.
  publish: Support systemd-style socket activation.
  daemon: Support systemd-style socket activation.

 doc/guix.texi                 | 11 ++++++++-
 guix/scripts/publish.scm      | 39 +++++++++++++++++++++++++-------
 nix/nix-daemon/guix-daemon.cc | 42 ++++++++++++++++++++++++++++++-----
 3 files changed, 78 insertions(+), 14 deletions(-)


base-commit: 0996d48d0e79a360e0d5583b812cd565f62ca32e

Comments

M April 9, 2022, 9:19 a.m. UTC | #1
Ludovic Courtès schreef op za 09-04-2022 om 11:12 [+0200]:
>   publish: Support systemd-style socket activation.

Does this imply that, at least when avahi/--advertise isn't used,
"guix publish" can be run in a container without network access,
in a container that only has access to /gnu/store, the private/public
key and wherever the nars are stored?

Greetings,
Maxime.
Ludovic Courtès April 9, 2022, 8:30 p.m. UTC | #2
Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op za 09-04-2022 om 11:12 [+0200]:
>>   publish: Support systemd-style socket activation.
>
> Does this imply that, at least when avahi/--advertise isn't used,
> "guix publish" can be run in a container without network access,
> in a container that only has access to /gnu/store, the private/public
> key and wherever the nars are stored?

I don’t think it makes any difference.  Or am I misunderstanding?

Ludo’.
M April 9, 2022, 8:49 p.m. UTC | #3
Ludovic Courtès schreef op za 09-04-2022 om 22:30 [+0200]:
> Maxime Devos <maximedevos@telenet.be> skribis:
> 
> > Ludovic Courtès schreef op za 09-04-2022 om 11:12 [+0200]:
> > >   publish: Support systemd-style socket activation.
> > 
> > Does this imply that, at least when avahi/--advertise isn't used,
> > "guix publish" can be run in a container without network access,
> > in a container that only has access to /gnu/store, the private/public
> > key and wherever the nars are stored?
> 
> I don’t think it makes any difference.  Or am I misunderstanding?

Is ‘it’ = ‘the new socket activation support’, or ‘the avahi/--
advertise option being enabled or not’?

Greetings,
Maxime.
Ludovic Courtès April 10, 2022, 5:34 p.m. UTC | #4
Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op za 09-04-2022 om 22:30 [+0200]:
>> Maxime Devos <maximedevos@telenet.be> skribis:
>> 
>> > Ludovic Courtès schreef op za 09-04-2022 om 11:12 [+0200]:
>> > >   publish: Support systemd-style socket activation.
>> > 
>> > Does this imply that, at least when avahi/--advertise isn't used,
>> > "guix publish" can be run in a container without network access,
>> > in a container that only has access to /gnu/store, the private/public
>> > key and wherever the nars are stored?
>> 
>> I don’t think it makes any difference.  Or am I misunderstanding?
>
> Is ‘it’ = ‘the new socket activation support’, or ‘the avahi/--
> advertise option being enabled or not’?

“It” referred to the long condition you wrote.  :-)

One thing is sure: when ‘--advertise’ is used, we shouldn’t use socket
activation or nothing will be advertised.  Is that what you mean?

Ludo’.
M April 10, 2022, 5:43 p.m. UTC | #5
Ludovic Courtès schreef op zo 10-04-2022 om 19:34 [+0200]:
> Maxime Devos <maximedevos@telenet.be> skribis:
> 
> > Ludovic Courtès schreef op za 09-04-2022 om 22:30 [+0200]:
> > > Maxime Devos <maximedevos@telenet.be> skribis:
> > > 
> > > > Ludovic Courtès schreef op za 09-04-2022 om 11:12 [+0200]:
> > > > >   publish: Support systemd-style socket activation.
> > > > 
> > > > Does this imply that, at least when avahi/--advertise isn't used,
> > > > "guix publish" can be run in a container without network access,
> > > > in a container that only has access to /gnu/store, the private/public
> > > > key and wherever the nars are stored?
> > > 
> > > I don’t think it makes any difference.  Or am I misunderstanding?
> > 
> > Is ‘it’ = ‘the new socket activation support’, or ‘the avahi/--
> > advertise option being enabled or not’?
> 
> “It” referred to the long condition you wrote.  :-)
> 
> One thing is sure: when ‘--advertise’ is used, we shouldn’t use socket
> activation or nothing will be advertised.  Is that what you mean?

No, how would socket activation prevent advertising?  How would guile-
avahi even know that we are doing socket activation?

What I mean was:

  * if guile-avahi sends messages to the network by itself,
    then it cannot be run inside a networkless container,
    otherwise only the container's loopback would receive them.

  * if guile-avahi talks to some daemon via a unix domain socket,
    then no problem

  * IIUC, previously, "guix publish" could not be run inside a network
    container, because it tried to listen by itself (and listening
    to a container's own loopback isn't useful).

  * but in case of socket activation, this problem disappears

  * bonus: except possibly for the secret key material, "guix publish"
    does not have to be started  as root anymore even if uses a
    reserved port such as port 80 (assuming socket activation is used).

Greetings,
Maxime.
Ludovic Courtès April 11, 2022, 9:48 a.m. UTC | #6
Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op zo 10-04-2022 om 19:34 [+0200]:

[...]

>> One thing is sure: when ‘--advertise’ is used, we shouldn’t use socket
>> activation or nothing will be advertised.  Is that what you mean?
>
> No, how would socket activation prevent advertising?

As currently implemented in the Shepherd, socket activation means that
the process is started lazily, the first time a connection request is
made.  If the ‘guix publish’ process isn’t started, then DNS-SD
publication doesn’t happen.

> How would guile- avahi even know that we are doing socket activation?
>
> What I mean was:
>
>   * if guile-avahi sends messages to the network by itself,
>     then it cannot be run inside a networkless container,
>     otherwise only the container's loopback would receive them.
>
>   * if guile-avahi talks to some daemon via a unix domain socket,
>     then no problem

Guile-Avahi talks to avahi-daemon over a Unix-domain socket;
avahi-daemon then does the actual mDNS/DNS-SD publication.

>   * IIUC, previously, "guix publish" could not be run inside a network
>     container, because it tried to listen by itself (and listening
>     to a container's own loopback isn't useful).
>
>   * but in case of socket activation, this problem disappears

Well, shepherd, as an ordinary process in the container, would also try
to listen by itself.  But I think that’s fine; worst thing is nobody
ever connects to that socket, but that’s ok, no?

>   * bonus: except possibly for the secret key material, "guix publish"
>     does not have to be started  as root anymore even if uses a
>     reserved port such as port 80 (assuming socket activation is used).

But it does need to access the secret key…

Ludo’.
M April 11, 2022, 10:06 a.m. UTC | #7
Ludovic Courtès schreef op ma 11-04-2022 om 11:48 [+0200]:
> >    * bonus: except possibly for the secret key material, "guix
> > publish"
> >      does not have to be started  as root anymore even if uses a
> >      reserved port such as port 80 (assuming socket activation is
> > used).
> 
> But it does need to access the secret key…

The ‘guix publish’ could be run as a separate, say, guix-publish user,
and the secret key could be made readable to guix-publish.

Alternatively, the shepherd could open the secret key file on behalf of
‘guix publish’ and send it together with the listening socket to ‘guix
publish’.

Greetings,
Maxime.
M April 11, 2022, 10:08 a.m. UTC | #8
Ludovic Courtès schreef op ma 11-04-2022 om 11:48 [+0200]:
> >    * IIUC, previously, "guix publish" could not be run inside a
> > network
> >      container, because it tried to listen by itself (and listening
> >      to a container's own loopback isn't useful).
> > 
> >    * but in case of socket activation, this problem disappears
> 
> Well, shepherd, as an ordinary process in the container,

I meant running ‘guix publish’ inside a container, not shepherd as a
whole in a container.  Basically, make-forkexec-constructor/container,
but for socket activation.

>  would also try to listen by itself.  But I think that’s fine; worst
> thing is nobody ever connects to that socket, but that’s ok, no?

If nobody every connects to the socket of ‘guix publish’, then ‘guix
publish’ is useless.

Greetings,
Maxime.
M April 11, 2022, 10:10 a.m. UTC | #9
Ludovic Courtès schreef op ma 11-04-2022 om 11:48 [+0200]:
> > > One thing is sure: when ‘--advertise’ is used, we shouldn’t use
> > > socket
> > > activation or nothing will be advertised.  Is that what you mean?
> > 
> > No, how would socket activation prevent advertising?
> 
> As currently implemented in the Shepherd, socket activation means
> that
> the process is started lazily, the first time a connection request is
> made.  If the ‘guix publish’ process isn’t started, then DNS-SD
> publication doesn’t happen.

Right, the DNS-SD publication would only happen when ‘guix publish’ is
contacted directly, e.g. somebody doing "guix build --substitute-
urls=http://...".

Greetings,
Maxime.
Ludovic Courtès April 11, 2022, 8:33 p.m. UTC | #10
Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op ma 11-04-2022 om 11:48 [+0200]:
>> >    * bonus: except possibly for the secret key material, "guix
>> > publish"
>> >      does not have to be started  as root anymore even if uses a
>> >      reserved port such as port 80 (assuming socket activation is
>> > used).
>> 
>> But it does need to access the secret key…
>
> The ‘guix publish’ could be run as a separate, say, guix-publish user,
> and the secret key could be made readable to guix-publish.

That doesn’t sound reasonable.

> Alternatively, the shepherd could open the secret key file on behalf of
> ‘guix publish’ and send it together with the listening socket to ‘guix
> publish’.

Sure, that’s feasible, but that’d require a custom protocol that I’d
rather avoid.

As things are now, ‘guix publish’ drops privileges as soon as it has
opened the signing key anyway.

Ludo’.
Ludovic Courtès April 11, 2022, 8:34 p.m. UTC | #11
Maxime Devos <maximedevos@telenet.be> skribis:

> I meant running ‘guix publish’ inside a container, not shepherd as a
> whole in a container.  Basically, make-forkexec-constructor/container,
> but for socket activation.

Oh, I see; that’s future work (the existing
‘make-forkexec-constructor/container’ is not composable, we need
something else.)

Ludo’.
M April 12, 2022, 8:42 a.m. UTC | #12
Ludovic Courtès schreef op ma 11-04-2022 om 22:33 [+0200]:
> > Alternatively, the shepherd could open the secret key file on
> > behalf of
> > ‘guix publish’ and send it together with the listening socket to
> > ‘guix
> > publish’.
> 
> Sure, that’s feasible, but that’d require a custom protocol that I’d
> rather avoid.

I don't think it does, as long as we are using Shepherd and not SystemD
(I don't think that SystemD supports opening regular files instead of
sockets?), we could just 

  * extend 'endpoint->listening-socket' (in Shepherd) to allow opening
    regular files (and not only actual sockets)
  * in 'systemd-socket' (in (guix scripts publish)), expect two startup
    file descriptors instead of one startup file descriptor, and return
    both (the first one is the actual listening socket, the second one
    the secret key file)
  * modify 'guix-publish' appropriately
  * modify the guix-publish service to pass the file descriptor of the
    secret key file in addition to listening socket.

Greetings,
Maxime.
M April 12, 2022, 8:48 a.m. UTC | #13
Ludovic Courtès schreef op ma 11-04-2022 om 22:33 [+0200]:
> > Ludovic Courtès schreef op ma 11-04-2022 om 11:48 [+0200]:
> > > >    * bonus: except possibly for the secret key material, "guix
> > > > publish"
> > > >      does not have to be started  as root anymore even if uses
> > > > a
> > > >      reserved port such as port 80 (assuming socket activation
> > > > is
> > > > used).
> > > 
> > > But it does need to access the secret key…
> > 
> > The ‘guix publish’ could be run as a separate, say, guix-publish
> > user,
> > and the secret key could be made readable to guix-publish.
> 
> That doesn’t sound reasonable.

Why not?  ‘guix publish’ needs read access to the secret key anyway. 
Though then (if done with chown) ‘guix publish’ could modify the secret
key file, so maybe instead of making it ‘owned’ by the 'guix-publish'
user, maybe just set an ACL to allow read access from ‘guix-publish’
but not write access?

Though that seems to be more complex than just letting ‘guix publish’
open the file and change users by itself, so maybe not.

Greetings,
Maxime.
Ludovic Courtès April 12, 2022, 10:15 a.m. UTC | #14
Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op ma 11-04-2022 om 22:33 [+0200]:
>> > Alternatively, the shepherd could open the secret key file on
>> > behalf of
>> > ‘guix publish’ and send it together with the listening socket to
>> > ‘guix
>> > publish’.
>> 
>> Sure, that’s feasible, but that’d require a custom protocol that I’d
>> rather avoid.
>
> I don't think it does, as long as we are using Shepherd and not SystemD
> (I don't think that SystemD supports opening regular files instead of
> sockets?), we could just 
>
>   * extend 'endpoint->listening-socket' (in Shepherd) to allow opening
>     regular files (and not only actual sockets)
>   * in 'systemd-socket' (in (guix scripts publish)), expect two startup
>     file descriptors instead of one startup file descriptor, and return
>     both (the first one is the actual listening socket, the second one
>     the secret key file)

We could, but like I wrote, I’d rather stick to the existing systemd (or
inetd) protocol, especially since this extension wouldn’t buy us much IMO.

Ludo’.