refactor: simplify shared config contracts
This commit is contained in:
@@ -35,8 +35,8 @@ In this repo, `flake.nix` imports `./modules` recursively via `inputs.import-tre
|
|||||||
- `modules/hosts/<name>/default.nix`: host features that assemble NixOS aspects into `flake.modules.nixos.<name>`.
|
- `modules/hosts/<name>/default.nix`: host features that assemble NixOS aspects into `flake.modules.nixos.<name>`.
|
||||||
- `modules/secrets/`: secret-related features shared by hosts.
|
- `modules/secrets/`: secret-related features shared by hosts.
|
||||||
- `modules/flake-parts.nix`: flake-parts entrypoint; defines systems, formatter, and `flake.nixosConfigurations`.
|
- `modules/flake-parts.nix`: flake-parts entrypoint; defines systems, formatter, and `flake.nixosConfigurations`.
|
||||||
- `modules/lib.nix`: shared constructors in `config.meta.lib`, especially `mkHost`, `mkHostUser`, and `mkCaddyReverseProxy`.
|
- `modules/lib.nix`: shared constructors and helpers in `config.meta.lib`, especially `mkHost` and `mkCaddyReverseProxy`.
|
||||||
- `modules/users.nix`: canonical user attrsets exposed through `meta.lib.users`.
|
- `modules/data.nix`: canonical shared repo data and account attrsets exposed through `meta.lib.repo` and `meta.lib.accounts`.
|
||||||
- `modules/features/meta.nix`: shared metadata schema for `meta.host` and `meta.user`.
|
- `modules/features/meta.nix`: shared metadata schema for `meta.host` and `meta.user`.
|
||||||
|
|
||||||
## How Features Are Applied Here
|
## How Features Are Applied Here
|
||||||
@@ -45,7 +45,7 @@ In this repo, `flake.nix` imports `./modules` recursively via `inputs.import-tre
|
|||||||
- Reusable Home Manager concerns are published as `flake.modules.homeManager.<name>`.
|
- Reusable Home Manager concerns are published as `flake.modules.homeManager.<name>`.
|
||||||
- Hosts are aspects too. `orion`, `polaris`, and `zenith` are `nixos` aspects assembled from smaller aspects.
|
- Hosts are aspects too. `orion`, `polaris`, and `zenith` are `nixos` aspects assembled from smaller aspects.
|
||||||
- Host modules should use `config.meta.lib.mkHost` to define `meta.host`, base imports, hostname, and state version.
|
- Host modules should use `config.meta.lib.mkHost` to define `meta.host`, base imports, hostname, and state version.
|
||||||
- Per-host user declarations should use `config.meta.lib.mkHostUser` so host-local defaults stay close to the host and `mkHost` can wire `meta.host` and `meta.user` into Home Manager consistently.
|
- Per-host user declarations should stay inline under `users.<name>` using canonical accounts from `meta.lib.accounts`, so host-local defaults stay close to the host and `mkHost` can wire `meta.host` and `meta.user` into Home Manager consistently.
|
||||||
- Features may rely on the `meta` contract. Existing modules already read `config.meta.host`, `config.meta.user`, and `config.meta.lib`.
|
- Features may rely on the `meta` contract. Existing modules already read `config.meta.host`, `config.meta.user`, and `config.meta.lib`.
|
||||||
|
|
||||||
## Preferred Aspect Patterns
|
## Preferred Aspect Patterns
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
let
|
let
|
||||||
users = {
|
userSpecs = {
|
||||||
kiri = {
|
kiri = {
|
||||||
name = "kiri";
|
|
||||||
realName = "Jelle Spreeuwenberg";
|
realName = "Jelle Spreeuwenberg";
|
||||||
homeDirectory = "/home/kiri";
|
homeDirectory = "/home/kiri";
|
||||||
terminalPackagePath = [ "kitty" ];
|
|
||||||
emails = {
|
emails = {
|
||||||
personal = {
|
personal = {
|
||||||
address = "mail@jelles.net";
|
address = "mail@jelles.net";
|
||||||
@@ -33,10 +31,8 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
ergon = {
|
ergon = {
|
||||||
name = "ergon";
|
|
||||||
realName = "Jelle Spreeuwenberg";
|
realName = "Jelle Spreeuwenberg";
|
||||||
homeDirectory = "/home/ergon";
|
homeDirectory = "/home/ergon";
|
||||||
terminalPackagePath = [ "kitty" ];
|
|
||||||
emails = {
|
emails = {
|
||||||
personal = {
|
personal = {
|
||||||
address = "mail@jelles.net";
|
address = "mail@jelles.net";
|
||||||
@@ -54,6 +50,8 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
accounts = lib.mapAttrs (name: spec: spec // { inherit name; }) userSpecs;
|
||||||
|
|
||||||
repo = {
|
repo = {
|
||||||
contact.email = "mail@jelles.net";
|
contact.email = "mail@jelles.net";
|
||||||
|
|
||||||
@@ -67,6 +65,12 @@ let
|
|||||||
command = "nautilus";
|
command = "nautilus";
|
||||||
packagePath = [ "nautilus" ];
|
packagePath = [ "nautilus" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
terminal = {
|
||||||
|
command = "kitty";
|
||||||
|
desktopId = "kitty.desktop";
|
||||||
|
packagePath = [ "kitty" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
@@ -178,13 +182,13 @@ in
|
|||||||
readOnly = true;
|
readOnly = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
options.meta.lib.users = lib.mkOption {
|
options.meta.lib.accounts = lib.mkOption {
|
||||||
type = lib.types.attrs;
|
type = lib.types.attrs;
|
||||||
description = "Canonical user attrsets shared by host definitions.";
|
description = "Canonical account attrsets shared by host definitions.";
|
||||||
internal = true;
|
internal = true;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
config.meta.lib.repo = repo;
|
config.meta.lib.repo = repo;
|
||||||
config.meta.lib.users = users;
|
config.meta.lib.accounts = accounts;
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,13 @@ let
|
|||||||
|
|
||||||
hasRequiredScopedEmail = scope: user: scopeEmailCount scope user == 1;
|
hasRequiredScopedEmail = scope: user: scopeEmailCount scope user == 1;
|
||||||
|
|
||||||
|
scopeEmailAddress =
|
||||||
|
scope: user:
|
||||||
|
let
|
||||||
|
emails = lib.filter (email: email.scope == scope) (builtins.attrValues user.emails);
|
||||||
|
in
|
||||||
|
if emails == [ ] then "" else (builtins.head emails).address;
|
||||||
|
|
||||||
primaryEmailFallback = {
|
primaryEmailFallback = {
|
||||||
address = "";
|
address = "";
|
||||||
primary = false;
|
primary = false;
|
||||||
@@ -125,6 +132,22 @@ let
|
|||||||
type = sourceControlScopeType;
|
type = sourceControlScopeType;
|
||||||
default = "personal";
|
default = "personal";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scopes = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
options.email = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
readOnly = true;
|
||||||
|
description = "Derived source-control identities keyed by scope.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -149,10 +172,6 @@ let
|
|||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
terminalPackagePath = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosConfigurationPath = lib.mkOption {
|
nixosConfigurationPath = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "${config.homeDirectory}/.config/nixos";
|
default = "${config.homeDirectory}/.config/nixos";
|
||||||
@@ -174,7 +193,12 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.primaryEmail = primaryEmail;
|
config = {
|
||||||
|
primaryEmail = primaryEmail;
|
||||||
|
sourceControl.scopes = lib.genAttrs (requiredSourceControlScopes config) (scope: {
|
||||||
|
email = scopeEmailAddress scope config;
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
networking = {
|
networking = {
|
||||||
firewall.enable = true;
|
firewall.enable = true;
|
||||||
firewall.allowPing = false;
|
firewall.allowPing = false;
|
||||||
nftables.enable = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,15 +56,13 @@ in
|
|||||||
}
|
}
|
||||||
) config.meta.host.displays;
|
) config.meta.host.displays;
|
||||||
inputProfiles = metaLib.mkInputProfiles config.meta.host.input;
|
inputProfiles = metaLib.mkInputProfiles config.meta.host.input;
|
||||||
terminal = metaLib.resolveUserTerminal {
|
terminal = metaLib.resolveRepoTerminal {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
user = config.meta.user;
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assertions = metaLib.mkTerminalAssertions {
|
assertions = metaLib.mkTerminalAssertions {
|
||||||
inherit terminal;
|
inherit terminal;
|
||||||
user = config.meta.user;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home.sessionVariables.NIXOS_OZONE_WL = "1";
|
home.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
@@ -154,7 +152,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
binds =
|
binds =
|
||||||
if terminal.hasMainProgram then
|
if terminal.hasPackage then
|
||||||
import ./_bindings.nix {
|
import ./_bindings.nix {
|
||||||
inherit
|
inherit
|
||||||
browserCommand
|
browserCommand
|
||||||
|
|||||||
@@ -6,6 +6,17 @@
|
|||||||
let
|
let
|
||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
metaLib = config.meta.lib;
|
metaLib = config.meta.lib;
|
||||||
|
mkNoctaliaSettings =
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
terminalPackage,
|
||||||
|
}:
|
||||||
|
import ./_noctalia-config.nix {
|
||||||
|
inherit
|
||||||
|
lib
|
||||||
|
terminalPackage
|
||||||
|
;
|
||||||
|
};
|
||||||
mkPortableSettings =
|
mkPortableSettings =
|
||||||
baseSettings:
|
baseSettings:
|
||||||
lib.recursiveUpdate baseSettings {
|
lib.recursiveUpdate baseSettings {
|
||||||
@@ -29,38 +40,56 @@ let
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.noctalia =
|
flake.modules.homeManager.noctalia-base =
|
||||||
{
|
{
|
||||||
inputs,
|
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
terminal = metaLib.resolveUserTerminal {
|
terminal = metaLib.resolveRepoTerminal {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
user = config.meta.user;
|
|
||||||
};
|
};
|
||||||
baseSettings =
|
baseSettings =
|
||||||
if terminal.hasMainProgram then
|
if terminal.hasPackage then
|
||||||
import ./_noctalia-config.nix {
|
mkNoctaliaSettings {
|
||||||
inherit
|
inherit lib;
|
||||||
lib
|
|
||||||
;
|
|
||||||
terminalPackage = terminal.package;
|
terminalPackage = terminal.package;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ };
|
{ };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ inputs.noctalia.homeModules.default ];
|
options.meta.lib.noctaliaBaseSettings = lib.mkOption {
|
||||||
|
type = lib.types.attrs;
|
||||||
assertions = metaLib.mkTerminalAssertions {
|
internal = true;
|
||||||
inherit terminal;
|
readOnly = true;
|
||||||
user = config.meta.user;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
meta.lib.noctaliaBaseSettings = baseSettings;
|
||||||
|
|
||||||
|
assertions = metaLib.mkTerminalAssertions {
|
||||||
|
inherit terminal;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.noctalia =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
homeModules.noctalia-base
|
||||||
|
inputs.noctalia.homeModules.default
|
||||||
|
];
|
||||||
|
|
||||||
programs.noctalia-shell = {
|
programs.noctalia-shell = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = lib.mkForce (
|
package = lib.mkForce (
|
||||||
@@ -69,7 +98,7 @@ in
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
settings = baseSettings;
|
settings = config.meta.lib.noctaliaBaseSettings;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,29 +106,15 @@ in
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
terminal = metaLib.resolveUserTerminal {
|
|
||||||
inherit pkgs;
|
|
||||||
user = config.meta.user;
|
|
||||||
};
|
|
||||||
baseSettings =
|
|
||||||
if terminal.hasMainProgram then
|
|
||||||
import ./_noctalia-config.nix {
|
|
||||||
inherit
|
|
||||||
lib
|
|
||||||
;
|
|
||||||
terminalPackage = terminal.package;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ };
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [ homeModules.noctalia ];
|
imports = [ homeModules.noctalia ];
|
||||||
programs.noctalia-shell.settings = lib.mkForce (
|
programs.noctalia-shell.settings = lib.mkForce (
|
||||||
if terminal.hasMainProgram then mkPortableSettings baseSettings else { }
|
if config.meta.lib.noctaliaBaseSettings == { } then
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
mkPortableSettings config.meta.lib.noctaliaBaseSettings
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ in
|
|||||||
host = config.meta.host;
|
host = config.meta.host;
|
||||||
user = config.meta.user;
|
user = config.meta.user;
|
||||||
sourceControl = user.sourceControl;
|
sourceControl = user.sourceControl;
|
||||||
|
sourceControlScopes = sourceControl.scopes;
|
||||||
hostSourceControlUsers = host.sourceControl.users;
|
hostSourceControlUsers = host.sourceControl.users;
|
||||||
hostUserSourceControl = hostSourceControlUsers.${user.name} or { };
|
hostUserSourceControl = hostSourceControlUsers.${user.name} or { };
|
||||||
|
|
||||||
scopeEmails = scope: lib.filter (email: email.scope == scope) (builtins.attrValues user.emails);
|
scopeConfig = scope: hostUserSourceControl.${scope} or null;
|
||||||
|
scopeIdentity = scope: sourceControlScopes.${scope} or null;
|
||||||
|
|
||||||
emailForScope =
|
emailForScope =
|
||||||
scope:
|
scope:
|
||||||
let
|
let
|
||||||
emails = scopeEmails scope;
|
identity = scopeIdentity scope;
|
||||||
in
|
in
|
||||||
if builtins.length emails == 1 then (builtins.head emails).address else null;
|
if identity == null then null else identity.email;
|
||||||
|
|
||||||
scopeConfig = scope: hostUserSourceControl.${scope} or null;
|
|
||||||
|
|
||||||
scopeHasSigningKey =
|
scopeHasSigningKey =
|
||||||
scope:
|
scope:
|
||||||
@@ -51,10 +51,7 @@ in
|
|||||||
in
|
in
|
||||||
if keyConfig == null then null else keyConfig.publicKey;
|
if keyConfig == null then null else keyConfig.publicKey;
|
||||||
|
|
||||||
scopesInUse = lib.unique ([
|
scopesInUse = builtins.attrNames sourceControlScopes;
|
||||||
"personal"
|
|
||||||
sourceControl.projectScope
|
|
||||||
]);
|
|
||||||
|
|
||||||
allowedSignersLines = map (scope: "${emailForScope scope} ${publicKeyForScope scope}") (
|
allowedSignersLines = map (scope: "${emailForScope scope} ${publicKeyForScope scope}") (
|
||||||
builtins.filter (scope: emailForScope scope != null && scopeHasSigningKey scope) scopesInUse
|
builtins.filter (scope: emailForScope scope != null && scopeHasSigningKey scope) scopesInUse
|
||||||
|
|||||||
@@ -14,17 +14,14 @@ in
|
|||||||
let
|
let
|
||||||
repoTheme = metaRepo.theme.kanagawa;
|
repoTheme = metaRepo.theme.kanagawa;
|
||||||
palette = repoTheme.palette;
|
palette = repoTheme.palette;
|
||||||
terminal = metaLib.resolveUserTerminal {
|
terminal = metaLib.resolveRepoTerminal {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
user = config.meta.user;
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assertions = metaLib.mkTerminalAssertions {
|
assertions = metaLib.mkTerminalAssertions {
|
||||||
inherit terminal;
|
inherit terminal;
|
||||||
user = config.meta.user;
|
|
||||||
requireDesktopEntry = true;
|
requireDesktopEntry = true;
|
||||||
requireKitty = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.terminal-exec = {
|
xdg.terminal-exec = {
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ in
|
|||||||
environment.localBinInPath = true;
|
environment.localBinInPath = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
flake.modules.nixos.workstation-host = {
|
||||||
|
imports = [
|
||||||
|
nixosModules.workstation-base
|
||||||
|
nixosModules.qbittorrent-client
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.workstation-base = {
|
flake.modules.homeManager.workstation-base = {
|
||||||
imports = [
|
imports = [
|
||||||
homeModules.ai
|
homeModules.ai
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ in
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
inputs.flake-parts.flakeModules.modules
|
inputs.flake-parts.flakeModules.modules
|
||||||
./repo-data.nix
|
./data.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
systems = [ "x86_64-linux" ];
|
systems = [ "x86_64-linux" ];
|
||||||
|
|||||||
@@ -17,15 +17,13 @@ in
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
terminal = metaLib.resolveUserTerminal {
|
terminal = metaLib.resolveRepoTerminal {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
user = config.meta.host.users.kiri;
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assertions = metaLib.mkTerminalAssertions {
|
assertions = metaLib.mkTerminalAssertions {
|
||||||
inherit terminal;
|
inherit terminal;
|
||||||
user = config.meta.host.users.kiri;
|
|
||||||
requireTerminfo = true;
|
requireTerminfo = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,7 +43,7 @@ in
|
|||||||
name = "orion";
|
name = "orion";
|
||||||
users = {
|
users = {
|
||||||
kiri = {
|
kiri = {
|
||||||
account = metaLib.users.kiri;
|
account = metaLib.accounts.kiri;
|
||||||
homeImports = [
|
homeImports = [
|
||||||
homeModules.shell
|
homeModules.shell
|
||||||
homeModules.git
|
homeModules.git
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ let
|
|||||||
nixosModules = config.flake.modules.nixos;
|
nixosModules = config.flake.modules.nixos;
|
||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
metaLib = config.meta.lib;
|
metaLib = config.meta.lib;
|
||||||
|
workstationHomeImports = [ homeModules.workstation-base ];
|
||||||
|
kiriHomeImports = workstationHomeImports ++ [
|
||||||
|
homeModules.syncthing
|
||||||
|
homeModules.qbittorrent-client
|
||||||
|
homeModules.noctalia
|
||||||
|
];
|
||||||
|
ergonHomeImports = workstationHomeImports ++ [ homeModules.noctalia ];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.polaris = metaLib.mkHost {
|
flake.modules.nixos.polaris = metaLib.mkHost {
|
||||||
@@ -31,29 +38,20 @@ in
|
|||||||
|
|
||||||
users = {
|
users = {
|
||||||
kiri = {
|
kiri = {
|
||||||
account = metaLib.users.kiri;
|
account = metaLib.accounts.kiri;
|
||||||
needsPassword = true;
|
needsPassword = true;
|
||||||
homeImports = [
|
homeImports = kiriHomeImports;
|
||||||
homeModules.workstation-base
|
|
||||||
homeModules.syncthing
|
|
||||||
homeModules.qbittorrent-client
|
|
||||||
homeModules.noctalia
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ergon = {
|
ergon = {
|
||||||
account = metaLib.users.ergon;
|
account = metaLib.accounts.ergon;
|
||||||
needsPassword = true;
|
needsPassword = true;
|
||||||
homeImports = [
|
homeImports = ergonHomeImports;
|
||||||
homeModules.workstation-base
|
|
||||||
homeModules.noctalia
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
nixosModules.workstation-base
|
nixosModules.workstation-host
|
||||||
nixosModules.qbittorrent-client
|
|
||||||
nixosModules.steam
|
nixosModules.steam
|
||||||
./_hardware.nix
|
./_hardware.nix
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ let
|
|||||||
nixosModules = config.flake.modules.nixos;
|
nixosModules = config.flake.modules.nixos;
|
||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
metaLib = config.meta.lib;
|
metaLib = config.meta.lib;
|
||||||
|
workstationHomeImports = [ homeModules.workstation-base ];
|
||||||
|
portableNoctalia = homeModules.noctalia-portable;
|
||||||
|
kiriHomeImports = workstationHomeImports ++ [
|
||||||
|
homeModules.syncthing
|
||||||
|
homeModules.qbittorrent-client
|
||||||
|
portableNoctalia
|
||||||
|
];
|
||||||
|
ergonHomeImports = workstationHomeImports ++ [ portableNoctalia ];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.zenith = metaLib.mkHost {
|
flake.modules.nixos.zenith = metaLib.mkHost {
|
||||||
@@ -39,29 +47,20 @@ in
|
|||||||
|
|
||||||
users = {
|
users = {
|
||||||
kiri = {
|
kiri = {
|
||||||
account = metaLib.users.kiri;
|
account = metaLib.accounts.kiri;
|
||||||
needsPassword = true;
|
needsPassword = true;
|
||||||
homeImports = [
|
homeImports = kiriHomeImports;
|
||||||
homeModules.workstation-base
|
|
||||||
homeModules.syncthing
|
|
||||||
homeModules.qbittorrent-client
|
|
||||||
homeModules.noctalia-portable
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ergon = {
|
ergon = {
|
||||||
account = metaLib.users.ergon;
|
account = metaLib.accounts.ergon;
|
||||||
needsPassword = true;
|
needsPassword = true;
|
||||||
homeImports = [
|
homeImports = ergonHomeImports;
|
||||||
homeModules.workstation-base
|
|
||||||
homeModules.noctalia-portable
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
nixosModules.workstation-base
|
nixosModules.workstation-host
|
||||||
nixosModules.qbittorrent-client
|
|
||||||
nixosModules.laptop-power
|
nixosModules.laptop-power
|
||||||
{
|
{
|
||||||
hardware.enableRedistributableFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|||||||
+23
-39
@@ -31,17 +31,9 @@ let
|
|||||||
let
|
let
|
||||||
hostUserSpecs = lib.mapAttrs (_: spec: normalizeHostUser spec) users;
|
hostUserSpecs = lib.mapAttrs (_: spec: normalizeHostUser spec) users;
|
||||||
hostUsers = lib.mapAttrs (_: spec: spec.account) hostUserSpecs;
|
hostUsers = lib.mapAttrs (_: spec: spec.account) hostUserSpecs;
|
||||||
|
|
||||||
userAssertions = lib.mapAttrsToList (userName: spec: {
|
|
||||||
assertion = userName == spec.account.name;
|
|
||||||
message = "Host `${name}` declares user `${userName}` with mismatched account name `${spec.account.name}`.";
|
|
||||||
}) hostUserSpecs;
|
|
||||||
|
|
||||||
passwordUserSpecs = lib.filterAttrs (_: spec: spec.needsPassword) hostUserSpecs;
|
passwordUserSpecs = lib.filterAttrs (_: spec: spec.needsPassword) hostUserSpecs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assertions = userAssertions;
|
|
||||||
|
|
||||||
meta.host = {
|
meta.host = {
|
||||||
inherit
|
inherit
|
||||||
displays
|
displays
|
||||||
@@ -69,7 +61,7 @@ let
|
|||||||
users.users = lib.mapAttrs (
|
users.users = lib.mapAttrs (
|
||||||
userName: spec:
|
userName: spec:
|
||||||
{
|
{
|
||||||
name = spec.account.name;
|
name = userName;
|
||||||
home = spec.account.homeDirectory;
|
home = spec.account.homeDirectory;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
shell = pkgs.zsh;
|
shell = pkgs.zsh;
|
||||||
@@ -131,67 +123,59 @@ let
|
|||||||
}:
|
}:
|
||||||
lib.attrByPath path null pkgs;
|
lib.attrByPath path null pkgs;
|
||||||
|
|
||||||
resolveUserTerminal =
|
resolveRepoTerminal =
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
user,
|
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
terminal = config.meta.lib.repo.desktop.terminal;
|
||||||
package = resolvePackagePath {
|
package = resolvePackagePath {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
path = user.terminalPackagePath;
|
path = terminal.packagePath;
|
||||||
};
|
};
|
||||||
hasPackage = package != null;
|
|
||||||
hasMainProgram = hasPackage && package ? meta.mainProgram;
|
|
||||||
mainProgram = if hasMainProgram then package.meta.mainProgram else null;
|
|
||||||
desktopId = if mainProgram == null then null else "${mainProgram}.desktop";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit
|
inherit
|
||||||
desktopId
|
|
||||||
hasMainProgram
|
|
||||||
hasPackage
|
|
||||||
mainProgram
|
|
||||||
package
|
package
|
||||||
;
|
;
|
||||||
|
inherit (terminal)
|
||||||
|
command
|
||||||
|
desktopId
|
||||||
|
packagePath
|
||||||
|
;
|
||||||
|
|
||||||
|
hasPackage = package != null;
|
||||||
|
|
||||||
hasDesktopEntry =
|
hasDesktopEntry =
|
||||||
desktopId != null && builtins.pathExists "${package}/share/applications/${desktopId}";
|
package != null && builtins.pathExists "${package}/share/applications/${terminal.desktopId}";
|
||||||
|
|
||||||
hasTerminfo = hasPackage && lib.elem "terminfo" package.outputs;
|
hasTerminfo = package != null && lib.elem "terminfo" package.outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
mkTerminalAssertions =
|
mkTerminalAssertions =
|
||||||
{
|
{
|
||||||
terminal,
|
terminal,
|
||||||
user,
|
|
||||||
requireDesktopEntry ? false,
|
requireDesktopEntry ? false,
|
||||||
requireKitty ? false,
|
|
||||||
requireMainProgram ? true,
|
|
||||||
requireTerminfo ? false,
|
requireTerminfo ? false,
|
||||||
}:
|
}:
|
||||||
lib.flatten [
|
lib.flatten [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
assertion = terminal.hasPackage;
|
assertion = terminal.hasPackage;
|
||||||
message = "Unknown terminal package `${lib.showAttrPath user.terminalPackagePath}` for user `${user.name}`.";
|
message = "Unknown terminal package `${lib.showAttrPath terminal.packagePath}` in `meta.lib.repo.desktop.terminal`.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = terminal.command == "kitty";
|
||||||
|
message = "The repo terminal is currently expected to be kitty.";
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
(lib.optional requireMainProgram {
|
|
||||||
assertion = terminal.hasMainProgram;
|
|
||||||
message = "Terminal package `${lib.showAttrPath user.terminalPackagePath}` must define `meta.mainProgram`.";
|
|
||||||
})
|
|
||||||
(lib.optional requireDesktopEntry {
|
(lib.optional requireDesktopEntry {
|
||||||
assertion = terminal.hasDesktopEntry;
|
assertion = terminal.hasDesktopEntry;
|
||||||
message = "Terminal package `${lib.showAttrPath user.terminalPackagePath}` must provide `${terminal.desktopId}`.";
|
message = "Terminal package `${lib.showAttrPath terminal.packagePath}` must provide `${terminal.desktopId}`.";
|
||||||
})
|
|
||||||
(lib.optional requireKitty {
|
|
||||||
assertion = terminal.hasMainProgram && terminal.mainProgram == "kitty";
|
|
||||||
message = "The terminal feature currently only supports kitty-specific Home Manager configuration.";
|
|
||||||
})
|
})
|
||||||
(lib.optional requireTerminfo {
|
(lib.optional requireTerminfo {
|
||||||
assertion = terminal.hasTerminfo;
|
assertion = terminal.hasTerminfo;
|
||||||
message = "Terminal package `${lib.showAttrPath user.terminalPackagePath}` must provide a `terminfo` output.";
|
message = "Terminal package `${lib.showAttrPath terminal.packagePath}` must provide a `terminfo` output.";
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -356,9 +340,9 @@ in
|
|||||||
readOnly = true;
|
readOnly = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
options.meta.lib.resolveUserTerminal = lib.mkOption {
|
options.meta.lib.resolveRepoTerminal = lib.mkOption {
|
||||||
type = lib.types.raw;
|
type = lib.types.raw;
|
||||||
description = "Internal helper to resolve and validate user terminal metadata.";
|
description = "Internal helper to resolve and validate the repo-standard terminal.";
|
||||||
internal = true;
|
internal = true;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
};
|
};
|
||||||
@@ -384,7 +368,7 @@ in
|
|||||||
mkTerminalAssertions
|
mkTerminalAssertions
|
||||||
mkHost
|
mkHost
|
||||||
resolvePackagePath
|
resolvePackagePath
|
||||||
resolveUserTerminal
|
resolveRepoTerminal
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user