Compare commits

..

9 Commits

Author SHA1 Message Date
Alexander Heldt
32acd3a55c tadpole: Specify ssh port for gitea 2024-08-31 17:16:38 +02:00
Alexander Heldt
10b8f99193 pinwheel: Add git url preference for git.ppp.pm 2024-08-31 16:34:20 +02:00
Alexander Heldt
25043c3856 pinwheel: Add ssh keys for git.ppp.pm 2024-08-31 16:33:13 +02:00
Alexander Heldt
3180842d6a pinwheel: Add secrets for git.ppp.pm 2024-08-31 16:31:46 +02:00
Alexander Heldt
4ef27e43d7 pinwheel: Use tailscale DNS for ssh to backwards 2024-08-31 16:21:29 +02:00
Alexander Heldt
27e1f8306a tadpole: Use standard SSH port for gitea 2024-08-31 16:21:17 +02:00
Alexander Heldt
e5c0fe3ff9 backwards: Add transmission module 2024-08-31 15:49:56 +02:00
Alexander Heldt
d15e13c81d backwards: Backup sync to external drive with restic 2024-08-31 15:49:56 +02:00
Alexander Heldt
6478356950 backwards: Add secret for restic 2024-08-31 15:44:50 +02:00
155 changed files with 1630 additions and 2704 deletions

1
.envrc
View File

@@ -1 +0,0 @@
use flake

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
.direnv/
*.qcow2 *.qcow2
result result

View File

@@ -25,13 +25,3 @@ EDITOR=vim agenix -d "some-secret.age" -i ~/.ssh/alex.pinwheel
Or use some other SSH key that is has been used to key the secret. Or use some other SSH key that is has been used to key the secret.
# Test VM
Build the test VM with the command:
```
cm --build-test-vm
```
and test it with:
```
cm --run-test-vm
```

View File

@@ -1,10 +1,4 @@
{ { inputs, pkgs, lib, config, ... }:
inputs,
pkgs,
lib,
config,
...
}:
let let
flakePath = config.config-manager.flakePath; flakePath = config.config-manager.flakePath;
nixosConfiguration = config.config-manager.nixosConfiguration; nixosConfiguration = config.config-manager.nixosConfiguration;
@@ -18,49 +12,49 @@ let
throw "'config-manager.nixosConfiguration' cannot be empty" throw "'config-manager.nixosConfiguration' cannot be empty"
else else
pkgs.writeShellScriptBin "cm" '' pkgs.writeShellScriptBin "cm" ''
help() { help() {
cat << EOF cat << EOF
Usage: Usage:
cm [flag] cm [flag]
Flags: Flags:
--update updates the flake --update updates the flake
--switch rebuilds + switches configuration (using 'nh') --switch rebuilds + switches configuration (using 'nh')
--build-test-vm, --btvm build test-vm --build-test-vm, --btvm build test-vm
--run-test-vm, --rtvm run test-vm --run-test-vm, --rtvm run test-vm
EOF EOF
} }
update() { update() {
echo -e "\033[0;31mUPDATING FLAKE\033[0m" echo -e "\033[0;31mUPDATING FLAKE\033[0m"
nix flake update --flake ${flakePath} nix flake update ${flakePath}
} }
switch() { switch() {
nixos-rebuild dry-build --flake ${flakePath}#${nixosConfiguration} nixos-rebuild dry-build --flake ${flakePath}#${nixosConfiguration}
${nh}/bin/nh os switch --hostname ${nixosConfiguration} ${flakePath} ${nh}/bin/nh os switch --hostname ${nixosConfiguration} ${flakePath}
} }
build-test-vm() { build-test-vm() {
nixos-rebuild build-vm --flake ${flakePath}#test-vm nixos-rebuild build-vm --flake ${flakePath}#test-vm
} }
run-test-vm() { run-test-vm() {
${flakePath}/result/bin/run-test-vm-vm ${flakePath}/result/bin/run-test-vm-vm
} }
case $1 in case $1 in
--update) --update)
update ;; update ;;
--switch) --switch)
switch ;; switch ;;
--build-test-vm | --btvm) --build-test-vm | --btvm)
build-test-vm ;; build-test-vm ;;
--run-test-vm | --rtvm) --run-test-vm | --rtvm)
run-test-vm ;; run-test-vm ;;
--help | *) --help | *)
help ;; help ;;
esac esac
''; '';
in in
{ {

162
flake.lock generated
View File

@@ -10,11 +10,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1760836749, "lastModified": 1723293904,
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=", "narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "2f0f812f69f3eb4140157fe15e12739adf82e32a", "rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -31,11 +31,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1744478979, "lastModified": 1700795494,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"owner": "lnl7", "owner": "lnl7",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b", "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -45,39 +45,20 @@
"type": "github" "type": "github"
} }
}, },
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1760701190,
"narHash": "sha256-y7UhnWlER8r776JsySqsbTUh2Txf7K30smfHlqdaIQw=",
"owner": "nix-community",
"repo": "disko",
"rev": "3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"emacs-overlay": { "emacs-overlay": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1760951609, "lastModified": 1725037990,
"narHash": "sha256-rWkUWKWcLin0+dKvinWC1IZVxJnIvXV3q/wlmmKkzo4=", "narHash": "sha256-7ZwhCJQ8/BvP5UDSOe9PUzrDlDePxfyDrkEYuuZZJJ8=",
"owner": "nix-community", "owner": "nix-community",
"repo": "emacs-overlay", "repo": "emacs-overlay",
"rev": "41bee8f6a80b36b0348a8e750e5db88fea528171", "rev": "45405f34d10260753298ff244a9b9c36e04b2e11",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -91,11 +72,11 @@
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1710146030,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -112,11 +93,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1745494811, "lastModified": 1703113217,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -132,11 +113,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1760969583, "lastModified": 1724435763,
"narHash": "sha256-vsf5mvR0xxK4GsfLx5bMJAQ4ysdrKymMIifNw+4TP7g=", "narHash": "sha256-UNky3lJNGQtUEXT2OY8gMxejakSWPTfWKvpFkpFlAfM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "c9d758b500e53db5b74aa02d17dc45b65229e8e9", "rev": "c2cd2a52e02f1dfa1c88f95abeb89298d46023be",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -152,11 +133,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759613406, "lastModified": 1722636442,
"narHash": "sha256-PzgQJydp+RlKvwDi807pXPlURdIAVqLppZDga3DwPqg=", "narHash": "sha256-+7IS0n3/F0I5j6ZbrVlLcIIPHY3o+/vLAqg/G48sG+w=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "contrib", "repo": "contrib",
"rev": "32e1a75b65553daefb419f0906ce19e04815aa3a", "rev": "9d67858b437d4a1299be496d371b66fc0d3e01f6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -165,27 +146,6 @@
"type": "github" "type": "github"
} }
}, },
"naviterm": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1757496832,
"narHash": "sha256-R5EMcms24G6QGk62iNAMApeZmKsHwCDLj68UUdkhSLw=",
"owner": "detoxify92",
"repo": "naviterm",
"rev": "3b3bd2bace3676000f530b2f47fa28f431c56761",
"type": "gitlab"
},
"original": {
"owner": "detoxify92",
"repo": "naviterm",
"type": "gitlab"
}
},
"nh": { "nh": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -193,11 +153,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1760961269, "lastModified": 1724689275,
"narHash": "sha256-Udg6DnM6scJj+imbttJR7GQpG2WWeDZ1JOtySTY99M0=", "narHash": "sha256-wpxC7XiZ9maYZA4BSLKGXc+pn2fwaiq2Ybu5kNjl1ao=",
"owner": "viperML", "owner": "viperML",
"repo": "nh", "repo": "nh",
"rev": "e27508e06f74c7f03616150c1ac1431eaef7f443", "rev": "a922eada049854019c5d1bbc82383f7095773e5c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -223,11 +183,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1760958188, "lastModified": 1724878143,
"narHash": "sha256-2m1S4jl+GEDtlt2QqeHil8Ny456dcGSKJAM7q3j/BFU=", "narHash": "sha256-UjpKo92iZ25M05kgSOw/Ti6VZwpgdlOa73zHj8OcaDk=",
"owner": "nixos", "owner": "nixos",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "d6645c340ef7d821602fd2cd199e8d1eed10afbc", "rev": "95c3dfe6ef2e96ddc1ccdd7194e3cda02ca9a8ef",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -239,11 +199,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1760878510, "lastModified": 1724819573,
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", "narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", "rev": "71e91c409d1e654808b2621f28a327acfdad8dc2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -255,16 +215,16 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1760862643, "lastModified": 1724855419,
"narHash": "sha256-PXwG0TM7Ek87DNx4LbGWuD93PbFeKAJs4FfALtp7Wo0=", "narHash": "sha256-WXHSyOF4nBX0cvHN3DfmEMcLOVdKH6tnMk9FQ8wTNRc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "33c6dca0c0cb31d6addcd34e90a63ad61826b28c", "rev": "ae2fc9e0e42caaf3f068c1bfdc11c71734125e06",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-25.05", "ref": "nixos-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -282,29 +242,25 @@
"rev": "662a254ea8065a0f104ccf5a46b59252e1e08b58", "rev": "662a254ea8065a0f104ccf5a46b59252e1e08b58",
"revCount": 54, "revCount": 54,
"type": "git", "type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/ppp.pm-site.git" "url": "ssh://git@codeberg.org/ppp/ppp.pm-site.git"
}, },
"original": { "original": {
"ref": "main", "ref": "main",
"type": "git", "type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/ppp.pm-site.git" "url": "ssh://git@codeberg.org/ppp/ppp.pm-site.git"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"disko": "disko",
"emacs-overlay": "emacs-overlay", "emacs-overlay": "emacs-overlay",
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"hyprland-contrib": "hyprland-contrib", "hyprland-contrib": "hyprland-contrib",
"naviterm": "naviterm",
"nh": "nh", "nh": "nh",
"nix-gc-env": "nix-gc-env", "nix-gc-env": "nix-gc-env",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"pppdotpm-site": "pppdotpm-site", "pppdotpm-site": "pppdotpm-site"
"whib-backend": "whib-backend",
"whib-frontend": "whib-frontend"
} }
}, },
"systems": { "systems": {
@@ -336,48 +292,6 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"whib-backend": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1739029248,
"narHash": "sha256-ux/Udy0Mhs66P/EQQ8S+xIuXRm9UHEYwSy12IZtlbnA=",
"ref": "master",
"rev": "222a8f6dde2e9270f6390b5e1e83c7ae1ea48290",
"revCount": 371,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib.git"
},
"original": {
"ref": "master",
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib.git"
}
},
"whib-frontend": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1761508816,
"narHash": "sha256-adV/lyxcmuopyuzZ49v46Yt0gft+ioEL4yl1S+vUbus=",
"ref": "master",
"rev": "ab10bf50cb6b023a1b99f91c7e8d550231135eef",
"revCount": 223,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib-react.git"
},
"original": {
"ref": "master",
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib-react.git"
}
} }
}, },
"root": "root", "root": "root",

147
flake.nix
View File

@@ -6,17 +6,12 @@
nixos-hardware.url = "github:nixos/nixos-hardware/master"; nixos-hardware.url = "github:nixos/nixos-hardware/master";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
nh = { nh = {
url = "github:viperML/nh"; url = "github:viperML/nh";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-gc-env.url = "github:Julow/nix-gc-env"; nix-gc-env.url= "github:Julow/nix-gc-env";
home-manager = { home-manager = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
@@ -38,108 +33,56 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
naviterm = {
url = "gitlab:detoxify92/naviterm";
inputs.nixpkgs.follows = "nixpkgs";
};
pppdotpm-site = { pppdotpm-site = {
url = "git+ssh://gitea@git.ppp.pm:1122/alex/ppp.pm-site.git?ref=main"; url = "git+ssh://git@codeberg.org/ppp/ppp.pm-site.git?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
whib-backend = {
url = "git+ssh://gitea@git.ppp.pm:1122/alex/whib.git?ref=master";
inputs.nixpkgs.follows = "nixpkgs";
};
whib-frontend = {
url = "git+ssh://gitea@git.ppp.pm:1122/alex/whib-react.git?ref=master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
}; };
outputs = outputs = { self, ... }@inputs: {
{ ... }@inputs: nixosConfigurations = {
{ pinwheel = inputs.nixpkgs.lib.nixosSystem {
nixosConfigurations = { system = "x86_64-linux";
pinwheel = inputs.nixpkgs.lib.nixosSystem { specialArgs = { inherit inputs; };
system = "x86_64-linux"; modules = [
specialArgs = { ./hosts/pinwheel/configuration.nix
inherit inputs; inputs.nixos-hardware.nixosModules.lenovo-thinkpad-x1-10th-gen
}; ./hosts/pinwheel/home.nix
modules = [ ];
./hosts/pinwheel/configuration.nix
inputs.nixos-hardware.nixosModules.lenovo-thinkpad-x1-10th-gen
./hosts/pinwheel/home.nix
];
};
manatee = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
inherit inputs;
};
modules = [
./hosts/manatee/configuration.nix
./hosts/manatee/home.nix
];
};
backwards = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
inherit inputs;
};
modules = [
./hosts/backwards/configuration.nix
./hosts/backwards/home.nix
];
};
tadpole =
let
system = "x86_64-linux";
in
inputs.nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit inputs;
};
modules = [
./hosts/tadpole/configuration.nix
./hosts/tadpole/home.nix
inputs.whib-backend.nixosModules.${system}.default
inputs.whib-frontend.nixosModules.${system}.default
];
};
test-vm =
let
system = "x86_64-linux";
in
inputs.nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit inputs;
};
modules = [
./hosts/test-vm/configuration.nix
inputs.whib-backend.nixosModules.${system}.default
inputs.whib-frontend.nixosModules.${system}.default
];
};
}; };
devShells = backwards = inputs.nixpkgs.lib.nixosSystem {
let system = "x86_64-linux";
system = "x86_64-linux"; specialArgs = { inherit inputs; };
pkgs = inputs.nixpkgs.legacyPackages.${system}; modules = [
in ./hosts/backwards/configuration.nix
{ ./hosts/backwards/home.nix
${system}.default = pkgs.mkShell { ];
packages = [ pkgs.nixfmt-rfc-style ]; };
};
}; sombrero = inputs.nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
specialArgs = { inherit inputs; };
modules = [
./hosts/sombrero/configuration.nix
./hosts/sombrero/home.nix
];
};
tadpole = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./hosts/tadpole/configuration.nix
./hosts/tadpole/home.nix
];
};
test-vm = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [ ./hosts/test-vm/configuration.nix ];
};
}; };
};
} }

View File

@@ -1,21 +1,19 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [ imports =
../../config-manager/default.nix [
../../shared-modules/syncthing.nix ../../config-manager/default.nix
./hardware-configuration.nix ../../shared-modules/syncthing.nix
./modules ./hardware-configuration.nix
]; ./modules
];
nix.settings.experimental-features = [ nix.settings.experimental-features = [ "nix-command" "flakes" ];
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
console.keyMap = "sv-latin1"; console.keyMap = "sv-latin1";
services.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
enable = true; enable = true;
@@ -24,26 +22,11 @@
pulse.enable = true; pulse.enable = true;
}; };
hardware = {
graphics = {
enable = true;
extraPackages = [
pkgs.intel-media-driver
pkgs.libvdpau-va-gl
];
};
};
users.users.alex = { users.users.alex = {
isNormalUser = true; isNormalUser = true;
description = "alex"; description = "alex";
extraGroups = [ extraGroups = [ "networkmanager" "wheel" ];
"networkmanager" packages = [];
"wheel"
"video"
"render"
];
packages = [ ];
}; };
environment.variables.EDITOR = "vim"; environment.variables.EDITOR = "vim";

View File

@@ -1,47 +1,32 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ { config, lib, pkgs, modulesPath, ... }:
config,
lib,
pkgs,
modulesPath,
...
}:
{ {
imports = [ imports =
(modulesPath + "/installer/scan/not-detected.nix") [ (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
"xhci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = { fileSystems."/" =
device = "/dev/disk/by-uuid/bad3d82a-7bb8-490f-bd01-a4b16fe6f33d"; { device = "/dev/disk/by-uuid/bad3d82a-7bb8-490f-bd01-a4b16fe6f33d";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/D049-60DD"; { device = "/dev/disk/by-uuid/D049-60DD";
fsType = "vfat"; fsType = "vfat";
options = [ options = [ "fmask=0077" "dmask=0077" ];
"fmask=0077" };
"dmask=0077"
swapDevices =
[ { device = "/dev/disk/by-uuid/ff4de0e5-2c60-4ee7-a55c-450727efb921"; }
]; ];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/ff4de0e5-2c60-4ee7-a55c-450727efb921"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's

View File

@@ -1,9 +1,4 @@
{ { inputs, lib, config, ... }:
inputs,
lib,
config,
...
}:
let let
configurationLimit = config.mod.gc.configurationLimit; configurationLimit = config.mod.gc.configurationLimit;
in in

View File

@@ -12,9 +12,9 @@ in
ssh.enable = true; ssh.enable = true;
git.enable = true; git.enable = true;
nginx.enable = true;
syncthing.enable = true; syncthing.enable = true;
restic.enable = true; restic.enable = true;
transmission.enable = true;
}; };
}; };
} }

View File

@@ -1,99 +0,0 @@
{ pkgs, ... }:
let
wrapped = pkgs.wrapFirefox pkgs.firefox-devedition-unwrapped {
extraPolicies = {
DisableFirefoxAccounts = false;
CaptivePortal = false;
DisableFirefoxStudies = true;
DisablePocket = true;
DisableTelemetry = true;
OfferToSaveLogins = false;
OfferToSaveLoginsDefault = false;
PasswordManagerEnabled = false;
FirefoxHome = {
Search = false;
Pocket = false;
Snippets = false;
TopSites = false;
Highlights = false;
};
UserMessaging = {
ExtensionRecommendations = false;
SkipOnboarding = true;
};
};
};
ff-alex = pkgs.writeShellApplication {
name = "ff-alex";
text = ''
${wrapped}/bin/firefox-devedition -P alex --new-window "$@"
'';
};
sharedSettings = {
"general.smoothScroll" = true;
"apz.gtk.kinetic_scroll.enabled" = false;
"network.dns.force_waiting_https_rr" = false;
};
in
{
home-manager.users.alex = {
programs.firefox = {
enable = true;
package = wrapped;
profiles = {
alex = {
id = 0;
name = "alex";
isDefault = true;
settings = sharedSettings // { };
};
};
};
xdg = {
# /etc/profiles/per-user/alex/share/applications
desktopEntries = {
ff-alex = {
name = "ff-alex";
exec = "${ff-alex}/bin/ff-alex %U";
terminal = false;
};
};
mimeApps = {
enable = true;
defaultApplications = {
"text/html" = "ff-alex.desktop";
"x-scheme-handler/http" = "ff-alex.desktop";
"x-scheme-handler/https" = "ff-alex.desktop";
"application/x-exension-htm" = "ff-alex.desktop";
"application/x-exension-html" = "ff-alex.desktop";
"application/x-exension-shtml" = "ff-alex.desktop";
"application/xhtml+xml" = "ff-alex.desktop";
"application/x-exension-xhtml" = "ff-alex.desktop";
"application/x-exension-xht" = "ff-alex.desktop";
};
};
# https://github.com/nix-community/home-manager/issues/1213
configFile."mimeapps.list".force = true;
};
home.packages = [
ff-alex
];
};
environment.variables = {
MOZ_ENABLE_WAYLAND = 1;
BROWSER = "${ff-alex}/bin/ff-alex $@";
};
}

View File

@@ -2,16 +2,13 @@
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ home.packages = [
pkgs.nethack (pkgs.retroarch.override {
cores = [
pkgs.moonlight-qt pkgs.libretro.snes9x
pkgs.libretro.genesis-plus-gx
pkgs.pcsx2 pkgs.libretro.swanstation
(pkgs.retroarch.withCores (cores: [ ];
pkgs.libretro.snes9x })
pkgs.libretro.genesis-plus-gx
pkgs.libretro.swanstation
]))
]; ];
}; };
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.git.enable; enabled = config.mod.git.enable;
in in

View File

@@ -0,0 +1,44 @@
{ pkgs, ... }:
{
fileSystems."/home/alex/media" = {
device = "/dev/disk/by-uuid/ad4acc0f-172c-40f8-8473-777c957e8764";
fsType = "ext4";
options = [ "nofail" ];
};
# 1. enable vaapi on OS-level
nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
};
hardware = {
graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-vaapi-driver # previously vaapiIntel
vaapiVdpau
libvdpau-va-gl
intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in)
vpl-gpu-rt # QSV on 11th gen or newer
];
};
};
services.jellyfin = {
enable = true;
openFirewall = true;
user = "alex";
group = "users";
dataDir = "/home/alex/media/jellyfin";
};
environment.systemPackages = [
pkgs.jellyfin
pkgs.jellyfin-web
pkgs.jellyfin-ffmpeg
];
}

View File

@@ -1,22 +1,10 @@
{ config, ... }:
{ {
networking = { networking = {
hostName = "backwards"; hostName = "backwards";
networkmanager.enable = false; networkmanager.enable = false;
wireless.enable = true;
#wireless.networks are defined in the secret `wpa_supplicant.conf` #wireless.networks are defined in the secret `wpa_supplicant.conf`
wireless = {
enable = true;
secretsFile = config.age.secrets.wireless-network-secrets.path;
networks = {
"w1-f1_5G" = {
pskRaw = "ext:w1-f1_psk";
};
};
};
defaultGateway = "192.168.50.1"; defaultGateway = "192.168.50.1";
nameservers = [ "1.1.1.1" ]; nameservers = [ "1.1.1.1" ];
@@ -24,18 +12,19 @@
wlp1s0 = { wlp1s0 = {
useDHCP = false; useDHCP = false;
ipv4 = { ipv4 = {
addresses = [ addresses = [{
{ address = "192.168.50.202";
address = "192.168.50.202"; prefixLength = 24;
prefixLength = 24; }];
}
];
}; };
}; };
}; };
}; };
age.secrets = { age.secrets = {
"wireless-network-secrets".file = ../../../../secrets/backwards/wireless-network-secrets.age; "wpa_supplicant.conf" = {
file = ../../../../secrets/backwards/wpa_supplicant.conf.age;
path = "/etc/wpa_supplicant.conf";
};
}; };
} }

View File

@@ -1,22 +0,0 @@
{ lib, config, ... }:
let
enabled = config.mod.nginx.enable;
in
{
options = {
mod.nginx = {
enable = lib.mkEnableOption "Enable nginx module";
};
};
config = lib.mkIf enabled {
services = {
nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
};
};
}

View File

@@ -21,32 +21,11 @@ in
"sync-to-external" = { "sync-to-external" = {
initialize = true; initialize = true;
user = "alex";
passwordFile = config.age.secrets.restic-password.path; passwordFile = config.age.secrets.restic-password.path;
paths = [ "/home/alex/sync" ]; paths = [ "/home/alex/sync" ];
repository = "/home/alex/backup/restic"; repository = "/home/alex/backup";
timerConfig = {
OnCalendar = "*-*-* 0/12:00:00"; # Every 12th hour, i.e. twice a day
Persistent = true;
};
pruneOpts = [
"--keep-daily 1"
"--keep-weekly 7"
"--keep-yearly 12"
];
};
"sync-to-cloud" = {
initialize = true;
passwordFile = config.age.secrets.restic-password.path;
environmentFile = config.age.secrets.restic-cloud-sync-key.path;
repositoryFile = config.age.secrets.restic-cloud-sync-repository.path;
paths = [ "/home/alex/sync" ];
exclude = [ "/home/alex/sync/reading-material" ];
timerConfig = { timerConfig = {
OnCalendar = "*-*-* 0/12:00:00"; # Every 12th hour, i.e. twice a day OnCalendar = "*-*-* 0/12:00:00"; # Every 12th hour, i.e. twice a day
@@ -65,10 +44,8 @@ in
age = { age = {
secrets = { secrets = {
"restic-password".file = ../../../../secrets/backwards/restic-password.age; "restic-password".file = ../../../../secrets/backwards/restic-password.age;
"restic-cloud-sync-key".file = ../../../../secrets/backwards/restic-cloud-sync-key.age;
"restic-cloud-sync-repository".file =
../../../../secrets/backwards/restic-cloud-sync-repository.age;
}; };
}; };
}; };
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.ssh.enable; enabled = config.mod.ssh.enable;
@@ -23,26 +18,12 @@ in
enable = true; enable = true;
matchBlocks = { matchBlocks = {
"manatee" = {
hostname = "manatee";
user = "alex";
identityFile = "/home/alex/.ssh/alex.backwards-manatee";
port = 1122;
};
"git.ppp.pm" = {
hostname = "git.ppp.pm";
identityFile = "/home/alex/.ssh/alex.backwards-git.ppp.pm";
};
"codeberg.org" = { "codeberg.org" = {
hostname = "codeberg.org"; hostname = "codeberg.org";
identityFile = "/home/alex/.ssh/alex.backwards-codeberg.org"; identityFile = "/home/alex/.ssh/alex.backwards-codeberg.org";
}; };
}; };
}; };
home.packages = [ pkgs.sshfs ];
}; };
environment.etc."ssh/authorized_keys_command" = { environment.etc."ssh/authorized_keys_command" = {
@@ -60,12 +41,10 @@ in
enable = true; enable = true;
ports = [ 1122 ]; ports = [ 1122 ];
hostKeys = [ hostKeys = [{
{ path = "${rootSSHKeyPath}/root.backwards";
path = "${rootSSHKeyPath}/root.backwards"; type = "ed25519";
type = "ed25519"; }];
}
];
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;
@@ -93,37 +72,11 @@ in
path = "${rootSSHKeyPath}/root.backwards.pub"; path = "${rootSSHKeyPath}/root.backwards.pub";
}; };
"alex.backwards-manatee" = {
file = ../../../../secrets/backwards/alex.backwards-manatee.age;
path = "/home/alex/.ssh/alex.backwards-manatee";
owner = "alex";
group = "users";
};
"alex.backwards-manatee.pub" = {
file = ../../../../secrets/backwards/alex.backwards-manatee.pub.age;
path = "/home/alex/.ssh/alex.backwards-manatee.pub";
owner = "alex";
group = "users";
};
"alex.pinwheel-backwards.pub" = { "alex.pinwheel-backwards.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-backwards.pub.age; file = ../../../../secrets/pinwheel/alex.pinwheel-backwards.pub.age;
path = "${authorizedKeysPath}/alex.pinwheel-backwards.pub"; path = "${authorizedKeysPath}/alex.pinwheel-backwards.pub";
}; };
"alex.backwards-git.ppp.pm" = {
file = ../../../../secrets/backwards/alex.backwards-git.ppp.pm.age;
path = "/home/alex/.ssh/alex.backwards-git.ppp.pm";
owner = "alex";
group = "users";
};
"alex.backwards-git.ppp.pm.pub" = {
file = ../../../../secrets/backwards/alex.backwards-git.ppp.pm.pub.age;
path = "/home/alex/.ssh/alex.backwards-git.ppp.pm.pub";
owner = "alex";
group = "users";
};
"alex.backwards-codeberg.org" = { "alex.backwards-codeberg.org" = {
file = ../../../../secrets/backwards/alex.backwards-codeberg.org.age; file = ../../../../secrets/backwards/alex.backwards-codeberg.org.age;
path = "/home/alex/.ssh/alex.backwards-codeberg.org"; path = "/home/alex/.ssh/alex.backwards-codeberg.org";

View File

@@ -34,16 +34,12 @@ in
devices = { devices = {
phone.id = config.lib.syncthing.phone; phone.id = config.lib.syncthing.phone;
pinwheel.id = config.lib.syncthing.pinwheel; pinwheel.id = config.lib.syncthing.pinwheel;
tablet.id = config.lib.syncthing.tablet;
}; };
folders = { folders = {
org = { org = {
path = "/home/alex/sync/org"; path = "/home/alex/sync/org";
devices = [ devices = [ "phone" "pinwheel" ];
"phone"
"pinwheel"
];
versioning = { versioning = {
type = "staggered"; type = "staggered";
params = { params = {
@@ -75,7 +71,7 @@ in
}; };
books = { books = {
path = "/home/alex/sync/reading-material/books"; path = "/home/alex/sync/books";
devices = [ "pinwheel" ]; devices = [ "pinwheel" ];
versioning = { versioning = {
type = "staggered"; type = "staggered";

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.transmission.enable; enabled = config.mod.transmission.enable;
in in
@@ -21,26 +16,25 @@ in
package = pkgs.transmission_4; package = pkgs.transmission_4;
openFirewall = true; openFirewall = true;
openRPCPort = true;
user = "storage"; user = "alex";
group = "storage"; group = "users";
home = "/mnt/media/public/.ts-home"; home = "/home/alex/media/ts-home";
downloadDirPermissions = "775"; downloadDirPermissions = "775";
settings = { settings = {
incomplete-dir-enabled = false;
download-dir = "/mnt/media/public/downloads";
rpc-bind-address = "0.0.0.0"; rpc-bind-address = "0.0.0.0";
rpc-port = 9191;
incomplete-dir-enabled = false;
download-dir = "/home/alex/media/downloads";
# Required to have empty user/pass to satisfy transmissionA
# https://github.com/transmission/transmission/discussions/1941#discussioncomment-1472352
rpc-whitelist-enabled = false;
rpc-authentication-required = true; rpc-authentication-required = true;
rpc-username = ""; rpc-whitelist-enabled = false;
rpc-password = ""; rpc-username = "transmission";
rpc-password = "{55d884e4042db67313da49e05d7089a368eb64b3Br.3X.Xi";
}; };
}; };
}; };

View File

@@ -1,56 +0,0 @@
{ pkgs, ... }:
{
imports = [
../../config-manager/default.nix
../../shared-modules/syncthing.nix
./hardware-configuration.nix
./disk-config.nix
./modules
];
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true;
users.users.alex = {
isNormalUser = true;
description = "alex";
extraGroups = [
"wheel"
"storage"
];
};
environment.variables.EDITOR = "vim";
environment.systemPackages = with pkgs; [
vim
git
];
config-manager = {
flakePath = "/home/alex/config";
};
# This option defines the first version of NixOS you have installed on this particular machine,
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
#
# Most users should NEVER change this value after the initial install, for any reason,
# even if you've upgraded your system to a new NixOS release.
#
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
# to actually do that.
#
# This value being lower than the current NixOS release does NOT mean your system is
# out of date, out of support, or vulnerable.
#
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
# and migrated your data accordingly.
#
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.11"; # Did you read the comment?
}

View File

@@ -1,243 +0,0 @@
{
inputs,
pkgs,
config,
...
}:
{
imports = [ inputs.disko.nixosModules.disko ];
config = {
users.groups.storage = { };
users.users.storage = {
isSystemUser = true;
description = "storage";
group = "storage";
};
systemd.tmpfiles.settings = {
"10-media-public" = {
"/mnt/media/public" = {
d = {
# Create directory
user = "storage";
group = "storage";
mode = "2775";
};
z = {
# Ensure permissions are inherited
user = "storage";
group = "storage";
mode = "2775";
};
};
};
"10-cameras-public" = {
"/mnt/cameras/public" = {
d = {
# Create directory
user = "storage";
group = "storage";
mode = "2775";
};
z = {
# Ensure permissions are inherited
user = "storage";
group = "storage";
mode = "2775";
};
};
};
"10-sync-public" = {
"/mnt/sync/public" = {
d = {
# Create directory
user = "storage";
group = "storage";
mode = "2775";
};
z = {
# Ensure permissions are inherited
user = "storage";
group = "storage";
mode = "2775";
};
};
};
};
environment.systemPackages = [
pkgs.smartmontools
];
services.smartd = {
enable = true;
devices = [
{ device = config.disko.devices.disk.root.device; }
{ device = config.disko.devices.disk.disk1.device; }
{ device = config.disko.devices.disk.disk2.device; }
];
};
services.zfs.autoScrub.enable = true;
networking.hostId = "0a9474e7"; # Required by ZFS
disko.devices = {
disk = {
root = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
disk1 = {
type = "disk";
device = "/dev/disk/by-id/ata-ST8000VN004-3CP101_WWZ8QCG4";
content = {
type = "gpt";
partitions = {
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "storage";
};
};
};
};
};
disk2 = {
type = "disk";
device = "/dev/disk/by-id/ata-ST8000VN004-3CP101_WWZ8QDJ5";
content = {
type = "gpt";
partitions = {
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "storage";
};
};
};
};
};
disk3 = {
type = "disk";
device = "/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_85K2A0UCF4MJ";
content = {
type = "gpt";
partitions = {
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "storage";
};
};
};
};
};
disk4 = {
type = "disk";
device = "/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_85K2A0V6F4MJ";
content = {
type = "gpt";
partitions = {
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "storage";
};
};
};
};
};
};
zpool = {
storage = {
type = "zpool";
mode = {
topology = {
type = "topology";
vdev = [
{
mode = "mirror";
members = [
"disk1"
"disk2"
];
}
{
mode = "mirror";
members = [
"disk3"
"disk4"
];
}
];
};
};
rootFsOptions = {
mountpoint = "none";
compression = "zstd";
xattr = "sa";
"com.sun:auto-snapshot" = "false";
};
datasets = {
media = {
type = "zfs_fs";
mountpoint = "/mnt/media";
options.mountpoint = "legacy"; # otherwise we get a race between systemd and zfs; https://github.com/nix-community/disko/issues/214
};
cameras = {
type = "zfs_fs";
mountpoint = "/mnt/cameras";
options.mountpoint = "legacy"; # otherwise we get a race between systemd and zfs; https://github.com/nix-community/disko/issues/214
};
sync = {
type = "zfs_fs";
mountpoint = "/mnt/sync";
options.mountpoint = "legacy"; # otherwise we get a race between systemd and zfs; https://github.com/nix-community/disko/issues/214
};
};
};
};
};
};
}

View File

@@ -1,39 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"nvme"
"ahci"
"usb_storage"
"usbhid"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -1,29 +0,0 @@
{ lib, config, ... }:
let
enabled = config.mod.audiobookshelf.enable;
in
{
options = {
mod.audiobookshelf = {
enable = lib.mkEnableOption "Enable audiobookshelf module";
};
};
config = lib.mkIf enabled {
users.users.audiobookshelf = {
isSystemUser = true;
description = "audiobookshelf";
group = "storage";
};
services.audiobookshelf = {
enable = true;
user = "audiobookshelf";
group = "storage";
host = "0.0.0.0";
port = 8000;
};
};
}

View File

@@ -1,43 +0,0 @@
{
inputs,
lib,
config,
...
}:
let
configurationLimit = config.mod.gc.configurationLimit;
in
{
imports = [ inputs.nix-gc-env.nixosModules.default ];
options = {
mod.gc = {
configurationLimit = lib.mkOption {
type = lib.types.int;
default = 10;
description = "number of configuration generations to keep";
};
};
};
config = {
nix.gc = {
automatic = true;
dates = "weekly";
# `delete_generations` added by nix-gc-env
delete_generations = "+${builtins.toString configurationLimit}";
};
boot = {
loader = {
systemd-boot = {
enable = true;
inherit configurationLimit;
};
efi.canTouchEfiVariables = true;
};
};
};
}

View File

@@ -1,47 +0,0 @@
{ lib, config, ... }:
let
enabled = config.mod.calibre-web.enable;
in
{
options = {
mod.calibre-web = {
enable = lib.mkEnableOption "add calibre-web module";
};
};
config = lib.mkIf enabled {
services = {
calibre-web = {
enable = true;
user = "storage";
group = "storage";
listen = {
ip = "0.0.0.0";
port = 8083;
};
dataDir = "/mnt/media/public/books";
options = {
calibreLibrary = "/mnt/media/public/books";
enableBookUploading = true;
};
};
nginx = {
virtualHosts."books.ppp.pm" = {
extraConfig = ''
client_max_body_size 1024M;
'';
locations."/" = {
proxyPass = "http://0.0.0.0:8083"; # TODO add option for port + host
};
};
};
};
};
}

View File

@@ -1,26 +0,0 @@
{ lib, ... }:
let
toModulePath = dir: _: ./. + "/${dir}";
filterDirs = dirs: lib.attrsets.filterAttrs (_: type: type == "directory") dirs;
in
{
imports = lib.mapAttrsToList toModulePath (filterDirs (builtins.readDir ./.));
config = {
mod = {
gc.configurationLimit = 10;
ssh.enable = true;
git.enable = true;
nginx.enable = true;
syncthing.enable = true;
transmission.enable = true;
calibre-web.enable = true;
audiobookshelf.enable = true;
jellyfin.enable = true;
immich.enable = true;
navidrome.enable = true;
};
};
}

View File

@@ -1,35 +0,0 @@
{ lib, config, ... }:
let
enabled = config.mod.immich.enable;
in
{
options = {
mod.immich = {
enable = lib.mkEnableOption "Enable immich module";
};
};
config = lib.mkIf enabled {
users.users.immich = {
isSystemUser = true;
group = "storage";
extraGroups = [
"render"
"video"
];
};
services.immich = {
enable = true;
user = "immich";
group = "storage";
host = "0.0.0.0";
mediaLocation = "/mnt/cameras/public";
accelerationDevices = [ "/dev/dri/renderD128" ];
};
};
}

View File

@@ -1,55 +0,0 @@
{
lib,
pkgs,
config,
...
}:
let
enabled = config.mod.jellyfin.enable;
in
{
options = {
mod.jellyfin = {
enable = lib.mkEnableOption "Enable jellyfin module";
};
};
config = lib.mkIf enabled {
users.users.jellyfin = {
isSystemUser = true;
group = "storage";
extraGroups = [
"render"
"video"
];
};
hardware = {
graphics = {
enable = true;
extraPackages = [
pkgs.intel-media-driver # Modern Intel VA-API driver (needed for N305)
pkgs.libvdpau-va-gl # VDPAU backend for VA-API GLX interop
];
};
};
services = {
jellyfin = {
enable = true;
openFirewall = true;
user = "jellyfin";
group = "storage";
};
};
environment.systemPackages = [
pkgs.jellyfin
pkgs.jellyfin-web
pkgs.jellyfin-ffmpeg
];
};
}

View File

@@ -1,33 +0,0 @@
{
lib,
pkgs,
config,
...
}:
let
navidromeEnabled = config.mod.navidrome.enable;
in
{
options = {
mod.navidrome = {
enable = lib.mkEnableOption "Enable navidrome module";
};
};
config = {
services = lib.mkIf navidromeEnabled {
navidrome = {
enable = true;
openFirewall = true;
user = "navidrome";
group = "storage";
settings = {
Port = 4533;
Address = "0.0.0.0";
MusicFolder = "/mnt/media/public/music";
};
};
};
};
}

View File

@@ -1,22 +0,0 @@
{ ... }:
{
networking = {
hostName = "manatee";
defaultGateway = "192.168.50.1";
nameservers = [ "1.1.1.1" ];
interfaces = {
enp3s0 = {
useDHCP = false;
ipv4 = {
addresses = [
{
address = "192.168.50.203";
prefixLength = 24;
}
];
};
};
};
};
}

View File

@@ -1,106 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
enabled = config.mod.ssh.enable;
authorizedKeysPath = "/home/alex/.ssh/authorized-keys";
rootSSHKeyPath = "/etc/ssh";
in
{
options = {
mod.ssh = {
enable = lib.mkEnableOption "enable ssh module";
};
};
config = lib.mkIf enabled {
home-manager.users.alex = {
programs.ssh = {
enable = true;
matchBlocks = {
"git.ppp.pm" = {
hostname = "git.ppp.pm";
identityFile = "/home/alex/.ssh/alex.manatee-git.ppp.pm";
};
};
};
};
environment.etc."ssh/authorized_keys_command" = {
mode = "0755";
text = ''
#!${pkgs.bash}/bin/bash
for file in ${authorizedKeysPath}/*; do
${pkgs.coreutils}/bin/cat "$file"
done
'';
};
services = {
openssh = {
enable = true;
ports = [ 1122 ];
hostKeys = [
{
path = "${rootSSHKeyPath}/root.manatee";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
};
authorizedKeysCommand = "/etc/ssh/authorized_keys_command";
authorizedKeysCommandUser = "root";
};
};
networking = {
firewall = {
allowedTCPPorts = [ 1122 ];
};
};
age.secrets = {
"root.manatee" = {
file = ../../../../secrets/manatee/root.manatee.age;
path = "${rootSSHKeyPath}/root.manatee";
};
"root.manatee.pub" = {
file = ../../../../secrets/manatee/root.manatee.pub.age;
path = "${rootSSHKeyPath}/root.manatee.pub";
};
"alex.pinwheel-manatee.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-manatee.pub.age;
path = "${authorizedKeysPath}/alex.pinwheel-manatee.pub";
};
"alex.backwards-manatee.pub" = {
file = ../../../../secrets/backwards/alex.backwards-manatee.pub.age;
path = "${authorizedKeysPath}/alex.backwards-manatee.pub";
};
"alex.manatee-git.ppp.pm" = {
file = ../../../../secrets/manatee/alex.manatee-git.ppp.pm.age;
path = "/home/alex/.ssh/alex.manatee-git.ppp.pm";
owner = "alex";
group = "users";
};
"alex.manatee-git.ppp.pm.pub" = {
file = ../../../../secrets/manatee/alex.manatee-git.ppp.pm.pub.age;
path = "/home/alex/.ssh/alex.manatee-git.ppp.pm.pub";
owner = "alex";
group = "users";
};
};
};
}

View File

@@ -1,61 +0,0 @@
{ lib, config, ... }:
let
enabled = config.mod.syncthing.enable;
in
{
options = {
mod.syncthing = {
enable = lib.mkEnableOption "Enable syncthing module";
};
};
config = lib.mkIf enabled {
services.syncthing = {
enable = true;
cert = config.age.secrets.syncthing-cert.path;
key = config.age.secrets.syncthing-key.path;
user = "storage";
group = "storage";
dataDir = "/mnt/sync/public";
guiAddress = "0.0.0.0:8384";
settings = {
gui = {
user = "syncthing";
password = "$2a$12$YBcqhl8AXpoLmIWikuMtkOQLcrPXKKj0xY/qy4hggWnfjeVLQ3Ct6";
insecureSkipHostcheck = false;
};
devices = {
pinwheel.id = config.lib.syncthing.pinwheel;
};
folders = {
org = {
path = "/mnt/sync/public/org";
devices = [
"pinwheel"
];
versioning = {
type = "staggered";
params = {
maxage = "2592000"; # 30 days
};
};
};
};
};
};
age = {
secrets = {
"syncthing-cert".file = ../../../../secrets/manatee/syncthing-cert.age;
"syncthing-key".file = ../../../../secrets/manatee/syncthing-key.age;
};
};
};
}

View File

@@ -1,17 +1,15 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [ imports =
../../config-manager/default.nix [
../../nix-wrapper/default.nix ../../config-manager/default.nix
../../shared-modules/syncthing.nix ../../nix-wrapper/default.nix
./hardware-configuration.nix ../../shared-modules/syncthing.nix
./modules ./hardware-configuration.nix
]; ./modules
];
nix.settings.experimental-features = [ nix.settings.experimental-features = [ "nix-command" "flakes" ];
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
users.users.alex = { users.users.alex = {

View File

@@ -1,47 +1,31 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ { config, lib, modulesPath, ... }:
config,
lib,
modulesPath,
...
}:
{ {
imports = [ imports =
(modulesPath + "/installer/scan/not-detected.nix") [ (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
"xhci_pci"
"thunderbolt"
"nvme"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ]; boot.kernelModules = [ ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = { fileSystems."/" =
device = "/dev/disk/by-uuid/9c3ef2ad-0244-4310-9984-2e548ced3e22"; { device = "/dev/disk/by-uuid/9c3ef2ad-0244-4310-9984-2e548ced3e22";
fsType = "ext4"; fsType = "ext4";
}; };
boot.initrd.luks.devices."luks-f569d036-e500-4839-bc78-ce4b032840d8".device = "/dev/disk/by-uuid/f569d036-e500-4839-bc78-ce4b032840d8"; boot.initrd.luks.devices."luks-f569d036-e500-4839-bc78-ce4b032840d8".device = "/dev/disk/by-uuid/f569d036-e500-4839-bc78-ce4b032840d8";
fileSystems."/boot" = { fileSystems."/boot" =
device = "/dev/disk/by-uuid/FCAE-6849"; { device = "/dev/disk/by-uuid/FCAE-6849";
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = [ swapDevices = [ ];
{
device = "/swapfile";
size = 48 * 1024; # 48GB
}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's

View File

@@ -14,9 +14,6 @@
home.homeDirectory = "/home/alex"; home.homeDirectory = "/home/alex";
home.packages = [ home.packages = [
inputs.whib-backend.packages.${pkgs.system}.whib-import
# pkgs.beekeeper-studio
pkgs.bitwarden-desktop
pkgs.gimp pkgs.gimp
pkgs.zip pkgs.zip
pkgs.unar pkgs.unar
@@ -25,7 +22,7 @@
pkgs.htop pkgs.htop
pkgs.onlyoffice-bin pkgs.onlyoffice-bin
pkgs.wdisplays pkgs.wdisplays
pkgs.vlc pkgs.postman
]; ];
home.stateVersion = "23.05"; home.stateVersion = "23.05";

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.bluetooth.enable; enabled = config.mod.bluetooth.enable;
in in
@@ -42,87 +37,77 @@ in
threshold = "30"; threshold = "30";
}; };
in in
{ {
timers = timers =
let let
mkTimer = device: { mkTimer = device: {
name = "notify-low-battery-for-${device.name}"; name = "notify-low-battery-for-${device.name}";
value = { value = {
unitConfig = { unitConfig = {
Description = "notify-battery-low timer for '${device.name}'"; Description = "notify-battery-low timer for '${device.name}'";
}; };
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
timerConfig = { timerConfig = {
Unit = "notify-low-battery-for-${device.name}.service"; Unit = "notify-low-battery-for-${device.name}.service";
OnCalendar = "*-*-* *:00:00"; # Every hour OnCalendar = "*-*-* *:00:00"; # Every hour
Persistent = true; Persistent = true;
};
}; };
}; };
}; in
in builtins.listToAttrs (builtins.map mkTimer [ trackpad headphones ]);
builtins.listToAttrs (
builtins.map mkTimer [
trackpad
headphones
]
);
services = services =
let let
mkService = device: { mkService = device: {
name = "notify-low-battery-for-${device.name}"; name = "notify-low-battery-for-${device.name}";
value = { value = {
unitConfig = { unitConfig = {
Description = "check battery level of '${device.name}'"; Description = "check battery level of '${device.name}'";
}; };
wantedBy = [ "default.target" ]; wantedBy = [ "default.target" ];
serviceConfig = { serviceConfig = {
Type = "exec"; Type = "exec";
}; };
path = [ path = [
pkgs.upower pkgs.upower
pkgs.gawk pkgs.gawk
pkgs.bc pkgs.bc
pkgs.libnotify pkgs.libnotify
]; ];
script = '' script = ''
CONNECTED=$(upower --show-info /org/freedesktop/UPower/devices/${device.id} | grep native-path | awk '{print $2}') CONNECTED=$(upower --show-info /org/freedesktop/UPower/devices/${device.id} | grep native-path | awk '{print $2}')
[ "$CONNECTED" == "(null)" ] && exit 0 [ "$CONNECTED" == "(null)" ] && exit 0
CHECKING="/tmp/checking-dismiss-low-battery-${device.id}" CHECKING="/tmp/checking-dismiss-low-battery-${device.id}"
[ ! -f "$CHECKING" ] && touch $CHECKING || exit 0 [ ! -f "$CHECKING" ] && touch $CHECKING || exit 0
DISMISSED="/tmp/dismiss-low-battery-${device.id}" DISMISSED="/tmp/dismiss-low-battery-${device.id}"
PERCENT=$(upower --show-info /org/freedesktop/UPower/devices/${device.id} | grep percentage | grep -o '[0-9]*') PERCENT=$(upower --show-info /org/freedesktop/UPower/devices/${device.id} | grep percentage | grep -o '[0-9]*')
if (( $(echo "$PERCENT < ${device.threshold}" | bc) )); then if (( $(echo "$PERCENT < ${device.threshold}" | bc) )); then
echo "'${device.name}' is under threshold. battery = $PERCENT% - threshold = ${device.threshold}%" echo "'${device.name}' is under threshold. battery = $PERCENT% - threshold = ${device.threshold}%"
if [ ! -f "$DISMISSED" ]; then if [ ! -f "$DISMISSED" ]; then
DISMISS=$(notify-send --expire-time 0 "Low battery" "${device.name} has $PERCENT% battery" --action=dismiss=Dismiss) DISMISS=$(notify-send --expire-time 0 "Low battery" "${device.name} has $PERCENT% battery" --action=dismiss=Dismiss)
[ "$DISMISS" == "dismiss" ] && touch $DISMISSED && echo "'${device.name}' dismissed" [ "$DISMISS" == "dismiss" ] && touch $DISMISSED && echo "'${device.name}' dismissed"
fi
else
echo "'${device.name}' is over threshold. battery = $PERCENT% - threshold = ${device.threshold}%"
[ -f "$DISMISSED" ] && rm $DISMISSED && echo "'${device.name}' undismissed"
fi fi
else
echo "'${device.name}' is over threshold. battery = $PERCENT% - threshold = ${device.threshold}%"
[ -f "$DISMISSED" ] && rm $DISMISSED && echo "'${device.name}' undismissed"
fi
rm $CHECKING rm $CHECKING
''; '';
};
}; };
}; in
in builtins.listToAttrs (builtins.map mkService [ trackpad headphones ]);
builtins.listToAttrs ( };
builtins.map mkService [
trackpad
headphones
]
);
};
}; };
} }

View File

@@ -1,10 +1,4 @@
{ { inputs, pkgs, lib, config, ... }:
inputs,
pkgs,
lib,
config,
...
}:
let let
configurationLimit = config.mod.gc.configurationLimit; configurationLimit = config.mod.gc.configurationLimit;
in in

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.c.enable; enabled = config.mod.c.enable;
in in

View File

@@ -1,6 +1,6 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.alex = { home-manager.users.alex= {
home.packages = [ pkgs.ungoogled-chromium ]; home.packages = [ pkgs.ungoogled-chromium ];
}; };

View File

@@ -3,7 +3,7 @@
colors = { colors = {
foreground = "bd93f9"; foreground = "bd93f9";
foreground-dim = "644294"; foreground-dim = "644294";
background = "1E1E2F"; background = "1E2029";
gray = "3a3a3a"; gray = "3a3a3a";
warning = "ff6969"; warning = "ff6969";

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
dockerEnabled = config.mod.containers.docker.enable; dockerEnabled = config.mod.containers.docker.enable;
podmanEnabled = config.mod.containers.podman.enable; podmanEnabled = config.mod.containers.podman.enable;

View File

@@ -27,13 +27,13 @@ in
zsh.enable = true; zsh.enable = true;
openvpn.enable = true; openvpn.enable = true;
mullvad.enable = true;
c.enable = true; c.enable = true;
go.enable = true; go.enable = true;
rust.enable = true; rust.enable = true;
scala.enable = true; scala.enable = true;
python.enable = true; python.enable = true;
gleam.enable = true;
keyboard.enable = true; keyboard.enable = true;
containers = { containers = {

View File

@@ -9,6 +9,7 @@ in
nix-direnv.enable = true; nix-direnv.enable = true;
}; };
programs.direnv.enableZshIntegration = lib.mkIf zshEnabled true; programs.direnv.enableZshIntegration = lib.mkIf zshEnabled true;
}; };
} }

View File

@@ -7,6 +7,8 @@
settings = { settings = {
global = { global = {
monitor = 1; monitor = 1;
width = 300;
height = 300;
offset = "10x10"; offset = "10x10";
origin = "top-right"; origin = "top-right";
transparency = 10; transparency = 10;

View File

@@ -1,5 +1,5 @@
{ emacs, runCommand, ... }: { emacs, runCommand, ... }:
runCommand "default.el" { } '' runCommand "default.el" {} ''
cp ${./config.org} $TMPDIR/config.org cp ${./config.org} $TMPDIR/config.org
cd $TMPDIR cd $TMPDIR
${emacs}/bin/emacs --batch -Q \ ${emacs}/bin/emacs --batch -Q \
@@ -7,4 +7,4 @@ runCommand "default.el" { } ''
-f org-babel-tangle -f org-babel-tangle
mv config.el $out mv config.el $out
'' ''

View File

@@ -479,34 +479,7 @@ Setup prefix for keybindings.
* Flycheck * Flycheck
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package flycheck (use-package flycheck)
:preface
(defun mp-flycheck-eldoc (callback &rest _ignored)
"Print flycheck messages at point by calling CALLBACK."
(when-let ((flycheck-errors (and flycheck-mode (flycheck-overlay-errors-at (point)))))
(mapc
(lambda (err)
(funcall callback
(format "%s: %s"
(let ((level (flycheck-error-level err)))
(pcase level
('info (propertize "I" 'face 'flycheck-error-list-info))
('error (propertize "E" 'face 'flycheck-error-list-error))
('warning (propertize "W" 'face 'flycheck-error-list-warning))
(_ level)))
(flycheck-error-message err))
:thing (or (flycheck-error-id err)
(flycheck-error-group err))
:face 'font-lock-doc-face))
flycheck-errors)))
(defun mp-flycheck-prefer-eldoc ()
(add-hook 'eldoc-documentation-functions #'mp-flycheck-eldoc nil t)
(setq eldoc-documentation-strategy 'eldoc-documentation-compose-eagerly)
(setq flycheck-display-errors-function nil)
(setq flycheck-help-echo-function nil))
:hook ((flycheck-mode . mp-flycheck-prefer-eldoc)))
(use-package flycheck-eglot (use-package flycheck-eglot
:after (flycheck eglot) :after (flycheck eglot)
@@ -525,28 +498,15 @@ Setup prefix for keybindings.
) )
(defun alex/format-on-save () (defun alex/format-on-save ()
(let ((excluded-files '("secrets.nix"))) (add-hook 'before-save-hook #'eglot-format-buffer -10 t)
(unless (member (file-name-nondirectory buffer-file-name) excluded-files) )
(add-hook 'before-save-hook #'eglot-format-buffer -10 t))))
(use-package eglot (use-package eglot
:preface
(defun mp-eglot-eldoc ()
(setq eldoc-echo-area-use-multiline-p nil)
(setq eldoc-documentation-strategy
'eldoc-documentation-compose-eagerly))
:config :config
(add-to-list 'eglot-server-programs (add-to-list 'eglot-server-programs
'(scala-mode . '(scala-mode .
("metals" :initializationOptions (:isHttpEnabled t)))) ("metals" :initializationOptions (:isHttpEnabled t))))
(add-to-list 'eglot-server-programs
'(nix-mode . ("nixd")))
(add-to-list 'eglot-server-programs
'(gleam-ts-mode . ("gleam" "lsp")))
(setq-default eglot-workspace-configuration (setq-default eglot-workspace-configuration
'( '(
:metals ( :metals (
@@ -556,20 +516,12 @@ Setup prefix for keybindings.
) )
:hook ( :hook (
(eglot-managed-mode . mp-eglot-eldoc)
(go-mode . eglot-ensure) (go-mode . eglot-ensure)
(go-mode . alex/organize-imports-on-save) (go-mode . alex/organize-imports-on-save)
(go-mode . alex/format-on-save) (go-mode . alex/format-on-save)
(c-mode . eglot-ensure) (c-mode . eglot-ensure)
(nix-mode . eglot-ensure) (nix-mode . eglot-ensure)
(nix-mode . alex/format-on-save)
(gleam-ts-mode . eglot-ensure)
(gleam-ts-mode . alex/format-on-save)
(python-mode . eglot-ensure)
(javascript-mode . eglot-ensure) (javascript-mode . eglot-ensure)
(js-mode . eglot-ensure) (js-mode . eglot-ensure)
(js-jsx-mode . eglot-ensure) (js-jsx-mode . eglot-ensure)
@@ -589,6 +541,13 @@ Setup prefix for keybindings.
:after eglot :after eglot
:config (eglot-booster-mode)) :config (eglot-booster-mode))
#+END_SRC #+END_SRC
** Eldoc-box
#+BEGIN_SRC emacs-lisp
(use-package eldoc-box
:after eglot
:bind (:map eglot-mode-map
("M-h" . eldoc-box-help-at-point)))
#+END_SRC
** Go ** Go
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package go-mode (use-package go-mode
@@ -606,12 +565,6 @@ Setup prefix for keybindings.
) )
) )
#+END_SRC #+END_SRC
** Gleam
#+BEGIN_SRC emacs-lisp
(use-package gleam-ts-mode
:mode "\\.gleam\\'"
)
#+END_SRC
** YAML ** YAML
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package yaml-mode (use-package yaml-mode
@@ -643,8 +596,7 @@ Setup prefix for keybindings.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(setq (setq
js-indent-level 2 js-indent-level 2
js2-basic-offset 2 js2-basic-offset 2)
indent-tabs-mode nil)
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode)) (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
#+END_SRC #+END_SRC

View File

@@ -3,7 +3,7 @@ let
emacs = pkgs.emacsWithPackagesFromUsePackage { emacs = pkgs.emacsWithPackagesFromUsePackage {
package = pkgs.emacs-unstable; package = pkgs.emacs-unstable;
config = ./config.org; config = ./config.org;
defaultInitFile = pkgs.callPackage ./config.nix { }; defaultInitFile = pkgs.callPackage ./config.nix {};
alwaysEnsure = true; alwaysEnsure = true;
alwaysTangle = true; alwaysTangle = true;
@@ -40,9 +40,9 @@ in
home-manager.users.alex = { home-manager.users.alex = {
home.sessionVariables = { home.sessionVariables = {
EDITOR = "${e}/bin/e $@"; EDITOR = "${e}/bin/e $@";
VISUAL = "${e}/bin/e $@"; VISUAL = "${e}/bin/e $@";
TIG_EDITOR = "${e}/bin/e $@"; TIG_EDITOR = "${e}/bin/e $@";
}; };
home.packages = [ home.packages = [
@@ -51,7 +51,6 @@ in
emacs emacs
pkgs.wl-clipboard pkgs.wl-clipboard
pkgs.emacs-lsp-booster pkgs.emacs-lsp-booster
pkgs.nixd
]; ];
}; };

View File

@@ -29,14 +29,14 @@ let
ff = pkgs.writeShellApplication { ff = pkgs.writeShellApplication {
name = "ff"; name = "ff";
text = '' text = ''
${wrapped}/bin/firefox-devedition --ProfileManager ${wrapped}/bin/firefox --ProfileManager
''; '';
}; };
ff-alex = pkgs.writeShellApplication { ff-alex = pkgs.writeShellApplication {
name = "ff-alex"; name = "ff-alex";
text = '' text = ''
${wrapped}/bin/firefox-devedition -P alex --new-window "$@" ${wrapped}/bin/firefox -P alex --new-window "$@"
''; '';
}; };
@@ -59,7 +59,7 @@ in
name = "alex"; name = "alex";
isDefault = true; isDefault = true;
settings = sharedSettings // { }; settings = sharedSettings // {};
}; };
work = { work = {
@@ -109,14 +109,12 @@ in
configFile."mimeapps.list".force = true; configFile."mimeapps.list".force = true;
}; };
home.packages = [
ff home.packages = [ ff ff-alex ];
ff-alex
];
}; };
environment.variables = { environment.variables = {
MOZ_ENABLE_WAYLAND = 1; MOZ_ENABLE_WAYLAND=1;
BROWSER = "${ff-alex}/bin/ff-alex $@"; BROWSER = "${ff-alex}/bin/ff-alex $@";
}; };
} }

View File

@@ -2,9 +2,9 @@
{ {
fonts.packages = [ fonts.packages = [
pkgs.noto-fonts pkgs.noto-fonts
pkgs.noto-fonts-cjk-sans pkgs.noto-fonts-cjk
pkgs.noto-fonts-emoji pkgs.noto-fonts-emoji
pkgs.nerd-fonts.jetbrains-mono pkgs.nerdfonts
pkgs.liberation_ttf pkgs.liberation_ttf
]; ];
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.foot.enable; enabled = config.mod.foot.enable;

View File

@@ -1,6 +1,16 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ pkgs.brogue-ce ]; home.packages = [
pkgs.brogue-ce
(pkgs.retroarch.override {
cores = [
pkgs.libretro.genesis-plus-gx
pkgs.libretro.snes9x
pkgs.libretro.dolphin
];
})
];
}; };
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.git.enable; enabled = config.mod.git.enable;
in in

View File

@@ -5,6 +5,9 @@
[url "git@github.com:"] [url "git@github.com:"]
insteadOf = https://github.com/ insteadOf = https://github.com/
[url "git@gitlab.com:"]
insteadOf = https://gitlab.com/
[url "git@codeberg.org:"] [url "git@codeberg.org:"]
insteadOf = https://codeberg.org/ insteadOf = https://codeberg.org/

View File

@@ -1,25 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
enabled = config.mod.gleam.enable;
in
{
options = {
mod.gleam = {
enable = lib.mkEnableOption "enable gleam module";
};
};
config = lib.mkIf enabled {
home-manager.users.alex = {
home.packages = [
pkgs.gleam
pkgs.erlang
];
};
};
}

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.go.enable; enabled = config.mod.go.enable;
in in
@@ -15,14 +10,26 @@ in
}; };
config = lib.mkIf enabled { config = lib.mkIf enabled {
nixpkgs.overlays = let
buildGo122 = pkgs: pkg:
pkg.override { buildGoModule = pkgs.buildGo122Module; };
in
[
(final: prev: {
go = prev.go_1_22;
gopls = buildGo122 prev prev.gopls;
go-tools = buildGo122 prev prev.go-tools;
govulncheck = buildGo122 prev prev.govulncheck;
gotestsum = buildGo122 prev prev.gotestsum;
})
];
home-manager.users.alex = { home-manager.users.alex = {
programs.go = { programs.go = {
enable = true; enable = true;
package = pkgs.go; package = pkgs.go;
env = { goPath = "code/go";
GOPATH = "/home/alex/code/go";
};
}; };
home.packages = [ home.packages = [

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.greetd.enable; enabled = config.mod.greetd.enable;
in in
@@ -18,17 +13,16 @@ in
services.greetd = { services.greetd = {
enable = true; enable = true;
settings = settings = let
let session = {
session = { user = "alex";
user = "alex"; command = "${pkgs.hyprland}/bin/Hyprland";
command = "${pkgs.hyprland}/bin/Hyprland"; };
}; in
in
{ {
initial_session = session; initial_session = session;
default_session = session; default_session = session;
}; };
}; };
}; };
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.hyprland.enable; enabled = config.mod.hyprland.enable;
in in
@@ -25,14 +20,11 @@ in
extraConfig = '' extraConfig = ''
exec-once=waybar exec-once=waybar
exec-once=hyprctl setcursor Adwaita 24
env = GDK_DPI_SCALE,1.5 env = GDK_DPI_SCALE,1.5
env = HYPRCURSOR_THEME,Adwaita env = XCURSOR_SIZE,64
env = HYPRCURSOR_SIZE,24
monitor=eDP-1, 1920x1200, auto-center-down, 1 monitor=eDP-1, 1920x1200, 0x0, 1
monitor=HDMI-A-1, 2560x1440@100, auto-center-up, 1
workspace = 1, monitor:HDMI-A-1 workspace = 1, monitor:HDMI-A-1
workspace = 2, monitor:HDMI-A-1 workspace = 2, monitor:HDMI-A-1
@@ -45,13 +37,6 @@ in
workspace = 9, monitor:eDP-1 workspace = 9, monitor:eDP-1
workspace = 10, monitor:eDP-1 workspace = 10, monitor:eDP-1
workspace = w[tv1], gapsout:0, gapsin:0
workspace = f[1], gapsout:0, gapsin:0
windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
''; '';
@@ -70,7 +55,7 @@ in
# 2 - Cursor focus will be detached from keyboard focus. Clicking on a window will move keyboard focus to that window. # 2 - Cursor focus will be detached from keyboard focus. Clicking on a window will move keyboard focus to that window.
follow_mouse = 2; follow_mouse = 2;
sensitivity = 0.3; sensitivity = 0.30;
touchpad = { touchpad = {
natural_scroll = false; natural_scroll = false;
tap-and-drag = false; tap-and-drag = false;
@@ -85,7 +70,7 @@ in
general = { general = {
layout = "dwindle"; layout = "dwindle";
gaps_in = 0; # gaps between windows gaps_in = 0; # gaps between windows
gaps_out = 0; # gaps between windows and monitor edges gaps_out = 0; # gaps between windows and monitor edges
"col.active_border" = "rgba(${config.lib.colors.foreground}ff)"; "col.active_border" = "rgba(${config.lib.colors.foreground}ff)";
@@ -94,61 +79,57 @@ in
dwindle = { dwindle = {
force_split = 2; force_split = 2;
no_gaps_when_only = 1;
}; };
bind = bind = let
let ws = x:
ws = let n = if (x + 1) < 10
x: then (x + 1)
let else 0;
n = if (x + 1) < 10 then (x + 1) else 0; in
in
builtins.toString n; builtins.toString n;
select = builtins.genList (x: "$mod, ${ws x}, workspace, ${builtins.toString (x + 1)}") 10; select = builtins.genList (x: "$mod, ${ws x}, workspace, ${builtins.toString (x + 1)}") 10;
move = builtins.genList ( move = builtins.genList (x: "$mod SHIFT, ${ws x}, movetoworkspacesilent, ${builtins.toString (x + 1)}") 10;
x: "$mod SHIFT, ${ws x}, movetoworkspacesilent, ${builtins.toString (x + 1)}"
) 10;
magnifier = pkgs.writeShellScript "magnifier" '' magnifier = pkgs.writeShellScript "magnifier" ''
CURRENT=$(${pkgs.hyprland}/bin/hyprctl getoption cursor:zoom_factor -j | ${pkgs.jq}/bin/jq .float) CURRENT=$(${pkgs.hyprland}/bin/hyprctl getoption cursor:zoom_factor -j | ${pkgs.jq}/bin/jq .float)
DELTA=0.1 DELTA=0.1
UPDATED=1 UPDATED=1
case $1 in case $1 in
--increase) --increase)
UPDATED=$(echo $CURRENT + $DELTA | ${pkgs.bc}/bin/bc) ;; UPDATED=$(echo $CURRENT + $DELTA | ${pkgs.bc}/bin/bc) ;;
--decrease) --decrease)
UPDATED=$(echo $CURRENT - $DELTA | ${pkgs.bc}/bin/bc) ;; UPDATED=$(echo $CURRENT - $DELTA | ${pkgs.bc}/bin/bc) ;;
--reset) --reset)
UPDATED=1 UPDATED=1
esac esac
if (( $(echo "$UPDATED < 1" | bc) )); then UPDATED=1; fi if (( $(echo "$UPDATED < 1" | bc) )); then UPDATED=1; fi
${pkgs.hyprland}/bin/hyprctl keyword cursor:zoom_factor $UPDATED ${pkgs.hyprland}/bin/hyprctl keyword cursor:zoom_factor $UPDATED
''; '';
in in
select select ++ move ++ [
++ move "$mod, ESCAPE, killactive"
++ [
"$mod, ESCAPE, killactive"
"$mod, f, fullscreen, 1" "$mod, f, fullscreen, 1"
"$mod SHIFT, f, togglefloating, active" "$mod SHIFT, f, togglefloating, active"
"$mod, h, movefocus, l" "$mod, h, movefocus, l"
"$mod, j, movefocus, d" "$mod, j, movefocus, d"
"$mod, k, movefocus, u" "$mod, k, movefocus, u"
"$mod, l, movefocus, r" "$mod, l, movefocus, r"
"$mod CONTROL, 1, exec, ${magnifier} --increase" "$mod CONTROL, 1, exec, ${magnifier} --increase"
"$mod CONTROL, 2, exec, ${magnifier} --decrease" "$mod CONTROL, 2, exec, ${magnifier} --decrease"
"$mod CONTROL, 3, exec, ${magnifier} --reset" "$mod CONTROL, 3, exec, ${magnifier} --reset"
]; ];
bindm = [ bindm = [
# mouse movements # mouse movements
"$mod, mouse:272, movewindow" # left click "$mod, mouse:272, movewindow" # left click
"$mod, mouse:273, resizewindow" # right click "$mod, mouse:273, resizewindow" # right click
]; ];
@@ -180,5 +161,84 @@ in
# openGL is needed for wayland/hyprland # openGL is needed for wayland/hyprland
hardware.graphics.enable = true; hardware.graphics.enable = true;
systemd.user.services.hyprland-monitors = {
# systemctl --user restart hyprland-monitors.service
# journalctl --user -u hyprland-monitors.service -e -f
unitConfig = {
Description = "handles hyprland monitor connect/disconnect";
};
wantedBy = [ "graphical-session.target" ];
requires = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
path = [
pkgs.coreutils # to include `cat`
pkgs.waybar
pkgs.hyprland
pkgs.socat
pkgs.jq
pkgs.bc
pkgs.libnotify
];
script = let
moveWSToMonitor = monitor: first: last:
if last < first
then throw "'first' has to be less than or equal to 'last'"
else
builtins.genList (n: "dispatch moveworkspacetomonitor ${builtins.toString (first + n)} ${monitor}") (last - first + 1);
external = moveWSToMonitor "HDMI-A-1" 1 5;
internal = moveWSToMonitor "eDPI-1" 6 10;
onlyInternal = moveWSToMonitor "eDPI-1" 1 10;
in
''
update() {
HDMI_STATUS=$(cat /sys/class/drm/card1-HDMI-A-1/status)
INTERNAL_WIDTH=1920
INTERNAL_HEIGHT=1200
if [ $HDMI_STATUS = "connected" ]; then
notify-send "Using external and laptop monitor"
hyprctl keyword monitor HDMI-A-1,preferred,0x0,1
HDMI=$(hyprctl monitors -j | jq '.[] | select(.name=="HDMI-A-1")')
HDMI_WIDTH=$(echo $HDMI | jq .width)
HDMI_HEIGHT=$(echo $HDMI | jq .height)
INTERNAL_POS_X=$(echo "($HDMI_WIDTH - $INTERNAL_WIDTH) / 2" | bc)
if (( $(echo "$INTERNAL_POS_X < 0" | bc) )); then INTERNAL_POS_X=0; fi
INTERNAL_POS_Y=$HDMI_HEIGHT
hyprctl keyword monitor eDP-1,$INTERNAL_WIDTH"x"$INTERNAL_HEIGHT,$INTERNAL_POS_X"x"$INTERNAL_POS_Y,1
hyprctl --batch "${lib.strings.concatStringsSep ";" (external ++ internal)}"
else
notify-send "Using only laptop monitor"
hyprctl --batch "keyword monitor HDMI-A,disable; keyword monitor eDP-1,$INTERNAL_WIDTH"x"$INTERNAL_HEIGHT,0x0,1"
hyprctl --batch "${lib.strings.concatStringsSep ";" onlyInternal}"
fi
}
handle() {
case $1 in
monitoradded\>\>*|monitorremoved\>\>*)
echo "handling event: \"$1\""
update ;;
esac
}
echo "Starting service with instance \"$HYPRLAND_INSTANCE_SIGNATURE\""
# Do initial configuration
update
socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do handle "$line"; done
'';
};
}; };
} }

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, ...}:
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ pkgs.nodePackages.typescript-language-server ]; home.packages = [ pkgs.nodePackages.typescript-language-server ];

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.keyboard.enable; enabled = config.mod.keyboard.enable;
in in

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;
in in

View File

@@ -0,0 +1,30 @@
{ pkgs, lib, config, ... }:
let
enabled = config.mod.mullvad.enable;
in
{
options = {
mod.mullvad = {
enable = lib.mkEnableOption "enable mullvad module";
};
};
config = lib.mkIf enabled {
services.mullvad-vpn = {
enable = true;
package = pkgs.mullvad-vpn;
};
age.secrets = {
"mullvad-device" = {
file = ../../../../secrets/pinwheel/mullvad-device.age;
path = "/etc/mullvad-vpn/device.json";
};
"mullvad-account-history" = {
file = ../../../../secrets/pinwheel/mullvad-account-history.age;
path = "/etc/mullvad-vpn/account-history.json";
};
};
};
}

View File

@@ -1,50 +0,0 @@
{
inputs,
pkgs,
lib,
config,
...
}:
let
hyprlandEnabled = config.mod.hyprland.enable;
in
{
home-manager.users.alex = {
wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled {
settings = {
bind =
let
prev = "${pkgs.playerctl}/bin/playerctl -p naviterm,spotify previous";
next = "${pkgs.playerctl}/bin/playerctl -p naviterm,spotify next";
in
[
", XF86AudioPrev, exec, ${prev}"
", XF86AudioNext, exec, ${next}"
", XF86AudioPlay, exec, ${pkgs.playerctl}/bin/playerctl -p naviterm,spotify play-pause"
", XF86AudioPause, exec, ${pkgs.playerctl}/bin/playerctl -p naviterm,spoitfy play-pause"
"$mod ALT, LEFT, exec, ${prev}"
"$mod ALT, RIGHT, exec, ${next}"
"$mod ALT, DOWN, exec, ${pkgs.playerctl}/bin/playerctl -p naviterm,spotify play-pause"
];
};
};
home.packages = [
pkgs.playerctl
pkgs.spotify
inputs.naviterm.packages.${pkgs.system}.default
];
};
systemd.user.services.playerctld = {
unitConfig = {
Description = "starts playerctld daemon";
};
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStart = "${pkgs.playerctl}/bin/playerctld";
};
};
}

View File

@@ -2,7 +2,7 @@
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ home.packages = [
pkgs.nixfmt-rfc-style pkgs.nil
pkgs.nix-tree pkgs.nix-tree
]; ];
}; };

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.openvpn.enable; enabled = config.mod.openvpn.enable;
in in
@@ -18,12 +13,13 @@ in
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ home.packages = [
pkgs.openvpn pkgs.openvpn
pkgs.update-systemd-resolved
]; ];
}; };
services.resolved = { services.resolved = {
enable = true; enable = false;
dnssec = "false"; dnssec = "true";
domains = [ "~." ]; domains = [ "~." ];
fallbackDns = [ fallbackDns = [
"1.1.1.1#one.one.one.one" "1.1.1.1#one.one.one.one"

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.physlock.enable; enabled = config.mod.physlock.enable;
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;
@@ -36,11 +31,11 @@ in
let let
pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause"; pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause";
in in
[ [
# will lock the screen with `physlock`, see `lockOn.suspend # will lock the screen with `physlock`, see `lockOn.suspend
"$mod SHIFT, x, exec, ${pause-music}; systemctl suspend" "$mod SHIFT, x, exec, ${pause-music}; systemctl suspend"
"$mod, x, exec, ${pause-music}; ${config.security.wrapperDir}/physlock -d -s -m" "$mod, x, exec, ${pause-music}; ${config.security.wrapperDir}/physlock -d -s -m"
]; ];
}; };
}; };
}; };

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.power.enable; enabled = config.mod.power.enable;
lowbat = config.mod.lowbat; lowbat = config.mod.lowbat;
@@ -44,8 +39,8 @@ in
enable = true; enable = true;
settings = { settings = {
START_CHARGE_THRESH_BAT0 = 75; START_CHARGE_THRESH_BAT0=75;
STOP_CHARGE_THRESH_BAT0 = 80; STOP_CHARGE_THRESH_BAT0=80;
}; };
}; };
}; };
@@ -63,7 +58,7 @@ in
Persistent = true; Persistent = true;
}; };
wantedBy = [ "timers.target" ]; wantedBy = ["timers.target"];
}; };
}; };
@@ -83,30 +78,28 @@ in
pkgs.swaylock pkgs.swaylock
]; ];
script = script = let
let pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause";
pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause"; in ''
in BATTERY_CAPACITY=$(cat /sys/class/power_supply/${lowbat.battery}/capacity)
'' BATTERY_STATUS=$(cat /sys/class/power_supply/${lowbat.battery}/status)
BATTERY_CAPACITY=$(cat /sys/class/power_supply/${lowbat.battery}/capacity) echo "Battery capacity: $BATTERY_CAPACITY"
echo "Battery status: $BATTERY_STATUS"
if [[ $BATTERY_CAPACITY -le ${builtins.toString lowbat.notifyCapacity} && $BATTERY_STATUS = "Discharging" ]]; then
notify-send --expire-time=0 --urgency=critical "Battery Low"
fi
if [[ $BATTERY_CAPACITY -le ${builtins.toString lowbat.suspendCapacity} && $BATTERY_STATUS = "Discharging" ]]; then
notify-send --expire-time=0 --urgency=critical "Battery Critically Low" "Suspending in 60 seconds if power is not plugged in"
sleep 60s
BATTERY_STATUS=$(cat /sys/class/power_supply/${lowbat.battery}/status) BATTERY_STATUS=$(cat /sys/class/power_supply/${lowbat.battery}/status)
echo "Battery capacity: $BATTERY_CAPACITY" if [[ $BATTERY_STATUS = "Discharging" ]]; then
echo "Battery status: $BATTERY_STATUS" ${pause-music}; ${pkgs.swaylock}/bin/swaylock -f; systemctl suspend
if [[ $BATTERY_CAPACITY -le ${builtins.toString lowbat.notifyCapacity} && $BATTERY_STATUS = "Discharging" ]]; then
notify-send --expire-time=0 --urgency=critical "Battery Low"
fi fi
fi
if [[ $BATTERY_CAPACITY -le ${builtins.toString lowbat.suspendCapacity} && $BATTERY_STATUS = "Discharging" ]]; then '';
notify-send --expire-time=0 --urgency=critical "Battery Critically Low" "Suspending in 60 seconds if power is not plugged in"
sleep 60s
BATTERY_STATUS=$(cat /sys/class/power_supply/${lowbat.battery}/status)
if [[ $BATTERY_STATUS = "Discharging" ]]; then
${pause-music}; ${pkgs.swaylock}/bin/swaylock -f; systemctl suspend
fi
fi
'';
}; };
}; };
}; };

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.python.enable; enabled = config.mod.python.enable;
in in

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.rust.enable; enabled = config.mod.rust.enable;
in in

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.scala.enable; enabled = config.mod.scala.enable;

View File

@@ -1,10 +1,4 @@
{ { inputs, pkgs, lib, config, ...}:
inputs,
pkgs,
lib,
config,
...
}:
let let
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.scripts.enable; enabled = config.mod.scripts.enable;

View File

@@ -1,16 +1,11 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;
in in
{ {
users.users.alex.extraGroups = [ "audio" ]; users.users.alex.extraGroups = [ "audio" ];
services.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
@@ -25,26 +20,24 @@ in
home-manager.users.alex = { home-manager.users.alex = {
wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled { wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled {
settings = { settings = {
bind = bind = let
let toggle-output-mute = pkgs.writeShellScript "toggle-output-mute" ''
toggle-output-mute = pkgs.writeShellScript "toggle-output-mute" '' ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle MUTED=$(${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep MUTED | wc -l)
MUTED=$(${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep MUTED | wc -l) echo $MUTED > /sys/class/leds/platform::mute/brightness
echo $MUTED > /sys/class/leds/platform::mute/brightness '';
'';
toggle-input-mute = pkgs.writeShellScript "toggle-input-mute" '' toggle-input-mute = pkgs.writeShellScript "toggle-input-mute" ''
${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
MUTED=$(${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | grep MUTED | wc -l) MUTED=$(${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | grep MUTED | wc -l)
echo $MUTED > /sys/class/leds/platform::micmute/brightness echo $MUTED > /sys/class/leds/platform::micmute/brightness
''; '';
in in [
[ ", XF86AudioRaiseVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 2%+"
", XF86AudioRaiseVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 2%+" ", XF86AudioLowerVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%-"
", XF86AudioLowerVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%-" ", XF86AudioMute, exec, ${toggle-output-mute}"
", XF86AudioMute, exec, ${toggle-output-mute}" ", XF86AudioMicMute, exec, ${toggle-input-mute}"
", XF86AudioMicMute, exec, ${toggle-input-mute}" ];
];
}; };
}; };

View File

@@ -0,0 +1,41 @@
{ pkgs, lib, config, ... }:
let
hyprlandEnabled = config.mod.hyprland.enable;
in
{
home-manager.users.alex = {
wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled {
settings = {
bind = let
prev = "${pkgs.playerctl}/bin/playerctl -p spotify previous";
next = "${pkgs.playerctl}/bin/playerctl -p spotify next";
in [
", XF86AudioPrev, exec, ${prev}"
", XF86AudioNext, exec, ${next}"
", XF86AudioPlay, exec, ${pkgs.playerctl}/bin/playerctl -p spotify play-pause"
", XF86AudioPause, exec, ${pkgs.playerctl}/bin/playerctl -p spoitfy play-pause"
"$mod ALT, LEFT, exec, ${prev}"
"$mod ALT, RIGHT, exec, ${next}"
"$mod ALT, DOWN, exec, ${pkgs.playerctl}/bin/playerctl -p spotify play-pause"
];
};
};
home.packages = [
pkgs.playerctl
pkgs.spotify
];
};
systemd.user.services.playerctld = {
unitConfig = {
Description = "starts playerctld daemon";
};
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStart = "${pkgs.playerctl}/bin/playerctld";
};
};
}

View File

@@ -5,13 +5,6 @@
enable = true; enable = true;
matchBlocks = { matchBlocks = {
"manatee" = {
hostname = "manatee";
user = "alex";
identityFile = "/home/alex/.ssh/alex.pinwheel-manatee";
port = 1122;
};
"backwards" = { "backwards" = {
hostname = "backwards"; hostname = "backwards";
user = "alex"; user = "alex";
@@ -19,6 +12,26 @@
port = 1122; port = 1122;
}; };
"sombrero.local" = {
hostname = "192.168.50.200";
user = "alex";
identityFile = "/home/alex/.ssh/alex.pinwheel-sombrero";
port = 1122;
};
"sombrero" = {
hostname = "sombrero.a2x.se";
user = "alex";
identityFile = "/home/alex/.ssh/alex.pinwheel-sombrero";
port = 1122;
};
"andromeda" = {
hostname = "andromeda.a2x.se";
user = "alex";
identityFile = "/home/alex/.ssh/alex.pinwheel-andromeda";
};
"tadpole" = { "tadpole" = {
hostname = "65.21.106.222"; hostname = "65.21.106.222";
user = "alex"; user = "alex";
@@ -47,19 +60,6 @@
}; };
age.secrets = { age.secrets = {
"alex.pinwheel-manatee" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-manatee.age;
path = "/home/alex/.ssh/alex.pinwheel-manatee";
owner = "alex";
group = "users";
};
"alex.pinwheel-manatee.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-manatee.pub.age;
path = "/home/alex/.ssh/alex.pinwheel-manatee.pub";
owner = "alex";
group = "users";
};
"alex.pinwheel-backwards" = { "alex.pinwheel-backwards" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-backwards.age; file = ../../../../secrets/pinwheel/alex.pinwheel-backwards.age;
path = "/home/alex/.ssh/alex.pinwheel-backwards"; path = "/home/alex/.ssh/alex.pinwheel-backwards";
@@ -72,6 +72,18 @@
owner = "alex"; owner = "alex";
group = "users"; group = "users";
}; };
"alex.pinwheel-sombrero" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-sombrero.age;
path = "/home/alex/.ssh/alex.pinwheel-sombrero";
owner = "alex";
group = "users";
};
"alex.pinwheel-sombrero.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-sombrero.pub.age;
path = "/home/alex/.ssh/alex.pinwheel-sombrero.pub";
owner = "alex";
group = "users";
};
"alex.pinwheel-github.com" = { "alex.pinwheel-github.com" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-github.com.age; file = ../../../../secrets/pinwheel/alex.pinwheel-github.com.age;
@@ -101,7 +113,7 @@
"alex.pinwheel-git.ppp.pm" = { "alex.pinwheel-git.ppp.pm" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-git.ppp.pm.age; file = ../../../../secrets/pinwheel/alex.pinwheel-git.ppp.pm.age;
path = "/home/alex/.ssh/alex.pinwheel-git.ppp.pm"; path = "/home/alex/.ssh/alex.pinwheel-git.ppp.pm.org";
owner = "alex"; owner = "alex";
group = "users"; group = "users";
}; };
@@ -112,6 +124,19 @@
group = "users"; group = "users";
}; };
"alex.pinwheel-andromeda" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-andromeda.age;
path = "/home/alex/.ssh/alex.pinwheel-andromeda";
owner = "alex";
group = "users";
};
"alex.pinwheel-andromeda.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-andromeda.pub.age;
path = "/home/alex/.ssh/alex.pinwheel-andromeda.pub";
owner = "alex";
group = "users";
};
"alex.pinwheel-tadpole" = { "alex.pinwheel-tadpole" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole.age; file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole.age;
path = "/home/alex/.ssh/alex.pinwheel-tadpole"; path = "/home/alex/.ssh/alex.pinwheel-tadpole";
@@ -130,11 +155,9 @@
enable = true; enable = true;
ports = [ 1122 ]; ports = [ 1122 ];
hostKeys = [ hostKeys = [{
{ path = "/etc/ssh/pinwheel";
path = "/etc/ssh/pinwheel"; type = "ed25519";
type = "ed25519"; }];
}
];
}; };
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.swaylock.enable; enabled = config.mod.swaylock.enable;
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;
@@ -35,19 +30,18 @@ in
wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled { wayland.windowManager.hyprland = lib.mkIf hyprlandEnabled {
settings = { settings = {
bind = bind = let
let pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause";
pause-music = "${pkgs.playerctl}/bin/playerctl -p spotify pause";
dpmsTimeout = config.mod.swaylock.dpmsTimeout; dpmsTimeout = config.mod.swaylock.dpmsTimeout;
dpms-lock = pkgs.writeShellScript "dpms-lock" '' dpms-lock = pkgs.writeShellScript "dpms-lock" ''
${pkgs.swayidle}/bin/swayidle \ ${pkgs.swayidle}/bin/swayidle \
timeout ${dpmsTimeout} "${pkgs.hyprland}/bin/hyprctl dispatch dpms off" \ timeout ${dpmsTimeout} "${pkgs.hyprland}/bin/hyprctl dispatch dpms off" \
resume "${pkgs.hyprland}/bin/hyprctl dispatch dpms on" & resume "${pkgs.hyprland}/bin/hyprctl dispatch dpms on" &
${pkgs.swaylock}/bin/swaylock && ${pkgs.procps}/bin/pkill swayidle ${pkgs.swaylock}/bin/swaylock && ${pkgs.procps}/bin/pkill swayidle
''; '';
in in
[ [
"$mod, x, exec, ${pause-music}; ${dpms-lock}" "$mod, x, exec, ${pause-music}; ${dpms-lock}"
"$mod SHIFT, x, exec, ${pause-music}; ${pkgs.swaylock}/bin/swaylock -f; systemctl suspend" "$mod SHIFT, x, exec, ${pause-music}; ${pkgs.swaylock}/bin/swaylock -f; systemctl suspend"

View File

@@ -16,17 +16,13 @@
devices = { devices = {
phone.id = config.lib.syncthing.phone; phone.id = config.lib.syncthing.phone;
backwards.id = config.lib.syncthing.backwards; backwards.id = config.lib.syncthing.backwards;
manatee.id = config.lib.syncthing.manatee; sombrero.id = config.lib.syncthing.sombrero;
}; };
folders = { folders = {
org = { org = {
path = "/home/alex/sync/org"; path = "/home/alex/sync/org";
devices = [ devices = [ "sombrero" "phone" "backwards" ];
"phone"
"backwards"
"manatee"
];
versioning = { versioning = {
type = "staggered"; type = "staggered";
params = { params = {
@@ -37,7 +33,7 @@
personal = { personal = {
path = "/home/alex/sync/personal"; path = "/home/alex/sync/personal";
devices = [ "backwards" ]; devices = [ "sombrero" "backwards" ];
versioning = { versioning = {
type = "staggered"; type = "staggered";
params = { params = {
@@ -48,7 +44,7 @@
work = { work = {
path = "/home/alex/sync/work"; path = "/home/alex/sync/work";
devices = [ "backwards" ]; devices = [ "sombrero" "backwards" ];
versioning = { versioning = {
type = "staggered"; type = "staggered";
params = { params = {
@@ -58,8 +54,8 @@
}; };
books = { books = {
path = "/home/alex/sync/reading-material/books"; path = "/home/alex/sync/books";
devices = [ "backwards" ]; devices = [ "sombrero" "backwards" ];
versioning = { versioning = {
type = "staggered"; type = "staggered";
params = { params = {

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, ...}:
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.packages = [ home.packages = [

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.vm.enable; enabled = config.mod.vm.enable;
in in
@@ -17,10 +12,7 @@ in
config = lib.mkIf enabled { config = lib.mkIf enabled {
virtualisation = { virtualisation = {
spiceUSBRedirection.enable = true; # Allow redirecting USB to the VM spiceUSBRedirection.enable = true; # Allow redirecting USB to the VM
libvirtd = { libvirtd.enable = true;
enable = true;
qemu.vhostUserPackages = [ pkgs.virtiofsd ];
};
}; };
users.users.alex = { users.users.alex = {
@@ -34,8 +26,8 @@ in
home-manager.users.alex = { home-manager.users.alex = {
dconf.settings = { dconf.settings = {
"org/virt-manager/virt-manager/connections" = { "org/virt-manager/virt-manager/connections" = {
autoconnect = [ "qemu:///system" ]; autoconnect = ["qemu:///system"];
uris = [ "qemu:///system" ]; uris = ["qemu:///system"];
}; };
}; };
}; };

View File

@@ -1,20 +1,15 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
hyprlandEnabled = config.mod.hyprland.enable; hyprlandEnabled = config.mod.hyprland.enable;
music-status = pkgs.writeShellScript "music-status" '' spotify-status = pkgs.writeShellScript "spotify-status" ''
STATUS=$(${pkgs.playerctl}/bin/playerctl -p naviterm,spotify status 2>&1) STATUS=$(${pkgs.playerctl}/bin/playerctl -p spotify status 2>&1)
if [ "$STATUS" = "No players found" ]; then if [ "$STATUS" = "No players found" ]; then
echo "" echo ""
else else
FORMAT="{{markup_escape(xesam:title)}} - {{markup_escape(xesam:artist)}}" FORMAT="{{markup_escape(xesam:title)}} - {{markup_escape(xesam:artist)}}"
OUTPUT=$(${pkgs.playerctl}/bin/playerctl -p naviterm,spotify metadata --format "$FORMAT") OUTPUT=$(${pkgs.playerctl}/bin/playerctl -p spotify metadata --format "$FORMAT")
case "$STATUS" in case "$STATUS" in
"Playing") "Playing")
echo "<span font='14' rise='-3000'></span> $OUTPUT" echo "<span font='14' rise='-3000'></span> $OUTPUT"
@@ -40,47 +35,49 @@ let
fi fi
''; '';
tailscale = pkgs.writeShellScript "tailscale" '' mullvad = pkgs.writeShellScript "mullvad" ''
STATUS_STOPPED="Tailscale is stopped." STATUS_DISCONNECTING="Disconnecting"
STATUS_DISCONNECTED="Disconnected"
STATUS_CONNECTING="Connecting"
STATUS_CONNECTED="Connected"
status() {
STATUS=$(${pkgs.mullvad}/bin/mullvad status | ${pkgs.gawk}/bin/awk 'NR==1{print $1}')
echo $STATUS
}
output() { output() {
STATUS=$(tailscale status) case $(status) in
$STATUS_DISCONNECTED)
case $STATUS in echo '{ "text": "", "class": "disconnected" }' ;;
$STATUS_STOPPED) $STATUS_CONNECTING)
echo '{ "text": "", "class": "disconnected" }' ;; echo '{ "text": "", "tooltip": "Connecting", "class": "disconnected" }' ;;
$STATUS_CONNECTED)
TOOLTIP=$(${pkgs.mullvad}/bin/mullvad status | ${pkgs.gawk}/bin/awk 'NR==1')
echo "{ \"text\": \"\", \"tooltip\":\"$TOOLTIP\" }" ;;
$STATUS_DISCONNECTING)
echo '{ "text": "", "tooltip": "Disconnecting", "class": "disconnected" }' ;;
*) *)
EXIT_NODE=$(tailscale status --json | ${pkgs.jq}/bin/jq .ExitNodeStatus) echo '{ "text": "", "tooltip": "Status unknown", "class": "disconnected" }' ;;
esac
}
EXIT_NODE_ONLINE=$(echo $EXIT_NODE | ${pkgs.jq}/bin/jq .Online) toggle() {
if [ "$EXIT_NODE_ONLINE" == "null" ]; then CURRENT_STATUS=$(status)
echo '{ "text": "", "class": "disconnected" }'
exit 0
fi
EXIT_NODE_ID=$(echo $EXIT_NODE | ${pkgs.jq}/bin/jq .ID) case "$CURRENT_STATUS" in
EXIT_NODE_NAME=$(tailscale status --json | ${pkgs.jq}/bin/jq ".Peer.[] | select(.ID == $EXIT_NODE_ID) | .HostName") $STATUS_DISCONNECTED)
echo "{ \"text\": \"\", \"tooltip\": $EXIT_NODE_NAME }" ${pkgs.mullvad}/bin/mullvad connect --wait > /dev/null && ${pkgs.libnotify}/bin/notify-send "Connected to VPN";;
;; $STATUS_CONNECTED)
${pkgs.mullvad}/bin/mullvad disconnect --wait > /dev/null && ${pkgs.libnotify}/bin/notify-send "Disconnected from VPN";;
esac esac
} }
toggle-exit-node() {
PREFERRED_EXIT_NODE=$(${pkgs.coreutils}/bin/cat ${config.age.secrets.tailscale-preferred-exit-node.path})
EXIT_NODE_ONLINE=$(tailscale status --json | ${pkgs.jq}/bin/jq .ExitNodeStatus.Online)
if [ "$EXIT_NODE_ONLINE" == "true" ]; then
tailscale set --exit-node="" && ${pkgs.libnotify}/bin/notify-send "Disconnected from Exit Node"
else
tailscale set --exit-node=$PREFERRED_EXIT_NODE && ${pkgs.libnotify}/bin/notify-send "Connected to Exit Node"
fi
}
case $1 in case $1 in
--toggle-exit-node) --toggle)
toggle-exit-node ;; toggle ;;
--output) --output)
output ;; output ;;
esac esac
''; '';
@@ -126,12 +123,12 @@ in
modules-left = lib.mkIf hyprlandEnabled [ "hyprland/workspaces" ]; modules-left = lib.mkIf hyprlandEnabled [ "hyprland/workspaces" ];
modules-right = [ modules-right = [
"custom/work-vpn-status" "custom/work-vpn-status"
"custom/music" "custom/spotify"
"custom/container-status" "custom/container-status"
"custom/dunst" "custom/dunst"
"custom/mullvad"
"bluetooth" "bluetooth"
"wireplumber" "wireplumber"
"custom/tailscale"
"network" "network"
"battery" "battery"
"clock" "clock"
@@ -139,12 +136,12 @@ in
"custom/work-vpn-status" = { "custom/work-vpn-status" = {
exec = "${work-vpn-status}"; exec = "${work-vpn-status}";
interval = 2; interval = 1;
}; };
"custom/music" = { "custom/spotify" = {
exec = music-status; exec = spotify-status;
interval = 2; interval = 1;
max-length = 70; max-length = 70;
tooltip = false; tooltip = false;
}; };
@@ -152,21 +149,21 @@ in
"custom/container-status" = { "custom/container-status" = {
exec = "${container-status}"; exec = "${container-status}";
return-type = "json"; return-type = "json";
interval = 2; interval = 1;
}; };
"custom/dunst" = { "custom/dunst" = {
exec = notifications-status; exec = notifications-status;
on-click-right = "${pkgs.dunst}/bin/dunstctl set-paused toggle"; on-click-right = "${pkgs.dunst}/bin/dunstctl set-paused toggle";
interval = 2; interval = 1;
tooltip = false; tooltip = false;
}; };
"custom/tailscale" = { "custom/mullvad" = {
exec = "${tailscale} --output"; exec = "${mullvad} --output";
return-type = "json"; return-type = "json";
on-click-right = "${tailscale} --toggle-exit-node"; on-click-right = "${mullvad} --toggle";
interval = 2; interval = 1;
}; };
bluetooth = { bluetooth = {
@@ -197,15 +194,8 @@ in
"interval" = 60; "interval" = 60;
"format" = "<span font='10' rise='1000'>{icon}</span> {capacity}%"; "format" = "<span font='10' rise='1000'>{icon}</span> {capacity}%";
"format-time" = "{H}h {M}min"; "format-time" = "{H}h {M}min";
"format-charging" = "󰂄 {capacity}%"; "format-charging" ="󰂄 {capacity}%";
"format-icons" = [ "format-icons" = ["󰁺" "󰁻" "󰁽" "󰁿" "󰂁" "󰁹" ];
"󰁺"
"󰁻"
"󰁽"
"󰁿"
"󰂁"
"󰁹"
];
}; };
"clock" = { "clock" = {
@@ -222,10 +212,7 @@ in
height = 30; height = 30;
spacing = 20; spacing = 20;
fixed-center = false; fixed-center = false;
output = [ output = [ "HDMI-A-1" ];
"HDMI-A-1"
"DP-3"
];
modules-left = lib.mkIf hyprlandEnabled [ "hyprland/workspaces" ]; modules-left = lib.mkIf hyprlandEnabled [ "hyprland/workspaces" ];
modules-right = [ modules-right = [
@@ -235,7 +222,7 @@ in
"custom/work-vpn-status" = { "custom/work-vpn-status" = {
exec = "${work-vpn-status}"; exec = "${work-vpn-status}";
interval = 2; interval = 1;
}; };
"clock" = { "clock" = {
@@ -280,11 +267,7 @@ in
color: #${config.lib.colors.warning}; color: #${config.lib.colors.warning};
} }
#custom-tailscale { #custom-mullvad.disconnected {
font-size: 30px;
}
#custom-tailscale.disconnected {
color: #${config.lib.colors.warning}; color: #${config.lib.colors.warning};
} }
@@ -303,12 +286,4 @@ in
''; '';
}; };
}; };
age.secrets = {
"tailscale-preferred-exit-node" = {
file = ../../../../secrets/pinwheel/tailscale-preferred-exit-node.age;
owner = "alex";
group = "users";
};
};
} }

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.wezterm.enable; enabled = config.mod.wezterm.enable;

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
gitEnabled = config.mod.git.enable; gitEnabled = config.mod.git.enable;
goEnabled = config.mod.go.enable; goEnabled = config.mod.go.enable;
@@ -12,24 +7,20 @@ in
{ {
home-manager.users.alex = { home-manager.users.alex = {
home.sessionVariables = { home.sessionVariables = {
GITHUB_ACTOR = "Alexander Heldt"; GITHUB_ACTOR="Alexander Heldt";
GITHUB_TOKEN = "$(${pkgs.coreutils}/bin/cat ${config.age.secrets.work-github-token.path})"; GITHUB_TOKEN="$(${pkgs.coreutils}/bin/cat ${config.age.secrets.work-github-token.path})";
}; };
home.packages = [ home.packages = [
# (pkgs.callPackage ./pants.nix { inherit (pkgs) system; }) (pkgs.callPackage ./syb-cli.nix {})
# (pkgs.callPackage ./syb-cli.nix { }) (pkgs.callPackage ./pants.nix {})
(pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-ultimate [ "ideavim" ]) (pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-ultimate [ "ideavim" ])
(pkgs.google-cloud-sdk.withExtraComponents [ pkgs.google-cloud-sdk.components.gke-gcloud-auth-plugin ])
(pkgs.google-cloud-sdk.withExtraComponents [ (pkgs.graphite-cli.overrideAttrs(_: {
pkgs.google-cloud-sdk.components.gke-gcloud-auth-plugin version = "1.4.3";
]) }))
pkgs.xdg-utils # needed by graphite-cli
pkgs.graphite-cli
pkgs.postman
pkgs.grpcurl
# for `radio` # for `radio`
pkgs.go-mockery pkgs.go-mockery
@@ -37,9 +28,7 @@ in
]; ];
programs.go = lib.mkIf goEnabled { programs.go = lib.mkIf goEnabled {
env = { goPrivate = [ "$(${pkgs.coreutils}/bin/cat ${config.age.secrets.work-go-private.path})" ];
GOPRIVATE = [ "$(${pkgs.coreutils}/bin/cat ${config.age.secrets.work-go-private.path})" ];
};
}; };
programs.git = lib.mkIf gitEnabled { programs.git = lib.mkIf gitEnabled {

View File

@@ -1,69 +1,47 @@
{ {
system, fetchurl,
pkgs, pkgs,
lib, lib,
...
}: }:
let let
pname = "pants";
version = "0.12.0"; version = "0.12.0";
if_let = v: p: if lib.attrsets.matchAttrs p v then v else null; scie-pants = pkgs.stdenv.mkDerivation {
match = inherit pname version;
v: l: builtins.elemAt (lib.lists.findFirst (x: (if_let v (builtins.elemAt x 0)) != null) null l) 1;
package = match { platform = system; } [ src = fetchurl {
[ url = "https://github.com/pantsbuild/scie-pants/releases/download/v${version}/scie-${pname}-linux-x86_64";
{ platform = "aarch64-linux"; } hash = "sha256-9PjgobndxVqDTYGtw1HESrtzwzH2qE9zFwR26xtwZrM=";
{ };
url = "https://github.com/pantsbuild/scie-pants/releases/download/v${version}/scie-pants-linux-aarch64";
hash = lib.fakeSha256;
}
]
[
{ platform = "x86_64-linux"; }
{
url = "https://github.com/pantsbuild/scie-pants/releases/download/v${version}/scie-pants-linux-x86_64";
hash = "sha256-9PjgobndxVqDTYGtw1HESrtzwzH2qE9zFwR26xtwZrM=";
}
]
[
{ platform = "aarch64-darwin"; }
{
url = "https://github.com/pantsbuild/scie-pants/releases/download/v${version}/scie-pants-macos-aarch64";
hash = "sha256-1Ha8GAOl7mWVunGKf7INMjar+jnLXaDEPStqE+kK3D4=";
}
]
];
unpatched = pkgs.stdenv.mkDerivation { phases = ["installPhase" "patchPhase"];
name = "scie-pants";
version = version;
sourceRoot = ".";
phases = [
"installPhase"
"patchPhase"
];
src = pkgs.fetchurl package;
installPhase = '' installPhase = ''
runHook preInstall
mkdir -p $out/bin mkdir -p $out/bin
cp $src $out/bin/pants cp $src $out/bin/pants
chmod +x $out/bin/pants chmod +x $out/bin/pants
runHook postInstall
'';
};
patched = pkgs.buildFHSEnv {
name = "pants";
targetPackages = [ pkgs.python39 ];
runScript = "${unpatched}/bin/pants";
profile = ''
export NIX_SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
export SSL_CERT_FILE="/etc/ssl/certs/ca-bundle.crt"
''; '';
}; };
in in
if pkgs.stdenv.isDarwin then unpatched else patched pkgs.buildFHSUserEnv {
name = "pants";
targetPackages = with pkgs; [
python39
];
runScript = "${scie-pants}/bin/pants";
profile = ''
export NIX_SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
export SSL_CERT_FILE="/etc/ssl/certs/ca-bundle.crt"
'';
meta = with lib; {
description = "Protects your Pants from the elements";
homepage = "https://github.com/pantsbuild/scie-pants";
license = licenses.asl20;
maintainers = [];
platforms = [ "x86_64-linux" ];
mainProgram = "pants";
};
}

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.zsh.enable; enabled = config.mod.zsh.enable;
in in
@@ -54,7 +49,7 @@ in
} }
]; ];
initContent = lib.strings.concatStringsSep "\n" [ initExtra = lib.strings.concatStringsSep "\n" [
"export KEYTIMEOUT=1" "export KEYTIMEOUT=1"
"bindkey -v '^?' backward-delete-char" "bindkey -v '^?' backward-delete-char"
"bindkey '^a' beginning-of-line" "bindkey '^a' beginning-of-line"

View File

@@ -0,0 +1,79 @@
{ pkgs, ... }:
{
imports =
[
../../config-manager/default.nix
../../shared-modules/syncthing.nix
./hardware-configuration.nix
./modules
];
nix.settings.experimental-features = [ "nix-command" "flakes" ];
nixpkgs.config.allowUnfree = true;
environment.variables.EDITOR = "vim";
hardware.enableRedistributableFirmware = true;
# Set your time zone.
time.timeZone = "Europe/Stockholm";
# Select internationalisation properties.
# i18n.defaultLocale = "en_US.UTF-8";
# console = {
# font = "Lat2-Terminus16";
# keyMap = "us";
# useXkbConfig = true; # use xkbOptions in tty.
# };
users = {
mutableUsers = false;
users.root = {
hashedPassword = "$6$3mkwaUWd8NA6XuEb$x80tETKGz6FEG.kej3v5Vh6hRNoC6bikhXogTP.zZwYtISA46JaN3RMK3ckbqt8Aj52d3krSLOfBaAR1qzuJ2/";
};
users."alex" = {
isNormalUser = true;
hashedPassword = "$6$3mkwaUWd8NA6XuEb$x80tETKGz6FEG.kej3v5Vh6hRNoC6bikhXogTP.zZwYtISA46JaN3RMK3ckbqt8Aj52d3krSLOfBaAR1qzuJ2/";
extraGroups = [ "wheel" ];
};
};
environment.systemPackages = with pkgs; [
gnumake
mkpasswd
vim
];
config-manager = {
flakePath = "/home/alex/config";
};
mod = {
git.enable = true;
ssh.enable = true;
docker.enable = true;
nginx.enable = true;
syncthing.enable = true;
plex.enable = true;
calibre-web.enable = true;
transmission.enable = true;
restic.enable = true;
pppdotpm-site.enable = false;
};
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
}

View File

@@ -0,0 +1,52 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "usb_storage" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/15329cb1-655e-475d-96f0-bfb8ccd05167";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/AD29-0697";
fsType = "vfat";
};
fileSystems."/home/alex/media" =
{ device = "/dev/disk/by-uuid/ad4acc0f-172c-40f8-8473-777c957e8764";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/home/alex/backup" =
{ device = "/dev/disk/by-uuid/34601701-65e6-4b2c-ac4d-8bef3dfd743f";
fsType = "ext4";
options = [ "nofail" ];
};
swapDevices =
[ { device = "/dev/disk/by-uuid/98c46b15-7efe-43fd-8812-7e2c01f5a40a"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eth0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
}

View File

@@ -1,4 +1,4 @@
{ inputs, ... }: { inputs, pkgs, ... }:
{ {
imports = [ inputs.home-manager.nixosModules.home-manager ]; imports = [ inputs.home-manager.nixosModules.home-manager ];
@@ -13,10 +13,13 @@
home.username = "alex"; home.username = "alex";
home.homeDirectory = "/home/alex"; home.homeDirectory = "/home/alex";
home.packages = [ ]; home.packages = [
pkgs.unar
];
home.stateVersion = "24.11"; home.stateVersion = "22.11";
}; };
}; };
}; };
} }

View File

@@ -4,7 +4,7 @@
config = { config = {
age = { age = {
identityPaths = [ "/etc/ssh/manatee" ]; identityPaths = [ "/etc/ssh/sombrero" ];
}; };
environment.systemPackages = [ environment.systemPackages = [

View File

@@ -0,0 +1,25 @@
{ pkgs, ... }: {
boot = {
loader = {
grub.enable = false;
efi.canTouchEfiVariables = true;
raspberryPi = {
enable = true;
version = 4;
};
};
tmp = {
useTmpfs = true;
};
kernelPackages = pkgs.linuxPackages_rpi4;
kernelParams = [
"8250.nr_uarts=1"
"console=ttyAMA0,115200"
"console=tty1"
"cma=128M"
];
};
}

View File

@@ -0,0 +1,52 @@
{ lib, config, ... }:
let
enabled = config.mod.calibre-web.enable;
nginxEnabled = config.mod.nginx.enable;
in
{
options = {
mod.calibre-web = {
enable = lib.mkEnableOption "add calibre-web module";
};
};
config = lib.mkIf (enabled && nginxEnabled) {
services = {
calibre-web = {
enable = true;
user = "alex";
group = "users";
listen = {
ip = "127.0.0.1";
port = 8083;
};
options = {
calibreLibrary = "/home/alex/backup/books";
enableBookUploading = true;
};
};
};
networking = {
firewall = {
allowedTCPPorts = [ 8083 ];
};
};
services = {
nginx = {
virtualHosts."books.sombrero.a2x.se" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8083";
};
};
};
};
};
}

View File

@@ -0,0 +1,8 @@
{ lib, ... }:
let
toModulePath = dir: _: ./. + "/${dir}";
filterDirs = dirs: lib.attrsets.filterAttrs (_: type: type == "directory") dirs;
in
{
imports = lib.mapAttrsToList toModulePath (filterDirs (builtins.readDir ./.));
}

View File

@@ -0,0 +1,29 @@
{ pkgs, lib, config, ... }:
let
enabled = config.mod.docker.enable;
in
{
options = {
mod.docker = {
enable = lib.mkEnableOption "enable docker module";
};
};
config = lib.mkIf enabled {
virtualisation = {
docker = {
enable = true;
};
oci-containers = {
backend = "docker";
};
};
users.users.alex.extraGroups = [ "docker" ];
home-manager.users.alex = {
home.packages = [ pkgs.docker-compose ];
};
};
}

View File

@@ -1,9 +1,4 @@
{ { pkgs, lib, config, ... }:
pkgs,
lib,
config,
...
}:
let let
enabled = config.mod.git.enable; enabled = config.mod.git.enable;
in in
@@ -22,10 +17,6 @@ in
includes = [ includes = [
{ path = ./gitconfig; } { path = ./gitconfig; }
]; ];
extraConfig = {
rerere.enable = true;
};
}; };
home.packages = [ pkgs.tig ]; home.packages = [ pkgs.tig ];

View File

@@ -5,5 +5,6 @@
[url "git@github.com:"] [url "git@github.com:"]
insteadOf = https://github.com/ insteadOf = https://github.com/
[url "gitea@git.ppp.pm:"] [url "git@codeberg.org:"]
insteadOf = https://git.ppp.pm/ insteadOf = https://codeberg.org/

View File

@@ -0,0 +1,6 @@
{ ... }:
{
services.mullvad-vpn = {
enable = true;
};
}

View File

@@ -0,0 +1,18 @@
{
networking = {
hostName = "sombrero";
defaultGateway = "192.168.50.1";
nameservers = [ "8.8.8.8" ];
interfaces = {
eth0 = {
ipv4 = {
addresses = [{
address = "192.168.50.200";
prefixLength = 24;
}];
};
};
};
};
}

View File

@@ -5,11 +5,21 @@ in
{ {
options = { options = {
mod.nginx = { mod.nginx = {
enable = lib.mkEnableOption "Enable nginx module"; enable = lib.mkEnableOption "add nginx module";
}; };
}; };
config = lib.mkIf enabled { config = lib.mkIf enabled {
security = {
acme = {
acceptTerms = true;
defaults = {
email = "p@ppp.pm";
};
};
};
services = { services = {
nginx = { nginx = {
enable = true; enable = true;
@@ -18,5 +28,11 @@ in
recommendedTlsSettings = true; recommendedTlsSettings = true;
}; };
}; };
networking = {
firewall = {
allowedTCPPorts = [ 80 443 ];
};
};
}; };
} }

View File

@@ -0,0 +1,42 @@
{ lib, config, ... }:
let
enable = config.mod.plex.enable;
dockerEnabled = config.mod.docker.enable;
in
{
options = {
mod.plex = {
enable = lib.mkEnableOption "enable plex module";
};
};
config = lib.mkIf (enable && dockerEnabled) {
virtualisation = {
oci-containers.containers = {
plex = {
image = "linuxserver/plex";
autoStart = true;
environment = {
TZ = "Europe/Stockholm";
VERSION = "latest";
};
extraOptions = [ "--network=host" ];
volumes = [
"/home/alex/media/plex/db:/config"
"/home/alex/media/movies:/movies"
"/home/alex/media/tv:/tv"
];
};
};
};
networking = {
firewall = {
allowedTCPPorts = [ 32400 ];
};
};
};
}

View File

@@ -0,0 +1,33 @@
{ inputs, lib, config, ... }:
let
enabled = config.mod.pppdotpm-site.enable;
nginxEnabled = config.mod.nginx.enable;
in
{
imports = [ inputs.pppdotpm-site.nixosModules.default ];
options = {
mod.pppdotpm-site = {
enable = lib.mkEnableOption "enable ppp.pm site";
};
};
config = lib.mkIf (enabled && nginxEnabled) {
security.acme = {
certs = {
"ppp.pm" = {
webroot = "/var/lib/acme/acme-challenge/";
email = "p@ppp.pm";
group = "nginx";
};
};
};
services.pppdotpm-site = {
enable = true;
domain = "ppp.pm";
useACMEHost = "ppp.pm";
};
};
}

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