(define-module (vkraus modules minetest) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu services admin) #:use-module (gnu system shadow) #:use-module (guix gexp) #:use-module (guix modules) #:use-module (guix records) #:use-module (guix packages) #:use-module (guix build-system minetest) #:use-module (guix git-download) #:use-module (gnu packages bash) #:use-module (gnu packages minetest) #:use-module (gnu packages admin) #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:use-module (ice-9 optargs) #:use-module ((guix licenses) #:prefix license:) #:export ( make-minetest-server-configuration minetest-server-configuration? minetest-server-configuration-admin minetest-server-configuration-games minetest-server-configuration-mods minetest-shepherd-service minetest-service-type)) (define-record-type (make-minetest-server-configuration admin games mods) minetest-server-configuration? (admin minetest-server-configuration-admin) (games minetest-server-configuration-games) (mods minetest-server-configuration-mods)) (define minetest-shepherd-service (match-lambda (($ admin games mods) (let ((script-file (computed-file "minetest-with-log-files" #~(begin (call-with-output-file #$output (lambda (port) (format port "#!~a/bin/bash ~a/bin/minetest \"$@\" >> /var/log/minetest/server.log 2>>/var/log/minetest/server.err " #$bash #$minetest))) (chmod #$output #o755)))) (game-pack (directory-union "minetest-game-pack" (map (cute file-append <> "/share/minetest/games") games))) (mod-pack (directory-union "minetest-mod-pack" (map (cute file-append <> "/share/minetest/mods") mods))) (config-file (plain-file "minetest.conf" (format #f "bind_address = eno1 ipv6_server = true name = ~a default_privs = \"\" " admin)))) (list (shepherd-service (provision '(minetest)) (documentation "Run a sensible minetest server") (requirement '(user-processes)) (modules '((gnu build shepherd) (gnu system file-systems))) (start (with-imported-modules (source-module-closure '((gnu build shepherd) (gnu system file-systems))) #~(begin (let ((user (getpwnam "minetest"))) (for-each (lambda (dir) (mkdir-p dir) (chown dir (passwd:uid user) (passwd:gid user)) (chmod dir #o700)) '("/var/log/minetest" "/var/lib/minetest")) (chown "/etc/minetest/password" (passwd:uid user) (passwd:gid user)) (chmod "/etc/minetest/password" #o700) (false-if-exception (delete-file "/var/lib/minetest/home/.minetest/debug.txt")) (make-forkexec-constructor (list #$script-file "--server" "--password-file" "/etc/minetest/password" "--world" "/var/lib/minetest/world" "--config" #$config-file) #:user "minetest" #:group "minetest" #:environment-variables `(,(format #f "MINETEST_SUBGAME_PATH=~a" #$game-pack) ,(format #f "MINETEST_MOD_PATH=~a" #$mod-pack) "HOME=/var/lib/minetest/home")))))) (stop #~(make-kill-destructor)))))))) (define %minetest-accounts (list (user-group (name "minetest") (system? #t)) (user-account (name "minetest") (group "minetest") (system? #t) (comment "The user that runs the minetest server.") (home-directory "/var/empty") (shell (file-append shadow "/sbin/nologin"))))) (define %minetest-rottlog `(,(log-rotation (frequency 'weekly) (files (list "/var/log/minetest/server.log" "/var/log/minetest/server.err")) (options '("sharedscripts" "storedir /var/log/minetest"))))) (define minetest-service-type (service-type (name 'minetest) (description "Run a minetest server") (extensions (list (service-extension account-service-type (const %minetest-accounts)) (service-extension rottlog-service-type (const %minetest-rottlog)) (service-extension shepherd-root-service-type minetest-shepherd-service)))))