complete rework v2

This commit is contained in:
Nickolaj Jepsen 2025-02-03 07:55:17 +01:00
parent 16813aeef9
commit 7409e9ca10
106 changed files with 1522 additions and 403 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
result/ result/
secrets/yubikey-identity.txt

521
flake.lock generated
View file

@ -1,5 +1,52 @@
{ {
"nodes": { "nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1736955230,
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
"owner": "ryantm",
"repo": "agenix",
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"agenix-rekey": {
"inputs": {
"devshell": "devshell",
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
],
"pre-commit-hooks": "pre-commit-hooks",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1737808592,
"narHash": "sha256-zSr8rSnaDlsifQhKW6kLKr+zZj0h9jbx/DQ8V7PENhM=",
"owner": "oddlama",
"repo": "agenix-rekey",
"rev": "a1dcdd27ff12a24f0d3ac1fe016ed08e1a89291f",
"type": "github"
},
"original": {
"owner": "oddlama",
"repo": "agenix-rekey",
"type": "github"
}
},
"ags": { "ags": {
"inputs": { "inputs": {
"astal": "astal", "astal": "astal",
@ -62,7 +109,259 @@
"type": "github" "type": "github"
} }
}, },
"colmena": {
"inputs": {
"flake-compat": "flake-compat_2",
"flake-utils": "flake-utils",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs",
"stable": "stable"
},
"locked": {
"lastModified": 1734897875,
"narHash": "sha256-LLpiqfOGBippRax9F33kSJ/Imt8gJXb6o0JwSBiNHCk=",
"owner": "zhaofengli",
"repo": "colmena",
"rev": "a6b51f5feae9bfb145daa37fd0220595acb7871e",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "colmena",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1700795494,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat_3",
"nixpkgs": "nixpkgs_2",
"utils": "utils"
},
"locked": {
"lastModified": 1727447169,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
"type": "github"
},
"original": {
"owner": "serokell",
"repo": "deploy-rs",
"type": "github"
}
},
"devshell": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1738148035,
"narHash": "sha256-KYOATYEwaKysL3HdHdS5kbQMXvzS4iPJzJrML+3TKAo=",
"owner": "nix-community",
"repo": "disko",
"rev": "18d0a984cc2bc82cf61df19523a34ad463aa7f54",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1650374568,
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_3": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1736143030,
"narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@ -83,6 +382,27 @@
"type": "github" "type": "github"
} }
}, },
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"colmena",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729742964,
"narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixlib": { "nixlib": {
"locked": { "locked": {
"lastModified": 1736643958, "lastModified": 1736643958,
@ -98,6 +418,21 @@
"type": "github" "type": "github"
} }
}, },
"nixos-facter-modules": {
"locked": {
"lastModified": 1736931726,
"narHash": "sha256-aY55yiifyo1XPPpbpH0kWlV1g2dNGBlx6622b7OK8ks=",
"owner": "numtide",
"repo": "nixos-facter-modules",
"rev": "fa11d87b61b2163efbb9aed7b7a5ae0299e5ab9c",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nixos-facter-modules",
"type": "github"
}
},
"nixos-generators": { "nixos-generators": {
"inputs": { "inputs": {
"nixlib": "nixlib", "nixlib": "nixlib",
@ -121,16 +456,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1738023785, "lastModified": 1734119587,
"narHash": "sha256-BPHmb3fUwdHkonHyHi1+x89eXB3kA1jffIpwPVJIVys=", "narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
"owner": "nixos", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2b4230bf03deb33103947e2528cac2ed516c5c89", "rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-24.11", "ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -151,14 +486,182 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1702272962,
"narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1738023785,
"narHash": "sha256-BPHmb3fUwdHkonHyHi1+x89eXB3kA1jffIpwPVJIVys=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2b4230bf03deb33103947e2528cac2ed516c5c89",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735882644,
"narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "a5a961387e75ae44cc20f0a57ae463da5e959656",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix",
"agenix-rekey": "agenix-rekey",
"ags": "ags", "ags": "ags",
"astal": "astal_2", "astal": "astal_2",
"home-manager": "home-manager", "colmena": "colmena",
"deploy-rs": "deploy-rs",
"disko": "disko",
"flake-parts": "flake-parts_2",
"home-manager": "home-manager_2",
"nixos-facter-modules": "nixos-facter-modules",
"nixos-generators": "nixos-generators", "nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable" "nixpkgs-unstable": "nixpkgs-unstable",
"treefmt-nix": "treefmt-nix_2"
}
},
"stable": {
"locked": {
"lastModified": 1730883749,
"narHash": "sha256-mwrFF0vElHJP8X3pFCByJR365Q2463ATp2qGIrDUdlE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dba414932936fde69f0606b4f1d87c5bc0003ede",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735135567,
"narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1738070913,
"narHash": "sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "bebf27d00f7d10ba75332a0541ac43676985dea3",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
} }
} }
}, },

View file

@ -3,6 +3,7 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
colmena.url = "github:zhaofengli/colmena";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixos-generators = { nixos-generators = {
url = "github:nix-community/nixos-generators"; url = "github:nix-community/nixos-generators";
@ -12,6 +13,9 @@
url = "github:nix-community/home-manager/release-24.11"; url = "github:nix-community/home-manager/release-24.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
astal = { astal = {
url = "github:aylur/astal"; url = "github:aylur/astal";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -20,34 +24,44 @@
url = "github:aylur/ags"; url = "github:aylur/ags";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
deploy-rs.url = "github:serokell/deploy-rs";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
agenix-rekey.url = "github:oddlama/agenix-rekey";
agenix-rekey.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = { outputs = {flake-parts, ...} @ inputs:
nixpkgs, flake-parts.lib.mkFlake {inherit inputs;} (
nixpkgs-unstable, {
nixos-generators, withSystem,
home-manager, lib,
inputs,
... ...
} @ inputs: let }: {
system = "x86_64-linux"; systems = [
stateVersion = "24.11"; "x86_64-linux"
pkgs = nixpkgs.legacyPackages.${system}; "aarch64-linux"
mkSystem = username: machine:
nixpkgs.lib.nixosSystem {
system = system;
specialArgs = {inherit inputs username machine stateVersion;};
modules = [
(import (./machines + "/${machine}"))
home-manager.nixosModules.home-manager
nixos-generators.nixosModules.all-formats
]; ];
}; imports = [
in { inputs.agenix-rekey.flakeModule
# Available through 'nixos-rebuild --flake .#wsl' # ./parts/hosts/laptop
formatter.${system} = pkgs.alejandra; # ./parts/hosts/desktop
nixosConfigurations = { # ./parts/hosts/qemu
desktop = mkSystem "nickolaj" "desktop"; ./parts/hosts
qemu = mkSystem "nickolaj" "qemu"; # ./parts/vm.nix
}; ./parts/formatter.nix
}; ./parts/devshell.nix
];
_module.args.mylib = import ./lib {inherit lib withSystem inputs;};
}
);
} }

122
justfile
View file

@ -1,19 +1,24 @@
build-vm: [group('vm')]
@git add . vm-build:
git add .
echo "Building VM..." echo "Building VM..."
nix build .#nixosConfigurations.qemu.config.formats.qcow nix build .#vm
echo "VM built." echo "VM built."
@sudo chmod 777 result/nixos.qcow2 sudo chmod 777 result/nixos.qcow2
echo "VM permissions set." echo "VM permissions set."
reload-vm: build-vm [group('vm')]
@sleep 5 vm-reload:
echo "Reloading VM..." echo "Reloading VM..."
-virsh destroy nixos virsh destroy nixos
virsh start nixos virsh start nixos
echo "VM reloaded." echo "VM reloaded."
setup-vm: [group('vm')]
vm-switch: vm-build vm-reload
[group('vm')]
vm-init:
virsh pool-define-as nixos dir - - - - $HOME/.local/libvirt/images/nixos virsh pool-define-as nixos dir - - - - $HOME/.local/libvirt/images/nixos
virsh pool-build nixos virsh pool-build nixos
virsh pool-start nixos virsh pool-start nixos
@ -28,3 +33,104 @@ setup-vm:
--virt-type kvm \ --virt-type kvm \
--import \ --import \
--graphics spice --graphics spice
[group('vm')]
vm-destroy:
virsh destroy nixos
virsh pool-destroy nixos
virsh pool-undefine nixos
[group('nix')]
repl:
nix repl --show-trace ".#" nixpkgs
[group('deploy')]
deploy-gen-hw hostname target:
nix run github:nix-community/nixos-anywhere -- \
--flake .#{{ hostname }} \
--target-host {{ target }} \
--generate-hardware-config nixos-generate-config \
./parts/hosts/{{ hostname }}/hardware-configuration.nix
tmp_dir := "/tmp/secrets/" + uuid()
[group('deploy')]
deploy hostname target:
#!/usr/bin/env -S bash -e
git add .
# username=$(nix eval --raw .#nixosConfigurations.{{hostname}}.config.user.username)
# Unencrypt boot secrets
install -d -m755 {{ tmp_dir }}/etc/ssh/
install -d -m755 {{ tmp_dir }}/run/agenix/
just secret-echo ./secrets/hashed-user-password > {{ tmp_dir }}/run/agenix/hashed-user-password
just secret-echo ./secrets/luks-password > {{ tmp_dir }}/luks-password
just secret-echo ./secrets/hosts/{{ hostname }}/id_ed25519 > {{ tmp_dir }}/etc/ssh/ssh_host_ed25519_key
cp ./secrets/hosts/{{ hostname }}/id_ed25519.pub {{ tmp_dir }}/etc/ssh/ssh_host_ed25519_key.pub
echo "Unencrypted files:"
find {{ tmp_dir }} -type f
read -n 1 -p "Did age decrypt the secrets correctly? [y/n]" yn
if [ "$yn" != "y" ]; then
rm -rf {{ tmp_dir }}
exit 0
fi
find {{ tmp_dir }} -type f -exec chmod 600 {} \;
# Deploy
nix run github:nix-community/nixos-anywhere -- \
--flake .#{{ hostname }} \
--disk-encryption-keys /luks-password {{ tmp_dir }}/luks-password \
--extra-files {{ tmp_dir }} \
--target-host {{ target }}
# Clean up
echo "Cleaning secrets..."
rm -rf {{ tmp_dir }}
[group('deploy')]
deploy-switch hostname target:
nix run nixpkgs#nixos-rebuild -- \
--flake .#{{ hostname }} \
--target-host {{ target }} \
--use-remote-sudo \
--verbose \
switch
identifier := "./secrets/yubikey-identity.age"
_get_user host:
user := nix eval --raw .#nixosConfigurations.{{host}}.config.user.username
[group("secret")]
secret-import path:
#!/usr/bin/env bash
# load the file from the root system
cat {{ path }} | nix develop --quiet --command bash -c \
"rage -e -r -o secrets/{{ path }}.age -i {{ identifier }}"
[group('secret')]
secret-echo file:
nix develop --quiet --command bash -c \
"rage -d {{ file }}.age -i {{ identifier }}"
default := ""
[group('secret')]
secret-edit name=default:
nix run .#agenix-rekey.x86_64-linux.edit {{ name }}
[group('secret')]
secret-rekey:
nix develop --quiet --command bash -c \
"agenix rekey"
[group('secret')]
secret-new-ssh-key hostname $USER:
#!/usr/bin/env -S nix develop --quiet --command bash
mkdir -p secrets/hosts/{{ hostname }}
ssh-keygen -t ed25519 -f secrets/hosts/{{ hostname }}/id_ed25519 -C "${USER}@{{ hostname }}"
age-plugin-yubikey -e secrets/hosts/{{ hostname }}/id_ed25519 \
-o secrets/hosts/{{ hostname }}/id_ed25519.age
rm secrets/hosts/{{ hostname }}/id_ed25519

53
lib/builder.nix Normal file
View file

@ -0,0 +1,53 @@
args @ {
lib,
withSystem,
inputs,
...
}:
with lib; let
inherit (import ./. args) recursiveMerge;
mkBase = {system ? "x86_64-linux", ...}:
withSystem system (
{
pkgs,
system,
...
}: {
inherit system;
specialArgs = {inherit inputs pkgs;};
modules = [
inputs.disko.nixosModules.disko
inputs.home-manager.nixosModules.home-manager
];
}
);
mkNixos = args:
inputs.nixpkgs.lib.nixosSystem (recursiveMerge [
(mkBase args)
args
]);
in {
mkHosts = root: let
hosts = attrNames (filterAttrs (_: type: type == "directory") (builtins.readDir root));
hostDirs = builtins.listToAttrs (
lib.map (hostName: lib.nameValuePair hostName (lib.path.append root hostName)) hosts
);
hostResolved =
lib.mapAttrs (
_: hostDir: (lib.map (fileName: lib.path.append hostDir fileName) (attrNames (builtins.readDir hostDir)))
)
hostDirs;
hostsConfig = mapAttrs (_: configs: mkNixos {modules = configs;}) hostResolved;
in
hostsConfig;
mkVm = configs:
inputs.nixos-generators.nixosGenerate {
modules = configs;
format = "qcow";
system = "x86_64-linux";
};
}

4
lib/default.nix Normal file
View file

@ -0,0 +1,4 @@
args: {
inherit (import ./util.nix args) recursiveMerge;
inherit (import ./builder.nix args) mkNixos mkHosts mkVm;
}

17
lib/util.nix Normal file
View file

@ -0,0 +1,17 @@
{lib, ...}:
with lib; {
recursiveMerge = attrList: let
f = attrPath:
zipAttrsWith (
n: values:
if tail values == []
then head values
else if all isList values
then unique (concatLists values)
else if all isAttrs values
then f (attrPath ++ [n]) values
else last values
);
in
f [] attrList;
}

View file

@ -1,15 +0,0 @@
{
username,
stateVersion,
...
}: {
imports = [
../../targets/graphical.nix
../../targets/shell.nix
];
config = {
user.username = username;
system.stateVersion = stateVersion;
};
}

View file

@ -1,18 +0,0 @@
{
username,
stateVersion,
...
}: {
imports = [
../../targets/graphical.nix
../../targets/shell.nix
];
config = {
user.username = username;
system.stateVersion = stateVersion;
monitor.primary.resolution = "1920x1080";
services.qemuGuest.enable = true;
services.spice-vdagentd.enable = true;
};
}

View file

@ -1,188 +0,0 @@
{
"name": "astal-shell",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "astal-shell",
"dependencies": {
"astal": "/usr/share/astal/gjs"
},
"devDependencies": {
"@biomejs/biome": "1.9.4"
}
},
"../../../../usr/share/astal/gjs": {
"name": "astal",
"license": "LGPL-2.1"
},
"node_modules/@biomejs/biome": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
"integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
"dev": true,
"hasInstallScript": true,
"license": "MIT OR Apache-2.0",
"bin": {
"biome": "bin/biome"
},
"engines": {
"node": ">=14.21.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "1.9.4",
"@biomejs/cli-darwin-x64": "1.9.4",
"@biomejs/cli-linux-arm64": "1.9.4",
"@biomejs/cli-linux-arm64-musl": "1.9.4",
"@biomejs/cli-linux-x64": "1.9.4",
"@biomejs/cli-linux-x64-musl": "1.9.4",
"@biomejs/cli-win32-arm64": "1.9.4",
"@biomejs/cli-win32-x64": "1.9.4"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
"integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
"integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
"integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
"integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
"integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
"integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
"integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
"integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/astal": {
"resolved": "../../../../usr/share/astal/gjs",
"link": true
}
}
}

View file

@ -1,28 +0,0 @@
@use "../../variables.scss" as *;
@keyframes pulse {
0% {
background-color: $accent;
}
50% {
background-color: $bg-alt;
}
100% {
background-color: $accent;
}
}
.PlaybackDropdown {
.no-streams {
color: $muted;
font-size: 14px;
}
}
.Playback {
.recording {
background-color: $accent;
border-radius: $radius;
animation: pulse 1s 10;
}
}

View file

@ -1,12 +0,0 @@
{...}: {
user.home-manager.programs.btop = {
enable = true;
settings = {
color_theme = "TTY";
theme_background = false;
update_ms = 500;
rounded_corners = false;
};
};
}

30
parts/devshell.nix Normal file
View file

@ -0,0 +1,30 @@
{
inputs,
config,
lib,
hostname,
...
}: {
perSystem = {
pkgs,
config,
config',
...
}: {
agenix-rekey.nixosConfigurations = inputs.self.nixosConfigurations;
devShells.default = pkgs.mkShellNoCC {
packages = [
pkgs.nix
pkgs.nixos-rebuild
pkgs.nixos-rebuild
pkgs.nh
pkgs.just
config.agenix-rekey.package
config.agenix-rekey.agePackage
];
AGENIX_REKEY_ADD_TO_GIT = "true";
};
};
}

18
parts/formatter.nix Normal file
View file

@ -0,0 +1,18 @@
{inputs, ...}: {
imports = [inputs.treefmt-nix.flakeModule];
perSystem = {config, ...}: {
treefmt = {
projectRootFile = "flake.nix";
programs = {
deadnix.enable = true;
alejandra.enable = true;
statix.enable = true;
just.enable = true;
prettier.enable = true;
};
settings.global.excludes = ["*.{gitignore,svg}"];
};
formatter = config.treefmt.build.wrapper;
};
}

93
parts/hosts/default.nix Normal file
View file

@ -0,0 +1,93 @@
{
inputs,
withSystem,
lib,
...
}:
with lib; let
mkSystem = {
hostname,
username,
modules ? [],
}:
withSystem "x86_64-linux" (
{
pkgs,
system,
...
}:
inputs.nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {inherit inputs pkgs hostname username;};
modules =
[
inputs.disko.nixosModules.disko
inputs.home-manager.nixosModules.home-manager
]
++ [
inputs.agenix.nixosModules.default
inputs.agenix-rekey.nixosModules.default
{
environment.variables = {
AGENIX_REKEY_PRIMARY_IDENTITY = builtins.readFile ../../secrets/hosts/${hostname}/id_ed25519.pub;
AGENIX_REKEY_PRIMARY_IDENTITY_ONLY = "true";
};
environment.etc."ssh/ssh_host_ed25519_key.pub".source = ../../secrets/hosts/${hostname}/id_ed25519.pub;
age = rec {
rekey = {
storageMode = "local";
hostPubkey = builtins.readFile ../../secrets/hosts/${hostname}/id_ed25519.pub;
masterIdentities = [
{ identity=secrets.id_ed25519.path; pubkey="builtins.readFile ../../secrets/hosts/${hostname}/id_ed25519.pub"; }
{ identity=../../secrets/yubikey-identity.age; pubkey="age1yubikey1q25a8ax2t0ujv7q5wvpmlpa52h599n6682jprxuftlw4zpxy2xu9s6lhrel"; }
];
localStorageDir = lib.path.append ../../secrets/rekeyed hostname;
generatedSecretsDir = lib.path.append ../../secrets hostname;
};
secrets.hashed-user-password.rekeyFile = ../../secrets/hashed-user-password.age;
secrets.id_ed25519={
rekeyFile = ../../secrets/hosts/${hostname}/id_ed25519.age;
path = "/etc/ssh/ssh_host_ed25519_key";
};
secrets.luks-password.rekeyFile = ../../secrets/luks-password.age;
secrets.luks-password.path = "/luks-password";
};
}
]
++ modules;
}
);
# TODO:
# mkHosts = root: let
# hosts = attrNames (filterAttrs (_: type: type == "directory") (builtins.readDir root));
# hostDirs = builtins.listToAttrs (
# lib.map (hostName: lib.nameValuePair hostName (lib.path.append root hostName)) hosts
# );
# hostResolved =
# lib.mapAttrs (
# _: hostDir: (lib.map (fileName: lib.path.append hostDir fileName) (attrNames (builtins.readDir hostDir)))
# )
# hostDirs;
# hostsConfig = mapAttrs (host: modules: mkSystem host modules ) hostResolved;
# in
# hostsConfig;
in {
flake.nixosConfigurations = {
laptop = mkSystem {
hostname = "laptop";
modules = [
./laptop/configuration.nix
./laptop/disk-configuration.nix
./laptop/hardware-configuration.nix
];
username = "nickolaj";
};
desktop = mkSystem {
hostname = "desktop";
modules = [
./desktop/configuration.nix
];
username = "nickolaj";
};
};
}

View file

@ -0,0 +1,12 @@
{hostname, ...}: {
imports = [
../../modules/base.nix
../../modules/shell.nix
../../modules/graphical.nix
];
config = {
user.username = "nickolaj";
system.stateVersion = "24.11";
};
}

View file

@ -0,0 +1,13 @@
{...}: {
imports = [
../../modules/base.nix
../../modules/shell.nix
../../modules/graphical.nix
];
config = {
user.username = "nickolaj";
networking.hostName = "laptop";
system.stateVersion = "24.11";
};
}

View file

@ -0,0 +1,62 @@
{config, ...}: {
disko.devices = {
disk = {
vdb = {
device = "/dev/nvme0n1";
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
};
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = ["defaults"];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# passwordFile = "/luks-password";
passwordFile = config.age.secrets.luks-password.path;
settings = {
allowDiscards = true;
bypassWorkqueues = true;
};
content = {
type = "btrfs";
extraArgs = ["-f"];
subvolumes = {
"@" = {
mountpoint = "/";
mountOptions = ["compress=zstd" "noatime"];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = ["compress=zstd" "noatime"];
};
"@home" = {
mountpoint = "/home";
mountOptions = ["compress=zstd" "noatime"];
};
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,33 @@
# 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,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
];
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.enp7s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,4 @@
{pkgs, ...}: {
programs.firefox.enable = true;
defaults.browser = pkgs.firefox;
}

View file

@ -1,15 +1,17 @@
{ {
pkgs, pkgs,
config,
lib, lib,
... ...
}: { }: {
service.terminal.default = lib.getExe pkgs.ghostty; defaults.terminal = lib.getExe pkgs.ghostty;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
ghostty ghostty
]; ];
user.home-manager = { user.home-manager = {
programs.ghostty = { programs.ghostty = {
enable = true; enable = true;
enableFishIntegration = config.programs.fish.enable;
}; };
}; };
} }

11
parts/modules/base.nix Normal file
View file

@ -0,0 +1,11 @@
{
imports = [
./base/nix.nix
./base/user.nix
./base/security.nix
./base/boot.nix
./base/ssh.nix
./base/defaults.nix
./hardware/usb.nix
];
}

View file

@ -0,0 +1,4 @@
_: {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
}

View file

@ -0,0 +1,21 @@
{lib, ...}: let
inherit (lib) mkOption types;
in {
options.defaults = {
terminal = mkOption {
type = types.nullOr types.str;
};
fileManager = mkOption {
type = types.nullOr types.str;
};
browser = mkOption {
type = types.nullOr types.str;
};
editor = mkOption {
type = types.nullOr types.str;
};
};
}

View file

@ -0,0 +1,5 @@
{config, ...}: {
environment.variables = {
EDITOR = config.defaults.editor;
};
}

View file

@ -1,4 +1,3 @@
{...}: { _: {
services.udisks2.enable = true;
nix.settings.experimental-features = "nix-command flakes"; nix.settings.experimental-features = "nix-command flakes";
} }

View file

@ -0,0 +1,7 @@
{config, ...}: {
security.sudo.wheelNeedsPassword = false;
nix.settings.trusted-users = [
"root"
config.user.username
];
}

View file

@ -0,0 +1,25 @@
{config, ...}: {
programs.ssh.startAgent = true;
services.openssh.hostKeys = [
{
type = "ed25519";
inherit (config.age.secrets.id_ed25519) path;
}
];
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
};
users.users.${config.user.username}.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/oT15GWYcRvWCTchReh5rnkXTC9Ukm6Zfufei9bq1fWB0EjpvosCMupADw+jvqiP/ttyBKewHwZQxiw9oeRPSphUtKB0UlQXFPASNf1VxrFlsbkDOSEa+FB+PBS3eeP0TTyNJh18oYszt/OFDzCvr1n53iGXTX9xm76bkBxVfAvhm/5vadjmXKGOpdM/OWNF8rCqSgwkME6PXdT1UAFVj+FBdLrNCqYh1pe1ZdRxYlYL5b4uHwQmuz57AkvWwRNKipzdtxMCkT3LNiCQzuOhv3QaqxQ6fgJ+ktkbcTLZtY7HdT+CRUuC+APr266jeLAz1yUxFH693QifbBdn8v7wWD++UnbP23QqNwdXEMnCjEPRFgnK4ERnhIq6jVR328f5DTRJHZZ9spEx7pWsiT2iQC8MxK0gk9xul4fduJsPETWXe84YaHe6wLK92SQKQMdLh6p+TBvhMhPW2PrH5C6iH2w1oXVGlhc4wvoB1leiKNVHf4m9CWRFgznSmVbxFHFk= nickolaj@arch-desktop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFtjpdHPRXg75YBonNshQdeuNZ3W3k/RzdYY+8QuQ3Pc nickolaj1177@gmail.com"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdBiNbNPcMdI/hp4zgBS3ShqYuVVRvUAA1ffrdiBQ0k nickolaj@fireproof.website"
];
users.users.root.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/oT15GWYcRvWCTchReh5rnkXTC9Ukm6Zfufei9bq1fWB0EjpvosCMupADw+jvqiP/ttyBKewHwZQxiw9oeRPSphUtKB0UlQXFPASNf1VxrFlsbkDOSEa+FB+PBS3eeP0TTyNJh18oYszt/OFDzCvr1n53iGXTX9xm76bkBxVfAvhm/5vadjmXKGOpdM/OWNF8rCqSgwkME6PXdT1UAFVj+FBdLrNCqYh1pe1ZdRxYlYL5b4uHwQmuz57AkvWwRNKipzdtxMCkT3LNiCQzuOhv3QaqxQ6fgJ+ktkbcTLZtY7HdT+CRUuC+APr266jeLAz1yUxFH693QifbBdn8v7wWD++UnbP23QqNwdXEMnCjEPRFgnK4ERnhIq6jVR328f5DTRJHZZ9spEx7pWsiT2iQC8MxK0gk9xul4fduJsPETWXe84YaHe6wLK92SQKQMdLh6p+TBvhMhPW2PrH5C6iH2w1oXVGlhc4wvoB1leiKNVHf4m9CWRFgznSmVbxFHFk= nickolaj@arch-desktop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFtjpdHPRXg75YBonNshQdeuNZ3W3k/RzdYY+8QuQ3Pc nickolaj1177@gmail.com"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdBiNbNPcMdI/hp4zgBS3ShqYuVVRvUAA1ffrdiBQ0k nickolaj@fireproof.website"
];
}

View file

@ -21,7 +21,7 @@ in {
users.users.${cfg.username} = { users.users.${cfg.username} = {
isNormalUser = true; isNormalUser = true;
extraGroups = ["wheel"]; extraGroups = ["wheel"];
initialPassword = "a"; hashedPasswordFile = config.age.secrets.hashed-user-password.path;
}; };
home-manager = { home-manager = {

View file

@ -1,2 +1,5 @@
Icons from https://glyphs.fyi with manually set stroke-width @ ~10 and color @ #000000, common iconnames might need to be renamed to avoid conflicts. Icons from https://glyphs.fyi with manually set stroke-width @ ~10 and color @ #000000, common iconnames might need to be renamed to avoid conflicts.
```
``` ```

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 340 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 784 B

After

Width:  |  Height:  |  Size: 784 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 382 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 999 B

Before After
Before After

View file

@ -0,0 +1,188 @@
{
"name": "astal-shell",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "astal-shell",
"dependencies": {
"astal": "/usr/share/astal/gjs"
},
"devDependencies": {
"@biomejs/biome": "1.9.4"
}
},
"../../../../usr/share/astal/gjs": {
"name": "astal",
"license": "LGPL-2.1"
},
"node_modules/@biomejs/biome": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
"integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
"dev": true,
"hasInstallScript": true,
"license": "MIT OR Apache-2.0",
"bin": {
"biome": "bin/biome"
},
"engines": {
"node": ">=14.21.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "1.9.4",
"@biomejs/cli-darwin-x64": "1.9.4",
"@biomejs/cli-linux-arm64": "1.9.4",
"@biomejs/cli-linux-arm64-musl": "1.9.4",
"@biomejs/cli-linux-x64": "1.9.4",
"@biomejs/cli-linux-x64-musl": "1.9.4",
"@biomejs/cli-win32-arm64": "1.9.4",
"@biomejs/cli-win32-x64": "1.9.4"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
"integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
"integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
"integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
"integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
"integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
"integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
"integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
"integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/astal": {
"resolved": "../../../../usr/share/astal/gjs",
"link": true
}
}
}

View file

@ -11,7 +11,9 @@
color: $fg; color: $fg;
background-color: $bg; background-color: $bg;
font-size: $font-large; font-size: $font-large;
transition: opacity $transition, border-color $transition; transition:
opacity $transition,
border-color $transition;
&.left { &.left {
border-left: 2px solid $accent; border-left: 2px solid $accent;
border-bottom: 2px solid $accent; border-bottom: 2px solid $accent;
@ -50,7 +52,8 @@
} }
} }
.menu, modelbutton { .menu,
modelbutton {
background-color: $bg; background-color: $bg;
transition: background-color $transition; transition: background-color $transition;
} }

View file

@ -70,7 +70,7 @@ export function connectDropdown(
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN} transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
valign={Gtk.Align.START} valign={Gtk.Align.START}
setup={(self) => { setup={(self) => {
bind(self, "child_revealed").subscribe(is_revealed => { bind(self, "child_revealed").subscribe((is_revealed) => {
if (!is_revealed) { if (!is_revealed) {
dropdown.hide(); dropdown.hide();
} }

View file

@ -0,0 +1,28 @@
@use "../../variables.scss" as *;
@keyframes pulse {
0% {
background-color: $accent;
}
50% {
background-color: $bg-alt;
}
100% {
background-color: $accent;
}
}
.PlaybackDropdown {
.no-streams {
color: $muted;
font-size: 14px;
}
}
.Playback {
.recording {
background-color: $accent;
border-radius: $radius;
animation: pulse 1s 10;
}
}

View file

@ -53,7 +53,7 @@ function Workspace(workspace: Hyprland.Workspace) {
return "circle-filled"; return "circle-filled";
} }
return Object.keys(count)[0] ?? 'circle-filled'; return Object.keys(count)[0] ?? "circle-filled";
}); });
return ( return (

View file

@ -43,7 +43,9 @@ expander-widget {
color: $fg; color: $fg;
} }
expander { expander {
-gtk-icon-source: -gtk-icontheme('pan-end-symbolic'); -gtk-icon-source: -gtk-icontheme("pan-end-symbolic");
&:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); } &:checked {
-gtk-icon-source: -gtk-icontheme("pan-down-symbolic");
}
} }
} }

View file

@ -1,10 +1,10 @@
$bg: #1C1B1A; $bg: #1c1b1a;
$bg-alt: #282726; $bg-alt: #282726;
$fg: #DAD8CE; $fg: #dad8ce;
$fg-alt: #B7B5AC; $fg-alt: #b7b5ac;
$muted: #878580; $muted: #878580;
$accent: #CF6A4C; $accent: #cf6a4c;
$error: #D14D41; $error: #d14d41;
$radius: 8px; $radius: 8px;
$transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1); $transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);

View file

@ -1,7 +1,4 @@
{ {pkgs, ...}: {
pkgs,
...
}: {
services.greetd = { services.greetd = {
enable = true; enable = true;
settings = { settings = {

View file

@ -0,0 +1,17 @@
{
pkgs,
config,
lib,
...
}: {
defaults.terminal = lib.getExe pkgs.ghostty;
environment.systemPackages = with pkgs; [
ghostty
];
user.home-manager = {
programs.ghostty = {
enable = true;
enableFishIntegration = config.programs.fish.enable;
};
};
}

View file

@ -1,23 +1,21 @@
{ {
pkgs,
lib, lib,
config, config,
... ...
}: }:
with lib; { with lib; {
imports = [ imports = [
../monitors.nix
./hyprpolkitagent.nix ./hyprpolkitagent.nix
]; ];
options = {
service.terminal.default = mkOption {
type = types.str;
description = "The default terminal emulator";
};
};
config = { config = {
assertions = [
{
message = "The terminal must be set to enable Hyprland";
assertion = config.defaults.terminal != null;
}
];
programs.uwsm.enable = true; programs.uwsm.enable = true;
programs.hyprland = { programs.hyprland = {
enable = true; enable = true;
@ -35,12 +33,6 @@ with lib; {
}; };
}; };
# TODO: Remove
environment.systemPackages = [
pkgs.uwsm
pkgs.foot
];
environment.sessionVariables.NIXOS_OZONE_WL = "1"; environment.sessionVariables.NIXOS_OZONE_WL = "1";
user.home-manager = { user.home-manager = {
@ -48,12 +40,9 @@ with lib; {
enable = true; enable = true;
xwayland.enable = true; xwayland.enable = true;
systemd.enable = false; # Conficts with UWSM systemd.enable = false; # Conficts with UWSM
systemd.variables = ["--all"];
settings = { settings = {
monitor = monitor = map (
map
(
m: let m: let
name = name =
if m.name != null if m.name != null
@ -72,8 +61,7 @@ with lib; {
then m.position then m.position
else "auto"; else "auto";
in "${name}, ${resolution}${refreshRate}, ${position}, 1" in "${name}, ${resolution}${refreshRate}, ${position}, 1"
) ) [config.monitor.primary];
[config.monitor.primary];
general = { general = {
gaps_in = 5; gaps_in = 5;
@ -121,7 +109,7 @@ with lib; {
use_active_for_splits = true; use_active_for_splits = true;
}; };
bind = [ bind = [
"SUPER, RETURN, exec, ${getExe config.programs.uwsm.package} app -- ${config.service.terminal.default}" "SUPER, RETURN, exec, ${getExe config.programs.uwsm.package} app -- ${config.defaults.terminal}"
"SUPER, BACKSPACE, killactive" "SUPER, BACKSPACE, killactive"
# "SUPER, SPACE, exec, uwsm app -- walker" # "SUPER, SPACE, exec, uwsm app -- walker"
# "SUPER SHIFT, SPACE, exec, uwsm app -- walker --modules applications" # "SUPER SHIFT, SPACE, exec, uwsm app -- walker --modules applications"

View file

@ -1,7 +1,4 @@
{ {pkgs, ...}: {
pkgs,
...
}: {
config = { config = {
user.home-manager.systemd.user.services.hyprpolkitagent = { user.home-manager.systemd.user.services.hyprpolkitagent = {
Unit = { Unit = {

View file

View file

@ -0,0 +1,12 @@
{
imports = [
./hardware/monitors.nix
./hardware/audio.nix
./desktop/fonts.nix
./desktop/greetd.nix
./desktop/hyprland/default.nix
./desktop/astal/default.nix
./apps/firefox.nix
./apps/ghostty.nix
];
}

View file

@ -1,4 +1,4 @@
{...}: { _: {
config = { config = {
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {

View file

@ -0,0 +1,3 @@
_: {
services.udisks2.enable = true;
}

8
parts/modules/shell.nix Normal file
View file

@ -0,0 +1,8 @@
{
imports = [
./shell/core.nix
./shell/fish.nix
./shell/git.nix
./shell/neovim.nix
];
}

View file

@ -0,0 +1,17 @@
{pkgs, ...}: {
config = {
environment.systemPackages = with pkgs; [
curl
wget
file
git
htop
jq
ripgrep
tmux
whois
man-pages
man-pages-posix
];
};
}

View file

@ -0,0 +1,33 @@
{
config,
pkgs,
lib,
...
}: {
config = {
programs.fish.enable = true;
users.users.${config.user.username}.shell = pkgs.fish;
user.home-manager.programs.fish = {
plugins = [
{
name = "to-fish";
src = pkgs.fetchFromGitHub {
owner = "joehillen";
repo = "to-fish";
rev = "52b151cfe67c00cb64d80ccc6dae398f20364938";
sha256 = lib.fakeSha256;
};
}
{
name = "theme-bobthefish";
src = pkgs.fetchFromGitHub {
owner = "oh-my-fish";
repo = "theme-bobthefish";
rev = "e3b4d4eafc23516e35f162686f08a42edf844e40";
sha256 = lib.fakeSha256;
};
}
];
};
};
}

View file

@ -0,0 +1,7 @@
{pkgs, ...}: {
config = {
environment.systemPackages = with pkgs; [
git
];
};
}

View file

@ -0,0 +1,10 @@
_: {
config = {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
};
}

15
parts/vm.nix Normal file
View file

@ -0,0 +1,15 @@
{mylib, ...}: {
perSystem = {system, ...}: {
packages.vm = mylib.mkVm [
./modules/base.nix
./modules/graphical.nix
{
user.username = "vm";
system.stateVersion = "24.11";
monitor.primary.resolution = "1920x1080";
services.qemuGuest.enable = true;
services.spice-vdagentd.enable = true;
}
];
};
}

2
result
View file

@ -1 +1 @@
/nix/store/n7qvf6g755ls61ifrmqdpkf9sp5jjpbx-nixos-disk-image /nix/store/5nim4d9ylax1vqj8yy92mn7yji5ygr2d-nixos-system-laptop-24.11.20250128.2b4230b

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFtjpdHPRXg75YBonNshQdeuNZ3W3k/RzdYY+8QuQ3Pc nickolaj1177@gmail.com

Binary file not shown.

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdBiNbNPcMdI/hp4zgBS3ShqYuVVRvUAA1ffrdiBQ0k nickolaj@fireproof.website

BIN
secrets/linux-password.age Normal file

Binary file not shown.

BIN
secrets/luks-password.age Normal file

Binary file not shown.

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 A8c9xw 4Bp5cZCuPmIeV4fOtNrJfx+LqDPjLoD9jeY7i+rwW3w
S27YS/fWOq7OH7vXs5Ha4c+eo311Q6GTOHYlxCduiR8
-> u\9-Hs#b-grease U? Ay~af'~
mJ3eKR1X0Wrlufmo2OwDi8/ItNgL/PFd4WqwE4ZRASUjv6dSafYEKV420YWjSGah
23j5zyErTWuaHn5ClRdoEsBgYUYlLJeOLVq4
--- OMzY7nfhXRhmwRoq/NBu6wwSG1vBui1RP2EtDwGx/QQ
6r ·Õ»“;Ú©Õ–§²Ê‘çº îBüª²AlûƘJMy—ÑãÙ~û<<3C>Ò½X©qÊ™<C38A>ïðîÞ¸Äz¯$3hÀÚäE‡š&ȇ†¤ÝwÒÏÿ<C38F>KÈ<>Ü)¯g?)Û¯ŽQ±ð&Ë <0B>‡€Ö

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