Subject: Re: [bug#77288] [PATCH v2 7/8] services: guix: Allow‘guix-daemon’to run without root privileges.

From: Ludovic Courtès <[email-masked]>
Date: Mon, 21 Apr 2025 12:11:03 +0200

Hello,

Maxim Cournoyer <[email-masked]> writes:

>> This procedure emulates lchown(2), for which Guile does not provide
>> bindings.
>
> OK.  Perhaps it should?  We could report to bug-guile and here add a
> comment pointing to the issue to remind us to export it in Guile and use
> it when it's there in the future.

Yes, we should do that.

>>> Likewise.  Also, I never remember why `in-vicinity' is useful, and it's
>>> not documented anywhere.
>>
>> It.s more concise and more accurate than (string-append a "/" b).
>> I.ve come to use it more.
>
> It's problematic that it's not documented though.  Grepping the guile
> source shouldn't be needed to understand the code, ideally.  The
> 'in-vicinity' name also suggests it might do something cleverer than
> just concatenating strings.

It’s “clever” in that it appends a slash only if needed.  That’s the
extent of its cleverness :-) but it’s nice.

>> C.UTF-8 is now always available (embedded in our libc), but the default
>> is always C.
>
> Uh.  Are there plans to change this in the future?  It seems we're well
> into the Unicode age :-).

It’s a POSIX issue though: processes always start out under the C locale
and have to call setlocale(3) to change that.

>>>>                                  (start-service 'guix-daemon))
>>>
>>> Are you sure this translates to 'wait for X to be up?'
>>
>> Yes, and many system tests use this idiom.  You can experience it,
>> assuming you have a system that takes a long enough to start, by running
>> .herd start X & herd start X.: one client will just wait for the other.
>
> That surprises me, because I thought I recently observed some problem
> with the use of 'start-service' in our test suite.  Perhaps the issue
> was that simply asserting against 'start-service', without checking that
> the returned service object 'running' slot is set to #t doesn't guard
> against when the service fails to start, which is what is currently done
> in many places.  Right?

Waiting for ‘start-service’ to complete guarantees that the attempt to
start the service has completed, and checking its return value lets you
know whether it has succeeded.

Here’s an example with my user shepherd, where ‘redshift’ was already
running and ‘failing’ was stopped but its ‘start’ method is (const #f):

--8<---------------cut here---------------start------------->8---
scheme@(gnu services herd)> (parameterize ((%shepherd-socket-file "/run/user/1000/shepherd/socket")) (start-service 'redshift))
shepherd: Service redshift is already running.
$7 = (service (version 0) (provides (redshift)) (requires (x11-display)) (respawn? #t) (docstring "Redshift program.") (enabled? #t) (running (process (version 0) (id 2691) (command ("/gnu/store/arj5gvqdi3j9kbpk9vjdh5l0gk1gaqsh-redshift-1.12/bin/redshift" "-c" "/gnu/store/lj6ajc15a3i7q198hb69gsda8dcxzh6f-redshift.conf")))) (conflicts ()) (last-respawns ()) (status-changes (…)) (startup-failures ()) (status running) (one-shot? #f) (transient? #f) (respawn-limit (5 . 7)) (respawn-delay 0.1) (actions (configuration)) (exit-statuses ((0 . 1745228665) …)) (recent-messages ((1745228689 . "Location: …") (1745228689 . "Waiting for initial location to become available..."))) (log-files ()) (pending-replacement? #f))
scheme@(gnu services herd)> (parameterize ((%shepherd-socket-file "/run/user/1000/shepherd/socket")) (start-service 'failing))
shepherd: Starting service failing...
shepherd: Service failing failed to start.
shepherd: Service failing could not be started.
$8 = #f
--8<---------------cut here---------------end--------------->8---

If we get the full-blown service sexp, as in the ‘redshift’ example, it
means that the service is ‘started’.

Ludo’.