(define-module (glicid services parallel)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (guix)
  #:use-module (guix records)
  #:use-module (ice-9 match)
  #:use-module (gnu packages parallel)
  #:use-module (glicid system file-systems)
  #:export (
    munged-configuration
    munged-configuration?
    munged-service
    munged-service-type
    slurmdbd-configuration
    slurmdbd-configuration?
    slurmdbd-service
    slurmdbd-service-type
    slurmctld-configuration
    slurmctld-configuration?
    slurmctld-service
    slurmctld-service-type
    slurmd-configuration
    slurmd-configuration?
    slurmd-service
    slurmd-service-type
  )
)

;
; Munged
;
(define-record-type* <munged-configuration>
  munged-configuration make-munged-configuration
  munged-configuration?
  (munge munge-configuration-munge
    (default munge)
  )
  (key-file munged-key-file
    (default (file-append munge "/etc/munge/munged.key"))
  )
  (log-file munged-log-file
    (default "/var/log/munged.log")
  )
)

(define munged-service
  (match-lambda
    (($ <munged-configuration> munge key-file log-file)
      (list
        (shepherd-service
          (provision '(munged) )
          (documentation "Run munged.")
          (requirement '(user-processes))
          (respawn? #t)
          (start #~(make-forkexec-constructor
            (list
              #$(file-append munge "/sbin/munged")
              "-F"
              "-f" ; until we fix the permissions
              "--key-file" #$key-file
            )
            #:log-file #$log-file
          ))
          (stop #~(make-kill-destructor))
        )
      )
    )
  )
)

(define %munged-activation
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/var/run/munge")
        (mkdir-p "/var/lib/munge")
        #t
    )
  )
)

(define munged-service-type
  (service-type (name 'munged)
    (extensions 
      (list
        (service-extension shepherd-root-service-type munged-service)
        (service-extension activation-service-type (const %munged-activation))
      )
    )
    (description "Run munged")
  )
)

;
; slurmdbd
;
(define-record-type* <slurmdbd-configuration>
  slurmdbd-configuration make-slurmdbd-configuration
  slurmdbd-configuration?
  (slurm slurm-configuration-slurm
    (default slurm)
  )
  (slurmdbd-conf slurmdbd-slurmdbd-conf
    (default (file-append slurm "/etc/slurm/slurmdbd.conf"))
  )
  (log-file slurmdbd-log-file
    (default "/var/log/slurmdbd.log")
  )
)

(define slurmdbd-service
  (match-lambda
    (($ <slurmdbd-configuration> slurm slurmdbd-conf log-file)
      (list
        (shepherd-service
          (provision '(slurmdbd) )
          (documentation "Run slurmdbd.")
          (requirement '(user-processes))
          (respawn? #t)
          (start #~(make-forkexec-constructor
            (list
              #$(file-append slurm "/sbin/slurmdbd")
              "-D"
            )
            #:log-file #$log-file
          ))
          (stop #~(make-kill-destructor))
        )
      )
    )
  )
)

(define %slurmdbd-activation
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/var/log/slurm")
        (mkdir-p "/var/lib/slurm-archives")
        (mkdir-p "/var/lib/slurm")
        ;(chmod "0600" "/etc/slurm/slurmdbd.conf")
        #t
    )
  )
)

(define slurmdbd-service-type
  (service-type (name 'slurmdbd)
    (extensions 
      (list
        (service-extension shepherd-root-service-type slurmdbd-service)
        (service-extension activation-service-type (const %slurmdbd-activation))
      )
    )
    (description "Run slurmdbd")
  )
)

;
; slurmctld
;
(define-record-type* <slurmctld-configuration>
  slurmctld-configuration make-slurmctld-configuration
  slurmctld-configuration?
  (slurm slurm-configuration-slurm
    (default slurm)
  )
  (slurmctld-conf slurmctld-slurmctld-conf
    (default (file-append slurm "/etc/slurm/slurmctld.conf"))
  )
  (log-file slurmctld-log-file
    (default "/var/log/slurmctld.log")
  )
)

(define slurmctld-service
  (match-lambda
    (($ <slurmctld-configuration> slurm slurmctld-conf log-file)
      (list
        (shepherd-service
          (provision '(slurmctld) )
          (documentation "Run slurmctld.")
          (requirement '(user-processes))
          (respawn? #t)
          (start #~(make-forkexec-constructor
            (list
              #$(file-append slurm "/sbin/slurmctld")
              "-D" "-R"
              "-f" #$slurmctld-conf
            )
            #:log-file #$log-file
          ))
          (stop #~(make-kill-destructor))
        )
      )
    )
  )
)

(define %slurmctld-activation
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/var/log/slurm")
        (mkdir-p "/var/lib/slurm-archives")
        (mkdir-p "/var/lib/slurm")
        #t
    )
  )
)

(define slurmctld-service-type
  (service-type (name 'slurmctld)
    (extensions 
      (list
        (service-extension shepherd-root-service-type slurmctld-service)
        (service-extension activation-service-type (const %slurmctld-activation))
      )
    )
    (description "Run slurmctld")
  )
)

;
; slurmd
;
(define-record-type* <slurmd-configuration>
  slurmd-configuration make-slurmd-configuration
  slurmd-configuration?
  (slurm slurm-configuration-slurm
    (default slurm)
  )
  (slurmd-conf slurmd-slurmd-conf
    (default (file-append slurm "/etc/slurm/slurm.conf"))
  )
  (log-file slurmd-log-file
    (default "/var/log/slurmd.log")
  )
  (slurmctld-host slurmd-slurmctld-host
    (default #f) ; string slurmctld-host[:port]
  )
  (log-level slurmd-log-level
    (default #f) ; string Verbose mode. Multiple -v's increase verbosity
  )
)

(define slurmd-service
  (match-lambda
    (($ <slurmd-configuration> slurm slurmd-conf slurmctld-host log-file log-level)
      (list
        (shepherd-service
          (provision '(slurmd) )
          (documentation "Run slurmd.")
          (requirement '(
            user-processes
;            file-system-/sys/fs/cgroup/blkio
;            file-system-/sys/fs/cgroup/cpu
;            file-system-/sys/fs/cgroup/cpuset
;            file-system-/sys/fs/cgroup/devices
;            file-system-/sys/fs/cgroup/memory
;            file-system-/sys/fs/cgroup/pids
;            file-system-/sys/fs/cgroup/cpuacct
;            file-system-/sys/fs/cgroup/freezer
;            file-system-/sys/fs/cgroup/hugetlb
;            file-system-/sys/fs/cgroup/net_cls
;            file-system-/sys/fs/cgroup/net_prio
;            file-system-/sys/fs/cgroup/perf_event
;            file-system-/sys/fs/cgroup/pids
;            file-system-/sys/fs/cgroup/rdma
;            file-system-/sys/fs/cgroup/unified
;            file-system-/sys/fs/cgroup/networking
;            file-system-/sys/fs/cgroup/udev
          ))
          (respawn? #t)
          (start #~(make-forkexec-constructor
            (list
              #$(file-append slurm "/sbin/slurmd")
              "-D"
              #$@(if slurmctld-host
                (list (string-append "--conf-server" slurmctld-host))
                (list (string-append "-f" slurmd-conf))
              )
              #$@(if log-level
                (list log-level)
                '()
              )
              
            )
            #:log-file #$log-file
          ))
          (stop #~(make-kill-destructor))
        )
      )
    )
  )
)

(define %slurmd-activation
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/var/log/slurm")
        (mkdir-p "/var/lib/slurm-archives")
        (mkdir-p "/var/lib/slurm")
        #t
    )
  )
)

(define slurmd-service-type
  (service-type (name 'slurmd)
    (extensions 
      (list
        (service-extension shepherd-root-service-type slurmd-service)
        (service-extension activation-service-type (const %slurmd-activation))
      )
    )
    (description "Run slurmd")
  )
)
