summaryrefslogtreecommitdiff
path: root/px/services
diff options
context:
space:
mode:
Diffstat (limited to 'px/services')
-rw-r--r--px/services/base.scm293
-rw-r--r--px/services/bluetooth.scm114
-rw-r--r--px/services/databases.scm132
-rw-r--r--px/services/desktop.scm124
-rw-r--r--px/services/device.scm332
-rw-r--r--px/services/disk.scm99
-rw-r--r--px/services/enterprise.scm126
-rw-r--r--px/services/log.scm152
-rw-r--r--px/services/monitoring.scm116
-rw-r--r--px/services/networking.scm157
-rw-r--r--px/services/ntp.scm73
-rw-r--r--px/services/package-management.scm64
-rw-r--r--px/services/security-token.scm123
-rw-r--r--px/services/server.scm76
14 files changed, 1981 insertions, 0 deletions
diff --git a/px/services/base.scm b/px/services/base.scm
new file mode 100644
index 0000000..91a966e
--- /dev/null
+++ b/px/services/base.scm
@@ -0,0 +1,293 @@
+;;; PantherX System Configuration Module
+;;; This module supports configuration modules for PantherX OS definitions
+;;;
+;;; Reza Alizadeh Majd <r.majd@pantherx.org>
+;;; Franz Geffke <franz@pantherx.org>
+;;;
+
+(define-module (px services base)
+ #:use-module (gnu packages gnome)
+ #:use-module (gnu packages openbox)
+ #:use-module (gnu packages networking)
+ #:use-module (gnu packages security-token)
+ #:use-module (gnu packages xdisorg)
+ #:use-module (gnu services)
+ #:use-module (gnu services avahi)
+ #:use-module (gnu services base)
+ #:use-module (gnu services cups)
+ #:use-module (gnu services dbus)
+ #:use-module (gnu services desktop)
+ #:use-module (gnu services networking)
+ #:use-module (gnu services pm)
+ #:use-module (gnu services sddm)
+ #:use-module (gnu services sound)
+ #:use-module (gnu services ssh)
+ #:use-module (gnu services xorg)
+ #:use-module (px packages desktop)
+ #:use-module (px services desktop)
+ #:use-module (px services device)
+ #:use-module (px services security-token)
+ #:use-module (guix gexp)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:export (%px-core-services
+
+ ;; for custom desktops (for ex. xfce)
+ ;; without lxqt
+ %px-desktop-services-base
+
+ %px-desktop-services
+ %px-desktop-ee-services
+
+ ;; for custom servers (for ex. docker)
+ ;; without nftables and dh
+ %px-server-services-base
+
+ %px-server-services
+ ; %px-server-iptables-services
+ %px-server-ee-services
+
+ %px-core-arm-services
+ %px-gui-arm-services
+ %px-desktop-arm-services)
+
+ #:re-export (px-desktop-service-type))
+
+;;;
+;;; Utilities
+;;;
+
+(define (make-firewall-rules open-ports)
+
+ (define (make-port-rules open-ports status)
+ "Generate list of strings each is a port/service rule for nftables"
+ (reduce-right append '()
+ (map (match-lambda
+ ((protocol ports ...)
+ (map (lambda (port)
+ (string-append " " protocol " dport " port " " status))
+ ports)))
+ open-ports)))
+
+ (let ((port-rules (make-port-rules open-ports "accept")))
+ (plain-file "nftables"
+ (string-append "#PantherX firewall rules\n"
+ "table inet filter {\n"
+ " chain input {\n"
+ " type filter hook input priority 0; policy drop;\n"
+ " # early drop of invalid connections\n"
+ " ct state invalid drop\n"
+ " # allow established/related connections\n"
+ " ct state { established, related } accept\n"
+ " # allow from loopback\n"
+ " iifname lo accept\n"
+ " # allow icmp\n"
+ " ip protocol icmp accept\n"
+ " ip6 nexthdr icmpv6 accept\n"
+ (string-join port-rules "\n" 'suffix)
+ " # reject everything else\n"
+ " reject with icmpx type port-unreachable\n"
+ " }\n"
+ " chain forward {\n"
+ " type filter hook forward priority 0; policy drop;\n"
+ " }\n"
+ " chain output {\n"
+ " type filter hook output priority 0; policy accept;\n"
+ " }\n"
+ "}\n"))))
+
+;;;
+;;;
+;;; CORE
+;;;
+
+(define %px-core-services
+ (append
+ ;; list of services that only required to be available in px-core-os,
+ ;; since they are available by default in upstream's %desktop-services
+ (list (service dhcp-client-service-type)
+ (service ntp-service-type))
+ %base-services))
+
+;;;
+;;; DESKTOP
+;;;
+
+(define %px-desktop-services-base
+ (append (list
+ ;; Various udev rules incl. FIDO support
+ (simple-service 'custom-udev-rules
+ udev-service-type
+ (list libu2f-host))
+
+ (ledger-wallet-service)
+ (nitro-key-service)
+
+ ;; Power savings
+ (service tlp-service-type)
+
+ ;; Bluetooth service
+ ;; (bluetooth-service #:auto-enable? #t)
+ (service bluetooth-service-type
+ (bluetooth-configuration
+ (auto-enable? #t)))
+
+ ;; Prevent overheating
+ ;; TLP does not conflict with thermald.
+ (service thermald-service-type)
+
+ ; Display manager
+ (service sddm-service-type
+ (sddm-configuration
+ (minimum-uid 1000)
+ (theme "px-sddm-theme")))
+
+ ;; Printing
+ (service cups-service-type
+ (cups-configuration
+ (web-interface? #t)
+ (browsing? #t)
+ (default-paper-size "a4")))
+
+ ;; Keychain
+ (service gnome-keyring-service-type
+ (gnome-keyring-configuration
+ (pam-services '(("passwd" . passwd)
+ ("sddm" . login)))))
+
+ ;; SSH is enabled by default but only with SSH key
+ (service openssh-service-type
+ (openssh-configuration
+ (permit-root-login 'prohibit-password)))
+
+ ;; Firewall
+ (service nftables-service-type
+ (nftables-configuration
+ (ruleset (make-firewall-rules '()))))
+
+ ;; Screensaver
+ (service screen-locker-service-type
+ (screen-locker-configuration
+ (name "xlock")
+ (program (file-append xlockmore "/bin/xlock")))))
+
+ (modify-services %desktop-services
+ ;; GDM is default on upstream, on x86_64
+ (delete gdm-service-type)
+ (delete screen-locker-service-type)
+ (dbus-root-service-type config => (dbus-configuration (inherit config)
+ (services (list blueman))))
+ (network-manager-service-type config =>
+ (network-manager-configuration
+ (inherit config)
+ (vpn-plugins (list network-manager-openvpn
+ network-manager-openconnect)))))))
+
+(define %px-desktop-services
+ (append
+ %px-desktop-services-base))
+
+(define %px-desktop-ee-services
+ (append (list (service px-device-identity-service-type)
+ (service px-user-identity-service-type)
+ ;; Desktop
+ (service px-desktop-service-type))
+ %px-desktop-services-base))
+
+;;;
+;;; SERVER
+;;;
+
+(define %px-server-services-base
+ (append (list
+ ;; OpenSSH is enabled by default but only with SSH key
+ (service openssh-service-type
+ (openssh-configuration
+ (permit-root-login 'prohibit-password)))
+
+ ;; Time service
+ (service ntp-service-type))
+
+ %base-services))
+
+(define %px-server-services
+ (append (list
+ ;; Firewall
+ (service nftables-service-type)
+ ;; DHCP
+ (service dhcp-client-service-type))
+ %px-server-services-base))
+
+; (define %px-server-iptables-services
+; (append (list
+; ;; Firewall
+; ;; nftables doesn't work well with Docker
+; (service iptables-service-type))
+; %px-server-services-base))
+
+(define %px-server-ee-services
+ (append (list (service px-device-identity-service-type)
+ ;; Firewall
+ (service nftables-service-type)
+ ;; DHCP
+ (service dhcp-client-service-type))
+ %px-server-services-base))
+
+;;;
+;;; ARM-SPECIFIC
+;;;
+
+(define %px-core-arm-services
+ (cons*
+ ;; networking
+ (service wpa-supplicant-service-type)
+ (service network-manager-service-type)
+ (service modem-manager-service-type)
+ (service usb-modeswitch-service-type)
+ (service ntp-service-type)
+
+ ;; remote access
+ (service openssh-service-type
+ (openssh-configuration
+ (x11-forwarding? #t)
+ (permit-root-login #t)))
+
+ %base-services))
+
+(define %px-gui-arm-services
+ (cons*
+ (service slim-service-type
+ (slim-configuration
+ (vt "vt7")
+ (auto-login? #t)
+ (auto-login-session (file-append openbox "/bin/openbox-session"))
+ (default-user "default")))
+ (service avahi-service-type)
+ (service udisks-service-type)
+ (service upower-service-type)
+ (service accountsservice-service-type)
+ (service polkit-service-type)
+ (service elogind-service-type)
+ (service dbus-root-service-type)
+ polkit-wheel-service
+ polkit-network-manager-service ;; control network without sudo
+ polkit-elogind-service ;; reboot without sudo
+
+ (service pulseaudio-service-type)
+ (service alsa-service-type)
+ %px-core-arm-services))
+
+(define %px-desktop-arm-services
+ (append
+ (list (service dhcp-client-service-type)
+ (service sddm-service-type
+ (sddm-configuration
+ (minimum-uid 1000)
+ (theme "px-sddm-theme")))
+ (service px-desktop-service-type
+ (px-desktop-configuration
+ (lxqt lxqt-modified)
+ (default-packages '()))))
+ (modify-services %desktop-services
+ (delete gdm-service-type)
+ (delete network-manager-service-type)))) \ No newline at end of file
diff --git a/px/services/bluetooth.scm b/px/services/bluetooth.scm
new file mode 100644
index 0000000..d8953df
--- /dev/null
+++ b/px/services/bluetooth.scm
@@ -0,0 +1,114 @@
+(define-module (px services bluetooth)
+ #:use-module (gnu)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu packages video)
+ #:use-module (gnu services mcron)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system)
+ #:use-module (gnu system shadow)
+
+ #:use-module (px packages device)
+ #:use-module (px packages security-token)
+ #:use-module (px packages tpm)
+
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+
+ #:export (btuart-configuration
+ btuart-service-type
+
+ bluetooth-client-manager-configuration
+ bluetooth-client-manager-service-type))
+
+;;
+;; btuart-service-type
+;;
+
+(define-record-type* <btuart-configuration>
+ btuart-configuration make-btuart-configuration
+ btuart-configuration?
+ (package btuart-configuration-package
+ (default bluez))
+ (device btuart-configuration-device
+ (default "/dev/ttyAMA0"))
+ (protocol btuart-configuration-protocol
+ (default "bcm"))
+ (baudrate btuart-configuration-baudrate
+ (default "3000000"))
+ (flow-control? btuart-configuration-flow-control?
+ (default #t)))
+
+
+(define btuart-shepherd-service
+ (match-lambda
+ (($ <btuart-configuration> package device protocol baudrate flow-control?)
+ (list
+ (shepherd-service
+ (documentation "attach serial lines as Bluetooth HCI interfaces")
+ (provision '(btuart))
+ (requirement '(udev))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append package "/bin/btattach")
+ "-B" #$device "-P" #$protocol
+ "-S" #$baudrate
+ (when #$flow-control? "-N"))))
+ (one-shot? #t))))))
+
+
+(define btuart-service-type
+ (service-type
+ (name 'btuart)
+ (extensions (list (service-extension shepherd-root-service-type
+ btuart-shepherd-service)))
+ (default-value (btuart-configuration))
+ (description "Attach serial lines as Bluetooth HCI interfaces")))
+
+;;
+;; bluetooth-client-manager-service
+;;
+
+(define-record-type* <bluetooth-client-manager-configuration>
+ bluetooth-client-manager-configuration make-bluetooth-client-manager-configuration
+ bluetooth-client-manager-configuration?
+ (package bluetooth-client-manager-configuration-package
+ (default bluetooth-client-manager-service))
+ (debug? bluetooth-client-manager-configuration-debug?
+ (default #f))
+ (skip-approval? bluetooth-client-manager-configuration-skip-approval?
+ (default #f)))
+
+
+(define bluetooth-client-manager-shepherd-service
+ (match-lambda
+ (($ <bluetooth-client-manager-configuration> package debug? skip-approval?)
+ (list (shepherd-service
+ (provision '(bluetooth-client-manager-service))
+ (documentation "Run px-device-identity-service as a daemon")
+ (requirement '(networking user-processes px-device-identity))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/bin/bluetooth-client-manager-service")
+ #$@(if debug? '("--verbose") '())
+ #$@(if skip-approval? '("--skip-approval") '()))
+ #:log-file "/var/log/bluetooth-client-manager-service.log"
+ #:environment-variables
+ (cons* "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))))
+ (stop #~(make-kill-destructor)))))))
+
+
+(define bluetooth-client-manager-service-type
+ (service-type
+ (name 'bluetooth-client-manager-service)
+ (description "PantherX Bluetooth Client Manager service")
+ (extensions (list (service-extension shepherd-root-service-type
+ bluetooth-client-manager-shepherd-service)))
+ (default-value (bluetooth-client-manager-configuration))))
diff --git a/px/services/databases.scm b/px/services/databases.scm
new file mode 100644
index 0000000..aa90f20
--- /dev/null
+++ b/px/services/databases.scm
@@ -0,0 +1,132 @@
+;;; Databases service definitions for PantherX
+;;; Author: Reza Alizadeh Majd (r.majd@pantherx.org)
+
+
+(define-module (px services databases)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system shadow)
+ #:use-module (gnu packages admin)
+ #:use-module (guix modules)
+ #:use-module (guix records)
+ #:use-module (guix gexp)
+ #:use-module (px packages databases)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 match)
+ #:export (mongodb-configuration
+ mongodb-configuration?
+ mongodb-configuration-mongodb
+ mongodb-configuration-config-file
+ mongodb-configuration-data-directory
+ mongodb-service-type))
+
+
+;;;
+;;; MongoDB
+;;;
+;;; @subsubheading MongoDB
+;;; @defvr {Scheme Variable} mongodb-service-type
+;;; This is the service type for @uref{https://www.mongodb.com/, MongoDB}.
+;;; The value for the service type is a @code{mongodb-configuration} object.
+;;; @end defvr
+;;; @lisp
+;;; (service mongodb-service-type)
+;;; @end lisp
+;;; @deftp {Data Type} mongodb-configuration
+;;; Data type representing the configuration of mongodb.
+;;; @table @asis
+;;; @item @code{mongodb} (default: @code{mongodb})
+;;; The MongoDB package to use.
+;;; @item @code{config-file} (default: @code{%default-mongodb-configuration-file})
+;;; The configuration file for MongoDB.
+;;; @item @code{data-directory} (default: @code{"/var/lib/mongodb"})
+;;; This value is used to create the directory, so that it exists and is
+;;; owned by the mongodb user. It should match the data-directory which
+;;; MongoDB is configured to use through the configuration file.
+;;; @end table
+;;; @end deftp
+
+
+(define %default-mongodb-configuration-file
+ (plain-file
+ "mongodb.yaml"
+ "# GNU Guix: MongoDB default configuration file
+processManagement:
+ pidFilePath: /var/run/mongodb/pid
+storage:
+ dbPath: /var/lib/mongodb
+"))
+
+
+(define-record-type* <mongodb-configuration>
+ mongodb-configuration make-mongodb-configuration
+ mongodb-configuration?
+ (mongodb mongodb-configuration-mongodb
+ (default mongodb))
+ (config-file mongodb-configuration-config-file
+ (default %default-mongodb-configuration-file))
+ (data-directory mongodb-configuration-data-directory
+ (default "/var/lib/mongodb")))
+
+(define %mongodb-accounts
+ (list (user-group (name "mongodb") (system? #t))
+ (user-account
+ (name "mongodb")
+ (group "mongodb")
+ (system? #t)
+ (comment "Mongodb server user")
+ (home-directory "/var/lib/mongodb")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define mongodb-activation
+ (match-lambda
+ (($ <mongodb-configuration> mongodb config-file data-directory)
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((user (getpwnam "mongodb")))
+ (for-each
+ (lambda (directory)
+ (mkdir-p directory)
+ (chown directory
+ (passwd:uid user) (passwd:gid user)))
+ '("/var/run/mongodb" #$data-directory)))))))
+
+(define mongodb-shepherd-service
+ (match-lambda
+ (($ <mongodb-configuration> mongodb config-file data-directory)
+ (shepherd-service
+ (provision '(mongodb))
+ (documentation "Run the Mongodb daemon.")
+ (requirement '(user-processes loopback))
+ (start #~(make-forkexec-constructor
+ `(,(string-append #$mongodb "/bin/mongod")
+ "--config"
+ ,#$config-file)
+ #:user "mongodb"
+ #:group "mongodb"
+ #:pid-file "/var/run/mongodb/pid"
+ #:log-file "/var/log/mongodb.log"))
+ (stop #~(make-kill-destructor))))))
+
+(define mongodb-service-type
+ (service-type
+ (name 'mongodb)
+ (description "Run the MongoDB document database server.")
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ (compose list
+ mongodb-shepherd-service))
+ (service-extension activation-service-type
+ mongodb-activation)
+ (service-extension account-service-type
+ (const %mongodb-accounts))))
+ (default-value
+ (mongodb-configuration))))
+
+
+(use-modules (gnu system)
+ (gnu bootloader)
+ (gnu bootloader grub)
+ (gnu system file-systems)
+ (px system config))
+
diff --git a/px/services/desktop.scm b/px/services/desktop.scm
new file mode 100644
index 0000000..2ce403d
--- /dev/null
+++ b/px/services/desktop.scm
@@ -0,0 +1,124 @@
+;;; Desktop service definitions for PantherX
+;;;
+;;; Reza Alizadeh Majd <r.majd@pantherx.org>
+;;; Franz Geffke <franz@pantherx.org>
+;;;
+
+(define-module (px services desktop)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages xdisorg)
+ #:use-module (gnu services)
+ #:use-module (gnu services avahi)
+ #:use-module (gnu services base)
+ #:use-module (gnu services cups)
+ #:use-module (gnu services dbus)
+ #:use-module (gnu services desktop)
+ #:use-module (gnu packages gnome)
+ #:use-module (gnu packages lxqt)
+ #:use-module (gnu services networking)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu services sddm)
+ #:use-module (gnu services ssh)
+ #:use-module (gnu services xorg)
+ #:use-module (gnu system)
+ #:use-module (gnu system setuid)
+ #:use-module (guix build utils)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix records)
+ #:use-module (px packages desktop)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 match)
+ #:export (px-desktop-configuration
+ px-desktop-configuration?
+ px-desktop-service-type
+
+ polkit-network-manager-service
+ polkit-elogind-service
+
+ create-swap-space-service))
+
+;;
+;; PantherX desktop service type
+;;
+
+(define-record-type* <px-desktop-configuration> px-desktop-configuration
+ make-px-desktop-configuration
+ px-desktop-configuration?
+ (lxqt px-config-package
+ (default lxqt-modified))
+ (default-packages px-config-default-packages
+ (default (list px-desktop-defaults))))
+
+(define (px-desktop-polkit-settings config)
+ "Return the list of LXQt dependencies that provide polkit actions and
+rules."
+ (list lxqt-admin))
+
+(define px-desktop-profile-packages
+ (lambda (config)
+ (append
+ (list (px-config-package config))
+ (px-config-default-packages config))))
+
+
+(define px-desktop-service-type
+ (service-type
+ (name 'px-desktop)
+ (extensions
+ (list (service-extension polkit-service-type
+ px-desktop-polkit-settings)
+ (service-extension profile-service-type
+ px-desktop-profile-packages)))
+ (default-value (px-desktop-configuration))
+ (description "Run LXQt desktop environment on PantherX.")))
+
+;;
+;; allow netdev group to control network manger
+;;
+
+(define polkit-network-manager
+ (file-union
+ "polkit-nm"
+ `(("share/polkit-1/rules.d/50-org.freedesktop.NetworkManager.rules"
+ ,(plain-file
+ "nm.rules"
+ "polkit.addRule(function(action, subject) {
+ if (action.id.indexOf(\"org.freedesktop.NetworkManager.\") == 0 && subject.isInGroup(\"netdev\")) {
+ return polkit.Result.YES;
+ }
+});
+")))))
+
+
+;; primarily for ARM
+
+(define polkit-network-manager-service
+ (simple-service 'polkit-nm polkit-service-type (list polkit-network-manager)))
+
+;;
+;; Allow users group to perform reboot/poweroff
+;; primarily for ARM
+;;
+
+(define polkit-loginctl
+ (file-union
+ "polkit-loginctl"
+ `(("share/polkit-1/rules.d/10-enable-session-power.rules"
+ ,(plain-file
+ "login.rules"
+ "polkit.addRule(function(action, subject) {
+ if ( (action.id == \"org.freedesktop.login1.reboot\" ||
+ action.id == \"org.freedesktop.login1.reboot-multiple-sessions\" ||
+ action.id == \"org.freedesktop.login1.power-off\" ||
+ action.id == \"org.freedesktop.login1.power-off-multiple-sessions\")
+ && subject.isInGroup(\"users\") ) {
+ return polkit.Result.YES;
+ }
+});
+")))))
+
+(define polkit-elogind-service
+ (simple-service 'polkit-login polkit-service-type (list polkit-loginctl))) \ No newline at end of file
diff --git a/px/services/device.scm b/px/services/device.scm
new file mode 100644
index 0000000..4fbbc64
--- /dev/null
+++ b/px/services/device.scm
@@ -0,0 +1,332 @@
+(define-module (px services device)
+ #:use-module (gnu)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu packages video)
+ #:use-module (gnu services mcron)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system)
+ #:use-module (gnu system shadow)
+
+ #:use-module (px packages device)
+ #:use-module (px packages security-token)
+ #:use-module (px packages tpm)
+
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+
+ #:export (<px-device-identity-configuration>
+ px-device-identity-configuration
+ px-device-identity-configuration?
+ px-device-identity-service-type
+
+ <px-device-identity-configuration>
+ px-user-identity-configuration
+ px-user-identity-configuration?
+ px-user-identity-service-type
+
+ px-enterprise-channels-service
+
+ px-device-runner-configuration
+ px-device-runner-service-type
+
+ px-file-upload-configuration
+ px-file-upload-service-type
+
+ btuart-configuration
+ btuart-service-type
+
+ bluetooth-client-manager-configuration
+ bluetooth-client-manager-service-type))
+
+
+;;
+;; Device Identity API SERVICE
+;;
+
+(define-record-type* <px-device-identity-configuration>
+ px-device-identity-configuration make-px-device-identity-configuration
+ px-device-identity-configuration?
+ (package px-device-identity-configuration-package
+ (default px-device-identity-service)))
+
+
+(define px-device-identity-shepherd-service
+ (match-lambda
+ (($ <px-device-identity-configuration> package)
+ (list (shepherd-service
+ (provision '(px-device-identity))
+ (documentation "Run px-device-identity-service as a daemon")
+ (requirement '(networking user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$screen "/bin/screen")
+ "-D" "-m" "-S" "identity-api"
+ (string-append #$package "/bin/px-device-identity-service"))))
+ (stop #~(make-kill-destructor)))))))
+
+
+(define px-device-identity-service-type
+ (service-type
+ (name 'px-device-identity)
+ (description "PantherX device identity service")
+ (extensions (list (service-extension shepherd-root-service-type
+ px-device-identity-shepherd-service)))
+ (default-value (px-device-identity-configuration))))
+
+
+;;
+;; User Identity Service
+;;
+
+(define-record-type* <px-user-identity-configuration>
+ px-user-identity-configuration make-px-user-identity-configuration
+ px-user-identity-configuration?
+ (package px-user-identity-configuration-package
+ (default px-user-identity-service)))
+
+(define (px-user-identity-shepherd-service config)
+ (match config
+ (($ <px-user-identity-configuration> package)
+ (list (shepherd-service
+ (provision '(px-user-identity))
+ (documentation "Run px-user-identity-service as a shepherd daemon")
+ (requirement `(networking user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$screen "/bin/screen")
+ "-D" "-m" "-S" "user-identity"
+ (string-append #$package "/bin/px-user-identity-service"))
+ #:environment-variables
+ (cons* "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))))
+ (stop #~(make-kill-destructor)))))))
+
+(define px-user-identity-service-type
+ (service-type
+ (name 'px-user-identity)
+ (description "PantherX user identity service")
+ (extensions (list (service-extension shepherd-root-service-type
+ px-user-identity-shepherd-service)))
+ (default-value (px-user-identity-configuration))))
+
+;;
+;; Pantherx Enterprise Channels Service
+;;
+
+(define (px-enterprise-channels-service channels)
+ (let ((channel-conf
+ (call-with-output-string
+ (lambda (port) (pretty-print channels port)))))
+ (simple-service
+ 'enterprise-channels
+ special-files-service-type
+ `(("/etc/guix/channels.scm"
+ ,(computed-file
+ "channels.scm"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((base-dir (dirname #$output)))
+ (mkdir-p base-dir)
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port #$channel-conf))))))))))))
+
+
+;;
+;; Device Runner Service
+;;
+
+(define-record-type* <px-device-runner-configuration>
+ px-device-runner-configuration make-px-device-runner-configuration
+ px-device-runner-configuration?
+ (schedule px-device-runner-configuration-schedule
+ (default "*/5 * * * *")))
+
+(define (px-device-runner-job config)
+ #~(job #$(px-device-runner-configuration-schedule config)
+ (string-append #$px-device-runner
+ "/bin/px-device-runner")))
+
+(define (px-device-runner-mcron-jobs config)
+ (list (px-device-runner-job config)))
+
+(define px-device-runner-service-type
+ (service-type
+ (name "px-device-runner")
+ (extensions
+ (list (service-extension mcron-service-type
+ px-device-runner-mcron-jobs)))
+ (description "Service definition to run device runnner as a cronjob")
+ (default-value (px-device-runner-configuration))))
+
+
+;;
+;; File Upload Service
+;;
+
+(define-record-type* <px-file-upload-configuration>
+ px-file-upload-configuration make-px-file-upload-configuration
+ px-file-upload-configuration?
+ (package px-file-upload-configuration-package
+ (default px-file-upload-cli))
+ (schedule px-file-upload-configuration-schedule
+ (default "0 * * * *"))
+ (types px-file-upload-configuration-types
+ (default '()))
+ (source px-file-upload-configuration-source)
+ (endpoint px-file-upload-configuration-endpoint)
+ (keys px-file-upload-configuration-keys
+ (default '()))
+ (parse? px-file-upload-configuration-parse?
+ (default #f))
+ (delete-on-success? px-file-upload-configuration-delete-on-success?
+ (default #f)))
+
+
+(define (px-file-upload-configuration->config config)
+ "Return configuration file for px-file-upload-cli"
+ (match config
+ (($ <px-file-upload-configuration>
+ package schedule types source endpoint keys parse? delete-on-success?)
+ (computed-file "file-upload.conf"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port
+ "types = ~a
+source = ~a
+endpoint = ~a
+keys = ~a
+parse_file_name = ~a
+delete_on_success = ~a"
+ #$(string-join types ",")
+ #$source
+ #$endpoint
+ #$(string-join keys "")
+ #$(if parse? "true" "false")
+ #$(if delete-on-success? "true" "false"))))))))))
+
+
+(define (px-file-upload-mcron-jobs config)
+ (let ((configpath (px-file-upload-configuration->config config))
+ (schedule (px-file-upload-configuration-schedule config))
+ (package (px-file-upload-configuration-package config)))
+ (list
+ #~(job #$schedule
+ (string-append
+ #$package "/bin/px-file-upload-cli"
+ " --config " #$configpath)))))
+
+
+(define px-file-upload-service-type
+ (service-type
+ (name 'px-file-upload)
+ (extensions
+ (list (service-extension mcron-service-type
+ px-file-upload-mcron-jobs)
+ (service-extension profile-service-type
+ (lambda (config)
+ (list (px-file-upload-configuration-package config)
+ px-device-identity
+ tpm2-tss-engine)))))
+ (description "Service definition to run file upload on intervals")))
+
+;;
+;; btuart-service-type
+;;
+
+(define-record-type* <btuart-configuration>
+ btuart-configuration make-btuart-configuration
+ btuart-configuration?
+ (package btuart-configuration-package
+ (default bluez))
+ (device btuart-configuration-device
+ (default "/dev/ttyAMA0"))
+ (protocol btuart-configuration-protocol
+ (default "bcm"))
+ (baudrate btuart-configuration-baudrate
+ (default "3000000"))
+ (flow-control? btuart-configuration-flow-control?
+ (default #t)))
+
+
+(define btuart-shepherd-service
+ (match-lambda
+ (($ <btuart-configuration> package device protocol baudrate flow-control?)
+ (list
+ (shepherd-service
+ (documentation "attach serial lines as Bluetooth HCI interfaces")
+ (provision '(btuart))
+ (requirement '(udev))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append package "/bin/btattach")
+ "-B" #$device "-P" #$protocol
+ "-S" #$baudrate
+ (when #$flow-control? "-N"))))
+ (one-shot? #t))))))
+
+
+(define btuart-service-type
+ (service-type
+ (name 'btuart)
+ (extensions (list (service-extension shepherd-root-service-type
+ btuart-shepherd-service)))
+ (default-value (btuart-configuration))
+ (description "Attach serial lines as Bluetooth HCI interfaces")))
+
+;;
+;; bluetooth-client-manager-service
+;;
+
+(define-record-type* <bluetooth-client-manager-configuration>
+ bluetooth-client-manager-configuration make-bluetooth-client-manager-configuration
+ bluetooth-client-manager-configuration?
+ (package bluetooth-client-manager-configuration-package
+ (default bluetooth-client-manager-service))
+ (debug? bluetooth-client-manager-configuration-debug?
+ (default #f))
+ (skip-approval? bluetooth-client-manager-configuration-skip-approval?
+ (default #f)))
+
+
+(define bluetooth-client-manager-shepherd-service
+ (match-lambda
+ (($ <bluetooth-client-manager-configuration> package debug? skip-approval?)
+ (list (shepherd-service
+ (provision '(bluetooth-client-manager-service))
+ (documentation "Run px-device-identity-service as a daemon")
+ (requirement '(networking user-processes px-device-identity))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/bin/bluetooth-client-manager-service")
+ #$@(if debug? '("--verbose") '())
+ #$@(if skip-approval? '("--skip-approval") '()))
+ #:log-file "/var/log/bluetooth-client-manager-service.log"
+ #:environment-variables
+ (cons* "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))))
+ (stop #~(make-kill-destructor)))))))
+
+
+(define bluetooth-client-manager-service-type
+ (service-type
+ (name 'bluetooth-client-manager-service)
+ (description "PantherX Bluetooth Client Manager service")
+ (extensions (list (service-extension shepherd-root-service-type
+ bluetooth-client-manager-shepherd-service)))
+ (default-value (bluetooth-client-manager-configuration))))
diff --git a/px/services/disk.scm b/px/services/disk.scm
new file mode 100644
index 0000000..ca10546
--- /dev/null
+++ b/px/services/disk.scm
@@ -0,0 +1,99 @@
+;;; Desktop service definitions for PantherX
+;;;
+;;; Reza Alizadeh Majd <r.majd@pantherx.org>
+;;; Franz Geffke <franz@pantherx.org>
+;;;
+
+(define-module (px services disk)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages xdisorg)
+ #:use-module (gnu services)
+ #:use-module (gnu services base)
+ #:use-module (gnu services cups)
+ #:use-module (gnu services dbus)
+ #:use-module (gnu services desktop)
+ #:use-module (gnu services networking)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system)
+ #:use-module (gnu system setuid)
+ #:use-module (guix build utils)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix records)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 match)
+ #:export (create-swap-space-service
+
+ disk-init-configuration
+ disk-init-service-type))
+
+;;
+;; Create swap-file service
+;; primarily for ARM
+;;
+
+(define (create-swap-space-service size)
+ (simple-service 'create-swap-space
+ activation-service-type
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((swapfile "/swapfile"))
+ (when (not (file-exists? swapfile))
+ (invoke #+(file-append util-linux "/bin/fallocate") "-l" #$size swapfile)
+ (chmod swapfile #o600)
+ (invoke #+(file-append util-linux "/sbin/mkswap") swapfile)
+ ))))))
+
+;;
+;; Disk initiation service
+;; primarily for ARM
+;;
+
+(define-record-type* <disk-init-configuration>
+ disk-init-configuration make-disk-init-configuration
+ disk-init-configuration?
+ (device disk-init-configuration-device)
+ (index disk-init-configuration-index)
+ (target disk-init-configuration-target)
+ (swap-size disk-init-configuration-swap-size
+ (default #f))
+ (swap-path disk-init-configuration-swap-path
+ (default "/swapfile")))
+
+(define disk-init-activation
+ (match-lambda
+ (($ <disk-init-configuration> device index target swap-size swap-path)
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((lock-file "/etc/disk-init.lock"))
+ (when (not (file-exists? lock-file))
+ ;; resize root partition
+ ;; workaround to fix growpart execution
+ (setenv "PATH" (string-append "/run/current-system/profile/bin:" (getenv "PATH")))
+ (invoke #+(file-append cloud-utils "/bin/growpart") #$device #$index)
+ (invoke #+(file-append e2fsprogs "/sbin/resize2fs") #$target)
+ (invoke #+(file-append coreutils "/bin/sync"))
+
+ ;; create swap-file
+ (when (and #$swap-size
+ (not (file-exists? #$swap-path)))
+ (invoke #+(file-append util-linux "/bin/fallocate")
+ "-l" #$swap-size #$swap-path)
+ (chmod #$swap-path #o600)
+ (invoke #+(file-append util-linux "/sbin/mkswap") #$swap-path))
+
+ (call-with-output-file lock-file
+ (lambda (port)
+ (display "disk image initiated\n" port))))))))))
+
+(define disk-init-service-type
+ (service-type
+ (name 'disk-init)
+ (extensions (list
+ (service-extension activation-service-type
+ disk-init-activation)))
+ (description "Resize root partition on first boot and create swapfile")))
diff --git a/px/services/enterprise.scm b/px/services/enterprise.scm
new file mode 100644
index 0000000..998092b
--- /dev/null
+++ b/px/services/enterprise.scm
@@ -0,0 +1,126 @@
+(define-module (px services enterprise)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu packages databases)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:export (px-channel-migration-configuration
+ px-channel-migration-service-type))
+
+;;;
+;;; Channel Migration Service
+;;;
+
+(define-record-type* <px-channel-migration-configuration>
+ px-channel-migration-configuration make-px-channel-migration-configuration
+ px-channel-migration-configuration?
+ (profile px-channel-migration-configuration-profile ;; path to profile we want to migrate (root)
+ (default "/root/.config/guix/current"))
+ (config px-channel-migration-configuration-config ;; path to system configuration file
+ (default "/etc/system.scm"))
+ (channels px-channel-migration-configuration-channels ;; path to channels file
+ (default "/etc/guix/channels.scm"))
+ (branch px-channel-migration-configuration-branch) ;; target branch that we want to migrate to
+ (timeout px-channel-migration-configuration-timeout ;; timeout before start the migration
+ (default 60)))
+
+
+(define (px-channel-migration->script config)
+ (match config
+ (($ <px-channel-migration-configuration> profile config channels branch timeout)
+ (computed-file
+ "px-channel-migration.sh"
+ #~(begin
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port "# AUTO GENERATED BY: px-channel-migration-service
+GUIX_PROFILE=~a
+SYSTEM_CONFIG=~a
+SYSTEM_CHANNELS=~a
+TARGET_BRANCH=~a
+START_TIMEOUT=~a
+RETRY_TIMEOUT=15
+echo \"--------------------------------------------\"
+echo \">>> service started\"
+echo \">>> Sleep for $START_TIMEOUT\"
+sleep $START_TIMEOUT
+
+UPGRADE_FILE=/etc/last_unattended_upgrade.txt
+
+if [ -f $UPGRADE_FILE ]; then
+ BOOT_TIME=$(cat /proc/stat | grep btime | awk '{print $2}')
+ LAST_UPGRADE=$(cat $UPGRADE_FILE)
+ if [ $BOOT_TIME -lt $LAST_UPGRADE ]; then
+ echo 'Migration ran once since last reboot. Exiting...'
+ exit 0
+ fi
+fi
+
+echo \">>> Profile Path: $GUIX_PROFILE\"
+. \"$GUIX_PROFILE/etc/profile\"
+
+echo \">>> System status:\"
+guix describe
+current_branch=$(guix describe --format=recutils | ~a -e \"name='guix'\" -P 'branch')
+# if [ \"$current_branch\" == \"$TARGET_BRANCH\" ]; then
+# echo \"Machine already migrated\"
+# exit 0
+# fi
+
+echo \">>> Pull latest changes\"
+guix pull --allow-downgrades --disable-authentication
+if [ $? -ne 0 ]; then
+ echo 'ERROR: Pull Failed'
+ exit 1
+fi
+
+echo \">>> Start system reconfigure\"
+function perform_reconfigure {
+ guix time-machine --disable-authentication --channels=$SYSTEM_CHANNELS \
+ -- system reconfigure --allow-downgrades $SYSTEM_CONFIG
+}
+perform_reconfigure
+while [ $? -ne 0 ]; do
+ echo \"ERROR: reconfigure failed. retry in $RETRY_TIMEOUT seconds.\"
+ sleep $RETRY_TIMEOUT
+ perform_reconfigure
+done
+
+guix describe
+echo $(date +'%s') > $UPGRADE_FILE
+echo \">>> Device channels migrated successfully.\"
+" #$profile #$config #$channels #$branch #$timeout #$(file-append recutils "/bin/recsel")))))))))
+
+
+(define (px-channel-migration-shepherd-service config)
+ (match config
+ (($ <px-channel-migration-configuration> ...)
+ (let ((script (px-channel-migration->script config)))
+ (list (shepherd-service
+ (provision '(px-channel-migration))
+ (documentation "Migrate device channels to new references")
+ (requirement '(networking user-processes))
+ (one-shot? #t)
+ (start #~(make-forkexec-constructor
+ (list (string-append #$bash "/bin/bash")
+ #$script)
+ #:environment-variables
+ (cons*
+ "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))
+ #:log-file "/var/log/px-channel-migration.log"))
+ (stop #~(make-kill-destructor))))))))
+
+
+(define px-channel-migration-service-type
+ (service-type
+ (name 'px-channel-migration)
+ (description "Migrate device channels to new references")
+ (extensions (list (service-extension shepherd-root-service-type
+ px-channel-migration-shepherd-service)))))
diff --git a/px/services/log.scm b/px/services/log.scm
new file mode 100644
index 0000000..f8f2bc2
--- /dev/null
+++ b/px/services/log.scm
@@ -0,0 +1,152 @@
+(define-module (px services log)
+ #:use-module (gnu)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages logging)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu services shepherd)
+ #:use-module (px packages log)
+ #:use-module (gnu system)
+ #:use-module (gnu system shadow)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+
+ #:export (remote-syslog-service-configuration
+ remote-syslog-service-type
+
+ %rsyslog-default-config
+ %rsyslog-default-config-file
+ rsyslog-configuration
+ rsyslog-service-type))
+
+;;
+;; remote-syslog SERVICE
+;;
+
+(define (script-builder destionation-host destionation-port hostname log-files package)
+ "Return the chorny configuration file corresponding to CONFIG."
+ (computed-file "remote-syslog-script.sh"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port "#!~a~% exec ~a \"$@\"~%"
+ #+(file-append bash "/bin/sh")
+ (string-append #$package "/bin/remote_syslog2"
+ " --no-detach"
+ " -d " #$destionation-host
+ " -p " #$destionation-port
+ " --pid-file=/var/run/remote_syslog.pid"
+ " --hostname " #$hostname
+ " " #$log-files))
+ (chmod port #o555)))))))
+
+(define-record-type* <remote-syslog-service-configuration>
+ remote-syslog-service-configuration make-remote-syslog-service-configuration
+ remote-syslog-service-configuration?
+ (destionation-host remote-syslog-service-configuration-destionation-host
+ (default "logs.papertrailapp.com"))
+ (destionation-port remote-syslog-service-configuration-destionation-port
+ (default "46169"))
+ (hostname remote-syslog-service-configuration-host
+ (default "$(hostname)"))
+ (log-files remote-syslog-service-configuration-log-files
+ (default "/var/log/messages"))
+ (package remote-syslog-service-configuration-package
+ (default remote_syslog2)))
+
+(define remote-syslog-shepherd-service
+ (match-lambda
+ (($ <remote-syslog-service-configuration> destionation-host destionation-port hostname log-files package)
+ (list (shepherd-service
+ (provision '(remote-syslog))
+ (documentation "Run remote-syslog as a daemon")
+ (requirement '(networking syslogd))
+ (start #~(make-forkexec-constructor
+ (list #$(script-builder destionation-host destionation-port hostname log-files package))))
+ (stop #~(make-kill-destructor)))))))
+
+(define remote-syslog-service-type
+ (service-type
+ (name "remote-syslog")
+ (description "Remote syslog service")
+ (extensions (list (service-extension shepherd-root-service-type
+ remote-syslog-shepherd-service)))
+ (default-value (remote-syslog-service-configuration))))
+
+
+;;
+;; rsyslog-service-type
+;;
+
+(define %rsyslog-default-config
+ "## full conf created by rsyslog version 8.2204.1 at 2023-01-02 16:44:08 ##
+
+$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
+$ModLoad imklog # provides kernel logging support (previously done by rklogd)
+$ModLoad immark # provides --MARK-- message capability
+
+$ModLoad imudp
+$UDPServerRun 514
+
+$ModLoad imtcp
+$InputTCPServerRun 514
+
+$WorkDirectory /var/lib/rsyslog
+$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
+
+*.* /var/log/rsyslog
+")
+
+
+(define %rsyslog-default-config-file
+ (plain-file "rsyslog.conf" %rsyslog-default-config))
+
+
+(define-record-type* <rsyslog-configuration>
+ rsyslog-configuration make-rsyslog-cofiguration
+ rsyslog-configuration?
+ (package rsyslog-configuration-package
+ (default rsyslog))
+ (config-file rsyslog-configuration-config-file
+ (default %rsyslog-default-config-file)))
+
+
+(define (rsyslog-activation config)
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules ((guix build utils)))
+ (let ((lib-dir "/var/lib/rsyslog"))
+ (mkdir-p lib-dir)))))
+
+
+(define rsyslog-shepherd-service
+ (match-lambda
+ (($ <rsyslog-configuration> package config-file)
+ (list
+ (shepherd-service
+ (provision '(rsyslogd))
+ (documentation "Rsyslog daemon service")
+ (requirement '(syslogd))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append package "/sbin/rsyslogd")
+ "-n" "-f" #$config-file)))
+ (stop #~(make-kill-destructor)))))))
+
+
+(define rsyslog-service-type
+ (service-type
+ (name 'rsyslog)
+ (description "Run rsyslog daemon on machine")
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ rsyslog-shepherd-service)
+ (service-extension activation-service-type
+ rsyslog-activation)))
+ (default-value (rsyslog-configuration))))
diff --git a/px/services/monitoring.scm b/px/services/monitoring.scm
new file mode 100644
index 0000000..a5c64e5
--- /dev/null
+++ b/px/services/monitoring.scm
@@ -0,0 +1,116 @@
+(define-module (px services monitoring)
+ #:use-module (gnu)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages curl)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages gnome)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (px packages device)
+ #:use-module (ice-9 match)
+ #:use-module (px packages monitoring)
+ #:export (<px-remote-status-service-configuration>
+ px-remote-status-service-configuration
+ px-remote-status-service-configuration?
+ px-remote-status-service-type))
+
+;;
+;; px-remote-status-service-type
+;;
+
+(define-record-type* <px-remote-status-service-configuration>
+ px-remote-status-service-configuration make-px-remote-status-configuration
+ px-remote-status-service-configuration?
+ (package px-remote-status-service-configuration-package
+ (default px-org-remote-status-service))
+ (interval px-remote-status-service-configuration-interval
+ (default 300))
+ (jobs px-remote-status-service-configuration-jobs
+ (default '())))
+
+(define (px-remote-service-configuration->monitrc config)
+ "Return monitrc file for config"
+ (match config
+ (($ <px-remote-status-service-configuration> jobs)
+ (computed-file
+ "monitrc"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils)
+ (ice-9 match))
+ (call-with-output-file #$output
+ (lambda (port)
+ (display "\
+### Monit default configurations
+## Check interval
+set daemon 30 # check services at 30 seconds intervals
+# with start delay 240 # optional: delay the first check by 4-minutes (by
+# # default Monit check immediately after Monit start)
+
+## Set syslog logging
+set log syslog
+
+## Monit embedded HTTP interface
+set httpd port 2812 and
+ use address localhost # only accept connection from localhost (drop if you use M/Monit)
+ allow localhost # allow localhost to connect to the server and
+ allow admin:monit # require user 'admin' with password 'monit'
+
+### Monit job definitions\n" port)
+ (for-each (lambda (job)
+ (display (string-append job "\n") port))
+ '#$(px-remote-status-service-configuration-jobs config))
+ ))))))))
+
+(define (px-remote-status-shepherd-service config)
+ "Return <shepherd-service> running px-org-remote-status-service"
+ (match config
+ (($ <px-remote-status-service-configuration> package interval)
+ (let ((monitrc (px-remote-service-configuration->monitrc config)))
+ (list (shepherd-service
+ (provision '(px-remote-status))
+ (documentation "Run px-org-remote-status-service as a shepherd daemon")
+ (requirement '(networking user-processes px-device-identity))
+ (modules `((srfi srfi-1)
+ (srfi srfi-26)
+ ,@%default-modules))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$screen "/bin/screen")
+ "-D" "-m" "-S" "remote-status"
+ (string-append #$package "/bin/px-org-remote-status-service")
+ "-i" (number->string #$interval)
+ "-m" #$monitrc)
+ #:environment-variables
+ (cons* (string-append "PATH="
+ #$monit "/bin:"
+ #$network-manager "/bin:"
+ #$lshw "/sbin:"
+ #$coreutils "/bin:"
+ #$sysstat "/bin:"
+ #$curl "/bin:"
+ #$util-linux+udev "/bin:"
+ #$px-device-identity "/bin:"
+ "/run/current-system/profile/bin:"
+ (getenv "PATH"))
+ "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (remove (cut string-prefix? "PATH=" <>)
+ (environ)))))
+ (stop #~(make-kill-destructor))))))))
+
+
+
+(define px-remote-status-service-type
+ (service-type
+ (name 'px-remote-status)
+ (description "PantherX remote status service")
+ (extensions (list (service-extension shepherd-root-service-type
+ px-remote-status-shepherd-service)))
+ (default-value (px-remote-status-service-configuration))))
+
diff --git a/px/services/networking.scm b/px/services/networking.scm
new file mode 100644
index 0000000..eac9b81
--- /dev/null
+++ b/px/services/networking.scm
@@ -0,0 +1,157 @@
+(define-module (px services networking)
+ #:use-module (gnu)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages ntp)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu services admin)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system)
+ #:use-module (gnu system shadow)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+ #:use-module (px packages networking)
+ #:use-module (srfi srfi-1)
+
+ #:export (chrony-service-configuration
+ chrony-service-type
+
+ nebula-configuration
+ nebula-configuration-package
+ nebula-configuration-provision
+ nebula-configuration-config-path
+ %default-nebula-configuration
+ nebula-service-type))
+
+;;
+;; Chrony SERVICE
+;;
+
+(define-record-type* <chrony-service-configuration>
+ chrony-service-configuration make-chrony-service-configuration
+ chrony-service-configuration?
+ (package chrony-service-configuration-package
+ (default chrony))
+ (user chrony-service-configuration-user
+ (default "root"))
+ (config chrony-service-configuration-config
+ (default "server 0.pool.ntp.org iburst
+server 1.pool.ntp.org iburst
+server 2.pool.ntp.org iburst
+server 3.pool.ntp.org iburst
+driftfile /var/lib/chrony/drift
+makestep 1.0 3
+rtcsync
+logdir /var/log/chrony")))
+
+(define (chrony-service-config-file config)
+ "Return the chorny configuration file corresponding to CONFIG."
+ (computed-file "chrony.conf"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port
+ #$config)))))))
+
+(define chrony-shepherd-service
+ (match-lambda
+ (($ <chrony-service-configuration> package user config)
+ (list (shepherd-service
+ (provision '(chrony))
+ (documentation "Run chrony as a daemon")
+ (requirement '(networking))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/sbin/chronyd")
+ "-n" "-u" #$user
+ "-f" #$(chrony-service-config-file config))))
+ (stop #~(make-kill-destructor)))))))
+
+(define chrony-service-type
+ (service-type
+ (name "chrony")
+ (description "Chrony service")
+ (extensions (list (service-extension shepherd-root-service-type
+ chrony-shepherd-service)))
+ (default-value (chrony-service-configuration))))
+
+
+;;
+;; Nebula SERVICE
+;;
+
+(define-record-type* <nebula-configuration>
+ nebula-configuration
+ make-nebula-configuration
+ nebula-configuration?
+ (package nebula-configuration-package
+ (default nebula))
+ (provision nebula-configuration-provision)
+ (config-path nebula-configuration-config-path))
+
+
+(define nebula-profile-packages
+ (lambda (configurations)
+ (fold (lambda (config prv)
+ (let ((pkg (nebula-configuration-package config)))
+ (if (memq pkg prv)
+ prv
+ (cons pkg prv))))
+ '() configurations)))
+
+
+(define (nebula-shepherd-service config)
+ (match config
+ (($ <nebula-configuration> package provision config-path)
+ (let ((log-path (string-append
+ "/var/log/"
+ (symbol->string (car provision))
+ ".log")))
+ (shepherd-service
+ (provision provision)
+ (documentation "Run configured instance of nebula on system start")
+ (requirement '(networking user-processes))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/bin/nebula")
+ "-config" #$config-path)
+ #:log-file #$log-path
+ #:environment-variables
+ (cons* "HOME=/root"
+ "XDG_DATA_HOME=/root/.local/share"
+ "XDG_CONFIG_HOME=/root/.config"
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))))
+ (stop #~(make-kill-destructor)))))))
+
+
+(define (nebula-shepherd-services configurations)
+ (map nebula-shepherd-service configurations))
+
+
+(define %default-nebula-configuration
+ (nebula-configuration
+ (provision '(nebula))
+ (config-path "/etc/nebula/config.yml")))
+
+(define %nebula-log-rotations
+ (list (log-rotation
+ (files (list "/var/log/nebula.log")))))
+
+(define nebula-service-type
+ (service-type
+ (name 'nebula)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ nebula-shepherd-services)
+ (service-extension profile-service-type
+ nebula-profile-packages)
+ (service-extension rottlog-service-type
+ (const %nebula-log-rotations))))
+ (default-value (list %default-nebula-configuration))
+ (description "Run configured instance of nebula on system start")))
diff --git a/px/services/ntp.scm b/px/services/ntp.scm
new file mode 100644
index 0000000..bbba3c6
--- /dev/null
+++ b/px/services/ntp.scm
@@ -0,0 +1,73 @@
+(define-module (px services ntp)
+ #:use-module (gnu)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages ntp)
+ #:use-module (gnu packages screen)
+ #:use-module (gnu services admin)
+ #:use-module (gnu services shepherd)
+ #:use-module (gnu system)
+ #:use-module (gnu system shadow)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 pretty-print)
+ #:use-module (srfi srfi-1)
+
+ #:export (chrony-service-configuration
+ chrony-service-type))
+
+;;
+;; Chrony SERVICE
+;;
+
+(define-record-type* <chrony-service-configuration>
+ chrony-service-configuration make-chrony-service-configuration
+ chrony-service-configuration?
+ (package chrony-service-configuration-package
+ (default chrony))
+ (user chrony-service-configuration-user
+ (default "root"))
+ (config chrony-service-configuration-config
+ (default "server 0.pool.ntp.org iburst
+server 1.pool.ntp.org iburst
+server 2.pool.ntp.org iburst
+server 3.pool.ntp.org iburst
+driftfile /var/lib/chrony/drift
+makestep 1.0 3
+rtcsync
+logdir /var/log/chrony")))
+
+(define (chrony-service-config-file config)
+ "Return the chorny configuration file corresponding to CONFIG."
+ (computed-file "chrony.conf"
+ (with-imported-modules
+ '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port
+ #$config)))))))
+
+(define chrony-shepherd-service
+ (match-lambda
+ (($ <chrony-service-configuration> package user config)
+ (list (shepherd-service
+ (provision '(chrony))
+ (documentation "Run chrony as a daemon")
+ (requirement '(networking))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/sbin/chronyd")
+ "-n" "-u" #$user
+ "-f" #$(chrony-service-config-file config))))
+ (stop #~(make-kill-destructor)))))))
+
+(define chrony-service-type
+ (service-type
+ (name "chrony")
+ (description "Chrony service")
+ (extensions (list (service-extension shepherd-root-service-type
+ chrony-shepherd-service)))
+ (default-value (chrony-service-configuration)))) \ No newline at end of file
diff --git a/px/services/package-management.scm b/px/services/package-management.scm
new file mode 100644
index 0000000..d393d2d
--- /dev/null
+++ b/px/services/package-management.scm
@@ -0,0 +1,64 @@
+(define-module (px services package-management)
+ #:use-module (gnu)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:use-module (px packages package-management)
+ #:export (px-unattended-upgrades-configuration
+ px-unattended-upgrades-configuration?
+ px-unattended-upgrades-service-type))
+
+;;
+;; px-unattended-upgrades-service-type
+;;
+
+(define-record-type* <px-unattended-upgrades-configuration>
+ px-unattended-upgrades-configuration make-px-unattended-upgrades-configuration
+ px-unattended-upgrades-configuration?
+ (package px-unattended-upgrades-configuration-package
+ (default px-unattended-upgrades))
+ (timeout px-unattended-upgrades-timeout
+ (default 300)))
+
+
+(define (px-unattended-upgrades-configuration->script config)
+ (match config
+ (($ <px-unattended-upgrades-configuration> package timeout)
+ (computed-file
+ "px-unattended-upgrades.sh"
+ #~(begin
+ (call-with-output-file #$output
+ (lambda (port)
+ (display "# AUTO GENERATED BY: px-unattended-upgrades-shepherd-service\n\n" port)
+ (display "echo \"$(date) > service started: \"\n" port)
+ (format port "echo \"$(date) > sleep for: ~a\"\n" #$timeout)
+ (format port "sleep ~a\n" #$timeout)
+ (display "echo \"$(date) > start upgrade\"\n" port)
+ (format port "~a/bin/px-unattended-upgrades\n" #$package))))))))
+
+
+(define (px-unattended-upgrades-shepherd-service config)
+ (match config
+ (($ <px-unattended-upgrades-configuration> package timeout)
+ (let ((script (px-unattended-upgrades-configuration->script config)))
+ (list (shepherd-service
+ (provision '(px-unattended-upgrades))
+ (documentation "Run px-unattended-upgrades once after reboot")
+ (requirement '(networking user-processes))
+ (one-shot? #t)
+ (start #~(make-forkexec-constructor
+ (list (string-append #$bash "/bin/bash")
+ #$script)
+ #:log-file "/var/log/px-unattended-upgrades.log"))
+ (stop #~(make-kill-destructor))))))))
+
+
+(define px-unattended-upgrades-service-type
+ (service-type
+ (name 'px-unattended-upgrades)
+ (description "PantherX unattended upgrades service")
+ (extensions (list (service-extension shepherd-root-service-type
+ px-unattended-upgrades-shepherd-service)))
+ (default-value (px-unattended-upgrades-configuration))))
diff --git a/px/services/security-token.scm b/px/services/security-token.scm
new file mode 100644
index 0000000..87c5d32
--- /dev/null
+++ b/px/services/security-token.scm
@@ -0,0 +1,123 @@
+;;; module for security tokens and hardware wallet related services
+;;; Author: Reza Alizadeh Majd (r.majd@pantherx.org)
+
+(define-module (px services security-token)
+ #:use-module (gnu services base)
+ #:export (ledger-wallet-service
+ nitro-key-service))
+
+
+;;;
+;;; Ledger hardware wallet definitions
+;;; udev-rules from: https://github.com/LedgerHQ/udev-rules/blob/master/20-hw1.rules
+;;;
+
+(define (ledger-udev-rule-record title vendor-id product-id tags)
+ (string-append "# " title "\n"
+ "SUBSYSTEMS==\"usb\", "
+ "ATTRS{idVendor}==\"" vendor-id "\", "
+ "ATTRS{idProduct}==\"" product-id "\", "
+ (string-join (map (lambda (tag)
+ (string-append "TAG+=\"" tag "\""))
+ tags) ", ")
+ "\n"))
+
+
+(define %ledger-udev-rule
+ (udev-rule "20-ledger.rules"
+ (string-append
+ (ledger-udev-rule-record "HW.1 / Nano"
+ "2581"
+ "1b7c|2b7c|3b7c|4b7c"
+ '("uaccess" "udev-acl"))
+ (ledger-udev-rule-record "Blue"
+ "2c97"
+ "0000|0000|0001|0002|0003|0004|0005|0006|0007|0008|0009|000a|000b|000c|000d|000e|000f|0010|0011|0012|0013|0014|0015|0016|0017|0018|0019|001a|001b|001c|001d|001e|001f"
+ '("uaccess" "udev-acl"))
+ (ledger-udev-rule-record "Nano S"
+ "2c97"
+ "0001|1000|1001|1002|1003|1004|1005|1006|1007|1008|1009|100a|100b|100c|100d|100e|100f|1010|1011|1012|1013|1014|1015|1016|1017|1018|1019|101a|101b|101c|101d|101e|101f"
+ '("uaccess" "udev-acl"))
+
+ (ledger-udev-rule-record "Aramis"
+ "2c97"
+ "0002|2000|2001|2002|2003|2004|2005|2006|2007|2008|2009|200a|200b|200c|200d|200e|200f|2010|2011|2012|2013|2014|2015|2016|2017|2018|2019|201a|201b|201c|201d|201e|201f"
+ '("uaccess" "udev-acl"))
+ (ledger-udev-rule-record "HW2"
+ "2c97"
+ "0003|3000|3001|3002|3003|3004|3005|3006|3007|3008|3009|300a|300b|300c|300d|300e|300f|3010|3011|3012|3013|3014|3015|3016|3017|3018|3019|301a|301b|301c|301d|301e|301f"
+ '("uaccess" "udev-acl"))
+ (ledger-udev-rule-record "Nano X"
+ "2c97"
+ "0004|4000|4001|4002|4003|4004|4005|4006|4007|4008|4009|400a|400b|400c|400d|400e|400f|4010|4011|4012|4013|4014|4015|4016|4017|4018|4019|401a|401b|401c|401d|401e|401f"
+ '("uaccess" "udev-acl"))
+ (ledger-udev-rule-record "Ledger Test"
+ "2c97"
+ "0005|5000|5001|5002|5003|5004|5005|5006|5007|5008|5009|500a|500b|500c|500d|500e|500f|5010|5011|5012|5013|5014|5015|5016|5017|5018|5019|501a|501b|501c|501d|501e|501f"
+ '("uaccess" "udev-acl")))))
+
+
+(define (ledger-wallet-service)
+ (udev-rules-service 'ledger %ledger-udev-rule))
+
+
+;;;
+;;; Nitrokey definitions
+;;; udev-rules from: https://raw.githubusercontent.com/Nitrokey/libnitrokey/master/data/41-nitrokey.rules
+;;;
+
+(define %nitro-key-udev-rule
+ (udev-rule "41-nitrokey.rules"
+ "ACTION!=\"add|change\", GOTO=\"u2f_end\"
+# Nitrokey U2F
+KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", ATTRS{idVendor}==\"2581\", ATTRS{idProduct}==\"f1d0\", TAG+=\"uaccess\"
+# Nitrokey FIDO U2F
+KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", ATTRS{idVendor}==\"20a0\", ATTRS{idProduct}==\"4287\", TAG+=\"uaccess\"
+# Nitrokey FIDO2
+KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", ATTRS{idVendor}==\"20a0\", ATTRS{idProduct}==\"42b1\", TAG+=\"uaccess\"
+# Nitrokey 3 NFC
+KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", ATTRS{idVendor}==\"20a0\", ATTRS{idProduct}==\"42b3\", TAG+=\"uaccess\"
+
+LABEL=\"u2f_end\"
+
+
+SUBSYSTEM!=\"usb\", GOTO=\"gnupg_rules_end\"
+ACTION!=\"add\", GOTO=\"gnupg_rules_end\"
+
+# USB SmartCard Readers
+## Crypto Stick 1.2
+ATTR{idVendor}==\"20a0\", ATTR{idProduct}==\"4107\", ENV{ID_SMARTCARD_READER}=\"1\", ENV{ID_SMARTCARD_READER_DRIVER}=\"gnupg\", TAG+=\"uaccess\"
+## Nitrokey Pro
+ATTR{idVendor}==\"20a0\", ATTR{idProduct}==\"4108\", ENV{ID_SMARTCARD_READER}=\"1\", ENV{ID_SMARTCARD_READER_DRIVER}=\"gnupg\", TAG+=\"uaccess\"
+## Nitrokey Pro Bootloader
+ATTRS{idVendor}==\"20a0\", ATTRS{idProduct}==\"42b4\", TAG+=\"uaccess\"
+## Nitrokey Storage
+ATTR{idVendor}==\"20a0\", ATTR{idProduct}==\"4109\", ENV{ID_SMARTCARD_READER}=\"1\", ENV{ID_SMARTCARD_READER_DRIVER}=\"gnupg\", TAG+=\"uaccess\"
+## Nitrokey Start
+ATTR{idVendor}==\"20a0\", ATTR{idProduct}==\"4211\", ENV{ID_SMARTCARD_READER}=\"1\", ENV{ID_SMARTCARD_READER_DRIVER}=\"gnupg\", TAG+=\"uaccess\"
+## Nitrokey HSM
+ATTR{idVendor}==\"20a0\", ATTR{idProduct}==\"4230\", ENV{ID_SMARTCARD_READER}=\"1\", ENV{ID_SMARTCARD_READER_DRIVER}=\"gnupg\", TAG+=\"uaccess\"
+
+LABEL=\"gnupg_rules_end\"
+
+
+# Nitrokey Storage dev Entry
+KERNEL==\"sd?1\", ATTRS{idVendor}==\"20a0\", ATTRS{idProduct}==\"4109\", SYMLINK+=\"nitrospace\""))
+
+(define (nitro-key-service)
+ (udev-rules-service 'nitro %nitro-key-udev-rule))
+
+
+;;;
+;;; YubiKey definitions
+;;; https://wiki.archlinux.org/title/YubiKey#YubiKey_not_acting_as_HID_device
+;;; DO NOTE: This rule is very similar to 1st of Nitrokey
+;;;
+
+(define %yubikey-udev-rule
+ (udev-rule "10-security-key.rules"
+ "
+KERNEL==\"hidraw*\", SUBSYSTEM==\"hidraw\", MODE=\"0664\", GROUP=\"users\", ATTRS{idVendor}==\"2581\", ATTRS{idProduct}==\"f1d0\""))
+
+(define (yubikey-service)
+ (udev-rules-service 'yubikey %yubikey-udev-rule))
diff --git a/px/services/server.scm b/px/services/server.scm
new file mode 100644
index 0000000..acb721b
--- /dev/null
+++ b/px/services/server.scm
@@ -0,0 +1,76 @@
+(define-module (px services server)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu packages node)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module (ice-9 match)
+ #:export (px-server-launcher-configuration
+ px-server-launcher-service-type))
+
+
+;;;
+;;; PantherX Server Launcher Service
+;;;
+
+(define-record-type* <px-server-launcher-configuration>
+ px-server-launcher-configuration make-px-server-launcher-configuration
+ px-server-launcher-configuration?
+ (user px-server-launcher-configuration-user
+ (default "panther"))
+ (group px-server-launcher-configuration-group
+ (default "users"))
+ (executable px-server-launcher-configuration-executable)
+ (args px-server-launcher-configuration-args
+ (default '()))
+ (cwd px-server-launcher-configuration-cwd
+ (default #f)))
+
+
+(define (px-server-launcher->script config)
+ (match config
+ (($ <px-server-launcher-configuration> user group executable args cwd)
+ (plain-file "px-server-launcher"
+ (string-append "#!/bin/sh\n\n"
+ "export PATH=$HOME/.local/bin:$PATH\n" ;; add user installed binaries to PATH
+ (if cwd (string-append "cd " cwd "\n") "")
+ "exec " executable " " (string-join args " ") "\n")))))
+
+
+(define (px-server-launcher-shepherd-service config)
+ (match config
+ (($ <px-server-launcher-configuration> user group executable args cwd)
+ (let* ((home-dir (if (eq? user "root")
+ "/root"
+ (string-append "/home/" user)))
+ (script (px-server-launcher->script config)))
+ (list (shepherd-service
+ (provision '(px-server-launcher))
+ (documentation "PantherX Server Application Launcher Service")
+ (requirement '(networking user-processes))
+ (one-shot? #t)
+ (start #~(make-forkexec-constructor
+ (list (string-append #$bash "/bin/bash")
+ #$script)
+ #:user #$user
+ #:group #$group
+ #:environment-variables
+ (cons* (string-append "HOME=" #$home-dir)
+ (string-append "PATH=/run/current-system/profile/bin")
+ (string-append "XDG_DATA_HOME=" #$home-dir "/.local/share")
+ (string-append "XDG_CONFIG_HOME=" #$home-dir "/.config")
+ "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs"
+ "SSL_CERT_FILE=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt"
+ (default-environment-variables))
+ #:log-file "/var/log/px-server-launcher.log"))
+ (stop #~(make-kill-destructor))))))))
+
+
+(define px-server-launcher-service-type
+ (service-type
+ (name 'px-server-launcher)
+ (description "PantherX Server Application Launcher Service")
+ (extensions (list
+ (service-extension shepherd-root-service-type
+ px-server-launcher-shepherd-service)))))