1 Commits
immich ... vps1

Author SHA1 Message Date
d73239251c Initial vps1 config migration 2023-12-24 13:03:38 +00:00
88 changed files with 1085 additions and 4703 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

@ -9,47 +9,8 @@ System and user configuration for NixOS-based systems.
| **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 .#`

470
flake.lock generated
View File

@ -8,11 +8,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1723293904,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
"lastModified": 1703371241,
"narHash": "sha256-f7ZcabJ5iAH2IRfVuI55xSPZ9TbegFzvFxoKtIPNEn8=",
"owner": "ryantm",
"repo": "agenix",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
"rev": "457669db4259ff69d1ac1183aaa6000420940c1f",
"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": 1722113426,
"narHash": "sha256-Yo/3loq572A8Su6aY5GP56knpuKYRvM2a1meP9oJZCw=",
"owner": "numtide",
"repo": "devshell",
"rev": "67cce7359e4cd3c45296fb4aaf6a19e2a9c757ae",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1727359191,
"narHash": "sha256-5PltTychnExFwzpEnY3WhOywaMV/M6NxYI/y3oXuUtw=",
"owner": "nix-community",
"repo": "disko",
"rev": "67dc29be3036cc888f0b9d4f0a788ee0f6768700",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1723137499,
"narHash": "sha256-MOE9NeU2i6Ws1GhGmppMnjOHkNLl2MQMJmGhaMzdoJM=",
"lastModified": 1703023593,
"narHash": "sha256-M+Cw6vh7xCDmIhyVuEPNmaNVUwpmdFQq8zlsXZTKees=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "fb5b578a4f49ae8705e5fea0419242ed1b8dba70",
"rev": "bad853333d9021e7012adb9b8fbfe7a7003f26bc",
"type": "github"
},
"original": {
@ -152,139 +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": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 57,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/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": 1725234343,
"narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "567b938d64d4b4112ee253b9274472dc3a346eb6",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat_4",
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
],
"nixpkgs-stable": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1724857454,
"narHash": "sha256-Qyl9Q4QMTLZnnBb/8OuQ9LSkzWjBU1T5l5zIzTxkkhk=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "4509ca64f1084e73bc7a721b20c669a8d4c5ebe6",
"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"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -313,86 +123,27 @@
]
},
"locked": {
"lastModified": 1726989464,
"narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=",
"lastModified": 1703367386,
"narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176",
"rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.05",
"ref": "release-23.11",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_3": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1720042825,
"narHash": "sha256-A0vrUB6x82/jvf17qPCpxaM+ulJnD8YZwH9Ci0BsAzE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "e1391fb22e18a36f57e6999c7a9f966dc80ac073",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.05",
"repo": "home-manager",
"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": 1725189302,
"narHash": "sha256-IhXok/kwQqtusPsoguQLCHA+h6gKvgdCrkhIaN+kByA=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "7c4b53a7d9f3a3df902b3fddf2ae245ef20ebcda",
"type": "github"
},
"original": {
"owner": "lnl7",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1727437159,
"narHash": "sha256-v4qLwEw5OmprgQZTT7KZMNU7JjXJzRypw8+Cw6++fWk=",
"lastModified": 1702453208,
"narHash": "sha256-0wRi9SposfE2wHqjuKt8WO2izKB/ASDOV91URunIqgo=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "d830ad47cc992b4a46b342bbc79694cbd0e980b2",
"rev": "7763c6fd1f299cb9361ff2abf755ed9619ef01d6",
"type": "github"
},
"original": {
@ -401,31 +152,6 @@
"type": "github"
}
},
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-24_05": "nixpkgs-24_05",
"utils": "utils_2"
},
"locked": {
"lastModified": 1718084203,
"narHash": "sha256-Cx1xoVfSMv1XDLgKg08CUd1EoTYWB45VmB9XIQzhmzI=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "29916981e7b3b5782dc5085ad18490113f8ff63b",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"ref": "nixos-24.05",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1703013332,
@ -442,36 +168,6 @@
"type": "github"
}
},
"nixpkgs-24_05": {
"locked": {
"lastModified": 1717144377,
"narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "805a384895c696f802a9bf5bf4720f37385df547",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.05",
"type": "indirect"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1727122398,
"narHash": "sha256-o8VBeCWHBxGd4kVMceIayf5GApqTavJbTa44Xcg5Rrk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "30439d93eb8b19861ccbe3e581abf97bdc91b093",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1702272962,
@ -490,85 +186,27 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1727264057,
"narHash": "sha256-KQPI8CTTnB9CrJ7LrmLC4VWbKZfljEPBXOFGZFRpxao=",
"lastModified": 1703068421,
"narHash": "sha256-WSw5Faqlw75McIflnl5v7qVD/B3S2sLh+968bpOGrWA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "759537f06e6999e141588ff1c9be7f3a5c060106",
"rev": "d65bceaee0fb1e64363f7871bc43dc1c6ecad99f",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.05",
"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"
],
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1725350106,
"narHash": "sha256-TaMMlI2KPJ3wCyxJk6AShOLhNuTeabHCnvYRkLBlEFs=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "0f2c31e6a57a83ed4e6fa3adc76749620231055d",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "nixos-24.05",
"repo": "nixvim",
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1727210241,
"narHash": "sha256-lufS6uzSbSrggNCSgubymMQWnQMh7PvQ+lRZ8qH9Uoc=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "a02fef2ece8084aff0b41700bb57d24d73574cd1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"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",
"secrets": "secrets",
"thunderbird-gnome-theme": "thunderbird-gnome-theme"
}
@ -576,11 +214,11 @@
"secrets": {
"flake": false,
"locked": {
"lastModified": 1724093899,
"narHash": "sha256-VohYwTIBq7NEssFibuu+HMXXwuCoLmMOmEwQf7sESSI=",
"lastModified": 1702936962,
"narHash": "sha256-uIZ2uPE26JKJ58463ejHMiAOpqBwflyN6tCmZ89vaSQ=",
"ref": "refs/heads/master",
"rev": "7f5901bb5d6eeaa94d7e1f18f66093be9df014e4",
"revCount": 27,
"rev": "c6db5c3ba8bff0e618fc3e31c9680863c5e53800",
"revCount": 5,
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/nix-secrets.git"
},
@ -619,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": 1721874544,
"narHash": "sha256-BHW9jlx92CsHY84FT0ce5Vxl0KFheLhNn2vndcIf7no=",
"lastModified": 1701889124,
"narHash": "sha256-K+6oh7+J6RDBFkxphY/pzf0B+q5+IY54ZMKZrFSKXlc=",
"owner": "rafaelmardojai",
"repo": "thunderbird-gnome-theme",
"rev": "628fcccb7788e3e0ad34f67114f563c87ac8c1dc",
"rev": "966e9dd54bd2ce9d36d51cd6af8c3bac7a764a68",
"type": "github"
},
"original": {
@ -650,27 +273,6 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1724833132,
"narHash": "sha256-F4djBvyNRAXGusJiNYInqR6zIMI3rvlp6WiKwsRISos=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "3ffd842a5f50f435d3e603312eefa4790db46af5",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
@ -688,24 +290,6 @@
"repo": "flake-utils",
"type": "github"
}
},
"utils_2": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",

149
flake.nix
View File

@ -2,45 +2,18 @@
description = "NixOS system configuration";
inputs = {
nixpkgs.url = "nixpkgs/nixos-24.05";
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.05";
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/nixos-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim/nixos-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
secrets = {
url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git";
flake = false;
@ -51,76 +24,74 @@
};
};
outputs = inputs @ { self, nixpkgs, ... }:
outputs = inputs @ { self, nixpkgs, agenix, deploy-rs, home-manager, nixos-hardware, secrets, ... }:
let
inherit (nixpkgs) lib;
domain = "mesh.vimium.net";
forEverySystem = lib.getAttrs lib.systems.flakeExposed;
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 ]; };
vps1 = nixosSystem { system = "x86_64-linux"; name = "vps1"; };
};
legacyPackages = forEachSystem (system:
lib.packagesFromDirectoryRecursive {
callPackage = nixpkgs.legacyPackages.${system}.callPackage;
directory = ./pkgs;
});
deploy.nodes = {
pi = {
hostname = "10.0.1.191";
sshUser = "jordan";
user = "root";
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}
];
}))
];
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [
inputs.agenix.packages.x86_64-linux.agenix
inputs.deploy-rs.packages.x86_64-linux.deploy-rs
];
profiles.system = {
user = "root";
path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
};
};
vps1 = {
magicRollback = true;
autoRollback = true;
hostname = "vps1.mesh.vimium.net";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.vps1;
};
deploy = {
magicRollback = true;
autoRollback = true;
sshUser = "root";
nodes = lib.genAttrs [
"mail"
# "pi"
# "skycam"
"vps1"
] mkDeployNode;
};
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
# checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
};
}

View File

@ -1,4 +1,4 @@
{ config, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
@ -6,20 +6,21 @@
../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 = {
desktop = {
@ -41,25 +42,15 @@
};
editors = {
neovim.enable = true;
vscode.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://uzu2y5b1@uzu2y5b1.repo.borgbase.com/./repo";
};
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,99 +0,0 @@
{ config, pkgs, self, ... }:
{
imports = [
self.inputs.agenix.nixosModules.age
self.inputs.home-manager.nixosModule
../modules
];
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.nixFlakes;
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,16 +1,33 @@
{ config, 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;
@ -22,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;
@ -45,35 +50,29 @@
randomizedDelaySec = "10min";
};
systemd.services.NetworkManager-wait-online.enable = false;
fonts.packages = with pkgs; [
noto-fonts
(nerdfonts.override { fonts = [ "BigBlueTerminal" "ComicShannsMono" "Terminus" "UbuntuMono" ]; })
];
modules = {
desktop.gnome.enable = true;
networking.tailscale.enable = true;
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="
];
};
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, ... }:
{ 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" = {
@ -46,6 +51,4 @@
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -7,12 +7,11 @@
boot = {
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 @@
{ config, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
@ -6,20 +6,22 @@
../desktop.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.zfsSupport = true;
boot = {
loader.grub = {
enable = true;
device = "/dev/sda";
zfsSupport = true;
};
};
networking.hostName = "helios";
networking.hostId = "47d23505";
networking.networkmanager.enable = true;
networking = {
hostId = "47d23505";
networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
desktop = {
@ -38,20 +40,9 @@
gpg.enable = true;
pass.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://b9cjl9hq@b9cjl9hq.repo.borgbase.com/./repo";
};
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,102 +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,67 +0,0 @@
{ config, lib, self, ... }:
{
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.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";
modules = {
desktop = {
browsers = {
firefox.enable = true;
};
media.recording = {
audio.enable = true;
};
};
dev = {
node.enable = true;
};
editors = {
neovim.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,126 +0,0 @@
{ lib, ... }:
{
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,42 +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;
};
opengl = {
enable = true;
extraPackages = with pkgs; [
libvdpau-va-gl
];
driSupport = true;
driSupport32Bit = true;
};
};
}

View File

@ -1,46 +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,195 +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";
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.opengl = {
enable = true;
extraPackages = with pkgs; [
vaapiVdpau
];
driSupport = true;
};
users.users.jellyfin.extraGroups = [ "video" "render" ];
services.jellyfin = {
enable = true;
cacheDir = "/var/cache/jellyfin";
dataDir = "/var/lib/jellyfin";
};
modules = {
podman.enable = true;
security = {
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,68 +0,0 @@
{ config, lib, pkgs, 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,18 +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,51 +0,0 @@
{ config, 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,22 +0,0 @@
{ config, lib, pkgs, 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,38 +1,41 @@
{ config, ... }:
{ 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 = {
enable = true;
graceful = true;
netbootxyz.enable = true;
};
boot.loader.efi.canTouchEfiVariables = true;
boot.loader = {
systemd-boot = {
enable = true;
graceful = true;
netbootxyz.enable = true;
};
efi.canTouchEfiVariables = true;
};
networking.hostName = "odyssey";
networking.hostId = "c5e68d78";
networking.networkmanager.enable = true;
networking = {
hostId = "c5e68d78";
networkmanager.enable = true;
firewall.trustedInterfaces = [ "lxdbr0" "virbr0" ]; # Work around https://github.com/NixOS/nixpkgs/issues/263359
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
virtualisation = {
libvirtd.enable = true;
lxd.enable = true;
};
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;
@ -49,22 +52,43 @@
};
};
age.secrets."passwords/services/borg/odyssey-passphrase" = {
file = "${inputs.secrets}/passwords/services/borg/odyssey-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = [
"/home/jordan/Documents"
];
repositories = [
{ label = "borgbase"; path = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/odyssey-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
};
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
modules = {
desktop = {
apps.qbittorrent.enable = true;
browsers = {
firefox.enable = true;
};
gaming = {
emulators = {
gamecube.enable = true;
ps2.enable = true;
ps3.enable = true;
psp.enable = true;
wii.enable = true;
xbox.enable = true;
};
lutris.enable = true;
gaming.emulators = {
ps2.enable = true;
psp.enable = true;
};
media.graphics = {
modeling.enable = true;
@ -75,40 +99,21 @@
audio.enable = true;
video.enable = true;
};
office.libreoffice.enable = true;
};
dev = {
node.enable = true;
};
editors = {
neovim.enable = true;
vscode.enable = true;
};
hardware.presonus-studio.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

@ -19,7 +19,6 @@
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = {
modesetting.enable = true;
package = config.boot.kernelPackages.nvidiaPackages.beta;
powerManagement.enable = true;
};
};
@ -65,9 +64,5 @@
networking.useDHCP = lib.mkDefault true;
environment.systemPackages = [
pkgs.apfs-fuse
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

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,13 +1,12 @@
{ config, lib, 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" = {
@ -18,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; [
@ -98,76 +27,48 @@
];
};
networking.hostId = "731d1660";
sound.enable = true;
age.secrets."passwords/networks.age" = {
file = "${inputs.secrets}/passwords/networks.age";
};
networking = {
wireless = {
enable = true;
interfaces = [ "wlan0" ];
environmentFile = config.age.secrets."passwords/networks.age".path;
networks = {
"Apollo 600 Mbps".psk = "@PSK_APOLLO@";
};
};
};
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
systemWide = true;
};
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;
extraComponents = [
"api"
"alert"
"auth"
"backup"
"command_line"
"default_config"
"homekit_controller"
"homekit"
"http"
"icloud"
"jellyfin"
"metoffice"
"mqtt"
"onkyo"
"ping"
"proximity"
"radio_browser"
"scrape"
"sensor"
"system_health"
];
config = {
default_config = {};
backup = {};
homeassistant = {
name = "Home";
latitude = "!secret latitude";
longitude = "!secret longitude";
country = "GB";
temperature_unit = "C";
time_zone = config.time.timeZone;
unit_system = "metric";
};
mqtt = { };
scene = "!include scenes.yaml";
automation = "!include automations.yaml";
system_health = { };
recorder = {
purge_keep_days = 365;
};
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 = [{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
port = 1883;
settings = {
allow_anonymous = true;
@ -176,24 +77,17 @@
};
age.secrets."files/services/zigbee2mqtt/secret.yaml" = {
file = "${self.inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age";
file = "${inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age";
path = "${config.services.zigbee2mqtt.dataDir}/secret.yaml";
owner = "zigbee2mqtt";
group = "zigbee2mqtt";
};
services.zigbee2mqtt = {
package = pkgs.unstable.zigbee2mqtt;
enable = true;
dataDir = "/var/lib/zigbee2mqtt";
settings = {
homeassistant = lib.optionalAttrs config.services.home-assistant.enable {
discovery_topic = "homeassistant";
status_topic = "hass/status";
legacy_entity_attributes = true;
legacy_triggers = true;
};
availability = true;
homeassistant = true;
frontend = true;
device_options = {
retain = true;
@ -206,7 +100,6 @@
network_key = "!secret.yaml network_key";
pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
transmit_power = 20;
};
mqtt = {
version = 5;
@ -215,35 +108,36 @@
};
};
modules = {
networking = {
wireless = {
enable = true;
interfaces = [ "wlan0" ];
age.secrets."passwords/services/borg/pi-passphrase" = {
file = "${inputs.secrets}/passwords/services/borg/pi-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repositories = [
{ label = "borgbase"; path = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/pi-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
};
services = {
borgmatic = {
enable = true;
directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repoPath = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo";
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
};
# Connection to ONKYO HT-R990
networking.interfaces.end0 = {
ipv4.addresses = [{
address = "172.16.0.1";
prefixLength = 30;
}];
};
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
environment.systemPackages = with pkgs; [
python311Packages.onkyo-eiscp
libraspberrypi
raspberrypi-eeprom
];

View File

@ -1,57 +1,48 @@
{ 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";
};
};
environment.systemPackages = with pkgs; [
git
neovim
];
nix = {
settings = {
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
ignoreIP = [
"100.64.0.0/10"
];
};
modules.networking.tailscale = {

View File

@ -1,29 +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,111 +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,33 +0,0 @@
{ config, 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

@ -15,4 +15,3 @@ 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,4 +1,4 @@
{ config, pkgs, lib, ... }:
{ config, lib, pkgs, inputs, ... }:
{
imports = [
@ -6,109 +6,190 @@
../server.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
networking = {
hostId = "08bf6db3";
hostId = "???";
hostName = "vps1";
domain = "mesh.vimium.net";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
8448 # Matrix federation
80 # HTTP
443 # HTTPS
5349 # STUN TLS
5350 # STUN TLS alt
];
allowedUDPPortRanges = [
{ from = 49152; to = 49999; } # TURN relay
];
};
};
users = {
users = {
jellyfin = {
isSystemUser = true;
group = "jellyfin";
shell = "/bin/sh";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaaS+KMAEAymZhIJGC4LK8aMhUzhpmloUgvP2cxeBH4 jellyfin"
];
users.users = {
git = {
isSystemUser = true;
useDefaultShell = true;
group = "git";
extraGroups = [ "gitea" ];
home = config.services.gitea.stateDir;
};
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"
];
};
};
users.groups = {
git = { };
jellyfin = { };
};
age.secrets."passwords/services/borg/vps1-passphrase" = {
file = "${inputs.secrets}/passwords/services/borg/vps1-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = [
"/home"
"/var/lib"
"/var/www"
];
repositories = [
{ label = "borgbase"; path = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/vps1-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
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 = "[::1]:3013";
ldapbindaddress = "[::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://[::1]:3013";
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
};
modules = rec {
databases.postgresql.enable = true;
services = {
borgmatic = {
enable = true;
directories = [
"/home"
"/var/lib"
"/var/www"
];
repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo";
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
age.secrets."passwords/services/coturn/shared-secret" = {
file = "${inputs.secrets}/passwords/services/coturn/shared-secret.age";
};
services.coturn = {
enable = true;
lt-cred-mech = true;
use-auth-secret = true;
static-auth-secret = "???";
realm = "turn.vimium.com";
relay-ips = [
"198.244.190.160"
];
no-tcp-relay = true;
extraConfig = ''
cipher-list="HIGH"
no-loopback-peers
no-multicast-peers
'';
secure-stun = true;
cert = "/var/lib/acme/turn.vimium.com/fullchain.pem";
pkey = "/var/lib/acme/turn.vimium.com/key.pem";
min-port = 49152;
max-port = 49999;
};
services.gitea = rec {
package = pkgs.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 = {
SSH_USER = "git";
SSH_DOMAIN = "git.vimium.com";
SSH_PORT = lib.head config.services.openssh.ports;
OFFLINE_MODE = true;
PROTOCOL = "http+unix";
DOMAIN = config.networking.domain;
ROOT_URL = "https://git.vimium.com/";
};
coturn = {
enable = true;
realm = "turn.vimium.com";
matrixIntegration = true;
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
log.ROOT_PATH = "${stateDir}/log";
ui = {
THEMES = "gitea,arc-green,github-dark,bthree-dark";
DEFAULT_THEME = "github-dark";
};
gitea.enable = true;
headscale.enable = true;
matrix = {
enable = true;
bridges = {
signal = true;
whatsapp = true;
};
usePostgresql = databases.postgresql.enable;
actions.ENABLED = true;
indexer = {
REPO_INDEXER_ENABLED = true;
};
nginx.enable = true;
photoprism.enable = true;
packages.CHUNKED_UPLOAD_PATH = lib.mkForce "${stateDir}/data/tmp/package-upload";
};
};
services.headscale = {
enable = true;
port = 8080;
settings = {
server_url = "https://headscale.vimium.net";
dns_config = {
base_domain = "vimium.net";
};
logtail.enabled = false;
};
};
services.matrix-synapse = {
enable = true;
settings = {
database.name = "sqlite3";
enable_registration = false;
server_name = "vimium.com";
turn_shared_secret = "???";
turn_uris = [
"turn:turn.vimium.com:5349?transport=udp"
"turn:turn.vimium.com:5350?transport=udp"
"turn:turn.vimium.com:5349?transport=tcp"
"turn:turn.vimium.com:5350?transport=tcp"
];
};
};
services.tailscale.enable = true;
networking.firewall = {
checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ];
allowedUDPPorts = [ config.services.tailscale.port ];
};
environment.systemPackages = with pkgs; [
config.services.headscale.package
];
system.stateVersion = "22.11";
}

View File

@ -1,40 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.modules.databases.postgresql;
in {
options.modules.databases.postgresql = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
services.postgresql = {
enable = true;
initdbArgs = [
"--allow-group-access"
"--encoding=UTF8"
"--locale=C"
];
settings = {
log_connections = true;
log_disconnections = true;
log_destination = lib.mkForce "syslog";
};
};
services.borgmatic.settings = {
postgresql_databases = [
{
name = "all";
}
];
};
};
}

View File

@ -1,18 +1,12 @@
{
imports = [
./options.nix
./podman.nix
./databases/postgresql.nix
./desktop/gnome.nix
./desktop/forensics.nix
./desktop/hyprland.nix
./desktop/kde.nix
./desktop/mimeapps.nix
./desktop/apps/qbittorrent.nix
./desktop/apps/slack.nix
./desktop/apps/thunderbird.nix
./desktop/apps/zoom.nix
./desktop/browsers/brave.nix
./desktop/browsers/firefox.nix
./desktop/gaming/emulators.nix
./desktop/gaming/lutris.nix
@ -31,23 +25,9 @@
./dev/zig.nix
./editors/neovim
./editors/vscode.nix
./hardware/presonus-studio.nix
./networking/netbird.nix
./networking/tailscale.nix
./networking/wireless.nix
./security/gpg.nix
./security/pass.nix
./services/borgmatic
./services/chrony
./services/coturn
./services/gitea
./services/gitea-runner
./services/headscale
./services/immich
./services/mail
./services/matrix
./services/nginx
./services/photoprism
./shell/git
./shell/zsh
];

View File

@ -1,4 +1,4 @@
{ config, lib, self, ... }:
{ config, lib, pkgs, inputs, ... }:
let cfg = config.modules.desktop.apps.thunderbird;
in {
@ -10,7 +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,17 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.browsers.brave;
in {
options.modules.desktop.browsers.brave = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
brave
];
};
}

View File

@ -1,4 +1,4 @@
{ config, lib, self, ... }:
{ config, lib, pkgs, inputs, ... }:
let cfg = config.modules.desktop.browsers.firefox;
in {
@ -10,7 +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;
@ -35,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;
@ -154,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" = "";
@ -203,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

@ -1,26 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.forensics;
in {
options.modules.desktop.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

@ -19,10 +19,6 @@ in {
default = false;
example = true;
};
ps1.enable = lib.mkOption {
default = false;
example = true;
};
ps2.enable = lib.mkOption {
default = false;
example = true;
@ -39,36 +35,25 @@ in {
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.ps2.enable pcsx2)
(lib.mkIf cfg.ps3.enable rpcs3)
(lib.mkIf cfg.psp.enable unstable.ppsspp)
(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.switch.enable yuzuPackages.mainline)
(lib.mkIf (cfg.wii.enable ||
cfg.gamecube.enable)
dolphin-emu)
(lib.mkIf cfg.xbox.enable unstable.xemu)
];
};
}

View File

@ -10,13 +10,8 @@ in {
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
(lutris.override {
extraPkgs = pkgs: [
winePackages.staging
wine64Packages.staging
];
})
user.packages = with pkgs; [
lutris
vulkan-loader
vulkan-tools
];

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, self, ... }:
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.gnome;
in {
@ -17,94 +17,31 @@ in {
};
services.flatpak.enable = true;
services.fwupd.enable = true;
programs.dconf.enable = true;
dconf.settings = {
"io/github/celluloid-player/celluloid" = {
draggable-video-area-enable = true;
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
cursor-theme = "Adwaita";
enable-hot-corners = false;
font-name = "Cantarell 11";
gtk-theme = "adw-gtk3-dark";
icon-theme = "MoreWaita";
monospace-font-name = "UbuntuMono Nerd Font 11";
toolbar-style = "both-horiz";
};
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
};
"org/gnome/desktop/sound" = {
theme-name = "freedesktop";
};
"org/gnome/desktop/search-providers" = {
disabled = [ "org.gnome.Epiphany.desktop" ];
};
"org/gnome/desktop/wm/keybindings" = {
switch-group = [ "<Super>grave" ];
switch-group-backward = [ "<Shift><Super>grave" ];
};
"org/gnome/desktop/wm/preferences" = {
button-layout = "appmenu:close";
};
"org/gnome/gnome-session" = {
auto-save-session = true;
};
"org/gnome/gnome-system-monitor" = {
show-dependencies = true;
};
"org/gnome/mutter" = {
center-new-windows = true;
edge-tiling = true;
experimental-features = [ "scale-monitor-framebuffer" ];
};
"org/gnome/settings-daemon/plugins/media-keys" = {
volume-up = [
"<Shift>F12"
"XF86AudioRaiseVolume"
];
volume-down = [
"<Shift>F11"
"XF86AudioLowerVolume"
];
};
"org/gnome/shell" = {
disable-user-extensions = false;
enabled-extensions = [
"appindicatorsupport@rgcjonas.gmail.com"
# "arcmenu@arcmenu.com"
# "another-window-session-manager@gmail.com"
"blur-my-shell@aunetx"
# "browser-tabs@com.github.harshadgavali"
"burn-my-windows@schneegans.github.com"
"clipboard-indicator@tudmotu.com"
"CoverflowAltTab@palatis.blogspot.com"
# "dash-to-panel@jderose9.github.com"
# "desktop-cube@schneegans.github.com"
# "EasyScreenCast@iacopodeenosee.gmail.com"
# "desktop-zoom@colin.kinlo.ch"
"espresso@coadmunkee.github.com"
"flypie@schneegans.github.com"
# "flypie@schneegans.github.com"
# "forge@jmmaranan.com"
"gsconnect@andyholmes.github.io"
# "gSnap@micahosborne"
# "hidetopbar@mathieu.bidon.ca"
"hue-lights@chlumskyvaclav@gmail.com"
"just-perfection-desktop@just-perfection"
# "mediacontrols@cliffniff.github.com"
# "mousefollowsfocus@matthes.biz"
# "pano@elhan.io"
# "paperwm@hedning:matrix.org"
"pip-on-top@rafostar.github.com"
# "rounded-window-corners@yilozt"
# "search-light@icedman.github.com"
# "smart-auto-move@khimaros.com"
"space-bar@luchrioh"
# "smart-auto-move@khimaros.com"
# "systemd-manager@hardpixel.eu"
# "tailscale-status@maxgallup.github.com"
# "tiling-assistant@leleat-on-github"
"tilingshell@ferrarodomenico.com"
"Vitals@CoreCoding.com"
"windowIsReady_Remover@nunofarruca@gmail.com"
# "worksets@blipk.xyz"
# "wsmatrix@martin.zurowietz.de"
];
favorite-apps = [
@ -112,6 +49,9 @@ in {
"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;
};
@ -123,14 +63,8 @@ in {
glide-open-effect = true;
glide-close-effect = true;
};
"org/gnome/shell/extensions/dash-to-panel" = {
intellihide = true;
panel-positions = ''
{"0":"TOP"}
'';
trans-panel-opacity = 0.3;
trans-use-custom-opacity = true;
trans-use-dynamic-opacity = true;
"org/gnome/shell/extensions/desktop-zoom" = {
mag-factor-delta = 0.07;
};
"org/gnome/shell/extensions/espresso" = {
enable-fullscreen = true;
@ -140,32 +74,18 @@ in {
"com.obsproject.Studio.desktop"
];
};
"org/gnome/shell/extensions/flypie" = {
preview-on-right-side = true;
"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/hidetopbar" = {
mouse-sensitive = true;
mouse-sensitive-fullscreen-window = true;
enable-active-window = false;
};
"org/gnome/shell/extensions/just-perfection" = {
activities-button = false;
window-demands-attention-focus = true;
workspace-wrap-around = true;
};
"org/gnome/shell/extensions/paperwm" = {
use-default-background = true;
};
"org/gnome/shell/extensions/pip-on-top" = {
stick = true;
};
"org/gnome/shell/extensions/search-light" = {
popup-at-cursor-monitor = true;
};
"org/gnome/shell/extensions/space-bar/behavior" = {
enable-activate-workspace-shortcuts = true;
show-empty-workspaces = true;
@ -178,15 +98,9 @@ in {
screen-left-gap = 8;
window-gap = 8;
};
"org/gnome/shell/extensions/tilingshell" = {
inner-gaps = 16;
outer-gaps = 8;
enable-blur-snap-assistant = true;
};
"org/gnome/Console" = {
font-scale = 1.4;
use-system-font = false;
custom-font = "ComicShannsMono Nerd Font 10";
"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;
@ -196,92 +110,100 @@ in {
show-hidden = true;
sort-directories-first = true;
};
};
environment.sessionVariables = {
QT_STYLE_OVERRIDE = lib.mkForce "kvantum";
QT_WAYLAND_DECORATION = lib.mkForce "adwaita";
};
home.configFile = {
"Kvantum/kvantum.kvconfig".text = lib.generators.toINI {} {
General.theme = "KvLibadwaitaDark";
"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;
};
"Kvantum/KvLibadwaita".source = "${self.inputs.kvlibadwaita}/src/KvLibadwaita";
};
fonts.packages = with pkgs; [
noto-fonts
ubuntu_font_family
];
user.packages = with pkgs; [
authenticator
# bottles
# bustle
celluloid
# d-spy
# drawing
# fragments
gnome.dconf-editor
gnome.ghex
# gnome-builder
gnome-decoder
gnome-firmware
gnome-frog
# gnome-obfuscate
gnome-podcasts
identity
fragments
mission-center
mousam
newsflash
# schemes
shortwave
sysprof
] ++ (if config.virtualisation.podman.enable then [
pods
] else []);
];
environment.systemPackages = with pkgs.unstable; [
adw-gtk3
kdePackages.qtstyleplugin-kvantum
libsForQt5.qtstyleplugin-kvantum
morewaita-icon-theme
nautilus-python
qadwaitadecorations
qadwaitadecorations-qt6
## Shell extensions
gnomeExtensions.appindicator
gnomeExtensions.arcmenu
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.clipboard-indicator
gnomeExtensions.coverflow-alt-tab
gnomeExtensions.dash-to-panel
gnomeExtensions.desktop-cube
gnomeExtensions.easyScreenCast
gnomeExtensions.desktop-zoom
gnomeExtensions.espresso
gnomeExtensions.fly-pie
gnomeExtensions.forge
gnomeExtensions.gsconnect
gnomeExtensions.gsnap
gnomeExtensions.hide-top-bar
gnome44Extensions."flypie@schneegans.github.com"
# gnomeExtensions.forge
# gnomeExtensions.gsnap
gnomeExtensions.hue-lights
gnomeExtensions.just-perfection
gnomeExtensions.media-controls
gnomeExtensions.mouse-follows-focus
# gnomeExtensions.mutter-primary-gpu
gnomeExtensions.pano
gnomeExtensions.paperwm
gnomeExtensions.pip-on-top
# 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.tiling-shell
gnomeExtensions.todotxt
# gnomeExtensions.todotxt
gnomeExtensions.vitals
gnomeExtensions.window-is-ready-remover
gnomeExtensions.worksets
gnomeExtensions.workspace-matrix
];
# 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.pinentryPackage = pkgs.pinentry-gnome3;
home.services.gpg-agent.pinentryFlavor = "gnome3";
};
}

View File

@ -1,27 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.hyprland;
in {
options.modules.desktop.hyprland = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
programs.hyprland.enable = true;
networking.networkmanager.enable = true;
user.packages = with pkgs; [
mpv
];
environment.systemPackages = with pkgs; [
adw-gtk3
];
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-gnome3;
};
}

View File

@ -1,37 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.kde;
in {
options.modules.desktop.kde = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
services = {
xserver = {
enable = true;
};
desktopManager.plasma6.enable = true;
displayManager.sddm = {
enable = true;
wayland.enable = true;
};
};
networking.networkmanager.enable = true;
user.packages = with pkgs; [
kmail
mpv
];
environment.systemPackages = with pkgs; [
adw-gtk3
];
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-qt;
};
}

View File

@ -1,24 +1,6 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.desktop.office.libreoffice;
# 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;
# };
# });
# };
let cfg = config.modules.desktop.office.libreoffice;
in {
options.modules.desktop.office.libreoffice = {
enable = lib.mkOption {
@ -29,10 +11,7 @@ in {
config = lib.mkIf cfg.enable {
user.packages = with pkgs; [
(if config.modules.desktop.kde.enable == true then libreoffice-qt else libreoffice)
hunspell
hunspellDicts.en-gb-large
hunspellDicts.en-us-large
libreoffice
];
};
}

View File

@ -2,6 +2,7 @@
let
cfg = config.modules.editors.neovim;
dev = config.modules.dev;
in {
options.modules.editors.neovim = {
enable = lib.mkOption {
@ -11,129 +12,124 @@ in {
};
config = lib.mkIf cfg.enable {
home.programs.nixvim = {
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;
};
tsserver.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 })";
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
];
};
};
};
})
] ++
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";
};
};
# 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 []);
plugins.treesitter = {
enable = true;
nixvimInjections = true;
folding = true;
indent = true;
};
plugins.treesitter-refactor = {
enable = true;
highlightDefinitions = {
enable = true;
clearOnCursorMove = false;
};
};
plugins.undotree.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;
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,88 +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,70 +0,0 @@
{ config, lib, self, ... }:
let
cfg = config.modules.networking.netbird;
hostname = config.networking.hostName;
in {
options.modules.networking.netbird = {
enable = lib.mkEnableOption "netbird";
coordinatorDomain = lib.mkOption {
type = lib.types.str;
default = "netbird.vimium.net";
};
meshDomain = lib.mkOption {
type = lib.types.str;
default = "mesh.vimium.net";
};
};
config = lib.mkIf cfg.enable {
age.secrets."passwords/services/netbird/data-store-encryption-key" = {
file = "${self.inputs.secrets}/passwords/services/netbird/data-store-encryption-key.age";
};
services.netbird = {
enable = true;
};
services.netbird.server = {
domain = cfg.coordinatorDomain;
enable = true;
enableNginx = true;
dashboard.settings = {
AUTH_AUTHORITY = "https://auth.vimium.com/oauth2/openid/netbird";
};
management = rec {
disableAnonymousMetrics = true;
dnsDomain = cfg.meshDomain;
oidcConfigEndpoint = "https://auth.vimium.com/oauth2/openid/netbird/.well-known/openid-configuration";
settings = {
DataStoreEncryptionKey = {
_secret = config.age.secrets."passwords/services/netbird/data-store-encryption-key".path;
};
HttpConfig = {
AuthAudience = "netbird";
};
StoreConfig = { Engine = "sqlite"; };
TURNConfig = {
Secret._secret = config.age.secrets."passwords/services/coturn/static-auth-secret".path;
TimeBasedCredentials = true;
};
PKCEAuthorizationFlow.ProviderConfig = {
AuthorizationEndpoint = "https://auth.vimium.com/ui/oauth2";
TokenEndpoint = "https://auth.vimium.com/oauth2/token";
};
};
singleAccountModeDomain = dnsDomain;
turnDomain = config.services.coturn.realm;
turnPort = config.services.coturn.listening-port;
};
};
systemd.services.netbird-signal.serviceConfig.RestartSec = "60";
systemd.services.netbird-management.serviceConfig.RestartSec = "60";
services.nginx.virtualHosts."netbird.vimium.net" = {
enableACME = true;
forceSSL = true;
};
};
}

View File

@ -1,9 +1,6 @@
{ config, lib, pkgs, self, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.networking.tailscale;
headscale = "https://headscale.vimium.net";
hostname = config.networking.hostName;
let cfg = config.modules.networking.tailscale;
in {
options.modules.networking.tailscale = {
enable = lib.mkOption {
@ -17,24 +14,8 @@ in {
};
config = lib.mkIf cfg.enable {
age.secrets."passwords/services/tailscale/${hostname}-authkey" = {
file = "${self.inputs.secrets}/passwords/services/tailscale/${hostname}-authkey.age";
};
environment.systemPackages = [ pkgs.tailscale ];
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."passwords/services/tailscale/${hostname}-authkey".path;
extraUpFlags = [
"--login-server"
headscale
];
};
services.tailscale.enable = true;
services.openssh.openFirewall = !cfg.restrictSSH;
networking.firewall = {
checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ];

View File

@ -1,60 +0,0 @@
{ config, lib, pkgs, self, ... }:
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 = "${self.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@";
};
};
networkmanager.ensureProfiles.profiles = {
"Apollo" = {
connection = {
id = "Apollo 600 Mbps";
type = "wifi";
};
wifi = {
mode = "infrastructure";
ssid = "Apollo 600 Mbps";
};
wifi-security = {
auth-alg = "open";
key-mgmt = "wpa-psk";
psk = "";
};
ipv4 = {
method = "auto";
};
ipv6 = {
addr-gen-mode = "stable-privacy";
method = "auto";
};
};
};
};
};
}

View File

@ -1,4 +1,4 @@
{ config, options, lib, self, ... }:
{ config, options, lib, home-manager, inputs, ... }:
with lib;
{
@ -29,7 +29,7 @@ with lib;
};
config = {
age.secrets."passwords/users/jordan".file = "${self.inputs.secrets}/passwords/users/jordan.age";
age.secrets."passwords/users/jordan".file = "${inputs.secrets}/passwords/users/jordan.age";
user =
let user = builtins.getEnv "USER";
name = if elem user [ "" "root" ] then "jordan" else user;
@ -66,11 +66,6 @@ with lib;
};
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;

View File

@ -1,45 +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,61 +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,41 +0,0 @@
{ config, lib, pkgs, ... }:
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,118 +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,226 +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,93 +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,67 +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 = {
acl_policy_path = null;
ip_prefixes = [
"100.64.0.0/10"
];
server_url = "https://${fqdn}";
derp = {
auto_update_enable = false;
update_frequency = "24h";
urls = [];
};
dns_config = {
base_domain = "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 = [
"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,54 +0,0 @@
{ config, lib, self, ... }:
with lib;
let cfg = config.modules.services.immich;
in {
options.modules.services.immich = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
services.nginx = {
virtualHosts = {
"gallery.vimium.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.immich.port}";
extraConfig = ''
client_max_body_size 50000M;
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_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
'';
};
};
};
};
age.secrets."files/services/immich/envfile" = {
file = "${self.inputs.secrets}/files/services/immich/envfile.age";
};
services.immich = {
enable = true;
secretsFile = config.age.secrets."files/services/immich/envfile".path;
};
};
}

View File

@ -1,74 +0,0 @@
{ config, lib, self, ... }:
let
cfg = config.modules.services.mail;
domains = [
"h0lt.com"
"jdholt.com"
"jordanholt.xyz"
"vimium.co"
"vimium.com"
"vimium.co.uk"
"vimium.info"
"vimium.net"
"vimium.org"
"vimium.xyz"
];
in {
options.modules.services.mail = {
enable = lib.mkOption {
default = false;
example = true;
};
};
imports = [
self.inputs.nixos-mailserver.nixosModule
];
config = lib.mkIf cfg.enable {
services.roundcube = {
enable = true;
hostName = config.mailserver.fqdn;
extraConfig = ''
$config['smtp_server'] = "tls://${config.mailserver.fqdn}";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
'';
plugins = [ "contextmenu" ];
};
services.nginx.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
mailserver = {
enable = true;
fqdn = "mail.vimium.com";
domains = domains;
indexDir = "/var/lib/dovecot/indices";
certificateDomains = [
"imap.vimium.com"
"smtp.vimium.com"
];
certificateScheme = "acme-nginx";
fullTextSearch.enable = true;
loginAccounts = {
"jordan@vimium.com" = {
hashedPasswordFile = config.users.users.jordan.hashedPasswordFile;
catchAll = domains;
};
};
extraVirtualAliases = {
"hostmaster@vimium.com" = "jordan@vimium.com";
"postmaster@vimium.com" = "jordan@vimium.com";
"webmaster@vimium.com" = "jordan@vimium.com";
"abuse@vimium.com" = "jordan@vimium.com";
};
};
};
}

View File

@ -1,253 +0,0 @@
{ config, lib, pkgs, self, ... }:
let
cfg = config.modules.services.matrix;
in {
options.modules.services.matrix = {
enable = lib.mkEnableOption "matrix";
element = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
bridges = {
signal = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Signal bridge.";
};
whatsapp = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable WhatsApp bridge.";
};
};
serverName = lib.mkOption {
type = lib.types.str;
default = "vimium.com";
example = "vimium.com";
};
slidingSync = {
enable = lib.mkEnableOption "sliding-sync";
};
usePostgresql = lib.mkEnableOption "postgresql";
};
config = let
matrixSubdomain = "matrix.${cfg.serverName}";
elementSubdomain = "chat.${cfg.serverName}";
matrixClientConfig = {
"m.homeserver" = {
base_url = "https://${matrixSubdomain}";
server_name = cfg.serverName;
};
"m.identity_server" = {};
"org.matrix.msc3575.proxy" = if cfg.slidingSync.enable then {
"url" = "https://${matrixSubdomain}";
} else { };
};
matrixServerConfig."m.server" = "${matrixSubdomain}:443";
commonBridgeSettings = bridge: {
appservice = {
database = lib.mkIf cfg.usePostgresql {
type = "postgres";
uri = "postgresql:///${bridge}?host=/run/postgresql";
};
};
bridge = {
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"${cfg.serverName}" = "user";
"@jordan:${cfg.serverName}" = "admin";
};
provisioning = {
shared_secret = "disable";
};
};
homeserver = {
address = "https://${matrixSubdomain}";
domain = cfg.serverName;
};
};
in lib.mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
8448 # Matrix federation
];
security.acme.certs = {
"${matrixSubdomain}" = {
reloadServices = [ "matrix-synapse" ];
};
};
services.nginx.virtualHosts = {
"${matrixSubdomain}" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::1]";
port = 443;
ssl = true;
}
{
addr = "[::1]";
port = 80;
}
{
addr = "[::1]";
port = 8448;
ssl = true;
}
];
locations = {
"/" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
'';
};
"/_matrix" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 50M;
'';
};
"/_synapse/client".proxyPass = "http://localhost:8008";
"~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = lib.mkIf cfg.slidingSync.enable {
priority = 100;
proxyPass = "http://localhost:8009";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
'';
};
};
};
"${cfg.serverName}" = let
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in {
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown matrixServerConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown matrixClientConfig);
};
} // (if cfg.element.enable then {
"${elementSubdomain}" = {
forceSSL = true;
enableACME = true;
root = pkgs.unstable.element-web.override {
conf = {
default_server_config = matrixClientConfig;
brand = "Vimium Chat";
branding = {
auth_header_logo_url = "https://vimium.com/images/logo.svg";
auth_footer_links = [
{ "text" = "Vimium.com"; "url" = "https://vimium.com"; }
];
};
};
};
};
} else {});
nixpkgs.config.permittedInsecurePackages = [
"jitsi-meet-1.0.8043"
"olm-3.2.16"
];
services.matrix-synapse = {
enable = true;
enableRegistrationScript = true;
settings = {
database.name = (if cfg.usePostgresql then "psycopg2" else "sqlite3");
enable_metrics = false;
enable_registration = false;
max_upload_size = "100M";
report_stats = false;
server_name = cfg.serverName;
app_service_config_files = (lib.optional cfg.bridges.whatsapp
"/var/lib/mautrix-whatsapp/whatsapp-registration.yaml");
};
};
systemd.services.matrix-synapse.serviceConfig.SupplementaryGroups =
(lib.optional cfg.bridges.whatsapp
config.systemd.services.mautrix-whatsapp.serviceConfig.Group);
age.secrets = if cfg.slidingSync.enable then {
"files/services/matrix/sliding-sync" = {
file = "${self.inputs.secrets}/files/services/matrix/sliding-sync.age";
};
} else {};
services.matrix-sliding-sync = lib.mkIf cfg.slidingSync.enable {
enable = true;
environmentFile = config.age.secrets."files/services/matrix/sliding-sync".path;
settings = { SYNCV3_SERVER = "https://${matrixSubdomain}"; };
};
services.postgresql = lib.mkIf cfg.usePostgresql {
ensureUsers = [
{
name = "matrix-synapse";
ensureDBOwnership = true;
}
] ++ (lib.optional cfg.bridges.signal
{
name = "mautrix-signal";
ensureDBOwnership = true;
})
++ (lib.optional cfg.bridges.whatsapp
{
name = "mautrix-whatsapp";
ensureDBOwnership = true;
});
ensureDatabases = [
"matrix-synapse"
] ++ (lib.optional cfg.bridges.signal
"mautrix-signal")
++ (lib.optional cfg.bridges.whatsapp
"mautrix-whatsapp");
};
services.mautrix-signal = lib.mkIf cfg.bridges.signal {
enable = true;
settings = commonBridgeSettings "mautrix-signal";
};
services.mautrix-whatsapp = lib.mkIf cfg.bridges.whatsapp {
enable = true;
settings = {
bridge = {
history_sync = {
backfill = true;
max_initial_conversations = -1;
message_count = 50;
request_full_sync = true;
};
mute_bridging = true;
};
} // commonBridgeSettings "mautrix-whatsapp";
};
};
}

View File

@ -1,182 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.modules.services.nginx;
nginxErrorPages = ''
location @error_pages {
rewrite ^.*$ /''${status}.html break;
root "/var/www/html/errors";
}
'';
nginxEdgeHeaders = ''
more_set_headers 'Server: Vimium';
more_set_headers 'Access-Control-Allow-Origin: *';
add_header Expect-CT max-age=30 always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Vimium-Responding-Instance $hostname;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options nosniff always;
'';
nginxStrictHeaders = ''
add_header X-Frame-Options SAMEORIGIN always;
add_header Permissions-Policy "fullscreen=(self), sync-xhr=(self)" always;
'';
mkRedirect = from: to: {
"${from}" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.${from}" ];
locations."/".return = "301 https://${to}$request_uri";
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
};
};
in {
options.modules.services.nginx = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
80 # HTTP
443 # HTTPS
];
services.nginx = {
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
sslProtocols = "TLSv1.2 TLSv1.3";
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
appendHttpConfig = ''
error_page 400 @error_pages;
error_page 401 @error_pages;
error_page 403 @error_pages;
error_page 404 @error_pages;
error_page 405 @error_pages;
error_page 429 @error_pages;
error_page 500 @error_pages;
error_page 501 @error_pages;
error_page 502 @error_pages;
error_page 503 @error_pages;
error_page 504 @error_pages;
client_body_buffer_size 16k;
client_header_buffer_size 8k;
'';
appendConfig = ''
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 50000;
'';
eventsConfig = ''
worker_connections 20000;
multi_accept off;
'';
proxyCachePath = {
"skycam" = {
enable = true;
keysZoneName = "skycam_cache";
maxSize = "100m";
};
};
virtualHosts = {
## Static sites
"jellyfin.vimium.com" = {
forceSSL = true;
enableACME = true;
extraConfig = nginxErrorPages + nginxEdgeHeaders;
locations."/" = {
proxyPass = "http://localhost:8000";
extraConfig = ''
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";
'';
};
};
"jdholt.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.jdholt.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/skycam/snapshot.jpg" = {
extraConfig = ''
set $backend "skycam.mesh.vimium.net:8080";
resolver 100.100.100.100;
proxy_pass http://$backend/snapshot;
proxy_cache skycam_cache;
proxy_cache_valid any 10s;
proxy_ignore_headers Cache-Control Expires Set-Cookie;
'';
};
locations."/".return = "301 https://vimium.com$request_uri";
};
"pki.vimium.com" = {
addSSL = true;
forceSSL = false;
enableACME = true;
extraConfig = ''
${nginxErrorPages}
more_set_headers 'Server: Vimium';
'';
locations."/" = {
root = "/var/www/pki.vimium.com";
};
};
"suhailhussain.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.suhailhussain.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/" = {
root = "/var/www/suhailhussain.com";
};
};
"vimium.com" = {
default = true;
forceSSL = true;
enableACME = true;
serverAliases = [ "www.vimium.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders + ''
add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always;
'';
locations."/" = {
root = "/var/www/vimium.com";
};
};
}
## Redirects
// (mkRedirect "h0lt.com" "jdholt.com")
// (mkRedirect "jordanholt.xyz" "jdholt.com")
// (mkRedirect "omnimagic.com" "vimium.com")
// (mkRedirect "omnimagic.net" "vimium.com")
// (mkRedirect "thelostlegend.com" "suhailhussain.com")
// (mkRedirect "vimium.co" "vimium.com")
// (mkRedirect "vimium.co.uk" "vimium.com")
// (mkRedirect "vimium.info" "vimium.com")
// (mkRedirect "vimium.net" "vimium.com")
// (mkRedirect "vimium.org" "vimium.com")
// (mkRedirect "vimium.xyz" "vimium.com");
};
};
}

View File

@ -1,57 +0,0 @@
{ config, lib, pkgs, self, ... }:
with lib;
let cfg = config.modules.services.photoprism;
in {
options.modules.services.photoprism = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
services.nginx = {
virtualHosts = {
"gallery.vimium.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.photoprism.port}";
extraConfig = ''
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_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
};
};
};
age.secrets."passwords/services/photoprism/admin" = {
file = "${self.inputs.secrets}/passwords/services/photoprism/admin.age";
};
services.photoprism = {
enable = true;
address = "localhost";
passwordFile = config.age.secrets."passwords/services/photoprism/admin".path;
originalsPath = "${config.services.photoprism.storagePath}/originals";
settings = {
PHOTOPRISM_APP_NAME = "Vimium Gallery";
PHOTOPRISM_SITE_AUTHOR = "Vimium";
PHOTOPRISM_SITE_TITLE = "Vimium Gallery";
PHOTOPRISM_SITE_CAPTION = "Vimium Gallery";
PHOTOPRISM_DISABLE_TLS = "true";
PHOTOPRISM_SPONSOR = "true";
};
};
};
}

View File

@ -21,7 +21,7 @@ in {
user.packages = with pkgs; [
fd
unstable.fzf
fzf
jq
nix-zsh-completions
nnn

View File

@ -1,25 +0,0 @@
From 625939e594ce255afa3fab3a40c3e524460e1f8b Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 10 Aug 2024 18:28:08 +0100
Subject: [PATCH] Ignore IPA signing
---
src/libcamera/ipa_manager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 6d5bbd05..43004175 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -295,7 +295,7 @@ bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
if (data.empty())
return false;
- bool valid = pubKey_.verify(data, ipa->signature());
+ bool valid = true;
LOG(IPAManager, Debug)
<< "IPA module " << ipa->path() << " signature is "
--
2.44.1

View File

@ -1,142 +0,0 @@
From 57128bb78f56cadf9e2dcca5ba4d710c3bd478a7 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Mon, 5 Aug 2024 21:53:09 +0100
Subject: [PATCH] Remove relative config lookups
---
src/libcamera/ipa_manager.cpp | 16 ----------
src/libcamera/ipa_proxy.cpp | 48 ++----------------------------
src/libcamera/pipeline_handler.cpp | 21 ++-----------
3 files changed, 4 insertions(+), 81 deletions(-)
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index f4e0b633..6d5bbd05 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -131,22 +131,6 @@ IPAManager::IPAManager()
<< "No IPA found in '" << modulePaths << "'";
}
- /*
- * When libcamera is used before it is installed, load IPAs from the
- * same build directory as the libcamera library itself.
- */
- std::string root = utils::libcameraBuildPath();
- if (!root.empty()) {
- std::string ipaBuildPath = root + "src/ipa";
- constexpr int maxDepth = 2;
-
- LOG(IPAManager, Info)
- << "libcamera is not installed. Adding '"
- << ipaBuildPath << "' to the IPA search path";
-
- ipaCount += addDir(ipaBuildPath.c_str(), maxDepth);
- }
-
/* Finally try to load IPAs from the installed system path. */
ipaCount += addDir(IPA_MODULE_DIR);
diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp
index 69975d8f..cd9284a3 100644
--- a/src/libcamera/ipa_proxy.cpp
+++ b/src/libcamera/ipa_proxy.cpp
@@ -122,33 +122,11 @@ std::string IPAProxy::configurationFile(const std::string &name,
}
}
- std::string root = utils::libcameraSourcePath();
- if (!root.empty()) {
- /*
- * When libcamera is used before it is installed, load
- * configuration files from the source directory. The
- * configuration files are then located in the 'data'
- * subdirectory of the corresponding IPA module.
- */
- std::string ipaConfDir = root + "src/ipa/" + ipaName + "/data";
-
- LOG(IPAProxy, Info)
- << "libcamera is not installed. Loading IPA configuration from '"
- << ipaConfDir << "'";
-
- std::string confPath = ipaConfDir + "/" + name;
+ for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) {
+ std::string confPath = dir + "/" + ipaName + "/" + name;
ret = stat(confPath.c_str(), &statbuf);
if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
return confPath;
-
- } else {
- /* Else look in the system locations. */
- for (const auto &dir : utils::split(IPA_CONFIG_DIR, ":")) {
- std::string confPath = dir + "/" + ipaName + "/" + name;
- ret = stat(confPath.c_str(), &statbuf);
- if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
- return confPath;
- }
}
if (fallbackName.empty()) {
@@ -197,28 +175,6 @@ std::string IPAProxy::resolvePath(const std::string &file) const
}
}
- /*
- * When libcamera is used before it is installed, load proxy workers
- * from the same build directory as the libcamera directory itself.
- * This requires identifying the path of the libcamera.so, and
- * referencing a relative path for the proxy workers from that point.
- */
- std::string root = utils::libcameraBuildPath();
- if (!root.empty()) {
- std::string ipaProxyDir = root + "src/libcamera/proxy/worker";
-
- LOG(IPAProxy, Info)
- << "libcamera is not installed. Loading proxy workers from '"
- << ipaProxyDir << "'";
-
- std::string proxyPath = ipaProxyDir + proxyFile;
- if (!access(proxyPath.c_str(), X_OK))
- return proxyPath;
-
- return std::string();
- }
-
- /* Else try finding the exec target from the install directory. */
std::string proxyPath = std::string(IPA_PROXY_DIR) + proxyFile;
if (!access(proxyPath.c_str(), X_OK))
return proxyPath;
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 5ea2ca78..fd8555ca 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -561,25 +561,8 @@ std::string PipelineHandler::configurationFile(const std::string &subdir,
struct stat statbuf;
int ret;
- std::string root = utils::libcameraSourcePath();
- if (!root.empty()) {
- /*
- * When libcamera is used before it is installed, load
- * configuration files from the source directory. The
- * configuration files are then located in the 'data'
- * subdirectory of the corresponding pipeline handler.
- */
- std::string confDir = root + "src/libcamera/pipeline/";
- confPath = confDir + subdir + "/data/" + name;
-
- LOG(Pipeline, Info)
- << "libcamera is not installed. Loading platform configuration file from '"
- << confPath << "'";
- } else {
- /* Else look in the system locations. */
- confPath = std::string(LIBCAMERA_DATA_DIR)
- + "/pipeline/" + subdir + '/' + name;
- }
+ confPath = std::string(LIBCAMERA_DATA_DIR)
+ + "/pipeline/" + subdir + '/' + name;
ret = stat(confPath.c_str(), &statbuf);
if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
--
2.44.1

View File

@ -1,35 +0,0 @@
final: prev:
/*
Generate an overlay from `pkgs` by handling the `callPackage` behaviour
ourselves, making exceptions for namespaced package sets. We cannot reuse
the definitions from `self.legacyPackages.${prev.system}`, as that would
evaluate nixpkgs twice here (prev.system does not exist then).
*/
let
lib = prev.lib;
pkgs = lib.packagesFromDirectoryRecursive {
callPackage = path: overrides: path;
directory = ../pkgs;
};
in
lib.mapAttrs
(name: value:
if lib.isAttrs value then
if lib.hasAttrByPath [ name "overrideScope" ] prev then
# Namespaced package sets created with `lib.makeScope pkgs.newScope`.
prev.${name}.overrideScope (final': prev':
lib.mapAttrs (name': value': final'.callPackage value' { }) value)
else if lib.hasAttrByPath [ name "extend" ] prev then
# Namespaced package sets created with `lib.makeExtensible`.
prev.${name}.extend (final': prev':
lib.mapAttrs (name': value': final.callPackage value' { }) value)
else
# Namespaced package sets in regular attrsets.
prev.${name} // value
else
final.callPackage value { })
pkgs

View File

@ -1,10 +1,10 @@
final: prev:
self: super:
{
gnome = prev.gnome.overrideScope' (gself: gsuper: {
gnome = super.gnome.overrideScope' (gself: gsuper: {
mutter = gsuper.mutter.overrideAttrs (oldAttrs: {
src = prev.fetchurl {
url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-46/mutter-triple-buffering-v4-46.tar.gz";
sha256 = "9MVb53tcOTkcXJ025bF2kX1+fGSfffliA43q00x2c/Y=";
src = super.fetchurl {
url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-45/mutter-triple-buffering-v4-45.tar.gz";
sha256 = "tN+zQ5brk+hc+louIipqPV/Bqft42ghKOzjZZMj5Q8A=";
};
});
});

View File

@ -1,64 +0,0 @@
final: prev:
{
libpisp = final.stdenv.mkDerivation {
name = "libpisp";
version = "1.0.5";
src = final.fetchFromGitHub {
owner = "raspberrypi";
repo = "libpisp";
rev = "v1.0.5";
hash = "sha256-CHd44CH5dBcZuK+5fZtONZ8HE/lwGKwK5U0BYUK8gG4=";
};
nativeBuildInputs = with final; [
pkg-config
meson
ninja
];
buildInputs = with final; [
nlohmann_json
boost
];
BOOST_INCLUDEDIR = "${prev.lib.getDev final.boost}/include";
BOOST_LIBRARYDIR = "${prev.lib.getLib final.boost}/lib";
};
libcamera = prev.libcamera.overrideAttrs (old: {
src = final.fetchFromGitHub {
owner = "raspberrypi";
repo = "libcamera";
rev = "eb00c13d7c9f937732305d47af5b8ccf895e700f";
hash = "sha256-p0/inkHPRUkxSIsTmj7VI7sIaX7OXdqjMGZ31W7cnt4=";
};
postPatch = ''
patchShebangs utils/ src/py/
'';
patches = [
./0001-Remove-relative-config-lookups.patch
./0001-Ignore-IPA-signing.patch
];
buildInputs = old.buildInputs ++ (with final; [
libpisp
libglibutil
]);
mesonFlags = old.mesonFlags ++ [
"--buildtype=release"
"-Dpipelines=rpi/vc4,rpi/pisp"
"-Dipas=rpi/vc4,rpi/pisp"
"-Dgstreamer=enabled"
"-Dtest=false"
"-Dcam=enabled"
"-Dpycamera=disabled"
];
});
camera-streamer = prev.callPackage ../pkgs/camera-streamer/package.nix {
libcamera = final.libcamera;
};
}

View File

@ -1,25 +0,0 @@
From 0f17bb86772afe9495891e420a809a0b3c071caf Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sat, 10 Aug 2024 15:37:15 +0100
Subject: [PATCH] Disable libdatachannel
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index d5029bd..e50ba1a 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ USE_HW_H264 ?= 1
USE_FFMPEG ?= $(shell pkg-config libavutil libavformat libavcodec && echo 1)
USE_LIBCAMERA ?= $(shell pkg-config libcamera && echo 1)
USE_RTSP ?= $(shell pkg-config live555 && echo 1)
-USE_LIBDATACHANNEL ?= $(shell [ -e $(LIBDATACHANNEL_PATH)/CMakeLists.txt ] && echo 1)
+USE_LIBDATACHANNEL ?= 0
ifeq (1,$(DEBUG))
CFLAGS += -g
--
2.44.1

View File

@ -1,78 +0,0 @@
{ stdenv
, fetchFromGitHub
, cmake
, gnumake
, pkg-config
, xxd
, v4l-utils
, nlohmann_json
, ffmpegSupport ? true
, ffmpeg
, libcameraSupport ? true
, libcamera
, rtspSupport ? false
, live555
, webrtcSupport ? false
, openssl
, lib
}:
stdenv.mkDerivation (finalAttrs: {
pname = "camera-streamer";
version = "0.2.8";
src = fetchFromGitHub {
owner = "ayufan";
repo = "camera-streamer";
rev = "refs/tags/v${finalAttrs.version}";
hash = "sha256-8vV8BMFoDeh22I1/qxk6zttJROaD/lrThBxXHZSPpT4=";
fetchSubmodules = true;
};
patches = [
./0001-Disable-libdatachannel.patch
];
# Second replacement fixes literal newline in generated version.h.
postPatch = ''
substituteInPlace Makefile \
--replace '/usr/local/bin' '/bin' \
--replace 'echo "#define' 'echo -e "#define'
'';
env.NIX_CFLAGS_COMPILE = builtins.toString [
"-Wno-error=stringop-overflow"
"-Wno-error=format"
"-Wno-format"
"-Wno-format-security"
"-Wno-error=unused-result"
];
nativeBuildInputs = [
cmake
gnumake
pkg-config
xxd
];
dontUseCmakeConfigure = true;
buildInputs = [ nlohmann_json v4l-utils ]
++ (lib.optional ffmpegSupport ffmpeg)
++ (lib.optional libcameraSupport libcamera)
++ (lib.optional rtspSupport live555)
++ (lib.optional webrtcSupport openssl);
installFlags = [ "DESTDIR=${builtins.placeholder "out"}" ];
preInstall = "mkdir -p $out/bin";
meta = with lib; {
description = "High-performance low-latency camera streamer for Raspberry Pi's";
website = "https://github.com/ayufan/camera-streamer";
license = licenses.gpl3Only;
};
})

View File

@ -1,58 +0,0 @@
{ stdenv
, fetchFromGitHub
, meson
, ninja
, pkg-config
, boost
, ffmpeg
, libcamera
, libdrm
, libexif
, libjpeg
, libpng
, libtiff
, lib
}:
stdenv.mkDerivation (finalAttrs: {
pname = "rpicam-apps";
version = "1.4.1";
src = fetchFromGitHub {
owner = "raspberrypi";
repo = "rpicam-apps";
rev = "v" + finalAttrs.version;
hash = "sha256-3NG2ZE/Ub3lTbfne0LCXuDgLGTPaAAADRdElEbZwvls=";
};
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
boost
ffmpeg
libcamera
libdrm
libexif
libjpeg
libpng
libtiff
];
# Meson is no longer able to pick up Boost automatically:
# https://github.com/NixOS/nixpkgs/issues/86131
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
meta = with lib; {
description = ''
libcamera-based applications to drive the cameras on a Raspberry Pi platform
'';
homepage = "https://github.com/raspberrypi/rpicam-apps";
license = licenses.bsd2;
};
})