unofficial mirror of help-guix@gnu.org 
 help / color / mirror / Atom feed
From: Jonathan McHugh <indieterminacy@libre.brussels>
To: help-guix@gnu.org
Subject: Re: Environment of a shepherd service
Date: Tue, 13 Apr 2021 22:47:58 +0200	[thread overview]
Message-ID: <87k0p5lxmp.fsf@libre.brussels> (raw)
In-Reply-To: <87lf9mosf4.fsf@rdklein.fr>

Did you read this blog post?:
https://guix.gnu.org/en/blog/2020/gnu-shepherd-user-services/

====== START ========
The GNU Shepherd manual suggests putting all the services inside a monolithic init.scm file, located by default at $XDG_CONFIG_DIR/shepherd/init.scm. While this does make it easy to keep everything in one place, it does create one glaring issue: any changes to the file mean that all the services need to be stopped and restarted in order for any changes to take place.

Luckily there's a nice function called scandir hiding in ice-9 ftw which returns a list of all files in a specified directory (with options for narrowing down the list or sorting it). This means that our init.scm can contain a minimum of code and all actual services can be loaded from individual files.

First the minimal init.scm:

(use-modules (shepherd service)
             ((ice-9 ftw) #:select (scandir)))

;; Load all the files in the directory 'init.d' with a suffix '.scm'.
(for-each
  (lambda (file)
    (load (string-append "init.d/" file)))
  (scandir (string-append (dirname (current-filename)) "/init.d")
           (lambda (file)
             (string-suffix? ".scm" file))))

;; Send shepherd into the background
(action 'shepherd 'daemonize)

Let's take a sample service for running syncthing, as defined in $XDG_CONFIG_DIR/shepherd/init.d/syncthing.scm:

(define syncthing
  (make <service>
    #:provides '(syncthing)
    #:docstring "Run `syncthing' without calling the browser"
    #:start (make-forkexec-constructor
              '("syncthing" "-no-browser")
              #:log-file (string-append (getenv "HOME")
                                        "/log/syncthing.log"))
    #:stop (make-kill-destructor)
    #:respawn? #t))
(register-services syncthing)

(start syncthing)

As with any other shepherd service it is defined and registered, and in
this case it will start automatically. When the file is loaded by
shepherd after being discovered by scandir everything works exactly as
though the service definition were located directly inside the init.scm.

======== END =======


HTH


Edouard Klein <edou@rdklein.fr> writes:

> Hi,
>
> So I looked at the source and I understand that there's no way around
> having only PATH=/run/current-system/profile/bin as the sole environment
> of a service (which makes me wonder how anyone is running any service in
> GuixSD, don't you need any env variables ?).
>
> I tried to define a trivial package that would use wrap-program to
> create a script that would set the environment variables to all the
> search-paths of my requisomatic package, but I don't know how to access
> those !
>
> In the code that is executed by the daemon, all references to the
> package are lost, it is not in the same strata as the package.
>
> I can get the store path to the package but that does not help me.
>
> I really could use some guidance here.
>
> Cheers,
>
> Edouard.
> edk@beaver-labs.com writes:
>
>> Dear fellow Guixers,
>>
>> I'm trying to create an operating system declaration, so that I can run
>> a piece of software of mine in a container with =guix system container=.
>>
>> I wrote a package for the software. The package works: the tests pass
>> and when the package is installed I can run the software.
>>
>> I wrote a shepherd service for the software (it's called requisomatic).
>> I copied the relevant part at the end of the email.
>>
>> When I run the container script created by =guix system container=, and
>> get a shell in the container, I can run the software (I added the software's
>> package to the globally installed packages in the operating-system definition).
>>
>> But, when I try to run it with shepherd, it fails because it can't find
>> flask (a dependency of the software, which I've put as a
>> propagated-input, and is indeed installed in the container).
>>
>> I replaced the software invocation in the shepherd service with just
>> "env", and saw that the whole env in the service is:
>>
>> PATH=/run/current-system/profile/bin
>>
>> whereas in the shell I get when I connect to the container, the env
>> contains many other variables, including a correctly set PYTHONPATH,
>> which allows the finding of flask.
>>
>> So I now know why my software is not starting, but my question is:
>>
>> Why is the PYTHONPATH (and the other env vars, for that matter) not
>> propagated from the package to the shepherd service by default ? And how
>> can I make it so ? I would have expected the shepherd service to run
>> with the global profile active.
>>
>> Follow up question, can shepherd services be specified to run in a
>> specific profile ? So that I can have two services with incompatible
>> dependencies running at the same time in the same operating-system ?
>>
>> Thanks in advance,
>>
>> Cheers,
>>
>> Edouard.
>>
>>
>>
>> -----extract from my operating-system declaration file-------
>> (define requisomatic-shepherd-service
>>   (match-lambda
>>     (($ <requisomatic-configuration> user group db-file)
>>      (list (shepherd-service
>>             (provision '(requisomatic))
>>             (requirement '(user-processes networking))
>>             (documentation "Run the requisomatic server")
>>             (start #~((make-forkexec-constructor
>>                     ;;   (append
>>                     ;;    (if db-file
>>                     ;;      `("env"
>>                     ;;        ,(string-append "REQUISOMATIC_DB_FILE=" db-file))
>>                     ;;      '())
>>                                         '("gunicorn" "requisomatic:app")
>>                    ;;   '("env")
>>                        ;;)
>>                        #:directory (string-append #$requisomatic "/bin/requisomatic/")
>>                        #:log-file "/var/log/requisomatic.log")))
>>             (stop #~(make-kill-destructor)))))))


-- 
Jonathan McHugh
indieterminacy@libre.brussels


  reply	other threads:[~2021-04-13 21:40 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-11 19:31 Environment of a shepherd service edk
2021-04-13 20:12 ` Edouard Klein
2021-04-13 20:47   ` Jonathan McHugh [this message]
2021-04-14  7:59     ` Edouard Klein
2021-04-25 15:36 ` Maxime Devos
2021-04-27 20:03   ` Edouard Klein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k0p5lxmp.fsf@libre.brussels \
    --to=indieterminacy@libre.brussels \
    --cc=help-guix@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).