├── .envrc ├── .guix-authorizations ├── .guix-channel ├── LICENSES ├── CC0-1.0.txt └── GPL-3.0-or-later.txt ├── NEWS ├── README.org ├── etc ├── committer.scm └── manifests │ ├── all-packages.scm │ ├── auto-update.scm │ └── manual-update.scm └── modules ├── guix └── import │ └── rosenthal-updaters.scm └── rosenthal ├── bootloader └── grub.scm ├── packages.scm ├── packages ├── admin.scm ├── binaries.scm ├── bootloaders.scm ├── browser-extensions.scm ├── busybox.scm ├── dns.scm ├── emacs-xyz.scm ├── golang.scm ├── networking.scm ├── password-utils.scm ├── rust-apps.scm ├── rust-crates.scm ├── ssh.scm ├── tree-sitter.scm ├── video.scm ├── web.scm ├── wm.scm └── xorg.scm ├── services ├── bittorrent.scm ├── child-error.scm ├── dns.scm ├── file-systems.scm ├── keyboard.scm ├── mail.scm ├── networking.scm └── web.scm └── utils ├── cargo.scm ├── download.scm ├── serializers.scm └── serializers ├── ini.scm └── yaml.scm /.envrc: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Hilton Chain 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | GUILE_LOAD_PATH="modules${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH" 6 | GUIX_PACKAGE_PATH="modules${GUIX_PACKAGE_PATH:+:}$GUIX_PACKAGE_PATH" 7 | export GUILE_LOAD_PATH GUIX_PACKAGE_PATH 8 | -------------------------------------------------------------------------------- /.guix-authorizations: -------------------------------------------------------------------------------- 1 | ;; -*- mode: scheme -*- 2 | ;; SPDX-FileCopyrightText: 2022, 2024 Hilton Chain 3 | ;; 4 | ;; SPDX-License-Identifier: CC0-1.0 5 | 6 | (authorizations 7 | (version 0) 8 | (;; primary: "220F 98D9 5E86 204C 0036 DA7B 6DEC 4360 408B 4185" 9 | ("F4C2 D1DF 3FDE EA63 D1D3 0776 ACC6 6D09 CA52 8292" 10 | (name "Hilton Chain")))) 11 | -------------------------------------------------------------------------------- /.guix-channel: -------------------------------------------------------------------------------- 1 | ;; -*- mode: scheme -*- 2 | ;; SPDX-FileCopyrightText: 2022, 2023, 2025 Hilton Chain 3 | ;; 4 | ;; SPDX-License-Identifier: CC0-1.0 5 | 6 | (channel 7 | (version 0) 8 | (directory "modules") 9 | (keyring-reference "keyring") 10 | (url "https://codeberg.org/hako/rosenthal.git") 11 | (news-file "NEWS")) 12 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | ;; -*- mode: scheme -*- 2 | ;; SPDX-FileCopyrightText: 2023, 2024 Hilton Chain 3 | ;; 4 | ;; SPDX-License-Identifier: GPL-3.0-or-later 5 | 6 | (channel-news 7 | (version 0) 8 | 9 | (entry ;2024-12-08 10 | (commit "162defb8388b4099f6ae8699ec8872f845a2481e") 11 | (title (en "Hyprland upstreamed") 12 | (zh "Hyprland 已合併至上游")) 13 | (body (en "All Hyprland packages have been upstreamed to Guix and deleted in 14 | Rosenthal.") 15 | (zh "所有 Hyprland 相關軟件包已合併至 Guix 上游並在 Rosenthal 中刪除。"))) 16 | 17 | (entry ;2023-07-01 18 | (commit "ed1058c688a2655521beeba3e6295db2c0c1f274") 19 | (title (en "@code{qbittorrent-enhanced} upstreamed") 20 | (zh "@code{qbittorrent-enhanced} 已合併至上游")) 21 | (body (en "Packages @code{qbittorrent-enhanced} and 22 | @code{qbittorrent-enhanced-nox} are upstreamed to Guix, they are now available 23 | in module @code{(gnu packages bittorrent)}. Previously deprecated packages 24 | @code{qbittorrent-enhanced-edition} and @code{qbittorrent-enhanced-edition-nox} 25 | are no longer available.") 26 | (zh "@code{qbittorrent-enhanced} 與 @code{qbittorrent-enhanced-nox} 27 | 已合併至 Guix 上游 @code{(gnu packages bittorrent)} 模塊。先前標記爲棄用的軟件包 28 | @code{qbittorrent-enhanced-edition} 及 @code{qbittorrent-enhanced-edition-nox} 29 | 已不再可用。"))) 30 | 31 | (entry ;2023-07-01 32 | (commit "17106e7ed3d21544dfd80e77aa785e1e5781fb1c") 33 | (title (en "@code{linux-xanmod} merged to Nonguix") 34 | (zh "@code{linux-xanmod} 已合併至 Nonguix")) 35 | (body (en "Package @code{linux-xanmod} has been merged to channel 36 | @url{https://gitlab.com/nonguix/nonguix, Nonguix}, it's not available in 37 | Rosenthal any more.") 38 | (zh "@code{linux-xanmod} 已移出 Rosenthal,合併至 39 | @url{https://gitlab.com/nonguix/nonguix, Nonguix} 頻道。"))) 40 | 41 | (entry ;2023-06-17 42 | (commit "c3ed521085962524d78f4c7007e7d77535ae085e") 43 | (title (en "Channel moved to Codeberg") 44 | (zh "頻道已移至 Codeberg")) 45 | (body (en "Rosenthal has been moved to Codeberg and the GitHub repository 46 | will remain as a mirror. Changing the URL in your @file{channels.scm} to 47 | @url{https://codeberg.org/hako/rosenthal.git} is recommended.") 48 | (zh "Rosenthal 頻道已移至 Codeberg,先前的 GitHub 倉庫將用作鏡像。建議修改 49 | @file{channels.scm} 內 URL 爲 @url{https://codeberg.org/hako/rosenthal.git}。")))) 50 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022, 2024, 2025 Hilton Chain 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | #+TITLE: Rosenthal - A certain Guix channel 5 | 6 | Rosenthal is a Guix channel (see [[https://guix.gnu.org/manual/devel/en/html_node/Channels.html][Channels]] in /GNU Guix Reference Manual/) created for experiments. It currently holds some packages and services not ready for upstreaming to [[https://guix.gnu.org/][GNU Guix]]. 7 | 8 | You can use [[https://toys.whereis.social/][toys]] to search packages and services from Rosenthal and other Guix channels. 9 | 10 | Note that all contents in this channel are subject to change and may be deleted **at any time**, please [[https://codeberg.org/hako/Rosenthal/issues][report an issue]] if you are affected. 11 | 12 | Channel definition: 13 | #+begin_src scheme 14 | (channel 15 | (name 'rosenthal) 16 | (url "https://codeberg.org/hako/rosenthal.git") 17 | (branch "trunk") 18 | (introduction 19 | (make-channel-introduction 20 | "7677db76330121a901604dfbad19077893865f35" 21 | (openpgp-fingerprint 22 | "13E7 6CD6 E649 C28C 3385 4DF5 5E5A A665 6149 17F7")))) 23 | #+end_src 24 | 25 | For configuration, see [[https://guix.gnu.org/manual/devel/en/html_node/Specifying-Additional-Channels.html][Specifying Additional Channels]], [[https://guix.gnu.org/manual/devel/en/html_node/Customizing-the-System_002dWide-Guix.html][Customizing the System-Wide Guix]] and [[https://guix.gnu.org/manual/devel/en/html_node/Guix-Home-Services.html#index-home_002dchannels_002dservice_002dtype][~home-channels-service-type~]] in /GNU Guix Reference Manual/. 26 | 27 | Wiki: https://codeberg.org/hako/Rosenthal/wiki 28 | 29 | Git repositories: 30 | - Codeberg: https://codeberg.org/hako/Rosenthal 31 | - (backup) URSpace VCS: https://git.boiledscript.com/hako/Rosenthal 32 | - (mirror) Github: https://github.com/rakino/Rosenthal 33 | -------------------------------------------------------------------------------- /etc/committer.scm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S guix repl 2 | !# 3 | 4 | ;;; GNU Guix --- Functional package management for GNU 5 | ;;; Copyright © 2020, 2021, 2022, 2023 Ricardo Wurmus 6 | ;;; Copyright © 2021 Sarah Morgensen 7 | ;;; Copyright © 2021 Xinglu Chen 8 | ;;; Copyright © 2022 Maxim Cournoyer 9 | ;;; 10 | ;;; This file is part of GNU Guix. 11 | ;;; 12 | ;;; GNU Guix is free software; you can redistribute it and/or modify it 13 | ;;; under the terms of the GNU General Public License as published by 14 | ;;; the Free Software Foundation; either version 3 of the License, or (at 15 | ;;; your option) any later version. 16 | ;;; 17 | ;;; GNU Guix is distributed in the hope that it will be useful, but 18 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;;; GNU General Public License for more details. 21 | ;;; 22 | ;;; You should have received a copy of the GNU General Public License 23 | ;;; along with GNU Guix. If not, see . 24 | 25 | ;;; Commentary: 26 | 27 | ;; This script stages and commits changes to package definitions. 28 | 29 | ;;; Code: 30 | 31 | (use-modules ((sxml xpath) #:prefix xpath:) 32 | (srfi srfi-1) 33 | (srfi srfi-2) 34 | (srfi srfi-9) 35 | (srfi srfi-11) 36 | (srfi srfi-26) 37 | (ice-9 format) 38 | (ice-9 popen) 39 | (ice-9 match) 40 | (ice-9 rdelim) 41 | (ice-9 regex) 42 | (ice-9 textual-ports) 43 | (guix gexp)) 44 | 45 | (define* (break-string str #:optional (max-line-length 70)) 46 | "Break the string STR into lines that are no longer than MAX-LINE-LENGTH. 47 | Return a single string." 48 | (define (restore-line words) 49 | (string-join (reverse words) " ")) 50 | (if (<= (string-length str) max-line-length) 51 | str 52 | (let ((words+lengths (map (lambda (word) 53 | (cons word (string-length word))) 54 | (string-tokenize str)))) 55 | (match (fold (match-lambda* 56 | (((word . length) 57 | (count current lines)) 58 | (let ((new-count (+ count length 1))) 59 | (if (< new-count max-line-length) 60 | (list new-count 61 | (cons word current) 62 | lines) 63 | (list length 64 | (list word) 65 | (cons (restore-line current) lines)))))) 66 | '(0 () ()) 67 | words+lengths) 68 | ((_ last-words lines) 69 | (string-join (reverse (cons (restore-line last-words) lines)) 70 | "\n")))))) 71 | 72 | (define* (break-string-with-newlines str #:optional (max-line-length 70)) 73 | "Break the lines of string STR into lines that are no longer than 74 | MAX-LINE-LENGTH. Return a single string." 75 | (string-join (map (cut break-string <> max-line-length) 76 | (string-split str #\newline)) 77 | "\n")) 78 | 79 | (define (read-excursion port) 80 | "Read an expression from PORT and reset the port position before returning 81 | the expression." 82 | (let ((start (ftell port)) 83 | (result (read port))) 84 | (seek port start SEEK_SET) 85 | result)) 86 | 87 | (define (lines+offsets-with-opening-parens port) 88 | "Record all line numbers (and their offsets) where an opening parenthesis is 89 | found in column 0. The resulting list is in reverse order." 90 | (let loop ((acc '()) 91 | (number 0)) 92 | (let ((line (read-line port))) 93 | (cond 94 | ((eof-object? line) acc) 95 | ((string-prefix? "(" line) 96 | (loop (cons (cons number ;line number 97 | (- (ftell port) 98 | (string-length line) 1)) ;offset 99 | acc) 100 | (1+ number))) 101 | (else (loop acc (1+ number))))))) 102 | 103 | (define (surrounding-sexp port target-line-no) 104 | "Return the top-level S-expression surrounding the change at line number 105 | TARGET-LINE-NO in PORT." 106 | (let* ((line-numbers+offsets 107 | (lines+offsets-with-opening-parens port)) 108 | (closest-offset 109 | (or (and=> (list-index (match-lambda 110 | ((line-number . offset) 111 | (< line-number target-line-no))) 112 | line-numbers+offsets) 113 | (lambda (index) 114 | (match (list-ref line-numbers+offsets index) 115 | ((line-number . offset) offset)))) 116 | (error "Could not find surrounding S-expression for line" 117 | target-line-no)))) 118 | (seek port closest-offset SEEK_SET) 119 | (read port))) 120 | 121 | ;;; Whether the hunk contains a newly added package (definition), a removed 122 | ;;; package (removal) or something else (#false). 123 | (define hunk-types '(addition removal #false)) 124 | 125 | (define-record-type 126 | (make-hunk file-name 127 | old-line-number 128 | new-line-number 129 | diff-lines 130 | type) 131 | hunk? 132 | (file-name hunk-file-name) 133 | ;; Line number before the change 134 | (old-line-number hunk-old-line-number) 135 | ;; Line number after the change 136 | (new-line-number hunk-new-line-number) 137 | ;; The full diff to be used with "git apply --cached" 138 | (diff-lines hunk-diff-lines) 139 | ;; Does this hunk add or remove a package? 140 | (type hunk-type)) ;one of 'hunk-types' 141 | 142 | (define* (hunk->patch hunk #:optional (port (current-output-port))) 143 | (let ((file-name (hunk-file-name hunk))) 144 | (format port 145 | "diff --git a/~a b/~a~%--- a/~a~%+++ b/~a~%~a" 146 | file-name file-name file-name file-name 147 | (string-join (hunk-diff-lines hunk) "")))) 148 | 149 | (define (diff-info) 150 | "Read the diff and return a list of values." 151 | (let ((port (open-pipe* OPEN_READ 152 | "git" "diff-files" 153 | "--no-prefix" 154 | ;; Only include one context line to avoid lumping in 155 | ;; new definitions with changes to existing 156 | ;; definitions. 157 | "--unified=1" 158 | "--" "modules/rosenthal"))) 159 | (define (extract-line-number line-tag) 160 | (abs (string->number 161 | (car (string-split line-tag #\,))))) 162 | (define (read-hunk) 163 | (let loop ((lines '()) 164 | (type #false)) 165 | (let ((line (read-line port 'concat))) 166 | (cond 167 | ((eof-object? line) 168 | (values (reverse lines) type)) 169 | ((or (string-prefix? "@@ " line) 170 | (string-prefix? "diff --git" line)) 171 | (unget-string port line) 172 | (values (reverse lines) type)) 173 | (else 174 | (loop (cons line lines) 175 | (or type 176 | (cond 177 | ((string-prefix? "+(define" line) 178 | 'addition) 179 | ((string-prefix? "-(define" line) 180 | 'removal) 181 | (else #false))))))))) 182 | (define info 183 | (let loop ((acc '()) 184 | (file-name #f)) 185 | (let ((line (read-line port))) 186 | (cond 187 | ((eof-object? line) acc) 188 | ((string-prefix? "--- " line) 189 | (match (string-split line #\space) 190 | ((_ file-name) 191 | (loop acc file-name)))) 192 | ((string-prefix? "@@ " line) 193 | (match (string-split line #\space) 194 | ((_ old-start new-start . _) 195 | (let-values 196 | (((diff-lines type) (read-hunk))) 197 | (loop (cons (make-hunk file-name 198 | (extract-line-number old-start) 199 | (extract-line-number new-start) 200 | (cons (string-append line "\n") 201 | diff-lines) 202 | type) acc) 203 | file-name))))) 204 | (else (loop acc file-name)))))) 205 | (close-pipe port) 206 | info)) 207 | 208 | (define (lines-to-first-change hunk) 209 | "Return the number of diff lines until the first change." 210 | (1- (count (lambda (line) 211 | ((negate char-set-contains?) 212 | (char-set #\+ #\-) 213 | (string-ref line 0))) 214 | (hunk-diff-lines hunk)))) 215 | 216 | (define %original-file-cache 217 | (make-hash-table)) 218 | 219 | (define (read-original-file file-name) 220 | "Return the contents of FILE-NAME prior to any changes." 221 | (let* ((port (open-pipe* OPEN_READ 222 | "git" "cat-file" "-p" (string-append 223 | "HEAD:" file-name))) 224 | (contents (get-string-all port))) 225 | (close-pipe port) 226 | contents)) 227 | 228 | (define (read-original-file* file-name) 229 | "Caching variant of READ-ORIGINAL-FILE." 230 | (or (hashv-ref %original-file-cache file-name) 231 | (let ((value (read-original-file file-name))) 232 | (hashv-set! %original-file-cache file-name value) 233 | value))) 234 | 235 | (define (old-sexp hunk) 236 | "Using the diff information in HUNK return the unmodified S-expression 237 | corresponding to the top-level definition containing the staged changes." 238 | ;; TODO: We can't seek with a pipe port... 239 | (call-with-input-string (read-original-file* (hunk-file-name hunk)) 240 | (lambda (port) 241 | (surrounding-sexp port 242 | (+ (lines-to-first-change hunk) 243 | (hunk-old-line-number hunk)))))) 244 | 245 | (define (new-sexp hunk) 246 | "Using the diff information in HUNK return the modified S-expression 247 | corresponding to the top-level definition containing the staged changes." 248 | (call-with-input-file (hunk-file-name hunk) 249 | (lambda (port) 250 | (surrounding-sexp port 251 | (+ (lines-to-first-change hunk) 252 | (hunk-new-line-number hunk)))))) 253 | 254 | (define* (change-commit-message file-name old new #:optional (port (current-output-port))) 255 | "Print ChangeLog commit message for changes between OLD and NEW." 256 | (define (get-values expr field) 257 | (match ((xpath:node-or 258 | (xpath:sxpath `(*any* *any* package ,field quasiquote *)) 259 | ;; For let binding 260 | (xpath:sxpath `(*any* *any* (*any*) package ,field quasiquote *))) 261 | (cons '*TOP* expr)) 262 | (() 263 | ;; New-style plain lists 264 | (match ((xpath:node-or 265 | (xpath:sxpath `(*any* *any* package ,field list *)) 266 | ;; For let binding 267 | (xpath:sxpath `(*any* *any* (*any*) package ,field list *))) 268 | (cons '*TOP* expr)) 269 | ((inner) inner) 270 | (_ '()))) 271 | ;; Old-style labelled inputs 272 | ((first . rest) 273 | (map cadadr first)))) 274 | (define (listify items) 275 | (match items 276 | ((one) one) 277 | ((one two) 278 | (string-append one " and " two)) 279 | ((one two . more) 280 | (string-append (string-join (drop-right items 1) ", ") 281 | ", and " (first (take-right items 1)))))) 282 | (define variable-name 283 | (second old)) 284 | (define version 285 | (and=> ((xpath:node-or 286 | (xpath:sxpath '(*any* *any* package version *any*)) 287 | ;; For let binding 288 | (xpath:sxpath '(*any* *any* (*any*) package version *any*))) 289 | (cons '*TOP* new)) 290 | first)) 291 | (format port 292 | "rosenthal: ~a: Update to ~a.~%~%* ~a (~a): Update to ~a.~%" 293 | variable-name version file-name variable-name version) 294 | (for-each (lambda (field) 295 | (let ((old-values (get-values old field)) 296 | (new-values (get-values new field))) 297 | (or (equal? old-values new-values) 298 | (let ((removed (lset-difference equal? old-values new-values)) 299 | (added (lset-difference equal? new-values old-values))) 300 | (format port 301 | "[~a]: ~a~%" field 302 | (break-string 303 | ;; A dependency can be a list of (pkg output). 304 | (match (list (map object->string removed) 305 | (map object->string added)) 306 | ((() added) 307 | (format #f "Add ~a." 308 | (listify added))) 309 | ((removed ()) 310 | (format #f "Remove ~a." 311 | (listify removed))) 312 | ((removed added) 313 | (format #f "Remove ~a; add ~a." 314 | (listify removed) 315 | (listify added)))))))))) 316 | '(inputs propagated-inputs native-inputs))) 317 | 318 | (define* (add-commit-message file-name variable-name 319 | #:optional (port (current-output-port))) 320 | "Print ChangeLog commit message for a change to FILE-NAME adding a 321 | definition." 322 | (format port "rosenthal: Add ~a.~%~%* ~a (~a): New variable.~%" 323 | variable-name file-name variable-name)) 324 | 325 | (define* (remove-commit-message file-name variable-name 326 | #:optional (port (current-output-port))) 327 | "Print ChangeLog commit message for a change to FILE-NAME removing a 328 | definition." 329 | (format port "rosenthal: Remove ~a.~%~%* ~a (~a): Delete variable.~%" 330 | variable-name file-name variable-name)) 331 | 332 | (define* (custom-commit-message file-name variable-name message changelog 333 | #:optional (port (current-output-port))) 334 | "Print custom commit message for a change to VARIABLE-NAME in FILE-NAME, using 335 | MESSAGE as the commit message and CHANGELOG as the body of the ChangeLog 336 | entry. If CHANGELOG is #f, the commit message is reused. If CHANGELOG already 337 | contains ': ', no colon is inserted between the location and body of the 338 | ChangeLog entry." 339 | (define (trim msg) 340 | (string-trim-right (string-trim-both msg) (char-set #\.))) 341 | 342 | (define (changelog-has-location? changelog) 343 | (->bool (string-match "^[[:graph:]]+:[[:blank:]]" changelog))) 344 | 345 | (let* ((message (trim message)) 346 | (changelog (if changelog (trim changelog) message)) 347 | (message/f (format #f "rosenthal: ~a: ~a." variable-name message)) 348 | (changelog/f (if (changelog-has-location? changelog) 349 | (format #f "* ~a (~a)~a." 350 | file-name variable-name changelog) 351 | (format #f "* ~a (~a): ~a." 352 | file-name variable-name changelog)))) 353 | (format port 354 | "~a~%~%~a~%" 355 | (break-string-with-newlines message/f 72) 356 | (break-string-with-newlines changelog/f 72)))) 357 | 358 | (define (add-copyright-line line) 359 | "Add the copyright line on LINE to the previous commit." 360 | (let ((author (match:substring 361 | (string-match "^\\+;;; Copyright ©[^[:alpha:]]+(.*)$" line) 362 | 1))) 363 | (format 364 | (current-output-port) "Amend and add copyright line for ~a~%" author) 365 | (system* "git" "commit" "--amend" "--no-edit"))) 366 | 367 | (define (group-hunks-by-sexp hunks) 368 | "Return a list of pairs associating all hunks with the S-expression they are 369 | modifying." 370 | (fold (lambda (sexp hunk acc) 371 | (match acc 372 | (((previous-sexp . hunks) . rest) 373 | (if (equal? sexp previous-sexp) 374 | (cons (cons previous-sexp 375 | (cons hunk hunks)) 376 | rest) 377 | (cons (cons sexp (list hunk)) 378 | acc))) 379 | (_ 380 | (cons (cons sexp (list hunk)) 381 | acc)))) 382 | '() 383 | (map new-sexp hunks) 384 | hunks)) 385 | 386 | (define (new+old+hunks hunks) 387 | (map (match-lambda 388 | ((new . hunks) 389 | (cons* new (old-sexp (first hunks)) hunks))) 390 | (group-hunks-by-sexp hunks))) 391 | 392 | (define %delay 1000) 393 | 394 | (define (main . args) 395 | (define* (change-commit-message* file-name old new #:rest rest) 396 | (let ((changelog #f)) 397 | (match args 398 | ((or (message changelog) (message)) 399 | (apply custom-commit-message 400 | file-name (second old) message changelog rest)) 401 | (_ 402 | (apply change-commit-message file-name old new rest))))) 403 | 404 | (read-disable 'positions) 405 | (match (diff-info) 406 | (() 407 | (display "Nothing to be done.\n" (current-error-port))) 408 | (hunks 409 | (let-values (((definitions changes) (partition hunk-type hunks))) 410 | ;; Additions/removals. 411 | (for-each 412 | (lambda (hunk) 413 | (and-let* ((define-line (find (cut string-match "(\\+|-)\\(define" <>) 414 | (hunk-diff-lines hunk))) 415 | (variable-name (and=> (string-tokenize define-line) 416 | second)) 417 | (commit-message-proc (match (hunk-type hunk) 418 | ('addition add-commit-message) 419 | ('removal remove-commit-message)))) 420 | (commit-message-proc (hunk-file-name hunk) variable-name) 421 | (let ((port (open-pipe* OPEN_WRITE 422 | "git" "apply" 423 | "--cached" 424 | "--unidiff-zero"))) 425 | (hunk->patch hunk port) 426 | (unless (eqv? 0 (status:exit-val (close-pipe port))) 427 | (error "Cannot apply"))) 428 | 429 | (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-"))) 430 | (commit-message-proc (hunk-file-name hunk) variable-name port) 431 | (usleep %delay) 432 | (unless (eqv? 0 (status:exit-val (close-pipe port))) 433 | (error "Cannot commit")))) 434 | (usleep %delay)) 435 | definitions) 436 | 437 | ;; Changes. 438 | (for-each 439 | (match-lambda 440 | ((new old . hunks) 441 | (for-each (lambda (hunk) 442 | (let ((port (open-pipe* OPEN_WRITE 443 | "git" "apply" 444 | "--cached" 445 | "--unidiff-zero"))) 446 | (hunk->patch hunk port) 447 | (unless (eqv? 0 (status:exit-val (close-pipe port))) 448 | (error "Cannot apply"))) 449 | (usleep %delay)) 450 | hunks) 451 | (define copyright-line 452 | (any (lambda (line) (and=> (string-prefix? "+;;; Copyright ©" line) 453 | (const line))) 454 | (hunk-diff-lines (first hunks)))) 455 | (cond 456 | (copyright-line 457 | (add-copyright-line copyright-line)) 458 | (else 459 | (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-"))) 460 | (change-commit-message* (hunk-file-name (first hunks)) 461 | old new) 462 | (change-commit-message* (hunk-file-name (first hunks)) 463 | old new 464 | port) 465 | (usleep %delay) 466 | (unless (eqv? 0 (status:exit-val (close-pipe port))) 467 | (error "Cannot commit"))))))) 468 | (new+old+hunks (match definitions 469 | ('() changes) ;reuse 470 | (_ 471 | ;; XXX: we recompute the hunks here because previous 472 | ;; insertions lead to offsets. 473 | (let-values (((definitions changes) 474 | (partition hunk-type (diff-info)))) 475 | changes))))))))) 476 | 477 | (apply main (cdr (command-line))) 478 | -------------------------------------------------------------------------------- /etc/manifests/all-packages.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: CC0-1.0 4 | 5 | (use-modules (guix profiles) 6 | (rosenthal packages)) 7 | 8 | (manifest (map package->manifest-entry (all-rosenthal-packages))) 9 | -------------------------------------------------------------------------------- /etc/manifests/auto-update.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: CC0-1.0 4 | 5 | (use-modules (guix profiles) 6 | (rosenthal packages)) 7 | 8 | (manifest (map package->manifest-entry 9 | (filter (negate rosenthal-disable-updater?) 10 | (all-rosenthal-packages)))) 11 | -------------------------------------------------------------------------------- /etc/manifests/manual-update.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: CC0-1.0 4 | 5 | (use-modules (guix profiles) 6 | (rosenthal packages)) 7 | 8 | (manifest (map package->manifest-entry 9 | (filter rosenthal-disable-updater? 10 | (all-rosenthal-packages)))) 11 | -------------------------------------------------------------------------------- /modules/guix/import/rosenthal-updaters.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2024, 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (guix import rosenthal-updaters) 6 | #:use-module (srfi srfi-71) 7 | #:use-module (web client) 8 | 9 | #:use-module (guix packages) 10 | #:use-module (guix records) 11 | #:use-module (guix upstream) 12 | #:export (%cloudflare-warp-updater)) 13 | 14 | (define* (cloudflare-warp-import pkg #:key version partial-version?) 15 | (let* ((source-uri (assq-ref (package-properties pkg) 'release-monitoring-url)) 16 | (response port (http-get source-uri #:streaming? #t)) 17 | (content (recutils->alist port)) 18 | (_ (close port)) 19 | (name (package-upstream-name pkg)) 20 | (newest-version 21 | (or version 22 | (assoc-ref content "Version"))) 23 | (url 24 | (if version 25 | (string-append "https://pkg.cloudflareclient.com/" 26 | "pool/bookworm/main/c/cloudflare-warp/" 27 | "cloudflare-warp_" version "_amd64.deb") 28 | (string-append "https://pkg.cloudflareclient.com/" 29 | (assoc-ref content "Filename"))))) 30 | (upstream-source 31 | (package name) 32 | (version newest-version) 33 | (urls (list url))))) 34 | 35 | (define %cloudflare-warp-updater 36 | (upstream-updater 37 | (name 'cloudflare-warp) 38 | (description "Updater for Cloudflare WARP client") 39 | (pred (lambda (package) 40 | (string=? "cloudflare-warp" (package-upstream-name package)))) 41 | (import cloudflare-warp-import))) 42 | -------------------------------------------------------------------------------- /modules/rosenthal/bootloader/grub.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal bootloader grub) 6 | #:use-module (gnu bootloader) 7 | #:use-module (gnu bootloader grub) 8 | #:use-module (rosenthal packages bootloaders) 9 | #:export (grub-efi-luks2-bootloader 10 | grub-efi-luks2-removable-bootloader)) 11 | 12 | (define grub-efi-luks2-bootloader 13 | (bootloader 14 | (inherit grub-efi-bootloader) 15 | ;; NOTE: Don't change the name. Generation switching code only knows 16 | ;; bootloaders defined in (gnu bootloader grub). 17 | (name 'grub-efi) 18 | (package grub-efi-luks2))) 19 | 20 | (define grub-efi-luks2-removable-bootloader 21 | (bootloader 22 | (inherit grub-efi-removable-bootloader) 23 | (package grub-efi-luks2))) 24 | -------------------------------------------------------------------------------- /modules/rosenthal/packages.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 2 | ;;; Copyright © 2015, 2018 Ludovic Courtès 3 | ;;; Copyright © 2025 Maxim Cournoyer 4 | 5 | (define-module (rosenthal packages) 6 | #:use-module (gnu packages) 7 | #:use-module (guix diagnostics) 8 | #:use-module (guix discovery) 9 | #:use-module (guix i18n) 10 | #:use-module (guix memoization) 11 | #:use-module (guix packages) 12 | #:use-module (guix ui) 13 | #:use-module (ice-9 match) 14 | #:use-module (srfi srfi-34) 15 | #:replace (%patch-path 16 | search-patch) 17 | #:export (rosenthal-patches 18 | %rosenthal-package-module-path 19 | all-rosenthal-packages 20 | rosenthal-disable-updater?)) 21 | 22 | ;;; Commentary: 23 | ;;; 24 | ;;; This module refines the default value of some parameters from (gnu 25 | ;;; packages) and the syntax/procedures using those. This allows 26 | ;;; 'search-paths' and friends to work without any user intervention. 27 | ;;; 28 | ;;; Code: 29 | 30 | (define %rosenthal-root-directory 31 | ;; This is like %distro-root-directory from (gnu packages), with adjusted 32 | ;; paths. 33 | (letrec-syntax ((dirname* (syntax-rules () 34 | ((_ file) 35 | (dirname file)) 36 | ((_ file head tail ...) 37 | (dirname (dirname* file tail ...))))) 38 | (try (syntax-rules () 39 | ((_ (file things ...) rest ...) 40 | (match (search-path %load-path file) 41 | (#f 42 | (try rest ...)) 43 | (absolute 44 | (dirname* absolute things ...)))) 45 | ((_) 46 | #f)))) 47 | (try ("rosenthal/packages/binaries.scm" rosenthal/ packages/) 48 | ("rosenthal/packages.scm" rosenthal/)))) 49 | 50 | (define %rosenthal-package-module-path 51 | `((,%rosenthal-root-directory . "rosenthal/packages"))) 52 | 53 | (define %patch-path 54 | ;; Define it after '%package-module-path' so that '%load-path' contains user 55 | ;; directories, allowing patches in $GUIX_PACKAGE_PATH to be found. 56 | (make-parameter 57 | (map (lambda (directory) 58 | (if (string=? directory %rosenthal-root-directory) 59 | (string-append directory "/rosenthal/packages/patches") 60 | directory)) 61 | %load-path))) 62 | 63 | ;;; XXX: The following must be redefined to make use of the overridden 64 | ;;; %patch-path parameter above. 65 | (define (search-patch file-name) 66 | "Search the patch FILE-NAME. Raise an error if not found." 67 | (or (search-path (%patch-path) file-name) 68 | (raise (formatted-message (G_ "~a: patch not found") 69 | file-name)))) 70 | 71 | ;;; XXX: `search-patches' being syntax, it can't be overridden by the module 72 | ;;; system, or so it seems, so we simply rename it. 73 | (define-syntax-rule (rosenthal-patches file-name ...) 74 | "Return the list of absolute file names corresponding to each 75 | FILE-NAME found in %PATCH-PATH." 76 | (list (search-patch file-name) ...)) 77 | 78 | ;; Adapted from (@ (gnu packages) all-packages). 79 | (define all-rosenthal-packages 80 | (mlambda () 81 | "Return the list of all public packages, including replacements and hidden 82 | packages, excluding superseded packages." 83 | ;; Note: 'fold-packages' never traverses the same package twice but 84 | ;; replacements break that (they may or may not be visible to 85 | ;; 'fold-packages'), hence this hash table to track visited packages. 86 | (define visited (make-hash-table)) 87 | 88 | (fold-packages (lambda (package result) 89 | (if (hashq-ref visited package) 90 | result 91 | (begin 92 | (hashq-set! visited package #t) 93 | (match (package-replacement package) 94 | ((? package? replacement) 95 | (hashq-set! visited replacement #t) 96 | (cons* replacement package result)) 97 | (#f 98 | (cons package result)))))) 99 | '() 100 | (all-modules %rosenthal-package-module-path #:warn warn-about-load-error) 101 | ;; Dismiss deprecated packages but keep hidden packages. 102 | #:select? (negate package-superseded)))) 103 | 104 | (define (rosenthal-disable-updater? p) 105 | (assq-ref (package-properties p) 'disable-updater?)) 106 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/admin.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022, 2025 Hilton Chain 2 | ;; SPDX-FileCopyrightText: 2025 William Goodspeed 3 | ;; 4 | ;; SPDX-License-Identifier: GPL-3.0-or-later 5 | 6 | (define-module (rosenthal packages admin) 7 | #:use-module ((guix licenses) #:prefix license:) 8 | #:use-module (guix git-download) 9 | #:use-module (guix gexp) 10 | #:use-module (guix packages) 11 | #:use-module (guix utils) 12 | #:use-module (guix build-system gnu) 13 | #:use-module (guix build-system meson) 14 | #:use-module (gnu packages admin) 15 | #:use-module (gnu packages linux) 16 | #:use-module (gnu packages m4) 17 | #:use-module (gnu packages pkg-config)) 18 | 19 | (define-public dinit 20 | (package 21 | (name "dinit") 22 | (version "0.19.4") 23 | (source 24 | (origin 25 | (method git-fetch) 26 | (uri (git-reference 27 | (url "https://github.com/davmac314/dinit") 28 | (commit (string-append "v" version)))) 29 | (file-name (git-file-name name version)) 30 | (sha256 31 | (base32 "09k7airphnpg6hmif91d9nfi5fhz40qh52sp8vnrshfy7mhkq571")))) 32 | (build-system meson-build-system) 33 | (arguments 34 | (list #:configure-flags 35 | #~(list "-Dshutdown-prefix=dinit-" 36 | "-Dunit-tests=true" 37 | "-Digr-tests=true" 38 | (string-append "-Ddinit-sbindir=" #$output "/sbin")) 39 | #:phases 40 | #~(modify-phases %standard-phases 41 | (add-after 'unpack 'fix-paths 42 | (lambda* (#:key inputs #:allow-other-keys) 43 | (substitute* "src/shutdown.cc" 44 | (("(/sbin/swapoff|/bin/umount)" path) 45 | (search-input-file inputs path)))))))) 46 | (native-inputs (list m4)) 47 | (inputs (list util-linux)) 48 | (home-page "https://davmac.org/projects/dinit/") 49 | (synopsis "Service manager with dependency management") 50 | (description 51 | "Dinit is a service manager for Unix-like operating systems that allows 52 | the user to manage services with dependencies and parallel startup.") 53 | (license license:asl2.0))) 54 | 55 | (define-public libseat-sans-logind 56 | (let ((base libseat)) 57 | (package 58 | (inherit base) 59 | (name "libseat-sans-logind") 60 | (arguments 61 | (substitute-keyword-arguments (package-arguments base) 62 | ((#:configure-flags configure-flags) 63 | #~(append #$configure-flags 64 | (list "-Dlibseat-logind=disabled"))))) 65 | (propagated-inputs '())))) 66 | 67 | (define-public pam-dumb-runtime-dir 68 | (package 69 | (name "pam-dumb-runtime-dir") 70 | (version "1.0.4") 71 | (source (origin 72 | (method git-fetch) 73 | (uri (git-reference 74 | (url "https://github.com/ifreund/dumb_runtime_dir") 75 | (commit (string-append "v" version)))) 76 | (file-name (git-file-name name version)) 77 | (sha256 78 | (base32 79 | "0nrxhvbh3bs4pi4f5h03zw1p1ys19qmmlx263ysly8302wkxk1m4")))) 80 | (build-system gnu-build-system) 81 | (arguments 82 | (list #:tests? #f ;No tests. 83 | #:make-flags 84 | #~(list (string-append "CC=" #$(cc-for-target)) 85 | (string-append "DESTDIR=" #$output) 86 | "PREFIX=") 87 | #:phases 88 | #~(modify-phases %standard-phases 89 | ;; No configure script. 90 | (delete 'configure)))) 91 | (native-inputs (list pkg-config)) 92 | (inputs (list linux-pam)) 93 | (home-page "https://github.com/ifreund/dumb_runtime_dir") 94 | (synopsis "Create @code{XDG_RUNTIME_DIR} on login and never remove it") 95 | (description 96 | "This package creates an @code{XDG_RUNTIME_DIR} directory on login per 97 | the freedesktop.org base directory spec. Flaunts the spec and never removes 98 | it, even after last logout. This keeps things simple and predictable. 99 | 100 | The user is responsible for ensuring that the @file{/run/user} directory 101 | exists and is only writable by root.") 102 | (license license:bsd-0))) 103 | 104 | (define-public seatd-sans-logind 105 | (let ((base seatd)) 106 | (package 107 | (inherit base) 108 | (name "seatd-sans-logind") 109 | (arguments 110 | (substitute-keyword-arguments (package-arguments base) 111 | ((#:configure-flags configure-flags) 112 | #~(append #$configure-flags 113 | (list "-Dlibseat-logind=disabled"))))) 114 | (propagated-inputs '())))) 115 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/binaries.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023-2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages binaries) 6 | #:use-module (srfi srfi-1) 7 | #:use-module ((guix licenses) #:prefix license:) 8 | #:use-module (guix gexp) 9 | #:use-module (guix deprecation) 10 | #:use-module (guix packages) 11 | #:use-module (guix download) 12 | #:use-module (guix build-system copy) 13 | #:use-module (gnu build icecat-extension) 14 | #:use-module (gnu packages base) 15 | #:use-module (gnu packages bash) 16 | #:use-module (gnu packages bootstrap) 17 | #:use-module (gnu packages compression) 18 | #:use-module (gnu packages elf) 19 | #:use-module (gnu packages gcc) 20 | #:use-module (gnu packages glib) 21 | #:use-module (gnu packages java) 22 | #:use-module (gnu packages nss) 23 | #:use-module (rosenthal packages networking) 24 | #:use-module (rosenthal packages rust-apps) 25 | #:use-module (rosenthal packages web)) 26 | 27 | (define license 28 | (@@ (guix licenses) license)) 29 | 30 | (define-public atuin-bin 31 | (deprecated-package "atuin-bin" atuin)) 32 | 33 | (define-public hugo-bin 34 | (deprecated-package "hugo-bin" hugo)) 35 | 36 | (define-public mihomo-bin 37 | (deprecated-package "mihomo-bin" mihomo)) 38 | 39 | (define-public clash-meta-bin 40 | (deprecated-package "clash-meta-bin" mihomo-bin)) 41 | 42 | (define-public cloudflare-warp-bin 43 | (package 44 | (name "cloudflare-warp-bin") 45 | (version "2025.4.943.0") 46 | (source (origin 47 | (method url-fetch) 48 | (uri (string-append "https://pkg.cloudflareclient.com" 49 | "/pool/bookworm/main/c/cloudflare-warp/" 50 | "cloudflare-warp_" version "_amd64.deb")) 51 | (sha256 52 | (base32 53 | "08gczvxr2826vsz15ysadxm8llwgshxm5qqczn29w9iyirkc4k2q")))) 54 | (build-system copy-build-system) 55 | (arguments 56 | (list #:install-plan 57 | #~'(("bin" "bin" #:include ("warp-cli" "warp-svc"))) 58 | #:phases 59 | #~(modify-phases %standard-phases 60 | (add-after 'unpack 'unpack-deb 61 | (lambda* (#:key source #:allow-other-keys) 62 | (invoke "ar" "-x" source) 63 | (invoke "tar" "-xf" "data.tar.gz"))) 64 | (add-after 'install 'patch-elf 65 | (lambda _ 66 | (let ((ld.so (string-append #$(this-package-input "glibc") 67 | #$(glibc-dynamic-linker))) 68 | (rpath (string-join 69 | (list 70 | (string-append 71 | (ungexp 72 | (this-package-input "gcc") "lib") "/lib") 73 | (string-append 74 | #$(this-package-input "dbus") "/lib") 75 | (string-append 76 | #$(this-package-input "glibc") "/lib") 77 | (string-append 78 | #$(this-package-input "nspr") "/lib") 79 | (string-append 80 | #$(this-package-input "nss") "/lib/nss")) 81 | ":"))) 82 | (define (patch-elf file) 83 | (format #t "Patching ~a ..." file) 84 | (unless (string-contains file ".so") 85 | (invoke "patchelf" "--set-interpreter" ld.so file)) 86 | (invoke "patchelf" "--set-rpath" rpath file) 87 | (display " done\n")) 88 | (for-each (lambda (file) 89 | (patch-elf file)) 90 | (find-files 91 | (string-append #$output "/bin"))))))))) 92 | (supported-systems '("x86_64-linux")) 93 | (native-inputs (list patchelf-0.16)) 94 | (inputs (list dbus `(,gcc "lib") glibc nspr nss)) 95 | (home-page "https://1.1.1.1/") 96 | (synopsis "Cloudflare WARP client") 97 | (description 98 | "The Cloudflare WARP client allows individuals to have a faster, more 99 | secure, and more private experience online. The WARP client sits between your 100 | device and the Internet, and has several connection modes to better suit 101 | different needs.") 102 | (license 103 | (license "Nonfree" 104 | "https://www.cloudflare.com/application/terms/" 105 | "This is a nonfree license. Check the URI for details.")) 106 | (properties 107 | '((upstream-name . "cloudflare-warp") 108 | (release-monitoring-url 109 | . "https://pkg.cloudflareclient.com/dists/bookworm/main/binary-amd64/Packages"))))) 110 | 111 | (define-public komga-bin 112 | (package 113 | (name "komga-bin") 114 | (version "1.21.3") 115 | (source (origin 116 | (method url-fetch) 117 | (uri (string-append 118 | "https://github.com/gotson/komga/releases/download/" version 119 | "/komga-" version ".jar")) 120 | (sha256 121 | (base32 122 | "1w3yk0xnc6pyqpmzg7vcadmmxxg2zr5lvf88ri7iyihdb85zyn1l")))) 123 | (build-system copy-build-system) 124 | (arguments 125 | (list #:install-plan 126 | #~'((#$(string-append "komga-" (package-version this-package) ".jar") 127 | "lib/komga/komga.jar")) 128 | #:phases 129 | #~(modify-phases %standard-phases 130 | (replace 'install 131 | (lambda* (#:key inputs source #:allow-other-keys) 132 | (let* ((lib (in-vicinity #$output "lib/komga")) 133 | (bin (in-vicinity #$output "bin")) 134 | (jar (in-vicinity lib "komga.jar")) 135 | (exe "komga")) 136 | (mkdir-p lib) 137 | (copy-file source jar) 138 | (call-with-output-file exe 139 | (lambda (port) 140 | (format port "~ 141 | #!~a 142 | export LC_ALL=C.UTF-8 143 | exec ~a -jar ~a $@~%" 144 | (search-input-file inputs "bin/bash") 145 | (search-input-file inputs "bin/java") 146 | jar))) 147 | (chmod exe #o555) 148 | (install-file exe bin))))))) 149 | (inputs (list bash-minimal openjdk)) 150 | (home-page "https://komga.org/") 151 | (synopsis "Media server for comics/mangas/BDs/magazines/eBooks") 152 | (description 153 | "Komga is a media server for your comics, mangas, BDs, magazines and 154 | eBooks.") 155 | (license license:expat) 156 | (properties '((upstream-name . "komga"))))) 157 | 158 | (define-public navidrome-bin 159 | (package 160 | (name "navidrome-bin") 161 | (version "0.56.1") 162 | (source (origin 163 | (method url-fetch) 164 | (uri (string-append 165 | "https://github.com/navidrome/navidrome/releases/download/v" 166 | version "/navidrome_" version "_linux_amd64.tar.gz")) 167 | (sha256 168 | (base32 169 | "0zad3rjviqfl7cm8iiyfc6gw3v84j273d4aijf3xwpgy5574siq3")))) 170 | (build-system copy-build-system) 171 | (arguments 172 | (list #:install-plan 173 | #~'(("navidrome" "bin/")))) 174 | (supported-systems '("x86_64-linux")) 175 | (home-page "https://www.navidrome.org/") 176 | (synopsis "Web-based music collection server and streamer") 177 | (description 178 | "Navidrome is a self-hosted music server that allows users to stream and 179 | manage their music collections. It provides a web interface and is compatible 180 | with the Subsonic API.") 181 | (license license:expat) 182 | (properties '((upstream-name . "navidrome"))))) 183 | 184 | (define-public shadow-tls-bin 185 | (package 186 | (name "shadow-tls-bin") 187 | (version "0.2.25") 188 | (source (origin 189 | (method url-fetch) 190 | (uri (string-append 191 | "https://github.com/ihciah/shadow-tls/releases/download/v" 192 | version "/shadow-tls-x86_64-unknown-linux-musl")) 193 | (sha256 194 | (base32 195 | "0chmqzfmyw5w8ybshkwigc3r25svq7fyw371d0dj2ibzsprgawx1")))) 196 | (build-system copy-build-system) 197 | (arguments 198 | (list #:install-plan 199 | #~'(("shadow-tls-x86_64-unknown-linux-musl" "bin/shadow-tls")) 200 | #:phases 201 | #~(modify-phases %standard-phases 202 | (add-after 'install 'fix-permission 203 | (lambda _ 204 | (chmod (string-append #$output "/bin/shadow-tls") #o555)))))) 205 | (supported-systems '("x86_64-linux")) 206 | (home-page "https://www.ihcblog.com/a-better-tls-obfs-proxy/") 207 | (synopsis "Proxy to expose real tls handshake to the firewall") 208 | (description 209 | "Shadow TLS is a proxy to expose real tls handshake to the @acronym{MITM, 210 | monster-in-the-middle}.") 211 | (license license:expat) 212 | (properties '((upstream-name . "shadow-tls"))))) 213 | 214 | (define-public sing-box-bin 215 | (deprecated-package "sing-box-bin" sing-box)) 216 | 217 | (define-public tailscale-bin 218 | (deprecated-package "tailscale-bin" tailscale)) 219 | 220 | (define-public wakapi-bin 221 | (package 222 | (name "wakapi-bin") 223 | (version "2.13.4") 224 | (source (origin 225 | (method url-fetch) 226 | (uri (string-append 227 | "https://github.com/muety/wakapi/releases/download/" 228 | version "/wakapi_linux_amd64.zip")) 229 | (sha256 230 | (base32 231 | "07wylvgi8yqcmywpvgbsqyhza86nmg8dfx1apmaynlw80y0nzial")))) 232 | (build-system copy-build-system) 233 | (arguments (list #:install-plan #~'(("wakapi" "bin/wakapi")))) 234 | (supported-systems '("x86_64-linux")) 235 | (native-inputs (list unzip)) 236 | (home-page "https://wakapi.dev/") 237 | (synopsis "WakaTime-compatible backend") 238 | (description 239 | "This package provides @code{wakapi}, a WakaTime-compatible backend for 240 | coding statistics.") 241 | (license license:expat) 242 | (properties '((upstream-name . "wakapi"))))) 243 | 244 | (define-public wakatime-cli-bin 245 | (package 246 | (name "wakatime-cli-bin") 247 | (version "1.115.3") 248 | (source (origin 249 | (method url-fetch) 250 | (uri (string-append "https://github.com/wakatime/wakatime-cli" 251 | "/releases/download/v" version 252 | "/wakatime-cli-linux-amd64.zip")) 253 | (sha256 254 | (base32 255 | "0vfnbcgyaav95a7jbmh8xvpwlmcf8wsqlrf28yq9y79sywhc78bk")))) 256 | (build-system copy-build-system) 257 | (arguments 258 | (list #:install-plan 259 | #~'(("wakatime-cli-linux-amd64" "bin/wakatime-cli")))) 260 | (supported-systems '("x86_64-linux")) 261 | (native-inputs (list unzip)) 262 | (home-page "https://wakatime.com/plugins") 263 | (synopsis "Command line interface to WakaTime") 264 | (description 265 | "This package provides @command{wakatime-cli}, the command line interface 266 | to WakaTime, which is used by all WakaTime text editor plugins.") 267 | (license license:bsd-3) 268 | (properties '((upstream-name . "wakatime-cli"))))) 269 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/bootloaders.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages bootloaders) 6 | #:use-module (guix download) 7 | #:use-module (guix gexp) 8 | #:use-module (guix packages) 9 | #:use-module (guix utils) 10 | #:use-module (gnu packages autotools) 11 | #:use-module (gnu packages bootloaders) 12 | #:use-module (gnu packages python)) 13 | 14 | ;; Patches obtained from: 15 | ;; 16 | 17 | (define grub-luks2-argon2-support-patch 18 | (origin 19 | (method url-fetch) 20 | (uri (string-append "https://leo3418.github.io/" 21 | "res/collections/gentoo-config-luks2-grub-systemd/" 22 | "grub-2.12-luks2-argon2-v4.patch")) 23 | (sha256 24 | (base32 25 | "02y15k6rd5vj2shfijyhq2nr2775vpa55ijfy6bb8irpnh8i2272")))) 26 | 27 | (define-public grub-efi-luks2 28 | (let ((base grub-efi)) 29 | (package 30 | (inherit base) 31 | (name "grub-efi-luks2") 32 | (source 33 | (let ((base (package-source base))) 34 | (origin 35 | (inherit base) 36 | (patches 37 | (append (origin-patches base) 38 | (list grub-luks2-argon2-support-patch)))))) 39 | (arguments 40 | (substitute-keyword-arguments (package-arguments base) 41 | ((#:configure-flags flags ''()) 42 | #~(append #$flags '("--disable-werror"))) 43 | ((#:phases phases '%standard-phases) 44 | #~(modify-phases #$phases 45 | (add-after 'unpack 'delete-configure-script 46 | (lambda _ 47 | (delete-file "configure"))))))) 48 | (native-inputs 49 | (modify-inputs (package-native-inputs base) 50 | (append autoconf automake python-minimal-wrapper))) 51 | (properties 52 | `(,@(package-properties base) 53 | (disable-updater? . #t)))))) 54 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/browser-extensions.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023-2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages browser-extensions) 6 | #:use-module (srfi srfi-1) 7 | #:use-module (guix gexp) 8 | #:use-module ((guix licenses) #:prefix license:) 9 | #:use-module (guix packages) 10 | #:use-module (guix download) 11 | #:use-module (guix git-download) 12 | #:use-module (guix build-system copy) 13 | #:use-module (gnu build icecat-extension)) 14 | 15 | (define-public bitwarden 16 | (package 17 | (name "bitwarden") 18 | (version "2025.5.0") 19 | (source (origin 20 | (method url-fetch/zipbomb) 21 | (uri (string-append "https://github.com/bitwarden/clients" 22 | "/releases/download/browser-v" version 23 | "/dist-firefox-" version ".zip")) 24 | (sha256 25 | (base32 26 | "139q19bn14p70czh9ylb3wjz0kmsgn340lcjn2wwi0vb6pdlwa3f")))) 27 | (build-system copy-build-system) 28 | (arguments 29 | (list #:install-plan 30 | #~'(("." #$(assq-ref (package-properties this-package) 'addon-id))))) 31 | (home-page "https://bitwarden.com/") 32 | (synopsis "Bitwarden client browser extension") 33 | (description 34 | "This package provides browser extension for Bitwarden client.") 35 | (license license:gpl3) 36 | (properties 37 | '((addon-id . "{446900e4-71c2-419f-a6a7-df9c091e268b}") 38 | (hidden? . #t) 39 | (disable-updater? . #t))))) 40 | 41 | (define-public bitwarden/icecat 42 | (let ((base (make-icecat-extension bitwarden))) 43 | (package 44 | (inherit base) 45 | (properties 46 | `(,@(alist-delete 'hidden? (package-properties base)) 47 | (disable-updater? . #t)))))) 48 | 49 | (define-public miniflux-injector 50 | (package 51 | (name "miniflux-injector") 52 | (version "2.3.3") 53 | (properties 54 | '((addon-id . "{528ec801-2e29-4cb9-ae71-5a90503138d1}") 55 | (hidden? . #t) 56 | (disable-updater? . #t))) 57 | (source 58 | (origin 59 | (method url-fetch/zipbomb) 60 | (uri (string-append 61 | "https://github.com/Sevichecc/miniflux-injector/releases/download" 62 | "/v" version "/miniflux_injector-" version ".zip")) 63 | (sha256 64 | (base32 65 | "199z441ak6dwy7skgbwc9aa4gfd2r4i22hxfm27s5k3rv7barbvs")) 66 | (modules '((guix build utils))) 67 | (snippet 68 | #~(substitute* "manifest.json" 69 | (("homepage_url.*" line) 70 | (string-append line "\ 71 | \"browser_specific_settings\": { 72 | \"gecko\": { 73 | \"id\": \"" #$(assq-ref properties 'addon-id) "\" 74 | } 75 | }, 76 | ")))))) 77 | (build-system copy-build-system) 78 | (arguments 79 | (list 80 | #:install-plan 81 | #~'(("." #$(assq-ref (package-properties this-package) 'addon-id))))) 82 | (home-page "https://github.com/Sevichecc/miniflux-injector") 83 | (synopsis "Injects Miniflux search results into search page") 84 | (description 85 | "This package provides a browser extension to inject Miniflux search 86 | results into search page. Search terms are sent to your Miniflux instance and 87 | results are added in a sidebar next to search engine results.") 88 | (license license:expat))) 89 | 90 | (define-public miniflux-injector/icecat 91 | (let ((base (make-icecat-extension miniflux-injector))) 92 | (package 93 | (inherit base) 94 | (properties 95 | `(,@(alist-delete 'hidden? (package-properties base)) 96 | (disable-updater? . #t)))))) 97 | 98 | (define-public ohmyech 99 | (package 100 | (name "ohmyech") 101 | (version "1.1") 102 | (properties 103 | '((addon-id . "{46b8ab0b-8adf-4e43-ad67-acef5a8d45c9}") 104 | (hidden? . #t) 105 | (disable-updater? . #t))) 106 | (source (origin 107 | (method git-fetch) 108 | (uri (git-reference 109 | (url "https://github.com/27justin/ohmyech") 110 | (commit "ec7935d500a9d354776586e25261cef3595c40c7"))) 111 | (file-name (git-file-name name version)) 112 | (sha256 113 | (base32 114 | "1mrbm8c8z9zpfrs0qk5qj64f35p7c5lrxfn3nhda0ar0b2rv6593")) 115 | (modules '((guix build utils))) 116 | (snippet 117 | #~(substitute* "manifest.json" 118 | (("\"version\".*" line) 119 | (string-append line "\ 120 | \"browser_specific_settings\": { 121 | \"gecko\": { 122 | \"id\": \"" #$(assq-ref properties 'addon-id) "\" 123 | } 124 | }, 125 | ")))))) 126 | (build-system copy-build-system) 127 | (arguments 128 | (list #:install-plan 129 | #~'(("." #$(assq-ref (package-properties this-package) 'addon-id))))) 130 | (home-page "https://github.com/27justin/ohmyech") 131 | (synopsis "Visual indicator for Encrpted Client Hello") 132 | (description 133 | "OhMyECH is a browser extension for indicating the use of @acronym{ECH, 134 | Encrypted Client Hello} on web pages. When enabled, it adds an icon to the 135 | browser address bar, providing users with a visual cue about whether the 136 | current page employs @acronym{ECH}, which helps protect sensitive information 137 | during the @acronym{TLS, Transport Layer Security} handshake process.") 138 | (license license:expat))) 139 | 140 | (define-public ohmyech-icecat 141 | (let ((base (make-icecat-extension ohmyech))) 142 | (package 143 | (inherit base) 144 | (properties 145 | `(,@(alist-delete 'hidden? (package-properties base)) 146 | (disable-updater? . #t)))))) 147 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/busybox.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages busybox) 6 | #:use-module (guix gexp) 7 | #:use-module (guix packages) 8 | #:use-module (guix utils) 9 | #:use-module (gnu packages busybox)) 10 | 11 | (define-public busybox/static 12 | (let ((base busybox)) 13 | (package 14 | (inherit base) 15 | (name "busybox-static") 16 | (arguments 17 | (substitute-keyword-arguments (package-arguments base) 18 | ((#:phases phases) 19 | #~(modify-phases #$phases 20 | (add-after 'configure 'static-build 21 | (lambda _ 22 | (substitute* ".config" 23 | (("# CONFIG_STATIC is not set") 24 | "CONFIG_STATIC=y")))) 25 | ;; FIXME: All mdev tests fail when building staticly. 26 | (add-before 'check 'disable-failing-tests 27 | (lambda _ 28 | (delete-file "testsuite/mdev.tests"))))))) 29 | (properties 30 | `(,@(package-properties base) 31 | (disable-updater? . #t)))))) 32 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/dns.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022-2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages dns) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix build-system copy) 8 | #:use-module (guix gexp) 9 | #:use-module (guix git-download) 10 | #:use-module (guix packages)) 11 | 12 | (define-public dnsmasq-china-list 13 | ;; No version. 14 | (let ((commit "c7ed41997e78b41841a394d6852b5ccdb1b3f31c") 15 | (revision "19")) 16 | (package 17 | (name "dnsmasq-china-list") 18 | (version (git-version "0" revision commit)) 19 | (source (origin 20 | (method git-fetch) 21 | (uri (git-reference 22 | (url "https://github.com/felixonmars/dnsmasq-china-list") 23 | (commit commit))) 24 | (file-name (git-file-name name version)) 25 | (sha256 26 | (base32 27 | "194vnc48l57cpdvphzsysfl9bsmcilnpgbaalbbk1iq7dhb9jb6x")))) 28 | (build-system copy-build-system) 29 | (arguments 30 | (list #:install-plan 31 | #~'(("." "share/dnsmasq-china-list/" #:include-regexp ("\\.conf"))) 32 | #:phases 33 | #~(modify-phases %standard-phases 34 | (add-before 'install 'build 35 | (lambda _ 36 | (for-each (lambda (target) 37 | (invoke "make" target 38 | "SERVER=domestic" 39 | "SMARTDNS_SPEEDTEST_MODE=tcp:80")) 40 | '("adguardhome" 41 | "bind" 42 | "coredns" 43 | "dnscrypt-proxy" 44 | "dnsforwarder6" 45 | "dnsmasq" 46 | "smartdns" "smartdns-domain-rules" 47 | "unbound"))))))) 48 | (home-page "https://github.com/felixonmars/dnsmasq-china-list") 49 | (synopsis "Chinese-specific DNS server configurations") 50 | (description 51 | "Chinese-specific configuration to improve your favorite DNS server. 52 | Best partner for chnroutes. 53 | 54 | @itemize 55 | @item Improve resolve speed for Chinese domains. 56 | @item Get the best CDN node near you whenever possible, but don't compromise 57 | foreign CDN results so you also get best CDN node for your VPN at the same 58 | time. 59 | @item Block ISP ads on NXDOMAIN result (like 114so). 60 | @end itemize") 61 | (license license:wtfpl2) 62 | (properties 63 | '((disable-updater? . #t)))))) 64 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/emacs-xyz.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022-2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages emacs-xyz) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix build-system emacs) 8 | #:use-module (guix gexp) 9 | #:use-module (guix download) 10 | #:use-module (guix git-download) 11 | #:use-module (guix packages) 12 | #:use-module (gnu packages emacs-xyz)) 13 | 14 | (define-public emacs-caddyfile-mode 15 | (let ((commit "fc41148f5a7eb320f070666f046fb9d88cf17680") 16 | (revision "0")) 17 | (package 18 | (name "emacs-caddyfile-mode") 19 | (version (git-version "0.2" revision commit)) 20 | (source (origin 21 | (method git-fetch) 22 | (uri (git-reference 23 | (url "https://github.com/Schnouki/caddyfile-mode") 24 | (commit commit))) 25 | (file-name (git-file-name name version)) 26 | (sha256 27 | (base32 28 | "1s9kbav5wbyividn9zncd153h89nil0i9aj9hgxa95q9fy84r23w")))) 29 | (build-system emacs-build-system) 30 | (propagated-inputs (list emacs-loop)) 31 | (home-page "https://github.com/Schnouki/caddyfile-mode") 32 | (synopsis "Emacs major mode for editing Caddy configuration files") 33 | (description 34 | "This package provides @code{caddyfile-mode}, an Emacs major mode for 35 | editing Caddyfiles, configuration files for @code{caddy}.") 36 | (license license:gpl3+) 37 | (properties 38 | '((disable-updater? . #t)))))) 39 | 40 | (define-public emacs-nftables-mode 41 | (package 42 | (name "emacs-nftables-mode") 43 | (version "1.1") 44 | (source 45 | (origin 46 | (method url-fetch) 47 | (uri (string-append "https://elpa.gnu.org/packages/nftables-mode-" 48 | version ".tar")) 49 | (sha256 50 | (base32 "1wjw6n60kj84j8gj62mr6s97xd0aqvr4v7npyxwmhckw9z13xcqv")))) 51 | (build-system emacs-build-system) 52 | (home-page "https://elpa.gnu.org/packages/nftables-mode.html") 53 | (synopsis "Major mode for editing nftables scripts") 54 | (description 55 | "@code{nftables-mode} is an Emacs major mode for editing nftables scripts. 56 | It currently only offers basic highlighting and primitive indentation.") 57 | (license license:gpl3+))) 58 | 59 | (define-public emacs-pcmpl-tailscale 60 | (let ((commit "acd6bce54af506b0450cf6aa1068f63d4e25c8ce") 61 | (revision "0")) 62 | (package 63 | (name "emacs-pcmpl-tailscale") 64 | (version (git-version "0.0.1" revision commit)) 65 | (source 66 | (origin 67 | (method git-fetch) 68 | (uri (git-reference 69 | (url "https://git.thanosapollo.org/pcmpl-tailscale") 70 | (commit commit))) 71 | (file-name (git-file-name name version)) 72 | (sha256 73 | (base32 "0lk808ahy8ckg2fr2pqk3p5if81nqrwsajrgqafv9hgn8w4l1x0p")))) 74 | (build-system emacs-build-system) 75 | (home-page "https://git.thanosapollo.org/pcmpl-tailscale") 76 | (synopsis "Enhanced shell completions for tailscale") 77 | (description 78 | "This package provides enhanced completions for the tailscale command 79 | and it's subcommands.") 80 | (license license:gpl3+) 81 | (properties 82 | '((disable-updater? . #t)))))) 83 | 84 | (define-public emacs-treesit-auto 85 | (package 86 | (name "emacs-treesit-auto") 87 | ;; NOTE: Not tagged, also change commit when updating. 88 | (version "1.0.7") 89 | (source 90 | (origin 91 | (method git-fetch) 92 | (uri (git-reference 93 | (url "https://github.com/renzmann/treesit-auto") 94 | (commit "016bd286a1ba4628f833a626f8b9d497882ecdf3"))) 95 | (file-name (git-file-name name version)) 96 | (sha256 97 | (base32 "03bvam7cpxqp4idhd235n76qdqhsbgw7m2lphy8qqwslbmcq23m4")))) 98 | (build-system emacs-build-system) 99 | (home-page "https://github.com/renzmann/treesit-auto") 100 | (synopsis "Automatically use tree-sitter major modes") 101 | (description 102 | "@code{treesit-auto} is an Emacs package for automatically using tree-sitter 103 | major modes and falling back to the original major mode when its tree-sitter 104 | counterpart is unavailable.") 105 | (license license:gpl3+) 106 | (properties 107 | '((disable-updater? . #t))))) 108 | 109 | ;; https://issues.guix.gnu.org/59552 110 | (define-public emacs-wakatime-mode 111 | ;; No release since May 5, 2015. 112 | (let ((commit "1c5b2254dd72f2ff504d6a6189a8c10be03a98d1") 113 | (revision "60")) 114 | (package 115 | (name "emacs-wakatime-mode") 116 | ;; 1.0.2 on commit 32a0154cd4bbd525d354997e6b12c6a9726d0b43, not tagged 117 | (version (git-version "1.0.2" revision commit)) 118 | (source (origin 119 | (method git-fetch) 120 | (uri (git-reference 121 | (url "https://github.com/wakatime/wakatime-mode") 122 | (commit commit))) 123 | (file-name (git-file-name name version)) 124 | (sha256 125 | (base32 126 | "00qv6b756qiaqrmfg1w03psnsdj0iaz3sp50ib4kmdm2g9vgxl1s")))) 127 | (build-system emacs-build-system) 128 | (arguments 129 | (list #:phases 130 | #~(modify-phases %standard-phases 131 | ;; XXX: WakaTime hasn't packaged in Guix yet. 132 | (delete 'patch-el-files)))) 133 | (home-page "https://wakatime.com/emacs") 134 | (synopsis "Automatic time tracking extension for Emacs using WakaTime") 135 | (description 136 | "WakaTime mode is an Emacs minor mode for automatic time tracking and 137 | metrics generated from your programming activity.") 138 | (license license:gpl3+) 139 | (properties 140 | '((disable-updater? . #t)))))) 141 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/golang.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages golang) 6 | #:use-module (guix packages) 7 | #:use-module ((guix build utils) #:select (alist-replace)) 8 | #:use-module (guix git-download) 9 | #:use-module (gnu packages golang)) 10 | 11 | (define-public go-cloudflare 12 | (let ((commit "37bc41c6ff79507200a315b72834fce6ca427a7e") 13 | (revision "0")) 14 | (package 15 | (inherit go-1.22) 16 | (name "go-cloudflare") 17 | (version (git-version "1.22.12" revision commit)) 18 | (source (origin 19 | (method git-fetch) 20 | (uri (git-reference 21 | (url "https://github.com/cloudflare/go") 22 | (commit commit))) 23 | (file-name (git-file-name name version)) 24 | (sha256 25 | (base32 26 | "1zg6jqwhj42gaapk1fzqc4i7a6shdbfbpqgqhjyry55r4i0nqvxy")))) 27 | (home-page "https://github.com/cloudflare/go") 28 | (synopsis "Go with Cloudflare experimental patches") 29 | (properties 30 | `(,@(package-properties go-1.22) 31 | (disable-updater? . #t)))))) 32 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/networking.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022-2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages networking) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix build-system go) 8 | #:use-module (guix gexp) 9 | #:use-module (guix git-download) 10 | #:use-module (guix packages) 11 | #:use-module (rosenthal utils download) 12 | #:use-module (gnu packages base) 13 | #:use-module (gnu packages dns) 14 | #:use-module (gnu packages golang) 15 | #:use-module (gnu packages golang-build) 16 | #:use-module (gnu packages linux) 17 | #:use-module (rosenthal packages golang)) 18 | 19 | (define-public cloudflared 20 | (package 21 | (name "cloudflared") 22 | (version "2025.5.0") 23 | (source (origin 24 | (method git-fetch) 25 | (uri (git-reference 26 | (url "https://github.com/cloudflare/cloudflared") 27 | (commit version))) 28 | (file-name (git-file-name name version)) 29 | ;; TODO: Unbundle vendored dependencies. 30 | ;; (modules '((guix build utils))) 31 | ;; (snippet '(delete-file-recursively "vendor")) 32 | (sha256 33 | (base32 34 | "0faf5mc1b85fzqj9as7lrb9lgxsvybn65vvw94i7mx003vvh8yb6")))) 35 | (build-system go-build-system) 36 | (arguments 37 | (list #:go go-cloudflare 38 | #:install-source? #f 39 | #:import-path "github.com/cloudflare/cloudflared/cmd/cloudflared" 40 | #:unpack-path "github.com/cloudflare/cloudflared" 41 | #:build-flags 42 | #~(list (string-append 43 | "-ldflags=" 44 | " -X main.Version=" #$(package-version this-package) 45 | " -X github.com/cloudflare/cloudflared/cmd/cloudflared/updater.BuiltForPackageManager=Guix")) 46 | #:phases 47 | #~(modify-phases %standard-phases 48 | (add-before 'build 'disable-cgo 49 | (lambda _ 50 | (setenv "CGO_ENABLED" "0"))) 51 | (add-after 'install 'install-documentation 52 | (lambda _ 53 | (let ((src "src/github.com/cloudflare/cloudflared/cloudflared_man_template") 54 | (dst (string-append #$output "/share/man/man1/cloudflared.1"))) 55 | (substitute* src 56 | (("\\$\\{VERSION\\}") #$(package-version this-package))) 57 | (mkdir-p (dirname dst)) 58 | (copy-file src dst))))))) 59 | (home-page "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/") 60 | (synopsis "Cloudflare Tunnel client") 61 | (description 62 | "This package provides the command-line client for Cloudflare Tunnel, a 63 | tunneling daemon that proxies traffic from the Cloudflare network to your 64 | origins. This daemon sits between Cloudflare network and your origin (e.g. a 65 | webserver). Cloudflare attracts client requests and sends them to you via 66 | this daemon, without requiring you to poke holes on your firewall --- your 67 | origin can remain as closed as possible.") 68 | (license license:asl2.0))) 69 | 70 | (define-public mihomo 71 | (package 72 | (name "mihomo") 73 | (version "1.19.9") 74 | (source (origin 75 | (method git-fetch) 76 | (uri (git-reference 77 | (url "https://github.com/MetaCubeX/mihomo") 78 | (commit (string-append "v" version)))) 79 | (file-name (git-file-name name version)) 80 | (sha256 81 | (base32 82 | "0zbgxh8snxvcg7ik418lfqnhf3f9j967k8d36wvydv0iq3i60nsg")))) 83 | (build-system go-build-system) 84 | (arguments 85 | (list 86 | #:tests? (not (%current-target-system)) ;TODO: Run test suite. 87 | #:go go-1.23 88 | #:install-source? #f 89 | #:import-path "." 90 | #:build-flags 91 | #~(list "-tags" "with_gvisor" 92 | (string-append 93 | "-ldflags=" 94 | " -X github.com/metacubex/mihomo/constant.Version=" 95 | #$(package-version this-package))) 96 | #:modules 97 | '((ice-9 match) 98 | ((guix build gnu-build-system) #:prefix gnu:) 99 | (guix build go-build-system) 100 | (guix build utils)) 101 | #:phases 102 | #~(modify-phases %standard-phases 103 | (replace 'unpack 104 | (lambda args 105 | (unsetenv "GO111MODULE") 106 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 107 | (copy-recursively 108 | #+(this-package-native-input "vendored-go-dependencies") 109 | "vendor"))) 110 | (replace 'install-license-files 111 | (assoc-ref gnu:%standard-phases 'install-license-files)) 112 | (delete 'check) 113 | (add-after 'install 'check 114 | (lambda* (#:key tests? #:allow-other-keys) 115 | (when tests? 116 | (let ((mihomo (in-vicinity #$output "bin/mihomo"))) 117 | (invoke mihomo "--help") 118 | (invoke mihomo "-v")))))))) 119 | (native-inputs 120 | (append 121 | (list (origin 122 | (method (go-mod-vendor #:go go-1.23)) 123 | (uri (package-source this-package)) 124 | (file-name "vendored-go-dependencies") 125 | (sha256 126 | (base32 127 | "0n8szf4knpiwa0jgir8p0swivgyzpd9i6rjv6xv03n4d15fgdc7v")))) 128 | (if (%current-target-system) 129 | (list this-package) 130 | '()))) 131 | (home-page "https://wiki.metacubex.one/") 132 | (synopsis "Rule-based proxy") 133 | (description 134 | "Mihomo is an anti-censorship proxy application, originally known as 135 | \"Clash Meta\", designed to facilitate secure and flexible internet access. 136 | It supports various protocols, making it a versatile tool for users seeking to 137 | bypass network restrictions." ) 138 | (license license:gpl3+))) 139 | 140 | (define-public sing-box 141 | (package 142 | (name "sing-box") 143 | (version "1.11.11") 144 | (source (origin 145 | (method git-fetch) 146 | (uri (git-reference 147 | (url "https://github.com/SagerNet/sing-box") 148 | (commit (string-append "v" version)))) 149 | (file-name (git-file-name name version)) 150 | (sha256 151 | (base32 152 | "1xw3n1cxh53vbv5ql8mdq47w732y4vrhkm44f693m7apl261iml5")))) 153 | (build-system go-build-system) 154 | (arguments 155 | (list 156 | #:tests? (not (%current-target-system)) ;TODO: Run test suite. 157 | #:go go-1.23 158 | #:install-source? #f 159 | #:import-path "./cmd/sing-box" 160 | #:build-flags 161 | #~(list "-tags" (string-join 162 | '("with_quic" 163 | "with_dhcp" 164 | "with_wireguard" 165 | "with_ech" 166 | "with_utls" 167 | "with_reality_server" 168 | "with_acme" 169 | "with_clash_api" 170 | "with_gvisor")) 171 | (string-append 172 | "-ldflags=" 173 | " -X github.com/sagernet/sing-box/constant.Version=" 174 | #$(package-version this-package))) 175 | #:modules 176 | '((ice-9 match) 177 | ((guix build gnu-build-system) #:prefix gnu:) 178 | (guix build go-build-system) 179 | (guix build utils)) 180 | #:phases 181 | #~(modify-phases %standard-phases 182 | (replace 'unpack 183 | (lambda args 184 | (unsetenv "GO111MODULE") 185 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 186 | (copy-recursively 187 | #+(this-package-native-input "vendored-go-dependencies") 188 | "vendor"))) 189 | (replace 'install-license-files 190 | (assoc-ref gnu:%standard-phases 'install-license-files)) 191 | (add-after 'install 'install-extras 192 | (lambda _ 193 | (let ((sing-box 194 | (or (which "sing-box") 195 | (in-vicinity #$output "bin/sing-box")))) 196 | (map 197 | (match-lambda 198 | ((shell . path) 199 | (let ((file (in-vicinity #$output path))) 200 | (mkdir-p (dirname file)) 201 | (with-output-to-file file 202 | (lambda () 203 | (invoke sing-box "completion" shell)))))) 204 | '(("bash" . "etc/bash_completion.d/sing-box") 205 | ("fish" . "share/fish/vendor_completions.d/sing-box.fish") 206 | ("zsh" . "share/zsh/site-functions/_sing-box"))))))))) 207 | (native-inputs 208 | (append 209 | (list (origin 210 | (method (go-mod-vendor #:go go-1.23)) 211 | (uri (package-source this-package)) 212 | (file-name "vendored-go-dependencies") 213 | (sha256 214 | (base32 215 | "1iv58j9zphisqdagc4vm0a6r06frbyrr3viabh2j0vycjsqp0jpz")))) 216 | (if (%current-target-system) 217 | (list this-package) 218 | '()))) 219 | (home-page "https://sing-box.sagernet.org/") 220 | (synopsis "Universal proxy platform") 221 | (description 222 | "@command{sing-box} is a customizable and univsersal proxy platform that 223 | can be used to create network proxy servers, clients and transparent proxies.") 224 | (license license:gpl3+))) 225 | 226 | (define-public socks2http 227 | (package 228 | (name "socks2http") 229 | (version "0.0.0-20160712034938-bafa2cde8eb4") 230 | (source (origin 231 | (method git-fetch) 232 | (uri (git-reference 233 | (url "https://github.com/zenhack/socks2http") 234 | (commit (go-version->git-ref version)))) 235 | (file-name (git-file-name name version)) 236 | (sha256 237 | (base32 238 | "0c388rir9d0cy5vxqxj7m72nra0w5cya4mmgqdcvqmnk2vawdyb9")))) 239 | (build-system go-build-system) 240 | (arguments 241 | (list #:install-source? #f 242 | #:import-path "github.com/zenhack/socks2http")) 243 | (inputs (list go-golang-org-x-net)) 244 | (home-page "https://github.com/zenhack/socks2http") 245 | (synopsis "SOCKS5 to HTTP proxy") 246 | (description 247 | "This package provides a simple tool to plumb HTTP proxy requests through 248 | a SOCKS5 proxy.") 249 | (license license:expat) 250 | (properties 251 | '((disable-updater? . #t))))) 252 | 253 | (define-public tailscale 254 | (package 255 | (name "tailscale") 256 | (version "1.84.0") 257 | (source (origin 258 | (method git-fetch) 259 | (uri (git-reference 260 | (url "https://github.com/tailscale/tailscale") 261 | (commit (string-append "v" version)))) 262 | (file-name (git-file-name name version)) 263 | (sha256 264 | (base32 265 | "1dpx3r4ryv64z51vzxdyrpxydnfxkm5frbbv26p441jfpm907ygk")) 266 | (modules '((guix build utils))) 267 | (snippet 268 | '(begin 269 | (delete-file-recursively "tool") 270 | (substitute* "net/tstun/tun_linux.go" 271 | (("/sbin/(modprobe)" _ cmd) cmd)))))) 272 | (build-system go-build-system) 273 | (arguments 274 | (list 275 | #:tests? (not (%current-target-system)) ;TODO: Run test suite. 276 | #:go go-1.24 277 | #:install-source? #f 278 | #:import-path "." 279 | #:build-flags 280 | #~(list "-tags" "ts_include_cli" 281 | (string-append 282 | "-ldflags=" 283 | " -X tailscale.com/version.longStamp=" 284 | #$(package-version this-package) 285 | " -X tailscale.com/version.shortStamp=" 286 | #$(package-version this-package))) 287 | #:modules 288 | '((ice-9 match) 289 | ((guix build gnu-build-system) #:prefix gnu:) 290 | (guix build go-build-system) 291 | (guix build utils)) 292 | #:phases 293 | #~(modify-phases %standard-phases 294 | (replace 'unpack 295 | (lambda args 296 | (unsetenv "GO111MODULE") 297 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 298 | (copy-recursively 299 | #+(this-package-native-input "vendored-go-dependencies") 300 | "vendor"))) 301 | (replace 'install-license-files 302 | (assoc-ref gnu:%standard-phases 'install-license-files)) 303 | (replace 'build 304 | (lambda* (#:key build-flags parallel-build? #:allow-other-keys) 305 | (let* ((njobs (if parallel-build? (parallel-job-count) 1))) 306 | (setenv "GOMAXPROCS" (number->string njobs)) 307 | (for-each 308 | (lambda (pkg) 309 | (apply invoke "go" "build" "-ldflags=-s -w" "-trimpath" 310 | "-o" (string-append #$output "/bin/" pkg) 311 | `(,@build-flags 312 | ,(string-append "tailscale.com/cmd/" pkg)))) 313 | '("derper" 314 | "derpprobe" 315 | "tailscaled" 316 | "tsidp"))))) 317 | (add-after 'install 'install-extras 318 | (lambda _ 319 | (symlink (in-vicinity #$output "bin/tailscaled") 320 | (in-vicinity #$output "bin/tailscale")) 321 | (let ((tailscale 322 | (or (which "tailscale") 323 | (in-vicinity #$output "bin/tailscale")))) 324 | (map 325 | (match-lambda 326 | ((shell . path) 327 | (let ((file (in-vicinity #$output path))) 328 | (mkdir-p (dirname file)) 329 | (with-output-to-file file 330 | (lambda () 331 | (invoke tailscale "completion" shell)))))) 332 | '(("bash" . "etc/bash_completion.d/tailscale") 333 | ("fish" . "share/fish/vendor_completions.d/tailscale.fish") 334 | ("zsh" . "share/zsh/site-functions/_tailscale")))))) 335 | (add-after 'install 'wrap-binaries 336 | (lambda* (#:key inputs #:allow-other-keys) 337 | (wrap-program (in-vicinity #$output "bin/tailscaled") 338 | `("PATH" ":" prefix 339 | ,(map (lambda (cmd) 340 | (dirname (search-input-file inputs cmd))) 341 | '("bin/find" 342 | "bin/getent" 343 | "bin/modprobe" 344 | "sbin/ip" 345 | "sbin/iptables" 346 | "sbin/resolvconf" 347 | "sbin/sysctl")))))) 348 | (delete 'check) 349 | (add-after 'install 'check 350 | (lambda* (#:key tests? #:allow-other-keys) 351 | (when tests? 352 | (for-each 353 | (lambda (cmd) 354 | (invoke (string-append #$output "/bin/" cmd) "--help")) 355 | '("derper" 356 | "derpprobe" 357 | "tailscaled" 358 | "tsidp")))))))) 359 | (native-inputs 360 | (append 361 | (list (origin 362 | (method (go-mod-vendor #:go go-1.24)) 363 | (uri (package-source this-package)) 364 | (file-name "vendored-go-dependencies") 365 | (sha256 366 | (base32 367 | "1pbcp946wingy0xw8nc1x0hdj55scndv8kdgzfni0f4hwlq045j0")))) 368 | (if (%current-target-system) 369 | (list this-package) 370 | '()))) 371 | (inputs 372 | (list findutils glibc iproute iptables-nft kmod openresolv procps)) 373 | (home-page "https://tailscale.com/") 374 | (synopsis "Mesh VPN service utilizing the WireGuard protocol and 2FA") 375 | (description 376 | "Tailscale is a mesh VPN service that simplifies the process of securely 377 | connecting devices and services across various networks. It allows you to 378 | create a private network with minimal configuration and aims to remove the 379 | complexity of building a trusted and secure network.") 380 | (license license:bsd-3))) 381 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/password-utils.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages password-utils) 6 | #:use-module (guix gexp) 7 | #:use-module ((guix licenses) #:prefix license:) 8 | #:use-module (guix packages) 9 | #:use-module (guix utils) 10 | #:use-module (guix download) 11 | #:use-module (guix git-download) 12 | #:use-module (rosenthal utils download) 13 | #:use-module (guix build-system go) 14 | #:use-module (gnu packages golang)) 15 | 16 | (define-public sops 17 | (package 18 | (name "sops") 19 | (version "3.10.2") 20 | (source (origin 21 | (method git-fetch) 22 | (uri (git-reference 23 | (url "https://github.com/getsops/sops") 24 | (commit (string-append "v" version)))) 25 | (file-name (git-file-name name version)) 26 | (sha256 27 | (base32 28 | "0hnp08w7kcb30ki9h1jca5x0n9cmyxq4nxl00590l0aca32jgm11")))) 29 | (build-system go-build-system) 30 | (arguments 31 | (list #:go go-1.23 32 | #:install-source? #f 33 | #:import-path "./cmd/sops" 34 | #:build-flags 35 | #~(list (string-append 36 | "-ldflags=" 37 | "-X github.com/getsops/sops/v3/version.Version=" 38 | #$(package-version this-package))) 39 | #:modules 40 | '(((guix build gnu-build-system) #:prefix gnu:) 41 | (guix build go-build-system) 42 | (guix build utils)) 43 | #:phases 44 | #~(modify-phases %standard-phases 45 | (replace 'unpack 46 | (lambda args 47 | (unsetenv "GO111MODULE") 48 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 49 | (copy-recursively 50 | #+(this-package-native-input "vendored-go-dependencies") 51 | "vendor"))) 52 | (replace 'install-license-files 53 | (assoc-ref gnu:%standard-phases 'install-license-files))))) 54 | (native-inputs 55 | (list (origin 56 | (method (go-mod-vendor #:go go-1.23)) 57 | (uri (package-source this-package)) 58 | (file-name "vendored-go-dependencies") 59 | (sha256 60 | (base32 61 | "0xc73hy8cm5qsaakhmy3fm0ijh5akghva330c3vinjsm8hhd98gd"))))) 62 | (home-page "https://getsops.io/") 63 | (synopsis "Simple and flexible tool for managing secrets") 64 | (description 65 | "@acronym{SOPS, Secrets OPerationS} is an editor of encrypted files that 66 | supports YAML, JSON, ENV, INI and binary formats and encrypts with @acronym{AWS 67 | KMS, Amazon Web Services Key Management Service}, @acronym{GCP KMS, Google Cloud 68 | Platform Key Management Service}, Azure Key Vault, @code{age}, and OpenPGP.") 69 | (license license:mpl2.0))) 70 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/rust-apps.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages rust-apps) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix gexp) 8 | #:use-module (guix packages) 9 | #:use-module (guix git-download) 10 | #:use-module (guix build-system cargo) 11 | #:use-module (rosenthal utils cargo)) 12 | 13 | (define-public atuin 14 | (package 15 | (name "atuin") 16 | (version "18.4.0") 17 | (source (origin 18 | (method git-fetch) 19 | (uri (git-reference 20 | (url "https://github.com/atuinsh/atuin") 21 | (commit (string-append "v" version)))) 22 | (file-name (git-file-name name version)) 23 | (sha256 24 | (base32 25 | "1zi7ar999ycvig9c9crylab540xdgr0h6v99q9j8ypk9i1fviyiz")))) 26 | (build-system cargo-build-system) 27 | (arguments 28 | (list 29 | #:install-source? #f 30 | #:features 31 | ''("client" "sync" "server" "clipboard" "daemon") 32 | #:phases 33 | #~(modify-phases %standard-phases 34 | (add-after 'unpack 'disable-failing-tests 35 | (lambda _ 36 | (substitute* '("crates/atuin/tests/sync.rs" 37 | "crates/atuin/tests/users.rs" 38 | "crates/atuin-dotfiles/src/store.rs" 39 | "crates/atuin-dotfiles/src/store/var.rs") 40 | (((string-append 41 | ".*async fn (" (string-join 42 | '(;; Require running database. 43 | "build_aliases" 44 | "build_vars" 45 | "sync" 46 | "registration" 47 | "change_password" 48 | "multi_user_test") 49 | "|") ")") 50 | all) 51 | (string-append "#[ignore]\n" all))))) 52 | (add-after 'unpack 'patch-references 53 | (lambda _ 54 | (substitute* (find-files "crates/atuin/src/shell") 55 | (("atuin (uuid|history|search)" all) 56 | (string-append #$output "/bin/" all))))) 57 | (replace 'install 58 | (lambda* (#:key outputs features #:allow-other-keys) 59 | (let* ((out (assoc-ref outputs "out")) 60 | (registry (string-append out "/share/cargo/registry")) 61 | (sources (string-append out "/share/cargo/src"))) 62 | (mkdir-p out) 63 | ;; Make cargo reuse all the artifacts we just built instead 64 | ;; of defaulting to making a new temp directory 65 | (setenv "CARGO_TARGET_DIR" "./target") 66 | ;; Only install crates which include binary targets, 67 | ;; otherwise cargo will raise an error. 68 | (invoke "cargo" "install" "--no-track" "--path" "crates/atuin" 69 | "--root" out "--features" (string-join features)))))))) 70 | (inputs (rosenthal-cargo-inputs 'atuin)) 71 | (home-page "https://atuin.sh/") 72 | (synopsis "Sync, search and backup shell history") 73 | (description 74 | "Atuin replaces existing shell history with a SQLite database, and records 75 | additional context for commands. Additionally, it provides optional and fully 76 | encrypted synchronisation of history between machines, via an Atuin server.") 77 | (license license:expat) 78 | (properties 79 | '((disable-updater? . #t))))) 80 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/ssh.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages ssh) 6 | #:use-module (guix gexp) 7 | #:use-module (guix packages) 8 | #:use-module (guix utils) 9 | #:use-module (gnu packages compression) 10 | #:use-module (gnu packages multiprecision) 11 | #:use-module (gnu packages ssh)) 12 | 13 | (define-public dropbear/static 14 | (let ((base dropbear)) 15 | (package 16 | (inherit dropbear) 17 | (name "dropbear-static") 18 | (arguments 19 | (substitute-keyword-arguments (package-arguments base) 20 | ((#:configure-flags flags) 21 | #~(append #$flags (list "--enable-static"))))) 22 | (inputs 23 | (modify-inputs (package-inputs base) 24 | (append `(,zlib "static")) 25 | (replace "libtomcrypt" `(,libtomcrypt "static")) 26 | (replace "libtommath" `(,libtommath "static")))) 27 | (properties 28 | `(,@(package-properties base) 29 | (disable-updater? . #t)))))) 30 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/tree-sitter.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages tree-sitter) 6 | #:use-module (guix gexp) 7 | #:use-module (guix packages)) 8 | 9 | (define tree-sitter-grammar 10 | (@@ (gnu packages tree-sitter) tree-sitter-grammar)) 11 | 12 | (define-public tree-sitter-yaml 13 | (let ((base 14 | (tree-sitter-grammar 15 | "yaml" "YAML" 16 | "1bimf5fq85wn8dwlk665w15n2bj37fma5rsfxrph3i9yb0lvzi3q" 17 | "0.5.0" 18 | #:repository-url "https://github.com/ikatyang/tree-sitter-yaml" 19 | #:get-cleanup-snippet 20 | (lambda (grammar-directories) 21 | #~(begin 22 | (use-modules (guix build utils)) 23 | (delete-file-recursively "docs") 24 | (delete-file "binding.gyp") 25 | (delete-file-recursively "bindings") 26 | (for-each 27 | (lambda (lang) 28 | (with-directory-excursion lang 29 | (delete-file "src/grammar.json") 30 | (delete-file "src/node-types.json") 31 | (delete-file "src/parser.c") 32 | (delete-file-recursively "src/tree_sitter"))) 33 | '#$grammar-directories)))))) 34 | (package 35 | (inherit base) 36 | (arguments 37 | (append '(#:tests? #f) ;FIXME 38 | (package-arguments base))) 39 | (properties 40 | '((disable-updater? . #t)))))) 41 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/video.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages video) 6 | #:use-module (guix gexp) 7 | #:use-module (guix packages) 8 | #:use-module (guix utils) 9 | #:use-module (gnu packages video)) 10 | 11 | (define-public libva-nox 12 | (let ((base libva)) 13 | (package 14 | (inherit base) 15 | (name "libva-nox") 16 | (arguments 17 | (substitute-keyword-arguments (package-arguments base) 18 | ((#:configure-flags configure-flags) 19 | #~(append #$configure-flags (list "--disable-glx"))) 20 | ((#:phases _) #~%standard-phases))) 21 | (inputs 22 | (modify-inputs (package-inputs base) 23 | (delete "libx11" "libxext" "libxfixes"))) 24 | (properties 25 | `(,@(package-properties base) 26 | (disable-updater? . #t)))))) 27 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/web.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022, 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages web) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix gexp) 8 | #:use-module (guix packages) 9 | #:use-module (guix utils) 10 | #:use-module (guix download) 11 | #:use-module (guix git-download) 12 | #:use-module (rosenthal utils download) 13 | #:use-module (guix build-system copy) 14 | #:use-module (guix build-system go) 15 | #:use-module (gnu packages golang) 16 | #:use-module (gnu packages image) 17 | #:use-module (gnu packages web) 18 | #:use-module (gnu packages version-control) 19 | #:use-module (rosenthal packages golang)) 20 | 21 | (define-public ai-robots-txt 22 | (package 23 | (name "ai-robots-txt") 24 | (version "1.31") 25 | (source (origin 26 | (method git-fetch) 27 | (uri (git-reference 28 | (url "https://github.com/ai-robots-txt/ai.robots.txt") 29 | (commit (string-append "v" version)))) 30 | (file-name (git-file-name name version)) 31 | (sha256 32 | (base32 33 | "1bvq24w8pq56knhdacjkq93v6l719jcj3jf4fsknlmp9m6izm3zj")) 34 | (modules '((guix build utils))) 35 | (snippet '(delete-file-recursively "code")))) 36 | (build-system copy-build-system) 37 | (arguments 38 | (list #:install-plan 39 | ''(("." "share/ai-robots-txt/" 40 | #:include ("robots.txt" 41 | ".htaccess" 42 | "nginx-block-ai-bots.conf" 43 | "Caddyfile" 44 | "haproxy-block-ai-bots.txt"))))) 45 | (home-page "https://github.com/ai-robots-txt/ai.robots.txt") 46 | (synopsis "List of AI agents and robots to block") 47 | (description 48 | "This package provides a collection of configuration files to help 49 | website owners block unwanted AI crawlers from accessing their sites.") 50 | (license license:expat))) 51 | 52 | (define-public caddy 53 | (package 54 | (name "caddy") 55 | (version "2.10.0") 56 | (source (origin 57 | (method git-fetch) 58 | (uri (git-reference 59 | (url "https://github.com/caddyserver/caddy") 60 | (commit (string-append "v" version)))) 61 | (file-name (git-file-name name version)) 62 | (sha256 63 | (base32 64 | "00crxr956sp865pc3mg0zsacsy80s8v4jgqpmbq3hrsk2gcdsc47")) 65 | (modules '((guix build utils))) 66 | (snippet '(substitute* "go.mod" 67 | (("^toolchain.*") ""))))) 68 | (build-system go-build-system) 69 | (arguments 70 | (list #:go go-1.24 71 | #:tests? (not (%current-target-system)) ;TODO: Run test suite. 72 | #:install-source? #f 73 | #:import-path 74 | (if (string=? "caddy" (package-name this-package)) 75 | "./cmd/caddy" 76 | ".") 77 | #:build-flags 78 | #~(list "-tags" "nobadger nomysql nopgx" 79 | (string-append 80 | "-ldflags=" 81 | " -X github.com/caddyserver/caddy/v2.CustomVersion=" 82 | #$(package-version this-package))) 83 | #:modules 84 | '((ice-9 match) 85 | ((guix build gnu-build-system) #:prefix gnu:) 86 | (guix build go-build-system) 87 | (guix build utils)) 88 | #:phases 89 | #~(modify-phases %standard-phases 90 | (replace 'unpack 91 | (lambda args 92 | (unsetenv "GO111MODULE") 93 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 94 | (copy-recursively 95 | #+(this-package-native-input "vendored-go-dependencies") 96 | "vendor"))) 97 | (replace 'install-license-files 98 | (assoc-ref gnu:%standard-phases 'install-license-files)) 99 | (add-after 'install 'install-extras 100 | (lambda _ 101 | (let ((caddy 102 | (or (which "caddy") 103 | (in-vicinity #$output "bin/caddy")))) 104 | (invoke caddy "manpage" "--directory" 105 | (in-vicinity #$output "share/man/man8")) 106 | (map 107 | (match-lambda 108 | ((shell . path) 109 | (let ((file (in-vicinity #$output path))) 110 | (mkdir-p (dirname file)) 111 | (with-output-to-file file 112 | (lambda () 113 | (invoke caddy "completion" shell)))))) 114 | '(("bash" . "etc/bash_completion.d/caddy") 115 | ("fish" . "share/fish/vendor_completions.d/caddy.fish") 116 | ("zsh" . "share/zsh/site-functions/_caddy")))))) 117 | (delete 'check) 118 | (add-after 'install 'check 119 | (lambda* (#:key tests? #:allow-other-keys) 120 | (when tests? 121 | (let ((caddy (in-vicinity #$output "bin/caddy"))) 122 | (invoke caddy "help") 123 | (invoke caddy "version")))))))) 124 | (native-inputs 125 | (list (origin 126 | (method (go-mod-vendor #:go go-1.24)) 127 | (uri (package-source this-package)) 128 | (file-name "vendored-go-dependencies") 129 | (sha256 130 | (base32 131 | "0iwxhc85xnhpqrahiaw1017vxg27hc5q22rc0f96g42mc2mbi2zl"))))) 132 | (home-page "https://caddyserver.com/") 133 | (synopsis "Extensible HTTP web server with automatic HTTPS") 134 | (description 135 | "Caddy is a web server designed for simplicity and ease of use. It is 136 | notable for its automatic HTTPS feature, which enables secure connections 137 | without requiring complex configuration. Caddy is built with a focus on 138 | performance and flexibility, making it suitable for a variety of applications, 139 | from serving static websites to running dynamic web applications.") 140 | (license license:asl2.0))) 141 | 142 | (define-public caddy/hako 143 | (package 144 | (inherit caddy) 145 | (name "caddy-hako") 146 | (version "2025.05.23-1") 147 | (source (origin 148 | (method git-fetch) 149 | (uri (git-reference 150 | (url "https://git.boiledscript.com/hako/caddy.git") 151 | (commit version))) 152 | (file-name (git-file-name name version)) 153 | (sha256 154 | (base32 155 | "03jdlyakaxysz5wmxbwrdwl3rgkp0a0ws10g27hj1lmkdic860h9")))) 156 | (native-inputs 157 | (modify-inputs (package-native-inputs caddy) 158 | (replace "vendored-go-dependencies" 159 | (origin 160 | (method (go-mod-vendor #:go go-1.24)) 161 | (uri (package-source this-package)) 162 | (file-name "vendored-go-dependencies") 163 | (sha256 164 | (base32 165 | "0m01p9y96m1krjg1rf53kndxklql8i4hfv09rc3xnxbmqh5ahm43")))))) 166 | (home-page "https://git.boiledscript.com/hako/caddy") 167 | (properties '((disable-updater? . #t))))) 168 | 169 | (define-public hugo 170 | (package 171 | (name "hugo") 172 | (version "0.147.6") 173 | (source (origin 174 | (method git-fetch) 175 | (uri (git-reference 176 | (url "https://github.com/gohugoio/hugo") 177 | (commit (string-append "v" version)))) 178 | (file-name (git-file-name name version)) 179 | (sha256 180 | (base32 181 | "08ghd15x1d9db0y2n3b8cqhp4axpb34jdsiwnx8x1dc0kg2q5dwc")))) 182 | (build-system go-build-system) 183 | (arguments 184 | (list 185 | #:go go-1.24 186 | #:install-source? #f 187 | #:import-path "." 188 | #:build-flags 189 | #~(list "-tags" "extended withdeploy" 190 | (string-append 191 | "-ldflags=" 192 | " -X github.com/gohugoio/hugo/common/hugo.vendorInfo=Nonguix")) 193 | #:test-flags ''("-skip=^TestCommands/mod|^TestCommands/server") 194 | #:test-subdirs ''(".") 195 | #:modules 196 | '(((guix build gnu-build-system) #:prefix gnu:) 197 | (guix build go-build-system) 198 | (guix build utils)) 199 | #:phases 200 | #~(modify-phases %standard-phases 201 | (replace 'unpack 202 | (lambda args 203 | (unsetenv "GO111MODULE") 204 | (apply (assoc-ref gnu:%standard-phases 'unpack) args) 205 | (copy-recursively 206 | #+(this-package-native-input "vendored-go-dependencies") 207 | "vendor"))) 208 | (replace 'install-license-files 209 | (assoc-ref gnu:%standard-phases 'install-license-files)) 210 | (add-after 'unpack 'fix-paths 211 | (lambda* (#:key native-inputs inputs #:allow-other-keys) 212 | (setenv "C_INCLUDE_PATH" 213 | (string-append 214 | (getenv "C_INCLUDE_PATH") ":" 215 | (dirname 216 | (dirname 217 | (dirname 218 | (search-input-file 219 | (or native-inputs inputs) 220 | "src/dec/alphai_dec.h")))))) 221 | (with-directory-excursion "vendor/github.com/bep/gowebp" 222 | (substitute* (find-files "internal/libwebp") 223 | (("../../libwebp_src/(.*)\"" _ file) 224 | (format #f "~a\"" 225 | (search-input-file 226 | (or native-inputs inputs) file))))) 227 | (with-directory-excursion "vendor/github.com/bep/golibsass" 228 | (substitute* (find-files "internal/libsass") 229 | (("../../libsass_src/(.*)\"" _ file) 230 | (format #f "~a\"" 231 | (search-input-file 232 | (or native-inputs inputs) file)))))))))) 233 | (native-inputs 234 | (list (origin 235 | (method (go-mod-vendor #:go go-1.24)) 236 | (uri (package-source this-package)) 237 | (file-name "vendored-go-dependencies") 238 | (sha256 239 | (base32 240 | "0wrzl37mv2qcww6s2bk4jf4gjj6pkxnwm44q8qrg0vijch8pxdbq"))) 241 | (package-source libsass) 242 | (package-source libwebp))) 243 | (home-page "https://gohugo.io/") 244 | (synopsis "Static site generator written in Go") 245 | (description 246 | "Hugo is a static site generator written in Go, optimized for speed and 247 | designed for flexibility. With its advanced templating system and fast asset 248 | pipelines, Hugo renders a complete site in seconds, often less.") 249 | (license license:asl2.0))) 250 | 251 | (define-public forgejo 252 | (package 253 | (name "forgejo") 254 | (version "11.0.1") 255 | ;; TODO: Address npm dependencies and fetch from git. 256 | (source (origin 257 | (method url-fetch) 258 | (uri (string-append 259 | "https://codeberg.org/forgejo/forgejo/releases/download/v" 260 | version "/forgejo-src-" version ".tar.gz")) 261 | (sha256 262 | (base32 263 | "1mpdbwq3h0l5yk8f2sjpnyr0b6wngryx3238166rf7l2k5869bmq")) 264 | (modules '((guix build utils))) 265 | ;; Avoid downloading toolchain. 266 | (snippet '(substitute* "go.mod" 267 | (("^toolchain.*") ""))))) 268 | (build-system go-build-system) 269 | (arguments 270 | (list #:tests? (not (%current-target-system)) ;TODO: Run test suite. 271 | #:go go-1.24 272 | #:install-source? #f 273 | #:import-path "." 274 | #:build-flags 275 | #~(list (string-append 276 | "-ldflags=" 277 | " -X main.ReleaseVersion=" #$(package-version this-package) 278 | " -X main.Version=" #$(package-version this-package) 279 | " -X main.ForgejoVersion=" #$(package-version this-package) 280 | " -X forgejo.org/modules/setting.AppWorkPath=/var/lib/forgejo" 281 | " -X forgejo.org/modules/setting.CustomPath=" #$output "/etc/forgejo" 282 | " -X forgejo.org/modules/setting.CustomConf=/etc/forgejo/app.ini")) 283 | #:modules 284 | '(((guix build gnu-build-system) #:prefix gnu:) 285 | (guix build go-build-system) 286 | (guix build union) 287 | (guix build utils)) 288 | #:phases 289 | #~(modify-phases %standard-phases 290 | (replace 'unpack 291 | (lambda args 292 | (unsetenv "GO111MODULE") 293 | (apply (assoc-ref gnu:%standard-phases 'unpack) args))) 294 | (replace 'install-license-files 295 | (assoc-ref gnu:%standard-phases 'install-license-files)) 296 | (add-after 'install 'rename-binary 297 | (lambda _ 298 | (rename-file (in-vicinity #$output "bin/forgejo.org") 299 | (in-vicinity #$output "bin/forgejo")))) 300 | (add-after 'install 'install-extras 301 | (lambda _ 302 | (mkdir-p (in-vicinity #$output "/etc/forgejo")) 303 | (copy-file "custom/conf/app.example.ini" 304 | (in-vicinity #$output "etc/forgejo/app.ini")) 305 | (for-each 306 | (lambda (dir) 307 | (copy-recursively 308 | dir (string-append #$output "/etc/forgejo/" dir))) 309 | '("options" "public" "templates")))) 310 | (delete 'check) 311 | (add-after 'rename-binary 'check 312 | (lambda* (#:key tests? #:allow-other-keys) 313 | (when tests? 314 | (let ((forgejo (in-vicinity #$output "bin/forgejo"))) 315 | (invoke forgejo "--help") 316 | (invoke forgejo "--version")))))))) 317 | (native-inputs (list git-minimal)) 318 | (home-page "https://forgejo.org/") 319 | (synopsis "Lightweight software forge") 320 | (description 321 | "Forgejo is a self-hosted, lightweight software forge designed to 322 | facilitate collaborative software development. It is built to be easy to 323 | install and maintain, making it an ideal choice for teams and organizations 324 | looking for a reliable platform to manage their software projects.") 325 | (license license:gpl3+) 326 | (properties 327 | '((disable-updater? . #t))))) 328 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/wm.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages wm) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix gexp) 8 | #:use-module (guix packages) 9 | #:use-module (guix git-download) 10 | #:use-module (guix build-system cargo) 11 | #:use-module (rosenthal utils cargo) 12 | #:use-module (gnu packages admin) 13 | #:use-module (gnu packages freedesktop) 14 | #:use-module (gnu packages gl) 15 | #:use-module (gnu packages glib) 16 | #:use-module (gnu packages gtk) 17 | #:use-module (gnu packages linux) 18 | #:use-module (gnu packages llvm) 19 | #:use-module (gnu packages pkg-config) 20 | #:use-module (gnu packages wm) 21 | #:use-module (gnu packages xdisorg)) 22 | 23 | (define-public rust-pipewire 24 | (let ((commit "fd3d8f7861a29c2eeaa4c393402e013578bb36d9") 25 | (revision "0")) 26 | (package 27 | (name "rust-pipewire") 28 | (version (git-version "0.8.0" revision commit)) 29 | (source 30 | (origin 31 | (method git-fetch) 32 | (uri (git-reference 33 | (url "https://gitlab.freedesktop.org/pipewire/pipewire-rs.git") 34 | (commit commit))) 35 | (file-name (git-file-name name version)) 36 | (sha256 37 | (base32 "1hzyhz7xg0mz8a5y9j6yil513p1m610q3j9pzf6q55vdh5mcn79v")))) 38 | (build-system cargo-build-system) 39 | (arguments 40 | (list #:skip-build? #t 41 | #:phases 42 | #~(modify-phases %standard-phases 43 | ;; Avoid circular dependency. 44 | (add-after 'unpack 'remove-dev-dependencies 45 | (lambda _ 46 | (substitute* "libspa/Cargo.toml" 47 | (("^pipewire.*") "")))) 48 | (replace 'package 49 | (lambda* (#:key cargo-package-flags vendor-dir #:allow-other-keys) 50 | (begin 51 | ;;error: invalid inclusion of reserved file name Cargo.toml.orig in package source 52 | (when (file-exists? "Cargo.toml.orig") 53 | (delete-file "Cargo.toml.orig")) 54 | 55 | (for-each 56 | (lambda (pkg) 57 | (apply invoke "cargo" "package" "--offline" "--package" pkg 58 | cargo-package-flags) 59 | (for-each 60 | (lambda (crate) 61 | (invoke "tar" "xzf" crate "-C" vendor-dir)) 62 | (find-files "target/package" "\\.crate$")) 63 | ((assoc-ref %standard-phases 'patch-cargo-checksums))) 64 | '("libspa-sys" "libspa" "pipewire-sys" "pipewire")))))))) 65 | (inputs (rosenthal-cargo-inputs 'rust-pipewire)) 66 | (home-page "https://pipewire.org/") 67 | (synopsis "Rust bindings for PipeWire") 68 | (description "This package provides Rust bindings for PipeWire.") 69 | (license license:expat) 70 | (properties 71 | '((hidden? . #t) 72 | (disable-updater? . #t)))))) 73 | 74 | (define-public rust-smithay 75 | (let ((commit "0cd3345c59f7cb139521f267956a1a4e33248393") 76 | (revision "0")) 77 | (package 78 | (name "rust-smithay") 79 | (version (git-version "0.4.0" revision commit)) 80 | (source (origin 81 | (method git-fetch) 82 | (uri (git-reference 83 | (url "https://github.com/Smithay/smithay") 84 | (commit commit))) 85 | (file-name (git-file-name name version)) 86 | (sha256 87 | (base32 88 | "191h87bpzg0l1ihfb4hmx00b86pfb5mwwc6s8i49al0vigc14l37")))) 89 | (build-system cargo-build-system) 90 | (arguments 91 | (list #:skip-build? #t 92 | #:phases 93 | #~(modify-phases %standard-phases 94 | (replace 'package 95 | (lambda* (#:key cargo-package-flags vendor-dir #:allow-other-keys) 96 | (begin 97 | ;;error: invalid inclusion of reserved file name Cargo.toml.orig in package source 98 | (when (file-exists? "Cargo.toml.orig") 99 | (delete-file "Cargo.toml.orig")) 100 | 101 | (for-each 102 | (lambda (pkg) 103 | (apply invoke "cargo" "package" "--offline" "--package" pkg 104 | cargo-package-flags) 105 | (for-each 106 | (lambda (crate) 107 | (invoke "tar" "xzf" crate "-C" vendor-dir)) 108 | (find-files "target/package" "\\.crate$")) 109 | ((assoc-ref %standard-phases 'patch-cargo-checksums))) 110 | '("smithay" "smithay-drm-extras")))))))) 111 | (inputs (rosenthal-cargo-inputs 'rust-smithay)) 112 | (home-page "https://github.com/Smithay/smithay") 113 | (synopsis "Smithy for Rust Wayland compositors") 114 | (description 115 | "Smithay aims to provide building blocks to create wayland compositors in 116 | Rust. While not being a full-blown compositor, it'll provide objects and 117 | interfaces implementing common functionalities that pretty much any compositor 118 | will need, in a generic fashion. 119 | 120 | It supports the @code{wayland}, @code{wayland-protocols}, and some external 121 | extensions, such as @code{wlr-protocols} and @code{plasma-wayland-protocols}.") 122 | (license license:expat) 123 | (properties 124 | '((hidden? . #t) 125 | (disable-updater? . #t)))))) 126 | 127 | (define-public niri 128 | (package 129 | (name "niri") 130 | (version "25.02") 131 | (source (origin 132 | (method git-fetch) 133 | (uri (git-reference 134 | (url "https://github.com/YaLTeR/niri") 135 | (commit (string-append "v" version)))) 136 | (file-name (git-file-name name version)) 137 | (sha256 138 | (base32 139 | "0vzskaalcz6pcml687n54adjddzgf5r07gggc4fhfsa08h1wfd4r")))) 140 | (build-system cargo-build-system) 141 | (arguments 142 | (list #:install-source? #f 143 | #:phases 144 | #~(modify-phases %standard-phases 145 | (add-after 'unpack 'use-guix-vendored-dependencies 146 | (lambda _ 147 | (substitute* "Cargo.toml" 148 | (("# version =.*") 149 | "version = \"*\"") 150 | (("git.*optional") 151 | "version = \"*\", optional") 152 | (("^git = .*") 153 | "")))) 154 | (add-after 'unpack 'set-environment 155 | (lambda _ 156 | (setenv "RUSTFLAGS" 157 | (string-join 158 | '("-C" "link-arg=-lEGL" 159 | "-C" "link-arg=-lwayland-client") 160 | " ")) 161 | (setenv "NIRI_BUILD_VERSION_STRING" 162 | #$(package-version this-package)) 163 | ;; For tests. 164 | (setenv "XDG_RUNTIME_DIR" "/tmp"))) 165 | (add-after 'install 'install-extras 166 | (lambda _ 167 | (substitute* "resources/niri.desktop" 168 | (("niri-session") 169 | (string-append #$output "/bin/niri --session"))) 170 | (install-file 171 | "resources/niri.desktop" 172 | (in-vicinity #$output "share/wayland-sessions")) 173 | (install-file 174 | "resources/niri-portals.conf" 175 | (in-vicinity #$output "share/xdg-desktop-portal"))))))) 176 | (native-inputs 177 | (list pkg-config)) 178 | (inputs 179 | (cons* clang 180 | libdisplay-info 181 | libinput-minimal 182 | libseat 183 | libxkbcommon 184 | mesa 185 | pango 186 | pipewire 187 | wayland 188 | (rosenthal-cargo-inputs 'niri))) 189 | (home-page "https://github.com/YaLTeR/niri") 190 | (synopsis "Scrollable-tiling Wayland compositor") 191 | (description 192 | "Niri is a scrollable-tiling Wayland compositor which arranges windows in a 193 | scrollable format. It is considered stable for daily use and performs most 194 | functions expected of a Wayland compositor.") 195 | (license license:gpl3) 196 | (properties 197 | '((disable-updater? . #t))))) 198 | -------------------------------------------------------------------------------- /modules/rosenthal/packages/xorg.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal packages xorg) 6 | #:use-module ((guix licenses) #:prefix license:) 7 | #:use-module (guix gexp) 8 | #:use-module (guix packages) 9 | #:use-module (guix git-download) 10 | #:use-module (guix build-system cargo) 11 | #:use-module (rosenthal utils cargo) 12 | #:use-module (gnu packages llvm) 13 | #:use-module (gnu packages pkg-config) 14 | #:use-module (gnu packages xorg)) 15 | 16 | (define-public xwayland-satellite 17 | (package 18 | (name "xwayland-satellite") 19 | (version "0.5.1") 20 | (source (origin 21 | (method git-fetch) 22 | (uri (git-reference 23 | (url "https://github.com/Supreeeme/xwayland-satellite") 24 | (commit (string-append "v" version)))) 25 | (file-name (git-file-name name version)) 26 | (sha256 27 | (base32 28 | "1r99qfbmc67202pcs4kiw94hiql0aqcsx877bgnlyxy6gzilq47y")))) 29 | (build-system cargo-build-system) 30 | (arguments 31 | (list #:install-source? #f 32 | #:tests? #f ;Requires running display server. 33 | #:phases 34 | #~(modify-phases %standard-phases 35 | (add-after 'unpack 'fix-paths 36 | (lambda* (#:key inputs #:allow-other-keys) 37 | (substitute* "src/lib.rs" 38 | (("\"Xwayland\"") 39 | (format #f "\"~a\"" 40 | (search-input-file inputs "bin/Xwayland"))))))))) 41 | (native-inputs (list pkg-config)) 42 | (inputs 43 | (cons* clang 44 | xcb-util-cursor 45 | xorg-server-xwayland 46 | (rosenthal-cargo-inputs 'xwayland-satellite))) 47 | (home-page "https://github.com/Supreeeme/xwayland-satellite") 48 | (synopsis "Xwayland outside your Wayland") 49 | (description 50 | "@command{xwayland-satellite} grants rootless Xwayland integration to any 51 | Wayland compositor implementing @code{xdg_wm_base} interface. This is 52 | particularly useful for compositors that (understandably) do not want to go 53 | through implementing support for rootless Xwayland themselves.") 54 | (license license:mpl2.0))) 55 | -------------------------------------------------------------------------------- /modules/rosenthal/services/bittorrent.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022, 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services bittorrent) 6 | #:use-module (ice-9 format) 7 | #:use-module (guix gexp) 8 | #:use-module (guix records) 9 | #:use-module (gnu packages admin) 10 | #:use-module (gnu packages bittorrent) 11 | #:use-module (gnu services) 12 | #:use-module (gnu services configuration) 13 | #:use-module (gnu services shepherd) 14 | #:use-module (gnu home services) 15 | #:use-module (gnu home services shepherd) 16 | #:use-module (gnu system shadow) 17 | #:export (qbittorrent-configuration 18 | qbittorrent-service-type 19 | home-qbittorrent-service-type)) 20 | 21 | ;; 22 | ;; qBittorrent 23 | ;; 24 | 25 | 26 | (define-configuration qbittorrent-configuration 27 | (qbittorrent 28 | (file-like qbittorrent-nox) 29 | "The qBittorrent package to use, we need @command{qbittorrent-nox}.") 30 | (webui-port 31 | (integer 8080) 32 | "Change the Web UI port.") 33 | (profile-directory 34 | (string "/var/lib/qbittorrent") 35 | "Directory to store configuration files in.") 36 | (extra-options 37 | (list-of-strings '()) 38 | "List of extra options.") 39 | (no-serialization)) 40 | 41 | (define %qbittorrent-accounts 42 | (list (user-group (name "qbittorrent") (system? #t)) 43 | (user-account 44 | (name "qbittorrent") 45 | (group "qbittorrent") 46 | (system? #t) 47 | (comment "qBittorrent user") 48 | (home-directory "/var/empty") 49 | (shell (file-append shadow "/sbin/nologin"))))) 50 | 51 | ;; Set default password to adminadmin 52 | (define %qbittorrent-default-config-file 53 | (plain-file 54 | "qBittorrent.conf" 55 | (format #f "~ 56 | [LegalNotice] 57 | Accepted=true 58 | [Preferences] 59 | WebUI\\Password_PBKDF2=\"@ByteArray(ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==)\"~%"))) 60 | 61 | (define qbittorrent-activation 62 | (match-record-lambda 63 | (profile-directory) 64 | #~(begin 65 | (use-modules (srfi srfi-26) 66 | (guix build utils)) 67 | (let ((user (getpwnam "qbittorrent")) 68 | (config-file 69 | (string-append 70 | #$profile-directory "/qBittorrent/config/qBittorrent.conf"))) 71 | (unless (file-exists? config-file) 72 | (mkdir-p (dirname config-file)) 73 | (copy-file #$%qbittorrent-default-config-file config-file) 74 | (map (cut chown <> (passwd:uid user) (passwd:gid user)) 75 | (cons #$profile-directory 76 | (find-files #$profile-directory #:directories? #t)))))))) 77 | 78 | (define qbittorrent-shepherd-service 79 | (match-record-lambda 80 | (qbittorrent webui-port profile-directory extra-options) 81 | (list (shepherd-service 82 | (documentation "Run qbittorrent.") 83 | (provision '(qbittorrent)) 84 | (requirement '(networking)) 85 | (start #~(make-forkexec-constructor 86 | (list #$(file-append qbittorrent "/bin/qbittorrent-nox") 87 | #$(string-append "--webui-port=" 88 | (number->string webui-port)) 89 | #$(string-append "--profile=" profile-directory) 90 | #$@extra-options) 91 | #:user "qbittorrent" 92 | #:group "qbittorrent" 93 | #:resource-limits '((nofile 65536 65536)))) 94 | (stop #~(make-kill-destructor #:grace-period 1800)) 95 | (actions 96 | (list (shepherd-configuration-action 97 | (string-append profile-directory 98 | "/qBittorrent/config/qBittorrent.conf")))))))) 99 | 100 | (define qbittorrent-service-type 101 | (service-type 102 | (name 'qbittorrent) 103 | (extensions 104 | (list (service-extension shepherd-root-service-type 105 | qbittorrent-shepherd-service) 106 | (service-extension activation-service-type 107 | qbittorrent-activation) 108 | (service-extension account-service-type 109 | (const %qbittorrent-accounts)))) 110 | (default-value (qbittorrent-configuration)) 111 | (description "Run qBittorrent daemon."))) 112 | 113 | (define home-qbittorrent-activation 114 | #~(let ((config-file 115 | (string-append 116 | (or (getenv "XDG_CONFIG_HOME") 117 | (string-append user-homedir "/.config")) 118 | "/qBittorrent/qBittorrent.conf"))) 119 | (unless (file-exists? config-file) 120 | (mkdir-p (dirname config-file)) 121 | (copy-file #$%qbittorrent-default-config-file config-file)))) 122 | 123 | (define home-qbittorrent-shepherd-service 124 | (match-record-lambda 125 | (qbittorrent webui-port extra-options) 126 | (list (shepherd-service 127 | (documentation "Run qbittorrent.") 128 | (provision '(qbittorrent)) 129 | (requirement '()) 130 | (start 131 | #~(make-forkexec-constructor 132 | (list 133 | #$(file-append qbittorrent "/bin/qbittorrent-nox") 134 | #$(string-append "--webui-port=" (number->string webui-port)) 135 | #$@extra-options))) 136 | (stop #~(make-kill-destructor #:grace-period 1800)))))) 137 | 138 | (define home-qbittorrent-service-type 139 | (service-type 140 | (name 'qbittorrent) 141 | (extensions 142 | (list (service-extension home-activation-service-type 143 | (const home-qbittorrent-activation)) 144 | (service-extension home-shepherd-service-type 145 | home-qbittorrent-shepherd-service))) 146 | (default-value (qbittorrent-configuration)) 147 | (description "Run qBittorrent daemon."))) 148 | -------------------------------------------------------------------------------- /modules/rosenthal/services/child-error.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022, 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services child-error) 6 | #:use-module (guix records) 7 | #:use-module (guix gexp) 8 | #:use-module (gnu home services) 9 | #:use-module (gnu home services shepherd) 10 | #:use-module (gnu packages admin) 11 | #:use-module (gnu packages web) 12 | #:use-module (gnu services) 13 | #:use-module (gnu services admin) 14 | #:use-module (gnu services configuration) 15 | #:use-module (gnu services databases) 16 | #:use-module (gnu services shepherd) 17 | #:use-module (gnu system shadow) 18 | #:use-module (rosenthal packages binaries) 19 | #:use-module (rosenthal packages networking) 20 | #:use-module (rosenthal utils serializers yaml) 21 | #:export (clash-configuration 22 | clash-service-type 23 | 24 | cloudflare-tunnel-configuration 25 | cloudflare-tunnel-service-type 26 | 27 | cloudflare-warp-configuration 28 | cloudflare-warp-service-type 29 | 30 | miniflux-configuration 31 | miniflux-service-type 32 | 33 | home-wakapi-configuration 34 | home-wakapi-service-type 35 | 36 | shadow-tls-configuration 37 | shadow-tls-client-configuration 38 | shadow-tls-server-configuration 39 | shadow-tls-service-type 40 | home-shadow-tls-service-type 41 | 42 | home-socks2http-configuration 43 | home-socks2http-service-type)) 44 | 45 | ;; 46 | ;; Clash 47 | ;; 48 | 49 | 50 | (define-configuration clash-configuration 51 | (clash 52 | (file-like mihomo-bin) 53 | "The clash package.") 54 | 55 | (log-file 56 | (string "/var/log/clash.log") 57 | "Where the logs go.") 58 | 59 | (data-directory 60 | (string "/var/lib/clash") 61 | "Where to store data.") 62 | 63 | (config 64 | (file-like (plain-file "empty" "")) 65 | "Clash configuration file.") 66 | 67 | (shepherd-provision 68 | (list '(clash)) 69 | "A list of Shepherd service names (symbols) provided by this service.") 70 | (no-serialization)) 71 | 72 | (define %clash-accounts 73 | (list (user-group (name "clash") (system? #t)))) 74 | 75 | (define clash-activation 76 | (match-record-lambda 77 | (data-directory config) 78 | #~(begin 79 | (use-modules (guix build utils)) 80 | (let ((config-dest (string-append #$data-directory "/config.yaml"))) 81 | (mkdir-p #$data-directory) 82 | (if (file-exists? config-dest) 83 | (delete-file config-dest)) 84 | (symlink #$config config-dest))))) 85 | 86 | (define clash-shepherd-service 87 | (match-record-lambda 88 | (clash log-file data-directory shepherd-provision) 89 | (list (shepherd-service 90 | (documentation "Run clash.") 91 | (provision shepherd-provision) 92 | (requirement '(loopback networking)) 93 | (start #~(make-forkexec-constructor 94 | (list (let ((mihomo-cmd 95 | #$(file-append clash "/bin/mihomo")) 96 | (clash-cmd 97 | #$(file-append clash "/bin/clash"))) 98 | (if (file-exists? mihomo-cmd) 99 | mihomo-cmd 100 | clash-cmd)) 101 | "-d" #$data-directory) 102 | #:group "clash" 103 | #:log-file #$log-file)) 104 | (stop #~(make-kill-destructor)) 105 | (actions 106 | (list (shepherd-configuration-action 107 | (string-append data-directory "/config.yaml")))))))) 108 | 109 | (define clash-service-type 110 | (service-type 111 | (name 'clash) 112 | (extensions 113 | (list (service-extension shepherd-root-service-type 114 | clash-shepherd-service) 115 | (service-extension activation-service-type 116 | clash-activation) 117 | (service-extension account-service-type 118 | (const %clash-accounts)) 119 | (service-extension log-rotation-service-type 120 | (compose list clash-configuration-log-file)))) 121 | (default-value (clash-configuration)) 122 | (description "Run Clash."))) 123 | 124 | 125 | ;; 126 | ;; Cloudflare Tunnel 127 | ;; 128 | 129 | 130 | (define-maybe string) 131 | 132 | (define-configuration cloudflare-tunnel-configuration 133 | (cloudflared 134 | (file-like cloudflared) 135 | "The cloudflared executable.") 136 | 137 | ;; Tunnel options 138 | (log-level 139 | (string "info") 140 | "Application logging level (@code{debug}, @code{info}, @code{warn}, 141 | @code{error}, @code{fatal}). At debug level cloudflared will log request URL, 142 | method, protocol, content length, as well as, all request and response 143 | headers. This can expose sensitive information in your logs.") 144 | (log-file 145 | (string "/var/log/cloudflared.log") 146 | "File path to store logs.") 147 | (extra-tunnel-options 148 | (list-of-strings '()) 149 | "List of extra tunnel options.") 150 | 151 | ;; Subcommand options 152 | (token 153 | maybe-string 154 | "The Tunnel token.") 155 | (token-file 156 | maybe-string 157 | "Secert file for the Tunnel token.") 158 | (extra-options 159 | (list-of-strings '()) 160 | "List of extra options.") 161 | (no-serialization)) 162 | 163 | (define %cloudflare-tunnel-accounts 164 | (list (user-account 165 | (name "cloudflared") 166 | (group "nogroup") 167 | (system? #t) 168 | (home-directory "/var/empty") 169 | (create-home-directory? #f) 170 | (shell (file-append shadow "/sbin/nologin"))))) 171 | 172 | (define cloudflare-tunnel-shepherd-service 173 | (match-record-lambda 174 | (cloudflared log-level log-file extra-tunnel-options 175 | token token-file extra-options) 176 | (list (shepherd-service 177 | (documentation "Run cloudflared.") 178 | (provision '(cloudflare-tunnel cloudflared)) 179 | (requirement '(loopback networking)) 180 | (start #~(make-forkexec-constructor 181 | (list #$(file-append cloudflared "/bin/cloudflared") 182 | "tunnel" 183 | "--no-autoupdate" 184 | "--loglevel" #$log-level 185 | #$@extra-tunnel-options 186 | "run" 187 | #$@extra-options) 188 | #:user "cloudflared" 189 | #:group "nogroup" 190 | #:log-file #$log-file 191 | #:environment-variables 192 | (list #$@(if (maybe-value-set? token) 193 | (list (format #f "TUNNEL_TOKEN=~a" 194 | token)) 195 | '()) 196 | #$@(if (maybe-value-set? token-file) 197 | (list (format #f "TUNNEL_TOKEN_FILE=~a" 198 | token-file)) 199 | '())))) 200 | (stop #~(make-kill-destructor)))))) 201 | 202 | (define cloudflare-tunnel-service-type 203 | (service-type 204 | (name 'cloudflare-tunnel) 205 | (extensions 206 | (list (service-extension shepherd-root-service-type 207 | cloudflare-tunnel-shepherd-service) 208 | (service-extension account-service-type 209 | (const %cloudflare-tunnel-accounts)) 210 | (service-extension log-rotation-service-type 211 | (compose list cloudflare-tunnel-configuration-log-file)))) 212 | (default-value (cloudflare-tunnel-configuration)) 213 | (description "Run cloudflared, the Cloudflare Tunnel daemon."))) 214 | 215 | 216 | ;; 217 | ;; Cloudflare Warp 218 | ;; 219 | 220 | 221 | (define-configuration cloudflare-warp-configuration 222 | (cloudflare-warp 223 | (file-like cloudflare-warp-bin) 224 | "The Cloudflare Warp package.") 225 | (no-serialization)) 226 | 227 | (define cloudflare-warp-shepherd-service 228 | (match-record-lambda 229 | (cloudflare-warp) 230 | (list (shepherd-service 231 | (documentation "Run warp-svc.") 232 | (provision '(cloudflare-warp)) 233 | (start #~(make-forkexec-constructor 234 | (list #$(file-append cloudflare-warp "/bin/warp-svc")) 235 | ;; Logs are written to 236 | ;; /var/lib/cloudflare-warp/cfwarp_service_log.txt. 237 | #:log-file "/dev/null")) 238 | (stop #~(make-kill-destructor)))))) 239 | 240 | (define cloudflare-warp-service-type 241 | (service-type 242 | (name 'cloudflare-warp) 243 | (extensions 244 | (list (service-extension shepherd-root-service-type 245 | cloudflare-warp-shepherd-service) 246 | (service-extension 247 | profile-service-type 248 | (compose list cloudflare-warp-configuration-cloudflare-warp)))) 249 | (default-value (cloudflare-warp-configuration)) 250 | (description "Run warp-svc, the Cloudflare Warp daemon."))) 251 | 252 | 253 | ;; 254 | ;; Miniflux 255 | ;; 256 | 257 | 258 | (define-maybe string) 259 | 260 | (define-configuration miniflux-configuration 261 | (miniflux 262 | (file-like miniflux) 263 | "The miniflux package.") 264 | (log-file 265 | (string "/var/log/miniflux.log") 266 | "Where the logs go.") 267 | (proxy-url 268 | maybe-string 269 | "Proxy URL to use.") 270 | (options 271 | (alist '()) 272 | "Association list of miniflux configuration options.") 273 | (no-serialization)) 274 | 275 | (define %miniflux-accounts 276 | (list (user-account 277 | (name "miniflux") 278 | (group "nogroup") 279 | (system? #t) 280 | (home-directory "/var/empty") 281 | (shell (file-append shadow "/sbin/nologin"))))) 282 | 283 | (define %miniflux-postgresql-role 284 | (list (postgresql-role 285 | (name "miniflux") 286 | (create-database? #t)))) 287 | 288 | (define miniflux-shepherd-service 289 | (match-record-lambda 290 | (miniflux log-file proxy-url options) 291 | (let ((config-file (mixed-text-file 292 | "miniflux.conf" 293 | (apply string-append 294 | (map (lambda (option) 295 | (format #f "~a=~a~%" 296 | (car option) (cdr option))) 297 | options))))) 298 | (list (shepherd-service 299 | (documentation "Run miniflux.") 300 | (provision '(miniflux)) 301 | (requirement '(postgres user-processes)) 302 | (start #~(make-forkexec-constructor 303 | (list #$(file-append miniflux "/bin/miniflux") 304 | "-config-file" #$config-file) 305 | #:user "miniflux" 306 | #:group "nogroup" 307 | #:log-file #$log-file 308 | #:environment-variables 309 | '#$(if (maybe-value-set? proxy-url) 310 | (list (string-append "HTTP_PROXY=" proxy-url) 311 | (string-append "HTTPS_PROXY=" proxy-url)) 312 | '()))) 313 | (stop #~(make-kill-destructor))))))) 314 | 315 | (define miniflux-service-type 316 | (service-type 317 | (name 'miniflux) 318 | (extensions 319 | (list (service-extension account-service-type 320 | (const %miniflux-accounts)) 321 | (service-extension postgresql-role-service-type 322 | (const %miniflux-postgresql-role)) 323 | (service-extension shepherd-root-service-type 324 | miniflux-shepherd-service))) 325 | (default-value (miniflux-configuration)) 326 | (description "Run Miniflux, a minimalist and opinionated feed reader."))) 327 | 328 | 329 | ;; 330 | ;; Wakapi 331 | ;; 332 | 333 | 334 | (define-configuration home-wakapi-configuration 335 | (wakapi 336 | (file-like wakapi-bin) 337 | "The wakapi package.") 338 | (config 339 | (yaml-config '()) 340 | "Association list of Wakapi configurations.") 341 | (no-serialization)) 342 | 343 | (define home-wakapi-shepherd-service 344 | (match-record-lambda 345 | (wakapi config) 346 | (let ((config-file (mixed-text-file 347 | "wakapi.yaml" 348 | #~(string-append #$@(yaml-serialize config) "\n")))) 349 | (list (shepherd-service 350 | (documentation "Run wakapi.") 351 | (provision '(wakapi)) 352 | (start #~(make-forkexec-constructor 353 | (list #$(file-append wakapi "/bin/wakapi") 354 | "-config" #$config-file))) 355 | (stop #~(make-kill-destructor)) 356 | (actions (list (shepherd-configuration-action config-file)))))))) 357 | 358 | (define home-wakapi-service-type 359 | (service-type 360 | (name 'home-wakapi) 361 | (extensions 362 | (list (service-extension home-shepherd-service-type 363 | home-wakapi-shepherd-service))) 364 | (default-value (home-wakapi-configuration)) 365 | (description "Run Wakapi, a self-hosted WakaTime-compatible backend."))) 366 | 367 | 368 | ;; 369 | ;; ShadowTLS 370 | ;; 371 | 372 | 373 | (define-maybe list-of-strings 374 | (no-serialization)) 375 | 376 | (define-configuration shadow-tls-client-configuration 377 | (listen-address 378 | (string "") 379 | "Listen address with port. Usually this port is used by Shadowsocks 380 | client.") 381 | (server-address 382 | (string "") 383 | "ShadowTLS server address with port.") 384 | (sni-list 385 | (list-of-strings '("")) 386 | "SNI list.") 387 | (password 388 | (string "") 389 | "Must be the same as the ShadowTLS server.") 390 | (alpn 391 | maybe-list-of-strings 392 | "ALPN ext. Do not use unless you know what you are doing.") 393 | (no-serialization)) 394 | 395 | (define-configuration shadow-tls-server-configuration 396 | (listen-address 397 | (string "") 398 | "Listen address with port.") 399 | (server-address 400 | (string "") 401 | "Data server address with port. Usually this port is listened by Shadowsocks 402 | server.") 403 | (tls-name-list 404 | (list-of-strings '("")) 405 | "TLS names. There must be a fallback server name at the last, and there can 406 | be multiple mappings. Mappings can be represented as 407 | @code{ServerName:Host:Port}. Host can be omitted, in this case 408 | @code{ServerName} is used as @code{Host}. @code{Port} can be omitted too, which 409 | is @code{443} by default") 410 | (password 411 | (string "") 412 | "Must be the same as the ShadowTLS client.") 413 | (no-serialization)) 414 | 415 | (define-record-type* shadow-tls-configuration 416 | make-shadow-tls-configuration 417 | shadow-tls-configuration? 418 | this-shadow-tls-configuration 419 | 420 | (shadow-tls shadow-tls-configuration-shadow-tls ;file-like 421 | (default shadow-tls-bin)) 422 | (threads shadow-tls-configuration-threads ;integer | #f 423 | (default #f)) 424 | (no-delay? shadow-tls-configuration-disable-no-delay? ;boolean 425 | (default #t)) 426 | (v3-protocol? shadow-tls-configuration-v3-protocol? ;boolean 427 | (default #f)) 428 | (log-level shadow-tls-configuration-log-level ;string 429 | (default "info")) 430 | (client shadow-tls-configuration-client ; | #f 431 | (default #f)) 432 | (server shadow-tls-configuration-server ; | #f 433 | (default #f)) 434 | (home-service? shadow-tls-configuration-home-service? 435 | (default for-home?) (innate))) 436 | 437 | (define shadow-tls-shepherd-service 438 | (match-record-lambda 439 | (shadow-tls threads no-delay? v3-protocol? log-level client server 440 | home-service?) 441 | (let ((common-options 442 | (append (if threads 443 | `("--threads" ,(number->string threads)) 444 | '()) 445 | (if no-delay? 446 | '() 447 | '("--disable-nodelay")) 448 | (if v3-protocol? 449 | '("--v3") 450 | '())))) 451 | (append 452 | (if client 453 | (match-record client 454 | 455 | (listen-address server-address sni-list password alpn) 456 | (let ((log-file 457 | (if home-service? 458 | #~(string-append %user-log-dir "/shadow-tls-client.log") 459 | "/var/log/shadow-tls-client.log"))) 460 | (list (shepherd-service 461 | (documentation "Run shadow-tls client.") 462 | (provision '(shadow-tls-client)) 463 | (requirement (if home-service? '() '(networking))) 464 | (modules '((shepherd support))) 465 | (start #~(make-forkexec-constructor 466 | (list #$(file-append 467 | shadow-tls "/bin/shadow-tls") 468 | #$@common-options 469 | "client" 470 | "--listen" #$listen-address 471 | "--server" #$server-address 472 | "--sni" #$(string-join sni-list ";") 473 | "--password" #$password 474 | #$@(if (maybe-value-set? alpn) 475 | `("--alpn" ,(string-join alpn ";")) 476 | '())) 477 | #:user #$(and (not home-service?) "nobody") 478 | #:group #$(and (not home-service?) "nogroup") 479 | #:log-file #$log-file 480 | #:environment-variables 481 | (list (string-append "RUST_LOG=" #$log-level)))) 482 | (stop #~(make-kill-destructor)))))) 483 | '()) 484 | (if server 485 | (match-record server 486 | 487 | (listen-address server-address tls-name-list password) 488 | (let ((log-file 489 | (if home-service? 490 | #~(string-append %user-log-dir "/shadow-tls-server.log") 491 | "/var/log/shadow-tls-server.log"))) 492 | (list (shepherd-service 493 | (documentation "Run shadow-tls server.") 494 | (provision '(shadow-tls-server)) 495 | (requirement (if home-service? '() '(networking))) 496 | (modules '((shepherd support))) 497 | (start #~(make-forkexec-constructor 498 | (list #$(file-append 499 | shadow-tls "/bin/shadow-tls") 500 | #$@common-options 501 | "server" 502 | "--listen" #$listen-address 503 | "--server" #$server-address 504 | "--tls" #$(string-join tls-name-list ";") 505 | "--password" #$password) 506 | #:user #$(and (not home-service?) "nobody") 507 | #:group #$(and (not home-service?) "nogroup") 508 | #:log-file #$log-file)) 509 | (stop #~(make-kill-destructor)))))) 510 | '()))))) 511 | 512 | (define shadow-tls-service-type 513 | (service-type 514 | (name 'shadow-tls) 515 | (extensions 516 | (list (service-extension shepherd-root-service-type 517 | shadow-tls-shepherd-service))) 518 | (default-value (shadow-tls-server-configuration)) 519 | (description "Run shadow-tls."))) 520 | 521 | (define home-shadow-tls-service-type 522 | (service-type 523 | (inherit (system->home-service-type shadow-tls-service-type)) 524 | (default-value (for-home (shadow-tls-configuration))))) 525 | 526 | 527 | ;; 528 | ;; Socks2http 529 | ;; 530 | 531 | 532 | (define-configuration home-socks2http-configuration 533 | (socks2http 534 | (file-like socks2http) 535 | "Socks2http package to use.") 536 | (socks-address 537 | (string ":1080") 538 | "SOCKS5 proxy address to connect to.") 539 | (http-address 540 | (string ":8000") 541 | "HTTP proxy address to serve.") 542 | (no-serialization)) 543 | 544 | (define home-socks2http-shepherd-service 545 | (match-record-lambda 546 | (socks2http socks-address http-address) 547 | (list (shepherd-service 548 | (documentation "Run socks2http.") 549 | (provision '(socks2http)) 550 | (start #~(make-forkexec-constructor 551 | (list #$(file-append socks2http "/bin/socks2http") 552 | "-raddr" #$socks-address 553 | "-laddr" #$http-address))) 554 | (stop #~(make-kill-destructor)))))) 555 | 556 | (define home-socks2http-service-type 557 | (service-type 558 | (name 'home-socks2http) 559 | (extensions 560 | (list (service-extension home-shepherd-service-type 561 | home-socks2http-shepherd-service))) 562 | (default-value (home-socks2http-configuration)) 563 | (description "Run socks2http."))) 564 | 565 | 566 | 567 | 568 | (define-service-type-mapping 569 | shadow-tls-service-type => home-shadow-tls-service-type) 570 | -------------------------------------------------------------------------------- /modules/rosenthal/services/dns.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2022, 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services dns) 6 | #:use-module (guix gexp) 7 | #:use-module (guix records) 8 | #:use-module (gnu services) 9 | #:use-module (gnu services configuration) 10 | #:use-module (gnu packages dns) 11 | #:use-module (gnu services shepherd) 12 | #:export (smartdns-configuration 13 | smartdns-service-type)) 14 | 15 | ;; 16 | ;; Smartdns 17 | ;; 18 | 19 | 20 | (define-configuration smartdns-configuration 21 | (smartdns 22 | (file-like smartdns) 23 | "The Smartdns package.") 24 | (config-file 25 | (file-like (plain-file "empty" "")) 26 | "Configuration file for Smartdns.") 27 | (no-serialization)) 28 | 29 | (define smartdns-shepherd-service 30 | (match-record-lambda 31 | (smartdns config-file) 32 | (list (shepherd-service 33 | (documentation "Run smartdns.") 34 | (provision '(smartdns dns)) 35 | (requirement '(loopback networking)) 36 | (start #~(make-forkexec-constructor 37 | (list #$(file-append smartdns "/sbin/smartdns") 38 | "-f" "-c" #$(file-append config-file)))) 39 | (stop #~(make-kill-destructor)))))) 40 | 41 | (define smartdns-service-type 42 | (service-type 43 | (name 'smartdns) 44 | (extensions 45 | (list (service-extension shepherd-root-service-type 46 | smartdns-shepherd-service))) 47 | (default-value (smartdns-configuration)) 48 | (description "Run Smartdns daemon."))) 49 | -------------------------------------------------------------------------------- /modules/rosenthal/services/file-systems.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services file-systems) 6 | #:use-module (guix gexp) 7 | #:use-module (gnu packages backup) 8 | #:use-module (rosenthal packages admin) 9 | #:use-module (gnu services) 10 | #:use-module (gnu services configuration) 11 | #:use-module (gnu services mcron) 12 | #:use-module (gnu system pam) 13 | #:export (btrbk-service-type 14 | btrbk-configuration 15 | 16 | dumb-runtime-dir-service-type)) 17 | 18 | 19 | ;; 20 | ;; Btrbk 21 | ;; 22 | 23 | 24 | (define-configuration btrbk-configuration 25 | (btrbk 26 | (file-like btrbk) 27 | "@code{btrbk} package to use.") 28 | (config-file 29 | (file-like (plain-file "empty" "")) 30 | "File-like object for btrbk configuration, see also @code{btrbk.conf(5)}.") 31 | (no-serialization)) 32 | 33 | (define (btrbk-etc-service config) 34 | `(("btrbk/btrbk.conf" ,(btrbk-configuration-config-file config)))) 35 | 36 | (define (btrbk-mcron-jobs config) 37 | (list #~(job next-hour-from 38 | #$(file-append (btrbk-configuration-btrbk config) 39 | "/bin/btrbk run --quiet")))) 40 | 41 | (define btrbk-service-type 42 | (service-type 43 | (name 'btrbk) 44 | (extensions 45 | (list (service-extension etc-service-type 46 | btrbk-etc-service) 47 | (service-extension mcron-service-type 48 | btrbk-mcron-jobs))) 49 | (default-value (btrbk-configuration)) 50 | (description "Configure and run btrbk hourly."))) 51 | 52 | 53 | ;;; 54 | ;;; pam-dumb-runtime-dir 55 | ;;; 56 | 57 | 58 | (define dumb-runtime-dir-activation 59 | #~(begin 60 | (use-modules (guix build utils)) 61 | (mkdir-p "/run/user") 62 | (chmod "/run/user" #o0755))) 63 | 64 | (define dumb-runtime-dir-pam-service 65 | (let ((optional-pam-entry 66 | (pam-entry 67 | (control "optional") 68 | (module 69 | (file-append 70 | pam-dumb-runtime-dir "/lib/security/pam_dumb_runtime_dir.so"))))) 71 | (list (pam-extension 72 | (transformer 73 | (lambda (pam) 74 | (if (string=? (pam-service-name pam) "login") 75 | (pam-service 76 | (inherit pam) 77 | (session 78 | (cons optional-pam-entry 79 | (pam-service-session pam)))) 80 | pam))))))) 81 | 82 | (define dumb-runtime-dir-service-type 83 | (service-type 84 | (name 'dumb-runtime-dir) 85 | (extensions 86 | (list (service-extension activation-service-type 87 | (const dumb-runtime-dir-activation)) 88 | (service-extension pam-root-service-type 89 | (const dumb-runtime-dir-pam-service)))) 90 | (default-value #f) ;No default value required. 91 | (description "Create @code{XDG_RUNTIME_DIR} on login and never remove it."))) 92 | -------------------------------------------------------------------------------- /modules/rosenthal/services/keyboard.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-FileCopyrightText: 2021 Andrew Tropin 2 | ;;; 3 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services keyboard) 6 | #:use-module (gnu system keyboard) 7 | #:use-module (gnu home services) 8 | #:export (home-keyboard-service-type)) 9 | 10 | (define (set-xkb-variables layout) 11 | (if layout 12 | `(("XKB_DEFAULT_LAYOUT" . ,(keyboard-layout-name layout)) 13 | ("XKB_DEFAULT_VARIANT" . ,(keyboard-layout-variant layout)) 14 | ("XKB_DEFAULT_OPTIONS" . ,(string-join 15 | (keyboard-layout-options layout) ",")) 16 | ("XKB_DEFAULT_MODEL" . ,(keyboard-layout-model layout))) 17 | '())) 18 | 19 | (define home-keyboard-service-type 20 | (service-type (name 'home-keyboard) 21 | (extensions 22 | (list (service-extension 23 | home-environment-variables-service-type 24 | set-xkb-variables))) 25 | (default-value #f) 26 | (description "Set layouts by configuring XKB_* 27 | environment variables. Service accepts an instance of 28 | @code{keyboard-layout} from @code{(gnu system keyboard)}."))) 29 | -------------------------------------------------------------------------------- /modules/rosenthal/services/mail.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services mail) 6 | #:use-module (srfi srfi-26) 7 | #:use-module (guix records) 8 | #:use-module (gnu services) 9 | #:use-module (gnu services admin) 10 | #:use-module (gnu services configuration) 11 | #:use-module (gnu services docker) 12 | #:export (docker-mailserver-configuration 13 | docker-mailserver-service-type)) 14 | 15 | ;;; 16 | ;;; Docker Mailserver 17 | ;;; https://docker-mailserver.github.io/docker-mailserver/latest/ 18 | ;;; 19 | 20 | (define-configuration docker-mailserver-configuration 21 | (data-directory 22 | (string "/var/lib/docker-mailserver") 23 | "Directory to store Docker Mailserver data.") 24 | (log-file 25 | (string "/var/log/docker-mailserver.log") 26 | "Path to log file.") 27 | (shepherd-requirement 28 | (list-of-symbols '()) 29 | "List of Shepherd service dependencies.") 30 | (options 31 | (alist '()) 32 | "Alist of Docker Mailserver configuration. See also 33 | @url{https://docker-mailserver.github.io/docker-mailserver/latest/config/environment/}.") 34 | (extra-arguments 35 | (list '()) 36 | "List of extra Docker arguments.") 37 | (no-serialization)) 38 | 39 | (define docker-mailserver-oci-containers 40 | (match-record-lambda 41 | (data-directory log-file shepherd-requirement options extra-arguments) 42 | (let ((docker-mailserver-path 43 | (cut string-append data-directory <>))) 44 | (list (oci-container-configuration 45 | (environment options) 46 | (image "ghcr.io/docker-mailserver/docker-mailserver:latest") 47 | (provision "docker-mailserver") 48 | (requirement shepherd-requirement) 49 | (log-file log-file) 50 | (network "host") 51 | (volumes 52 | `((,(docker-mailserver-path "/data") . "/var/mail") 53 | (,(docker-mailserver-path "/state") . "/var/mail-state") 54 | (,(docker-mailserver-path "/logs") . "/var/log/mail") 55 | (,(docker-mailserver-path "/config") . "/tmp/docker-mailserver") 56 | ("/etc/localtime" . "/etc/localtime:ro"))) 57 | (extra-arguments extra-arguments)))))) 58 | 59 | (define docker-mailserver-service-type 60 | (service-type 61 | (name 'docker-mailserver) 62 | (extensions 63 | (list (service-extension oci-container-service-type 64 | docker-mailserver-oci-containers) 65 | (service-extension log-rotation-service-type 66 | (compose list docker-mailserver-configuration-log-file)))) 67 | (default-value (docker-mailserver-configuration)) 68 | (description "Run Docker Mailserver."))) 69 | -------------------------------------------------------------------------------- /modules/rosenthal/services/networking.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2023 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services networking) 6 | #:use-module (srfi srfi-1) 7 | #:use-module (ice-9 match) 8 | #:use-module (guix gexp) 9 | #:use-module (guix records) 10 | #:use-module (gnu packages linux) 11 | #:use-module (gnu packages networking) 12 | #:use-module (rosenthal packages networking) 13 | #:use-module (gnu services) 14 | #:use-module (gnu services admin) 15 | #:use-module (gnu services configuration) 16 | #:use-module (gnu services dbus) 17 | #:use-module (gnu services shepherd) 18 | #:export (iwd-configuration 19 | iwd-service-type 20 | 21 | tailscale-configuration 22 | tailscale-service-type)) 23 | 24 | ;; 25 | ;; iwd 26 | ;; 27 | 28 | 29 | (define %iwd-config-general 30 | '(enable-network-configuration? 31 | use-default-interface? 32 | address-randomization 33 | address-randomization-range 34 | roam-threshold 35 | roam-threshold-5g 36 | roam-retry-interval 37 | management-frame-protection 38 | control-port-over-nl80211? 39 | disable-anqp? 40 | disable-ocv? 41 | country)) 42 | 43 | (define %iwd-config-network 44 | '(enable-ipv6? 45 | name-resolving-service 46 | route-priority-offset)) 47 | 48 | (define %iwd-config-blacklist 49 | '(initial-timeout 50 | multiplier 51 | maximum-timeout)) 52 | 53 | (define %iwd-config-rank 54 | '(band-modifier-5ghz 55 | band-modifier-6ghz)) 56 | 57 | (define %iwd-config-scan 58 | '(disable-periodic-scan? 59 | initial-periodic-scan-interval 60 | maximum-periodic-scan-interval 61 | disable-roaming-scan?)) 62 | 63 | (define %iwd-config-ipv4 64 | '(ap-address-pool)) 65 | 66 | (define %iwd-config-driver-quirks 67 | '(default-interface 68 | force-pae 69 | power-save-disable)) 70 | 71 | (define (uglify-field-name field-name) 72 | (case field-name 73 | ((control-port-over-nl80211?) "ControlPortOverNL80211") 74 | ((disable-anqp?) "DisableANQP") 75 | ((disable-ocv?) "DisableOCV") 76 | ((enable-ipv6?) "EnableIPv6") 77 | ((ap-address-pool) "APAddressPool") 78 | (else (string-delete char-set:punctuation 79 | (string-capitalize (symbol->string field-name)))))) 80 | 81 | (define (serialize-field field-name val) 82 | (format #f "~a = ~a~%" (uglify-field-name field-name) val)) 83 | 84 | (define serialize-string serialize-field) 85 | 86 | (define-maybe string) 87 | 88 | (define (serialize-boolean field-name val) 89 | (serialize-field field-name (if val "true" "false"))) 90 | 91 | (define-maybe boolean) 92 | 93 | (define cidr4? (@@ (gnu services vpn) cidr4?)) 94 | 95 | (define serialize-cidr4 serialize-field) 96 | 97 | (define-maybe cidr4) 98 | 99 | (define (randomization-method? val) 100 | (memv val '(#f once network))) 101 | 102 | (define (serialize-randomization-method field-name val) 103 | (serialize-field field-name (or val 'disabled))) 104 | 105 | (define-maybe randomization-method) 106 | 107 | (define (randomization-range? val) 108 | (memv val '(full nic))) 109 | 110 | (define serialize-randomization-range serialize-field) 111 | 112 | (define-maybe randomization-range) 113 | 114 | (define (signal-strength? val) 115 | (and (number? val) 116 | (>= val -100) 117 | (<= val 1))) 118 | 119 | (define serialize-signal-strength serialize-field) 120 | 121 | (define-maybe signal-strength) 122 | 123 | (define (seconds? val) 124 | (and (integer? val) 125 | (not (negative? val)))) 126 | 127 | (define serialize-seconds serialize-field) 128 | 129 | (define-maybe seconds) 130 | 131 | (define (protection-mode? val) 132 | (memv val '(0 1 2))) 133 | 134 | (define serialize-protection-mode serialize-field) 135 | 136 | (define-maybe protection-mode) 137 | 138 | (define (resolution-method? val) 139 | (memv val '(#f resolvconf))) 140 | 141 | (define (serialize-resolution-method field-name val) 142 | (serialize-field field-name (or val 'none))) 143 | 144 | (define serialize-integer serialize-field) 145 | 146 | (define-maybe integer) 147 | 148 | (define serialize-number serialize-field) 149 | 150 | (define-maybe number) 151 | 152 | (define (serialize-list-of-strings field-name val) 153 | (serialize-field field-name (string-join val ","))) 154 | 155 | (define-maybe list-of-strings) 156 | 157 | (define list-of-cidr4? (list-of cidr4?)) 158 | 159 | (define serialize-list-of-cidr4 serialize-list-of-strings) 160 | 161 | (define-maybe list-of-cidr4) 162 | 163 | (define-configuration iwd-configuration 164 | (iwd 165 | (file-like iwd) 166 | "The iwd package to use.") 167 | 168 | (log-file 169 | (string "/var/log/iwd.log") 170 | "Log file location.") 171 | 172 | ;; General 173 | (enable-network-configuration? 174 | (boolean #f) 175 | "Enable network configuration.") 176 | 177 | (use-default-interface? 178 | maybe-boolean 179 | "Do not allow iwd to destroy / recreate wireless interfaces at startup, 180 | including default interfaces.") 181 | 182 | (address-randomization 183 | maybe-randomization-method 184 | "Available values are @code{#f}, @code{once} and @code{network}. @code{#f} 185 | for default kernel behavior, @code{once} to randomize the MAC address when iwd 186 | starts or the hardware is detected for the first time, @code{network} to 187 | randomize the MAC address on each connection to a network (the MAC address is 188 | generated based on the SSID and permanent address of the adapter).") 189 | 190 | (address-randomization-range 191 | maybe-randomization-range 192 | "Available values are @code{nic} and @code{full}. @code{nic} to only 193 | randomize the NIC specific octets (last 3 ones), @code{full} to randomize all 194 | 6 octets of the address.") 195 | 196 | (roam-threshold 197 | maybe-signal-strength 198 | "Value in dBm, control how aggressively iwd roams when connected to a 2.4Ghz 199 | access point.") 200 | 201 | (roam-threshold-5g 202 | maybe-signal-strength 203 | "Value in dBm, control how aggressively iwd roams when connected to a 5Ghz 204 | access point.") 205 | 206 | (roam-retry-interval 207 | maybe-seconds 208 | "How long to wait before attempting to roam again if the last roam attempt 209 | failed, or if the signal of the newly connected BSS is still considered weak.") 210 | 211 | (management-frame-protection 212 | maybe-protection-mode 213 | "Available values are @code{0}, @code{1} and @code{2}. @code{0} to 214 | completely turn off MFP (even if the hardware is capable), @code{1} to enable 215 | MFP if the local hardware and remote AP both support it, @code{2} to always 216 | require MFP.") 217 | 218 | (control-port-over-nl80211? 219 | maybe-boolean 220 | "Enable sending EAPoL packets over NL80211.") 221 | 222 | (disable-anqp? 223 | maybe-boolean 224 | "Disable ANQP queries.") 225 | 226 | (disable-ocv? 227 | maybe-boolean 228 | "Disable Operating Channel Validation.") 229 | 230 | (country 231 | maybe-string 232 | "ISO Alpha-2 Country Code. Request the country to be set for the system.") 233 | 234 | ;; Network 235 | (enable-ipv6? 236 | maybe-boolean 237 | "Configure IPv6 addresses and routes.") 238 | 239 | (name-resolving-service 240 | (resolution-method 'resolvconf) 241 | "Available values are @code{resolvconf} and @code{#f}. Configure a DNS 242 | resolution method used by the system and must be used in conjunction with 243 | @code{enable-network-configuration?}. @code{#f} to ignore DNS and domain name 244 | information.") 245 | 246 | (route-priority-offset 247 | maybe-integer 248 | "Configure a route priority offset used by the system to prioritize the 249 | default routes. The route with lower priority offset is preferred.") 250 | 251 | ;; Blacklist 252 | (initial-timeout 253 | maybe-seconds 254 | "The initial time that a BSS spends on the blacklist.") 255 | 256 | (multiplier 257 | maybe-integer 258 | "If the BSS was blacklisted previously and another connection attempt has 259 | failed after the initial timeout has expired, then the BSS blacklist time will 260 | be extended by a multiple of @code{multiplier} for each unsuccessful attempt up 261 | to @code{maximum-timeout} time.") 262 | 263 | (maximum-timeout 264 | maybe-seconds 265 | "Maximum time that a BSS is blacklisted.") 266 | 267 | ;; Rank 268 | (band-modifier-5ghz 269 | maybe-number 270 | "Increase or decrease the preference for 5GHz access points by increasing or 271 | decreasing the value of this modifier.") 272 | 273 | (band-modifier-6ghz 274 | maybe-number 275 | "Increase or decrease the preference for 6GHz access points by increasing or 276 | decreasing the value of this modifier.") 277 | 278 | ;; Scan 279 | (disable-periodic-scan? 280 | maybe-boolean 281 | "Disable periodic scan.") 282 | 283 | (initial-periodic-scan-interval 284 | maybe-seconds 285 | "The initial periodic scan interval upon disconnect.") 286 | 287 | (maximum-periodic-scan-interval 288 | maybe-seconds 289 | "The maximum periodic scan interval.") 290 | 291 | (disable-roaming-scan? 292 | maybe-boolean 293 | "Disable roaming scan.") 294 | 295 | ;; IPv4 296 | (ap-address-pool 297 | maybe-list-of-cidr4 298 | "Define the space of IPs used for the AP mode subnet addresses and the DHCP 299 | server.") 300 | 301 | ;; DriverQuirks 302 | (default-interface 303 | maybe-list-of-strings 304 | "List of drivers or glob matches. If a driver in use matches one in this 305 | list, IWD will not attempt to remove and re-create the default interface.") 306 | 307 | (force-pae 308 | maybe-list-of-strings 309 | "List of drivers or glob matches. If a driver in use matches one in this 310 | list, @code{control-port-over-nl80211?} will not be used, and PAE will be used 311 | instead.") 312 | 313 | (power-save-disable 314 | maybe-list-of-strings 315 | "List of drivers or glob matches. If a driver in use matches one in this 316 | list, power save will be disabled.")) 317 | 318 | (define (serialize-iwd-configuration config) 319 | (apply mixed-text-file "main.conf" 320 | (append-map 321 | (match-lambda 322 | ((section . fields) 323 | (list "[" section "]\n" 324 | (serialize-configuration 325 | config 326 | (filter-configuration-fields 327 | iwd-configuration-fields 328 | fields))))) 329 | `(("General" . ,%iwd-config-general) 330 | ("Network" . ,%iwd-config-network) 331 | ("Blacklist" . ,%iwd-config-blacklist) 332 | ("Rank" . ,%iwd-config-rank) 333 | ("Scan" . ,%iwd-config-scan) 334 | ("IPv4" . ,%iwd-config-ipv4) 335 | ("DriverQuirks" . ,%iwd-config-driver-quirks))))) 336 | 337 | (define (add-iwd-config-file config) 338 | `(("iwd/main.conf" 339 | ,(serialize-iwd-configuration config)))) 340 | 341 | (define add-iwd-package 342 | (compose list iwd-configuration-iwd)) 343 | 344 | (define (iwd-shepherd-service config) 345 | (match-record config 346 | (iwd log-file 347 | enable-network-configuration? name-resolving-service) 348 | (let ((conf (serialize-iwd-configuration config))) 349 | (list (shepherd-service 350 | (documentation "Run iwd") 351 | (provision `(,@(if enable-network-configuration? 352 | '(networking) 353 | '()) 354 | iwd)) 355 | (requirement '(user-processes dbus-system)) 356 | (start #~(make-forkexec-constructor 357 | (list (string-append #$iwd "/libexec/iwd")) 358 | #:log-file #$log-file)) 359 | (stop #~(make-kill-destructor)) 360 | (actions 361 | (list (shepherd-configuration-action "/etc/iwd/main.conf")))))))) 362 | 363 | (define iwd-service-type 364 | (service-type 365 | (name 'iwd) 366 | (extensions 367 | (list (service-extension shepherd-root-service-type 368 | iwd-shepherd-service) 369 | (service-extension dbus-root-service-type 370 | add-iwd-package) 371 | (service-extension etc-service-type 372 | add-iwd-config-file) 373 | (service-extension profile-service-type 374 | add-iwd-package) 375 | (service-extension log-rotation-service-type 376 | (compose list iwd-configuration-log-file)))) 377 | (default-value (iwd-configuration)) 378 | (description "Run iwd, the iNet wireless daemon."))) 379 | 380 | 381 | ;; 382 | ;; Tailscale 383 | ;; 384 | 385 | 386 | (define-configuration tailscale-configuration 387 | (tailscale 388 | (file-like tailscale) 389 | "The tailscale package to use.") 390 | 391 | (iptables 392 | (file-like iptables-nft) 393 | "The iptables package to use.") 394 | 395 | (log-file 396 | (string "/var/log/tailscaled.log") 397 | "Path to log file.") 398 | 399 | (socket 400 | (string "/var/run/tailscale/tailscaled.sock") 401 | "Path of the service UNIX socket.") 402 | 403 | (state-directory 404 | (string "/var/lib/tailscale") 405 | "Path to directory for storage of config state, TLS certs, temporary incoming 406 | Taildrop files, etc. If empty, it's derived from @code{state-file} when 407 | possible.") 408 | 409 | (upload-log? 410 | (boolean #f) 411 | "Whether to upload logs or not, technical support is also disabled when set 412 | to #f.") 413 | 414 | (verbosity 415 | (integer 0) 416 | "Log verbosity level; 0 is default, 1 or higher are increasingly verbose.") 417 | 418 | (extra-options 419 | (list-of-strings '()) 420 | "List of extra options.") 421 | (no-serialization)) 422 | 423 | (define tailscale-shepherd-service 424 | (match-record-lambda 425 | (tailscale iptables log-file socket state-directory 426 | upload-log? verbosity extra-options) 427 | (let ((environment 428 | #~(list (string-append "PATH=" 429 | (string-join 430 | '(#$(file-append iptables "/sbin") 431 | #$(file-append iproute "/sbin")) 432 | ":"))))) 433 | (list (shepherd-service 434 | (documentation "Run tailscaled") 435 | (provision '(tailscaled)) 436 | (requirement '(user-processes)) 437 | (start 438 | #~(make-forkexec-constructor 439 | (list 440 | #$(file-append tailscale "/bin/tailscaled") 441 | #$@(if upload-log? 442 | '() 443 | '("-no-logs-no-support")) 444 | "-socket" #$socket 445 | "-statedir" #$state-directory 446 | "-verbose" #$(number->string verbosity) 447 | #$@extra-options) 448 | #:environment-variables #$environment 449 | #:log-file #$log-file)) 450 | (stop #~(make-kill-destructor))))))) 451 | 452 | (define tailscale-service-type 453 | (service-type 454 | (name 'tailscaled) 455 | (extensions 456 | (list (service-extension shepherd-root-service-type 457 | tailscale-shepherd-service) 458 | (service-extension profile-service-type 459 | (compose list tailscale-configuration-tailscale)) 460 | (service-extension log-rotation-service-type 461 | (compose list tailscale-configuration-log-file)))) 462 | (default-value (tailscale-configuration)) 463 | (description "Run tailscaled."))) 464 | -------------------------------------------------------------------------------- /modules/rosenthal/services/web.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2024 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal services web) 6 | #:use-module (guix gexp) 7 | #:use-module (guix modules) 8 | #:use-module (guix records) 9 | #:use-module (gnu packages admin) 10 | #:use-module (gnu packages version-control) 11 | #:use-module (gnu packages video) 12 | #:use-module (rosenthal packages binaries) 13 | #:use-module (rosenthal packages web) 14 | #:use-module (gnu services) 15 | #:use-module (gnu services admin) 16 | #:use-module (gnu services configuration) 17 | #:use-module (gnu services databases) 18 | #:use-module (gnu services docker) 19 | #:use-module (gnu services shepherd) 20 | #:use-module (gnu system privilege) 21 | #:use-module (gnu system shadow) 22 | #:use-module (rosenthal utils serializers yaml) 23 | #:export (caddy-configuration 24 | caddy-service-type 25 | 26 | forgejo-configuration 27 | forgejo-service-type 28 | 29 | jellyfin-configuration 30 | jellyfin-service-type 31 | 32 | komga-configuration 33 | komga-service-type 34 | 35 | misskey-configuration 36 | misskey-service-type 37 | 38 | navidrome-configuration 39 | navidrome-service-type 40 | 41 | vaultwarden-configuration 42 | vaultwarden-service-type)) 43 | 44 | ;;; 45 | ;;; Caddy 46 | ;;; 47 | 48 | (define-configuration/no-serialization caddy-configuration 49 | (caddy 50 | (file-like caddy) 51 | "") 52 | (caddyfile 53 | file-like 54 | "")) 55 | 56 | (define (caddy-accounts config) 57 | (list (user-group (name "caddy") (system? #t)) 58 | (user-account 59 | (name "caddy") 60 | (group "caddy") 61 | (system? #t) 62 | (comment "Caddy user") 63 | (home-directory "/var/lib/caddy")))) 64 | 65 | (define caddy-privileged-programs 66 | (match-record-lambda 67 | (caddy) 68 | (list (privileged-program 69 | (program (file-append caddy "/bin/caddy")) 70 | (capabilities "cap_net_bind_service=+ep"))))) 71 | 72 | (define caddy-activation 73 | (match-record-lambda 74 | (caddyfile) 75 | (with-imported-modules 76 | (source-module-closure '((guix build utils) 77 | (gnu build activation))) 78 | #~(begin 79 | (use-modules (srfi srfi-26) 80 | (guix build utils) 81 | (gnu build activation)) 82 | (let* ((config-dir "/etc/caddy") 83 | (data-dir "/var/lib/caddy") 84 | (config-file (in-vicinity config-dir "Caddyfile")) 85 | (user (getpwnam "caddy"))) 86 | (for-each (cut mkdir-p/perms <> user #o750) 87 | (list config-dir data-dir)) 88 | (copy-file #$caddyfile config-file) 89 | (for-each 90 | (lambda (file) 91 | (chown file (passwd:uid user) (passwd:gid user))) 92 | (find-files data-dir #:directories? #t))))))) 93 | 94 | (define (caddy-shepherd-services config) 95 | (list (shepherd-service 96 | (provision '(caddy)) 97 | (requirement '(user-processes loopback)) 98 | (start 99 | #~(make-forkexec-constructor 100 | (list "/run/privileged/bin/caddy" "run" 101 | "--environ" "--config" "/etc/caddy/Caddyfile") 102 | #:user "caddy" 103 | #:group "caddy" 104 | #:directory "/var/lib/caddy" 105 | #:log-file "/var/log/caddy.log" 106 | #:resource-limits '((nofile 1048576 1048576)) 107 | #:environment-variables '("HOME=/var/lib/caddy"))) 108 | (stop 109 | #~(make-kill-destructor))))) 110 | 111 | (define caddy-service-type 112 | (service-type 113 | (name 'caddy) 114 | (extensions 115 | (list (service-extension account-service-type 116 | caddy-accounts) 117 | (service-extension privileged-program-service-type 118 | caddy-privileged-programs) 119 | (service-extension activation-service-type 120 | caddy-activation) 121 | (service-extension shepherd-root-service-type 122 | caddy-shepherd-services))) 123 | (default-value #f) 124 | (description ""))) 125 | 126 | 127 | 128 | ;; 129 | ;; Forgejo 130 | ;; 131 | 132 | 133 | (define (file-object? val) 134 | (or (string? val) 135 | (file-like? val))) 136 | 137 | (define list-of-file-likes? 138 | (list-of file-like?)) 139 | 140 | (define-configuration forgejo-configuration 141 | (forgejo 142 | (file-like forgejo) 143 | "Package to provide @file{/bin/forgejo}.") 144 | (git-packages 145 | (list-of-file-likes (list git git-lfs)) 146 | "@code{git} and extension packages to install.") 147 | (config-file 148 | (file-object "/var/lib/forgejo/app.ini") 149 | "Filesystem path or file-like object of Forgejo configuration, 150 | @file{app.ini}.") 151 | (no-serialization)) 152 | 153 | (define %forgejo-accounts 154 | (list (user-group (name "forgejo") (system? #t)) 155 | (user-account 156 | (name "forgejo") 157 | (group "forgejo") 158 | (system? #t) 159 | (comment "Forgejo user") 160 | (home-directory "/var/lib/forgejo")))) 161 | 162 | (define %forgejo-postgresql-role 163 | (list (postgresql-role 164 | (name "forgejo") 165 | (create-database? #t)))) 166 | 167 | (define forgejo-activation 168 | #~(begin 169 | (use-modules (guix build utils)) 170 | (let ((dir "/var/lib/forgejo") 171 | (user (getpwnam "forgejo"))) 172 | (mkdir-p dir) 173 | (chown dir (passwd:uid user) (passwd:gid user)) 174 | (chmod dir #o750)))) 175 | 176 | (define forgejo-shepherd-service 177 | (match-record-lambda 178 | (forgejo config-file) 179 | (list (shepherd-service 180 | (documentation "Run Forgejo.") 181 | (provision '(forgejo)) 182 | (requirement '(loopback postgresql)) 183 | (start 184 | #~(make-forkexec-constructor 185 | (list #$(file-append forgejo "/bin/forgejo") 186 | "--config" #$config-file) 187 | #:user "forgejo" 188 | #:group "forgejo" 189 | #:log-file "/var/log/forgejo.log" 190 | #:environment-variables 191 | '("GIT_EXEC_PATH=/run/current-system/profile/libexec/git-core" 192 | "GIT_SSL_CAINFO=/run/current-system/profile/etc/ssl/certs/ca-certificates.crt" 193 | "HOME=/var/lib/forgejo" 194 | "PATH=/run/current-system/profile/bin" 195 | "SSL_CERT_DIR=/run/current-system/profile/etc/ssl/certs" 196 | "SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt") 197 | #:resource-limits '((nofile 524288 524288)))) 198 | (stop 199 | #~(make-kill-destructor)) 200 | (actions 201 | (list (shepherd-configuration-action config-file))))))) 202 | 203 | (define forgejo-service-type 204 | (service-type 205 | (name 'forgejo) 206 | (extensions 207 | (list (service-extension account-service-type 208 | (const %forgejo-accounts)) 209 | (service-extension postgresql-role-service-type 210 | (const %forgejo-postgresql-role)) 211 | (service-extension profile-service-type 212 | forgejo-configuration-git-packages) 213 | (service-extension activation-service-type 214 | (const forgejo-activation)) 215 | (service-extension shepherd-root-service-type 216 | forgejo-shepherd-service))) 217 | (default-value (forgejo-configuration)) 218 | (description "Run Forgejo."))) 219 | 220 | 221 | ;; 222 | ;; Jellyfin 223 | ;; 224 | 225 | 226 | (define-maybe string) 227 | 228 | (define-configuration jellyfin-configuration 229 | (cache-directory 230 | (string "/var/cache/jellyfin") 231 | "Path to cache directory.") 232 | (config-directory 233 | (string "/var/lib/jellyfin") 234 | "Path to configuration directory.") 235 | (proxy-url 236 | maybe-string 237 | "Proxy URL.") 238 | (log-file 239 | (string "/var/log/jellyfin.log") 240 | "Path to log file.") 241 | (auto-start? 242 | (boolean #t) 243 | "Whether to start automatically.") 244 | (extra-options 245 | (list '()) 246 | "List of extra options.") 247 | (no-serialization)) 248 | 249 | (define %jellyfin-accounts 250 | (list (user-account 251 | (name "jellyfin") 252 | (group "docker") 253 | (system? #t) 254 | (home-directory "/var/empty") 255 | (shell (file-append shadow "/sbin/nologin"))))) 256 | 257 | (define jellyfin-activation 258 | (match-record-lambda 259 | (cache-directory config-directory) 260 | #~(let ((user (getpwnam "jellyfin"))) 261 | (for-each 262 | (lambda (directory) 263 | (unless (file-exists? directory) 264 | (mkdir-p directory) 265 | (chown directory (passwd:uid user) (passwd:gid user)))) 266 | '#$(list cache-directory config-directory))))) 267 | 268 | (define jellyfin-oci-containers 269 | (match-record-lambda 270 | (cache-directory config-directory 271 | proxy-url log-file auto-start? extra-options) 272 | (list (oci-container-configuration 273 | (user "jellyfin") 274 | (group "docker") 275 | (environment 276 | (if (maybe-value-set? proxy-url) 277 | `(("http_proxy" . ,proxy-url) 278 | ("https_proxy" . ,proxy-url)) 279 | '())) 280 | (image "jellyfin/jellyfin:latest") 281 | (provision "jellyfin") 282 | (log-file log-file) 283 | (auto-start? auto-start?) 284 | (respawn? #t) 285 | (network "host") 286 | (volumes 287 | `((,cache-directory . "/cache") 288 | (,config-directory . "/config"))) 289 | (extra-arguments extra-options))))) 290 | 291 | (define jellyfin-service-type 292 | (service-type 293 | (name 'jellyfin) 294 | (extensions 295 | (list (service-extension account-service-type 296 | (const %jellyfin-accounts)) 297 | (service-extension activation-service-type 298 | jellyfin-activation) 299 | (service-extension log-rotation-service-type 300 | (compose list jellyfin-configuration-log-file)) 301 | (service-extension oci-container-service-type 302 | jellyfin-oci-containers))) 303 | (default-value (jellyfin-configuration)) 304 | (description "Run Jellyfin, a media system."))) 305 | 306 | 307 | ;;; 308 | ;;; Komga 309 | ;;; 310 | 311 | 312 | (define-configuration komga-configuration 313 | (komga 314 | (file-like komga-bin) 315 | "Package to provide @file{/bin/komga}.") 316 | (port 317 | (integer 25600) 318 | "Port to listen to for the API and web interface.") 319 | (auto-start? 320 | (boolean #t) 321 | "Whether to start automatically.") 322 | (no-serialization)) 323 | 324 | (define %komga-accounts 325 | (list (user-group (name "komga") (system? #t)) 326 | (user-account 327 | (name "komga") 328 | (group "komga") 329 | (system? #t) 330 | (comment "Komga user") 331 | (home-directory "/var/lib/komga")))) 332 | 333 | (define komga-shepherd-service 334 | (match-record-lambda 335 | (komga port auto-start?) 336 | (list (shepherd-service 337 | (documentation "Run Komga.") 338 | (provision '(komga)) 339 | (requirement '(loopback)) 340 | (start 341 | #~(make-forkexec-constructor 342 | (list #$(file-append komga "/bin/komga")) 343 | #:user "komga" 344 | #:group "komga" 345 | #:log-file "/var/log/komga.log" 346 | #:environment-variables 347 | '("KOMGA_CONFIGDIR=/var/lib/komga" 348 | #$(string-append "SERVER_PORT=" (number->string port))))) 349 | (stop 350 | #~(make-kill-destructor)) 351 | (auto-start? auto-start?))))) 352 | 353 | (define komga-service-type 354 | (service-type 355 | (name 'komga) 356 | (extensions 357 | (list (service-extension account-service-type 358 | (const %komga-accounts)) 359 | (service-extension shepherd-root-service-type 360 | komga-shepherd-service))) 361 | (default-value (komga-configuration)) 362 | (description "Run Komga."))) 363 | 364 | 365 | ;; 366 | ;; Misskey 367 | ;; 368 | 369 | 370 | (define-configuration misskey-configuration 371 | (image 372 | (string "misskey/misskey:latest") 373 | "Misskey docker image to use.") 374 | (config 375 | (yaml-config '()) 376 | "Alist of Misskey configuration, to be serialized to YAML format.") 377 | (data-directory 378 | (string "/var/lib/misskey") 379 | "Directory to store @file{files} in.") 380 | (log-file 381 | (string "/var/log/misskey.log") 382 | "Log file to use.") 383 | (no-serialization)) 384 | 385 | (define %misskey-accounts 386 | (list (user-account 387 | (name "misskey") 388 | (group "docker") 389 | (system? #t) 390 | (home-directory "/var/empty") 391 | (shell (file-append shadow "/sbin/nologin"))))) 392 | 393 | (define %misskey-postgresql-role 394 | (list (postgresql-role 395 | (name "misskey") 396 | (create-database? #t)))) 397 | 398 | (define misskey-activation 399 | (match-record-lambda 400 | (data-directory) 401 | #~(begin 402 | (use-modules (guix build utils)) 403 | (let ((user (getpwnam "misskey"))) 404 | (unless (file-exists? #$data-directory) 405 | (mkdir-p #$data-directory) 406 | (chown #$data-directory (passwd:uid user) (passwd:gid user))))))) 407 | 408 | (define misskey-oci-containers 409 | (match-record-lambda 410 | (image config data-directory log-file ) 411 | (let ((config-file 412 | (mixed-text-file 413 | "misskey.yaml" 414 | #~(string-append #$@(yaml-serialize config) "\n")))) 415 | (list (oci-container-configuration 416 | (user "misskey") 417 | (group "docker") 418 | (image image) 419 | (provision "misskey") 420 | (requirement '(postgresql redis)) 421 | (log-file log-file) 422 | (respawn? #t) 423 | (network "host") 424 | (volumes 425 | `((,(string-append data-directory "/files") . "/misskey/files") 426 | (,config-file . "/misskey/.config/default.yml")))))))) 427 | 428 | (define misskey-service-type 429 | (service-type 430 | (name 'misskey) 431 | (extensions 432 | (list (service-extension account-service-type 433 | (const %misskey-accounts)) 434 | (service-extension postgresql-role-service-type 435 | (const %misskey-postgresql-role)) 436 | (service-extension log-rotation-service-type 437 | (compose list misskey-configuration-log-file)) 438 | (service-extension activation-service-type 439 | misskey-activation) 440 | (service-extension oci-container-service-type 441 | misskey-oci-containers))) 442 | (default-value (misskey-configuration)) 443 | (description "Run Misskey, an interplanetary microblogging platform."))) 444 | 445 | 446 | ;;; 447 | ;;; Navidrome 448 | ;;; 449 | 450 | 451 | (define-configuration navidrome-configuration 452 | (navidrome 453 | (file-like navidrome-bin) 454 | "") 455 | (ffmpeg 456 | (file-like ffmpeg) 457 | "") 458 | (auto-start? 459 | (boolean #t) 460 | "") 461 | (extra-config 462 | (string "") 463 | "") 464 | (no-serialization)) 465 | 466 | (define %navidrome-accounts 467 | (list (user-group (name "navidrome") (system? #t)) 468 | (user-account 469 | (name "navidrome") 470 | (group "navidrome") 471 | (system? #t) 472 | (comment "Navidrome user") 473 | (home-directory "/var/lib/navidrome")))) 474 | 475 | (define navidrome-shepherd-service 476 | (match-record-lambda 477 | (navidrome ffmpeg auto-start? extra-config) 478 | (let ((config-file 479 | (mixed-text-file 480 | "navidrome.toml" 481 | "DataFolder = '/var/lib/navidrome'\n" 482 | "CacheFolder = '/var/lib/navidrome/cache'\n" 483 | "EnableInsightsCollector = false\n" 484 | extra-config))) 485 | (list (shepherd-service 486 | (documentation "Run Navidrome.") 487 | (provision '(navidrome)) 488 | (requirement '(loopback user-processes)) 489 | (start 490 | #~(make-forkexec-constructor 491 | (list #$(file-append navidrome "/bin/navidrome") 492 | "--configfile" #$config-file) 493 | #:user "navidrome" 494 | #:group "navidrome" 495 | #:log-file "/var/log/navidrome.log" 496 | #:environment-variables 497 | (list "LC_ALL=C.UTF-8" 498 | (string-append "PATH=" #$ffmpeg "/bin")))) 499 | (stop 500 | #~(make-kill-destructor)) 501 | (auto-start? auto-start?) 502 | (actions 503 | (list (shepherd-configuration-action config-file)))))))) 504 | 505 | (define navidrome-service-type 506 | (service-type 507 | (name 'navidrome) 508 | (extensions 509 | (list (service-extension account-service-type 510 | (const %navidrome-accounts)) 511 | (service-extension shepherd-root-service-type 512 | navidrome-shepherd-service))) 513 | (default-value (navidrome-configuration)) 514 | (description "Run Navidrome."))) 515 | 516 | 517 | ;; 518 | ;; Vaultwarden 519 | ;; 520 | 521 | 522 | (define-configuration vaultwarden-configuration 523 | (admin-token 524 | maybe-string 525 | "Token for the admin interface, preferably an Argon2 PCH string.") 526 | (database-url 527 | (string "postgresql://user:password@host:port/database") 528 | "Database URL.") 529 | (port 530 | (integer 8000) 531 | "Port to listen on.") 532 | (data-directory 533 | (string "/var/lib/vaultwarden") 534 | "Main data folder.") 535 | (log-file 536 | (string "/var/log/vaultwarden.log") 537 | "Logging to this file.") 538 | (proxy-url 539 | maybe-string 540 | "Proxy URL to use.") 541 | (extra-options 542 | (alist '()) 543 | "Extra options.") 544 | (no-serialization)) 545 | 546 | (define %vaultwarden-accounts 547 | (list (user-account 548 | (name "vaultwarden") 549 | (group "docker") 550 | (system? #t) 551 | (home-directory "/var/empty") 552 | (shell (file-append shadow "/sbin/nologin"))))) 553 | 554 | (define %vaultwarden-postgresql-role 555 | (list (postgresql-role 556 | (name "vaultwarden") 557 | (create-database? #t)))) 558 | 559 | (define vaultwarden-activation 560 | (match-record-lambda 561 | (data-directory log-file) 562 | #~(begin 563 | (use-modules (guix build utils)) 564 | (let ((user (getpwnam "vaultwarden"))) 565 | (unless (file-exists? #$data-directory) 566 | (mkdir-p #$data-directory) 567 | (chown #$data-directory (passwd:uid user) (passwd:gid user))) 568 | (unless (file-exists? #$log-file) 569 | (mkdir-p (dirname #$log-file)) 570 | (call-with-output-file #$log-file 571 | (lambda (port) 572 | (write-char #\newline port))) 573 | (chown #$log-file (passwd:uid user) (passwd:gid user))))))) 574 | 575 | (define vaultwarden-oci-containers 576 | (match-record-lambda 577 | (admin-token database-url port data-directory log-file proxy-url extra-options) 578 | (list (oci-container-configuration 579 | (user "vaultwarden") 580 | (group "docker") 581 | (host-environment 582 | `(,@(if (maybe-value-set? admin-token) 583 | `(("ADMIN_TOKEN" . ,admin-token)) 584 | '()) 585 | ("DATABASE_URL" . ,database-url))) 586 | (environment 587 | `(,@(if (maybe-value-set? proxy-url) 588 | `(("HTTP_PROXY" . ,proxy-url)) 589 | '()) 590 | ("LOG_FILE" . "vaultwarden.log") 591 | ("ROCKET_PORT" . ,(number->string port)) 592 | ("USE_SYSLOG" . "True") 593 | ,@extra-options)) 594 | (image "vaultwarden/server:latest-alpine") 595 | (provision "vaultwarden") 596 | (requirement '(postgresql)) 597 | (respawn? #t) 598 | (network "host") 599 | (volumes 600 | `((,data-directory . "/data") 601 | (,log-file . "/vaultwarden.log"))) 602 | (extra-arguments 603 | `(,@(if (maybe-value-set? admin-token) 604 | '("--env" "ADMIN_TOKEN") 605 | '()) 606 | "--env" "DATABASE_URL")))))) 607 | 608 | (define vaultwarden-service-type 609 | (service-type 610 | (name 'vaultwarden) 611 | (extensions 612 | (list (service-extension account-service-type 613 | (const %vaultwarden-accounts)) 614 | (service-extension postgresql-role-service-type 615 | (const %vaultwarden-postgresql-role)) 616 | (service-extension activation-service-type 617 | vaultwarden-activation) 618 | (service-extension log-rotation-service-type 619 | (compose list vaultwarden-configuration-log-file)) 620 | (service-extension oci-container-service-type 621 | vaultwarden-oci-containers))) 622 | (default-value (vaultwarden-configuration)) 623 | (description "Run Vaultwarden, a Bitwarden compatible server."))) 624 | -------------------------------------------------------------------------------- /modules/rosenthal/utils/cargo.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;;; 3 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal utils cargo) 6 | #:use-module (guix diagnostics) 7 | #:use-module (guix i18n) 8 | #:export (rosenthal-cargo-inputs)) 9 | 10 | (define* (rosenthal-cargo-inputs name #:key (module '(rosenthal packages rust-crates))) 11 | "Lookup Cargo inputs for NAME defined in MODULE, return an empty list if 12 | unavailable." 13 | (let ((lookup (module-ref (resolve-interface module) 'lookup-cargo-inputs))) 14 | (or (lookup name) 15 | (begin 16 | (warning (G_ "no Cargo inputs available for '~a'~%") name) 17 | '())))) 18 | -------------------------------------------------------------------------------- /modules/rosenthal/utils/download.scm: -------------------------------------------------------------------------------- 1 | ;; SPDX-FileCopyrightText: 2025 Hilton Chain 2 | ;; 3 | ;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal utils download) 6 | #:use-module (guix gexp) 7 | #:use-module (guix packages) 8 | #:use-module (guix build-system gnu) 9 | #:export (go-mod-vendor)) 10 | 11 | ;;; 12 | ;;; ‘go mod vendor’ based fetcher 13 | ;;; 14 | 15 | (define* (go-mod-vendor #:key go) 16 | (lambda* (src hash-algo hash #:optional name #:key (system (%current-system))) 17 | (define nss-certs 18 | (module-ref (resolve-interface '(gnu packages certs)) 'nss-certs)) 19 | 20 | (gexp->derivation 21 | (or name "vendored-go-dependencies") 22 | (with-imported-modules %default-gnu-imported-modules 23 | #~(begin 24 | (use-modules (guix build gnu-build-system) 25 | (guix build utils)) 26 | ;; Support Unicode in file name. 27 | (setlocale LC_ALL "C.UTF-8") 28 | ;; For HTTPS support. 29 | (setenv "SSL_CERT_DIR" #+(file-append nss-certs "/etc/ssl/certs")) 30 | 31 | ((assoc-ref %standard-phases 'unpack) #:source #+src) 32 | (invoke #+(file-append go "/bin/go") "mod" "vendor") 33 | (copy-recursively "vendor" #$output))) 34 | #:system system 35 | #:hash-algo hash-algo 36 | #:hash hash 37 | ;; Is a directory. 38 | #:recursive? #t 39 | #:env-vars '(("GOCACHE" . "/tmp/go-cache") 40 | ("GOPATH" . "/tmp/go")) 41 | ;; Honor the user's proxy and locale settings. 42 | #:leaked-env-vars '("GOPROXY" 43 | "http_proxy" "https_proxy" 44 | "LC_ALL" "LC_MESSAGES" "LANG" 45 | "COLUMNS") 46 | #:local-build? #t))) 47 | -------------------------------------------------------------------------------- /modules/rosenthal/utils/serializers.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-FileCopyrightText: Copyright © 2022 Andrew Tropin 2 | ;;; 3 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal utils serializers) 6 | #:use-module (gnu services configuration) 7 | #:use-module (guix gexp) 8 | #:use-module (srfi srfi-1) 9 | 10 | #:export (alist? 11 | 12 | path? 13 | serialize-path 14 | 15 | string-or-gexp? 16 | serialize-string-or-gexp 17 | 18 | gexp-text-config? 19 | serialize-gexp-text-config) 20 | #:re-export (interpose)) 21 | 22 | (define (alist? lst) 23 | (every pair? lst)) 24 | 25 | 26 | (define path? string?) 27 | (define (serialize-path field-name val) val) 28 | 29 | (define (string-or-gexp? sg) (or (string? sg) (gexp? sg))) 30 | (define (serialize-string-or-gexp field-name val) "") 31 | 32 | ;; Guix proper has a different version of text-config. 33 | (define (gexp-text-config? config) 34 | (and (list? config) (every string-or-gexp? config))) 35 | (define (serialize-gexp-text-config field-name val) 36 | #~(string-append #$@(interpose val "\n" 'suffix))) 37 | -------------------------------------------------------------------------------- /modules/rosenthal/utils/serializers/ini.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-FileCopyrightText: Copyright © 2022 Andrew Tropin 2 | ;;; 3 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal utils serializers ini) 6 | #:use-module (ice-9 match) 7 | #:use-module (ice-9 format) 8 | #:use-module (srfi srfi-1) 9 | #:use-module (rosenthal utils serializers) 10 | #:use-module (guix packages) 11 | #:use-module (guix gexp) 12 | #:use-module (guix diagnostics) 13 | #:use-module (guix ui) 14 | 15 | #:export (ini-serialize 16 | ini-print 17 | ini-merge 18 | ini-append 19 | 20 | serialize-ini-config 21 | ini-config?)) 22 | 23 | (define ini-config? list?) 24 | 25 | (define sample-ini 26 | `((global ((daemon) 27 | (log . file))) 28 | (http ((host . 127.0.0.1) 29 | (port . 1234))))) 30 | 31 | (define (format-ini-section section) 32 | (match section 33 | ('global "") 34 | (name (format #f "[~a]\n" (symbol->string name))))) 35 | 36 | (define* (ini-serialize 37 | config 38 | #:key 39 | (equal-string " = ") 40 | (format-ini-section format-ini-section)) 41 | "For global properties use global section, the properties will be added to the 42 | beginning of the list before any section, this behavior can be adjusted with 43 | FORMAT-INI-SECTION argument. 44 | 45 | @lisp 46 | `((global ((daemon) 47 | (log . file))) 48 | (http ((host . 127.0.0.1) 49 | (port . 1234)))) 50 | @end lisp 51 | 52 | would yeld 53 | 54 | @example 55 | @end example 56 | " 57 | (define (serialize-ini-term term) 58 | (match term 59 | (#t "true") 60 | (#f "false") 61 | ((? symbol? e) (symbol->string e)) 62 | ((? number? e) (number->string e)) 63 | ((? string? e) (object->string e)) 64 | ((lst ...) 65 | (raise (formatted-message 66 | (G_ "INI term should be a non-list value (string, \ 67 | boolean, number, symbol, or gexp). Provided term is:\n ~a") lst))) 68 | (e e))) 69 | 70 | (define (serialize-ini-properties properties) 71 | (unless (alist? properties) 72 | (raise (formatted-message 73 | (G_ "INI properties should be an alist, \ 74 | but provided value is:\n ~a") properties))) 75 | (append-map 76 | (match-lambda 77 | ((? gexp? e) 78 | (list e "\n")) 79 | ((k) 80 | (list (serialize-ini-term k) equal-string "\n")) 81 | ((k . v) 82 | (list (serialize-ini-term k) equal-string 83 | (serialize-ini-term v) "\n"))) 84 | properties)) 85 | 86 | (define (serialize-ini-section section) 87 | (match section 88 | ((name properties) 89 | (append 90 | (list (format-ini-section name)) 91 | (serialize-ini-properties properties))) 92 | (e 93 | (raise (formatted-message 94 | (G_ "INI section should be a list containing a section name as \ 95 | the first element and alist of properties as the second, but provided value \ 96 | is:\n~a") e))))) 97 | 98 | ;; TODO: serialize global section before all other sections. 99 | (append-map 100 | (lambda (expr) 101 | (append 102 | (match expr 103 | ((? gexp? e) (list e)) 104 | (e (serialize-ini-section e))) 105 | (list "\n"))) 106 | config)) 107 | 108 | (define (ini-merge ini1 ini2) 109 | "Combine to INIs. Naive quadratic implementation, which can be rediculously 110 | slow." 111 | (define keys-to-merge 112 | (fold 113 | (match-lambda* 114 | (((k v) acc) (if (assoc-ref ini2 k) (cons k acc) acc)) 115 | (((? gexp? e) acc) acc)) 116 | '() ini1)) 117 | 118 | (define enriched-ini1 119 | (fold-right 120 | (match-lambda* 121 | (((k v) acc) 122 | (cons 123 | (cons k (list (append v (car (or (assoc-ref ini2 k) '(())))))) 124 | acc)) 125 | (((? gexp? e) acc) (cons e acc))) 126 | '() 127 | ini1)) 128 | 129 | (define stripped-ini2 130 | (remove (match-lambda 131 | ((k . v) (memq k keys-to-merge)) 132 | (e #f)) 133 | ini2)) 134 | (append enriched-ini1 stripped-ini2)) 135 | 136 | (define (ini-append x acc) 137 | (ini-merge acc x)) 138 | 139 | (define serialize-ini-config ini-serialize) 140 | ;; (display 141 | ;; (merge-ini 142 | ;; '((section1 ((k1 . v1))) 143 | ;; (section2 ((k4 . v4)))) 144 | ;; '((section1 ((k2 . v2) 145 | ;; (k3 . v3))) 146 | ;; (section3 ((k5 . v5)))))) 147 | 148 | ;; (cdr '(a ((k . v) (k2 . v2)))) 149 | 150 | (define (ini-print ini) 151 | "Prints generated INI, useful for debugging." 152 | (display (apply string-append (ini-serialize ini)))) 153 | -------------------------------------------------------------------------------- /modules/rosenthal/utils/serializers/yaml.scm: -------------------------------------------------------------------------------- 1 | ;;; SPDX-FileCopyrightText: Copyright © 2023 Miguel Ángel Moreno 2 | ;;; 3 | ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | (define-module (rosenthal utils serializers yaml) 6 | #:use-module (rosenthal utils serializers) 7 | #:use-module (gnu home services utils) 8 | #:use-module (gnu services configuration) 9 | #:use-module (guix diagnostics) 10 | #:use-module (guix gexp) 11 | #:use-module (guix ui) 12 | #:use-module (ice-9 match) 13 | #:use-module (ice-9 format) 14 | #:use-module (srfi srfi-1) 15 | #:use-module (srfi srfi-43) 16 | #:export (yaml-print 17 | yaml-config? 18 | yaml-serialize 19 | 20 | serialize-yaml-term 21 | serialize-yaml-element 22 | serialize-yaml-config)) 23 | 24 | (define yaml-config? list?) 25 | 26 | (define (yaml-term? t) 27 | (fold (lambda (x acc) (or acc (x t))) 28 | #f 29 | (list boolean? symbol? number? string? file-like? gexp?))) 30 | 31 | (define (serialize-yaml-string v) 32 | (format #f "~s" v)) 33 | 34 | (define (serialize-yaml-symbol v) 35 | (format #f "~a" v)) 36 | 37 | (define (serialize-yaml-term term) 38 | (match term 39 | ((? boolean? v) (if v "true" "false")) 40 | ((? number? v) (number->string v)) 41 | ((? string? v) (serialize-yaml-string v)) 42 | ((? symbol? v) (serialize-yaml-symbol v)) 43 | ((or (? gexp? v) 44 | (? file-like? v)) 45 | v) 46 | (v (raise (formatted-message 47 | (G_ "\ 48 | YAML term should be boolean, number, string, symbol, or gexp. Provided term 49 | is:\n ~a") v))))) 50 | 51 | (define (serialize-yaml-key k) 52 | (list 53 | (cond 54 | ((symbol? k) (serialize-yaml-symbol k)) 55 | ((string? k) (serialize-yaml-string k)) 56 | (else (raise (formatted-message 57 | (G_ "\ 58 | YAML key should be symbol or string. Provided key is:\n ~a") 59 | k)))))) 60 | 61 | (define (serialize-yaml-newline pretty?) 62 | (if pretty? (list "\n") '())) 63 | 64 | (define (serialize-yaml-space pretty?) 65 | (if pretty? (list " ") '())) 66 | 67 | (define (serialize-yaml-indentation level pretty?) 68 | (if pretty? 69 | (list (format #f "~v_" (- (* 2 level) 2))) 70 | '())) 71 | 72 | (define (serialize-yaml-vector v level pretty?) 73 | (append 74 | (serialize-yaml-newline pretty?) 75 | (vector-fold 76 | (lambda (i acc e) 77 | (append acc 78 | (if (> i 0) 79 | (serialize-yaml-newline pretty?) 80 | '()) 81 | (serialize-yaml-indentation (1+ level) pretty?) 82 | (list "- ") 83 | (match e 84 | ((? alist? e) 85 | (serialize-yaml-vector-alist e (+ 1 level) pretty?)) 86 | (_ (serialize-yaml-element e (1+ level) pretty?))))) 87 | '() v))) 88 | 89 | (define (serialize-yaml-list v pretty?) 90 | (append 91 | (list "[") 92 | (interpose 93 | (append-map 94 | (lambda (x) 95 | (serialize-yaml-element x 0 pretty?)) 96 | v) 97 | ", ") 98 | (list "]"))) 99 | 100 | (define (serialize-yaml-pair v level pretty?) 101 | (append 102 | (serialize-yaml-indentation level pretty?) 103 | (serialize-yaml-key (car v)) 104 | (list ":") 105 | (serialize-yaml-space pretty?) 106 | (if (alist? (cdr v)) 107 | (serialize-yaml-newline pretty?) 108 | (list "")) 109 | (serialize-yaml-element (cdr v) level pretty?))) 110 | 111 | (define (serialize-yaml-alist v level pretty?) 112 | (append 113 | (serialize-yaml-pair (car v) (1+ level) pretty?) 114 | (append-map 115 | (lambda (x) 116 | (append 117 | (serialize-yaml-newline pretty?) 118 | (serialize-yaml-pair x (1+ level) pretty?))) 119 | (cdr v)))) 120 | 121 | (define (serialize-yaml-vector-alist v level pretty?) 122 | (append 123 | (serialize-yaml-pair (car v) (- level (- level 1)) pretty?) 124 | (append-map 125 | (lambda (x) 126 | (append 127 | (serialize-yaml-newline pretty?) 128 | (serialize-yaml-pair x (1+ level) pretty?))) 129 | (cdr v)))) 130 | 131 | (define (serialize-yaml-element yaml level pretty?) 132 | (append 133 | (match yaml 134 | (() (list "")) 135 | ((? yaml-term? v) (list (serialize-yaml-term v))) 136 | ((? alist? v) (serialize-yaml-alist v level pretty?)) 137 | ((? list? v) (serialize-yaml-list v pretty?)) 138 | ((? vector? v) (serialize-yaml-vector v level pretty?)) 139 | (e (throw 'yaml-invalid yaml))))) 140 | 141 | (define (serialize-yaml-config f c) 142 | #~(apply string-append 143 | (list #$@(serialize-yaml-element c 0 #t)))) 144 | 145 | (define* (yaml-serialize config) 146 | "Returns a list of YAML strings which have to be concatenated. It supports 147 | gexps, file-likes, vectors -> arrays, alists -> dictionaries, etc." 148 | (serialize-yaml-config #f config)) 149 | 150 | (define* (yaml-print yaml #:key (pretty? #t)) 151 | "Prints the generated YAML, useful for debugging purposes." 152 | (display (apply string-append 153 | (serialize-yaml-element yaml 0 pretty?)))) 154 | --------------------------------------------------------------------------------