Compare commits
7 commits
28783f14c5
...
f60b8243cd
Author | SHA1 | Date | |
---|---|---|---|
f60b8243cd | |||
c2e8ca5e33 | |||
|
eae18caa21 | ||
|
b8f729c290 | ||
|
2ac0a35c5e | ||
|
3ce077f92c | ||
|
16da0a275c |
21 changed files with 22 additions and 1819 deletions
|
@ -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
|
||||
|
|
|
@ -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; })
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Script pour installer automatiquement NixOS sur les machines de la DGNum
|
|
@ -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 ];
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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 ];
|
||||
}
|
||||
|
|
136
meta/dns.nix
136
meta/dns.nix
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
183
meta/network.nix
183
meta/network.nix
|
@ -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";
|
||||
};
|
||||
}
|
||||
|
|
106
meta/nodes.nix
106
meta/nodes.nix
|
@ -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";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 [ ]) != [ ];
|
||||
|
|
|
@ -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" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,10 +179,10 @@
|
|||
"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
|
||||
}
|
|
@ -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"))
|
||||
|
|
@ -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}',"}
|
|
@ -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
|
||||
'';
|
|
@ -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
|
||||
|
|
@ -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" = [ ];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue