forgejo good, nginx coming along

This commit is contained in:
Julian Sutter 2026-02-15 22:46:17 -08:00
parent 29eb6493be
commit 8fdbb33939
40 changed files with 153 additions and 493 deletions

0
.gitignore vendored Normal file → Executable file
View file

0
README.md Normal file → Executable file
View file

0
appflakes/immich/README.md Normal file → Executable file
View file

0
appflakes/immich/flake.lock generated Normal file → Executable file
View file

0
appflakes/immich/flake.nix Normal file → Executable file
View file

0
appflakes/octofriend/README.md Normal file → Executable file
View file

0
appflakes/octofriend/flake.lock generated Normal file → Executable file
View file

0
appflakes/octofriend/flake.nix Normal file → Executable file
View file

View file

@ -1 +0,0 @@
/nix/store/cmq4skpafnf055fyjmk8qxjhvbxl0xws-octofriend-git-6d9c260

0
desktop/3dprinting.nix Normal file → Executable file
View file

0
desktop/daw.nix Normal file → Executable file
View file

0
desktop/dev.nix Normal file → Executable file
View file

0
desktop/dnm.nix Normal file → Executable file
View file

0
desktop/gaming.nix Normal file → Executable file
View file

0
desktop/media.nix Normal file → Executable file
View file

0
desktop/office.nix Normal file → Executable file
View file

0
desktop/plasma.nix Normal file → Executable file
View file

0
desktop/stp-elc-udmshare.nix Normal file → Executable file
View file

0
desktop/tailscale.nix Normal file → Executable file
View file

0
desktop/virtualization.nix Normal file → Executable file
View file

0
docs/README-unstable and stable packages.md Normal file → Executable file
View file

0
docs/agents.md Normal file → Executable file
View file

82
flake.lock generated Normal file → Executable file
View file

@ -1,23 +1,5 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -85,54 +67,6 @@
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1765779637,
"narHash": "sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1306659b587dc277866c7b69eb97e5f07864d8c4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"octofriend": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2",
"octofriend": "octofriend_2"
},
"locked": {
"path": "./appflakes/octofriend",
"type": "path"
},
"original": {
"path": "./appflakes/octofriend",
"type": "path"
},
"parent": []
},
"octofriend_2": {
"flake": false,
"locked": {
"lastModified": 1766013652,
"narHash": "sha256-X7t2CGNZP+OS2pbMtRAg3XIGq3HA3N3rPk5ELV1FNRQ=",
"owner": "synthetic-lab",
"repo": "octofriend",
"rev": "6d9c260743e4b645fd4b216ce1cd979d5c0dd473",
"type": "github"
},
"original": {
"owner": "synthetic-lab",
"repo": "octofriend",
"type": "github"
}
},
"plasma-manager": { "plasma-manager": {
"inputs": { "inputs": {
"home-manager": [ "home-manager": [
@ -162,24 +96,8 @@
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"octofriend": "octofriend",
"plasma-manager": "plasma-manager" "plasma-manager": "plasma-manager"
} }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

8
flake.nix Normal file → Executable file
View file

@ -17,10 +17,9 @@
inputs.home-manager.follows = "home-manager"; inputs.home-manager.follows = "home-manager";
}; };
octofriend = { url = "path:./appflakes/octofriend"; };
}; };
outputs = { self, nixpkgs, nixpkgs-unstable, nixos-hardware, home-manager, plasma-manager, octofriend }: outputs = { self, nixpkgs, nixpkgs-unstable, nixos-hardware, home-manager, plasma-manager }:
let let
localSystem = { localSystem = {
system = "x86_64-linux"; system = "x86_64-linux";
@ -32,7 +31,6 @@
config.allowUnfree = true; config.allowUnfree = true;
}; };
inherit octofriend;
}; };
mkSystem = { modules, hardware ? [] }: nixpkgs.lib.nixosSystem { mkSystem = { modules, hardware ? [] }: nixpkgs.lib.nixosSystem {
@ -45,6 +43,7 @@
# Common desktop modules # Common desktop modules
commonDesktopModules = [ commonDesktopModules = [
./systems/common.nix ./systems/common.nix
./systems/desktop.nix
./users/jsutter.nix ./users/jsutter.nix
./desktop/plasma.nix ./desktop/plasma.nix
./desktop/dev.nix ./desktop/dev.nix
@ -78,7 +77,7 @@
modules = commonDesktopModules ++ [ modules = commonDesktopModules ++ [
./systems/labrizor.nix ./systems/labrizor.nix
./users/jsutter.nix ./users/jsutter.nix
./desktop/3dprinting.nix ./desktop/3dprinting.nix
]; ];
}; };
warp = mkSystem { warp = mkSystem {
@ -86,6 +85,7 @@
./systems/common.nix ./systems/common.nix
./users/jsutter.nix ./users/jsutter.nix
./systems/warp.nix ./systems/warp.nix
./servers/forgejo.nix
]; ];
}; };
}; };

0
servers/README.md Normal file → Executable file
View file

0
servers/common.nix Normal file → Executable file
View file

368
servers/forgejo.nix Normal file → Executable file
View file

@ -1,314 +1,92 @@
{ config, pkgs, lib, ... }: { lib, pkgs, config, ... }:
with lib;
let let
cfg = config.services.forgejo; cfg = config.services.forgejo;
in { srv = cfg.settings.server;
options.services.forgejo = {
enable = mkEnableOption "Forgejo Git server";
domain = mkOption { fqdn = "git.symbiotrip.com";
type = types.str;
example = "git.example.com";
description = "The domain name for Forgejo";
};
stateDir = mkOption { smtpPassword = "Monaco55";
type = types.str; runnerToken = "PUT_RUNNER_REGISTRATION_TOKEN_HERE";
default = "/var/lib/forgejo"; adminPassword = "2wiggyWah!";
description = "Directory for Forgejo data";
};
database = { adminUser = "jsutter";
createLocally = mkOption { adminEmail = "jsutter@symbiotrip.com";
type = types.bool;
default = true;
description = "Whether to create a local PostgreSQL database"; in
{
security.acme.certs.${fqdn}.group = config.services.nginx.group;
services.nginx.virtualHosts.${fqdn} = {
forceSSL = true;
enableACME = true;
useACMEHost = fqdn;
acmeRoot = null;
extraConfig = ''
client_max_body_size 512M;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
locations."/".proxyPass = "http://localhost:${toString srv.HTTP_PORT}";
};
services.forgejo = {
enable = true;
database.type = "postgres";
lfs.enable = true;
settings = {
server = {
DOMAIN = fqdn;
ROOT_URL = "https://${fqdn}/";
HTTP_PORT = 3000;
}; };
passwordFile = mkOption { service.DISABLE_REGISTRATION = true;
type = types.nullOr types.path;
default = null;
example = "/run/keys/forgejo-db";
description = "Path to file containing database password";
};
};
mailer = { actions = {
enable = mkOption { ENABLED = true;
type = types.bool; DEFAULT_ACTIONS_URL = "github";
default = false;
description = "Enable email notifications";
}; };
host = mkOption { mailer = {
type = types.str; ENABLED = true;
example = "smtp.gmail.com"; SMTP_ADDR = "mail.example.com";
description = "SMTP server hostname"; FROM = "noreply@${fqdn}";
}; USER = "noreply@${fqdn}";
PASSWD = smtpPassword;
port = mkOption {
type = types.port;
default = 587;
description = "SMTP server port";
};
from = mkOption {
type = types.str;
example = "git@example.com";
description = "Email sender address";
};
userFile = mkOption {
type = types.path;
example = "/run/keys/forgejo-smtp-user";
description = "Path to file containing SMTP username";
};
passwordFile = mkOption {
type = types.path;
example = "/run/keys/forgejo-smtp-pass";
description = "Path to file containing SMTP password";
};
};
oauth2 = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable OAuth2 authentication";
};
github = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable GitHub OAuth2 provider";
};
clientId = mkOption {
type = types.str;
description = "GitHub OAuth client ID";
};
clientSecret = mkOption {
type = types.path;
description = "Path to GitHub OAuth client secret";
};
};
};
lfs = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable Git LFS support";
};
storage = mkOption {
type = types.str;
default = "/var/lib/forgejo/lfs";
description = "Path to LFS storage";
};
};
backup = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable automated backups";
};
interval = mkOption {
type = types.str;
default = "daily";
description = "Backup interval (systemd timer format)";
};
retentionDays = mkOption {
type = types.int;
default = 7;
description = "Number of backups to keep";
};
backupDir = mkOption {
type = types.str;
default = "/var/backups/forgejo";
description = "Directory to store backups";
}; };
}; };
}; };
config = mkIf cfg.enable { # Create/ensure admin user
# PostgreSQL database systemd.services.forgejo.preStart = let
services.postgresql = mkIf cfg.database.createLocally { adminCmd = "${lib.getExe cfg.package} admin user";
in ''
${adminCmd} create \
--admin \
--username ${adminUser} \
--email "${adminEmail}" \
--password "${adminPassword}" \
--must-change-password=false || true
'';
# Actions runner (runs jobs in Docker containers per labels)
virtualisation.docker.enable = true;
services.gitea-actions-runner = {
package = pkgs.forgejo-runner;
instances.default = {
enable = true; enable = true;
enableTCPIP = false; name = "warp";
ensureDatabases = [ "forgejo" ]; url = "https://${fqdn}";
ensureUsers = [ token = runnerToken;
{ labels = [
name = "forgejo"; "node-22:docker://node:22-bookworm"
ensureDBOwnership = true; "nixos-latest:docker://nixos/nix"
} # "native:host"
]; ];
}; };
# Forgejo service
services.forgejo = {
enable = true;
settings = {
server = {
HTTP_PORT = 3000;
DOMAIN = cfg.domain;
ROOT_URL = "https://${cfg.domain}/";
DISABLE_SSH = false;
SSH_PORT = 22;
LFS_START_SERVER = cfg.lfs.enable;
LFS_CONTENT_PATH = cfg.lfs.storage;
};
database = {
DB_TYPE = "postgres";
HOST = "/run/postgresql";
NAME = "forgejo";
USER = "forgejo";
PASSWD = mkIf (cfg.database.passwordFile != null) "#dbpass#";
};
service = {
DISABLE_REGISTRATION = false;
REQUIRE_SIGNIN_VIEW = false;
ENABLE_NOTIFY_MAIL = cfg.mailer.enable;
};
mailer = mkIf cfg.mailer.enable {
ENABLED = true;
FROM = cfg.mailer.from;
SMTP_ADDR = cfg.mailer.host;
SMTP_PORT = toString cfg.mailer.port;
USER = "#smtpuser#";
PASSWD = "#smtppass#";
PROTOCOL = "smtps";
};
session = {
COOKIE_SECURE = true;
COOKIE_SAMESITE = "strict";
};
security = {
INSTALL_LOCK = true;
PASSWORD_CHECK_PWN = true;
PASSWORD_COMPLEXITY = "lower,digit"
};
};
};
# Set database password from file
systemd.services.forgejo = {
serviceConfig = mkMerge [
(mkIf (cfg.database.passwordFile != null) {
EnvironmentFile = cfg.database.passwordFile;
})
(mkIf cfg.mailer.enable {
EnvironmentFile = [ cfg.mailer.userFile cfg.mailer.passwordFile ];
})
];
};
# Nginx reverse proxy
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts.${cfg.domain} = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://localhost:3000";
# Proxy for WebSocket
locations."/" = {
proxyPass = "http://localhost:3000";
proxyWebsockets = true;
extraConfig = ''
proxy_buffering off;
proxy_read_timeout 86400;
'';
};
# Proxy for LFS
locations."/.git/info/lfs" = {
proxyPass = "http://localhost:3000";
extraConfig = ''
client_max_body_size 0;
'';
};
};
};
# Firewall
networking.firewall = {
allowedTCPPorts = [ 80 443 ];
allowedUDPPorts = [ 443 ];
};
# Backup service
systemd.services.forgejo-backup = mkIf cfg.backup.enable {
description = "Forgejo backup service";
serviceConfig = {
Type = "oneshot";
User = "forgejo";
Group = "forgejo";
WorkingDirectory = cfg.stateDir;
ExecStart = "${pkgs.forgejo}/bin/forgejo dump --type zip --file ${cfg.backup.backupDir}/forgejo-backup-%Y-%m-%d.zip";
};
};
systemd.timers.forgejo-backup = mkIf cfg.backup.enable {
description = "Forgejo backup timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.backup.interval;
Persistent = true;
};
};
# Backup cleanup
systemd.services.forgejo-backup-cleanup = mkIf cfg.backup.enable {
description = "Clean up old Forgejo backups";
serviceConfig = {
Type = "oneshot";
User = "root";
ExecStart = pkgs.writeShellScript "forgejo-backup-cleanup" ''
find ${cfg.backup.backupDir} -name "forgejo-backup-*.zip" -mtime +${toString cfg.backup.retentionDays} -delete
'';
};
};
systemd.timers.forgejo-backup-cleanup = mkIf cfg.backup.enable {
description = "Forgejo backup cleanup timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "weekly";
Persistent = true;
};
};
# Create backup directory
system.activationScripts.forgejo-backup-dir = ''
mkdir -p ${cfg.backup.backupDir}
chown forgejo:forgejo ${cfg.backup.backupDir}
chmod 750 ${cfg.backup.backupDir}
'';
# Add Forgejo to known services
environment.systemPackages = with pkgs; [
forgejo
];
}; };
} }

0
servers/hugo.nix Normal file → Executable file
View file

29
servers/nginx.nix Normal file
View file

@ -0,0 +1,29 @@
{ config, lib, pkgs, ... }:
let
# WARNING: this ends up world-readable in the Nix store if you inline it.
cloudflareEnv = pkgs.writeText "cloudflare-acme.env" ''
umnyPSYOr9U3m404_IBMl4PTOzg29nz_XzNEGw2v
'';
in
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
security.acme = {
acceptTerms = true;
# These defaults are inherited by security.acme.certs.* unless overridden. :contentReference[oaicite:0]{index=0}
defaults = {
email = "admin@symbiotrip.com";
dnsProvider = "cloudflare"; # :contentReference[oaicite:1]{index=1}
environmentFile = cloudflareEnv; # :contentReference[oaicite:2]{index=2}
};
};
}

0
systems/aurora.nix Normal file → Executable file
View file

22
systems/common.nix Normal file → Executable file
View file

@ -61,12 +61,6 @@
# Services # Services
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
services.openssh.enable = true; services.openssh.enable = true;
security.polkit.enable = true; security.polkit.enable = true;
programs.zsh.enable = true; programs.zsh.enable = true;
@ -103,7 +97,6 @@
python3 python3
pv pv
whois whois
kdePackages.xdg-desktop-portal-kde
fwupd fwupd
usbutils # lsusb usbutils # lsusb
pciutils # lspci pciutils # lspci
@ -113,23 +106,8 @@
nvme-cli nvme-cli
smartmontools smartmontools
ripgrep ripgrep
mesa-demos
]; ];
services.flatpak.enable = true;
fonts.packages = with pkgs; [
noto-fonts-color-emoji
noto-fonts-cjk-sans
liberation_ttf
fira-code
fira-code-symbols
mplus-outline-fonts.githubRelease
dina-font
proggyfonts
];
services.xserver.excludePackages = [ pkgs.xterm ];
documentation.nixos.enable = false; documentation.nixos.enable = false;
systemd.network.wait-online.enable = false; systemd.network.wait-online.enable = false;

29
systems/desktop.nix Executable file
View file

@ -0,0 +1,29 @@
{ config, pkgs, ... }:
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
environment.systemPackages = with pkgs; [
kdePackages.xdg-desktop-portal-kde
mesa-demos
];
services.flatpak.enable = true;
fonts.packages = with pkgs; [
noto-fonts-color-emoji
noto-fonts-cjk-sans
liberation_ttf
fira-code
fira-code-symbols
mplus-outline-fonts.githubRelease
dina-font
proggyfonts
];
services.xserver.excludePackages = [ pkgs.xterm ];
}

0
systems/framework.nix Normal file → Executable file
View file

0
systems/labrizor.nix Normal file → Executable file
View file

View file

@ -1,71 +0,0 @@
{ config, lib, pkgs, modulesPath, ... }: {
networking.hostName = "skip01";
# CPU Settings for 13th gen Intel Core i5
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Boot and kernel modules for Intel NUC
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ]; # No graphics drivers needed for headless
boot.kernelModules = [ "kvm-intel" ]; # Intel virtualization support
boot.extraModulePackages = [];
# Server-specific kernel parameters
boot.kernelParams = [
"intel_iommu=on" # Enable IOMMU for virtualization
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
# No graphics support needed for headless server
# Power management optimized for server use
powerManagement = {
enable = true;
cpuFreqGovernor = "ondemand";
};
# Thermal management
services.thermald.enable = true;
# Server-oriented settings
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = "no";
};
};
# Swap configuration (smaller for server use)
swapDevices = [
{
device = "/swapfile";
size = 8192; # 8GB swap for server workload
priority = 0;
}
];
# Enable hardware monitoring (CLI only)
hardware.sensor.iio.enable = true;
# Network performance tuning for server use
boot.kernel.sysctl = {
"net.core.rmem_max" = 134217728;
"net.core.wmem_max" = 134217728;
"net.ipv4.tcp_rmem" = "4096 65536 134217728";
"net.ipv4.tcp_wmem" = "4096 65536 134217728";
"net.core.netdev_max_backlog" = 5000;
};
# Disable unnecessary services for server use
services.xserver.enable = lib.mkForce false;
services.pipewire.enable = lib.mkForce false;
# Enable container support for future server services
virtualisation.docker.enable = true;
virtualisation.podman.enable = lib.mkDefault true;
}

36
systems/warp.nix Normal file → Executable file
View file

@ -1,32 +1,33 @@
{ config, lib, pkgs, modulesPath, ... }: { { config, lib, pkgs, modulesPath, ... }: {
networking.hostName = "warp"; networking.hostName = "warp";
# CPU Settings for 13th gen Intel Core fileSystems."/" =
{ device = "/dev/disk/by-partlabel/primary";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-partlabel/ESP";
fsType = "vfat";
};
# CPU Settings for 13th gen Intel Core i5
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Boot and kernel modules for Intel NUC # Boot and kernel modules for Intel NUC
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ]; boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ]; # No graphics drivers needed for headless
# File system configuration - placeholder for actual hardware boot.kernelModules = [ "kvm-intel" ]; # Intel virtualization support
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
boot.initrd.kernelModules = [];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = []; boot.extraModulePackages = [];
# Server-specific kernel parameters # Server-specific kernel parameters
boot.kernelParams = [ boot.kernelParams = [
"intel_iommu=on" "intel_iommu=on" # Enable IOMMU for virtualization
]; ];
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
# No graphics support needed for headless server
# Power management optimized for server use # Power management optimized for server use
powerManagement = { powerManagement = {
enable = true; enable = true;
@ -46,16 +47,16 @@
}; };
}; };
# Swap configuration # Swap configuration (smaller for server use)
swapDevices = [ swapDevices = [
{ {
device = "/swapfile"; device = "/swapfile";
size = 8192; size = 8192; # 8GB swap for server workload
priority = 0; priority = 0;
} }
]; ];
# Enable hardware monitoring # Enable hardware monitoring (CLI only)
hardware.sensor.iio.enable = true; hardware.sensor.iio.enable = true;
# Network performance tuning for server use # Network performance tuning for server use
@ -70,9 +71,8 @@
# Disable unnecessary services for server use # Disable unnecessary services for server use
services.xserver.enable = lib.mkForce false; services.xserver.enable = lib.mkForce false;
services.pipewire.enable = lib.mkForce false; services.pipewire.enable = lib.mkForce false;
services.flatpak.enable = lib.mkForce false;
# Enable container support for server services # Enable container support for future server services
virtualisation.docker.enable = true; virtualisation.docker.enable = true;
virtualisation.podman.enable = lib.mkDefault true; virtualisation.podman.enable = lib.mkDefault true;
} }

0
users/aksutter.nix Normal file → Executable file
View file

0
users/common-home.nix Normal file → Executable file
View file

0
users/isutter.nix Normal file → Executable file
View file

0
users/jsutter.nix Normal file → Executable file
View file