Compare commits
7 Commits
46b249560f
...
af840f242b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af840f242b | ||
|
|
d9f17670e1 | ||
|
|
c1028fc0f0 | ||
|
|
5466c59dde | ||
|
|
d53093a6c1 | ||
|
|
5d1d3dc850 | ||
|
|
f4fd826c90 |
@@ -27,11 +27,6 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# nixos-generators = {
|
||||
# url = "github:nix-community/nixos-generators";
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
# };
|
||||
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
|
||||
lanzaboote.url = "github:nix-community/lanzaboote/v1.0.0";
|
||||
@@ -144,7 +139,6 @@
|
||||
systems = {
|
||||
# common modules
|
||||
modules.nixos = with inputs; [
|
||||
# nix-cachyos-kernel.nixosModules.default
|
||||
authentik-nix.nixosModules.default
|
||||
disko.nixosModules.disko
|
||||
impermanence.nixosModules.impermanence
|
||||
|
||||
@@ -43,220 +43,6 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
# programs.nix-plist-manager = {
|
||||
# enable = true;
|
||||
# options = {
|
||||
# applications = {
|
||||
# finder = {
|
||||
# settings = {
|
||||
# general = {
|
||||
# showTheseItemsOnTheDesktop = {
|
||||
# hardDisks = false;
|
||||
# externalDisks = true;
|
||||
# cdsDvdsAndiPods = false;
|
||||
# connectedServers = false;
|
||||
# };
|
||||
# openFoldersInTabsInsteadOfNewWindows = true;
|
||||
# };
|
||||
# sidebar = {
|
||||
# recentTags = true;
|
||||
# };
|
||||
# advanced = {
|
||||
# removeItemsFromTheTrashAfter30Days = true;
|
||||
# showAllFilenameExtensions = true;
|
||||
# showWarningBeforeChangingAnExtension = true;
|
||||
# showWarningBeforeRemovingFromiCloudDrive = true;
|
||||
# showWarningBeforeEmptyingTheTrash = true;
|
||||
# keepFoldersOnTop = {
|
||||
# inWindowsWhenSortingByName = true;
|
||||
# onDesktop = true;
|
||||
# };
|
||||
# whenPerformingASearch = "Search This Mac";
|
||||
# };
|
||||
# };
|
||||
# menuBar = {
|
||||
# view = {
|
||||
# showTabBar = true;
|
||||
# showSidebar = true;
|
||||
# showPathBar = true;
|
||||
# showStatusBar = true;
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# systemSettings = {
|
||||
# appearance = {
|
||||
# appearance = "Dark";
|
||||
# accentColor = "Multicolor";
|
||||
# # clickInTheScrollBarTo = "Jump to the next page";
|
||||
# sidebarIconSize = "Medium";
|
||||
# showScrollBars = "When scrolling";
|
||||
# };
|
||||
# controlCenter = {
|
||||
# wifi = true;
|
||||
# bluetooth = true;
|
||||
# airdrop = true;
|
||||
# stageManager = true;
|
||||
# focusModes = "active";
|
||||
# screenMirroring = "active";
|
||||
# display = "never";
|
||||
# sound = "always";
|
||||
# nowPlaying = "active";
|
||||
# accessibilityShortcuts = "unset";
|
||||
# musicRecognition = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# hearing = "unset";
|
||||
# fastUserSwitching = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# keyboardBrightness = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# battery = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = false;
|
||||
# };
|
||||
# batteryShowPercentage = true;
|
||||
# # menuBarOnly = {
|
||||
# # spotlight = false;
|
||||
# # siri = true;
|
||||
# # };
|
||||
# # automaticallyHideAndShowTheMenuBar = "In Full Screen Only";
|
||||
# };
|
||||
# desktopAndDock = {
|
||||
# desktopAndStageManager = {
|
||||
# showItems = {
|
||||
# onDesktop = true;
|
||||
# inStageManager = true;
|
||||
# };
|
||||
# clickWallpaperToRevealDesktop = "Always";
|
||||
# stageManager = false;
|
||||
# showRecentAppsInStageManager = true;
|
||||
# showWindowsFromAnApplication = "All at Once";
|
||||
# };
|
||||
# dock = {
|
||||
# animateOpeningApplications = true;
|
||||
# automaticallyHideAndShowTheDock = enabled;
|
||||
# doubleClickAWindowsTitleBarTo = "Minimize";
|
||||
# magnification = disabled;
|
||||
# minimizeWindowsIntoApplicationIcon = true;
|
||||
# minimizeWindowsUsing = "Genie Effect";
|
||||
# positionOnScreen = "Bottom";
|
||||
# showIndicatorsForOpenApplications = true;
|
||||
# showSuggestedAndRecentAppsInDock = false;
|
||||
# size = 64; # 16 - 128
|
||||
# # persistentApps = [
|
||||
# # { app = "/Applications/Clock.app"; }
|
||||
# # { folder = "/Applications"; }
|
||||
# # { app = "/Applications/Safari.app"; }
|
||||
# # { app = "/Applications/Firefox.app"; }
|
||||
# # { app = "/Applications/Tabby.app"; }
|
||||
# # { app = "/Applications/Termius.app"; }
|
||||
# # { app = "/Applications/Muic.app"; }
|
||||
# # { app = "/Applications/Vesktop.app"; }
|
||||
# # { app = "/Applications/Messages.app"; }
|
||||
# # { app = "/Applications/Calendar.app"; }
|
||||
# # { app = "/Applications/Reminders.app"; }
|
||||
# # { app = "/Applications/Notes.app"; }
|
||||
# # { app = "/Applications/Weather.app"; }
|
||||
# # { app = "/Applications/Maps.app"; }
|
||||
# # { app = "/Applications/App Store.app"; }
|
||||
# # { app = "/Applications/System Settings.app"; }
|
||||
# # { app = "/Applications/ChatGPT.app"; }
|
||||
# # { app = "/Applications/Nextcloud.app"; }
|
||||
# # { app = "/Applications/VSCodium.app"; }
|
||||
# # { app = "/Applications/Omnissa Horizon Client.app"; }
|
||||
# # { app = "/Applications/Proton Pass.app"; }
|
||||
# # { app = "/Applications/OrcaSlicer.app"; }
|
||||
# # { app = "/Applications/AlDente.app"; }
|
||||
# # ];
|
||||
# # persistentOthers = [
|
||||
# # "~/Downloads"
|
||||
# # ];
|
||||
# };
|
||||
# hotCorners = {
|
||||
# # ["-" "Mission Control" "Application Windows" "Desktop" "Start Screen Saver" "Disable Screen Saver" "Dashboard" "Put Display to Sleep" "Launchpad" "Notification Center" "Lock Screen" "Quick Note"]
|
||||
# topLeft = "-";
|
||||
# topRight = "-";
|
||||
# bottomLeft = "-";
|
||||
# bottomRight = "-";
|
||||
# };
|
||||
# missionControl = {
|
||||
# automaticallyRearrangeSpacesBasedOnMostRecentUse = true;
|
||||
# displaysHaveSeparateSpaces = true;
|
||||
# dragWindowsToTopOfScreenToEnterMissionControl = true;
|
||||
# groupWindowsByApplication = true;
|
||||
# whenSwitchingToAnApplicationSwitchToAspaceWithOpenWindowsForTheApplication = true;
|
||||
# };
|
||||
# widgets = {
|
||||
# showWidgets = {
|
||||
# onDesktop = true;
|
||||
# inStageManager = true;
|
||||
# };
|
||||
# widgetStyle = "Automatic";
|
||||
# useIphoneWidgets = true;
|
||||
# };
|
||||
# windows = {
|
||||
# askToKeepChangesWhenClosingDocuments = true;
|
||||
# closeWindowsWhenQuittingAnApplication = true;
|
||||
# dragWindowsToScreenEdgesToTile = true;
|
||||
# dragWindowsToMenuBarToFillScreen = true;
|
||||
# holdOptionKeyWhileDraggingWindowsToTile = true;
|
||||
# preferTabsWhenOpeningDocuments = "In Full Screen";
|
||||
# tiledWindowsHaveMargin = false;
|
||||
# };
|
||||
# };
|
||||
# focus = {
|
||||
# shareAcrossDevices = true;
|
||||
# };
|
||||
# # general.dateAndTime."24HourTime" = false;
|
||||
# notifications = {
|
||||
# notificationCenter = {
|
||||
# showPreviews = "When Unlocked";
|
||||
# summarizeNotifications = true;
|
||||
# };
|
||||
# };
|
||||
# sound = {
|
||||
# soundEffects = {
|
||||
# alertSound = "Boop";
|
||||
# alertVolume = 0.7;
|
||||
# playFeedbackWhenVolumeIsChanged = true;
|
||||
# playUserInterfaceSoundEffects = true;
|
||||
# };
|
||||
# };
|
||||
# spotlight = {
|
||||
# helpAppleImproveSearch = false;
|
||||
# # searchResults = {
|
||||
# # applications = true;
|
||||
# # calculator = true;
|
||||
# # contacts = true;
|
||||
# # conversion = true;
|
||||
# # definition = true;
|
||||
# # developer = true;
|
||||
# # documents = true;
|
||||
# # eventsAndReminders = true;
|
||||
# # folders = true;
|
||||
# # fonts = false;
|
||||
# # images = true;
|
||||
# # mailAndMessages = true;
|
||||
# # movies = true;
|
||||
# # music = true;
|
||||
# # other = false;
|
||||
# # pdfDocuments = true;
|
||||
# # presentations = true;
|
||||
# # siriSuggestions = false;
|
||||
# # systemSettings = true;
|
||||
# # tips = false;
|
||||
# # websites = true;
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
# Manage bug in compilations - who uses manpages in 2024 anyways? :P
|
||||
manual.manpages = enabled;
|
||||
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# steam-rom-manager HM module is needed for the steam-rom-manager program
|
||||
# options. On NixOS hosts it's provided via sharedModules; here we add it
|
||||
# explicitly so the standalone homeConfiguration build also includes it.
|
||||
imports = [
|
||||
inputs.steam-rom-manager.homeManagerModules.default
|
||||
];
|
||||
|
||||
home = {
|
||||
username = "admin";
|
||||
packages =
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "nixos";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
services.nextcloud-client.enable = lib.mkForce false;
|
||||
services.kdeconnect.enable = false;
|
||||
}
|
||||
|
||||
152
lib/README.md
152
lib/README.md
@@ -1,130 +1,44 @@
|
||||
# mjallen-lib Utility Functions
|
||||
|
||||
This directory contains utility functions that can be used to enhance your Nix configuration. These functions are inspired by the khanelinix repository and provide a more explicit and modular approach to building Nix configurations.
|
||||
Utility functions for the NixOS/nix-darwin configuration. Exposed via Snowfall Lib as `lib.mjallen.*`.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
- `default.nix`: Main entry point that imports and exposes all utility functions
|
||||
- `module/`: Utilities for module creation and option handling
|
||||
- `file/`: Utilities for file handling and module discovery
|
||||
- `system/`: Utilities for system configuration building
|
||||
- `default.nix`: Main entry point — exports `module`, `file`, and `versioning`
|
||||
- `module/`: Module creation helpers (`mkModule`, `mkOpt`, `mkBoolOpt`, etc.)
|
||||
- `file/`: File and path utilities
|
||||
- `versioning/`: Multi-source version pinning helpers (used by packages)
|
||||
|
||||
## How to Use
|
||||
## Module Utilities (`lib.mjallen.module`)
|
||||
|
||||
### 1. Import the Library
|
||||
| Function | Description |
|
||||
|---|---|
|
||||
| `mkModule` | Create a NixOS module with standard options (enable, port, reverseProxy, firewall, user, postgresql, redis) |
|
||||
| `mkOpt` | `type → default → description → mkOption` shorthand |
|
||||
| `mkOpt'` | `mkOpt` without description |
|
||||
| `mkBoolOpt` | Boolean `mkOpt` shorthand |
|
||||
| `mkBoolOpt'` | Boolean `mkOpt` without description |
|
||||
| `mkReverseProxyOpt` | Standard Caddy reverse proxy sub-options |
|
||||
| `enabled` | `{ enable = true; }` shorthand |
|
||||
| `disabled` | `{ enable = false; }` shorthand |
|
||||
| `capitalize` | Capitalise the first character of a string |
|
||||
| `boolToNum` | Convert a boolean to 0 or 1 |
|
||||
| `default-attrs` | Apply `lib.mkDefault` to every value in an attrset |
|
||||
| `force-attrs` | Apply `lib.mkForce` to every value in an attrset |
|
||||
| `nested-default-attrs` | Apply `default-attrs` one level deeper |
|
||||
| `nested-force-attrs` | Apply `force-attrs` one level deeper |
|
||||
| `enableForSystem` | Filter a module list to only those that match a given system string |
|
||||
|
||||
The library is already imported in your flake.nix file through the outputs-builder:
|
||||
## File Utilities (`lib.mjallen.file`)
|
||||
|
||||
```nix
|
||||
outputs-builder = channels: {
|
||||
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
||||
|
||||
# Add mjallen-lib to the flake outputs
|
||||
overlays = {
|
||||
mjallen-lib = final: prev: {
|
||||
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
| Function | Description |
|
||||
|---|---|
|
||||
| `getFile` | Resolve a path relative to the flake root |
|
||||
| `safeImport` | Import a Nix file with a fallback on error |
|
||||
| `scanDir` | Return a list of directory names under a path |
|
||||
| `importModulesRecursive` | Recursively discover and import all `default.nix` files under a directory |
|
||||
|
||||
This makes the mjallen-lib available to all your modules through the extended lib.
|
||||
## Versioning Utilities (`lib.mjallen.versioning`)
|
||||
|
||||
### 2. Use the Module Utilities
|
||||
|
||||
The module utilities provide functions for creating modules with consistent options:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.module) mkModule mkOpt mkBoolOpt;
|
||||
in
|
||||
mkModule {
|
||||
name = "mymodule";
|
||||
description = "My awesome module";
|
||||
options = {
|
||||
setting1 = mkOpt lib.types.str "default" "Description of setting1";
|
||||
setting2 = mkBoolOpt false "Description of setting2";
|
||||
};
|
||||
config = {
|
||||
# Module implementation
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Use the File Utilities
|
||||
|
||||
The file utilities provide functions for file handling and module discovery:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.file) safeImport importModulesRecursive;
|
||||
in
|
||||
{
|
||||
# Import a file with error handling
|
||||
myConfig = safeImport ./my-config.nix {};
|
||||
|
||||
# Import all modules recursively
|
||||
imports = importModulesRecursive ./modules;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Use the System Utilities
|
||||
|
||||
The system utilities provide functions for building system configurations:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.system.common) mkHomeManagerConfig;
|
||||
in
|
||||
{
|
||||
# Build home-manager configurations
|
||||
homeManagerConfig = mkHomeManagerConfig {
|
||||
extendedLib = lib;
|
||||
inputs = inputs;
|
||||
system = "x86_64-linux";
|
||||
matchingHomes = { ... };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Available Functions
|
||||
|
||||
### Module Utilities
|
||||
|
||||
- `mkModule`: Create a module with common options
|
||||
- `mkOpt`: Create an option with a type, default value, and description
|
||||
- `mkOpt'`: Create an option with a type and default value (no description)
|
||||
- `mkBoolOpt`: Create a boolean option with a default value and description
|
||||
- `mkBoolOpt'`: Create a boolean option with a default value (no description)
|
||||
- `enabled`: Standard enable pattern
|
||||
- `disabled`: Standard disable pattern
|
||||
- `capitalize`: Capitalize a string
|
||||
- `boolToNum`: Convert a boolean to a number
|
||||
- `default-attrs`: Apply mkDefault to all attributes
|
||||
- `force-attrs`: Apply mkForce to all attributes
|
||||
- `nested-default-attrs`: Apply default-attrs to nested attributes
|
||||
- `nested-force-attrs`: Apply force-attrs to nested attributes
|
||||
|
||||
### File Utilities
|
||||
|
||||
- `readFile`: Read a file and return its contents
|
||||
- `pathExists`: Check if a file exists
|
||||
- `safeImport`: Import a nix file with error handling
|
||||
- `scanDir`: Scan a directory and return directory names
|
||||
- `getFile`: Get a file path relative to the flake root
|
||||
- `importModulesRecursive`: Recursively discover and import all Nix modules in a directory tree
|
||||
- `scanSystems`: Recursively scan systems directory structure
|
||||
- `filterNixOSSystems`: Filter systems for NixOS (Linux)
|
||||
- `filterDarwinSystems`: Filter systems for Darwin (macOS)
|
||||
- `scanHomes`: Scan homes directory structure for home configurations
|
||||
|
||||
### System Utilities
|
||||
|
||||
- `mkExtendedLib`: Extend the nixpkgs lib with mjallen-lib
|
||||
- `mkNixpkgsConfig`: Create a nixpkgs configuration
|
||||
- `mkHomeConfigs`: Create home configurations for a system and hostname
|
||||
- `mkHomeManagerConfig`: Create a home-manager configuration
|
||||
- `mkSpecialArgs`: Create special arguments for a system configuration
|
||||
Used by packages that track multiple upstream variants (e.g. `linux-rpi`, `proton-cachyos`).
|
||||
See `lib/versioning/default.nix` for the full API.
|
||||
|
||||
@@ -17,12 +17,9 @@ let
|
||||
in
|
||||
rec {
|
||||
|
||||
# Conditionally enable modules based on system
|
||||
enableForSystem =
|
||||
system: modules:
|
||||
builtins.filter (
|
||||
mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
|
||||
) modules;
|
||||
# ---------------------------------------------------------------------------
|
||||
# NixOS service module helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Create a NixOS module with standard options (enable, port, reverseProxy,
|
||||
# firewall, user, postgresql, redis) and optional caller-supplied options and
|
||||
@@ -61,7 +58,6 @@ rec {
|
||||
'';
|
||||
};
|
||||
|
||||
# Open firewall
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
allowedUDPPorts = [ cfg.port ];
|
||||
@@ -76,11 +72,8 @@ rec {
|
||||
groups.${name} = { };
|
||||
};
|
||||
|
||||
# Ensure the service waits for the filesystem that hosts configDir and
|
||||
# dataDir to be mounted before starting. RequiresMountsFor is the
|
||||
# idiomatic systemd way to express this: if the paths live on the root
|
||||
# filesystem the directive is silently ignored, so it is safe on every
|
||||
# host — not just the NAS.
|
||||
# RequiresMountsFor is silently ignored when the paths live on the root
|
||||
# filesystem, so this is safe on non-NAS hosts too.
|
||||
systemd.services.${serviceName}.unitConfig.RequiresMountsFor = [
|
||||
cfg.configDir
|
||||
cfg.dataDir
|
||||
@@ -107,10 +100,6 @@ rec {
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
# defaultConfig and moduleConfig are kept as separate inline modules so
|
||||
# the NixOS module system handles all merging (mkIf, mkForce, mkMerge,
|
||||
# etc.) correctly, rather than merging raw attrsets with // or
|
||||
# recursiveUpdate which can silently clobber mkIf wrappers.
|
||||
{ config = lib.mkIf cfg.enable defaultConfig; }
|
||||
{ config = lib.mkIf cfg.enable moduleConfig; }
|
||||
];
|
||||
@@ -165,6 +154,147 @@ rec {
|
||||
};
|
||||
};
|
||||
|
||||
# Wraps mkModule for Podman/OCI container services. Generates all the
|
||||
# standard mkModule options plus the container definition. The serviceName
|
||||
# is set to "podman-<name>" automatically.
|
||||
#
|
||||
# Required args:
|
||||
# config — the NixOS config attrset (pass through from the module args)
|
||||
# name — service name (used for the container name and option path)
|
||||
# image — OCI image reference string
|
||||
# internalPort — port the container listens on internally
|
||||
#
|
||||
# Optional args:
|
||||
# description — human-readable description (defaults to name)
|
||||
# options — extra mkModule options attrset
|
||||
# volumes — extra volume strings (in addition to none)
|
||||
# environment — extra environment variables (merged with PUID/PGID/TZ)
|
||||
# environmentFiles — list of paths to env-files (e.g. sops template paths)
|
||||
# extraOptions — list of extra --opt strings passed to the container runtime
|
||||
# devices — list of device mappings
|
||||
# extraConfig — extra NixOS config merged into moduleConfig
|
||||
mkContainerService =
|
||||
{
|
||||
config,
|
||||
name,
|
||||
image,
|
||||
internalPort,
|
||||
description ? name,
|
||||
options ? { },
|
||||
volumes ? [ ],
|
||||
environment ? { },
|
||||
environmentFiles ? [ ],
|
||||
extraOptions ? [ ],
|
||||
devices ? [ ],
|
||||
extraConfig ? { },
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.services.${name};
|
||||
in
|
||||
mkModule {
|
||||
inherit
|
||||
config
|
||||
name
|
||||
description
|
||||
options
|
||||
;
|
||||
serviceName = "podman-${name}";
|
||||
moduleConfig = lib.recursiveUpdate {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
inherit
|
||||
image
|
||||
volumes
|
||||
environmentFiles
|
||||
extraOptions
|
||||
devices
|
||||
;
|
||||
ports = [ "${toString cfg.port}:${toString internalPort}" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
}
|
||||
// environment;
|
||||
};
|
||||
} extraConfig;
|
||||
};
|
||||
|
||||
# Generates a sops secrets block + a sops template env-file in a single call.
|
||||
#
|
||||
# secrets — attrset of sops secret keys → extra attrs (e.g. owner/group).
|
||||
# The sopsFile is set automatically to nas-secrets.yaml unless
|
||||
# overridden per-secret via { sopsFile = ...; }.
|
||||
# name — template file name, e.g. "glance.env"
|
||||
# content — the template body string (use config.sops.placeholder."key")
|
||||
# restartUnit — systemd unit to restart when the secret changes
|
||||
# owner, group, mode — file ownership/permissions (defaults match NAS convention)
|
||||
# sopsFile — default sops file for all secrets (can be overridden per-secret)
|
||||
mkSopsEnvFile =
|
||||
{
|
||||
secrets,
|
||||
name,
|
||||
content,
|
||||
restartUnit,
|
||||
owner ? "nix-apps",
|
||||
group ? "jallen-nas",
|
||||
mode ? "660",
|
||||
sopsFile ? (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml"),
|
||||
}:
|
||||
{
|
||||
sops.secrets = mapAttrs (_key: extra: { inherit sopsFile; } // extra) secrets;
|
||||
|
||||
sops.templates.${name} = {
|
||||
inherit
|
||||
mode
|
||||
owner
|
||||
group
|
||||
content
|
||||
;
|
||||
restartUnits = [ restartUnit ];
|
||||
};
|
||||
};
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Home Manager module helper
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Create a Home Manager module with a standard enable option and optional
|
||||
# extra options, gating all config behind `cfg.enable`.
|
||||
#
|
||||
# domain — option namespace domain, e.g. "programs" or "desktop"
|
||||
# name — module name, e.g. "btop"
|
||||
# description — text for mkEnableOption (defaults to name)
|
||||
# options — attrset of extra options merged into the submodule
|
||||
# config — the NixOS/HM config attrset passed through from module args
|
||||
# moduleConfig — the Home Manager config body (already gated behind cfg.enable)
|
||||
mkHomeModule =
|
||||
{
|
||||
config,
|
||||
domain,
|
||||
name,
|
||||
description ? name,
|
||||
options ? { },
|
||||
moduleConfig,
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.${domain}.${name};
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.${namespace}.${domain}.${name} = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
enable = lib.mkEnableOption description;
|
||||
}
|
||||
// options;
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable moduleConfig;
|
||||
};
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Option creation helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -50,8 +50,9 @@
|
||||
|
||||
nixpkgs = {
|
||||
config = {
|
||||
cudaSupport = lib.mkDefault config.${namespace}.hardware.nvidia.enable;
|
||||
rocmSupport = lib.mkDefault config.${namespace}.hardware.amd.enable;
|
||||
# CUDA and ROCm are not applicable on Darwin; those hardware modules are
|
||||
# NixOS-only. Unfree allowance is handled globally via channels-config in
|
||||
# the flake.
|
||||
allowUnsupportedSystem = true;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -52,13 +52,15 @@ in
|
||||
mission-center
|
||||
parted
|
||||
vesktop
|
||||
] ++ (
|
||||
if !isArm then
|
||||
]
|
||||
++ (
|
||||
if !isArm then
|
||||
[
|
||||
# goverlay
|
||||
# winboat
|
||||
]
|
||||
else [ ]
|
||||
else
|
||||
[ ]
|
||||
)
|
||||
else
|
||||
[ ]
|
||||
@@ -68,10 +70,12 @@ in
|
||||
};
|
||||
|
||||
programs = {
|
||||
nix-index-database.comma = enabled;
|
||||
# nix-index-database is not available in all home configs (e.g. iso-minimal
|
||||
# standalone homes don't load the nix-index-database HM module).
|
||||
# Set it per-host in homes that explicitly load the module.
|
||||
btop = {
|
||||
enable = lib.mkDefault true;
|
||||
package = pkgs.unstable.btop;
|
||||
package = pkgs.btop;
|
||||
};
|
||||
fastfetch = lib.mkDefault enabled;
|
||||
home-manager = lib.mkDefault enabled;
|
||||
|
||||
@@ -4,79 +4,81 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.btop;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
config = mkIf cfg.enable {
|
||||
programs.btop = {
|
||||
enable = true;
|
||||
settings = {
|
||||
truecolor = true;
|
||||
force_tty = false;
|
||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty";
|
||||
vim_keys = true;
|
||||
rounded_corners = true;
|
||||
graph_symbol = "braille";
|
||||
graph_symbol_cpu = "default";
|
||||
graph_symbol_mem = "default";
|
||||
graph_symbol_net = "default";
|
||||
graph_symbol_proc = "default";
|
||||
shown_boxes = "cpu mem net proc";
|
||||
update_ms = 2000;
|
||||
proc_sorting = "cpu lazy";
|
||||
proc_reversed = false;
|
||||
proc_tree = false;
|
||||
proc_colors = true;
|
||||
proc_gradient = true;
|
||||
proc_per_core = false;
|
||||
proc_mem_bytes = true;
|
||||
proc_cpu_graphs = true;
|
||||
proc_info_smaps = false;
|
||||
proc_left = false;
|
||||
proc_filter_kernel = false;
|
||||
cpu_graph_upper = "total";
|
||||
cpu_graph_lower = "total";
|
||||
cpu_invert_lower = true;
|
||||
cpu_single_graph = false;
|
||||
cpu_bottom = false;
|
||||
show_uptime = true;
|
||||
check_temp = true;
|
||||
cpu_sensor = "Auto";
|
||||
show_coretemp = true;
|
||||
cpu_core_map = "";
|
||||
temp_scale = "celsius";
|
||||
base_10_sizes = false;
|
||||
show_cpu_freq = true;
|
||||
clock_format = "%X";
|
||||
background_update = true;
|
||||
custom_cpu_name = "";
|
||||
disks_filter = "";
|
||||
mem_graphs = true;
|
||||
mem_below_net = false;
|
||||
zfs_arc_cached = true;
|
||||
show_swap = true;
|
||||
swap_disk = true;
|
||||
show_disks = true;
|
||||
only_physical = true;
|
||||
use_fstab = true;
|
||||
zfs_hide_datasets = false;
|
||||
disk_free_priv = false;
|
||||
show_io_stat = true;
|
||||
io_mode = false;
|
||||
io_graph_combined = false;
|
||||
io_graph_speeds = "";
|
||||
net_download = 100;
|
||||
net_upload = 100;
|
||||
net_auto = true;
|
||||
net_sync = true;
|
||||
net_iface = "";
|
||||
show_battery = true;
|
||||
selected_battery = "Auto";
|
||||
log_level = "WARNING";
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "btop";
|
||||
moduleConfig = {
|
||||
programs.btop = {
|
||||
enable = true;
|
||||
settings = {
|
||||
truecolor = true;
|
||||
force_tty = false;
|
||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty";
|
||||
vim_keys = true;
|
||||
rounded_corners = true;
|
||||
graph_symbol = "braille";
|
||||
graph_symbol_cpu = "default";
|
||||
graph_symbol_mem = "default";
|
||||
graph_symbol_net = "default";
|
||||
graph_symbol_proc = "default";
|
||||
shown_boxes = "cpu mem net proc";
|
||||
update_ms = 2000;
|
||||
proc_sorting = "cpu lazy";
|
||||
proc_reversed = false;
|
||||
proc_tree = false;
|
||||
proc_colors = true;
|
||||
proc_gradient = true;
|
||||
proc_per_core = false;
|
||||
proc_mem_bytes = true;
|
||||
proc_cpu_graphs = true;
|
||||
proc_info_smaps = false;
|
||||
proc_left = false;
|
||||
proc_filter_kernel = false;
|
||||
cpu_graph_upper = "total";
|
||||
cpu_graph_lower = "total";
|
||||
cpu_invert_lower = true;
|
||||
cpu_single_graph = false;
|
||||
cpu_bottom = false;
|
||||
show_uptime = true;
|
||||
check_temp = true;
|
||||
cpu_sensor = "Auto";
|
||||
show_coretemp = true;
|
||||
cpu_core_map = "";
|
||||
temp_scale = "celsius";
|
||||
base_10_sizes = false;
|
||||
show_cpu_freq = true;
|
||||
clock_format = "%X";
|
||||
background_update = true;
|
||||
custom_cpu_name = "";
|
||||
disks_filter = "";
|
||||
mem_graphs = true;
|
||||
mem_below_net = false;
|
||||
zfs_arc_cached = true;
|
||||
show_swap = true;
|
||||
swap_disk = true;
|
||||
show_disks = true;
|
||||
only_physical = true;
|
||||
use_fstab = true;
|
||||
zfs_hide_datasets = false;
|
||||
disk_free_priv = false;
|
||||
show_io_stat = true;
|
||||
io_mode = false;
|
||||
io_graph_combined = false;
|
||||
io_graph_speeds = "";
|
||||
net_download = 100;
|
||||
net_upload = 100;
|
||||
net_auto = true;
|
||||
net_sync = true;
|
||||
net_iface = "";
|
||||
show_battery = true;
|
||||
selected_battery = "Auto";
|
||||
log_level = "WARNING";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.btop = {
|
||||
enable = mkEnableOption "enable btop";
|
||||
};
|
||||
}
|
||||
46
modules/home/programs/common/default-apps.nix
Normal file
46
modules/home/programs/common/default-apps.nix
Normal file
@@ -0,0 +1,46 @@
|
||||
# Shared defaultApps submodule options, used by both the hyprland and
|
||||
# nwg-panel modules. Import this file and pass the result as the `options`
|
||||
# argument to types.submodule to avoid duplicating the definition.
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
browser = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.firefox;
|
||||
description = "Default web browser";
|
||||
};
|
||||
editor = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.micro;
|
||||
description = "Default text editor";
|
||||
};
|
||||
fileExplorer = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.nautilus;
|
||||
description = "Default file explorer";
|
||||
};
|
||||
visual = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.vscodium;
|
||||
description = "Default visual/IDE editor";
|
||||
};
|
||||
terminal = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.kitty;
|
||||
description = "Default terminal emulator";
|
||||
};
|
||||
office = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.onlyoffice-desktopeditors;
|
||||
description = "Default office suite";
|
||||
};
|
||||
video = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.vlc;
|
||||
description = "Default video player";
|
||||
};
|
||||
imageViewer = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.nomacs;
|
||||
description = "Default image viewer";
|
||||
};
|
||||
}
|
||||
@@ -158,50 +158,7 @@ with lib;
|
||||
};
|
||||
|
||||
defaultApps = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
browser = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox;
|
||||
description = "Default browser";
|
||||
};
|
||||
editor = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.micro;
|
||||
description = "Default text editor";
|
||||
};
|
||||
fileExplorer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nautilus;
|
||||
description = "Default file explorer";
|
||||
};
|
||||
visual = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vscodium;
|
||||
description = "Default visual editor";
|
||||
};
|
||||
terminal = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.kitty;
|
||||
description = "Default terminal";
|
||||
};
|
||||
office = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.onlyoffice-desktopeditors;
|
||||
description = "Default office suite";
|
||||
};
|
||||
video = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vlc;
|
||||
description = "Default video player";
|
||||
};
|
||||
imageViewer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nomacs;
|
||||
description = "Default image viewer";
|
||||
};
|
||||
};
|
||||
};
|
||||
type = types.submodule (import ../common/default-apps.nix);
|
||||
description = "Default applications used across the system";
|
||||
};
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.kitty;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.kitty = {
|
||||
enable = true;
|
||||
shellIntegration.enableZshIntegration = true;
|
||||
|
||||
settings = {
|
||||
bold_font = "auto";
|
||||
italic_font = "auto";
|
||||
bold_italic_font = "auto";
|
||||
mouse_hide_wait = "2.0";
|
||||
cursor_shape = "block";
|
||||
url_style = "dotted";
|
||||
confirm_os_window_close = "0";
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "kitty";
|
||||
moduleConfig = {
|
||||
programs.kitty = {
|
||||
enable = true;
|
||||
shellIntegration.enableZshIntegration = true;
|
||||
settings = {
|
||||
bold_font = "auto";
|
||||
italic_font = "auto";
|
||||
bold_italic_font = "auto";
|
||||
mouse_hide_wait = "2.0";
|
||||
cursor_shape = "block";
|
||||
url_style = "dotted";
|
||||
confirm_os_window_close = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.kitty = {
|
||||
enable = mkEnableOption "enable kitty terminal";
|
||||
};
|
||||
}
|
||||
@@ -4,33 +4,37 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.mako;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
config = mkIf cfg.enable {
|
||||
services.mako = {
|
||||
enable = true;
|
||||
settings = {
|
||||
font = mkDefault cfg.fontName;
|
||||
icons = true;
|
||||
ignore-timeout = true;
|
||||
sort = "-time";
|
||||
width = 500;
|
||||
height = 110;
|
||||
layer = "overlay";
|
||||
border-radius = 15;
|
||||
border-size = 1;
|
||||
max-icon-size = 64;
|
||||
default-timeout = 5000;
|
||||
|
||||
# background-color = mkDefault config.lib.stylix.colors.base00;
|
||||
# text-color = mkDefault config.lib.stylix.colors.base06;
|
||||
# border-color = mkDefault config.lib.stylix.colors.base0F;
|
||||
# progress-color = mkDefault "over ${config.lib.stylix.colors.base0C}";
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "mako";
|
||||
options = {
|
||||
fontName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "DejaVu Sans";
|
||||
description = "Font name for mako notifications.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
moduleConfig = {
|
||||
services.mako = {
|
||||
enable = true;
|
||||
settings = {
|
||||
font = lib.mkDefault config.${namespace}.programs.mako.fontName;
|
||||
icons = true;
|
||||
ignore-timeout = true;
|
||||
sort = "-time";
|
||||
width = 500;
|
||||
height = 110;
|
||||
layer = "overlay";
|
||||
border-radius = 15;
|
||||
border-size = 1;
|
||||
max-icon-size = 64;
|
||||
default-timeout = 5000;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.mako = {
|
||||
enable = mkEnableOption "enable mako";
|
||||
|
||||
fontName = mkOption {
|
||||
type = types.str;
|
||||
default = "DejaVu Sans";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -5,134 +5,131 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.nwg-dock;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "nwg-dock";
|
||||
moduleConfig = {
|
||||
home.packages = with pkgs; [ nwg-dock-hyprland ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = with pkgs; [ nwg-dock-hyprland ];
|
||||
home.file = {
|
||||
".config/nwg-dock-hyprland/config.json".text = ''
|
||||
{
|
||||
"position": "bottom",
|
||||
"anchor": "center",
|
||||
"margin": 12,
|
||||
"icon_size": 48,
|
||||
"icon_size_hover": 64,
|
||||
"spacing": 6,
|
||||
"padding": 8,
|
||||
"autohide": false,
|
||||
"autohide_timeout": 0.3,
|
||||
"exclusive": true,
|
||||
"layer": "top",
|
||||
"height": 72,
|
||||
"background_alpha": 0.55,
|
||||
"rounded_corners": 16,
|
||||
"show_labels": false,
|
||||
"show_running": true,
|
||||
"show_pinned": true,
|
||||
"pinned": [
|
||||
"firefox.desktop",
|
||||
"org.wezfurlong.wezterm.desktop",
|
||||
"codium.desktop",
|
||||
"org.gnome.Nautilus.desktop"
|
||||
]
|
||||
}
|
||||
'';
|
||||
|
||||
home.file = {
|
||||
".config/nwg-dock-hyprland/config.json".text = ''
|
||||
{
|
||||
"position": "bottom",
|
||||
"anchor": "center",
|
||||
"margin": 12,
|
||||
"icon_size": 48,
|
||||
"icon_size_hover": 64,
|
||||
"spacing": 6,
|
||||
"padding": 8,
|
||||
"autohide": false,
|
||||
"autohide_timeout": 0.3,
|
||||
"exclusive": true,
|
||||
"layer": "top",
|
||||
"height": 72,
|
||||
"background_alpha": 0.55,
|
||||
"rounded_corners": 16,
|
||||
"show_labels": false,
|
||||
"show_running": true,
|
||||
"show_pinned": true,
|
||||
"pinned": [
|
||||
"firefox.desktop",
|
||||
"org.wezfurlong.wezterm.desktop",
|
||||
"codium.desktop",
|
||||
"org.gnome.Nautilus.desktop"
|
||||
]
|
||||
}
|
||||
'';
|
||||
".config/nwg-dock-hyprland/style.css".text = ''
|
||||
window {
|
||||
background: #36364f;
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: rgba(156, 142, 122, 0.7)
|
||||
}
|
||||
|
||||
".config/nwg-dock-hyprland/style.css".text = ''
|
||||
window {
|
||||
background: #36364f;
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: rgba(156, 142, 122, 0.7)
|
||||
}
|
||||
#box {
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
#box {
|
||||
/* Define attributes of the box surrounding icons here */
|
||||
padding: 10px
|
||||
}
|
||||
#active {
|
||||
border-bottom: solid 1px;
|
||||
border-color: rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
|
||||
#active {
|
||||
/* This is to underline the button representing the currently active window */
|
||||
border-bottom: solid 1px;
|
||||
border-color: rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: #999
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: #999
|
||||
}
|
||||
button {
|
||||
padding: 4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #eee;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #eee;
|
||||
font-size: 12px
|
||||
}
|
||||
button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 2px;
|
||||
}
|
||||
button:focus {
|
||||
box-shadow: none
|
||||
}
|
||||
'';
|
||||
|
||||
button:focus {
|
||||
box-shadow: none
|
||||
}
|
||||
'';
|
||||
".config/nwg-dock-hyprland/drawer.css".text = ''
|
||||
window {
|
||||
background: ${config.lib.stylix.colors.base00};
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0E}b0
|
||||
}
|
||||
|
||||
".config/nwg-dock-hyprland/drawer.css".text = ''
|
||||
window {
|
||||
background: ${config.lib.stylix.colors.base00};
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0E}b0
|
||||
}
|
||||
#box {
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
#box {
|
||||
/* Define attributes of the box surrounding icons here */
|
||||
padding: 10px
|
||||
}
|
||||
active {
|
||||
border-bottom: solid 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0B}1a
|
||||
}
|
||||
|
||||
active {
|
||||
/* This is to underline the button representing the currently active window */
|
||||
border-bottom: solid 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0B}1a
|
||||
}
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: ${config.lib.stylix.colors.base0F}
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: ${config.lib.stylix.colors.base0F}
|
||||
}
|
||||
button {
|
||||
padding: 4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #eee;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #eee;
|
||||
font-size: 12px
|
||||
}
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base00}1a;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base00}1a;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
box-shadow: none
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
button:focus {
|
||||
box-shadow: none
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.nwg-dock = {
|
||||
enable = mkEnableOption "enable nwg-dock";
|
||||
};
|
||||
}
|
||||
@@ -5,53 +5,50 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.nwg-drawer;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "nwg-drawer";
|
||||
moduleConfig = {
|
||||
home.packages = with pkgs; [ nwg-drawer ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = with pkgs; [ nwg-drawer ];
|
||||
home.file.".config/nwg-drawer/drawer.css".text = ''
|
||||
window {
|
||||
background-color: ${config.lib.stylix.colors.base00}bf;
|
||||
color: ${config.lib.stylix.colors.base05}00
|
||||
}
|
||||
|
||||
home.file = {
|
||||
".config/nwg-drawer/drawer.css".text = ''
|
||||
window {
|
||||
background-color: ${config.lib.stylix.colors.base00}bf;
|
||||
color: ${config.lib.stylix.colors.base05}00
|
||||
}
|
||||
entry {
|
||||
background-color: ${config.lib.stylix.colors.base01}0f
|
||||
}
|
||||
|
||||
/* search entry */
|
||||
entry {
|
||||
background-color: ${config.lib.stylix.colors.base01}0f
|
||||
}
|
||||
button, image {
|
||||
background: none;
|
||||
border: none
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border: none
|
||||
}
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base0F}1a
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base0F}1a
|
||||
}
|
||||
#category-button {
|
||||
margin: 0 10px 0 10px
|
||||
}
|
||||
|
||||
/* in case you wanted to give category buttons a different look */
|
||||
#category-button {
|
||||
margin: 0 10px 0 10px
|
||||
}
|
||||
#pinned-box {
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted ${config.lib.stylix.colors.base03}
|
||||
}
|
||||
|
||||
#pinned-box {
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted ${config.lib.stylix.colors.base03}
|
||||
}
|
||||
|
||||
#files-box {
|
||||
padding: 5px;
|
||||
border: 1px dotted ${config.lib.stylix.colors.base03};
|
||||
border-radius: 15px
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
#files-box {
|
||||
padding: 5px;
|
||||
border: 1px dotted ${config.lib.stylix.colors.base03};
|
||||
border-radius: 15px
|
||||
}
|
||||
'';
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.nwg-drawer = {
|
||||
enable = mkEnableOption "enable nwg-drawer";
|
||||
};
|
||||
}
|
||||
@@ -1,51 +1,14 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.nwg-panel = {
|
||||
enable = mkEnableOption "enable nwg-panel";
|
||||
enable = lib.mkEnableOption "nwg-panel";
|
||||
|
||||
defaultApps = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
browser = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox;
|
||||
};
|
||||
editor = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.micro;
|
||||
};
|
||||
fileExplorer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nautilus;
|
||||
};
|
||||
visual = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vscodium;
|
||||
};
|
||||
terminal = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.kitty;
|
||||
};
|
||||
office = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.onlyoffice-desktopeditors;
|
||||
};
|
||||
video = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vlc;
|
||||
};
|
||||
imageViewer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.gnome-photos;
|
||||
};
|
||||
};
|
||||
};
|
||||
defaultApps = lib.mkOption {
|
||||
type = lib.types.submodule (import ../common/default-apps.nix);
|
||||
description = "Default applications used across the system.";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,105 +4,60 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.wlogout;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
config = mkIf cfg.enable {
|
||||
programs.wlogout = {
|
||||
enable = false;
|
||||
layout = {
|
||||
lock = {
|
||||
label = "lock";
|
||||
action = "hyprlock --immediate";
|
||||
text = "Lock";
|
||||
keybind = "l";
|
||||
};
|
||||
hibernate = {
|
||||
label = "hibernate";
|
||||
action = "systemctl hibernate";
|
||||
text = "Hibernate";
|
||||
keybind = "h";
|
||||
};
|
||||
logout = {
|
||||
label = "logout";
|
||||
action = "sleep 1; hyprctl dispatch exit";
|
||||
text = "Logout";
|
||||
keybind = "e";
|
||||
};
|
||||
shutdown = {
|
||||
label = "shutdown";
|
||||
action = "systemctl poweroff";
|
||||
text = "Shutdown";
|
||||
keybind = "s";
|
||||
};
|
||||
suspend = {
|
||||
label = "suspend";
|
||||
action = "systemctl suspend";
|
||||
text = "Suspend";
|
||||
keybind = "u";
|
||||
};
|
||||
reboot = {
|
||||
label = "reboot";
|
||||
action = "reboot";
|
||||
text = "Reboot";
|
||||
keybind = "r";
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "wlogout";
|
||||
moduleConfig = {
|
||||
programs.wlogout = {
|
||||
enable = false;
|
||||
layout = {
|
||||
lock = { label = "lock"; action = "hyprlock --immediate"; text = "Lock"; keybind = "l"; };
|
||||
hibernate = { label = "hibernate"; action = "systemctl hibernate"; text = "Hibernate"; keybind = "h"; };
|
||||
logout = { label = "logout"; action = "sleep 1; hyprctl dispatch exit"; text = "Logout"; keybind = "e"; };
|
||||
shutdown = { label = "shutdown"; action = "systemctl poweroff"; text = "Shutdown"; keybind = "s"; };
|
||||
suspend = { label = "suspend"; action = "systemctl suspend"; text = "Suspend"; keybind = "u"; };
|
||||
reboot = { label = "reboot"; action = "reboot"; text = "Reboot"; keybind = "r"; };
|
||||
};
|
||||
style = ''
|
||||
* {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
window {
|
||||
background-color: ${config.lib.stylix.colors.base00}f0
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 8px;
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base01};
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 25%;
|
||||
}
|
||||
|
||||
button:active,
|
||||
button:focus,
|
||||
button:hover {
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base02Alt};
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
#lock { background-image: image(url("icons/lock.png")); }
|
||||
#logout { background-image: image(url("icons/logout.png")); }
|
||||
#suspend { background-image: image(url("icons/suspend.png")); }
|
||||
#hibernate { background-image: image(url("icons/hibernate.png")); }
|
||||
#shutdown { background-image: image(url("icons/shutdown.png")); }
|
||||
#reboot { background-image: image(url("icons/reboot.png")); }
|
||||
'';
|
||||
};
|
||||
};
|
||||
style = ''
|
||||
* {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
window {
|
||||
background-color: ${config.lib.stylix.colors.base00}f0
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 8px;
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base01};
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 25%;
|
||||
}
|
||||
|
||||
button:active,
|
||||
button:focus,
|
||||
button:hover {
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base02Alt};
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
#lock {
|
||||
background-image: image(url("icons/lock.png"));
|
||||
}
|
||||
|
||||
#logout {
|
||||
background-image: image(url("icons/logout.png"));
|
||||
}
|
||||
|
||||
#suspend {
|
||||
background-image: image(url("icons/suspend.png"));
|
||||
}
|
||||
|
||||
#hibernate {
|
||||
background-image: image(url("icons/hibernate.png"));
|
||||
}
|
||||
|
||||
#shutdown {
|
||||
background-image: image(url("icons/shutdown.png"));
|
||||
}
|
||||
|
||||
#reboot {
|
||||
background-image: image(url("icons/reboot.png"));
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.wlogout = {
|
||||
enable = mkEnableOption "enable wlogout";
|
||||
};
|
||||
}
|
||||
@@ -4,103 +4,104 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.wofi;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkHomeModule {
|
||||
inherit config;
|
||||
domain = "programs";
|
||||
name = "wofi";
|
||||
options = {
|
||||
fontName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "DejaVu Sans";
|
||||
description = "Font name for wofi.";
|
||||
};
|
||||
};
|
||||
moduleConfig = {
|
||||
programs.wofi = {
|
||||
enable = true;
|
||||
style = ''
|
||||
* {
|
||||
font-family: "${config.${namespace}.programs.wofi.fontName}", monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.wofi = {
|
||||
enable = true;
|
||||
style = ''
|
||||
* {
|
||||
font-family: "${cfg.fontName}", monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
window {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0.16em solid ${config.lib.stylix.colors.base0E};
|
||||
border-radius: 0.1em;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Window */
|
||||
window {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0.16em solid ${config.lib.stylix.colors.base0E};
|
||||
border-radius: 0.1em;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#inner-box {
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Inner Box */
|
||||
#inner-box {
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#outer-box {
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Outer Box */
|
||||
#outer-box {
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#scroll {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Scroll */
|
||||
#scroll {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#input {
|
||||
margin: 5px 20px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 0.1em;
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Input */
|
||||
#input {
|
||||
margin: 5px 20px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 0.1em;
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#input image {
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base08};
|
||||
}
|
||||
|
||||
#input image {
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base08};
|
||||
}
|
||||
#input * {
|
||||
outline: 4px solid ${config.lib.stylix.colors.base08}!important;
|
||||
}
|
||||
|
||||
#input * {
|
||||
outline: 4px solid ${config.lib.stylix.colors.base08}!important;
|
||||
}
|
||||
#text {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
}
|
||||
|
||||
/* Text */
|
||||
#text {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
}
|
||||
#entry {
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
#entry {
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
#entry arrow {
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
|
||||
#entry arrow {
|
||||
border: none;
|
||||
color: ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
#entry:selected {
|
||||
border: 0.11em solid ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
|
||||
/* Selected Entry */
|
||||
#entry:selected {
|
||||
border: 0.11em solid ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
#entry:selected #text {
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
}
|
||||
|
||||
#entry:selected #text {
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
}
|
||||
|
||||
#entry:drop(active) {
|
||||
background-color: ${config.lib.stylix.colors.base0E}!important;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
#entry:drop(active) {
|
||||
background-color: ${config.lib.stylix.colors.base0E}!important;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.wofi = {
|
||||
enable = mkEnableOption "enable wofi";
|
||||
|
||||
fontName = mkOption {
|
||||
type = types.str;
|
||||
default = "Deja Vu Sans";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -5,8 +5,9 @@ with lib;
|
||||
enable = mkEnableOption "enable sops";
|
||||
|
||||
defaultSopsFile = mkOption {
|
||||
type = types.str;
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Path to the default sops secrets file.";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ let
|
||||
cfg = config.${namespace}.desktop.gnome;
|
||||
in
|
||||
{
|
||||
imports = [ ../../../home/desktop/gnome/options.nix ];
|
||||
options.${namespace}.desktop.gnome = {
|
||||
enable = lib.mkEnableOption "GNOME desktop environment";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services = {
|
||||
# Enable Desktop Environment.
|
||||
desktopManager.gnome = enabled;
|
||||
# Enable Desktop Environment.
|
||||
displayManager = {
|
||||
gdm = lib.mkDefault enabled;
|
||||
gdm.wayland = lib.mkDefault true;
|
||||
displayManager.gdm = {
|
||||
enable = lib.mkDefault true;
|
||||
wayland = lib.mkDefault true;
|
||||
};
|
||||
|
||||
gnome = {
|
||||
gnome = lib.mkOverride 90 {
|
||||
at-spi2-core = disabled;
|
||||
core-apps = enabled;
|
||||
core-developer-tools = disabled;
|
||||
@@ -49,11 +49,9 @@ in
|
||||
|
||||
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
|
||||
|
||||
programs = {
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
package = pkgs.gnomeExtensions.gsconnect;
|
||||
};
|
||||
programs.kdeconnect = {
|
||||
enable = false;
|
||||
package = pkgs.gnomeExtensions.gsconnect;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,17 +38,15 @@ in
|
||||
remotePlay.openFirewall = true;
|
||||
# Open ports in the firewall for Source Dedicated Server
|
||||
dedicatedServer.openFirewall = true;
|
||||
extraCompatPackages =
|
||||
with pkgs.unstable;
|
||||
[
|
||||
proton-ge-bin
|
||||
]
|
||||
++ (with pkgs.${namespace}; [
|
||||
proton-cachyos
|
||||
proton-cachyos-v3
|
||||
proton-cachyos-v2
|
||||
proton-cachyos-v1
|
||||
]);
|
||||
extraCompatPackages = [
|
||||
pkgs.proton-ge-bin
|
||||
]
|
||||
++ (with pkgs.${namespace}; [
|
||||
proton-cachyos
|
||||
proton-cachyos-v3
|
||||
proton-cachyos-v2
|
||||
proton-cachyos-v1
|
||||
]);
|
||||
gamescopeSession = lib.mkDefault {
|
||||
enable = true;
|
||||
args = [
|
||||
|
||||
@@ -12,15 +12,13 @@ let
|
||||
in
|
||||
{
|
||||
options.${namespace}.hardware.amd = {
|
||||
enable = mkEnableOption "amd hardware config";
|
||||
enable = mkEnableOption "AMD hardware configuration";
|
||||
|
||||
corectrl.enable = mkBoolOpt false "Enable Corectl";
|
||||
corectrl.enable = mkBoolOpt false "Enable CoreCtrl GPU control";
|
||||
corectrl.enablePolkit = mkBoolOpt false "Enable CoreCtrl polkit rules";
|
||||
corectrl.polkitGroup = mkOpt types.str "wheel" "Group allowed to use CoreCtrl without password";
|
||||
|
||||
corectrl.enablePolkit = mkBoolOpt false "Enable Corectl Polkit";
|
||||
|
||||
corectrl.polkitGroup = mkOpt types.str "wheel" "Corectl Polkit Group";
|
||||
|
||||
lact.enable = mkBoolOpt false "Enable Lact daemon";
|
||||
lact.enable = mkBoolOpt false "Enable LACT daemon (AMD GPU control)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
@@ -29,26 +27,23 @@ in
|
||||
"nct6775"
|
||||
"k10temp"
|
||||
];
|
||||
kernelParams = [ (if cfg.enable then "amdgpu.ppfeaturemask=0xffffffff" else null) ];
|
||||
kernelParams = [ "amdgpu.ppfeaturemask=0xffffffff" ];
|
||||
};
|
||||
|
||||
# Configure programs
|
||||
programs.corectrl = {
|
||||
enable = cfg.corectrl.enable;
|
||||
package = pkgs.corectrl;
|
||||
};
|
||||
|
||||
# Configure environment
|
||||
environment = {
|
||||
# Force radv
|
||||
variables = {
|
||||
AMD_VULKAN_ICD = "RADV";
|
||||
STEAM_FORCE_DESKTOPUI_SCALING = "1.0";
|
||||
GDK_SCALE = "1";
|
||||
};
|
||||
systemPackages = lib.mkIf cfg.lact.enable [ pkgs.lact ];
|
||||
};
|
||||
|
||||
# Configure polkit
|
||||
security.polkit = lib.mkIf cfg.corectrl.enablePolkit {
|
||||
extraConfig = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
@@ -63,13 +58,13 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# nixpkg is broken so need to manually define
|
||||
# k10temp is listed in kernelModules above, but the module doesn't always
|
||||
# load early enough for sensors to be available. This service ensures it
|
||||
# is loaded after multi-user.target.
|
||||
systemd.services = {
|
||||
load-k10temp = {
|
||||
description = "Load k10temp manually cause it wont otherwise";
|
||||
script = ''
|
||||
${pkgs.kmod}/bin/modprobe k10temp
|
||||
'';
|
||||
description = "Load k10temp kernel module";
|
||||
script = "${pkgs.kmod}/bin/modprobe k10temp";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
lactd = lib.mkIf cfg.lact.enable {
|
||||
@@ -78,17 +73,10 @@ in
|
||||
bash
|
||||
lact
|
||||
];
|
||||
script = ''
|
||||
lact daemon
|
||||
'';
|
||||
script = "lact daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Configure environment
|
||||
environment = {
|
||||
systemPackages = with pkgs; lib.mkIf cfg.lact.enable [ lact ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -219,6 +219,25 @@ in
|
||||
default = "uefi";
|
||||
};
|
||||
|
||||
nixosGenerationsDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/boot/nixos-generations";
|
||||
description = "Directory on the boot partition where NixOS generations are stored (kernel bootType only).";
|
||||
};
|
||||
|
||||
firmwarePackage = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = null;
|
||||
defaultText = lib.literalExpression "pkgs.\${namespace}.raspberrypifw";
|
||||
description = "Raspberry Pi firmware package used for device-tree installation (kernel/uboot bootType).";
|
||||
};
|
||||
|
||||
useGenerationDeviceTree = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to install a per-generation device tree alongside the kernel (kernel bootType only).";
|
||||
};
|
||||
|
||||
apply-overlays-dtmerge = {
|
||||
enable = lib.mkEnableOption "" // {
|
||||
description = ''
|
||||
@@ -260,7 +279,6 @@ in
|
||||
]
|
||||
);
|
||||
loader = {
|
||||
# kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
|
||||
generic-extlinux-compatible = {
|
||||
enable = lib.mkDefault (if cfg.bootType == "uefi" then false else true);
|
||||
useGenerationDeviceTree = lib.mkOverride 60 (if cfg.bootType == "uefi" then false else true);
|
||||
@@ -347,38 +365,28 @@ in
|
||||
deviceTree = {
|
||||
filter = lib.mkDefault (if (cfg.variant == "5") then "bcm2712*.dtb" else "bcm2711*.dtb");
|
||||
package = lib.mkOverride 80 config.boot.kernelPackages.kernel;
|
||||
overlays = (
|
||||
if (cfg.variant == "4") then
|
||||
[
|
||||
{
|
||||
name = "rpi4-cpu-revision";
|
||||
dtsText = ''
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
overlays = lib.optionals (cfg.variant == "4") [
|
||||
{
|
||||
name = "rpi4-cpu-revision";
|
||||
dtsText = ''
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm2711";
|
||||
/ {
|
||||
compatible = "brcm,bcm2711";
|
||||
|
||||
fragment@0 {
|
||||
target-path = "/";
|
||||
__overlay__ {
|
||||
system {
|
||||
linux,revision = <0x00d03114>;
|
||||
};
|
||||
};
|
||||
fragment@0 {
|
||||
target-path = "/";
|
||||
__overlay__ {
|
||||
system {
|
||||
linux,revision = <0x00d03114>;
|
||||
};
|
||||
};
|
||||
'';
|
||||
}
|
||||
]
|
||||
else
|
||||
[
|
||||
# {
|
||||
# name = "bcm2712d0-overlay";
|
||||
# dtsFile = "${pkgs.${namespace}.raspberrypi-overlays}/dtbs/raspberrypi-overlays/bcm2712d0-overlay.dts";
|
||||
# }
|
||||
]
|
||||
);
|
||||
};
|
||||
};
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
firmware = [ pkgs.${namespace}.raspberryPiWirelessFirmware ];
|
||||
graphics.enable32Bit = lib.mkForce false;
|
||||
@@ -386,14 +394,6 @@ in
|
||||
};
|
||||
|
||||
system = {
|
||||
#build.installBootLoader = lib.mkOverride 60 (if cfg.bootType == "uefi" then (builder."uefi") else (builder."uboot")); # todo
|
||||
#boot = {
|
||||
# loader = {
|
||||
# id = lib.mkOverride 60 (if cfg.bootType == "uefi" then "raspberrypi-uefi" else "raspberrypi-uboot"); # todo
|
||||
# kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
|
||||
# };
|
||||
#};
|
||||
# Pi specific system tags
|
||||
nixos.tags = [
|
||||
"raspberry-pi-${cfg.variant}"
|
||||
# config.boot.loader.raspberry-pi.bootloader
|
||||
|
||||
@@ -144,10 +144,7 @@ in
|
||||
|
||||
# Configure WiFi profiles if any are defined
|
||||
ensureProfiles = mkIf (cfg.networkmanager.profiles != { }) {
|
||||
environmentFiles = [
|
||||
config.sops.secrets.wifi.path
|
||||
];
|
||||
|
||||
environmentFiles = lib.optional (config.sops.secrets ? wifi) config.sops.secrets.wifi.path;
|
||||
profiles = profiles;
|
||||
};
|
||||
})
|
||||
|
||||
@@ -59,10 +59,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
apcupsd = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,11 +72,10 @@ let
|
||||
|
||||
open-webui = {
|
||||
enable = true;
|
||||
package = pkgs.unstable.open-webui;
|
||||
package = pkgs.open-webui;
|
||||
host = "0.0.0.0";
|
||||
port = 8888;
|
||||
openFirewall = cfg.openFirewall;
|
||||
# stateDir = "/media/nas/main/nix-app-data/open-webui";
|
||||
environmentFile = config.sops.secrets."jallen-nas/open-webui".path;
|
||||
environment = {
|
||||
OPENID_PROVIDER_URL = "https://authentik.mjallen.dev/application/o/chat/.well-known/openid-configuration";
|
||||
|
||||
@@ -70,7 +70,7 @@ let
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
dataDir = "${cfg.configDir}/sonarr";
|
||||
package = pkgs.unstable.sonarr;
|
||||
package = pkgs.sonarr;
|
||||
};
|
||||
|
||||
# Enable Sabnzbd service
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
# NOTE: AUTHENTIK_TOKEN for the RAC outpost is stored in sops.
|
||||
# Add jallen-nas/authentik-rac/token to secrets/nas-secrets.yaml and ensure
|
||||
# jallen-nas/sops.nix declares the "authentik-rac.env" template before deploying.
|
||||
@@ -15,37 +14,31 @@ let
|
||||
|
||||
authentikConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
description = "authentik Service";
|
||||
description = "authentik identity provider";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services = {
|
||||
authentik = {
|
||||
enable = true;
|
||||
environmentFile = cfg.environmentFile;
|
||||
settings = {
|
||||
port = cfg.port;
|
||||
};
|
||||
};
|
||||
services.authentik = {
|
||||
enable = true;
|
||||
environmentFile = cfg.environmentFile;
|
||||
settings.port = cfg.port;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# RAC outpost: uses podman but has a legacy container name "authenticRac"
|
||||
# (different from the option name "authentikRac"), so we use mkModule directly.
|
||||
authentikRacConfig = lib.${namespace}.mkModule {
|
||||
inherit config;
|
||||
name = "authentikRac";
|
||||
serviceName = "podman-authenticRac";
|
||||
description = "authentik_rac Service";
|
||||
description = "authentik RAC outpost";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."authenticRac" = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/goauthentik/rac";
|
||||
ports = [ "${toString cfgRac.port}:4822" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/authentik-rac:/media"
|
||||
];
|
||||
# AUTHENTIK_TOKEN is injected via the sops template "authentik-rac.env"
|
||||
# defined in systems/x86_64-linux/jallen-nas/sops.nix
|
||||
volumes = [ "${cfg.configDir}/authentik-rac:/media" ];
|
||||
environmentFiles = [ config.sops.templates."authentik-rac.env".path ];
|
||||
environment = {
|
||||
AUTHENTIK_HOST = "https://${name}.mjallen.dev";
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.services.authentik = {
|
||||
enable = mkEnableOption "authentik identity provider";
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 9000;
|
||||
description = "Port for authentik web interface";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to open firewall for authentik";
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Path to environment file containing authentik secrets";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/authentik";
|
||||
description = "Data directory for authentik";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -4,40 +4,27 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "booklore";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
bookloreConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "booklore";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "booklore/booklore";
|
||||
volumes = [
|
||||
"${cfg.configDir}/booklore:/app/data"
|
||||
"${cfg.configDir}/bookdrop:/bookdrop"
|
||||
"${cfg.dataDir}/books:/books"
|
||||
];
|
||||
ports = [
|
||||
"${toString cfg.port}:6060"
|
||||
];
|
||||
environment = {
|
||||
DATABASE_URL = "jdbc:mariadb://10.0.1.3:3306/booklore";
|
||||
DATABASE_USERNAME = "booklore";
|
||||
DATABASE_PASSWORD = "Lucifer008!";
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.booklore;
|
||||
in
|
||||
{
|
||||
imports = [ bookloreConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "booklore";
|
||||
image = "booklore/booklore";
|
||||
internalPort = 6060;
|
||||
volumes = [
|
||||
"${cfg.configDir}/booklore:/app/data"
|
||||
"${cfg.configDir}/bookdrop:/bookdrop"
|
||||
"${cfg.dataDir}/books:/books"
|
||||
];
|
||||
environment = {
|
||||
DATABASE_URL = "jdbc:mariadb://10.0.1.3:3306/booklore";
|
||||
DATABASE_USERNAME = "booklore";
|
||||
# TODO: move DATABASE_PASSWORD to a sops secret
|
||||
DATABASE_PASSWORD = "Lucifer008!";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "calibre";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
cfgWeb = config.${namespace}.services."${name}-web";
|
||||
|
||||
calibreConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
@@ -16,15 +16,11 @@ let
|
||||
description = "Calibre Server";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services = {
|
||||
calibre-server = {
|
||||
enable = false;
|
||||
openFirewall = true;
|
||||
port = cfg.port;
|
||||
libraries = [
|
||||
"${cfg.dataDir}/books"
|
||||
];
|
||||
};
|
||||
services.calibre-server = {
|
||||
enable = false;
|
||||
openFirewall = true;
|
||||
port = cfg.port;
|
||||
libraries = [ "${cfg.dataDir}/books" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -39,15 +35,15 @@ let
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
package = pkgs.stable.calibre-web;
|
||||
dataDir = "${cfg.configDir}/calibre-web";
|
||||
dataDir = "${cfgWeb.configDir}/calibre-web";
|
||||
listen = {
|
||||
ip = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
port = cfgWeb.port;
|
||||
};
|
||||
options = {
|
||||
enableBookUploading = true;
|
||||
enableBookConversion = true;
|
||||
calibreLibrary = "${cfg.dataDir}/books";
|
||||
calibreLibrary = "${cfgWeb.dataDir}/books";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,41 +4,25 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "dispatcharr";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
dispatcharrConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "dispatcharr podman container";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/dispatcharr/dispatcharr";
|
||||
extraOptions = [ "--device=/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/dispatcharr:/data"
|
||||
"${cfg.dataDir}/movies:/movies"
|
||||
"${cfg.dataDir}/tv:/tv"
|
||||
];
|
||||
ports = [
|
||||
"${toString cfg.port}:9191"
|
||||
];
|
||||
environment = {
|
||||
# DISPATCHARR_LOG_LEVEL = "DEBUG";
|
||||
DISPATCHARR_ENV = "aio";
|
||||
# DJANGO_SECRET_KEY = "123456";
|
||||
# PUID = cfg.puid;
|
||||
# PGID = cfg.pgid;
|
||||
# TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.dispatcharr;
|
||||
in
|
||||
{
|
||||
imports = [ dispatcharrConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "dispatcharr";
|
||||
image = "ghcr.io/dispatcharr/dispatcharr";
|
||||
internalPort = 9191;
|
||||
extraOptions = [ "--device=/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/dispatcharr:/data"
|
||||
"${cfg.dataDir}/movies:/movies"
|
||||
"${cfg.dataDir}/tv:/tv"
|
||||
];
|
||||
environment = {
|
||||
DISPATCHARR_ENV = "aio";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,32 +4,18 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "free-games-claimer";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
fgcConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "free-games-claimer";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."${name}" = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/vogler/free-games-claimer";
|
||||
ports = [ "${toString cfg.port}:6080" ];
|
||||
volumes = [ "${cfg.configDir}/free-games-claimer:/fgc/data" ];
|
||||
environmentFiles = [ config.sops.templates."fgc.env".path ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services."free-games-claimer";
|
||||
in
|
||||
{
|
||||
imports = [ fgcConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "free-games-claimer";
|
||||
image = "ghcr.io/vogler/free-games-claimer";
|
||||
internalPort = 6080;
|
||||
volumes = [ "${cfg.configDir}/free-games-claimer:/fgc/data" ];
|
||||
environmentFiles = [ config.sops.templates."fgc.env".path ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -11,29 +11,14 @@ let
|
||||
glanceConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
description = "glance";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
sops = {
|
||||
secrets = {
|
||||
"jallen-nas/glance/arr-username" = {
|
||||
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
|
||||
};
|
||||
"jallen-nas/glance/arr-password" = {
|
||||
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
|
||||
};
|
||||
};
|
||||
templates = {
|
||||
"glance.env" = {
|
||||
mode = "660";
|
||||
restartUnits = [ "glance.service" ];
|
||||
content = ''
|
||||
ARR_USER=${config.sops.placeholder."jallen-nas/glance/arr-username"}
|
||||
ARR_PASS=${config.sops.placeholder."jallen-nas/glance/arr-password"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
options = {
|
||||
nasPoolPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = cfg.dataDir;
|
||||
description = "Path to the NAS pool mount to display in server-stats.";
|
||||
};
|
||||
|
||||
};
|
||||
moduleConfig = {
|
||||
services.glance = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
@@ -75,7 +60,7 @@ let
|
||||
"/home" = {
|
||||
name = "Home";
|
||||
};
|
||||
"/media/nas/main" = {
|
||||
"${cfg.nasPoolPath}" = {
|
||||
name = "nas_pool";
|
||||
};
|
||||
};
|
||||
@@ -295,5 +280,25 @@ let
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ glanceConfig ];
|
||||
imports = [
|
||||
glanceConfig
|
||||
|
||||
# Sops env-file for arr credentials (gated behind glance.enable)
|
||||
{
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.${namespace}.mkSopsEnvFile {
|
||||
name = "glance.env";
|
||||
restartUnit = "glance.service";
|
||||
secrets = {
|
||||
"jallen-nas/glance/arr-username" = { };
|
||||
"jallen-nas/glance/arr-password" = { };
|
||||
};
|
||||
content = ''
|
||||
ARR_USER=${config.sops.placeholder."jallen-nas/glance/arr-username"}
|
||||
ARR_PASS=${config.sops.placeholder."jallen-nas/glance/arr-password"}
|
||||
'';
|
||||
}
|
||||
);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,40 +1,23 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "lubelogger";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
lubeloggerConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "lubelogger";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.lubelogger = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/hargata/lubelogger";
|
||||
ports = [ "${toString cfg.port}:8080" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/lubelogger:/App/data"
|
||||
"${cfg.configDir}/lubelogger/keys:/root/.aspnet/DataProtection-Keys"
|
||||
];
|
||||
# environmentFiles = [
|
||||
# "${cfg.configDir}/lubelogger/lubelogger.env"
|
||||
# ];
|
||||
environment = {
|
||||
PUID = toString config.users.users.nix-apps.uid;
|
||||
PGID = toString config.users.groups.jallen-nas.gid;
|
||||
TZ = "America/Chicago";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.lubelogger;
|
||||
in
|
||||
{
|
||||
imports = [ lubeloggerConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "lubelogger";
|
||||
image = "ghcr.io/hargata/lubelogger";
|
||||
internalPort = 8080;
|
||||
volumes = [
|
||||
"${cfg.configDir}/lubelogger:/App/data"
|
||||
"${cfg.configDir}/lubelogger/keys:/root/.aspnet/DataProtection-Keys"
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,43 +4,29 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "manyfold";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
manyfoldConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "manyfold";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."${name}" = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/manyfold3d/manyfold-solo";
|
||||
ports = [ "${toString cfg.port}:3214" ];
|
||||
extraOptions = [
|
||||
"--cap-drop=ALL"
|
||||
"--cap-add=CHOWN"
|
||||
"--cap-add=DAC_OVERRIDE"
|
||||
"--cap-add=SETUID"
|
||||
"--cap-add=SETGID"
|
||||
"--security-opt=no-new-privileges:true"
|
||||
];
|
||||
volumes = [
|
||||
"${cfg.configDir}/manyfold:/config"
|
||||
"${cfg.dataDir}/documents/3d-models:/libraries"
|
||||
];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
environmentFiles = [ config.sops.secrets."jallen-nas/manyfold/secretkeybase".path ];
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.manyfold;
|
||||
in
|
||||
{
|
||||
imports = [ manyfoldConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "manyfold";
|
||||
image = "ghcr.io/manyfold3d/manyfold-solo";
|
||||
internalPort = 3214;
|
||||
extraOptions = [
|
||||
"--cap-drop=ALL"
|
||||
"--cap-add=CHOWN"
|
||||
"--cap-add=DAC_OVERRIDE"
|
||||
"--cap-add=SETUID"
|
||||
"--cap-add=SETGID"
|
||||
"--security-opt=no-new-privileges:true"
|
||||
];
|
||||
volumes = [
|
||||
"${cfg.configDir}/manyfold:/config"
|
||||
"${cfg.dataDir}/documents/3d-models:/libraries"
|
||||
];
|
||||
environmentFiles = [ config.sops.secrets."jallen-nas/manyfold/secretkeybase".path ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ let
|
||||
description = "mongodb";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."${cfg.name}" = {
|
||||
virtualisation.oci-containers.containers."${name}" = {
|
||||
autoStart = true;
|
||||
image = "mongo";
|
||||
ports = [ "${cfg.port}:27017" ];
|
||||
volumes = [ "${cfg.configPath}/mongodb:/data/db" ];
|
||||
ports = [ "${toString cfg.port}:27017" ];
|
||||
volumes = [ "${cfg.configDir}/mongodb:/data/db" ];
|
||||
extraOptions = [ "--network-alias=mongo" ];
|
||||
# environmentFiles = cfg.environmentFiles;
|
||||
environment = {
|
||||
|
||||
@@ -37,7 +37,7 @@ in
|
||||
sopsFile = (lib.snowfall.fs.get-file "secrets/pi5-secrets.yaml");
|
||||
owner = "nebula-jallen-nebula";
|
||||
group = "nebula-jallen-nebula";
|
||||
restartUnits = [ "nebula@v-nebula.service" ];
|
||||
restartUnits = [ "nebula@jallen-nebula.service" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,54 +1,39 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
inherit (lib.${namespace}) mkOpt;
|
||||
name = "netbootxyz";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
netbootxyzConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
description = "netbootxyz";
|
||||
options = {
|
||||
assetPort = mkOpt types.port 4001 "NGINX server for hosting assets.";
|
||||
|
||||
tftpPort = mkOpt types.port 69 "HTTPS port for netbootxyz";
|
||||
};
|
||||
moduleConfig = {
|
||||
# Open firewall for netbootxyz if enabled
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [
|
||||
cfg.assetPort
|
||||
cfg.tftpPort
|
||||
];
|
||||
allowedUDPPorts = [
|
||||
cfg.assetPort
|
||||
cfg.tftpPort
|
||||
];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
containers.netbootxyz = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/netbootxyz/netbootxyz:latest";
|
||||
ports = [
|
||||
"${toString cfg.port}:3000"
|
||||
"${toString cfg.assetPort}:80"
|
||||
"${toString cfg.tftpPort}:69"
|
||||
];
|
||||
volumes = [
|
||||
"${cfg.configDir}/netbootxyz:/config"
|
||||
"${cfg.dataDir}/isos:/assets"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
inherit (lib.${namespace}) mkOpt mkContainerService;
|
||||
cfg = config.${namespace}.services.netbootxyz;
|
||||
in
|
||||
{
|
||||
imports = [ netbootxyzConfig ];
|
||||
imports = [
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = "netbootxyz";
|
||||
image = "ghcr.io/netbootxyz/netbootxyz:latest";
|
||||
internalPort = 3000;
|
||||
options = {
|
||||
assetPort = mkOpt lib.types.port 4001 "NGINX port for hosting assets";
|
||||
tftpPort = mkOpt lib.types.port 69 "TFTP port";
|
||||
};
|
||||
volumes = [
|
||||
"${cfg.configDir}/netbootxyz:/config"
|
||||
"${cfg.dataDir}/isos:/assets"
|
||||
];
|
||||
extraConfig = {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.assetPort cfg.tftpPort ];
|
||||
allowedUDPPorts = [ cfg.assetPort cfg.tftpPort ];
|
||||
};
|
||||
virtualisation.oci-containers.containers.netbootxyz.ports = lib.mkForce [
|
||||
"${toString cfg.port}:3000"
|
||||
"${toString cfg.assetPort}:80"
|
||||
"${toString cfg.tftpPort}:69"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,61 +9,6 @@ let
|
||||
name = "opencloud";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
# # Create an environment file from the configuration
|
||||
# envFile = pkgs.writeText "opencloud-environment" ''
|
||||
# OC_JWT_SECRET=${config.sops.placeholder."jallen-nas/onlyoffice-key"}
|
||||
# OC_TRANSFER_SECRET=${config.sops.placeholder."jallen-nas/onlyoffice-key"}
|
||||
# OC_MACHINE_AUTH_API_KEY=${config.sops.placeholder."jallen-nas/onlyoffice-key"}
|
||||
|
||||
# OC_ADD_RUN_SERVICES=collaboration,app-provider
|
||||
# OC_REVA_GATEWAY=eu.opencloud.api.gateway
|
||||
# APP_PROVIDER_WOPI_APP_NAME=Collabora
|
||||
# APP_PROVIDER_ENABLE=true
|
||||
# APP_PROVIDER_SERVICE_NAME=app-provider-collabora
|
||||
# COLLABORATION_APP_NAME=Collabora
|
||||
# COLLABORATION_APP_PRODUCT=Collabora
|
||||
# COLLABORATION_WOPI_DISCOVERY_URL=https://office.mjallen.dev/hosting/discovery
|
||||
# COLLABORATION_WOPI_SRC=https://office.mjallen.dev
|
||||
# OC_COLLABORATION_WOPI_URL=https://office.mjallen.dev
|
||||
# COLLABORATION_APP_ADDR=https://office.mjallen.dev
|
||||
# COLLABORATION_APP_INSECURE=false
|
||||
# COLLABORATION_APP_PROOF_DISABLE=true
|
||||
# COLLABORATION_WOPI_SHORTTOKENS=false
|
||||
# MICRO_REGISTRY=nats-js-kv
|
||||
# MICRO_REGISTRY_ADDRESS=127.0.0.1:9233
|
||||
# OC_SYSTEM_USER_ID=${cfg.puid}
|
||||
|
||||
# OC_LOG_LEVEL=info
|
||||
|
||||
# APP_PROVIDER_PROVIDERS=collabora
|
||||
|
||||
# APP_PROVIDER_COLLABORA_NAME=Collabora
|
||||
# APP_PROVIDER_COLLABORA_PRODUCT=Collabora Online
|
||||
|
||||
# APP_PROVIDER_COLLABORA_ADDR=https://office.mjallen.dev
|
||||
# APP_PROVIDER_COLLABORA_ICON=https://office.mjallen.dev/favicon.ico
|
||||
|
||||
# APP_PROVIDER_COLLABORA_MIME_TYPES=application/vnd.openxmlformats-officedocument.wordprocessingml.document application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.openxmlformats-officedocument.presentationml.presentation application/msword application/vnd.ms-excel application/vnd.ms-powerpoint text/plain
|
||||
|
||||
# NATS_NATS_HOST=${cfg.listenAddress}
|
||||
# GATEWAY_GRPC_ADDR=${cfg.listenAddress}:9142
|
||||
|
||||
# OC_DB_TYPE=postgres
|
||||
# OC_DB_HOST=10.0.1.3
|
||||
# OC_DB_PORT=5432
|
||||
# OC_DB_USER=opencloud
|
||||
# OC_DB_NAME=opencloud
|
||||
|
||||
# OC_INSECURE=true
|
||||
# PROXY_TLS=false
|
||||
# PROXY_HTTP_ADDR=${cfg.listenAddress}:9200
|
||||
# OC_URL=https://cloud.mjallen.dev
|
||||
# OC_PUBLIC_URL=https://cloud.mjallen.dev
|
||||
# PUID=${cfg.puid}
|
||||
# PGID=${cfg.pgid}
|
||||
# TZ=${cfg.timeZone}
|
||||
# '';
|
||||
|
||||
opencloudConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "opencloud";
|
||||
@@ -87,11 +32,6 @@ let
|
||||
OC_DB_NAME = "opencloud";
|
||||
OC_INSECURE = "true";
|
||||
OC_LOG_LEVEL = "debug";
|
||||
|
||||
# PROXY_TLS = "false";
|
||||
# PROXY_HTTP_ADDR= "${cfg.listenAddress}:9200";
|
||||
# OC_URL = "https://cloud.mjallen.dev"
|
||||
# OC_PUBLIC_URL = "https://cloud.mjallen.dev"
|
||||
};
|
||||
};
|
||||
# Create the secret template
|
||||
@@ -104,12 +44,6 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# # Create directories
|
||||
# systemd.tmpfiles.rules = [
|
||||
# "d '${cfg.dataDir}/opencloud' 0750 ${cfg.user} ${cfg.group} - -"
|
||||
# "d '${cfg.configDir}/opencloud' 0750 ${cfg.user} ${cfg.group} - -"
|
||||
# ];
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
@@ -4,37 +4,27 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
inherit (lib.${namespace}) mkOpt;
|
||||
name = "orca-slicer";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
orcaConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "orca slicer web ui";
|
||||
options = {
|
||||
httpsPort = mkOpt types.int 443 "HTTPS port";
|
||||
};
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."${name}" = {
|
||||
autoStart = true;
|
||||
image = "linuxserver/orcaslicer";
|
||||
ports = [
|
||||
inherit (lib.${namespace}) mkOpt mkContainerService;
|
||||
cfg = config.${namespace}.services."orca-slicer";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = "orca-slicer";
|
||||
image = "linuxserver/orcaslicer";
|
||||
internalPort = 3000;
|
||||
options = {
|
||||
httpsPort = mkOpt lib.types.int 443 "HTTPS port";
|
||||
};
|
||||
extraConfig = {
|
||||
virtualisation.oci-containers.containers."orca-slicer".ports = lib.mkForce [
|
||||
"${toString cfg.port}:3000"
|
||||
"${toString cfg.httpsPort}:3001"
|
||||
];
|
||||
volumes = [ "${cfg.configDir}/orca-slicer:/config" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ orcaConfig ];
|
||||
volumes = [ "${cfg.configDir}/orca-slicer:/config" ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.services.free-games-claimer = {
|
||||
enable = mkEnableOption "free-games-claimer docker service";
|
||||
|
||||
autoStart = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
httpPort = mkOption {
|
||||
type = types.str;
|
||||
default = "6080";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "free-games-claimer";
|
||||
};
|
||||
|
||||
image = mkOption {
|
||||
type = types.str;
|
||||
default = "ghcr.io/vogler/free-games-claimer";
|
||||
};
|
||||
|
||||
dataPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/media/nas/main/nix-app-data/free-games-claimer";
|
||||
};
|
||||
|
||||
puid = mkOption {
|
||||
type = types.str;
|
||||
default = "911";
|
||||
};
|
||||
|
||||
pgid = mkOption {
|
||||
type = types.str;
|
||||
default = "1000";
|
||||
};
|
||||
|
||||
timeZone = mkOption {
|
||||
type = types.str;
|
||||
default = "America/Chicago";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -4,118 +4,74 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "sparky-fitness-server";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
sparky-fitness-server = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "sparky-fitness-server";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "codewithcj/sparkyfitness_server";
|
||||
ports = [ "${toString cfg.port}:3010" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/sparky-fitness/server/backup:/app/SparkyFitnessServer/backup"
|
||||
"${cfg.configDir}/sparky-fitness/server/uploads:/app/SparkyFitnessServer/uploads"
|
||||
];
|
||||
# environmentFiles = [
|
||||
# "${cfg.configDir}/lubelogger/lubelogger.env"
|
||||
# ];
|
||||
environment = {
|
||||
SPARKY_FITNESS_LOG_LEVEL = "0";
|
||||
ALLOW_PRIVATE_NETWORK_CORS = "false";
|
||||
SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS = "";
|
||||
SPARKY_FITNESS_DB_USER = "sparkyfitness";
|
||||
SPARKY_FITNESS_DB_HOST = "10.0.1.3"; # Use the service name 'sparkyfitness-db' for inter-container communication
|
||||
SPARKY_FITNESS_DB_NAME = "sparkyfitness";
|
||||
SPARKY_FITNESS_DB_PASSWORD = "sparkyfitness";
|
||||
SPARKY_FITNESS_APP_DB_USER = "sparkyfitness";
|
||||
SPARKY_FITNESS_APP_DB_PASSWORD = "sparkyfitness";
|
||||
SPARKY_FITNESS_DB_PORT = "${toString dbCfg.port}";
|
||||
SPARKY_FITNESS_API_ENCRYPTION_KEY = "088ab2c6487ca1048c1fe74a4d8bd906e88db56953406769426b615d6df2407b";
|
||||
# Uncomment the line below and comment the line above to use a file-based secret
|
||||
# SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE: /run/secrets/sparkyfitness_api_key
|
||||
|
||||
BETTER_AUTH_SECRET = "a0304bda5a9efd0d92595c8d46526e33d58f436408f6b70ea37c2b84308d9abe";
|
||||
# Uncomment the line below and comment the line above to use a file-based secret
|
||||
# BETTER_AUTH_SECRET_FILE: /run/secrets/sparkyfitness_better_auth_secret
|
||||
SPARKY_FITNESS_FRONTEND_URL = "http://10.0.1.3:${toString frontendCfg.port}";
|
||||
SPARKY_FITNESS_DISABLE_SIGNUP = "false";
|
||||
SPARKY_FITNESS_ADMIN_EMAIL = "jalle008@proton.me"; #User with this email can access the admin panel
|
||||
# SPARKY_FITNESS_EMAIL_HOST = "${SPARKY_FITNESS_EMAIL_HOST}";
|
||||
# SPARKY_FITNESS_EMAIL_PORT = "${SPARKY_FITNESS_EMAIL_PORT}";
|
||||
# SPARKY_FITNESS_EMAIL_SECURE = "${SPARKY_FITNESS_EMAIL_SECURE}";
|
||||
# SPARKY_FITNESS_EMAIL_USER = "${SPARKY_FITNESS_EMAIL_USER}";
|
||||
# SPARKY_FITNESS_EMAIL_PASS = "${SPARKY_FITNESS_EMAIL_PASS}";
|
||||
# SPARKY_FITNESS_EMAIL_FROM = "${SPARKY_FITNESS_EMAIL_FROM}";
|
||||
PUID = toString config.users.users.nix-apps.uid;
|
||||
PGID = toString config.users.groups.jallen-nas.gid;
|
||||
TZ = "America/Chicago";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fontendName = "sparky-fitness";
|
||||
frontendCfg = config.${namespace}.services.${fontendName};
|
||||
|
||||
sparky-fitness-frontend = lib.${namespace}.mkModule {
|
||||
inherit config;
|
||||
name = fontendName;
|
||||
serviceName = "podman-${fontendName}";
|
||||
description = "sparky-fitness";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${fontendName} = {
|
||||
autoStart = true;
|
||||
image = "codewithcj/sparkyfitness";
|
||||
ports = [ "${toString frontendCfg.port}:80" ];
|
||||
environment = {
|
||||
SPARKY_FITNESS_FRONTEND_URL = "http://10.0.1.3:${toString frontendCfg.port}";
|
||||
SPARKY_FITNESS_SERVER_HOST = "10.0.1.3";
|
||||
SPARKY_FITNESS_SERVER_PORT = "${toString cfg.port}";
|
||||
PUID = toString config.users.users.nix-apps.uid;
|
||||
PGID = toString config.users.groups.jallen-nas.gid;
|
||||
TZ = "America/Chicago";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
inherit (lib.${namespace}) mkContainerService;
|
||||
|
||||
serverName = "sparky-fitness-server";
|
||||
frontendName = "sparky-fitness";
|
||||
dbName = "sparky-fitness-db";
|
||||
|
||||
serverCfg = config.${namespace}.services.${serverName};
|
||||
frontendCfg = config.${namespace}.services.${frontendName};
|
||||
dbCfg = config.${namespace}.services.${dbName};
|
||||
|
||||
sparky-fitness-db = lib.${namespace}.mkModule {
|
||||
inherit config;
|
||||
name = dbName;
|
||||
serviceName = "podman-${dbName}";
|
||||
description = "sparky-fitness-db";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${dbName} = {
|
||||
autoStart = true;
|
||||
image = "postgres:15-alpine";
|
||||
ports = [ "${toString dbCfg.port}:5432" ];
|
||||
volumes = [
|
||||
"${dbCfg.configDir}/sparky-fitness/db:/var/lib/postgresql/data"
|
||||
];
|
||||
environment = {
|
||||
POSTGRES_DB = "sparkyfitness-db";
|
||||
POSTGRES_USER = "sparkyfitness";
|
||||
POSTGRES_PASSWORD = "sparkyfitness";
|
||||
PUID = toString config.users.users.nix-apps.uid;
|
||||
PGID = toString config.users.groups.jallen-nas.gid;
|
||||
TZ = "America/Chicago";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ sparky-fitness-server sparky-fitness-frontend sparky-fitness-db ];
|
||||
imports = [
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = serverName;
|
||||
image = "codewithcj/sparkyfitness_server";
|
||||
internalPort = 3010;
|
||||
volumes = [
|
||||
"${serverCfg.configDir}/sparky-fitness/server/backup:/app/SparkyFitnessServer/backup"
|
||||
"${serverCfg.configDir}/sparky-fitness/server/uploads:/app/SparkyFitnessServer/uploads"
|
||||
];
|
||||
environment = {
|
||||
SPARKY_FITNESS_LOG_LEVEL = "0";
|
||||
ALLOW_PRIVATE_NETWORK_CORS = "false";
|
||||
SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS = "";
|
||||
SPARKY_FITNESS_DB_USER = "sparkyfitness";
|
||||
SPARKY_FITNESS_DB_HOST = "10.0.1.3";
|
||||
SPARKY_FITNESS_DB_NAME = "sparkyfitness";
|
||||
# TODO: move DB password and secrets to sops
|
||||
SPARKY_FITNESS_DB_PASSWORD = "sparkyfitness";
|
||||
SPARKY_FITNESS_APP_DB_USER = "sparkyfitness";
|
||||
SPARKY_FITNESS_APP_DB_PASSWORD = "sparkyfitness";
|
||||
SPARKY_FITNESS_DB_PORT = "${toString dbCfg.port}";
|
||||
SPARKY_FITNESS_API_ENCRYPTION_KEY = "088ab2c6487ca1048c1fe74a4d8bd906e88db56953406769426b615d6df2407b";
|
||||
BETTER_AUTH_SECRET = "a0304bda5a9efd0d92595c8d46526e33d58f436408f6b70ea37c2b84308d9abe";
|
||||
SPARKY_FITNESS_FRONTEND_URL = "http://10.0.1.3:${toString frontendCfg.port}";
|
||||
SPARKY_FITNESS_DISABLE_SIGNUP = "false";
|
||||
SPARKY_FITNESS_ADMIN_EMAIL = "jalle008@proton.me";
|
||||
};
|
||||
})
|
||||
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = frontendName;
|
||||
image = "codewithcj/sparkyfitness";
|
||||
internalPort = 80;
|
||||
environment = {
|
||||
SPARKY_FITNESS_FRONTEND_URL = "http://10.0.1.3:${toString frontendCfg.port}";
|
||||
SPARKY_FITNESS_SERVER_HOST = "10.0.1.3";
|
||||
SPARKY_FITNESS_SERVER_PORT = "${toString serverCfg.port}";
|
||||
};
|
||||
})
|
||||
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = dbName;
|
||||
image = "postgres:15-alpine";
|
||||
internalPort = 5432;
|
||||
volumes = [
|
||||
"${dbCfg.configDir}/sparky-fitness/db:/var/lib/postgresql/data"
|
||||
];
|
||||
environment = {
|
||||
POSTGRES_DB = "sparkyfitness-db";
|
||||
POSTGRES_USER = "sparkyfitness";
|
||||
# TODO: move POSTGRES_PASSWORD to sops
|
||||
POSTGRES_PASSWORD = "sparkyfitness";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,52 +4,45 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
inherit (lib.${namespace}) mkOpt;
|
||||
name = "tdarr";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
tdarrConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
description = "tdarr";
|
||||
options = {
|
||||
serverPort = mkOpt types.str "8266" "node port";
|
||||
};
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/haveagitgat/tdarr";
|
||||
extraOptions = [ "--device=nvidia.com/gpu=0" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/tdarr/config:/app/configs"
|
||||
"${cfg.configDir}/tdarr/server:/app/server"
|
||||
"${cfg.configDir}/tdarr/logs:/app/logs"
|
||||
"${cfg.configDir}/tdarr/transcode:/temp"
|
||||
"${cfg.dataDir}/movies:/data/movies"
|
||||
"${cfg.dataDir}/tv:/data/tv"
|
||||
];
|
||||
ports = [
|
||||
"${cfg.serverPort}:8266"
|
||||
"${cfg.port}:8265"
|
||||
];
|
||||
environment = {
|
||||
serverPort = "8266";
|
||||
webUIPort = "8265";
|
||||
internalNode = "true";
|
||||
inContainer = "true";
|
||||
ffmpegVersion = "6";
|
||||
nodeName = "tdarr node";
|
||||
NVIDIA_VISIBLE_DEVICES = "all";
|
||||
NVIDIA_DRIVER_CAPABILITIES = "all";
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
inherit (lib.${namespace}) mkOpt mkContainerService;
|
||||
cfg = config.${namespace}.services.tdarr;
|
||||
in
|
||||
{
|
||||
imports = [ tdarrConfig ];
|
||||
imports = [
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = "tdarr";
|
||||
image = "ghcr.io/haveagitgat/tdarr";
|
||||
internalPort = 8265;
|
||||
options = {
|
||||
serverPort = mkOpt lib.types.str "8266" "Tdarr node server port";
|
||||
};
|
||||
extraOptions = [ "--device=nvidia.com/gpu=0" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/tdarr/config:/app/configs"
|
||||
"${cfg.configDir}/tdarr/server:/app/server"
|
||||
"${cfg.configDir}/tdarr/logs:/app/logs"
|
||||
"${cfg.configDir}/tdarr/transcode:/temp"
|
||||
"${cfg.dataDir}/movies:/data/movies"
|
||||
"${cfg.dataDir}/tv:/data/tv"
|
||||
];
|
||||
environment = {
|
||||
serverPort = "8266";
|
||||
webUIPort = "8265";
|
||||
internalNode = "true";
|
||||
inContainer = "true";
|
||||
ffmpegVersion = "6";
|
||||
nodeName = "tdarr node";
|
||||
NVIDIA_VISIBLE_DEVICES = "all";
|
||||
NVIDIA_DRIVER_CAPABILITIES = "all";
|
||||
};
|
||||
extraConfig = {
|
||||
virtualisation.oci-containers.containers.tdarr.ports = lib.mkForce [
|
||||
"${cfg.serverPort}:8266"
|
||||
"${toString cfg.port}:8265"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,66 +4,44 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "termix";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
termixConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "termix";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
sops = {
|
||||
secrets = {
|
||||
"jallen-nas/termix/client-id" = {
|
||||
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
|
||||
};
|
||||
"jallen-nas/termix/client-secret" = {
|
||||
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
|
||||
};
|
||||
};
|
||||
templates = {
|
||||
"termix.env" = {
|
||||
mode = "660";
|
||||
owner = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
restartUnits = [ "podman-termix.service" ];
|
||||
content = ''
|
||||
OIDC_CLIENT_ID=${config.sops.placeholder."jallen-nas/termix/client-id"}
|
||||
OIDC_CLIENT_SECRET=${config.sops.placeholder."jallen-nas/termix/client-secret"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/lukegus/termix";
|
||||
volumes = [
|
||||
"${cfg.configDir}/termix:/app/data"
|
||||
];
|
||||
ports = [
|
||||
"${toString cfg.port}:8080"
|
||||
];
|
||||
environment = {
|
||||
OIDC_ISSUER_URL = "https://authentik.mjallen.dev/application/o/termix/";
|
||||
OIDC_AUTHORIZATION_URL = "https://authentik.mjallen.dev/application/o/authorize/";
|
||||
OIDC_TOKEN_URL = "https://authentik.mjallen.dev/application/o/token/";
|
||||
OIDC_FORCE_HTTPS = "true";
|
||||
GUACD_HOST = "10.0.1.3";
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.termix;
|
||||
inherit (lib.${namespace}) mkSopsEnvFile mkContainerService;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./guacd.nix
|
||||
termixConfig
|
||||
|
||||
# Sops env-file for OIDC credentials
|
||||
{
|
||||
config = lib.mkIf cfg.enable (mkSopsEnvFile {
|
||||
name = "termix.env";
|
||||
restartUnit = "podman-termix.service";
|
||||
secrets = {
|
||||
"jallen-nas/termix/client-id" = { };
|
||||
"jallen-nas/termix/client-secret" = { };
|
||||
};
|
||||
content = ''
|
||||
OIDC_CLIENT_ID=${config.sops.placeholder."jallen-nas/termix/client-id"}
|
||||
OIDC_CLIENT_SECRET=${config.sops.placeholder."jallen-nas/termix/client-secret"}
|
||||
'';
|
||||
});
|
||||
}
|
||||
|
||||
(mkContainerService {
|
||||
inherit config;
|
||||
name = "termix";
|
||||
image = "ghcr.io/lukegus/termix";
|
||||
internalPort = 8080;
|
||||
volumes = [ "${cfg.configDir}/termix:/app/data" ];
|
||||
environmentFiles = [ config.sops.templates."termix.env".path ];
|
||||
environment = {
|
||||
OIDC_ISSUER_URL = "https://authentik.mjallen.dev/application/o/termix/";
|
||||
OIDC_AUTHORIZATION_URL = "https://authentik.mjallen.dev/application/o/authorize/";
|
||||
OIDC_TOKEN_URL = "https://authentik.mjallen.dev/application/o/token/";
|
||||
OIDC_FORCE_HTTPS = "true";
|
||||
GUACD_HOST = "10.0.1.3";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,32 +4,13 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "guacd";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
guacdConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "guacd";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "guacamole/guacd";
|
||||
ports = [
|
||||
"${toString cfg.port}:4822"
|
||||
];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ guacdConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "guacd";
|
||||
image = "guacamole/guacd";
|
||||
internalPort = 4822;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,40 +4,24 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "tunarr";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
tunarrConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "tunarr";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/chrisbenincasa/tunarr";
|
||||
extraOptions = [ "--device=/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/tunarr:/config/tunarr"
|
||||
"${cfg.configDir}/tunarr:/root/.local/share/tunarr"
|
||||
"${cfg.dataDir}/movies:/libraries/movies"
|
||||
"${cfg.dataDir}/tv:/libraries/tv"
|
||||
"${cfg.configDir}/transcode:/transcode"
|
||||
];
|
||||
ports = [
|
||||
"${toString cfg.port}:8000"
|
||||
];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.tunarr;
|
||||
in
|
||||
{
|
||||
imports = [ tunarrConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "tunarr";
|
||||
image = "ghcr.io/chrisbenincasa/tunarr";
|
||||
internalPort = 8000;
|
||||
extraOptions = [ "--device=/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/tunarr:/config/tunarr"
|
||||
"${cfg.configDir}/tunarr:/root/.local/share/tunarr"
|
||||
"${cfg.dataDir}/movies:/libraries/movies"
|
||||
"${cfg.dataDir}/tv:/libraries/tv"
|
||||
"${cfg.configDir}/transcode:/transcode"
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,41 +4,23 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "unmanic";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
unmanicConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "podman-${name}";
|
||||
description = "unmanic";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers.${name} = {
|
||||
autoStart = true;
|
||||
image = "josh5/unmanic";
|
||||
devices = [
|
||||
"/dev/dri:/dev/dri"
|
||||
];
|
||||
volumes = [
|
||||
"${cfg.configDir}/unmanic:/config"
|
||||
"${cfg.dataDir}/movies:/library/movies"
|
||||
"${cfg.dataDir}/tv:/library/tv"
|
||||
"${cfg.configDir}/unmanic/transcode:/tmp/unmanic"
|
||||
];
|
||||
ports = [
|
||||
"${toString cfg.port}:8888"
|
||||
];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
cfg = config.${namespace}.services.unmanic;
|
||||
in
|
||||
{
|
||||
imports = [ unmanicConfig ];
|
||||
imports = [
|
||||
(lib.${namespace}.mkContainerService {
|
||||
inherit config;
|
||||
name = "unmanic";
|
||||
image = "josh5/unmanic";
|
||||
internalPort = 8888;
|
||||
devices = [ "/dev/dri:/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/unmanic:/config"
|
||||
"${cfg.dataDir}/movies:/library/movies"
|
||||
"${cfg.dataDir}/tv:/library/tv"
|
||||
"${cfg.configDir}/unmanic/transcode:/tmp/unmanic"
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,43 +4,54 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.services.your_spotify;
|
||||
inherit (lib.${namespace}) mkOpt mkModule;
|
||||
name = "your-spotify";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
virtualisation.oci-containers.containers."${cfg.name}-server" = {
|
||||
autoStart = true;
|
||||
image = cfg.imageServer;
|
||||
volumes = [ "${cfg.configPath}:/root/.your-spotify" ];
|
||||
ports = [ "${cfg.portServer}:8080" ];
|
||||
dependsOn = [ "mongo" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
API_ENDPOINT = "https://your-spotify-server.mjallen.dev";
|
||||
CLIENT_ENDPOINT = "https://your-spotify.mjallen.dev";
|
||||
SPOTIFY_PUBLIC = "e270589d72a6494680a17d325af8670d";
|
||||
SPOTIFY_SECRET = "423cb7b69fe8486e89eccd01e0c22924";
|
||||
MONGO_ENDPOINT = "mongodb://10.0.1.3:27017";
|
||||
imports = [
|
||||
(mkModule {
|
||||
inherit config name;
|
||||
description = "Your Spotify — self-hosted Spotify stats";
|
||||
options = {
|
||||
serverPort = mkOpt lib.types.int 7777 "Port for the API server container";
|
||||
webPort = mkOpt lib.types.int 7778 "Port for the web client container";
|
||||
imageServer = mkOpt lib.types.str "yooooomi/your_spotify_server" "Server OCI image";
|
||||
imageWeb = mkOpt lib.types.str "yooooomi/your_spotify_client" "Web client OCI image";
|
||||
};
|
||||
};
|
||||
moduleConfig = {
|
||||
virtualisation.oci-containers.containers."${name}-server" = {
|
||||
autoStart = true;
|
||||
image = cfg.imageServer;
|
||||
volumes = [ "${cfg.configDir}:/root/.your-spotify" ];
|
||||
ports = [ "${toString cfg.serverPort}:8080" ];
|
||||
dependsOn = [ "mongo" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
API_ENDPOINT = "https://your-spotify-server.mjallen.dev";
|
||||
CLIENT_ENDPOINT = "https://your-spotify.mjallen.dev";
|
||||
# TODO: move Spotify API keys to sops secrets
|
||||
SPOTIFY_PUBLIC = "e270589d72a6494680a17d325af8670d";
|
||||
SPOTIFY_SECRET = "423cb7b69fe8486e89eccd01e0c22924";
|
||||
MONGO_ENDPOINT = "mongodb://10.0.1.3:27017";
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers."${cfg.name}-web" = {
|
||||
autoStart = true;
|
||||
image = cfg.imageWeb;
|
||||
ports = [ "${cfg.portWeb}:3000" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
API_ENDPOINT = "https://your-spotify-server.mjallen.dev";
|
||||
virtualisation.oci-containers.containers."${name}-web" = {
|
||||
autoStart = true;
|
||||
image = cfg.imageWeb;
|
||||
ports = [ "${toString cfg.webPort}:3000" ];
|
||||
environment = {
|
||||
PUID = cfg.puid;
|
||||
PGID = cfg.pgid;
|
||||
TZ = cfg.timeZone;
|
||||
API_ENDPOINT = "https://your-spotify-server.mjallen.dev";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.services.your_spotify = {
|
||||
enable = mkEnableOption "your_spotify docker service";
|
||||
|
||||
autoStart = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
portServer = mkOption {
|
||||
type = types.str;
|
||||
default = "7777";
|
||||
};
|
||||
|
||||
portWeb = mkOption {
|
||||
type = types.str;
|
||||
default = "7778";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "your_spotify";
|
||||
};
|
||||
|
||||
imageServer = mkOption {
|
||||
type = types.str;
|
||||
default = "yooooomi/your_spotify_server";
|
||||
};
|
||||
|
||||
imageWeb = mkOption {
|
||||
type = types.str;
|
||||
default = "yooooomi/your_spotify_client";
|
||||
};
|
||||
|
||||
configPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/your-spotify";
|
||||
};
|
||||
|
||||
puid = mkOption {
|
||||
type = types.str;
|
||||
default = "911";
|
||||
};
|
||||
|
||||
pgid = mkOption {
|
||||
type = types.str;
|
||||
default = "100";
|
||||
};
|
||||
|
||||
timeZone = mkOption {
|
||||
type = types.str;
|
||||
default = "UTC";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
programs = {
|
||||
zsh.enable = lib.mkForce true;
|
||||
gnupg.agent = {
|
||||
enable = lib.mkDefault true;
|
||||
enableSSHSupport = lib.mkDefault true;
|
||||
};
|
||||
nix-index = {
|
||||
enable = lib.mkDefault true;
|
||||
enableBashIntegration = lib.mkDefault false;
|
||||
enableZshIntegration = lib.mkDefault true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -6,114 +6,35 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
defaultSops = (lib.snowfall.fs.get-file "secrets/secrets.yaml");
|
||||
cfg = config.${namespace}.sops;
|
||||
defaultSops = lib.snowfall.fs.get-file "secrets/secrets.yaml";
|
||||
isx86 = system == "x86_64-linux";
|
||||
user = config.${namespace}.user.name;
|
||||
in
|
||||
{
|
||||
# Permission modes are in octal representation (same as chmod),
|
||||
# the digits represent: user|group|others
|
||||
# 7 - full (rwx)
|
||||
# 6 - read and write (rw-)
|
||||
# 5 - read and execute (r-x)
|
||||
# 4 - read only (r--)
|
||||
# 3 - write and execute (-wx)
|
||||
# 2 - write only (-w-)
|
||||
# 1 - execute only (--x)
|
||||
# 0 - none (---)
|
||||
# Either a user id or group name representation of the secret owner
|
||||
# It is recommended to get the user name from `config.users.users.<?name>.name` to avoid misconfiguration
|
||||
# Either the group id or group name representation of the secret group
|
||||
# It is recommended to get the group name from `config.users.users.<?name>.group` to avoid misconfiguration
|
||||
sops = {
|
||||
defaultSopsFile = defaultSops;
|
||||
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
# ------------------------------
|
||||
# Secrets
|
||||
# ------------------------------
|
||||
secrets = {
|
||||
"wifi" = { };
|
||||
config = lib.mkIf cfg.enable {
|
||||
sops = {
|
||||
defaultSopsFile = if cfg.defaultSopsFile != null then cfg.defaultSopsFile else defaultSops;
|
||||
age.sshKeyPaths = cfg.sshKeyPaths;
|
||||
|
||||
"matt_password" = {
|
||||
neededForUsers = true;
|
||||
mode = "0600";
|
||||
owner = config.users.users."${user}".name;
|
||||
group = config.users.users."${user}".group;
|
||||
};
|
||||
secrets = {
|
||||
"wifi" = { };
|
||||
"disk-key".mode = "0600";
|
||||
|
||||
"disk-key" = {
|
||||
mode = "0600";
|
||||
};
|
||||
"matt_password" = {
|
||||
neededForUsers = true;
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
# ------------------------------
|
||||
# SSH keys
|
||||
# ------------------------------
|
||||
# "ssh-keys-public/desktop-nixos" = {
|
||||
# sopsFile = sharedSops;
|
||||
# mode = "0644";
|
||||
# owner = config.users.users."${user}".name;
|
||||
# group = config.users.users."${user}".group;
|
||||
# restartUnits = [ "sshd.service" ];
|
||||
# };
|
||||
# "ssh-keys-private/desktop-nixos" = {
|
||||
# sopsFile = sharedSops;
|
||||
# mode = "0600";
|
||||
# owner = config.users.users."${user}".name;
|
||||
# group = config.users.users."${user}".group;
|
||||
# restartUnits = [ "sshd.service" ];
|
||||
# };
|
||||
# "ssh-keys-public/desktop-nixos-root" = {
|
||||
# sopsFile = sharedSops;
|
||||
# path = "/root/.ssh/id_ed25519.pub";
|
||||
# mode = "0600";
|
||||
# restartUnits = [ "sshd.service" ];
|
||||
# };
|
||||
# "ssh-keys-private/desktop-nixos-root" = {
|
||||
# sopsFile = sharedSops;
|
||||
# path = "/root/.ssh/id_ed25519";
|
||||
# mode = "0600";
|
||||
# restartUnits = [ "sshd.service" ];
|
||||
# };
|
||||
|
||||
# ------------------------------
|
||||
# Secureboot keys
|
||||
# ------------------------------
|
||||
"secureboot/GUID" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/GUID";
|
||||
mode = "0600";
|
||||
"secureboot/GUID" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/db-key" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/db-pem" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/KEK-key" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/KEK-pem" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/PK-key" = lib.mkIf isx86 { mode = "0600"; };
|
||||
"secureboot/keys/PK-pem" = lib.mkIf isx86 { mode = "0600"; };
|
||||
};
|
||||
"secureboot/keys/db-key" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/db/db.key";
|
||||
mode = "0600";
|
||||
};
|
||||
"secureboot/keys/db-pem" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/db/db.pem";
|
||||
mode = "0600";
|
||||
};
|
||||
"secureboot/keys/KEK-key" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/KEK/KEK.key";
|
||||
mode = "0600";
|
||||
};
|
||||
"secureboot/keys/KEK-pem" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/KEK/KEK.pem";
|
||||
mode = "0600";
|
||||
};
|
||||
"secureboot/keys/PK-key" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/PK/PK.key";
|
||||
mode = "0600";
|
||||
};
|
||||
"secureboot/keys/PK-pem" = lib.mkIf isx86 {
|
||||
# path = "/etc/secureboot/keys/PK/PK.pem";
|
||||
mode = "0600";
|
||||
};
|
||||
};
|
||||
|
||||
# ------------------------------
|
||||
# Templates
|
||||
# ------------------------------
|
||||
templates = {
|
||||
# ...
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ with lib;
|
||||
enable = mkEnableOption "enable sops";
|
||||
|
||||
defaultSopsFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Default sops file to use for secrets. If null, will use the system-wide default.";
|
||||
example = "/etc/nixos/secrets/secrets.yaml";
|
||||
|
||||
@@ -8,20 +8,27 @@
|
||||
with lib;
|
||||
let
|
||||
inherit (lib.${namespace}) mkOpt mkBoolOpt;
|
||||
cfg = config.${namespace}.user // {
|
||||
hashedPasswordFile = (
|
||||
if
|
||||
(
|
||||
config.${namespace}.user.hashedPassword == null
|
||||
&& config.${namespace}.user.hashedPasswordFile == null
|
||||
&& config.${namespace}.user.password == null
|
||||
)
|
||||
then
|
||||
defaultPasswordFile
|
||||
else
|
||||
config.${namespace}.user.hashedPasswordFile
|
||||
);
|
||||
};
|
||||
cfg = config.${namespace}.user;
|
||||
|
||||
# Reference the sops-managed password file only when the secret has been
|
||||
# declared somewhere in the configuration. Checking the attrset with ?
|
||||
# avoids forcing evaluation of the secret path on hosts that don't use sops.
|
||||
sopsMattPassword =
|
||||
let
|
||||
secretName = cfg.sopsPasswordSecret;
|
||||
in
|
||||
if secretName != null && builtins.hasAttr secretName config.sops.secrets then
|
||||
config.sops.secrets.${secretName}.path
|
||||
else
|
||||
null;
|
||||
|
||||
# Fall back to the sops-managed password file only when no explicit password
|
||||
# method has been set by the caller.
|
||||
resolvedPasswordFile =
|
||||
if cfg.hashedPassword == null && cfg.hashedPasswordFile == null && cfg.password == null then
|
||||
sopsMattPassword
|
||||
else
|
||||
cfg.hashedPasswordFile;
|
||||
|
||||
# Common SSH keys used across systems
|
||||
commonSshKeys = [
|
||||
@@ -39,7 +46,6 @@ let
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGdwsYDOkjd17rKdpjKN+3Yx1rRHT/Fiv2erc2JdE6ibHKBxLSEZ4kCOFCyGyc5ZO6Cmb09GfAe9FugkD4titns= cardno:33_720_987"
|
||||
];
|
||||
|
||||
defaultPasswordFile = config.sops.secrets."matt_password".path;
|
||||
in
|
||||
{
|
||||
options.${namespace}.user = with types; {
|
||||
@@ -73,7 +79,11 @@ in
|
||||
|
||||
hashedPasswordFile = mkOpt (nullOr path) null "Path to the password file for this user account";
|
||||
|
||||
mutableUsers = mkBoolOpt false "Whether users are mutable (can be modified after creation).";
|
||||
sopsPasswordSecret =
|
||||
mkOpt (nullOr str) "matt_password"
|
||||
"Name of the sops secret to use as the hashed password file when no explicit password method is set. Set to null to disable the sops fallback.";
|
||||
|
||||
mutableUsers = mkBoolOpt false "Whether users are mutable (can be modified after modification).";
|
||||
};
|
||||
|
||||
config = {
|
||||
@@ -94,8 +104,8 @@ in
|
||||
packages
|
||||
password
|
||||
hashedPassword
|
||||
hashedPasswordFile
|
||||
;
|
||||
hashedPasswordFile = resolvedPasswordFile;
|
||||
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
@@ -137,8 +147,8 @@ in
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(cfg.password != null) || (cfg.hashedPassword != null) || (cfg.hashedPasswordFile != null);
|
||||
message = "User '${cfg.name}' requires at least one password method (password, hashedPassword, or hashedPasswordFile).";
|
||||
(cfg.password != null) || (cfg.hashedPassword != null) || (resolvedPasswordFile != null);
|
||||
message = "User '${cfg.name}' requires at least one password method (password, hashedPassword, hashedPasswordFile, or a sops 'matt_password' secret).";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
@@ -146,19 +156,11 @@ in
|
||||
passwordMethods = lib.count (x: x != null) [
|
||||
cfg.password
|
||||
cfg.hashedPassword
|
||||
cfg.hashedPasswordFile
|
||||
resolvedPasswordFile
|
||||
];
|
||||
in
|
||||
passwordMethods <= 1;
|
||||
message = "User '${cfg.name}' can only use one password method at a time. Found multiple: ${
|
||||
lib.concatStringsSep ", " (
|
||||
lib.filter (x: x != null) [
|
||||
(if cfg.password != null then "password" else null)
|
||||
(if cfg.hashedPassword != null then "hashedPassword" else null)
|
||||
(if cfg.hashedPasswordFile != null then "hashedPasswordFile" else null)
|
||||
]
|
||||
)
|
||||
}";
|
||||
message = "User '${cfg.name}' can only use one password method at a time.";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
virtualisation = {
|
||||
libvirtd.enable = lib.mkDefault true;
|
||||
podman.enable = lib.mkDefault true;
|
||||
waydroid.enable = lib.mkDefault true;
|
||||
waydroid.enable = lib.mkDefault false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,34 +2,14 @@
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
|
||||
final: prev:
|
||||
let
|
||||
ubootPackages = final.callPackage ../../packages/uboot { };
|
||||
|
||||
# fetchFromGitHub = inputs.nixpkgs.fetchFromGitHub;
|
||||
|
||||
# linux618Src = fetchFromGitHub {
|
||||
# owner = "raspberrypi";
|
||||
# repo = "linux";
|
||||
# rev = "bb594fb36f555f9b88b7b6fcf8b71c669c1d60c7";
|
||||
# hash = "sha256-T3RJRroYtzLwx4JqcaX15Ka1uVf72jQOZMf7TJVZ6co=";
|
||||
# };
|
||||
|
||||
# linux619Src = fetchFromGitHub {
|
||||
# owner = "raspberrypi";
|
||||
# repo = "linux";
|
||||
# rev = "87e52a7868888c66b2782c949c8406c27f909c11";
|
||||
# hash = "sha256-C81aKv+pQYNx6Bj3PL0vrxvBzrLB99+95YeIBm+4kt0=";
|
||||
# };
|
||||
|
||||
linux-rpi5 = final.linuxPackagesFor (final.${namespace}.linux-rpi);
|
||||
linux-rpi5-latest = final.linuxPackagesFor (
|
||||
final.${namespace}.linux-rpi.override {
|
||||
kernelVersion = "unstable";
|
||||
}
|
||||
);
|
||||
|
||||
linux-rpi4 = final.linuxPackagesFor (
|
||||
final.${namespace}.linux-rpi.override {
|
||||
rpiVersion = 4;
|
||||
@@ -38,23 +18,8 @@ let
|
||||
in
|
||||
{
|
||||
${namespace} = prev.${namespace} // {
|
||||
uboot-pi5 = ubootPackages.ubootRaspberryPi5;
|
||||
uboot-pi4 = ubootPackages.ubootRaspberryPi4;
|
||||
|
||||
linuxPackages_rpi5-lts = linux-rpi5;
|
||||
linuxPackages_rpi4-lts = linux-rpi4;
|
||||
linuxPackages_rpi5-latest = linux-rpi5-latest;
|
||||
# linuxPackages_rpi5-rc = linux-rpi5.overrideAttrs (_old: {
|
||||
# modDirVersion = "6.19.0-rc5";
|
||||
# src = linux619Src;
|
||||
# });
|
||||
# linuxPackages_rpi4-latest = linux-rpi4.overrideAttrs (_old: {
|
||||
# modDirVersion = "6.18.4";
|
||||
# src = linux618Src;
|
||||
# });
|
||||
# linuxPackages_rpi4-rc = linux-rpi4.overrideAttrs (_old: {
|
||||
# modDirVersion = "6.19.0-rc5";
|
||||
# src = linux619Src;
|
||||
# });
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{ inputs, ... }:
|
||||
_final: _prev: {
|
||||
mjallen-lib = (import ../../lib { inherit inputs; }).mjallen-lib;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{ inputs, ... }:
|
||||
final: _prev: {
|
||||
unstable = import inputs.nixpkgs-unstable {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
}
|
||||
@@ -23,6 +23,8 @@
|
||||
${namespace} = {
|
||||
headless.enable = false;
|
||||
|
||||
sops.enable = true;
|
||||
|
||||
impermanence = {
|
||||
enable = true;
|
||||
# extraDirectories = [
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
}:
|
||||
{
|
||||
boot = {
|
||||
# loader.raspberry-pi = {
|
||||
# bootloader = "kernel";
|
||||
# firmwarePackage = pkgs.raspberrypifw;
|
||||
# };
|
||||
kernelPackages = pkgs.${namespace}.linuxPackages_rpi5-latest;
|
||||
initrd = {
|
||||
availableKernelModules = lib.mkForce [ ];
|
||||
@@ -43,84 +39,17 @@
|
||||
|
||||
specialisation = {
|
||||
"linux-stable".configuration = {
|
||||
boot = {
|
||||
kernelPackages = lib.mkOverride 90 pkgs.${namespace}.linuxPackages_rpi5-lts;
|
||||
# loader.systemd-boot.installDeviceTree = true;
|
||||
};
|
||||
# hardware.deviceTree = {
|
||||
# enable = true;
|
||||
# package = lib.mkForce pkgs.${namespace}.linuxPackages_rpi5-lts.kernel;
|
||||
# name = "bcm2712-rpi-5-b.dtb";
|
||||
# filter = "bcm2712*";
|
||||
# };
|
||||
# boot.bootspec.extensions."org.nixos.systemd-boot" = lib.mkForce {
|
||||
# inherit (config.boot.loader.systemd-boot) sortKey;
|
||||
# devicetree = "./bcm2712-rpi-5-b.dtb";
|
||||
# };
|
||||
boot.kernelPackages = lib.mkOverride 90 pkgs.${namespace}.linuxPackages_rpi5-lts;
|
||||
};
|
||||
};
|
||||
|
||||
${namespace}.hardware.raspberry-pi.config = {
|
||||
# extra-config = {
|
||||
# armstub = "RPI_EFI.fd";
|
||||
# };
|
||||
all = {
|
||||
# # [all] conditional filter, https://www.raspberrypi.com/documentation/computers/config_txt.html#conditional-filters
|
||||
|
||||
# options = {
|
||||
# # https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_uart
|
||||
# # in conjunction with `console=serial0,115200` in kernel command line (`cmdline.txt`)
|
||||
# # creates a serial console, accessible using GPIOs 14 and 15 (pins
|
||||
# # 8 and 10 on the 40-pin header)
|
||||
# enable_uart = {
|
||||
# enable = true;
|
||||
# value = true;
|
||||
# };
|
||||
# # https://www.raspberrypi.com/documentation/computers/config_txt.html#uart_2ndstage
|
||||
# # enable debug logging to the UART, also automatically enables
|
||||
# # UART logging in `start.elf`
|
||||
# uart_2ndstage = {
|
||||
# enable = true;
|
||||
# value = true;
|
||||
# };
|
||||
# };
|
||||
|
||||
# Base DTB parameters
|
||||
# https://github.com/raspberrypi/linux/blob/a1d3defcca200077e1e382fe049ca613d16efd2b/arch/arm/boot/dts/overlays/README#L132
|
||||
base-dt-params = {
|
||||
|
||||
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#enable-pcie
|
||||
pciex1 = {
|
||||
enable = true;
|
||||
value = "on";
|
||||
};
|
||||
# PCIe Gen 3.0
|
||||
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0
|
||||
pciex1_gen = {
|
||||
enable = true;
|
||||
value = "3";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# extra-config = ''
|
||||
# armstub=RPI_EFI.fd
|
||||
# device_tree_address=0x1f0000
|
||||
# device_tree_end=0x210000
|
||||
|
||||
# # Force 32 bpp framebuffer allocation.
|
||||
# framebuffer_depth=32
|
||||
|
||||
# # Disable compensation for displays with overscan.
|
||||
# disable_overscan=1
|
||||
|
||||
# # Force maximum USB power regardless of the power supply.
|
||||
# usb_max_current_enable=1
|
||||
|
||||
# # Force maximum CPU speed.
|
||||
# force_turbo=1
|
||||
# '';
|
||||
|
||||
};
|
||||
${namespace}.hardware.raspberry-pi.config.all.base-dt-params = {
|
||||
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#enable-pcie
|
||||
pciex1.enable = true;
|
||||
pciex1.value = "on";
|
||||
# PCIe Gen 3.0
|
||||
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0
|
||||
pciex1_gen.enable = true;
|
||||
pciex1_gen.value = "3";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
${namespace} = {
|
||||
|
||||
sops.enable = true;
|
||||
|
||||
# ###################################################
|
||||
# # Impermanence # #
|
||||
# ###################################################
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
${namespace} = {
|
||||
headless.enable = false;
|
||||
|
||||
sops.enable = true;
|
||||
|
||||
bootloader.lanzaboote.enable = true;
|
||||
|
||||
desktop.gnome.enable = true;
|
||||
|
||||
@@ -19,10 +19,7 @@ in
|
||||
ai = {
|
||||
enable = true;
|
||||
};
|
||||
arrs = {
|
||||
enable = true;
|
||||
enableVpn = true;
|
||||
};
|
||||
arrs.enable = true;
|
||||
attic = {
|
||||
enable = true;
|
||||
port = 9012;
|
||||
|
||||
@@ -26,6 +26,7 @@ in
|
||||
powerManagement.cpuFreqGovernor = "powersave";
|
||||
|
||||
${namespace} = {
|
||||
sops.enable = true;
|
||||
# ###################################################
|
||||
# # Boot # #
|
||||
# ###################################################
|
||||
|
||||
@@ -17,6 +17,7 @@ in
|
||||
consoleLogLevel = 3;
|
||||
};
|
||||
${namespace} = {
|
||||
sops.enable = true;
|
||||
services = {
|
||||
actual = mkForce disabled;
|
||||
ai = mkForce disabled;
|
||||
|
||||
@@ -21,66 +21,69 @@ let
|
||||
};
|
||||
in
|
||||
{
|
||||
# Bespoke services that define their own path options (not via mkModule).
|
||||
# Set NAS-specific paths here so the module defaults stay generic.
|
||||
${namespace}.services.your_spotify.configPath = lib.mkDefault "${appdata}/your_spotify";
|
||||
${namespace}.services.ocis = {
|
||||
dataPath = lib.mkDefault "${data}/ocis";
|
||||
configPath = lib.mkDefault "${appdata}/ocis";
|
||||
};
|
||||
|
||||
imports = map svcDefault [
|
||||
"actual"
|
||||
"ai"
|
||||
"arrs"
|
||||
"attic"
|
||||
"authentik"
|
||||
"authentikRac"
|
||||
"booklore"
|
||||
"caddy"
|
||||
"calibre"
|
||||
"calibre-web"
|
||||
"code-server"
|
||||
"collabora"
|
||||
"coturn"
|
||||
"crowdsec"
|
||||
"dispatcharr"
|
||||
"free-games-claimer"
|
||||
"gitea"
|
||||
"glance"
|
||||
"glances"
|
||||
"grafana"
|
||||
"guacd"
|
||||
"headscale"
|
||||
"immich"
|
||||
"jellyfin"
|
||||
"jellyseerr"
|
||||
"lubelogger"
|
||||
"manyfold"
|
||||
"matrix"
|
||||
"minecraft"
|
||||
"mongodb"
|
||||
"nebula"
|
||||
"nebula-lighthouse"
|
||||
"netbootxyz"
|
||||
"nextcloud"
|
||||
"ntfy"
|
||||
"onlyoffice"
|
||||
"opencloud"
|
||||
"orca-slicer"
|
||||
"paperless"
|
||||
"paperless-ai"
|
||||
"protonmail-bridge"
|
||||
"restic"
|
||||
"sparky-fitness"
|
||||
"sparky-fitness-server"
|
||||
"sparky-fitness-db"
|
||||
"sunshine"
|
||||
"tdarr"
|
||||
"termix"
|
||||
"tunarr"
|
||||
"unmanic"
|
||||
"uptime-kuma"
|
||||
"wyoming"
|
||||
];
|
||||
imports =
|
||||
# Bespoke services with their own path option names (not configDir/dataDir).
|
||||
[
|
||||
{
|
||||
${namespace}.services.ocis = {
|
||||
dataPath = lib.mkDefault "${data}/ocis";
|
||||
configPath = lib.mkDefault "${appdata}/ocis";
|
||||
};
|
||||
}
|
||||
]
|
||||
++ map svcDefault [
|
||||
"actual"
|
||||
"ai"
|
||||
"arrs"
|
||||
"attic"
|
||||
"authentik"
|
||||
"authentikRac"
|
||||
"booklore"
|
||||
"caddy"
|
||||
"calibre"
|
||||
"calibre-web"
|
||||
"code-server"
|
||||
"collabora"
|
||||
"coturn"
|
||||
"crowdsec"
|
||||
"dispatcharr"
|
||||
"free-games-claimer"
|
||||
"gitea"
|
||||
"glance"
|
||||
"glances"
|
||||
"grafana"
|
||||
"guacd"
|
||||
"headscale"
|
||||
"immich"
|
||||
"jellyfin"
|
||||
"jellyseerr"
|
||||
"lubelogger"
|
||||
"manyfold"
|
||||
"matrix"
|
||||
"minecraft"
|
||||
"mongodb"
|
||||
"nebula"
|
||||
"nebula-lighthouse"
|
||||
"netbootxyz"
|
||||
"nextcloud"
|
||||
"ntfy"
|
||||
"onlyoffice"
|
||||
"opencloud"
|
||||
"orca-slicer"
|
||||
"paperless"
|
||||
"paperless-ai"
|
||||
"protonmail-bridge"
|
||||
"restic"
|
||||
"sparky-fitness"
|
||||
"sparky-fitness-server"
|
||||
"sparky-fitness-db"
|
||||
"sunshine"
|
||||
"tdarr"
|
||||
"termix"
|
||||
"tunarr"
|
||||
"unmanic"
|
||||
"uptime-kuma"
|
||||
"wyoming"
|
||||
"your-spotify"
|
||||
];
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
nasData = "/media/nas/main";
|
||||
in
|
||||
{
|
||||
systemd.network.wait-online.enable = false;
|
||||
# Force tailscaled to use nftables (Critical for clean nftables-only systems)
|
||||
@@ -37,7 +40,7 @@
|
||||
enable = true;
|
||||
package = pkgs.postgresql_16;
|
||||
enableTCPIP = true;
|
||||
dataDir = "/media/nas/main/databases/postgresql";
|
||||
dataDir = "${nasData}/databases/postgresql";
|
||||
ensureDatabases = [
|
||||
"authentik"
|
||||
"homeassistant"
|
||||
@@ -95,7 +98,7 @@
|
||||
mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb; # explicit MariaDB package
|
||||
dataDir = "/media/nas/main/databases/mariadb";
|
||||
dataDir = "${nasData}/databases/mariadb";
|
||||
settings.mysqld = {
|
||||
bind-address = "0.0.0.0";
|
||||
port = 3306;
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
# let
|
||||
# configFile = pkgs.writeText "openvpn-config-us.protonvpn.udp" ''
|
||||
# errors-to-stderr
|
||||
# ${config.services.openvpn.servers."us.protonvpn.udp".config}
|
||||
# auth-user-pass ${config.services.openvpn.servers."us.protonvpn.udp".authUserPass}
|
||||
# '';
|
||||
# in
|
||||
{
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = true;
|
||||
sops = {
|
||||
@@ -31,80 +24,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
# networking.nftables = {
|
||||
# enable = true;
|
||||
# ruleset = ''
|
||||
# table ip nat {
|
||||
# chain postrouting {
|
||||
# type nat hook postrouting priority 100;
|
||||
# oifname "enp197s0" ip saddr 10.200.0.0/30 masquerade
|
||||
# }
|
||||
# }
|
||||
# '';
|
||||
# };
|
||||
|
||||
# systemd.services = {
|
||||
# vpn-netns =
|
||||
# let
|
||||
# ip = "${pkgs.iproute2}/bin/ip";
|
||||
# in {
|
||||
# description = "Create VPN network namespace";
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# before = [ "openvpn-us.protonvpn.udp.service" ];
|
||||
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = true;
|
||||
|
||||
# ExecStart = pkgs.writeShellScript "vpn-netns-up" ''
|
||||
# set -euxo pipefail
|
||||
|
||||
# # Ensure namespace exists
|
||||
# ${ip} netns add vpn 2>/dev/null || true
|
||||
|
||||
# # Clean up any previous veth (deleting one end deletes the peer too)
|
||||
# ${ip} link del veth-host 2>/dev/null || true
|
||||
|
||||
# # Create veth pair
|
||||
# ${ip} link add veth-host type veth peer name veth-vpn
|
||||
|
||||
# # Move peer into namespace
|
||||
# ${ip} link set veth-vpn netns vpn
|
||||
|
||||
# # Host side
|
||||
# ${ip} addr add 10.200.0.1/30 dev veth-host 2>/dev/null || true
|
||||
# ${ip} link set veth-host up
|
||||
|
||||
# # Namespace side
|
||||
# ${ip} -n vpn addr add 10.200.0.2/30 dev veth-vpn 2>/dev/null || true
|
||||
# ${ip} -n vpn link set veth-vpn up
|
||||
# ${ip} -n vpn link set lo up
|
||||
|
||||
# # Default route in namespace via host
|
||||
# ${ip} -n vpn route replace default via 10.200.0.1
|
||||
|
||||
# ${ip} -n vpn route replace 10.0.1.0/24 via 10.200.0.1 dev veth-vpn
|
||||
# '';
|
||||
# ExecStop = pkgs.writeShellScript "vpn-netns-down" ''
|
||||
# set -eux
|
||||
# ${ip} link del veth-host 2>/dev/null || true
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
|
||||
# "openvpn-us.protonvpn.udp" = {
|
||||
# after = [ "network-online.target" "vpn-netns.service" ];
|
||||
# wants = [ "network-online.target" ];
|
||||
# serviceConfig = {
|
||||
# ExecStart = lib.mkOverride 90 ''
|
||||
# ${pkgs.iproute2}/bin/ip netns exec vpn \
|
||||
# ${pkgs.openvpn}/sbin/openvpn --config ${configFile}
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
# Services configs
|
||||
services = {
|
||||
openvpn = {
|
||||
servers = {
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
${namespace} = {
|
||||
headless.enable = false;
|
||||
|
||||
sops.enable = true;
|
||||
|
||||
bootloader.lanzaboote.enable = true;
|
||||
|
||||
desktop = {
|
||||
@@ -100,6 +102,7 @@
|
||||
"cosmic" = {
|
||||
configuration = {
|
||||
${namespace} = {
|
||||
sops.enable = true;
|
||||
desktop = {
|
||||
cosmic.enable = lib.mkForce true;
|
||||
hyprland = {
|
||||
|
||||
@@ -28,6 +28,13 @@ in
|
||||
# Secrets
|
||||
# ------------------------------
|
||||
secrets = {
|
||||
"matt_password" = {
|
||||
neededForUsers = true;
|
||||
mode = "0600";
|
||||
owner = config.users.users."${user}".name;
|
||||
group = config.users.users."${user}".group;
|
||||
};
|
||||
|
||||
"desktop/hass_token" = {
|
||||
sopsFile = desktopSopsFile;
|
||||
mode = "0777";
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
}:
|
||||
{
|
||||
${namespace} = {
|
||||
sops.enable = true;
|
||||
# ###################################################
|
||||
# # Boot # #
|
||||
# ###################################################
|
||||
|
||||
Reference in New Issue
Block a user