refactor!: battleship alive!

This commit is contained in:
Gustavo "Guz" L. de Mello
2024-04-10 13:12:23 -03:00
parent 69c5ca2bd7
commit 5082bdeed4
85 changed files with 744 additions and 4958 deletions

View File

@@ -1,7 +1,11 @@
keys:
- &primary age1sseqwwa7fc0ftry8njyuagdg28fkmtdwmj6m7p3etjsj83suee3shfzjyz
creation_rules:
- path_regex: secrets/desktop-secrets.yaml$
- path_regex: secrets/battleship-secrets.yaml$
key_groups:
- age:
- *primary
- path_regex: secrets/battleship-secrets.lesser.json$
key_groups:
- age:
- *primary

View File

@@ -0,0 +1,136 @@
{
config,
pkgs,
inputs,
lib,
...
}: {
imports = [
../../modules/nixos
./secrets.nix
./gpu-configuration.nix
./hardware-configuration.nix
];
programs.nih.enable = true;
programs.nih.flakeDir = "/home/guz/.nix";
programs.nih.host = "battleship";
profiles.locale.enable = true;
programs.hyprland.enable = true;
services.xserver = {
enable = true;
displayManager = {
sddm.enable = true;
};
};
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-gnome3;
};
services.flatpak.enable = true;
xdg.portal.enable = true;
xdg.portal.extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
fonts.fontconfig.enable = true;
fonts.packages = with pkgs; [
fira-code
(nerdfonts.override {fonts = ["FiraCode"];})
];
home-manager-helper.enable = true;
home-manager-helper.users."guz" = {
name = "guz";
shell = pkgs.zsh;
hashedPassword = "$y$j9T$J7gmdB306rufrjdsY5kJq0$spluDZf8jEkG0VYcZXzBIpnACVIk27C8YTbo2vbNFfA";
home = import ./home.nix;
isNormalUser = true;
extraGroups = ["wheel" "networkmanager"];
};
environment.sessionVariables = {
EDITOR = "nvim";
};
environment.systemPackages = with pkgs; [
git
];
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
# hardware.pulseaudio.enable = true;
services.interception-tools = let
device = "/dev/input/by-id/usb-BY_Tech_Gaming_Keyboard-event-kbd";
in {
enable = true;
plugins = [pkgs.interception-tools-plugins.caps2esc];
udevmonConfig = ''
- JOB: "${pkgs.interception-tools}/bin/intercept -g ${device} | ${pkgs.interception-tools-plugins.caps2esc}/bin/caps2esc -m 2 | ${pkgs.interception-tools}/bin/uinput -d ${device}"
DEVICE:
EVENTS:
EV_KEY: [[KEY_CAPSLOCK, KEY_ESC]]
LINK: ${device}
'';
};
environment.pathsToLink = [" /share/zsh "];
programs.zsh.enable = true;
nix.settings.experimental-features = ["nix-command" "flakes"];
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [];
networking = {
networkmanager.enable = true;
hostName = "battleship";
wireless.enable = false;
dhcpcd.enable = true;
defaultGateway = "192.168.1.1";
interfaces."enp6s0".ipv4.addresses = [
{
address = "192.168.1.13";
prefixLength = 24;
}
];
nameservers = ["8.8.8.8" "1.1.1.1"];
};
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
wireplumber.enable = true;
#jack.enable = true;
};
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
}

View File

@@ -0,0 +1,89 @@
{
config,
lib,
inputs,
pkgs,
...
}: let
cfg = config.desktop.colors;
in {
imports = [
inputs.nix-colors.homeManagerModules.default
];
options.desktop.colors = with lib;
with lib.types; {
accent = mkOption {
type = str;
default = "cdd6f4";
description = "The accent color of Frappuccino";
};
accentBase = mkOption {
type = str;
default = "magenta";
description = "The base name for the accent color to be used in the terminal";
};
scheme = mkOption {
type = path;
default = ./frappuccino.yaml;
};
};
config = with lib; {
colorScheme = inputs.nix-colors.lib.schemeFromYAML "frappuccino" (builtins.readFile cfg.scheme);
home.packages = with pkgs; [
gnome.gnome-themes-extra
];
gtk = {
enable = true;
theme = {
name = "Catppuccin-Mocha-Compact-Mauve-Dark";
package = pkgs.catppuccin-gtk.override {
size = "compact";
tweaks = ["rimless" "black"];
accents = ["mauve"];
variant = "mocha";
};
};
};
programs.wezterm.config.color_scheme = mkDefault "system";
programs.wezterm.colorSchemes = mkIf (config.programs.wezterm.config.color_scheme == "system") {
system = with config.colorScheme.palette; {
foreground = "#${base05}";
background = "#${base00}";
cursor_fg = "#${base01}";
cursor_bg = "#${cfg.accent}";
cursor_border = "#${cfg.accent}";
selection_fg = "#${base04}";
selection_bg = "#${cfg.accent}";
split = "#${base04}";
ansi = [
"#${base03}"
"#${base08}"
"#${base0B}"
"#${base0A}"
"#${base0D}"
"#${base0E}"
"#${base0C}"
"#${base03}"
];
brights = [
"#${base03}"
"#${base08}"
"#${base0B}"
"#${base0A}"
"#${base0D}"
"#${base0E}"
"#${base0C}"
"#${base03}"
];
};
};
};
}

View File

@@ -0,0 +1,112 @@
{
config,
pkgs,
...
}: let
wallpaper = ../../../static/guz-wallpaper-default.png;
desktop-boot = pkgs.writeShellScriptBin "desktop-boot" ''
function eww() { ${config.programs.eww.package}/bin/eww "$@"; }
function swww() { ${pkgs.swww}/bin/swww "$@"; }
function swww-daemon() { ${pkgs.swww}/bin/swww-daemon "$@"; }
if [[ "$(eww ping)" -ne "pong" ]]; then
eww daemon &> /dev/null
fi
eww close-all
eww open bar
eww open bar-2
eww reload
(swww-daemon &> /dev/null) & swww img "${/. + wallpaper}"
'';
desktop-update = pkgs.writeShellScriptBin "desktop-update" ''
function hyprctl() { ${config.wayland.windowManager.hyprland.package}/bin/hyprctl; }
# hyprctl reload
'';
in {
imports = [
./keymaps.nix
./colors
./eww
];
programs.hyprland.enable = true;
programs.hyprland.settings = let
monitor-1 = "HDMI-A-1";
monitor-2 = "DVI-D-1";
in {
animations = {
enabled = true;
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
animation = [
"windows, 1, 7, myBezier"
"windowsOut, 1, 7, default, popin 80%"
"border, 1, 10, default"
"borderangle, 1, 8, default"
"fade, 1, 7, default"
"workspaces, 1, 6, default"
];
};
decoration = {
rounding = 5;
dim_inactive = true;
dim_strength = 0.2;
dim_around = 0.4;
blur.enabled = false;
};
dwindle = {
pseudotile = true;
preserve_split = true;
};
exec = [
"${desktop-boot}/bin/desktop-boot"
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
];
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 0;
"col.active_border" = "rgba(ffffff99) rgba(ffffff33) 90deg";
"col.inactive_border" = "rgba(18181800)";
layout = "dwindle";
};
gestures.workspace_swipe = false;
input = {
kb_layout = "br";
kb_variant = "abnt2";
follow_mouse = 1;
sensitivity = 0;
};
master.new_is_master = true;
monitor = [
"${monitor-1},2560x1080,0x0,1"
"${monitor-2},1920x1080,2560x0,1"
];
windowrulev2 = [
"float,class:^(org.inkscape.Inkscape)$"
"tile,class:^(org.inkscape.Inkscape)$,title:(.*)(- Inkscape)$"
];
workspace = [
# Primary monitor
"1,monitor:${monitor-1},default:true"
"2,monitor:${monitor-1}"
"3,monitor:${monitor-1}"
"4,monitor:${monitor-1}"
"5,monitor:${monitor-1}"
# Second monitor
"6,monitor:${monitor-2}"
"7,monitor:${monitor-1}"
"8,monitor:${monitor-1}"
"9,monitor:${monitor-1}"
"0,monitor:${monitor-1},default:true"
];
};
home.activation = {
desktop-update = "${desktop-update}/bin/desktop-update";
};
}

View File

@@ -4,7 +4,6 @@
pkgs,
...
}: let
cfg = config.eww;
ewwDir = "${config.xdg.configHome}/eww";
eww-get-active-workspace = pkgs.writeShellScriptBin "eww-get-active-workspace" ''
@@ -62,14 +61,9 @@
'';
in {
imports = [];
options.eww = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
eww-wayland
];
options = {};
config = {
programs.eww.package = pkgs.eww;
home.file."${ewwDir}/eww.yuck".source = ./eww.yuck;
home.file."${ewwDir}/eww.scss".source = ./eww.scss;
@@ -98,7 +92,7 @@ in {
'';
home.file."${ewwDir}/vars.scss".text = ''
$color-accent: #${config.theme.accent};
$color-accent: #${config.desktop.colors.accent};
$foreground: rgba(#${config.colorScheme.palette.base03}, 1);
$background: rgba(#${config.colorScheme.palette.base00} , 1);

View File

@@ -21,7 +21,7 @@ tooltip {
@include box-style();
color: $color-accent;
font-family: 'Fira Code Nerd Font';
font-family: 'Fira Code Nerd Font', 'Fira Code';
font-weight: bold;
background-color: $background;

View File

@@ -0,0 +1,53 @@
{pkgs, ...}: {
imports = [
];
programs.hyprland.enable = true;
programs.hyprland.settings = let
mod = "SUPER";
in {
bind = [
"${mod}, C, killactive"
"${mod}, M, exit"
"${mod}, V, togglefloating"
"${mod}, F, fullscreen"
"${mod}, Z, togglesplit"
"${mod}, Q, exec, ${pkgs.wezterm}/bin/wezterm"
"${mod}, E, exec, ${pkgs.wezterm}/bin/wezterm start lf"
"${mod} + SHIFT, E, exec, ${pkgs.librewolf}/bin/librewolf"
"${mod}, S, exec, ${pkgs.rofi}/bin/rofi -show drun -show-icons"
",Print, exec, ${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp -d)\" - | ${pkgs.wl-clipboard}/bin/wl-copy"
"${mod}, 1, workspace, 1"
"${mod}, 2, workspace, 2"
"${mod}, 3, workspace, 3"
"${mod}, 4, workspace, 4"
"${mod}, 5, workspace, 5"
"${mod} + SHIFT, 1, movetoworkspace, 1"
"${mod} + SHIFT, 2, movetoworkspace, 2"
"${mod} + SHIFT, 3, movetoworkspace, 3"
"${mod} + SHIFT, 4, movetoworkspace, 4"
"${mod} + SHIFT, 5, movetoworkspace, 5"
"${mod}, 6, workspace, 6"
"${mod}, 7, workspace, 7"
"${mod}, 8, workspace, 8"
"${mod}, 9, workspace, 9"
"${mod}, 0, workspace, 10"
"${mod} + SHIFT, 6, movetoworkspace, 6"
"${mod} + SHIFT, 7, movetoworkspace, 7"
"${mod} + SHIFT, 8, movetoworkspace, 8"
"${mod} + SHIFT, 9, movetoworkspace, 9"
"${mod} + SHIFT, 0, movetoworkspace, 10"
"${mod}, H, movefocus, l"
"${mod}, L, movefocus, r"
"${mod}, K, movefocus, u"
"${mod}, J, movefocus, d"
];
bindm = [
"${mod}, mouse:272, movewindow"
"${mod}, mouse:273, resizewindow"
];
};
}

27
hosts/battleship/home.nix Normal file
View File

@@ -0,0 +1,27 @@
{...}: {
imports = [
../../modules/home-manager
./packages.nix
./desktop
../../modules/home-manager/programs-old/librewolf
];
profiles.gterminal.enable = true;
programs.bash = {
enable = true;
initExtra = ''
export XDG_DATA_DIRS="$XDG_DATA_DIRS:/usr/share:/var/lib/flatpak/exports/share:$HOME/.local/share/flatpak/exports/share"
export GPG_TTY=$(tty)
'';
};
services.gnome-keyring.enable = true;
fonts.fontconfig.enable = true;
home.sessionVariables = {
EDITOR = "nvim";
};
}

View File

@@ -0,0 +1,70 @@
{
config,
pkgs,
inputs,
lib,
...
}: {
imports = [];
librewolf = {
enable = true;
profiles = {
guz = {
id = 0;
settings = {
"webgl.disabled" = false;
"browser.startup.homepage" = "https://search.brave.com";
"privacy.clearOnShutdown.history" = false;
"privacy.clearOnShutdown.downloads" = false;
"extensions.activeThemeID" = "firefox-compact-dark@mozilla.org";
"privacy.clearOnShutdown.cookies" = false;
};
extensions = with inputs.firefox-addons.packages."x86_64-linux"; [
darkreader
canvasblocker
smart-referer
libredirect
tridactyl
];
};
};
};
services.flatpak.enable = true;
xdg.portal.enable = true;
xdg.portal.extraPortals = with pkgs; [
xdg-desktop-portal-wlr
xdg-desktop-portal-gtk
];
xdg.portal.config = {
common.default = ["gtk"];
};
xdg.portal.xdgOpenUsePortal = true;
services.flatpak.packages = [
"nz.mega.MEGAsync"
"com.bitwarden.desktop"
"org.prismlauncher.PrismLauncher"
"org.mozilla.Thunderbird"
"net.blockbench.Blockbench"
];
nixpkgs.config.allowUnfree = true;
nixpkgs.config.allowUnfreePredicate = _: true;
home.packages = with pkgs; [
## Programs
webcord-vencord
gimp
inkscape
pureref
gamemode
lutris
pavucontrol
libreoffice
pinentry
## Fonts
fira-code
(nerdfonts.override {fonts = ["FiraCode"];})
];
}

View File

@@ -0,0 +1,42 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
lesser-secrets = with builtins;
fromJSON (readFile ../../secrets/battleship-secrets.lesser.decrypted.json);
jsonType = pkgs.formats.json {};
in {
imports = [
inputs.sops-nix.nixosModules.sops
];
options.battleship-secrets = with lib;
with lib.types; {
lesser = mkOption {
type = submodule ({...}: {
freeformType = jsonType.type;
options = {};
});
default = lesser-secrets;
};
};
config = {
environment.systemPackages = with pkgs; [
sops
];
sops.defaultSopsFile = ../../secrets/battleship-secrets.yaml;
sops.defaultSopsFormat = "yaml";
sops.secrets.lon = {
owner = config.users.users.guz.name;
};
sops.secrets.lat = {
owner = config.users.users.guz.name;
};
sops.age.keyFile = "/home/guz/.config/sops/age/keys.txt";
};
}

View File

@@ -1,9 +0,0 @@
{config, ...}: let
cfg = config.desktop;
in {
imports = [
./scripts/desktop.nix
];
options.desktop = {};
config = {};
}

View File

@@ -1,55 +0,0 @@
{pkgs, ...}: let
desktop = pkgs.writeShellScriptBin "desktop" ''
function cat() {
echo $1 | ${pkgs.lolcat}/bin/lolcat
echo ""
}
flakeDir="/home/guz/.nix"
function nix-build() {
local env="$2"
if [[ "$env" -ne "" ]]; then
cat "Building the $env desktop!"
sudo nixos-rebuild switch --flake "$flakeDir#desktop@$env"
else
cat "Building the desktop!"
sudo nixos-rebuild switch --flake "$flakeDir#desktop@default"
fi
}
# command for switching desktop environments/modes
function desktop-switch() {
local env="$1"
if [[ "$env" == "--build" ]]; then
nix-build $env $2
else
cat "Switching to $1 desktop!"
# this will be used a lot, that's why "test" and --fast is passed
# for building to a new configuration, use nix-build instead
sudo nixos-rebuild test --fast --flake "$flakeDir#desktop@$env"
fi
}
desktop-switch $1 $2
# echo "Restarting services (just in case)" # why? Because discord, as always
# systemctl --user stop xdg-desktop-portal-hyprland.service xdg-desktop-portal.service pipewire.service
# systemctl --user start xdg-desktop-portal-hyprland.service xdg-desktop-portal.service pipewire.service
echo ""
cat "Done!"
echo "Restarting zsh"
exec zsh
'';
in {
imports = [];
options.desktop.cli = {};
config = {
home.packages = [
desktop
];
};
}

View File

@@ -1,15 +0,0 @@
{pkgs, ...}: {
imports = [
../shared-configuration.nix
];
options.default.configuration = {};
config = {
set-user.users = [
{
username = "guz";
shell = pkgs.zsh;
home = import ./home.nix;
}
];
};
}

View File

@@ -1,9 +0,0 @@
{...}: {
imports = [
../shared-home.nix
];
options.default.home = {};
config = {
librewolf.profiles.guz.isDefault = true;
};
}

View File

@@ -1,51 +0,0 @@
{pkgs, ...}: {
imports = [
../../modules/home-manager/programs/hyprland.nix
];
options.keybinds = {};
config = {
hyprland.binds.keyboard = [
"$mod, C, killactive"
"$mod, M, exit"
"$mod, V, togglefloating"
"$mod, F, fullscreen"
"$mod, Z, togglesplit"
"$mod, Q, exec, ${pkgs.wezterm}/bin/wezterm"
"$mod, E, exec, ${pkgs.wezterm}/bin/wezterm start lf"
"$mod + SHIFT, E, exec, ${pkgs.librewolf}/bin/librewolf"
"$mod, S, exec, ${pkgs.rofi}/bin/rofi -show drun -show-icons"
",Print, exec, ${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp -d)\" - | ${pkgs.wl-clipboard}/bin/wl-copy"
"$mod, 1, workspace, 1"
"$mod, 2, workspace, 2"
"$mod, 3, workspace, 3"
"$mod, 4, workspace, 4"
"$mod, 5, workspace, 5"
"$mod + SHIFT, 1, movetoworkspace, 1"
"$mod + SHIFT, 2, movetoworkspace, 2"
"$mod + SHIFT, 3, movetoworkspace, 3"
"$mod + SHIFT, 4, movetoworkspace, 4"
"$mod + SHIFT, 5, movetoworkspace, 5"
"$mod, 6, workspace, 6"
"$mod, 7, workspace, 7"
"$mod, 8, workspace, 8"
"$mod, 9, workspace, 9"
"$mod, 0, workspace, 10"
"$mod + SHIFT, 6, movetoworkspace, 6"
"$mod + SHIFT, 7, movetoworkspace, 7"
"$mod + SHIFT, 8, movetoworkspace, 8"
"$mod + SHIFT, 9, movetoworkspace, 9"
"$mod + SHIFT, 0, movetoworkspace, 10"
"$mod, H, movefocus, l"
"$mod, L, movefocus, r"
"$mod, K, movefocus, u"
"$mod, J, movefocus, d"
];
hyprland.binds.mouse = [
"$mod, mouse:272, movewindow"
"$mod, mouse:273, resizewindow"
];
};
}

View File

@@ -1,284 +0,0 @@
{
config,
pkgs,
inputs,
lib,
...
}: {
imports = [
../../modules/nih
../../modules/nixos/config/host.nix
../../modules/nixos/systems/set-user.nix
../../modules/nixos/systems/fonts.nix
# Include the results of the hardware scan.
./hardware-configuration.nix
./gpu-configuration.nix
];
options.shared.configuration = {};
config = {
nih = {
enable = true;
ip = "192.168.1.13";
handleDomains = false;
networking = {
interface = "enp6s0";
wireless = false;
};
users.test = {
username = "test";
};
serives = {
tailscale.enable = true;
};
users.test = {
programs.hyprland = {
enable = true;
exec = [
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
];
monitors = [
{
name = "monitor1";
resolution = "2560x1080";
id = "HDMI-A-1";
}
{
name = "monitor2";
resolution = "1920x1080";
id = "DVI-D-1";
offset = "2560x0";
}
];
windowRules = {
"class:^(org.inkscape.Inkscape)$" = ["float"];
"class:^(org.inkscape.Inkscape)$,title:(.*)(- Inkscape)$" = ["tile"];
};
workspaces = [
# First monitor
{
name = "1";
monitor = "$monitor1";
default = true;
}
{
name = "2";
monitor = "$monitor1";
}
{
name = "3";
monitor = "$monitor1";
}
{
name = "4";
monitor = "$monitor1";
}
{
name = "5";
monitor = "$monitor1";
}
# Second monitor
{
name = "6";
monitor = "$monitor2";
}
{
name = "7";
monitor = "$monitor2";
}
{
name = "8";
monitor = "$monitor2";
}
{
name = "9";
monitor = "$monitor2";
}
{
name = "10";
monitor = "$monitor2";
default = true;
}
];
};
programs.lf = {
enable = true;
settings = {
preview = true;
hidden = true;
drawbox = true;
icons = true;
ignorecase = true;
};
keybindings = {
"." = "set hidden!";
"<enter>" = "open";
"%" = "mkfile";
d = "mkdir";
D = "delete";
ee = "editor-open";
};
};
};
};
my-fonts.enable = true;
my-fonts.user = "guz";
my-fonts.fonts = with pkgs; [
fira-code
(nerdfonts.override {fonts = ["FiraCode"];})
(google-fonts.override {fonts = ["Gloock" "Cinzel" "Red Hat Display"];})
(stdenv.mkDerivation rec {
pname = "calsans";
version = "1.0.0";
src = pkgs.fetchzip {
url = "https://github.com/calcom/font/releases/download/v${version}/CalSans_Semibold_v${version}.zip";
stripRoot = false;
hash = "sha256-JqU64JUgWimJgrKX3XYcml8xsvy//K7O5clNKJRGaTM=";
};
installPhase = ''
runHook preInstall
install -m444 -Dt $out/share/fonts/truetype fonts/webfonts/*.ttf
runHook postInstall
'';
meta = with lib; {
homepage = "https://github.com/calcom/font";
license = licenses.ofl;
platforms = platforms.all;
};
})
];
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [];
virtualisation.waydroid.enable = true;
sops.defaultSopsFile = ../../secrets/desktop-secrets.yaml;
sops.defaultSopsFormat = "yaml";
sops.secrets.lon = {
owner = config.users.users.guz.name;
};
sops.secrets.lat = {
owner = config.users.users.guz.name;
};
sops.age.keyFile = "/home/guz/.config/sops/age/keys.txt";
programs.hyprland = {
enable = true;
xwayland.enable = true;
package = inputs.hyprland.packages."${pkgs.system}".hyprland;
portalPackage = inputs.xdg-desktop-portal-hyprland.packages."${pkgs.system}".xdg-desktop-portal-hyprland;
};
xdg.portal.enable = true;
xdg.portal.extraPortals = with pkgs; [
xdg-desktop-portal-kde
];
environment.sessionVariables = {
WLR_NO_HARDWARE_CURSORS = "1";
NIXOS_OZONE_WL = "1";
};
environment.systemPackages = with pkgs; [
inputs.xdg-desktop-portal-hyprland.packages."${pkgs.system}".xdg-desktop-portal-hyprland
inputs.hyprland.packages."${pkgs.system}".hyprland
electron_28
wlroots
kitty
rofi-wayland
dunst
libnotify
swww
sops
wl-clipboard
];
nixpkgs.config.allowUnfreePredicate = pkg:
builtins.elem (lib.getName pkg) [
"steam"
"steam-original"
"steam-run"
];
programs.steam = {
enable = true;
};
# Enable the X11 windowing system.
services.xserver.enable = true;
# Enable the GNOME Desktop Environment.
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
programs.zsh.enable = true;
# Define a user account. Don't forget to set a password with passwd.
services.flatpak.enable = true;
environment.pathsToLink = [" /share/zsh "];
services.tailscale = {
enable = true;
useRoutingFeatures = "client";
};
hardware.opentabletdriver.enable = true;
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
# hardware.pulseaudio.enable = true;
services.interception-tools = let
device = "/dev/input/by-id/usb-BY_Tech_Gaming_Keyboard-event-kbd";
in {
enable = true;
plugins = [pkgs.interception-tools-plugins.caps2esc];
udevmonConfig = ''
- JOB: "${pkgs.interception-tools}/bin/intercept -g ${device} | ${pkgs.interception-tools-plugins.caps2esc}/bin/caps2esc -m 2 | ${pkgs.interception-tools}/bin/uinput -d ${device}"
DEVICE:
EVENTS:
EV_KEY: [[KEY_CAPSLOCK, KEY_ESC]]
LINK: ${device}
'';
};
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
};
}

View File

@@ -1,137 +0,0 @@
{
config,
pkgs,
inputs,
...
}: {
imports = [
../../modules/home-manager/theme.nix
../../modules/home-manager/programs-old/librewolf
../../modules/home-manager/programs-old/krita
../../modules/home-manager/programs-old/davinci.nix
../../modules/home-manager/programs-old/obs.nix
../../modules/home-manager/programs-old/obsidian.nix
../../modules/home-manager/packages-old/nixx.nix
../../modules/home-manager/packages-old/nixi.nix
./terminal.nix
./wm.nix
./keybinds.nix
./.desktop
];
options.shared.home = {};
config = {
programs.bash = {
enable = true;
initExtra = ''
export XDG_DATA_DIRS="$XDG_DATA_DIRS:/usr/share:/var/lib/flatpak/exports/share:$HOME/.local/share/flatpak/exports/share"
export GPG_TTY=$(tty)
'';
};
services.gnome-keyring.enable = true;
programs.gpg.enable = true;
services.gpg-agent = {
enable = true;
pinentryFlavor = "gnome3";
};
krita.enable = true;
davinci.enable = true;
obs.enable = true;
obsidian = {
enable = true;
vaultCmd = true;
};
librewolf = {
enable = true;
profiles = {
guz = {
id = 0;
settings = {
"webgl.disabled" = false;
"browser.startup.homepage" = "https://search.brave.com";
"privacy.clearOnShutdown.history" = false;
"privacy.clearOnShutdown.downloads" = false;
"extensions.activeThemeID" = "firefox-compact-dark@mozilla.org";
"privacy.clearOnShutdown.cookies" = false;
};
extensions = with inputs.firefox-addons.packages."x86_64-linux"; [
darkreader
canvasblocker
smart-referer
libredirect
tridactyl
];
};
};
};
services.flatpak.packages = [
"nz.mega.MEGAsync"
"com.bitwarden.desktop"
"org.prismlauncher.PrismLauncher"
"org.mozilla.Thunderbird"
"net.blockbench.Blockbench"
];
# services.flatpak.overrides = { };
nixpkgs.config.allowUnfree = true;
nixpkgs.config.allowUnfreePredicate = _: true;
home.packages = with pkgs; [
## Programs
webcord-vencord
gimp
inkscape
pureref
gamemode
lutris
pavucontrol
libreoffice
# (pkgs.writeShellScriptBin "my-hello" ''
# echo "Hello, ${config.home.username}!"
# '')
## Fonts
fira-code
(nerdfonts.override {fonts = ["FiraCode"];})
];
# Home Manager is pretty good at managing dotfiles. The primary way to manage
# plain files is through 'home.file'.
home.file = {
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
# # symlink to the Nix store copy.
# ".screenrc".source = dotfiles/screenrc;
# # You can also set the file content immediately.
# ".gradle/gradle.properties".text = ''
# org.gradle.console=verbose
# org.gradle.daemon.idletimeout=3600000
# '';
};
# Home Manager can also manage your environment variables through
# 'home.sessionVariables'. If you don't want to manage your shell through Home
# Manager then you have to manually source 'hm-session-vars.sh' located at
# either
#
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# /etc/profiles/per-user/guz/etc/profile.d/hm-session-vars.sh
#
home.sessionVariables = {
EDITOR = "neovim";
};
};
}

View File

@@ -1,46 +0,0 @@
{
config,
inputs,
pkgs,
...
}: {
imports = [
../../modules/home-manager/programs/lf.nix
../../modules/home-manager/programs/starship.nix
../../modules/home-manager/programs/tmux.nix
../../modules/home-manager/programs/wezterm.nix
../../modules/home-manager/programs/zsh.nix
];
options.terminal = {};
config = {
lf.enable = true;
starship.enable = true;
starship.enableZsh = true;
tmux.enable = true;
tmux.shell = "\${pkgs.zsh}/bin/zsh";
wezterm.enable = true;
wezterm.integration.zsh = true;
wezterm.fontSize = 10;
wezterm.defaultProg = [
"zsh"
"--login"
];
zsh.enable = true;
zsh.extraConfig.init = ''
export GPG_TTY=$(tty)
alias tmux="tmux -f ${config.xdg.configHome}/tmux/tmux.conf"
alias nvim="${pkgs.steam-run}/bin/steam-run nvim"
'';
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
};
};
}

View File

@@ -1,137 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.wm;
wm-boot = pkgs.writeShellScriptBin "wm-boot" ''
eww="${pkgs.eww-wayland}/bin/eww"
swww="${pkgs.swww}/bin/swww"
if [[ "$($eww ping)" -ne "pong" ]]; then
$eww daemon
fi
$eww close-all
$eww open bar
$eww open bar-2
$eww reload
$swww init
'';
wm-update = pkgs.writeShellScriptBin "wm-update" ''
eww="${pkgs.eww-wayland}/bin/eww"
swww="${pkgs.swww}/bin/swww"
$eww reload
$swww img "${builtins.toPath cfg.wallpaper}"
'';
in {
imports = [
../../modules/home-manager/programs/hyprland.nix
../../modules/home-manager/programs/eww
];
options.wm = with lib;
with lib.types; {
wallpaper = mkOption {
default = ../../static/guz-wallpaper-default.png;
type = path;
};
};
config = {
eww.enable = true;
hyprland.enable = true;
hyprland.exec = [
"${wm-boot}/bin/wm-boot"
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
];
home.activation = {
wm-update = "${wm-update}/bin/wm-update";
};
hyprland.monitors = [
{
name = "monitor1";
resolution = "2560x1080";
id = "HDMI-A-1";
}
{
name = "monitor2";
resolution = "1920x1080";
id = "DVI-D-1";
offset = "2560x0";
}
];
hyprland.windowRules = {
"class:^(org.inkscape.Inkscape)$" = ["float"];
"class:^(org.inkscape.Inkscape)$,title:(.*)(- Inkscape)$" = ["tile"];
};
hyprland.workspaces = [
# First monitor
{
name = "1";
monitor = "$monitor1";
default = true;
}
{
name = "2";
monitor = "$monitor1";
}
{
name = "3";
monitor = "$monitor1";
}
{
name = "4";
monitor = "$monitor1";
}
{
name = "5";
monitor = "$monitor1";
}
# Second monitor
{
name = "6";
monitor = "$monitor2";
}
{
name = "7";
monitor = "$monitor2";
}
{
name = "8";
monitor = "$monitor2";
}
{
name = "9";
monitor = "$monitor2";
}
{
name = "10";
monitor = "$monitor2";
default = true;
}
];
xdg.desktopEntries = {
librewolf = {
name = "Librewolf";
genericName = "Web Browser";
exec = "${pkgs.librewolf}/bin/librewolf %U";
terminal = false;
categories = ["Application" "Network" "WebBrowser"];
mimeType = ["text/html" "text/xml"];
};
davinci = {
name = "Davinci Resolve";
genericName = "Video Editor";
exec = "${pkgs.davinci-resolve}/bin/davinci-resolve %U";
terminal = false;
categories = ["Application" "Video"];
};
};
};
}

View File

@@ -1,15 +0,0 @@
{pkgs, ...}: {
imports = [
../shared-configuration.nix
];
options.work.configuration = {};
config = {
set-user.users = [
{
username = "guz";
shell = pkgs.zsh;
home = import ./home.nix;
}
];
};
}

View File

@@ -1,30 +0,0 @@
{inputs, ...}: {
imports = [
../shared-home.nix
];
options.work.home = {};
config = {
theme.accent = "94e2d5";
wm.wallpaper = ../../../static/guz-wallpaper-work.png;
librewolf.profiles.work = {
isDefault = true;
id = 1;
settings = {
"webgl.disabled" = false;
"browser.startup.homepage" = "https://github.com";
"privacy.clearOnShutdown.history" = false;
"privacy.clearOnShutdown.downloads" = false;
"extensions.activeThemeID" = "firefox-compact-dark@mozilla.org";
"privacy.clearOnShutdown.cookies" = false;
};
extensions = with inputs.firefox-addons.packages."x86_64-linux"; [
darkreader
canvasblocker
smart-referer
github-file-icons
libredirect
tridactyl
];
};
};
}

View File

@@ -154,7 +154,7 @@ in {
};
zsh.enable = true;
zsh.enableAutosuggestions = true;
zsh.autosuggestion.enable = true;
zsh.enableCompletion = true;
zsh.initExtra = ''
export GPG_TTY=$(tty)

View File

@@ -1,19 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.davinci;
in {
imports = [];
options.davinci = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
davinci-resolve
];
};
}

View File

@@ -1,333 +0,0 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
cfg = config.hyprland;
in {
imports = [];
options.hyprland = with lib;
with lib.types; {
enable = mkEnableOption "";
monitors = mkOption {
default = [];
/*
type = listOf (submodule ({ ... }: {
options = {
id = mkOption {
type = str;
};
name = mkOption {
type = str;
};
resolution = mkOption {
type = str;
};
hz = mkOption {
type = nullOr int;
default = null;
};
offset = mkOption {
type = nullOr str;
default = null;
};
scale = mkOption {
type = nullOr int;
default = null;
};
};
}));
*/
};
exec = mkOption {
default = [];
type = listOf str;
};
env = mkOption {
default = {};
type = attrsOf str;
};
windowRules = mkOption {
default = {};
description = "window = [ \"rule\" ]";
type = attrsOf (listOf str);
};
input = {
keyboard.layout = mkOption {
default = "br";
type = str;
};
keyboard.variant = mkOption {
default = "abnt2";
type = str;
};
mouse.follow = mkOption {
default = true;
type = bool;
};
mouse.sensitivity = mkOption {
default = 0;
type = number;
};
};
general = {
gaps_in = mkOption {
default = 5;
type = number;
};
gaps_out = mkOption {
default = 10;
type = number;
};
border.size = mkOption {
default = 0;
type = number;
};
border.color.active = mkOption {
default = "rgba(ffffff99) rgba(ffffff33) 90deg";
type = str;
};
border.color.inactive = mkOption {
default = "rgba(18181800)";
type = str;
};
layout = mkOption {
default = "dwindle";
type = str;
};
};
decoration = {
rouding = mkOption {
default = 5;
type = number;
};
dim.inactive = mkOption {
default = true;
type = bool;
};
dim.strength = mkOption {
default = 0.2;
type = number;
};
dim.around = mkOption {
default = 0.4;
type = number;
};
};
animations = {
enabled = mkOption {
default = true;
type = bool;
};
};
workspaces = mkOption {
default = [];
/*
type = {
name = str;
monitor = nullOr str;
default = nullOr bool;
extraRules = nullOr str;
};
*/
};
binds = {
mod = mkOption {
default = "SUPER";
type = str;
};
keyboard = mkOption {
default = [];
type = listOf str;
};
mouse = mkOption {
default = [];
type = listOf str;
};
};
};
config = lib.mkIf cfg.enable {
wayland.windowManager.hyprland.enable = true;
wayland.windowManager.hyprland.package = inputs.hyprland.packages."${pkgs.system}".hyprland;
wayland.windowManager.hyprland.xwayland.enable = true;
wayland.windowManager.hyprland.systemd.enable = true;
wayland.windowManager.hyprland.settings = lib.mkMerge [
# Sets monitor variables ("$name" = "id") so it can be used in rules later
(
builtins.listToAttrs (map
(m: {
name = "\$${m.name}";
value = "${m.id}";
})
cfg.monitors)
)
{
# Construct the "name,resolution@hz,offset,scale" strings
monitor = (
map
(
m: "${m.name},${m.resolution}@${
toString (
if m ? hz
then m.hz
else 60
)
},${
if m ? offset
then m.offset
else "0x0"
},${
toString (
if m ? scale
then m.scale
else 1
)
}"
)
cfg.monitors
);
exec-once = cfg.exec;
# "Hack" to transform attributes sets to lists (because I didn't know other way to do it)
# Transform { "envName" = "value" } to [ "envName,value" ]
env =
builtins.attrValues
(builtins.mapAttrs (n: v: "${n},${v}") (lib.attrsets.mergeAttrsList [
{
"XCURSOR_SIZE" = "24";
"MOZ_ENABLE_WAYLAND" = "1";
}
cfg.env
]));
windowrulev2 = let
firefoxPipRules = [
"float"
# "nofullscreenrequest"
"size 480 270"
"fakefullscreen"
"nodim"
"noblur"
];
in
builtins.concatLists
(builtins.attrValues (
builtins.mapAttrs
(
w: rs: (map (r: "${r},${w}") rs)
)
(lib.attrsets.mergeAttrsList [
{
"title:^(Picture-in-Picture)$,class:^(firefox)$" = firefoxPipRules;
"title:^(Firefox)$,class:^(firefox)$" = firefoxPipRules;
"title:^(Picture-in-Picture)$" = firefoxPipRules;
"class:^(xwaylandvideobridge)$" = [
"opacity 0.0 override 0.0 override"
"noanim"
"nofocus"
"noinitialfocus"
];
}
cfg.windowRules
])
));
input = {
kb_layout = cfg.input.keyboard.layout;
kb_variant = cfg.input.keyboard.variant;
follow_mouse =
if cfg.input.mouse.follow
then "1"
else "0";
sensitivity = toString cfg.input.mouse.sensitivity;
};
general = {
gaps_in = toString cfg.general.gaps_in;
gaps_out = toString cfg.general.gaps_out;
border_size = toString cfg.general.border.size;
"col.active_border" = toString cfg.general.border.color.active;
"col.inactive_border" = toString cfg.general.border.color.inactive;
layout = cfg.general.layout;
};
decoration = {
rounding = toString cfg.decoration.rouding;
dim_inactive =
if cfg.decoration.dim.inactive
then "true"
else "false";
dim_strength = toString cfg.decoration.dim.strength;
dim_around = toString cfg.decoration.dim.around;
blur = {
enabled = "false";
size = "20";
};
};
animations = {
enabled =
if cfg.animations.enabled
then "yes"
else "no";
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
animation = [
"windows, 1, 7, myBezier"
"windowsOut, 1, 7, default, popin 80%"
"border, 1, 10, default"
"borderangle, 1, 8, default"
"fade, 1, 7, default"
"workspaces, 1, 6, default"
];
};
dwindle = {
pseudotile = "yes";
preserve_split = "yes";
};
master = {
new_is_master = "true";
};
gestures = {
workspace_swipe = "off";
};
workspace = (
map
(w: "${w.name},${
if w ? monitor
then "monitor:${w.monitor},"
else ""
}${
if w ? default && w.default
then "default:true,"
else ""
}${
if w ? extraRules
then "${w.extraRules}"
else ""
}")
cfg.workspaces
);
"$mod" = cfg.binds.mod;
bind = cfg.binds.keyboard;
bindm = cfg.binds.mouse;
}
];
};
}

View File

@@ -1,20 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.krita;
in {
imports = [];
options.krita = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [krita];
home.file."${config.xdg.configHome}/kritarc".source = ./kritarc;
home.file."${config.xdg.configHome}/kritashortcutsrc".source = ./kritashortcutsrc;
};
}

View File

@@ -1,94 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.lf;
in {
imports = [];
options.lf = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = lib.mkIf cfg.enable {
programs.lf = {
enable = true;
settings = {
preview = true;
hidden = true;
drawbox = true;
icons = true;
ignorecase = true;
};
commands = {
delete-trash = '' ''${{
touch "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo"
echo "[Trash Info]" > "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo"
echo "Path=$f" >> "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo"
echo "DeletionDate=$(date +%Y-%m-%dT%H:%M:%S)" >> "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo"
mv $f ${config.xdg.dataHome}/Trash/files
}}'';
dragon-out = ''%${pkgs.xdragon}/bin/xdragon -a -x "$fx"'';
editor-open = ''$$EDITOR $f'';
mkfile = '' ''${{
printf "Dirname: "
read DIR
if [[ $DIR = */ ]]; then
mkdir $DIR
else
touch $DIR
fi
}}'';
mkdir = '' ''${{
printf "Dirname: "
read DIR
mkdir $DIR
}}'';
trash = ''cd ${config.xdg.dataHome}/Trash/files'';
trash-recover = '' ''${{
mv $f "$(cat "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo" | sed -n '2 p' | tr "=" "\n" | sed -n '2 p')"
rm -rf "${config.xdg.dataHome}/Trash/info/$(basename $f).trashinfo"
}}'';
};
keybindings = {
"." = "set hidden!";
"<enter>" = "open";
a = "mkfile";
A = "mkdir";
D = "delete";
R = "trash-recover";
ee = "editor-open";
};
extraConfig = let
previewer = pkgs.writeShellScriptBin "pv.sh" ''
file=$1
w=$2
h=$3
x=$4
y=$5
if [[ "$(${pkgs.file}/bin/file -Lb --mime-type "$file")" =~ ^image ]]; then
${pkgs.kitty}/bin/kitty +kitten icat --silent --stdin no --transfer-mode file --place "''${w}x''${h}@''${x}x''${y}" "$file" < /dev/null > /dev/tty
exit 1
fi
${pkgs.pistol}/bin/pistol "$file"
'';
cleaner = pkgs.writeShellScriptBin "clean.sh" ''
${pkgs.kitty}/bin/kitty +kitten icat --clear --stdin no --silent --transfer-mode file < /dev/null > /dev/tty
'';
in ''
set cleaner ${cleaner}/bin/clean.sh
set previewer ${previewer}/bin/pv.sh
'';
};
};
}

View File

@@ -1,23 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.obs;
in {
imports = [];
options.obs = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
obs-studio
obs-cli
obs-studio-plugins.wlrobs
obs-studio-plugins.obs-pipewire-audio-capture
obs-studio-plugins.obs-vkcapture
];
};
}

View File

@@ -1,49 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.obsidian;
vaultCmd = pkgs.writeShellScriptBin "vault" ''
command="$1";
if [[ "$command" == "sync" ]]; then
git="${pkgs.git}/bin/git";
date="$(date +%F) $(date +%R)"
cd ${cfg.vaultDir}
$git pull
if [[ "$(echo "$($git diff --shortstat)" | awk '{print $1}')" -ne "" ]]; then
$git commit -m "vault backup: $date" -a
fi
$git push
fi
'';
in {
imports = [];
options.obsidian = with lib;
with lib.types; {
enable = mkEnableOption "";
vaultCmd = mkOption {
type = bool;
default = false;
};
vaultDir = mkOption {
type = str;
default = "${config.home.homeDirectory}/.vault";
};
};
config = lib.mkIf cfg.enable {
services.flatpak.packages = [
"md.obsidian.Obsidian"
];
home.packages = [
(
if cfg.vaultCmd
then vaultCmd
else null
)
];
};
}

View File

@@ -1,21 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.starship;
in {
imports = [];
options.starship = with lib;
with lib.types; {
enable = mkEnableOption "Enable module";
enableZsh = mkEnableOption "Enable Zsh Integration";
enableBash = mkEnableOption "Enable Bash Integration";
};
config = lib.mkIf cfg.enable {
programs.starship.enable = true;
programs.starship.enableZshIntegration = lib.mkIf cfg.enableZsh true;
programs.starship.enableBashIntegration = lib.mkIf cfg.enableBash true;
};
}

View File

@@ -1,85 +0,0 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
cfg = config.tmux;
in {
imports = [];
options.tmux = with lib;
with lib.types; {
enable = mkEnableOption "Enable Tmux module";
baseIndex = mkOption {
type = ints.unsigned;
default = 1;
};
prefix = mkOption {
type = str;
default = "C-Space";
};
shell = mkOption {
type = str;
default = "\${pkgs.bash}/bin/bash";
};
};
config = lib.mkIf cfg.enable {
programs.tmux.enable = true;
programs.tmux.baseIndex = cfg.baseIndex;
programs.tmux.keyMode = "vi";
programs.tmux.mouse = true;
programs.tmux.terminal = "screen-256color";
programs.tmux.prefix = cfg.prefix;
# TODO: package tmux plugins so tpm is not necessary
home.file."${config.xdg.configHome}/tmux/plugins/tpm" = {
source = inputs.tmux-plugin-manager;
};
home.packages = with pkgs; [
entr # b0o/tmux-autoreload depends on it
];
programs.tmux.extraConfig = ''
set -g @plugin 'b0o/tmux-autoreload'
set -g @plugin 'aserowy/tmux.nvim'
set -g @plugin 'guz013/frappuccino-tmux'
set -g @plugin 'pschmitt/tmux-ssh-split'
set -sg terminal-overrides ",*:RGB"
set -g renumber-windows on
bind -T prefix / split-window -v -c "#''''{pane_current_path}"
bind -T prefix \\ split-window -h -c "#''''{pane_current_path}"
set -g @catppuccin_window_left_separator ""
set -g @catppuccin_window_right_separator " "
set -g @catppuccin_window_middle_separator " "
set -g @catppuccin_window_number_position "right"
set -g @catppuccin_window_default_fill "number"
set -g @catppuccin_window_default_text "#W"
set -g @catppuccin_window_current_fill "number"
set -g @catppuccin_window_current_text "#W"
set -g @catppuccin_status_modules_right "application directory session"
set -g @catppuccin_status_left_separator " "
set -g @catppuccin_status_right_separator ""
set -g @catppuccin_status_right_separator_inverse "no"
set -g @catppuccin_status_fill "icon"
set -g @catppuccin_status_connect_separator "no"
set -g @catppuccin_directory_text "#{pane_current_path}"
run '${config.xdg.configHome}/tmux/plugins/tpm/tpm'
'';
};
}

View File

@@ -1,84 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.wezterm;
in {
imports = [];
options.wezterm = with lib;
with lib.types; {
enable = mkEnableOption "Enable Wezterm";
integration = {
zsh = mkEnableOption "Enable Zsh Integration";
};
colorScheme = mkOption {
type = str;
default = "system";
};
defaultProg = mkOption {
default = [];
};
font = mkOption {
default = "Fira Code";
type = str;
};
fontSize = mkOption {
default = 12;
type = number;
};
};
config = lib.mkIf cfg.enable {
programs.wezterm.enable = true;
programs.wezterm.enableZshIntegration = lib.mkIf (cfg.integration.zsh) true;
programs.wezterm.extraConfig = ''
return {
enable_tab_bar = false;
color_scheme = "${cfg.colorScheme}",
default_prog = { ${lib.concatMapStrings (x: "'" + x + "',") cfg.defaultProg} },
font = wezterm.font("${cfg.font}"),
font_size = ${toString cfg.fontSize},
enable_wayland = false, -- TEMPORALLY FIX (see wez/wezterm#4483)
}
'';
programs.wezterm.colorSchemes = {
system = with config.colorScheme.palette; {
foreground = "#${base05}";
background = "#${base00}";
cursor_fg = "#${base01}";
cursor_bg = "#${config.theme.accent}";
cursor_border = "#${config.theme.accent}";
selection_fg = "#${base04}";
selection_bg = "#${config.theme.accent}";
split = "#${base04}";
ansi = [
"#${base03}"
"#${base08}"
"#${base0B}"
"#${base0A}"
"#${base0D}"
"#${base0E}"
"#${base0C}"
"#${base03}"
];
brights = [
"#${base03}"
"#${base08}"
"#${base0B}"
"#${base0A}"
"#${base0D}"
"#${base0E}"
"#${base0C}"
"#${base03}"
];
};
};
};
}

View File

@@ -1,67 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.zsh;
in {
imports = [];
options.zsh = with lib;
with lib.types; {
enable = mkEnableOption "Enable Zsh shell";
plugins = {
suggestions.enable = mkOption {
type = bool;
default = true;
};
completion.enable = mkOption {
type = bool;
default = true;
};
};
extraConfig = {
init = mkOption {
type = lines;
default = "";
};
beforeComp = mkOption {
type = lines;
default = "";
};
first = mkOption {
type = lines;
default = "";
};
};
loginExtra = mkOption {
type = lines;
default = "";
};
logoutExtra = mkOption {
type = lines;
default = "";
};
variables = mkOption {
type = attrsOf str;
default = {};
};
};
config = lib.mkIf cfg.enable {
programs.zsh = {
enable = true;
oh-my-zsh.enable = true;
loginExtra = cfg.loginExtra;
logoutExtra = cfg.logoutExtra;
initExtra = cfg.extraConfig.init;
initExtraBeforeCompInit = cfg.extraConfig.beforeComp;
initExtraFirst = cfg.extraConfig.first;
localVariables = cfg.variables;
enableAutosuggestions = lib.mkIf (cfg.plugins.suggestions.enable) true;
enableCompletion = lib.mkIf (cfg.plugins.completion.enable) true;
};
};
}

View File

@@ -1,6 +1,9 @@
{...}: {
imports = [
./hyprland.nix
./krita
./neovim.nix
./obsidian
./wezterm.nix
];
options = {};

View File

@@ -0,0 +1,38 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
cfg = config.programs.hyprland;
hyprconfValueType = with lib.types;
nullOr (oneOf [
bool
int
float
str
path
(attrsOf hyprconfValueType)
(listOf hyprconfValueType)
]);
in {
imports = [];
options.programs.hyprland = with lib;
with lib.types; {
enable = mkEnableOption "";
settings = mkOption {
type = attrsOf hyprconfValueType;
default = {};
};
};
config = with lib;
mkIf cfg.enable {
wayland.windowManager.hyprland.enable = true;
wayland.windowManager.hyprland.package = inputs.hyprland.packages."${pkgs.system}".hyprland;
wayland.windowManager.hyprland.xwayland.enable = true;
wayland.windowManager.hyprland.systemd.enable = true;
wayland.windowManager.hyprland.settings = cfg.settings;
};
}

View File

@@ -0,0 +1,21 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.krita;
in {
imports = [];
options.programs.krita = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = with lib;
mkIf cfg.enable {
home.packages = with pkgs; [krita];
home.file."${config.xdg.configHome}/kritarc".source = ./kritarc;
home.file."${config.xdg.configHome}/kritashortcutsrc".source = ./kritashortcutsrc;
};
}

View File

@@ -0,0 +1 @@
{...}: {}

View File

@@ -0,0 +1,42 @@
{
config,
pkgs,
lib,
...
}: let
cfg = config.programs.obsidian;
vaultCmd = pkgs.writeShellScriptBin "vault" ''
function awk() { ${pkgs.gawk}/bin/awk "$@"; }
function git() { ${pkgs.git}/bin/git "$@"; }
function gum() { ${pkgs.gum}/bin/gum "$@"; }
${builtins.readFile ./vault.sh}
'';
in {
imports = [];
options.programs.obsidian = with lib;
with lib.types; {
enable = mkEnableOption "";
vaultCmd = mkOption {
type = bool;
default = false;
};
vaultDir = mkOption {
type = str;
default = "${config.home.homeDirectory}/.vault";
};
};
config = with lib;
mkIf cfg.enable {
services.flatpak.packages = mkIf cfg.flatpak [
"md.obsidian.Obsidian"
];
home.packages = [
(
if cfg.vaultCmd
then vaultCmd
else null
)
];
};
}

View File

@@ -0,0 +1,41 @@
function vault-sync() {
local vault_dir="$1"
date="$(date +%F) $(date +%R)"
set -e
pushd $vault_dir
gum log --structured --prefix 'vault sync' --level info "Syncing vault through git"
gum log --structured --prefix 'vault sync' --level debug "Pulling from remote"
git pull
# Skip if there's no changes
if git diff --quiet "*.*"; then
gum log --structured \
--prefix 'vault sync' \
--level warn \
'No files changed'
popd
exit 0
else
gum log --structured --prefix 'vault sync' --level debug 'Committing' commit_msg "vault sync: $date"
git commit -am "vault sync: $date"
gum log --structured --prefix 'vault sync' --level debug 'Pushing to remote'
git push
gum log --structured --prefix 'vault sync' --level info 'Vault synced!'
fi
popd
}
case "$1" in
"sync") vault-sync $vault_dir ;;
*) gum log --structured --prefix 'vault' --level error "Command $1 does not exist" ;;
esac

View File

@@ -1,50 +0,0 @@
{
config,
lib,
inputs,
pkgs,
...
}: let
cfg = config.theme;
in {
imports = [
inputs.nix-colors.homeManagerModules.default
];
options.theme = with lib;
with lib.types; {
accent = mkOption {
type = str;
default = "cdd6f4";
description = "The accent color of Frappuccino";
};
accentBase = mkOption {
type = str;
default = "magenta";
description = "The base name for the accent color to be used in the terminal";
};
scheme = mkOption {
type = path;
default = ../../themes/frappuccino.yaml;
};
};
config = {
colorScheme = inputs.nix-colors.lib.schemeFromYAML "frappuccino" (builtins.readFile cfg.scheme);
home.packages = with pkgs; [
gnome.gnome-themes-extra
];
gtk = {
enable = true;
theme = {
name = "Catppuccin-Mocha-Compact-Mauve-Dark";
package = pkgs.catppuccin-gtk.override {
size = "compact";
tweaks = ["rimless" "black"];
accents = ["mauve"];
variant = "mocha";
};
};
};
};
}

View File

@@ -1,74 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.nih;
in {
imports = [
./domains
./networking
./services
./sound.nix
./users.nix
];
options.nih = with lib;
with lib.types; {
domain = mkOption {
type = str;
default = "${cfg.name}.local";
};
enable = mkEnableOption "";
flakeDir = mkOption {
type = either str path;
};
ip = mkOption {
type = str;
};
localIp = mkOption {
type = str;
default = cfg.ip;
};
name = mkOption {
type = str;
default = "nih";
};
type = mkOption {
type = enum ["laptop" "desktop" "server"];
default = "desktop";
};
_nih = mkOption {
type = attrsOf anything;
default = with builtins; {
servicesNamesList = readDir ./services;
};
};
};
config = with lib;
mkIf cfg.enable {
boot = {
loader.systemd-boot.enable = mkDefault true;
loader.efi.canTouchEfiVariables = mkDefault true;
};
systemd.services."nih-setup" = with builtins; {
script = ''
echo ${builtins.toJSON cfg._nih.servicesNamesList}
'';
wantedBy = ["multi-user.target"];
after = ["forgejo.service"];
serviceConfig = {
Type = "oneshot";
};
};
# Handle domains configuration
services.openssh.enable = mkDefault (
if cfg.type == "server"
then true
else false
);
};
}

View File

@@ -1,32 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.nih.domains;
in {
imports = [
./tailscale.nix
./tailscale-caddy.nix
];
options.nih.domains = with lib;
with lib.types; {
enable = mkOption {
type = bool;
default = false;
};
domain = mkOption {
type = str;
default = "${config.nih.name}.local";
};
handler = mkOption {
type = enum ["tailscale" "tailscale-caddy" "adguard" "adguard-caddy"];
default = "tailscale";
};
};
config = with lib;
mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [80 433];
};
}

View File

@@ -1,50 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
with builtins; let
tailnetName = config.services.tailscale.tailnetName;
ip = config.nih.ip;
domain = config.nih.domains.domain;
listHas = item: list: (lib.lists.count (x: x == item) list) > 0;
servicesList = filterAttrs (n: v: (listHas n ["adguardhome" "caddy" "tailscale"])) config.services;
servicesWithDomain = filterAttrs (n: v: isAttrs v && v ? nihDomain && v ? nihPort) servicesList;
in {
imports = [];
config = with lib;
mkIf (config.nih.domains.enable && config.nih.domains.handler == "tailscale-caddy") {
services.tailscale = {
enable = mkForce true;
useRoutingFeatures = mkForce "both";
};
services.adguardhome = {
enable = mkForce true;
dns.rewrites = {
"*.homelab.local" = "192.168.1.10";
"homelab.local" = "192.168.1.10";
};
};
services.caddy = {
enable = mkForce true;
virtualHosts."homelab.kiko-liberty.ts.net" = {
extraConfig = ''
reverse_proxy 192.168.1.10:4040
'';
};
/*
virtualHosts = mapAttrs'
(n: v: nameValuePair (v.nihDomain) ({
extraConfig = ''
reverse_proxy 100.66.139.89:${toString v.nihPort}
'';
}))
servicesWithDomain;
*/
};
};
}

View File

@@ -1,24 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.nih.domains.handlers.tailscale;
in {
imports = [];
options.nih.domains.handlers.tailscale = with lib;
with lib.types; {
enable = mkOption {
type = bool;
default = config.nih.domains.enable && config.nih.domains.handler == "tailscale";
};
};
config = with lib;
mkIf cfg.enable {
services.tailscale = {
enable = mkDefault true;
useRoutingFeatures = mkDefault "server";
};
};
}

View File

@@ -1,73 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.nih.networking;
in {
options.nih.networking = with lib;
with lib.types; {
defaultGateway = mkOption {
type = str;
default = "192.168.1.1";
};
hostName = mkOption {
type = str;
default = config.nih.name;
};
interface = mkOption {
type = nullOr str;
default = null;
};
localIp = mkOption {
type = str;
default = config.nih.localIp;
};
nameservers = mkOption {
type = listOf str;
default = ["1.1.1.1" "8.8.8.8"];
};
networkmanager = mkOption {
type = bool;
default = true;
};
portForwarding = mkOption {
type = bool;
default = false;
};
wireless = mkOption {
type = bool;
default =
if config.nih.type == "laptop"
then true
else false;
};
};
config = with lib; {
boot.kernel.sysctl."net.ipv4.ip_forward" =
if cfg.portForwarding
then 1
else 0;
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" =
if cfg.portForwarding
then 1
else 0;
networking = {
hostName = cfg.hostName;
defaultGateway = cfg.defaultGateway;
dhcpcd.enable = true;
interfaces = mkIf (cfg.interface != null) {
"${cfg.interface}".ipv4.addresses = [
{
address = cfg.localIp;
prefixLength = 28;
}
];
};
nameservers = cfg.nameservers;
networkmanager.enable = cfg.networkmanager;
wireless.enable = cfg.wireless;
};
};
}

View File

@@ -1,20 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs;
in {
imports = [
./direnv.nix
./hyprland.nix
./lf.nix
./starship.nix
./tmux.nix
./wezterm.nix
./zsh.nix
];
options.programs = {};
config = {};
}

View File

@@ -1,22 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.direnv;
in {
imports = [];
options.programs.direnv = with lib; with lib.types; {};
config = with lib;
mkIf cfg.enable {
programs.direnv = {
enableBashIntegration = mkDefault config.programs.bash.enable;
enableFishIntegration = mkDefault config.programs.fish.enable;
enableNushellIntegration = mkDefault config.programs.nushell.enable;
enableZshIntegration = mkDefault config.programs.zsh.enable;
nix-direnv.enable = true;
};
};
}

View File

@@ -1,323 +0,0 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
cfg = config.programs.hyprland;
in {
imports = [];
options.programs.hyprland = with lib;
with lib.types; {
enable = mkEnableOption "";
monitors = mkOption {
default = [];
type = listOf (submodule ({...}: {
options = {
id = mkOption {
type = str;
};
name = mkOption {
type = str;
};
resolution = mkOption {
type = str;
};
hz = mkOption {
type = int;
default = 60;
};
offset = mkOption {
type = str;
default = "0x0";
};
scale = mkOption {
type = int;
default = 1;
};
};
}));
};
exec = mkOption {
default = [];
type = listOf str;
};
env = mkOption {
default = {};
type = attrsOf str;
};
windowRules = mkOption {
default = {};
description = "window = [ \"rule\" ]";
type = attrsOf (listOf str);
};
input = {
keyboard.layout = mkOption {
default = "br";
type = str;
};
keyboard.variant = mkOption {
default = "abnt2";
type = str;
};
mouse.follow = mkOption {
default = true;
type = bool;
};
mouse.sensitivity = mkOption {
default = 0;
type = number;
};
};
general = {
gaps_in = mkOption {
default = 5;
type = number;
};
gaps_out = mkOption {
default = 10;
type = number;
};
border.size = mkOption {
default = 0;
type = number;
};
border.color.active = mkOption {
default = "rgba(ffffff99) rgba(ffffff33) 90deg";
type = str;
};
border.color.inactive = mkOption {
default = "rgba(18181800)";
type = str;
};
layout = mkOption {
default = "dwindle";
type = str;
};
};
decoration = {
rouding = mkOption {
default = 5;
type = number;
};
dim.inactive = mkOption {
default = true;
type = bool;
};
dim.strength = mkOption {
default = 0.2;
type = number;
};
dim.around = mkOption {
default = 0.4;
type = number;
};
};
animations = {
enabled = mkOption {
default = true;
type = bool;
};
};
workspaces = mkOption {
default = [];
type =
listOf
(submodule ({...}: {
options = {
name = mkOption {
type = str;
};
monitor = mkOption {
type = nullOr str;
default = null;
};
default = mkOption {
type = bool;
default = false;
};
extraRules = mkOption {
type = str;
default = "";
};
};
}));
};
binds = {
mod = mkOption {
default = "SUPER";
type = str;
};
keyboard = mkOption {
default = [];
type = listOf str;
};
mouse = mkOption {
default = [];
type = listOf str;
};
};
};
config = lib.mkIf cfg.enable {
wayland.windowManager.hyprland.enable = true;
wayland.windowManager.hyprland.package = inputs.hyprland.packages."${pkgs.system}".hyprland;
wayland.windowManager.hyprland.xwayland.enable = true;
wayland.windowManager.hyprland.systemd.enable = true;
wayland.windowManager.hyprland.settings = lib.mkMerge [
# Sets monitor variables ("$name" = "id") so it can be used in rules later
(
builtins.listToAttrs (map
(m: {
name = "\$${m.name}";
value = "${m.id}";
})
cfg.monitors)
)
{
# Construct the "name,resolution@hz,offset,scale" strings
monitor = (
map
(m: "${m.name},${m.resolution}@${toString m.hz},${m.offset},${toString m.scale}")
cfg.monitors
);
exec-once = cfg.exec;
# "Hack" to transform attributes sets to lists (because I didn't know other way to do it)
# Transform { "envName" = "value" } to [ "envName,value" ]
env =
builtins.attrValues
(builtins.mapAttrs (n: v: "${n},${v}") (lib.attrsets.mergeAttrsList [
{
"XCURSOR_SIZE" = "24";
"MOZ_ENABLE_WAYLAND" = "1";
}
cfg.env
]));
windowrulev2 = let
firefoxPipRules = [
"float"
# "nofullscreenrequest"
"size 480 270"
"fakefullscreen"
"nodim"
"noblur"
];
in
builtins.concatLists
(builtins.attrValues (
builtins.mapAttrs
(
w: rs: (map (r: "${r},${w}") rs)
)
(lib.attrsets.mergeAttrsList [
{
"title:^(Picture-in-Picture)$,class:^(firefox)$" = firefoxPipRules;
"title:^(Firefox)$,class:^(firefox)$" = firefoxPipRules;
"title:^(Picture-in-Picture)$" = firefoxPipRules;
"class:^(xwaylandvideobridge)$" = [
"opacity 0.0 override 0.0 override"
"noanim"
"nofocus"
"noinitialfocus"
];
}
cfg.windowRules
])
));
input = {
kb_layout = cfg.input.keyboard.layout;
kb_variant = cfg.input.keyboard.variant;
follow_mouse =
if cfg.input.mouse.follow
then "1"
else "0";
sensitivity = toString cfg.input.mouse.sensitivity;
};
general = {
gaps_in = toString cfg.general.gaps_in;
gaps_out = toString cfg.general.gaps_out;
border_size = toString cfg.general.border.size;
"col.active_border" = toString cfg.general.border.color.active;
"col.inactive_border" = toString cfg.general.border.color.inactive;
layout = cfg.general.layout;
};
decoration = {
rounding = toString cfg.decoration.rouding;
dim_inactive =
if cfg.decoration.dim.inactive
then "true"
else "false";
dim_strength = toString cfg.decoration.dim.strength;
dim_around = toString cfg.decoration.dim.around;
blur = {
enabled = "false";
size = "20";
};
};
animations = {
enabled =
if cfg.animations.enabled
then "yes"
else "no";
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
animation = [
"windows, 1, 7, myBezier"
"windowsOut, 1, 7, default, popin 80%"
"border, 1, 10, default"
"borderangle, 1, 8, default"
"fade, 1, 7, default"
"workspaces, 1, 6, default"
];
};
dwindle = {
pseudotile = "yes";
preserve_split = "yes";
};
master = {
new_is_master = "true";
};
gestures = {
workspace_swipe = "off";
};
workspace = (
map
(w: "${w.name},${
if w.monitor != null
then "monitor:${w.monitor},"
else ""
}${
if w.default
then "default:true,"
else ""
}${w.extraRules} ")
cfg.workspaces
);
"$
mod " = cfg.binds.mod;
bind = cfg.binds.keyboard;
bindm = cfg.binds.mouse;
}
];
};
}

View File

@@ -1,86 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.lf;
in {
imports = [];
options.programs.lf = with lib;
with lib.types; {
cmds = {
mkfile = mkOption {
type = bool;
default = true;
};
editor-open = mkOption {
type = bool;
default = true;
};
dragon-out = mkOption {
type = bool;
default = true;
};
};
extraCfg = mkOption {
type = lines;
default = "";
};
filePreviewer = mkOption {
type = bool;
default = true;
};
};
config = with lib;
mkIf cfg.enable {
programs.lf = {
commands = {
dragon-out = mkIf cfg.cmds.dragon-out ''%${pkgs.xdragon}/bin/xdragon -a -x "$fx"'';
editor-open = mkIf cfg.cmds.editor-open ''$$EDITOR $f'';
mkfile = mkIf cfg.cmds.mkfile '' ''${{
printf "Dirname: "
read DIR
if [[ $DIR = */ ]]; then
mkdir $DIR
else
touch $DIR
fi
}}'';
};
extraConfig = let
previewer = pkgs.writeShellScriptBin "pv.sh" ''
file=$1
w=$2
h=$3
x=$4
y=$5
if [[ "$(${pkgs.file}/bin/file -Lb --mime-type "$file")" =~ ^image ]]; then
${pkgs.kitty}/bin/kitty +kitten icat --silent --stdin no --transfer-mode file --place "''${w}x''${h}@''${x}x''${y}" "$file" < /dev/null > /dev/tty
exit 1
fi
${pkgs.pistol}/bin/pistol "$file"
'';
cleaner = pkgs.writeShellScriptBin "clean.sh" ''
${pkgs.kitty}/bin/kitty +kitten icat --clear --stdin no --silent --transfer-mode file < /dev/null > /dev/tty
'';
in
mkDefault ''
${
if cfg.filePreviewer
then ''
set cleaner ${cleaner}/bin/clean.sh
set previewer ${previewer}/bin/pv.sh
''
else ""
}
${cfg.extraCfg}
'';
};
};
}

View File

@@ -1,20 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.starship;
in {
imports = [];
options.programs.starship = with lib; with lib.types; {};
config = with lib;
mkIf cfg.enable {
programs.starship = {
enableFishIntegration = mkDefault config.programs.fish.enable;
enableIonIntegration = mkDefault config.programs.ion.enable;
enableNushellIntegration = mkDefault config.programs.nushell.enable;
enableZshIntegration = mkDefault config.programs.zsh.enable;
};
};
}

View File

@@ -1,12 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.tmux;
in {
imports = [];
options.programs.tmux = with lib; with lib.types; {};
config = with lib; mkIf cfg.enable {};
}

View File

@@ -1,78 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with builtins; let
cfg = config.programs.wezterm;
jsonFormat = pkgs.formats.json {};
toLua = with lib.strings;
v:
if isList v
then "{ ${concatMapStringsSep ", " (i: toLua i) v} }"
else if isAttrs v
then "\{ ${concatStringsSep ", " (attrValues (mapAttrs (n: a: "${n} = ${toLua a}") v))} \}"
else if isNull v
then "nil"
else if isBool v
then
if v
then "true"
else "false"
else if isInt v
then toString v
else if isString v && hasPrefix "lua " v
then "${substring 4 (stringLength v) v}"
else "\"${toString v}\"";
configInLua = pkgs.writeText "nih-wezterm-generated-config" ''
local wezterm = require("wezterm");
local nih_generated_config = {};
${concatStringsSep "\n" (attrValues (mapAttrs
(n: v: "nih_generated_config.${n} = ${toLua v};")
cfg.config))}
local function extra_config()
${cfg.extraConfig}
end
for k,v in pairs(extra_config()) do nih_generated_config[k] = v end
return nih_generated_config;
'';
prettyConfig = pkgs.runCommand "nih-wezterm-pretty-config" {config = configInLua;} ''
echo "Nih's Wezterm configuration file builder";
echo "input file: $config";
echo "output file: $out";
echo ""
echo "Formatting config file with Stylua"
cat $config | ${pkgs.stylua}/bin/stylua - > $out
echo ""
echo "Checking erros with luacheck"
${pkgs.luajitPackages.luacheck}/bin/luacheck \
--no-max-line-length \
--no-unused \
"$out";
'';
in {
imports = [];
options.programs.wezterm = with lib;
with lib.types; {
config = mkOption {
type = submodule ({...}: {
freeformType = jsonFormat.type;
});
default = {};
};
};
config = with lib;
mkIf cfg.enable {
programs.wezterm = {
enableBashIntegration = mkDefault config.programs.bash.enable;
enableZshIntegration = mkDefault config.programs.zsh.enable;
};
xdg.configFile."wezterm/wezterm.lua".source = prettyConfig;
};
}

View File

@@ -1,12 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.programs.zsh;
in {
imports = [];
options.programs.zsh = with lib; with lib.types; {};
config = with lib; mkIf cfg.enable {};
}

View File

@@ -1,75 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.services.adguardhome;
in {
imports = [];
options.services.adguardhome = with lib;
with lib.types; {
nihDomain = mkOption {
type = str;
default = "adguard.${config.nih.domains.domain}";
};
nihPort = mkOption {
type = port;
default = 3053;
};
dns.filters = mkOption {
type = attrsOf (submodule ({lib, ...}: {
options = {
name = mkOption {
type = nullOr str;
default = null;
};
url = mkOption {
type = str;
};
enabled = {
type = bool;
default = true;
};
};
}));
default = {};
};
dns.rewrites = mkOption {
type = attrsOf str;
default = {};
};
};
config = with lib;
mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [53];
allowedUDPPorts = [53 51820];
};
services.adguardhome = {
settings = {
bind_port = mkForce cfg.nihPort;
http = {
address = "${cfg.settings.bind_host}:${toString cfg.settings.bind_port}";
};
dns.rewrites = builtins.attrValues (builtins.mapAttrs
(from: to: {
domain = from;
answer = to;
})
cfg.dns.rewrites);
filters = attrValues (mapAttrs
(id: list: {
name =
if isNull list.name
then id
else list.name;
ID = id;
url = list.url;
enabled = list.enabled;
})
cfg.dns.filters);
};
};
};
}

View File

@@ -1,11 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.caddy;
in {
imports = [];
options.server.caddy = with lib; with lib.types; {};
config = lib.mkIf cfg.enable {};
}

View File

@@ -1,16 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.services;
in {
imports = [
./adguardhome.nix
./caddy.nix
./tailscale.nix
];
options.services = {};
config = {};
}

View File

@@ -1,54 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.services.tailscale;
in {
imports = [];
options.services.tailscale = with lib;
with lib.types; {
exitNode = mkOption {
type = bool;
default = false;
};
tailnetName = mkOption {
type = str;
};
};
config = with lib;
mkIf cfg.enable {
services.tailscale = {
extraUpFlags = [
(
if cfg.exitNode
then "--advertise-exit-node"
else null
)
(
if cfg.exitNode
then "--exit-node"
else null
)
];
useRoutingFeatures = mkDefault (
if config.nih.type == "server" || cfg.exitNode
then "server"
else "client"
);
};
networking.firewall.allowedTCPPorts = [80 433];
systemd.services."tailscaled" = mkIf config.services.caddy.enable {
serviceConfig = {
Environment = ["TS_PERMIT_CERT_UID=caddy"];
};
};
nih.networking = mkIf cfg.exitNode {
portForwarding = mkDefault true;
nameservers = ["100.100.100.100"];
};
};
}

View File

@@ -1,38 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.nih.sound;
in {
imports = [];
options.nih.sound = with lib;
with lib.types; {
enable = mkOption {
type = bool;
default = true;
};
pipewire.enable = mkOption {
type = bool;
default = true;
};
pulseaudio.enable = mkOption {
type = bool;
default = !cfg.pipewire.enable;
};
};
config = with lib;
mkIf cfg.enable {
sound.enable = true;
hardware.pulseaudio.enable = cfg.pulseaudio.enable;
security.rtkit.enable = true;
services.pipewire = mkIf cfg.pipewire.enable {
enable = true;
alsa.enable = mkDefault true;
alsa.support32Bit = mkDefault true;
pulse.enable = mkDefault true;
wireplumber.enable = mkDefault true;
};
};
}

View File

@@ -1,14 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.profiles;
in {
imports = [
./gterminal.nix
];
options.profiles = {};
config = {};
}

View File

@@ -1,123 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.profiles.gterminal;
in {
imports = [];
options.profiles.gterminal = with lib;
with lib.types; {
enable = mkEnableOption "";
};
config = with lib;
mkIf cfg.enable {
home.packages = with pkgs; [
neovim
gcc
wget
git
tmux
lazygit
nixpkgs-fmt
nixpkgs-lint
];
programs = {
direnv.enable = true;
lf.enable = true;
neovim.enable = true;
starship.enable = true;
tmux.baseIndex = 1;
tmux.enable = true;
tmux.extraConfig = ''
set -sg terminal-overrides ",*:RGB"
set -g renumber-windows on
bind -T prefix / split-window -v -c "#''''{pane_current_path}"
bind -T prefix \\ split-window -h -c "#''''{pane_current_path}"
'';
tmux.keyMode = "vi";
tmux.mouse = true;
tmux.prefix = "C-Space";
tmux.plugins = with pkgs; [
{
plugin = tmuxPlugins.catppuccin.overrideAttrs (_: {
src = fetchFromGitHub {
owner = "guz013";
repo = "frappuccino-tmux";
rev = "4255b0a769cc6f35e12595fe5a33273a247630aa";
sha256 = "0k8yprhx5cd8v1ddpcr0dkssspc17lq2a51qniwafkkzxi3kz3i5";
};
});
extraConfig = ''
set -g @catppuccin_window_left_separator ""
set -g @catppuccin_window_right_separator " "
set -g @catppuccin_window_middle_separator " "
set -g @catppuccin_window_number_position "right"
set -g @catppuccin_window_default_fill "number"
set -g @catppuccin_window_default_text "#W"
set -g @catppuccin_window_current_fill "number"
set -g @catppuccin_window_current_text "#W"
set -g @catppuccin_status_modules_right "application directory session"
set -g @catppuccin_status_left_separator " "
set -g @catppuccin_status_right_separator ""
set -g @catppuccin_status_right_separator_inverse "no"
set -g @catppuccin_status_fill "icon"
set -g @catppuccin_status_connect_separator "no"
set -g @catppuccin_directory_text "#{pane_current_path}"
'';
}
{
plugin = tmuxPlugins.better-mouse-mode;
extraConfig = "set-option -g mouse on";
}
{
plugin = tmuxPlugins.mkTmuxPlugin {
pluginName = "tmux.nvim";
version = "unstable-2024-04-05";
src = fetchFromGitHub {
owner = "aserowy";
repo = "tmux.nvim";
rev = "63e9c5e054099dd30af306bd8ceaa2f1086e1b07";
sha256 = "0ynzljwq6hv7415p7pr0aqx8kycp84p3p3dy4jcx61dxfgdpgc4c";
};
};
extraConfig = '''';
}
];
tmux.shell = "${pkgs.zsh}/bin/zsh";
tmux.terminal = "screen-256color";
wezterm = mkIf (config._nih.type != "server") {
enable = true;
config = {
default_prog = ["zsh" "--login"];
enable_wayland = false;
enable_tab_bar = false;
font = "lua wezterm.font(\"Fira Code\")";
font_size = 10;
};
};
zsh.enable = true;
zsh.enableAutosuggestions = true;
zsh.enableCompletion = true;
zsh.initExtra = ''
export GPG_TTY=$(tty)
alias tmux="tmux -f ${config.xdg.configHome}/tmux/tmux.conf";
'';
};
};
}

View File

@@ -1,165 +0,0 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
cfg = config.nih;
hmModule = lib.types.submoduleWith {
description = "Home Manager module";
specialArgs = {
lib = lib;
osConfig = config;
};
modules =
[
({name, ...}: {
config = {
submoduleSupport.enable = true;
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
home.username = config.users.users.${name}.name;
home.homeDirectory = config.users.users.${name}.home;
# Make activation script use same version of Nix as system as a whole.
# This avoids problems with Nix not being in PATH.
nix.package = config.nix.package;
};
})
]
++ config.home-manager.sharedModules;
};
in {
imports = [];
options.nih = with lib;
with lib.types; {
users = mkOption {
type =
attrsOf
(submodule ({...}: {
options = {
description = mkOption {
type = nullOr str;
default = null;
};
extraGroups = mkOption {
type = listOf str;
default = ["networkmanager" "wheel"];
};
home = mkOption {
type = attrsOf anything;
default = {};
};
normalUser = mkOption {
type = bool;
default = true;
};
packages = mkOption {
type = listOf package;
default = [];
};
password = mkOption {
type = nullOr (passwdEntry str);
default = null;
};
profiles = mkOption {
type = attrsOf anything;
default = {};
};
programs = mkOption {
type = attrsOf anything;
default = {};
};
services = mkOption {
type = attrsOf anything;
default = {};
};
shell = mkOption {
type = package;
default = pkgs.bash;
};
username = mkOption {
type = passwdEntry str;
apply = x:
assert (builtins.stringLength
x
< 32
|| abort "Username '${x}' is longer than 31 characters"); x;
};
};
}));
};
};
config = with lib; {
users.users =
builtins.mapAttrs
(name: value: {
name = value.username;
hashedPassword = value.password;
description =
if value.description != null
then value.description
else value.username;
isNormalUser = value.normalUser;
shell = value.shell;
extraGroups = value.extraGroups ++ ["wheel"];
})
cfg.users;
users.mutableUsers = true;
home-manager.extraSpecialArgs = {inherit inputs;};
home-manager.users =
builtins.mapAttrs
(name: value:
mkMerge [
{
imports = [
inputs.nix-index-database.hmModules.nix-index
inputs.flatpaks.homeManagerModules.nix-flatpak
./programs
./user-profiles
];
options = with lib;
with lib.types; {
_nih = mkOption {
type = attrsOf anything;
default = {};
};
};
config = {
_nih = {
type = config.nih.type;
};
profiles = mkMerge [value.profiles];
programs = mkMerge [
{home-manager.enable = true;}
value.programs
];
services = mkMerge [
{flatpak.enable = mkDefault true;}
value.services
];
home = mkMerge [
{
username = value.username;
homeDirectory =
mkDefault
"/home/${value.username}";
stateVersion =
mkDefault
"23.11"; # Do not change
}
value.home
];
};
}
])
cfg.users;
};
}

View File

@@ -1,94 +0,0 @@
# Config shared between all host's configuration.nix (NixOS config)
{
config,
pkgs,
inputs,
lib,
...
}: let
cfg = config.host;
in {
imports = [
inputs.home-manager.nixosModules.default
inputs.sops-nix.nixosModules.sops
../systems/localization.nix
];
options.host = with lib;
with lib.types; {
networking = {
hostName = mkOption {
default = "nixos";
type = str;
description = "Define the host's network name";
};
wireless.enable = mkOption {
default = false;
type = bool;
description = "Enables wireless support";
};
};
time = {
timeZone = mkOption {
type = str;
description = "Sets host's time zone";
};
};
};
config = {
# Nix configuration
nix.settings.experimental-features = ["nix-command" "flakes"];
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
};
networking = {
networkmanager.enable = true;
hostName = lib.mkDefault cfg.networking.hostName;
wireless.enable = cfg.networking.wireless.enable;
# Configure network proxy if necessary
# proxy.default = "http://user:password@proxy:port/";
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
};
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
wireplumber.enable = true;
#jack.enable = true;
};
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
vim
neovim
tmux
git
lazygit
gcc # Added temporally so my neovim config doesn't break
wget
nixpkgs-fmt
nixpkgs-lint
];
environment.sessionVariables = {
EDITOR = "nvim";
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
};
}

View File

@@ -1,6 +1,7 @@
{...}: {
imports = [
./nih
./hyprland.nix
];
options = {};
config = {};

View File

@@ -0,0 +1,38 @@
{
config,
lib,
inputs,
pkgs,
...
}: let
cfg = config.programs.hyprland;
in {
imports = [];
options.programs.hyprland = with lib;
with lib.types; {
useFlakes = mkOption {
type = bool;
default = true;
};
};
config = with lib;
mkIf cfg.enable {
programs.hyprland = {
xwayland.enable = mkDefault true;
package = mkDefault (
if cfg.useFlakes
then inputs.hyprland.packages."${pkgs.system}".hyprland
else pkgs.hyprland
);
portalPackage = mkDefault (
if cfg.useFlakes
then inputs.xdg-desktop-portal-hyprland.packages."${pkgs.system}".xdg-desktop-portal-hyprland
else pkgs.xdg-desktop-portal-hyprland
);
};
xdg.portal.enable = true;
xdg.portal.extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
};
}

View File

@@ -1,151 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my-fonts;
in
{
config,
lib,
...
}: let
cfg = config.my-fonts;
in {
imports = [];
options.my-fonts = with lib;
with lib.types; {
enable = mkEnableOption "";
fonts = mkOption {
type = listOf package;
default = [];
};
user = mkOption {
type = str;
};
fonts-presets = {
libreoffice = mkOption {
type = bool;
default = true;
};
};
};
config = lib.mkIf cfg.enable {
fonts = {
fontconfig.enable = true;
fontDir.enable = true;
packages = with pkgs;
(if cfg.fonts-presets.libreoffice then [
dejavu_fonts
gentium
gentium-book-basic
liberation_ttf
liberation-sans-narrow
libertinus
(google-fonts.override {
fonts = [
"Alef"
"Amiri"
"Amiri Quran"
"Caladea"
"Carlito"
"Frank Ruhl Libre"
"Gentium Plus"
"Mirian Libre"
"Noto Kufi Arabic"
"Noto Naskh Arabic"
"Noto Sans"
"Noto Sans Arabic"
"Noto Sans Armenian"
"Noto Sans Georgian"
"Noto Sans Hebrew"
"Noto Sans Lao"
"Noto Sans Lisu"
"Noto Serif"
"Noto Serif Armenian"
"Noto Serif Georgian"
"Noto Serif Hebrew"
"Noto Serif Lao"
"Reem Kufi"
"Rubik"
"Scheherazade New"
];
})
(stdenv.mkDerivation rec {
pname = "david-libre";
version = "1.001";
src = pkgs.fetchzip {
url = "https://github.com/meirsadan/david-libre/releases/download/v${version}/DavidLibre_TTF_v1.001.zip";
stripRoot = false;
hash = "sha256-suzC7tc7UoVrS3hpOk2154WEWlXQcxD+hil0cMb/paw=";
};
installPhase = ''
runHook preInstall
install -m444 -Dt $out/share/fonts/truetype *.ttf
runHook postInstall
'';
meta = with lib; {
homepage = "https://github.com/meirsadan/david-libre";
license = licenses.ofl;
platforms = platforms.all;
};
})
(stdenv.mkDerivation rec {
pname = "linux-libertine";
version = "5.3.0";
src = pkgs.fetchzip {
url = "https://downloads.sourceforge.net/project/linuxlibertine/linuxlibertine/5.3.0/LinLibertineTTF_5.3.0_2012_07_02.tgz";
stripRoot = false;
hash = "sha256-Az9neVss6ygRtnGdNtJRCYN2C2FlJPbvfNxfSxsbTRQ=";
};
installPhase = ''
runHook preInstall
install -m444 -Dt $out/share/fonts/truetype *.ttf
runHook postInstall
'';
meta = with lib; {
homepage = "https://libertine-fonts.org";
license = licenses.ofl;
platforms = platforms.all;
};
})
] else [ ])
++ cfg.fonts;
};
environment.systemPackages = cfg.fonts;
systemd.services."my-fonts-setup" = {
script = ''
if [ -d "/home/${cfg.user}/.local/share/fonts" ]; then
echo "";
else
ln -sf /run/current-system/sw/share/X11/fonts /home/${cfg.user}/.local/share/fonts;
fi
if [ -d "/home/${cfg.user}/.fonts" ]; then
echo "";
else
ln -sf /run/current-system/sw/share/X11/fonts /home/${cfg.user}/.fonts;
fi
'';
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
};
};
systemd.services."my-fonts-setup-sudo" = {
script = ''
if [ -d "/usr/share/fonts" ]; then
echo "";
else
mkdir -p /usr/share;
ln -sf /run/current-system/sw/share/X11/fonts /usr/share/fonts;
fi
'';
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
};
};
};
}

View File

@@ -1,67 +0,0 @@
{
config,
pkgs,
inputs,
lib,
...
}: let
cfg = config.localization;
in {
options.localization = with lib;
with lib.types; {
locale = mkOption {
default = "en_US.UTF-8";
type = str;
description = "Sets default locale of the host";
};
extraLocales = mkOption {
default = rec {
LC_ADDRESS = "pt_BR.UTF-8";
LC_IDENTIFICATION = LC_ADDRESS;
LC_MEASUREMENT = LC_ADDRESS;
LC_MONETARY = LC_ADDRESS;
LC_NAME = LC_ADDRESS;
LC_NUMERIC = LC_ADDRESS;
LC_PAPER = LC_ADDRESS;
LC_TELEPHONE = LC_ADDRESS;
LC_TIME = LC_ADDRESS;
};
description = "Extra localization settings";
};
keymap.layout = mkOption {
default = "br";
type = str;
};
keymap.variant = mkOption {
default = "";
type = str;
};
keymap.console = mkOption {
default = "br-abnt2";
type = str;
};
time = {
zone = mkOption {
default = "America/Sao_Paulo";
type = str;
};
};
};
config = {
i18n = {
defaultLocale = cfg.locale;
extraLocaleSettings = cfg.extraLocales;
};
services.xserver = {
xkb.layout = cfg.keymap.layout;
xkb.variant = cfg.keymap.variant;
};
console.keyMap = cfg.keymap.console;
time = {
timeZone = cfg.time.zone;
};
};
}

View File

@@ -1,102 +0,0 @@
{
config,
pkgs,
inputs,
lib,
...
}: let
cfg = config.set-user;
in {
options.set-user = with lib;
with lib.types; {
users = mkOption {
default = [];
type = listOf (submodule ({...}: {
options = {
username = mkOption {
type = str;
};
description = mkOption {
type = nullOr str;
default = null;
};
normalUser = mkOption {
type = bool;
default = true;
};
shell = mkOption {
type = package;
default = pkgs.bash;
};
packages = mkOption {
type = listOf package;
default = [];
};
extraGroups = mkOption {
type = listOf str;
default = ["networkmanager" "wheel"];
};
home = mkOption {
type = anything;
};
flatpak = mkOption {
type = nullOr bool;
default = true;
};
};
}));
};
};
config = let
home-default = user: {
imports = [
(
if user ? flatpak && !user.flatpak
then null
else inputs.flatpaks.homeManagerModules.nix-flatpak
)
inputs.nix-index-database.hmModules.nix-index
];
programs.home-manager.enable = true;
home.username = user.username;
home.homeDirectory = "/home/${user.username}";
home.stateVersion = "23.11"; # Do not change
};
in {
users.users = (
builtins.listToAttrs
(
map
(u: {
name = u.username;
value = {
description =
if u.description != null
then u.description
else u.username;
isNormalUser = u.normalUser;
shell = u.shell;
packages = u.packages;
extraGroups = u.extraGroups ++ ["wheel"];
};
})
cfg.users
)
);
home-manager.extraSpecialArgs = {inherit inputs;};
home-manager.users = (
builtins.listToAttrs
(
map
(u: {
name = u.username;
value =
if u ? home
then lib.mkMerge [(home-default u) u.home]
else (home-default u);
})
cfg.users
)
);
};
}

View File

@@ -1,94 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.adguard;
in {
imports = [];
options.server.adguard = with lib;
with lib.types; {
enable = mkEnableOption "";
extraArgs = mkOption {
type = listOf str;
default = [];
};
domain = mkOption {
type = str;
default = "adguard." + config.server.domain;
};
port = mkOption {
type = port;
default = 3010;
};
settings = {
server.domain = mkOption {
type = str;
default = cfg.domain;
};
server.port = mkOption {
type = port;
default = cfg.port;
};
server.address = mkOption {
type = str;
default = "0.0.0.0";
};
dns.rewrites = mkOption {
type = attrsOf str;
default = {};
};
dns.filters = mkOption {
type = attrsOf (submodule ({lib, ...}: {
options = {
name = mkOption {
type = nullOr str;
default = null;
};
url = mkOption {
type = str;
};
enabled = {
type = bool;
default = true;
};
};
}));
default = {};
};
};
};
config = lib.mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [53];
allowedUDPPorts = [53 51820];
};
services.adguardhome = with builtins; {
enable = true;
settings = {
bind_port = cfg.settings.server.port;
bind_host = cfg.settings.server.address;
http = {
address = "${cfg.settings.server.address}:${toString cfg.settings.server.port}";
};
dns.rewrites = builtins.attrValues (builtins.mapAttrs
(from: to: {
domain = from;
answer = to;
})
cfg.settings.dns.rewrites);
filters = attrValues (mapAttrs
(id: list: {
name =
if isNull list.name
then id
else list.name;
ID = id;
url = list.url;
enabled = list.enabled;
})
cfg.settings.dns.filters);
};
};
};
}

View File

@@ -1,36 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.caddy;
in {
imports = [];
options.server.caddy = with lib;
with lib.types; {
enable = mkEnableOption "";
settings = {
virtualHosts = mkOption {
type = attrsOf (submodule ({
config,
lib,
...
}: {
options = {
extraConfig = mkOption {
type = lines;
default = "";
};
};
}));
default = {};
};
};
};
config = lib.mkIf cfg.enable {
services.caddy = {
enable = true;
virtualHosts = cfg.settings.virtualHosts;
};
};
}

View File

@@ -1,124 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.server;
server = pkgs.writeShellScriptBin "server" ''
gum="${pkgs.gum}/bin/gum";
flakeDir="${toString cfg.flakeDir}";
command="$1";
if [[ "$command" == "build" ]]; then
shift 1;
sudo nixos-rebuild switch --flake "$flakeDir" "$@"
fi
${
if cfg.forgejo.cliAlias
then ''
if [[ "$command" == "forgejo" ]]; then
shift 1;
sudo --user=${cfg.forgejo.user} ${cfg.forgejo.package}/bin/gitea --work-path ${cfg.forgejo.data.root} "$@"
fi
if [[ "$command" == "forgejo-act" ]]; then
shift 1;
sudo --user=${cfg.forgejo.user} ${cfg.forgejo.actions.package}/bin/act_runner --config /var/lib/gitea-runner/${cfg.forgejo.actions.instanceName} "$@"
fi
''
else ""
}
'';
in {
imports = [
./adguard.nix
./caddy.nix
./forgejo.nix
./jellyfin.nix
./jellyseerr.nix
./network.nix
./nextcloud.nix
./photoprism.nix
./tailscale.nix
];
options.server = with lib;
with lib.types; {
enable = mkEnableOption "";
name = mkOption {
type = str;
default = "server";
};
flakeDir = mkOption {
type = str;
};
storage = mkOption {
type = path;
default = /data + "/${cfg.name}";
description = "The Homelab central storage path";
};
domain = mkOption {
type = either str path;
default = "${cfg.name}.local";
};
localIp = mkOption {
type = str;
};
ip = mkOption {
type = str;
default = cfg.localIp;
};
handleDomains = mkOption {
type = bool;
default = true;
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
server
];
networking.firewall.allowedTCPPorts = lib.mkIf cfg.handleDomains [80 433];
systemd.services."tailscaled" = lib.mkIf cfg.handleDomains {
serviceConfig = {
Environment = ["TS_PERMIT_CERT_UID=caddy"];
};
};
server = with lib;
mkIf cfg.handleDomains {
adguard = {
enable = true;
settings.dns.rewrites =
if hasPrefix "*." cfg.domain
then {
"${cfg.domain}" = cfg.ip;
}
else {
"${cfg.domain}" = cfg.ip;
"${"*." + cfg.domain}" = cfg.ip;
};
};
caddy = let
homelabServices = lib.filterAttrs (n: v: builtins.isAttrs v && v ? domain) cfg;
in
with lib;
mkIf cfg.handleDomains {
enable = true;
settings.virtualHosts =
mapAttrs'
(name: value:
nameValuePair (value.domain) {
extraConfig = ''
reverse_proxy ${cfg.localIp}:${toString value.port}
'';
})
homelabServices;
};
};
};
}

View File

@@ -1,419 +0,0 @@
{
config,
lib,
pkgs,
utils,
...
}: let
cfg = config.server.forgejo;
users = builtins.attrValues (builtins.mapAttrs
(username: info: {
name =
if isNull info.name
then username
else info.name;
email = info.email;
password = info.password;
admin = info.admin;
})
cfg.settings.users);
settingsFormat = pkgs.formats.yaml {};
in {
imports = [];
options.server.forgejo = with lib;
with lib.types; {
enable = mkEnableOption "";
user = mkOption {
type = str;
default = "git";
};
actions.enable = mkOption {
type = bool;
default = false;
};
actions.runnerToken = mkOption {
type = str;
};
actions.package = mkOption {
type = package;
default = pkgs.forgejo-actions-runner;
};
actions.instanceUrl = mkOption {
type = str;
default = "https://${cfg.domain}";
};
actions.url = mkOption {
type = str;
default = "http://localhost:${toString cfg.port}";
};
actions.instanceName = mkOption {
type = str;
default = "${cfg.user}Forgejo${toString cfg.port}";
};
actions.settings = mkOption {
type = submodule {
freeformType = settingsFormat.type;
options = {
runner.insecure = mkOption {
type = bool;
default = true;
};
};
};
default = {};
};
package = mkOption {
type = package;
default = pkgs.forgejo;
};
cliAlias = mkOption {
type = bool;
default = true;
};
domain = mkOption {
type = str;
default = "forgejo." + config.server.domain;
};
port = mkOption {
type = port;
default = 3020;
};
data = {
root = mkOption {
type = path;
default = config.server.storage + /forgejo;
};
};
handleUndeclaredUsers = mkOption {
type = bool;
default = false;
};
settings = {
users = mkOption {
type = attrsOf (submodule ({
config,
lib,
...
}:
with lib;
with lib.types; {
options = {
name = mkOption {
type = nullOr (either str path);
default = null;
};
password = mkOption {
type = either str path;
};
email = mkOption {
type = either str path;
};
admin = mkOption {
type = bool;
default = false;
};
};
}));
default = {};
};
name = mkOption {
type = str;
default = "Forgejo: Beyond coding. We forge";
};
prod = mkOption {
type = bool;
default = true;
};
repo.defaultUnits = mkOption {
type = listOf (enum [
"repo.code"
"repo.releases"
"repo.issues"
"repo.pulls"
"repo.wiki"
"repo.projects"
"repo.packages"
"repo.actions"
]);
default = [
"repo.code"
"repo.issues"
"repo.pulls"
];
};
repo.disabledUnits = mkOption {
type = listOf (enum [
"repo.issues"
"repo.ext_issues"
"repo.pulls"
"repo.wiki"
"repo.ext_wiki"
"repo.projects"
"repo.packages"
"repo.actions"
]);
default = [];
};
repo.pushCreate = mkOption {
type = bool;
default = false;
};
cors.enable = mkOption {
type = bool;
default = false;
};
cors.domains = mkOption {
type = listOf str;
default = [];
};
cors.methods = mkOption {
type = listOf str;
default = [];
};
ui.defaultTheme = mkOption {
type = str;
default = "forgejo-auto";
};
ui.themes = mkOption {
type = listOf str;
default = [
"forgejo-auto"
"forgejo-light"
"forgejo-dark"
"auto"
"gitea"
"arc-green"
];
};
server.protocol = mkOption {
type = enum ["http" "https" "fcgi" "http+unix" "fcgi+unix"];
default = "http";
};
server.domain = mkOption {
type = str;
default = cfg.domain;
};
server.port = mkOption {
type = port;
default = cfg.port;
};
server.address = mkOption {
type = either str path;
default =
if hasSuffix "+unix" cfg.settings.server.protocol
then "/run/forgejo/forgejo.sock"
else "0.0.0.0";
};
server.url = mkOption {
type = str;
default = "http://${cfg.settings.server.domain}:${toString cfg.settings.server.port}";
};
server.offline = mkOption {
type = bool;
default = false;
};
server.compression = mkOption {
type = bool;
default = false;
};
server.landingPage = mkOption {
type = enum ["home" "explore" "organizations" "login" str];
default = "home";
};
service.registration = mkOption {
type = bool;
default = false;
};
security.allowBypassGiteaEnv = mkOption {
type = bool;
default = false;
};
};
};
config = let
inherit (utils) escapeSystemdPath;
in
with lib;
mkIf cfg.enable {
users.users."${cfg.user}" = {
home = cfg.data.root;
useDefaultShell = true;
group = cfg.user;
isSystemUser = true;
initialPassword = "1313";
};
users.groups."${cfg.user}" = {};
virtualisation.docker.enable = cfg.actions.enable;
services.gitea-actions-runner.instances."${cfg.actions.instanceName}" = mkIf cfg.actions.enable {
enable = true;
name = cfg.actions.instanceName;
url = cfg.actions.instanceUrl;
token = cfg.actions.runnerToken;
settings = cfg.actions.settings;
labels = [
"host:host"
"shell:host://-self-hosted"
"debian-latest:docker://node:18-bullseye"
"ubuntu-latest:docker://node:18-bullseye"
"debian-slim:docker://node:18-bullseye-slim"
"ubuntu-slim:docker://node:18-bullseye-slim"
"alpine-latest:docker://alpine:latest"
];
};
services.gitea-actions-runner.package = cfg.actions.package;
systemd.services."${escapeSystemdPath cfg.actions.instanceName}".serviceConfig.User = cfg.user;
services.forgejo = {
enable = true;
package = cfg.package;
user = cfg.user;
group = cfg.user;
stateDir = toString cfg.data.root;
useWizard = false;
database = {
user = cfg.user;
type = "sqlite3";
};
settings = with builtins; {
actions = mkIf cfg.actions.enable {
ENABLED = true;
DEFAULT_ACTIONS_URL = cfg.actions.url;
};
DEFAULT = {
APP_NAME = cfg.settings.name;
RUN_MODE =
if cfg.settings.prod
then "prod"
else "dev";
};
repository = {
DISABLED_REPO_UNITS = concatStringsSep "," cfg.settings.repo.disabledUnits;
DEFAULT_REPO_UNITS = concatStringsSep "," cfg.settings.repo.defaultUnits;
ENABLE_PUSH_CREATE_USER = cfg.settings.repo.pushCreate;
ENABLE_PUSH_CREATE_ORG = cfg.settings.repo.pushCreate;
};
cors = {
ENABLED = cfg.settings.cors.enable;
ALLOW_DOMAIN = concatStringsSep "," cfg.settings.cors.domains;
METHODS = concatStringsSep "," cfg.settings.cors.methods;
};
ui = {
DEFAULT_THEME = cfg.settings.ui.defaultTheme;
THEMES = concatStringsSep "," cfg.settings.ui.themes;
};
server = {
PROTOCOL = cfg.settings.server.protocol;
DOMAIN = cfg.settings.server.domain;
ROOT_URL = cfg.settings.server.url;
HTTP_ADDR = cfg.settings.server.address;
HTTP_PORT = cfg.settings.server.port;
OFFLINE_MODE = cfg.settings.server.offline;
ENABLE_GZIP = cfg.settings.server.compression;
LANDING_PAGE = cfg.settings.server.landingPage;
};
security = {
ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET =
if cfg.settings.security.allowBypassGiteaEnv
then false
else true;
};
service = {
DISABLE_REGISTRATION =
if cfg.settings.service.registration
then false
else true;
};
};
};
systemd.services."homelab-forgejo-setup" = with builtins; {
script = ''
configFile="${toString cfg.data.root}/custom/conf/app.ini";
touch $configFile
gum="${pkgs.gum}/bin/gum"
forgejo="${cfg.package}/bin/gitea --config $configFile"
user="$forgejo admin user"
awk="${pkgs.gawk}/bin/awk"
declaredUsers=(${toString (map (user: "${
if isPath user.name
then "$(cat ${toString user.name})"
else user.name
}")
users)});
$gum log --structured --time timeonly --level info "HANDLING UNDECLARED USERS"
$user list | $awk '{print $2}' | tail -n +2 | while read username; do
if printf '%s\0' "''${declaredUsers[@]}" | grep -Fxqz -- "$username"; then
$gum log --structured --time timeonly --level warn "Declared user already exists, ignoring" username $username;
else
if [[ "$($user list | tail -n +2 | $awk '{print $2 " " $5}' | grep "$username " | $awk '{print $2}')" == "true" ]]; then
$gum log --structured --time timeonly --level warn "Undeclared user is a ADMIN, ignoring" username $username;
else
${
if cfg.handleUndeclaredUsers
then ''
$gum log --structured --time timeonly --level warn "DELETING undeclared user" username $username;
$user delete -u "$username";
''
else ''
$gum log --structured --time timeonly --level warn "UNDECLARED user, please declare it in the config so it's reproducible" username "$username";
''
}
fi
fi
done
${toString (map (user: ''
username="${
if isPath user.name
then "\"$(cat ${toString user.name})\""
else user.name
}";
email="${
if isPath user.email
then "\"$(cat ${toString user.email})\""
else user.email
}";
password="${
if isPath user.password
then "\"$(cat ${toString user.password})\""
else user.password
}";
if [[ "$($user list | grep "$username" | $awk '{print $2}')" ]]; then
$gum log --structured --time timeonly --level warn "User with username already exists" username $username;
elif [[ "$($user list | grep "$email" | $awk '{print $3}')" ]]; then
$gum log --structured --time timeonly --level warn "User with email already exists" email $email;
else
$gum log --structured --time timeonly --level info ${
if user.admin
then "Creating ADMIN user"
else "Creating user"
} username $username email $email password $password;
$user create --username $username --email $email --password $password ${
if user.admin
then "--admin"
else ""
};
fi
'')
users)}
'';
wantedBy = ["multi-user.target"];
after = ["forgejo.service"];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.user;
};
};
};
}

View File

@@ -1,650 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.server.jellyfin;
networkConfig = pkgs.writeTextFile {
name = "network.json";
text = builtins.toJSON cfg.settings.network;
};
encodingConfig = pkgs.writeTextFile {
name = "encoding.json";
text = builtins.toJSON cfg.settings.encoding;
};
systemConfig = pkgs.writeTextFile {
name = "encoding.json";
text = builtins.toJSON cfg.settings.system;
};
in {
imports = [
./jellyseerr.nix
];
options.server.jellyfin = with lib;
with lib.types; {
enable = mkEnableOption "";
user = mkOption {
type = str;
default = "jellyfin";
};
package = mkOption {
type = package;
default = pkgs.jellyfin;
};
domain = mkOption {
type = str;
default = "jellyfin." + config.server.domain;
};
port = mkOption {
type = port;
default = 8096;
};
data = {
root = mkOption {
type = path;
default = config.server.storage + /jellyfin;
};
};
jellyseerr = mkOption {
type = bool;
default = true;
};
settings = {
network = mkOption {
type = submodule {
freeformType = (pkgs.formats.json {}).type;
options = {
AutoDiscovery = mkOption {
type = bool;
default = true;
};
AutoDiscoveryTracing = mkOption {
type = bool;
default = false;
};
BaseUrl = mkOption {
type = str;
default = "https://${cfg.domain}";
};
CertificatePassword = mkOption {
type = str;
default = "";
};
CertificatePath = mkOption {
type = str;
default = "";
};
EnableHttps = mkOption {
type = bool;
default = false;
};
EnableIPV4 = mkOption {
type = bool;
default = true;
};
EnableIPV6 = mkOption {
type = bool;
default = false;
};
EnablePublishedServerUriByRequest = mkOption {
type = bool;
default = false;
};
EnableSSDPTracing = mkOption {
type = bool;
default = false;
};
EnableRemoteAccess = mkOption {
type = bool;
default = true;
};
EnableUPnP = mkOption {
type = bool;
default = false;
};
GatewayMonitorPeriod = mkOption {
type = int;
default = 60;
};
HDHomerunPortRange = mkOption {
type = str;
default = "";
};
HttpServerPortNumber = mkOption {
type = port;
default = cfg.port;
};
HttpsPortNumber = mkOption {
type = port;
default = cfg.settings.network.PublicHttpsPort;
};
IgnoreVirtualInterfaces = mkOption {
type = bool;
default = true;
};
IsRemoteIPFilterBlacklist = mkOption {
type = bool;
default = false;
};
KnownProxies = mkOption {
type = str;
default = "";
};
LocalNetworkAddresses = mkOption {
type = str;
default = "";
};
LocalNetworkSubnets = mkOption {
type = str;
default = "";
};
PublicHttpsPort = mkOption {
type = port;
default = 8920;
};
PublicPort = mkOption {
type = port;
default = cfg.settings.network.HttpServerPortNumber;
};
PublishedServerUriBySubnet = mkOption {
type = str;
default = "";
};
RequireHttps = mkOption {
type = bool;
default = false;
};
RemoteIPFilter = mkOption {
type = str;
default = "";
};
SSDPTracingFilter = mkOption {
type = str;
default = "";
};
TrustAllIP6Interfaces = mkOption {
type = bool;
default = false;
};
UDPPortRange = mkOption {
type = str;
default = "";
};
UDPSendCount = mkOption {
type = int;
default = 2;
};
UDPSendDelay = mkOption {
type = int;
default = 100;
};
UPnPCreateHttpPortMap = mkOption {
type = bool;
default = false;
};
VirtualInterfacenNames = mkOption {
type = str;
default = "vEthernet*";
};
};
};
default = {};
};
encoding = mkOption {
type = submodule {
freeformType = (pkgs.formats.json {}).type;
options = {
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions.string = mkOption {
type = listOf str;
default = ["mkv"];
};
DeinterlaceDoubleRate = mkOption {
type = bool;
default = false;
};
DeinterlaceMethod = mkOption {
type = str;
default = "yadif";
};
DownMixAudioBoost = mkOption {
type = int;
default = 2;
};
EnableDecodingColorDepth10Hevc = mkOption {
type = bool;
default = true;
};
EnableDecodingColorDepth10Vp9 = mkOption {
type = bool;
default = true;
};
EnableEnhancedNvdecDecoder = mkOption {
type = bool;
default = true;
};
EnableFallbackFont = mkOption {
type = bool;
default = false;
};
EnableHardwareEncoding = mkOption {
type = bool;
default = true;
};
EnableIntelLowPowerH264HwEncoder = mkOption {
type = bool;
default = false;
};
EnableIntelLowPowerHevcHwEncoder = mkOption {
type = bool;
default = false;
};
EnableSubtitleExtraction = mkOption {
type = bool;
default = true;
};
EnableThrottling = mkOption {
type = bool;
default = false;
};
EnableTonemapping = mkOption {
type = bool;
default = false;
};
EnableVppTonemapping = mkOption {
type = bool;
default = false;
};
EncoderAppPathDisplay = mkOption {
type = either path str;
default = "${pkgs.jellyfin-ffmpeg}/bin/ffmpeg";
};
EncodingThreadCount = mkOption {
type = int;
default = -1;
};
H264Crf = mkOption {
type = int;
default = 23;
};
H265Crf = mkOption {
type = int;
default = 28;
};
HardwareDecodingCodecs.string = mkOption {
type = listOf str;
default = ["h254" "vc1"];
};
MaxMuxingQueueSize = mkOption {
type = int;
default = 2048;
};
PreferSystemNativeHwDecoder = mkOption {
type = bool;
default = true;
};
ThrottleDelaySeconds = mkOption {
type = int;
default = 180;
};
TonemappingAlgorithm = mkOption {
type = str;
default = "bt2390";
};
TonemappingDesat = mkOption {
type = int;
default = 0;
};
TonemappingMode = mkOption {
type = str;
default = "auto";
};
TonemappingParam = mkOption {
type = int;
default = 0;
};
TonemappingPeak = mkOption {
type = int;
default = 100;
};
TonemappingRange = mkOption {
type = str;
default = "auto";
};
VaapiDevice = mkOption {
type = either path str;
default = "/dev/dri/renderD128";
};
VppTonemappingBrightness = mkOption {
type = int;
default = 16;
};
VppTonemappingContrast = mkOption {
type = int;
default = 1;
};
};
};
default = {};
};
system = mkOption {
type = submodule {
freeformType = (pkgs.formats.json {}).type;
options = {
ActivityLogRetentionDays = mkOption {
type = int;
default = 30;
};
AllowClientLogUpload = mkOption {
type = bool;
default = true;
};
CodecsUsed = mkOption {
type = str;
default = "";
};
ContentTypes = mkOption {
type = str;
default = "";
};
CorsHost.string = mkOption {
type = listOf str;
default = ["*"];
};
DisableLiveTvChannelUserDataName = mkOption {
type = bool;
default = true;
};
DisplaySpecialsWithinSeasons = mkOption {
type = bool;
default = true;
};
EnableCaseSensitiveItemIds = mkOption {
type = bool;
default = true;
};
EnableExternalContentInSuggestions = mkOption {
type = bool;
default = true;
};
EnableFolderView = mkOption {
type = bool;
default = false;
};
EnableGroupingIntoCollections = mkOption {
type = bool;
default = false;
};
EnableMetrics = mkOption {
type = bool;
default = false;
};
EnableNormalizedItemByNameIds = mkOption {
type = bool;
default = true;
};
EnableSlowResponseWarning = mkOption {
type = bool;
default = true;
};
ImageExtractionTimeoutMs = mkOption {
type = int;
default = 0;
};
ImageSavingConvention = mkOption {
type = str;
default = "Legacy";
};
IsPortAuthorized = mkOption {
type = bool;
default = true;
};
IsStartupWizardCompleted = mkOption {
type = bool;
default = true;
};
LibraryMetadataRefreshConcurrency = mkOption {
type = int;
default = 0;
};
LibraryMonitorDelay = mkOption {
type = int;
default = 60;
};
LogFileRetentionDays = mkOption {
type = int;
default = 3;
};
MaxAudiobookResume = mkOption {
type = int;
default = 5;
};
MaxResumePct = mkOption {
type = int;
default = 90;
};
MetadataCountryCode = mkOption {
type = str;
default = "US";
};
MetadataNetworkPath = mkOption {
type = str;
default = "";
};
MetadataOptions.MetadataOptions = mkOption {
default = [
{
ItemType = "Book";
}
{
ItemType = "Movie";
}
{
ItemType = "MusicVideo";
DisabledMetadataFetchers.string = ["The Open Movie Database"];
DisabledImageFetchers.string = ["The Open Movie Database"];
}
{
ItemType = "Series";
}
{
ItemType = "MusicAlbum";
DisabledMetadataFetchers.string = ["TheAudioDB"];
}
{
ItemType = "MusicArtist";
DisabledMetadataFetchers.string = ["TheAudioDB"];
}
{
ItemType = "BoxSet";
}
{
ItemType = "Season";
}
{
ItemType = "Episode";
}
];
type = listOf (submodule {
options = {
ItemType = mkOption {
default = "Movie";
type = str;
};
DisabledMetadataSavers.string = mkOption {
default = [];
type = listOf str;
};
LocalMetadataReaderOrder.string = mkOption {
default = [];
type = listOf str;
};
DisabledMetadataFetchers.string = mkOption {
default = [];
type = listOf str;
};
MetadataFetcherOrder.string = mkOption {
default = [];
type = listOf str;
};
DisabledImageFetchers.string = mkOption {
default = [];
type = listOf str;
};
ImageFetcherOrder.string = mkOption {
default = [];
type = listOf str;
};
};
});
};
MetadataPath = mkOption {
type = str;
default = "";
};
MinAudiobookResume = mkOption {
type = int;
default = 5;
};
MinResumeDurationSeconds = mkOption {
type = int;
default = 300;
};
MinResumePct = mkOption {
type = int;
default = 5;
};
PathSubstitutions = mkOption {
type = str;
default = "";
};
PluginRepositories.RepositoryInfo = mkOption {
default = [
{
Name = "Jellyfin Stable";
Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json";
Enabled = true;
}
];
type = listOf (submodule {
options = {
Name = mkOption {
type = str;
};
Url = mkOption {
type = str;
};
Enabled = mkOption {
default = true;
type = bool;
};
};
});
};
PreferredMetadataLanguage = mkOption {
type = str;
default = "en";
};
QuickConnectAvailable = mkOption {
type = bool;
default = true;
};
RemoteClientBitrateLimit = mkOption {
type = int;
default = 0;
};
RemoveOldPlugins = mkOption {
type = bool;
default = false;
};
SaveMetadataHidden = mkOption {
type = bool;
default = false;
};
ServerName = mkOption {
type = str;
default = "";
};
SkipDeserializationForBasicTypes = mkOption {
type = bool;
default = true;
};
SlowResponseThreshold = mkOption {
type = int;
default = 500;
};
SortRemoveCharacters.string = mkOption {
type = listOf str;
default = ["," "&" "-" "{" "}" "'"];
};
SortRemoveWords.string = mkOption {
type = listOf str;
default = ["the" "a" "an"];
};
SortReplaceCharacters.string = mkOption {
type = listOf str;
default = ["." "+" "%"];
};
UICulture = mkOption {
type = str;
default = "en-US";
};
};
};
default = {};
};
};
};
config = lib.mkIf cfg.enable {
services.jellyfin = {
enable = true;
package = cfg.package;
user = cfg.user;
group = cfg.user;
openFirewall = true;
};
server.jellyseerr.enable = cfg.jellyseerr;
systemd.services."homelab-jellyfin-config" = {
script = ''
jellyfin_dir="/var/lib/jellyfin";
function network_file() {
echo '<?xml version="1.0" enconding="utf-8"?>';
echo '<NetworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">';
cat ${networkConfig} | ${pkgs.yq-go}/bin/yq --input-format json --output-format xml;
echo '</NetworkConfiguration>';
}
function encoding_file() {
echo '<?xml version="1.0" enconding="utf-8"?>';
echo '<EncodingOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">';
cat ${encodingConfig} | ${pkgs.yq-go}/bin/yq --input-format json --output-format xml;
echo '</EncodingOptions>';
}
function system_file() {
echo '<?xml version="1.0" enconding="utf-8"?>';
echo '<ServerConfiguraion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">';
cat ${systemConfig} | ${pkgs.yq-go}/bin/yq --input-format json --output-format xml;
echo '</ServerConfiguraion>';
}
mkdir -p $jellyfin_dir/config;
touch "$jellyfin_dir/config/network.xml";
echo "$(network_file)" > "$jellyfin_dir/config/network.xml";
touch "$jellyfin_dir/config/encoding.xml";
echo "$(encoding_file)" > "$jellyfin_dir/config/encoding.xml";
touch "$jellyfin_dir/config/system.xml";
echo "$(system_file)" > "$jellyfin_dir/config/system.xml";
'';
wantedBy = ["multi-user.target"];
after = ["jellyfin.service"];
serviceConfig = {
Type = "oneshot";
};
};
};
}

View File

@@ -1,28 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.jellyseerr;
in {
imports = [];
options.server.jellyseerr = with lib;
with lib.types; {
enable = mkEnableOption "";
domain = mkOption {
type = str;
default = "jellyseerr." + config.server.domain;
};
port = mkOption {
type = port;
default = config.server.jellyfin.port + 10;
};
};
config = lib.mkIf cfg.enable {
services.jellyseerr = {
enable = true;
port = cfg.port;
openFirewall = true;
};
};
}

View File

@@ -1,78 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.network;
in {
imports = [];
options.server.network = with lib;
with lib.types; {
enable = mkOption {
type = bool;
default = true;
};
hostName = mkOption {
type = str;
default = config.server.name;
};
interface = mkOption {
type = str;
};
localIp = mkOption {
type = str;
default = config.server.localIp;
};
defaultGateway = mkOption {
type = str;
default = "192.168.1.1";
};
nameservers = mkOption {
type = listOf str;
default = ["1.1.1.1" "8.8.8.8"];
};
portForwarding = mkOption {
type = bool;
default = false;
};
openssh = mkOption {
type = bool;
default = true;
};
settings = {};
};
config = lib.mkIf cfg.enable {
host.networking.hostName = cfg.hostName;
networking = {
dhcpcd.enable = true;
interfaces."${cfg.interface}".ipv4.addresses = [
{
address = cfg.localIp;
prefixLength = 28;
}
];
defaultGateway = cfg.defaultGateway;
nameservers =
[
(
if config.server.tailscale.enable
then "100.100.100.100"
else null
)
]
++ cfg.nameservers;
};
boot.kernel.sysctl."net.ipv4.ip_forward" =
if cfg.portForwarding
then 1
else 0;
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" =
if cfg.portForwarding
then 1
else 0;
services.openssh.enable = cfg.openssh;
};
}

View File

@@ -1,63 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.server.nextcloud;
in {
imports = [];
options.server.nextcloud = with lib;
with lib.types; {
enable = mkEnableOption "";
user = mkOption {
type = str;
default = "nextcloud";
};
package = mkOption {
type = package;
default = pkgs.nextcloud28;
};
domain = mkOption {
type = str;
default = "nextcloud." + config.server.domain;
};
port = mkOption {
type = port;
default = 3030;
};
data = {
root = mkOption {
type = path;
default = config.server.storage + /nextcloud;
};
};
configureRedis = mkOption {
type = bool;
default = false;
};
settings = {
admin.user = mkOption {
type = str;
default = cfg.user;
};
admin.passwordFile = mkOption {
type = path;
};
};
};
config = lib.mkIf cfg.enable {
services.nextcloud = {
config = {
adminuser = cfg.settings.admin.user;
adminpassFile = toString cfg.settings.admin.passwordFile;
};
configureRedis = cfg.configureRedis;
enable = true;
home = toString cfg.data.root;
hostName = cfg.domain;
https = true;
package = cfg.package;
};
};
}

View File

@@ -1,38 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.photoprism;
in {
imports = [];
options.server.photoprism = with lib;
with lib.types; {
enable = mkEnableOption "";
user = mkOption {
type = str;
default = "photoprism";
};
domain = mkOption {
type = str;
default = "photoprism." + config.server.domain;
};
port = mkOption {
type = port;
default = 2342;
};
};
config = lib.mkIf cfg.enable {
services.photoprism = {
enable = true;
port = cfg.port;
settings = {
PHOTOPRISM_HTTP_PORT = cfg.port;
PHOTOPRISM_SITE_URL = cfg.domain;
PHOTOPRISM_DISABLE_TLS = true;
PHOTOPRISM_ADMIN_USER = cfg.user;
PHOTOPRISM_ADMIN_PASSWORD = cfg.user;
};
};
};
}

View File

@@ -1,36 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.server.tailscale;
in {
imports = [
./network.nix
];
options.server.tailscale = with lib;
with lib.types; {
enable = mkEnableOption "";
mode = mkOption {
type = enum [
"client"
"server"
"both"
];
default = "both";
};
exitNode = mkOption {
type = bool;
default = false;
};
settings = {};
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
useRoutingFeatures = cfg.mode;
};
server.network = lib.mkIf cfg.exitNode {portForwarding = lib.mkDefault true;};
};
}

View File

@@ -0,0 +1,19 @@
{
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1sseqwwa7fc0ftry8njyuagdg28fkmtdwmj6m7p3etjsj83suee3shfzjyz",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvNDBWYVBTR2s3dW1ITTEw\nazZnSWtRTFJ6Ui9kU1RBNlp1YlEvTjJMb1drCjVqbndTQmRIMUhUN2h4bHROU1h2\nRmUwdzhQdEFSSmtvaGxRZGlFUDc4NHMKLS0tIEI4TWk5eVIxV21tUXRaV2ZXZ1h5\ndzZIeEFEbDFsNWdJQkg2UTQvYmhBWEkKNYuVCvc0/tUi8IvoK8p6lTgbwAxa+0mU\n1uFymroQstSxzpA9Ol9hTR6X6dfBf+1zUnPpst0447fn2KyCNW0LGw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2024-04-10T13:50:59Z",
"mac": "ENC[AES256_GCM,data:8pobkHaDYMnKqFxmJXroWUFVgUhNtEHMyM4QXsSVjB5011C3K/0jDFZ51zC2tatA+luPYvcQyA03iNYfDMPfnuQT8TDYw7qB4UH7NHZuby4WD/rsEbnDjZtzKBAOolk8Bg7uSodP5cSiNaPAY6qQcH3xotxn1jBlTLl2bgBmEdI=,iv:Ep/NtDiy0GBGTXlmlNqw60qk4DQR7I/UrkkMCPeYIew=,tag:zeUsdaEca7ggn8JBz+Kc6A==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.8.1"
}
}

View File

@@ -1,10 +0,0 @@
#!/usr/bin/env bash
export SOPS_AGE_KEY_FILE=/home/guz/.config/sops/age/keys.txt
secrets_dir="/home/guz/.nix/secrets"
sops --output $secrets_dir/homelab-lesser-secrets.decrypted.json \
-d $secrets_dir/homelab-lesser-secrets.json