Hilton Chain <[email protected]> writes:
> On Wed, 02 Apr 2025 23:46:51 +0800,
> Rutherther wrote:
>>
>>
>> Hello Hilton,
>>
>> Hilton Chain <[email protected]> writes:
>>
>> >
>> > 2. Need of manually exposing interfaces. e.g. those from shepherd-service.
>> >
>>
>> I feel like this has been a topic mentioned multiple times in the last
>> few weeks on this mailing list. Here I have e-mail from Carlo Zancanaro
>> in mind, "Configuring shepherd services belonging to system services" (I
>> don't know how to 'mention' e-mails in a good way, if you have tips,
>> please do share them),
>> where also this patch https://issues.guix.gnu.org/27155 has been
>> mentioned.
>>
>> I think it's a pity we don't have a generic solution merged yet,
>> especially given the patch that is 8 years old and Ludo mentions in it
>> "It was long overdue.", I agree.
>> The general finalizer approach would allow for exposing further
>> procedures that would alter the services after they are made, things
>> like this would become possible to do easily and we could build on it
>> further, functions like '(finalize-shepherd-service "service" (lambda
>> (config) (.. (inherit (config)))))' and more specific ones like
>> (shepherd-override-auto-start? #f)'.
>>
>> Regards,
>> Rutherther
>
> What I want is to have a consistent configuration interface, this is what
> currently in my mind, it's not conflict with the finalizer approach. But I
> haven't got time to implemented it yet.
>
> --8<---------------cut here---------------start------------->8---
> (iwd-configuration
> (alist-config
> `(;; Interface for Guix services, shepherd, postgresql-role, user etc.
> (shepherd
> . ((iwd
> . ((provision . (networking iwd))
> (requirement . ())
> (auto-start? . #f)))))
> ;; For serializers.
> (config
> . ((iwd
> . ((General
> . ((EnableNetworkConfiguration . #t)
> (ControlPortOverNL80211 . #t)))
> (Network
> . ((EnableIPv6 . #t))))))))))
> --8<---------------cut here---------------end--------------->8---
Instead of alist, I tried to use the current configuration interface,
but with service extensions exposed. I'll see how to add serializers in
later and experiment with more services.
Configuration interface:
--8<---------------cut here---------------start------------->8---
(service caddy-service-type
(caddy-configuration
(caddyfile (plain-file "test" "test"))))
--8<---------------cut here---------------end--------------->8---
--8<---------------cut here---------------start------------->8---
(service caddy-service-type
(let ((base (caddy-configuration (caddyfile (plain-file "test" "test")))))
(caddy-configuration
(inherit base)
(shepherd
(map (lambda (s)
(if (member 'caddy (shepherd-service-provision s))
(shepherd-service
(inherit s)
(documentation "test test"))
s))
(caddy-configuration-shepherd base))))))
--8<---------------cut here---------------end--------------->8---
Service definicion:
--8<---------------cut here---------------start------------->8---
(define-record-type* <caddy-configuration>
caddy-configuration make-caddy-configuration
caddy-configuration?
this-caddy-configuration
(caddy caddy-configuration-caddy
(default caddy))
(caddyfile caddy-configuration-caddyfile)
;; Extensions
(accounts caddy-configuration-accounts
(default (%caddy-accounts
this-caddy-configuration))
(thunked))
(privileged-program caddy-configuration-privileged-program
(default (%caddy-privileged-program
this-caddy-configuration))
(thunked))
(activation caddy-configuration-activation
(default (%caddy-activation
this-caddy-configuration))
(thunked))
(shepherd caddy-configuration-shepherd
(default (%caddy-shepherd
this-caddy-configuration))
(thunked)))
(define (%caddy-accounts config)
(list (user-group (name "caddy") (system? #t))
(user-account
(name "caddy")
(group "caddy")
(system? #t)
(comment "Caddy user")
(home-directory "/var/lib/caddy"))))
(define %caddy-privileged-program
(match-record-lambda <caddy-configuration>
(caddy)
(list (privileged-program
(program (file-append caddy "/bin/caddy"))
(capabilities "cap_net_bind_service=+ep")))))
(define %caddy-activation
(match-record-lambda <caddy-configuration>
(caddyfile)
(with-imported-modules
(source-module-closure '((guix build utils)
(gnu build activation)))
#~(begin
(use-modules (srfi srfi-26)
(guix build utils)
(gnu build activation))
(let* ((config-dir "/etc/caddy")
(data-dir "/var/lib/caddy")
(config-file (in-vicinity config-dir "Caddyfile"))
(user (getpwnam "caddy")))
(for-each (cut mkdir-p/perms <> user #o750)
(list config-dir data-dir))
(copy-file #$caddyfile config-file)
(for-each
(lambda (file)
(chown file (passwd:uid user) (passwd:gid user)))
(find-files data-dir #:directories? #t)))))))
(define (%caddy-shepherd config)
(list (shepherd-service
(provision '(caddy))
(requirement '(user-processes loopback))
(start
#~(make-forkexec-constructor
(list "/run/privileged/bin/caddy" "run"
"--environ" "--config" "/etc/caddy/Caddyfile")
#:user "caddy"
#:group "caddy"
#:directory "/var/lib/caddy"
#:log-file "/var/log/caddy.log"
#:resource-limits '((nofile 1048576 1048576))
#:environment-variables '("HOME=/var/lib/caddy")))
(stop
#~(make-kill-destructor)))))
(define caddy-service-type
(service-type
(name 'caddy)
(extensions
(list (service-extension account-service-type
caddy-configuration-accounts)
(service-extension privileged-program-service-type
caddy-configuration-privileged-program)
(service-extension activation-service-type
caddy-configuration-activation)
(service-extension shepherd-root-service-type
caddy-configuration-shepherd)))
(default-value #f)
(description "")))
--8<---------------cut here---------------end--------------->8---