From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 0/2] Add apcupsd Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Sun, 12 Jan 2025 23:04:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-To: guix-patches@gnu.org X-Debbugs-Original-Xcc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by submit@debbugs.gnu.org id=B.173672302126859 (code B ref -1); Sun, 12 Jan 2025 23:04:01 +0000 Received: (at submit) by debbugs.gnu.org; 12 Jan 2025 23:03:41 +0000 Received: from localhost ([127.0.0.1]:49434 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tX6zc-0006z7-Ry for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:03:41 -0500 Received: from lists.gnu.org ([2001:470:142::17]:51028) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tX6za-0006yr-FH for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:03:38 -0500 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 <~@wolfsden.cz>) id 1tX6zT-0002Y6-RM for guix-patches@gnu.org; Sun, 12 Jan 2025 18:03:31 -0500 Received: from wolfsden.cz ([37.205.8.62]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <~@wolfsden.cz>) id 1tX6zR-0002AL-Oa for guix-patches@gnu.org; Sun, 12 Jan 2025 18:03:31 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id A3BE0342D88; Sun, 12 Jan 2025 23:03:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723004; bh=cGFxvdC/c6T4ddXl9L2OjLona+t5z0KhM0b5+IkJrd4=; h=From:To:Cc:Subject:Date; b=T4BAGAN1qTkucn2r7VNbyzaPRZv2bf0/vKSoqmJOnIUWGlwXyHr47FSa5jiicHhou VXAvq6YPA2LFmb4czk4ocynK/wg/z/WHY32i/1GEoWznQAlRZ6BDk9KuxaLOPLA+eY rGOefqaMyl4ML8LycxB2PddRlaQ20Szkmh4L2gfrjqXyh/XsWbKo0+hNwmMTg4siji ZlEBtn1FYAwVMFEzDrQJVa1kRg29j4m78NkOP0tL3fK8fEG1+2/iWnbExqdhcL8v4Z WsZfcHy1LsPLQqbIgn6zpyjVeIgrF35PrKKXWSKaX/f0u1biH//u3P12298i8Ndyj2 Fx4Cb92aOLQLARTjWru4CbMzoJb1ULBFd9StJbGHx4djUvXF8NA8T38Jeg39VFFq/l fNdMDWKjsyLCmtuNU7W241XpbV491BtDm4BXiRvT5PQ0g3RZZlP94PRwahRcsS0qR3 6Q+/eEUIGPYmS4e2JeUtH1cBKKg90JHwVuJXpUmMoaLwGscosAhw3cPLK24PamzBYC yCyQzUpDBRyFhrVOmd0lpeRN6SY2lW7a2vkTSBlb7j3Rr5PWMZ7VgO6RYlSNhluxEv GFfz+oVmaxQE2pYpRNo5rV5Vn1ZUZoWvsRh6ChyVitGgZauaWIBRKSI3sGv2e8bEaR m3XW4Gj329NhuzVI7hMtEmPg= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id CF550342A88; Sun, 12 Jan 2025 23:03:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723003; bh=cGFxvdC/c6T4ddXl9L2OjLona+t5z0KhM0b5+IkJrd4=; h=From:To:Cc:Subject:Date; b=Bd5U8sbKPSGVRMegt6FIy9+/ty7Wdx060FX6ynMb7wzd7HTIST+UtdtfrwkcTpG/+ swpoNmKj9XAvU+iOiTBK8wPwggvSZsQAy1Y1vUpOcG2zIUtFH/RsgWCITRCpxI1bF8 wnNhcfiwpGjLbJtozdAWTmZsY9zcrEQP5+LKnfJsHALd3G1rsT/wmG0Fd1BMHSCPU8 h4Lp/Amb1pqXdKk1vw8StBI/410eCqMDz4t8cFkIzR1NX9aRFmE2bCvwDM6UP8zPOk 8byTK9yxQY8ehIkX92kM87tVGsSsna15n4EfUdlgmKEdAeakE/JJT986foTSNUFCG1 m4ZqJjufsg7hlYjmpE94XNAGcz+Fw42mtmAjhHRCe8Ba0akRZhuOUoMAHimynXKnny kRyr8vjGsohGBsTHjHNf1erjdKdj3r1FExDCQW2SOMhlczxHQX9O1UDaZCUPUa3MBW C44vrM2Yxp0qY6+IegT9O4EJREqBbyHE2Lag4UGP9hm8OVQImNJ6ydWscRagfx7l6r 3IikeNE+qGK8H03nYokf5frjYv/BzJiAH7LW5c+ohKtaZ7gVgfb9fU1XptK88iVKuz JVO8+lQzVl3OgY3mLwCBPlx2t073GQGCM6xRhvRyetnqI+kfy8LTkaUlXGa0AZR/V8 Oya3/9KAcP4ejHnIyxCUbHDc= From: Tomas Volf <~@wolfsden.cz> Date: Mon, 13 Jan 2025 00:03:16 +0100 Message-ID: X-Mailer: git-send-email 2.47.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=37.205.8.62; envelope-from=~@wolfsden.cz; helo=wolfsden.cz X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) For machines running with an uninterruptible power supply (UPS), it is necessary to be able to react to events from it. That allows to, for example, safely shutdown the system when battery is getting low or get a notification that battery needs to be replaced. This series adds package and service type for apcupsd, daemon to manage UPS devices made by American Power Conversion Corporation (APC). Tomas Volf (2): gnu: Add apcupsd. services: Add power. doc/guix.texi | 374 +++++++++++++++++++++- gnu/local.mk | 2 + gnu/packages/power.scm | 125 ++++++++ gnu/services/power.scm | 690 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1188 insertions(+), 3 deletions(-) create mode 100644 gnu/packages/power.scm create mode 100644 gnu/services/power.scm -- 2.47.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 12 Jan 2025 23:06:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz> Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173672313227428 (code B ref 75528); Sun, 12 Jan 2025 23:06:01 +0000 Received: (at 75528) by debbugs.gnu.org; 12 Jan 2025 23:05:32 +0000 Received: from localhost ([127.0.0.1]:49448 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tX71P-00078J-K4 for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:05:32 -0500 Received: from wolfsden.cz ([37.205.8.62]:59848) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tX71M-000788-7L for 75528@debbugs.gnu.org; Sun, 12 Jan 2025 18:05:29 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id D6036342C1D; Sun, 12 Jan 2025 23:05:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723126; bh=p0bKALsrwxfPOLQkolSwo4qZhiRU8Etm+n76/Meke8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=RP/2ORxPaEdcQtl5WsjLev/9oB93Wj+tosAyE3GrT7P+DAW0JU8VafZrtTQVf1ek3 yIohgWmHB30Whu/ktIMLV4D8zBevNCgTGOt2FWPiowzmLkDDem7b39srggfm8bCSyX XLeCZs0Yc9Oy+kbALrfTuNXUeVuujz0+f5G9UjUwgLDLOk9UcHf4CYV/kJDQ3t8L1P EfG0AbuewzQXzxTqSVNjW555nFt1hPxnG6lZnAc0A+HJvmXw5VwZFOA9EtNMyQCtT+ fFyYbMv3fc6BBC0wjGD6pJNPOGyaGSxO1TE6wQduGCeo8Ss5HyZK4WW27K+onmC25a +XFcFeRMAZIOu/f23ySxsqzWFNP8lSJdYVGLbE1O4bq0Arn5zm7KHGbQ/dVAVYrfg9 2YebP1qHQ6ie+AWORu2t7oMPbDgdVUtwz9HXGBqZ0HRe9odWV423E3P8yD2KF4MQq4 mmVo4jX1r2V4ywK5kQ3LmGQQPQTSTBGeVrsUq0Mfo51jiSJe7ocbo6uuWHgYeuRKEI scKnPbbvWubV6jk1U8FPdQuic+5fOQrJl6q/dcgR99OCMC9yloNaCeMvjTGs4aUYF7 AKHH5m18LUT8M0TaC22nU6Wj9ODDG+fK2AB16iBFDBA1fno1VBQ0rMN1SmBReCSvC5 Dslcb/ucoesb1Ui3ez3RLxns= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id F2D12341673; Sun, 12 Jan 2025 23:05:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723126; bh=p0bKALsrwxfPOLQkolSwo4qZhiRU8Etm+n76/Meke8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=RP/2ORxPaEdcQtl5WsjLev/9oB93Wj+tosAyE3GrT7P+DAW0JU8VafZrtTQVf1ek3 yIohgWmHB30Whu/ktIMLV4D8zBevNCgTGOt2FWPiowzmLkDDem7b39srggfm8bCSyX XLeCZs0Yc9Oy+kbALrfTuNXUeVuujz0+f5G9UjUwgLDLOk9UcHf4CYV/kJDQ3t8L1P EfG0AbuewzQXzxTqSVNjW555nFt1hPxnG6lZnAc0A+HJvmXw5VwZFOA9EtNMyQCtT+ fFyYbMv3fc6BBC0wjGD6pJNPOGyaGSxO1TE6wQduGCeo8Ss5HyZK4WW27K+onmC25a +XFcFeRMAZIOu/f23ySxsqzWFNP8lSJdYVGLbE1O4bq0Arn5zm7KHGbQ/dVAVYrfg9 2YebP1qHQ6ie+AWORu2t7oMPbDgdVUtwz9HXGBqZ0HRe9odWV423E3P8yD2KF4MQq4 mmVo4jX1r2V4ywK5kQ3LmGQQPQTSTBGeVrsUq0Mfo51jiSJe7ocbo6uuWHgYeuRKEI scKnPbbvWubV6jk1U8FPdQuic+5fOQrJl6q/dcgR99OCMC9yloNaCeMvjTGs4aUYF7 AKHH5m18LUT8M0TaC22nU6Wj9ODDG+fK2AB16iBFDBA1fno1VBQ0rMN1SmBReCSvC5 Dslcb/ucoesb1Ui3ez3RLxns= From: Tomas Volf <~@wolfsden.cz> Date: Mon, 13 Jan 2025 00:05:13 +0100 Message-ID: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/packages/power.scm (apcupsd): New variable. Change-Id: I74f59cd1fa2a13954117ff1683a10a84576cc839 --- gnu/local.mk | 1 + gnu/packages/power.scm | 125 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 gnu/packages/power.scm diff --git a/gnu/local.mk b/gnu/local.mk index 855f2acccc..6ca7bf68ac 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -557,6 +557,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/polkit.scm \ %D%/packages/popt.scm \ %D%/packages/potassco.scm \ + %D%/packages/power.scm \ %D%/packages/printers.scm \ %D%/packages/profiling.scm \ %D%/packages/prolog.scm \ diff --git a/gnu/packages/power.scm b/gnu/packages/power.scm new file mode 100644 index 0000000000..98dc98c6e4 --- /dev/null +++ b/gnu/packages/power.scm @@ -0,0 +1,125 @@ +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> +;;; Copyright (C) 2023 Raven Hallsby + +;;;; Commentary: + +;;; Power-related packages. + +;;;; Code: + +(define-module (gnu packages power) + #:use-module (gnu) + #:use-module (gnu packages libusb) + #:use-module (gnu packages linux) + #:use-module (gnu packages pkg-config) + #:use-module (gnu packages python-xyz) + #:use-module (guix build-system gnu) + #:use-module (guix download) + #:use-module (guix gexp) + #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix packages)) + +(define-public apcupsd + (package + (name "apcupsd") + (version "3.14.14") + (source (origin + (method url-fetch) + (uri + (string-append + "mirror://sourceforge/" name "/" name " - Stable/" version + "/" name "-" version ".tar.gz")) + (sha256 + (base32 + "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv")))) + (native-inputs + (list pkg-config python-docutils)) + (inputs + (list libusb libusb-compat)) + (outputs '("out" "doc")) + (build-system gnu-build-system) + (arguments + (list + #:configure-flags + #~(list + ;; The configure script ignores --prefix for most of the paths. + (string-append "--exec-prefix=" #$output) + (string-append "--mandir=" #$output "/share/man") + (string-append "--sbindir=" #$output "/sbin") + (string-append "--sysconfdir=" #$output "/etc/apcupsd") + (string-append "--with-halpolicydir=" #$output "/share/halpolicy") + + ;; Put us into the version string. + "--with-distname=GNU/Guix" + "--disable-install-distdir" + + ;; State directories. + "--localstatedir=/var" + "--with-log-dir=/var/log" + "--with-pid-dir=/var/run" + "--with-lock-dir=/var/run/apcupsd/lock" + "--with-nologin=/var/run/apcupsd" + "--with-pwrfail-dir=/var/run/apcupsd" + + ;; Configure requires these, but we do not use the genenerated + ;; apcupsd.conf, so in order to reduce dependencies of the package, + ;; provide fake values. + (string-append "ac_cv_path_SHUTDOWN=/nope") + (string-append "ac_cv_path_APCUPSD_MAIL=/nope") + ;; While `wall' is not expanded anywhere, it still is searched for. + (string-append "ac_cv_path_WALL=/nope") + + ;; Enable additional drivers. + "--enable-test" + "--enable-usb" + "--enable-modbus-usb") + #:tests? #f ; There are no tests. + #:modules (cons '(ice-9 ftw) %default-gnu-modules) + #:phases + #~(modify-phases %standard-phases + ;; These are not installed, so trick Make into thinking they were + ;; already generated. Allows us not to depend on mandoc, util-linux. + (add-before 'configure 'touch-txt-docs + (lambda _ + (for-each (lambda (f) + (call-with-output-file f close-port)) + '("doc/apcupsd.man.txt" + "doc/apcaccess.man.txt" + "doc/apctest.man.txt" + "doc/apccontrol.man.txt" + "doc/apcupsd.conf.man.txt")))) + (add-after 'build 'build-manual + (lambda _ + (invoke "make" "-C" "doc/manual" "manual.html"))) + (add-after 'install-license-files 'move-doc + (lambda _ + (let ((target (string-append #$output:doc + "/share/doc/" + (strip-store-file-name #$output)))) + (mkdir-p target) + (for-each (lambda (f) + (copy-file (string-append "doc/manual/" f) + (string-append target "/" f))) + (scandir "doc/manual" + (lambda (f) + (or (string-suffix? ".png" f) + (string-suffix? ".html" f)))))))) + ;; If sending mails is required, use proper mail program. + (add-after 'install 'remove-smtp + (lambda _ + (delete-file (string-append #$output "/sbin/smtp")))) + ;; The configuration files and scripts are not really suitable for + ;; Guix, and our service provides its own version anyway. So nuke + ;; these to make sure `apcupsd' and `apctest' executed without any + ;; arguments fail. `apctest' actually segfaults, but only after + ;; printing an error ¯\_(ツ)_/¯. + (add-after 'install 'remove-etc-apcupsd + (lambda _ + (delete-file-recursively (string-append #$output "/etc/apcupsd"))))))) + (home-page "https://www.apcupsd.org") + (synopsis "A daemon for controlling APC UPSes") + (description "Apcupsd can be used for power mangement and controlling most +of APC’s UPS models on Unix and Windows machines. Apcupsd works with most of +APC’s Smart-UPS models as well as most simple signalling models such a Back-UPS, +and BackUPS-Office.") + (license license:gpl2))) -- 2.47.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Sun, 12 Jan 2025 23:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-Xcc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173672313827448 (code B ref 75528); Sun, 12 Jan 2025 23:06:02 +0000 Received: (at 75528) by debbugs.gnu.org; 12 Jan 2025 23:05:38 +0000 Received: from localhost ([127.0.0.1]:49450 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tX71U-00078c-I1 for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:05:38 -0500 Received: from wolfsden.cz ([37.205.8.62]:59852) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tX71O-00078H-Rw for 75528@debbugs.gnu.org; Sun, 12 Jan 2025 18:05:33 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id E84613414EE; Sun, 12 Jan 2025 23:05:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723129; bh=IQ6imuI/xWTpcFS3o6s/qnP05FzScxSeK9RdNZROh6Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pDlUZUvuZegoTTAZ6YjcpkxqSZqLHyk/sHRq8HcVAb/acjQpRO7lyRWDMwI5y3fl9 QddCyzx3ohlrGF903NNDrhhMjpFTavsLzCZVrfI+tMlSNfL1cvZEmn3gE9BNM8SJU6 wAunANTteV/DNk65Af8gq8pr/HNI8k9FfYDPzxkocYulHiGiP+DgVvXse5ilZTexw7 f+DZ/b3WzPyABk4o4MA2do6bp2ljm/dtABkGQT43jm82f3Rk47yu+ZREflbP4A7XCo eJpSJUnfRzJ8Fj2sOXFkQbEuMVLhNLRNFs2XRaxpxAifjzFAhmHKvsRunlYGyNAP9x gQ5DLqzNokePWy9Ls7y/Y9/1SvO9hVRgu7jiKgYyWuL1dLV1Qjt7UXx6KpQUr37p39 PCYcA/SD52pTZoaW2W2WY+kwymOgUo0fKOg59iUyaNu+yXrjxtWI3cTrdg9U1VsTh3 MCmZz0ns7MUgGdwgwygzEqK+h5sNKV0cij2Ufel4NbDsPaqcpLGi+icszEEPDAC0pS xdIdWqahkJF0T/hwE0lC4cxO6g4v+7MS/brPaz5/2mGlNBesZt5U5kCxQY7qax29cX bWC3b9E9Sjwxuu7Cn8dkuNYlv2DNm4Z6Kg3sSWvCgzUYzDDGkFHkvvxZF7hjFtp60P 62a3ntdrD04aabBgG9t2XH2k= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 7FD0C34242F; Sun, 12 Jan 2025 23:05:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723126; bh=IQ6imuI/xWTpcFS3o6s/qnP05FzScxSeK9RdNZROh6Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=klbBR33rxP30rS96Q4MDlPmpUYu4ZtuO9NdLzyOX7obfmR32F0uZUup/Jp161KjzT 2lEpBrKdTdgpw8YdVSnvUtVpKlFjjzQa3MbNDpWCLiAUVYL/fasKxOSKJWxGMl0tCi a9/V66YL4Hh+2Y4UCvH8xSBCZ+YKmORrZDOSrVLrOUZcuKU0JiQY4oTOhbRyYrNYt1 YIF0AxKtQZN9ezGzi6TpIflAbJluUnSxg/uLB1A8yrSbPXb7svqXGEtJ82udEwL8Xx v19li8YLWoizPaSvKIFUFQtS89RQ3HQ2G8tFJM2cXoR9GvKHOcAhaQnIDE4PYSl2dC Oik2TOdu+i6plLXTzthgFe7gghkSlUhNEuiSoZe5Gco6lzGXgyQXxr5Cay+MN0OLg6 iHS9IBkcbb6Epnc45cXHEdid+Ivf8HfgUxzg/A3GtuYb/3d33zJNyVf0/Uk+8bBjWF juDosGjRNKDxCbH/kLAt/myDFHhXztLuiTzcZDIlMK660+j/MU1crjCnBJH7sxk5O9 dAY6/zkTRErorxoJ8rPx9g7Zi0O1Qbubo79FEBgIZq3xi95iyX0sUlrVj3ISnHeDWv RYB8LjtcVUxPwGebTT0zlP7e6+4qeiS79WBKNM4LiyrbcyH7EnoV0pJszUF3tskjff Cb7Q8548JouLQdfD4yamMics= From: Tomas Volf <~@wolfsden.cz> Date: Mon, 13 Jan 2025 00:05:14 +0100 Message-ID: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/services/power.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Power Management Services): Document service and data types. Change-Id: If205d19bea1d20a99309626e28521a2d6fe6702f --- doc/guix.texi | 374 +++++++++++++++++++++- gnu/local.mk | 1 + gnu/services/power.scm | 690 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1062 insertions(+), 3 deletions(-) create mode 100644 gnu/services/power.scm diff --git a/doc/guix.texi b/doc/guix.texi index d6e17c74cd..6cb11200cd 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -123,7 +123,7 @@ Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* Copyright @copyright{} 2023 Graham James Addis@* -Copyright @copyright{} 2023, 2024 Tomas Volf@* +Copyright @copyright{} 2023-2025 Tomas Volf@* Copyright @copyright{} 2024 Herman Rimm@* Copyright @copyright{} 2024 Matthew Trzcinski@* Copyright @copyright{} 2024 Richard Sent@* @@ -420,7 +420,7 @@ Top * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -19255,7 +19255,7 @@ Services * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -36263,6 +36263,374 @@ Power Management Services @end table @end deftp +The @code{(gnu services power)} module provides a service definition for +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with APC +UPSes. Apcupsd also works with some OEM-branded products manufactured +by APC. + +@defvar apcupsd-service-type +The service type for apcupsd. For USB UPSes no configuration is +necessary, however tweaking some fields to better suit your needs might +be desirable. The defaults are taken from the upstream configuration +and they are not very conservative (@code{battery-level} of 5% is too +low in my opinion). + +The default event handlers do send emails, read more in +@ref{apcupsd-event-handlers}. + +@lisp +(service apcupsd-service-type) +@end lisp +@end defvar + +@deftp {Data Type} apcupsd-configuration + +Available @code{apcupsd-configuration} fields are: + +@table @asis +@item @code{package} (default: @code{apcupsd}) (type: package) +Package to use. + +@item @code{shepherd-base-name} (default: @code{apcupsd}) (type: symbol) +Base name of the shepherd service. You can add the service multiple +times with different prefix to manage multiple UPSes. + +@item @code{auto-start?} (default: @code{#t}) (type: boolean) +Should the shepherd service auto-start? + +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: string) +Path to the pid file. + +@item @code{debug-level} (default: @code{0}) (type: integer) +Logging verbosity. Bigger number means more logs. In the source code I +saw up to @code{300}, so for all logs, @code{999} seems reasonable. + +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) +Directory containing runtime information. You need to change this if +you desire to run multiple instances of the daemon. + +@item @code{name} (type: maybe-string) +Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the +EEPROM. It should be 8 characters or less. + +@item @code{cable} (default: @code{usb}) (type: enum-cable) +The type of cable connecting the UPS to your computer. Possible generic +choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. Or a specific cable model number may be used: +@code{'940-0119A}, @code{'940-0127A}, @code{'940-0128A}, +@code{'940-0020B}, @code{'940-0020C}, @code{'940-0023A}, +@code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, +@code{'940-0095C}, @code{'940-0625A}, @code{'M-04-02-2000}. + +@item @code{type} (default: @code{usb}) (type: enum-type) +Type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a +serial cable (not USB). + +@item usb +Most new UPSes are USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information +Server. This is used if the UPS powering your computer is connected to +a different computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as SNMP above but requires use of the net-snmp library. Unless you +have a specific need for this old driver, you should use @code{'snmp} +instead. + +@item dumb +Old serial character device for use with simple-signaling UPSes. + +@item pcnet +PowerChute Network Shutdown protocol which can be used as an alternative +to SNMP with the AP9617 family of smart slot cards. + +@item modbus +Serial device for use with newest SmartUPS models supporting the MODBUS +protocol. + +@end table + +@item @code{device} (default: @code{""}) (type: string) +For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables autodetection, which is the best choice +for most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. +@var{hostname} is the ip address or hostname of the UPS on the network. +@var{vendor} can be can be "APC" or "APC_NOTRAP". "APC_NOTRAP" will +disable SNMP trap catching; you usually want "APC". @var{port} is +usually 161. @var{community} is usually "private". + +@item netsnmp +Same as @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. +@var{ipaddr} is the IP address of the UPS management card. +@var{username} and @var{passphrase} are the credentials for which the +card has been configured. @var{port} is the port number on which to +listen for messages from the UPS, normally 3052. If this parameter is +empty or missing, the default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it +empty for MODBUS over USB or set to the serial number of the UPS. + +@end table + +@item @code{poll-time} (default: @code{60}) (type: integer) +Interval (in seconds) at which apcupsd polls the UPS for status. This +setting applies both to directly-attached UPSes (apcsmart, usb, dumb) +and networked UPSes (net, snmp). Lowering this setting will improve +apcupsd's responsiveness to certain events at the cost of higher CPU +utilization. + +@item @code{on-batery-delay} (default: @code{6}) (type: integer) +The the time in seconds from when a power failure is detected until we +react to it with an onbattery event. The @code{'powerout} event will be +triggered immediately when a power failure is detected. However, the +@code{'onbattery} event will be trigger only after this delay. + +@item @code{battery-level} (default: @code{5}) (type: integer) +If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{remaining-minutes} (default: @code{3}) (type: integer) +If during a power failure, the remaining runtime in minutes (as +calculated internally by the UPS) is below or equal to this value, +apcupsd will initiate a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{timeout} (default: @code{0}) (type: integer) +If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. A value of +0 disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{annoy-interval} (default: @code{300}) (type: integer) +Time in seconds between annoying users (via the @code{'annoyme} event) +to sign off prior to system shutdown. 0 disables. + +@item @code{annoy-delay} (default: @code{60}) (type: integer) +Initial delay in seconds after power failure before warning users to get +off the system. + +@item @code{no-logon} (default: @code{disable}) (type: enum-no-logon) +The condition which determines when users are prevented from logging in +during a power failure. + +@item @code{kill-delay} (default: @code{0}) (type: integer) +If this is non-zero, apcupsd will continue running after a shutdown has +been requested, and after the specified time in seconds attempt to kill +the power. This is for use on systems where apcupsd cannot regain +control after a shutdown. + +@item @code{net-server} (default: @code{#f}) (type: boolean) +If enabled, a network information server process will be started. + +@item @code{net-server-ip} (default: @code{"127.0.0.1"}) (type: string) +IP address on which NIS server will listen for incoming connections. + +@item @code{net-server-port} (default: @code{3551}) (type: integer) +IP port on which NIS server will listen for incoming connections. + +@item @code{net-server-events-file} (type: maybe-string) +If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file patch. + +@item @code{net-server-events-file-max-size} (default: @code{10}) (type: integer) +Maximum size of the events file in kilobytes. + +@item @code{class} (default: @code{standalone}) (type: enum-class) +Normally standalone unless you share an UPS using an APC ShareUPS card. + +@item @code{mode} (default: @code{disable}) (type: enum-mode) +Normally disable unless you share an UPS using an APC ShareUPS card. + +@item @code{stat-time} (default: @code{0}) (type: integer) +Time interval in seconds between writing the status file, 0 disables. + +@item @code{log-stats} (default: @code{#f}) (type: boolean) +Also write the stats as a logs. This generates a lot of output. + +@item @code{data-time} (default: @code{0}) (type: integer) +Time interval in seconds between writing the data records to the log +file, 0 disables. + +@item @code{facility} (type: maybe-string) +The logging facility for the syslog. + +@item @code{event-handlers} (type: apcupsd-event-handlers) +Handlers for events produced by apcupsd. + +@end table + +@end deftp + +@anchor{apcupsd-event-handlers} +@deftp {Data Type} apcupsd-event-handlers + +For description of the events please refer to the @command{apcupsd}'s +manual, which can be found in the @samp{apcupsd-doc} package. + +Each handler shall be a gexp. It is spliced into the control script for +the daemon. In addition to the standard Guile programming environment, +these procedures and variables are also available. + +@table @code +@item conf +Variable containing path to the configuration file. + +@item powerfail-file +Variable containing path to the powerfail file. + +@item cmd +The event currently being handled. + +@item name +The name of the UPS as specified in the configuration file. + +@item connected +Is @code{"1"} if apcupsd is connected to the UPS via a serial port (or a +USB port). In most configurations, this will be the case. In the case +of a Slave machine where apcupsd is not directly connected to the UPS, +this value will be @code{"0"}. + +@item powered +Is @code{"1"} if the computer on which @command{apcupsd} is running is +powered by the UPS and @code{"0"} if not. At the moment, this value is +unimplemented and always @code{"0"}. + +@item (err @var{fmt} @var{args...}) +Wrapper around @code{format} outputting to @code{(current-error-port)}. + +@item (wall @var{fmt} @var{args...}) +Wrapper around @code{format} outputting via @command{wall}. + +@item (apcupsd @var{args...}) +Call @command{apcupsd} while passing the correct configuration file and +all the arguments. + +@item (mail-to-root @var{subject} @var{body}) +Send an email to the local administrator. This procedure assumes the +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} +(as would be the case with @code{opensmtpd-service-type}). + +@end table + +Available @code{apcupsd-event-handlers} fields are: + +@table @asis +@item @code{killpower} (type: gexp) +Handler for killpower event. + +@item @code{commfailure} (type: gexp) +Handler for commfailure event. + +@item @code{commok} (type: gexp) +Handler for commfailure event. + +@item @code{powerout} (type: gexp) +Handler for powerout event. + +@item @code{onbattery} (type: gexp) +Handler for onbattery event. + +@item @code{offbattery} (type: gexp) +Handler for offbattery event. + +@item @code{mainsback} (type: gexp) +Handler for mainsback event. + +@item @code{failing} (type: gexp) +Handler for failing event. + +@item @code{timeout} (type: gexp) +Handler for timeout event. + +@item @code{loadlimit} (type: gexp) +Handler for loadlimit event. + +@item @code{runlimit} (type: gexp) +Handler for runlimit event. + +@item @code{doreboot} (type: gexp) +Handler for doreboot event. + +@item @code{doshutdown} (type: gexp) +Handler for doshutdown event. + +@item @code{annoyme} (type: gexp) +Handler for annoyme event. + +@item @code{emergency} (type: gexp) +Handler for emergency event. + +@item @code{changeme} (type: gexp) +Handler for changeme event. + +@item @code{remotedown} (type: gexp) +Handler for remotedown event. + +@item @code{startselftest} (type: gexp) +Handler for startselftest event. + +@item @code{endselftest} (type: gexp) +Handler for endselftest event. + +@item @code{battdetach} (type: gexp) +Handler for battdetach event. + +@item @code{battattach} (type: gexp) +Handler for battattach event. + +@end table + +@end deftp + @node Audio Services @subsection Audio Services diff --git a/gnu/local.mk b/gnu/local.mk index 6ca7bf68ac..dea0e43fe6 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -758,6 +758,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/nix.scm \ %D%/services/nfs.scm \ %D%/services/pam-mount.scm \ + %D%/services/power.scm \ %D%/services/science.scm \ %D%/services/security.scm \ %D%/services/security-token.scm \ diff --git a/gnu/services/power.scm b/gnu/services/power.scm new file mode 100644 index 0000000000..a6f9259eb3 --- /dev/null +++ b/gnu/services/power.scm @@ -0,0 +1,690 @@ +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> + +;;;; Commentary: + +;;; Power-related services. + +;;;; Code: + +(define-module (gnu services power) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (ice-9 match) + #:use-module (gnu) + #:use-module (gnu packages admin) + #:use-module (gnu packages linux) + #:use-module (gnu packages power) + #:use-module (gnu services) + #:use-module (gnu services configuration) + #:use-module (gnu services shepherd) + #:use-module (guix packages) + #:use-module (guix records) + #:export (apcupsd-service-type + + apcupsd-configuration + apcupsd-configuration-package + apcupsd-configuration-shepherd-base-name + apcupsd-configuration-auto-start? + apcupsd-configuration-pid-file + apcupsd-configuration-debug-level + apcupsd-configuration-run-dir + apcupsd-configuration-name + apcupsd-configuration-cable + apcupsd-configuration-type + apcupsd-configuration-device + apcupsd-configuration-poll-time + apcupsd-configuration-on-batery-delay + apcupsd-configuration-battery-level + apcupsd-configuration-remaining-minutes + apcupsd-configuration-timeout + apcupsd-configuration-annoy-interval + apcupsd-configuration-annoy-delay + apcupsd-configuration-no-logon + apcupsd-configuration-kill-delay + apcupsd-configuration-net-server + apcupsd-configuration-net-server-ip + apcupsd-configuration-net-server-port + apcupsd-configuration-net-server-events-file + apcupsd-configuration-net-server-events-file-max-size + apcupsd-configuration-class + apcupsd-configuration-mode + apcupsd-configuration-stat-time + apcupsd-configuration-log-stats + apcupsd-configuration-data-time + apcupsd-configuration-facility + apcupsd-configuration-event-handlers + + apcupsd-event-handlers-annoyme + apcupsd-event-handlers-battattach + apcupsd-event-handlers-battdetach + apcupsd-event-handlers-changeme + apcupsd-event-handlers-commfailure + apcupsd-event-handlers-commok + apcupsd-event-handlers-doreboot + apcupsd-event-handlers-doshutdown + apcupsd-event-handlers-emergency + apcupsd-event-handlers-endselftest + apcupsd-event-handlers-failing + apcupsd-event-handlers-killpower + apcupsd-event-handlers-loadlimit + apcupsd-event-handlers-mainsback + apcupsd-event-handlers-offbattery + apcupsd-event-handlers-onbattery + apcupsd-event-handlers-powerout + apcupsd-event-handlers-remotedown + apcupsd-event-handlers-runlimit + apcupsd-event-handlers-startselftest + apcupsd-event-handlers-timeout)) + +(define-configuration/no-serialization apcupsd-event-handlers + (killpower + (gexp + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) + (sleep 10) + (apcupsd "--killpower") + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) + "Handler for killpower event.") + (commfailure + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a lost." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Warning: communications lost with UPS ~a" name))) + "Handler for commfailure event.") + (commok + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a restored." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Communications restored with UPS ~a" name))) + "Handler for commfailure event.") + (powerout + (gexp + #~(#t)) + "Handler for powerout event.") + (onbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power failure on UPS ~a. Running on batteries." name))) + "Handler for onbattery event.") + (offbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power has returned." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power has returned on UPS ~a..." name))) + "Handler for offbattery event.") + (mainsback + (gexp + #~((when (file-exists? powerfail-file) + (wall "Continuing with shutdown.")))) + "Handler for mainsback event.") + (failing + (gexp + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name))) + "Handler for failing event.") + (timeout + (gexp + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." name))) + "Handler for timeout event.") + (loadlimit + (gexp + #~((wall "Remaining battery charge below limit on UPS ~a. Doing shutdown." name))) + "Handler for loadlimit event.") + (runlimit + (gexp + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing shutdown." name))) + "Handler for runlimit event.") + (doreboot + (gexp + #~((wall "UPS ~a initiating Reboot Sequence" name) + (system* #$(file-append shepherd "/sbin/reboot")))) + "Handler for doreboot event.") + (doshutdown + (gexp + #~((wall "UPS ~a initiated Shutdown Sequence" name) + (system* #$(file-append shepherd "/sbin/halt")))) + "Handler for doshutdown event.") + (annoyme + (gexp + #~((wall "Power problems with UPS ~a. Please logoff." name))) + "Handler for annoyme event.") + (emergency + (gexp + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a." name))) + "Handler for emergency event.") + (changeme + (gexp + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Emergency! Batteries have failed on UPS ~a. Change them NOW." name))) + "Handler for changeme event.") + (remotedown + (gexp + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) + "Handler for remotedown event.") + (startselftest + (gexp + #~(#t)) + "Handler for startselftest event.") + (endselftest + (gexp + #~(#t)) + "Handler for endselftest event.") + (battdetach + (gexp + #~(#t)) + "Handler for battdetach event.") + (battattach + (gexp + #~(#t)) + "Handler for battattach event.")) + +(define-syntax define-enum + (lambda (x) + (syntax-case x () + ((_ name values) + (let* ((d/n (syntax->datum #'name)) + (d/predicate (string->symbol + (format #f "enum-~a?" d/n))) + (d/serialize (string->symbol + (format #f "serialize-enum-~a" d/n)))) + (with-syntax + ((predicate (datum->syntax x d/predicate)) + (serialize (datum->syntax x d/serialize))) + #'(begin + (define (predicate value) + (memq value values)) + (define serialize serialize-symbol)))))))) + +(define mangle-field-name + (match-lambda + ('name "UPSNAME") + ('cable "UPSCABLE") + ('type "UPSTYPE") + ('device "DEVICE") + ('poll-time "POLLTIME") + ('lock-dir "LOCKFILE") + ('power-fail-dir "PWRFAILDIR") + ('no-login-dir "NOLOGINDIR") + ('on-batery-delay "ONBATTERYDELAY") + ('battery-level "BATTERYLEVEL") + ('remaining-minutes "MINUTES") + ('timeout "TIMEOUT") + ('annoy-interval "ANNOY") + ('annoy-delay "ANNOYDELAY") + ('no-logon "NOLOGON") + ('kill-delay "KILLDELAY") + ('net-server "NETSERVER") + ('net-server-ip "NISIP") + ('net-server-port "NISPORT") + ('net-server-events-file "EVENTSFILE") + ('net-server-events-file-max-size "EVENTSFILEMAX") + ('class "UPSCLASS") + ('mode "UPSMODE") + ('stat-time "STATTIME") + ('stat-file "STATFILE") + ('log-stats "LOGSTATS") + ('data-time "DATATIME") + ('facility "FACILITY"))) + +(define (serialize-string field-name value) + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) +(define serialize-symbol serialize-string) +(define serialize-integer serialize-string) +(define (serialize-boolean field-name value) + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) #$(if value "on" "off"))) + +(define-maybe string) + +(define-enum cable '( simple smart ether usb + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-2000)) +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test)) +(define-enum no-logon '(disable timeout percent minutes always)) +(define-enum class '(standalone shareslave sharemaster)) +(define-enum mode '(disable share)) + +(define-configuration apcupsd-configuration + (package (package apcupsd) "Package to use.") + + (shepherd-base-name + (symbol 'apcupsd) + "Base name of the shepherd service. You can add the service multiple times +with different prefix to manage multiple UPSes." + empty-serializer) + (auto-start? + (boolean #t) + "Should the shepherd service auto-start?" + empty-serializer) + (pid-file + (string "/var/run/apcupsd.pid") + "Path to the pid file." + empty-serializer) + (debug-level + (integer 0) + "Logging verbosity. Bigger number means more logs. In the source code I saw +up to @code{300}, so for all logs, @code{999} seems reasonable." + empty-serializer) + + (run-dir + (string "/var/run/apcupsd") + "Directory containing runtime information. You need to change this if you +desire to run multiple instances of the daemon." + empty-serializer) + + ;; General configuration parameters + (name + maybe-string + "Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the EEPROM. +It should be 8 characters or less.") + (cable + (enum-cable 'usb) + "The type of cable connecting the UPS to your computer. Possible generic +choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Or a specific cable model number may be used: @code{'940-0119A}, +@code{'940-0127A}, @code{'940-0128A}, @code{'940-0020B}, @code{'940-0020C}, +@code{'940-0023A}, @code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, @code{'940-0095C}, +@code{'940-0625A}, @code{'M-04-02-2000}.") + (type + (enum-type 'usb) + "Type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a serial +cable (not USB). + +@item usb +Most new UPSes are USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information Server. +This is used if the UPS powering your computer is connected to a different +computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as SNMP above but requires use of the net-snmp library. Unless you have a +specific need for this old driver, you should use @code{'snmp} instead. + +@item dumb +Old serial character device for use with simple-signaling UPSes. + +@item pcnet +PowerChute Network Shutdown protocol which can be used as an alternative to SNMP +with the AP9617 family of smart slot cards. + +@item modbus +Serial device for use with newest SmartUPS models supporting the MODBUS +protocol. + +@end table") + (device + (string "") + "For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables autodetection, which is the best choice for most +installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. +@var{hostname} is the ip address or hostname of the UPS on the network. +@var{vendor} can be can be \"APC\" or \"APC_NOTRAP\". \"APC_NOTRAP\" will +disable SNMP trap catching; you usually want \"APC\". @var{port} is usually +161. @var{community} is usually \"private\". + +@item netsnmp +Same as @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. +@var{ipaddr} is the IP address of the UPS management card. @var{username} and +@var{passphrase} are the credentials for which the card has been configured. +@var{port} is the port number on which to listen for messages from the UPS, +normally 3052. If this parameter is empty or missing, the default of 3052 will +be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it empty +for MODBUS over USB or set to the serial number of the UPS. + +@end table") + (poll-time + (integer 60) + "Interval (in seconds) at which apcupsd polls the UPS for status. This +setting applies both to directly-attached UPSes (apcsmart, usb, dumb) and +networked UPSes (net, snmp). Lowering this setting will improve apcupsd's +responsiveness to certain events at the cost of higher CPU utilization.") + + ;; Configuration parameters used during power failures + (on-batery-delay + (integer 6) + "The the time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be triggered +immediately when a power failure is detected. However, the @code{'onbattery} +event will be trigger only after this delay.") + (battery-level + (integer 5) + "If during a power failure, the remaining battery percentage (as reported by +the UPS) is below or equal to this value, apcupsd will initiate a system +shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (remaining-minutes + (integer 3) + "If during a power failure, the remaining runtime in minutes (as calculated +internally by the UPS) is below or equal to this value, apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (timeout + (integer 0) + "If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. A value of 0 +disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (annoy-interval + (integer 300) + "Time in seconds between annoying users (via the @code{'annoyme} event) to +sign off prior to system shutdown. 0 disables.") + (annoy-delay + (integer 60) + "Initial delay in seconds after power failure before warning users to get off +the system.") + (no-logon + (enum-no-logon 'disable) + "The condition which determines when users are prevented from logging in +during a power failure.") + (kill-delay + (integer 0) + "If this is non-zero, apcupsd will continue running after a shutdown has been +requested, and after the specified time in seconds attempt to kill the power. +This is for use on systems where apcupsd cannot regain control after a +shutdown.") + + ;; Configuration statements for Network Information Server + (net-server + (boolean #f) + "If enabled, a network information server process will be started.") + (net-server-ip + (string "127.0.0.1") + "IP address on which NIS server will listen for incoming connections.") + (net-server-port + (integer 3551) + "IP port on which NIS server will listen for incoming connections.") + (net-server-events-file + maybe-string + "If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file patch.") + (net-server-events-file-max-size + (integer 10) + "Maximum size of the events file in kilobytes.") + ;; Configuration statements used if sharing a UPS with more than one machine + (class (enum-class 'standalone) + "Normally standalone unless you share an UPS using an APC ShareUPS card.") + (mode (enum-mode 'disable) + "Normally disable unless you share an UPS using an APC ShareUPS card.") + ;; Configuration statements to control apcupsd system logging + (stat-time + (integer 0) + "Time interval in seconds between writing the status file, 0 disables.") + (log-stats + (boolean #f) + "Also write the stats as a logs. This generates a lot of output.") + (data-time + (integer 0) + "Time interval in seconds between writing the data records to the log file, 0 +disables.") + (facility + maybe-string + "The logging facility for the syslog.") + + ;; Event handlers + (event-handlers + (apcupsd-event-handlers (apcupsd-event-handlers)) + "Handlers for events produced by apcupsd." + empty-serializer)) + +(define (s/apccontrol cfg) + (program-file + "apccontrol" + #~(begin + (use-modules (srfi srfi-9) + (ice-9 format) + (ice-9 match) + (ice-9 popen)) + ;; Script dir depends on these, and the configuration depends on the script + ;; dir. To sever the cyclic dependency, pass the paths via environment + ;; variables. + (define conf (getenv "GUIX_APCUPSD_CONF")) + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) + + (define (err . args) + (apply format (current-error-port) args)) + (define (wall . args) + (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) + (define (apcupsd . args) + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) + (define (mail-to-root subject body) + (let ((port (open-pipe* OPEN_WRITE + "/run/privileged/bin/sendmail" + "-F" "apcupsd" + "root"))) + (format port "Subject: ~a~%~%~a~&" subject body) + (close-pipe port))) + (match (cdr (command-line)) + (((? string? cmd) name connected powered) + (match cmd + ;; I am sure this could be done by macro, but meh. Last release of + ;; apcupsd was in 2016, so maintaining this will not be much work. + ("killpower" + #$@(apcupsd-event-handlers-killpower + (apcupsd-configuration-event-handlers cfg))) + ("commfailure" + #$@(apcupsd-event-handlers-commfailure + (apcupsd-configuration-event-handlers cfg))) + ("commok" + #$@(apcupsd-event-handlers-commok + (apcupsd-configuration-event-handlers cfg))) + ("powerout" + #$@(apcupsd-event-handlers-powerout + (apcupsd-configuration-event-handlers cfg))) + ("onbattery" + #$@(apcupsd-event-handlers-onbattery + (apcupsd-configuration-event-handlers cfg))) + ("offbattery" + #$@(apcupsd-event-handlers-offbattery + (apcupsd-configuration-event-handlers cfg))) + ("mainsback" + #$@(apcupsd-event-handlers-mainsback + (apcupsd-configuration-event-handlers cfg))) + ("failing" + #$@(apcupsd-event-handlers-failing + (apcupsd-configuration-event-handlers cfg))) + ("timeout" + #$@(apcupsd-event-handlers-timeout + (apcupsd-configuration-event-handlers cfg))) + ("loadlimit" + #$@(apcupsd-event-handlers-loadlimit + (apcupsd-configuration-event-handlers cfg))) + ("runlimit" + #$@(apcupsd-event-handlers-runlimit + (apcupsd-configuration-event-handlers cfg))) + ("doreboot" + #$@(apcupsd-event-handlers-doreboot + (apcupsd-configuration-event-handlers cfg))) + ("doshutdown" + #$@(apcupsd-event-handlers-doshutdown + (apcupsd-configuration-event-handlers cfg))) + ("annoyme" + #$@(apcupsd-event-handlers-annoyme + (apcupsd-configuration-event-handlers cfg))) + ("emergency" + #$@(apcupsd-event-handlers-emergency + (apcupsd-configuration-event-handlers cfg))) + ("changeme" + #$@(apcupsd-event-handlers-changeme + (apcupsd-configuration-event-handlers cfg))) + ("remotedown" + #$@(apcupsd-event-handlers-remotedown + (apcupsd-configuration-event-handlers cfg))) + ("startselftest" + #$@(apcupsd-event-handlers-startselftest + (apcupsd-configuration-event-handlers cfg))) + ("endselftest" + #$@(apcupsd-event-handlers-endselftest + (apcupsd-configuration-event-handlers cfg))) + ("battdetach" + #$@(apcupsd-event-handlers-battdetach + (apcupsd-configuration-event-handlers cfg))) + ("battattach" + #$@(apcupsd-event-handlers-battattach + (apcupsd-configuration-event-handlers cfg))) + (_ + (err "Unknown event: ~a~%" cmd) + (err "Iff the event was passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f)))) + (args + (err "Unknown arguments: ~a~%" args) + (err "Iff the arguments were passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f)))))) + +(define (apcupsd-script-dir cfg) + (computed-file + "apcupsd-script-dir" + #~(begin + (mkdir #$output) + (chdir #$output) + (symlink #$(s/apccontrol cfg) "apccontrol")))) + +(define (apcupsd-config-file cfg) + (let ((run-dir (apcupsd-configuration-run-dir cfg))) + (mixed-text-file + "apcupsd.conf" + "\ +## apcupsd.conf v1.1 ## +# +# for apcupsd release 3.14.14 (31 May 2016) - GNU Guix +# +# \"apcupsd\" POSIX config file (crafted via apcupsd-service-type) +" + (serialize-configuration cfg apcupsd-configuration-fields) + ;; This one is confusing. The manual page states: + ;; + ;; > It must be changed when running more than one copy of apcupsd on the + ;; > same computer to control multiple UPSes. + ;; + ;; However would you not want the lock to be per-device, not per-process? + ;; I decided to follow the documentation, but I do not understand why it + ;; should be like this. I do not have multiple UPSes to try. + (serialize-string 'lock-dir (string-append run-dir "/lock")) + (serialize-string 'power-fail-dir run-dir) + (serialize-string 'no-login-dir run-dir) + (serialize-string 'stat-file (string-append run-dir "/apcupsd.status")) + "SCRIPTDIR " (apcupsd-script-dir cfg) "\n"))) + +(define (apcupsd-shepherd-services cfg) + (match-record cfg + ( package pid-file debug-level run-dir + shepherd-base-name auto-start?) + (let* ((config-file (apcupsd-config-file cfg)) + (s/ shepherd-base-name) + (s/run-dirs (string->symbol (format #f "~a-run-dirs" s/)))) + (list + (shepherd-service + (documentation "Create the run directories.") + (provision (list s/run-dirs)) + (one-shot? #t) + (auto-start? auto-start?) + (start #~(lambda _ + ((@ (guix build utils) mkdir-p) + #$(string-append run-dir "/lock")) + #t))) + (shepherd-service + (documentation "Run apcupsd daemon.") + (requirement (list s/run-dirs)) + (provision (list s/)) + (auto-start? auto-start?) + (start #~(make-forkexec-constructor + '(#$(file-append package "/sbin/apcupsd") + "-b" ; Do not daemonize. + "-f" #$config-file + "-P" #$pid-file + "-d" #$(number->string debug-level)) + #:log-file + #$(format #f "/var/log/~a.log" shepherd-base-name) + #:environment-variables + (cons* (string-append "GUIX_APCUPSD_CONF=" + #$config-file) + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE=" + run-dir "/powerfail") + (default-environment-variables)))) + (stop #~(make-kill-destructor)) + (actions (list (shepherd-configuration-action config-file)))))))) + +(define (apcupsd-pam-extensions cfg) + (define pam-nologin + (pam-entry + (control "required") + (module "pam_nologin.so") + (arguments (list (string-append "file=" + (apcupsd-configuration-run-dir cfg) + "/nologin"))))) + + (list (pam-extension + (transformer + (lambda (pam) + (pam-service + (inherit pam) + (auth (cons pam-nologin (pam-service-auth pam))))))))) + +(define apcupsd-service-type + (service-type + (name 'apcupsd) + (description "Configure and optionally start apcupsd.") + (extensions (list (service-extension shepherd-root-service-type + apcupsd-shepherd-services) + (service-extension pam-root-service-type + apcupsd-pam-extensions))) + (compose identity) + (extend (λ (cfg lst) + (fold (cut <> <>) cfg lst))) + (default-value (apcupsd-configuration)))) -- 2.47.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 05 Feb 2025 07:00:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173873876520910 (code B ref 75528); Wed, 05 Feb 2025 07:00:01 +0000 Received: (at 75528) by debbugs.gnu.org; 5 Feb 2025 06:59:25 +0000 Received: from localhost ([127.0.0.1]:48082 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tfZNc-0005RA-GK for submit@debbugs.gnu.org; Wed, 05 Feb 2025 01:59:25 -0500 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:61761) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tfZNY-0005Qp-FN for 75528@debbugs.gnu.org; Wed, 05 Feb 2025 01:59:22 -0500 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2f9ba87f5d4so2567685a91.3 for <75528@debbugs.gnu.org>; Tue, 04 Feb 2025 22:59:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738738754; x=1739343554; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0cOqEVYqkXp6eOC3CPacp68UTUQavTbArC7gkfA8ZBM=; b=AHdV8OyXJqRDY6wnFGH83+LiPlrPsYUAPIFG8ezd6/zuppXmkpw2Sr8rzfwNEKOXuo 05XxY9aZtEMe9Quwo6kOiXwFyErYWjuwnHB9BhNs3NDXmrVXdleP1NVOrRGFWhkob/YV CX6LNEpNP7lYSZsm1h6xGqXcP9nyMN4nIs3QvU4PA44z4bM2jeA0HFCt0huaO434DJ18 jj7oGFY3VdwSumQpE3QfmVMm1eWat1/CZUPifC4k+UDpq5AF1mmDwF4Xrdftjgjl/8Oo 8R06oJQlbKKAeRpGfCXpqRmIQ7JxFx0qoW+GvnQ3ZeEk0mb8Fy1Z0ZyhRJQWYazzi9Pc on/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738738754; x=1739343554; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=0cOqEVYqkXp6eOC3CPacp68UTUQavTbArC7gkfA8ZBM=; b=mjSb2Jz+m5u1ZLBUiZyycehb2dR4P9QUK1zMBP5NrXs9b4yeBQ4qKtszQMnkHlxcZr pFft/GiQ76KUrs4jAy3gqa45++Tl/u7Cxc53zLgxDj69FZ7lRwGS4SMm2hnIrCqzYB5y yutWiF4RLiRH67kLs9cGbNjHKSTS7G6N8bdvPfkUhkZACR4HBns44RoWi5RxVlnHRQHg nVr6BRKxP63O3ZRBSOXUwq30ybwHVdoh9juYH2fUcrThMR7/G/mTRBlGM2OM7udBi3f7 mX0ObhKOWGWc09fRaI6OAXUooVmSfg/ueybsO0UQ+jP4rwdKNRojv4QRKMvmXwvhgmls U3uQ== X-Gm-Message-State: AOJu0YwMjN4rBg8XDKLH1Y4Lxn6PFGHEUpdM1H4dE1f0kO+SECwWE8gH DYqa/KkafIXkD/NEkD08c4IW7h1BNdiUdLF3qWsoYPJ1kJhIqLnq5hcUKg== X-Gm-Gg: ASbGncufk5l1amkc/UuAtg24gNU5nYiL8smJGhyUYQ2T44MP8LHvgEu5b+aZyRFxHPb /b8kO3htLqHr8RYLraYX4NnL53LlCWKquvmh+KOoqxckFUaactz++pSxtLpXXZ1hOJb572cwoec ePtv4iXnVRt6TNJDfWjeP2RsO2BqVS7Qm8Ge7oCp9uCSgibp/Nipu1W1bgb3ZJrKFnHMM1nbo5i QikJt36Zzvb3F89Y9d1A1dLVpDJ5fJ0DvSdieHj6eWQoRjTzINEwvX84muvA7U0SAJxBNXKRVyQ +XYUjTbo44EK X-Google-Smtp-Source: AGHT+IE9hiwGWVZ2wKui97uxuA6ma1b6tb+2FUEDx/nnXxWXEegnsmWt5OEu/qpsDxx9hatqkq9DOA== X-Received: by 2002:a17:90b:38c3:b0:2ee:c457:bf83 with SMTP id 98e67ed59e1d1-2f9e077dd92mr2516956a91.19.1738738753424; Tue, 04 Feb 2025 22:59:13 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f9e1d60b64sm752279a91.2.2025.02.04.22.59.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Feb 2025 22:59:12 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> (Tomas Volf's message of "Mon, 13 Jan 2025 00:05:13 +0100") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> Date: Wed, 05 Feb 2025 15:59:02 +0900 Message-ID: <87jza498sp.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: > * gnu/packages/power.scm (apcupsd): New variable. 'guix lint' says: --8<---------------cut here---------------start------------->8--- gnu/packages/power.scm:120:14: apcupsd@3.14.14: no article allowed at the b= eginning of the synopsis gnu/packages/power.scm:119:15: apcupsd@3.14.14: TLS certificate error: X.50= 9 server certificate for 'www.apcupsd.org' does not match: CN=3Dsf.net --8<---------------cut here---------------end--------------->8--- Please fix these. > Change-Id: I74f59cd1fa2a13954117ff1683a10a84576cc839 > --- > gnu/local.mk | 1 + > gnu/packages/power.scm | 125 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 126 insertions(+) > create mode 100644 gnu/packages/power.scm > > diff --git a/gnu/local.mk b/gnu/local.mk > index 855f2acccc..6ca7bf68ac 100644 > --- a/gnu/local.mk > +++ b/gnu/local.mk > @@ -557,6 +557,7 @@ GNU_SYSTEM_MODULES =3D \ > %D%/packages/polkit.scm \ > %D%/packages/popt.scm \ > %D%/packages/potassco.scm \ > + %D%/packages/power.scm \ This change should be mentioned in the change log as well, e.g.: * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. [...] > +(define-public apcupsd > + (package > + (name "apcupsd") > + (version "3.14.14") > + (source (origin > + (method url-fetch) > + (uri > + (string-append > + "mirror://sourceforge/" name "/" name " - Stable/" versi= on > + "/" name "-" version ".tar.gz")) > + (sha256 > + (base32 > + "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv"))= )) > + (native-inputs > + (list pkg-config python-docutils)) > + (inputs > + (list libusb libusb-compat)) nitpick: If there are less than 5 and they fit on the same line, I prefer to list them on the same line as the field name itself. That's how 'guix style' does it, although it has a tendency to protrude past our max column width of 80 guideline in other places (that's bug#62303). Also, we conventionally list the input fields below the arguments field of a package, although technically it's unimportant. > + (outputs '("out" "doc")) > + (build-system gnu-build-system) > + (arguments > + (list > + #:configure-flags > + #~(list > + ;; The configure script ignores --prefix for most of the paths. Well done with the comment. > + (string-append "--exec-prefix=3D" #$output) > + (string-append "--mandir=3D" #$output "/share/man") > + (string-append "--sbindir=3D" #$output "/sbin") > + (string-append "--sysconfdir=3D" #$output "/etc/apcupsd") > + (string-append "--with-halpolicydir=3D" #$output "/share/halpol= icy") > + > + ;; Put us into the version string. > + "--with-distname=3DGNU/Guix" The name is 'GNU Guix'. > + "--disable-install-distdir" > + > + ;; State directories. > + "--localstatedir=3D/var" > + "--with-log-dir=3D/var/log" > + "--with-pid-dir=3D/var/run" > + "--with-lock-dir=3D/var/run/apcupsd/lock" > + "--with-nologin=3D/var/run/apcupsd" > + "--with-pwrfail-dir=3D/var/run/apcupsd" I think /var/run is deprecated in favor of just /run, so we should configure the package to use this, I think. > + (string-append "ac_cv_path_SHUTDOWN=3D/nope") > + (string-append "ac_cv_path_APCUPSD_MAIL=3D/nope") > + ;; While `wall' is not expanded anywhere, it still is searched = for. > + (string-append "ac_cv_path_WALL=3D/nope") I'm not sure if this package is actively developed, but that last issue should ideally be reported (then cross-referenced here). > + ;; Enable additional drivers. > + "--enable-test" Is '--enable-test' useful? What does it do? > + "--enable-usb" > + "--enable-modbus-usb") > + #:tests? #f ; There are no tests. > + #:modules (cons '(ice-9 ftw) %default-gnu-modules) > + #:phases > + #~(modify-phases %standard-phases > + ;; These are not installed, so trick Make into thinking they w= ere > + ;; already generated. Allows us not to depend on mandoc, util= -linux. > + (add-before 'configure 'touch-txt-docs > + (lambda _ > + (for-each (lambda (f) > + (call-with-output-file f close-port)) > + '("doc/apcupsd.man.txt" > + "doc/apcaccess.man.txt" > + "doc/apctest.man.txt" > + "doc/apccontrol.man.txt" > + "doc/apcupsd.conf.man.txt")))) I think I'd rather depend on these than introduce hacks like below. These are only needed as native inputs anyway, right? > + (add-after 'build 'build-manual > + (lambda _ > + (invoke "make" "-C" "doc/manual" "manual.html"))) > + (add-after 'install-license-files 'move-doc > + (lambda _ > + (let ((target (string-append #$output:doc > + "/share/doc/" > + (strip-store-file-name #$outp= ut)))) > + (mkdir-p target) > + (for-each (lambda (f) > + (copy-file (string-append "doc/manual/" f) > + (string-append target "/" f))) > + (scandir "doc/manual" > + (lambda (f) > + (or (string-suffix? ".png" f) > + (string-suffix? ".html" f))))))= )) > + ;; If sending mails is required, use proper mail program. > + (add-after 'install 'remove-smtp > + (lambda _ > + (delete-file (string-append #$output "/sbin/smtp")))) > + ;; The configuration files and scripts are not really suitable= for > + ;; Guix, and our service provides its own version anyway. So = nuke I'd use the more peaceful 'remove' or 'delete' instead of 'nuke'. > + ;; these to make sure `apcupsd' and `apctest' executed without= any > + ;; arguments fail. `apctest' actually segfaults, but only aft= er > + ;; printing an error =C2=AF\_(=E3=83=84)_/=C2=AF. Please don't embed emojis in the source :-). > + (add-after 'install 'remove-etc-apcupsd > + (lambda _ > + (delete-file-recursively (string-append #$output "/etc/apc= upsd"))))))) Break this long line so it fits under 80 columns (our code style guideline). > + (home-page "https://www.apcupsd.org") I'd use 'http', since their TLS cert is now invalid. > + (synopsis "A daemon for controlling APC UPSes") s/A // (as hinted by 'guix lint'). > + (description "Apcupsd can be used for power mangement and controllin= g most s/mangement/management/ > +of APC=E2=80=99s UPS models on Unix and Windows machines. Apcupsd works= with most of > +APC=E2=80=99s Smart-UPS models as well as most simple signalling models = such a Back-UPS, > +and BackUPS-Office.") > + (license license:gpl2))) I think it's actually license:gpl2+, according to apcupsd-3.14.14/COPYING, which says: --8<---------------cut here---------------start------------->8--- Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. --8<---------------cut here---------------end--------------->8--- In this case for most file the last sentence applies, some other explicitly mention 'or any later version'. That's also supported by the debian/copyright file. Another thing found: the doc output doesn't build reproducibly, as shown by: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix build --no-grafts --check -K guix build: error: derivation `/gnu/store/r62j72bd3an8k2fbmaiil5hma32syxdy-= apcupsd-3.14.14.drv' may not be deterministic: output `/gnu/store/bhwkrgkqa= hgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc' differs from `/gnu/store/bhwkr= gkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc-check' --8<---------------cut here---------------end--------------->8--- Let's see why: $ diff -r /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc{,= -check} diff -r /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc/sha= re/doc/apcupsd-3.14.14/manual.html /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj= 390-apcupsd-3.14.14-doc-check/share/doc/apcupsd-3.14.14/manual.html 376c376 <
February 5, 2025 06:54:22
--- >
February 5, 2025 06:54:50
Ah, the classic date time stamp. You'll want to neuter it in the source or in the built html file (with a preference for the former). Could you please send a v2? --=20 Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 05 Feb 2025 07:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173873923422565 (code B ref 75528); Wed, 05 Feb 2025 07:08:02 +0000 Received: (at 75528) by debbugs.gnu.org; 5 Feb 2025 07:07:14 +0000 Received: from localhost ([127.0.0.1]:48119 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tfZVC-0005rt-I0 for submit@debbugs.gnu.org; Wed, 05 Feb 2025 02:07:14 -0500 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]:43482) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tfZVA-0005rf-73 for 75528@debbugs.gnu.org; Wed, 05 Feb 2025 02:07:12 -0500 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2f13acbe29bso855383a91.1 for <75528@debbugs.gnu.org>; Tue, 04 Feb 2025 23:07:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738739225; x=1739344025; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=4WRpCHnweP3s4tNZvxLgBxac8CYc44O51lFCsQ/8USs=; b=FdlZD8Y0RN6sImZ+ceXWJYCWsZ812Rsijq7Nu/8mW2lux+9IwiWIB5XUhDwM7zh6QY hlijDZEf/7pO1ab6ahpBLU6hFrTxC7cprZWlNk9bBvNug+UZ1KXDaJhlB4aDANJK5tS3 2/UF93lzvgmPw6C9oqLw1L8l43aLtTTQtF7WcCYfaEhCPbCpKOdYwkvtCQvMWpZDPjI1 /YFeXl4Q/HBclYE5HJmvKv/vwi0Idw17cSd2/1UfiLJZdKWPdFTY17nDJn+6jkEibAxG inBBT9NpD+30jJ4aethKYfk572F9o/+N3vbP7byVx3d3ZtLlGG0WCaJc13erZXV6IRAp 24gA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738739225; x=1739344025; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=4WRpCHnweP3s4tNZvxLgBxac8CYc44O51lFCsQ/8USs=; b=NDlNEL4B9SUDlMllPbq6bcmQy7HWX88HwFQmmx2x50NrSVW7bboVqr9/774rnjsoD8 o58CX+CASIQcwtNDDqDReJK5gZeURdf2wEDw4MYayZ1WE13Z84i5+2HNMDZFF1VfhHvS tVxVroWjemiPYciBMY5vf5waBf9D5HfdNh2RKCXElXtgZ6eIVayh2QFTtsn0l8+mPnYL JuB4IImThwe+zhpQRzpDyC7KSZ0Ag3n60hf3t7uYz/kQuSK5jokKG2doKbnCl6qtugxt ASTEwdKtCcWJCE8G+IPoAdHAkIj1BscfdSB2vtSw1fCgcEzKmCfSJEULrjOX23kkQlpy WJsg== X-Gm-Message-State: AOJu0Yzb0ba9AXygIxUdiEQRforBGVHIkaC6ujkeqchebGJarc2z8HtG 5iDlu7ABKzkQ8U8lmwGARkXcDAoFq1dkX2ug1yExTLkkGNx4T8VK7Fd5qg== X-Gm-Gg: ASbGncsIUiQ8KG/5pTAUaLpPLy24MLVrGj3PAovNmH5y9XqIlYqfiJHif/z8LyN7GZ+ YtU18OcKHY0/o/T50Y3y5kkAlX/PkD6Bk2VxWjPa+ZdUITCMh9UbGGyGWsrVfYzOdfhp09bgJz2 MjQy5clFDEx0SDrnJAbYXc3WyimrzTNuZjQPUhuIeszPooXup8vTCdXn7fKE9tpDnmr/m+xZIZx W/pXX2314b+vY92h6+dtIeZJnOC9esKRILjYqtnNaRS5WqxGM7xht/w3Tqe6xqyG0whpbMYGMDl vnc3ZuOg4VK+ X-Google-Smtp-Source: AGHT+IHdsmMGNzHN38iZdCv9j+/ldmH7jtFquh1KOpwfwkEtg3rD+bsH2Abj8f7rhMXlZmuX3lv4gQ== X-Received: by 2002:a05:6a00:3910:b0:728:15fd:dabb with SMTP id d2e1a72fcca58-73035203d66mr3107001b3a.8.1738739225214; Tue, 04 Feb 2025 23:07:05 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72fe69ba3c1sm12119919b3a.108.2025.02.04.23.07.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Feb 2025 23:07:04 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> (Tomas Volf's message of "Mon, 13 Jan 2025 00:05:13 +0100") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> Date: Wed, 05 Feb 2025 16:06:53 +0900 Message-ID: <87frks98fm.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, Tomas Volf <~@wolfsden.cz> writes: > --- /dev/null > +++ b/gnu/packages/power.scm > @@ -0,0 +1,125 @@ > +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> > +;;; Copyright (C) 2023 Raven Hallsby One last thing; I don't see Raven listed in a 'Co-authored-by:' git trailer in the commit message; should they? Or otherwise mention plainly this work was based on their previous work, made available '$where'. -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 05 Feb 2025 13:40:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173876279910706 (code B ref 75528); Wed, 05 Feb 2025 13:40:01 +0000 Received: (at 75528) by debbugs.gnu.org; 5 Feb 2025 13:39:59 +0000 Received: from localhost ([127.0.0.1]:49102 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tffdF-0002ma-B7 for submit@debbugs.gnu.org; Wed, 05 Feb 2025 08:39:59 -0500 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:57478) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tffdA-0002mI-QL for 75528@debbugs.gnu.org; Wed, 05 Feb 2025 08:39:55 -0500 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-21f0c4275a1so24584355ad.2 for <75528@debbugs.gnu.org>; Wed, 05 Feb 2025 05:39:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738762787; x=1739367587; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wGY7zRM8YeYVCVekFP9pHGwJV2AqBBWw08p9Hecat5U=; b=TSNqvDDkOwIzCtUYx+PJZQuXHsgXqCZL9G7gBZNXLAhyPbuxoMvdZ2mVeoDqtKLWlw kCZnxdtlyRPlliY83xk1s5lemPCxOpIGqarZu9tSIl0oUNT6acHVL1BA1T5E5NDnRHNY UTQgem0wjDo0IWRtb5pQ6skF4Uu0rwdddwpwbHc+vPOb0KQ7nqBQv95tlnxOjDwroJKa kFEnhLJ3DTNVW9n7EjwenlN0F1tGfSduDz5asb8SOrivPu51cSj55Ue9SzoouP0pPeGI PpQUSXPz/+9LVgkMl85jhWYYIFaHG9ZBYdtTn8VDfYdXkBTjy5AgeUpjnHO7dYWj+wHZ LKyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738762787; x=1739367587; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=wGY7zRM8YeYVCVekFP9pHGwJV2AqBBWw08p9Hecat5U=; b=eTp5WBXJPjosyk2dZ3EcuIhCPTOjFptouxH0kpXhG2Z+RXcnqKaKK9I4Qs2y0R6oFW 6eqYhw6QaS/WK2olKh2h3T2t+tXzjKOjXCYFfaOx0fs+Muu8SOtDHoIWJnHH+gsq89xG 6eE3WOWsXqUBrv6er9D+BXXF6/30YIYiSJcX355s/2RKHpoZ9G1PfDH9Ra+BInC8ATH2 sg1Z75mE5TnTYjViRFq3Q6N5fjzrUJjH+G92RNV5GaYFnSc3qHrTUFhjLlGJr548Od3G wFeOv/7uWX254/qJm7fn1vpNNeDpJHFXbMIqZyple+Skfmi+sip23MBlJwuJN4Of/6JN Y3xg== X-Gm-Message-State: AOJu0YzXhRQas139yHw6hpigTmmdWH+XkTSn3vKfe01isNcpWbsoUCvq jER8llODqPSi3dyTUvT5Eafqs472XfuNkrsLnOk3utVtIK1rwJy1 X-Gm-Gg: ASbGncslRDG6yPlknB+C1vE+qrVh3Nne62NnOhq20FOu+M+d2c/p1M/CqF2ZtbNndw9 L0+sVJPai996pmmd1x1/2BCFKpe8RBpXzvXpJrK04ZX/Z6nfM/2hJtWTXXNi6bCbc/5n8RxtHwV TIqqWvp/DRkgHa2rS2KZfeXpDP/nYOYc6mSfDyXCAwgbyIVT6vWPDcY2FyeZkgb7cJqpH54A4tJ jrC1YN6bS8zSVmW9mY1sHXdbG1kRZYgn2357dFz/FLsrnpZBA1d0aoEgzvktjU4PdEVkMlH9JwU UQFN0MzNHG3o X-Google-Smtp-Source: AGHT+IEbXkoEOEZebiZnVHR7r9/IfftY56gD6ggMREb22LCirh1wndj1C+PjLexwcqAwTKT8IEgIbA== X-Received: by 2002:a17:902:e891:b0:21f:7bd:5801 with SMTP id d9443c01a7336-21f17e2cb28mr42397445ad.6.1738762786038; Wed, 05 Feb 2025 05:39:46 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21f13a991fbsm17734455ad.135.2025.02.05.05.39.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Feb 2025 05:39:45 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> (Tomas Volf's message of "Mon, 13 Jan 2025 00:05:14 +0100") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> Date: Wed, 05 Feb 2025 22:39:33 +0900 Message-ID: <878qqk8q96.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 2.0 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Hi Tomas, Tomas Volf writes: > * gnu/services/power.scm: New file. Content analysis details: (2.0 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (maxim.cournoyer[at]gmail.com) 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:62c listed in] [list.dnswl.org] 2.0 URI_DOTEDU Has .edu URI X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: > * gnu/services/power.scm: New file. I see there's already a gnu/services/pm.scm file; it seems we don't need another one? Or was it a conscious decision? [...] > +The @code{(gnu services power)} module provides a service definition for > +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with APC > +UPSes. Apcupsd also works with some OEM-branded products manufactured > +by APC. I'd introduce a few @acronym here to help readers, e.g. for OEM and UPS. > +@defvar apcupsd-service-type > +The service type for apcupsd. For USB UPSes no configuration is > +necessary, however tweaking some fields to better suit your needs might > +be desirable. The defaults are taken from the upstream configuration > +and they are not very conservative (@code{battery-level} of 5% is too > +low in my opinion). I'd say, (for example, the default @code{battery-level} of 5% may be considered too low by some), to keep it neutral. > +The default event handlers do send emails, read more in > +@ref{apcupsd-event-handlers}. > + > +@lisp > +(service apcupsd-service-type) > +@end lisp > +@end defvar > + > +@deftp {Data Type} apcupsd-configuration > + > +Available @code{apcupsd-configuration} fields are: > + > +@table @asis > +@item @code{package} (default: @code{apcupsd}) (type: package) > +Package to use. That's more conventionally named with the same of the package, e.g. 'acpupsd', not 'package'. I'd word the description as 'The @code{apcupsd} package to use'. > +@item @code{shepherd-base-name} (default: @code{apcupsd}) (type: symbol) > +Base name of the shepherd service. You can add the service multiple > +times with different prefix to manage multiple UPSes. s/prefix/prefixes/ aaa > + > +@item @code{auto-start?} (default: @code{#t}) (type: boolean) > +Should the shepherd service auto-start? > + > +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: st= ring) > +Path to the pid file. All file names becoming /run/ prefixed instead of /var/run, based on a previous comment. We don't use path in GNU to denote file names, we use 'file names'. That's mentioned in info '(standards) GNU Manuals': Please do not use the term "pathname" that is used in Unix documentation; use "file name" (two words) instead. We use the term "path" only for search paths, which are lists of directory names. > + > +@item @code{debug-level} (default: @code{0}) (type: integer) > +Logging verbosity. Bigger number means more logs. In the source code I > +saw up to @code{300}, so for all logs, @code{999} seems reasonable. I think it's best to not use first person pronoun in the manual to keep it a bit more formal. So instead of 'I saw', this could be reworded to: 'The source code uses up to @code{300} as debug level value, so a value of @code{999} seems reasonable to enable all logs.' or similar. > + > +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) > +Directory containing runtime information. You need to change this if > +you desire to run multiple instances of the daemon. > + > +@item @code{name} (type: maybe-string) > +Use this to give your UPS a name in log files and such. This is > +particularly useful if you have multiple UPSes. This does not set the > +EEPROM. It should be 8 characters or less. > + > +@item @code{cable} (default: @code{usb}) (type: enum-cable) > +The type of cable connecting the UPS to your computer. Possible generic > +choices are @code{'simple}, @code{'smart}, @code{'ether} and > +@code{'usb}. Or a specific cable model number may be used: nitpick: I'd reword to 'Alternatively, a specific [...]', which reads better to me. [...] > +@item usb > +A null string setting enables autodetection, which is the best choice > +for most installations. nitpick: My dictionary (aspell) prefers auto-detection. [...] > +@anchor{apcupsd-event-handlers} > +@deftp {Data Type} apcupsd-event-handlers > + > +For description of the events please refer to the @command{apcupsd}'s > +manual, which can be found in the @samp{apcupsd-doc} package. I think you also meant it is in the @samp{doc} output, not in a different package, right? In any case, I'd refer them to the man page of apccontrol, which details the events. Also, to avoid the odd rendering as "the =E2=80=98apcupsd=E2=80=99=E2=80=99s manual" in info, I'd = instead rephrase to: For a description of the events please refer to @samp{man 8 apccontrol}. > + > +Each handler shall be a gexp. It is spliced into the control script for > +the daemon. In addition to the standard Guile programming environment, > +these procedures and variables are also available. s/these/the following/ [...] s/available./available:/ Since these are spliced in the control script and thus not at the top level, users won't be able to import Guile modules they may want to use, so it seems there should be a field to define which Guile modules should be imported and used by default in the configuration. > + > +@table @code > +@item conf > +Variable containing path to the configuration file. s/path/file name/, anywhere this appears. > + > +@item powerfail-file > +Variable containing path to the powerfail file. Ditto. > +@item cmd > +The event currently being handled. > + > +@item name > +The name of the UPS as specified in the configuration file. > + > +@item connected > +Is @code{"1"} if apcupsd is connected to the UPS via a serial port (or a @command{apcupsd} Also, any reason why these integer values are expressed as strings? > +USB port). In most configurations, this will be the case. In the case > +of a Slave machine where apcupsd is not directly connected to the UPS, s/Slave/slave/ ? Could be nicer to use a neutral alternative like 'follower machine'. > +this value will be @code{"0"}. > + > +@item powered > +Is @code{"1"} if the computer on which @command{apcupsd} is running is > +powered by the UPS and @code{"0"} if not. At the moment, this value is > +unimplemented and always @code{"0"}. > + > +@item (err @var{fmt} @var{args...}) > +Wrapper around @code{format} outputting to @code{(current-error-port)}. > + > +@item (wall @var{fmt} @var{args...}) > +Wrapper around @code{format} outputting via @command{wall}. > + > +@item (apcupsd @var{args...}) > +Call @command{apcupsd} while passing the correct configuration file and > +all the arguments. > + > +@item (mail-to-root @var{subject} @var{body}) > +Send an email to the local administrator. This procedure assumes the > +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} > +(as would be the case with @code{opensmtpd-service-type}). > + > +@end table > + > +Available @code{apcupsd-event-handlers} fields are: > + > +@table @asis > +@item @code{killpower} (type: gexp) > +Handler for killpower event. > + > +@item @code{commfailure} (type: gexp) > +Handler for commfailure event. > + > +@item @code{commok} (type: gexp) > +Handler for commfailure event. > + > +@item @code{powerout} (type: gexp) > +Handler for powerout event. > + > +@item @code{onbattery} (type: gexp) > +Handler for onbattery event. > + > +@item @code{offbattery} (type: gexp) > +Handler for offbattery event. > + > +@item @code{mainsback} (type: gexp) > +Handler for mainsback event. > + > +@item @code{failing} (type: gexp) > +Handler for failing event. > + > +@item @code{timeout} (type: gexp) > +Handler for timeout event. > + > +@item @code{loadlimit} (type: gexp) > +Handler for loadlimit event. > + > +@item @code{runlimit} (type: gexp) > +Handler for runlimit event. > + > +@item @code{doreboot} (type: gexp) > +Handler for doreboot event. > + > +@item @code{doshutdown} (type: gexp) > +Handler for doshutdown event. > + > +@item @code{annoyme} (type: gexp) > +Handler for annoyme event. > + > +@item @code{emergency} (type: gexp) > +Handler for emergency event. > + > +@item @code{changeme} (type: gexp) > +Handler for changeme event. > + > +@item @code{remotedown} (type: gexp) > +Handler for remotedown event. > + > +@item @code{startselftest} (type: gexp) > +Handler for startselftest event. > + > +@item @code{endselftest} (type: gexp) > +Handler for endselftest event. > + > +@item @code{battdetach} (type: gexp) > +Handler for battdetach event. > + > +@item @code{battattach} (type: gexp) > +Handler for battattach event. > + > +@end table > + > +@end deftp nitpick: I'd remove the newline between the two @end above (I know, it gets generated this way...). [...] > +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> We use the unicode symbol (=C2=A9) for copyright throughout Guix; please use it too, for uniformity. > + > +;;;; Commentary: > + > +;;; Power-related services. > + > +;;;; Code: > + > +(define-module (gnu services power) > + #:use-module (srfi srfi-1) > + #:use-module (srfi srfi-26) > + #:use-module (ice-9 match) > + #:use-module (gnu) > + #:use-module (gnu packages admin) > + #:use-module (gnu packages linux) > + #:use-module (gnu packages power) > + #:use-module (gnu services) > + #:use-module (gnu services configuration) > + #:use-module (gnu services shepherd) > + #:use-module (guix packages) > + #:use-module (guix records) Please order lexicographically (that is, alphabetically but on things which are not necessarily words :-)). > + #:export (apcupsd-service-type > + > + apcupsd-configuration > + apcupsd-configuration-package > + apcupsd-configuration-shepherd-base-name > + apcupsd-configuration-auto-start? > + apcupsd-configuration-pid-file > + apcupsd-configuration-debug-level > + apcupsd-configuration-run-dir > + apcupsd-configuration-name > + apcupsd-configuration-cable > + apcupsd-configuration-type > + apcupsd-configuration-device > + apcupsd-configuration-poll-time > + apcupsd-configuration-on-batery-delay > + apcupsd-configuration-battery-level > + apcupsd-configuration-remaining-minutes > + apcupsd-configuration-timeout > + apcupsd-configuration-annoy-interval > + apcupsd-configuration-annoy-delay > + apcupsd-configuration-no-logon > + apcupsd-configuration-kill-delay > + apcupsd-configuration-net-server > + apcupsd-configuration-net-server-ip > + apcupsd-configuration-net-server-port > + apcupsd-configuration-net-server-events-file > + apcupsd-configuration-net-server-events-file-max-size > + apcupsd-configuration-class > + apcupsd-configuration-mode > + apcupsd-configuration-stat-time > + apcupsd-configuration-log-stats > + apcupsd-configuration-data-time > + apcupsd-configuration-facility > + apcupsd-configuration-event-handlers > + > + apcupsd-event-handlers-annoyme > + apcupsd-event-handlers-battattach > + apcupsd-event-handlers-battdetach > + apcupsd-event-handlers-changeme > + apcupsd-event-handlers-commfailure > + apcupsd-event-handlers-commok > + apcupsd-event-handlers-doreboot > + apcupsd-event-handlers-doshutdown > + apcupsd-event-handlers-emergency > + apcupsd-event-handlers-endselftest > + apcupsd-event-handlers-failing > + apcupsd-event-handlers-killpower > + apcupsd-event-handlers-loadlimit > + apcupsd-event-handlers-mainsback > + apcupsd-event-handlers-offbattery > + apcupsd-event-handlers-onbattery > + apcupsd-event-handlers-powerout > + apcupsd-event-handlers-remotedown > + apcupsd-event-handlers-runlimit > + apcupsd-event-handlers-startselftest > + apcupsd-event-handlers-timeout)) > + > +(define-configuration/no-serialization apcupsd-event-handlers > + (killpower > + (gexp > + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) > + (sleep 10) > + (apcupsd "--killpower") > + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) > + "Handler for killpower event.") In many places in your writing, I find that it skips adding 'the' (definite article), which I've learned should be use when describing something specific, such as here with the specific handlers: "Handler for the @code{killpower} event." In case it helps, I've found this page seems useful in briefly explaining when to use 'the' [0]. [0] https://owl.purdue.edu/owl/general_writing/grammar/using_articles.html > + (commfailure > + (gexp > + #~((let ((msg (format #f "~a Communications with UPS ~a lost." > + (gethostname) name))) > + (mail-to-root msg msg)) > + (wall "Warning: communications lost with UPS ~a" name))) > + "Handler for commfailure event.") > + (commok > + (gexp > + #~((let ((msg (format #f "~a Communications with UPS ~a restored." > + (gethostname) name))) > + (mail-to-root msg msg)) > + (wall "Communications restored with UPS ~a" name))) > + "Handler for commfailure event.") > + (powerout > + (gexp > + #~(#t)) > + "Handler for powerout event.") > + (onbattery > + (gexp > + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" > + (gethostname) name))) > + (mail-to-root msg msg)) > + (wall "Power failure on UPS ~a. Running on batteries." name))) > + "Handler for onbattery event.") > + (offbattery > + (gexp > + #~((let ((msg (format #f "~a UPS ~a Power has returned." > + (gethostname) name))) > + (mail-to-root msg msg)) > + (wall "Power has returned on UPS ~a..." name))) > + "Handler for offbattery event.") > + (mainsback > + (gexp > + #~((when (file-exists? powerfail-file) > + (wall "Continuing with shutdown.")))) > + "Handler for mainsback event.") > + (failing > + (gexp > + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name)= )) > + "Handler for failing event.") > + (timeout > + (gexp > + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." n= ame))) > + "Handler for timeout event.") > + (loadlimit > + (gexp > + #~((wall "Remaining battery charge below limit on UPS ~a. Doing shu= tdown." name))) > + "Handler for loadlimit event.") > + (runlimit > + (gexp > + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing sh= utdown." name))) > + "Handler for runlimit event.") > + (doreboot > + (gexp > + #~((wall "UPS ~a initiating Reboot Sequence" name) > + (system* #$(file-append shepherd "/sbin/reboot")))) > + "Handler for doreboot event.") > + (doshutdown > + (gexp > + #~((wall "UPS ~a initiated Shutdown Sequence" name) > + (system* #$(file-append shepherd "/sbin/halt")))) > + "Handler for doshutdown event.") > + (annoyme > + (gexp > + #~((wall "Power problems with UPS ~a. Please logoff." name))) > + "Handler for annoyme event.") > + (emergency > + (gexp > + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a." = name))) > + "Handler for emergency event.") > + (changeme > + (gexp > + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." > + (gethostname) name))) > + (mail-to-root msg msg)) > + (wall "Emergency! Batteries have failed on UPS ~a. Change them = NOW." name))) > + "Handler for changeme event.") > + (remotedown > + (gexp > + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) > + "Handler for remotedown event.") > + (startselftest > + (gexp > + #~(#t)) > + "Handler for startselftest event.") > + (endselftest > + (gexp > + #~(#t)) > + "Handler for endselftest event.") > + (battdetach > + (gexp > + #~(#t)) > + "Handler for battdetach event.") > + (battattach > + (gexp > + #~(#t)) > + "Handler for battattach event.")) Sounds fun :-). I was wondering if the handlers could be of the maybe-gexp type, and when not provided the handler would not be called at all? Or does the design of apcupsd mandates that all handlers be defined? > +(define-syntax define-enum > + (lambda (x) > + (syntax-case x () > + ((_ name values) > + (let* ((d/n (syntax->datum #'name)) > + (d/predicate (string->symbol > + (format #f "enum-~a?" d/n))) > + (d/serialize (string->symbol > + (format #f "serialize-enum-~a" d/n)))) Even for internal bindings, better variable names would help reading the code. > + (with-syntax > + ((predicate (datum->syntax x d/predicate)) > + (serialize (datum->syntax x d/serialize))) > + #'(begin > + (define (predicate value) > + (memq value values)) > + (define serialize serialize-symbol)))))))) That is a nice minimal enum for using with define-configuration. Note that Guile has some kind of very limited enum from (rnrs enums), but I don't think they'd be too useful here. See for example 'make-enumeration' from (rnrs enums), which I used in for the ntp-server-types in (gnu services networking). > +(define mangle-field-name > + (match-lambda > + ('name "UPSNAME") > + ('cable "UPSCABLE") > + ('type "UPSTYPE") > + ('device "DEVICE") > + ('poll-time "POLLTIME") > + ('lock-dir "LOCKFILE") > + ('power-fail-dir "PWRFAILDIR") > + ('no-login-dir "NOLOGINDIR") > + ('on-batery-delay "ONBATTERYDELAY") > + ('battery-level "BATTERYLEVEL") > + ('remaining-minutes "MINUTES") > + ('timeout "TIMEOUT") > + ('annoy-interval "ANNOY") > + ('annoy-delay "ANNOYDELAY") > + ('no-logon "NOLOGON") > + ('kill-delay "KILLDELAY") > + ('net-server "NETSERVER") > + ('net-server-ip "NISIP") > + ('net-server-port "NISPORT") > + ('net-server-events-file "EVENTSFILE") > + ('net-server-events-file-max-size "EVENTSFILEMAX") > + ('class "UPSCLASS") > + ('mode "UPSMODE") > + ('stat-time "STATTIME") > + ('stat-file "STATFILE") > + ('log-stats "LOGSTATS") > + ('data-time "DATATIME") > + ('facility "FACILITY"))) > + > +(define (serialize-string field-name value) > + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) > +(define serialize-symbol serialize-string) > +(define serialize-integer serialize-string) > +(define (serialize-boolean field-name value) > + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) #$(if value "o= n" "off"))) You'll want to break the above line. > + > +(define-maybe string) > + > +(define-enum cable '( simple smart ether usb > + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C > + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G > + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-= 2000)) > +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test= )) > +(define-enum no-logon '(disable timeout percent minutes always)) > +(define-enum class '(standalone shareslave sharemaster)) > +(define-enum mode '(disable share)) > + > +(define-configuration apcupsd-configuration > + (package (package apcupsd) "Package to use.") Please stick to the convention where the name of the package is the name of the field used to specify such package (here: apcupsd). > + (shepherd-base-name > + (symbol 'apcupsd) > + "Base name of the shepherd service. You can add the service multiple= times > +with different prefix to manage multiple UPSes." > + empty-serializer) > + (auto-start? > + (boolean #t) > + "Should the shepherd service auto-start?" > + empty-serializer) > + (pid-file > + (string "/var/run/apcupsd.pid") /var/run -> /run (adjust everywhere) > + "Path to the pid file." I'm repeating myself because I reviewed the texi produced from this, but yeah, s/path/file name/, and make sure to adjust the rest of the comments I made for the .texi in the source (I'd just edit the source and regenerate the doc from it). [...] > +(define (s/apccontrol cfg) what is the 's/' prefix for in the procedure name? 'serialize'? Spell this out in full to be clear rather than cryptic (that's a convention followed at large in general in Scheme). > + (program-file > + "apccontrol" > + #~(begin > + (use-modules (srfi srfi-9) > + (ice-9 format) > + (ice-9 match) > + (ice-9 popen)) Please sort modules lexicographically. > + ;; Script dir depends on these, and the configuration depends on = the script > + ;; dir. To sever the cyclic dependency, pass the paths via envir= onment > + ;; variables. > + (define conf (getenv "GUIX_APCUPSD_CONF")) > + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) > + > + (define (err . args) > + (apply format (current-error-port) args)) > + (define (wall . args) > + (system* #$(file-append util-linux "/bin/wall") (apply format #= f args))) > + (define (apcupsd . args) > + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" con= f args)) > + (define (mail-to-root subject body) > + (let ((port (open-pipe* OPEN_WRITE > + "/run/privileged/bin/sendmail" > + "-F" "apcupsd" > + "root"))) > + (format port "Subject: ~a~%~%~a~&" subject body) > + (close-pipe port))) > + (match (cdr (command-line)) > + (((? string? cmd) name connected powered) > + (match cmd > + ;; I am sure this could be done by macro, but meh. Last rel= ease of > + ;; apcupsd was in 2016, so maintaining this will not be much= work. > + ("killpower" > + #$@(apcupsd-event-handlers-killpower > + (apcupsd-configuration-event-handlers cfg))) > + ("commfailure" > + #$@(apcupsd-event-handlers-commfailure > + (apcupsd-configuration-event-handlers cfg))) > + ("commok" > + #$@(apcupsd-event-handlers-commok > + (apcupsd-configuration-event-handlers cfg))) > + ("powerout" > + #$@(apcupsd-event-handlers-powerout > + (apcupsd-configuration-event-handlers cfg))) > + ("onbattery" > + #$@(apcupsd-event-handlers-onbattery > + (apcupsd-configuration-event-handlers cfg))) > + ("offbattery" > + #$@(apcupsd-event-handlers-offbattery > + (apcupsd-configuration-event-handlers cfg))) > + ("mainsback" > + #$@(apcupsd-event-handlers-mainsback > + (apcupsd-configuration-event-handlers cfg))) > + ("failing" > + #$@(apcupsd-event-handlers-failing > + (apcupsd-configuration-event-handlers cfg))) > + ("timeout" > + #$@(apcupsd-event-handlers-timeout > + (apcupsd-configuration-event-handlers cfg))) > + ("loadlimit" > + #$@(apcupsd-event-handlers-loadlimit > + (apcupsd-configuration-event-handlers cfg))) > + ("runlimit" > + #$@(apcupsd-event-handlers-runlimit > + (apcupsd-configuration-event-handlers cfg))) > + ("doreboot" > + #$@(apcupsd-event-handlers-doreboot > + (apcupsd-configuration-event-handlers cfg))) > + ("doshutdown" > + #$@(apcupsd-event-handlers-doshutdown > + (apcupsd-configuration-event-handlers cfg))) > + ("annoyme" > + #$@(apcupsd-event-handlers-annoyme > + (apcupsd-configuration-event-handlers cfg))) > + ("emergency" > + #$@(apcupsd-event-handlers-emergency > + (apcupsd-configuration-event-handlers cfg))) > + ("changeme" > + #$@(apcupsd-event-handlers-changeme > + (apcupsd-configuration-event-handlers cfg))) > + ("remotedown" > + #$@(apcupsd-event-handlers-remotedown > + (apcupsd-configuration-event-handlers cfg))) > + ("startselftest" > + #$@(apcupsd-event-handlers-startselftest > + (apcupsd-configuration-event-handlers cfg))) > + ("endselftest" > + #$@(apcupsd-event-handlers-endselftest > + (apcupsd-configuration-event-handlers cfg))) > + ("battdetach" > + #$@(apcupsd-event-handlers-battdetach > + (apcupsd-configuration-event-handlers cfg))) > + ("battattach" > + #$@(apcupsd-event-handlers-battattach > + (apcupsd-configuration-event-handlers cfg))) > + (_ > + (err "Unknown event: ~a~%" cmd) > + (err "Iff the event was passed by apcupsd, this is a bug.~%= ") s/Iff/If/, perhaps s/passed/emitted/. I don't understand, in which scenario would an event *not* be emitted by apcupsd? > + (err "Please report to bug-guix@gnu.org.~%") > + (exit #f)))) > + (args > + (err "Unknown arguments: ~a~%" args) > + (err "Iff the arguments were passed by apcupsd, this is a bug.= ~%") s/Iff/If/ > + (err "Please report to bug-guix@gnu.org.~%") > + (exit #f)))))) > + > +(define (apcupsd-script-dir cfg) s/cfg/config/ > + (computed-file > + "apcupsd-script-dir" > + #~(begin > + (mkdir #$output) > + (chdir #$output) > + (symlink #$(s/apccontrol cfg) "apccontrol")))) > + > +(define (apcupsd-config-file cfg) s/cfg/config/ > + (let ((run-dir (apcupsd-configuration-run-dir cfg))) > + (mixed-text-file > + "apcupsd.conf" > + "\ > +## apcupsd.conf v1.1 ## > +# > +# for apcupsd release 3.14.14 (31 May 2016) - GNU Guix Is this config really bound to a version like above? Unless they change things in backward incompatible ways, it should work for newer ones too, no? > +# > +# \"apcupsd\" POSIX config file (crafted via apcupsd-service-type) s/crafted via/auto-generated by/ > +" > + (serialize-configuration cfg apcupsd-configuration-fields) > + ;; This one is confusing. The manual page states: > + ;; > + ;; > It must be changed when running more than one copy of apcupsd = on the > + ;; > same computer to control multiple UPSes. > + ;; > + ;; However would you not want the lock to be per-device, not per-pr= ocess? > + ;; I decided to follow the documentation, but I do not understand w= hy it > + ;; should be like this. I do not have multiple UPSes to try. > + (serialize-string 'lock-dir (string-append run-dir "/lock")) > + (serialize-string 'power-fail-dir run-dir) > + (serialize-string 'no-login-dir run-dir) > + (serialize-string 'stat-file (string-append run-dir "/apcupsd.statu= s")) > + "SCRIPTDIR " (apcupsd-script-dir cfg) "\n"))) > + > +(define (apcupsd-shepherd-services cfg) s/cfg/config/ > + (match-record cfg > + ( package pid-file debug-level run-dir ^ extraneous space =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 > + shepherd-base-name auto-start?) > + (let* ((config-file (apcupsd-config-file cfg)) > + (s/ shepherd-base-name) Please improve the variables names a bit; what is 's/' ? > + (s/run-dirs (string->symbol (format #f "~a-run-dirs" s/)))) > + (list > + (shepherd-service > + (documentation "Create the run directories.") > + (provision (list s/run-dirs)) > + (one-shot? #t) > + (auto-start? auto-start?) > + (start #~(lambda _ > + ((@ (guix build utils) mkdir-p) > + #$(string-append run-dir "/lock")) > + #t))) Is there a reason why this is not done in an activation script instead? That's more conventional, I think. > + (shepherd-service > + (documentation "Run apcupsd daemon.") Run *the* apcupsd daemon. > + (requirement (list s/run-dirs)) > + (provision (list s/)) > + (auto-start? auto-start?) > + (start #~(make-forkexec-constructor > + '(#$(file-append package "/sbin/apcupsd") > + "-b" ; Do not daemonize. If you want, margin comments are ok without space or full sentence (punctuation), e.g.: --8<---------------cut here---------------start------------->8--- ;do not daemonize --8<---------------cut here---------------end--------------->8--- =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 > + "-f" #$config-file > + "-P" #$pid-file > + "-d" #$(number->string debug-level)) > + #:log-file > + #$(format #f "/var/log/~a.log" shepherd-base-name) > + #:environment-variables > + (cons* (string-append "GUIX_APCUPSD_CONF=3D" > + #$config-file) > + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE= =3D" > + run-dir "/powerfail") > + (default-environment-variables)))) > + (stop #~(make-kill-destructor)) > + (actions (list (shepherd-configuration-action config-file)))))))) > + > +(define (apcupsd-pam-extensions cfg) s/cfg/config/ > + (define pam-nologin A comment explaining why this PAM extention is required would be helpful (I have no idea myself -- but I must confess: PAM is still a bit of a mystery to me). > + (pam-entry > + (control "required") > + (module "pam_nologin.so") > + (arguments (list (string-append "file=3D" > + (apcupsd-configuration-run-dir cfg) > + "/nologin"))))) > + > + (list (pam-extension > + (transformer > + (lambda (pam) > + (pam-service > + (inherit pam) > + (auth (cons pam-nologin (pam-service-auth pam))))))))) > + > +(define apcupsd-service-type > + (service-type > + (name 'apcupsd) > + (description "Configure and optionally start apcupsd.") > + (extensions (list (service-extension shepherd-root-service-type > + apcupsd-shepherd-services) > + (service-extension pam-root-service-type > + apcupsd-pam-extensions))) > + (compose identity) > + (extend (=CE=BB (cfg lst) nitpick: There was a stylistic choice to prefer lambda instead of =CE=BB in the Guix code base to try to make it more accessible at some point. > + (fold (cut <> <>) cfg lst))) > + (default-value (apcupsd-configuration)))) Thanks for this very complete, carefully and thoughtfully crafted contribution. As you can see, the only comments I had were mostly nitpicks and small details. I look forward to the next revision. --=20 Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 09 Feb 2025 16:12:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173911746218903 (code B ref 75528); Sun, 09 Feb 2025 16:12:02 +0000 Received: (at 75528) by debbugs.gnu.org; 9 Feb 2025 16:11:02 +0000 Received: from localhost ([127.0.0.1]:45924 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1th9td-0004uU-0u for submit@debbugs.gnu.org; Sun, 09 Feb 2025 11:11:02 -0500 Received: from wolfsden.cz ([37.205.8.62]:37850) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1th9tZ-0004uI-1u for 75528@debbugs.gnu.org; Sun, 09 Feb 2025 11:10:58 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id BBD673251F5; Sun, 9 Feb 2025 16:10:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739117454; bh=7rNLQyoGFWV4NZsFfD6Nr6J2im9YGM5IRuSuolrXIZQ=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=YNTLtYWX6WnQdyMQ1saB5NPNG363yyZBBjAKmZONyHcVo6g5232Lo3LLxzztiXu8O uESZNpqM4VwP7wLQp0ZVafespZd3yEFz+Ka+7z7FGy+YqgZqvMsAWiTJ7q7xXLniCP QroOSYzsc+BeWQ83K8ZqGRQV8MbxRNZAnQVc65tKVhuMcugL3vVwmpn12cUfDN5j8t 6wFiLftS4iapkjcC0bW82pQJTA9S+qI/ODWGMv9NSvzlNd+T8vvnmAzciuXxJG17QD OXqnDp5tlDQWErnfQZ9pAXs0HhkG0KNztNVnTRWFvkCl1f/UXWWtDY6tOfmhAamX3O N1cvyt2oAzRTfh4L1QL/y4XkBiVdcPOUdcIAEuNWLg6GpEaJaKPh9Q9ecPYIPrXCPD Lf5MRsDNoRXASnUvjN2fLgLmHBMaGwGfSjhjpQujZeu2xe9BECDkJfZ3d6+vrbhdix PvtgG5Wfw0smMjg79y4HLlkO0JUxX+27u0nZ/VvvTcvBeL69WFp79tsIe7Hfh0/2Xm 64XNNwnZMxlKlY8N19qqMZRMXe2grlFqhxWQ4g13acOi2UM0sNiuPaoiXMJkeCgYr8 aPOSOzxO7wLVv4yHBxLaYSl0H21dYvb92iEud/K6iIV7JH6uyB/v6qYru+d0WtLY/B YyGt2qiRW5LXK3/AIO8eD34Y= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 4C36A326506; Sun, 9 Feb 2025 16:10:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739117452; bh=7rNLQyoGFWV4NZsFfD6Nr6J2im9YGM5IRuSuolrXIZQ=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=ERF5sLn/uxy7DB3yUY3pa1hT2Ll9fHiE6vqgmbAheOa/+UjO9nCWu7jwTscM6MMQG w1ZNaqxTXqVtmb+teGs4DHHl37WkL2sBPvBk4x4ArK99yjJVoRA3B4hrtSOKJqCd5V JRJQHaR/rUD10WWDo+zk5j9v7wuOU1I1kDukLlyn14LlLk+qBerkLsjZk72M6jbOlX Bu8F6znJKOGK27CxxnsRaPODA1nwfpxZXEPsEd9QYZXirwchw/TL7/0SSJ3vjwSewO MqtmlrvpMlmno6W6tIM12iteuom38OHVfv6jkRXBo1Y8SCMQpM6tP5IVw0oNkZgSNS 9bDTeR0C6AGJh5TIbYy0m2prM2lCZi8CBFKq0gRm1/f5IqaXtE5Hej82mv2YV7w7K7 ptDtEv5daZ99SjNN6dmgGUO7c166/ZsS71vTKeul8Y+zt+x+3viI12+/hUiH1st82M RnzItilQlc9QsBZOOI3rFdfYdtNmttmX1L/SPcWkmt29aRFcSA06MgSz+/WoKf0UJ/ IYfwO9+EZJrLOQP/pO6tzW6VLUz4k1TR/lZMgtJT17K+EySQnBqBfiV42xp0rn19HA L0ZhqtrT3hx8LgunViqTlw9D13zSc39ShpioGMT7kKlHSUiE0wN1XY6Wrqc241rZ0t ozShY2XiK1BLss6T7w/6V1HE= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87jza498sp.fsf@gmail.com> (Maxim Cournoyer's message of "Wed, 05 Feb 2025 15:59:02 +0900") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87jza498sp.fsf@gmail.com> Date: Sun, 09 Feb 2025 17:10:51 +0100 Message-ID: <87pljrf69g.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Maxim, thank you for the review, replies below. Maxim Cournoyer writes: > Hi Tomas, > > Tomas Volf <~@wolfsden.cz> writes: > >> * gnu/packages/power.scm (apcupsd): New variable. > > 'guix lint' says: > > gnu/packages/power.scm:120:14: apcupsd@3.14.14: no article allowed at the= beginning of the synopsis > gnu/packages/power.scm:119:15: apcupsd@3.14.14: TLS certificate error: X.= 509 server certificate for 'www.apcupsd.org' does not match: CN=3Dsf.net > > > Please fix these. Both fixed. > >> Change-Id: I74f59cd1fa2a13954117ff1683a10a84576cc839 >> --- >> gnu/local.mk | 1 + >> gnu/packages/power.scm | 125 +++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 126 insertions(+) >> create mode 100644 gnu/packages/power.scm >> >> diff --git a/gnu/local.mk b/gnu/local.mk >> index 855f2acccc..6ca7bf68ac 100644 >> --- a/gnu/local.mk >> +++ b/gnu/local.mk >> @@ -557,6 +557,7 @@ GNU_SYSTEM_MODULES =3D \ >> %D%/packages/polkit.scm \ >> %D%/packages/popt.scm \ >> %D%/packages/potassco.scm \ >> + %D%/packages/power.scm \ > > This change should be mentioned in the change log as well, e.g.: > > * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. > > [...] I used slightly different message, since the previous line mentions "new variable", but the object being registered is whole file. > >> +(define-public apcupsd >> + (package >> + (name "apcupsd") >> + (version "3.14.14") >> + (source (origin >> + (method url-fetch) >> + (uri >> + (string-append >> + "mirror://sourceforge/" name "/" name " - Stable/" vers= ion >> + "/" name "-" version ".tar.gz")) >> + (sha256 >> + (base32 >> + "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv")= ))) >> + (native-inputs >> + (list pkg-config python-docutils)) >> + (inputs >> + (list libusb libusb-compat)) > > nitpick: If there are less than 5 and they fit on the same line, I > prefer to list them on the same line as the field name itself. That's > how 'guix style' does it, although it has a tendency to protrude past > our max column width of 80 guideline in other places (that's > bug#62303). Fair enough. I do not have strong preference, so I have made it into a single line. I have to admit I do not run `guix style' (yes, yes, I know contributing part of the manual mandates it), since the code produced is often subpar compared to the hand-crafted variant. > > Also, we conventionally list the input fields below the arguments field > of a package, although technically it's unimportant. Moved. > >> + (outputs '("out" "doc")) >> + (build-system gnu-build-system) >> + (arguments >> + (list >> + #:configure-flags >> + #~(list >> + ;; The configure script ignores --prefix for most of the paths. > > Well done with the comment. > >> + (string-append "--exec-prefix=3D" #$output) >> + (string-append "--mandir=3D" #$output "/share/man") >> + (string-append "--sbindir=3D" #$output "/sbin") >> + (string-append "--sysconfdir=3D" #$output "/etc/apcupsd") >> + (string-append "--with-halpolicydir=3D" #$output "/share/halpo= licy") >> + >> + ;; Put us into the version string. >> + "--with-distname=3DGNU/Guix" > > The name is 'GNU Guix'. I was afraid of the space. :) But seems to work fine, changed. > >> + "--disable-install-distdir" >> + >> + ;; State directories. >> + "--localstatedir=3D/var" >> + "--with-log-dir=3D/var/log" >> + "--with-pid-dir=3D/var/run" >> + "--with-lock-dir=3D/var/run/apcupsd/lock" >> + "--with-nologin=3D/var/run/apcupsd" >> + "--with-pwrfail-dir=3D/var/run/apcupsd" > > I think /var/run is deprecated in favor of just /run, so we should > configure the package to use this, I think. It seems pretty much all programs on my system are using /var/run, including Shepherd. Only programs that store information in /run seem to be elogind and dbus. Is deprecation of /var/run listed somewhere in the manual? I am surprised Shepherd (since it is actively maintained and core component) is still in /var/run. I looked and found 42 references to /var/run, but none with the deprecation notice. Assuming you will insist on moving it to /run, is there some structure to follow in that directory? Or just s~/var/run~/run~? What about /var and /var/log? Should those be moved somewhere as well? > >> + (string-append "ac_cv_path_SHUTDOWN=3D/nope") >> + (string-append "ac_cv_path_APCUPSD_MAIL=3D/nope") >> + ;; While `wall' is not expanded anywhere, it still is searched= for. >> + (string-append "ac_cv_path_WALL=3D/nope") > > I'm not sure if this package is actively developed, but that last issue > should ideally be reported (then cross-referenced here). I did not found a way to report a bug. Nothing is listed in the manual, and their apcupsd-users mailing list requires JavaScript to sign up (and does not tell me the email address otherwise). I did try to blindly send an email, will see if it will be accepted without being subscribed. If that happens, I will add the link here. > >> + ;; Enable additional drivers. >> + "--enable-test" > > Is '--enable-test' useful? What does it do? According to the manual =2D-8<---------------cut here---------------start------------->8--- This turns on a test driver that is used only for debugging. =2D-8<---------------cut here---------------end--------------->8--- Since there does not seem to be any harm in having it on, I enabled it, since Guix seems to aim for feature complete packages (I assume that is the reason for everything being so large). But I have no use for it, so I can turn it off if you would prefer. > >> + "--enable-usb" >> + "--enable-modbus-usb") >> + #:tests? #f ; There are no tests. >> + #:modules (cons '(ice-9 ftw) %default-gnu-modules) >> + #:phases >> + #~(modify-phases %standard-phases >> + ;; These are not installed, so trick Make into thinking they = were >> + ;; already generated. Allows us not to depend on mandoc, uti= l-linux. >> + (add-before 'configure 'touch-txt-docs >> + (lambda _ >> + (for-each (lambda (f) >> + (call-with-output-file f close-port)) >> + '("doc/apcupsd.man.txt" >> + "doc/apcaccess.man.txt" >> + "doc/apctest.man.txt" >> + "doc/apccontrol.man.txt" >> + "doc/apcupsd.conf.man.txt")))) > > I think I'd rather depend on these than introduce hacks like below. The "hacks" *below* would still be required. The HTML manual is not built nor installed by default, and there is no target to invoke to install them. So both 'build-manual and 'move-doc phases would still be required. We could get rid of the "hack" *above* ('touch-txt-docs), true. It is worth those two additional inputs? > These are only needed as native inputs anyway, right? Yes. > >> + (add-after 'build 'build-manual >> + (lambda _ >> + (invoke "make" "-C" "doc/manual" "manual.html"))) >> + (add-after 'install-license-files 'move-doc >> + (lambda _ >> + (let ((target (string-append #$output:doc >> + "/share/doc/" >> + (strip-store-file-name #$out= put)))) >> + (mkdir-p target) >> + (for-each (lambda (f) >> + (copy-file (string-append "doc/manual/" f) >> + (string-append target "/" f))) >> + (scandir "doc/manual" >> + (lambda (f) >> + (or (string-suffix? ".png" f) >> + (string-suffix? ".html" f)))))= ))) >> + ;; If sending mails is required, use proper mail program. >> + (add-after 'install 'remove-smtp >> + (lambda _ >> + (delete-file (string-append #$output "/sbin/smtp")))) >> + ;; The configuration files and scripts are not really suitabl= e for >> + ;; Guix, and our service provides its own version anyway. So= nuke > > I'd use the more peaceful 'remove' or 'delete' instead of 'nuke'. Uh, sure. Done. > >> + ;; these to make sure `apcupsd' and `apctest' executed withou= t any >> + ;; arguments fail. `apctest' actually segfaults, but only af= ter >> + ;; printing an error =C2=AF\_(=E3=83=84)_/=C2=AF. > > Please don't embed emojis in the source :-). Technically kaomoji (=E9=A1=94=E6=96=87=E5=AD=97), not emoji (=E7=B5=B5=E6= =96=87=E5=AD=97), but point taken. :) > >> + (add-after 'install 'remove-etc-apcupsd >> + (lambda _ >> + (delete-file-recursively (string-append #$output "/etc/ap= cupsd"))))))) > > Break this long line so it fits under 80 columns (our code style > guideline). I thought (well, still do), that going 4 characters over the limit was worth the increase in readability. Nevertheless, I have split it into two lines. > >> + (home-page "https://www.apcupsd.org") > > I'd use 'http', since their TLS cert is now invalid. Done as part of resolving the ling warning. > >> + (synopsis "A daemon for controlling APC UPSes") > > s/A // (as hinted by 'guix lint'). Same. > >> + (description "Apcupsd can be used for power mangement and controlli= ng most > > s/mangement/management/ Nice catch, fixed. > >> +of APC=E2=80=99s UPS models on Unix and Windows machines. Apcupsd work= s with most of >> +APC=E2=80=99s Smart-UPS models as well as most simple signalling models= such a Back-UPS, >> +and BackUPS-Office.") >> + (license license:gpl2))) > > I think it's actually license:gpl2+, according to > apcupsd-3.14.14/COPYING, which says: > > Each version is given a distinguishing version number. If the Program > specifies a version number of this License which applies to it and "any > later version", you have the option of following the terms and conditions > either of that version or of any later version published by the Free > Software Foundation. If the Program does not specify a version number of > this License, you may choose any version ever published by the Free Softw= are > Foundation. > > > In this case for most file the last sentence applies, some other > explicitly mention 'or any later version'. That's also supported by the > debian/copyright file. I do not think this is correct. When I check apcupsd-3.14.14/src/apcupsd.c file, I see this in its header: =2D-8<---------------cut here---------------start------------->8--- * Copyright (C) 1999-2005 Kern Sibbald * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General * Public License as published by the Free Software Foundation. * * This program 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 this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1335, USA. =2D-8<---------------cut here---------------end--------------->8--- There is no mention of "any later version". Does that not make the combined work GPL-2.0-only, even if other files would be under GPL-2.0-or-later (I did no check whether they are)? I did not find debian/copyright file in the source code. > > Another thing found: the doc output doesn't build reproducibly, as > shown by: > > $ ./pre-inst-env guix build --no-grafts --check -K > guix build: error: derivation `/gnu/store/r62j72bd3an8k2fbmaiil5hma32syxd= y-apcupsd-3.14.14.drv' may not be deterministic: output `/gnu/store/bhwkrgk= qahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc' differs from `/gnu/store/bhw= krgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc-check' > > Let's see why: > > $ diff -r /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc= {,-check} This is great, I did not know that it names the store item -check. Very useful, thank you. > diff -r > /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc/share/doc= /apcupsd-3.14.14/manual.html > /gnu/store/bhwkrgkqahgs5h8crcfyacvnwp7rj390-apcupsd-3.14.14-doc-check/sha= re/doc/apcupsd-3.14.14/manual.html > 376c376 > <
February 5, 2025 06:54:22
> --- >>
February 5, 2025 06:54:50
> > Ah, the classic date time stamp. You'll want to neuter it in the source > or in the built html file (with a preference for the former). Nice find, I have missed this. I have patched the source code of the manual to not embed the date and time, seems to work now. > > Could you please send a v2? Definitely, I will go through your review for the service file as well, and once I have all the answers (both here and there), will send v2. Once more thanks for the review, Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmeo04sOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wakexA/9FXapBD7LTzTio9FuXl/LZfl0plqmid/KZEtn vGP4MBKSCb/IpQaYi1XQuXQEtBzoLMDprJraelLfMVck5I5v0Sqfsi5pZSSUHcHr ZzN2/flboVWyaol/Wee5zTFJUcAM8H2Pc61lNemwR8360Gm0qLIWXgIEiVw/k2I+ ViBbPXDo8zJJjTYT6L2GMFwVu2Rn6Ww9khd4U1mUy0IXxcu7rVgzoAJsA3He7Q1f TY7Sx4j5ggVZFcoTAc6VIYxRDHb78eiTCTObbPnSCODE2cCsmrLvuoW7qy+GhMKP ZkU/SLKoxx+H7xQ0Wp6QKPshUsAj8mKkK5LWtq0uT6LuLsY06HxxEihIynNSvwjc 8KA+zW7RzUqSEfne4V3xi6YXpyR396A7QmkT44Vy5Knd1zKaK2TMtJw38gYzVR/Y ACLmO0MylPthoHQgyKsdWBQT4Ynmstetw5jAbLGgqvxMhW9Otwhzo4auSbX0+qXI +EeXCQN8IzEIFWUFcKDm/+QqHyPtTDMcg/FjjYlbH16bJQzT0YX2pWWUt7xuyLlD FtSsvw80F4mdCaN0upKWRasFoqLarqmwGc+TRfEBZST4CBQBOZ8g5WsI+0/dZuAV FpJ2wcmoUhNkzeFA3uSUfsNCNsIEE9SjhIgI+IB8HaBtWv7l+4uumMyt3DOw/fPf OZSCClI= =ft5W -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 09 Feb 2025 16:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173911838721684 (code B ref 75528); Sun, 09 Feb 2025 16:27:01 +0000 Received: (at 75528) by debbugs.gnu.org; 9 Feb 2025 16:26:27 +0000 Received: from localhost ([127.0.0.1]:45951 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1thA8Z-0005df-Dk for submit@debbugs.gnu.org; Sun, 09 Feb 2025 11:26:27 -0500 Received: from wolfsden.cz ([37.205.8.62]:33404) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1thA8V-0005dP-Ej for 75528@debbugs.gnu.org; Sun, 09 Feb 2025 11:26:25 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 5893932594C; Sun, 9 Feb 2025 16:26:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739118381; bh=LKccF9PrVqbMZC4mAlqG8qKsUQDIwxD2MmFoOLebM4Q=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=OIzhWMJTxIDy8trqFm8/7e+n7tQtycsddEn0Bexs/qW1EsqzGkzOVacdPRy0ujHPr 7D6Py6PGb9G0UiTCHTKkdetTZ7IyND8+nAA4Zboge1pMezkQQjQGEZAn2iXAtyqMFz wUH76N4y12Oya+04FCUhR6RZ3w2aBqYN1lBXqcUlojw725iIAFch1kLyt0E2F2HbKj oeq25JgSAEA1g9Jn0htamBDggWK65rPh9WD6Eh2oECMHkq0l/i/5P9+6VmmFJRb+wo ULGOsIFnaBEDaCXlDHWnKwhz7+aPgUeKf43TXXlp2Zuru2pif9ie5JLoHerN4SPdhy 9fqV4tmvfbwYhRL9p/cm003hyse1vvNmYVHPqEK692v9E12yVuXmMlMnCNtp9q89XV /CwEkdeurXf0DCrpv0PXGPxNWg2o9cHgTVXHh44cUcFG2gGVkwcMf0JUM1Db6GKSMf zDa4Ij8PpjgO2Q0RlQjnTKG+bY+2E41mzEnK4qd0wk5NWEw7+rjFcPhqXM0OqmIkfH IeMwR92IMHwYeZPE6UDVWNxNOfR76NGDTgMYhgYGzT79g1YcCJPYnTxaDRuC4ERcXZ Z95gfVA6oxg3vuR/uUVrACIUN+Ct853FKpZFoE6rGMke/kmSdnHY9qofU1HcC+S+0m KKaMp+GmgSXj57pqYc3Uo5Ec= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED, URIBL_SBL_A autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 84E02324C70; Sun, 9 Feb 2025 16:26:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739118380; bh=LKccF9PrVqbMZC4mAlqG8qKsUQDIwxD2MmFoOLebM4Q=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=AniDATDQlYhqMNsFe8cUh241ay00HmOIigp/i6hDmZtKILQhjR0OlvwHCDUvpayV8 u5XLDEawrcuYzOBXZJzYnCoJOmdi2PSX7gydZ4xQCUFb8PWqH2QnC1m7mtJZ5Xhyvz Q/kw3SJe4E2SOQhZ8jUrwyZi+wu0arNApG49DW7sH0x/Vm4SExlJ3EG8FtKqGoTi3a +wwbaa5DMhVTxKupvQjbT/9Sb+bIu8K2mLLqcsyBkd+oZqZ2dLUqhICPB5Uu56YF3K qxKUjah+b5PHN4exb96TKOzRNeJHzfQfyxAkrEm41fzhX/m+hA3uLmnizYq04tzPmf eq77VoOhUhOTPefwUyEyAFQHABP/hb/fmbVjrjAOfjMQyvvWSFZi7mpS7GVPAcB+7v Vjz15QYP3WtH7FsADOraDsyBg7ExCV6sO4iu+rE8DE40N9x95n0BYA0mN4Pp1qGno2 /2BVrPU0ilsIgdzhzrM4tZ4ohS7uo4Q0UfdpWplZUjPiKyKL6Wa6eCEhhHyu+28SBS oPozkG4s00hEbBfqwJWPgyP/qwESEGCKUcdEVPvj78jAAvtYMkmZyCfWEyUAMi7OoY /2mVLF+/bZsRPtZGQm5Lea40Vl73nlMU326BfvANRVCORH3+2RICOV6n9iE3ROpXlJ mGYoRdL5nj/ouNAvcKMYk6kM= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87frks98fm.fsf@gmail.com> (Maxim Cournoyer's message of "Wed, 05 Feb 2025 16:06:53 +0900") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87frks98fm.fsf@gmail.com> Date: Sun, 09 Feb 2025 17:26:20 +0100 Message-ID: <87lduff5jn.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.3 (/) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Hi, Maxim Cournoyer writes: > Hi, > > Tomas Volf <~@wolfsden.cz> writes: > >> --- /dev/null >> +++ b/gnu/packages/power.scm >> @@ -0,0 +1,125 @@ >> +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> >> +;;; Copyright (C) 2023 Raven Hallsby > > One last thing; I don't see Raven listed in a 'Co-authored-by:' git > trailer in the commit message; should they? Or otherwise mention > plainly this work was based on their previous work, made available > '$where'. I did not know about co-authored trailer. Should it be used even in situations where I just took a look at his version online without any active involvement? Currently I have modified the commit message to: =2D-8<---------------cut here---------------start------------->8--- gnu: Add apcupsd. Some parts were taken or inspired by the work of Raven Hallsby available here[0]. For that reason I have added his copyright as well (I asked for t= he permission). 0: https://raw.githubusercontent.com/KarlJoad/guix/9013b5ac3fadb48fad2e7ef1= fbfaa4848dcb922a/gnu/packages/power.scm * gnu/packages/power.scm (apcupsd): New variable. * gnu/local.mk (GNU_SYSTEM_MODULES): Register the new file. Change-Id: I0e4b2f50c8adf0f96d140e2be0f79e3740f4955c =2D-8<---------------cut here---------------end--------------->8--- Is that sufficient? Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmeo1ywOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wakakQ/+Icqd2dgQ/CeDbt0YUQW5ZOoGvxusDcC37Cir RyMl6sw3w/G+g9Om9KVRHFAu6yDgrrukGpEuHXv3bD7YgwwYUkbiyUD26qeMFZt2 oj23ujzH/gPoyDJP01N2nuFDZx2x4c5E6K4K9Hx3Eoh8B3Ot5KKHhIngbaPAO9TH dnEmRXnUH5eHAzEOl7QoY8WpV6gn7TQuxHOQdhM/Fc4ypbgmgq2w+Z0cYJSBXe3V HDNeJhxKb06+KJvsRsOsMUM1pZdZo9SUCdPzjoxy0hk+mT5t39TTNFGzk88rcC7T 37VElKMiDb6SzqXiJ+Ijiltv0CfibcrbSOZQCrRI4MfIIxOn0K+xAfrwcEwTg1rI nqIc87aKQ5H9qsEzKKWPcCaXefbNoAb3c6J5XVml9LN8h1+/Uvh3HbwXKw/i/F+1 QDbmiTcjauP5Sa2uK88pNMqoQG5bGJuSu/xqKTKHVlu1tzQRF8URiKNnQ4eMuwM5 ns/NaRZTYnKQWZlCi1LxBwZHbqa+TSAziLixhpuc7VWIDTuZiMrzXuiM/jK7q1Ko kMNqBPPtvY1tNxl63d41hVR0Tx5lnCmT+uG0UQPNYpYQYRJO7MbkxXTDdPZfp0NT A/n1YWABfMkK35ALxF5E3JicQ707o4u5T77YQ4k+j1p/S4t8h6DR8qvPZr74Utbq SqKLf08= =po+1 -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Feb 2025 05:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.17394254296789 (code B ref 75528); Thu, 13 Feb 2025 05:44:02 +0000 Received: (at 75528) by debbugs.gnu.org; 13 Feb 2025 05:43:49 +0000 Received: from localhost ([127.0.0.1]:39575 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tiS0r-0001lR-81 for submit@debbugs.gnu.org; Thu, 13 Feb 2025 00:43:49 -0500 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]:58734) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tiS0o-0001l6-HJ for 75528@debbugs.gnu.org; Thu, 13 Feb 2025 00:43:47 -0500 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2fa3e20952fso1040706a91.1 for <75528@debbugs.gnu.org>; Wed, 12 Feb 2025 21:43:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739425420; x=1740030220; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=Nrm0nqFSqzZ2s2xPTK2mgHsH7Zepe8RhOD0EkmAoAew=; b=UpJlbJpyEpvqnpmbavtUz3UcVNr3J/K2Ng5XGegew/acWmreTwQlMg1quJdjF6GStr 4YXsdHZO45a1FlXAPaw1hI4IwIzlXIrVo5RH+6rebVp9hfnLTkzgaLmJFU2ULNBAskAp Q+zbHEmxkC/pciodUBFlYh4hPrfRb0hyCqoCnrpYjw6Fx8uPSIKDjfOCJPN1+yZGc5pX RexvdQq6oMYleuvOYmMKDtIt+YSAusc6Xmhh7pshmQvyc42TPzcoJRGhukV8k2Vg+Qw+ NPxDjPf6fSpi2l0JUPeKuTfv3hsrKD2b0Or+YjJryi8BkczpF9mgS1bvHKvWStIv48+P gpVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739425420; x=1740030220; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Nrm0nqFSqzZ2s2xPTK2mgHsH7Zepe8RhOD0EkmAoAew=; b=B2lss4bbYSq8LJImgdyIegOdBRi03sN5h0dq/aYhiQVV3nA2lVCe01+QLfMuqNmqVC fPrSlF5+5eMxW4guNfT+CDQFvQ4LLfSqonW14bJjkdiiVmDOfuUPptGgWxRwqGHqMTAG 5OlTRWrk4n56KFNF687FFKOtgVjqgQ/9JglFYoMJM4Zq3WB17h9p0Buczj/FgM1NCaoa CgQqaq/QQ9D7LthDJGiEZMaNz7VP3XDA1TJyD7dLk5Aqfd9zYuI3p/2hjcsVF+w46Pat p3NgipPhRgxCBOnHQR+OLQuXXj/OMo2tHbTMxWyW4nm44uZuZiFk0GIDahrAYMtOPq/0 eibQ== X-Gm-Message-State: AOJu0YyeLmFyy6JTjjgqyd9efJfuWUeKX0tkJynj9qWRvyg+BMQFOFuM XaoweXSGmanmh7zYODZ1aa/Nh/cnVeEigA8VGSiD5L4NdKe6fIobT8XpK4Qe X-Gm-Gg: ASbGncsCYLlM5UXK7EEGyP2WHPoYwnh9SoqtkyB4j3yl+qUgt4Q9eTqvyj08um5hER8 eXf4G+0ynkKKo4TQDNncWpKRACZTyK+dW8gugMi9Z+E0slm16t1f7BJGZOtWnSA2vyxqM80ioXq RDj+l7sMrF9H5kjRtdb09OIkGLdB5ixk9qQVPgZH2GXxBMM8wfTcxjoO7bCS99SY+s7nlDxOu2I xCLWACW4NdN4WvMf0uBQUad8FDSf80SVLTZFijaPfHbOrAKLxVjogUf3CMmzXN74br24N+lx7yW 9ipKpZzCyeew X-Google-Smtp-Source: AGHT+IEnFG8yYEQr6pPXXwa4isEqc/zXog/fNIeWNmS6/Kw8Q/PKPYSoWekXbwRXgLB46f1wpwmPXQ== X-Received: by 2002:a05:6a00:98b:b0:732:1bad:e245 with SMTP id d2e1a72fcca58-7322c37ea39mr8013084b3a.7.1739425419676; Wed, 12 Feb 2025 21:43:39 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73242761694sm411698b3a.125.2025.02.12.21.43.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Feb 2025 21:43:38 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <87lduff5jn.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 09 Feb 2025 17:26:20 +0100") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87frks98fm.fsf@gmail.com> <87lduff5jn.fsf@wolfsden.cz> Date: Thu, 13 Feb 2025 14:43:27 +0900 Message-ID: <87y0yal7r4.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.3 (/) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: > Hi, > > Maxim Cournoyer writes: > >> Hi, >> >> Tomas Volf <~@wolfsden.cz> writes: >> >>> --- /dev/null >>> +++ b/gnu/packages/power.scm >>> @@ -0,0 +1,125 @@ >>> +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> >>> +;;; Copyright (C) 2023 Raven Hallsby >> >> One last thing; I don't see Raven listed in a 'Co-authored-by:' git >> trailer in the commit message; should they? Or otherwise mention >> plainly this work was based on their previous work, made available >> '$where'. > > I did not know about co-authored trailer. Should it be used even in > situations where I just took a look at his version online without any > active involvement? Currently I have modified the commit message to: I believe if you reused enough of the code to make it necessary to add their name to the copyright notice, then a Co-authored-by git trailer would make sense (whether they were actively involved in your version or not). > gnu: Add apcupsd. > > Some parts were taken or inspired by the work of Raven Hallsby available > here[0]. For that reason I have added his copyright as well (I asked for the > permission). > > 0: https://raw.githubusercontent.com/KarlJoad/guix/9013b5ac3fadb48fad2e7ef1fbfaa4848dcb922a/gnu/packages/power.scm > > * gnu/packages/power.scm (apcupsd): New variable. > * gnu/local.mk (GNU_SYSTEM_MODULES): Register the new file. > > Change-Id: I0e4b2f50c8adf0f96d140e2be0f79e3740f4955c > > Is that sufficient? Co-authored-by is not mandatory, but I see it as a nice etiquette to have, similar to how it's important to preserve the proper commit authorship information, for due credits. -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Feb 2025 06:02:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173942649510347 (code B ref 75528); Thu, 13 Feb 2025 06:02:02 +0000 Received: (at 75528) by debbugs.gnu.org; 13 Feb 2025 06:01:35 +0000 Received: from localhost ([127.0.0.1]:39651 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tiSI3-0002go-1C for submit@debbugs.gnu.org; Thu, 13 Feb 2025 01:01:35 -0500 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]:49280) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tiSI0-0002gU-Ia for 75528@debbugs.gnu.org; Thu, 13 Feb 2025 01:01:33 -0500 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2fbfa8c73a6so1045453a91.2 for <75528@debbugs.gnu.org>; Wed, 12 Feb 2025 22:01:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739426485; x=1740031285; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=35DuGeHP+2fVSq2DvNHpu3BA5r/8Kyffx1hiuxkVkEc=; b=Ha0pl78bnRWJjl5Wtyj1mrtS2MtffywydirR9SpgwunebELP8MZm51bA4uKix6K0q/ wZe1CEpuzCLoY2snbAW8ltGD/71khP4r77ZdX66n45FgiDk/Rv5RHfpUlEz5hbHv9uSG wavBFOKC5jxqpOQ7LP39OO68Lfq/QfxbRHFe7colaMI0VxGCFqOPC8vLa3XnBMM8j6hH BWntl9bLnwC14oI6y1OT+h9zXEjxpNF8KiU6M8PzMzFuFTOvnKzPH8SVdk/cwxPhmEMo lKZJUwVUwh66jgIBd8zJhXCpo9PIT+QBz6q6n4e9ieLMNzON+llOcBPeWJ8dKdkMtv+8 ZiWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739426485; x=1740031285; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=35DuGeHP+2fVSq2DvNHpu3BA5r/8Kyffx1hiuxkVkEc=; b=BDpSaaaKShjnvQtviN7cetWpc33J+6ySQSZZgIjWEZ5SS6xdArUocTkOCQ7Zcz36XF tvyfBO7g0QKY2JOiiBMcvXWvGREKHLyg3ZCJb0TuYRBZjtlVDQnk98DoiQfCeMCfaqYZ VZJI7jsn+SQeO8KloVlQTI43Bq/7r3eZq1BHHLQnCAHFAHd50M2CfYHOyldxJC+RxhYI f4Gvw86syEIdHCXBUJfzTq2kBKdFOQmUeohXvHJ7T/Q4Q03c3NdyA6zQg0XOUtWdShHh Wgo06lhXqGAZwFo3lRWAenT4T6OPtj6OS6ifsOGkt528gpgUv+iDLdNN0peyDI2U+n94 LaJA== X-Gm-Message-State: AOJu0Yz9RqYOwQydtctG9vVGsbwogR51VRvDr7PxkT49vz5efWiukzvm 5cW37pmUWPKX31BXU6He0Z8ygVTYjkqsZ68dCBP4M4//2vwVz4uPOPV2QXTc X-Gm-Gg: ASbGncureqKkRmjiDIDD/njvnOQA2BQ65U85s0rmtuVOJP0ZrzwN552X4t4GFHOX983 9pnOBjwTJzsHjaDtIylJjune/gTt/LVae6bfjFZUk4W5jV5Rt2DYu1wWdfIlFHjWlIgxW5lfFVf TDlg3CvyS4vpUGI0cUGESPRtmmiwnHwpcTy8HNI6akEHeKzHEtgpTr7u0H4dUblpTN5FfANgrTB 807DP3so/s4z+aoqZcN3w/I/nHBWg3Jm3ng24Hfp+dYqtyoHGB9Kdm8pU4l2ztNxTFot/wLlUui EBTFMOTs9kp2 X-Google-Smtp-Source: AGHT+IHUpbWOlageiMPzyj8+GJzUV5i5jl+KXiHRYiUxBuDLzrL17f+jAa6Jj9OIE6EKcgAlyvcwag== X-Received: by 2002:a17:90b:2712:b0:2ea:bf1c:1e3a with SMTP id 98e67ed59e1d1-2fbf5bec6bbmr11731289a91.12.1739426485261; Wed, 12 Feb 2025 22:01:25 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2fbf98f0facsm2479394a91.23.2025.02.12.22.01.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Feb 2025 22:01:24 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <87pljrf69g.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 09 Feb 2025 17:10:51 +0100") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87jza498sp.fsf@gmail.com> <87pljrf69g.fsf@wolfsden.cz> Date: Thu, 13 Feb 2025 15:01:12 +0900 Message-ID: <87tt8yl6xj.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: [...] >> I think /var/run is deprecated in favor of just /run, so we should >> configure the package to use this, I think. > > It seems pretty much all programs on my system are using /var/run, > including Shepherd. Only programs that store information in /run seem > to be elogind and dbus. > > Is deprecation of /var/run listed somewhere in the manual? I am > surprised Shepherd (since it is actively maintained and core component) > is still in /var/run. I looked and found 42 references to /var/run, but > none with the deprecation notice. > > Assuming you will insist on moving it to /run, is there some structure > to follow in that directory? Or just s~/var/run~/run~? What about /var > and /var/log? Should those be moved somewhere as well? > >> >>> + (string-append "ac_cv_path_SHUTDOWN=/nope") >>> + (string-append "ac_cv_path_APCUPSD_MAIL=/nope") >>> + ;; While `wall' is not expanded anywhere, it still is searched for. >>> + (string-append "ac_cv_path_WALL=/nope") >> >> I'm not sure if this package is actively developed, but that last issue >> should ideally be reported (then cross-referenced here). > > I did not found a way to report a bug. Nothing is listed in the manual, > and their apcupsd-users mailing list requires JavaScript to sign up (and > does not tell me the email address otherwise). > > I did try to blindly send an email, will see if it will be accepted > without being subscribed. If that happens, I will add the link here. OK, thank you. >> >>> + ;; Enable additional drivers. >>> + "--enable-test" >> >> Is '--enable-test' useful? What does it do? > > According to the manual > > This turns on a test driver that is used only for debugging. > > > Since there does not seem to be any harm in having it on, I enabled it, > since Guix seems to aim for feature complete packages (I assume that is > the reason for everything being so large). But I have no use for it, so > I can turn it off if you would prefer. For this kind of very edge case that is not enabled by default, I'd leave it off. Our maximalist take on things doesn't including switching on every non-default option, but if extra dependencies are automatically picked as part of the configure script, then we would typically add them, unless they grow the 'guix size' of the package unreasonably (like adding libreoffice to emacs-org-mode because it has support for it :-)). It's one of the reason. Other reasons are references kept erroneously, static libraries, large documentation, wrappers keeping references to native inputs that shouldn't be captured, etc. There's a lot of work to do to reduce the size of the distribution :-). [...] >>> + (add-before 'configure 'touch-txt-docs >>> + (lambda _ >>> + (for-each (lambda (f) >>> + (call-with-output-file f close-port)) >>> + '("doc/apcupsd.man.txt" >>> + "doc/apcaccess.man.txt" >>> + "doc/apctest.man.txt" >>> + "doc/apccontrol.man.txt" >>> + "doc/apcupsd.conf.man.txt")))) >> >> I think I'd rather depend on these than introduce hacks like below. > > The "hacks" *below* would still be required. The HTML manual is not > built nor installed by default, and there is no target to invoke to > install them. So both 'build-manual and 'move-doc phases would still be > required. > > We could get rid of the "hack" *above* ('touch-txt-docs), true. It is > worth those two additional inputs? Yes, I meant above, sorry. I don't see mandoc and util-linux as large dependencies enough to justify working around these, especially if they are only used at build time. And, the would actually be useful when working on the source of acupsd in a 'guix shell -D acupsd' environment, so I'd just add them. [...] >> >>> + (add-after 'install 'remove-etc-apcupsd >>> + (lambda _ >>> + (delete-file-recursively (string-append #$output "/etc/apcupsd"))))))) >> >> Break this long line so it fits under 80 columns (our code style >> guideline). > > I thought (well, still do), that going 4 characters over the limit was > worth the increase in readability. Nevertheless, I have split it into > two lines. Thanks. In some cases where it really hurts readability, it may be fine (it's a guideline after all), but the usual business of simply moving one parentheses pair down is not one of these :-). [...] > I do not think this is correct. When I check > apcupsd-3.14.14/src/apcupsd.c file, I see this in its header: [...] > There is no mention of "any later version". Does that not make the > combined work GPL-2.0-only, even if other files would be under > GPL-2.0-or-later (I did no check whether they are)? You are right, and yes the combined work would be GPLv2 only then. > I did not find debian/copyright file in the source code. There's one at least in https://sourceforge.net/projects/apcupsd/files/apcupsd%20-%20Stable/3.14.14/apcupsd-3.14.14.tar.gz/download [...] >> Could you please send a v2? > > Definitely, I will go through your review for the service file as well, > and once I have all the answers (both here and there), will send v2. I haven't seen v2 yet, I guess you are still working out the service part? -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 14 Feb 2025 22:58:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173957383232471 (code B ref 75528); Fri, 14 Feb 2025 22:58:01 +0000 Received: (at 75528) by debbugs.gnu.org; 14 Feb 2025 22:57:12 +0000 Received: from localhost ([127.0.0.1]:52234 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tj4cR-0008Rf-TP for submit@debbugs.gnu.org; Fri, 14 Feb 2025 17:57:12 -0500 Received: from wolfsden.cz ([37.205.8.62]:39864) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tj4cO-0008RR-W8 for 75528@debbugs.gnu.org; Fri, 14 Feb 2025 17:57:10 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id E826A376700; Fri, 14 Feb 2025 22:57:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739573826; bh=gyAi1bDcKp8tAWbsO399IDalTfae67CjJxWmq/2wjU8=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=GayhSBIQ+H/O3U6SyuLOmEH0b5XwS1TPFxbqQX8ugnuKphZsLHJRTFuoVcqlmwPj9 CB6EfR09rMlxSMy3wq37RhoMXic5eXw+w0n2YtaoHNzagRcwVtdKkxMlKZV7UZOnhI +Jw8svnp8a1jUAKJpmpnEVH3Czu3UbD/VFx9MxhbReAc+WLvJwAxj0GPwi4w/uLULs H4CMUBjxvXJtFRY2T8UKopJyuDzCRtGIAEa8BmuPiH7UfHQqtf165AB0tB668IXkU0 wp7IQyFGNowkoUZwfySpCnFS1UsC83LiM+6vzRnc6NrP7Ppy9Mu9nT1zANkEmWWXzg FU9ytYAsVhTp8joKBbLdGdP+zWcVxzMJsWWh2ITehN37rpGLtW5KDHZg49zbRAbAFx /plmBCJTwCHUTiq/kL5fFNrciEAs+wJvWV7XLUr41zLMP2BzvHznj4s8mFEuDUp/jm mU2yvpv0+Hb5lYKPSukw+6aiOep59pj9xtuJINhfdGfCtpISlTl1yR0SgVe217GUGf hjs0lGWoHzVBL6wS2l/lfKi+HK6XvSt2GvpIpp6nZGzLLDvjZ6/ghCYYPEbFYbOm55 oWfZJz76cwP8JRYjfmfrnlHxoYnD3cBSTDgHRLCu+V4zzXxBkd9fKwHp1b7A7whdWB vO+CjXbeur2d5kb2dRTyKtsc= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 5B6F23758CF; Fri, 14 Feb 2025 22:57:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739573826; bh=gyAi1bDcKp8tAWbsO399IDalTfae67CjJxWmq/2wjU8=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=GayhSBIQ+H/O3U6SyuLOmEH0b5XwS1TPFxbqQX8ugnuKphZsLHJRTFuoVcqlmwPj9 CB6EfR09rMlxSMy3wq37RhoMXic5eXw+w0n2YtaoHNzagRcwVtdKkxMlKZV7UZOnhI +Jw8svnp8a1jUAKJpmpnEVH3Czu3UbD/VFx9MxhbReAc+WLvJwAxj0GPwi4w/uLULs H4CMUBjxvXJtFRY2T8UKopJyuDzCRtGIAEa8BmuPiH7UfHQqtf165AB0tB668IXkU0 wp7IQyFGNowkoUZwfySpCnFS1UsC83LiM+6vzRnc6NrP7Ppy9Mu9nT1zANkEmWWXzg FU9ytYAsVhTp8joKBbLdGdP+zWcVxzMJsWWh2ITehN37rpGLtW5KDHZg49zbRAbAFx /plmBCJTwCHUTiq/kL5fFNrciEAs+wJvWV7XLUr41zLMP2BzvHznj4s8mFEuDUp/jm mU2yvpv0+Hb5lYKPSukw+6aiOep59pj9xtuJINhfdGfCtpISlTl1yR0SgVe217GUGf hjs0lGWoHzVBL6wS2l/lfKi+HK6XvSt2GvpIpp6nZGzLLDvjZ6/ghCYYPEbFYbOm55 oWfZJz76cwP8JRYjfmfrnlHxoYnD3cBSTDgHRLCu+V4zzXxBkd9fKwHp1b7A7whdWB vO+CjXbeur2d5kb2dRTyKtsc= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87tt8yl6xj.fsf@gmail.com> (Maxim Cournoyer's message of "Thu, 13 Feb 2025 15:01:12 +0900") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87jza498sp.fsf@gmail.com> <87pljrf69g.fsf@wolfsden.cz> <87tt8yl6xj.fsf@gmail.com> Date: Fri, 14 Feb 2025 23:57:05 +0100 Message-ID: <87tt8w6sou.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: >> I did not found a way to report a bug. Nothing is listed in the manual, >> and their apcupsd-users mailing list requires JavaScript to sign up (and >> does not tell me the email address otherwise). >> >> I did try to blindly send an email, will see if it will be accepted >> without being subscribed. If that happens, I will add the link here. > > OK, thank you. I have now added a link to my message to the mailing list. >>> >>>> + ;; Enable additional drivers. >>>> + "--enable-test" >>> >>> Is '--enable-test' useful? What does it do? >> >> According to the manual >> >> This turns on a test driver that is used only for debugging. >> >> >> Since there does not seem to be any harm in having it on, I enabled it, >> since Guix seems to aim for feature complete packages (I assume that is >> the reason for everything being so large). But I have no use for it, so >> I can turn it off if you would prefer. > > For this kind of very edge case that is not enabled by default, I'd > leave it off. Our maximalist take on things doesn't including switching > on every non-default option, but if extra dependencies are automatically > picked as part of the configure script, then we would typically add > them, unless they grow the 'guix size' of the package unreasonably (like > adding libreoffice to emacs-org-mode because it has support for it :-)). > > It's one of the reason. Other reasons are references kept erroneously, > static libraries, large documentation, wrappers keeping references to > native inputs that shouldn't be captured, etc. There's a lot of work to > do to reduce the size of the distribution :-). > > [...] Makes sense, I took it out. >>>> + (add-before 'configure 'touch-txt-docs >>>> + (lambda _ >>>> + (for-each (lambda (f) >>>> + (call-with-output-file f close-port)) >>>> + '("doc/apcupsd.man.txt" >>>> + "doc/apcaccess.man.txt" >>>> + "doc/apctest.man.txt" >>>> + "doc/apccontrol.man.txt" >>>> + "doc/apcupsd.conf.man.txt")))) >>> >>> I think I'd rather depend on these than introduce hacks like below. >> >> The "hacks" *below* would still be required. The HTML manual is not >> built nor installed by default, and there is no target to invoke to >> install them. So both 'build-manual and 'move-doc phases would still be >> required. >> >> We could get rid of the "hack" *above* ('touch-txt-docs), true. It is >> worth those two additional inputs? > > Yes, I meant above, sorry. I don't see mandoc and util-linux as large > dependencies enough to justify working around these, especially if they > are only used at build time. And, the would actually be useful when > working on the source of acupsd in a 'guix shell -D acupsd' environment, > so I'd just add them. > > [...] > Makes sense, I will remove the phase and add the dependencies into native-inputs. >>> Could you please send a v2? >> >> Definitely, I will go through your review for the service file as well, >> and once I have all the answers (both here and there), will send v2. > > I haven't seen v2 yet, I guess you are still working out the service > part? I did not get to the service part yet (life has sadly been somewhat busy), will get to it during this weekend. But I was also waiting for your response here, there was no reason to send v2 since I was pretty sure I will need to do additional changes, so v3 would required anyway. Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmevykEOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wal1Og/+KElBecFbmgeWz9UIeEhGj8cjKnNaLzR8UJm4 /nYaAH70G1tVWlh7y91yq3Ps4xrkU/mHYAS5R7JD8wcz4W993ZSKfg1YjUdvqHQZ 6nzv/o7y+obJq58Vcghx4myIOPbF2fRhm4h3qzFYjKU5CFPIwrfisTuKrSlX6Vu/ MMrpa9H+1E3HsllIuvkfU79yodoCGdaYsSM9ss8e33G0lGFD/QvzYBpepDq+Jz9O BFEENZOGKjrpMyUXG/2ERzLcvIex2NolJxYC8n6Kkq2XuPW4yunH8vfEWkDYGUvg HEW9PCCsou2f44U6ozVD4ce/xH84scm06RaM8hD8WISQlkasL5FNvEw9AsdgWUnw YIhJgoBn7oiOLCrcp6XPZWFe6pLdQJOJOOk3eKRh/4ywdyGj4GibKZ0Q18Sg0wNI K4CGIs+1sGdqt1G/jbMBCRzuDJPq3mrkHWIPwPiACZqkIVXBmlCLv6/MmZrS8vQy 0h1EQAKr+oldvpwthPrADwwU1x1Le1/gDLOPEr/PcKGv/+edM1lQf6BqUFsK1b02 j88zRCteHHpj73QIfeUSc1Swky55JFFIKjn+Z5fJma5+jC8EEAMuxByKtzsnuhGo HjBhFgod+6MqvTAw3uFJow+mc0bB89PABE+w7Lv7FDCorU54BQFKYHXfGSDc0D/h 9EtyOio= =GqeM -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 15 Feb 2025 14:06:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173962832030885 (code B ref 75528); Sat, 15 Feb 2025 14:06:01 +0000 Received: (at 75528) by debbugs.gnu.org; 15 Feb 2025 14:05:20 +0000 Received: from localhost ([127.0.0.1]:54037 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjInI-000825-BF for submit@debbugs.gnu.org; Sat, 15 Feb 2025 09:05:20 -0500 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]:51245) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tjInG-0007wD-7b for 75528@debbugs.gnu.org; Sat, 15 Feb 2025 09:05:18 -0500 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2fbfc9ff0b9so4671106a91.2 for <75528@debbugs.gnu.org>; Sat, 15 Feb 2025 06:05:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739628310; x=1740233110; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=RWxGdEQA3EIv4OwqjxoXJHiP9e7LGDZvsbyCl4Omgx8=; b=WXbIgx0i5EDswR0haHM/oYqkxY9VqWipakWoWV4vXOSZGr+9L6QV9en6TfNqVKGeX5 wNJnW/EJ2wESYOzUEZfRl1P7AQz/embkYoF/a7jx3QTZFr38Enec0rOMq09QjVgXg5qe e4G00PvfOAHBOCo6jbYD/G8YestG+OfWQeFk2O0gbrN8IWy/RYhBT8dMqfMI0YH+2CYR dtL2ycUqdkXAl9nFYgpc9zfomiWpAzRW2jdyYhfLUso1895j254ubaZNS2SoLK1YP9Kw K4hTb0cZkWuojKaqmjdQHXvPwj0wg7uIKvAdnvl1uWO0D/1dGsHjzEBX5M57q5TbzvrE 1I9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739628310; x=1740233110; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=RWxGdEQA3EIv4OwqjxoXJHiP9e7LGDZvsbyCl4Omgx8=; b=wawNxDDf+ZZTVORH0s/Or53QRs4MYCFWVX8i6mnxwv65xwyPuLB9QEhgwm31r7eOYA wnSXKLclfliko0L74NKFTgoSuqz+oqAP4UP5gsobXFXHoo4TSc/MmRFImIeH3geYxSnV wuMMLBRrD04w/qpeu4drohV+ODKokPuncAuWN9CZ1zNxdU+w+zq1CJsZzaoanWTkiiDj GfB3otRb/8gpvEVYuCbH6XNbrIU7VFV+S4NbauXjvuUqUnpJ1LzkshH5eeOcgEbrfFJS kXNJEJEnEfhbXhe9mIFjwpVWg3sDbpZk4N6lHnQLztP5s3fFdRTp5n6WL/4gbtmcJXHp t6kA== X-Gm-Message-State: AOJu0YyRUmr9m5WBpoUyOXA+E758rBBzU3GYhULuAscc/kooCcHLyVHv u09vAYKxttf+19eQpv4LfVyEl7vn9iO8l6ADyxDUjp1E5GB4SUUl6kx/eg== X-Gm-Gg: ASbGncu8zQ0Ky20ohMxuiB/5zjB/Ubffuu6b+V62OihS1M9ussjdR7VHFn4b7wL4hAh wCLtjZTnnfH57paaoXdFPVnv9fG4WhIU2PGpBvwIxbH7GfWkUHYhhtafEgqvwxNTdHvWbQg/JEb vBFzDkj30hPhgmmOpcjTlKIn0K321MopZWaHy8MK5yKgp6SEh9i4IwyDy5qPEami8eM1m7hHAW6 bnX4nFbMqITdOXJBhOIbq92dcQHDGI6xZkIdbgRJXaCVEtJdrk8LQZkUc1l7VbhhdBb/VP91Tkv sgGt9ADBrus9 X-Google-Smtp-Source: AGHT+IEVjWSkGGssfqI3SNgihscaoZZpzD3o2qR68bb+7s9UqTYZpCf/HEO93CJJCtCjmcnYz/lcjw== X-Received: by 2002:a17:90b:3809:b0:2ee:94d1:7a9d with SMTP id 98e67ed59e1d1-2fc411540bfmr4059317a91.32.1739628310075; Sat, 15 Feb 2025 06:05:10 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d545d453sm43583585ad.115.2025.02.15.06.05.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Feb 2025 06:05:09 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <87tt8w6sou.fsf@wolfsden.cz> (Tomas Volf's message of "Fri, 14 Feb 2025 23:57:05 +0100") References: <51cba7679af5c4aa9cf0e6d70453e369ff0909d6.1736722765.git.~@wolfsden.cz> <87jza498sp.fsf@gmail.com> <87pljrf69g.fsf@wolfsden.cz> <87tt8yl6xj.fsf@gmail.com> <87tt8w6sou.fsf@wolfsden.cz> Date: Sat, 15 Feb 2025 23:04:57 +0900 Message-ID: <87frkf8fsm.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Thank you for having taken my suggestions into consideration :-). [...] >> I haven't seen v2 yet, I guess you are still working out the service >> part? > > I did not get to the service part yet (life has sadly been somewhat > busy), will get to it during this weekend. But I was also waiting for > your response here, there was no reason to send v2 since I was pretty > sure I will need to do additional changes, so v3 would required anyway. No worries. Just keep me in CC when you get around ot it, and it's probably going to be fine to go then. -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 15 Feb 2025 22:01:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173965681318955 (code B ref 75528); Sat, 15 Feb 2025 22:01:02 +0000 Received: (at 75528) by debbugs.gnu.org; 15 Feb 2025 22:00:13 +0000 Received: from localhost ([127.0.0.1]:58343 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjQCo-0004uq-E6 for submit@debbugs.gnu.org; Sat, 15 Feb 2025 17:00:12 -0500 Received: from wolfsden.cz ([37.205.8.62]:55610) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tjQCj-0004pl-TB for 75528@debbugs.gnu.org; Sat, 15 Feb 2025 17:00:09 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 1345F37AA53; Sat, 15 Feb 2025 22:00:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739656804; bh=wcQ/eExVDX4lQBrPM3EDfqhlbAdBVp0+AR3TbXjqi0k=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=hBfcFFSkiKscPRDqgmsewq7lI3gMen1oqu0oWfpUMmtblPho/dmI/rvf2Xcibrfw7 Mw4xYAfK76KW8Vxb/VbVPmKaA9dtwdV90rmhayxxbKraEKgZ56lp7f1YLY/xF0qHOM 89sKAuBCKMBJH2Q/CpYkWdXiY+Mah+O7+VAuqxzcFsjfL3v5XT4UO6k4A5dHMnb8VP +IV4RzxzTBTVzusvuddf3lsJnK2Brcu8UOcd9IRKgqxT0ud2Xtz8pWVYH4Nqb7FJmQ Iv8hM4nE83SHNgWG/+3CoRwXFBFJ0kd58AtQIM7mhbdoL/K4bpJ/oINSRb4x2oKV1K I+4aL3gOcO3iyh0OHyXrUN5j6zyJ3o2OTf2Opr2/Wr/0tn2lL8tnwFEVQGVTlR9lAC IFXzbYXlYwnY8lV9vVu7l4qNQbqwU7L4LzNW/o1jtBUPaf4vtGCUv9FCc0wvfdkaky fEfxvfCkBPCPR57ZRedVEXaUFwmtgnStG5wSzgAax8ukHh5wPyTenSF4iCtZB8HpPl NIftcEEVDBogBKiV8PDazmYQeS8hiCtjOl8nInDZRxrT53td8E81JoTcDRZwLg9MRw F9/s/cdZ2YkDJLHPELLixgO0sVZCiDCCx0VLTvkIs0RUVOW04vBIwBQ1jwtodU+REb I9rqVGXpe4iuDaFxd+1MMbYg= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from localhost (unknown [193.32.127.154]) by wolfsden.cz (Postfix) with ESMTPSA id 7770F37AEE9; Sat, 15 Feb 2025 21:59:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739656798; bh=wcQ/eExVDX4lQBrPM3EDfqhlbAdBVp0+AR3TbXjqi0k=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=M9xJFIUVskf/7Y28oHZKL/19btozgHa3Kyu1hWSRFtG+J+oEfo5UCnliqVq89xzTg aCqcKP7z6XR/ZZjMHif8xT5JTc4vYrKSvjtP3+l2eyBV6WEW9lmAk5QRJIqR+oeqiK lZvQa9TbPsdMNf3nVdpOeepKWdYKgzzT/aTtasD2hVlNZAM88aSb5YUtq7VqA89NMr uKF1c7nGMEdJS/qhFPI1PWi3a4b1DkjuDMvsaf8jUp4LlESQcBXUs/5QDpTbaQfphl RzO7oJY87HXUFMds+Pd/r+QXAeDERs1VfSoXq4+KMk1leSkNxcLIWLvz8RANiByuyt vgq8d129IsmcpaF/fmT+OZw31SzJk35VvUtYBYjuwWUWsfYDy+j+MSi39nvo/3C9iZ nmj+JP9QN6IF2spZZMsbcSUxGA1ETyBqPNBODjGqb5xaR8xm1Y0/w9aajVPXR1jpE/ bKEqFvJ+7sUrg6G8267+Vi4Z8DvRo2Vhu4zCJer5L4y0JJB6VfvVX1X8x+hvZNEVCR NwRnxvhONf4zhKwr+fyet+NiOkknGqnuoKzBfpT1k1Pxi8pQYa0QnxH+Lc9VMtC65O wOr8vHa3A6gpvzg/DkLPo84o4oqzcc4j0qIXtkF6D4zF+/uPMrkIAyaLkYG8/mhO35 o2LlS2BDRHZElMz1gSTjO/JA= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <878qqk8q96.fsf@gmail.com> (Maxim Cournoyer's message of "Wed, 05 Feb 2025 22:39:33 +0900") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> <878qqk8q96.fsf@gmail.com> Date: Sat, 15 Feb 2025 22:59:57 +0100 Message-ID: <874j0u7tsy.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > Hi Tomas, > > Tomas Volf <~@wolfsden.cz> writes: > >> * gnu/services/power.scm: New file. > > I see there's already a gnu/services/pm.scm file; it seems we don't need > another one? Or was it a conscious decision? Yes, it was intentional, for couple of reasons (in no particular order). I like the symmetry between gnu/{packages,services}/power.scm. It makes finding the service-type easy without even opening the manual. The "pm" is for "power management", and I have never heard anyone call apcupsd "a power management daemon". It reacts to power outage, true, but it does not "manage" the power in any way. So it seemed like a poor fit. The current pm.scm exports 8 bindings, the new power.scm 54. So it would feel like taking over the file. Shorter files are faster to compile (especially when define-configuration is used), so having two files that can be built in parallel seemed better. And like this I can also write the changelog in to the commit message in a reasonably short form. If I put it into pm.scm, I would need to list every single binding, in power.scm I mention just a new file. > >> +The @code{(gnu services power)} module provides a service definition for >> +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with APC >> +UPSes. Apcupsd also works with some OEM-branded products manufactured >> +by APC. > > I'd introduce a few @acronym here to help readers, e.g. for OEM and > UPS. I added ones for UPS, OEM and APC. > >> +@defvar apcupsd-service-type >> +The service type for apcupsd. For USB UPSes no configuration is >> +necessary, however tweaking some fields to better suit your needs might >> +be desirable. The defaults are taken from the upstream configuration >> +and they are not very conservative (@code{battery-level} of 5% is too >> +low in my opinion). > > I'd say, (for example, the default @code{battery-level} of 5% may be > considered too low by some), to keep it neutral. Done. > >> +The default event handlers do send emails, read more in >> +@ref{apcupsd-event-handlers}. >> + >> +@lisp >> +(service apcupsd-service-type) >> +@end lisp >> +@end defvar >> + >> +@deftp {Data Type} apcupsd-configuration >> + >> +Available @code{apcupsd-configuration} fields are: >> + >> +@table @asis >> +@item @code{package} (default: @code{apcupsd}) (type: package) >> +Package to use. > > That's more conventionally named with the same of the package, > e.g. 'acpupsd', not 'package'. I'd word the description as 'The > @code{apcupsd} package to use'. I see, good to know, will try to adhere to that convention from now on. > >> +@item @code{shepherd-base-name} (default: @code{apcupsd}) (type: symbol) >> +Base name of the shepherd service. You can add the service multiple >> +times with different prefix to manage multiple UPSes. > > s/prefix/prefixes/ I will just take your word on this one. :) >> + >> +@item @code{auto-start?} (default: @code{#t}) (type: boolean) >> +Should the shepherd service auto-start? >> + >> +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: s= tring) >> +Path to the pid file. > > All file names becoming /run/ prefixed instead of /var/run, based on a > previous comment. I will just quote myself from the package's patch, since it seems I did not get an answer there: =2D-8<---------------cut here---------------start------------->8--- It seems pretty much all programs on my system are using /var/run, including Shepherd. Only programs that store information in /run seem to be elogind and dbus. Is deprecation of /var/run listed somewhere in the manual? I am surprised Shepherd (since it is actively maintained and core component) is still in /var/run. I looked and found 42 references to /var/run, but none with the deprecation notice. Assuming you will insist on moving it to /run, is there some structure to follow in that directory? Or just s~/var/run~/run~? What about /var and /var/log? Should those be moved somewhere as well? =2D-8<---------------cut here---------------end--------------->8--- Thanks. > > We don't use path in GNU to denote file names, we use 'file names'. > That's mentioned in info '(standards) GNU Manuals': > > Please do not use the term "pathname" that is used in Unix > documentation; use "file name" (two words) instead. We use the term > "path" only for search paths, which are lists of directory names. > Changed into "File name of the pid file.". Out of curiosity, does this apply to directories as well? So, hypothetically, I should instead of "Path to the directory storing XY." use "File name of the directory storing XY."? >> + >> +@item @code{debug-level} (default: @code{0}) (type: integer) >> +Logging verbosity. Bigger number means more logs. In the source code I >> +saw up to @code{300}, so for all logs, @code{999} seems reasonable. > > I think it's best to not use first person pronoun in the manual to keep > it a bit more formal. So instead of 'I saw', this could be reworded to: > 'The source code uses up to @code{300} as debug level value, so a value > of @code{999} seems reasonable to enable all logs.' or similar. Sorry, I have probably gotten too influenced by (gnus) and its personal style I have enjoyed a lot. I have used your suggestion verbatim. > >> + >> +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) >> +Directory containing runtime information. You need to change this if >> +you desire to run multiple instances of the daemon. >> + >> +@item @code{name} (type: maybe-string) >> +Use this to give your UPS a name in log files and such. This is >> +particularly useful if you have multiple UPSes. This does not set the >> +EEPROM. It should be 8 characters or less. >> + >> +@item @code{cable} (default: @code{usb}) (type: enum-cable) >> +The type of cable connecting the UPS to your computer. Possible generic >> +choices are @code{'simple}, @code{'smart}, @code{'ether} and >> +@code{'usb}. Or a specific cable model number may be used: > > nitpick: I'd reword to 'Alternatively, a specific [...]', which reads > better to me. Done. > >> +@item usb >> +A null string setting enables autodetection, which is the best choice >> +for most installations. > > nitpick: My dictionary (aspell) prefers auto-detection. Huh, so does hunspell. Shame on me, I need to remember to enable flyspell-prog-mode more often. > > [...] > >> +@anchor{apcupsd-event-handlers} >> +@deftp {Data Type} apcupsd-event-handlers >> + >> +For description of the events please refer to the @command{apcupsd}'s >> +manual, which can be found in the @samp{apcupsd-doc} package. > > I think you also meant it is in the @samp{doc} output, not in a > different package, right? Right. > In any case, I'd refer them to the man page of apccontrol, which > details the events. Also, to avoid the odd rendering as "the > =E2=80=98apcupsd=E2=80=99=E2=80=99s manual" in info, I'd instead rephrase= to: > > For a description of the events please refer to @samp{man 8 > apccontrol}. I like this version, thank you. > >> + >> +Each handler shall be a gexp. It is spliced into the control script for >> +the daemon. In addition to the standard Guile programming environment, >> +these procedures and variables are also available. > > s/these/the following/ [...] s/available./available:/ Done. > Since these are spliced in the control script and thus not at the top > level, users won't be able to import Guile modules they may want to use, > so it seems there should be a field to define which Guile modules should > be imported and used by default in the configuration. Hm, that is a good point. I did not think of that. I have added a `modules' field to the apcupsd-event-handlers record. > >> + >> +@table @code >> +@item conf >> +Variable containing path to the configuration file. > > s/path/file name/, anywhere this appears. Done. I went back to the package and replaced it there as well. It is bit unfortunate that autotools call the variables `ac_cv_path_', instead of `ac_cv_file_name_', but nothing I can do about that. > >> + >> +@item powerfail-file >> +Variable containing path to the powerfail file. > > Ditto. And done. > >> +@item cmd >> +The event currently being handled. >> + >> +@item name >> +The name of the UPS as specified in the configuration file. >> + >> +@item connected >> +Is @code{"1"} if apcupsd is connected to the UPS via a serial port (or a > > @command{apcupsd} Thanks. > > Also, any reason why these integer values are expressed as strings? No. I have just adhered to the original calling convention of the shell script, and argv is all char*. These are even not really an integer values, but bools. So I changed this one to `connected?', and the other one to `powered?', with #t/#f values. > >> +USB port). In most configurations, this will be the case. In the case >> +of a Slave machine where apcupsd is not directly connected to the UPS, > > s/Slave/slave/ ? Could be nicer to use a neutral alternative like > 'follower machine'. The "Slave machine" (including the capitalization) is a term used in the manual. I can lower-case it if you would prefer, seems that manual actually uses both casings now when I looked for it. I do not think inventing new terminology is a good idea, since users will not be able to find it in the manual distributed with the program. > >> +this value will be @code{"0"}. >> + >> +@item powered >> +Is @code{"1"} if the computer on which @command{apcupsd} is running is >> +powered by the UPS and @code{"0"} if not. At the moment, this value is >> +unimplemented and always @code{"0"}. >> + >> +@item (err @var{fmt} @var{args...}) >> +Wrapper around @code{format} outputting to @code{(current-error-port)}. >> + >> +@item (wall @var{fmt} @var{args...}) >> +Wrapper around @code{format} outputting via @command{wall}. >> + >> +@item (apcupsd @var{args...}) >> +Call @command{apcupsd} while passing the correct configuration file and >> +all the arguments. >> + >> +@item (mail-to-root @var{subject} @var{body}) >> +Send an email to the local administrator. This procedure assumes the >> +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} >> +(as would be the case with @code{opensmtpd-service-type}). >> + >> +@end table >> + >> +Available @code{apcupsd-event-handlers} fields are: >> + >> +@table @asis >> +@item @code{killpower} (type: gexp) >> +Handler for killpower event. >> + >> +@item @code{commfailure} (type: gexp) >> +Handler for commfailure event. >> + >> +@item @code{commok} (type: gexp) >> +Handler for commfailure event. >> + >> +@item @code{powerout} (type: gexp) >> +Handler for powerout event. >> + >> +@item @code{onbattery} (type: gexp) >> +Handler for onbattery event. >> + >> +@item @code{offbattery} (type: gexp) >> +Handler for offbattery event. >> + >> +@item @code{mainsback} (type: gexp) >> +Handler for mainsback event. >> + >> +@item @code{failing} (type: gexp) >> +Handler for failing event. >> + >> +@item @code{timeout} (type: gexp) >> +Handler for timeout event. >> + >> +@item @code{loadlimit} (type: gexp) >> +Handler for loadlimit event. >> + >> +@item @code{runlimit} (type: gexp) >> +Handler for runlimit event. >> + >> +@item @code{doreboot} (type: gexp) >> +Handler for doreboot event. >> + >> +@item @code{doshutdown} (type: gexp) >> +Handler for doshutdown event. >> + >> +@item @code{annoyme} (type: gexp) >> +Handler for annoyme event. >> + >> +@item @code{emergency} (type: gexp) >> +Handler for emergency event. >> + >> +@item @code{changeme} (type: gexp) >> +Handler for changeme event. >> + >> +@item @code{remotedown} (type: gexp) >> +Handler for remotedown event. >> + >> +@item @code{startselftest} (type: gexp) >> +Handler for startselftest event. >> + >> +@item @code{endselftest} (type: gexp) >> +Handler for endselftest event. >> + >> +@item @code{battdetach} (type: gexp) >> +Handler for battdetach event. >> + >> +@item @code{battattach} (type: gexp) >> +Handler for battattach event. >> + >> +@end table >> + >> +@end deftp > > nitpick: I'd remove the newline between the two @end above (I know, it > gets generated this way...). Done. > >> +;;; Copyright (C) 2025 Tomas Volf <~@wolfsden.cz> > > We use the unicode symbol (=C2=A9) for copyright throughout Guix; please = use > it too, for uniformity. So =C2=A9 is fine, but =CE=BB is not. I fail to see the consistency. (But of course adjusted, it is just that I do not get the difference.) > >> + >> +;;;; Commentary: >> + >> +;;; Power-related services. >> + >> +;;;; Code: >> + >> +(define-module (gnu services power) >> + #:use-module (srfi srfi-1) >> + #:use-module (srfi srfi-26) >> + #:use-module (ice-9 match) >> + #:use-module (gnu) >> + #:use-module (gnu packages admin) >> + #:use-module (gnu packages linux) >> + #:use-module (gnu packages power) >> + #:use-module (gnu services) >> + #:use-module (gnu services configuration) >> + #:use-module (gnu services shepherd) >> + #:use-module (guix packages) >> + #:use-module (guix records) > > Please order lexicographically (that is, alphabetically but on things > which are not necessarily words :-)). Interesting. I personally order imports lexicographically, but within groups of: 1. stdlib (srfi, rnrs, ...) 2. guile extensions (ice-9, ...) 3. 3rd-party dependencies (guile-lib, guile-json, ...) 4. modules from the program itself (gnu, guix, ...) Given your requirement for sorting everything lexicographically (with no grouping), the following: =2D-8<---------------cut here---------------start------------->8--- (use-modules (gnu services) (srfi srfi-1)) (when #f (modify-services '() (delete 'x))) =2D-8<---------------cut here---------------end--------------->8--- Prints a warning when compiled: =2D-8<---------------cut here---------------start------------->8--- WARNING: (guile-user): imported module (gnu services) overrides core bindin= g `delete' =2D-8<---------------cut here---------------end--------------->8--- However, when done "my" way (putting srfi-1 first, since "stdlib"), the warning goes away. This is not really issue here, since I am not using modify-services, the warning is not printed (I have no idea why). But since in general order of imports seem to matter, I wonder whether mandating global order is a good idea. What are your thoughts here? > >> + #:export (apcupsd-service-type >> + >> + apcupsd-configuration >> + apcupsd-configuration-package >> + apcupsd-configuration-shepherd-base-name >> + apcupsd-configuration-auto-start? >> + apcupsd-configuration-pid-file >> + apcupsd-configuration-debug-level >> + apcupsd-configuration-run-dir >> + apcupsd-configuration-name >> + apcupsd-configuration-cable >> + apcupsd-configuration-type >> + apcupsd-configuration-device >> + apcupsd-configuration-poll-time >> + apcupsd-configuration-on-batery-delay >> + apcupsd-configuration-battery-level >> + apcupsd-configuration-remaining-minutes >> + apcupsd-configuration-timeout >> + apcupsd-configuration-annoy-interval >> + apcupsd-configuration-annoy-delay >> + apcupsd-configuration-no-logon >> + apcupsd-configuration-kill-delay >> + apcupsd-configuration-net-server >> + apcupsd-configuration-net-server-ip >> + apcupsd-configuration-net-server-port >> + apcupsd-configuration-net-server-events-file >> + apcupsd-configuration-net-server-events-file-max-size >> + apcupsd-configuration-class >> + apcupsd-configuration-mode >> + apcupsd-configuration-stat-time >> + apcupsd-configuration-log-stats >> + apcupsd-configuration-data-time >> + apcupsd-configuration-facility >> + apcupsd-configuration-event-handlers >> + >> + apcupsd-event-handlers-annoyme >> + apcupsd-event-handlers-battattach >> + apcupsd-event-handlers-battdetach >> + apcupsd-event-handlers-changeme >> + apcupsd-event-handlers-commfailure >> + apcupsd-event-handlers-commok >> + apcupsd-event-handlers-doreboot >> + apcupsd-event-handlers-doshutdown >> + apcupsd-event-handlers-emergency >> + apcupsd-event-handlers-endselftest >> + apcupsd-event-handlers-failing >> + apcupsd-event-handlers-killpower >> + apcupsd-event-handlers-loadlimit >> + apcupsd-event-handlers-mainsback >> + apcupsd-event-handlers-offbattery >> + apcupsd-event-handlers-onbattery >> + apcupsd-event-handlers-powerout >> + apcupsd-event-handlers-remotedown >> + apcupsd-event-handlers-runlimit >> + apcupsd-event-handlers-startselftest >> + apcupsd-event-handlers-timeout)) >> + >> +(define-configuration/no-serialization apcupsd-event-handlers >> + (killpower >> + (gexp >> + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) >> + (sleep 10) >> + (apcupsd "--killpower") >> + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name)= )) >> + "Handler for killpower event.") > > In many places in your writing, I find that it skips adding 'the' > (definite article), which I've learned should be use when describing > something specific, such as here with the specific handlers: > > "Handler for the @code{killpower} event." > > In case it helps, I've found this page seems useful in briefly > explaining when to use 'the' [0]. > > [0] https://owl.purdue.edu/owl/general_writing/grammar/using_articles.ht= ml Yeah I always have a problem with these. My mother tongue does not have this concept at all, so it is bit hard for me. Thank you for the link, it was useful. I went through the texts and tried to add them where I felt they were missing, you are right, there were a lot of them missing. > >> + (commfailure >> + (gexp >> + #~((let ((msg (format #f "~a Communications with UPS ~a lost." >> + (gethostname) name))) >> + (mail-to-root msg msg)) >> + (wall "Warning: communications lost with UPS ~a" name))) >> + "Handler for commfailure event.") >> + (commok >> + (gexp >> + #~((let ((msg (format #f "~a Communications with UPS ~a restored." >> + (gethostname) name))) >> + (mail-to-root msg msg)) >> + (wall "Communications restored with UPS ~a" name))) >> + "Handler for commfailure event.") >> + (powerout >> + (gexp >> + #~(#t)) >> + "Handler for powerout event.") >> + (onbattery >> + (gexp >> + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" >> + (gethostname) name))) >> + (mail-to-root msg msg)) >> + (wall "Power failure on UPS ~a. Running on batteries." name))) >> + "Handler for onbattery event.") >> + (offbattery >> + (gexp >> + #~((let ((msg (format #f "~a UPS ~a Power has returned." >> + (gethostname) name))) >> + (mail-to-root msg msg)) >> + (wall "Power has returned on UPS ~a..." name))) >> + "Handler for offbattery event.") >> + (mainsback >> + (gexp >> + #~((when (file-exists? powerfail-file) >> + (wall "Continuing with shutdown.")))) >> + "Handler for mainsback event.") >> + (failing >> + (gexp >> + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name= ))) >> + "Handler for failing event.") >> + (timeout >> + (gexp >> + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." = name))) >> + "Handler for timeout event.") >> + (loadlimit >> + (gexp >> + #~((wall "Remaining battery charge below limit on UPS ~a. Doing sh= utdown." name))) >> + "Handler for loadlimit event.") >> + (runlimit >> + (gexp >> + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing s= hutdown." name))) >> + "Handler for runlimit event.") >> + (doreboot >> + (gexp >> + #~((wall "UPS ~a initiating Reboot Sequence" name) >> + (system* #$(file-append shepherd "/sbin/reboot")))) >> + "Handler for doreboot event.") >> + (doshutdown >> + (gexp >> + #~((wall "UPS ~a initiated Shutdown Sequence" name) >> + (system* #$(file-append shepherd "/sbin/halt")))) >> + "Handler for doshutdown event.") >> + (annoyme >> + (gexp >> + #~((wall "Power problems with UPS ~a. Please logoff." name))) >> + "Handler for annoyme event.") >> + (emergency >> + (gexp >> + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a."= name))) >> + "Handler for emergency event.") >> + (changeme >> + (gexp >> + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." >> + (gethostname) name))) >> + (mail-to-root msg msg)) >> + (wall "Emergency! Batteries have failed on UPS ~a. Change them= NOW." name))) >> + "Handler for changeme event.") >> + (remotedown >> + (gexp >> + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) >> + "Handler for remotedown event.") >> + (startselftest >> + (gexp >> + #~(#t)) >> + "Handler for startselftest event.") >> + (endselftest >> + (gexp >> + #~(#t)) >> + "Handler for endselftest event.") >> + (battdetach >> + (gexp >> + #~(#t)) >> + "Handler for battdetach event.") >> + (battattach >> + (gexp >> + #~(#t)) >> + "Handler for battattach event.")) > > Sounds fun :-). I was wondering if the handlers could be of the > maybe-gexp type, and when not provided the handler would not be called > at all? Or does the design of apcupsd mandates that all handlers be > defined? The control script is called for all events. So I *could* use maybe-gexp, and change =2D-8<---------------cut here---------------start------------->8--- ("battattach" #$@(apcupsd-event-handlers-battattach (apcupsd-configuration-event-handlers cfg))) =2D-8<---------------cut here---------------end--------------->8--- into =2D-8<---------------cut here---------------start------------->8--- ("battattach" #$@(let ((h (apcupsd-event-handlers-battattach (apcupsd-configuration-event-handlers cfg)))) (if (maybe-value-set? h) h #~(#t)))) =2D-8<---------------cut here---------------end--------------->8--- and do that for all the events. But I have to admit I do not consider that an improvement. There probably is a better way to express that, but the current approach (of always having, possibly NOP, handler defined) helps keep the code straight forward. > >> +(define-syntax define-enum >> + (lambda (x) >> + (syntax-case x () >> + ((_ name values) >> + (let* ((d/n (syntax->datum #'name)) >> + (d/predicate (string->symbol >> + (format #f "enum-~a?" d/n))) >> + (d/serialize (string->symbol >> + (format #f "serialize-enum-~a" d/n)))) > > Even for internal bindings, better variable names would help reading the > code. > When I am writing syntax-case, I always struggle with the naming, since I effectively have to have two variables for a single thing. One for datum, and one for syntax. I have expanded the d/ info full datum/, however if can suggest better naming scheme for situations like this, I am all ears. >> + (with-syntax >> + ((predicate (datum->syntax x d/predicate)) >> + (serialize (datum->syntax x d/serialize))) >> + #'(begin >> + (define (predicate value) >> + (memq value values)) >> + (define serialize serialize-symbol)))))))) > > That is a nice minimal enum for using with define-configuration. Note > that Guile has some kind of very limited enum from (rnrs enums), but I > don't think they'd be too useful here. See for example > 'make-enumeration' from (rnrs enums), which I used in for the > ntp-server-types in (gnu services networking). > >> +(define mangle-field-name >> + (match-lambda >> + ('name "UPSNAME") >> + ('cable "UPSCABLE") >> + ('type "UPSTYPE") >> + ('device "DEVICE") >> + ('poll-time "POLLTIME") >> + ('lock-dir "LOCKFILE") >> + ('power-fail-dir "PWRFAILDIR") >> + ('no-login-dir "NOLOGINDIR") >> + ('on-batery-delay "ONBATTERYDELAY") >> + ('battery-level "BATTERYLEVEL") >> + ('remaining-minutes "MINUTES") >> + ('timeout "TIMEOUT") >> + ('annoy-interval "ANNOY") >> + ('annoy-delay "ANNOYDELAY") >> + ('no-logon "NOLOGON") >> + ('kill-delay "KILLDELAY") >> + ('net-server "NETSERVER") >> + ('net-server-ip "NISIP") >> + ('net-server-port "NISPORT") >> + ('net-server-events-file "EVENTSFILE") >> + ('net-server-events-file-max-size "EVENTSFILEMAX") >> + ('class "UPSCLASS") >> + ('mode "UPSMODE") >> + ('stat-time "STATTIME") >> + ('stat-file "STATFILE") >> + ('log-stats "LOGSTATS") >> + ('data-time "DATATIME") >> + ('facility "FACILITY"))) >> + >> +(define (serialize-string field-name value) >> + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) >> +(define serialize-symbol serialize-string) >> +(define serialize-integer serialize-string) >> +(define (serialize-boolean field-name value) >> + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) #$(if value "= on" "off"))) > > You'll want to break the above line. Done. > >> + >> +(define-maybe string) >> + >> +(define-enum cable '( simple smart ether usb >> + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C >> + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G >> + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02= -2000)) >> +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus tes= t)) >> +(define-enum no-logon '(disable timeout percent minutes always)) >> +(define-enum class '(standalone shareslave sharemaster)) >> +(define-enum mode '(disable share)) >> + >> +(define-configuration apcupsd-configuration >> + (package (package apcupsd) "Package to use.") > > Please stick to the convention where the name of the package is the name > of the field used to specify such package (here: apcupsd). Done. > >> + (shepherd-base-name >> + (symbol 'apcupsd) >> + "Base name of the shepherd service. You can add the service multipl= e times >> +with different prefix to manage multiple UPSes." >> + empty-serializer) >> + (auto-start? >> + (boolean #t) >> + "Should the shepherd service auto-start?" >> + empty-serializer) >> + (pid-file >> + (string "/var/run/apcupsd.pid") > > /var/run -> /run (adjust everywhere) See the reaction above regarding the /var/run. > >> + "Path to the pid file." > > I'm repeating myself because I reviewed the texi produced from this, but > yeah, s/path/file name/, and make sure to adjust the rest of the > comments I made for the .texi in the source (I'd just edit the source > and regenerate the doc from it). > > [...] Done (as part of the texi modification). > > >> +(define (s/apccontrol cfg) > > what is the 's/' prefix for in the procedure name? 'serialize'? Spell > this out in full to be clear rather than cryptic (that's a convention > followed at large in general in Scheme). The s/ was supposed to stand for script/, I originally expected I will have more than one. I have renamed it to %apccontrol. > >> + (program-file >> + "apccontrol" >> + #~(begin >> + (use-modules (srfi srfi-9) >> + (ice-9 format) >> + (ice-9 match) >> + (ice-9 popen)) > > Please sort modules lexicographically. See the reaction above. > >> + ;; Script dir depends on these, and the configuration depends on= the script >> + ;; dir. To sever the cyclic dependency, pass the paths via envi= ronment >> + ;; variables. >> + (define conf (getenv "GUIX_APCUPSD_CONF")) >> + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) >> + >> + (define (err . args) >> + (apply format (current-error-port) args)) >> + (define (wall . args) >> + (system* #$(file-append util-linux "/bin/wall") (apply format = #f args))) >> + (define (apcupsd . args) >> + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" co= nf args)) >> + (define (mail-to-root subject body) >> + (let ((port (open-pipe* OPEN_WRITE >> + "/run/privileged/bin/sendmail" >> + "-F" "apcupsd" >> + "root"))) >> + (format port "Subject: ~a~%~%~a~&" subject body) >> + (close-pipe port))) >> + (match (cdr (command-line)) >> + (((? string? cmd) name connected powered) >> + (match cmd >> + ;; I am sure this could be done by macro, but meh. Last re= lease of >> + ;; apcupsd was in 2016, so maintaining this will not be muc= h work. >> + ("killpower" >> + #$@(apcupsd-event-handlers-killpower >> + (apcupsd-configuration-event-handlers cfg))) >> + ("commfailure" >> + #$@(apcupsd-event-handlers-commfailure >> + (apcupsd-configuration-event-handlers cfg))) >> + ("commok" >> + #$@(apcupsd-event-handlers-commok >> + (apcupsd-configuration-event-handlers cfg))) >> + ("powerout" >> + #$@(apcupsd-event-handlers-powerout >> + (apcupsd-configuration-event-handlers cfg))) >> + ("onbattery" >> + #$@(apcupsd-event-handlers-onbattery >> + (apcupsd-configuration-event-handlers cfg))) >> + ("offbattery" >> + #$@(apcupsd-event-handlers-offbattery >> + (apcupsd-configuration-event-handlers cfg))) >> + ("mainsback" >> + #$@(apcupsd-event-handlers-mainsback >> + (apcupsd-configuration-event-handlers cfg))) >> + ("failing" >> + #$@(apcupsd-event-handlers-failing >> + (apcupsd-configuration-event-handlers cfg))) >> + ("timeout" >> + #$@(apcupsd-event-handlers-timeout >> + (apcupsd-configuration-event-handlers cfg))) >> + ("loadlimit" >> + #$@(apcupsd-event-handlers-loadlimit >> + (apcupsd-configuration-event-handlers cfg))) >> + ("runlimit" >> + #$@(apcupsd-event-handlers-runlimit >> + (apcupsd-configuration-event-handlers cfg))) >> + ("doreboot" >> + #$@(apcupsd-event-handlers-doreboot >> + (apcupsd-configuration-event-handlers cfg))) >> + ("doshutdown" >> + #$@(apcupsd-event-handlers-doshutdown >> + (apcupsd-configuration-event-handlers cfg))) >> + ("annoyme" >> + #$@(apcupsd-event-handlers-annoyme >> + (apcupsd-configuration-event-handlers cfg))) >> + ("emergency" >> + #$@(apcupsd-event-handlers-emergency >> + (apcupsd-configuration-event-handlers cfg))) >> + ("changeme" >> + #$@(apcupsd-event-handlers-changeme >> + (apcupsd-configuration-event-handlers cfg))) >> + ("remotedown" >> + #$@(apcupsd-event-handlers-remotedown >> + (apcupsd-configuration-event-handlers cfg))) >> + ("startselftest" >> + #$@(apcupsd-event-handlers-startselftest >> + (apcupsd-configuration-event-handlers cfg))) >> + ("endselftest" >> + #$@(apcupsd-event-handlers-endselftest >> + (apcupsd-configuration-event-handlers cfg))) >> + ("battdetach" >> + #$@(apcupsd-event-handlers-battdetach >> + (apcupsd-configuration-event-handlers cfg))) >> + ("battattach" >> + #$@(apcupsd-event-handlers-battattach >> + (apcupsd-configuration-event-handlers cfg))) >> + (_ >> + (err "Unknown event: ~a~%" cmd) >> + (err "Iff the event was passed by apcupsd, this is a bug.~= %") > > s/Iff/If/, I think `Iff' is used correctly here, no? > perhaps s/passed/emitted/. Sure, why not. > I don't understand, in which scenario would an event *not* be emitted > by apcupsd? If you call the script manually from command line. ^_^ > >> + (err "Please report to bug-guix@gnu.org.~%") >> + (exit #f)))) >> + (args >> + (err "Unknown arguments: ~a~%" args) >> + (err "Iff the arguments were passed by apcupsd, this is a bug= .~%") > > s/Iff/If/ Same here. >> + (err "Please report to bug-guix@gnu.org.~%") >> + (exit #f)))))) >> + >> +(define (apcupsd-script-dir cfg) > > s/cfg/config/ Done. > >> + (computed-file >> + "apcupsd-script-dir" >> + #~(begin >> + (mkdir #$output) >> + (chdir #$output) >> + (symlink #$(s/apccontrol cfg) "apccontrol")))) >> + >> +(define (apcupsd-config-file cfg) > > s/cfg/config/ Done. > >> + (let ((run-dir (apcupsd-configuration-run-dir cfg))) >> + (mixed-text-file >> + "apcupsd.conf" >> + "\ >> +## apcupsd.conf v1.1 ## >> +# >> +# for apcupsd release 3.14.14 (31 May 2016) - GNU Guix > > Is this config really bound to a version like above? Unless they change > things in backward incompatible ways, it should work for newer ones too, > no? This file header is taken from the official configuration file distributed with the apcupsd (except the GNU Guix part). So while I do expect that this configuration file should work with newer version, the upstream decided to put the version into the configuration file. I have no strong opinion either way here, should I just remove the file header completely? > >> +# >> +# \"apcupsd\" POSIX config file (crafted via apcupsd-service-type) > > s/crafted via/auto-generated by/ But, but, "crafted" sound way more fancy. :) Well, replaced anyway. However I have used just "generated by", the "auto-" part felt bit off. > >> +" >> + (serialize-configuration cfg apcupsd-configuration-fields) >> + ;; This one is confusing. The manual page states: >> + ;; >> + ;; > It must be changed when running more than one copy of apcupsd= on the >> + ;; > same computer to control multiple UPSes. >> + ;; >> + ;; However would you not want the lock to be per-device, not per-p= rocess? >> + ;; I decided to follow the documentation, but I do not understand = why it >> + ;; should be like this. I do not have multiple UPSes to try. >> + (serialize-string 'lock-dir (string-append run-dir "/lock")) >> + (serialize-string 'power-fail-dir run-dir) >> + (serialize-string 'no-login-dir run-dir) >> + (serialize-string 'stat-file (string-append run-dir "/apcupsd.stat= us")) >> + "SCRIPTDIR " (apcupsd-script-dir cfg) "\n"))) >> + >> +(define (apcupsd-shepherd-services cfg) > > s/cfg/config/ And done. > >> + (match-record cfg >> + ( package pid-file debug-level run-dir > ^ extraneous space This is intentional, it is neat little trick I have learned recently. Without the extra leading space, Emacs indents it in this way: =2D-8<---------------cut here---------------start------------->8--- (match-record config (apcupsd pid-file debug-level run-dir shepherd-base-name auto-start?) =2D-8<---------------cut here---------------end--------------->8--- However, with the extra leading space, the indentation changes to: =2D-8<---------------cut here---------------start------------->8--- (match-record config ( apcupsd pid-file debug-level run-dir shepherd-base-name auto-start?) =2D-8<---------------cut here---------------end--------------->8--- Since in this case it is not a procedure call, but a list, first member (apcupsd) is not special in any way. So it feels weird for it to have a special priority regarding the indentation. With the extra leading space, all list members are equal, as they should be. > >> + shepherd-base-name auto-start?) >> + (let* ((config-file (apcupsd-config-file cfg)) >> + (s/ shepherd-base-name) > > Please improve the variables names a bit; what is 's/' ? I removed them completely, with activation-service-type they are not needed at all now. > >> + (s/run-dirs (string->symbol (format #f "~a-run-dirs" s/)))) >> + (list >> + (shepherd-service >> + (documentation "Create the run directories.") >> + (provision (list s/run-dirs)) >> + (one-shot? #t) >> + (auto-start? auto-start?) >> + (start #~(lambda _ >> + ((@ (guix build utils) mkdir-p) >> + #$(string-append run-dir "/lock")) >> + #t))) > > Is there a reason why this is not done in an activation script instead? > That's more conventional, I think. The reason is simple, I forgot that activation-service-type exists. ^_^ I have converted the code to use it. > >> + (shepherd-service >> + (documentation "Run apcupsd daemon.") > > Run *the* apcupsd daemon. Done. > >> + (requirement (list s/run-dirs)) >> + (provision (list s/)) >> + (auto-start? auto-start?) >> + (start #~(make-forkexec-constructor >> + '(#$(file-append package "/sbin/apcupsd") >> + "-b" ; Do not daemonize. > > If you want, margin comments are ok without space or full sentence > (punctuation), e.g.: > > ;do not daemonize I have no strong preference. What is the convention in Guix/Guile community? Or is this down to each individual programmer? > > >> + "-f" #$config-file >> + "-P" #$pid-file >> + "-d" #$(number->string debug-level)) >> + #:log-file >> + #$(format #f "/var/log/~a.log" shepherd-base-name) >> + #:environment-variables >> + (cons* (string-append "GUIX_APCUPSD_CONF=3D" >> + #$config-file) >> + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE= =3D" >> + run-dir "/powerfail") >> + (default-environment-variables)))) >> + (stop #~(make-kill-destructor)) >> + (actions (list (shepherd-configuration-action config-file))))))= )) >> + >> +(define (apcupsd-pam-extensions cfg) > > s/cfg/config/ Done. > >> + (define pam-nologin > > A comment explaining why this PAM extention is required would be helpful > (I have no idea myself -- but I must confess: PAM is still a bit of a > mystery to me). I have added: =2D-8<---------------cut here---------------start------------->8--- ;; The apcupsd can be configured to prevent users from logging in on cert= ain ;; conditions. This is implemented by creation of a "nologin" file, and ;; using a pam nologin module to prevent the login (if the file exists). =2D-8<---------------cut here---------------end--------------->8--- > >> + (pam-entry >> + (control "required") >> + (module "pam_nologin.so") >> + (arguments (list (string-append "file=3D" >> + (apcupsd-configuration-run-dir cfg) >> + "/nologin"))))) >> + >> + (list (pam-extension >> + (transformer >> + (lambda (pam) >> + (pam-service >> + (inherit pam) >> + (auth (cons pam-nologin (pam-service-auth pam))))))))) >> + >> +(define apcupsd-service-type >> + (service-type >> + (name 'apcupsd) >> + (description "Configure and optionally start apcupsd.") >> + (extensions (list (service-extension shepherd-root-service-type >> + apcupsd-shepherd-services) >> + (service-extension pam-root-service-type >> + apcupsd-pam-extensions))) >> + (compose identity) >> + (extend (=CE=BB (cfg lst) > > nitpick: There was a stylistic choice to prefer lambda instead of =CE=BB = in > the Guix code base to try to make it more accessible at some point. Nice, thanks for catching it. I am aware, but sometimes I miss one or two when copying code from my channel. > >> + (fold (cut <> <>) cfg lst))) >> + (default-value (apcupsd-configuration)))) > > Thanks for this very complete, carefully and thoughtfully crafted > contribution. As you can see, the only comments I had were mostly > nitpicks and small details. I look forward to the next revision. And thank you for the very thorough review. It is mostly details, but it still surprised me how many I have managed to get wrong. Thanks, Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmexDl0OHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wam6eg//ZsdLZ9t5dVF3UsGAkiXLAxEC9mX4NJeUA5Qk eRvqxLPdsJmm0IJCNBmwo7fmwFyjseHO0yCGgW6S4LtwJ0zFMNDjKaOGp1a99Qqz h6XTlh5EzXUKP9Z3NGyDpLVjVhSMY3cTkKLdnmn7wk2hnh9wehAdjeevy133yvS3 GhuRAydKE9V6uqiEqAq+CL8K30ARZL7RZQf1SZpTZTil+6DMOliw25grPMR9D48a Vn3XrVrpE5P+nTf9RXD2+3lPfMMaEyrsVtwpWyEYBiL4/QadK5ZglNsm0ljsEh2Q /ubmZ4n57cS8QXOiETq+RaUg0uAL3nlmoRnryu772bst19y7G7swOVYD44JFxyyi fBriRudZTlNE22c4haFeCyXsnxi1UB4uz8MMYNDPvh39qdvL3xA+QbHKAPNhOCsB ZfJuNRXw4XndphDXX7nAC1Qv1zs5oZrpUFuUTgQwXqsbQ9eoJJqNUdafkbdxlW9x HDcJVi5L4Y8N/ZYhacHFDr+GBw4ql7jez0mDGUZux3OScpMPS3DDAdNkk4Pqo79a MQPOQPV+cxqfLyY3dsuqofP+VKdzVIX+KAerJvTivjFjwbbw9IbG8kaNZuv5PA1P jMs8dgRDdMDQ8thO+h0ktLnPNAx4tQFCvxxywpgg0VgQdxhZb5Dp1jzq21QmrLzM wboDN48= =7Re+ -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 16 Feb 2025 05:34:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173968401116943 (code B ref 75528); Sun, 16 Feb 2025 05:34:02 +0000 Received: (at 75528) by debbugs.gnu.org; 16 Feb 2025 05:33:31 +0000 Received: from localhost ([127.0.0.1]:59478 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjXHU-0004P8-5k for submit@debbugs.gnu.org; Sun, 16 Feb 2025 00:33:31 -0500 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]:57347) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tjXHQ-0004Oo-JJ for 75528@debbugs.gnu.org; Sun, 16 Feb 2025 00:33:26 -0500 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-22114b800f7so7797735ad.2 for <75528@debbugs.gnu.org>; Sat, 15 Feb 2025 21:33:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739683998; x=1740288798; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tDzB3OHvVW9oAzv2C5HlGEkIGUThVapy4nM5jCaUbCw=; b=Yc1b49mqFCw2rJLoA/uQrRMq8pihbxH+wsOYf5njGHw4fsYdQ7M87X1AIL+XQWhC/F GaVi3QOD7dczP5fPBOX5AZzF191MSP9Hhxv8NK7qfnyqWv72ntY6joNPHo14I9/L4sti 92qBr/dAgKA3uC/lGSMUqHKZQYIvXCDk0pMt15JPOnRIS/Iggp5J6Rvi4lSn7WXclbzM 5Npuo5xt5xcB2Sl6bGuI6xKS19OiCGlIIJdOJ/S1Z1tBGuY9R27U3PMv/HqwY037xnxH QXCy+PCj7tVhd/BDhBmONvpmKzVNpEWDKO9ErrGKSW8mmiAgdyhAvOo5ymtDGAgjIy+8 hacg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739683998; x=1740288798; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=tDzB3OHvVW9oAzv2C5HlGEkIGUThVapy4nM5jCaUbCw=; b=wWqVWU+yyerHRvnWGn1CSikbItGmWz8oJMTHvv8us0GA2OBak/snZlVm/n88DpdEwy 9Um3qsWRcSc1Oo0jd2cm8szLLFVuKeRuQMJ5tTUb/OvsWMdWAF0pHrKLrNeiWCeykVnp OUdUnPxdPHklLYgNiASJ76sSo2b3B24wiP2CiF8o77peMsWI9X577+X7IJeAFrtxG5xD Gd0FHdZ58PG+40YYjhgUp6NLsDj2ZZVfK6b6kQB1flHBkiez6WahIJr5U/RGF4ju6sdj wwwGkYsEHKJoEHVbYeFA6rX5RMgDmgyrpxWhuajdIenxSWOOQnJOp9jiwGWHH19skoF1 L/Fg== X-Gm-Message-State: AOJu0YwtYtRRFxSJNF/FwgnkrOhXUqdMbs8/kO9NiyBJlT1In+daX78M Y19zNVAjvZQdf97T2F865m6WUDS0c7roNfzSctkKj/h2GfftaHF7Bu+iKA== X-Gm-Gg: ASbGncveOndW6+4grmaqUrAiGDMdFV+lWTQfzryhjuPqJEtH5Cv71U5JXTrRU05avL5 H4AX+ZQ10YnOrF6R6mG8Et1nphG5xZE6/501QzIBf3R8+xRFyH+XPNNX3IiKRnWTZ3rZJWHYsHm yutqWbQHimtOfg7NHdeB/d4/ST+CgwYFFheGkF0NGvNhuiaFxAwhB9caf0E3/hxvM5Kz0kJumfb GFC7Qkog2/JpjOqHWCjIVVGryEoW0ki1bcXp5DHThdabqfmiO5Lin9pELlEwEPz71ZAavwCqLE/ voZNbZ2yKYB/ X-Google-Smtp-Source: AGHT+IEpLw1onp2P3hygGpxwVSe2KaqvXFNa+RPXEPSaKLQ/Sz/kgbF0w/Hh8V8AHeuMbW4vkITzOQ== X-Received: by 2002:a17:902:b189:b0:216:69ca:7714 with SMTP id d9443c01a7336-22103f0505cmr62569685ad.11.1739683997732; Sat, 15 Feb 2025 21:33:17 -0800 (PST) Received: from terra ([2405:6586:be0:0:c8ff:1707:9b9:af89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d5584dfbsm50690175ad.213.2025.02.15.21.33.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Feb 2025 21:33:16 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <874j0u7tsy.fsf@wolfsden.cz> (Tomas Volf's message of "Sat, 15 Feb 2025 22:59:57 +0100") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> <878qqk8q96.fsf@gmail.com> <874j0u7tsy.fsf@wolfsden.cz> Date: Sun, 16 Feb 2025 14:33:05 +0900 Message-ID: <878qq678tq.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: [...] >> I see there's already a gnu/services/pm.scm file; it seems we don't need >> another one? Or was it a conscious decision? > > Yes, it was intentional, for couple of reasons (in no particular order). > > I like the symmetry between gnu/{packages,services}/power.scm. It makes > finding the service-type easy without even opening the manual. > > The "pm" is for "power management", and I have never heard anyone call > apcupsd "a power management daemon". It reacts to power outage, true, > but it does not "manage" the power in any way. So it seemed like a poor > fit. > > The current pm.scm exports 8 bindings, the new power.scm 54. So it > would feel like taking over the file. OK, that's reasonable, let's keep it (gnu services power). > Shorter files are faster to compile (especially when > define-configuration is used), so having two files that can be built in > parallel seemed better. > > And like this I can also write the changelog in to the commit message in > a reasonably short form. If I put it into pm.scm, I would need to list > every single binding, in power.scm I mention just a new file. Haha, yes, the last point is a funny 'loophole' of the change log format. Change a couple things to a package? Needs a lot of description. Add a new package? Two words suffice :-). It's reasonable though (but still funny). [...] >>> + >>> +@item @code{auto-start?} (default: @code{#t}) (type: boolean) >>> +Should the shepherd service auto-start? >>> + >>> +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: = string) >>> +Path to the pid file. >> >> All file names becoming /run/ prefixed instead of /var/run, based on a >> previous comment. > > I will just quote myself from the package's patch, since it seems I did > not get an answer there: > > It seems pretty much all programs on my system are using /var/run, > including Shepherd. Only programs that store information in /run seem > to be elogind and dbus. > > Is deprecation of /var/run listed somewhere in the manual? I am > surprised Shepherd (since it is actively maintained and core component) > is still in /var/run. I looked and found 42 references to /var/run, but > none with the deprecation notice. > > Assuming you will insist on moving it to /run, is there some structure > to follow in that directory? Or just s~/var/run~/run~? What about /var > and /var/log? Should those be moved somewhere as well? Deprecating /var/run to /run is not a Guix thing, but a File Hiearchy Standard (FHS) thing [0]. Since we already use /run, there's no good reason to have /var/run something else than a symlink to /run, and there's an actual change pending merge that would do that, along making /run mounted as a tmpfs (bug#73494). [0] https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s13.html > > Thanks. > >> >> We don't use path in GNU to denote file names, we use 'file names'. >> That's mentioned in info '(standards) GNU Manuals': >> >> Please do not use the term "pathname" that is used in Unix >> documentation; use "file name" (two words) instead. We use the term >> "path" only for search paths, which are lists of directory names. >> > > Changed into "File name of the pid file.". nitpick: s/pid/PID/ > Out of curiosity, does this apply to directories as well? So, > hypothetically, I should instead of "Path to the directory storing XY." > use "File name of the directory storing XY."? Since a directory is implicitly a file, you can just say 'Directory storing XY.' >>> + >>> +@item @code{debug-level} (default: @code{0}) (type: integer) >>> +Logging verbosity. Bigger number means more logs. In the source code= I >>> +saw up to @code{300}, so for all logs, @code{999} seems reasonable. >> >> I think it's best to not use first person pronoun in the manual to keep >> it a bit more formal. So instead of 'I saw', this could be reworded to: >> 'The source code uses up to @code{300} as debug level value, so a value >> of @code{999} seems reasonable to enable all logs.' or similar. > > Sorry, I have probably gotten too influenced by (gnus) and its personal > style I have enjoyed a lot. > > I have used your suggestion verbatim. Opinions seem to vary on which style is best, but in Guix I'm pretty sure we've stuck to what I've described for the most part until now, so we should continue, for consistency. [...] > Done. I went back to the package and replaced it there as well. It is > bit unfortunate that autotools call the variables `ac_cv_path_', instead > of `ac_cv_file_name_', but nothing I can do about that. That's funny; the 'standards' Texinfo manual comes from autoconf, and is the one documenting one. But autoconf is old, perhaps that guide line was clarified later. [...] >> Also, any reason why these integer values are expressed as strings? > > No. I have just adhered to the original calling convention of the shell > script, and argv is all char*. These are even not really an integer > values, but bools. So I changed this one to `connected?', and the other > one to `powered?', with #t/#f values. > >> >>> +USB port). In most configurations, this will be the case. In the case >>> +of a Slave machine where apcupsd is not directly connected to the UPS, >> >> s/Slave/slave/ ? Could be nicer to use a neutral alternative like >> 'follower machine'. > > The "Slave machine" (including the capitalization) is a term used in the > manual. I can lower-case it if you would prefer, seems that manual > actually uses both casings now when I looked for it. > > I do not think inventing new terminology is a good idea, since users > will not be able to find it in the manual distributed with the program. The 'slave' word always carry a negative connotation. I think it's a good idea to be proactive on modernizing the terminology where we can. [...] >> We use the unicode symbol (=C2=A9) for copyright throughout Guix; please= use >> it too, for uniformity. > > So =C2=A9 is fine, but =CE=BB is not. I fail to see the consistency. I guess that could be explained somewhere along those lines: - =CE=BB is used in code; newcomers could be confused as to what it means, = or have to copy-paste it around thinking it's required by the syntax to define anonymous procedures (while it's not -- they can just type 'lambda'). - =C2=A9 is just a widely understood symbol used in a text comment. >>> + >>> +;;;; Commentary: >>> + >>> +;;; Power-related services. >>> + >>> +;;;; Code: >>> + >>> +(define-module (gnu services power) >>> + #:use-module (srfi srfi-1) >>> + #:use-module (srfi srfi-26) >>> + #:use-module (ice-9 match) >>> + #:use-module (gnu) >>> + #:use-module (gnu packages admin) >>> + #:use-module (gnu packages linux) >>> + #:use-module (gnu packages power) >>> + #:use-module (gnu services) >>> + #:use-module (gnu services configuration) >>> + #:use-module (gnu services shepherd) >>> + #:use-module (guix packages) >>> + #:use-module (guix records) >> >> Please order lexicographically (that is, alphabetically but on things >> which are not necessarily words :-)). > > Interesting. I personally order imports lexicographically, but within > groups of: > > 1. stdlib (srfi, rnrs, ...) > 2. guile extensions (ice-9, ...) > 3. 3rd-party dependencies (guile-lib, guile-json, ...) > 4. modules from the program itself (gnu, guix, ...) That's similar to what I'd do in C or C++, except I'd reverse it so that I can catch missing includes from my own files. In Guix I've never read we do that. Perhaps it'd make sense. But currently we typically globally sort lexicographically, I think (but many modules imports are in a messy state). > Given your requirement for sorting everything lexicographically (with no > grouping), the following: > > (use-modules (gnu services) > (srfi srfi-1)) > > (when #f > (modify-services '() > (delete 'x))) > > > Prints a warning when compiled: > > WARNING: (guile-user): imported module (gnu services) overrides core bind= ing `delete' > > However, when done "my" way (putting srfi-1 first, since "stdlib"), the > warning goes away. That's an interesting workaround, but I think we should look into that problem and fix it definitely I often used #:hidden (delete) without any issue it seems, so I'm not even sure if its existence still solves a true problem in current Guile. [...] >>> +(define-configuration/no-serialization apcupsd-event-handlers >>> + (killpower >>> + (gexp >>> + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) >>> + (sleep 10) >>> + (apcupsd "--killpower") >>> + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name= ))) >>> + "Handler for killpower event.") >> By the way, why do we need to sleep 10 seconds here? It seems unnecessary. [...] >> Sounds fun :-). I was wondering if the handlers could be of the >> maybe-gexp type, and when not provided the handler would not be called >> at all? Or does the design of apcupsd mandates that all handlers be >> defined? > > The control script is called for all events. So I *could* use > maybe-gexp, and change > > ("battattach" > #$@(apcupsd-event-handlers-battattach > (apcupsd-configuration-event-handlers cfg))) > > > into > > ("battattach" > #$@(let ((h (apcupsd-event-handlers-battattach > (apcupsd-configuration-event-handlers cfg)))) > (if (maybe-value-set? h) > h > #~(#t)))) > > > and do that for all the events. But I have to admit I do not consider > that an improvement. There probably is a better way to express that, > but the current approach (of always having, possibly NOP, handler > defined) helps keep the code straight forward. OK; we could probably script the control script differently, but let's keep what we have so far, it's simple and I doubt performance is an issue ;-). >>> +(define-syntax define-enum >>> + (lambda (x) >>> + (syntax-case x () >>> + ((_ name values) >>> + (let* ((d/n (syntax->datum #'name)) >>> + (d/predicate (string->symbol >>> + (format #f "enum-~a?" d/n))) >>> + (d/serialize (string->symbol >>> + (format #f "serialize-enum-~a" d/n)))) >> >> Even for internal bindings, better variable names would help reading the >> code. >> > > When I am writing syntax-case, I always struggle with the naming, since > I effectively have to have two variables for a single thing. One for > datum, and one for syntax. > > I have expanded the d/ info full datum/, however if can suggest better > naming scheme for situations like this, I am all ears. I'd stick to describe what they really are, e.g. for the enum-$name? symbol, 'predicate-name' or 'predicate-variable-name' instead of d/predicate. When deeply nested, it's OK to abbreviate the names a bit if it becomes difficult to fit in our 80 columns width, so it could be 'pred-var-name' or the likes. [...] >>> + (shepherd-base-name >>> + (symbol 'apcupsd) >>> + "Base name of the shepherd service. You can add the service multip= le times >>> +with different prefix to manage multiple UPSes." >>> + empty-serializer) >>> + (auto-start? >>> + (boolean #t) >>> + "Should the shepherd service auto-start?" >>> + empty-serializer) >>> + (pid-file >>> + (string "/var/run/apcupsd.pid") >> >> /var/run -> /run (adjust everywhere) > > See the reaction above regarding the /var/run. Which I've now covered in my reply above (sorry for missing in in my first replies). [...] > The s/ was supposed to stand for script/, I originally expected I will > have more than one. I have renamed it to %apccontrol. > >> >>> + (program-file >>> + "apccontrol" >>> + #~(begin >>> + (use-modules (srfi srfi-9) >>> + (ice-9 format) >>> + (ice-9 match) >>> + (ice-9 popen)) >> >> Please sort modules lexicographically. > > See the reaction above. I've replied above. I'd suggest to stick to lexicographically sort the whole imports block to stick with current conventions (although I don't think this particular one is documented). >>> + ;; Script dir depends on these, and the configuration depends o= n the script >>> + ;; dir. To sever the cyclic dependency, pass the paths via env= ironment >>> + ;; variables. >>> + (define conf (getenv "GUIX_APCUPSD_CONF")) >>> + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) >>> + >>> + (define (err . args) >>> + (apply format (current-error-port) args)) >>> + (define (wall . args) >>> + (system* #$(file-append util-linux "/bin/wall") (apply format= #f args))) >>> + (define (apcupsd . args) >>> + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" c= onf args)) >>> + (define (mail-to-root subject body) >>> + (let ((port (open-pipe* OPEN_WRITE >>> + "/run/privileged/bin/sendmail" >>> + "-F" "apcupsd" >>> + "root"))) >>> + (format port "Subject: ~a~%~%~a~&" subject body) >>> + (close-pipe port))) >>> + (match (cdr (command-line)) >>> + (((? string? cmd) name connected powered) >>> + (match cmd >>> + ;; I am sure this could be done by macro, but meh. Last r= elease of >>> + ;; apcupsd was in 2016, so maintaining this will not be mu= ch work. >>> + ("killpower" >>> + #$@(apcupsd-event-handlers-killpower >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("commfailure" >>> + #$@(apcupsd-event-handlers-commfailure >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("commok" >>> + #$@(apcupsd-event-handlers-commok >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("powerout" >>> + #$@(apcupsd-event-handlers-powerout >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("onbattery" >>> + #$@(apcupsd-event-handlers-onbattery >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("offbattery" >>> + #$@(apcupsd-event-handlers-offbattery >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("mainsback" >>> + #$@(apcupsd-event-handlers-mainsback >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("failing" >>> + #$@(apcupsd-event-handlers-failing >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("timeout" >>> + #$@(apcupsd-event-handlers-timeout >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("loadlimit" >>> + #$@(apcupsd-event-handlers-loadlimit >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("runlimit" >>> + #$@(apcupsd-event-handlers-runlimit >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("doreboot" >>> + #$@(apcupsd-event-handlers-doreboot >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("doshutdown" >>> + #$@(apcupsd-event-handlers-doshutdown >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("annoyme" >>> + #$@(apcupsd-event-handlers-annoyme >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("emergency" >>> + #$@(apcupsd-event-handlers-emergency >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("changeme" >>> + #$@(apcupsd-event-handlers-changeme >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("remotedown" >>> + #$@(apcupsd-event-handlers-remotedown >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("startselftest" >>> + #$@(apcupsd-event-handlers-startselftest >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("endselftest" >>> + #$@(apcupsd-event-handlers-endselftest >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("battdetach" >>> + #$@(apcupsd-event-handlers-battdetach >>> + (apcupsd-configuration-event-handlers cfg))) >>> + ("battattach" >>> + #$@(apcupsd-event-handlers-battattach >>> + (apcupsd-configuration-event-handlers cfg))) >>> + (_ >>> + (err "Unknown event: ~a~%" cmd) >>> + (err "Iff the event was passed by apcupsd, this is a bug.= ~%") I just thought about it, perhaps it could be more concise to extract the field values using match-record (these are bound to shorter names, since they omit the 'apcupsd-configuration-' prefix). [...] >> I don't understand, in which scenario would an event *not* be emitted >> by apcupsd? > > If you call the script manually from command line. ^_^ I see! [...] >>> + (let ((run-dir (apcupsd-configuration-run-dir cfg))) >>> + (mixed-text-file >>> + "apcupsd.conf" >>> + "\ >>> +## apcupsd.conf v1.1 ## >>> +# >>> +# for apcupsd release 3.14.14 (31 May 2016) - GNU Guix >> >> Is this config really bound to a version like above? Unless they change >> things in backward incompatible ways, it should work for newer ones too, >> no? > > This file header is taken from the official configuration file > distributed with the apcupsd (except the GNU Guix part). So while I do > expect that this configuration file should work with newer version, the > upstream decided to put the version into the configuration file. > > I have no strong opinion either way here, should I just remove the file > header completely? I think so, since we're going the path of producing our own, we don't need to keep things that are not deemed useful. >>> +# >>> +# \"apcupsd\" POSIX config file (crafted via apcupsd-service-type) >> >> s/crafted via/auto-generated by/ > > But, but, "crafted" sound way more fancy. :) Well, replaced anyway. > However I have used just "generated by", the "auto-" part felt bit off. Eheh. Good! >>> +" >>> + (serialize-configuration cfg apcupsd-configuration-fields) >>> + ;; This one is confusing. The manual page states: >>> + ;; >>> + ;; > It must be changed when running more than one copy of apcups= d on the >>> + ;; > same computer to control multiple UPSes. >>> + ;; >>> + ;; However would you not want the lock to be per-device, not per-= process? >>> + ;; I decided to follow the documentation, but I do not understand= why it >>> + ;; should be like this. I do not have multiple UPSes to try. >>> + (serialize-string 'lock-dir (string-append run-dir "/lock")) >>> + (serialize-string 'power-fail-dir run-dir) >>> + (serialize-string 'no-login-dir run-dir) >>> + (serialize-string 'stat-file (string-append run-dir "/apcupsd.sta= tus")) >>> + "SCRIPTDIR " (apcupsd-script-dir cfg) "\n"))) >>> + >>> +(define (apcupsd-shepherd-services cfg) >> >> s/cfg/config/ > > And done. > >> >>> + (match-record cfg >>> + ( package pid-file debug-level run-dir >> ^ extraneous space > > This is intentional, it is neat little trick I have learned recently. > Without the extra leading space, Emacs indents it in this way: > > (match-record config > (apcupsd pid-file debug-level run-dir > shepherd-base-name auto-start?) > > > However, with the extra leading space, the indentation changes to: > > (match-record config > ( apcupsd pid-file debug-level run-dir > shepherd-base-name auto-start?) > > > Since in this case it is not a procedure call, but a list, first member > (apcupsd) is not special in any way. So it feels weird for it to have a > special priority regarding the indentation. With the extra leading > space, all list members are equal, as they should be. I see; that's an issue with our .dir-locals.el indentation rules. It should be fixed there, not worked around in actual code, though I can that workaround documented in 'info "(emacs) Lisp Indent"', for lists. In theory, we could define a function and assign it to the lisp-indent-function property (see .dir-locals.el), per 'C-h f scheme-indent-function' in Emacs to do whatever we like. While an interesting side project, I think using the workaround you propose is fine until then :-). [...] >> If you want, margin comments are ok without space or full sentence >> (punctuation), e.g.: >> >> ;do not daemonize > > I have no strong preference. What is the convention in Guix/Guile > community? Or is this down to each individual programmer? Our coding style in general comes from https://mumble.net/~campbell/scheme/style.txt (info '(guix) Formatting Code'), which mentions the above but leaves the choice. Since Ludo uses the above style, and authored most of the original code, it's the prevalent style in the code base and I suggest we stick to it, for consistency. [...] > I have added: > > ;; The apcupsd can be configured to prevent users from logging in on ce= rtain > ;; conditions. This is implemented by creation of a "nologin" file, and > ;; using a pam nologin module to prevent the login (if the file exists). Thanks, that helps! I'll let you take care of the small remaining things, and probably the next revision will be good to go. --=20 Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 16 Feb 2025 15:17:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173971899716229 (code B ref 75528); Sun, 16 Feb 2025 15:17:01 +0000 Received: (at 75528) by debbugs.gnu.org; 16 Feb 2025 15:16:37 +0000 Received: from localhost ([127.0.0.1]:36380 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjgNo-0004Dd-Kz for submit@debbugs.gnu.org; Sun, 16 Feb 2025 10:16:37 -0500 Received: from wolfsden.cz ([37.205.8.62]:37224) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tjgNk-0004DL-Ld for 75528@debbugs.gnu.org; Sun, 16 Feb 2025 10:16:34 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id C777437D77E; Sun, 16 Feb 2025 15:16:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739718990; bh=zkFrpT90rGwQnyrtfOxYNUR/UYkStVHWG2TIRoGkQ3I=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=EEwQ+Jzo+3MfVBTqLgDKpgLmx4T5n5VimJyKrsJRAm4b8RFTDPDyQt/RXy+xGOn9M jBHI8aN15+ZJTE2agrQkJCCMjBYy3q8EFGTzH3YEBSC6LT1jSvuZK5CFCT7Ra7VtPr dQA1ytKMt82B14RMD/jZYNyDuqRUAEXdR6qMId2fquzO8WpibFB/ke7djebw4UUf6H fcm3TJ/RtBPbZqfvSXFWnDK1FadEGF8VTa3rna/44qEjrqvW+sjR5Ui3qU60mjH6c+ aRroII4Jl1E+YoHLA3o7dSl5GVaXpU1XdH0f3dp6mUjroxlg4FS3DblTlGt9WoiCMY mL8wWPrFMvKoAkc16j3dEwcn+tjsUDHRqjBpVJrbJ/hX/ppexND47QcJDXmshNuZaG OrRNSBhRBrkHimM6wzGXlEtJA9lNpDz4oHgbK1KEh3bAUoE/1zFpN4Jd8MJMaA980t t/gycCQav+pEsdjyeNhqmOwWr7mgHUumTOmXFjB1z/GM6Sr+E8zwi8TxspUAG1YBrG XGT/Se9XZCag1hVTt9XVjhOTPfiPHL6coObtbbX3iGI9GJ6WosI/At9r+vgQLTBAw2 IvXtfk6YtzfViqt/lwNQTSwz6FxApqkJWgr0hNktmprjGd0V3qB8QrmRv523tuZdhE PfCaq2wQvsmAyG9wIjoeifIs= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id C1EE037EEA6; Sun, 16 Feb 2025 15:16:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739718989; bh=zkFrpT90rGwQnyrtfOxYNUR/UYkStVHWG2TIRoGkQ3I=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=xWTsqAPv0P2TAovvXz1ZRRFlAbWyUZLayBA22zjLq1dDG1T8rNN/M2vsvJ9deatSw detJ6pSy4+yaw/rYAXEiIgEXRRujaTYL481CCGzKz1fP28xvqM+iLkRJe1ZW153b/l VQG0oPZS2wMS2K8iETwoG/e5EEfpIs8MoEfAr6nLX0xjd7fhtT7jsrzeCyR1zDBRj5 HIWt3yraJQs/JlZ1KA8kvyu2VLW48q3ZfIt4HUtg/p/lOpUb0WCB+8uxZ6oyOdxhDr OgbO4dkD7scPrv71PGd35X+sJ7Ay+N5UIl8p7IYzyiRTJ4vmUfIvOJ+/4X7FjykNO5 DjkM5oRDnOlomr7THBtP1OdAg+eCAsXuWM0lE+dAL5tsOrCW0Tny0u1mKDEhbe+osN azM0NYjXDCYpr7Zo19qy/4Nrbuwvmv0ZMjdhrwvneJcSJ4gQaTKBmlKQ+A6ThOnFB/ ZvNo5Pf04++rutqp5Jg26cI5hJCOqfvSeCKPqfJB1hz0jVKlKD08Ico4JAifY1/Zm2 iH3MT3fgBEUJ8csZ3Yztf7Md5PzAiiBECQZhApmcLose4vkugr27/ksn1/5ZgceO2L YxLoDpmZYPQsTccCpU7QUI9202S8UWRJu8QrNJMGG1+vD4JPZLB4kMR9xi96dOejB6 EC4ba7xRXcLnt284FBNEwmQQ= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <878qq678tq.fsf@gmail.com> (Maxim Cournoyer's message of "Sun, 16 Feb 2025 14:33:05 +0900") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> <878qqk8q96.fsf@gmail.com> <874j0u7tsy.fsf@wolfsden.cz> <878qq678tq.fsf@gmail.com> Date: Sun, 16 Feb 2025 16:16:29 +0100 Message-ID: <875xl9538y.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: >>>> + >>>> +@item @code{auto-start?} (default: @code{#t}) (type: boolean) >>>> +Should the shepherd service auto-start? >>>> + >>>> +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type:= string) >>>> +Path to the pid file. >>> >>> All file names becoming /run/ prefixed instead of /var/run, based on a >>> previous comment. >> >> I will just quote myself from the package's patch, since it seems I did >> not get an answer there: >> >> It seems pretty much all programs on my system are using /var/run, >> including Shepherd. Only programs that store information in /run seem >> to be elogind and dbus. >> >> Is deprecation of /var/run listed somewhere in the manual? I am >> surprised Shepherd (since it is actively maintained and core component) >> is still in /var/run. I looked and found 42 references to /var/run, but >> none with the deprecation notice. >> >> Assuming you will insist on moving it to /run, is there some structure >> to follow in that directory? Or just s~/var/run~/run~? What about /var >> and /var/log? Should those be moved somewhere as well? > > Deprecating /var/run to /run is not a Guix thing, but a File Hiearchy > Standard (FHS) thing [0]. Since we already use /run, there's no good > reason to have /var/run something else than a symlink to /run, and > there's an actual change pending merge that would do that, along making > /run mounted as a tmpfs (bug#73494). > > [0] https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s13.html I did not know we actually care about FHS (for example our /usr/bin definitely does not look like it should in that case :) ). I did the s|/var/run|/run|. > > [..] > >>> >>> s/Slave/slave/ ? Could be nicer to use a neutral alternative like >>> 'follower machine'. >> >> The "Slave machine" (including the capitalization) is a term used in the >> manual. I can lower-case it if you would prefer, seems that manual >> actually uses both casings now when I looked for it. >> >> I do not think inventing new terminology is a good idea, since users >> will not be able to find it in the manual distributed with the program. > > The 'slave' word always carry a negative connotation. I think it's a > good idea to be proactive on modernizing the terminology where we can. In that case I would suggest to contact the upstream and convince them regarding this topic. Once that happens, we will be able to adjust the documentation with the next release (which would be free of offensive terminology). In any case, this is not a first occurrence of the word "slave" in the Guix repository nor manual. >> Given your requirement for sorting everything lexicographically (with no >> grouping), the following: >> >> (use-modules (gnu services) >> (srfi srfi-1)) >> >> (when #f >> (modify-services '() >> (delete 'x))) >> >> >> Prints a warning when compiled: >> >> WARNING: (guile-user): imported module (gnu services) overrides core bin= ding `delete' >> >> However, when done "my" way (putting srfi-1 first, since "stdlib"), the >> warning goes away. > > That's an interesting workaround, but I think we should look into that > problem and fix it definitely I often used #:hidden (delete) without any > issue it seems, so I'm not even sure if its existence still solves a > true problem in current Guile. I have recently (~few months back) tried to remove the `delete' and it a wall quickly, so I assume for reasons I do not understand it is still required. Having to use #:hidden (delete) on every single relevant import is in my opinion much worse solution than just ordering imports with srfi-1 at the top. But, I concur, it would be best it this just worked in any order. Anyway, I have sorted the modules as requested. I am not sure whether to sort =2D-8<---------------cut here---------------start------------->8--- #$@(apcupsd-event-handlers-modules (apcupsd-configuration-event-handlers cfg)) =2D-8<---------------cut here---------------end--------------->8--- Under `a' or `m' though. Opinion? > > [...] > >>>> +(define-configuration/no-serialization apcupsd-event-handlers >>>> + (killpower >>>> + (gexp >>>> + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) >>>> + (sleep 10) >>>> + (apcupsd "--killpower") >>>> + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" nam= e))) >>>> + "Handler for killpower event.") >>> > > By the way, why do we need to sleep 10 seconds here? It seems > unnecessary. All default handlers are just conversions of the official apccontrol script, and it has the sleep in there. I am not sure why, so I have decided it would be better to leave it as it was. > I just thought about it, perhaps it could be more concise to extract the > field values using match-record (these are bound to shorter names, since > they omit the 'apcupsd-configuration-' prefix). If I got the idea right, you suggest converting =2D-8<---------------cut here---------------start------------->8--- ("emergency" #$@(apcupsd-event-handlers-emergency (apcupsd-configuration-event-handlers cfg))) =2D-8<---------------cut here---------------end--------------->8--- into =2D-8<---------------cut here---------------start------------->8--- ("emergency" #$@(match-record cfg (handlers) (match-record handlers (emerge= ncy) emergency))) =2D-8<---------------cut here---------------end--------------->8--- I am not sure it is increase in readability, but maybe I misunderstood the suggestion. >>>> + (let ((run-dir (apcupsd-configuration-run-dir cfg))) >>>> + (mixed-text-file >>>> + "apcupsd.conf" >>>> + "\ >>>> +## apcupsd.conf v1.1 ## >>>> +# >>>> +# for apcupsd release 3.14.14 (31 May 2016) - GNU Guix >>> >>> Is this config really bound to a version like above? Unless they change >>> things in backward incompatible ways, it should work for newer ones too, >>> no? >> >> This file header is taken from the official configuration file >> distributed with the apcupsd (except the GNU Guix part). So while I do >> expect that this configuration file should work with newer version, the >> upstream decided to put the version into the configuration file. >> >> I have no strong opinion either way here, should I just remove the file >> header completely? > > I think so, since we're going the path of producing our own, we don't > need to keep things that are not deemed useful. I have removed the version, but kept the header, so that there is reference to apcupsd-service-type left in the file. >>>> + (match-record cfg >>>> + ( package pid-file debug-level run-dir >>> ^ extraneous space >> >> This is intentional, it is neat little trick I have learned recently. >> Without the extra leading space, Emacs indents it in this way: >> >> (match-record config >> (apcupsd pid-file debug-level run-dir >> shepherd-base-name auto-start?) >> >> >> However, with the extra leading space, the indentation changes to: >> >> (match-record config >> ( apcupsd pid-file debug-level run-dir >> shepherd-base-name auto-start?) >> >> >> Since in this case it is not a procedure call, but a list, first member >> (apcupsd) is not special in any way. So it feels weird for it to have a >> special priority regarding the indentation. With the extra leading >> space, all list members are equal, as they should be. > > I see; that's an issue with our .dir-locals.el indentation rules. It > should be fixed there, not worked around in actual code, though I can > that workaround documented in 'info "(emacs) Lisp Indent"', for lists. > In theory, we could define a function and assign it to the > lisp-indent-function property (see .dir-locals.el), per 'C-h f > scheme-indent-function' in Emacs to do whatever we like. While an > interesting side project, I think using the workaround you propose is > fine until then :-). Getting bit off topic, but I am not sure how that would work. Between various macros, and Scheme being LISP-1, I have no idea how to write robust code that would just magically always indent "right". But I would be glad to be proven wrong. :) > > [...] > >>> If you want, margin comments are ok without space or full sentence >>> (punctuation), e.g.: >>> >>> ;do not daemonize >> >> I have no strong preference. What is the convention in Guix/Guile >> community? Or is this down to each individual programmer? > > Our coding style in general comes from > https://mumble.net/~campbell/scheme/style.txt (info '(guix) Formatting > Code'), which mentions the above but leaves the choice. Since Ludo uses > the above style, and authored most of the original code, it's the > prevalent style in the code base and I suggest we stick to it, for > consistency. Sure, adjusted. > >> I have added: >> >> ;; The apcupsd can be configured to prevent users from logging in on c= ertain >> ;; conditions. This is implemented by creation of a "nologin" file, a= nd >> ;; using a pam nologin module to prevent the login (if the file exists= ). > > Thanks, that helps! > > I'll let you take care of the small remaining things, and probably the > next revision will be good to go. One additional change I have made is to change =2D-8<---------------cut here---------------start------------->8--- (requirement '()) =2D-8<---------------cut here---------------end--------------->8--- into =2D-8<---------------cut here---------------start------------->8--- (requirement '(user-processes)) =2D-8<---------------cut here---------------end--------------->8--- Without the dependency, the daemon got respawned by shepherd on shutdown and prevented the machine from going offline, which sucked a bit. ^_^ I thought I would mention it so that you can keep it in mind for future code reviews. With that I think I am out of things that I want to change or would appreciate feedback on, so I am sending a v2. Thank you for working with me through this, the code is much better than in v1. Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmeyAU0OHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wak4wg/+PGqF0Acnye2mO13Lw+gXEmqCgvtzSZidWT5h Zm0v+amhsB4z663+3HvGBCJ1CEcbze7myZpWPC88jtNkzytwD3YUPLUXu9ruvjBy XfFOZf6iGdjdvg/M9mwCNGqO1RPCDPa3gKC3kJQdZZ3gqd4r2Sp6DWnJs6gK+qpT KBkiX3h0snPZgydqImM0h8c3J70cv1WmQaGX+IYGuNxQdBnFArmGyu9G2dLNwYMp O+uCAtpGPDiT8gCwXv8ck6ItvRY7vfil6Vc57/kEpar67D+ZNkNLnUsVzZkrXlBc he5kXcyURvtvwx7csfCFkHKvVw6LuHNAvOqx9m3+wepZWVPPXYj/93H/eBe999Rj TM5/ej7+qXyfX90drf+z4BSmhtVbo0JbtNrN12eS8SGD5qEEYt1SXZijG1PDnsUE QGS/avJRVlOQgLKlpEwjSICdCO47BzCQui3C0B/CLn4cLk6eDRLcKVY2xK/5xn+6 e3JhpQwoapTpcD6HCqklF0OwCr3NjWRLChNuMbOAWMs5Q/P0eUlXfItBB+sQOiMy H5IJzWvkLWQVia/AFnndYJmx1EzRoKtK5w/dOQwXefY58+3iZbS2TfkN+9lpA3iv hXmlkSZZhIzP348xXbIT9wcWnL0uXLdL9PUba265As4mGWOGo6NBgtPUzud+4mQt bglEh18= =C70Z -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v2 1/2] gnu: Add apcupsd. References: In-Reply-To: Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 16 Feb 2025 15:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Raven Hallsby Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173971903616326 (code B ref 75528); Sun, 16 Feb 2025 15:18:02 +0000 Received: (at 75528) by debbugs.gnu.org; 16 Feb 2025 15:17:16 +0000 Received: from localhost ([127.0.0.1]:36389 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjgOR-0004FF-Ol for submit@debbugs.gnu.org; Sun, 16 Feb 2025 10:17:16 -0500 Received: from wolfsden.cz ([37.205.8.62]:42950) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tjgOE-0004EQ-2N for 75528@debbugs.gnu.org; Sun, 16 Feb 2025 10:17:03 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 1A72E37D9F0; Sun, 16 Feb 2025 15:17:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739719021; bh=N4T3Yn+ZnxmUVIrGK3cV0tHOCFSDIP0yQDb8olslY64=; h=From:To:Cc:Subject:Date; b=IvXKWHNzW/KF7qzEvmZ3SdAju92mixflZ6mGvWjM1gMxm6mkiutXwMcxvWPPNacKd qFYja1balsvp7ppX77nas9QI+hBLHIt3oJPEkK/GKtJ6QUynLvnavyxvcZaq3KLMEO EnFyRSYXcLJcFLQUwghDVDDYg0H4Ht5gmoV6RaM6VsLRP3Somq0NCyyhMGOBdObzX1 oojS9f7lyahgoOYQZlCU34fOM+MX5ZTx4PTLExgfelZJkirwAWFP0tOsyy4tNKO4yI Uqoro+WBVT8zmX4LD/xYOmEp3NkLteOVqGZdY8md3d2vShM5hi270J8dRe+kg6pCnc S04YoBEx3WQMWzZh735EWTtBthHiRaww2KC5MiLFeL1PkYMjDl+AWLUrmZzZDValcu bZhGwue6hJLYgHtOmXY4GyEahbw5w6umDgq1F+ces3V+QVS6xXWp2lfDqTbqkLwmcD jGDA+kSYsNXzpNNIgiOkACeA5/JqfEF7moHcBYDZqqRjgF9FamTrm3uaIc8VQc3I2n fdFSQ8e0l55kffAxZGoyNsqNgHP4jY9lp4yzZJB7x06pMJNgdf1/cL53dQ75PdA8Qg bFZhdAPxHcD/+zUpguKdEUjmfQR0f1hG3qG1nTB/85pTjVkQgGYyaXaSOzN7FerMWD 0Hzv5n/2N3lTemb6qwczuygo= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 1670937EEA7; Sun, 16 Feb 2025 15:16:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739719019; bh=N4T3Yn+ZnxmUVIrGK3cV0tHOCFSDIP0yQDb8olslY64=; h=From:To:Cc:Subject:Date; b=XWTdVE2o67XhIr75FolfxHC9N4cMxNDYjcVm5fQHyIAjMfVjwzOWPLIfK/L3Fu3HR t5BCv0vLsGkDZg/phwVmfg5w7m9sjPtmIvICie2qUtuL2CzaCAJk2CbGfRwuyJMC5y H3J2XlwtTLn0FZaGj3ncnU9AYV5vkzO3zUjO6wkxZfuMbzgdSS1opI5i4CFrFII3v/ 4nLZUqKN7KbkXoc1DGcDe10UiHC8iqAGDmNHO3RbLW1npVuEtsqbugeL2qxtxlSlwB U4RDc2gbFcD9Rka88Ws5IT82TefZ7hfjhCXpZTiYxC40ijDQi1lZ3rdA2Y7euV7+gA p/rTPBmuucfVWH4FTawR2xQ3bpkEXxZCtQ9wZO9OSCEAYturY6mckU4QaQJW72Jfpz oN0pWRVGETlwilBYjvPumQX2kdLhZxh+L5FrsHgPa5+rBpi5l6YZhEnEKFYIdfWgMd gLC4x117Y0jdpVEv210NPOnBmaMWENmxAvwxa2p5RzUoTCf95xo9PES91QZmcqfAfh O82E/p3RXB7/cThxUnRH/orjDIrhYVJ5kI4ykG2t3twaEPS7TTwbVG+CHJSfiLFSiM odNvBzjDD3Ms0y+0h7Lmwzm+RBHmqjTsC9O9AHRx1OAVFM10GFABSxiu0Rt68+FDoM R9+Y35nLmGyvvq5L78VTUSoE= From: Tomas Volf <~@wolfsden.cz> Date: Sun, 16 Feb 2025 16:16:45 +0100 Message-ID: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> X-Mailer: git-send-email 2.48.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/packages/power.scm (apcupsd): New variable. * gnu/local.mk (GNU_SYSTEM_MODULES): Register the new file. Co-authored-by: Raven Hallsby Change-Id: I5366f6deea111a6a9ea56648122cdc8b3297f08c --- gnu/local.mk | 1 + gnu/packages/power.scm | 122 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 gnu/packages/power.scm diff --git a/gnu/local.mk b/gnu/local.mk index bbe6fe4fce..3e9740779e 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -560,6 +560,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/polkit.scm \ %D%/packages/popt.scm \ %D%/packages/potassco.scm \ + %D%/packages/power.scm \ %D%/packages/printers.scm \ %D%/packages/profiling.scm \ %D%/packages/prolog.scm \ diff --git a/gnu/packages/power.scm b/gnu/packages/power.scm new file mode 100644 index 0000000000..843a907aa5 --- /dev/null +++ b/gnu/packages/power.scm @@ -0,0 +1,122 @@ +;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz> +;;; Copyright © 2023 Raven Hallsby + +;;;; Commentary: + +;;; Power-related packages. + +;;;; Code: + +(define-module (gnu packages power) + #:use-module (gnu) + #:use-module (gnu packages libusb) + #:use-module (gnu packages linux) + #:use-module (gnu packages man) + #:use-module (gnu packages pkg-config) + #:use-module (gnu packages python-xyz) + #:use-module (guix build-system gnu) + #:use-module (guix download) + #:use-module (guix gexp) + #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix packages)) + +(define-public apcupsd + (package + (name "apcupsd") + (version "3.14.14") + (source (origin + (method url-fetch) + (uri + (string-append + "mirror://sourceforge/" name "/" name " - Stable/" version + "/" name "-" version ".tar.gz")) + (sha256 + (base32 + "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv")))) + (outputs '("out" "doc")) + (build-system gnu-build-system) + (arguments + (list + #:configure-flags + #~(list + ;; The configure script ignores --prefix for most of the file names. + (string-append "--exec-prefix=" #$output) + (string-append "--mandir=" #$output "/share/man") + (string-append "--sbindir=" #$output "/sbin") + (string-append "--sysconfdir=" #$output "/etc/apcupsd") + (string-append "--with-halpolicydir=" #$output "/share/halpolicy") + + ;; Put us into the version string. + "--with-distname=GNU Guix" + "--disable-install-distdir" + + ;; State directories. + "--localstatedir=/var" + "--with-log-dir=/var/log" + "--with-pid-dir=/run" + "--with-lock-dir=/run/apcupsd/lock" + "--with-nologin=/run/apcupsd" + "--with-pwrfail-dir=/run/apcupsd" + + ;; Configure requires these, but we do not use the genenerated + ;; apcupsd.conf, so in order to reduce dependencies of the package, + ;; provide fake values. + (string-append "ac_cv_path_SHUTDOWN=/nope") + (string-append "ac_cv_path_APCUPSD_MAIL=/nope") + ;; While `wall' is not expanded anywhere, it still is searched for. + ;; See https://sourceforge.net/p/apcupsd/mailman/message/59128628/ . + (string-append "ac_cv_path_WALL=/nope") + + ;; Enable additional drivers. + "--enable-usb" + "--enable-modbus-usb") + #:tests? #f ; There are no tests. + #:modules (cons '(ice-9 ftw) %default-gnu-modules) + #:phases + #~(modify-phases %standard-phases + (add-before 'configure 'remove-time-from-manual + (lambda _ + ;; Do not bake the date and time of the build into the manual. + (substitute* "doc/manual/manual.rst" + (("\\| \\|date\\| \\|time\\|") "")) + (substitute* "autoconf/variables.mak.in" + (("^(RST2HTMLOPTS = .*) --time (.*)" all pref suff) + (string-append pref " " suff))))) + (add-after 'build 'build-manual + (lambda _ + (invoke "make" "-C" "doc/manual" "manual.html"))) + (add-after 'install-license-files 'move-doc + (lambda _ + (let ((target (string-append #$output:doc + "/share/doc/" + (strip-store-file-name #$output)))) + (mkdir-p target) + (for-each (lambda (f) + (copy-file (string-append "doc/manual/" f) + (string-append target "/" f))) + (scandir "doc/manual" + (lambda (f) + (or (string-suffix? ".png" f) + (string-suffix? ".html" f)))))))) + ;; If sending mails is required, use proper mail program. + (add-after 'install 'remove-smtp + (lambda _ + (delete-file (string-append #$output "/sbin/smtp")))) + ;; The configuration files and scripts are not really suitable for + ;; Guix, and our service provides its own version anyway. So delete + ;; these to make sure `apcupsd' and `apctest' executed without any + ;; arguments fail. `apctest' actually segfaults, but only after + ;; printing an error. + (add-after 'install 'remove-etc-apcupsd + (lambda _ + (delete-file-recursively + (string-append #$output "/etc/apcupsd"))))))) + (native-inputs (list mandoc pkg-config python-docutils util-linux)) + (inputs (list libusb libusb-compat)) + (home-page "http://www.apcupsd.org") + (synopsis "Daemon for controlling APC UPSes") + (description "The apcupsd can be used for power management and controlling +most of APC’s UPS models on Unix and Windows machines. The apcupsd works with +most of APC’s Smart-UPS models as well as most simple signalling models such a +Back-UPS, and BackUPS-Office.") + (license license:gpl2))) -- 2.48.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v2 2/2] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Sun, 16 Feb 2025 15:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-Xcc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173971903916335 (code B ref 75528); Sun, 16 Feb 2025 15:18:02 +0000 Received: (at 75528) by debbugs.gnu.org; 16 Feb 2025 15:17:19 +0000 Received: from localhost ([127.0.0.1]:36391 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tjgOS-0004FM-Jd for submit@debbugs.gnu.org; Sun, 16 Feb 2025 10:17:18 -0500 Received: from wolfsden.cz ([37.205.8.62]:57494) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tjgOL-0004F0-4g for 75528@debbugs.gnu.org; Sun, 16 Feb 2025 10:17:12 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 2E5B237DFCE; Sun, 16 Feb 2025 15:17:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739719028; bh=NHOp0KPow807wkGbt3Qi68ZR/IkY93qU6er84OB0gig=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=xYN0GsAz6Jfv+c6s+PSmUGtU6KUII8A02twdlaGUEp1Ms/qHINdLgPO8Q+8LwDWCk KOVwToniF2jbCjM9BPvO8YgAK73F2H/QSQ2IXWyFhFSO1Sxz6XCvppZAMcFImCD4ww KEJhcu/1sULAArj1X2vDnmUpX29FpbOCnrHeyCJb9KLjA7qNrhmV/7qYTf35lUrWxx Riwe1nz6vgJpieVCJDeIZdd2fMHwvgJwDsD9/EdMUyWI3wOuRCtebYaHY5DTirP58B 9X5CYeZQSgRu2N/5g0KxNMZPaq4/RuXKnce4ni+8SBxX2Io03S3ZQAZi6kwTIDPxfb KTLnUNEj7L+a34aQThhI8vRwCc2Pzg80Gbu8bPjHx20XXLjjq83Vnl5XxVlGZDrJO5 PRV57nmCoPffIz1wCcyqery5+nMIeOlZqfSmN8bC9Pi3f+IQbA/SBnfdEjgSpe6xYC nezhXA1FhNBFEgO9Rhfun7U2xVdhjL6NRqBphSz4lWX7mVvkFb5XGljC4VZ2q2fKQS Y0gGd3FGR4iz5MiM+wlYY2xZIWVDzIw55BphRqn3cCMZyOQEOG/gt1wbXC5syJijWt gwgZ9qlFMiEqKD+RBqLK+rdWzgRDD3X3xOwziGxc+AByXQnifIx+2cNUw5nsivYHSE 1Fe4O4Vi8qNJKSU+zbmDeIag= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id A85A937DC77; Sun, 16 Feb 2025 15:17:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1739719023; bh=NHOp0KPow807wkGbt3Qi68ZR/IkY93qU6er84OB0gig=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ThUUe5cvlph0ZXi+zL+dbDu2cM6+5DuEkXMLZIz3vwUuO+XjsQTqAIPjCjf05jPHW 3m/QhliTeA9yzJ9ywQIloq6HpEA7h/1YZvaCA6CdviVJm9jIhq0lQud7i30mGeiyXc w7obpypeyrXP46sNJELFWnIejekOui6gs1T/daxgyIC8uJwdaAuj3VesE1SQYEcCOM OvD73cK1xOeU3zdqt2WI3zH/a+H/FfAG20LDMhCLWjRiLb14CwLC6MfyzXr1LPh6Dg kGBKbnSioTxcRFt3b+dk8MJGLlGJM3pgS1InFh4jAgwux/nR2QUfQhBwIV6pIA0vTl P/BZMPcrkEKPyb/+nnwyiJrmWgEYBX8vMsc3JsUv8kGtT2SZryo31KTMwORotbuVBr zIj+5rI85Q02vBPG1so+/qsxlJ4l1SI+WFGpYbkzVd/hZiJARF4wQPP7l+Bjk1thvt ySEjG1KBdhgxkzP90JBJ+CW/AnUVa7N3u99NCOec99SpywwWbJVN5tNL1tqoHS42A9 V1aYjAuSQv4AKoD0CPSZxlFqjh0xbg2lr/QTGhgZpmB78WXc/l1erujutimD2djdO9 SdaBAyDMJed02C3gm3aXao4XaPjp9bHgULmDcYsjeyOUGhobh0l7CNG2EWzOG96Qiy he5txMfRrQrNJRzVYln0lhLA= From: Tomas Volf <~@wolfsden.cz> Date: Sun, 16 Feb 2025 16:16:46 +0100 Message-ID: <0b295c3bf879d00157b0476744e218ad0d921656.1739719006.git.~@wolfsden.cz> X-Mailer: git-send-email 2.48.1 In-Reply-To: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> References: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/services/power.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Power Management Services): Document service and data types. Change-Id: If205d19bea1d20a99309626e28521a2d6fe6702f --- doc/guix.texi | 382 +++++++++++++++++++++- gnu/local.mk | 1 + gnu/services/power.scm | 711 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1091 insertions(+), 3 deletions(-) create mode 100644 gnu/services/power.scm diff --git a/doc/guix.texi b/doc/guix.texi index f8b3022ccf..eee47d0b86 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -123,7 +123,7 @@ Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* Copyright @copyright{} 2023 Graham James Addis@* -Copyright @copyright{} 2023, 2024 Tomas Volf@* +Copyright @copyright{} 2023-2025 Tomas Volf@* Copyright @copyright{} 2024, 2025 Herman Rimm@* Copyright @copyright{} 2024 Matthew Trzcinski@* Copyright @copyright{} 2024 Richard Sent@* @@ -421,7 +421,7 @@ Top * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -19269,7 +19269,7 @@ Services * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -36516,6 +36516,382 @@ Power Management Services @end table @end deftp +The @code{(gnu services power)} module provides a service definition for +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with +@acronym{APC, APC by Schneider Electric or formerly American Power +Conversion Corporation} @acronym{UPS, Uninterruptible Power Supply} +devices. Apcupsd also works with some @acronym{OEM, Original Equipment +Manufacturer}-branded products manufactured by APC. + +@defvar apcupsd-service-type +The service type for apcupsd. For USB UPSes no configuration is +necessary, however tweaking some fields to better suit your needs might +be desirable. The defaults are taken from the upstream configuration +and they are not very conservative (for example, the default +@code{battery-level} of 5% may be considered too low by some). + +The default event handlers do send emails, read more in +@ref{apcupsd-event-handlers}. + +@lisp +(service apcupsd-service-type) +@end lisp +@end defvar + +@deftp {Data Type} apcupsd-configuration + +Available @code{apcupsd-configuration} fields are: + +@table @asis +@item @code{apcupsd} (default: @code{apcupsd}) (type: package) +The @code{apcupsd} package to use. + +@item @code{shepherd-service-name} (default: @code{apcupsd}) (type: symbol) +The name of the shepherd service. You can add the service multiple +times with different names to manage multiple UPSes. + +@item @code{auto-start?} (default: @code{#t}) (type: boolean) +Should the shepherd service auto-start? + +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: string) +The file name of the pid file. + +@item @code{debug-level} (default: @code{0}) (type: integer) +The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} +seems reasonable to enable all the logs. + +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) +The directory containing runtime information. You need to change this +if you desire to run multiple instances of the daemon. + +@item @code{name} (type: maybe-string) +Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the +EEPROM. It should be 8 characters or less. + +@item @code{cable} (default: @code{usb}) (type: enum-cable) +The type of a cable connecting the UPS to your computer. Possible +generic choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: +@code{'940-0119A}, @code{'940-0127A}, @code{'940-0128A}, +@code{'940-0020B}, @code{'940-0020C}, @code{'940-0023A}, +@code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, +@code{'940-0095C}, @code{'940-0625A}, @code{'M-04-02-2000}. + +@item @code{type} (default: @code{usb}) (type: enum-type) +The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a +serial cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information +Server. This is used if the UPS powering your computer is connected to +a different computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless +you have a specific need for this old driver, you should use the +@code{'snmp} instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an +alternative to an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the +MODBUS protocol. + +@end table + +@item @code{device} (default: @code{""}) (type: string) +For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice +for most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. +The @var{hostname} is the ip address or hostname of the UPS on the +network. The @var{vendor} can be can be "APC" or "APC_NOTRAP". +"APC_NOTRAP" will disable SNMP trap catching; you usually want "APC". +The @var{port} is usually 161. The @var{community} is usually +"private". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. +The @var{ipaddr} is the IP address of the UPS management card. The +@var{username} and the @var{passphrase} are the credentials for which +the card has been configured. The @var{port} is the port number on +which to listen for messages from the UPS, normally 3052. If this +parameter is empty or missing, the default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it +empty for MODBUS over USB or set to the serial number of the UPS. + +@end table + +@item @code{poll-time} (default: @code{60}) (type: integer) +The interval (in seconds) at which apcupsd polls the UPS for status. +This setting applies both to directly-attached UPSes (apcsmart, usb, +dumb) and networked UPSes (net, snmp). Lowering this setting will +improve the apcupsd's responsiveness to certain events at the cost of +higher CPU utilization. + +@item @code{on-batery-delay} (default: @code{6}) (type: integer) +The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be +triggered immediately when a power failure is detected. However, the +@code{'onbattery} event will be trigger only after this delay. + +@item @code{battery-level} (default: @code{5}) (type: integer) +If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{remaining-minutes} (default: @code{3}) (type: integer) +If during a power failure, the remaining runtime in minutes (as +calculated internally by the UPS) is below or equal to this value, +apcupsd will initiate a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{timeout} (default: @code{0}) (type: integer) +If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value +of 0 disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{annoy-interval} (default: @code{300}) (type: integer) +The time in seconds between annoying users (via the @code{'annoyme} +event) to sign off prior to system shutdown. 0 disables. + +@item @code{annoy-delay} (default: @code{60}) (type: integer) +The initial delay in seconds after a power failure before warning users +to get off the system. + +@item @code{no-logon} (default: @code{disable}) (type: enum-no-logon) +The condition which determines when users are prevented from logging in +during a power failure. + +@item @code{kill-delay} (default: @code{0}) (type: integer) +If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to +kill the power. This is for use on systems where apcupsd cannot regain +control after a shutdown. + +@item @code{net-server} (default: @code{#f}) (type: boolean) +If enabled, a network information server process will be started. + +@item @code{net-server-ip} (default: @code{"127.0.0.1"}) (type: string) +An IP address on which the NIS server will listen for incoming +connections. + +@item @code{net-server-port} (default: @code{3551}) (type: integer) +An IP port on which the NIS server will listen for incoming connections. + +@item @code{net-server-events-file} (type: maybe-string) +If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name. + +@item @code{net-server-events-file-max-size} (default: @code{10}) (type: integer) +The maximum size of the events file in kilobytes. + +@item @code{class} (default: @code{standalone}) (type: enum-class) +Normally standalone unless you share an UPS using an APC ShareUPS card. + +@item @code{mode} (default: @code{disable}) (type: enum-mode) +Normally disable unless you share an UPS using an APC ShareUPS card. + +@item @code{stat-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the status file, 0 +disables. + +@item @code{log-stats} (default: @code{#f}) (type: boolean) +Also write the stats as a logs. This generates a lot of output. + +@item @code{data-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the data records to the log +file, 0 disables. + +@item @code{facility} (type: maybe-string) +The logging facility for the syslog. + +@item @code{event-handlers} (type: apcupsd-event-handlers) +Handlers for events produced by apcupsd. + +@end table +@end deftp + +@anchor{apcupsd-event-handlers} +@deftp {Data Type} apcupsd-event-handlers + +For a description of the events please refer to @samp{man 8 apccontrol}. + +Each handler shall be a gexp. It is spliced into the control script for +the daemon. In addition to the standard Guile programming environment, +the following procedures and variables are also available: + +@table @code +@item conf +Variable containing the file name of the configuration file. + +@item powerfail-file +Variable containing the file name of the powerfail file. + +@item cmd +The event currently being handled. + +@item name +The name of the UPS as specified in the configuration file. + +@item connected? +Is @code{#t} if @command{apcupsd} is connected to the UPS via a serial +port (or a USB port). In most configurations, this will be the case. +In the case of a Slave machine where apcupsd is not directly connected +to the UPS, this value will be @code{#f}. + +@item powered? +Is @code{#t} if the computer on which @command{apcupsd} is running is +powered by the UPS and @code{#f} if not. At the moment, this value is +unimplemented and always @code{#f}. + +@item (err @var{fmt} @var{args...}) +Wrapper around @code{format} outputting to @code{(current-error-port)}. + +@item (wall @var{fmt} @var{args...}) +Wrapper around @code{format} outputting via @command{wall}. + +@item (apcupsd @var{args...}) +Call @command{apcupsd} while passing the correct configuration file and +all the arguments. + +@item (mail-to-root @var{subject} @var{body}) +Send an email to the local administrator. This procedure assumes the +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} +(as would be the case with @code{opensmtpd-service-type}). + +@end table + +Available @code{apcupsd-event-handlers} fields are: + +@table @asis +@item @code{modules} (type: gexp) +Additional modules to import into the generated handler script. + +@item @code{killpower} (type: gexp) +The handler for the killpower event. + +@item @code{commfailure} (type: gexp) +The handler for the commfailure event. + +@item @code{commok} (type: gexp) +The handler for the commfailure event. + +@item @code{powerout} (type: gexp) +The handler for the powerout event. + +@item @code{onbattery} (type: gexp) +The handler for the onbattery event. + +@item @code{offbattery} (type: gexp) +The handler for the offbattery event. + +@item @code{mainsback} (type: gexp) +The handler for the mainsback event. + +@item @code{failing} (type: gexp) +The handler for the failing event. + +@item @code{timeout} (type: gexp) +The handler for the timeout event. + +@item @code{loadlimit} (type: gexp) +The handler for the loadlimit event. + +@item @code{runlimit} (type: gexp) +The handler for the runlimit event. + +@item @code{doreboot} (type: gexp) +The handler for the doreboot event. + +@item @code{doshutdown} (type: gexp) +The handler for the doshutdown event. + +@item @code{annoyme} (type: gexp) +The handler for the annoyme event. + +@item @code{emergency} (type: gexp) +The handler for the emergency event. + +@item @code{changeme} (type: gexp) +The handler for the changeme event. + +@item @code{remotedown} (type: gexp) +The handler for the remotedown event. + +@item @code{startselftest} (type: gexp) +The handler for the startselftest event. + +@item @code{endselftest} (type: gexp) +The handler for the endselftest event. + +@item @code{battdetach} (type: gexp) +The handler for the battdetach event. + +@item @code{battattach} (type: gexp) +The handler for the battattach event. + +@end table +@end deftp + @node Audio Services @subsection Audio Services diff --git a/gnu/local.mk b/gnu/local.mk index 3e9740779e..61f652876e 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -761,6 +761,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/nix.scm \ %D%/services/nfs.scm \ %D%/services/pam-mount.scm \ + %D%/services/power.scm \ %D%/services/science.scm \ %D%/services/security.scm \ %D%/services/security-token.scm \ diff --git a/gnu/services/power.scm b/gnu/services/power.scm new file mode 100644 index 0000000000..72b2a40fef --- /dev/null +++ b/gnu/services/power.scm @@ -0,0 +1,711 @@ +;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz> + +;;;; Commentary: + +;;; Power-related services. + +;;;; Code: + +(define-module (gnu services power) + #:use-module (gnu) + #:use-module (gnu packages admin) + #:use-module (gnu packages linux) + #:use-module (gnu packages power) + #:use-module (gnu services configuration) + #:use-module (gnu services shepherd) + #:use-module (gnu services) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:export (apcupsd-service-type + + apcupsd-configuration + apcupsd-configuration-apcupsd + apcupsd-configuration-shepherd-service-name + apcupsd-configuration-auto-start? + apcupsd-configuration-pid-file + apcupsd-configuration-debug-level + apcupsd-configuration-run-dir + apcupsd-configuration-name + apcupsd-configuration-cable + apcupsd-configuration-type + apcupsd-configuration-device + apcupsd-configuration-poll-time + apcupsd-configuration-on-batery-delay + apcupsd-configuration-battery-level + apcupsd-configuration-remaining-minutes + apcupsd-configuration-timeout + apcupsd-configuration-annoy-interval + apcupsd-configuration-annoy-delay + apcupsd-configuration-no-logon + apcupsd-configuration-kill-delay + apcupsd-configuration-net-server + apcupsd-configuration-net-server-ip + apcupsd-configuration-net-server-port + apcupsd-configuration-net-server-events-file + apcupsd-configuration-net-server-events-file-max-size + apcupsd-configuration-class + apcupsd-configuration-mode + apcupsd-configuration-stat-time + apcupsd-configuration-log-stats + apcupsd-configuration-data-time + apcupsd-configuration-facility + apcupsd-configuration-event-handlers + + apcupsd-event-handlers + apcupsd-event-handlers-modules + apcupsd-event-handlers-annoyme + apcupsd-event-handlers-battattach + apcupsd-event-handlers-battdetach + apcupsd-event-handlers-changeme + apcupsd-event-handlers-commfailure + apcupsd-event-handlers-commok + apcupsd-event-handlers-doreboot + apcupsd-event-handlers-doshutdown + apcupsd-event-handlers-emergency + apcupsd-event-handlers-endselftest + apcupsd-event-handlers-failing + apcupsd-event-handlers-killpower + apcupsd-event-handlers-loadlimit + apcupsd-event-handlers-mainsback + apcupsd-event-handlers-offbattery + apcupsd-event-handlers-onbattery + apcupsd-event-handlers-powerout + apcupsd-event-handlers-remotedown + apcupsd-event-handlers-runlimit + apcupsd-event-handlers-startselftest + apcupsd-event-handlers-timeout)) + +(define-configuration/no-serialization apcupsd-event-handlers + (modules + (gexp #~()) + "Additional modules to import into the generated handler script.") + (killpower + (gexp + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) + (sleep 10) + (apcupsd "--killpower") + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) + "The handler for the killpower event.") + (commfailure + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a lost." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Warning: communications lost with UPS ~a" name))) + "The handler for the commfailure event.") + (commok + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a restored." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Communications restored with UPS ~a" name))) + "The handler for the commfailure event.") + (powerout + (gexp + #~(#t)) + "The handler for the powerout event.") + (onbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power failure on UPS ~a. Running on batteries." name))) + "The handler for the onbattery event.") + (offbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power has returned." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power has returned on UPS ~a..." name))) + "The handler for the offbattery event.") + (mainsback + (gexp + #~((when (file-exists? powerfail-file) + (wall "Continuing with shutdown.")))) + "The handler for the mainsback event.") + (failing + (gexp + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name))) + "The handler for the failing event.") + (timeout + (gexp + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." name))) + "The handler for the timeout event.") + (loadlimit + (gexp + #~((wall "Remaining battery charge below limit on UPS ~a. Doing shutdown." name))) + "The handler for the loadlimit event.") + (runlimit + (gexp + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing shutdown." name))) + "The handler for the runlimit event.") + (doreboot + (gexp + #~((wall "UPS ~a initiating Reboot Sequence" name) + (system* #$(file-append shepherd "/sbin/reboot")))) + "The handler for the doreboot event.") + (doshutdown + (gexp + #~((wall "UPS ~a initiated Shutdown Sequence" name) + (system* #$(file-append shepherd "/sbin/halt")))) + "The handler for the doshutdown event.") + (annoyme + (gexp + #~((wall "Power problems with UPS ~a. Please logoff." name))) + "The handler for the annoyme event.") + (emergency + (gexp + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a." name))) + "The handler for the emergency event.") + (changeme + (gexp + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Emergency! Batteries have failed on UPS ~a. Change them NOW." name))) + "The handler for the changeme event.") + (remotedown + (gexp + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) + "The handler for the remotedown event.") + (startselftest + (gexp + #~(#t)) + "The handler for the startselftest event.") + (endselftest + (gexp + #~(#t)) + "The handler for the endselftest event.") + (battdetach + (gexp + #~(#t)) + "The handler for the battdetach event.") + (battattach + (gexp + #~(#t)) + "The handler for the battattach event.")) + +(define-syntax define-enum + (lambda (x) + (syntax-case x () + ((_ name values) + (let* ((datum/name (syntax->datum #'name)) + (datum/predicate (string->symbol + (format #f "enum-~a?" datum/name))) + (datum/serialize (string->symbol + (format #f "serialize-enum-~a" datum/name)))) + (with-syntax + ((predicate (datum->syntax x datum/predicate)) + (serialize (datum->syntax x datum/serialize))) + #'(begin + (define (predicate value) + (memq value values)) + (define serialize serialize-symbol)))))))) + +(define mangle-field-name + (match-lambda + ('name "UPSNAME") + ('cable "UPSCABLE") + ('type "UPSTYPE") + ('device "DEVICE") + ('poll-time "POLLTIME") + ('lock-dir "LOCKFILE") + ('power-fail-dir "PWRFAILDIR") + ('no-login-dir "NOLOGINDIR") + ('on-batery-delay "ONBATTERYDELAY") + ('battery-level "BATTERYLEVEL") + ('remaining-minutes "MINUTES") + ('timeout "TIMEOUT") + ('annoy-interval "ANNOY") + ('annoy-delay "ANNOYDELAY") + ('no-logon "NOLOGON") + ('kill-delay "KILLDELAY") + ('net-server "NETSERVER") + ('net-server-ip "NISIP") + ('net-server-port "NISPORT") + ('net-server-events-file "EVENTSFILE") + ('net-server-events-file-max-size "EVENTSFILEMAX") + ('class "UPSCLASS") + ('mode "UPSMODE") + ('stat-time "STATTIME") + ('stat-file "STATFILE") + ('log-stats "LOGSTATS") + ('data-time "DATATIME") + ('facility "FACILITY"))) + +(define (serialize-string field-name value) + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) +(define serialize-symbol serialize-string) +(define serialize-integer serialize-string) +(define (serialize-boolean field-name value) + #~(format #f "~a ~a\n" + #$(mangle-field-name field-name) + #$(if value "on" "off"))) + +(define-maybe string) + +(define-enum cable '( simple smart ether usb + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-2000)) +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test)) +(define-enum no-logon '(disable timeout percent minutes always)) +(define-enum class '(standalone shareslave sharemaster)) +(define-enum mode '(disable share)) + +(define-configuration apcupsd-configuration + (apcupsd (package apcupsd) "The @code{apcupsd} package to use.") + + (shepherd-service-name + (symbol 'apcupsd) + "The name of the shepherd service. You can add the service multiple times +with different names to manage multiple UPSes." + empty-serializer) + (auto-start? + (boolean #t) + "Should the shepherd service auto-start?" + empty-serializer) + (pid-file + (string "/run/apcupsd.pid") + "The file name of the PID file." + empty-serializer) + (debug-level + (integer 0) + "The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} seems +reasonable to enable all the logs." + empty-serializer) + + (run-dir + (string "/run/apcupsd") + "The directory containing runtime information. You need to change this if +you desire to run multiple instances of the daemon." + empty-serializer) + + ;; General configuration parameters + (name + maybe-string + "Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the EEPROM. +It should be 8 characters or less.") + (cable + (enum-cable 'usb) + "The type of a cable connecting the UPS to your computer. Possible generic +choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: @code{'940-0119A}, +@code{'940-0127A}, @code{'940-0128A}, @code{'940-0020B}, @code{'940-0020C}, +@code{'940-0023A}, @code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, @code{'940-0095C}, +@code{'940-0625A}, @code{'M-04-02-2000}.") + (type + (enum-type 'usb) + "The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a serial +cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information Server. +This is used if the UPS powering your computer is connected to a different +computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless you +have a specific need for this old driver, you should use the @code{'snmp} +instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an alternative to +an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the MODBUS +protocol. + +@end table") + (device + (string "") + "For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice for +most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. The +@var{hostname} is the ip address or hostname of the UPS on the network. The +@var{vendor} can be can be \"APC\" or \"APC_NOTRAP\". \"APC_NOTRAP\" will +disable SNMP trap catching; you usually want \"APC\". The @var{port} is +usually 161. The @var{community} is usually \"private\". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. The +@var{ipaddr} is the IP address of the UPS management card. The @var{username} +and the @var{passphrase} are the credentials for which the card has been +configured. The @var{port} is the port number on which to listen for messages +from the UPS, normally 3052. If this parameter is empty or missing, the +default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it empty +for MODBUS over USB or set to the serial number of the UPS. + +@end table") + (poll-time + (integer 60) + "The interval (in seconds) at which apcupsd polls the UPS for status. This +setting applies both to directly-attached UPSes (apcsmart, usb, dumb) and +networked UPSes (net, snmp). Lowering this setting will improve the apcupsd's +responsiveness to certain events at the cost of higher CPU utilization.") + + ;; Configuration parameters used during power failures + (on-batery-delay + (integer 6) + "The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be triggered +immediately when a power failure is detected. However, the @code{'onbattery} +event will be trigger only after this delay.") + (battery-level + (integer 5) + "If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (remaining-minutes + (integer 3) + "If during a power failure, the remaining runtime in minutes (as calculated +internally by the UPS) is below or equal to this value, apcupsd will initiate +a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (timeout + (integer 0) + "If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value of 0 +disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (annoy-interval + (integer 300) + "The time in seconds between annoying users (via the @code{'annoyme} event) +to sign off prior to system shutdown. 0 disables.") + (annoy-delay + (integer 60) + "The initial delay in seconds after a power failure before warning users to +get off the system.") + (no-logon + (enum-no-logon 'disable) + "The condition which determines when users are prevented from logging in +during a power failure.") + (kill-delay + (integer 0) + "If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to kill +the power. This is for use on systems where apcupsd cannot regain control +after a shutdown.") + + ;; Configuration statements for Network Information Server + (net-server + (boolean #f) + "If enabled, a network information server process will be started.") + (net-server-ip + (string "127.0.0.1") + "An IP address on which the NIS server will listen for incoming +connections.") + (net-server-port + (integer 3551) + "An IP port on which the NIS server will listen for incoming connections.") + (net-server-events-file + maybe-string + "If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name.") + (net-server-events-file-max-size + (integer 10) + "The maximum size of the events file in kilobytes.") + ;; Configuration statements used if sharing a UPS with more than one machine + (class (enum-class 'standalone) + "Normally standalone unless you share an UPS using an APC ShareUPS card.") + (mode (enum-mode 'disable) + "Normally disable unless you share an UPS using an APC ShareUPS card.") + ;; Configuration statements to control apcupsd system logging + (stat-time + (integer 0) + "The time interval in seconds between writing the status file, 0 +disables.") + (log-stats + (boolean #f) + "Also write the stats as a logs. This generates a lot of output.") + (data-time + (integer 0) + "The time interval in seconds between writing the data records to the log +file, 0 disables.") + (facility + maybe-string + "The logging facility for the syslog.") + + ;; Event handlers + (event-handlers + (apcupsd-event-handlers (apcupsd-event-handlers)) + "Handlers for events produced by apcupsd." + empty-serializer)) + +(define (%apccontrol config) + (program-file + "apccontrol" + #~(begin + (use-modules (ice-9 format) + (ice-9 match) + (ice-9 popen) + (srfi srfi-9) + #$@(apcupsd-event-handlers-modules + (apcupsd-configuration-event-handlers config))) + ;; Script dir depends on these, and the configuration depends on the + ;; script dir. To sever the cyclic dependency, pass the file names via + ;; environment variables. + (define conf (getenv "GUIX_APCUPSD_CONF")) + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) + + (define (err . args) + (apply format (current-error-port) args)) + (define (wall . args) + (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) + (define (apcupsd . args) + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) + (define (mail-to-root subject body) + (let ((port (open-pipe* OPEN_WRITE + "/run/privileged/bin/sendmail" + "-F" "apcupsd" + "root"))) + (format port "Subject: ~a~%~%~a~&" subject body) + (close-pipe port))) + (match (cdr (command-line)) + (((? string? cmd) name connected powered) + (let ((connected? (match connected + ("1" #t) + ("0" #f))) + (powered? (match powered + ("1" #t) + ("0" #f)))) + (match cmd + ;; I am sure this could be done by macro, but meh. Last release + ;; of apcupsd was in 2016, so maintaining this will not be much + ;; work. + ("killpower" + #$@(apcupsd-event-handlers-killpower + (apcupsd-configuration-event-handlers config))) + ("commfailure" + #$@(apcupsd-event-handlers-commfailure + (apcupsd-configuration-event-handlers config))) + ("commok" + #$@(apcupsd-event-handlers-commok + (apcupsd-configuration-event-handlers config))) + ("powerout" + #$@(apcupsd-event-handlers-powerout + (apcupsd-configuration-event-handlers config))) + ("onbattery" + #$@(apcupsd-event-handlers-onbattery + (apcupsd-configuration-event-handlers config))) + ("offbattery" + #$@(apcupsd-event-handlers-offbattery + (apcupsd-configuration-event-handlers config))) + ("mainsback" + #$@(apcupsd-event-handlers-mainsback + (apcupsd-configuration-event-handlers config))) + ("failing" + #$@(apcupsd-event-handlers-failing + (apcupsd-configuration-event-handlers config))) + ("timeout" + #$@(apcupsd-event-handlers-timeout + (apcupsd-configuration-event-handlers config))) + ("loadlimit" + #$@(apcupsd-event-handlers-loadlimit + (apcupsd-configuration-event-handlers config))) + ("runlimit" + #$@(apcupsd-event-handlers-runlimit + (apcupsd-configuration-event-handlers config))) + ("doreboot" + #$@(apcupsd-event-handlers-doreboot + (apcupsd-configuration-event-handlers config))) + ("doshutdown" + #$@(apcupsd-event-handlers-doshutdown + (apcupsd-configuration-event-handlers config))) + ("annoyme" + #$@(apcupsd-event-handlers-annoyme + (apcupsd-configuration-event-handlers config))) + ("emergency" + #$@(apcupsd-event-handlers-emergency + (apcupsd-configuration-event-handlers config))) + ("changeme" + #$@(apcupsd-event-handlers-changeme + (apcupsd-configuration-event-handlers config))) + ("remotedown" + #$@(apcupsd-event-handlers-remotedown + (apcupsd-configuration-event-handlers config))) + ("startselftest" + #$@(apcupsd-event-handlers-startselftest + (apcupsd-configuration-event-handlers config))) + ("endselftest" + #$@(apcupsd-event-handlers-endselftest + (apcupsd-configuration-event-handlers config))) + ("battdetach" + #$@(apcupsd-event-handlers-battdetach + (apcupsd-configuration-event-handlers config))) + ("battattach" + #$@(apcupsd-event-handlers-battattach + (apcupsd-configuration-event-handlers config))) + (_ + (err "Unknown event: ~a~%" cmd) + (err "Iff the event was emitted by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))) + (args + (err "Unknown arguments: ~a~%" args) + (err "Iff the arguments were passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f)))))) + +(define (apcupsd-script-dir config) + (computed-file + "apcupsd-script-dir" + #~(begin + (mkdir #$output) + (chdir #$output) + (symlink #$(%apccontrol config) "apccontrol")))) + +(define (apcupsd-config-file config) + (let ((run-dir (apcupsd-configuration-run-dir config))) + (mixed-text-file + "apcupsd.conf" + "\ +## apcupsd.conf v1.1 ## +# +# for apcupsd - GNU Guix +# +# \"apcupsd\" POSIX config file (generated by apcupsd-service-type) +" + (serialize-configuration config apcupsd-configuration-fields) + ;; This one is confusing. The manual page states: + ;; + ;; > It must be changed when running more than one copy of apcupsd on the + ;; > same computer to control multiple UPSes. + ;; + ;; However would you not want the lock to be per-device, not per-process? + ;; I decided to follow the documentation, but I do not understand why it + ;; should be like this. I do not have multiple UPSes to try. + (serialize-string 'lock-dir (string-append run-dir "/lock")) + (serialize-string 'power-fail-dir run-dir) + (serialize-string 'no-login-dir run-dir) + (serialize-string 'stat-file (string-append run-dir "/apcupsd.status")) + "SCRIPTDIR " (apcupsd-script-dir config) "\n"))) + +(define (apcupsd-activation config) + (match-record config (run-dir) + #~(begin + (use-modules (guix build utils)) + (mkdir-p #$(string-append run-dir "/lock"))))) + +(define (apcupsd-shepherd-services config) + (match-record config + ( apcupsd pid-file debug-level run-dir + shepherd-service-name auto-start?) + (let ((config-file (apcupsd-config-file config))) + (list + (shepherd-service + (documentation "Run the apcupsd daemon.") + (requirement '(user-processes)) + (provision (list shepherd-service-name)) + (auto-start? auto-start?) + (start #~(make-forkexec-constructor + '(#$(file-append apcupsd "/sbin/apcupsd") + "-b" ;do not daemonize + "-f" #$config-file + "-P" #$pid-file + "-d" #$(number->string debug-level)) + #:log-file + #$(format #f "/var/log/~a.log" shepherd-service-name) + #:environment-variables + (cons* (string-append "GUIX_APCUPSD_CONF=" + #$config-file) + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE=" + run-dir "/powerfail") + (default-environment-variables)))) + (stop #~(make-kill-destructor)) + (actions (list (shepherd-configuration-action config-file)))))))) + +(define (apcupsd-pam-extensions config) + ;; The apcupsd can be configured to prevent users from logging in on certain + ;; conditions. This is implemented by creation of a "nologin" file, and + ;; using a pam nologin module to prevent the login (if the file exists). + (define pam-nologin + (pam-entry + (control "required") + (module "pam_nologin.so") + (arguments (list (string-append "file=" + (apcupsd-configuration-run-dir config) + "/nologin"))))) + + (list (pam-extension + (transformer + (lambda (pam) + (pam-service + (inherit pam) + (auth (cons pam-nologin (pam-service-auth pam))))))))) + +(define apcupsd-service-type + (service-type + (name 'apcupsd) + (description "Configure and optionally start the apcupsd.") + (extensions (list (service-extension activation-service-type + apcupsd-activation) + (service-extension shepherd-root-service-type + apcupsd-shepherd-services) + (service-extension pam-root-service-type + apcupsd-pam-extensions))) + (compose identity) + (extend (lambda (cfg lst) + (fold (cut <> <>) cfg lst))) + (default-value (apcupsd-configuration)))) -- 2.48.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 18 Feb 2025 06:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.173986150112292 (code B ref 75528); Tue, 18 Feb 2025 06:52:02 +0000 Received: (at 75528) by debbugs.gnu.org; 18 Feb 2025 06:51:41 +0000 Received: from localhost ([127.0.0.1]:53800 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tkHSC-0003Br-1H for submit@debbugs.gnu.org; Tue, 18 Feb 2025 01:51:41 -0500 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:49197) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tkHS3-0003Ad-EM for 75528@debbugs.gnu.org; Tue, 18 Feb 2025 01:51:34 -0500 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-22113560c57so44911485ad.2 for <75528@debbugs.gnu.org>; Mon, 17 Feb 2025 22:51:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739861481; x=1740466281; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=7ge4Ndl8lfcpNmRBnwEaz6zGe7sFixC0a/dM478KLBA=; b=TJZedyC8d5+dhD6NpWX4gGp2mvGHL3tbO1K3VBcEDgzIGai5zpZAOGmsPGBqPy3og3 M/I8oAYp5Ze482+BnrVCIJV1dAGHXOJPxrKocuUPkzDqns62CLT3x4pf7IDhDLDVjyOF sLoBfmCm+qR7SbFzBnXHJGuM+YC0TxY2vr/b+fLXbjcayDVlmIDqCT+zcmp0IFDb9ppq XzT00Ll6b5U4CigmDYOrQMURLlPxm+g5+KN+899N9JfdfoyLxxb6h1O8f3zM0uMhBwas XYRGJoYh7BbPubql0omRjqC+6+VFKZq0sPtDGPhlImQk4OXHEmWvwMgWdDr62UQPgG+b mPVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739861481; x=1740466281; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=7ge4Ndl8lfcpNmRBnwEaz6zGe7sFixC0a/dM478KLBA=; b=Rar6VaNEpr9SEU+WajDwDnvLHBNv4Qtf3c3n6H3BAfvP8GLo9fk6zYGmnPEqUlZCpl iSSlMgR1TfKcMSLEAz903TmBpuNNx144pYdPk20Iwl9nP1JeL/8RwIT7HjvRnfQdVd4N bFaoJxD4iWd1CZUwD8Z8oveh/mdlI7ICo43LhLziqMvNUVNRj6t5L42/bynWc8aVxhTH Diierd/sE2Plhmpd2BW7bJeV5hVPMvf1YXM4vZC4RHriLKqpCM5yBiRUZgnqjU02v++m uzmsHtAzF3iH1W9LuQOiYhd5dWm1dVuYnU+2VawRVc/nm+552ya0oc6Jy3VgIMQVEZqT tThw== X-Gm-Message-State: AOJu0YzbBzlXSyr0SYNRcuMuDCtu6Dt4KZ5XI8nBhQhR2DwjnIJP0DwG 7sDJPW3RY6IwKDc/301qF6N6o8ZunzF6EtSQhyM94n/UwdXfGSV5tNuwo42i X-Gm-Gg: ASbGncsnegABSWQWD2pMQri179cAQVREIDYD2bMMDoqosrtzsMRapVZXeMHp2mOTgat qMEfSyT6hFt522iuXOpo0nJePQW0kB/SDwWyVlGkyY4j1a7cioiJdADGo1mq+j1ozJAcLjQt54N 8rAqsvcOOoaJIXGgZ7Q9HWJeWw8bVF6eiZjUb17Ju6CAuF/bli88pMED5BqPWNtDaNdFZ2S+6/4 UMfw528l9O5/8e8H03aCG2MJjR2XlbzJDzpxGYu79dlrq4jPSkaxpn79K0abLqMrsHLEbkwBE8m Sgfuw1oErvEtVg== X-Google-Smtp-Source: AGHT+IE1WduPHKGTtUxSBkffSZ6RtleUDtGM7gf/ojTLAso8mxyjkrO2Jpi6ahByZ52EcpuqchjeAg== X-Received: by 2002:a05:6a00:1391:b0:72d:9cbc:730d with SMTP id d2e1a72fcca58-732617c4b97mr20362072b3a.11.1739861480400; Mon, 17 Feb 2025 22:51:20 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7324273e2fesm9326467b3a.118.2025.02.17.22.51.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 22:51:19 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <875xl9538y.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 16 Feb 2025 16:16:29 +0100") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> <878qqk8q96.fsf@gmail.com> <874j0u7tsy.fsf@wolfsden.cz> <878qq678tq.fsf@gmail.com> <875xl9538y.fsf@wolfsden.cz> Date: Tue, 18 Feb 2025 15:51:06 +0900 Message-ID: <87r03vycdh.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: [...] >> Deprecating /var/run to /run is not a Guix thing, but a File Hiearchy >> Standard (FHS) thing [0]. Since we already use /run, there's no good >> reason to have /var/run something else than a symlink to /run, and >> there's an actual change pending merge that would do that, along making >> /run mounted as a tmpfs (bug#73494). >> >> [0] https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s13.html > > I did not know we actually care about FHS (for example our /usr/bin > definitely does not look like it should in that case :) ). > > I did the s|/var/run|/run|. We typically do not follow FHS much due to each of our packages being installed under their own prefix, but for the few things where we do, like here, I think it makes sense to stick to it, as it brings familiarity and consistency to our users. >>>> s/Slave/slave/ ? Could be nicer to use a neutral alternative like >>>> 'follower machine'. >>> >>> The "Slave machine" (including the capitalization) is a term used in the >>> manual. I can lower-case it if you would prefer, seems that manual >>> actually uses both casings now when I looked for it. >>> >>> I do not think inventing new terminology is a good idea, since users >>> will not be able to find it in the manual distributed with the program. >> >> The 'slave' word always carry a negative connotation. I think it's a >> good idea to be proactive on modernizing the terminology where we can. > > In that case I would suggest to contact the upstream and convince them > regarding this topic. Once that happens, we will be able to adjust the > documentation with the next release (which would be free of offensive > terminology). > > In any case, this is not a first occurrence of the word "slave" in the > Guix repository nor manual. That there are currently other occurrences is not a good reason to add more, in my opinion :-). That said, I've looked at upstream sources and it's true that the old master/slave terminology is currently deeply interwined in code and doc... so I did an experiment and came up with . I also forwarded the svn diff to upstream via their mailing list. We'll see what they think. [...] >>> WARNING: (guile-user): imported module (gnu services) overrides core binding `delete' >>> >>> However, when done "my" way (putting srfi-1 first, since "stdlib"), the >>> warning goes away. >> >> That's an interesting workaround, but I think we should look into that >> problem and fix it definitely I often used #:hidden (delete) without any >> issue it seems, so I'm not even sure if its existence still solves a >> true problem in current Guile. > > I have recently (~few months back) tried to remove the `delete' and it a > wall quickly, so I assume for reasons I do not understand it is still > required. > > Having to use #:hidden (delete) on every single relevant import is in my > opinion much worse solution than just ordering imports with srfi-1 at > the top. > > But, I concur, it would be best it this just worked in any order. OK, good to know, but let's keep this out of scope for the context of this change. > Anyway, I have sorted the modules as requested. I am not sure whether > to sort > > #$@(apcupsd-event-handlers-modules > (apcupsd-configuration-event-handlers cfg)) > > > Under `a' or `m' though. Opinion? I'm not sure I understood the question, but under `a' makes more sense to me (which `m' are you referring to?). >>>>> +(define-configuration/no-serialization apcupsd-event-handlers >>>>> + (killpower >>>>> + (gexp >>>>> + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) >>>>> + (sleep 10) >>>>> + (apcupsd "--killpower") >>>>> + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) >>>>> + "Handler for killpower event.") >>>> >> >> By the way, why do we need to sleep 10 seconds here? It seems >> unnecessary. > > All default handlers are just conversions of the official apccontrol > script, and it has the sleep in there. I am not sure why, so I have > decided it would be better to leave it as it was. OK, I guess it's safer to keep it. >> I just thought about it, perhaps it could be more concise to extract the >> field values using match-record (these are bound to shorter names, since >> they omit the 'apcupsd-configuration-' prefix). > > If I got the idea right, you suggest converting > > ("emergency" > #$@(apcupsd-event-handlers-emergency > (apcupsd-configuration-event-handlers cfg))) > > > into > > ("emergency" > #$@(match-record cfg (handlers) > (match-record handlers (emergency) > emergency))) > > > I am not sure it is increase in readability, but maybe I misunderstood > the suggestion. I think something like this should work: --8<---------------cut here---------------start------------->8--- modified gnu/services/power.scm @@ -494,119 +494,67 @@ (define-configuration apcupsd-configuration empty-serializer)) (define (%apccontrol config) - (program-file - "apccontrol" - #~(begin - (use-modules (ice-9 format) - (ice-9 match) - (ice-9 popen) - (srfi srfi-9) - #$@(apcupsd-event-handlers-modules - (apcupsd-configuration-event-handlers config))) - ;; Script dir depends on these, and the configuration depends on the - ;; script dir. To sever the cyclic dependency, pass the file names via - ;; environment variables. - (define conf (getenv "GUIX_APCUPSD_CONF")) - (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) - - (define (err . args) - (apply format (current-error-port) args)) - (define (wall . args) - (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) - (define (apcupsd . args) - (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) - (define (mail-to-root subject body) - (let ((port (open-pipe* OPEN_WRITE - "/run/privileged/bin/sendmail" - "-F" "apcupsd" - "root"))) - (format port "Subject: ~a~%~%~a~&" subject body) - (close-pipe port))) - (match (cdr (command-line)) - (((? string? cmd) name connected powered) - (let ((connected? (match connected + (define event-handlers (apcupsd-configuration-event-handlers config)) + (match-record event-handlers + ( modules killpower commfailure commok powerout + onbattery offbattery ...) + (program-file + "apccontrol" + #~(begin + (use-modules (ice-9 format) + (ice-9 match) + (ice-9 popen) + (srfi srfi-9) + #$@modules) + ;; Script dir depends on these, and the configuration depends on the + ;; script dir. To sever the cyclic dependency, pass the file names via + ;; environment variables. + (define conf (getenv "GUIX_APCUPSD_CONF")) + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) + + (define (err . args) + (apply format (current-error-port) args)) + + (define (wall . args) + (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) + + (define (apcupsd . args) + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) + + (define (mail-to-root subject body) + (let ((port (open-pipe* OPEN_WRITE + "/run/privileged/bin/sendmail" + "-F" "apcupsd" + "root"))) + (format port "Subject: ~a~%~%~a~&" subject body) + (close-pipe port))) + + (match (cdr (command-line)) + (((? string? cmd) name connected powered) + (let ((connected? (match connected + ("1" #t) + ("0" #f))) + (powered? (match powered ("1" #t) - ("0" #f))) - (powered? (match powered - ("1" #t) - ("0" #f)))) - (match cmd - ;; I am sure this could be done by macro, but meh. Last release - ;; of apcupsd was in 2016, so maintaining this will not be much - ;; work. - ("killpower" - #$@(apcupsd-event-handlers-killpower - (apcupsd-configuration-event-handlers config))) - ("commfailure" - #$@(apcupsd-event-handlers-commfailure - (apcupsd-configuration-event-handlers config))) - ("commok" - #$@(apcupsd-event-handlers-commok - (apcupsd-configuration-event-handlers config))) - ("powerout" - #$@(apcupsd-event-handlers-powerout - (apcupsd-configuration-event-handlers config))) - ("onbattery" - #$@(apcupsd-event-handlers-onbattery - (apcupsd-configuration-event-handlers config))) - ("offbattery" - #$@(apcupsd-event-handlers-offbattery - (apcupsd-configuration-event-handlers config))) - ("mainsback" - #$@(apcupsd-event-handlers-mainsback - (apcupsd-configuration-event-handlers config))) - ("failing" - #$@(apcupsd-event-handlers-failing - (apcupsd-configuration-event-handlers config))) - ("timeout" - #$@(apcupsd-event-handlers-timeout - (apcupsd-configuration-event-handlers config))) - ("loadlimit" - #$@(apcupsd-event-handlers-loadlimit - (apcupsd-configuration-event-handlers config))) - ("runlimit" - #$@(apcupsd-event-handlers-runlimit - (apcupsd-configuration-event-handlers config))) - ("doreboot" - #$@(apcupsd-event-handlers-doreboot - (apcupsd-configuration-event-handlers config))) - ("doshutdown" - #$@(apcupsd-event-handlers-doshutdown - (apcupsd-configuration-event-handlers config))) - ("annoyme" - #$@(apcupsd-event-handlers-annoyme - (apcupsd-configuration-event-handlers config))) - ("emergency" - #$@(apcupsd-event-handlers-emergency - (apcupsd-configuration-event-handlers config))) - ("changeme" - #$@(apcupsd-event-handlers-changeme - (apcupsd-configuration-event-handlers config))) - ("remotedown" - #$@(apcupsd-event-handlers-remotedown - (apcupsd-configuration-event-handlers config))) - ("startselftest" - #$@(apcupsd-event-handlers-startselftest - (apcupsd-configuration-event-handlers config))) - ("endselftest" - #$@(apcupsd-event-handlers-endselftest - (apcupsd-configuration-event-handlers config))) - ("battdetach" - #$@(apcupsd-event-handlers-battdetach - (apcupsd-configuration-event-handlers config))) - ("battattach" - #$@(apcupsd-event-handlers-battattach - (apcupsd-configuration-event-handlers config))) - (_ - (err "Unknown event: ~a~%" cmd) - (err "Iff the event was emitted by apcupsd, this is a bug.~%") - (err "Please report to bug-guix@gnu.org.~%") - (exit #f))))) - (args - (err "Unknown arguments: ~a~%" args) - (err "Iff the arguments were passed by apcupsd, this is a bug.~%") - (err "Please report to bug-guix@gnu.org.~%") - (exit #f)))))) + ("0" #f)))) + (match cmd + ("killpower" #$killpower) + ("commfailure" #$commfailure) + ("commok" #$commok) + ("powerout" #$powerout) + ("onbattery" #$onbattery) + ("offbattery" #$offbattery) + [...] + (_ + (err "Unknown event: ~a~%" cmd) + (err "If the event was emitted by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))) + (args + (err "Unknown arguments: ~a~%" args) + (err "If the arguments were passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f)))))))) (define (apcupsd-script-dir config) (computed-file --8<---------------cut here---------------end--------------->8--- [...] >>> This file header is taken from the official configuration file >>> distributed with the apcupsd (except the GNU Guix part). So while I do >>> expect that this configuration file should work with newer version, the >>> upstream decided to put the version into the configuration file. >>> >>> I have no strong opinion either way here, should I just remove the file >>> header completely? >> >> I think so, since we're going the path of producing our own, we don't >> need to keep things that are not deemed useful. > > I have removed the version, but kept the header, so that there is > reference to apcupsd-service-type left in the file. Sounds reasonable. [...] > Getting bit off topic, but I am not sure how that would work. Between > various macros, and Scheme being LISP-1, I have no idea how to write > robust code that would just magically always indent "right". > > But I would be glad to be proven wrong. :) I guess you could have a procedure that calls the existing indenting Elisp functions, and then have a post-processing pass on top to fix it the way wa want. It's probably a bit over the top :-). I like your/Emacs' down to Earth solution. [...] > One additional change I have made is to change > > (requirement '()) > > > into > > (requirement '(user-processes)) > > Without the dependency, the daemon got respawned by shepherd on shutdown > and prevented the machine from going offline, which sucked a bit. ^_^ Oh wow; good catch. That seems a rather large foot gun to have for service writers. I wonder if something could be done about it in the Shepherd. > I thought I would mention it so that you can keep it in mind for future > code reviews. Indeed, thanks for bringing this to my attention. > With that I think I am out of things that I want to change or would > appreciate feedback on, so I am sending a v2. Thank you for working > with me through this, the code is much better than in v1. I'll let you work through my last match-record suggestion above, if you want and send a v3. I'm also attaching a fixup with the terminology changes I've submitted upstream if you'd like to validate it still works (I don't have any UPS to try it with myself). --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-fixup-services-Add-power.patch Content-Transfer-Encoding: 8bit >From 63457572d4b84ba17ef34ab479fd0e425f7ca774 Mon Sep 17 00:00:00 2001 Message-ID: <63457572d4b84ba17ef34ab479fd0e425f7ca774.1739861410.git.maxim.cournoyer@gmail.com> From: Maxim Cournoyer Date: Tue, 18 Feb 2025 09:46:45 +0900 Subject: [PATCH] fixup! services: Add power. --- doc/guix.texi | 2 +- gnu/local.mk | 1 + .../patches/apcupsd-leader-follower.patch | 1847 +++++++++++++++++ gnu/packages/power.scm | 4 +- gnu/services/power.scm | 4 +- 5 files changed, 1854 insertions(+), 4 deletions(-) create mode 100644 gnu/packages/patches/apcupsd-leader-follower.patch diff --git a/doc/guix.texi b/doc/guix.texi index 126e542122..06f51fa3f9 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -36789,7 +36789,7 @@ Power Management Services @item connected? Is @code{#t} if @command{apcupsd} is connected to the UPS via a serial port (or a USB port). In most configurations, this will be the case. -In the case of a Slave machine where apcupsd is not directly connected +In the case of a follower machine where apcupsd is not directly connected to the UPS, this value will be @code{#f}. @item powered? diff --git a/gnu/local.mk b/gnu/local.mk index 8042ba0482..d1e7af3743 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -990,6 +990,7 @@ dist_patch_DATA = \ %D%/packages/patches/antlr3-3_1-fix-java8-compilation.patch \ %D%/packages/patches/antlr3-3_3-fix-java8-compilation.patch \ %D%/packages/patches/aoflagger-use-system-provided-pybind11.patch \ + %D%/packages/patches/apcupsd-leader-follower.patch \ %D%/packages/patches/apr-fix-atomics.patch \ %D%/packages/patches/apr-skip-getservbyname-test.patch \ %D%/packages/patches/aria2-unbundle-wslay.patch \ diff --git a/gnu/packages/patches/apcupsd-leader-follower.patch b/gnu/packages/patches/apcupsd-leader-follower.patch new file mode 100644 index 0000000000..632b6ede71 --- /dev/null +++ b/gnu/packages/patches/apcupsd-leader-follower.patch @@ -0,0 +1,1847 @@ +This replaces the master/slave termininology with leader/follower, which +is more inclusive and forward-looking. + +Index: ReleaseNotes +=================================================================== +--- ReleaseNotes (revision 2381) ++++ ReleaseNotes (working copy) +@@ -5,10 +5,15 @@ + new features over the previous 3.12.x stable series. Users of all previous + versions are encouraged to upgrade. + +-IF YOU USE THE OLD STYLE MASTER/SLAVE NETWORKING MODE, BE SURE TO READ THE ++IF YOU USE THE OLD STYLE LEADER/FOLLOWER NETWORKING MODE, BE SURE TO READ THE + 3.14.0 RELEASE NOTES BELOW. + ++3.15.0 -- TBD + ++VARIA ++ ++ * Replace master/slave terminology with leader/follower throughout project ++ + 3.14.14 -- 31 May 2016 + + BUG FIXES +Index: autoconf/configure.in +=================================================================== +--- autoconf/configure.in (revision 2381) ++++ autoconf/configure.in (working copy) +@@ -600,8 +600,8 @@ + []) + + AC_ARG_ENABLE(net, [ +-AC_HELP_STRING([--enable-net], [Compile networking driver for slaves (default)]) +-AC_HELP_STRING([--disable-net], [No network driver for slaves])], ++AC_HELP_STRING([--enable-net], [Compile networking driver for followers (default)]) ++AC_HELP_STRING([--disable-net], [No network driver for followers])], + [ if test "$enableval" = "yes" ; then + AC_DEFINE(HAVE_NET_DRIVER,, [Define if building net driver]) + NET_DRIVER="net" +Index: configure +=================================================================== +--- configure (revision 2381) ++++ configure (working copy) +@@ -1477,8 +1477,8 @@ + --enable-usb Compile USB UPS code + --disable-usb No USB UPS code (default) + +- --enable-net Compile networking driver for slaves (default) +- --disable-net No network driver for slaves ++ --enable-net Compile networking driver for followers (default) ++ --disable-net No network driver for followers + + --enable-snmp Compile SNMP driver (default) + --disable-snmp No SNMP driver +Index: doc/apcaccess.8 +=================================================================== +--- doc/apcaccess.8 (revision 2381) ++++ doc/apcaccess.8 (working copy) +@@ -92,7 +92,7 @@ + : Date and time apcupsd was started + .It STATUS + : UPS status. One or more of the following (space-separated): +-CAL TRIM BOOST ONLINE ONBATT OVERLOAD LOWBATT REPLACEBATT NOBATT SLAVE SLAVEDOWN ++CAL TRIM BOOST ONLINE ONBATT OVERLOAD LOWBATT REPLACEBATT NOBATT FOLLOWER FOLLOWERDOWN + .br + or + .br +@@ -101,8 +101,8 @@ + or + .br + SHUTTING DOWN +-.It MASTERUPD +-: Last time the master sent an update to the slave ++.It LEADERUPD ++: Last time the leader sent an update to the follower + .It ENDAPC + : Date and time of status information was written + .El +Index: doc/apccontrol.8 +=================================================================== +--- doc/apccontrol.8 (revision 2381) ++++ doc/apccontrol.8 (working copy) +@@ -34,7 +34,7 @@ + configuration file - not the name in the EEPROM of a smart UPS. + .It connected + This is 1 if apcupsd is connected to the UPS via a serial or USB port. +-In the case of a slave machine where apcupsd is not directly connected ++In the case of a follower machine where apcupsd is not directly connected + to the UPS, this value will be 0. + .It powered + This is 1 if the computer on which apcupsd is running is powered by the UPS +@@ -164,9 +164,9 @@ + .Pp + Default action -- does nothing. + .It remotedown +-apcupsd generates this event on a slave machine when it detects either (1) +-that the master has shutdown, or (2) that an onbattery event has occurred +-and communication with the master has been lost. ++apcupsd generates this event on a follower machine when it detects either (1) ++that the leader has shutdown, or (2) that an onbattery event has occurred ++and communication with the leader has been lost. + .Pp + Default action: sends "Remote Shutdown. Beginning Shutdown Sequence." to wall and exits. Immediately after this, apcupsd generates a doshutdown event to + shutdown the system. +Index: doc/apcupsd.conf.5 +=================================================================== +--- doc/apcupsd.conf.5 (revision 2381) ++++ doc/apcupsd.conf.5 (working copy) +@@ -286,7 +286,7 @@ + .Ss SHARE-UPS CONFIGURATION DIRECTIVES + .Pp + .Bl -hang -width "xxxxxxx" +-.It UPSCLASS [\& standalone | shareslave | sharemaster \&] ++.It UPSCLASS [\& standalone | sharefollower | shareleader \&] + .Pp + The default is "standalone" and should be used for + all computers powered by the UPS, with a direct connection to +@@ -293,10 +293,10 @@ + the UPS and where there are no other computers dependent on power + from the UPS. This is the "normal" case. + .Pp +-Use "shareslave" if you are using a Share-UPS interface expander ++Use "sharefollower" if you are using a Share-UPS interface expander + and connected to the BASIC port (simple signalling). + .Pp +-Use "sharemaster", if you are using a Share-UPS interface ++Use "shareleader", if you are using a Share-UPS interface + expander and connected to the ADVANCED port (smart signalling). + .Pp + .It UPSMODE [\& disable | share \&] +Index: doc/manual/manual.rst +=================================================================== +--- doc/manual/manual.rst (revision 2381) ++++ doc/manual/manual.rst (working copy) +@@ -80,7 +80,7 @@ + serial-line UPS, you'll have to read about serial installation (see + `Installation: Serial-Line UPSes`_). If you need more + details about administration for unusual situations (such as a +-master/slave or multi-UPS setup) you'll need to read the sections on ++leader/follower or multi-UPS setup) you'll need to read the sections on + those topics as well. Finally, + there are a number of technical reference sections which + gives full details on things like configuration file directives and +@@ -262,9 +262,9 @@ + + net + This is the keyword to specify if you are using your +- UPS in Slave mode (i.e. the machine is not directly connected to ++ UPS in Follower mode (i.e. the machine is not directly connected to + the UPS, but to another machine which is), and it is connected to +- the Master via an ethernet connection. You must have apcupsd's ++ the Leader via an ethernet connection. You must have apcupsd's + Network Information Services NIS turned on for this mode to work. + + snmp +@@ -1229,12 +1229,12 @@ + your halt script should things go wrong. Please consult the + specific system dependent README files for more details. + +-Please note that if you install from RPMs for a slave machine, you ++Please note that if you install from RPMs for a follower machine, you + will need to remove the changes that the RPM install script made + (similar to what is noted above) to the halt script. This is +-because on a slave machine there is no connection to the UPS, so ++because on a follower machine there is no connection to the UPS, so + there is no need to attempt to power off the UPS. That will be done +-by the master. ++by the leader. + + + Configure Options +@@ -1280,9 +1280,9 @@ + --enable-dumb Turns on generation of the dumb signalling driver code (default). + --enable-usb Turns on generation of the USB driver code. By default this is disabled. + --enable-net Turns on generation of the NIS +- network driver for slaves. For each slave, this is the only driver ++ network driver for followers. For each follower, this is the only driver + needed. This driver works by reading the information from the the +- configured master using the NIS (Network Information Services) ++ configured leader using the NIS (Network Information Services) + interface. + --enable-snmp Turns on generation of the + SNMP driver. This driver accesses the UPS over the network using +@@ -1346,7 +1346,7 @@ + checking is done on the value entered, so you must ensure that it + is a valid IP address. + --with-net-port=port This option allows +- you to specify what port apcupsd will use for Master and Slave ++ you to specify what port apcupsd will use for Leader and Follower + communications. The default is system dependent but usually 6666. + This option simply sets the appropriate port in the apcupsd.conf + file, which can be changed at any later time. +@@ -2046,22 +2046,22 @@ + change in state of the NIS server before the server has shutdown. + Normally, you have at least 30 seconds of grace time between the + time the NIS server decides to shutdown and the time it no longer +-responds. Your slave must poll during this interval. ++responds. Your follower must poll during this interval. + + Any client run using the Net driver will shutdown when its own + timers expire or when the NIS server shuts down, whichever occurs +-first. This means that if you want the slave to shutdown before the ++first. This means that if you want the follower to shutdown before the + server, you need only set ``BATTERYLEVEL``, ``MINUTES`` or + ``TIMEOUT`` on the client for a faster shutdown than the values +-defined on the NIS server. This can often be useful if the slave is +-less important than the master and you wish to reduce battery power +-consumption so that the master can remain up longer during a power ++defined on the NIS server. This can often be useful if the follower is ++less important than the leader and you wish to reduce battery power ++consumption so that the leader can remain up longer during a power + outage. + + NIS clients work principally by reading the STATFLAG record that is + sent by the NIS server (present in the output of apcaccess). The + low 16 bits are the standard APC status flag, and the upper 16 bits +-represent the internal state of apcupsd, so the slave can see when ++represent the internal state of apcupsd, so the follower can see when + the power fails and know when to shutdown. + + It would be possible to have a client also work as a server, but +@@ -2069,23 +2069,23 @@ + to the secondary client. + + +-Differences between NIS Client/Server and the old (now removed) Master/Slave modes +-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++Differences between NIS Client/Server and the old (now removed) Leader/Follower modes ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-The difference between the NIS mode and the removed master/slave ++The difference between the NIS mode and the removed leader/follower + mode is that the NIS server has no explicit knowledge of the +-slaves. The NIS server makes its information available via the net +-(NIS), and the NIS slaves read it. When the NIS server is going to +-shutdown, it makes the information available to any NIS slave that ++followers. The NIS server makes its information available via the net ++(NIS), and the NIS followers read it. When the NIS server is going to ++shutdown, it makes the information available to any NIS follower that + polls it, but the NIS server does not explicitly call each NIS +-slave as is the case in the Master/Slave networking described ++follower as is the case in the Leader/Follower networking described + several sections above. + +-Think of the difference as push (Master/Slave) vs. pull +-(NIS-based). In the case of M/S, the master makes all the shutdown +-decisions and notifies the slaves when they are to shut down or +-when some other interesting event happens. The slaves just do +-whatever the master says, whenever the master says to. On the other ++Think of the difference as push (Leader/Follower) vs. pull ++(NIS-based). In the case of M/S, the leader makes all the shutdown ++decisions and notifies the followers when they are to shut down or ++when some other interesting event happens. The followers just do ++whatever the leader says, whenever the leader says to. On the other + hand, with the NIS-based network config you basically "publish" the + UPS status from one server and then your clients view that status + and make their own decisions. +@@ -3138,7 +3138,7 @@ + ensure that the clients can reach it by opening up ``NISPORT`` + (default: TCP 3551) on any firewall running on the server. You may + wish to configure your firewall(s) to *only* allow connections from +-your local network or specifically from the masters, slaves, and ++your local network or specifically from the leaders, followers, and + servers as needed. + + +@@ -3319,12 +3319,12 @@ + device. + + :Question: +- How do I ensure that the slaves shutdown before the master? ++ How do I ensure that the followers shutdown before the leader? + :Answer: +- Slaves make their shutdown decision independently from the master. ++ Followers make their shutdown decision independently from the leader. + Therefore you can use the ``TIMEOUT``, ``MINUTES``, and ``BATTERYLEVEL`` +- settings in the slaves' apcupsd.conf to configure them to shut down +- before the master. ++ settings in the followers' apcupsd.conf to configure them to shut down ++ before the leader. + + :Question: + How do I ensure that my database server is correctly shutdown? +@@ -3408,7 +3408,7 @@ + *connected* + is 1 if apcupsd is connected to the UPS + via a serial port (or a USB port). In most configurations, this +- will be the case. In the case of a Slave machine where apcupsd is ++ will be the case. In the case of a Follower machine where apcupsd is + not directly connected to the UPS, this value will be 0. + + *powered* +@@ -3513,8 +3513,8 @@ + *Default:* nothing + + **remotedown** +- This event is generated on a slave +- machine when it detects either that the master has shutdown, or ++ This event is generated on a follower ++ machine when it detects either that the leader has shutdown, or + that a onbattery situation exists and the communications line has + been severed. + +@@ -3991,7 +3991,7 @@ + attempt to autotedect by trying "private" and "public". + (optional, default: autodetect). + +-A NIS Server/Client (Master/Slave) configuration ++A NIS Server/Client (Leader/Follower) configuration + with multiple servers is still applicable. However, an alternative + configuration is possible with an SNMP + enabled UPS. In this arrangement, all connected servers will be +@@ -4418,8 +4418,8 @@ + On some Windows systems, the + domain resolution does not seem to work if you have not configured + a DNS server in the Network section of the Control Panel. This +-problem should be apparent only when running a slave configuration. +-In this case, when you specify the name of the master in your ++problem should be apparent only when running a follower configuration. ++In this case, when you specify the name of the leader in your + apcupsd.conf file, apcupsd will be unable to resolve the name to a + valid IP address. To circumvent this problem, simply enter the + address as an IP address rather than a hostname, or alternatively, +@@ -5022,7 +5022,7 @@ + do not provide a battery exhausted signal (only testing can + determine this point). For more information, see the + `Testing Apcupsd`_ section of this manual. This +- timer can also be useful if you want some slave machines to ++ timer can also be useful if you want some follower machines to + shutdown before other machines to conserve battery power. It is + also useful for testing apcupsd because you can force a rapid + shutdown by setting a small value (e.g. 60) and pulling the plug to +@@ -5195,17 +5195,17 @@ + The following directives apply to sharing an UPS using a ShareUPS + hardware module. Most users will not use this mode. + +-**UPSCLASS** *standalone* | *shareslave* | *sharemaster* ++**UPSCLASS** *standalone* | *sharefollower* | *shareleader* + + The default is ``standalone`` and should be used for all machines + powered by the UPS and having a serial port or other direct + connection to the UPS. This is the normal case. + +- Use ``shareslave`` if and only if you are using a ShareUPS and ++ Use ``sharefollower`` if and only if you are using a ShareUPS and + connected to a BASIC Port with Simple Signal. This code is not + fully tested. + +- Use ``sharemaster``, if and only if you are using a ShareUPS and ++ Use ``shareleader``, if and only if you are using a ShareUPS and + connected to the ADVANCED Port Smart Signal control. This code is + not fully tested. + +@@ -5782,19 +5782,19 @@ + automatically reboot. In any case, your machine should have been + cleanly shut down. + +-Master/Slave Shutdown +---------------------- ++Leader/Follower Shutdown ++------------------------ + +-In master/slave configurations, however, the master cannot be 100 +-percent sure that the slaves have all shutdown before it performs ++In leader/follower configurations, however, the leader cannot be 100 ++percent sure that the followers have all shutdown before it performs + the power off. To avoid this situation, be sure to configure any +-slaves (clients) to shut down before the master by setting different ++followers (clients) to shut down before the leader by setting different + ``TIMEOUT``, ``BATTERYLEVEL``, or ``MINUTES`` parameters in the + config file. + +-Also, on a slave machine, you do not want to use the modified halt ++Also, on a follower machine, you do not want to use the modified halt + script since it will recall apcupsd, which will detect that it is a +-slave (i.e. no connection to the UPS) and will complain that it ++follower (i.e. no connection to the UPS) and will complain that it + cannot do the killpower. This situation is not harmful just + annoying and possibly confusing. + +Index: examples/Makefile +=================================================================== +--- examples/Makefile (revision 2381) ++++ examples/Makefile (working copy) +@@ -3,12 +3,12 @@ + SUBDIRS = + include $(topdir)/autoconf/targets.mak + +-TARGETS = hid-ups hid-set client megaclient newslave upsapm \ ++TARGETS = hid-ups hid-set client megaclient newfollower upsapm \ + smartsim snoopdecode + + SRCS = $(foreach target,$(TARGETS),$(target).c) + +-all-targets: client megaclient newslave upsapm smartsim snoopdecode ++all-targets: client megaclient newfollower upsapm smartsim snoopdecode + + $(TARGETS): %: $(call SRC2OBJ,%.c) $(APCLIBS) + $(LINK) +Index: examples/nagios_plugin_check_apcupsd.c +=================================================================== +--- examples/nagios_plugin_check_apcupsd.c (revision 2381) ++++ examples/nagios_plugin_check_apcupsd.c (working copy) +@@ -202,8 +202,8 @@ + retVal = NAGIOS_OK; + strcpy(sStatus, S_NAGIOS_OK); + } +- if (iStatus & UPS_slave) { +- strcat(status, "SLAVE "); ++ if (iStatus & UPS_follower) { ++ strcat(status, "FOLLOWER "); + retVal = NAGIOS_OK; + strcpy(sStatus, S_NAGIOS_OK); + } +Index: examples/newfollower.c +=================================================================== +--- examples/newfollower.c (nonexistent) ++++ examples/newfollower.c (working copy) +@@ -0,0 +1,251 @@ ++/* ++ * Client test program for apcnisd to be used ++ * as a base for the new leader/follower code. ++ * ++ * Build it with: cc newfollower.c ../lib/libapc.a -o newclient ++ * ++ * Execute: ./newfollower [host[:port]] ++ * ++ * The two commands currently (Apr 2001) accepted by the ++ * server are "status" and "events". ++ * ++ */ ++ ++#include "apc.h" ++ ++#ifdef HAVE_NISLIB ++ ++/* Default values, can be changed on command line */ ++#define SERV_TCP_PORT 3551 ++#define SERV_HOST_ADDR "127.0.0.1" ++ ++#define BIGBUF 4096 ++char statbuf[BIGBUF]; ++int statlen = BIGBUF; ++ ++/* List of variables that can be read by getupsvar() ++ * First field is that name given to getupsvar(), ++ * Second field is our internal name as produced by the STATUS ++ * output from apcupsd. ++ * Third field, if 0 returns everything to the end of the ++ * line, and if 1 returns only to first space (e.g. integers, ++ * and floating point values. ++ */ ++static struct { ++ const char *request; ++ const char *upskeyword; ++ int nfields; ++} cmdtrans[] = { ++ {"model", "MODEL", 0}, ++ {"upsmodel", "UPSMODEL", 0}, ++ {"date", "DATE", 0}, ++ {"battcap", "BCHARGE", 1}, ++ {"mbattchg", "MBATTCHG", 1}, ++ {"battvolt", "BATTV", 1}, ++ {"nombattv", "NOMBATTV", 1}, ++ {"utility", "LINEV", 1}, ++ {"upsload", "LOADPCT", 1}, ++ {"loadpct", "LOADPCT", 1}, ++ {"outputv", "OUTPUTV", 1}, ++ {"status", "STATFLAG", 1}, ++ {"linemin", "MINLINEV", 1}, ++ {"linemax", "MAXLINEV", 1}, ++ {"upstemp", "ITEMP", 1}, ++ {"outputfreq", "LINEFREQ", 1}, ++ {"translo", "LOTRANS", 1}, ++ {"transhi", "HITRANS", 1}, ++ {"runtime", "TIMELEFT", 1}, ++ {"mintimel", "MINTIMEL", 1}, ++ {"retpct", "RETPCT", 1}, /* min batt to turn on UPS */ ++ {"sense", "SENSE", 1}, ++ {"hostname", "HOSTNAME", 1}, ++ {"battdate", "BATTDATE", 1}, ++ {"serialno", "SERIALNO", 1}, ++ {"lastxfer", "LASTXFER", 0}, /* reason for last xfer to batteries */ ++ {"selftest", "SELFTEST", 1}, /* results of last self test */ ++ {"laststest", "LASTSTEST", 0}, ++ {"version", "VERSION", 1}, ++ {"upsname", "UPSNAME", 1}, ++ {"lowbatt", "DLOWBATT", 1}, /* low battery power off delay */ ++ {"battpct", "BCHARGE", 1}, ++ {"highxfer", "HITRANS", 1}, ++ {"lowxfer", "LOTRANS", 1}, ++ {"cable", "CABLE", 0}, ++ {"firmware", "FIRMWARE", 0}, ++ {NULL, NULL} ++}; ++ ++int fetch_data(char *host, int port); ++int getupsvar(char *host, int port, const char *request, char *answer, int anslen); ++int fill_buffer(int sockfd); ++ ++extern int net_errno; ++ ++void error_abort(char *msg) ++{ ++ fprintf(stderr, msg); ++ exit(1); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int port; ++ char host[200]; ++ char msg[200], *p; ++ char hostname[100]; ++ char release[100]; ++ char upsname[100]; ++ char status[100]; ++ ++ strcpy(host, SERV_HOST_ADDR); ++ port = SERV_TCP_PORT; ++ ++ if (argc > 1) { ++ strcpy(host, argv[1]); /* get host from command line */ ++ p = strchr(host, ':'); ++ if (p) { ++ *p++ = 0; ++ port = atoi(p); ++ } ++ } ++ ++ if (getupsvar(host, port, "hostname", msg, sizeof(msg)) <= 0) { ++ printf("Error getting variable\n"); ++ exit(1); ++ } ++ strcpy(hostname, msg); ++ ++ if (getupsvar(host, port, "version", msg, sizeof(msg)) <= 0) { ++ printf("Error getting variable\n"); ++ exit(1); ++ } ++ strcpy(release, msg); ++ ++ if (getupsvar(host, port, "upsname", msg, sizeof(msg)) <= 0) { ++ printf("Error getting variable\n"); ++ exit(1); ++ } ++ strcpy(upsname, msg); ++ ++ if (getupsvar(host, port, "status", msg, sizeof(msg)) <= 0) { ++ printf("Error getting variable\n"); ++ exit(1); ++ } ++ strcpy(status, msg); ++ ++ printf("For host=%s ups=%s apcupsd version=%s, the Status=%s\n", ++ hostname, upsname, release, status); ++ ++ exit(0); ++} ++ ++ ++/* ++ * Read data into memory buffer to be used by getupsvar() ++ * Returns 0 on error ++ * Returns 1 if data fetched ++ */ ++int fetch_data(char *host, int port) ++{ ++ int sockfd; ++ int stat; ++ ++ if ((sockfd = net_open(host, NULL, port)) < 0) { ++ printf("fetch_data: tcp_open failed for %s port %d", host, port); ++ return 0; ++ } ++ ++ stat = fill_buffer(sockfd); /* fill statbuf */ ++ net_close(sockfd); ++ return stat; ++ ++} ++ ++/* ++ * ++ * Returns 1 if var found ++ * answer has var ++ * Returns 0 if variable name not found ++ * answer has "Not found" is variable name not found ++ * answer may have "N/A" if the UPS does not support this ++ * feature ++ * Returns -1 if network problem ++ * answer has "N/A" if host is not available or network error ++ */ ++int getupsvar(char *host, int port, const char *request, char *answer, int anslen) ++{ ++ int i; ++ const char *stat_match = NULL; ++ char *find; ++ int nfields = 0; ++ ++ if (!fetch_data(host, port)) { ++ strcpy(answer, "N/A"); ++ return -1; ++ } ++ ++ for (i=0; cmdtrans[i].request; i++) ++ if (!(strcmp(cmdtrans[i].request, request))) { ++ stat_match = cmdtrans[i].upskeyword; ++ nfields = cmdtrans[i].nfields; ++ } ++ ++ if (stat_match != NULL) { ++ if ((find=strstr(statbuf, stat_match)) != NULL) { ++ if (nfields == 1) /* get one field */ ++ sscanf (find, "%*s %*s %s", answer); ++ else { /* get everything to eol */ ++ i = 0; ++ find += 11; /* skip label */ ++ while (*find != '\n') ++ answer[i++] = *find++; ++ answer[i] = 0; ++ } ++ if (strcmp(answer, "N/A") == 0) ++ return 0; ++ return 1; ++ } ++ } ++ ++ strcpy(answer, "Not found"); ++ return 0; ++} ++ ++#define MAXLINE 512 ++ ++/* Fill buffer with data from UPS network daemon ++ * Returns 0 on error ++ * Returns 1 if OK ++ */ ++int fill_buffer(int sockfd) ++{ ++ int n, stat = 1; ++ char buf[1000]; ++ ++ statbuf[0] = 0; ++ statlen = 0; ++ if (net_send(sockfd, "status", 6) != 6) { ++ printf("fill_buffer: write error on socket\n"); ++ return 0; ++ } ++ ++ while ((n = net_recv(sockfd, buf, sizeof(buf)-1)) > 0) { ++ buf[n] = 0; ++ strcat(statbuf, buf); ++ } ++ if (n < 0) ++ stat = 0; ++ ++ statlen = strlen(statbuf); ++ return stat; ++ ++} ++ ++#else /* HAVE_NISLIB */ ++ ++int main(int argc, char *argv[]) { ++ printf("Sorry, NIS code is not compiled in apcupsd.\n"); ++ return 1; ++} ++ ++#endif /* HAVE_NISLIB */ +Index: examples/newslave.c +=================================================================== +--- examples/newslave.c (revision 2381) ++++ examples/newslave.c (nonexistent) +@@ -1,251 +0,0 @@ +-/* +- * Client test program for apcnisd to be used +- * as a base for the new master/slave code. +- * +- * Build it with: cc newslave.c ../lib/libapc.a -o newclient +- * +- * Execute: ./newslave [host[:port]] +- * +- * The two commands currently (Apr 2001) accepted by the +- * server are "status" and "events". +- * +- */ +- +-#include "apc.h" +- +-#ifdef HAVE_NISLIB +- +-/* Default values, can be changed on command line */ +-#define SERV_TCP_PORT 3551 +-#define SERV_HOST_ADDR "127.0.0.1" +- +-#define BIGBUF 4096 +-char statbuf[BIGBUF]; +-int statlen = BIGBUF; +- +-/* List of variables that can be read by getupsvar() +- * First field is that name given to getupsvar(), +- * Second field is our internal name as produced by the STATUS +- * output from apcupsd. +- * Third field, if 0 returns everything to the end of the +- * line, and if 1 returns only to first space (e.g. integers, +- * and floating point values. +- */ +-static struct { +- const char *request; +- const char *upskeyword; +- int nfields; +-} cmdtrans[] = { +- {"model", "MODEL", 0}, +- {"upsmodel", "UPSMODEL", 0}, +- {"date", "DATE", 0}, +- {"battcap", "BCHARGE", 1}, +- {"mbattchg", "MBATTCHG", 1}, +- {"battvolt", "BATTV", 1}, +- {"nombattv", "NOMBATTV", 1}, +- {"utility", "LINEV", 1}, +- {"upsload", "LOADPCT", 1}, +- {"loadpct", "LOADPCT", 1}, +- {"outputv", "OUTPUTV", 1}, +- {"status", "STATFLAG", 1}, +- {"linemin", "MINLINEV", 1}, +- {"linemax", "MAXLINEV", 1}, +- {"upstemp", "ITEMP", 1}, +- {"outputfreq", "LINEFREQ", 1}, +- {"translo", "LOTRANS", 1}, +- {"transhi", "HITRANS", 1}, +- {"runtime", "TIMELEFT", 1}, +- {"mintimel", "MINTIMEL", 1}, +- {"retpct", "RETPCT", 1}, /* min batt to turn on UPS */ +- {"sense", "SENSE", 1}, +- {"hostname", "HOSTNAME", 1}, +- {"battdate", "BATTDATE", 1}, +- {"serialno", "SERIALNO", 1}, +- {"lastxfer", "LASTXFER", 0}, /* reason for last xfer to batteries */ +- {"selftest", "SELFTEST", 1}, /* results of last self test */ +- {"laststest", "LASTSTEST", 0}, +- {"version", "VERSION", 1}, +- {"upsname", "UPSNAME", 1}, +- {"lowbatt", "DLOWBATT", 1}, /* low battery power off delay */ +- {"battpct", "BCHARGE", 1}, +- {"highxfer", "HITRANS", 1}, +- {"lowxfer", "LOTRANS", 1}, +- {"cable", "CABLE", 0}, +- {"firmware", "FIRMWARE", 0}, +- {NULL, NULL} +-}; +- +-int fetch_data(char *host, int port); +-int getupsvar(char *host, int port, const char *request, char *answer, int anslen); +-int fill_buffer(int sockfd); +- +-extern int net_errno; +- +-void error_abort(char *msg) +-{ +- fprintf(stderr, msg); +- exit(1); +-} +- +-int main(int argc, char *argv[]) +-{ +- int port; +- char host[200]; +- char msg[200], *p; +- char hostname[100]; +- char release[100]; +- char upsname[100]; +- char status[100]; +- +- strcpy(host, SERV_HOST_ADDR); +- port = SERV_TCP_PORT; +- +- if (argc > 1) { +- strcpy(host, argv[1]); /* get host from command line */ +- p = strchr(host, ':'); +- if (p) { +- *p++ = 0; +- port = atoi(p); +- } +- } +- +- if (getupsvar(host, port, "hostname", msg, sizeof(msg)) <= 0) { +- printf("Error getting variable\n"); +- exit(1); +- } +- strcpy(hostname, msg); +- +- if (getupsvar(host, port, "version", msg, sizeof(msg)) <= 0) { +- printf("Error getting variable\n"); +- exit(1); +- } +- strcpy(release, msg); +- +- if (getupsvar(host, port, "upsname", msg, sizeof(msg)) <= 0) { +- printf("Error getting variable\n"); +- exit(1); +- } +- strcpy(upsname, msg); +- +- if (getupsvar(host, port, "status", msg, sizeof(msg)) <= 0) { +- printf("Error getting variable\n"); +- exit(1); +- } +- strcpy(status, msg); +- +- printf("For host=%s ups=%s apcupsd version=%s, the Status=%s\n", +- hostname, upsname, release, status); +- +- exit(0); +-} +- +- +-/* +- * Read data into memory buffer to be used by getupsvar() +- * Returns 0 on error +- * Returns 1 if data fetched +- */ +-int fetch_data(char *host, int port) +-{ +- int sockfd; +- int stat; +- +- if ((sockfd = net_open(host, NULL, port)) < 0) { +- printf("fetch_data: tcp_open failed for %s port %d", host, port); +- return 0; +- } +- +- stat = fill_buffer(sockfd); /* fill statbuf */ +- net_close(sockfd); +- return stat; +- +-} +- +-/* +- * +- * Returns 1 if var found +- * answer has var +- * Returns 0 if variable name not found +- * answer has "Not found" is variable name not found +- * answer may have "N/A" if the UPS does not support this +- * feature +- * Returns -1 if network problem +- * answer has "N/A" if host is not available or network error +- */ +-int getupsvar(char *host, int port, const char *request, char *answer, int anslen) +-{ +- int i; +- const char *stat_match = NULL; +- char *find; +- int nfields = 0; +- +- if (!fetch_data(host, port)) { +- strcpy(answer, "N/A"); +- return -1; +- } +- +- for (i=0; cmdtrans[i].request; i++) +- if (!(strcmp(cmdtrans[i].request, request))) { +- stat_match = cmdtrans[i].upskeyword; +- nfields = cmdtrans[i].nfields; +- } +- +- if (stat_match != NULL) { +- if ((find=strstr(statbuf, stat_match)) != NULL) { +- if (nfields == 1) /* get one field */ +- sscanf (find, "%*s %*s %s", answer); +- else { /* get everything to eol */ +- i = 0; +- find += 11; /* skip label */ +- while (*find != '\n') +- answer[i++] = *find++; +- answer[i] = 0; +- } +- if (strcmp(answer, "N/A") == 0) +- return 0; +- return 1; +- } +- } +- +- strcpy(answer, "Not found"); +- return 0; +-} +- +-#define MAXLINE 512 +- +-/* Fill buffer with data from UPS network daemon +- * Returns 0 on error +- * Returns 1 if OK +- */ +-int fill_buffer(int sockfd) +-{ +- int n, stat = 1; +- char buf[1000]; +- +- statbuf[0] = 0; +- statlen = 0; +- if (net_send(sockfd, "status", 6) != 6) { +- printf("fill_buffer: write error on socket\n"); +- return 0; +- } +- +- while ((n = net_recv(sockfd, buf, sizeof(buf)-1)) > 0) { +- buf[n] = 0; +- strcat(statbuf, buf); +- } +- if (n < 0) +- stat = 0; +- +- statlen = strlen(statbuf); +- return stat; +- +-} +- +-#else /* HAVE_NISLIB */ +- +-int main(int argc, char *argv[]) { +- printf("Sorry, NIS code is not compiled in apcupsd.\n"); +- return 1; +-} +- +-#endif /* HAVE_NISLIB */ +Index: examples/status/Back-UPS-Pro-1000.status +=================================================================== +--- examples/status/Back-UPS-Pro-1000.status (revision 2381) ++++ examples/status/Back-UPS-Pro-1000.status (working copy) +@@ -4,7 +4,7 @@ + RELEASE : 3.8.1-3 + CABLE : Custom Cable Smart + MODEL : BACK-UPS PRO 1000 +-UPSMODE : Net Master ++UPSMODE : Net Leader + STARTTIME: Thu Mar 08 11:22:12 EST 2001 + SHARE : NetworkUPS + UPSNAME : N/A +Index: examples/status/JapaneseUPS.status +=================================================================== +--- examples/status/JapaneseUPS.status (revision 2381) ++++ examples/status/JapaneseUPS.status (working copy) +@@ -1,10 +1,10 @@ + APC : 001,050,1103 + DATE : Mon Sep 11 13:51:14 JST 2000 +-HOSTNAME : master ++HOSTNAME : leader + RELEASE : 3.7.2 + CABLE : Custom Cable Smart + MODEL : APC Smart-UPS 1250 +-UPSMODE : Net Master ++UPSMODE : Net Leader + SHARE : NetworkUPS + UPSNAME : UPS_IDEN + STATUS : ONLINE +Index: examples/status/PowerStack450.status +=================================================================== +--- examples/status/PowerStack450.status (revision 2381) ++++ examples/status/PowerStack450.status (working copy) +@@ -5,7 +5,7 @@ + UPSNAME : UPS_IDEN + CABLE : Custom Cable Smart + MODEL : PowerStack 450 +-UPSMODE : Net Master ++UPSMODE : Net Leader + STARTTIME: Sun Mar 31 01:23:34 PST 2002 + SHARE : NetworkUPS + STATUS : ONLINE +Index: examples/status/SmartUPS5000.status +=================================================================== +--- examples/status/SmartUPS5000.status (revision 2381) ++++ examples/status/SmartUPS5000.status (working copy) +@@ -1,10 +1,10 @@ + APC : 001,050,1145 + DATE : Tue Aug 29 13:35:43 CEST 2000 +-HOSTNAME : net-master ++HOSTNAME : net-leader + RELEASE : 3.7.2 + CABLE : Custom Cable Smart + MODEL : SMART-UPS 5000 RM +-UPSMODE : Net Master ++UPSMODE : Net Leader + SHARE : NetworkUPS + UPSNAME : UPS_IDEN + STATUS : ONLINE +Index: examples/status/newbackupspro2.status +=================================================================== +--- examples/status/newbackupspro2.status (revision 2381) ++++ examples/status/newbackupspro2.status (working copy) +@@ -3,7 +3,7 @@ + RELEASE : 3.7.2 + CABLE : APC Cable 940-0095A + MODEL : BACK-UPS PRO 420 +-UPSMODE : Net Master ++UPSMODE : Net Leader + SHARE : NetworkUPS + UPSNAME : UPS_IDEN + STATUS : ONLINE +Index: examples/upsapm.c +=================================================================== +--- examples/upsapm.c (revision 2381) ++++ examples/upsapm.c (working copy) +@@ -1,6 +1,6 @@ + /* + * Client test program for apcnisd to be used +- * as a base for the new master/slave code. ++ * as a base for the new leader/follower code. + * + * Build it with: cc upsapm.c ../lib/libapc.a -o newclient + * +Index: examples/usb_hid_usages +=================================================================== +--- examples/usb_hid_usages (revision 2381) ++++ examples/usb_hid_usages (working copy) +@@ -1057,7 +1057,7 @@ + 0xD9 CurrentOutOfRange + 0xDA CurrentNotRegulated + 0xDB VoltageNotRegulated +- 0xDC MasterMode ++ 0xDC LeaderMode + 0xDD ChargerBattery/HostControlled + 0xF0 ChargerSpecInfo + 0xF1 ChargerSpecRef +Index: include/defines.h +=================================================================== +--- include/defines.h (revision 2381) ++++ include/defines.h (working copy) +@@ -82,8 +82,8 @@ + /* Extended bit values added by apcupsd */ + #define UPS_commlost 0x00000100 /* Communications with UPS lost */ + #define UPS_shutdown 0x00000200 /* Shutdown in progress */ +-#define UPS_slave 0x00000400 /* Set if this is a slave */ +-#define UPS_slavedown 0x00000800 /* Slave not responding */ ++#define UPS_follower 0x00000400 /* Set if this is a follower */ ++#define UPS_followerdown 0x00000800 /* Follower not responding */ + #define UPS_onbatt_msg 0x00020000 /* Set when UPS_ONBATT message is sent */ + #define UPS_fastpoll 0x00040000 /* Set on power failure to poll faster */ + #define UPS_shut_load 0x00080000 /* Set when BatLoad <= percent */ +@@ -94,7 +94,7 @@ + #define UPS_plugged 0x01000000 /* Set if computer is plugged into UPS */ + #define UPS_battpresent 0x04000000 /* Indicates if battery is connected */ + +-#define UPS_LOCAL_BITS (UPS_commlost|UPS_shutdown|UPS_slave|UPS_slavedown| \ ++#define UPS_LOCAL_BITS (UPS_commlost|UPS_shutdown|UPS_follower|UPS_followerdown| \ + UPS_onbatt_msg|UPS_fastpoll|UPS_plugged| \ + UPS_shut_load|UPS_shut_btime|UPS_shut_ltime|UPS_shut_emerg) + +Index: include/struct.h +=================================================================== +--- include/struct.h (revision 2381) ++++ include/struct.h (working copy) +@@ -68,8 +68,8 @@ + typedef enum { + NO_CLASS = 0, + STANDALONE, +- SHARESLAVE, +- SHAREMASTER, ++ SHAREFOLLOWER, ++ SHARELEADER, + } ClassMode; + + typedef enum { +@@ -158,8 +158,8 @@ + void clear_shut_load() { Status &= ~UPS_shut_load; }; + void clear_shut_ltime() { Status &= ~UPS_shut_ltime; }; + void clear_shut_remote() { Status &= ~UPS_shut_remote; }; +- void clear_slavedown() { Status &= ~UPS_slavedown; }; +- void clear_slave() { Status &= ~UPS_slave; }; ++ void clear_followerdown() { Status &= ~UPS_followerdown; }; ++ void clear_follower() { Status &= ~UPS_follower; }; + void clear_trim() { Status &= ~UPS_trim; }; + void clear_battpresent() {Status &= ~UPS_battpresent; }; + +@@ -190,9 +190,9 @@ + void set_shut_ltime() { Status |= UPS_shut_ltime; }; + void set_shut_ltime(int val) { if (val) set_shut_ltime(); else clear_shut_ltime(); }; + void set_shut_remote() { Status |= UPS_shut_remote; }; +- void set_slavedown() { Status |= UPS_slavedown; }; +- void set_slavedown(int val) { if (val) set_slavedown(); else clear_slavedown(); }; +- void set_slave() { Status |= UPS_slave; }; ++ void set_followerdown() { Status |= UPS_followerdown; }; ++ void set_followerdown(int val) { if (val) set_followerdown(); else clear_followerdown(); }; ++ void set_follower() { Status |= UPS_follower; }; + void set_trim() { Status |= UPS_trim; }; + void set_trim(int val) { if (val) set_trim(); else clear_trim(); }; + void set_battpresent() { Status |= UPS_battpresent; }; +@@ -215,8 +215,8 @@ + bool is_shut_load() const { return (Status & UPS_shut_load) == UPS_shut_load; }; + bool is_shut_ltime() const { return (Status & UPS_shut_ltime) == UPS_shut_ltime; }; + bool is_shut_remote() const { return (Status & UPS_shut_remote) == UPS_shut_remote; }; +- bool is_slave() const { return (Status & UPS_slave) == UPS_slave; }; +- bool is_slavedown() const { return (Status & UPS_slavedown) == UPS_slavedown; }; ++ bool is_follower() const { return (Status & UPS_follower) == UPS_follower; }; ++ bool is_followerdown() const { return (Status & UPS_followerdown) == UPS_followerdown; }; + bool is_trim() const { return (Status & UPS_trim) == UPS_trim; }; + bool is_battpresent() const { return (Status & UPS_battpresent) == UPS_battpresent; }; + +@@ -252,7 +252,7 @@ + time_t last_time_annoy; + time_t last_time_nologon; + time_t last_time_changeme; +- time_t last_master_connect_time; /* last time master connected */ ++ time_t last_leader_connect_time; /* last time leader connected */ + time_t start_shut_ltime; + time_t start_shut_load; + time_t start_shut_lbatt; +@@ -342,7 +342,7 @@ + int eventfilemax; /* max size of eventfile in kilobytes */ + int event_fd; /* fd for eventfile */ + +- char master_name[APC_FILENAME_MAX]; ++ char leader_name[APC_FILENAME_MAX]; + char lockpath[APC_FILENAME_MAX]; + int lockfile; + +Index: platforms/debian/packageinfo/examples +=================================================================== +--- platforms/debian/packageinfo/examples (revision 2381) ++++ platforms/debian/packageinfo/examples (working copy) +@@ -1,3 +1,3 @@ + examples/apcupsd.conf +-examples/apcupsd.slave.conf +-examples/apcupsd.master.conf ++examples/apcupsd.follower.conf ++examples/apcupsd.leader.conf +Index: platforms/etc/apcupsd.conf.in +=================================================================== +--- platforms/etc/apcupsd.conf.in (revision 2381) ++++ platforms/etc/apcupsd.conf.in (working copy) +@@ -48,7 +48,7 @@ + # setting enables autodetection, which is + # the best choice for most installations. + # +-# net hostname:port Network link to a master apcupsd through apcupsd's ++# net hostname:port Network link to a leader apcupsd through apcupsd's + # Network Information Server. This is used if the + # UPS powering your computer is connected to a + # different computer for monitoring. +@@ -236,7 +236,7 @@ + # Remaining items are for ShareUPS (APC expansion card) ONLY + # + +-# UPSCLASS [ standalone | shareslave | sharemaster ] ++# UPSCLASS [ standalone | sharefollower | shareleader ] + # Normally standalone unless you share an UPS using an APC ShareUPS + # card. + UPSCLASS standalone +Index: platforms/mingw/apccontrol.bat +=================================================================== +Cannot display: file marked as a binary type. +svn:mime-type = application/octet-stream +Index: platforms/mingw/apcupsd.conf.in +=================================================================== +--- platforms/mingw/apcupsd.conf.in (revision 2381) ++++ platforms/mingw/apcupsd.conf.in (working copy) +@@ -49,7 +49,7 @@ + # setting enables autodetection, which is + # the best choice for most installations. + # +-# net hostname:port Network link to a master apcupsd through apcupsd's ++# net hostname:port Network link to a leader apcupsd through apcupsd's + # Network Information Server. This is used if the + # UPS powering your computer is connected to a + # different computer for monitoring. +@@ -227,7 +227,7 @@ + # Remaining items are for ShareUPS (APC expansion card) ONLY + # + +-# UPSCLASS [ standalone | shareslave | sharemaster ] ++# UPSCLASS [ standalone | sharefollower | shareleader ] + # Normally standalone unless you share an UPS using an APC ShareUPS + # card. + UPSCLASS standalone +Index: platforms/openbsd/README +=================================================================== +--- platforms/openbsd/README (revision 2381) ++++ platforms/openbsd/README (working copy) +@@ -19,7 +19,7 @@ + + For most operating systems, the following sequence occurs: + 1. mains power loss +- 2. warning messages are sent from the master at various intervals ++ 2. warning messages are sent from the leader at various intervals + 3. minimum battery level or max run time is reached + 4. apcupsd invokes the control script with 'doshutdown' argument, + then exits +@@ -36,7 +36,7 @@ + modified to the following: + + 1. mains power loss +- 2. warning messages are sent from the master at various intervals ++ 2. warning messages are sent from the leader at various intervals + 3. minimum battery level or max run time is reached + 4. apcupsd sends message to UPS to power off after a configurable + number of seconds +@@ -63,7 +63,7 @@ + If the OpenBSD server is running in apcupsd networked mode with another + machine such as a Linux server, it is possible for the former to complete + the shutdown and the latter to cancel it. Depending on which machine +-is the master and which is the slave, this could either result in one ++is the leader and which is the follower, this could either result in one + machine remaining in a halted state indefinitely, or (worse) the other + machine losing power while not in a halted state. + +@@ -71,7 +71,7 @@ + mode, that shutdown cancellation be disabled on all machines. + + To date, the OpenBSD code has only been tested in standalone mode and +-as a net master, with a Slackware Linux machine as the net slave. ++as a net leader, with a Slackware Linux machine as the net follower. + + Modifying the Power Off Interval + -------------------------------- +Index: platforms/slackware/README +=================================================================== +--- platforms/slackware/README (revision 2381) ++++ platforms/slackware/README (working copy) +@@ -43,7 +43,7 @@ + action. If there is reference to rc.local in the rc.M script, then you + are probably safe. + +-If you are using the network feature (master-slave) of apcupsd and are ++If you are using the network feature (leader-follower) of apcupsd and are + running a DNS server locally, make sure the name server is up and running + before executing rc.apcupsd. Since named is normally started out of + rc.inet2, this should be a non-issue. +Index: platforms/yellowdog/apcupsd.spec.in +=================================================================== +--- platforms/yellowdog/apcupsd.spec.in (revision 2381) ++++ platforms/yellowdog/apcupsd.spec.in (working copy) +@@ -120,7 +120,6 @@ + --enable-cgi \ + --enable-pthreads \ + --enable-net \ +- --enable-master-slave \ + --enable-apcsmart \ + --enable-dumb \ + --enable-usb \ +Index: src/action.c +=================================================================== +--- src/action.c (revision 2381) ++++ src/action.c (working copy) +@@ -161,10 +161,10 @@ + } + + /* +- * For network slaves, apcupsd needs to terminate here for now. ++ * For network followers, apcupsd needs to terminate here for now. + * This is sloppy, but it works. If you are networked, then the +- * master must fall also. This is required so that the UPS +- * can reboot the slaves. ++ * leader must fall also. This is required so that the UPS ++ * can reboot the followers. + */ + if (ok == 3) + sendsig_terminate(); +@@ -210,7 +210,7 @@ + make_file(ups, ups->pwrfailpath); + prohibit_logins(ups); + +- if (!ups->is_slave()) { ++ if (!ups->is_follower()) { + /* + * Note, try avoid using this option if at all possible + * as it will shutoff the UPS power, and you cannot +@@ -485,7 +485,7 @@ + /* shutdown requested but still running */ + if (ups->is_shutdown()) { + if (ups->killdelay && now - ups->ShutDown >= ups->killdelay) { +- if (!ups->is_slave()) ++ if (!ups->is_follower()) + initiate_hibernate(ups); + ups->ShutDown = now; /* wait a bit before doing again */ + ups->set_shutdown(); +Index: src/cgi/multimon.c +=================================================================== +--- src/cgi/multimon.c (revision 2381) ++++ src/cgi/multimon.c (working copy) +@@ -85,7 +85,7 @@ + { "CAL", "CALIBRATION", 1 }, + { "CL", "COMM LOST", 2 }, + { "SD", "SHUTTING DOWN", 2 }, +- { "SLAVE", "SLAVE", 0 }, ++ { "FOLLOWER", "FOLLOWER", 0 }, + { NULL, NULL, 0 } + }; + +@@ -185,8 +185,8 @@ + strcat(status, "CL "); + if (ups_status & UPS_shutdown) + strcat(status, "SD "); +- if (ups_status & UPS_slave) +- strcat(status, "SLAVE "); ++ if (ups_status & UPS_follower) ++ strcat(status, "FOLLOWER "); + + stat = strtok (status, " "); + while (stat != NULL) { +Index: src/cgi/upsstats.c +=================================================================== +--- src/cgi/upsstats.c (revision 2381) ++++ src/cgi/upsstats.c (working copy) +@@ -298,8 +298,8 @@ + fputs("COMM LOST ", stdout); + if (status & UPS_shutdown) + fputs("SHUTDOWN ", stdout); +- if (status & UPS_slave) +- fputs("SLAVE ", stdout); ++ if (status & UPS_follower) ++ fputs("FOLLOWER ", stdout); + if (!(status & UPS_battpresent)) + fputs("NOBATT ", stdout); + fputs ("\n", stdout); +Index: src/device.c +=================================================================== +--- src/device.c (revision 2381) ++++ src/device.c (working copy) +@@ -99,9 +99,9 @@ + "ignored at %s:%d\n", ups->pwrfailpath, __FILE__, __LINE__); + } else { + /* We are on batteries, so do the kill_power */ +- if (ups->upsclass.type == SHAREMASTER) { ++ if (ups->upsclass.type == SHARELEADER) { + log_event(ups, LOG_WARNING, +- "Waiting 30 seconds for slave(s) to shutdown."); ++ "Waiting 30 seconds for follower(s) to shutdown."); + sleep(30); + } + +@@ -111,11 +111,11 @@ + + log_event(ups, LOG_WARNING, "Attempting to kill the UPS power!"); + +- if (ups->upsclass.type == SHARESLAVE) { ++ if (ups->upsclass.type == SHAREFOLLOWER) { + sleep(10); +- log_event(ups, LOG_WARNING, "Waiting For ShareUPS Master to shutdown"); ++ log_event(ups, LOG_WARNING, "Waiting For ShareUPS Leader to shutdown"); + sleep(60); +- log_event(ups, LOG_WARNING, "Failed to have power killed by Master!"); ++ log_event(ups, LOG_WARNING, "Failed to have power killed by Leader!"); + + /* + * ***FIXME*** this really should not do a reboot here, +Index: src/drivers/apcsmart/smartsetup.c +=================================================================== +--- src/drivers/apcsmart/smartsetup.c (revision 2381) ++++ src/drivers/apcsmart/smartsetup.c (working copy) +@@ -123,7 +123,7 @@ + char a = 'Y'; + + if (_ups->fd == -1) +- return 1; /* we must be a slave */ ++ return 1; /* we must be a follower */ + + /* Have to clear RTS line to access the serial cable mode PnP on BKPro */ + /* Shouldn't hurt on other cables, so just do it all the time. */ +Index: src/drivers/dumb/dumbsetup.c +=================================================================== +--- src/drivers/dumb/dumbsetup.c (revision 2381) ++++ src/drivers/dumb/dumbsetup.c (working copy) +@@ -88,7 +88,7 @@ + tcsetattr(_ups->fd, TCSANOW, &_newtio); + tcflush(_ups->fd, TCIFLUSH); + +- _ups->clear_slave(); ++ _ups->clear_follower(); + + return 1; + } +Index: src/drivers/modbus/ModbusComm.cpp +=================================================================== +--- src/drivers/modbus/ModbusComm.cpp (revision 2381) ++++ src/drivers/modbus/ModbusComm.cpp (working copy) +@@ -128,8 +128,8 @@ + if (txsz > MODBUS_MAX_PDU_SZ || rxsz > MODBUS_MAX_PDU_SZ) + return false; + +- // Prepend slave address and function code +- txfrm[0] = _slaveaddr; ++ // Prepend follower address and function code ++ txfrm[0] = _followeraddr; + txfrm[1] = fc; + + // Add PDU +@@ -173,11 +173,11 @@ + continue; + } + +- if (rxfrm[0] != _slaveaddr) ++ if (rxfrm[0] != _followeraddr) + { +- // Not from expected slave: Retry ++ // Not from expected follower: Retry + Dmsg(0, "%s: Bad address (exp=%u, rx=%u)\n", +- __func__, _slaveaddr, rxfrm[0]); ++ __func__, _followeraddr, rxfrm[0]); + continue; + } + +Index: src/drivers/modbus/ModbusComm.h +=================================================================== +--- src/drivers/modbus/ModbusComm.h (revision 2381) ++++ src/drivers/modbus/ModbusComm.h (working copy) +@@ -30,8 +30,8 @@ + class ModbusComm + { + public: +- ModbusComm(uint8_t slaveaddr = DEFAULT_SLAVE_ADDR) : +- _slaveaddr(slaveaddr), _open(false) {} ++ ModbusComm(uint8_t followeraddr = DEFAULT_FOLLOWER_ADDR) : ++ _followeraddr(followeraddr), _open(false) {} + virtual ~ModbusComm() {} + + virtual bool Open(const char *dev) = 0; +@@ -45,7 +45,7 @@ + uint16_t ModbusCrc(const uint8_t *data, unsigned int sz); + + // MODBUS constants +- static const uint8_t DEFAULT_SLAVE_ADDR = 1; ++ static const uint8_t DEFAULT_FOLLOWER_ADDR = 1; + + // MODBUS timeouts + static const unsigned int MODBUS_INTERCHAR_TIMEOUT_MS = 25; // Spec is 15, increase for compatibility with USB serial dongles +@@ -69,7 +69,7 @@ + virtual bool ModbusTx(const ModbusFrame *frm, unsigned int sz) = 0; + virtual bool ModbusRx(ModbusFrame *frm, unsigned int *sz) = 0; + +- uint8_t _slaveaddr; ++ uint8_t _followeraddr; + bool _open; + + private: +Index: src/drivers/modbus/ModbusRs232Comm.cpp +=================================================================== +--- src/drivers/modbus/ModbusRs232Comm.cpp (revision 2381) ++++ src/drivers/modbus/ModbusRs232Comm.cpp (working copy) +@@ -44,8 +44,8 @@ + #define O_BINARY 0 + #endif + +-ModbusRs232Comm::ModbusRs232Comm(uint8_t slaveaddr) : +- ModbusComm(slaveaddr), ++ModbusRs232Comm::ModbusRs232Comm(uint8_t followeraddr) : ++ ModbusComm(followeraddr), + _fd(-1) + { + } +Index: src/drivers/modbus/ModbusRs232Comm.h +=================================================================== +--- src/drivers/modbus/ModbusRs232Comm.h (revision 2381) ++++ src/drivers/modbus/ModbusRs232Comm.h (working copy) +@@ -30,7 +30,7 @@ + class ModbusRs232Comm: public ModbusComm + { + public: +- ModbusRs232Comm(uint8_t slaveaddr = DEFAULT_SLAVE_ADDR); ++ ModbusRs232Comm(uint8_t followeraddr = DEFAULT_FOLLOWER_ADDR); + virtual ~ModbusRs232Comm() {} + + virtual bool Open(const char *dev); +Index: src/drivers/modbus/ModbusUsbComm.cpp +=================================================================== +--- src/drivers/modbus/ModbusUsbComm.cpp (revision 2381) ++++ src/drivers/modbus/ModbusUsbComm.cpp (working copy) +@@ -42,8 +42,8 @@ + #define ModbusRTURx 0xFF8600FC + #define ModbusRTUTx 0xFF8600FD + +-ModbusUsbComm::ModbusUsbComm(uint8_t slaveaddr) : +- ModbusComm(slaveaddr) ++ModbusUsbComm::ModbusUsbComm(uint8_t followeraddr) : ++ ModbusComm(followeraddr) + { + } + +@@ -178,13 +178,13 @@ + { + // READ_HOLDING_REGS response includes a size byte. + // Add 3 bytes to PDU size to account for size byte itself +- // plus frame header (slaveaddr and op code). ++ // plus frame header (followeraddr and op code). + frmsz = rpt[3] + 3; + } + else if (rpt[2] == MODBUS_FC_WRITE_MULTIPLE_REGS) + { + // WRITE_MULTIPLE_REGS response is always a fixed length +- // 2 byte frame header (slaveaddr and op code) ++ // 2 byte frame header (followeraddr and op code) + // 2 byte register starting address + // 2 byte register count + frmsz = 6; +Index: src/drivers/modbus/ModbusUsbComm.h +=================================================================== +--- src/drivers/modbus/ModbusUsbComm.h (revision 2381) ++++ src/drivers/modbus/ModbusUsbComm.h (working copy) +@@ -31,7 +31,7 @@ + class ModbusUsbComm: public ModbusComm + { + public: +- ModbusUsbComm(uint8_t slaveaddr = DEFAULT_SLAVE_ADDR); ++ ModbusUsbComm(uint8_t followeraddr = DEFAULT_FOLLOWER_ADDR); + virtual ~ModbusUsbComm() {} + + virtual bool Open(const char *dev); +Index: src/drivers/net/net.c +=================================================================== +--- src/drivers/net/net.c (revision 2381) ++++ src/drivers/net/net.c (working copy) +@@ -294,7 +294,7 @@ + char answer[200]; + int stat = 1; + int32_t newStatus; /* this really should be uint32_t! */ +- int32_t masterStatus; /* status from master */ ++ int32_t leaderStatus; /* status from leader */ + + if (!_got_caps) { + get_capabilities(); +@@ -322,20 +322,20 @@ + if (!getupsvar("status", answer, sizeof(answer))) { + Dmsg(100, "HEY!!! Couldn't get status flag.\n"); + stat = 0; +- masterStatus = 0; ++ leaderStatus = 0; + } else { + /* + * Make sure we don't override local bits, and that + * all non-local bits are set/cleared correctly. + * +- * local bits = UPS_commlost|UPS_shutdown|UPS_slave|UPS_slavedown| ++ * local bits = UPS_commlost|UPS_shutdown|UPS_follower|UPS_followerdown| + * UPS_prev_onbatt|UPS_prev_battlow|UPS_onbatt_msg| + * UPS_fastpoll|UPS_plugged|UPS_dev_setup + */ + + /* First transfer set or not set all non-local bits */ +- masterStatus = strtol(answer, NULL, 0); +- newStatus = masterStatus & ~UPS_LOCAL_BITS; /* clear local bits */ ++ leaderStatus = strtol(answer, NULL, 0); ++ newStatus = leaderStatus & ~UPS_LOCAL_BITS; /* clear local bits */ + _ups->Status &= UPS_LOCAL_BITS; /* clear non-local bits */ + _ups->Status |= newStatus; /* set new non-local bits */ + +@@ -343,20 +343,20 @@ + * Now set any special bits, note this is set only, we do + * not clear these bits, but let our own core code clear them + */ +- newStatus = masterStatus & (UPS_commlost | UPS_fastpoll); ++ newStatus = leaderStatus & (UPS_commlost | UPS_fastpoll); + _ups->Status |= newStatus; + } + + Dmsg(100, "Got Status = %s 0x%x\n", answer, _ups->Status); + +- if (masterStatus & UPS_shutdown && !_ups->is_shut_remote()) { +- _ups->set_shut_remote(); /* if master is shutting down so do we */ +- log_event(_ups, LOG_ERR, "Shutdown because NIS master is shutting down."); +- Dmsg(100, "Set SHUT_REMOTE because of master status.\n"); ++ if (leaderStatus & UPS_shutdown && !_ups->is_shut_remote()) { ++ _ups->set_shut_remote(); /* if leader is shutting down so do we */ ++ log_event(_ups, LOG_ERR, "Shutdown because NIS leader is shutting down."); ++ Dmsg(100, "Set SHUT_REMOTE because of leader status.\n"); + } + + /* +- * If we lost connection with master and we ++ * If we lost connection with leader and we + * are running on batteries, shutdown on the fourth + * consequtive pass here. While on batteries, this code + * is called once per second. +@@ -365,7 +365,7 @@ + if (_comm_loss++ == 4 && !_ups->is_shut_remote()) { + _ups->set_shut_remote(); + log_event(_ups, LOG_ERR, +- "Shutdown because loss of comm with NIS master while on batteries."); ++ "Shutdown because loss of comm with NIS leader while on batteries."); + Dmsg(100, "Set SHUT_REMOTE because of loss of comm on batteries.\n"); + } + } else { +@@ -380,8 +380,8 @@ + bool NetUpsDriver::Open() + { + strlcpy(_device, _ups->device, sizeof(_device)); +- strlcpy(_ups->master_name, _ups->device, sizeof(_ups->master_name)); +- strlcpy(_ups->upsclass.long_name, "Net Slave", sizeof(_ups->upsclass.long_name)); ++ strlcpy(_ups->leader_name, _ups->device, sizeof(_ups->leader_name)); ++ strlcpy(_ups->upsclass.long_name, "Net Follower", sizeof(_ups->upsclass.long_name)); + + /* Now split the device. */ + _hostname = _device; +@@ -478,11 +478,11 @@ + return 0; + + write_lock(_ups); +- _ups->set_slave(); ++ _ups->set_follower(); + + /* ***FIXME**** poll time needs to be scanned */ + _ups->poll_time = time(NULL); +- _ups->last_master_connect_time = _ups->poll_time; ++ _ups->last_leader_connect_time = _ups->poll_time; + + if (GETVAR(CI_VLINE, "utility")) + _ups->LineVoltage = atof(answer); +Index: src/drivers/pcnet/pcnet.c +=================================================================== +--- src/drivers/pcnet/pcnet.c (revision 2381) ++++ src/drivers/pcnet/pcnet.c (working copy) +@@ -674,9 +674,9 @@ + + /* + * Note, we set _ups->fd here so the "core" of apcupsd doesn't +- * think we are a slave, which is what happens when it is -1. ++ * think we are a follower, which is what happens when it is -1. + * (ADK: Actually this only appears to be true for apctest as +- * apcupsd proper uses the UPS_slave flag.) ++ * apcupsd proper uses the UPS_follower flag.) + * Internally, we use the fd in our own private space + */ + _ups->fd = 1; +Index: src/drivers/snmplite/apc-oids.h +=================================================================== +--- src/drivers/snmplite/apc-oids.h (revision 2381) ++++ src/drivers/snmplite/apc-oids.h (working copy) +@@ -230,7 +230,7 @@ + __UNUSED__ static int upsDiagIMType[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 2, -1}; + __UNUSED__ static int upsDiagIMStatus[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 3, -1}; + __UNUSED__ static int upsDiagIMFirmwareRev[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 4, -1}; +-__UNUSED__ static int upsDiagIMSlaveFirmwareRev[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 5, -1}; ++__UNUSED__ static int upsDiagIMFollowerFirmwareRev[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 5, -1}; + __UNUSED__ static int upsDiagIMHardwareRev[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 6, -1}; + __UNUSED__ static int upsDiagIMSerialNum[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 7, -1}; + __UNUSED__ static int upsDiagIMManufactureDate[] = {1, 3, 6, 1, 4, 1, 318, 1, 1, 1, 13, 1, 2, 1, 8, -1}; +Index: src/drivers/test/testdriver.c +=================================================================== +--- src/drivers/test/testdriver.c (revision 2381) ++++ src/drivers/test/testdriver.c (working copy) +@@ -57,7 +57,7 @@ + if (!open_test_device()) + Error_abort("Cannot open UPS device %s\n", _ups->device); + +- _ups->clear_slave(); ++ _ups->clear_follower(); + write_unlock(_ups); + return true; + } +Index: src/drivers/usb/bsd/bsd-usb.c +=================================================================== +--- src/drivers/usb/bsd/bsd-usb.c (revision 2381) ++++ src/drivers/usb/bsd/bsd-usb.c (working copy) +@@ -170,9 +170,9 @@ + + /* + * Note, we set _ups->fd here so the "core" of apcupsd doesn't +- * think we are a slave, which is what happens when it is -1. ++ * think we are a follower, which is what happens when it is -1. + * (ADK: Actually this only appears to be true for apctest as +- * apcupsd proper uses the UPS_slave flag.) ++ * apcupsd proper uses the UPS_follower flag.) + * Internally, we use the fd in our own private space + */ + _ups->fd = 1; +@@ -693,7 +693,7 @@ + + bool rc = open_usb_device(); + +- _ups->clear_slave(); ++ _ups->clear_follower(); + write_unlock(_ups); + return rc; + } +Index: src/drivers/usb/generic/generic-usb.c +=================================================================== +--- src/drivers/usb/generic/generic-usb.c (revision 2381) ++++ src/drivers/usb/generic/generic-usb.c (working copy) +@@ -460,14 +460,14 @@ + + /* + * Note, we set _ups->fd here so the "core" of apcupsd doesn't +- * think we are a slave, which is what happens when it is -1. ++ * think we are a follower, which is what happens when it is -1. + * (ADK: Actually this only appears to be true for apctest as +- * apcupsd proper uses the UPS_slave flag.) ++ * apcupsd proper uses the UPS_follower flag.) + * Internally, we use the fd in our own private space + */ + _ups->fd = 1; + +- _ups->clear_slave(); ++ _ups->clear_follower(); + write_unlock(_ups); + return rc; + } +Index: src/drivers/usb/linux/linux-usb.c +=================================================================== +--- src/drivers/usb/linux/linux-usb.c (revision 2381) ++++ src/drivers/usb/linux/linux-usb.c (working copy) +@@ -213,9 +213,9 @@ + + /* + * Note, we set _ups->fd here so the "core" of apcupsd doesn't +- * think we are a slave, which is what happens when it is -1. ++ * think we are a follower, which is what happens when it is -1. + * (ADK: Actually this only appears to be true for apctest as +- * apcupsd proper uses the UPS_slave flag.) ++ * apcupsd proper uses the UPS_follower flag.) + * Internally, we use the fd in our own private space + */ + _ups->fd = 1; +@@ -642,7 +642,7 @@ + + bool rc = open_usb_device(); + +- _ups->clear_slave(); ++ _ups->clear_follower(); + write_unlock(_ups); + return rc; + } +Index: src/gapcmon/gapcmon.c +=================================================================== +--- src/gapcmon/gapcmon.c (revision 2381) ++++ src/gapcmon/gapcmon.c (working copy) +@@ -4741,7 +4741,7 @@ + + /* + * GConf2 routine +- * Handles changes to prefs_model, or the master list of monitors in the preferences page. ++ * Handles changes to prefs_model, or the leader list of monitors in the preferences page. + * Triggers for this routine should not be installed until after the + * control panel has been created. + */ +Index: src/lib/apcconfig.c +=================================================================== +--- src/lib/apcconfig.c (revision 2381) ++++ src/lib/apcconfig.c (working copy) +@@ -80,8 +80,8 @@ + + static const GENINFO upsclasses[] = { + { "standalone", "Stand Alone", STANDALONE }, +- { "shareslave", "ShareUPS Slave", SHARESLAVE }, +- { "sharemaster", "ShareUPS Master", SHAREMASTER }, ++ { "sharefollower", "ShareUPS Follower", SHAREFOLLOWER }, ++ { "shareleader", "ShareUPS Leader", SHARELEADER }, + { NULL, "*invalid-ups-class*", NO_CLASS }, + }; + +@@ -190,7 +190,7 @@ + */ + {"CONTROL", obsolete, TRUE, (GENINFO *)"CONTROL config directive is obsolete" }, + {"NETACCESS", obsolete, TRUE, (GENINFO *)"NETACCESS config directive is obsolete" }, +- {"MASTER", obsolete, TRUE, (GENINFO *)"MASTER config directive is obsolete" }, ++ {"LEADER", obsolete, TRUE, (GENINFO *)"LEADER config directive is obsolete" }, + {"USERMAGIC", obsolete, FALSE, (GENINFO *)"USERMAGIC config directive is obsolete" }, + {"SLAVE", obsolete, FALSE, (GENINFO *)"SLAVE config directive is obsolete" }, + {"NETPORT", obsolete, FALSE, (GENINFO *)"NETPORT config directive is obsolete" }, +@@ -681,7 +681,7 @@ + if (ups->annoy >= ups->annoydelay) + ups->annoydelay = 0; + +- if (ups->sharenet.type == SHAREMASTER) { ++ if (ups->sharenet.type == SHARELEADER) { + ups->maxtime = 0; + ups->percent = 10; + ups->runtime = 5; +Index: src/lib/apcexec.c +=================================================================== +--- src/lib/apcexec.c (revision 2381) ++++ src/lib/apcexec.c (working copy) +@@ -107,13 +107,13 @@ + asnprintf(cmdline, sizeof(cmdline), + "\"%s\" /E:4096 /c \"%s%s\" %s \"%s\" %d %d \"%s\"", + comspec, ups->scriptdir, APCCONTROL_FILE, cmd.command, +- ups->upsname, !ups->is_slave(), ups->is_plugged(), sbindir); ++ ups->upsname, !ups->is_follower(), ups->is_plugged(), sbindir); + } else { + /* WinNT/2K/Vista need quotes around the entire sub-command */ + asnprintf(cmdline, sizeof(cmdline), + "\"%s\" /c \"\"%s%s\" %s \"%s\" %d %d \"%s\"\"", + comspec, ups->scriptdir, APCCONTROL_FILE, cmd.command, +- ups->upsname, !ups->is_slave(), ups->is_plugged(), sbindir); ++ ups->upsname, !ups->is_follower(), ups->is_plugged(), sbindir); + } + + /* Initialize the STARTUPINFOA struct to hide the console window */ +@@ -165,7 +165,7 @@ + return SUCCESS; + } + +- asnprintf(connected, sizeof(connected), "%d", !ups->is_slave()); ++ asnprintf(connected, sizeof(connected), "%d", !ups->is_follower()); + asnprintf(powered, sizeof(powered), "%d", (int)ups->is_plugged()); + asnprintf(apccontrol, sizeof(apccontrol), "%s%s", ups->scriptdir, APCCONTROL_FILE); + +Index: src/lib/apcstatus.c +=================================================================== +--- src/lib/apcstatus.c (revision 2381) ++++ src/lib/apcstatus.c (working copy) +@@ -49,7 +49,7 @@ + */ + read_lock(ups); + +- if (ups->poll_time == 0) /* this is always zero on slave */ ++ if (ups->poll_time == 0) /* this is always zero on follower */ + ups->poll_time = now; + + /* put the last UPS poll time on the DATE record */ +@@ -73,16 +73,16 @@ + if (ups->sharenet.type != DISABLE) + s_write(ups, "SHARE : %s\n", ups->sharenet.long_name); + +- /* If slave, send last update time/date from master */ +- if (ups->is_slave()) { /* we must be a slave */ +- if (ups->last_master_connect_time == 0) { +- s_write(ups, "MASTERUPD: No connection to Master\n"); ++ /* If follower, send last update time/date from leader */ ++ if (ups->is_follower()) { /* we must be a follower */ ++ if (ups->last_leader_connect_time == 0) { ++ s_write(ups, "LEADERUPD: No connection to Leader\n"); + } else { +- format_date(ups->last_master_connect_time, datetime, sizeof(datetime)); +- s_write(ups, "MASTERUPD: %s\n", datetime); ++ format_date(ups->last_leader_connect_time, datetime, sizeof(datetime)); ++ s_write(ups, "LEADERUPD: %s\n", datetime); + } + +- s_write(ups, "MASTER : %s\n", ups->master_name); ++ s_write(ups, "LEADER : %s\n", ups->leader_name); + } + + if (ups->UPS_Cap[CI_UPSMODEL]) +@@ -118,11 +118,11 @@ + if (!ups->is_battpresent()) + strlcat(status, "NOBATT ", sizeof(status)); + +- if (ups->is_slave()) +- strlcat(status, "SLAVE ", sizeof(status)); ++ if (ups->is_follower()) ++ strlcat(status, "FOLLOWER ", sizeof(status)); + +- if (ups->is_slavedown()) +- strlcat(status, "SLAVEDOWN", sizeof(status)); ++ if (ups->is_followerdown()) ++ strlcat(status, "FOLLOWERDOWN", sizeof(status)); + + /* These override the above */ + if (ups->is_commlost()) diff --git a/gnu/packages/power.scm b/gnu/packages/power.scm index 843a907aa5..cfa3edcab8 100644 --- a/gnu/packages/power.scm +++ b/gnu/packages/power.scm @@ -32,7 +32,9 @@ (define-public apcupsd "/" name "-" version ".tar.gz")) (sha256 (base32 - "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv")))) + "0rwqiyzlg9p0szf3x6q1ppvrw6f6dbpn2rc5z623fk3bkdalhxyv")) + (patch-flags '("-p0")) + (patches (search-patches "apcupsd-leader-follower.patch")))) (outputs '("out" "doc")) (build-system gnu-build-system) (arguments diff --git a/gnu/services/power.scm b/gnu/services/power.scm index 72b2a40fef..3eeb5318f6 100644 --- a/gnu/services/power.scm +++ b/gnu/services/power.scm @@ -253,7 +253,7 @@ (define-enum cable '( simple smart ether usb 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-2000)) (define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test)) (define-enum no-logon '(disable timeout percent minutes always)) -(define-enum class '(standalone shareslave sharemaster)) +(define-enum class '(standalone sharefollower shareleader)) (define-enum mode '(disable share)) (define-configuration apcupsd-configuration @@ -315,7 +315,7 @@ (define-configuration apcupsd-configuration Most new UPSes are an USB. @item net -Network link to a master apcupsd through apcupsd's Network Information Server. +Network link to a leader apcupsd through apcupsd's Network Information Server. This is used if the UPS powering your computer is connected to a different computer for monitoring. base-commit: 8c483c12e94bcf43e4c44170f1d5fea5fbba4970 prerequisite-patch-id: 42f60b7b8949c7d41d47f400576627b868cfdacb prerequisite-patch-id: 9c6033a9adb2f18f01259f4e0152d8b442e64edd -- 2.48.1 --=-=-= Content-Type: text/plain Thank you for your patience! -- Thanks, Maxim --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v2 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 22 Feb 2025 15:07:09 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Raven Hallsby Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174023679312522 (code B ref 75528); Sat, 22 Feb 2025 15:07:09 +0000 Received: (at 75528) by debbugs.gnu.org; 22 Feb 2025 15:06:33 +0000 Received: from localhost ([127.0.0.1]:52690 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tlr5C-0003F8-UK for submit@debbugs.gnu.org; Sat, 22 Feb 2025 10:06:29 -0500 Received: from mail-qk1-x733.google.com ([2607:f8b0:4864:20::733]:51222) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tlr30-0002qd-LT for 75528@debbugs.gnu.org; Sat, 22 Feb 2025 10:04:12 -0500 Received: by mail-qk1-x733.google.com with SMTP id af79cd13be357-7c08fc20194so545826885a.2 for <75528@debbugs.gnu.org>; Sat, 22 Feb 2025 07:04:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740236639; x=1740841439; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=imunrVws00H/6bCkqpvofu5htJdAWjoS8v+RgXlyb3A=; b=XIjH7AoIad4hUMvLxDuzeNemUAaSfFsNKcjiGe2TkZn7Yh2KgvMY3Se79BR+hk1Skg HJD2DCCEdwASl+6qGJsigrx0X7JcGvB8CXuYiHBuqIYPo78IGcngApPPckfxzvXQ5uU7 ngcxLlsZDsVoF+oRAdZFsJF/5zw5B+9uUjjnZI/vkggfo5HlQAFxfofcSIBLny4D+14V IXvJ9HczXXCAxLwGUFpIyV01/irMePS3ACijxsSXBD1tg1na4qx+TxlC59HrT6XpYGMx g7lDZXZ7CPbots+0OdImDHqcdXBBaidpYH9BSu83CHDE7iO+iPePj67PbqYXUMRnT3lc fN+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740236639; x=1740841439; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=imunrVws00H/6bCkqpvofu5htJdAWjoS8v+RgXlyb3A=; b=LAMqqXsaAvctRaZ7NSAnNN++Y97FZo0yAthWC0/hM2bnZ9B9fNbGz4H281QPxPvQHa H2iTAfrBRrRdF3YchmhPx3sEeQUpUjQuV3Zc+z+S7eAlumJs8EEnH++CeoVLLwGD6DXM qnTUIRBygGjmnVOXtsKzYsgyajbdz7d6DkpBNnv3u1yULABTXS9HdtPmhyIsFERmpG0K lxurChBB+iWF7S8hU3i1BLVPsHgEtBxiju2tz2kWwQa41A8BitdCGvcqURqKI5r3KimD WzFBnu9R74DY9C9VnFLwy9WfNWOUQ859rfiwBgzDUTZXImY4Cm7Ft2VhsrtDOOisZXTP K3sQ== X-Gm-Message-State: AOJu0YzzjA/j2lx9Rmsczm7eHBE4e8wC3WvfXmMy8q45wPBb44dX/93Z esOYXZkF8roEAXLS+IyVy3m4aSNm6o84vZYDr2OAesAN6gfy/ie/HUzbtOlw2QM= X-Gm-Gg: ASbGncsNgN17BOpKm/WJCU6HfKqk6nnEIvotmlAAn1hxp3aZCwFUzB5h7EhA4BZMp3n 2jt3K4m+q9KUbaud00qObPGlmKbZqm/jWKiJmk+4VDe/jEWd5+rcjCx4ivQp2mLScftLbsu5GPp TrmRVz+MjLZ7YdPVDcO1wdxt32cbUlaDXp8yKQfx4To+eYPJMJUyhUy3xY3LQ5RFOJ8IRYN8P3m gTIpu8URkZQEMT2roS8pYTWM4GBCwS+7sCUpEM97gPE7/v0K8IYfkBUXCKTtRLz/5n3MT0mT8Sv Ns2oaEuJBzK+9u4WGniRA/Fx X-Google-Smtp-Source: AGHT+IGdV7e/YKilRpeosRQInEPDBoi4XNyvqz3f8T1/yOmQke3A+Gxwf+CHXdVdYxvA7HbSgJOIgA== X-Received: by 2002:a17:902:d50d:b0:216:5448:22a4 with SMTP id d9443c01a7336-2219ff30d0bmr128086715ad.10.1740236273282; Sat, 22 Feb 2025 06:57:53 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d545d638sm152862255ad.147.2025.02.22.06.57.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Feb 2025 06:57:52 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> (Tomas Volf's message of "Sun, 16 Feb 2025 16:16:45 +0100") References: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> Date: Sat, 22 Feb 2025 23:57:39 +0900 Message-ID: <87wmdirpr0.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, Tomas Volf <~@wolfsden.cz> writes: > * gnu/packages/power.scm (apcupsd): New variable. > * gnu/local.mk (GNU_SYSTEM_MODULES): Register the new file. Edited this one lightly: --8<---------------cut here---------------start------------->8--- modified gnu/packages/power.scm @@ -115,8 +115,9 @@ (define-public apcupsd (inputs (list libusb libusb-compat)) (home-page "http://www.apcupsd.org") (synopsis "Daemon for controlling APC UPSes") - (description "The apcupsd can be used for power management and control= ling -most of APC=E2=80=99s UPS models on Unix and Windows machines. The apcups= d works with -most of APC=E2=80=99s Smart-UPS models as well as most simple signalling m= odels such a + (description "@command{apcupsd} can be used for power management and +controlling most of @acronym{APC, American Power Conversion}=E2=80=99s @ac= ronym{UPS, +Uninterruptible Power Supply} models. @command{apcupsd} works with most of +APC=E2=80=99s Smart-UPS models as well as most simple signalling models su= ch a Back-UPS, and BackUPS-Office.") (license license:gpl2))) --8<---------------cut here---------------end--------------->8--- We do not mention Windows or other nonfree OS support in package descriptions as Guix doesn't run natively there anyway and we'd rather not advertise them. And pushed. I'm still waiting for a v3 for the service (if you can implement the match-record suggestion) to push 2/2. --=20 Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v2 1/2] gnu: Add apcupsd. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 22 Feb 2025 23:14:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.1740266025587 (code B ref 75528); Sat, 22 Feb 2025 23:14:02 +0000 Received: (at 75528) by debbugs.gnu.org; 22 Feb 2025 23:13:45 +0000 Received: from localhost ([127.0.0.1]:57723 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tlygr-00009P-8u for submit@debbugs.gnu.org; Sat, 22 Feb 2025 18:13:45 -0500 Received: from wolfsden.cz ([37.205.8.62]:36650) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tlygn-00009E-Rl for 75528@debbugs.gnu.org; Sat, 22 Feb 2025 18:13:43 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id B764B3486CF; Sat, 22 Feb 2025 23:13:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740266019; bh=pmGfZ6nEZT8H9dSYPEcShYhaSaZgfF0jcst5URcmp9U=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=TKYANn8XunKxHDMFXI4OHqfcvJedP/mpvo9JeUBlz265GTfAXaomCgCe4yrEiljQe gO6c84VEVMIK54K44cHAKTm47n2gcTsFdZP9Bjpe10Ep3SidaR+5jDZSyPeONZ2MPl FXuU3Bo6p85Q2pTIZcjGiusyXSENd2fqN5b1tCGcHpsmotxNhT7BmdDmKIQB3daj3i aZmGfmQWtAajNVpoQsx2NshCVzCqyoXrQfXgSWjx1xPH9/VB8JzecSz0a/MJFDZF2L uX750DuvsV1R0rjR/armuB8R4TpfieMqXWpF9mza++L2bup5W+m56y7wrjfGAZX4C/ 9KHYS5yn0ICPVQbWekFpd0MjrGTijGLpLdfrWhxLLCRNjd7NIi6oERvU10Vmo7zvft mUJxyd0lAB1WKn5RkTL6czJCTos3qw66Ty1cmhSVj5MPW8rp0VbKIYePChUAqo9Iq3 CIqY4wsKT1PvLsbgokQKZdRYKZurgldvg14wa3iXZYpVHrR7RnlZzESDO0St9hv4Ad jnDY3S0TijX7jkLsAahhwXfuCgZtPPcxnWD7DVZ61rVu4NJHTbOdJSU/boaRQa86eH seH1A8HJl5xtShO9U+khVZkCVuH+ljyJHh8adw1gbk44BgrjCWUCAJ1tP7CsTYhVp2 QPBEP1BraKaO+PpiYg0+XZg0= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (nat-237.starnet.cz [178.255.168.237]) by wolfsden.cz (Postfix) with ESMTPSA id BC03B3486CC; Sat, 22 Feb 2025 23:13:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740266018; bh=pmGfZ6nEZT8H9dSYPEcShYhaSaZgfF0jcst5URcmp9U=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=lWbtRwqIuzGJUTI0NhL1onN8HaeRJhNVRsOn6jgblrMhTSRfe2LhpZHJFs43saROI quxD/otq0PlTVHlCHIvzGp/XkKR+6+oDv/FlihYlioGaqQTYgU8HpM7OdzEN7LQ1dp FSzr7twv0tMon68RP+XQvOwZjggh50fQ7uLoywnDxZhGzwgUmbQbcSXln4fyrPrwPR M7pNg7bbLvIEtio7H9Uk5mzlIbDFjl6WawIsgxkw/dKemzZMTi97BvIjMCoCnnY9jO IhUD+RTg4SHH76EYf9rgmM/dAqPJ1a80cq+Gck13tRx/T4744fP9ENbmMoUEbWlQdQ PS0GO4m7dBbxCIlDV/dZjnH4Wv0N6O4QyxkOLc/niFkRzJZBKVg/ZVyYIhXSgnX+th m6r5dpKR4XLBsDzp8KAoa0zYDDXSSyk1l7edNiyBiE0Ed2/bzhVAaoumKbsxGe/w/+ hEWFbDQetokY1K/vXNKgAZGvRLKT6oX/ZSnIevciqLyiMahYDOYIC+YTBdJfhxG+fO RKxaD+eOkgJQbMWx81KoETxFpe4N5xm92jDE0j3czit0Lo5g/sL2mKJUptbnkS6Jql 556r4nffC0iMVZp9mP4l1gAT2Bud9vFkdmfO5FXX9OErCoibJFfV1K9fRUvyvXHydq MpEHB4/70ereOe0M7am/AFhs= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87wmdirpr0.fsf@gmail.com> (Maxim Cournoyer's message of "Sat, 22 Feb 2025 23:57:39 +0900") References: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> <87wmdirpr0.fsf@gmail.com> Date: Sun, 23 Feb 2025 00:13:38 +0100 Message-ID: <8734g54lp9.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > Hi, > > Tomas Volf <~@wolfsden.cz> writes: > >> * gnu/packages/power.scm (apcupsd): New variable. >> * gnu/local.mk (GNU_SYSTEM_MODULES): Register the new file. > > Edited this one lightly: > > modified gnu/packages/power.scm > @@ -115,8 +115,9 @@ (define-public apcupsd > (inputs (list libusb libusb-compat)) > (home-page "http://www.apcupsd.org") > (synopsis "Daemon for controlling APC UPSes") > - (description "The apcupsd can be used for power management and contr= olling > -most of APC=E2=80=99s UPS models on Unix and Windows machines. The apcu= psd works with > -most of APC=E2=80=99s Smart-UPS models as well as most simple signalling= models such a > + (description "@command{apcupsd} can be used for power management and > +controlling most of @acronym{APC, American Power Conversion}=E2=80=99s @= acronym{UPS, > +Uninterruptible Power Supply} models. @command{apcupsd} works with most= of > +APC=E2=80=99s Smart-UPS models as well as most simple signalling models = such a > Back-UPS, and BackUPS-Office.") > (license license:gpl2))) > > We do not mention Windows or other nonfree OS support in package > descriptions as Guix doesn't run natively there anyway and we'd rather > not advertise them. Makes sense. > > And pushed. I'm still waiting for a v3 for the service (if you can > implement the match-record suggestion) to push 2/2. Will take a look (and hopefully send the patch) tomorrow, sorry for the delays. Other things got in the way. Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAme6WiIOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wakIGQ//QkDjf8YPm7gqfR04NXymV/KvVCJ2rvKC7z04 X6eIbwUyuyh5l92MJg4dHICHazE1HYiyX5e0ZJOmoonrWByKz8ViY/8qewyA0jJA Zbcq+NQS3RH2q/Xb9puRgRUmdw4cSUcN09VV7vCOIPPGM0fj+0VlV3kWS51MCGzq Lbo7ijQ7G8ndKEjfOrUkDKdh9ObGbWJ3hT8LcvAxV4haLf4dcm+0gG8/sRy3AySd MTrICgkml6clBdKzS3I0nQT+XmQ49DDhxpv/CQSiNPs1SyaVx+ceMXkPiuxOwS3c UuzLqmlS7dBvMqUhD1llzF6tJ/JL13/SzqNHc31OLDnJU1Xkuys3aqCRPk/PGZAq uffqFZf/p5uHp8F6tOueE9Zo389YC0BesJRPr+jKe3OnKc0LXFne17rvO/vpf9yo /5OCMsiMMeJfMoo2NBy2qVxmaxOOfTgibjMmldaxJELgjlpV4t+639dKqsan08lF Ps+0m6I5Ch/MjqQ5d+h7PF7dSezCuO+KsHEutdihvSXS9INE7c55N/XIlRX32YEU V7SdgzaBMh/aVkBudE5satNfuVfyy+Sb50YyPKj4CrqmfLNB3oS9l5L/UylhbQn9 Uk/s/Zq/a9TDVpsk50yIbaB+b33TGYVgORrKEtIS97zblCdiQLFueQ0esSl2n9h5 v2vqLUs= =Qix9 -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v2 1/2] gnu: Add apcupsd. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 23 Feb 2025 01:56:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174027573628801 (code B ref 75528); Sun, 23 Feb 2025 01:56:02 +0000 Received: (at 75528) by debbugs.gnu.org; 23 Feb 2025 01:55:36 +0000 Received: from localhost ([127.0.0.1]:58293 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tm1DU-0007US-G7 for submit@debbugs.gnu.org; Sat, 22 Feb 2025 20:55:36 -0500 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]:61505) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tm1DR-0007UA-DB for 75528@debbugs.gnu.org; Sat, 22 Feb 2025 20:55:34 -0500 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-221206dbd7eso67402905ad.2 for <75528@debbugs.gnu.org>; Sat, 22 Feb 2025 17:55:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740275726; x=1740880526; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=Lu4RWK/lbo2Q5AT+eVkRdewn+x1g09bNDLTAdI8GbsQ=; b=CtQsgSIrFCUOm9wtK5u2WJJZprSZKOqOzo4/zQFTkIZBk1JU6UHJAWmXraZL8Q6d0t XKG32I0Am8Gjh3aVvaK+ljZQVLd65+2jDQZyskjFGhTOtwM02J117gutmQueCrHrPbd0 nN05uHywW1otoNszTVTYoscuSpgZoDZ7hVAgouAkF1kWPFosj45LSKDyc+8cx4Gt2fP2 yYzf+POQITKhKDGBaoKb8Px7vXPZ1zwD20Hb7AzekO+45nuJsyoooykyut7XITUJNPX9 u0eh0VYKmNfIdNklwQDvUufboa80Z4Y3mUSlBxYpqrCrpNr7cssRg1qvU+Dp3aSmhFm3 8Hcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740275726; x=1740880526; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Lu4RWK/lbo2Q5AT+eVkRdewn+x1g09bNDLTAdI8GbsQ=; b=VnG6MLJArOCv+Hj5PUoCIm3UTWBZIVd6wpegC3398vV1hJLF3m7F2dWCw1nhLcpdGi SDTncbbMDeRncyaWEXvvGpQSKxhlqLUrJVcm3/15EanGrNrmUF0r7euoJaXMmhB6uhhc sUVvmy4dSj4LFYUwuStBJ0rqb8t8WUfkHpb7drilTCSZkAtT00X4smby41tica94xWu9 rOQuRM7jSDqn7hYNljB0OdUc7fNJoAdOB04ErWQGogcW+URIemYakt5wzA0Ue8SSoy6U gsjqS+5APmOPTcruPH+EXLhIxBzi0JmhzQry/rSk4EFNQKLWj0jkQJiW8AIYb1YVR+i/ 4VOQ== X-Gm-Message-State: AOJu0Yzez27FPTm1fKSfg7juz4Yo4g4jLeZu9GnIIEca//DWr9mIw4ZN GVMpJNd9z6RRmsHUVD/XK6HU45YmRTgYE+i3Mw473s/lACbWZVuly/+IGy/rkpY= X-Gm-Gg: ASbGncuIThaPRsNCO7vdgBNYOBKpZTtzHse5OoyhhYmmB/OsXqr8/YWDMiNwkCwD2mB U5KMwUs4dDRDVEIPuRYkN0Wu5AD5e/3SFMzfeINejH8xejlo27EFTQMdJC5mIkLc1mlQN/EJzOI H+OPuzDbiUo7k1WLpOirptKH4Hos2rbNuY1NO7VyqphaPMZci7M8N6Hohw8n4JyRoH24WKwydhz Pogtqca41Ai4QgqLsrxbCeF1X+lyX798c6ev6JJPdVbsWd2UIIG4PsA9zwUXzx5m7b6q9ukiFgj tA1MSw+Akti77BtXSpKoaPpm X-Google-Smtp-Source: AGHT+IHeWCOYHCP/bvEt8q1XgFj4uFYH6X3CkTTmSx+2nYXhe07FqPXGDDgNRu/t6L+nAwFeSMclGQ== X-Received: by 2002:a17:902:f68e:b0:220:dfbd:55ed with SMTP id d9443c01a7336-2219ffbed96mr139193195ad.43.1740275726151; Sat, 22 Feb 2025 17:55:26 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d5349024sm158217465ad.8.2025.02.22.17.55.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Feb 2025 17:55:24 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <8734g54lp9.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 23 Feb 2025 00:13:38 +0100") References: <9b91fcc95120426959b89c466beadf61505fee59.1739719006.git.~@wolfsden.cz> <87wmdirpr0.fsf@gmail.com> <8734g54lp9.fsf@wolfsden.cz> Date: Sun, 23 Feb 2025 10:55:12 +0900 Message-ID: <87ikp1qvb3.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: [...] > Will take a look (and hopefully send the patch) tomorrow, sorry for the > delays. Other things got in the way. No worries, juggling with all life things is tough! -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. References: In-Reply-To: Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Sun, 23 Feb 2025 21:11:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-Xcc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174034504528302 (code B ref 75528); Sun, 23 Feb 2025 21:11:01 +0000 Received: (at 75528) by debbugs.gnu.org; 23 Feb 2025 21:10:45 +0000 Received: from localhost ([127.0.0.1]:36962 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tmJFK-0007MO-SP for submit@debbugs.gnu.org; Sun, 23 Feb 2025 16:10:45 -0500 Received: from wolfsden.cz ([37.205.8.62]:43692) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tmJFE-0007M8-Px for 75528@debbugs.gnu.org; Sun, 23 Feb 2025 16:10:40 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 9E16A349E52; Sun, 23 Feb 2025 21:10:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740345034; bh=Edoo0Fcpft9FWd7pmxQBHeTfATDn4Mdo/hccBngDacc=; h=From:To:Cc:Subject:Date; b=qsbCfSXP8yXSyyj2cO8X7E46I6Fy//IcjWxusN1Kl051aNdG3uJC4dGTGWGKN/NrE 0QklbjC8o2RnsqxO6LKT+A4ES4dxWrj5WzqQeTL0P5iRMz0mKTMpfbBH4G/PW+2ByE NY/46pxs7qb8ZOUpsaxO19FWReFGjAD6gImXHe9kHHufsqg8k3ee8s7/tN5ik4w0Sp KY/cL+ztOzisnD7vFnNMPs5jD7ErbIs4W5QfTAvsP03m9u51v9GKsbpt61/d7O9jD4 sKei4EpyDQ+qnA33aPJ0YR4bQCIkkj9xKg26tqb+NjMd/4UKmq7gi+CGnrZD5rY+DA MZu9Z3SJsRlJolxnCxXPHFdudPfRdDjL5vWUhNidotPHzFE0H+/N5y5T6FeHjV5okI 8iKWoAp0VDp4WOpPM0gk/9lgu9PXoYarnnrt+VD8kUZB9vWfRHW7BFOcmaEGYdR5Zv /mOATc5IyV6sVllagRD5Q9w6/GflvJrxALYISjDYw32oiWVSWowdfvhrgg0XPIfJG8 gu2hFkNK6Ssowc98Xsn2IUTWkRYpkJMHMWuo2HjYJyMxSQQmYZKb4lU9yBsBazSnYM N+AsS0aiV0XyNHw0568NPc8duEN6ePB+D7xyEfzKCi/i75V4liBYYjXsINh1WibECM 2R0KoaOW5+dr6AnrRvPKzBag= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 2F1DA34BE11; Sun, 23 Feb 2025 21:10:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740345031; bh=Edoo0Fcpft9FWd7pmxQBHeTfATDn4Mdo/hccBngDacc=; h=From:To:Cc:Subject:Date; b=fgUAVZAPywwSMOmHir0MzoVCHtIl7rIHafmROdQWTnQofmtwUlum/px2O7WXzx/rb D0EB+E3x9R66+elY9gVRon44k44q1AdzSU1kRP6XVNfDAkpcesr9k/9tXcLAghiMKZ nv6IXrV5C4lW4y1C3txZy5eJe4tevpJusEeq4DhNZjeKblEJuOjnQAmvseFQrdT3nx /KR6ocJg6J3e6qdG8SDfpms6mFA7yFTf3Fnu0d3GMBTdQ8EhBb5UeElREM7r6JOpm0 USGobfCC1uV+iXqn/Dx5a/u9xlSUKQ8CqDUBVcNYhzunaPY/QQzMvBA8JyXG+UEyml bv01IZOpuEeLZhM1j2T5v1rNcH6yBtWVdl7f6qh6OEGtmFGzzlcpVM7rYBDn3NATh3 VC0LaSnkDGixgDMjwjGF6bm3umK/IE2Qs8zoML5LjCYIcyYtGEjV8yhsA0+BoEVLxL oFtBM2p6e9Z+bqkbrZEUWednxq4OUh0qMwiPWcBKxcE6UAAonmWYTOLz6zbpL9cG8P vvohqiY9y99lL+bEN/YbC1M51uLZcMUrikyJ9v1n8v6KqD3XPhUSwFDW56mQmd0TVZ vehkafKsnWIL36cP7i/V4m1FjQNWdiSaXNFfhKgvSigeWLwtjmw5txt7i3wAnRMIKx dAJJNsCsFf2y61htYgPdrgpQ= From: Tomas Volf <~@wolfsden.cz> Date: Sun, 23 Feb 2025 22:10:21 +0100 Message-ID: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> X-Mailer: git-send-email 2.48.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/services/power.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Power Management Services): Document service and data types. Change-Id: If205d19bea1d20a99309626e28521a2d6fe6702f --- doc/guix.texi | 382 ++++++++++++++++++++++- gnu/local.mk | 1 + gnu/services/power.scm | 672 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1052 insertions(+), 3 deletions(-) create mode 100644 gnu/services/power.scm diff --git a/doc/guix.texi b/doc/guix.texi index 83ba0f3292..a9eb6e4da3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -123,7 +123,7 @@ Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* Copyright @copyright{} 2023 Graham James Addis@* -Copyright @copyright{} 2023, 2024 Tomas Volf@* +Copyright @copyright{} 2023-2025 Tomas Volf@* Copyright @copyright{} 2024, 2025 Herman Rimm@* Copyright @copyright{} 2024 Matthew Trzcinski@* Copyright @copyright{} 2024 Richard Sent@* @@ -422,7 +422,7 @@ Top * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -19270,7 +19270,7 @@ Services * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -36849,6 +36849,382 @@ Power Management Services @end table @end deftp +The @code{(gnu services power)} module provides a service definition for +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with +@acronym{APC, APC by Schneider Electric or formerly American Power +Conversion Corporation} @acronym{UPS, Uninterruptible Power Supply} +devices. Apcupsd also works with some @acronym{OEM, Original Equipment +Manufacturer}-branded products manufactured by APC. + +@defvar apcupsd-service-type +The service type for apcupsd. For USB UPSes no configuration is +necessary, however tweaking some fields to better suit your needs might +be desirable. The defaults are taken from the upstream configuration +and they are not very conservative (for example, the default +@code{battery-level} of 5% may be considered too low by some). + +The default event handlers do send emails, read more in +@ref{apcupsd-event-handlers}. + +@lisp +(service apcupsd-service-type) +@end lisp +@end defvar + +@deftp {Data Type} apcupsd-configuration + +Available @code{apcupsd-configuration} fields are: + +@table @asis +@item @code{apcupsd} (default: @code{apcupsd}) (type: package) +The @code{apcupsd} package to use. + +@item @code{shepherd-service-name} (default: @code{apcupsd}) (type: symbol) +The name of the shepherd service. You can add the service multiple +times with different names to manage multiple UPSes. + +@item @code{auto-start?} (default: @code{#t}) (type: boolean) +Should the shepherd service auto-start? + +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: string) +The file name of the pid file. + +@item @code{debug-level} (default: @code{0}) (type: integer) +The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} +seems reasonable to enable all the logs. + +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) +The directory containing runtime information. You need to change this +if you desire to run multiple instances of the daemon. + +@item @code{name} (type: maybe-string) +Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the +EEPROM. It should be 8 characters or less. + +@item @code{cable} (default: @code{usb}) (type: enum-cable) +The type of a cable connecting the UPS to your computer. Possible +generic choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: +@code{'940-0119A}, @code{'940-0127A}, @code{'940-0128A}, +@code{'940-0020B}, @code{'940-0020C}, @code{'940-0023A}, +@code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, +@code{'940-0095C}, @code{'940-0625A}, @code{'M-04-02-2000}. + +@item @code{type} (default: @code{usb}) (type: enum-type) +The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a +serial cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information +Server. This is used if the UPS powering your computer is connected to +a different computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless +you have a specific need for this old driver, you should use the +@code{'snmp} instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an +alternative to an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the +MODBUS protocol. + +@end table + +@item @code{device} (default: @code{""}) (type: string) +For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice +for most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. +The @var{hostname} is the ip address or hostname of the UPS on the +network. The @var{vendor} can be can be "APC" or "APC_NOTRAP". +"APC_NOTRAP" will disable SNMP trap catching; you usually want "APC". +The @var{port} is usually 161. The @var{community} is usually +"private". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. +The @var{ipaddr} is the IP address of the UPS management card. The +@var{username} and the @var{passphrase} are the credentials for which +the card has been configured. The @var{port} is the port number on +which to listen for messages from the UPS, normally 3052. If this +parameter is empty or missing, the default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it +empty for MODBUS over USB or set to the serial number of the UPS. + +@end table + +@item @code{poll-time} (default: @code{60}) (type: integer) +The interval (in seconds) at which apcupsd polls the UPS for status. +This setting applies both to directly-attached UPSes (apcsmart, usb, +dumb) and networked UPSes (net, snmp). Lowering this setting will +improve the apcupsd's responsiveness to certain events at the cost of +higher CPU utilization. + +@item @code{on-batery-delay} (default: @code{6}) (type: integer) +The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be +triggered immediately when a power failure is detected. However, the +@code{'onbattery} event will be trigger only after this delay. + +@item @code{battery-level} (default: @code{5}) (type: integer) +If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{remaining-minutes} (default: @code{3}) (type: integer) +If during a power failure, the remaining runtime in minutes (as +calculated internally by the UPS) is below or equal to this value, +apcupsd will initiate a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{timeout} (default: @code{0}) (type: integer) +If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value +of 0 disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{annoy-interval} (default: @code{300}) (type: integer) +The time in seconds between annoying users (via the @code{'annoyme} +event) to sign off prior to system shutdown. 0 disables. + +@item @code{annoy-delay} (default: @code{60}) (type: integer) +The initial delay in seconds after a power failure before warning users +to get off the system. + +@item @code{no-logon} (default: @code{disable}) (type: enum-no-logon) +The condition which determines when users are prevented from logging in +during a power failure. + +@item @code{kill-delay} (default: @code{0}) (type: integer) +If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to +kill the power. This is for use on systems where apcupsd cannot regain +control after a shutdown. + +@item @code{net-server} (default: @code{#f}) (type: boolean) +If enabled, a network information server process will be started. + +@item @code{net-server-ip} (default: @code{"127.0.0.1"}) (type: string) +An IP address on which the NIS server will listen for incoming +connections. + +@item @code{net-server-port} (default: @code{3551}) (type: integer) +An IP port on which the NIS server will listen for incoming connections. + +@item @code{net-server-events-file} (type: maybe-string) +If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name. + +@item @code{net-server-events-file-max-size} (default: @code{10}) (type: integer) +The maximum size of the events file in kilobytes. + +@item @code{class} (default: @code{standalone}) (type: enum-class) +Normally standalone unless you share an UPS using an APC ShareUPS card. + +@item @code{mode} (default: @code{disable}) (type: enum-mode) +Normally disable unless you share an UPS using an APC ShareUPS card. + +@item @code{stat-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the status file, 0 +disables. + +@item @code{log-stats} (default: @code{#f}) (type: boolean) +Also write the stats as a logs. This generates a lot of output. + +@item @code{data-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the data records to the log +file, 0 disables. + +@item @code{facility} (type: maybe-string) +The logging facility for the syslog. + +@item @code{event-handlers} (type: apcupsd-event-handlers) +Handlers for events produced by apcupsd. + +@end table +@end deftp + +@anchor{apcupsd-event-handlers} +@deftp {Data Type} apcupsd-event-handlers + +For a description of the events please refer to @samp{man 8 apccontrol}. + +Each handler shall be a gexp. It is spliced into the control script for +the daemon. In addition to the standard Guile programming environment, +the following procedures and variables are also available: + +@table @code +@item conf +Variable containing the file name of the configuration file. + +@item powerfail-file +Variable containing the file name of the powerfail file. + +@item cmd +The event currently being handled. + +@item name +The name of the UPS as specified in the configuration file. + +@item connected? +Is @code{#t} if @command{apcupsd} is connected to the UPS via a serial +port (or a USB port). In most configurations, this will be the case. +In the case of a Slave machine where apcupsd is not directly connected +to the UPS, this value will be @code{#f}. + +@item powered? +Is @code{#t} if the computer on which @command{apcupsd} is running is +powered by the UPS and @code{#f} if not. At the moment, this value is +unimplemented and always @code{#f}. + +@item (err @var{fmt} @var{args...}) +Wrapper around @code{format} outputting to @code{(current-error-port)}. + +@item (wall @var{fmt} @var{args...}) +Wrapper around @code{format} outputting via @command{wall}. + +@item (apcupsd @var{args...}) +Call @command{apcupsd} while passing the correct configuration file and +all the arguments. + +@item (mail-to-root @var{subject} @var{body}) +Send an email to the local administrator. This procedure assumes the +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} +(as would be the case with @code{opensmtpd-service-type}). + +@end table + +Available @code{apcupsd-event-handlers} fields are: + +@table @asis +@item @code{modules} (type: gexp) +Additional modules to import into the generated handler script. + +@item @code{killpower} (type: gexp) +The handler for the killpower event. + +@item @code{commfailure} (type: gexp) +The handler for the commfailure event. + +@item @code{commok} (type: gexp) +The handler for the commfailure event. + +@item @code{powerout} (type: gexp) +The handler for the powerout event. + +@item @code{onbattery} (type: gexp) +The handler for the onbattery event. + +@item @code{offbattery} (type: gexp) +The handler for the offbattery event. + +@item @code{mainsback} (type: gexp) +The handler for the mainsback event. + +@item @code{failing} (type: gexp) +The handler for the failing event. + +@item @code{timeout} (type: gexp) +The handler for the timeout event. + +@item @code{loadlimit} (type: gexp) +The handler for the loadlimit event. + +@item @code{runlimit} (type: gexp) +The handler for the runlimit event. + +@item @code{doreboot} (type: gexp) +The handler for the doreboot event. + +@item @code{doshutdown} (type: gexp) +The handler for the doshutdown event. + +@item @code{annoyme} (type: gexp) +The handler for the annoyme event. + +@item @code{emergency} (type: gexp) +The handler for the emergency event. + +@item @code{changeme} (type: gexp) +The handler for the changeme event. + +@item @code{remotedown} (type: gexp) +The handler for the remotedown event. + +@item @code{startselftest} (type: gexp) +The handler for the startselftest event. + +@item @code{endselftest} (type: gexp) +The handler for the endselftest event. + +@item @code{battdetach} (type: gexp) +The handler for the battdetach event. + +@item @code{battattach} (type: gexp) +The handler for the battattach event. + +@end table +@end deftp + @node Audio Services @subsection Audio Services diff --git a/gnu/local.mk b/gnu/local.mk index 257b66d1c2..bf82ec1c43 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -764,6 +764,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/nix.scm \ %D%/services/nfs.scm \ %D%/services/pam-mount.scm \ + %D%/services/power.scm \ %D%/services/science.scm \ %D%/services/security.scm \ %D%/services/security-token.scm \ diff --git a/gnu/services/power.scm b/gnu/services/power.scm new file mode 100644 index 0000000000..7e30955f83 --- /dev/null +++ b/gnu/services/power.scm @@ -0,0 +1,672 @@ +;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz> + +;;;; Commentary: + +;;; Power-related services. + +;;;; Code: + +(define-module (gnu services power) + #:use-module (gnu) + #:use-module (gnu packages admin) + #:use-module (gnu packages linux) + #:use-module (gnu packages power) + #:use-module (gnu services configuration) + #:use-module (gnu services shepherd) + #:use-module (gnu services) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:export (apcupsd-service-type + + apcupsd-configuration + apcupsd-configuration-apcupsd + apcupsd-configuration-shepherd-service-name + apcupsd-configuration-auto-start? + apcupsd-configuration-pid-file + apcupsd-configuration-debug-level + apcupsd-configuration-run-dir + apcupsd-configuration-name + apcupsd-configuration-cable + apcupsd-configuration-type + apcupsd-configuration-device + apcupsd-configuration-poll-time + apcupsd-configuration-on-batery-delay + apcupsd-configuration-battery-level + apcupsd-configuration-remaining-minutes + apcupsd-configuration-timeout + apcupsd-configuration-annoy-interval + apcupsd-configuration-annoy-delay + apcupsd-configuration-no-logon + apcupsd-configuration-kill-delay + apcupsd-configuration-net-server + apcupsd-configuration-net-server-ip + apcupsd-configuration-net-server-port + apcupsd-configuration-net-server-events-file + apcupsd-configuration-net-server-events-file-max-size + apcupsd-configuration-class + apcupsd-configuration-mode + apcupsd-configuration-stat-time + apcupsd-configuration-log-stats + apcupsd-configuration-data-time + apcupsd-configuration-facility + apcupsd-configuration-event-handlers + + apcupsd-event-handlers + apcupsd-event-handlers-modules + apcupsd-event-handlers-annoyme + apcupsd-event-handlers-battattach + apcupsd-event-handlers-battdetach + apcupsd-event-handlers-changeme + apcupsd-event-handlers-commfailure + apcupsd-event-handlers-commok + apcupsd-event-handlers-doreboot + apcupsd-event-handlers-doshutdown + apcupsd-event-handlers-emergency + apcupsd-event-handlers-endselftest + apcupsd-event-handlers-failing + apcupsd-event-handlers-killpower + apcupsd-event-handlers-loadlimit + apcupsd-event-handlers-mainsback + apcupsd-event-handlers-offbattery + apcupsd-event-handlers-onbattery + apcupsd-event-handlers-powerout + apcupsd-event-handlers-remotedown + apcupsd-event-handlers-runlimit + apcupsd-event-handlers-startselftest + apcupsd-event-handlers-timeout)) + +(define-configuration/no-serialization apcupsd-event-handlers + (modules + (gexp #~()) + "Additional modules to import into the generated handler script.") + (killpower + (gexp + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) + (sleep 10) + (apcupsd "--killpower") + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) + "The handler for the killpower event.") + (commfailure + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a lost." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Warning: communications lost with UPS ~a" name))) + "The handler for the commfailure event.") + (commok + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a restored." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Communications restored with UPS ~a" name))) + "The handler for the commfailure event.") + (powerout + (gexp + #~(#t)) + "The handler for the powerout event.") + (onbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power failure on UPS ~a. Running on batteries." name))) + "The handler for the onbattery event.") + (offbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power has returned." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power has returned on UPS ~a..." name))) + "The handler for the offbattery event.") + (mainsback + (gexp + #~((when (file-exists? powerfail-file) + (wall "Continuing with shutdown.")))) + "The handler for the mainsback event.") + (failing + (gexp + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name))) + "The handler for the failing event.") + (timeout + (gexp + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." name))) + "The handler for the timeout event.") + (loadlimit + (gexp + #~((wall "Remaining battery charge below limit on UPS ~a. Doing shutdown." name))) + "The handler for the loadlimit event.") + (runlimit + (gexp + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing shutdown." name))) + "The handler for the runlimit event.") + (doreboot + (gexp + #~((wall "UPS ~a initiating Reboot Sequence" name) + (system* #$(file-append shepherd "/sbin/reboot")))) + "The handler for the doreboot event.") + (doshutdown + (gexp + #~((wall "UPS ~a initiated Shutdown Sequence" name) + (system* #$(file-append shepherd "/sbin/halt")))) + "The handler for the doshutdown event.") + (annoyme + (gexp + #~((wall "Power problems with UPS ~a. Please logoff." name))) + "The handler for the annoyme event.") + (emergency + (gexp + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a." name))) + "The handler for the emergency event.") + (changeme + (gexp + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Emergency! Batteries have failed on UPS ~a. Change them NOW." name))) + "The handler for the changeme event.") + (remotedown + (gexp + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) + "The handler for the remotedown event.") + (startselftest + (gexp + #~(#t)) + "The handler for the startselftest event.") + (endselftest + (gexp + #~(#t)) + "The handler for the endselftest event.") + (battdetach + (gexp + #~(#t)) + "The handler for the battdetach event.") + (battattach + (gexp + #~(#t)) + "The handler for the battattach event.")) + +(define-syntax define-enum + (lambda (x) + (syntax-case x () + ((_ name values) + (let* ((datum/name (syntax->datum #'name)) + (datum/predicate (string->symbol + (format #f "enum-~a?" datum/name))) + (datum/serialize (string->symbol + (format #f "serialize-enum-~a" datum/name)))) + (with-syntax + ((predicate (datum->syntax x datum/predicate)) + (serialize (datum->syntax x datum/serialize))) + #'(begin + (define (predicate value) + (memq value values)) + (define serialize serialize-symbol)))))))) + +(define mangle-field-name + (match-lambda + ('name "UPSNAME") + ('cable "UPSCABLE") + ('type "UPSTYPE") + ('device "DEVICE") + ('poll-time "POLLTIME") + ('lock-dir "LOCKFILE") + ('power-fail-dir "PWRFAILDIR") + ('no-login-dir "NOLOGINDIR") + ('on-batery-delay "ONBATTERYDELAY") + ('battery-level "BATTERYLEVEL") + ('remaining-minutes "MINUTES") + ('timeout "TIMEOUT") + ('annoy-interval "ANNOY") + ('annoy-delay "ANNOYDELAY") + ('no-logon "NOLOGON") + ('kill-delay "KILLDELAY") + ('net-server "NETSERVER") + ('net-server-ip "NISIP") + ('net-server-port "NISPORT") + ('net-server-events-file "EVENTSFILE") + ('net-server-events-file-max-size "EVENTSFILEMAX") + ('class "UPSCLASS") + ('mode "UPSMODE") + ('stat-time "STATTIME") + ('stat-file "STATFILE") + ('log-stats "LOGSTATS") + ('data-time "DATATIME") + ('facility "FACILITY"))) + +(define (serialize-string field-name value) + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) +(define serialize-symbol serialize-string) +(define serialize-integer serialize-string) +(define (serialize-boolean field-name value) + #~(format #f "~a ~a\n" + #$(mangle-field-name field-name) + #$(if value "on" "off"))) + +(define-maybe string) + +(define-enum cable '( simple smart ether usb + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-2000)) +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test)) +(define-enum no-logon '(disable timeout percent minutes always)) +(define-enum class '(standalone shareslave sharemaster)) +(define-enum mode '(disable share)) + +(define-configuration apcupsd-configuration + (apcupsd (package apcupsd) "The @code{apcupsd} package to use.") + + (shepherd-service-name + (symbol 'apcupsd) + "The name of the shepherd service. You can add the service multiple times +with different names to manage multiple UPSes." + empty-serializer) + (auto-start? + (boolean #t) + "Should the shepherd service auto-start?" + empty-serializer) + (pid-file + (string "/run/apcupsd.pid") + "The file name of the PID file." + empty-serializer) + (debug-level + (integer 0) + "The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} seems +reasonable to enable all the logs." + empty-serializer) + + (run-dir + (string "/run/apcupsd") + "The directory containing runtime information. You need to change this if +you desire to run multiple instances of the daemon." + empty-serializer) + + ;; General configuration parameters + (name + maybe-string + "Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the EEPROM. +It should be 8 characters or less.") + (cable + (enum-cable 'usb) + "The type of a cable connecting the UPS to your computer. Possible generic +choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: @code{'940-0119A}, +@code{'940-0127A}, @code{'940-0128A}, @code{'940-0020B}, @code{'940-0020C}, +@code{'940-0023A}, @code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, @code{'940-0095C}, +@code{'940-0625A}, @code{'M-04-02-2000}.") + (type + (enum-type 'usb) + "The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a serial +cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information Server. +This is used if the UPS powering your computer is connected to a different +computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless you +have a specific need for this old driver, you should use the @code{'snmp} +instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an alternative to +an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the MODBUS +protocol. + +@end table") + (device + (string "") + "For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice for +most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. The +@var{hostname} is the ip address or hostname of the UPS on the network. The +@var{vendor} can be can be \"APC\" or \"APC_NOTRAP\". \"APC_NOTRAP\" will +disable SNMP trap catching; you usually want \"APC\". The @var{port} is +usually 161. The @var{community} is usually \"private\". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. The +@var{ipaddr} is the IP address of the UPS management card. The @var{username} +and the @var{passphrase} are the credentials for which the card has been +configured. The @var{port} is the port number on which to listen for messages +from the UPS, normally 3052. If this parameter is empty or missing, the +default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it empty +for MODBUS over USB or set to the serial number of the UPS. + +@end table") + (poll-time + (integer 60) + "The interval (in seconds) at which apcupsd polls the UPS for status. This +setting applies both to directly-attached UPSes (apcsmart, usb, dumb) and +networked UPSes (net, snmp). Lowering this setting will improve the apcupsd's +responsiveness to certain events at the cost of higher CPU utilization.") + + ;; Configuration parameters used during power failures + (on-batery-delay + (integer 6) + "The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be triggered +immediately when a power failure is detected. However, the @code{'onbattery} +event will be trigger only after this delay.") + (battery-level + (integer 5) + "If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (remaining-minutes + (integer 3) + "If during a power failure, the remaining runtime in minutes (as calculated +internally by the UPS) is below or equal to this value, apcupsd will initiate +a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (timeout + (integer 0) + "If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value of 0 +disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (annoy-interval + (integer 300) + "The time in seconds between annoying users (via the @code{'annoyme} event) +to sign off prior to system shutdown. 0 disables.") + (annoy-delay + (integer 60) + "The initial delay in seconds after a power failure before warning users to +get off the system.") + (no-logon + (enum-no-logon 'disable) + "The condition which determines when users are prevented from logging in +during a power failure.") + (kill-delay + (integer 0) + "If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to kill +the power. This is for use on systems where apcupsd cannot regain control +after a shutdown.") + + ;; Configuration statements for Network Information Server + (net-server + (boolean #f) + "If enabled, a network information server process will be started.") + (net-server-ip + (string "127.0.0.1") + "An IP address on which the NIS server will listen for incoming +connections.") + (net-server-port + (integer 3551) + "An IP port on which the NIS server will listen for incoming connections.") + (net-server-events-file + maybe-string + "If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name.") + (net-server-events-file-max-size + (integer 10) + "The maximum size of the events file in kilobytes.") + ;; Configuration statements used if sharing a UPS with more than one machine + (class (enum-class 'standalone) + "Normally standalone unless you share an UPS using an APC ShareUPS card.") + (mode (enum-mode 'disable) + "Normally disable unless you share an UPS using an APC ShareUPS card.") + ;; Configuration statements to control apcupsd system logging + (stat-time + (integer 0) + "The time interval in seconds between writing the status file, 0 +disables.") + (log-stats + (boolean #f) + "Also write the stats as a logs. This generates a lot of output.") + (data-time + (integer 0) + "The time interval in seconds between writing the data records to the log +file, 0 disables.") + (facility + maybe-string + "The logging facility for the syslog.") + + ;; Event handlers + (event-handlers + (apcupsd-event-handlers (apcupsd-event-handlers)) + "Handlers for events produced by apcupsd." + empty-serializer)) + +(define (%apccontrol config) + (program-file + "apccontrol" + (match-record (apcupsd-configuration-event-handlers config) + + ( killpower commfailure commok powerout onbattery offbattery mainsback + failing timeout loadlimit runlimit doreboot doshutdown annoyme + emergency changeme remotedown startselftest endselftest battdetach + battattach ) + #~(begin + (use-modules (ice-9 format) + (ice-9 match) + (ice-9 popen) + (srfi srfi-9) + #$@(apcupsd-event-handlers-modules + (apcupsd-configuration-event-handlers config))) + ;; Script dir depends on these, and the configuration depends on the + ;; script dir. To sever the cyclic dependency, pass the file names via + ;; environment variables. + (define conf (getenv "GUIX_APCUPSD_CONF")) + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) + + (define (err . args) + (apply format (current-error-port) args)) + (define (wall . args) + (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) + (define (apcupsd . args) + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) + (define (mail-to-root subject body) + (let ((port (open-pipe* OPEN_WRITE + "/run/privileged/bin/sendmail" + "-F" "apcupsd" + "root"))) + (format port "Subject: ~a~%~%~a~&" subject body) + (close-pipe port))) + (match (cdr (command-line)) + (((? string? cmd) name connected powered) + (let ((connected? (match connected + ("1" #t) + ("0" #f))) + (powered? (match powered + ("1" #t) + ("0" #f)))) + (match cmd + ("killpower" #$killpower) + ("commfailure" #$commfailure) + ("commok" #$commok) + ("powerout" #$powerout) + ("onbattery" #$onbattery) + ("offbattery" #$offbattery) + ("mainsback" #$mainsback) + ("failing" #$failing) + ("timeout" #$timeout) + ("loadlimit" #$loadlimit) + ("runlimit" #$runlimit) + ("doreboot" #$doreboot) + ("doshutdown" #$doshutdown) + ("annoyme" #$annoyme) + ("emergency" #$emergency) + ("changeme" #$changeme) + ("remotedown" #$remotedown) + ("startselftest" #$startselftest) + ("endselftest" #$endselftest) + ("battdetach" #$battdetach) + ("battattach" #$battattach) + (_ + (err "Unknown event: ~a~%" cmd) + (err "Iff the event was emitted by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))) + (args + (err "Unknown arguments: ~a~%" args) + (err "Iff the arguments were passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))))) + +(define (apcupsd-script-dir config) + (computed-file + "apcupsd-script-dir" + #~(begin + (mkdir #$output) + (chdir #$output) + (symlink #$(%apccontrol config) "apccontrol")))) + +(define (apcupsd-config-file config) + (let ((run-dir (apcupsd-configuration-run-dir config))) + (mixed-text-file + "apcupsd.conf" + "\ +## apcupsd.conf v1.1 ## +# +# for apcupsd - GNU Guix +# +# \"apcupsd\" POSIX config file (generated by apcupsd-service-type) +" + (serialize-configuration config apcupsd-configuration-fields) + ;; This one is confusing. The manual page states: + ;; + ;; > It must be changed when running more than one copy of apcupsd on the + ;; > same computer to control multiple UPSes. + ;; + ;; However would you not want the lock to be per-device, not per-process? + ;; I decided to follow the documentation, but I do not understand why it + ;; should be like this. I do not have multiple UPSes to try. + (serialize-string 'lock-dir (string-append run-dir "/lock")) + (serialize-string 'power-fail-dir run-dir) + (serialize-string 'no-login-dir run-dir) + (serialize-string 'stat-file (string-append run-dir "/apcupsd.status")) + "SCRIPTDIR " (apcupsd-script-dir config) "\n"))) + +(define (apcupsd-activation config) + (match-record config (run-dir) + #~(begin + (use-modules (guix build utils)) + (mkdir-p #$(string-append run-dir "/lock"))))) + +(define (apcupsd-shepherd-services config) + (match-record config + ( apcupsd pid-file debug-level run-dir + shepherd-service-name auto-start?) + (let ((config-file (apcupsd-config-file config))) + (list + (shepherd-service + (documentation "Run the apcupsd daemon.") + (requirement '(user-processes)) + (provision (list shepherd-service-name)) + (auto-start? auto-start?) + (start #~(make-forkexec-constructor + '(#$(file-append apcupsd "/sbin/apcupsd") + "-b" ;do not daemonize + "-f" #$config-file + "-P" #$pid-file + "-d" #$(number->string debug-level)) + #:log-file + #$(format #f "/var/log/~a.log" shepherd-service-name) + #:environment-variables + (cons* (string-append "GUIX_APCUPSD_CONF=" + #$config-file) + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE=" + run-dir "/powerfail") + (default-environment-variables)))) + (stop #~(make-kill-destructor)) + (actions (list (shepherd-configuration-action config-file)))))))) + +(define (apcupsd-pam-extensions config) + ;; The apcupsd can be configured to prevent users from logging in on certain + ;; conditions. This is implemented by creation of a "nologin" file, and + ;; using a pam nologin module to prevent the login (if the file exists). + (define pam-nologin + (pam-entry + (control "required") + (module "pam_nologin.so") + (arguments (list (string-append "file=" + (apcupsd-configuration-run-dir config) + "/nologin"))))) + + (list (pam-extension + (transformer + (lambda (pam) + (pam-service + (inherit pam) + (auth (cons pam-nologin (pam-service-auth pam))))))))) + +(define apcupsd-service-type + (service-type + (name 'apcupsd) + (description "Configure and optionally start the apcupsd.") + (extensions (list (service-extension activation-service-type + apcupsd-activation) + (service-extension shepherd-root-service-type + apcupsd-shepherd-services) + (service-extension pam-root-service-type + apcupsd-pam-extensions))) + (compose identity) + (extend (lambda (cfg lst) + (fold (cut <> <>) cfg lst))) + (default-value (apcupsd-configuration)))) -- 2.48.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH 2/2] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 23 Feb 2025 21:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174034573030351 (code B ref 75528); Sun, 23 Feb 2025 21:23:01 +0000 Received: (at 75528) by debbugs.gnu.org; 23 Feb 2025 21:22:10 +0000 Received: from localhost ([127.0.0.1]:37013 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tmJQP-0007tR-B3 for submit@debbugs.gnu.org; Sun, 23 Feb 2025 16:22:10 -0500 Received: from wolfsden.cz ([37.205.8.62]:42164) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tmJPu-0007s2-JY for 75528@debbugs.gnu.org; Sun, 23 Feb 2025 16:21:40 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id B237134C585; Sun, 23 Feb 2025 21:21:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740345696; bh=il0hvKzMi8bEQO3D+GztKwDG/kaUWY9YMdVU257+8Bc=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=HJlhJ1+VtoGkFMVVlONbQa/3vObzwAADI3tYpGFeiskh7EP8YlrsRHydjGLC63I6E U6Sn3SNloIXmyQSiFZ4Fl+adTrL939t4MHjKSZ1XXTYpWL+1/wK+U9czhih6XnSAy5 ZgqlGV1F8HNCMa/52nxiC8Qa3+mPHGcaf2HJCS3vrwzZHw/kD2liNKDtSvvx+VV3Nt GYiqU0OE2EcGGtkhgr4w4qQcBlkqHmMbAO9Ax5oEBTTmMqT3is7ssvHlwO+t0VOZdr 1r7896UZwnJDqpGWV2srbgY0KQa/4zzTdzMkfjdl8wHBQH/pvMg6Ty8QhHdfJxrpFC +w6qOCdqOYg58bHsZaL2EAqBblQ+s99gBhJ77NMqjTQ3dGIkiDvCfDzIDISce1G5UH IEj/ifP7nHnaeS1YDkk4prlRGLRqv2jelUnlB1Z7e/Ctsst8Y6L+HurdN5ug9Tjnn4 u/KLFWMB8tT1W8d+zu1CHxfg2y49Ce4Nb/nul+lyzoWliggYou4ISNmUfD8KkJMvjO dhZmNtXRaLRhrku9MHAuX//uoMJXZO1st5DxKg50dc8gu6icQMlCn8mE8ZE6UW6XTZ CsgGty5Sb66fcU8FpqZpmXMd3f1SvTjQzpRA3Z4Cn22kDnBnc2TEKbQftBa2fUz2PX 1m7qK7SNCZj/weaTfEKfMLow= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id D31E434C72E; Sun, 23 Feb 2025 21:21:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740345695; bh=il0hvKzMi8bEQO3D+GztKwDG/kaUWY9YMdVU257+8Bc=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=SU9eDwKBbQyJzUIXavf2aMyLy1FecLuRtF8aERi745HC9BL4CnPpzB/D6wapuNFRB Klcm4Sj8chyrrTWdWjodfm81hxCUNrpbLVRrHifciP+oaIF60nkC45s3bfhZ2vlI1K Vf0zxnV8jjjPSLHp6wmKDWMqk+Bwfbd8p793yIzU24VzjUT4Ha5THyEXNk+xMjiqxi nhVHQ66fKerlFiUt9qbsw6SiYK+ikHMdS5KUDRQwRxMHcBbaKUKMbKZczoJulfXuh8 EeFztUbVyj5tEas7dCCtazJQ7AK4qb7surVFzSdwo+FkCPVkLePNkJpPvbZn4hNQ3Q gpiQaVDbK8tvbwwWt5FaB54dQ7NzwzjnCSdcncDlEN+5/Ngzt+CJEbYdc9UNTbwe0+ Us8nFf9lp2ckdM/bddR3HwcWhvhUlu+9TIGYcl7bFc9pKs+v2RarrrzZEuweQbgYLn h+2zBZWy+WbUus2rTglu+6JsOTPU2242gchlEkvV5EvedAjD+o4sDZRqRxMBhj7pJ5 kwrwPC5l4HAiROV1s8qbxLFSvZme3eJoVkECJkLpdD+iMB9T/5qdEqWSiL8GM6ZJ4W ciV64r4XQV2LVVl3Ypd0n6TZAw2/7xAmbvEtZX905oDQAMJLHHnQ1vxVrUj8slqCZw mVrjvRqxUKLHBRiI3zS1YMu4= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87r03vycdh.fsf@gmail.com> (Maxim Cournoyer's message of "Tue, 18 Feb 2025 15:51:06 +0900") References: <05ba17f2babc772a26072dca72c2e6e6f852e0ad.1736722765.git.~@wolfsden.cz> <878qqk8q96.fsf@gmail.com> <874j0u7tsy.fsf@wolfsden.cz> <878qq678tq.fsf@gmail.com> <875xl9538y.fsf@wolfsden.cz> <87r03vycdh.fsf@gmail.com> Date: Sun, 23 Feb 2025 22:21:35 +0100 Message-ID: <87jz9g2w80.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > [..] >>> I just thought about it, perhaps it could be more concise to extract the >>> field values using match-record (these are bound to shorter names, since >>> they omit the 'apcupsd-configuration-' prefix). >> >> If I got the idea right, you suggest converting >> >> ("emergency" >> #$@(apcupsd-event-handlers-emergency >> (apcupsd-configuration-event-handlers cfg))) >> >> >> into >> >> ("emergency" >> #$@(match-record cfg (handlers) >> (match-record handlers (eme= rgency) >> emergency))) >> >> >> I am not sure it is increase in readability, but maybe I misunderstood >> the suggestion. > > I think something like this should work: > > modified gnu/services/power.scm > @@ -494,119 +494,67 @@ (define-configuration apcupsd-configuration > empty-serializer)) >=20=20 > (define (%apccontrol config) > - (program-file > - "apccontrol" > - #~(begin > - (use-modules (ice-9 format) > - (ice-9 match) > - (ice-9 popen) > - (srfi srfi-9) > - #$@(apcupsd-event-handlers-modules > - (apcupsd-configuration-event-handlers config))) > - ;; Script dir depends on these, and the configuration depends on = the > - ;; script dir. To sever the cyclic dependency, pass the file nam= es via > - ;; environment variables. > - (define conf (getenv "GUIX_APCUPSD_CONF")) > - (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) > - > - (define (err . args) > - (apply format (current-error-port) args)) > - (define (wall . args) > - (system* #$(file-append util-linux "/bin/wall") (apply format #= f args))) > - (define (apcupsd . args) > - (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" con= f args)) > - (define (mail-to-root subject body) > - (let ((port (open-pipe* OPEN_WRITE > - "/run/privileged/bin/sendmail" > - "-F" "apcupsd" > - "root"))) > - (format port "Subject: ~a~%~%~a~&" subject body) > - (close-pipe port))) > - (match (cdr (command-line)) > - (((? string? cmd) name connected powered) > - (let ((connected? (match connected > + (define event-handlers (apcupsd-configuration-event-handlers config)) > + (match-record event-handlers > + ( modules killpower commfailure commok powerout > + onbattery offbattery ...) > + (program-file > + "apccontrol" > + #~(begin > + (use-modules (ice-9 format) > + (ice-9 match) > + (ice-9 popen) > + (srfi srfi-9) > + #$@modules) > + ;; Script dir depends on these, and the configuration depends o= n the > + ;; script dir. To sever the cyclic dependency, pass the file n= ames via > + ;; environment variables. > + (define conf (getenv "GUIX_APCUPSD_CONF")) > + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) > + > + (define (err . args) > + (apply format (current-error-port) args)) > + > + (define (wall . args) > + (system* #$(file-append util-linux "/bin/wall") (apply format= #f args))) > + > + (define (apcupsd . args) > + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" c= onf args)) > + > + (define (mail-to-root subject body) > + (let ((port (open-pipe* OPEN_WRITE > + "/run/privileged/bin/sendmail" > + "-F" "apcupsd" > + "root"))) > + (format port "Subject: ~a~%~%~a~&" subject body) > + (close-pipe port))) > +=20=20=20=20=20=20=20=20=20 > + (match (cdr (command-line)) > + (((? string? cmd) name connected powered) > + (let ((connected? (match connected > + ("1" #t) > + ("0" #f))) > + (powered? (match powered > ("1" #t) > - ("0" #f))) > - (powered? (match powered > - ("1" #t) > - ("0" #f)))) > - (match cmd > - ;; I am sure this could be done by macro, but meh. Last r= elease > - ;; of apcupsd was in 2016, so maintaining this will not be= much > - ;; work. > - ("killpower" > - #$@(apcupsd-event-handlers-killpower > - (apcupsd-configuration-event-handlers config))) > - ("commfailure" > - #$@(apcupsd-event-handlers-commfailure > - (apcupsd-configuration-event-handlers config))) > - ("commok" > - #$@(apcupsd-event-handlers-commok > - (apcupsd-configuration-event-handlers config))) > - ("powerout" > - #$@(apcupsd-event-handlers-powerout > - (apcupsd-configuration-event-handlers config))) > - ("onbattery" > - #$@(apcupsd-event-handlers-onbattery > - (apcupsd-configuration-event-handlers config))) > - ("offbattery" > - #$@(apcupsd-event-handlers-offbattery > - (apcupsd-configuration-event-handlers config))) > - ("mainsback" > - #$@(apcupsd-event-handlers-mainsback > - (apcupsd-configuration-event-handlers config))) > - ("failing" > - #$@(apcupsd-event-handlers-failing > - (apcupsd-configuration-event-handlers config))) > - ("timeout" > - #$@(apcupsd-event-handlers-timeout > - (apcupsd-configuration-event-handlers config))) > - ("loadlimit" > - #$@(apcupsd-event-handlers-loadlimit > - (apcupsd-configuration-event-handlers config))) > - ("runlimit" > - #$@(apcupsd-event-handlers-runlimit > - (apcupsd-configuration-event-handlers config))) > - ("doreboot" > - #$@(apcupsd-event-handlers-doreboot > - (apcupsd-configuration-event-handlers config))) > - ("doshutdown" > - #$@(apcupsd-event-handlers-doshutdown > - (apcupsd-configuration-event-handlers config))) > - ("annoyme" > - #$@(apcupsd-event-handlers-annoyme > - (apcupsd-configuration-event-handlers config))) > - ("emergency" > - #$@(apcupsd-event-handlers-emergency > - (apcupsd-configuration-event-handlers config))) > - ("changeme" > - #$@(apcupsd-event-handlers-changeme > - (apcupsd-configuration-event-handlers config))) > - ("remotedown" > - #$@(apcupsd-event-handlers-remotedown > - (apcupsd-configuration-event-handlers config))) > - ("startselftest" > - #$@(apcupsd-event-handlers-startselftest > - (apcupsd-configuration-event-handlers config))) > - ("endselftest" > - #$@(apcupsd-event-handlers-endselftest > - (apcupsd-configuration-event-handlers config))) > - ("battdetach" > - #$@(apcupsd-event-handlers-battdetach > - (apcupsd-configuration-event-handlers config))) > - ("battattach" > - #$@(apcupsd-event-handlers-battattach > - (apcupsd-configuration-event-handlers config))) > - (_ > - (err "Unknown event: ~a~%" cmd) > - (err "Iff the event was emitted by apcupsd, this is a bug= .~%") > - (err "Please report to bug-guix@gnu.org.~%") > - (exit #f))))) > - (args > - (err "Unknown arguments: ~a~%" args) > - (err "Iff the arguments were passed by apcupsd, this is a bug.= ~%") > - (err "Please report to bug-guix@gnu.org.~%") > - (exit #f)))))) > + ("0" #f)))) > + (match cmd > + ("killpower" #$killpower) > + ("commfailure" #$commfailure) > + ("commok" #$commok) > + ("powerout" #$powerout) > + ("onbattery" #$onbattery) > + ("offbattery" #$offbattery) > + [...] > + (_ > + (err "Unknown event: ~a~%" cmd) > + (err "If the event was emitted by apcupsd, this is a bu= g.~%") > + (err "Please report to bug-guix@gnu.org.~%") > + (exit #f))))) > + (args > + (err "Unknown arguments: ~a~%" args) > + (err "If the arguments were passed by apcupsd, this is a bug= .~%") > + (err "Please report to bug-guix@gnu.org.~%") > + (exit #f)))))))) >=20=20 > (define (apcupsd-script-dir config) > (computed-file > > [...] I get the idea now, thank you. Yes, that is *much* nicer. Updated. > [..] > I'll let you work through my last match-record suggestion above, if you > want and send a v3. Incorporated and v3 sent. This time a single patch, since the package was already merged. > > I'm also attaching a fixup with the terminology changes I've submitted > upstream if you'd like to validate it still works (I don't have any > UPS to try it with myself). Thank you, but I will pass on that. I respect your choice to invest time into this effort, but for me this issue it not high enough on my priority list to do the same. Have a nice day, Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAme7kV8OHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/walzCBAAkJIp59W6bm0O5lXkXNQXC5TDfeHGkxtfP6i/ /eIH6HOyln9+AmMltb2ppmRI3ZtGPBXVv6ix9mzDuFlq9AG/xRQF9u8pZaWUb2q0 kaSR1JWwSpVbKEEmZbM1/CkaKnLqL2/bYVT+eHRSXb3Gopoqlgx/+h+R9OFpe/mX UywKOBAwGxGzdIMB/i0uyVutuG5rPsjnGfGnTBqCKggcYW33ELkwVZ/39PXaiBfc dm2n6hTl/iXr+Tas3niQx3YQavqapAkDdFcffuCZQS6Sv6VBzHOAJxtF7XCevvVc RT15Y+mk2v1Ajf5+gRHkXpOH7zfg/4ALFC8nTU9VSUxEQDLfbn0F/cnzSQLKc6A+ W1T65RHyE2voK1e9WpK4xa5QH3I7lrkGLIWULJgOZYITHt/QGooQ+8H4z1Z44gdx vdq9CQbGjCxb6OZi/61i4bpT8Iv3v8slplVwqPyq5wVAzjMUdT3mjgwObEYrfgpx iYPWBn3G69YkqW89rxr9ju6MwoHSp6qvOexjbbGdaGZbitKpfUhKvuw2QvcpQN2q 4oc4FQgmfK5Mjd7AkE3EDW6z0iqOlEQJOPqYVUhNfGDl6eBTWx2Tn48DJJtpwETM F0B5cEjzRGosFtDDqZYTNbQiHpdiwIhH8mpBh7OnIAqUDeV370dZbcGTnmd3fx1K CYAi8HE= =hzbK -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 28 Feb 2025 02:13:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.17407087427911 (code B ref 75528); Fri, 28 Feb 2025 02:13:01 +0000 Received: (at 75528) by debbugs.gnu.org; 28 Feb 2025 02:12:22 +0000 Received: from localhost ([127.0.0.1]:41481 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tnprR-00023W-AE for submit@debbugs.gnu.org; Thu, 27 Feb 2025 21:12:21 -0500 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]:58674) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tnprN-00022N-4b for 75528@debbugs.gnu.org; Thu, 27 Feb 2025 21:12:18 -0500 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-2210d92292eso42190105ad.1 for <75528@debbugs.gnu.org>; Thu, 27 Feb 2025 18:12:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740708731; x=1741313531; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=uarbYvXMq8KyQbq0/vkSm8zrD1jo/dUu/LOAu+8ld8Q=; b=MBvHArFGlBh/zGW2N/+BAMcG+IkK2YOskw3fnQleKOAKeow2muRer93xyvMsRZkVP/ wsLadeWxUBzhOIBfcPPmUYuj2iVEZE49e3uTkbE17rhrSOP+yj2zehYPLrfvIbvaPrSK ujtALDqYHlFDJTWeD1yXoyaHeHniA8/Q/F1FNKLX+vHQOOcyFa6fZLfC7h+vR5koaBhX QIlKcW/lH6xDDGFtkw5+Y7jMFOCYsn0NFMvxVduJJqK9qoQMrX4SlTRpDi4OHSa1KXhn oP2Z9f0PxJSXn0xSw6SpExrYl5LekLKhEXPn3l9h3IavI6AUmXPZ+k8jGH339vDQ1MKt F1IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740708731; x=1741313531; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=uarbYvXMq8KyQbq0/vkSm8zrD1jo/dUu/LOAu+8ld8Q=; b=MjZ6Gd/vYlqSHa5YTUnd63onzjWrqDXp0OtPBBLI1yai/Qyd6LOnK0+S5sTIeupG1M kVbsDIHyCWdh6GM+QbYnAagyFVvUUH9mH6eW1pPwvjxaewL1EEqJeFLfWi1b5H4Ldrl6 ytjJJR9lEGau0IFp//aM642TifIchr/POTxdA/Yl/F951VZjYD3Hxjxg5+pRXuRRlg/g 36TdGV/P0TcJqWpyIiLyIN/YkGJ16U/fN35QYUez730jyxfV/CJY/4NOTvw0HicZ82+7 CqR0myuhCfEQ/VYRFLr+7NObyy/MEuK7fJVdstwcF8IXZPW7FWKsZeKSavAd0jOaNckf IcHg== X-Gm-Message-State: AOJu0YxOl73IcOeUpPOHja9mDpuy8n90EgHbJBnfJ2jsz87Y/z1kzVnu eUZxLRmzRGEs8aLg3pBOBw32k42BH6DTmY7VnRvX0dCEFbVrcqnP X-Gm-Gg: ASbGncuIxDyduGCd8w1I7I5CPQxUWdf1g4lHYNxQ4iukr5CMhBEG8Vmc6yj6UmykPEN 8hOh3nnK90XUfEZHE3awLPl+KHnhqsKX2sfpo6JErEJSit0sRpWAHw03+FURpU4IMCncwJ2hij9 usxMVNiXB132gBI5OKsN6sU2+6AruqNgQASpuAjUPiqvVsfm8sJ8cNAgYLcKrpgxqeNtr1JH37v Se2L07bNFhb4aA4A/HHW0Fwr+e7V9Se0b5QYrZFZTeAPe+ZUGHtKyALmhxz8yoC2KSq7cY8yB9e XkOSndMF8bPDPhDo4sUHmVtc X-Google-Smtp-Source: AGHT+IHB/AMU1KctpSZK+0TnbnfPYfMWMmkxrwcdUbFKlGTkBLkp7iUi9BgcJjyh2r4t0Y6QQ7oqBg== X-Received: by 2002:a05:6a00:390f:b0:732:a24:7354 with SMTP id d2e1a72fcca58-734ac32d058mr2641361b3a.4.1740708730645; Thu, 27 Feb 2025 18:12:10 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7349fe6f0eesm2529300b3a.82.2025.02.27.18.12.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Feb 2025 18:12:10 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> (Tomas Volf's message of "Sun, 23 Feb 2025 22:10:21 +0100") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> Date: Fri, 28 Feb 2025 11:11:56 +0900 Message-ID: <87ecziizrn.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, I was about to merge this, but I have one last (I promise!) question, see below. Tomas Volf <~@wolfsden.cz> writes: [...] > +(define apcupsd-service-type > + (service-type > + (name 'apcupsd) > + (description "Configure and optionally start the apcupsd.") > + (extensions (list (service-extension activation-service-type > + apcupsd-activation) > + (service-extension shepherd-root-service-type > + apcupsd-shepherd-services) > + (service-extension pam-root-service-type > + apcupsd-pam-extensions))) > + (compose identity) > + (extend (lambda (cfg lst) > + (fold (cut <> <>) cfg lst))) What does the above extend does? I find the (cut <> <>) particularly cryptic, as it's typically used to specialize procedures, which there are none above. -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 01 Mar 2025 23:47:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174087278016899 (code B ref 75528); Sat, 01 Mar 2025 23:47:01 +0000 Received: (at 75528) by debbugs.gnu.org; 1 Mar 2025 23:46:20 +0000 Received: from localhost ([127.0.0.1]:46713 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1toWXD-0004OM-0W for submit@debbugs.gnu.org; Sat, 01 Mar 2025 18:46:19 -0500 Received: from wolfsden.cz ([37.205.8.62]:47426) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1toWXA-0004O3-RD for 75528@debbugs.gnu.org; Sat, 01 Mar 2025 18:46:18 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 91D7235514D; Sat, 1 Mar 2025 23:46:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740872775; bh=djD1M0kwvCF4Uc5xIAlJhThCN3RrpiJjGEQAeu446Uc=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=qK2MoPmdLu9dLBG2liTH+Z0PaTfA+NOZeui5InlFVkQxBVWlAc3PnZITU0/ef6WT7 Sfm0JdNpW8KJE6kzAh51cy1S/2GpCbm0t+X6aa1BUrVRjitfg3kIn5c0Pzs2E6izzc m2kPfsJrcUbPw6foLTtNzNsJ8P1YiUbdX61tgo54WMCWZrqXJEyo373pmh9GTIbPhl jRhfiWs98RCTz8hIrtNzqrx7yZnSJ7WgnefvDDi6MJWU76KljbfxtUemWaxMDnuwNE BHFZbmIwnn0TQkzrfc1zgKEO8rE5uh71PJ2BclNGZcqc+Dj+FalL2+CzsBEHY9Pimq jHyV39mJrCKv4cCHtjzrjBz+v2/G19GtSKhSXUz/cXb12gA/HUxIpWzocf4SeaKlij cELwiosmmUCnjudexOUh74tkIB/U+7U2CCs7UB3/NzGTR8P1+x8A7irvOQYXCl7q+l U32g3i2jO50j4/MSjjubHP9Ylh4Rx/Xnmb1lOzLClZQdQemf7T8+/2hXcnDRsSm2PQ Mp6fCA9hdzeBmuqBCS4h0GorFh5bVS8f40GKKZP4cEXwPVLQV5AtoiV02a5ta2yamH etZTeFs0vVBhsvRTxVuDX8bpGtvZzQwMSrj4EwA6ZyjNITBL42UusRFy53NG+qB8YY qNrJqvC/Vap0kFu4pYsp8Z1Y= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 38751353FD4; Sat, 1 Mar 2025 23:46:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740872775; bh=djD1M0kwvCF4Uc5xIAlJhThCN3RrpiJjGEQAeu446Uc=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=qK2MoPmdLu9dLBG2liTH+Z0PaTfA+NOZeui5InlFVkQxBVWlAc3PnZITU0/ef6WT7 Sfm0JdNpW8KJE6kzAh51cy1S/2GpCbm0t+X6aa1BUrVRjitfg3kIn5c0Pzs2E6izzc m2kPfsJrcUbPw6foLTtNzNsJ8P1YiUbdX61tgo54WMCWZrqXJEyo373pmh9GTIbPhl jRhfiWs98RCTz8hIrtNzqrx7yZnSJ7WgnefvDDi6MJWU76KljbfxtUemWaxMDnuwNE BHFZbmIwnn0TQkzrfc1zgKEO8rE5uh71PJ2BclNGZcqc+Dj+FalL2+CzsBEHY9Pimq jHyV39mJrCKv4cCHtjzrjBz+v2/G19GtSKhSXUz/cXb12gA/HUxIpWzocf4SeaKlij cELwiosmmUCnjudexOUh74tkIB/U+7U2CCs7UB3/NzGTR8P1+x8A7irvOQYXCl7q+l U32g3i2jO50j4/MSjjubHP9Ylh4Rx/Xnmb1lOzLClZQdQemf7T8+/2hXcnDRsSm2PQ Mp6fCA9hdzeBmuqBCS4h0GorFh5bVS8f40GKKZP4cEXwPVLQV5AtoiV02a5ta2yamH etZTeFs0vVBhsvRTxVuDX8bpGtvZzQwMSrj4EwA6ZyjNITBL42UusRFy53NG+qB8YY qNrJqvC/Vap0kFu4pYsp8Z1Y= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87ecziizrn.fsf@gmail.com> (Maxim Cournoyer's message of "Fri, 28 Feb 2025 11:11:56 +0900") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> <87ecziizrn.fsf@gmail.com> Date: Sun, 02 Mar 2025 00:46:14 +0100 Message-ID: <87h64cnwl5.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > Hi Tomas, > > I was about to merge this, but I have one last (I promise!) question, see > below. No problem, I appreciate the review, it lead to higher code quality of this series. > > Tomas Volf <~@wolfsden.cz> writes: > > [...] > >> +(define apcupsd-service-type >> + (service-type >> + (name 'apcupsd) >> + (description "Configure and optionally start the apcupsd.") >> + (extensions (list (service-extension activation-service-type >> + apcupsd-activation) >> + (service-extension shepherd-root-service-type >> + apcupsd-shepherd-services) >> + (service-extension pam-root-service-type >> + apcupsd-pam-extensions))) >> + (compose identity) >> + (extend (lambda (cfg lst) >> + (fold (cut <> <>) cfg lst))) > > What does the above extend does? I find the (cut <> <>) particularly > cryptic, as it's typically used to specialize procedures, which there > are none above. I consider the behavior of the default #f value for extend field to be unfortunate, so I prefer to specify extend for all my services. Yet in this case there is no obvious thing to extend, so I opted for the extension to be a procedure, taking in the configuration and returning, possibly modified, configuration. The (cut <> <>) is just a handy, more concise way to write (lambda (proc arg) (proc arg)). What are your thoughts here? Should I just drop both compose and extend from here? Or is it fine like this? Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmfDnEYOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/walz8w//e+ledml4Eug7ORzwjOdPY1RR949ZnenMowGU psEEpxX7ikWjzPjJimnfdOoOYzfowwWEVg8ENn673ycWS3E5TKFzuPACD3ilmwew aJgiCQztpHPRl7VqPtcR7lM0Tet6Qptcb71wJJQKpUusfYMY7ukPg4rEmoI3Au5s 9pMjyq6IdoZ7/yOYdjzipy2IiP2ra0fZsQ4ap6BTzIBnvx501GjHMJG1FcU6AKHB X1ius2qp4cG6+sjLCtB2/9WcrJqCJfGrpMLPKAB2Ldv6ZFzU9aVwFH1lLGd6Fo+L iI0D//lLgokug59y2BKJ7/DjQ3eMsDYY/GGE5jUJPY0ZjreUbPj+zuf5u1Mhiko8 c7Lbl+fX+VUN1zE+9iKnsH8459f+vktSmn1NS321Sh2uusTRCLDtvS30g0Pxz6WJ 64gITXDO1V/g1Ptu62VwjZRXM+KBvhsWWdgzXTF9Dn7baZE34KQlN/FF4YQYG757 KO9RYgRRB/TrUzhhYVW2xTO9gap/8az1M24HpHEK2IWrJnIPf8akHpzSOpmODSOO sygVN8Nu/b+QEpNo4kfcG6CpnTV7LRgEfV6jR1wxgsNN2ukqkAWq+jU2Hf3Qp16W a1N5pUgLANnNBJ721JAmW94QsIiVII7HP+Nqsub0o3X6gCNzJGmuIUwiZW9cZ85K JM7RHTQ= =Uatq -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 02 Mar 2025 05:28:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Tomas Volf <~@wolfsden.cz> Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174089324117961 (code B ref 75528); Sun, 02 Mar 2025 05:28:01 +0000 Received: (at 75528) by debbugs.gnu.org; 2 Mar 2025 05:27:21 +0000 Received: from localhost ([127.0.0.1]:50661 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tobrE-0004fP-6G for submit@debbugs.gnu.org; Sun, 02 Mar 2025 00:27:21 -0500 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]:51684) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tobrB-0004ek-7K for 75528@debbugs.gnu.org; Sun, 02 Mar 2025 00:27:18 -0500 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-2239aa5da08so5972415ad.3 for <75528@debbugs.gnu.org>; Sat, 01 Mar 2025 21:27:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740893231; x=1741498031; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=RaojjTV0W/7zXco+cOPjDLxGxx/4YDi7EsNFWYCuZEk=; b=Dd5kENYNxsiCXiRAT7UuvEDMbPtATvHtNy2Y5ous0ljfRvDC1nqJy8BkIADBA9QFiH 20wkGq8GlQcuVRJPq2pPK0JTb9kcISToinx97tacaRWR05SPPeFYDd9Ga6OHOwpjY8nW szj4kWDqfIl45bQvYcov4H8i42Gr+HbEpaXJ3jg+G9ek4xVa/BfoWS7Y28ZXRvds6TCr dhM65DrooYeIdTijE5eFvH0gFRsd1iDGzOSuGqUTbY+tze0lURByXXzJn0cFd67E8xhY nRk9ReZJEMQa8wXh6k52wujtv0yluona9D9QlUWp2ObE9xDPZi9MapB05b6WNnFSAHaE cpSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740893231; x=1741498031; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=RaojjTV0W/7zXco+cOPjDLxGxx/4YDi7EsNFWYCuZEk=; b=hksqpz8PjNBANf5K0+MmWyPznF0TRFo5oSCBHCHh8vRSWorFuRTpp1sC7Un5Q3Xh2A 4Ggcfwk/JRRGdVkMNXeSjUWxs0m+4FNLGbRLgRoBmCiyf1Fz/QVG0X8PVaqUQRRmVVEb bYu+XHg+Of5qUKe4HEc0t5IPep3F+TT0kv/S2E4nBxSVO6os1wz2VJ4jNqVGusBayYNH 8jQ21DzqRU2HXrEDvl75HXCPTsSwgIiWVyCI5koQezjRoTbwrZrzl0PDZcT6a1Jkpicy fsqzCwVSmtWt5fHRbW2aD/jj+d0/1Gi2I0B0Sj1cO4PkFPIjFjAoakHUl6dFYO2vgSfP fBMA== X-Gm-Message-State: AOJu0YwXruwfe85E1MEmdDLlKKR8JREW+ERmgWNVuE+vC5zXI+n6zdJr rYMHMlcZGR1GhUSBjbKC2FAOSdm+R1u1t5l1X16BbCVgfqjjFYXA X-Gm-Gg: ASbGnctJFA4jt2Fh5D7U3wdxtksVpT8AYGBODA6EwgL3NLf/SH4W/FcUV4jZXVY6hNU zcNCNNSCFOHXI4QK8aNYrKWkMB/2YTc1YWWakeWoGW4kVoLsPpQj/g6gogpfavvpW+ra+lwt4wt SxvYTA+Ln798kkbfNDYrtsS5YlalmbCVvpQowgrzxxsMeBlm/xNlfaeDARith+++lTiEGx9rKQT 7TzdNzfNyLKqLQxKXp/rbS+B3/8ih3pubggT91yS1WeLcvY5kfifZ7TljIkjPXLHf2j7F06mc2E aUqIxQ9cyR+A/U+ZTBAd0eUI/kB9uQymdKopCZV+uM8= X-Google-Smtp-Source: AGHT+IE17jd+fIGEl1oSXTCL92GhiPWc5N0h+VM+Hgn9NNzq0ZKNjDHRitQmHdsuXwEhBCCKbDMwyg== X-Received: by 2002:a05:6a00:ad0:b0:732:2484:e0ce with SMTP id d2e1a72fcca58-734ac42a51bmr12777290b3a.17.1740893230873; Sat, 01 Mar 2025 21:27:10 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-734a003dcafsm6544715b3a.132.2025.03.01.21.27.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Mar 2025 21:27:10 -0800 (PST) From: Maxim Cournoyer In-Reply-To: <87h64cnwl5.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 02 Mar 2025 00:46:14 +0100") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> <87ecziizrn.fsf@gmail.com> <87h64cnwl5.fsf@wolfsden.cz> Date: Sun, 02 Mar 2025 14:26:58 +0900 Message-ID: <875xksgfz1.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: > Maxim Cournoyer writes: > >> Hi Tomas, >> >> I was about to merge this, but I have one last (I promise!) question, see >> below. > > No problem, I appreciate the review, it lead to higher code quality of > this series. :-) >> >> Tomas Volf <~@wolfsden.cz> writes: >> >> [...] >> >>> +(define apcupsd-service-type >>> + (service-type >>> + (name 'apcupsd) >>> + (description "Configure and optionally start the apcupsd.") >>> + (extensions (list (service-extension activation-service-type >>> + apcupsd-activation) >>> + (service-extension shepherd-root-service-type >>> + apcupsd-shepherd-services) >>> + (service-extension pam-root-service-type >>> + apcupsd-pam-extensions))) >>> + (compose identity) >>> + (extend (lambda (cfg lst) >>> + (fold (cut <> <>) cfg lst))) >> >> What does the above extend does? I find the (cut <> <>) particularly >> cryptic, as it's typically used to specialize procedures, which there >> are none above. > > I consider the behavior of the default #f value for extend field to be > unfortunate, so I prefer to specify extend for all my services. Yet in > this case there is no obvious thing to extend, so I opted for the > extension to be a procedure, taking in the configuration and returning, > possibly modified, configuration. I see. That's wasn't obvious to me. If there's nothing to be composed/extended, I think leaving the compose and extend fields to their default values communicate this better. > The (cut <> <>) is just a handy, more concise way to write > (lambda (proc arg) (proc arg)). I see. I think my confusion also stemmed from the fact I can never fully remember how extend/compose work until I look it up again :-). > What are your thoughts here? Should I just drop both compose and extend > from here? Or is it fine like this? I'd just drop them. If we discover a need later, we can add them back in, ideally with users (other services) as self-documenting code. -- Thanks, Maxim From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v4] services: Add power. References: In-Reply-To: Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Sun, 02 Mar 2025 13:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75528@debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz>, Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-Xcc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174092324224487 (code B ref 75528); Sun, 02 Mar 2025 13:48:02 +0000 Received: (at 75528) by debbugs.gnu.org; 2 Mar 2025 13:47:22 +0000 Received: from localhost ([127.0.0.1]:56102 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tojf5-0006MY-29 for submit@debbugs.gnu.org; Sun, 02 Mar 2025 08:47:22 -0500 Received: from wolfsden.cz ([37.205.8.62]:35688) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tojf0-0006MF-5m for 75528@debbugs.gnu.org; Sun, 02 Mar 2025 08:47:17 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 2AEA6358ED4; Sun, 2 Mar 2025 13:47:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740923232; bh=ijfnYgjvcUcHlUGCblfanKyAGXg+EhKh9Jih30C+2wM=; h=From:To:Cc:Subject:Date; b=nuN/zZUU8VxbM0gYUQyJ0fzPxr7HtFxBrQYnxAHIaEEthQjnjcIIEEbDHeRQuLR+p zn1jLB+00n1MzLLaa6chwZrhvWsL9XBZKWJW9Y+Sq9iWfBlqBcjExokbc2qkRZ4tC4 7BcH/LXtCKACeBRtyJ73UPfM40tQNw4LzutnixP4YUCRZr3ubO46UZRpw9Fu8f7tIT T0cg+B219Am8nq6bWeKBmBsUviilfXQPQmqaWodTid2JHW+uVtx8oalBF+kle2+0V/ jTcccFzqxjDkClJAXx4osMgbMna0JWYryzy5cWNNOnvRR3oDVJztGTucUyYEswo73G QxIPHBzFrkavX8fd+6ePYy6Epg+1aSjUX6ZhlHI79DMQbFKrdxeTgsOwFE0/7kG+rE KNCy3R2vJGglKIhtGBkVPT9eZPhQPlVTn4B9oXzVCm3CiA+H7qiCiNXOJZq3O9prsX f2vA0hGGizwZIEzI+GVIB1BrwpJM0qXfaKtGJCQ2nlDW8o0h2L7J6zXClDUyaBEN0x x197or6hpLfxj0tVQC+d0Gt4SyA91F4ZzzwVJ4huJ+lCIMz2JhPYpMfa+BV5BrHWsl Pgn+ValxMaHWoPmJIWiPCU4C8miGbFFSCj1qm+XnL5izh+KWwKIAhQPx4r4RPfUQiz Fk7opOoAM8/crQVAxLp6hFOM= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 2DDD33587BB; Sun, 2 Mar 2025 13:47:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740923229; bh=ijfnYgjvcUcHlUGCblfanKyAGXg+EhKh9Jih30C+2wM=; h=From:To:Cc:Subject:Date; b=Y+p9Az8u+MNAuuKCoaYIdVSH2tj1WobVjhsw8mYfuDhWDWuD+DijQ4Gb/nxexvp2R l8h+cSN1MG2mstiDRX0wf7dNDm1tltcilUlncVmrv8liy0L/X6eJUyHwPT9Kfmr9VL 2fPyFTIEQQAK5Ja8HlP89+044hsRa/abpKvi3yp9RLTxTxYLXQUt3dKgnaCk1XLrxG RCI5pWtk+vr89wHyt5aHHGVHTS7OP+/CvUK+uiTDgn105IJe9L+kmX9r1etIe0/NlN UQDZ1Sd1LfQ6t/rH8FKGNkAnzn55W5Sc8l4uMUFu/M1EcXfNZH+SQjpoxZCibhvRee PLMnlsWrthv9Vo0NUTea4PYRYP3UiMRiLjDFW3rXJhslFMELjuABkVuzqStDibTMzq FWZ8aaUnxDPA7wIvIGgqWJF1C+VyPKLe+gZOVvDec+sL6ejmfU9WGvR+GTIZXqbm9L YeLTCYf9mUdtKjSqXYg1QAG7BVaam7v0gneXarCPoKhBps1Zm+mMadnJyyVe+Ds96B /x+gahYCbrNuNuIfZiXCYBhHZQCgu5cew16TU9tPUtRL4Havf6qyOnxboWpdl248GF pWWg4d0kASzJVaHJOX7jQoFBhMLgd4+HHfR6m/Gg7JnY41a3YzbhdFnGplhsSY+Azn X0Ud953wGq8Wk2+cx7lFvJmY= From: Tomas Volf <~@wolfsden.cz> Date: Sun, 2 Mar 2025 14:44:34 +0100 Message-ID: <8430d41161be949bd8bbb869036bec8f3009e97d.1740923074.git.~@wolfsden.cz> X-Mailer: git-send-email 2.48.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) * gnu/services/power.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Power Management Services): Document service and data types. Change-Id: If205d19bea1d20a99309626e28521a2d6fe6702f --- doc/guix.texi | 382 ++++++++++++++++++++++- gnu/local.mk | 1 + gnu/services/power.scm | 669 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1049 insertions(+), 3 deletions(-) create mode 100644 gnu/services/power.scm diff --git a/doc/guix.texi b/doc/guix.texi index a036c85c31..095e067ea1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -123,7 +123,7 @@ Copyright @copyright{} 2023 Thomas Ieong@* Copyright @copyright{} 2023 Saku Laesvuori@* Copyright @copyright{} 2023 Graham James Addis@* -Copyright @copyright{} 2023, 2024 Tomas Volf@* +Copyright @copyright{} 2023-2025 Tomas Volf@* Copyright @copyright{} 2024, 2025 Herman Rimm@* Copyright @copyright{} 2024 Matthew Trzcinski@* Copyright @copyright{} 2024 Richard Sent@* @@ -422,7 +422,7 @@ Top * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -19270,7 +19270,7 @@ Services * Network File System:: NFS related services. * Samba Services:: Samba services. * Continuous Integration:: Cuirass and Laminar services. -* Power Management Services:: Extending battery life. +* Power Management Services:: Extending battery life, etc. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. * Version Control Services:: Providing remote access to Git repositories. @@ -36868,6 +36868,382 @@ Power Management Services @end table @end deftp +The @code{(gnu services power)} module provides a service definition for +@uref{http://www.apcupsd.org/, apcupsd}, a utility to interact with +@acronym{APC, APC by Schneider Electric or formerly American Power +Conversion Corporation} @acronym{UPS, Uninterruptible Power Supply} +devices. Apcupsd also works with some @acronym{OEM, Original Equipment +Manufacturer}-branded products manufactured by APC. + +@defvar apcupsd-service-type +The service type for apcupsd. For USB UPSes no configuration is +necessary, however tweaking some fields to better suit your needs might +be desirable. The defaults are taken from the upstream configuration +and they are not very conservative (for example, the default +@code{battery-level} of 5% may be considered too low by some). + +The default event handlers do send emails, read more in +@ref{apcupsd-event-handlers}. + +@lisp +(service apcupsd-service-type) +@end lisp +@end defvar + +@deftp {Data Type} apcupsd-configuration + +Available @code{apcupsd-configuration} fields are: + +@table @asis +@item @code{apcupsd} (default: @code{apcupsd}) (type: package) +The @code{apcupsd} package to use. + +@item @code{shepherd-service-name} (default: @code{apcupsd}) (type: symbol) +The name of the shepherd service. You can add the service multiple +times with different names to manage multiple UPSes. + +@item @code{auto-start?} (default: @code{#t}) (type: boolean) +Should the shepherd service auto-start? + +@item @code{pid-file} (default: @code{"/var/run/apcupsd.pid"}) (type: string) +The file name of the pid file. + +@item @code{debug-level} (default: @code{0}) (type: integer) +The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} +seems reasonable to enable all the logs. + +@item @code{run-dir} (default: @code{"/var/run/apcupsd"}) (type: string) +The directory containing runtime information. You need to change this +if you desire to run multiple instances of the daemon. + +@item @code{name} (type: maybe-string) +Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the +EEPROM. It should be 8 characters or less. + +@item @code{cable} (default: @code{usb}) (type: enum-cable) +The type of a cable connecting the UPS to your computer. Possible +generic choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: +@code{'940-0119A}, @code{'940-0127A}, @code{'940-0128A}, +@code{'940-0020B}, @code{'940-0020C}, @code{'940-0023A}, +@code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, +@code{'940-0095C}, @code{'940-0625A}, @code{'M-04-02-2000}. + +@item @code{type} (default: @code{usb}) (type: enum-type) +The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a +serial cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information +Server. This is used if the UPS powering your computer is connected to +a different computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless +you have a specific need for this old driver, you should use the +@code{'snmp} instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an +alternative to an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the +MODBUS protocol. + +@end table + +@item @code{device} (default: @code{""}) (type: string) +For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice +for most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. +The @var{hostname} is the ip address or hostname of the UPS on the +network. The @var{vendor} can be can be "APC" or "APC_NOTRAP". +"APC_NOTRAP" will disable SNMP trap catching; you usually want "APC". +The @var{port} is usually 161. The @var{community} is usually +"private". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. +The @var{ipaddr} is the IP address of the UPS management card. The +@var{username} and the @var{passphrase} are the credentials for which +the card has been configured. The @var{port} is the port number on +which to listen for messages from the UPS, normally 3052. If this +parameter is empty or missing, the default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it +empty for MODBUS over USB or set to the serial number of the UPS. + +@end table + +@item @code{poll-time} (default: @code{60}) (type: integer) +The interval (in seconds) at which apcupsd polls the UPS for status. +This setting applies both to directly-attached UPSes (apcsmart, usb, +dumb) and networked UPSes (net, snmp). Lowering this setting will +improve the apcupsd's responsiveness to certain events at the cost of +higher CPU utilization. + +@item @code{on-batery-delay} (default: @code{6}) (type: integer) +The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be +triggered immediately when a power failure is detected. However, the +@code{'onbattery} event will be trigger only after this delay. + +@item @code{battery-level} (default: @code{5}) (type: integer) +If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{remaining-minutes} (default: @code{3}) (type: integer) +If during a power failure, the remaining runtime in minutes (as +calculated internally by the UPS) is below or equal to this value, +apcupsd will initiate a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{timeout} (default: @code{0}) (type: integer) +If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value +of 0 disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation + +@item @code{annoy-interval} (default: @code{300}) (type: integer) +The time in seconds between annoying users (via the @code{'annoyme} +event) to sign off prior to system shutdown. 0 disables. + +@item @code{annoy-delay} (default: @code{60}) (type: integer) +The initial delay in seconds after a power failure before warning users +to get off the system. + +@item @code{no-logon} (default: @code{disable}) (type: enum-no-logon) +The condition which determines when users are prevented from logging in +during a power failure. + +@item @code{kill-delay} (default: @code{0}) (type: integer) +If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to +kill the power. This is for use on systems where apcupsd cannot regain +control after a shutdown. + +@item @code{net-server} (default: @code{#f}) (type: boolean) +If enabled, a network information server process will be started. + +@item @code{net-server-ip} (default: @code{"127.0.0.1"}) (type: string) +An IP address on which the NIS server will listen for incoming +connections. + +@item @code{net-server-port} (default: @code{3551}) (type: integer) +An IP port on which the NIS server will listen for incoming connections. + +@item @code{net-server-events-file} (type: maybe-string) +If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name. + +@item @code{net-server-events-file-max-size} (default: @code{10}) (type: integer) +The maximum size of the events file in kilobytes. + +@item @code{class} (default: @code{standalone}) (type: enum-class) +Normally standalone unless you share an UPS using an APC ShareUPS card. + +@item @code{mode} (default: @code{disable}) (type: enum-mode) +Normally disable unless you share an UPS using an APC ShareUPS card. + +@item @code{stat-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the status file, 0 +disables. + +@item @code{log-stats} (default: @code{#f}) (type: boolean) +Also write the stats as a logs. This generates a lot of output. + +@item @code{data-time} (default: @code{0}) (type: integer) +The time interval in seconds between writing the data records to the log +file, 0 disables. + +@item @code{facility} (type: maybe-string) +The logging facility for the syslog. + +@item @code{event-handlers} (type: apcupsd-event-handlers) +Handlers for events produced by apcupsd. + +@end table +@end deftp + +@anchor{apcupsd-event-handlers} +@deftp {Data Type} apcupsd-event-handlers + +For a description of the events please refer to @samp{man 8 apccontrol}. + +Each handler shall be a gexp. It is spliced into the control script for +the daemon. In addition to the standard Guile programming environment, +the following procedures and variables are also available: + +@table @code +@item conf +Variable containing the file name of the configuration file. + +@item powerfail-file +Variable containing the file name of the powerfail file. + +@item cmd +The event currently being handled. + +@item name +The name of the UPS as specified in the configuration file. + +@item connected? +Is @code{#t} if @command{apcupsd} is connected to the UPS via a serial +port (or a USB port). In most configurations, this will be the case. +In the case of a Slave machine where apcupsd is not directly connected +to the UPS, this value will be @code{#f}. + +@item powered? +Is @code{#t} if the computer on which @command{apcupsd} is running is +powered by the UPS and @code{#f} if not. At the moment, this value is +unimplemented and always @code{#f}. + +@item (err @var{fmt} @var{args...}) +Wrapper around @code{format} outputting to @code{(current-error-port)}. + +@item (wall @var{fmt} @var{args...}) +Wrapper around @code{format} outputting via @command{wall}. + +@item (apcupsd @var{args...}) +Call @command{apcupsd} while passing the correct configuration file and +all the arguments. + +@item (mail-to-root @var{subject} @var{body}) +Send an email to the local administrator. This procedure assumes the +@command{sendmail} is located at @command{/run/privileged/bin/sendmail} +(as would be the case with @code{opensmtpd-service-type}). + +@end table + +Available @code{apcupsd-event-handlers} fields are: + +@table @asis +@item @code{modules} (type: gexp) +Additional modules to import into the generated handler script. + +@item @code{killpower} (type: gexp) +The handler for the killpower event. + +@item @code{commfailure} (type: gexp) +The handler for the commfailure event. + +@item @code{commok} (type: gexp) +The handler for the commfailure event. + +@item @code{powerout} (type: gexp) +The handler for the powerout event. + +@item @code{onbattery} (type: gexp) +The handler for the onbattery event. + +@item @code{offbattery} (type: gexp) +The handler for the offbattery event. + +@item @code{mainsback} (type: gexp) +The handler for the mainsback event. + +@item @code{failing} (type: gexp) +The handler for the failing event. + +@item @code{timeout} (type: gexp) +The handler for the timeout event. + +@item @code{loadlimit} (type: gexp) +The handler for the loadlimit event. + +@item @code{runlimit} (type: gexp) +The handler for the runlimit event. + +@item @code{doreboot} (type: gexp) +The handler for the doreboot event. + +@item @code{doshutdown} (type: gexp) +The handler for the doshutdown event. + +@item @code{annoyme} (type: gexp) +The handler for the annoyme event. + +@item @code{emergency} (type: gexp) +The handler for the emergency event. + +@item @code{changeme} (type: gexp) +The handler for the changeme event. + +@item @code{remotedown} (type: gexp) +The handler for the remotedown event. + +@item @code{startselftest} (type: gexp) +The handler for the startselftest event. + +@item @code{endselftest} (type: gexp) +The handler for the endselftest event. + +@item @code{battdetach} (type: gexp) +The handler for the battdetach event. + +@item @code{battattach} (type: gexp) +The handler for the battattach event. + +@end table +@end deftp + @node Audio Services @subsection Audio Services diff --git a/gnu/local.mk b/gnu/local.mk index c8a29bf98b..0048e09ede 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -764,6 +764,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/nix.scm \ %D%/services/nfs.scm \ %D%/services/pam-mount.scm \ + %D%/services/power.scm \ %D%/services/science.scm \ %D%/services/security.scm \ %D%/services/security-token.scm \ diff --git a/gnu/services/power.scm b/gnu/services/power.scm new file mode 100644 index 0000000000..68a67e63e8 --- /dev/null +++ b/gnu/services/power.scm @@ -0,0 +1,669 @@ +;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz> + +;;;; Commentary: + +;;; Power-related services. + +;;;; Code: + +(define-module (gnu services power) + #:use-module (gnu) + #:use-module (gnu packages admin) + #:use-module (gnu packages linux) + #:use-module (gnu packages power) + #:use-module (gnu services configuration) + #:use-module (gnu services shepherd) + #:use-module (gnu services) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:export (apcupsd-service-type + + apcupsd-configuration + apcupsd-configuration-apcupsd + apcupsd-configuration-shepherd-service-name + apcupsd-configuration-auto-start? + apcupsd-configuration-pid-file + apcupsd-configuration-debug-level + apcupsd-configuration-run-dir + apcupsd-configuration-name + apcupsd-configuration-cable + apcupsd-configuration-type + apcupsd-configuration-device + apcupsd-configuration-poll-time + apcupsd-configuration-on-batery-delay + apcupsd-configuration-battery-level + apcupsd-configuration-remaining-minutes + apcupsd-configuration-timeout + apcupsd-configuration-annoy-interval + apcupsd-configuration-annoy-delay + apcupsd-configuration-no-logon + apcupsd-configuration-kill-delay + apcupsd-configuration-net-server + apcupsd-configuration-net-server-ip + apcupsd-configuration-net-server-port + apcupsd-configuration-net-server-events-file + apcupsd-configuration-net-server-events-file-max-size + apcupsd-configuration-class + apcupsd-configuration-mode + apcupsd-configuration-stat-time + apcupsd-configuration-log-stats + apcupsd-configuration-data-time + apcupsd-configuration-facility + apcupsd-configuration-event-handlers + + apcupsd-event-handlers + apcupsd-event-handlers-modules + apcupsd-event-handlers-annoyme + apcupsd-event-handlers-battattach + apcupsd-event-handlers-battdetach + apcupsd-event-handlers-changeme + apcupsd-event-handlers-commfailure + apcupsd-event-handlers-commok + apcupsd-event-handlers-doreboot + apcupsd-event-handlers-doshutdown + apcupsd-event-handlers-emergency + apcupsd-event-handlers-endselftest + apcupsd-event-handlers-failing + apcupsd-event-handlers-killpower + apcupsd-event-handlers-loadlimit + apcupsd-event-handlers-mainsback + apcupsd-event-handlers-offbattery + apcupsd-event-handlers-onbattery + apcupsd-event-handlers-powerout + apcupsd-event-handlers-remotedown + apcupsd-event-handlers-runlimit + apcupsd-event-handlers-startselftest + apcupsd-event-handlers-timeout)) + +(define-configuration/no-serialization apcupsd-event-handlers + (modules + (gexp #~()) + "Additional modules to import into the generated handler script.") + (killpower + (gexp + #~((wall "Apccontrol doing: apcupsd --killpower on UPS ~a" name) + (sleep 10) + (apcupsd "--killpower") + (wall "Apccontrol has done: apcupsd --killpower on UPS ~a" name))) + "The handler for the killpower event.") + (commfailure + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a lost." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Warning: communications lost with UPS ~a" name))) + "The handler for the commfailure event.") + (commok + (gexp + #~((let ((msg (format #f "~a Communications with UPS ~a restored." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Communications restored with UPS ~a" name))) + "The handler for the commfailure event.") + (powerout + (gexp + #~(#t)) + "The handler for the powerout event.") + (onbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power Failure !!!" + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power failure on UPS ~a. Running on batteries." name))) + "The handler for the onbattery event.") + (offbattery + (gexp + #~((let ((msg (format #f "~a UPS ~a Power has returned." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Power has returned on UPS ~a..." name))) + "The handler for the offbattery event.") + (mainsback + (gexp + #~((when (file-exists? powerfail-file) + (wall "Continuing with shutdown.")))) + "The handler for the mainsback event.") + (failing + (gexp + #~((wall "Battery power exhausted on UPS ~a. Doing shutdown." name))) + "The handler for the failing event.") + (timeout + (gexp + #~((wall "Battery time limit exceeded on UPS ~a. Doing shutdown." name))) + "The handler for the timeout event.") + (loadlimit + (gexp + #~((wall "Remaining battery charge below limit on UPS ~a. Doing shutdown." name))) + "The handler for the loadlimit event.") + (runlimit + (gexp + #~((wall "Remaining battery runtime below limit on UPS ~a. Doing shutdown." name))) + "The handler for the runlimit event.") + (doreboot + (gexp + #~((wall "UPS ~a initiating Reboot Sequence" name) + (system* #$(file-append shepherd "/sbin/reboot")))) + "The handler for the doreboot event.") + (doshutdown + (gexp + #~((wall "UPS ~a initiated Shutdown Sequence" name) + (system* #$(file-append shepherd "/sbin/halt")))) + "The handler for the doshutdown event.") + (annoyme + (gexp + #~((wall "Power problems with UPS ~a. Please logoff." name))) + "The handler for the annoyme event.") + (emergency + (gexp + #~((wall "Emergency Shutdown. Possible battery failure on UPS ~a." name))) + "The handler for the emergency event.") + (changeme + (gexp + #~((let ((msg (format #f "~a UPS ~a battery needs changing NOW." + (gethostname) name))) + (mail-to-root msg msg)) + (wall "Emergency! Batteries have failed on UPS ~a. Change them NOW." name))) + "The handler for the changeme event.") + (remotedown + (gexp + #~((wall "Remote Shutdown. Beginning Shutdown Sequence."))) + "The handler for the remotedown event.") + (startselftest + (gexp + #~(#t)) + "The handler for the startselftest event.") + (endselftest + (gexp + #~(#t)) + "The handler for the endselftest event.") + (battdetach + (gexp + #~(#t)) + "The handler for the battdetach event.") + (battattach + (gexp + #~(#t)) + "The handler for the battattach event.")) + +(define-syntax define-enum + (lambda (x) + (syntax-case x () + ((_ name values) + (let* ((datum/name (syntax->datum #'name)) + (datum/predicate (string->symbol + (format #f "enum-~a?" datum/name))) + (datum/serialize (string->symbol + (format #f "serialize-enum-~a" datum/name)))) + (with-syntax + ((predicate (datum->syntax x datum/predicate)) + (serialize (datum->syntax x datum/serialize))) + #'(begin + (define (predicate value) + (memq value values)) + (define serialize serialize-symbol)))))))) + +(define mangle-field-name + (match-lambda + ('name "UPSNAME") + ('cable "UPSCABLE") + ('type "UPSTYPE") + ('device "DEVICE") + ('poll-time "POLLTIME") + ('lock-dir "LOCKFILE") + ('power-fail-dir "PWRFAILDIR") + ('no-login-dir "NOLOGINDIR") + ('on-batery-delay "ONBATTERYDELAY") + ('battery-level "BATTERYLEVEL") + ('remaining-minutes "MINUTES") + ('timeout "TIMEOUT") + ('annoy-interval "ANNOY") + ('annoy-delay "ANNOYDELAY") + ('no-logon "NOLOGON") + ('kill-delay "KILLDELAY") + ('net-server "NETSERVER") + ('net-server-ip "NISIP") + ('net-server-port "NISPORT") + ('net-server-events-file "EVENTSFILE") + ('net-server-events-file-max-size "EVENTSFILEMAX") + ('class "UPSCLASS") + ('mode "UPSMODE") + ('stat-time "STATTIME") + ('stat-file "STATFILE") + ('log-stats "LOGSTATS") + ('data-time "DATATIME") + ('facility "FACILITY"))) + +(define (serialize-string field-name value) + #~(format #f "~a ~a\n" #$(mangle-field-name field-name) '#$value)) +(define serialize-symbol serialize-string) +(define serialize-integer serialize-string) +(define (serialize-boolean field-name value) + #~(format #f "~a ~a\n" + #$(mangle-field-name field-name) + #$(if value "on" "off"))) + +(define-maybe string) + +(define-enum cable '( simple smart ether usb + 940-0119A 940-0127A 940-0128A 940-0020B 940-0020C + 940-0023A 940-0024B 940-0024C 940-1524C 940-0024G + 940-0095A 940-0095B 940-0095C 940-0625A MAM-04-02-2000)) +(define-enum type '(apcsmart usb net snmp netsnmp dumb pcnet modbus test)) +(define-enum no-logon '(disable timeout percent minutes always)) +(define-enum class '(standalone shareslave sharemaster)) +(define-enum mode '(disable share)) + +(define-configuration apcupsd-configuration + (apcupsd (package apcupsd) "The @code{apcupsd} package to use.") + + (shepherd-service-name + (symbol 'apcupsd) + "The name of the shepherd service. You can add the service multiple times +with different names to manage multiple UPSes." + empty-serializer) + (auto-start? + (boolean #t) + "Should the shepherd service auto-start?" + empty-serializer) + (pid-file + (string "/run/apcupsd.pid") + "The file name of the PID file." + empty-serializer) + (debug-level + (integer 0) + "The logging verbosity. Bigger number means more logs. The source code +uses up to @code{300} as debug level value, so a value of @code{999} seems +reasonable to enable all the logs." + empty-serializer) + + (run-dir + (string "/run/apcupsd") + "The directory containing runtime information. You need to change this if +you desire to run multiple instances of the daemon." + empty-serializer) + + ;; General configuration parameters + (name + maybe-string + "Use this to give your UPS a name in log files and such. This is +particularly useful if you have multiple UPSes. This does not set the EEPROM. +It should be 8 characters or less.") + (cable + (enum-cable 'usb) + "The type of a cable connecting the UPS to your computer. Possible generic +choices are @code{'simple}, @code{'smart}, @code{'ether} and +@code{'usb}. + +Alternatively, a specific cable model number may be used: @code{'940-0119A}, +@code{'940-0127A}, @code{'940-0128A}, @code{'940-0020B}, @code{'940-0020C}, +@code{'940-0023A}, @code{'940-0024B}, @code{'940-0024C}, @code{'940-1524C}, +@code{'940-0024G}, @code{'940-0095A}, @code{'940-0095B}, @code{'940-0095C}, +@code{'940-0625A}, @code{'M-04-02-2000}.") + (type + (enum-type 'usb) + "The type of the UPS you have. + +@table @code +@item apcsmart +Newer serial character device, appropriate for SmartUPS models using a serial +cable (not an USB). + +@item usb +Most new UPSes are an USB. + +@item net +Network link to a master apcupsd through apcupsd's Network Information Server. +This is used if the UPS powering your computer is connected to a different +computer for monitoring. + +@item snmp +SNMP network link to an SNMP-enabled UPS device. + +@item netsnmp +Same as the SNMP above but requires use of the net-snmp library. Unless you +have a specific need for this old driver, you should use the @code{'snmp} +instead. + +@item dumb +An old serial character device for use with simple-signaling UPSes. + +@item pcnet +A PowerChute Network Shutdown protocol which can be used as an alternative to +an SNMP with the AP9617 family of smart slot cards. + +@item modbus +A serial device for use with newest SmartUPS models supporting the MODBUS +protocol. + +@end table") + (device + (string "") + "For USB UPSes, usually you want to set this to an empty string (the +default). For other UPS types, you must specify an appropriate port or +address. + +@table @code +@item apcsmart +Set to the appropriate @file{/dev/tty**} device. + +@item usb +A null string setting enables auto-detection, which is the best choice for +most installations. + +@item net +Set to @code{@var{hostname}:@var{port}}. + +@item snmp +Set to @code{@var{hostname}:@var{port}:@var{vendor}:@var{community}}. The +@var{hostname} is the ip address or hostname of the UPS on the network. The +@var{vendor} can be can be \"APC\" or \"APC_NOTRAP\". \"APC_NOTRAP\" will +disable SNMP trap catching; you usually want \"APC\". The @var{port} is +usually 161. The @var{community} is usually \"private\". + +@item netsnmp +Same as the @code{'snmp}. + +@item dumb +Set to the appropriate @file{/dev/tty**} device. + +@item pcnet +Set to @code{@var{ipaddr}:@var{username}:@var{passphrase}:@var{port}}. The +@var{ipaddr} is the IP address of the UPS management card. The @var{username} +and the @var{passphrase} are the credentials for which the card has been +configured. The @var{port} is the port number on which to listen for messages +from the UPS, normally 3052. If this parameter is empty or missing, the +default of 3052 will be used. + +@item modbus +Set to the appropriate @file{/dev/tty**} device. You can also leave it empty +for MODBUS over USB or set to the serial number of the UPS. + +@end table") + (poll-time + (integer 60) + "The interval (in seconds) at which apcupsd polls the UPS for status. This +setting applies both to directly-attached UPSes (apcsmart, usb, dumb) and +networked UPSes (net, snmp). Lowering this setting will improve the apcupsd's +responsiveness to certain events at the cost of higher CPU utilization.") + + ;; Configuration parameters used during power failures + (on-batery-delay + (integer 6) + "The time in seconds from when a power failure is detected until we react +to it with an onbattery event. The @code{'powerout} event will be triggered +immediately when a power failure is detected. However, the @code{'onbattery} +event will be trigger only after this delay.") + (battery-level + (integer 5) + "If during a power failure, the remaining battery percentage (as reported +by the UPS) is below or equal to this value, the apcupsd will initiate a +system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (remaining-minutes + (integer 3) + "If during a power failure, the remaining runtime in minutes (as calculated +internally by the UPS) is below or equal to this value, apcupsd will initiate +a system shutdown. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (timeout + (integer 0) + "If during a power failure, the UPS has run on batteries for this many +seconds or longer, apcupsd will initiate a system shutdown. The value of 0 +disables this timer. + +@quotation Note +@code{battery-level}, @code{remaining-minutes}, and @code{timeout} work +in a conjunction, so the first that occurs will cause the initation of a +shutdown. +@end quotation") + (annoy-interval + (integer 300) + "The time in seconds between annoying users (via the @code{'annoyme} event) +to sign off prior to system shutdown. 0 disables.") + (annoy-delay + (integer 60) + "The initial delay in seconds after a power failure before warning users to +get off the system.") + (no-logon + (enum-no-logon 'disable) + "The condition which determines when users are prevented from logging in +during a power failure.") + (kill-delay + (integer 0) + "If this is non-zero, the apcupsd will continue running after a shutdown +has been requested, and after the specified time in seconds attempt to kill +the power. This is for use on systems where apcupsd cannot regain control +after a shutdown.") + + ;; Configuration statements for Network Information Server + (net-server + (boolean #f) + "If enabled, a network information server process will be started.") + (net-server-ip + (string "127.0.0.1") + "An IP address on which the NIS server will listen for incoming +connections.") + (net-server-port + (integer 3551) + "An IP port on which the NIS server will listen for incoming connections.") + (net-server-events-file + maybe-string + "If you want the last few EVENTS to be available over the network by the +network information server, you must set this to a file name.") + (net-server-events-file-max-size + (integer 10) + "The maximum size of the events file in kilobytes.") + ;; Configuration statements used if sharing a UPS with more than one machine + (class (enum-class 'standalone) + "Normally standalone unless you share an UPS using an APC ShareUPS card.") + (mode (enum-mode 'disable) + "Normally disable unless you share an UPS using an APC ShareUPS card.") + ;; Configuration statements to control apcupsd system logging + (stat-time + (integer 0) + "The time interval in seconds between writing the status file, 0 +disables.") + (log-stats + (boolean #f) + "Also write the stats as a logs. This generates a lot of output.") + (data-time + (integer 0) + "The time interval in seconds between writing the data records to the log +file, 0 disables.") + (facility + maybe-string + "The logging facility for the syslog.") + + ;; Event handlers + (event-handlers + (apcupsd-event-handlers (apcupsd-event-handlers)) + "Handlers for events produced by apcupsd." + empty-serializer)) + +(define (%apccontrol config) + (program-file + "apccontrol" + (match-record (apcupsd-configuration-event-handlers config) + + ( killpower commfailure commok powerout onbattery offbattery mainsback + failing timeout loadlimit runlimit doreboot doshutdown annoyme + emergency changeme remotedown startselftest endselftest battdetach + battattach ) + #~(begin + (use-modules (ice-9 format) + (ice-9 match) + (ice-9 popen) + (srfi srfi-9) + #$@(apcupsd-event-handlers-modules + (apcupsd-configuration-event-handlers config))) + ;; Script dir depends on these, and the configuration depends on the + ;; script dir. To sever the cyclic dependency, pass the file names via + ;; environment variables. + (define conf (getenv "GUIX_APCUPSD_CONF")) + (define powerfail-file (getenv "GUIX_APCUPSD_POWERFAIL_FILE")) + + (define (err . args) + (apply format (current-error-port) args)) + (define (wall . args) + (system* #$(file-append util-linux "/bin/wall") (apply format #f args))) + (define (apcupsd . args) + (apply system* #$(file-append apcupsd "/sbin/apcupsd") "-f" conf args)) + (define (mail-to-root subject body) + (let ((port (open-pipe* OPEN_WRITE + "/run/privileged/bin/sendmail" + "-F" "apcupsd" + "root"))) + (format port "Subject: ~a~%~%~a~&" subject body) + (close-pipe port))) + (match (cdr (command-line)) + (((? string? cmd) name connected powered) + (let ((connected? (match connected + ("1" #t) + ("0" #f))) + (powered? (match powered + ("1" #t) + ("0" #f)))) + (match cmd + ("killpower" #$killpower) + ("commfailure" #$commfailure) + ("commok" #$commok) + ("powerout" #$powerout) + ("onbattery" #$onbattery) + ("offbattery" #$offbattery) + ("mainsback" #$mainsback) + ("failing" #$failing) + ("timeout" #$timeout) + ("loadlimit" #$loadlimit) + ("runlimit" #$runlimit) + ("doreboot" #$doreboot) + ("doshutdown" #$doshutdown) + ("annoyme" #$annoyme) + ("emergency" #$emergency) + ("changeme" #$changeme) + ("remotedown" #$remotedown) + ("startselftest" #$startselftest) + ("endselftest" #$endselftest) + ("battdetach" #$battdetach) + ("battattach" #$battattach) + (_ + (err "Unknown event: ~a~%" cmd) + (err "Iff the event was emitted by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))) + (args + (err "Unknown arguments: ~a~%" args) + (err "Iff the arguments were passed by apcupsd, this is a bug.~%") + (err "Please report to bug-guix@gnu.org.~%") + (exit #f))))))) + +(define (apcupsd-script-dir config) + (computed-file + "apcupsd-script-dir" + #~(begin + (mkdir #$output) + (chdir #$output) + (symlink #$(%apccontrol config) "apccontrol")))) + +(define (apcupsd-config-file config) + (let ((run-dir (apcupsd-configuration-run-dir config))) + (mixed-text-file + "apcupsd.conf" + "\ +## apcupsd.conf v1.1 ## +# +# for apcupsd - GNU Guix +# +# \"apcupsd\" POSIX config file (generated by apcupsd-service-type) +" + (serialize-configuration config apcupsd-configuration-fields) + ;; This one is confusing. The manual page states: + ;; + ;; > It must be changed when running more than one copy of apcupsd on the + ;; > same computer to control multiple UPSes. + ;; + ;; However would you not want the lock to be per-device, not per-process? + ;; I decided to follow the documentation, but I do not understand why it + ;; should be like this. I do not have multiple UPSes to try. + (serialize-string 'lock-dir (string-append run-dir "/lock")) + (serialize-string 'power-fail-dir run-dir) + (serialize-string 'no-login-dir run-dir) + (serialize-string 'stat-file (string-append run-dir "/apcupsd.status")) + "SCRIPTDIR " (apcupsd-script-dir config) "\n"))) + +(define (apcupsd-activation config) + (match-record config (run-dir) + #~(begin + (use-modules (guix build utils)) + (mkdir-p #$(string-append run-dir "/lock"))))) + +(define (apcupsd-shepherd-services config) + (match-record config + ( apcupsd pid-file debug-level run-dir + shepherd-service-name auto-start?) + (let ((config-file (apcupsd-config-file config))) + (list + (shepherd-service + (documentation "Run the apcupsd daemon.") + (requirement '(user-processes)) + (provision (list shepherd-service-name)) + (auto-start? auto-start?) + (start #~(make-forkexec-constructor + '(#$(file-append apcupsd "/sbin/apcupsd") + "-b" ;do not daemonize + "-f" #$config-file + "-P" #$pid-file + "-d" #$(number->string debug-level)) + #:log-file + #$(format #f "/var/log/~a.log" shepherd-service-name) + #:environment-variables + (cons* (string-append "GUIX_APCUPSD_CONF=" + #$config-file) + #$(string-append "GUIX_APCUPSD_POWERFAIL_FILE=" + run-dir "/powerfail") + (default-environment-variables)))) + (stop #~(make-kill-destructor)) + (actions (list (shepherd-configuration-action config-file)))))))) + +(define (apcupsd-pam-extensions config) + ;; The apcupsd can be configured to prevent users from logging in on certain + ;; conditions. This is implemented by creation of a "nologin" file, and + ;; using a pam nologin module to prevent the login (if the file exists). + (define pam-nologin + (pam-entry + (control "required") + (module "pam_nologin.so") + (arguments (list (string-append "file=" + (apcupsd-configuration-run-dir config) + "/nologin"))))) + + (list (pam-extension + (transformer + (lambda (pam) + (pam-service + (inherit pam) + (auth (cons pam-nologin (pam-service-auth pam))))))))) + +(define apcupsd-service-type + (service-type + (name 'apcupsd) + (description "Configure and optionally start the apcupsd.") + (extensions (list (service-extension activation-service-type + apcupsd-activation) + (service-extension shepherd-root-service-type + apcupsd-shepherd-services) + (service-extension pam-root-service-type + apcupsd-pam-extensions))) + (default-value (apcupsd-configuration)))) -- 2.48.1 From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 02 Mar 2025 13:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org, Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174092326524592 (code B ref 75528); Sun, 02 Mar 2025 13:48:02 +0000 Received: (at 75528) by debbugs.gnu.org; 2 Mar 2025 13:47:45 +0000 Received: from localhost ([127.0.0.1]:56109 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tojfU-0006OW-Kf for submit@debbugs.gnu.org; Sun, 02 Mar 2025 08:47:44 -0500 Received: from wolfsden.cz ([37.205.8.62]:33540) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tojfS-0006OD-5O for 75528@debbugs.gnu.org; Sun, 02 Mar 2025 08:47:42 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id 410FE358153; Sun, 2 Mar 2025 13:47:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740923261; bh=s+GbiQoU1tiZbnwSo9Koj/6XF1RdSw0jLmqboavdE+4=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=w+WzD/+N+lcshzIXYd3U2/+8DVWnn0mCOs9pWltRZomkjZduRI1e6At6tnEdXES8/ AOt3AQzP9Z7wytSyWCdT4q4VeUK9w3jvxNV52EVnYlJRpVba4c69ly5O63XDQFFSaH YenDyu8PJeut81JwEq6ZyRy+JeLmP8CL3Yzm5u1NKFReJaCNZCOF85pGCxR/Lg3Fj+ ET/Ni/BnYEr82FVAFQvh+6Dy+JVSA4h8R4eMyDSU5QINLqXa9uMkre01oyBmsZJwdB eD+DNkKt+tH2e+dagYcTuJ4hr+WEfjZJQJUcFhGPeaLOk+OQzC5rYBHowJeOguLy6S p3aJIJRvBLuM4bmpHaE6JC0dLlL/oBvAI9U8zD7MTO+6XqYDUS5tSzMPH4jL1KGGGs jiXNdl4eTxXM3XATp1aJ1z0mNJ7S15KhY3QL3nyzN0C/vCgJpN1x1RvU03U1H2IabI WClCoWB7ha7KPX/oZD469ND2Fhp1t2cP3/MCm9bkMLwcHCPfxzjgChOtFrBhu+tzd2 DO+kvx5ZVPCW2YNQ692M38Q7s5Zk3TmjuZY37D3Celh2yAeOD1I9Jp8Ne37MHxG/Q3 rCEHk82i7yAk8vCBT/rBMuVpTSop5SMyO6RJWgGYgGMkQgYyKS7idCZ85azPYf0+gD w0ovjAZHoBJkBTttXmbQhtXM= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id F159B358151; Sun, 2 Mar 2025 13:47:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740923261; bh=s+GbiQoU1tiZbnwSo9Koj/6XF1RdSw0jLmqboavdE+4=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=w+WzD/+N+lcshzIXYd3U2/+8DVWnn0mCOs9pWltRZomkjZduRI1e6At6tnEdXES8/ AOt3AQzP9Z7wytSyWCdT4q4VeUK9w3jvxNV52EVnYlJRpVba4c69ly5O63XDQFFSaH YenDyu8PJeut81JwEq6ZyRy+JeLmP8CL3Yzm5u1NKFReJaCNZCOF85pGCxR/Lg3Fj+ ET/Ni/BnYEr82FVAFQvh+6Dy+JVSA4h8R4eMyDSU5QINLqXa9uMkre01oyBmsZJwdB eD+DNkKt+tH2e+dagYcTuJ4hr+WEfjZJQJUcFhGPeaLOk+OQzC5rYBHowJeOguLy6S p3aJIJRvBLuM4bmpHaE6JC0dLlL/oBvAI9U8zD7MTO+6XqYDUS5tSzMPH4jL1KGGGs jiXNdl4eTxXM3XATp1aJ1z0mNJ7S15KhY3QL3nyzN0C/vCgJpN1x1RvU03U1H2IabI WClCoWB7ha7KPX/oZD469ND2Fhp1t2cP3/MCm9bkMLwcHCPfxzjgChOtFrBhu+tzd2 DO+kvx5ZVPCW2YNQ692M38Q7s5Zk3TmjuZY37D3Celh2yAeOD1I9Jp8Ne37MHxG/Q3 rCEHk82i7yAk8vCBT/rBMuVpTSop5SMyO6RJWgGYgGMkQgYyKS7idCZ85azPYf0+gD w0ovjAZHoBJkBTttXmbQhtXM= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <875xksgfz1.fsf@gmail.com> (Maxim Cournoyer's message of "Sun, 02 Mar 2025 14:26:58 +0900") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> <87ecziizrn.fsf@gmail.com> <87h64cnwl5.fsf@wolfsden.cz> <875xksgfz1.fsf@gmail.com> Date: Sun, 02 Mar 2025 14:47:40 +0100 Message-ID: <87cyezo877.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > [..] > >> What are your thoughts here? Should I just drop both compose and extend >> from here? Or is it fine like this? > > I'd just drop them. If we discover a need later, we can add them back > in, ideally with users (other services) as self-documenting code. Makes sense, I have sent v4. Have a nice day, Tomas =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmfEYXwOHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/walEOg//ThhL2tNdAOoQnnHNoT6VM4/sbVOvOg3+o//B 1nd8JyYXxp1r8bGKb+jOqHyKY6MnOpWKbtazGqLnNM6+UwxI3BrrjB59z1GcxbJ7 RvkOS81CQjOrFlNBwUSReVDA/QJA1jyvwQsnF2pY6Mc2CNo9zC+g08IWPY1Qz5i/ x1l/Vyemq11rpbV7ceE+Du4Hk2xH70UP09Hn7ws/MQJ2SCbTWn6dxRw6qvnTJ+fh IWNzdeJCPfZvZ+sEfO1VO4Mr8jKVPlzKhQf5M0K2XcitDwyi7ObDS8UBfOcCDHRl 6PP4nZ+Ck0E6nfX4izoXOgqdK/lyTAbWl+VDLBcsiUQQoO+xDh0rHDk9jw/lRx3C L/K/qkoKWb5lIT0V50XRhIEU5TaSkYUZgijvCGygLwe+PAHV+wJENMz0R59Ufatx L/hPW8RBzrBaTBbGsZE2bHNvLpPDb04cTb+u7FRL2VoF0XQxyhJF2Do02QFa6ad6 bQdCLm9Pjsb5xHyNcNvJzuklSXAgWwzjkx3v8GQV3LzcsVJIryRFHqp67KSlW4ME LrCHS/G8dwpuapiW9k+5NmsHINu1D0SlqZvU/swo8lIYupYSmW1Eipjqp8m6pda7 g9TqnPt8jg2LRPNFj8t8NIeeuxZl5YxDLj+wX4L8rUCX8nQlX39fi2tkXm0jx1pS vQv01m4= =3ovo -----END PGP SIGNATURE----- --=-=-=-- From unknown Sun Jun 22 00:21:05 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Tomas Volf <~@wolfsden.cz> Subject: bug#75528: closed (Re: [bug#75528] [PATCH v3] services: Add power.) Message-ID: References: <87mse3fnaf.fsf@gmail.com> X-Gnu-PR-Message: they-closed 75528 X-Gnu-PR-Package: guix-patches X-Gnu-PR-Keywords: patch Reply-To: 75528@debbugs.gnu.org Date: Sun, 02 Mar 2025 15:47:03 +0000 Content-Type: multipart/mixed; boundary="----------=_1740930423-8349-1" This is a multi-part message in MIME format... ------------=_1740930423-8349-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #75528: [PATCH 0/2] Add apcupsd which was filed against the guix-patches package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 75528@debbugs.gnu.org. --=20 75528: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D75528 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1740930423-8349-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 75528-done) by debbugs.gnu.org; 2 Mar 2025 15:46:54 +0000 Received: from localhost ([127.0.0.1]:33172 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tolWo-00029W-0t for submit@debbugs.gnu.org; Sun, 02 Mar 2025 10:46:54 -0500 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:59749) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tolWk-00028o-J7 for 75528-done@debbugs.gnu.org; Sun, 02 Mar 2025 10:46:51 -0500 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2fee05829edso1839203a91.3 for <75528-done@debbugs.gnu.org>; Sun, 02 Mar 2025 07:46:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740930404; x=1741535204; darn=debbugs.gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=Llz3yaijxh+reyq+l7cMLoVfr87HsWTZcbj2PmoeDe4=; b=VzKgRTDsPPJlC3arbLegBzHqnQb7k0vq+sZeudU9+poHtMfAOXC8l6ImODeE5juPTD o9IO9FCxxiVHQ6HMj9drVE6fU0/5PAPPI22ZpId0n2eMdkCMNbripBFXrxhlLrkokymc Z2cYyjLnmtmA4NZyFbdYNLKzxHq3mNWjhHoSKOzJXRHo0HW7mssSQ4PhqW+CtJeRnB3G E1/4xYvD+LIi6URwWPJcqj7lW+4PYUHNTElTLHy1nFZF2GfCMUvFZwwJ6XpOlJ+aXVk2 oaTF44XSWI6vxRq9cKpSNdG0E/t7oYS0YWx54pock5xFqpd70c+rMaHD5J/JlWWW49aQ IH+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740930404; x=1741535204; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Llz3yaijxh+reyq+l7cMLoVfr87HsWTZcbj2PmoeDe4=; b=iLrOiiH/zKwMdTi048XJvlemESrWd5CBeAe+6gP9RIzGyeHV98BsI45TY8Hm4EI3+X fkUY/sgmtpr/eFvk8Lr9BJBMGfGFpnfVi1BEtRycpB/fegZRS5j7bg4rYlwkwLSNlehY Unz7iBD5kmPBx9oiIyXN7FnN758rfFPQlCYxh2ceLYGQasLyBJFy5kbkaEB17j6uQrgs QK2utgb08JroKyznBRN8aEFsw9W5xgyUDxwSp4IA69LrzT+Ea91vGPP+r2ZfAcfQueTF 4ctOjPk6waQOf12dPBpr1AWieBbkZV//8nkJv0nNvDI5hCvUA+WJU5hYRWm5VcfkmNh7 yGNQ== X-Gm-Message-State: AOJu0Yxsx5ZXnOyiFnTGlVCGcvoXwO4N7KinIcHS3dkZogiaf9LRrMO3 yHZAczSXT511XV5j4DInK5O1lnLHQaIbjKEFY/+eQx30RGXssmMI X-Gm-Gg: ASbGncu7rKiqJ+kw/FTlYKuCKyOKVRrtZk6R7CYJSjezYHAzPKvRR71OapXchbyZqET 9BPXcGUxTxNLf4LExnJgjoQGGSEyVVMLryL5adhUrit5zDCaYUsozrpoGM6Do8nFG6+UtBsVJjf 1G2mmOrcVV18bz5I5AwK3cm02JSXIt4Px2fI8NXGp/0H2zb3aPPUI67golzq6HYzS6ZuM3UmRwZ lAc12ws/uASyhIhlvQfStKIkzhUvDoi2oo5mzaZ/tNIWzSnnu1IwQU+GeffcCeQOoIDzc+2OHJQ Cn8OiJWY659mCQHE6fK1LHqG1Byg99PyRpIvecikeG0= X-Google-Smtp-Source: AGHT+IEyktFmQrmJHY2xTzO+YGylCtY35qW9iuYRWJSWewXhLA+Wif4MgN2k35gV8qmutdvUCUEvYg== X-Received: by 2002:a17:90b:3509:b0:2f9:9ddd:68b9 with SMTP id 98e67ed59e1d1-2febabd9c6bmr14266284a91.26.1740930404466; Sun, 02 Mar 2025 07:46:44 -0800 (PST) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2235050fc35sm62442535ad.212.2025.03.02.07.46.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Mar 2025 07:46:43 -0800 (PST) From: Maxim Cournoyer To: Tomas Volf <~@wolfsden.cz> Subject: Re: [bug#75528] [PATCH v3] services: Add power. In-Reply-To: <87h64cnwl5.fsf@wolfsden.cz> (Tomas Volf's message of "Sun, 02 Mar 2025 00:46:14 +0100") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> <87ecziizrn.fsf@gmail.com> <87h64cnwl5.fsf@wolfsden.cz> Date: Mon, 03 Mar 2025 00:46:32 +0900 Message-ID: <87mse3fnaf.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 75528-done Cc: 75528-done@debbugs.gnu.org, Ludovic =?utf-8?Q?Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi, Tomas Volf <~@wolfsden.cz> writes: [...] > What are your thoughts here? Should I just drop both compose and extend > from here? Or is it fine like this? This was the last small change, so I've adjusted on my side and pushed as commit d0e46a0003. Thank you for your patience! -- Maxim ------------=_1740930423-8349-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 12 Jan 2025 23:03:41 +0000 Received: from localhost ([127.0.0.1]:49434 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tX6zc-0006z7-Ry for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:03:41 -0500 Received: from lists.gnu.org ([2001:470:142::17]:51028) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1tX6za-0006yr-FH for submit@debbugs.gnu.org; Sun, 12 Jan 2025 18:03:38 -0500 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 <~@wolfsden.cz>) id 1tX6zT-0002Y6-RM for guix-patches@gnu.org; Sun, 12 Jan 2025 18:03:31 -0500 Received: from wolfsden.cz ([37.205.8.62]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <~@wolfsden.cz>) id 1tX6zR-0002AL-Oa for guix-patches@gnu.org; Sun, 12 Jan 2025 18:03:31 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id A3BE0342D88; Sun, 12 Jan 2025 23:03:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723004; bh=cGFxvdC/c6T4ddXl9L2OjLona+t5z0KhM0b5+IkJrd4=; h=From:To:Cc:Subject:Date; b=T4BAGAN1qTkucn2r7VNbyzaPRZv2bf0/vKSoqmJOnIUWGlwXyHr47FSa5jiicHhou VXAvq6YPA2LFmb4czk4ocynK/wg/z/WHY32i/1GEoWznQAlRZ6BDk9KuxaLOPLA+eY rGOefqaMyl4ML8LycxB2PddRlaQ20Szkmh4L2gfrjqXyh/XsWbKo0+hNwmMTg4siji ZlEBtn1FYAwVMFEzDrQJVa1kRg29j4m78NkOP0tL3fK8fEG1+2/iWnbExqdhcL8v4Z WsZfcHy1LsPLQqbIgn6zpyjVeIgrF35PrKKXWSKaX/f0u1biH//u3P12298i8Ndyj2 Fx4Cb92aOLQLARTjWru4CbMzoJb1ULBFd9StJbGHx4djUvXF8NA8T38Jeg39VFFq/l fNdMDWKjsyLCmtuNU7W241XpbV491BtDm4BXiRvT5PQ0g3RZZlP94PRwahRcsS0qR3 6Q+/eEUIGPYmS4e2JeUtH1cBKKg90JHwVuJXpUmMoaLwGscosAhw3cPLK24PamzBYC yCyQzUpDBRyFhrVOmd0lpeRN6SY2lW7a2vkTSBlb7j3Rr5PWMZ7VgO6RYlSNhluxEv GFfz+oVmaxQE2pYpRNo5rV5Vn1ZUZoWvsRh6ChyVitGgZauaWIBRKSI3sGv2e8bEaR m3XW4Gj329NhuzVI7hMtEmPg= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id CF550342A88; Sun, 12 Jan 2025 23:03:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1736723003; bh=cGFxvdC/c6T4ddXl9L2OjLona+t5z0KhM0b5+IkJrd4=; h=From:To:Cc:Subject:Date; b=Bd5U8sbKPSGVRMegt6FIy9+/ty7Wdx060FX6ynMb7wzd7HTIST+UtdtfrwkcTpG/+ swpoNmKj9XAvU+iOiTBK8wPwggvSZsQAy1Y1vUpOcG2zIUtFH/RsgWCITRCpxI1bF8 wnNhcfiwpGjLbJtozdAWTmZsY9zcrEQP5+LKnfJsHALd3G1rsT/wmG0Fd1BMHSCPU8 h4Lp/Amb1pqXdKk1vw8StBI/410eCqMDz4t8cFkIzR1NX9aRFmE2bCvwDM6UP8zPOk 8byTK9yxQY8ehIkX92kM87tVGsSsna15n4EfUdlgmKEdAeakE/JJT986foTSNUFCG1 m4ZqJjufsg7hlYjmpE94XNAGcz+Fw42mtmAjhHRCe8Ba0akRZhuOUoMAHimynXKnny kRyr8vjGsohGBsTHjHNf1erjdKdj3r1FExDCQW2SOMhlczxHQX9O1UDaZCUPUa3MBW C44vrM2Yxp0qY6+IegT9O4EJREqBbyHE2Lag4UGP9hm8OVQImNJ6ydWscRagfx7l6r 3IikeNE+qGK8H03nYokf5frjYv/BzJiAH7LW5c+ohKtaZ7gVgfb9fU1XptK88iVKuz JVO8+lQzVl3OgY3mLwCBPlx2t073GQGCM6xRhvRyetnqI+kfy8LTkaUlXGa0AZR/V8 Oya3/9KAcP4ejHnIyxCUbHDc= From: Tomas Volf <~@wolfsden.cz> To: guix-patches@gnu.org Subject: [PATCH 0/2] Add apcupsd Date: Mon, 13 Jan 2025 00:03:16 +0100 Message-ID: X-Mailer: git-send-email 2.47.1 MIME-Version: 1.0 X-Debbugs-Cc: Ludovic Courtès , Maxim Cournoyer Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=37.205.8.62; envelope-from=~@wolfsden.cz; helo=wolfsden.cz X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-Debbugs-Envelope-To: submit Cc: Tomas Volf <~@wolfsden.cz> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) For machines running with an uninterruptible power supply (UPS), it is necessary to be able to react to events from it. That allows to, for example, safely shutdown the system when battery is getting low or get a notification that battery needs to be replaced. This series adds package and service type for apcupsd, daemon to manage UPS devices made by American Power Conversion Corporation (APC). Tomas Volf (2): gnu: Add apcupsd. services: Add power. doc/guix.texi | 374 +++++++++++++++++++++- gnu/local.mk | 2 + gnu/packages/power.scm | 125 ++++++++ gnu/services/power.scm | 690 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1188 insertions(+), 3 deletions(-) create mode 100644 gnu/packages/power.scm create mode 100644 gnu/services/power.scm -- 2.47.1 ------------=_1740930423-8349-1-- From unknown Sun Jun 22 00:21:05 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#75528] [PATCH v3] services: Add power. Resent-From: Tomas Volf <~@wolfsden.cz> Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 02 Mar 2025 16:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75528 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Maxim Cournoyer Cc: 75528@debbugs.gnu.org Received: via spool by 75528-submit@debbugs.gnu.org id=B75528.174093446925340 (code B ref 75528); Sun, 02 Mar 2025 16:55:01 +0000 Received: (at 75528) by debbugs.gnu.org; 2 Mar 2025 16:54:29 +0000 Received: from localhost ([127.0.0.1]:33961 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tomaC-0006ac-WB for submit@debbugs.gnu.org; Sun, 02 Mar 2025 11:54:29 -0500 Received: from wolfsden.cz ([37.205.8.62]:48716) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <~@wolfsden.cz>) id 1toma9-0006Zv-16 for 75528@debbugs.gnu.org; Sun, 02 Mar 2025 11:54:26 -0500 Received: by wolfsden.cz (Postfix, from userid 104) id A779435A59A; Sun, 2 Mar 2025 16:54:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740934463; bh=/r1K23LmCwg7TabXMTn3pw/FyHH15vfYixxHQfp2v20=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=k+0Z5CA7j++2xz0PqmyXyh6Jct1c8KKe0b6Rbs603wTpctE6TYtzzomt2REf1Xu2v wd6K1o/jSrDw2F3It33fauWFz0hZFxoxckKA2vBm4iHCJrRNTQ1Mu3kNecS8RgjtA3 N+CTJ9OEQiHELPBwZz4UXoAaSoNiyL9dBz20/VOF9syo4rPap0+dBlB0zzG+OVR2+i sRCLMbqd883sX4GF2xknX58l3dU6GF8pfGk+qXr1gIpkB5s2Yn+3/+kOfUrqDNog7i YW0AxMc7yGTen6SLkVFxG4oC1jRjhCxYZ1K1WYsDgtqE2GKVVDCasi8bB5ogqrSeUk JXk+zyqxtVPB9nxVwHK0PZKmqDNYBQ9rD504FeT6x0vRtxtN0kIX77ZA7uvl/PalRZ PtIVZm6r5ru1Fd6DgCjLp13nTwqq2PN/DbhubOBkXGnFvu57KgC3Hud5s14XS5nVnl wdwfuz8aAbAx+WZ2FYHt1JFlRhd7MMKDT7PcEZNqbMe9CTK+00uLHz3/3G4L4j6T7C UIjNCZdqE72bJj4HrGXwo1X7O6xatv+IyclaXSOdHPP/aUPGLOdr82menFuV0uo3CZ 2neKYRSczEH4jRN0Fbygui0Twsv/2ZZ6i+/2Xz8vt6ttNDALErbdFHvBBIJcVj7UPe PG93YeBfC2huvTOcpj6zbp/g= X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on wolfsden X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from localhost (unknown [128.0.188.242]) by wolfsden.cz (Postfix) with ESMTPSA id 78E4C358AFD; Sun, 2 Mar 2025 16:54:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wolfsden.cz; s=mail; t=1740934462; bh=/r1K23LmCwg7TabXMTn3pw/FyHH15vfYixxHQfp2v20=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=cPCG+VGoc7QOTfiMVHEuoYCZJ1axW39xSX9ry7ek2YKo5Iorj7i07OhLpTejXrFVA H+KmmNr4BNU11CGzHyPBG5VoZfmsOQ7eqTeyVrmuTKJrzoYgTYvi8Tdg9YT7++wZeT DdtQcjAmxeweAgQlxtMkotLI8B5riEJiOkf3VclWNKSX8MNlCMoXLaclV+IEv3fso3 qqnqMiaitoAuLTxVyTpswDs3xsR8icD9LflUsTTc23tS4gt/JB231k1Ejl/SiLL/pc 9+my6irRbEsJ9CtLCACYVHUj3Zte5ELSZukp9JazzR0K+N0r/w0gpJDUmQqYtbjBlT E8nuIA+eiitgchVdUD7MzJmEZeuYDiNGCauxmkMeHn2pUybv44xaV6WUHnrfM7gL/t u1uhzQhbhdZgp9NvDWt7cWEgZoUE7tDyixKq1O243TbO+IU9+I4EQGVb+WK//hRD+P YikuJ/dLgphcM94PYOBqXs3ZmwRuSDW8CeYKCOrrcPlUc2truNBzUbdGHco0vGI6sq IWbXeXVyCpyWZAUqGsBZs1Tv13o+9OvsnA3tWgr6Uo3QA0EBC5nATvP/dVCigi1DJt 4AdxjXvwPpG9qdXwBcD1Du3pY34ymCxz0nHkFT6Y3bdK+ztfS52dCuau8b6JpQukfV UK16SQVbf4pPQEu8e1B3U4V4= From: Tomas Volf <~@wolfsden.cz> In-Reply-To: <87mse3fnaf.fsf@gmail.com> (Maxim Cournoyer's message of "Mon, 03 Mar 2025 00:46:32 +0900") References: <376f456f8d49b825ddb1969734cc2aab4c99d780.1740345021.git.~@wolfsden.cz> <87ecziizrn.fsf@gmail.com> <87h64cnwl5.fsf@wolfsden.cz> <87mse3fnaf.fsf@gmail.com> Date: Sun, 02 Mar 2025 17:54:22 +0100 Message-ID: <87h64bmkzl.fsf@wolfsden.cz> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Maxim Cournoyer writes: > Hi, > > Tomas Volf <~@wolfsden.cz> writes: > > [...] > >> What are your thoughts here? Should I just drop both compose and extend >> from here? Or is it fine like this? > > This was the last small change, so I've adjusted on my side and pushed > as commit d0e46a0003. > > Thank you for your patience! And thank you for working with me through this. :) =2D-=20 There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmfEjT4OHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wam7exAAp6U0kwERjWjl0C/+ahS6mI74tYTvjVtkKhy0 E8lIDbFsQYbmf+60BA3KQuHmuMcDMC64FP3ASF6sqz7ZbT8vImPWxmRkJClz552K yfKTM1CZjFCeLzJAADZdDugPZMFcRPA9/Bl8B/lvnG/FXgdfbozAr1Ta1uxlfeIL s6yJzlGrOd/hrRTM1HRoaNzuz3oebo3Qoq2c19i35znseZwy7Fegs9Uv9TtI4Zpf lTf4Ncq8Ac2p0CR7fxLRmKtkHYFCgZTxK1NkhexDY9/58dD7S8EFmdgf3rzqYsRV aqvTXTIZ1ifv2AkWsLwv6vBXocEmiSKOSPEzqDEULyRjtPcMwoNfL4Ixf4s9nYZN FBSLmZi/5lrHPrGvyG7e23YsBmgJ8XJQySBEiUNDsOUgpkDXVPOT38RGdQrLTm+R iMQYQNJTVtsGMPB3ECX6Rq+UskMI4yu0XrsZchiTfbBuIC5ok59NR+S71OYXG0lp XUmX1VXAMEjYS2mhTgz44NmFxojbE6O4ON3/H2EmA0dyFD5niUUoYjKyqh8eV+Jy Qf7D0Pg/YSMIkjFQjkgnQ85KQFaZs7NsF3qANTx/ngWX+rgJb0E2z0FuBh0qiY00 LIWLycDf2yysNg79KnYmANGx0zXdjPf3lOoKjDqmffv56QcxBnLV10g3DBzw5Yd+ rvj1t2I= =JYSo -----END PGP SIGNATURE----- --=-=-=--