The other part of dotfiles

This commit is contained in:
Davide Pasetto 2024-06-27 15:31:12 +02:00
parent 2fbfed0e7a
commit 9f1ba4a64b
No known key found for this signature in database
GPG key ID: 8E7AB0CBE3149AF1
25 changed files with 1089 additions and 0 deletions

24
modules/audio.nix Normal file
View file

@ -0,0 +1,24 @@
{ lib, config, pkgs, ... }:
let
cfg = config.audio;
in
{
options.audio = {
enable = lib.mkEnableOption "Enable sound module";
};
config = lib.mkIf cfg.enable {
# Enable sound with pipewire.
services.pipewire = {
enable = true;
audio.enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
hardware.pulseaudio.enable = false;
};
}

View file

@ -0,0 +1,31 @@
{ lib, config, pkgs, ... }:
let
cfg = config.btrfsAutoscrub;
in
{
options.btrfsAutoscrub = {
enable = lib.mkEnableOption "Enable BTRFS Auto Scrub module";
interval = lib.mkOption {
default = "weekly";
type = config.services.btrfs.autoScrub.interval.type;
description = config.services.btrfs.autoScrub.interval.description;
};
fileSystems = lib.mkOption {
default = [ ];
type = config.services.btrfs.autoScrub.fileSystems.type;
description = config.services.btrfs.autoScrub.fileSystems.description;
};
};
config = lib.mkIf cfg.enable {
services.btrfs.autoScrub = {
enable = true;
interval = cfg.interval;
fileSystems = cfg.interval;
};
};
}

15
modules/default.nix Normal file
View file

@ -0,0 +1,15 @@
{
imports = [
# Folders
./desktop
./networking
./services
./virtualisation
# Files
./btrfs-autoscrub.nix
./main-user.nix
./audio.nix
];
}

View file

@ -0,0 +1,7 @@
{
imports = [
./gnome.nix
./plymouth.nix
./steam.nix
];
}

110
modules/desktop/gnome.nix Normal file
View file

@ -0,0 +1,110 @@
{ lib, config, pkgs, ... }:
let
cfg = config.gnome;
in
{
options.gnome = {
enable = lib.mkEnableOption "Enable Gnome and apply customization module";
keyboardLayout = lib.mkOption {
default = "it";
type = lib.types.str;
description = config.services.xserver.xkb.layout.description;
};
disableXTerm = lib.mkOption {
default = true;
type = lib.types.bool;
description = ''
Disable the default terminal. Xterm.
If disable don't forget to install one terminal!
'';
};
# extraExtension = lib.mkOption {
# default = [ ];
# description = ''
# Extra extensions to add without polluting the main module
# '';
# };
};
config = lib.mkIf cfg.enable {
services = {
xserver = {
enable = true;
xkb.layout = cfg.keyboardLayout;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
desktopManager.xterm.enable = !cfg.disableXTerm;
excludePackages = lib.mkIf cfg.disableXTerm [ pkgs.xterm ];
};
libinput.enable = true;
};
environment = {
systemPackages = with pkgs; [
dconf
dconf2nix
gnome-extension-manager
gnome.dconf-editor
gnome.gnome-tweaks
];
# Remove standard Gnome Packages
gnome.excludePackages = (with pkgs; [
gedit # text editor
gnome-photos
gnome-tour
gnome-connections
gnome-photos
]) ++ (with pkgs.gnome; [
atomix # puzzle game
cheese # webcam tool
epiphany # web browser
evince # document viewer
geary # email reader
gnome-calendar
gnome-characters
gnome-clocks
gnome-contacts
gnome-font-viewer
gnome-maps
gnome-music
gnome-terminal
gnome-weather
hitori # sudoku game
iagno # go game
tali # poker game
totem # video player
yelp # help viewer
]);
};
# gnome-extensions
# home.packages = with pkgs;
# lib.mkIf cfg.enableExtension
# [
# gnomeExtensions.blur-my-shell
# gnomeExtensions.caffeine
# gnomeExtensions.dash-to-dock
# gnomeExtensions.gsconnect
# gnomeExtensions.gtile
# gnomeExtensions.just-perfection
# gnomeExtensions.pano
# gnomeExtensions.quick-settings-tweaker
# gnomeExtensions.rounded-window-corners
# gnomeExtensions.tailscale-status
# gnomeExtensions.vitals
# ] ++ cfg.extraExtension;
};
}

View file

@ -0,0 +1,18 @@
{ lib, config, pkgs, ... }:
let
cfg = config.plymouth;
in
{
options.plymouth = {
enable = lib.mkEnableOption "Enable Plymouth and apply customization module";
};
config = lib.mkIf cfg.enable {
boot.plymouth = {
enable = true;
theme = "colorful_loop";
themePackages = [ (pkgs.adi1090x-plymouth-themes.override { selected_themes = [ "colorful_loop" ]; }) ];
};
};
}

18
modules/desktop/steam.nix Normal file
View file

@ -0,0 +1,18 @@
{ lib, config, pkgs, ... }:
let
cfg = config.steam;
in
{
options.steam = {
enable = lib.mkEnableOption "Enable Steam and apply customization module";
};
config = lib.mkIf cfg.enable {
programs.steam.enable = true;
# Necessary for Steam
hardware.opengl.driSupport32Bit = true;
};
}

2
modules/esphome.nix Normal file
View file

@ -0,0 +1,2 @@
# Aggiungere l'user al gruppo "dialout"
{ }

56
modules/main-user.nix Normal file
View file

@ -0,0 +1,56 @@
{ lib, config, pkgs, ... }:
let
cfg = config.mainUser;
in
{
options.mainUser = {
enable = lib.mkEnableOption "Enable user module";
userName = lib.mkOption {
default = "pazpi";
type = lib.types.str;
description = config.users.users."<name>".userName.description;
};
description = lib.mkOption {
default = "Davide Pasetto";
type = lib.types.str;
description = config.users.users."<name>".description;
};
hashedPassword = lib.mkOption {
default = "";
type = lib.types.str;
description = config.users.users."<name>".initialHashedPassword.description;
};
flatpak = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Enable the flatpak engine for the user
'';
};
};
config = lib.mkIf cfg.enable {
users.users.${cfg.userName} = {
description = cfg.description;
extraGroups = [ "users" "wheel" ];
initialHashedPassword = cfg.hashedPassword;
isNormalUser = true;
isSystemUser = false;
shell = pkgs.zsh;
uid = 1000;
packages = with pkgs; lib.mkIf cfg.flatpak [ flatpak gnome.gnome-software ];
};
console.keyMap = "it";
programs.zsh.enable = true;
};
}

View file

@ -0,0 +1,18 @@
{ lib, config, pkgs, ... }:
let
cfg = config.avahi;
in
{
options.avahi = {
enable = lib.mkEnableOption "Enable Avahi and apply customization module";
};
config = lib.mkIf cfg.enable {
services.avahi = {
enable = true;
nssmdns = true;
openFirewall = true;
};
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./avahi.nix
./tailscale.nix
];
}

View file

@ -0,0 +1,39 @@
{ lib, config, pkgs, ... }:
let
cfg = config.tailscale;
in
{
options.tailscale = {
enable = lib.mkEnableOption "Enable Tailscale module";
authKeyFile = lib.mkOption {
default = "";
type = config.services.tailscale.authKeyFile.type;
description = config.services.tailscale.authKeyFile.description;
};
exitNode = lib.mkOption {
default = "";
description = ''
The tailscale IP of the optional exit node.
'';
};
extraUpFlags = lib.mkOption {
default = "";
type = config.services.tailscale.extraUpFlags.type;
description = config.services.tailscale.extraUpFlags.description;
};
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
authKeyFile = cfg.authKeyFile;
useRoutingFeatures = if cfg.exitNode == "" then "none" else "both";
extraUpFlags = [ "--exit-node=${cfg.exitNode}" ] ++ cfg.extraUpFlags;
};
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./download-pod.nix
./nextcloud-podman.nix
];
}

View file

@ -0,0 +1,139 @@
{ lib, config, pkgs, ... }:
let
cfg = config.download-pod-old;
in
{
options.download-pod = {
enable = lib.mkEnableOption "Enable download services module";
proxy = {
enable = lib.mkEnableOption "Enable proxy for the services";
hostName = lib.mkOption {
default = "example.com";
type = lib.types.str;
description = ''
Top level hostname
'';
};
serverName = lib.mkOption {
default = "localhost";
type = lib.types.str;
description = ''
Server name where Caddy is
'';
};
};
dataDir = lib.mkOption {
default = "/mnt/data";
type = lib.types.str;
description = ''
Base download dir for stuff
'';
};
};
config = lib.mkIf cfg.enable
{
podman.enable = true;
systemd.services.pod-download = {
description = "Start podman 'download' pod";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
requiredBy = [
"podman-jackett.service"
"podman-radarr.service"
"podman-sabnzbd.service"
"podman-sonarr.service"
];
unitConfig = {
RequiresMountsFor = "/run/containers";
};
serviceConfig = {
Type = "oneshot";
ExecStart = "-${pkgs.podman}/bin/podman pod create -p 9117:9117 -p 7878:7878 -p 8080:8080 -p 8989:8989 download";
}; # -p 9117:9117 -p 7878:7878 -p 8080:8080 -p 8989:8989
#--share cgroup,ipc,uts
path = [ pkgs.podman ];
};
virtualisation.oci-containers.containers = {
jackett = {
image = "linuxserver/jackett";
autoStart = true;
user = "1000:100";
ports = [ "9117:9117" ];
extraOptions = [
"--init=true"
"--pod=download"
];
volumes = [ "jackett_config:/config" "${cfg.dataDir}:/data" ];
};
radarr = {
image = "linuxserver/radarr";
autoStart = true;
user = "1000:100";
ports = [ "7878:7878" ];
extraOptions = [
"--init=true"
"--pod=download"
];
volumes = [ "radarr_config:/config" "${cfg.dataDir}:/data" ];
};
sabnzbd = {
image = "linuxserver/sabnzbd";
autoStart = true;
user = "1000:100";
ports = [ "8080:8080" ];
extraOptions = [
"--init=true"
"--pod=download"
];
volumes = [ "sabnzbd_config:/config" "${cfg.dataDir}:/data" ];
};
sonarr = {
image = "linuxserver/sonarr";
autoStart = true;
user = "1000:100";
ports = [ "8989:8989" ];
extraOptions = [
"--init=true"
"--pod=download"
];
volumes = [ "sonarr_config:/config" "${cfg.dataDir}:/data" ];
};
};
services.caddy = lib.mkIf cfg.proxy.enable {
enable = true;
enableReload = false;
virtualHosts = {
"jackett.${cfg.proxy.hostName}".extraConfig = ''
reverse_proxy http://${cfg.proxy.serverName}:9117
'';
"radarr.${cfg.proxy.hostName}".extraConfig = ''
reverse_proxy http://${cfg.proxy.serverName}:7878
'';
"sabnzbd.${cfg.proxy.hostName}".extraConfig = ''
reverse_proxy http://${cfg.proxy.serverName}:8080
'';
"sonarr.${cfg.proxy.hostName}".extraConfig = ''
reverse_proxy http://${cfg.proxy.serverName}:8989
'';
};
};
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
let
cfg = config.download-pod;
in
{
options.download-pod = {
enable = lib.mkEnableOption "Enable the download searcher stack";
};
config = lib.mkIf cfg.enable {
oci-containers.pods.download = { };
};
}

View file

@ -0,0 +1,17 @@
{ lib, config, pkgs, ... }:
let
cfg = config.nextcloud-pd;
in
{
options.nextcloud-pd = {
enable = lib.mkEnableOption "Enable Nextcloud module";
};
config = lib.mkIf cfg.enable {
podman.enable = true;
virtualisation.oci-containers.containers = { };
};
}

View file

@ -0,0 +1,9 @@
{
imports = [
./docker.nix
./libvirtd.nix
./lxc.nix
./podman.nix
./oci-containers
];
}

View file

@ -0,0 +1,22 @@
{ lib, config, pkgs, ... }:
let
cfg = config.docker;
in
{
options.docker = {
enable = lib.mkEnableOption "Enable Docker module";
};
config = lib.mkIf cfg.enable {
virtualisation = {
docker = {
storageDriver = "btrfs";
rootless = {
enable = true;
setSocketVariable = true;
};
};
};
};
}

View file

@ -0,0 +1,16 @@
{ lib, config, pkgs, ... }:
let
cfg = config.libvirtd;
in
{
options.libvirtd = {
enable = lib.mkEnableOption "Enable libvirtd module";
};
config = lib.mkIf cfg.enable {
virtualisation.libvirtd.enable = true;
programs.virt-manager.enable = true;
users.users.${config.mainUser.userName}.extraGroups = [ "libvirtd" ];
};
}

View file

@ -0,0 +1,46 @@
{ lib, config, pkgs, ... }:
let
cfg = config.lxc;
in
{
options.lxc = {
enable = lib.mkEnableOption "Enable LXC module";
};
config = lib.mkIf cfg.enable {
virtualisation = {
# Enable LXC containers
lxd = {
enable = true;
# This turns on a few sysctl settings that the LXD documentation recommends
# for running in production.
recommendedSysctlSettings = true;
};
# This enables lxcfs, which is a FUSE fs that sets up some things so that
# things like /proc and cgroups work better in lxd containers.
# See https://linuxcontainers.org/lxcfs/introduction/ for more info.
#
# Also note that the lxcfs NixOS option says that in order to make use of
# lxcfs in the container, you need to include the following NixOS setting
# in the NixOS container guest configuration:
#
# virtualisation.lxc.defaultConfig = "lxc.include = ''${pkgs.lxcfs}/share/lxc/config/common.conf.d/00-lxcfs.conf";
lxc.lxcfs.enable = true;
};
# ip forwarding is needed for NAT'ing to work.
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
"net.ipv4.conf.default.forwarding" = true;
};
# kernel module for forwarding to work
boot.kernelModules = [ "nf_nat_ftp" ];
users.users.${config.mainUser.userName}.extraGroups = [ "lxd" ];
};
}

View file

@ -0,0 +1,122 @@
# ```admonish note title="To do"
# Run podman containers run as a non-root user.
# ```
#
# An abstraction over running containers as systemd units, enforcing some good
# practices:
#
# - Container DNS behaves the same under docker and podman.
# - Ports are exposed on `127.0.0.1`, rather than `0.0.0.0`.
# - Volumes are backed up by bind-mounts to the host filesystem.
#
# Switching between using docker or podman for the container runtime should be
# totally transparent.
#
# **Erase your darlings:** overrides the `volumeBaseDir`.
{ config, lib, pkgs, ... }:
with lib;
let
mkPortDef = { host, inner }: "127.0.0.1:${toString host}:${toString inner}";
mkVolumeDef = container: { name, host, inner }:
if host != null
then "${host}:${inner}"
else "${cfg.volumeBaseDir}/${container.volumeSubDir}/${name}:${inner}";
shouldPreStart = _name: container: container.pullOnStart;
mkPreStart = name: container: nameValuePair "${cfg.backend}-${name}" {
preStart = if container.pullOnStart then "${cfg.backend} pull ${container.image}" else "";
};
shouldNetworkService = _name: container: container.network != null;
mkNetworkService = _name: container:
let package = if cfg.backend == "docker" then pkgs.docker else pkgs.podman;
in nameValuePair "${cfg.backend}-net-${container.network}" {
description = "Manage the ${container.network} network for ${cfg.backend}";
preStart = "${package}/bin/${cfg.backend} network rm ${container.network} || true";
serviceConfig = {
Type = "oneshot";
ExecStart = "${package}/bin/${cfg.backend} network create -d bridge ${container.network}";
ExecStop = "${package}/bin/${cfg.backend} network rm ${container.network}";
RemainAfterExit = "yes";
};
};
mkPodService = name: pod:
let
package = if cfg.backend == "podman" then pkgs.podman else throw "mkPodService only supports podman";
aliases = map (cn: "${name}-${cn}") (attrNames pod.containers);
ports = concatLists (catAttrs "ports" (attrValues pod.containers));
in
nameValuePair "${cfg.backend}-pod-${name}" {
description = "Manage the ${name} pod for ${cfg.backend}";
preStart = "${package}/bin/${cfg.backend} pod rm --force --ignore ${name} || true";
serviceConfig = {
Type = "oneshot";
ExecStart =
let args = map (n: "--network-alias=${n}") aliases ++ map (pd: "-p ${mkPortDef pd}") ports;
in "${package}/bin/${cfg.backend} pod create ${concatStringsSep " " args} ${name}";
ExecStop = "${package}/bin/${cfg.backend} pod rm ${name}";
RemainAfterExit = "yes";
};
};
mkContainer = _name: container: with container;
let
hasNetwork = container.network != null;
hasPod = container.pod != null;
in
{
inherit autoStart cmd environment environmentFiles image login;
dependsOn =
container.dependsOn ++
(if hasNetwork then [ "net-${container.network}" ] else [ ]) ++
(if hasPod then [ "pod-${container.pod}" ] else [ ]);
extraOptions =
container.extraOptions ++
(if hasNetwork then [ "--network=${container.network}" ] else [ ]) ++
(if hasPod then [ "--pod=${container.pod}" ] else [ ]);
/* ports are defined at the pod level */
ports = if hasPod then [ ] else map mkPortDef ports;
volumes = map (mkVolumeDef container) volumes;
};
cfg = config.nixfiles.oci-containers;
allContainers =
let
mkPodContainer = podName: pod: containerName: container: nameValuePair "${podName}-${containerName}" (
container //
{
network = if cfg.backend == "docker" then podName else null;
pod = if cfg.backend == "docker" then null else podName;
volumeSubDir = pod.volumeSubDir;
}
);
in
concatMapAttrs (podName: pod: mapAttrs' (mkPodContainer podName pod) pod.containers) cfg.pods;
in
{
imports = [
./options.nix
];
config = {
virtualisation.${cfg.backend} = {
enable = true;
autoPrune.enable = true;
};
virtualisation.oci-containers = {
backend = cfg.backend;
containers = mapAttrs mkContainer allContainers;
};
systemd.services = mkMerge [
(mapAttrs' mkPreStart (filterAttrs shouldPreStart allContainers))
(mapAttrs' mkNetworkService (filterAttrs shouldNetworkService allContainers))
(if cfg.backend == "podman" then mapAttrs' mkPodService cfg.pods else { })
];
};
}

View file

@ -0,0 +1,207 @@
{ lib, ... }:
with lib;
let
portOptions = {
host = mkOption {
type = types.int;
description = mdDoc ''
Host port (on 127.0.0.1) to expose the container port on.
'';
};
inner = mkOption {
type = types.int;
description = mdDoc ''
The container port to expose to the hosti.
'';
};
};
volumeOptions = {
name = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Name of the volume. This is equivalent to:
```nix
host = "''${volumeBaseDir}/''${volumeSubDir}/''${name}";
```
This option c.logonflicts with `''${host}`.
'';
};
host = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Directory on the host to bind-mount into the container.
This option conflicts with `''${name}`.
'';
};
inner = mkOption {
type = types.str;
description = mdDoc ''
Directory in the container to mount the volume to.
'';
};
};
containerOptions = {
/* regular oci-containers */
autoStart = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Start the container automatically on boot.
'';
};
cmd = mkOption {
type = types.listOf types.str;
default = [ ];
description = mdDoc ''
Command-line arguments to pass to the container image's entrypoint.
'';
};
dependsOn = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "concourse-db" ];
description = mdDoc ''
Other containers that this one depends on, in `''${pod}-''${name}`
format.
'';
};
environment = mkOption {
type = types.attrsOf types.str;
default = { };
description = mdDoc ''
Environment variables to set for this container.
'';
};
environmentFiles = mkOption {
type = types.listOf types.path;
default = [ ];
description = mdDoc ''
List of environment files for this container.
'';
};
extraOptions = mkOption {
type = types.listOf types.str;
default = [ ];
description = mdDoc ''
Extra options to pass to `docker run` / `podman run`.
'';
};
image = mkOption {
type = types.str;
description = mdDoc ''
Container image to run.
'';
};
login = {
username = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Username for the container registry.
'';
};
passwordFile = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
File containing the password for the container registry.
'';
};
registry = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Container registry to authenticate with.
'';
};
};
/* changed */
ports = mkOption {
type = types.listOf (types.submodule { options = portOptions; });
default = [ ];
description = mdDoc ''
List of ports to expose.
'';
};
volumes = mkOption {
type = types.listOf (types.submodule { options = volumeOptions; });
default = [ ];
description = mdDoc ''
List of volume definitions.
'';
};
/* new options */
pullOnStart = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Pull the container image when starting (useful for `:latest` images).
'';
};
};
in
{
options.nixfiles.oci-containers = {
backend = mkOption {
type = types.enum [ "docker" "podman" ];
default = "docker";
description = mdDoc ''
The container runtime.
'';
};
pods = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
containers = mkOption {
type = types.attrsOf (types.submodule { options = containerOptions; });
default = { };
description = mdDoc ''
Attrset of container definitions.
'';
};
volumeSubDir = mkOption {
type = types.str;
default = name;
description = mdDoc ''
Subdirectory of the `''${volumeBaseDir}` to store bind-mounts
under.
'';
};
};
}));
default = { };
description = mdDoc ''
Attrset of pod definitions.
'';
};
volumeBaseDir = mkOption {
type = types.str;
description = mdDoc ''
Directory to store volume bind-mounts under.
'';
};
};
}

View file

@ -0,0 +1,29 @@
{ lib, config, pkgs, ... }:
let
cfg = config.podman;
in
{
options.podman = {
enable = lib.mkEnableOption "Enable Podman module";
};
config = lib.mkIf cfg.enable {
virtualisation.podman = {
enable = true;
# Depending on the host filesystem
# extraPackages = [ pkgs.zfs ];
};
# Depending on the host filesystem
# virtualisation.containers.storage.settings = {
# storage = {
# driver = "zfs";
# graphroot = "/var/lib/containers/storage";
# runroot = "/run/containers/storage";
# };
# };
};
}