Compare commits

..

No commits in common. "06a76ae98f2aaaad3f7090f88f4837cb274915c7" and "265fba390834b131743b1c673d7d75257db3cb11" have entirely different histories.

26 changed files with 294 additions and 259 deletions

View file

@ -1,8 +1,8 @@
{ lib }: { lib, ... }:
{ {
options.assets = lib.options.create { options.assets = lib.mkOption {
type = lib.types.raw; type = lib.types.unspecified;
writable = false; readOnly = true;
}; };
config.assets = { config.assets = {

23
flake.lock generated
View file

@ -276,6 +276,26 @@
} }
}, },
"flake-parts_2": { "flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1741352980,
"narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": { "inputs": {
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
@ -489,7 +509,7 @@
}, },
"niko-nur": { "niko-nur": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_3",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
@ -702,6 +722,7 @@
"disko": "disko", "disko": "disko",
"fenix": "fenix", "fenix": "fenix",
"firefox-darwin": "firefox-darwin", "firefox-darwin": "firefox-darwin",
"flake-parts": "flake-parts_2",
"helix": "helix", "helix": "helix",
"home-manager": "home-manager", "home-manager": "home-manager",
"lix": "lix", "lix": "lix",

View file

@ -1,37 +1,73 @@
{ {
outputs = outputs =
inputs: inputs@{ flake-parts, ... }:
let let
nilla = import ./nilla.nix { inherit inputs; }; nilla = import ./nilla.nix { inherit inputs; };
transpose =
attrs:
let
inherit (inputs.nixpkgs) lib;
# maps an attrset of systems to packages to list of [ {name; system; value;} ]
pkgToListAll =
name: pkg:
map (system: {
inherit name system;
value = pkg.${system};
}) (builtins.attrNames pkg);
pkgsToListAll = pkgs: map (name: pkgToListAll name pkgs.${name}) (builtins.attrNames pkgs);
# list of all packages in format [ {name; system; value;} ]
allPkgs = lib.flatten (pkgsToListAll attrs);
systems = builtins.groupBy (pkg: pkg.system) allPkgs;
in
builtins.mapAttrs (_: pkgs: lib.listToAttrs pkgs) systems;
in
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" "aarch64-linux"
"aarch64-darwin" "aarch64-darwin"
]; ];
# NOTE: Assumes every package is available for every system.
# For now let's say this is always the case. imports = [
transpose = inputs.treefmt.flakeModule
attrs:
let ./assets
inherit (inputs.nixpkgs) lib; ./hosts
mappedForSystem = system: builtins.mapAttrs (_: pkg: pkg.result.${system}) attrs; ./modules
in ./services
lib.genAttrs systems mappedForSystem; ];
in
{ flake.devShells = transpose (builtins.mapAttrs (_: shell: shell.result) nilla.shells);
inherit (nilla) nixosModules; flake.packages = transpose (builtins.mapAttrs (_: pkg: pkg.result) nilla.packages);
inherit (nilla) darwinModules;
inherit (nilla) homeModules; perSystem = {
inherit (nilla) nixosConfigurations; treefmt = {
inherit (nilla) darwinConfigurations; programs.deadnix.enable = true;
inherit (nilla) homeConfigurations; programs.nixfmt.enable = true;
devShells = transpose nilla.shells; programs.statix.enable = true;
packages = transpose nilla.packages; programs.fish_indent.enable = true;
formatter = nilla.packages.formatter.result; programs.deno.enable = true;
programs.stylua.enable = true;
programs.shfmt.enable = true;
settings.global.excludes = [
# agenix
"*.age"
# racket
"*.rkt"
"**/rashrc"
];
settings.on-unmatched = "fatal";
};
};
}; };
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable"; nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
disko = { disko = {
url = "github:nix-community/disko"; url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";

View file

@ -1,11 +1,11 @@
{ {
config, config,
self,
inputs,
...
}: }:
let
inputs = builtins.mapAttrs (_: input: input.result) config.inputs;
in
{ {
includes = [ imports = [
./kazuki ./kazuki
./hijiri-vm ./hijiri-vm
./hijiri ./hijiri
@ -17,20 +17,20 @@ in
./youko ./youko
]; ];
config.configBuilders = builders =
let let
sharedOptions = { sharedOptions = {
_file = ./default.nix; _file = ./default.nix;
settei.sane-defaults.allSshKeys = config.assets.sshKeys.user; settei.sane-defaults.allSshKeys = config.assets.sshKeys.user;
settei.flake-qol.inputs = inputs // { settei.flake-qol.inputs = inputs // {
settei = inputs.self; settei = self;
}; };
}; };
baseNixos = inputs.nixpkgs.lib.nixosSystem { baseNixos = inputs.nixpkgs.lib.nixosSystem {
modules = [ modules = [
config.nixosModules.combined self.nixosModules.combined
sharedOptions sharedOptions
]; ];
specialArgs.configurationName = "base"; specialArgs.configurationName = "base";
@ -38,7 +38,7 @@ in
baseDarwin = inputs.darwin.lib.darwinSystem { baseDarwin = inputs.darwin.lib.darwinSystem {
modules = [ modules = [
config.darwinModules.combined self.darwinModules.combined
sharedOptions sharedOptions
]; ];
specialArgs.configurationName = "base"; specialArgs.configurationName = "base";
@ -50,7 +50,7 @@ in
baseNixos.extendModules { baseNixos.extendModules {
modules = [ modules = [
module module
config.extraHostConfigs.${name} or { } config.__extraHostConfigs.${name} or { }
]; ];
specialArgs.configurationName = name; specialArgs.configurationName = name;
}; };
@ -61,7 +61,7 @@ in
eval = baseDarwin._module.args.extendModules { eval = baseDarwin._module.args.extendModules {
modules = [ modules = [
module module
config.extraHostConfigs.${name} or { } config.__extraHostConfigs.${name} or { }
]; ];
specialArgs.configurationName = name; specialArgs.configurationName = name;
}; };

View file

@ -1,5 +1,5 @@
{ {
config.configurations.nixos.hijiri-vm = configurations.nixos.hijiri-vm =
{ {
modulesPath, modulesPath,
lib, lib,

View file

@ -1,5 +1,5 @@
{ {
config.configurations.darwin.hijiri = configurations.darwin.hijiri =
{ {
config, config,
pkgs, pkgs,

View file

@ -1,6 +1,6 @@
{ lib, ... }: { lib, ... }:
{ {
config.configurations.nixos = configurations.nixos =
let let
mkInstaller = mkInstaller =
system: system:

View file

@ -1,5 +1,5 @@
{ {
config.configurations.nixos.kazuki = configurations.nixos.kazuki =
{ {
modulesPath, modulesPath,
... ...

View file

@ -1,5 +1,5 @@
{ {
config.configurations.darwin.kogata = configurations.darwin.kogata =
{ pkgs, ... }: { pkgs, ... }:
{ {
nixpkgs.system = "aarch64-darwin"; nixpkgs.system = "aarch64-darwin";

View file

@ -1,5 +1,5 @@
{ {
config.configurations.nixos.legion = configurations.nixos.legion =
{ {
config, config,
username, username,

View file

@ -1,5 +1,5 @@
{ {
config.configurations.nixos.ude = configurations.nixos.ude =
{ {
config, config,
modulesPath, modulesPath,

View file

@ -1,5 +1,5 @@
{ {
config.configurations.nixos.youko = configurations.nixos.youko =
{ {
config, config,
lib, lib,

View file

@ -1,21 +1,29 @@
{ {
config, config,
inputs,
...
}: }:
let let
inputs = builtins.mapAttrs (_: input: input.result) config.inputs; flakeModule = import ./flake { inherit (inputs) nixpkgs darwin home-manager; };
perInput = system: flake: {
packages = flake.packages.${system};
};
in in
{ {
config.homeModules = rec { imports = [
flakeModule
];
flake.homeModules = rec {
settei = ./home; settei = ./home;
default = settei; default = settei;
}; };
config.nixosModules = rec { flake.flakeModules = rec {
settei = flakeModule;
default = settei;
};
flake.nixosModules = rec {
settei = import ./system { settei = import ./system {
inherit perInput; inherit (config) perInput;
isLinux = true; isLinux = true;
}; };
combined = { combined = {
@ -38,9 +46,9 @@ in
default = combined; default = combined;
}; };
config.darwinModules = rec { flake.darwinModules = rec {
settei = import ./system { settei = import ./system {
inherit perInput; inherit (config) perInput;
isLinux = false; isLinux = false;
}; };
combined = { combined = {

View file

@ -0,0 +1,54 @@
{
nixpkgs,
darwin,
home-manager,
}:
{
config,
lib,
...
}:
with lib;
{
_file = ./configurations.nix;
options = {
# Those functions take the final arguments and emit a valid configuration.
# Probably should hardly ever be overriden
builders = {
nixos = mkOption {
type = types.functionTo types.unspecified;
default = _name: nixpkgs.lib.nixosSystem;
};
darwin = mkOption {
type = types.functionTo types.unspecified;
default = _name: darwin.lib.darwinSystem;
};
home = mkOption {
type = types.functionTo types.unspecified;
default = _name: home-manager.lib.homeManagerConfiguration;
};
};
configurations = {
nixos = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
};
darwin = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
};
home = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
};
};
};
config.flake = {
nixosConfigurations = mapAttrs config.builders.nixos config.configurations.nixos;
darwinConfigurations = mapAttrs config.builders.darwin config.configurations.darwin;
homeConfigurations = mapAttrs config.builders.home config.configurations.home;
};
}

13
modules/flake/default.nix Normal file
View file

@ -0,0 +1,13 @@
{
nixpkgs,
darwin,
home-manager,
}:
{
_file = ./default.nix;
imports = [
(import ./configurations.nix { inherit nixpkgs darwin home-manager; })
./services.nix
];
}

View file

@ -0,0 +1,95 @@
# List of features I want this module to eventually have
# TODO: Automatic port allocation
# TODO: Making it possible to conveniently isolate services (running them in NixOS containers)
# TODO: Handling specializations
# TODO: Convenient http handling
# TODO: Automatic backup
{ config, lib, ... }:
let
serviceModule =
{ config, ... }:
{
options = {
host = lib.mkOption {
type = lib.types.str;
};
ports = lib.mkOption {
type = with lib.types; listOf port;
default = [ ];
};
hosts = lib.mkOption {
type = with lib.types; listOf str;
default = [ config.host ];
};
config = lib.mkOption {
type = lib.types.deferredModule;
default = { };
};
hostConfig = lib.mkOption {
type = with lib.types; attrsOf deferredModule;
default = { };
};
};
};
moduleToHostConfigs =
cfg:
lib.genAttrs cfg.hosts (host: {
imports = [
cfg.config
(cfg.hostConfig.${host} or { })
];
});
maybeGetPreviousConfigs = acc: host: (acc.${host} or { imports = [ ]; }).imports;
in
{
_file = ./services.nix;
options = {
services = lib.mkOption {
type = with lib.types; attrsOf (submodule serviceModule);
default = { };
};
__extraHostConfigs = lib.mkOption {
type = with lib.types; attrsOf deferredModule;
readOnly = true;
};
};
config.__extraHostConfigs =
let
duplicatePorts = lib.pipe config.services [
lib.attrValues
(map (cfg: cfg.ports))
lib.flatten
(lib.groupBy' (cnt: _: cnt + 1) 0 toString)
(lib.filterAttrs (_: cnt: cnt > 1))
lib.attrNames
];
assertMsg =
let
plural = lib.length duplicatePorts > 1;
in
"\nBad service config:\nThe following port${if plural then "s" else ""} ${
if plural then "were" else "was"
} declared multiple times: ${lib.concatStringsSep ", " duplicatePorts}";
# Here I collect all the services.<name>.config into a flat
# __extraHostConfigs.<host>.imports = [
# ...
# ]
# so that I can easily import them in hosts/default.nix
hostConfigs = lib.pipe config.services [
lib.attrValues
(lib.foldl' (
acc: cfg:
acc
// lib.mapAttrs (host: c: {
imports = c.imports ++ (maybeGetPreviousConfigs acc host);
}) (moduleToHostConfigs cfg)
) { })
];
in
if duplicatePorts != [ ] then throw assertMsg else hostConfigs;
}

View file

@ -1,7 +1,12 @@
{ lib }: { lib }:
{ {
config.builders.custom-load = { config.builders.custom-load = {
settings.type = lib.types.submodule { }; settings.type = lib.types.submodule {
options.args = lib.options.create {
type = lib.types.null;
default.value = null;
};
};
settings.default = { }; settings.default = { };
build = pkg: lib.attrs.generate pkg.systems (system: pkg.package { inherit system; }); build = pkg: lib.attrs.generate pkg.systems (system: pkg.package { inherit system; });
}; };

View file

@ -1,47 +0,0 @@
{ config, lib }:
{
options = {
configBuilders = {
nixos = lib.options.create {
type = lib.types.function lib.types.raw;
default.value = _name: config.inputs.nixpkgs.result.lib.nixosSystem;
};
darwin = lib.options.create {
type = lib.types.function lib.types.raw;
default.value = _name: config.inputs.darwin.result.lib.darwinSystem;
};
home = lib.options.create {
type = lib.types.function lib.types.raw;
default.value = _name: config.inputs.home-manager.result.lib.homeManagerConfiguration;
};
};
configurations = {
nixos = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = { };
};
darwin = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = { };
};
home = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = { };
};
};
nixosConfigurations = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = builtins.mapAttrs config.configBuilders.nixos config.configurations.nixos;
};
darwinConfigurations = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = builtins.mapAttrs config.configBuilders.darwin config.configurations.darwin;
};
homeConfigurations = lib.options.create {
type = lib.types.attrs.lazy lib.types.raw;
default.value = builtins.mapAttrs config.configBuilders.home config.configurations.home;
};
};
}

View file

@ -1,8 +1,3 @@
{ {
includes = [ includes = [ ./builders ];
./builders
./services.nix
./configurations.nix
./modules.nix
];
} }

View file

@ -1,17 +0,0 @@
{ lib }:
{
options = {
nixosModules = lib.options.create {
type = lib.types.attrs.of lib.types.raw;
default.value = { };
};
darwinModules = lib.options.create {
type = lib.types.attrs.of lib.types.raw;
default.value = { };
};
homeModules = lib.options.create {
type = lib.types.attrs.of lib.types.raw;
default.value = { };
};
};
}

View file

@ -1,95 +0,0 @@
{ lib, config }:
let
inherit (builtins)
attrNames
attrValues
concatStringsSep
mapAttrs
foldl'
groupBy
length
;
serviceModule =
{ config }:
{
options = {
host = lib.options.create {
type = lib.types.string;
};
ports = lib.options.create {
type = lib.types.list.of lib.types.port;
default.value = [ ];
};
hosts = lib.options.create {
type = lib.types.list.of lib.types.string;
default.value = [ config.host ];
};
module = lib.options.create {
type = lib.types.raw;
default.value = { };
};
hostModule = lib.options.create {
type = lib.types.attrs.of lib.types.raw;
default.value = { };
};
};
};
moduleToHostConfigs =
cfg:
lib.attrs.generate cfg.hosts (host: {
imports = [
cfg.module
(cfg.hostModule.${host} or { })
];
});
maybeGetPreviousConfigs = acc: host: (acc.${host} or { imports = [ ]; }).imports;
# Copied from nixpkgs/lib/lists.nix
groupBy' =
op: nul: pred: lst:
mapAttrs (_name: foldl' op nul) (groupBy pred lst);
duplicatePorts = lib.fp.pipe [
attrValues
(map (cfg: cfg.ports))
lib.lists.flatten
(groupBy' (cnt: _: cnt + 1) 0 toString)
(lib.attrs.filter (_: cnt: cnt > 1))
attrNames
] config.services;
in
{
options.services = lib.options.create {
type = lib.types.attrs.of (lib.types.submodule serviceModule);
default.value = { };
};
options.extraHostConfigs = lib.options.create {
type = lib.types.attrs.of lib.types.raw;
writable = false;
default.value = lib.fp.pipe [
attrValues
(foldl' (
acc: cfg:
acc
// mapAttrs (host: c: {
imports = c.imports ++ (maybeGetPreviousConfigs acc host);
}) (moduleToHostConfigs cfg)
) { })
] config.services;
};
config.assertions = [
{
assertion = duplicatePorts == [ ];
message =
let
plural = length duplicatePorts > 1;
in
"\nBad service config:\nThe following port${if plural then "s" else ""} ${
if plural then "were" else "was"
} declared multiple times: ${concatStringsSep ", " duplicatePorts}";
}
];
}

View file

@ -8,10 +8,6 @@
./modules/nilla ./modules/nilla
./pkgs ./pkgs
./wrappers ./wrappers
./hosts
./assets
./services
./modules
]; ];
config.inputs = builtins.mapAttrs (_: src: { config.inputs = builtins.mapAttrs (_: src: {
@ -59,23 +55,13 @@
name = "settei-base"; name = "settei-base";
paths = with (getPkgs system); [ paths = with (getPkgs system); [
# TODO: wrappers # TODO: wrappers
helix # helix
fish # fish
git-commit-last git-commit-last
git-fixup git-fixup
]; ];
} }
); );
formatter = {
inherit systems;
builder = "custom-load";
package =
{ system }:
let
eval = inputs.treefmt.lib.evalModule inputs.nixpkgs.legacyPackages.${system} ./treefmt.nix;
in
eval.config.build.wrapper;
};
}; };
config.shells.default = { config.shells.default = {

View file

@ -1,12 +1,12 @@
{ {
config.services.attic = services.attic =
let let
atticPort = 9476; atticPort = 9476;
in in
{ {
host = "kazuki"; host = "kazuki";
ports = [ atticPort ]; ports = [ atticPort ];
module = config =
{ config, ... }: { config, ... }:
{ {
age.secrets.attic-creds = { age.secrets.attic-creds = {

View file

@ -1,5 +1,5 @@
{ {
includes = [ imports = [
./attic.nix ./attic.nix
./forgejo-runner.nix ./forgejo-runner.nix
]; ];

View file

@ -1,10 +1,10 @@
{ {
config.services.forgejo-runner = { services.forgejo-runner = {
hosts = [ hosts = [
"ude" "ude"
"youko" "youko"
]; ];
module = config =
{ {
config, config,
lib, lib,

View file

@ -1,19 +0,0 @@
{
projectRootFile = "nilla.nix";
programs.deadnix.enable = true;
programs.nixfmt.enable = true;
programs.statix.enable = true;
programs.fish_indent.enable = true;
programs.deno.enable = true;
programs.stylua.enable = true;
programs.shfmt.enable = true;
settings.global.excludes = [
# agenix
"*.age"
# racket
"*.rkt"
"**/rashrc"
];
settings.on-unmatched = "fatal";
}