guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

code review


From: Catonano
Subject: code review
Date: Mon, 11 Sep 2017 22:10:22 +0200

I could use some code review on my Trytond service hypothesis

As far as I understand, there are 2 steps that need to be done in order for a Trytond service to be usable.

1) as the "postgres" role (that is as the operating system "postgres" user), create a "tryton" role

2) as the tryton user (hence under the tryton role) run the Tryton initialization script (trytond-admin -c <config file> -d <database name> --all)

I feel like I should extend the postgresql service in order to create te trytond role but I don't know how

Also, I create the trytond role with no password. But what if someone wants to use this service for a real server ?

The role password should be a parameter somehow. Again, I'm not sure how

I borrowed some code from the postgresql service code and somewhat edited it

But I feel like an amateur neurosurgeon :-/

I could really use a review of this code

Here it is

(define-module (gnu services trytond)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu system shadow)
  #:use-module (gnu packages admin)
 ;; do I really need to access the postgresql package, here ?
  #:use-module (gnu packages databases)
  #:use-module (gnu packages tryton) 
  #:use-module (guix modules)
  #:use-module (guix records)
  #:use-module (guix gexp)
  #:use-module (ice-9 match)
  #:export (trytond-configuration
            trytond-configuration?
            trytond-service
            trytond-service-type
            ))

;;; Commentary:
;;;
;;; Trytond based services. Mainly Trytond and GNUHealth for now
;;;
;;; Code:

(define-record-type* <trytond-configuration>
  trytond-configuration make-trytond-configuration
  trytond-configuration?
  (trytond     trytond-configuration-trytond ;<package>
               (default trytond))
;; do I really need to access the postgresql package, here ?
  (postgresql  postgresql-configuration-trytond
               (default postgresql))
  (locale         trytond-configuration-locale
                  (default "en_US.utf8"))
  (config-file    trytond-configuration-file)
  (data-directory trytond-configuration-data-directory)
  )


(define %default-trytond-config
  (mixed-text-file "trytond.conf"
                   "[database]\n"
                   ;; how do I connect with a role that has no password  ?
                   ;; I create the trytond role without the password
                   ;; but what if someone wants to use this service for a real server ?
                   ;; the password should be a parameter, somehow
                   ;;"uri = 'postgresql://trytond:password@/'\n"
                   "uri = 'postgresql://trytond:@/'\n" ;; is this string gonna work ?
                   "path = /var/lib/trytond"))

(define %trytond-accounts
  (list (user-group (name "trytond") (system? #t))
        (user-account
         (name "trytond")
         (group "trytond")
         (system? #t)
         (comment "Trytond server user")
         (home-directory "/var/empty")
         (shell (file-append shadow "/sbin/nologin")))))

(define trytond-activation
  (match-lambda
    (($ <trytond-configuration> trytond postgresql locale config-file data-directory)
     #~(begin
         (use-modules (guix build utils)
                                (gnu packages database)
                                (ice-9 match))

         (let ((trytond-user (getpwnam "trytond"))
               (postgres-user (getpwnam "postgres"))
               (create-the-trytond-role (string-append #$postgresql
                                       "/bin/createuser"
                                       "trytond"
                                        "-d")) ;; the role can create new DBs
               (run-the-trytond-init-script (string-append #$trytond
                                      "/bin/trytond-admin"
                                      "-c"
                                      #$config-file
                                      "-d"
                                      "trytondb" ;;the database name
                                      "--all"))
               (trytond-initscript-args
                (append
                 (if #$locale
                     (list (string-append "-l " #$locale))
                     '()))))
           ;; Create data directory.
           (mkdir-p #$data-directory)
           (chown #$data-directory
                  (passwd:uid trytond-user)
                  (passwd:gid trytond-user))

          
           ;; Drop privileges and create the tryton role in a new
           ;; process.  Wait for it to finish before proceeding.
           ;; shouldn't this be done by extending the postgresql service ?
           ;; but how ?
           (match (primitive-fork)
             (0
              ;; Exit with a non-zero status code if an exception is thrown.
              (dynamic-wind
                (const #t)
                (lambda ()
                  (setgid (passwd:gid postgres-user))
                  (setuid (passwd:uid postgres-user))
                  (primitive-exit
                   (apply system*
                          ;; shouldn't this be done by an extension to the postgresql service ?
                          ;; but how ?
                          create-the-trytond-role)))
                (lambda ()
                  (primitive-exit 1))))
             (pid (waitpid pid))))))))



          
           ;; Drop privileges and run the trytond init script in a new
           ;; process.  Wait for it to finish before proceeding.
           (match (primitive-fork)
             (0
              ;; Exit with a non-zero status code if an exception is thrown.
              (dynamic-wind
                (const #t)
                (lambda ()
                  (setgid (passwd:gid trytond-user))
                  (setuid (passwd:uid trytond-user))
                  (primitive-exit
                   (apply system*
                          run-the-trytond-init-script
                          trytond-initscript-args)))
                (lambda ()
                  (primitive-exit 1))))
             (pid (waitpid pid))))))))

(define trytond-shepherd-service
  (match-lambda
    (($ <trytond-configuration> trytond locale config-file)
     (let ((start-script
            ;; Wrapper script that switches to the 'trytond' user before
            ;; launching daemon.
            (program-file "start-trytond"
                          #~(let ((user (getpwnam "trytond"))
                                  (trytond (string-append #$trytond
                                                           "/bin/trytond")))
                              (setgid (passwd:gid user))
                              (setuid (passwd:uid user))
                              (system* trytond
                                       (string-append "-c "
                                                      #$config-file))))))
       (list (shepherd-service
              (provision '(trytond))
              (documentation "Run the Trytond daemon.")
              (requirement '(user-processes loopback postgresql))
              ;; why do I require the postgrresql service if I don't use it ?
              (start #~(make-forkexec-constructor #$start-script))
              (stop #~(make-kill-destructor))))))))

(define trytond-service-type
  (service-type (name 'trytond)
                (extensions
     ;; how is the postgresql service meant to be extended ?
                 (list (service-extension shepherd-root-service-type
                                          trytond-shepherd-service)
                       (service-extension activation-service-type
                                          trytond-activation)
                       (service-extension account-service-type
                                          (const %trytond-accounts))))))

(define* (trytond-service #:key (trytond trytond)
                          (postgresql postgresql)
                             ;;(port 5432) ;; The port is in the config file
                          (locale "en_US.utf8")
                          (config-file %default-trytond-config)
                          ;;(data-directory "/var/lib/trytond/data")
                          )
  "Return a service that runs @var{trytond}, the Tryton server component.

The Trytond daemon loads its runtime configuration from @var{config-file}
and relies on the PostgreSQL service for data storage."
  (service trytond-service-type
           (trytond-configuration
            (trytond trytond)
            (postgresql postgresql) ;; sigh
            ;;(port port)
            (locale locale)
            (config-file config-file)
            ;;(data-directory data-directory)
            )))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]