From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms13.migadu.com with LMTPS id iHSqHLeRwmbnaQEA62LTzQ:P1 (envelope-from ) for ; Mon, 19 Aug 2024 00:28:39 +0000 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1.migadu.com with LMTPS id iHSqHLeRwmbnaQEA62LTzQ (envelope-from ) for ; Mon, 19 Aug 2024 02:28:39 +0200 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=debbugs.gnu.org header.s=debbugs-gnu-org header.b=Lt3GzcHV; dkim=fail ("headers rsa verify failed") header.d=fabionatali.com header.s=gm1 header.b=gaAbK4zp; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1724027319; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=UgVD/v66N6ItZePXY8ZsCRToY0mbU9MSncEpL1BQtC8=; b=dvVOuonFxg7WLI5e5X+lD5+3WjFh621oi2xXNdLRmicrNt7mOZgS9fLzuB35lPZ5hreOf/ KR/1fcauwfGmwyGf30jdCerL2ulBNnZvSMB8nw8YUb6rquPEnsg6XwB6TjXlmbnXmQHjFB RtKe0DOfUyHh2t/o00Nk/q+ADgHOYW6Y7eHJAV2kGKOeksuppPcZaQqVarm/J132EpNBPB hp9pOmVGISogvSTbthPH/T41+0guoJBziv5SIHgiP0aT1wkKUDSZ4ZCUKTiGV9K3UFJ4yy z8md7rkaCPjkDDB0POw1564JMrkxKwyVsP+i8+yseegeeeRnslSdPkfOjdkxiQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1724027319; a=rsa-sha256; cv=none; b=l1IwdVR/wXosWGUi0gt2+TYw7AGjsv1quvzKHK014h9Me5xgT0ajvbt/wSPaJENcnreZkJ TEN3MgMBN5OOKy7Y7udyH4B7cZ6WtPJDdatvTjNx6MJBs4EBhm+bLVFRA+hXMlrRV6Adde mDrjFL+bE0jF9QYu5sPAYbErkf5zg6ZkNMVgVxZIv/45rjGT0qskFO0XFBoPLuS/phEmwd FtTD8Y9WHX+Rjs2fEWi3CSMroZ/UusIoOuLbpZTSau2mWAE2pEyWctVkFYcxGdlQLkSKDw /5IINdXE76B9OCEGEIKf5edVFLRWuCBzemUvsZQEMEFPt7ZWHPTlsre4DCNOMQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=debbugs.gnu.org header.s=debbugs-gnu-org header.b=Lt3GzcHV; dkim=fail ("headers rsa verify failed") header.d=fabionatali.com header.s=gm1 header.b=gaAbK4zp; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 1E4C8380E6 for ; Mon, 19 Aug 2024 02:28:38 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sfqG0-0007w7-Sl; Sun, 18 Aug 2024 20:28:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sfqFy-0007vq-85 for guix-patches@gnu.org; Sun, 18 Aug 2024 20:28:22 -0400 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sfqFx-0005NF-Vp for guix-patches@gnu.org; Sun, 18 Aug 2024 20:28:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:References:In-Reply-To:From:To:Subject; bh=UgVD/v66N6ItZePXY8ZsCRToY0mbU9MSncEpL1BQtC8=; b=Lt3GzcHVrLv31lxO6+Ny38O2ElbYskDfDDUb3F1zgYwqT0oGnOCm9pc2uJsxIjMRp7nQUoC0pQP2wjoegEAUNvPbP9+um4juUUrS3V/TBviiG519ofn8AXSi3Rn+hn0C7AbJMk2dnBHCnzwktkWrhIBa/r4zKMYFiU3eY/yRklRklVywDzHyy3LayBoui1OQUBLfGTm6vRA5smKxdK/piFRI9y51j5xGbb6c6etpjezmYBY8kDFILBFdCUu3SqmlJ3c36/LUvVGUOKMm1pbsYFhaQqiS7Az/6nx6JURa5nqJ0Eix9bwg3JJ88AiG0miIz2PgmFxkJgJTxq5SFkHBSQ==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sfqGc-00087l-GX for guix-patches@gnu.org; Sun, 18 Aug 2024 20:29:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#72398] [PATCH] services: Add readymedia-service-type. Resent-From: Fabio Natali Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 19 Aug 2024 00:29:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 72398 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Arun Isaac , 72398@debbugs.gnu.org Received: via spool by 72398-submit@debbugs.gnu.org id=B72398.172402732031195 (code B ref 72398); Mon, 19 Aug 2024 00:29:02 +0000 Received: (at 72398) by debbugs.gnu.org; 19 Aug 2024 00:28:40 +0000 Received: from localhost ([127.0.0.1]:56989 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfqGF-000873-Gi for submit@debbugs.gnu.org; Sun, 18 Aug 2024 20:28:40 -0400 Received: from relay5-d.mail.gandi.net ([217.70.183.197]:44927) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfqGB-00086n-PY for 72398@debbugs.gnu.org; Sun, 18 Aug 2024 20:28:37 -0400 Received: by mail.gandi.net (Postfix) with ESMTPSA id 01FD61C0002; Mon, 19 Aug 2024 00:27:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fabionatali.com; s=gm1; t=1724027246; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=UgVD/v66N6ItZePXY8ZsCRToY0mbU9MSncEpL1BQtC8=; b=gaAbK4zpC5mP/8Y/r5zjQGSeT5s2x2iSSguh+mFIkFtaRnoYgZ3e3dxqZ55axHBhepYrrP tcU0a0hmJiRalqO40kzgOJFyH/VfoPFaTEV4re8UtlINlwgvDUbHXIKRqk6Mgf6Fam/2oe 1olrpF65EeuW46i5zFyeUnpw1v1H6ArBMNz9B1yc2Y2R8A/NVS7A70RaC8X1l+QK8Ad8dh ZS8TynNF9ZIIlvALbateeEA5HHGP9LD8wFhO2mpgQ4sD22Xhkmvh1Z602eMNrym380s7ye 0MxXB/MqYPaJnryBk4R2mpXA0dj2d0SL8Fu2ifuW71stzASauANiswqIzodRIQ== In-Reply-To: <87jzglwcqh.fsf@systemreboot.net> References: <87jzglwcqh.fsf@systemreboot.net> Date: Mon, 19 Aug 2024 01:27:28 +0100 Message-ID: <87h6bhicgf.fsf@fabionatali.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-GND-Sasl: me@fabionatali.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Fabio Natali X-ACL-Warn: , Fabio Natali via Guix-patches From: Fabio Natali via Guix-patches via Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -4.07 X-Spam-Score: -4.07 X-Migadu-Queue-Id: 1E4C8380E6 X-Migadu-Scanner: mx11.migadu.com X-TUID: t1+4SEsXtKhL --=-=-= Content-Type: text/plain Hey Arun, Thanks for reviewing the patch and for the useful feedback, I really appreciate it! Please find my comments/answers below. Patch v2 is attached. On 2024-08-13, 00:19 +0100, Arun Isaac wrote: > Could you also suggest some quick way for me to test this service > without actually having to reconfigure my system? Good point. There might be more clever ways to go about it, but here's my testing process. - Create a folder, e.g. '/tmp/foo', and populate it with at least one music file, e.g. '/tmp/foo/foo.mp3'. - Save this system definition in a file, e.g. '/tmp/config.scm'. Note the insecure user credentials. (use-modules (gnu)) (use-package-modules video) (use-service-modules desktop upnp) (operating-system (host-name "host") (bootloader (bootloader-configuration (bootloader grub-bootloader) (targets '("/dev/vda")))) (file-systems (cons (file-system (device "/dev/vda1") (mount-point "/") (type "ext4")) %base-file-systems)) (users (cons* (user-account (name "user") (group "users") (supplementary-groups '("wheel")) (password (crypt "password" "foo"))) %base-user-accounts)) (sudoers-file (plain-file "sudoers" (string-append (plain-file-content %sudoers-specification) "%wheel ALL = NOPASSWD: ALL"))) (packages (cons* vlc %base-packages)) (services (cons* (service gnome-desktop-service-type) (service readymedia-service-type (readymedia-configuration (media-dirs (list (readymedia-media-dir (path "/media/music") (type "A")))))) %desktop-services))) - From within the Guix repository checkout, once the ReadyMedia service patch has been applied, build and launch the VM with: $(./pre-inst-env guix system vm \ --share=/tmp/foo=/media/music \ /tmp/config.scm) -m 2048 -smp 2 - Log in as 'user'. Open a terminal and verify that the ReadyMedia service is running with 'sudo herd status'. - Open VLC and follow these instructions https://www.vlchelp.com/access-media-upnp-dlna/ to verify that the ReadyMedia service is running and that the 'foo.mp3' file can be played. - Open a browser and verify that the ReadyMedia web page is also reachable at 'http://127.0.0.1:8200'. This should be it, testing-wise. >> +(define %readymedia-cache-dir "/var/cache/readymedia") >> +(define %readymedia-log-dir "/var/log/readymedia") > > Can we have these two in the record? Fixed in v2. > Nitpick: Just to be consistent with other services, I would indent > this (and the other fields) like so with the default on the next line: > >> (readymedia readymedia-configuration-readymedia >> (default readymedia)) Fixed. >> +(define (readymedia-configuration->config-file config) > Could you use mixed-text-file here instead of plain-file? Or, you > could also try computed-file if that's more succinct. 'mixed-text-file' improves things a bit, see v2. WDYT? >> +(define (readymedia-shepherd-service config) > Re-format by putting the first file-system-mapping on the same line as > the cons*. It's customary to format lisp function calls that way. It > makes it easier to see what the arguments are. Fixed. > Likwise with map. Put the lambda on the same line as the map. Fixed. > Looking forward to a v2 patch! v2 attached. :) Thanks Arun, let me know what you think. Should you spot anything else just let me know. Cheers, F. --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline; filename=0001-services-Add-readymedia-service-type.patch Content-Transfer-Encoding: quoted-printable >From ce75351ca7a1f30487e525b7d543ca010d765303 Mon Sep 17 00:00:00 2001 Message-ID: From: Fabio Natali Date: Mon, 19 Aug 2024 01:20:13 +0100 Subject: [PATCH] services: Add readymedia-service-type. * gnu/services/upnp.scm: New file. * gnu/local.mk: Add this. * doc/guix.texi: Document this. Change-Id: I80b02235ec36b7a1ea85fea98bdc9e08126b09a3 --- doc/guix.texi | 103 ++++++++++++++++++++++++ gnu/local.mk | 1 + gnu/services/upnp.scm | 180 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 gnu/services/upnp.scm diff --git a/doc/guix.texi b/doc/guix.texi index 0e1e253b02..ff07d3c6e2 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -129,6 +129,7 @@ Copyright @copyright{} 2024 Richard Sent@* Copyright @copyright{} 2024 Dariqq@* Copyright @copyright{} 2024 Denis 'GNUtoo' Carikli@* +Copyright @copyright{} 2024 Fabio Natali@* =20 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -41599,6 +41600,108 @@ Miscellaneous Services =20 @end deftp =20 +@c %end of fragment + +@cindex DLNA/UPnP +@subsubheading DLNA/UPnP Services + +The @code{(gnu services upnp)} module offers services related to the +DLNA and UPnP-VA networking protocols. For now, it provides the +@code{readymedia-service-type}. + +@uref{https://sourceforge.net/projects/minidlna/, ReadyMedia} +(formerly known as MiniDLNA) is a DLNA/UPnP-AV media server. The +project's daemon, @code{minidlnad}, can serve media files (audio, +pictures, and video) to DLNA/UPnP-AV clients available in the network. + +@code{readymedia-service-type} is a Guix service that wraps around +ReadyMedia's @code{minidlnad}. For increased security, the service +makes use of @code{least-authority-wrapper} which limits the resources +that the daemon has access to. The daemon runs as the +@code{readymedia} unprivileged user, which is a member of the +@code{readymedia} group. + +Consider the following configuration: + +@lisp +(use-service-modules upnp @dots{}) + +(operating-system + ;; @dots{} + (services + (list + (service readymedia-service-type + (readymedia-configuration + (media-dirs + (list (readymedia-media-dir (path "/media/audio") + (type "A")) + (readymedia-media-dir (path "/media/video") + (type "V")) + (readymedia-media-dir (path "/media/misc")))))) +@end lisp + +This sets up the ReadyMedia daemon to serve files from the media +folders specified in @code{media-dirs}. The @code{media-dirs} field +is mandatory. All other fields (such as network ports and the server +name) come with a predefined default and can be omitted. + +@c %start of fragment + +@deftp {Data Type} readymedia-configuration +Available @code{readymedia-configuration} fields are: + +@table @asis +@item @code{readymedia} (default: @code{readymedia}) (type: package) +The ReadyMedia package to be used for the service. + +@item @code{friendly-name} (default: @code{#f}) (type: maybe-string) +A custom name that will be displayed on connected clients. + +@item @code{media-dirs} (type: list) +The list of media folders to serve content from. Each item is a +@code{readymedia-media-dir}. + +@item @code{cache-dir} (default: @code{"/var/cache/readymedia"}) (type: st= ring) +A folder for ReadyMedia's cache files. If not existing already, the +folder will be created as part of the service activation and the +ReadyMedia user will be assigned ownership. + +@item @code{log-dir} (default: @code{"/var/log/readymedia"}) (type: string) +A folder for ReadyMedia's log files. If not existing already, the +folder will be created as part of the service activation and the +ReadyMedia user will be assigned ownership. + +@item @code{port} (default: @code{#f}) (type: maybe-integer) +A custom port that the service will be listening on. + +@item @code{extra-config} (default: @code{'()}) (type: list-of-strings) +A list of further options, to be passed as key-value strings as +accepted by ReadyMedia. + +@end table + +@end deftp + +@c %end of fragment + +@c %start of fragment + +@deftp {Data Type} readymedia-media-dir +A @code{media-dirs} entry includes a @code{path} and, optionally, a +media type string. + +@table @asis +@item @code{path} (type: string) +The media folder location. + +@item @code{type} (default: @code{""}) (type: string) +Valid media types are @code{"A"} for audio, @code{"P"} for pictures, +@code{"V"} for video, and a combination of those individual letters +for mixed types. An empty string means no type specified. + +@end table + +@end deftp =20 @c %end of fragment =20 diff --git a/gnu/local.mk b/gnu/local.mk index 86ff662efa..c850ffbffe 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -752,6 +752,7 @@ GNU_SYSTEM_MODULES =3D \ %D%/services/syncthing.scm \ %D%/services/sysctl.scm \ %D%/services/telephony.scm \ + %D%/services/upnp.scm \ %D%/services/version-control.scm \ %D%/services/vnc.scm \ %D%/services/vpn.scm \ diff --git a/gnu/services/upnp.scm b/gnu/services/upnp.scm new file mode 100644 index 0000000000..076fd4159f --- /dev/null +++ b/gnu/services/upnp.scm @@ -0,0 +1,180 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright =C2=A9 2024 Fabio Natali +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu services upnp) + #:use-module (gnu build linux-container) + #:use-module (gnu packages admin) + #:use-module (gnu packages upnp) + #:use-module (gnu services admin) + #:use-module (gnu services base) + #:use-module (gnu services shepherd) + #:use-module (gnu services) + #:use-module (gnu system file-systems) + #:use-module (gnu system shadow) + #:use-module (guix gexp) + #:use-module (guix least-authority) + #:use-module (guix records) + #:export (readymedia-configuration + readymedia-configuration-readymedia + readymedia-configuration-friendly-name + readymedia-configuration-media-dirs + readymedia-configuration-port + readymedia-configuration-extra-config + readymedia-configuration? + readymedia-media-dir + readymedia-media-dir-path + readymedia-media-dir-type + readymedia-media-dir? + readymedia-service-type)) + +;;; Commentary: +;;; +;;; UPnP services. +;;; +;;; Code: + +(define %readymedia-user-account "readymedia") +(define %readymedia-user-group "readymedia") + +(define-record-type* + readymedia-configuration make-readymedia-configuration + readymedia-configuration? + (readymedia readymedia-configuration-readymedia + (default readymedia)) + (cache-dir readymedia-configuration-cache-dir + (default "/var/cache/readymedia")) + (log-dir readymedia-configuration-log-dir + (default "/var/log/readymedia")) + (friendly-name readymedia-configuration-friendly-name + (default #f)) + (media-dirs readymedia-configuration-media-dirs) + (port readymedia-configuration-port + (default #f)) + (extra-config readymedia-configuration-extra-config + (default '()))) + +;; READYMEDIA-MEDIA-DIR is a record that indicates path and media type of a +;; media folder. The media type string can be empty (no media type specifi= ed), +;; one character (a single media type, e.g. "A" for audio only), or more +;; characters (mixed media types, e.g. "PV" for pictures and video). The a= llowed +;; individual types are A for audio, P for pictures, V for video. +(define-record-type* + readymedia-media-dir make-readymedia-media-dir + readymedia-media-dir? + (path readymedia-media-dir-path) + (type readymedia-media-dir-type (default ""))) + +(define (readymedia-media-dir->string entry) + "Convert a media-dir ENTRY to a ReadyMedia/MiniDLNA media dir string." + (format #f + "media_dir=3D~a,~a" + (readymedia-media-dir-type entry) + (readymedia-media-dir-path entry))) + +(define (readymedia-configuration->config-file config) + "Return the ReadyMedia/MiniDLNA configuration file corresponding to CONF= IG." + (let ((friendly-name (readymedia-configuration-friendly-name config)) + (media-dirs (readymedia-configuration-media-dirs config)) + (cache-dir (readymedia-configuration-cache-dir config)) + (log-dir (readymedia-configuration-log-dir config)) + (port (readymedia-configuration-port config)) + (extra-config (readymedia-configuration-extra-config config))) + (mixed-text-file + "minidlna.conf" + "db_dir=3D" cache-dir "\n" + "log_dir=3D" log-dir "\n" + (if friendly-name (format #f "friendly_name=3D~a\n" friendly-name) "") + (if port (format #f "port=3D~a\n" port) "") + (string-join (map readymedia-media-dir->string media-dirs) "\n" 'suff= ix) + (string-join extra-config "\n" 'suffix)))) + +(define (readymedia-shepherd-service config) + "Return a least-authority ReadyMedia/MiniDLNA Shepherd service." + (let* ((minidlna-conf (readymedia-configuration->config-file config)) + (media-dirs (readymedia-configuration-media-dirs config)) + (cache-dir (readymedia-configuration-cache-dir config)) + (log-dir (readymedia-configuration-log-dir config)) + (readymedia (least-authority-wrapper + (file-append + (readymedia-configuration-readymedia config) + "/sbin/minidlnad") + #:name "minidlna" + #:mappings (cons* (file-system-mapping + (source cache-dir) + (target source) + (writable? #t)) + (file-system-mapping + (source log-dir) + (target source) + (writable? #t)) + (file-system-mapping + (source minidlna-conf) + (target source)) + (map (lambda (e) + (file-system-mapping + (source + (readymedia-media-dir-pat= h e)) + (target source) + (writable? #f))) + media-dirs)) + #:namespaces (delq 'net %namespaces)))) + (list (shepherd-service + (documentation "Run the ReadyMedia/MiniDLNA daemon.") + (provision '(readymedia)) + (requirement '(networking user-processes)) + (start #~(make-forkexec-constructor + ;; "-S" is to daemonise minidlnad. + (list #$readymedia "-f" #$minidlna-conf "-S") + #:user "readymedia" + #:group "readymedia")) + (stop #~(make-kill-destructor)))))) + +(define readymedia-accounts + (list (user-group + (name %readymedia-user-group) + (system? #t)) + (user-account + (name %readymedia-user-account) + (group %readymedia-user-group) + (system? #t) + (comment "ReadyMedia/MiniDLNA daemon user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))) + +(define (readymedia-activation config) + "Set up directories for ReadyMedia/MiniDLNA." + (let ((cache-dir (readymedia-configuration-cache-dir config)) + (log-dir (readymedia-configuration-log-dir config))) + #~(begin + (use-modules (guix build utils)) + (define %user (getpw #$%readymedia-user-account)) + (mkdir-p #$cache-dir) + (chown #$cache-dir (passwd:uid %user) (passwd:gid %user)) + (mkdir-p #$log-dir) + (chown #$log-dir (passwd:uid %user) (passwd:gid %user))))) + +(define readymedia-service-type + (service-type + (name 'readymedia) + (extensions + (list + (service-extension shepherd-root-service-type readymedia-shepherd-ser= vice) + (service-extension account-service-type (const readymedia-accounts)) + (service-extension activation-service-type readymedia-activation))) + (description + "Run @command{minidlnad}, the ReadyMedia/MiniDLNA media server."))) base-commit: 71f0676a295841e2cc662eec0d3e9b7e69726035 --=20 2.45.2 --=-=-=--