Compare commits

...

7 commits

Author SHA1 Message Date
Luj
f60b8243cd Merge pull request 'Finish to init repo' (#1) from finish_init into main
All checks were successful
Check meta / check_meta (push) Successful in 18s
lint / check (push) Successful in 23s
build configuration / build_krz01 (push) Successful in 1m52s
Reviewed-on: #1
2024-10-18 11:24:45 +02:00
c2e8ca5e33
chore(deps): update nix-pkgs
All checks were successful
lint / check (push) Successful in 22s
Check meta / check_meta (pull_request) Successful in 19s
lint / check (pull_request) Successful in 24s
build configuration / build_krz01 (pull_request) Successful in 1m56s
2024-10-18 11:20:33 +02:00
sinavir
eae18caa21 chore(shell): Specialize for lab-infra
Some checks failed
Check meta / check_meta (pull_request) Successful in 17s
lint / check (push) Successful in 22s
build configuration / build_krz01 (pull_request) Failing after 18s
lint / check (pull_request) Successful in 22s
2024-10-18 11:07:33 +02:00
sinavir
b8f729c290 chore(proxmox-nixos): Update 2024-10-18 09:24:22 +02:00
sinavir
2ac0a35c5e chore(meta): Revamp and remove DNS for now
Some checks failed
Check meta / check_meta (push) Successful in 22s
Check meta / check_meta (pull_request) Successful in 21s
lint / check (push) Successful in 23s
lint / check (pull_request) Successful in 24s
build configuration / build_krz01 (pull_request) Failing after 3m26s
We don't have a dns server for the lab infra for now. Later we will
probably reintroduce the tooling for our dns server. This will be good
for people to get into understanding the main infra repository.
2024-10-17 13:36:27 +02:00
sinavir
3ce077f92c chore(iso): Remove as it is broken
Several stuff are broken in the generation of the iso:
 - Impure (using nixpkgs in user nix_path)
 - Using a software which is just a wrpper around nixpkgs
 - Raid stuff is kinda broken (depend on the version of nixpkgs you use,
going back to impurity stated above)
2024-10-17 13:36:27 +02:00
sinavir
16da0a275c feat(patches): Remove unecessary patches 2024-10-17 13:36:27 +02:00
21 changed files with 22 additions and 1819 deletions

View file

@ -15,11 +15,3 @@ jobs:
- name: Check the validity of meta options
run: nix-build meta/verify.nix -A meta
check_dns:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Check the validity of the DNS configuration
run: nix-build meta/verify.nix -A dns --no-out-link

View file

@ -74,19 +74,13 @@ in
host: { site, ... }: "${host}.${site}.infra.dgnum.eu"
) (import ./meta/nodes.nix);
dns = import ./meta/dns.nix;
mkCacheSettings = import ./machines/storage01/tvix-cache/cache-settings.nix;
shells = {
default = pkgs.mkShell {
name = "dgnum-infra";
name = "dgnum-lab-infra";
packages = [
(pkgs.nixos-generators.overrideAttrs (_: {
version = "1.8.0-unstable";
src = builtins.storePath sources.nixos-generators;
}))
pkgs.npins
(pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; })

View file

@ -1,5 +0,0 @@
#!/usr/bin/env bash
NIXPKGS=$(nix-build --no-out-link nixpkgs.nix)
nixos-generate -c configuration.nix -I NIX_PATH="$NIXPKGS" -f install-iso

View file

@ -1,38 +0,0 @@
{ lib, pkgs, ... }:
let
dgn-keys = import ../keys;
dgn-members = (import ../meta lib).organization.groups.root;
in
{
imports = [ ./dgn-install ];
boot = {
blacklistedKernelModules = [ "snd_pcsp" ];
kernelPackages = pkgs.linuxPackages_latest;
tmp.cleanOnBoot = true;
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
supportedFilesystems = [
"exfat"
"zfs"
"bcachefs"
];
swraid.enable = lib.mkForce false;
};
console.keyMap = "fr";
services = {
openssh.enable = true;
};
users.users.root.openssh.authorizedKeys.keys = dgn-keys.getKeys dgn-members;
}

View file

@ -1 +0,0 @@
Script pour installer automatiquement NixOS sur les machines de la DGNum

View file

@ -1,20 +0,0 @@
{ pkgs, ... }:
let
installScript = pkgs.writeShellApplication {
name = "dgn-install";
runtimeInputs = with pkgs; [
coreutils
gnused
nixos-install-tools
zfs
];
text = builtins.readFile ./dgn-install.sh;
};
in
{
environment.systemPackages = [ installScript ];
}

View file

@ -1,149 +0,0 @@
bootDevice=
rootDevice=
domain="par01.infra.dgnum.eu"
hostname="dgn0x"
hasZFS=
while [ "$#" -gt 0 ]; do
i="$1"
shift 1
case "$i" in
--root)
rootDevice="$1"
shift 1
;;
--boot)
bootDevice="$1"
shift 1
;;
--swap)
swapDevice="$1"
shift 1
;;
--domain)
domain="$1"
shift 1
;;
--hostname)
hostname="$1"
shift 1
;;
--with-zfs)
hasZFS="1"
;;
*)
echo "$0: unknown option \`$i'"
exit 1
;;
esac
done
if [ -z "$bootDevice" ]; then
echo "Missing boot partition"
exit 1
fi
if [ -z "$rootDevice" ]; then
echo "Missing root partition"
exit 1
fi
# Mount the partitions to where they should be
mount "$rootDevice" /mnt
mkdir /mnt/boot
mount "$bootDevice" /mnt/boot
if [ -n "$swapDevice" ]; then
swapon "$swapDevice"
fi
# Generate configration
nixos-generate-config --root /mnt
NIX="/mnt/etc/nixos/"
# Setup our own files
mv $NIX/configuration.nix $NIX/base-configuration.nix
cat <<EOF > $NIX/dgnum-server.nix
{ ... }: {
services.nscd.enableNsncd = false;
programs.bash.promptInit = ''
# Provide a nice prompt if the terminal supports it.
if [ "\$TERM" != "dumb" ] || [ -n "\$INSIDE_EMACS" ]; then
PROMPT_COLOR="1;31m"
((UID)) && PROMPT_COLOR="1;32m"
if [ -n "\$INSIDE_EMACS" ] || [ "\$TERM" = "eterm" ] || [ "\$TERM" = "eterm-color" ]; then
# Emacs term mode doesn't support xterm title escape sequence (\e]0;)
PS1="\n\[\033[\$PROMPT_COLOR\][\u@\$(hostname -f):\w]\\\$\[\033[0m\] "
else
PS1="\n\[\033[\$PROMPT_COLOR\][\[\e]0;\u@\H: \w\a\]\u@\$(hostname -f):\w]\\\$\[\033[0m\] "
fi
if test "\$TERM" = "xterm"; then
PS1="\[\033]2;\$(hostname -f):\u:\w\007\]\$PS1"
fi
fi
'';
}
EOF
cat <<EOF > $NIX/configuration.nix
{ pkgs, ... }: {
imports = [
./base-configuration.nix
./dgnum-server.nix
$(if [ -n "$hasZFS" ]; then echo './zfs.nix'; fi)
];
boot.tmp.cleanOnBoot = true;
console.keyMap = "fr";
time.timeZone = "Europe/Paris";
environment.systemPackages = with pkgs; [
vim
wget
kitty.terminfo
];
networking = {
hostName = "$hostname";
domain = "$domain";
};
# Activate SSH and set the keys
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
};
users.users.root.openssh.authorizedKeys.keyFiles = [ ./rootKeys ];
}
EOF
if [ -n "$hasZFS" ]; then
cat <<EOF > $NIX/zfs.nix
{ ... }: {
boot = {
supportedFilesystems = [ "zfs" ];
zfs.forceImportRoot = false;
zfs.extraPools = [
$(zpool list -Ho name | sed 's/^/"/;s/$/"/')
];
};
networking.hostId = "$(head -c4 /dev/urandom | od -A none -t x4 | sed 's/ //')";
}
EOF
fi
# Copy the keys
cp /etc/ssh/authorized_keys.d/root $NIX/rootKeys
# Perform the installation
nixos-install

View file

@ -1,9 +0,0 @@
let
version = (import ../meta/nixpkgs.nix).default;
nixpkgs = (import ../npins)."nixos-${version}";
in
(import nixpkgs { }).srcOnly {
name = "nixpkgs-for-iso";
src = nixpkgs;
}

View file

@ -1,14 +1,12 @@
{ sources, lib, ... }:
{ sources, ... }:
let
proxmox-nixos = import sources.proxmox-nixos;
in
{
imports = [ proxmox-nixos.nixosModules.proxmox-ve ];
services.proxmox-ve.enable = true;
nixpkgs.overlays = [ proxmox-nixos.overlays.x86_64-linux ];
networking.firewall = {
trustedInterfaces = [ "wt0" ];
allowedTCPPorts = lib.mkForce [ 22 ];
services.proxmox-ve = {
enable = true;
openFirewall = false;
};
nixpkgs.overlays = [ proxmox-nixos.overlays.x86_64-linux ];
}

View file

@ -1,136 +0,0 @@
{ lib, dns, ... }:
let
inherit (lib) mapAttrs' nameValuePair;
inherit (lib.extra) fuseAttrs mapSingleFuse;
inherit (dns.lib.combinators) mx spf ttl;
meta = (import ./.) lib;
mkCNAME = host: { CNAME = [ host ]; };
mkHosted =
server:
{
dual ? [ ],
v4 ? [ ],
v6 ? [ ],
}:
let
base = "${server}.${meta.nodes.${server}.site}.infra";
mkHost = host: mapSingleFuse (_: mkCNAME host);
in
fuseAttrs [
(mkHost base dual)
(mkHost "v4.${base}" v4)
(mkHost "v6.${base}" v6)
];
cnames = builtins.mapAttrs (_: to: { CNAME = [ to ]; }) {
"dev" = "dev.pages.codeberg.page.";
"irc" = "public.p.lahfa.xyz.";
"webmail" = "kurisu.dual.lahfa.xyz.";
# Transition to new site names
"web01.dmi01.infra" = "web01.rat01.infra";
"web02.dmi01.infra" = "web02.rat01.infra";
"compute01.par01.infra" = "compute01.pav01.infra";
"storage01.par01.infra" = "storage01.pav01.infra";
# Miscelleanous redirections
"traque" = "traque.katvayor.net.";
# Temporary redirection for the BDS
# FIXME: finish the django apps module
"gestiobds.dj" = "cof.ens.fr.";
};
hosted = fuseAttrs (builtins.attrValues (builtins.mapAttrs mkHosted { }));
kurisuDKIM = [
{
selector = "kurisu";
k = "rsa";
s = [ "email" ];
p = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDa5KuK6ry+Ss2VsKL0FsDpoBlc7dcXZyp62fGqFJFJv4/GEivPWiwbr2o5oLKjQVI4kIYjIZsyQJFtI/Xcu4BrtDdBknb5WvCN8V9EvIMh3pfXOBLVx4oqw4BR7wF8Rw1J9xyfgsfK+m2n0M39XlMHH0Nuy6kU48jH9vYpZs17ZQIDAQAB";
}
];
in
{
SOA = {
nameServer = "ns01.dgnum.eu.";
adminEmail = "dns.dgnum.eu";
retry = 3600;
minimum = 300;
};
# Primary DNS servers
NS = [
"ns01.dgnum.eu." # ns-03.hubrecht.ovh
"ns02.dgnum.eu." # kurisu.lahfa.xyz
];
# dgnum.codeberg.pages
# ALIAS = [ "codeberg.page" ];
A = [ "217.197.91.145" ];
AAAA = [ "2001:67c:1401:20f0::1" ];
MX = map (ttl 3600) [ (mx.mx 10 "kurisu.lahfa.xyz.") ];
SRV = [
{
service = "autodiscover";
proto = "tcp";
port = 443;
target = "autoconfig.mail.lahfa.xyz.";
}
];
TXT = [
"dgnum.codeberg.page"
(spf.strict [ "a:kurisu.lahfa.xyz" ])
];
DMARC = [ { p = "none"; } ];
DKIM = kurisuDKIM;
subdomains =
hosted
// cnames
// {
ns01 = {
A = [ "51.178.27.125" ];
AAAA = [ "2001:41d0:305:2100::542c" ];
};
ns02 = {
A = [ "163.172.69.160" ];
AAAA = [ "2001:bc8:38ee::1" ];
};
}
// {
infra = {
MX = map (ttl 3600) [ (mx.mx 10 "kurisu.lahfa.xyz.") ];
TXT = [ (spf.strict [ "a:kurisu.lahfa.xyz" ]) ];
DMARC = [ { p = "none"; } ];
DKIM = kurisuDKIM;
subdomains = mapAttrs' (
host:
{ site, ... }:
nameValuePair "${host}.${site}" (
with meta.network.${host}.addresses;
{
A = ipv4;
AAAA = ipv6;
subdomains = {
v4.A = ipv4;
v6.AAAA = ipv6;
};
}
)
) meta.nodes;
};
};
}

View file

@ -1,34 +1,4 @@
{
bridge01 = {
hostId = "f57f3ba0";
interfaces = { };
netbirdIp = null;
};
compute01 = {
interfaces = {
eno1 = {
ipv4 = [
{
address = "129.199.146.147";
prefixLength = 24;
}
{
address = "192.168.1.147";
prefixLength = 24;
}
];
gateways = [ "129.199.146.254" ];
enableDefaultDNS = true;
};
};
hostId = "8df60941";
netbirdIp = "100.80.75.197";
};
krz01 = {
interfaces = {
eno1 = {
@ -51,157 +21,4 @@
hostId = "bd11e8fc";
netbirdIp = "100.80.103.206";
};
geo01 = {
interfaces = {
eno1 = {
ipv4 = [
{
address = "129.199.210.194";
prefixLength = 24;
}
];
gateways = [ "129.199.210.254" ];
dns = [
"129.199.96.11"
"129.199.72.99"
];
};
};
hostId = "b88fee0c";
netbirdIp = "100.80.8.66";
};
geo02 = {
interfaces = {
eno1 = {
ipv4 = [
{
address = "129.199.210.69";
prefixLength = 24;
}
];
gateways = [ "129.199.210.254" ];
dns = [
"129.199.96.11"
"129.199.72.99"
];
};
};
hostId = "45d65237";
netbirdIp = "100.80.233.249";
};
storage01 = {
interfaces = {
eno1 = {
ipv4 = [
{
address = "129.199.146.148";
prefixLength = 24;
}
{
address = "192.168.1.148";
prefixLength = 24;
}
];
gateways = [ "129.199.146.254" ];
enableDefaultDNS = true;
};
};
hostId = "d4e7c369";
netbirdIp = "100.80.156.154";
};
vault01 = {
interfaces = {
vlan-uplink-cri = {
ipv4 = [
{
# see also machines/vault01/networking.nix
address = "129.199.195.129";
prefixLength = 32;
}
];
gateways = [ ];
enableDefaultDNS = true;
};
};
hostId = "e83b600d";
netbirdIp = "100.80.255.180";
};
web01 = {
interfaces = {
ens3 = {
ipv4 = [
{
address = "129.199.129.53";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ];
enableDefaultDNS = true;
};
};
hostId = "050df79e";
netbirdIp = "100.80.77.90";
};
web02 = {
interfaces = {
ens3 = {
ipv4 = [
{
address = "129.199.129.235";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ];
enableDefaultDNS = true;
};
};
hostId = "b431ca10";
netbirdIp = null; # web02 is not to be connected on the VPN
};
rescue01 = {
interfaces = {
ens18 = {
ipv6 = [
{
address = "2a01:e0a:de4:a0e1:2d73:2a7e:18db:5728";
prefixLength = 64;
}
];
ipv4 = [
{
address = "192.168.0.232";
prefixLength = 21;
}
];
gateways = [ "192.168.0.1" ];
enableDefaultDNS = true;
};
};
addresses.ipv4 = [ "82.67.34.230" ];
hostId = "007f0200";
netbirdIp = "100.80.97.140";
};
}

View file

@ -19,66 +19,6 @@
- luj01 -> VM de Luj
*/
{
bridge01 = {
site = "hyp01";
hashedPassword = "$y$j9T$EPJdz70kselouXAVUmAH01$8nYbUBY9NPTMfYigegY0qFSdxJwhqzW8sFacDqEYCP5";
stateVersion = "24.05";
adminGroups = [ "fai" ];
deployment = {
targetHost = "fd26:baf9:d250:8000::ffff";
sshOptions = [
"-J"
"root@vault01.hyp01.infra.dgnum.eu"
];
};
};
web01 = {
site = "rat01";
deployment.tags = [ "web" ];
hashedPassword = "$y$j9T$9YqXO93VJE/GP3z8Sh4h51$hrBsEPL2O1eP/wBZTrNT8XV906V4JKbQ0g04IWBcyd2";
stateVersion = "23.05";
vm-cluster = "Hyperviseur NPS";
nixpkgs = "24.05";
};
compute01 = {
site = "pav01";
hashedPassword = "$y$j9T$2nxZHq84G7fWvWMEaGavE/$0ADnmD9qMpXJJ.rWWH9086EakvZ3wAg0mSxZYugOf3C";
stateVersion = "23.05";
nix-modules = [ "services/stirling-pdf" ];
nixpkgs = "24.05";
};
geo01 = {
site = "oik01";
deployment.tags = [ "geo" ];
hashedPassword = "$y$j9T$2XmDpJu.QLhV57yYCh5Lf1$LK.X0HKB02Q0Ujvhj5nIofW2IRrIAL/Uxnvl9AXM1L8";
stateVersion = "24.05";
nixpkgs = "24.05";
};
geo02 = {
site = "oik01";
deployment.tags = [ "geo" ];
hashedPassword = "$y$j9T$Q4fbMpSm9beWu4DPNAR9t0$dx/1pH4GPY72LpS5ZiECXAZFDdxwmIywztsX.qo2VVA";
stateVersion = "24.05";
nixpkgs = "24.05";
};
krz01 = {
site = "pav01";
@ -87,51 +27,5 @@
stateVersion = "24.05";
nixpkgs = "unstable";
adminGroups = [ "lab" ];
};
storage01 = {
site = "pav01";
hashedPassword = "$y$j9T$tvRu1EJ9MwDSvEm0ogwe70$bKSw6nNteN0L3NOy2Yix7KlIvO/oROQmQ.Ynq002Fg8";
stateVersion = "23.11";
nixpkgs = "24.05";
nix-modules = [ "services/forgejo-nix-runners" ];
};
vault01 = {
site = "hyp01";
deployment.targetHost = "vault01.hyp01.infra.dgnum.eu";
hashedPassword = "$y$j9T$5osXVNxCDxu3jIndcyh7G.$UrjiDRpMu3W59tKHLGNdLWllZh.4p8IM4sBS5SrNrN1";
stateVersion = "23.11";
nixpkgs = "24.05";
adminGroups = [ "fai" ];
};
web02 = {
site = "rat01";
hashedPassword = "$y$j9T$p42UVNy78PykkQOjPwXNJ/$B/zCUOrHXVSFGUY63wnViMiSmU2vCWsiX0y62qqgNQ5";
stateVersion = "24.05";
nixpkgs = "24.05";
vm-cluster = "Hyperviseur NPS";
};
rescue01 = {
site = "luj01";
deployment.targetHost = "v6.rescue01.luj01.infra.dgnum.eu";
hashedPassword = "$y$j9T$nqoMMu/axrD0m8AlUFdbs.$UFVmIdPAOHBe2jJv5HJJTcDgINC7LTnSGRQNs9zS1mC";
stateVersion = "23.11";
vm-cluster = "Hyperviseur Luj";
};
}

View file

@ -70,39 +70,6 @@ in
Groups of the DGNum organization.
'';
};
external = mkOption {
type = attrsOf (listOf str);
description = ''
External services used by the DGNum organization.
'';
};
services = mkOption {
type = attrsOf (submodule {
options = {
admins = mkOption {
type = listOf str;
default = [ ];
description = ''
List of administrators of the service.
'';
};
adminGroups = mkOption {
type = listOf str;
default = [ ];
description = ''
List of administrator groups of the service.
'';
};
};
});
description = ''
Administrator access of the different DGNum services,
it is mainly indicative as most services cannot configure this statically.
'';
};
};
nodes = mkOption {
@ -360,21 +327,6 @@ in
extract "adminGroups" config.nodes
))
# Check that all services admins exist
(membersExists (name: "A member of the service ${name} admins was not found in the members list.") (
extract "admins" org.services
))
# Check that all services adminGroups exist
(groupsExists (
name: "A member of the service ${name} adminGroups was not found in the groups list."
) (extract "adminGroups" org.services))
# Check that all external services admins exist
(membersExists (
name: "A member of the external service ${name} admins was not found in the members list."
) org.external)
# Check that all members have ssh keys
(builtins.map (name: {
assertion = ((import ../keys)._keys.${name} or [ ]) != [ ];

View file

@ -10,6 +10,11 @@
email = "catvayor@dgnum.eu";
};
cst1 = {
name = "Constantin Gierczak--Galle";
email = "cst1@dgnum.eu";
};
ecoppens = {
name = "Elias Coppens";
email = "ecoppens@dgnum.eu";
@ -48,52 +53,10 @@
"raito"
"mdebray"
"luj"
];
# members of this group are root on the fai infrastructure
fai = [
"catvayor"
"ecoppens"
"cst1"
];
lab = [
"catvayor"
"ecoppens"
];
};
external = {
dns = [
"thubrecht"
"raito"
];
email = [ "raito" ];
irc = [ "raito" ];
};
services = {
# Démarches Normaliennes
ds-fr.admins = [
"thubrecht"
"jemagius"
];
# Cloud DGNum
nextcloud.admins = [
"thubrecht"
"raito"
];
# Netbox DGNum
netbox.adminGroups = [
"root"
"fai"
];
# Videos DGNum
peertube.admins = [ "thubrecht" ];
};
}

View file

@ -3,8 +3,6 @@
let
sources = import ../npins;
pkgs = import sources.nixpkgs { };
dns = import sources."dns.nix" { inherit pkgs; };
in
{
@ -22,15 +20,4 @@ in
else
pkgs.writers.writeJSON "meta.json" config;
dns = dns.util.writeZone "dgnum.eu" (
pkgs.lib.recursiveUpdate { SOA.serial = 0; } (
import ./dns.nix {
inherit dns;
lib = pkgs.lib // {
extra = import ../lib/nix-lib;
};
}
)
);
}

View file

@ -131,9 +131,9 @@
"url": "https://git.hubrecht.ovh/hubrecht/nix-pkgs"
},
"branch": "main",
"revision": "3e731378f3984313ef902c5e5a49e002e6e2c27e",
"revision": "0e80d4dcdd54a75556c0784de55dc139ad4fe797",
"url": null,
"hash": "1vy2dj9fyy653w6idvi1r73s0nd2a332a1xkppddjip6rk0i030p"
"hash": "1hlb0cczxq0jrzw4lhmkibnb8skcar0rmny594aqgyikknwzx2qf"
},
"nixos-23.11": {
"type": "Channel",
@ -179,9 +179,9 @@
"repo": "proxmox-nixos"
},
"branch": "main",
"revision": "7869ffc2e0db36f314fb60f1ab0087b760700b00",
"url": "https://github.com/SaumonNet/proxmox-nixos/archive/7869ffc2e0db36f314fb60f1ab0087b760700b00.tar.gz",
"hash": "0cam36s3ar366y41rvihjqghkdjl9a1n1wzym8p2mkar1r9x7haj"
"revision": "950e4cccac0f942076e8558f7f9f4d496cabfb18",
"url": "https://github.com/SaumonNet/proxmox-nixos/archive/950e4cccac0f942076e8558f7f9f4d496cabfb18.tar.gz",
"hash": "0bhqw42ydc0jfkfqw64xsg518a1pbxnvpqw92nna7lm8mzpxm6d4"
}
},
"version": 3

View file

@ -1,808 +0,0 @@
From 3b656cbdf40c6056983e95ac5c87839a68571096 Mon Sep 17 00:00:00 2001
From: Alexander Tomokhov <alexoundos@gmail.com>
Date: Tue, 3 Oct 2023 22:20:59 +0400
Subject: [PATCH 1/8] castopod: 1.6.4 -> 1.6.5
---
pkgs/applications/audio/castopod/default.nix | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pkgs/applications/audio/castopod/default.nix b/pkgs/applications/audio/castopod/default.nix
index 9d9f83e2ecce40..83c70f9b36646d 100644
--- a/pkgs/applications/audio/castopod/default.nix
+++ b/pkgs/applications/audio/castopod/default.nix
@@ -7,11 +7,11 @@
}:
stdenv.mkDerivation {
pname = "castopod";
- version = "1.6.4";
+ version = "1.6.5";
src = fetchurl {
- url = "https://code.castopod.org/adaures/castopod/uploads/ce56d4f149242f12bedd20f9a2b0916d/castopod-1.6.4.tar.gz";
- sha256 = "080jj91yxbn3xsbs0sywzwa2f5in9bp9qi2zwqcfqpaxlq9ga62v";
+ url = "https://code.castopod.org/adaures/castopod/uploads/5aaaa6cf2edaed25bd7253449e5f8584/castopod-1.6.5.tar.gz";
+ sha256 = "04gcq2vmfy5aa2fmsm1qqv1k8g024nikmysdrhy33wj460d529b5";
};
dontBuild = true;
From 4cd096c27c52ff9948bc7d9ebc05490147ca9675 Mon Sep 17 00:00:00 2001
From: Alexander Tomokhov <alexoundos@gmail.com>
Date: Tue, 3 Oct 2023 22:19:36 +0400
Subject: [PATCH 2/8] nixos/castopod: fix startup, displaying images, uploads
up to 500 MiB
- new maxUploadSize option
- new dataDir option (with ReadWritePaths systemd support)
- admin page reports correct free disk space (instead of /nix/store)
- fix example configuration in documentation
- now podcast creation and file upload are tested during NixOS test
- move castopod from audio to web-apps folder
- verbose logging from the browser test
---
nixos/modules/module-list.nix | 2 +-
.../services/{audio => web-apps}/castopod.md | 11 +-
.../services/{audio => web-apps}/castopod.nix | 60 ++--
nixos/tests/castopod.nix | 263 +++++++++++++-----
pkgs/applications/audio/castopod/default.nix | 13 +-
5 files changed, 256 insertions(+), 93 deletions(-)
rename nixos/modules/services/{audio => web-apps}/castopod.md (72%)
rename nixos/modules/services/{audio => web-apps}/castopod.nix (80%)
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 627427262da632..97043c965400c5 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -337,7 +337,6 @@
./services/amqp/rabbitmq.nix
./services/audio/alsa.nix
./services/audio/botamusique.nix
- ./services/audio/castopod.nix
./services/audio/gmediarender.nix
./services/audio/gonic.nix
./services/audio/goxlr-utility.nix
@@ -1282,6 +1281,7 @@
./services/web-apps/bookstack.nix
./services/web-apps/c2fmzq-server.nix
./services/web-apps/calibre-web.nix
+ ./services/web-apps/castopod.nix
./services/web-apps/coder.nix
./services/web-apps/changedetection-io.nix
./services/web-apps/chatgpt-retrieval-plugin.nix
diff --git a/nixos/modules/services/audio/castopod.md b/nixos/modules/services/web-apps/castopod.md
similarity index 72%
rename from nixos/modules/services/audio/castopod.md
rename to nixos/modules/services/web-apps/castopod.md
index ee8590737a7c73..f61bf1166a4d24 100644
--- a/nixos/modules/services/audio/castopod.md
+++ b/nixos/modules/services/web-apps/castopod.md
@@ -4,6 +4,7 @@ Castopod is an open-source hosting platform made for podcasters who want to enga
## Quickstart {#module-services-castopod-quickstart}
+Configure ACME (https://nixos.org/manual/nixos/unstable/#module-security-acme).
Use the following configuration to start a public instance of Castopod on `castopod.example.com` domain:
```nix
@@ -11,11 +12,11 @@ networking.firewall.allowedTCPPorts = [ 80 443 ];
services.castopod = {
enable = true;
database.createLocally = true;
- nginx.virtualHost = {
- serverName = "castopod.example.com";
- enableACME = true;
- forceSSL = true;
- };
+ localDomain = "castopod.example.com";
+};
+services.nginx.virtualHosts."castopod.example.com" = {
+ enableACME = true;
+ forceSSL = true;
};
```
diff --git a/nixos/modules/services/audio/castopod.nix b/nixos/modules/services/web-apps/castopod.nix
similarity index 80%
rename from nixos/modules/services/audio/castopod.nix
rename to nixos/modules/services/web-apps/castopod.nix
index b782b548914795..7c99551c83183f 100644
--- a/nixos/modules/services/audio/castopod.nix
+++ b/nixos/modules/services/web-apps/castopod.nix
@@ -4,7 +4,6 @@ let
fpm = config.services.phpfpm.pools.castopod;
user = "castopod";
- stateDirectory = "/var/lib/castopod";
# https://docs.castopod.org/getting-started/install.html#requirements
phpPackage = pkgs.php.withExtensions ({ enabled, all }: with all; [
@@ -29,6 +28,15 @@ in
defaultText = lib.literalMD "pkgs.castopod";
description = lib.mdDoc "Which Castopod package to use.";
};
+ dataDir = lib.mkOption {
+ type = lib.types.path;
+ default = "/var/lib/castopod";
+ description = lib.mdDoc ''
+ The path where castopod stores all data. This path must be in sync
+ with the castopod package (where it is hardcoded during the build in
+ accordance with its own `dataDir` argument).
+ '';
+ };
database = {
createLocally = lib.mkOption {
type = lib.types.bool;
@@ -111,6 +119,18 @@ in
Options for Castopod's PHP pool. See the documentation on `php-fpm.conf` for details on configuration directives.
'';
};
+ maxUploadSize = lib.mkOption {
+ type = lib.types.int;
+ default = 512;
+ description = lib.mdDoc ''
+ Maximum supported size for a file upload in MiB. Maximum HTTP body
+ size is set to this value for nginx and PHP (because castopod doesn't
+ support chunked uploads yet:
+ https://code.castopod.org/adaures/castopod/-/issues/330). Note, that
+ practical upload size limit is smaller. For example, with 512 MiB
+ setting - around 500 MiB is possible.
+ '';
+ };
};
};
@@ -120,13 +140,13 @@ in
sslEnabled = with config.services.nginx.virtualHosts.${cfg.localDomain}; addSSL || forceSSL || onlySSL || enableACME || useACMEHost != null;
baseURL = "http${lib.optionalString sslEnabled "s"}://${cfg.localDomain}";
in
- lib.mapAttrs (name: lib.mkDefault) {
+ lib.mapAttrs (_name: lib.mkDefault) {
"app.forceGlobalSecureRequests" = sslEnabled;
"app.baseURL" = baseURL;
- "media.baseURL" = "/";
+ "media.baseURL" = baseURL;
"media.root" = "media";
- "media.storage" = stateDirectory;
+ "media.storage" = cfg.dataDir;
"admin.gateway" = "admin";
"auth.gateway" = "auth";
@@ -142,13 +162,13 @@ in
services.phpfpm.pools.castopod = {
inherit user;
group = config.services.nginx.group;
- phpPackage = phpPackage;
+ inherit phpPackage;
phpOptions = ''
- # https://code.castopod.org/adaures/castopod/-/blob/main/docker/production/app/uploads.ini
+ # https://code.castopod.org/adaures/castopod/-/blob/develop/docker/production/common/uploads.template.ini
file_uploads = On
memory_limit = 512M
- upload_max_filesize = 500M
- post_max_size = 512M
+ upload_max_filesize = ${toString cfg.maxUploadSize}M
+ post_max_size = ${toString cfg.maxUploadSize}M
max_execution_time = 300
max_input_time = 300
'';
@@ -165,25 +185,25 @@ in
path = [ pkgs.openssl phpPackage ];
script =
let
- envFile = "${stateDirectory}/.env";
+ envFile = "${cfg.dataDir}/.env";
media = "${cfg.settings."media.storage"}/${cfg.settings."media.root"}";
in
''
- mkdir -p ${stateDirectory}/writable/{cache,logs,session,temp,uploads}
+ mkdir -p ${cfg.dataDir}/writable/{cache,logs,session,temp,uploads}
if [ ! -d ${lib.escapeShellArg media} ]; then
cp --no-preserve=mode,ownership -r ${cfg.package}/share/castopod/public/media ${lib.escapeShellArg media}
fi
- if [ ! -f ${stateDirectory}/salt ]; then
- openssl rand -base64 33 > ${stateDirectory}/salt
+ if [ ! -f ${cfg.dataDir}/salt ]; then
+ openssl rand -base64 33 > ${cfg.dataDir}/salt
fi
cat <<'EOF' > ${envFile}
${lib.generators.toKeyValue { } cfg.settings}
EOF
- echo "analytics.salt=$(cat ${stateDirectory}/salt)" >> ${envFile}
+ echo "analytics.salt=$(cat ${cfg.dataDir}/salt)" >> ${envFile}
${if (cfg.database.passwordFile != null) then ''
echo "database.default.password=$(cat ${lib.escapeShellArg cfg.database.passwordFile})" >> ${envFile}
@@ -192,10 +212,10 @@ in
''}
${lib.optionalString (cfg.environmentFile != null) ''
- cat ${lib.escapeShellArg cfg.environmentFile}) >> ${envFile}
+ cat ${lib.escapeShellArg cfg.environmentFile} >> ${envFile}
''}
- php spark castopod:database-update
+ php ${cfg.package}/share/castopod/spark castopod:database-update
'';
serviceConfig = {
StateDirectory = "castopod";
@@ -204,6 +224,7 @@ in
RemainAfterExit = true;
User = user;
Group = config.services.nginx.group;
+ ReadWritePaths = cfg.dataDir;
};
};
@@ -212,9 +233,7 @@ in
wantedBy = [ "multi-user.target" ];
path = [ phpPackage ];
script = ''
- php public/index.php scheduled-activities
- php public/index.php scheduled-websub-publish
- php public/index.php scheduled-video-clips
+ php ${cfg.package}/share/castopod/spark tasks:run
'';
serviceConfig = {
StateDirectory = "castopod";
@@ -222,6 +241,8 @@ in
Type = "oneshot";
User = user;
Group = config.services.nginx.group;
+ ReadWritePaths = cfg.dataDir;
+ LogLevelMax = "notice"; # otherwise periodic tasks flood the journal
};
};
@@ -251,6 +272,7 @@ in
extraConfig = ''
try_files $uri $uri/ /index.php?$args;
index index.php index.html;
+ client_max_body_size ${toString cfg.maxUploadSize}M;
'';
locations."^~ /${cfg.settings."media.root"}/" = {
@@ -278,7 +300,7 @@ in
};
};
- users.users.${user} = lib.mapAttrs (name: lib.mkDefault) {
+ users.users.${user} = lib.mapAttrs (_name: lib.mkDefault) {
description = "Castopod user";
isSystemUser = true;
group = config.services.nginx.group;
diff --git a/nixos/tests/castopod.nix b/nixos/tests/castopod.nix
index 4435ec617d4e67..2db7aa0bda6507 100644
--- a/nixos/tests/castopod.nix
+++ b/nixos/tests/castopod.nix
@@ -4,74 +4,211 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
meta = with lib.maintainers; {
maintainers = [ alexoundos misuzu ];
};
+
nodes.castopod = { nodes, ... }: {
+ # otherwise 500 MiB file upload fails!
+ virtualisation.diskSize = 512 + 3 * 512;
+
networking.firewall.allowedTCPPorts = [ 80 ];
- networking.extraHosts = ''
- 127.0.0.1 castopod.example.com
- '';
+ networking.extraHosts =
+ lib.strings.concatStringsSep "\n"
+ (lib.attrsets.mapAttrsToList
+ (name: _: "127.0.0.1 ${name}")
+ nodes.castopod.services.nginx.virtualHosts);
+
services.castopod = {
enable = true;
database.createLocally = true;
localDomain = "castopod.example.com";
+ maxUploadSize = 512;
};
- environment.systemPackages =
- let
- username = "admin";
- email = "admin@castood.example.com";
- password = "v82HmEp5";
- testRunner = pkgs.writers.writePython3Bin "test-runner"
- {
- libraries = [ pkgs.python3Packages.selenium ];
- flakeIgnore = [
- "E501"
- ];
- } ''
- from selenium.webdriver.common.by import By
- from selenium.webdriver import Firefox
- from selenium.webdriver.firefox.options import Options
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
-
- options = Options()
- options.add_argument('--headless')
- driver = Firefox(options=options)
- try:
- driver.implicitly_wait(20)
- driver.get('http://castopod.example.com/cp-install')
-
- wait = WebDriverWait(driver, 10)
-
- wait.until(EC.title_contains("installer"))
-
- driver.find_element(By.CSS_SELECTOR, '#username').send_keys(
- '${username}'
- )
- driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
- '${email}'
- )
- driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
- '${password}'
- )
- driver.find_element(By.XPATH, "//button[contains(., 'Finish install')]").click()
-
- wait.until(EC.title_contains("Auth"))
-
- driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
- '${email}'
- )
- driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
- '${password}'
- )
- driver.find_element(By.XPATH, "//button[contains(., 'Login')]").click()
-
- wait.until(EC.title_contains("Admin dashboard"))
- finally:
- driver.close()
- driver.quit()
- '';
- in
- [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ];
};
+
+ nodes.client = { nodes, pkgs, lib, ... }:
+ let
+ domain = nodes.castopod.services.castopod.localDomain;
+
+ getIP = node:
+ (builtins.head node.networking.interfaces.eth1.ipv4.addresses).address;
+
+ targetPodcastSize = 500 * 1024 * 1024;
+ lameMp3Bitrate = 348300;
+ lameMp3FileAdjust = -800;
+ targetPodcastDuration = toString
+ ((targetPodcastSize + lameMp3FileAdjust) / (lameMp3Bitrate / 8));
+ mp3file = with pkgs;
+ runCommand "gen-castopod.mp3" { nativeBuildInputs = [ sox lame ]; } ''
+ sox -n -r 48000 -t wav - synth ${targetPodcastDuration} sine 440 `
+ `| lame --noreplaygain -cbr -q 9 -b 320 - $out
+ FILESIZE="$(stat -c%s $out)"
+ [ "$FILESIZE" -gt 0 ]
+ [ "$FILESIZE" -le "${toString targetPodcastSize}" ]
+ '';
+
+ bannerWidth = 3000;
+ banner = pkgs.runCommand "gen-castopod-cover.jpg" { } ''
+ ${pkgs.imagemagick}/bin/magick `
+ `-background green -bordercolor white -gravity northwest xc:black `
+ `-duplicate 99 `
+ `-seed 1 -resize "%[fx:rand()*72+24]" `
+ `-seed 0 -rotate "%[fx:rand()*360]" -border 6x6 -splice 16x36 `
+ `-seed 0 -rotate "%[fx:floor(rand()*4)*90]" -resize "150x50!" `
+ `+append -crop 10x1@ +repage -roll "+%[fx:(t%2)*72]+0" -append `
+ `-resize ${toString bannerWidth} -quality 1 $out
+ '';
+
+ coverWidth = toString 3000;
+ cover = pkgs.runCommand "gen-castopod-banner.jpg" { } ''
+ ${pkgs.imagemagick}/bin/magick `
+ `-background white -bordercolor white -gravity northwest xc:black `
+ `-duplicate 99 `
+ `-seed 1 -resize "%[fx:rand()*72+24]" `
+ `-seed 0 -rotate "%[fx:rand()*360]" -border 6x6 -splice 36x36 `
+ `-seed 0 -rotate "%[fx:floor(rand()*4)*90]" -resize "144x144!" `
+ `+append -crop 10x1@ +repage -roll "+%[fx:(t%2)*72]+0" -append `
+ `-resize ${coverWidth} -quality 1 $out
+ '';
+ in
+ {
+ networking.extraHosts =
+ lib.strings.concatStringsSep "\n"
+ (lib.attrsets.mapAttrsToList
+ (name: _: "${getIP nodes.castopod} ${name}")
+ nodes.castopod.services.nginx.virtualHosts);
+
+ environment.systemPackages =
+ let
+ username = "admin";
+ email = "admin@${domain}";
+ password = "Abcd1234";
+ podcastTitle = "Some Title";
+ episodeTitle = "Episode Title";
+ browser-test = pkgs.writers.writePython3Bin "browser-test"
+ {
+ libraries = [ pkgs.python3Packages.selenium ];
+ flakeIgnore = [ "E124" "E501" ];
+ } ''
+ from selenium.webdriver.common.by import By
+ from selenium.webdriver import Firefox
+ from selenium.webdriver.firefox.options import Options
+ from selenium.webdriver.firefox.service import Service
+ from selenium.webdriver.support.ui import WebDriverWait
+ from selenium.webdriver.support import expected_conditions as EC
+ from subprocess import STDOUT
+ import logging
+
+ selenium_logger = logging.getLogger("selenium")
+ selenium_logger.setLevel(logging.DEBUG)
+ selenium_logger.addHandler(logging.StreamHandler())
+
+ options = Options()
+ options.add_argument('--headless')
+ service = Service(log_output=STDOUT)
+ driver = Firefox(options=options, service=service)
+ driver = Firefox(options=options)
+ driver.implicitly_wait(20)
+
+ # install ##########################################################
+
+ driver.get('http://${domain}/cp-install')
+
+ wait = WebDriverWait(driver, 10)
+
+ wait.until(EC.title_contains("installer"))
+
+ driver.find_element(By.CSS_SELECTOR, '#username').send_keys(
+ '${username}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
+ '${email}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
+ '${password}'
+ )
+ driver.find_element(By.XPATH,
+ "//button[contains(., 'Finish install')]"
+ ).click()
+
+ wait.until(EC.title_contains("Auth"))
+
+ driver.find_element(By.CSS_SELECTOR, '#email').send_keys(
+ '${email}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#password').send_keys(
+ '${password}'
+ )
+ driver.find_element(By.XPATH,
+ "//button[contains(., 'Login')]"
+ ).click()
+
+ wait.until(EC.title_contains("Admin dashboard"))
+
+ # create podcast ###################################################
+
+ driver.get('http://${domain}/admin/podcasts/new')
+
+ wait.until(EC.title_contains("Create podcast"))
+
+ driver.find_element(By.CSS_SELECTOR, '#cover').send_keys(
+ '${cover}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#banner').send_keys(
+ '${banner}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#title').send_keys(
+ '${podcastTitle}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#handle').send_keys(
+ 'some_handle'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#description').send_keys(
+ 'Some description'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#owner_name').send_keys(
+ 'Owner Name'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#owner_email').send_keys(
+ 'owner@email.xyz'
+ )
+ driver.find_element(By.XPATH,
+ "//button[contains(., 'Create podcast')]"
+ ).click()
+
+ wait.until(EC.title_contains("${podcastTitle}"))
+
+ driver.find_element(By.XPATH,
+ "//span[contains(., 'Add an episode')]"
+ ).click()
+
+ wait.until(EC.title_contains("Add an episode"))
+
+ # upload podcast ###################################################
+
+ driver.find_element(By.CSS_SELECTOR, '#audio_file').send_keys(
+ '${mp3file}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#cover').send_keys(
+ '${cover}'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#description').send_keys(
+ 'Episode description'
+ )
+ driver.find_element(By.CSS_SELECTOR, '#title').send_keys(
+ '${episodeTitle}'
+ )
+ driver.find_element(By.XPATH,
+ "//button[contains(., 'Create episode')]"
+ ).click()
+
+ wait.until(EC.title_contains("${episodeTitle}"))
+
+ driver.close()
+ driver.quit()
+ '';
+ in
+ [ pkgs.firefox-unwrapped pkgs.geckodriver browser-test ];
+ };
+
testScript = ''
start_all()
castopod.wait_for_unit("castopod-setup.service")
@@ -79,9 +216,9 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
castopod.wait_for_unit("nginx.service")
castopod.wait_for_open_port(80)
castopod.wait_until_succeeds("curl -sS -f http://castopod.example.com")
- castopod.succeed("curl -s http://localhost/cp-install | grep 'Create your Super Admin account' > /dev/null")
- with subtest("Create superadmin and log in"):
- castopod.succeed("PYTHONUNBUFFERED=1 systemd-cat -t test-runner test-runner")
+ with subtest("Create superadmin, log in, create and upload a podcast"):
+ client.succeed(\
+ "PYTHONUNBUFFERED=1 systemd-cat -t browser-test browser-test")
'';
})
diff --git a/pkgs/applications/audio/castopod/default.nix b/pkgs/applications/audio/castopod/default.nix
index 83c70f9b36646d..badace09587d2b 100644
--- a/pkgs/applications/audio/castopod/default.nix
+++ b/pkgs/applications/audio/castopod/default.nix
@@ -3,7 +3,7 @@
, ffmpeg-headless
, lib
, nixosTests
-, stateDirectory ? "/var/lib/castopod"
+, dataDir ? "/var/lib/castopod"
}:
stdenv.mkDerivation {
pname = "castopod";
@@ -20,13 +20,16 @@ stdenv.mkDerivation {
postPatch = ''
# not configurable at runtime unfortunately:
substituteInPlace app/Config/Paths.php \
- --replace "__DIR__ . '/../../writable'" "'${stateDirectory}/writable'"
+ --replace "__DIR__ . '/../../writable'" "'${dataDir}/writable'"
- # configuration file must be writable, place it to ${stateDirectory}
+ substituteInPlace modules/Admin/Controllers/DashboardController.php \
+ --replace "disk_total_space('./')" "disk_total_space('${dataDir}')"
+
+ # configuration file must be writable, place it to ${dataDir}
substituteInPlace modules/Install/Controllers/InstallController.php \
- --replace "ROOTPATH" "'${stateDirectory}/'"
+ --replace "ROOTPATH" "'${dataDir}/'"
substituteInPlace public/index.php spark \
- --replace "DotEnv(ROOTPATH)" "DotEnv('${stateDirectory}')"
+ --replace "DotEnv(ROOTPATH)" "DotEnv('${dataDir}')"
# ffmpeg is required for Video Clips feature
substituteInPlace modules/MediaClipper/VideoClipper.php \
From 45d43fe39fa3167d5cf7ba9a2cb9fcd6fbe2c5c3 Mon Sep 17 00:00:00 2001
From: Alexander Tomokhov <alexoundos@gmail.com>
Date: Mon, 11 Dec 2023 09:00:26 +0400
Subject: [PATCH 3/8] nixos/castopod: little documentation fix
---
nixos/modules/services/web-apps/castopod.nix | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/nixos/modules/services/web-apps/castopod.nix b/nixos/modules/services/web-apps/castopod.nix
index 7c99551c83183f..11cf4b36aeb385 100644
--- a/nixos/modules/services/web-apps/castopod.nix
+++ b/nixos/modules/services/web-apps/castopod.nix
@@ -126,9 +126,10 @@ in
Maximum supported size for a file upload in MiB. Maximum HTTP body
size is set to this value for nginx and PHP (because castopod doesn't
support chunked uploads yet:
- https://code.castopod.org/adaures/castopod/-/issues/330). Note, that
- practical upload size limit is smaller. For example, with 512 MiB
- setting - around 500 MiB is possible.
+ https://code.castopod.org/adaures/castopod/-/issues/330).
+
+ Note, that practical upload size limit is smaller. For example, with
+ 512 MiB setting - around 500 MiB is possible.
'';
};
};
From 4aafd48b7e76748eaf0ff7409b12b455d1db31ec Mon Sep 17 00:00:00 2001
From: sinavir <sinavir@sinavir.fr>
Date: Fri, 23 Feb 2024 22:02:10 +0100
Subject: [PATCH 4/8] castopod: 1.6.5 -> 1.10.3
---
pkgs/applications/audio/castopod/default.nix | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkgs/applications/audio/castopod/default.nix b/pkgs/applications/audio/castopod/default.nix
index badace09587d2b..438f1d728f9624 100644
--- a/pkgs/applications/audio/castopod/default.nix
+++ b/pkgs/applications/audio/castopod/default.nix
@@ -10,8 +10,8 @@ stdenv.mkDerivation {
version = "1.6.5";
src = fetchurl {
- url = "https://code.castopod.org/adaures/castopod/uploads/5aaaa6cf2edaed25bd7253449e5f8584/castopod-1.6.5.tar.gz";
- sha256 = "04gcq2vmfy5aa2fmsm1qqv1k8g024nikmysdrhy33wj460d529b5";
+ url = "https://code.castopod.org/adaures/castopod/uploads/2bb52d4607a772ac8b397efa3559a3ae/castopod-1.10.3.tar.gz";
+ sha256 = "0w1yl14v3aajm089vwpq9wkiibv3w312y004ggdbf7xwzsrmjs51";
};
dontBuild = true;
From 6205595efbdcc2f3440022b4ff7258e2f50a6427 Mon Sep 17 00:00:00 2001
From: sinavir <sinavir@sinavir.fr>
Date: Fri, 23 Feb 2024 22:27:24 +0100
Subject: [PATCH 6/8] nixos/castopod: use LoadCredentials
---
nixos/modules/services/web-apps/castopod.nix | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/nixos/modules/services/web-apps/castopod.nix b/nixos/modules/services/web-apps/castopod.nix
index 11cf4b36aeb385..042fb3954d2b73 100644
--- a/nixos/modules/services/web-apps/castopod.nix
+++ b/nixos/modules/services/web-apps/castopod.nix
@@ -67,6 +67,8 @@ in
description = lib.mdDoc ''
A file containing the password corresponding to
[](#opt-services.castopod.database.user).
+
+ This file is loaded using systemd LoadCredentials.
'';
};
};
@@ -93,6 +95,8 @@ in
Environment file to inject e.g. secrets into the configuration.
See [](https://code.castopod.org/adaures/castopod/-/blob/main/.env.example)
for available environment variables.
+
+ This file is loaded using systemd LoadCredentials.
'';
};
configureNginx = lib.mkOption {
@@ -207,19 +211,23 @@ in
echo "analytics.salt=$(cat ${cfg.dataDir}/salt)" >> ${envFile}
${if (cfg.database.passwordFile != null) then ''
- echo "database.default.password=$(cat ${lib.escapeShellArg cfg.database.passwordFile})" >> ${envFile}
+ echo "database.default.password=$(cat "$CREDENTIALS_DIRECTORY/dbpasswordfile)" >> ${envFile}
'' else ''
echo "database.default.password=" >> ${envFile}
''}
${lib.optionalString (cfg.environmentFile != null) ''
- cat ${lib.escapeShellArg cfg.environmentFile} >> ${envFile}
+ cat "$CREDENTIALS_DIRECTORY/envfile" >> ${envFile}
''}
php ${cfg.package}/share/castopod/spark castopod:database-update
'';
serviceConfig = {
StateDirectory = "castopod";
+ LoadCredential = lib.optional (cfg.environmentFile != null)
+ "envfile:${cfg.environmentFile}"
+ ++ (lib.optional (cfg.database.passwordFile != null)
+ "dbpasswordfile:${cfg.database.passwordFile}");
WorkingDirectory = "${cfg.package}/share/castopod";
Type = "oneshot";
RemainAfterExit = true;
From 9b03fc35a30671e5d4146bbcbe6b5536fa9baacc Mon Sep 17 00:00:00 2001
From: sinavir <sinavir@sinavir.fr>
Date: Sat, 2 Mar 2024 18:01:54 +0100
Subject: [PATCH 7/8] nixos/castopod: build mp3 in the test
---
nixos/tests/castopod.nix | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/nixos/tests/castopod.nix b/nixos/tests/castopod.nix
index 2db7aa0bda6507..2bdc6941c23815 100644
--- a/nixos/tests/castopod.nix
+++ b/nixos/tests/castopod.nix
@@ -37,14 +37,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
targetPodcastDuration = toString
((targetPodcastSize + lameMp3FileAdjust) / (lameMp3Bitrate / 8));
mp3file = with pkgs;
- runCommand "gen-castopod.mp3" { nativeBuildInputs = [ sox lame ]; } ''
- sox -n -r 48000 -t wav - synth ${targetPodcastDuration} sine 440 `
- `| lame --noreplaygain -cbr -q 9 -b 320 - $out
- FILESIZE="$(stat -c%s $out)"
- [ "$FILESIZE" -gt 0 ]
- [ "$FILESIZE" -le "${toString targetPodcastSize}" ]
- '';
-
+ runCommand ;
bannerWidth = 3000;
banner = pkgs.runCommand "gen-castopod-cover.jpg" { } ''
${pkgs.imagemagick}/bin/magick `
@@ -185,7 +178,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
# upload podcast ###################################################
driver.find_element(By.CSS_SELECTOR, '#audio_file').send_keys(
- '${mp3file}'
+ '/tmp/podcast.mp3'
)
driver.find_element(By.CSS_SELECTOR, '#cover').send_keys(
'${cover}'
@@ -206,7 +199,23 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
driver.quit()
'';
in
- [ pkgs.firefox-unwrapped pkgs.geckodriver browser-test ];
+ [
+ pkgs.firefox-unwrapped
+ pkgs.geckodriver
+ browser-test
+ (pkgs.writeShellApplication {
+ name = "build-mp3";
+ runtimeInputs = with pkgs; [ sox lame ];
+ text = ''
+ out=/tmp/podcast.mp3
+ sox -n -r 48000 -t wav - synth ${targetPodcastDuration} sine 440 `
+ `| lame --noreplaygain -cbr -q 9 -b 320 - $out
+ FILESIZE="$(stat -c%s $out)"
+ [ "$FILESIZE" -gt 0 ]
+ [ "$FILESIZE" -le "${toString targetPodcastSize}" ]
+ '';
+ })
+ ];
};
testScript = ''
@@ -217,6 +226,8 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
castopod.wait_for_open_port(80)
castopod.wait_until_succeeds("curl -sS -f http://castopod.example.com")
+ client.succeed("build-mp3")
+
with subtest("Create superadmin, log in, create and upload a podcast"):
client.succeed(\
"PYTHONUNBUFFERED=1 systemd-cat -t browser-test browser-test")
From 538281e8be427f820371f4005e991e0281872e12 Mon Sep 17 00:00:00 2001
From: sinavir <sinavir@sinavir.fr>
Date: Sat, 2 Mar 2024 18:04:35 +0100
Subject: [PATCH 8/8] nixos/castopod: Increase test timeouts
---
nixos/tests/castopod.nix | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nixos/tests/castopod.nix b/nixos/tests/castopod.nix
index 2bdc6941c23815..2c5c745f7da0df 100644
--- a/nixos/tests/castopod.nix
+++ b/nixos/tests/castopod.nix
@@ -105,7 +105,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
driver.get('http://${domain}/cp-install')
- wait = WebDriverWait(driver, 10)
+ wait = WebDriverWait(driver, 20)
wait.until(EC.title_contains("installer"))

View file

@ -1,28 +0,0 @@
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -131,6 +131,7 @@
(mkRemovedOptionModule [ "services" "nextcloud" "disableImagemagick" ] ''
Use services.nextcloud.enableImagemagick instead.
'')
+ (mkRenamedOptionModule [ "services" "nextcloud" "config" "objectstore" "s3" "autocreate" ] [ "services" "nextcloud" "config" "objectstore" "s3" "verify_bucket_exists" ])
];
options.services.nextcloud = {
@@ -487,7 +487,7 @@
The name of the S3 bucket.
'';
};
- autocreate = mkOption {
+ verify_bucket_exists = mkOption {
type = types.bool;
description = lib.mdDoc ''
Create the objectstore if it does not exist.
@@ -820,7 +820,7 @@
'class' => '\\OC\\Files\\ObjectStore\\S3',
'arguments' => [
'bucket' => '${s3.bucket}',
- 'autocreate' => ${boolToString s3.autocreate},
+ 'verify_bucket_exists' => ${boolToString s3.verify_bucket_exists},
'key' => '${s3.key}',
'secret' => nix_read_secret('${s3.secretFile}'),
${optionalString (s3.hostname != null) "'hostname' => '${s3.hostname}',"}

View file

@ -1,24 +0,0 @@
diff --git a/pkgs/by-name/cr/crabfit-frontend/package.nix b/pkgs/by-name/cr/crabfit-frontend/package.nix
index 99d7be0fdeae..9f858e8a9a9e 100644
--- a/pkgs/by-name/cr/crabfit-frontend/package.nix
+++ b/pkgs/by-name/cr/crabfit-frontend/package.nix
@@ -8,7 +8,7 @@
nodejs,
yarn,
fixup_yarn_lock,
- google-fonts,
+ karla,
api_url ? "http://127.0.0.1:3000",
frontend_url ? "crab.fit",
}:
@@ -83,9 +83,7 @@ stdenv.mkDerivation (finalAttrs: {
patchShebangs node_modules
mkdir -p src/app/fonts
- cp "${
- google-fonts.override { fonts = [ "Karla" ]; }
- }/share/fonts/truetype/Karla[wght].ttf" src/app/fonts/karla.ttf
+ cp "${karla}/share/fonts/truetype/Karla-Regular.ttf" src/app/fonts/karla.ttf
runHook postConfigure
'';

View file

@ -1,54 +0,0 @@
From 4d6e57d2d577cc105c9e0cd397408e9e3ce85cd0 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Tue, 8 Oct 2024 16:33:14 +0200
Subject: [PATCH] fix(packaging): correctness of the build top directory
It was using /build which is an implementation detail and not
guaranteed.
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
pkgs/pve-container/default.nix | 6 +++---
pkgs/pve-rs/default.nix | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pkgs/pve-container/default.nix b/pkgs/pve-container/default.nix
index 445c271..5633c0f 100644
--- a/pkgs/pve-container/default.nix
+++ b/pkgs/pve-container/default.nix
@@ -30,7 +30,7 @@ perl536.pkgs.toPerlModule (
postPatch = ''
sed -i Makefile \
-e "s/pct.1 pct.conf.5 pct.bash-completion pct.zsh-completion //" \
- -e "s,/usr/share/lxc,/build/lxc," \
+ -e "s,/usr/share/lxc,$NIX_BUILD_TOP/lxc," \
-e "/pve-doc-generator/d" \
-e "/PVE_GENERATING_DOCS/d" \
-e "/SERVICEDIR/d" \
@@ -45,8 +45,8 @@ perl536.pkgs.toPerlModule (
dontPatchShebangs = true;
postConfigure = ''
- cp -r ${lxc}/share/lxc /build
- chmod -R +w /build/lxc
+ cp -r ${lxc}/share/lxc $NIX_BUILD_TOP/
+ chmod -R +w $NIX_BUILD_TOP/lxc
'';
makeFlags = [
diff --git a/pkgs/pve-rs/default.nix b/pkgs/pve-rs/default.nix
index c024287..881beab 100644
--- a/pkgs/pve-rs/default.nix
+++ b/pkgs/pve-rs/default.nix
@@ -57,7 +57,7 @@ perl536.pkgs.toPerlModule (
];
makeFlags = [
- "BUILDIR=/build"
+ "BUILDIR=$NIX_BUILD_TOP"
"BUILD_MODE=release"
"DESTDIR=$(out)"
"GITVERSION:=${src.rev}"
--
2.46.0

View file

@ -6,131 +6,9 @@ let
in
{
"nixos-24.05" = [
# netbox qrcode plugin
{
_type = "commit";
sha = "ae4bf4c110378ebacb3989c9533726859cfebbfa";
hash = "sha256-SgHhW9HCkDQsxT3eG4P9q68c43e3sbDHRY9qs7oSt8o=";
}
"nixos-24.05" = [ netboxAgent ];
netboxAgent
"nixos-unstable" = [ netboxAgent ];
{
id = "275165";
hash = "sha256-9a26V3Pi8yLD3N9+mC1kvJoruxRTp/qOHapnt6VX7pw=";
}
# karla: init at 2.004
{
_type = "commit";
sha = "7c51104112e8ea0e2ac53bf7d535e677f7686a9e";
hash = "sha256-1TBLzZkvkFhCL8RYVVIUhTyrH3+X1iJIMkyHffmrOWc=";
}
# Crabfit: don't depend on all google-fonts
{
_type = "static";
path = ./04-crabfit-karla.patch;
}
];
"nixos-23.11" = [
# netbox module
{
_type = "commit";
sha = "163fed297ed65a24241f190d8e954ce1877f9020";
includes = [ "nixos/modules/services/web-apps/netbox.nix" ];
hash = "sha256-mjeRxtZozgLNzHkCxcTs3xnonNPkmPoaGxawixC9jfo=";
}
# netbox qrcode plugin
{
_type = "commit";
sha = "ae4bf4c110378ebacb3989c9533726859cfebbfa";
hash = "sha256-SgHhW9HCkDQsxT3eG4P9q68c43e3sbDHRY9qs7oSt8o=";
}
netboxAgent
# missing jsonargparse deps for netbox-agent
{
# json arg parse dep: typesched-client
_type = "commit";
sha = "b1770afd23a7a1ebb4e5bccd8d34dfb3a58a4341";
hash = "sha256-PNUOPgmNFQr+bwG8MQiwlI4+zkDKLL3e1GgHHskX/Dk=";
}
{
# json arg parse dep: reconplogger
_type = "commit";
sha = "3835e47059eee32eaf5ef0eb03fce90e8c9b8ab4";
hash = "sha256-owJL1nmYfEXSHekBGgbJrTkl3OpX6dG9oq3mjN4Xgj8=";
}
{
# json arg parse dep: logmatic
_type = "commit";
sha = "b0de35af031b4282ac99919384f029a18704d819";
hash = "sha256-0nJzF2WMPNs2/zI65T1j9DQ0kORDKCu3H2PWjd/bXuo=";
}
{
# init at 4.27.2
_type = "commit";
sha = "aa724f81163725b54a06623d191de6d4c064c5ea";
hash = "sha256-ZWOVpVVsmjBCCiMe/j4YKz6YP4m5I8TTbqWNqBaMtKA=";
}
{
# 4.27.2 -> 4.27.3
id = "284460";
hash = "sha256-di9F8d5l0QDWt9yNpamHMyMm4AVxnsRko8+/Ruo7G3I=";
}
{
# 4.27.3 -> 4.27.4
id = "285873";
hash = "sha256-GRytcYvIsMP2RfHlmOJIH3po2/KmfZ3fDwo3YUyXGEU=";
}
{
# 4.27.4 -> 4.27.5
id = "288546";
hash = "sha256-iHXwZQKlaWmbd9kJbm6YyjIc3bPFHGbIghYRCPsSGHo=";
}
{
# 4.27.5 -> 4.27.6
id = "296359";
hash = "sha256-BHevlu8eqkoRgxwFMoS9bkT/9+w0Hfp3JXWh6UKovUk=";
}
{
# 4.27.6 -> 4.27.7
id = "297825";
hash = "sha256-tu91+T1G/sHfCLfLL4Jk/zLU/QwnHLbpxiYzRBJXFXw=";
}
# castopod: 1.6.4 -> 1.7.0 + ajout du support de loadcredentials
{
_type = "static";
path = ./01-castopod.patch;
}
# nixos/nextcloud: Rename autocreate (a no-op) to verify_bucket_exists
{
_type = "static";
path = ./03-nextcloud.patch;
}
];
"nixos-unstable" = [
netboxAgent
# netbox qrcode plugin
{
_type = "commit";
sha = "ae4bf4c110378ebacb3989c9533726859cfebbfa";
hash = "sha256-SgHhW9HCkDQsxT3eG4P9q68c43e3sbDHRY9qs7oSt8o=";
}
];
"proxmox-nixos" = [
{
_type = "static";
path = ./05-pmnos-correctness-build-directory.patch;
}
];
"proxmox-nixos" = [ ];
}