Compare commits

..

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

88 changed files with 1745 additions and 2722 deletions

View file

@ -13,7 +13,3 @@ creation_rules:
key_groups:
- age:
- *leyla
- path_regex: secrets/application-keys.yaml$
key_groups:
- age:
- *leyla

View file

@ -41,33 +41,30 @@ nix multi user, multi system, configuration with `sops` secret management, `home
## Research topics
- Look into this for auto rotating sops keys `https://technotim.live/posts/rotate-sops-encryption-keys/`
- Look into this for npins https://jade.fyi/blog/pinning-nixos-with-npins/
- 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/
- nix config mcp https://github.com/utensils/mcp-nixos
# 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
## New Features
- crab-hole
- figure out why syncthing and jellyfins permissions don't propagate downwards
- figure out steam vr things?
- auto turn off on power loss - nut
- zfs email after scrubbing # TODO: test this
- SMART test with email results
- fix nfs
- samba mounts
- 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)
- Create Tor guard/relay server
- migrate away from flakes and move to npins
- whisper
- figure out ai vs code plugin
- nix mcp
- samba mounts
- figure out steam vr things?
- Open GL?
- 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
- rotate sops encryption keys periodically (and somehow sync between devices?)
- wake on LAN for updates
- SMART test with email results
- Create Tor guard/relay server
- remote distributed builds - https://nix.dev/tutorials/nixos/distributed-builds-setup.html
- ISO target that contains authorized keys for nixos-anywhere https://github.com/diegofariasm/yggdrasil/blob/4acc43ebc7bcbf2e41376d14268e382007e94d78/hosts/bootstrap/default.nix
- migrate away from flakes and move to npins
- fix nfs
- fix home assistant
- create adguard server

View file

@ -1,10 +1,15 @@
{osConfig, ...}: let
{
pkgs,
lib,
config,
osConfig,
...
}: let
userConfig = osConfig.host.users.eve;
in {
imports = [
./packages.nix
./gnomeconf.nix
];
nixpkgs.config = {
allowUnfree = true;
};
home = {
username = userConfig.name;
@ -52,5 +57,37 @@ in {
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;
git = {
enable = true;
userName = "Eve Halfmann";
userEmail = "evesnrobins@gmail.com";
extraConfig.init.defaultBranch = "main";
};
openssh = {
hostKeys = [
{
type = "ed25519";
path = "${config.home.username}_${osConfig.networking.hostName}_ed25519";
}
];
};
};
}

View file

@ -1,12 +0,0 @@
{pkgs, ...}: {
config = {
dconf = {
enable = true;
settings = {
"org/gnome/shell".enabled-extensions = [
pkgs.gnomeExtensions.dash-to-panel.extensionUuid
];
};
};
};
}

View file

@ -1,67 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: let
userConfig = osConfig.host.users.eve;
hardware = osConfig.host.hardware;
in {
config = {
nixpkgs.config = {
allowUnfree = true;
};
# Packages that can be installed without any extra configuration
# See https://search.nixos.org/packages for all options
home.packages = lib.lists.optionals userConfig.isDesktopUser (
with pkgs; [
ungoogled-chromium
krita
gnomeExtensions.dash-to-panel
(lib.mkIf hardware.piperMouse.enable piper)
]
);
# Packages that need to be installed with some extra configuration
# See https://home-manager-options.extranix.com/ for all options
programs = lib.mkMerge [
{
# Let Home Manager install and manage itself.
home-manager.enable = true;
}
(lib.mkIf (config.user.isDesktopUser || config.user.isTerminalUser) {
git = {
enable = true;
userName = "Eve";
userEmail = "evesnrobins@gmail.com";
extraConfig.init.defaultBranch = "main";
};
openssh = {
enable = true;
hostKeys = [
{
type = "ed25519";
path = "${config.home.username}_${osConfig.networking.hostName}_ed25519";
}
];
};
})
(lib.mkIf config.user.isDesktopUser {
vscode = {
enable = true;
package = pkgs.vscodium;
};
firefox.enable = true;
bitwarden.enable = true;
discord.enable = true;
makemkv.enable = true;
signal-desktop-bin.enable = true;
steam.enable = true;
})
];
};
}

View file

@ -1,23 +1,26 @@
{pkgs, ...}: {
config = {
gnome = {
extraWindowControls = true;
colorScheme = "prefer-dark";
clockFormat = "24h";
extensions = [
pkgs.gnomeExtensions.dash-to-dock
];
hotkeys = {
"Open Terminal" = {
binding = "<Super>t";
command = "kgx";
};
};
};
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";
@ -26,6 +29,18 @@
"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 =

View file

@ -1,11 +1,11 @@
{
config,
osConfig,
config,
...
}: {
imports = [
./packages
./i18n.nix
./packages.nix
./impermanence.nix
./dconf.nix
];
@ -39,7 +39,7 @@
# org.gradle.console=verbose
# org.gradle.daemon.idletimeout=3600000
# '';
"${config.xdg.configHome}/user-dirs.dirs" = {
".config/user-dirs.dirs" = {
force = true;
text = ''
# This file is written by xdg-user-dirs-update
@ -82,5 +82,70 @@
# EDITOR = "emacs";
};
};
user = {
continue = {
enable = true;
docs = {
"Continue Docs" = {
startUrl = "https://docs.continue.dev";
};
"Nixpkgs" = {
startUrl = "https://ryantm.github.io/nixpkgs/#preface";
};
"Nix Manual" = {
startUrl = "https://nixos.org/manual/nixos/stable/";
};
"Home manager Manual" = {
startUrl = "https://nix-community.github.io/home-manager/";
};
"Nix Docs" = {
startUrl = "https://nix.dev/index.html";
};
"Linux Man Page" = {
startUrl = "https://linux.die.net/man/";
};
};
};
};
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";
}
];
};
};
};
}

View file

@ -0,0 +1,342 @@
{
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;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
# Usage Experience
"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 = [""];
# }
];
};
};
};
}

View file

@ -1,6 +1,5 @@
{
lib,
config,
osConfig,
...
}: {
@ -10,10 +9,14 @@
"desktop"
"downloads"
"documents"
{
directory = ".local/share/Steam";
method = "symlink";
}
];
files = [
".bash_history" # keep shell history around
"${config.xdg.dataHome}/recently-used.xbel" # gnome recently viewed files
".local/share/recently-used.xbel" # gnome recently viewed files
];
allowOther = true;
};

View file

@ -0,0 +1,95 @@
{
lib,
osConfig,
pkgs,
...
}: let
userConfig = osConfig.host.users.leyla;
hardware = osConfig.host.hardware;
in {
imports = [
./vscode/default.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)
])
)
)
);
};
}

View file

@ -1,118 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: let
hardware = osConfig.host.hardware;
in {
imports = [
./vscode
./firefox.nix
./direnv.nix
./openssh.nix
./git.nix
./makemkv.nix
];
config = lib.mkMerge [
{
programs = lib.mkMerge [
{
# Let Home Manager install and manage itself.
home-manager.enable = true;
}
(lib.mkIf (config.user.isTerminalUser || config.user.isDesktopUser) {
bash.enable = true;
git.enable = true;
openssh.enable = true;
})
(lib.mkIf config.user.isDesktopUser {
bitwarden.enable = true;
obs-studio.enable = hardware.graphicsAcceleration.enable;
qbittorrent.enable = true;
prostudiomasters.enable = true;
protonvpn-gui.enable = true;
dbeaver-bin.enable = true;
bruno.enable = true;
})
(lib.mkIf (hardware.directAccess.enable && config.user.isDesktopUser) {
anki.enable = true;
makemkv.enable = true;
discord.enable = true;
signal-desktop-bin.enable = true;
calibre.enable = true;
obsidian.enable = true;
jetbrains.idea-community.enable = true;
vscode.enable = true;
firefox.enable = true;
steam.enable = true;
})
];
}
(lib.mkIf config.user.isTerminalUser {
home.packages = with pkgs; [
# command line tools
sox
yt-dlp
ffmpeg
imagemagick
];
})
(lib.mkIf config.user.isDesktopUser {
nixpkgs.config = {
allowUnfree = true;
};
home.packages = (
(with pkgs; [
aileron
proxmark3
])
++ (
lib.lists.optionals hardware.directAccess.enable (with pkgs; [
#foss platforms
ungoogled-chromium
libreoffice
inkscape
gimp
krita
freecad
# cura
# kicad-small
onionshare
# rhythmbox
# wireshark
# rpi-imager
# fritzing
mfoc
tor-browser
pdfarranger
picard
gdx-liftoff
# proprietary platforms
(lib.mkIf hardware.graphicsAcceleration.enable davinci-resolve)
# development tools
# androidStudioPackages.canary
qFlipper
# system tools
openvpn
noisetorch
# hardware management tools
(lib.mkIf hardware.piperMouse.enable piper)
(lib.mkIf hardware.openRGB.enable openrgb)
(lib.mkIf hardware.viaKeyboard.enable via)
])
)
);
})
];
}

View file

@ -1,22 +0,0 @@
{
lib,
config,
osConfig,
...
}: let
userConfig = osConfig.host.users.leyla;
in {
config = lib.mkIf userConfig.isDesktopUser {
programs = {
direnv = {
enable = true;
enableBashIntegration = true;
nix-direnv.enable = true;
config = {
global.hide_env_diff = true;
whitelist.exact = ["${config.home.homeDirectory}/documents/code/nix-config"];
};
};
};
};
}

View file

@ -1,343 +0,0 @@
{
lib,
pkgs,
inputs,
...
}: {
config = {
programs.firefox = {
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;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
# Usage Experience
"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 = [""];
# }
];
};
};
};
};
}

View file

@ -1,11 +0,0 @@
{...}: {
config = {
programs = {
git = {
userName = "Leyla Becker";
userEmail = "git@jan-leila.com";
extraConfig.init.defaultBranch = "main";
};
};
};
}

View file

@ -1,17 +0,0 @@
{
config,
inputs,
...
}: {
config = {
sops.secrets = {
"application-keys/makemkv" = {
sopsFile = "${inputs.secrets}/application-keys.yaml";
};
};
programs.makemkv = {
appKeyFile = config.sops.placeholder."application-keys/makemkv";
destinationDir = "/home/leyla/downloads/makemkv";
};
};
}

View file

@ -1,23 +0,0 @@
{
config,
osConfig,
...
}: {
config = {
programs = {
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";
}
];
};
};
};
}

View file

@ -1,122 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: let
nix-development-enabled = osConfig.host.nix-development.enable;
ai-tooling-enabled = osConfig.host.ai.enable;
in {
imports = [
./user-words.nix
];
config = lib.mkIf config.user.isDesktopUser {
programs = {
bash.shellAliases = {
code = "codium";
};
vscode = {
package = pkgs.vscodium;
mutableExtensionsDir = false;
profiles.default = {
enableUpdateCheck = false;
enableExtensionUpdateCheck = false;
userSettings = lib.mkMerge [
{
"workbench.colorTheme" = "Atom One Dark";
"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";
})
(lib.mkIf ai-tooling-enabled {
"aiCode.ollamaHost" = "http://defiant:11434";
})
];
extensions = let
extension-pkgs = pkgs.nix-vscode-extensions.forVSCodeVersion config.programs.vscode.package.version;
in (
(
with extension-pkgs.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
orta.vscode-jest
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 nix-development-enabled [
# nix extensions
pinage404.nix-extension-pack
jnoortheen.nix-ide
kamadorueda.alejandra
])
)
)
++ (
with extension-pkgs.vscode-marketplace; (
[
# js extensions
karyfoundation.nearley
]
++ (lib.lists.optionals ai-tooling-enabled [
])
)
)
++ (
with pkgs.codium-extensions; (
[]
++ (
lib.lists.optionals ai-tooling-enabled [
ai-code
]
)
)
)
);
};
};
};
};
}

View file

@ -1,69 +0,0 @@
{...}: {
config.programs.vscode.profiles.default.userSettings = {
"cSpell.userWords" = [
"leyla"
"ollama"
"webdav"
"pname"
"direnv"
"deepseek"
"qwen"
"syncthing"
"immich"
"sonos"
"makemkv"
"hass"
"qbittorent"
"prostudiomasters"
"tmpfiles"
"networkmanager"
"Networkd"
"networkmanager"
"dialout"
"adbusers"
"protonmail"
"authkey"
"netdevs"
"atomix"
"geary"
"gedit"
"hitori"
"iagno"
"alsa"
"timezoned"
"pipewire"
"pulseaudio"
"rtkit"
"disko"
"ashift"
"autotrim"
"canmount"
"mountpoint"
"xattr"
"acltype"
"relatime"
"keyformat"
"keylocation"
"vdevs"
# codium extensions
"akamud"
"onedark"
"jeanp"
"dsznajder"
"dbaeumer"
"orta"
"tauri"
"unifiedjs"
"tamasfe"
"pinage"
"jnoortheen"
"kamadorueda"
"karyfoundation"
"nearley"
# nix.optimise is spelled wrong
"optimise"
];
};
}

View file

@ -0,0 +1,118 @@
{
lib,
pkgs,
inputs,
config,
osConfig,
...
}: let
nix-development-enabled = osConfig.host.nix-development.enable;
ai-tooling-enabled = config.user.continue.enable && osConfig.host.ai.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" = import ./user-words.nix;
"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 ai-tooling-enabled {
"continue.telemetryEnabled" = false;
})
];
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 nix-development-enabled [
# nix extensions
pinage404.nix-extension-pack
jnoortheen.nix-ide
kamadorueda.alejandra
])
++ (
with vscode-marketplace;
[
# js extensions
karyfoundation.nearley
]
++ (lib.lists.optionals ai-tooling-enabled [
continue.continue
])
)
);
};
};
};
}

View file

@ -0,0 +1,6 @@
[
"leyla"
"webdav"
"ollama"
"optimise"
]

View file

@ -17,12 +17,6 @@
"services/zfs_smtp_token" = {
sopsFile = "${inputs.secrets}/defiant-services.yaml";
};
"services/paperless_password" = {
sopsFile = "${inputs.secrets}/defiant-services.yaml";
mode = "0700";
owner = "paperless";
group = "paperless";
};
};
host = {
@ -46,8 +40,6 @@
tokenFile = config.sops.secrets."services/zfs_smtp_token".path;
};
pool = {
# We are having to boot off of the nvm cache drive because I cant figure out how to boot via the HBA
bootDrives = ["nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"];
vdevs = [
[
"ata-ST18000NE000-3G6101_ZVTCXVEB"
@ -115,6 +107,13 @@
};
};
};
# home-assistant = {
# enable = false;
# subdomain = "home";
# };
adguardhome = {
enable = false;
};
};
systemd.network = {
@ -191,9 +190,6 @@
};
};
# limit arc usage to 50gb because ollama doesn't play nice with zfs using up all of the memory
boot.kernelParams = ["zfs.zfs_arc_max=53687091200"];
services = {
# TODO: move zfs scrubbing into module
zfs = {
@ -201,24 +197,24 @@
autoSnapshot.enable = true;
};
# temp enable desktop environment for setup
# temp enable desktop enviroment for setup
# Enable the X11 windowing system.
xserver.enable = true;
xserver = {
enable = true;
# Enable the GNOME Desktop Environment.
displayManager = {
gdm.enable = true;
};
desktopManager = {
gnome.enable = true;
# Enable the GNOME Desktop Environment.
displayManager = {
gdm.enable = true;
};
desktopManager = {
gnome.enable = true;
};
};
ollama = {
enable = true;
exposePort = true;
acceleration = false;
loadModels = [
# conversation models
"llama3.1:8b"
@ -281,23 +277,10 @@
subdomain = "search";
};
home-assistant = {
enable = true;
subdomain = "home";
openFirewall = true;
database = "postgres";
extensions = {
sonos.enable = true;
jellyfin.enable = true;
wyoming.enable = true;
};
};
paperless = {
enable = true;
subdomain = "documents";
passwordFile = config.sops.secrets."services/paperless_password".path;
virt-home-assistant = {
enable = false;
networkBridge = "bond0";
hostDevice = "0x10c4:0xea60";
};
qbittorrent = {
@ -315,7 +298,7 @@
hibernate.enable = false;
hybrid-sleep.enable = false;
};
services.displayManager.gdm.autoSuspend = 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

View file

@ -2,12 +2,12 @@
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{
config,
lib,
pkgs,
...
}: {
imports = [
./nvidia-drivers.nix
];
# Use the systemd-boot EFI boot loader.
@ -36,15 +36,10 @@
# Enable the X11 windowing system.
services.xserver.enable = true;
# Enable wacom touchscreen device
services.xserver.wacom.enable = true;
# installed opentabletdriver
hardware.opentabletdriver.enable = true;
# Enable the GNOME Desktop Environment.
services.displayManager.gdm.enable = true;
services.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
host = {
users = {
@ -54,17 +49,6 @@
isPrincipleUser = true;
};
};
hardware = {
piperMouse.enable = true;
};
storage = {
enable = true;
pool = {
mode = "";
drives = ["wwn-0x5000039fd0cf05eb"];
};
};
};
# Configure keymap in X11
@ -96,17 +80,12 @@
# programs.firefox.enable = true;
nixpkgs.config.allowUnfree = true;
# Packages that can be installed without any extra configuration
# See https://search.nixos.org/packages for all options
environment.systemPackages = with pkgs; [
wget
];
# Packages that need to be installed with some extra configuration
# See https://search.nixos.org/options for all options
programs = {};
# List packages installed in system profile.
# You can use https://search.nixos.org/ to find more packages (and options).
# environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
# wget
# ];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.

View file

@ -3,5 +3,6 @@
imports = [
./configuration.nix
./hardware-configuration.nix
./disco-configuration.nix
];
}

View file

@ -0,0 +1,57 @@
{...}: {
disko.devices = {
disk = {
disk1 = {
type = "disk";
device = "/dev/disk/by-id/wwn-0x5000039fd0cf05eb";
content = {
type = "gpt";
partitions = {
ESP = {
size = "64M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = ["umask=0077"];
};
};
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
zpool = {
zroot = {
type = "zpool";
mode = "";
options.cachefile = "none";
rootFsOptions = {
compression = "zstd";
"com.sun:auto-snapshot" = "true";
};
mountpoint = "/";
postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank";
datasets = {
"system/nix" = {
type = "zfs_fs";
mountpoint = "/nix";
options = {
atime = "off";
relatime = "off";
canmount = "on";
};
};
};
};
};
};
}

View file

@ -1,51 +0,0 @@
{
config,
lib,
pkgs,
...
}: {
# Enable OpenGL
hardware.graphics = {
enable = true;
};
# Load nvidia driver for Xorg and Wayland
services = {
xserver = {
# Load nvidia driver for Xorg and Wayland
videoDrivers = ["nvidia"];
};
# Use X instead of wayland
displayManager.gdm.wayland = false;
};
hardware.nvidia = {
# Modesetting is required.
modesetting.enable = true;
# 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
# of just the bare essentials.
powerManagement.enable = false;
# Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
powerManagement.finegrained = false;
# 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
# Only available from driver 515.43.04+
open = true;
# Enable the Nvidia settings menu,
# 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.stable;
};
}

View file

@ -1,8 +1,7 @@
{
lib,
pkgs,
config,
inputs,
pkgs,
...
}: {
imports = [
@ -11,19 +10,6 @@
nixpkgs.config.allowUnfree = true;
boot = {
initrd = {
availableKernelModules = ["usb_storage" "sd_mod"];
};
kernelModules = ["sg"];
# Bootloader.
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
};
host = {
users = {
leyla = {
@ -42,66 +28,38 @@
enable = true;
models = {
"Llama 3.1 8B" = {
model = "llama3.1:8b";
model = "lamma3.1:8b";
roles = ["chat" "edit" "apply"];
apiBase = "http://defiant:11434";
};
"Deepseek Coder:6.7B" = {
model = "deepseek-coder:6.7b";
roles = ["chat" "edit" "apply"];
apiBase = "http://defiant:11434";
};
"Deepseek Coder:33B" = {
model = "deepseek-coder:33b";
roles = ["chat" "edit" "apply"];
apiBase = "http://defiant:11434";
};
"Deepseek r1:8B" = {
model = "deepseek-r1:8b";
roles = ["chat"];
apiBase = "http://defiant:11434";
};
"Deepseek r1:32B" = {
model = "deepseek-r1:32b";
roles = ["chat"];
apiBase = "http://defiant:11434";
apiBase = "http://twilight:11434";
};
"qwen2.5-coder:1.5b-base" = {
model = "qwen2.5-coder:1.5b-base";
roles = ["autocomplete"];
apiBase = "http://defiant:11434";
apiBase = "http://twilight:11434";
};
"nomic-embed-text:latest" = {
model = "nomic-embed-text:latest";
roles = ["embed"];
apiBase = "http://defiant:11434";
apiBase = "http://twilight:11434";
};
};
};
};
environment.systemPackages = with pkgs; [
cachefilesd
webtoon-dl
prostudiomasters
];
services.cachefilesd.enable = true;
programs = {
adb.enable = true;
};
networking = {
networkmanager.enable = true;
hostName = "horizon"; # Define your hostname.
};
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware = {
graphics.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 = {
@ -115,10 +73,6 @@
fprintd = {
enable = true;
};
# firmware update tool
fwupd = {
enable = true;
};
tailscale = {
enable = true;
authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/horizon".path;
@ -126,13 +80,6 @@
};
syncthing.enable = true;
ollama = {
enable = true;
loadModels = [
"llama3.1:8b"
];
};
};
# Enable touchpad support (enabled default in most desktopManager).

View file

@ -4,6 +4,7 @@
{
config,
lib,
pkgs,
modulesPath,
...
}: {
@ -11,10 +12,22 @@
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "nvme"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
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 = {
"/" = {
@ -26,20 +39,98 @@
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";}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.tailscale0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp170s0.useDHCP = lib.mkDefault true;
networking = {
networkmanager.enable = true;
useDHCP = lib.mkDefault true;
hostName = "horizon"; # Define your hostname.
};
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware = {
graphics.enable = true;
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
};
}

View file

@ -1,7 +1,6 @@
{
inputs,
config,
pkgs,
...
}: {
imports = [
@ -10,14 +9,6 @@
nixpkgs.config.allowUnfree = true;
boot.initrd.availableKernelModules = ["usb_storage"];
boot.kernelModules = ["sg"];
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
sops.secrets = {
"vpn-keys/tailscale-authkey/twilight" = {
sopsFile = "${inputs.secrets}/vpn-keys.yaml";
@ -130,70 +121,13 @@
syncthing.enable = true;
};
boot.supportedFilesystems = ["nfs"];
fileSystems = {
"/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"
];
};
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
};
environment.systemPackages = with pkgs; [
cachefilesd
];
hardware.steam-hardware.enable = true; # Provides udev rules for controller, HTC vive, and Valve Index
networking = {
networkmanager.enable = true;
hostName = "twilight"; # Define your hostname.
};
# enabled virtualisation for docker
# virtualisation.docker.enable = true;

View file

@ -3,6 +3,5 @@
imports = [
./configuration.nix
./hardware-configuration.nix
./nvidia-drivers.nix
];
}

View file

@ -4,6 +4,7 @@
{
config,
lib,
pkgs,
modulesPath,
...
}: {
@ -11,10 +12,30 @@
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "sd_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-amd"];
boot.extraModulePackages = [];
boot = {
initrd = {
availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
kernelModules = [];
};
kernelModules = ["kvm-amd" "sg"];
extraModulePackages = [];
# Bootloader.
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
supportedFilesystems = ["nfs"];
};
services.xserver = {
# Load nvidia driver for Xorg and Wayland
videoDrivers = ["nvidia"];
# Use X instead of wayland for gaming reasons
displayManager.gdm.wayland = false;
};
fileSystems = {
"/" = {
@ -27,16 +48,111 @@
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 = [];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
networking = {
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.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware = {
# Enable OpenGL
graphics.enable = true;
# install graphics drivers
nvidia = {
# Modesetting is required.
modesetting.enable = true;
# 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
# of just the bare essentials.
powerManagement.enable = false;
# Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
powerManagement.finegrained = false;
# 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
# 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`.
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;
};
}

View file

@ -1,47 +0,0 @@
{config, ...}: {
services = {
xserver = {
# Load nvidia driver for Xorg and Wayland
videoDrivers = ["nvidia"];
};
# Use X instead of wayland for gaming reasons
displayManager.gdm.wayland = false;
};
hardware = {
# Enable OpenGL
graphics.enable = true;
# install graphics drivers
nvidia = {
# Modesetting is required.
modesetting.enable = true;
# 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
# of just the bare essentials.
powerManagement.enable = false;
# Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
powerManagement.finegrained = false;
# 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
# Only available from driver 515.43.04+
# Currently alpha-quality/buggy, so false is currently the recommended setting.
open = true;
# Enable the Nvidia settings menu,
# 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;
};
};
}

165
flake.lock generated
View file

@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1752113600,
"narHash": "sha256-7LYDxKxZgBQ8LZUuolAQ8UkIB+jb4A2UmiR+kzY9CLI=",
"lastModified": 1748225455,
"narHash": "sha256-AzlJCKaM4wbEyEpV3I/PUq5mHnib2ryEy32c+qfj6xk=",
"owner": "nix-community",
"repo": "disko",
"rev": "79264292b7e3482e5702932949de9cbb69fedf6d",
"rev": "a894f2811e1ee8d10c50560551e50d6ab3c392ba",
"type": "github"
},
"original": {
@ -28,11 +28,11 @@
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1752379414,
"narHash": "sha256-0R3slhrjrnzyxR/fAYy5UliZvSgaVS38YCESBdH5RJw=",
"lastModified": 1748405006,
"narHash": "sha256-pmt0SFjACJJAI8g8QU5arg2c9BXNZG9/okVwRSDJkG8=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "51e77bb95540b7dd6c60f8fd65a0c472a2c9c3b7",
"rev": "f9801a86d6603260940890c36650275090d1dceb",
"type": "gitlab"
},
"original": {
@ -75,39 +75,6 @@
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flakey-profile": {
"locked": {
"lastModified": 1712898590,
"narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
"owner": "lf-",
"repo": "flakey-profile",
"rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
"type": "github"
},
"original": {
"owner": "lf-",
"repo": "flakey-profile",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -115,11 +82,11 @@
]
},
"locked": {
"lastModified": 1752467539,
"narHash": "sha256-4kaR+xmng9YPASckfvIgl5flF/1nAZOplM+Wp9I5SMI=",
"lastModified": 1748455938,
"narHash": "sha256-mQ/iNzPra2WtDQ+x2r5IadcWNr0m3uHvLMzJkXKAG/8=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "1e54837569e0b80797c47be4720fab19e0db1616",
"rev": "02077149e2921014511dac2729ae6dadb4ec50e2",
"type": "github"
},
"original": {
@ -143,41 +110,6 @@
"type": "github"
}
},
"lix": {
"flake": false,
"locked": {
"lastModified": 1746827285,
"narHash": "sha256-hsFe4Tsqqg4l+FfQWphDtjC79WzNCZbEFhHI8j2KJzw=",
"rev": "47aad376c87e2e65967f17099277428e4b3f8e5a",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/47aad376c87e2e65967f17099277428e4b3f8e5a.tar.gz?rev=47aad376c87e2e65967f17099277428e4b3f8e5a"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/lix/archive/2.93.0.tar.gz"
}
},
"lix-module": {
"inputs": {
"flake-utils": "flake-utils",
"flakey-profile": "flakey-profile",
"lix": "lix",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1746838955,
"narHash": "sha256-11R4K3iAx4tLXjUs+hQ5K90JwDABD/XHhsM9nkeS5N8=",
"rev": "cd2a9c028df820a83ca2807dc6c6e7abc3dfa7fc",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/cd2a9c028df820a83ca2807dc6c6e7abc3dfa7fc.tar.gz?rev=cd2a9c028df820a83ca2807dc6c6e7abc3dfa7fc"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.93.0.tar.gz"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
@ -185,11 +117,11 @@
]
},
"locked": {
"lastModified": 1751313918,
"narHash": "sha256-HsJM3XLa43WpG+665aGEh8iS8AfEwOIQWk3Mke3e7nk=",
"lastModified": 1748352827,
"narHash": "sha256-sNUUP6qxGkK9hXgJ+p362dtWLgnIWwOCmiq72LAWtYo=",
"owner": "LnL7",
"repo": "nix-darwin",
"rev": "e04a388232d9a6ba56967ce5b53a8a6f713cdfcf",
"rev": "44a7d0e687a87b73facfe94fba78d323a6686a90",
"type": "github"
},
"original": {
@ -221,17 +153,17 @@
},
"nix-vscode-extensions": {
"inputs": {
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1752459325,
"narHash": "sha256-46TgjdxT02a4nFd9HCXCf8kK5ZSH7r9gYROLtc8zVOg=",
"lastModified": 1748397853,
"narHash": "sha256-tudGoP5caIJ5TzkV6wnsmUk7Spx21oWMKpkmPbjRNZc=",
"owner": "nix-community",
"repo": "nix-vscode-extensions",
"rev": "61c2e99ebd586f463a6c0ebe3d931e74883b163d",
"rev": "ac4fc8eb9a1ee5eeb3c0a30f57652e4c5428d3a5",
"type": "github"
},
"original": {
@ -242,11 +174,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1752048960,
"narHash": "sha256-gATnkOe37eeVwKKYCsL+OnS2gU4MmLuZFzzWCtaKLI8=",
"lastModified": 1747900541,
"narHash": "sha256-dn64Pg9xLETjblwZs9Euu/SsjW80pd6lr5qSiyLY1pg=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "7ced9122cff2163c6a0212b8d1ec8c33a1660806",
"rev": "11f2d9ea49c3e964315215d6baa73a8d42672f06",
"type": "github"
},
"original": {
@ -258,11 +190,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1751984180,
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
"lastModified": 1748370509,
"narHash": "sha256-QlL8slIgc16W5UaI3w7xHQEP+Qmv/6vSNTpoZrrSlbk=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
"rev": "4faa5f5321320e49a78ae7848582f684d64783e9",
"type": "github"
},
"original": {
@ -279,25 +211,23 @@
"flake-compat": "flake-compat",
"home-manager": "home-manager",
"impermanence": "impermanence",
"lix-module": "lix-module",
"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",
"steam-fetcher": "steam-fetcher"
"sops-nix": "sops-nix"
}
},
"secrets": {
"flake": false,
"locked": {
"lastModified": 1752531440,
"narHash": "sha256-04tQ3EUrtmZ7g6fVUkZC4AbAG+Z7lng79qU3jsiqWJY=",
"lastModified": 1743538790,
"narHash": "sha256-QXmvyxfAhpifxAWcYTvuGfzv9I+9gHw0bq4WYtGEB9A=",
"ref": "refs/heads/main",
"rev": "f016767c13aa36dde91503f7a9f01bdd02468045",
"revCount": 20,
"rev": "3d63dff77f8eda1667e3586169642cf256c4aa34",
"revCount": 17,
"type": "git",
"url": "ssh://git@git.jan-leila.com/jan-leila/nix-config-secrets.git"
},
@ -313,11 +243,11 @@
]
},
"locked": {
"lastModified": 1751606940,
"narHash": "sha256-KrDPXobG7DFKTOteqdSVeL1bMVitDcy7otpVZWDE6MA=",
"lastModified": 1747603214,
"narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "3633fc4acf03f43b260244d94c71e9e14a2f6e0d",
"rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd",
"type": "github"
},
"original": {
@ -326,26 +256,6 @@
"type": "github"
}
},
"steam-fetcher": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1714795926,
"narHash": "sha256-PkgC9jqoN6cJ8XYzTA2PlrWs7aPJkM3BGiTxNqax0cA=",
"owner": "nix-community",
"repo": "steam-fetcher",
"rev": "12f66eafb7862d91b3e30c14035f96a21941bd9c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "steam-fetcher",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
@ -360,21 +270,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View file

@ -5,10 +5,10 @@
# base packages
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.93.0.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
# lix-module = {
# url = "https://git.lix.systems/lix-project/nixos-module/archive/stable.tar.gz";
# inputs.nixpkgs.follows = "nixpkgs";
# };
# secret encryption
sops-nix = {
@ -71,11 +71,6 @@
flake-compat = {
url = "github:edolstra/flake-compat";
};
steam-fetcher = {
url = "github:nix-community/steam-fetcher";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
@ -136,11 +131,11 @@
systemsHomes
// homeSystems;
in {
formatter = forEachPkgs (system: pkgs: pkgs.alejandra);
formatter = forEachPkgs (pkgs: pkgs.alejandra);
# templates = import ./templates;
devShells = forEachPkgs (system: pkgs: {
devShells = forEachPkgs (pkgs: {
default = pkgs.mkShell {
packages = with pkgs; [
# for version controlling this repo
@ -155,8 +150,6 @@
nixos-anywhere
# for updating disko configurations
disko
# for viewing dconf entries
dconf-editor
];
SOPS_AGE_KEY_DIRECTORY = import ./const/sops_age_key_directory.nix;

View file

@ -1,7 +1,3 @@
# this folder is for derivation overlays
{inputs, ...}: {
nixpkgs.overlays = [
inputs.steam-fetcher.overlays.default
inputs.nix-vscode-extensions.overlays.default
];
{...}: {
}

View file

@ -1,42 +0,0 @@
{
buildNpmPackage,
vscode-utils,
pkgs,
...
}: let
version = "0.0.1";
pname = "ai-code";
publisher = "jan-leila";
vsix = buildNpmPackage {
inherit version pname;
src = builtins.fetchGit {
url = "ssh://git@git.jan-leila.com/jan-leila/ai-code.git";
rev = "bdb615876df41717180c31640a8542b86326a9b3";
};
npmDepsHash = "sha256-kjMyEnT3dz0yH5Ydh+aGoFDocKpBYGRmfnwbEdvvgpY=";
nativeBuildInputs = with pkgs; [
vsce
];
buildPhase = ''
${pkgs.vsce}/bin/vsce package -o ${pname}.zip
'';
installPhase = ''
mkdir -p $out
mv ${pname}.zip $out/${pname}.zip
'';
};
in
vscode-utils.buildVscodeExtension {
inherit pname version;
src = "${vsix}/${pname}.zip";
vscodeExtUniqueId = "${publisher}.${pname}";
vscodeExtPublisher = publisher;
vscodeExtName = pname;
}

View file

@ -1,3 +0,0 @@
{pkgs, ...}: {
ai-code = pkgs.callPackage ./ai-code.nix {};
}

View file

@ -1,26 +1,4 @@
{pkgs, ...}: {
nixpkgs.overlays = [
(final: prev: {
webtoon-dl =
pkgs.callPackage
./webtoon-dl.nix
{};
})
# TODO: this package always needs to be called with the --in-process-gpu flag for some reason, can we automate that?
(final: prev: {
prostudiomasters =
pkgs.callPackage
./prostudiomasters.nix
{};
})
(final: prev: {
noita_entangled_worlds = pkgs.callPackage ./noita-entangled-worlds.nix {};
})
(final: prev: {
gdx-liftoff = pkgs.callPackage ./gdx-liftoff.nix {};
})
(final: prev: {
codium-extensions = pkgs.callPackage ./codium-extensions {};
})
];
# this folder is for custom derivations
{...}: {
# package = pkgs.callPackage ./package.nix {};
}

View file

@ -1,44 +0,0 @@
{
stdenv,
fetchurl,
makeWrapper,
jdk,
lib,
xorg,
libGL,
...
}:
stdenv.mkDerivation rec {
pname = "gdx-liftoff";
version = "1.13.5.1";
src = fetchurl {
url = "https://github.com/libgdx/gdx-liftoff/releases/download/v${version}/gdx-liftoff-${version}.jar";
hash = "sha256-9vCXGNGwI/P4VmcdIzTv2GPAX8bZb7nkfopaRAf6yMA=";
};
dontUnpack = true;
nativeBuildInputs = [makeWrapper];
runtimeDependencies = lib.makeLibraryPath [
# glfw
libGL
xorg.libX11
xorg.libXcursor
xorg.libXext
xorg.libXrandr
xorg.libXxf86vm
];
installPhase = ''
runHook preInstall
install -Dm644 $src $out/lib/gdx-liftoff-${version}.jar
makeWrapper ${lib.getExe jdk} $out/bin/gdx-liftoff-${version} \
--append-flags "-jar $out/lib/gdx-liftoff-${version}.jar"\
${lib.optionalString stdenv.hostPlatform.isLinux "--prefix LD_LIBRARY_PATH : ${runtimeDependencies}"}
runHook postInstall
'';
}

View file

@ -1,46 +0,0 @@
# not working yet
{
pkgs,
rustPlatform,
fetchFromGitHub,
...
}: let
version = "1.5.3";
repo = fetchFromGitHub {
owner = "IntQuant";
repo = "noita_entangled_worlds";
rev = "v${version}";
hash = "sha256-frrpD0aWTeDbZYtp15R+quUUAZf7OvHlbSLtGJJtAqk=";
};
in
rustPlatform.buildRustPackage {
name = "noita-proxy-${version}";
src = repo + "/noita-proxy";
prePatch = ''
substituteInPlace Cargo.toml \
--replace "path = \"../shared\"" "path = \"${repo + "/shared"}\""
'';
nativeBuildInputs = with pkgs; [
pkg-config
python3
cmake
];
buildInputs = with pkgs; [
openssl
openssl.dev
libpulseaudio
libjack2
alsa-lib
xorg.libxcb
xorg.libxcb.dev
libopus
];
propagatedBuildInputs = with pkgs; [
steamworks-sdk-redist
];
runtimeDependencies = with pkgs; [
steamworks-sdk-redist
];
doCheck = false;
cargoHash = "sha256-TzUS6d6PopgGf2i1yVaXaXdzNrvfSz+Gv67BAtxYmb4=";
}

View file

@ -0,0 +1,75 @@
{
lib,
pkgs,
config,
osConfig,
...
}: let
ai-tooling-enabled = config.user.continue.enable && osConfig.host.ai.enable;
in {
options = {
user.continue = {
enable = lib.mkEnableOption "should continue be enabled on this machine";
docs = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
options = {
name = lib.mkOption {
type = lib.types.str;
default = name;
};
startUrl = lib.mkOption {
type = lib.types.str;
};
};
}));
};
context = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
options = {
provider = lib.mkOption {
type = lib.types.str;
default = name;
};
};
}));
default = {
"code" = {};
"docs" = {};
"diff" = {};
"terminal" = {};
"problems" = {};
"folder" = {};
"codebase" = {};
};
};
};
};
config =
lib.mkIf ai-tooling-enabled
(lib.mkMerge [
{
home = {
file = {
".continue/config.yaml".source = (pkgs.formats.yaml {}).generate "continue-config" {
name = "Assistant";
version = "1.0.0";
schema = "v1";
models = lib.attrsets.attrValues osConfig.host.ai.models;
context = lib.attrsets.attrValues config.user.continue.context;
docs = lib.attrsets.attrValues config.user.continue.docs;
};
};
};
}
(lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
".continue/index"
".continue/sessions"
];
allowOther = true;
};
})
]);
}

View file

@ -1,12 +1,9 @@
# this folder container modules that are for home manager only
{...}: {
imports = [
./sops.nix
./user.nix
./flipperzero.nix
./i18n.nix
./openssh.nix
./gnome.nix
./programs
./continue.nix
];
}

View file

@ -1,106 +0,0 @@
{
lib,
config,
...
}: {
options.gnome = {
extraWindowControls = lib.mkEnableOption "Should we add back in the minimize and maximize window controls?";
clockFormat = lib.mkOption {
type = lib.types.enum [
"12h"
"24h"
];
default = "24h";
};
colorScheme = lib.mkOption {
type = lib.types.enum [
"default"
"prefer-dark"
"prefer-light"
];
default = "default";
};
accentColor = lib.mkOption {
type = lib.types.enum [
"blue"
"teal"
"green"
"yellow"
"orange"
"red"
"pink"
"purple"
"slate"
];
default = "blue";
};
extensions = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
description = "The set of extensions to install and enable in the user environment.";
};
hotkeys = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
options = {
key = lib.mkOption {
type = lib.types.strMatching "[a-zA-Z0-9-]+";
default = builtins.replaceStrings [" " "/" "_"] ["-" "-" "-"] name;
};
name = lib.mkOption {
type = lib.types.str;
default = name;
};
binding = lib.mkOption {
type = lib.types.str;
};
command = lib.mkOption {
type = lib.types.str;
};
};
}));
default = {};
};
};
config = {
home.packages = config.gnome.extensions;
dconf = {
settings = lib.mkMerge [
{
"org/gnome/shell" = {
disable-user-extensions = false; # enables user extensions
enabled-extensions = builtins.map (extension: extension.extensionUuid) config.gnome.extensions;
};
"org/gnome/desktop/wm/preferences".button-layout = lib.mkIf config.gnome.extraWindowControls ":minimize,maximize,close";
"org/gnome/desktop/interface".color-scheme = config.gnome.colorScheme;
"org/gnome/desktop/interface".accent-color = config.gnome.accentColor;
"org/gnome/desktop/interface".clock-format = config.gnome.clockFormat;
}
(
lib.mkMerge (
builtins.map (value: let
entry = "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${value.key}";
in {
${entry} = {
binding = value.binding;
command = value.command;
name = value.name;
};
"org/gnome/settings-daemon/plugins/media-keys" = {
custom-keybindings = [
"/${entry}/"
];
};
})
(
lib.attrsets.mapAttrsToList (_: value: value) config.gnome.hotkeys
)
)
)
];
};
};
}

View file

@ -6,7 +6,6 @@
...
}: {
options.programs.openssh = {
enable = lib.mkEnableOption "should we enable openssh";
authorizedKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
@ -38,65 +37,63 @@
};
};
config = lib.mkIf config.programs.openssh.enable (
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
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
);
};
})
];
}

View file

@ -1,15 +0,0 @@
{
lib,
config,
osConfig,
...
}: {
config = lib.mkIf (config.programs.anki.enable && osConfig.host.impermanence.enable) {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.dataHome}/Anki2/"
];
allowOther = true;
};
};
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.bitwarden = {
enable = lib.mkEnableOption "enable bitwarden";
};
config = lib.mkIf config.programs.bitwarden.enable (lib.mkMerge [
{
home.packages = with pkgs; [
bitwarden
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/Bitwarden"
];
allowOther = true;
};
}
)
]);
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.bruno = {
enable = lib.mkEnableOption "enable bruno";
};
config = lib.mkIf config.programs.bruno.enable (lib.mkMerge [
{
home.packages = with pkgs; [
bruno
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/bruno/"
];
allowOther = true;
};
}
)
]);
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.calibre = {
enable = lib.mkEnableOption "enable calibre";
};
config = lib.mkIf config.programs.calibre.enable (lib.mkMerge [
{
home.packages = with pkgs; [
calibre
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/calibre"
];
allowOther = true;
};
}
)
]);
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.dbeaver-bin = {
enable = lib.mkEnableOption "enable dbeaver";
};
config = lib.mkIf config.programs.dbeaver-bin.enable (lib.mkMerge [
{
home.packages = with pkgs; [
dbeaver-bin
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.dataHome}/DBeaverData/"
];
allowOther = true;
};
}
)
]);
}

View file

@ -1,20 +0,0 @@
{...}: {
imports = [
./firefox.nix
./signal.nix
./bitwarden.nix
./makemkv.nix
./obs.nix
./anki.nix
./qbittorrent.nix
./discord.nix
./obsidian.nix
./prostudiomasters.nix
./idea.nix
./protonvpn.nix
./calibre.nix
./bruno.nix
./dbeaver.nix
./steam.nix
];
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.discord = {
enable = lib.mkEnableOption "enable discord";
};
config = lib.mkIf config.programs.discord.enable (lib.mkMerge [
{
home.packages = with pkgs; [
discord
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/discord/"
];
allowOther = true;
};
}
)
]);
}

View file

@ -1,43 +0,0 @@
{
lib,
config,
osConfig,
...
}: let
buildProfilePersistence = profile: {
directories = [
".mozilla/firefox/${profile}/extensions"
];
files = [
".mozilla/firefox/${profile}/cookies.sqlite"
".mozilla/firefox/${profile}/favicons.sqlite"
# Permissions and ${profileName} levels for each site
".mozilla/firefox/${profile}/permissions.sqlite"
".mozilla/firefox/${profile}/content-prefs.sqlite"
# Browser history and bookmarks
".mozilla/firefox/${profile}/places.sqlite"
# I guess this is useful?
# https://bugzilla.mozilla.org/show_bug.cgi?id=1511384
# https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria
".mozilla/firefox/${profile}/storage.sqlite"
# Extension configuration
".mozilla/firefox/${profile}/extension-settings.json"
];
allowOther = true;
};
in {
config = lib.mkIf (config.programs.firefox.enable && osConfig.host.impermanence.enable) {
home.persistence."/persist${config.home.homeDirectory}" = lib.mkMerge (
(
lib.attrsets.mapAttrsToList
(profile: _: buildProfilePersistence profile)
config.programs.firefox.profiles
)
++ (
lib.lists.optional
((builtins.length (lib.attrsets.mapAttrsToList (key: value: value) config.programs.firefox.profiles)) == 0)
(buildProfilePersistence "default")
)
);
};
}

View file

@ -1,33 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.jetbrains.idea-community = {
enable = lib.mkEnableOption "enable idea-community";
};
config = lib.mkIf config.programs.jetbrains.idea-community.enable (lib.mkMerge [
{
home.packages = with pkgs; [
jetbrains.idea-community
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
# configuration
"${config.xdg.configHome}/JetBrains/"
# plugins
"${config.xdg.dataHome}/JetBrains/"
# System and Logs
"${config.xdg.cacheHome}/JetBrains/"
];
};
}
)
]);
}

View file

@ -1,42 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.makemkv = {
enable = lib.mkEnableOption "enable makemkv";
appKeyFile = lib.mkOption {
type = lib.types.str;
};
destinationDir = lib.mkOption {
type = lib.types.str;
};
};
config = lib.mkIf config.programs.makemkv.enable (lib.mkMerge [
{
home.packages = with pkgs; [
makemkv
];
sops.templates."MakeMKV.settings.conf".content = ''
app_DestinationDir = "${config.programs.makemkv.destinationDir}"
app_DestinationType = "2"
app_Key = "${config.programs.makemkv.appKeyFile}"
'';
home.file.".MakeMKV/settings.conf".source = config.lib.file.mkOutOfStoreSymlink config.sops.templates."MakeMKV.settings.conf".path;
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
".MakeMKV"
];
};
}
)
]);
}

View file

@ -1,14 +0,0 @@
{
lib,
config,
osConfig,
...
}: {
config = lib.mkIf config.programs.obs-studio.enable (lib.mkMerge [
(
lib.mkIf osConfig.host.impermanence.enable {
# TODO: map impermanence for obs
}
)
]);
}

View file

@ -1,18 +0,0 @@
{
lib,
config,
osConfig,
...
}: {
config = lib.mkIf config.programs.obsidian.enable (lib.mkMerge [
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/obsidian"
];
};
}
)
]);
}

View file

@ -1,28 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.prostudiomasters = {
enable = lib.mkEnableOption "enable prostudiomasters";
};
config = lib.mkIf config.programs.prostudiomasters.enable (lib.mkMerge [
{
home.packages = with pkgs; [
prostudiomasters
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/ProStudioMasters"
];
};
}
)
]);
}

View file

@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.protonvpn-gui = {
enable = lib.mkEnableOption "enable protonvpn";
};
config = lib.mkIf config.programs.protonvpn-gui.enable (lib.mkMerge [
{
home.packages = with pkgs; [
protonvpn-gui
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/protonvpn"
"${config.xdg.configHome}/Proton"
];
};
}
)
]);
}

View file

@ -1,28 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.qbittorrent = {
enable = lib.mkEnableOption "enable qbittorrent";
};
config = lib.mkIf config.programs.qbittorrent.enable (lib.mkMerge [
{
home.packages = with pkgs; [
qbittorrent
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/qBittorrent"
];
};
}
)
]);
}

View file

@ -1,28 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.signal-desktop-bin = {
enable = lib.mkEnableOption "enable signal";
};
config = lib.mkIf config.programs.signal-desktop-bin.enable (lib.mkMerge [
{
home.packages = with pkgs; [
signal-desktop-bin
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
"${config.xdg.configHome}/Signal"
];
};
}
)
]);
}

View file

@ -1,37 +0,0 @@
{
lib,
pkgs,
config,
osConfig,
...
}: {
options.programs.steam = {
enable = lib.mkEnableOption "enable steam";
};
config = lib.mkIf config.programs.steam.enable (
lib.mkMerge [
{
home.packages = with pkgs; [
steam
steam.run
];
}
(
lib.mkIf osConfig.host.impermanence.enable {
home.persistence."/persist${config.home.homeDirectory}" = {
directories = [
{
directory = "${config.xdg.dataHome}/Steam";
method = "symlink";
}
];
allowOther = true;
};
}
)
]
);
# TODO: bind impermanence config
}

View file

@ -1,7 +0,0 @@
{...}: {
config = {
sops = {
age.keyFile = "/var/lib/sops-nix/key.txt";
};
};
}

View file

@ -1,17 +0,0 @@
{
lib,
config,
osConfig,
...
}: {
options.user = {
isDesktopUser = lib.mkOption {
type = lib.types.bool;
default = osConfig.host.users.${config.home.username}.isDesktopUser;
};
isTerminalUser = lib.mkOption {
type = lib.types.bool;
default = osConfig.host.users.${config.home.username}.isTerminalUser;
};
};
}

View file

@ -14,8 +14,8 @@
./ollama.nix
./ai.nix
./tailscale.nix
./steam.nix
./server
./packages
];
nixpkgs.config.permittedInsecurePackages = [

View file

@ -11,25 +11,6 @@
host.desktop.enable = lib.mkDefault true;
}
(lib.mkIf config.host.desktop.enable {
environment.gnome.excludePackages = with pkgs; [
xterm # default terminal
atomix # puzzle game
cheese # webcam tool
epiphany # web browser
geary # email reader
gedit # text editor
decibels # audio player
gnome-characters # character set viewer
gnome-music # music player
gnome-photos # photo viewer
gnome-logs # log viewer
gnome-maps # map viewer
gnome-tour # welcome tour
hitori # sudoku game
iagno # go game
tali # poker game
yelp # help viewer
];
services = {
# Enable CUPS to print documents.
printing.enable = true;
@ -38,14 +19,34 @@
# 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
];
};
# Enable the GNOME Desktop Environment.
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
pipewire = {
enable = true;
alsa.enable = true;
@ -69,6 +70,8 @@
# enable RealtimeKit for pulse audio
security.rtkit.enable = true;
# disable welcome tour
environment.gnome.excludePackages = [pkgs.gnome-tour];
})
];
}

View file

@ -20,8 +20,6 @@
disk: lib.attrsets.nameValuePair (hashDisk disk) disk
)
config.host.storage.pool.cache;
datasets = config.host.storage.pool.datasets // config.host.storage.pool.extraDatasets;
in {
options.host.storage = {
enable = lib.mkEnableOption "are we going create zfs disks with disko on this device";
@ -50,68 +48,21 @@ in {
};
};
pool = {
mode = lib.mkOption {
type = lib.types.str;
default = "raidz2";
description = "what level of redundancy should this pool have";
};
# list of drives in pool that will have a boot partition put onto them
bootDrives = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "list of disks that are going to have a boot partition installed on them";
default = lib.lists.flatten config.host.storage.pool.vdevs;
};
# shorthand for vdevs if you only have 1 vdev
drives = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "list of drives that are going to be in the vdev";
default = [];
};
# list of all drives in each vdev
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];
};
# list of cache drives for pool
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 = [];
};
# Default datasets that are needed to make a functioning system
datasets = lib.mkOption {
type = lib.types.attrsOf (inputs.disko.lib.subType {
types = {inherit (inputs.disko.lib.types) zfs_fs zfs_volume;};
});
default = {
"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
'';
};
};
};
extraDatasets = lib.mkOption {
type = lib.types.attrsOf (inputs.disko.lib.subType {
types = {inherit (inputs.disko.lib.types) zfs_fs zfs_volume;};
@ -170,37 +121,59 @@ in {
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 = {
ESP = lib.mkIf (builtins.elem drive.value config.host.storage.pool.bootDrives) {
# The 2GB here for the boot partition might be a bit overkill we probably only need like 1/4th of that but storage is cheap
size = "2G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = ["umask=0077"];
};
};
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "rpool";
(
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) ++ cache
})
(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
)
)
);
@ -212,7 +185,7 @@ in {
type = "topology";
vdev = (
builtins.map (disks: {
mode = config.host.storage.pool.mode;
mode = "raidz2";
members =
builtins.map (disk: disk.name) disks;
})
@ -249,15 +222,13 @@ in {
);
datasets = lib.mkMerge [
(
lib.attrsets.mapAttrs (name: value: {
(lib.attrsets.mapAttrs (name: value: {
type = value.type;
options = value.options;
mountpoint = value.mountpoint;
postCreateHook = value.postCreateHook;
})
datasets
)
config.host.storage.pool.extraDatasets)
];
};
};

View file

@ -4,6 +4,5 @@
./flipperzero.nix
./i18n.nix
./openssh.nix
./steam.nix
];
}

View file

@ -1,18 +0,0 @@
{
lib,
config,
...
}: let
setupSteam =
lib.lists.any
(value: value)
(lib.attrsets.mapAttrsToList (name: value: value.programs.steam.enable) config.home-manager.users);
in {
config = lib.mkIf setupSteam {
programs.steam = {
enable = true;
# TODO: figure out how to not install steam here
# package = lib.mkDefault pkgs.emptyFile;
};
};
}

View file

@ -25,18 +25,6 @@
}
];
# fixes issues with /var/lib/private not having the correct permissions https://github.com/nix-community/impermanence/issues/254
system.activationScripts."createPersistentStorageDirs".deps = ["var-lib-private-permissions" "users" "groups"];
system.activationScripts = {
"var-lib-private-permissions" = {
deps = ["specialfs"];
text = ''
mkdir -p /persist/system/root/var/lib/private
chmod 0700 /persist/system/root/var/lib/private
'';
};
};
programs.fuse.userAllowOther = true;
boot.initrd.postResumeCommands = lib.mkAfter ''
@ -50,6 +38,33 @@
};
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";

View file

@ -32,11 +32,17 @@
enable = true;
hideMounts = true;
directories = [
{
directory = config.services.ollama.models;
user = config.services.ollama.user;
group = config.services.ollama.group;
}
{
directory = "/var/lib/private/ollama";
user = config.services.ollama.user;
group = config.services.ollama.group;
mode = "0700";
defaultPerms.mode = "0700";
}
];
};

View file

@ -0,0 +1,17 @@
{pkgs, ...}: {
nixpkgs.overlays = [
(final: prev: {
webtoon-dl =
pkgs.callPackage
./webtoon-dl.nix
{};
})
# TODO: this package always needs to be called with the --in-process-gpu flag for some reason, can we automate that?
(final: prev: {
prostudiomasters =
pkgs.callPackage
./prostudiomasters.nix
{};
})
];
}

View file

@ -0,0 +1,72 @@
{
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";
}
];
};
})
]);
}

View file

@ -8,10 +8,9 @@
./jellyfin.nix
./forgejo.nix
./searx.nix
./home-assistant.nix
./wyoming.nix
./virt-home-assistant.nix
./adguardhome.nix
./immich.nix
./qbittorent.nix
./paperless.nix
];
}

View file

@ -16,6 +16,20 @@ in {
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 = {
@ -47,6 +61,16 @@ in {
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 {};
};

View file

@ -28,12 +28,6 @@ in {
extraUsers = {
${db_user} = {
isClient = true;
createUser = true;
};
};
extraDatabases = {
${db_user} = {
name = db_user;
};
};
};

View file

@ -1,229 +1,130 @@
{
lib,
pkgs,
config,
inputs,
...
}: let
configDir = "/var/lib/hass";
dbUser = "hass";
in {
options.services.home-assistant = {
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";
};
database = lib.mkOption {
type = lib.types.enum [
"builtin"
"postgres"
];
description = "what database do we want to use";
default = "builtin";
};
extensions = {
sonos = {
enable = lib.mkEnableOption "enable the sonos plugin";
port = lib.mkOption {
type = lib.types.int;
default = 1400;
description = "what port to use for sonos discovery";
};
};
jellyfin = {
enable = lib.mkEnableOption "enable the jellyfin plugin";
};
wyoming = {
enable = lib.mkEnableOption "enable wyoming";
};
};
};
config = lib.mkIf config.services.home-assistant.enable (lib.mkMerge [
config = lib.mkIf config.host.home-assistant.enable (lib.mkMerge [
{
host = {
reverse_proxy.subdomains.${config.services.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;
'';
};
};
services.home-assistant = {
configDir = configDir;
extraComponents = [
"default_config"
"esphome"
"met"
"radio_browser"
"isal"
"zha"
"webostv"
"tailscale"
"syncthing"
"analytics_insights"
"unifi"
"openweathermap"
"ollama"
"mobile_app"
"logbook"
"ssdp"
"usb"
"webhook"
"bluetooth"
"dhcp"
"energy"
"history"
"backup"
"assist_pipeline"
"conversation"
"sun"
"zeroconf"
"cpuspeed"
];
config = {
http = {
server_port = 8123;
use_x_forwarded_for = true;
trusted_proxies = ["127.0.0.1" "::1"];
ip_ban_enabled = true;
login_attempts_threshold = 10;
};
homeassistant = {
external_url = "https://${config.services.home-assistant.subdomain}.${config.host.reverse_proxy.hostname}";
# internal_url = "http://192.168.1.2:8123";
};
recorder.db_url = "postgresql://@/${dbUser}";
"automation manual" = [];
"automation ui" = "!include automations.yaml";
mobile_app = {};
};
extraPackages = python3Packages:
with python3Packages; [
hassil
numpy
gtts
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";
# };
});
}
];
};
};
# TODO: configure /var/lib/hass/secrets.yaml via sops
# 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}";
networking.firewall.allowedUDPPorts = [
1900
];
# websockets.enable = true;
# forwardHeaders.enable = true;
systemd.tmpfiles.rules = [
"f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass"
];
# extraConfig = ''
# add_header Upgrade $http_upgrade;
# add_header Connection \"upgrade\";
# proxy_buffering off;
# proxy_read_timeout 90;
# '';
# };
# };
}
(lib.mkIf (config.services.home-assistant.extensions.sonos.enable) {
services.home-assistant.extraComponents = ["sonos"];
networking.firewall.allowedTCPPorts = [
config.services.home-assistant.extensions.sonos.port
];
})
(lib.mkIf (config.services.home-assistant.extensions.jellyfin.enable) {
services.home-assistant.extraComponents = ["jellyfin"];
# TODO: configure port, address, and login information here
})
(lib.mkIf (config.services.home-assistant.extensions.wyoming.enable) {
services.home-assistant.extraComponents = ["wyoming"];
services.wyoming.enable = true;
})
(lib.mkIf (config.services.home-assistant.database == "postgres") {
host = {
postgres = {
enable = true;
extraUsers = {
${dbUser} = {
isClient = true;
createUser = true;
};
};
extraDatabases = {
${dbUser} = {
name = dbUser;
};
};
};
};
services.home-assistant = {
extraPackages = python3Packages:
with python3Packages; [
psycopg2
];
};
systemd.services.home-assistant = {
requires = [
config.systemd.services.postgresql.name
];
};
})
(lib.mkIf config.services.fail2ban.enable {
environment.etc = {
"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 = {
jails = {
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;
};
};
};
})
(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";
}
];
};
# 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";
# }
# ];
# };
})
]);
}

View file

@ -55,7 +55,7 @@ in {
}
(lib.mkIf config.services.fail2ban.enable {
environment.etc = {
"fail2ban/filter.d/jellyfin.local".text = (
"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>\"\\\)\\\."
@ -65,7 +65,7 @@ in {
services.fail2ban = {
jails = {
jellyfin-iptables.settings = {
jellyfin-iptables.settings = lib.mkIf config.services.jellyfin.enable {
enabled = true;
filter = "jellyfin";
action = ''iptables-multiport[name=HTTP, port="http,https"]'';

View file

@ -1,110 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
dataDir = "/var/lib/paperless";
in {
options.services.paperless = {
subdomain = lib.mkOption {
type = lib.types.str;
description = "subdomain of base domain that paperless will be hosted at";
default = "paperless";
};
database = {
user = lib.mkOption {
type = lib.types.str;
description = "what is the user and database that we are going to use for paperless";
default = "paperless";
};
};
};
config = lib.mkIf config.services.paperless.enable (lib.mkMerge [
{
host = {
reverse_proxy.subdomains.${config.services.paperless.subdomain} = {
target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}";
websockets.enable = true;
forwardHeaders.enable = true;
extraConfig = ''
# allow large file uploads
client_max_body_size 50000M;
'';
};
postgres = {
enable = true;
extraUsers = {
${config.services.paperless.database.user} = {
isClient = true;
createUser = true;
};
};
extraDatabases = {
${config.services.paperless.database.user} = {
name = config.services.paperless.database.user;
};
};
};
};
services.paperless = {
configureTika = true;
settings = {
PAPERLESS_URL = "https://${config.services.paperless.subdomain}.${config.host.reverse_proxy.hostname}";
PAPERLESS_DBENGINE = "postgresql";
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_DBNAME = config.services.paperless.database.user;
PAPERLESS_DBUSER = config.services.paperless.database.user;
};
};
}
(lib.mkIf config.services.fail2ban.enable {
environment.etc = {
"fail2ban/filter.d/paperless.local".text = (
pkgs.lib.mkDefault (pkgs.lib.mkAfter ''
[Definition]
failregex = Login failed for user `.*` from (?:IP|private IP) `<HOST>`\.$
ignoreregex =
'')
);
};
services.fail2ban = {
jails = {
paperless.settings = {
enabled = true;
filter = "paperless";
action = ''iptables-multiport[name=HTTP, port="http,https"]'';
logpath = "${config.services.paperless.dataDir}/log/*.log";
backend = "auto";
findtime = 600;
bantime = 600;
maxretry = 5;
};
};
};
})
(lib.mkIf config.host.impermanence.enable {
assertions = [
{
assertion = config.services.paperless.dataDir == dataDir;
message = "paperless data location does not match persistence";
}
];
environment.persistence."/persist/system/root" = {
directories = [
{
directory = dataDir;
user = "paperless";
group = "paperless";
}
];
};
})
]);
}

View file

@ -4,7 +4,7 @@
...
}: {
options.host.podman = {
enable = lib.mkEnableOption "should podman be enabled on this computer";
enable = lib.mkEnableOption "should home-assistant be enabled on this computer";
macvlan = {
subnet = lib.mkOption {
type = lib.types.str;

View file

@ -0,0 +1,155 @@
{
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;
}
];
};
})
]);
}

View file

@ -1,63 +0,0 @@
{
lib,
config,
...
}: {
options.services.wyoming.enable = lib.mkEnableOption "should wyoming be enabled on this device";
config = lib.mkIf config.services.wyoming.enable (lib.mkMerge [
{
services.wyoming = {
# Text to speech
piper = {
servers = {
"en" = {
enable = true;
# see https://github.com/rhasspy/rhasspy3/blob/master/programs/tts/piper/script/download.py
voice = "en-us-amy-low";
uri = "tcp://0.0.0.0:10200";
speaker = 0;
};
};
};
# Speech to text
faster-whisper = {
servers = {
"en" = {
enable = true;
# see https://github.com/rhasspy/rhasspy3/blob/master/programs/asr/faster-whisper/script/download.py
model = "tiny-int8";
language = "en";
uri = "tcp://0.0.0.0:10300";
device = "cpu";
};
};
};
openwakeword = {
enable = true;
uri = "tcp://0.0.0.0:10400";
preloadModels = [
"ok_nabu"
];
# TODO: custom models
};
};
# needs access to /proc/cpuinfo
systemd.services."wyoming-faster-whisper-en".serviceConfig.ProcSubset = lib.mkForce "all";
}
(lib.mkIf config.host.impermanence.enable {
environment.persistence."/persist/system/root" = {
enable = true;
hideMounts = true;
directories = [
{
directory = "/var/lib/private/wyoming";
mode = "0700";
}
];
};
})
]);
}

View file

@ -1,9 +0,0 @@
{...}: {
programs = {
steam = {
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Game Transfers
};
};
}

View file

@ -1,5 +1,6 @@
{...}: {
nix = {
settings.download-buffer-size = 524288000;
gc = {
automatic = true;
dates = "weekly";

View file

@ -17,13 +17,13 @@
eve = 1002;
jellyfin = 2000;
forgejo = 2002;
adguardhome = 2003;
hass = 2004;
syncthing = 2007;
ollama = 2008;
git = 2009;
immich = 2010;
qbittorrent = 2011;
paperless = 2012;
};
gids = {
@ -33,13 +33,13 @@
jellyfin_media = 2001;
jellyfin = 2000;
forgejo = 2002;
adguardhome = 2003;
hass = 2004;
syncthing = 2007;
ollama = 2008;
git = 2009;
immich = 2010;
qbittorrent = 2011;
paperless = 2012;
};
users = config.users.users;
@ -127,6 +127,12 @@ in {
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;
@ -163,12 +169,6 @@ in {
isNormalUser = true;
group = config.users.users.qbittorrent.name;
};
paperless = {
uid = lib.mkForce uids.paperless;
isSystemUser = true;
group = config.users.users.paperless.name;
};
};
groups = {
@ -219,6 +219,14 @@ in {
];
};
adguardhome = {
gid = lib.mkForce gids.adguardhome;
members = [
users.adguardhome.name
# leyla
];
};
hass = {
gid = lib.mkForce gids.hass;
members = [
@ -265,13 +273,6 @@ in {
leyla
];
};
paperless = {
gid = lib.mkForce gids.paperless;
members = [
users.paperless.name
];
};
};
};
}

@ -1 +1 @@
Subproject commit f016767c13aa36dde91503f7a9f01bdd02468045
Subproject commit 3d63dff77f8eda1667e3586169642cf256c4aa34

View file

@ -65,7 +65,7 @@ flake=${flake:-$target}
mode=${mode:-switch}
user=${user:-$USER}
command="nixos-rebuild $mode --sudo --ask-sudo-password --flake .#$flake"
command="nixos-rebuild $mode --use-remote-sudo --flake .#$flake"
if [[ $host ]];
then

View file

@ -10,7 +10,7 @@
nix-syncthing = inputs.nix-syncthing;
disko = inputs.disko;
impermanence = inputs.impermanence;
lix-module = inputs.lix-module;
# lix-module = inputs.lix-module;
systems = [
"aarch64-darwin"
@ -53,7 +53,7 @@
../modules/system-modules
];
in {
forEachPkgs = lambda: forEachSystem (system: lambda system (pkgsFor system));
forEachPkgs = lambda: forEachSystem (system: lambda (pkgsFor system));
mkUnless = condition: yes: (lib.mkIf (!condition) yes);
mkIfElse = condition: yes: no:
@ -83,7 +83,7 @@ in {
impermanence.nixosModules.impermanence
home-manager.nixosModules.home-manager
disko.nixosModules.disko
lix-module.nixosModules.default
# lix-module.nixosModules.default
../modules/nixos-modules
../configurations/nixos/${host}
];