summaryrefslogtreecommitdiff
path: root/gnu/services
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/avahi.scm2
-rw-r--r--gnu/services/base.scm279
-rw-r--r--gnu/services/databases.scm4
-rw-r--r--gnu/services/dbus.scm4
-rw-r--r--gnu/services/desktop.scm11
-rw-r--r--gnu/services/dict.scm2
-rw-r--r--gnu/services/mail.scm14
-rw-r--r--gnu/services/networking.scm27
-rw-r--r--gnu/services/nfs.scm54
-rw-r--r--gnu/services/sddm.scm318
-rw-r--r--gnu/services/spice.scm2
-rw-r--r--gnu/services/ssh.scm133
-rw-r--r--gnu/services/web.scm6
-rw-r--r--gnu/services/xorg.scm13
14 files changed, 737 insertions, 132 deletions
diff --git a/gnu/services/avahi.scm b/gnu/services/avahi.scm
index 807cc05a22..60e9e61f94 100644
--- a/gnu/services/avahi.scm
+++ b/gnu/services/avahi.scm
@@ -88,7 +88,7 @@
(system? #t)
(comment "Avahi daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define %avahi-activation
;; Activation gexp.
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index f3f6408687..afbecdb47e 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -39,6 +39,7 @@
#:use-module (gnu packages package-management)
#:use-module (gnu packages ssh)
#:use-module (gnu packages lsof)
+ #:use-module (gnu packages terminals)
#:use-module ((gnu build file-systems)
#:select (mount-flags->bit-mask))
#:use-module (guix gexp)
@@ -57,6 +58,8 @@
session-environment-service-type
host-name-service
console-keymap-service
+ %default-console-font
+ console-font-service-type
console-font-service
udev-configuration
@@ -66,6 +69,11 @@
udev-service
udev-rule
+ login-configuration
+ login-configuration?
+ login-service-type
+ login-service
+
mingetty-configuration
mingetty-configuration?
mingetty-service
@@ -82,6 +90,9 @@
nscd-service-type
nscd-service
+
+ syslog-configuration
+ syslog-configuration?
syslog-service
syslog-service-type
%default-syslog.conf
@@ -108,6 +119,11 @@
rngd-configuration?
rngd-service-type
rngd-service
+
+ kmscon-configuration
+ kmscon-configuration?
+ kmscon-service-type
+
pam-limits-service-type
pam-limits-service
@@ -513,7 +529,7 @@ stopped before 'kill' is called."
(define device (rngd-configuration-device config))
(define rngd-command
- (list #~(string-append #$rng-tools "/sbin/rngd")
+ (list (file-append rng-tools "/sbin/rngd")
"-f" "-r" device))
(shepherd-service
@@ -621,37 +637,83 @@ strings or string-valued gexps."
"Return a service to load console keymaps from @var{files}."
(service console-keymap-service-type files))
-(define console-font-service-type
- (shepherd-service-type
- 'console-font
- (match-lambda
- ((tty font)
- (let ((device (string-append "/dev/" tty)))
- (shepherd-service
- (documentation "Load a Unicode console font.")
- (provision (list (symbol-append 'console-font-
- (string->symbol tty))))
-
- ;; Start after mingetty has been started on TTY, otherwise the settings
- ;; are ignored.
- (requirement (list (symbol-append 'term-
- (string->symbol tty))))
+(define %default-console-font
+ ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
+ ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
+ ;; codepoints notably found in the UTF-8 manual.
+ "LatGrkCyr-8x16")
+
+(define (console-font-shepherd-services tty+font)
+ "Return a list of Shepherd services for each pair in TTY+FONT."
+ (map (match-lambda
+ ((tty . font)
+ (let ((device (string-append "/dev/" tty)))
+ (shepherd-service
+ (documentation "Load a Unicode console font.")
+ (provision (list (symbol-append 'console-font-
+ (string->symbol tty))))
+
+ ;; Start after mingetty has been started on TTY, otherwise the settings
+ ;; are ignored.
+ (requirement (list (symbol-append 'term-
+ (string->symbol tty))))
+
+ (start #~(lambda _
+ (and #$(unicode-start device)
+ (zero?
+ (system* (string-append #$kbd "/bin/setfont")
+ "-C" #$device #$font)))))
+ (stop #~(const #t))
+ (respawn? #f)))))
+ tty+font))
- (start #~(lambda _
- (and #$(unicode-start device)
- (zero?
- (system* (string-append #$kbd "/bin/setfont")
- "-C" #$device #$font)))))
- (stop #~(const #t))
- (respawn? #f)))))))
+(define console-font-service-type
+ (service-type (name 'console-fonts)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ console-font-shepherd-services)))
+ (compose concatenate)
+ (extend append)))
(define* (console-font-service tty #:optional (font "LatGrkCyr-8x16"))
- "Return a service that sets up Unicode support in @var{tty} and loads
+ "This procedure is deprecated in favor of @code{console-font-service-type}.
+
+Return a service that sets up Unicode support in @var{tty} and loads
@var{font} for that tty (fonts are per virtual console in Linux.)"
- ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
- ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
- ;; codepoints notably found in the UTF-8 manual.
- (service console-font-service-type (list tty font)))
+ (simple-service (symbol-append 'console-font- (string->symbol tty))
+ console-font-service-type `((,tty . ,font))))
+
+(define %default-motd
+ (plain-file "motd" "This is the GNU operating system, welcome!\n\n"))
+
+(define-record-type* <login-configuration>
+ login-configuration make-login-configuration
+ login-configuration?
+ (motd login-configuration-motd ;file-like
+ (default %default-motd))
+ ;; Allow empty passwords by default so that first-time users can log in when
+ ;; the 'root' account has just been created.
+ (allow-empty-passwords? login-configuration-allow-empty-passwords?
+ (default #t))) ;Boolean
+
+(define (login-pam-service config)
+ "Return the list of PAM service needed for CONF."
+ ;; Let 'login' be known to PAM.
+ (list (unix-pam-service "login"
+ #:allow-empty-passwords?
+ (login-configuration-allow-empty-passwords? config)
+ #:motd
+ (login-configuration-motd config))))
+
+(define login-service-type
+ (service-type (name 'login)
+ (extensions (list (service-extension pam-root-service-type
+ login-pam-service)))))
+
+(define* (login-service #:optional (config (login-configuration)))
+ "Return a service configure login according to @var{config}, which specifies
+the message of the day, among other things."
+ (service login-service-type config))
(define-record-type* <mingetty-configuration>
mingetty-configuration make-mingetty-configuration
@@ -659,35 +721,17 @@ strings or string-valued gexps."
(mingetty mingetty-configuration-mingetty ;<package>
(default mingetty))
(tty mingetty-configuration-tty) ;string
- (motd mingetty-configuration-motd ;file-like
- (default (plain-file "motd" "Welcome.\n")))
(auto-login mingetty-auto-login ;string | #f
(default #f))
(login-program mingetty-login-program ;gexp
(default #f))
(login-pause? mingetty-login-pause? ;Boolean
- (default #f))
-
- ;; Allow empty passwords by default so that first-time users can log in when
- ;; the 'root' account has just been created.
- (allow-empty-passwords? mingetty-configuration-allow-empty-passwords?
- (default #t))) ;Boolean
-
-(define (mingetty-pam-service conf)
- "Return the list of PAM service needed for CONF."
- ;; Let 'login' be known to PAM. All the mingetty services will have that
- ;; PAM service, but that's fine because they're all identical and duplicates
- ;; are removed.
- (list (unix-pam-service "login"
- #:allow-empty-passwords?
- (mingetty-configuration-allow-empty-passwords? conf)
- #:motd
- (mingetty-configuration-motd conf))))
+ (default #f)))
(define mingetty-shepherd-service
(match-lambda
- (($ <mingetty-configuration> mingetty tty motd auto-login login-program
- login-pause? allow-empty-passwords?)
+ (($ <mingetty-configuration> mingetty tty auto-login login-program
+ login-pause?)
(list
(shepherd-service
(documentation "Run mingetty on an tty.")
@@ -715,9 +759,7 @@ strings or string-valued gexps."
(define mingetty-service-type
(service-type (name 'mingetty)
(extensions (list (service-extension shepherd-root-service-type
- mingetty-shepherd-service)
- (service-extension pam-root-service-type
- mingetty-pam-service)))))
+ mingetty-shepherd-service)))))
(define* (mingetty-service config)
"Return a service to run mingetty according to @var{config}, which specifies
@@ -885,17 +927,27 @@ given @var{config}---an @code{<nscd-configuration>} object. @xref{Name
Service Switch}, for an example."
(service nscd-service-type config))
+
+(define-record-type* <syslog-configuration>
+ syslog-configuration make-syslog-configuration
+ syslog-configuration?
+ (syslogd syslog-configuration-syslogd
+ (default (file-append inetutils "/libexec/syslogd")))
+ (config-file syslog-configuration-config-file
+ (default %default-syslog.conf)))
+
(define syslog-service-type
(shepherd-service-type
'syslog
- (lambda (config-file)
+ (lambda (config)
(shepherd-service
(documentation "Run the syslog daemon (syslogd).")
(provision '(syslogd))
(requirement '(user-processes))
(start #~(make-forkexec-constructor
- (list (string-append #$inetutils "/libexec/syslogd")
- "--no-detach" "--rcfile" #$config-file)))
+ (list #$(syslog-configuration-syslogd config)
+ "--rcfile" #$(syslog-configuration-config-file config))
+ #:pid-file "/var/run/syslog.pid"))
(stop #~(make-kill-destructor))))))
;; Snippet adapted from the GNU inetutils manual.
@@ -921,14 +973,14 @@ Service Switch}, for an example."
mail.* /var/log/maillog
"))
-(define* (syslog-service #:key (config-file %default-syslog.conf))
- "Return a service that runs @command{syslogd}. If configuration file
-name @var{config-file} is not specified, use some reasonable default
-settings.
+(define* (syslog-service #:optional (config (syslog-configuration)))
+ "Return a service that runs @command{syslogd} and takes
+@var{<syslog-configuration>} as a parameter.
@xref{syslogd invocation,,, inetutils, GNU Inetutils}, for more
information on the configuration file syntax."
- (service syslog-service-type config-file))
+ (service syslog-service-type config))
+
(define pam-limits-service-type
(let ((security-limits
@@ -996,7 +1048,7 @@ starting at FIRST-UID, and under GID."
(comment (format #f "Guix Build User ~2d" n))
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin"))))
+ (shell (file-append shadow "/sbin/nologin"))))
1+
1))
@@ -1023,7 +1075,7 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
(define %default-authorized-guix-keys
;; List of authorized substitute keys.
- (list #~(string-append #$guix "/share/guix/hydra.gnu.org.pub")))
+ (list (file-append guix "/share/guix/hydra.gnu.org.pub")))
(define-record-type* <guix-configuration>
guix-configuration make-guix-configuration
@@ -1154,7 +1206,7 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
(system? #t)
(comment "guix publish user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define guix-publish-service-type
(service-type (name 'guix-publish)
@@ -1419,41 +1471,76 @@ This service is not part of @var{%base-services}."
(service gpm-service-type
(gpm-configuration (gpm gpm) (options options))))
+(define-record-type* <kmscon-configuration>
+ kmscon-configuration make-kmscon-configuration
+ kmscon-configuration?
+ (kmscon kmscon-configuration-kmscon
+ (default kmscon))
+ (virtual-terminal kmscon-configuration-virtual-terminal)
+ (login-program kmscon-configuration-login-program
+ (default #~(string-append #$shadow "/bin/login")))
+ (login-arguments kmscon-configuration-login-arguments
+ (default '("-p")))
+ (hardware-acceleration? kmscon-configuration-hardware-acceleration?
+ (default #f))) ; #t causes failure
+
+(define kmscon-service-type
+ (shepherd-service-type
+ 'kmscon
+ (lambda (config)
+ (let ((kmscon (kmscon-configuration-kmscon config))
+ (virtual-terminal (kmscon-configuration-virtual-terminal config))
+ (login-program (kmscon-configuration-login-program config))
+ (login-arguments (kmscon-configuration-login-arguments config))
+ (hardware-acceleration? (kmscon-configuration-hardware-acceleration? config)))
+
+ (define kmscon-command
+ #~(list
+ (string-append #$kmscon "/bin/kmscon") "--login"
+ "--vt" #$virtual-terminal
+ #$@(if hardware-acceleration? '("--hwaccel") '())
+ "--" #$login-program #$@login-arguments))
+
+ (shepherd-service
+ (documentation "kmscon virtual terminal")
+ (requirement '(user-processes udev dbus-system))
+ (provision (list (symbol-append 'term- (string->symbol virtual-terminal))))
+ (start #~(make-forkexec-constructor #$kmscon-command))
+ (stop #~(make-kill-destructor)))))))
+
(define %base-services
;; Convenience variable holding the basic services.
- (let ((motd (plain-file "motd" "
-This is the GNU operating system, welcome!\n\n")))
- (list (console-font-service "tty1")
- (console-font-service "tty2")
- (console-font-service "tty3")
- (console-font-service "tty4")
- (console-font-service "tty5")
- (console-font-service "tty6")
-
- (mingetty-service (mingetty-configuration
- (tty "tty1") (motd motd)))
- (mingetty-service (mingetty-configuration
- (tty "tty2") (motd motd)))
- (mingetty-service (mingetty-configuration
- (tty "tty3") (motd motd)))
- (mingetty-service (mingetty-configuration
- (tty "tty4") (motd motd)))
- (mingetty-service (mingetty-configuration
- (tty "tty5") (motd motd)))
- (mingetty-service (mingetty-configuration
- (tty "tty6") (motd motd)))
-
- (static-networking-service "lo" "127.0.0.1"
- #:provision '(loopback))
- (syslog-service)
- (urandom-seed-service)
- (guix-service)
- (nscd-service)
-
- ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
- ;; used, so enable them by default. The FUSE and ALSA rules are
- ;; less critical, but handy.
- (udev-service #:rules (list lvm2 fuse alsa-utils crda)))))
+ (list (login-service)
+
+ (service console-font-service-type
+ (map (lambda (tty)
+ (cons tty %default-console-font))
+ '("tty1" "tty2" "tty3" "tty4" "tty5" "tty6")))
+
+ (mingetty-service (mingetty-configuration
+ (tty "tty1")))
+ (mingetty-service (mingetty-configuration
+ (tty "tty2")))
+ (mingetty-service (mingetty-configuration
+ (tty "tty3")))
+ (mingetty-service (mingetty-configuration
+ (tty "tty4")))
+ (mingetty-service (mingetty-configuration
+ (tty "tty5")))
+ (mingetty-service (mingetty-configuration
+ (tty "tty6")))
+
+ (static-networking-service "lo" "127.0.0.1"
+ #:provision '(loopback))
+ (syslog-service)
+ (urandom-seed-service)
+ (guix-service)
+ (nscd-service)
+
+ ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
+ ;; used, so enable them by default. The FUSE and ALSA rules are
+ ;; less critical, but handy.
+ (udev-service #:rules (list lvm2 fuse alsa-utils crda))))
;;; base.scm ends here
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 86847f8c50..1eed85542b 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -76,7 +76,7 @@ host all all ::1/128 trust"))
(system? #t)
(comment "PostgreSQL server user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define postgresql-activation
(match-lambda
@@ -171,7 +171,7 @@ and stores the database cluster in @var{data-directory}."
(group "mysql")
(system? #t)
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define mysql-configuration-file
(match-lambda
diff --git a/gnu/services/dbus.scm b/gnu/services/dbus.scm
index 690561cccd..876f56d45f 100644
--- a/gnu/services/dbus.scm
+++ b/gnu/services/dbus.scm
@@ -128,13 +128,13 @@ includes the @code{etc/dbus-1/system.d} directories of each package listed in
(system? #t)
(comment "D-Bus system bus user")
(home-directory "/var/run/dbus")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define dbus-setuid-programs
;; Return the file name of the setuid program that we need.
(match-lambda
(($ <dbus-configuration> dbus services)
- (list #~(string-append #$dbus "/libexec/dbus-daemon-launch-helper")))))
+ (list (file-append dbus "/libexec/dbus-daemon-launch-helper")))))
(define (dbus-activation config)
"Return an activation gexp for D-Bus using @var{config}."
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index 8dacf54668..dfd1ea6e92 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -460,9 +460,8 @@ Users need to be in the @code{lp} group to access the D-Bus service.
(define polkit-setuid-programs
(match-lambda
(($ <polkit-configuration> polkit)
- (list #~(string-append #$polkit
- "/lib/polkit-1/polkit-agent-helper-1")
- #~(string-append #$polkit "/bin/pkexec")))))
+ (list (file-append polkit "/lib/polkit-1/polkit-agent-helper-1")
+ (file-append polkit "/bin/pkexec")))))
(define polkit-service-type
(service-type (name 'polkit)
@@ -522,7 +521,7 @@ the capability to suspend the system if the user is logged in locally."
(system? #t)
(comment "colord daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define colord-service-type
(service-type (name 'colord)
@@ -738,8 +737,8 @@ seats.)"
(define pam-elogind
(pam-entry
(control "required")
- (module #~(string-append #$(elogind-package config)
- "/lib/security/pam_elogind.so"))))
+ (module (file-append (elogind-package config)
+ "/lib/security/pam_elogind.so"))))
(list (lambda (pam)
(pam-service
diff --git a/gnu/services/dict.scm b/gnu/services/dict.scm
index b06922c911..da5d004701 100644
--- a/gnu/services/dict.scm
+++ b/gnu/services/dict.scm
@@ -73,7 +73,7 @@
(group "dicod")
(system? #t)
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define (dicod-configuration-file config)
(define database->text
diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm
index c252d669de..cb0f119f43 100644
--- a/gnu/services/mail.scm
+++ b/gnu/services/mail.scm
@@ -987,7 +987,7 @@ could allow a user to delete others' mailboxes, or ln -s
(mail-full-filesystem-access?
(boolean #f)
- "Allow full filesystem access to clients. There's no access checks
+ "Allow full file system access to clients. There's no access checks
other than what the operating system does for the active UID/GID. It
works with both maildir and mboxes, allowing you to prefix mailboxes
names with e.g. /path/ or ~user/.")
@@ -997,7 +997,7 @@ names with e.g. /path/ or ~user/.")
(mmap-disable?
(boolean #f)
"Don't use mmap() at all. This is required if you store indexes to
-shared filesystems (NFS or clustered filesystem).")
+shared file systems (NFS or clustered file system).")
(dotlock-use-excl?
(boolean #t)
@@ -1229,7 +1229,7 @@ disabled.")
(boolean #f)
"When creating new mdbox files, immediately preallocate their size to
@samp{mdbox-rotate-size}. This setting currently works only in Linux
-with some filesystems (ext4, xfs).")
+with some file systems (ext4, xfs).")
(mail-attachment-dir
(string "")
@@ -1249,7 +1249,7 @@ externally.")
(mail-attachment-fs
(string "sis posix")
- "Filesystem backend to use for saving attachments:
+ "File system backend to use for saving attachments:
@table @code
@item posix
No SiS done by Dovecot (but this might help FS's own deduplication)
@@ -1352,7 +1352,7 @@ regeneration entirely.")
"SSL crypto device to use, for valid values run \"openssl engine\".")
(postmaster-address
- (string "")
+ (string "postmaster@%d")
"Address to use when sending rejection mails.
Default is postmaster@@<your domain>. %d expands to recipient domain.")
@@ -1505,7 +1505,7 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(system? #t)
(comment "Dovecot daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))
+ (shell (file-append shadow "/sbin/nologin")))
(user-group (name "dovenull") (system? #t))
(user-account
@@ -1514,7 +1514,7 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(system? #t)
(comment "Dovecot daemon login user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define %dovecot-activation
;; Activation gexp.
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 71f49a03a5..7495179f8e 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 John Darrington <jmd@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -193,7 +194,7 @@ gateway."
'dhcp-client
(lambda (dhcp)
(define dhclient
- #~(string-append #$dhcp "/sbin/dhclient"))
+ (file-append dhcp "/sbin/dhclient"))
(define pid-file
"/var/run/dhclient.pid")
@@ -272,7 +273,7 @@ Protocol (DHCP) client, on all the non-loopback network interfaces."
(let ()
;; TODO: Add authentication support.
(define config
- (string-append "driftfile /var/run/ntp.drift\n"
+ (string-append "driftfile /var/run/ntpd/ntp.drift\n"
(string-join (map (cut string-append "server " <>)
servers)
"\n")
@@ -305,7 +306,19 @@ restrict -6 ::1\n"))
(system? #t)
(comment "NTP daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
+
+
+(define (ntp-service-activation config)
+ "Return the activation gexp for CONFIG."
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (define %user
+ (getpw "ntpd"))
+
+ (let ((directory "/var/run/ntpd"))
+ (mkdir-p directory)
+ (chown directory (passwd:uid %user) (passwd:gid %user))))))
(define ntp-service-type
(service-type (name 'ntp)
@@ -313,7 +326,9 @@ restrict -6 ::1\n"))
(list (service-extension shepherd-root-service-type
ntp-shepherd-service)
(service-extension account-service-type
- (const %ntp-accounts))))))
+ (const %ntp-accounts))
+ (service-extension activation-service-type
+ ntp-service-activation)))))
(define* (ntp-service #:key (ntp ntp)
(servers %ntp-servers))
@@ -346,7 +361,7 @@ keep the system clock synchronized with that of @var{servers}."
(system? #t)
(comment "Tor daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define-record-type <hidden-service>
(hidden-service name mapping)
@@ -539,7 +554,7 @@ project's documentation} for more information."
(system? #t)
(comment "BitlBee daemon user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define %bitlbee-activation
;; Activation gexp for BitlBee.
diff --git a/gnu/services/nfs.scm b/gnu/services/nfs.scm
new file mode 100644
index 0000000000..82713d8133
--- /dev/null
+++ b/gnu/services/nfs.scm
@@ -0,0 +1,54 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 John Darrington <jmd@gnu.org>
+;;;
+;;; 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 services nfs)
+ #:use-module (gnu)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu packages onc-rpc)
+ #:use-module (guix)
+ #:use-module (guix records)
+ #:export (rpcbind-service-type
+ rpcbind-configuration
+ rpcbind-configuration?))
+
+(define-record-type* <rpcbind-configuration>
+ rpcbind-configuration make-rpcbind-configuration
+ rpcbind-configuration?
+ (rpcbind rpcbind-configuration-rpcbind
+ (default rpcbind))
+ (warm-start? rpcbind-configuration-warm-start?
+ (default #t)))
+
+(define rpcbind-service-type
+ (shepherd-service-type
+ 'rpcbind
+ (lambda (config)
+ (define pkg
+ (rpcbind-configuration-rpcbind config))
+
+ (define rpcbind-command
+ #~(list (string-append #$pkg "/bin/rpcbind") "-f"
+ #$@(if (rpcbind-configuration-warm-start? config) '("-w") '())))
+
+ (shepherd-service
+ (documentation "Start the RPC bind daemon.")
+ (requirement '(networking))
+ (provision '(rpcbind-daemon))
+
+ (start #~(make-forkexec-constructor #$rpcbind-command))
+ (stop #~(make-kill-destructor))))))
diff --git a/gnu/services/sddm.scm b/gnu/services/sddm.scm
new file mode 100644
index 0000000000..ef1e78e9bf
--- /dev/null
+++ b/gnu/services/sddm.scm
@@ -0,0 +1,318 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 David Craven <david@craven.ch>
+;;;
+;;; 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 services sddm)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages display-managers)
+ #:use-module (gnu packages freedesktop)
+ #:use-module (gnu packages xorg)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu services xorg)
+ #:use-module (gnu system pam)
+ #:use-module (gnu system shadow)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:export (sddm-configuration
+ sddm-confiugration?
+ sddm-service-type
+ sddm-service))
+
+(define-record-type* <sddm-configuration>
+ sddm-configuration make-sddm-configuration
+ sddm-configuration?
+ (sddm sddm-configuration-sddm
+ (default sddm))
+
+ ;; [General]
+ ;; valid values are x11 and wayland
+ ;; currently doesn't do anything is enabled by wayland greeter PR
+ (display-server sddm-configuration-display-server
+ (default "x11"))
+ ;; valid values are on, off or none
+ (numlock sddm-configuration-numlock
+ (default "on"))
+ (halt-command sddm-configuration-halt-command
+ (default (file-append shepherd "/sbin/halt")))
+ (reboot-command sddm-configuration-reboot-command
+ (default (file-append shepherd "/sbin/reboot")))
+
+ ;; [Theme]
+ ;; valid values are elarun or maldives
+ (theme sddm-configuration-theme
+ (default "maldives"))
+ (themes-directory sddm-configuration-themes-directory
+ (default "/run/current-system/profile/share/sddm/themes"))
+ (faces-directory sddm-configuration-faces-directory
+ (default "/run/current-system/profile/share/sddm/faces"))
+
+ ;; [Users]
+ (default-path sddm-configuration-default-path
+ (default "/run/current-system/profile/bin"))
+ (minimum-uid sddm-configuration-minimum-uid
+ (default 1000))
+ (maximum-uid sddm-configuration-maximum-uid
+ (default 2000))
+ (remember-last-user? sddm-configuration-remember-last-user?
+ (default #t))
+ (remember-last-session? sddm-configuration-remember-last-session?
+ (default #t))
+ (hide-users sddm-configuration-hide-users
+ (default ""))
+ (hide-shells sddm-configuration-hide-shells
+ (default (file-append shadow "/sbin/nologin")))
+
+ ;; [Wayland]
+ (session-command sddm-configuration-session-command
+ (default (file-append sddm "/share/sddm/scripts/wayland-session")))
+ (sessions-directory sddm-configuration-sessions-directory
+ (default "/run/current-system/profile/share/wayland-sessions"))
+ ;; [X11]
+ (xorg-server-path sddm-configuration-xorg-server-path
+ (default (xorg-start-command)))
+ (xauth-path sddm-configuration-xauth-path
+ (default (file-append xauth "/bin/xauth")))
+ (xephyr-path sddm-configuration-xephyr-path
+ (default (file-append xorg-server "/bin/Xephyr")))
+ (xdisplay-start sddm-configuration-xdisplay-start
+ (default (file-append sddm "/share/sddm/scripts/Xsetup")))
+ (xdisplay-stop sddm-configuration-xdisplay-stop
+ (default (file-append sddm "/share/sddm/scripts/Xstop")))
+ (xsession-command sddm-configuration-xsession-command
+ (default (xinitrc)))
+ (xsessions-directory sddm-configuration-xsessions-directory
+ (default "/run/current-system/profile/share/xsessions"))
+ (minimum-vt sddm-configuration-minimum-vt
+ (default 7))
+ (xserver-arguments sddm-configuration-xserver-arguments
+ (default "-nolisten tcp"))
+
+ ;; [Autologin]
+ (auto-login-user sddm-configuration-auto-login-user
+ (default ""))
+ ;; valid values are xfce.desktop gnome.desktop weston.desktop hawaii.desktop
+ (auto-login-session sddm-configuration-auto-login-session
+ (default ""))
+ (relogin? sddm-configuration-relogin?
+ (default #f)))
+
+(define (sddm-configuration-file config)
+ (mixed-text-file "sddm.conf" "
+[General]
+DisplayServer=" (sddm-configuration-display-server config) "
+Numlock=" (sddm-configuration-numlock config) "
+HaltCommand=" (sddm-configuration-halt-command config) "
+RebootCommand=" (sddm-configuration-reboot-command config) "
+
+[Users]
+DefaultPath=" (sddm-configuration-default-path config) "
+MinimumUid=" (number->string (sddm-configuration-minimum-uid config))"
+MaximumUid=" (number->string (sddm-configuration-maximum-uid config))"
+RememberLastUser=" (if (sddm-configuration-remember-last-user? config)
+ "true" "false") "
+RememberLastSession=" (if (sddm-configuration-remember-last-session? config)
+ "true" "false") "
+HideUsers=" (sddm-configuration-hide-users config) "
+Hideshells=" (sddm-configuration-hide-shells config) "
+
+[Theme]
+Current=" (sddm-configuration-theme config) "
+ThemeDir=" (sddm-configuration-themes-directory config) "
+FacesDir=" (sddm-configuration-faces-directory config) "
+
+[Wayland]
+SessionCommand=" (sddm-configuration-session-command config) "
+SessionDir=" (sddm-configuration-sessions-directory config) "
+
+[X11]
+ServerPath=" (sddm-configuration-xorg-server-path config) "
+XauthPath=" (sddm-configuration-xauth-path config) "
+XephyrPath=" (sddm-configuration-xephyr-path config) "
+DisplayCommand=" (sddm-configuration-xdisplay-start config) "
+DisplayStopCommand=" (sddm-configuration-xdisplay-stop config) "
+SessionCommand=" (sddm-configuration-xsession-command config) "
+SessionDir=" (sddm-configuration-xsessions-directory config) "
+MinimumVT=" (number->string (sddm-configuration-minimum-vt config)) "
+ServerArguments=" (sddm-configuration-xserver-arguments config) "
+
+[Autologin]
+User=" (sddm-configuration-auto-login-user config) "
+Session=" (sddm-configuration-auto-login-session config) "
+Relogin=" (if (sddm-configuration-relogin? config)
+ "true" "false") "
+"))
+
+(define (sddm-shepherd-service config)
+ "Return a <shepherd-service> for sddm with CONFIG."
+
+ (define sddm-command
+ #~(list (string-append #$(sddm-configuration-sddm config) "/bin/sddm")))
+
+ (list (shepherd-service
+ (documentation "SDDM display manager.")
+ (requirement '(user-processes))
+ (provision '(display-manager))
+ (start #~(make-forkexec-constructor #$sddm-command))
+ (stop #~(make-kill-destructor)))))
+
+(define (sddm-etc-service config)
+ (list `("sddm.conf" ,(sddm-configuration-file config))))
+
+(define (sddm-pam-service)
+ "Return a PAM service for @command{sddm}."
+ (pam-service
+ (name "sddm")
+ (auth
+ (list
+ (pam-entry
+ (control "requisite")
+ (module "pam_nologin.so"))
+ (pam-entry
+ (control "required")
+ (module "pam_env.so"))
+ (pam-entry
+ (control "required")
+ (module "pam_succeed_if.so")
+ (arguments (list "uid >= 1000" "quiet")))
+ ;; should be factored out into system-auth
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so"))))
+ (account
+ (list
+ ;; should be factored out into system-account
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so"))))
+ (password
+ (list
+ ;; should be factored out into system-password
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so")
+ (arguments (list "sha512" "shadow" "try_first_pass")))))
+ (session
+ (list
+ ;; lfs has a required pam_limits.so
+ ;; should be factored out into system-session
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so"))))))
+
+(define (sddm-greeter-pam-service)
+ "Return a PAM service for @command{sddm-greeter}."
+ (pam-service
+ (name "sddm-greeter")
+ (auth
+ (list
+ ;; Load environment form /etc/environment and ~/.pam_environment
+ (pam-entry
+ (control "required")
+ (module "pam_env.so"))
+ ;; Always let the greeter start without authentication
+ (pam-entry
+ (control "required")
+ (module "pam_permit.so"))))
+ (account
+ (list
+ ;; No action required for account management
+ (pam-entry
+ (control "required")
+ (module "pam_permit.so"))))
+ (password
+ (list
+ ;; Can't change password
+ (pam-entry
+ (control "required")
+ (module "pam_deny.so"))))
+ (session
+ (list
+ ;; Setup session
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so"))))))
+
+(define (sddm-autologin-pam-service)
+ "Return a PAM service for @command{sddm-autologin}"
+ (pam-service
+ (name "sddm-autologin")
+ (auth
+ (list
+ (pam-entry
+ (control "requisite")
+ (module "pam_nologin.so"))
+ (pam-entry
+ (control "required")
+ (module "pam_succeed_if.so")
+ (arguments (list "uid >= 1000" "quiet")))
+ (pam-entry
+ (control "required")
+ (module "pam_permit.so"))))
+ (account
+ (list
+ (pam-entry
+ (control "include")
+ (module "sddm"))))
+ (password
+ (list
+ (pam-entry
+ (control "required")
+ (module "pam_deny.so"))))
+ (session
+ (list
+ (pam-entry
+ (control "include")
+ (module "sddm"))))))
+
+(define (sddm-pam-services config)
+ (list (sddm-pam-service)
+ (sddm-greeter-pam-service)
+ (sddm-autologin-pam-service)))
+
+(define %sddm-accounts
+ (list (user-group (name "sddm") (system? #t))
+ (user-account
+ (name "sddm")
+ (group "sddm")
+ (system? #t)
+ (comment "SDDM user")
+ (home-directory "/var/lib/sddm")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+;; Add default themes to profile
+(define sddm-profile-service
+ (compose list sddm-configuration-sddm))
+
+(define sddm-service-type
+ (service-type (name 'sddm)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ sddm-shepherd-service)
+ (service-extension etc-service-type
+ sddm-etc-service)
+ (service-extension pam-root-service-type
+ sddm-pam-services)
+ (service-extension account-service-type
+ (const %sddm-accounts))
+ (service-extension profile-service-type
+ sddm-profile-service)))))
+
+(define* (sddm-service #:optional (config (sddm-configuration)))
+ "Run the @uref{https://github.com/sddm/sddm,SSDM display manager}
+with the given @var{config}, a @code{<sddm-configuration>} object."
+ (service sddm-service-type config))
diff --git a/gnu/services/spice.scm b/gnu/services/spice.scm
index 26f072e7a8..bd0a538346 100644
--- a/gnu/services/spice.scm
+++ b/gnu/services/spice.scm
@@ -43,7 +43,7 @@
(define spice-vdagentd-command
(list
- #~(string-append #$spice-vdagent "/sbin/spice-vdagentd")
+ (file-append spice-vdagent "/sbin/spice-vdagentd")
"-x"))
(list
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 9a7ea0fb46..084f8fa4ea 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016 David Craven <david@craven.ch>
+;;; Copyright © 2016 Julien Lepiller <julien@lepiller.eu>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -19,17 +20,25 @@
(define-module (gnu services ssh)
#:use-module (gnu packages ssh)
+ #:use-module (gnu packages admin)
#:use-module (gnu services)
#:use-module (gnu services shepherd)
#:use-module (gnu system pam)
+ #:use-module (gnu system shadow)
#:use-module (guix gexp)
#:use-module (guix records)
#:use-module (srfi srfi-26)
+ #:use-module (ice-9 match)
#:export (lsh-configuration
lsh-configuration?
lsh-service
lsh-service-type
+ openssh-configuration
+ openssh-configuration?
+ openssh-service-type
+ openssh-service
+
dropbear-configuration
dropbear-configuration?
dropbear-service-type
@@ -122,7 +131,7 @@
(define lsh-command
(append
- (cons #~(string-append #$lsh "/sbin/lshd")
+ (cons (file-append lsh "/sbin/lshd")
(if daemonic?
(let ((syslog (if (lsh-configuration-syslog-output? config)
'()
@@ -246,6 +255,128 @@ The other options should be self-descriptive."
;;;
+;;; OpenSSH.
+;;;
+
+(define-record-type* <openssh-configuration>
+ openssh-configuration make-openssh-configuration
+ openssh-configuration?
+ (pid-file openssh-configuration-pid-file) ;string
+ (port-number openssh-configuration-port-number) ;integer
+ (permit-root-login openssh-configuration-permit-root-login) ;Boolean | 'without-password
+ (allow-empty-passwords? openssh-configuration-allow-empty-passwords?) ;Boolean
+ (password-authentication? openssh-configuration-password-authentication?) ;Boolean
+ (pubkey-authentication? openssh-configuration-pubkey-authentication?) ;Boolean
+ (rsa-authentication? openssh-configuration-rsa-authentication?) ;Boolean
+ (x11-forwarding? openssh-configuration-x11-forwarding?) ;Boolean
+ (protocol-number openssh-configuration-protocol-number)) ;integer
+
+(define %openssh-accounts
+ (list (user-group (name "sshd") (system? #t))
+ (user-account
+ (name "sshd")
+ (group "sshd")
+ (system? #t)
+ (comment "sshd privilege separation user")
+ (home-directory "/var/run/sshd")
+ (shell #~(string-append #$shadow "/sbin/nologin")))))
+
+(define (openssh-activation config)
+ "Return the activation GEXP for CONFIG."
+ #~(begin
+ (mkdir-p "/etc/ssh")
+ (mkdir-p (dirname #$(openssh-configuration-pid-file config)))
+
+ ;; Generate missing host keys.
+ (system* (string-append #$openssh "/bin/ssh-keygen") "-A")))
+
+(define (openssh-config-file config)
+ "Return the sshd configuration file corresponding to CONFIG."
+ (computed-file
+ "sshd_config"
+ #~(call-with-output-file #$output
+ (lambda (port)
+ (display "# Generated by 'openssh-service'.\n" port)
+ (format port "Protocol ~a\n"
+ #$(if (eq? (openssh-configuration-protocol-number config) 1)
+ "1" "2"))
+ (format port "Port ~a\n"
+ #$(number->string (openssh-configuration-port-number config)))
+ (format port "PermitRootLogin ~a\n"
+ #$(match (openssh-configuration-permit-root-login config)
+ (#t "yes")
+ (#f "no")
+ ('without-password "without-password")))
+ (format port "PermitEmptyPasswords ~a\n"
+ #$(if (openssh-configuration-allow-empty-passwords? config)
+ "yes" "no"))
+ (format port "PasswordAuthentication ~a\n"
+ #$(if (openssh-configuration-password-authentication? config)
+ "yes" "no"))
+ (format port "PubkeyAuthentication ~a\n"
+ #$(if (openssh-configuration-pubkey-authentication? config)
+ "yes" "no"))
+ (format port "RSAAuthentication ~a\n"
+ #$(if (openssh-configuration-rsa-authentication? config)
+ "yes" "no"))
+ (format port "X11Forwarding ~a\n"
+ #$(if (openssh-configuration-x11-forwarding? config)
+ "yes" "no"))
+ (format port "PidFile ~a\n"
+ #$(openssh-configuration-pid-file config))
+ #t))))
+
+(define (openssh-shepherd-service config)
+ "Return a <shepherd-service> for openssh with CONFIG."
+
+ (define pid-file
+ (openssh-configuration-pid-file config))
+
+ (define openssh-command
+ #~(list (string-append #$openssh "/sbin/sshd")
+ "-D" "-f" #$(openssh-config-file config)))
+
+ (list (shepherd-service
+ (documentation "OpenSSH server.")
+ (requirement '(networking syslogd))
+ (provision '(ssh-daemon))
+ (start #~(make-forkexec-constructor #$openssh-command
+ #:pid-file #$pid-file))
+ (stop #~(make-kill-destructor)))))
+
+(define openssh-service-type
+ (service-type (name 'openssh)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ openssh-shepherd-service)
+ (service-extension activation-service-type
+ openssh-activation)
+ (service-extension account-service-type
+ (const %openssh-accounts))))))
+
+(define* (openssh-service #:key
+ (pid-file "/var/run/sshd.pid")
+ (port-number 22)
+ (permit-root-login 'without-password)
+ (allow-empty-passwords? #f)
+ (password-authentication? #t)
+ (pubkey-authentication? #t)
+ (rsa-authentication? #t)
+ (x11-forwarding? #f)
+ (protocol-number 2))
+ (service openssh-service-type (openssh-configuration
+ (pid-file pid-file)
+ (port-number port-number)
+ (permit-root-login permit-root-login)
+ (allow-empty-passwords? allow-empty-passwords?)
+ (password-authentication? password-authentication?)
+ (pubkey-authentication? pubkey-authentication?)
+ (rsa-authentication? rsa-authentication?)
+ (x11-forwarding? x11-forwarding?)
+ (protocol-number protocol-number))))
+
+
+;;;
;;; Dropbear.
;;;
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index d86aab50b5..0a2a09bbf5 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -67,7 +67,7 @@
(system? #t)
(comment "nginx server user")
(home-directory "/var/empty")
- (shell #~(string-append #$shadow "/sbin/nologin")))))
+ (shell (file-append shadow "/sbin/nologin")))))
(define nginx-activation
(match-lambda
@@ -80,13 +80,13 @@
(format #t "creating nginx run directory '~a'~%" #$run-directory)
(mkdir-p #$run-directory)
;; Check configuration file syntax.
- (system* (string-append #$nginx "/bin/nginx")
+ (system* (string-append #$nginx "/sbin/nginx")
"-c" #$config-file "-t")))))
(define nginx-shepherd-service
(match-lambda
(($ <nginx-configuration> nginx log-directory run-directory config-file)
- (let* ((nginx-binary #~(string-append #$nginx "/sbin/nginx"))
+ (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
(nginx-action
(lambda args
#~(lambda _
diff --git a/gnu/services/xorg.scm b/gnu/services/xorg.scm
index 4e311deb84..d098d831e1 100644
--- a/gnu/services/xorg.scm
+++ b/gnu/services/xorg.scm
@@ -42,6 +42,8 @@
#:export (xorg-configuration-file
%default-xorg-modules
xorg-start-command
+ xinitrc
+
%default-slim-theme
%default-slim-theme-name
slim-configuration
@@ -265,7 +267,7 @@ which should be passed to this script as the first argument. If not, the
(define %default-slim-theme
;; Theme based on work by Felipe López.
- #~(string-append #$%artwork-repository "/slim"))
+ (file-append %artwork-repository "/slim"))
(define %default-slim-theme-name
;; This must be the name of the sub-directory in %DEFAULT-SLIM-THEME that
@@ -372,8 +374,8 @@ reboot_cmd " shepherd "/sbin/reboot\n"
(theme %default-slim-theme)
(theme-name %default-slim-theme-name)
(xauth xauth) (shepherd shepherd) (bash bash)
- (auto-login-session #~(string-append #$windowmaker
- "/bin/wmaker"))
+ (auto-login-session (file-append windowmaker
+ "/bin/wmaker"))
(startx (xorg-start-command)))
"Return a service that spawns the SLiM graphical login manager, which in
turn starts the X display server with @var{startx}, a command as returned by
@@ -448,14 +450,13 @@ command is @var{program}, to the set of setuid programs and add a PAM entry
for it. For example:
@lisp
-(screen-locker-service xlockmore \"xlock\")
+ (screen-locker-service xlockmore \"xlock\")
@end lisp
makes the good ol' XlockMore usable."
(service screen-locker-service-type
(screen-locker program
- #~(string-append #$package
- #$(string-append "/bin/" program))
+ (file-append package "/bin/" program)
allow-empty-passwords?)))
;;; xorg.scm ends here