mirror of
https://codeberg.org/guix/guix.git
synced 2025-10-02 02:15:12 +00:00
Compare commits
16 commits
771659666d
...
da04b3bb42
Author | SHA1 | Date | |
---|---|---|---|
|
da04b3bb42 | ||
|
3b55a14377 | ||
|
f5d61ca686 | ||
|
bb2dacd811 | ||
|
3c422c6111 | ||
|
f2c9dabec8 | ||
|
abc35bae81 | ||
|
8a69897b7e | ||
|
8f7837e104 | ||
|
054aae7bb2 | ||
|
d411aff611 | ||
|
e1038aee6d | ||
|
55b39642e2 | ||
|
e10da6bff8 | ||
|
67f5f23c88 | ||
|
d4c1dc6df5 |
16 changed files with 576 additions and 31 deletions
|
@ -144,6 +144,7 @@ Copyright @copyright{} 2024 Evgeny Pisemsky@*
|
|||
Copyright @copyright{} 2025 jgart@*
|
||||
Copyright @copyright{} 2025 Artur Wroblewski@*
|
||||
Copyright @copyright{} 2025 Edouard Klein@*
|
||||
Copyright @copyright{} 2025 Rodion Goritskov@*
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
|
@ -35700,6 +35701,80 @@ The file which should store the logging output of Agate.
|
|||
@end table
|
||||
@end deftp
|
||||
|
||||
@subsubheading Miniflux
|
||||
|
||||
@cindex miniflux
|
||||
The @uref{https://miniflux.app/, Miniflux} is a minimalist RSS feed reader
|
||||
with a web interface.
|
||||
|
||||
Depending on the configuration, an initial administrator user can be pre-created
|
||||
on startup. To enable this, @code{create-admin?} should be set to @code{#t}, and
|
||||
both @code{admin-username-file} and @code{admin-password-file} should point to
|
||||
files containing the username and password, respectively. However, it is
|
||||
recommended to manually change the password to a secure one via the web
|
||||
UI after the initial service startup.
|
||||
|
||||
@defvar miniflux-service-type
|
||||
This is the type of the Miniflux service. Its value
|
||||
must be a @code{miniflux-configuration} record as in this example:
|
||||
|
||||
@lisp
|
||||
(service miniflux-service-type
|
||||
(miniflux-configuration
|
||||
(listen-address "0.0.0.0:8080")
|
||||
(base-url "http://my-news-source.test")
|
||||
(create-administrator-account? #t)
|
||||
(administrator-account-name "/var/miniflux/initial-admin-username")
|
||||
(administrator-account-password "/var/miniflux/initial-admin-password")))
|
||||
@end lisp
|
||||
|
||||
The details of the @code{miniflux-configuration} record type are given below.
|
||||
|
||||
@end defvar
|
||||
|
||||
@deftp {Data Type} miniflux-configuration
|
||||
Available @code{miniflux-configuration} fields are:
|
||||
|
||||
@table @asis
|
||||
@item @code{listen-address} (default: @code{"127.0.0.1:8080"}) (type: string)
|
||||
Address to listen on.
|
||||
Use absolute path like @code{"/var/run/miniflux/miniflux.sock"} for a Unix socket.
|
||||
|
||||
@item @code{base-url} (default: @code{"http://127.0.0.1/"}) (type: string)
|
||||
Base URL to generate HTML links and base path for cookies.
|
||||
|
||||
@item @code{create-administrator-account?} (default: @code{#f}) (type: boolean)
|
||||
Create an initial administrator account.
|
||||
|
||||
@item @code{administrator-account-name} (type: maybe-string-or-file-path)
|
||||
Initial administrator account name as a string or an absolute path
|
||||
to a file with an account name inside.
|
||||
|
||||
@item @code{administrator-account-password} (type: maybe-string-or-file-path)
|
||||
Initial administrator account password as a string or an absolute path
|
||||
to a file with a password inside.
|
||||
|
||||
@item @code{run-migrations?} (default: @code{#t}) (type: boolean)
|
||||
Run database migrations during application startup.
|
||||
|
||||
@item @code{database-url} (default: @code{"host=/var/run/postgresql"}) (type: string)
|
||||
PostgreSQL connection string.
|
||||
|
||||
@item @code{user} (default: @code{"miniflux"}) (type: string)
|
||||
User name for Postgresql and system account.
|
||||
|
||||
@item @code{group} (default: @code{"miniflux"}) (type: string)
|
||||
Group for the system account.
|
||||
|
||||
@item @code{log-file} (default: @code{"/var/log/miniflux.log"}) (type: string)
|
||||
Path to the log file.
|
||||
|
||||
@item @code{extra-settings} (type: maybe-list)
|
||||
Extra configuration parameters as a list of strings.
|
||||
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@node High Availability Services
|
||||
@subsection High Availability Services
|
||||
|
||||
|
|
|
@ -1058,8 +1058,8 @@ the \"texlive\" importer."
|
|||
(define-member (person "Ludovic Courtès"
|
||||
"ludo@gnu.org"
|
||||
"civodul")
|
||||
core home bootstrap core-packages installer
|
||||
documentation mentors)
|
||||
core core-packages hpc installer
|
||||
mentors)
|
||||
|
||||
(define-member (person "Andreas Enge"
|
||||
"andreas@enge.fr"
|
||||
|
|
|
@ -168,7 +168,7 @@
|
|||
(lambda (e)
|
||||
(or (member e
|
||||
'("no-warn" "whole-window" "border" "exclude-titlebar"
|
||||
"release" "locked" "inhibited" "no-repeat"))
|
||||
"release" "locked" "to-code" "inhibited" "no-repeat"))
|
||||
(string-prefix? "input-device=" e)))
|
||||
lst))
|
||||
|
||||
|
@ -177,7 +177,7 @@
|
|||
(lambda (e)
|
||||
(or (member e
|
||||
'("no-warn" "whole-window" "border" "exclude-titlebar"
|
||||
"release" "locked" "to-code" "inhibited" "no-repeat"))
|
||||
"release" "locked" "inhibited" "no-repeat"))
|
||||
(string-prefix? "input-device=" e)))
|
||||
lst))
|
||||
|
||||
|
|
|
@ -601,8 +601,13 @@ interface and is based on GNU Guile.")
|
|||
"/bin/gzip")
|
||||
(string-append "--with-zstd=" #$(this-package-input "zstd")
|
||||
"/bin/zstd")))))
|
||||
(inputs (modify-inputs (package-inputs shepherd-0.10)
|
||||
(append gzip zstd)))))
|
||||
(native-inputs
|
||||
(modify-inputs (package-native-inputs shepherd-0.10)
|
||||
(replace "guile-fibers" guile-fibers))) ;use latest guile-fibers available
|
||||
(inputs
|
||||
(modify-inputs (package-inputs shepherd-0.10)
|
||||
(replace "guile-fibers" guile-fibers) ;use latest guile-fibers available
|
||||
(append gzip zstd)))))
|
||||
|
||||
(define-public shepherd shepherd-0.10)
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ client.")
|
|||
python-docker-5
|
||||
python-dockerpty
|
||||
python-docopt
|
||||
python-dotenv
|
||||
python-dotenv-0.13.0
|
||||
python-jsonschema-3
|
||||
python-pyyaml
|
||||
python-requests
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2013, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2025 Andy Tai <atai@atai.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -20,19 +21,22 @@
|
|||
#:use-module (guix packages)
|
||||
#:use-module (guix download)
|
||||
#:use-module (guix build-system gnu)
|
||||
#:use-module (guix licenses))
|
||||
#:use-module (guix licenses)
|
||||
#:use-module (gnu packages check)
|
||||
#:use-module (gnu packages pkg-config))
|
||||
|
||||
|
||||
(define-public gcal
|
||||
(package
|
||||
(name "gcal")
|
||||
(version "4.1")
|
||||
(version "4.2.0")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "mirror://gnu/gcal/gcal-"
|
||||
(uri (string-append "https://www.alteholz.dev/gnu/gcal-"
|
||||
version ".tar.xz"))
|
||||
(sha256
|
||||
(base32
|
||||
"1av11zkfirbixn05hyq4xvilin0ncddfjqzc4zd9pviyp506rdci"))
|
||||
"1p3q6his31bxs24nsgpfavw3nlhalqf0zak4f3b530p725s2vgfq"))
|
||||
(modules '((guix build utils)))
|
||||
(snippet
|
||||
'(begin
|
||||
|
@ -50,6 +54,8 @@
|
|||
"/* BSD stdio derived implementations")))
|
||||
#t))))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs (list check pkg-config))
|
||||
(arguments `(#:configure-flags '("LDFLAGS=-lm")))
|
||||
(home-page "https://www.gnu.org/software/gcal/")
|
||||
(synopsis "Calculating and printing a wide variety of calendars")
|
||||
(description
|
||||
|
|
|
@ -1189,7 +1189,20 @@ is not available for Guile 2.0.")
|
|||
(base32
|
||||
"15ynxr3pfjscd6mz641zagv6i84jh9y65i5dnbb3j3q72j6bbvnb"))
|
||||
(patches '())))
|
||||
(arguments '())))
|
||||
(arguments
|
||||
(if (target-aarch64?)
|
||||
(list #:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-before 'check 'disable-jit
|
||||
(lambda _
|
||||
;; XXX: Due to a JIT bug in Guile 3.0.9 on AArch64,
|
||||
;; some tests would hang:
|
||||
;; <https://codeberg.org/fibers/fibers/issues/83>.
|
||||
;; Disable JIT for now; re-enable it when Guile 3.0.10+
|
||||
;; is used. (Note: The Shepherd disables JIT on
|
||||
;; AArch64 so it can safely use Fibers.)
|
||||
(setenv "GUILE_JIT_THRESHOLD" "-1")))))
|
||||
'()))))
|
||||
|
||||
(define-public guile-fibers guile-fibers-1.4)
|
||||
|
||||
|
|
|
@ -502,7 +502,7 @@ without requiring the source code to be rewritten.")
|
|||
;; The main goal here is to allow for '--with-branch'.
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://git.savannah.gnu.org/git/guile.git")
|
||||
(url "https://codeberg.org/guile/guile.git")
|
||||
(commit commit)))
|
||||
(file-name (git-file-name name version))
|
||||
(sha256
|
||||
|
|
|
@ -4353,16 +4353,16 @@ It is a replacement for the @command{urlview} program.")
|
|||
(define-public mumi
|
||||
(package
|
||||
(name "mumi")
|
||||
(version "0.13.0")
|
||||
(version "0.14.0")
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://git.savannah.gnu.org/git/guix/mumi.git/")
|
||||
(url "https://codeberg.org/guix/mumi.git")
|
||||
(commit version)))
|
||||
(file-name (git-file-name name version))
|
||||
(sha256
|
||||
(base32
|
||||
"04mcd1xkdpvxlvpf4k4mvnwi06sdy8vy1di6gxxsr9msgdb366ir"))))
|
||||
"1v5gjzh8idz926518c0bv0qsmyggr6lvqn5vksf5j0qdh6r6dar7"))))
|
||||
(build-system gnu-build-system)
|
||||
(arguments
|
||||
(list
|
||||
|
|
|
@ -1470,14 +1470,15 @@ Knuth’s LR(1) parser construction technique.")
|
|||
(wrap-program (string-append #$output "/bin/" "binsec")
|
||||
`("OCAMLPATH" ":" prefix ,ocamlpath))))))))
|
||||
(inputs (list bash-minimal))
|
||||
(native-inputs (list gmp ocaml-qcheck ocaml-ounit2))
|
||||
(native-inputs (list gmp ocaml-qcheck ocaml-ounit2 z3))
|
||||
(propagated-inputs (list dune-site
|
||||
ocaml-base
|
||||
ocaml-menhir
|
||||
ocaml-graph
|
||||
ocaml-zarith
|
||||
ocaml-grain-dypgen
|
||||
ocaml-toml))
|
||||
ocaml-toml
|
||||
ocaml-z3))
|
||||
(synopsis "Binary-level analysis platform")
|
||||
(description
|
||||
"BINSEC is a binary analysis platform which implements analysis
|
||||
|
|
|
@ -1931,7 +1931,7 @@ This package just includes the agent component.")))
|
|||
(define-public guix-jupyter
|
||||
(package
|
||||
(name "guix-jupyter")
|
||||
(version "0.3.0")
|
||||
(version "0.3.1")
|
||||
(home-page "https://codeberg.org/guix-science/guix-jupyter")
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
|
@ -1939,7 +1939,7 @@ This package just includes the agent component.")))
|
|||
(commit (string-append "v" version))))
|
||||
(sha256
|
||||
(base32
|
||||
"0cvjxv60la2bqmwb7m2bfpvjy8hx1hmjk2qy9wfzaffcabgr0x44"))
|
||||
"1yvrmaj4qcb9vn2nfjz1q0cil830hvmxpp8cgi76aylbnv36aask"))
|
||||
(file-name (string-append "guix-jupyter-" version "-checkout"))))
|
||||
(build-system gnu-build-system)
|
||||
(arguments
|
||||
|
|
|
@ -185,7 +185,7 @@ it.")
|
|||
(define-public trealla
|
||||
(package
|
||||
(name "trealla")
|
||||
(version "2.83.8")
|
||||
(version "2.83.9")
|
||||
(source
|
||||
(origin
|
||||
(method git-fetch)
|
||||
|
@ -194,7 +194,7 @@ it.")
|
|||
(url "https://github.com/trealla-prolog/trealla")
|
||||
(commit (string-append "v" version))))
|
||||
(sha256
|
||||
(base32 "1bpfzrwsgbmjl1maiaw5b8ixkgh548gw1lkiznsjgkjm7dxr4ns4"))
|
||||
(base32 "01gxml7g6qf185pa51v8vrsv1m42b3dz5rcnyqf7ic041s6p9bwl"))
|
||||
(file-name (git-file-name name version))))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs
|
||||
|
|
|
@ -5294,7 +5294,10 @@ WebSocket usage in Python programs.")
|
|||
(method url-fetch)
|
||||
(uri (pypi-uri "websocket-client" version))
|
||||
(sha256
|
||||
(base32 "0p0cz2mdissq7iw1n7jrmsfir0jfmgs1dvnpnrx477ffx9hbsxnk"))))))
|
||||
(base32 "0p0cz2mdissq7iw1n7jrmsfir0jfmgs1dvnpnrx477ffx9hbsxnk"))))
|
||||
(native-inputs
|
||||
(modify-inputs (package-native-inputs python-websocket-client)
|
||||
(append python-six)))))
|
||||
|
||||
(define-public python-purl
|
||||
(package
|
||||
|
|
|
@ -4809,6 +4809,31 @@ Unicode-to-LaTeX conversion.")
|
|||
@code{subprocess} feature.")
|
||||
(license license:expat)))
|
||||
|
||||
;; Old version just for python-dotenv-0.13.0 for docker-compose; remove once
|
||||
;; that is updated.
|
||||
(define-public python-sh-1
|
||||
(package
|
||||
(inherit python-sh)
|
||||
(version "1.14.2")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (pypi-uri "sh" version))
|
||||
(sha256
|
||||
(base32
|
||||
"03gyss1rhj4in7pgysg4q0hxp3230whinlpy1532ljs99lrx0ywx"))))
|
||||
;(build-system python-build-system)
|
||||
(arguments
|
||||
'(#:phases
|
||||
(modify-phases %standard-phases
|
||||
(replace 'check
|
||||
(lambda _
|
||||
;; XXX: A Python 2 test fails when HOME=/homeless-shelter.
|
||||
(setenv "HOME" "/tmp")
|
||||
(invoke "python" "sh.py" "test"))))))
|
||||
(native-inputs
|
||||
(list python-setuptools))))
|
||||
|
||||
(define-public python-cftime
|
||||
(package
|
||||
(name "python-cftime")
|
||||
|
@ -20156,18 +20181,22 @@ and dataclasses.")
|
|||
(define-public python-argparse-manpage
|
||||
(package
|
||||
(name "python-argparse-manpage")
|
||||
(version "4.5")
|
||||
(version "4.7")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (pypi-uri "argparse-manpage" version))
|
||||
(uri (pypi-uri "argparse_manpage" version))
|
||||
(sha256
|
||||
(base32
|
||||
"1nq4sq1zk1xzdsqq61hd27jhj978ys136aba1zjg02x1g0c0cg11"))))
|
||||
(base32 "0clb20scp408gxac675v731vnj89pk9d5fb7pcy7bj1a45mvgshx"))))
|
||||
(build-system pyproject-build-system)
|
||||
(arguments
|
||||
(list
|
||||
#:test-flags
|
||||
;; Tests require PIP.
|
||||
#~(list "--ignore=tests/test_examples.py")))
|
||||
(native-inputs
|
||||
(list python-pip python-pytest python-setuptools python-tomli
|
||||
python-wheel))
|
||||
(list python-pytest
|
||||
python-setuptools))
|
||||
(home-page "https://github.com/praiskup/argparse-manpage")
|
||||
(synopsis "Build manual page from Python's ArgumentParser object")
|
||||
(description
|
||||
|
@ -36879,6 +36908,35 @@ systems in Python.")
|
|||
key-value pairs from a @code{.env} file and set them as environment variables.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
;; Old version just for docker-compose; remove once that is updated.
|
||||
(define-public python-dotenv-0.13.0
|
||||
(package (inherit python-dotenv)
|
||||
(name "python-dotenv")
|
||||
(version "0.13.0")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (pypi-uri "python-dotenv" version))
|
||||
(sha256
|
||||
(base32
|
||||
"0x5dagmfn31phrbxlwacw3s4w5vibv8fxqc62nqcdvdhjsy0k69v"))))
|
||||
(arguments
|
||||
`(#:phases
|
||||
(modify-phases %standard-phases
|
||||
(replace 'check
|
||||
(lambda* (#:key tests? inputs outputs #:allow-other-keys)
|
||||
(when tests?
|
||||
(add-installed-pythonpath inputs outputs)
|
||||
(setenv "PATH" (string-append (getenv "PATH") ":"
|
||||
(assoc-ref outputs "out") "/bin"))
|
||||
;; Skip the ipython tests.
|
||||
(delete-file "tests/test_ipython.py")
|
||||
(invoke "python" "-m" "pytest")))))))
|
||||
(native-inputs
|
||||
(modify-inputs (package-native-inputs python-dotenv)
|
||||
(append python-mock)
|
||||
(replace "python-sh" python-sh-1)))))
|
||||
|
||||
(define-public date2name
|
||||
(let ((commit "6c8f37277e8ec82aa50f90b8921422be30c4e798")
|
||||
(revision "1"))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
;;; Copyright © 2023 Miguel Ángel Moreno <mail@migalmoreno.com>
|
||||
;;; Copyright © 2024 Leo Nikkilä <hello@lnikki.la>
|
||||
;;; Copyright © 2025 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||
;;; Copyright © 2025 Rodion Goritskov <rodion@goritskov.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -40,8 +41,10 @@
|
|||
#:use-module (gnu services shepherd)
|
||||
#:use-module (gnu services admin)
|
||||
#:use-module (gnu services configuration)
|
||||
#:use-module (gnu services databases)
|
||||
#:use-module (gnu services getmail)
|
||||
#:use-module (gnu services mail)
|
||||
#:use-module (gnu system file-systems)
|
||||
#:use-module (gnu system pam)
|
||||
#:use-module (gnu system shadow)
|
||||
#:use-module (gnu packages admin)
|
||||
|
@ -59,7 +62,9 @@
|
|||
#:use-module (gnu packages mail)
|
||||
#:use-module (gnu packages rust-apps)
|
||||
#:autoload (guix i18n) (G_)
|
||||
#:autoload (gnu build linux-container) (%namespaces)
|
||||
#:use-module (guix diagnostics)
|
||||
#:use-module (guix least-authority)
|
||||
#:use-module (guix packages)
|
||||
#:use-module (guix records)
|
||||
#:use-module (guix modules)
|
||||
|
@ -74,6 +79,7 @@
|
|||
#:use-module (srfi srfi-34)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (ice-9 format)
|
||||
#:use-module (ice-9 regex)
|
||||
#:export (httpd-configuration
|
||||
httpd-configuration?
|
||||
httpd-configuration-package
|
||||
|
@ -328,7 +334,23 @@
|
|||
agate-configuration-group
|
||||
agate-configuration-log-file
|
||||
|
||||
agate-service-type))
|
||||
agate-service-type
|
||||
|
||||
miniflux-configuration
|
||||
miniflux-configuration?
|
||||
miniflux-configuration-listen-address
|
||||
miniflux-configuration-base-url
|
||||
miniflux-configuration-create-administrator-account?
|
||||
miniflux-configuration-administrator-account-name
|
||||
miniflux-configuration-administrator-account-password
|
||||
miniflux-configuration-run-migrations?
|
||||
miniflux-configuration-database-url
|
||||
miniflux-configuration-user
|
||||
miniflux-configuration-group
|
||||
miniflux-configuration-log-file
|
||||
miniflux-configuration-extra-settings
|
||||
|
||||
miniflux-service-type))
|
||||
|
||||
;;; Commentary:
|
||||
;;;
|
||||
|
@ -2279,3 +2301,173 @@ root=/srv/gemini
|
|||
(default-value (agate-configuration))
|
||||
(description "Run Agate, a simple Gemini protocol server written in
|
||||
Rust.")))
|
||||
|
||||
(define (serialize-string field-name val)
|
||||
(format #f "~a=~a\n" field-name val))
|
||||
|
||||
(define (string-or-file-path? val)
|
||||
(string? val))
|
||||
(define (serialize-string-or-file-path field-name val)
|
||||
(serialize-string (if (absolute-file-name? val)
|
||||
(format #f "~a_FILE" field-name) field-name) val))
|
||||
(define-maybe string-or-file-path)
|
||||
|
||||
(define (serialize-list field-name val)
|
||||
(string-append (string-join val "\n") "\n"))
|
||||
(define-maybe list)
|
||||
|
||||
(define (serialize-boolean field-name val)
|
||||
(if val (serialize-string field-name "1") (serialize-string field-name "0")))
|
||||
|
||||
(define-configuration/no-serialization miniflux-configuration
|
||||
(listen-address
|
||||
(string "127.0.0.1:8080")
|
||||
"Address to listen on.
|
||||
Use absolute path like @code{\"/var/run/miniflux/miniflux.sock\"} for a Unix socket.")
|
||||
(base-url
|
||||
(string "http://127.0.0.1/")
|
||||
"Base URL to generate HTML links and base path for cookies.")
|
||||
(create-administrator-account?
|
||||
(boolean #f)
|
||||
"Create an initial administrator account.")
|
||||
(administrator-account-name
|
||||
maybe-string-or-file-path
|
||||
"Initial administrator account name as a string or an absolute path to a file with a account name inside.")
|
||||
(administrator-account-password
|
||||
maybe-string-or-file-path
|
||||
"Initial administrator account password as a string or an absolute path to a file with a password inside.")
|
||||
(run-migrations?
|
||||
(boolean #t)
|
||||
"Run database migrations during application startup.")
|
||||
(database-url
|
||||
(string "host=/var/run/postgresql")
|
||||
"PostgreSQL connection string.")
|
||||
(user
|
||||
(string "miniflux")
|
||||
"User name for Postgresql and system account.")
|
||||
(group
|
||||
(string "miniflux")
|
||||
"Group for the system account.")
|
||||
(log-file
|
||||
(string "/var/log/miniflux.log")
|
||||
"Path to the log file.")
|
||||
(extra-settings
|
||||
maybe-list
|
||||
"Extra configuration parameters as a list of strings."))
|
||||
|
||||
(define (miniflux-serialize-configuration config)
|
||||
(match-record config <miniflux-configuration>
|
||||
(listen-address base-url create-administrator-account?
|
||||
administrator-account-name administrator-account-password
|
||||
run-migrations? database-url extra-settings)
|
||||
(string-append (serialize-string "LISTEN_ADDR" listen-address)
|
||||
(serialize-string "BASE_URL" base-url)
|
||||
(serialize-boolean "CREATE_ADMIN" create-administrator-account?)
|
||||
(serialize-maybe-string-or-file-path "ADMIN_USERNAME" administrator-account-name)
|
||||
(serialize-maybe-string-or-file-path "ADMIN_PASSWORD" administrator-account-password)
|
||||
(serialize-boolean "RUN_MIGRATIONS" run-migrations?)
|
||||
(serialize-string "DATABASE_URL" database-url)
|
||||
(serialize-maybe-list #f extra-settings))))
|
||||
|
||||
(define (miniflux-configuration-file config)
|
||||
(mixed-text-file "miniflux.conf" (miniflux-serialize-configuration config)))
|
||||
|
||||
(define (pair->file-system-mapping pair previous)
|
||||
(if (pair? pair)
|
||||
(let ((path (car pair))
|
||||
(writable (cdr pair)))
|
||||
(if (or (and (string? path)
|
||||
(absolute-file-name? path))
|
||||
(computed-file? path))
|
||||
(append previous (list (file-system-mapping
|
||||
(source path)
|
||||
(target source)
|
||||
(writable? writable))))
|
||||
previous))
|
||||
previous))
|
||||
|
||||
(define (miniflux-shepherd-service config)
|
||||
(match-record config <miniflux-configuration>
|
||||
(user group log-file database-url listen-address
|
||||
administrator-account-name administrator-account-password)
|
||||
(let ((config-file (miniflux-configuration-file config)))
|
||||
(list (shepherd-service
|
||||
(documentation "Run Miniflux server")
|
||||
(provision '(miniflux))
|
||||
(requirement '(postgres networking))
|
||||
(start #~(make-forkexec-constructor
|
||||
(list #$(least-authority-wrapper
|
||||
(file-append miniflux "/bin/miniflux")
|
||||
#:name "miniflux"
|
||||
#:user user
|
||||
#:group group
|
||||
#:preserved-environment-variables
|
||||
(append %default-preserved-environment-variables
|
||||
'("SSL_CERT_FILE"))
|
||||
#:mappings
|
||||
(fold pair->file-system-mapping
|
||||
'()
|
||||
`((,log-file . #t)
|
||||
(,config-file . #f)
|
||||
("/etc/ssl/certs/ca-certificates.crt" . #f)
|
||||
(,administrator-account-name . #f)
|
||||
(,administrator-account-password . #f)
|
||||
(,(dirname listen-address) . #t)
|
||||
,(let* ((db-socket-match (string-match ".*host=(/[^ ]*).*" database-url))
|
||||
(db-socket (if db-socket-match (match:substring db-socket-match 1) #f)))
|
||||
(if db-socket
|
||||
`(,db-socket . #t)))))
|
||||
#:namespaces
|
||||
(fold delq %namespaces '(net user)))
|
||||
"-config-file"
|
||||
#$config-file)
|
||||
#:log-file #$log-file))
|
||||
(stop #~(make-kill-destructor)))))))
|
||||
|
||||
(define (miniflux-accounts config)
|
||||
(match-record config <miniflux-configuration>
|
||||
(user group)
|
||||
`(,(user-group
|
||||
(name group)
|
||||
(system? #t))
|
||||
,(user-account
|
||||
(name user)
|
||||
(group group)
|
||||
(system? #t)
|
||||
(comment "miniflux server user")
|
||||
(home-directory "/var/empty")
|
||||
(shell (file-append shadow "/sbin/nologin"))))))
|
||||
|
||||
(define (miniflux-postgresql-role config)
|
||||
(list (postgresql-role
|
||||
(name (miniflux-configuration-user config))
|
||||
(create-database? #t))))
|
||||
|
||||
(define (miniflux-log-files config)
|
||||
(list (miniflux-configuration-log-file config)))
|
||||
|
||||
(define (miniflux-activation-service-type config)
|
||||
(match-record config <miniflux-configuration>
|
||||
(user listen-address)
|
||||
#~(begin
|
||||
(use-modules (gnu build activation))
|
||||
(let ((user (getpwnam #$user)))
|
||||
(if (absolute-file-name? #$listen-address)
|
||||
(mkdir-p/perms (dirname #$listen-address) user #o755))))))
|
||||
|
||||
(define miniflux-service-type
|
||||
(service-type
|
||||
(name 'miniflux)
|
||||
(default-value (miniflux-configuration))
|
||||
(extensions
|
||||
(list (service-extension account-service-type
|
||||
miniflux-accounts)
|
||||
(service-extension postgresql-role-service-type
|
||||
miniflux-postgresql-role)
|
||||
(service-extension shepherd-root-service-type
|
||||
miniflux-shepherd-service)
|
||||
(service-extension log-rotation-service-type
|
||||
miniflux-log-files)
|
||||
(service-extension activation-service-type
|
||||
miniflux-activation-service-type)))
|
||||
(description "Run Miniflux, minimalist feed reader")))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
|
||||
;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com>
|
||||
;;; Copyright © 2024 Maxim Cournoyer <maxim@guixotic.coop>
|
||||
;;; Copyright © 2025 Rodion Goritskov <rodion@goritskov.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -37,6 +38,7 @@
|
|||
#:use-module (gnu packages base)
|
||||
#:use-module (gnu packages databases)
|
||||
#:use-module (gnu packages guile-xyz)
|
||||
#:use-module (gnu packages gnupg)
|
||||
#:use-module (gnu packages patchutils)
|
||||
#:use-module (gnu packages python)
|
||||
#:use-module (gnu packages tls)
|
||||
|
@ -56,7 +58,10 @@
|
|||
%test-hpcguix-web
|
||||
%test-anonip
|
||||
%test-patchwork
|
||||
%test-agate))
|
||||
%test-agate
|
||||
%test-miniflux-admin-string
|
||||
%test-miniflux-admin-file
|
||||
%test-miniflux-socket))
|
||||
|
||||
(define %index.html-contents
|
||||
;; Contents of the /index.html file.
|
||||
|
@ -848,3 +853,190 @@ HTTP-PORT."
|
|||
(name "agate")
|
||||
(description "Connect to a running Agate service.")
|
||||
(value (run-agate-test name %agate-os %index.gmi-contents))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Miniflux
|
||||
;;;
|
||||
|
||||
(define %miniflux-create-admin-credentials
|
||||
#~(begin
|
||||
(mkdir "/var/miniflux")
|
||||
(call-with-output-file "/var/miniflux/admin-username"
|
||||
(lambda (port)
|
||||
(display "test" port)))
|
||||
(call-with-output-file "/var/miniflux/admin-password"
|
||||
(lambda (port)
|
||||
(display "testpassword" port)))))
|
||||
|
||||
(define miniflux-base-system
|
||||
(lambda (miniflux-config)
|
||||
(simple-operating-system
|
||||
(simple-service 'create-admin-credentials
|
||||
activation-service-type
|
||||
%miniflux-create-admin-credentials)
|
||||
(service dhcpcd-service-type)
|
||||
(service postgresql-service-type
|
||||
(postgresql-configuration
|
||||
(postgresql postgresql-13)))
|
||||
(service miniflux-service-type
|
||||
miniflux-config))))
|
||||
|
||||
(define %miniflux-with-admin-as-string
|
||||
(miniflux-base-system
|
||||
(miniflux-configuration
|
||||
(listen-address "0.0.0.0:8080")
|
||||
(create-administrator-account? #t)
|
||||
(administrator-account-name "test")
|
||||
(administrator-account-password "testpassword"))))
|
||||
|
||||
(define %miniflux-with-admin-as-file
|
||||
(miniflux-base-system
|
||||
(miniflux-configuration
|
||||
(listen-address "0.0.0.0:8080")
|
||||
(create-administrator-account? #t)
|
||||
(administrator-account-name "/var/miniflux/admin-username")
|
||||
(administrator-account-password "/var/miniflux/admin-password"))))
|
||||
|
||||
(define %miniflux-with-socket
|
||||
(miniflux-base-system
|
||||
(miniflux-configuration
|
||||
(listen-address "/var/run/miniflux/miniflux.sock"))))
|
||||
|
||||
(define* (run-miniflux-test name test-os)
|
||||
(define os
|
||||
(marionette-operating-system
|
||||
test-os
|
||||
#:imported-modules '((gnu services herd)
|
||||
(guix combinators))))
|
||||
|
||||
(define forwarded-port 8080)
|
||||
|
||||
(define vm
|
||||
(virtual-machine
|
||||
(operating-system os)
|
||||
(memory-size 512)
|
||||
(port-forwardings `((8080 . ,forwarded-port)))))
|
||||
|
||||
(define test
|
||||
(with-extensions (list guile-gcrypt)
|
||||
(with-imported-modules '((gnu build marionette))
|
||||
#~(begin
|
||||
(use-modules (srfi srfi-64)
|
||||
(srfi srfi-11)
|
||||
(gnu build marionette)
|
||||
(web client)
|
||||
(web uri)
|
||||
(web response)
|
||||
(ice-9 match)
|
||||
(ice-9 iconv)
|
||||
(gcrypt base64))
|
||||
|
||||
(define marionette
|
||||
(make-marionette (list #$vm)))
|
||||
|
||||
(test-runner-current (system-test-runner #$output))
|
||||
(test-begin #$name)
|
||||
|
||||
(test-assert "Check Miniflux service is running"
|
||||
(begin
|
||||
(#$retry-on-error
|
||||
(lambda ()
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd))
|
||||
(match (start-service '#$(string->symbol "miniflux"))
|
||||
(#f #f)
|
||||
(('service response-parts ...)
|
||||
(match (assq-ref response-parts 'running)
|
||||
(#f #f)
|
||||
((running) #t)))))
|
||||
marionette))
|
||||
#:delay 1
|
||||
#:times 10)))
|
||||
|
||||
(test-assert "Miniflux TCP port ready, IPv4"
|
||||
(wait-for-tcp-port #$forwarded-port marionette))
|
||||
|
||||
(test-assert "Miniflux login page is opened"
|
||||
(begin
|
||||
(wait-for-tcp-port #$forwarded-port marionette)
|
||||
(#$retry-on-error
|
||||
(lambda ()
|
||||
(let-values (((_ text)
|
||||
(http-get
|
||||
#$(format #f "http://localhost:~A/" forwarded-port)
|
||||
#:decode-body? #t)))
|
||||
(string-contains text "<title>Sign In - Miniflux</title>")))
|
||||
#:times 10
|
||||
#:delay 2)))
|
||||
|
||||
(define authorization-header
|
||||
(let ((encoded (base64-encode (string->bytevector "test:testpassword" "utf-8"))))
|
||||
`(authorization . (basic . ,encoded))))
|
||||
|
||||
(test-equal "Miniflux initial admin API call is successful"
|
||||
200
|
||||
(begin
|
||||
(wait-for-tcp-port #$forwarded-port marionette)
|
||||
(#$retry-on-error
|
||||
(lambda ()
|
||||
(let-values (((response _)
|
||||
(http-get #$(format #f "http://localhost:~A/v1/me" forwarded-port)
|
||||
#:headers (list authorization-header)
|
||||
#:decode-body? #t)))
|
||||
|
||||
(response-code response)))
|
||||
#:times 10
|
||||
#:delay 2)))
|
||||
|
||||
(test-end)))))
|
||||
(gexp->derivation (string-append name "-test") test))
|
||||
|
||||
(define* (run-miniflux-socket-test name test-os)
|
||||
(define os
|
||||
(marionette-operating-system
|
||||
test-os
|
||||
#:imported-modules '((gnu services herd)
|
||||
(guix combinators))))
|
||||
|
||||
(define vm
|
||||
(virtual-machine
|
||||
(operating-system os)
|
||||
(memory-size 512)))
|
||||
|
||||
(define test
|
||||
(with-imported-modules '((gnu build marionette))
|
||||
#~(begin
|
||||
(use-modules (srfi srfi-64)
|
||||
(gnu build marionette))
|
||||
|
||||
(define marionette
|
||||
(make-marionette (list #$vm)))
|
||||
|
||||
(test-runner-current (system-test-runner #$output))
|
||||
(test-begin #$name)
|
||||
|
||||
(test-assert "Check socket file is created"
|
||||
(wait-for-unix-socket "/var/run/miniflux/miniflux.sock" marionette))
|
||||
|
||||
(test-end))))
|
||||
(gexp->derivation (string-append name "-test") test))
|
||||
|
||||
(define %test-miniflux-admin-string
|
||||
(system-test
|
||||
(name "miniflux-admin-string")
|
||||
(description "Run Miniflux with initial admin credentials as string.")
|
||||
(value (run-miniflux-test name %miniflux-with-admin-as-string))))
|
||||
|
||||
(define %test-miniflux-admin-file
|
||||
(system-test
|
||||
(name "miniflux-admin-file")
|
||||
(description "Run Miniflux with initial admin credentials as file.")
|
||||
(value (run-miniflux-test name %miniflux-with-admin-as-file))))
|
||||
|
||||
(define %test-miniflux-socket
|
||||
(system-test
|
||||
(name "miniflux-socket")
|
||||
(description "Run Miniflux on unix socket.")
|
||||
(value (run-miniflux-socket-test name %miniflux-with-socket))))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue