initial commit
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.pre-commit-config.yaml
|
||||||
|
.direnv
|
||||||
|
tmp
|
||||||
|
result
|
||||||
|
latest.iso
|
||||||
2
FUNDING.yaml
Normal file
2
FUNDING.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github: emergentmind
|
||||||
|
ko_fi: unmovedcentre
|
||||||
9
LICENSE
Normal file
9
LICENSE
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Téo Adams
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
BIN
assets/wallpapers/emergentmind-nix-config-wp.png
Normal file
BIN
assets/wallpapers/emergentmind-nix-config-wp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
BIN
docs/nixos-ascendancy.png
Normal file
BIN
docs/nixos-ascendancy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
5
docs/secretsmgmt.md
Normal file
5
docs/secretsmgmt.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Nix-Config and Nix-Secrets Secrets Management
|
||||||
|
|
||||||
|
[README](../README.md) > Nix-Config Secrets Management
|
||||||
|
|
||||||
|
This content has been updated and moved to my website [NixOS Secrets Management](https://unmovedcentre.com/posts/secrets-management/). There is also an accompanying [video series](https://youtu.be/6EMNHDOY-wo).
|
||||||
332
flake.lock
generated
Normal file
332
flake.lock
generated
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"disko": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746729224,
|
||||||
|
"narHash": "sha256-9R4sOLAK1w3Bq54H3XOJogdc7a6C2bLLmatOQ+5pf5w=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "disko",
|
||||||
|
"rev": "85555d27ded84604ad6657ecca255a03fd878607",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hardware": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747083103,
|
||||||
|
"narHash": "sha256-dMx20S2molwqJxbmMB4pGjNfgp5H1IOHNa1Eby6xL+0=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"rev": "d1d68fe8b00248caaa5b3bbe4984c12b47e0867d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747020534,
|
||||||
|
"narHash": "sha256-D/6rkiC6w2p+4SwRiVKrWIeYzun8FBg7NlMKMwQMxO0=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "b4bbdc6fde16fc2051fcde232f6e288cd22007ca",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "release-24.11",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix-darwin": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs-darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747069642,
|
||||||
|
"narHash": "sha256-a4TdGi/Ju8P3r5OIecNfM3LH3kccMY0dIo+EwiyphmM=",
|
||||||
|
"owner": "lnl7",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"rev": "d642c9856003ed37ce34dab618abf37e3ade1061",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "lnl7",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix4vscode": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-overlay": "rust-overlay",
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747097775,
|
||||||
|
"narHash": "sha256-WYW1IpCnWSkTIO0oVv1r6rVP6SCZixmIZ3ftlm8Ern8=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nix4vscode",
|
||||||
|
"rev": "c566a8cdd1e24591ed6644b918c4e474c0b49f8a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nix4vscode",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-hardware": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747083103,
|
||||||
|
"narHash": "sha256-dMx20S2molwqJxbmMB4pGjNfgp5H1IOHNa1Eby6xL+0=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"rev": "d1d68fe8b00248caaa5b3bbe4984c12b47e0867d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1736320768,
|
||||||
|
"narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "4bc9c909d9ac828a039f288cf872d16d38185db8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-darwin": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747037616,
|
||||||
|
"narHash": "sha256-LRoT0AiI9kTK1pP8j0Va4geuE1YTtRwQuW/vLC3aaBY=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "40909cce0f2c3346ded03302b86228d8b292b9ce",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-24.11-darwin",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746957726,
|
||||||
|
"narHash": "sha256-k9ut1LSfHCr0AW82ttEQzXVCqmyWVA5+SHJkS5ID/Jo=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "a39ed32a651fdee6842ec930761e31d1f242cb94",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746904237,
|
||||||
|
"narHash": "sha256-3e+AVBczosP5dCLQmMoMEogM57gmZ2qrVSrmq9aResQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "d89fc19e405cb2d55ce7cc114356846a0ee5e956",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746957726,
|
||||||
|
"narHash": "sha256-k9ut1LSfHCr0AW82ttEQzXVCqmyWVA5+SHJkS5ID/Jo=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "a39ed32a651fdee6842ec930761e31d1f242cb94",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pre-commit-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746537231,
|
||||||
|
"narHash": "sha256-Wb2xeSyOsCoTCTj7LOoD6cdKLEROyFAArnYoS+noCWo=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "fa466640195d38ec97cf0493d6d6882bc4d14969",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"disko": "disko",
|
||||||
|
"hardware": "hardware",
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"nix-darwin": "nix-darwin",
|
||||||
|
"nix4vscode": "nix4vscode",
|
||||||
|
"nixos-hardware": "nixos-hardware",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"nixpkgs-darwin": "nixpkgs-darwin",
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
|
"pre-commit-hooks": "pre-commit-hooks",
|
||||||
|
"zen-browser": "zen-browser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1742178793,
|
||||||
|
"narHash": "sha256-S2onMdoDS4tIYd3/Jc5oFEZBr2dJOgPrh9KzSO/bfDw=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "954582a766a50ebef5695a9616c93b5386418c08",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zen-browser": {
|
||||||
|
"inputs": {
|
||||||
|
"home-manager": [
|
||||||
|
"home-manager"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1747071553,
|
||||||
|
"narHash": "sha256-EMIzJ+F2DTuOSPD608HaAra9cah87Emz8GjYNGtxpLo=",
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"rev": "50065c8bee3f5c20d29bce19037447b2c2006c48",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
182
flake.nix
Normal file
182
flake.nix
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
description = "EmergentMind's Nix-Config Starter";
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
} @ inputs: let
|
||||||
|
inherit (self) outputs;
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Architectures =========
|
||||||
|
#
|
||||||
|
# NOTE(starter): Comment or uncomment architectures below as required by your hosts.
|
||||||
|
forAllSystems = nixpkgs.lib.genAttrs [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Host Config Functions =========
|
||||||
|
#
|
||||||
|
# Handle a given host config based on whether its underlying system is nixos or darwin
|
||||||
|
mkHost = host: isDarwin: {
|
||||||
|
${host} = let
|
||||||
|
func =
|
||||||
|
if isDarwin
|
||||||
|
then inputs.nix-darwin.lib.darwinSystem
|
||||||
|
else lib.nixosSystem;
|
||||||
|
systemFunc = func;
|
||||||
|
in
|
||||||
|
systemFunc {
|
||||||
|
specialArgs = {
|
||||||
|
inherit
|
||||||
|
inputs
|
||||||
|
outputs
|
||||||
|
isDarwin
|
||||||
|
;
|
||||||
|
|
||||||
|
# ========== Extend lib with lib.custom ==========
|
||||||
|
# This approach allows lib.custom to propagate into hm
|
||||||
|
# see: https://github.com/nix-community/home-manager/pull/3454
|
||||||
|
lib = nixpkgs.lib.extend (self: super: {custom = import ./lib {inherit (nixpkgs) lib;};});
|
||||||
|
};
|
||||||
|
modules = [
|
||||||
|
./hosts/${
|
||||||
|
if isDarwin
|
||||||
|
then "darwin"
|
||||||
|
else "nixos"
|
||||||
|
}/${host}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Invoke mkHost for each host config that is declared for either nixos or darwin
|
||||||
|
mkHostConfigs = hosts: isDarwin: lib.foldl (acc: set: acc // set) {} (lib.map (host: mkHost host isDarwin) hosts);
|
||||||
|
# Return the hosts declared in the given directory
|
||||||
|
readHosts = folder: lib.attrNames (builtins.readDir ./hosts/${folder});
|
||||||
|
in {
|
||||||
|
#
|
||||||
|
# ========= Overlays =========
|
||||||
|
#
|
||||||
|
# Custom modifications/overrides to upstream packages.
|
||||||
|
overlays = import ./overlays {inherit inputs;};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Host Configurations =========
|
||||||
|
#
|
||||||
|
# Building configurations is available through `just rebuild` or `nixos-rebuild --flake .#hostname`
|
||||||
|
# NOTE(starter): Only uncomment darwinConfigurations if you actually have a host module configured in `./hosts/darwin`
|
||||||
|
nixosConfigurations = mkHostConfigs (readHosts "nixos") false;
|
||||||
|
#darwinConfigurations = mkHostConfigs (readHosts "darwin") true;
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Packages =========
|
||||||
|
#
|
||||||
|
# Add custom packages to be shared or upstreamed.
|
||||||
|
packages = forAllSystems (
|
||||||
|
system: let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [self.overlays.default];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
lib.packagesFromDirectoryRecursive {
|
||||||
|
callPackage = lib.callPackageWith pkgs;
|
||||||
|
directory = ./pkgs/common;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Formatting =========
|
||||||
|
#
|
||||||
|
# Nix formatter available through 'nix fmt' https://nix-community.github.io/nixpkgs-fmt
|
||||||
|
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= DevShell =========
|
||||||
|
#
|
||||||
|
# Custom shell for bootstrapping on new hosts, modifying nix-config, and secrets management
|
||||||
|
devShells = forAllSystems (
|
||||||
|
system:
|
||||||
|
import ./shell.nix {
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
#
|
||||||
|
# ========= Official NixOS, Nix-Darwin, and HM Package Sources =========
|
||||||
|
#
|
||||||
|
# NOTE(starter): As with typical flake-based configs, you'll need to update the nixOS, hm,
|
||||||
|
# and darwin version numbers below when new releases are available.
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
# The next two inputs are for pinning nixpkgs to stable vs unstable regardless of what the above is set to.
|
||||||
|
# This is particularly useful when an upcoming stable release is in beta because you can effectively
|
||||||
|
# keep 'nixpkgs-stable' set to stable for critical packages while setting 'nixpkgs' to the beta branch to
|
||||||
|
# get a jump start on deprecation changes.
|
||||||
|
# See also 'stable-packages' and 'unstable-packages' overlays at 'overlays/default.nix"
|
||||||
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
hardware.url = "github:nixos/nixos-hardware";
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager/release-24.11";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-24.11-darwin";
|
||||||
|
nix-darwin = {
|
||||||
|
url = "github:lnl7/nix-darwin";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs-darwin";
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Utilities =========
|
||||||
|
#
|
||||||
|
disko = {
|
||||||
|
url = "github:nix-community/disko";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixos-hardware = {
|
||||||
|
url = "github:NixOS/nixos-hardware/master";
|
||||||
|
};
|
||||||
|
|
||||||
|
nix4vscode = {
|
||||||
|
url = "github:nix-community/nix4vscode";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
pre-commit-hooks = {
|
||||||
|
url = "github:cachix/git-hooks.nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Extra Applications =========
|
||||||
|
#
|
||||||
|
zen-browser = {
|
||||||
|
url = "github:0xc000022070/zen-browser-flake";
|
||||||
|
inputs = {
|
||||||
|
home-manager.follows = "home-manager";
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========= Personal Repositories =========
|
||||||
|
#
|
||||||
|
# Private secrets repo. See ./docs/secretsmgmt.md
|
||||||
|
# Authenticates via ssh and use shallow clone
|
||||||
|
# FIXME(starter): The url below points to the 'simple' branch of the public, nix-secrets-reference repository which is inherently INSECURE!
|
||||||
|
# Replace the url with your personal, private nix-secrets repo.
|
||||||
|
/*
|
||||||
|
nix-secrets = {
|
||||||
|
url = "git+ssh://git@github.com/emergentmind/nix-secrets-reference.git?ref=simple&shallow=1";
|
||||||
|
inputs = { };
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
}
|
||||||
15
home/exampleSecondUser/Hostname1.nix
Normal file
15
home/exampleSecondUser/Hostname1.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
#################### Required Configs ####################
|
||||||
|
common/core # required
|
||||||
|
|
||||||
|
#################### Host-specific Optional Configs ####################
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
vlc
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
9
home/exampleSecondUser/common/core/brave.nix
Normal file
9
home/exampleSecondUser/common/core/brave.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
programs.brave = {
|
||||||
|
enable = true;
|
||||||
|
commandLineArgs = [
|
||||||
|
"--no-default-browser-check"
|
||||||
|
"--restore-last-session"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
47
home/exampleSecondUser/common/core/default.nix
Normal file
47
home/exampleSecondUser/common/core/default.nix
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = lib.flatten [
|
||||||
|
(lib.custom.scanPaths ./.)
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
"modules/home"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
home = {
|
||||||
|
username = lib.mkDefault "exampleSecondUser";
|
||||||
|
homeDirectory = lib.mkDefault "/home/${config.home.username}";
|
||||||
|
stateVersion = lib.mkDefault "24.11";
|
||||||
|
sessionPath = [ "$HOME/.local/bin" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
|
||||||
|
# Packages that don't have custom configs go here
|
||||||
|
nix-tree
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
package = lib.mkDefault pkgs.nix;
|
||||||
|
settings = {
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
warn-dirty = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
home-manager.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Nicely reload system units when changing configs
|
||||||
|
systemd.user.startServices = "sd-switch";
|
||||||
|
}
|
||||||
11
home/exampleSecondUser/common/core/gtk.nix
Normal file
11
home/exampleSecondUser/common/core/gtk.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
iconTheme = {
|
||||||
|
name = "elementary-Xfce-dark";
|
||||||
|
package = pkgs.elementary-xfce-icon-theme;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
19
home/panotaka/Bellerophon.nix
Normal file
19
home/panotaka/Bellerophon.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{...}: {
|
||||||
|
imports = [
|
||||||
|
#
|
||||||
|
# ========== Required Configs ==========
|
||||||
|
#
|
||||||
|
common/core
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Host-specific Optional Configs ==========
|
||||||
|
#
|
||||||
|
# FIXME(starter): add or remove any optional config directories or files ehre
|
||||||
|
common/optional/browsers
|
||||||
|
common/optional/desktops
|
||||||
|
common/optional/comms
|
||||||
|
common/optional/media
|
||||||
|
common/optional/coding
|
||||||
|
common/optional/games
|
||||||
|
];
|
||||||
|
}
|
||||||
12
home/panotaka/common/core/bash.nix
Normal file
12
home/panotaka/common/core/bash.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# FIXME(starter): customize your bash preferences here
|
||||||
|
{
|
||||||
|
programs.bash = {
|
||||||
|
enable = true;
|
||||||
|
enableCompletion = true;
|
||||||
|
shellAliases = {
|
||||||
|
};
|
||||||
|
|
||||||
|
initExtra = ''
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
10
home/panotaka/common/core/darwin.nix
Normal file
10
home/panotaka/common/core/darwin.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Core home functionality that will only work on Darwin
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
home.sessionPath = [ "/opt/homebrew/bin" ];
|
||||||
|
|
||||||
|
home = {
|
||||||
|
username = config.hostSpec.username;
|
||||||
|
homeDirectory = config.hostSpec.home;
|
||||||
|
};
|
||||||
|
}
|
||||||
79
home/panotaka/common/core/default.nix
Normal file
79
home/panotaka/common/core/default.nix
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#FIXME: Move attrs that will only work on linux to nixos.nix
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
hostSpec,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
platform =
|
||||||
|
if hostSpec.isDarwin
|
||||||
|
then "darwin"
|
||||||
|
else "nixos";
|
||||||
|
in {
|
||||||
|
imports = lib.flatten [
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
"modules/common/host-spec.nix"
|
||||||
|
"modules/home"
|
||||||
|
])
|
||||||
|
./${platform}.nix
|
||||||
|
|
||||||
|
# FIXME(starter): add/edit as desired
|
||||||
|
./fish.nix
|
||||||
|
./bash.nix
|
||||||
|
./direnv.nix
|
||||||
|
./fonts.nix
|
||||||
|
./kitty.nix
|
||||||
|
./git.nix
|
||||||
|
./ssh.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit hostSpec;
|
||||||
|
|
||||||
|
services.ssh-agent.enable = true;
|
||||||
|
|
||||||
|
home = {
|
||||||
|
username = lib.mkDefault config.hostSpec.username;
|
||||||
|
homeDirectory = lib.mkDefault config.hostSpec.home;
|
||||||
|
stateVersion = lib.mkDefault "24.11";
|
||||||
|
sessionPath = [
|
||||||
|
"$HOME/.local/bin"
|
||||||
|
];
|
||||||
|
sessionVariables = {
|
||||||
|
FLAKE = "$HOME/src/nix/nix-config";
|
||||||
|
SHELL = "bash";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
# FIXME(starter): add/edit as desired
|
||||||
|
# Packages that don't have custom configs go here
|
||||||
|
curl
|
||||||
|
pciutils
|
||||||
|
pfetch # system info
|
||||||
|
pre-commit # git hooks
|
||||||
|
p7zip # compression & encryption
|
||||||
|
usbutils
|
||||||
|
unzip # zip extraction
|
||||||
|
unrar # rar extraction
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
package = lib.mkDefault pkgs.nix;
|
||||||
|
settings = {
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
warn-dirty = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
|
||||||
|
# Nicely reload system units when changing configs
|
||||||
|
systemd.user.startServices = "sd-switch";
|
||||||
|
}
|
||||||
8
home/panotaka/common/core/direnv.nix
Normal file
8
home/panotaka/common/core/direnv.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
nix-direnv.enable = true; # better than native direnv nix functionality - https://github.com/nix-community/nix-direnv
|
||||||
|
};
|
||||||
|
}
|
||||||
25
home/panotaka/common/core/fish.nix
Normal file
25
home/panotaka/common/core/fish.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
grc
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
interactiveShellInit = ''
|
||||||
|
set fish_greeting # Disable greeting
|
||||||
|
'';
|
||||||
|
plugins = [
|
||||||
|
{
|
||||||
|
name = "grc";
|
||||||
|
src = pkgs.fishPlugins.grc.src;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "autopair";
|
||||||
|
src = pkgs.fishPlugins.autopair.src;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
7
home/panotaka/common/core/fonts.nix
Normal file
7
home/panotaka/common/core/fonts.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
fonts.fontconfig.enable = true;
|
||||||
|
home.packages = [
|
||||||
|
pkgs.noto-fonts
|
||||||
|
];
|
||||||
|
}
|
||||||
25
home/panotaka/common/core/git.nix
Normal file
25
home/panotaka/common/core/git.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# git is core no matter what but additional settings may could be added made in optional/foo eg: development.nix
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.gitAndTools.gitFull;
|
||||||
|
|
||||||
|
ignores = [
|
||||||
|
".csvignore"
|
||||||
|
# nix
|
||||||
|
"*.drv"
|
||||||
|
"result"
|
||||||
|
# python
|
||||||
|
"*.py?"
|
||||||
|
"__pycache__/"
|
||||||
|
".venv/"
|
||||||
|
# direnv
|
||||||
|
".direnv"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
5
home/panotaka/common/core/kitty.nix
Normal file
5
home/panotaka/common/core/kitty.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
programs.kitty = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
7
home/panotaka/common/core/nixos.nix
Normal file
7
home/panotaka/common/core/nixos.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Core home functionality that will only work on Linux
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
9
home/panotaka/common/core/screen.nix
Normal file
9
home/panotaka/common/core/screen.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.screen ];
|
||||||
|
home.file.".screenrc".text = ''
|
||||||
|
startup_message off
|
||||||
|
defbce on
|
||||||
|
setenv TERM xterm-256color
|
||||||
|
'';
|
||||||
|
}
|
||||||
24
home/panotaka/common/core/ssh.nix
Normal file
24
home/panotaka/common/core/ssh.nix
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# FIXME(starter): adjust to you security requirements
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
programs.ssh =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
controlMaster = "auto";
|
||||||
|
controlPath = "${config.home.homeDirectory}/.ssh/sockets/S.%r@%h:%p";
|
||||||
|
controlPersist = "20m";
|
||||||
|
# Avoids infinite hang if control socket connection interrupted. ex: vpn goes down/up
|
||||||
|
serverAliveCountMax = 3;
|
||||||
|
serverAliveInterval = 5; # 3 * 5s
|
||||||
|
hashKnownHosts = true;
|
||||||
|
addKeysToAgent = "yes";
|
||||||
|
};
|
||||||
|
home.file = {
|
||||||
|
".ssh/config.d/.keep".text = "# Managed by Home Manager";
|
||||||
|
".ssh/sockets/.keep".text = "# Managed by Home Manager";
|
||||||
|
};
|
||||||
|
}
|
||||||
6
home/panotaka/common/optional/browsers/chromium.nix
Normal file
6
home/panotaka/common/optional/browsers/chromium.nix
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.chromium = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.ungoogled-chromium;
|
||||||
|
};
|
||||||
|
}
|
||||||
8
home/panotaka/common/optional/browsers/default.nix
Normal file
8
home/panotaka/common/optional/browsers/default.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# FIXME(starter): add/edit any browser modules here
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./chromium.nix
|
||||||
|
./firefox.nix
|
||||||
|
./zen.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
5
home/panotaka/common/optional/browsers/firefox.nix
Normal file
5
home/panotaka/common/optional/browsers/firefox.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{...}: {
|
||||||
|
programs.librewolf = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
24
home/panotaka/common/optional/browsers/zen.nix
Normal file
24
home/panotaka/common/optional/browsers/zen.nix
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
# home.nix
|
||||||
|
imports = [
|
||||||
|
inputs.zen-browser.homeModules.beta
|
||||||
|
# or inputs.zen-browser.homeModules.twilight
|
||||||
|
# or inputs.zen-browser.homeModules.twilight-official
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.zen-browser = {
|
||||||
|
enable = true;
|
||||||
|
policies = {
|
||||||
|
AutofillAddressEnabled = true;
|
||||||
|
AutofillCreditCardEnabled = false;
|
||||||
|
DisableAppUpdate = true;
|
||||||
|
DisableFeedbackCommands = true;
|
||||||
|
DisableFirefoxStudies = true;
|
||||||
|
DisablePocket = true; # save webs for later reading
|
||||||
|
DisableTelemetry = true;
|
||||||
|
DontCheckDefaultBrowser = true;
|
||||||
|
NoDefaultBookmarks = true;
|
||||||
|
OfferToSaveLogins = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
13
home/panotaka/common/optional/coding/default.nix
Normal file
13
home/panotaka/common/optional/coding/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
./vscode
|
||||||
|
./zed.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
hoppscotch
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
69
home/panotaka/common/optional/coding/vscode/default.nix
Normal file
69
home/panotaka/common/optional/coding/vscode/default.nix
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
./javascript.nix
|
||||||
|
./latex.nix
|
||||||
|
./markdown.nix
|
||||||
|
./nix.nix
|
||||||
|
./rust.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.vscode = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.vscodium;
|
||||||
|
enableUpdateCheck = false; # Disable VSCode self-update and let Home Manager to manage VSCode versions instead.
|
||||||
|
enableExtensionUpdateCheck = false; # Disable extensions auto-update and let nix4vscode manage updates and extensions
|
||||||
|
# Extensions
|
||||||
|
extensions = pkgs.nix4vscode.forVscode [
|
||||||
|
# General extensions
|
||||||
|
|
||||||
|
## Code Completion
|
||||||
|
"continue.continue"
|
||||||
|
#rooveterinaryinc.roo-cline
|
||||||
|
|
||||||
|
## Development Environment
|
||||||
|
"ms-toolsai.jupyter"
|
||||||
|
"ms-vscode-remote.remote-containers"
|
||||||
|
|
||||||
|
## Error Checking
|
||||||
|
"usernamehw.errorlens"
|
||||||
|
|
||||||
|
## Export and Visualisation
|
||||||
|
"ibm.output-colorizer"
|
||||||
|
"nobuhito.printcode"
|
||||||
|
"pnp.polacode"
|
||||||
|
|
||||||
|
## Git
|
||||||
|
"lamartire.git-indicators"
|
||||||
|
"mhutchie.git-graph"
|
||||||
|
|
||||||
|
## Miscelaneous
|
||||||
|
"britesnow.vscode-toggle-quotes"
|
||||||
|
"mrmlnc.vscode-duplicate"
|
||||||
|
"qcz.text-power-tools"
|
||||||
|
|
||||||
|
# Language extensions
|
||||||
|
|
||||||
|
## CSV
|
||||||
|
"mechatroner.rainbow-csv"
|
||||||
|
|
||||||
|
## Golang
|
||||||
|
"golang.go"
|
||||||
|
|
||||||
|
## Python
|
||||||
|
"ms-python.python"
|
||||||
|
|
||||||
|
## SVG
|
||||||
|
"jock.svg"
|
||||||
|
];
|
||||||
|
# Settings
|
||||||
|
userSettings = {
|
||||||
|
"editor.linkedEditing" = true;
|
||||||
|
"editor.inlineSuggest.enabled" = true;
|
||||||
|
"continue.enableTabAutocomplete" = true;
|
||||||
|
|
||||||
|
"window.menuBarVisibility" = "toggle";
|
||||||
|
#"github.copilot.editor.enableAutoCompletions" = true;
|
||||||
|
"redhat.telemetry.enabled" = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
56
home/panotaka/common/optional/coding/vscode/javascript.nix
Normal file
56
home/panotaka/common/optional/coding/vscode/javascript.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.vscode = {
|
||||||
|
extensions = pkgs.nix4vscode.forVscode [
|
||||||
|
# General
|
||||||
|
"christian-kohler.npm-intellisense"
|
||||||
|
"dbaeumer.vscode-eslint"
|
||||||
|
"denoland.vscode-deno"
|
||||||
|
"esbenp.prettier-vscode"
|
||||||
|
|
||||||
|
"liamhammett.inline-parameters"
|
||||||
|
"yatki.vscode-surround"
|
||||||
|
|
||||||
|
# Astro
|
||||||
|
"astro-build.astro-vscode"
|
||||||
|
|
||||||
|
# CSS
|
||||||
|
"bradlc.vscode-tailwindcss"
|
||||||
|
"pranaygp.vscode-css-peek"
|
||||||
|
"stylelint.vscode-stylelint"
|
||||||
|
"zignd.html-css-class-completion"
|
||||||
|
|
||||||
|
# ServiceNow
|
||||||
|
"arnoudkooicom.sn-scriptsync"
|
||||||
|
|
||||||
|
# Svelte
|
||||||
|
"svelte.svelte-vscode"
|
||||||
|
|
||||||
|
# Tauri
|
||||||
|
"tauri-apps.tauri-vscode"
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
"ms-playwright.playwright"
|
||||||
|
];
|
||||||
|
userSettings = {
|
||||||
|
"[javascript]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[typescript]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[typescriptreact]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[json]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[jsonc]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[html]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[scss]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[css]"."editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
"[astro]"."editor.defaultFormatter" = "astro-build.astro-vscode";
|
||||||
|
|
||||||
|
"svelte.enable-ts-plugin" = true;
|
||||||
|
"playwright.reuseBrowser" = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
deno
|
||||||
|
pnpm
|
||||||
|
bun
|
||||||
|
nodejs
|
||||||
|
];
|
||||||
|
}
|
||||||
28
home/panotaka/common/optional/coding/vscode/latex.nix
Normal file
28
home/panotaka/common/optional/coding/vscode/latex.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.vscode = {
|
||||||
|
extensions = pkgs.nix4vscode.forVscode [
|
||||||
|
# General
|
||||||
|
"james-yu.latex-workshop"
|
||||||
|
];
|
||||||
|
userSettings = {
|
||||||
|
"latex-workshop.latex.recipe.default" = "tectonic";
|
||||||
|
"latex-workshop.latex.autoBuild.run" = "onSave";
|
||||||
|
"latex-workshop.latex.outDir" = "%WORKSPACE_FOLDER%/build/index";
|
||||||
|
"latex-workshop.view.pdf.viewer" = "tab";
|
||||||
|
"latex-workshop.latex.recipes" = [
|
||||||
|
{
|
||||||
|
"name" = "tectonic";
|
||||||
|
"tools" = ["tectonic"];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"latex-workshop.latex.tools" = [
|
||||||
|
{
|
||||||
|
"name" = "tectonic";
|
||||||
|
"command" = "tectonic";
|
||||||
|
"args" = ["-X" "build" "--keep-intermediates" "--keep-logs"];
|
||||||
|
"env" = {};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
15
home/panotaka/common/optional/coding/vscode/markdown.nix
Normal file
15
home/panotaka/common/optional/coding/vscode/markdown.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.vscode = {
|
||||||
|
extensions = pkgs.nix4vscode.forVscode [
|
||||||
|
# General
|
||||||
|
"bpruitt-goddard.mermaid-markdown-syntax-highlighting"
|
||||||
|
"davidanson.vscode-markdownlint"
|
||||||
|
"yzhang.markdown-all-in-one"
|
||||||
|
];
|
||||||
|
userSettings = {
|
||||||
|
"[markdown]" = {
|
||||||
|
"editor.defaultFormatter" = "esbenp.prettier-vscode";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
18
home/panotaka/common/optional/coding/vscode/nix.nix
Normal file
18
home/panotaka/common/optional/coding/vscode/nix.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
nil
|
||||||
|
alejandra
|
||||||
|
deadnix
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.vscode = {
|
||||||
|
extensions = pkgs.nix4vscode.forVscode [
|
||||||
|
"jnoortheen.nix-ide"
|
||||||
|
"kamadorueda.alejandra"
|
||||||
|
];
|
||||||
|
userSettings = {
|
||||||
|
"nix.enableLanguageServer" = true;
|
||||||
|
"nix.serverPath" = "nil";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
19
home/panotaka/common/optional/coding/vscode/rust.nix
Normal file
19
home/panotaka/common/optional/coding/vscode/rust.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.vscode = {
|
||||||
|
extensions =
|
||||||
|
pkgs.nix4vscode.forVscode
|
||||||
|
[
|
||||||
|
# General
|
||||||
|
"serayuzgur.crates"
|
||||||
|
"tamasfe.even-better-toml"
|
||||||
|
"rust-lang.rust-analyzer"
|
||||||
|
];
|
||||||
|
userSettings = {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
cargo
|
||||||
|
rustc
|
||||||
|
];
|
||||||
|
}
|
||||||
5
home/panotaka/common/optional/coding/zed.nix
Normal file
5
home/panotaka/common/optional/coding/zed.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.zed-editor = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
13
home/panotaka/common/optional/comms/default.nix
Normal file
13
home/panotaka/common/optional/comms/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# FIXME(starter): add/edit any optional, communications related pkgs here
|
||||||
|
{pkgs, ...}: {
|
||||||
|
#imports = [ ./foo.nix ];
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
teams-for-linux
|
||||||
|
signal-desktop
|
||||||
|
discord
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
14
home/panotaka/common/optional/desktops/default.nix
Normal file
14
home/panotaka/common/optional/desktops/default.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Packages with custom configs go here
|
||||||
|
|
||||||
|
########## Utilities ##########
|
||||||
|
#./fonts.nix
|
||||||
|
./gtk.nix
|
||||||
|
];
|
||||||
|
home.packages = [
|
||||||
|
pkgs.pavucontrol # gui for pulseaudio server and volume controls
|
||||||
|
pkgs.galculator # gtk based calculator
|
||||||
|
];
|
||||||
|
}
|
||||||
14
home/panotaka/common/optional/desktops/gtk.nix
Normal file
14
home/panotaka/common/optional/desktops/gtk.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
iconTheme = {
|
||||||
|
name = "elementary-Xfce-dark";
|
||||||
|
package = pkgs.elementary-xfce-icon-theme;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
7
home/panotaka/common/optional/desktops/playerctl.nix
Normal file
7
home/panotaka/common/optional/desktops/playerctl.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.playerctl ];
|
||||||
|
services.playerctld = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
7
home/panotaka/common/optional/games/default.nix
Normal file
7
home/panotaka/common/optional/games/default.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# FIXME(starter): add/edit any browser modules here
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./steam.nix
|
||||||
|
./minecraft.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
3
home/panotaka/common/optional/games/minecraft.nix
Normal file
3
home/panotaka/common/optional/games/minecraft.nix
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = [pkgs.prismlauncher];
|
||||||
|
}
|
||||||
3
home/panotaka/common/optional/games/steam.nix
Normal file
3
home/panotaka/common/optional/games/steam.nix
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = [pkgs.steam];
|
||||||
|
}
|
||||||
11
home/panotaka/common/optional/media/default.nix
Normal file
11
home/panotaka/common/optional/media/default.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# FIXME(starter): add/edit any optional, media related pkgs here
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
#imports = [ ./foo.nix ];
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
vlc
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
20
home/panotaka/common/optional/productivity/default.nix
Normal file
20
home/panotaka/common/optional/productivity/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
./obsidian.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# FIXME(starter): add/edit any optional, communications related pkgs here
|
||||||
|
|
||||||
|
#imports = [ ./foo.nix ];
|
||||||
|
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
blender
|
||||||
|
inkscape
|
||||||
|
libreoffice-qt
|
||||||
|
hunspell
|
||||||
|
hunspellDicts
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
8
home/panotaka/common/optional/productivity/obsidian.nix
Normal file
8
home/panotaka/common/optional/productivity/obsidian.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = builtins.attrValues {
|
||||||
|
inherit
|
||||||
|
(pkgs)
|
||||||
|
obsidian
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
6
home/panotaka/iso.nix
Normal file
6
home/panotaka/iso.nix
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
common/core
|
||||||
|
];
|
||||||
|
}
|
||||||
16
home/ta/common/optional/desktops/fonts.nix
Normal file
16
home/ta/common/optional/desktops/fonts.nix
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
# TODO add ttf-font-awesome or font-awesome for waybar
|
||||||
|
fontProfiles = {
|
||||||
|
enable = true;
|
||||||
|
monospace = {
|
||||||
|
family = "FiraCode Nerd Font";
|
||||||
|
package = pkgs.nerdfonts.override { fonts = [ "FiraCode" ]; };
|
||||||
|
};
|
||||||
|
regular = {
|
||||||
|
family = "Fira Sans";
|
||||||
|
package = pkgs.fira;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
3
hosts/common/core/darwin.nix
Normal file
3
hosts/common/core/darwin.nix
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Core functionality for every nix-darwin host
|
||||||
|
# NOTE(starter): Declare any darwin-specific, core configurations here.
|
||||||
|
{ }
|
||||||
103
hosts/common/core/default.nix
Normal file
103
hosts/common/core/default.nix
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# FIXME(starter): modify this file and the other .nix files in `nix-config/hosts/common/core/` to declare
|
||||||
|
# settings that will occur across all hosts
|
||||||
|
|
||||||
|
# IMPORTANT: This is used by NixOS and nix-darwin so options must exist in both!
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
outputs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
isDarwin,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
platform = if isDarwin then "darwin" else "nixos";
|
||||||
|
platformModules = "${platform}Modules";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = lib.flatten [
|
||||||
|
inputs.home-manager.${platformModules}.home-manager
|
||||||
|
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
"modules/common"
|
||||||
|
"modules/hosts/common"
|
||||||
|
"modules/hosts/${platform}"
|
||||||
|
"hosts/common/core/${platform}.nix"
|
||||||
|
#"hosts/common/core/sops.nix" # Core because it's used for backups, mail
|
||||||
|
"hosts/common/core/ssh.nix"
|
||||||
|
#"hosts/common/core/services" # uncomment this line if you add any modules to services directory
|
||||||
|
"hosts/common/users/primary"
|
||||||
|
"hosts/common/users/primary/${platform}.nix"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Core Host Specifications ==========
|
||||||
|
#
|
||||||
|
# FIXME(starter): modify the hostSpec options below to define values that are common across all hosts
|
||||||
|
# such as the username and handle of the primary user (see also `nix-config/hosts/common/users/primary`)
|
||||||
|
hostSpec = {
|
||||||
|
username = "panotaka";
|
||||||
|
handle = "panotaka";
|
||||||
|
# FIXME(starter): modify the attribute sets hostSpec will inherit from your nix-secrets.
|
||||||
|
# If you're not using nix-secrets then remove the following six lines below.
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.hostName = config.hostSpec.hostName;
|
||||||
|
|
||||||
|
# System-wide packages, in case we log in as root
|
||||||
|
environment.systemPackages = [ pkgs.openssh ];
|
||||||
|
|
||||||
|
# Force home-manager to use global packages
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
|
||||||
|
# If there is a conflict file that is backed up, use this extension
|
||||||
|
home-manager.backupFileExtension = "bk";
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Overlays ==========
|
||||||
|
#
|
||||||
|
nixpkgs = {
|
||||||
|
overlays = [
|
||||||
|
outputs.overlays.default
|
||||||
|
];
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Nix Nix Nix ==========
|
||||||
|
#
|
||||||
|
nix = {
|
||||||
|
# This will add each flake input as a registry
|
||||||
|
# To make nix3 commands consistent with your flake
|
||||||
|
registry = lib.mapAttrs (_: value: { flake = value; }) inputs;
|
||||||
|
|
||||||
|
# This will add your inputs to the system's legacy channels
|
||||||
|
# Making legacy nix commands consistent as well, awesome!
|
||||||
|
nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
# See https://jackson.dev/post/nix-reasonable-defaults/
|
||||||
|
connect-timeout = 5;
|
||||||
|
log-lines = 25;
|
||||||
|
min-free = 128000000; # 128MB
|
||||||
|
max-free = 1000000000; # 1GB
|
||||||
|
|
||||||
|
trusted-users = [ "@wheel" ];
|
||||||
|
# Deduplicate and optimize nix store
|
||||||
|
auto-optimise-store = true;
|
||||||
|
warn-dirty = false;
|
||||||
|
|
||||||
|
allow-import-from-derivation = true;
|
||||||
|
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
36
hosts/common/core/nixos.nix
Normal file
36
hosts/common/core/nixos.nix
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Core functionality for every nixos host
|
||||||
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
|
# Database for aiding terminal-based programs
|
||||||
|
environment.enableAllTerminfo = true;
|
||||||
|
# Enable firmware with a license allowing redistribution
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
|
# This should be handled by config.security.pam.sshAgentAuth.enable
|
||||||
|
security.sudo.extraConfig = ''
|
||||||
|
Defaults lecture = never # rollback results in sudo lectures after each reboot, it's somewhat useless anyway
|
||||||
|
Defaults pwfeedback # password input feedback - makes typed password visible as asterisks
|
||||||
|
Defaults timestamp_timeout=120 # only ask for password every 2h
|
||||||
|
# Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic.
|
||||||
|
Defaults env_keep+=SSH_AUTH_SOCK
|
||||||
|
'';
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Nix Helper ==========
|
||||||
|
#
|
||||||
|
# Provide better build output and will also handle garbage collection in place of standard nix gc (garbace collection)
|
||||||
|
# FIXME(starter): customize garbage collection rules as desired.
|
||||||
|
programs.nh = {
|
||||||
|
enable = true;
|
||||||
|
clean.enable = true;
|
||||||
|
clean.extraArgs = "--keep-since 20d --keep 20";
|
||||||
|
flake = "/home/user/${config.hostSpec.home}/nix-config";
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Localization ==========
|
||||||
|
#
|
||||||
|
# FIXME(starter): customize localization values as desired.
|
||||||
|
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
|
||||||
|
time.timeZone = lib.mkDefault "America/Edmonton";
|
||||||
|
}
|
||||||
9
hosts/common/core/services/default.nix
Normal file
9
hosts/common/core/services/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Add your core services to the same directory as this default.nix file.
|
||||||
|
# They will automatically be imported below.
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = (lib.custom.scanPaths ./.);
|
||||||
|
}
|
||||||
11
hosts/common/core/ssh.nix
Normal file
11
hosts/common/core/ssh.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
programs.ssh = lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||||
|
startAgent = true;
|
||||||
|
enableAskPassword = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
65
hosts/common/disks/btrfs-disk.nix
Normal file
65
hosts/common/disks/btrfs-disk.nix
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# `...` is needed because dikso passes diskoFile
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
disk ? "/dev/vda",
|
||||||
|
withSwap ? false,
|
||||||
|
swapSize,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
disk0 = {
|
||||||
|
type = "disk";
|
||||||
|
device = disk;
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
priority = 1;
|
||||||
|
name = "ESP";
|
||||||
|
start = "1M";
|
||||||
|
end = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "defaults" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-f" ]; # Override existing partition
|
||||||
|
# Subvolumes must set a mountpoint in order to be mounted,
|
||||||
|
# unless their parent is mounted
|
||||||
|
subvolumes = {
|
||||||
|
"@root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@swap" = lib.mkIf withSwap {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
swap.swapfile.size = "${swapSize}G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
71
hosts/common/disks/luks-btrfs-disk.nix
Normal file
71
hosts/common/disks/luks-btrfs-disk.nix
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# `...` is needed because dikso passes diskoFile
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
disk ? "/dev/vda",
|
||||||
|
withSwap ? false,
|
||||||
|
swapSize,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
main = {
|
||||||
|
type = "disk";
|
||||||
|
device = disk;
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
size = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
luks = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "luks";
|
||||||
|
name = "crypted";
|
||||||
|
# disable settings.keyFile if you want to use interactive password entry
|
||||||
|
#passwordFile = "/tmp/secret.key"; # Interactive
|
||||||
|
settings = {
|
||||||
|
allowDiscards = true;
|
||||||
|
};
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-f" ]; # Override existing partition
|
||||||
|
# Subvolumes must set a mountpoint in order to be mounted,
|
||||||
|
# unless their parent is mounted
|
||||||
|
subvolumes = {
|
||||||
|
"@root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@swap" = lib.mkIf withSwap {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
swap.swapfile.size = "${swapSize}G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
21
hosts/common/optional/audio.nix
Normal file
21
hosts/common/optional/audio.nix
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# NOTE(starter): configure your audio needs as required.
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
hardware.pulseaudio.enable = false;
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
wireplumber.enable = true;
|
||||||
|
jack.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
playerctl # cli utility and lib for controlling media players
|
||||||
|
# pamixer # cli pulseaudio sound mixer
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}
|
||||||
4
hosts/common/optional/kde.nix
Normal file
4
hosts/common/optional/kde.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# NOTE(starter): This is just a basic enabling of the XFCE windows manager for simplicity
|
||||||
|
{
|
||||||
|
services.desktopManager.plasma6.enable = true;
|
||||||
|
}
|
||||||
13
hosts/common/optional/minimal-user.nix
Normal file
13
hosts/common/optional/minimal-user.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# NOTE: This module is required for nixos-installer
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
# Set a temp password for use by minimal builds like installer and iso
|
||||||
|
users.users.${config.hostSpec.username} = {
|
||||||
|
isNormalUser = true;
|
||||||
|
# This is a hashed version of the plain-text password "nixos" for use in the ISO. Even though,
|
||||||
|
# the password is known, we use `hashedPassword` here instead of `password` to mitigate
|
||||||
|
# occurrences of the latter not being used during build.
|
||||||
|
password = "password";
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
10
hosts/common/optional/sddm.nix
Normal file
10
hosts/common/optional/sddm.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# NOTE(starter): This is just a basic enabling of the XFCE windows manager for simplicity
|
||||||
|
{
|
||||||
|
services.displayManager = {
|
||||||
|
sddm.enable = true;
|
||||||
|
sddm.wayland = {
|
||||||
|
enable = true;
|
||||||
|
compositor = "kwin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
36
hosts/common/optional/services/openssh.nix
Normal file
36
hosts/common/optional/services/openssh.nix
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
# FIXME(starter): if you are not defining ports in your "soft" nix-secrets, you can
|
||||||
|
# replace the following line with: sshPort = 22;
|
||||||
|
# and substitute 22 with a custom port number if needed.
|
||||||
|
sshPort = 22;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
ports = [ sshPort ];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
# Harden
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
# Automatically remove stale sockets
|
||||||
|
StreamLocalBindUnlink = "yes";
|
||||||
|
# Allow forwarding ports to everywhere
|
||||||
|
GatewayPorts = "clientspecified";
|
||||||
|
};
|
||||||
|
|
||||||
|
hostKeys = [
|
||||||
|
{
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
type = "ed25519";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ sshPort ];
|
||||||
|
}
|
||||||
5
hosts/common/optional/xfce.nix
Normal file
5
hosts/common/optional/xfce.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# NOTE(starter): This is just a basic enabling of the XFCE windows manager for simplicity
|
||||||
|
{
|
||||||
|
services.xserver.desktopManager.xfce.enable = true;
|
||||||
|
services.xserver.desktopManager.xfce.enableScreensaver = false;
|
||||||
|
}
|
||||||
67
hosts/common/users/exampleSecondUser/default.nix
Normal file
67
hosts/common/users/exampleSecondUser/default.nix
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# FIXME(starter): this is an example of how a secondary user called "exampleSecondUser" can be declared.
|
||||||
|
# NOTE that this file's parent directory matches the username!
|
||||||
|
# Modify the directory name and all instances of `exampleSecondUser` in this file to a real username to
|
||||||
|
# make use of this file. You'll also need to import this file in the relevant `nix-config/hosts/[platform]/[hostname]/default.nix`
|
||||||
|
# host file for the user to be created on the host.
|
||||||
|
# NOTE that this file also assumes you will be declaring the user's password via sops.
|
||||||
|
# .
|
||||||
|
# If you have no need for secondary users, simple delete this file and its parent directory, and ensure that
|
||||||
|
# your `nix-confitg/hosts/[platform]/[hostname]/default.nix` files do not import this file.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Basic user for viewing exampleSecondUser
|
||||||
|
#
|
||||||
|
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hostSpec = config.hostSpec;
|
||||||
|
secretsSubPath = "passwords/exampleSecondUser";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Decrypt passwords/exampleSecondUser to /run/secrets-for-users/ so it can be used to create the user
|
||||||
|
sops.secrets.${secretsSubPath}.neededForUsers = true;
|
||||||
|
users.mutableUsers = false; # Required for password to be set via sops during system activation!
|
||||||
|
|
||||||
|
users.users.exampleSecondUser = {
|
||||||
|
isNormalUser = true;
|
||||||
|
hashedPasswordFile = config.sops.secrets.${secretsSubPath}.path;
|
||||||
|
shell = pkgs.zsh; # default shell
|
||||||
|
extraGroups = [
|
||||||
|
"audio"
|
||||||
|
"video"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = [ pkgs.home-manager ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
# Import this user's personal/home configurations
|
||||||
|
// lib.optionalAttrs (inputs ? "home-manager") {
|
||||||
|
home-manager = {
|
||||||
|
extraSpecialArgs = {
|
||||||
|
inherit pkgs inputs;
|
||||||
|
hostSpec = config.hostSpec;
|
||||||
|
};
|
||||||
|
users.exampleSecondUser.imports = lib.flatten (
|
||||||
|
lib.optional (!hostSpec.isMinimal) [
|
||||||
|
(
|
||||||
|
{ config, ... }:
|
||||||
|
import (lib.custom.relativeToRoot "home/exampleSecondUser/${hostSpec.hostName}.nix") {
|
||||||
|
inherit
|
||||||
|
pkgs
|
||||||
|
inputs
|
||||||
|
config
|
||||||
|
lib
|
||||||
|
hostSpec
|
||||||
|
;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
7
hosts/common/users/primary/darwin.nix
Normal file
7
hosts/common/users/primary/darwin.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# User config applicable only to darwin
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
users.users.${config.hostSpec.username} = {
|
||||||
|
home = "/Users/${config.hostSpec.username}";
|
||||||
|
};
|
||||||
|
}
|
||||||
68
hosts/common/users/primary/default.nix
Normal file
68
hosts/common/users/primary/default.nix
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# NOTE(starter): this is the primary user across all hosts. The username for primary is defined in hostSpec,
|
||||||
|
# and is declared in `nix-config/common/core/default.nix`
|
||||||
|
|
||||||
|
# User config applicable to both nixos and darwin
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hostSpec = config.hostSpec;
|
||||||
|
pubKeys = lib.filesystem.listFilesRecursive ./keys;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
users.users.${hostSpec.username} = {
|
||||||
|
name = hostSpec.username;
|
||||||
|
shell = pkgs.bash; # default shell
|
||||||
|
|
||||||
|
# These get placed into /etc/ssh/authorized_keys.d/<name> on nixos
|
||||||
|
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create ssh sockets directory for controlpaths when homemanager not loaded (i.e. isMinimal)
|
||||||
|
systemd.tmpfiles.rules =
|
||||||
|
let
|
||||||
|
user = config.users.users.${hostSpec.username}.name;
|
||||||
|
group = config.users.users.${hostSpec.username}.group;
|
||||||
|
in
|
||||||
|
# you must set the rule for .ssh separately first, otherwise it will be automatically created as root:root and .ssh/sockects will fail
|
||||||
|
[
|
||||||
|
"d /home/${hostSpec.username}/.ssh 0750 ${user} ${group} -"
|
||||||
|
"d /home/${hostSpec.username}/.ssh/sockets 0750 ${user} ${group} -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# No matter what environment we are in we want these tools
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.just
|
||||||
|
pkgs.rsync
|
||||||
|
];
|
||||||
|
}
|
||||||
|
# Import the user's personal/home configurations, unless the environment is minimal
|
||||||
|
// lib.optionalAttrs (inputs ? "home-manager") {
|
||||||
|
home-manager = {
|
||||||
|
extraSpecialArgs = {
|
||||||
|
inherit pkgs inputs;
|
||||||
|
hostSpec = config.hostSpec;
|
||||||
|
};
|
||||||
|
users.${hostSpec.username}.imports = lib.flatten (
|
||||||
|
lib.optional (!hostSpec.isMinimal) [
|
||||||
|
(
|
||||||
|
{ config, ... }:
|
||||||
|
import (lib.custom.relativeToRoot "home/${hostSpec.username}/${hostSpec.hostName}.nix") {
|
||||||
|
inherit
|
||||||
|
pkgs
|
||||||
|
inputs
|
||||||
|
config
|
||||||
|
lib
|
||||||
|
hostSpec
|
||||||
|
;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
1
hosts/common/users/primary/keys/README.md
Normal file
1
hosts/common/users/primary/keys/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Add your ssh public keys to this directory. E.g. id_foo.pub
|
||||||
44
hosts/common/users/primary/nixos.nix
Normal file
44
hosts/common/users/primary/nixos.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# User config applicable only to nixos
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hostSpec = config.hostSpec;
|
||||||
|
ifTheyExist = groups: builtins.filter (group: builtins.hasAttr group config.users.groups) groups;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
users.mutableUsers = false; # Only allow declarative credentials; Required for password to be set via sops during system activation!
|
||||||
|
users.users.${hostSpec.username} = {
|
||||||
|
home = "/home/${hostSpec.username}";
|
||||||
|
isNormalUser = true;
|
||||||
|
password = "password";
|
||||||
|
|
||||||
|
extraGroups = lib.flatten [
|
||||||
|
"wheel"
|
||||||
|
(ifTheyExist [
|
||||||
|
"audio"
|
||||||
|
"video"
|
||||||
|
"docker"
|
||||||
|
"git"
|
||||||
|
"networkmanager"
|
||||||
|
"scanner" # for print/scan"
|
||||||
|
"lp" # for print/scan"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# No matter what environment we are in we want these tools for root, and the user(s)
|
||||||
|
programs.git.enable = true;
|
||||||
|
|
||||||
|
# root's ssh key are mainly used for remote deployment, borg, and some other specific ops
|
||||||
|
users.users.root = {
|
||||||
|
shell = pkgs.bash;
|
||||||
|
hashedPasswordFile = config.users.users.${hostSpec.username}.hashedPasswordFile;
|
||||||
|
hashedPassword = config.users.users.${hostSpec.username}.hashedPassword; # This comes from hosts/common/optional/minimal.nix and gets overridden if sops is working
|
||||||
|
openssh.authorizedKeys.keys = config.users.users.${hostSpec.username}.openssh.authorizedKeys.keys; # root's ssh keys are mainly used for remote deployment.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
73
hosts/host-template.nix.placeholder
Normal file
73
hosts/host-template.nix.placeholder
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
#
|
||||||
|
# ========== Hardware ==========
|
||||||
|
#
|
||||||
|
./hardware-configuration.nix
|
||||||
|
#inputs.hardware.nixosModules.common-cpu-amd
|
||||||
|
#inputs.hardware.nixosModules.common-cpu-intel
|
||||||
|
#inputs.hardware.nixosModules.common-gpu-nvidia
|
||||||
|
#inputs.hardware.nixosModules.common-gpu-intel
|
||||||
|
#inputs.hardware.nixosModules.common-pc-ssd
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Disk Layout ==========
|
||||||
|
#
|
||||||
|
#inputs.disko.nixosModules.disko
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Misc Inputs ==========
|
||||||
|
#
|
||||||
|
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
#
|
||||||
|
# ========== Required Configs ==========
|
||||||
|
#
|
||||||
|
"hosts/common/core"
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Non-Primary Users to Create ==========
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Optional Configs ==========
|
||||||
|
#
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Host Specification ==========
|
||||||
|
#
|
||||||
|
|
||||||
|
hostSpec = {
|
||||||
|
hostName = "foo";
|
||||||
|
scaling = lib.mkForce "1";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
networkmanager.enable = true;
|
||||||
|
enableIPv6 = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.loader = {
|
||||||
|
systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
efi.canTouchEfiVariables = true;
|
||||||
|
timeout = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd = {
|
||||||
|
systemd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://wiki.nixos.org/wiki/FAQ/When_do_I_update_stateVersion
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
||||||
107
hosts/nixos/Bellerophon/default.nix
Normal file
107
hosts/nixos/Bellerophon/default.nix
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# This is an example nixos hosts module.
|
||||||
|
# They will automatically be imported below.
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
#
|
||||||
|
# Bellerophon - Example Desktop
|
||||||
|
#
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = lib.flatten [
|
||||||
|
#
|
||||||
|
# ========== Hardware ==========
|
||||||
|
#
|
||||||
|
inputs.nixos-hardware.nixosModules.common-cpu-intel
|
||||||
|
inputs.nixos-hardware.nixosModules.common-hidpi
|
||||||
|
inputs.nixos-hardware.nixosModules.common-pc-laptop
|
||||||
|
inputs.nixos-hardware.nixosModules.common-pc-laptop-ssd
|
||||||
|
|
||||||
|
./hardware-configuration.nix
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Disk Layout ==========
|
||||||
|
#
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
# FIXME(starter): modify with the disko spec file you want to use.
|
||||||
|
(lib.custom.relativeToRoot "hosts/common/disks/luks-btrfs-disk.nix")
|
||||||
|
# FIXME(starter): modify the options below to inform disko of the host's disk path and swap requirements.
|
||||||
|
# IMPORTANT: nix-config-starter assumes a single disk per host. If you require more disks, you
|
||||||
|
# must modify or create new dikso specs.
|
||||||
|
{
|
||||||
|
_module.args = {
|
||||||
|
disk = "/dev/nvme0n1";
|
||||||
|
withSwap = true;
|
||||||
|
swapSize = "64";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
#
|
||||||
|
# ========== Required Configs ==========
|
||||||
|
#
|
||||||
|
"hosts/common/core"
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Non-Primary Users to Create ==========
|
||||||
|
#
|
||||||
|
# FIXME(starter): the primary user, defined in `nix-config/hosts/common/users`, is added by default, via
|
||||||
|
# `hosts/common/core` above.
|
||||||
|
# To create additional users, specify the path to their config file, as shown in the commented line below, and create/modify
|
||||||
|
# the specified file as required. See `nix-config/hosts/common/users/exampleSecondUser` for more info.
|
||||||
|
|
||||||
|
#"hosts/common/users/exampleSecondUser"
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Optional Configs ==========
|
||||||
|
#
|
||||||
|
# FIXME(starter): add or remove any optional host-level configuration files the host will use
|
||||||
|
# The following are for example sake only and are not necessarily required.
|
||||||
|
"hosts/common/optional/services/openssh.nix" # allow remote SSH access
|
||||||
|
"hosts/common/optional/audio.nix" # pipewire and cli controls
|
||||||
|
"hosts/common/optional/kde.nix"
|
||||||
|
"hosts/common/optional/sddm.nix"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
#
|
||||||
|
# ========== Host Specification ==========
|
||||||
|
#
|
||||||
|
|
||||||
|
# FIXME(starter): declare any host-specific hostSpec options. Note that hostSpec options pertaining to
|
||||||
|
# more than one host can be declared in `nix-config/hosts/common/core/` see the default.nix file there
|
||||||
|
# for examples.
|
||||||
|
hostSpec = {
|
||||||
|
hostName = "Bellerophon";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
networkmanager.enable = true;
|
||||||
|
enableIPv6 = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.loader = {
|
||||||
|
systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
# When using plymouth, initrd can expand by a lot each time, so limit how many we keep around
|
||||||
|
configurationLimit = lib.mkDefault 10;
|
||||||
|
};
|
||||||
|
efi.canTouchEfiVariables = true;
|
||||||
|
timeout = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd = {
|
||||||
|
systemd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.graphics = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
# https://wiki.nixos.org/wiki/FAQ/When_do_I_update_stateVersion
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
||||||
49
hosts/nixos/Bellerophon/hardware-configuration.nix
Normal file
49
hosts/nixos/Bellerophon/hardware-configuration.nix
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# 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" "thunderbolt" "vmd" "nvme" "usbhid"];
|
||||||
|
boot.initrd.kernelModules = [];
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_6_12;
|
||||||
|
boot.kernelModules = ["kvm-intel"];
|
||||||
|
boot.kernelPatches = [
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name = "zenbook-asus-wmi";
|
||||||
|
patch = ./zenbook-asus-wmi.patch;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
# 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.docker0.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
sof-firmware
|
||||||
|
|
||||||
|
#rotation stuff
|
||||||
|
pkgs.gnome-monitor-config
|
||||||
|
pkgs.usbutils
|
||||||
|
pkgs.inotify-tools
|
||||||
|
pkgs.kdePackages.libkscreen
|
||||||
|
];
|
||||||
|
}
|
||||||
107
hosts/nixos/iso/default.nix
Normal file
107
hosts/nixos/iso/default.nix
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#NOTE: This ISO is NOT minimal. We don't want a minimal environment when using the iso for recovery purposes.
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = lib.flatten [
|
||||||
|
# FIXME(starter): comment/uncomment the following two lines depending on if you want a cli-only, minimal iso, or a graphical iso that installs gnome
|
||||||
|
# If you are planning to make use of `nix-config/nixos-installer`, you will not require a graphical iso.
|
||||||
|
"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
|
||||||
|
#"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix"
|
||||||
|
"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/channel.nix"
|
||||||
|
# This is overkill but I want my core home level utils if I need to use the iso environment for recovery purpose
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
"modules/common/host-spec.nix"
|
||||||
|
# We want primary default so we get ssh authorized keys, zsh, and some basic tty tools. It also pulls in the hm spec for iso.
|
||||||
|
# Note that we are not pulling in "hosts/common/users/primary/nixos.nix" for the iso as it's not needed.
|
||||||
|
"hosts/common/users/primary/"
|
||||||
|
"hosts/common/optional/minimal-user.nix"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
hostSpec = {
|
||||||
|
hostName = "iso";
|
||||||
|
# FIXME(starter): the username below will be available in additional the the standard `root` and `nixos` users from the nixos installation image.
|
||||||
|
username = "panotaka";
|
||||||
|
isProduction = lib.mkForce false;
|
||||||
|
|
||||||
|
# FIXME(starter): add your github username and github-noreply email address
|
||||||
|
handle = "panotaka";
|
||||||
|
#email.gitHub = "foo@users.noreply.github.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
# root's ssh key are mainly used for remote deployment
|
||||||
|
users.extraUsers.root = {
|
||||||
|
inherit (config.users.users.${config.hostSpec.username}) hashedPassword;
|
||||||
|
openssh.authorizedKeys.keys =
|
||||||
|
config.users.users.${config.hostSpec.username}.openssh.authorizedKeys.keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
isoBuildTime = {
|
||||||
|
#
|
||||||
|
text = lib.readFile (
|
||||||
|
"${pkgs.runCommand "timestamp" {
|
||||||
|
# builtins.currentTime requires --impure
|
||||||
|
env.when = builtins.currentTime;
|
||||||
|
} "echo -n `date -d @$when +%Y-%m-%d_%H-%M-%S` > $out"}"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add the build time to the prompt so it's easier to know the ISO age
|
||||||
|
programs.bash.promptInit = ''
|
||||||
|
export PS1="\\[\\033[01;32m\\]\\u@\\h-$(cat /etc/isoBuildTime)\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ "
|
||||||
|
'';
|
||||||
|
|
||||||
|
# The default compression-level is (6) and takes too long on some machines (>30m). 3 takes <2m
|
||||||
|
isoImage.squashfsCompression = "zstd -Xcompression-level 3";
|
||||||
|
|
||||||
|
nixpkgs = {
|
||||||
|
hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
extraOptions = "experimental-features = nix-command flakes";
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
qemuGuest.enable = true;
|
||||||
|
openssh = {
|
||||||
|
settings.PermitRootLogin = lib.mkForce "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
supportedFilesystems = lib.mkForce [
|
||||||
|
"btrfs"
|
||||||
|
"vfat"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "iso";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
|
||||||
|
# gnome power settings to not turn off screen
|
||||||
|
targets = {
|
||||||
|
sleep.enable = false;
|
||||||
|
suspend.enable = false;
|
||||||
|
hibernate.enable = false;
|
||||||
|
hybrid-sleep.enable = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
130
justfile
Normal file
130
justfile
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
SOPS_FILE := "../nix-secrets/.sops.yaml"
|
||||||
|
|
||||||
|
# Define path to helpers
|
||||||
|
export HELPERS_PATH := justfile_directory() + "/scripts/helpers.sh"
|
||||||
|
|
||||||
|
# default recipe to display help information
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
# Update commonly changing flakes and prep for a rebuild
|
||||||
|
rebuild-pre: update-nix-secrets
|
||||||
|
@git add --intent-to-add .
|
||||||
|
|
||||||
|
# Run post-rebuild checks, like if sops is running properly afterwards
|
||||||
|
rebuild-post: check-sops
|
||||||
|
|
||||||
|
# Run a flake check on the config and installer
|
||||||
|
check ARGS="":
|
||||||
|
NIXPKGS_ALLOW_UNFREE=1 REPO_PATH=$(pwd) nix flake check --impure --keep-going --show-trace {{ARGS}}
|
||||||
|
cd nixos-installer && NIXPKGS_ALLOW_UNFREE=1 REPO_PATH=$(pwd) nix flake check --impure --keep-going --show-trace {{ARGS}}
|
||||||
|
|
||||||
|
# Rebuild the system
|
||||||
|
rebuild: rebuild-pre && rebuild-post
|
||||||
|
# NOTE: Add --option eval-cache false if you end up caching a failure you cant get around
|
||||||
|
scripts/rebuild.sh
|
||||||
|
|
||||||
|
# Rebuild the system and run a flake check
|
||||||
|
rebuild-full: rebuild-pre && rebuild-post
|
||||||
|
scripts/rebuild.sh
|
||||||
|
just check
|
||||||
|
|
||||||
|
# Rebuild the system and run a flake check
|
||||||
|
rebuild-trace: rebuild-pre && rebuild-post
|
||||||
|
scripts/rebuild.sh trace
|
||||||
|
just check
|
||||||
|
|
||||||
|
# Update the flake
|
||||||
|
update:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
# Update and then rebuild
|
||||||
|
rebuild-update: update rebuild
|
||||||
|
|
||||||
|
# Git diff there entire repo expcept for flake.lock
|
||||||
|
diff:
|
||||||
|
git diff ':!flake.lock'
|
||||||
|
|
||||||
|
# Generate a new age key
|
||||||
|
age-key:
|
||||||
|
nix-shell -p age --run "age-keygen"
|
||||||
|
|
||||||
|
# Check if sops-nix activated successfully
|
||||||
|
check-sops:
|
||||||
|
scripts/check-sops.sh
|
||||||
|
|
||||||
|
# Update nix-secrets flake
|
||||||
|
update-nix-secrets:
|
||||||
|
@(cd ../nix-secrets && git fetch && git rebase > /dev/null) || true
|
||||||
|
nix flake update nix-secrets --timeout 5
|
||||||
|
|
||||||
|
# Build an iso image for installing new systems and create a symlink for qemu usage
|
||||||
|
iso:
|
||||||
|
# If we dont remove this folder, libvirtd VM doesnt run with the new iso...
|
||||||
|
rm -rf result
|
||||||
|
nix build --impure .#nixosConfigurations.iso.config.system.build.isoImage && ln -sf result/iso/*.iso latest.iso
|
||||||
|
|
||||||
|
# Install the latest iso to a flash drive
|
||||||
|
iso-install DRIVE: iso
|
||||||
|
sudo dd if=$(eza --sort changed result/iso/*.iso | tail -n1) of={{DRIVE}} bs=4M status=progress oflag=sync
|
||||||
|
|
||||||
|
# Configure a drive password using disko
|
||||||
|
disko DRIVE PASSWORD:
|
||||||
|
echo "{{PASSWORD}}" > /tmp/disko-password
|
||||||
|
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- \
|
||||||
|
--mode disko \
|
||||||
|
disks/btrfs-luks-impermanence-disko.nix \
|
||||||
|
--arg disk '"{{DRIVE}}"' \
|
||||||
|
--arg password '"{{PASSWORD}}"'
|
||||||
|
rm /tmp/disko-password
|
||||||
|
|
||||||
|
# Copy all the config files to the remote host
|
||||||
|
sync USER HOST PATH:
|
||||||
|
rsync -av --filter=':- .gitignore' -e "ssh -l {{USER}} -oport=22" . {{USER}}@{{HOST}}:{{PATH}}/nix-config
|
||||||
|
|
||||||
|
# Run nixos-rebuild on the remote host
|
||||||
|
build-host HOST:
|
||||||
|
NIX_SSHOPTS="-p22" nixos-rebuild --target-host {{HOST}} --use-remote-sudo --show-trace --impure --flake .#"{{HOST}}" switch
|
||||||
|
|
||||||
|
# Called by the rekey recipe
|
||||||
|
sops-rekey:
|
||||||
|
cd ../nix-secrets && for file in $(ls sops/*.yaml); do \
|
||||||
|
sops updatekeys -y $file; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# Update all keys in sops/*.yaml files in nix-secrets to match the creation rules keys
|
||||||
|
rekey: sops-rekey
|
||||||
|
cd ../nix-secrets && \
|
||||||
|
(pre-commit run --all-files || true) && \
|
||||||
|
git add -u && (git commit -nm "chore: rekey" || true) && git push
|
||||||
|
|
||||||
|
# Update an age key anchor or add a new one
|
||||||
|
sops-update-age-key FIELD KEYNAME KEY:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
source {{HELPERS_PATH}}
|
||||||
|
sops_update_age_key {{FIELD}} {{KEYNAME}} {{KEY}}
|
||||||
|
|
||||||
|
# Update an existing user age key anchor or add a new one
|
||||||
|
sops-update-user-age-key USER HOST KEY:
|
||||||
|
just sops-update-age-key users {{USER}}_{{HOST}} {{KEY}}
|
||||||
|
|
||||||
|
# Update an existing host age key anchor or add a new one
|
||||||
|
sops-update-host-age-key HOST KEY:
|
||||||
|
just sops-update-age-key hosts {{HOST}} {{KEY}}
|
||||||
|
|
||||||
|
# Automatically create creation rules entries for a <host>.yaml file for host-specific secrets
|
||||||
|
sops-add-host-creation-rules USER HOST:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
source {{HELPERS_PATH}}
|
||||||
|
sops_add_host_creation_rules "{{USER}}" "{{HOST}}"
|
||||||
|
|
||||||
|
# Automatically create creation rules entries for a shared.yaml file for shared secrets
|
||||||
|
sops-add-shared-creation-rules USER HOST:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
source {{HELPERS_PATH}}
|
||||||
|
sops_add_shared_creation_rules "{{USER}}" "{{HOST}}"
|
||||||
|
|
||||||
|
# Automatically add the host and user keys to creation rules for shared.yaml and <host>.yaml
|
||||||
|
sops-add-creation-rules USER HOST:
|
||||||
|
just sops-add-host-creation-rules {{USER}} {{HOST}} && \
|
||||||
|
just sops-add-shared-creation-rules {{USER}} {{HOST}}
|
||||||
21
lib/default.nix
Normal file
21
lib/default.nix
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#NOTE(starter): custom functions added here are available via `lib.custom.foo` by passing `lib` into
|
||||||
|
# the expression parameters. The two functions below are used by `nix-config` and should not be modified.
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
# use path relative to the root of the project
|
||||||
|
relativeToRoot = lib.path.append ../.;
|
||||||
|
scanPaths =
|
||||||
|
path:
|
||||||
|
builtins.map (f: (path + "/${f}")) (
|
||||||
|
builtins.attrNames (
|
||||||
|
lib.attrsets.filterAttrs (
|
||||||
|
path: _type:
|
||||||
|
(_type == "directory") # include directories
|
||||||
|
|| (
|
||||||
|
(path != "default.nix") # ignore default.nix
|
||||||
|
&& (lib.strings.hasSuffix ".nix" path) # include .nix files
|
||||||
|
)
|
||||||
|
) (builtins.readDir path)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
9
modules/common/default.nix
Normal file
9
modules/common/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Add your reusable modules that are common across both home and hosts to this directory, in their own file (https://wiki.nixos.org/wiki/NixOS_modules).
|
||||||
|
# They will automatically be imported below but must be enabled elsewhere in the config, such as in common/core,
|
||||||
|
# common/optional, or common/hosts files for example.
|
||||||
|
# These are modules not specific to either nixos, darwin, or home-manger that you would share with others, not your personal configurations.
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.custom.scanPaths ./.;
|
||||||
|
}
|
||||||
153
modules/common/host-spec.nix
Normal file
153
modules/common/host-spec.nix
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
# Specifications For Differentiating Hosts
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
options.hostSpec = {
|
||||||
|
# Data variables that don't dictate configuration settings
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The username of the host";
|
||||||
|
};
|
||||||
|
hostName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The hostname of the host";
|
||||||
|
};
|
||||||
|
email = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
description = "The email of the user";
|
||||||
|
};
|
||||||
|
work = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf lib.types.anything;
|
||||||
|
description = "An attribute set of work-related information if isWork is true";
|
||||||
|
};
|
||||||
|
networking = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf lib.types.anything;
|
||||||
|
description = "An attribute set of networking information";
|
||||||
|
};
|
||||||
|
wifi = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate if a host has wifi";
|
||||||
|
};
|
||||||
|
domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The domain of the host";
|
||||||
|
};
|
||||||
|
userFullName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The full name of the user";
|
||||||
|
};
|
||||||
|
handle = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The handle of the user (eg: github user)";
|
||||||
|
};
|
||||||
|
home = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The home directory of the user";
|
||||||
|
default =
|
||||||
|
let
|
||||||
|
user = config.hostSpec.username;
|
||||||
|
in
|
||||||
|
if pkgs.stdenv.isLinux then "/home/${user}" else "/Users/${user}";
|
||||||
|
};
|
||||||
|
persistFolder = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The folder to persist data if impermenance is enabled";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configuration Settings
|
||||||
|
isMinimal = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a minimal host";
|
||||||
|
};
|
||||||
|
isProduction = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Used to indicate a production host";
|
||||||
|
};
|
||||||
|
isServer = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a server host";
|
||||||
|
};
|
||||||
|
isWork = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that uses work resources";
|
||||||
|
};
|
||||||
|
# Sometimes we can't use pkgs.stdenv.isLinux due to infinite recursion
|
||||||
|
isDarwin = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that is darwin";
|
||||||
|
};
|
||||||
|
useYubikey = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate if the host uses a yubikey";
|
||||||
|
};
|
||||||
|
voiceCoding = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that uses voice coding";
|
||||||
|
};
|
||||||
|
isAutoStyled = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that wants auto styling like stylix";
|
||||||
|
};
|
||||||
|
useNeovimTerminal = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that uses neovim for terminals";
|
||||||
|
};
|
||||||
|
useWindowManager = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Used to indicate a host that uses a window manager";
|
||||||
|
};
|
||||||
|
useAtticCache = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Used to indicate a host that uses LAN atticd for caching";
|
||||||
|
};
|
||||||
|
hdr = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Used to indicate a host that uses HDR";
|
||||||
|
};
|
||||||
|
scaling = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "1";
|
||||||
|
description = "Used to indicate what scaling to use. Floating point number";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
assertions =
|
||||||
|
let
|
||||||
|
# We import these options to HM and NixOS, so need to not fail on HM
|
||||||
|
isImpermanent =
|
||||||
|
config ? "system" && config.system ? "impermanence" && config.system.impermanence.enable;
|
||||||
|
in
|
||||||
|
[
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
!config.hostSpec.isWork || (config.hostSpec.isWork && !builtins.isNull config.hostSpec.work);
|
||||||
|
message = "isWork is true but no work attribute set is provided";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !isImpermanent || (isImpermanent && !("${config.hostSpec.persistFolder}" == ""));
|
||||||
|
message = "config.system.impermanence.enable is true but no persistFolder path is provided";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
9
modules/home/default.nix
Normal file
9
modules/home/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Add your reusable home-manager modules to this directory, in their own file (https://wiki.nixos.org/wiki/NixOS_modules).
|
||||||
|
# They will automatically be imported below but must be enabled elsewhere in the config, such as in common/core,
|
||||||
|
# common/optional, or common/hosts files for example.
|
||||||
|
# These are modules you would share with others, not your personal configurations.
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.custom.scanPaths ./.;
|
||||||
|
}
|
||||||
10
modules/hosts/common/default.nix
Normal file
10
modules/hosts/common/default.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Add your reusable host-level modules that are common across both nixos and darwin to this directory, in
|
||||||
|
# their own file (https://wiki.nixos.org/wiki/NixOS_modules).
|
||||||
|
# They will automatically be imported below but must be enabled elsewhere in the config, such as in common/core,
|
||||||
|
# common/optional, or common/hosts files for example.
|
||||||
|
# These are modules you would share with others, not your personal configurations.
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.custom.scanPaths ./.;
|
||||||
|
}
|
||||||
9
modules/hosts/darwin/default.nix
Normal file
9
modules/hosts/darwin/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Add your reusable nix-darwin modules to this directory, in their own file (https://wiki.nixos.org/wiki/NixOS_modules).
|
||||||
|
# They will automatically be imported below but must be enabled elsewhere in the config, such as in common/core,
|
||||||
|
# common/optional, or common/hosts files for example.
|
||||||
|
# These are modules you would share with others, not your personal configurations.
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.custom.scanPaths ./.;
|
||||||
|
}
|
||||||
9
modules/hosts/nixos/default.nix
Normal file
9
modules/hosts/nixos/default.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Add your reusable NixOS modules to this directory, in their own file (https://wiki.nixos.org/wiki/NixOS_modules).
|
||||||
|
# They will automatically be imported below but must be enabled elsewhere in the config, such as in common/core,
|
||||||
|
# common/optional, or common/hosts files for example.
|
||||||
|
# These are modules you would share with others, not your personal configurations.
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
imports = lib.custom.scanPaths ./.;
|
||||||
|
}
|
||||||
312
nixos-installer/README.md
Normal file
312
nixos-installer/README.md
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
# NixOS Installer for Nix-Config
|
||||||
|
|
||||||
|
This flake is separate from the main nix-config flake and prepares a Nix environment for bootstrapping a nix-config host on a new machine. Most of the process is automated with the [`nixos-bootstrap.sh`](../scripts/nixos-bootstraph.sh) script that is run on a "source" host to install NixOS on a "target" machine. There are a couple of small manual steps that are typical of any OS installation procedure, such defining information about the target host and adding host-specific secrets to the relevant sops secrets file. This document explains some of the reasoning behind the use of a separate flake and then provides installation steps. For a more indepth look at some of the concepts, reasoning, and automation process, see the blog post [Remotely Installing NixOS and nix-config with Secrets](https://unmovedcentre.com/posts/remote-install-nixos-config/) on my website. Note that the blog post was written during the first iteration of the bootstrap script and there have been significant enhancements to the code since that time. The general idea and flow still stand and may provide useful insight to understanding the script itself, for those who want to learn more about what it does.
|
||||||
|
|
||||||
|
- [Why an extra flake?](#why-an-extra-flake)
|
||||||
|
- [Assumptions](#assumptions)
|
||||||
|
- [Generating a custom NixOS ISO](#generating-a-custom-nixos-iso)
|
||||||
|
- [Requirements for Installing a New Host](#requirements-for-installing-a-new-host)
|
||||||
|
- [Requirements for installing an existing nix-config host on a new machine](requirements-for-installing-an-existing-nix-config-host-on-a-new-machine)
|
||||||
|
- [Installation Steps](#installation-steps)
|
||||||
|
- [Troubleshooting](#Troubleshooting)
|
||||||
|
|
||||||
|
## Why an extra flake?
|
||||||
|
|
||||||
|
The main flake, `nix-config/flake.nix`, takes longer to build, debug, and deploy because even the core modules are focused on a broad set of functional requirements. In contrast, this simplified flake is focused only on providing an environment with which to accomplish the following:
|
||||||
|
|
||||||
|
- Prepare the machine to successfully authenticate with our private nix-secrets repo _and_ decrypt the required secrets when the main flake is built.
|
||||||
|
- Adjust and verify the new host's `hardware-configuration.nix` and potentially modify it prior to building the main flake.
|
||||||
|
- We also have the option of testing new filesystem related features such as impermanence, Secure Boot, TPM2, Encryption, etc in a light weight environment prior to finalizing the main flake.
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
The installer and instructions here assume that a _private_ nix-secrets repository is in use in conjunction with the nix-config _and_ the nix-secrets repo is structured to use shared secrets as well as host-specific secrets. Reference the _complex_ branch of the [nix-secrets-reference](https://github.com/EmergentMind/nix-secrets-reference) repository for an example of the expected structure as well as the article on [NixOS Secrets Management](https://unmovedcentre.com/posts/secrets-management/) to learn more.
|
||||||
|
|
||||||
|
For users new to Nix and NixOS it may be worth noting that because this script is installing NixOS, the usual [NixOS requirements](https://nixos.org/download/#nixos-iso) apply.
|
||||||
|
|
||||||
|
## Generating a custom NixOS ISO
|
||||||
|
|
||||||
|
We recommend using a custom ISO similar to what is defined in `nix-config/hosts/nixos/iso`. The official minimal NixOS iso has historical omitted some basic tty utilities that are expected by the installer scripts. The config for the ISO used in nix-config are similarly light-weight to [`nixos-installer/flake.nix`](flake.nix).
|
||||||
|
|
||||||
|
To generate the ISO, simply run `just iso` from the root of your `nix-config` directory. The resulting .iso file will be saved to `nix-config/result/iso/foo.iso`. A symlink to the file is also created at `nix-config/latest.iso`. The filename is time stamped for convenient reference when frequently trying out different ISOs in VMs. For example, `nixos-24.11.20250123.035f8c0-x86_64-linux.iso`.
|
||||||
|
|
||||||
|
If you are installing the host to a VM or remote infrastructure, configure the machine to boot into the .iso file.
|
||||||
|
|
||||||
|
If you are installing on a bare metal machine, write the .iso to a USB device. You can generate the iso and write it to a device in one command, using `just iso /path/to/usb/device`.
|
||||||
|
|
||||||
|
## Requirements for installing a new host
|
||||||
|
|
||||||
|
### Pre-installation steps:
|
||||||
|
|
||||||
|
1. Add `nix-config/hosts/nixos/[hostname]/` and `nix-config/home/[user]/[hostname].nix` files. You must declare the configuration settings for the target host as usual in your nix-config.
|
||||||
|
Be sure to specify the device name (e.g. sda, nvme0n1, vda, etc) you want to install to along with the desired `nix-config/hosts/common/disks` disko spec.
|
||||||
|
|
||||||
|
If needed, you can find the device name on the target machine itself by booting it into the iso environment and running `lsblk` to see a list of the devices. Virtual Machines often using a device called `vda`.
|
||||||
|
2. Add a `newConfig` entry for the target host in `nix-config/nixos-installer/flake.nix`, passing in the required arguments as noted in the file comments.
|
||||||
|
3. If you are planning to use the `backup` module on the target host, you _must_ temporarily disable it in the target host's config options until bootstrapping is complete. Failure to disable these two modules, will cause nix-config to look for the associated secrets in the new `[hostname].yaml` secrets file where they have not yet been added, causing sops-nix to fail to start during the build process. After rebuilding, we'll add the required keys to secrets and re-enable these modules.
|
||||||
|
For example:
|
||||||
|
```nix
|
||||||
|
# nix-config/hosts/nixos/guppy/default.nix
|
||||||
|
#--------------------
|
||||||
|
|
||||||
|
# ...
|
||||||
|
# The back module is enabled via a services option. Set it to false.
|
||||||
|
services.backup = {
|
||||||
|
enable = false;
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
#...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### A note about secrets
|
||||||
|
|
||||||
|
There are different ways to set up secrets for a new target host. Some are more involved than others but they _all_ require some level of manual entry.
|
||||||
|
The installer script automates many of the required steps and therefore we will only describe the process of relying on that automation and making required manual entries near the end of the installation process.
|
||||||
|
|
||||||
|
In brief, the script will:
|
||||||
|
|
||||||
|
- create a host-specific age key pair
|
||||||
|
- create a host-specific user age key pair for the primary user
|
||||||
|
- create a `nix-secrets/sops/[hostname].yaml` secrets file with the user age private key (the host age private key is always derived from the host ssh key and therefore does not need to be stored in secrets)
|
||||||
|
- update the `.sops.yaml` file with:
|
||||||
|
- public age keys entries for both the host and user
|
||||||
|
- update the `creation_rules` for `shared.yaml` with the host and user age keys for the target host.
|
||||||
|
- create a new `creation_rules` entry for `[hostname].yaml` specifying that the secrets file can be encrypted and decrypted by the primary user and host of both the target host _AND_ the host from which the installation script is being executed. This is important because until the target host has been fully bootstrapped, its `[hostname].yaml` must be accessible by something.
|
||||||
|
|
||||||
|
For example, a host `ghost` running the installer script on target host `guppy` will result in the following sops `creation_rules` entry in `.sops.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- path_regex: guppy\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *ta_guppy
|
||||||
|
- *guppy
|
||||||
|
- *ta_ghost
|
||||||
|
- *ghost
|
||||||
|
```
|
||||||
|
|
||||||
|
As mentioned, the time for manual steps will be noted below.
|
||||||
|
|
||||||
|
## Requirements for installing an existing nix-config host on a new machine
|
||||||
|
|
||||||
|
Prior to installing an existing host config onto a new machine you likely only need to ensure that the `nix-config//hosts/nixos/[hostname]/default.nix`specific the correct disk device for disko.
|
||||||
|
|
||||||
|
Your existing config should already have a `hardware-configuration.nix` and a functioning compliment of sops secrets and sops creation rules. Therefore, many of the steps presented by the script can be safely skipped. The applicable steps will be noted below.
|
||||||
|
|
||||||
|
If you haven't already, add a `newConfig` entry for the target host in `nix-config/nixos-installer/flake.nix`, passing in the required arguments as noted in the file comments.
|
||||||
|
|
||||||
|
## Installation Steps
|
||||||
|
|
||||||
|
### 0. VM setup (optional)
|
||||||
|
|
||||||
|
This is only relevant if you are _not_ installing the target host on bare metal.
|
||||||
|
|
||||||
|
- Disk size: a decent _minimum_ disk size without swap is 25GB to accommodate for multiple generations on a testing machine.
|
||||||
|
If you are using swap, remember that the space will come from the main disk you allocated for the VM so be sure to allocate enough _additional_ main disk space to accommodate your swap size needs.
|
||||||
|
For example, if you need 50GB of storage for you machine and you also specified a swapsize of 8GB in nix-config, then allocate 48GB for the VMs disk size.
|
||||||
|
- You _must_ set up the hypervisor firmware to use UEFI instead of BIOS or the VM will fail to boot into the minimal-configuration.
|
||||||
|
When creating the VM using virtmanager, you must select "Customize configuration before install" during step 5 of 5, and then change BIOS to UEFI on the next screen.
|
||||||
|
- For the CD/DVD-ROM source path select the custom iso file.
|
||||||
|
- Ensure the boot order is sane for automated reboots. For example, on VirtManager, set `VirtIO Disk 1` ahead of `SATA CDROM`, ensure both are checked, and also check `Enable boot menu` so that you can easily override the boot order on reboot if need be.
|
||||||
|
|
||||||
|
NOTE: If you encounter installation problems during reboot into the minimal-configuration, refer to [Troubleshooting](#troubleshooting) as there are a couple of different causes.
|
||||||
|
|
||||||
|
### 1. Initial boot
|
||||||
|
|
||||||
|
Boot the target machine into the NixOS ISO environment.
|
||||||
|
|
||||||
|
If necessary, note the IP address of the machine by running `ip a`.
|
||||||
|
|
||||||
|
### 2. Run the bootstrap script
|
||||||
|
|
||||||
|
On the source machine where nix-config already resides, run the following command from the root of `nix-confg`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/bootstrap-nixos.sh -n [hostname] -d [destination]
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `[hostname]` with the name of the target host you are installing.
|
||||||
|
Replace `[destination]` with the location of the target machine.
|
||||||
|
Be sure to specify `--impermanence` if necessary. Use `--debug` if something goes wrong...
|
||||||
|
|
||||||
|
This is an example of running the script from `nix-config` base folder installing on a VM (`guppy`) with the `--debug` flag enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/bootstrap-nixos.sh -n guppy -d=192.168.122.29 --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will give you several yes/no or no/yes questions. The questions are fairly self explanatory but we'll go through them here and make some notes that will be valuable depending on whether you are bootstrapping a new or existing host.
|
||||||
|
|
||||||
|
|
||||||
|
1. "Run nixos-anywhere installation?" default yes - This initiates installation of the minimal-config environment.
|
||||||
|
1. "Manually set luks encryption passphrase?" default no - if you are using LUKS, say "y" and enter a temporary password when prompted. Disko will use for setting up LUKS and you can change it when installation is complete.
|
||||||
|
2. "Generate a new hardware config for this host? Yes if your nix-config doesn't have an entry for this host." default no - Say yes only for new hosts that don't have a premade `hardware-configuration.nix`
|
||||||
|
3. "Has your system restarted and are you ready to continue? (no exits)" - This is important. Nixosanywhere, will report the target host as available prior to it being fully rebooted. Wait until the target host prints a log in prompt before saying yes.
|
||||||
|
2. "Generate host (ssh-based) age key?" default yes - usually only needed for new hosts
|
||||||
|
3. "Generate user age key?" default yes - usually only needed for new hosts
|
||||||
|
4. "Add ssh host fingerprints for git{lab,hub}?" default yes - this will setup the full nix-config accessing nix-secrets as an input during the next steps
|
||||||
|
5. "Do you want to copy your full nix-config and nix-secrets to $target_hostname?" default yes - copies the source of both repos from the source machine to the target machine, faster than cloning from github/lab
|
||||||
|
1. "Do you want to rebuild immediately?" default yes - builds the full config
|
||||||
|
6. "Do you want to commit and push the generated hardware-configuration.nix for $target_hostname to nix-config?" default yes - This will _only_ be presented if you said yes to question 1.2 and will push the file to your repo with an appropriate commit message.
|
||||||
|
|
||||||
|
Note: these questions are largely in place to allow subsequent running of the script when errors are encountered without being required to start from the very beginning again. For example, if you get all the way to step 5.1 and there was a problem with your final config for the target host that causes a build failure, you can fix the issue on your source host, rerun the script, skip through all of the questions until 5, and then pick up where you left off.
|
||||||
|
|
||||||
|
|
||||||
|
On completion, the script should end with a "Success!" message.
|
||||||
|
|
||||||
|
Depending on your host, the following post-install steps may not be required.
|
||||||
|
|
||||||
|
### 3. Post install steps for LUKS (optional)
|
||||||
|
|
||||||
|
#### Change LUKS2's passphrase if you entered a temporary passphrase during bootstrap
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# when entering /path/to/dev/ you must specify the partition (e.g. /dev/nvmeon1p2)
|
||||||
|
# test the old passphrase
|
||||||
|
sudo cryptsetup --verbose open --test-passphrase /path/to/dev/
|
||||||
|
|
||||||
|
# change the passphrase
|
||||||
|
sudo cryptsetup luksChangeKey /path/to/dev/
|
||||||
|
|
||||||
|
# test the new passphrase
|
||||||
|
sudo cryptsetup --verbose open --test-passphrase /path/to/dev/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Enroll yubikeys for touch-based unlock
|
||||||
|
Enable yubikey support:
|
||||||
|
|
||||||
|
NOTE: This requires LUKS2 (use cryptsetup luksDump /path/to/dev/ to check)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemd-cryptenroll --fido2-device=auto /path/to/dev/
|
||||||
|
```
|
||||||
|
|
||||||
|
You will need to do it for each yubikey you want to use.
|
||||||
|
|
||||||
|
#### Update the unlock passphrase for secondary drive unlock
|
||||||
|
If you passed the `--luks-secondary-drive-labels` arg when running the bootstrap script, it automatically created a `/luks-secondary-unlock.key` file for you using the passphrase you specified during bootstrap.
|
||||||
|
If you used a temporary passphrase during bootstrap, you can update the secondary unlock key by running the following command and following the prompts.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cryptsetup luksChangeKey /luks-secondary-unlock.key
|
||||||
|
```
|
||||||
|
|
||||||
|
#### If you forgot to use the `--luks-secondary-drive-labels` arg during bootstrap but need to set it up
|
||||||
|
|
||||||
|
From - https://wiki.nixos.org/wiki/Full_Disk_Encryption#Unlocking_secondary_drives :
|
||||||
|
|
||||||
|
1. Create a keyfile for your secondary drive(s), store it safely and add it as a LUKS key:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# dd bs=512 count=4 if=/dev/random of=/luks-secondary-unlock.key iflag=fullblock
|
||||||
|
# chmod 400 /luks-secondary-unlock.key
|
||||||
|
```
|
||||||
|
|
||||||
|
You can specify your own name for `luks-secondary-unlock.key`
|
||||||
|
2. For each secondary device, run the following command and specify the respective device:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# cryptsetup luksAddKey /path/to/dev /luks-secondary-unlock.key
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create /etc/crypttab in configuration.nix using the following option (replacing UUID-OF-SDB with the actual UUID of /dev/sdb):
|
||||||
|
|
||||||
|
To list the UUIDs of the devices use: `sudo lsblk -o +name,mountpoint,uuid`
|
||||||
|
You need the UUID of the partition that the volume exists on, not the uuid of the volume itself
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
environment.etc.crypttab.text = ''
|
||||||
|
volumename UUID=UUID-OF-SDB /mykeyfile.key
|
||||||
|
''
|
||||||
|
}
|
||||||
|
```
|
||||||
|
example:
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
environment.etc.crypttab.text = ''
|
||||||
|
cryptextra UUID=569e2951-1957-4387-8b51-f445741b02b6 /luks-secondary-unlock.key
|
||||||
|
''
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
With this approach, the secondary drive is unlocked just before the boot process completes, without the need to enter its password.
|
||||||
|
The secondary drive will be unlocked and made available under /dev/mapper/cryptstorage for mounting.
|
||||||
|
|
||||||
|
### 4. Enable `backup` module (optional)
|
||||||
|
|
||||||
|
Enable the backup module in the target host's config file. For example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# nix-config/hosts/nixos/guppy/default.nix
|
||||||
|
#--------------------
|
||||||
|
|
||||||
|
# ...
|
||||||
|
services.backup = {
|
||||||
|
enable = true;
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
#...
|
||||||
|
```
|
||||||
|
|
||||||
|
You will, of course, need to declare additional backup options for the module to function correctly.
|
||||||
|
|
||||||
|
### 5. Rebuild (optional)
|
||||||
|
|
||||||
|
If you did any of the steps from 3 through 5, you will need to rebuild for the changes to take effect. Run `just rebuild` from the `nix-config` directory on the new host.
|
||||||
|
|
||||||
|
### 6. Everything else (optional)
|
||||||
|
|
||||||
|
Here you should have a fully working system, but here are some common tasks you may need to do for a "daily-driver" machine:
|
||||||
|
|
||||||
|
- Recover any backup files needed
|
||||||
|
- .mozilla
|
||||||
|
- syncthing
|
||||||
|
- Manually set syncthing username/password
|
||||||
|
- Run any commonly used apps and perform
|
||||||
|
- firefox and initiate sync
|
||||||
|
- protonvpn
|
||||||
|
- Re-link signal-desktop
|
||||||
|
- Login to spotify
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Rebooting a VM into the minimal-config environment hangs indefinitely on "booting in to hard disk..."
|
||||||
|
|
||||||
|
There are two know causes for this issue:
|
||||||
|
|
||||||
|
1. The VM __must__ be created with the hypervisor firmware set to UEFI instead of BIOS. You will likely have to re-create the VM as this can't be changed after the fact.
|
||||||
|
|
||||||
|
2. The `hardware-configuration.nix` file may not have the required virtual I/O kernel module. Depending on the VM device type you will need to add either `virtio_pci` or `virtio_scsi` to the list of `availableKernelModules` in the host's `hardware-configuration.nix`
|
||||||
|
For example:
|
||||||
|
```nix
|
||||||
|
# nix-config/hosts/nixos/guppy/hardware-configuration.nix
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
# ...
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"ahci"
|
||||||
|
"xhci_pci"
|
||||||
|
"virtio_pci"
|
||||||
|
"sr_mod"
|
||||||
|
"virtio_blk"
|
||||||
|
];
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Activation script snippet 'setupSecrets' failed - /run/secrets/keys/age: is a directory
|
||||||
|
|
||||||
|
This issue may be encountere when running the bootstrap script to update a host that had been previously installed with an older variant of nix-secrets where the age keys for all hosts were stored as "keys: age: [hostname]: [keydata]" where as now, because we're using host-specific secrets, the structure is "keys: age: [keydata]".
|
||||||
|
|
||||||
|
The failure will occur will occur near the end of the build output and will not display as an error in red.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
...
|
||||||
|
sops-install-secrets: Imported /etc/ssh/ssh_host_ed25519_key as age key with fingerprint age1ee6shkrhqg0n84n3ksjays6h5klxv2xmhn5uksq9qvsxd079cvdql7tyk8
|
||||||
|
/nix/store/chvwxir82c2mf99961qyf9hfqjq76g02-sops-install-secrets-0.0.1/bin/sops-install-secrets: cannot request units to restart: read /run/secrets/keys/age: is a directory
|
||||||
|
Activation script snippet 'setupSecrets' failed (1)
|
||||||
|
Failed to run activate script
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
To resolve the issue, run `sudo rm -r /run/secrets/keys/age` on the target host and then rebuild.
|
||||||
62
nixos-installer/flake.lock
generated
Normal file
62
nixos-installer/flake.lock
generated
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"disko": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1732645828,
|
||||||
|
"narHash": "sha256-+4U2I2653JvPFxcux837ulwYS864QvEueIljUkwytsk=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "disko",
|
||||||
|
"rev": "869ba3a87486289a4197b52a6c9e7222edf00b3e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "disko",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1732238832,
|
||||||
|
"narHash": "sha256-sQxuJm8rHY20xq6Ah+GwIUkF95tWjGRd1X8xF+Pkk38=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "8edf06bea5bcbee082df1b7369ff973b91618b8d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1732350895,
|
||||||
|
"narHash": "sha256-GcOQbOgmwlsRhpLGSwZJwLbo3pu9ochMETuRSS1xpz4=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0c582677378f2d9ffcb01490af2f2c678dcb29d3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"disko": "disko",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
62
nixos-installer/flake.nix
Normal file
62
nixos-installer/flake.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
description = "Minimal NixOS configuration for bootstrapping systems";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
# FIXME(starter): adjust nixos version for the minimal environment as desired.
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
disko.url = "github:nix-community/disko"; # Declarative partitioning and formatting
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
}@inputs:
|
||||||
|
let
|
||||||
|
inherit (self) outputs;
|
||||||
|
|
||||||
|
minimalSpecialArgs = {
|
||||||
|
inherit inputs outputs;
|
||||||
|
lib = nixpkgs.lib.extend (self: super: { custom = import ../lib { inherit (nixpkgs) lib; }; });
|
||||||
|
};
|
||||||
|
|
||||||
|
newConfig =
|
||||||
|
name: disk: swapSize:
|
||||||
|
(
|
||||||
|
let
|
||||||
|
diskSpecPath =
|
||||||
|
../hosts/common/disks/btrfs-disk.nix;
|
||||||
|
in
|
||||||
|
nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
specialArgs = minimalSpecialArgs;
|
||||||
|
modules = [
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
diskSpecPath
|
||||||
|
{
|
||||||
|
_module.args = {
|
||||||
|
inherit disk;
|
||||||
|
withSwap = swapSize > 0;
|
||||||
|
swapSize = builtins.toString swapSize;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
./minimal-configuration.nix
|
||||||
|
../hosts/nixos/${name}/hardware-configuration.nix
|
||||||
|
|
||||||
|
{ networking.hostName = name; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixosConfigurations = {
|
||||||
|
# This should mimic what is specified in the respective `nix-config/hosts/[platform]/[hostname]/default.nix`
|
||||||
|
# Add entries for each host you will be bootstrapping
|
||||||
|
|
||||||
|
# host = newConfig "name" disk" "swapSize"
|
||||||
|
# Swap size is in GiB
|
||||||
|
Bellerophon = newConfig "Bellerophon" "/dev/nvme0n1" 16;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
85
nixos-installer/minimal-configuration.nix
Normal file
85
nixos-installer/minimal-configuration.nix
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = lib.flatten [
|
||||||
|
(map lib.custom.relativeToRoot [
|
||||||
|
"modules/common/host-spec.nix"
|
||||||
|
"hosts/common/core/ssh.nix"
|
||||||
|
"hosts/common/users/primary"
|
||||||
|
"hosts/common/users/primary/nixos.nix"
|
||||||
|
"hosts/common/optional/minimal-user.nix"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
hostSpec = {
|
||||||
|
isMinimal = lib.mkForce true;
|
||||||
|
hostName = "installer";
|
||||||
|
# FIXME(starter): Add your primary username or whatever user you want to use for installation
|
||||||
|
username = "user";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot".options = [ "umask=0077" ]; # Removes permissions and security warnings.
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
boot.loader.systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
# we use Git for version control, so we don't need to keep too many generations.
|
||||||
|
configurationLimit = lib.mkDefault 3;
|
||||||
|
# pick the highest resolution for systemd-boot's console.
|
||||||
|
consoleMode = lib.mkDefault "max";
|
||||||
|
};
|
||||||
|
boot.initrd = {
|
||||||
|
systemd.enable = true;
|
||||||
|
systemd.emergencyAccess = true; # Don't need to enter password in emergency mode
|
||||||
|
};
|
||||||
|
boot.kernelParams = [
|
||||||
|
"systemd.setenv=SYSTEMD_SULOGIN_FORCE=1"
|
||||||
|
"systemd.show_status=true"
|
||||||
|
#"systemd.log_level=debug"
|
||||||
|
"systemd.log_target=console"
|
||||||
|
"systemd.journald.forward_to_console=1"
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
wget
|
||||||
|
curl
|
||||||
|
rsync
|
||||||
|
git
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
networkmanager.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
qemuGuest.enable = true;
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
ports = [ 22 ];
|
||||||
|
settings.PermitRootLogin = "yes";
|
||||||
|
authorizedKeysFiles = lib.mkForce [ "/etc/ssh/authorized_keys.d/%u" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
# registry and nixPath shouldn't be required here because flakes but removal results in warning spam on build
|
||||||
|
registry = lib.mapAttrs (_: value: { flake = value; }) inputs;
|
||||||
|
nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
warn-dirty = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
||||||
52
overlays/default.nix
Normal file
52
overlays/default.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# This file defines overlays/custom modifications to upstream packages
|
||||||
|
#
|
||||||
|
{inputs, ...}: let
|
||||||
|
# Adds my custom packages
|
||||||
|
additions = final: prev: (prev.lib.packagesFromDirectoryRecursive {
|
||||||
|
callPackage = prev.lib.callPackageWith final;
|
||||||
|
directory = ../pkgs/common;
|
||||||
|
});
|
||||||
|
|
||||||
|
linuxModifications = final: prev: prev.lib.mkIf final.stdenv.isLinux {};
|
||||||
|
|
||||||
|
modifications = final: prev: {
|
||||||
|
# example = prev.example.overrideAttrs (oldAttrs: let ... in {
|
||||||
|
# ...
|
||||||
|
# });
|
||||||
|
# flameshot = prev.flameshot.overrideAttrs {
|
||||||
|
# cmakeFlags = [
|
||||||
|
# (prev.lib.cmakeBool "USE_WAYLAND_GRIM" true)
|
||||||
|
# (prev.lib.cmakeBool "USE_WAYLAND_CLIPBOARD" true)
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
overlays = [
|
||||||
|
inputs.nix4vscode.overlays.forVscode
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
stable-packages = final: _prev: {
|
||||||
|
stable = import inputs.nixpkgs-stable {
|
||||||
|
inherit (final) system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
# overlays = [
|
||||||
|
# ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
unstable-packages = final: _prev: {
|
||||||
|
unstable = import inputs.nixpkgs-unstable {
|
||||||
|
inherit (final) system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
# overlays = [
|
||||||
|
# ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
default = final: prev:
|
||||||
|
(additions final prev)
|
||||||
|
// (modifications final prev)
|
||||||
|
// (linuxModifications final prev)
|
||||||
|
// (stable-packages final prev)
|
||||||
|
// (unstable-packages final prev);
|
||||||
|
}
|
||||||
46
pkgs/common/cd-gitroot/package.nix
Normal file
46
pkgs/common/cd-gitroot/package.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# NOTE(starter): This is a "bonus" custom package that has been left here because the
|
||||||
|
# inclusion of custom pkgs in `nix-config/flake.nix` was never designed to work with an
|
||||||
|
# empty `nix-config/pkgs/common` directory.
|
||||||
|
# If nothing else, it can serve as an example of how to package something similar.
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchgit,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
pname = "cd-gitroot";
|
||||||
|
install_path = "share/zsh/${pname}";
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
inherit pname;
|
||||||
|
version = "66f6ba7549b9973eb57bfbc188e29d2f73bf31bb";
|
||||||
|
src = fetchgit {
|
||||||
|
url = "https://github.com/mollifier/cd-gitroot";
|
||||||
|
hash = "sha256-pLdF8wbkA9mPI5cg8VPYAW7i3cWNJX3+lfAZ5cZPUgE=";
|
||||||
|
};
|
||||||
|
strictDeps = true;
|
||||||
|
dontBuild = true;
|
||||||
|
buildInputs = [ ];
|
||||||
|
installPhase = ''
|
||||||
|
install -m755 -D cd-gitroot.plugin.zsh --target-directory $out/${install_path}/
|
||||||
|
install -m755 -D cd-gitroot --target-directory $out/${install_path}/
|
||||||
|
install -m755 -D _cd-gitroot --target-directory $out/share/zsh/site-functions/
|
||||||
|
'';
|
||||||
|
meta = {
|
||||||
|
homepage = "https://github.com/mollifier/cd-gitroot";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
longDescription = ''
|
||||||
|
zsh plugin to change directory to git repository root directory.
|
||||||
|
You can add the following to your `programs.zsh.plugins` list:
|
||||||
|
```nix
|
||||||
|
programs.zsh.plugins = [
|
||||||
|
{
|
||||||
|
name = "${pname}";
|
||||||
|
src = "''${pkgs.${pname}}/${install_path}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
maintainers = [ lib.maintainers.fidgetingbits ];
|
||||||
|
};
|
||||||
|
}
|
||||||
312
scripts/bootstrap-nixos.sh
Executable file
312
scripts/bootstrap-nixos.sh
Executable file
@@ -0,0 +1,312 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Helpers library
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/helpers.sh"
|
||||||
|
|
||||||
|
# User variables
|
||||||
|
target_hostname=""
|
||||||
|
target_destination=""
|
||||||
|
target_user=${BOOTSTRAP_USER-$(whoami)} # Set BOOTSTRAP_ defaults in your shell.nix
|
||||||
|
ssh_port=${BOOTSTRAP_SSH_PORT-22}
|
||||||
|
ssh_key=${BOOTSTRAP_SSH_KEY-}
|
||||||
|
persist_dir=""
|
||||||
|
luks_passphrase="passphrase"
|
||||||
|
luks_secondary_drive_labels=""
|
||||||
|
nix_src_path="src/nix/" # path relative to /home/${target_user} where nix-config and nix-secrets are written in the users home
|
||||||
|
git_root=$(git rev-parse --show-toplevel)
|
||||||
|
nix_secrets_dir=${NIX_SECRETS_DIR:-"${git_root}"/../nix-secrets}
|
||||||
|
|
||||||
|
# Create a temp directory for generated host keys
|
||||||
|
temp=$(mktemp -d)
|
||||||
|
|
||||||
|
# Cleanup temporary directory on exit
|
||||||
|
function cleanup() {
|
||||||
|
rm -rf "$temp"
|
||||||
|
}
|
||||||
|
trap cleanup exit
|
||||||
|
|
||||||
|
# Copy data to the target machine
|
||||||
|
function sync() {
|
||||||
|
# $1 = user, $2 = source, $3 = destination
|
||||||
|
rsync -av --filter=':- .gitignore' -e "ssh -oControlMaster=no -l $1 -oport=${ssh_port}" "$2" "$1@${target_destination}:${nix_src_path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage function
|
||||||
|
function help_and_exit() {
|
||||||
|
echo
|
||||||
|
echo "Remotely installs NixOS on a target machine using this nix-config."
|
||||||
|
echo
|
||||||
|
echo "USAGE: $0 -n <target_hostname> -d <target_destination> -k <ssh_key> [OPTIONS]"
|
||||||
|
echo
|
||||||
|
echo "ARGS:"
|
||||||
|
echo " -n <target_hostname> specify target_hostname of the target host to deploy the nixos config on."
|
||||||
|
echo " -d <target_destination> specify ip or domain to the target host."
|
||||||
|
echo " -k <ssh_key> specify the full path to the ssh_key you'll use for remote access to the"
|
||||||
|
echo " target during install process."
|
||||||
|
echo " Example: -k /home/${target_user}/.ssh/my_ssh_key"
|
||||||
|
echo
|
||||||
|
echo "OPTIONS:"
|
||||||
|
echo " -u <target_user> specify target_user with sudo access. nix-config will be cloned to their home."
|
||||||
|
echo " Default='${target_user}'."
|
||||||
|
echo " --port <ssh_port> specify the ssh port to use for remote access. Default=${ssh_port}."
|
||||||
|
echo ' --luks-secondary-drive-labels <drives> specify the luks device names (as declared with "disko.devices.disk.*.content.luks.name" in host/common/disks/*.nix) separated by commas.'
|
||||||
|
echo ' Example: --luks-secondary-drive-labels "cryptprimary,cryptextra"'
|
||||||
|
echo " --impermanence Use this flag if the target machine has impermanence enabled. WARNING: Assumes /persist path."
|
||||||
|
echo " --debug Enable debug mode."
|
||||||
|
echo " -h | --help Print this help."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle command-line arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-n)
|
||||||
|
shift
|
||||||
|
target_hostname=$1
|
||||||
|
;;
|
||||||
|
-d)
|
||||||
|
shift
|
||||||
|
target_destination=$1
|
||||||
|
;;
|
||||||
|
-u)
|
||||||
|
shift
|
||||||
|
target_user=$1
|
||||||
|
;;
|
||||||
|
-k)
|
||||||
|
shift
|
||||||
|
ssh_key=$1
|
||||||
|
;;
|
||||||
|
--luks-secondary-drive-labels)
|
||||||
|
shift
|
||||||
|
luks_secondary_drive_labels=$1
|
||||||
|
;;
|
||||||
|
--port)
|
||||||
|
shift
|
||||||
|
ssh_port=$1
|
||||||
|
;;
|
||||||
|
--temp-override)
|
||||||
|
shift
|
||||||
|
temp=$1
|
||||||
|
;;
|
||||||
|
--impermanence)
|
||||||
|
persist_dir="/persist"
|
||||||
|
;;
|
||||||
|
--debug)
|
||||||
|
set -x
|
||||||
|
;;
|
||||||
|
-h | --help) help_and_exit ;;
|
||||||
|
*)
|
||||||
|
red "ERROR: Invalid option detected."
|
||||||
|
help_and_exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$target_hostname" ] || [ -z "$target_destination" ] || [ -z "$ssh_key" ]; then
|
||||||
|
red "ERROR: -n, -d, and -k are all required"
|
||||||
|
echo
|
||||||
|
help_and_exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SSH commands
|
||||||
|
ssh_cmd="ssh \
|
||||||
|
-oControlPath=none \
|
||||||
|
-oport=${ssh_port} \
|
||||||
|
-oForwardAgent=yes \
|
||||||
|
-oStrictHostKeyChecking=no \
|
||||||
|
-oUserKnownHostsFile=/dev/null \
|
||||||
|
-i $ssh_key \
|
||||||
|
-t $target_user@$target_destination"
|
||||||
|
# shellcheck disable=SC2001
|
||||||
|
ssh_root_cmd=$(echo "$ssh_cmd" | sed "s|${target_user}@|root@|") # uses @ in the sed switch to avoid it triggering on the $ssh_key value
|
||||||
|
scp_cmd="scp -oControlPath=none -oport=${ssh_port} -oStrictHostKeyChecking=no -i $ssh_key"
|
||||||
|
|
||||||
|
git_root=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
# Setup minimal environment for nixos-anywhere and run it
|
||||||
|
generated_hardware_config=0
|
||||||
|
function nixos_anywhere() {
|
||||||
|
# Clear the known keys, since they should be newly generated for the iso
|
||||||
|
green "Wiping known_hosts of $target_destination"
|
||||||
|
sed -i "/$target_hostname/d; /$target_destination/d" ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
green "Installing NixOS on remote host $target_hostname at $target_destination"
|
||||||
|
|
||||||
|
###
|
||||||
|
# nixos-anywhere extra-files generation
|
||||||
|
###
|
||||||
|
green "Preparing a new ssh_host_ed25519_key pair for $target_hostname."
|
||||||
|
# Create the directory where sshd expects to find the host keys
|
||||||
|
install -d -m755 "$temp/$persist_dir/etc/ssh"
|
||||||
|
|
||||||
|
# Generate host ssh key pair without a passphrase
|
||||||
|
ssh-keygen -t ed25519 -f "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key" -C "$target_user"@"$target_hostname" -N ""
|
||||||
|
|
||||||
|
# Set the correct permissions so sshd will accept the key
|
||||||
|
chmod 600 "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key"
|
||||||
|
|
||||||
|
green "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
|
||||||
|
# This will fail if we already know the host, but that's fine
|
||||||
|
ssh-keyscan -p "$ssh_port" "$target_destination" | grep -v '^#' >>~/.ssh/known_hosts || true
|
||||||
|
|
||||||
|
###
|
||||||
|
# nixos-anywhere installation
|
||||||
|
###
|
||||||
|
cd nixos-installer
|
||||||
|
# when using luks, disko expects a passphrase on /tmp/disko-password, so we set it for now and will update the passphrase later
|
||||||
|
if no_or_yes "Manually set luks encryption passphrase? (Default: \"$luks_passphrase\")"; then
|
||||||
|
blue "Enter your luks encryption passphrase:"
|
||||||
|
read -rs luks_passphrase
|
||||||
|
$ssh_root_cmd "/bin/sh -c 'echo $luks_passphrase > /tmp/disko-password'"
|
||||||
|
else
|
||||||
|
green "Using '$luks_passphrase' as the luks encryption passphrase. Change after installation."
|
||||||
|
$ssh_root_cmd "/bin/sh -c 'echo $luks_passphrase > /tmp/disko-password'"
|
||||||
|
fi
|
||||||
|
# this will run if luks_secondary_drive_labels cli argument was set, regardless of whether the luks_passphrase is default or not
|
||||||
|
if [ -n "${luks_secondary_drive_labels}" ]; then
|
||||||
|
luks_setup_secondary_drive_decryption
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If you are rebuilding a machine without any hardware changes, this is likely unneeded or even possibly disruptive
|
||||||
|
if no_or_yes "Generate a new hardware config for this host? Yes if your nix-config doesn't have an entry for this host."; then
|
||||||
|
green "Generating hardware-configuration.nix on $target_hostname and adding it to the local nix-config."
|
||||||
|
$ssh_root_cmd "nixos-generate-config --no-filesystems --root /mnt"
|
||||||
|
$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix \
|
||||||
|
"${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix
|
||||||
|
generated_hardware_config=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --extra-files here picks up the ssh host key we generated earlier and puts it onto the target machine
|
||||||
|
SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- \
|
||||||
|
--ssh-port "$ssh_port" \
|
||||||
|
--post-kexec-ssh-port "$ssh_port" \
|
||||||
|
--extra-files "$temp" \
|
||||||
|
--flake .#"$target_hostname" \
|
||||||
|
root@"$target_destination"
|
||||||
|
|
||||||
|
if ! yes_or_no "Has your system restarted and are you ready to continue? (no exits)"; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "Adding $target_destination's ssh host fingerprint to ~/.ssh/known_hosts"
|
||||||
|
ssh-keyscan -p "$ssh_port" "$target_destination" | grep -v '^#' >>~/.ssh/known_hosts || true
|
||||||
|
|
||||||
|
if [ -n "$persist_dir" ]; then
|
||||||
|
$ssh_root_cmd "cp /etc/machine-id $persist_dir/etc/machine-id || true"
|
||||||
|
$ssh_root_cmd "cp -R /etc/ssh/ $persist_dir/etc/ssh/ || true"
|
||||||
|
fi
|
||||||
|
cd - >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function sops_generate_host_age_key() {
|
||||||
|
green "Generating an age key based on the new ssh_host_ed25519_key"
|
||||||
|
|
||||||
|
# Get the SSH key
|
||||||
|
target_key=$(ssh-keyscan -p "$ssh_port" -t ssh-ed25519 "$target_destination" 2>&1 | grep ssh-ed25519 | cut -f2- -d" ") || {
|
||||||
|
red "Failed to get ssh key. Host down or maybe SSH port now changed?"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
host_age_key=$(echo "$target_key" | ssh-to-age)
|
||||||
|
|
||||||
|
if grep -qv '^age1' <<<"$host_age_key"; then
|
||||||
|
red "The result from generated age key does not match the expected format."
|
||||||
|
yellow "Result: $host_age_key"
|
||||||
|
yellow "Expected format: age10000000000000000000000000000000000000000000000000000000000"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "Updating nix-secrets/.sops.yaml"
|
||||||
|
sops_update_age_key "hosts" "$target_hostname" "$host_age_key"
|
||||||
|
}
|
||||||
|
|
||||||
|
function luks_setup_secondary_drive_decryption() {
|
||||||
|
green "Generating /luks-secondary-unlock.key"
|
||||||
|
local key=${persist_dir}/luks-secondary-unlock.key
|
||||||
|
$ssh_root_cmd "dd bs=512 count=4 if=/dev/random of=$key iflag=fullblock && chmod 400 $key"
|
||||||
|
|
||||||
|
green "Cryptsetup luksAddKey will now be used to add /luks-secondary-unlock.key for the specified secondary drive names."
|
||||||
|
readarray -td, drivenames <<<"$luks_secondary_drive_labels"
|
||||||
|
for name in "${drivenames[@]}"; do
|
||||||
|
device_path=$($ssh_root_cmd -q "cryptsetup status \"$name\" | awk \'/device:/ {print \$2}\'")
|
||||||
|
$ssh_root_cmd "echo \"$luks_passphrase\" | cryptsetup luksAddKey $device_path /luks-secondary-unlock.key"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate required options
|
||||||
|
# FIXME(bootstrap): The ssh key and destination aren't required if only rekeying, so could be moved into specific sections?
|
||||||
|
if [ -z "${target_hostname}" ] || [ -z "${target_destination}" ] || [ -z "${ssh_key}" ]; then
|
||||||
|
red "ERROR: -n, -d, and -k are all required"
|
||||||
|
echo
|
||||||
|
help_and_exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if yes_or_no "Run nixos-anywhere installation?"; then
|
||||||
|
nixos_anywhere
|
||||||
|
fi
|
||||||
|
|
||||||
|
updated_age_keys=0
|
||||||
|
if yes_or_no "Generate host (ssh-based) age key?"; then
|
||||||
|
sops_generate_host_age_key
|
||||||
|
updated_age_keys=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if yes_or_no "Generate user age key?"; then
|
||||||
|
# This may end up creating the host.yaml file, so add creation rules in advance
|
||||||
|
sops_setup_user_age_key "$target_user" "$target_hostname"
|
||||||
|
# We need to add the new file before we rekey later
|
||||||
|
cd "$nix_secrets_dir"
|
||||||
|
git add sops/"${target_hostname}".yaml
|
||||||
|
cd - >/dev/null
|
||||||
|
updated_age_keys=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $updated_age_keys == 1 ]]; then
|
||||||
|
# If the age generation commands added previously unseen keys (and associated anchors) we want to add those
|
||||||
|
# to some creation rules, namely <host>.yaml and shared.yaml
|
||||||
|
sops_add_creation_rules "${target_user}" "${target_hostname}"
|
||||||
|
# Since we may update the sops.yaml file twice above, only rekey once at the end
|
||||||
|
just rekey
|
||||||
|
green "Updating flake input to pick up new .sops.yaml"
|
||||||
|
nix flake update nix-secrets
|
||||||
|
fi
|
||||||
|
|
||||||
|
if yes_or_no "Do you want to copy your full nix-config and nix-secrets to $target_hostname?"; then
|
||||||
|
green "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
|
||||||
|
ssh-keyscan -p "$ssh_port" "$target_destination" 2>/dev/null | grep -v '^#' >>~/.ssh/known_hosts || true
|
||||||
|
green "Copying full nix-config to $target_hostname"
|
||||||
|
sync "$target_user" "${git_root}"/../nix-config
|
||||||
|
green "Copying full nix-secrets to $target_hostname"
|
||||||
|
sync "$target_user" "${nix_secrets_dir}"
|
||||||
|
|
||||||
|
# FIXME(bootstrap): Add some sort of key access from the target to download the config (if it's a cloud system)
|
||||||
|
if yes_or_no "Do you want to rebuild immediately?"; then
|
||||||
|
green "Rebuilding nix-config on $target_hostname"
|
||||||
|
$ssh_cmd "cd ${nix_src_path}nix-config && sudo nixos-rebuild --impure --show-trace --flake .#$target_hostname switch"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
green "NixOS was successfully installed!"
|
||||||
|
echo "Post-install config build instructions:"
|
||||||
|
echo "To copy nix-config from this machine to the $target_hostname, run the following command"
|
||||||
|
echo "just sync $target_user $target_destination"
|
||||||
|
echo "To rebuild, sign into $target_hostname and run the following command"
|
||||||
|
echo "cd nix-config"
|
||||||
|
echo "sudo nixos-rebuild --show-trace --flake .#$target_hostname switch"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $generated_hardware_config == 1 ]]; then
|
||||||
|
if yes_or_no "Do you want to commit and push the generated hardware-configuration.nix for $target_hostname to nix-config?"; then
|
||||||
|
(pre-commit run --all-files 2>/dev/null || true) &&
|
||||||
|
git add "$git_root/hosts/$target_hostname/hardware-configuration.nix" &&
|
||||||
|
(git commit -m "feat: hardware-configuration.nix for $target_hostname" || true) &&
|
||||||
|
git push
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "Success!"
|
||||||
|
reen "Success!"
|
||||||
31
scripts/check-sops.sh
Executable file
31
scripts/check-sops.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
os=$(uname -s)
|
||||||
|
if [ "$os" == "Darwin" ]; then
|
||||||
|
sops_running=$(launchctl list | rg sops)
|
||||||
|
if [[ -z $sops_running ]]; then
|
||||||
|
echo "ERROR: sops-nix is not running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else # If the sops-nix service wasn't started at all, we don't need to check if it failed
|
||||||
|
sops_running=$(journalctl --no-pager --no-hostname --since "10 minutes ago" | rg "Starting sops-nix activation")
|
||||||
|
if [ -z "$sops_running" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Also this is HM specific atm, need a way to test the NixOS version too
|
||||||
|
sops_result=$(journalctl --no-pager --no-hostname --since "10 minutes ago" |
|
||||||
|
tac |
|
||||||
|
awk '!flag; /Starting sops-nix activation/{flag = 1};' |
|
||||||
|
tac |
|
||||||
|
rg sops)
|
||||||
|
|
||||||
|
# If we don't have "Finished sops-nix activation." in the logs, then we failed
|
||||||
|
if [[ ! $sops_result =~ "Finished sops-nix activation" ]]; then
|
||||||
|
echo "ERROR: sops-nix failed to activate"
|
||||||
|
echo "ERROR: $sops_result"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
179
scripts/helpers.sh
Normal file
179
scripts/helpers.sh
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
### UX helpers
|
||||||
|
|
||||||
|
function red() {
|
||||||
|
echo -e "\x1B[31m[!] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[31m[!] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function green() {
|
||||||
|
echo -e "\x1B[32m[+] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[32m[+] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function blue() {
|
||||||
|
echo -e "\x1B[34m[*] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[34m[*] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function yellow() {
|
||||||
|
echo -e "\x1B[33m[*] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[33m[*] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ask yes or no, with yes being the default
|
||||||
|
function yes_or_no() {
|
||||||
|
echo -en "\x1B[34m[?] $* [y/n] (default: y): \x1B[0m"
|
||||||
|
while true; do
|
||||||
|
read -rp "" yn
|
||||||
|
yn=${yn:-y}
|
||||||
|
case $yn in
|
||||||
|
[Yy]*) return 0 ;;
|
||||||
|
[Nn]*) return 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ask yes or no, with no being the default
|
||||||
|
function no_or_yes() {
|
||||||
|
echo -en "\x1B[34m[?] $* [y/n] (default: n): \x1B[0m"
|
||||||
|
while true; do
|
||||||
|
read -rp "" yn
|
||||||
|
yn=${yn:-n}
|
||||||
|
case $yn in
|
||||||
|
[Yy]*) return 0 ;;
|
||||||
|
[Nn]*) return 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
### SOPS helpers
|
||||||
|
nix_secrets_dir=${NIX_SECRETS_DIR:-"$(dirname "${BASH_SOURCE[0]}")/../../nix-secrets"}
|
||||||
|
SOPS_FILE="${nix_secrets_dir}/.sops.yaml"
|
||||||
|
|
||||||
|
# Updates the .sops.yaml file with a new host or user age key.
|
||||||
|
function sops_update_age_key() {
|
||||||
|
field="$1"
|
||||||
|
keyname="$2"
|
||||||
|
key="$3"
|
||||||
|
|
||||||
|
if [ ! "$field" == "hosts" ] && [ ! "$field" == "users" ]; then
|
||||||
|
red "Invalid field passed to sops_update_age_key. Must be either 'hosts' or 'users'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $(yq ".keys.${field}[] | select(anchor == \"$keyname\")" "${SOPS_FILE}") ]]; then
|
||||||
|
green "Updating existing ${keyname} key"
|
||||||
|
yq -i "(.keys.${field}[] | select(anchor == \"$keyname\")) = \"$key\"" "$SOPS_FILE"
|
||||||
|
else
|
||||||
|
green "Adding new ${keyname} key"
|
||||||
|
yq -i ".keys.$field += [\"$key\"] | .keys.${field}[-1] anchor = \"$keyname\"" "$SOPS_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Adds the user and host to the shared.yaml creation rules
|
||||||
|
function sops_add_shared_creation_rules() {
|
||||||
|
u="\"$1_$2\"" # quoted user_host for yaml
|
||||||
|
h="\"$2\"" # quoted hostname for yaml
|
||||||
|
|
||||||
|
shared_selector='.creation_rules[] | select(.path_regex == "shared\.yaml$")'
|
||||||
|
if [[ -n $(yq "$shared_selector" "${SOPS_FILE}") ]]; then
|
||||||
|
echo "BEFORE"
|
||||||
|
cat "${SOPS_FILE}"
|
||||||
|
if [[ -z $(yq "$shared_selector.key_groups[].age[] | select(alias == $h)" "${SOPS_FILE}") ]]; then
|
||||||
|
green "Adding $u and $h to shared.yaml rule"
|
||||||
|
# NOTE: Split on purpose to avoid weird file corruption
|
||||||
|
yq -i "($shared_selector).key_groups[].age += [$u, $h]" "$SOPS_FILE"
|
||||||
|
yq -i "($shared_selector).key_groups[].age[-2] alias = $u" "$SOPS_FILE"
|
||||||
|
yq -i "($shared_selector).key_groups[].age[-1] alias = $h" "$SOPS_FILE"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
red "shared.yaml rule not found"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Adds the user and host to the host.yaml creation rules
|
||||||
|
function sops_add_host_creation_rules() {
|
||||||
|
host="$2" # hostname for selector
|
||||||
|
h="\"$2\"" # quoted hostname for yaml
|
||||||
|
u="\"$1_$2\"" # quoted user_host for yaml
|
||||||
|
w="\"$(whoami)_$(hostname)\"" # quoted whoami_hostname for yaml
|
||||||
|
n="\"$(hostname)\"" # quoted hostname for yaml
|
||||||
|
|
||||||
|
host_selector=".creation_rules[] | select(.path_regex | contains(\"${host}\.yaml\"))"
|
||||||
|
if [[ -z $(yq "$host_selector" "${SOPS_FILE}") ]]; then
|
||||||
|
green "Adding new host file creation rule"
|
||||||
|
yq -i ".creation_rules += {\"path_regex\": \"${host}\\.yaml$\", \"key_groups\": [{\"age\": [$u, $h]}]}" "$SOPS_FILE"
|
||||||
|
# Add aliases one by one
|
||||||
|
yq -i "($host_selector).key_groups[].age[0] alias = $u" "$SOPS_FILE"
|
||||||
|
yq -i "($host_selector).key_groups[].age[1] alias = $h" "$SOPS_FILE"
|
||||||
|
yq -i "($host_selector).key_groups[].age[2] alias = $w" "$SOPS_FILE"
|
||||||
|
yq -i "($host_selector).key_groups[].age[3] alias = $n" "$SOPS_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Adds the user and host to the shared.yaml and host.yaml creation rules
|
||||||
|
function sops_add_creation_rules() {
|
||||||
|
user="$1"
|
||||||
|
host="$2"
|
||||||
|
|
||||||
|
sops_add_shared_creation_rules "$user" "$host"
|
||||||
|
sops_add_host_creation_rules "$user" "$host"
|
||||||
|
}
|
||||||
|
|
||||||
|
age_secret_key=""
|
||||||
|
# Generate a user age key, update the .sops.yaml entries, and return the key in age_secret_key
|
||||||
|
# args: user, hostname
|
||||||
|
function sops_generate_user_age_key() {
|
||||||
|
target_user="$1"
|
||||||
|
target_hostname="$2"
|
||||||
|
key_name="${target_user}_${target_hostname}"
|
||||||
|
green "Age key does not exist. Generating."
|
||||||
|
user_age_key=$(age-keygen)
|
||||||
|
readarray -t entries <<<"$user_age_key"
|
||||||
|
age_secret_key=${entries[2]}
|
||||||
|
public_key=$(echo "${entries[1]}" | rg key: | cut -f2 -d: | xargs)
|
||||||
|
green "Generated age key for ${key_name}"
|
||||||
|
# Place the anchors into .sops.yaml so other commands can reference them
|
||||||
|
sops_update_age_key "users" "$key_name" "$public_key"
|
||||||
|
sops_add_creation_rules "${target_user}" "${target_hostname}"
|
||||||
|
|
||||||
|
# "return" key so it can be used by caller
|
||||||
|
export age_secret_key
|
||||||
|
}
|
||||||
|
|
||||||
|
function sops_setup_user_age_key() {
|
||||||
|
target_user="$1"
|
||||||
|
target_hostname="$2"
|
||||||
|
|
||||||
|
secret_file="${nix_secrets_dir}/sops/${target_hostname}.yaml"
|
||||||
|
config="${nix_secrets_dir}/.sops.yaml"
|
||||||
|
# If the secret file doesn't exist, it means we're generating a new user key as well
|
||||||
|
if [ ! -f "$secret_file" ]; then
|
||||||
|
green "Host secret file does not exist. Creating $secret_file"
|
||||||
|
sops_generate_user_age_key "${target_user}" "${target_hostname}"
|
||||||
|
mkdir -p "$(dirname "$secret_file")"
|
||||||
|
echo "{}" >"$secret_file"
|
||||||
|
sops --config "$config" -e "$secret_file" >"$secret_file.enc"
|
||||||
|
mv "$secret_file.enc" "$secret_file"
|
||||||
|
fi
|
||||||
|
if ! sops --config "$config" -d --extract '["keys]["age"]' "$secret_file" >/dev/null 2>&1; then
|
||||||
|
if [ -z "$age_secret_key" ]; then
|
||||||
|
sops_generate_user_age_key "${target_user}" "${target_hostname}"
|
||||||
|
fi
|
||||||
|
# shellcheck disable=SC2116,SC2086
|
||||||
|
sops --config "$config" --set "$(echo '["keys"]["age"] "'$age_secret_key'"')" "$secret_file"
|
||||||
|
else
|
||||||
|
green "Age key already exists for ${target_hostname}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
106
scripts/rebuild.sh
Executable file
106
scripts/rebuild.sh
Executable file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
#
|
||||||
|
# This script is used to rebuild the system configuration for the current host.
|
||||||
|
#
|
||||||
|
# SC2086 is ignored because we purposefully pass some values as a set of arguments, so we want the splitting to happen
|
||||||
|
|
||||||
|
function red() {
|
||||||
|
echo -e "\x1B[31m[!] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[31m[!] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function green() {
|
||||||
|
echo -e "\x1B[32m[+] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[32m[+] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function yellow() {
|
||||||
|
echo -e "\x1B[33m[*] $1 \x1B[0m"
|
||||||
|
if [ -n "${2-}" ]; then
|
||||||
|
echo -e "\x1B[33m[*] $($2) \x1B[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_args="--show-trace --impure --flake "
|
||||||
|
if [[ -n $1 && $1 == "trace" ]]; then
|
||||||
|
switch_args="$switch_args --show-trace "
|
||||||
|
elif [[ -n $1 ]]; then
|
||||||
|
HOST=$1
|
||||||
|
else
|
||||||
|
HOST=$(hostname)
|
||||||
|
fi
|
||||||
|
switch_args="$switch_args .#$HOST switch"
|
||||||
|
|
||||||
|
os=$(uname -s)
|
||||||
|
if [ "$os" == "Darwin" ]; then
|
||||||
|
# FIXME: This might not have to be darwin specific
|
||||||
|
|
||||||
|
# FIXME: This will break if HM tries to create the file. We should use environment variables instead
|
||||||
|
mkdir -p ~/.config/nix || true
|
||||||
|
CONF=~/.config/nix/nix.conf
|
||||||
|
if [ ! -f $CONF ]; then
|
||||||
|
# Enable nix-command and flakes to bootstrap
|
||||||
|
cat <<-EOF >$CONF
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Do some darwin pre-installation for bootstrapping
|
||||||
|
if ! which git &>/dev/null; then
|
||||||
|
echo "Installing xcode tools"
|
||||||
|
xcode-select --install
|
||||||
|
fi
|
||||||
|
|
||||||
|
# https://docs.brew.sh/Installation
|
||||||
|
if [ ! -e /opt/homebrew/bin/brew ]; then
|
||||||
|
echo "Installing rosetta"
|
||||||
|
# This is required for emulation of x86_64 binaries, so let's just
|
||||||
|
# assume if they didn't install brew yet, they need this
|
||||||
|
softwareupdate --install-rosetta --agree-to-license
|
||||||
|
echo "Installing homebrew"
|
||||||
|
export NONINTERACTIVE=1
|
||||||
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "====== REBUILD ======"
|
||||||
|
# Test if there's no darwin-rebuild, then use nix build and then run it
|
||||||
|
if ! which darwin-rebuild &>/dev/null; then
|
||||||
|
nix build --show-trace .#darwinConfigurations."$HOST".system
|
||||||
|
./result/sw/bin/darwin-rebuild $switch_args
|
||||||
|
else
|
||||||
|
echo $switch_args
|
||||||
|
darwin-rebuild $switch_args
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
green "====== REBUILD ======"
|
||||||
|
if command -v nh &>/dev/null; then
|
||||||
|
REPO_PATH=$(pwd)
|
||||||
|
export REPO_PATH
|
||||||
|
nh os switch . -- --impure --show-trace
|
||||||
|
else
|
||||||
|
sudo nixos-rebuild $switch_args
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2181
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
green "====== POST-REBUILD ======"
|
||||||
|
green "Rebuilt successfully"
|
||||||
|
|
||||||
|
# Check if there are any pending changes that would affect the build succeeding.
|
||||||
|
if git diff --exit-code >/dev/null && git diff --staged --exit-code >/dev/null; then
|
||||||
|
# Check if the current commit has a buildable tag
|
||||||
|
if git tag --points-at HEAD | grep -q buildable; then
|
||||||
|
yellow "Current commit is already tagged as buildable"
|
||||||
|
else
|
||||||
|
git tag buildable-"$(date +%Y%m%d%H%M%S)" -m ''
|
||||||
|
green "Tagged current commit as buildable"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
yellow "WARN: There are pending changes that would affect the build succeeding. Commit them before tagging"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
9
scripts/system-install.sh
Executable file
9
scripts/system-install.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ -e "$1" ]; then
|
||||||
|
HOST=$1
|
||||||
|
else
|
||||||
|
HOST=$(hostname)
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo nixos-rebuild --flake .#"$HOST" install
|
||||||
45
shell.nix
Normal file
45
shell.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Shell for bootstrapping flake-enabled nix and other tooling
|
||||||
|
{
|
||||||
|
pkgs ?
|
||||||
|
# If pkgs is not defined, instantiate nixpkgs from locked commit
|
||||||
|
let
|
||||||
|
lock = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.nixpkgs.locked;
|
||||||
|
nixpkgs = fetchTarball {
|
||||||
|
url = "https://github.com/nixos/nixpkgs/archive/${lock.rev}.tar.gz";
|
||||||
|
sha256 = lock.narHash;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
import nixpkgs { overlays = [ ]; },
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
NIX_CONFIG = "extra-experimental-features = nix-command flakes";
|
||||||
|
BOOTSTRAP_USER = "panotaka";
|
||||||
|
BOOTSTRAP_SSH_PORT = "22";
|
||||||
|
BOOTSTRAP_SSH_KEY = "~/.ssh/id_manu";
|
||||||
|
|
||||||
|
|
||||||
|
nativeBuildInputs = builtins.attrValues {
|
||||||
|
inherit (pkgs)
|
||||||
|
|
||||||
|
# NOTE(starter): add any packages you want available in the shell when accessing the parent directory.
|
||||||
|
# These will be installed regardless of what was installed specific for the host or home configs
|
||||||
|
nix
|
||||||
|
home-manager
|
||||||
|
nil
|
||||||
|
alejandra
|
||||||
|
nh
|
||||||
|
git
|
||||||
|
just
|
||||||
|
pre-commit
|
||||||
|
deadnix
|
||||||
|
sops
|
||||||
|
yq-go # jq for yaml, used for build scripts
|
||||||
|
bats # for bash testing
|
||||||
|
age # for bootstrap script
|
||||||
|
ssh-to-age # for bootstrap script
|
||||||
|
;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
3
tests/fixtures/nix-secrets/age_key.txt
vendored
Normal file
3
tests/fixtures/nix-secrets/age_key.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# created: 2025-02-07T09:27:05+08:00
|
||||||
|
# public key: age1uq2uymv63r4h5r47vkuhjz3hcz9rv48df8u5jt8zeejgt2wzme3qz3se8y
|
||||||
|
AGE-SECRET-KEY-1Z7AENV0K5VRCV87EDK2XYE4ZWJ3G39W7J3TEAWQSX2F46NGWL4FQ6QKGLE
|
||||||
11
tests/fixtures/nix-secrets/sops.yaml
vendored
Normal file
11
tests/fixtures/nix-secrets/sops.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
keys:
|
||||||
|
users:
|
||||||
|
- &alice_testbox USER_KEY_1
|
||||||
|
hosts:
|
||||||
|
- &testbox age1v8v79wlsjnwvxaa6eulqx3zft0m5srj7etgk4v3rg80j42uzecxs26gaxz
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: shared\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *alice_testbox
|
||||||
|
- *testbox
|
||||||
9
tests/helpers/test_helper.bash
Normal file
9
tests/helpers/test_helper.bash
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
setup() {
|
||||||
|
TEST_TEMP="$(mktemp -d)"
|
||||||
|
FIXTURES_DIR="$(dirname "$BATS_TEST_DIRNAME")/tests/fixtures"
|
||||||
|
export TEST_TEMP
|
||||||
|
export FIXTURES_DIR
|
||||||
|
}
|
||||||
|
teardown() {
|
||||||
|
rm -rf "$TEST_TEMP"
|
||||||
|
}
|
||||||
102
tests/sops.bats
Normal file
102
tests/sops.bats
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
AGE_TEST_KEY_1="age1v8v79wlsjnwvxaa6eulqx3zft0m5srj7etgk4v3rg80j42uzecxs26gaxz"
|
||||||
|
AGE_TEST_KEY_2="age1zmplxr8x2h3tk4fd3zkleyspa7vtnyz5pyrj7zlf5vsl3fquhqvsp8n4k0"
|
||||||
|
AGE_TEST_KEY_3="age1zrjsjhsuwhqkdn2psjpukrsgjh5qls9023gructewn9skz4ya9gskncgmq"
|
||||||
|
AGE_TEST_KEY_4="age1e4zy6wcl0a8teaudtmsujkuupf56vkqdul0gljlssdqftrx3uphqqfx8p7"
|
||||||
|
|
||||||
|
# This key has a real associated private key in the fixtures
|
||||||
|
AGE_STATIC_HOST_KEY="age1uq2uymv63r4h5r47vkuhjz3hcz9rv48df8u5jt8zeejgt2wzme3qz3se8y"
|
||||||
|
|
||||||
|
setup_sops() {
|
||||||
|
load 'helpers/test_helper'
|
||||||
|
setup
|
||||||
|
mkdir -p "$TEST_TEMP"
|
||||||
|
cp -R "$FIXTURES_DIR"/nix-secrets/*.yaml "$TEST_TEMP"
|
||||||
|
mv "$TEST_TEMP/sops.yaml" "$TEST_TEMP/.sops.yaml"
|
||||||
|
NIX_SECRETS_DIR="$TEST_TEMP"
|
||||||
|
export NIX_SECRETS_DIR
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$BATS_TEST_DIRNAME/../scripts/helpers.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "add sops user anchor" {
|
||||||
|
setup_sops
|
||||||
|
|
||||||
|
sops_update_age_key users alice_testbox "${AGE_TEST_KEY_2}"
|
||||||
|
|
||||||
|
run grep -c "&alice_testbox" "$NIX_SECRETS_DIR"/.sops.yaml
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" = "1" ]
|
||||||
|
|
||||||
|
run grep "${AGE_TEST_KEY_2}" "$NIX_SECRETS_DIR"/.sops.yaml
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "add sops host anchor" {
|
||||||
|
setup_sops
|
||||||
|
|
||||||
|
sops_update_age_key hosts testbox "${AGE_TEST_KEY_1}"
|
||||||
|
|
||||||
|
run grep -c "&testbox" "$NIX_SECRETS_DIR"/.sops.yaml
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" = "1" ]
|
||||||
|
|
||||||
|
run grep "${AGE_TEST_KEY_1}" "$NIX_SECRETS_DIR"/.sops.yaml
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "update shared creation rules" {
|
||||||
|
setup_sops
|
||||||
|
|
||||||
|
sops_update_age_key users bob_deadbeef "${AGE_TEST_KEY_3}"
|
||||||
|
sops_update_age_key hosts deadbeef "${AGE_TEST_KEY_4}"
|
||||||
|
sops_add_shared_creation_rules bob deadbeef
|
||||||
|
|
||||||
|
yq '.creation_rules' "$NIX_SECRETS_DIR"/.sops.yaml >"$TEST_TEMP/creation_rules"
|
||||||
|
run grep "bob" "$TEST_TEMP/creation_rules"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run grep "deadbeef" "$TEST_TEMP/creation_rules"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "add host creation rules to sops" {
|
||||||
|
setup_sops
|
||||||
|
|
||||||
|
sops_update_age_key users bob_deadbeef "${AGE_TEST_KEY_1}"
|
||||||
|
sops_update_age_key hosts deadbeef "${AGE_TEST_KEY_2}"
|
||||||
|
sops_update_age_key users "$(whoami)_$(hostname)" "${AGE_STATIC_HOST_KEY}"
|
||||||
|
sops_update_age_key hosts "$(hostname)" "${AGE_STATIC_HOST_KEY}"
|
||||||
|
sops_add_host_creation_rules bob deadbeef
|
||||||
|
|
||||||
|
yq '.creation_rules' "$NIX_SECRETS_DIR"/.sops.yaml >"$TEST_TEMP/creation_rules"
|
||||||
|
run grep "bob" "$TEST_TEMP/creation_rules"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run grep "deadbeef" "$TEST_TEMP/creation_rules"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "add host.yaml file" {
|
||||||
|
setup_sops
|
||||||
|
|
||||||
|
sops_update_age_key users bob_deadbeef "${AGE_TEST_KEY_1}"
|
||||||
|
sops_update_age_key hosts deadbeef "${AGE_TEST_KEY_2}"
|
||||||
|
sops_update_age_key users "$(whoami)_$(hostname)" "${AGE_STATIC_HOST_KEY}"
|
||||||
|
sops_update_age_key hosts "$(hostname)" "${AGE_STATIC_HOST_KEY}"
|
||||||
|
sops_add_host_creation_rules bob deadbeef
|
||||||
|
|
||||||
|
# Create a new <host>.yaml file and verify it holds the correct entry
|
||||||
|
export SOPS_AGE_KEY_FILE="$BATS_TEST_DIRNAME/fixtures/nix-secrets/age_key.txt"
|
||||||
|
run sops_setup_user_age_key "deadbeef" "bob"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
teardown
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user