wip
This commit is contained in:
@@ -4,36 +4,60 @@ let
|
||||
serverCfg = config.syscfg.server;
|
||||
|
||||
in {
|
||||
sops = true;
|
||||
db = false;
|
||||
vm = {
|
||||
portForward = [ 8123 ];
|
||||
cfg = {cfg,...}:{
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
|
||||
paths = [{
|
||||
path = "${serverCfg.configPath}/homeassistant/";
|
||||
mode = "0755";
|
||||
}];
|
||||
extraComponents = [
|
||||
"matter" "thread" "cast" "zha"
|
||||
"default_config" "met" "esphome" "radio_browser"
|
||||
"telegram_bot" "swiss_public_transport" "nextcloud" "jellyfin"
|
||||
] ++ (if containerCfg.extra ? components then containerCfg.extra.components else []);
|
||||
|
||||
|
||||
extraPackages = pp: with pp; [
|
||||
python-telegram gtts
|
||||
];
|
||||
lovelaceConfig = {};
|
||||
|
||||
config = {
|
||||
homeassistant = {
|
||||
name = "Home";
|
||||
latitude = "${if containerCfg.extra ? latitude then toString containerCfg.extra.latitude else toString 0}";
|
||||
longitude = "${if containerCfg.extra ? longitude then toString containerCfg.extra.longitude else toString 0}";
|
||||
elevation = "${if containerCfg.extra ? elevation then toString containerCfg.extra.elevation else toString 0}";
|
||||
unit_system = "metric";
|
||||
time_zone = config.time.timeZone;
|
||||
};
|
||||
lovelace = { mode = "yaml"; };
|
||||
customLovelaceModules = [];
|
||||
|
||||
# default_config = {};
|
||||
http = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "10.0.0.0/8" "127.0.0.1" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
containers = {
|
||||
server = builder.mkContainer {
|
||||
dummy = builder.mkContainer {
|
||||
subdomain = containerCfg.subdomain;
|
||||
image = "ghcr.io/home-assistant/home-assistant:${version}";
|
||||
port = 8123;
|
||||
secret = name;
|
||||
extraOptions = [
|
||||
"--network=host" # Shares host IP: fixes timeouts & MDNS discovery
|
||||
"--cap-add=NET_ADMIN" # Grants administrative network rights to fix DHCP packets
|
||||
"--cap-add=NET_RAW" # Allows raw socket parsing needed for network sniffing
|
||||
];
|
||||
overrides = {
|
||||
volumes = [
|
||||
"${serverCfg.configPath}/homeassistant/:/config"
|
||||
"/run/dbus:/run/dbus:ro"
|
||||
];
|
||||
image = "alpine:latest";
|
||||
extraLabels = {
|
||||
"traefik.http.services.${containerCfg.subdomain}.loadbalancer.server.url" = "http://${builder.hostIp}:8123";
|
||||
};
|
||||
overrides = {cmd = [ "sleep" "infinity" ];};
|
||||
};
|
||||
};
|
||||
|
||||
setup = {
|
||||
trigger = "server";
|
||||
trigger = "dummy";
|
||||
envFile = config.sops.secrets."CUSTOM".path;
|
||||
script = pkgs.writeShellScript "setup" ''
|
||||
|
||||
@@ -60,6 +84,7 @@ in {
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"time_zone":"${config.time.timeZone}"}' > /dev/null 2>&1 || true
|
||||
# We can configure many more things above !
|
||||
|
||||
${pkgs.curl} -s -X POST "$HASS_URL/api/onboarding/analytics" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
@@ -69,7 +94,6 @@ in {
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"client_id":"'"$HASS_URL"'","redirect_uri":"'"$HASS_URL"'/?auth_callback=1"}' > /dev/null 2>&1 || true
|
||||
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
3
modules/server/containers/apps/openhab.nix
Normal file
3
modules/server/containers/apps/openhab.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
{... }:{
|
||||
|
||||
}
|
||||
@@ -13,6 +13,9 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
routerName = if subpath != null
|
||||
then "${subdomain}-${lib.strings.sanitizeDerivationName subpath}"
|
||||
else subdomain;
|
||||
in {
|
||||
paths = [{
|
||||
path = "${serverCfg.dataPath}/transmission/complete";
|
||||
@@ -41,8 +44,12 @@ in {
|
||||
WHITELIST = "";# 127.0.0.1,::1,10.*";
|
||||
# HOST_WHITELIST = "traefik-server,authentik-server,authentik-worker";
|
||||
};
|
||||
extraLabels = { } // (if serverCfg.containers ? authentik then {
|
||||
"traefik.http.routers.${containerCfg.subdomain}.middlewares" = "authentik";
|
||||
extraLabels = {
|
||||
"traefik.http.routers.${routerName}.middlewares" = "transmission-rewrite";
|
||||
"traefik.http.middlewares.transmission-rewrite.replacepathregex.regex=^/p2p(.*)"
|
||||
"traefik.http.middlewares.transmission-rewrite.replacepathregex.replacement=/transmission/web$$1"
|
||||
} // (if serverCfg.containers ? authentik then {
|
||||
"traefik.http.routers.${routerName}.middlewares" = "authentik,transmission-rewrite";
|
||||
} else {});
|
||||
|
||||
overrides = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{ config, lib, pkgs, serverCfg }:
|
||||
let
|
||||
builder =
|
||||
contBuilder =
|
||||
{ image ? null, imageStream ? null, imageFile ? null
|
||||
, secret ? null
|
||||
, subdomain ? null, subpath?null, port ? 0
|
||||
, subdomain ? null, subpath?null, port ? null
|
||||
, extraEnv ? { }, extraLabels ? { }, extraOptions ? [ ]
|
||||
, overrides ? { }
|
||||
}:
|
||||
@@ -35,13 +35,40 @@ let
|
||||
"traefik.enable" = "false";
|
||||
}) // extraLabels;
|
||||
|
||||
extraOptions = extraOptions ++ [
|
||||
extraOptions = [
|
||||
"--add-host=host.containers.internal:host-gateway"
|
||||
];
|
||||
] ++ extraOptions;
|
||||
};
|
||||
in lib.recursiveUpdate base overrides;
|
||||
vmBuilder = { name, vm }: (import "${pkgs.path}/nixos/lib/eval-config.nix" {
|
||||
system = "x86_64-linux";
|
||||
modules = [ vm.cfg
|
||||
({ config, lib, modulesPath, ... }: {
|
||||
imports = [
|
||||
"${modulesPath}/profiles/qemu-guest.nix"
|
||||
"${modulesPath}/virtualisation/qemu-vm.nix"
|
||||
];
|
||||
networking.hostName = name;
|
||||
networking.useDHCP = true;
|
||||
networking.firewall.enable = false;
|
||||
services.qemuGuest.enable = true;
|
||||
system.stateVersion = "25.11";
|
||||
virtualisation = {
|
||||
memorySize = vm.memory or 2048;
|
||||
cores = vm.cores or 2;
|
||||
forwardPorts = let
|
||||
parsePortString = port: {
|
||||
from = "host";
|
||||
host.port = port;
|
||||
guest.port = port;
|
||||
};
|
||||
in if (vm ? portForward && vm.portForward != null) then map parsePortString vm.portForward else [];
|
||||
};})
|
||||
];
|
||||
}.config.system.build.vm);
|
||||
in {
|
||||
mkContainer = builder;
|
||||
mkContainer = contBuilder;
|
||||
mkVm = vmBuilder;
|
||||
mkData = { name, dir, vars?{} }: pkgs.runCommand name vars ''
|
||||
mkdir -p $out
|
||||
cp -r ${./data + "/${dir}"}/. $out/
|
||||
@@ -52,4 +79,7 @@ in {
|
||||
done
|
||||
'';
|
||||
host = "host.containers.internal";
|
||||
hostIp = if (config.virtualisation.podman.defaultNetwork.settings ? subnets)
|
||||
then (builtins.elemAt config.virtualisation.podman.defaultNetwork.settings.subnets 0).gateway
|
||||
else "10.88.0.1";
|
||||
}
|
||||
@@ -17,6 +17,7 @@ in{
|
||||
allPathConfigs = lib.concatMap (app: app.paths) appsList;
|
||||
allSetupConfigs = lib.concatMap (app: if app.setup?script then [({name = app.name; envFile="";} // app.setup)] else []) appsList;
|
||||
allCronsConfigs = lib.concatMap (app: app.cron) appsList;
|
||||
allVMConfigs = builtins.filter (app: app.vm != null) appsList;
|
||||
in{
|
||||
virtualisation.oci-containers = {
|
||||
backend = "podman";
|
||||
@@ -47,7 +48,30 @@ in{
|
||||
'';
|
||||
startAt = "weekly";
|
||||
};
|
||||
} // lib.listToAttrs (lib.concatMap (e: [{
|
||||
}
|
||||
// lib.listToAttrs (lib.concatMap (e: [{
|
||||
name = "${e.name}-vm";
|
||||
value = {
|
||||
description = "Isolated NixOS Guest VM for ${e.name}";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
QEMU_VM_REG_SND = "0";
|
||||
NIX_DISK_IMAGE = "/media/data/kvm/${e.name}-guest.qcw2";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /media/data/kvm";
|
||||
ExecStart = ''
|
||||
${builder.mkVm { name = e.name; vm = e.vm; }}/bin/run-${e.name}-vm -nographic
|
||||
'';
|
||||
};
|
||||
};
|
||||
}]) allVMConfigs)
|
||||
// lib.listToAttrs (lib.concatMap (e: [{
|
||||
name = "${e.name}-setup";
|
||||
value = {
|
||||
description = "Run ${e.name} setup";
|
||||
|
||||
@@ -29,6 +29,7 @@ in with lib; {
|
||||
|
||||
paths = lib.mkOption {type = lib.types.listOf lib.types.attrs; default = [ ];};
|
||||
containers = lib.mkOption {type = lib.types.attrsOf lib.types.attrs; default = { };};
|
||||
vm = lib.mkOption {type = lib.types.nullOr lib.types.attrs; default = null;};
|
||||
cron = lib.mkOption {type = lib.types.listOf lib.types.str; default = [ ];};
|
||||
|
||||
setup = {
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
# ===== DEV =====
|
||||
gitea.subdomain = "git";
|
||||
# ===== HOME =====
|
||||
# homeassistant.subdomain = "hass";
|
||||
# frigate = { subdomain = "hass"; subpath = "cam"; };
|
||||
openhab.subdomain = "hass";
|
||||
# trmnl = { subdomain = "hass"; subpath = "trmnl"; };
|
||||
# influx.subdomain = "metrum";
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user