Format everything, RFC-style

This commit is contained in:
Nicolas Jeannerod 2024-11-11 17:25:42 +01:00 committed by Valentin Gagarin
parent 9e234e7b2d
commit 81176a1a9a
16 changed files with 684 additions and 535 deletions

View file

@ -5,7 +5,8 @@ let
inherit (lib) mkOption mkEnableOption mkForce; inherit (lib) mkOption mkEnableOption mkForce;
inherit (lib.types) types; inherit (lib.types) types;
in { in
{
imports = [ imports = [
./garage.nix ./garage.nix
./mastodon.nix ./mastodon.nix

View file

@ -8,27 +8,49 @@ let
in in
# TODO: expand to a multi-machine setup # TODO: expand to a multi-machine setup
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (builtins) toString; inherit (builtins) toString;
inherit (lib) types mkOption mkEnableOption optionalString concatStringsSep; inherit (lib)
types
mkOption
mkEnableOption
optionalString
concatStringsSep
;
inherit (lib.strings) escapeShellArg; inherit (lib.strings) escapeShellArg;
inherit (lib.attrsets) filterAttrs mapAttrs'; inherit (lib.attrsets) filterAttrs mapAttrs';
cfg = config.services.garage; cfg = config.services.garage;
fedicfg = config.fediversity.internal.garage; fedicfg = config.fediversity.internal.garage;
concatMapAttrs = scriptFn: attrset: concatStringsSep "\n" (lib.mapAttrsToList scriptFn attrset); concatMapAttrs = scriptFn: attrset: concatStringsSep "\n" (lib.mapAttrsToList scriptFn attrset);
ensureBucketScriptFn = bucket: { website, aliases, corsRules }: ensureBucketScriptFn =
bucket:
{
website,
aliases,
corsRules,
}:
let let
bucketArg = escapeShellArg bucket; bucketArg = escapeShellArg bucket;
corsRulesJSON = escapeShellArg (builtins.toJSON { corsRulesJSON = escapeShellArg (
CORSRules = [{ builtins.toJSON {
CORSRules = [
{
AllowedHeaders = corsRules.allowedHeaders; AllowedHeaders = corsRules.allowedHeaders;
AllowedMethods = corsRules.allowedMethods; AllowedMethods = corsRules.allowedMethods;
AllowedOrigins = corsRules.allowedOrigins; AllowedOrigins = corsRules.allowedOrigins;
}]; }
}); ];
in '' }
);
in
''
# garage bucket info tells us if the bucket already exists # garage bucket info tells us if the bucket already exists
garage bucket info ${bucketArg} || garage bucket create ${bucketArg} garage bucket info ${bucketArg} || garage bucket create ${bucketArg}
@ -37,9 +59,11 @@ let
garage bucket website --allow ${bucketArg} garage bucket website --allow ${bucketArg}
''} ''}
${concatStringsSep "\n" (map (alias: '' ${concatStringsSep "\n" (
map (alias: ''
garage bucket alias ${bucketArg} ${escapeShellArg alias} garage bucket alias ${bucketArg} ${escapeShellArg alias}
'') aliases)} '') aliases
)}
${optionalString corsRules.enable '' ${optionalString corsRules.enable ''
garage bucket allow --read --write --owner ${bucketArg} --key tmp garage bucket allow --read --write --owner ${bucketArg} --key tmp
@ -49,11 +73,25 @@ let
''} ''}
''; '';
ensureBucketsScript = concatMapAttrs ensureBucketScriptFn cfg.ensureBuckets; ensureBucketsScript = concatMapAttrs ensureBucketScriptFn cfg.ensureBuckets;
ensureAccessScriptFn = key: bucket: { read, write, owner }: '' ensureAccessScriptFn =
key: bucket:
{
read,
write,
owner,
}:
''
garage bucket allow ${optionalString read "--read"} ${optionalString write "--write"} ${optionalString owner "--owner"} \ garage bucket allow ${optionalString read "--read"} ${optionalString write "--write"} ${optionalString owner "--owner"} \
${escapeShellArg bucket} --key ${escapeShellArg key} ${escapeShellArg bucket} --key ${escapeShellArg key}
''; '';
ensureKeyScriptFn = key: {id, secret, ensureAccess}: '' ensureKeyScriptFn =
key:
{
id,
secret,
ensureAccess,
}:
''
## FIXME: Check whether the key exist and skip this step if that is the case. Get rid of this `|| :` ## FIXME: Check whether the key exist and skip this step if that is the case. Get rid of this `|| :`
garage key import --yes -n ${escapeShellArg key} ${escapeShellArg id} ${escapeShellArg secret} || : garage key import --yes -n ${escapeShellArg key} ${escapeShellArg id} ${escapeShellArg secret} || :
${concatMapAttrs (ensureAccessScriptFn key) ensureAccess} ${concatMapAttrs (ensureAccessScriptFn key) ensureAccess}
@ -66,7 +104,8 @@ in
options = { options = {
services.garage = { services.garage = {
ensureBuckets = mkOption { ensureBuckets = mkOption {
type = types.attrsOf (types.submodule { type = types.attrsOf (
types.submodule {
options = { options = {
website = mkOption { website = mkOption {
type = types.bool; type = types.bool;
@ -93,11 +132,13 @@ in
default = [ ]; default = [ ];
}; };
}; };
}); }
);
default = { }; default = { };
}; };
ensureKeys = mkOption { ensureKeys = mkOption {
type = types.attrsOf (types.submodule { type = types.attrsOf (
types.submodule {
# TODO: these should be managed as secrets, not in the nix store # TODO: these should be managed as secrets, not in the nix store
options = { options = {
id = mkOption { id = mkOption {
@ -109,7 +150,8 @@ in
# TODO: assert at least one of these is true # TODO: assert at least one of these is true
# NOTE: this currently needs to be done at the top level module # NOTE: this currently needs to be done at the top level module
ensureAccess = mkOption { ensureAccess = mkOption {
type = types.attrsOf (types.submodule { type = types.attrsOf (
types.submodule {
options = { options = {
read = mkOption { read = mkOption {
type = types.bool; type = types.bool;
@ -124,18 +166,23 @@ in
default = false; default = false;
}; };
}; };
}); }
);
default = [ ]; default = [ ];
}; };
}; };
}); }
);
default = { }; default = { };
}; };
}; };
}; };
config = lib.mkIf config.fediversity.enable { config = lib.mkIf config.fediversity.enable {
environment.systemPackages = [ pkgs.minio-client pkgs.awscli ]; environment.systemPackages = [
pkgs.minio-client
pkgs.awscli
];
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
fedicfg.rpc.port fedicfg.rpc.port
@ -178,9 +225,11 @@ in
''; '';
}; };
}; };
in mapAttrs' in
(bucket: _: {name = fedicfg.web.domainForBucket bucket; inherit value;}) mapAttrs' (bucket: _: {
(filterAttrs (_: {website, ...}: website) cfg.ensureBuckets); name = fedicfg.web.domainForBucket bucket;
inherit value;
}) (filterAttrs (_: { website, ... }: website) cfg.ensureBuckets);
systemd.services.ensure-garage = { systemd.services.ensure-garage = {
after = [ "garage.service" ]; after = [ "garage.service" ];
@ -188,7 +237,11 @@ in
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
}; };
path = [ cfg.package pkgs.perl pkgs.awscli ]; path = [
cfg.package
pkgs.perl
pkgs.awscli
];
script = '' script = ''
set -xeuo pipefail set -xeuo pipefail

View file

@ -5,7 +5,12 @@ let
}; };
in in
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
lib.mkIf (config.fediversity.enable && config.fediversity.mastodon.enable) { lib.mkIf (config.fediversity.enable && config.fediversity.mastodon.enable) {
#### garage setup #### garage setup
@ -58,7 +63,10 @@ lib.mkIf (config.fediversity.enable && config.fediversity.mastodon.enable) {
#### mastodon setup #### mastodon setup
# open up access to the mastodon web interface. 80 is necessary if only for ACME # open up access to the mastodon web interface. 80 is necessary if only for ACME
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [
80
443
];
services.mastodon = { services.mastodon = {
enable = true; enable = true;

View file

@ -5,10 +5,18 @@ let
}; };
in in
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
lib.mkIf (config.fediversity.enable && config.fediversity.peertube.enable) { lib.mkIf (config.fediversity.enable && config.fediversity.peertube.enable) {
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [
80
443
];
services.garage = { services.garage = {
ensureBuckets = { ensureBuckets = {

View file

@ -5,7 +5,12 @@ let
}; };
in in
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
lib.mkIf (config.fediversity.enable && config.fediversity.pixelfed.enable) { lib.mkIf (config.fediversity.enable && config.fediversity.pixelfed.enable) {
services.garage = { services.garage = {
@ -80,5 +85,8 @@ lib.mkIf (config.fediversity.enable && config.fediversity.pixelfed.enable) {
after = [ "ensure-garage.service" ]; after = [ "ensure-garage.service" ];
}; };
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [
80
443
];
} }

View file

@ -9,20 +9,30 @@
disko.url = "github:nix-community/disko"; disko.url = "github:nix-community/disko";
}; };
outputs = { self, nixpkgs, nixpkgs-latest, pixelfed, disko }: outputs =
{
self,
nixpkgs,
nixpkgs-latest,
pixelfed,
disko,
}:
let let
system = "x86_64-linux"; system = "x86_64-linux";
lib = nixpkgs.lib; lib = nixpkgs.lib;
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
pkgsLatest = nixpkgs-latest.legacyPackages.${system}; pkgsLatest = nixpkgs-latest.legacyPackages.${system};
bleedingFediverseOverlay = (self: super: { bleedingFediverseOverlay = (
self: super: {
pixelfed = pkgsLatest.pixelfed.overrideAttrs (old: { pixelfed = pkgsLatest.pixelfed.overrideAttrs (old: {
src = pixelfed; src = pixelfed;
patches = (old.patches or [ ]) ++ [ ./fediversity/pixelfed-group-permissions.patch ]; patches = (old.patches or [ ]) ++ [ ./fediversity/pixelfed-group-permissions.patch ];
}); });
## TODO: give mastodon, peertube the same treatment ## TODO: give mastodon, peertube the same treatment
}); }
in { );
in
{
nixosModules = { nixosModules = {
## Bleeding-edge fediverse packages ## Bleeding-edge fediverse packages
bleedingFediverse = { bleedingFediverse = {

View file

@ -4,15 +4,22 @@
WARNING: Running this installer will format the target disk! WARNING: Running this installer will format the target disk!
*/ */
{ nixpkgs, {
hostKeys ? {} nixpkgs,
hostKeys ? { },
}: }:
machine: machine:
let let
inherit (builtins) concatStringsSep attrValues mapAttrs; inherit (builtins) concatStringsSep attrValues mapAttrs;
installer = { config, pkgs, lib, ... }: installer =
{
config,
pkgs,
lib,
...
}:
let let
bootstrap = pkgs.writeShellApplication { bootstrap = pkgs.writeShellApplication {
name = "bootstrap"; name = "bootstrap";
@ -20,20 +27,16 @@ let
text = '' text = ''
${machine.config.system.build.diskoScript} ${machine.config.system.build.diskoScript}
nixos-install --no-root-password --no-channel-copy --system ${machine.config.system.build.toplevel} nixos-install --no-root-password --no-channel-copy --system ${machine.config.system.build.toplevel}
${ ${concatStringsSep "\n" (
concatStringsSep "\n" (
attrValues ( attrValues (
mapAttrs mapAttrs (kind: keys: ''
(kind: keys: ''
cp ${keys.private} /mnt/etc/ssh/ssh_host_${kind}_key cp ${keys.private} /mnt/etc/ssh/ssh_host_${kind}_key
chmod 600 /mnt/etc/ssh/ssh_host_${kind}_key chmod 600 /mnt/etc/ssh/ssh_host_${kind}_key
cp ${keys.public} /mnt/etc/ssh/ssh_host_${kind}_key.pub cp ${keys.public} /mnt/etc/ssh/ssh_host_${kind}_key.pub
chmod 644 /mnt/etc/ssh/ssh_host_${kind}_key.pub chmod 644 /mnt/etc/ssh/ssh_host_${kind}_key.pub
'') '') hostKeys
hostKeys
) )
) )}
}
poweroff poweroff
''; '';
}; };

View file

@ -2,10 +2,12 @@
let let
lib = pkgs.lib; lib = pkgs.lib;
rebuildableTest = import ./rebuildableTest.nix pkgs; rebuildableTest = import ./rebuildableTest.nix pkgs;
seleniumScript = pkgs.writers.writePython3Bin "selenium-script" seleniumScript =
pkgs.writers.writePython3Bin "selenium-script"
{ {
libraries = with pkgs.python3Packages; [ selenium ]; libraries = with pkgs.python3Packages; [ selenium ];
} '' }
''
from selenium import webdriver from selenium import webdriver
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options from selenium.webdriver.firefox.options import Options
@ -35,7 +37,9 @@ pkgs.nixosTest {
name = "test-mastodon-garage"; name = "test-mastodon-garage";
nodes = { nodes = {
server = { config, ... }: { server =
{ config, ... }:
{
virtualisation.memorySize = lib.mkVMOverride 4096; virtualisation.memorySize = lib.mkVMOverride 4096;
imports = with self.nixosModules; [ imports = with self.nixosModules; [
bleedingFediverse bleedingFediverse
@ -62,7 +66,9 @@ pkgs.nixosTest {
}; };
}; };
testScript = { nodes, ... }: '' testScript =
{ nodes, ... }:
''
import re import re
import time import time

View file

@ -50,10 +50,12 @@ let
driver.quit() driver.quit()
''; '';
seleniumScriptPostPicture = pkgs.writers.writePython3Bin "selenium-script-post-picture" seleniumScriptPostPicture =
pkgs.writers.writePython3Bin "selenium-script-post-picture"
{ {
libraries = with pkgs.python3Packages; [ selenium ]; libraries = with pkgs.python3Packages; [ selenium ];
} '' }
''
import os import os
import time import time
${seleniumImports} ${seleniumImports}
@ -93,10 +95,12 @@ let
${seleniumTakeScreenshot "\"/home/selenium/screenshot.png\""} ${seleniumTakeScreenshot "\"/home/selenium/screenshot.png\""}
${seleniumQuit}''; ${seleniumQuit}'';
seleniumScriptGetSrc = pkgs.writers.writePython3Bin "selenium-script-get-src" seleniumScriptGetSrc =
pkgs.writers.writePython3Bin "selenium-script-get-src"
{ {
libraries = with pkgs.python3Packages; [ selenium ]; libraries = with pkgs.python3Packages; [ selenium ];
} '' }
''
${seleniumImports} ${seleniumImports}
${seleniumSetup} ${seleniumSetup}
${seleniumPixelfedLogin} ${seleniumPixelfedLogin}
@ -115,7 +119,9 @@ pkgs.nixosTest {
name = "test-pixelfed-garage"; name = "test-pixelfed-garage";
nodes = { nodes = {
server = { config, ... }: { server =
{ config, ... }:
{
services = { services = {
xserver = { xserver = {
@ -129,8 +135,10 @@ pkgs.nixosTest {
user = "selenium"; user = "selenium";
}; };
}; };
virtualisation.resolution = { x = 1680; y = 1050; }; virtualisation.resolution = {
x = 1680;
y = 1050;
};
virtualisation = { virtualisation = {
memorySize = lib.mkVMOverride 8192; memorySize = lib.mkVMOverride 8192;
@ -167,7 +175,9 @@ pkgs.nixosTest {
}; };
}; };
testScript = { nodes, ... }: '' testScript =
{ nodes, ... }:
''
import re import re
server.start() server.start()

View file

@ -1,9 +1,16 @@
pkgs: test: pkgs: test:
let let
inherit (pkgs.lib) mapAttrsToList concatStringsSep genAttrs mkIf; inherit (pkgs.lib)
mapAttrsToList
concatStringsSep
genAttrs
mkIf
;
inherit (builtins) attrNames; inherit (builtins) attrNames;
interactiveConfig = ({ config, ... }: { interactiveConfig = (
{ config, ... }:
{
# so we can run `nix shell nixpkgs#foo` on the machines # so we can run `nix shell nixpkgs#foo` on the machines
nix.extraOptions = '' nix.extraOptions = ''
extra-experimental-features = nix-command flakes extra-experimental-features = nix-command flakes
@ -20,13 +27,16 @@ let
}; };
virtualisation = mkIf (config.networking.hostName == "jumphost") { virtualisation = mkIf (config.networking.hostName == "jumphost") {
forwardPorts = [{ forwardPorts = [
{
from = "host"; from = "host";
host.port = 2222; host.port = 2222;
guest.port = 22; guest.port = 22;
}]; }
];
}; };
}); }
);
sshConfig = pkgs.writeText "ssh-config" '' sshConfig = pkgs.writeText "ssh-config" ''
Host * Host *
@ -50,10 +60,11 @@ let
# create an association array from machine names to the path to their # create an association array from machine names to the path to their
# configuration in the nix store # configuration in the nix store
declare -A configPaths=(${ declare -A configPaths=(${
concatStringsSep " " concatStringsSep " " (
(mapAttrsToList mapAttrsToList (
(n: v: ''["${n}"]="${v.system.build.toplevel}"'') n: v: ''["${n}"]="${v.system.build.toplevel}"''
rebuildableTest.driverInteractive.nodes) ) rebuildableTest.driverInteractive.nodes
)
}) })
rebuild_one() { rebuild_one() {
@ -113,16 +124,14 @@ let
# we're at it) # we're at it)
rebuildableTest = rebuildableTest =
let let
preOverride = pkgs.nixosTest (test // { preOverride = pkgs.nixosTest (
test
// {
interactive = (test.interactive or { }) // { interactive = (test.interactive or { }) // {
# no need to // with test.interactive.nodes here, since we are iterating # no need to // with test.interactive.nodes here, since we are iterating
# over all of them, and adding back in the config via `imports` # over all of them, and adding back in the config via `imports`
nodes = genAttrs nodes =
( genAttrs (attrNames test.nodes or { } ++ attrNames test.interactive.nodes or { } ++ [ "jumphost" ])
attrNames test.nodes or { } ++
attrNames test.interactive.nodes or { } ++
[ "jumphost" ]
)
(n: { (n: {
imports = [ imports = [
(test.interactive.${n} or { }) (test.interactive.${n} or { })
@ -131,14 +140,20 @@ let
}); });
}; };
# override with test.passthru in case someone wants to overwrite us. # override with test.passthru in case someone wants to overwrite us.
passthru = { inherit rebuildScript sshConfig; } // (test.passthru or { }); passthru = {
}); inherit rebuildScript sshConfig;
} // (test.passthru or { });
}
);
in in
preOverride // { preOverride
// {
driverInteractive = preOverride.driverInteractive.overrideAttrs (old: { driverInteractive = preOverride.driverInteractive.overrideAttrs (old: {
# this comes from runCommand, not mkDerivation, so this is the only # this comes from runCommand, not mkDerivation, so this is the only
# hook we have to override # hook we have to override
buildCommand = old.buildCommand + '' buildCommand =
old.buildCommand
+ ''
ln -s ${sshConfig} $out/ssh-config ln -s ${sshConfig} $out/ssh-config
ln -s ${rebuildScript}/bin/rebuild $out/bin/rebuild ln -s ${rebuildScript}/bin/rebuild $out/bin/rebuild
''; '';
@ -146,4 +161,3 @@ let
}; };
in in
rebuildableTest rebuildableTest

View file

@ -1,4 +1,9 @@
{ lib, config, modulesPath, ... }: {
lib,
config,
modulesPath,
...
}:
let let
inherit (lib) mkVMOverride mapAttrs' filterAttrs; inherit (lib) mkVMOverride mapAttrs' filterAttrs;
@ -7,7 +12,8 @@ let
fedicfg = config.fediversity.internal.garage; fedicfg = config.fediversity.internal.garage;
in { in
{
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];
services.nginx.virtualHosts = services.nginx.virtualHosts =
@ -16,9 +22,11 @@ in {
forceSSL = mkVMOverride false; forceSSL = mkVMOverride false;
enableACME = mkVMOverride false; enableACME = mkVMOverride false;
}; };
in mapAttrs' in
(bucket: _: {name = fedicfg.web.domainForBucket bucket; inherit value;}) mapAttrs' (bucket: _: {
(filterAttrs (_: {website, ...}: website) cfg.ensureBuckets); name = fedicfg.web.domainForBucket bucket;
inherit value;
}) (filterAttrs (_: { website, ... }: website) cfg.ensureBuckets);
virtualisation.diskSize = 2048; virtualisation.diskSize = 2048;
virtualisation.forwardPorts = [ virtualisation.forwardPorts = [

View file

@ -1,5 +1,6 @@
# customize nixos-rebuild build-vm to be a bit more convenient # customize nixos-rebuild build-vm to be a bit more convenient
{ pkgs, ... }: { { pkgs, ... }:
{
# let us log in # let us log in
users.mutableUsers = false; users.mutableUsers = false;
users.users.root.hashedPassword = ""; users.users.root.hashedPassword = "";
@ -34,7 +35,10 @@
# no graphics. see nixos-shell # no graphics. see nixos-shell
virtualisation = { virtualisation = {
graphics = false; graphics = false;
qemu.consoles = [ "tty0" "hvc0" ]; qemu.consoles = [
"tty0"
"hvc0"
];
qemu.options = [ qemu.options = [
"-serial null" "-serial null"
"-device virtio-serial" "-device virtio-serial"
@ -45,7 +49,10 @@
}; };
# we can't forward port 80 or 443, so let's run nginx on a different port # we can't forward port 80 or 443, so let's run nginx on a different port
networking.firewall.allowedTCPPorts = [ 8443 8080 ]; networking.firewall.allowedTCPPorts = [
8443
8080
];
services.nginx.defaultSSLListenPort = 8443; services.nginx.defaultSSLListenPort = 8443;
services.nginx.defaultHTTPListenPort = 8080; services.nginx.defaultHTTPListenPort = 8080;
virtualisation.forwardPorts = [ virtualisation.forwardPorts = [

View file

@ -1,4 +1,10 @@
{ modulesPath, lib, config, ... }: { {
modulesPath,
lib,
config,
...
}:
{
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];

View file

@ -1,4 +1,5 @@
{ pkgs, modulesPath, ... }: { { pkgs, modulesPath, ... }:
{
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];

View file

@ -1,9 +1,15 @@
{ pkgs, lib, modulesPath, ... }: {
pkgs,
lib,
modulesPath,
...
}:
let let
inherit (lib) mkVMOverride; inherit (lib) mkVMOverride;
in { in
{
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];
fediversity = { fediversity = {