services: rework bitcoin-core service to use a system account
authoralex <[email protected]>
Sat, 6 Sep 2025 07:49:30 +0000 (00:49 -0700)
committeralex <[email protected]>
Sat, 6 Sep 2025 23:24:14 +0000 (16:24 -0700)
This gets around the problem of a user's home not being able to be
written if the data directory is created inside the user's home with the
wrong permissions.

infiniteadaptability/services/bitcoin-core.scm

index d319b0277781e968c351bcf57ec1e1a871112596..fe9df2936f9a986a85180524688feda3e3dd4683 100644 (file)
@@ -1,9 +1,12 @@
 (define-module (infiniteadaptability services bitcoin-core)
   #:use-module (gnu)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages base)
   #:use-module (gnu packages finance)
   #:use-module (gnu services)
   #:use-module (gnu services shepherd)
   #:use-module (guix gexp)
+  #:use-module (guix modules)
   #:use-module (guix records)
   #:export (bitcoin-core-configuration bitcoin-core-service-type))
 
@@ -18,7 +21,7 @@
            (default bitcoin-core))
 
   (datadir bitcoin-core-configuration-datadir ;string
-           (default "/home/bitcoin/.bitcoin"))
+           (default "/bitcoin/.bitcoin"))
 
   (extra-content bitcoin-core-configuration-extra-content ;string
                  (default "")))
         (user-account
           (name %username)
           (group %username)
-          (home-directory (string-append "/home/" %username)))))
-
-(define (bitcoin-core-activation config)
-  "Return the activation GEXP for CONFIG."
-  (with-imported-modules '((guix build utils))
-                         #~(begin
-                             (use-modules (guix build utils))
-                             (define %user
-                               (getpw #$(bitcoin-core-configuration-user
-                                         config)))
-
-                             (let* ((homedir (passwd:dir %user))
-                                    (datadir #$(bitcoin-core-configuration-datadir
-                                                config)))
-                               
-                               ;; This is important if the datadir is inside the user's directory
-                               (mkdir-p homedir)
-                               (chown homedir
-                                      (passwd:uid %user)
-                                      (passwd:gid %user))
-
-                               (mkdir-p datadir)
-                               (chown datadir
-                                      (passwd:uid %user)
-                                      (passwd:gid %user))))))
+          (system? #t)
+          (home-directory "/var/run/bitcoin")
+          (shell (file-append shadow "/sbin/nologin")))))
 
 (define (bitcoin-core-service config)
   "Return a <bitcoin-core-service> for bitcoin with CONFIG."
@@ -80,6 +61,9 @@
   (define config-file
     (bitcoin-core-config-file config))
 
+  (define datadir
+    (bitcoin-core-configuration-datadir config))
+
   (define bitcoind-command
     #~(list (string-append #$(bitcoin-core-configuration-bitcoin config)
                            "/bin/bitcoind")
             (string-append "-pid="
                            #$pid-file) "-daemon"))
 
+  (define username
+    (bitcoin-core-configuration-user config))
+
   (list (shepherd-service (documentation "bitcoin core service")
                           (provision '(bitcoin-core))
                           (requirement '(user-processes networking))
-                          (start #~(make-forkexec-constructor #$bitcoind-command
-                                                              #:pid-file #$pid-file
-                                                              #:user "bitcoin"
-                                                              #:group
-                                                              "bitcoin"
-                                                              #:directory
-                                                              "/home/bitcoin"))
+                          (start (with-imported-modules (source-module-closure '
+                                                         ((gnu build
+                                                               activation)))
+                                                        #~(begin
+                                                            (use-modules (gnu
+                                                                          build
+                                                                          activation))
+                                                            (let ((user (getpw #$username)))
+                                                              (mkdir-p/perms #$datadir
+                                                               user #o755))
+
+                                                            (make-forkexec-constructor #$bitcoind-command
+                                                             #:pid-file #$pid-file
+                                                             #:user #$username
+                                                             #:group #$username
+                                                             #:directory
+                                                             "/var/run/bitcoin"))))
 
                           (stop #~(make-kill-destructor SIGINT
                                                         #:grace-period 600)))))
                 (extensions (list (service-extension
                                    shepherd-root-service-type
                                    bitcoin-core-service)
-                                  (service-extension activation-service-type
-                                                     bitcoin-core-activation)
                                   (service-extension account-service-type
                                                      bitcoin-core-accounts)))))