mirror of
https://github.com/oqyude/nixos.git
synced 2026-10-07 20:47:14 +03:00
big refactoring
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
deviceType = "minimal";
|
||||
modules = [
|
||||
(
|
||||
# Host: "default" (device: minimal)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
inputs,
|
||||
...
|
||||
@@ -13,6 +13,3 @@
|
||||
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,18 +1,73 @@
|
||||
{ inputs, ... }@flakeContext:
|
||||
let
|
||||
lib = inputs.nixpkgs.lib;
|
||||
mkSystem = import ../lib/mkSystem.nix flakeContext;
|
||||
xlibLib = import ../lib/xlib.nix { inherit lib; };
|
||||
|
||||
# One record per host. The attribute name IS the hostname, so it is written
|
||||
# exactly once; `hostname` is only needed where the attribute name is not
|
||||
# the real hostname (the `default` entry).
|
||||
#
|
||||
# device device type, must be a key of `devices` in lib/xlib.nix
|
||||
# modules module body for this host
|
||||
hosts = {
|
||||
default = {
|
||||
hostname = "nixos";
|
||||
device = "minimal";
|
||||
modules = [ ./any.nix ];
|
||||
};
|
||||
atoridu = {
|
||||
device = "primary";
|
||||
modules = [ ./mini-pc.nix ];
|
||||
};
|
||||
rydiwo = {
|
||||
device = "secondary";
|
||||
modules = [ ./mini-laptop.nix ];
|
||||
};
|
||||
otreca = {
|
||||
device = "vds";
|
||||
modules = [ ./vds.nix ];
|
||||
};
|
||||
sapphira = {
|
||||
device = "server";
|
||||
modules = [ ./server.nix ];
|
||||
};
|
||||
wsl = {
|
||||
device = "wsl";
|
||||
modules = [ ./wsl.nix ];
|
||||
};
|
||||
};
|
||||
|
||||
mkHost =
|
||||
name:
|
||||
{
|
||||
device,
|
||||
modules,
|
||||
hostname ? name,
|
||||
...
|
||||
}:
|
||||
let
|
||||
xlib = xlibLib.mkXlib {
|
||||
inherit hostname;
|
||||
type = device;
|
||||
};
|
||||
in
|
||||
{
|
||||
nixosConfigurations = {
|
||||
default = mkSystem (import ./any.nix); # default
|
||||
atoridu = mkSystem (import ./mini-pc.nix); # atoridu
|
||||
rydiwo = mkSystem (import ./mini-laptop.nix); # rydiwo
|
||||
otreca = mkSystem (import ./vds.nix); # vds
|
||||
sapphira = mkSystem (import ./server.nix); # sapphira
|
||||
wsl = mkSystem (import ./wsl.nix); # wsl
|
||||
inherit xlib;
|
||||
system = mkSystem { inherit xlib modules; };
|
||||
};
|
||||
in
|
||||
{
|
||||
nixosConfigurations = lib.mapAttrs' (
|
||||
name: spec: lib.nameValuePair name (mkHost name spec).system
|
||||
) hosts;
|
||||
|
||||
# Per-host xlib values, for code that lives outside the module system
|
||||
# (deploy, overlays, pkgs).
|
||||
xlib = lib.mapAttrs' (name: spec: lib.nameValuePair name (mkHost name spec).xlib) hosts;
|
||||
|
||||
nixOnDroidConfigurations = {
|
||||
epral = import ./mobile.nix flakeContext; # epral (Android via nix-on-droid)
|
||||
epral = import ./mobile.nix flakeContext; # epral (Android device via nix-on-droid)
|
||||
# Alias so a plain `nix-on-droid switch` from a local clone
|
||||
# (~/.config/nix-on-droid) picks up the device config without `#epral`.
|
||||
default = import ./mobile.nix flakeContext;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
deviceType = "secondary";
|
||||
hostname = "rydiwo";
|
||||
modules = [
|
||||
(
|
||||
# Host: "rydiwo" (device: secondary)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
@@ -31,11 +30,8 @@
|
||||
mask = "0000";
|
||||
};
|
||||
|
||||
xlib.ssh.enable = true;
|
||||
host.ssh.enable = true;
|
||||
hardware.intel-gpu-tools.enable = true;
|
||||
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
+25
-24
@@ -1,8 +1,7 @@
|
||||
{
|
||||
deviceType = "primary";
|
||||
hostname = "atoridu";
|
||||
modules = [
|
||||
(
|
||||
# Host: "atoridu" (device: primary)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
@@ -18,23 +17,28 @@
|
||||
self.nixosModules.default
|
||||
];
|
||||
|
||||
fileSystems = lib.listToAttrs (
|
||||
# mkNtfsMount returns a `{ "<path>" = { ... }; }` attrset (the shape
|
||||
# fileSystems itself wants), so several mounts are combined with
|
||||
# mergeAttrsList — not listToAttrs, which would demand `name`/`value`.
|
||||
#
|
||||
# These three ntfs3 drives are intentionally left unmounted. The entries
|
||||
# are kept commented out rather than deleted, so restoring a drive is a
|
||||
# matter of uncommenting its block. `enable = false` would declare a drive
|
||||
# without mounting it; dropping the field mounts it.
|
||||
fileSystems = lib.mergeAttrsList (
|
||||
map (xlib.helpers.mkNtfsMount) [
|
||||
{
|
||||
path = xlib.dirs.therima-drive;
|
||||
uuid = "C0A2DDEFA2DDEA44";
|
||||
enable = false;
|
||||
}
|
||||
{
|
||||
path = xlib.dirs.vetymae-drive;
|
||||
uuid = "6408433908430A0E";
|
||||
enable = false;
|
||||
}
|
||||
{
|
||||
path = xlib.dirs.soptur-drive;
|
||||
uuid = "C00C56E40C56D54E";
|
||||
enable = false;
|
||||
}
|
||||
# {
|
||||
# path = xlib.dirs.therima-drive;
|
||||
# uuid = "C0A2DDEFA2DDEA44";
|
||||
# }
|
||||
# {
|
||||
# path = xlib.dirs.vetymae-drive;
|
||||
# uuid = "6408433908430A0E";
|
||||
# }
|
||||
# {
|
||||
# path = xlib.dirs.soptur-drive;
|
||||
# uuid = "C00C56E40C56D54E";
|
||||
# }
|
||||
]
|
||||
);
|
||||
|
||||
@@ -78,6 +82,3 @@
|
||||
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ let
|
||||
# (essentials, users.nix, home-manager, sops-nix, disko, grub2-themes)
|
||||
# and nixpkgs.overlays are skipped so it evaluates under nix-on-droid's
|
||||
# module system (class = "nixOnDroid").
|
||||
xlib = import ../lib/xlib.nix { lib = inputs.nixpkgs.lib; };
|
||||
nixOnDroidModule =
|
||||
{
|
||||
lib,
|
||||
@@ -21,11 +22,6 @@ let
|
||||
inputs.self.nixosModules.strict
|
||||
];
|
||||
|
||||
xlib.device = {
|
||||
type = "termux";
|
||||
hostname = "epral";
|
||||
};
|
||||
|
||||
# Login shell. nix-on-droid writes /etc/passwd from user.shell on every
|
||||
# activation, so `chsh` is useless here — set it in nix instead.
|
||||
# (default is bashInteractive)
|
||||
@@ -120,6 +116,13 @@ inputs.nix-on-droid.lib.nixOnDroidConfiguration {
|
||||
nixOnDroidModule
|
||||
];
|
||||
extraSpecialArgs = {
|
||||
deviceType = "termux";
|
||||
# `xlib` is the same value shape NixOS hosts get (lib/mkSystem.nix);
|
||||
# the hostname lives here because nixOnDroidConfigurations is keyed by
|
||||
# both "epral" and the "default" alias, so it cannot come from the
|
||||
# attribute name.
|
||||
xlib = xlib.mkXlib {
|
||||
hostname = "epral";
|
||||
type = "termux";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
deviceType = "server";
|
||||
hostname = "sapphira";
|
||||
modules = [
|
||||
(
|
||||
# Host: "sapphira" (device: server)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
@@ -63,7 +62,7 @@
|
||||
"z ${xlib.dirs.services-mnt-folder} 0777 root root -"
|
||||
];
|
||||
|
||||
xlib.ssh.enable = true;
|
||||
host.ssh.enable = true;
|
||||
|
||||
networking = {
|
||||
networkmanager.enable = true;
|
||||
@@ -78,6 +77,3 @@
|
||||
stateVersion = "25.05";
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
+5
-10
@@ -1,10 +1,8 @@
|
||||
# Host: "otreca" (device: vds)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
deviceType = "vds";
|
||||
hostname = "otreca";
|
||||
modules = [
|
||||
(
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
pkgs,
|
||||
@@ -43,7 +41,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
xlib.ssh.enable = true;
|
||||
host.ssh.enable = true;
|
||||
services.openssh.openFirewall = true;
|
||||
|
||||
services.tailscale = {
|
||||
@@ -117,6 +115,3 @@
|
||||
stateVersion = "25.05";
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
+6
-11
@@ -1,13 +1,11 @@
|
||||
# Host: "wsl" (device: wsl)
|
||||
#
|
||||
# The host record lives in configurations/default.nix; this file is only the
|
||||
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
|
||||
{
|
||||
deviceType = "wsl";
|
||||
hostname = "wsl";
|
||||
modules = [
|
||||
(
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
pkgs,
|
||||
xlib,
|
||||
inputs,
|
||||
...
|
||||
@@ -34,11 +32,8 @@
|
||||
enable = true;
|
||||
startMenuLaunchers = true;
|
||||
useWindowsDriver = true;
|
||||
defaultUser = config.xlib.device.username;
|
||||
defaultUser = xlib.device.username;
|
||||
};
|
||||
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
+3
-1
@@ -6,7 +6,9 @@ let
|
||||
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos inputs.self.nixosConfigurations.${hostname};
|
||||
};
|
||||
};
|
||||
user = "${inputs.self.nixosConfigurations.default.config.xlib.device.username}";
|
||||
# Login user for every deploy target. Read from the hoisted xlib instead of
|
||||
# digging through a built NixOS configuration.
|
||||
user = "${inputs.self.xlib.default.device.username}";
|
||||
server = "sapphira";
|
||||
vds = "otreca";
|
||||
mini-laptop = "rydiwo";
|
||||
|
||||
+1
-5
@@ -53,11 +53,7 @@ let
|
||||
imports = [
|
||||
(./. + "/${xlib.device.type}.nix")
|
||||
];
|
||||
headless = builtins.elem xlib.device.type [
|
||||
"server"
|
||||
"vds"
|
||||
"wsl"
|
||||
];
|
||||
headless = xlib.isHeadless;
|
||||
};
|
||||
};
|
||||
sharedModules = [
|
||||
|
||||
+14
-12
@@ -2,26 +2,28 @@
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
# Builds a NixOS system from a host record.
|
||||
#
|
||||
# `xlib` is the pure host value (lib/xlib.nix `mkXlib`) built in
|
||||
# configurations/default.nix. It is handed to every module as the `xlib`
|
||||
# argument, so modules read plain `xlib.*` data instead of `config.xlib.*`
|
||||
# and the host record stays the single source of truth.
|
||||
{
|
||||
deviceType,
|
||||
hostname ? null,
|
||||
xlib,
|
||||
modules ? [ ],
|
||||
system ? "x86_64-linux",
|
||||
...
|
||||
}:
|
||||
let
|
||||
lib = inputs.nixpkgs.lib;
|
||||
in
|
||||
lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = modules ++ [
|
||||
{
|
||||
xlib.device = {
|
||||
type = deviceType;
|
||||
}
|
||||
// lib.optionalAttrs (hostname != null) { inherit hostname; };
|
||||
}
|
||||
];
|
||||
inherit
|
||||
system
|
||||
modules
|
||||
;
|
||||
specialArgs = {
|
||||
inherit deviceType inputs;
|
||||
inherit inputs;
|
||||
inherit xlib;
|
||||
};
|
||||
}
|
||||
|
||||
+113
-4
@@ -2,9 +2,49 @@
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
# Shared pure helper functions for module definitions.
|
||||
# Injected into every module via `xlib.helpers` (see options.nix).
|
||||
# Pure host library: no module system involved.
|
||||
#
|
||||
# `mkXlib` derives everything a host needs to know about itself (identity,
|
||||
# well-known paths, capability flags, shared helpers) from a single record.
|
||||
# It is built in flake-level code (configurations/default.nix) and handed to
|
||||
# every module as the `xlib` argument via lib/mkSystem.nix, so modules read
|
||||
# plain `xlib.*` values instead of `config.xlib.*` and nothing in xlib can be
|
||||
# overridden per host — the host record is the only place to change it.
|
||||
let
|
||||
# Every supported device type and its capabilities. Single source of truth:
|
||||
# replaces the old `lib.types.enum` in modules/options.nix and the
|
||||
# hand-written type lists in modules/default.nix and home/home.nix.
|
||||
devices = {
|
||||
minimal = {
|
||||
desktop = false;
|
||||
headless = false;
|
||||
};
|
||||
primary = {
|
||||
desktop = true;
|
||||
headless = false;
|
||||
};
|
||||
secondary = {
|
||||
desktop = true;
|
||||
headless = false;
|
||||
};
|
||||
server = {
|
||||
desktop = false;
|
||||
headless = true;
|
||||
};
|
||||
vds = {
|
||||
desktop = false;
|
||||
headless = true;
|
||||
};
|
||||
wsl = {
|
||||
desktop = false;
|
||||
headless = true;
|
||||
};
|
||||
termux = {
|
||||
desktop = false;
|
||||
headless = true;
|
||||
};
|
||||
};
|
||||
|
||||
# tmpfiles rule: "type dir mode user group -"
|
||||
mkTmpfile =
|
||||
type: dir: mode: user: group:
|
||||
@@ -138,8 +178,8 @@ let
|
||||
name = targetPath;
|
||||
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
|
||||
}) paths;
|
||||
in
|
||||
{
|
||||
|
||||
helpers = {
|
||||
inherit
|
||||
mkTmpfile
|
||||
mkTmpDirs
|
||||
@@ -150,4 +190,73 @@ in
|
||||
mkExfatMount
|
||||
mkSymlinks
|
||||
;
|
||||
};
|
||||
|
||||
# Well-known paths. Everything derives from `username`, which is why the
|
||||
# whole set can be computed outside the module system.
|
||||
mkDirs =
|
||||
username:
|
||||
let
|
||||
user-home = "/home/${username}";
|
||||
wsl-home = "/mnt/c/Users/${username}";
|
||||
server-home = "${user-home}/External";
|
||||
services-mnt-folder = "/mnt/services";
|
||||
in
|
||||
{
|
||||
inherit
|
||||
user-home
|
||||
wsl-home
|
||||
server-home
|
||||
services-mnt-folder
|
||||
;
|
||||
|
||||
user-storage = "${user-home}/Storage";
|
||||
wsl-storage = "${wsl-home}/Storage";
|
||||
server-credentials = "${server-home}/Credentials/server";
|
||||
storage = "${server-home}/Storage";
|
||||
calibre-library = "${server-home}/Books-Library";
|
||||
services-folder = "${server-home}/Services";
|
||||
services-nodes-folder = "${services-mnt-folder}/nodes";
|
||||
postgresql-folder = "${services-mnt-folder}/postgresql";
|
||||
music-library = "${user-home}/Music";
|
||||
|
||||
archive-drive = "/mnt/archive";
|
||||
lamet-drive = "/mnt/lamet";
|
||||
mobile-drive = "/mnt/mobile";
|
||||
therima-drive = "/mnt/therima";
|
||||
vetymae-drive = "/mnt/vetymae";
|
||||
soptur-drive = "/mnt/soptur";
|
||||
};
|
||||
|
||||
mkXlib =
|
||||
{
|
||||
hostname,
|
||||
type,
|
||||
username ? "oqyude",
|
||||
}:
|
||||
let
|
||||
# Unknown device type fails here, at flake level, with the valid list.
|
||||
capabilities = devices.${type} or (throw "xlib: unknown device type '${type}', expected one of ${lib.concatStringsSep ", " (builtins.attrNames devices)}");
|
||||
in
|
||||
{
|
||||
device = {
|
||||
inherit
|
||||
hostname
|
||||
type
|
||||
username
|
||||
;
|
||||
};
|
||||
isDesktop = capabilities.desktop;
|
||||
isHeadless = capabilities.headless;
|
||||
dirs = mkDirs username;
|
||||
inherit helpers;
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit
|
||||
devices
|
||||
helpers
|
||||
mkDirs
|
||||
mkXlib
|
||||
;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
}:
|
||||
let
|
||||
panel = "${xlib.dirs.services-nodes-folder}/${xlib.device.hostname}/3x-ui";
|
||||
certDomain = xlib.services."3x-ui".certDomain or null;
|
||||
# Domain whose Let's Encrypt cert (at /var/lib/acme/<domain>/) gets mounted
|
||||
# read-only into the 3x-ui container so the panel can terminate TLS itself.
|
||||
# Null when 3x-ui serves plain HTTP and TLS is terminated by an upstream
|
||||
# nginx.
|
||||
certDomain = config.host."3x-ui".certDomain;
|
||||
certMounts =
|
||||
if certDomain == null then
|
||||
[ ]
|
||||
@@ -28,9 +32,39 @@ let
|
||||
];
|
||||
# VDS-only: nginx stream forwards host:443 → 127.0.0.1:15380 →
|
||||
# container:443, so Xray sees its REALITY inbound on port 443.
|
||||
realityPorts = lib.optional xlib.services."3x-ui".reality443Forwarding "127.0.0.1:15380:443/tcp";
|
||||
realityPorts = lib.optional config.host."3x-ui".reality443Forwarding "127.0.0.1:15380:443/tcp";
|
||||
in
|
||||
{
|
||||
options.host."3x-ui" = {
|
||||
# Domain whose LE cert should be mounted into the 3x-ui container at
|
||||
# /root/cert/fullchain.pem and key.pem. Set null if 3x-ui serves plain
|
||||
# HTTP and TLS is terminated by an upstream nginx.
|
||||
certDomain = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "pubray1.zeroq.su";
|
||||
description = ''
|
||||
Domain whose LE cert should be mounted into the 3x-ui
|
||||
container at /root/cert/fullchain.pem and key.pem.
|
||||
'';
|
||||
};
|
||||
# Publish host:15380 → container:443. Only nodes that host an Xray
|
||||
# REALITY inbound on container:443 need this (so nginx stream can
|
||||
# forward TLS to Xray via 127.0.0.1:15380 while Xray itself sees
|
||||
# incoming connections on its configured port 443). Set false on nodes
|
||||
# that only run the 3x-ui panel.
|
||||
reality443Forwarding = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
When true, publish host:15380 → container:443 so Xray
|
||||
inside the container can serve REALITY on its real
|
||||
configured port 443 (nginx stream forwards 443 → 15380).
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
@@ -118,4 +152,5 @@ in
|
||||
"${matchAll}".allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+9
-25
@@ -3,30 +3,20 @@ let
|
||||
# NixOS-only modules. termux runs nix-on-droid (its own module system,
|
||||
# class = "nixOnDroid"): options like services.*, users.*, sops.*, disko.*
|
||||
# and nixpkgs.overlays (flake assertion) do not exist there.
|
||||
moduleArgs = config: {
|
||||
inherit inputs;
|
||||
xlib = config.xlib;
|
||||
};
|
||||
#
|
||||
# `xlib` arrives as a module argument (see lib/mkSystem.nix) and is plain
|
||||
# data, not a module option, so nothing here has to declare or set it.
|
||||
defaultModule =
|
||||
{
|
||||
config,
|
||||
deviceType,
|
||||
lib,
|
||||
xlib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
isDesktop = builtins.elem deviceType [
|
||||
"primary"
|
||||
"secondary"
|
||||
];
|
||||
in
|
||||
{
|
||||
imports =
|
||||
with inputs;
|
||||
[
|
||||
./essentials
|
||||
./options.nix
|
||||
./users.nix
|
||||
|
||||
home-manager.nixosModules.home-manager # home-manager module
|
||||
@@ -37,33 +27,27 @@ let
|
||||
self.homeConfigurations.default.nixosModule # default homeConfigurations
|
||||
disko.nixosModules.disko # disko module
|
||||
]
|
||||
++ lib.optional isDesktop ./desktop # desktop class: primary/secondary
|
||||
# desktop class: primary/secondary
|
||||
++ lib.optional xlib.isDesktop ./desktop
|
||||
# device-type module dir; "minimal" has no extra modules
|
||||
++ lib.optional (!isDesktop && deviceType != "minimal") (./. + "/${deviceType}");
|
||||
++ lib.optional (!xlib.isDesktop && xlib.device.type != "minimal") (./. + "/${xlib.device.type}");
|
||||
nixpkgs.overlays = with inputs; [
|
||||
self.nixosOverlays.default
|
||||
];
|
||||
networking.hostName = lib.mkDefault config.xlib.device.hostname;
|
||||
_module.args = moduleArgs config;
|
||||
networking.hostName = lib.mkDefault xlib.device.hostname;
|
||||
};
|
||||
strictModule =
|
||||
{
|
||||
config,
|
||||
deviceType,
|
||||
lib,
|
||||
xlib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = with inputs; [
|
||||
imports = [
|
||||
# ./essentials
|
||||
# ./users.nix
|
||||
./options.nix
|
||||
(./. + "/${deviceType}")
|
||||
(./. + "/${xlib.device.type}")
|
||||
# sops-nix.nixosModules.sops
|
||||
];
|
||||
|
||||
_module.args = moduleArgs config;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
@@ -3,7 +3,16 @@
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
lib.mkIf config.xlib.ssh.enable {
|
||||
{
|
||||
options.host.ssh = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable the SSH server with the shared config below.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.ssh.enable {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
allowSFTP = true;
|
||||
@@ -20,4 +29,5 @@ lib.mkIf config.xlib.ssh.enable {
|
||||
UsePAM = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Option factory for the xlib.dirs namespace
|
||||
mkDir =
|
||||
default: description:
|
||||
lib.mkOption {
|
||||
type = lib.types.str;
|
||||
inherit default description;
|
||||
};
|
||||
|
||||
helpers = import ../lib/xlib.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
options = {
|
||||
xlib = {
|
||||
device = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"minimal"
|
||||
"primary"
|
||||
"secondary"
|
||||
"server"
|
||||
"vds"
|
||||
"wsl"
|
||||
"termux"
|
||||
];
|
||||
default = "minimal";
|
||||
description = "Type of device for this host.";
|
||||
};
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "oqyude";
|
||||
description = "Username for host.";
|
||||
};
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nixos";
|
||||
description = "Hostname...";
|
||||
};
|
||||
};
|
||||
ssh = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable SSH server with the standard config.";
|
||||
};
|
||||
};
|
||||
dirs = {
|
||||
user-home = mkDir "/home/${config.xlib.device.username}" "User home directory.";
|
||||
user-storage = mkDir "${config.xlib.dirs.user-home}/Storage" "User storage directory.";
|
||||
archive-drive = mkDir "/mnt/archive" "Archive drive mount point.";
|
||||
lamet-drive = mkDir "/mnt/lamet" "Lamet drive mount point.";
|
||||
mobile-drive = mkDir "/mnt/mobile" "Mobile drive mount point.";
|
||||
therima-drive = mkDir "/mnt/therima" "Therima drive mount point.";
|
||||
vetymae-drive = mkDir "/mnt/vetymae" "Vetymae drive mount point.";
|
||||
soptur-drive = mkDir "/mnt/soptur" "Soptur drive mount point.";
|
||||
wsl-home = mkDir "/mnt/c/Users/${config.xlib.device.username}" "WSL home directory.";
|
||||
wsl-storage = mkDir "${config.xlib.dirs.wsl-home}/Storage" "WSL storage directory.";
|
||||
server-home = mkDir "/home/${config.xlib.device.username}/External" "Server home directory.";
|
||||
server-credentials = mkDir "${config.xlib.dirs.server-home}/Credentials/server" "Server credentials directory.";
|
||||
storage = mkDir "${config.xlib.dirs.server-home}/Storage" "General storage directory.";
|
||||
calibre-library = mkDir "${config.xlib.dirs.server-home}/Books-Library" "Calibre library directory.";
|
||||
music-library = mkDir "${config.xlib.dirs.user-home}/Music" "Music library directory.";
|
||||
services-folder = mkDir "${config.xlib.dirs.server-home}/Services" "All services folder.";
|
||||
services-mnt-folder = mkDir "/mnt/services" "All services folder.";
|
||||
services-nodes-folder = mkDir "${config.xlib.dirs.services-mnt-folder}/nodes" "All nodes folder.";
|
||||
postgresql-folder = mkDir "${config.xlib.dirs.services-mnt-folder}/postgresql" "PostgreSQL service folder.";
|
||||
};
|
||||
helpers = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
default = helpers;
|
||||
description = "Shared helper functions (see lib/xlib.nix).";
|
||||
};
|
||||
services."3x-ui" = {
|
||||
# Domain whose Let's Encrypt cert (at /var/lib/acme/<domain>/)
|
||||
# gets mounted read-only into the 3x-ui container so the panel
|
||||
# can terminate TLS itself. Set null if 3x-ui serves plain HTTP
|
||||
# and TLS is terminated by an upstream nginx.
|
||||
certDomain = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "pubray1.zeroq.su";
|
||||
description = ''
|
||||
Domain whose LE cert should be mounted into the 3x-ui
|
||||
container at /root/cert/fullchain.pem and key.pem.
|
||||
'';
|
||||
};
|
||||
# Publish host:15380 → container:443. Only nodes that host an
|
||||
# Xray REALITY inbound on container:443 need this (so nginx
|
||||
# stream can forward TLS to Xray via 127.0.0.1:15380 while Xray
|
||||
# itself sees incoming connections on its configured port 443).
|
||||
# Set false on nodes that only run the 3x-ui panel.
|
||||
reality443Forwarding = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
When true, publish host:15380 → container:443 so Xray
|
||||
inside the container can serve REALITY on its real
|
||||
configured port 443 (nginx stream forwards 443 → 15380).
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -50,7 +50,7 @@
|
||||
# there are other vhosts on the same port). Cert is still mounted in
|
||||
# case 3x-ui is later reconfigured to terminate TLS itself (e.g. for
|
||||
# direct node-API access); nginx doesn't have to use it.
|
||||
xlib.services."3x-ui".certDomain = "x.zeroq.su";
|
||||
host."3x-ui".certDomain = "x.zeroq.su";
|
||||
systemd.tmpfiles.rules = [
|
||||
(xlib.helpers.mkTmpfile "d" "/mnt" "0755" "root" "root")
|
||||
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-mnt-folder "0755" "root" "root")
|
||||
|
||||
@@ -37,8 +37,6 @@ let
|
||||
);
|
||||
in
|
||||
{
|
||||
xlib.device.username = "oqyude";
|
||||
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
users = {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
];
|
||||
# VDS hosts the public-facing Xray REALITY inbound on container:443,
|
||||
# fronted by nginx stream on host:443 → host:15380 → container:443.
|
||||
xlib.services."3x-ui" = {
|
||||
host."3x-ui" = {
|
||||
certDomain = "pubray1.zeroq.su";
|
||||
reality443Forwarding = true;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user