34 Commits

Author SHA1 Message Date
d1b805789b hyprland: add recommended env vars
All checks were successful
Check flake / build-amd64-linux (push) Successful in 3m13s
2025-03-16 22:38:59 +00:00
1001119829 hyprland: extract hypridle 2025-03-16 22:07:13 +00:00
aaa944fd33 hyprland: extract hyprpaper 2025-03-16 22:05:15 +00:00
ad6d6d4f15 hyprland: extract hyprlock 2025-03-16 22:03:35 +00:00
cd4b58ae90 hyprland: preload wallpaper 2025-03-16 21:58:54 +00:00
f7b7a65860 hyprland: add config
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m26s
2025-03-16 18:59:16 +00:00
050a93bc01 hyprland: enable NetworkManager
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m52s
2025-03-16 17:24:07 +00:00
c2659206a0 hyprland: re-add system module
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m35s
2025-03-16 17:20:00 +00:00
7bc95779e7 mutter: bump overlay
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m19s
2025-03-16 16:41:28 +00:00
8b099e335c nixvim: rename options to opts
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m36s
2025-03-16 16:19:49 +00:00
e64b4879c0 mail: don't rely on home-manager for password
All checks were successful
Check flake / build-amd64-linux (push) Successful in 4m29s
2025-03-16 16:12:19 +00:00
9f1baa4c1e eos: remove battery percentage
Some checks failed
Check flake / build-amd64-linux (push) Failing after 2m34s
2025-03-16 16:04:15 +00:00
635b5c8921 gnome: use osConfig
Some checks failed
Check flake / build-amd64-linux (push) Failing after 59s
2025-03-16 16:01:31 +00:00
63583d9375 home-manager: fix xdg config file definition
Some checks failed
Check flake / build-amd64-linux (push) Failing after 26s
2025-03-16 15:59:58 +00:00
c77a0e921a hyprland: move adw-gtk3 to user package
Some checks failed
Check flake / build-amd64-linux (push) Failing after 16s
2025-03-16 15:53:59 +00:00
befc31158c gnome: fix session variable definition 2025-03-16 15:53:42 +00:00
556010c860 flake.lock: Update
Some checks failed
Check flake / build-amd64-linux (push) Failing after 16s
Flake lock file updates:

• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/6607cf789e541e7873d40d3a8f7815ea92204f32?narHash=sha256-cPfs8qMccim2RBgtKGF%2Bx9IBCduRvd/N5F4nYpU0TVE%3D' (2025-03-13)
  → 'github:NixOS/nixpkgs/c80f6a7e10b39afcc1894e02ef785b1ad0b0d7e5?narHash=sha256-C7jVfohcGzdZRF6DO%2BybyG/sqpo1h6bZi9T56sxLy%2Bk%3D' (2025-03-15)
• Removed input 'plasma-manager'
• Removed input 'plasma-manager/home-manager'
• Removed input 'plasma-manager/nixpkgs'
2025-03-16 15:46:47 +00:00
ecbdfbaa7f treewide: use inputs instead of self 2025-03-16 15:45:04 +00:00
7cd825d938 hyprland: move from module to user config 2025-03-16 15:25:06 +00:00
2b76dbea66 kde: remove module 2025-03-16 15:25:06 +00:00
df0e6b2924 gnome: split home-manager config from module 2025-03-16 15:25:06 +00:00
4543939b17 treewide: remove redundant home-manager modules 2025-03-16 15:25:05 +00:00
85ecd4a72a thunderbird: move from module to user config 2025-03-16 15:25:05 +00:00
5d1f6aca74 firefox: move from module to user config 2025-03-16 15:25:05 +00:00
1f665646ea home-manager: init on all hosts 2025-03-16 15:25:05 +00:00
14b53c4321 zsh: global completion opt-out 2025-03-16 14:31:51 +00:00
d8e0e78728 pass: move from module to user config 2025-03-16 14:31:50 +00:00
7879fda102 neovim: move from module to user config 2025-03-16 14:31:50 +00:00
c1f28192a0 gpg: move from module to user config 2025-03-16 14:31:50 +00:00
d1c2adface git: move from module to user config 2025-03-16 14:31:50 +00:00
ab75776ebe zsh: move from module to user config 2025-03-16 13:51:58 +00:00
dba3b8944d programs/dev: remove modules 2025-03-16 13:39:22 +00:00
0d8b1e7a37 nix-serve: refactor 2025-03-16 12:45:25 +00:00
ee02393220 hyprland: add notification daemon 2025-03-16 11:40:22 +00:00
104 changed files with 1645 additions and 3403 deletions

View File

@@ -10,12 +10,10 @@ System and user configuration for NixOS-based systems.
| **Terminal:** | Ghostty |
## Provisioning a new host
> [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used
> for provisioning
Generate a new SSH host key in "$temp/etc/ssh" as per [this guide](https://nix-community.github.io/nixos-anywhere/howtos/secrets.html#example-decrypting-an-openssh-host-key-with-pass).
```
ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key
```
@@ -31,7 +29,6 @@ Create a new directory under `hosts/` with a system configuration and disk layou
Boot the NixOS installer (or any Linux distribution) on the target.
Then run:
```
nix run github:nix-community/nixos-anywhere -- \
--disk-encryption-keys /tmp/secret.key /tmp/secret.key \
@@ -43,19 +40,15 @@ nix run github:nix-community/nixos-anywhere -- \
### Post install
If backups are configured, you'll need to run:
```
borgmatic init --encryption repokey-blake2
```
then restart `borgmatic`.
To join the Tailscale network, run:
```
tailscale up --login-server https://headscale.vimium.net
```
then visit the URL, SSH onto `vps1` and run `headscale --user mesh nodes register --key <key>`.
The new node can optionally be given a friendly name with `headscale node rename -i <index> <hostname>`.

931
flake.lock generated

File diff suppressed because it is too large Load Diff

217
flake.nix
View File

@@ -2,176 +2,159 @@
description = "NixOS system configuration";
inputs = {
agenix = {
url = "github:ryantm/agenix";
inputs.home-manager.follows = "nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
agenix-rekey = {
url = "github:oddlama/agenix-rekey";
inputs.nixpkgs.follows = "nixpkgs";
inputs.pre-commit-hooks.follows = "pre-commit-hooks";
};
deploy-rs = {
url = "github:serokell/deploy-rs";
inputs.nixpkgs.follows = "nixpkgs";
};
devshell = {
url = "github:numtide/devshell";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "nixpkgs/nixos-24.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs";
agenix.url = "github:ryantm/agenix";
deploy-rs.url = "github:serokell/deploy-rs";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
url = "github:nix-community/home-manager/release-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland.url = "github:hyprwm/Hyprland";
hyprland-plugins = {
url = "github:hyprwm/hyprland-plugins";
inputs.hyprland.follows = "hyprland";
};
firefox-gnome-theme = {
url = "github:rafaelmardojai/firefox-gnome-theme";
flake = false;
};
flake-parts.url = "github:hercules-ci/flake-parts";
gitea-github-theme = {
url = "git+ssh://git@git.vimium.com/jordan/gitea-github-theme.git?ref=main";
flake = false;
};
impermanence.url = "github:nix-community/impermanence";
kvlibadwaita = {
url = "github:GabePoel/KvLibadwaita";
flake = false;
};
nixos-hardware.url = "github:NixOS/nixos-hardware";
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.05";
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs";
nixvim = {
url = "github:nix-community/nixvim/nixos-25.05";
url = "github:nix-community/nixvim/nixos-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-topology = {
url = "github:oddlama/nix-topology";
inputs.nixpkgs.follows = "nixpkgs";
inputs.pre-commit-hooks.follows = "pre-commit-hooks";
};
pre-commit-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
secrets = {
url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git";
flake = false;
};
thunderbird-gnome-theme = {
url = "github:rafaelmardojai/thunderbird-gnome-theme";
flake = false;
};
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs@{
nixpkgs,
flake-parts,
...
}:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
inputs.agenix-rekey.flakeModule
inputs.pre-commit-hooks.flakeModule
inputs.nix-topology.flakeModule
inputs.treefmt-nix.flakeModule
./nix/devshell.nix
./nix/hosts.nix
];
inputs@{ self, nixpkgs, ... }:
let
inherit (nixpkgs) lib;
flake = {
overlays = nixpkgs.lib.packagesFromDirectoryRecursive {
callPackage = path: overrides: import path;
directory = ./overlays;
domain = "mesh.vimium.net";
forEachSystem = lib.genAttrs [
"x86_64-linux"
"aarch64-linux"
];
mkDeployNode = hostName: {
hostname = "${hostName}.${domain}";
profiles.system = {
user = "root";
path =
inputs.deploy-rs.lib.${
self.nixosConfigurations.${hostName}.config.system.build.toplevel.system
}.activate.nixos
self.nixosConfigurations.${hostName};
};
};
in
{
overlays = lib.packagesFromDirectoryRecursive {
callPackage = path: overrides: import path;
directory = ./overlays;
};
systems = [
"aarch64-linux"
"x86_64-linux"
legacyPackages = forEachSystem (
system:
lib.packagesFromDirectoryRecursive {
callPackage = nixpkgs.legacyPackages.${system}.callPackage;
directory = ./pkgs;
}
);
nixosConfigurations = lib.pipe ./hosts [
builtins.readDir
(lib.filterAttrs (name: value: value == "directory"))
(lib.mapAttrs (
name: value:
lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [
{
networking = {
inherit domain;
hostName = name;
};
}
./hosts/${name}
];
}
))
];
perSystem =
{ pkgs, ... }:
{
formatter = pkgs.nixfmt-rfc-style;
legacyPackages = pkgs.lib.packagesFromDirectoryRecursive {
callPackage = pkgs.callPackage;
directory = ./pkgs;
};
pre-commit = {
settings = {
excludes = [ "pkgs/libcamera-rpi/libcamera-rpi-ipa-priv-key.pem" ];
hooks = {
check-case-conflicts.enable = true;
check-executables-have-shebangs.enable = true;
check-merge-conflicts.enable = true;
detect-private-keys.enable = true;
end-of-file-fixer.enable = true;
fix-byte-order-marker.enable = true;
mixed-line-endings.enable = true;
treefmt.enable = true;
trim-trailing-whitespace.enable = true;
};
};
};
treefmt = {
projectRootFile = "flake.nix";
programs = {
checks =
builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib
// (forEachSystem (system: {
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
check-case-conflicts.enable = true;
check-executables-have-shebangs.enable = true;
check-merge-conflicts.enable = true;
deadnix = {
enable = true;
no-lambda-arg = true;
settings = {
noLambdaArg = true;
};
};
mdformat.enable = true;
detect-private-keys.enable = true;
end-of-file-fixer.enable = true;
fix-byte-order-marker.enable = true;
mixed-line-endings.enable = true;
nixfmt-rfc-style.enable = true;
shellcheck.enable = true;
trim-trailing-whitespace.enable = true;
};
};
}));
formatter = forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
devShells = forEachSystem (system: {
default = nixpkgs.legacyPackages.${system}.mkShell {
inherit (self.checks.${system}.pre-commit-check) shellHook;
buildInputs = [
inputs.agenix.packages.${system}.agenix
inputs.deploy-rs.packages.${system}.deploy-rs
] ++ self.checks.${system}.pre-commit-check.enabledPackages;
};
});
deploy = {
magicRollback = true;
autoRollback = true;
sshUser = "root";
nodes = lib.genAttrs [
"mail"
# "pi"
# "skycam"
"vps1"
] mkDeployNode;
};
};
}

View File

@@ -1,41 +0,0 @@
# Artemis
## Overview
Couch gaming PC and media centre
## Specs
- CPU - AMD Ryzen 7 9800X3D @ 4.70GHz
- Chipset - AMD B850
- Memory - 64 GB DDR5
- Motherboard - ASUS ROG STRIX B850-I Gaming WiFi
- GPU - AMD Radeon 7900 XTX
- Case - MCPRUE Apollo S v4
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
WD Black SN850X | `/dev/nvme0n1p1` (EFI, 500 MiB, NixOS Boot) <br> `/dev/nvme0n1p2` (ZFS, 4 TiB, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
│ ├── nix
│ └── tmp
├── system
│ ├── root
│ └── var
└── user
└── home
```
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `artemis.mesh.vimium.net`.

View File

@@ -1,103 +0,0 @@
{
inputs,
config,
lib,
pkgs,
...
}:
let
inherit (lib)
getExe
mkForce
;
in
{
imports = [
inputs.disko.nixosModules.disko
./hardware-configuration.nix
./disko-config.nix
../desktop.nix
];
nixpkgs = {
hostPlatform = "x86_64-linux";
};
boot.loader = {
systemd-boot = {
enable = true;
graceful = true;
};
efi.canTouchEfiVariables = true;
};
networking = {
hostId = "4f9a2b7e";
networkmanager.enable = mkForce false;
};
services.openssh.settings.PermitRootLogin = mkForce "prohibit-password";
users = {
users = {
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
};
services.earlyoom = {
enable = true;
extraArgs = [
"-M"
"409600,307200"
]
++ (
if config.swapDevices.zramSwap.enable or false then
[
"-S"
"409600,307200"
]
else
[ ]
);
};
services.sunshine = {
enable = false;
package = pkgs.unstable.sunshine;
capSysAdmin = true;
};
environment = {
systemPackages = [ pkgs.wine ];
sessionVariables.WINE_BIN = getExe pkgs.wine;
};
modules = {
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://neafzrj7@neafzrj7.repo.borgbase.com/./repo";
};
};
system = {
wireless = {
enable = true;
interfaces = [ "wlp11s0" ];
};
desktop = {
gnome.enable = lib.mkForce false;
hyprland.enable = true;
};
};
};
system.stateVersion = "25.05";
}

View File

@@ -1,118 +0,0 @@
{ ... }:
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-WD_BLACK_SN850X_4000GB_25115L4A0708";
content = {
type = "gpt";
partitions = {
ESP = {
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "rpool";
};
};
};
};
};
};
zpool = {
rpool = {
type = "zpool";
options = {
ashift = "12";
};
rootFsOptions = {
canmount = "off";
mountpoint = "none";
dnodesize = "auto";
xattr = "sa";
};
postCreateHook = "zfs snapshot rpool@blank";
datasets = {
local = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"local/nix" = {
type = "zfs_fs";
mountpoint = "/nix";
options = {
atime = "off";
mountpoint = "legacy";
};
};
"local/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
system = {
type = "zfs_fs";
mountpoint = "/";
options = {
mountpoint = "legacy";
};
};
"system/var" = {
type = "zfs_fs";
mountpoint = "/var";
options = {
mountpoint = "legacy";
};
};
"system/var/tmp" = {
type = "zfs_fs";
mountpoint = "/var/tmp";
options = {
devices = "off";
mountpoint = "legacy";
};
};
"system/var/log" = {
type = "zfs_fs";
mountpoint = "/var/log";
options = {
compression = "on";
acltype = "posix";
mountpoint = "legacy";
};
};
user = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"user/home" = {
type = "zfs_fs";
mountpoint = "/home";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
};
};
};
};
}

View File

@@ -1,121 +0,0 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
let
inherit (lib)
getExe
mkDefault
mkOverride
;
in
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
# Inspired by: https://github.com/Jovian-Experiments/Jovian-NixOS
boot = {
binfmt.registrations."DOSWin" = {
wrapInterpreterInShell = false;
interpreter = getExe pkgs.wine;
recognitionType = "magic";
offset = 0;
magicOrExtension = "MZ";
};
initrd = {
availableKernelModules = [
"xhci_pci"
"ehci_pci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
kernelModules = [
"amdgpu"
];
supportedFilesystems = [ "zfs" ];
};
kernel.sysctl = {
"kernel.sched_cfs_bandwidth_slice_u" = mkDefault 3000;
"kernel.sched_latency_ns" = mkDefault 3000000;
"kernel.sched_min_granularity_ns" = mkDefault 300000;
"kernel.sched_wakeup_granularity_ns" = mkDefault 500000;
"kernel.sched_migration_cost_ns" = mkDefault 50000;
"kernel.sched_nr_migrate" = mkDefault 128;
"kernel.split_lock_mitigate" = mkDefault 0;
"net.ipv4.tcp_mtu_probing" = true;
"net.ipv4.tcp_fin_timeout" = mkDefault 5;
"vm.max_map_count" = mkOverride 999 2147483642;
};
kernelModules = [
"hid_nintendo"
"hid_playstation"
"kvm-amd"
"ntsync"
];
kernelParams = [
"log_buf_len=4M"
"amdgpu.lockup_timeout=5000,10000,10000,5000"
"ttm.pages_min=2097152"
"amdgpu.sched_hw_submission=4"
"audit=0"
];
kernelPackages = pkgs.linuxPackages_6_15;
supportedFilesystems = [ "ntfs" ];
};
hardware = {
bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
MultiProfile = "multiple";
FastConnectable = true;
# enable experimental LL privacy, experimental offload codecs
KernelExperimental = "15c0a148-c273-11ea-b3de-0242ac130004";
};
LE = {
ScanIntervalSuspend = 2240;
ScanWindowSuspend = 224;
};
};
};
graphics = {
enable32Bit = true;
extraPackages = [
pkgs.gamescope-wsi
pkgs.vk-hdr-layer
];
extraPackages32 = [ pkgs.pkgsi686Linux.gamescope-wsi ];
};
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
enableRedistributableFirmware = true;
};
powerManagement.cpuFreqGovernor = "schedutil";
services.udev.packages = [
(pkgs.writeTextFile {
name = "ntsync-udev-rules";
text = ''KERNEL=="ntsync", MODE="0660", TAG+="uaccess"'';
destination = "/etc/udev/rules.d/70-ntsync.rules";
})
];
services.pulseaudio.enable = false;
services.xserver.videoDrivers = [ "amdgpu" ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -1,28 +1,24 @@
# Atlas
## Overview
A general purpose mini computer used for web browsing and multimedia.
## Specs
- CPU - Intel Core i7-4790K @ 4.00GHz
- Chipset - Intel Z97
- Memory - 8 GB DDR3
- Motherboard - ASRock Z97M-ITX
- GPU - AMD Radeon R9 290X 4GB
- Case - SilverStone Sugo SG13
- NIC - Intel Gigabit I218-V, Broadcom BCM4360 802.11ac
* CPU - Intel Core i7-4790K @ 4.00GHz
* Chipset - Intel Z97
* Memory - 8 GB DDR3
* Motherboard - ASRock Z97M-ITX
* GPU - AMD Radeon R9 290X 4GB
* Case - SilverStone Sugo SG13
* NIC - Intel Gigabit I218-V, Broadcom BCM4360 802.11ac
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Samsung SSD 850 | `/dev/sda1` (NTFS, 500 GiB, Windows XP)
Samsung SSD 850 | `/dev/sdb1` (EFI, 500 MiB, NixOS Boot) <br> `/dev/sdb2` (ZFS, 500 GiB, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
@@ -38,6 +34,5 @@ rpool/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `atlas.mesh.vimium.net`.

View File

@@ -8,25 +8,17 @@
{
imports = [
inputs.agenix.nixosModules.age
inputs.home-manager.nixosModules.home-manager
inputs.home-manager.nixosModule
../modules/nixos
];
nixpkgs = {
config.allowUnfree = true;
overlays = [
inputs.agenix.overlays.default
(import ../overlays/default.nix)
(final: prev: {
unstable = import inputs.nixpkgs-unstable {
config = {
allowUnfree = true;
};
system = final.system;
};
})
];
};
nixpkgs.overlays = [
inputs.agenix.overlays.default
(import ../overlays/default.nix)
(final: prev: {
unstable = import inputs.nixpkgs-unstable { system = final.system; };
})
];
time.timeZone = "Europe/London";
@@ -76,7 +68,7 @@
'';
buildMachines = [
{
hostName = "10.0.1.235";
hostName = "10.0.1.79";
sshUser = "root";
system = "aarch64-linux";
maxJobs = 6;

View File

@@ -1,7 +1,4 @@
{
pkgs,
...
}:
{ pkgs, ... }:
{
imports = [
@@ -9,10 +6,14 @@
../users/jordan
];
nixpkgs.overlays = [
(import ../overlays/gnome.nix)
];
services.printing.enable = true;
services.openssh.startWhenNeeded = true;
services.pulseaudio.enable = false;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
@@ -46,6 +47,18 @@
systemd.services.NetworkManager-wait-online.enable = false;
fonts.packages = with pkgs; [
noto-fonts
(nerdfonts.override {
fonts = [
"BigBlueTerminal"
"ComicShannsMono"
"Terminus"
"UbuntuMono"
];
})
];
modules = {
system.desktop.gnome.enable = true;
services.tailscale.enable = true;

View File

@@ -1,22 +1,18 @@
# Eos
## Overview
ThinkPad X220 laptop.
## Specs
- CPU - Intel Core i5-2520M @ 3.20GHz
- Memory - 8 GB DDR3
* CPU - Intel Core i5-2520M @ 3.20GHz
* Memory - 8 GB DDR3
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
Solid | `/dev/sda1` (EFI, NixOS Boot) <br> `/dev/sda2` (ZFS, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
@@ -32,6 +28,5 @@ rpool/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `eos.mesh.vimium.net`.

View File

@@ -1,19 +1,16 @@
# Helios
## Overview
Dell OptiPlex 980 small form factor desktop.
## Specs
- CPU - Intel Core i7-860 @ 2.8GHz
- Chipset - Intel Q57 Express
- Memory - 8 GB DDR2
- GPU - AMD FirePro 2460
- NIC - Intel Gigabit 82578DM
* CPU - Intel Core i7-860 @ 2.8GHz
* Chipset - Intel Q57 Express
* Memory - 8 GB DDR2
* GPU - AMD FirePro 2460
* NIC - Intel Gigabit 82578DM
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
SanDisk Ultra II | `/dev/sda1` (ext2, 200 MiB, NixOS Boot) <br> `/dev/sda2` (ZFS, 480 GiB, NixOS Root)
@@ -22,7 +19,6 @@ SanDisk Ultra II | `/dev/sda1` (ext2, 200 MiB, NixOS Boot) <br> `/dev/sda2` (ZFS
> an MBR partition table.
#### ZFS pool layout
```
rpool/
├── local
@@ -38,6 +34,5 @@ rpool/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `192.168.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `helios.mesh.vimium.net`.

View File

@@ -1,12 +1,5 @@
{
pkgs,
lib,
...
}:
{ pkgs, ... }:
let
inherit (lib) mkForce;
in
{
imports = [
./hardware-configuration.nix
@@ -42,10 +35,6 @@ in
repoPath = "ssh://b9cjl9hq@b9cjl9hq.repo.borgbase.com/./repo";
};
};
system.desktop = {
gnome.enable = mkForce false;
hyprland.enable = true;
};
};
system.stateVersion = "22.11";

View File

@@ -28,8 +28,6 @@
supportedFilesystems = [ "zfs" ];
};
powerManagement.cpuFreqGovernor = "schedutil";
fileSystems."/" = {
device = "rpool/system/root";
fsType = "zfs";

View File

@@ -1,25 +1,21 @@
# Hypnos
## Overview
15-inch MacBook Pro 11,3 (Mid 2014).
## Specs
- CPU - Intel Core i7-4870HQ @ 2.50GHz
- Memory - 16 GB DDR3
- GPU - Intel Iris Pro 5200
- GPU - NVIDIA GeForce GT 750M
- NIC - Broadcom BCM43xx 802.11ac
* CPU - Intel Core i7-4870HQ @ 2.50GHz
* Memory - 16 GB DDR3
* GPU - Intel Iris Pro 5200
* GPU - NVIDIA GeForce GT 750M
* NIC - Broadcom BCM43xx 802.11ac
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Apple SSD SM0512F | `/dev/sda1` (EFI, 256 MiB, NixOS Boot) <br> `/dev/sda2` (ZFS, 500 GiB, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
@@ -35,6 +31,5 @@ rpool/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `hypnos.mesh.vimium.net`.

View File

@@ -16,6 +16,7 @@
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};

View File

@@ -1,25 +1,21 @@
# Library
## Overview
Media and public file server.
## Specs
- CPU - AMD Ryzen 5 5600G @ 3.90GHz
- Chipset - AMD B550
- Memory - 64 GB DDR4
- Motherboard - ASRock B550M Pro4
- Case - JMCD-12S4
* CPU - AMD Ryzen 5 5600G @ 3.90GHz
* Chipset - AMD B550
* Memory - 64 GB DDR4
* Motherboard - ASRock B550M Pro4
* Case - Fractal Design Node 804
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Samsung 970 Evo Plus | `/dev/nvme0n1p1` (EFI, 512 MiB, NixOS Boot) <br> `/dev/nvme0n1p2` (ZFS `rpool`, 200 GiB, NixOS Root)
Samsung 980 Evo | `/dev/nvme0n1p1` (EFI, 512 MiB, NixOS Boot) <br> `/dev/nvme0n1p2` (ZFS `rpool`, 200 GiB, NixOS Root)
#### ZFS datasets
```
rpool/
├── local
@@ -45,6 +41,5 @@ library/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind the `rpool` datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `library.mesh.vimium.net`.

View File

@@ -1,39 +0,0 @@
{
inputs,
config,
pkgs,
...
}:
{
age.secrets."files/services/open-webui/envfile" = {
file = "${inputs.secrets}/files/services/open-webui/envfile.age";
};
services.open-webui = {
enable = true;
package = pkgs.unstable.open-webui;
port = 8081;
environment =
let
clientId = "open-webui";
publicUrl = "https://chat.ai.vimium.com";
in
{
WEBUI_URL = publicUrl;
ENABLE_LOGIN_FORM = "False";
ENABLE_OAUTH_SIGNUP = "True";
ENABLE_OAUTH_ROLE_MANAGEMENT = "True";
OAUTH_CLIENT_ID = clientId;
OAUTH_PROVIDER_NAME = "Vimium";
OFFLINE_MODE = "True";
OPENID_PROVIDER_URL = "https://auth.vimium.com/oauth2/openid/${clientId}/.well-known/openid-configuration";
OPENID_REDIRECT_URI = "${publicUrl}/oauth/oidc/callback";
};
environmentFile = config.age.secrets."files/services/open-webui/envfile".path;
};
modules.services.borgmatic.directories = [
"/var/lib/private/open-webui"
];
}

View File

@@ -1,17 +1,8 @@
{
...
}:
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./ai.nix
./grafana.nix
./jellyfin.nix
./jellysearch.nix
./nginx.nix
./prometheus.nix
./tunnel.nix
../server.nix
];
@@ -20,10 +11,7 @@
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
zfs.extraPools = [
"downloads"
"library"
];
zfs.extraPools = [ "library" ];
};
networking = {
@@ -58,12 +46,147 @@
enable = true;
};
services.grafana = {
enable = true;
settings = {
server = {
domain = "library.mesh.vimium.net";
http_addr = "0.0.0.0";
http_port = 3000;
};
};
};
services.prometheus = {
enable = true;
port = 9001;
exporters = {
node = {
enable = true;
enabledCollectors = [ "systemd" ];
port = 9002;
};
zfs = {
enable = true;
port = 9003;
};
};
scrapeConfigs = [
{
job_name = "node";
static_configs = [
{
targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
"127.0.0.1:${toString config.services.prometheus.exporters.zfs.port}"
];
}
];
}
];
};
systemd.services.vps1-tunnel = {
enable = true;
description = "vps1.mesh.vimium.net SSH tunnel";
after = [
"network-online.target"
"jellyfin.service"
];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "simple";
ExecStart = pkgs.lib.mkForce ''
${pkgs.openssh}/bin/ssh \
-NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o TCPKeepAlive=no \
-i %h/.ssh/id_jellyfin \
-R localhost:8000:localhost:8000 \
jellyfin@vps1.mesh.vimium.net
'';
Restart = "always";
RestartSec = 20;
};
wantedBy = [ "default.target" ];
};
services.nginx =
let
proxyConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
in
{
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
virtualHosts = {
"library.mesh.vimium.net" = {
locations."/" = {
root = "/mnt/library";
extraConfig = ''
autoindex on;
'';
};
};
"jellyfin.vimium.com" = {
default = true;
listen = [
{
addr = "127.0.0.1";
port = 8000;
}
];
locations."/" = {
proxyPass = "http://localhost:8096";
extraConfig = proxyConfig;
};
locations."/metrics" = {
return = "404";
};
};
};
};
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
vaapiVdpau
];
};
users.users.jellyfin.extraGroups = [
"video"
"render"
];
services.jellyfin = {
enable = true;
package = pkgs.unstable.jellyfin;
cacheDir = "/var/cache/jellyfin";
dataDir = "/var/lib/jellyfin";
};
modules = {
podman.enable = true;
services = {
borgmatic = {
enable = true;
directories = [
config.services.jellyfin.dataDir
"/home/jordan"
];
repoPath = "ssh://b61758r4@b61758r4.repo.borgbase.com/./repo";

View File

@@ -1,16 +0,0 @@
{
...
}:
{
services.grafana = {
enable = true;
settings = {
server = {
domain = "library.mesh.vimium.net";
http_addr = "0.0.0.0";
http_port = 3000;
};
};
};
}

View File

@@ -1,30 +0,0 @@
{
config,
pkgs,
...
}:
{
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
vaapiVdpau
];
};
users.users.jellyfin.extraGroups = [
"video"
"render"
];
services.jellyfin = {
enable = true;
package = pkgs.unstable.jellyfin;
cacheDir = "/var/cache/jellyfin";
dataDir = "/var/lib/jellyfin";
};
modules.services.borgmatic.directories = [
config.services.jellyfin.dataDir
];
}

View File

@@ -1,58 +0,0 @@
{
inputs,
config,
pkgs,
...
}:
{
age.secrets."files/services/meilisearch/envfile" = {
file = "${inputs.secrets}/files/services/meilisearch/envfile.age";
};
services.meilisearch = {
enable = true;
package = pkgs.meilisearch;
masterKeyEnvironmentFile = config.age.secrets."files/services/meilisearch/envfile".path;
};
users.users.jellysearch = {
group = "jellysearch";
isSystemUser = true;
};
users.groups.jellysearch = { };
systemd.services.jellysearch = {
enable = true;
description = "JellySearch";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Restart = "on-failure";
ExecStart = "${pkgs.jellysearch}/bin/jellysearch";
StateDirectory = "jellysearch";
StateDirectoryMode = "0750";
WorkingDirectory = "/var/lib/jellysearch";
EnvironmentFile = config.age.secrets."files/services/meilisearch/envfile".path;
NoNewPrivileges = true;
SystemCallArchitectures = "native";
RestrictRealtime = true;
RestrictSUIDSGID = true;
ProtectHostname = true;
LockPersonality = true;
PrivateDevices = true;
PrivateUsers = true;
RemoveIPC = true;
};
environment = {
DOTNET_ENVIRONMENT = "Production";
INDEX_CRON = "0 0 0/2 ? * * *";
JELLYFIN_URL = "http://localhost:8096";
JELLYFIN_CONFIG_DIR = "${toString config.services.jellyfin.dataDir}";
MEILI_URL = "http://localhost:${toString config.services.meilisearch.listenPort}";
};
};
}

View File

@@ -1,85 +0,0 @@
{
pkgs,
...
}:
{
services.nginx =
let
proxyConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
in
{
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
virtualHosts = {
"library.mesh.vimium.net" = {
locations."/" = {
root = "/mnt/library";
extraConfig = ''
autoindex on;
'';
};
};
"chat.ai.vimium.com" = {
listen = [
{
addr = "127.0.0.1";
port = 8001;
}
];
locations."/" = {
proxyPass = "http://localhost:8081";
extraConfig = proxyConfig + ''
# Disable proxy buffering for better streaming response from models
proxy_buffering off;
# Increase max request size for large attachments and long audio messages
client_max_body_size 20M;
proxy_read_timeout 10m;
'';
};
};
"jellyfin.vimium.com" = {
default = true;
listen = [
{
addr = "127.0.0.1";
port = 8000;
}
];
locations."/" = {
extraConfig = ''
# Proxy JellySearch first
if ($arg_searchTerm) {
proxy_pass http://localhost:5000;
break;
}
proxy_pass http://localhost:8096;
''
+ proxyConfig
+ ''
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
'';
};
locations."/metrics" = {
return = "404";
};
};
};
};
}

View File

@@ -1,35 +0,0 @@
{
config,
...
}:
{
services.prometheus = {
enable = true;
port = 9001;
exporters = {
node = {
enable = true;
enabledCollectors = [ "systemd" ];
port = 9002;
};
zfs = {
enable = true;
port = 9003;
};
};
scrapeConfigs = [
{
job_name = "node";
static_configs = [
{
targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
"127.0.0.1:${toString config.services.prometheus.exporters.zfs.port}"
];
}
];
}
];
};
}

View File

@@ -1,33 +0,0 @@
{
pkgs,
...
}:
{
systemd.services.vps1-tunnel = {
enable = true;
description = "vps1.mesh.vimium.net SSH tunnel";
after = [
"network-online.target"
"jellyfin.service"
];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "simple";
ExecStart = pkgs.lib.mkForce ''
${pkgs.openssh}/bin/ssh \
-NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o TCPKeepAlive=no \
-i %h/.ssh/id_jellyfin \
-R localhost:8000:localhost:8000 \
-R localhost:8001:localhost:8001 \
jellyfin@vps1.mesh.vimium.net
'';
Restart = "always";
RestartSec = 20;
};
wantedBy = [ "default.target" ];
};
}

View File

@@ -1,21 +1,17 @@
# Mail server
## Overview
Mail server hosted in OVH.
## Specs
- CPU - ??
- Memory - ??
* CPU - ??
* Memory - ??
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
NVMe | `/dev/sda1` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `mail.mesh.vimium.net`.

View File

@@ -1,5 +1,6 @@
{
inputs,
lib,
...
}:
@@ -24,6 +25,18 @@
};
};
users = {
users = {
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
modules = {
services = {
borgmatic = {

View File

@@ -5,32 +5,25 @@
}:
let
sendingDomains = [
"jdholt.com"
"vimium.com"
];
receiveOnlyDomains = [
domains = [
"h0lt.com"
"jdholt.com"
"jordanholt.xyz"
"vimium.co"
"vimium.com"
"vimium.co.uk"
"vimium.info"
"vimium.net"
"vimium.org"
"vimium.xyz"
];
allDomains = sendingDomains ++ receiveOnlyDomains;
in
{
imports = [
inputs.nixos-mailserver.nixosModule
];
age.secrets = {
"files/services/postfix/sasl_passwd".file =
"${inputs.secrets}/files/services/postfix/sasl_passwd.age";
"passwords/users/jordan".file = "${inputs.secrets}/passwords/users/jordan.age";
};
age.secrets."passwords/users/jordan".file = "${inputs.secrets}/passwords/users/jordan.age";
services.roundcube = {
enable = true;
@@ -53,7 +46,7 @@ in
mailserver = {
enable = true;
fqdn = "mail.vimium.com";
domains = allDomains;
domains = domains;
indexDir = "/var/lib/dovecot/indices";
certificateDomains = [
@@ -67,22 +60,15 @@ in
loginAccounts = {
"jordan@vimium.com" = {
hashedPasswordFile = config.age.secrets."passwords/users/jordan".path;
aliases = map (domain: "@" + domain) sendingDomains;
catchAll = receiveOnlyDomains;
catchAll = domains;
};
};
};
services.postfix.config = {
relayhost = "[mail.smtp2go.com]:2525";
smtp_sasl_auth_enable = "yes";
smtp_sasl_password_maps = "texthash:${
config.age.secrets."files/services/postfix/sasl_passwd".path
}";
smtp_sasl_security_options = "noanonymous";
smtp_destination_concurrency_limit = "20";
header_size_limit = "4096000";
extraVirtualAliases = {
"hostmaster@vimium.com" = "jordan@vimium.com";
"postmaster@vimium.com" = "jordan@vimium.com";
"webmaster@vimium.com" = "jordan@vimium.com";
"abuse@vimium.com" = "jordan@vimium.com";
};
};
}

View File

@@ -1,26 +1,22 @@
# Odyssey
## Overview
Primary workstation.
## Specs
- CPU - AMD Ryzen 9 9950X3D @ 4.30GHz
- Chipset - AMD X870E
- Memory - 96 GB DDR5
- Motherboard - ASUS ProArt X870E-Creator WiFi
- GPU - NVIDIA RTX 3090
- Case - Thermaltake A500
* CPU - Intel Core i7-5930K @ 4.10GHz
* Chipset - Intel X99
* Memory - 64 GB DDR4
* Motherboard - ASUS X99-A
* GPU - NVIDIA RTX 3090
* Case - Thermaltake A500
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Samsung 980 Pro | `/dev/nvme0n1p1` (EFI, 512 MiB, NixOS Boot) <br> `/dev/nvme0n1p2` (ZFS, 2 TiB, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
@@ -36,6 +32,5 @@ rpool/
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `odyssey.mesh.vimium.net`.

View File

@@ -9,12 +9,14 @@
./hardware-configuration.nix
./gitea-runner.nix
./nix-serve.nix
./zonos-container.nix
../desktop.nix
];
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};
@@ -39,12 +41,11 @@
virtualisation = {
libvirtd.enable = true;
# https://github.com/NixOS/nixpkgs/issues/422385
# lxd.enable = true;
lxd.enable = true;
};
services.sunshine = {
enable = false;
enable = true;
package = pkgs.unstable.sunshine;
capSysAdmin = true;
};

View File

@@ -22,32 +22,22 @@
];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ];
kernelModules = [ "kvm-amd" ];
kernelPackages = pkgs.linuxPackages_6_12;
kernelModules = [ "kvm-intel" ];
kernelPackages = pkgs.linuxPackages;
supportedFilesystems = [ "ntfs" ];
binfmt.emulatedSystems = [ "aarch64-linux" ];
};
hardware = {
bluetooth = {
enable = true;
powerOnBoot = true;
};
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
graphics = {
extraPackages = [ pkgs.vk-hdr-layer ];
};
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = {
modesetting.enable = true;
open = true;
package = config.boot.kernelPackages.nvidiaPackages.beta;
powerManagement.enable = true;
nvidiaSettings = false;
};
};
powerManagement.cpuFreqGovernor = "schedutil";
services.xserver.videoDrivers = [ "nvidia" ];
fileSystems."/" = {

View File

@@ -0,0 +1,72 @@
# Auto-generated using compose2nix v0.3.2-pre.
{ pkgs, lib, ... }:
{
hardware.nvidia-container-toolkit.enable = true;
# Runtime
virtualisation.docker = {
enable = true;
# enableNvidia = true;
enableOnBoot = true;
autoPrune.enable = true;
daemon.settings.features.cdi = true;
rootless.enable = true;
rootless.daemon.settings.features.cdi = true;
};
virtualisation.oci-containers.backend = "docker";
# Containers
virtualisation.oci-containers.containers."zonos_container" = {
image = "compose2nix/zonos_container";
environment = {
"GRADIO_SHARE" = "False";
"NVIDIA_VISIBLE_DEVICES" = "0";
};
cmd = [
"python3"
"gradio_interface.py"
];
log-driver = "journald";
extraOptions = [
"--device=nvidia.com/gpu=0"
"--network=host"
];
};
systemd.services."docker-zonos_container" = {
serviceConfig = {
Restart = lib.mkOverride 90 "no";
};
partOf = [
"docker-compose-zonos-root.target"
];
wantedBy = [
"docker-compose-zonos-root.target"
];
};
# Builds
systemd.services."docker-build-zonos_container" = {
path = [
pkgs.docker
pkgs.git
];
serviceConfig = {
Type = "oneshot";
TimeoutSec = 900;
};
script = ''
cd /home/jordan/projects/jordan/Zonos
docker build -t compose2nix/zonos_container .
'';
};
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."docker-compose-zonos-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -1,23 +1,19 @@
# Pi
## Overview
Raspberry Pi 4
## Specs
- SoC - Broadcom BCM2711
- CPU - ARM Cortex-A72 @ 1.8 GHz
- Memory - 8 GB LPDDR4
* SoC - Broadcom BCM2711
* CPU - ARM Cortex-A72 @ 1.8 GHz
* Memory - 8 GB LPDDR4
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `pi.mesh.vimium.net`.

View File

@@ -9,7 +9,6 @@
inputs.nixos-hardware.nixosModules.raspberry-pi-4
./hardware-configuration.nix
./home-assistant
./snapcast.nix
../server.nix
];

View File

@@ -1,5 +1,6 @@
{
lib,
pkgs,
modulesPath,
...
}:
@@ -10,6 +11,44 @@
];
boot = {
kernelPackages =
let
version = "6.1.73";
tag = "stable_20240124";
srcHash = "sha256-P4ExzxWqZj+9FZr9U2tmh7rfs/3+iHEv0m74PCoXVuM=";
in
pkgs.linuxPackagesFor (
pkgs.linux_rpi4.override {
argsOverride = {
src = pkgs.fetchFromGitHub {
owner = "raspberrypi";
repo = "linux";
rev = tag;
hash = srcHash;
};
version = version;
modDirVersion = version;
structuredExtraConfig = { };
kernelPatches = [
{
name = "drm-rp1-depends-on-instead-of-select-MFD_RP1.patch";
patch = pkgs.fetchpatch {
url = "https://github.com/peat-psuwit/rpi-linux/commit/6de0bb51929cd3ad4fa27b2a421a2af12e6468f5.patch";
hash = "sha256-9pHcbgWTiztu48SBaLPVroUnxnXMKeCGt5vEo9V8WGw=";
};
}
{
name = "iommu-bcm2712-don-t-allow-building-as-module.patch";
patch = pkgs.fetchpatch {
url = "https://github.com/peat-psuwit/rpi-linux/commit/693a5e69bddbcbe1d1b796ebc7581c3597685b1b.patch";
hash = "sha256-8BYYQDM5By8cTk48ASYKJhGVQnZBIK4PXtV70UtfS+A=";
};
}
];
};
}
);
# Stop ZFS kernel being built
supportedFilesystems = lib.mkForce [
"btrfs"
@@ -30,6 +69,23 @@
(final: prev: {
makeModulesClosure = x: prev.makeModulesClosure (x // { allowMissing = true; });
})
(final: prev: {
raspberrypifw =
let
version = "1.20240529";
srcHash = "sha256-KsCo7ZG6vKstxRyFljZtbQvnDSqiAPdUza32xTY/tlA=";
in
pkgs.raspberrypifw.override {
argsOverride = {
src = prev.fetchFromGitHub {
owner = "raspberrypi";
repo = "firmware";
rev = "${version}";
hash = srcHash;
};
};
};
})
];
fileSystems = {

View File

@@ -63,6 +63,7 @@
};
media_player = [ ];
mobile_app = { };
onkyo = { };
open_meteo = { };
recorder = {
purge_keep_days = 365;

View File

@@ -1,43 +0,0 @@
{
pkgs,
...
}:
{
# Put all sinks in pipewire group
services.pipewire.systemWide = true;
services.avahi = {
enable = true;
nssmdns4 = true;
publish = {
enable = true;
domain = true;
addresses = true;
};
};
services.snapserver = {
enable = true;
streams = {
default = {
type = "file";
location = "/var/lib/snapserver/test.wav";
sampleFormat = "44100:16:2";
codec = "flac";
};
};
};
systemd.services.snapclient = {
wantedBy = [ "multi-user.target" ];
after = [ "pipewire.service" ];
requires = [ "pipewire.service" ];
description = "Snapcast client";
serviceConfig = {
ExecStart = "${pkgs.snapcast}/bin/snapclient -h 127.0.0.1 --player pulse --mixer hardware";
DynamicUser = true;
SupplementaryGroups = [ "pipewire" ];
};
};
}

View File

@@ -1,11 +1,7 @@
{
lib,
...
}:
let
inherit (lib) mkForce;
in
{
imports = [
./common.nix
@@ -33,16 +29,6 @@ in
# };
};
users = {
users = {
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
};
systemd = {
enableEmergencyMode = false;
@@ -50,6 +36,11 @@ in
AllowSuspend=no
AllowHibernation=no
'';
watchdog = {
runtimeTime = "20s";
rebootTime = "30s";
};
};
services.fail2ban = {
@@ -65,8 +56,6 @@ in
];
};
services.openssh.settings.PermitRootLogin = mkForce "prohibit-password";
modules.services.tailscale = {
enable = true;
restrictSSH = false;

View File

@@ -1,32 +1,26 @@
# Skycam
## Overview
Raspberry Pi 4-based webcam
## Specs
- SoC - Broadcom BCM2711
- CPU - ARM Cortex-A72 @ 1.8 GHz
- Memory - 8 GB LPDDR4
* SoC - Broadcom BCM2711
* CPU - ARM Cortex-A72 @ 1.8 GHz
* Memory - 8 GB LPDDR4
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `skycam.mesh.vimium.net`.
## Devices and connections
- Camera Module 3 with wide-angle lens
## Building
To generate a compressed SD card image for Skycam, run:
`nix build '.#nixosConfigurations.skycam.config.system.build.sdImage'`

View File

@@ -1,16 +1,78 @@
{
inputs,
config,
lib,
pkgs,
...
}:
{
imports = [
inputs.nixos-hardware.nixosModules.raspberry-pi-4
./hardware-configuration.nix
../server.nix
];
nixpkgs.hostPlatform = "aarch64-linux";
hardware = {
raspberry-pi."4" = {
apply-overlays-dtmerge.enable = true;
audio.enable = false;
xhci.enable = false;
};
deviceTree = {
enable = true;
filter = "*rpi-4-*.dtb";
# From https://github.com/Electrostasy/dots/blob/3b81723feece67610a252ce754912f6769f0cd34/hosts/phobos/klipper.nix#L43-L65
overlays =
let
mkCompatibleDtsFile =
dtbo:
let
drv =
pkgs.runCommand "fix-dts"
{
nativeBuildInputs = with pkgs; [
dtc
gnused
];
}
''
mkdir "$out"
dtc -I dtb -O dts ${dtbo} | sed -e 's/bcm2835/bcm2711/' > $out/overlay.dts
'';
in
"${drv}/overlay.dts";
inherit (config.boot.kernelPackages) kernel;
in
[
{
name = "imx708.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/imx708.dtbo";
}
{
name = "vc4-kms-v3d-pi4.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/vc4-kms-v3d-pi4.dtbo";
}
];
};
firmware = with pkgs; [
firmwareLinuxNonfree
];
};
services.udev.extraRules = ''
SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660"
KERNEL=="vcsm-cma", GROUP="video", MODE="0660"
SUBSYSTEM=="dma_heap", GROUP="video", MODE="0660"
'';
nixpkgs.overlays = [
(import ./../../overlays/libcamera.nix)
];
networking = {
hostId = "731d1660";
firewall = {
@@ -20,80 +82,45 @@
};
};
services.go2rtc =
let
rpicam-vid = "${pkgs.rpicam-apps}/bin/rpicam-vid";
in
{
enable = true;
settings = {
log.level = "debug";
streams.rpicam = "exec:${rpicam-vid} -v1 -t0 -o- --inline --flush=1 --width=4608 --height=2592 --framerate=1 --codec mjpeg --quality 90 --denoise=cdn_off --sharpness 1.25 --exposure long --gain 3";
};
};
systemd.services = {
daily-reboot = {
description = "Daily system reboot";
serviceConfig = {
Type = "oneshot";
ExecStart = "/run/current-system/sw/bin/reboot";
Restart = "no";
};
};
skycam-archiver =
let
snapshotScript = pkgs.writeShellScript "skycam-archiver" ''
${pkgs.lib.getExe pkgs.curl} -s -o "/var/lib/skycam-archiver/snapshot-$(date +%Y%m%d-%H%M%S).jpg" "http://skycam.mesh.vimium.net:1984/api/frame.jpeg?src=rpicam"
'';
in
{
description = "Capture skycam snapshot and save with timestamp";
serviceConfig = {
Type = "oneshot";
StateDirectory = "skycam-archiver";
ExecStart = "${snapshotScript}";
};
requires = [ "go2rtc.service" ];
after = [ "go2rtc.service" ];
};
};
systemd.timers = {
daily-reboot = {
description = "Timer for daily system reboot";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 03:00:00";
Persistent = false;
};
};
skycam-archiver = {
description = "Timer for capturing skycam snapshots every 30 minutes";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "5min";
OnUnitActiveSec = "30min";
Unit = "skycam-archiver.service";
};
};
};
modules.services.borgmatic = {
enable = true;
directories = [
"/var/lib/skycam-archiver"
users.users.root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
repoPath = "ssh://m94ekv2i@m94ekv2i.repo.borgbase.com/./repo";
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
systemd.services.ustreamer = {
enable = true;
description = "uStreamer service";
unitConfig = {
Type = "simple";
ConditionPathExists = "/sys/bus/i2c/drivers/imx708/10-001a/video4linux";
};
serviceConfig = {
ExecStart = ''
${pkgs.libcamera}/bin/libcamerify ${pkgs.unstable.ustreamer}/bin/ustreamer \
--host=0.0.0.0 \
--resolution=4608x2592
'';
DynamicUser = "yes";
SupplementaryGroups = [ "video" ];
Restart = "always";
RestartSec = 10;
};
wantedBy = [ "network-online.target" ];
confinement.mode = "chroot-only";
};
environment.systemPackages = with pkgs; [
camera-streamer
git
neovim
libcamera
libraspberrypi
raspberrypi-eeprom
rpicam-apps
v4l-utils
unstable.ustreamer
];
system.stateVersion = "24.05";

View File

@@ -1,29 +1,18 @@
{
inputs,
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
inputs.nixos-hardware.nixosModules.raspberry-pi-4
(modulesPath + "/installer/sd-card/sd-image-aarch64.nix")
];
boot = {
kernelPatches = [
{
name = "cache-ls-table-dmabuf";
patch = pkgs.fetchurl {
url = "https://github.com/raspberrypi/linux/pull/6429.patch";
sha256 = "sha256-fEd+SgnjQXjAm1UcZTkHHPafmVeK/IySdLzhKI7DbS0=";
};
}
];
kernelModules = [ "bcm2835-v4l2" ];
kernelParams = [
"cma=512M"
"panic=0"
];
supportedFilesystems = lib.mkForce [
@@ -34,61 +23,6 @@
tmp.cleanOnBoot = false;
};
hardware = {
raspberry-pi."4" = {
apply-overlays-dtmerge.enable = true;
audio.enable = false;
xhci.enable = false;
};
deviceTree = {
enable = true;
filter = "*rpi-4-*.dtb";
# From https://github.com/Electrostasy/dots/blob/3b81723feece67610a252ce754912f6769f0cd34/hosts/phobos/klipper.nix#L43-L65
overlays =
let
mkCompatibleDtsFile =
dtbo:
let
drv =
pkgs.runCommand "fix-dts"
{
nativeBuildInputs = with pkgs; [
dtc
gnused
];
}
''
mkdir "$out"
dtc -I dtb -O dts ${dtbo} | sed -e 's/bcm2835/bcm2711/' > $out/overlay.dts
'';
in
"${drv}/overlay.dts";
inherit (config.boot.kernelPackages) kernel;
in
[
{
name = "imx708.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/imx708.dtbo";
}
{
name = "vc4-kms-v3d-pi4.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/vc4-kms-v3d-pi4.dtbo";
}
];
};
firmware = with pkgs; [
firmwareLinuxNonfree
];
};
services.udev.extraRules = ''
SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660"
KERNEL=="vcsm-cma", GROUP="video", MODE="0660"
SUBSYSTEM=="dma_heap", GROUP="video", MODE="0660"
SUBSYSTEM=="dma_heap", KERNEL=="linux,cma", SYMLINK+="dma_heap/vidbuf_cached", OPTIONS+="link_priority=-50"
'';
nixpkgs.overlays = [
(final: super: {
makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; });

View File

@@ -1,21 +1,17 @@
# vps1
## Overview
VPS hosted in OVH.
## Specs
- CPU - ??
- Memory - ??
* CPU - ??
* Memory - ??
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
NVMe | `/dev/sda1` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `vps1.mesh.vimium.net`.

View File

@@ -40,25 +40,26 @@ in
};
};
age.secrets = {
"passwords/services/coturn/static-auth-secret" = {
file = "${inputs.secrets}/passwords/services/coturn/static-auth-secret.age";
owner = "turnserver";
group = "turnserver";
};
}
// (
if matrixIntegration then
{
"passwords/services/coturn/matrix-turn-config.yml" = {
file = "${inputs.secrets}/passwords/services/coturn/matrix-turn-config.yml.age";
owner = "matrix-synapse";
group = "matrix-synapse";
};
}
else
{ }
);
age.secrets =
{
"passwords/services/coturn/static-auth-secret" = {
file = "${inputs.secrets}/passwords/services/coturn/static-auth-secret.age";
owner = "turnserver";
group = "turnserver";
};
}
// (
if matrixIntegration then
{
"passwords/services/coturn/matrix-turn-config.yml" = {
file = "${inputs.secrets}/passwords/services/coturn/matrix-turn-config.yml.age";
owner = "matrix-synapse";
group = "matrix-synapse";
};
}
else
{ }
);
services.coturn = {
enable = true;

View File

@@ -1,4 +1,5 @@
{
lib,
...
}:
@@ -11,6 +12,7 @@
./kanidm.nix
./matrix.nix
./nginx.nix
./outline.nix
./photoprism.nix
../server.nix
];
@@ -39,12 +41,19 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaaS+KMAEAymZhIJGC4LK8aMhUzhpmloUgvP2cxeBH4 jellyfin"
];
};
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
groups = {
jellyfin = { };
};
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
modules = {
services = {
borgmatic = {

View File

@@ -26,7 +26,6 @@ in
origin = uri;
tls_chain = "${config.security.acme.certs.${domain}.directory}/full.pem";
tls_key = "${config.security.acme.certs.${domain}.directory}/key.pem";
version = "2";
};
};

View File

@@ -63,95 +63,96 @@ in
};
};
services.nginx.virtualHosts = {
"${matrixSubdomain}" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::1]";
port = 443;
ssl = true;
}
{
addr = "[::1]";
port = 80;
}
{
addr = "[::1]";
port = 8448;
ssl = true;
}
];
locations = {
"/" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
'';
services.nginx.virtualHosts =
{
"${matrixSubdomain}" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::1]";
port = 443;
ssl = true;
}
{
addr = "[::1]";
port = 80;
}
{
addr = "[::1]";
port = 8448;
ssl = true;
}
];
locations = {
"/" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
'';
};
"/_matrix" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 50M;
'';
};
"/_synapse/client".proxyPass = "http://localhost:8008";
};
"/_matrix" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 50M;
};
"${serverName}" =
let
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in
{
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown matrixServerConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown matrixClientConfig);
};
"/_synapse/client".proxyPass = "http://localhost:8008";
};
};
"${serverName}" =
let
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in
{
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown matrixServerConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown matrixClientConfig);
};
}
// (
if useElement then
{
"${elementSubdomain}" = {
forceSSL = true;
enableACME = true;
root = pkgs.unstable.element-web.override {
conf = {
default_server_config = matrixClientConfig;
brand = "Vimium Chat";
branding = {
auth_header_logo_url = "https://vimium.com/images/logo.svg";
auth_footer_links = [
{
"text" = "Vimium.com";
"url" = "https://vimium.com";
}
];
}
// (
if useElement then
{
"${elementSubdomain}" = {
forceSSL = true;
enableACME = true;
root = pkgs.unstable.element-web.override {
conf = {
default_server_config = matrixClientConfig;
brand = "Vimium Chat";
branding = {
auth_header_logo_url = "https://vimium.com/images/logo.svg";
auth_footer_links = [
{
"text" = "Vimium.com";
"url" = "https://vimium.com";
}
];
};
};
};
};
};
}
else
{ }
);
}
else
{ }
);
nixpkgs.config.permittedInsecurePackages = [
"jitsi-meet-1.0.8043"
@@ -175,25 +176,27 @@ in
);
services.postgresql = lib.mkIf usePostgresql {
ensureUsers = [
{
name = "matrix-synapse";
ensureUsers =
[
{
name = "matrix-synapse";
ensureDBOwnership = true;
}
]
++ (lib.optional bridges.signal {
name = "mautrix-signal";
ensureDBOwnership = true;
}
]
++ (lib.optional bridges.signal {
name = "mautrix-signal";
ensureDBOwnership = true;
})
++ (lib.optional bridges.whatsapp {
name = "mautrix-whatsapp";
ensureDBOwnership = true;
});
ensureDatabases = [
"matrix-synapse"
]
++ (lib.optional bridges.signal "mautrix-signal")
++ (lib.optional bridges.whatsapp "mautrix-whatsapp");
})
++ (lib.optional bridges.whatsapp {
name = "mautrix-whatsapp";
ensureDBOwnership = true;
});
ensureDatabases =
[
"matrix-synapse"
]
++ (lib.optional bridges.signal "mautrix-signal")
++ (lib.optional bridges.whatsapp "mautrix-whatsapp");
};
services.mautrix-signal = lib.mkIf bridges.signal {
@@ -213,7 +216,6 @@ in
};
mute_bridging = true;
};
}
// commonBridgeSettings "mautrix-whatsapp";
} // commonBridgeSettings "mautrix-whatsapp";
};
}

View File

@@ -82,125 +82,98 @@ in
maxSize = "100m";
};
};
virtualHosts = {
## Static sites
"chat.ai.vimium.com" = {
forceSSL = true;
enableACME = true;
extraConfig = nginxErrorPages + nginxEdgeHeaders;
locations."/" = {
proxyPass = "http://localhost:8001";
virtualHosts =
{
## Static sites
"jellyfin.vimium.com" = {
forceSSL = true;
enableACME = true;
extraConfig = nginxErrorPages + nginxEdgeHeaders;
locations."/" = {
proxyPass = "http://localhost:8000";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
};
"jdholt.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.jdholt.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/skycam/snapshot.jpg" = {
extraConfig = ''
set $backend "skycam.mesh.vimium.net:8080";
resolver 100.100.100.100;
proxy_pass http://$backend/snapshot;
proxy_cache skycam_cache;
proxy_cache_valid any 10s;
proxy_ignore_headers Cache-Control Expires Set-Cookie;
'';
};
locations."/".return = "301 https://vimium.com$request_uri";
};
"pki.vimium.com" = {
addSSL = true;
forceSSL = false;
enableACME = true;
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Disable proxy buffering for better streaming response from models
proxy_buffering off;
# Increase max request size for large attachments and long audio messages
client_max_body_size 20M;
proxy_read_timeout 10m;
${nginxErrorPages}
more_set_headers 'Server: Vimium';
'';
locations."/" = {
root = "/var/www/pki.vimium.com";
};
};
};
"jellyfin.vimium.com" = {
forceSSL = true;
enableACME = true;
extraConfig = nginxErrorPages + nginxEdgeHeaders;
locations."/" = {
proxyPass = "http://localhost:8000";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
"suhailhussain.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.suhailhussain.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/" = {
root = "/var/www/suhailhussain.com";
};
};
};
"jdholt.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.jdholt.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/skycam" = {
root = "/var/www/jdholt.com";
"vimium.com" = {
default = true;
forceSSL = true;
enableACME = true;
serverAliases = [ "www.vimium.com" ];
extraConfig =
nginxErrorPages
+ nginxEdgeHeaders
+ nginxStrictHeaders
+ ''
add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always;
'';
locations."/" = {
root = "/var/www/vimium.com";
};
};
locations."/skycam/snapshot.jpg" = {
extraConfig = ''
set $backend "skycam.mesh.vimium.net:1984";
resolver 100.100.100.100;
proxy_pass http://$backend/api/frame.jpeg?src=rpicam;
proxy_cache skycam_cache;
proxy_cache_valid any 10s;
proxy_ignore_headers Cache-Control Expires Set-Cookie;
'';
};
locations."/".return = "301 https://vimium.com$request_uri";
};
"pki.vimium.com" = {
addSSL = true;
forceSSL = false;
enableACME = true;
extraConfig = ''
${nginxErrorPages}
more_set_headers 'Server: Vimium';
'';
locations."/" = {
root = "/var/www/pki.vimium.com";
};
};
"suhailhussain.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.suhailhussain.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/" = {
root = "/var/www/suhailhussain.com";
};
};
"vimium.com" = {
default = true;
forceSSL = true;
enableACME = true;
serverAliases = [ "www.vimium.com" ];
extraConfig =
nginxErrorPages
+ nginxEdgeHeaders
+ nginxStrictHeaders
+ ''
add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always;
'';
locations."/" = {
root = "/var/www/vimium.com";
};
};
}
## Redirects
// (mkRedirect "h0lt.com" "jdholt.com")
// (mkRedirect "jordanholt.xyz" "jdholt.com")
// (mkRedirect "omnimagic.com" "vimium.com")
// (mkRedirect "omnimagic.net" "vimium.com")
// (mkRedirect "thelostlegend.com" "suhailhussain.com")
// (mkRedirect "vimium.co" "vimium.com")
// (mkRedirect "vimium.co.uk" "vimium.com")
// (mkRedirect "vimium.info" "vimium.com")
// (mkRedirect "vimium.net" "vimium.com")
// (mkRedirect "vimium.org" "vimium.com")
// (mkRedirect "vimium.xyz" "vimium.com");
}
## Redirects
// (mkRedirect "h0lt.com" "jdholt.com")
// (mkRedirect "jordanholt.xyz" "jdholt.com")
// (mkRedirect "omnimagic.com" "vimium.com")
// (mkRedirect "omnimagic.net" "vimium.com")
// (mkRedirect "thelostlegend.com" "suhailhussain.com")
// (mkRedirect "vimium.co" "vimium.com")
// (mkRedirect "vimium.co.uk" "vimium.com")
// (mkRedirect "vimium.info" "vimium.com")
// (mkRedirect "vimium.net" "vimium.com")
// (mkRedirect "vimium.org" "vimium.com")
// (mkRedirect "vimium.xyz" "vimium.com");
};
}

53
hosts/vps1/outline.nix Normal file
View File

@@ -0,0 +1,53 @@
{
inputs,
config,
...
}:
let
domain = "outline.vimium.com";
in
{
nixpkgs.config.allowUnfree = true;
services.nginx.virtualHosts = {
"${domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
'';
};
};
};
age.secrets."passwords/services/outline/oidc-client-secret" = {
file = "${inputs.secrets}/passwords/services/outline/oidc-client-secret.age";
owner = "outline";
group = "outline";
};
services.outline = {
enable = true;
forceHttps = false;
oidcAuthentication = {
clientId = "outline";
clientSecretFile = config.age.secrets."passwords/services/outline/oidc-client-secret".path;
displayName = "Vimium";
authUrl = "https://auth.vimium.com/ui/oauth2";
tokenUrl = "https://auth.vimium.com/oauth2/token";
userinfoUrl = "https://auth.vimium.com/oauth2/openid/outline/userinfo";
};
publicUrl = "https://${domain}";
storage.storageType = "local";
};
}

View File

@@ -1,31 +0,0 @@
{
inputs,
...
}:
{
imports = [
inputs.disko.nixosModules.disko
./hardware-configuration.nix
./disko-config.nix
../server.nix
];
nixpkgs = {
hostPlatform = "x86_64-linux";
};
networking = {
hostId = "60de4af8";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
modules.services.tailscale.isExitNode = true;
system.stateVersion = "25.05";
}

View File

@@ -1,55 +0,0 @@
{ lib, ... }:
{
disko.devices = {
disk.disk1 = {
device = lib.mkDefault "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "2M";
type = "EF02";
};
esp = {
name = "ESP";
size = "300M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "pool";
};
};
};
};
};
lvm_vg = {
pool = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
};
};
};
};
}

View File

@@ -1,29 +0,0 @@
{
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot = {
initrd = {
availableKernelModules = [
"ata_piix"
"uhci_hcd"
"xen_blkfront"
"vmw_pvscsi"
];
kernelModules = [ "nvme" ];
};
loader.grub = {
efiSupport = true;
efiInstallAsRemovable = true;
};
tmp.cleanOnBoot = true;
};
zramSwap.enable = true;
}

View File

@@ -7,6 +7,7 @@
./services/tailscale.nix
./system/desktop/gnome.nix
./system/desktop/hyprland.nix
./system/desktop/mimeapps.nix
./system/wireless.nix
];
}

View File

@@ -100,7 +100,7 @@ in
};
};
pipewire-pulse."40-upmix" = upmixConfig;
client."40-upmix" = upmixConfig;
client-rt."40-upmix" = upmixConfig;
};
};
}

View File

@@ -64,8 +64,7 @@ in
];
# Add `pg_dumpall` to unit environment
systemd.services.borgmatic.path =
if config.services.postgresql.enable then [ config.services.postgresql.package ] else [ ];
systemd.services.borgmatic.path = [ config.services.postgresql.package ];
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;

View File

@@ -17,14 +17,6 @@ in
default = false;
example = true;
};
isExitNode = lib.mkOption {
default = false;
example = true;
};
useExitNode = lib.mkOption {
default = false;
example = true;
};
restrictSSH = lib.mkOption {
default = true;
example = true;
@@ -45,8 +37,7 @@ in
extraUpFlags = [
"--login-server"
headscale
]
++ (if cfg.isExitNode then [ "--advertise-exit-node" ] else [ ]);
];
};
services.openssh.openFirewall = !cfg.restrictSSH;

View File

@@ -31,6 +31,7 @@ in
environment.systemPackages = with pkgs.unstable; [
adw-gtk3
adwaita-fonts
kdePackages.qtstyleplugin-kvantum
libsForQt5.qtstyleplugin-kvantum
morewaita-icon-theme
nautilus-python

View File

@@ -15,11 +15,13 @@ in
options.modules.system.desktop.hyprland.enable = mkEnableOption "hyprland";
config = mkIf cfg.enable {
services.displayManager.ly.enable = true;
networking.networkmanager.enable = true;
programs.hyprland = {
enable = true;
withUWSM = true;
# withUWSM = true;
};
};
}

View File

@@ -1,15 +1,24 @@
{
config,
lib,
...
}:
let
avApp = "mpv.desktop";
imageApp = "org.gnome.Loupe.desktop";
cfg = config.modules.system.desktop.mimeapps;
avApp = "io.github.celluloid_player.Celluloid.desktop";
imageApp = "org.gnome.eog.desktop";
in
{
xdg.mimeApps = {
enable = true;
defaultApplications = {
options.modules.system.desktop.mimeapps = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
xdg.mime.defaultApplications = {
# Audio/video
"audio/x-vorbis+ogg" = avApp;
"audio/3gpp" = avApp;

View File

@@ -1,24 +0,0 @@
{ inputs, ... }:
{
imports = [
inputs.devshell.flakeModule
];
perSystem =
{ config, pkgs, ... }:
{
devshells.default = {
commands = [
{
package = config.treefmt.build.wrapper;
help = "Format all files";
}
{
package = pkgs.deploy-rs;
name = "deploy";
help = "Deploy this nix-config to remote hosts";
}
];
};
};
}

View File

@@ -1,60 +0,0 @@
{
inputs,
...
}:
{
flake =
{ config, lib, ... }:
let
domain = "mesh.vimium.net";
mkDeployNode = hostName: {
hostname = "${hostName}.${domain}";
profiles.system = {
user = "root";
path =
inputs.deploy-rs.lib.${
config.nixosConfigurations.${hostName}.config.system.build.toplevel.system
}.activate.nixos
config.nixosConfigurations.${hostName};
};
};
in
{
nixosConfigurations = lib.pipe ../hosts [
builtins.readDir
(lib.filterAttrs (name: value: value == "directory"))
(lib.mapAttrs (
name: value:
inputs.nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [
{
networking = {
inherit domain;
hostName = name;
};
}
../hosts/${name}
];
}
))
];
deploy = {
magicRollback = true;
autoRollback = true;
sshUser = "root";
nodes = lib.genAttrs [
"artemis"
"mail"
"pi"
"skycam"
"vps1"
"vps2"
] mkDeployNode;
};
};
}

View File

@@ -0,0 +1,24 @@
From 625939e594ce255afa3fab3a40c3e524460e1f8b Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 10 Aug 2024 18:28:08 +0100
Subject: [PATCH] Ignore IPA signing
---
src/libcamera/ipa_manager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 6d5bbd05..43004175 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -295,7 +295,7 @@ bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
if (data.empty())
return false;
- bool valid = pubKey_.verify(data, ipa->signature());
+ bool valid = true;
LOG(IPAManager, Debug)
<< "IPA module " << ipa->path() << " signature is "
--
2.44.1

View File

@@ -0,0 +1,141 @@
From 57128bb78f56cadf9e2dcca5ba4d710c3bd478a7 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Mon, 5 Aug 2024 21:53:09 +0100
Subject: [PATCH] Remove relative config lookups
---
src/libcamera/ipa_manager.cpp | 16 ----------
src/libcamera/ipa_proxy.cpp | 48 ++----------------------------
src/libcamera/pipeline_handler.cpp | 21 ++-----------
3 files changed, 4 insertions(+), 81 deletions(-)
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index f4e0b633..6d5bbd05 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -131,22 +131,6 @@ IPAManager::IPAManager()
<< "No IPA found in '" << modulePaths << "'";
}
- /*
- * When libcamera is used before it is installed, load IPAs from the
- * same build directory as the libcamera library itself.
- */
- std::string root = utils::libcameraBuildPath();
- if (!root.empty()) {
- std::string ipaBuildPath = root + "src/ipa";
- constexpr int maxDepth = 2;
-
- LOG(IPAManager, Info)
- << "libcamera is not installed. Adding '"
- << ipaBuildPath << "' to the IPA search path";
-
- ipaCount += addDir(ipaBuildPath.c_str(), maxDepth);
- }
-
/* Finally try to load IPAs from the installed system path. */
ipaCount += addDir(IPA_MODULE_DIR);
diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp
index 69975d8f..cd9284a3 100644
--- a/src/libcamera/ipa_proxy.cpp
+++ b/src/libcamera/ipa_proxy.cpp
@@ -122,33 +122,11 @@ std::string IPAProxy::configurationFile(const std::string &name,
}
}
- std::string root = utils::libcameraSourcePath();
- if (!root.empty()) {
- /*
- * When libcamera is used before it is installed, load
- * configuration files from the source directory. The
- * configuration files are then located in the 'data'
- * subdirectory of the corresponding IPA module.
- */
- std::string ipaConfDir = root + "src/ipa/" + ipaName + "/data";
-
- LOG(IPAProxy, Info)
- << "libcamera is not installed. Loading IPA configuration from '"
- << ipaConfDir << "'";
-
- std::string confPath = ipaConfDir + "/" + name;
+ for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) {
+ std::string confPath = dir + "/" + ipaName + "/" + name;
ret = stat(confPath.c_str(), &statbuf);
if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
return confPath;
-
- } else {
- /* Else look in the system locations. */
- for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) {
- std::string confPath = dir + "/" + ipaName + "/" + name;
- ret = stat(confPath.c_str(), &statbuf);
- if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
- return confPath;
- }
}
if (fallbackName.empty()) {
@@ -197,28 +175,6 @@ std::string IPAProxy::resolvePath(const std::string &file) const
}
}
- /*
- * When libcamera is used before it is installed, load proxy workers
- * from the same build directory as the libcamera directory itself.
- * This requires identifying the path of the libcamera.so, and
- * referencing a relative path for the proxy workers from that point.
- */
- std::string root = utils::libcameraBuildPath();
- if (!root.empty()) {
- std::string ipaProxyDir = root + "src/libcamera/proxy/worker";
-
- LOG(IPAProxy, Info)
- << "libcamera is not installed. Loading proxy workers from '"
- << ipaProxyDir << "'";
-
- std::string proxyPath = ipaProxyDir + proxyFile;
- if (!access(proxyPath.c_str(), X_OK))
- return proxyPath;
-
- return std::string();
- }
-
- /* Else try finding the exec target from the install directory. */
std::string proxyPath = std::string(IPA_PROXY_DIR) + proxyFile;
if (!access(proxyPath.c_str(), X_OK))
return proxyPath;
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 5ea2ca78..fd8555ca 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -561,25 +561,8 @@ std::string PipelineHandler::configurationFile(const std::string &subdir,
struct stat statbuf;
int ret;
- std::string root = utils::libcameraSourcePath();
- if (!root.empty()) {
- /*
- * When libcamera is used before it is installed, load
- * configuration files from the source directory. The
- * configuration files are then located in the 'data'
- * subdirectory of the corresponding pipeline handler.
- */
- std::string confDir = root + "src/libcamera/pipeline/";
- confPath = confDir + subdir + "/data/" + name;
-
- LOG(Pipeline, Info)
- << "libcamera is not installed. Loading platform configuration file from '"
- << confPath << "'";
- } else {
- /* Else look in the system locations. */
- confPath = std::string(LIBCAMERA_DATA_DIR)
- + "/pipeline/" + subdir + '/' + name;
- }
+ confPath = std::string(LIBCAMERA_DATA_DIR)
+ + "/pipeline/" + subdir + '/' + name;
ret = stat(confPath.c_str(), &statbuf);
if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
--
2.44.1

21
overlays/gnome.nix Normal file
View File

@@ -0,0 +1,21 @@
final: prev: {
gvdb = prev.fetchgit {
url = "https://gitlab.gnome.org/GNOME/gvdb.git";
rev = "b54bc5da25127ef416858a3ad92e57159ff565b3"; # From gvdb_wrap
sha256 = "c56yOepnKPEYFcU1B1TrDl8ydU0JU+z6R8siAQP4d2A=";
};
mutter = prev.mutter.overrideAttrs (attrs: {
src = prev.fetchurl {
url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-47/mutter-triple-buffering-v4-47.tar.gz";
sha256 = "LoGAOCFopDT5+fV/6FffBzwlqK5XtozEGaOHTEXmkmg=";
};
postPatch = ''
mkdir -p subprojects/gvdb
cp -r ${final.gvdb}/* subprojects/gvdb/
${attrs.postPatch or ""}
'';
});
}

65
overlays/libcamera.nix Normal file
View File

@@ -0,0 +1,65 @@
final: prev: {
libpisp = final.stdenv.mkDerivation {
name = "libpisp";
version = "1.0.5";
src = final.fetchFromGitHub {
owner = "raspberrypi";
repo = "libpisp";
rev = "v1.0.5";
hash = "sha256-CHd44CH5dBcZuK+5fZtONZ8HE/lwGKwK5U0BYUK8gG4=";
};
nativeBuildInputs = with final; [
pkg-config
meson
ninja
];
buildInputs = with final; [
nlohmann_json
boost
];
BOOST_INCLUDEDIR = "${prev.lib.getDev final.boost}/include";
BOOST_LIBRARYDIR = "${prev.lib.getLib final.boost}/lib";
};
libcamera = prev.libcamera.overrideAttrs (old: {
src = final.fetchFromGitHub {
owner = "raspberrypi";
repo = "libcamera";
rev = "eb00c13d7c9f937732305d47af5b8ccf895e700f";
hash = "sha256-p0/inkHPRUkxSIsTmj7VI7sIaX7OXdqjMGZ31W7cnt4=";
};
postPatch = ''
patchShebangs utils/ src/py/
'';
patches = [
./0001-Remove-relative-config-lookups.patch
./0001-Ignore-IPA-signing.patch
];
buildInputs =
old.buildInputs
++ (with final; [
libpisp
libglibutil
]);
mesonFlags = old.mesonFlags ++ [
"--buildtype=release"
"-Dpipelines=rpi/vc4,rpi/pisp"
"-Dipas=rpi/vc4,rpi/pisp"
"-Dgstreamer=enabled"
"-Dtest=false"
"-Dcam=enabled"
"-Dpycamera=disabled"
];
});
camera-streamer = prev.callPackage ../pkgs/camera-streamer/package.nix {
libcamera = final.libcamera;
};
}

View File

@@ -1,28 +0,0 @@
{
stdenv,
fetchurl,
lib,
}:
stdenv.mkDerivation rec {
pname = "apple-color-emoji";
version = "18.4";
src = fetchurl {
url = "https://github.com/samuelngs/apple-emoji-linux/releases/download/v${version}/AppleColorEmoji.ttf";
hash = "sha256-pP0He9EUN7SUDYzwj0CE4e39SuNZ+SVz7FdmUviF6r0=";
};
dontUnpack = true;
installPhase = ''
install -Dm644 $src -t $out/share/fonts/truetype
'';
meta = {
description = "Apple Color Emoji for Linux";
longDescription = "Brings Apple's vibrant emojis to your Linux experience";
homepage = "https://github.com/samuelngs/apple-emoji-linux";
license = lib.licenses.unfree;
platforms = lib.platforms.unix;
};
}

View File

@@ -0,0 +1,24 @@
From 0f17bb86772afe9495891e420a809a0b3c071caf Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 10 Aug 2024 15:37:15 +0100
Subject: [PATCH] Disable libdatachannel
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index d5029bd..e50ba1a 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ USE_HW_H264 ?= 1
USE_FFMPEG ?= $(shell pkg-config libavutil libavformat libavcodec && echo 1)
USE_LIBCAMERA ?= $(shell pkg-config libcamera && echo 1)
USE_RTSP ?= $(shell pkg-config live555 && echo 1)
-USE_LIBDATACHANNEL ?= $(shell [ -e $(LIBDATACHANNEL_PATH)/CMakeLists.txt ] && echo 1)
+USE_LIBDATACHANNEL ?= 0
ifeq (1,$(DEBUG))
CFLAGS += -g
--
2.44.1

View File

@@ -0,0 +1,82 @@
{
stdenv,
fetchFromGitHub,
cmake,
gnumake,
pkg-config,
xxd,
v4l-utils,
nlohmann_json,
ffmpegSupport ? true,
ffmpeg,
libcameraSupport ? true,
libcamera,
rtspSupport ? false,
live555,
webrtcSupport ? false,
openssl,
lib,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "camera-streamer";
version = "0.2.8";
src = fetchFromGitHub {
owner = "ayufan";
repo = "camera-streamer";
rev = "refs/tags/v${finalAttrs.version}";
hash = "sha256-8vV8BMFoDeh22I1/qxk6zttJROaD/lrThBxXHZSPpT4=";
fetchSubmodules = true;
};
patches = [
./0001-Disable-libdatachannel.patch
];
# Second replacement fixes literal newline in generated version.h.
postPatch = ''
substituteInPlace Makefile \
--replace '/usr/local/bin' '/bin' \
--replace 'echo "#define' 'echo -e "#define'
'';
env.NIX_CFLAGS_COMPILE = builtins.toString [
"-Wno-error=stringop-overflow"
"-Wno-error=format"
"-Wno-format"
"-Wno-format-security"
"-Wno-error=unused-result"
];
nativeBuildInputs = [
cmake
gnumake
pkg-config
xxd
];
dontUseCmakeConfigure = true;
buildInputs =
[
nlohmann_json
v4l-utils
]
++ (lib.optional ffmpegSupport ffmpeg)
++ (lib.optional libcameraSupport libcamera)
++ (lib.optional rtspSupport live555)
++ (lib.optional webrtcSupport openssl);
installFlags = [ "DESTDIR=${builtins.placeholder "out"}" ];
preInstall = "mkdir -p $out/bin";
meta = with lib; {
description = "High-performance low-latency camera streamer for Raspberry Pi's";
website = "https://github.com/ayufan/camera-streamer";
license = licenses.gpl3Only;
};
})

View File

@@ -1,172 +0,0 @@
[
{
"pname": "MeiliSearch",
"version": "0.15.0",
"hash": "sha256-MM8Z8xc+AG0m+jNXAHSLhUB2egJC4lI+u6BDTVaOwzg="
},
{
"pname": "Microsoft.AspNetCore.OpenApi",
"version": "8.0.4",
"hash": "sha256-Y/UnyBlwraJjxDmEO3vsgB63GO1M7OXyIS10vL1Fs5A="
},
{
"pname": "Microsoft.Data.Sqlite",
"version": "8.0.6",
"hash": "sha256-t1g1cF4T26Np10H7opo/vCMTMNb9SS9pmLA9pSCUBp4="
},
{
"pname": "Microsoft.Data.Sqlite.Core",
"version": "8.0.6",
"hash": "sha256-MgUBbb0LDM1ixm8pBfBrSTVjNoGFn6NQMD36mirELmo="
},
{
"pname": "Microsoft.Extensions.ApiDescription.Server",
"version": "6.0.5",
"hash": "sha256-RJjBWz+UHxkQE2s7CeGYdTZ218mCufrxl0eBykZdIt4="
},
{
"pname": "Microsoft.Extensions.Logging.Abstractions",
"version": "2.1.1",
"hash": "sha256-TzbYgz4EemrYKHMvB9HWDkFmq0BkTetKPUwBpYHk9+k="
},
{
"pname": "Microsoft.IdentityModel.Abstractions",
"version": "7.4.0",
"hash": "sha256-rzTsvh5hDX7zk6wYzUKNg7lIQf38G/EeR6qUq/j3Eo0="
},
{
"pname": "Microsoft.IdentityModel.JsonWebTokens",
"version": "7.4.0",
"hash": "sha256-IeezkUkScumgLQZqq2Zu4YsyldIUA/XpTeONB2AtYDc="
},
{
"pname": "Microsoft.IdentityModel.Logging",
"version": "7.4.0",
"hash": "sha256-rudTpYcSlIlE1OX2LO3Qd6DAisqd5vsuX/Edu7rHIJs="
},
{
"pname": "Microsoft.IdentityModel.Tokens",
"version": "7.4.0",
"hash": "sha256-qVqVYxBy5p6Jerd1rfMUgApV7vcH54N4neS2x+N5zRQ="
},
{
"pname": "Microsoft.OpenApi",
"version": "1.2.3",
"hash": "sha256-OafkxXKnDmLZo5tjifjycax0n0F/OnWQTEZCntBMYR0="
},
{
"pname": "Microsoft.OpenApi",
"version": "1.4.3",
"hash": "sha256-vk47e78OwopXJx2LhDRbKFObqF3GShHfNHR2SzvbQeA="
},
{
"pname": "Microsoft.Win32.SystemEvents",
"version": "6.0.0",
"hash": "sha256-N9EVZbl5w1VnMywGXyaVWzT9lh84iaJ3aD48hIBk1zA="
},
{
"pname": "Quartz",
"version": "3.10.0",
"hash": "sha256-1sb+JKJdS01lScgVjcbDHxbXSpHeMn1Mqg/CQ8r+BKI="
},
{
"pname": "SQLitePCLRaw.bundle_e_sqlite3",
"version": "2.1.6",
"hash": "sha256-dZD/bZsYXjOu46ZH5Y/wgh0uhHOqIxC+S+0ecKhr718="
},
{
"pname": "SQLitePCLRaw.core",
"version": "2.1.6",
"hash": "sha256-RxWjm52PdmMV98dgDy0BCpF988+BssRZUgALLv7TH/E="
},
{
"pname": "SQLitePCLRaw.lib.e_sqlite3",
"version": "2.1.6",
"hash": "sha256-uHt5d+SFUkSd6WD7Tg0J3e8eVoxy/FM/t4PAkc9PJT0="
},
{
"pname": "SQLitePCLRaw.provider.e_sqlite3",
"version": "2.1.6",
"hash": "sha256-zHc/YZsd72eXlI8ba1tv58HZWUIiyjJaxq2CCP1hQe8="
},
{
"pname": "Swashbuckle.AspNetCore",
"version": "6.4.0",
"hash": "sha256-czuCv3Os7Oo06m3W+auJjrTGuYT82E+Bi80sJqeVb8o="
},
{
"pname": "Swashbuckle.AspNetCore.Swagger",
"version": "6.4.0",
"hash": "sha256-1u4A9vzDUJ+wLoxH5yQEVhpOxi+VnAMd64Z18SLqjPE="
},
{
"pname": "Swashbuckle.AspNetCore.SwaggerGen",
"version": "6.4.0",
"hash": "sha256-Alra5J+i0L/4JoS5pATJexVu8LId8HZcofkx7KiRqMw="
},
{
"pname": "Swashbuckle.AspNetCore.SwaggerUI",
"version": "6.4.0",
"hash": "sha256-P84wlE4EVruLVGGTUHK29wWYs/BTq/MR5P7PuSBwr+c="
},
{
"pname": "System.Configuration.ConfigurationManager",
"version": "6.0.1",
"hash": "sha256-U/0HyekAZK5ya2VNfGA1HeuQyJChoaqcoIv57xLpzLQ="
},
{
"pname": "System.Drawing.Common",
"version": "6.0.0",
"hash": "sha256-/9EaAbEeOjELRSMZaImS1O8FmUe8j4WuFUw1VOrPyAo="
},
{
"pname": "System.IdentityModel.Tokens.Jwt",
"version": "7.4.0",
"hash": "sha256-LYvdJPbPuxr8V3FJacStflSf9GVStprl1Wr+dfgqMdw="
},
{
"pname": "System.Memory",
"version": "4.5.3",
"hash": "sha256-Cvl7RbRbRu9qKzeRBWjavUkseT2jhZBUWV1SPipUWFk="
},
{
"pname": "System.Net.Http.Json",
"version": "6.0.0",
"hash": "sha256-R4s4Fb3OTKpg9gXSv+8CQ9gPJPJMmj3/nagzaRndm+g="
},
{
"pname": "System.Runtime.CompilerServices.Unsafe",
"version": "6.0.0",
"hash": "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I="
},
{
"pname": "System.Security.AccessControl",
"version": "6.0.0",
"hash": "sha256-qOyWEBbNr3EjyS+etFG8/zMbuPjA+O+di717JP9Cxyg="
},
{
"pname": "System.Security.Cryptography.ProtectedData",
"version": "6.0.0",
"hash": "sha256-Wi9I9NbZlpQDXgS7Kl06RIFxY/9674S7hKiYw5EabRY="
},
{
"pname": "System.Security.Permissions",
"version": "6.0.0",
"hash": "sha256-/MMvtFWGN/vOQfjXdOhet1gsnMgh6lh5DCHimVsnVEs="
},
{
"pname": "System.Text.Encodings.Web",
"version": "6.0.0",
"hash": "sha256-UemDHGFoQIG7ObQwRluhVf6AgtQikfHEoPLC6gbFyRo="
},
{
"pname": "System.Text.Json",
"version": "6.0.0",
"hash": "sha256-9AE/5ds4DqEfb0l+27fCBTSeYCdRWhxh2Bhg8IKvIuo="
},
{
"pname": "System.Windows.Extensions",
"version": "6.0.0",
"hash": "sha256-N+qg1E6FDJ9A9L50wmVt3xPQV8ZxlG1xeXgFuxO+yfM="
}
]

View File

@@ -1,36 +0,0 @@
{
lib,
fetchFromGitLab,
buildDotnetModule,
dotnetCorePackages,
}:
buildDotnetModule rec {
pname = "jellysearch";
version = "0.0.1";
src = fetchFromGitLab {
owner = "DomiStyle";
repo = "JellySearch";
rev = "7397e3f8c7daa6f0d30b22dda7c5159a913ca6b8";
hash = "sha256-7t0j4S5A9yvRN8zjToMNsxJ72OjU3j++EAqq9CKcPaI=";
};
patches = [
./patches/Only-listen-on-loopback-interface.patch
];
projectFile = "src/JellySearch/JellySearch.csproj";
executables = [ "jellysearch" ];
nugetDeps = ./nuget-deps.json;
dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.aspnetcore_8_0;
meta = with lib; {
description = "A fast full-text search proxy for Jellyfin";
homepage = "https://gitlab.com/DomiStyle/jellysearch";
license = licenses.mit;
mainProgram = "JellySearch";
platforms = dotnet-runtime.meta.platforms;
};
}

View File

@@ -1,24 +0,0 @@
From dede2b55ef53028b1347ccb731657a12d7fa3d15 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sun, 22 Jun 2025 17:16:56 +0100
Subject: [PATCH] Only listen on loopback interface
---
src/JellySearch/Program.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/JellySearch/Program.cs b/src/JellySearch/Program.cs
index a0c6ee1..98798f7 100644
--- a/src/JellySearch/Program.cs
+++ b/src/JellySearch/Program.cs
@@ -6,7 +6,7 @@ using Quartz.Impl;
var builder = WebApplication.CreateBuilder(args);
-builder.WebHost.UseUrls("http://0.0.0.0:5000"); // Listen on every IP
+builder.WebHost.UseUrls("http://127.0.0.1:5000"); // Listen on loopback only
builder.Services.AddCors(options =>
{
--
2.49.0

View File

@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCocmtyzPPjv+52
JiZrpZFfaZ0eeUgugc8gV+0+2Q9GEkl/xxqjiDVg31gBO3iwQov2NmGuPbXr+vwZ
QcUqNQakmmdi22tBaTtd6hMuhu9OfbP8sIFaf0dToZRHkPgf63+WCF6w0O9enEz4
zjW3kPa1eVRVekiYCXGML/VhN+h5WwWouNWgEOw5JH39ZuGmhsGN5XekkHtyMkwq
Vr+JodoSizhYs9VBYNA1J4PlyiS4BYr4pLiLffzPwRjcSS777x33g+nWNr1lsFxB
nDoVvVnq0E7fiXxlmCtAr/7dv0Ug5ixuNfZ9yoT0f+mfUiG/anmfodHujIm2Db37
jvmfxaq1AgMBAAECggEAFhJKBHSY92xod0g37A55fiZFTV8oZ1mgdXU386522yBd
y5Wf5rIcBmm1axHrFjNeCgClq3JQEk/kdP3Ccy2YBXzq04/7HYrHmd5oLYZGOINt
kExjYqN/SdTH7FmxPWN66AKIP8RcvQmfZ1GDxd4DiZNQitO3S96e53bIQPkVp8Lg
GfK6LQCdOGimD00wvRoeqbV0PWGGVMfx+KvD5hxKYolyi/hNUxToD28qCAoMlMTi
yL+17q3nIYZvUmL0k7d64U+lXF8ov3cVXNJzAzFi41MXZ2Xqk3Lj+IhNweUhlOyn
fTo8QntNlirNL/XmtJ+5mPbGufE/6zsSNOf2Cyz2aQKBgQDio/tA3tFBzOz31hox
gW6NKarhp7e5R3XHQjZPmQXKq2lGCTBN+LzwCLYDa+ZWkS+cel/xSbkUFl0dopCu
7uGrSvmVAv+l1k879WHsYmLlDjJSa8WmDtVQ0SJr70X9UJmD2BivWnTnzrpZFu2A
Nv57gvebJTI4tLfAAyIfbg8gOQKBgQC+RJRv8/jVha/4sPonQYvpH0scS0Xzwca6
xd23e+vULBpk7IVzMbVGJEDdfWXVJeAO++FSQcgTJA38nfYm2XRPZAProliLaW8o
XVhhhWbXP7Jc8BmL5zyfDaLOXNFBX2kfr/oKeOoQ+0dRDlWKlarw1SxC+RT6i2qQ
YETgXHKmXQKBgGk8mWsqy2HRZOtDqE/6eLnlciprtVy7+M14Sj21oUHVTAGwPJTH
/fs7IEEAdikWK1RuYmRoxh60r7IWDTadR35BRxjRFqILnCkMLNcVbDRN3kH1NwZ/
dr+bDG+v4ADazx2wVu39g7Erhc3eXpOddZcmXhDVObeo+nWXPt33PeDJAoGBAJ4v
+FVnuo8Tee1Cfogat87W5KSedIcnqSjpjt+Y2MXq8PrNplnSjwrE42UCd6KRvcnX
Ykr4Q/ad+D75uYgtLMVAuv2yWPl3bCJcETnrJkh5PbqFKEgntT/rn1sA0j0OrSDa
NwFz6+64a1+ZkkcJDjjykr0Px4BSXwOv9jOuyOdFAoGADZEADOLX5y4utxboe1M0
UnaFKGEDE6H8qdRJQ9bSvEwJI142al02CvnvqvP4cpd8rKOCRs9nSXFJFXCedTLy
ojSVfjTyJMTVJxab/c/Qugkxb/TqGfEnZF2yoTsfPYp2pXRd6DvyKlDQzlSOj933
FrqeSe1QKapuPRsujVwLZDU=
-----END PRIVATE KEY-----

View File

@@ -1,64 +0,0 @@
{
lib,
fetchFromGitHub,
libcamera,
boost,
nlohmann_json,
python3Packages,
git,
cacert,
meson,
}:
libcamera.overrideAttrs (old: {
buildInputs = old.buildInputs ++ [
boost
nlohmann_json
];
nativeBuildInputs = old.nativeBuildInputs ++ [ python3Packages.pybind11 ];
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
patches = [
./patches/libcamera-installed.patch
./patches/libcamera-no-timeout.patch
];
postPatch = old.postPatch + ''
patchShebangs src/py/libcamera
'';
preBuild = ''
ninja src/ipa-priv-key.pem
install -D ${./libcamera-rpi-ipa-priv-key.pem} src/ipa-priv-key.pem
'';
mesonFlags = old.mesonFlags ++ [
"--buildtype=release"
"-Dcam=disabled"
"-Dgstreamer=disabled"
"-Dipas=rpi/vc4,rpi/pisp"
"-Dpipelines=rpi/vc4,rpi/pisp"
"-Dtest=false"
];
src = fetchFromGitHub {
owner = "raspberrypi";
repo = "libcamera";
rev = "d83ff0a4ae4503bc56b7ed48cd142c3dd423ad3b";
sha256 = "sha256-VP0s1jOON9J3gn81aiemsChvGeqx0PPivQF5rmSga6M=";
nativeBuildInputs = [ git ];
postFetch = ''
cd "$out"
export NIX_SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
${lib.getExe meson} subprojects download \
libpisp
find subprojects -type d -name .git -prune -execdir rm -r {} +
'';
};
})

View File

@@ -1,53 +0,0 @@
From e65bbb6e263d99212cd29a32d89e4c45d0c05353 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 21 Jun 2025 18:38:38 +0100
Subject: [PATCH] libcamera installed
---
src/libcamera/source_paths.cpp | 9 ---------
src/py/libcamera/meson.build | 4 ++--
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/libcamera/source_paths.cpp b/src/libcamera/source_paths.cpp
index 1af5386a..3fc7d044 100644
--- a/src/libcamera/source_paths.cpp
+++ b/src/libcamera/source_paths.cpp
@@ -39,15 +39,6 @@ namespace {
*/
bool isLibcameraInstalled()
{
- /*
- * DT_RUNPATH (DT_RPATH when the linker uses old dtags) is removed on
- * install.
- */
- for (const ElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) {
- if (dyn->d_tag == DT_RUNPATH || dyn->d_tag == DT_RPATH)
- return false;
- }
-
return true;
}
diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index 596a203c..c0b1db59 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -34,14 +34,14 @@ gen_py_controls = files('gen-py-controls.py')
pycamera_sources += custom_target('py_gen_controls',
input : controls_files,
output : ['py_controls_generated.cpp'],
- command : [gen_py_controls, '--mode', 'controls', '-o', '@OUTPUT@',
+ command : ['python3', gen_py_controls, '--mode', 'controls', '-o', '@OUTPUT@',
'-t', gen_py_controls_template, '@INPUT@'],
env : py_build_env)
pycamera_sources += custom_target('py_gen_properties',
input : properties_files,
output : ['py_properties_generated.cpp'],
- command : [gen_py_controls, '--mode', 'properties', '-o', '@OUTPUT@',
+ command : ['python3', gen_py_controls, '--mode', 'properties', '-o', '@OUTPUT@',
'-t', gen_py_controls_template, '@INPUT@'],
env : py_build_env)
--
2.49.0

View File

@@ -1,29 +0,0 @@
From 98918c4efdcf03701908bb756f252ba11b59490b Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 21 Jun 2025 18:41:54 +0100
Subject: [PATCH] libcamera no timeout
---
src/libcamera/ipc_pipe_unixsocket.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp
index 668ec73b..faf7e2a5 100644
--- a/src/libcamera/ipc_pipe_unixsocket.cpp
+++ b/src/libcamera/ipc_pipe_unixsocket.cpp
@@ -130,11 +130,13 @@ int IPCPipeUnixSocket::call(const IPCUnixSocket::Payload &message,
/* \todo Make this less dangerous, see IPCPipe::sendSync() */
timeout.start(2000ms);
while (!iter->second.done) {
+ #if 0
if (!timeout.isRunning()) {
LOG(IPCPipe, Error) << "Call timeout!";
callData_.erase(iter);
return -ETIMEDOUT;
}
+ #endif
Thread::current()->eventDispatcher()->processEvents();
}
--
2.49.0

View File

@@ -1,68 +1,58 @@
{
stdenv,
callPackage,
fetchFromGitHub,
makeWrapper,
meson,
ninja,
pkg-config,
boost,
ffmpeg-headless,
ffmpeg,
libcamera,
libdrm,
libepoxy,
libexif,
libjpeg,
libpng,
libtiff,
libX11,
lib,
}:
let
libcamera-rpi = callPackage (import ../libcamera-rpi/package.nix) { };
in
stdenv.mkDerivation (finalAttrs: {
pname = "rpicam-apps";
version = "1.7.0";
version = "1.4.1";
src = fetchFromGitHub {
owner = "raspberrypi";
repo = "rpicam-apps";
rev = "v${finalAttrs.version}";
hash = "sha256-79qpAfY83YOZdM5ZPyIOkg3s7x75hvjG6Cc96UAIdb0=";
rev = "v" + finalAttrs.version;
hash = "sha256-3NG2ZE/Ub3lTbfne0LCXuDgLGTPaAAADRdElEbZwvls=";
};
buildInputs = [
boost
ffmpeg-headless
libcamera-rpi
libdrm
libepoxy # GLES/EGL preview window
libexif
libjpeg
libpng
libtiff
libX11
];
nativeBuildInputs = [
makeWrapper
meson
ninja
pkg-config
];
# See all options here: https://github.com/raspberrypi/rpicam-apps/blob/main/meson_options.txt
mesonFlags = [
"-Denable_drm=disabled"
"-Denable_egl=disabled"
"-Denable_hailo=disabled"
"-Denable_qt=disabled"
"-Denable_libav=disabled"
buildInputs = [
boost
ffmpeg
libcamera
libdrm
libexif
libjpeg
libpng
libtiff
];
postInstall = ''
for f in rpicam-hello rpicam-jpeg rpicam-raw rpicam-still rpicam-vid
do
wrapProgram $out/bin/$f --set-default LIBCAMERA_IPA_PROXY_PATH ${libcamera-rpi}/libexec/libcamera
done
'';
# Meson is no longer able to pick up Boost automatically:
# https://github.com/NixOS/nixpkgs/issues/86131
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
meta = with lib; {
description = ''
libcamera-based applications to drive the cameras on a Raspberry Pi platform
'';
homepage = "https://github.com/raspberrypi/rpicam-apps";
license = licenses.bsd2;
};
})

View File

@@ -1,20 +0,0 @@
{
stdenv,
fetchFromGitHub,
}:
stdenv.mkDerivation {
pname = "segoe-ui";
version = "unstable-2024-05-16";
src = fetchFromGitHub {
owner = "mrbvrz";
repo = "segoe-ui-linux";
rev = "a89213b7136da6dd5c3638db1f2c6e814c40fa84";
hash = "sha256-0KXfNu/J1/OUnj0jeQDnYgTdeAIHcV+M+vCPie6AZcU=";
};
installPhase = ''
mkdir -p $out/share/fonts/truetype
install -m644 $src/font/*.ttf $out/share/fonts/truetype/
'';
}

View File

@@ -1,29 +0,0 @@
{
stdenv,
fetchFromGitHub,
lib,
}:
stdenv.mkDerivation {
pname = "sf-pro";
version = "unstable-2021-06-22";
src = fetchFromGitHub {
owner = "sahibjotsaggu";
repo = "San-Francisco-Pro-Fonts";
rev = "8bfea09aa6f1139479f80358b2e1e5c6dc991a58";
sha256 = "sha256-mAXExj8n8gFHq19HfGy4UOJYKVGPYgarGd/04kUIqX4=";
};
installPhase = ''
mkdir -p $out/share/fonts/opentype
mkdir -p $out/share/fonts/truetype
install -m644 $src/*.otf $out/share/fonts/opentype/
install -m644 $src/*.ttf $out/share/fonts/truetype/
'';
meta = {
description = "San Francisco Pro fonts";
homepage = "https://github.com/sahibjotsaggu/San-Francisco-Pro-Fonts";
license = lib.licenses.unfree;
};
}

View File

@@ -0,0 +1,25 @@
From 18efb9b5c8e562b169425f6ba79977e52e8b91b9 Mon Sep 17 00:00:00 2001
From: Pavel Sobolev <paveloomm@gmail.com>
Date: Sat, 13 Jan 2024 12:49:45 +0000
Subject: [PATCH] Ensure the default config file is writable.
---
streamrip/config.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/streamrip/config.py b/streamrip/config.py
index 7ee2f57..88a5fef 100644
--- a/streamrip/config.py
+++ b/streamrip/config.py
@@ -378,6 +378,9 @@ def set_user_defaults(path: str, /):
"""Update the TOML file at the path with user-specific default values."""
shutil.copy(BLANK_CONFIG_PATH, path)
+ # Ensure the default config file is writable
+ os.chmod(path, 0o644)
+
with open(path) as f:
toml = parse(f.read())
toml["downloads"]["folder"] = DEFAULT_DOWNLOADS_FOLDER # type: ignore
--
2.42.0

View File

@@ -0,0 +1,78 @@
{
lib,
python3Packages,
fetchFromGitHub,
ffmpeg,
}:
python3Packages.buildPythonApplication {
pname = "streamrip";
version = "2.0.7";
pyproject = true;
src = fetchFromGitHub {
owner = "nathom";
repo = "streamrip";
rev = "46b570dbb6f81d604cbaa3bfa379463e0a20a841";
hash = "sha256-LD99OjguaBnrQxCwmCeHvmBMq5aOfobwnMd5/aCRZW8=";
};
patches = [
./ensure-the-default-config-file-is-writable.patch
];
nativeBuildInputs = with python3Packages; [
poetry-core
];
propagatedBuildInputs = with python3Packages; [
aiodns
aiofiles
aiohttp
aiolimiter
appdirs
cleo
click-help-colors
deezer-py
m3u8
mutagen
pathvalidate
pillow
pycryptodomex
pytest-asyncio
pytest-mock
rich
simple-term-menu
tomlkit
tqdm
];
nativeCheckInputs = with python3Packages; [
pytestCheckHook
];
prePatch = ''
sed -i 's#aiofiles = ".*"#aiofiles = "*"#' pyproject.toml
sed -i 's#deezer-py = ".*"#deezer-py = "*"#' pyproject.toml
sed -i 's#m3u8 = ".*"#m3u8 = "*"#' pyproject.toml
sed -i 's#pathvalidate = ".*"#pathvalidate = "*"#' pyproject.toml
sed -i 's#Pillow = ".*"#Pillow = "*"#' pyproject.toml
sed -i 's#pytest-asyncio = ".*"#pytest-asyncio = "*"#' pyproject.toml
sed -i 's#tomlkit = ".*"#tomlkit = "*"#' pyproject.toml
sed -i 's#"ffmpeg"#"${lib.getBin ffmpeg}/bin/ffmpeg"#g' streamrip/client/downloadable.py
'';
preCheck = ''
export HOME=$(mktemp -d)
'';
meta = with lib; {
description = "Scriptable music downloader for Qobuz, Tidal, SoundCloud, and Deezer";
homepage = "https://github.com/nathom/streamrip";
license = licenses.gpl3Only;
maintainers = with maintainers; [ paveloom ];
mainProgram = "rip";
};
}

View File

@@ -1,44 +0,0 @@
{
stdenv,
fetchFromGitHub,
lib,
meson,
ninja,
pkg-config,
vulkan-headers,
vulkan-loader,
wayland-scanner,
wayland,
xorg,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "vk-hdr-layer";
version = "303e0c69e1d33acd95158d92b1fc652fb5b85399";
src = fetchFromGitHub {
owner = "Zamundaaa";
repo = "VK_hdr_layer";
rev = "303e0c69e1d33acd95158d92b1fc652fb5b85399";
fetchSubmodules = true;
hash = "sha256-NsC44Ifl/fAHvFqP7NLrVZ71Y+x5mBEkv+r43HN5yn4=";
};
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
vulkan-headers
vulkan-loader
wayland
wayland-scanner
xorg.libX11
];
meta = {
description = "Vulkan layer utilizing a small color management / HDR protocol for experimentation";
homepage = "https://github.com/Zamundaaa/VK_hdr_layer";
license = lib.licenses.mit;
};
})

View File

@@ -1,20 +0,0 @@
{
pkgs,
...
}:
{
imports = [
./common/optional/graphical/firefox.nix
./common/optional/graphical/fonts.nix
./common/optional/graphical/hyprland
./common/optional/graphical/mimeapps.nix
];
home.packages = with pkgs; [
jellyfin-media-player
lutris
unstable.pcsx2
xemu
];
}

View File

@@ -1,16 +0,0 @@
{
pkgs,
...
}:
{
imports = [
./common/optional/graphical/firefox.nix
./common/optional/graphical/gnome.nix
];
home.packages = with pkgs; [
jellyfin-media-player
qbittorrent
];
}

View File

@@ -1,18 +0,0 @@
{
pkgs,
...
}:
{
home.packages = with pkgs; [
adwaita-fonts
apple-color-emoji
corefonts
nerd-fonts.bigblue-terminal
nerd-fonts.comic-shanns-mono
nerd-fonts.terminess-ttf
nerd-fonts.ubuntu-mono
sf-pro
vista-fonts
];
}

View File

@@ -1,15 +0,0 @@
* {
font-family: sans-serif;
}
window#waybar {
border-radius: 1em;
}
.modules-left {
margin-left: 10px;
}
.modules-right {
margin-right: 10px;
}

View File

@@ -1,54 +0,0 @@
{
...
}:
{
programs.waybar = {
enable = true;
settings = [
{
layer = "top";
position = "top";
height = 30;
margin = "10 20 0 20";
spacing = 10;
modules-left = [
"hyprland/workspaces"
];
modules-center = [
"hyprland/window"
];
modules-right = [
"disk"
"cpu"
"memory"
"privacy"
"clock"
];
clock = {
format = "{:%I:%M %p}";
};
disk = {
format = "{free}";
path = "/";
};
privacy = {
modules = [
{
type = "screenshare";
}
{
type = "audio-in";
}
];
};
}
];
style = ./waybar.css;
systemd.enable = true;
};
}

View File

@@ -1,13 +0,0 @@
{
pkgs,
...
}:
{
home.packages = with pkgs; [
hunspell
hunspellDicts.en-gb-large
hunspellDicts.en-us-large
libreoffice
];
}

View File

@@ -1,12 +0,0 @@
{
...
}:
{
services.ssh-agent.enable = true;
programs.ssh = {
enable = true;
addKeysToAgent = "yes";
};
}

View File

@@ -1,16 +1,11 @@
{
inputs,
lib,
config,
pkgs,
...
}:
let
inherit (lib)
optional
;
name = "jordan";
hostFile = ./. + "/${config.networking.hostName}.nix";
in
{
age.secrets."passwords/users/jordan".file = "${inputs.secrets}/passwords/users/jordan.age";
@@ -36,14 +31,13 @@ in
home-manager.users.${name} = {
imports = [
./common/git.nix
./common/gpg.nix
./common/neovim.nix
./common/pass.nix
./common/shell.nix
./common/ssh.nix
]
++ optional (builtins.pathExists hostFile) hostFile;
./git.nix
./gpg.nix
./graphical
./neovim.nix
./pass.nix
./shell.nix
];
home = {
username = name;
@@ -51,9 +45,4 @@ in
xdg.enable = true;
};
# Workaround: https://github.com/nix-community/home-manager/issues/7166
systemd.services."home-manager-${name}".serviceConfig = {
RemainAfterExit = "yes";
};
}

View File

@@ -0,0 +1,39 @@
{
lib,
pkgs,
osConfig,
...
}:
{
imports =
[
./firefox.nix
./thunderbird.nix
]
++ lib.optionals osConfig.modules.system.desktop.gnome.enable [
./gnome.nix
]
++ lib.optionals osConfig.modules.system.desktop.hyprland.enable [
./hyprland
];
home.packages = with pkgs; [
# ardour
# audacity
# blender
# gimp
# handbrake
# hunspell
# hunspellDicts.en-gb-large
# hunspellDicts.en-us-large
# inkscape
# krita
# libreoffice
# mkvtoolnix
# obs-studio
qbittorrent
# slack
# zoom-us
];
}

View File

@@ -10,8 +10,7 @@
enable = true;
profiles.Default = {
search = {
default = "ddg";
privateDefault = "ddg";
default = "DuckDuckGo";
force = true;
};
userChrome = ''

View File

@@ -239,5 +239,5 @@ in
[ ]
);
services.gpg-agent.pinentry.package = pkgs.pinentry-gnome3;
services.gpg-agent.pinentryPackage = pkgs.pinentry-gnome3;
}

View File

@@ -1,5 +1,4 @@
{
inputs,
lib,
pkgs,
osConfig,
@@ -7,64 +6,36 @@
}:
let
inherit (lib)
attrValues
concatStringsSep
elem
mapAttrs
mkIf
versionOlder
optionals
;
inherit (lib.generators)
toINI
;
concatMapAttrsStringSep =
sep: f: attrs:
concatStringsSep sep (attrValues (mapAttrs f attrs));
globalVariables = {
_JAVA_AWT_WM_NONREPARENTING = "1";
GDK_BACKEND = "wayland";
MOZ_ENABLE_WAYLAND = "1";
NIXOS_OZONE_WL = "1";
QT_QPA_PLATFORM = "wayland";
QT_STYLE_OVERRIDE = "kvantum";
QT_WAYLAND_DECORATION = "adwaita";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
SDL_VIDEODRIVER = "wayland";
XDG_SESSION_TYPE = "wayland";
}
// (
if elem "nvidia" osConfig.services.xserver.videoDrivers then
{
GBM_BACKEND = "nvidia-drm";
GSK_RENDERER =
if versionOlder osConfig.hardware.nvidia.package.version "570" then "ngl" else "vulkan";
LIBVA_DRIVER_NAME = "nvidia";
}
else
{ }
);
hyprVariables = {
AQ_DRM_DEVICES = "/dev/dri/card0:/dev/dri/card1";
};
in
{
imports = [
./hypridle.nix
./hyprlock.nix
./hyprpaper.nix
./waybar.nix
];
wayland.windowManager.hyprland = {
enable = true;
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
portalPackage =
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
plugins = [
pkgs.unstable.hyprlandPlugins.hyprbars
pkgs.unstable.hyprlandPlugins.hypr-dynamic-cursors
];
settings = {
env =
optionals (elem "nvidia" osConfig.services.xserver.videoDrivers) [
"GBM_BACKEND,nvidia-drm"
"LIBVA_DRIVER_NAME,nvidia"
]
++ [
"_JAVA_AWT_WM_NONREPARENTING,1"
"GDK_BACKEND,wayland"
"MOZ_ENABLE_WAYLAND,1"
"NIXOS_OZONE_WL,1"
"QT_WAYLAND_DISABLE_WINDOWDECORATION,1"
"QT_QPA_PLATFORM,wayland"
"SDL_VIDEODRIVER,wayland"
"XDG_SESSION_TYPE,wayland"
];
general = {
gaps_in = 5;
gaps_out = 20;
@@ -75,22 +46,6 @@ in
layout = "dwindle";
};
plugin = {
dynamic-cursors = {
enabled = true;
mode = "none";
shake = {
enabled = true;
};
};
hyprbars = {
enabled = true;
bar_height = 20;
bar_blur = true;
};
};
dwindle = {
pseudotile = true;
preserve_split = true;
@@ -105,15 +60,6 @@ in
disable_hyprland_logo = true;
};
ecosystem = {
no_donation_nag = true;
no_update_news = true;
};
experimental = {
xx_color_management_v4 = true;
};
decoration = {
rounding = 10;
@@ -124,6 +70,7 @@ in
enabled = true;
range = 4;
render_power = 3;
color = "rgba(1a1a1aee)";
};
blur = {
@@ -164,20 +111,16 @@ in
];
};
monitor = [
"desc:Dell Inc. DELL U3219Q HPTP413, preferred, auto, 1, vrr, 0, bitdepth, 10, cm, hdr"
"desc:LG Electronics LG TV SSCR2, 3840x2160@60, 0x0, 1, vrr, 0, bitdepth, 10, cm, hdr"
];
exec-once = "waybar";
input = {
kb_layout = "us";
kb_options = "caps:super";
kb_layout = "gb";
follow_mouse = 1;
sensitivity = 0;
};
device = {
name = "mx-anywhere-3s-mouse";
name = "epic-mouse-v1";
sensitivity = -0.5;
};
@@ -253,72 +196,16 @@ in
};
};
xdg.configFile = mkIf osConfig.programs.hyprland.withUWSM {
"Kvantum/kvantum.kvconfig".text = toINI { } {
General.theme = "KvLibadwaitaDark";
};
"Kvantum/KvLibadwaita".source = "${inputs.kvlibadwaita}/src/KvLibadwaita";
"uwsm/env".text = concatMapAttrsStringSep "\n" (
name: value: "export ${name}=${value}"
) globalVariables;
"uwsm/env-hyprland".text = concatMapAttrsStringSep "\n" (
name: value: "export ${name}=${value}"
) hyprVariables;
};
home.pointerCursor = {
enable = true;
gtk.enable = true;
name = "macOS";
package = pkgs.apple-cursor;
size = 28;
};
gtk = {
enable = true;
iconTheme = {
name = "MoreWaita";
package = pkgs.unstable.morewaita-icon-theme;
};
};
fonts.fontconfig = {
enable = true;
defaultFonts = {
sansSerif = [
"Adwaita Sans"
];
emoji = [
"Apple Color Emoji"
];
};
};
programs.kitty = {
enable = true;
settings = {
background = "#000000";
background_opacity = 0.7;
};
};
home.packages = with pkgs.unstable; [
adw-gtk3
anyrun
clipse
dunst
libsForQt5.qtstyleplugin-kvantum
loupe
kitty
mpv
qadwaitadecorations
qadwaitadecorations-qt6
waybar
wl-clipboard
];
services = {
flameshot.enable = true;
unclutter.enable = true;
};
services.gpg-agent.pinentry.package = pkgs.pinentry-gnome3;
services.gpg-agent.pinentryPackage = pkgs.pinentry-gnome3;
}

View File

@@ -4,7 +4,7 @@
{
services.hypridle = {
enable = true;
enable = false;
settings = {
general = {
after_sleep_cmd = "hyprctl dispatch dpms on";

View File

@@ -1,24 +1,14 @@
{
config,
lib,
...
}:
let
inherit (lib)
getExe
;
in
{
wayland.windowManager.hyprland.settings.bind = [
"$mainMod, L, exec, uwsm app -- ${getExe config.programs.hyprlock.package}"
];
{
programs.hyprlock = {
enable = true;
enable = false;
settings = {
general = {
disable_loading_bar = false;
grace = 3;
grace = 300;
hide_cursor = true;
no_fade_in = false;
};

View File

@@ -1,19 +0,0 @@
{
pkgs,
...
}:
{
imports = [
./common/optional/graphical/firefox.nix
./common/optional/graphical/fonts.nix
./common/optional/graphical/hyprland
./common/optional/graphical/mimeapps.nix
];
programs.nh.enable = true;
home.packages = with pkgs; [
jellyfin-media-player
];
}

View File

@@ -1,16 +0,0 @@
{
pkgs,
...
}:
{
imports = [
./common/optional/graphical/firefox.nix
./common/optional/graphical/fonts.nix
./common/optional/graphical/gnome.nix
];
home.packages = with pkgs; [
audacity
];
}

Some files were not shown because too many files have changed in this diff Show More