mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 14:50:40 +02:00
feat: reenable immich with native module, prepare nixos-extra-modules update
This commit is contained in:
parent
ef2f2a9b77
commit
157c303f38
25 changed files with 1521 additions and 184 deletions
40
flake/agenix-rekey.nix
Normal file
40
flake/agenix-rekey.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
inputs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
inputs.agenix-rekey.flakeModule
|
||||
];
|
||||
|
||||
flake = {
|
||||
# The identities that are used to rekey agenix secrets and to
|
||||
# decrypt all repository-wide secrets.
|
||||
secretsConfig = {
|
||||
masterIdentities = [ "\"$DEVSHELL_DIR\"/secrets/yk1-nix-rage.pub" ];
|
||||
extraEncryptionPubkeys = [ ../secrets/backup.pub ];
|
||||
};
|
||||
};
|
||||
|
||||
perSystem =
|
||||
{ config, ... }:
|
||||
{
|
||||
agenix-rekey.nixosConfigurations = self.nodes;
|
||||
devshells.default = {
|
||||
commands = [
|
||||
{
|
||||
inherit (config.agenix-rekey) package;
|
||||
help = "Edit, generate and rekey secrets";
|
||||
}
|
||||
];
|
||||
env = [
|
||||
{
|
||||
# Always add files to git after agenix rekey and agenix generate.
|
||||
name = "AGENIX_REKEY_ADD_TO_GIT";
|
||||
value = "true";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
90
flake/devshell.nix
Normal file
90
flake/devshell.nix
Normal file
|
@ -0,0 +1,90 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.devshell.flakeModule
|
||||
inputs.pre-commit-hooks.flakeModule
|
||||
inputs.treefmt-nix.flakeModule
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
pre-commit.settings.hooks.treefmt.enable = true;
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
programs = {
|
||||
deadnix.enable = true;
|
||||
statix.enable = true;
|
||||
nixfmt.enable = true;
|
||||
rustfmt.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
devshells.default = {
|
||||
packages = [
|
||||
pkgs.nix # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
|
||||
];
|
||||
|
||||
commands = [
|
||||
{
|
||||
package = config.treefmt.build.wrapper;
|
||||
help = "Format all files";
|
||||
}
|
||||
{
|
||||
package = pkgs.deploy;
|
||||
help = "Build and deploy this nix config to nodes";
|
||||
}
|
||||
{
|
||||
package = pkgs.nix-tree;
|
||||
help = "Interactively browse dependency graphs of Nix derivations";
|
||||
}
|
||||
{
|
||||
package = pkgs.nvd;
|
||||
help = "Diff two nix toplevels and show which packages were upgraded";
|
||||
}
|
||||
{
|
||||
package = pkgs.nix-diff;
|
||||
help = "Explain why two Nix derivations differ";
|
||||
}
|
||||
{
|
||||
package = pkgs.nix-output-monitor;
|
||||
help = "Nix Output Monitor (a drop-in alternative for `nix` which shows a build graph)";
|
||||
}
|
||||
{
|
||||
package = pkgs.writeShellApplication {
|
||||
name = "build";
|
||||
text = ''
|
||||
set -euo pipefail
|
||||
[[ "$#" -ge 1 ]] \
|
||||
|| { echo "usage: build <HOST>..." >&2; exit 1; }
|
||||
HOSTS=()
|
||||
for h in "$@"; do
|
||||
HOSTS+=(".#nixosConfigurations.$h.config.system.build.toplevel")
|
||||
done
|
||||
nom build --no-link --print-out-paths --show-trace "''${HOSTS[@]}"
|
||||
'';
|
||||
};
|
||||
help = "Build a host configuration";
|
||||
}
|
||||
];
|
||||
|
||||
devshell.startup.pre-commit.text = config.pre-commit.installationScript;
|
||||
|
||||
env = [
|
||||
{
|
||||
# Additionally configure nix-plugins with our extra builtins file.
|
||||
# We need this for our repo secrets.
|
||||
name = "NIX_CONFIG";
|
||||
value = ''
|
||||
plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
|
||||
extra-builtins-file = ${./..}/flake/extra-builtins.nix
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
45
flake/extra-builtins.nix
Normal file
45
flake/extra-builtins.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
# This file is intended to be used together with pkgs.nix-plugins,
|
||||
# to provide rage decryption as an additional safe builtin.
|
||||
#
|
||||
# Make sure that nix-plugins is installed by adding the following
|
||||
# statement to your configuration.nix:
|
||||
#
|
||||
# ```nix
|
||||
# {
|
||||
# nix.extraOptions = ''
|
||||
# plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
|
||||
# # Please adjust path accordingly, or leave this out and alternativaly
|
||||
# # pass `--option extra-builtins-file ./extra-builtins.nix` to each invocation
|
||||
# extra-builtins-file = ${./extra-builtins.nix}
|
||||
# '';
|
||||
# }
|
||||
# ```
|
||||
{ exec, ... }:
|
||||
let
|
||||
assertMsg = pred: msg: pred || builtins.throw msg;
|
||||
hasSuffix =
|
||||
suffix: content:
|
||||
let
|
||||
lenContent = builtins.stringLength content;
|
||||
lenSuffix = builtins.stringLength suffix;
|
||||
in
|
||||
lenContent >= lenSuffix && builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||
in
|
||||
{
|
||||
# Instead of calling rage directly here, we call a wrapper script that will cache the output
|
||||
# in a predictable path in /tmp, which allows us to only require the password for each encrypted
|
||||
# file once.
|
||||
rageImportEncrypted =
|
||||
identities: nixFile:
|
||||
assert assertMsg (builtins.isPath nixFile)
|
||||
"The file to decrypt must be given as a path to prevent impurity.";
|
||||
assert assertMsg (hasSuffix ".nix.age" nixFile)
|
||||
"The content of the decrypted file must be a nix expression and should therefore end in .nix.age";
|
||||
exec (
|
||||
[
|
||||
./rage-decrypt-and-cache.sh
|
||||
nixFile
|
||||
]
|
||||
++ identities
|
||||
);
|
||||
}
|
22
flake/globals.nix
Normal file
22
flake/globals.nix
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
globals = {
|
||||
optModules = [
|
||||
../modules/globals.nix
|
||||
];
|
||||
defModules = [
|
||||
../globals.nix
|
||||
];
|
||||
attrkeys = [
|
||||
"domains"
|
||||
"hetzner"
|
||||
"kanidm"
|
||||
"macs"
|
||||
"mail"
|
||||
"monitoring"
|
||||
"myuser"
|
||||
"net"
|
||||
"root"
|
||||
"services"
|
||||
];
|
||||
};
|
||||
}
|
95
flake/hosts.nix
Normal file
95
flake/hosts.nix
Normal file
|
@ -0,0 +1,95 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
flake =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
concatMapAttrs
|
||||
filterAttrs
|
||||
flip
|
||||
genAttrs
|
||||
mapAttrs
|
||||
mapAttrs'
|
||||
nameValuePair
|
||||
;
|
||||
|
||||
# Creates a new nixosSystem with the correct specialArgs, pkgs and name definition
|
||||
mkHost =
|
||||
{ minimal }:
|
||||
name:
|
||||
let
|
||||
pkgs = config.pkgs.x86_64-linux; # FIXME: NOOOOOOOOOOOOOOOOOOOOOOO
|
||||
in
|
||||
inputs.nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {
|
||||
# Use the correct instance lib that has our overlays
|
||||
inherit (pkgs) lib;
|
||||
inherit (config) nodes globals;
|
||||
inherit inputs minimal;
|
||||
};
|
||||
modules = [
|
||||
{
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"qtwebengine-5.15.19" # teamspeak3, whatever I don't visit any untrusted servers
|
||||
];
|
||||
nixpkgs.overlays = (import ../pkgs/default.nix inputs) ++ [
|
||||
inputs.idmail.overlays.default
|
||||
# inputs.nixos-cosmic.overlays.default
|
||||
inputs.nix-topology.overlays.default
|
||||
inputs.nixos-extra-modules.overlays.default
|
||||
inputs.nixvim.overlays.default
|
||||
];
|
||||
|
||||
node.name = name;
|
||||
node.secretsDir = ../hosts/${name}/secrets;
|
||||
}
|
||||
../hosts/${name}
|
||||
];
|
||||
};
|
||||
|
||||
# Get all folders in hosts/
|
||||
hosts = builtins.attrNames (filterAttrs (_: type: type == "directory") (builtins.readDir ../hosts));
|
||||
in
|
||||
{
|
||||
nixosConfigurations = genAttrs hosts (mkHost {
|
||||
minimal = false;
|
||||
});
|
||||
nixosConfigurationsMinimal = genAttrs hosts (mkHost {
|
||||
minimal = true;
|
||||
});
|
||||
|
||||
# True NixOS nodes can define additional guest nodes that are built
|
||||
# together with it. We collect all defined guests from each node here
|
||||
# to allow accessing any node via the unified attribute `nodes`.
|
||||
guestConfigs = flip concatMapAttrs config.nixosConfigurations (
|
||||
_: node:
|
||||
flip mapAttrs' (node.config.guests or { }) (
|
||||
guestName: guestDef:
|
||||
nameValuePair guestDef.nodeName (
|
||||
if guestDef.backend == "microvm" then
|
||||
node.config.microvm.vms.${guestName}.config
|
||||
else
|
||||
node.config.containers.${guestName}.nixosConfiguration
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
# All nixosSystem instanciations are collected here, so that we can refer
|
||||
# to any system via nodes.<name>
|
||||
nodes = config.nixosConfigurations // config.guestConfigs;
|
||||
# Add a shorthand to easily target toplevel derivations
|
||||
"@" = mapAttrs (_: v: v.config.system.build.toplevel) config.nodes;
|
||||
|
||||
# Pre-evaluate the wireguard network information to avoid recalculating it
|
||||
# for every host and every location it is used.
|
||||
wireguardEvalCache = config.pkgs.x86_64-linux.lib.wireguard.createEvalCache inputs [
|
||||
"proxy-sentinel"
|
||||
"proxy-home"
|
||||
];
|
||||
};
|
||||
}
|
38
flake/installer-configuration.nix
Normal file
38
flake/installer-configuration.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
system.stateVersion = "24.11";
|
||||
nix.extraOptions = ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
|
||||
console.keyMap = "de-latin1-nodeadkeys";
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
||||
users.users.root = {
|
||||
password = "nixos";
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA5Uq+CDy5Pmt3If5M6d8K/Q7HArU6sZ7sgoj3T521Wm"
|
||||
];
|
||||
};
|
||||
|
||||
environment = {
|
||||
variables.EDITOR = "nvim";
|
||||
systemPackages = with pkgs; [
|
||||
neovim
|
||||
git
|
||||
tmux
|
||||
parted
|
||||
ripgrep
|
||||
fzf
|
||||
wget
|
||||
curl
|
||||
];
|
||||
|
||||
etc.issue.text = ''
|
||||
\d \t
|
||||
This is \e{cyan}\n\e{reset} [\e{lightblue}\l\e{reset}] (\s \m \r)
|
||||
\e{halfbright}\4\e{reset} \e{halfbright}\6\e{reset}
|
||||
'';
|
||||
};
|
||||
}
|
27
flake/iso.nix
Normal file
27
flake/iso.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# For each major system, we provide a customized installer image that
|
||||
# has ssh and some other convenience stuff preconfigured.
|
||||
# Not strictly necessary for new setups.
|
||||
packages.live-iso = inputs.nixos-generators.nixosGenerate {
|
||||
inherit pkgs;
|
||||
modules = [
|
||||
./installer-configuration.nix
|
||||
../config/ssh.nix
|
||||
];
|
||||
format =
|
||||
{
|
||||
x86_64-linux = "install-iso";
|
||||
aarch64-linux = "sd-aarch64-installer";
|
||||
}
|
||||
.${system};
|
||||
};
|
||||
};
|
||||
}
|
39
flake/pkgs.nix
Normal file
39
flake/pkgs.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
(
|
||||
{
|
||||
lib,
|
||||
flake-parts-lib,
|
||||
...
|
||||
}:
|
||||
flake-parts-lib.mkTransposedPerSystemModule {
|
||||
name = "pkgs";
|
||||
file = ./pkgs.nix;
|
||||
option = lib.mkOption {
|
||||
type = lib.types.unspecified;
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
_module.args.pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
overlays = (import ../pkgs/default.nix inputs) ++ [
|
||||
inputs.nix-topology.overlays.default
|
||||
# inputs.nixos-cosmic.overlays.default
|
||||
inputs.nixos-extra-modules.overlays.default
|
||||
];
|
||||
};
|
||||
|
||||
inherit pkgs;
|
||||
};
|
||||
}
|
44
flake/rage-decrypt-and-cache.sh
Executable file
44
flake/rage-decrypt-and-cache.sh
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
print_out_path=false
|
||||
if [[ "$1" == "--print-out-path" ]]; then
|
||||
print_out_path=true
|
||||
shift
|
||||
fi
|
||||
|
||||
file="$1"
|
||||
shift
|
||||
identities=("$@")
|
||||
|
||||
# Strip .age suffix, and store path prefix or ./ if applicable
|
||||
basename="${file%".age"}"
|
||||
[[ "$file" == "/nix/store/"* ]] && basename="${basename#*"-"}"
|
||||
[[ "$file" == "./"* ]] && basename="${basename#"./"}"
|
||||
|
||||
# Calculate a unique content-based identifier (relocations of
|
||||
# the source file in the nix store should not affect caching)
|
||||
new_name="$(sha512sum "$file")"
|
||||
new_name="${new_name:0:32}-${basename//"/"/"%"}"
|
||||
|
||||
# Derive the path where the decrypted file will be stored
|
||||
out="/var/tmp/nix-import-encrypted/$UID/$new_name"
|
||||
umask 077
|
||||
mkdir -p "$(dirname "$out")"
|
||||
|
||||
# Decrypt only if necessary
|
||||
if [[ ! -e "$out" ]]; then
|
||||
args=()
|
||||
for i in "${identities[@]}"; do
|
||||
args+=("--identity" "$i")
|
||||
done
|
||||
rage --decrypt "${args[@]}" --output "$out" "$file"
|
||||
fi
|
||||
|
||||
# Print out path or decrypted content
|
||||
if [[ "$print_out_path" == true ]]; then
|
||||
echo "$out"
|
||||
else
|
||||
cat "$out"
|
||||
fi
|
14
flake/storage-box.nix
Normal file
14
flake/storage-box.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
apps.setupHetznerStorageBoxes =
|
||||
import (inputs.nixos-extra-modules + "/apps/setup-hetzner-storage-boxes.nix")
|
||||
{
|
||||
inherit pkgs;
|
||||
nixosConfigurations = inputs.self.nodes;
|
||||
decryptIdentity = builtins.head inputs.self.secretsConfig.masterIdentities;
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue