aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017, 2018, 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Mathieu Othacehe <othacehe@gnu.org>
;;; Copyright © 2022 Leo Nikkilä <hello@lnikki.la>
;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu build shepherd)
  #:use-module (gnu system file-systems)
  #:use-module (gnu build linux-container)
  #:use-module (guix build utils)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:use-module (ice-9 match)
  ;; XXX: Lazy-bind the Shepherd to avoid a compile-time dependency.
  #:autoload (shepherd service) (fork+exec-command
                                 read-pid-file
                                 exec-command
                                 %precious-signals)
  #:autoload (shepherd system) (unblock-signals)
  #:export (default-mounts
            fork+exec-command/container))

;;; Commentary:
;;;
;;; This module provides extensions to the GNU Shepherd.  In particular, it
;;; provides a helper to start services in a container.
;;;
;;; Code:

(define (clean-up file)
  (when file
    (catch 'system-error
      (lambda ()
        (delete-file file))
      (lambda args
        (unless (= ENOENT (system-error-errno args))
          (apply throw args))))))

(define-syntax-rule (catch-system-error exp)
  (catch 'system-error
    (lambda ()
      exp)
    (const #f)))

(define (default-namespaces args)
  ;; Most daemons are here to talk to the network, and most of them expect to
  ;; run under a non-zero UID.
  (fold delq %namespaces '(net user)))

(define* (default-mounts #:key (namespaces (default-namespaces '())))
  (define (tmpfs directory)
    (file-system
      (device "none")
      (mount-point directory)
      (type "tmpfs")
      (check? #f)))

  (define accounts
    ;; This is for processes in the default user namespace but living in a
    ;; different mount namespace, so that they can lookup users.
    (list (file-system-mapping
           (source "/etc/passwd") (target source))
          (file-system-mapping
           (source "/etc/group") (target source))))

  (append (cons (tmpfs "/tmp") %container-file-systems)
          (let ((mappings `(,@(if (memq 'net namespaces)
                                  '()
                                  %network-file-mappings)
                            ,@(if (and (memq 'mnt namespaces)
                                       (not (memq 'user namespaces)))
                                  accounts
                                  '())

                            ;; Tell the process what timezone we're in.  This
                            ;; makes sure that, for instance, its syslog
                            ;; messages have the correct timestamp.
                            ,(file-system-mapping
                              (source "/etc/localtime")
                              (target source))

                            ,%store-mapping)))    ;XXX: coarse-grain
            (map file-system-mapping->bind-mount
                 (filter (lambda (mapping)
                           (file-exists? (file-system-mapping-source mapping)))
                         mappings)))))

(define* (exec-command* command #:key user group log-file pid-file
                        (supplementary-groups '())
                        (directory "/") (environment-variables (environ)))
  "Like 'exec-command', but first restore signal handles modified by
shepherd (PID 1)."
  ;; First restore the default handlers.
  (for-each (cut sigaction <> SIG_DFL) %precious-signals)

  ;; Unblock any signals that have been blocked by the parent process.
  (unblock-signals %precious-signals)

  (mkdir-p "/var/run")
  (clean-up pid-file)

  (exec-command command
                #:user user
                #:group group
                #:supplementary-groups supplementary-groups
                #:log-file log-file
                #:directory directory
                #:environment-variables environment-variables))

(define* (fork+exec-command/container command
                                      #:key pid
                                      #:allow-other-keys
                                      #:rest args)
  "This is a variant of 'fork+exec-command' procedure, that joins the
namespaces of process PID beforehand.  If there is no support for containers,
on Hurd systems for instance, fallback to direct forking."
  (define (strip-pid args)
    ;; TODO: Replace with 'strip-keyword-arguments' when that no longer pulls
    ;; in (guix config).
    (let loop ((args args)
               (result '()))
      (match args
        (()
         (reverse result))
        ((#:pid _ . rest)
         (loop rest result))
        ((head . rest)
         (loop rest (cons head result))))))

  (let ((container-support? (file-exists? "/proc/self/ns")))
    (if (and container-support?
             (not (and pid (= pid (getpid)))))
        (container-excursion* pid
          (lambda ()
            ;; Note: In the Shepherd 0.9, 'fork+exec-command' expects to be
            ;; called from the shepherd process (because it creates a pipe to
            ;; capture stdout/stderr and spawns a logging fiber) so we cannot
            ;; use it here.
            (match (primitive-fork)
              (0 (dynamic-wind
                   (const #t)
                   (lambda ()
                     (apply exec-command* command (strip-pid args)))
                   (lambda ()
                     (primitive-_exit 127))))
              (pid pid))))               ;XXX: assuming the same PID namespace
        (apply fork+exec-command command (strip-pid args)))))

;; Local Variables:
;; eval: (put 'container-excursion* 'scheme-indent-function 1)
;; End:

;;; shepherd.scm ends here
gsubject'>guix-install.sh: Time out fetching OpenPGP keys.Tobias Geerinckx-Rice The default 900s provide no useful backstop in interactive use. * etc/guix-install.sh (chk_gpg_keyring): Add a 30s wget --timeout. 2022-10-17news: Add 'pt' translation.Thiago Jung Bauermann * etc/news.scm: Add Portuguese translation of entry about the new --emulate-fhs option. Signed-off-by: Julien Lepiller <julien@lepiller.eu> 2022-10-14news: Add 'de' translation.Florian Pelz * etc/news.scm: Add German translation of '--emulate-fhs' entry. 2022-10-13news: Add entry for 'guix shell --emulate-fhs'.Ludovic Courtès * etc/news.scm: Add entry. 2022-10-11guix-install.sh: Restore compatibility with "yes" invocation.Maxim Cournoyer Commit 6a2e303d3a had modified prompt_yes_no to only read a single character, aiming to ease the user experience. This was, in retrospect, a bad idea, as it makes user input error more likely and introduces complexity. This commit reverts to line-oriented input, while preserving the default yes value so that a user can simply hit 'Enter' at the prompt in place of typing "yes". * etc/guix-install.sh (_flush): Delete function. (prompt_yes_no): Restore line-oriented read. Remove loop. Make anything else than yes means no. Use Bash features to streamline definition. Reported-by: Lars-Dominik Braun <lars@6xq.net> and others. 2022-10-07guix-install.sh: Add Bash prompt customization option.Maxim Cournoyer Fixes <https://issues.guix.gnu.org/55484>. * etc/guix-install.sh (sys_customize_bashrc): New function. (main): Use it. 2022-10-07guix-install.sh: Introduce 'die' utility function.Maxim Cournoyer * etc/guix-install.sh (die): New function. (chk_sys_arch): Use it. (guix_get_bin_list, guix_get_bin, sys_create_store): Likewise. 2022-10-07guix-install.sh: Improve prompt_yes_no procedure.Maxim Cournoyer * etc/guix-install.sh (_flush): New function. (prompt_yes_no): Clear input, then only read the first character, silently. Add the [Yes/no] string to the message. When a newline is entered by the user, treat it as the default value, which is "yes". (chk_gpg_keyring): Remove "(yes/no)" from the prompt message. (configure_substitute_discovery): Likewise. (sys_authorize_build_farms): Likewise. 2022-10-06snippets: Fix move.Liliana Marie Prikler The current move is never correct. It flip-flops between car and cadr for the destination. Since the position of the destination is not actually a fixed point in the list of changes, use a more robust method of inferring it. * etc/snippets/tempel/text-mode (move\ ): Infer source and destination from washed diffs. Process new module before destination. 2022-10-06snippets: tempel: Reformat.Liliana Marie Prikler This makes it so that ‘indent-region’ and ‘delete-trailing-whitespace’ do not change the file. * etc/snippets/tempel/text-mode: Reformat. 2022-10-06snippets: tempel: Fix calls to mapconcat.Liliana Marie Prikler * etc/snippets/tempel/text-mode (update\ ,https\ ): Add "\n" as separator argument to mapconcat. 2022-10-03news: Add 'pt' translation.Thiago Jung Bauermann * etc/news.scm: Add Portuguese translation of entry about the --with-source option being recursive. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-10-03etc: teams: Add news.scm to translations team scope.Thiago Jung Bauermann * etc/teams.scm.in (translations)[#:scope]: Add etc/news.scm. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-10-01news: Add 'de' translation.Florian Pelz * etc/news.scm: Add German translation of '--with-source' entry. 2022-09-29news: Add entry for '--with-source'.Jesse Gibbons * etc/news.scm: Add entry. Co-authored-by: Ludovic Courtès <ludo@gnu.org> 2022-09-28teams: Add Simon Tournier.zimoun * etc/teams.scm.in: Add Simon Tournier. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-28etc: teams: Add (.( * etc/teams.scm.in: Add (. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-28etc: teams: Add more scopes to teams.( * etc/teams.scm.in (r, julia, ruby, go, rust, kernel, translations, home, mozilla, racket): Add scopes. (emacs)[scope]: Add ``guix import elpa''-related files. (installer)[scope]: Correct ``guix/installer'' to ``gnu/installer''. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-28news: Add 'pt' translation.Thiago Jung Bauermann * etc/news.scm: Add Portuguese translation of entries about WSL system images and about Guix System image API documentation. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-27teams: Add pukkamustard.pukkamustard * etc/teams.scm.in: Add pukkamustard. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-27teams: Add Josselin Poiret.Josselin Poiret * etc/teams.scm.in: Add Josselin Poiret. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-26etc: Add tempel snippet move.Nicolas Graves * etc/snippets/tempel/text-mode (move\): New entry. Signed-off-by: Ludovic Courtès <ludo@gnu.org> 2022-09-26news: Add another 'de' translation.Florian Pelz * etc/news.scm: Add German translation of images API entry. 2022-09-26news: Add 'de' translation.Florian Pelz * etc/news.scm: Add German translation of WSL images entry. 2022-09-26etc: teams: Add description and scope for lisp team.Guillaume Le Vaillant * etc/teams.scm.in (lisp): Add description and scope fields. 2022-09-25etc: teams: Give games a scope.Liliana Marie Prikler * etc/teams.scm.in (games)[#:name]: Change to “Games and Toys”. [#:description, #:scope]: New fields. 2022-09-25etc: teams: Add description and scope for emacs.Liliana Marie Prikler * etc/teams.scm.in (emacs): Add #:description and #:scope. 2022-09-25etc: teams: Define Java team scope.Julien Lepiller * etc/teams.scm.in (java): Define it. 2022-09-25etc: teams: Define OCaml team scope.Julien Lepiller * etc/teams.scm.in (ocaml): Define it. 2022-09-25news: Add entry about image API documentation.Mathieu Othacehe * etc/news.scm: Add entry. 2022-09-25news: Add entry about WSL images.Mathieu Othacehe * etc/news.scm: Add entry. 2022-09-25etc: teams: Define python team scope.Lars-Dominik Braun * etc/teams.scm.in (python): Define it. 2022-09-25etc: teams: Define haskell team scope.Lars-Dominik Braun * etc/teams.scm.in (haskell): Define it. 2022-09-25etc: installer: Define installer team scope.Mathieu Othacehe * etc/teams.scm.in (installer): Define it. 2022-09-25etc: teams: Define core team scope.Mathieu Othacehe * etc/teams.scm.in (core): Define it. 2022-09-25etc: teams: Add regular expression support to scopes.Liliana Marie Prikler * etc/teams.scm (find-teams-by-scope): Differentiate between raw strings and regexps. Make raw string matches strict. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> 2022-09-25etc: teams: Add scope support.Mathieu Othacehe Add a scope list to each team. This list defines all the files and directories that are mentored by the team. Also add a cc-members command that takes two Git revision strings as input, add returns the members that should be CC'ed given the files impacted between the two revisions. * etc/teams.scm.in (<team>)[scope]: New field. (team, list-teams): Adapt those procedures. (find-team-by-scope, diff-revisions): New procedures. (main): Add a "cc-members" command. * doc/contributing.texi ("Teams"): Document it. ("Sending a Patch Series"): Adapt it.