[PATCH] home: Add home-syncthing-service-type.

  • Done
  • quality assurance status badge
Details
4 participants
  • Attila Lendvai
  • Ludovic Courtès
  • Bruno Victal
  • Sergey Trofimov
Owner
unassigned
Submitted by
Sergey Trofimov
Severity
normal
S
S
Sergey Trofimov wrote on 23 Mar 2023 09:10
(address . guix-patches@gnu.org)(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
20230323081026.13850-1-sarg@sarg.org.ru
* gnu/home/services/syncthing.scm
(home-syncthing-service-type): New variable.
(home-syncthing-configuration): New procedure.
* gnu/services/syncthing.scm
(syncthing-shepherd-service): Adapt to be used as a home service.
* doc/guix.texi: Ditto.
---
doc/guix.texi | 42 ++++++++++++++++++++++++++++-
gnu/home/services/syncthing.scm | 48 +++++++++++++++++++++++++++++++++
gnu/services/syncthing.scm | 15 +++++++----
3 files changed, 99 insertions(+), 6 deletions(-)
create mode 100644 gnu/home/services/syncthing.scm

Toggle diff (166 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index dfdb26103a..a2fe2514db 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -20735,7 +20735,7 @@ List of command-line arguments passing to @code{syncthing} binary.
Sum of logging flags, see
@uref{https://docs.syncthing.net/users/syncthing.html#cmdoption-logflags, Syncthing documentation logflags}.
-@item @code{user} (default: @var{#f})
+@item @code{user}
The user as which the Syncthing service is to be run.
This assumes that the specified user exists.
@@ -41790,6 +41790,7 @@ services)}.
* Sound: Sound Home Services. Dealing with audio.
* Messaging: Messaging Home Services. Services for managing messaging.
* Media: Media Home Services. Services for managing media.
+* Networking: Networking Home Services.
@end menu
@c In addition to that Home Services can provide
@@ -42978,6 +42979,45 @@ kodi} for more information.
@end table
@end deftp
+@node Networking Home Services
+@subsection Networking Home Services
+
+@cindex syncthing
+With the @code{(gnu home services syncthing)} service, you can configure
+@uref{https://github.com/syncthing/syncthing, Syncthing} to run upon
+login.
+
+Here is an example of a service and its configuration that you could add
+to the @code{services} field of your @code{home-environment}:
+
+@lisp
+(service home-syncthing-service-type
+ (home-syncthing-configuration
+ (arguments '("--paused"))))
+@end lisp
+
+@defvar home-syncthing-service-type
+This is the type of the @code{syncthing} home service, whose value is an
+@code{home-syncthing-configuration} object.
+@end defvar
+
+@deftp {Data Type} home-syncthing-configuration
+Data type representing the configuration for @code{home-syncthing-service-type}.
+
+@table @asis
+@item @code{syncthing} (default: @var{syncthing})
+@code{syncthing} package to use.
+
+@item @code{arguments} (default: @var{'()})
+List of command-line arguments passing to @code{syncthing} binary.
+
+@item @code{logflags} (default: @var{0})
+Sum of logging flags, see
+@uref{https://docs.syncthing.net/users/syncthing.html#cmdoption-logflags, Syncthing documentation logflags}.
+
+@end table
+@end deftp
+
@node Invoking guix home
@section Invoking @command{guix home}
diff --git a/gnu/home/services/syncthing.scm b/gnu/home/services/syncthing.scm
new file mode 100644
index 0000000000..928a23986b
--- /dev/null
+++ b/gnu/home/services/syncthing.scm
@@ -0,0 +1,48 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Oleg Pykhalov <go.wigust@gmail.com>
+;;; Copyright © 2023 Sergey Trofimov <sarg@sarg.org.ru>
+;;;
+;;; 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 home services syncthing)
+ #:use-module (gnu services)
+ #:use-module (gnu services syncthing)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu home services shepherd)
+
+ #:export (home-syncthing-service-type
+ home-syncthing-configuration))
+
+(define syncthing-home-shepherd-service
+ (lambda (configuration)
+ (map (lambda (srv) (shepherd-service (inherit srv) (requirement '())))
+ ((@@ (gnu services syncthing) syncthing-shepherd-service) configuration))))
+
+(define-syntax-rule (home-syncthing-configuration args ...)
+ (syncthing-configuration
+ (user #f)
+ args ...))
+
+(define home-syncthing-service-type
+ (service-type (name 'syncthing)
+ (extensions (list (service-extension home-shepherd-service-type
+ syncthing-home-shepherd-service)))
+ (default-value (home-syncthing-configuration))
+ (description
+ "Run @uref{https://github.com/syncthing/syncthing, Syncthing}
+decentralized continuous file system synchronization.")))
+
+;;; syncthing.scm ends here
diff --git a/gnu/services/syncthing.scm b/gnu/services/syncthing.scm
index 7c3d5b027d..960f0a1db8 100644
--- a/gnu/services/syncthing.scm
+++ b/gnu/services/syncthing.scm
@@ -43,8 +43,7 @@ (define-record-type* <syncthing-configuration>
(default '()))
(logflags syncthing-configuration-logflags ;number
(default 0))
- (user syncthing-configuration-user ;string
- (default #f))
+ (user syncthing-configuration-user) ;string
(group syncthing-configuration-group ;string
(default "users"))
(home syncthing-configuration-home ;string
@@ -55,9 +54,12 @@ (define syncthing-shepherd-service
(($ <syncthing-configuration> syncthing arguments logflags user group home)
(list
(shepherd-service
- (provision (list (string->symbol (string-append "syncthing-" user))))
+ (provision (list
+ (or (and user (string->symbol (string-append "syncthing-" user)))
+ 'syncthing)))
(documentation "Run syncthing.")
(requirement '(loopback))
+ (modules '((srfi srfi-1) (shepherd support)))
(start #~(make-forkexec-constructor
(append (list (string-append #$syncthing "/bin/syncthing")
"-no-browser"
@@ -65,9 +67,12 @@ (define syncthing-shepherd-service
(string-append "-logflags=" (number->string #$logflags)))
'#$arguments)
#:user #$user
- #:group #$group
+ #:group (and #$user #$group)
#:environment-variables
- (append (list (string-append "HOME=" (or #$home (passwd:dir (getpw #$user))))
+ (append (list (string-append "HOME="
+ (or #$home
+ (and #$user (passwd:dir (getpw #$user)))
+ user-homedir))
"SSL_CERT_DIR=/etc/ssl/certs"
"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt")
(remove (lambda (str)
--
2.39.2
L
L
Ludovic Courtès wrote on 28 Mar 2023 17:58
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
87o7ocg960.fsf@gnu.org
Hi,

Sergey Trofimov <sarg@sarg.org.ru> skribis:

Toggle quote (7 lines)
> * gnu/home/services/syncthing.scm
> (home-syncthing-service-type): New variable.
> (home-syncthing-configuration): New procedure.
> * gnu/services/syncthing.scm
> (syncthing-shepherd-service): Adapt to be used as a home service.
> * doc/guix.texi: Ditto.

Nice!

Note: You can just say “New file” for a new file; however please specify
the name of the node added to the manual, for clarity.

Toggle quote (5 lines)
> +(define syncthing-home-shepherd-service
> + (lambda (configuration)
> + (map (lambda (srv) (shepherd-service (inherit srv) (requirement '())))
> + ((@@ (gnu services syncthing) syncthing-shepherd-service) configuration))))

You could do that without resorting to @@, by using ‘find’ on the
extensions of ‘syncthing-service-type’.

Toggle quote (12 lines)
> diff --git a/gnu/services/syncthing.scm b/gnu/services/syncthing.scm
> index 7c3d5b027d..960f0a1db8 100644
> --- a/gnu/services/syncthing.scm
> +++ b/gnu/services/syncthing.scm
> @@ -43,8 +43,7 @@ (define-record-type* <syncthing-configuration>
> (default '()))
> (logflags syncthing-configuration-logflags ;number
> (default 0))
> - (user syncthing-configuration-user ;string
> - (default #f))
> + (user syncthing-configuration-user) ;string

This means that users of ‘syncthing-service-type’ will now have to
provide a value for ‘user’, which wasn’t the case until now. Is this
change necessary?

The rest looks reasonable to me. My main concern is whether it would
make sense to automate system->home service translation. I’ll expand on
that separately.

Thanks,
Ludo’.
L
L
Ludovic Courtès wrote on 28 Mar 2023 18:18
Automatically mapping services from System to Home
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
87edp8g88j.fsf@gnu.org
One idea I toyed with is automatic translation of service types from
System to Home. The service itself would look like this:

Toggle snippet (11 lines)
(define-module (gnu home services syncthing)
#:use-module (gnu home services)
#:use-module (gnu services syncthing)
#:export (home-syncthing-service-type)
#:re-export (syncthing-configuration
syncthing-configuration?))

(define home-syncthing-service-type
(system-service-type->home-service-type syncthing-service-type))

The code to do that is attached below. The key here is that we’d define
mappings, like:

(define-service-type-mapping
shepherd-root-service-type => home-shepherd-service-type)

The rest of the service type graph would be automatically constructed
from this.

I feel like it would be worth pursuing this path so that there’s as
little duplication as possible between Home and System.

OTOH, it doesn’t take care of things like #:user in
‘make-forkexec-constructor’ calls and the like.

Thoughts?

Ludo’.
Toggle diff (135 lines)
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index b7ea6f08dd..b32e7395b1 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -31,8 +32,10 @@ (define-module (gnu home services)
#:use-module (guix diagnostics)
#:use-module (guix i18n)
#:use-module (guix modules)
+ #:use-module (guix memoization)
#:use-module (srfi srfi-1)
#:use-module (ice-9 match)
+ #:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
@@ -46,6 +49,9 @@ (define-module (gnu home services)
fold-home-service-types
home-provenance
+ define-service-type-mapping
+ system-service-type->home-service-type
+
%initialize-gettext)
#:re-export (service
@@ -396,6 +402,77 @@ (define home-activation-service-type
reconfiguration or generation switching. This service can be extended
with one gexp, but many times, and all gexps must be idempotent.")))
+
+;;;
+;;; Service type graph rewriting.
+;;;
+
+(define (service-type-mapping proc)
+ (define (rewrite extension)
+ (match (proc (service-extension-target extension))
+ (#f #f)
+ (target
+ (service-extension target
+ (service-extension-compute extension)))))
+
+ (define replace
+ (mlambdaq (type)
+ (service-type
+ (inherit type)
+ (location (service-type-location type))
+ (extensions (filter-map rewrite (service-type-extensions type))))))
+
+ replace)
+
+;; (define (service-type-extensions-rewriting replacements)
+;; (define replace
+;; (let ((replacements (alist->vhash replacements hashq)))
+;; (lambda (type)
+;; (match (vhash-assq type replacements)
+;; (#f type)
+;; ((_ . replacement) replacement)))))
+
+;; (service-type-mapping replace))
+
+(define system-service-type->home-service-type
+ (let ()
+ (define (replace type)
+ (define replacement
+ (hashq-ref %system/home-service-type-mapping type
+ *unspecified*))
+
+ (if (eq? replacement *unspecified*)
+ type
+ replacement))
+
+ (service-type-mapping replace)))
+
+(define %system/home-service-type-mapping
+ (make-hash-table))
+
+(define-syntax define-service-type-mapping
+ (syntax-rules (=>)
+ ((_ system-type => home-type)
+ (hashq-set! %system/home-service-type-mapping
+ system-type home-type))))
+
+(define-syntax define-service-type-mappings
+ (syntax-rules (=>)
+ ((_ (system-type => home-type) ...)
+ (begin
+ (define-service-type-mapping system-type => home-type)
+ ...))))
+
+(define-service-type-mappings
+ (system-service-type => home-service-type)
+ (activation-service-type => home-activation-service-type))
+
+;; (define system->home-service-type
+;; (service-type-extensions-rewriting
+;; `((,system-service-type . ,home-service-type)
+;; (,activation-service-type . ,home-activation-service-type)
+;; (,shepherd-root-service-type . ,home-shepherd-service-type))))
+
;;;
;;; On-change.
diff --git a/gnu/home/services/shepherd.scm b/gnu/home/services/shepherd.scm
index 7a9cc064bb..21b73d8cdf 100644
--- a/gnu/home/services/shepherd.scm
+++ b/gnu/home/services/shepherd.scm
@@ -131,4 +131,5 @@ (define-public home-shepherd-service-type
(default-value (home-shepherd-configuration))
(description "Configure and install userland Shepherd.")))
-
+(define-service-type-mapping
+ shepherd-root-service-type => home-shepherd-service-type)
diff --git a/gnu/services/syncthing.scm b/gnu/services/syncthing.scm
index 7c3d5b027d..130a87705e 100644
--- a/gnu/services/syncthing.scm
+++ b/gnu/services/syncthing.scm
@@ -57,7 +57,7 @@ (define syncthing-shepherd-service
(shepherd-service
(provision (list (string->symbol (string-append "syncthing-" user))))
(documentation "Run syncthing.")
- (requirement '(loopback))
+ ;; (requirement '(loopback))
(start #~(make-forkexec-constructor
(append (list (string-append #$syncthing "/bin/syncthing")
"-no-browser"
S
S
Sergey Trofimov wrote on 28 Mar 2023 21:29
Re: [bug#62401] [PATCH] home: Add home-syncthing-service-type.
(name . Ludovic Courtès)(address . ludo@gnu.org)
87ilek64p4.fsf@sarg.org.ru
Hi Ludovic,

Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (18 lines)
> Hi,
>
> Sergey Trofimov <sarg@sarg.org.ru> skribis:
>
>> * gnu/home/services/syncthing.scm
>> (home-syncthing-service-type): New variable.
>> (home-syncthing-configuration): New procedure.
>> * gnu/services/syncthing.scm
>> (syncthing-shepherd-service): Adapt to be used as a home
>> service.
>> * doc/guix.texi: Ditto.
>
> Nice!
>
> Note: You can just say “New file” for a new file; however please
> specify
> the name of the node added to the manual, for clarity.

So it looks like this?
Toggle snippet (5 lines)
* gnu/home/services/syncthing.scm: New file.
* doc/guix.texi: Document home-syncthing-service-type and
home-syncthing-configuration.

Toggle quote (11 lines)
>> +(define syncthing-home-shepherd-service
>> + (lambda (configuration)
>> + (map (lambda (srv) (shepherd-service (inherit srv)
>> (requirement '())))
>> + ((@@ (gnu services syncthing)
>> syncthing-shepherd-service) configuration))))
>
> You could do that without resorting to @@, by using ‘find’ on
> the
> extensions of ‘syncthing-service-type’.

Not sure I get you. I use @@ because `syncthing-shepherd-service`
is not exported and I want to leave that as is.

Toggle quote (21 lines)
>> diff --git a/gnu/services/syncthing.scm
>> b/gnu/services/syncthing.scm
>> index 7c3d5b027d..960f0a1db8 100644
>> --- a/gnu/services/syncthing.scm
>> +++ b/gnu/services/syncthing.scm
>> @@ -43,8 +43,7 @@ (define-record-type*
>> <syncthing-configuration>
>> (default '()))
>> (logflags syncthing-configuration-logflags ;number
>> (default 0))
>> - (user syncthing-configuration-user ;string
>> - (default #f))
>> + (user syncthing-configuration-user) ;string
>
> This means that users of ‘syncthing-service-type’ will now have
> to
> provide a value for ‘user’, which wasn’t the case until now. Is
> this
> change necessary?
>

The existing code fails on this line, when the user is not
specified:
Toggle snippet (4 lines)
(provision (list (string->symbol (string-append "syncthing-"
user))))

string-append doesn't accept nil args

Toggle quote (7 lines)
>
> The rest looks reasonable to me. My main concern is whether it
> would
> make sense to automate system->home service translation. I’ll
> expand on
> that separately.

Does guix really need a system syncthing service? It runs under
`user`, looks for configuration in `/home/user` and therefore
looks out of place in the system services list.
A
A
Attila Lendvai wrote on 28 Mar 2023 21:59
Re: Automatically mapping services from System to Home
(name . Ludovic Courtès)(address . ludo@gnu.org)
c5fO0YPa379sD5mE3Zbq8jhYF6LHKZivfkH8WOHp_nIPyvH0N5CBkEn5o21xJAGeJknbTKcepR1DscRaP0CgZTC-uMCgBnxw8fg7fYLlIeE=@lendvai.name
Toggle quote (2 lines)
> Thoughts?

my gut reaction is that whatever the automatic mapping does should be captured/reified into the code that defines a service... factoring out the common parts, and adding on top of that whatever is necessary in the two different contexts.

but then i'm not sure i fully understand the differences between these two contexts, and i don't have a proposal.diff either, so...

BTW, what are the differences?

- a possible call to setuid/setgid, and their values in the config if
the service is not to be started as root?

- the default values of the config file and log file(s)? possibly
some service-specific values in the config whose default value
depend on the user/group under which the service is running?

maybe the user/group should be a mandatory value under the hood, and the service code should dispatch on their values and the current effective user/group id, and act accordingly?

what am i missing?

--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“The moral law is one of the basic laws of the universe. It is likewise called the principle of Karma, the result of cause and effect, or action and reaction. There is nothing vindictive about this principle. It works impersonally like any law of nature. As the fruit is contained in the seed, so the consequences are inherent in the act. This principle guides the destinies of both people and nations. Knowledge of this principle gives human beings the power to control our own destiny.”
— Thor Kiimaletho
B
B
Bruno Victal wrote on 29 Mar 2023 17:21
07fc2e40-7e23-a7cb-469d-95aae6614ff5@makinata.eu
Hi Ludo’,

On 2023-03-28 17:18, Ludovic Courtès wrote:
Toggle quote (31 lines)
> One idea I toyed with is automatic translation of service types from
> System to Home. The service itself would look like this:
>
> --8<---------------cut here---------------start------------->8---
> (define-module (gnu home services syncthing)
> #:use-module (gnu home services)
> #:use-module (gnu services syncthing)
> #:export (home-syncthing-service-type)
> #:re-export (syncthing-configuration
> syncthing-configuration?))
>
> (define home-syncthing-service-type
> (system-service-type->home-service-type syncthing-service-type))
> --8<---------------cut here---------------end--------------->8---
>
> The code to do that is attached below. The key here is that we’d define
> mappings, like:
>
> (define-service-type-mapping
> shepherd-root-service-type => home-shepherd-service-type)
>
> The rest of the service type graph would be automatically constructed
> from this.
>
> I feel like it would be worth pursuing this path so that there’s as
> little duplication as possible between Home and System.
>
> OTOH, it doesn’t take care of things like #:user in
> ‘make-forkexec-constructor’ calls and the like.
>

I've been thinking that shepherd services should, in general, come with a
preamble in their configuration record-types. (perhaps à la SRFI-136 parent-style records?)

Below is a non-exhaustive list of “things” that should almost always be configurable,
unless it's reasonable to omit it:

Toggle snippet (36 lines)
;; These fields were listed based on “experience” in reworking,
;; repurposing and adding new (system) services within Guix.


(define-configuration example-configuration
;; Allow the package to be overridden.
(package
file-like
"Lorem ipsum …")

;; Note that they're not strings. This allows for tailoring
;; the user-account used by the service (e.g. adding extra groups
;; for the daemon to have access to other directories, etc.
(user
user-account
"Lorem ipsum …")

;; ^^^^^ Ditto.
(group
user-group
"Lorem ipsum …")

(shepherd-requirement ; or shepherd-requirements, the former already has some presence in Guix
; but could be phased-out in favor of the plural form
list-of-symbols
"Lorem ipsum …")

;; Uncommonly seen among services
;; but mpd-service-type is an example where this is important.
(environment-variables
list-of-env-vars
"Lorem ipsum …")



Tossing another idea in the air, with https://issues.guix.gnu.org/62298
define-configuration could perhaps be enriched with additional parameters to
hint that certain fields should be treated differently depending
on “context”? Naturally the service code will have to be adjusted
to use these hints, but overall it should result in a much cleaner
way to guide serializations and service-extension pruning.


It could be something of the sort:

Toggle snippet (33 lines)
(define-configuration example-configuration

(user
user-account
"Lorem ipsum …"
(attributes 'system-service)
…)

;; or
(define-configuration example-configuration

(user
user-account
"Lorem ipsum …"
system-only
…)


;; or
(define-configuration example-configuration

(user
user-account
"Lorem ipsum …"
(system #t)
(home #f)
…)


Cheers,
Bruno
B
B
Bruno Victal wrote on 29 Mar 2023 18:35
Re: [bug#62401] [PATCH] home: Add home-syncthing-service-type.
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
ce54e905-1a64-85d4-908d-f3347a49b700@makinata.eu
Hi Sergey,

On 2023-03-28 20:29, Sergey Trofimov wrote:
Toggle quote (4 lines)
>
> Does guix really need a system syncthing service? It runs under `user`, looks for configuration in `/home/user` and therefore looks out of place in the system services list.
>

A system service doesn't necessarily mean root or "non-interactive/system user" only.
It's a service that can be configured by the system admin and it can be made to run under any user.

Someone could very well want to configure some kinds of services within config.scm rather than having
to manage both a system and user config.

My 2¢.


Cheers,
Bruno
L
L
Ludovic Courtès wrote on 7 Aug 2023 11:50
Re: bug#62401: [PATCH] home: Add home-syncthing-service-type.
87edkfw58w.fsf_-_@gnu.org
Hi Bruno, Sergey, and all,

https://issues.guix.gnu.org/65119 is an attempt to provide a
consistent and simple way to “port” System services to Home, including
Syncthing, as discussed in this thread.

Let me know what you think!

Ludo’.
L
L
Ludovic Courtès wrote on 21 Aug 2023 15:02
control message for bug #62401
(address . control@debbugs.gnu.org)
87h6osblb8.fsf@gnu.org
close 62401
quit
?