momo: NixOS 23.11, fix build (treefmt), move to flake-parts #262

Merged
teutat3s merged 12 commits from momo/nixos-23.11 into momo/main 2024-01-08 22:50:39 +00:00
20 changed files with 820 additions and 784 deletions
Showing only changes of commit 0212b85efc - Show all commits

View file

@ -36,8 +36,8 @@
erpnext.inputs.agenix.follows = "agenix";
};
outputs = inputs@{ self, ...}:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
outputs = inputs @ {self, ...}:
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
debug = true;
systems = [
"x86_64-linux"
@ -52,7 +52,12 @@
./overlays
];
perSystem = args@{ system, pkgs, config, ... }: {
perSystem = args @ {
system,
pkgs,
config,
...
}: {
_module.args = {
inherit inputs;
pkgs = import inputs.nixpkgs {
@ -61,7 +66,7 @@
inputs.agenix.overlays.default
];
};
unstable = import inputs.unstable { inherit system; };
unstable = import inputs.unstable {inherit system;};
};
devShells.default = pkgs.mkShell {

View file

@ -1,5 +1,8 @@
{ self, inputs, ...}:
{
self,
inputs,
...
}: {
flake = {
nixosConfigurations = {
pioneer-momo-koeln = self.nixos-flake.lib.mkLinuxSystem {

View file

@ -1,4 +1,4 @@
{ ... }: {
{...}: {
imports = [
./configuration.nix
./hardware-configuration.nix

View file

@ -1,5 +1,4 @@
{ lib }:
hostnames: {
{lib}: hostnames: {
"127.0.0.1" = hostnames;
"::1" = hostnames;
}

View file

@ -1,4 +1,8 @@
{ lib, inputs, ... }: {
{
lib,
inputs,
...
}: {
# Configuration common to all Linux systems
flake = {
lib = let
@ -10,9 +14,8 @@
#foo = callLibs ./foo.nix;
## In configs, they can be used under "lib.our"
deploy = import ./deploy.nix { inherit inputs lib; };
deploy = import ./deploy.nix {inherit inputs lib;};
addLocalHostname = callLibs ./add-local-hostname.nix;
recursiveMerge = callLibs ./recursive-merge.nix;
};
};
}

View file

@ -1,11 +1,13 @@
/*
* The contents of this file are adapted from digga
* https://github.com/divnix/digga
*
* Licensed under the MIT license
*/
{ lib, inputs }: let
* The contents of this file are adapted from digga
* https://github.com/divnix/digga
*
* Licensed under the MIT license
*/
{
lib,
inputs,
}: let
getFqdn = c: let
net = c.config.networking;
fqdn =

View file

@ -1,16 +0,0 @@
{ lib }:
attrList:
let
f = attrPath:
zipAttrsWith (
n: values:
if tail values == []
then head values
else if all isList values
then unique (concatLists values)
else if all isAttrs values
then f (attrPath ++ [n]) values
else last values
);
in
f [] attrList;

View file

@ -3,16 +3,24 @@
pkgs,
lib,
...
}:
let
}: let
cfg = config.services.ddclient;
boolToStr = bool: if bool then "yes" else "no";
boolToStr = bool:
if bool
then "yes"
else "no";
dataDir = "/var/lib/ddclient";
StateDirectory = builtins.baseNameOf dataDir;
RuntimeDirectory = StateDirectory;
usev4 = if cfg.usev4 != "" then "usev4=${cfg.usev4}" else "";
usev6 = if cfg.usev6 != "" then "usev6=${cfg.usev6}" else "";
usev4 =
if cfg.usev4 != ""
then "usev4=${cfg.usev4}"
else "";
usev6 =
if cfg.usev6 != ""
then "usev6=${cfg.usev6}"
else "";
configFile' = pkgs.writeText "ddclient.conf" ''
# This file can be used as a template for configFile or is automatically generated by Nix options.
@ -22,7 +30,11 @@ let
cache=${dataDir}/ddclient.cache
foreground=yes
login=${cfg.username}
password=${if cfg.protocol == "nsupdate" then "/run/${RuntimeDirectory}/ddclient.key" else "@password_placeholder@"}
password=${
if cfg.protocol == "nsupdate"
then "/run/${RuntimeDirectory}/ddclient.key"
else "@password_placeholder@"
}
protocol=${cfg.protocol}
${lib.optionalString (cfg.script != "") "script=${cfg.script}"}
${lib.optionalString (cfg.server != "") "server=${cfg.server}"}
@ -34,30 +46,43 @@ let
${cfg.extraConfig}
${lib.concatStringsSep "," cfg.domains}
'';
configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
configFile =
if (cfg.configFile != null)
then cfg.configFile
else configFile';
preStart = ''
install --mode=600 --owner=$USER ${configFile} /run/${RuntimeDirectory}/ddclient.conf
${lib.optionalString (cfg.configFile == null) (if (cfg.protocol == "nsupdate") then ''
${lib.optionalString (cfg.configFile == null) (
if (cfg.protocol == "nsupdate")
then ''
install --mode=600 --owner=$USER ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key
'' else if (cfg.passwordFile != null) then ''
''
else if (cfg.passwordFile != null)
then ''
"${pkgs.replace-secret}/bin/replace-secret" "@password_placeholder@" "${cfg.passwordFile}" "/run/${RuntimeDirectory}/ddclient.conf"
'' else ''
''
else ''
sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf
'')}
''
)}
'';
in with lib; {
in
with lib; {
disabledModules = [
"services/networking/ddclient.nix"
];
imports = [
(mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
(config:
let value = getAttrFromPath [ "services" "ddclient" "domain" ] config;
in if value != "" then [ value ] else []))
(mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
(mkRemovedOptionModule [ "services" "ddclient" "password" ] "Use services.ddclient.passwordFile instead.")
(mkChangedOptionModule ["services" "ddclient" "domain"] ["services" "ddclient" "domains"]
(config: let
value = getAttrFromPath ["services" "ddclient" "domain"] config;
in
if value != ""
then [value]
else []))
(mkRemovedOptionModule ["services" "ddclient" "homeDir"] "")
(mkRemovedOptionModule ["services" "ddclient" "password"] "Use services.ddclient.passwordFile instead.")
];
###### interface
@ -82,7 +107,7 @@ in with lib; {
};
domains = mkOption {
default = [ "" ];
default = [""];
type = listOf str;
description = lib.mdDoc ''
Domain name(s) to synchronize.
@ -212,14 +237,13 @@ in with lib; {
};
};
###### implementation
config = mkIf config.services.ddclient.enable {
systemd.services.ddclient = {
description = "Dynamic DNS Client";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
wantedBy = ["multi-user.target"];
after = ["network.target"];
restartTriggers = optional (cfg.configFile != null) cfg.configFile;
serviceConfig = {
@ -235,11 +259,11 @@ in with lib; {
systemd.timers.ddclient = {
description = "Run ddclient";
wantedBy = [ "timers.target" ];
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = cfg.interval;
OnUnitInactiveSec = cfg.interval;
};
};
};
}
}

View file

@ -37,5 +37,5 @@
# exit system mode: "Enter" or "Escape"
bindsym Return mode "default"
bindsym Escape mode "default"
}
}
''

View file

@ -24,7 +24,8 @@ in {
'';
};
environment.systemPackages = with pkgs; mkIf psCfg.graphical.v4l2loopback.enable [
environment.systemPackages = with pkgs;
mkIf psCfg.graphical.v4l2loopback.enable [
linuxPackages.v4l2loopback
];

View file

@ -1,14 +1,17 @@
{ config, pkgs, lib, ... }:
with lib;
let
{
config,
pkgs,
lib,
...
}:
with lib; let
cfg = config.services.invoiceplane;
eachSite = cfg.sites;
user = "invoiceplane";
webserver = config.services.${cfg.webserver};
invoiceplane-config = hostName: cfg: pkgs.writeText "ipconfig.php" ''
invoiceplane-config = hostName: cfg:
pkgs.writeText "ipconfig.php" ''
IP_URL=http://${hostName}
ENABLE_DEBUG=false
DISABLE_SETUP=false
@ -16,7 +19,11 @@ let
DB_HOSTNAME=${cfg.database.host}
DB_USERNAME=${cfg.database.user}
# NOTE: file_get_contents adds newline at the end of returned string
DB_PASSWORD=${if cfg.database.passwordFile == null then "" else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"}
DB_PASSWORD=${
if cfg.database.passwordFile == null
then ""
else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"
}
DB_DATABASE=${cfg.database.name}
DB_PORT=${toString cfg.database.port}
SESS_EXPIRATION=864000
@ -28,11 +35,13 @@ let
REMOVE_INDEXPHP=true
'';
extraConfig = hostName: cfg: pkgs.writeText "extraConfig.php" ''
extraConfig = hostName: cfg:
pkgs.writeText "extraConfig.php" ''
${toString cfg.extraConfig}
'';
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
pkg = hostName: cfg:
pkgs.stdenv.mkDerivation rec {
pname = "invoiceplane-${hostName}";
version = src.version;
src = pkgs.invoiceplane;
@ -64,10 +73,12 @@ let
'';
};
siteOpts = { lib, name, ... }:
{
siteOpts = {
lib,
name,
...
}: {
options = {
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
stateDir = mkOption {
@ -155,7 +166,7 @@ let
};
poolConfig = mkOption {
type = with types; attrsOf (oneOf [ str int bool ]);
type = with types; attrsOf (oneOf [str int bool]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
@ -186,7 +197,6 @@ let
};
cron = {
enable = mkOption {
type = types.bool;
default = false;
@ -202,14 +212,10 @@ let
type = types.str;
description = lib.mdDoc "Cron key taken from the administration page.";
};
};
};
};
in
{
in {
disabledModules = [
"services/web-apps/invoiceplane.nix"
];
@ -218,7 +224,6 @@ in
options = {
services.invoiceplane = mkOption {
type = types.submodule {
options.sites = mkOption {
type = types.attrsOf (types.submodule siteOpts);
default = {};
@ -226,7 +231,7 @@ in
};
options.webserver = mkOption {
type = types.enum [ "caddy" ];
type = types.enum ["caddy"];
default = "caddy";
description = lib.mdDoc ''
Which webserver to use for virtual host management. Currently only
@ -237,53 +242,61 @@ in
default = {};
description = lib.mdDoc "InvoicePlane configuration.";
};
};
# implementation
config = mkIf (eachSite != {}) (mkMerge [{
assertions = flatten (mapAttrsToList (hostName: cfg:
[{ assertion = cfg.database.createLocally -> cfg.database.user == user;
config = mkIf (eachSite != {}) (mkMerge [
{
assertions = flatten (mapAttrsToList (hostName: cfg: [
{
assertion = cfg.database.createLocally -> cfg.database.user == user;
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
}
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
{
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.'';
}
{ assertion = cfg.cron.enable -> cfg.cron.key != null;
{
assertion = cfg.cron.enable -> cfg.cron.key != null;
message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.'';
}
]) eachSite);
])
eachSite);
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
enable = true;
package = mkDefault pkgs.mariadb;
ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite;
ensureUsers = mapAttrsToList (hostName: cfg:
{ name = cfg.database.user;
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
ensureUsers =
mapAttrsToList (
hostName: cfg: {
name = cfg.database.user;
ensurePermissions = {"${cfg.database.name}.*" = "ALL PRIVILEGES";};
}
) eachSite;
)
eachSite;
};
services.phpfpm = {
phpPackage = pkgs.php81;
pools = mapAttrs' (hostName: cfg: (
pools =
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-${hostName}" {
inherit user;
group = webserver.group;
settings = {
settings =
{
"listen.owner" = webserver.user;
"listen.group" = webserver.group;
} // cfg.poolConfig;
}
)) eachSite;
// cfg.poolConfig;
}
))
eachSite;
};
}
{
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
"d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -"
"f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -"
@ -294,41 +307,42 @@ in
"d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
]) eachSite);
])
eachSite);
systemd.services.invoiceplane-config = {
serviceConfig.Type = "oneshot";
script = concatStrings (mapAttrsToList (hostName: cfg:
''
script = concatStrings (mapAttrsToList (hostName: cfg: ''
mkdir -p ${cfg.stateDir}/logs \
${cfg.stateDir}/uploads
if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then
cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php"
fi
'') eachSite);
wantedBy = [ "multi-user.target" ];
'')
eachSite);
wantedBy = ["multi-user.target"];
};
users.users.${user} = {
group = webserver.group;
isSystemUser = true;
};
}
{
# Cron service implementation
systemd.timers = mapAttrs' (hostName: cfg: (
systemd.timers =
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
wantedBy = [ "timers.target" ];
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m";
OnUnitActiveSec = "5m";
Unit = "invoiceplane-cron-${hostName}.service";
};
})
)) eachSite;
))
eachSite;
systemd.services =
mapAttrs' (hostName: cfg: (
@ -339,14 +353,15 @@ in
ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}";
};
})
)) eachSite;
))
eachSite;
}
(mkIf (cfg.webserver == "caddy") {
services.caddy = {
enable = true;
virtualHosts = mapAttrs' (hostName: cfg: (
virtualHosts =
mapAttrs' (hostName: cfg: (
nameValuePair "http://${hostName}" {
extraConfig = ''
root * ${pkg hostName cfg}
@ -354,9 +369,9 @@ in
php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket}
'';
}
)) eachSite;
))
eachSite;
};
})
]);
}

View file

@ -5,7 +5,8 @@
flake,
...
}: {
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
nixpkgs.config.allowUnfreePredicate = pkg:
builtins.elem (lib.getName pkg) [
"1password"
"1password-cli"
"cups-brother-hl3140cw"

View file

@ -16,11 +16,15 @@
services.printing.listenAddresses = ["localhost:631"];
services.printing.defaultShared = lib.mkDefault false;
services.printing.drivers = [
services.printing.drivers =
[
pkgs.gutenprint
] ++ (if (pkgs.system == "x86_64-linux")
then [ pkgs.cups-brother-hl3140cw ]
else []);
]
++ (
if (pkgs.system == "x86_64-linux")
then [pkgs.cups-brother-hl3140cw]
else []
);
networking.hosts = flake.self.lib.addLocalHostname ["cups.local"];

View file

@ -1,5 +1,4 @@
{ ... }:
{
{...}: {
enable = true;
nix-direnv = {
enable = true;

View file

@ -1,5 +1,4 @@
{ ... }:
{
{...}: {
enable = true;
extraConfig = {

View file

@ -44,7 +44,8 @@ in {
universal-ctags
];
plugins = with pkgs.vimPlugins; lib.mkIf cfg.full [
plugins = with pkgs.vimPlugins;
lib.mkIf cfg.full [
(pkgs.vimPlugins.nvim-treesitter.withPlugins (p: [
p.ini
p.json

View file

@ -6,7 +6,7 @@
}: let
psCfg = config.pub-solar;
in
with lib; {
with lib; {
imports = [
./home.nix
];
@ -98,4 +98,4 @@ with lib; {
}
];
};
}
}

View file

@ -6,18 +6,16 @@
}: {
flake = {
nixosModules = rec {
overlays = ({ ... }: {
overlays = {...}: {
nixpkgs.overlays = [
(final: prev:
let
(final: prev: let
unstable = import inputs.unstable {
system = prev.system;
};
master = import inputs.master {
system = prev.system;
};
in
{
in {
direnv = unstable.direnv;
nix-direnv = unstable.nix-direnv;
#vimPlugins = prev.vimPlugins // {inherit (unstable.vimPlugins) nvim-lspconfig;};
@ -31,7 +29,7 @@
(import ./nix-index.nix)
(import ./neovim-plugins.nix)
];
});
};
};
};
}

View file

@ -1,5 +1,4 @@
{ self, ... }:
{
{self, ...}: {
flake = {
nixosModules = rec {
root = import ./root;

View file

@ -1,4 +1,3 @@
{...}:
{
{...}: {
users.users.root.hashedPassword = "";
}