Compare commits
No commits in common. "main" and "469ba567" have entirely different histories.
|
@ -1,2 +0,0 @@
|
|||
[core]
|
||||
hooksPath = .hooks
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,4 +1 @@
|
|||
result
|
||||
.direnv
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
result
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
|||
[submodule "secrets"]
|
||||
path = secrets
|
||||
url = git@git.jan-leila.com:jan-leila/nix-config-secrets.git
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i bash ../shell.nix
|
||||
|
||||
echo "restoring stashed changes"
|
||||
|
||||
git stash pop -q
|
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i bash ../shell.nix
|
||||
|
||||
echo "stashing all uncommitted changes"
|
||||
git stash -q --keep-index
|
||||
|
||||
echo "checking flakes all compile"
|
||||
nix flake check
|
||||
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "running linter"
|
||||
alejandra -q .
|
||||
|
||||
RESULT=$?
|
||||
|
||||
echo "adding lint changes to commit"
|
||||
git add -u
|
||||
|
||||
exit $RESULT
|
10
.sops.yaml
10
.sops.yaml
|
@ -1,15 +1,7 @@
|
|||
keys:
|
||||
- &leyla age15ga3jmn2mqtlgwwtdcdh6l5vdx6um9aftrkexxfyue6xvcqapqusle75jh
|
||||
creation_rules:
|
||||
- path_regex: secrets/user-passwords.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *leyla
|
||||
- path_regex: secrets/defiant-services.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *leyla
|
||||
- path_regex: secrets/vpn-keys.yaml$
|
||||
- path_regex: secrets/secrets.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *leyla
|
||||
|
|
21
.vscode/settings.json
vendored
21
.vscode/settings.json
vendored
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"attrsets",
|
||||
"bitwarden",
|
||||
"forgejo",
|
||||
"gids",
|
||||
"headscale",
|
||||
"hesperium",
|
||||
"jellyfin",
|
||||
"macvlan",
|
||||
"nextcloud",
|
||||
"nixos",
|
||||
"nixpkgs",
|
||||
"pihole",
|
||||
"pkgs",
|
||||
"rpool",
|
||||
"searx",
|
||||
"ublock",
|
||||
"uids"
|
||||
]
|
||||
}
|
84
README.md
84
README.md
|
@ -1,9 +1,3 @@
|
|||
# nix-config
|
||||
|
||||
https://git.jan-leila.com/jan-leila/nix-config
|
||||
|
||||
nix multi user, multi system, configuration with `sops` secret management, `home-manager`, and `nixos-anywhere` setup via `disko` with `zfs` + `impermanence`
|
||||
|
||||
# Hosts
|
||||
|
||||
## Host Map
|
||||
|
@ -11,60 +5,62 @@ nix multi user, multi system, configuration with `sops` secret management, `home
|
|||
| :---------: | :------------------------: | :--------------: | :-------: |
|
||||
| `twilight` | Desktop Computer | Leyla | Desktop |
|
||||
| `horizon` | 13 inch Framework Laptop | Leyla | Laptop |
|
||||
| `defiant` | NAS Server | Leyla | Server |
|
||||
| `hesperium` | Mac | ????? | ??? |
|
||||
| `emergent` | Desktop Computer | Eve | Desktop |
|
||||
| `threshold` | Laptop | Eve | Laptop |
|
||||
| `wolfram` | Steam Deck | House | Handheld |
|
||||
| `ceder` | A5 Tablet (not using nix) | Leyla | Tablet |
|
||||
| `skate` | A6 Tablet (not using nix) | Leyla | Tablet |
|
||||
| `shale` | A6 Tablet (not using nix) | Eve | Tablet |
|
||||
| `coven` | Pixel 8 (not using nix) | Leyla | Android |
|
||||
| `defiant` | NAS Server | Leyla | Service |
|
||||
| `emergent` | Desktop Computer | Eve | Laptop |
|
||||
| `threshold` | Laptop | Eve | Desktop |
|
||||
|
||||
# Tooling
|
||||
## Rebuilding
|
||||
|
||||
### Rebuild current machine to match target host:
|
||||
`sudo nixos-rebuild switch --flake .#hostname`
|
||||
|
||||
### Rebuild current machine maintaining current target
|
||||
`./rebuild.sh`
|
||||
|
||||
## Updating
|
||||
`nix flake update`
|
||||
# New machine setup
|
||||
keys for decrypting password secrets for each users located at `/var/lib/sops-nix/key.txt`
|
||||
|
||||
updating passwords: `sops secrets/secrets.yaml`
|
||||
|
||||
## New host setup
|
||||
`./install.sh --target 192.168.1.130 --flake hostname`
|
||||
|
||||
## Updating Secrets
|
||||
`sops secrets/secrets_file_here.yaml`
|
||||
> how the current config was set up https://www.youtube.com/watch?v=G5f6GC7SnhU
|
||||
|
||||
## Inspecting a configuration
|
||||
`nix-inspect -p .`
|
||||
> something about ssh keys for remotes
|
||||
|
||||
# Notes:
|
||||
|
||||
## Research topics
|
||||
- Look into this for auto rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/`
|
||||
- Look into this for fixing nixos-anywhere `https://github.com/lucidph3nx/nixos-config/tree/main`
|
||||
- Look into this for rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/`
|
||||
- Look into this for openssh known configurations https://search.nixos.org/options?channel=unstable&from=0&size=15&sort=alpha_asc&type=packages&query=services.openssh
|
||||
- Look into this for flake templates https://nix.dev/manual/nix/2.22/command-ref/new-cli/nix3-flake-init
|
||||
- https://nixos-and-flakes.thiscute.world/
|
||||
- Look into this for headscale https://carlosvaz.com/posts/setting-up-headscale-on-nixos/
|
||||
|
||||
# Updating
|
||||
`nix flake update`
|
||||
|
||||
# Tasks:
|
||||
|
||||
## Tech Debt
|
||||
- monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/)
|
||||
- syncthing folder passwords
|
||||
- nfs export should be backed by the same values for server and client
|
||||
- allowUnfree should be enabled user side not host side (this isn't enabled at all right now for some reason???)
|
||||
- Move configs for pipe mouse, open rgb, and via keyboard to hardware config and install users side from those configs
|
||||
- have nfs binds and exports defined by same code
|
||||
- move services from defiant into own flake
|
||||
- made base domain in nas services configurable
|
||||
- vscode extensions should be in own flake (make sure to add the nixpkgs.overlays in it too)
|
||||
## New Features
|
||||
- GNOME default monitors per hardware configuration?
|
||||
- offline access for nfs mounts (overlay with rsync might be a good option here? https://www.spinics.net/lists/linux-unionfs/msg07105.html note about nfs4 and overlay fs)
|
||||
- samba mounts
|
||||
- Flake templates
|
||||
- Docker parity with existing NAS on defiant
|
||||
- NFS on defiant
|
||||
- firefox declarative???
|
||||
- figure out steam vr things?
|
||||
- Open GL?
|
||||
- util functions
|
||||
- openssh known hosts
|
||||
- limit boot configurations to 2 on defiant
|
||||
- rotate sops encryption keys periodically (and somehow sync between devices?)
|
||||
- zfs email after scrubbing # TODO: test this
|
||||
- wake on LAN for updates
|
||||
- ISO target that contains authorized keys for nixos-anywhere https://github.com/diegofariasm/yggdrasil/blob/4acc43ebc7bcbf2e41376d14268e382007e94d78/hosts/bootstrap/default.nix
|
||||
- zfs encryption FIDO2 2fa (look into shavee)
|
||||
- Secure Boot - https://github.com/nix-community/lanzaboote
|
||||
- SMART test with email results
|
||||
- Create Tor guard/relay server
|
||||
- remote distributed builds - https://nix.dev/tutorials/nixos/distributed-builds-setup.html
|
||||
- migrate away from flakes and move to npins
|
||||
- fix nfs
|
||||
- fix home assistant
|
||||
- create adguard server
|
||||
- zfs email after scrubbing
|
||||
- headscale server
|
||||
- mastodon server
|
||||
- tail scale clients
|
||||
- wake on LAN
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--flake*|-f*)
|
||||
if [[ "$1" != *=* ]]; then shift; fi
|
||||
flake="${1#*=}"
|
||||
;;
|
||||
# --user*|-u*)
|
||||
# if [[ "$1" != *=* ]]; then shift; fi
|
||||
# user="${1#*=}"
|
||||
# ;;
|
||||
--help|-h)
|
||||
echo "--help -h: print this message"
|
||||
echo "--flake -f: set the flake to build an installer for"
|
||||
# echo "--user -u: set the user to install flake as on the target system"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Error: Invalid argument $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
flake=${flake:-"basic"}
|
||||
user=${user:-$USER}
|
||||
|
||||
nix build .#installerConfigurations.$flake.config.system.build.isoImage
|
|
@ -1,16 +0,0 @@
|
|||
{...}: {
|
||||
host = {
|
||||
users = {
|
||||
leyla = {
|
||||
isDesktopUser = true;
|
||||
isTerminalUser = true;
|
||||
isPrincipleUser = true;
|
||||
};
|
||||
eve.isNormalUser = false;
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = 5;
|
||||
|
||||
nixpkgs.hostPlatform = "aarch64-darwin";
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
];
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
osConfig,
|
||||
...
|
||||
}: let
|
||||
users = config.host.users;
|
||||
in {
|
||||
leyla = lib.mkIf users.leyla.isNormalUser (import ./leyla);
|
||||
eve = lib.mkIf users.eve.isNormalUser (import ./eve);
|
||||
git = lib.mkIf (osConfig.services.forgejo.enable or false) (import ./git);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
osConfig,
|
||||
...
|
||||
}: let
|
||||
userConfig = osConfig.host.users.eve;
|
||||
in {
|
||||
nixpkgs.config = {
|
||||
allowUnfree = true;
|
||||
};
|
||||
|
||||
home = {
|
||||
username = userConfig.name;
|
||||
homeDirectory = osConfig.users.users.eve.home;
|
||||
|
||||
# This value determines the Home Manager release that your configuration is
|
||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
||||
# introduces backwards incompatible changes.
|
||||
#
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
stateVersion = "23.11"; # Please read the comment before changing.
|
||||
|
||||
# Home Manager is pretty good at managing dotfiles. The primary way to manage
|
||||
# plain files is through 'home.file'.
|
||||
file = {
|
||||
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
|
||||
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
|
||||
# # symlink to the Nix store copy.
|
||||
# ".screenrc".source = dotfiles/screenrc;
|
||||
|
||||
# # You can also set the file content immediately.
|
||||
# ".gradle/gradle.properties".text = ''
|
||||
# org.gradle.console=verbose
|
||||
# org.gradle.daemon.idletimeout=3600000
|
||||
# '';
|
||||
};
|
||||
|
||||
# Home Manager can also manage your environment variables through
|
||||
# 'home.sessionVariables'. If you don't want to manage your shell through Home
|
||||
# Manager then you have to manually source 'hm-session-vars.sh' located at
|
||||
# either
|
||||
#
|
||||
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
# or
|
||||
#
|
||||
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
# or
|
||||
#
|
||||
# /etc/profiles/per-user/leyla/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
sessionVariables = {
|
||||
# EDITOR = "emacs";
|
||||
};
|
||||
|
||||
packages = lib.lists.optionals userConfig.isDesktopUser (
|
||||
with pkgs; [
|
||||
firefox
|
||||
bitwarden
|
||||
discord
|
||||
makemkv
|
||||
signal-desktop-bin
|
||||
ungoogled-chromium
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
programs = {
|
||||
# Let Home Manager install and manage itself.
|
||||
home-manager.enable = true;
|
||||
};
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
{osConfig, ...}: {
|
||||
home = {
|
||||
username = osConfig.users.users.git.name;
|
||||
homeDirectory = osConfig.users.users.git.home;
|
||||
|
||||
# This value determines the Home Manager release that your configuration is
|
||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
||||
# introduces backwards incompatible changes.
|
||||
#
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
stateVersion = "23.11"; # Please read the comment before changing.
|
||||
};
|
||||
|
||||
programs.ssh.extraConfig = ''
|
||||
AuthorizedKeysFile
|
||||
/var/lib/forgejo/.ssh/authorized_keys
|
||||
'';
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
{pkgs, ...}: {
|
||||
config = {
|
||||
dconf = {
|
||||
enable = true;
|
||||
settings = {
|
||||
"org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
||||
|
||||
"org/gnome/desktop/wm/preferences".button-layout = ":minimize,maximize,close";
|
||||
|
||||
"org/gnome/shell" = {
|
||||
disable-user-extensions = false; # enables user extensions
|
||||
enabled-extensions = [
|
||||
# Put UUIDs of extensions that you want to enable here.
|
||||
# If the extension you want to enable is packaged in nixpkgs,
|
||||
# you can easily get its UUID by accessing its extensionUuid
|
||||
# field (look at the following example).
|
||||
pkgs.gnomeExtensions.dash-to-dock.extensionUuid
|
||||
|
||||
# Alternatively, you can manually pass UUID as a string.
|
||||
# "dash-to-dock@micxgx.gmail.com"
|
||||
];
|
||||
};
|
||||
|
||||
"org/gnome/shell/extensions/dash-to-dock" = {
|
||||
"dock-position" = "LEFT";
|
||||
"intellihide-mode" = "ALL_WINDOWS";
|
||||
"show-trash" = false;
|
||||
"require-pressure-to-show" = false;
|
||||
"show-mounts" = false;
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys" = {
|
||||
custom-keybindings = [
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
|
||||
];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
|
||||
binding = "<Super>t";
|
||||
command = "kgx";
|
||||
name = "Open Terminal";
|
||||
};
|
||||
|
||||
"org/gnome/shell" = {
|
||||
favorite-apps = ["org.gnome.Nautilus.desktop" "firefox.desktop" "codium.desktop" "steam.desktop" "org.gnome.Console.desktop"];
|
||||
# app-picker-layout =
|
||||
# builtins.map (
|
||||
# applications:
|
||||
# lib.hm.gvariant (builtins.listToAttrs (lib.lists.imap0 (i: v: lib.attrsets.nameValuePair v (lib.hm.gvariant.mkVariant "{'position': <${i}>}")) applications))
|
||||
# ) [
|
||||
# [
|
||||
# "org.gnome.Nautilus.desktop"
|
||||
# "bitwarden.desktop"
|
||||
# "firefox.desktop"
|
||||
# "torbrowser.desktop"
|
||||
# "chromium-browser.desktop"
|
||||
# "codium.desktop"
|
||||
# "idea-community.desktop"
|
||||
# "org.gnome.TextEditor.desktop"
|
||||
# "dbeaver.desktop"
|
||||
# "bruno.desktop"
|
||||
# "anki.desktop"
|
||||
# "obsidian.desktop"
|
||||
# "signal-desktop.desktop"
|
||||
# "discord.desktop"
|
||||
# "gimp.desktop"
|
||||
# "org.inkscape.Inkscape.desktop"
|
||||
# "org.kde.krita.desktop"
|
||||
# "davinci-resolve.desktop"
|
||||
# "com.obsproject.Studio.desktop"
|
||||
# "org.freecad.FreeCAD.desktop"
|
||||
# "makemkv.desktop"
|
||||
# "easytag.desktop"
|
||||
# "transmission-gtk.desktop"
|
||||
# ]
|
||||
# [
|
||||
# "SteamVR.desktop"
|
||||
# "Beat Saber.desktop"
|
||||
# "Noun Town.desktop"
|
||||
# "WEBFISHING.desktop"
|
||||
# "Factorio.desktop"
|
||||
# ]
|
||||
# [
|
||||
# "org.gnome.Settings.desktop"
|
||||
# "org.gnome.SystemMonitor.desktop"
|
||||
# "org.gnome.Snapshot.desktop"
|
||||
# "org.gnome.Usage.desktop"
|
||||
# "org.gnome.DiskUtility.desktop"
|
||||
# "org.gnome.Evince.desktop"
|
||||
# "org.gnome.fonts.desktop"
|
||||
# "noisetorch.desktop"
|
||||
# "nvidia-settings.desktop"
|
||||
# "OpnRGB.desktop"
|
||||
# "org.freedesktop.Piper.desktop"
|
||||
# "via-nativia.desktop"
|
||||
# "protonvpn-app.desktop"
|
||||
# "simple-scan.desktop"
|
||||
# ]
|
||||
# ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
{
|
||||
osConfig,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./i18n.nix
|
||||
./packages.nix
|
||||
./impermanence.nix
|
||||
./dconf.nix
|
||||
];
|
||||
|
||||
config = {
|
||||
# Home Manager needs a bit of information about you and the paths it should
|
||||
# manage.
|
||||
home = {
|
||||
username = osConfig.host.users.leyla.name;
|
||||
homeDirectory = osConfig.users.users.leyla.home;
|
||||
|
||||
# This value determines the Home Manager release that your configuration is
|
||||
# compatible with. This helps avoid breakage when a new Home Manager release
|
||||
# introduces backwards incompatible changes.
|
||||
#
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
stateVersion = "23.11"; # Please read the comment before changing.
|
||||
|
||||
# Home Manager is pretty good at managing dotfiles. The primary way to manage
|
||||
# plain files is through 'home.file'.
|
||||
file = {
|
||||
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
|
||||
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
|
||||
# # symlink to the Nix store copy.
|
||||
# ".screenrc".source = dotfiles/screenrc;
|
||||
|
||||
# # You can also set the file content immediately.
|
||||
# ".gradle/gradle.properties".text = ''
|
||||
# org.gradle.console=verbose
|
||||
# org.gradle.daemon.idletimeout=3600000
|
||||
# '';
|
||||
".config/user-dirs.dirs" = {
|
||||
force = true;
|
||||
text = ''
|
||||
# This file is written by xdg-user-dirs-update
|
||||
# If you want to change or add directories, just edit the line you're
|
||||
# interested in. All local changes will be retained on the next run.
|
||||
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
|
||||
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
|
||||
# absolute path. No other format is supported.
|
||||
#
|
||||
XDG_DESKTOP_DIR="$HOME/desktop"
|
||||
XDG_DOWNLOAD_DIR="$HOME/downloads"
|
||||
XDG_DOCUMENTS_DIR="$HOME/documents"
|
||||
XDG_TEMPLATES_DIR="$HOME/documents/templates"
|
||||
XDG_MUSIC_DIR="$HOME/documents/music"
|
||||
XDG_PICTURES_DIR="$HOME/documents/photos"
|
||||
XDG_VIDEOS_DIR="$HOME/documents/videos"
|
||||
XDG_PUBLICSHARE_DIR="$HOME/documents/public"
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
keyboard.layout = "us,it,de";
|
||||
|
||||
# Home Manager can also manage your environment variables through
|
||||
# 'home.sessionVariables'. If you don't want to manage your shell through Home
|
||||
# Manager then you have to manually source 'hm-session-vars.sh' located at
|
||||
# either
|
||||
#
|
||||
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
# or
|
||||
#
|
||||
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
# or
|
||||
#
|
||||
# /etc/profiles/per-user/leyla/etc/profile.d/hm-session-vars.sh
|
||||
#
|
||||
sessionVariables = {
|
||||
# EDITOR = "emacs";
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
# Let Home Manager install and manage itself.
|
||||
home-manager.enable = true;
|
||||
|
||||
# set up git defaults
|
||||
git = {
|
||||
enable = true;
|
||||
userName = "Leyla Becker";
|
||||
userEmail = "git@jan-leila.com";
|
||||
extraConfig.init.defaultBranch = "main";
|
||||
};
|
||||
|
||||
# add direnv to auto load flakes for development
|
||||
direnv = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
nix-direnv.enable = true;
|
||||
config = {
|
||||
global.hide_env_diff = true;
|
||||
whitelist.exact = ["/home/leyla/documents/code/nix-config"];
|
||||
};
|
||||
};
|
||||
bash.enable = true;
|
||||
|
||||
openssh = {
|
||||
authorizedKeys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJHeItmt8TRW43uNcOC+eIurYC7Eunc0V3LGocQqLaYj leyla@horizon"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIILimFIW2exEH/Xo7LtXkqgE04qusvnPNpPWSCeNrFkP leyla@defiant"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKBiZkg1c2aaNHiieBX4cEziqvJVj9pcDfzUrKU/mO0I leyla@twilight"
|
||||
];
|
||||
hostKeys = [
|
||||
{
|
||||
type = "ed25519";
|
||||
path = "${config.home.username}_${osConfig.networking.hostName}_ed25519";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,341 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
profiles.leyla = {
|
||||
settings = {
|
||||
"browser.search.defaultenginename" = "Searx";
|
||||
"browser.search.order.1" = "Searx";
|
||||
};
|
||||
|
||||
search = {
|
||||
force = true;
|
||||
default = "Searx";
|
||||
engines = {
|
||||
"Nix Packages" = {
|
||||
urls = [
|
||||
{
|
||||
template = "https://search.nixos.org/packages";
|
||||
params = [
|
||||
{
|
||||
name = "type";
|
||||
value = "packages";
|
||||
}
|
||||
{
|
||||
name = "query";
|
||||
value = "{searchTerms}";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
|
||||
definedAliases = ["@np"];
|
||||
};
|
||||
"NixOS Wiki" = {
|
||||
urls = [{template = "https://nixos.wiki/index.php?search={searchTerms}";}];
|
||||
icon = "https://nixos.wiki/favicon.png";
|
||||
updateInterval = 24 * 60 * 60 * 1000; # every day
|
||||
definedAliases = ["@nw"];
|
||||
};
|
||||
"Searx" = {
|
||||
urls = [{template = "https://search.jan-leila.com/?q={searchTerms}";}];
|
||||
icon = "https://nixos.wiki/favicon.png";
|
||||
updateInterval = 24 * 60 * 60 * 1000; # every day
|
||||
definedAliases = ["@searx"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extensions.packages = with inputs.firefox-addons.packages.${pkgs.system}; [
|
||||
bitwarden
|
||||
terms-of-service-didnt-read
|
||||
multi-account-containers
|
||||
shinigami-eyes
|
||||
|
||||
ublock-origin
|
||||
sponsorblock
|
||||
dearrow
|
||||
df-youtube
|
||||
return-youtube-dislikes
|
||||
|
||||
privacy-badger
|
||||
decentraleyes
|
||||
clearurls
|
||||
localcdn
|
||||
|
||||
snowflake
|
||||
|
||||
deutsch-de-language-pack
|
||||
dictionary-german
|
||||
|
||||
# (
|
||||
# buildFirefoxXpiAddon rec {
|
||||
# pname = "italiano-it-language-pack";
|
||||
# version = "132.0.20241110.231641";
|
||||
# addonId = "langpack-it@firefox.mozilla.org";
|
||||
# url = "https://addons.mozilla.org/firefox/downloads/file/4392453/italiano_it_language_pack-${version}.xpi";
|
||||
# sha256 = "";
|
||||
# meta = with lib;
|
||||
# {
|
||||
# description = "Firefox Language Pack for Italiano (it) – Italian";
|
||||
# license = licenses.mpl20;
|
||||
# mozPermissions = [];
|
||||
# platforms = platforms.all;
|
||||
# };
|
||||
# }
|
||||
# )
|
||||
# (
|
||||
# buildFirefoxXpiAddon rec {
|
||||
# pname = "dizionario-italiano";
|
||||
# version = "5.1";
|
||||
# addonId = "it-IT@dictionaries.addons.mozilla.org";
|
||||
# url = "https://addons.mozilla.org/firefox/downloads/file/1163874/dizionario_italiano-${version}.xpi";
|
||||
# sha256 = "";
|
||||
# meta = with lib;
|
||||
# {
|
||||
# description = "Add support for Italian to spellchecking";
|
||||
# license = licenses.gpl3;
|
||||
# mozPermissions = [];
|
||||
# platforms = platforms.all;
|
||||
# };
|
||||
# }
|
||||
# )
|
||||
];
|
||||
|
||||
settings = {
|
||||
# Disable irritating first-run stuff
|
||||
"browser.disableResetPrompt" = true;
|
||||
"browser.download.panel.shown" = true;
|
||||
"browser.feeds.showFirstRunUI" = false;
|
||||
"browser.messaging-system.whatsNewPanel.enabled" = false;
|
||||
"browser.rights.3.shown" = true;
|
||||
"browser.shell.checkDefaultBrowser" = false;
|
||||
"browser.shell.defaultBrowserCheckCount" = 1;
|
||||
"browser.startup.homepage_override.mstone" = "ignore";
|
||||
"browser.uitour.enabled" = false;
|
||||
"startup.homepage_override_url" = "";
|
||||
"trailhead.firstrun.didSeeAboutWelcome" = true;
|
||||
"browser.bookmarks.restore_default_bookmarks" = false;
|
||||
"browser.bookmarks.addedImportButton" = true;
|
||||
|
||||
# Usage Experiance
|
||||
"browser.startup.homepage" = "about:home";
|
||||
"browser.download.useDownloadDir" = false;
|
||||
"browser.uiCustomization.state" = builtins.toJSON {
|
||||
"currentVersion" = 20;
|
||||
"newElementCount" = 6;
|
||||
"dirtyAreaCache" = [
|
||||
"nav-bar"
|
||||
"PersonalToolbar"
|
||||
"toolbar-menubar"
|
||||
"TabsToolbar"
|
||||
"unified-extensions-area"
|
||||
"vertical-tabs"
|
||||
];
|
||||
"placements" = {
|
||||
"widget-overflow-fixed-list" = [];
|
||||
"unified-extensions-area" = [
|
||||
"privacy_privacy_com-browser-action"
|
||||
# bitwarden
|
||||
"_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action"
|
||||
"ublock0_raymondhill_net-browser-action"
|
||||
"sponsorblocker_ajay_app-browser-action"
|
||||
"dearrow_ajay_app-browser-action"
|
||||
"jid1-mnnxcxisbpnsxq_jetpack-browser-action"
|
||||
"_testpilot-containers-browser-action"
|
||||
"addon_simplelogin-browser-action"
|
||||
"_74145f27-f039-47ce-a470-a662b129930a_-browser-action"
|
||||
"jid1-bofifl9vbdl2zq_jetpack-browser-action"
|
||||
"dfyoutube_example_com-browser-action"
|
||||
"_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action"
|
||||
"_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action"
|
||||
"_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browse-action"
|
||||
"jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action"
|
||||
];
|
||||
"nav-bar" = [
|
||||
"back-button"
|
||||
"forward-button"
|
||||
"stop-reload-button"
|
||||
"urlbar-container"
|
||||
"downloads-button"
|
||||
"unified-extensions-button"
|
||||
"reset-pbm-toolbar-button"
|
||||
];
|
||||
"toolbar-menubar" = [
|
||||
"menubar-items"
|
||||
];
|
||||
"TabsToolbar" = [
|
||||
"firefox-view-button"
|
||||
"tabbrowser-tabs"
|
||||
"new-tab-button"
|
||||
"alltabs-button"
|
||||
];
|
||||
"vertical-tabs" = [];
|
||||
"PersonalToolbar" = [
|
||||
"import-button"
|
||||
"personal-bookmarks"
|
||||
];
|
||||
};
|
||||
"seen" = [
|
||||
"save-to-pocket-button"
|
||||
"developer-button"
|
||||
"privacy_privacy_com-browser-action"
|
||||
"sponsorblocker_ajay_app-browser-action"
|
||||
"ublock0_raymondhill_net-browser-action"
|
||||
"addon_simplelogin-browser-action"
|
||||
"dearrow_ajay_app-browser-action"
|
||||
"_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action"
|
||||
"_74145f27-f039-47ce-a470-a662b129930a_-browser-action"
|
||||
"jid1-bofifl9vbdl2zq_jetpack-browser-action"
|
||||
"dfyoutube_example_com-browser-action"
|
||||
"_testpilot-containers-browser-action"
|
||||
"_b86e4813-687a-43e6-ab65-0bde4ab75758_-browser-action"
|
||||
"jid1-mnnxcxisbpnsxq_jetpack-browser-action"
|
||||
"_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action"
|
||||
"_b11bea1f-a888-4332-8d8a-cec2be7d24b9_-browser-action"
|
||||
"jid0-3guet1r69sqnsrca5p8kx9ezc3u_jetpack-browser-action"
|
||||
];
|
||||
};
|
||||
"browser.newtabpage.activity-stream.feeds.topsites" = false;
|
||||
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
|
||||
"browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false;
|
||||
"browser.newtabpage.blocked" = lib.genAttrs [
|
||||
# Facebook
|
||||
"4gPpjkxgZzXPVtuEoAL9Ig=="
|
||||
# Reddit
|
||||
"gLv0ja2RYVgxKdp0I5qwvA=="
|
||||
# Amazon
|
||||
"K00ILysCaEq8+bEqV/3nuw=="
|
||||
# Twitter
|
||||
"T9nJot5PurhJSy8n038xGA=="
|
||||
] (_: 1);
|
||||
"identity.fxaccounts.enabled" = false;
|
||||
|
||||
# Security
|
||||
"privacy.trackingprotection.enabled" = true;
|
||||
"dom.security.https_only_mode" = true;
|
||||
|
||||
"extensions.formautofill.addresses.enabled" = false;
|
||||
"extensions.formautofill.creditCards.enabled" = false;
|
||||
"signon.rememberSignons" = false;
|
||||
"privacy.sanitize.sanitizeOnShutdown" = true;
|
||||
"privacy.clearOnShutdown_v2.cache" = true;
|
||||
"privacy.clearOnShutdown_v2.cookiesAndStorage" = true;
|
||||
"privacy.clearOnShutdown_v2.historyFormDataAndDownloads" = true;
|
||||
"urlclassifier.trackingSkipURLs" = "";
|
||||
"urlclassifier.features.socialtracking.skipURLs" = "";
|
||||
"dom.security.https_only_mode_pbm" = true;
|
||||
"dom.security.https_only_mode_error_page_user_suggestions" = true;
|
||||
|
||||
# Disable telemetry
|
||||
"app.shield.optoutstudies.enabled" = false;
|
||||
"browser.discovery.enabled" = false;
|
||||
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
|
||||
"browser.newtabpage.activity-stream.telemetry" = false;
|
||||
"browser.ping-centre.telemetry" = false;
|
||||
"datareporting.healthreport.service.enabled" = false;
|
||||
"datareporting.healthreport.uploadEnabled" = false;
|
||||
"datareporting.policy.dataSubmissionEnabled" = false;
|
||||
"datareporting.sessions.current.clean" = true;
|
||||
"devtools.onboarding.telemetry.logged" = false;
|
||||
"toolkit.telemetry.archive.enabled" = false;
|
||||
"toolkit.telemetry.bhrPing.enabled" = false;
|
||||
"toolkit.telemetry.enabled" = false;
|
||||
"toolkit.telemetry.firstShutdownPing.enabled" = false;
|
||||
"toolkit.telemetry.hybridContent.enabled" = false;
|
||||
"toolkit.telemetry.newProfilePing.enabled" = false;
|
||||
"toolkit.telemetry.prompted" = 2;
|
||||
"toolkit.telemetry.rejected" = true;
|
||||
"toolkit.telemetry.reportingpolicy.firstRun" = false;
|
||||
"toolkit.telemetry.server" = "";
|
||||
"toolkit.telemetry.shutdownPingSender.enabled" = false;
|
||||
"toolkit.telemetry.unified" = false;
|
||||
"toolkit.telemetry.unifiedIsOptIn" = false;
|
||||
"toolkit.telemetry.updatePing.enabled" = false;
|
||||
};
|
||||
|
||||
bookmarks = {
|
||||
force = true;
|
||||
settings = [
|
||||
{
|
||||
name = "Media";
|
||||
url = "https://media.jan-leila.com/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Photos";
|
||||
url = "https://photos.jan-leila.com";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Git";
|
||||
url = "https://git.jan-leila.com/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Home Automation";
|
||||
url = "https://home.jan-leila.com/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Mail";
|
||||
url = "https://mail.protonmail.com";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Open Street Map";
|
||||
url = "https://www.openstreetmap.org/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Password Manager";
|
||||
url = "https://vault.bitwarden.com/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Mastodon";
|
||||
url = "https://mspsocial.net";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Linked In";
|
||||
url = "https://www.linkedin.com/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "Job Search";
|
||||
url = "https://www.jobsinnetwork.com/?state=cleaned_history&language%5B%5D=en&query=react&locations.countryCode%5B%5D=IT&locations.countryCode%5B%5D=DE&locations.countryCode%5B%5D=NL&experience%5B%5D=medior&experience%5B%5D=junior&page=1";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
{
|
||||
name = "React Docs";
|
||||
url = "https://react.dev/";
|
||||
keyword = "";
|
||||
tags = [""];
|
||||
}
|
||||
# Template
|
||||
# {
|
||||
# name = "";
|
||||
# url = "";
|
||||
# keyword = "";
|
||||
# tags = [""];
|
||||
# }
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{...}: {
|
||||
i18n = {
|
||||
defaultLocale = "en_IE.UTF-8";
|
||||
|
||||
extraLocaleSettings = {
|
||||
# LC_ADDRESS = "en_IE.UTF-8"; # lets just get used to this one now
|
||||
# LC_TELEPHONE = "en_IE.UTF-8"; # lets just get used to this one now
|
||||
LC_MONETARY = "en_US.UTF-8"; # to be changed once I move
|
||||
LC_PAPER = "en_US.UTF-8"; # convenient for american printers until I move
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
osConfig,
|
||||
...
|
||||
}: {
|
||||
config = lib.mkIf osConfig.host.impermanence.enable {
|
||||
home.persistence."/persist/home/leyla" = {
|
||||
directories = [
|
||||
"desktop"
|
||||
"downloads"
|
||||
"documents"
|
||||
{
|
||||
directory = ".local/share/Steam";
|
||||
method = "symlink";
|
||||
}
|
||||
];
|
||||
files = [
|
||||
".bash_history" # keep shell history around
|
||||
".local/share/recently-used.xbel" # gnome recently viewed files
|
||||
];
|
||||
allowOther = true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
osConfig,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
userConfig = osConfig.host.users.leyla;
|
||||
hardware = osConfig.host.hardware;
|
||||
in {
|
||||
imports = [
|
||||
./vscode.nix
|
||||
./firefox.nix
|
||||
];
|
||||
|
||||
nixpkgs.config = {
|
||||
allowUnfree = true;
|
||||
};
|
||||
|
||||
home = {
|
||||
packages =
|
||||
lib.lists.optionals userConfig.isTerminalUser (
|
||||
with pkgs; [
|
||||
# command line tools
|
||||
sox
|
||||
yt-dlp
|
||||
ffmpeg
|
||||
imagemagick
|
||||
]
|
||||
)
|
||||
++ (
|
||||
lib.lists.optionals userConfig.isDesktopUser (
|
||||
(with pkgs; [
|
||||
# helvetica font
|
||||
aileron
|
||||
|
||||
gnomeExtensions.dash-to-dock
|
||||
|
||||
# development tools
|
||||
dbeaver-bin
|
||||
bruno
|
||||
proxmark3
|
||||
])
|
||||
++ (
|
||||
lib.lists.optionals hardware.directAccess.enable (with pkgs; [
|
||||
#foss platforms
|
||||
signal-desktop-bin
|
||||
bitwarden
|
||||
ungoogled-chromium
|
||||
libreoffice
|
||||
inkscape
|
||||
gimp
|
||||
krita
|
||||
freecad
|
||||
# cura
|
||||
# kicad-small
|
||||
makemkv
|
||||
onionshare
|
||||
# rhythmbox
|
||||
(lib.mkIf hardware.graphicsAcceleration.enable obs-studio)
|
||||
# wireshark
|
||||
# rpi-imager
|
||||
# fritzing
|
||||
mfoc
|
||||
tor-browser
|
||||
anki
|
||||
pdfarranger
|
||||
calibre
|
||||
qbittorrent
|
||||
picard
|
||||
|
||||
# proprietary platforms
|
||||
discord
|
||||
obsidian
|
||||
(lib.mkIf hardware.graphicsAcceleration.enable davinci-resolve)
|
||||
|
||||
# development tools
|
||||
# androidStudioPackages.canary
|
||||
jetbrains.idea-community
|
||||
qFlipper
|
||||
|
||||
# system tools
|
||||
protonvpn-gui
|
||||
openvpn
|
||||
noisetorch
|
||||
|
||||
# hardware management tools
|
||||
(lib.mkIf hardware.piperMouse.enable piper)
|
||||
(lib.mkIf hardware.openRGB.enable openrgb)
|
||||
(lib.mkIf hardware.viaKeyboard.enable via)
|
||||
])
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
osConfig,
|
||||
...
|
||||
}: let
|
||||
nix-development-enabled = osConfig.host.nix-development.enable;
|
||||
in {
|
||||
nixpkgs = {
|
||||
overlays = [
|
||||
inputs.nix-vscode-extensions.overlays.default
|
||||
];
|
||||
};
|
||||
|
||||
programs = {
|
||||
bash.shellAliases = {
|
||||
code = "codium";
|
||||
};
|
||||
|
||||
vscode = let
|
||||
extensions = inputs.nix-vscode-extensions.extensions.${pkgs.system};
|
||||
open-vsx = extensions.open-vsx;
|
||||
vscode-marketplace = extensions.vscode-marketplace;
|
||||
in {
|
||||
enable = true;
|
||||
|
||||
package = pkgs.vscodium;
|
||||
|
||||
mutableExtensionsDir = false;
|
||||
|
||||
profiles.default = {
|
||||
enableUpdateCheck = false;
|
||||
enableExtensionUpdateCheck = false;
|
||||
|
||||
userSettings = lib.mkMerge [
|
||||
{
|
||||
"workbench.colorTheme" = "Atom One Dark";
|
||||
"cSpell.userWords" = [
|
||||
"webdav"
|
||||
];
|
||||
"javascript.updateImportsOnFileMove.enabled" = "always";
|
||||
"editor.tabSize" = 2;
|
||||
"editor.insertSpaces" = false;
|
||||
}
|
||||
(lib.mkIf nix-development-enabled {
|
||||
"nix.enableLanguageServer" = true;
|
||||
"nix.serverPath" = "nil";
|
||||
"[nix]" = {
|
||||
"editor.defaultFormatter" = "kamadorueda.alejandra";
|
||||
"editor.formatOnPaste" = true;
|
||||
"editor.formatOnSave" = true;
|
||||
"editor.formatOnType" = true;
|
||||
};
|
||||
"alejandra.program" = "alejandra";
|
||||
"nixpkgs" = {
|
||||
"expr" = "import <nixpkgs> {}";
|
||||
};
|
||||
})
|
||||
(lib.mkIf osConfig.services.ollama.enable {
|
||||
"twinny.fileContextEnabled" = true;
|
||||
"twinny.enableLogging" = false;
|
||||
"twinny.completionCacheEnabled" = true;
|
||||
|
||||
# builtins.elemAt osConfig.services.ollama.loadModels 0;
|
||||
})
|
||||
];
|
||||
|
||||
extensions = (
|
||||
with open-vsx;
|
||||
[
|
||||
# vs code feel extensions
|
||||
ms-vscode.atom-keybindings
|
||||
akamud.vscode-theme-onedark
|
||||
streetsidesoftware.code-spell-checker
|
||||
streetsidesoftware.code-spell-checker-german
|
||||
streetsidesoftware.code-spell-checker-italian
|
||||
jeanp413.open-remote-ssh
|
||||
|
||||
# html extensions
|
||||
formulahendry.auto-rename-tag
|
||||
ms-vscode.live-server
|
||||
|
||||
# js extensions
|
||||
dsznajder.es7-react-js-snippets
|
||||
dbaeumer.vscode-eslint
|
||||
standard.vscode-standard
|
||||
firsttris.vscode-jest-runner
|
||||
stylelint.vscode-stylelint
|
||||
tauri-apps.tauri-vscode
|
||||
|
||||
# go extensions
|
||||
golang.go
|
||||
|
||||
# astro blog extensions
|
||||
astro-build.astro-vscode
|
||||
unifiedjs.vscode-mdx
|
||||
|
||||
# misc extensions
|
||||
tamasfe.even-better-toml
|
||||
]
|
||||
++ (
|
||||
lib.lists.optionals osConfig.services.ollama.enable [
|
||||
rjmacarthy.twinny
|
||||
]
|
||||
)
|
||||
++ (lib.lists.optionals nix-development-enabled [
|
||||
# nix extensions
|
||||
pinage404.nix-extension-pack
|
||||
jnoortheen.nix-ide
|
||||
kamadorueda.alejandra
|
||||
])
|
||||
++ (
|
||||
with vscode-marketplace; [
|
||||
# js extensions
|
||||
karyfoundation.nearley
|
||||
]
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
osConfig,
|
||||
...
|
||||
}: let
|
||||
nix-development-enabled = osConfig.host.nix-development.enable;
|
||||
in {
|
||||
nixpkgs = {
|
||||
overlays = [
|
||||
inputs.nix-vscode-extensions.overlays.default
|
||||
];
|
||||
};
|
||||
|
||||
programs = {
|
||||
bash.shellAliases = {
|
||||
code = "codium";
|
||||
};
|
||||
|
||||
vscode = let
|
||||
extensions = inputs.nix-vscode-extensions.extensions.${pkgs.system};
|
||||
open-vsx = extensions.open-vsx;
|
||||
vscode-marketplace = extensions.vscode-marketplace;
|
||||
in {
|
||||
enable = true;
|
||||
|
||||
package = pkgs.vscodium;
|
||||
|
||||
mutableExtensionsDir = false;
|
||||
enableUpdateCheck = false;
|
||||
enableExtensionUpdateCheck = false;
|
||||
|
||||
userSettings = lib.mkMerge [
|
||||
{
|
||||
"workbench.colorTheme" = "Atom One Dark";
|
||||
"cSpell.language" = "en,de-DE,it";
|
||||
"cSpell.userWords" = import ./user-words.nix;
|
||||
}
|
||||
(lib.mkIf nix-development-enabled {
|
||||
"nix.enableLanguageServer" = true;
|
||||
"nix.serverPath" = "nil";
|
||||
"[nix]" = {
|
||||
"editor.defaultFormatter" = "kamadorueda.alejandra";
|
||||
"editor.formatOnPaste" = true;
|
||||
"editor.formatOnSave" = true;
|
||||
"editor.formatOnType" = true;
|
||||
};
|
||||
"alejandra.program" = "alejandra";
|
||||
"nixpkgs" = {
|
||||
"expr" = "import <nixpkgs> {}";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
extensions = (
|
||||
with open-vsx;
|
||||
[
|
||||
# vs code feel extensions
|
||||
ms-vscode.atom-keybindings
|
||||
akamud.vscode-theme-onedark
|
||||
streetsidesoftware.code-spell-checker
|
||||
streetsidesoftware.code-spell-checker-german
|
||||
streetsidesoftware.code-spell-checker-italian
|
||||
jeanp413.open-remote-ssh
|
||||
|
||||
# html extensions
|
||||
formulahendry.auto-rename-tag
|
||||
ms-vscode.live-server
|
||||
|
||||
# js extensions
|
||||
dsznajder.es7-react-js-snippets
|
||||
dbaeumer.vscode-eslint
|
||||
standard.vscode-standard
|
||||
firsttris.vscode-jest-runner
|
||||
stylelint.vscode-stylelint
|
||||
tauri-apps.tauri-vscode
|
||||
|
||||
# astro blog extensions
|
||||
astro-build.astro-vscode
|
||||
unifiedjs.vscode-mdx
|
||||
|
||||
# misc extensions
|
||||
bungcip.better-toml
|
||||
]
|
||||
++ (lib.lists.optionals nix-development-enabled [
|
||||
# nix extensions
|
||||
pinage404.nix-extension-pack
|
||||
jnoortheen.nix-ide
|
||||
kamadorueda.alejandra
|
||||
])
|
||||
++ (
|
||||
with vscode-marketplace; [
|
||||
# js extensions
|
||||
karyfoundation.nearley
|
||||
]
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
[
|
||||
"leyla"
|
||||
]
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [(modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")];
|
||||
|
||||
systemd.services.sshd.wantedBy = pkgs.lib.mkForce ["multi-user.target"];
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AaAeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee username@host"
|
||||
];
|
||||
|
||||
isoImage.squashfsCompression = "gzip -Xcompression-level 1";
|
||||
|
||||
networking.hostName = "installer";
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
];
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
# server nas
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
sops.secrets = {
|
||||
"vpn-keys/tailscale-authkey/defiant" = {
|
||||
sopsFile = "${inputs.secrets}/vpn-keys.yaml";
|
||||
};
|
||||
"vpn-keys/proton-wireguard/defiant-p2p" = {
|
||||
sopsFile = "${inputs.secrets}/vpn-keys.yaml";
|
||||
mode = "0640";
|
||||
owner = "root";
|
||||
group = "systemd-network";
|
||||
};
|
||||
"services/zfs_smtp_token" = {
|
||||
sopsFile = "${inputs.secrets}/defiant-services.yaml";
|
||||
};
|
||||
};
|
||||
|
||||
host = {
|
||||
users = {
|
||||
leyla = {
|
||||
isDesktopUser = true;
|
||||
isTerminalUser = true;
|
||||
isPrincipleUser = true;
|
||||
};
|
||||
};
|
||||
impermanence.enable = true;
|
||||
storage = {
|
||||
enable = true;
|
||||
encryption = true;
|
||||
notifications = {
|
||||
enable = true;
|
||||
host = "smtp.protonmail.ch";
|
||||
port = 587;
|
||||
to = "leyla@jan-leila.com";
|
||||
user = "leyla@jan-leila.com";
|
||||
tokenFile = config.sops.secrets."services/zfs_smtp_token".path;
|
||||
};
|
||||
pool = {
|
||||
drives = [
|
||||
"ata-ST18000NE000-3G6101_ZVTCXVEB"
|
||||
"ata-ST18000NE000-3G6101_ZVTCXWSC"
|
||||
"ata-ST18000NE000-3G6101_ZVTD10EH"
|
||||
"ata-ST18000NT001-3NF101_ZVTE0S3Q"
|
||||
"ata-ST18000NT001-3NF101_ZVTEF27J"
|
||||
"ata-ST18000NT001-3NF101_ZVTEZACV" # this one is broken replace with "ata-ST18000NT001-XXXXXX_ZVTJ732N"
|
||||
];
|
||||
cache = [
|
||||
"nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"
|
||||
];
|
||||
};
|
||||
};
|
||||
network_storage = {
|
||||
enable = true;
|
||||
directories = [
|
||||
{
|
||||
folder = "leyla_documents";
|
||||
user = "leyla";
|
||||
group = "leyla";
|
||||
bind = "/home/leyla/documents";
|
||||
}
|
||||
{
|
||||
folder = "eve_documents";
|
||||
user = "eve";
|
||||
group = "eve";
|
||||
}
|
||||
{
|
||||
folder = "users_documents";
|
||||
user = "root";
|
||||
group = "users";
|
||||
}
|
||||
{
|
||||
folder = "media";
|
||||
user = "jellyfin";
|
||||
group = "jellyfin_media";
|
||||
bind = config.services.jellyfin.media_directory;
|
||||
}
|
||||
];
|
||||
nfs = {
|
||||
enable = true;
|
||||
directories = ["leyla_documents" "eve_documents" "users_documents" "media"];
|
||||
};
|
||||
};
|
||||
reverse_proxy = {
|
||||
enable = true;
|
||||
enableACME = true;
|
||||
hostname = "jan-leila.com";
|
||||
};
|
||||
postgres = {
|
||||
extraUsers = {
|
||||
leyla = {
|
||||
isAdmin = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
# home-assistant = {
|
||||
# enable = false;
|
||||
# subdomain = "home";
|
||||
# };
|
||||
adguardhome = {
|
||||
enable = false;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
|
||||
# config = {
|
||||
# routeTables = {
|
||||
# p2p = 1;
|
||||
# };
|
||||
# };
|
||||
|
||||
netdevs = {
|
||||
"10-bond0" = {
|
||||
netdevConfig = {
|
||||
Kind = "bond";
|
||||
Name = "bond0";
|
||||
};
|
||||
bondConfig = {
|
||||
Mode = "802.3ad";
|
||||
TransmitHashPolicy = "layer3+4";
|
||||
};
|
||||
};
|
||||
|
||||
# "15-p2p0" = {
|
||||
# netdevConfig = {
|
||||
# Kind = "wireguard";
|
||||
# Name = "p2p0";
|
||||
# MTUBytes = "1280";
|
||||
# };
|
||||
# wireguardConfig = {
|
||||
# PrivateKeyFile = config.sops.secrets."vpn-keys/proton-wireguard/defiant-p2p".path;
|
||||
# ListenPort = 51820;
|
||||
# # RouteTable = "p2p";
|
||||
# };
|
||||
# wireguardPeers = [
|
||||
# {
|
||||
# PublicKey = "rRO6yJim++Ezz6scCLMaizI+taDjU1pzR2nfW6qKbW0=";
|
||||
# Endpoint = "185.230.126.146:51820";
|
||||
# AllowedIPs = ["0.0.0.0/0"];
|
||||
# RouteTable = "off";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
};
|
||||
networks = {
|
||||
"40-bond0" = {
|
||||
matchConfig.Name = "bond0";
|
||||
linkConfig = {
|
||||
RequiredForOnline = "degraded-carrier";
|
||||
RequiredFamilyForOnline = "any";
|
||||
};
|
||||
networkConfig.DHCP = "yes";
|
||||
|
||||
address = [
|
||||
"192.168.1.10/32"
|
||||
];
|
||||
|
||||
gateway = ["192.168.1.1"];
|
||||
dns = ["192.168.1.1"];
|
||||
};
|
||||
|
||||
# "45-p2p0" = {
|
||||
# matchConfig.Name = "p2p0";
|
||||
# address = [
|
||||
# "10.2.0.2/32"
|
||||
# ];
|
||||
# routes = [
|
||||
# {
|
||||
# Destination = "0.0.0.0/0";
|
||||
# }
|
||||
# ];
|
||||
# linkConfig.RequiredForOnline = false;
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
# TODO: move zfs scrubbing into module
|
||||
zfs = {
|
||||
autoScrub.enable = true;
|
||||
autoSnapshot.enable = true;
|
||||
};
|
||||
|
||||
# temp enable desktop enviroment for setup
|
||||
# Enable the X11 windowing system.
|
||||
xserver = {
|
||||
enable = true;
|
||||
|
||||
# Enable the GNOME Desktop Environment.
|
||||
displayManager = {
|
||||
gdm.enable = true;
|
||||
};
|
||||
desktopManager = {
|
||||
gnome.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
ollama = {
|
||||
enable = false;
|
||||
|
||||
loadModels = [
|
||||
"deepseek-coder:6.7b"
|
||||
"deepseek-r1:8b"
|
||||
"deepseek-r1:32b"
|
||||
"deepseek-r1:70b"
|
||||
];
|
||||
};
|
||||
tailscale = {
|
||||
enable = true;
|
||||
authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/defiant".path;
|
||||
useRoutingFeatures = "server";
|
||||
extraUpFlags = [
|
||||
"--advertise-exit-node"
|
||||
"--advertise-routes=192.168.0.0/24"
|
||||
"--accept-dns=false"
|
||||
];
|
||||
extraSetFlags = [
|
||||
"--advertise-exit-node"
|
||||
"--advertise-routes=192.168.0.0/24"
|
||||
"--accept-dns=false"
|
||||
];
|
||||
};
|
||||
|
||||
syncthing.enable = true;
|
||||
|
||||
fail2ban.enable = true;
|
||||
|
||||
jellyfin = {
|
||||
enable = true;
|
||||
subdomain = "media";
|
||||
extraSubdomains = ["jellyfin"];
|
||||
};
|
||||
|
||||
immich = {
|
||||
enable = true;
|
||||
subdomain = "photos";
|
||||
};
|
||||
|
||||
forgejo = {
|
||||
enable = true;
|
||||
subdomain = "git";
|
||||
};
|
||||
|
||||
searx = {
|
||||
enable = true;
|
||||
subdomain = "search";
|
||||
};
|
||||
|
||||
virt-home-assistant = {
|
||||
enable = false;
|
||||
networkBridge = "bond0";
|
||||
hostDevice = "0x10c4:0xea60";
|
||||
};
|
||||
|
||||
qbittorrent = {
|
||||
enable = true;
|
||||
mediaDir = "/srv/qbittorent";
|
||||
openFirewall = true;
|
||||
webPort = 8084;
|
||||
};
|
||||
};
|
||||
|
||||
# disable computer sleeping
|
||||
systemd.targets = {
|
||||
sleep.enable = false;
|
||||
suspend.enable = false;
|
||||
hibernate.enable = false;
|
||||
hybrid-sleep.enable = false;
|
||||
};
|
||||
services.xserver.displayManager.gdm.autoSuspend = false;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It's perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# server nas
|
||||
{...}: {
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./configuration.nix
|
||||
];
|
||||
}
|
|
@ -1,63 +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,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = ["xhci_pci" "aacraid" "ahci" "usbhid" "nvme" "usb_storage" "sd_mod"];
|
||||
kernelModules = [];
|
||||
};
|
||||
kernelModules = ["kvm-amd"];
|
||||
extraModulePackages = [];
|
||||
|
||||
# Bootloader.
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi = {
|
||||
canTouchEfiVariables = true;
|
||||
efiSysMountPoint = "/boot";
|
||||
};
|
||||
};
|
||||
supportedFilesystems = ["zfs"];
|
||||
|
||||
zfs.extraPools = ["rpool"];
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = "defiant"; # Define your hostname.
|
||||
hostId = "c51763d6";
|
||||
useNetworkd = true;
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
|
||||
networks = {
|
||||
"30-eno1" = {
|
||||
matchConfig.Name = "eno1";
|
||||
networkConfig.Bond = "bond0";
|
||||
};
|
||||
"30-eno2" = {
|
||||
matchConfig.Name = "eno2";
|
||||
networkConfig.Bond = "bond0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware = {
|
||||
# TODO: hardware graphics
|
||||
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
};
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
{
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
inputs.nixos-hardware.nixosModules.framework-11th-gen-intel
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
host = {
|
||||
users = {
|
||||
leyla = {
|
||||
isDesktopUser = true;
|
||||
isTerminalUser = true;
|
||||
isPrincipleUser = true;
|
||||
};
|
||||
eve.isDesktopUser = true;
|
||||
};
|
||||
|
||||
hardware = {
|
||||
directAccess.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.callPackage
|
||||
./webtoon-dl.nix
|
||||
{})
|
||||
];
|
||||
|
||||
programs = {
|
||||
adb.enable = true;
|
||||
steam = {
|
||||
enable = true;
|
||||
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
|
||||
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets = {
|
||||
"vpn-keys/tailscale-authkey/horizon" = {
|
||||
sopsFile = "${inputs.secrets}/vpn-keys.yaml";
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
# sudo fprintd-enroll
|
||||
fprintd = {
|
||||
enable = true;
|
||||
};
|
||||
ollama = {
|
||||
enable = false;
|
||||
|
||||
loadModels = [
|
||||
"deepseek-coder:1.3b"
|
||||
"deepseek-r1:1.5b"
|
||||
];
|
||||
};
|
||||
tailscale = {
|
||||
enable = true;
|
||||
authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/horizon".path;
|
||||
useRoutingFeatures = "client";
|
||||
};
|
||||
|
||||
syncthing.enable = true;
|
||||
};
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
# services.xserver.libinput.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It's perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# leyla laptop
|
||||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
}
|
|
@ -1,136 +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 + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = ["xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod"];
|
||||
kernelModules = [];
|
||||
};
|
||||
kernelModules = ["kvm-intel" "sg"];
|
||||
extraModulePackages = [];
|
||||
|
||||
# Bootloader.
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
supportedFilesystems = ["nfs"];
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/866d422b-f816-4ad9-9846-791839cb9337";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/E138-65B5";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
"/mnt/leyla_documents" = {
|
||||
device = "defiant:/export/leyla_documents";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"vers=4"
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"noatime"
|
||||
"nofail"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"fsc"
|
||||
"timeo=600"
|
||||
"retrans=2"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/eve_documents" = {
|
||||
device = "defiant:/export/eve_documents";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"vers=4"
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"nofail"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"fsc"
|
||||
"timeo=600"
|
||||
"retrans=2"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/users_documents" = {
|
||||
device = "defiant:/export/users_documents";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"vers=4"
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"nofail"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"fsc"
|
||||
"timeo=600"
|
||||
"retrans=2"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/media" = {
|
||||
device = "defiant:/export/media";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"vers=4"
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"noatime"
|
||||
"nofail"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"noatime"
|
||||
"nodiratime"
|
||||
"relatime"
|
||||
"fsc"
|
||||
"timeo=600"
|
||||
"retrans=2"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
cachefilesd
|
||||
];
|
||||
|
||||
services.cachefilesd.enable = true;
|
||||
|
||||
swapDevices = [
|
||||
{device = "/dev/disk/by-uuid/be98e952-a072-4c3a-8c12-69500b5a2fff";}
|
||||
];
|
||||
|
||||
networking = {
|
||||
networkmanager.enable = true;
|
||||
useDHCP = lib.mkDefault true;
|
||||
hostName = "horizon"; # Define your hostname.
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
hardware = {
|
||||
graphics.enable = true;
|
||||
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
};
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
...
|
||||
}:
|
||||
buildGoModule rec {
|
||||
pname = "webtoon-dl";
|
||||
version = "0.0.10";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "robinovitch61";
|
||||
repo = "webtoon-dl";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-geVb3LFPZxPQYARZnaqOr5sgaN6mqkEX5ZiLvg8mF5k=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-NTqUygJ6b6kTnLUnJqxCo/URzaRouPLACEPi2Ob1s9w=";
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./monitors.nix
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
sops.secrets = {
|
||||
"vpn-keys/tailscale-authkey/twilight" = {
|
||||
sopsFile = "${inputs.secrets}/vpn-keys.yaml";
|
||||
};
|
||||
};
|
||||
host = {
|
||||
users = {
|
||||
leyla = {
|
||||
isDesktopUser = true;
|
||||
isTerminalUser = true;
|
||||
isPrincipleUser = true;
|
||||
};
|
||||
eve.isDesktopUser = true;
|
||||
};
|
||||
hardware = {
|
||||
piperMouse.enable = true;
|
||||
viaKeyboard.enable = true;
|
||||
openRGB.enable = true;
|
||||
graphicsAcceleration.enable = true;
|
||||
directAccess.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
ollama = {
|
||||
enable = false;
|
||||
|
||||
loadModels = [
|
||||
"deepseek-coder:6.7b"
|
||||
"deepseek-r1:8b"
|
||||
"deepseek-r1:32b"
|
||||
];
|
||||
};
|
||||
|
||||
tailscale = {
|
||||
enable = true;
|
||||
authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/twilight".path;
|
||||
useRoutingFeatures = "both";
|
||||
extraUpFlags = [
|
||||
"--advertise-exit-node"
|
||||
"--advertise-routes=192.168.0.0/24"
|
||||
];
|
||||
extraSetFlags = [
|
||||
"--advertise-exit-node"
|
||||
"--advertise-routes=192.168.0.0/24"
|
||||
];
|
||||
};
|
||||
|
||||
syncthing.enable = true;
|
||||
};
|
||||
programs.steam = {
|
||||
enable = true;
|
||||
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
|
||||
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
|
||||
};
|
||||
|
||||
# enabled virtualisation for docker
|
||||
# virtualisation.docker.enable = true;
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
# services.xserver.libinput.enable = true;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It's perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# leyla desktop
|
||||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
{pkgs, ...}: {
|
||||
systemd.tmpfiles.rules = [
|
||||
"L+ /run/gdm/.config/monitors.xml - - - - ${pkgs.writeText "gdm-monitors.xml" ''
|
||||
<monitors version="2">
|
||||
<configuration>
|
||||
<logicalmonitor>
|
||||
<x>0</x>
|
||||
<y>156</y>
|
||||
<scale>1</scale>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-4</connector>
|
||||
<vendor>DEL</vendor>
|
||||
<product>DELL U2719D</product>
|
||||
<serial>8RGXNS2</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>2560</width>
|
||||
<height>1440</height>
|
||||
<rate>59.951</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>2560</x>
|
||||
<y>324</y>
|
||||
<scale>1</scale>
|
||||
<primary>yes</primary>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-2</connector>
|
||||
<vendor>GSM</vendor>
|
||||
<product>LG ULTRAGEAR</product>
|
||||
<serial>0x00068c96</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<rate>240.001</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>4480</x>
|
||||
<y>0</y>
|
||||
<scale>1</scale>
|
||||
<transform>
|
||||
<rotation>left</rotation>
|
||||
<flipped>no</flipped>
|
||||
</transform>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>HDMI-0</connector>
|
||||
<vendor>HWP</vendor>
|
||||
<product>HP w2207</product>
|
||||
<serial>CND7332S88</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1600</width>
|
||||
<height>1000</height>
|
||||
<rate>59.999</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<logicalmonitor>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<scale>1</scale>
|
||||
<primary>yes</primary>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-1</connector>
|
||||
<vendor>DEL</vendor>
|
||||
<product>DELL U2719D</product>
|
||||
<serial>8RGXNS2</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>2560</width>
|
||||
<height>1440</height>
|
||||
<rate>59.951</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>4480</x>
|
||||
<y>226</y>
|
||||
<scale>1</scale>
|
||||
<transform>
|
||||
<rotation>left</rotation>
|
||||
<flipped>no</flipped>
|
||||
</transform>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>HDMI-1</connector>
|
||||
<vendor>HWP</vendor>
|
||||
<product>HP w2207</product>
|
||||
<serial>CND7332S88</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1680</width>
|
||||
<height>1050</height>
|
||||
<rate>59.954</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>2560</x>
|
||||
<y>226</y>
|
||||
<scale>1</scale>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-2</connector>
|
||||
<vendor>GSM</vendor>
|
||||
<product>LG ULTRAGEAR</product>
|
||||
<serial>0x00068c96</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<rate>240.001</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<logicalmonitor>
|
||||
<x>2560</x>
|
||||
<y>228</y>
|
||||
<scale>1</scale>
|
||||
<primary>yes</primary>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-2</connector>
|
||||
<vendor>GSM</vendor>
|
||||
<product>LG ULTRAGEAR</product>
|
||||
<serial>0x00068c96</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<rate>240.001</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>4480</x>
|
||||
<y>69</y>
|
||||
<scale>1</scale>
|
||||
<transform>
|
||||
<rotation>left</rotation>
|
||||
<flipped>no</flipped>
|
||||
</transform>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>HDMI-1</connector>
|
||||
<vendor>HWP</vendor>
|
||||
<product>HP w2207</product>
|
||||
<serial>CND7332S88</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1680</width>
|
||||
<height>1050</height>
|
||||
<rate>59.954</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<logicalmonitor>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<scale>1</scale>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>DP-3</connector>
|
||||
<vendor>DEL</vendor>
|
||||
<product>DELL U2719D</product>
|
||||
<serial>8RGXNS2</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>2560</width>
|
||||
<height>1440</height>
|
||||
<rate>59.951</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
<disabled>
|
||||
<monitorspec>
|
||||
<connector>None-1</connector>
|
||||
<vendor>unknown</vendor>
|
||||
<product>unknown</product>
|
||||
<serial>unknown</serial>
|
||||
</monitorspec>
|
||||
</disabled>
|
||||
</configuration>
|
||||
</monitors>
|
||||
''}"
|
||||
];
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
{config, ...}: {
|
||||
folders = {
|
||||
leyla_documents = {
|
||||
id = "hvrj0-9bm1p";
|
||||
};
|
||||
leyla_calendar = {
|
||||
id = "8oatl-1rv6w";
|
||||
};
|
||||
leyla_supernote_notes = {
|
||||
id = "dwbuv-zffnf";
|
||||
};
|
||||
eve_records = {
|
||||
id = "by6at-d4h9n";
|
||||
};
|
||||
share = {
|
||||
id = "73ot0-cxmkx";
|
||||
};
|
||||
};
|
||||
devices = {
|
||||
defiant = {
|
||||
id = "3R6E6Y4-2F7MF2I-IGB4WE6-A3SQSMV-LIBYSAM-2OXHHU2-KJ6CGIV-QNMCPAR";
|
||||
folders = {
|
||||
leyla_documents = {
|
||||
folder = config.folders.leyla_documents;
|
||||
path = "/mnt/sync/leyla/documents";
|
||||
};
|
||||
leyla_calendar = {
|
||||
folder = config.folders.leyla_calendar;
|
||||
path = "/mnt/sync/leyla/calendar";
|
||||
};
|
||||
leyla_supernote_notes = {
|
||||
folder = config.folders.leyla_supernote_notes;
|
||||
path = "/mnt/sync/leyla/notes";
|
||||
};
|
||||
eve_records = {
|
||||
folder = config.folders.eve_records;
|
||||
path = "/mnt/sync/eve/records";
|
||||
};
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
path = "/mnt/sync/default/share";
|
||||
};
|
||||
};
|
||||
};
|
||||
twilight = {
|
||||
id = "UDIYL7V-OAZ2BI3-EJRAWFB-GZYVDWR-JNUYW3F-FFQ35MU-XBTGWEF-QD6K6QN";
|
||||
folders = {
|
||||
leyla_documents = {
|
||||
folder = config.folders.leyla_documents;
|
||||
path = "/mnt/sync/leyla/documents";
|
||||
};
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
path = "/mnt/sync/default/share";
|
||||
};
|
||||
};
|
||||
};
|
||||
horizon = {
|
||||
id = "OGPAEU6-5UR56VL-SP7YC4Y-IMVCRTO-XFD4CYN-Z6T5TZO-PFZNAT6-4MKWPQS";
|
||||
folders = {
|
||||
leyla_documents = {
|
||||
folder = config.folders.leyla_documents;
|
||||
path = "/mnt/sync/leyla/documents";
|
||||
};
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
path = "/mnt/sync/default/share";
|
||||
};
|
||||
};
|
||||
};
|
||||
coven = {
|
||||
id = "QGU7NN6-OMXTWVA-YCZ73S5-2O7ECTS-MUCTN4M-YH6WLEL-U4U577I-7PBNCA5";
|
||||
folders = {
|
||||
leyla_documents = {
|
||||
folder = config.folders.leyla_documents;
|
||||
};
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
};
|
||||
};
|
||||
};
|
||||
ceder = {
|
||||
id = "MGXUJBS-7AENXHB-7YQRNWG-QILKEJD-5462U2E-WAQW4R4-I2TVK5H-SMK6LAA";
|
||||
folders = {
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
};
|
||||
leyla_documents = {
|
||||
folder = config.folders.leyla_documents;
|
||||
};
|
||||
leyla_calendar = {
|
||||
folder = config.folders.leyla_calendar;
|
||||
};
|
||||
leyla_notes = {
|
||||
folder = config.folders.leyla_supernote_notes;
|
||||
};
|
||||
};
|
||||
};
|
||||
emergent = {
|
||||
id = "6MIDMKJ-7IFHXVX-FIR3YTB-KVE75LN-PA6IOTN-I257LWR-MMC4K6C-5H4SHQN";
|
||||
folders = {
|
||||
eve_records = {
|
||||
folder = config.folders.eve_records;
|
||||
};
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
};
|
||||
};
|
||||
};
|
||||
shale = {
|
||||
id = "AOAXEVD-QJ2IVRA-6G44Q7Q-TGUPXU2-FWWKOBH-DPKWC5N-LBAEHWJ-7EQF4AM";
|
||||
folders = {
|
||||
share = {
|
||||
folder = config.folders.share;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
"/var/lib/sops-nix"
|
60
enviroments/client/default.nix
Normal file
60
enviroments/client/default.nix
Normal file
|
@ -0,0 +1,60 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
../common
|
||||
];
|
||||
|
||||
services = {
|
||||
|
||||
# Enable CUPS to print documents.
|
||||
printing.enable = true;
|
||||
|
||||
xserver = {
|
||||
# Enable the X11 windowing system.
|
||||
enable = true;
|
||||
|
||||
# Enable the GNOME Desktop Environment.
|
||||
displayManager.gdm.enable = true;
|
||||
desktopManager = {
|
||||
gnome.enable = true;
|
||||
xterm.enable = false;
|
||||
};
|
||||
|
||||
# Get rid of xTerm
|
||||
excludePackages = [ pkgs.xterm ];
|
||||
|
||||
# Configure keymap in X11
|
||||
xkb = {
|
||||
layout = "us,it,de";
|
||||
variant = "";
|
||||
};
|
||||
};
|
||||
|
||||
pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
# If you want to use JACK applications, uncomment this
|
||||
#jack.enable = true;
|
||||
|
||||
# use the example session manager (no others are packaged yet so this is enabled by default,
|
||||
# no need to redefine it in your config for now)
|
||||
#media-session.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# Enable sound with pipewire.
|
||||
hardware.pulseaudio.enable = false;
|
||||
security.rtkit.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# helvetica font
|
||||
aileron
|
||||
|
||||
cachefilesd
|
||||
|
||||
gnomeExtensions.dash-to-dock
|
||||
];
|
||||
}
|
71
enviroments/common/default.nix
Normal file
71
enviroments/common/default.nix
Normal file
|
@ -0,0 +1,71 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
../../users
|
||||
];
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
nix.settings.trusted-users = [ "leyla" ];
|
||||
|
||||
# Enable networking
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
# Set your time zone.
|
||||
time.timeZone = "America/Chicago";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "en_US.UTF-8";
|
||||
LC_IDENTIFICATION = "en_US.UTF-8";
|
||||
LC_MEASUREMENT = "en_US.UTF-8";
|
||||
LC_MONETARY = "en_US.UTF-8";
|
||||
LC_NAME = "en_US.UTF-8";
|
||||
LC_NUMERIC = "en_US.UTF-8";
|
||||
LC_PAPER = "en_US.UTF-8";
|
||||
LC_TELEPHONE = "en_US.UTF-8";
|
||||
LC_TIME = "en_US.UTF-8";
|
||||
};
|
||||
|
||||
users.groups.users = {};
|
||||
|
||||
services = {
|
||||
openssh = {
|
||||
enable = true;
|
||||
ports = [ 22 ];
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
AllowUsers = [ "leyla" ]; # Allows all users by default. Can be [ "user1" "user2" ]
|
||||
UseDns = true;
|
||||
X11Forwarding = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops = {
|
||||
defaultSopsFile = ../../secrets/secrets.yaml;
|
||||
defaultSopsFormat = "yaml";
|
||||
gnupg.sshKeyPaths = [];
|
||||
|
||||
age ={
|
||||
keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sshKeyPaths = [];
|
||||
# generateKey = true;
|
||||
};
|
||||
};
|
||||
environment.sessionVariables = {
|
||||
AGE_KEY_FILE_LOCATION = "/var/lib/sops-nix/";
|
||||
};
|
||||
|
||||
# List packages installed in system profile.
|
||||
environment.systemPackages = with pkgs; [
|
||||
wget
|
||||
|
||||
# version control
|
||||
git
|
||||
|
||||
# system debuging tools
|
||||
iputils
|
||||
dnsutils
|
||||
];
|
||||
}
|
63
enviroments/server/default.nix
Normal file
63
enviroments/server/default.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
../common
|
||||
];
|
||||
|
||||
services = let
|
||||
headscaleDomain = "headscale.jan-leila.com";
|
||||
in {
|
||||
nfs.server = {
|
||||
enable = true;
|
||||
exports = ''
|
||||
/home/leyla 192.168.1.0/22(rw,sync,no_subtree_check,crossmnt)
|
||||
/home/eve 192.168.1.0/22(rw,sync,no_subtree_check,crossmnt)
|
||||
/home/ester 192.168.1.0/22(rw,sync,no_subtree_check,crossmnt)
|
||||
/home/users 192.168.1.0/22(rw,sync,no_subtree_check,crossmnt)
|
||||
'';
|
||||
};
|
||||
|
||||
headscale = {
|
||||
enable = true;
|
||||
address = "0.0.0.0";
|
||||
port = 8080;
|
||||
settings = {
|
||||
server_url = "https://${headscaleDomain}";
|
||||
dns_config.base_domain = "jan-leila.com";
|
||||
logtail.enabled = false;
|
||||
};
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = false; # TODO: enable this when you want to test all the configs
|
||||
virtualHosts = {
|
||||
${headscaleDomain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass =
|
||||
"http://localhost:${toString config.services.headscale.port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "jan-leila@protonmail.com";
|
||||
};
|
||||
|
||||
# disable computer sleeping
|
||||
systemd.targets = {
|
||||
sleep.enable = false;
|
||||
suspend.enable = false;
|
||||
hibernate.enable = false;
|
||||
hybrid-sleep.enable = false;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 2049 ];
|
||||
|
||||
environment.systemPackages = [ config.services.headscale.package ];
|
||||
}
|
187
flake.lock
187
flake.lock
|
@ -7,11 +7,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744145203,
|
||||
"narHash": "sha256-I2oILRiJ6G+BOSjY+0dGrTPe080L3pbKpc+gCV3Nmyk=",
|
||||
"lastModified": 1725377834,
|
||||
"narHash": "sha256-tqoAO8oT6zEUDXte98cvA1saU9+1dLJQe3pMKLXv8ps=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "76c0a6dba345490508f36c1aa3c7ba5b6b460989",
|
||||
"rev": "e55f9a8678adc02024a4877c2a403e3f6daf24fe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -20,35 +20,14 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"firefox-addons": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"lastModified": 1744813899,
|
||||
"narHash": "sha256-5J6kSkPbtuyX0tRggqadwulpqdgWHyQEDwhqVnY0T+g=",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"rev": "f6dff741f9f485b3596a368704ec171d9eb8c7cd",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -62,11 +41,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -82,11 +61,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744820898,
|
||||
"narHash": "sha256-gUldr3LtCm/OfEnbH6sFFlyyxqPMCsfMs2Ha+0fdPDs=",
|
||||
"lastModified": 1725948275,
|
||||
"narHash": "sha256-4QOPemDQ9VRLQaAdWuvdDBhh+lEUOAnSMHhdr4nS1mk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "7ede02c32a729db0d6340bdb41d10e73ec511ca0",
|
||||
"rev": "e5fa72bad0c6f533e8d558182529ee2acc9454fe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -95,75 +74,20 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"impermanence": {
|
||||
"locked": {
|
||||
"lastModified": 1737831083,
|
||||
"narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=",
|
||||
"owner": "nix-community",
|
||||
"repo": "impermanence",
|
||||
"rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "impermanence",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744478979,
|
||||
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
|
||||
"owner": "LnL7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "LnL7",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-syncthing": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741849924,
|
||||
"narHash": "sha256-5vyb1H6HtW24QVqfI56P4QVQP6vHh1jS9ULwnunCO94=",
|
||||
"ref": "main",
|
||||
"rev": "86bcb200c83b6a5d13b3583126b9d8dc6770613a",
|
||||
"revCount": 6,
|
||||
"type": "git",
|
||||
"url": "https://git.jan-leila.com/jan-leila/nix-syncthing"
|
||||
},
|
||||
"original": {
|
||||
"ref": "main",
|
||||
"type": "git",
|
||||
"url": "https://git.jan-leila.com/jan-leila/nix-syncthing"
|
||||
}
|
||||
},
|
||||
"nix-vscode-extensions": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744768710,
|
||||
"narHash": "sha256-ow0HDShvAe9gkM3Ww5aoJo1lDLpC5pYQ7qLtnTaHoyI=",
|
||||
"lastModified": 1726623336,
|
||||
"narHash": "sha256-mslZtr0SPdHDLUM5VRV0ipQQ4G0Piv2Kk15490w4JXM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-vscode-extensions",
|
||||
"rev": "47bd3dc652c4a02dc565a9360fe828af38bea287",
|
||||
"rev": "b23683fef09032c85bb8b20f8ec72fb2f70075ff",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -174,11 +98,11 @@
|
|||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1744633460,
|
||||
"narHash": "sha256-fbWE4Xpw6eH0Q6in+ymNuDwTkqmFmtxcQEmtRuKDTTk=",
|
||||
"lastModified": 1725885300,
|
||||
"narHash": "sha256-5RLEnou1/GJQl+Wd+Bxaj7QY7FFQ9wjnFq1VNEaxTmc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "9a049b4a421076d27fee3eec664a18b2066824cb",
|
||||
"rev": "166dee4f88a7e3ba1b7a243edb1aca822f00680e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -190,11 +114,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1744463964,
|
||||
"narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=",
|
||||
"lastModified": 1725634671,
|
||||
"narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
|
||||
"rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -204,50 +128,59 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1725762081,
|
||||
"narHash": "sha256-vNv+aJUW5/YurRy1ocfvs4q/48yVESwlC/yHzjkZSP8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dc454045f5b5d814e5862a6d057e7bb5c29edc05",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1725534445,
|
||||
"narHash": "sha256-Yd0FK9SkWy+ZPuNqUgmVPXokxDgMJoGuNpMEtkfcf84=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9bb1e7571aadf31ddb4af77fc64b2d59580f9a39",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"firefox-addons": "firefox-addons",
|
||||
"flake-compat": "flake-compat",
|
||||
"home-manager": "home-manager",
|
||||
"impermanence": "impermanence",
|
||||
"nix-darwin": "nix-darwin",
|
||||
"nix-syncthing": "nix-syncthing",
|
||||
"nix-vscode-extensions": "nix-vscode-extensions",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"secrets": "secrets",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
},
|
||||
"secrets": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1743538790,
|
||||
"narHash": "sha256-QXmvyxfAhpifxAWcYTvuGfzv9I+9gHw0bq4WYtGEB9A=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "3d63dff77f8eda1667e3586169642cf256c4aa34",
|
||||
"revCount": 17,
|
||||
"type": "git",
|
||||
"url": "ssh://git@git.jan-leila.com/jan-leila/nix-config-secrets.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@git.jan-leila.com/jan-leila/nix-config-secrets.git"
|
||||
}
|
||||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1744669848,
|
||||
"narHash": "sha256-pXyanHLUzLNd3MX9vsWG+6Z2hTU8niyphWstYEP3/GU=",
|
||||
"lastModified": 1725922448,
|
||||
"narHash": "sha256-ruvh8tlEflRPifs5tlpa0gkttzq4UtgXkJQS7FusgFE=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "61154300d945f0b147b30d24ddcafa159148026a",
|
||||
"rev": "cede1a08039178ac12957733e97ab1006c6b6892",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
191
flake.nix
191
flake.nix
|
@ -5,168 +5,71 @@
|
|||
# base packages
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
# lix-module = {
|
||||
# url = "https://git.lix.systems/lix-project/nixos-module/archive/stable.tar.gz";
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
# };
|
||||
# encrypt files that contain secreats that I would like to not encrypt
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
|
||||
# secret encryption
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# self hosted repo of secrets file to further protect files in case of future encryption vulnerabilities
|
||||
secrets = {
|
||||
url = "git+ssh://git@git.jan-leila.com/jan-leila/nix-config-secrets.git";
|
||||
flake = false;
|
||||
};
|
||||
|
||||
# common config for syncthing
|
||||
nix-syncthing = {
|
||||
url = "git+https://git.jan-leila.com/jan-leila/nix-syncthing?ref=main";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# disk configurations
|
||||
# declairtive disk configuration
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# delete your darlings
|
||||
impermanence = {
|
||||
url = "github:nix-community/impermanence";
|
||||
};
|
||||
|
||||
nix-darwin = {
|
||||
url = "github:LnL7/nix-darwin";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# users home directories
|
||||
# managment per user
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# firefox extensions
|
||||
firefox-addons = {
|
||||
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
# repo of hardware configs for prebuilt systems
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
|
||||
# vscode extensions
|
||||
# vscode extensions
|
||||
nix-vscode-extensions = {
|
||||
url = "github:nix-community/nix-vscode-extensions";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# pregenerated hardware configurations
|
||||
nixos-hardware = {
|
||||
url = "github:NixOS/nixos-hardware/master";
|
||||
};
|
||||
|
||||
# this is just here so that we have a lock on it for our dev shells
|
||||
flake-compat = {
|
||||
url = "github:edolstra/flake-compat";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
sops-nix,
|
||||
nix-syncthing,
|
||||
home-manager,
|
||||
impermanence,
|
||||
...
|
||||
} @ inputs: let
|
||||
util = import ./util {inherit inputs;};
|
||||
forEachPkgs = util.forEachPkgs;
|
||||
outputs = { self, nixpkgs, disko, nixos-hardware, ... }@inputs:
|
||||
let
|
||||
forEachSystem = nixpkgs.lib.genAttrs [
|
||||
"aarch64-darwin"
|
||||
"aarch64-linux"
|
||||
"x86_64-darwin"
|
||||
"x86_64-linux"
|
||||
];
|
||||
forEachPkgs = lambda: forEachSystem (system: lambda nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
packages = forEachPkgs (pkgs: import ./pkgs { inherit pkgs; });
|
||||
|
||||
mkNixosInstaller = util.mkNixosInstaller;
|
||||
mkNixosSystem = util.mkNixosSystem;
|
||||
mkDarwinSystem = util.mkDarwinSystem;
|
||||
mkHome = util.mkHome;
|
||||
syncthingConfiguration = util.syncthingConfiguration;
|
||||
|
||||
installerSystems = {
|
||||
basic = mkNixosInstaller "basic" [];
|
||||
};
|
||||
|
||||
nixosSystems = {
|
||||
horizon = mkNixosSystem "horizon";
|
||||
twilight = mkNixosSystem "twilight";
|
||||
defiant = mkNixosSystem "defiant";
|
||||
};
|
||||
|
||||
darwinSystems = {
|
||||
hesperium = mkDarwinSystem "hesperium";
|
||||
};
|
||||
|
||||
homeSystems = {
|
||||
# stand alone home manager configurations here:
|
||||
# name = mkHome "name"
|
||||
};
|
||||
|
||||
systemsHomes = nixpkgs.lib.attrsets.mergeAttrsList (
|
||||
nixpkgs.lib.attrsets.mapAttrsToList (hostname: system: (
|
||||
nixpkgs.lib.attrsets.mapAttrs' (user: _: {
|
||||
name = "${user}@${hostname}";
|
||||
value = mkHome {
|
||||
user = user;
|
||||
host = hostname;
|
||||
system = system.pkgs.hostPlatform.system;
|
||||
osConfig = system.config;
|
||||
};
|
||||
})
|
||||
system.config.home-manager.users
|
||||
))
|
||||
(nixosSystems // darwinSystems)
|
||||
);
|
||||
|
||||
homeConfigurations =
|
||||
systemsHomes
|
||||
// homeSystems;
|
||||
in {
|
||||
formatter = forEachPkgs (pkgs: pkgs.alejandra);
|
||||
|
||||
# templates = import ./templates;
|
||||
|
||||
devShells = forEachPkgs (pkgs: {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
# for version controlling this repo
|
||||
git
|
||||
# for formatting code in this repo
|
||||
alejandra
|
||||
# for editing secrets in the secrets repo
|
||||
sops
|
||||
# for viewing configuration options defined in this repo
|
||||
nix-inspect
|
||||
# for installing flakes from this repo onto other systems
|
||||
nixos-anywhere
|
||||
# for updating disko configurations
|
||||
disko
|
||||
];
|
||||
|
||||
SOPS_AGE_KEY_DIRECTORY = import ./const/sops_age_key_directory.nix;
|
||||
|
||||
shellHook = ''
|
||||
git config core.hooksPath .hooks
|
||||
'';
|
||||
nixosConfigurations = {
|
||||
# Leyla Laptop
|
||||
horizon = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./hosts/horizon/configuration.nix
|
||||
inputs.home-manager.nixosModules.default
|
||||
nixos-hardware.nixosModules.framework-11th-gen-intel
|
||||
];
|
||||
};
|
||||
# Leyla Desktop
|
||||
twilight = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./hosts/twilight/configuration.nix
|
||||
inputs.home-manager.nixosModules.default
|
||||
];
|
||||
};
|
||||
# NAS Service
|
||||
defiant = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
./hosts/defiant/disko-config.nix
|
||||
./hosts/defiant/configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
installerConfigurations = installerSystems;
|
||||
|
||||
nixosConfigurations = nixosSystems;
|
||||
|
||||
darwinConfigurations = darwinSystems;
|
||||
|
||||
homeConfigurations = homeConfigurations;
|
||||
|
||||
syncthingConfiguration = syncthingConfiguration;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
57
hosts/defiant/configuration.nix
Normal file
57
hosts/defiant/configuration.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
# server nas
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
imports =
|
||||
[
|
||||
inputs.home-manager.nixosModules.default
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
|
||||
./hardware-configuration.nix
|
||||
|
||||
../../enviroments/server
|
||||
];
|
||||
|
||||
users.leyla.isThinUser = true;
|
||||
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
zfsSupport = true;
|
||||
efiSupport = true;
|
||||
efiInstallAsRemovable = true;
|
||||
};
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
services = {
|
||||
zfs = {
|
||||
autoScrub.enable = true;
|
||||
autoSnapshot.enable = true;
|
||||
};
|
||||
|
||||
# temp enable desktop enviroment for setup
|
||||
# Enable the X11 windowing system.
|
||||
xserver = {
|
||||
enable = true;
|
||||
|
||||
# Enable the GNOME Desktop Environment.
|
||||
displayManager = {
|
||||
gdm.enable = true;
|
||||
};
|
||||
desktopManager = {
|
||||
gnome.enable = true;
|
||||
xterm.enable = false;
|
||||
};
|
||||
|
||||
# Get rid of xTerm
|
||||
excludePackages = [ pkgs.xterm ];
|
||||
};
|
||||
};
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
136
hosts/defiant/disko-config.nix
Normal file
136
hosts/defiant/disko-config.nix
Normal file
|
@ -0,0 +1,136 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
bootDisk = devicePath: {
|
||||
type = "disk";
|
||||
device = devicePath;
|
||||
content = {
|
||||
type = "gpt";
|
||||
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "1G";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
zfsDisk = devicePath: {
|
||||
type = "disk";
|
||||
device = devicePath;
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
zfs = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "zfs";
|
||||
pool = "zroot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cacheDisk = devicePath: swapSize: {
|
||||
type = "disk";
|
||||
device = devicePath;
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
encryptedSwap = {
|
||||
size = swapSize;
|
||||
content = {
|
||||
type = "swap";
|
||||
randomEncryption = true;
|
||||
discardPolicy = "both";
|
||||
resumeDevice = true;
|
||||
};
|
||||
};
|
||||
zfs = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "zfs";
|
||||
pool = "zroot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
disko.devices = {
|
||||
disk = {
|
||||
boot = bootDisk "/dev/disk/by-path/pci-0000:23:00.3-usb-0:1:1.0-scsi-0:0:0:0";
|
||||
|
||||
hd_13_tb_a = zfsDisk "/dev/disk/by-id/ata-ST18000NE000-3G6101_ZVTCXVEB";
|
||||
hd_13_tb_b = zfsDisk "/dev/disk/by-id/ata-ST18000NE000-3G6101_ZVTCXWSC";
|
||||
hd_13_tb_c = zfsDisk "/dev/disk/by-id/ata-ST18000NE000-3G6101_ZVTD10EH";
|
||||
|
||||
# ssd_2_tb_a = cacheDisk "64G" "/dev/disk/by-id/XXX";
|
||||
};
|
||||
zpool = {
|
||||
zroot = {
|
||||
type = "zpool";
|
||||
mode = {
|
||||
topology = {
|
||||
type = "topology";
|
||||
vdev = [
|
||||
{
|
||||
# should this only mirror for this inital config with 3 drives we will used raidz2 for future configs???
|
||||
mode = "mirror";
|
||||
members = [
|
||||
"hd_13_tb_a" "hd_13_tb_b" "hd_13_tb_c"
|
||||
];
|
||||
}
|
||||
];
|
||||
cache = [ ];
|
||||
# cache = [ "ssd_2_tb_a" ];
|
||||
};
|
||||
};
|
||||
|
||||
options = {
|
||||
ashift = "12";
|
||||
};
|
||||
|
||||
rootFsOptions = {
|
||||
encryption = "on";
|
||||
keyformat = "hex";
|
||||
keylocation = "prompt";
|
||||
compression = "lz4";
|
||||
xattr = "sa";
|
||||
acltype = "posixacl";
|
||||
"com.sun:auto-snapshot" = "false";
|
||||
};
|
||||
|
||||
mountpoint = "/";
|
||||
postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank";
|
||||
|
||||
datasets = {
|
||||
"nix" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/nix";
|
||||
};
|
||||
"home" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/mnt/home";
|
||||
options = {
|
||||
"com.sun:auto-snapshot" = "true";
|
||||
};
|
||||
};
|
||||
"var" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/var";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
45
hosts/defiant/hardware-configuration.nix
Normal file
45
hosts/defiant/hardware-configuration.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
# 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" "aacraid" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = [ "kvm-amd" ];
|
||||
extraModulePackages = [ ];
|
||||
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
|
||||
zfs.extraPools = [ "zroot" ];
|
||||
};
|
||||
|
||||
# fileSystems."/" =
|
||||
# { device = "/dev/disk/by-uuid/dc6a9664-80f2-4988-afd7-fee5bd3ee2ca";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking = {
|
||||
# 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`.
|
||||
useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
||||
hostId = "c51763d6";
|
||||
hostName = "defiant"; # Define your hostname.
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
49
hosts/horizon/configuration.nix
Normal file
49
hosts/horizon/configuration.nix
Normal file
|
@ -0,0 +1,49 @@
|
|||
# leyla laptop
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
imports =
|
||||
[
|
||||
inputs.home-manager.nixosModules.default
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
|
||||
./hardware-configuration.nix
|
||||
|
||||
../../enviroments/client
|
||||
];
|
||||
|
||||
users = {
|
||||
leyla.isFullUser = true;
|
||||
ester.isFullUser = true;
|
||||
eve.isFullUser = true;
|
||||
};
|
||||
|
||||
# enabled virtualisation for docker
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
rootless = {
|
||||
enable = true;
|
||||
setSocketVariable = true;
|
||||
};
|
||||
};
|
||||
users.extraGroups.docker.members = [ "leyla" ];
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
# services.xserver.libinput.enable = true;
|
||||
|
||||
# Allow unfree packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
104
hosts/horizon/hardware-configuration.nix
Normal file
104
hosts/horizon/hardware-configuration.nix
Normal file
|
@ -0,0 +1,104 @@
|
|||
# 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" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = [ "kvm-intel" "sg" ];
|
||||
extraModulePackages = [ ];
|
||||
|
||||
# Bootloader.
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
|
||||
fileSystems = {
|
||||
"/" =
|
||||
{ device = "/dev/disk/by-uuid/866d422b-f816-4ad9-9846-791839cb9337";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
"/boot" =
|
||||
{ device = "/dev/disk/by-uuid/E138-65B5";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
"/mnt/leyla_home" =
|
||||
{
|
||||
device = "defiant:/home/leyla";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "noatime" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
"/mnt/eve_home" =
|
||||
{
|
||||
device = "defiant:/home/eve";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
"/mnt/ester_home" =
|
||||
{
|
||||
device = "defiant:/home/ester";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
"/mnt/users_home" =
|
||||
{
|
||||
device = "defiant:/home/users";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
# "/mnt/legacy_leyla_home" =
|
||||
# {
|
||||
# device = "server.arpa:/home/leyla";
|
||||
# fsType = "nfs";
|
||||
# options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
# };
|
||||
|
||||
# "/mnt/legacy_share_home" =
|
||||
# {
|
||||
# device = "server.arpa:/home/share";
|
||||
# fsType = "nfs";
|
||||
# options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
# };
|
||||
|
||||
# "/mnt/legacy_docker_home" =
|
||||
# {
|
||||
# device = "server.arpa:/home/docker";
|
||||
# fsType = "nfs";
|
||||
# options = [ "x-systemd.automount" "noauto" "x-systemd.idle-timeout=600" ];
|
||||
# };
|
||||
};
|
||||
|
||||
services.cachefilesd.enable = true;
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/be98e952-a072-4c3a-8c12-69500b5a2fff"; }
|
||||
];
|
||||
|
||||
networking = {
|
||||
useDHCP = lib.mkDefault true;
|
||||
hostName = "horizon"; # Define your hostname.
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
42
hosts/twilight/configuration.nix
Normal file
42
hosts/twilight/configuration.nix
Normal file
|
@ -0,0 +1,42 @@
|
|||
# leyla laptop
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
imports =
|
||||
[
|
||||
inputs.home-manager.nixosModules.default
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
|
||||
./hardware-configuration.nix
|
||||
|
||||
../../enviroments/client
|
||||
];
|
||||
|
||||
users = {
|
||||
leyla = {
|
||||
isFullUser = true;
|
||||
hasPiperMouse = true;
|
||||
hasOpenRGBHardware = true;
|
||||
hasViaKeyboard = true;
|
||||
hasGPU = true;
|
||||
};
|
||||
ester.isFullUser = true;
|
||||
eve.isFullUser = true;
|
||||
};
|
||||
|
||||
# enabled virtualisation for docker
|
||||
# virtualisation.docker.enable = true;
|
||||
|
||||
# Enable touchpad support (enabled default in most desktopManager).
|
||||
# services.xserver.libinput.enable = true;
|
||||
|
||||
# Allow unfree packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
}
|
|
@ -1,32 +1,26 @@
|
|||
# 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, ... }:
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
|
||||
kernelModules = [];
|
||||
availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = ["kvm-amd" "sg"];
|
||||
extraModulePackages = [];
|
||||
kernelModules = [ "kvm-amd" "sg" ];
|
||||
extraModulePackages = [ ];
|
||||
|
||||
# Bootloader.
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
supportedFilesystems = ["nfs"];
|
||||
};
|
||||
|
||||
services.xserver = {
|
||||
|
@ -37,90 +31,10 @@
|
|||
displayManager.gdm.wayland = false;
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/8be49c65-2b57-48f1-b74d-244d26061adb";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/3006-3867";
|
||||
fsType = "vfat";
|
||||
options = ["fmask=0022" "dmask=0022"];
|
||||
};
|
||||
|
||||
"/mnt/leyla_documents" = {
|
||||
device = "defiant:/exports/leyla_documents";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"noatime"
|
||||
"nofail"
|
||||
"soft"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"fsc"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/users_documents" = {
|
||||
device = "defiant:/exports/users_documents";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"nofail"
|
||||
"soft"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"fsc"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/media" = {
|
||||
device = "defiant:/exports/media";
|
||||
fsType = "nfs";
|
||||
options = [
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"user"
|
||||
"noatime"
|
||||
"nofail"
|
||||
"soft"
|
||||
"x-systemd.idle-timeout=600"
|
||||
"noatime"
|
||||
"nodiratime"
|
||||
"relatime"
|
||||
"rsize=32768"
|
||||
"wsize=32768"
|
||||
"fsc"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
cachefilesd
|
||||
];
|
||||
|
||||
swapDevices = [];
|
||||
|
||||
networking = {
|
||||
networkmanager.enable = true;
|
||||
# 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`.
|
||||
useDHCP = lib.mkDefault true;
|
||||
hostName = "twilight"; # Define your hostname.
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
hardware = {
|
||||
# Enable OpenGL
|
||||
graphics.enable = true;
|
||||
|
||||
|
||||
# install graphics drivers
|
||||
nvidia = {
|
||||
# Modesetting is required.
|
||||
|
@ -128,7 +42,7 @@
|
|||
|
||||
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
||||
# Enable this if you have graphical corruption issues or application crashes after waking
|
||||
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
||||
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
||||
# of just the bare essentials.
|
||||
powerManagement.enable = false;
|
||||
|
||||
|
@ -138,21 +52,68 @@
|
|||
|
||||
# Use the NVidia open source kernel module (not to be confused with the
|
||||
# independent third-party "nouveau" open source driver).
|
||||
# Support is limited to the Turing and later architectures. Full list of
|
||||
# supported GPUs is at:
|
||||
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
||||
# Support is limited to the Turing and later architectures. Full list of
|
||||
# supported GPUs is at:
|
||||
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
||||
# Only available from driver 515.43.04+
|
||||
# Currently alpha-quality/buggy, so false is currently the recommended setting.
|
||||
open = false;
|
||||
|
||||
# Enable the Nvidia settings menu,
|
||||
# accessible via `nvidia-settings`.
|
||||
# accessible via `nvidia-settings`.
|
||||
nvidiaSettings = true;
|
||||
|
||||
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
||||
package = config.boot.kernelPackages.nvidiaPackages.production;
|
||||
};
|
||||
|
||||
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" =
|
||||
{ device = "/dev/disk/by-uuid/8be49c65-2b57-48f1-b74d-244d26061adb";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
"/boot" =
|
||||
{ device = "/dev/disk/by-uuid/3006-3867";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
"/mnt/leyla_home" =
|
||||
{
|
||||
device = "server.arpa:/home/leyla";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
"/mnt/share_home" =
|
||||
{
|
||||
device = "server.arpa:/home/share";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "user" "nofail" "soft" "x-systemd.idle-timeout=600" "fsc" ];
|
||||
};
|
||||
|
||||
"/mnt/docker_home" =
|
||||
{
|
||||
device = "server.arpa:/home/docker";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "noauto" "x-systemd.idle-timeout=600" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking = {
|
||||
# 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`.
|
||||
useDHCP = lib.mkDefault true;
|
||||
hostName = "twilight"; # Define your hostname.
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
|
|
@ -39,7 +39,6 @@ if [ -z ${flake} ]; then
|
|||
exit 1;
|
||||
fi
|
||||
|
||||
# TODO: we might not need to copy the key over here anymore?
|
||||
temp=$(mktemp -d)
|
||||
# Function to cleanup temporary directory on exit
|
||||
cleanup() {
|
||||
|
@ -48,8 +47,8 @@ cleanup() {
|
|||
trap cleanup EXIT
|
||||
|
||||
# copy key file to temp folder to copy over to target
|
||||
mkdir -p $temp$SOPS_AGE_KEY_DIRECTORY
|
||||
cp -r $SOPS_AGE_KEY_DIRECTORY/* $temp$SOPS_AGE_KEY_DIRECTORY
|
||||
mkdir -p $temp$AGE_KEY_FILE_LOCATION
|
||||
cp -r $AGE_KEY_FILE_LOCATION/* $temp$AGE_KEY_FILE_LOCATION
|
||||
|
||||
# commit number in this is because the main branch of nixos-anywhere is broken right now
|
||||
nixos-anywhere --extra-files $temp --flake ".#$flake" ${user:-nixos}@$target
|
||||
nix run github:nix-community/nixos-anywhere/b3b6bfebba35d55fba485ceda588984dec74c54f -- --extra-files $temp --flake ".#$flake" ${user:-nixos}@$target
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
# this folder is for modules that are common between nixos, home-manager, and darwin
|
||||
{...}: {
|
||||
imports = [
|
||||
./overlays
|
||||
./pkgs
|
||||
];
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
# this folder is for derivation overlays
|
||||
{...}: {
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
# this folder is for custom derivations
|
||||
{...}: {
|
||||
# package = pkgs.callPackage ./package.nix {};
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# this folder container modules that are for darwin only
|
||||
{...}: {
|
||||
imports = [
|
||||
./home-manager
|
||||
./users.nix
|
||||
./system.nix
|
||||
];
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
# modules in this folder are to adapt home-manager modules configs to darwin-module configs
|
||||
{...}: {}
|
|
@ -1,27 +0,0 @@
|
|||
{self, ...}: {
|
||||
system.configurationRevision = self.rev or self.dirtyRev or null;
|
||||
|
||||
nix = {
|
||||
gc = {
|
||||
automatic = true;
|
||||
interval = [
|
||||
{
|
||||
Hour = 4;
|
||||
Minute = 15;
|
||||
Weekday = 7;
|
||||
}
|
||||
];
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
optimise = {
|
||||
automatic = true;
|
||||
interval = [
|
||||
{
|
||||
Hour = 4;
|
||||
Minute = 15;
|
||||
Weekday = 7;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
host = config.host;
|
||||
in {
|
||||
users = {
|
||||
users = {
|
||||
leyla = {
|
||||
name = lib.mkForce host.users.leyla.name;
|
||||
home = lib.mkForce "/home/${host.users.leyla.name}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# this folder container modules that are for home manager only
|
||||
{...}: {
|
||||
imports = [
|
||||
./flipperzero.nix
|
||||
./i18n.nix
|
||||
./openssh.nix
|
||||
];
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{lib, ...}: {
|
||||
options.hardware.flipperzero.enable = lib.mkEnableOption "enable flipperzero hardware";
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
i18n = {
|
||||
defaultLocale = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "en_US.UTF-8";
|
||||
example = "nl_NL.UTF-8";
|
||||
description = ''
|
||||
The default locale. It determines the language for program
|
||||
messages, the format for dates and times, sort order, and so on.
|
||||
It also determines the character set, such as UTF-8.
|
||||
'';
|
||||
};
|
||||
|
||||
extraLocaleSettings = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = {};
|
||||
example = {
|
||||
LC_MESSAGES = "en_US.UTF-8";
|
||||
LC_TIME = "de_DE.UTF-8";
|
||||
};
|
||||
description = ''
|
||||
A set of additional system-wide locale settings other than
|
||||
`LANG` which can be configured with
|
||||
{option}`i18n.defaultLocale`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
home.sessionVariables =
|
||||
{
|
||||
LANG = config.i18n.defaultLocale;
|
||||
}
|
||||
// config.i18n.extraLocaleSettings;
|
||||
};
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
osConfig,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
options.programs.openssh = {
|
||||
authorizedKeys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
};
|
||||
hostKeys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [];
|
||||
example = [
|
||||
{
|
||||
type = "rsa";
|
||||
bits = 4096;
|
||||
path = "${config.home.username}_${osConfig.networking.hostName}_rsa";
|
||||
rounds = 100;
|
||||
openSSHFormat = true;
|
||||
}
|
||||
{
|
||||
type = "ed25519";
|
||||
path = "${config.home.username}_${osConfig.networking.hostName}_ed25519";
|
||||
rounds = 100;
|
||||
comment = "key comment";
|
||||
}
|
||||
];
|
||||
description = ''
|
||||
NixOS can automatically generate SSH host keys. This option
|
||||
specifies the path, type and size of each key. See
|
||||
{manpage}`ssh-keygen(1)` for supported types
|
||||
and sizes. Paths are relative to home directory
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(
|
||||
lib.mkIf ((builtins.length config.programs.openssh.hostKeys) != 0) {
|
||||
services.ssh-agent.enable = true;
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
compression = true;
|
||||
addKeysToAgent = "confirm";
|
||||
extraConfig = lib.strings.concatLines (
|
||||
builtins.map (hostKey: "IdentityFile ~/.ssh/${hostKey.path}") config.programs.openssh.hostKeys
|
||||
);
|
||||
};
|
||||
|
||||
systemd.user.services = builtins.listToAttrs (
|
||||
builtins.map (hostKey:
|
||||
lib.attrsets.nameValuePair "ssh-gen-keys-${hostKey.path}" {
|
||||
Install = {
|
||||
WantedBy = ["default.target"];
|
||||
};
|
||||
Service = let
|
||||
path = "${config.home.homeDirectory}/.ssh/${hostKey.path}";
|
||||
in {
|
||||
Restart = "always";
|
||||
Type = "simple";
|
||||
ExecStart = "${
|
||||
pkgs.writeShellScript "ssh-gen-keys" ''
|
||||
if ! [ -s "${path}" ]; then
|
||||
if ! [ -h "${path}" ]; then
|
||||
rm -f "${path}"
|
||||
fi
|
||||
mkdir -p "$(dirname '${path}')"
|
||||
chmod 0755 "$(dirname '${path}')"
|
||||
${pkgs.openssh}/bin/ssh-keygen \
|
||||
-t "${hostKey.type}" \
|
||||
${lib.optionalString (hostKey ? bits) "-b ${toString hostKey.bits}"} \
|
||||
${lib.optionalString (hostKey ? rounds) "-a ${toString hostKey.rounds}"} \
|
||||
${lib.optionalString (hostKey ? comment) "-C '${hostKey.comment}'"} \
|
||||
${lib.optionalString (hostKey ? openSSHFormat && hostKey.openSSHFormat) "-o"} \
|
||||
-f "${path}" \
|
||||
-N ""
|
||||
chown ${config.home.username} ${path}*
|
||||
chgrp ${config.home.username} ${path}*
|
||||
fi
|
||||
''
|
||||
}";
|
||||
};
|
||||
})
|
||||
config.programs.openssh.hostKeys
|
||||
);
|
||||
}
|
||||
)
|
||||
(lib.mkIf osConfig.host.impermanence.enable {
|
||||
home.persistence."/persist${config.home.homeDirectory}" = {
|
||||
files = lib.lists.flatten (
|
||||
builtins.map (hostKey: [".ssh/${hostKey.path}" ".ssh/${hostKey.path}.pub"]) config.programs.openssh.hostKeys
|
||||
);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
# this folder container modules that are for nixos only
|
||||
{...}: {
|
||||
imports = [
|
||||
./home-manager
|
||||
./system.nix
|
||||
./hardware.nix
|
||||
./users.nix
|
||||
./desktop.nix
|
||||
./ssh.nix
|
||||
./i18n.nix
|
||||
./sync.nix
|
||||
./impermanence.nix
|
||||
./disko.nix
|
||||
./ollama.nix
|
||||
./tailscale.nix
|
||||
./server
|
||||
];
|
||||
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"dotnet-sdk-6.0.428"
|
||||
];
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options.host.desktop.enable = lib.mkEnableOption "should desktop configuration be enabled";
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
host.desktop.enable = lib.mkDefault true;
|
||||
}
|
||||
(lib.mkIf config.host.desktop.enable {
|
||||
services = {
|
||||
# Enable CUPS to print documents.
|
||||
printing.enable = true;
|
||||
|
||||
xserver = {
|
||||
# Enable the X11 windowing system.
|
||||
enable = true;
|
||||
|
||||
# Enable the GNOME Desktop Environment.
|
||||
displayManager.gdm.enable = true;
|
||||
desktopManager = {
|
||||
gnome.enable = true;
|
||||
};
|
||||
|
||||
# Get rid of xTerm
|
||||
desktopManager.xterm.enable = false;
|
||||
excludePackages = with pkgs; [
|
||||
xterm
|
||||
atomix # puzzle game
|
||||
cheese # webcam tool
|
||||
epiphany # web browser
|
||||
geary # email reader
|
||||
gedit # text editor
|
||||
gnome-characters
|
||||
gnome-music
|
||||
gnome-photos
|
||||
gnome-tour
|
||||
gnome-logs
|
||||
gnome-maps
|
||||
hitori # sudoku game
|
||||
iagno # go game
|
||||
tali # poker game
|
||||
yelp # help viewer
|
||||
];
|
||||
};
|
||||
|
||||
pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
|
||||
# If you want to use JACK applications, uncomment this
|
||||
#jack.enable = true;
|
||||
|
||||
# use the example session manager (no others are packaged yet so this is enabled by default,
|
||||
# no need to redefine it in your config for now)
|
||||
#media-session.enable = true;
|
||||
};
|
||||
automatic-timezoned = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# Enable sound with pipewire.
|
||||
pulseaudio.enable = false;
|
||||
};
|
||||
|
||||
# enable RealtimeKit for pulse audio
|
||||
security.rtkit.enable = true;
|
||||
# disable welcome tour
|
||||
environment.gnome.excludePackages = [pkgs.gnome-tour];
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
# there currently is a bug with disko that causes long disk names to be generated improperly this hash function should alleviate it when used for disk names instead of what we are defaulting to
|
||||
# max gpt length is 36 and disk adds formats it like disk-xxxx-zfs which means we need to be 9 characters under that
|
||||
hashDisk = drive: (builtins.substring 0 27 (builtins.hashString "sha256" drive));
|
||||
|
||||
vdevs =
|
||||
builtins.map (
|
||||
disks:
|
||||
builtins.map (disk: lib.attrsets.nameValuePair (hashDisk disk) disk) disks
|
||||
)
|
||||
config.host.storage.pool.vdevs;
|
||||
cache =
|
||||
builtins.map (
|
||||
disk: lib.attrsets.nameValuePair (hashDisk disk) disk
|
||||
)
|
||||
config.host.storage.pool.cache;
|
||||
in {
|
||||
options.host.storage = {
|
||||
enable = lib.mkEnableOption "are we going create zfs disks with disko on this device";
|
||||
encryption = lib.mkEnableOption "is the vdev going to be encrypted";
|
||||
notifications = {
|
||||
enable = lib.mkEnableOption "are notifications enabled";
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what is the host that we are going to send the email to";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "what port is the host using to receive mail on";
|
||||
};
|
||||
to = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what account is the email going to be sent to";
|
||||
};
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what user is the email going to be set from";
|
||||
};
|
||||
tokenFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "file containing the password to be used by msmtp for notifications";
|
||||
};
|
||||
};
|
||||
pool = {
|
||||
vdevs = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.listOf lib.types.str);
|
||||
description = "list of disks that are going to be in";
|
||||
default = [config.host.storage.pool.drives];
|
||||
};
|
||||
drives = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "list of drives that are going to be in the vdev";
|
||||
default = [];
|
||||
};
|
||||
cache = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "list of drives that are going to be used as cache";
|
||||
default = [];
|
||||
};
|
||||
extraDatasets = lib.mkOption {
|
||||
type = lib.types.attrsOf (inputs.disko.lib.subType {
|
||||
types = {inherit (inputs.disko.lib.types) zfs_fs zfs_volume;};
|
||||
});
|
||||
description = "List of datasets to define";
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.storage.enable {
|
||||
programs.msmtp = lib.mkIf config.host.storage.notifications.enable {
|
||||
enable = true;
|
||||
setSendmail = true;
|
||||
defaults = {
|
||||
aliases = "/etc/aliases";
|
||||
port = config.host.storage.notifications.port;
|
||||
tls_trust_file = "/etc/ssl/certs/ca-certificates.crt";
|
||||
tls = "on";
|
||||
auth = "login";
|
||||
tls_starttls = "off";
|
||||
};
|
||||
accounts = {
|
||||
zfs_notifications = {
|
||||
host = config.host.storage.notifications.host;
|
||||
passwordeval = "cat ${config.host.storage.notifications.tokenFile}";
|
||||
user = config.host.storage.notifications.user;
|
||||
from = config.host.storage.notifications.user;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.zfs = {
|
||||
autoScrub.enable = true;
|
||||
autoSnapshot.enable = true;
|
||||
|
||||
zed = lib.mkIf config.host.storage.notifications.enable {
|
||||
# this option is broken we are just going to disable it
|
||||
enableMail = false;
|
||||
|
||||
settings = {
|
||||
ZED_DEBUG_LOG = "/tmp/zed.debug.log";
|
||||
ZED_EMAIL_ADDR = [config.host.storage.notifications.to];
|
||||
ZED_EMAIL_PROG = "${pkgs.msmtp}/bin/msmtp";
|
||||
ZED_EMAIL_OPTS = "@ADDRESS@";
|
||||
|
||||
ZED_NOTIFY_INTERVAL_SECS = 3600;
|
||||
ZED_NOTIFY_VERBOSE = true;
|
||||
|
||||
ZED_USE_ENCLOSURE_LEDS = true;
|
||||
ZED_SCRUB_AFTER_RESILVER = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
disko.devices = {
|
||||
disk = (
|
||||
builtins.listToAttrs (
|
||||
(
|
||||
builtins.map
|
||||
(drive:
|
||||
lib.attrsets.nameValuePair (drive.name) {
|
||||
type = "disk";
|
||||
device = "/dev/disk/by-id/${drive.value}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
zfs = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "zfs";
|
||||
pool = "rpool";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(lib.lists.flatten vdevs)
|
||||
)
|
||||
++ (
|
||||
builtins.map
|
||||
(drive:
|
||||
lib.attrsets.nameValuePair (drive.name) {
|
||||
type = "disk";
|
||||
device = "/dev/disk/by-id/${drive.value}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
# We are having to boot off of the nvm cache drive because I cant figure out how to boot via the HBA
|
||||
ESP = {
|
||||
# 2G here because its not much relative to how much storage we have for caching
|
||||
size = "2G";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = ["umask=0077"];
|
||||
};
|
||||
};
|
||||
zfs = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "zfs";
|
||||
pool = "rpool";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
cache
|
||||
)
|
||||
)
|
||||
);
|
||||
zpool = {
|
||||
rpool = {
|
||||
type = "zpool";
|
||||
mode = {
|
||||
topology = {
|
||||
type = "topology";
|
||||
vdev = (
|
||||
builtins.map (disks: {
|
||||
mode = "raidz2";
|
||||
members =
|
||||
builtins.map (disk: disk.name) disks;
|
||||
})
|
||||
vdevs
|
||||
);
|
||||
cache = builtins.map (disk: disk.name) cache;
|
||||
};
|
||||
};
|
||||
|
||||
options = {
|
||||
ashift = "12";
|
||||
autotrim = "on";
|
||||
};
|
||||
|
||||
rootFsOptions =
|
||||
{
|
||||
canmount = "off";
|
||||
mountpoint = "none";
|
||||
|
||||
xattr = "sa";
|
||||
acltype = "posixacl";
|
||||
relatime = "on";
|
||||
|
||||
compression = "lz4";
|
||||
|
||||
"com.sun:auto-snapshot" = "false";
|
||||
}
|
||||
// (
|
||||
lib.attrsets.optionalAttrs config.host.storage.encryption {
|
||||
encryption = "on";
|
||||
keyformat = "hex";
|
||||
keylocation = "prompt";
|
||||
}
|
||||
);
|
||||
|
||||
datasets = lib.mkMerge [
|
||||
(lib.attrsets.mapAttrs (name: value: {
|
||||
type = value.type;
|
||||
options = value.options;
|
||||
mountpoint = value.mountpoint;
|
||||
postCreateHook = value.postCreateHook;
|
||||
})
|
||||
config.host.storage.pool.extraDatasets)
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{lib, ...}: {
|
||||
options.host.hardware = {
|
||||
piperMouse = {
|
||||
enable = lib.mkEnableOption "host has a piper mouse";
|
||||
};
|
||||
viaKeyboard = {
|
||||
enable = lib.mkEnableOption "host has a via keyboard";
|
||||
};
|
||||
openRGB = {
|
||||
enable = lib.mkEnableOption "host has open rgb hardware";
|
||||
};
|
||||
graphicsAcceleration = {
|
||||
enable = lib.mkEnableOption "host has a gpu for graphical acceleration";
|
||||
};
|
||||
directAccess = {
|
||||
enable = lib.mkEnableOption "can a host be used on its own";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# modules in this folder are to adapt home-manager modules configs to nixos-module configs
|
||||
{...}: {
|
||||
imports = [
|
||||
./flipperzero.nix
|
||||
./i18n.nix
|
||||
./openssh.nix
|
||||
];
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
home-users = lib.attrsets.mapAttrsToList (_: user: user) config.home-manager.users;
|
||||
in {
|
||||
hardware.flipperzero.enable = lib.lists.any (home-user: home-user.hardware.flipperzero.enable) home-users;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
home-users = lib.attrsets.mapAttrsToList (_: user: user) config.home-manager.users;
|
||||
in {
|
||||
config = {
|
||||
i18n.supportedLocales =
|
||||
lib.unique
|
||||
(builtins.map (l: (lib.replaceStrings ["utf8" "utf-8" "UTF8"] ["UTF-8" "UTF-8" "UTF-8"] l) + "/UTF-8") (
|
||||
[
|
||||
"C.UTF-8"
|
||||
"en_US.UTF-8"
|
||||
config.i18n.defaultLocale
|
||||
]
|
||||
++ (lib.attrValues (lib.filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
|
||||
++ (
|
||||
map (user-config: user-config.i18n.defaultLocale) home-users
|
||||
)
|
||||
++ (lib.lists.flatten (
|
||||
map (user-config: lib.attrValues (lib.filterAttrs (n: v: n != "LANGUAGE") user-config.i18n.extraLocaleSettings)) home-users
|
||||
))
|
||||
));
|
||||
};
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
users.users =
|
||||
lib.attrsets.mapAttrs (name: value: {
|
||||
openssh.authorizedKeys.keys = value.programs.openssh.authorizedKeys;
|
||||
})
|
||||
config.home-manager.users;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{...}: {
|
||||
i18n.defaultLocale = "en_IE.UTF-8";
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
options.host.impermanence.enable = lib.mkEnableOption "are we going to use impermanence on this device";
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(config.host.impermanence.enable && !config.host.storage.enable);
|
||||
message = ''
|
||||
Disko storage must be enabled to use impermanence.
|
||||
'';
|
||||
}
|
||||
];
|
||||
}
|
||||
(
|
||||
lib.mkIf config.host.impermanence.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.host.impermanence.enable && config.host.storage.enable;
|
||||
message = "Impermanence can not be used without managed host storage.";
|
||||
}
|
||||
];
|
||||
|
||||
programs.fuse.userAllowOther = true;
|
||||
|
||||
boot.initrd.postResumeCommands = lib.mkAfter ''
|
||||
zfs rollback -r rpool/local/system/root@blank
|
||||
'';
|
||||
|
||||
fileSystems = {
|
||||
"/".neededForBoot = true;
|
||||
"/persist/system/root".neededForBoot = true;
|
||||
"/persist/system/var/log".neededForBoot = true;
|
||||
};
|
||||
|
||||
host.storage.pool.extraDatasets = {
|
||||
# local datasets are for data that should be considered ephemeral
|
||||
"local" = {
|
||||
type = "zfs_fs";
|
||||
options.canmount = "off";
|
||||
};
|
||||
# nix directory needs to be available pre persist and doesn't need to be snapshotted or backed up
|
||||
"local/system/nix" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/nix";
|
||||
options = {
|
||||
atime = "off";
|
||||
relatime = "off";
|
||||
canmount = "on";
|
||||
};
|
||||
};
|
||||
# dataset for root that gets rolled back on every boot
|
||||
"local/system/root" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/";
|
||||
options = {
|
||||
canmount = "on";
|
||||
};
|
||||
postCreateHook = ''
|
||||
zfs snapshot rpool/local/system/root@blank
|
||||
'';
|
||||
};
|
||||
|
||||
# persist datasets are datasets that contain information that we would like to keep around
|
||||
"persist" = {
|
||||
type = "zfs_fs";
|
||||
options.canmount = "off";
|
||||
options = {
|
||||
"com.sun:auto-snapshot" = "true";
|
||||
};
|
||||
};
|
||||
# this is where root data actually lives
|
||||
"persist/system/root" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/persist/system/root";
|
||||
};
|
||||
"persist/system/var/log" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/persist/system/var/log";
|
||||
# logs should be append only so we shouldn't need to snapshot them
|
||||
options = {
|
||||
"com.sun:auto-snapshot" = "false";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist/system/var/log" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
"/var/log"
|
||||
];
|
||||
};
|
||||
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
"/var/lib/nixos"
|
||||
"/var/lib/systemd/coredump"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
];
|
||||
};
|
||||
|
||||
security.sudo.extraConfig = "Defaults lecture=never";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
services.ollama = {
|
||||
group = "ollama";
|
||||
user = "ollama";
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable (lib.mkIf config.services.ollama.enable {
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = config.services.ollama.models;
|
||||
user = config.services.ollama.user;
|
||||
group = config.services.ollama.group;
|
||||
}
|
||||
];
|
||||
};
|
||||
}))
|
||||
];
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
dnsPort = 53;
|
||||
in {
|
||||
options.host.adguardhome = {
|
||||
enable = lib.mkEnableOption "should home-assistant be enabled on this computer";
|
||||
directory = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/AdGuardHome/";
|
||||
};
|
||||
};
|
||||
config = lib.mkIf config.host.adguardhome.enable (lib.mkMerge [
|
||||
{
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
mutableSettings = false;
|
||||
settings = {
|
||||
dns = {
|
||||
bootstrap_dns = [
|
||||
"1.1.1.1"
|
||||
"9.9.9.9"
|
||||
];
|
||||
upstream_dns = [
|
||||
"dns.quad9.net"
|
||||
];
|
||||
};
|
||||
filtering = {
|
||||
protection_enabled = true;
|
||||
filtering_enabled = true;
|
||||
|
||||
parental_enabled = false; # Parental control-based DNS requests filtering.
|
||||
safe_search = {
|
||||
enabled = false; # Enforcing "Safe search" option for search engines, when possible.
|
||||
};
|
||||
};
|
||||
# The following notation uses map
|
||||
# to not have to manually create {enabled = true; url = "";} for every filter
|
||||
# This is, however, fully optional
|
||||
filters =
|
||||
map (url: {
|
||||
enabled = true;
|
||||
url = url;
|
||||
}) [
|
||||
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt"
|
||||
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_9.txt" # The Big List of Hacked Malware Web Sites
|
||||
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_11.txt" # malicious url blocklist
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
dnsPort
|
||||
];
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = config.host.adguardhome.directory;
|
||||
user = "adguardhome";
|
||||
group = "adguardhome";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./fail2ban.nix
|
||||
./network_storage
|
||||
./reverse_proxy.nix
|
||||
./postgres.nix
|
||||
./podman.nix
|
||||
./jellyfin.nix
|
||||
./forgejo.nix
|
||||
./searx.nix
|
||||
./virt-home-assistant.nix
|
||||
./adguardhome.nix
|
||||
./immich.nix
|
||||
./qbittorent.nix
|
||||
];
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
dataFolder = "/var/lib/fail2ban";
|
||||
dataFile = "fail2ban.sqlite3";
|
||||
in {
|
||||
config = lib.mkIf config.services.fail2ban.enable (lib.mkMerge [
|
||||
{
|
||||
environment.etc = {
|
||||
"fail2ban/filter.d/nginx.local".text = lib.mkIf config.services.nginx.enable (
|
||||
pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
|
||||
[Definition]
|
||||
failregex = "limiting requests, excess:.* by zone.*client: <HOST>"
|
||||
'')
|
||||
);
|
||||
# "fail2ban/filter.d/hass.local".text = lib.mkIf config.services.home-assistant.enable (
|
||||
# pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
|
||||
# [INCLUDES]
|
||||
# before = common.conf
|
||||
|
||||
# [Definition]
|
||||
# failregex = ^%(__prefix_line)s.*Login attempt or request with invalid authentication from <HOST>.*$
|
||||
|
||||
# ignoreregex =
|
||||
|
||||
# [Init]
|
||||
# datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S
|
||||
# '')
|
||||
# );
|
||||
};
|
||||
|
||||
services.fail2ban = {
|
||||
maxretry = 5;
|
||||
ignoreIP = [
|
||||
# Whitelist local networks
|
||||
"10.0.0.0/8"
|
||||
"172.16.0.0/12"
|
||||
"192.168.0.0/16"
|
||||
|
||||
# tail scale tailnet
|
||||
"100.64.0.0/10"
|
||||
"fd7a:115c:a1e0::/48"
|
||||
];
|
||||
bantime = "24h"; # Ban IPs for one day on the first ban
|
||||
bantime-increment = {
|
||||
enable = true; # Enable increment of bantime after each violation
|
||||
formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)";
|
||||
maxtime = "168h"; # Do not ban for more than 1 week
|
||||
overalljails = true; # Calculate the ban time based on all the violations
|
||||
};
|
||||
jails = {
|
||||
nginx-iptables.settings = lib.mkIf config.services.nginx.enable {
|
||||
enabled = true;
|
||||
filter = "nginx";
|
||||
action = ''iptables-multiport[name=HTTP, port="http,https"]'';
|
||||
backend = "auto";
|
||||
findtime = 600;
|
||||
bantime = 600;
|
||||
maxretry = 5;
|
||||
};
|
||||
# home-assistant-iptables.settings = lib.mkIf config.services.home-assistant.enable {
|
||||
# enabled = true;
|
||||
# filter = "hass";
|
||||
# action = ''iptables-multiport[name=HTTP, port="http,https"]'';
|
||||
# logpath = "${config.services.home-assistant.configDir}/*.log";
|
||||
# backend = "auto";
|
||||
# findtime = 600;
|
||||
# bantime = 600;
|
||||
# maxretry = 5;
|
||||
# };
|
||||
# TODO; figure out if there is any fail2ban things we can do on searx
|
||||
# searx-iptables.settings = lib.mkIf config.services.searx.enable {};
|
||||
};
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.fail2ban.daemonSettings.Definition.dbfile == "${dataFolder}/${dataFile}";
|
||||
message = "fail2ban data file does not match persistence";
|
||||
}
|
||||
];
|
||||
|
||||
environment.persistence."/persist/system/root" = {
|
||||
directories = [
|
||||
{
|
||||
directory = dataFolder;
|
||||
user = "fail2ban";
|
||||
group = "fail2ban";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
forgejoPort = 8081;
|
||||
stateDir = "/var/lib/forgejo";
|
||||
db_user = "forgejo";
|
||||
sshPort = 22222;
|
||||
in {
|
||||
options.services.forgejo = {
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that forgejo will be hosted at";
|
||||
default = "forgejo";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.forgejo.enable (lib.mkMerge [
|
||||
{
|
||||
host = {
|
||||
reverse_proxy.subdomains.${config.services.forgejo.subdomain} = {
|
||||
target = "http://localhost:${toString forgejoPort}";
|
||||
};
|
||||
postgres = {
|
||||
enable = true;
|
||||
extraUsers = {
|
||||
${db_user} = {
|
||||
isClient = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.forgejo = {
|
||||
database = {
|
||||
type = "postgres";
|
||||
socket = "/run/postgresql";
|
||||
};
|
||||
lfs.enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = "${config.services.forgejo.subdomain}.${config.host.reverse_proxy.hostname}";
|
||||
HTTP_PORT = forgejoPort;
|
||||
START_SSH_SERVER = true;
|
||||
SSH_LISTEN_PORT = sshPort;
|
||||
SSH_PORT = 22;
|
||||
BUILTIN_SSH_SERVER_USER = config.users.users.git.name;
|
||||
ROOT_URL = "https://git.jan-leila.com";
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
};
|
||||
database = {
|
||||
DB_TYPE = "postgres";
|
||||
NAME = db_user;
|
||||
USER = db_user;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
config.services.forgejo.settings.server.SSH_LISTEN_PORT
|
||||
];
|
||||
}
|
||||
(lib.mkIf config.services.fail2ban.enable {
|
||||
environment.etc = {
|
||||
"fail2ban/filter.d/forgejo.local".text = lib.mkIf config.services.forgejo.enable (
|
||||
pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
|
||||
[Definition]
|
||||
failregex = ".*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>"
|
||||
'')
|
||||
);
|
||||
};
|
||||
|
||||
services.fail2ban = {
|
||||
jails = {
|
||||
forgejo-iptables.settings = lib.mkIf config.services.forgejo.enable {
|
||||
enabled = true;
|
||||
filter = "forgejo";
|
||||
action = ''iptables-multiport[name=HTTP, port="http,https"]'';
|
||||
logpath = "${config.services.forgejo.settings.log.ROOT_PATH}/*.log";
|
||||
backend = "auto";
|
||||
findtime = 600;
|
||||
bantime = 600;
|
||||
maxretry = 5;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.forgejo.stateDir == stateDir;
|
||||
message = "forgejo state directory does not match persistence";
|
||||
}
|
||||
];
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = stateDir;
|
||||
user = "forgejo";
|
||||
group = "forgejo";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
configDir = "/var/lib/hass";
|
||||
in {
|
||||
options.host.home-assistant = {
|
||||
enable = lib.mkEnableOption "should home-assistant be enabled on this computer";
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that home-assistant will be hosted at";
|
||||
default = "home-assistant";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.home-assistant.enable (lib.mkMerge [
|
||||
{
|
||||
virtualisation.libvirt = {
|
||||
swtpm.enable = true;
|
||||
connections."qemu:///session" = {
|
||||
networks = [
|
||||
{
|
||||
definition = inputs.nix-virt.lib.network.writeXML (inputs.nix-virt.lib.network.templates.bridge
|
||||
{
|
||||
uuid = "d57e37e2-311f-4e5c-a484-97c2210c2770";
|
||||
subnet_byte = 71;
|
||||
});
|
||||
active = true;
|
||||
}
|
||||
];
|
||||
domains = [
|
||||
{
|
||||
definition = inputs.nix-virt.lib.domain.writeXML (inputs.nix-virt.lib.domain.templates.linux
|
||||
{
|
||||
name = "Home Assistant";
|
||||
uuid = "c5cc0efc-6101-4c1d-be31-acbba203ccde";
|
||||
memory = {
|
||||
count = 4;
|
||||
unit = "GiB";
|
||||
};
|
||||
# storage_vol = {
|
||||
# pool = "MyPool";
|
||||
# volume = "Penguin.qcow2";
|
||||
# };
|
||||
});
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# systemd.tmpfiles.rules = [
|
||||
# "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass"
|
||||
# ];
|
||||
# services.home-assistant = {
|
||||
# enable = true;
|
||||
# configDir = configDir;
|
||||
# extraComponents = [
|
||||
# "met"
|
||||
# "radio_browser"
|
||||
# "isal"
|
||||
# "zha"
|
||||
# "jellyfin"
|
||||
# "webostv"
|
||||
# "tailscale"
|
||||
# "syncthing"
|
||||
# "sonos"
|
||||
# "analytics_insights"
|
||||
# "unifi"
|
||||
# "openweathermap"
|
||||
# ];
|
||||
# config = {
|
||||
# http = {
|
||||
# server_port = 8082;
|
||||
# use_x_forwarded_for = true;
|
||||
# trusted_proxies = ["127.0.0.1" "::1"];
|
||||
# ip_ban_enabled = true;
|
||||
# login_attempts_threshold = 10;
|
||||
# };
|
||||
# # recorder.db_url = "postgresql://@/${db_user}";
|
||||
# "automation manual" = [];
|
||||
# "automation ui" = "!include automations.yaml";
|
||||
# };
|
||||
# extraPackages = python3Packages:
|
||||
# with python3Packages; [
|
||||
# hassil
|
||||
# numpy
|
||||
# gtts
|
||||
# ];
|
||||
# };
|
||||
# host = {
|
||||
# reverse_proxy.subdomains.${config.host.home-assistant.subdomain} = {
|
||||
# target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}";
|
||||
|
||||
# websockets.enable = true;
|
||||
# forwardHeaders.enable = true;
|
||||
|
||||
# extraConfig = ''
|
||||
# add_header Upgrade $http_upgrade;
|
||||
# add_header Connection \"upgrade\";
|
||||
|
||||
# proxy_buffering off;
|
||||
|
||||
# proxy_read_timeout 90;
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
# assertions = [
|
||||
# {
|
||||
# assertion = config.services.home-assistant.configDir == configDir;
|
||||
# message = "home assistant config directory does not match persistence";
|
||||
# }
|
||||
# ];
|
||||
# environment.persistence."/persist/system/root" = {
|
||||
# enable = true;
|
||||
# hideMounts = true;
|
||||
# directories = [
|
||||
# {
|
||||
# directory = configDir;
|
||||
# user = "hass";
|
||||
# group = "hass";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
mediaLocation = "/var/lib/immich";
|
||||
in {
|
||||
options.services.immich = {
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that immich will be hosted at";
|
||||
default = "immich";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.immich.enable (lib.mkMerge [
|
||||
{
|
||||
host = {
|
||||
reverse_proxy.subdomains.${config.services.immich.subdomain} = {
|
||||
target = "http://localhost:${toString config.services.immich.port}";
|
||||
|
||||
websockets.enable = true;
|
||||
forwardHeaders.enable = true;
|
||||
|
||||
extraConfig = ''
|
||||
# allow large file uploads
|
||||
client_max_body_size 50000M;
|
||||
|
||||
# set timeout
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
send_timeout 600s;
|
||||
proxy_redirect off;
|
||||
'';
|
||||
};
|
||||
postgres = {
|
||||
enable = true;
|
||||
extraUsers = {
|
||||
${config.services.immich.database.user} = {
|
||||
isClient = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.${config.services.tailscale.interfaceName} = {
|
||||
allowedUDPPorts = [
|
||||
config.services.immich.port
|
||||
];
|
||||
allowedTCPPorts = [
|
||||
config.services.immich.port
|
||||
];
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.services.fail2ban.enable {
|
||||
environment.etc = {
|
||||
"fail2ban/filter.d/immich.local".text = lib.mkIf config.services.immich.enable (
|
||||
pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
|
||||
[Definition]
|
||||
failregex = immich-server.*Failed login attempt for user.+from ip address\s?<ADDR>
|
||||
journalmatch = CONTAINER_TAG=immich-server
|
||||
'')
|
||||
);
|
||||
};
|
||||
|
||||
services.fail2ban = {
|
||||
jails = {
|
||||
immich-iptables.settings = lib.mkIf config.services.immich.enable {
|
||||
enabled = true;
|
||||
filter = "immich";
|
||||
backend = "systemd";
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.immich.mediaLocation == mediaLocation;
|
||||
message = "immich media location does not match persistence";
|
||||
}
|
||||
];
|
||||
environment.persistence."/persist/system/root" = {
|
||||
directories = [
|
||||
{
|
||||
directory = mediaLocation;
|
||||
user = "immich";
|
||||
group = "immich";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
jellyfinPort = 8096;
|
||||
dlanPort = 1900;
|
||||
jellyfin_data_directory = "/var/lib/jellyfin";
|
||||
jellyfin_cache_directory = "/var/cache/jellyfin";
|
||||
in {
|
||||
options.services.jellyfin = {
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that jellyfin will be hosted at";
|
||||
default = "jellyfin";
|
||||
};
|
||||
extraSubdomains = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "ex subdomain of base domain that jellyfin will be hosted at";
|
||||
default = [];
|
||||
};
|
||||
media_directory = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "directory jellyfin media will be hosted at";
|
||||
default = "/srv/jellyfin/media";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.jellyfin.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
host.reverse_proxy.subdomains.jellyfin = {
|
||||
target = "http://localhost:${toString jellyfinPort}";
|
||||
|
||||
subdomain = config.services.jellyfin.subdomain;
|
||||
extraSubdomains = config.services.jellyfin.extraSubdomains;
|
||||
|
||||
forwardHeaders.enable = true;
|
||||
|
||||
extraConfig = ''
|
||||
client_max_body_size 20M;
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
proxy_buffering off;
|
||||
'';
|
||||
};
|
||||
environment.systemPackages = [
|
||||
pkgs.jellyfin
|
||||
pkgs.jellyfin-web
|
||||
pkgs.jellyfin-ffmpeg
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [jellyfinPort dlanPort];
|
||||
}
|
||||
(lib.mkIf config.services.fail2ban.enable {
|
||||
environment.etc = {
|
||||
"fail2ban/filter.d/jellyfin.local".text = lib.mkIf config.services.jellyfin.enable (
|
||||
pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
|
||||
[Definition]
|
||||
failregex = "^.*Authentication request for .* has been denied \\\(IP: \"<ADDR>\"\\\)\\\."
|
||||
'')
|
||||
);
|
||||
};
|
||||
|
||||
services.fail2ban = {
|
||||
jails = {
|
||||
jellyfin-iptables.settings = lib.mkIf config.services.jellyfin.enable {
|
||||
enabled = true;
|
||||
filter = "jellyfin";
|
||||
action = ''iptables-multiport[name=HTTP, port="http,https"]'';
|
||||
logpath = "${config.services.jellyfin.dataDir}/log/*.log";
|
||||
backend = "auto";
|
||||
findtime = 600;
|
||||
bantime = 600;
|
||||
maxretry = 5;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
fileSystems."/persist/system/jellyfin".neededForBoot = true;
|
||||
|
||||
host.storage.pool.extraDatasets = {
|
||||
# sops age key needs to be available to pre persist for user generation
|
||||
"persist/system/jellyfin" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/persist/system/jellyfin";
|
||||
options = {
|
||||
atime = "off";
|
||||
relatime = "off";
|
||||
canmount = "on";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.jellyfin.dataDir == jellyfin_data_directory;
|
||||
message = "jellyfin data directory does not match persistence";
|
||||
}
|
||||
{
|
||||
assertion = config.services.jellyfin.cacheDir == jellyfin_cache_directory;
|
||||
message = "jellyfin cache directory does not match persistence";
|
||||
}
|
||||
];
|
||||
|
||||
environment.persistence = {
|
||||
"/persist/system/root" = {
|
||||
directories = [
|
||||
{
|
||||
directory = jellyfin_data_directory;
|
||||
user = "jellyfin";
|
||||
group = "jellyfin";
|
||||
}
|
||||
{
|
||||
directory = jellyfin_cache_directory;
|
||||
user = "jellyfin";
|
||||
group = "jellyfin";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
"/persist/system/jellyfin" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = config.services.jellyfin.media_directory;
|
||||
user = "jellyfin";
|
||||
group = "jellyfin_media";
|
||||
mode = "1770";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
export_directory = config.host.network_storage.export_directory;
|
||||
in {
|
||||
imports = [
|
||||
./nfs.nix
|
||||
];
|
||||
|
||||
options = {
|
||||
host.network_storage = {
|
||||
enable = lib.mkEnableOption "is this machine going to export network storage";
|
||||
export_directory = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "what are exports going to be stored in";
|
||||
default = "/export";
|
||||
};
|
||||
directories = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.submodule ({config, ...}: {
|
||||
options = {
|
||||
folder = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what is the name of this export directory";
|
||||
};
|
||||
bind = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
description = "is this directory bound to anywhere";
|
||||
default = null;
|
||||
};
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what user owns this directory";
|
||||
default = "nouser";
|
||||
};
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what group owns this directory";
|
||||
default = "nogroup";
|
||||
};
|
||||
_directory = lib.mkOption {
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
type = lib.types.path;
|
||||
default = "${export_directory}/${config.folder}";
|
||||
};
|
||||
};
|
||||
}));
|
||||
description = "list of directory names to export";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.network_storage.enable (lib.mkMerge [
|
||||
{
|
||||
# create any folders that we need to have for our exports
|
||||
systemd.tmpfiles.rules =
|
||||
[
|
||||
"d ${config.host.network_storage.export_directory} 2775 nobody nogroup -"
|
||||
]
|
||||
++ (
|
||||
builtins.map (
|
||||
directory: "d ${directory._directory} 2770 ${directory.user} ${directory.group}"
|
||||
)
|
||||
config.host.network_storage.directories
|
||||
);
|
||||
|
||||
# set up any bind mounts that we need for our exports
|
||||
fileSystems = builtins.listToAttrs (
|
||||
builtins.map (directory:
|
||||
lib.attrsets.nameValuePair directory._directory {
|
||||
device = directory.bind;
|
||||
options = ["bind"];
|
||||
}) (
|
||||
builtins.filter (directory: directory.bind != null) config.host.network_storage.directories
|
||||
)
|
||||
);
|
||||
}
|
||||
# (lib.mkIf config.host.impermanence.enable {
|
||||
# environment.persistence."/persist/system/root" = {
|
||||
# enable = true;
|
||||
# hideMounts = true;
|
||||
# directories = [
|
||||
# config.host.network_storage.export_directory
|
||||
# ];
|
||||
# };
|
||||
# })
|
||||
]);
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
host.network_storage.nfs = {
|
||||
enable = lib.mkEnableOption "is this server going to export network storage as nfs shares";
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2049;
|
||||
description = "port that nfs will run on";
|
||||
};
|
||||
directories = lib.mkOption {
|
||||
type = lib.types.listOf (
|
||||
lib.types.enum (
|
||||
builtins.map (
|
||||
directory: directory.folder
|
||||
)
|
||||
config.host.network_storage.directories
|
||||
)
|
||||
);
|
||||
description = "list of exported directories to be exported via nfs";
|
||||
};
|
||||
};
|
||||
};
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(config.host.network_storage.nfs.enable && !config.host.network_storage.enable);
|
||||
message = "nfs cant be enabled with network storage disabled";
|
||||
}
|
||||
];
|
||||
}
|
||||
(
|
||||
lib.mkIf (config.host.network_storage.nfs.enable && config.host.network_storage.enable) {
|
||||
services.nfs = {
|
||||
settings = {
|
||||
nfsd = {
|
||||
threads = 32;
|
||||
port = config.host.network_storage.nfs.port;
|
||||
};
|
||||
};
|
||||
server = {
|
||||
enable = true;
|
||||
|
||||
lockdPort = 4001;
|
||||
mountdPort = 4002;
|
||||
statdPort = 4000;
|
||||
|
||||
exports = lib.strings.concatLines (
|
||||
[
|
||||
"${config.host.network_storage.export_directory} 100.64.0.0/10(rw,fsid=0,no_subtree_check)"
|
||||
]
|
||||
++ (
|
||||
lib.lists.imap0 (
|
||||
i: directory: let
|
||||
createOptions = fsid: "(rw,fsid=${toString fsid},nohide,insecure,no_subtree_check)";
|
||||
addresses = [
|
||||
# loopback
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
# local network
|
||||
# "192.168.0.0/24"
|
||||
# tailscale
|
||||
"100.64.0.0/10"
|
||||
"fd7a:115c:a1e0::/48"
|
||||
];
|
||||
options = lib.strings.concatStrings (
|
||||
lib.strings.intersperse " " (
|
||||
lib.lists.imap0 (index: address: "${address}${createOptions (1 + (i * (builtins.length addresses)) + index)}") addresses
|
||||
)
|
||||
);
|
||||
in "${directory._directory} ${options}"
|
||||
)
|
||||
(
|
||||
builtins.filter (
|
||||
directory: lib.lists.any (target: target == directory.folder) config.host.network_storage.nfs.directories
|
||||
)
|
||||
config.host.network_storage.directories
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
networking.firewall.interfaces.${config.services.tailscale.interfaceName} = let
|
||||
ports = [
|
||||
111
|
||||
config.host.network_storage.nfs.port
|
||||
config.services.nfs.server.lockdPort
|
||||
config.services.nfs.server.mountdPort
|
||||
config.services.nfs.server.statdPort
|
||||
20048
|
||||
];
|
||||
in {
|
||||
allowedTCPPorts = ports;
|
||||
allowedUDPPorts = ports;
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options.host.podman = {
|
||||
enable = lib.mkEnableOption "should home-assistant be enabled on this computer";
|
||||
macvlan = {
|
||||
subnet = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Subnet for macvlan address range";
|
||||
};
|
||||
gateway = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Gateway for macvlan";
|
||||
# TODO: see if we can default this to systemd network gateway
|
||||
};
|
||||
networkInterface = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Parent network interface for macvlan";
|
||||
# TODO: see if we can default this some interface?
|
||||
};
|
||||
};
|
||||
};
|
||||
config = lib.mkIf config.host.podman.enable {
|
||||
systemd = {
|
||||
services = {
|
||||
# "podman-network-macvlan" = {
|
||||
# path = [pkgs.podman];
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = true;
|
||||
# ExecStop = "podman network rm -f macvlan";
|
||||
# };
|
||||
# script = ''
|
||||
# podman network inspect macvlan || podman network create --driver macvlan --subnet ${config.host.podman.macvlan.subnet} --gateway ${config.host.podman.macvlan.gateway} --opt parent=${config.host.podman.macvlan.networkInterface} macvlan
|
||||
# '';
|
||||
# partOf = ["podman-compose-root.target"];
|
||||
# wantedBy = ["podman-compose-root.target"];
|
||||
# };
|
||||
};
|
||||
# disable computer sleeping
|
||||
targets = {
|
||||
# Root service
|
||||
# When started, this will automatically create all resources and start
|
||||
# the containers. When stopped, this will teardown all resources.
|
||||
"podman-compose-root" = {
|
||||
unitConfig = {
|
||||
Description = "Root target for podman targets.";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
# Runtime
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
# defaultNetwork.settings = {
|
||||
# # Required for container networking to be able to use names.
|
||||
# dns_enabled = true;
|
||||
# };
|
||||
};
|
||||
|
||||
oci-containers = {
|
||||
backend = "podman";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
dataDir = "/var/lib/postgresql/16";
|
||||
adminUsers = lib.lists.filter (user: user.isAdmin) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers);
|
||||
clientUsers = lib.lists.filter (user: user.isClient) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers);
|
||||
createUsers = lib.lists.filter (user: user.createUser) (lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraUsers);
|
||||
createDatabases = lib.attrsets.mapAttrsToList (_: user: user) config.host.postgres.extraDatabases;
|
||||
in {
|
||||
options = {
|
||||
host.postgres = {
|
||||
enable = lib.mkEnableOption "enable postgres";
|
||||
extraUsers = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
};
|
||||
isAdmin = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
isClient = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
createUser = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = {};
|
||||
};
|
||||
extraDatabases = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.postgres.enable (lib.mkMerge [
|
||||
{
|
||||
services = {
|
||||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_16;
|
||||
ensureUsers =
|
||||
[
|
||||
{
|
||||
name = "postgres";
|
||||
}
|
||||
]
|
||||
++ (
|
||||
builtins.map (user: {
|
||||
name = user.name;
|
||||
ensureDBOwnership = true;
|
||||
})
|
||||
createUsers
|
||||
);
|
||||
ensureDatabases = builtins.map (database: database.name) createDatabases;
|
||||
identMap =
|
||||
''
|
||||
# ArbitraryMapName systemUser DBUser
|
||||
|
||||
# Administration Users
|
||||
superuser_map root postgres
|
||||
superuser_map postgres postgres
|
||||
''
|
||||
+ (
|
||||
lib.strings.concatLines (builtins.map (user: "superuser_map ${user.name} postgres") adminUsers)
|
||||
)
|
||||
+ ''
|
||||
|
||||
# Client Users
|
||||
''
|
||||
+ (
|
||||
lib.strings.concatLines (builtins.map (user: "user_map ${user.name} ${user.name}") clientUsers)
|
||||
);
|
||||
# configuration here lets users access the db that matches their name and lets user postgres access everything
|
||||
authentication = pkgs.lib.mkOverride 10 ''
|
||||
# type database DBuser origin-address auth-method optional_ident_map
|
||||
local all postgres peer map=superuser_map
|
||||
local sameuser all peer map=user_map
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.postgresql.dataDir == dataDir;
|
||||
message = "postgres data directory does not match persistence";
|
||||
}
|
||||
];
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = dataDir;
|
||||
user = "postgres";
|
||||
group = "postgres";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
qbittorent_data_directory = "/var/lib/qbittorrent";
|
||||
in {
|
||||
options.services.qbittorrent = {
|
||||
enable = lib.mkEnableOption "should the headless qbittorrent service be enabled";
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
The directory where qBittorrent stores its data files.
|
||||
'';
|
||||
};
|
||||
|
||||
mediaDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = lib.mdDoc ''
|
||||
The directory to create to store qbittorrent media.
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
User account under which qBittorrent runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "qbittorrent";
|
||||
description = lib.mdDoc ''
|
||||
Group under which qBittorrent runs.
|
||||
'';
|
||||
};
|
||||
|
||||
webPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8080;
|
||||
description = lib.mdDoc ''
|
||||
qBittorrent web UI port.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open services.qBittorrent.webPort to the outside network.";
|
||||
};
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.qbittorrent-nox;
|
||||
defaultText = lib.literalExpression "pkgs.qbittorrent-nox";
|
||||
description = "The qbittorrent package to use.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.qbittorrent.enable (lib.mkMerge [
|
||||
{
|
||||
networking.firewall = lib.mkIf config.services.qbittorrent.openFirewall {
|
||||
allowedTCPPorts = [config.services.qbittorrent.webPort];
|
||||
};
|
||||
|
||||
systemd.services.qbittorrent = {
|
||||
# based on the plex.nix service module and
|
||||
# https://github.com/qbittorrent/qBittorrent/blob/master/dist/unix/systemd/qbittorrent-nox%40.service.in
|
||||
description = "qBittorrent-nox service";
|
||||
documentation = ["man:qbittorrent-nox(1)"];
|
||||
after = ["network.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = config.services.qbittorrent.user;
|
||||
Group = config.services.qbittorrent.group;
|
||||
|
||||
# Run the pre-start script with full permissions (the "!" prefix) so it
|
||||
# can create the data directory if necessary.
|
||||
ExecStartPre = let
|
||||
preStartScript = pkgs.writeScript "qbittorrent-run-prestart" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
# Create data directory if it doesn't exist
|
||||
if ! test -d "$QBT_PROFILE"; then
|
||||
echo "Creating initial qBittorrent data directory in: $QBT_PROFILE"
|
||||
install -d -m 0755 -o "${config.services.qbittorrent.user}" -g "${config.services.qbittorrent.group}" "$QBT_PROFILE"
|
||||
fi
|
||||
'';
|
||||
in "!${preStartScript}";
|
||||
|
||||
#ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox";
|
||||
ExecStart = "${config.services.qbittorrent.package}/bin/qbittorrent-nox";
|
||||
# To prevent "Quit & shutdown daemon" from working; we want systemd to
|
||||
# manage it!
|
||||
#Restart = "on-success";
|
||||
#UMask = "0002";
|
||||
#LimitNOFILE = cfg.openFilesLimit;
|
||||
};
|
||||
|
||||
environment = {
|
||||
QBT_PROFILE = config.services.qbittorrent.dataDir;
|
||||
QBT_WEBUI_PORT = toString config.services.qbittorrent.webPort;
|
||||
};
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
fileSystems."/persist/system/qbittorrent".neededForBoot = true;
|
||||
|
||||
host.storage.pool.extraDatasets = {
|
||||
# sops age key needs to be available to pre persist for user generation
|
||||
"persist/system/qbittorrent" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/persist/system/qbittorrent";
|
||||
options = {
|
||||
canmount = "on";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.services.qbittorrent.dataDir == qbittorent_data_directory;
|
||||
message = "qbittorrent data directory does not match persistence";
|
||||
}
|
||||
];
|
||||
|
||||
environment.persistence = {
|
||||
"/persist/system/root" = {
|
||||
directories = [
|
||||
{
|
||||
directory = qbittorent_data_directory;
|
||||
user = "qbittorrent";
|
||||
group = "qbittorrent";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
"/persist/system/qbittorrent" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = config.services.qbittorrent.mediaDir;
|
||||
user = "qbittorrent";
|
||||
group = "qbittorrent";
|
||||
mode = "1775";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
dataDir = "/var/lib/acme";
|
||||
httpPort = 80;
|
||||
httpsPort = 443;
|
||||
in {
|
||||
options.host.reverse_proxy = {
|
||||
enable = lib.mkEnableOption "turn on the reverse proxy";
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what host name are we going to be proxying from";
|
||||
};
|
||||
forceSSL = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "force connections to use https";
|
||||
default = config.host.reverse_proxy.enableACME;
|
||||
};
|
||||
enableACME = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "auto renew certificates";
|
||||
default = true;
|
||||
};
|
||||
subdomains = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
|
||||
options = {
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what is the default subdomain to be used for this application to be used for";
|
||||
default = name;
|
||||
};
|
||||
extraSubdomains = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "extra domains that should be configured for this domain";
|
||||
default = [];
|
||||
};
|
||||
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what url will all traffic to this application be forwarded to";
|
||||
};
|
||||
|
||||
websockets.enable = lib.mkEnableOption "should the default config proxy websockets";
|
||||
|
||||
forwardHeaders.enable = lib.mkEnableOption "should the default config contain forward headers";
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
These lines go to the end of the upstream verbatim.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.host.reverse_proxy.enable (lib.mkMerge [
|
||||
{
|
||||
security.acme = lib.mkIf config.host.reverse_proxy.enableACME {
|
||||
acceptTerms = true;
|
||||
defaults.email = "jan-leila@protonmail.com";
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = lib.mkMerge (
|
||||
lib.lists.flatten (
|
||||
lib.attrsets.mapAttrsToList (
|
||||
name: value: let
|
||||
hostConfig = {
|
||||
forceSSL = config.host.reverse_proxy.forceSSL;
|
||||
enableACME = config.host.reverse_proxy.enableACME;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = value.target;
|
||||
proxyWebsockets = value.websockets.enable;
|
||||
recommendedProxySettings = value.forwardHeaders.enable;
|
||||
extraConfig =
|
||||
value.extraConfig;
|
||||
};
|
||||
};
|
||||
};
|
||||
in (
|
||||
[
|
||||
{
|
||||
${"${value.subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig;
|
||||
}
|
||||
]
|
||||
++ builtins.map (subdomain: {${"${subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig;})
|
||||
value.extraSubdomains
|
||||
)
|
||||
)
|
||||
config.host.reverse_proxy.subdomains
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
httpPort
|
||||
httpsPort
|
||||
];
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
# TODO: figure out how to write an assertion for this
|
||||
# assertions = [
|
||||
# {
|
||||
# assertion = security.acme.certs.<name>.directory == dataDir;
|
||||
# message = "postgres data directory does not match persistence";
|
||||
# }
|
||||
# ];
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = dataDir;
|
||||
user = "acme";
|
||||
group = "acme";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
options.services.searx = {
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that searx will be hosted at";
|
||||
default = "searx";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.searx.enable {
|
||||
sops.secrets = {
|
||||
"services/searx" = {
|
||||
sopsFile = "${inputs.secrets}/defiant-services.yaml";
|
||||
};
|
||||
};
|
||||
host = {
|
||||
reverse_proxy.subdomains.searx = {
|
||||
subdomain = config.services.searx.subdomain;
|
||||
target = "http://localhost:${toString config.services.searx.settings.server.port}";
|
||||
};
|
||||
};
|
||||
services.searx = {
|
||||
environmentFile = config.sops.secrets."services/searx".path;
|
||||
|
||||
# Rate limiting
|
||||
limiterSettings = {
|
||||
real_ip = {
|
||||
x_for = 1;
|
||||
ipv4_prefix = 32;
|
||||
ipv6_prefix = 56;
|
||||
};
|
||||
|
||||
botdetection = {
|
||||
ip_limit = {
|
||||
filter_link_local = true;
|
||||
link_token = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
port = 8083;
|
||||
secret_key = "@SEARXNG_SECRET@";
|
||||
};
|
||||
|
||||
# Search engine settings
|
||||
search = {
|
||||
safe_search = 2;
|
||||
autocomplete_min = 2;
|
||||
autocomplete = "duckduckgo";
|
||||
};
|
||||
|
||||
# Enabled plugins
|
||||
enabled_plugins = [
|
||||
"Basic Calculator"
|
||||
"Hash plugin"
|
||||
"Tor check plugin"
|
||||
"Open Access DOI rewrite"
|
||||
"Hostnames plugin"
|
||||
"Unit converter plugin"
|
||||
"Tracker URL remover"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
options.services.virt-home-assistant = {
|
||||
enable = lib.mkEnableOption "Wether to enable home assistant virtual machine";
|
||||
networkBridge = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what network bridge should we attach to the image";
|
||||
};
|
||||
hostDevice = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what host devices should be attached to the image";
|
||||
};
|
||||
initialVersion = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what home assistant image version should we pull for initial instal";
|
||||
default = "15.0";
|
||||
};
|
||||
imageName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "where should the image be installed to";
|
||||
default = "home-assistant.qcow2";
|
||||
};
|
||||
installLocation = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "where should the image be installed to";
|
||||
default = "/etc/hass";
|
||||
};
|
||||
virtualMachineName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "what name should we give the virtual machine";
|
||||
default = "home-assistant";
|
||||
};
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "subdomain of base domain that home-assistant will be hosted at";
|
||||
default = "home-assistant";
|
||||
};
|
||||
};
|
||||
config = lib.mkIf config.services.virt-home-assistant.enable (lib.mkMerge [
|
||||
{
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# virt-manager
|
||||
# ];
|
||||
|
||||
# TODO: move this to external module and just have an assertion here that its enabled
|
||||
# enable virtualization on the system
|
||||
virtualisation = {
|
||||
libvirtd = {
|
||||
enable = true;
|
||||
qemu.ovmf.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: deactivation script?
|
||||
# create service to install and start the container
|
||||
systemd.services.virt-install-home-assistant = let
|
||||
# TODO: all of these need to be escaped to be used in commands reliably
|
||||
bridgedNetwork = config.services.virt-home-assistant.networkBridge;
|
||||
hostDevice = config.services.virt-home-assistant.hostDevice;
|
||||
virtualMachineName = config.services.virt-home-assistant.virtualMachineName;
|
||||
imageName = config.services.virt-home-assistant.imageName;
|
||||
installLocation = config.services.virt-home-assistant.installLocation;
|
||||
installImage = "${installLocation}/${imageName}";
|
||||
initialVersion = config.services.virt-home-assistant.initialVersion;
|
||||
|
||||
home-assistant-qcow2 = pkgs.fetchurl {
|
||||
name = "home-assistant.qcow2";
|
||||
url = "https://github.com/home-assistant/operating-system/releases/download/${initialVersion}/haos_ova-${initialVersion}.qcow2.xz";
|
||||
hash = "sha256-V1BEjvvLNbMMKJVyMCmipjQ/3owoJteeVxoF9LDHo1U=";
|
||||
postFetch = ''
|
||||
cp $out src.xz
|
||||
rm -r $out
|
||||
${pkgs.xz}/bin/unxz src.xz --stdout > $out/${imageName}
|
||||
'';
|
||||
};
|
||||
|
||||
# Write a script to install the Home Assistant OS qcow2 image
|
||||
virtInstallScript = pkgs.writeShellScriptBin "virt-install-hass" ''
|
||||
# Copy the initial image out of the package store to the install location if we don't have one yet
|
||||
if [ ! -f ${installImage} ]; then
|
||||
cp ${home-assistant-qcow2} ${installLocation}
|
||||
fi
|
||||
|
||||
# Check if VM already exists, and other pre-conditions
|
||||
if ! ${pkgs.libvirt}/bin/virsh list --all | grep -q ${virtualMachineName}; then
|
||||
${pkgs.virt-manager}/bin/virt-install --name ${virtualMachineName} \
|
||||
--description "Home Assistant OS" \
|
||||
--os-variant=generic \
|
||||
--boot uefi \
|
||||
--ram=2048 \
|
||||
--vcpus=2 \
|
||||
--import \
|
||||
--disk ${installImage},bus=sata \
|
||||
--network bridge=${bridgedNetwork} \
|
||||
--host-device ${hostDevice} \
|
||||
--graphics none
|
||||
${pkgs.libvirt}/bin/virsh autostart ${virtualMachineName}
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
description = "Install and start Home Assistant";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["local-fs.target"];
|
||||
requires = ["libvirtd.service"];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig = {
|
||||
ExecStart = "${virtInstallScript}/bin/virt-install-hass";
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: figure out what we need to proxy to the virtual image
|
||||
# host = {
|
||||
# reverse_proxy.subdomains.${config.services.virt-home-assistant.subdomain} = {
|
||||
# target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}";
|
||||
|
||||
# websockets.enable = true;
|
||||
# forwardHeaders.enable = true;
|
||||
|
||||
# extraConfig = ''
|
||||
# add_header Upgrade $http_upgrade;
|
||||
# add_header Connection \"upgrade\";
|
||||
|
||||
# proxy_buffering off;
|
||||
|
||||
# proxy_read_timeout 90;
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
}
|
||||
(lib.mkIf config.services.fail2ban.enable {
|
||||
# TODO: figure out how to write a config for this, prob based on nginx proxy logs?
|
||||
})
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
# assertions = [
|
||||
# {
|
||||
# assertion = config.services.virt-home-assistant.installLocation == configDir;
|
||||
# message = "home assistant install location does not match persistence";
|
||||
# }
|
||||
# ];
|
||||
environment.persistence."/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = config.services.virt-home-assistant.installLocation;
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
services = {
|
||||
openssh = {
|
||||
enable = true;
|
||||
ports = [22];
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
UseDns = true;
|
||||
X11Forwarding = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
environment.persistence."/persist/system/root" = {
|
||||
files = lib.lists.flatten (
|
||||
builtins.map (hostKey: [hostKey.path "${hostKey.path}.pub"]) config.services.openssh.hostKeys
|
||||
);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
outputs,
|
||||
...
|
||||
}: let
|
||||
mountDir = "/mnt/sync";
|
||||
configDir = "/etc/syncthing";
|
||||
in {
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
systemd = lib.mkIf config.services.syncthing.enable {
|
||||
tmpfiles.rules = [
|
||||
"d ${mountDir} 2755 syncthing syncthing -"
|
||||
"d ${config.services.syncthing.dataDir} 775 syncthing syncthing -"
|
||||
"d ${config.services.syncthing.configDir} 755 syncthing syncthing -"
|
||||
];
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.services.syncthing.enable (lib.mkMerge [
|
||||
{
|
||||
services.syncthing = {
|
||||
user = "syncthing";
|
||||
group = "syncthing";
|
||||
dataDir = "${mountDir}/default";
|
||||
configDir = configDir;
|
||||
overrideDevices = true;
|
||||
overrideFolders = true;
|
||||
configuration = outputs.syncthingConfiguration;
|
||||
deviceName = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
assertions =
|
||||
[
|
||||
{
|
||||
assertion = config.services.syncthing.configDir == configDir;
|
||||
message = "syncthing config dir does not match persistence";
|
||||
}
|
||||
]
|
||||
++ lib.attrsets.mapAttrsToList (_: folder: {
|
||||
assertion = lib.strings.hasPrefix mountDir folder.path;
|
||||
message = "syncthing folder ${folder.label} is stored at ${folder.path} which not under the persisted path of ${mountDir}";
|
||||
})
|
||||
config.services.syncthing.settings.folders;
|
||||
environment.persistence = {
|
||||
"/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = mountDir;
|
||||
user = "syncthing";
|
||||
group = "syncthing";
|
||||
}
|
||||
{
|
||||
directory = configDir;
|
||||
user = "syncthing";
|
||||
group = "syncthing";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
]))
|
||||
];
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
{...}: {
|
||||
nix = {
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
optimise = {
|
||||
automatic = true;
|
||||
dates = ["weekly"];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
tailscale_data_directory = "/var/lib/tailscale";
|
||||
in {
|
||||
options.host.tailscale = {
|
||||
enable = lib.mkEnableOption "should tailscale be enabled on this computer";
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.tailscale.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
# any configs we want shared between all machines
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
environment.persistence = {
|
||||
"/persist/system/root" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
{
|
||||
directory = tailscale_data_directory;
|
||||
user = "root";
|
||||
group = "root";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
|
@ -1,352 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
SOPS_AGE_KEY_DIRECTORY = import ../../const/sops_age_key_directory.nix;
|
||||
|
||||
host = config.host;
|
||||
|
||||
principleUsers = host.principleUsers;
|
||||
terminalUsers = host.terminalUsers;
|
||||
normalUsers = host.normalUsers;
|
||||
|
||||
uids = {
|
||||
leyla = 1000;
|
||||
eve = 1002;
|
||||
jellyfin = 2000;
|
||||
forgejo = 2002;
|
||||
adguardhome = 2003;
|
||||
hass = 2004;
|
||||
syncthing = 2007;
|
||||
ollama = 2008;
|
||||
git = 2009;
|
||||
immich = 2010;
|
||||
qbittorrent = 2011;
|
||||
};
|
||||
|
||||
gids = {
|
||||
leyla = 1000;
|
||||
eve = 1002;
|
||||
users = 100;
|
||||
jellyfin_media = 2001;
|
||||
jellyfin = 2000;
|
||||
forgejo = 2002;
|
||||
adguardhome = 2003;
|
||||
hass = 2004;
|
||||
syncthing = 2007;
|
||||
ollama = 2008;
|
||||
git = 2009;
|
||||
immich = 2010;
|
||||
qbittorrent = 2011;
|
||||
};
|
||||
|
||||
users = config.users.users;
|
||||
leyla = users.leyla.name;
|
||||
eve = users.eve.name;
|
||||
in {
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
# principle users are by definition trusted
|
||||
nix.settings.trusted-users = builtins.map (user: user.name) principleUsers;
|
||||
|
||||
# we should only be able to ssh into principle users of a computer who are also set up for terminal access
|
||||
services.openssh.settings.AllowUsers = builtins.map (user: user.name) (lib.lists.intersectLists terminalUsers principleUsers);
|
||||
|
||||
# we need to set up env variables to nix can find keys to decrypt passwords on rebuild
|
||||
environment = {
|
||||
sessionVariables = {
|
||||
SOPS_AGE_KEY_DIRECTORY = SOPS_AGE_KEY_DIRECTORY;
|
||||
SOPS_AGE_KEY_FILE = "${SOPS_AGE_KEY_DIRECTORY}/key.txt";
|
||||
};
|
||||
};
|
||||
|
||||
# set up user passwords
|
||||
sops = {
|
||||
defaultSopsFormat = "yaml";
|
||||
gnupg.sshKeyPaths = [];
|
||||
|
||||
age = {
|
||||
keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sshKeyPaths = [];
|
||||
# generateKey = true;
|
||||
};
|
||||
|
||||
secrets = {
|
||||
"passwords/leyla" = {
|
||||
neededForUsers = true;
|
||||
sopsFile = "${inputs.secrets}/user-passwords.yaml";
|
||||
};
|
||||
"passwords/eve" = {
|
||||
neededForUsers = true;
|
||||
sopsFile = "${inputs.secrets}/user-passwords.yaml";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
users = {
|
||||
leyla = {
|
||||
uid = lib.mkForce uids.leyla;
|
||||
name = lib.mkForce host.users.leyla.name;
|
||||
description = "Leyla";
|
||||
extraGroups =
|
||||
(lib.lists.optionals host.users.leyla.isNormalUser ["networkmanager"])
|
||||
++ (lib.lists.optionals host.users.leyla.isPrincipleUser ["wheel" "dialout"])
|
||||
++ (lib.lists.optionals host.users.leyla.isDesktopUser ["adbusers"]);
|
||||
hashedPasswordFile = config.sops.secrets."passwords/leyla".path;
|
||||
isNormalUser = host.users.leyla.isNormalUser;
|
||||
isSystemUser = !host.users.leyla.isNormalUser;
|
||||
group = config.users.users.leyla.name;
|
||||
};
|
||||
|
||||
eve = {
|
||||
uid = lib.mkForce uids.eve;
|
||||
name = lib.mkForce host.users.eve.name;
|
||||
description = "Eve";
|
||||
extraGroups = lib.optionals host.users.eve.isNormalUser ["networkmanager"];
|
||||
hashedPasswordFile = config.sops.secrets."passwords/eve".path;
|
||||
isNormalUser = host.users.eve.isNormalUser;
|
||||
isSystemUser = !host.users.eve.isNormalUser;
|
||||
group = config.users.users.eve.name;
|
||||
};
|
||||
|
||||
jellyfin = {
|
||||
uid = lib.mkForce uids.jellyfin;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.jellyfin.name;
|
||||
};
|
||||
|
||||
forgejo = {
|
||||
uid = lib.mkForce uids.forgejo;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.forgejo.name;
|
||||
};
|
||||
|
||||
adguardhome = {
|
||||
uid = lib.mkForce uids.adguardhome;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.adguardhome.name;
|
||||
};
|
||||
|
||||
hass = {
|
||||
uid = lib.mkForce uids.hass;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.hass.name;
|
||||
};
|
||||
|
||||
syncthing = {
|
||||
uid = lib.mkForce uids.syncthing;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.syncthing.name;
|
||||
};
|
||||
|
||||
ollama = {
|
||||
uid = lib.mkForce uids.ollama;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.ollama.name;
|
||||
};
|
||||
|
||||
git = {
|
||||
uid = lib.mkForce uids.git;
|
||||
isSystemUser = !config.services.forgejo.enable;
|
||||
isNormalUser = config.services.forgejo.enable;
|
||||
group = config.users.users.git.name;
|
||||
};
|
||||
|
||||
immich = {
|
||||
uid = lib.mkForce uids.immich;
|
||||
isSystemUser = true;
|
||||
group = config.users.users.immich.name;
|
||||
};
|
||||
|
||||
qbittorrent = {
|
||||
uid = lib.mkForce uids.qbittorrent;
|
||||
isNormalUser = true;
|
||||
group = config.users.users.qbittorrent.name;
|
||||
};
|
||||
};
|
||||
|
||||
groups = {
|
||||
leyla = {
|
||||
gid = lib.mkForce gids.leyla;
|
||||
members = [
|
||||
leyla
|
||||
];
|
||||
};
|
||||
|
||||
eve = {
|
||||
gid = lib.mkForce gids.eve;
|
||||
members = [
|
||||
eve
|
||||
];
|
||||
};
|
||||
|
||||
users = {
|
||||
gid = lib.mkForce gids.users;
|
||||
members = [
|
||||
leyla
|
||||
eve
|
||||
];
|
||||
};
|
||||
|
||||
jellyfin_media = {
|
||||
gid = lib.mkForce gids.jellyfin_media;
|
||||
members = [
|
||||
users.jellyfin.name
|
||||
leyla
|
||||
eve
|
||||
];
|
||||
};
|
||||
|
||||
jellyfin = {
|
||||
gid = lib.mkForce gids.jellyfin;
|
||||
members = [
|
||||
users.jellyfin.name
|
||||
# leyla
|
||||
];
|
||||
};
|
||||
|
||||
forgejo = {
|
||||
gid = lib.mkForce gids.forgejo;
|
||||
members = [
|
||||
users.forgejo.name
|
||||
# leyla
|
||||
];
|
||||
};
|
||||
|
||||
adguardhome = {
|
||||
gid = lib.mkForce gids.adguardhome;
|
||||
members = [
|
||||
users.adguardhome.name
|
||||
# leyla
|
||||
];
|
||||
};
|
||||
|
||||
hass = {
|
||||
gid = lib.mkForce gids.hass;
|
||||
members = [
|
||||
users.hass.name
|
||||
# leyla
|
||||
];
|
||||
};
|
||||
|
||||
syncthing = {
|
||||
gid = lib.mkForce gids.syncthing;
|
||||
members = [
|
||||
users.syncthing.name
|
||||
leyla
|
||||
eve
|
||||
];
|
||||
};
|
||||
|
||||
ollama = {
|
||||
gid = lib.mkForce gids.ollama;
|
||||
members = [
|
||||
users.ollama.name
|
||||
];
|
||||
};
|
||||
|
||||
git = {
|
||||
gid = lib.mkForce gids.git;
|
||||
members = [
|
||||
users.git.name
|
||||
];
|
||||
};
|
||||
|
||||
immich = {
|
||||
gid = lib.mkForce gids.immich;
|
||||
members = [
|
||||
users.immich.name
|
||||
# leyla
|
||||
];
|
||||
};
|
||||
|
||||
qbittorrent = {
|
||||
gid = lib.mkForce gids.qbittorrent;
|
||||
members = [
|
||||
users.qbittorrent.name
|
||||
leyla
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
(lib.mkIf config.host.impermanence.enable {
|
||||
boot.initrd.postResumeCommands = lib.mkAfter (
|
||||
lib.strings.concatLines (builtins.map (user: "zfs rollback -r rpool/local/home/${user.name}@blank")
|
||||
normalUsers)
|
||||
);
|
||||
|
||||
systemd = {
|
||||
tmpfiles.rules =
|
||||
builtins.map (
|
||||
user: "d /persist/home/${user.name} 700 ${user.name} ${user.name} -"
|
||||
)
|
||||
normalUsers;
|
||||
};
|
||||
|
||||
fileSystems = lib.mkMerge [
|
||||
{
|
||||
${SOPS_AGE_KEY_DIRECTORY}.neededForBoot = true;
|
||||
}
|
||||
(
|
||||
builtins.listToAttrs (
|
||||
builtins.map (user:
|
||||
lib.attrsets.nameValuePair "/persist/home/${user.name}" {
|
||||
neededForBoot = true;
|
||||
})
|
||||
normalUsers
|
||||
)
|
||||
)
|
||||
(
|
||||
builtins.listToAttrs (
|
||||
builtins.map (user:
|
||||
lib.attrsets.nameValuePair "/home/${user.name}" {
|
||||
neededForBoot = true;
|
||||
})
|
||||
normalUsers
|
||||
)
|
||||
)
|
||||
];
|
||||
|
||||
host.storage.pool.extraDatasets = lib.mkMerge (
|
||||
[
|
||||
{
|
||||
# sops age key needs to be available to pre persist for user generation
|
||||
"local/system/sops" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = SOPS_AGE_KEY_DIRECTORY;
|
||||
options = {
|
||||
atime = "off";
|
||||
relatime = "off";
|
||||
canmount = "on";
|
||||
};
|
||||
};
|
||||
}
|
||||
]
|
||||
++ (
|
||||
builtins.map (user: {
|
||||
"local/home/${user.name}" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/home/${user.name}";
|
||||
options = {
|
||||
canmount = "on";
|
||||
};
|
||||
postCreateHook = ''
|
||||
zfs snapshot rpool/local/home/${user.name}@blank
|
||||
'';
|
||||
};
|
||||
"persist/home/${user.name}" = {
|
||||
type = "zfs_fs";
|
||||
mountpoint = "/persist/home/${user.name}";
|
||||
};
|
||||
})
|
||||
normalUsers
|
||||
)
|
||||
);
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
# this folder container modules that are for nixos and darwin
|
||||
{...}: {
|
||||
imports = [
|
||||
./home-manager
|
||||
./system.nix
|
||||
./nix-development.nix
|
||||
./users.nix
|
||||
];
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
# modules in this folder are to adapt home-manager modules configs to system-module configs
|
||||
{...}: {}
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
options.host.nix-development.enable = lib.mkEnableOption "should desktop configuration be enabled";
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
host.nix-development.enable = lib.mkDefault true;
|
||||
}
|
||||
(lib.mkIf config.host.nix-development.enable {
|
||||
nix = {
|
||||
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
||||
};
|
||||
environment.systemPackages = with pkgs; [
|
||||
# nix language server
|
||||
nil
|
||||
# nix formatter
|
||||
alejandra
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{...}: {
|
||||
nix = {
|
||||
settings = {
|
||||
experimental-features = ["nix-command" "flakes"];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
host = config.host;
|
||||
|
||||
hostUsers = host.hostUsers;
|
||||
principleUsers = host.principleUsers;
|
||||
in {
|
||||
options.host = {
|
||||
users = lib.mkOption {
|
||||
default = {};
|
||||
type = lib.types.attrsOf (lib.types.submodule ({
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
What should this users name on the system be
|
||||
'';
|
||||
defaultText = lib.literalExpression "config.host.users.\${name}.name";
|
||||
};
|
||||
isPrincipleUser = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
User should be configured as root and have ssh access
|
||||
'';
|
||||
defaultText = lib.literalExpression "config.host.users.\${name}.isPrincipleUser";
|
||||
};
|
||||
isDesktopUser = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
User should install their desktop applications
|
||||
'';
|
||||
defaultText = lib.literalExpression "config.host.users.\${name}.isDesktopUser";
|
||||
};
|
||||
isTerminalUser = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
User should install their terminal applications
|
||||
'';
|
||||
defaultText = lib.literalExpression "config.host.users.\${name}.isTerminalUser";
|
||||
};
|
||||
isNormalUser = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.isDesktopUser || config.isTerminalUser;
|
||||
description = ''
|
||||
User should install their applications and can log in
|
||||
'';
|
||||
defaultText = lib.literalExpression "config.host.users.\${name}.isNormalUser";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
hostUsers = lib.mkOption {
|
||||
default = lib.attrsets.mapAttrsToList (_: user: user) host.users;
|
||||
};
|
||||
principleUsers = lib.mkOption {
|
||||
default = lib.lists.filter (user: user.isPrincipleUser) hostUsers;
|
||||
};
|
||||
normalUsers = lib.mkOption {
|
||||
default = lib.lists.filter (user: user.isNormalUser) hostUsers;
|
||||
};
|
||||
desktopUsers = lib.mkOption {
|
||||
default = lib.lists.filter (user: user.isDesktopUser) hostUsers;
|
||||
};
|
||||
terminalUsers = lib.mkOption {
|
||||
default = lib.lists.filter (user: user.isTerminalUser) hostUsers;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
host.users = {
|
||||
leyla = {
|
||||
isPrincipleUser = lib.mkDefault false;
|
||||
isDesktopUser = lib.mkDefault false;
|
||||
isTerminalUser = lib.mkDefault false;
|
||||
};
|
||||
eve = {
|
||||
isPrincipleUser = lib.mkDefault false;
|
||||
isDesktopUser = lib.mkDefault false;
|
||||
isTerminalUser = lib.mkDefault false;
|
||||
};
|
||||
};
|
||||
|
||||
assertions =
|
||||
(
|
||||
builtins.map (user: {
|
||||
assertion = !(user.isPrincipleUser && !user.isNormalUser);
|
||||
message = ''
|
||||
Non normal user ${user.name} can not be a principle user.
|
||||
'';
|
||||
})
|
||||
hostUsers
|
||||
)
|
||||
++ [
|
||||
{
|
||||
assertion = (builtins.length principleUsers) > 0;
|
||||
message = ''
|
||||
At least one user must be a principle user.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 3d63dff77f8eda1667e3586169642cf256c4aa34
|
19
overlays/intellij.nix
Normal file
19
overlays/intellij.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
_:
|
||||
{
|
||||
# nixpkgs.overlays = [
|
||||
# (self: super: {
|
||||
# # idea is too out of date for android gradle things
|
||||
# jetbrains = {
|
||||
# jdk = super.jdk17;
|
||||
# idea-community = super.jetbrains.idea-community.overrideAttrs (oldAttrs: rec {
|
||||
# version = "2023.3.3";
|
||||
# name = "idea-community-${version}";
|
||||
# src = super.fetchurl {
|
||||
# sha256 = "sha256-3BI97Tx+3onnzT1NXkb62pa4dj9kjNDNvFt9biYgP9I=";
|
||||
# url = "https://download.jetbrains.com/idea/ideaIC-${version}.tar.gz";
|
||||
# };
|
||||
# });
|
||||
# };
|
||||
# })
|
||||
# ];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue