Compare commits

..

No commits in common. "main" and "flakes" have entirely different histories.
main ... flakes

119 changed files with 815 additions and 4628 deletions

1
.envrc
View file

@ -1 +0,0 @@
use_nix

View file

@ -2,19 +2,18 @@
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
* `orm`: Oracle Cloud free AMD VM, currently idling
* `kalessin`: Oracle Cloud free ARM VM, currently idling
### Referenced only
* `kilgharrah`: Custom-built personal desktop, currently running Arch
* `shaw`: [My girlfriend's NAS](https://github.com/randomnetcat/nix-configs/tree/main/hosts/shaw)
* `latias`: My Steam Deck
@ -22,7 +21,7 @@ The canonical location for this repository is https://git.unspecified.systems/qe
### 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 +29,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.

View file

@ -1,29 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.qenya.base-graphical;
in
{
imports = [
./gnome.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,21 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkMerge mkOption types;
cfg = config.qenya.base-graphical;
in
{
config = mkIf cfg.enable {
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
# ];
};
}

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;
};
services.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,22 +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;
};
services.resolved = {
enable = true;
fallbackDns = [ ];
dnsovertls = "true";
extraConfig = ''
DNS=2a07:e340::4#base.dns.mullvad.net 194.242.2.4#base.dns.mullvad.net
'';
};
}

View file

@ -1,19 +1,10 @@
{
imports = [
./base-graphical
./base-server
./users
./boot.nix
./gpg.nix
./home-manager.nix
./misc.nix
./environment.nix
./nginx.nix
./nix.nix
./packages.nix
./sanoid.nix
./openssh.nix
./security.nix
./ssh.nix
./steam.nix
./tailscale.nix
./zsh.nix
];
}

View file

@ -2,21 +2,21 @@
{
environment.systemPackages = with pkgs; [
btop
git
wget
# hardware troubleshooting
lshw
parted
smartmontools
wget
# network troubleshooting
inetutils
lsof
tcpdump
netcat # <3
wireguard-tools
# used for nix config
npins
colmena
agenix
];
environment.wordlist.enable = true;

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,12 +0,0 @@
{ config, lib, pkgs, ... }:
{
nix.settings.experimental-features = "nix-command flakes";
nixpkgs.flake = {
source = lib.cleanSource pkgs.path;
setNixPath = true;
setFlakeRegistry = true;
};
nixpkgs.config.allowUnfree = true;
nix.settings.trusted-users = [ "@wheel" ];
}

13
common/openssh.nix Normal file
View file

@ -0,0 +1,13 @@
{ config, lib, pkgs, ... }:
{
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
services.fail2ban.enable = true;
}

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

@ -1,21 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) concatMapAttrs;
keys = import ../keys.nix;
in
{
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
programs.ssh.knownHosts = concatMapAttrs
(host: key: {
"${host}.birdsong.network".publicKey = key;
})
keys.machines;
}

View file

@ -1,17 +0,0 @@
{ config, lib, pkgs, ... }:
{
config = lib.mkIf config.programs.steam.enable {
programs.steam = {
package = pkgs.steam.override {
extraArgs = "-pipewire"; # for remote play with PipeWire
};
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
localNetworkGameTransfers.openFirewall = true;
};
services.joycond.enable = true;
};
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
{
services.tailscale = {
enable = true;
openFirewall = true;
extraUpFlags = [ "--login-server" "https://headscale.unspecified.systems" ];
extraDaemonFlags = [ "--no-logs-no-support" ]; # disable telemetry
};
systemd.services.tailscaled-autoconnect = {
after = [ "tailscaled.service" "network-online.target" ];
wants = [ "tailscaled.service" "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
script = ''
sleep 2 # wait for tailscaled to settle
${lib.getExe config.services.tailscale.package} up --reset ${lib.escapeShellArgs config.services.tailscale.extraUpFlags}
'';
};
networking.domain = "birdsong.network";
}

View file

@ -1,32 +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,25 @@
{ config, lib, pkgs, self, ... }:
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkEnableOption;
keys = import ../../keys.nix;
cfg = config.fountain.users.qenya;
in
{
options.fountain.users.qenya = {
enable = mkEnableOption "user qenya";
};
config = mkIf cfg.enable {
let keys = import ../../keys.nix;
in {
users.users.qenya = {
uid = 1001;
isNormalUser = true;
group = "qenya";
home = "/home/qenya";
extraGroups = [
"wheel" # sudo
"networkmanager" # UI wifi configuration
"dialout" # access to serial ports
];
shell = pkgs.zsh;
openssh.authorizedKeys.keys = keys.users.qenya;
uid = 1001;
};
users.groups.qenya.gid = config.users.users.qenya.uid;
home-manager.users.qenya = { config, lib, pkgs, osConfig, ... }: {
home.homeDirectory = osConfig.users.users.qenya.home;
programs.zsh.enable = true;
home-manager.users."qenya" = self.homeManagerModules."qenya";
imports = [
../../home
];
};
}

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";
};
config = mkIf cfg.enable {
users.users.randomcat = {
uid = 1000;
isNormalUser = true;
group = "randomcat";
home = "/home/randomcat";
openssh.authorizedKeys.keys = keys.users.randomcat;
};
users.groups.randomcat.gid = config.users.users.randomcat.uid;
uid = 1003;
};
}

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;
};
}

5
common/zsh.nix Normal file
View file

@ -0,0 +1,5 @@
{ config, lib, pkgs,... }:
{
programs.zsh.enable = true;
}

9
deployment/local.nix Normal file
View file

@ -0,0 +1,9 @@
{ name, nodes, config, lib, pkgs, ... }:
{
deployment = {
allowLocalDeployment = true;
targetHost = null;
tags = [ "local" ];
};
}

12
deployment/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" ];
}

353
flake.lock generated
View file

@ -3,18 +3,18 @@
"agenix": {
"inputs": {
"darwin": [],
"home-manager": [],
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1750173260,
"narHash": "sha256-9P1FziAwl5+3edkfFcr5HeGtQUtrSdk/MksX39GieoA=",
"lastModified": 1723293904,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
"owner": "ryantm",
"repo": "agenix",
"rev": "531beac616433bac6f9e2a19feb8e99a22a66baf",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
"type": "github"
},
"original": {
@ -23,350 +23,86 @@
"type": "github"
}
},
"colmena": {
"inputs": {
"flake-compat": [],
"flake-utils": "flake-utils",
"nix-github-actions": [],
"nixpkgs": [
"nixpkgs"
],
"stable": []
},
"birdsong": {
"locked": {
"lastModified": 1749739748,
"narHash": "sha256-csQQPoCA5iv+Nd9yCOCQNKflP7qUKEe7D27wsz+LPKM=",
"owner": "zhaofengli",
"repo": "colmena",
"rev": "c61641b156dfa3e82fc0671e77fccf7d7ccfaa3b",
"type": "github"
"lastModified": 1722971137,
"narHash": "sha256-1x0vaUy/uFCfoDn0a4K55+MNseAqLQmv1GPP6GQFFIA=",
"ref": "main",
"rev": "2fd6d96a00ef69a2afe72a2fe9d18d759c1cc8f3",
"revCount": 7,
"type": "git",
"url": "https://git.qenya.tel/qenya/birdsong"
},
"original": {
"owner": "zhaofengli",
"repo": "colmena",
"type": "github"
}
},
"firefox-addons": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1750737804,
"narHash": "sha256-wClGd2PhxdjjphR6wIgoiDcR+Gfg4/+FyseSOjIIzVU=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "aaaf4fec792bad465ea4a35c0be5bc2a54f33095",
"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": 1749398372,
"narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569",
"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"
"ref": "main",
"type": "git",
"url": "https://git.qenya.tel/qenya/birdsong"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1750792728,
"narHash": "sha256-Lh3dopA8DdY+ZoaAJPrtkZOZaFEJGSYjOdAYYgOPgE4=",
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "366f00797b1efb70f2882d3da485e3c10fd3d557",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.05",
"repo": "home-manager",
"type": "github"
}
},
"home-manager-unstable": {
"home-manager_2": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1750798083,
"narHash": "sha256-DTCCcp6WCFaYXWKFRA6fiI2zlvOLCf5Vwx8+/0R8Wc4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "ff31a4677c1a8ae506aa7e003a3dba08cb203f82",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"lix": {
"flake": false,
"locked": {
"lastModified": 1750762203,
"narHash": "sha256-LmQhjQ7c+AOkwhvR9GFgJOy8oHW35MoQRELtrwyVnPw=",
"rev": "38b358ce27203f972faa2973cf44ba80c758f46e",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/38b358ce27203f972faa2973cf44ba80c758f46e.tar.gz?rev=38b358ce27203f972faa2973cf44ba80c758f46e"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/lix/archive/release-2.93.tar.gz"
}
},
"lix-module": {
"inputs": {
"flake-utils": "flake-utils_2",
"flakey-profile": "flakey-profile",
"lix": "lix",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1750776670,
"narHash": "sha256-EfA5K5EZAnspmraJrXQlziffVpaT+QDBiE6yKmuaNNQ=",
"rev": "c3c78a32273e89d28367d8605a4c880f0b6607e3",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/c3c78a32273e89d28367d8605a4c880f0b6607e3.tar.gz?rev=c3c78a32273e89d28367d8605a4c880f0b6607e3"
"lastModified": 1720042825,
"narHash": "sha256-A0vrUB6x82/jvf17qPCpxaM+ulJnD8YZwH9Ci0BsAzE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "e1391fb22e18a36f57e6999c7a9f966dc80ac073",
"type": "github"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.93.1.tar.gz"
"owner": "nix-community",
"ref": "release-24.05",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1750622754,
"narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=",
"lastModified": 1723688146,
"narHash": "sha256-sqLwJcHYeWLOeP/XoLwAtYjr01TISlkOfz+NG82pbdg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1",
"rev": "c3d4ac725177c030b1e289015989da2ad9d56af0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1748740939,
"narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "656a64127e9d791a334452c6b6606d17539476e2",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-small": {
"locked": {
"lastModified": 1750784235,
"narHash": "sha256-IYCCkKerO3lMUcMaDRLfwnfyPopQbGWF8iHRd0XcCBc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a5e9291e97f5ba0b4ba7d657ddedd5f86d11acfd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1750506804,
"narHash": "sha256-VLFNc4egNjovYVxDGyBYTrvVCgDYgENp5bVi9fPTDYc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4206c4cb56751df534751b058295ea61357bbbaa",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable-small": {
"locked": {
"lastModified": 1750776346,
"narHash": "sha256-sWw7gz2B02fHQkmPSutVcoawLuiPT0hpztL0ldCnIy0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4396a137499b6cc9f9fe9f3c266577bd52d455a4",
"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": 1748196248,
"narHash": "sha256-1iHjsH6/5UOerJEoZKE+Gx1BgAoge/YcnUsOA4wQ/BU=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "b7697abe89967839b273a863a3805345ea54ab56",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
}
},
"randomcat": {
"flake": false,
"locked": {
"lastModified": 1750730821,
"narHash": "sha256-U5uW9mRSuA2dRaOyswmz2I0fUVQbGRSZROXIe2WKS+8=",
"owner": "randomnetcat",
"repo": "nix-configs",
"rev": "1a2a536f5550c3b323e19f46d166340ad01745fd",
"type": "github"
},
"original": {
"owner": "randomnetcat",
"repo": "nix-configs",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"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"
"birdsong": "birdsong",
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs"
}
},
"systems": {
@ -383,21 +119,6 @@
"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",

234
flake.nix
View file

@ -1,169 +1,103 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-small.url = "github:NixOS/nixpkgs/nixos-25.05-small";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-unstable-small.url = "github:NixOS/nixpkgs/nixos-unstable-small";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
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.93.1.tar.gz";
home-manager = {
url = "github:nix-community/home-manager/release-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
agenix = {
url = "github:ryantm/agenix?tag=0.15.0";
inputs = {
nixpkgs.follows = "nixpkgs";
darwin.follows = "";
};
};
birdsong.url = "git+https://git.qenya.tel/qenya/birdsong?ref=main";
};
outputs = inputs@{ self, nixpkgs, home-manager, agenix, birdsong, ... }: {
colmena = {
meta.nixpkgs = import nixpkgs { system = "x86_64-linux"; };
meta.nodeNixpkgs.kalessin = import nixpkgs { system = "aarch64-linux"; }; # TODO: this should be generated from the host config somehow
defaults = { name, nodes, config, lib, pkgs, ... }: {
deployment.replaceUnknownProfiles = lib.mkDefault false;
networking.hostName = name;
nix.settings.experimental-features = "nix-command flakes";
nixpkgs.flake.source = nixpkgs;
nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];
nixpkgs.config = {
allowUnfree = true;
packageOverrides = pkgs:
let sources = import ./npins;
in {
agenix = agenix.packages.${config.nixpkgs.hostPlatform.system}.default;
nur = (import sources.nur { inherit pkgs; });
};
};
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
useUserPackages = true;
useGlobalPkgs = true;
};
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";
};
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 = [ ./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 =
let
home-manager = inputs.home-manager.nixosModules.home-manager;
home-manager-unstable = inputs.home-manager-unstable.nixosModules.home-manager;
in
{
meta = {
nixpkgs = import nixpkgs-unstable {
system = "x86_64-linux";
overlays = [
inputs.lix-module.overlays.default
];
};
nodeNixpkgs = {
kilgharrah = import nixpkgs-unstable { 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"; };
tehanu = 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.agenix.nixosModules.default
home-manager.nixosModules.home-manager
agenix.nixosModules.default
birdsong.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 = "100.73.34.182"; # TODO: no fqdn yet
tohru = { name, nodes, ... }: {
networking.hostId = "31da19c1";
time.timeZone = "Europe/London";
kilgharrah.imports = [ ./hosts/kilgharrah home-manager-unstable ];
tohru.imports = [ ./hosts/tohru home-manager ];
elucredassa.imports = [ ./hosts/elucredassa home-manager ];
yevaud.imports = [ ./hosts/yevaud home-manager ];
orm.imports = [ ./hosts/orm home-manager ];
kalessin.imports = [ ./hosts/kalessin home-manager ];
tehanu.imports = [ ./hosts/tehanu home-manager ];
imports = [
./deployment/local.nix
./hosts/tohru/configuration.nix
];
};
yevaud = { name, nodes, ... }: {
networking.hostId = "09673d65";
time.timeZone = "Etc/UTC";
imports = [
./deployment/remote.nix
./hosts/yevaud/configuration.nix
];
};
orm = { name, nodes, ... }: {
networking.hostId = "00000000";
time.timeZone = "Etc/UTC";
imports = [
./deployment/remote.nix
./hosts/orm/configuration.nix
];
};
kalessin = { name, nodes, ... }: {
networking.hostId = "534b538e";
time.timeZone = "Etc/UTC";
deployment = {
buildOnTarget = true;
replaceUnknownProfiles = true;
};
imports = [
./deployment/remote.nix
./hosts/kalessin/configuration.nix
];
};
};
};
}

View file

@ -1,134 +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;
sourceFqdn = "${sourceHost}.birdsong.network";
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";
};
};
};
};
})
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
];
}

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;
}

27
home/dconf/appearance.nix Normal file
View file

@ -0,0 +1,27 @@
{ config, lib, pkgs, ... }:
let inherit (lib) mkIf;
in {
dconf = {
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" = mkIf config.dconf.enable {
source = ./background-image.jpg;
};
}

View file

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Before After
Before After

19
home/dconf/default.nix Normal file
View file

@ -0,0 +1,19 @@
{ config, lib, pkgs, ... }:
# dconf is the configuration manager for GNOME.
# home-manager, in its infinite wisdom, sets `dconf.enable` to true by default.
# This is a problem because we don't want it to attempt to apply our settings on
# a system that doesn't actually have GNOME installed. So, we override the
# default to false.
let inherit (lib) mkDefault;
in {
dconf.enable = mkDefault false;
imports = [
# TODO: nix-ify other parts of GNOME config
./appearance.nix
./keyboard.nix
];
}

14
home/dconf/keyboard.nix Normal file
View file

@ -0,0 +1,14 @@
# { 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,14 +1,10 @@
{
imports = [
./dconf
./feishin.nix
./firefox.nix
./fonts.nix
./cli.nix
./git.nix
./packages.nix
./tmux.nix
./vscode.nix
./xdg-mime-apps.nix
./zsh.nix
];

View file

@ -6,9 +6,12 @@
userName = "Katherina Walshe-Grey";
userEmail = "git@qenya.tel";
extraConfig = {
init.defaultBranch = "main";
pull.rebase = true;
push.autoSetupRemote = true;
init = {
defaultBranch = "main";
};
push = {
autoSetupRemote = true;
};
};
};
}

File diff suppressed because it is too large Load diff

View file

@ -1,26 +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;
"org/gnome/settings-daemon/plugins/power".power-saver-profile-on-low-battery = true;
};
imports = [
./desktop.nix
./keyboard.nix
./mouse-touchpad.nix
./multitasking.nix
./shell.nix
./wellbeing.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,19 +0,0 @@
{ config, lib, pkgs, ... }:
# These features are cool and I would like to keep trying them, but they are
# horribly bugged in GNOME 48.1. Consider re-enabling them when 48.2 is
# released. See, e.g.:
# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8289
# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8299
# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8305
# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8376
# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8398
{
dconf.settings = {
# "org/gnome/desktop/screen-time-limits".daily-limit-enabled = true;
# "org/gnome/desktop/break-reminders".selected-breaks = [ "eyesight" "movement" ];
"org/gnome/desktop/screen-time-limits".daily-limit-enabled = false;
"org/gnome/desktop/break-reminders".selected-breaks = [ ];
};
}

View file

@ -1,24 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
# Feishin ideally wants to see mpv at runtime, but this isn't catered for by
# the derivation in nixpkgs as it isn't strictly necessary.
# An easier way to do this would be to write mpv's full nix store path to
# Feishin's config. But Feishin has one JSON file for config and state, and
# we'd rather not overwrite the latter. Until and unless home-manager grows
# support for partially patching files, we live with this.
let
inherit (lib) mkIf;
isGraphical = osConfig.services.xserver.enable;
in
{
home.packages = mkIf isGraphical [
(pkgs.feishin.overrideAttrs (originalAttrs: {
buildInputs = originalAttrs.buildInputs ++ [ pkgs.mpv ];
postFixup = ''
${originalAttrs.postFixup or ""}
wrapProgram $out/bin/feishin --prefix PATH : ${lib.makeBinPath [ pkgs.mpv ]}
'';
}))
];
}

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.packages = 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,17 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
inherit (lib) mkIf;
isGraphical = osConfig.services.xserver.enable;
in
mkIf isGraphical {
fonts.fontconfig = {
enable = true;
};
home.packages = with pkgs; [
meslo-lgs-nf
];
programs.vscode.profiles.default.userSettings."terminal.integrated.fontFamily" = "MesloLGS NF";
}

View file

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

View file

@ -1,87 +0,0 @@
{ config, lib, pkgs, osConfig, ... }:
let
inherit (lib) mkIf mkDefault;
isGraphical = osConfig.services.xserver.enable;
in
{
programs.vscode = mkIf isGraphical {
enable = true;
package = pkgs.vscodium;
mutableExtensionsDir = false;
profiles.default = {
enableExtensionUpdateCheck = false;
enableUpdateCheck = false;
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
];
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";
};
};
"python.createEnvironment.contentButton" = "show";
"python.defaultInterpreterPath" = "${pkgs.python3}/bin/python";
"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?
};
};
}

63
home/vscode.nix Normal file
View file

@ -0,0 +1,63 @@
{ config, lib, pkgs, osConfig, ... }:
let
inherit (lib) mkIf;
inherit (pkgs) fetchFromGitHub;
inherit (osConfig.nixpkgs.hostPlatform) system;
extensions =
(import (fetchFromGitHub {
# On a stable channel, do NOT keep this up-to-date! VS Code extensions
# have breaking changes more frequently than the NixOS release cadence.
owner = "nix-community";
repo = "nix-vscode-extensions";
rev = "27ce569a199d2da1a8483fe3d69dd41664da3a63";
hash = "sha256-yyB4Kh3EFbYP+1JHza/IEeHwABypcYVi6vvWTmad/rY=";
})).extensions.${system};
in
{
programs.vscode = {
enableExtensionUpdateCheck = false;
enableUpdateCheck = false;
package = pkgs.vscodium;
extensions = with extensions.open-vsx; [
golang.go
jdinhlife.gruvbox
jnoortheen.nix-ide
ms-python.python
];
mutableExtensionsDir = false;
userSettings = {
"[go]" = {
"editor.defaultFormatter" = "golang.go";
"editor.formatOnSave" = false;
};
"extensions.autoUpdate" = false;
"git.autofetch" = true;
"git.confirmSync" = false;
"git.enableSmartCommit" = true;
"git.inputValidation" = true;
"git.inputValidationSubjectLength" = null;
"gopls" = {
"formatting.gofumpt" = true;
"ui.semanticTokens" = true;
};
"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;
"terminal.integrated.defaultProfile.linux" = "zsh";
"workbench.colorTheme" = "Gruvbox Dark Hard";
};
};
# Language servers etc
home.packages = mkIf config.programs.vscode.enable (with pkgs; [
gopls
nil
nixpkgs-fmt
]);
}

View file

@ -1,7 +1,6 @@
{ config, lib, pkgs, ... }:
{
home.packages = with pkgs; [ direnv ];
programs.zsh = {
enable = true;
enableCompletion = true;
@ -11,12 +10,7 @@
shellAliases = {
ll = "ls -l";
# don't clobber
mv = "mv -i";
rename = "rename -i";
nix-shell = ''nix-shell --command "zsh"'';
nix-shell = ''nix-shell --command "zsh"''; # TODO: tweak theme to display something when inside nix-shell
};
history = {
@ -27,15 +21,10 @@
oh-my-zsh = {
enable = true;
plugins = [ "git" "sudo" "direnv" ];
theme = ""; # defer to powerlevel10k
plugins = [ "git" "sudo" ];
theme = "agnoster";
};
initContent = ''
source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme
source ${./.p10k.zsh}
'';
envExtra = ''
DEFAULT_USER=qenya
'';

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,36 +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" ]; }];
};
}

View file

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

View file

@ -1,52 +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";
fountain.users.qenya.enable = true;
fountain.users.randomcat.enable = true;
fountain.users.trungle.enable = true;
fountain.admins = [ "qenya" "randomcat" ];
qenya.base-server.enable = true;
qenya.services.remote-builder = {
enable = true;
authorizedKeys.keys = [ ];
};
randomcat.services.zfs.datasets = {
"rpool_kalessin/state" = { mountpoint = "none"; };
"rpool_kalessin/state/headscale" = { mountpoint = "/var/lib/headscale"; };
"rpool_kalessin/state/owncast" = { mountpoint = "/var/lib/owncast"; };
};
services.sanoid.datasets."rpool_kalessin/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
};
qenya.services.owncast = {
enable = true;
domain = "live.qenya.tel";
dataDir = "/var/lib/owncast";
};
qenya.services.headscale = {
enable = true;
domain = "headscale.unspecified.systems";
dataDir = "/var/lib/headscale";
};
system.stateVersion = "23.11";
}

View file

@ -35,4 +35,13 @@
};
swapDevices = [ ];
# 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.enp0s6.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View file

@ -1,6 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.enp0s6.useDHCP = true;
}

View file

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

View file

@ -1,66 +0,0 @@
{ config, lib, pkgs, ... }:
let
keys = import ../../keys.nix;
in
{
imports = [
./backup.nix
./filesystems.nix
./hardware.nix
./networking.nix
./plasma.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;
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 ];
};
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,51 +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 ];
# enable playing from bluray drive
boot.kernelModules = [ "sg" ];
environment.systemPackages = [
((pkgs.vlc.override {
libbluray = (pkgs.libbluray.override {
withJava = true;
withAACS = true;
withBDplus = true;
});
}).overrideAttrs (originalAttrs: {
buildInputs = originalAttrs.buildInputs ++ [ pkgs.libdvdcss ];
# TODO: nixpkgs bug: libbluray needs patching to look at the nix store path of jdk17 when searching for a jdk
# as a workaround, wrap vlc and set JAVA_HOME, which it uses instead of searching when specified
nativeBuildInputs = originalAttrs.nativeBuildInputs ++ [ pkgs.makeWrapper ];
postFixup = ''
${originalAttrs.postFixup or ""}
wrapProgram $out/bin/vlc --set JAVA_HOME ${pkgs.jdk17.home}
'';
}))
];
}

View file

@ -1,15 +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";
};
}

View file

@ -1,109 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
let
inherit (lib) mkForce;
in
{
services.xserver.displayManager.gdm.enable = mkForce false;
services.xserver.desktopManager.gnome.enable = mkForce false;
services.displayManager.sddm.enable = true;
services.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
environment.systemPackages = with pkgs; [
(catppuccin-kde.override {
flavour = [ "mocha" ];
accents = [ "mauve" ];
winDecStyles = [ "modern" ];
})
];
home-manager.users.qenya = { pkgs, ... }: {
imports = [
inputs.plasma-manager.homeManagerModules.plasma-manager
];
programs.plasma = {
enable = true;
overrideConfig = true;
workspace = {
lookAndFeel = "Catppuccin-Mocha-Mauve";
colorScheme = "CatppuccinMochaMauve";
splashScreen.engine = "KSplashQML";
splashScreen.theme = "Catppuccin-Mocha-Mauve";
windowDecorations.library = "org.kde.kwin.aurorae";
windowDecorations.theme = "__aurorae__svg__CatppuccinMocha-Modern";
};
# For the moment, this hosts some network-accessible services, so we want it on 24/7
powerdevil.AC.autoSuspend.action = "nothing";
panels = [
# Dock
{
height = 49; # 41 * 1.2
lengthMode = "fit";
location = "bottom";
alignment = "center";
hiding = "dodgewindows";
widgets = [{
name = "org.kde.plasma.icontasks";
config.General = {
fill = false;
iconSpacing = 2;
launchers = lib.concatStringsSep "," [
"applications:firefox.desktop"
"applications:codium.desktop"
"applications:steam.desktop"
"applications:discord.desktop"
"applications:com.obsproject.Studio.desktop"
"applications:org.kde.dolphin.desktop"
"applications:org.kde.konsole.desktop"
"applications:org.kde.plasma-systemmonitor.desktop"
];
maxStripes = 1;
showOnlyCurrentDesktop = false;
showOnlyCurrentScreen = false;
};
}];
screen = "all";
}
# Top bar
{
height = 29; # 24 * 1.2
location = "top";
alignment = "left";
floating = false;
widgets = [
{
name = "org.kde.plasma.kickoff";
config.General = {
lengthFirstMargin = 7;
};
}
{ name = "org.kde.plasma.panelspacer"; }
{
name = "org.kde.plasma.digitalclock";
config.Appearance = {
autoFontAndSize = false;
customDateFormat = "dddd, d MMM";
dateDisplayFormat = "BesideTime";
dateFormat = "custom";
fontFamily = "Inter";
fontStyleName = "Bold";
fontWeight = 700;
boldText = true;
showWeekNumbers = true;
};
}
{ name = "org.kde.plasma.panelspacer"; }
{ name = "org.kde.plasma.systemtray"; }
];
screen = "all";
}
];
};
};
}

View file

@ -0,0 +1,19 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
age.secrets.wireguard-peer-orm.file = ../../secrets/wireguard-peer-orm.age;
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-orm.path;
};
system.stateVersion = "23.11";
}

View file

@ -1,69 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking.hostName = "orm";
networking.hostId = "00000000";
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/private/actual"; };
"rpool_orm/state/postgresql" = { mountpoint = "/var/lib/postgresql"; };
};
services.sanoid.datasets."rpool_orm/state" = {
useTemplate = [ "production" ];
recursive = "zfs";
};
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 Tailscale
authentication = pkgs.lib.mkOverride 10 ''
#type database DBuser auth-method
local all all trust # used by nixos for local monitoring
host sameuser all 100.64.0.0/10 scram-sha-256
host sameuser all fd7a:115c:a1e0::/48 scram-sha-256
'';
};
networking.firewall.interfaces."tailscale0".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";
}

View file

@ -1,6 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.ens3.useDHCP = true;
}

View file

@ -1,19 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
];
nixpkgs.hostPlatform = "aarch64-linux";
networking.hostName = "tehanu";
networking.hostId = "8e1185ab";
fountain.users.qenya.enable = true;
fountain.admins = [ "qenya" ];
qenya.base-server.enable = 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_tehanu/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "rpool_tehanu/nix";
fsType = "zfs";
};
fileSystems."/var" =
{ device = "rpool_tehanu/var";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/629B-BA09";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices = [ ];
}

View file

@ -1,6 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
networking.interfaces.enp0s6.useDHCP = true;
}

View file

@ -0,0 +1,59 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./syncthing.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.editor = false;
age.secrets.wireguard-peer-tohru.file = ../../secrets/wireguard-peer-tohru.age;
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-tohru.path;
persistentKeepalive = 23;
};
programs.evolution.enable = true;
qenya.services.fonts.enable = true;
qenya.services.steam.enable = true;
home-manager.users.qenya = { pkgs, ... }: {
imports = [
./home.nix
];
};
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,69 +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
apostrophe
foliate
nicotine-plus
tuba
# 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, ... }:
{
dconf.enable = true;
programs = {
firefox.enable = true; # TODO: config is not yet nix-ified
vscode.enable = true;
};
home.packages = with pkgs; [
bitwarden
discord
foliate
gimp-with-plugins
jellyfin-media-player
keepassxc
tor-browser-bundle-bin
# libreoffice
libreoffice
hunspell
hunspellDicts.en_GB-ise
# games
openttd
prismlauncher
nur.repos.qenya.digital-a-love-story
nur.repos.qenya.dont-take-it-personally-babe
];
}

View file

@ -1,8 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.useNetworkd = true;
systemd.network.wait-online.enable = false;
networking.networkmanager.enable = true;
}

View file

@ -0,0 +1,41 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
age.secrets.wireguard-peer-yevaud.file = ../../secrets/wireguard-peer-yevaud.age;
birdsong.peering = {
enable = true;
privateKeyFile = config.age.secrets.wireguard-peer-yevaud.path;
};
qenya.services.forgejo = {
enable = true;
domain = "git.qenya.tel";
stateDir = "/data/forgejo";
};
services.nginx = {
enable = true;
virtualHosts = {
"git.katherina.rocks" = {
forceSSL = true;
enableACME = true;
locations."/".return = "301 https://git.qenya.tel$request_uri";
};
"birdsong.network" = {
forceSSL = true;
enableACME = true;
locations."/".return = "301 https://git.qenya.tel/qenya/birdsong/";
};
};
};
system.stateVersion = "23.11";
}

View file

@ -1,49 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
./experiments/pennykettle.nix
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
networking.hostName = "yevaud";
networking.hostId = "09673d65";
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";
};
};
system.stateVersion = "23.11";
}

View file

@ -1,66 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.firewall.allowedUDPPorts = [ 51820 ];
networking.firewall.interfaces."tailscale0".allowedTCPPorts = config.networking.firewall.allowedTCPPorts ++ [ 1080 ];
environment.systemPackages = [ pkgs.wireguard-tools ];
networking.wireguard.interfaces."wg-protonvpn" = {
ips = [ "10.2.0.2/32" ];
peers = [{
allowedIPs = [ "0.0.0.0/0" "::/0" ];
endpoint = "217.138.216.162:51820";
publicKey = "C+u+eQw5yWI2APCfVJwW6Ovj3g4IrTOfe+tMZnNz43s=";
}];
privateKeyFile = config.age.secrets.protonvpn-pennykettle1.path;
listenPort = 51820;
table = "957851094"; # randomly generated
};
networking.localCommands = ''
ip rule add from 10.2.0.2/32 table 957851094
'';
networking.firewall.checkReversePath = "loose";
age.secrets.protonvpn-pennykettle1 = {
file = ../../../secrets/protonvpn-pennykettle1.age;
owner = "root";
group = "systemd-network";
mode = "640";
};
services.dante = {
enable = true;
config = ''
debug: 2
internal: tailscale0
external: wg-protonvpn
# auth/tls handled by tailscale
clientmethod: none
socksmethod: none
# allow connections from tailscale
# "0/0" matches any v4 or v6 address
client pass {
from: 100.64.0.0/10 to: 0/0
log: error connect disconnect
}
client pass {
from: fd7a:115c:a1e0::/48 to: 0/0
log: error connect disconnect
}
socks pass {
from: 0/0 to: 0/0
protocol: tcp udp
log: error connect disconnect iooperation
}
'';
};
systemd.services.dante = {
wants = [ "tailscaled-autoconnect.service" ];
after = [ "tailscaled-autoconnect.service" ];
};
}

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";
}

View file

@ -1,5 +0,0 @@
{ config, lib, pkgs, ... }:
{
networking.interfaces.ens3.useDHCP = true;
}

View file

@ -1,34 +1,19 @@
{
machines = {
reese = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd0qGxvcMLDwX1bqYpwOUL5c/CIgBllMFr+bGkwiwAn root@reese";
bear = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIZ9Kn1CIcDHaleKHf7zO6O30Rbxs/FwL0/Ie+mEjZJr root@bear";
shaw = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw";
groves = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQNZ/Q+x7mDYfYXftpZpWkfPByyMBbYmVFobM4vSDW2 root@groves";
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";
tehanu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ1fNylfLo7Z8m/DroRlj7cHMLhYL7boP3r/upVrtMJQ root@tehanu";
kilgharrah = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgGF3gzzlMbxxk3UAAgHJ7sDdjqtrw7UW16M1XhXtz2 root@kilgharrah";
elucredassa = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+Y/vqGNc1wXUAg4XMAAcLupkggywj2LpYDwA16ONbH root@elucredassa";
carter = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEHHHYG6A995Po05+JXQsvB79ZoIiSOJnW6AiJgVYPic root@carter";
};
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"
];
};
}

80
npins/default.nix Normal file
View file

@ -0,0 +1,80 @@
# 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,
branch ? null,
...
}:
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";
let
urlToName =
url: rev:
let
matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url;
short = builtins.substring 0 7 rev;
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
in
"${if matched == null then "source" else builtins.head matched}${appendShort}";
name = urlToName repository.url revision;
in
builtins.fetchGit {
url = repository.url;
rev = revision;
inherit name;
# 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`"

17
npins/sources.json Normal file
View file

@ -0,0 +1,17 @@
{
"pins": {
"nur": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "nix-community",
"repo": "NUR"
},
"branch": "master",
"revision": "6cbb9fb9c5d55fa2af9a5b0d3185d56c90ad62aa",
"url": "https://github.com/nix-community/NUR/archive/6cbb9fb9c5d55fa2af9a5b0d3185d56c90ad62aa.tar.gz",
"hash": "1w1n56p4hbq1zlz8hiw3169kxsw4cn5maahlk8vdzprs498f69kg"
}
},
"version": 3
}

View file

@ -1,18 +1,19 @@
let
keys = import ./keys.nix;
commonKeys = keys.users.qenya;
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;
protonvpn-pennykettle1 = [ machines.yevaud ] ++ keys.users.qenya;
wireguard-peer-orm = [ machines.orm ];
wireguard-peer-tohru = [ machines.tohru ];
wireguard-peer-yevaud = [ machines.yevaud ];
};
in
builtins.listToAttrs (
map
(secretName: {
name = "secrets/${secretName}.age";
value.publicKeys = secrets."${secretName}";
value.publicKeys = secrets."${secretName}" ++ commonKeys;
})
(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

View file

@ -0,0 +1,10 @@
age-encryption.org/v1
-> ssh-ed25519 l/RSAw +h2Jz8m9ZEklGxWK8HcixO3+D4AVATPI3m3wE1ITviM
US+J+FDPJ/nmLT1ylRGfXyfjiJRgLpdgCg1L3IPrmrc
-> ssh-ed25519 900ILw bX/KdX53EFQCmWI0MU/wKfzqKmAw+/fMs4/955iYOlw
7epwHu5g+p6BHe/ksaA9MAvpneZBwHeqnMtSc1m3FFY
-> !V-grease &x6T2i d0B}!
tkT/G8gEKyx280vDO1QgG5ERBCkR9XCgk8IIE1AeBONi9eo+Z0sGfNHv2DXFx14B
TcKX31wDmUbtv8j+4d7722YeZ4jvKiSuQA38zLREOGJyhA
--- TR/GFMXQ4N6AMuScg8LSednd6jAJugxgCJLegPtFmgI
4>?(Yë×Ã|R5V¡×ù«  ôן4<C5B8>Å'æ[¤K<5F>ë,ϧ —ÅT²Ïkº5öåTC~c×*D[N䃼Þá<ê

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