2 Commits

Author SHA1 Message Date
5a76f7703f flake.lock: Update
Flake lock file updates:

• Updated input 'agenix':
    'github:ryantm/agenix/457669db4259ff69d1ac1183aaa6000420940c1f' (2023-12-23)
  → 'github:ryantm/agenix/417caa847f9383e111d1397039c9d4337d024bf0' (2023-12-24)
• Updated input 'nixos-hardware':
    'github:NixOS/nixos-hardware/7763c6fd1f299cb9361ff2abf755ed9619ef01d6' (2023-12-13)
  → 'github:NixOS/nixos-hardware/a15b6e525f5737a47b4ce28445c836996fb2ea8c' (2023-12-25)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/d65bceaee0fb1e64363f7871bc43dc1c6ecad99f' (2023-12-20)
  → 'github:NixOS/nixpkgs/0b3d618173114c64ab666f557504d6982665d328' (2023-12-21)
• Updated input 'secrets':
    'git+ssh://git@git.vimium.com/jordan/nix-secrets.git?ref=refs/heads/master&rev=4ec3e87d6a7b1f14d23c12c60cad62a6e43be4ca' (2023-12-25)
  → 'git+ssh://git@git.vimium.com/jordan/nix-secrets.git?ref=refs/heads/master&rev=ef1f91b155f3bdc4efb2824ad0c47b21b8b1bbfa' (2023-12-25)
2023-12-26 00:33:08 +00:00
e642de2d19 Add WIP modules for matrix and coturn 2023-12-26 00:31:31 +00:00
148 changed files with 1958 additions and 7324 deletions

View File

@ -1,15 +0,0 @@
name: Check flake
on:
push:
branches: ['master']
jobs:
build-amd64-linux:
runs-on: nix
steps:
- uses: actions/checkout@v4
with:
ref: master
- name: Check flake
run: |
echo "Checking flake at ${{ gitea.ref }}"
nix flake check

View File

@ -1,4 +1,4 @@
Copyright (C) 2025 by Jordan Holt <jordan@vimium.com>
Copyright (C) 2023 by Jordan Holt <jordan@vimium.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

View File

@ -6,49 +6,11 @@ System and user configuration for NixOS-based systems.
|-|-|
| **Shell:** | zsh |
| **DE:** | GNOME |
| **Theme:** | Adwaita |
| **Terminal:** | Ptyxis |
| **Theme:** | adwaita |
| **Terminal:** | Console |
## Provisioning a new host
> [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used
> for provisioning
Generate a new SSH host key in "$temp/etc/ssh" as per [this guide](https://nix-community.github.io/nixos-anywhere/howtos/secrets.html#example-decrypting-an-openssh-host-key-with-pass).
```
ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key
```
Update [nix-secrets](/jordan/nix-secrets) with the new host key to enable the system to decrypt
any relevant secrets.
In order to use the borgmatic module for backups, go to [borgbase.com](https://borgbase.com).
Add the generated SSH host key and create a new repository for the system.
Create a new directory under `hosts/` with a system configuration and disk layout.
Boot the NixOS installer (or any Linux distribution) on the target.
Then run:
```
nix run github:nix-community/nixos-anywhere -- \
--disk-encryption-keys /tmp/secret.key /tmp/secret.key \
--extra-files "$temp" \
--flake .#<hostname> \
root@<target-ip>
```
### Post install
If backups are configured, you'll need to run:
```
borgmatic init --encryption repokey-blake2
```
then restart `borgmatic`.
To join the Tailscale network, run:
```
tailscale up --login-server https://headscale.vimium.net
```
then visit the URL, SSH onto `vps1` and run `headscale --user mesh nodes register --key <key>`.
The new node can optionally be given a friendly name with `headscale node rename -i <index> <hostname>`.
## Quick start
1. Copy SSH keypair and `known_hosts` to `~/.ssh`
1. Import GPG keys and set ultimate trust with `echo "KEYID:6:" | gpg --import-ownertrust`
1. `git clone git@git.vimium.com:jordan/nix-config.git projects/jordan/nix-config`
1. `sudo nixos-rebuild switch --flake .#`

564
flake.lock generated
View File

@ -8,11 +8,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1736955230,
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
"lastModified": 1703433843,
"narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=",
"owner": "ryantm",
"repo": "agenix",
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
"rev": "417caa847f9383e111d1397039c9d4337d024bf0",
"type": "github"
},
"original": {
@ -21,22 +21,6 @@
"type": "github"
}
},
"blobs": {
"flake": false,
"locked": {
"lastModified": 1604995301,
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"type": "gitlab"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
@ -66,11 +50,11 @@
"utils": "utils"
},
"locked": {
"lastModified": 1727447169,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
"lastModified": 1703087360,
"narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
"rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
"type": "github"
},
"original": {
@ -79,55 +63,14 @@
"type": "github"
}
},
"devshell": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735644329,
"narHash": "sha256-tO3HrHriyLvipc4xr+Ewtdlo7wM1OjXNjlWRgmM7peY=",
"owner": "numtide",
"repo": "devshell",
"rev": "f7795ede5b02664b57035b3b757876703e2c3eac",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1739841949,
"narHash": "sha256-lSOXdgW/1zi/SSu7xp71v+55D5Egz8ACv0STkj7fhbs=",
"owner": "nix-community",
"repo": "disko",
"rev": "15dbf8cebd8e2655a883b74547108e089f051bf0",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1739223196,
"narHash": "sha256-vAxN2f3rvl5q62gQQjZGVSvF93nAsOxntuFz+e/655w=",
"lastModified": 1703023593,
"narHash": "sha256-M+Cw6vh7xCDmIhyVuEPNmaNVUwpmdFQq8zlsXZTKees=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "a89108e6272426f4eddd93ba17d0ea101c34fb21",
"rev": "bad853333d9021e7012adb9b8fbfe7a7003f26bc",
"type": "github"
},
"original": {
@ -152,177 +95,6 @@
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_3": {
"locked": {
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"revCount": 69,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-compat_4": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1738453229,
"narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": [
"nixvim",
"flake-compat"
],
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1737465171,
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitea-github-theme": {
"flake": false,
"locked": {
"lastModified": 1717248105,
"narHash": "sha256-BwSsIkl7DpN/c8HNXOh2aKjOuPmFsGybv4RegOC7Xq0=",
"ref": "main",
"rev": "4f829f88e6f443ff048c4d337bd010315aa4b50a",
"revCount": 101,
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/gitea-github-theme.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/gitea-github-theme.git"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"nixvim",
"git-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"
}
},
"gitignore_2": {
"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"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -351,115 +123,27 @@
]
},
"locked": {
"lastModified": 1739757849,
"narHash": "sha256-Gs076ot1YuAAsYVcyidLKUMIc4ooOaRGO0PqTY7sBzA=",
"lastModified": 1703367386,
"narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "9d3d080aec2a35e05a15cedd281c2384767c2cfe",
"rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.11",
"ref": "release-23.11",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_3": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1739570999,
"narHash": "sha256-eCc0/Q4bPpe4/AS+uzIrHLJcR6BxPQ69q2kD0/Qe6rU=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "254d47082e23dbf72fdeca1da6fe1da420f478d8",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.11",
"repo": "home-manager",
"type": "github"
}
},
"ixx": {
"inputs": {
"flake-utils": [
"nixvim",
"nuschtosSearch",
"flake-utils"
],
"nixpkgs": [
"nixvim",
"nuschtosSearch",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729958008,
"narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=",
"owner": "NuschtOS",
"repo": "ixx",
"rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"ref": "v0.0.6",
"repo": "ixx",
"type": "github"
}
},
"kvlibadwaita": {
"flake": false,
"locked": {
"lastModified": 1710621848,
"narHash": "sha256-xBl6zmpqTAH5MIT5iNAdW6kdOcB5MY0Dtrb95hdYpwA=",
"owner": "GabePoel",
"repo": "KvLibadwaita",
"rev": "87c1ef9f44ec48855fd09ddab041007277e30e37",
"type": "github"
},
"original": {
"owner": "GabePoel",
"repo": "KvLibadwaita",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1739553546,
"narHash": "sha256-L4ou3xfOr17EAe836djRoQ7auVkYOREMtiQa82wVGqU=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "353846417f985e74fdc060555f17939e4472ea2c",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "nix-darwin-24.11",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1740089251,
"narHash": "sha256-Y78mDBWoO8CLLTjQfPfII+KXFb6lAmF9GrLbyVBsIMM=",
"lastModified": 1703545041,
"narHash": "sha256-nvQA+k1rSszrf4kA4eK2i/SGbzoXyoKHzzyzq/Jca1w=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "18e9f9753e9ae261bcc7d3abe15745686991fd30",
"rev": "a15b6e525f5737a47b4ce28445c836996fb2ea8c",
"type": "github"
},
"original": {
@ -468,29 +152,6 @@
"type": "github"
}
},
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-24_11": "nixpkgs-24_11"
},
"locked": {
"lastModified": 1739121270,
"narHash": "sha256-EmJhpy9U8sVlepl2QPjG019VfG67HcucsQNItTqW6cA=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "8c1c4640b878c692dd3d8055e8cdea0a2bbd8cf3",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1703013332,
@ -507,36 +168,6 @@
"type": "github"
}
},
"nixpkgs-24_11": {
"locked": {
"lastModified": 1734083684,
"narHash": "sha256-5fNndbndxSx5d+C/D0p/VF32xDiJCJzyOqorOYW4JEo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "314e12ba369ccdb9b352a4db26ff419f7c49fa84",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.11",
"type": "indirect"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1739866667,
"narHash": "sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "73cf49b8ad837ade2de76f87eb53fc85ed5d4680",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1702272962,
@ -555,132 +186,27 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1739923778,
"narHash": "sha256-BqUY8tz0AQ4to2Z4+uaKczh81zsGZSYxjgvtw+fvIfM=",
"lastModified": 1703200384,
"narHash": "sha256-q5j06XOsy0qHOarsYPfZYJPWbTbc8sryRxianlEPJN0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "36864ed72f234b9540da4cf7a0c49e351d30d3f1",
"rev": "0b3d618173114c64ab666f557504d6982665d328",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.11",
"ref": "nixos-23.11",
"type": "indirect"
}
},
"nixvim": {
"inputs": {
"devshell": "devshell",
"flake-compat": "flake-compat_3",
"flake-parts": "flake-parts",
"git-hooks": "git-hooks",
"home-manager": "home-manager_3",
"nix-darwin": "nix-darwin",
"nixpkgs": [
"nixpkgs"
],
"nuschtosSearch": "nuschtosSearch",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1739623149,
"narHash": "sha256-9hyreNdQtQaFzWAx38CHiKHFQ8vAc/J2/kXeT7Nwy6s=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "6b2c62b91a10a773e705f55e8b34a19c8b1f3728",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "nixos-24.11",
"repo": "nixvim",
"type": "github"
}
},
"nuschtosSearch": {
"inputs": {
"flake-utils": "flake-utils",
"ixx": "ixx",
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1738508923,
"narHash": "sha256-4DaDrQDAIxlWhTjH6h/+xfG05jt3qDZrZE/7zDLQaS4=",
"owner": "NuschtOS",
"repo": "search",
"rev": "86e2038290859006e05ca7201425ea5b5de4aecb",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"repo": "search",
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1739557722,
"narHash": "sha256-XikzLpPUDYiNyJ4w2SfRShdbSkIgE3btYdxCGInmtc4=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "1f3e1f38dedbbb8aad77e184fb54ec518e2d9522",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat_4",
"gitignore": "gitignore_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1737465171,
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"deploy-rs": "deploy-rs",
"disko": "disko",
"firefox-gnome-theme": "firefox-gnome-theme",
"gitea-github-theme": "gitea-github-theme",
"home-manager": "home-manager_2",
"kvlibadwaita": "kvlibadwaita",
"nixos-hardware": "nixos-hardware",
"nixos-mailserver": "nixos-mailserver",
"nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim",
"plasma-manager": "plasma-manager",
"pre-commit-hooks": "pre-commit-hooks",
"secrets": "secrets",
"thunderbird-gnome-theme": "thunderbird-gnome-theme"
}
@ -688,11 +214,11 @@
"secrets": {
"flake": false,
"locked": {
"lastModified": 1730732927,
"narHash": "sha256-t3MTEgi6O7DMxMjdi3xcTAztLDQmEtqQ+oU+ZbWz2AI=",
"lastModified": 1703545643,
"narHash": "sha256-FS/acsRQ01Gj39P1t5CQ6cKOdwADmenk//vVmpA/EgU=",
"ref": "refs/heads/master",
"rev": "4ae2ac777c38f60a29384b70c456f41847cdf1b5",
"revCount": 28,
"rev": "ef1f91b155f3bdc4efb2824ad0c47b21b8b1bbfa",
"revCount": 9,
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/nix-secrets.git"
},
@ -731,29 +257,14 @@
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"thunderbird-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1732643121,
"narHash": "sha256-i0Uo5EN45rlGuR85hvPet43zW/thOQTwHypVg9shTHU=",
"lastModified": 1701889124,
"narHash": "sha256-K+6oh7+J6RDBFkxphY/pzf0B+q5+IY54ZMKZrFSKXlc=",
"owner": "rafaelmardojai",
"repo": "thunderbird-gnome-theme",
"rev": "1994e7ec0649053e2a0811973245758d41e33f5f",
"rev": "966e9dd54bd2ce9d36d51cd6af8c3bac7a764a68",
"type": "github"
},
"original": {
@ -762,27 +273,6 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1738953846,
"narHash": "sha256-yrK3Hjcr8F7qS/j2F+r7C7o010eVWWlm4T1PrbKBOxQ=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "4f09b473c936d41582dd744e19f34ec27592c5fd",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"

179
flake.nix
View File

@ -2,49 +2,18 @@
description = "NixOS system configuration";
inputs = {
nixpkgs.url = "nixpkgs/nixos-24.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs";
nixpkgs.url = "nixpkgs/nixos-23.11";
agenix.url = "github:ryantm/agenix";
deploy-rs.url = "github:serokell/deploy-rs";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager/release-24.11";
url = "github:nix-community/home-manager/release-23.11";
inputs.nixpkgs.follows = "nixpkgs";
};
firefox-gnome-theme = {
url = "github:rafaelmardojai/firefox-gnome-theme";
flake = false;
};
gitea-github-theme = {
url = "git+ssh://git@git.vimium.com/jordan/gitea-github-theme.git?ref=main";
flake = false;
};
kvlibadwaita = {
url = "github:GabePoel/KvLibadwaita";
flake = false;
};
nixos-hardware.url = "github:NixOS/nixos-hardware";
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim/nixos-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
pre-commit-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
secrets = {
url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git";
flake = false;
@ -55,111 +24,63 @@
};
};
outputs =
inputs@{ self, nixpkgs, ... }:
outputs = inputs @ { self, nixpkgs, agenix, deploy-rs, home-manager, nixos-hardware, secrets, ... }:
let
inherit (nixpkgs) lib;
domain = "mesh.vimium.net";
forEachSystem = lib.genAttrs [
"x86_64-linux"
"aarch64-linux"
nixpkgsForSystem = system: inputs.nixpkgs;
overlays = [
agenix.overlays.default
(import ./overlays/gnome.nix)
];
mkDeployNode = hostName: {
hostname = "${hostName}.${domain}";
profiles.system = {
user = "root";
path =
inputs.deploy-rs.lib.${
self.nixosConfigurations.${hostName}.config.system.build.toplevel.system
}.activate.nixos
self.nixosConfigurations.${hostName};
commonModules = [
agenix.nixosModules.age
home-manager.nixosModule
./modules
];
nixosSystem = { system, name, extraModules ? [] }:
let
nixpkgs = nixpkgsForSystem system;
lib = (import nixpkgs { inherit overlays system; }).lib;
in
inputs.nixpkgs.lib.nixosSystem {
inherit lib system;
specialArgs = { modulesPath = toString (nixpkgs + "/nixos/modules"); inherit inputs; };
baseModules = import (nixpkgs + "/nixos/modules/module-list.nix");
modules = commonModules ++ [
({ config, ... }:
{
nixpkgs.pkgs = import nixpkgs {
inherit overlays system;
config.allowUnfree = true;
};
networking.hostName = name;
nix = {
extraOptions = "experimental-features = nix-command flakes";
};
})
./hosts/${name}
] ++ extraModules;
};
in
{
overlays = lib.packagesFromDirectoryRecursive {
callPackage = path: overrides: import path;
directory = ./overlays;
nixosConfigurations = {
atlas = nixosSystem { system = "x86_64-linux"; name = "atlas"; };
eos = nixosSystem { system = "x86_64-linux"; name = "eos"; };
helios = nixosSystem { system = "x86_64-linux"; name = "helios"; };
odyssey = nixosSystem { system = "x86_64-linux"; name = "odyssey"; };
pi = nixosSystem { system = "aarch64-linux"; name = "pi"; extraModules = [ nixos-hardware.nixosModules.raspberry-pi-4 ]; };
};
legacyPackages = forEachSystem (
system:
lib.packagesFromDirectoryRecursive {
callPackage = nixpkgs.legacyPackages.${system}.callPackage;
directory = ./pkgs;
}
);
nixosConfigurations = lib.pipe ./hosts [
builtins.readDir
(lib.filterAttrs (name: value: value == "directory"))
(lib.mapAttrs (
name: value:
lib.nixosSystem {
specialArgs = { inherit self; };
modules = [
{
networking = {
inherit domain;
hostName = name;
};
}
./hosts/${name}
];
}
))
];
checks =
builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib
// (forEachSystem (system: {
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
check-case-conflicts.enable = true;
check-executables-have-shebangs.enable = true;
check-merge-conflicts.enable = true;
deadnix = {
enable = true;
settings = {
noLambdaArg = true;
};
};
detect-private-keys.enable = true;
end-of-file-fixer.enable = true;
fix-byte-order-marker.enable = true;
mixed-line-endings.enable = true;
nixfmt-rfc-style.enable = true;
trim-trailing-whitespace.enable = true;
};
};
}));
formatter = forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
devShells = forEachSystem (system: {
default = nixpkgs.legacyPackages.${system}.mkShell {
inherit (self.checks.${system}.pre-commit-check) shellHook;
buildInputs = [
inputs.agenix.packages.${system}.agenix
inputs.deploy-rs.packages.${system}.deploy-rs
] ++ self.checks.${system}.pre-commit-check.enabledPackages;
};
});
deploy = {
magicRollback = true;
autoRollback = true;
deploy.nodes.pi = {
hostname = "10.0.1.191";
sshUser = "root";
nodes = lib.genAttrs [
"mail"
# "pi"
# "skycam"
"vps1"
] mkDeployNode;
profiles.system = {
user = "root";
path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
};
};
# checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
};
}

View File

@ -1,4 +1,4 @@
{ ... }:
{ config, lib, pkgs, ... }:
{
imports = [
@ -6,52 +6,51 @@
../desktop.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
networking.hostName = "atlas";
networking.hostId = "8425e349";
networking.networkmanager.enable = true;
networking = {
hostId = "8425e349";
networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
virtualisation.virtualbox.host.enable = true;
users.extraGroups.vboxusers.members = [ "jordan" ];
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
programs = {
dev = {
node.enable = true;
};
firefox.enable = true;
git.enable = true;
gpg.enable = true;
graphics = {
raster.enable = true;
vector.enable = true;
};
libreoffice.enable = true;
neovim.enable = true;
pass.enable = true;
desktop = {
apps = {
qbittorrent.enable = true;
thunderbird.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://uzu2y5b1@uzu2y5b1.repo.borgbase.com/./repo";
browsers = {
firefox.enable = true;
};
media.graphics = {
raster.enable = true;
vector.enable = true;
};
office.libreoffice.enable = true;
};
dev = {
node.enable = true;
};
editors = {
neovim.enable = true;
vscode.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,9 +1,4 @@
{
config,
lib,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
@ -11,14 +6,7 @@
];
boot = {
initrd.availableKernelModules = [
"xhci_pci"
"ehci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
];
initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ];
kernelModules = [ "kvm-intel" ];

View File

@ -1,105 +0,0 @@
{
pkgs,
self,
...
}:
{
imports = [
self.inputs.agenix.nixosModules.age
self.inputs.home-manager.nixosModule
../modules/home-manager
../modules/nixos
];
nixpkgs.overlays = [
self.inputs.agenix.overlays.default
(import ../overlays/default.nix)
(final: prev: {
unstable = import self.inputs.nixpkgs-unstable { system = final.system; };
})
];
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
security.sudo.execWheelOnly = true;
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
services.journald.extraConfig = ''
SystemMaxUse=4G
MaxRetentionSec=90day
'';
users.defaultUserShell = pkgs.zsh;
programs.zsh.enable = true;
nix = {
package = pkgs.nixVersions.stable;
extraOptions = ''
experimental-features = nix-command flakes
'';
buildMachines = [
{
hostName = "10.0.1.79";
sshUser = "root";
system = "aarch64-linux";
maxJobs = 6;
speedFactor = 1;
supportedFeatures = [
"big-parallel"
"benchmark"
];
}
];
distributedBuilds = true;
settings = {
connect-timeout = 5;
log-lines = 25;
min-free = 128000000;
max-free = 1000000000;
fallback = true;
trusted-users = [ "@wheel" ];
auto-optimise-store = true;
substituters = [
"http://odyssey.mesh.vimium.net"
"https://cache.nixos.org"
];
trusted-public-keys = [
"odyssey.mesh.vimium.net:ZhQhjscPWjoN4rlZwoMELznEiBnZ9O26iyGA27ibilQ="
];
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
};
environment.systemPackages = with pkgs; [
git
neovim
];
}

View File

@ -1,17 +1,35 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
./common.nix
];
time.timeZone = "Europe/London";
nixpkgs.overlays = [
(import ../overlays/gnome.nix)
];
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
services.printing.enable = true;
services.openssh.startWhenNeeded = true;
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
startWhenNeeded = true;
};
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
@ -21,22 +39,10 @@
pulse.enable = true;
};
fileSystems."/mnt/library" = {
device = "library.mesh.vimium.net:/mnt/library";
fsType = "nfs";
options = [
"nfsvers=4.2"
"bg"
"soft"
"timeo=20"
"retry=5"
"nocto"
"ro"
"x-systemd.automount"
"x-systemd.requires=tailscaled.service"
"noauto"
environment.systemPackages = with pkgs; [
git
neovim
];
};
system.autoUpgrade = {
enable = true;
@ -44,42 +50,29 @@
randomizedDelaySec = "10min";
};
systemd.services.NetworkManager-wait-online.enable = false;
fonts.packages = with pkgs; [
noto-fonts
(nerdfonts.override {
fonts = [
"BigBlueTerminal"
"ComicShannsMono"
"Terminus"
"UbuntuMono"
nix = {
settings = {
connect-timeout = 5;
log-lines = 25;
min-free = 128000000;
max-free = 1000000000;
fallback = true;
auto-optimise-store = true;
substituters = [
"http://odyssey.mesh.vimium.net"
"https://cache.nixos.org"
];
})
trusted-public-keys = [
"odyssey.mesh.vimium.net:ZhQhjscPWjoN4rlZwoMELznEiBnZ9O26iyGA27ibilQ="
];
modules = {
system.desktop.gnome.enable = true;
services.tailscale.enable = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
};
environment.systemPackages = with pkgs; [
bind
bmon
fd
ffmpeg
iotop
# unstable.nix-du
# unstable.nix-melt
unstable.nix-tree
unstable.nix-visualize
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
];
environment.sessionVariables.NIXOS_OZONE_WL = "1";
modules.desktop.gnome.enable = true;
modules.networking.tailscale.enable = true;
}

View File

@ -1,4 +1,4 @@
{ ... }:
{ config, lib, pkgs, ... }:
{
imports = [
@ -6,17 +6,22 @@
../desktop.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
networking.hostName = "eos";
networking.hostId = "cc858347";
networking.networkmanager.enable = true;
networking = {
hostId = "cc858347";
networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.settings.auto-optimise-store = true;
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
dconf.settings = {
"org/gnome/desktop/interface" = {
@ -25,21 +30,25 @@
};
modules = {
programs = {
desktop = {
apps.qbittorrent.enable = true;
browsers = {
firefox.enable = true;
};
};
dev = {
node.enable = true;
};
firefox.enable = true;
git.enable = true;
gpg.enable = true;
editors = {
neovim.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
qbittorrent.enable = true;
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,9 +1,4 @@
{
config,
lib,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
@ -11,19 +6,12 @@
];
boot = {
initrd.availableKernelModules = [
"ehci_pci"
"ahci"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ];
kernel.sysctl = {
"kernel.nmi_watchdog" = 0;
"vm.laptop_mode" = 5;
};
kernelModules = [ ];
kernelParams = [ "elevator=none" ];
extraModulePackages = [ ];
supportedFilesystems = [ "zfs" ];
};

View File

@ -1,4 +1,4 @@
{ pkgs, ... }:
{ config, lib, pkgs, inputs, ... }:
{
imports = [
@ -6,8 +6,6 @@
../desktop.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot = {
loader.grub = {
enable = true;
@ -17,25 +15,36 @@
};
networking = {
hostName = "helios";
hostId = "47d23505";
networkmanager.enable = true;
};
environment.systemPackages = [
pkgs.moonlight-qt
];
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
programs = {
desktop = {
apps.qbittorrent.enable = true;
browsers = {
firefox.enable = true;
};
};
dev = {
node.enable = true;
};
firefox.enable = true;
git.enable = true;
gpg.enable = true;
editors = {
neovim.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
qbittorrent.enable = true;
};
services = {
borgmatic = {
@ -47,9 +56,8 @@
};
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,9 +1,4 @@
{
config,
lib,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
@ -11,15 +6,7 @@
];
boot = {
initrd.availableKernelModules = [
"ehci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
"sr_mod"
"zfs"
];
initrd.availableKernelModules = [ "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" "zfs" ];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ];
kernelModules = [ "kvm-intel" ];

View File

@ -1,101 +0,0 @@
From d310ddee0fb8e7a5a8b89668c6cb8f9dc863ce94 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sun, 28 Apr 2024 15:59:52 +0100
Subject: [PATCH] Add apple_set_os EFI boot service
---
drivers/firmware/efi/libstub/x86-stub.c | 59 +++++++++++++++++++++++++
include/linux/efi.h | 1 +
2 files changed, 60 insertions(+)
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index d5a8182cf..be722c43a 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -449,6 +449,63 @@ static void setup_graphics(struct boot_params *boot_params)
}
}
+typedef struct {
+ u64 version;
+ void (*set_os_version) (const char *os_version);
+ void (*set_os_vendor) (const char *os_vendor);
+} apple_set_os_interface_t;
+
+static efi_status_t apple_set_os()
+{
+ apple_set_os_interface_t *set_os;
+ efi_guid_t set_os_guid = APPLE_SET_OS_PROTOCOL_GUID;
+ efi_status_t status;
+ void **handles;
+ unsigned long i, nr_handles, size = 0;
+
+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
+ &set_os_guid, NULL, &size, handles);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
+ size, &handles);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
+ &set_os_guid, NULL, &size, handles);
+ }
+
+ if (status != EFI_SUCCESS)
+ goto free_handle;
+
+ nr_handles = size / sizeof(void *);
+ for (i = 0; i < nr_handles; i++) {
+ void *h = handles[i];
+
+ status = efi_bs_call(handle_protocol, h,
+ &set_os_guid, &set_os);
+
+ if (status != EFI_SUCCESS || !set_os)
+ continue;
+
+ if (set_os->version > 0) {
+ efi_bs_call((unsigned long)set_os->set_os_version,
+ "Mac OS X 10.9");
+ }
+
+ if (set_os->version >= 2) {
+ efi_bs_call((unsigned long)set_os->set_os_vendor,
+ "Apple Inc.");
+ }
+ }
+
+free_handle:
+ efi_bs_call(free_pool, uga_handle);
+
+ return status;
+}
static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)
{
@@ -951,6 +1008,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
setup_unaccepted_memory();
+ apple_set_os();
+
status = exit_boot(boot_params, handle);
if (status != EFI_SUCCESS) {
efi_err("exit_boot() failed!\n");
diff --git a/include/linux/efi.h b/include/linux/efi.h
index d59b0947f..81158014f 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -385,6 +385,7 @@ void efi_native_runtime_setup(void);
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
+#define APPLE_SET_OS_PROTOCOL_GUID EFI_GUID(0xc5c5da95, 0x7d5c, 0x45e6, 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77)
#define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
#define EFI_LOAD_FILE_PROTOCOL_GUID EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
--
2.42.0

View File

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

View File

@ -1,71 +0,0 @@
{
config,
lib,
self,
pkgs,
...
}:
{
imports = [
self.inputs.disko.nixosModules.disko
./hardware-configuration.nix
./disko-config.nix
../desktop.nix
];
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
networking.hostId = "cf791898";
# nvidia 470 driver doesn't work with Wayland
services = {
xserver = {
displayManager.gdm.wayland = lib.mkForce false;
videoDrivers = [ "nvidia" ];
};
displayManager = {
defaultSession = if config.modules.system.desktop.kde.enable then "plasmax11" else "gnome-xorg";
sddm.wayland.enable = lib.mkForce false;
};
};
# Workaround for label rendering bug in GTK4 with nvidia 470 driver
environment.sessionVariables.GSK_RENDERER = "gl";
environment.systemPackages = [
pkgs.moonlight-qt
];
modules = {
programs = {
dev = {
node.enable = true;
};
firefox.enable = true;
git.enable = true;
gpg.enable = true;
neovim.enable = true;
pass.enable = true;
recording = {
audio.enable = true;
};
};
shell = {
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,125 +0,0 @@
{ ... }:
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/ata-APPLE_SSD_SM0512F_S1K5NYBF736152";
content = {
type = "gpt";
partitions = {
ESP = {
size = "256M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "rpool";
};
};
};
};
};
};
zpool = {
rpool = {
type = "zpool";
options = {
ashift = "12";
};
rootFsOptions = {
canmount = "off";
mountpoint = "none";
dnodesize = "auto";
xattr = "sa";
};
postCreateHook = "zfs snapshot rpool@blank";
datasets = {
local = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"local/nix" = {
type = "zfs_fs";
mountpoint = "/nix";
options = {
atime = "off";
mountpoint = "legacy";
};
};
"local/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
system = {
type = "zfs_fs";
mountpoint = "/";
options = {
mountpoint = "legacy";
};
};
"system/var" = {
type = "zfs_fs";
mountpoint = "/var";
options = {
mountpoint = "legacy";
};
};
"system/var/tmp" = {
type = "zfs_fs";
mountpoint = "/var/tmp";
options = {
devices = "off";
mountpoint = "legacy";
};
};
"system/var/log" = {
type = "zfs_fs";
mountpoint = "/var/log";
options = {
compression = "on";
acltype = "posix";
mountpoint = "legacy";
};
};
user = {
type = "zfs_fs";
options = {
mountpoint = "none";
encryption = "aes-256-gcm";
keyformat = "passphrase";
keylocation = "file:///tmp/secret.key";
};
# use this to read the key during boot
postCreateHook = ''
zfs set keylocation="prompt" "rpool/$name";
'';
};
"user/home" = {
type = "zfs_fs";
mountpoint = "/home";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
};
};
};
};
}

View File

@ -1,56 +0,0 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
];
kernel.sysctl = {
"kernel.nmi_watchdog" = 0;
"vm.laptop_mode" = 5;
};
kernelModules = [
"applesmc"
"kvm-intel"
"wl"
];
extraModulePackages = [
config.boot.kernelPackages.broadcom_sta
config.boot.kernelPackages.nvidiaPackages.legacy_470
];
};
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware = {
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = {
package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
modesetting.enable = true;
powerManagement.enable = true;
};
graphics = {
enable = true;
extraPackages = with pkgs; [
libvdpau-va-gl
];
enable32Bit = true;
};
};
}

View File

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

View File

@ -1,204 +0,0 @@
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
../server.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
zfs.extraPools = [ "library" ];
};
networking = {
hostId = "d24ae953";
hosts = {
"100.64.0.1" = [ "auth.vimium.com" ];
};
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
services.zfs = {
autoScrub = {
enable = true;
pools = [ "library" ];
};
autoSnapshot = {
enable = true;
flags = "-k -p --utc";
frequent = 0;
hourly = 0;
daily = 7;
monthly = 1;
};
};
services.nfs.server = {
enable = true;
};
services.grafana = {
enable = true;
settings = {
server = {
domain = "library.mesh.vimium.net";
http_addr = "0.0.0.0";
http_port = 3000;
};
};
};
services.prometheus = {
enable = true;
port = 9001;
exporters = {
node = {
enable = true;
enabledCollectors = [ "systemd" ];
port = 9002;
};
zfs = {
enable = true;
port = 9003;
};
};
scrapeConfigs = [
{
job_name = "node";
static_configs = [
{
targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
"127.0.0.1:${toString config.services.prometheus.exporters.zfs.port}"
];
}
];
}
];
};
systemd.services.vps1-tunnel = {
enable = true;
description = "vps1.mesh.vimium.net SSH tunnel";
after = [
"network-online.target"
"jellyfin.service"
];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "simple";
ExecStart = pkgs.lib.mkForce ''
${pkgs.openssh}/bin/ssh \
-NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o TCPKeepAlive=no \
-i %h/.ssh/id_jellyfin \
-R localhost:8000:localhost:8000 \
jellyfin@vps1.mesh.vimium.net
'';
Restart = "always";
RestartSec = 20;
};
wantedBy = [ "default.target" ];
};
services.nginx =
let
proxyConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
in
{
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
virtualHosts = {
"library.mesh.vimium.net" = {
locations."/" = {
root = "/mnt/library";
extraConfig = ''
autoindex on;
'';
};
};
"jellyfin.vimium.com" = {
default = true;
listen = [
{
addr = "127.0.0.1";
port = 8000;
}
];
locations."/" = {
proxyPass = "http://localhost:8096";
extraConfig = proxyConfig;
};
locations."/metrics" = {
return = "404";
};
};
};
};
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
vaapiVdpau
];
};
users.users.jellyfin.extraGroups = [
"video"
"render"
];
services.jellyfin = {
enable = true;
package = pkgs.unstable.jellyfin;
cacheDir = "/var/cache/jellyfin";
dataDir = "/var/lib/jellyfin";
};
modules = {
podman.enable = true;
programs = {
gpg.enable = true;
};
shell = {
zsh.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
config.services.jellyfin.dataDir
"/home/jordan"
];
repoPath = "ssh://b61758r4@b61758r4.repo.borgbase.com/./repo";
};
};
};
system.stateVersion = "22.11";
}

View File

@ -1,78 +0,0 @@
{
config,
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usb_storage"
"sd_mod"
];
initrd.kernelModules = [ ];
kernelModules = [ "kvm-amd" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "rpool/system/root";
fsType = "zfs";
};
fileSystems."/var" = {
device = "rpool/system/var";
fsType = "zfs";
};
fileSystems."/var/log" = {
device = "rpool/system/var/log";
fsType = "zfs";
};
fileSystems."/var/tmp" = {
device = "rpool/system/var/tmp";
fsType = "zfs";
};
fileSystems."/var/lib/containers/storage" = {
device = "rpool/system/var/lib-containers-storage";
fsType = "zfs";
};
fileSystems."/nix" = {
device = "rpool/local/nix";
fsType = "zfs";
};
fileSystems."/tmp" = {
device = "rpool/local/tmp";
fsType = "zfs";
};
fileSystems."/home" = {
device = "rpool/user/home";
fsType = "zfs";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/F697-F1C0";
fsType = "vfat";
};
swapDevices = [ ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

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

View File

@ -1,55 +0,0 @@
{
lib,
self,
...
}:
{
imports = [
self.inputs.disko.nixosModules.disko
./hardware-configuration.nix
./disko-config.nix
../server.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking = {
hostId = "08ac2f14";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
users = {
users = {
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
modules = {
services = {
borgmatic = {
enable = true;
directories = [
"/var/dkim"
"/var/lib"
"/var/vmail"
];
repoPath = "ssh://kg2mpt28@kg2mpt28.repo.borgbase.com/./repo";
};
mail.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

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

View File

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

45
hosts/odyssey/audio.nix Normal file
View File

@ -0,0 +1,45 @@
{ config, pkgs, ... }:
let
snd-usb-audio-module = pkgs.callPackage ./snd-usb-audio.nix {
kernel = config.boot.kernelPackages.kernel;
};
upmixConfig = ''
stream.properties = {
channelmix.upmix = true
channelmix.upmix-method = psd
}
'';
in {
boot.extraModulePackages = [
(snd-usb-audio-module.overrideAttrs (_: {
patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ];
}))
];
environment.etc = {
"pipewire/pipewire.conf.d/surround.conf".text = ''
context.modules = [
{
name = libpipewire-module-loopback
args = {
node.description = "Genelec 4.1 Surround"
capture.props = {
node.name = "Genelec_Speakers"
media.class = "Audio/Sink"
audio.position = [ FL FR SL SR LFE ]
}
playback.props = {
node.name = "playback.Genelec_Speakers"
audio.position = [ AUX0 AUX1 AUX3 AUX4 AUX5 ]
target.object = "alsa_output.usb-PreSonus_Studio_1824c_SC4E21110775-00.multichannel-output"
stream.dont-remix = true
node.passive = true
}
}
}
]
'';
"pipewire/pipewire-pulse.conf.d/40-upmix.conf".text = upmixConfig;
"pipewire/client-rt.conf.d/40-upmix.conf".text = upmixConfig;
};
}

View File

@ -1,41 +1,41 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, inputs, ... }:
{
imports = [
./hardware-configuration.nix
./audio.nix
../desktop.nix
];
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};
boot.loader = {
systemd-boot = {
boot.loader.systemd-boot = {
enable = true;
graceful = true;
netbootxyz.enable = true;
};
efi.canTouchEfiVariables = true;
};
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostId = "c5e68d78";
networkmanager.enable = true;
firewall.trustedInterfaces = [
"lxdbr0"
"virbr0"
]; # Work around https://github.com/NixOS/nixpkgs/issues/263359
};
networking.hostName = "odyssey";
networking.hostId = "c5e68d78";
networking.networkmanager.enable = true;
virtualisation = {
libvirtd.enable = true;
lxd.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
virtualisation.libvirtd.enable = true;
virtualisation.lxd.enable = true;
# Work around https://github.com/NixOS/nixpkgs/issues/263359
networking.firewall.trustedInterfaces = [ "lxdbr0" "virbr0" ];
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
services.journald.extraConfig = ''
SystemMaxUse=4G
MaxRetentionSec=90day
'';
services.nix-serve = {
enable = true;
@ -47,70 +47,54 @@
recommendedProxySettings = true;
virtualHosts = {
"odyssey.mesh.vimium.net" = {
locations."/".proxyPass =
"http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
};
};
};
services.sunshine = {
enable = true;
package = pkgs.unstable.sunshine;
capSysAdmin = true;
};
modules = {
programs = {
dev = {
node.enable = true;
};
emulators = {
gamecube.enable = true;
ps2.enable = true;
ps3.enable = true;
psp.enable = true;
wii.enable = true;
xbox.enable = true;
};
desktop = {
apps.qbittorrent.enable = true;
browsers = {
firefox.enable = true;
git.enable = true;
gpg.enable = true;
graphics = {
};
gaming.emulators = {
ps2.enable = true;
psp.enable = true;
};
media.graphics = {
modeling.enable = true;
raster.enable = true;
vector.enable = true;
};
libreoffice.enable = true;
lutris.enable = true;
pass.enable = true;
neovim.enable = true;
qbittorrent.enable = true;
recording = {
media.recording = {
audio.enable = true;
video.enable = true;
};
};
hardware.presonus-studio.enable = true;
dev = {
node.enable = true;
};
editors = {
neovim.enable = true;
vscode.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
"/home/jordan/Downloads"
"/home/jordan/Music"
"/home/jordan/Pictures"
"/home/jordan/projects"
"/home/jordan/Videos"
"/home/jordan/.mozilla"
];
repoPath = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo";
};
gitea-runner.enable = true;
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,10 +1,4 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
@ -12,14 +6,7 @@
];
boot = {
initrd.availableKernelModules = [
"xhci_pci"
"ehci_pci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ];
kernelModules = [ "kvm-intel" ];
@ -32,8 +19,6 @@
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = {
modesetting.enable = true;
open = true;
package = config.boot.kernelPackages.nvidiaPackages.beta;
powerManagement.enable = true;
};
};
@ -79,9 +64,5 @@
networking.useDHCP = lib.mkDefault true;
environment.systemPackages = [
pkgs.apfs-fuse
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@ -1,17 +1,8 @@
{
pkgs,
lib,
kernel ? pkgs.linuxPackages_latest.kernel,
}:
{ pkgs, lib, kernel ? pkgs.linuxPackages_latest.kernel }:
pkgs.stdenv.mkDerivation {
pname = "snd-usb-audio";
inherit (kernel)
src
version
postPatch
nativeBuildInputs
;
inherit (kernel) src version postPatch nativeBuildInputs;
kernel_dev = kernel.dev;
kernelVersion = kernel.modDirVersion;
@ -42,3 +33,4 @@ pkgs.stdenv.mkDerivation {
license = lib.licenses.gpl2;
};
}

View File

@ -16,10 +16,3 @@ SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `pi.mesh.vimium.net`.
## Devices and connections
- SONOFF Zigbee 3.0 USB Dongle Plus (connected to USB 2.0 port to avoid [interference](https://www.unit3compliance.co.uk/2-4ghz-intra-system-or-self-platform-interference-demonstration/))
- HDMI to ONKYO HT-R990
- S/PDIF to ONKYO HT-R990
- Ethernet to ONKYO HT-R990

View File

@ -1,17 +1,12 @@
{
pkgs,
self,
...
}:
{ config, lib, pkgs, inputs, ... }:
{
imports = [
self.inputs.nixos-hardware.nixosModules.raspberry-pi-4
./hardware-configuration.nix
../server.nix
];
nixpkgs.hostPlatform = "aarch64-linux";
networking.hostId = "731d1660";
hardware = {
raspberry-pi."4" = {
@ -22,78 +17,8 @@
};
deviceTree = {
enable = true;
filter = "*rpi-4-*.dtb";
overlays = [
{
name = "audio-off-overlay";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&vchiq>;
__overlay__ {
status = "disabled";
};
};
};
'';
}
{
# Adapted from: https://github.com/raspberrypi/linux/blob/rpi-6.1.y/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
# changes:
# - modified top-level "compatible" field from bcm2835 to bcm2711
# - s/i2s_clk_consumer/i2s/ (name on bcm2711 platform)
name = "hifiberry-digi-pro";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
wm8804@3b {
#sound-dai-cells = <0>;
compatible = "wlf,wm8804";
reg = <0x3b>;
PVDD-supply = <&vdd_3v3_reg>;
DVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
};
fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "hifiberry,hifiberry-digi";
i2s-controller = <&i2s>;
status = "okay";
clock44-gpio = <&gpio 5 0>;
clock48-gpio = <&gpio 6 0>;
};
};
};
'';
}
{ name = "hifiberry-digi-pro"; dtboFile = "${pkgs.device-tree_rpi.overlays}/hifiberry-digi-pro.dtbo"; }
];
};
firmware = with pkgs; [
@ -102,7 +27,7 @@
];
};
networking.hostId = "731d1660";
sound.enable = true;
security.rtkit.enable = true;
services.pipewire = {
@ -110,10 +35,66 @@
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
systemWide = true;
};
virtualisation.oci-containers = {
backend = "podman";
containers.homeassistant = {
volumes = [ "home-assistant:/config" ];
environment.TZ = config.time.timeZone;
image = "ghcr.io/home-assistant/home-assistant:stable";
extraOptions = [
"--network=host"
"--device=/dev/ttyUSB0:/dev/ttyUSB0"
];
};
};
services.mosquitto = {
enable = true;
listeners = [{
port = 1883;
settings = {
allow_anonymous = true;
};
}];
};
age.secrets."files/services/zigbee2mqtt/secret.yaml" = {
file = "${inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age";
path = "${config.services.zigbee2mqtt.dataDir}/secret.yaml";
owner = "zigbee2mqtt";
group = "zigbee2mqtt";
};
services.zigbee2mqtt = {
enable = true;
dataDir = "/var/lib/zigbee2mqtt";
settings = {
homeassistant = true;
frontend = true;
device_options = {
retain = true;
};
serial = {
port = "/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0";
};
advanced = {
channel = 20;
network_key = "!secret.yaml network_key";
pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
};
mqtt = {
version = 5;
server = "mqtt://localhost:1883";
};
};
};
modules = {
system = {
networking = {
wireless = {
enable = true;
interfaces = [ "wlan0" ];
@ -122,27 +103,20 @@
services = {
borgmatic = {
enable = true;
directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repoPath = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo";
};
home-assistant.enable = true;
};
};
# Connection to ONKYO HT-R990
networking.interfaces.end0 = {
ipv4.addresses = [
{
address = "172.16.0.1";
prefixLength = 30;
}
];
};
environment.systemPackages = with pkgs; [
python311Packages.onkyo-eiscp
libraspberrypi
raspberrypi-eeprom
];
system.stateVersion = "22.11";
}

View File

@ -1,9 +1,4 @@
{
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
@ -11,80 +6,17 @@
];
boot = {
kernelPackages =
let
version = "6.1.73";
tag = "stable_20240124";
srcHash = "sha256-P4ExzxWqZj+9FZr9U2tmh7rfs/3+iHEv0m74PCoXVuM=";
in
pkgs.linuxPackagesFor (
pkgs.linux_rpi4.override {
argsOverride = {
src = pkgs.fetchFromGitHub {
owner = "raspberrypi";
repo = "linux";
rev = tag;
hash = srcHash;
};
version = version;
modDirVersion = version;
structuredExtraConfig = { };
kernelPatches = [
{
name = "drm-rp1-depends-on-instead-of-select-MFD_RP1.patch";
patch = pkgs.fetchpatch {
url = "https://github.com/peat-psuwit/rpi-linux/commit/6de0bb51929cd3ad4fa27b2a421a2af12e6468f5.patch";
hash = "sha256-9pHcbgWTiztu48SBaLPVroUnxnXMKeCGt5vEo9V8WGw=";
};
}
{
name = "iommu-bcm2712-don-t-allow-building-as-module.patch";
patch = pkgs.fetchpatch {
url = "https://github.com/peat-psuwit/rpi-linux/commit/693a5e69bddbcbe1d1b796ebc7581c3597685b1b.patch";
hash = "sha256-8BYYQDM5By8cTk48ASYKJhGVQnZBIK4PXtV70UtfS+A=";
};
}
];
};
}
);
# Stop ZFS kernel being built
supportedFilesystems = lib.mkForce [
"btrfs"
"cifs"
"f2fs"
"jfs"
"ntfs"
"reiserfs"
"vfat"
"xfs"
];
supportedFilesystems = lib.mkForce [ "btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs" ];
tmp.cleanOnBoot = true;
};
# Fix missing modules
# https://github.com/NixOS/nixpkgs/issues/154163
nixpkgs.overlays = [
(final: prev: {
makeModulesClosure = x: prev.makeModulesClosure (x // { allowMissing = true; });
})
(final: prev: {
raspberrypifw =
let
version = "1.20240529";
srcHash = "sha256-KsCo7ZG6vKstxRyFljZtbQvnDSqiAPdUza32xTY/tlA=";
in
pkgs.raspberrypifw.override {
argsOverride = {
src = prev.fetchFromGitHub {
owner = "raspberrypi";
repo = "firmware";
rev = "${version}";
hash = srcHash;
};
};
};
(final: super: {
makeModulesClosure = x:
super.makeModulesClosure (x // { allowMissing = true; });
})
];
@ -96,3 +28,4 @@
};
};
}

View File

@ -1,62 +1,51 @@
{
...
}:
{ config, lib, pkgs, ... }:
{
imports = [
./common.nix
];
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
documentation.enable = false;
fonts.fontconfig.enable = false;
security = {
acme = {
acceptTerms = true;
defaults = {
email = "hostmaster@vimium.com";
group = "nginx";
webroot = "/var/lib/acme/acme-challenge";
};
};
# auditd.enable = true;
# audit = {
# enable = true;
# rules = [
# "-a exit,always -F arch=b64 -S execve"
# ];
# };
};
systemd = {
enableEmergencyMode = false;
sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
watchdog = {
runtimeTime = "20s";
rebootTime = "30s";
};
};
services.fail2ban = {
services.openssh = {
enable = true;
bantime = "1h";
bantime-increment = {
enable = true;
maxtime = "24h";
rndtime = "7m";
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
ignoreIP = [
"100.64.0.0/10"
};
environment.systemPackages = with pkgs; [
git
neovim
];
nix = {
settings = {
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
};
modules.services.tailscale = {
modules.networking.tailscale = {
enable = true;
restrictSSH = false;
};

View File

@ -1,28 +0,0 @@
# Skycam
## Overview
Raspberry Pi 4-based webcam
## Specs
* SoC - Broadcom BCM2711
* CPU - ARM Cortex-A72 @ 1.8 GHz
* Memory - 8 GB LPDDR4
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `skycam.mesh.vimium.net`.
## Devices and connections
- Camera Module 3 with wide-angle lens
## Building
To generate a compressed SD card image for Skycam, run:
`nix build '.#nixosConfigurations.skycam.config.system.build.sdImage'`
Once a card is imaged, the existing SSH host keys should be copied to
`/etc/ssh` manually to enable secret decryption.

View File

@ -1,127 +0,0 @@
{
config,
lib,
pkgs,
self,
...
}:
{
imports = [
self.inputs.nixos-hardware.nixosModules.raspberry-pi-4
./hardware-configuration.nix
../server.nix
];
nixpkgs.hostPlatform = "aarch64-linux";
hardware = {
raspberry-pi."4" = {
apply-overlays-dtmerge.enable = true;
audio.enable = false;
xhci.enable = false;
};
deviceTree = {
enable = true;
filter = "*rpi-4-*.dtb";
# From https://github.com/Electrostasy/dots/blob/3b81723feece67610a252ce754912f6769f0cd34/hosts/phobos/klipper.nix#L43-L65
overlays =
let
mkCompatibleDtsFile =
dtbo:
let
drv =
pkgs.runCommand "fix-dts"
{
nativeBuildInputs = with pkgs; [
dtc
gnused
];
}
''
mkdir "$out"
dtc -I dtb -O dts ${dtbo} | sed -e 's/bcm2835/bcm2711/' > $out/overlay.dts
'';
in
"${drv}/overlay.dts";
inherit (config.boot.kernelPackages) kernel;
in
[
{
name = "imx708.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/imx708.dtbo";
}
{
name = "vc4-kms-v3d-pi4.dtbo";
dtsFile = mkCompatibleDtsFile "${kernel}/dtbs/overlays/vc4-kms-v3d-pi4.dtbo";
}
];
};
firmware = with pkgs; [
firmwareLinuxNonfree
];
};
services.udev.extraRules = ''
SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660"
KERNEL=="vcsm-cma", GROUP="video", MODE="0660"
SUBSYSTEM=="dma_heap", GROUP="video", MODE="0660"
'';
nixpkgs.overlays = [
(import ./../../overlays/libcamera.nix)
];
networking = {
hostId = "731d1660";
firewall = {
enable = true;
allowedTCPPorts = [ 8080 ];
allowedUDPPorts = [ 8080 ];
};
};
users.users.root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
systemd.services.ustreamer = {
enable = true;
description = "uStreamer service";
unitConfig = {
Type = "simple";
ConditionPathExists = "/sys/bus/i2c/drivers/imx708/10-001a/video4linux";
};
serviceConfig = {
ExecStart = ''
${pkgs.libcamera}/bin/libcamerify ${pkgs.unstable.ustreamer}/bin/ustreamer \
--host=0.0.0.0 \
--resolution=4608x2592
'';
DynamicUser = "yes";
SupplementaryGroups = [ "video" ];
Restart = "always";
RestartSec = 10;
};
wantedBy = [ "network-online.target" ];
confinement.mode = "chroot-only";
};
environment.systemPackages = with pkgs; [
camera-streamer
git
neovim
libcamera
libraspberrypi
raspberrypi-eeprom
v4l-utils
unstable.ustreamer
];
system.stateVersion = "24.05";
}

View File

@ -1,39 +0,0 @@
{
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/sd-card/sd-image-aarch64.nix")
];
boot = {
kernelModules = [ "bcm2835-v4l2" ];
kernelParams = [
"cma=512M"
"panic=0"
];
supportedFilesystems = lib.mkForce [
"f2fs"
"vfat"
"xfs"
];
tmp.cleanOnBoot = false;
};
nixpkgs.overlays = [
(final: super: {
makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; });
})
];
fileSystems = {
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
options = [ "noatime" ];
};
};
}

View File

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

View File

@ -1,124 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
imports = [
./hardware-configuration.nix
../server.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking = {
hostId = "08bf6db3";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
users = {
users = {
jellyfin = {
isSystemUser = true;
group = "jellyfin";
shell = "/bin/sh";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaaS+KMAEAymZhIJGC4LK8aMhUzhpmloUgvP2cxeBH4 jellyfin"
];
};
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
groups = {
jellyfin = { };
};
extraGroups.acme.members = [
"kanidm"
"nginx"
];
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
security.acme.certs."auth.vimium.com" = {
postRun = "systemctl restart kanidm.service";
group = "acme";
};
services.kanidm =
let
baseDomain = "vimium.com";
domain = "auth.${baseDomain}";
uri = "https://${domain}";
in
{
package = pkgs.unstable.kanidm;
enableClient = true;
enableServer = true;
clientSettings = {
inherit uri;
};
serverSettings = {
bindaddress = "127.0.0.1:3013";
ldapbindaddress = "100.64.0.1:636";
domain = baseDomain;
origin = uri;
tls_chain = "${config.security.acme.certs.${domain}.directory}/full.pem";
tls_key = "${config.security.acme.certs.${domain}.directory}/key.pem";
};
};
services.nginx.virtualHosts = {
"auth.vimium.com" = {
useACMEHost = "auth.vimium.com";
forceSSL = true;
locations."/" = {
proxyPass = "https://127.0.0.1:3013";
};
};
};
modules = rec {
services = {
borgmatic = {
enable = true;
directories = [
"/home"
"/var/lib"
"/var/www"
];
repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo";
};
coturn = {
enable = true;
realm = "turn.vimium.com";
matrixIntegration = true;
};
gitea.enable = true;
headscale.enable = true;
matrix = {
enable = true;
bridges = {
signal = true;
whatsapp = true;
};
usePostgresql = services.postgresql.enable;
};
nginx.enable = true;
photoprism.enable = true;
postgresql.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,33 +0,0 @@
{
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot = {
initrd = {
availableKernelModules = [
"ata_piix"
"uhci_hcd"
"xen_blkfront"
"vmw_pvscsi"
];
kernelModules = [ "nvme" ];
};
loader.grub.device = "/dev/sda";
tmp.cleanOnBoot = true;
};
zramSwap.enable = true;
fileSystems = {
"/" = {
device = "/dev/sda1";
fsType = "ext4";
};
};
}

38
modules/default.nix Normal file
View File

@ -0,0 +1,38 @@
{
imports = [
./options.nix
./desktop/gnome.nix
./desktop/mimeapps.nix
./desktop/apps/qbittorrent.nix
./desktop/apps/slack.nix
./desktop/apps/thunderbird.nix
./desktop/apps/zoom.nix
./desktop/browsers/firefox.nix
./desktop/gaming/emulators.nix
./desktop/gaming/lutris.nix
./desktop/gaming/steam.nix
./desktop/media/graphics.nix
./desktop/media/recording.nix
./desktop/office/libreoffice.nix
./dev/cc.nix
./dev/java.nix
./dev/lua.nix
./dev/node.nix
./dev/python.nix
./dev/rust.nix
./dev/scala.nix
./dev/shell.nix
./dev/zig.nix
./editors/neovim
./editors/vscode.nix
./networking/tailscale.nix
./networking/wireless.nix
./security/gpg.nix
./security/pass.nix
./services/borgmatic
./services/coturn
./services/matrix
./shell/git
./shell/zsh
];
}

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.qbittorrent;
in
{
options.modules.programs.qbittorrent = {
let cfg = config.modules.desktop.apps.qbittorrent;
in {
options.modules.desktop.apps.qbittorrent = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.slack;
in
{
options.modules.programs.slack = {
let cfg = config.modules.desktop.apps.slack;
in {
options.modules.desktop.apps.slack = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
self,
...
}:
{ config, lib, pkgs, inputs, ... }:
let
cfg = config.modules.programs.thunderbird;
in
{
options.modules.programs.thunderbird = {
let cfg = config.modules.desktop.apps.thunderbird;
in {
options.modules.desktop.apps.thunderbird = {
enable = lib.mkOption {
default = false;
example = true;
@ -17,8 +10,7 @@ in
};
config = lib.mkIf cfg.enable {
home.file.".thunderbird/Default/chrome/thunderbird-gnome-theme".source =
self.inputs.thunderbird-gnome-theme;
home.file.".thunderbird/Default/chrome/thunderbird-gnome-theme".source = inputs.thunderbird-gnome-theme;
home.programs.thunderbird = {
enable = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.zoom;
in
{
options.modules.programs.zoom = {
let cfg = config.modules.desktop.apps.zoom;
in {
options.modules.desktop.apps.zoom = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
self,
...
}:
{ config, lib, pkgs, inputs, ... }:
let
cfg = config.modules.programs.firefox;
in
{
options.modules.programs.firefox = {
let cfg = config.modules.desktop.browsers.firefox;
in {
options.modules.desktop.browsers.firefox = {
enable = lib.mkOption {
default = false;
example = true;
@ -17,8 +10,7 @@ in
};
config = lib.mkIf cfg.enable {
home.file.".mozilla/firefox/Default/chrome/firefox-gnome-theme".source =
self.inputs.firefox-gnome-theme;
home.file.".mozilla/firefox/Default/chrome/firefox-gnome-theme".source = inputs.firefox-gnome-theme;
home.programs.firefox = {
enable = true;
@ -43,79 +35,23 @@ in
## Preferences
"browser.ctrlTab.sortByRecentlyUsed" = true;
"browser.discovery.enabled" = false;
"browser.download.open_pdf_attachments_inline" = true;
"browser.menu.showViewImageInfo" = true;
"browser.newtabpage.enabled" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"browser.newtabpage.activity-stream.default.sites" = "";
"browser.privatebrowsing.forceMediaMemoryCache" = true;
"browser.search.widget.inNavBar" = true;
"browser.startup.page" = 3;
"browser.startup.homepage" = "https://www.vimium.com";
"browser.toolbars.bookmarks.visibility" = "never";
"browser.uitour.enabled" = false;
"browser.urlbar.suggest.engines" = false;
"browser.urlbar.suggest.calculator" = true;
"browser.urlbar.trending.featureGate" = false;
"browser.urlbar.unitConversion.enabled" = true;
"cookiebanners.service.mode" = 1;
"cookiebanners.service.mode.privateBrowsing" = 1;
"network.IDN_show_punycode" = true;
## Performance
"browser.cache.jsbc_compression_level" = 3;
"content.notify.interval" = 100000;
"dom.enable_web_task_scheduling" = true;
"dom.security.sanitizer.enabled" = true;
"gfx.canvas.accelerated.cache-items" = 4096;
"gfx.canvas.accelerated.cache-size" = 512;
"gfx.content.skia-font-cache-size" = 20;
"gfx.webrender.all" = true;
"gfx.webrender.compositor" = true;
"gfx.webrender.enable" = true;
"image.mem.decode_bytes_at_a_time" = 32768;
"layers.acceleration.force-enabled" = true;
"layout.css.grid-template-masonry-value.enabled" = true;
"media.ffmpeg.vaapi.enabled" = true;
"media.memory_cache_max_size" = 65536;
"media.cache_readahead_limit" = 7200;
"media.cache_resume_threshold" = 3600;
"network.dns.disablePrefetch" = true;
"network.dns.disablePrefetchFromHTTPS" = true;
"network.dnsCacheExpiration" = 3600;
"network.http.max-connections" = 1800;
"network.http.max-persistent-connections-per-server" = 10;
"network.http.max-urgent-start-excessive-connections-per-host" = 5;
"network.http.pacing.requests.enabled" = false;
"network.predictor.enabled" = false;
"network.prefetch-next" = false;
"network.ssl_tokens_cache_capacity" = 10240;
"pdfjs.enableScripting" = false;
"security.mixed_content.block_display_content" = true;
## Experiments
"app.normandy.enabled" = false;
"app.normandy.api_url" = "";
"app.normandy.user_id" = "";
"app.shield.optoutstudies.enabled" = false;
"browser.shopping.experience2023.active" = false;
"browser.shopping.experience2023.enabled" = false;
"extensions.screenshots.disabled" = true;
"extensions.screenshots.upload-disabled" = true;
"experiments.supported" = false;
"experiments.enabled" = false;
"experiments.manifest.uri" = "";
"network.allow-experiments" = false;
## Privacy
"dom.private-attribution.submission.enabled" = false;
# "privacy.resistFingerprinting" = true;
"privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts" = false;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.pbmode.enabled" = true;
"privacy.userContext.enabled" = true;
"privacy.trackingprotection.enabled" = false;
## Geo
"geo.enabled" = false;
@ -162,34 +98,12 @@ in
"dom.battery.enabled" = false;
"dom.vr.enabled" = false;
"media.navigator.enabled" = false;
# "dom.webaudio.enabled" = false;
"dom.webaudio.enabled" = false;
## Isolation
"privacy.firstparty.isolate" = true;
"privacy.firstparty.isolate.restrict_opener_access" = true;
## Telemetry
"beacon.enabled" = false;
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
"browser.newtabpage.activity-stream.telemetry" = false;
"browser.send_pings" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.healthReport.uploadEnabled" = false;
"toolkit.coverage.opt-out" = true;
"toolkit.coverage.endpoint.base" = "";
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.coverage.opt-out" = true;
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.reportingPolicy.firstRun" = false;
"toolkit.telemetry.server" = "data:,";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.updatePing.enabled" = false;
## Pocket/Hello
"loop.enabled" = false;
"loop.feedback.baseUrl" = "";
@ -211,10 +125,6 @@ in
"browser.pocket.useLocaleList" = false;
"brwoser.pocket.enabledLocales" = "";
## Plugins
"plugin.state.flash" = 0;
"plugin.state.java" = 0;
## Misc
"browser.selfsupport.url" = "";
};

View File

@ -0,0 +1,59 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.gaming.emulators;
in {
options.modules.desktop.gaming.emulators = {
ds.enable = lib.mkOption {
default = false;
example = true;
};
gb.enable = lib.mkOption {
default = false;
example = true;
};
gba.enable = lib.mkOption {
default = false;
example = true;
};
gamecube.enable = lib.mkOption {
default = false;
example = true;
};
ps2.enable = lib.mkOption {
default = false;
example = true;
};
ps3.enable = lib.mkOption {
default = false;
example = true;
};
psp.enable = lib.mkOption {
default = false;
example = true;
};
snes.enable = lib.mkOption {
default = false;
example = true;
};
wii.enable = lib.mkOption {
default = false;
example = true;
};
};
config = {
user.packages = with pkgs; [
(lib.mkIf cfg.ps2.enable pcsx2)
(lib.mkIf cfg.ps3.enable rpcs3)
(lib.mkIf cfg.psp.enable ppsspp)
(lib.mkIf cfg.ds.enable desmume)
(lib.mkIf (cfg.gba.enable ||
cfg.gb.enable ||
cfg.snes.enable)
higan)
(lib.mkIf (cfg.wii.enable ||
cfg.gamecube.enable)
dolphin-emu)
];
};
}

View File

@ -0,0 +1,25 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.gaming.lutris;
in {
options.modules.desktop.gaming.lutris = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
lutris
vulkan-loader
vulkan-tools
];
hardware.opengl = {
enable = true;
driSupport = true;
driSupport32Bit = true;
};
};
}

View File

@ -1,14 +1,8 @@
{
config,
lib,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.steam;
in
{
options.modules.programs.steam = {
let cfg = config.modules.desktop.gaming.steam;
in {
options.modules.desktop.gaming.steam = {
enable = lib.mkOption {
default = false;
example = true;

209
modules/desktop/gnome.nix Normal file
View File

@ -0,0 +1,209 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.gnome;
in {
options.modules.desktop.gnome = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
};
services.flatpak.enable = true;
programs.dconf.enable = true;
dconf.settings = {
"org/gnome/shell" = {
disable-user-extensions = false;
enabled-extensions = [
# "another-window-session-manager@gmail.com"
"blur-my-shell@aunetx"
"burn-my-windows@schneegans.github.com"
# "desktop-cube@schneegans.github.com"
# "desktop-zoom@colin.kinlo.ch"
"espresso@coadmunkee.github.com"
# "flypie@schneegans.github.com"
# "forge@jmmaranan.com"
"hue-lights@chlumskyvaclav@gmail.com"
"just-perfection-desktop@just-perfection"
# "pano@elhan.io"
# "paperwm@hedning:matrix.org"
# "search-light@icedman.github.com"
"space-bar@luchrioh"
# "smart-auto-move@khimaros.com"
# "systemd-manager@hardpixel.eu"
# "tailscale-status@maxgallup.github.com"
# "tiling-assistant@leleat-on-github"
"Vitals@CoreCoding.com"
# "wsmatrix@martin.zurowietz.de"
];
favorite-apps = [
"firefox.desktop"
"org.gnome.Nautilus.desktop"
];
};
"org/gnome/shell/extensions/another-window-session-manager" = {
enable-autorestore-sessions = true;
};
"org/gnome/shell/extensions/blur-my-shell/panel" = {
static-blur = true;
};
"org/gnome/shell/extensions/blur-my-shell/applications" = {
blur = false;
};
"org/gnome/shell/extensions/burn-my-windows" = {
fire-close-effect = false;
glide-open-effect = true;
glide-close-effect = true;
};
"org/gnome/shell/extensions/desktop-zoom" = {
mag-factor-delta = 0.07;
};
"org/gnome/shell/extensions/espresso" = {
enable-fullscreen = true;
show-indicator = true;
show-notifications = false;
inhibit-apps = [
"com.obsproject.Studio.desktop"
];
};
"org/gnome/shell/extensions/paperwm" = {
use-default-background = true;
};
"org/gnome/shell/extensions/forge" = {
window-gap-size = 8;
window-gap-hidden-on-single = false;
};
"org/gnome/shell/extensions/just-perfection" = {
activities-button = false;
window-demands-attention-focus = true;
workspace-wrap-around = true;
};
"org/gnome/shell/extensions/space-bar/behavior" = {
enable-activate-workspace-shortcuts = true;
show-empty-workspaces = true;
smart-workspace-names = false;
};
"org/gnome/shell/extensions/tiling-assistant" = {
screen-top-gap = 8;
screen-right-gap = 8;
screen-bottom-gap = 8;
screen-left-gap = 8;
window-gap = 8;
};
"org/gnome/desktop/background" = {
picture-uri = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-l.jpg";
picture-uri-dark = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-d.jpg";
};
"org/gtk/settings/file-chooser" = {
show-hidden = true;
sort-directories-first = true;
};
"org/gtk/gtk4/settings/file-chooser" = {
show-hidden = true;
sort-directories-first = true;
};
"org/gnome/settings-daemon/plugins/media-keys" = {
volume-up = [
"<Shift>F12"
"XF86AudioRaiseVolume"
];
volume-down = [
"<Shift>F11"
"XF86AudioLowerVolume"
];
};
"org/gnome/gnome-session" = {
auto-save-session = true;
};
"org/gnome/gnome-system-monitor" = {
show-dependencies = true;
};
"org/gnome/Console" = {
font-scale = 1.4;
};
"org/gnome/mutter" = {
center-new-windows = true;
experimental-features = [ "scale-monitor-framebuffer" ];
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false;
monospace-font-name = "Ubuntu Mono 11";
};
"org/gnome/desktop/wm/keybindings" = {
switch-group = [ "<Super>grave" ];
switch-group-backward = [ "<Shift><Super>grave" ];
};
"io/github/celluloid-player/celluloid" = {
draggable-video-area-enable = true;
};
};
fonts.packages = with pkgs; [
noto-fonts
ubuntu_font_family
];
user.packages = with pkgs; [
celluloid
fragments
mission-center
];
environment.systemPackages = with pkgs; [
bind
bmon
fd
ffmpeg
gnome.gnome-boxes
gnomeExtensions.another-window-session-manager
# gnomeExtensions.bifocals
gnomeExtensions.blur-my-shell
gnomeExtensions.browser-tabs
gnomeExtensions.burn-my-windows
gnomeExtensions.desktop-cube
gnomeExtensions.desktop-zoom
gnomeExtensions.espresso
gnome44Extensions."flypie@schneegans.github.com"
# gnomeExtensions.forge
# gnomeExtensions.gsnap
gnomeExtensions.hue-lights
gnomeExtensions.just-perfection
# gnomeExtensions.mutter-primary-gpu
gnomeExtensions.pano
gnomeExtensions.paperwm
# gnomeExtensions.pip-on-top
gnomeExtensions.rounded-window-corners
gnomeExtensions.search-light
gnomeExtensions.smart-auto-move
gnomeExtensions.space-bar
gnomeExtensions.systemd-manager
gnomeExtensions.tailscale-status
gnomeExtensions.tiling-assistant
# gnomeExtensions.todotxt
gnomeExtensions.vitals
# gnomeExtensions.window-is-ready-remover
# gnomeExtensions.worksets
# gnomeExtensions.workspace-matrix
iotop
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
] ++ (if config.virtualisation.podman.enable then [
pods
] else []);
home.services.gpg-agent.pinentryFlavor = "gnome3";
};
}

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.graphics;
in
{
options.modules.programs.graphics = {
let cfg = config.modules.desktop.media.graphics;
in {
options.modules.desktop.media.graphics = {
modeling.enable = lib.mkOption {
default = false;
example = true;

View File

@ -0,0 +1,28 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.media.recording;
in {
options.modules.desktop.media.recording = {
audio.enable = lib.mkOption {
default = false;
example = true;
};
video.enable = lib.mkOption {
default = false;
example = true;
};
};
config = {
user.packages = with pkgs;
(if cfg.audio.enable then [
ardour
audacity
] else []) ++
(if cfg.video.enable then [
handbrake
mkvtoolnix
obs-studio
] else []);
};
}

View File

@ -1,16 +1,11 @@
{
config,
lib,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.system.desktop.mimeapps;
cfg = config.modules.desktop.mimeapps;
avApp = "io.github.celluloid_player.Celluloid.desktop";
imageApp = "org.gnome.eog.desktop";
in
{
options.modules.system.desktop.mimeapps = {
in {
options.modules.desktop.mimeapps = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.node;
in
{
options.modules.programs.dev.node = {
let cfg = config.modules.desktop.office.libreoffice;
in {
options.modules.desktop.office.libreoffice = {
enable = lib.mkOption {
default = false;
example = true;
@ -18,7 +11,7 @@ in
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
nodejs_22
libreoffice
];
};
}

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.cc;
in
{
options.modules.programs.dev.cc = {
let cfg = config.modules.dev.cc;
in {
options.modules.dev.cc = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.java;
in
{
options.modules.programs.dev.java = {
let cfg = config.modules.dev.java;
in {
options.modules.dev.java = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.lua;
in
{
options.modules.programs.dev.lua = {
let cfg = config.modules.dev.lua;
in {
options.modules.dev.lua = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.brave;
in
{
options.modules.programs.brave = {
let cfg = config.modules.dev.node;
in {
options.modules.dev.node = {
enable = lib.mkOption {
default = false;
example = true;
@ -18,7 +11,7 @@ in
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
brave
nodejs_latest
];
};
}

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.python;
in
{
options.modules.programs.dev.python = {
let cfg = config.modules.dev.python;
in {
options.modules.dev.python = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.rust;
in
{
options.modules.programs.dev.rust = {
let cfg = config.modules.dev.rust;
in {
options.modules.dev.rust = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.scala;
in
{
options.modules.programs.dev.scala = {
let cfg = config.modules.dev.scala;
in {
options.modules.dev.scala = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.shell;
in
{
options.modules.programs.dev.shell = {
let cfg = config.modules.dev.shell;
in {
options.modules.dev.shell = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.dev.zig;
in
{
options.modules.programs.dev.zig = {
let cfg = config.modules.dev.zig;
in {
options.modules.dev.zig = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -0,0 +1,135 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.editors.neovim;
dev = config.modules.dev;
in {
options.modules.editors.neovim = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
(neovim.override {
configure = {
customRC = ''
luafile ~/.config/nvim/init.lua
'';
packages.myPlugins = with pkgs.vimPlugins; {
start = [
(nvim-treesitter.withPlugins (
plugins: with plugins; [
bash
c
cmake
cpp
css
dockerfile
elm
glsl
graphql
haskell
http
html
java
javascript
jsdoc
json
json5
latex
lua
markdown
ninja
nix
org
perl
php
pug
python
regex
rst
ruby
rust
scala
scss
toml
tsx
typescript
vim
yaml
zig
]
))
nvim-treesitter-context
nvim-treesitter-textobjects
nvim-lspconfig
];
};
};
})
] ++
# Install appropriate language servers
(if dev.cc.enable then [
ccls # C/C++
] else []) ++
(if dev.java.enable then [
java-language-server # Java
ltex-ls # LaTeX
] else []) ++
(if dev.lua.enable then [
sumneko-lua-language-server # Lua
] else []) ++
(if dev.node.enable then [
nodePackages.bash-language-server # Bash
nodePackages.dockerfile-language-server-nodejs # Dockerfile
nodePackages.graphql-language-service-cli # GraphQL
nodePackages.purescript-language-server # PureScript
nodePackages.svelte-language-server # Svelte
nodePackages.typescript-language-server # JavaScript/TypeScript
nodePackages.vim-language-server # Vim
nodePackages.vscode-langservers-extracted # HTML, CSS, JSON, ESLint
nodePackages.vue-language-server # Vue.js
nodePackages.yaml-language-server # YAML
] else []) ++
(if dev.python.enable then [
cmake-language-server # CMake
python310Packages.python-lsp-server # Python
] else []) ++
(if dev.rust.enable then [
rust-analyzer # Rust
] else []) ++
(if dev.scala.enable then [
metals # Scala
] else []) ++
(if dev.zig.enable then [
zls # Zig
] else []);
home.configFile = {
"nvim/init.lua".source = ./init.lua;
"nvim/lua" = { source = ./lua; recursive = true; };
"nvim/lua/config/lsp.lua".text = ''
-- This file is autogenerated, do not edit.
${if dev.cc.enable then "require('config.lsp.cc')\n" else ""}
${if dev.java.enable then "require('config.lsp.java')\n" else ""}
${if dev.lua.enable then "require('config.lsp.lua')\n" else ""}
${if dev.node.enable then "require('config.lsp.node')\n" else ""}
${if dev.python.enable then "require('config.lsp.python')\n" else ""}
${if dev.rust.enable then "require('config.lsp.rust')\n" else ""}
${if dev.scala.enable then "require('config.lsp.scala')\n" else ""}
${if dev.zig.enable then "require('config.lsp.zig')\n" else ""}
'';
};
env.EDITOR = "nvim";
environment.shellAliases = {
vim = "nvim";
v = "nvim";
};
};
}

View File

@ -0,0 +1,6 @@
require("config.core")
require("config.keymap")
require("config.treesitter")
require("config.plugins")
require("config.lsp")

View File

@ -0,0 +1,36 @@
local o = vim.opt
local wo = vim.wo
local bo = vim.bo
-- Global dirs
local cachedir = os.getenv("XDG_CACHE_HOME")
o.backupdir = cachedir .. "/nvim/backup/"
o.directory = cachedir .. "/nvim/swap/"
o.undodir = cachedir .. "/nvim/undo/"
-- Global
o.breakindent = true
o.clipboard = "unnamedplus"
o.compatible = false
o.encoding = "utf-8"
o.expandtab = true
o.foldlevel = 99
o.hidden = true
o.hlsearch = false
o.ignorecase = true
o.laststatus = 2
o.listchars = { eol = '', tab = '', trail = '·' }
o.relativenumber = true
o.shiftwidth = 2
o.showmode = false
o.smartcase = true
o.smarttab = true
o.softtabstop = 2
o.synmaxcol = 150
o.tabstop = 4
o.undofile = true
o.wildmenu = true
-- Window
-- Buffer

View File

@ -0,0 +1,35 @@
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
vim.g.mapleader = ","
-- Modes
-- Normal = "n",
-- Insert = "i",
-- Visual = "v",
-- Visual Block = "x",
-- Term = "t",
-- Command = "c"
keymap("n", "<Left>", "<Nop>", opts)
keymap("n", "<Right>", "<Nop>", opts)
keymap("n", "<Up>", "<Nop>", opts)
keymap("n", "<Down>", "<Nop>", opts)
keymap("n", "<C-h>", "<C-w>h", { noremap = true })
keymap("n", "<C-j>", "<C-w>j", { noremap = true })
keymap("n", "<C-k>", "<C-w>k", { noremap = true })
keymap("n", "<C-l>", "<C-w>l", { noremap = true })
keymap("n", "gV", "`[v`]", opts)
keymap("n", ";", ":", { noremap = true })
-- Bubble single lines with vim-unimpaired
keymap("n", "<C-Up>", "[e", opts)
keymap("n", "<C-Down>", "]e", opts)
-- Bubble multiple lines with vim-unimpaired
keymap("v", "<C-Up>", "[egv", opts)
keymap("v", "<C-Down>", "]egv", opts)

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires C/C++
lspconfig.ccls.setup{}

View File

@ -0,0 +1,6 @@
lspconfig = require('lspconfig')
-- Requires Java
lspconfig.java_language_server.setup{}
lspconfig.ltex.setup{}

View File

@ -0,0 +1,22 @@
lspconfig = require('lspconfig')
-- Requires Lua
lspconfig.sumneko_lua.setup {
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = {'vim'},
},
-- Do not send telemetry data containing a randomized but unique identifier
telemetry = {
enable = false,
},
},
},
}

View File

@ -0,0 +1,17 @@
lspconfig = require('lspconfig')
-- Requires Node.js
lspconfig.bashls.setup{}
lspconfig.cssls.setup{}
lspconfig.dockerls.setup{}
lspconfig.eslint.setup{}
lspconfig.graphql.setup{}
lspconfig.html.setup{}
lspconfig.jsonls.setup{}
lspconfig.purescriptls.setup{}
lspconfig.svelte.setup{}
lspconfig.tsserver.setup{}
lspconfig.vimls.setup{}
lspconfig.vuels.setup{}
lspconfig.yamlls.setup{}

View File

@ -0,0 +1,6 @@
lspconfig = require('lspconfig')
-- Requires Python
lspconfig.cmake.setup{}
lspconfig.pylsp.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Rust
lspconfig.rls.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Scala
lspconfig.metals.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Zig
lspconfig.zls.setup{}

View File

@ -0,0 +1,77 @@
local fn = vim.fn
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) > 0 then
PACKER_BOOTSTRAP = fn.system {
"git",
"clone",
"--depth",
"1",
"https://github.com/wbthomason/packer.nvim",
install_path,
}
print "Installing packer close and reopen Neovim..."
vim.cmd [[packadd packer.nvim]]
end
vim.cmd [[
augroup packer_user_config
autocmd!
autocmd BufWritePost plugins.lua source <afile> | PackerSync
augroup end
]]
local status_ok, packer = pcall(require, "packer")
if not status_ok then
return
end
packer.init {
display = {
open_fn = function()
return require("packer.util").float { border = "rounded" }
end,
},
}
return packer.startup(function(use)
-- Utilities
use { "wbthomason/packer.nvim", opt = true }
use { "mbbill/undotree" }
use { "nvim-lua/plenary.nvim" }
use { "tpope/vim-fugitive", event = "User InGitRepo" }
-- Editing
use { "andymass/vim-matchup" }
use { "godlygeek/tabular" }
use { "JoosepAlviste/nvim-ts-context-commentstring" }
use { "kana/vim-textobj-user" }
use { "mg979/vim-visual-multi", branch = "master" }
use { "p00f/nvim-ts-rainbow" }
use { "terryma/vim-expand-region" }
use { "tommcdo/vim-exchange", event = "VimEnter" }
use { "tpope/vim-abolish" }
use { "tpope/vim-commentary", event = "VimEnter" }
use { "tpope/vim-repeat", event = "VimEnter" }
use { "tpope/vim-surround", event = "VimEnter" }
use { "windwp/nvim-autopairs" }
use { "windwp/nvim-ts-autotag" }
-- UI
use { "junegunn/goyo.vim" }
use { "junegunn/limelight.vim" }
use { "markonm/traces.vim" }
-- Searching
use { "nvim-telescope/telescope.nvim", config = [[require('config.telescope')]] }
use { "cljoly/telescope-repo.nvim", requires = "telescope.nvim" }
use { "dyng/ctrlsf.vim" }
-- LSP
use { "jose-elias-alvarez/null-ls.nvim" }
if PACKER_BOOTSTRAP then
require("packer").sync()
end
end)

View File

@ -0,0 +1,46 @@
local status_ok, telescope = pcall(require, "telescope")
if not status_ok then
return
end
local actions = require("telescope.actions")
telescope.setup({
defaults = {
file_ignore_patterns = { ".git/", "node_modules" },
},
mappings = {
i = {
["<Down>"] = actions.cycle_history_next,
["<Up>"] = actions.cycle_history_prev,
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
},
},
extensions = {
repo = {
list = {
fd_opts = {
"--no-ignore-vcs",
},
search_dirs = {
"~/projects",
"~/repos",
"~/workspace",
},
},
},
},
})
telescope.load_extension("repo")
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
keymap("n", "<Leader>ff", "<cmd>Telescope find_files<cr>", opts)
keymap("n", "<Leader>fg", "<cmd>Telescope live_grep<cr>", opts)
keymap("n", "<Leader>fb", "<cmd>Telescope buffers<cr>", opts)
keymap("n", "<Leader>fh", "<cmd>Telescope help_tags<cr>", opts)
keymap("n", "<Leader>fr", "<cmd>Telescope repo list<cr>", opts)

View File

@ -0,0 +1,35 @@
require("nvim-treesitter.configs").setup({
ignore_install = {},
highlight = {
enable = true,
disable = {},
},
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
-- Extensions
autotag = { enable = true },
context_commentstring = { enable = true },
matchup = { enable = true },
rainbow = { enable = true },
textobjects = {
select = {
enable = true,
keymaps = {
["af"] = "@function.outer",
["if"] = "@function.inner",
},
},
},
})
vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"

View File

@ -1,15 +1,8 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.programs.vscode;
in
{
options.modules.programs.vscode = {
let cfg = config.modules.editors.vscode;
in {
options.modules.editors.vscode = {
enable = lib.mkOption {
default = false;
example = true;

View File

@ -1,33 +0,0 @@
{
imports = [
./options.nix
./programs/brave.nix
./programs/dev/cc.nix
./programs/dev/java.nix
./programs/dev/lua.nix
./programs/dev/node.nix
./programs/dev/python.nix
./programs/dev/rust.nix
./programs/dev/scala.nix
./programs/dev/shell.nix
./programs/dev/zig.nix
./programs/emulators.nix
./programs/firefox.nix
./programs/forensics.nix
./programs/git
./programs/gpg.nix
./programs/graphics.nix
./programs/libreoffice.nix
./programs/lutris.nix
./programs/neovim.nix
./programs/pass.nix
./programs/qbittorrent.nix
./programs/recording.nix
./programs/slack.nix
./programs/steam.nix
./programs/thunderbird.nix
./programs/vscode.nix
./programs/zoom.nix
./shell/zsh
];
}

View File

@ -1,137 +0,0 @@
{
config,
options,
lib,
self,
...
}:
with lib;
{
options = with types; {
user = mkOption {
type = attrs;
default = { };
};
home = {
configFile = mkOption {
type = attrs;
default = { };
description = "Files to place in $XDG_CONFIG_HOME";
};
dataFile = mkOption {
type = attrs;
default = { };
description = "Files to place in $XDG_DATA_HOME";
};
file = mkOption {
type = attrs;
default = { };
description = "Files to place directly in $HOME";
};
packages = mkOption {
type = attrs;
default = { };
description = "User-level installed packages";
};
programs = mkOption {
type = attrs;
default = { };
description = "Programs managed directly from home-manager";
};
services = mkOption {
type = attrs;
default = { };
description = "Services managed directly from home-manager";
};
};
dconf.settings = mkOption {
type = attrs;
default = { };
description = "dconf settings to enable";
};
env = mkOption {
type = attrsOf (oneOf [
str
path
(listOf (either str path))
]);
apply = mapAttrs (
n: v: if isList v then concatMapStringsSep ":" (x: toString x) v else (toString v)
);
default = { };
description = "";
};
};
config = {
age.secrets."passwords/users/jordan".file = "${self.inputs.secrets}/passwords/users/jordan.age";
user =
let
user = builtins.getEnv "USER";
name =
if
elem user [
""
"root"
]
then
"jordan"
else
user;
in
{
inherit name;
isNormalUser = true;
extraGroups = [
"audio"
"lxd"
"networkmanager"
"wheel"
];
description = "Jordan Holt";
useDefaultShell = true;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
hashedPasswordFile = config.age.secrets."passwords/users/jordan".path;
home = "/home/${name}";
group = "users";
uid = 1000;
};
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users.${config.user.name} = {
home = {
file = mkAliasDefinitions options.home.file;
stateVersion = config.system.stateVersion;
};
programs = mkAliasDefinitions options.home.programs;
services = mkAliasDefinitions options.home.services;
xdg = {
enable = true;
configFile = mkAliasDefinitions options.home.configFile;
dataFile = mkAliasDefinitions options.home.dataFile;
};
dconf.settings = mkAliasDefinitions options.dconf.settings;
};
sharedModules = [
self.inputs.nixvim.homeManagerModules.nixvim
self.inputs.plasma-manager.homeManagerModules.plasma-manager
];
};
users.users.${config.user.name} = mkAliasDefinitions options.user;
environment.extraInit = concatStringsSep "\n" (
mapAttrsToList (n: v: "export ${n}=\"${v}\"") config.env
);
};
}

View File

@ -1,76 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.programs.emulators;
in
{
options.modules.programs.emulators = {
ds.enable = lib.mkOption {
default = false;
example = true;
};
gb.enable = lib.mkOption {
default = false;
example = true;
};
gba.enable = lib.mkOption {
default = false;
example = true;
};
gamecube.enable = lib.mkOption {
default = false;
example = true;
};
ps1.enable = lib.mkOption {
default = false;
example = true;
};
ps2.enable = lib.mkOption {
default = false;
example = true;
};
ps3.enable = lib.mkOption {
default = false;
example = true;
};
psp.enable = lib.mkOption {
default = false;
example = true;
};
snes.enable = lib.mkOption {
default = false;
example = true;
};
switch.enable = lib.mkOption {
default = false;
example = true;
};
wii.enable = lib.mkOption {
default = false;
example = true;
};
xbox.enable = lib.mkOption {
default = false;
example = true;
};
};
config = {
user.packages = with pkgs; [
(lib.mkIf cfg.ps1.enable duckstation)
(lib.mkIf cfg.ps2.enable unstable.pcsx2)
(lib.mkIf cfg.ps3.enable rpcs3)
(lib.mkIf cfg.psp.enable unstable.ppsspp)
(lib.mkIf cfg.ds.enable desmume)
(lib.mkIf (cfg.gba.enable || cfg.gb.enable || cfg.snes.enable) higan)
(lib.mkIf cfg.switch.enable yuzuPackages.mainline)
(lib.mkIf (cfg.wii.enable || cfg.gamecube.enable) dolphin-emu)
(lib.mkIf cfg.xbox.enable unstable.xemu)
];
};
}

View File

@ -1,33 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.programs.forensics;
in
{
options.modules.programs.forensics = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
acquire
afflib
autopsy
fatcat
foremost
hstsparser
networkminer
sleuthkit
testdisk-qt
tracee
];
};
}

View File

@ -1,44 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.programs.libreoffice;
in
# libreoffice-gtk4 = pkgs.libreoffice.override {
# extraMakeWrapperArgs = [
# "--set SAL_USE_VCLPLUGIN gtk4"
# ];
# unwrapped = pkgs.libreoffice-unwrapped.overrideAttrs (oldAttrs: {
# buildInputs = oldAttrs.buildInputs ++ [
# pkgs.gtk4
# ];
# configureFlags = oldAttrs.configureFlags ++ [
# "--disable-werror"
# "--enable-gtk4"
# ];
# passthru = oldAttrs.passthru // {
# inherit (pkgs) gtk4;
# };
# });
# };
{
options.modules.programs.libreoffice = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
(if config.modules.system.desktop.kde.enable == true then libreoffice-qt else libreoffice)
hunspell
hunspellDicts.en-gb-large
hunspellDicts.en-us-large
];
};
}

View File

@ -1,36 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.programs.lutris;
in
{
options.modules.programs.lutris = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
(lutris.override {
extraPkgs = pkgs: [
winePackages.staging
wine64Packages.staging
];
})
vulkan-loader
vulkan-tools
];
hardware.graphics = {
enable = true;
enable32Bit = true;
};
};
}

View File

@ -1,146 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.modules.programs.neovim;
in
{
options.modules.programs.neovim = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
home.programs.nixvim.config = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
options = {
number = true;
tabstop = 2;
shiftwidth = 2;
expandtab = true;
foldlevel = 99;
splitbelow = true;
splitright = true;
undofile = true;
updatetime = 100;
list = true;
};
globals = {
mapleader = ",";
maplocalleader = ",";
};
clipboard = {
register = "unnamedplus";
providers.wl-copy.enable = true;
};
plugins.comment.enable = true;
plugins.hmts.enable = true;
plugins.lightline.enable = true;
plugins.luasnip.enable = true;
plugins.lsp = {
enable = true;
servers = {
bashls.enable = true;
ccls.enable = true;
cssls.enable = true;
eslint.enable = true;
gopls.enable = true;
html.enable = true;
lua_ls.enable = true;
pylsp.enable = true;
nixd.enable = true;
rust_analyzer = {
enable = true;
installCargo = true;
installRustc = true;
};
ts_ls.enable = true;
};
};
plugins.nvim-autopairs.enable = true;
plugins.cmp = {
enable = true;
autoEnableSources = true;
settings = {
sources = [
{ name = "nvim_lsp"; }
{ name = "path"; }
{ name = "buffer"; }
];
mapping = {
"<Tab>" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})";
"<S-Tab>" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})";
"<CR>" = "cmp.mapping.confirm({ select = true })";
};
};
};
plugins.telescope = {
enable = true;
keymaps = {
"<leader>ff" = "find_files";
"<leader>fg" = "live_grep";
"<leader>b" = "buffers";
"<leader>fh" = "help_tags";
"<C-p>" = "git_files";
"<C-f>" = "live_grep";
};
};
plugins.treesitter = {
enable = true;
nixvimInjections = true;
folding = true;
settings.indent.enable = true;
};
plugins.treesitter-refactor = {
enable = true;
highlightDefinitions = {
enable = true;
clearOnCursorMove = false;
};
};
plugins.undotree.enable = true;
plugins.web-devicons.enable = true;
# plugins.gitsigns.enable = true;
# plugins.gitgutter.enable = true;
# plugins.goyo.enable = true;
# plugins.fugitive.enable = true;
# plugins.fzf-lua.enable = true;
# plugins.neo-tree.enable = true;
# plugins.none-ls.enable = true;
# plugins.nvim-tree.enable = true;
# plugins.oil.enable = true;
# plugins.project-nvim.enable = true;
# plugins.surround.enable = true;
};
env.EDITOR = "nvim";
};
}

View File

@ -1,46 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.programs.recording;
in
{
options.modules.programs.recording = {
audio.enable = lib.mkOption {
default = false;
example = true;
};
video.enable = lib.mkOption {
default = false;
example = true;
};
};
config = {
user.packages =
with pkgs;
(
if cfg.audio.enable then
[
ardour
audacity
]
else
[ ]
)
++ (
if cfg.video.enable then
[
handbrake
mkvtoolnix
obs-studio
]
else
[ ]
);
};
}

View File

@ -1,192 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.shell.zsh;
in
{
options.modules.shell.zsh = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
users.defaultUserShell = pkgs.zsh;
home.programs = {
zsh = {
enable = true;
autocd = true;
autosuggestion = {
enable = true;
strategy = [ "completion" ];
};
defaultKeymap = "viins";
dotDir = ".config/zsh";
enableCompletion = true;
enableVteIntegration = true;
history = {
append = true;
extended = true;
ignoreAllDups = true;
ignoreDups = true;
ignoreSpace = true;
save = 1000000;
size = 1000000;
};
initExtra = ''
## Colors
autoload -U colors && colors
## Directories
setopt AUTO_PUSHD
setopt CDABLE_VARS
setopt PUSHD_IGNORE_DUPS
setopt PUSHD_SILENT
setopt PUSHD_TO_HOME
## Expansion and globbing
setopt EXTENDED_GLOB
unsetopt GLOB_DOTS
unsetopt NOMATCH
## History
setopt BANG_HIST
setopt HIST_VERIFY
setopt INC_APPEND_HISTORY_TIME
## I/O
setopt INTERACTIVE_COMMENTS
setopt MULTIOS
unsetopt CLOBBER
## Jobs
setopt LONG_LIST_JOBS
setopt AUTO_RESUME
unsetopt BG_NICE
unsetopt NOTIFY
unsetopt HUP
unsetopt CHECK_JOBS
## Shell emulation
setopt APPEND_CREATE
## Prompt
PS1="%B%{$fg[magenta]%}%~%{$reset_color%} $%b "
## Vi mode
export KEYTIMEOUT=1
## Zsh line editor
unsetopt BEEP
'';
initExtraBeforeCompInit = ''
setopt HASH_LIST_ALL
'';
localVariables = {
# Prevent zsh-vi-mode overriding other keybinds
ZVM_INIT_MODE = "sourcing";
};
plugins = with pkgs; [
{
name = "zsh-vi-mode";
src = zsh-vi-mode;
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh";
}
{
name = "fast-syntax-highlighting";
src = zsh-fast-syntax-highlighting;
file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh";
}
{
name = "jq-zsh-plugin";
src = jq-zsh-plugin;
file = "share/jq-zsh-plugin/jq.plugin.zsh";
}
{
name = "zsh-autopair";
src = zsh-autopair;
file = "share/zsh/zsh-autopair/autopair.zsh";
}
{
name = "zsh-forgit";
src = zsh-forgit;
file = "share/zsh/zsh-forgit/forgit.plugin.zsh";
}
{
name = "zsh-fzf-tab";
src = zsh-fzf-tab;
file = "share/fzf-tab/fzf-tab.plugin.zsh";
}
];
sessionVariables = {
MODE_INDICATOR = "";
MODE_CURSOR_VIINS = "#b77ee0 blinking bar";
MODE_CURSOR_REPLACE = "$MODE_CURSOR_VIINS #ff3334";
MODE_CURSOR_VICMD = "#b77ee0 block";
MODE_CURSOR_SEARCH = "#e7c547 steady underline";
MODE_CURSOR_VISUAL = "$MODE_CURSOR_VICMD steady bar";
MODE_CURSOR_VLINE = "$MODE_CURSOR_VISUAL #54ced6";
ZVM_LINE_INIT_MODE = "i";
};
shellAliases = {
# Verbose file operations
cp = "cp -iv";
mv = "mv -iv";
rm = "rm -v";
mkdir = "mkdir -v";
# Colorize commands
ls = "ls -h --color=auto --group-directories-first";
# Abbreviations
e = "$EDITOR";
f = "$FILE";
g = "git";
m = "neomutt";
n = "$FILE";
v = "$EDITOR";
};
};
broot.enable = true;
direnv = {
enable = true;
nix-direnv.enable = true;
};
fzf = {
enable = true;
enableZshIntegration = true;
package = pkgs.unstable.fzf;
};
mcfly.enable = true;
navi.enable = true;
nix-index.enable = true;
};
user.packages = with pkgs; [
bat
fd
jq
nix-zsh-completions
nnn
ripgrep
];
};
}

View File

@ -0,0 +1,25 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.networking.tailscale;
in {
options.modules.networking.tailscale = {
enable = lib.mkOption {
default = false;
example = true;
};
restrictSSH = lib.mkOption {
default = true;
example = true;
};
};
config = lib.mkIf cfg.enable {
services.tailscale.enable = true;
services.openssh.openFirewall = !cfg.restrictSSH;
networking.firewall = {
checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ];
allowedUDPPorts = [ config.services.tailscale.port ];
};
};
}

View File

@ -0,0 +1,36 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let cfg = config.modules.networking.wireless;
in {
options.modules.networking.wireless = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Automatically connect to known networks";
};
interfaces = mkOption {
default = [ ]; # All interfaces
example = [ "wlan0" ];
description = mdDoc "Interfaces for `wpa_supplicant` to bind to";
};
};
config = mkIf cfg.enable {
age.secrets."passwords/networks" = {
file = "${inputs.secrets}/passwords/networks.age";
};
networking = {
wireless = {
enable = true;
interfaces = cfg.interfaces;
environmentFile = config.age.secrets.passwords/networks.path;
networks = {
"Apollo 600 Mbps".psk = "@PSK_APOLLO@";
};
};
};
};
}

View File

@ -1,26 +0,0 @@
{
imports = [
./hardware/presonus-studio
./podman.nix
./services/borgmatic.nix
./services/chrony.nix
./services/coturn.nix
./services/gitea.nix
./services/gitea-runner.nix
./services/headscale.nix
./services/home-assistant
./services/mail.nix
./services/matrix.nix
./services/music-assistant.nix
./services/netbird.nix
./services/nginx.nix
./services/photoprism.nix
./services/postgresql.nix
./services/tailscale.nix
./system/desktop/gnome.nix
./system/desktop/hyprland.nix
./system/desktop/kde.nix
./system/desktop/mimeapps.nix
./system/wireless.nix
];
}

View File

@ -1,106 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.hardware.presonus-studio;
snd-usb-audio-module = pkgs.callPackage ./snd-usb-audio.nix {
kernel = config.boot.kernelPackages.kernel;
};
patched = snd-usb-audio-module.overrideAttrs (prev: {
patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ];
});
upmixConfig = {
"stream.properties" = {
"channelmix.upmix" = true;
"channelmix.upmix-method" = "psd";
};
};
in
{
options.modules.hardware.presonus-studio = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
boot.kernelModules = [ "snd-usb-audio" ];
boot.extraModulePackages = [
(patched)
];
# Workaround for mainline module loading instead of patched module
systemd.services.reload-snd-usb-audio = {
description = "Reload snd_usb_audio kernel module";
wantedBy = [ "sound.target" ];
serviceConfig.Type = "oneshot";
path = with pkgs; [
kmod
];
script = ''
# Only reload if device hasn't been initialised
if ! cat /proc/asound/card*/usbmixer | grep -q "Mute Main Out Switch"; then
rmmod snd_usb_audio
insmod /run/booted-system/kernel-modules/lib/modules/$(uname -r)/extra/snd-usb-audio.ko.xz
fi
'';
};
services.pipewire.extraConfig = {
pipewire = {
"10-network" = {
"context.modules" = [
{
"name" = "libpipewire-module-rtp-session";
"args" = {
"stream.props" = {
"node.name" = "rtp-source";
};
};
}
];
};
"surround" = {
"context.modules" = [
{
"name" = "libpipewire-module-loopback";
"args" = {
"node.description" = "Genelec 4.1 Surround";
"capture.props" = {
"node.name" = "Genelec_Speakers";
"media.class" = "Audio/Sink";
"audio.position" = [
"FL"
"FR"
"SL"
"SR"
"LFE"
];
};
"playback.props" = {
"node.name" = "playback.Genelec_Speakers";
"audio.position" = [
"AUX0"
"AUX1"
"AUX3"
"AUX4"
"AUX5"
];
"target.object" = "alsa_output.usb-PreSonus_Studio_1824c_SC4E21110775-00.multichannel-output";
"stream.dont-remix" = true;
"node.passive" = true;
};
};
}
];
};
};
pipewire-pulse."40-upmix" = upmixConfig;
client-rt."40-upmix" = upmixConfig;
};
};
}

View File

@ -1,51 +0,0 @@
{
pkgs,
lib,
config,
...
}:
with lib;
let
cfg = config.modules.podman;
in
{
options.modules.podman = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Enable podman on this host";
};
};
config = mkIf cfg.enable {
virtualisation = {
docker.enable = false;
podman = {
enable = true;
defaultNetwork.settings.dns_enabled = true;
autoPrune = {
enable = true;
dates = "weekly";
flags = [ "--all" ];
};
extraPackages = [ pkgs.zfs ];
};
containers.storage.settings.storage = {
driver = "zfs";
graphroot = "/var/lib/containers/storage";
runroot = "/run/containers/storage";
};
oci-containers.backend = "podman";
};
networking.firewall.interfaces."podman+" = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
};
}

View File

@ -1,72 +0,0 @@
{
config,
lib,
self,
...
}:
let
cfg = config.modules.services.borgmatic;
hostname = config.networking.hostName;
in
{
options.modules.services.borgmatic = {
enable = lib.mkOption {
default = false;
example = true;
description = lib.mdDoc "Enable backups on this host with `borgmatic`";
};
directories = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [
"/home/jordan/Documents"
];
description = lib.mdDoc "List of directories to backup";
};
repoPath = lib.mkOption {
type = lib.types.str;
example = "ssh://example@example.repo.borgbase.com/./repo";
description = lib.mdDoc "Destination borg repository for backup";
};
};
config = lib.mkIf cfg.enable {
age.secrets."passwords/services/borg/${hostname}-passphrase" = {
file = "${self.inputs.secrets}/passwords/services/borg/${hostname}-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = cfg.directories;
repositories = [
{
label = "borgbase";
path = cfg.repoPath;
}
];
encryption_passcommand = "cat ${
config.age.secrets."passwords/services/borg/${hostname}-passphrase".path
}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
services.postgresql.ensureUsers = [
{
name = "root";
ensureClauses.superuser = true;
}
];
# Add `pg_dumpall` to unit environment
systemd.services.borgmatic.path = [ config.services.postgresql.package ];
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
};
}

View File

@ -1,46 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.services.chrony;
in
{
options.modules.services.chrony = {
enable = mkOption {
default = false;
example = true;
description = "Enable chrony NTP deamon";
};
config = mkIf cfg.enable {
services.chrony = {
enable = true;
servers = [
"uk.pool.ntp.org"
"time.cloudflare.com"
];
extraConfig = ''
makestep 1.0 3
bindaddress 0.0.0.0
port 123
allow
'';
};
services.timesyncd.enable = mkForce false;
networking.firewall = {
allowedUDPPorts = [ 123 ];
allowedTCPPorts = [ 123 ];
};
};
};
}

View File

@ -1,135 +0,0 @@
{
config,
lib,
self,
...
}:
let
cfg = config.modules.services.coturn;
in
{
options.modules.services.coturn = {
enable = lib.mkOption {
default = false;
example = true;
};
realm = lib.mkOption {
type = lib.types.str;
description = "The realm to be used by the TURN server.";
example = "turn.vimium.com";
};
matrixIntegration = lib.mkOption {
default = false;
description = "Configure the matrix-synapse module to use this TURN server.";
example = true;
};
};
config = lib.mkIf cfg.enable {
networking.firewall =
let
range =
with config.services.coturn;
lib.singleton {
from = min-port;
to = max-port;
};
in
{
allowedTCPPorts = [
3478 # TURN listener
5349 # STUN TLS
5350 # STUN TLS alt
];
allowedUDPPorts = [
3478 # TURN listener
5349 # TLS
5350 # TLS alt
];
allowedUDPPortRanges = range; # TURN peer relays
};
security.acme.certs = {
"${config.services.coturn.realm}" = {
group = "turnserver";
reloadServices = [ "coturn" ];
};
};
age.secrets =
{
"passwords/services/coturn/static-auth-secret" = {
file = "${self.inputs.secrets}/passwords/services/coturn/static-auth-secret.age";
owner = "turnserver";
group = "turnserver";
};
}
// (
if cfg.matrixIntegration then
{
"passwords/services/coturn/matrix-turn-config.yml" = {
file = "${self.inputs.secrets}/passwords/services/coturn/matrix-turn-config.yml.age";
owner = "matrix-synapse";
group = "matrix-synapse";
};
}
else
{ }
);
services.coturn = rec {
enable = true;
realm = cfg.realm;
use-auth-secret = true;
static-auth-secret-file = config.age.secrets."passwords/services/coturn/static-auth-secret".path;
cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
min-port = 49000;
max-port = 50000;
no-cli = true;
no-tcp-relay = true;
extraConfig = ''
cipher-list="HIGH"
no-multicast-peers
# Ban private CIDR blocks
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
'';
};
services.matrix-synapse = lib.mkIf cfg.matrixIntegration {
settings = with config.services.coturn; {
turn_uris = [
"turn:${realm}:3478?transport=udp"
"turn:${realm}:3478?transport=tcp"
];
turn_user_lifetime = "1h";
};
extraConfigFiles = [
config.age.secrets."passwords/services/coturn/matrix-turn-config.yml".path
];
};
};
}

View File

@ -1,242 +0,0 @@
{
pkgs,
config,
lib,
self,
...
}:
# Based on: https://git.clan.lol/clan/clan-infra/src/branch/main/modules/web01/gitea/actions-runner.nix
with lib;
let
cfg = config.modules.services.gitea-runner;
hostname = config.networking.hostName;
giteaUrl = "https://git.vimium.com";
storeDepsBins = with pkgs; [
coreutils
findutils
gnugrep
gawk
git
nix
nix-update
bash
jq
nodejs
];
storeDeps = pkgs.runCommand "store-deps" { } ''
mkdir -p $out/bin
for dir in ${toString storeDepsBins}; do
for bin in "$dir"/bin/*; do
ln -s "$bin" "$out/bin/$(basename "$bin")"
done
done
# Add SSL CA certs
mkdir -p $out/etc/ssl/certs
cp -a "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" $out/etc/ssl/certs/ca-bundle.crt
'';
in
{
options.modules.services.gitea-runner = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Enable a runner for Gitea Actions on this host";
};
};
config = mkIf cfg.enable {
modules.podman.enable = true;
systemd.services = {
gitea-runner-nix-image = {
wantedBy = [ "multi-user.target" ];
after = [ "podman.service" ];
requires = [ "podman.service" ];
path = [
config.virtualisation.podman.package
pkgs.gnutar
pkgs.shadow
pkgs.getent
];
script = ''
set -eux -o pipefail
mkdir -p etc/nix
# Create an unpriveleged user that we can use also without the run-as-user.sh script
touch etc/passwd etc/group
groupid=$(cut -d: -f3 < <(getent group nix-ci-user))
userid=$(cut -d: -f3 < <(getent passwd nix-ci-user))
groupadd --prefix $(pwd) --gid "$groupid" nix-ci-user
emptypassword='$6$1ero.LwbisiU.h3D$GGmnmECbPotJoPQ5eoSTD6tTjKnSWZcjHoVTkxFLZP17W9hRi/XkmCiAMOfWruUwy8gMjINrBMNODc7cYEo4K.'
useradd --prefix $(pwd) -p "$emptypassword" -m -d /tmp -u "$userid" -g "$groupid" -G nix-ci-user nix-ci-user
cat <<NIX_CONFIG > etc/nix/nix.conf
accept-flake-config = true
experimental-features = nix-command flakes
NIX_CONFIG
cat <<NSSWITCH > etc/nsswitch.conf
passwd: files mymachines systemd
group: files mymachines systemd
shadow: files
hosts: files mymachines dns myhostname
networks: files
ethers: files
services: files
protocols: files
rpc: files
NSSWITCH
# list the content as it will be imported into the container
tar -cv . | tar -tvf -
tar -cv . | podman import - gitea-runner-nix
'';
serviceConfig = {
RuntimeDirectory = "gitea-runner-nix-image";
WorkingDirectory = "/run/gitea-runner-nix-image";
Type = "oneshot";
RemainAfterExit = true;
};
};
gitea-runner-nix = {
after = [ "gitea-runner-nix-image.service" ];
requires = [ "gitea-runner-nix-image.service" ];
serviceConfig = {
# Hardening (may overlap with DynamicUser=)
# The following options are only for optimizing output of systemd-analyze
AmbientCapabilities = "";
CapabilityBoundingSet = "";
# ProtectClock= adds DeviceAllow=char-rtc r
DeviceAllow = "";
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
UMask = "0066";
ProtectProc = "invisible";
SystemCallFilter = [
"~@clock"
"~@cpu-emulation"
"~@module"
"~@mount"
"~@obsolete"
"~@raw-io"
"~@reboot"
"~@swap"
# needed by go?
#"~@resources"
"~@privileged"
"~capset"
"~setdomainname"
"~sethostname"
];
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
"AF_NETLINK"
];
# Needs network access
PrivateNetwork = false;
# Cannot be true due to Node
MemoryDenyWriteExecute = false;
# The more restrictive "pid" option makes `nix` commands in CI emit
# "GC Warning: Couldn't read /proc/stat"
# You may want to set this to "pid" if not using `nix` commands
ProcSubset = "all";
# Coverage programs for compiled code such as `cargo-tarpaulin` disable
# ASLR (address space layout randomization) which requires the
# `personality` syscall
# You may want to set this to `true` if not using coverage tooling on
# compiled code
LockPersonality = false;
# Note that this has some interactions with the User setting; so you may
# want to consult the systemd docs if using both.
DynamicUser = true;
};
};
};
users.users.nix-ci-user = {
group = "nix-ci-user";
description = "Used for running nix-based CI jobs";
home = "/var/empty";
isSystemUser = true;
};
users.groups.nix-ci-user = { };
age.secrets."files/services/gitea-runner/${hostname}-token" = {
file = "${self.inputs.secrets}/files/services/gitea-runner/${hostname}-token.age";
group = "podman";
};
services.gitea-actions-runner.instances = {
act = {
enable = true;
url = giteaUrl;
name = "act-runner-${hostname}";
tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path;
settings = {
cache.enabled = true;
runner.capacity = 4;
};
labels = [
"debian-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest"
"ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest"
];
};
nix = {
enable = true;
url = giteaUrl;
name = "nix-runner-${hostname}";
tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path;
settings = {
cache.enabled = true;
container = {
options = "-e NIX_BUILD_SHELL=/bin/bash -e PAGER=cat -e PATH=/bin -e SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt --device /dev/kvm -v /nix:/nix -v ${storeDeps}/bin:/bin -v ${storeDeps}/etc/ssl:/etc/ssl --user nix-ci-user";
network = "host";
valid_volumes = [
"/nix"
"${storeDeps}/bin"
"${storeDeps}/etc/ssl"
];
};
runner.capacity = 4;
};
labels = [
"nix:docker://gitea-runner-nix"
];
};
};
};
}

View File

@ -1,100 +0,0 @@
{
config,
lib,
pkgs,
self,
...
}:
let
cfg = config.modules.services.gitea;
in
{
options.modules.services.gitea = {
enable = lib.mkEnableOption "gitea";
domain = lib.mkOption {
type = lib.types.string;
default = "git.vimium.com";
};
};
config = lib.mkIf cfg.enable {
users = {
users.git = {
isSystemUser = true;
useDefaultShell = true;
group = "git";
extraGroups = [ "gitea" ];
home = config.services.gitea.stateDir;
};
groups.git = { };
};
services.nginx = {
upstreams.gitea = {
servers = {
"unix:${config.services.gitea.settings.server.HTTP_ADDR}" = { };
};
};
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://gitea";
};
};
};
systemd.tmpfiles.rules = [
"d '${config.services.gitea.customDir}/public/assets/css' 0750 ${config.services.gitea.user} ${config.services.gitea.group} - -"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github.css' - - - - ${self.inputs.gitea-github-theme}/theme-github.css"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github-auto.css' - - - - ${self.inputs.gitea-github-theme}/theme-github-auto.css"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github-dark.css' - - - - ${self.inputs.gitea-github-theme}/theme-github-dark.css"
];
services.gitea = rec {
package = pkgs.unstable.gitea;
enable = true;
user = "git";
appName = "Vimium Git";
stateDir = "/var/lib/gitea";
repositoryRoot = "${stateDir}/repositories";
database = {
type = "sqlite3";
inherit user;
path = "${stateDir}/gitea.db";
};
lfs = {
enable = true;
contentDir = "${stateDir}/lfs";
};
settings = {
server = {
DOMAIN = config.networking.domain;
LANDING_PAGE = "explore";
OFFLINE_MODE = true;
PROTOCOL = "http+unix";
SSH_USER = "git";
SSH_DOMAIN = "${cfg.domain}";
SSH_PORT = lib.head config.services.openssh.ports;
ROOT_URL = "https://${cfg.domain}/";
};
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
log = {
ROOT_PATH = "${stateDir}/log";
"logger.router.MODE" = "";
};
ui = {
THEMES = "gitea,arc-green,github,github-auto,github-dark";
DEFAULT_THEME = "github-dark";
};
actions.ENABLED = true;
indexer = {
REPO_INDEXER_ENABLED = true;
};
packages.CHUNKED_UPLOAD_PATH = lib.mkForce "${stateDir}/data/tmp/package-upload";
};
};
};
}

View File

@ -1,72 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.modules.services.headscale;
fqdn = "headscale.vimium.net";
in
{
options.modules.services.headscale = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.headscale ];
services.headscale = {
enable = true;
port = 8080;
settings = {
policy.path = null;
ip_prefixes = [
"100.64.0.0/10"
];
server_url = "https://${fqdn}";
derp = {
auto_update_enable = false;
update_frequency = "24h";
};
dns = {
base_domain = "mesh.vimium.net";
extra_records = [
{
name = "grafana.mesh.vimium.net";
type = "A";
value = "100.64.0.6";
}
{
name = "home.mesh.vimium.net";
type = "A";
value = "100.64.0.7";
}
];
magic_dns = true;
nameservers.global = [
"9.9.9.9"
];
};
logtail.enabled = false;
};
};
services.nginx.virtualHosts = {
"${fqdn}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.headscale.port}";
proxyWebsockets = true;
};
};
};
};
}

View File

@ -1,315 +0,0 @@
{
config,
lib,
pkgs,
self,
...
}:
let
cfg = config.modules.services.home-assistant;
in
{
imports = [
./floorplan/default.nix
./mqtt.nix
];
options.modules.services.home-assistant.enable = lib.mkEnableOption "home-assistant";
config = lib.mkIf cfg.enable {
age.secrets."files/services/home-assistant/secrets.yaml" = {
file = "${self.inputs.secrets}/files/services/home-assistant/secrets.yaml.age";
path = "${config.services.home-assistant.configDir}/secrets.yaml";
owner = "hass";
group = "hass";
};
services.home-assistant = {
enable = true;
config = {
automation = "!include automations.yaml";
backup = { };
binary_sensor = [ ];
default_config = { };
http = {
server_host = "::1";
trusted_proxies = [ "::1" ];
use_x_forwarded_for = true;
};
ffmpeg = { };
homeassistant = {
name = "Home";
latitude = "!secret latitude";
longitude = "!secret longitude";
country = "GB";
temperature_unit = "C";
time_zone = config.time.timeZone;
unit_system = "metric";
auth_providers = [
{
type = "trusted_networks";
trusted_networks = [
"100.64.0.0/10"
"127.0.0.1"
];
allow_bypass_login = true;
}
{
type = "homeassistant";
}
];
};
logger = {
default = "info";
logs = { };
};
lovelace = {
mode = "yaml";
};
media_player = [ ];
mobile_app = { };
onkyo = { };
open_meteo = { };
recorder = {
purge_keep_days = 365;
};
scene = "!include scenes.yaml";
script = "!include scripts.yaml";
sensor = [ ];
system_health = { };
zeroconf = { };
};
extraComponents = [
"air_quality"
"airly"
"alert"
"api"
"application_credentials"
"asuswrt"
"auth"
"automation"
"bayesian"
"binary_sensor"
# "blackbird"
"blueprint"
"bluetooth_adapters"
"bluetooth_le_tracker"
"button"
"calendar"
"camera"
"cast"
"cert_expiry"
"climate"
"co2signal"
"color_extractor"
"command_line"
"compensation"
"configurator"
"counter"
"cover"
"cpuspeed"
"default_config"
"demo"
"derivative"
"device_automation"
"device_sun_light_trigger"
"device_tracker"
"dlna_dmr"
"dlna_dms"
"dnsip"
"esphome"
"fail2ban"
"fan"
"feedreader"
"ffmpeg"
"file"
"file_upload"
"filesize"
"folder"
"folder_watcher"
"forecast_solar"
"frontend"
"gdacs"
"generic"
"generic_hygrostat"
"generic_thermostat"
"geo_json_events"
"geo_location"
"geo_rss_events"
"github"
"group"
"hardware"
"hdmi_cec"
"history_stats"
"homeassistant"
"homekit"
"homekit_controller"
"html5"
"http"
"humidifier"
"icloud"
"image_processing"
"input_boolean"
"input_button"
"input_datetime"
"input_number"
"input_select"
"input_text"
"integration"
"ios"
"jellyfin"
"light"
"local_calendar"
"local_file"
"local_ip"
"local_todo"
"lock"
"logentries"
"logger"
"lovelace"
"manual"
"manual_mqtt"
"matter"
"media_player"
"min_max"
"mjpeg"
"modern_forms"
"mold_indicator"
"moon"
"mysensors"
"network"
"nmap_tracker"
"notify"
"number"
"onboarding"
"onkyo"
"panel_custom"
"persistent_notification"
"person"
"ping"
"plant"
"prometheus"
"proximity"
"push"
"proximity"
"python_script"
"radio_browser"
"random"
"recorder"
"remote"
"repairs"
"rest"
"rest_command"
"rss_feed_template"
"scene"
"schedule"
"scrape"
"script"
"search"
"season"
"select"
"sense"
"sensor"
"sensorpush"
"shell_command"
"shopping_list"
"siren"
"smtp"
"snmp"
"sql"
"statistics"
"sun"
"switch"
"switch_as_x"
"system_health"
"system_log"
"systemmonitor"
"tag"
"tailscale"
"tcp"
"template"
"text"
"thread"
"threshold"
"time_date"
"timer"
"tod"
"todo"
"tomorrowio"
"trend"
"universal"
"upb"
"update"
"upnp"
"uptime"
"utility_meter"
"vacuum"
"vlc"
"vlc_telnet"
"wake_on_lan"
"water_heater"
"weather"
"websocket_api"
"wled"
"workday"
"worldclock"
"zone"
];
extraPackages =
python3Packages: with python3Packages; [
onkyo-eiscp
zeroconf
];
customComponents = with pkgs; [
home-assistant-browser-mod
];
customLovelaceModules =
(with pkgs.home-assistant-custom-lovelace-modules; [
bubble-card
button-card
card-mod
light-entity-card
mini-graph-card
mini-media-player
mushroom
sankey-chart
universal-remote-card
])
++ (with pkgs; [
lovelace-auto-entities
lovelace-layout-card
lovelace-my-cards
lovelace-simple-weather-card
lovelace-state-switch
lovelace-weather-radar-card
]);
lovelaceConfigWritable = true;
};
modules.services.borgmatic.directories = [
config.services.home-assistant.configDir
];
services.nginx = {
enable = true;
virtualHosts."home.mesh.vimium.net" = {
forceSSL = false;
extraConfig = ''
proxy_buffering off;
'';
locations."/" = {
proxyPass = "http://[::1]:8123";
proxyWebsockets = true;
};
};
};
};
}

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