Compare commits

..

1 commit
main ... lix

Author SHA1 Message Date
Katherina Walshe-Grey a035d2613b switch from CppNix to Lix 2.90.0
Closes #8
2024-07-17 16:24:58 +01:00
122 changed files with 738 additions and 2978 deletions

1
.envrc
View file

@ -1 +0,0 @@
use_nix

View file

@ -2,27 +2,19 @@
My NixOS configuration files.
The canonical location for this repository is https://git.unspecified.systems/qenya/nixfiles. If you're viewing it elsewhere, it is a mirror and may not be up-to-date.
The canonical location for this repository is https://git.qenya.tel/qenya/nixfiles. If you're viewing it elsewhere, it is a mirror and may not be up-to-date.
## Machines
### Managed
* `kilgharrah`: Custom-built personal desktop; also currently running Jellyfin, Navidrome and Audiobookshelf servers (and an FTP server, for shits and giggles)
* `tohru`: Dell Latitude 5300, personal laptop
* `elucredassa`: Acer Aspire A315-53, old laptop with a broken keyboard that now sits in a corner being a backup server
* `yevaud`: Oracle Cloud free AMD VM, hosts a Forgejo instance and WireGuard server for the other machines in the network
* `orm`: Oracle Cloud free AMD VM, hosts an instance of Actual Budget and a PostgreSQL server for other services that need one
* `kalessin`: Oracle Cloud free ARM VM, currently idling
### Referenced only
* `shaw`: [My girlfriend's NAS](https://github.com/randomnetcat/nix-configs/tree/main/hosts/shaw)
* `latias`: My Steam Deck
* `yevaud`: Oracle Cloud free AMD VM, hosts a Forgejo instance
* `orm`: Oracle Cloud free AMD VM, currently idling
## Usage
### Building
To build locally, run `nixos-rebuild switch --flake .#[hostname]` as root.
To build locally, run `colmena apply-local` as root.
To build the remote machines, run `colmena apply`. See the [colmena documentation](https://colmena.cli.rs/) for command-line options. Notable options include:
* `--on [hostname]`: build a specific machine only
@ -30,4 +22,14 @@ To build the remote machines, run `colmena apply`. See the [colmena documentatio
### Updating
`nix flake update --commit-lock-file`
Run `npins update` to update the dependencies within the currently selected upgrade channels.
To upgrade to a new major version of a dependency, simply re-add it and the old version will be overwritten, e.g.:
```sh
npins add --name nixpkgs channel nixos-unstable
```
In either case, commit the changes to `npins/sources.json`.
See the [npins documentation](https://github.com/andir/npins) for more details.

16
colmena/local.nix Normal file
View file

@ -0,0 +1,16 @@
{ name, nodes, config, lib, pkgs, ... }:
let sources = import ../npins;
in {
deployment = {
allowLocalDeployment = true;
targetHost = null;
tags = [ "local" ];
};
environment.systemPackages = with pkgs; [
agenix
colmena
npins
];
}

12
colmena/remote.nix Normal file
View file

@ -0,0 +1,12 @@
{ name, nodes, config, lib, pkgs, ... }:
{
deployment = {
targetHost = "${name}.birdsong.network";
targetUser = "qenya";
tags = [ "remote" ];
};
security.sudo.wheelNeedsPassword = false;
nix.settings.trusted-users = [ "@wheel" ];
}

View file

@ -1,29 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qenya.base-graphical;
in
{
imports = [
./desktop.nix
./sound.nix
];
options.qenya.base-graphical.enable = mkEnableOption "Base configuration for graphical environments";
config = mkIf cfg.enable {
services.xserver.enable = true;
services.libinput.enable = true;
services.printing.enable = true;
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
fonts.packages = with pkgs; [
corefonts
];
};
}

View file

@ -1,35 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkMerge mkOption types;
cfg = config.qenya.base-graphical;
in
{
options.qenya.base-graphical.desktop = mkOption {
type = types.enum [ "gnome" "plasma6" ];
default = "gnome";
example = "plasma6";
description = "Which display manager and desktop manager to use.";
};
config = mkIf cfg.enable (mkMerge [
(mkIf (cfg.desktop == "gnome") {
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# TODO: agree on this with randomcat as it affects her too, since for some reason this is system-wide
# environment.gnome.excludePackages = with pkgs.gnome; [
# pkgs.gnome-tour
# epiphany # GNOME Web
# geary
# gnome-calendar
# gnome-contacts
# gnome-music
# ];
})
(mkIf (cfg.desktop == "plasma6") {
services.displayManager.sddm.enable = true;
services.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
})
]);
}

View file

@ -1,20 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qenya.base-graphical;
in
{
config = mkIf cfg.enable {
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
jack.enable = true;
};
hardware.pulseaudio.enable = false; # this theoretically defaults to false but something else seems to be flipping it
environment.systemPackages = with pkgs; [ helvum ]; # patchbay
};
}

View file

@ -1,17 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qenya.base-server;
in
{
options.qenya.base-server.enable = mkEnableOption "Base configuration for headless servers";
config = mkIf cfg.enable {
time.timeZone = "Etc/UTC";
# Allow remote deployment with colmena
deployment.targetUser = null;
security.sudo.wheelNeedsPassword = false;
};
}

View file

@ -1,13 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf;
in
{
boot.loader = {
systemd-boot.enable = true;
systemd-boot.editor = false;
systemd-boot.memtest86.enable = mkIf config.nixpkgs.hostPlatform.isx86 true;
efi.canTouchEfiVariables = true;
};
}

View file

@ -1,18 +0,0 @@
{
imports = [
./base-graphical
./base-server
./users
./boot.nix
./gpg.nix
./home-manager.nix
./misc.nix
./nginx.nix
./nix.nix
./openssh.nix
./packages.nix
./sanoid.nix
./security.nix
./steam.nix
];
}

7
common/fonts.nix Normal file
View file

@ -0,0 +1,7 @@
{ config, lib, pkgs, ... }:
{
fonts.packages = with pkgs; [
corefonts
];
}

View file

@ -1,8 +0,0 @@
{ config, lib, pkgs, ... }:
{
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
}

View file

@ -1,12 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
{
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
backupFileExtension = "backup";
extraSpecialArgs = {
inherit inputs;
};
};
}

View file

@ -1,12 +0,0 @@
{ config, lib, pkgs, ... }:
{
nix.gc = {
automatic = true;
dates = "weekly";
randomizedDelaySec = "45min";
options = "--delete-older-than 30d";
};
nix.optimise.automatic = true;
services.fstrim.enable = true;
}

View file

@ -7,19 +7,23 @@
recommendedProxySettings = true;
recommendedTlsSettings = true;
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
appendHttpConfig = ''
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
add_header Content-Security-Policy "default-src https: data: blob: ws: 'unsafe-inline' 'wasm-unsafe-eval'; object-src 'none'; base-uri 'self';" always;
add_header Referrer-Policy strict-origin-when-cross-origin;
map $scheme $hsts_header {
https "max-age=31536000; includeSubdomains; preload";
}
add_header Strict-Transport-Security $hsts_header;
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
add_header 'Referrer-Policy' 'strict-origin-when-cross-origin';
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-Clacks-Overhead "GNU Terry Pratchett" always;
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
'';
};
security.acme = {
acceptTerms = true;
defaults.email = "auto@qenya.tel";
defaults.email = "accounts@katherina.rocks"; # TODO: replace with more appropriate email
};
}

View file

@ -1,21 +0,0 @@
{ config, lib, pkgs, ... }:
{
nix.settings.experimental-features = "nix-command flakes";
nixpkgs.flake = {
source = lib.cleanSource pkgs.path;
setNixPath = true;
setFlakeRegistry = true;
};
nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];
nixpkgs.config.allowUnfree = true;
nix.settings.trusted-users = [ "@wheel" ];
# this is a dependency of feishin (used in qenya's home-manager). it does not actually have a known vulnerability,
# it's just unsuspported because Electron's support cycle is a ludicrously short 6 months.
# feishin's dev is going to be rewriting it without Electron (as "audioling").
# modern software development was a mistake.
nixpkgs.config.permittedInsecurePackages = [
"electron-31.7.7"
];
}

View file

@ -1,35 +0,0 @@
{ config, pkgs, inputs, ... }:
{
config = {
services.sanoid = {
enable = true;
extraArgs = [ "--verbose" ];
# Local snapshots for important datasets
templates."production" = {
yearly = 0;
monthly = 3;
daily = 30;
hourly = 36;
autosnap = true;
autoprune = true;
};
# Reduced-retention version for datasets that are backed up to the NAS
templates."safe" = {
yearly = 0;
monthly = 0;
daily = 7;
hourly = 24;
autosnap = true;
autoprune = true;
};
# datasets."rpool_sggau1/reese/system" = {
# useTemplate = [ "safe" ];
# recursive = "zfs";
# };
};
};
}

View file

@ -8,4 +8,6 @@
PermitRootLogin = "no";
};
};
services.fail2ban.enable = true;
}

View file

@ -1,12 +1,11 @@
{ config, lib, pkgs, ... }:
{
config = lib.mkIf config.programs.steam.enable {
programs.steam = {
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
};
services.joycond.enable = true;
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
};
}
services.joycond.enable = true;
}

View file

@ -1,33 +1,7 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkOption types genAttrs;
cfg = config.fountain;
in
{
# TODO: consider DRY-ing these
imports = [
./gaelan.nix
./qenya.nix
./randomcat.nix
./trungle.nix
./richard.nix
];
options.fountain = {
admins = mkOption {
type = types.listOf types.str;
default = [ ];
description = "List of users who should have root on this system";
};
};
config = {
users.mutableUsers = false;
users.users = genAttrs cfg.admins
(name: {
extraGroups = [ "wheel" ];
}
);
};
}
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkEnableOption;
keys = import ../../keys.nix;
cfg = config.fountain.users.gaelan;
in
{
options.fountain.users.gaelan = {
enable = mkEnableOption "user gaelan";
};
config = mkIf cfg.enable {
users.users.gaelan = {
uid = 1003;
isNormalUser = true;
group = "gaelan";
openssh.authorizedKeys.keys = keys.users.gaelan;
};
users.groups.gaelan.gid = config.users.users.gaelan.uid;
};
}

View file

@ -1,28 +1,29 @@
{ config, lib, pkgs, self, ... }:
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkEnableOption;
keys = import ../../keys.nix;
cfg = config.fountain.users.qenya;
let keys = import ../../keys.nix;
in
{
options.fountain.users.qenya = {
enable = mkEnableOption "user qenya";
users.users.qenya = {
isNormalUser = true;
home = "/home/qenya";
extraGroups = [
"wheel" # sudo
"networkmanager" # UI wifi configuration
"dialout" # access to serial ports
];
openssh.authorizedKeys.keys = keys.users.qenya;
uid = 1001;
};
config = mkIf cfg.enable {
users.users.qenya = {
uid = 1001;
isNormalUser = true;
group = "qenya";
shell = pkgs.zsh;
openssh.authorizedKeys.keys = keys.users.qenya;
home-manager.users.qenya = { config, lib, pkgs, osConfig, ... }: {
home.homeDirectory = osConfig.users.users.qenya.home;
programs.git = {
enable = true;
userName = "Katherina Walshe-Grey";
userEmail = "git@qenya.tel";
};
users.groups.qenya.gid = config.users.users.qenya.uid;
programs.zsh.enable = true;
home-manager.users."qenya" = self.homeManagerModules."qenya";
home.stateVersion = "23.11";
};
}

View file

@ -1,23 +1,12 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkEnableOption;
keys = import ../../keys.nix;
cfg = config.fountain.users.randomcat;
let keys = import ../../keys.nix;
in
{
options.fountain.users.randomcat = {
enable = mkEnableOption "user randomcat";
users.users.randomcat = {
isNormalUser = true;
home = "/home/randomcat";
openssh.authorizedKeys.keys = keys.users.randomcat;
uid = 1003;
};
config = mkIf cfg.enable {
users.users.randomcat = {
uid = 1000;
isNormalUser = true;
group = "randomcat";
openssh.authorizedKeys.keys = keys.users.randomcat;
};
users.groups.randomcat.gid = config.users.users.randomcat.uid;
};
}
}

12
common/users/richard.nix Normal file
View file

@ -0,0 +1,12 @@
{ config, lib, pkgs, ... }:
let keys = import ../../keys.nix;
in
{
users.users.richard = {
isNormalUser = true;
home = "/home/richard";
openssh.authorizedKeys.keys = keys.users.richard;
uid = 1002;
};
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkEnableOption;
keys = import ../../keys.nix;
cfg = config.fountain.users.trungle;
in
{
options.fountain.users.trungle = {
enable = mkEnableOption "user trungle";
};
config = mkIf cfg.enable {
users.users.trungle = {
uid = 1002;
isNormalUser = true;
group = "trungle";
openssh.authorizedKeys.keys = keys.users.trungle;
};
users.groups.trungle.gid = config.users.users.trungle.uid;
};
}

View file

@ -1,22 +1,13 @@
{ config, lib, pkgs, ... }:
{
# CLI utilities I get frustrated if I'm missing
environment.systemPackages = with pkgs; [
btop
git
wget
# hardware troubleshooting
inetutils
lshw
parted
smartmontools
# network troubleshooting
inetutils
lsof
tcpdump
netcat # <3
wireguard-tools
wget
];
environment.wordlist.enable = true;

View file

@ -1,444 +0,0 @@
{
"nodes": {
"actual": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1738814288,
"narHash": "sha256-4WqR/ligsEvxcFOjui1dwquR8U327uGoBjdI5p0ey4A=",
"ref": "main",
"rev": "f64adb78f15981d60af97e7aa691d2ebdf48ceaa",
"revCount": 21,
"type": "git",
"url": "https://git.xeno.science/xenofem/actual-nix"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.xeno.science/xenofem/actual-nix"
}
},
"agenix": {
"inputs": {
"darwin": [],
"home-manager": [],
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1736955230,
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
"owner": "ryantm",
"repo": "agenix",
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"birdsong": {
"locked": {
"lastModified": 1738782723,
"narHash": "sha256-tQ8DZrB9pucCl0qOEzvqRBrrYS0f72Sxhf+jYJQV1eE=",
"ref": "main",
"rev": "a40220a4b977bc04cbe9e13ff5c667ed6f252677",
"revCount": 22,
"type": "git",
"url": "https://git.qenya.tel/qenya/birdsong"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.qenya.tel/qenya/birdsong"
}
},
"colmena": {
"inputs": {
"flake-compat": [],
"flake-utils": "flake-utils",
"nix-github-actions": [],
"nixpkgs": [
"nixpkgs"
],
"stable": []
},
"locked": {
"lastModified": 1739900653,
"narHash": "sha256-hPSLvw6AZQYrZyGI6Uq4XgST7benF/0zcCpugn/P0yM=",
"owner": "zhaofengli",
"repo": "colmena",
"rev": "2370d4336eda2a9ef29fce10fa7076ae011983ab",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "colmena",
"type": "github"
}
},
"firefox-addons": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1744010161,
"narHash": "sha256-6PNBLb/YXVlx2YaDqtljQYpk2MlE0VRjGXcEg1RN/qw=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "60f50437003e17137a871686dfa3fc4291edd5e5",
"type": "gitlab"
},
"original": {
"dir": "pkgs/firefox-addons",
"owner": "rycee",
"ref": "master",
"repo": "nur-expressions",
"type": "gitlab"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flakey-profile": {
"locked": {
"lastModified": 1712898590,
"narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
"owner": "lf-",
"repo": "flakey-profile",
"rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
"type": "github"
},
"original": {
"owner": "lf-",
"repo": "flakey-profile",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1743808813,
"narHash": "sha256-2lDQBOmlz9ggPxcS7/GvcVdzXMIiT+PpMao6FbLJSr0=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "a9f8b3db211b4609ddd83683f9db89796c7f6ac6",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.11",
"repo": "home-manager",
"type": "github"
}
},
"home-manager-unstable": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1744008831,
"narHash": "sha256-g3mHJLB8ShKuMaBBZxiGuoftJ22f7Boegiw5xBUnS8E=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "f463902a3f03e15af658e48bcc60b39188ddf734",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"lix": {
"flake": false,
"locked": {
"lastModified": 1737234286,
"narHash": "sha256-pgDJZjj4jpzkFxsqBTI/9Yb0n3gW+DvDtuv9SwQZZcs=",
"rev": "079528098f5998ba13c88821a2eca1005c1695de",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/079528098f5998ba13c88821a2eca1005c1695de.tar.gz?rev=079528098f5998ba13c88821a2eca1005c1695de"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/lix/archive/release-2.92.tar.gz"
}
},
"lix-module": {
"inputs": {
"flake-utils": "flake-utils_2",
"flakey-profile": "flakey-profile",
"lix": "lix",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1742943028,
"narHash": "sha256-fprwZKE1uMzO9tiWWOrmLWBW3GPkMayQfb0xOvVFIno=",
"rev": "868d97695bab9d21f6070b03957bcace249fbe3c",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/868d97695bab9d21f6070b03957bcace249fbe3c.tar.gz?rev=868d97695bab9d21f6070b03957bcace249fbe3c"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1743813633,
"narHash": "sha256-BgkBz4NpV6Kg8XF7cmHDHRVGZYnKbvG0Y4p+jElwxaM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "7819a0d29d1dd2bc331bec4b327f0776359b1fa6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1743296961,
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-small": {
"locked": {
"lastModified": 1743891346,
"narHash": "sha256-QNxnxIi6PJEnwJp7ZXUpxX4/z/cmRJGeIOkIYfYh/8E=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f27c6099cec4fe9b67c7fbc51d8324dcb4b52694",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1743827369,
"narHash": "sha256-rpqepOZ8Eo1zg+KJeWoq1HAOgoMCDloqv5r2EAa9TSA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "42a1c966be226125b48c384171c44c651c236c22",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable-small": {
"locked": {
"lastModified": 1743948488,
"narHash": "sha256-uKcMmNPvGPb58MhAFru/CMDYl69nZRK3A3SLch9ejgA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "da98c5d529f118c82e80a3f9b4fb01fdeba3cf7a",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager-unstable"
],
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1742765550,
"narHash": "sha256-2vVIh2JrL6GAGfgCeY9e6iNKrBjs0Hw3bGQEAbwVs68=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "b70be387276e632fe51232887f9e04e2b6ef8c16",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
}
},
"randomcat": {
"flake": false,
"locked": {
"lastModified": 1744004743,
"narHash": "sha256-MIWwT/A4IfXmmSMCU3lVVnFJNmkXpYxcK+Fishja6XY=",
"owner": "randomnetcat",
"repo": "nix-configs",
"rev": "335ef83e439cfcb4781d5a8f54f606afb63e9f48",
"type": "github"
},
"original": {
"owner": "randomnetcat",
"repo": "nix-configs",
"type": "github"
}
},
"root": {
"inputs": {
"actual": "actual",
"agenix": "agenix",
"birdsong": "birdsong",
"colmena": "colmena",
"firefox-addons": "firefox-addons",
"flake-parts": "flake-parts",
"home-manager": "home-manager",
"home-manager-unstable": "home-manager-unstable",
"lix-module": "lix-module",
"nixpkgs": "nixpkgs",
"nixpkgs-small": "nixpkgs-small",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixpkgs-unstable-small": "nixpkgs-unstable-small",
"plasma-manager": "plasma-manager",
"randomcat": "randomcat",
"scoutshonour": "scoutshonour"
}
},
"scoutshonour": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1735301893,
"narHash": "sha256-d95MCTUYMCcOQv4LpmWxPuVnx7McezXYs2Idw8u8ngI=",
"ref": "main",
"rev": "f447cd380ea1fb81a0ff8f292b6bbdf0be9c9520",
"revCount": 23,
"type": "git",
"url": "https://git.qenya.tel/qenya/nix-scoutshonour"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.qenya.tel/qenya/nix-scoutshonour"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

178
flake.nix
View file

@ -1,178 +0,0 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
nixpkgs-small.url = "github:NixOS/nixpkgs/nixos-24.11-small";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-unstable-small.url = "github:NixOS/nixpkgs/nixos-unstable-small";
lix-module = {
# lix haven't figured out automatic updates yet: https://git.lix.systems/lix-project/nixos-module/issues/39
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager/release-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
inputs.home-manager.follows = "home-manager-unstable";
};
flake-parts.url = "github:hercules-ci/flake-parts";
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.darwin.follows = "";
inputs.home-manager.follows = "";
};
colmena = {
url = "github:zhaofengli/colmena";
inputs.nixpkgs.follows = "nixpkgs";
inputs.stable.follows = "";
inputs.nix-github-actions.follows = "";
inputs.flake-compat.follows = "";
};
randomcat = {
url = "github:randomnetcat/nix-configs";
flake = false;
};
firefox-addons = {
url = "gitlab:rycee/nur-expressions?ref=master&dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
# Third-party flake providing package and NixOS module for Actual Budget as
# nixpkgs are having trouble: https://github.com/NixOS/nixpkgs/issues/269069
actual = {
url = "git+https://git.xeno.science/xenofem/actual-nix?ref=main";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
birdsong.url = "git+https://git.qenya.tel/qenya/birdsong?ref=main";
scoutshonour = {
url = "git+https://git.qenya.tel/qenya/nix-scoutshonour?ref=main";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
};
outputs = inputs@{ self, nixpkgs, nixpkgs-small, nixpkgs-unstable, flake-parts, colmena, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ ./flake ];
systems = [ "x86_64-linux" "aarch64-linux" ];
perSystem = { pkgs, system, ... }: {
devShells.default = pkgs.mkShell {
packages = [
inputs.colmena.packages.${system}.colmena
inputs.agenix.packages.${system}.default
inputs.plasma-manager.packages.${system}.rc2nix
];
};
};
flake.nixosConfigurations = self.outputs.colmenaHive.nodes;
flake.colmenaHive = colmena.lib.makeHive self.outputs.colmena;
# The name of this output type is not standardised. I have picked
# "homeManagerModules" as the discussion here suggests it's the most common:
# https://github.com/nix-community/home-manager/issues/1783
#
# However, note CppNix >= 2.22.3, >= 2.24 has blessed "homeModules":
# https://github.com/NixOS/nix/pull/10858
flake.homeManagerModules = {
"qenya".imports = [
inputs.plasma-manager.homeManagerModules.plasma-manager
./home/qenya
];
"qenya@shaw".imports = [ ./hosts/shaw/home.nix ];
};
fountain.backup = {
keys = {
elucredassa = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFa3hjej6KGmS2aQ4s46Y7U8pN4yyR2FuMofpHRwXNk syncoid@elucredassa" ];
};
sync = {
"orm-state" = {
dataset = "state";
sourceHost = "orm";
targetHost = "elucredassa";
source = "rpool_orm";
target = "rpool_elucredassa/backup/orm";
};
"kalessin-state" = {
dataset = "state";
sourceHost = "kalessin";
targetHost = "elucredassa";
source = "rpool_kalessin";
target = "rpool_elucredassa/backup/kalessin";
};
};
};
flake.colmena = {
meta = {
nixpkgs = import nixpkgs-unstable {
system = "x86_64-linux";
overlays = [
inputs.lix-module.overlays.default
];
};
nodeNixpkgs = {
kilgharrah = import nixpkgs { system = "x86_64-linux"; };
tohru = import nixpkgs { system = "x86_64-linux"; };
elucredassa = import nixpkgs-small { system = "x86_64-linux"; };
yevaud = import nixpkgs-small { system = "x86_64-linux"; };
orm = import nixpkgs-small { system = "x86_64-linux"; };
kalessin = import nixpkgs-small { system = "aarch64-linux"; };
};
specialArgs = {
inherit self;
inherit inputs;
};
};
defaults = { config, lib, pkgs, ... }: {
deployment.targetHost = lib.mkDefault config.networking.fqdn;
deployment.buildOnTarget = lib.mkDefault true;
imports = [
inputs.lix-module.nixosModules.default
inputs.home-manager.nixosModules.home-manager
inputs.agenix.nixosModules.default
inputs.birdsong.nixosModules.default
inputs.actual.nixosModules.default
./common
./services
(builtins.toPath "${inputs.randomcat}/services/default.nix")
];
};
kilgharrah.deployment.targetHost = null; # disable remote deployment
tohru.deployment.targetHost = null; # disable remote deployment
elucredassa.deployment.targetHost = "10.127.3.2"; # no fqdn yet
kilgharrah.imports = [ ./hosts/kilgharrah ];
tohru.imports = [ ./hosts/tohru ];
elucredassa.imports = [ ./hosts/elucredassa ];
yevaud.imports = [ ./hosts/yevaud ];
orm.imports = [ ./hosts/orm ];
kalessin.imports = [ ./hosts/kalessin ];
};
};
}

View file

@ -1,138 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.fountain.backup;
keys = import ../keys.nix;
syncOptions = {
dataset = lib.mkOption {
type = lib.types.str;
description = ''
The name of the dataset to be synced (not including its parent
datasets, if any). This will be the same on the source and target.
It must already exist on the source, defined with the
{option}`randomcat.services.zfs` module, and not exist on the target.
'';
};
sourceHost = lib.mkOption {
type = lib.types.str;
description = ''
The host from which the dataset should be synced. Must be an entry in
{option}`flake.colmena`.
'';
};
targetHost = lib.mkOption {
type = lib.types.str;
description = ''
The host to which the dataset should be synced. Must be an entry in
{option}`flake.colmena`.
'';
};
source = lib.mkOption {
type = lib.types.str;
description = ''
The path to the synced dataset in the ZFS namespace on the source host,
excluding the component that is the name of the dataset itself.
'';
};
target = lib.mkOption {
type = lib.types.str;
description = ''
The path to the synced dataset in the ZFS namespace on the target host,
excluding the component that is the name of the dataset itself. It must
already exist, defined with the {option}`randomcat.services.zfs`
module.
'';
};
};
in
{
options.fountain.backup = {
keys = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.singleLineStr);
default = { };
description = ''
Lists of verbatim OpenSSH public keys that may be used to identify the
syncoid user on each target host. The key to each list must be the
host's hostname, as listed in {option}`flake.colmena`.
'';
example = {
host = [ "ssh-rsa AAAAB3NzaC1yc2etc/etc/etcjwrsh8e596z6J0l7 example@host" ];
bar = [ "ssh-ed25519 AAAAC3NzaCetcetera/etceteraJZMfk3QPfQ foo@bar" ];
};
};
sync = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule { options = syncOptions; });
default = { };
description = ''
Details of ZFS datasets whose snapshots should be synced from machine
to machine using syncoid. Syncoid will run hourly at 15 past the hour
and copy all ZFS snapshots from the source dataset to the target
dataset (recursing into child datasets).
See descriptions for the individual options for more details. The name
of each attribute in this set is arbitrary and used to generate systemd
unit names.
This module does not actually cause snapshots to be taken; sanoid must
be configured separately to do this.
'';
example = {
"orm-state" = {
dataset = "state";
sourceHost = "orm";
targetHost = "elucredassa";
source = "rpool_orm";
target = "rpool_elucredassa/backup/orm";
};
};
};
};
# TODO: add some assertions to verify the options
config.flake.colmena = lib.mkMerge (lib.mapAttrsToList
(name: sync:
let
inherit (sync) dataset sourceHost targetHost source target;
# TODO: don't want to have to dig into the node config for the fqdn
sourceFqdn = config.flake.nixosConfigurations.${sourceHost}.config.networking.fqdn;
in
{
${sourceHost} = { pkgs, ... }: {
randomcat.services.zfs.datasets."${source}/${dataset}".zfsPermissions.users.backup = [ "hold" "send" ];
users.users.backup = {
group = "backup";
isSystemUser = true;
useDefaultShell = true;
openssh.authorizedKeys.keys = cfg.keys.${targetHost};
packages = with pkgs; [ mbuffer lzop ]; # syncoid uses these if available but doesn't pull them in automatically
};
users.groups.backup = { };
};
${targetHost} = {
randomcat.services.zfs.datasets.${target}.zfsPermissions.users.syncoid = [ "mount" "create" "receive" "recordsize" ];
services.syncoid = {
enable = true;
interval = "*-*-* *:15:00";
commonArgs = [ "--no-sync-snap" ];
commands = {
${name} = {
source = "backup@${sourceFqdn}:${source}/${dataset}";
target = "${target}/${dataset}";
recursive = true;
recvOptions = "ux recordsize o compression=lz4";
};
};
};
# TODO: this should be handled by a networking module
programs.ssh.knownHosts.${sourceFqdn}.publicKey = keys.machines.${sourceHost};
};
})
cfg.sync
);
}

View file

@ -1,19 +0,0 @@
# https://git.lix.systems/the-distro/infra/src/commit/fbb23bf517206175764f154ddfd304b9ec501f87/colmena.nix
{ lib, ... }: {
options.flake.colmena = lib.mkOption {
type = lib.types.submodule {
freeformType = lib.types.attrsOf (lib.mkOptionType {
name = "NixOS module";
description = "module containing NixOS options and/or config";
descriptionClass = "noun";
check = value: builtins.isAttrs value || builtins.isFunction value || builtins.isPath value;
merge = loc: defs: {
imports = map (def: def.value) defs;
};
});
options.meta = lib.mkOption {
type = lib.types.attrs;
};
};
};
}

View file

@ -1,6 +0,0 @@
{
imports = [
./backup.nix
./colmena.nix
];
}

67
hive.nix Normal file
View file

@ -0,0 +1,67 @@
let sources = import ./npins;
in {
meta.nixpkgs = sources.nixpkgs;
defaults = { name, nodes, ... }: {
deployment.replaceUnknownProfiles = false;
networking.hostName = name;
nixpkgs.config = {
allowUnfree = true;
packageOverrides = pkgs: {
agenix = (import sources.agenix { inherit pkgs; }).agenix;
nur = (import sources.nur { inherit pkgs; });
vscode-extensions = (import sources.nix-vscode-extensions).extensions.x86_64-linux; # TODO: This should check the host architecture
};
};
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
};
imports = [
(import "${sources.home-manager}/nixos")
(import "${sources.agenix}/modules/age.nix")
# TODO: npins requires manual intervention to upgrade lix and lix-module (add the tarball URL to sources.json)
# See: https://github.com/andir/npins/issues/47
(import "${sources.lix-module}/module.nix" { lix = sources.lix; })
./pinning.nix
./common/nginx.nix
./common/ssh.nix
./common/sudo.nix
./common/utilities.nix
./common/users
];
};
tohru = { name, nodes, ... }: {
networking.hostId = "31da19c1";
time.timeZone = "Europe/London";
imports = [
./colmena/local.nix
./hosts/tohru/configuration.nix
];
};
yevaud = { name, nodes, ... }: {
networking.hostId = "09673d65";
time.timeZone = "Etc/UTC";
imports = [
./colmena/remote.nix
./hosts/yevaud/configuration.nix
];
};
orm = { name, nodes, ... }: {
networking.hostId = "00000000";
time.timeZone = "Etc/UTC";
imports = [
./colmena/remote.nix
./hosts/orm/configuration.nix
];
};
}

14
home/cli.nix Normal file
View file

@ -0,0 +1,14 @@
{ config, lib, pkgs, ... }:
{
home.packages = with pkgs; [
tree # like `ls -R` but nicer
# Extremely important
fortune
cowsay
lolcat
];
programs.btop.enable = true;
}

6
home/firefox.nix Normal file
View file

@ -0,0 +1,6 @@
{ config, lib, pkgs, ... }:
{
# TODO: nix-ify Firefox config
programs.firefox.enable = true;
}

12
home/git.nix Normal file
View file

@ -0,0 +1,12 @@
{ config, lib, pkgs, ... }:
{
programs.git = {
enable = true;
extraConfig = {
init = {
defaultBranch = "main";
};
};
};
}

25
home/gnome/appearance.nix Normal file
View file

@ -0,0 +1,25 @@
{ config, lib, pkgs, ... }:
{
dconf = {
enable = true;
settings =
let
backgroundOptions = {
color-shading-type = "solid";
picture-options = "zoom";
picture-uri = "${config.home.homeDirectory}/.background-image";
primary-color = "#3a4ba0";
secondary-color = "#2f302f";
};
in
{
"org/gnome/desktop/background" = backgroundOptions // {
picture-uri-dark = backgroundOptions.picture-uri;
};
"org/gnome/desktop/screensaver" = backgroundOptions;
"org/gnome/desktop/interface".color-scheme = "prefer-dark";
};
};
home.file.".background-image".source = ./background-image.jpg;
}

View file

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

9
home/gnome/default.nix Normal file
View file

@ -0,0 +1,9 @@
{ config, lib, pkgs, ... }:
{
imports = [
# TODO: nix-ify other parts of GNOME config
./appearance.nix
./keyboard.nix
];
}

15
home/gnome/keyboard.nix Normal file
View file

@ -0,0 +1,15 @@
# { config, lib, pkgs, ... }:
{
dconf = {
enable = true;
settings = {
"org/gnome/desktop/wm/keybindings" = {
# These are largely useless on most normal systems
# and conflict with VS Code's default keybinds for "Copy Line Up/Down"
move-to-workspace-up = [ ];
move-to-workspace-down = [ ];
};
};
};
}

9
home/libreoffice.nix Normal file
View file

@ -0,0 +1,9 @@
{ config, lib, pkgs, ... }:
{
home.packages = with pkgs; [
libreoffice
hunspell
hunspellDicts.en_GB-ise
];
}

View file

@ -1,24 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
# dconf is the configuration manager for GNOME.
let
isGnome = osConfig.services.xserver.desktopManager.gnome.enable;
in
{
dconf.enable = isGnome;
dconf.settings = {
"org/gnome/settings-daemon/plugins/color".night-light-enabled = true;
"org/gnome/desktop/sound".event-sounds = false;
"org/gnome/desktop/sound".allow-volume-above-100-percent = true;
};
imports = [
./desktop.nix
./keyboard.nix
./mouse-touchpad.nix
./multitasking.nix
./shell.nix
];
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
let inherit (lib) mkIf;
in {
dconf.settings = {
"org/gnome/desktop/background" = {
picture-options = "zoom";
picture-uri = "${config.home.homeDirectory}/.background-image";
picture-uri-dark = "${config.home.homeDirectory}/.background-image";
};
"org/gnome/desktop/screensaver" = {
picture-options = "zoom";
picture-uri = "${config.home.homeDirectory}/.background-image";
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false;
};
};
home.file.".background-image" = mkIf config.dconf.enable {
source = ./background-image.jpg;
};
}

View file

@ -1,12 +0,0 @@
# { config, lib, pkgs, ... }:
{
dconf.settings = {
"org/gnome/desktop/wm/keybindings" = {
# These are largely useless on most normal systems
# and conflict with VS Code's default keybinds for "Copy Line Up/Down"
move-to-workspace-up = [ ];
move-to-workspace-down = [ ];
};
};
}

View file

@ -1,16 +0,0 @@
{ config, lib, pkgs, ... }:
{
dconf.settings = {
"org/gnome/desktop/peripherals/mouse" = {
natural-scroll = false;
};
"org/gnome/desktop/peripherals/touchpad" = {
click-method = "fingers";
disable-while-typing = false;
natural-scroll = true; # the correct option, whatever Janet says
tap-to-click = true;
two-finger-scrolling-enabled = true;
};
};
}

View file

@ -1,11 +0,0 @@
{ config, lib, pkgs, ... }:
{
dconf.settings = {
"org/gnome/mutter" = {
edge-tiling = true;
dynamic-workspaces = true;
workspaces-only-on-primary = true;
};
};
}

View file

@ -1,26 +0,0 @@
{ config, lib, pkgs, ... }:
{
dconf.settings = {
"org/gnome/shell" = {
disable-user-extensions = true;
# TODO: this is fine for now on tohru (the only GNOME system I use) but shouldn't depend on certain apps being installed
favorite-apps = [
"discord.desktop"
"org.gnome.Evolution.desktop"
"firefox.desktop"
"torbrowser.desktop"
"steam.desktop"
"codium.desktop"
"org.gnome.Console.desktop"
"org.gnome.Nautilus.desktop"
"org.gnome.SystemMonitor.desktop"
];
# TODO: fill this out (needs preinstalled stuff removing first)
# app-picker-layout = [
# ...
# ];
};
};
}

View file

@ -1,15 +0,0 @@
{
imports = [
./dconf
./plasma
./firefox.nix
./git.nix
./packages.nix
./tmux.nix
./vscode.nix
./xdg-mime-apps.nix
./zsh.nix
];
home.stateVersion = "23.11";
}

View file

@ -1,59 +0,0 @@
{ config, lib, pkgs, osConfig, inputs, ... }:
let
inherit (lib) mkIf;
isGraphical = osConfig.services.xserver.enable;
in
{
programs.firefox = lib.mkIf isGraphical {
enable = true;
languagePacks = [ "en-GB" ];
profiles.default = {
extensions = with inputs.firefox-addons.packages.${pkgs.hostPlatform.system}; [
bitwarden
ublock-origin
];
settings = {
"browser.startup.page" = 3; # resume previous session
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
# disable telemetry
"datareporting.healthreport.uploadEnabled" = false;
"app.shield.optoutstudies.enabled" = false;
"browser.crashReports.unsubmittedCheck.autoSubmit2" = false;
# disable prefetch?
# DNS over HTTPS
"network.trr.custom_uri" = "https://base.dns.mullvad.net/dns-query";
"network.trr.excluded-domains" = "detectportal.firefox.com";
"network.trr.mode" = 3;
"network.trr.uri" = "https://base.dns.mullvad.net/dns-query";
"browser.search.suggest.enabled" = false;
"browser.urlbar.suggest.searches" = false;
"dom.security.https_only_mode" = true;
"browser.contentblocking.category" = "strict"; # Enhanced Tracking Protection
# I think these are implied by the above
# "privacy.donottrackheader.enabled" = true;
# "privacy.trackingprotection.enabled" = true;
# "privacy.trackingprotection.emailtracking.enabled" = true;
# "privacy.trackingprotection.socialtracking.enabled" = true;
"privacy.sanitize.sanitizeOnShutdown" = true;
"privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = false;
"dom.private-attribution.submission.enabled" = false; # disable "Privacy-Preserving Attribution for Advertising"
"extensions.autoDisableScopes" = 0; # automatically enable extensions installed through nix
# external password manager
"signon.rememberSignons" = false;
"extensions.formautofill.creditCards.enabled" = false;
};
};
};
}

View file

@ -1,14 +0,0 @@
{ config, lib, pkgs, ... }:
{
programs.git = {
enable = true;
userName = "Katherina Walshe-Grey";
userEmail = "git@qenya.tel";
extraConfig = {
init.defaultBranch = "main";
pull.rebase = true;
push.autoSetupRemote = true;
};
};
}

View file

@ -1,34 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
inherit (lib) optionals;
isGraphical = osConfig.services.xserver.enable;
in
{
home.packages = with pkgs; [
eza # like `ls` but fancier
hexyl # like `xxd` but cooler
tree # like `ls -R` but nicer
units
zip
unzip
# Extremely important
fortune
cowsay
lolcat
] ++ optionals isGraphical [
bitwarden
discord
feishin
gimp-with-plugins
jellyfin-media-player
tor-browser-bundle-bin
zoom-us
# libreoffice
libreoffice
hunspell
hunspellDicts.en_GB-ise
];
}

View file

@ -1,11 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
isPlasma = osConfig.services.desktopManager.plasma6.enable || osConfig.services.xserver.desktopManager.plasma5.enable;
in
{
programs.plasma.enable = isPlasma;
programs.plasma.overrideConfig = true;
imports = [ ];
}

View file

@ -1,83 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
inherit (lib) mkIf mkDefault;
isGraphical = osConfig.services.xserver.enable;
in
{
programs.vscode = mkIf isGraphical {
enable = true;
enableExtensionUpdateCheck = false;
enableUpdateCheck = false;
package = pkgs.vscodium;
extensions = with pkgs.vscode-extensions; [
charliermarsh.ruff
dbaeumer.vscode-eslint
eamodio.gitlens
golang.go
jdinhlife.gruvbox
jnoortheen.nix-ide
matangover.mypy
mkhl.direnv
ms-python.black-formatter
ms-python.python
rust-lang.rust-analyzer
vadimcn.vscode-lldb
];
mutableExtensionsDir = false;
userSettings = {
"css.format.spaceAroundSelectorSeparator" = true;
"css.format.newlineBetweenSelectors" = false;
"debug.allowBreakpointsEverywhere" = true;
"extensions.autoUpdate" = false;
"files.insertFinalNewline" = true;
"git.autofetch" = true;
"git.confirmSync" = false;
"git.enableSmartCommit" = true;
"git.inputValidation" = true;
"git.inputValidationSubjectLength" = null;
"javascript.updateImportsOnFileMove.enabled" = "always";
"nix.enableLanguageServer" = true;
"nix.serverPath" = "${pkgs.nil}/bin/nil";
"nix.serverSettings".nil = {
diagnostics.ignored = [ "unused_binding" "unused_with" ];
formatting.command = [ "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt" ];
nix.flake.autoArchive = true;
};
"rust-analyzer.check.command" = "clippy";
"terminal.integrated.allowChords" = false;
"terminal.integrated.defaultProfile.linux" = "zsh";
"workbench.colorTheme" = "Gruvbox Dark Medium";
"[go]" = {
"editor.defaultFormatter" = "golang.go";
"editor.formatOnSave" = false;
};
"go.alternateTools" = {
"go" = "${pkgs.go}/bin/go";
"golangci-lint" = "${pkgs.golangci-lint}/bin/golangci-lint";
"gopls" = "${pkgs.gopls}/bin/gopls";
"dlv" = "${pkgs.delve}/bin/dlv";
"staticcheck" = "${pkgs.go-tools}/bin/staticcheck";
};
"go.lintTool" = "golangci-lint";
"go.toolsManagement.checkForUpdates" = "off";
"gopls" = {
"formatting.gofumpt" = true;
"ui.semanticTokens" = true;
};
"[python]" = {
"editor.defaultFormatter" = "ms-python.black-formatter";
"editor.formatOnSave" = true;
"editor.codeActionsOnSave" = {
"source.fixAll" = "explicit";
"source.organizeImports" = "explicit";
};
};
"ruff.nativeServer" = "on";
"ruff.path" = "${pkgs.ruff}/bin/ruff";
"mypy.dmypyExecutable" = "${pkgs.mypy}/bin/dmypy";
};
};
}

View file

@ -1,21 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
isGraphical = osConfig.services.xserver.enable;
in
{
xdg.mimeApps = {
enable = isGraphical;
defaultApplications = {
"application/pdf" = [ "org.gnome.Evince.desktop" "org.kde.okular.desktop" ];
"application/zip" = [ "org.gnome.FileRoller.desktop" "org.kde.ark.desktop" ];
"image/gif" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
"image/jpeg" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
"image/png" = [ "org.gnome.Loupe.desktop" "org.kde.gwenview.desktop" ];
"text/plain" = [ "org.gnome.TextEditor.desktop" "org.kde.kate.desktop" ];
"x-scheme-handler/http" = "firefox.desktop";
"x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/mailto" = "org.gnome.Evolution.desktop"; # TODO: email on KDE - is Kontact any good?
};
};
}

View file

@ -1,38 +0,0 @@
{ config, lib, pkgs, ... }:
{
home.packages = with pkgs; [ direnv ];
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
dotDir = ".config/zsh";
shellAliases = {
ll = "ls -l";
# don't clobber
mv = "mv -i";
rename = "rename -i";
nix-shell = ''nix-shell --command "zsh"''; # TODO: tweak theme to display something when inside nix-shell
};
history = {
size = 10000;
path = "${config.xdg.dataHome}/zsh/history";
ignorePatterns = [ "rm *" "pkill *" ];
};
oh-my-zsh = {
enable = true;
plugins = [ "git" "sudo" "direnv" ];
theme = "agnoster";
};
envExtra = ''
DEFAULT_USER=qenya
'';
};
}

39
home/vscode.nix Normal file
View file

@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
{
programs.vscode = {
enable = true;
enableExtensionUpdateCheck = false;
enableUpdateCheck = false;
package = pkgs.vscodium;
extensions = with pkgs.vscode-extensions; [
open-vsx.jnoortheen.nix-ide
open-vsx.ms-python.python
open-vsx.robbowen.synthwave-vscode
];
mutableExtensionsDir = false;
userSettings = {
"extensions.autoUpdate" = false;
"git.autofetch" = true;
"git.confirmSync" = false;
"git.enableSmartCommit" = true;
"git.inputValidation" = true;
"git.inputValidationSubjectLength" = null;
"javascript.updateImportsOnFileMove.enabled" = "always";
"nix.enableLanguageServer" = true;
"nix.serverPath" = "nil";
"nix.serverSettings".nil = {
diagnostics.ignored = [ "unused_binding" "unused_with" ];
formatting.command = [ "nixpkgs-fmt" ];
};
"terminal.integrated.allowChords" = false;
"workbench.colorTheme" = "SynthWave '84";
};
};
# Language servers etc
home.packages = with pkgs; [
nil
nixpkgs-fmt
];
}

View file

@ -1,43 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
let
inherit (lib) mkForce;
in
{
imports = [
./filesystems.nix
./hardware.nix
./networking.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking.hostName = "elucredassa";
networking.hostId = "a8ec6755";
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "rtsx_pci_sdmmc" ];
boot.kernelModules = [ "kvm-intel" ];
qenya.base-server.enable = true;
i18n.defaultLocale = "en_GB.UTF-8";
console.keyMap = "uk";
services.xserver.xkb.layout = "gb";
# These are populated by fountain.backup
randomcat.services.zfs.datasets = {
"rpool_elucredassa/backup" = { mountpoint = "none"; };
"rpool_elucredassa/backup/kalessin" = { mountpoint = "none"; };
"rpool_elucredassa/backup/orm" = { mountpoint = "none"; };
};
qenya.services.distributed-builds = {
enable = true;
keyFile = "/etc/ssh/ssh_host_ed25519_key";
builders = [ "kilgharrah" ];
};
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
system.stateVersion = "24.11";
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
{
boot.initrd.luks.devices = {
"luks-rpool-elucredassa".device = "/dev/disk/by-uuid/5ece5b58-c57a-41ae-b086-03707c39c9a7";
};
fileSystems = {
"/" = {
device = "rpool_elucredassa/root";
fsType = "zfs";
};
"/boot" = {
device = "/dev/disk/by-uuid/2519-E2D6";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
};
swapDevices = [{ device = "/dev/disk/by-uuid/c7c48325-e90d-414d-b579-84cb45616ee9"; }];
boot.supportedFilesystems = [ "ntfs" ]; # for USB drives
}

View file

@ -1,11 +0,0 @@
{ config, lib, pkgs, ... }:
{
hardware.enableAllFirmware = true;
hardware.cpu.intel.updateMicrocode = true;
services.fwupd.enable = true;
# this is an old laptop
services.logind.lidSwitch = "ignore";
}

View file

@ -1,48 +0,0 @@
{ config, lib, pkgs, ... }:
{
systemd.network.enable = true;
networking.useDHCP = false;
systemd.network.networks."10-wan" = {
matchConfig.Name = "enp1s0f1";
networkConfig = {
DHCP = "ipv4";
IPv6AcceptRA = true;
Tunnel = "sit-he-ipv6";
};
linkConfig.RequiredForOnline = "routable";
};
systemd.network.netdevs."25-he-ipv6" = {
netdevConfig = {
Name = "sit-he-ipv6";
Kind = "sit";
Description = "Hurricane Electric IPv6 Tunnel";
MTUBytes = 1480;
};
tunnelConfig = {
Remote = "216.66.88.98";
TTL = 255;
};
};
systemd.network.networks."25-he-ipv6" = {
matchConfig.Name = "sit-he-ipv6";
networkConfig.Address = [ "2001:470:1f1c:3e::2/64" ];
routes = [{ Destination = [ "::/0" ]; }];
};
birdsong.peering = {
enable = true;
privateKeyFile = "/etc/wireguard/privatekey";
persistentKeepalive = 29;
};
# restricted to fit within the 6in4 tunnel
systemd.network.netdevs."30-birdsong".netdevConfig.MTUBytes = 1280;
# these two lines work around this bug: https://github.com/NixOS/nixpkgs/issues/375960
systemd.network.netdevs."30-birdsong".netdevConfig.Kind = "wireguard";
systemd.network.netdevs."30-birdsong".netdevConfig.Name = "wg-birdsong";
}

View file

@ -1,40 +0,0 @@
{ config, lib, pkgs, ... }:
let
keys = import ../../keys.nix;
in
{
imports = [
./hardware-configuration.nix
./networking.nix
];
nixpkgs.hostPlatform = "aarch64-linux";
networking.hostName = "kalessin";
networking.hostId = "534b538e";
networking.domain = "birdsong.network";
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
fountain.users.randomcat.enable = true;
fountain.users.trungle.enable = true;
qenya.base-server.enable = true;
qenya.services.remote-builder = {
enable = true;
authorizedKeys.keys = [ ];
};
randomcat.services.zfs.datasets = {
"rpool_kalessin/state" = { mountpoint = "none"; };
};
services.sanoid.datasets."rpool_kalessin/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
process_children_only = true;
};
system.stateVersion = "23.11";
}

View file

@ -1,38 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_scsi" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "rpool_kalessin/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "rpool_kalessin/nix";
fsType = "zfs";
};
fileSystems."/var" =
{ device = "rpool_kalessin/var";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/2ADE-A033";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices = [ ];
}

View file

@ -1,18 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.enp0s6.useDHCP = true;
age.secrets.wireguard-peer-kalessin = {
file = ../../secrets/wireguard-peer-kalessin.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-kalessin.path;
};
}

View file

@ -1,8 +0,0 @@
{ config, lib, pkgs, ... }:
{
services.sanoid.datasets."rpool_albion/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
};
}

View file

@ -1,67 +0,0 @@
{ config, lib, pkgs, ... }:
let
keys = import ../../keys.nix;
in
{
imports = [
./backup.nix
./filesystems.nix
./hardware.nix
./networking.nix
./ftp.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking.hostName = "kilgharrah";
networking.hostId = "72885bb5";
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];
boot.kernelModules = [ "kvm-intel" ];
qenya.base-graphical.enable = true;
qenya.base-graphical.desktop = "plasma6";
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console.keyMap = "uk";
services.xserver.xkb.layout = "gb";
fountain.users.qenya.enable = true;
age.secrets.user-password-kilgharrah-qenya.file = ../../secrets/user-password-kilgharrah-qenya.age;
users.users.qenya.hashedPasswordFile = config.age.secrets.user-password-kilgharrah-qenya.path;
fountain.admins = [ "qenya" ];
home-manager.users.qenya = { pkgs, ... }: {
home.packages = with pkgs; [ obs-studio ];
# For the moment, this hosts some network-accessible services, so we want it on 24/7
programs.plasma.powerdevil.AC.autoSuspend.action = "nothing";
};
qenya.services.remote-builder = {
enable = true;
authorizedKeys.keys = [
keys.machines.yevaud
keys.machines.orm
keys.machines.tohru
keys.machines.elucredassa
];
};
programs.steam.enable = true;
qenya.services.audiobookshelf = {
enable = true;
domain = "audiobookshelf.qenya.tel";
};
qenya.services.jellyfin = {
enable = true;
domain = "jellyfin.qenya.tel";
};
qenya.services.navidrome = {
enable = true;
domain = "music.qenya.tel";
dataDir = "/srv/music";
};
system.stateVersion = "24.05";
}

View file

@ -1,93 +0,0 @@
{ config, lib, pkgs, ... }:
{
# SSD on board
boot.initrd.luks.devices = {
"cryptroot".device = "/dev/disk/by-uuid/b414aaba-0a36-4135-a7e1-dc9489286acd";
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@" "compress=zstd" ];
};
"/home" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@home" "compress=zstd" ];
};
"/nix" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@nix" "compress=zstd" "noatime" ];
};
"/swap" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@swap" "noatime" ];
};
"/root" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@root" "compress=zstd" ];
};
"/srv" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@srv" "compress=zstd" ];
};
"/var/cache" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@cache" "compress=zstd" "noatime" ];
};
"/var/tmp" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@tmp" "compress=zstd" "noatime" ];
};
"/var/log" = {
device = "/dev/disk/by-uuid/ad4cbc18-8849-40ed-b0bf-097f8f46346b";
fsType = "btrfs";
options = [ "subvol=@log" "compress=zstd" "noatime" ];
};
"/boot" = {
device = "/dev/disk/by-uuid/9582-E78D";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
};
swapDevices = [{
device = "/swap/swapfile";
size = 32 * 1024;
}];
# HDD in bay
environment.etc.crypttab.text = ''
albion UUID=8a924f24-9b65-4f05-aeda-5b4080cc7aa1 /root/luks-albion.key
'';
randomcat.services.zfs.datasets = {
"rpool_albion/data" = { mountpoint = "none"; };
"rpool_albion/data/steam" = { mountpoint = "/home/qenya/.local/share/Steam"; };
"rpool_albion/state" = { mountpoint = "none"; };
"rpool_albion/state/audiobookshelf" = { mountpoint = "/var/lib/audiobookshelf"; };
"rpool_albion/state/jellyfin" = { mountpoint = "/var/lib/jellyfin"; };
"rpool_albion/state/navidrome" = { mountpoint = "/var/lib/navidrome"; };
"rpool_albion/srv" = { mountpoint = "none"; };
"rpool_albion/srv/audiobookshelf" = { mountpoint = "/srv/audiobookshelf"; };
"rpool_albion/srv/ftp" = { mountpoint = "/srv/ftp"; };
"rpool_albion/srv/jellyfin" = { mountpoint = "/srv/jellyfin"; };
"rpool_albion/srv/music" = { mountpoint = "/srv/music"; };
};
# Other
boot.supportedFilesystems = [ "ntfs" "zfs" ];
}

View file

@ -1,70 +0,0 @@
{ config, lib, pkgs, ... }:
{
age.secrets.ftp-userDb-qenya = {
# To update this, see the nixos docs for services.vsftpd.userDbPath. Note
# that the command it gives to create a userDb, if applied to an *existing*
# userDb, will *add* the entries from the source file, overwriting any
# entries with the same username but leaving other existing entries intact.
# Also note the database format does not salt hashes.
file = ../../secrets/ftp-userDb-qenya.age;
# we have to specify this manually because pam_userdb strips the extension
path = "/etc/vsftpd/userDb.db";
};
services.vsftpd = {
enable = true;
localUsers = true;
forceLocalLoginsSSL = true;
forceLocalDataSSL = true;
rsaCertFile = "${config.security.acme.certs."ftp.qenya.tel".directory}/fullchain.pem";
rsaKeyFile = "${config.security.acme.certs."ftp.qenya.tel".directory}/key.pem";
enableVirtualUsers = true;
userlistDeny = false; # turn userlist from a denylist into an allowlist
userlist = [ "qenya" ]; # this is just a list of the users in the userDb
userDbPath = "/etc/vsftpd/userDb";
localRoot = "/srv/ftp";
extraConfig = ''
# nothing in the default cipher suite is enabled in modern ssl clients!
ssl_ciphers=HIGH
# set this to something firewallable
pasv_min_port=51000
pasv_max_port=51099
# don't bother with upgrading to TLS, just listen on FTPS only
implicit_ssl=YES
listen_port=990
'';
};
services.nginx = {
enable = true;
virtualHosts = {
"ftp.qenya.tel" = {
forceSSL = true;
useACMEHost = "ftp.qenya.tel";
locations."/".return = "503";
};
};
};
security.acme.certs = {
"ftp.qenya.tel" = {
webroot = "/var/lib/acme/acme-challenge";
group = "acme_ftp.qenya.tel";
};
};
users.groups."acme_ftp.qenya.tel".members = [
"vsftpd" # not configurable in the vsftpd nixos module
config.services.nginx.group
];
networking.firewall.allowedTCPPorts = [ 990 80 443 ];
networking.firewall.allowedTCPPortRanges = [{ from = 51000; to = 51099; }];
}

View file

@ -1,31 +0,0 @@
{ config, lib, pkgs, ... }:
{
hardware.enableAllFirmware = true;
hardware.cpu.intel.updateMicrocode = true;
services.fwupd.enable = true;
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia.open = false;
# # Downgrade to driver version 535 as 550 has problems with Wayland
# hardware.nvidia.package =
# let
# rcu_patch = pkgs.fetchpatch {
# url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch";
# hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg=";
# };
# in
# config.boot.kernelPackages.nvidiaPackages.mkDriver {
# version = "535.154.05";
# sha256_64bit = "sha256-fpUGXKprgt6SYRDxSCemGXLrEsIA6GOinp+0eGbqqJg=";
# sha256_aarch64 = "sha256-G0/GiObf/BZMkzzET8HQjdIcvCSqB1uhsinro2HLK9k=";
# openSha256 = "sha256-wvRdHguGLxS0mR06P5Qi++pDJBCF8pJ8hr4T8O6TJIo=";
# settingsSha256 = "sha256-9wqoDEWY4I7weWW05F4igj1Gj9wjHsREFMztfEmqm10=";
# persistencedSha256 = "sha256-d0Q3Lk80JqkS1B54Mahu2yY/WocOqFFbZVBh+ToGhaE=";
# patches = [ rcu_patch ];
# };
services.printing.drivers = [ pkgs.hplip ];
}

View file

@ -1,28 +0,0 @@
{ config, lib, pkgs, ... }:
{
systemd.network.enable = true;
networking.useDHCP = false;
systemd.network.networks."10-wan" = {
matchConfig.Name = "enp2s0";
networkConfig = {
DHCP = "ipv4";
IPv6AcceptRA = true;
};
linkConfig.RequiredForOnline = "routable";
};
age.secrets.wireguard-peer-kilgharrah = {
file = ../../secrets/wireguard-peer-kilgharrah.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-kilgharrah.path;
persistentKeepalive = 31;
};
}

View file

@ -0,0 +1,13 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./home.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
system.stateVersion = "23.11";
}

View file

@ -1,72 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking.hostName = "orm";
networking.hostId = "00000000";
networking.domain = "birdsong.network";
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
qenya.base-server.enable = true;
qenya.services.distributed-builds = {
enable = true;
keyFile = "/etc/ssh/ssh_host_ed25519_key";
builders = [ "kilgharrah" ];
};
nix.settings.max-jobs = 0;
randomcat.services.zfs.datasets = {
"rpool_orm/state" = { mountpoint = "none"; };
"rpool_orm/state/actual" = { mountpoint = "/var/lib/actual"; };
"rpool_orm/state/postgresql" = { mountpoint = "/var/lib/postgresql"; };
};
services.sanoid.datasets."rpool_orm/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
process_children_only = true;
};
services.postgresql = {
enable = true;
package = pkgs.postgresql_17;
dataDir = "/var/lib/postgresql/17";
# managing imperatively instead of using ensureDatabases/ensureUsers
enableTCPIP = true;
settings = {
port = 5432;
# TODO: fix SSL
# ssl = true;
};
# only allow remote connections from within birdsong vpn
# TODO: don't hardcode the IP addresses
authentication = pkgs.lib.mkOverride 10 ''
#type database DBuser auth-method
local all all trust # used by nixos for local monitoring
host sameuser all 10.127.0.0/16 scram-sha-256
host sameuser all fd70:81ca:f8f::/48 scram-sha-256
'';
};
networking.firewall.interfaces."wg-birdsong".allowedTCPPorts = [ 5432 ];
qenya.services.actual = {
enable = true;
domain = "actual.unspecified.systems";
};
fountain.services.web-redirect = {
enable = true;
domains = {
"actual.qenya.tel" = "actual.unspecified.systems";
};
};
system.stateVersion = "23.11";
}

View file

@ -37,4 +37,13 @@
swapDevices =
[ { device = "/dev/disk/by-uuid/a0ac8f60-25f9-4dec-af70-e3f4cd36c575"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens3.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

12
hosts/orm/home.nix Normal file
View file

@ -0,0 +1,12 @@
{ config, lib, pkgs, ... }:
{
home-manager.users.qenya = { pkgs, ... }: {
imports = [
../../home/cli.nix
../../home/git.nix
];
home.stateVersion = "23.11";
};
}

View file

@ -1,18 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.ens3.useDHCP = true;
age.secrets.wireguard-peer-orm = {
file = ../../secrets/wireguard-peer-orm.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-orm.path;
};
}

View file

@ -1,11 +0,0 @@
{ config, lib, pkgs, ... }:
{
services.syncthing = {
enable = true;
extraOptions = [
"--gui-address=:8385"
"--home=/home/qenya/state/syncthing"
];
};
}

View file

@ -0,0 +1,45 @@
{ config, lib, pkgs, ... }:
{
imports =
[
./hardware-configuration.nix
./home.nix
../../common/fonts.nix
../../common/steam.nix
./syncthing.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.editor = false;
networking.networkmanager.enable = true;
i18n.defaultLocale = "en_GB.UTF-8";
console.keyMap = "uk";
services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
services.xserver.xkb.layout = "gb";
services.printing.enable = true;
sound.enable = true;
hardware.pulseaudio.enable = true;
# USB drives
boot.supportedFilesystems = [ "ntfs" ];
hardware.enableAllFirmware = true;
services.fwupd.enable = true;
services.fstrim.enable = true;
boot.initrd.luks.devices = {
"rpool".device = "/dev/nvme0n1p2";
};
system.stateVersion = "23.11";
}

View file

@ -1,68 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
let
inherit (lib) mkForce;
in
{
imports = [
./filesystems.nix
./hardware.nix
./networking.nix
./syncthing.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking.hostName = "tohru";
networking.hostId = "31da19c1";
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "rtsx_pci_sdmmc" ];
boot.kernelModules = [ "kvm-intel" ];
qenya.base-graphical.enable = true;
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console.keyMap = "uk";
services.xserver.xkb.layout = "gb";
# tohru does not have the resources to run this under other load and is generally powered off when not in use.
# instead, just run `nix-store --optimise` every so often.
nix.optimise.automatic = mkForce false;
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
age.secrets.user-password-tohru-qenya.file = ../../secrets/user-password-tohru-qenya.age;
users.users.qenya.hashedPasswordFile = config.age.secrets.user-password-tohru-qenya.path;
users.users.qenya.extraGroups = [
"networkmanager" # UI wifi configuration
"dialout" # access to serial ports
];
nixpkgs.overlays = [ inputs.scoutshonour.overlays.default ];
home-manager.users.qenya = { pkgs, ... }: {
home.packages = with pkgs; [
keepassxc
amberol
foliate
nicotine-plus
# games
openttd
prismlauncher
scoutshonour.digital-a-love-story
scoutshonour.dont-take-it-personally-babe
];
};
qenya.services.distributed-builds = {
enable = true;
keyFile = "/etc/ssh/ssh_host_ed25519_key";
builders = [ "kilgharrah" ];
};
programs.evolution.enable = true; # not in home-manager yet; not declaratively configurable yet
programs.steam.enable = true;
system.stateVersion = "23.11";
}

View file

@ -1,51 +0,0 @@
{ config, lib, pkgs, ... }:
{
boot.initrd.luks.devices = {
"rpool".device = "/dev/nvme0n1p2";
};
boot.supportedFilesystems = [ "ntfs" ]; # for USB drives
fileSystems = {
"/" = {
device = "rpool/root";
fsType = "zfs";
};
"/nix" = {
device = "rpool/nix";
fsType = "zfs";
};
"/var" = {
device = "rpool/var";
fsType = "zfs";
};
"/config" = {
device = "rpool/config";
fsType = "zfs";
};
"/home" = {
device = "rpool/home";
fsType = "zfs";
};
"/data" = {
device = "rpool/data";
fsType = "zfs";
};
"/data/syncthing" = {
device = "rpool/data/syncthing";
fsType = "zfs";
};
"/data/steam" = {
device = "rpool/data/steam";
fsType = "zfs";
};
"/boot" = {
device = "/dev/disk/by-uuid/7DD4-487E";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
};
swapDevices = [{ device = "/dev/disk/by-uuid/a066313e-2467-4e07-ad0c-aeb7ff3f8d97"; }];
}

View file

@ -0,0 +1,76 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "rpool/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "rpool/nix";
fsType = "zfs";
};
fileSystems."/var" =
{ device = "rpool/var";
fsType = "zfs";
};
fileSystems."/config" =
{ device = "rpool/config";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "rpool/home";
fsType = "zfs";
};
fileSystems."/data" =
{ device = "rpool/data";
fsType = "zfs";
};
fileSystems."/data/syncthing" =
{ device = "rpool/data/syncthing";
fsType = "zfs";
};
fileSystems."/data/steam" =
{ device = "rpool/data/steam";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/7DD4-487E";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices =
[ { device = "/dev/disk/by-uuid/a066313e-2467-4e07-ad0c-aeb7ff3f8d97"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -1,10 +0,0 @@
{ config, lib, pkgs, ... }:
{
hardware.enableAllFirmware = true;
hardware.cpu.intel.updateMicrocode = true;
services.fwupd.enable = true;
services.printing.drivers = [ pkgs.hplip ];
}

31
hosts/tohru/home.nix Normal file
View file

@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
{
home-manager.users.qenya = { pkgs, ... }: {
imports = [
../../home/cli.nix
../../home/firefox.nix
../../home/git.nix
../../home/gnome
../../home/libreoffice.nix
../../home/vscode.nix
];
home.packages = (with pkgs; [
bitwarden
discord
foliate
gimp-with-plugins
keepassxc
openttd
thunderbird
tor-browser-bundle-bin
]) ++ (with pkgs.nur.repos.qenya; [
digital-a-love-story
dont-take-it-personally-babe
]);
programs.chromium.enable = true;
home.stateVersion = "23.11";
};
}

View file

@ -1,21 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
systemd.network.wait-online.enable = false;
networking.networkmanager.enable = true;
age.secrets.wireguard-peer-tohru = {
file = ../../secrets/wireguard-peer-tohru.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-tohru.path;
persistentKeepalive = 23;
};
}

View file

@ -11,41 +11,12 @@
settings = {
devices = {
"kilgharrah" = { id = "RDT7IGD-76FZ6LY-37PPB2W-DWPQRPR-LZ4AXF7-4GIIHYJ-RVXUUSG-ZXPN3AZ"; };
"latias" = { id = "EN4W2SB-LB4AAZQ-6AQIE7G-S3BSCSP-V2EUNMM-KAQEHW3-PPAPGBO-PXRPWAL"; };
"shaw" = { id = "NC7WMZS-GQETJYR-IAYGD65-GHTSTVP-VAAG43K-W7N3LO5-C5OQMZ2-DTK6YA7"; };
};
folders = {
"Sync" = {
id = "uln2v-zwzwj";
path = "~/Sync";
devices = [ "kilgharrah" "shaw" ];
};
"Documents" = {
id = "alp59-7gs9s";
path = "~/Documents";
devices = [ "kilgharrah" "shaw" ];
};
"Music" = {
id = "7xvkf-y62s7";
path = "~/Music";
devices = [ "kilgharrah" "shaw" ];
};
"Pictures" = {
id = "tbmhx-ep7wk";
path = "~/Pictures";
devices = [ "kilgharrah" "shaw" ];
};
"ES-DE" = {
id = "c1cbh-llw94";
path = "~/ES-DE";
devices = [ "kilgharrah" "latias" "shaw" ];
};
"ROMs" = {
id = "dcze4-v6act";
path = "~/ROMs";
devices = [ "kilgharrah" "latias" "shaw" ];
devices = [ "kilgharrah" ];
};
};
};

View file

@ -0,0 +1,15 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./home.nix
./forgejo.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
system.stateVersion = "23.11";
}

View file

@ -1,63 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
./experiments/birdsong-dns.nix
# TODO: this breaks external IPv6 somehow
# ./experiments/pennykettle.nix
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
networking.hostName = "yevaud";
networking.hostId = "09673d65";
networking.domain = "birdsong.network";
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
qenya.base-server.enable = true;
qenya.services.distributed-builds = {
enable = true;
keyFile = "/etc/ssh/ssh_host_ed25519_key";
builders = [ "kilgharrah" ];
};
nix.settings.max-jobs = 0;
randomcat.services.zfs.datasets = {
"rpool/state" = { mountpoint = "none"; };
"rpool/state/forgejo" = { mountpoint = "/var/lib/forgejo"; };
};
services.sanoid.datasets."rpool/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
};
qenya.services.forgejo = {
enable = true;
domain = "git.unspecified.systems";
};
fountain.services.web-redirect = {
enable = true;
domains = {
"git.katherina.rocks" = "git.unspecified.systems";
"git.qenya.tel" = "git.unspecified.systems";
};
};
services.nginx = {
enable = true;
virtualHosts = {
"birdsong.network" = {
forceSSL = true;
enableACME = true;
locations."/".return = "301 https://git.unspecified.systems/qenya/birdsong/";
};
};
};
system.stateVersion = "23.11";
}

View file

@ -1,32 +0,0 @@
{ config, lib, pkgs, ... }:
{
services.bind = {
# enable = true;
cacheNetworks = [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ];
forwarders = [ ];
listenOn = [ config.birdsong.hosts.yevaud.ipv4 ];
listenOnIpv6 = [ config.birdsong.hosts.yevaud.ipv6 ];
zones = {
"birdsong.internal" = {
master = true;
file = pkgs.writeText "birdsong.internal.zone" ''
$TTL 60
$ORIGIN birdsong.internal.
birdsong.internal. IN SOA ns.birdsong.internal. auto.qenya.tel. ( 2024122701 7200 3600 1209600 3600 )
birdsong.internal. IN NS ns.birdsong.internal.
yevaud.c.birdsong.internal. IN A 10.127.1.1
yevaud.c.birdsong.internal. IN AAAA fd70:81ca:0f8f:1::1
ns.birdsong.internal. IN A 10.127.1.1
ns.birdsong.internal. IN AAAA fd70:81ca:0f8f:1::1
'';
};
};
};
networking.resolvconf.useLocalResolver = false;
networking.firewall.allowedTCPPorts = [ 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];
}

View file

@ -1,85 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.nat.enable = true;
networking.nat.internalInterfaces = [ "ve-pennykettle1" ];
networking.nat.externalInterface = "ens3";
networking.firewall.allowedUDPPorts = [ 51821 ];
containers."pennykettle1" = {
privateNetwork = true;
extraVeths."ve-pennykettle1" = {
hostAddress = "10.235.1.1";
localAddress = "10.235.2.1";
forwardPorts = [{ hostPort = 51821; }];
};
ephemeral = true;
autoStart = true;
bindMounts."/run/secrets/wg-key".hostPath = config.age.secrets.protonvpn-pennykettle1.path;
config = { config, pkgs, ... }: {
system.stateVersion = "24.05";
systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
environment.systemPackages = [ pkgs.wireguard-tools ];
networking.useDHCP = false;
networking.useHostResolvConf = false;
networking.firewall.allowedUDPPorts = [ 51821 ];
systemd.network = {
enable = true;
networks."10-ve" = {
matchConfig.Name = "ve-pennykettle1";
networkConfig.Address = "10.235.2.1/32";
# linkConfig.RequiredForOnline = "routable";
routes = [{
routeConfig = {
Gateway = "10.235.1.1";
Destination = "217.138.216.162/32";
};
}];
};
networks."30-protonvpn" = {
matchConfig.Name = "wg-protonvpn";
networkConfig = {
DefaultRouteOnDevice = true;
Address = [ "10.2.0.2/32" ];
DNS = "10.2.0.1";
};
linkConfig = {
RequiredForOnline = "yes";
ActivationPolicy = "always-up";
};
};
netdevs."30-protonvpn" = {
netdevConfig = {
Name = "wg-protonvpn";
Kind = "wireguard";
Description = "WireGuard tunnel to ProtonVPN (DE#1; NAT: strict, no port forwarding)";
};
wireguardConfig = {
ListenPort = 51821;
PrivateKeyFile = "/run/secrets/wg-key";
};
wireguardPeers = [{
wireguardPeerConfig = {
PublicKey = "C+u+eQw5yWI2APCfVJwW6Ovj3g4IrTOfe+tMZnNz43s=";
AllowedIPs = "0.0.0.0/0";
Endpoint = "217.138.216.162:51820";
PersistentKeepalive = 5;
};
}];
};
};
};
};
age.secrets.protonvpn-pennykettle1 = {
file = ../../../secrets/protonvpn-pennykettle1.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
}

49
hosts/yevaud/forgejo.nix Normal file
View file

@ -0,0 +1,49 @@
{ config, lib, pkgs, ... }:
{
# TODO: email out
# TODO: interface customisation
services = {
nginx = {
enable = true;
virtualHosts = {
"git.qenya.tel" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://[::1]:3000/";
};
"git.katherina.rocks" = {
forceSSL = true;
enableACME = true;
locations."/".return = "301 https://git.qenya.tel$request_uri";
};
};
};
forgejo = {
enable = true;
stateDir = "/data/forgejo";
settings = {
DEFAULT.APP_NAME = "git.qenya.tel";
cache = {
ADAPTER = "twoqueue";
HOST = ''{"size": 100, "recent_ratio": 0.25, "ghost_ratio": 0.5}'';
};
database = {
DB_TYPE = "sqlite3";
SQLITE_JOURNAL_MODE = "WAL";
};
security.LOGIN_REMEMBER_DAYS = 365;
server = {
DOMAIN = "git.qenya.tel";
HTTP_PORT = 3000;
ROOT_URL = "https://git.qenya.tel/";
};
service.DISABLE_REGISTRATION = true;
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View file

@ -28,6 +28,11 @@
fsType = "zfs";
};
fileSystems."/data/forgejo" =
{ device = "rpool/forgejo";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/107D-5AB3";
fsType = "vfat";
@ -37,4 +42,13 @@
swapDevices =
[ { device = "/dev/disk/by-uuid/f8b6eb35-33ad-4e19-bf3d-cac5ec38a8dc"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens3.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

13
hosts/yevaud/home.nix Normal file
View file

@ -0,0 +1,13 @@
{ config, lib, pkgs, ... }:
{
home-manager.users.qenya = { pkgs, ... }: {
imports = [
../../home/cli.nix
../../home/git.nix
../../home/tmux.nix
];
home.stateVersion = "23.11";
};
}

View file

@ -1,18 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.ens3.useDHCP = true;
age.secrets.wireguard-peer-yevaud = {
file = ../../secrets/wireguard-peer-yevaud.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-yevaud.path;
};
}

View file

@ -1,29 +1,19 @@
{
machines = {
kilgharrah = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgGF3gzzlMbxxk3UAAgHJ7sDdjqtrw7UW16M1XhXtz2 root@kilgharrah";
elucredassa = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+Y/vqGNc1wXUAg4XMAAcLupkggywj2LpYDwA16ONbH root@elucredassa";
tohru = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8wuGzF0Y7SaH9aimo3SmCz99MTQwL+rEVhx0jsueU root@tohru";
yevaud = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHUAgyQhl390yUObLUI+jEbuNrZ2U6+8px628DolD+T root@yevaud";
orm = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGc9rkcdOVWozBFj3kLVnSyUQQbyyH+UG+bLawanQkRQ root@orm";
kalessin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOPt3iSSmgnlsv1/jafgZgI7o8UuXzcAL45hID2ThfS8 root@kalessin";
shaw = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw";
};
users = {
qenya = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjBuuxo+w3yED0aPnsNb8S90p/GgBqFEG9K4ETZ5Wkq qenya@kilgharrah"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEmkV9arotms79lJPsLHkdzAac4eu3pYS08ym0sB/on qenya@tohru"
];
randomcat = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDHagOaeTR+/7FL9sErciMw30cmV/VW8HU7J3ZFU5nj9 janet@randomcat.org"
];
trungle = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA57legzdIcYTVVri4Wc0CvgWefbRhmUqhu0F/5f8FB reuben@glenda-artix"
richard = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHAuYWPfYVKdjBY/gBMt2n11Seb+hMqjui1PQ6C4ph8i richard@tress"
];
gaelan = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFbDvPKnPXe+58QgdgK8yZ3Ac9dkJdtHJ3pQwWhszM7McwCzCEO/b940K0orLjfeUruC+hGJZO8heIh0J6JwSK907aS2wpHofU9q7bMT0PYeuHrSb2iFrOFIkTIWpO8hnWad8TGKOlOdNTKEdB9zwxXEKTFb9QW1Z27Zql79W44jUvaOTb7gKUps37O77lHEJDModaRsXS2523pSbrTZKDwZ73+S0ECeNUwwzLUyOOUHfENEXnM18hWm8mV0iU7kxFcmS33z9rWlWPNiCXnBnSi5LPgBarYOAqQf56f9OisafKqvc3uX+yn0kGCDWglVGUkbhfSIP9+w+yv/h/NJWIJlJC92ndbktAqAQW4gb7lXYxpbdoWcmqEy97q0e2vyBdhcVXwZ+0q+U8I74m8trq36ieHDtLKYkiFBX6zvrLP4I5OZU+EecdV2HcMoU8HNa5u1mvG+oHaEgkR70a5cQtrPzWLS/OMLqvWL39vO7RNskzwWCSuWScxDGitr+BunRRbL4aKNkkPjdDlIqb/SfSrFikOo75f5Ku4I32nbM7SNpIjA4cHe50rx1UB8lT+RwHdxL99OdoxIPCe6OLA5uT8VGPXkvqd/ZIFOL2HaM+uPLaYbjwLrHlwSOLgGbehmsSD369EXv6NAc5wbzsSLJQhJ66d5unnzGjn4dRt9sbDw== gbs@canishe.com"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHId+2dJYiZK++p8lu9Bax0J29JjeuU4qcIBdLwEz3lm gbs@canishe.com"
];
};
}

47
npins/default.nix Normal file
View file

@ -0,0 +1,47 @@
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
mkSource = spec:
assert spec ? type; let
path =
if spec.type == "Git" then mkGitSource spec
else if spec.type == "GitRelease" then mkGitSource spec
else if spec.type == "PyPi" then mkPyPiSource spec
else if spec.type == "Channel" then mkChannelSource spec
else builtins.throw "Unknown source type ${spec.type}";
in
spec // { outPath = path; };
mkGitSource = { repository, revision, url ? null, hash, ... }:
assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball
if url != null then
(builtins.fetchTarball {
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
})
else assert repository.type == "Git"; builtins.fetchGit {
url = repository.url;
rev = revision;
# hash = hash;
};
mkPyPiSource = { url, hash, ... }:
builtins.fetchurl {
inherit url;
sha256 = hash;
};
mkChannelSource = { url, hash, ... }:
builtins.fetchTarball {
inherit url;
sha256 = hash;
};
in
if version == 3 then
builtins.mapAttrs (_: mkSource) data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"

90
npins/sources.json Normal file
View file

@ -0,0 +1,90 @@
{
"pins": {
"agenix": {
"type": "GitRelease",
"repository": {
"type": "GitHub",
"owner": "ryantm",
"repo": "agenix"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"version": "0.15.0",
"revision": "564595d0ad4be7277e07fa63b5a991b3c645655d",
"url": "https://api.github.com/repos/ryantm/agenix/tarball/0.15.0",
"hash": "01dhrghwa7zw93cybvx4gnrskqk97b004nfxgsys0736823956la"
},
"home-manager": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "nix-community",
"repo": "home-manager"
},
"branch": "release-24.05",
"revision": "391ca6e950c2525b4f853cbe29922452c14eda82",
"url": "https://github.com/nix-community/home-manager/archive/391ca6e950c2525b4f853cbe29922452c14eda82.tar.gz",
"hash": "17cb6y4dymp351mj89y1bmxvqzw8m9h89nqd3qrwg6qjdm9sgkxa"
},
"lix": {
"type": "GitRelease",
"repository": {
"type": "Git",
"url": "https://git.lix.systems/lix-project/lix.git"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"version": "2.90.0",
"revision": "2a4376be20d70feaa2b0e640c5041fb66ddc67ed",
"url": "https://git.lix.systems/lix-project/lix/archive/2.90.0.tar.gz",
"hash": "1iyylsiv1n6mf6rbi4k4fm5nv24a940cwfz92gk9fx6axh2kxjbz"
},
"lix-module": {
"type": "GitRelease",
"repository": {
"type": "Git",
"url": "https://git.lix.systems/lix-project/nixos-module.git"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"version": "2.90.0",
"revision": "5c48c833c15bb80d127a398a8c2484d42fdd8257",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.90.0.tar.gz",
"hash": "1lb0xljlbhcjd1y79sspfrd15jar7q10sqkwzmqnzkk0cdqbchy8"
},
"nix-vscode-extensions": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "nix-community",
"repo": "nix-vscode-extensions"
},
"branch": "master",
"revision": "3be7b0b799d739c3e15f3fd0a909d682c173962f",
"url": "https://github.com/nix-community/nix-vscode-extensions/archive/3be7b0b799d739c3e15f3fd0a909d682c173962f.tar.gz",
"hash": "00z3lqlpfabdp6sg8d6z2vlyvnig89brkhwgri5waznrw3ksna2y"
},
"nixpkgs": {
"type": "Channel",
"name": "nixos-24.05",
"url": "https://releases.nixos.org/nixos/24.05/nixos-24.05.2355.d032c1a6dfad/nixexprs.tar.xz",
"hash": "1fynyfjsmrxs383mygzlbkb3yhzmlnnpf8x84mikaiqc3ngszsv8"
},
"nur": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "nix-community",
"repo": "NUR"
},
"branch": "master",
"revision": "6206fd683edcb79c4a0592cf25e610449ed0d82d",
"url": "https://github.com/nix-community/NUR/archive/6206fd683edcb79c4a0592cf25e610449ed0d82d.tar.gz",
"hash": "108k8qshygkcdc1y5k9dfyw24jizcp1jvhkz8a7pzf57frkhzrdx"
}
},
"version": 3
}

10
pinning.nix Normal file
View file

@ -0,0 +1,10 @@
{ config, lib, pkgs, ... }:
let sources = import ./npins;
in {
# Make <nixpkgs> point systemwide to the pinned nixpkgs
# https://jade.fyi/blog/pinning-nixos-with-npins/
nix.settings.experimental-features = "nix-command flakes";
nixpkgs.flake.source = sources.nixpkgs;
nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];
}

View file

@ -1,23 +0,0 @@
let
keys = import ./keys.nix;
secrets = with keys; {
ftp-userDb-qenya = [ machines.kilgharrah ] ++ keys.users.qenya;
user-password-kilgharrah-qenya = [ machines.kilgharrah ] ++ keys.users.qenya;
user-password-tohru-qenya = [ machines.tohru ] ++ keys.users.qenya;
wireguard-peer-orm = [ machines.orm ] ++ keys.users.qenya;
wireguard-peer-tohru = [ machines.tohru ] ++ keys.users.qenya;
wireguard-peer-yevaud = [ machines.yevaud ] ++ keys.users.qenya;
wireguard-peer-kalessin = [ machines.kalessin ] ++ keys.users.qenya;
wireguard-peer-kilgharrah = [ machines.kilgharrah ] ++ keys.users.qenya;
protonvpn-pennykettle1 = [ machines.yevaud ] ++ keys.users.qenya;
};
in
builtins.listToAttrs (
map
(secretName: {
name = "secrets/${secretName}.age";
value.publicKeys = secrets."${secretName}";
})
(builtins.attrNames secrets)
)

Binary file not shown.

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 uJfgGw +h4WiWyMlQZ5iaMFTl/whUD0vJnIN0GYeqRbZ0MIH0o
eKio4DsSJlrvSAjmR0naDO/lmB78o7cy7QC9WZjHUa0
-> ssh-ed25519 seJ9Iw xov8WY0TxEj5/wkWg1T0kmrbpXsNhDLnZwqyIg0eExA
wu5QApQk6K8Fu5XMTrWY2veoYbJVuQmn3DJXewVB860
-> ssh-ed25519 900ILw N6RbpHr4Vwgm0BUCuMXzVo3VEgrl29NF8ZJU5Far7yk
KdA1dZXmcSF3cH9bVdmIbj7iZO3uuSY+isjswDzSu+Y
--- YtnS9FqXVat2hi9BLvX+71HEZDw3zcxIQ7Dp5+iao4c
¢¼ða'þš|<7C>‡N7N”†ÊT5]O¤0Säm<-1ë»ëª:d®„g¡^/ä†u7µïNû?XþMçûìÄì~Þs.9c¾C

4
secrets/secrets.nix Normal file
View file

@ -0,0 +1,4 @@
let
keys = ../ssh-keys.nix;
in
{ }

Some files were not shown because too many files have changed in this diff Show more