Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33385d5275 | ||
|
|
19bf815be8 | ||
|
|
0152438472 | ||
|
|
f9b07deb19 | ||
|
|
6e55d375d2 | ||
|
|
0e066cb4d7 | ||
|
|
bd64283f04 | ||
|
|
6025b6c4f1 | ||
|
|
92b04773b2 | ||
|
|
783a7a3390 | ||
|
|
0ef4354c1a | ||
|
|
192a978d46 | ||
|
|
a4519904b6 | ||
|
|
83a6e45bf4 | ||
|
|
2ba6f3466f | ||
|
|
b3f5b4b406 | ||
|
|
2e680f2519 | ||
|
|
445183f826 | ||
|
|
aec980e6fe | ||
|
|
68f732ec4b | ||
|
|
dc382dcfcc | ||
|
|
b1a06034f1 | ||
|
|
aa3e8cc263 | ||
|
|
b680255bc5 | ||
|
|
a3f7af4e39 | ||
|
|
cd5c8a0034 | ||
|
|
1f14f020ed | ||
|
|
05affb6b1f |
@@ -10,8 +10,8 @@ keys:
|
|||||||
- &pi5 age1t2d5scrukk0guva5sr97a8tge5j8kd865adezrcru7p269pzwvpsamkgje
|
- &pi5 age1t2d5scrukk0guva5sr97a8tge5j8kd865adezrcru7p269pzwvpsamkgje
|
||||||
- &deck age1c8qw59ffcq9l77gfmtyc3djtvt3md0u6dwhrjcgsm98ntyf72ufqugj7cg
|
- &deck age1c8qw59ffcq9l77gfmtyc3djtvt3md0u6dwhrjcgsm98ntyf72ufqugj7cg
|
||||||
- &steamdeck age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
- &steamdeck age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
||||||
- &matt_macbook-pro age1xg6mvj3x6s3t8058c6rsk3q4kskvm6nsffwckxkkjzhyn7r6tczqgkj23p
|
- &matt_macbook-pro age19daqsncuzeh3j6cwk8uxp6yfj8h0qtz02jxlwwy4v8j0mfgznsvq30440g
|
||||||
- &macbook-pro age1rdn39ywgzmc8wlsl5lrfe77e652wzjmjx58gx4k2ydghd35kdqvqscrf3h
|
- &macbook-pro age19w4zafpwnq9yhzuf8r5te2yhq7xlqj76rcgzcz935hllyrz4yvws4jn6ca
|
||||||
- &nuc age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
- &nuc age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
||||||
- &admin_nuc age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
- &admin_nuc age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
||||||
creation_rules:
|
creation_rules:
|
||||||
|
|||||||
156
README.md
156
README.md
@@ -1,50 +1,118 @@
|
|||||||
# nixOS Config
|
# NixOS Configuration Repository
|
||||||
|
|
||||||
### Common Files
|
This repository contains my personal NixOS configurations for multiple systems, managed using [Snowfall Lib](https://github.com/snowfallorg/lib) and the Nix Flakes system.
|
||||||
* [flake.nix](./flake.nix)
|
|
||||||
* [impermenance.nix](./share/impermanence/default.nix)
|
## Overview
|
||||||
* [share](./share)
|
|
||||||
* [overlays](./overlays)
|
This repository provides a centralized, declarative configuration for all my systems, including:
|
||||||
|
|
||||||
|
- Desktop PC (AMD)
|
||||||
|
- NAS server
|
||||||
|
- Steam Deck
|
||||||
|
- Intel NUC
|
||||||
|
- Raspberry Pi 4
|
||||||
|
- Raspberry Pi 5
|
||||||
|
- MacBook Pro (NixOS on Apple Silicon)
|
||||||
|
- MacBook Pro (Darwin/macOS)
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── checks/ # Pre-commit hooks and other checks
|
||||||
|
├── flake.nix # Main flake configuration
|
||||||
|
├── homes/ # Home-manager configurations for users
|
||||||
|
│ ├── aarch64-darwin/ # macOS home configurations
|
||||||
|
│ ├── aarch64-linux/ # ARM Linux home configurations
|
||||||
|
│ └── x86_64-linux/ # x86 Linux home configurations
|
||||||
|
├── modules/ # Reusable configuration modules
|
||||||
|
│ ├── home/ # Home-manager modules
|
||||||
|
│ └── nixos/ # NixOS system modules
|
||||||
|
├── overlays/ # Nixpkgs overlays
|
||||||
|
├── packages/ # Custom package definitions
|
||||||
|
├── secrets/ # Encrypted secrets (managed with sops-nix)
|
||||||
|
└── systems/ # System-specific configurations
|
||||||
|
├── aarch64-darwin/ # macOS system configurations
|
||||||
|
├── aarch64-linux/ # ARM Linux system configurations
|
||||||
|
└── x86_64-linux/ # x86 Linux system configurations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- **Modular Design**: Reusable modules for various system components
|
||||||
|
- **Multi-System Support**: Configurations for different hardware platforms
|
||||||
|
- **Home Manager Integration**: User environment management
|
||||||
|
- **Secret Management**: Encrypted secrets with sops-nix
|
||||||
|
- **Disk Management**: Declarative disk partitioning with disko
|
||||||
|
- **State Management**: Persistent state management with impermanence
|
||||||
|
- **Desktop Environments**: Support for GNOME, Hyprland, and COSMIC
|
||||||
|
- **Hardware-Specific Optimizations**: Tailored configurations for different hardware
|
||||||
|
|
||||||
|
## Key Technologies
|
||||||
|
|
||||||
|
- [Nix](https://nixos.org/) and [NixOS](https://nixos.org/)
|
||||||
|
- [Nix Flakes](https://nixos.wiki/wiki/Flakes)
|
||||||
|
- [Snowfall Lib](https://github.com/snowfallorg/lib)
|
||||||
|
- [Home Manager](https://github.com/nix-community/home-manager)
|
||||||
|
- [sops-nix](https://github.com/Mic92/sops-nix)
|
||||||
|
- [disko](https://github.com/nix-community/disko)
|
||||||
|
- [impermanence](https://github.com/nix-community/impermanence)
|
||||||
|
- [lanzaboote](https://github.com/nix-community/lanzaboote) (Secure Boot)
|
||||||
|
|
||||||
|
## Notable System Configurations
|
||||||
|
|
||||||
### Desktop
|
### Desktop
|
||||||
* [boot.nix](./hosts/desktop/boot.nix)
|
|
||||||
* [configuration.nix](./hosts/desktop/configuration.nix)
|
A powerful AMD-based desktop with gaming capabilities, featuring:
|
||||||
* [hardware-configuration.nix](./hosts/desktop/hardware-configuration.nix)
|
- AMD CPU and GPU optimizations
|
||||||
* [filesystems.nix](./hosts/desktop/filesystems.nix)
|
- Multiple desktop environment options (GNOME, Hyprland, COSMIC)
|
||||||
* [home.nix](./hosts/desktop/home.nix)
|
- Gaming setup with Steam and related tools
|
||||||
* [sops.nix](./hosts/desktop/sops.nix)
|
|
||||||
* [specialisations.hyprland](./hosts/desktop/hyprland)
|
|
||||||
* [specialisations.gnome](./hosts/desktop/gnome)
|
|
||||||
* [specialisations.cosmic](./hosts/desktop/cosmic)
|
|
||||||
|
|
||||||
### NAS
|
### NAS
|
||||||
* [boot.nix](./hosts/nas/boot.nix)
|
|
||||||
* [configuration.nix](./hosts/nas/configuration.nix)
|
|
||||||
* [hardware-configuration.nix](./hosts/nas/hardware-configuration.nix)
|
|
||||||
* [impermenance.nix](./hosts/nas/impermenance.nix)
|
|
||||||
* [apps.nix](./hosts/desktop/apps.nix)
|
|
||||||
* [home.nix](./hosts/desktop/home.nix)
|
|
||||||
* [networking.nix](./hosts/desktop/networking.nix)
|
|
||||||
* [services.nix](./hosts/desktop/services.nix)
|
|
||||||
* [sops.nix](./hosts/desktop/sops.nix)
|
|
||||||
* [ups.nix](./hosts/desktop/ups.nix)
|
|
||||||
* [samba](./modules/samba)
|
|
||||||
* nas-apps
|
|
||||||
* [arrs](./hosts/nas/apps/arrs/default.nix)
|
|
||||||
* [free-games-claimer](./modules/apps/free-games-claimer)
|
|
||||||
* [jackett](./modules/apps/jackett)
|
|
||||||
* [jellyfin](./hosts/nas/apps/jellyfin/default.nix)
|
|
||||||
* [jellyseerr](./hosts/nas/apps/jellyseerr/default.nix)
|
|
||||||
* [jackett](./modules/apps/manyfold)
|
|
||||||
* [mariadb](./modules/apps/mariadb)
|
|
||||||
* [mealie](./modules/apps/mealie)
|
|
||||||
* [nextcloud+onlyoffice](./hosts/nas/apps/nextcloud/default.nix)
|
|
||||||
* [ollama](./hosts/nas/apps/ollama/default.nix)
|
|
||||||
* [paperless](./hosts/nas/apps/paperless/default.nix)
|
|
||||||
* [tdarr](./modules/apps/tdarr)
|
|
||||||
* [traefik](./hosts/nas/apps/traefik/default.nix)
|
|
||||||
* [wireguard](./modules/apps/your-spotify)
|
|
||||||
|
|
||||||
### Raspberry Pi 4
|
A home server with various self-hosted services:
|
||||||
* [configuration.nix](./hosts/pi4/configuration.nix)
|
- Media management (Jellyfin, Jellyseerr)
|
||||||
* [hardware-configuration.nix](./hosts/pi4/hardware-configuration.nix)
|
- Download automation (Sonarr, Radarr, etc.)
|
||||||
|
- Document management (Paperless)
|
||||||
|
- File sharing (Samba, Nextcloud)
|
||||||
|
- AI services (Ollama)
|
||||||
|
|
||||||
|
### Raspberry Pi
|
||||||
|
|
||||||
|
Configurations for both Pi 4 and Pi 5:
|
||||||
|
- Hardware-specific optimizations
|
||||||
|
- Disk partitioning suitable for ARM devices
|
||||||
|
- Bluetooth and wireless support
|
||||||
|
|
||||||
|
### Steam Deck
|
||||||
|
|
||||||
|
Custom NixOS configuration for the Steam Deck:
|
||||||
|
- Integration with Jovian for Steam Deck compatibility
|
||||||
|
- Gaming optimizations
|
||||||
|
- Steam ROM Manager
|
||||||
|
|
||||||
|
### MacBook Pro
|
||||||
|
|
||||||
|
Configurations for both:
|
||||||
|
- NixOS on Apple Silicon
|
||||||
|
- nix-darwin for macOS
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Building a System Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and activate a system configuration
|
||||||
|
sudo nixos-rebuild switch --flake .#hostname
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building a Home Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and activate a home configuration
|
||||||
|
home-manager switch --flake .#username@hostname
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||||
|
|||||||
11
flake.lock
generated
11
flake.lock
generated
@@ -180,16 +180,15 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1742690494,
|
"lastModified": 1755519972,
|
||||||
"narHash": "sha256-SFacEbSRMoTyWG5VXh4ieofJGge+cLq9lH8ifB+zjBg=",
|
"narHash": "sha256-bU4nqi3IpsUZJeyS8Jk85ytlX61i4b0KCxXX9YcOgVc=",
|
||||||
"owner": "nvmd",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "9dc58d4d49c9f74623a06e2fc20cdfd8bb3cbe8b",
|
"rev": "4073ff2f481f9ef3501678ff479ed81402caae6d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nvmd",
|
"owner": "nix-community",
|
||||||
"ref": "gpt-attrs",
|
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,8 @@
|
|||||||
|
|
||||||
disko = {
|
disko = {
|
||||||
# the fork is needed for partition attributes support
|
# the fork is needed for partition attributes support
|
||||||
url = "github:nvmd/disko/gpt-attrs";
|
# url = "github:nvmd/disko/gpt-attrs";
|
||||||
# url = "github:nix-community/disko";
|
url = "github:nix-community/disko";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
let
|
|
||||||
shellAliases = {
|
|
||||||
ll = "ls -alh";
|
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
|
||||||
update-flake = "nix flake update pi4-nixpkgs pi4-home-manager pi4-impermanence pi4-sops-nix pi4-nixos-hardware pi4-nixos-raspberrypi pi4-disko --flake /etc/nixos";
|
|
||||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
|
||||||
nas-ssh = "kitten ssh admin@10.0.1.3";
|
|
||||||
ducks = "du -cksh * | sort -hr | head -n 15";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.username = "matt";
|
home.username = "matt";
|
||||||
|
|
||||||
|
mjallen = {
|
||||||
|
shell-aliases = {
|
||||||
|
enable = true;
|
||||||
|
flakeInputs = [
|
||||||
|
"pi4-nixpkgs"
|
||||||
|
"pi4-home-manager"
|
||||||
|
"pi4-impermanence"
|
||||||
|
"pi4-sops-nix"
|
||||||
|
"pi4-nixos-hardware"
|
||||||
|
"pi4-nixos-raspberrypi"
|
||||||
|
"pi4-disko"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
sops = {
|
sops = {
|
||||||
age.keyFile = "/home/matt/.config/sops/age/keys.txt";
|
age.keyFile = "/home/matt/.config/sops/age/keys.txt";
|
||||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||||
@@ -50,10 +54,13 @@ in
|
|||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
mangohud.enable = lib.mkForce true;
|
mangohud.enable = lib.mkForce true;
|
||||||
zsh.shellAliases = shellAliases;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nextcloud-client.enable = lib.mkForce true;
|
nextcloud-client.enable = lib.mkForce false;
|
||||||
|
kdeconnect = {
|
||||||
|
enable = false;
|
||||||
|
indicator = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,4 +57,12 @@ in
|
|||||||
programs = {
|
programs = {
|
||||||
zsh.shellAliases = shellAliases;
|
zsh.shellAliases = shellAliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
nextcloud-client.enable = false;
|
||||||
|
kdeconnect = {
|
||||||
|
enable = false;
|
||||||
|
indicator = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,4 +15,12 @@ in
|
|||||||
programs = {
|
programs = {
|
||||||
zsh.shellAliases = shellAliases;
|
zsh.shellAliases = shellAliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
nextcloud-client.enable = lib.mkForce false;
|
||||||
|
kdeconnect = {
|
||||||
|
enable = false;
|
||||||
|
indicator = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,27 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
|
||||||
shellAliases = {
|
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10";
|
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
|
||||||
update-flake = "nix flake update nas-nixpkgs nas-authentik-nix nas-cosmic nas-crowdsec nas-home-manager nas-impermanence nas-lanzaboote nas-nixos-hardware nas-sops-nix --flake /etc/nixos";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.username = "admin";
|
home.username = "admin";
|
||||||
|
|
||||||
# mjallen.home.enable = true;
|
# mjallen.home.enable = true;
|
||||||
|
|
||||||
|
mjallen = {
|
||||||
|
shell-aliases = {
|
||||||
|
enable = true;
|
||||||
|
buildHost = ""; # NAS builds locally
|
||||||
|
flakeInputs = [
|
||||||
|
"nas-nixpkgs"
|
||||||
|
"nas-authentik-nix"
|
||||||
|
"nas-cosmic"
|
||||||
|
"nas-crowdsec"
|
||||||
|
"nas-home-manager"
|
||||||
|
"nas-impermanence"
|
||||||
|
"nas-lanzaboote"
|
||||||
|
"nas-nixos-hardware"
|
||||||
|
"nas-sops-nix"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
sops = {
|
sops = {
|
||||||
age.keyFile = "/home/admin/.config/sops/age/keys.txt";
|
age.keyFile = "/home/admin/.config/sops/age/keys.txt";
|
||||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||||
@@ -60,8 +71,6 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
zsh.shellAliases = shellAliases;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# services.nixai = {
|
# services.nixai = {
|
||||||
|
|||||||
@@ -78,6 +78,6 @@ in
|
|||||||
mgba
|
mgba
|
||||||
prismlauncher
|
prismlauncher
|
||||||
ryujinx-greemdev
|
ryujinx-greemdev
|
||||||
vmware-horizon-client
|
omnissa-horizon-client
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
|
||||||
shellAliases = {
|
|
||||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
|
||||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
|
||||||
update-flake = "nix flake update desktop-nixpkgs desktop-chaotic desktop-home-manager desktop-impermanence desktop-lanzaboote desktop-nixos-hardware desktop-sops-nix desktop-steam-rom-manager --flake /etc/nixos";
|
|
||||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.username = "matt";
|
home.username = "matt";
|
||||||
|
|
||||||
@@ -14,6 +6,19 @@ in
|
|||||||
sops = {
|
sops = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
shell-aliases = {
|
||||||
|
enable = true;
|
||||||
|
flakeInputs = [
|
||||||
|
"desktop-nixpkgs"
|
||||||
|
"desktop-chaotic"
|
||||||
|
"desktop-home-manager"
|
||||||
|
"desktop-impermanence"
|
||||||
|
"desktop-lanzaboote"
|
||||||
|
"desktop-nixos-hardware"
|
||||||
|
"desktop-sops-nix"
|
||||||
|
"desktop-steam-rom-manager"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
@@ -25,8 +30,6 @@ in
|
|||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
password-store.enable = true;
|
password-store.enable = true;
|
||||||
|
|
||||||
zsh.shellAliases = shellAliases;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
|||||||
@@ -292,7 +292,8 @@ in
|
|||||||
"tag +waydroid, class:([Ww]aydroid.*)"
|
"tag +waydroid, class:([Ww]aydroid.*)"
|
||||||
"float, tag:waydroid"
|
"float, tag:waydroid"
|
||||||
"pin, tag:waydroid"
|
"pin, tag:waydroid"
|
||||||
] ++ cfg.windowRule;
|
]
|
||||||
|
++ cfg.windowRule;
|
||||||
|
|
||||||
plugin = {
|
plugin = {
|
||||||
touch_gestures = {
|
touch_gestures = {
|
||||||
@@ -395,16 +396,15 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig =
|
extraConfig = ''
|
||||||
''
|
exec-once = dbus-update-activation-environment --systemd --all
|
||||||
exec-once = dbus-update-activation-environment --systemd --all
|
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
||||||
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
exec-once = xhost +SI:localuser:root
|
||||||
exec-once = xhost +SI:localuser:root
|
exec-once = nwg-look -a
|
||||||
exec-once = nwg-look -a
|
exec-once = nwg-dock-hyprland -d
|
||||||
exec-once = nwg-dock-hyprland -d
|
''
|
||||||
''
|
+ cfg.extraConfig or '''';
|
||||||
+ cfg.extraConfig or '''';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
programs.hyprlock = {
|
programs.hyprlock = {
|
||||||
enable = false;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
background = [
|
background = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,10 +52,14 @@
|
|||||||
nh = {
|
nh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
flake = "/etc/nixos";
|
flake = "/etc/nixos";
|
||||||
|
clean = {
|
||||||
|
enable = true;
|
||||||
|
extraArgs = "--keep 5";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
micro = {
|
micro = {
|
||||||
enable = true;
|
enable = lib.mkDefault true;
|
||||||
settings = {
|
settings = {
|
||||||
autoindent = true;
|
autoindent = true;
|
||||||
autosu = true;
|
autosu = true;
|
||||||
@@ -66,7 +70,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
tmux = {
|
tmux = {
|
||||||
enable = true;
|
enable = lib.mkDefault true;
|
||||||
terminal = "screen-256color";
|
terminal = "screen-256color";
|
||||||
sensibleOnTop = true;
|
sensibleOnTop = true;
|
||||||
focusEvents = true;
|
focusEvents = true;
|
||||||
@@ -109,8 +113,8 @@
|
|||||||
nextcloud-client.enable = lib.mkDefault true;
|
nextcloud-client.enable = lib.mkDefault true;
|
||||||
pass-secret-service.enable = lib.mkDefault true;
|
pass-secret-service.enable = lib.mkDefault true;
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = true;
|
enable = lib.mkDefault true;
|
||||||
indicator = true;
|
indicator = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
system,
|
system,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
@@ -9,6 +10,7 @@ let
|
|||||||
x86_only = with pkgs; [
|
x86_only = with pkgs; [
|
||||||
vscode-extensions.redhat.vscode-xml
|
vscode-extensions.redhat.vscode-xml
|
||||||
];
|
];
|
||||||
|
open-remote-ssh = pkgs.${namespace}.open-remote-ssh;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
programs = {
|
programs = {
|
||||||
@@ -39,7 +41,7 @@ in
|
|||||||
|
|
||||||
# open-remote-ssh
|
# open-remote-ssh
|
||||||
# nix-vscode-extensions.open-vsx.jeanp413.open-remote-ssh
|
# nix-vscode-extensions.open-vsx.jeanp413.open-remote-ssh
|
||||||
# open-vsx.jeanp413.open-remote-ssh
|
open-remote-ssh
|
||||||
]
|
]
|
||||||
++ (if !isArm then x86_only else [ ])
|
++ (if !isArm then x86_only else [ ])
|
||||||
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
|
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
|
||||||
@@ -138,6 +140,8 @@ in
|
|||||||
"*.db" = "default";
|
"*.db" = "default";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"enable-proposed-api" = [ "jeanp413.open-remote-ssh" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ in
|
|||||||
"custom/right-end"
|
"custom/right-end"
|
||||||
];
|
];
|
||||||
|
|
||||||
# modules-right = [
|
# modules-right = [
|
||||||
# "tray"
|
# "tray"
|
||||||
# "custom/left-end" ] ++
|
# "custom/left-end" ] ++
|
||||||
# cfg.modules-right ++
|
# cfg.modules-right ++
|
||||||
# [ "custom/right-end" ];
|
# [ "custom/right-end" ];
|
||||||
|
|
||||||
@@ -323,262 +323,262 @@ in
|
|||||||
format = " ";
|
format = " ";
|
||||||
tooltip = false;
|
tooltip = false;
|
||||||
};
|
};
|
||||||
} // cfg.extraModules;
|
}
|
||||||
|
// cfg.extraModules;
|
||||||
};
|
};
|
||||||
|
|
||||||
# * { font-size: 13px; }
|
# * { font-size: 13px; }
|
||||||
# window.eDP-1 * { font-size: 10px; }
|
# window.eDP-1 * { font-size: 10px; }
|
||||||
|
|
||||||
style =
|
style = ''
|
||||||
''
|
.blink_me {
|
||||||
.blink_me {
|
animation: blinker 1s linear infinite;
|
||||||
animation: blinker 1s linear infinite;
|
}
|
||||||
|
|
||||||
|
@keyframes blinker {
|
||||||
|
50% {
|
||||||
|
color: ${nord.aurora.nord11};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes blinker {
|
* {
|
||||||
50% {
|
font-family:
|
||||||
color: ${nord.aurora.nord11};
|
Jetbrains Mono Nerd Font,
|
||||||
}
|
monospace;
|
||||||
}
|
font-size: 14px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
#waybar {
|
||||||
font-family:
|
background: transparent;
|
||||||
Jetbrains Mono Nerd Font,
|
color: ${nord.snowStorm.nord6};
|
||||||
monospace;
|
margin: 5px 5px;
|
||||||
font-size: 14px;
|
}
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#waybar {
|
#workspaces {
|
||||||
background: transparent;
|
background-color: ${nord.polarNight.nord0};
|
||||||
color: ${nord.snowStorm.nord6};
|
${defaultBorderRadius}
|
||||||
margin: 5px 5px;
|
${defaultOpacity}
|
||||||
}
|
${defaultCenterOptions}
|
||||||
|
margin-left: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
#workspaces {
|
#workspaces button {
|
||||||
background-color: ${nord.polarNight.nord0};
|
color: ${nord.frost.nord10};
|
||||||
${defaultBorderRadius}
|
${defaultBorderRadius}
|
||||||
${defaultOpacity}
|
padding: 0.4rem;
|
||||||
${defaultCenterOptions}
|
}
|
||||||
margin-left: 0.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button {
|
#workspaces button.active {
|
||||||
color: ${nord.frost.nord10};
|
color: ${nord.frost.nord8};
|
||||||
${defaultBorderRadius}
|
${defaultBorderRadius}
|
||||||
padding: 0.4rem;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.active {
|
#workspaces button:hover {
|
||||||
color: ${nord.frost.nord8};
|
color: ${nord.frost.nord7};
|
||||||
${defaultBorderRadius}
|
${defaultBorderRadius}
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspaces button:hover {
|
#workspaces button.focused {
|
||||||
color: ${nord.frost.nord7};
|
color: ${nord.snowStorm.nord6};
|
||||||
${defaultBorderRadius}
|
background: ${nord.aurora.nord13};
|
||||||
}
|
${defaultBorderRadius}
|
||||||
|
}
|
||||||
|
|
||||||
#workspaces button.focused {
|
#workspaces button.urgent {
|
||||||
color: ${nord.snowStorm.nord6};
|
color: ${nord.polarNight.nord0};
|
||||||
background: ${nord.aurora.nord13};
|
background: ${nord.snowStorm.nord6};
|
||||||
${defaultBorderRadius}
|
${defaultBorderRadius}
|
||||||
}
|
}
|
||||||
|
|
||||||
#workspaces button.urgent {
|
#tooltip {
|
||||||
color: ${nord.polarNight.nord0};
|
background: ${nord.polarNight.nord0};
|
||||||
background: ${nord.snowStorm.nord6};
|
border-color: ${nord.polarNight.nord0};
|
||||||
${defaultBorderRadius}
|
${defaultBorderRadius}
|
||||||
}
|
border-width: 1rem;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
#tooltip {
|
#window {
|
||||||
background: ${nord.polarNight.nord0};
|
color: ${nord.aurora.nord15};
|
||||||
border-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultBorderRadius}
|
${defaultOpacity}
|
||||||
border-width: 1rem;
|
${defaultBorderRadius}
|
||||||
border-style: solid;
|
${defaultCenterOptions}
|
||||||
}
|
margin-left: 4rem;
|
||||||
|
margin-right: ${toString cfg.windowOffset}rem;
|
||||||
|
}
|
||||||
|
|
||||||
#window {
|
/* make window module transparent when no windows present */
|
||||||
color: ${nord.aurora.nord15};
|
#window.empty {
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: transparent;
|
||||||
${defaultOpacity}
|
}
|
||||||
${defaultBorderRadius}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
margin-left: 4rem;
|
|
||||||
margin-right: ${toString cfg.windowOffset}rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make window module transparent when no windows present */
|
#custom-weather {
|
||||||
#window.empty {
|
color: ${nord.frost.nord10};
|
||||||
background-color: transparent;
|
background-color: ${nord.polarNight.nord0};
|
||||||
}
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#custom-weather {
|
#battery {
|
||||||
color: ${nord.frost.nord10};
|
color: ${nord.aurora.nord15};
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultOpacity}
|
${defaultOpacity}
|
||||||
${defaultCenterOptions}
|
${defaultCenterOptions}
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
min-width: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
#battery {
|
#clock {
|
||||||
color: ${nord.aurora.nord15};
|
color: ${nord.frost.nord9};
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultOpacity}
|
${defaultOpacity}
|
||||||
${defaultCenterOptions}
|
${defaultCenterOptions}
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
min-width: 3rem;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#clock {
|
/* ------------- */
|
||||||
color: ${nord.frost.nord9};
|
|
||||||
background-color: ${nord.polarNight.nord0};
|
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------- */
|
#idle_inhibitor {
|
||||||
|
color: ${nord.frost.nord10};
|
||||||
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
#idle_inhibitor {
|
#idle_inhibitor:hover {
|
||||||
color: ${nord.frost.nord10};
|
background: ${nord.polarNight.nord3};
|
||||||
background-color: ${nord.polarNight.nord0};
|
}
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0;
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#idle_inhibitor:hover {
|
#network {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.aurora.nord15};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
#network {
|
#network:hover {
|
||||||
color: ${nord.aurora.nord15};
|
background: ${nord.polarNight.nord3};
|
||||||
background-color: ${nord.polarNight.nord0};
|
}
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0;
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#network:hover {
|
#bluetooth {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.frost.nord9};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#bluetooth {
|
#bluetooth:hover {
|
||||||
color: ${nord.frost.nord9};
|
background: ${nord.polarNight.nord3};
|
||||||
background-color: ${nord.polarNight.nord0};
|
}
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bluetooth:hover {
|
#wireplumber.source {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.frost.nord8};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#wireplumber.source {
|
#wireplumber.source.muted {
|
||||||
color: ${nord.frost.nord8};
|
animation-name: blinker;
|
||||||
background-color: ${nord.polarNight.nord0};
|
animation-duration: 2s;
|
||||||
${defaultOpacity}
|
animation-timing-function: linear;
|
||||||
${defaultCenterOptions}
|
animation-iteration-count: infinite;
|
||||||
border-radius: 0;
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wireplumber.source.muted {
|
#wireplumber.source:hover {
|
||||||
animation-name: blinker;
|
background: ${nord.polarNight.nord3};
|
||||||
animation-duration: 2s;
|
}
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wireplumber.source:hover {
|
#wireplumber.sink {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.frost.nord7};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#wireplumber.sink {
|
#wireplumber.sink.muted {
|
||||||
color: ${nord.frost.nord7};
|
animation-name: blinker;
|
||||||
background-color: ${nord.polarNight.nord0};
|
animation-duration: 5s;
|
||||||
${defaultOpacity}
|
animation-timing-function: linear;
|
||||||
${defaultCenterOptions}
|
animation-iteration-count: infinite;
|
||||||
border-radius: 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#wireplumber.sink.muted {
|
#wireplumber.sink:hover {
|
||||||
animation-name: blinker;
|
background: ${nord.polarNight.nord3};
|
||||||
animation-duration: 5s;
|
}
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wireplumber.sink:hover {
|
#keyboard-state.numlock {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.frost.nord8};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#keyboard-state.numlock {
|
#keyboard-state.capslock {
|
||||||
color: ${nord.frost.nord8};
|
color: ${nord.frost.nord9};
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultOpacity}
|
${defaultOpacity}
|
||||||
${defaultCenterOptions}
|
${defaultCenterOptions}
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#keyboard-state.capslock {
|
#temperature.gpu {
|
||||||
color: ${nord.frost.nord9};
|
color: ${nord.frost.nord10};
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultOpacity}
|
${defaultOpacity}
|
||||||
${defaultCenterOptions}
|
${defaultCenterOptions}
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#temperature.gpu {
|
#temperature.gpu:hover {
|
||||||
color: ${nord.frost.nord10};
|
background: ${nord.polarNight.nord3};
|
||||||
background-color: ${nord.polarNight.nord0};
|
}
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#temperature.gpu:hover {
|
#temperature {
|
||||||
background: ${nord.polarNight.nord3};
|
color: ${nord.frost.nord9};
|
||||||
}
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
#temperature {
|
/* ------------- */
|
||||||
color: ${nord.frost.nord9};
|
|
||||||
background-color: ${nord.polarNight.nord0};
|
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
border-radius: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------- */
|
#tray {
|
||||||
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${defaultCenterOptions}
|
||||||
|
${defaultBorderRadius}
|
||||||
|
margin-right: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
#tray {
|
/* ------------- */
|
||||||
background-color: ${nord.polarNight.nord0};
|
|
||||||
${defaultOpacity}
|
|
||||||
${defaultCenterOptions}
|
|
||||||
${defaultBorderRadius}
|
|
||||||
margin-right: 0.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------- */
|
#custom-left-end {
|
||||||
|
background-color: ${nord.polarNight.nord0};
|
||||||
|
${defaultOpacity}
|
||||||
|
${borderLeft}
|
||||||
|
}
|
||||||
|
|
||||||
#custom-left-end {
|
#custom-right-end {
|
||||||
background-color: ${nord.polarNight.nord0};
|
background-color: ${nord.polarNight.nord0};
|
||||||
${defaultOpacity}
|
${defaultOpacity}
|
||||||
${borderLeft}
|
${borderRight}
|
||||||
}
|
}
|
||||||
|
''
|
||||||
#custom-right-end {
|
+ cfg.extraModulesStyle or '''';
|
||||||
background-color: ${nord.polarNight.nord0};
|
|
||||||
${defaultOpacity}
|
|
||||||
${borderRight}
|
|
||||||
}
|
|
||||||
''
|
|
||||||
+ cfg.extraModulesStyle or '''';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
57
modules/home/shell-aliases/default.nix
Normal file
57
modules/home/shell-aliases/default.nix
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.mjallen.shell-aliases;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mjallen.shell-aliases = {
|
||||||
|
enable = lib.mkEnableOption "Common shell aliases";
|
||||||
|
|
||||||
|
buildHost = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "admin@10.0.1.3";
|
||||||
|
description = "Build host for nixos-rebuild commands";
|
||||||
|
};
|
||||||
|
|
||||||
|
flakeInputs = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of flake inputs to update";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraAliases = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Additional host-specific aliases";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.zsh.shellAliases = {
|
||||||
|
# Common file operations
|
||||||
|
ll = "ls -alh";
|
||||||
|
ducks = "du -cksh * | sort -hr | head -n 15";
|
||||||
|
|
||||||
|
# NixOS rebuild commands
|
||||||
|
update-boot =
|
||||||
|
"sudo nixos-rebuild boot --max-jobs 10"
|
||||||
|
+ lib.optionalString (cfg.buildHost != "") " --build-host ${cfg.buildHost}";
|
||||||
|
update-switch =
|
||||||
|
"sudo nixos-rebuild switch --max-jobs 10"
|
||||||
|
+ lib.optionalString (cfg.buildHost != "") " --build-host ${cfg.buildHost}";
|
||||||
|
|
||||||
|
# Flake update command
|
||||||
|
update-flake = lib.mkIf (
|
||||||
|
cfg.flakeInputs != [ ]
|
||||||
|
) "nix flake update ${lib.concatStringsSep " " cfg.flakeInputs} --flake /etc/nixos";
|
||||||
|
|
||||||
|
# NAS management
|
||||||
|
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||||
|
nas-ssh = "kitten ssh admin@10.0.1.3";
|
||||||
|
}
|
||||||
|
// cfg.extraAliases;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -65,20 +65,19 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
home = {
|
home = {
|
||||||
file =
|
file = {
|
||||||
{
|
"Desktop/.keep".text = "";
|
||||||
"Desktop/.keep".text = "";
|
"Documents/.keep".text = "";
|
||||||
"Documents/.keep".text = "";
|
"Downloads/.keep".text = "";
|
||||||
"Downloads/.keep".text = "";
|
"Music/.keep".text = "";
|
||||||
"Music/.keep".text = "";
|
"Pictures/.keep".text = "";
|
||||||
"Pictures/.keep".text = "";
|
"Videos/.keep".text = "";
|
||||||
"Videos/.keep".text = "";
|
}
|
||||||
}
|
// lib.optionalAttrs (cfg.icon != null) {
|
||||||
// lib.optionalAttrs (cfg.icon != null) {
|
".face".source = cfg.icon;
|
||||||
".face".source = cfg.icon;
|
".face.icon".source = cfg.icon;
|
||||||
".face.icon".source = cfg.icon;
|
"Pictures/${cfg.icon.fileName or (builtins.baseNameOf cfg.icon)}".source = cfg.icon;
|
||||||
"Pictures/${cfg.icon.fileName or (builtins.baseNameOf cfg.icon)}".source = cfg.icon;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
homeDirectory = mkDefault cfg.home;
|
homeDirectory = mkDefault cfg.home;
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.actual;
|
cfg = config.${namespace}.services.actual;
|
||||||
dataDir = "/data";
|
dataDir = "/data";
|
||||||
hostAddress = "10.0.1.3";
|
hostAddress = "10.0.1.3";
|
||||||
actualUserId = config.users.users.nix-apps.uid;
|
actualUserId = config.users.users.nix-apps.uid;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.actual = {
|
options.${namespace}.services.actual = {
|
||||||
enable = mkEnableOption "actual service";
|
enable = mkEnableOption "actual service";
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.free-games-claimer;
|
cfg = config.${namespace}.services.free-games-claimer;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.free-games-claimer = {
|
options.${namespace}.services.free-games-claimer = {
|
||||||
enable = mkEnableOption "free-games-claimer docker service";
|
enable = mkEnableOption "free-games-claimer docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.manyfold;
|
cfg = config.${namespace}.services.manyfold;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.manyfold = {
|
options.${namespace}.services.manyfold = {
|
||||||
enable = mkEnableOption "manyfold docker service";
|
enable = mkEnableOption "manyfold docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.mongodb;
|
cfg = config.${namespace}.services.mongodb;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.mongodb = {
|
options.${namespace}.services.mongodb = {
|
||||||
enable = mkEnableOption "mongodb docker service";
|
enable = mkEnableOption "mongodb docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.tdarr;
|
cfg = config.${namespace}.services.tdarr;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.tdarr = {
|
options.${namespace}.services.tdarr = {
|
||||||
enable = mkEnableOption "tdarr docker service";
|
enable = mkEnableOption "tdarr docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.your_spotify;
|
cfg = config.${namespace}.services.your_spotify;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.your_spotify = {
|
options.${namespace}.services.your_spotify = {
|
||||||
enable = mkEnableOption "your_spotify docker service";
|
enable = mkEnableOption "your_spotify docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.arrs;
|
cfg = config.${namespace}.services.arrs;
|
||||||
radarrDataDir = "/var/lib/radarr";
|
radarrDataDir = "/var/lib/radarr";
|
||||||
downloadDir = "/downloads";
|
downloadDir = "/downloads";
|
||||||
incompleteDir = "/downloads-incomplete";
|
incompleteDir = "/downloads-incomplete";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.arrs = {
|
options.${namespace}.services.arrs = {
|
||||||
enable = mkEnableOption "arrs services";
|
enable = mkEnableOption "arrs services";
|
||||||
|
|
||||||
radarr = {
|
radarr = {
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.crowdsec;
|
cfg = config.${namespace}.services.crowdsec;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.crowdsec = {
|
options.${namespace}.services.crowdsec = {
|
||||||
enable = mkEnableOption "crowdsec service";
|
enable = mkEnableOption "crowdsec service";
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ in
|
|||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
kdeconnect = {
|
kdeconnect = {
|
||||||
enable = true;
|
enable = lib.mkDefault true;
|
||||||
package = pkgs.gnomeExtensions.gsconnect;
|
package = pkgs.gnomeExtensions.gsconnect;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
92
modules/nixos/development/default.nix
Normal file
92
modules/nixos/development/default.nix
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.development;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.${namespace}.development = {
|
||||||
|
enable = lib.mkEnableOption "Common development tools and packages";
|
||||||
|
|
||||||
|
includeLanguages = lib.mkOption {
|
||||||
|
type = lib.types.listOf (
|
||||||
|
lib.types.enum [
|
||||||
|
"python"
|
||||||
|
"c"
|
||||||
|
"rust"
|
||||||
|
"nodejs"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
default = [
|
||||||
|
"python"
|
||||||
|
"c"
|
||||||
|
];
|
||||||
|
description = "Programming languages to include tools for";
|
||||||
|
};
|
||||||
|
|
||||||
|
includeContainers = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Include container development tools";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages =
|
||||||
|
with pkgs;
|
||||||
|
[
|
||||||
|
# Version control
|
||||||
|
git
|
||||||
|
|
||||||
|
# Build tools
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
binutils
|
||||||
|
|
||||||
|
# System utilities
|
||||||
|
jq
|
||||||
|
|
||||||
|
# Text processing
|
||||||
|
|
||||||
|
]
|
||||||
|
++ lib.optionals (builtins.elem "python" cfg.includeLanguages) [
|
||||||
|
python3
|
||||||
|
python3Packages.pip
|
||||||
|
]
|
||||||
|
++ lib.optionals (builtins.elem "c" cfg.includeLanguages) [
|
||||||
|
gcc
|
||||||
|
gdb
|
||||||
|
]
|
||||||
|
++ lib.optionals (builtins.elem "rust" cfg.includeLanguages) [
|
||||||
|
rustc
|
||||||
|
cargo
|
||||||
|
]
|
||||||
|
++ lib.optionals (builtins.elem "nodejs" cfg.includeLanguages) [
|
||||||
|
nodejs
|
||||||
|
npm
|
||||||
|
]
|
||||||
|
++ lib.optionals cfg.includeContainers [
|
||||||
|
docker-compose
|
||||||
|
podman-compose
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable container support if requested
|
||||||
|
virtualisation.podman = lib.mkIf cfg.includeContainers {
|
||||||
|
enable = true;
|
||||||
|
dockerCompat = true;
|
||||||
|
autoPrune.enable = true;
|
||||||
|
defaultNetwork.settings = {
|
||||||
|
dns_enabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Common development programs
|
||||||
|
programs = {
|
||||||
|
nix-ld.enable = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,23 +2,78 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
system,
|
system,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
cfg = config.${namespace}.hardware.disko;
|
||||||
isArm = builtins.match "aarch64*" system != null;
|
isArm = builtins.match "aarch64*" system != null;
|
||||||
rootDisk = "/dev/nvme0n1";
|
rootDisk = "/dev/nvme0n1";
|
||||||
|
|
||||||
|
# BTRFS root partition configuration
|
||||||
|
btrfsRoot = {
|
||||||
|
name = "btrfs-root";
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-f" ]; # Override existing partition
|
||||||
|
# Subvolumes must set a mountpoint in order to be mounted,
|
||||||
|
# unless their parent is mounted
|
||||||
|
subvolumes = {
|
||||||
|
"home" = {
|
||||||
|
mountOptions = [ "compress=zstd" ];
|
||||||
|
mountpoint = "/home";
|
||||||
|
};
|
||||||
|
"root" = {
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
mountpoint = "/root";
|
||||||
|
};
|
||||||
|
"nix" = {
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
mountpoint = "/nix";
|
||||||
|
};
|
||||||
|
"etc" = {
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
mountpoint = "/etc";
|
||||||
|
};
|
||||||
|
"log" = {
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
mountpoint = "/var/log";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# BCacheFS root partition configuration
|
||||||
|
bcachefsRoot = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "bcachefs";
|
||||||
|
# This refers to a filesystem in the `bcachefs_filesystems` attrset below.
|
||||||
|
filesystem = "mounted_subvolumes_in_multi";
|
||||||
|
label = "ssd.ssd1";
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--discard"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf isArm {
|
imports = [ ../options.nix ];
|
||||||
|
config = lib.mkIf (isArm && cfg.enable) {
|
||||||
disko.devices = {
|
disko.devices = {
|
||||||
nodev."/" = {
|
|
||||||
fsType = "tmpfs";
|
|
||||||
mountOptions = [
|
|
||||||
"mode=755"
|
|
||||||
"defaults"
|
|
||||||
"size=2G"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
# root disk setup
|
# root disk setup
|
||||||
disk.main = {
|
disk.main = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
@@ -58,58 +113,33 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
root = {
|
root = if cfg.filesystem == "btrfs" then btrfsRoot else bcachefsRoot;
|
||||||
name = "btrfs-root";
|
};
|
||||||
size = "100%";
|
};
|
||||||
content = {
|
};
|
||||||
type = "btrfs";
|
|
||||||
extraArgs = [ "-f" ]; # Override existing partition
|
bcachefs_filesystems = lib.mkIf (cfg.filesystem == "bcachefs") {
|
||||||
# Subvolumes must set a mountpoint in order to be mounted,
|
mounted_subvolumes_in_multi = {
|
||||||
# unless their parent is mounted
|
type = "bcachefs_filesystem";
|
||||||
subvolumes = {
|
# passwordFile = "/etc/nixos/pool.jwe";
|
||||||
"home" = {
|
extraFormatArgs = [
|
||||||
mountOptions = [ "compress=zstd" ];
|
"--compression=zstd"
|
||||||
mountpoint = "/home";
|
];
|
||||||
};
|
subvolumes = {
|
||||||
"root" = {
|
"/root" = {
|
||||||
mountOptions = [
|
mountpoint = "/";
|
||||||
"compress=zstd"
|
};
|
||||||
"noatime"
|
"/persistent" = {
|
||||||
];
|
mountpoint = "/persistent";
|
||||||
mountpoint = "/root";
|
};
|
||||||
};
|
"/nix" = {
|
||||||
"nix" = {
|
mountOptions = [
|
||||||
mountOptions = [
|
"noatime"
|
||||||
"compress=zstd"
|
];
|
||||||
"noatime"
|
mountpoint = "/nix";
|
||||||
];
|
|
||||||
mountpoint = "/nix";
|
|
||||||
};
|
|
||||||
"etc" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/etc";
|
|
||||||
};
|
|
||||||
"tmp" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/tmp";
|
|
||||||
};
|
|
||||||
"log" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/var/log";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
mountpoint = "/partition-root";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,5 +3,13 @@ with lib;
|
|||||||
{
|
{
|
||||||
options.${namespace}.hardware.disko = {
|
options.${namespace}.hardware.disko = {
|
||||||
enable = mkEnableOption "enable disko";
|
enable = mkEnableOption "enable disko";
|
||||||
|
filesystem = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"bcachefs"
|
||||||
|
"btrfs"
|
||||||
|
];
|
||||||
|
default = "btrfs";
|
||||||
|
description = "Filesystem to use for the root partition";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,91 +9,134 @@ let
|
|||||||
cfg = config.${namespace}.hardware.disko;
|
cfg = config.${namespace}.hardware.disko;
|
||||||
isArm = builtins.match "aarch64*" system != null;
|
isArm = builtins.match "aarch64*" system != null;
|
||||||
rootDisk = "/dev/nvme0n1";
|
rootDisk = "/dev/nvme0n1";
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ../options.nix ];
|
|
||||||
|
|
||||||
config = lib.mkIf (cfg.enable && !isArm) {
|
# BTRFS root partition configuration
|
||||||
disko.devices = {
|
btrfsRoot = {
|
||||||
nodev."/" = {
|
name = "btrfs-root";
|
||||||
fsType = "tmpfs";
|
size = "100%";
|
||||||
mountOptions = [
|
content = {
|
||||||
"mode=755"
|
type = "btrfs";
|
||||||
"defaults"
|
extraArgs = [ "-f" ]; # Override existing partition
|
||||||
"size=25%"
|
# Subvolumes must set a mountpoint in order to be mounted,
|
||||||
];
|
# unless their parent is mounted
|
||||||
};
|
subvolumes = {
|
||||||
# root disk setup
|
"home" = {
|
||||||
disk.main = {
|
mountOptions = [ "compress=zstd" ];
|
||||||
type = "disk";
|
mountpoint = "/home";
|
||||||
device = rootDisk;
|
};
|
||||||
imageSize = "32G";
|
"root" = {
|
||||||
content = {
|
mountOptions = [
|
||||||
type = "gpt";
|
"compress=zstd"
|
||||||
# specify partitions
|
"noatime"
|
||||||
partitions = {
|
];
|
||||||
# /boot
|
mountpoint = "/root";
|
||||||
ESP = {
|
};
|
||||||
priority = 1;
|
"nix" = {
|
||||||
name = "ESP";
|
mountOptions = [
|
||||||
start = "1M";
|
"compress=zstd"
|
||||||
end = "1G";
|
"noatime"
|
||||||
type = "EF00";
|
];
|
||||||
content = {
|
mountpoint = "/nix";
|
||||||
type = "filesystem";
|
};
|
||||||
format = "vfat";
|
"etc" = {
|
||||||
mountpoint = "/boot";
|
mountOptions = [
|
||||||
mountOptions = [ "umask=0077" ];
|
"compress=zstd"
|
||||||
};
|
"noatime"
|
||||||
};
|
];
|
||||||
|
mountpoint = "/etc";
|
||||||
root = {
|
};
|
||||||
name = "btrfs-root";
|
"log" = {
|
||||||
size = "100%";
|
mountOptions = [
|
||||||
content = {
|
"compress=zstd"
|
||||||
type = "btrfs";
|
"noatime"
|
||||||
extraArgs = [ "-f" ]; # Override existing partition
|
];
|
||||||
# Subvolumes must set a mountpoint in order to be mounted,
|
mountpoint = "/var/log";
|
||||||
# unless their parent is mounted
|
|
||||||
subvolumes = {
|
|
||||||
"home" = {
|
|
||||||
mountOptions = [ "compress=zstd" ];
|
|
||||||
mountpoint = "/home";
|
|
||||||
};
|
|
||||||
"root" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/root";
|
|
||||||
};
|
|
||||||
"nix" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/nix";
|
|
||||||
};
|
|
||||||
"etc" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/etc";
|
|
||||||
};
|
|
||||||
"log" = {
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
mountpoint = "/var/log";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# BCacheFS root partition configuration
|
||||||
|
bcachefsRoot = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "bcachefs";
|
||||||
|
# This refers to a filesystem in the `bcachefs_filesystems` attrset below.
|
||||||
|
filesystem = "mounted_subvolumes_in_multi";
|
||||||
|
label = "ssd.ssd1";
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--discard"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../options.nix ];
|
||||||
|
config = lib.mkIf (!isArm && cfg.enable) {
|
||||||
|
disko.devices = lib.mkMerge [
|
||||||
|
{
|
||||||
|
disk = {
|
||||||
|
main = {
|
||||||
|
device = rootDisk;
|
||||||
|
type = "disk";
|
||||||
|
imageSize = "32G";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
type = "EF00";
|
||||||
|
size = "100M";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
root = if cfg.filesystem == "btrfs" then btrfsRoot else bcachefsRoot;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
bcachefs_filesystems = lib.mkIf (cfg.filesystem == "bcachefs") {
|
||||||
|
mounted_subvolumes_in_multi = {
|
||||||
|
type = "bcachefs_filesystem";
|
||||||
|
# passwordFile = "/etc/nixos/pool.jwe";
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--compression=zstd"
|
||||||
|
];
|
||||||
|
subvolumes = {
|
||||||
|
"subvolumes/root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"verbose"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"subvolumes/persistent" = {
|
||||||
|
mountpoint = "/persistent";
|
||||||
|
};
|
||||||
|
"subvolumes/nix" = {
|
||||||
|
mountOptions = [
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
mountpoint = "/nix";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(lib.mkIf (cfg.filesystem == "btrfs") {
|
||||||
|
nodev."/" = {
|
||||||
|
fsType = "tmpfs";
|
||||||
|
mountOptions = [
|
||||||
|
"mode=755"
|
||||||
|
"defaults"
|
||||||
|
"size=25%"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
{ config, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.gitea;
|
cfg = config.${namespace}.services.gitea;
|
||||||
hostAddress = "10.0.1.3";
|
hostAddress = "10.0.1.3";
|
||||||
# localAddress = "10.0.4.18";
|
# localAddress = "10.0.4.18";
|
||||||
# httpPort = 3000;
|
# httpPort = 3000;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.gitea = {
|
options.${namespace}.services.gitea = {
|
||||||
enable = mkEnableOption "gitea service";
|
enable = mkEnableOption "gitea service";
|
||||||
|
|
||||||
httpPort = mkOption {
|
httpPort = mkOption {
|
||||||
|
|||||||
@@ -9,21 +9,6 @@ let
|
|||||||
cfg = config.${namespace}.services.home-assistant;
|
cfg = config.${namespace}.services.home-assistant;
|
||||||
mosquittoPort = 1883;
|
mosquittoPort = 1883;
|
||||||
zigbee2mqttPort = 8080;
|
zigbee2mqttPort = 8080;
|
||||||
|
|
||||||
# In configuration.nix or a separate file
|
|
||||||
python-steam = pkgs.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "steam";
|
|
||||||
version = "1.4.4";
|
|
||||||
pyproject = false;
|
|
||||||
src = pkgs.fetchPypi {
|
|
||||||
inherit pname version;
|
|
||||||
sha256 = "sha256-K1vWkRwNSnMS9EG40WK52NR8i+u478bIhnOTsDI/pS4=";
|
|
||||||
};
|
|
||||||
|
|
||||||
buildInputs = with pkgs.python3Packages; [ setuptools ];
|
|
||||||
|
|
||||||
doCheck = false; # no tests in the PyPI tarball
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
@@ -66,6 +51,7 @@ in
|
|||||||
"nws"
|
"nws"
|
||||||
"ollama"
|
"ollama"
|
||||||
"onedrive"
|
"onedrive"
|
||||||
|
"open_router"
|
||||||
"ping"
|
"ping"
|
||||||
"radio_browser"
|
"radio_browser"
|
||||||
"samsungtv"
|
"samsungtv"
|
||||||
@@ -198,7 +184,7 @@ in
|
|||||||
gehomesdk
|
gehomesdk
|
||||||
onedrive-personal-sdk
|
onedrive-personal-sdk
|
||||||
python-roborock
|
python-roborock
|
||||||
python-steam
|
pkgs.${namespace}.python-steam
|
||||||
apple-weatherkit
|
apple-weatherkit
|
||||||
|
|
||||||
samsungctl
|
samsungctl
|
||||||
@@ -234,7 +220,7 @@ in
|
|||||||
trusted_proxies = [
|
trusted_proxies = [
|
||||||
"172.30.33.0/24"
|
"172.30.33.0/24"
|
||||||
"10.0.1.4"
|
"10.0.1.4"
|
||||||
"10.0.4.2"
|
"10.0.1.3"
|
||||||
"10.0.1.18"
|
"10.0.1.18"
|
||||||
"10.0.1.0/24"
|
"10.0.1.0/24"
|
||||||
];
|
];
|
||||||
@@ -256,7 +242,7 @@ in
|
|||||||
openhasp = {
|
openhasp = {
|
||||||
plate = {
|
plate = {
|
||||||
objects = [
|
objects = [
|
||||||
{
|
{
|
||||||
obj = "p0b1"; # temperature label on all pages
|
obj = "p0b1"; # temperature label on all pages
|
||||||
properties = {
|
properties = {
|
||||||
"text" = ''{{ states("sensor.thermostat_current_temperature") }}°F'';
|
"text" = ''{{ states("sensor.thermostat_current_temperature") }}°F'';
|
||||||
@@ -265,8 +251,8 @@ in
|
|||||||
{
|
{
|
||||||
obj = "p1b2"; # light-switch toggle button
|
obj = "p1b2"; # light-switch toggle button
|
||||||
properties = {
|
properties = {
|
||||||
"val" = ''{{ 1 if states("light.living_room_lights") == "on" else 0 }}'';
|
"val" = ''{{ 1 if states("light.living_room_lights") == "on" else 0 }}'';
|
||||||
"text" = ''{{ "\uE6E8" if is_state("light.living_room_lights", "on") else "\uE335" | e }}'';
|
"text" = ''{{ "\uE6E8" if is_state("light.living_room_lights", "on") else "\uE335" | e }}'';
|
||||||
};
|
};
|
||||||
event = {
|
event = {
|
||||||
"up" = {
|
"up" = {
|
||||||
|
|||||||
@@ -1,73 +1,196 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
{
|
||||||
# Set up impernance configuration for things like bluetooth
|
config,
|
||||||
# In this configuration with /etc and /var/log being persistent, only directories outside of that need to be done here. See hardware configuration for all mountpoints.
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.impermanence;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./options.nix ];
|
||||||
|
|
||||||
environment.persistence."/nix/persist/system" = {
|
config = mkIf cfg.enable {
|
||||||
hideMounts = true;
|
security.sudo.extraConfig = ''
|
||||||
directories = [
|
# rollback results in sudo lectures after each reboot
|
||||||
"/var/lib/bluetooth"
|
Defaults lecture = never
|
||||||
"/var/lib/iwd"
|
'';
|
||||||
"/var/lib/nixos"
|
|
||||||
"/var/lib/libvirt"
|
system.activationScripts = {
|
||||||
"/var/lib/waydroid"
|
"var-lib-private-permissions" = {
|
||||||
"/var/lib/systemd/coredump"
|
deps = [ "createPersistentStorageDirs" ];
|
||||||
"/etc/NetworkManager/system-connections"
|
text = ''
|
||||||
"/var/lib/tailscale"
|
mkdir -p /var/lib/private
|
||||||
"/var/lib/homeassistant"
|
chmod 0700 /var/lib/private
|
||||||
"/var/lib/mosquitto"
|
'';
|
||||||
"/var/lib/music-assistant"
|
};
|
||||||
"/var/lib/postgresql"
|
};
|
||||||
"/var/lib/zigbee2mqtt"
|
|
||||||
|
boot.initrd.systemd.services.rootfs-cleanup = {
|
||||||
|
description = "Clean file system root";
|
||||||
|
wantedBy = [
|
||||||
|
"initrd.target"
|
||||||
|
];
|
||||||
|
after = [
|
||||||
|
"initrd-root-device.target"
|
||||||
|
];
|
||||||
|
before = [
|
||||||
|
"sysroot.mount"
|
||||||
|
];
|
||||||
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script =
|
||||||
|
if (hasAttr "/" config.fileSystems) && (config.fileSystems."/".fsType == "btrfs") then
|
||||||
|
''
|
||||||
|
# workaround for machines without working rtc battery
|
||||||
|
# The time may not yet be correctly set, so wait until it is
|
||||||
|
if [[ $(date '+%s') -lt 1730469314 ]]; then
|
||||||
|
sleep 30 # this should hopefully be enough
|
||||||
|
fi
|
||||||
|
mkdir /btrfs_tmp
|
||||||
|
mount ${config.fileSystems."/".device} -t btrfs /btrfs_tmp
|
||||||
|
if [[ -e /btrfs_tmp/root ]]; then
|
||||||
|
mkdir -p /btrfs_tmp/old_roots
|
||||||
|
timestamp=$(date --date="@$(stat -c %X /btrfs_tmp/root)" "+%Y-%m-%d_%H:%M:%S")
|
||||||
|
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
delete_subvolume_recursively() {
|
||||||
|
IFS=$'\n'
|
||||||
|
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||||
|
delete_subvolume_recursively "/btrfs_tmp/$i"
|
||||||
|
done
|
||||||
|
btrfs subvolume delete "$1" || rm -rf "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -atime +30); do
|
||||||
|
delete_subvolume_recursively "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
btrfs subvolume create /btrfs_tmp/root
|
||||||
|
umount /btrfs_tmp
|
||||||
|
''
|
||||||
|
else if (hasAttr "/" config.fileSystems) && (config.fileSystems."/".fsType == "bcachefs") then
|
||||||
|
''
|
||||||
|
# workaround for machines without working rtc battery
|
||||||
|
# The time may not yet be correctly set, so wait until it is
|
||||||
|
if [[ $(date '+%s') -lt 1730469314 ]]; then
|
||||||
|
sleep 30 # this should hopefully be enough
|
||||||
|
fi
|
||||||
|
if [[ -e /root_tmp/root ]]; then
|
||||||
|
mkdir -p /root_tmp/old_roots
|
||||||
|
timestamp=$(date --date="@$(stat -c %X /root_tmp/root)" "+%Y-%m-%d_%H:%M:%S")
|
||||||
|
mv /root_tmp/root "/root_tmp/old_roots/$timestamp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in $(find /root_tmp/old_roots/ -maxdepth 1 -atime +30); do
|
||||||
|
bcachefs subvolume delete $i
|
||||||
|
done
|
||||||
|
|
||||||
|
bcachefs subvolume create /root_tmp/root
|
||||||
|
''
|
||||||
|
else
|
||||||
|
# For tmpfs or other filesystems, do nothing
|
||||||
|
"";
|
||||||
|
};
|
||||||
|
|
||||||
|
assertions = [
|
||||||
{
|
{
|
||||||
directory = "/var/lib/colord";
|
assertion = hasAttr "/" config.fileSystems;
|
||||||
user = "colord";
|
message = "To use impermanence, you need to define a root volume";
|
||||||
group = "colord";
|
}
|
||||||
mode = "u=rwx,g=rx,o=";
|
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
if hasAttr "/" config.fileSystems then
|
||||||
|
config.fileSystems."/".fsType == "btrfs"
|
||||||
|
|| config.fileSystems."/".fsType == "bcachefs"
|
||||||
|
|| config.fileSystems."/".fsType == "tmpfs"
|
||||||
|
else
|
||||||
|
false;
|
||||||
|
message = "rootfs must be btrfs, bcachefs, or tmpfs; not " + config.fileSystems."/".fsType;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
if
|
||||||
|
hasAttr "/" config.fileSystems
|
||||||
|
&& (config.fileSystems."/".fsType == "btrfs" || config.fileSystems."/".fsType == "bcachefs")
|
||||||
|
then
|
||||||
|
any (
|
||||||
|
t: t == "subvol=root" || t == "subvol=/root" || t == "X-mount.subdir=subvolumes/root"
|
||||||
|
) config.fileSystems."/".options
|
||||||
|
else
|
||||||
|
true;
|
||||||
|
message = "btrfs or bcachefs rootfs must mount subvolume root";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
directory = "/etc/nix";
|
assertion = !config.boot.isContainer;
|
||||||
user = "root";
|
message = "impermanence is not supported in containers";
|
||||||
group = "root";
|
|
||||||
mode = "u=rwx,g=rx,o=rx";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
directory = "/var/lib/private/authentik/media";
|
|
||||||
user = "authentik";
|
|
||||||
group = "authentik";
|
|
||||||
mode = "u=rwx,g=,o=";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
directory = "/var/lib/private";
|
|
||||||
mode = "u=rwx,g=rx,o=";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
directory = "/media/nas";
|
|
||||||
user = "nas-apps";
|
|
||||||
group = "jallen-nas";
|
|
||||||
mode = "u=rwx,g=rx,o=rx";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
directory = "/var/lib/crowdsec";
|
|
||||||
user = "crowdsec";
|
|
||||||
group = "crowdsec";
|
|
||||||
mode = "u=rwx,g=rwx,o=rx";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
directory = "/plugins-storage";
|
|
||||||
user = "traefik";
|
|
||||||
group = "traefik";
|
|
||||||
mode = "u=rwx,g=rwx,o=rx";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
files = [
|
|
||||||
"/etc/machine-id"
|
environment.persistence.${cfg.persistencePath} = {
|
||||||
];
|
hideMounts = true;
|
||||||
|
directories = [
|
||||||
|
"/var/lib/bluetooth"
|
||||||
|
"/var/lib/iwd"
|
||||||
|
"/var/lib/nixos"
|
||||||
|
"/var/lib/libvirt"
|
||||||
|
"/var/lib/waydroid"
|
||||||
|
"/var/lib/systemd/coredump"
|
||||||
|
"/etc/NetworkManager/system-connections"
|
||||||
|
"/var/lib/tailscale"
|
||||||
|
"/var/lib/homeassistant"
|
||||||
|
"/var/lib/mosquitto"
|
||||||
|
"/var/lib/music-assistant"
|
||||||
|
"/var/lib/postgresql"
|
||||||
|
"/var/lib/zigbee2mqtt"
|
||||||
|
{
|
||||||
|
directory = "/var/lib/colord";
|
||||||
|
user = "colord";
|
||||||
|
group = "colord";
|
||||||
|
mode = "u=rwx,g=rx,o=";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/etc/nix";
|
||||||
|
user = "root";
|
||||||
|
group = "root";
|
||||||
|
mode = "u=rwx,g=rx,o=rx";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/var/lib/private/authentik/media";
|
||||||
|
user = "authentik";
|
||||||
|
group = "authentik";
|
||||||
|
mode = "u=rwx,g=,o=";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/var/lib/private";
|
||||||
|
mode = "u=rwx,g=rx,o=";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/media/nas";
|
||||||
|
user = "nas-apps";
|
||||||
|
group = "jallen-nas";
|
||||||
|
mode = "u=rwx,g=rx,o=rx";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/var/lib/crowdsec";
|
||||||
|
user = "crowdsec";
|
||||||
|
group = "crowdsec";
|
||||||
|
mode = "u=rwx,g=rwx,o=rx";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
directory = "/plugins-storage";
|
||||||
|
user = "traefik";
|
||||||
|
group = "traefik";
|
||||||
|
mode = "u=rwx,g=rwx,o=rx";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
files = [
|
||||||
|
"/etc/machine-id"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
security.sudo.extraConfig = ''
|
|
||||||
# rollback results in sudo lectures after each reboot
|
|
||||||
Defaults lecture = never
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
modules/nixos/impermanence/options.nix
Normal file
12
modules/nixos/impermanence/options.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ lib, namespace, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.${namespace}.impermanence = {
|
||||||
|
enable = mkEnableOption "enable impermanence";
|
||||||
|
persistencePath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/nix/persist/system";
|
||||||
|
description = "Path to the persistence directory";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
53
modules/nixos/monitoring/default.nix
Normal file
53
modules/nixos/monitoring/default.nix
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.monitoring;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.${namespace}.monitoring = {
|
||||||
|
enable = lib.mkEnableOption "Common monitoring and system tools";
|
||||||
|
|
||||||
|
includeNetworkTools = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Include network monitoring tools";
|
||||||
|
};
|
||||||
|
|
||||||
|
includePerformanceTools = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Include performance monitoring tools";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages =
|
||||||
|
with pkgs;
|
||||||
|
[
|
||||||
|
# Basic system monitoring
|
||||||
|
htop
|
||||||
|
|
||||||
|
]
|
||||||
|
++ lib.optionals cfg.includePerformanceTools [
|
||||||
|
glances
|
||||||
|
nmon
|
||||||
|
iotop
|
||||||
|
|
||||||
|
]
|
||||||
|
++ lib.optionals cfg.includeNetworkTools [
|
||||||
|
speedtest-cli
|
||||||
|
iftop
|
||||||
|
nethogs
|
||||||
|
tcpdump
|
||||||
|
wireshark-cli
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable common system services for monitoring
|
||||||
|
programs.screen.enable = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -9,113 +9,45 @@ let
|
|||||||
cfg = config.${namespace}.network;
|
cfg = config.${namespace}.network;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.network = with types; {
|
imports = [
|
||||||
hostName = lib.mkOption {
|
./options.nix
|
||||||
type = str;
|
];
|
||||||
default = "nixos";
|
|
||||||
description = "The hostname of the system.";
|
|
||||||
};
|
|
||||||
|
|
||||||
ipv4 = {
|
|
||||||
method = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "auto";
|
|
||||||
};
|
|
||||||
address = lib.mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "10.0.1.1";
|
|
||||||
};
|
|
||||||
gateway = lib.mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "10.0.1.1";
|
|
||||||
};
|
|
||||||
dns = lib.mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "10.0.1.1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
networking = {
|
networking = {
|
||||||
hostName = lib.mkForce cfg.hostName;
|
hostName = lib.mkForce cfg.hostName;
|
||||||
|
|
||||||
# Enable Network Manager
|
# Use networkd if enabled
|
||||||
networkmanager = {
|
useNetworkd = lib.mkIf cfg.useNetworkd true;
|
||||||
enable = true;
|
|
||||||
wifi.powersave = lib.mkDefault false;
|
|
||||||
settings.connectivity.uri = lib.mkDefault "http://nmcheck.gnome.org/check_network_status.txt";
|
|
||||||
ensureProfiles = {
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.secrets.wifi.path
|
|
||||||
];
|
|
||||||
|
|
||||||
profiles = {
|
# Set default gateway and nameservers if in manual mode
|
||||||
"Joey's Jungle 6G" = {
|
defaultGateway = lib.mkIf (cfg.ipv4.method == "manual") {
|
||||||
connection = {
|
address = cfg.ipv4.gateway;
|
||||||
id = "Joey's Jungle 6G";
|
interface = lib.mkIf (cfg.ipv4.interface != "") cfg.ipv4.interface;
|
||||||
type = "wifi";
|
|
||||||
};
|
|
||||||
ipv4 =
|
|
||||||
if (cfg.ipv4.method == "auto") then
|
|
||||||
{
|
|
||||||
method = "auto";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
address1 = cfg.ipv4.address;
|
|
||||||
dns = cfg.ipv4.dns;
|
|
||||||
gateway = cfg.ipv4.gateway;
|
|
||||||
method = "manual";
|
|
||||||
};
|
|
||||||
ipv6 = {
|
|
||||||
addr-gen-mode = "stable-privacy";
|
|
||||||
method = "auto";
|
|
||||||
};
|
|
||||||
wifi = {
|
|
||||||
mode = "infrastructure";
|
|
||||||
ssid = "Joey's Jungle 6G";
|
|
||||||
};
|
|
||||||
wifi-security = {
|
|
||||||
key-mgmt = "sae";
|
|
||||||
psk = "$PSK";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"Joey's Jungle 5G" = {
|
|
||||||
connection = {
|
|
||||||
id = "Joey's Jungle 5G";
|
|
||||||
type = "wifi";
|
|
||||||
};
|
|
||||||
ipv4 =
|
|
||||||
if (cfg.ipv4.method == "auto") then
|
|
||||||
{
|
|
||||||
method = "auto";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
address1 = cfg.ipv4.address;
|
|
||||||
dns = cfg.ipv4.dns;
|
|
||||||
gateway = cfg.ipv4.gateway;
|
|
||||||
method = "manual";
|
|
||||||
};
|
|
||||||
ipv6 = {
|
|
||||||
addr-gen-mode = "stable-privacy";
|
|
||||||
method = "auto";
|
|
||||||
};
|
|
||||||
wifi = {
|
|
||||||
mode = "infrastructure";
|
|
||||||
ssid = "Joey's Jungle 5G";
|
|
||||||
};
|
|
||||||
wifi-security = {
|
|
||||||
key-mgmt = "sae";
|
|
||||||
psk = "$PSK";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nameservers = lib.mkIf (cfg.ipv4.method == "manual") [ cfg.ipv4.dns ];
|
||||||
|
|
||||||
|
# Set hostId if provided
|
||||||
|
hostId = lib.mkIf (cfg.hostId != "") cfg.hostId;
|
||||||
|
|
||||||
|
# Configure NAT if enabled
|
||||||
|
nat = lib.mkIf cfg.nat.enable {
|
||||||
|
enable = true;
|
||||||
|
internalInterfaces = cfg.nat.internalInterfaces;
|
||||||
|
externalInterface = cfg.nat.externalInterface;
|
||||||
|
enableIPv6 = cfg.nat.enableIPv6;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure firewall
|
||||||
firewall = {
|
firewall = {
|
||||||
|
enable = cfg.firewall.enable;
|
||||||
|
allowPing = cfg.firewall.allowPing;
|
||||||
|
allowedTCPPorts = cfg.firewall.allowedTCPPorts;
|
||||||
|
allowedUDPPorts = cfg.firewall.allowedUDPPorts;
|
||||||
|
trustedInterfaces = cfg.firewall.trustedInterfaces;
|
||||||
|
|
||||||
|
# Default port ranges for KDE Connect
|
||||||
allowedTCPPortRanges = [
|
allowedTCPPortRanges = [
|
||||||
{
|
{
|
||||||
from = 1714;
|
from = 1714;
|
||||||
@@ -123,7 +55,70 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
allowedUDPPortRanges = config.networking.firewall.allowedTCPPortRanges;
|
allowedUDPPortRanges = config.networking.firewall.allowedTCPPortRanges;
|
||||||
|
|
||||||
|
# Extra firewall commands
|
||||||
|
extraCommands = lib.mkIf (cfg.extraFirewallCommands != "") cfg.extraFirewallCommands;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Configure iwd if enabled
|
||||||
|
wireless.iwd = lib.mkIf cfg.iwd.enable {
|
||||||
|
enable = true;
|
||||||
|
settings = cfg.iwd.settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure NetworkManager
|
||||||
|
networkmanager = mkMerge [
|
||||||
|
# Disable NetworkManager when iwd is enabled
|
||||||
|
(mkIf cfg.iwd.enable {
|
||||||
|
enable = mkForce false;
|
||||||
|
wifi.backend = mkForce "iwd";
|
||||||
|
})
|
||||||
|
|
||||||
|
# Enable NetworkManager when wifi is enabled and iwd is disabled
|
||||||
|
(mkIf (cfg.wifi.enable && !cfg.iwd.enable) {
|
||||||
|
enable = true;
|
||||||
|
wifi.powersave = cfg.wifi.powersave;
|
||||||
|
settings.connectivity.uri = mkDefault "http://nmcheck.gnome.org/check_network_status.txt";
|
||||||
|
|
||||||
|
# Configure WiFi profiles if any are defined
|
||||||
|
ensureProfiles = mkIf (cfg.wifi.profiles != { }) {
|
||||||
|
environmentFiles = [
|
||||||
|
config.sops.secrets.wifi.path
|
||||||
|
];
|
||||||
|
|
||||||
|
profiles = mapAttrs (name: profile: {
|
||||||
|
connection = {
|
||||||
|
id = name;
|
||||||
|
type = "wifi";
|
||||||
|
};
|
||||||
|
ipv4 =
|
||||||
|
if (cfg.ipv4.method == "auto") then
|
||||||
|
{
|
||||||
|
method = "auto";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
address1 = cfg.ipv4.address;
|
||||||
|
dns = cfg.ipv4.dns;
|
||||||
|
gateway = cfg.ipv4.gateway;
|
||||||
|
method = "manual";
|
||||||
|
};
|
||||||
|
ipv6 = {
|
||||||
|
addr-gen-mode = "stable-privacy";
|
||||||
|
method = "auto";
|
||||||
|
};
|
||||||
|
wifi = {
|
||||||
|
mode = "infrastructure";
|
||||||
|
ssid = profile.ssid;
|
||||||
|
};
|
||||||
|
wifi-security = {
|
||||||
|
key-mgmt = profile.keyMgmt;
|
||||||
|
psk = profile.psk;
|
||||||
|
};
|
||||||
|
}) cfg.wifi.profiles;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
162
modules/nixos/network/options.nix
Normal file
162
modules/nixos/network/options.nix
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.${namespace}.network = with types; {
|
||||||
|
hostName = lib.mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "nixos";
|
||||||
|
description = "The hostname of the system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
ipv4 = {
|
||||||
|
method = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "auto";
|
||||||
|
description = "Method for IPv4 configuration (auto or manual).";
|
||||||
|
};
|
||||||
|
address = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "10.0.1.1/24";
|
||||||
|
description = "IPv4 address with subnet mask (e.g., 10.0.1.1/24).";
|
||||||
|
};
|
||||||
|
gateway = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "10.0.1.1";
|
||||||
|
description = "IPv4 default gateway.";
|
||||||
|
};
|
||||||
|
interface = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "Interface for the default gateway (required when using networkd).";
|
||||||
|
};
|
||||||
|
dns = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "10.0.1.1";
|
||||||
|
description = "IPv4 DNS server.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
useNetworkd = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to use systemd-networkd for networking.";
|
||||||
|
};
|
||||||
|
|
||||||
|
nat = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable NAT.";
|
||||||
|
};
|
||||||
|
internalInterfaces = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of internal interfaces for NAT.";
|
||||||
|
};
|
||||||
|
externalInterface = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "External interface for NAT.";
|
||||||
|
};
|
||||||
|
enableIPv6 = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable IPv6 NAT.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
firewall = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to enable the firewall.";
|
||||||
|
};
|
||||||
|
allowPing = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to allow ICMP ping.";
|
||||||
|
};
|
||||||
|
allowedTCPPorts = mkOption {
|
||||||
|
type = types.listOf types.port;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of allowed TCP ports.";
|
||||||
|
};
|
||||||
|
allowedUDPPorts = mkOption {
|
||||||
|
type = types.listOf types.port;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of allowed UDP ports.";
|
||||||
|
};
|
||||||
|
trustedInterfaces = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of trusted interfaces.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
wifi = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to enable WiFi configuration.";
|
||||||
|
};
|
||||||
|
powersave = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable WiFi power saving.";
|
||||||
|
};
|
||||||
|
profiles = mkOption {
|
||||||
|
type = types.attrsOf (
|
||||||
|
types.submodule {
|
||||||
|
options = {
|
||||||
|
ssid = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "SSID of the WiFi network.";
|
||||||
|
};
|
||||||
|
psk = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$PSK";
|
||||||
|
description = "PSK environment variable for the WiFi password.";
|
||||||
|
};
|
||||||
|
keyMgmt = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "sae";
|
||||||
|
description = "Key management type (e.g., sae, wpa-psk).";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
description = "WiFi network profiles.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hostId = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "Host ID for ZFS and other services.";
|
||||||
|
};
|
||||||
|
|
||||||
|
iwd = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable iwd for wireless networking.";
|
||||||
|
};
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = "Settings for iwd.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraFirewallCommands = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "Extra commands for the firewall.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,10 +3,12 @@
|
|||||||
nix = {
|
nix = {
|
||||||
settings = {
|
settings = {
|
||||||
substituters = [
|
substituters = [
|
||||||
|
"https://nixos-raspberrypi.cachix.org"
|
||||||
"https://nix-community.cachix.org"
|
"https://nix-community.cachix.org"
|
||||||
"https://cache.nixos.org/"
|
"https://cache.nixos.org/"
|
||||||
];
|
];
|
||||||
trusted-public-keys = [
|
trusted-public-keys = [
|
||||||
|
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
];
|
];
|
||||||
warn-dirty = lib.mkForce false;
|
warn-dirty = lib.mkForce false;
|
||||||
|
|||||||
@@ -8,18 +8,6 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.${namespace}.services.ollama;
|
cfg = config.${namespace}.services.ollama;
|
||||||
|
|
||||||
llamaPackage = pkgs.llama-cpp.overrideAttrs (_old: {
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "ggml-org";
|
|
||||||
repo = "llama.cpp";
|
|
||||||
rev = "b4920";
|
|
||||||
sha256 = "sha256-SnQIeY74JpAPRMxWcpklDH5D4CQvAgi0GYx5+ECk2J4=";
|
|
||||||
};
|
|
||||||
# Optionally override other attributes if you need to
|
|
||||||
# version = "my-fork-version";
|
|
||||||
# pname = "llama-cpp-custom";
|
|
||||||
});
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.nas-apps.orca-slicer;
|
cfg = config.${namespace}.services.orca-slicer;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./options.nix ];
|
imports = [ ./options.nix ];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, namespace, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
options.nas-apps.orca-slicer = {
|
options.${namespace}.services.orca-slicer = {
|
||||||
enable = mkEnableOption "orca slicer docker service";
|
enable = mkEnableOption "orca slicer docker service";
|
||||||
|
|
||||||
autoStart = mkOption {
|
autoStart = mkOption {
|
||||||
|
|||||||
92
modules/nixos/raspberry-pi/default.nix
Normal file
92
modules/nixos/raspberry-pi/default.nix
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.hardware.raspberry-pi;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.${namespace}.hardware.raspberry-pi = {
|
||||||
|
enable = lib.mkEnableOption "Raspberry Pi common configuration";
|
||||||
|
|
||||||
|
variant = lib.mkOption {
|
||||||
|
type = lib.types.enum [
|
||||||
|
"4"
|
||||||
|
"5"
|
||||||
|
];
|
||||||
|
description = "Raspberry Pi variant (4 or 5)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# Common Raspberry Pi packages
|
||||||
|
environment.systemPackages =
|
||||||
|
with pkgs;
|
||||||
|
[
|
||||||
|
libraspberrypi
|
||||||
|
raspberrypi-eeprom
|
||||||
|
raspberrypifw
|
||||||
|
raspberrypiWirelessFirmware
|
||||||
|
raspberrypi-armstubs
|
||||||
|
]
|
||||||
|
++ lib.optionals (cfg.variant == "4") [
|
||||||
|
i2c-tools
|
||||||
|
]
|
||||||
|
++ lib.optionals (cfg.variant == "5") [
|
||||||
|
erofs-utils
|
||||||
|
fex
|
||||||
|
squashfuse
|
||||||
|
squashfsTools
|
||||||
|
];
|
||||||
|
|
||||||
|
# Common nixpkgs overlays for Raspberry Pi
|
||||||
|
nixpkgs.overlays = lib.mkAfter [
|
||||||
|
(_self: super: {
|
||||||
|
# This is used in (modulesPath + "/hardware/all-firmware.nix") when at least
|
||||||
|
# enableRedistributableFirmware is enabled
|
||||||
|
inherit (super) raspberrypiWirelessFirmware;
|
||||||
|
# Some derivations want to use it as an input,
|
||||||
|
# e.g. raspberrypi-dtbs, omxplayer, sd-image-* modules
|
||||||
|
inherit (super) raspberrypifw;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
# Common Bluetooth configuration
|
||||||
|
systemd.services.btattach = {
|
||||||
|
before = [ "bluetooth.service" ];
|
||||||
|
after = [ "dev-ttyAMA0.device" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Common hardware settings
|
||||||
|
hardware.i2c.enable = lib.mkIf (cfg.variant == "4") true;
|
||||||
|
|
||||||
|
# Pi 5 specific settings
|
||||||
|
hardware.graphics.enable32Bit = lib.mkIf (cfg.variant == "5") (lib.mkForce false);
|
||||||
|
zramSwap.enable = lib.mkIf (cfg.variant == "5") true;
|
||||||
|
|
||||||
|
# Pi 5 specific system tags
|
||||||
|
system.nixos.tags = lib.mkIf (cfg.variant == "5") (
|
||||||
|
let
|
||||||
|
bootCfg = config.boot.loader.raspberry-pi;
|
||||||
|
in
|
||||||
|
[
|
||||||
|
"raspberry-pi-${bootCfg.variant}"
|
||||||
|
bootCfg.bootloader
|
||||||
|
config.boot.kernelPackages.kernel.version
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
# Common programs
|
||||||
|
programs.kdeconnect.enable = lib.mkDefault false;
|
||||||
|
|
||||||
|
# Root user shell configuration
|
||||||
|
users.users.root.shell = pkgs.zsh;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
let
|
let
|
||||||
defaultSops = (lib.snowfall.fs.get-file "secrets/pi4-secrets.yaml");
|
# defaultSops = (lib.snowfall.fs.get-file "secrets/pi4-secrets.yaml");
|
||||||
# sharedSops = (lib.snowfall.fs.get-file "secrets/secrets.yaml");
|
defaultSops = (lib.snowfall.fs.get-file "secrets/secrets.yaml");
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Permission modes are in octal representation (same as chmod),
|
# Permission modes are in octal representation (same as chmod),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ let
|
|||||||
cacheUrl = "http://${serverIp}:9012";
|
cacheUrl = "http://${serverIp}:9012";
|
||||||
cloudUrl = "http://${config.containers.nextcloud.localAddress}:80";
|
cloudUrl = "http://${config.containers.nextcloud.localAddress}:80";
|
||||||
giteaUrl = "http://${config.containers.gitea.localAddress}:${toString config.containers.gitea.config.services.gitea.settings.server.HTTP_PORT}";
|
giteaUrl = "http://${config.containers.gitea.localAddress}:${toString config.containers.gitea.config.services.gitea.settings.server.HTTP_PORT}";
|
||||||
hassUrl = "http://homeassistant.local:8123";
|
hassUrl = "http://nuc-nixos.local:8123";
|
||||||
immichUrl = "http://${serverIp}:${toString config.services.immich.port}";
|
immichUrl = "http://${serverIp}:${toString config.services.immich.port}";
|
||||||
jellyfinUrl = "http://${serverIp}:8096";
|
jellyfinUrl = "http://${serverIp}:8096";
|
||||||
jellyseerrUrl = "http://${config.containers.jellyseerr.localAddress}:${toString config.containers.jellyseerr.config.services.jellyseerr.port}";
|
jellyseerrUrl = "http://${config.containers.jellyseerr.localAddress}:${toString config.containers.jellyseerr.config.services.jellyseerr.port}";
|
||||||
|
|||||||
@@ -8,6 +8,18 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.${namespace}.user;
|
cfg = config.${namespace}.user;
|
||||||
|
|
||||||
|
isRoot = (cfg.name == "root");
|
||||||
|
|
||||||
|
# Common SSH keys used across systems
|
||||||
|
commonSshKeys = [
|
||||||
|
# MacBook
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCw9zq8DLGByI5v2gAn95hKNyOsm3g61a2buxu2BBMFysQJgmZPCCLUqRJKhSM5Vm/JOgsAmdpRBRZQoHD+6S844CJHb4v4VIbjkyQgYCuM7Rst2IOZ5QybvsA2/D0nwytZ+HXQqDj2AagUYDbz0gyyIHkDQ5YGBMkvkWz/h1Vci6aoBM7VihEDM4KlWoTVuPeASGM8r5IZ2FS83Djbqo4ov6AYvLMrKB9Z7hmFgH6R3LE0gxOkzbGVXtSuvJyrjvgytoT22UhATjjxSQ9D+YJXXkQoB3lUdg8OoIquUPjMZpl4mR8ffvseWPfcvD1XlD5t+TOHFqKpESO547tlOBYhdpew+NSgAXpamCU6oyV8tDCywLQu2ucxHRn78u6WXzWHkDtffdhzmk6TZaPhWqVHuTGjR4higBgGqUfSaKOMszt+FDRZAr3HtuQ2+zJ8bowK9fW5OqilTtK2HtQqroD9ApegDNbqOz6kGy5IycSXvqPURy/M4lxZxbtBPuemcJs= mattjallen@MacBook-Pro.local"
|
||||||
|
# Desktop Windows
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ2PYPjZddOzR8OJj16G88KcUhCDLkvrEmpUQP0wKHDUuA27HQQ2ORo66asadwGHY3k1VDZ1ei9l9H++SIIeKOaaUr5yZdktvj4POUNtbd9ZhcS7sZU7BSF+NMDM+h3tImh6z0S7mWvRQOUv3ZM+ZER+5xTWJVG1OOJEpb1drxJk6Qz0wbZKSR7TPNFBLLXlVy7hkNYf07RtDyhCCxNB3hJfa8c+oztnWumwDhDQWLqiUXWIU2QH6iRLGl/WYnujtNvVVaV/Hn3JJkS6MM9dnV3cpoIO0+J7+WfsN9rZ0wXt5yY3GhiGXwmcO5eYVli8lHlLWtK7aYSETyry6CBsLbojzOQO5rSqhpwfF2njAAFAQU0UjLc8PahisIuFKCwHH4iyXXOagiv5K1Mc/0Ak+WhhMPee6vV2p7NTyNpXRvouDbWy5cSRH31WgQ9fK5mIGe5v8nGGqtEhUubUkiOgP+H3UbT2V/nTv/TFKdJcKw+WmizvTrxBmaMjWALlkYl+s= mattl@Jallen-PC"
|
||||||
|
# Desktop NixOS
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBMydhOc6SnOdB5WrEd7X07DrboAtagCUgXiOJjLov matt@matt-nixos"
|
||||||
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.user = with types; {
|
options.${namespace}.user = with types; {
|
||||||
@@ -41,11 +53,58 @@ in
|
|||||||
default = null;
|
default = null;
|
||||||
description = "Path to the password file for this user account";
|
description = "Path to the password file for this user account";
|
||||||
};
|
};
|
||||||
|
sshKeys = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of SSH public keys for the user.";
|
||||||
|
};
|
||||||
|
enableCommonSshKeys = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to include common SSH keys used across systems.";
|
||||||
|
};
|
||||||
|
uid = lib.mkOption {
|
||||||
|
type = int;
|
||||||
|
default = if isRoot then ids.uids.root else 1000;
|
||||||
|
description = "The user ID for the user account.";
|
||||||
|
};
|
||||||
|
packages = lib.mkOption {
|
||||||
|
type = listOf package;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of packages to install for this user.";
|
||||||
|
};
|
||||||
|
linger = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable systemd user service persistence.";
|
||||||
|
};
|
||||||
|
password = lib.mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = "Plain text password for the user (development only).";
|
||||||
|
};
|
||||||
|
hashedPassword = lib.mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = "Hashed password for the user.";
|
||||||
|
};
|
||||||
|
mutableUsers = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether users are mutable (can be modified after creation).";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
users.mutableUsers = cfg.mutableUsers;
|
||||||
|
|
||||||
users.users.${cfg.name} = {
|
users.users.${cfg.name} = {
|
||||||
inherit (cfg) name;
|
inherit (cfg)
|
||||||
|
name
|
||||||
|
uid
|
||||||
|
linger
|
||||||
|
packages
|
||||||
|
;
|
||||||
|
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel"
|
"wheel"
|
||||||
@@ -64,14 +123,27 @@ in
|
|||||||
"power"
|
"power"
|
||||||
"nix"
|
"nix"
|
||||||
"i2c"
|
"i2c"
|
||||||
] ++ cfg.extraGroups;
|
]
|
||||||
|
++ cfg.extraGroups;
|
||||||
|
|
||||||
group = "users";
|
group = "users";
|
||||||
home = "/home/${cfg.name}";
|
home = "/home/${cfg.name}";
|
||||||
isNormalUser = true;
|
isNormalUser = (!isRoot);
|
||||||
|
isSystemUser = isRoot;
|
||||||
shell = lib.mkForce pkgs.zsh;
|
shell = lib.mkForce pkgs.zsh;
|
||||||
uid = 1000;
|
|
||||||
hashedPasswordFile = cfg.passwordFile;
|
# SSH keys - combine user-specific and common keys
|
||||||
} // cfg.extraOptions;
|
openssh.authorizedKeys.keys = cfg.sshKeys ++ (lib.optionals cfg.enableCommonSshKeys commonSshKeys);
|
||||||
|
|
||||||
|
# Authentication - priority: passwordFile > hashedPassword > password
|
||||||
|
hashedPasswordFile = lib.mkIf (cfg.passwordFile != null) cfg.passwordFile;
|
||||||
|
hashedPassword = lib.mkIf (
|
||||||
|
cfg.passwordFile == null && cfg.hashedPassword != null
|
||||||
|
) cfg.hashedPassword;
|
||||||
|
password = lib.mkIf (
|
||||||
|
cfg.passwordFile == null && cfg.hashedPassword == null && cfg.password != null
|
||||||
|
) cfg.password;
|
||||||
|
}
|
||||||
|
// cfg.extraOptions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
45
packages/open-remote-ssh/default.nix
Normal file
45
packages/open-remote-ssh/default.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchurl,
|
||||||
|
vscode-utils,
|
||||||
|
pkgs,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = "0.0.49";
|
||||||
|
publisher = "jeanp413";
|
||||||
|
name = "open-remote-ssh";
|
||||||
|
in
|
||||||
|
vscode-utils.buildVscodeMarketplaceExtension {
|
||||||
|
mktplcRef = {
|
||||||
|
inherit name publisher version;
|
||||||
|
};
|
||||||
|
|
||||||
|
vsix = fetchurl {
|
||||||
|
url = "https://open-vsx.org/api/${publisher}/${name}/${version}/file/${publisher}.${name}-${version}.vsix";
|
||||||
|
sha256 = "sha256-QfJnAAx+kO2iJ1EzWoO5HLogJKg3RiC3hg1/u2Jm6t4=";
|
||||||
|
};
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
${pkgs.unzip}/bin/unzip -q $src
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Use any remote machine with a SSH server as your development environment";
|
||||||
|
longDescription = ''
|
||||||
|
The Open Remote SSH extension allows you to open a remote folder on any
|
||||||
|
remote machine, virtual machine, or container with a running SSH server
|
||||||
|
and take full advantage of VS Code's feature set. This is an open-source
|
||||||
|
alternative to Microsoft's proprietary Remote SSH extension, designed to
|
||||||
|
work with VSCodium and other open-source VS Code variants.
|
||||||
|
|
||||||
|
Note: This extension requires enabling proposed APIs in VSCodium/Code-OSS.
|
||||||
|
You need to add "jeanp413.open-remote-ssh" to the "enable-proposed-api"
|
||||||
|
array in ~/.vscode-oss/argv.json
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/jeanp413/open-remote-ssh";
|
||||||
|
changelog = "https://github.com/jeanp413/open-remote-ssh/releases";
|
||||||
|
license = licenses.mit;
|
||||||
|
platforms = platforms.all;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{ python3Packages, fetchFromGitHub, ... }:
|
{ python3Packages, fetchFromGitHub, ... }:
|
||||||
python3Packages.buildPythonPackage rec {
|
python3Packages.buildPythonPackage {
|
||||||
pname = "pipewire-python";
|
pname = "pipewire-python";
|
||||||
version = "0.2.3";
|
version = "0.2.3";
|
||||||
format = "pyproject";
|
format = "pyproject";
|
||||||
@@ -12,6 +12,10 @@ python3Packages.buildPythonPackage rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = with python3Packages; [ flit-core ];
|
buildInputs = with python3Packages; [ flit-core ];
|
||||||
nativeBuildInputs = with python3Packages; [ build wheel ];
|
nativeBuildInputs = with python3Packages; [
|
||||||
doCheck = false; # no tests in the PyPI tarball
|
build
|
||||||
|
wheel
|
||||||
|
];
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
}
|
}
|
||||||
|
|||||||
16
packages/python-steam/default.nix
Normal file
16
packages/python-steam/default.nix
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{ python3Packages, fetchPypi, ... }:
|
||||||
|
|
||||||
|
python3Packages.buildPythonPackage rec {
|
||||||
|
pname = "steam";
|
||||||
|
version = "1.4.4";
|
||||||
|
pyproject = false;
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-K1vWkRwNSnMS9EG40WK52NR8i+u478bIhnOTsDI/pS4=";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildInputs = with python3Packages; [ setuptools ];
|
||||||
|
|
||||||
|
doCheck = false; # no tests in the PyPI tarball
|
||||||
|
}
|
||||||
@@ -11,7 +11,10 @@ python3Packages.buildPythonPackage rec {
|
|||||||
sha256 = "sha256-rEmWsCIBGNmDEecVT8O9O5/E0WVpTfA7amFI70DEmiI=";
|
sha256 = "sha256-rEmWsCIBGNmDEecVT8O9O5/E0WVpTfA7amFI70DEmiI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = with python3Packages; [ poetry-core hatchling ];
|
buildInputs = with python3Packages; [
|
||||||
|
poetry-core
|
||||||
|
hatchling
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildInputs = with python3Packages; [
|
nativeBuildInputs = with python3Packages; [
|
||||||
aiodns
|
aiodns
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
jallen-nas:
|
jallen-nas:
|
||||||
admin_password: ENC[AES256_GCM,data:0XUblR800UyliA8JfYUZbncDRxiU6eoTaf3i80+OCwJ/31oBhSqj9OtgYeRg3IyURwik1Nk/609IuHjIhly3mgTjOD6Hpzxpag==,iv:0yO3z8ItHRQFeI9JOnFTKhKVHi5u9cMtpglFRlkvYLE=,tag:iUd79iWAJQ9iqP0qolSwfA==,type:str]
|
admin_password: ENC[AES256_GCM,data:0XUblR800UyliA8JfYUZbncDRxiU6eoTaf3i80+OCwJ/31oBhSqj9OtgYeRg3IyURwik1Nk/609IuHjIhly3mgTjOD6Hpzxpag==,iv:0yO3z8ItHRQFeI9JOnFTKhKVHi5u9cMtpglFRlkvYLE=,tag:iUd79iWAJQ9iqP0qolSwfA==,type:str]
|
||||||
|
nas_pool: ENC[AES256_GCM,data:sx78UwPhgklzf8e/Tjw/2esAspMFTnSj3ahEtv3btVLpotwE9UDMtFGPkkh8r82mGLmzC3dRsWYaOAFW4ioVBpmiochpdAR+QfmOBgsOFQPKdqlF0DDXcElT+qxhJ9Uoo26v0XZwaTdplI9f8OTxCPZtihX4Y27sFNjhCM9loN+IJKqxPFNaK4RRJtFQL5sG2OaiPkSd/Wf082RTW12CNWYRY2RSTCqzKB7YclTcAAwdj72uJTER7uU8Fr4/PpUN7AJ/GGK9OetY5QbkieelwESBqQR12CLCF1/d82CaN/lL8jtuc3Q7QFsRGr28fHBNqOywkJ6aNxxZCKS0fjQGpasroQtt5fv8pNMs7Gu67SiuKGb/z0wKdd5c03sxD/42bSf2aM1vUW8Bm6PGGVk8OT0UWMA9FhbWeVr3HSb6gFktOlC3oRLGPUU3WcdkLAmqCWtSQuVHNx6/s/JDj8UyWqyDCu/7afxKX9gt+I6G+3EWmVs/fi91+tpYd5hyhTBFmOoC+wooVqnGVXtM7cUbWTJS4Ua82zcroHj+KKoX5sOOzOXfI9TVRLccPYlbdSY46467+ycEXsc7cxnigKerO29GhFFoC3pGxwwBcMYWDl8466H7cCDpYohPdY/q9dYuB3LBEzFizmANQ/kGEkZt1I1fydO+sN5ZcTyhnOCHQFI9lYPDsQ6Gztb4n8PEHYdHbp1Zue0p82H8hhgC4v2ne2GezdiYRCl1y2MZvF8CgkwAw/PkX2cb8CAMuG0ZHtOLFwUPjPk2KCe8G6yK0SekE/Zm36wlPz8yLd9S2dLRBcxXZiQEHXqONjVGf3fhbE8QyDZ83xITlRTnbQt1rF0vPrgeJD/m3u4QMo1BrF6EIsCCesQrNPLRRGddh7uyhVX9OKy633OKxLy2Gt1VjfuE77ZaPmNgIjk1geCXuKUFD/BC9DJiknVuajS8tFHIIh7YYUBZY/Q=,iv:ZvI+1L4Zwgwz0t++fvVxX7HXXuS8G8DcKz7WDlq9oS8=,tag:sbXluJh9CQhJH11gk2Ohfg==,type:str]
|
||||||
ups_password: ENC[AES256_GCM,data:tYuJ9nU3E2/Ko6Y=,iv:lQq+g68lKCp1rmPvS/84xGIXHxD9zY5zZrrjEJlY8Hs=,tag:p6McEr+sXGAQyMAz1Kaxfw==,type:str]
|
ups_password: ENC[AES256_GCM,data:tYuJ9nU3E2/Ko6Y=,iv:lQq+g68lKCp1rmPvS/84xGIXHxD9zY5zZrrjEJlY8Hs=,tag:p6McEr+sXGAQyMAz1Kaxfw==,type:str]
|
||||||
authentik-env: ENC[AES256_GCM,data:AzHHGyhoyMp/ebnK6LQ5apBUhQT04SPJrtA6XcdaQ38C+fYuG2ph2iWFb+giafxCe8IXWAYT8CWoeqcspM7CPSAAKgqfVaPhMvjXqLxCY/rpegb5jBD1U6tURhPsH3ADrERk+kCmTV2eUpuV+nluiGM+fRdwhB0zu378HKwhXCpSO4L24aXhe9pxxxaTQzncWH6zW5iaRdouDVr1bAUzLi9BpnmS0ZK/rfLq2whErCeN++Srx6aCgwJ7jaqetBglQkIl3YG6flS8u3vsKtI+RVaNJ5tzrWR/qv0vBy8y1PZEuuXZdiHjn1hjiPE1T31j2+aQdbX70RaJfIt6E4lVtArQHv8PTUDxUoxcnUv52xLTStT5/UdIlNoZjPMwvaknpK7Z0uw9w4j76gmgk06xsxoCpnXIGTm1QpGqviBhgfNs5Va/qi4MBfByaym3UAz9LPHs4keuvJNN8dS0q5OMnRswl14PjIb1MIKB/QCVHvb4hO7eIRiWOkA7nb9LP/y1mjAYslr+I+GNpU8oIYTAvKoMS7ZgC49RoLWytAXUru2I7CqDR9zgPzlDQ9gLPoFKw2uKulpAy0ayQWPcgPA2CFmF+5zdINNSNKn0gRZ/2RTc3DiWmzo4P13EmrOwvkWCkiswFu1d6ctKZFhQnfPuj9LRGp/Os55JpLrreSyRJug6lgR4bPdC3x8sbxNmb5S2Y+4aFfgPXfdCdXs5b+8j28d1d4EoOO/arUzNADz9ODD5esb2g8UC2QtQd0RRYX/qmiM=,iv:YKvFxz3M8HKlg56JfN6uv8hvCFlEbhBkaSQz1v9l3zk=,tag:rz7UixSDqOXH7Ga6mkVYAw==,type:str]
|
authentik-env: ENC[AES256_GCM,data:AzHHGyhoyMp/ebnK6LQ5apBUhQT04SPJrtA6XcdaQ38C+fYuG2ph2iWFb+giafxCe8IXWAYT8CWoeqcspM7CPSAAKgqfVaPhMvjXqLxCY/rpegb5jBD1U6tURhPsH3ADrERk+kCmTV2eUpuV+nluiGM+fRdwhB0zu378HKwhXCpSO4L24aXhe9pxxxaTQzncWH6zW5iaRdouDVr1bAUzLi9BpnmS0ZK/rfLq2whErCeN++Srx6aCgwJ7jaqetBglQkIl3YG6flS8u3vsKtI+RVaNJ5tzrWR/qv0vBy8y1PZEuuXZdiHjn1hjiPE1T31j2+aQdbX70RaJfIt6E4lVtArQHv8PTUDxUoxcnUv52xLTStT5/UdIlNoZjPMwvaknpK7Z0uw9w4j76gmgk06xsxoCpnXIGTm1QpGqviBhgfNs5Va/qi4MBfByaym3UAz9LPHs4keuvJNN8dS0q5OMnRswl14PjIb1MIKB/QCVHvb4hO7eIRiWOkA7nb9LP/y1mjAYslr+I+GNpU8oIYTAvKoMS7ZgC49RoLWytAXUru2I7CqDR9zgPzlDQ9gLPoFKw2uKulpAy0ayQWPcgPA2CFmF+5zdINNSNKn0gRZ/2RTc3DiWmzo4P13EmrOwvkWCkiswFu1d6ctKZFhQnfPuj9LRGp/Os55JpLrreSyRJug6lgR4bPdC3x8sbxNmb5S2Y+4aFfgPXfdCdXs5b+8j28d1d4EoOO/arUzNADz9ODD5esb2g8UC2QtQd0RRYX/qmiM=,iv:YKvFxz3M8HKlg56JfN6uv8hvCFlEbhBkaSQz1v9l3zk=,tag:rz7UixSDqOXH7Ga6mkVYAw==,type:str]
|
||||||
traefik:
|
traefik:
|
||||||
@@ -142,7 +143,7 @@ sops:
|
|||||||
WmFoMmlNbXUvREZESnU3ZzFMbkNGVjAKGLZWo3E9098b2kOn77U/CGQpo4/mqSXY
|
WmFoMmlNbXUvREZESnU3ZzFMbkNGVjAKGLZWo3E9098b2kOn77U/CGQpo4/mqSXY
|
||||||
5+rZJuC7Iqh+VDW519Cf1go+0k05rgree3IqHXN2/KHX+pC0L6CkyA==
|
5+rZJuC7Iqh+VDW519Cf1go+0k05rgree3IqHXN2/KHX+pC0L6CkyA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-06-11T03:10:55Z"
|
lastmodified: "2025-08-20T23:28:44Z"
|
||||||
mac: ENC[AES256_GCM,data:01jMwSJK3zW0vltFj06veiAsJBBSKrN5SJuU87/sfhjrfZHWQ/fOITK4Ihz/d9/J2kA9bMJEM50C3cSBaakdYW4RDkL1P83aOsJLjp/c3WjJ8BApDdzoQzUvkjIVt7qd/jNg13c8d+ofBkeSsZ8T3COrOHCc3RgG961T4Ij9WBY=,iv:cNJUQ8ZEPKPKfUlTYD/Zlfomev3ZC/mnP90Me3ycjMc=,tag:LluaNhFpQbuql208sEyPkA==,type:str]
|
mac: ENC[AES256_GCM,data:ArFy5LYoBr6AhBQkUxGqe2k1wQn/XwRkZYRDTVmFIuCpNWYgTRtUYYBnbvn2FPvpq4avm65/iUKTkvkSnSWMPmj4oCAVOTgZxG0eOlC8c6XEFq0ir9Nz6K8oyStxTcDWfiYlHAxx7EBeGIBrj8TcQHuE2P/PxdPYEJDbnohCRnY=,iv:1tyLcAdfvO/kDE2yZ4kU3l3xCMUVEf9Z2z9X8gjacLY=,tag:H0vcvlmzTaatgtnoiyDvSw==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.10.2
|
version: 3.10.2
|
||||||
|
|||||||
@@ -38,128 +38,128 @@ sops:
|
|||||||
- recipient: age157jemphjzg6zmk373vpccuguyw6e75qnkqmz8pcnn2yue85p939swqqhy0
|
- recipient: age157jemphjzg6zmk373vpccuguyw6e75qnkqmz8pcnn2yue85p939swqqhy0
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkcmtYM1FKMXd1Y1EvMVhk
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSZnFYM2JnRXd2emJFSm5h
|
||||||
UFNSZTVWUGFiKzRsUVhvQWJGa2VJVkxjNkJBCmZBTjNTZlN2NGRZNm8xQkZKazU2
|
Q3RSYktiLzMxRlBKZnpVOStLaXNHNmtLVVgwCkM5UnZEN24wOUVuNnZyMVhoM3Bx
|
||||||
UkRwZjFtYnRTcUlva2k1S05qNzVhMUkKLS0tIDZHR2tWS0RvZGNEZ3hpeVJjUkxN
|
SFZhQWhEbHB3Q1NRSUt5S3lBYmtWTFEKLS0tIE5uTTB6Q0hrWUtodXkzZkZkSHpG
|
||||||
OHlHdVdGcnpaYnkrRHU4b2xzclN0MlUK53/V+ITz49SUgxVeaxBSh7yITBEqWPlB
|
Q0t2cVV3WFAzZjNrdDZiS1Q5YjJybU0K6biA2WO5121mlrOXI7cuhsfFUCB5fAOi
|
||||||
uUIkdKVq93XFfpTG4st00Uj6oow9M+QB43bG/hXjfiv7ALDEfT3XaA==
|
scwVKg77FjgECrjJIWwlzGrznW5pJaQ5ZIfHMW+wt5zVBTHfwU9Oyw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age13g9a4d4jrvckfddpgn8sm4kjtzajr67le56pfdg78ktr5pd09phq32j89u
|
- recipient: age13g9a4d4jrvckfddpgn8sm4kjtzajr67le56pfdg78ktr5pd09phq32j89u
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkRjVWY0pKNzB3QmpXRGJM
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNZGxsMHl0cHFObkJRL2Vu
|
||||||
MEticE10YWhKNm94R1VIbWpwUklUV0R5TkZVCkR1bmZEV0hOQWt6WXRlMk9mYmlx
|
MThuK24vQ2JtL2ZucG5LYXBzL2pJTjMwcURFClZsMkZCWHptZlpDakl3NW1TRVhN
|
||||||
Q3cwMEdGeGs3RGd2NGIzTUhFb2tWVjgKLS0tIFNmVjdXdjBmZGZTYy9RZWxQbFo1
|
Q3dkK0FVblZxamhETEhza2dyV0hoQzAKLS0tIFlhK0c3czRCbGU4eWZNRXRNcjN4
|
||||||
YUp0SHhqejc3dndlOFA4dDB4aXFUb0kKcKAVGwr8t2nsFNcmrkwpYAhdjfdsV9oN
|
MTkvZ3pVa2VrOGlWZzI1MEh6azJXRUUK1g78WdC8kugPyfSNmE/abme0OAux8r6F
|
||||||
YZqicWUc07Lu05vMS8MomwupAtkwxy+MswWd6jD0nzp8CIfhOgOpjA==
|
HzLnPgFdqbmxMqgEx1kqV10dAdp6JAy31zXHoX/Gb0dK271gRo/1Wg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1wpvfpv5n32lruk7c0da4uaeapsmhjxdvg8z4ljehn06l6g2y0e0sum404l
|
- recipient: age1wpvfpv5n32lruk7c0da4uaeapsmhjxdvg8z4ljehn06l6g2y0e0sum404l
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNQUpETHZvM0Y3ZHQ1a082
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2R3lHQ3hzQW9SNWNiS3RZ
|
||||||
b01xWDI5d0NpREhOd3JVQ1cyRlhzakFTR0FRCmJrMTRYTWhhWERlbFU0cGlqZ010
|
VTFUemJRUnRLcHNWdVVvblRrMk1rVHRDY0JnCjVSWFRYTGorWTRDOU9SMXNhV3BP
|
||||||
QzdHSWlxZEtodVB0cXdiYi9MM0h4WW8KLS0tIGNLNlVERk1RY3haaWpRd1RjTkY0
|
akRUaytZYThHMS9HK2lQUTBBQ1FWWGMKLS0tIERnTzBuSlJLVmtSNW8wcHhxWVlt
|
||||||
NkhqampldGlwNi85NUxLUFNKaXBwRW8K6DLM1IE1pxpuQ/NA/ywLCocqVxQ/4a9a
|
TnJmQTNFWWtRZ0VQdkZmZ0pjS0dLMm8K5szoKD6/RvBrkUL2P4asRzCq+718jDaz
|
||||||
e8aNYcwXaD628b5HLotHtgzrjA37txAzfqElzvamOxL8/1IgvZVauQ==
|
wuTQ+6Jqcso3caHbJpcf1VlkE/HjaI64cVMlt97j53XT02JyZmxiWw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1jv8ap5zwa49ftv0gg7wqf5ps0e68uuwxe2fekjsn0zkyql964unqyc58rf
|
- recipient: age1jv8ap5zwa49ftv0gg7wqf5ps0e68uuwxe2fekjsn0zkyql964unqyc58rf
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSdUF5VWhVNXJWMWxwb2hI
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKRnpyRy9Ra2RSeU96K2Qz
|
||||||
Mis5aGtXNUdWVnNBMjg2L050eXhYUWRVL0hFCmlSQWtLTlFGNFVITmt6dDcvQ0Rp
|
MWFjcjZVQnk0NE9QcDhSengzaGVSczFkNFUwCkNuMEhQNENTZUJwYUVVN2FYem5F
|
||||||
cEhVTS83eEpoRitPZ29mQlZnT3RJVmsKLS0tIC94ZHBNRmpQdW5EM1NwQ2tMWFp0
|
OWIrKzRILys5T1FmSDZYRExxT3A1N0EKLS0tIFVsT2NiamY3S0dKL2FwTjZCSFJ6
|
||||||
RWIxTnVEZDY4TnZXeDRFeXBkSWluZGcKtvV5fbMxUKZ2dp/unsZcsv+V51vNZkjm
|
SjJIVElqeGRqem1PQ2g4WWczSExRQ1kKrV69W1SSfKfE+MicJ7bCTsTTy3op+tWG
|
||||||
LanIBZBYfbeki2C8b+VPE0ELwtzRQNnGz7DrEzKIV3J2RIscAwwRGQ==
|
in6fgwL24wmk5WYClVQuXhYzPH/GyRTLptzYad+lvOUj2CorwUJ4UA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1pm3fehmmk0vmnrscz9vm96rakn46aaldr5ydpscmde3v9x0k3faswwdzxs
|
- recipient: age1pm3fehmmk0vmnrscz9vm96rakn46aaldr5ydpscmde3v9x0k3faswwdzxs
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZUXRFS1RuMytoSmhEY1Uy
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiODBnN2lXUEl2RTVqV3lH
|
||||||
b2pzMHhmcmVrcE5QeVd2d3JmN05QQzZ2ZmhzCmcyZDkrSVlpWjRZNTJlek02c29U
|
ZEJMbG5sT0Nnd09rNlZOczhxSnNsZXM2SW1vCkR3Zlkvci9UK1d0R2tqbmZlU21l
|
||||||
b3ZHdWpSNWhjT1BrbGRXVDRUdW9aZTQKLS0tIG53Y0xwZnd5OVJvb0FMNmQzTS9u
|
U2V6S3FhVXVUQXVnc3ZvZW1LYkNOdjgKLS0tIGtoRVRlRVJRTkZCVE9CWTdsb3ZB
|
||||||
aTR0THNqQ3ZGMjMwb2c5aUJVNTRoVGcKusofba5Zk+GQYtvPVFk8kkQjinF4gn3L
|
Umo1RzBLbkk2c2RmdGN5WWpJeEljMFUKeOqAB6CbuDYc8aNlcQQhxIO1Ms2ding4
|
||||||
rzLJuPql7U/nnFx4obRJEQhrJFXlVrwMmvEyi0Tyz55yH1Y6vZ39aA==
|
JeC/SGoHYIpaKR4oIXz0Lr/Xlu5t8IVfZVlc7CPKdu0UO41qAeQiWw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1mn2afyp9my7y7hcyzum0wdwt49zufnkt8swnyy8pj30cwzs4zvgsthj0lt
|
- recipient: age1mn2afyp9my7y7hcyzum0wdwt49zufnkt8swnyy8pj30cwzs4zvgsthj0lt
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGbU1uN2JBU3FzNkFiS1N2
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWMGFLVGJYTlVjNmZQdmtp
|
||||||
cE11L2NZUEwrNGkwbVhvRVUveFF2aXhDdTFJCnRBS3VxZmFWQStJS3pTcGpmelhy
|
TkVjRWx4Z1R2QTAwVmJMTWNCd0pza0NPU2xVCm9UcFQxVzI3RG9WeXJ4VUQraVMv
|
||||||
Tm5xQXdDT2JraTN0M1JKaUVLNjMydmMKLS0tIHJDWXVPT1dwdzA3TkpIT2xTczVL
|
TUQxRWNFbG1ndzNNMjZvVlhXU1ozU0UKLS0tIGdWeExjWGtJdWhGTWxmS2V3Q0ND
|
||||||
N3g2elREZEVCUDc0VFZBaEZWNWVhaDAKrnqiYwyFjQJnzNd1t1iy82JC9CJrBYEG
|
UHl6b2J4U1BNWHZQK0Z1RGtYRVdzNncK+UhQlaLlYcrZl17jBVHLfyEMMG82pn61
|
||||||
34DFwUhiPQcXjYtW8DhTOXyhQbDrjf1r2cD5+JId+dpIAmG8MDWRxA==
|
V2wtdOZPk1NFNVa1/kTntmfxjK/mV883gVHuUru0HpVIRD8x/lw8Rw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ykkjw57t3z3deup3gtp7dujyaslskn74e0d9hsmqaha2pj3rvazqgndw5a
|
- recipient: age1ykkjw57t3z3deup3gtp7dujyaslskn74e0d9hsmqaha2pj3rvazqgndw5a
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnKzFyMWt1K2t0UXNpeG9G
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxaTVCZmR3QjhBTlhjQkpH
|
||||||
SlAzMVBSZXI5TUxaMzk4OVY2czBwbUFYTWo4CkdGUjdva3B5Z2ZYYXAyVmJYZWdC
|
R0R4ZXNrQms3MmI5cS92Q0l0OG5IS05iQ1JrCitpRnpiY0wxaXc0NzlBZnhqSFpj
|
||||||
Nmt1S2E3RTdNcXMzY3FWMXhIblRZUTgKLS0tIEpCZDBUTXpHL1FrMXVpUzJFMmw1
|
bWFocnRKRDErUTlqNml5OEFTcDkxK1UKLS0tIHgxakcxdTE5TDBrOEFJNGlTRDNz
|
||||||
U3VqVklnUlFrUndXSEs0QTlYMklTdU0K67wrP/l3xaryQTHZB+UZItMmwt3Pm0nB
|
OHF1ZUFGaFVRNlRPRGhDbTlIeE5PdzQKzhiyVOJ0eB6RcVoiKhRykXrMB0msTO1p
|
||||||
l/aJXyIqEXcAuqP36RvzBXQexhFS0q7PbIwjEtAfqK8DGntEsF3PHw==
|
oErds6/XYa5SDABpc7cCMeFX5QYWA6XCquJ1zQ2yquPiBrj1D80Z8g==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1t2d5scrukk0guva5sr97a8tge5j8kd865adezrcru7p269pzwvpsamkgje
|
- recipient: age1t2d5scrukk0guva5sr97a8tge5j8kd865adezrcru7p269pzwvpsamkgje
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCV3UwSWxveDkyUDNtcGFt
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhZ0xVaHlaSTVnb3hKSkhO
|
||||||
YVFQOS81a3NJUng1NmpjVFNncnhTNU5XZjJJCkpKUzV3Kzc2cVlVUDNNWjJ3a0s0
|
NThvL3pzd0lCdjUvZGlUcHlWb1JCRWFUVFNRCnVmVzFvY2F6L0VnNStzNVZ6WjNW
|
||||||
dm95R1lyVCszaGovMjliUmplWGIvN28KLS0tIEN5dHA3bE1WUjJjTlFUTUx1Rm9r
|
NnFjblNMakVKUWlqd3JGWENOQmtVOGMKLS0tIGV5R0htSVJTRXNnd1hnZk4yOWIv
|
||||||
SkhOUXVzbVFRQlRzQTFUYUZjUmM2TkkKZ6OSRYcgUiB0gQLs5xGlrLpjgxYuYXKt
|
bk9BSVJxRGZpbldheW5pNzU2UmdsT2cKh18db9FTk5/Ji/SNXGVamyB1yrIo+Xsi
|
||||||
d3MaGf7cL6QeNEADGPeReXgSBJljI5QLTwyrQVCM4WyFL3hGo6v8Ng==
|
kmeROZP87ALKg7oDX0yvemhhLqfyotzkeOilZEf4cuQwsR2Gq4BZ/w==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1c8qw59ffcq9l77gfmtyc3djtvt3md0u6dwhrjcgsm98ntyf72ufqugj7cg
|
- recipient: age1c8qw59ffcq9l77gfmtyc3djtvt3md0u6dwhrjcgsm98ntyf72ufqugj7cg
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBybnVTRjRDS1RNbzU2ZjY4
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAveFRnL3NhMElqY1ArQS9O
|
||||||
RElxMmcyMVJCbU91cnJock93TFlxREJ5YmxJCml2b1FBWFNMc2VQT1gzK0dUQ1Qy
|
Q1o0ME1sQm1vckFOM0ZkcUF1UzQ4VmhKTlV3CnBIOVZ1Qk40VEFPbHJld1JkQVhs
|
||||||
cDBEbyt0WXRyNVFFemNiV2wwQXV3Z2MKLS0tIHBxbEgxQnRKUTFZT2xldnplZXJ5
|
OEdPVG1TWlZlT1lZMUYvYVFJUTdXK0kKLS0tIFM4N2pONXhWa2hIMGlOcStuZUJ0
|
||||||
dGdJR2JVb1ExWGRQcGR2SWNOVU53eFEKAFyNit0rGZ+z63I/EnJcAmvphZC9aPrJ
|
dmk1cnJvalUzSUdESldjTVdpQVV5ZVEKNr+5rSc1pQbMIQxtNJyNIm4bFvl5b6pa
|
||||||
7+PY7WNLa5VmgxBmwmUW1vvuZq9cFRU7yXPI9LbMtzTy7ByBxztZyw==
|
DvuAmZd3dSTCRPGwv9m2tkbpSlE5Yp3gDe9Ivi82EAIx9ob8aImXBw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
- recipient: age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1M1dYSTV0UGxtTmh6dHZX
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMcHpLWWx3cm00ZGp0bkhn
|
||||||
bXB1eElEMlNOUmhoRjNnZmw4STh2d0x4UHg4CnlhdFEwMjlPWWNuMndQMEJCQUtJ
|
QjN2dVJyRVl5cElObmtWZVdidWYrTTRnd2lrCmVVdERvR0ZzR3FZb0p0YzNQdFFK
|
||||||
YzN3TG54R2JXNldZQ2loT0xUN3Q5YjAKLS0tIGdSRW1zZmlpOTRFTmFCT0RUMWps
|
NStuMEx6QzIvN2lPSUtseGVtRlU4eHcKLS0tIC9NdzQrVDQzV1JWTXNCbDBRN2Fo
|
||||||
Zk40WkZtZkVVeXcwOXFUVEJINU02RmcK2OK9FnYsvgTG4x0RZFt6NYDlG6fiaVsB
|
V3dKbnBuNUZyalIvWER4dlRZaDdUL3MKONyd0ZgC5L06aJKohJE+zS3Zy+Msr3Uy
|
||||||
eVs34Ll3xuddxeGBVuQdeX5kxxzqxe1fBKE+IEzsRSMLQgN2Mdqi7g==
|
DIM84V0OTuzw05ni61L5pqRL51Kyi61hOjCSNF8+Gm3XalL9NEKrfg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1xg6mvj3x6s3t8058c6rsk3q4kskvm6nsffwckxkkjzhyn7r6tczqgkj23p
|
- recipient: age19daqsncuzeh3j6cwk8uxp6yfj8h0qtz02jxlwwy4v8j0mfgznsvq30440g
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBreTg0SmtBeHB3MHd2M2w3
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoS1dJenhHZG1jK1hndzFw
|
||||||
YmUvRTM5ZWFwSVNvUDVDRGVHQmxDZ1FkeXprCmxrREpML09FTzFGOFkwOUUwbjVz
|
UjErT1VMTTNaMHdad09wM1o0QWl1UHVOdG1BCndiajR4aHp2bCtLb1FpWTZLQU9k
|
||||||
ditIODE1b0o0NG5ZekIrTlFoTFFyL2MKLS0tIGVtSTFmTG04MW9QWGJZM0lOdlhM
|
dVI2NnpXT3Jnc2FTZG5vNW4rbWVFbUkKLS0tIDRrYUxPZTE1WU9LVmNRVExia0xN
|
||||||
djlTNTVralMrM2wrZ0Znb0psSkZrejAKr7ydGdN+LQlIgMjWAfGR3EXADwBbhYrd
|
R0JXd3FCUmJTQXkxMXBmcjFNY09YQW8Khz3AliRA5RzNelz+/f6j62qcS2VNJyRg
|
||||||
WsT4TIMH8pemXPAdthgIBSvbBtmTfM2jKFiDXxTEkSmyp8hLxxKJag==
|
SwYg0l2BBALvnI2VDj4X4YYQM5YxgNCtSdsb//ijVkypkDm/wTKp3w==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1rdn39ywgzmc8wlsl5lrfe77e652wzjmjx58gx4k2ydghd35kdqvqscrf3h
|
- recipient: age19w4zafpwnq9yhzuf8r5te2yhq7xlqj76rcgzcz935hllyrz4yvws4jn6ca
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLZko4M0xZMVNOb2ZTOXJp
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMNlhYS0dFd203UXBLMzJa
|
||||||
THNUMUpobWIxR2VtTGZzS0p2ekd0VmYwaUhvCjh5Q2hIRXA1dDY3UFhiaDEzZzg1
|
YUVrZnZYMSt2QXRlbXU3UDhobGFVdmhkUVdJCklpUzZUbFFHNGgxaGltalRjZVlQ
|
||||||
bTduMTVwK2pIUFdpTmNZdUhzSjJpNDAKLS0tIDFFc3grWG5yak1jT0Q1aER4UXd3
|
QjU4QXVHbzUzM1JPREJoZUJJdVpLaFEKLS0tIFVRN09qd0NzVzhuSWN0YmQyZ3l4
|
||||||
SGtpQm9sZkEySWo2TS9UZ0xlTjE1MXcKC2T7uEnnDr06tt4sajTAuwKECQWIxa21
|
TkdzdlIyYVRpRE9OaG5EeE1KNDMwTDQKfy3OEtd6iT6md5AIkwuy61xXtjy2XrVL
|
||||||
alsXZe2lCxN6b5kA1jkQO1/y+zEzvn+z9ui1ZaRuDavkMEUj+QH2qg==
|
BZOwFI4qtDN8SgpCTpkIE+Iyv5XvWMTw8v8+MNuas2CYX0GsN5ODyg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
- recipient: age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvVzFybisva1lJTm9DaU5L
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnaDZaMnBZc0FzcHlQR2t1
|
||||||
Y2JlWERmTEY3ZS84NU80RkwzaGVQc0dlMldjCllXU0dkY2R5dVNpblptTGl6bGtE
|
QVhWTDMyZy9qOXB5RDlMVjh1Ly94RzZPNDJBCjNTbG94bTFJdVpEcXAydVlVbHYy
|
||||||
Q0hwaFdFRHhnMTZwdytjU2xOSWRzeGMKLS0tIHlsSVRnNVlLRzFnbU54L2ppZXFl
|
WWV5YTZqeHhJeDYzQWpUUlhnb1dQb28KLS0tIHNjaWx3eTk0ZDJwdWFsZ0k1U1BR
|
||||||
MFNLVkdtQkxRbDVBV1pGMU5IZzRNdmMKH5o9sT1uerA9ANpJ8nVB15AERNn61s9h
|
NGdjV1dsRjlZbjhUWllsSU9LQmdkMHMK+7GWHmYubQ2m2YjCjo6VibRHCMHE0SUV
|
||||||
l514Enz5GwkKjITsWeb6J+k4VtGd2wfoX2YySDOMNUsXnlH1BvFFBw==
|
mercB7H9IyoHqDyH+VmfMfsKQyhUzNGx21xNwA/AxkrECl781FJMVw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
- recipient: age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXcDVKdW12dFFEd0tVWVBz
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCaDBrcW9UNitUSTJJSXJD
|
||||||
QmJpblJXMWZhbFprZnNvTGhCQzQ3S3Yva0NRCmUyZzJRSVd1SzFzTGN3a01icVJK
|
Y09ZWmZtTDVaNGphYkV0aWdlRjZVWGQrbEFNClpXaUJpZ2pXeHdKbVZTWjMzdEtW
|
||||||
c3RxRnZ2MU1sRDU2UmUrZ2Znd0pCTVkKLS0tIFI3V3BrclBITFZGSjFmTjBhS2c1
|
SGlleEY4a2lnbTVrV2FqQnBQeXRnVnMKLS0tIGh2MDdpcVk0SVZ0eU02bWV4TTc0
|
||||||
U1VIMUEyTTdQd25zMVU5OGd1aUhuVkUK8x6JppexvYSvZe1hn7DuO0t/scXlVU07
|
VE9jKzk2ZkNNMklDTWh3a2NDakxJNFEKITKH9DQKJYN2PCidfZ5A3ypHe0kurphx
|
||||||
an4u0gtwNlmn2hz/QxHa1cIxEc/awQIU3AkotjlzhYug2wbtyZTxjw==
|
4qtUgLbGMEcuGfHXCMUtzJAzh8k74Ld6AzLGSTHEjjjmIRmw1o6LhQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-05-29T02:27:34Z"
|
lastmodified: "2025-05-29T02:27:34Z"
|
||||||
mac: ENC[AES256_GCM,data:GqBTWeckU/ERKV/5OiPuFOSfUXUTEN7OpKKhGbWCl5oTUE1/CkmMheWJy5WiTlk89KAd66+gBK5kG29PQhEOkUcjoLZTdwghOiJVi90+zPdfz1fGkjs570GtNRulEBL13Ld9KRMHbRSOijM33jmgSpHY8Tcb7RzFTVQs6ZpJ6Fk=,iv:groe/8rbUW9PJTyI457u+LQsiBEzc0YKvKpNToTBrdQ=,tag:OvUbSTSR664p+hBa+BQ++A==,type:str]
|
mac: ENC[AES256_GCM,data:GqBTWeckU/ERKV/5OiPuFOSfUXUTEN7OpKKhGbWCl5oTUE1/CkmMheWJy5WiTlk89KAd66+gBK5kG29PQhEOkUcjoLZTdwghOiJVi90+zPdfz1fGkjs570GtNRulEBL13Ld9KRMHbRSOijM33jmgSpHY8Tcb7RzFTVQs6ZpJ6Fk=,iv:groe/8rbUW9PJTyI457u+LQsiBEzc0YKvKpNToTBrdQ=,tag:OvUbSTSR664p+hBa+BQ++A==,type:str]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./nix.nix
|
|
||||||
./homebrew.nix
|
./homebrew.nix
|
||||||
./programs.nix
|
./programs.nix
|
||||||
./system.nix
|
./system.nix
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Auto upgrade nix package and the daemon service.
|
|
||||||
# services.nix-daemon.enable = true;
|
|
||||||
# nix.package = pkgs.nix;
|
|
||||||
|
|
||||||
# Necessary for using flakes on this system.
|
|
||||||
nix = {
|
|
||||||
settings.experimental-features = "nix-command flakes";
|
|
||||||
};
|
|
||||||
|
|
||||||
# The platform the configuration will be used on.
|
|
||||||
nixpkgs = {
|
|
||||||
config.allowUnfree = true;
|
|
||||||
hostPlatform = "aarch64-darwin";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -15,18 +15,36 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
./boot.nix
|
./boot.nix
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./services.nix
|
./services.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
hardware.asahi = {
|
hardware.asahi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
useExperimentalGPUDriver = true;
|
|
||||||
peripheralFirmwareDirectory = ./firmware;
|
peripheralFirmwareDirectory = ./firmware;
|
||||||
setupAsahiSound = true;
|
setupAsahiSound = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
|
user = {
|
||||||
|
name = "matt";
|
||||||
|
extraGroups = [
|
||||||
|
"ratbagd"
|
||||||
|
"input"
|
||||||
|
"scanner"
|
||||||
|
"lp"
|
||||||
|
"video"
|
||||||
|
"i2c"
|
||||||
|
];
|
||||||
|
packages = with pkgs; [
|
||||||
|
firefox
|
||||||
|
tree
|
||||||
|
git
|
||||||
|
box64
|
||||||
|
prismlauncher
|
||||||
|
distrobox
|
||||||
|
];
|
||||||
|
};
|
||||||
desktop = {
|
desktop = {
|
||||||
hyprland = {
|
hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -59,36 +77,33 @@ in
|
|||||||
};
|
};
|
||||||
network = {
|
network = {
|
||||||
hostName = "macbook-pro-nixos";
|
hostName = "macbook-pro-nixos";
|
||||||
|
wifi.enable = false;
|
||||||
|
iwd = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
General = {
|
||||||
|
EnableNetworkConfiguration = true;
|
||||||
|
};
|
||||||
|
Rank = {
|
||||||
|
BandModifier2_4GHz = 1.0;
|
||||||
|
BandModifier5GHz = 5.0;
|
||||||
|
BandModifier6GHz = 10.0;
|
||||||
|
};
|
||||||
|
Network = {
|
||||||
|
AutoConnect = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
extraFirewallCommands = ''
|
||||||
|
iptables -I INPUT -m pkttype --pkt-type multicast -j ACCEPT
|
||||||
|
iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
|
||||||
|
iptables -I INPUT -p udp -m udp --match multiport --dports 1990,2021 -j ACCEPT
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
nixpkgs.config.allowUnsupportedSystem = true;
|
nixpkgs.config.allowUnsupportedSystem = true;
|
||||||
|
|
||||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
|
||||||
users.users.matt = {
|
|
||||||
isNormalUser = true;
|
|
||||||
extraGroups = [
|
|
||||||
"wheel"
|
|
||||||
"keys"
|
|
||||||
"networkmanager"
|
|
||||||
"ratbagd"
|
|
||||||
"input"
|
|
||||||
"scanner"
|
|
||||||
"lp"
|
|
||||||
"video"
|
|
||||||
"i2c"
|
|
||||||
]; # Enable ‘sudo’ for the user.
|
|
||||||
shell = pkgs.zsh;
|
|
||||||
packages = with pkgs; [
|
|
||||||
firefox
|
|
||||||
tree
|
|
||||||
git
|
|
||||||
box64
|
|
||||||
prismlauncher
|
|
||||||
distrobox
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
containers.enable = true;
|
containers.enable = true;
|
||||||
podman.enable = true;
|
podman.enable = true;
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{ lib, modulesPath, ... }:
|
{
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -9,7 +13,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
"uas"
|
"usb_storage"
|
||||||
"sdhci_pci"
|
"sdhci_pci"
|
||||||
];
|
];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
@@ -19,69 +23,11 @@
|
|||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "none";
|
device = "none";
|
||||||
fsType = "tmpfs";
|
fsType = "tmpfs";
|
||||||
};
|
options = [ "mode=755" ];
|
||||||
|
|
||||||
fileSystems."/root" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
"subvol=root"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/etc" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
"subvol=etc"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/tmp" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
"subvol=tmp"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/nix" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
"subvol=nix"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/var/log" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
"subvol=log"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/home" = {
|
|
||||||
device = "/dev/disk/by-uuid/adcc14fa-8bf7-4b4b-a9e4-b038993b96cc";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"compress=zstd"
|
|
||||||
"subvol=home"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = "/dev/disk/by-uuid/23FA-AD3E";
|
device = "/dev/disk/by-uuid/E66E-1A03";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
options = [
|
options = [
|
||||||
"fmask=0022"
|
"fmask=0022"
|
||||||
@@ -89,12 +35,37 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# swapDevices = [
|
fileSystems."/root" = {
|
||||||
# {
|
device = "/dev/disk/by-uuid/335f1bb3-6fdb-474e-972c-77b64e930d03";
|
||||||
# device = "/tmp/swapfile";
|
fsType = "btrfs";
|
||||||
# randomEncryption.enable = true;
|
options = [ "subvol=root" ];
|
||||||
# }
|
};
|
||||||
# ];
|
|
||||||
|
fileSystems."/etc" = {
|
||||||
|
device = "/dev/disk/by-uuid/335f1bb3-6fdb-474e-972c-77b64e930d03";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=etc" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "/dev/disk/by-uuid/335f1bb3-6fdb-474e-972c-77b64e930d03";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=nix" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/log" = {
|
||||||
|
device = "/dev/disk/by-uuid/335f1bb3-6fdb-474e-972c-77b64e930d03";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=log" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home" = {
|
||||||
|
device = "/dev/disk/by-uuid/335f1bb3-6fdb-474e-972c-77b64e930d03";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=home" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
|||||||
@@ -3,118 +3,58 @@
|
|||||||
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
||||||
|
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
user = "matt";
|
|
||||||
# password = config.sops.secrets."pi4/matt-password".path;
|
|
||||||
kernelBundle = pkgs.linuxAndFirmware.latest;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./adguard.nix
|
./adguard.nix
|
||||||
./boot.nix
|
./boot.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./sops.nix
|
./sops.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
hardware.disko.enable = true;
|
hardware = {
|
||||||
};
|
disko.enable = true;
|
||||||
|
raspberry-pi = {
|
||||||
nix = {
|
enable = true;
|
||||||
settings = {
|
variant = "4";
|
||||||
substituters = [
|
|
||||||
"https://nixos-raspberrypi.cachix.org"
|
|
||||||
"https://cache.mjallen.dev"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
|
|
||||||
"cache.mjallen.dev-1:IzFmKCd8/gggI6lcCXsW65qQwiCLGFFN9t9s2iw7Lvc="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Configure nixpkgs
|
|
||||||
nixpkgs = {
|
|
||||||
overlays = lib.mkAfter [
|
|
||||||
(_self: _super: {
|
|
||||||
# This is used in (modulesPath + "/hardware/all-firmware.nix") when at least
|
|
||||||
# enableRedistributableFirmware is enabled
|
|
||||||
# I know no easier way to override this package
|
|
||||||
inherit (kernelBundle) raspberrypiWirelessFirmware;
|
|
||||||
# Some derivations want to use it as an input,
|
|
||||||
# e.g. raspberrypi-dtbs, omxplayer, sd-image-* modules
|
|
||||||
inherit (kernelBundle) raspberrypifw;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.zsh.enable = true;
|
|
||||||
hardware.i2c.enable = true;
|
|
||||||
|
|
||||||
services = {
|
|
||||||
openssh = {
|
|
||||||
enable = true;
|
|
||||||
authorizedKeysFiles = [
|
|
||||||
config.sops.secrets."ssh-keys-public/pi5".path
|
|
||||||
];
|
|
||||||
hostKeys = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.btattach = {
|
|
||||||
before = [ "bluetooth.service" ];
|
|
||||||
after = [ "dev-ttyAMA0.device" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment = {
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
i2c-tools
|
|
||||||
libraspberrypi
|
|
||||||
raspberrypi-eeprom
|
|
||||||
raspberrypifw
|
|
||||||
raspberrypiWirelessFirmware
|
|
||||||
raspberrypi-armstubs
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
users = {
|
|
||||||
mutableUsers = false;
|
|
||||||
users = {
|
|
||||||
"${user}" = {
|
|
||||||
isNormalUser = true;
|
|
||||||
# hashedPasswordFile = password;
|
|
||||||
password = lib.mkForce "BogieDudie1";
|
|
||||||
extraGroups = [
|
|
||||||
"wheel"
|
|
||||||
"docker"
|
|
||||||
"video"
|
|
||||||
];
|
|
||||||
shell = pkgs.zsh;
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
# macBook
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCw9zq8DLGByI5v2gAn95hKNyOsm3g61a2buxu2BBMFysQJgmZPCCLUqRJKhSM5Vm/JOgsAmdpRBRZQoHD+6S844CJHb4v4VIbjkyQgYCuM7Rst2IOZ5QybvsA2/D0nwytZ+HXQqDj2AagUYDbz0gyyIHkDQ5YGBMkvkWz/h1Vci6aoBM7VihEDM4KlWoTVuPeASGM8r5IZ2FS83Djbqo4ov6AYvLMrKB9Z7hmFgH6R3LE0gxOkzbGVXtSuvJyrjvgytoT22UhATjjxSQ9D+YJXXkQoB3lUdg8OoIquUPjMZpl4mR8ffvseWPfcvD1XlD5t+TOHFqKpESO547tlOBYhdpew+NSgAXpamCU6oyV8tDCywLQu2ucxHRn78u6WXzWHkDtffdhzmk6TZaPhWqVHuTGjR4higBgGqUfSaKOMszt+FDRZAr3HtuQ2+zJ8bowK9fW5OqilTtK2HtQqroD9ApegDNbqOz6kGy5IycSXvqPURy/M4lxZxbtBPuemcJs= mattjallen@MacBook-Pro.local"
|
|
||||||
# desktop windows
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ2PYPjZddOzR8OJj16G88KcUhCDLkvrEmpUQP0wKHDUuA27HQQ2ORo66asadwGHY3k1VDZ1ei9l9H++SIIeKOaaUr5yZdktvj4POUNtbd9ZhcS7sZU7BSF+NMDM+h3tImh6z0S7mWvRQOUv3ZM+ZER+5xTWJVG1OOJEpb1drxJk6Qz0wbZKSR7TPNFBLLXlVy7hkNYf07RtDyhCCxNB3hJfa8c+oztnWumwDhDQWLqiUXWIU2QH6iRLGl/WYnujtNvVVaV/Hn3JJkS6MM9dnV3cpoIO0+J7+WfsN9rZ0wXt5yY3GhiGXwmcO5eYVli8lHlLWtK7aYSETyry6CBsLbojzOQO5rSqhpwfF2njAAFAQU0UjLc8PahisIuFKCwHH4iyXXOagiv5K1Mc/0Ak+WhhMPee6vV2p7NTyNpXRvouDbWy5cSRH31WgQ9fK5mIGe5v8nGGqtEhUubUkiOgP+H3UbT2V/nTv/TFKdJcKw+WmizvTrxBmaMjWALlkYl+s= mattl@Jallen-PC"
|
|
||||||
# desktop nixos
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBMydhOc6SnOdB5WrEd7X07DrboAtagCUgXiOJjLov matt@matt-nixos"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
root = {
|
|
||||||
isSystemUser = true;
|
|
||||||
isNormalUser = false;
|
|
||||||
shell = pkgs.zsh;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
user = {
|
||||||
|
name = "matt";
|
||||||
|
password = "BogieDudie1";
|
||||||
|
mutableUsers = false;
|
||||||
|
extraGroups = [
|
||||||
|
"docker"
|
||||||
|
"video"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
network = {
|
||||||
|
hostName = "pi4";
|
||||||
|
ipv4 = {
|
||||||
|
method = "manual";
|
||||||
|
address = "10.0.1.2/24";
|
||||||
|
gateway = "10.0.1.1";
|
||||||
|
dns = "1.1.1.1";
|
||||||
|
};
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowPing = true;
|
||||||
|
allowedTCPPorts = [ 53 ];
|
||||||
|
allowedUDPPorts = [ 53 ];
|
||||||
|
};
|
||||||
|
wifi = {
|
||||||
|
enable = true;
|
||||||
|
powersave = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Root user configuration - explicit to avoid conflicts with home-manager
|
||||||
|
users.users.root = {
|
||||||
|
isSystemUser = true;
|
||||||
|
isNormalUser = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
|
||||||
hostname = "pi4";
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
# Networking configs
|
# Networking configs
|
||||||
networking = {
|
networking = {
|
||||||
hostName = hostname;
|
# hostName = lib.mkForce hostname;
|
||||||
|
|
||||||
defaultGateway.address = "10.0.1.1";
|
defaultGateway.address = "10.0.1.1";
|
||||||
nameservers = [ "10.0.1.1" ];
|
nameservers = [ "10.0.1.1" ];
|
||||||
|
|||||||
@@ -3,121 +3,47 @@
|
|||||||
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
||||||
|
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
user = "matt";
|
|
||||||
password = config.sops.secrets."pi5/matt-password".path;
|
|
||||||
kernelBundle = pkgs.linuxAndFirmware.latest;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./boot.nix
|
./boot.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./services.nix
|
./services.nix
|
||||||
./sops.nix
|
./sops.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
hardware.disko.enable = true;
|
hardware = {
|
||||||
|
disko.enable = true;
|
||||||
|
raspberry-pi = {
|
||||||
|
enable = true;
|
||||||
|
variant = "5";
|
||||||
|
};
|
||||||
|
};
|
||||||
desktop.hyprland.enable = false;
|
desktop.hyprland.enable = false;
|
||||||
network = {
|
user = {
|
||||||
hostName = "pi5";
|
name = "matt";
|
||||||
};
|
password = "BogieDudie1";
|
||||||
};
|
mutableUsers = false;
|
||||||
|
extraGroups = [ "docker" ];
|
||||||
# Enable nix flakes and nix-command tools
|
sshKeys = [
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
substituters = [
|
|
||||||
"https://nixos-raspberrypi.cachix.org"
|
|
||||||
# "https://cache.mjallen.dev"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
|
|
||||||
# "cache.mjallen.dev-1:IzFmKCd8/gggI6lcCXsW65qQwiCLGFFN9t9s2iw7Lvc="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Configure nixpkgs
|
|
||||||
nixpkgs = {
|
|
||||||
overlays = lib.mkAfter [
|
|
||||||
(_self: _super: {
|
|
||||||
# This is used in (modulesPath + "/hardware/all-firmware.nix") when at least
|
|
||||||
# enableRedistributableFirmware is enabled
|
|
||||||
# I know no easier way to override this package
|
|
||||||
inherit (kernelBundle) raspberrypiWirelessFirmware;
|
|
||||||
# Some derivations want to use it as an input,
|
|
||||||
# e.g. raspberrypi-dtbs, omxplayer, sd-image-* modules
|
|
||||||
inherit (kernelBundle) raspberrypifw;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
system.nixos.tags =
|
|
||||||
let
|
|
||||||
cfg = config.boot.loader.raspberry-pi;
|
|
||||||
in
|
|
||||||
[
|
|
||||||
"raspberry-pi-${cfg.variant}"
|
|
||||||
cfg.bootloader
|
|
||||||
config.boot.kernelPackages.kernel.version
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services.btattach = {
|
|
||||||
before = [ "bluetooth.service" ];
|
|
||||||
after = [ "dev-ttyAMA0.device" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment = {
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
erofs-utils
|
|
||||||
fex
|
|
||||||
libraspberrypi
|
|
||||||
raspberrypi-eeprom
|
|
||||||
raspberrypifw
|
|
||||||
raspberrypiWirelessFirmware
|
|
||||||
raspberrypi-armstubs
|
|
||||||
squashfuse
|
|
||||||
squashfsTools
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.graphics.enable32Bit = lib.mkForce false;
|
|
||||||
|
|
||||||
users = {
|
|
||||||
mutableUsers = false;
|
|
||||||
users."${user}" = {
|
|
||||||
isNormalUser = true;
|
|
||||||
# hashedPasswordFile = password;
|
|
||||||
password = lib.mkForce "BogieDudie1";
|
|
||||||
extraGroups = [
|
|
||||||
"wheel"
|
|
||||||
"docker"
|
|
||||||
];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
# macBook
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCw9zq8DLGByI5v2gAn95hKNyOsm3g61a2buxu2BBMFysQJgmZPCCLUqRJKhSM5Vm/JOgsAmdpRBRZQoHD+6S844CJHb4v4VIbjkyQgYCuM7Rst2IOZ5QybvsA2/D0nwytZ+HXQqDj2AagUYDbz0gyyIHkDQ5YGBMkvkWz/h1Vci6aoBM7VihEDM4KlWoTVuPeASGM8r5IZ2FS83Djbqo4ov6AYvLMrKB9Z7hmFgH6R3LE0gxOkzbGVXtSuvJyrjvgytoT22UhATjjxSQ9D+YJXXkQoB3lUdg8OoIquUPjMZpl4mR8ffvseWPfcvD1XlD5t+TOHFqKpESO547tlOBYhdpew+NSgAXpamCU6oyV8tDCywLQu2ucxHRn78u6WXzWHkDtffdhzmk6TZaPhWqVHuTGjR4higBgGqUfSaKOMszt+FDRZAr3HtuQ2+zJ8bowK9fW5OqilTtK2HtQqroD9ApegDNbqOz6kGy5IycSXvqPURy/M4lxZxbtBPuemcJs= mattjallen@MacBook-Pro.local"
|
|
||||||
# desktop windows
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ2PYPjZddOzR8OJj16G88KcUhCDLkvrEmpUQP0wKHDUuA27HQQ2ORo66asadwGHY3k1VDZ1ei9l9H++SIIeKOaaUr5yZdktvj4POUNtbd9ZhcS7sZU7BSF+NMDM+h3tImh6z0S7mWvRQOUv3ZM+ZER+5xTWJVG1OOJEpb1drxJk6Qz0wbZKSR7TPNFBLLXlVy7hkNYf07RtDyhCCxNB3hJfa8c+oztnWumwDhDQWLqiUXWIU2QH6iRLGl/WYnujtNvVVaV/Hn3JJkS6MM9dnV3cpoIO0+J7+WfsN9rZ0wXt5yY3GhiGXwmcO5eYVli8lHlLWtK7aYSETyry6CBsLbojzOQO5rSqhpwfF2njAAFAQU0UjLc8PahisIuFKCwHH4iyXXOagiv5K1Mc/0Ak+WhhMPee6vV2p7NTyNpXRvouDbWy5cSRH31WgQ9fK5mIGe5v8nGGqtEhUubUkiOgP+H3UbT2V/nTv/TFKdJcKw+WmizvTrxBmaMjWALlkYl+s= mattl@Jallen-PC"
|
|
||||||
# desktop nixos
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBMydhOc6SnOdB5WrEd7X07DrboAtagCUgXiOJjLov matt@matt-nixos"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTha0FbV1tkpnJr7xVH78S5MetJH+0o2YrEcuvhL692 root@jallen-nas"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTha0FbV1tkpnJr7xVH78S5MetJH+0o2YrEcuvhL692 root@jallen-nas"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIwoHWOLSTGVif9hAhaMLl0qDA4roIzCNuyR6kyIXDOj admin@jallen-nas"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIwoHWOLSTGVif9hAhaMLl0qDA4roIzCNuyR6kyIXDOj admin@jallen-nas"
|
||||||
];
|
];
|
||||||
shell = pkgs.zsh;
|
|
||||||
};
|
};
|
||||||
users.root.shell = pkgs.zsh;
|
network = {
|
||||||
|
hostName = "pi5";
|
||||||
|
ipv4 = {
|
||||||
|
method = "manual";
|
||||||
|
gateway = "10.0.1.1";
|
||||||
|
dns = "10.0.1.1";
|
||||||
|
};
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowPing = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
zramSwap.enable = true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
services = {
|
services = {
|
||||||
xserver.desktopManager.gnome.enable = true;
|
|
||||||
|
|
||||||
shairport-sync = {
|
shairport-sync = {
|
||||||
enable = false;
|
enable = false;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
|
|||||||
@@ -51,17 +51,6 @@ let
|
|||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# nix = {
|
|
||||||
# settings = {
|
|
||||||
# substituters = [
|
|
||||||
# "https://cache.mjallen.dev"
|
|
||||||
# ];
|
|
||||||
# trusted-public-keys = [
|
|
||||||
# "cache.mjallen.dev-1:IzFmKCd8/gggI6lcCXsW65qQwiCLGFFN9t9s2iw7Lvc="
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
chaotic.mesa-git.enable = false;
|
chaotic.mesa-git.enable = false;
|
||||||
|
|
||||||
# Environment configuration
|
# Environment configuration
|
||||||
@@ -84,6 +73,7 @@ in
|
|||||||
brscan5.enable = false;
|
brscan5.enable = false;
|
||||||
# extraBackends = [ pkgsVersion.brscan5 ];
|
# extraBackends = [ pkgsVersion.brscan5 ];
|
||||||
};
|
};
|
||||||
|
flipperzero.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Common Configuration
|
# Common Configuration
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ in
|
|||||||
./configuration.nix
|
./configuration.nix
|
||||||
./filesystems.nix
|
./filesystems.nix
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
# ./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./nix.nix
|
./nix.nix
|
||||||
./sops.nix
|
./sops.nix
|
||||||
|
|
||||||
@@ -38,10 +38,22 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
|
hardware.disko.enable = false;
|
||||||
bootloader.lanzaboote.enable = true;
|
bootloader.lanzaboote.enable = true;
|
||||||
|
impermanence.enable = true;
|
||||||
desktop.gnome.enable = true;
|
desktop.gnome.enable = true;
|
||||||
network = {
|
network = {
|
||||||
hostName = "matt-nixos";
|
hostName = "matt-nixos";
|
||||||
|
wifi = {
|
||||||
|
enable = true;
|
||||||
|
powersave = false;
|
||||||
|
profiles = {
|
||||||
|
"Joey's Jungle 6G" = {
|
||||||
|
ssid = "Joey's Jungle 6G";
|
||||||
|
keyMgmt = "sae";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
user = {
|
user = {
|
||||||
passwordFile = passwordFile;
|
passwordFile = passwordFile;
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ in
|
|||||||
fsType = "bcachefs";
|
fsType = "bcachefs";
|
||||||
options = [
|
options = [
|
||||||
"noatime"
|
"noatime"
|
||||||
] ++ defaultLocalOptions;
|
]
|
||||||
|
++ defaultLocalOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Network shares
|
# Network shares
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ in
|
|||||||
options = [
|
options = [
|
||||||
"subvol=nix"
|
"subvol=nix"
|
||||||
"noatime"
|
"noatime"
|
||||||
] ++ defeaultBtrfsOptions;
|
]
|
||||||
|
++ defeaultBtrfsOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/etc" = {
|
fileSystems."/etc" = {
|
||||||
@@ -41,7 +42,8 @@ in
|
|||||||
options = [
|
options = [
|
||||||
"subvol=etc"
|
"subvol=etc"
|
||||||
"noatime"
|
"noatime"
|
||||||
] ++ defeaultBtrfsOptions;
|
]
|
||||||
|
++ defeaultBtrfsOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/root" = {
|
fileSystems."/root" = {
|
||||||
@@ -50,7 +52,8 @@ in
|
|||||||
options = [
|
options = [
|
||||||
"subvol=root"
|
"subvol=root"
|
||||||
"noatime"
|
"noatime"
|
||||||
] ++ defeaultBtrfsOptions;
|
]
|
||||||
|
++ defeaultBtrfsOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/var/log" = {
|
fileSystems."/var/log" = {
|
||||||
@@ -59,7 +62,8 @@ in
|
|||||||
options = [
|
options = [
|
||||||
"subvol=log"
|
"subvol=log"
|
||||||
"noatime"
|
"noatime"
|
||||||
] ++ defeaultBtrfsOptions;
|
]
|
||||||
|
++ defeaultBtrfsOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/home" = {
|
fileSystems."/home" = {
|
||||||
@@ -67,7 +71,8 @@ in
|
|||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [
|
options = [
|
||||||
"subvol=home"
|
"subvol=home"
|
||||||
] ++ defeaultBtrfsOptions;
|
]
|
||||||
|
++ defeaultBtrfsOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
|
|||||||
@@ -8,4 +8,4 @@
|
|||||||
environment.variables = {
|
environment.variables = {
|
||||||
LSFG_DLL_PATH = "/media/matt/data/steam/steamapps/common/Lossless Scaling/Lossless.dll";
|
LSFG_DLL_PATH = "/media/matt/data/steam/steamapps/common/Lossless Scaling/Lossless.dll";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
services = {
|
services = {
|
||||||
|
# Existing properly namespaced services
|
||||||
immich.enable = true;
|
immich.enable = true;
|
||||||
jellyfin.enable = true;
|
jellyfin.enable = true;
|
||||||
jellyseerr.enable = true;
|
jellyseerr.enable = true;
|
||||||
@@ -11,93 +12,92 @@
|
|||||||
paperless.enable = true;
|
paperless.enable = true;
|
||||||
traefik.enable = true;
|
traefik.enable = true;
|
||||||
wyoming.enable = true;
|
wyoming.enable = true;
|
||||||
|
|
||||||
|
# Newly migrated services
|
||||||
|
actual = {
|
||||||
|
enable = true;
|
||||||
|
port = 3333;
|
||||||
|
localAddress = "10.0.3.18";
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/actual";
|
||||||
|
reverseProxy = {
|
||||||
|
enable = true;
|
||||||
|
host = "actual.mjallen.dev";
|
||||||
|
middlewares = [
|
||||||
|
"crowdsec"
|
||||||
|
"whitelist-geoblock"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
arrs = {
|
||||||
|
enable = true;
|
||||||
|
localAddress = "10.0.1.51";
|
||||||
|
downloadsDir = "/media/nas/main/ssd_app_data/downloads";
|
||||||
|
incompleteDownloadsDir = "/media/nas/main/ssd_app_data/downloads-incomplete";
|
||||||
|
moviesDir = "/media/nas/main/movies";
|
||||||
|
tvDir = "/media/nas/main/tv";
|
||||||
|
isosDir = "/media/nas/main/isos";
|
||||||
|
radarr = {
|
||||||
|
enable = true;
|
||||||
|
port = 7878;
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/radarr";
|
||||||
|
};
|
||||||
|
sonarr = {
|
||||||
|
enable = true;
|
||||||
|
port = 8989;
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/sonarr";
|
||||||
|
};
|
||||||
|
sabnzbd = {
|
||||||
|
enable = true;
|
||||||
|
port = 8280;
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/sabnzbd";
|
||||||
|
};
|
||||||
|
deluge = {
|
||||||
|
enable = true;
|
||||||
|
port = 8112;
|
||||||
|
};
|
||||||
|
jackett = {
|
||||||
|
enable = true;
|
||||||
|
port = 9117;
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/jackett";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
crowdsec = {
|
||||||
|
enable = true;
|
||||||
|
port = 9898;
|
||||||
|
apiAddress = "10.0.1.3";
|
||||||
|
apiKey = "1daH89qmJ41r2Lpd9hvDw4sxtOAtBzaj3aKFOFqE";
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/crowdsec";
|
||||||
|
};
|
||||||
|
|
||||||
|
gitea = {
|
||||||
|
enable = true;
|
||||||
|
httpPort = 3000;
|
||||||
|
sshPort = 2222;
|
||||||
|
localAddress = "10.0.4.18";
|
||||||
|
dataDir = "/media/nas/main/nix-app-data/gitea";
|
||||||
|
reverseProxy = {
|
||||||
|
enable = true;
|
||||||
|
host = "gitea.mjallen.dev";
|
||||||
|
middlewares = [
|
||||||
|
"crowdsec"
|
||||||
|
"whitelist-geoblock"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
free-games-claimer.enable = true;
|
||||||
|
|
||||||
|
manyfold.enable = true;
|
||||||
|
|
||||||
|
orca-slicer = {
|
||||||
|
enable = true;
|
||||||
|
httpPort = "3100";
|
||||||
|
httpsPort = "3101";
|
||||||
|
};
|
||||||
|
|
||||||
|
tdarr.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
nas-apps = {
|
|
||||||
actual = {
|
|
||||||
enable = true;
|
|
||||||
port = 3333;
|
|
||||||
localAddress = "10.0.3.18";
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/actual";
|
|
||||||
reverseProxy = {
|
|
||||||
enable = true;
|
|
||||||
host = "actual.mjallen.dev";
|
|
||||||
middlewares = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
arrs = {
|
|
||||||
enable = true;
|
|
||||||
localAddress = "10.0.1.51";
|
|
||||||
downloadsDir = "/media/nas/main/ssd_app_data/downloads";
|
|
||||||
incompleteDownloadsDir = "/media/nas/main/ssd_app_data/downloads-incomplete";
|
|
||||||
moviesDir = "/media/nas/main/movies";
|
|
||||||
tvDir = "/media/nas/main/tv";
|
|
||||||
isosDir = "/media/nas/main/isos";
|
|
||||||
radarr = {
|
|
||||||
enable = true;
|
|
||||||
port = 7878;
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/radarr";
|
|
||||||
};
|
|
||||||
sonarr = {
|
|
||||||
enable = true;
|
|
||||||
port = 8989;
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/sonarr";
|
|
||||||
};
|
|
||||||
sabnzbd = {
|
|
||||||
enable = true;
|
|
||||||
port = 8280;
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/sabnzbd";
|
|
||||||
};
|
|
||||||
deluge = {
|
|
||||||
enable = true;
|
|
||||||
port = 8112;
|
|
||||||
};
|
|
||||||
jackett = {
|
|
||||||
enable = true;
|
|
||||||
port = 9117;
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/jackett";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
crowdsec = {
|
|
||||||
enable = true;
|
|
||||||
port = 9898;
|
|
||||||
apiAddress = "10.0.1.3";
|
|
||||||
apiKey = "1daH89qmJ41r2Lpd9hvDw4sxtOAtBzaj3aKFOFqE";
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/crowdsec";
|
|
||||||
};
|
|
||||||
|
|
||||||
gitea = {
|
|
||||||
enable = true;
|
|
||||||
httpPort = 3000;
|
|
||||||
sshPort = 2222;
|
|
||||||
localAddress = "10.0.4.18";
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/gitea";
|
|
||||||
reverseProxy = {
|
|
||||||
enable = true;
|
|
||||||
host = "gitea.mjallen.dev";
|
|
||||||
middlewares = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
free-games-claimer.enable = true;
|
|
||||||
|
|
||||||
manyfold.enable = true;
|
|
||||||
|
|
||||||
orca-slicer = {
|
|
||||||
enable = true;
|
|
||||||
httpPort = "3100";
|
|
||||||
httpsPort = "3101";
|
|
||||||
};
|
|
||||||
|
|
||||||
tdarr.enable = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib) types mkOption;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.nas-apps = mkOption {
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule (
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 80;
|
|
||||||
};
|
|
||||||
|
|
||||||
localAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
reverseProxy = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
host = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
middlewares = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
{ pkgs, ... }:
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
configLimit = 50;
|
configLimit = 50;
|
||||||
kernel = pkgs.linuxPackages; # linuxPackages_latest;
|
kernel = pkgs.linuxPackages; # linuxPackages_latest;
|
||||||
@@ -35,6 +40,8 @@ in
|
|||||||
consoleLogLevel = 3;
|
consoleLogLevel = 3;
|
||||||
bootspec.enable = true;
|
bootspec.enable = true;
|
||||||
|
|
||||||
|
plymouth.enable = lib.mkForce false;
|
||||||
|
|
||||||
initrd = {
|
initrd = {
|
||||||
kernelModules = [
|
kernelModules = [
|
||||||
"tpm"
|
"tpm"
|
||||||
@@ -50,7 +57,7 @@ in
|
|||||||
clevis = {
|
clevis = {
|
||||||
enable = true;
|
enable = true;
|
||||||
devices = {
|
devices = {
|
||||||
# "/dev/sde:/dev/sdf:/dev/sdh:/dev/sdi:/dev/sdj".secretFile = "../../../pool.jwe";
|
"/dev/disk/by-label/nas_pool".secretFile = config.sops.secrets."jallen-nas/nas_pool".path;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -59,6 +66,8 @@ in
|
|||||||
binfmt.emulatedSystems = [ "aarch64-linux" ]; # --argstr system aarch64-linux
|
binfmt.emulatedSystems = [ "aarch64-linux" ]; # --argstr system aarch64-linux
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.etc."clevis/nas_pool.jwe".source = config.sops.secrets."jallen-nas/nas_pool".path;
|
||||||
|
|
||||||
zramSwap = {
|
zramSwap = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Edit this configuration file to define what should be installed on
|
# Edit this configuration file to define what should be installed on
|
||||||
# your system. Help is available in the configuration.nix(5) man page, on
|
# your system. Help is available in the configuration.nix(5) man page, on
|
||||||
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
||||||
@@ -6,7 +5,6 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
|
||||||
namespace,
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
@@ -18,8 +16,7 @@
|
|||||||
./boot.nix
|
./boot.nix
|
||||||
./apps.nix
|
./apps.nix
|
||||||
./grafana.nix
|
./grafana.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./nixpkgs.nix
|
|
||||||
./ups.nix
|
./ups.nix
|
||||||
./users.nix
|
./users.nix
|
||||||
./samba.nix
|
./samba.nix
|
||||||
@@ -34,6 +31,15 @@
|
|||||||
${namespace} = {
|
${namespace} = {
|
||||||
bootloader.lanzaboote.enable = true;
|
bootloader.lanzaboote.enable = true;
|
||||||
desktop.cosmic.enable = false;
|
desktop.cosmic.enable = false;
|
||||||
|
development = {
|
||||||
|
enable = true;
|
||||||
|
includeLanguages = [
|
||||||
|
"python"
|
||||||
|
"c"
|
||||||
|
];
|
||||||
|
includeContainers = true;
|
||||||
|
};
|
||||||
|
monitoring.enable = true;
|
||||||
hardware.nvidia = {
|
hardware.nvidia = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableBeta = true;
|
enableBeta = true;
|
||||||
@@ -46,10 +52,72 @@
|
|||||||
ipv4 = {
|
ipv4 = {
|
||||||
address = "10.0.1.3/24";
|
address = "10.0.1.3/24";
|
||||||
method = "manual";
|
method = "manual";
|
||||||
|
gateway = "10.0.1.1";
|
||||||
|
interface = "wlp6s0";
|
||||||
|
};
|
||||||
|
useNetworkd = true;
|
||||||
|
hostId = "4b501480";
|
||||||
|
nat = {
|
||||||
|
enable = true;
|
||||||
|
internalInterfaces = [ "ve-+" ];
|
||||||
|
externalInterface = "wlp6s0";
|
||||||
|
enableIPv6 = true;
|
||||||
|
};
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowPing = true;
|
||||||
|
allowedTCPPorts = [
|
||||||
|
8008 # restic
|
||||||
|
9000 # authentik
|
||||||
|
2342 # grafana
|
||||||
|
51820 # wireguard
|
||||||
|
1025
|
||||||
|
1143
|
||||||
|
10200
|
||||||
|
10300
|
||||||
|
8127
|
||||||
|
9980 # onlyoffice
|
||||||
|
4000 # netbootxyz
|
||||||
|
4080 # netbootxyz
|
||||||
|
3000 # gitea
|
||||||
|
2222 # gitea ssh
|
||||||
|
3300
|
||||||
|
9898
|
||||||
|
6754 # lubelogger
|
||||||
|
2283 # immich
|
||||||
|
4444 # code-server
|
||||||
|
9012
|
||||||
|
8192
|
||||||
|
];
|
||||||
|
allowedUDPPorts = [
|
||||||
|
8008 # restic
|
||||||
|
9000 # authentik
|
||||||
|
2342 # grafana
|
||||||
|
51820 # wireguard
|
||||||
|
1025
|
||||||
|
1143
|
||||||
|
10200
|
||||||
|
10300
|
||||||
|
8127
|
||||||
|
9980 # onlyoffice
|
||||||
|
4000 # netbootxyz
|
||||||
|
4080 # netbootxyz
|
||||||
|
3000 # gitea
|
||||||
|
2222 # gitea ssh
|
||||||
|
3300
|
||||||
|
9898
|
||||||
|
6754 # lubelogger
|
||||||
|
2283 # immich
|
||||||
|
4444 # code-server
|
||||||
|
9012
|
||||||
|
8192
|
||||||
|
];
|
||||||
|
trustedInterfaces = [ "tailscale0" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
user = {
|
user = {
|
||||||
name = "admin";
|
name = "admin";
|
||||||
|
linger = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,34 +133,26 @@
|
|||||||
|
|
||||||
systemPackages = with pkgs; [
|
systemPackages = with pkgs; [
|
||||||
attic-client
|
attic-client
|
||||||
binutils
|
bcachefs-tools
|
||||||
cryptsetup
|
cryptsetup
|
||||||
clevis
|
clevis
|
||||||
cmake
|
|
||||||
deconz
|
deconz
|
||||||
duperemove
|
duperemove
|
||||||
efibootmgr
|
efibootmgr
|
||||||
ffmpeg
|
ffmpeg
|
||||||
gcc
|
|
||||||
glances
|
|
||||||
ipset
|
ipset
|
||||||
jq
|
|
||||||
llama-cpp
|
llama-cpp
|
||||||
ninja
|
|
||||||
# inputs.nas-nixai.packages.x86_64-linux.nixai
|
# inputs.nas-nixai.packages.x86_64-linux.nixai
|
||||||
networkmanagerapplet
|
networkmanagerapplet
|
||||||
nmon
|
|
||||||
nut
|
nut
|
||||||
packagekit
|
packagekit
|
||||||
pass
|
pass
|
||||||
protonmail-bridge
|
protonmail-bridge
|
||||||
protonvpn-cli
|
protonvpn-cli
|
||||||
python3
|
|
||||||
python3Packages.llama-cpp-python
|
python3Packages.llama-cpp-python
|
||||||
qrencode
|
qrencode
|
||||||
rcon
|
rcon
|
||||||
sbctl
|
sbctl
|
||||||
speedtest-cli
|
|
||||||
tigervnc
|
tigervnc
|
||||||
tpm2-tools
|
tpm2-tools
|
||||||
tpm2-tss
|
tpm2-tss
|
||||||
@@ -102,8 +162,6 @@
|
|||||||
# Configure programs
|
# Configure programs
|
||||||
programs = {
|
programs = {
|
||||||
virt-manager.enable = true;
|
virt-manager.enable = true;
|
||||||
nix-ld.enable = true;
|
|
||||||
screen.enable = true;
|
|
||||||
coolercontrol = {
|
coolercontrol = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nvidiaSupport = true;
|
nvidiaSupport = true;
|
||||||
@@ -152,58 +210,6 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Virtualisation
|
# Additional virtualization beyond what's in development module
|
||||||
virtualisation = {
|
virtualisation.libvirtd.enable = true;
|
||||||
podman = {
|
|
||||||
enable = true;
|
|
||||||
dockerCompat = true;
|
|
||||||
autoPrune.enable = true;
|
|
||||||
defaultNetwork.settings = {
|
|
||||||
dns_enabled = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
libvirtd.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable nix flakes and nix-command tools
|
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
substituters = [
|
|
||||||
"https://nix-community.cachix.org"
|
|
||||||
"https://cache.nixos.org/"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
];
|
|
||||||
warn-dirty = lib.mkForce false;
|
|
||||||
experimental-features = lib.mkForce [
|
|
||||||
"nix-command"
|
|
||||||
"flakes"
|
|
||||||
];
|
|
||||||
trusted-users = [ "@wheel" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Garbage collect automatically every week
|
|
||||||
gc.automatic = lib.mkDefault true;
|
|
||||||
gc.options = lib.mkDefault "--delete-older-than 30d";
|
|
||||||
|
|
||||||
optimise.automatic = lib.mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Nixpkgs configuration
|
|
||||||
nixpkgs = {
|
|
||||||
config = {
|
|
||||||
allowUnfree = lib.mkForce true;
|
|
||||||
allowUnsupportedSystem = true;
|
|
||||||
permittedInsecurePackages = [
|
|
||||||
# ...
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
nixpkgs.config.allowUnfreePredicate =
|
|
||||||
pkg:
|
|
||||||
builtins.elem (lib.getName pkg) [
|
|
||||||
"vscode-extension-github-copilot"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
let
|
|
||||||
defaultOptions = [ "compress=zstd" ];
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
fileSystems."/mnt" = {
|
fileSystems."/media/nas/main" = {
|
||||||
label = "nas_pool";
|
label = "nas_pool";
|
||||||
# device = "/dev/sde:/dev/sdf:/dev/sdh:/dev/sdi:/dev/:sdj";
|
# device = "/dev/sde:/dev/sdf:/dev/sdh:/dev/sdi:/dev/sdj:/dev/nmve0n1:/dev/nvme1n1";
|
||||||
fsType = "bcachefs";
|
fsType = "bcachefs";
|
||||||
mountPoint = "/media/nas/main";
|
mountPoint = "/media/nas/main";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Configure nixpkgs
|
|
||||||
nixpkgs = {
|
|
||||||
config = {
|
|
||||||
# Enable non free
|
|
||||||
allowUnfree = true;
|
|
||||||
|
|
||||||
# enable cuda support
|
|
||||||
cudaSupport = true;
|
|
||||||
allowUnfreePredicate =
|
|
||||||
p:
|
|
||||||
builtins.all (
|
|
||||||
license:
|
|
||||||
license.free
|
|
||||||
|| builtins.elem license.shortName [
|
|
||||||
"CUDA EULA"
|
|
||||||
"cuDNN EULA"
|
|
||||||
"cuTENSOR EULA"
|
|
||||||
"NVidia OptiX EULA"
|
|
||||||
]
|
|
||||||
) (if builtins.isList p.meta.license then p.meta.license else [ p.meta.license ]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
Common Settings:
|
|
||||||
INTERVAL=10
|
|
||||||
|
|
||||||
Settings of hwmon6/pwm5: -- chipset?
|
|
||||||
Depends on hwmon6/temp9_input
|
|
||||||
Controls hwmon6/fan5_input
|
|
||||||
MINTEMP=20
|
|
||||||
MAXTEMP=60
|
|
||||||
MINSTART=16
|
|
||||||
MINSTOP=14
|
|
||||||
MINPWM=14
|
|
||||||
|
|
||||||
Settings of hwmon6/pwm4: -- case?
|
|
||||||
Depends on hwmon2/temp1_input
|
|
||||||
Controls hwmon6/fan4_input
|
|
||||||
MINTEMP=20
|
|
||||||
MAXTEMP=90
|
|
||||||
MINSTART=60
|
|
||||||
MINSTOP=45
|
|
||||||
|
|
||||||
Settings of hwmon6/pwm3: -- cpu?
|
|
||||||
Depends on hwmon2/temp1_input
|
|
||||||
Controls hwmon6/fan3_input
|
|
||||||
MINTEMP=20
|
|
||||||
MAXTEMP=90
|
|
||||||
MINSTART=150
|
|
||||||
MINSTOP=0
|
|
||||||
MAXPWM=30
|
|
||||||
|
|
||||||
Settings of hwmon6/pwm2: -- cpu?
|
|
||||||
Depends on hwmon2/temp1_input
|
|
||||||
Controls hwmon6/fan2_input
|
|
||||||
MINTEMP=20
|
|
||||||
MAXTEMP=90
|
|
||||||
MINSTART=105
|
|
||||||
MINSTOP=0
|
|
||||||
@@ -34,6 +34,12 @@ in
|
|||||||
group = config.users.users."${user}".group;
|
group = config.users.users."${user}".group;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"jallen-nas/nas_pool" = {
|
||||||
|
mode = "0600";
|
||||||
|
owner = config.users.users."${user}".name;
|
||||||
|
group = config.users.users."${user}".group;
|
||||||
|
};
|
||||||
|
|
||||||
"wifi" = {
|
"wifi" = {
|
||||||
sopsFile = sharedSops;
|
sopsFile = sharedSops;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
{
|
{
|
||||||
lib,
|
|
||||||
namespace,
|
namespace,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./boot.nix
|
./boot.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./users.nix
|
./users.nix
|
||||||
./sops.nix
|
./sops.nix
|
||||||
];
|
];
|
||||||
@@ -17,43 +16,36 @@
|
|||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
services.home-assistant.enable = true;
|
services.home-assistant.enable = true;
|
||||||
hardware.disko.enable = true;
|
hardware.disko = {
|
||||||
network.hostName = "nuc-nixos";
|
enable = true;
|
||||||
};
|
# filesystem = "bcachefs";
|
||||||
|
|
||||||
# Enable nix flakes and nix-command tools
|
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
substituters = [
|
|
||||||
"https://nix-community.cachix.org"
|
|
||||||
"https://cache.nixos.org/"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
];
|
|
||||||
warn-dirty = lib.mkForce false;
|
|
||||||
experimental-features = lib.mkForce [
|
|
||||||
"nix-command"
|
|
||||||
"flakes"
|
|
||||||
];
|
|
||||||
trusted-users = [ "@wheel" ];
|
|
||||||
};
|
};
|
||||||
|
impermanence.enable = true;
|
||||||
# Garbage collect automatically every week
|
network = {
|
||||||
gc.automatic = lib.mkDefault true;
|
hostName = "nuc-nixos";
|
||||||
gc.options = lib.mkDefault "--delete-older-than 30d";
|
useNetworkd = false;
|
||||||
|
ipv4 = {
|
||||||
optimise.automatic = lib.mkDefault true;
|
method = "manual";
|
||||||
};
|
address = "10.0.1.4/24";
|
||||||
|
gateway = "10.0.1.1";
|
||||||
# Nixpkgs configuration
|
dns = "10.0.1.1";
|
||||||
nixpkgs = {
|
};
|
||||||
config = {
|
wifi = {
|
||||||
allowUnfree = lib.mkForce true;
|
enable = true;
|
||||||
allowUnsupportedSystem = true;
|
profiles = {
|
||||||
permittedInsecurePackages = [
|
"Joey's Jungle 6G" = {
|
||||||
# ...
|
ssid = "Joey's Jungle 6G";
|
||||||
];
|
keyMgmt = "sae";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowPing = true;
|
||||||
|
allowedTCPPorts = [ 8192 ];
|
||||||
|
allowedUDPPorts = [ 8192 ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,5 @@ in
|
|||||||
# Further reduce systemd output
|
# Further reduce systemd output
|
||||||
systemd = {
|
systemd = {
|
||||||
services.systemd-udev-settle.enable = false;
|
services.systemd-udev-settle.enable = false;
|
||||||
extraConfig = ''
|
|
||||||
ShowStatus=no
|
|
||||||
DefaultTimeoutStartSec=15s
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = lib.mkForce true;
|
|
||||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
users.users = {
|
users.users = {
|
||||||
deck = {
|
deck = {
|
||||||
|
|||||||
@@ -15,19 +15,30 @@
|
|||||||
./boot.nix
|
./boot.nix
|
||||||
./configuration.nix
|
./configuration.nix
|
||||||
./jovian.nix
|
./jovian.nix
|
||||||
./networking.nix
|
# ./networking.nix - moved to modules/nixos/network
|
||||||
./sops.nix
|
./sops.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
|
|
||||||
${namespace} = {
|
${namespace} = {
|
||||||
hardware.disko.enable = true;
|
hardware.disko.enable = true;
|
||||||
|
impermanence.enable = true;
|
||||||
bootloader.lanzaboote.enable = true;
|
bootloader.lanzaboote.enable = true;
|
||||||
desktop.gnome.enable = true;
|
desktop.gnome.enable = true;
|
||||||
user = {
|
user = {
|
||||||
name = "deck";
|
name = "deck";
|
||||||
};
|
};
|
||||||
network.hostName = "steamdeck";
|
network = {
|
||||||
|
hostName = "steamdeck";
|
||||||
|
wifi = {
|
||||||
|
enable = true;
|
||||||
|
powersave = false;
|
||||||
|
profiles = {
|
||||||
|
"Joey's Jungle 5G" = {
|
||||||
|
ssid = "Joey's Jungle 5G";
|
||||||
|
keyMgmt = "sae";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
551
update-check.py
551
update-check.py
@@ -1,551 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Automatic Nix package update checker
|
|
||||||
Auto-discovers and checks GitHub-based Nix packages for updates
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import argparse
|
|
||||||
import requests
|
|
||||||
import subprocess
|
|
||||||
import shutil
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict, List, Optional, Tuple, NamedTuple
|
|
||||||
from dataclasses import dataclass
|
|
||||||
import sys
|
|
||||||
|
|
||||||
class PackageInfo(NamedTuple):
|
|
||||||
owner: str
|
|
||||||
repo: str
|
|
||||||
version: str
|
|
||||||
rev: str
|
|
||||||
current_hash: str
|
|
||||||
package_name: str
|
|
||||||
file_path: Path
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class UpdateResult:
|
|
||||||
name: str
|
|
||||||
current_version: str
|
|
||||||
latest_version: str
|
|
||||||
has_update: bool
|
|
||||||
file_path: Path
|
|
||||||
repo_url: str
|
|
||||||
current_hash: Optional[str] = None
|
|
||||||
new_hash: Optional[str] = None
|
|
||||||
error: Optional[str] = None
|
|
||||||
|
|
||||||
class NixPackageChecker:
|
|
||||||
def __init__(self, search_paths: List[str] = None, max_depth: int = 3):
|
|
||||||
self.search_paths = search_paths or ["."]
|
|
||||||
self.max_depth = max_depth
|
|
||||||
self.session = requests.Session()
|
|
||||||
self.session.headers.update({'User-Agent': 'nix-package-checker'})
|
|
||||||
|
|
||||||
def find_nix_packages(self) -> List[Path]:
|
|
||||||
"""Auto-discover Nix package files with fetchFromGitHub"""
|
|
||||||
packages = []
|
|
||||||
|
|
||||||
for search_path in self.search_paths:
|
|
||||||
base_path = Path(search_path)
|
|
||||||
if not base_path.exists():
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Find .nix files up to max_depth
|
|
||||||
for depth in range(self.max_depth + 1):
|
|
||||||
pattern = "**/" * depth + "*.nix"
|
|
||||||
for nix_file in base_path.glob(pattern):
|
|
||||||
if self._is_github_package(nix_file):
|
|
||||||
packages.append(nix_file)
|
|
||||||
|
|
||||||
return sorted(set(packages))
|
|
||||||
|
|
||||||
def _is_github_package(self, nix_file: Path) -> bool:
|
|
||||||
"""Check if a .nix file contains fetchFromGitHub"""
|
|
||||||
try:
|
|
||||||
content = nix_file.read_text(encoding='utf-8')
|
|
||||||
return 'fetchFromGitHub' in content and any(
|
|
||||||
pattern in content for pattern in ['owner =', 'repo =', 'version =']
|
|
||||||
)
|
|
||||||
except (UnicodeDecodeError, PermissionError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def compare_versions(self, current: str, latest: str) -> bool:
|
|
||||||
"""Compare versions, return True if latest is newer"""
|
|
||||||
if current == latest:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Handle HACS-X format
|
|
||||||
hacs_current = re.match(r'HACS-(\d+)', current)
|
|
||||||
hacs_latest = re.match(r'HACS-(\d+)', latest)
|
|
||||||
if hacs_current and hacs_latest:
|
|
||||||
return int(hacs_latest.group(1)) > int(hacs_current.group(1))
|
|
||||||
|
|
||||||
# Handle semantic versioning vX.Y.Z
|
|
||||||
sem_current = re.match(r'v?(\d+)\.(\d+)\.(\d+)', current)
|
|
||||||
sem_latest = re.match(r'v?(\d+)\.(\d+)\.(\d+)', latest)
|
|
||||||
if sem_current and sem_latest:
|
|
||||||
curr_parts = tuple(map(int, sem_current.groups()))
|
|
||||||
lat_parts = tuple(map(int, sem_latest.groups()))
|
|
||||||
return lat_parts > curr_parts
|
|
||||||
|
|
||||||
# Fallback to string comparison
|
|
||||||
return latest > current
|
|
||||||
|
|
||||||
def parse_nix_file(self, nix_file: Path) -> Optional[PackageInfo]:
|
|
||||||
"""Extract package information from a .nix file"""
|
|
||||||
try:
|
|
||||||
content = nix_file.read_text(encoding='utf-8')
|
|
||||||
except (UnicodeDecodeError, PermissionError) as e:
|
|
||||||
print(f"❌ Error reading {nix_file}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Patterns to extract fields
|
|
||||||
patterns = {
|
|
||||||
'owner': r'owner\s*=\s*"([^"]+)"',
|
|
||||||
'repo': r'repo\s*=\s*"([^"]+)"',
|
|
||||||
'version': r'version\s*=\s*"([^"]+)"',
|
|
||||||
'rev': r'rev\s*=\s*(?:"([^"]+)"|([^;"\s]+))',
|
|
||||||
'hash': r'hash\s*=\s*"([^"]+)"',
|
|
||||||
# Package name patterns (in order of preference)
|
|
||||||
'domain': r'domain\s*=\s*"([^"]+)"', # Home Assistant components
|
|
||||||
'pname': r'pname\s*=\s*"([^"]+)"', # Standard Nix convention
|
|
||||||
'name': r'name\s*=\s*"([^"]+)"' # Older convention
|
|
||||||
}
|
|
||||||
|
|
||||||
extracted = {}
|
|
||||||
for field, pattern in patterns.items():
|
|
||||||
match = re.search(pattern, content)
|
|
||||||
if match:
|
|
||||||
if field == 'rev':
|
|
||||||
# Handle both quoted and unquoted rev values
|
|
||||||
extracted[field] = match.group(1) or match.group(2)
|
|
||||||
else:
|
|
||||||
extracted[field] = match.group(1)
|
|
||||||
|
|
||||||
# Validate required fields
|
|
||||||
required = ['owner', 'repo', 'version']
|
|
||||||
if not all(field in extracted for field in required):
|
|
||||||
missing = [f for f in required if f not in extracted]
|
|
||||||
print(f"⚠️ {nix_file.name}: Missing fields: {missing}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Handle rev = version case
|
|
||||||
rev = extracted.get('rev', extracted['version'])
|
|
||||||
if rev == 'version':
|
|
||||||
rev = extracted['version']
|
|
||||||
|
|
||||||
# Extract current hash (may not exist for all packages)
|
|
||||||
current_hash = extracted.get('hash', '')
|
|
||||||
|
|
||||||
# Determine package name (priority: domain > pname > name > repo > directory)
|
|
||||||
package_name = None
|
|
||||||
for name_field in ['domain', 'pname', 'name']:
|
|
||||||
if name_field in extracted:
|
|
||||||
package_name = extracted[name_field]
|
|
||||||
break
|
|
||||||
|
|
||||||
if not package_name:
|
|
||||||
# Fall back to repo name
|
|
||||||
package_name = extracted['repo']
|
|
||||||
|
|
||||||
# If still no name and it's in a subdirectory, use directory name
|
|
||||||
if not package_name or package_name == extracted['repo']:
|
|
||||||
parent_dir = nix_file.parent.name
|
|
||||||
if parent_dir != '.' and parent_dir != nix_file.parent.parent.name:
|
|
||||||
package_name = f"{parent_dir}-{extracted['repo']}" if package_name == extracted['repo'] else parent_dir
|
|
||||||
|
|
||||||
return PackageInfo(
|
|
||||||
owner=extracted['owner'],
|
|
||||||
repo=extracted['repo'],
|
|
||||||
version=extracted['version'],
|
|
||||||
rev=rev,
|
|
||||||
current_hash=current_hash,
|
|
||||||
package_name=package_name,
|
|
||||||
file_path=nix_file
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_latest_release(self, owner: str, repo: str) -> Optional[str]:
|
|
||||||
"""Get latest GitHub release tag"""
|
|
||||||
url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = self.session.get(url, timeout=10)
|
|
||||||
if response.status_code == 200:
|
|
||||||
return response.json().get('tag_name')
|
|
||||||
elif response.status_code == 404:
|
|
||||||
# Try getting tags if no releases
|
|
||||||
return self._get_latest_tag(owner, repo)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ API error for {owner}/{repo}: {response.status_code}")
|
|
||||||
return None
|
|
||||||
except requests.RequestException as e:
|
|
||||||
print(f"⚠️ Network error for {owner}/{repo}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_latest_tag(self, owner: str, repo: str) -> Optional[str]:
|
|
||||||
"""Fallback to get latest tag if no releases"""
|
|
||||||
url = f"https://api.github.com/repos/{owner}/{repo}/tags"
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = self.session.get(url, timeout=10)
|
|
||||||
if response.status_code == 200:
|
|
||||||
tags = response.json()
|
|
||||||
return tags[0]['name'] if tags else None
|
|
||||||
except requests.RequestException:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_github_hash(self, owner: str, repo: str, rev: str) -> Optional[str]:
|
|
||||||
"""Get hash for GitHub source using nix-prefetch-url or nix-prefetch-github"""
|
|
||||||
# Try nix-prefetch-url first (more commonly available)
|
|
||||||
if shutil.which('nix-prefetch-url'):
|
|
||||||
return self._get_hash_with_prefetch_url(owner, repo, rev)
|
|
||||||
# Fall back to nix-prefetch-github
|
|
||||||
elif shutil.which('nix-prefetch-github'):
|
|
||||||
return self._get_hash_with_prefetch_github(owner, repo, rev)
|
|
||||||
else:
|
|
||||||
print("⚠️ Neither nix-prefetch-url nor nix-prefetch-github found.")
|
|
||||||
print(" nix-prefetch-url is included in nix by default")
|
|
||||||
print(" nix-prefetch-github: nix-env -iA nixpkgs.nix-prefetch-github")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_hash_with_prefetch_url(self, owner: str, repo: str, rev: str) -> Optional[str]:
|
|
||||||
"""Get hash using nix-prefetch-url with GitHub archive URL"""
|
|
||||||
# GitHub archive URL format
|
|
||||||
url = f"https://github.com/{owner}/{repo}/archive/{rev}.tar.gz"
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Use --unpack to match fetchFromGitHub behavior
|
|
||||||
cmd = ['nix-prefetch-url', '--unpack', url]
|
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
|
||||||
|
|
||||||
if result.returncode == 0:
|
|
||||||
# nix-prefetch-url outputs the hash directly (sha256)
|
|
||||||
hash_value = result.stdout.strip()
|
|
||||||
return hash_value
|
|
||||||
else:
|
|
||||||
print(f"⚠️ nix-prefetch-url failed for {owner}/{repo}@{rev}:")
|
|
||||||
print(f" URL: {url}")
|
|
||||||
print(f" Error: {result.stderr.strip()}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
print(f"⚠️ Timeout fetching hash for {owner}/{repo}@{rev} (60s limit)")
|
|
||||||
return None
|
|
||||||
except subprocess.SubprocessError as e:
|
|
||||||
print(f"⚠️ Error with nix-prefetch-url for {owner}/{repo}@{rev}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_hash_with_prefetch_github(self, owner: str, repo: str, rev: str) -> Optional[str]:
|
|
||||||
"""Get hash using nix-prefetch-github (fallback method)"""
|
|
||||||
try:
|
|
||||||
cmd = ['nix-prefetch-github', owner, repo, '--rev', rev]
|
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
|
||||||
|
|
||||||
if result.returncode == 0:
|
|
||||||
# Parse JSON output to get sha256
|
|
||||||
data = json.loads(result.stdout)
|
|
||||||
return data.get('sha256')
|
|
||||||
else:
|
|
||||||
print(f"⚠️ nix-prefetch-github failed for {owner}/{repo}@{rev}:")
|
|
||||||
print(f" {result.stderr.strip()}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
print(f"⚠️ Timeout fetching hash for {owner}/{repo}@{rev}")
|
|
||||||
return None
|
|
||||||
except (subprocess.SubprocessError, json.JSONDecodeError) as e:
|
|
||||||
print(f"⚠️ Error with nix-prefetch-github for {owner}/{repo}@{rev}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def update_nix_file(self, pkg_info: PackageInfo, new_version: str, new_hash: str) -> bool:
|
|
||||||
"""Update a .nix file with new version and hash"""
|
|
||||||
try:
|
|
||||||
content = pkg_info.file_path.read_text(encoding='utf-8')
|
|
||||||
|
|
||||||
# Create backup
|
|
||||||
backup_path = pkg_info.file_path.with_suffix('.nix.backup')
|
|
||||||
backup_path.write_text(content, encoding='utf-8')
|
|
||||||
|
|
||||||
# Update version
|
|
||||||
content = re.sub(
|
|
||||||
r'(version\s*=\s*)"[^"]+";',
|
|
||||||
f'\\1"{new_version}";',
|
|
||||||
content
|
|
||||||
)
|
|
||||||
|
|
||||||
# Update hash
|
|
||||||
if pkg_info.current_hash:
|
|
||||||
content = re.sub(
|
|
||||||
r'(hash\s*=\s*)"[^"]+";',
|
|
||||||
f'\\1"sha256-{new_hash}";',
|
|
||||||
content
|
|
||||||
)
|
|
||||||
|
|
||||||
# Write updated content
|
|
||||||
pkg_info.file_path.write_text(content, encoding='utf-8')
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ Error updating {pkg_info.file_path}: {e}")
|
|
||||||
return False
|
|
||||||
"""Compare versions, return True if latest is newer"""
|
|
||||||
if current == latest:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Handle HACS-X format
|
|
||||||
hacs_current = re.match(r'HACS-(\d+)', current)
|
|
||||||
hacs_latest = re.match(r'HACS-(\d+)', latest)
|
|
||||||
if hacs_current and hacs_latest:
|
|
||||||
return int(hacs_latest.group(1)) > int(hacs_current.group(1))
|
|
||||||
|
|
||||||
# Handle semantic versioning vX.Y.Z
|
|
||||||
sem_current = re.match(r'v?(\d+)\.(\d+)\.(\d+)', current)
|
|
||||||
sem_latest = re.match(r'v?(\d+)\.(\d+)\.(\d+)', latest)
|
|
||||||
if sem_current and sem_latest:
|
|
||||||
curr_parts = tuple(map(int, sem_current.groups()))
|
|
||||||
lat_parts = tuple(map(int, sem_latest.groups()))
|
|
||||||
return lat_parts > curr_parts
|
|
||||||
|
|
||||||
# Fallback to string comparison
|
|
||||||
return latest > current
|
|
||||||
|
|
||||||
def check_package(self, pkg_info: PackageInfo, fetch_hash: bool = False) -> UpdateResult:
|
|
||||||
"""Check a single package for updates"""
|
|
||||||
latest_version = self.get_latest_release(pkg_info.owner, pkg_info.repo)
|
|
||||||
|
|
||||||
if latest_version is None:
|
|
||||||
return UpdateResult(
|
|
||||||
name=pkg_info.package_name,
|
|
||||||
current_version=pkg_info.version,
|
|
||||||
latest_version="unknown",
|
|
||||||
has_update=False,
|
|
||||||
file_path=pkg_info.file_path,
|
|
||||||
repo_url=f"https://github.com/{pkg_info.owner}/{pkg_info.repo}",
|
|
||||||
current_hash=pkg_info.current_hash,
|
|
||||||
error="Could not fetch latest release"
|
|
||||||
)
|
|
||||||
|
|
||||||
has_update = self.compare_versions(pkg_info.version, latest_version)
|
|
||||||
new_hash = None
|
|
||||||
|
|
||||||
# Fetch new hash if update available and requested
|
|
||||||
if has_update and fetch_hash:
|
|
||||||
print(f" 🔄 Fetching hash for {pkg_info.package_name} ({pkg_info.owner}/{pkg_info.repo}@{latest_version})...")
|
|
||||||
new_hash = self.get_github_hash(pkg_info.owner, pkg_info.repo, latest_version)
|
|
||||||
|
|
||||||
return UpdateResult(
|
|
||||||
name=pkg_info.package_name,
|
|
||||||
current_version=pkg_info.version,
|
|
||||||
latest_version=latest_version,
|
|
||||||
has_update=has_update,
|
|
||||||
file_path=pkg_info.file_path,
|
|
||||||
repo_url=f"https://github.com/{pkg_info.owner}/{pkg_info.repo}",
|
|
||||||
current_hash=pkg_info.current_hash,
|
|
||||||
new_hash=new_hash
|
|
||||||
)
|
|
||||||
|
|
||||||
def check_all_packages(self, fetch_hash: bool = False, auto_update: bool = False) -> List[UpdateResult]:
|
|
||||||
"""Check all discovered packages"""
|
|
||||||
nix_files = self.find_nix_packages()
|
|
||||||
|
|
||||||
if not nix_files:
|
|
||||||
print("No Nix package files found")
|
|
||||||
return []
|
|
||||||
|
|
||||||
print(f"Found {len(nix_files)} package files")
|
|
||||||
|
|
||||||
# Show which hash fetching tool is available
|
|
||||||
if fetch_hash or auto_update:
|
|
||||||
if shutil.which('nix-prefetch-url'):
|
|
||||||
print("Hash fetching: using nix-prefetch-url")
|
|
||||||
elif shutil.which('nix-prefetch-github'):
|
|
||||||
print("Hash fetching: using nix-prefetch-github")
|
|
||||||
else:
|
|
||||||
print("⚠️ No hash fetching tool available")
|
|
||||||
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for nix_file in nix_files:
|
|
||||||
pkg_info = self.parse_nix_file(nix_file)
|
|
||||||
if pkg_info:
|
|
||||||
result = self.check_package(pkg_info, fetch_hash=fetch_hash)
|
|
||||||
results.append(result)
|
|
||||||
|
|
||||||
# Auto-update if requested and update available
|
|
||||||
if auto_update and result.has_update and result.new_hash:
|
|
||||||
print(f" 🔄 Auto-updating {result.name}...")
|
|
||||||
if self.update_nix_file(pkg_info, result.latest_version, result.new_hash):
|
|
||||||
print(f" ✅ Updated {result.file_path}")
|
|
||||||
else:
|
|
||||||
print(f" ❌ Failed to update {result.file_path}")
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
def print_results(results: List[UpdateResult], show_all: bool = True, show_hashes: bool = False):
|
|
||||||
"""Print results in a nice format"""
|
|
||||||
if not results:
|
|
||||||
return
|
|
||||||
|
|
||||||
updates_available = [r for r in results if r.has_update]
|
|
||||||
|
|
||||||
if show_all:
|
|
||||||
print(f"\n{'Package':<25} {'Current':<15} {'Latest':<15} {'Status'}")
|
|
||||||
print("-" * 70)
|
|
||||||
|
|
||||||
for result in results:
|
|
||||||
if result.error:
|
|
||||||
status = f"❌ {result.error}"
|
|
||||||
elif result.has_update:
|
|
||||||
status = "🔄 Update available"
|
|
||||||
else:
|
|
||||||
status = "✅ Up to date"
|
|
||||||
|
|
||||||
print(f"{result.name:<25} {result.current_version:<15} {result.latest_version:<15} {status}")
|
|
||||||
|
|
||||||
# Show file path for default.nix files or when there might be confusion
|
|
||||||
if result.file_path.name == 'default.nix' or len([r for r in results if r.name == result.name]) > 1:
|
|
||||||
rel_path = result.file_path.relative_to(Path.cwd()) if result.file_path.is_absolute() else result.file_path
|
|
||||||
print(f"{'':>25} File: {rel_path}")
|
|
||||||
|
|
||||||
# Show hash information if available and requested
|
|
||||||
if show_hashes and result.has_update and result.new_hash:
|
|
||||||
print(f"{'':>25} Current hash: {result.current_hash[:16]}..." if result.current_hash else "")
|
|
||||||
print(f"{'':>25} New hash: sha256-{result.new_hash[:16]}...")
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
print(f"\nSummary:")
|
|
||||||
print(f" Total packages: {len(results)}")
|
|
||||||
print(f" Updates available: {len(updates_available)}")
|
|
||||||
|
|
||||||
if updates_available:
|
|
||||||
print(f"\nPackages with updates:")
|
|
||||||
for result in updates_available:
|
|
||||||
rel_path = result.file_path.relative_to(Path.cwd()) if result.file_path.is_absolute() else result.file_path
|
|
||||||
print(f" • {result.name}: {result.current_version} → {result.latest_version}")
|
|
||||||
print(f" File: {rel_path}")
|
|
||||||
print(f" Repo: {result.repo_url}")
|
|
||||||
if show_hashes and result.new_hash:
|
|
||||||
print(f" New hash: sha256-{result.new_hash}")
|
|
||||||
|
|
||||||
def print_updates_only(results: List[UpdateResult], show_hashes: bool = False):
|
|
||||||
"""Print only packages with updates"""
|
|
||||||
updates = [r for r in results if r.has_update]
|
|
||||||
|
|
||||||
if not updates:
|
|
||||||
print("No updates available")
|
|
||||||
return
|
|
||||||
|
|
||||||
print("Updates available:")
|
|
||||||
for result in updates:
|
|
||||||
rel_path = result.file_path.relative_to(Path.cwd()) if result.file_path.is_absolute() else result.file_path
|
|
||||||
print(f" {result.name}: {result.current_version} → {result.latest_version}")
|
|
||||||
print(f" File: {rel_path}")
|
|
||||||
if show_hashes and result.new_hash:
|
|
||||||
print(f" New hash: sha256-{result.new_hash}")
|
|
||||||
elif show_hashes:
|
|
||||||
print(f" Hash: (not fetched)")
|
|
||||||
|
|
||||||
def output_json(results: List[UpdateResult]):
|
|
||||||
"""Output results as JSON"""
|
|
||||||
data = {}
|
|
||||||
for result in results:
|
|
||||||
data[result.name] = {
|
|
||||||
"current_version": result.current_version,
|
|
||||||
"latest_version": result.latest_version,
|
|
||||||
"has_update": result.has_update,
|
|
||||||
"file_path": str(result.file_path),
|
|
||||||
"repo_url": result.repo_url,
|
|
||||||
"current_hash": result.current_hash,
|
|
||||||
"new_hash": result.new_hash,
|
|
||||||
"error": result.error
|
|
||||||
}
|
|
||||||
|
|
||||||
print(json.dumps(data, indent=2))
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Automatically check Nix packages for GitHub updates",
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
||||||
epilog="""
|
|
||||||
Examples:
|
|
||||||
%(prog)s # Check all packages in current directory
|
|
||||||
%(prog)s --updates # Show only packages with updates
|
|
||||||
%(prog)s --fetch-hash # Also fetch new hashes for updates
|
|
||||||
%(prog)s --auto-update # Automatically update .nix files
|
|
||||||
%(prog)s --json # Output as JSON
|
|
||||||
%(prog)s --path ./packages # Check specific directory
|
|
||||||
%(prog)s --depth 5 # Search deeper directory levels
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
For hash fetching: nix-prefetch-url (part of nix) or nix-prefetch-github
|
|
||||||
nix-prefetch-url is preferred and usually already available
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument('--updates', action='store_true',
|
|
||||||
help='Show only packages with updates available')
|
|
||||||
parser.add_argument('--fetch-hash', action='store_true',
|
|
||||||
help='Fetch new hashes for packages with updates (requires nix-prefetch-url or nix-prefetch-github)')
|
|
||||||
parser.add_argument('--auto-update', action='store_true',
|
|
||||||
help='Automatically update .nix files with new versions and hashes')
|
|
||||||
parser.add_argument('--json', action='store_true',
|
|
||||||
help='Output results as JSON')
|
|
||||||
parser.add_argument('--path', action='append', default=[],
|
|
||||||
help='Search path for .nix files (can be used multiple times)')
|
|
||||||
parser.add_argument('--depth', type=int, default=3,
|
|
||||||
help='Maximum directory depth to search (default: 3)')
|
|
||||||
parser.add_argument('--list', action='store_true',
|
|
||||||
help='List discovered package files without checking updates')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Auto-update implies fetch-hash
|
|
||||||
if args.auto_update:
|
|
||||||
args.fetch_hash = True
|
|
||||||
|
|
||||||
# Use provided paths or default to current directory
|
|
||||||
search_paths = args.path if args.path else ["."]
|
|
||||||
|
|
||||||
checker = NixPackageChecker(search_paths=search_paths, max_depth=args.depth)
|
|
||||||
|
|
||||||
if args.list:
|
|
||||||
# Just list discovered files
|
|
||||||
nix_files = checker.find_nix_packages()
|
|
||||||
print(f"Discovered {len(nix_files)} package files:")
|
|
||||||
for nix_file in nix_files:
|
|
||||||
pkg_info = checker.parse_nix_file(nix_file)
|
|
||||||
if pkg_info:
|
|
||||||
rel_path = nix_file.relative_to(Path.cwd()) if nix_file.is_absolute() else nix_file
|
|
||||||
print(f" {pkg_info.package_name:<25} {pkg_info.owner}/{pkg_info.repo} ({pkg_info.version}) - {rel_path}")
|
|
||||||
else:
|
|
||||||
rel_path = nix_file.relative_to(Path.cwd()) if nix_file.is_absolute() else nix_file
|
|
||||||
print(f" {'(parse failed)':<25} - {rel_path}")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Check for updates
|
|
||||||
results = checker.check_all_packages(
|
|
||||||
fetch_hash=args.fetch_hash,
|
|
||||||
auto_update=args.auto_update
|
|
||||||
)
|
|
||||||
|
|
||||||
if not results:
|
|
||||||
print("No packages found to check")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Output results
|
|
||||||
if args.json:
|
|
||||||
output_json(results)
|
|
||||||
elif args.updates:
|
|
||||||
print_updates_only(results, show_hashes=args.fetch_hash)
|
|
||||||
else:
|
|
||||||
print_results(results, show_all=True, show_hashes=args.fetch_hash)
|
|
||||||
|
|
||||||
# Set exit code based on updates available
|
|
||||||
updates_available = any(r.has_update for r in results)
|
|
||||||
sys.exit(1 if updates_available else 0)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user