mkDiskoFiles = map (hostname: {
name = "${hostname}";
- value = self.nixosConfigurations."${hostname}".config.monorepo.vars.myDiskoSpec;
+ value = self.nixosConfigurations."${hostname}".config.monorepo.vars.diskoSpec;
});
in {
#+end_src
* Modules
** Vars
-Variables used for regular configuration in your system ~defafult.nix~ file. The options are
+Variables used for regular configuration in your system ~default.nix~ file. The options are
largely self-documenting.
#+begin_src nix :tangle ../nix/modules/vars.nix
{ lib, ... }:
description = "device that NixOS is installed to";
};
- myDiskoSpec = lib.mkOption {
+ diskoSpec = lib.mkOption {
type = lib.types.attrs;
description = "retains a copy of the disko spec for reflection";
};
settings = {
PasswordAuthentication = lib.mkDefault (! config.monorepo.profiles.server.enable);
AllowUsers = [ config.monorepo.vars.userName "root" "git" ];
- PermitRootLogin = "yes";
+ PermitRootLogin = "prohibit-password";
KbdInteractiveAuthentication = false;
};
};
passBlock = ''
<Pass password>
Method = sha256
- Hash = d4abdd69aa24de69693885c5bd83a4a0e9ee989e1a69a905041b0dad9abc06ea
- Salt = sDY,?H5AxC-!gH3a.:)D
+ Hash = ${config.sops.secrets.znc_password_hash}
+ Salt = ${config.sops.secrets.znc_password_salt}
</Pass>
'';
modules = [
boot = {
+
+ extraModprobeConfig = ''
+ options snd-usb-audio vid=0x1235 pid=0x8200 device_setup=1
+ '';
extraModulePackages = [ ];
initrd = {
];
kernelParams = [
+ "usbcore.autosuspend=-1"
"debugfs=off"
"page_alloc.shuffle=1"
"slab_nomerge"
};
xdg.portal = {
- enable = true;
+ enable = (! config.monorepo.profiles.ttyonly.enable);
wlr.enable = true;
- extraPortals = with pkgs; [
+ extraPortals = with pkgs; if (! config.monorepo.profiles.ttyonly.enable) then [
xdg-desktop-portal-gtk
xdg-desktop-portal
xdg-desktop-portal-hyprland
- ];
+ ] else [];
config.common.default = "*";
};
#+end_src
** Disko
This is the disko configuration for my continuity system. It features a boot and ext4 partition,
-on disk /dev/sda. All my SATA disks have this location by default, but if you want to use nvme,
-you will have to import that configuration in your ~systems/xxx/default.nix~.
-*** NVME
-For my nvme drives.
+with configurable disk.
+*** Simple
+This configuration is used for simple partitioning schemes with EFI.
#+begin_src nix :tangle ../nix/disko/drive-simple.nix
{ lib, config, ... }:
let
};
in
{
- monorepo.vars.myDiskoSpec = spec;
+ monorepo.vars.diskoSpec = spec;
disko.devices = spec.disko.devices;
}
#+end_src
-*** VDA
-For my virtual machines.
+*** BIOS
+For machines that use BIOS instead of EFI.
#+begin_src nix :tangle ../nix/disko/drive-bios.nix
{ config, lib, ... }:
let
};
in
{
- monorepo.vars.myDiskoSpec = spec;
+ monorepo.vars.diskoSpec = spec;
disko.devices = spec.disko.devices;
}
#+end_src
As you can see, I have my installed home packages installed based on the profiles enabled. Also,
I have many imports that we'll go through next.
#+begin_src nix :tangle ../nix/modules/home/default.nix
- { lib, config, pkgs, ... }:
+ { lib, config, pkgs, sops-nix, ... }:
{
imports = [
+ sops-nix.homeManagerModules.sops
../vars.nix
./fcitx.nix
./secrets.nix
{
programs.firefox = {
enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
+ package = pkgs.firefox-bin;
policies = {
EnableTrackingProtection = true;
OfferToSaveLogins = false;
};
- package = pkgs.firefox-wayland;
profiles = {
default = {
id = 0;
monitor = [
"Unknown-1,disable"
];
- windowrule = [
- "workspace 1, title:(^(.*emacs.*)$)"
- "workspace 2, title:(^(.*firefox.*)$)"
- "workspace 2, title:(^(.*Tor Browser.*)$)"
- "workspace 2, title:(^(.*Chromium-browser.*)$)"
- "workspace 2, title:(^(.*chromium.*)$)"
- "workspace 3, title:(^(.*discord.*)$)"
- "workspace 3, title:^(.*vesktop.*)$)"
- "workspace 3, title:(^(.*fluffychat.*)$)"
- "workspace 3, title:(^(.*element-desktop.*)$)"
- "workspace 4, title:(^(.*qpwgraph.*)$)"
- "workspace 4, title:(^(.*mpv.*)$)"
- "workspace 5, title:(^(.*Monero.*)$)"
- "workspace 5, title:(^(.*org\.bitcoin\..*)$)"
- "workspace 5, title:(^(.*Bitcoin Core - preston.*)$)"
- "workspace 5, title:(^(.*org\.getmonero\..*)$)"
- "workspace 5, title:(^(.*Monero - preston.*)$)"
- "workspace 5, title:(^(.*electrum.*)$)"
+ windowrulev2 = [
+ "workspace 1, class:^(emacs)$"
+ "workspace 2, class:^(firefox)$"
+ "workspace 2, title:^(.*Tor Browser.*)$"
+ "workspace 2, title:^(.*Chromium-browser.*)$"
+ "workspace 2, class:^(chromium)$"
+ "workspace 3, class:^(discord)$"
+ "workspace 3, class:^(vesktop)$"
+ "workspace 3, title:^(.*fluffychat.*)$"
+ "workspace 3, class:^(.*element-desktop.*)$"
+ "workspace 4, class:^(.*qpwgraph.*)$"
+ "workspace 4, class:^(.*mpv.*)$"
+ "workspace 5, title:^(.*Monero.*)$"
+ "workspace 5, title:^(.*org\.bitcoin\..*)$"
+ "workspace 5, title:^(.*Bitcoin Core - preston.*)$"
+ "workspace 5, title:^(.*org\.getmonero\..*)$"
+ "workspace 5, title:^(.*Monero - preston.*)$"
+ "workspace 5, title:^(.*electrum.*)$"
"pseudo,title:fcitx"
];
bind = [
*** Secrets
This uses sops in order to declaratively create the secrets on my system by unencrypting
the yaml file specified. Yes, this is safe to include in the repo.
-#+begin_src nix :tangle ../nix/modules/secrets.nix
+#+begin_src nix :tangle ../nix/modules/home/secrets.nix
{ config, ... }:
{
sops = {
format = "yaml";
path = "${config.sops.defaultSymlinkPath}/znc";
};
+ znc_password_salt = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/znc_password_salt";
+ };
+
+ znc_password_hash = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/znc_password_hash";
+ };
+
matrix_bridge = {
format = "yaml";
path = "${config.sops.defaultSymlinkPath}/matrix_bridge";
{ config, sops-nix, ... }:
{
home-manager = {
+
sharedModules = [
sops-nix.homeManagerModules.sops
];
}
#+end_src
** Includes
-These are the common includes for my systems.
+These are the common includes for each of my systems. This ensures that we don't have to duplicate includes every time we want to add a new
+system.
#+begin_src nix :tangle ../nix/systems/includes.nix
{ config, lib, ... }:
{
#+begin_src nix :tangle ../nix/systems/installer/commits.nix
{
diskoCommitHash = "a5c4f2ab72e3d1ab43e3e65aa421c6f2bd2e12a1";
- monorepoCommitHash = "8f4f46e59ad0b7c5662a417d10f3074f17c962c3";
+ monorepoCommitHash = "5b8d09f2d7ebb7a1670c695af5761353d5b76d7e";
monorepoUrl = "https://github.com/ret2pop/monorepo";
}
#+end_src
gum input --placeholder "Press Enter to continue" >/dev/null
vim "$HOME/monorepo/nix/systems/$SYSTEM/home.nix"
- sed -i "/hostnames = \[/,/];/ { /];/i \ \"your-hostname-$SYSTEM\" }" "$HOME/monorepo/nix/flake.nix"
+ sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/nix/flake.nix"
if [ ! -f "$HOME/monorepo/nix/disko/$DRIVE" ]; then
cp "$HOME/monorepo/nix/disko/drive-simple.nix" "$HOME/monorepo/nix/disko/$DRIVE"
};
}
#+end_src
+* Add System Script
+Here is a script to add a new system automatically:
+#+begin_src bash :tangle ../nix/add-system.sh
+ #!/usr/bin/env bash
+ sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/nix/flake.nix"
+ sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/config/nix.org"
+
+ mkdir -p "$HOME/monorepo/nix/systems/$1"
+
+ cat > "$HOME/monorepo/nix/systems/$1/default.nix" <<EOF
+ { ... }:
+ {
+ imports = [
+ ../includes.nix
+ ../../disko/drive-simple.nix
+ ];
+ # CHANGEME
+ config.monorepo.vars.drive = "/dev/sda";
+ }
+ EOF
+
+ cp "$HOME/monorepo/nix/systems/continuity/home.nix" "$HOME/monorepo/nix/systems/$1/home.nix"
+#+end_src
+note that one will have to add some files to this org file afterwards, but this is a fine short term solution.
--- /dev/null
+#!/usr/bin/env bash
+sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/nix/flake.nix"
+sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/config/nix.org"
+
+mkdir -p "$HOME/monorepo/nix/systems/$1"
+
+cat > "$HOME/monorepo/nix/systems/$1/default.nix" <<EOF
+{ ... }:
+{
+ imports = [
+ ../includes.nix
+ ../../disko/drive-simple.nix
+ ];
+ # CHANGEME
+ config.monorepo.vars.drive = "/dev/sda";
+}
+EOF
+
+cp "$HOME/monorepo/nix/systems/continuity/home.nix" "$HOME/monorepo/nix/systems/$1/home.nix"
};
in
{
- monorepo.vars.myDiskoSpec = spec;
+ monorepo.vars.diskoSpec = spec;
disko.devices = spec.disko.devices;
}
};
in
{
- monorepo.vars.myDiskoSpec = spec;
+ monorepo.vars.diskoSpec = spec;
disko.devices = spec.disko.devices;
}
mkDiskoFiles = map (hostname: {
name = "${hostname}";
- value = self.nixosConfigurations."${hostname}".config.monorepo.vars.myDiskoSpec;
+ value = self.nixosConfigurations."${hostname}".config.monorepo.vars.diskoSpec;
});
in {
boot = {
+
+ extraModprobeConfig = ''
+ options snd-usb-audio vid=0x1235 pid=0x8200 device_setup=1
+'';
extraModulePackages = [ ];
initrd = {
];
kernelParams = [
+ "usbcore.autosuspend=-1"
"debugfs=off"
"page_alloc.shuffle=1"
"slab_nomerge"
};
xdg.portal = {
- enable = true;
+ enable = (! config.monorepo.profiles.ttyonly.enable);
wlr.enable = true;
- extraPortals = with pkgs; [
+ extraPortals = with pkgs; if (! config.monorepo.profiles.ttyonly.enable) then [
xdg-desktop-portal-gtk
xdg-desktop-portal
xdg-desktop-portal-hyprland
- ];
+ ] else [];
config.common.default = "*";
};
-{ lib, config, pkgs, ... }:
+{ lib, config, pkgs, sops-nix, ... }:
{
imports = [
+ sops-nix.homeManagerModules.sops
../vars.nix
./fcitx.nix
./secrets.nix
{
programs.firefox = {
enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
+ package = pkgs.firefox-bin;
policies = {
EnableTrackingProtection = true;
OfferToSaveLogins = false;
};
- package = pkgs.firefox-wayland;
profiles = {
default = {
id = 0;
monitor = [
"Unknown-1,disable"
];
- windowrule = [
- "workspace 1, title:(^(.*emacs.*)$)"
- "workspace 2, title:(^(.*firefox.*)$)"
- "workspace 2, title:(^(.*Tor Browser.*)$)"
- "workspace 2, title:(^(.*Chromium-browser.*)$)"
- "workspace 2, title:(^(.*chromium.*)$)"
- "workspace 3, title:(^(.*discord.*)$)"
- "workspace 3, title:^(.*vesktop.*)$)"
- "workspace 3, title:(^(.*fluffychat.*)$)"
- "workspace 3, title:(^(.*element-desktop.*)$)"
- "workspace 4, title:(^(.*qpwgraph.*)$)"
- "workspace 4, title:(^(.*mpv.*)$)"
- "workspace 5, title:(^(.*Monero.*)$)"
- "workspace 5, title:(^(.*org\.bitcoin\..*)$)"
- "workspace 5, title:(^(.*Bitcoin Core - preston.*)$)"
- "workspace 5, title:(^(.*org\.getmonero\..*)$)"
- "workspace 5, title:(^(.*Monero - preston.*)$)"
- "workspace 5, title:(^(.*electrum.*)$)"
+ windowrulev2 = [
+ "workspace 1, class:^(emacs)$"
+ "workspace 2, class:^(firefox)$"
+ "workspace 2, title:^(.*Tor Browser.*)$"
+ "workspace 2, title:^(.*Chromium-browser.*)$"
+ "workspace 2, class:^(chromium)$"
+ "workspace 3, class:^(discord)$"
+ "workspace 3, class:^(vesktop)$"
+ "workspace 3, title:^(.*fluffychat.*)$"
+ "workspace 3, class:^(.*element-desktop.*)$"
+ "workspace 4, class:^(.*qpwgraph.*)$"
+ "workspace 4, class:^(.*mpv.*)$"
+ "workspace 5, title:^(.*Monero.*)$"
+ "workspace 5, title:^(.*org\.bitcoin\..*)$"
+ "workspace 5, title:^(.*Bitcoin Core - preston.*)$"
+ "workspace 5, title:^(.*org\.getmonero\..*)$"
+ "workspace 5, title:^(.*Monero - preston.*)$"
+ "workspace 5, title:^(.*electrum.*)$"
"pseudo,title:fcitx"
];
bind = [
age = {
keyFile = "/home/${config.monorepo.vars.userName}/.ssh/keys.txt";
};
- secrets.mail = {
- format = "yaml";
- path = "${config.sops.defaultSymlinkPath}/mail";
- };
- secrets.digikey = {
- format = "yaml";
- path = "${config.sops.defaultSymlinkPath}/digikey";
- };
+ secrets = {
+ mail = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/mail";
+ };
+ cloudflare-dns = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/cloudflare-dns";
+ };
+ digikey = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/digikey";
+ };
+ dn42 = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/dn42";
+ };
+ znc = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/znc";
+ };
+ znc_password_salt = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/znc_password_salt";
+ };
+ znc_password_hash = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/znc_password_hash";
+ };
+
+ matrix_bridge = {
+ format = "yaml";
+ path = "${config.sops.defaultSymlinkPath}/matrix_bridge";
+ };
+ };
defaultSymlinkPath = "/run/user/1000/secrets";
defaultSecretsMountPoint = "/run/user/1000/secrets.d";
};
secrets = {
mail = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
path = "${config.sops.defaultSymlinkPath}/mail";
};
cloudflare-dns = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
path = "${config.sops.defaultSymlinkPath}/cloudflare-dns";
};
digikey = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
path = "${config.sops.defaultSymlinkPath}/digikey";
};
dn42 = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
path = "${config.sops.defaultSymlinkPath}/dn42";
};
znc = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
path = "${config.sops.defaultSymlinkPath}/znc";
};
+ znc_password_salt = {
+ format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
+ path = "${config.sops.defaultSymlinkPath}/znc_password_salt";
+ };
+
+ znc_password_hash = {
+ format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
+ path = "${config.sops.defaultSymlinkPath}/znc_password_hash";
+ };
+
matrix_bridge = {
format = "yaml";
+ sopsFile = config.sops.defaultSopsFile;
+# sopsFile = ../../secrets/secrets.yaml;
path = "${config.sops.defaultSymlinkPath}/matrix_bridge";
};
};
settings = {
PasswordAuthentication = lib.mkDefault (! config.monorepo.profiles.server.enable);
AllowUsers = [ config.monorepo.vars.userName "root" "git" ];
- PermitRootLogin = "yes";
+ PermitRootLogin = "prohibit-password";
KbdInteractiveAuthentication = false;
};
};
description = "device that NixOS is installed to";
};
- myDiskoSpec = lib.mkOption {
+ diskoSpec = lib.mkOption {
type = lib.types.attrs;
description = "retains a copy of the disko spec for reflection";
};
passBlock = ''
<Pass password>
Method = sha256
- Hash = d4abdd69aa24de69693885c5bd83a4a0e9ee989e1a69a905041b0dad9abc06ea
- Salt = sDY,?H5AxC-!gH3a.:)D
+ Hash = ${config.sops.secrets.znc_password_hash}
+ Salt = ${config.sops.secrets.znc_password_salt}
</Pass>
'';
modules = [
dn42: ENC[AES256_GCM,data:xSYssg7ReFjmf7LvmqmH/A==,iv:Gj/LZrxzRJLOLbP5rumjmViYWP6ufW3ocngektBW3V8=,tag:SA4f1vAnMFUO5Yk6NTr81Q==,type:str]
znc: ENC[AES256_GCM,data:EYB9Gk/oZgU=,iv:zxtAFRKGPhfeanhOP6YiXQujWny6XGFvf2op2NNlo78=,tag:jxGNirhEbyYrZ+S3ZjssxA==,type:str]
matrix_bridge: ENC[AES256_GCM,data:wkfUpMvpoktkUaFr2BopCRo=,iv:gMdF+nnyl9XeJhGvAUKcfK5mvLytt8DvcPLgxMUtOlg=,tag:v06PRV6rM+4a1E3iW3vjnQ==,type:str]
+znc_password_hash: ENC[AES256_GCM,data:OretCSRPEqXUaaEucDsEgjceyOQ9hNpKU61cnR0ZYt7FWAPO4OVYYs/S1xpC11ZmqAItTYZTCXJUoZEI+uwOgg==,iv:/YQewdQvwuQHx9Ci3Qj8yzSe1ZpvQfJ+/+TSl+7eEEc=,tag:m9y1TCGzzdf4F6nFBFdm5w==,type:str]
+znc_password_salt: ENC[AES256_GCM,data:7hpewfbF0sGAFUahJuHNRhN8MIc=,iv:Gf2UGgEt9Yi+x44Rqy90QtG3dsUy4GX+FCe58YNk3Qs=,tag:q6Wu1bTasXpqoHxGmgJ4Lw==,type:str]
sops:
- kms: []
- gcp_kms: []
- azure_kv: []
- hc_vault: []
age:
- recipient: age165ul43e8rc0qwzz2f2q9cw02psm2mkudsrwavq2e0pxs280p64yqy2z0dr
enc: |
OFFNeEtOTk5FSm9RaDFad0UyeWZ2WDgKIwGoB4a5WAIkE93gzqdUzNlo5vgQ1zLy
yhEFrE1NbhyItnZIg/yRhqFG0dv7D3pEP3pq2Seew6pKJg/s9UTJ8Q==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2025-03-19T06:34:16Z"
- mac: ENC[AES256_GCM,data:5pXwLkFf9N1uafukgPkYpMC5JywdkhCYwH+JCMlCkjGlJedtGagbiqsvceLDD4yo01h9v0KovN4kPS6qrkdTYxOBPkkoTpZzwE6/pGMCRL9tizF2Zi2LmKUsS5uyFQf9KvFkon6bdf9+z/mavnhBhrZSSBSkJiJeQpjkjRJGuVQ=,iv:E+epnNJi/g9MkwxQtcEctC+JKJXkcJvuuFjHGiLbvg4=,tag:50CSytg3EDPDxhrFQjcmeQ==,type:str]
- pgp: []
+ lastmodified: "2025-09-08T08:02:24Z"
+ mac: ENC[AES256_GCM,data:o+eA42aOTNxbNrfOVj4eFDsVyKA+5GBbYwUWVvLxVgEoiHk+M/XUl3lAlAvCP5L65oGK3ZRrKwgOaPzle6FTWj8GsJD906YZcqNhhydKVpax9NIXjkPbSp0Q7kIws0M7Iudf9GZotrLQZTB8jKGLkGfdjQbhJuQAklyZEAuN1q0=,iv:sEiTEyNOUG5SsffY4LM7lFtS8F1pUIjmO/xOCPrE7oo=,tag:41yJ48o/DLjXa9wgvZ1RcQ==,type:str]
unencrypted_suffix: _unencrypted
- version: 3.9.4
+ version: 3.10.2
{ config, sops-nix, ... }:
{
home-manager = {
+
sharedModules = [
sops-nix.homeManagerModules.sops
];
{
diskoCommitHash = "a5c4f2ab72e3d1ab43e3e65aa421c6f2bd2e12a1";
- monorepoCommitHash = "8f4f46e59ad0b7c5662a417d10f3074f17c962c3";
+ monorepoCommitHash = "5b8d09f2d7ebb7a1670c695af5761353d5b76d7e";
monorepoUrl = "https://github.com/ret2pop/monorepo";
}
gum input --placeholder "Press Enter to continue" >/dev/null
vim "$HOME/monorepo/nix/systems/$SYSTEM/home.nix"
- sed -i "/hostnames = \[/,/];/ { /];/i \ \"your-hostname-$SYSTEM\" }" "$HOME/monorepo/nix/flake.nix"
+ sed -i "/# add hostnames here/i \ \"$1\"" "$HOME/monorepo/nix/flake.nix"
if [ ! -f "$HOME/monorepo/nix/disko/$DRIVE" ]; then
cp "$HOME/monorepo/nix/disko/drive-simple.nix" "$HOME/monorepo/nix/disko/$DRIVE"