Compare commits

...

10 commits

35 changed files with 473 additions and 342 deletions

View file

@ -6,13 +6,15 @@
Collection of my personal Nix configurations and opinionated NixOS, nix-darwin, home-manager, and flake-parts modules. Collection of my personal Nix configurations and opinionated NixOS, nix-darwin, home-manager, and flake-parts modules.
> [!CAUTION] > [!CAUTION]
> I tried to make the modules in this repository useful to others without having to modify them, > I tried to make the modules in this repository useful to others without having
> meaning I tried to have many configuration options, have them be disabled by default, etc. > to modify them, meaning I tried to have many configuration options, have them
> That is no more and although I still encourage people to use my config for learning and inspiration, > be disabled by default, etc. That is no more and although I still encourage
> the modules will now assume they're running in my infrastructure and I'll only add > people to use my config for learning and inspiration, the modules will now
> configuration and/or enabling options when it makes sense to me, personally. > assume they're running in my infrastructure and I'll only add configuration
> and/or enabling options when it makes sense to me, personally.
## Project structure ## Project structure
- hosts - per-machine configurations - hosts - per-machine configurations
- kazuki - my linux arm server - kazuki - my linux arm server
- legion - my linux x86 server - legion - my linux x86 server
@ -24,29 +26,38 @@ Collection of my personal Nix configurations and opinionated NixOS, nix-darwin,
- system - my opinionated nixos/nix-darwin modules - system - my opinionated nixos/nix-darwin modules
- home - my opinionated home-manager modules - home - my opinionated home-manager modules
- flake - flake-parts modules - flake - flake-parts modules
- services - configs for services I self-host
- secrets - agenix secrets - secrets - agenix secrets
- wrappers - nix packages wrapped with my configs (see: [wrapper-manager](https://github.com/viperML/wrapper-manager)) - wrappers - nix packages wrapped with my configs (see:
[wrapper-manager](https://github.com/viperML/wrapper-manager))
- assets - miscellaneous values reused throughout my config - assets - miscellaneous values reused throughout my config
- effects.nix - hercules-ci configuration - effects.nix - hercules-ci configuration
## Code guidelines ## Code guidelines
Not set rules but general guidelines for myself to hopefully keep this config clean, maintainable, and reusable. Not set rules but general guidelines for myself to hopefully keep this config
clean, maintainable, and reusable.
- only importing downwards. this means no `imports = [ ../../foo/bar/some-module.nix ];` - only importing downwards. this means no
- ideally only one level of imports. `imports = [ ../../foo/bar/some-module.nix ];`
this means i'll try to only do `imports = [ ./foo ];` or `imports = [ ./bar.nix ]` but not `imports = [ ./x/y/z.nix ];` - ideally only one level of imports. this means i'll try to only do
- the file should be roughly in order of most interesting to least interesting options. `imports = [ ./foo ];` or `imports = [ ./bar.nix ]` but not
`imports = [ ./x/y/z.nix ];`
- the file should be roughly in order of most interesting to least interesting
options.
- `imports` should be the first attribute (except for `_file`) - `imports` should be the first attribute (except for `_file`)
- there should be no implicit state anywhere in the config. - there should be no implicit state anywhere in the config. (sounds obvious but
(sounds obvious but this is already broken with legion and the zfs pool but i'll let that one slide) this is already broken with legion and the zfs pool but i'll let that one
to achieve this i still need to create a proper live iso with my config and my bootstrapping ssh key slide) to achieve this i still need to create a proper live iso with my config
and my bootstrapping ssh key
## TODOs ## TODOs
Sorted rougly by priority Sorted rougly by priority
- bring back ci (sorta done) - bring back ci (sorta done)
- hercules-ci effects for deploying machines on update (if configuration is valid) - hercules-ci effects for deploying machines on update (if configuration is
valid)
- fix disko - fix disko
- make the configuration truly declarative (to a reasonable degree) - make the configuration truly declarative (to a reasonable degree)
- themeing solution - themeing solution

View file

@ -16,6 +16,7 @@
./modules ./modules
./wrappers ./wrappers
./pkgs ./pkgs
./services
]; ];
perSystem = perSystem =
@ -54,6 +55,18 @@
programs.nixfmt.enable = true; programs.nixfmt.enable = true;
programs.statix.enable = true; programs.statix.enable = true;
programs.fish_indent.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";
}; };
}; };
}; };

View file

@ -1,8 +1,8 @@
builds: builds:
include: include:
- 'devShells.*.*' - "devShells.*.*"
- 'packages.*.*' - "packages.*.*"
- 'formatter.*' - "formatter.*"
- 'nixosConfigurations.*' - "nixosConfigurations.*"
- 'darwinConfigurations.*' - "darwinConfigurations.*"
- 'homeConfigurations.*' - "homeConfigurations.*"

View file

@ -62,7 +62,10 @@
nixos = nixos =
name: module: name: module:
baseNixos.extendModules { baseNixos.extendModules {
modules = [ module ]; modules = [
module
config.__extraHostConfigs.${name} or { }
];
specialArgs.configurationName = name; specialArgs.configurationName = name;
}; };
@ -70,7 +73,10 @@
name: module: name: module:
let let
eval = baseDarwin._module.args.extendModules { eval = baseDarwin._module.args.extendModules {
modules = [ module ]; modules = [
module
config.__extraHostConfigs.${name} or { }
];
specialArgs.configurationName = name; specialArgs.configurationName = name;
}; };
in in

View file

@ -15,7 +15,7 @@
nixpkgs.system = "aarch64-darwin"; nixpkgs.system = "aarch64-darwin";
settei.user.config = { settei.user.config = {
common.desktop.enable = true; settei.desktop.enable = true;
home.packages = with pkgs; [ home.packages = with pkgs; [
utm utm
qemu qemu
@ -28,7 +28,7 @@
}; };
# TODO: Declarative syncthing config # TODO: Declarative syncthing config
}; };
common.incus.enable = true; settei.incus.enable = true;
# TODO: Setup podman remote # TODO: Setup podman remote
system.defaults = { system.defaults = {

View file

@ -1,115 +0,0 @@
{ config, lib, ... }:
let
atticPort = 9476;
in
{
age.secrets.attic-creds = {
file = ../../secrets/attic-creds.age;
owner = config.services.atticd.user;
};
age.secrets.nrab-lol-cf = {
file = ../../secrets/nrab-lol-cf.age;
owner = config.services.nginx.user;
};
services.atticd = {
enable = true;
environmentFile = config.age.secrets.attic-creds.path;
settings = {
listen = "[::]:${toString atticPort}";
storage = {
type = "local";
path = "/storage-box";
};
compression.type = "none";
chunking = {
nar-size-threshold = 0;
min-size = 0;
avg-size = 0;
max-size = 0;
};
api-endpoint = "https://attic.nrab.lol/";
};
};
users = {
users.atticd = {
uid = 990;
isSystemUser = true;
group = "atticd";
home = "/var/lib/atticd";
createHome = true;
};
groups.atticd = {
gid = 988;
};
};
systemd.services.atticd = {
after = [ "storage\\x2dbox.mount" ];
serviceConfig.DynamicUser = lib.mkForce false;
};
security.acme = {
acceptTerms = true;
defaults.email = "nikodem@rabulinski.com";
};
users.users.nginx.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [
80
443
];
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
virtualHosts."attic.nrab.lol" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
locations."/" = {
proxyPass = "http://attic";
};
extraConfig = ''
client_max_body_size 24G;
'';
};
virtualHosts."cache.nrab.lol" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
locations."/" = {
proxyPass = "http://attic/public$request_uri";
};
extraConfig = ''
proxy_cache nixstore;
proxy_cache_use_stale error timeout http_500 http_502;
proxy_cache_lock on;
proxy_cache_key $request_uri;
proxy_cache_valid 200 24h;
'';
};
upstreams."attic".servers = {
"localhost:${toString atticPort}" = { };
};
appendHttpConfig = ''
proxy_cache_path /var/cache/nginx/nixstore levels=1:2 keys_zone=nixstore:10m max_size=10g inactive=24h use_temp_path=off;
'';
};
security.acme.certs."attic.nrab.lol" = {
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.nrab-lol-cf.path;
};
security.acme.certs."cache.nrab.lol" = {
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.nrab-lol-cf.path;
};
}

View file

@ -13,7 +13,6 @@
./mail.nix ./mail.nix
./vault.nix ./vault.nix
./storage.nix ./storage.nix
./attic.nix
./ntfy.nix ./ntfy.nix
./zitadel.nix ./zitadel.nix
./forgejo.nix ./forgejo.nix
@ -42,14 +41,5 @@
routes = [ { Gateway = "fe80::1"; } ]; routes = [ { Gateway = "fe80::1"; } ];
}; };
networking.useNetworkd = true; networking.useNetworkd = true;
common.hercules.enable = true;
common.github-runner = {
enable = true;
runners.settei = {
url = "https://github.com/nrabulinski/settei";
instances = 2;
};
};
}; };
} }

View file

@ -4,7 +4,7 @@
{ {
nixpkgs.system = "aarch64-darwin"; nixpkgs.system = "aarch64-darwin";
settei.user.config.common.desktop.enable = true; settei.user.config.settei.desktop.enable = true;
settei.unfree.allowedPackages = [ "teams" ]; settei.unfree.allowedPackages = [ "teams" ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
@ -15,11 +15,5 @@
ipv4 = "100.102.13.61"; ipv4 = "100.102.13.61";
ipv6 = "fd7a:115c:a1e0::e126:d3d"; ipv6 = "fd7a:115c:a1e0::e126:d3d";
}; };
common.hercules.enable = true;
common.github-runner = {
enable = true;
runners.settei.url = "https://github.com/nrabulinski/settei";
};
}; };
} }

View file

@ -31,7 +31,7 @@
networking = { networking = {
hostName = "legion"; hostName = "legion";
hostId = builtins.substring 0 8 (builtins.readFile ./machine-id); hostId = builtins.substring 0 8 "524209a432724c7abaf04398cdd6eecd";
networkmanager.enable = true; networkmanager.enable = true;
}; };
systemd.services.NetworkManager-wait-online.enable = false; systemd.services.NetworkManager-wait-online.enable = false;
@ -41,15 +41,7 @@
age.secrets.niko-pass.file = ../../secrets/legion-niko-pass.age; age.secrets.niko-pass.file = ../../secrets/legion-niko-pass.age;
users.users.${username}.hashedPasswordFile = config.age.secrets.niko-pass.path; users.users.${username}.hashedPasswordFile = config.age.secrets.niko-pass.path;
common.hercules.enable = true; settei.incus.enable = true;
common.github-runner = {
enable = true;
runners.settei = {
url = "https://github.com/nrabulinski/settei";
instances = 4;
};
};
common.incus.enable = true;
virtualisation.podman.enable = true; virtualisation.podman.enable = true;
}; };
} }

View file

@ -11,7 +11,7 @@
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
settei.user.config = { settei.user.config = {
common.desktop.enable = true; settei.desktop.enable = true;
home.packages = with pkgs; [ home.packages = with pkgs; [
brightnessctl brightnessctl
dmenu dmenu

View file

@ -1 +0,0 @@
524209a432724c7abaf04398cdd6eecd

View file

@ -25,16 +25,7 @@
ipv6 = "fd7a:115c:a1e0:ab12:4843:cd96:6276:2a8b"; ipv6 = "fd7a:115c:a1e0:ab12:4843:cd96:6276:2a8b";
}; };
common.hercules.enable = true; settei.incus.enable = true;
services.hercules-ci-agent.settings.concurrentTasks = 6;
common.github-runner = {
enable = true;
runners.settei = {
url = "https://github.com/nrabulinski/settei";
instances = 6;
};
};
common.incus.enable = true;
virtualisation.podman.enable = true; virtualisation.podman.enable = true;
services.nginx = { services.nginx = {

View file

@ -1,11 +1,39 @@
{
config,
inputs,
...
}:
let
flakeModule = import ./flake { inherit (inputs) nixpkgs darwin home-manager; };
in
{ {
imports = [ imports = [
./system flakeModule
./flake
]; ];
flake.homeModules = rec { flake.homeModules = rec {
settei = ./home; settei = ./home;
default = settei; default = settei;
}; };
flake.flakeModules = rec {
settei = flakeModule;
default = settei;
};
flake.nixosModules = rec {
settei = import ./system {
inherit (config) perInput;
isLinux = true;
};
default = settei;
};
flake.darwinModules = rec {
settei = import ./system {
inherit (config) perInput;
isLinux = false;
};
default = settei;
};
} }

View file

@ -1,19 +1,13 @@
{ {
flake-parts-lib, nixpkgs,
lib, darwin,
inputs, home-manager,
...
}: }:
let
inherit (flake-parts-lib) importApply;
flakeModules = {
configurations = importApply ./configurations.nix { inherit (inputs) nixpkgs darwin home-manager; };
};
in
{ {
imports = lib.attrValues flakeModules; _file = ./default.nix;
flake = { imports = [
inherit flakeModules; (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

@ -10,7 +10,7 @@
let let
# TODO: Conditionally define based on whether we're in a system configuration or not # TODO: Conditionally define based on whether we're in a system configuration or not
fishOverlayModule = lib.mkIf (!args ? osConfig) { fishOverlayModule = lib.mkIf (!args ? osConfig) {
# See modules/system/common/default.nix for reasoning. # See modules/system/settei/default.nix for reasoning.
nixpkgs.overlays = [ (_: _: { inherit (inputs'.settei.packages) fish; }) ]; nixpkgs.overlays = [ (_: _: { inherit (inputs'.settei.packages) fish; }) ];
}; };
in in
@ -21,8 +21,10 @@ in
./desktop ./desktop
fishOverlayModule fishOverlayModule
./xdg.nix ./xdg.nix
./unfree.nix
]; ];
programs.home-manager.enable = true;
programs.fish.enable = true; programs.fish.enable = true;
programs.nix-index.enable = true; programs.nix-index.enable = true;
programs.ssh = { programs.ssh = {

View file

@ -11,11 +11,11 @@
imports = [ ./zellij.nix ]; imports = [ ./zellij.nix ];
options.common.desktop = { options.settei.desktop = {
enable = lib.mkEnableOption "Common configuration for desktop machines"; enable = lib.mkEnableOption "Common configuration for desktop machines";
}; };
config = lib.mkIf config.common.desktop.enable { config = lib.mkIf config.settei.desktop.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
inputs'.settei.packages.wezterm inputs'.settei.packages.wezterm
nerd-fonts.iosevka nerd-fonts.iosevka
@ -23,6 +23,7 @@
fontconfig fontconfig
signal-desktop signal-desktop
]; ];
settei.unfree.allowedPackages = [ "signal-desktop" ];
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;

View file

@ -1,9 +1,9 @@
# Copy of modules/system/unfree.nix
{ config, lib, ... }: { config, lib, ... }:
{ {
_file = ./unfree.nix; _file = ./unfree.nix;
options = { options = {
# TODO(maybe?): Allow other types and more customizability
settei.unfree.allowedPackages = settei.unfree.allowedPackages =
with lib; with lib;
mkOption { mkOption {

View file

@ -1,21 +1,48 @@
{ config, lib, ... }:
{ {
flake = perInput,
lib.genAttrs # TODO: Figure out a nicer way of doing this without infrec?
[ isLinux,
"nixosModules" }:
"darwinModules" {
] config,
( lib,
attr: pkgs,
let inputs',
isLinux = lib.hasPrefix "nixos" attr; username,
in ...
{ }:
settei = import ./settei { {
inherit (config) perInput; _file = ./default.nix;
inherit isLinux;
}; imports = [
} (import ./sane-defaults.nix { inherit isLinux; })
); (import ./flake-qol.nix { inherit perInput; })
./user.nix
(import ./programs { inherit isLinux; })
(import ./tailscale.nix { inherit isLinux; })
(import ./containers.nix { inherit isLinux; })
./unfree.nix
(import ./hercules.nix { inherit isLinux; })
(import ./github-runner.nix { inherit isLinux; })
(import ./incus.nix { inherit isLinux; })
(import ./monitoring.nix { inherit isLinux; })
];
options.settei = with lib; {
username = mkOption {
type = types.str;
default = "niko";
};
};
config = {
programs.fish.enable = true;
users.users.${username}.shell = pkgs.fish;
time.timeZone = lib.mkDefault "Europe/Warsaw";
# NixOS' fish module doesn't allow setting what package to use for fish,
# so I need to override the fish package.
nixpkgs.overlays = [ (_: _: { inherit (inputs'.settei.packages) fish; }) ];
};
} }

View file

@ -8,7 +8,7 @@ let
inherit (lib) mkOption types; inherit (lib) mkOption types;
github-runner-user = "github-runner"; github-runner-user = "github-runner";
cfg = config.common.github-runner; cfg = config.settei.github-runner;
sharedConfig = { sharedConfig = {
age.secrets.github-token = { age.secrets.github-token = {
@ -50,13 +50,13 @@ let
}; };
darwinConfig = lib.optionalAttrs (!isLinux) { darwinConfig = lib.optionalAttrs (!isLinux) {
warnings = lib.singleton "common.github-runner doesn't do anything on darwin yet"; warnings = lib.singleton "settei.github-runner doesn't do anything on darwin yet";
}; };
in in
{ {
_file = ./github-runner.nix; _file = ./github-runner.nix;
options.common.github-runner = { options.settei.github-runner = {
enable = lib.mkEnableOption "using this machine as a self-hosted github runner"; enable = lib.mkEnableOption "using this machine as a self-hosted github runner";
runners = mkOption { runners = mkOption {
type = type =

View file

@ -0,0 +1,47 @@
{ isLinux }:
{
config,
lib,
...
}:
let
options = {
settei.hercules.enable = lib.mkEnableOption "Enables hercules-ci-agent with my configuration";
};
herculesUser =
if isLinux then
config.systemd.services.hercules-ci-agent.serviceConfig.User
else
config.launchd.daemons.hercules-ci-agent.serviceConfig.UserName;
in
{
_file = ./hercules.nix;
inherit options;
config = lib.mkIf config.settei.hercules.enable {
age.secrets.hercules-token = {
file = ../../../secrets/hercules-token.age;
owner = herculesUser;
};
age.secrets.hercules-cache = {
file = ../../../secrets/hercules-cache.age;
owner = herculesUser;
};
age.secrets.hercules-secrets = {
file = ../../../secrets/hercules-secrets.age;
owner = herculesUser;
};
services.hercules-ci-agent = {
enable = true;
settings = {
clusterJoinTokenPath = config.age.secrets.hercules-token.path;
concurrentTasks = lib.mkDefault 4;
binaryCachesPath = config.age.secrets.hercules-cache.path;
secretsJsonPath = config.age.secrets.hercules-secrets.path;
};
};
};
}

View file

@ -9,7 +9,7 @@
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
cfg = config.common.incus; cfg = config.settei.incus;
sharedConfig = { sharedConfig = {
environment.systemPackages = [ environment.systemPackages = [
@ -71,7 +71,7 @@ in
{ {
_file = ./incus.nix; _file = ./incus.nix;
options.common.incus = { options.settei.incus = {
enable = lib.mkEnableOption "incus, the VM and container manager"; enable = lib.mkEnableOption "incus, the VM and container manager";
clientOnly = mkOption { clientOnly = mkOption {
type = types.bool; type = types.bool;
@ -81,7 +81,7 @@ in
clientPackage = lib.mkOption { clientPackage = lib.mkOption {
type = types.package; type = types.package;
default = cfg.package.client; default = cfg.package.client;
defaultText = lib.literalExpression "config.common.incus.package.client"; defaultText = lib.literalExpression "config.settei.incus.package.client";
description = "The incus client package to use. This package is added to PATH."; description = "The incus client package to use. This package is added to PATH.";
}; };
}; };

View file

@ -38,7 +38,6 @@ let
# Flakes are unusable without git present so pull it into the environment by default # Flakes are unusable without git present so pull it into the environment by default
settei.user.config.programs.git.enable = lib.mkDefault true; settei.user.config.programs.git.enable = lib.mkDefault true;
# FIXME: Move to common
users.users.${username}.openssh.authorizedKeys.keys = users.users.${username}.openssh.authorizedKeys.keys =
let let
configName' = configName' =
@ -109,6 +108,8 @@ let
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
boot.kernel.sysctl."kernel.yama.ptrace_scope" = 0; boot.kernel.sysctl."kernel.yama.ptrace_scope" = 0;
settei.user.config.services.ssh-agent.enable = true;
}; };
darwinConfig = lib.optionalAttrs (!isLinux) { darwinConfig = lib.optionalAttrs (!isLinux) {

View file

@ -1,50 +0,0 @@
{
perInput,
# TODO: Figure out a nicer way of doing this without infrec?
isLinux,
}:
{
config,
configurationName,
lib,
pkgs,
inputs,
inputs',
username,
...
}:
{
_file = ./default.nix;
imports = [
(import ./sane-defaults.nix { inherit isLinux; })
(import ./flake-qol.nix { inherit perInput; })
./user.nix
(import ./programs { inherit isLinux; })
(import ./tailscale.nix { inherit isLinux; })
(import ./containers.nix { inherit isLinux; })
./unfree.nix
(import ./hercules.nix { inherit isLinux; })
(import ./github-runner.nix { inherit isLinux; })
(import ./incus.nix { inherit isLinux; })
(import ./monitoring.nix { inherit isLinux; })
];
options.settei = with lib; {
username = mkOption {
type = types.str;
default = "niko";
};
};
config = {
programs.fish.enable = true;
users.users.${username}.shell = pkgs.fish;
time.timeZone = lib.mkDefault "Europe/Warsaw";
# NixOS' fish module doesn't allow setting what package to use for fish,
# so I need to override the fish package.
nixpkgs.overlays = [ (_: _: { inherit (inputs'.settei.packages) fish; }) ];
};
}

View file

@ -1,50 +0,0 @@
{ isLinux }:
{
config,
lib,
...
}:
let
options = {
common.hercules.enable = lib.mkEnableOption "Enables hercules-ci-agent with my configuration";
};
herculesUser =
if isLinux then
config.systemd.services.hercules-ci-agent.serviceConfig.User
else
config.launchd.daemons.hercules-ci-agent.serviceConfig.UserName;
in
{
_file = ./hercules.nix;
inherit options;
config =
lib.mkIf false
# config.common.hercules.enable
{
age.secrets.hercules-token = {
file = ../../../secrets/hercules-token.age;
owner = herculesUser;
};
age.secrets.hercules-cache = {
file = ../../../secrets/hercules-cache.age;
owner = herculesUser;
};
age.secrets.hercules-secrets = {
file = ../../../secrets/hercules-secrets.age;
owner = herculesUser;
};
services.hercules-ci-agent = {
enable = true;
settings = {
clusterJoinTokenPath = config.age.secrets.hercules-token.path;
concurrentTasks = lib.mkDefault 4;
binaryCachesPath = config.age.secrets.hercules-cache.path;
secretsJsonPath = config.age.secrets.hercules-secrets.path;
};
};
};
}

31
modules/system/unfree.nix Normal file
View file

@ -0,0 +1,31 @@
{
config,
lib,
username,
...
}:
let
# TODO: Maybe eventually support multi-user
userAllowedPackages =
lib.optionals config.settei.user.enable
config.home-manager.users.${username}.settei.unfree.allowedPackages;
in
{
_file = ./unfree.nix;
options = {
# TODO(maybe?): Allow other types and more customizability
settei.unfree.allowedPackages =
with lib;
mkOption {
type = types.listOf types.str;
default = [ ];
};
};
config = {
nixpkgs.config.allowUnfreePredicate = lib.mkForce (
pkg: builtins.elem (lib.getName pkg) (config.settei.unfree.allowedPackages ++ userAllowedPackages)
);
};
}

View file

@ -51,9 +51,6 @@ in
homeDirectory = config.users.users.${username}.home; homeDirectory = config.users.users.${username}.home;
stateVersion = "22.05"; stateVersion = "22.05";
}; };
programs.home-manager.enable = true;
services.ssh-agent.enable = true;
}; };
}; };
in in

122
services/attic.nix Normal file
View file

@ -0,0 +1,122 @@
{
services.attic =
let
atticPort = 9476;
in
{
host = "kazuki";
ports = [ atticPort ];
config =
{ config, ... }:
{
age.secrets.attic-creds = {
file = ../secrets/attic-creds.age;
owner = config.services.atticd.user;
};
age.secrets.nrab-lol-cf = {
file = ../secrets/nrab-lol-cf.age;
owner = config.services.nginx.user;
};
services.atticd = {
enable = true;
environmentFile = config.age.secrets.attic-creds.path;
settings = {
listen = "[::]:${toString atticPort}";
storage = {
type = "local";
path = "/storage-box";
};
compression.type = "none";
chunking = {
nar-size-threshold = 0;
min-size = 0;
avg-size = 0;
max-size = 0;
};
api-endpoint = "https://attic.nrab.lol/";
};
};
users = {
users.atticd = {
uid = 990;
isSystemUser = true;
group = "atticd";
home = "/var/lib/atticd";
createHome = true;
};
groups.atticd = {
gid = 988;
};
};
systemd.services.atticd = {
after = [ "storage\\x2dbox.mount" ];
};
security.acme = {
acceptTerms = true;
defaults.email = "nikodem@rabulinski.com";
};
users.users.nginx.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [
80
443
];
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
virtualHosts."attic.nrab.lol" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
locations."/" = {
proxyPass = "http://attic";
};
extraConfig = ''
client_max_body_size 24G;
'';
};
virtualHosts."cache.nrab.lol" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
locations."/" = {
proxyPass = "http://attic/public$request_uri";
};
extraConfig = ''
proxy_cache nixstore;
proxy_cache_use_stale error timeout http_500 http_502;
proxy_cache_lock on;
proxy_cache_key $request_uri;
proxy_cache_valid 200 24h;
'';
};
upstreams."attic".servers = {
"localhost:${toString atticPort}" = { };
};
appendHttpConfig = ''
proxy_cache_path /var/cache/nginx/nixstore levels=1:2 keys_zone=nixstore:10m max_size=10g inactive=24h use_temp_path=off;
'';
};
security.acme.certs."attic.nrab.lol" = {
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.nrab-lol-cf.path;
};
security.acme.certs."cache.nrab.lol" = {
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.nrab-lol-cf.path;
};
};
};
}

5
services/default.nix Normal file
View file

@ -0,0 +1,5 @@
{
imports = [
./attic.nix
];
}

View file

@ -1,22 +1,22 @@
local wezterm = require 'wezterm' local wezterm = require("wezterm")
local cfg = { local cfg = {
color_scheme = 'Default Dark (base16)', color_scheme = "Default Dark (base16)",
enable_tab_bar = false, enable_tab_bar = false,
font = wezterm.font('IosevkaTerm Nerd Font'), font = wezterm.font("IosevkaTerm Nerd Font"),
window_decorations = 'TITLE | RESIZE', window_decorations = "TITLE | RESIZE",
font_size = 10.5, font_size = 10.5,
native_macos_fullscreen_mode = true, native_macos_fullscreen_mode = true,
hide_mouse_cursor_when_typing = false, hide_mouse_cursor_when_typing = false,
keys = { keys = {
{ key = "Enter", mods = "CTRL", action = wezterm.action { SendString = "\x1b[13;5u" } }, { key = "Enter", mods = "CTRL", action = wezterm.action({ SendString = "\x1b[13;5u" }) },
{ key = "Enter", mods = "SHIFT", action = wezterm.action { SendString = "\x1b[13;2u" } }, { key = "Enter", mods = "SHIFT", action = wezterm.action({ SendString = "\x1b[13;2u" }) },
}, },
} }
if string.find(wezterm.target_triple, "darwin") then if string.find(wezterm.target_triple, "darwin") then
cfg.font_size = 14.0 cfg.font_size = 14.0
cfg.window_decorations = 'RESIZE' cfg.window_decorations = "RESIZE"
end end
return cfg return cfg