mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
feat: clean up the repo
This commit is contained in:
parent
bc9c310c77
commit
f6ec9f37eb
249 changed files with 804 additions and 13048 deletions
|
|
@ -1,119 +0,0 @@
|
|||
{ tf, target, name, meta, pkgs, config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
|
||||
* marries meta config to NixOS configs for each host.
|
||||
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy;
|
||||
unmergedValues = types.mkOptionType {
|
||||
name = "unmergedValues";
|
||||
merge = loc: defs: map (def: def.value) defs;
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
out = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
deploy.tf = mkOption {
|
||||
type = types.submodule {
|
||||
inherit (unmerged) freeformType;
|
||||
|
||||
options = {
|
||||
triggers = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = { };
|
||||
};
|
||||
import = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
imports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Other targets to depend on";
|
||||
default = [ ];
|
||||
};
|
||||
attrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
out.set = mkOption { type = types.unspecified; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
functionlessConfig = lib.removeAttrs config ["out" "_module" "platform" "deploy" "secrets"];
|
||||
mutatedConfig = functionlessConfig // (optionalAttrs (config.platform != {}) {
|
||||
${functionlessConfig.esphome.platform} = config.platform;
|
||||
});
|
||||
jsonConfig = builtins.toJSON mutatedConfig;
|
||||
secretsMap = mapAttrs (name: _: tf.variables."${config.esphome.name}-secret-${name}".ref) config.secrets;
|
||||
secretsFile = builtins.toJSON secretsMap;
|
||||
closureConfig = pkgs.writeText "${functionlessConfig.esphome.name}.json" jsonConfig;
|
||||
in mkMerge [
|
||||
{
|
||||
_module.args.tf = mapNullable (target: target.tf) target;
|
||||
out = jsonConfig;
|
||||
deploy.tf = {
|
||||
terraform.environment.ESPHOME = "${pkgs.esphome}";
|
||||
attrs = [ "import" "imports" "out" "attrs" "triggers" ];
|
||||
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
|
||||
out.set = removeAttrs cfg.tf cfg.tf.attrs;
|
||||
triggers = {
|
||||
upload = {
|
||||
system = config.out;
|
||||
};
|
||||
};
|
||||
resources = {
|
||||
"${name}-secrets" = {
|
||||
provider = "local";
|
||||
type = "file";
|
||||
inputs = {
|
||||
filename = "${builtins.toString tf.terraform.dataDir}/esphome-${name}-secrets.json";
|
||||
content = secretsFile;
|
||||
};
|
||||
};
|
||||
"${name}-upload" = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
inputs.triggers = cfg.tf.triggers.upload;
|
||||
provisioners = [
|
||||
{
|
||||
type = "local-exec";
|
||||
local-exec = {
|
||||
working_dir = builtins.toString tf.terraform.dataDir;
|
||||
command = ''
|
||||
${pkgs.esphome}/bin/esphome compile ${closureConfig} ${tf.resources."${name}-secrets".refAttr "filename"}
|
||||
${pkgs.esphome}/bin/esphome upload ${closureConfig} ${tf.resources."${name}-secrets".refAttr "filename"} --device ${name}.local
|
||||
'';
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf (config.secrets != {}) {
|
||||
deploy.tf.variables = mapAttrs' (name: content: let
|
||||
parts = if hasInfix "#" content then splitString "#" content else content;
|
||||
field = head (reverseList parts);
|
||||
path = if length parts > 1 then head parts else "password";
|
||||
in nameValuePair "${config.esphome.name}-secret-${name}" ({
|
||||
value.shellCommand = let
|
||||
bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${meta.network.nodes.all.${builtins.getEnv "HOME_HOSTNAME"}.secrets.repo.bitw.source} "$@"'';
|
||||
in "${bitw}/bin/bitw get ${path} -f ${field}";
|
||||
type = "string";
|
||||
sensitive = true;
|
||||
})
|
||||
) config.secrets;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{ name, config, meta, pkgs, lib, ... }: with lib;
|
||||
{
|
||||
options = {
|
||||
} // genAttrs [ "esphome" "api" "platform" "wifi" "i2c" "logger" "ota" "sensor" "secrets" ] (key:
|
||||
mkOption {
|
||||
type = types.unspecified;
|
||||
default = {};
|
||||
}
|
||||
);
|
||||
imports = with meta; [
|
||||
esphome.base
|
||||
];
|
||||
}
|
||||
|
|
@ -1,234 +0,0 @@
|
|||
{ config, pkgs, lib, ... }: let
|
||||
inherit (lib.types) bool enum str int submodule oneOf attrsOf listOf package;
|
||||
inherit (lib.options) mkEnableOption mkOption;
|
||||
inherit (lib.strings) optionalString concatStringsSep toUpper hasInfix;
|
||||
inherit (lib.attrsets) mapAttrsToList mapAttrs attrValues;
|
||||
inherit (pkgs.stdenv) mkDerivation;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
cfg = config.base16.gtk.settings;
|
||||
bcfg = config.base16.gtk;
|
||||
in {
|
||||
options = {
|
||||
base16.gtk = {
|
||||
enable = mkEnableOption "Enable GTK theme generation";
|
||||
packages = {
|
||||
icons = mkOption {
|
||||
type = attrsOf package;
|
||||
};
|
||||
themes = mkOption {
|
||||
type = attrsOf package;
|
||||
};
|
||||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf (submodule {
|
||||
freeformType = attrsOf (oneOf [bool str int]);
|
||||
options = {
|
||||
name = mkOption {
|
||||
description = "Name of the theme";
|
||||
type = str;
|
||||
default = ''"${config.base16.defaultSchemeName}"'';
|
||||
};
|
||||
theme_style = mkOption {
|
||||
description = "What GTK theme do we use as the base for generating the resulting base16 GTK theme";
|
||||
type = enum ["materia" "oomox"];
|
||||
default = "oomox";
|
||||
};
|
||||
roundness = mkOption {
|
||||
description = "GTK theme roundness";
|
||||
type = int;
|
||||
default = 2;
|
||||
};
|
||||
spacing = mkOption {
|
||||
description = "GTK theme spacing";
|
||||
type = int;
|
||||
default = 3;
|
||||
};
|
||||
outline_width = mkOption {
|
||||
description = "GTK outline width";
|
||||
type = int;
|
||||
default = 1;
|
||||
};
|
||||
button_outline_offset = mkOption {
|
||||
description = "GTK theme button outline offset";
|
||||
type = int;
|
||||
default = -3;
|
||||
};
|
||||
button_outline_width = mkOption {
|
||||
description = "GTK theme button outline width";
|
||||
type = int;
|
||||
default = 1;
|
||||
};
|
||||
icon_style = mkOption {
|
||||
description = "What icon theme do we use as the base for generating the resulting base16 color templated icon theme";
|
||||
type = enum ["numix" "archdroid" "gnomecolors" "papirus" "suruplus" "suruplus_aspromauros"];
|
||||
default = "archdroid";
|
||||
};
|
||||
numix_style = mkOption {
|
||||
description = "If you chose numix for base16.gtk.icons, this chooses the Numix icon theme sub-style";
|
||||
type = enum [ 0 1 2 3 4 5 ];
|
||||
default = 0;
|
||||
};
|
||||
suruplus_gradient_enabled = mkOption {
|
||||
description = "If you chose suruplus for base16.gtk.icons, this chooses to enable the gradient on it";
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
base16_generate_dark = mkOption {
|
||||
description = "Choose whether to invert the GUI colours";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf bcfg.enable (let
|
||||
oomoxPath = "${pkgs.oomox}/lib/share/oomox/plugins";
|
||||
iconPathSelector = icon_style: {
|
||||
archdroid = "icons_archdroid/archdroid-icon-theme/change_color.sh";
|
||||
gnomecolors = "icons_gnomecolors/gnome-colors-icon-theme/change_color.sh";
|
||||
}.${icon_style} or "icons_${icon_style}/change_color.sh";
|
||||
themePathSelector = theme_style: {
|
||||
materia = "theme_materia/materia-theme/change_color.sh";
|
||||
}.${theme_style} or "theme_${theme_style}/change_color.sh";
|
||||
iconsTheme = icon_style: {
|
||||
numix = "numix_icons";
|
||||
suruplus = "icons_suru";
|
||||
suruplus_aspromauros = "icons_suruplus_aspromauros";
|
||||
archdroid = "archdroid";
|
||||
gnomecolors = "gnome_colors";
|
||||
papirus = "papirus_icons";
|
||||
}.${icon_style};
|
||||
configForScheme = schemeName: scheme: let
|
||||
schemeSettings = cfg.${schemeName} or cfg.default;
|
||||
keyValues = mapAttrsToList (k: v: let
|
||||
typeHandler = {
|
||||
"string" = if hasInfix "base" v then scheme.${v}.hex else v;
|
||||
"bool" = if v == true then "True" else "False";
|
||||
"int" = toString v;
|
||||
}.${builtins.typeOf v};
|
||||
keyHandler = {
|
||||
"icon_style" = iconsTheme v;
|
||||
}.${k} or typeHandler;
|
||||
in "${toUpper k}=${keyHandler}") schemeSettings;
|
||||
in ''
|
||||
${concatStringsSep "\n" keyValues}
|
||||
'';
|
||||
configForSchemes = mapAttrs configForScheme config.base16.schemes;
|
||||
configFilesForSchemes = mapAttrs (k: v: pkgs.writeText "oomox-config-${k}" v) configForSchemes;
|
||||
iconPackageForScheme = schemeName: schemeConfigFile: let
|
||||
schemeConfig = cfg.${schemeName} or cfg.default;
|
||||
in with pkgs; mkDerivation rec {
|
||||
name = "icons-${cfg.${schemeName}.icon_style or cfg.default.icon_style}-${schemeName}";
|
||||
src = fetchFromGitHub {
|
||||
owner = "themix-project";
|
||||
repo = "oomox";
|
||||
rev = "1.14";
|
||||
sha256 = "0zk2q0z0n64kl6my60vkq11gp4mc442jxqcwbi4kl108242izpjv";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
nativeBuildInputs = [ glib libxml2 bc ];
|
||||
buildInputs = [ gnome.gnome-themes-extra gdk-pixbuf librsvg pkgs.sassc pkgs.inkscape pkgs.optipng ];
|
||||
propagatedUserEnvPkgs = [ gtk-engine-murrine ];
|
||||
installPhase = ''
|
||||
export HOME=./
|
||||
mkdir -p ./.icons
|
||||
patchShebangs plugins/${iconPathSelector schemeConfig.icon_style}
|
||||
plugins/${iconPathSelector schemeConfig.icon_style} ${schemeConfigFile} \
|
||||
-o ${schemeConfig.icon_style}-$name
|
||||
mkdir -p $out/share/icons/${schemeConfig.icon_style}-$name
|
||||
mv ./.icons/* $out/share/icons
|
||||
'';
|
||||
};
|
||||
themePackageForScheme = schemeName: schemeConfigFile: let
|
||||
schemeConfig = cfg.${schemeName} or cfg.default;
|
||||
in with pkgs; mkDerivation rec {
|
||||
name = "theme-${cfg.${schemeName}.theme_style or cfg.default.theme_style}-${schemeName}";
|
||||
src = fetchFromGitHub {
|
||||
owner = "themix-project";
|
||||
repo = "oomox";
|
||||
rev = "1.14";
|
||||
sha256 = "0zk2q0z0n64kl6my60vkq11gp4mc442jxqcwbi4kl108242izpjv";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
nativeBuildInputs = [ glib libxml2 bc ];
|
||||
buildInputs = [ gnome.gnome-themes-extra gdk-pixbuf librsvg pkgs.sassc pkgs.inkscape pkgs.optipng ];
|
||||
propagatedUserEnvPkgs = [ gtk-engine-murrine ];
|
||||
installPhase = ''
|
||||
export HOME=./
|
||||
mkdir -p $out/share/themes/${schemeConfig.theme_style}-$name
|
||||
patchShebangs plugins/theme_${schemeConfig.theme_style}
|
||||
plugins/${themePathSelector schemeConfig.theme_style} \
|
||||
--hidpi False -t $out/share/themes -m all --output ${schemeConfig.theme_style}-$name ${schemeConfigFile}
|
||||
'';
|
||||
};
|
||||
themePackagesForSchemes = mapAttrs (k: v: themePackageForScheme k v) configFilesForSchemes;
|
||||
iconPackagesForSchemes = mapAttrs (k: v: iconPackageForScheme k v) configFilesForSchemes;
|
||||
in {
|
||||
base16.gtk = {
|
||||
packages = {
|
||||
themes = themePackagesForSchemes;
|
||||
icons = iconPackagesForSchemes;
|
||||
};
|
||||
settings.default = mapAttrs (_: mkDefault) {
|
||||
base16_invert_terminal = false;
|
||||
base16_mild_terminal = false;
|
||||
terminal_theme_accuracy = 128;
|
||||
terminal_theme_auto_bgfg = true;
|
||||
terminal_theme_extend_palette = false;
|
||||
terminal_theme_mode = "manual";
|
||||
unity_default_launcher_style = false;
|
||||
suruplus_gradient1 = "3623c";
|
||||
suruplus_gradient2 = "base0E";
|
||||
caret1_fg = "base07";
|
||||
caret2_fg = "base07";
|
||||
terminal_background = "base00";
|
||||
terminal_foreground = "base05";
|
||||
terminal_cursor = "base05";
|
||||
terminal_color0 = "base01";
|
||||
terminal_color1 = "base08";
|
||||
terminal_color2 = "base0B";
|
||||
terminal_color3 = "base09";
|
||||
terminal_color4 = "base0D";
|
||||
terminal_color5 = "base0E";
|
||||
terminal_color6 = "base0C";
|
||||
terminal_color7 = "base06";
|
||||
terminal_color8 = "base02";
|
||||
terminal_color9 = "base08";
|
||||
terminal_color10 = "base0B";
|
||||
terminal_color11 = "base0A";
|
||||
terminal_color12 = "base0D";
|
||||
terminal_color13 = "base0E";
|
||||
terminal_color14 = "base0C";
|
||||
terminal_color15 = "base07";
|
||||
bg = "base01";
|
||||
fg = "base06";
|
||||
hdr_bg = "base00";
|
||||
hdr_fg = "base05";
|
||||
sel_bg = "base0E";
|
||||
sel_fg = "base00";
|
||||
accent_bg = "base0E";
|
||||
txt_bg = "base02";
|
||||
txt_fg = "base07";
|
||||
btn_bg = "base00";
|
||||
btn_fg = "base05";
|
||||
hdr_btn_bg = "base01";
|
||||
hdr_btn_fg = "base05";
|
||||
wm_border_focus = "base0E";
|
||||
wm_border_unfocus = "base00";
|
||||
spotify_proto_bg = "base00";
|
||||
spotify_proto_fg = "base05";
|
||||
spotify_proto_sel = "base0E";
|
||||
icons_light_folder = "base0D";
|
||||
icons_light = "base0D";
|
||||
icons_medium = "base0E";
|
||||
icons_dark = "base00";
|
||||
icons_symbolic_panel = "base06";
|
||||
icons_symbolic_action = "3623c";
|
||||
icons_archdroid = "base0E";
|
||||
};
|
||||
};
|
||||
home.packages = (attrValues iconPackagesForSchemes) ++ (attrValues themePackagesForSchemes);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* Provides in-scope TF config for home-manager.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy.tf;
|
||||
unmergedValues = types.mkOptionType {
|
||||
name = "unmergedValues";
|
||||
merge = loc: defs: map (def: def.value) defs;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
options.deploy.tf = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf unmergedValues;
|
||||
|
||||
options = {
|
||||
attrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
out.set = mkOption { type = types.unspecified; };
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
config = {
|
||||
deploy.tf = {
|
||||
attrs = [ "out" "attrs" ];
|
||||
out.set = removeAttrs cfg cfg.attrs;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{ config, lib, nixos, ... }: with lib; {
|
||||
options.hardware.displays = mkOption {
|
||||
type = with types; attrsOf (submodule ({ config, ... }: {
|
||||
options = {
|
||||
pos = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
res = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
config = mkMerge [
|
||||
{
|
||||
hardware.displays = nixos.hardware.displays;
|
||||
}
|
||||
(mkIf config.wayland.windowManager.sway.enable {
|
||||
wayland.windowManager.sway.config.output = config.hardware.displays;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.network.firewall;
|
||||
in
|
||||
{
|
||||
options.network.firewall = {
|
||||
public.tcp.ports = mkOption {
|
||||
type = types.listOf types.port;
|
||||
default = [ ];
|
||||
};
|
||||
public.udp.ports = mkOption {
|
||||
type = types.listOf types.port;
|
||||
default = [ ];
|
||||
};
|
||||
private.tcp.ports = mkOption {
|
||||
type = types.listOf types.port;
|
||||
default = [ ];
|
||||
};
|
||||
private.udp.ports = mkOption {
|
||||
type = types.listOf types.port;
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
public.tcp.ranges = mkOption {
|
||||
type = types.listOf (types.attrsOf types.port);
|
||||
default = [ ];
|
||||
};
|
||||
public.udp.ranges = mkOption {
|
||||
type = types.listOf (types.attrsOf types.port);
|
||||
default = [ ];
|
||||
};
|
||||
private.tcp.ranges = mkOption {
|
||||
type = types.listOf (types.attrsOf types.port);
|
||||
default = [ ];
|
||||
};
|
||||
private.udp.ranges = mkOption {
|
||||
type = types.listOf (types.attrsOf types.port);
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
public.interfaces = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Public firewall interfaces";
|
||||
default = [ ];
|
||||
};
|
||||
private.interfaces = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Private firewall interfaces";
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{ config, nixos, ... }: {
|
||||
secrets.repo = nixos.secrets.repo;
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{ config, lib, pkgs, ... }: with lib;
|
||||
|
||||
let cfg = config.programs.swaylock; in
|
||||
{
|
||||
options.programs.swaylock = {
|
||||
colors = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config.programs.swaylock.settings = mapAttrs' (arg: color: nameValuePair ("${arg}-color") (removePrefix "#" color)) cfg.colors;
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
{ meta, config, pkgs, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* provides a central way to change the font my system uses.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.nixfiles.theme; in
|
||||
{
|
||||
imports = with meta; [
|
||||
modules.home.swaylock
|
||||
];
|
||||
options.nixfiles.theme = {
|
||||
enable = mkEnableOption "kat's theme module";
|
||||
sass = {
|
||||
variables = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = (cfg.base16 // cfg.base16t // {
|
||||
term_font = cfg.font.termName;
|
||||
font = cfg.font.name;
|
||||
font_size = cfg.font.size_css;
|
||||
});
|
||||
};
|
||||
css_style = mkOption {
|
||||
type = types.enum [ "nested" "compressed" "compact" "expanded" ];
|
||||
default = "expanded";
|
||||
};
|
||||
};
|
||||
swaylock = mkEnableOption "use swaylock module";
|
||||
base16 = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
base16t = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
alpha = mkOption {
|
||||
type = types.float;
|
||||
};
|
||||
font = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "Iosevka Nerd Font";
|
||||
};
|
||||
termName = mkOption {
|
||||
type = types.str;
|
||||
default = "Iosevka Nerd Font";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.float;
|
||||
default = 10.0;
|
||||
};
|
||||
size_css = mkOption {
|
||||
type = types.str;
|
||||
default = "${toString (cfg.font.size + 3)}px";
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable) {
|
||||
nixfiles.theme = {
|
||||
base16 = lib.mapAttrs' (k: v: lib.nameValuePair k "#${v.hex}")
|
||||
(lib.filterAttrs (n: _: lib.hasInfix "base" n) config.base16.defaultScheme);
|
||||
base16t = lib.mapAttrs' (k: v: lib.nameValuePair "${k}t" "rgba(${toString v.red.byte}, ${toString v.green.byte}, ${toString v.blue.byte}, ${toString cfg.alpha})")
|
||||
(lib.filterAttrs (n: _: lib.hasInfix "base" n) config.base16.defaultScheme);
|
||||
alpha = 0.7;
|
||||
};
|
||||
|
||||
programs.swaylock = mkIf (cfg.swaylock) {
|
||||
enable = true;
|
||||
package = pkgs.swaylock-effects-develop;
|
||||
settings = {
|
||||
screenshots = true;
|
||||
daemonize = true;
|
||||
show-failed-attempts = true;
|
||||
indicator = true;
|
||||
indicator-radius = 110;
|
||||
indicator-thickness = 8;
|
||||
font = cfg.font.name;
|
||||
font-size = cfg.font.size_css;
|
||||
clock = true;
|
||||
datestr = "%F";
|
||||
timestr = "%T";
|
||||
effect-blur = "5x2";
|
||||
fade-in = 0.2;
|
||||
};
|
||||
colors = with cfg.base16; {
|
||||
key-hl = base0C;
|
||||
separator = base01;
|
||||
line = base01;
|
||||
line-clear = base01;
|
||||
line-caps-lock = base01;
|
||||
line-ver = base01;
|
||||
line-wrong = base01;
|
||||
ring = base00;
|
||||
ring-clear = base0B;
|
||||
ring-caps-lock = base09;
|
||||
ring-ver = base0D;
|
||||
ring-wrong = base08;
|
||||
inside = base00;
|
||||
inside-clear = base00;
|
||||
inside-caps-lock = base00;
|
||||
inside-ver = base00;
|
||||
inside-wrong = base00;
|
||||
text = base05;
|
||||
text-clear = base05;
|
||||
text-caps-lock = base05;
|
||||
text-ver = base05;
|
||||
text-wrong = base05;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services.swayidle = mkIf (cfg.swaylock) {
|
||||
Unit = {
|
||||
Description = "swayidle";
|
||||
Documentation = [ "man:swayidle(1)" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart =
|
||||
let
|
||||
lockCommand = config.programs.swaylock.script;
|
||||
in
|
||||
''
|
||||
${pkgs.swayidle}/bin/swayidle -w \
|
||||
timeout 300 '${lockCommand}' \
|
||||
timeout 600 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"' \
|
||||
before-sleep '${lockCommand}'
|
||||
'';
|
||||
RestartSec = 3;
|
||||
Restart = "always";
|
||||
};
|
||||
Install = { WantedBy = [ "sway-session.target" ]; };
|
||||
};
|
||||
|
||||
lib.nixfiles.sassTemplate = { name, src }:
|
||||
let
|
||||
variables = pkgs.writeText "base-variables.sass" ''
|
||||
${(concatStringsSep "\n" (mapAttrsToList(var: con: "\$${var}: ${con}") cfg.sass.variables))}
|
||||
'';
|
||||
source = pkgs.callPackage
|
||||
({ sass, stdenv }: stdenv.mkDerivation {
|
||||
inherit name src variables;
|
||||
nativeBuildInputs = lib.singleton sass;
|
||||
phases = [ "buildPhase" ];
|
||||
buildPhase = ''
|
||||
cat $variables $src > src-mut.sass
|
||||
sass src-mut.sass $out --sourcemap=none --trace --style=${cfg.sass.css_style}
|
||||
'';
|
||||
})
|
||||
{ };
|
||||
in
|
||||
{
|
||||
inherit source;
|
||||
text = builtins.readFile source;
|
||||
};
|
||||
_module.args = { inherit (config.lib) nixfiles; };
|
||||
};
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
{ inputs, tree, config, pkgs, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* makes tf-nix a part of the meta config
|
||||
* handles the trusted import for tf-nix
|
||||
* provides the target interface
|
||||
* imports the per-host TF config for each target
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy;
|
||||
meta = config;
|
||||
tfModule = { lib, ... }: with lib; {
|
||||
config._module.args = {
|
||||
pkgs = mkDefault pkgs;
|
||||
};
|
||||
};
|
||||
tfType = types.submoduleWith {
|
||||
modules = [
|
||||
tfModule
|
||||
"${toString inputs.tf-nix}/modules"
|
||||
];
|
||||
specialArgs = {
|
||||
meta = config;
|
||||
};
|
||||
shorthandOnlyDefinesConfig = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
"${toString inputs.tf-nix}/modules/run.nix"
|
||||
];
|
||||
options = {
|
||||
deploy = {
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = ../../tf;
|
||||
};
|
||||
local = {
|
||||
isRoot = mkOption {
|
||||
type = types.bool;
|
||||
default = builtins.getEnv "HOME_UID" == "0";
|
||||
};
|
||||
hostName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default =
|
||||
let
|
||||
hostName = builtins.getEnv "HOME_HOSTNAME";
|
||||
in
|
||||
if hostName == "" then null else hostName;
|
||||
};
|
||||
};
|
||||
targets =
|
||||
let
|
||||
type = types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
enable = mkEnableOption "Enable the target" // { default = true; };
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
};
|
||||
nodeNames = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
tf = mkOption {
|
||||
type = tfType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config.tf = mkMerge (singleton
|
||||
({ ... }: {
|
||||
imports = if name == "home" then attrValues (removeAttrs tree.impure.modules.tf [ "acme" "__functor" ])
|
||||
else [
|
||||
tree.impure.modules.tf
|
||||
];
|
||||
deploy.gcroot = {
|
||||
name = mkDefault "nixfiles-${config.name}";
|
||||
user = mkIf (builtins.getEnv "HOME_USER" != "") (mkDefault (builtins.getEnv "HOME_USER"));
|
||||
};
|
||||
providers.local = { };
|
||||
deps = {
|
||||
select.allProviders = true;
|
||||
enable = true;
|
||||
apply = {
|
||||
doneCommand = ''
|
||||
git -C "${toString cfg.dataDir}" add -A
|
||||
git -C "${toString cfg.dataDir}" commit -m "${config.name}: $(date +'%F %T')"
|
||||
git -C "${toString cfg.dataDir}" push
|
||||
'';
|
||||
};
|
||||
};
|
||||
terraform = {
|
||||
version = "1.0";
|
||||
prettyJson = true;
|
||||
logPath = cfg.dataDir + "/terraform-${config.name}.log";
|
||||
dataDir = cfg.dataDir + "/tfdata/${config.name}";
|
||||
environment.TF_CLI_ARGS_apply = "-backup=-";
|
||||
environment.TF_CLI_ARGS_taint = "-backup=-";
|
||||
};
|
||||
state = {
|
||||
file = cfg.dataDir + "/terraform-${config.name}.tfstate";
|
||||
};
|
||||
runners = {
|
||||
lazy = {
|
||||
inherit (meta.runners.lazy) file args;
|
||||
attrPrefix = "deploy.targets.${name}.tf.runners.run.";
|
||||
};
|
||||
run = {
|
||||
apply.name = "${name}-apply-uw";
|
||||
terraform.name = "${name}-tf";
|
||||
myApply = {
|
||||
name = "${name}-apply";
|
||||
command = let
|
||||
path = toString cfg.dataDir;
|
||||
in ''
|
||||
set -e
|
||||
git -C "${path}" pull
|
||||
${config.tf.runners.run.apply.package}/bin/${config.tf.runners.run.apply.executable}
|
||||
git -C "${path}" add -A
|
||||
git -C "${path}" commit -m "${config.name}: $(date +'%F %T')"
|
||||
git -C "${path}" push --force
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
continue.envVar = "TF_NIX_CONTINUE_${replaceStrings [ "-" ] [ "_" ] config.name}";
|
||||
}) ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.nixos.${nodeName}.deploy.tf.out.set) config.nodeNames
|
||||
++ (optionals (config.name == "home") (mapAttrsToList (node: config: (mapAttrs (_: mkMerge) config.deploy.tf.out.set)) meta.network.nodes.esphome)));
|
||||
});
|
||||
in
|
||||
mkOption {
|
||||
type = types.attrsOf type;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
deploy.targets =
|
||||
let
|
||||
nodeNames = attrNames config.network.nodes.nixos;
|
||||
targets = config.deploy.targets;
|
||||
explicitlyDefinedHosts = concatLists (mapAttrsToList (targetName: target: remove targetName target.nodeNames) config.deploy.targets);
|
||||
in
|
||||
genAttrs nodeNames (nodeName: {
|
||||
enable = mkDefault (! elem nodeName explicitlyDefinedHosts);
|
||||
nodeNames = singleton nodeName;
|
||||
});
|
||||
|
||||
runners = {
|
||||
run = mkMerge (mapAttrsToList
|
||||
(targetName: target: mapAttrs'
|
||||
(k: run:
|
||||
nameValuePair run.name run.set
|
||||
)
|
||||
target.tf.runners.run)
|
||||
(filterAttrs (_: v: v.enable) cfg.targets));
|
||||
lazy.run = mkMerge (mapAttrsToList
|
||||
(targetName: target: mapAttrs'
|
||||
(k: run:
|
||||
nameValuePair run.name run.set
|
||||
)
|
||||
target.tf.runners.lazy.run)
|
||||
(filterAttrs (_: v: v.enable) cfg.targets));
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{ config, pkgs, root, ... }: {
|
||||
runners.lazy = {
|
||||
file = root;
|
||||
args = [ "--show-trace" ];
|
||||
};
|
||||
deploy.targets.dummy.enable = false;
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
{ config, lib, meta, root, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
meta,
|
||||
root,
|
||||
...
|
||||
}:
|
||||
with lib; {
|
||||
options = {
|
||||
lib = mkOption {
|
||||
type = types.attrsOf (types.attrsOf types.unspecified);
|
||||
|
|
@ -11,18 +14,6 @@ with lib;
|
|||
nixosImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
darwinImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
esphomeImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
homeImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
users = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
|
@ -31,35 +22,15 @@ with lib;
|
|||
(root + "/nixos/systems/HN.nix")
|
||||
(root + "/nixos/systems/HN/nixos.nix")
|
||||
]);
|
||||
esphomeImports = mkDefault (map (path: toString path) [
|
||||
(root + "/esphome/boards/HN.nix")
|
||||
(root + "/esphome/boards/HN/esphome.nix")
|
||||
]);
|
||||
darwinImports = mkDefault (map (path: toString path) [
|
||||
(root + "/darwin/systems/HN.nix")
|
||||
(root + "/darwin/systems/HN/darwin.nix")
|
||||
]);
|
||||
homeImports = [];
|
||||
users = mkDefault (singleton "kat");
|
||||
};
|
||||
lib.nixfiles.nixosImport = hostName: lib.nodeImport {
|
||||
inherit (config.network.importing) nixosImports homeImports users;
|
||||
profiles = meta.nixos;
|
||||
inherit hostName;
|
||||
};
|
||||
lib.nixfiles.esphomeImport = hostName: lib.nodeImport {
|
||||
nixosImports = config.network.importing.esphomeImports;
|
||||
homeImports = [];
|
||||
users = [];
|
||||
profiles = { base = { }; };
|
||||
inherit hostName;
|
||||
};
|
||||
lib.nixfiles.darwinImport = hostName: lib.nodeImport {
|
||||
nixosImports = config.network.importing.darwinImports;
|
||||
profiles = meta.darwin;
|
||||
inherit (config.network.importing) homeImports users;
|
||||
inherit hostName;
|
||||
};
|
||||
_module.args = { inherit (config.lib) nixfiles; };
|
||||
lib.nixfiles.nixosImport = hostName:
|
||||
lib.nodeImport {
|
||||
inherit (config.network.importing) nixosImports;
|
||||
profiles = meta.nixos;
|
||||
homeImports = [];
|
||||
users = [];
|
||||
inherit hostName;
|
||||
};
|
||||
_module.args = {inherit (config.lib) nixfiles;};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,171 +1,94 @@
|
|||
{ pkgs, inputs, lib, meta, config, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* Makes hosts nixosModules.
|
||||
* Manages module imports and specialArgs.
|
||||
* Builds network.nodes.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
lib,
|
||||
meta,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
/*
|
||||
This module:
|
||||
* Makes hosts nixosModules.
|
||||
* Manages module imports and specialArgs.
|
||||
* Builds network.nodes.
|
||||
*/
|
||||
with lib; {
|
||||
options.network = {
|
||||
nixos = {
|
||||
extraModules = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
specialArgs = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
modulesPath = mkOption {
|
||||
type = types.path;
|
||||
default = toString (pkgs.path + "/nixos/modules");
|
||||
};
|
||||
};
|
||||
darwin = {
|
||||
extraModules = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
specialArgs = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = { };
|
||||
};
|
||||
modulesPath = mkOption {
|
||||
type = types.path;
|
||||
default = toString (inputs.darwin + "/modules");
|
||||
};
|
||||
};
|
||||
esphome = {
|
||||
extraModules = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
specialArgs = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
nodes.all = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = config.network.nodes.nixos // config.network.nodes.darwin // config.network.nodes.esphome;
|
||||
};
|
||||
nodes.esphome = let
|
||||
esphomeType = types.submoduleWith {
|
||||
modules = config.network.esphome.extraModules;
|
||||
inherit (config.network.esphome) specialArgs;
|
||||
};
|
||||
in mkOption {
|
||||
type = types.attrsOf esphomeType;
|
||||
default = { };
|
||||
};
|
||||
nodes.nixos =
|
||||
let
|
||||
nixosModule = { name, config, meta, modulesPath, lib, ... }: with lib; {
|
||||
options = {
|
||||
nixpkgs.crossOverlays = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [ ];
|
||||
nodes = let
|
||||
nixosModule = {
|
||||
name,
|
||||
config,
|
||||
meta,
|
||||
modulesPath,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; {
|
||||
options = {
|
||||
nixpkgs.crossOverlays = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
config = {
|
||||
nixpkgs = {
|
||||
system = mkDefault "x86_64-linux";
|
||||
pkgs = let
|
||||
pkgsReval = import pkgs.path {
|
||||
inherit (config.nixpkgs) localSystem crossSystem crossOverlays;
|
||||
inherit (pkgs) overlays config;
|
||||
};
|
||||
in
|
||||
mkDefault (
|
||||
if config.nixpkgs.config == pkgs.config && config.nixpkgs.system == pkgs.targetPlatform.system
|
||||
then pkgs
|
||||
else pkgsReval
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
nixpkgs = {
|
||||
system = mkDefault "x86_64-linux";
|
||||
pkgs =
|
||||
let
|
||||
pkgsReval = import pkgs.path {
|
||||
inherit (config.nixpkgs) localSystem crossSystem crossOverlays;
|
||||
inherit (pkgs) overlays config;
|
||||
};
|
||||
in
|
||||
mkDefault (if config.nixpkgs.config == pkgs.config && config.nixpkgs.system == pkgs.targetPlatform.system then pkgs else pkgsReval);
|
||||
};
|
||||
};
|
||||
};
|
||||
nixosType =
|
||||
let
|
||||
baseModules = import (config.network.nixos.modulesPath + "/module-list.nix");
|
||||
in
|
||||
types.submoduleWith {
|
||||
modules = baseModules
|
||||
++ singleton nixosModule
|
||||
++ config.network.nixos.extraModules;
|
||||
nixosType = let
|
||||
baseModules = import (config.network.nixos.modulesPath + "/module-list.nix");
|
||||
in
|
||||
types.submoduleWith {
|
||||
modules =
|
||||
baseModules
|
||||
++ singleton nixosModule
|
||||
++ config.network.nixos.extraModules;
|
||||
|
||||
specialArgs = {
|
||||
inherit baseModules;
|
||||
inherit (config.network.nixos) modulesPath;
|
||||
} // config.network.nixos.specialArgs;
|
||||
};
|
||||
specialArgs =
|
||||
{
|
||||
inherit baseModules;
|
||||
inherit (config.network.nixos) modulesPath;
|
||||
}
|
||||
// config.network.nixos.specialArgs;
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = types.attrsOf nixosType;
|
||||
default = { };
|
||||
};
|
||||
nodes.darwin =
|
||||
let
|
||||
darwinModule = { name, config, meta, modulesPath, lib, ... }: with lib; {
|
||||
config = {
|
||||
_module.args.pkgs = pkgs;
|
||||
nixpkgs = {
|
||||
system = mkDefault pkgs.system;
|
||||
};
|
||||
};
|
||||
};
|
||||
darwinType =
|
||||
let
|
||||
baseModules = import (config.network.darwin.modulesPath + "/module-list.nix");
|
||||
flakeModule = (config.network.darwin.modulesPath + "/system/flake-overrides.nix");
|
||||
in
|
||||
types.submoduleWith {
|
||||
modules = baseModules
|
||||
++ singleton darwinModule
|
||||
++ singleton flakeModule
|
||||
++ config.network.darwin.extraModules;
|
||||
|
||||
specialArgs = {
|
||||
inherit baseModules;
|
||||
inherit (config.network.darwin) modulesPath;
|
||||
} // config.network.darwin.specialArgs;
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = types.attrsOf darwinType;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config.network = {
|
||||
esphome = {
|
||||
extraModules = [
|
||||
meta.modules.esphome
|
||||
];
|
||||
specialArgs = {
|
||||
target = config.deploy.targets.home;
|
||||
inherit (config.network) nodes;
|
||||
inherit inputs meta;
|
||||
};
|
||||
};
|
||||
darwin = {
|
||||
extraModules = [
|
||||
inputs.home-manager.darwinModules.home-manager
|
||||
meta.modules.system
|
||||
meta.modules.type
|
||||
meta.system
|
||||
];
|
||||
specialArgs = {
|
||||
inherit (config.network) nodes;
|
||||
inherit inputs meta;
|
||||
};
|
||||
};
|
||||
nixos = {
|
||||
extraModules = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
meta.modules.nixos
|
||||
meta.modules.system
|
||||
meta.modules.type
|
||||
meta.system
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
meta.modules.nixos
|
||||
meta.system
|
||||
];
|
||||
specialArgs = {
|
||||
inherit (config.network) nodes;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
{ config, lib, ... }: with lib; {
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; {
|
||||
options = {
|
||||
networks = mkOption {
|
||||
type = with types; attrsOf (submodule ({ name, config, ... }: {
|
||||
type = with types;
|
||||
attrsOf (submodule ({
|
||||
name,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
member_configs = mkOption {
|
||||
type = unspecified;
|
||||
|
|
@ -10,17 +20,18 @@
|
|||
type = unspecified;
|
||||
};
|
||||
};
|
||||
}));
|
||||
}));
|
||||
};
|
||||
};
|
||||
config = {
|
||||
networks = let
|
||||
names = [ "gensokyo" "chitei" "internet" "tailscale" ];
|
||||
network_filter = network: rec {
|
||||
member_configs = filterAttrs (_: nodeConfig: nodeConfig.networks.${network}.interfaces != []) config.network.nodes.nixos;
|
||||
members = mapAttrs (_: nodeConfig: nodeConfig.networks.${network}) member_configs;
|
||||
};
|
||||
networks' = genAttrs names network_filter;
|
||||
in networks';
|
||||
names = ["gensokyo" "chitei" "internet" "tailscale"];
|
||||
network_filter = network: rec {
|
||||
member_configs = filterAttrs (_: nodeConfig: nodeConfig.networks.${network}.interfaces != []) config.network.nodes;
|
||||
members = mapAttrs (_: nodeConfig: nodeConfig.networks.${network}) member_configs;
|
||||
};
|
||||
networks' = genAttrs names network_filter;
|
||||
in
|
||||
networks';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
{ config, pkgs, lib, ... }: with lib; {
|
||||
options.secrets.command = mkOption {
|
||||
type = types.str;
|
||||
default = let
|
||||
bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.network.nodes.all.${builtins.getEnv "HOME_HOSTNAME"}.secrets.repo.bitw.source} "$@"'';
|
||||
in
|
||||
"${bitw}/bin/bitw get";
|
||||
};
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
{ config, pkgs, lib, tree, ... }: with lib; let
|
||||
home = config.deploy.targets.home.tf;
|
||||
in {
|
||||
imports = lib.optional (tree.pure.trusted ? modules.meta) tree.pure.trusted.modules.meta.tailscale;
|
||||
options = {
|
||||
tailnet_uri = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
tailnet = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
ipv4 = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
ipv6 = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
pp = mkOption {
|
||||
type = types.unspecified;
|
||||
default = family: port: "http://${config."ipv${toString family}"}:${toString port}/";
|
||||
};
|
||||
ppp = mkOption {
|
||||
type = types.unspecified;
|
||||
default = family: port: path: "http://${config."ipv${toString family}"}:${toString port}/${path}";
|
||||
};
|
||||
tags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
config = {
|
||||
tailnet_uri = "inskip.me";
|
||||
tailnet = let
|
||||
raw = home.resources.tailnet_devices.importAttr "devices";
|
||||
in mkIf (home.state.enable) (mapListToAttrs (elet: nameValuePair (removeSuffix ".${config.tailnet_uri}" elet.name) {
|
||||
tags = elet.tags;
|
||||
id = elet.id;
|
||||
user = elet.user;
|
||||
ipv4 = head (filter (e: hasInfix "." e) elet.addresses);
|
||||
ipv6 = head (filter (e: hasInfix ":" e) elet.addresses);
|
||||
}) raw);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
{ tf, target, name, meta, config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
|
||||
* marries meta config to NixOS configs for each host.
|
||||
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy;
|
||||
unmergedValues = types.mkOptionType {
|
||||
name = "unmergedValues";
|
||||
merge = loc: defs: map (def: def.value) defs;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.deploy = {
|
||||
targetName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
system = mkOption {
|
||||
type = types.unspecified;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
options.deploy.tf = mkOption {
|
||||
type = types.submodule {
|
||||
inherit (unmerged) freeformType;
|
||||
|
||||
options = {
|
||||
import = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
imports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Other targets to depend on";
|
||||
default = [ ];
|
||||
};
|
||||
attrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
out.set = mkOption { type = types.unspecified; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
deploy = {
|
||||
system = config.system.build.toplevel;
|
||||
targetName = let targetsList = attrNames (filterAttrs (_: target: target.enable && elem name target.nodeNames) meta.deploy.targets); in
|
||||
if (builtins.length targetsList == 0) then null
|
||||
else lib.warnIf (builtins.length targetsList > 1) "The host ${name} is assigned to several targets: ${concatMapStrings (x: "${x},") targetsList}." (head targetsList);
|
||||
};
|
||||
deploy.tf = mkMerge (singleton
|
||||
(lib.mkIf (config.deploy.targetName != null) {
|
||||
attrs = [ "import" "imports" "out" "attrs" ];
|
||||
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
|
||||
out.set = removeAttrs cfg.tf cfg.tf.attrs;
|
||||
deploy.systems.${config.networking.hostName} =
|
||||
with tf.resources; {
|
||||
isRemote =
|
||||
(config.networking.hostName != builtins.getEnv "HOME_HOSTNAME");
|
||||
nixosConfig = config;
|
||||
connection = tf.resources.${config.networking.hostName}.connection.set;
|
||||
triggers.copy.${config.networking.hostName} =
|
||||
tf.resources.${config.networking.hostName}.refAttr "id";
|
||||
triggers.secrets.${config.networking.hostName} =
|
||||
tf.resources.${config.networking.hostName}.refAttr "id";
|
||||
};
|
||||
}) ++ mapAttrsToList
|
||||
(_: user:
|
||||
mapAttrs (_: mkMerge) user.deploy.tf.out.set)
|
||||
config.home-manager.users);
|
||||
|
||||
_module.args.target = mapNullable (targetName: meta.deploy.targets.${targetName}) cfg.targetName;
|
||||
_module.args.tf = mapNullable (target: target.tf) target;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{ config, lib, ... }: with lib; {
|
||||
options.hardware.displays = mkOption {
|
||||
type = with types; attrsOf (submodule ({ config, ... }: {
|
||||
options = {
|
||||
pos = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
res = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
|
@ -1,391 +1,26 @@
|
|||
{ config, lib, tf, pkgs, meta, ... }: with lib; {
|
||||
imports = with meta; [
|
||||
nixos.sops
|
||||
];
|
||||
options = let
|
||||
nixos = config;
|
||||
in {
|
||||
domains = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
host = mkOption {
|
||||
type = nullOr str;
|
||||
default = nixos.networking.hostName;
|
||||
};
|
||||
owner = mkOption {
|
||||
type = str;
|
||||
default = "nginx";
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = "domain-auth";
|
||||
};
|
||||
network = mkOption {
|
||||
type = unspecified;
|
||||
default = "internet";
|
||||
};
|
||||
type = mkOption {
|
||||
type = types.enum [
|
||||
"ipv4"
|
||||
"ipv6"
|
||||
"both"
|
||||
"cname"
|
||||
];
|
||||
};
|
||||
create_cert = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = nullOr str;
|
||||
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
|
||||
};
|
||||
cname = mkOption {
|
||||
type = nullOr str;
|
||||
default = "${config.domain}.${config.zone}";
|
||||
};
|
||||
prefix = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
uqdn = mkOption {
|
||||
type = nullOr str;
|
||||
default = (if config.domain == "@" then (removeSuffix "." config.zone) else (removeSuffix "." config.target));
|
||||
};
|
||||
zone = mkOption {
|
||||
type = nullOr str;
|
||||
default = "kittywit.ch.";
|
||||
};
|
||||
key_path = mkOption {
|
||||
type = nullOr str;
|
||||
default = if config.create_cert then nixos.secrets.files."${lib.removeSuffix "." config.cname}-key".path else null;
|
||||
};
|
||||
cert_path = mkOption {
|
||||
type = nullOr str;
|
||||
default = if config.create_cert then nixos.secrets.files."${lib.removeSuffix "." config.cname}-cert".path else null;
|
||||
};
|
||||
target = mkOption {
|
||||
type = nullOr str;
|
||||
default = if (config.type == "cname" && config.host != nixos.networking.hostName) then
|
||||
meta.network.nodes.nixos.${config.host}.networks.${config.network}.target
|
||||
else "${if config.domain == null then "" else "${config.domain}."}${config.zone}";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
networks = let
|
||||
nixos = config;
|
||||
in mkOption {
|
||||
default = { };
|
||||
type = with types; attrsOf (submodule ({ name, config, options, ... }: let
|
||||
portRangeModule = { config, ... }: {
|
||||
options = {
|
||||
from = mkOption {
|
||||
type = types.port;
|
||||
};
|
||||
to = mkOption {
|
||||
type = types.port;
|
||||
default = config.from;
|
||||
};
|
||||
/*isRange = mkOption {
|
||||
type = types.bool;
|
||||
default = assert config.to >= config.from; config.from != config.to;
|
||||
readOnly = true;
|
||||
};*/
|
||||
};
|
||||
};
|
||||
portRangeType = types.submodule portRangeModule;
|
||||
convToPort = value: if isInt value
|
||||
then { from = value; }
|
||||
else assert length value == 2; { from = elemAt value 0; to = elemAt value 1; };
|
||||
portType = coercedTo (oneOf [ int (listOf int) ]) convToPort portRangeType;
|
||||
in {
|
||||
options = with types; {
|
||||
interfaces = mkOption {
|
||||
description = "Interfaces this network operates upon.";
|
||||
type = listOf str;
|
||||
default = [];
|
||||
};
|
||||
tcp = mkOption {
|
||||
description = "Port numbers or ranges to allow TCP traffic outbound.";
|
||||
type = listOf portType;
|
||||
default = [];
|
||||
};
|
||||
udp = mkOption {
|
||||
description = "Port numbers or ranges to allow UDP traffic outbound.";
|
||||
type = listOf portType;
|
||||
default = [];
|
||||
};
|
||||
ip = mkOption {
|
||||
description = "The machine's IPv4 address on the network, if it has one.";
|
||||
type = unspecified;
|
||||
default = hostname: class: if hostname != nixos.networking.hostName then
|
||||
if class == 6 then
|
||||
config.ipv6
|
||||
else if class == 4 then
|
||||
config.ipv4
|
||||
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid."
|
||||
else
|
||||
if class == 6 then
|
||||
config.ipv6
|
||||
else if class == 4 then
|
||||
config.ipv4
|
||||
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid.";
|
||||
};
|
||||
ipv4 = mkOption {
|
||||
description = "The machine's IPv4 address on the network, if it has one.";
|
||||
type = nullOr str;
|
||||
};
|
||||
ipv6 = mkOption {
|
||||
description = "The machine's IPv6 address on the network, if it has one.";
|
||||
type = nullOr str;
|
||||
};
|
||||
ipv4_defined = mkOption {
|
||||
type = types.bool;
|
||||
default = options.ipv4.isDefined;
|
||||
};
|
||||
ipv6_defined = mkOption {
|
||||
type = types.bool;
|
||||
default = options.ipv6.isDefined;
|
||||
};
|
||||
create_domain = mkOption {
|
||||
type = bool;
|
||||
default = config.extra_domains != [];
|
||||
};
|
||||
create_cert = mkOption {
|
||||
type = bool;
|
||||
default = config.extra_domains != [];
|
||||
};
|
||||
extra_domains = mkOption {
|
||||
type = listOf str;
|
||||
description = "Domains to add to the certificate generated for this network.";
|
||||
default = [];
|
||||
};
|
||||
key_path = mkOption {
|
||||
type = nullOr str;
|
||||
default = if config.create_cert && config.interfaces != [] then nixos.secrets.files."${lib.removeSuffix "." config.target}-key".path else null;
|
||||
};
|
||||
cert_path = mkOption {
|
||||
type = nullOr str;
|
||||
default = if config.create_cert && config.interfaces != [] then nixos.secrets.files."${lib.removeSuffix "." config.target}-cert".path else null;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = nullOr str;
|
||||
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
|
||||
};
|
||||
prefix = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
zone = mkOption {
|
||||
type = nullOr str;
|
||||
default = "kittywit.ch.";
|
||||
};
|
||||
uqdn = mkOption {
|
||||
type = nullOr str;
|
||||
default = (if config.domain == "@" then (removeSuffix "." config.zone) else (removeSuffix "." config.target));
|
||||
};
|
||||
target = mkOption {
|
||||
type = nullOr str;
|
||||
default = "${config.domain}.${config.zone}";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
meta,
|
||||
...
|
||||
}:
|
||||
with lib; {
|
||||
options.deploy.system = mkOption {
|
||||
type = types.unspecified;
|
||||
readOnly = true;
|
||||
};
|
||||
config = let
|
||||
sane_networks = lib.filterAttrs (network: settings: settings.interfaces != []) config.networks;
|
||||
in {
|
||||
networks = {
|
||||
internet = {
|
||||
zone = mkDefault "kittywit.ch.";
|
||||
create_domain = true;
|
||||
};
|
||||
chitei = {
|
||||
zone = mkDefault "kittywit.ch.";
|
||||
create_domain = false;
|
||||
};
|
||||
gensokyo = {
|
||||
zone = mkDefault "gensokyo.zone.";
|
||||
create_domain = true;
|
||||
};
|
||||
tailscale = mkMerge [
|
||||
(mkIf tf.state.enable {
|
||||
ipv4 = mkForce meta.tailnet.${config.networking.hostName}.ipv4 or null;
|
||||
ipv6 = mkForce meta.tailnet.${config.networking.hostName}.ipv6 or null;
|
||||
})
|
||||
{
|
||||
ipv4 = mkDefault "wawawawaawa";
|
||||
ipv6 = mkDefault "awawawawawa";
|
||||
interfaces = singleton "tailscale0";
|
||||
zone = "inskip.me.";
|
||||
create_domain = true;
|
||||
create_cert = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
config = {
|
||||
deploy.system = config.system.build.toplevel;
|
||||
|
||||
networking.domain = "inskip.me";
|
||||
|
||||
deploy.tf = {
|
||||
dns.records = let
|
||||
# Families of address to create domains for
|
||||
address_families = [ "ipv4" "ipv6" ];
|
||||
domains = config.domains;
|
||||
# Merge the result of a map upon address_families to mapAttrs'
|
||||
domains' = map (family: mapAttrs' (name: settings: let
|
||||
network = if settings.host != config.networking.hostName then
|
||||
meta.network.nodes.nixos.${settings.host}.networks.${settings.network}
|
||||
else sane_networks.${settings.network};
|
||||
in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${if settings.domain == "@" then "root" else settings.domain}-${settings.zone}" ({
|
||||
inherit (settings) zone;
|
||||
enable = mkDefault false;
|
||||
} // optionalAttrs (settings.domain != null && settings.domain != "" && settings.domain != "@") {
|
||||
inherit (settings) domain;
|
||||
} // optionalAttrs (settings.domain == null || settings.domain == "" || settings.domain == "@") {
|
||||
enable = mkForce true;
|
||||
} // (optionalAttrs (settings.type == "cname" && family == "ipv4") {
|
||||
cname = { inherit (network) target; };
|
||||
enable = mkForce true;
|
||||
}) // (optionalAttrs (network.ipv6_defined && family == "ipv6" && (settings.type == "both" || settings.type == family)) {
|
||||
aaaa.address = network.ipv6;
|
||||
enable = mkForce network.ipv6_defined;
|
||||
})
|
||||
// (optionalAttrs (!network.ipv4_defined && !network.ipv6_defined) {
|
||||
a.address = "127.0.0.1";
|
||||
enable = mkForce false;
|
||||
}) // (optionalAttrs (network.ipv4_defined && family == "ipv4" && (settings.type == "both" || settings.type == family)) {
|
||||
a.address = network.ipv4;
|
||||
enable = mkForce network.ipv4_defined;
|
||||
}))) domains) address_families;
|
||||
networks = sane_networks;
|
||||
# Networks to actually create domains for
|
||||
networks' = filterAttrs (_: settings: settings.create_domain) networks;
|
||||
# Extra domains to automatically be cnamed
|
||||
extraDomainedNetworks = filterAttrs (_: settings: settings.extra_domains != []) networks';
|
||||
extraDomains = listToAttrs (concatLists (mapAttrsToList (network: settings:
|
||||
map (domain: let
|
||||
split_domain = splitString "." domain;
|
||||
isRoot = (length split_domain) <= 2;
|
||||
in nameValuePair "${network}-cname-${if isRoot then "root" else elemAt split_domain ((length split_domain) - 2)}-${concatStringsSep "." (sublist (length split_domain - 2) (length split_domain) split_domain)}." {
|
||||
zone = if isRoot then "${domain}." else "${concatStringsSep "." (sublist ((length split_domain) - 2) (length split_domain) split_domain)}.";
|
||||
enable = !isRoot;
|
||||
domain = if isRoot then "@"
|
||||
else elemAt split_domain (length split_domain - 2);
|
||||
cname = { inherit (settings) target; };
|
||||
}) settings.extra_domains) extraDomainedNetworks));
|
||||
# Merge the result of a map upon address_families to mapAttrs'
|
||||
networks'' = map (family: mapAttrs' (network: settings:
|
||||
nameValuePair "${network}-${family}-${settings.domain}-${settings.zone}" ({
|
||||
inherit (settings) zone domain;
|
||||
} // (if family == "ipv6" then {
|
||||
aaaa.address = settings.ipv6;
|
||||
enable = mkForce settings.ipv6_defined;
|
||||
} else {
|
||||
enable = mkForce settings.ipv4_defined;
|
||||
a.address = settings.ipv4;
|
||||
})
|
||||
)) networks') address_families;
|
||||
in mkMerge (if tf.state.enable then (networks'' ++ domains' ++ [ extraDomains ]) else []);
|
||||
|
||||
acme = let
|
||||
home = meta.deploy.targets.home.tf;
|
||||
in {
|
||||
certs = let
|
||||
nvP = network: settings: nameValuePair settings.uqdn {
|
||||
keyType = "4096";
|
||||
dnsNames = [ settings.uqdn ] ++ (lib.optionals (settings ? extra_domains) settings.extra_domains);
|
||||
};
|
||||
network_certs = mapAttrs' nvP (filterAttrs (network: settings: settings.create_cert) sane_networks);
|
||||
domain_certs = mapAttrs' nvP (filterAttrs (network: settings: settings.create_cert) config.domains);
|
||||
in domain_certs // network_certs;
|
||||
};
|
||||
|
||||
variables = {
|
||||
tailscale-authkey.export = true;
|
||||
tailscale-apikey = {
|
||||
value.shellCommand = "${meta.secrets.command} secrets/tailscale -f api_key";
|
||||
sensitive = true;
|
||||
export = true;
|
||||
};
|
||||
};
|
||||
providers.tailscale = {
|
||||
inputs = {
|
||||
api_key = tf.variables.tailscale-apikey.ref;
|
||||
tailnet = "inskip.me";
|
||||
};
|
||||
};
|
||||
resources.tailnet_device_key = {
|
||||
provider = "tailscale";
|
||||
type = "device_key";
|
||||
inputs = {
|
||||
device_id = meta.tailnet.${config.networking.hostName}.id;
|
||||
key_expiry_disabled = true;
|
||||
};
|
||||
};
|
||||
resources.tailnet_key = {
|
||||
provider = "tailscale";
|
||||
type = "tailnet_key";
|
||||
inputs = {
|
||||
reusable = false;
|
||||
ephemeral = false;
|
||||
preauthorized = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
sops.secrets.tailscale-key = { };
|
||||
|
||||
services.nginx.virtualHosts = let
|
||||
networkVirtualHosts = concatLists (mapAttrsToList (network: settings: map(domain: nameValuePair (if domain != "@" then domain else settings.zone) {
|
||||
}) ([ settings.uqdn ] ++ settings.extra_domains)) (filterAttrs (_: settings: settings.create_cert) sane_networks));
|
||||
domainVirtualHosts = (filterAttrs (network: settings: settings.create_cert) config.domains);
|
||||
domainVirtualHosts' = (mapAttrsToList (network: settings: let
|
||||
in nameValuePair settings.uqdn {
|
||||
}) domainVirtualHosts);
|
||||
in listToAttrs (networkVirtualHosts ++ (lib.optionals config.services.nginx.enable domainVirtualHosts'));
|
||||
|
||||
users.groups.domain-auth = {
|
||||
gid = 10600;
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
interfaces = mkMerge (mapAttrsToList (network: settings:
|
||||
genAttrs settings.interfaces (_: { allowedTCPPortRanges = settings.tcp; allowedUDPPortRanges = settings.udp; })
|
||||
) (removeAttrs sane_networks ["tailscale"]));
|
||||
trustedInterfaces = [ "tailscale0" ];
|
||||
allowedTCPPorts = [ 5200 ];
|
||||
allowedUDPPorts = [ config.services.tailscale.port ];
|
||||
trustedInterfaces = ["tailscale0"];
|
||||
allowedTCPPorts = [5200];
|
||||
allowedUDPPorts = [config.services.tailscale.port];
|
||||
};
|
||||
|
||||
services.tailscale.enable = true;
|
||||
|
||||
systemd.services.tailscale-autoconnect = {
|
||||
description = "Automatic connection to Tailscale";
|
||||
|
||||
# make sure tailscale is running before trying to connect to tailscale
|
||||
after = [ "network-pre.target" "tailscale.service" ];
|
||||
wants = [ "network-pre.target" "tailscale.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
# set this service as a oneshot job
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
# have the job run this shell script
|
||||
script = with pkgs; ''
|
||||
# wait for tailscaled to settle
|
||||
sleep 2
|
||||
|
||||
# check if we are already authenticated to tailscale
|
||||
status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
|
||||
if [ $status = "Running" ]; then # if so, then do nothing
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# otherwise authenticate with tailscale
|
||||
# to-do: --advertise-exit-node
|
||||
${tailscale}/bin/tailscale up -authkey $(cat ${config.sops.secrets.tailscale-key.path})
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
{ config, lib, pkgs, tf, ... }: let
|
||||
inherit (lib.types) unspecified isType;
|
||||
inherit (lib.options) mkEnableOption mkOption;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs' nameValuePair mapAttrsToList;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
cfg = config.services.pounce;
|
||||
in {
|
||||
options.services.pounce = {
|
||||
enable = mkEnableOption "Pounce BNC";
|
||||
servers = mkOption {
|
||||
type = unspecified;
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable) {
|
||||
#services.pounce.servers = builtins.fromJSON tf.variables."pounce-config".import;
|
||||
secrets = {
|
||||
variables = (mapAttrs' (server: config:
|
||||
nameValuePair "pounce-${server}-cert" {
|
||||
path = "gensokyo/pounce";
|
||||
field = "${server}-cert";
|
||||
}
|
||||
) cfg.servers) // (mapAttrs' (server: config:
|
||||
nameValuePair "pounce-${server}-password" {
|
||||
path = "gensokyo/pounce";
|
||||
field = "${server}-password";
|
||||
}
|
||||
) cfg.servers) // {
|
||||
"pounce-config" = {
|
||||
path = "gensokyo/pounce";
|
||||
field = "notes";
|
||||
};
|
||||
};
|
||||
files = (mapAttrs' (server: config:
|
||||
nameValuePair "pounce-${server}-config" {
|
||||
text = concatStringsSep "\n" (mapAttrsToList (key: value: if (builtins.typeOf value == "bool") then "${key}"
|
||||
else if (builtins.typeOf value == "int") then "${key} = ${builtins.toString value}"
|
||||
else if (builtins.typeOf value == "list") then "${key} = ${concatStringsSep "," value}" else "${key} = ${value}") config);
|
||||
owner = "pounce";
|
||||
group = "pounce";
|
||||
}
|
||||
) cfg.servers) // (mapAttrs' (server: config:
|
||||
nameValuePair "pounce-${server}-cert" {
|
||||
text = tf.variables."pounce-${server}-cert".ref;
|
||||
owner = "pounce";
|
||||
group = "domain-auth";
|
||||
}
|
||||
) cfg.servers);
|
||||
};
|
||||
users.users.pounce = {
|
||||
uid = 1501;
|
||||
isSystemUser = true;
|
||||
group = "domain-auth";
|
||||
};
|
||||
systemd.services = mapAttrs' (name: text: nameValuePair "pounce-${name}" {
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
ExecStart = "${pkgs.pounce}/bin/pounce ${config.secrets.file."pounce-${name}-config".path}";
|
||||
WorkingDirectory = "/var/lib/pounce";
|
||||
User = "pounce";
|
||||
Group = "domain-auth";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
}) cfg.servers;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{ config, lib, meta, ... }: with lib; {
|
||||
config = mkIf (config.secrets.variables != { }) {
|
||||
deploy.tf.variables = mapAttrs'
|
||||
(name: content:
|
||||
nameValuePair name ({
|
||||
value.shellCommand = "${meta.secrets.command} ${content.path}" + optionalString (content.field != "") " -f ${content.field}";
|
||||
type = "string";
|
||||
sensitive = true;
|
||||
})
|
||||
)
|
||||
config.secrets.variables;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
{ config, lib, pkgs, meta, tf, ... }: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
inherit (lib.attrsets) mapAttrs filterAttrs mapAttrsToList attrValues;
|
||||
inherit (lib.lists) concatLists;
|
||||
inherit (lib.types) attrsOf listOf str;
|
||||
cfg = config.storage;
|
||||
in {
|
||||
options.storage = {
|
||||
enable = mkEnableOption "nixfiles storage primitives";
|
||||
replica = mkEnableOption "full replication of our volumes onto a node";
|
||||
defaultBrick = mkEnableOption "naively create a default brick for this node";
|
||||
bricks = mkOption {
|
||||
type = attrsOf str;
|
||||
default = if cfg.defaultBrick then {
|
||||
default = "/export/default/brick";
|
||||
} else {};
|
||||
description = "the brick locations used by glusterfs";
|
||||
};
|
||||
replicas = mkOption {
|
||||
type = listOf str;
|
||||
default = let
|
||||
replicaNodes = filterAttrs (_: node: node.storage.replica) config.network.nodes.nixos;
|
||||
in concatLists (mapAttrsToList (_: node: map (brick: "${node.networks.tailscale.uqdn}:${brick}" (attrValues node.storage.bricks)) replicaNodes));
|
||||
};
|
||||
services = mkOption {
|
||||
type = listOf str;
|
||||
default = let
|
||||
filteredServices = removeAttrs config.services [
|
||||
"chronos" "beegfs" "beegfsEnable" "bird"
|
||||
"bird6" "bitwarden_rs" "buildkite-agent" "cgmanager"
|
||||
"codimd" "couchpotato" "cryptpad" "dd-agent"
|
||||
"deepin" "dnscrypt-proxy" "flashpolicyd" "dhcpd"
|
||||
"foldingAtHome" "fourStore" "fourStoreEndpoint" "fprot"
|
||||
"frab" "geoip-updater" "gogoclient" "hbase"
|
||||
"iodined" "kippo" "localtime" "mailpile"
|
||||
"marathon" "mathics" "meguca" "mesos"
|
||||
"mingetty" "moinmoin" "mwlib" "nixosManual"
|
||||
"openfire" "openvpn" "osquery" "paperless-ng"
|
||||
"piwik" "plexpy" "prey" "prometheus2"
|
||||
"quagga" "racoon" "railcar" "redis"
|
||||
"riak" "rmilter" "seeks" "shellinabox"
|
||||
"ssmtp" "venus" "virtuoso" "vmwareGuest"
|
||||
"wakeonlan" "winstone" "nginx"
|
||||
];
|
||||
#enabledServices = filterAttrs (_: settings: (settings ? enable) && settings.enable) filteredServices;
|
||||
enabledServices = filterAttrs (_: service: service ? serviceConfig.RuntimeDirectory) config.systemd.services;
|
||||
serviceDirs = mapAttrsToList (service: _: service) enabledServices;
|
||||
in serviceDirs;
|
||||
};
|
||||
};
|
||||
config = mkMerge [
|
||||
(mkIf false {
|
||||
environment.systemPackages = [ pkgs.glusterfs ];
|
||||
|
||||
services.glusterfs = {
|
||||
enable = true;
|
||||
tlsSettings = {
|
||||
tlsKeyPath = config.networks.tailscale.key_path;
|
||||
tlsPem = config.networks.tailscale.cert_path;
|
||||
};
|
||||
};
|
||||
|
||||
deploy.tf = {
|
||||
};
|
||||
})
|
||||
(mkIf cfg.defaultBrick {
|
||||
system.activationScripts.nixfiles-storage-defaultbrick.text = ''
|
||||
mkdir -p /export/default/brick
|
||||
'';
|
||||
})
|
||||
(mkIf cfg.replica {
|
||||
deploy.tf = {
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{ config, lib, meta, ... }: with lib; {
|
||||
secrets.variables = lib.mkMerge (mapAttrsToList (username: user: user.secrets.variables) config.home-manager.users);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{ config, meta, lib, name, ... }: with lib;
|
||||
let
|
||||
home = meta.deploy.targets.home.tf;
|
||||
in lib.mkIf (name != "home") {
|
||||
acme = {
|
||||
enable = true;
|
||||
account = {
|
||||
register = lib.mkDefault false;
|
||||
emailAddress = "kat@inskip.me";
|
||||
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
|
||||
};
|
||||
challenge = {
|
||||
defaultProvider = "rfc2136";
|
||||
configs.rfc2136 = {
|
||||
RFC2136_NAMESERVER = config.variables.katdns-address.ref;
|
||||
RFC2136_TSIG_KEY = config.variables.katdns-name.ref;
|
||||
RFC2136_TSIG_SECRET = config.variables.katdns-key.ref;
|
||||
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{ config, ... }: {
|
||||
deploy.gcroot.enable = true;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{ config, meta, lib, ... }: with lib; {
|
||||
|
||||
variables.katdns-address = {
|
||||
value.shellCommand = "${meta.secrets.command} secrets/katdns -f address";
|
||||
type = "string";
|
||||
sensitive = true;
|
||||
};
|
||||
variables.katdns-name = {
|
||||
value.shellCommand = "${meta.secrets.command} secrets/katdns -f username";
|
||||
type = "string";
|
||||
sensitive = true;
|
||||
};
|
||||
variables.katdns-key = {
|
||||
value.shellCommand = "${meta.secrets.command} secrets/katdns -f password";
|
||||
type = "string";
|
||||
sensitive = true;
|
||||
};
|
||||
|
||||
providers.katdns = {
|
||||
type = "dns";
|
||||
inputs.update = {
|
||||
server = config.variables.katdns-address.ref;
|
||||
key_name = config.variables.katdns-name.ref;
|
||||
key_secret = config.variables.katdns-key.ref;
|
||||
key_algorithm = "hmac-sha512";
|
||||
};
|
||||
};
|
||||
|
||||
dns.zones = genAttrs [ "inskip.me." "kittywit.ch." "dork.dev." "gensokyo.zone." ] (_: {
|
||||
provider = "dns.katdns";
|
||||
});
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{ config, lib, ... }: with lib; let
|
||||
secretType = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
path = mkOption { type = types.str; };
|
||||
field = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
});
|
||||
repoSecretType = types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
};
|
||||
text = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
});
|
||||
in {
|
||||
options.secrets = {
|
||||
variables = mkOption {
|
||||
type = types.attrsOf secretType;
|
||||
default = { };
|
||||
};
|
||||
repo = mkOption {
|
||||
type = types.attrsOf repoSecretType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue