3 Commits

Author SHA1 Message Date
a1d4948bb3 Add nerdfonts 2024-03-09 21:35:42 +00:00
5d21d262fa Remove unused variable 2024-03-09 21:17:54 +00:00
1926dda49d Switch to lunarvim 2024-03-03 23:17:42 +00:00
72 changed files with 686 additions and 3940 deletions

View File

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

View File

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

View File

@ -6,50 +6,19 @@ System and user configuration for NixOS-based systems.
|-|-| |-|-|
| **Shell:** | zsh | | **Shell:** | zsh |
| **DE:** | GNOME | | **DE:** | GNOME |
| **Theme:** | Adwaita | | **Theme:** | adwaita |
| **Terminal:** | Ptyxis | | **Terminal:** | Console |
## Provisioning a new host ## Provisioning
> [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used > [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used for provisioning
> 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). 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 Then run;
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 -- \ nix run github:nix-community/nixos-anywhere -- \
--disk-encryption-keys /tmp/secret.key /tmp/secret.key \ --disk-encryption-keys /tmp/secret.key /tmp/secret.key \
--extra-files "$temp" \ --extra-files "$temp" \
--flake .#<hostname> \ --flake .#<hostname> \
root@<target-ip> root@<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>`.

482
flake.lock generated
View File

@ -8,11 +8,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1723293904, "lastModified": 1707830867,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=", "narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41", "rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -21,22 +21,6 @@
"type": "github" "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": { "darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -66,11 +50,11 @@
"utils": "utils" "utils": "utils"
}, },
"locked": { "locked": {
"lastModified": 1727447169, "lastModified": 1708091384,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", "narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
"owner": "serokell", "owner": "serokell",
"repo": "deploy-rs", "repo": "deploy-rs",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", "rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -79,27 +63,6 @@
"type": "github" "type": "github"
} }
}, },
"devshell": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"disko": { "disko": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -107,11 +70,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1735468753, "lastModified": 1709439398,
"narHash": "sha256-2dt1nOe9zf9pDkf5Kn7FUFyPRo581s0n90jxYXJ94l0=", "narHash": "sha256-MW0zp3ta7SvdpjvhVCbtP20ewRwQZX2vRFn14gTc4Kg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "84a5b93637cc16cbfcc61b6e1684d626df61eb21", "rev": "1f76b318aa11170c8ca8c225a9b4c458a5fcbb57",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -123,11 +86,11 @@
"firefox-gnome-theme": { "firefox-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1735511798, "lastModified": 1708965002,
"narHash": "sha256-U9WjPisByrvw8Kt6Ufg9kLrvg7uHPsFSyG93GR3I1iE=", "narHash": "sha256-gIBZCPB0sA8Gagrxd8w4+y9uUkWBnXJBmq9Ur5BYTQU=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "firefox-gnome-theme", "repo": "firefox-gnome-theme",
"rev": "097c98cb4a7568f6f83a43e37950c08b575dd126", "rev": "4e966509c180f93ba8665cd73cad8456bf44baab",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -152,144 +115,6 @@
"type": "github" "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-parts": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": [
"nixvim",
"flake-compat"
],
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
],
"nixpkgs-stable": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1734797603,
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
"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": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -318,114 +143,27 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1735344290, "lastModified": 1706981411,
"narHash": "sha256-oJDtWPH1oJT34RJK1FSWjwX4qcGOBRkcNQPD0EbSfNM=", "narHash": "sha256-cLbLPTL1CDmETVh4p0nQtvoF+FSEjsnJTFpTxhXywhQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "613691f285dad87694c2ba1c9e6298d04736292d", "rev": "652fda4ca6dafeb090943422c34ae9145787af37",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-24.11", "ref": "release-23.11",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
}, },
"home-manager_3": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735344290,
"narHash": "sha256-oJDtWPH1oJT34RJK1FSWjwX4qcGOBRkcNQPD0EbSfNM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "613691f285dad87694c2ba1c9e6298d04736292d",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.11",
"repo": "home-manager",
"type": "github"
}
},
"ixx": {
"inputs": {
"flake-utils": [
"nixvim",
"nuschtosSearch",
"flake-utils"
],
"nixpkgs": [
"nixvim",
"nuschtosSearch",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729958008,
"narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=",
"owner": "NuschtOS",
"repo": "ixx",
"rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"ref": "v0.0.6",
"repo": "ixx",
"type": "github"
}
},
"kvlibadwaita": {
"flake": false,
"locked": {
"lastModified": 1710621848,
"narHash": "sha256-xBl6zmpqTAH5MIT5iNAdW6kdOcB5MY0Dtrb95hdYpwA=",
"owner": "GabePoel",
"repo": "KvLibadwaita",
"rev": "87c1ef9f44ec48855fd09ddab041007277e30e37",
"type": "github"
},
"original": {
"owner": "GabePoel",
"repo": "KvLibadwaita",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735218083,
"narHash": "sha256-MoUAbmXz9TEr7zlKDRO56DBJHe30+7B5X7nhXm+Vpc8=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "bc03f7818771a75716966ce8c23110b715eff2aa",
"type": "github"
},
"original": {
"owner": "lnl7",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1735388221, "lastModified": 1709410583,
"narHash": "sha256-e5IOgjQf0SZcFCEV/gMGrsI0gCJyqOKShBQU0iiM3Kg=", "narHash": "sha256-esOSUoQ7mblwcsSea0K17McZuwAIjoS6dq/4b83+lvw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "7c674c6734f61157e321db595dbfcd8523e04e19", "rev": "59e37017b9ed31dee303dbbd4531c594df95cfbc",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -434,29 +172,6 @@
"type": "github" "type": "github"
} }
}, },
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-24_11": "nixpkgs-24_11"
},
"locked": {
"lastModified": 1735230346,
"narHash": "sha256-zgR8NTiNDPVNrfaiOlB9yHSmCqFDo7Ks2IavaJ2dZo4=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "dc0569066e79ae96184541da6fa28f35a33fbf7b",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1703013332, "lastModified": 1703013332,
@ -473,28 +188,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-24_11": {
"locked": {
"lastModified": 1734083684,
"narHash": "sha256-5fNndbndxSx5d+C/D0p/VF32xDiJCJzyOqorOYW4JEo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "314e12ba369ccdb9b352a4db26ff419f7c49fa84",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.11",
"type": "indirect"
}
},
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1735471104, "lastModified": 1709237383,
"narHash": "sha256-0q9NGQySwDQc7RhAV2ukfnu7Gxa5/ybJ2ANT8DQrQrs=", "narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "88195a94f390381c6afcdaa933c2f6ff93959cb4", "rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -521,109 +221,29 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1735669367, "lastModified": 1709309926,
"narHash": "sha256-tfYRbFhMOnYaM4ippqqid3BaLOXoFNdImrfBfCp4zn0=", "narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "edf04b75c13c2ac0e54df5ec5c543e300f76f1c9", "rev": "79baff8812a0d68e24a836df0a364c678089e2c7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-24.11", "ref": "nixos-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
"nixvim": {
"inputs": {
"devshell": "devshell",
"flake-compat": "flake-compat_3",
"flake-parts": "flake-parts",
"git-hooks": "git-hooks",
"home-manager": "home-manager_3",
"nix-darwin": "nix-darwin",
"nixpkgs": [
"nixpkgs"
],
"nuschtosSearch": "nuschtosSearch",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1735389157,
"narHash": "sha256-3co5A7PUEN+Bm7b3/6BxFsmvplg3XYUNR2MzWnheZoE=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "c8fa65c6ac35dba157de0873d645ab398c370123",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "nixos-24.11",
"repo": "nixvim",
"type": "github"
}
},
"nuschtosSearch": {
"inputs": {
"flake-utils": "flake-utils",
"ixx": "ixx",
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733773348,
"narHash": "sha256-Y47y+LesOCkJaLvj+dI/Oa6FAKj/T9sKVKDXLNsViPw=",
"owner": "NuschtOS",
"repo": "search",
"rev": "3051be7f403bff1d1d380e4612f0c70675b44fc9",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"repo": "search",
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1735049224,
"narHash": "sha256-fWUd9kyXdepphJ7cCzOsuSo7l0kbFCkUqfgKqZyFZzE=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "d16bbded0ae452bc088489e7dca3ef58d8d1830b",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"deploy-rs": "deploy-rs", "deploy-rs": "deploy-rs",
"disko": "disko", "disko": "disko",
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"gitea-github-theme": "gitea-github-theme",
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"kvlibadwaita": "kvlibadwaita",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixos-mailserver": "nixos-mailserver",
"nixpkgs": "nixpkgs_3", "nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim",
"plasma-manager": "plasma-manager",
"secrets": "secrets", "secrets": "secrets",
"thunderbird-gnome-theme": "thunderbird-gnome-theme" "thunderbird-gnome-theme": "thunderbird-gnome-theme"
} }
@ -631,11 +251,11 @@
"secrets": { "secrets": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1730732927, "lastModified": 1709495020,
"narHash": "sha256-t3MTEgi6O7DMxMjdi3xcTAztLDQmEtqQ+oU+ZbWz2AI=", "narHash": "sha256-eiz0qUjUbdeb6m28XPY7OVnrGMZ45JiT2dZZ0Bmq2X0=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "4ae2ac777c38f60a29384b70c456f41847cdf1b5", "rev": "d135b4d6d5f0079999188895f8b5f35e821b0d4b",
"revCount": 28, "revCount": 14,
"type": "git", "type": "git",
"url": "ssh://git@git.vimium.com/jordan/nix-secrets.git" "url": "ssh://git@git.vimium.com/jordan/nix-secrets.git"
}, },
@ -674,29 +294,14 @@
"type": "github" "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": { "thunderbird-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1732643121, "lastModified": 1701889124,
"narHash": "sha256-i0Uo5EN45rlGuR85hvPet43zW/thOQTwHypVg9shTHU=", "narHash": "sha256-K+6oh7+J6RDBFkxphY/pzf0B+q5+IY54ZMKZrFSKXlc=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "thunderbird-gnome-theme", "repo": "thunderbird-gnome-theme",
"rev": "1994e7ec0649053e2a0811973245758d41e33f5f", "rev": "966e9dd54bd2ce9d36d51cd6af8c3bac7a764a68",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -705,27 +310,6 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735135567,
"narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": { "utils": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"

143
flake.nix
View File

@ -2,7 +2,7 @@
description = "NixOS system configuration"; description = "NixOS system configuration";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-24.11"; nixpkgs.url = "nixpkgs/nixos-23.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs"; # nixpkgs-master.url = "nixpkgs";
agenix.url = "github:ryantm/agenix"; agenix.url = "github:ryantm/agenix";
@ -12,35 +12,14 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-24.11"; url = "github:nix-community/home-manager/release-23.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
firefox-gnome-theme = { firefox-gnome-theme = {
url = "github:rafaelmardojai/firefox-gnome-theme"; url = "github:rafaelmardojai/firefox-gnome-theme";
flake = false; 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-hardware.url = "github:NixOS/nixos-hardware";
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim/nixos-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
secrets = { secrets = {
url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git"; url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git";
flake = false; flake = false;
@ -51,60 +30,62 @@
}; };
}; };
outputs = inputs @ { self, nixpkgs, ... }: outputs = inputs @ { self, nixpkgs, nixpkgs-unstable, agenix, deploy-rs, disko, home-manager, nixos-hardware, secrets, ... }:
let let
inherit (nixpkgs) lib; mkPkgsForSystem = system: inputs.nixpkgs;
overlays = [
domain = "mesh.vimium.net"; agenix.overlays.default
forEverySystem = lib.getAttrs lib.systems.flakeExposed; (import ./overlays/gnome.nix)
forEachSystem = lib.genAttrs [ (
"x86_64-linux" final: prev: {
"aarch64-linux" unstable = import inputs.nixpkgs-unstable { system = final.system; };
custom = self.packages { system = final.system; };
}
)
]; ];
mkDeployNode = hostName: { commonModules = [
hostname = "${hostName}.${domain}"; agenix.nixosModules.age
disko.nixosModules.disko
profiles.system = { home-manager.nixosModule
user = "root"; ./modules
path = inputs.deploy-rs.lib.${self.nixosConfigurations.${hostName}.config.system.build.toplevel.system}.activate.nixos self.nixosConfigurations.${hostName}; ];
mkNixosSystem = { system, name, extraModules ? [] }:
let
nixpkgs = mkPkgsForSystem 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;
})
./hosts/${name}
] ++ extraModules;
}; };
};
in in
{ {
overlays = lib.packagesFromDirectoryRecursive { nixosConfigurations = {
callPackage = path: overrides: import path; atlas = mkNixosSystem { system = "x86_64-linux"; name = "atlas"; };
directory = ./overlays; eos = mkNixosSystem { system = "x86_64-linux"; name = "eos"; };
helios = mkNixosSystem { system = "x86_64-linux"; name = "helios"; };
hypnos = mkNixosSystem { system = "x86_64-linux"; name = "hypnos"; };
library = mkNixosSystem { system = "x86_64-linux"; name = "library"; };
odyssey = mkNixosSystem { system = "x86_64-linux"; name = "odyssey"; };
pi = mkNixosSystem { system = "aarch64-linux"; name = "pi"; extraModules = [ nixos-hardware.nixosModules.raspberry-pi-4 ]; };
vps1 = mkNixosSystem { system = "x86_64-linux"; name = "vps1"; };
}; };
legacyPackages = forEachSystem (system:
lib.packagesFromDirectoryRecursive {
callPackage = nixpkgs.legacyPackages.${system}.callPackage;
directory = ./pkgs;
});
nixosConfigurations = lib.pipe ./hosts [
builtins.readDir
(lib.filterAttrs (name: value: value == "directory"))
(lib.mapAttrs (name: value:
lib.nixosSystem {
specialArgs = { inherit self; };
modules = [
{
networking = {
inherit domain;
hostName = name;
};
}
./hosts/${name}
];
}))
];
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell { devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [ buildInputs = [
inputs.agenix.packages.x86_64-linux.agenix deploy-rs.packages.x86_64-linux.deploy-rs
inputs.deploy-rs.packages.x86_64-linux.deploy-rs
]; ];
}; };
@ -112,15 +93,27 @@
magicRollback = true; magicRollback = true;
autoRollback = true; autoRollback = true;
sshUser = "root"; sshUser = "root";
nodes = lib.genAttrs [ nodes = {
"mail" vps1 = {
# "pi" hostname = "vps1.mesh.vimium.net";
# "skycam"
"vps1" profiles.system = {
] mkDeployNode; user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.vps1;
};
};
# pi = {
# hostname = "10.0.1.191";
#
# profiles.system = {
# user = "root";
# path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
# };
# };
};
}; };
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 = [ imports = [
@ -6,8 +6,6 @@
../desktop.nix ../desktop.nix
]; ];
nixpkgs.hostPlatform = "x86_64-linux";
boot.loader = { boot.loader = {
systemd-boot.enable = true; systemd-boot.enable = true;
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
@ -18,9 +16,6 @@
networkmanager.enable = true; networkmanager.enable = true;
}; };
virtualisation.virtualbox.host.enable = true;
users.extraGroups.vboxusers.members = [ "jordan" ];
modules = { modules = {
desktop = { desktop = {
apps = { apps = {
@ -41,6 +36,7 @@
}; };
editors = { editors = {
neovim.enable = true; neovim.enable = true;
vscode.enable = true;
}; };
security = { security = {
gpg.enable = true; gpg.enable = true;

View File

@ -1,22 +1,6 @@
{ config, pkgs, self, ... }: { config, lib, pkgs, ... }:
{ {
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"; time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8"; i18n.defaultLocale = "en_GB.UTF-8";
@ -31,7 +15,7 @@
LC_TELEPHONE = "en_GB.UTF-8"; LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8"; LC_TIME = "en_GB.UTF-8";
}; };
console.keyMap = "uk"; console.keyMap = "uk";
security.sudo.execWheelOnly = true; security.sudo.execWheelOnly = true;
@ -54,28 +38,17 @@
programs.zsh.enable = true; programs.zsh.enable = true;
nix = { nix = {
package = pkgs.nixVersions.stable; package = pkgs.nixFlakes;
extraOptions = '' extraOptions = ''
experimental-features = nix-command flakes 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 = { settings = {
connect-timeout = 5; connect-timeout = 5;
log-lines = 25; log-lines = 25;
min-free = 128000000; min-free = 128000000;
max-free = 1000000000; max-free = 1000000000;
fallback = true; fallback = true;
trusted-users = [ "@wheel" ]; allowed-users = [ "@wheel" ];
auto-optimise-store = true; auto-optimise-store = true;
substituters = [ substituters = [
"http://odyssey.mesh.vimium.net" "http://odyssey.mesh.vimium.net"

View File

@ -1,17 +1,14 @@
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
./common.nix ./common.nix
]; ];
nixpkgs.overlays = [ services.printing.enable = true;
(import ../overlays/gnome.nix)
];
services.printing.enable = false;
services.openssh.startWhenNeeded = true; services.openssh.startWhenNeeded = true;
sound.enable = true;
hardware.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
@ -24,18 +21,7 @@
fileSystems."/mnt/library" = { fileSystems."/mnt/library" = {
device = "library.mesh.vimium.net:/mnt/library"; device = "library.mesh.vimium.net:/mnt/library";
fsType = "nfs"; fsType = "nfs";
options = [ options = [ "nfsvers=4.2" "soft" "nocto" "ro" "x-systemd.automount" "noauto" ];
"nfsvers=4.2"
"bg"
"soft"
"timeo=20"
"retry=5"
"nocto"
"ro"
"x-systemd.automount"
"x-systemd.requires=tailscaled.service"
"noauto"
];
}; };
system.autoUpgrade = { system.autoUpgrade = {
@ -44,35 +30,8 @@
randomizedDelaySec = "10min"; randomizedDelaySec = "10min";
}; };
systemd.services.NetworkManager-wait-online.enable = false;
fonts.packages = with pkgs; [
noto-fonts
(nerdfonts.override { fonts = [ "BigBlueTerminal" "ComicShannsMono" "Terminus" "UbuntuMono" ]; })
];
modules = { modules = {
desktop.gnome.enable = true; desktop.gnome.enable = true;
networking.tailscale.enable = true; networking.tailscale.enable = true;
}; };
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";
} }

View File

@ -1,4 +1,4 @@
{ config, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
@ -6,8 +6,6 @@
../desktop.nix ../desktop.nix
]; ];
nixpkgs.hostPlatform = "x86_64-linux";
boot.loader = { boot.loader = {
systemd-boot.enable = true; systemd-boot.enable = true;
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;

View File

@ -7,12 +7,11 @@
boot = { boot = {
initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ]; initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
initrd.kernelModules = [ ];
initrd.supportedFilesystems = [ "zfs" ]; initrd.supportedFilesystems = [ "zfs" ];
kernel.sysctl = { kernelModules = [ ];
"kernel.nmi_watchdog" = 0;
"vm.laptop_mode" = 5;
};
kernelParams = [ "elevator=none" ]; kernelParams = [ "elevator=none" ];
extraModulePackages = [ ];
supportedFilesystems = [ "zfs" ]; supportedFilesystems = [ "zfs" ];
}; };

View File

@ -1,4 +1,4 @@
{ config, ... }: { config, lib, pkgs, inputs, ... }:
{ {
imports = [ imports = [
@ -6,8 +6,6 @@
../desktop.nix ../desktop.nix
]; ];
nixpkgs.hostPlatform = "x86_64-linux";
boot = { boot = {
loader.grub = { loader.grub = {
enable = true; enable = true;

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,21 +1,12 @@
{ config, lib, self, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
self.inputs.disko.nixosModules.disko
./hardware-configuration.nix ./hardware-configuration.nix
./disko-config.nix ./disko-config.nix
../desktop.nix ../desktop.nix
]; ];
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};
boot.loader = { boot.loader = {
systemd-boot.enable = true; systemd-boot.enable = true;
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
@ -23,21 +14,6 @@
networking.hostId = "cf791898"; 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 = { modules = {
desktop = { desktop = {
browsers = { browsers = {

View File

@ -7,15 +7,9 @@
boot = { boot = {
initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
kernel.sysctl = { initrd.kernelModules = [ ];
"kernel.nmi_watchdog" = 0;
"vm.laptop_mode" = 5;
};
kernelModules = [ "applesmc" "kvm-intel" "wl" ]; kernelModules = [ "applesmc" "kvm-intel" "wl" ];
extraModulePackages = [ extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
config.boot.kernelPackages.broadcom_sta
config.boot.kernelPackages.nvidiaPackages.legacy_470
];
}; };
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
@ -25,17 +19,9 @@
hardware = { hardware = {
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = { nvidia = {
package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
modesetting.enable = true; modesetting.enable = true;
powerManagement.enable = true; powerManagement.enable = true;
}; };
graphics = {
enable = true;
extraPackages = with pkgs; [
libvdpau-va-gl
];
enable32Bit = true;
};
}; };
} }

View File

@ -1,13 +1,12 @@
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
with lib.my;
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../server.nix ../server.nix
]; ];
nixpkgs.hostPlatform = "x86_64-linux";
boot = { boot = {
loader.systemd-boot.enable = true; loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true; loader.efi.canTouchEfiVariables = true;
@ -15,13 +14,19 @@
}; };
networking = { networking = {
domain = "mesh.vimium.net";
hostId = "d24ae953"; hostId = "d24ae953";
firewall = { firewall = {
enable = true; enable = true;
allowedTCPPorts = [ allowedTCPPorts = [
22 # SSH 22 # SSH
]; ];
interfaces."podman+" = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
}; };
networkmanager.enable = true;
}; };
services.zfs = { services.zfs = {
@ -43,17 +48,6 @@
enable = true; enable = true;
}; };
services.grafana = {
enable = true;
settings = {
server = {
domain = "library.mesh.vimium.net";
http_addr = "0.0.0.0";
http_port = 3000;
};
};
};
services.prometheus = { services.prometheus = {
enable = true; enable = true;
port = 9001; port = 9001;
@ -70,7 +64,7 @@
}; };
scrapeConfigs = [ scrapeConfigs = [
{ {
job_name = "node"; job_name = "library";
static_configs = [{ static_configs = [{
targets = [ targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}" "127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
@ -156,22 +150,9 @@
}; };
}; };
hardware.graphics = { services.jellyfin.enable = true;
enable = true;
extraPackages = with pkgs; [
vaapiVdpau
];
};
users.users.jellyfin.extraGroups = [ "video" "render" ];
services.jellyfin = {
enable = true;
package = pkgs.unstable.jellyfin;
cacheDir = "/var/cache/jellyfin";
dataDir = "/var/lib/jellyfin";
};
modules = { modules = {
podman.enable = true;
security = { security = {
gpg.enable = true; gpg.enable = true;
}; };
@ -182,7 +163,6 @@
borgmatic = { borgmatic = {
enable = true; enable = true;
directories = [ directories = [
config.services.jellyfin.dataDir
"/home/jordan" "/home/jordan"
]; ];
repoPath = "ssh://b61758r4@b61758r4.repo.borgbase.com/./repo"; repoPath = "ssh://b61758r4@b61758r4.repo.borgbase.com/./repo";

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;
}

View File

@ -1,4 +1,4 @@
{ config, ... }: { config, lib, pkgs, inputs, ... }:
{ {
imports = [ imports = [
@ -6,14 +6,6 @@
../desktop.nix ../desktop.nix
]; ];
nixpkgs = {
hostPlatform = "x86_64-linux";
config = {
allowUnfree = true;
nvidia.acceptLicense = true;
};
};
boot.loader = { boot.loader = {
systemd-boot = { systemd-boot = {
enable = true; enable = true;
@ -55,16 +47,13 @@
browsers = { browsers = {
firefox.enable = true; firefox.enable = true;
}; };
gaming = { gaming.emulators = {
emulators = { gamecube.enable = true;
gamecube.enable = true; ps2.enable = true;
ps2.enable = true; ps3.enable = true;
ps3.enable = true; psp.enable = true;
psp.enable = true; wii.enable = true;
wii.enable = true; xbox.enable = true;
xbox.enable = true;
};
lutris.enable = true;
}; };
media.graphics = { media.graphics = {
modeling.enable = true; modeling.enable = true;
@ -75,13 +64,13 @@
audio.enable = true; audio.enable = true;
video.enable = true; video.enable = true;
}; };
office.libreoffice.enable = true;
}; };
dev = { dev = {
node.enable = true; node.enable = true;
}; };
editors = { editors = {
neovim.enable = true; neovim.enable = true;
vscode.enable = true;
}; };
hardware.presonus-studio.enable = true; hardware.presonus-studio.enable = true;
security = { security = {
@ -93,16 +82,9 @@
enable = true; enable = true;
directories = [ directories = [
"/home/jordan/Documents" "/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"; repoPath = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo";
}; };
gitea-runner.enable = true;
}; };
shell = { shell = {
git.enable = true; git.enable = true;

View File

@ -19,8 +19,6 @@
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
nvidia = { nvidia = {
modesetting.enable = true; modesetting.enable = true;
open = true;
package = config.boot.kernelPackages.nvidiaPackages.beta;
powerManagement.enable = true; powerManagement.enable = true;
}; };
}; };

View File

@ -1,13 +1,12 @@
{ config, lib, pkgs, self, ... }: { config, lib, pkgs, inputs, ... }:
{ {
imports = [ imports = [
self.inputs.nixos-hardware.nixosModules.raspberry-pi-4
./hardware-configuration.nix ./hardware-configuration.nix
../server.nix ../server.nix
]; ];
nixpkgs.hostPlatform = "aarch64-linux"; networking.hostId = "731d1660";
hardware = { hardware = {
raspberry-pi."4" = { raspberry-pi."4" = {
@ -98,7 +97,7 @@
]; ];
}; };
networking.hostId = "731d1660"; sound.enable = true;
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
@ -108,6 +107,111 @@
pulse.enable = true; pulse.enable = true;
}; };
age.secrets."files/services/home-assistant/secrets.yaml" = {
file = "${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;
};
};
};
services.mosquitto = {
enable = true;
listeners = [{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
port = 1883;
settings = {
allow_anonymous = true;
};
}];
};
age.secrets."files/services/zigbee2mqtt/secret.yaml" = {
file = "${inputs.secrets}/files/services/zigbee2mqtt/secret.yaml.age";
path = "${config.services.zigbee2mqtt.dataDir}/secret.yaml";
owner = "zigbee2mqtt";
group = "zigbee2mqtt";
};
services.zigbee2mqtt = {
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;
frontend = true;
device_options = {
retain = true;
};
serial = {
port = "/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0";
};
advanced = {
channel = 20;
network_key = "!secret.yaml network_key";
pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
transmit_power = 20;
};
mqtt = {
version = 5;
server = "mqtt://localhost:1883";
};
};
};
modules = { modules = {
networking = { networking = {
wireless = { wireless = {
@ -118,9 +222,12 @@
services = { services = {
borgmatic = { borgmatic = {
enable = true; enable = true;
directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repoPath = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo"; repoPath = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo";
}; };
home-assistant.enable = true;
}; };
}; };

View File

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

View File

@ -7,51 +7,15 @@
documentation.enable = false; documentation.enable = false;
fonts.fontconfig.enable = false;
security = { security = {
acme = { acme.acceptTerms = true;
acceptTerms = true; auditd.enable = true;
defaults = { audit = {
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 = {
enable = true;
bantime = "1h";
bantime-increment = {
enable = true; enable = true;
maxtime = "24h"; rules = [
rndtime = "7m"; "-a exit,always -F arch=b64 -S execve"
];
}; };
ignoreIP = [
"100.64.0.0/10"
];
}; };
modules.networking.tailscale = { 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

@ -1,4 +1,4 @@
{ config, pkgs, lib, ... }: { config, lib, pkgs, inputs, ... }:
{ {
imports = [ imports = [
@ -6,10 +6,9 @@
../server.nix ../server.nix
]; ];
nixpkgs.hostPlatform = "x86_64-linux";
networking = { networking = {
hostId = "08bf6db3"; hostId = "08bf6db3";
domain = "mesh.vimium.net";
firewall = { firewall = {
enable = true; enable = true;
allowedTCPPorts = [ allowedTCPPorts = [
@ -37,49 +36,17 @@
groups = { groups = {
jellyfin = { }; jellyfin = { };
}; };
extraGroups.acme.members = [ "kanidm" "nginx" ];
}; };
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password"; services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
security.acme.certs."auth.vimium.com" = { security.acme.defaults = {
postRun = "systemctl restart kanidm.service"; email = "hostmaster@vimium.com";
group = "acme"; group = "nginx";
webroot = "/var/lib/acme/acme-challenge";
}; };
services.kanidm = let modules = {
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";
};
};
};
modules = rec {
databases.postgresql.enable = true;
services = { services = {
borgmatic = { borgmatic = {
enable = true; enable = true;
@ -90,23 +57,11 @@
]; ];
repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo"; repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo";
}; };
coturn = { coturn.enable = true;
enable = true;
realm = "turn.vimium.com";
matrixIntegration = true;
};
gitea.enable = true; gitea.enable = true;
headscale.enable = true; headscale.enable = true;
matrix = { matrix-synapse.enable = true;
enable = true;
bridges = {
signal = true;
whatsapp = true;
};
usePostgresql = databases.postgresql.enable;
};
nginx.enable = true; nginx.enable = true;
photoprism.enable = true;
}; };
}; };

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 = [ imports = [
./options.nix ./options.nix
./podman.nix
./databases/postgresql.nix
./desktop/gnome.nix ./desktop/gnome.nix
./desktop/forensics.nix
./desktop/hyprland.nix
./desktop/kde.nix
./desktop/mimeapps.nix ./desktop/mimeapps.nix
./desktop/apps/qbittorrent.nix ./desktop/apps/qbittorrent.nix
./desktop/apps/slack.nix ./desktop/apps/slack.nix
./desktop/apps/thunderbird.nix ./desktop/apps/thunderbird.nix
./desktop/apps/zoom.nix ./desktop/apps/zoom.nix
./desktop/browsers/brave.nix
./desktop/browsers/firefox.nix ./desktop/browsers/firefox.nix
./desktop/gaming/emulators.nix ./desktop/gaming/emulators.nix
./desktop/gaming/lutris.nix ./desktop/gaming/lutris.nix
@ -32,22 +26,16 @@
./editors/neovim ./editors/neovim
./editors/vscode.nix ./editors/vscode.nix
./hardware/presonus-studio.nix ./hardware/presonus-studio.nix
./networking/netbird.nix
./networking/tailscale.nix ./networking/tailscale.nix
./networking/wireless.nix ./networking/wireless.nix
./security/gpg.nix ./security/gpg.nix
./security/pass.nix ./security/pass.nix
./services/borgmatic ./services/borgmatic
./services/chrony
./services/coturn ./services/coturn
./services/gitea ./services/gitea
./services/gitea-runner
./services/headscale ./services/headscale
./services/home-assistant ./services/matrix-synapse
./services/mail
./services/matrix
./services/nginx ./services/nginx
./services/photoprism
./shell/git ./shell/git
./shell/zsh ./shell/zsh
]; ];

View File

@ -1,4 +1,4 @@
{ config, lib, self, ... }: { config, lib, pkgs, inputs, ... }:
let cfg = config.modules.desktop.apps.thunderbird; let cfg = config.modules.desktop.apps.thunderbird;
in { in {
@ -10,7 +10,7 @@ in {
}; };
config = lib.mkIf cfg.enable { 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 = { home.programs.thunderbird = {
enable = true; 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; let cfg = config.modules.desktop.browsers.firefox;
in { in {
@ -10,7 +10,7 @@ in {
}; };
config = lib.mkIf cfg.enable { 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 = { home.programs.firefox = {
enable = true; enable = true;
@ -35,79 +35,23 @@ in {
## Preferences ## Preferences
"browser.ctrlTab.sortByRecentlyUsed" = true; "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.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.search.widget.inNavBar" = true;
"browser.startup.page" = 3; "browser.startup.page" = 3;
"browser.startup.homepage" = "https://www.vimium.com"; "browser.startup.homepage" = "https://www.vimium.com";
"browser.toolbars.bookmarks.visibility" = "never"; "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 ## Experiments
"app.normandy.enabled" = false; "app.normandy.enabled" = false;
"app.normandy.api_url" = ""; "app.normandy.api_url" = "";
"app.normandy.user_id" = ""; "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.disabled" = true;
"extensions.screenshots.upload-disabled" = true; "extensions.screenshots.upload-disabled" = true;
"experiments.supported" = false; "experiments.supported" = false;
"experiments.enabled" = false; "experiments.enabled" = false;
"experiments.manifest.uri" = ""; "experiments.manifest.uri" = "";
"network.allow-experiments" = false; "network.allow-experiments" = false;
"privacy.trackingprotection.enabled" = 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;
## Geo ## Geo
"geo.enabled" = false; "geo.enabled" = false;
@ -154,34 +98,12 @@ in {
"dom.battery.enabled" = false; "dom.battery.enabled" = false;
"dom.vr.enabled" = false; "dom.vr.enabled" = false;
"media.navigator.enabled" = false; "media.navigator.enabled" = false;
# "dom.webaudio.enabled" = false; "dom.webaudio.enabled" = false;
## Isolation ## Isolation
"privacy.firstparty.isolate" = true; "privacy.firstparty.isolate" = true;
"privacy.firstparty.isolate.restrict_opener_access" = 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 ## Pocket/Hello
"loop.enabled" = false; "loop.enabled" = false;
"loop.feedback.baseUrl" = ""; "loop.feedback.baseUrl" = "";
@ -203,10 +125,6 @@ in {
"browser.pocket.useLocaleList" = false; "browser.pocket.useLocaleList" = false;
"brwoser.pocket.enabledLocales" = ""; "brwoser.pocket.enabledLocales" = "";
## Plugins
"plugin.state.flash" = 0;
"plugin.state.java" = 0;
## Misc ## Misc
"browser.selfsupport.url" = ""; "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

@ -54,11 +54,11 @@ in {
}; };
config = { config = {
user.packages = with pkgs; [ user.packages = with pkgs.unstable; [
(lib.mkIf cfg.ps1.enable duckstation) (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.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.ds.enable desmume)
(lib.mkIf (cfg.gba.enable || (lib.mkIf (cfg.gba.enable ||
cfg.gb.enable || cfg.gb.enable ||
@ -68,7 +68,7 @@ in {
(lib.mkIf (cfg.wii.enable || (lib.mkIf (cfg.wii.enable ||
cfg.gamecube.enable) cfg.gamecube.enable)
dolphin-emu) dolphin-emu)
(lib.mkIf cfg.xbox.enable unstable.xemu) (lib.mkIf cfg.xbox.enable xemu)
]; ];
}; };
} }

View File

@ -10,20 +10,16 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ user.packages = with pkgs; [
(lutris.override { lutris
extraPkgs = pkgs: [
winePackages.staging
wine64Packages.staging
];
})
vulkan-loader vulkan-loader
vulkan-tools vulkan-tools
]; ];
hardware.graphics = { hardware.opengl = {
enable = true; enable = true;
enable32Bit = true; driSupport = true;
driSupport32Bit = true;
}; };
}; };
} }

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, self, ... }: { config, lib, pkgs, ... }:
let cfg = config.modules.desktop.gnome; let cfg = config.modules.desktop.gnome;
in { in {
@ -21,106 +21,38 @@ in {
programs.dconf.enable = true; programs.dconf.enable = true;
dconf.settings = { dconf.settings = {
"io/github/celluloid-player/celluloid" = {
draggable-video-area-enable = true;
};
"org/gnome/Console" = {
font-scale = 1.4;
use-system-font = false;
custom-font = "ComicShannsMono Nerd Font 10";
};
"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/Ptyxis" = {
use-system-font = false;
font-name = "ComicShannsMono Nerd Font 11";
audible-bell = false;
};
"org/gnome/settings-daemon/plugins/media-keys" = {
volume-up = [
"<Shift>F12"
"XF86AudioRaiseVolume"
];
volume-down = [
"<Shift>F11"
"XF86AudioLowerVolume"
];
};
"org/gnome/shell" = { "org/gnome/shell" = {
disable-user-extensions = false; disable-user-extensions = false;
enabled-extensions = [ enabled-extensions = [
"appindicatorsupport@rgcjonas.gmail.com" # "another-window-session-manager@gmail.com"
# "arcmenu@arcmenu.com"
"blur-my-shell@aunetx" "blur-my-shell@aunetx"
"burn-my-windows@schneegans.github.com" "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" # "desktop-cube@schneegans.github.com"
# "EasyScreenCast@iacopodeenosee.gmail.com" # "desktop-zoom@colin.kinlo.ch"
"espresso@coadmunkee.github.com" "espresso@coadmunkee.github.com"
"flypie@schneegans.github.com" # "flypie@schneegans.github.com"
# "forge@jmmaranan.com" # "forge@jmmaranan.com"
"gsconnect@andyholmes.github.io" "hue-lights@chlumskyvaclav@gmail.com"
# "gSnap@micahosborne"
"hidetopbar@mathieu.bidon.ca"
"just-perfection-desktop@just-perfection" "just-perfection-desktop@just-perfection"
# "mediacontrols@cliffniff.github.com"
# "mousefollowsfocus@matthes.biz"
# "pano@elhan.io" # "pano@elhan.io"
# "paperwm@hedning:matrix.org" # "paperwm@hedning:matrix.org"
"pip-on-top@rafostar.github.com"
# "search-light@icedman.github.com" # "search-light@icedman.github.com"
# "smart-auto-move@khimaros.com"
"space-bar@luchrioh" "space-bar@luchrioh"
# "smart-auto-move@khimaros.com"
# "systemd-manager@hardpixel.eu"
# "tailscale-status@maxgallup.github.com"
# "tiling-assistant@leleat-on-github" # "tiling-assistant@leleat-on-github"
"tilingshell@ferrarodomenico.com"
"Vitals@CoreCoding.com" "Vitals@CoreCoding.com"
"windowIsReady_Remover@nunofarruca@gmail.com"
# "worksets@blipk.xyz"
# "wsmatrix@martin.zurowietz.de" # "wsmatrix@martin.zurowietz.de"
]; ];
favorite-apps = [ favorite-apps = [
"firefox.desktop" "firefox.desktop"
"org.gnome.Nautilus.desktop" "org.gnome.Nautilus.desktop"
"org.gnome.Ptyxis.desktop"
]; ];
}; };
"org/gnome/shell/extensions/another-window-session-manager" = {
enable-autorestore-sessions = true;
};
"org/gnome/shell/extensions/blur-my-shell/panel" = { "org/gnome/shell/extensions/blur-my-shell/panel" = {
static-blur = true; static-blur = true;
}; };
@ -132,14 +64,8 @@ in {
glide-open-effect = true; glide-open-effect = true;
glide-close-effect = true; glide-close-effect = true;
}; };
"org/gnome/shell/extensions/dash-to-panel" = { "org/gnome/shell/extensions/desktop-zoom" = {
intellihide = true; mag-factor-delta = 0.07;
panel-positions = ''
{"0":"TOP"}
'';
trans-panel-opacity = 0.3;
trans-use-custom-opacity = true;
trans-use-dynamic-opacity = true;
}; };
"org/gnome/shell/extensions/espresso" = { "org/gnome/shell/extensions/espresso" = {
enable-fullscreen = true; enable-fullscreen = true;
@ -149,32 +75,18 @@ in {
"com.obsproject.Studio.desktop" "com.obsproject.Studio.desktop"
]; ];
}; };
"org/gnome/shell/extensions/flypie" = { "org/gnome/shell/extensions/paperwm" = {
preview-on-right-side = true; use-default-background = true;
}; };
"org/gnome/shell/extensions/forge" = { "org/gnome/shell/extensions/forge" = {
window-gap-size = 8; window-gap-size = 8;
window-gap-hidden-on-single = false; 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" = { "org/gnome/shell/extensions/just-perfection" = {
activities-button = false; activities-button = false;
window-demands-attention-focus = true; window-demands-attention-focus = true;
workspace-wrap-around = 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" = { "org/gnome/shell/extensions/space-bar/behavior" = {
enable-activate-workspace-shortcuts = true; enable-activate-workspace-shortcuts = true;
show-empty-workspaces = true; show-empty-workspaces = true;
@ -187,10 +99,15 @@ in {
screen-left-gap = 8; screen-left-gap = 8;
window-gap = 8; window-gap = 8;
}; };
"org/gnome/shell/extensions/tilingshell" = { "org/gnome/desktop/background" = {
inner-gaps = 16; picture-uri = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-l.jpg";
outer-gaps = 8; picture-uri-dark = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-d.jpg";
enable-blur-snap-assistant = true; };
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
};
"org/gnome/desktop/search-providers" = {
disabled = [ "org.gnome.Epiphany.desktop" ];
}; };
"org/gtk/settings/file-chooser" = { "org/gtk/settings/file-chooser" = {
show-hidden = true; show-hidden = true;
@ -200,91 +117,119 @@ in {
show-hidden = true; show-hidden = true;
sort-directories-first = true; sort-directories-first = true;
}; };
}; "org/gnome/settings-daemon/plugins/media-keys" = {
volume-up = [
environment.sessionVariables = { "<Shift>F12"
QT_STYLE_OVERRIDE = lib.mkForce "kvantum"; "XF86AudioRaiseVolume"
QT_WAYLAND_DECORATION = lib.mkForce "adwaita"; ];
}; volume-down = [
"<Shift>F11"
home.configFile = { "XF86AudioLowerVolume"
"Kvantum/kvantum.kvconfig".text = lib.generators.toINI {} { ];
General.theme = "KvLibadwaitaDark"; };
"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;
edge-tiling = true;
experimental-features = [ "scale-monitor-framebuffer" ];
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false;
monospace-font-name = "UbuntuMono Nerd Font 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
(nerdfonts.override { fonts = [ "BigBlueTerminal" "ComicShannsMono" "UbuntuMono" ]; })
];
user.packages = with pkgs; [ user.packages = with pkgs; [
authenticator authenticator
# bottles bottles
# bustle bustle
celluloid celluloid
# d-spy d-spy
# drawing drawing
# fragments fragments
dconf-editor gnome.ghex
ghex
# gnome-builder # gnome-builder
gnome-decoder gnome-decoder
gnome-firmware gnome-firmware
gnome-frog gnome-frog
# gnome-obfuscate gnome-obfuscate
gnome-podcasts gnome-podcasts
identity identity
# mission-center mission-center
mousam
newsflash newsflash
ptyxis schemes
# schemes
shortwave shortwave
sysprof ];
environment.systemPackages = with pkgs; [
adw-gtk3
bind
bmon
fd
ffmpeg
gnome.gnome-boxes
gnomeExtensions.another-window-session-manager
# gnomeExtensions.bifocals
gnomeExtensions.blur-my-shell
gnomeExtensions.browser-tabs
gnomeExtensions.burn-my-windows
gnomeExtensions.desktop-cube
gnomeExtensions.desktop-zoom
gnomeExtensions.espresso
gnome44Extensions."flypie@schneegans.github.com"
# gnomeExtensions.forge
# gnomeExtensions.gsnap
gnomeExtensions.hue-lights
gnomeExtensions.just-perfection
# gnomeExtensions.mutter-primary-gpu
gnomeExtensions.pano
gnomeExtensions.paperwm
# gnomeExtensions.pip-on-top
gnomeExtensions.rounded-window-corners
gnomeExtensions.search-light
gnomeExtensions.smart-auto-move
gnomeExtensions.space-bar
gnomeExtensions.systemd-manager
gnomeExtensions.tailscale-status
gnomeExtensions.tiling-assistant
# gnomeExtensions.todotxt
gnomeExtensions.vitals
# gnomeExtensions.window-is-ready-remover
# gnomeExtensions.worksets
# gnomeExtensions.workspace-matrix
iotop
unstable.morewaita-icon-theme
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
] ++ (if config.virtualisation.podman.enable then [ ] ++ (if config.virtualisation.podman.enable then [
pods pods
] else []); ] else []);
environment.systemPackages = with pkgs.unstable; [ home.services.gpg-agent.pinentryFlavor = "gnome3";
adw-gtk3
kdePackages.qtstyleplugin-kvantum
libsForQt5.qtstyleplugin-kvantum
morewaita-icon-theme
nautilus-python
qadwaitadecorations
qadwaitadecorations-qt6
## Shell extensions
gnomeExtensions.appindicator
gnomeExtensions.arcmenu
gnomeExtensions.blur-my-shell
gnomeExtensions.burn-my-windows
gnomeExtensions.clipboard-indicator
gnomeExtensions.coverflow-alt-tab
gnomeExtensions.dash-to-panel
gnomeExtensions.desktop-cube
gnomeExtensions.easyScreenCast
gnomeExtensions.espresso
gnomeExtensions.fly-pie
gnomeExtensions.forge
gnomeExtensions.gsconnect
gnomeExtensions.gsnap
gnomeExtensions.hide-top-bar
gnomeExtensions.just-perfection
gnomeExtensions.media-controls
gnomeExtensions.mouse-follows-focus
# gnomeExtensions.pano (disabled due to: https://github.com/NixOS/nixpkgs/issues/369438)
gnomeExtensions.paperwm
gnomeExtensions.pip-on-top
gnomeExtensions.search-light
gnomeExtensions.smart-auto-move
gnomeExtensions.space-bar
gnomeExtensions.tiling-assistant
gnomeExtensions.tiling-shell
gnomeExtensions.todotxt
gnomeExtensions.vitals
gnomeExtensions.window-is-ready-remover
gnomeExtensions.worksets
gnomeExtensions.workspace-matrix
];
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-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, ... }: { config, lib, pkgs, ... }:
let let cfg = config.modules.desktop.office.libreoffice;
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;
# };
# });
# };
in { in {
options.modules.desktop.office.libreoffice = { options.modules.desktop.office.libreoffice = {
enable = lib.mkOption { enable = lib.mkOption {
@ -29,10 +11,7 @@ in {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
user.packages = with pkgs; [ user.packages = with pkgs; [
(if config.modules.desktop.kde.enable == true then libreoffice-qt else libreoffice) libreoffice
hunspell
hunspellDicts.en-gb-large
hunspellDicts.en-us-large
]; ];
}; };
} }

View File

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

View File

@ -7,12 +7,12 @@ let
patched = snd-usb-audio-module.overrideAttrs (prev: { patched = snd-usb-audio-module.overrideAttrs (prev: {
patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ]; patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ];
}); });
upmixConfig = { upmixConfig = ''
"stream.properties" = { stream.properties = {
"channelmix.upmix" = true; channelmix.upmix = true
"channelmix.upmix-method" = "psd"; channelmix.upmix-method = psd
}; }
}; '';
in { in {
options.modules.hardware.presonus-studio = { options.modules.hardware.presonus-studio = {
enable = lib.mkOption { enable = lib.mkOption {
@ -27,62 +27,43 @@ in {
(patched) (patched)
]; ];
# Workaround for mainline module loading instead of patched module environment.etc = {
systemd.services.reload-snd-usb-audio = { "pipewire/pipewire.conf.d/10-network.conf".text = ''
description = "Reload snd_usb_audio kernel module"; context.modules = [
wantedBy = [ "sound.target" ]; {
serviceConfig.Type = "oneshot"; name = libpipewire-module-rtp-session
path = with pkgs; [ args = {
kmod stream.props = {
]; node.name = "rtp-source"
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
''; '';
}; "pipewire/pipewire.conf.d/surround.conf".text = ''
context.modules = [
services.pipewire.extraConfig = { {
pipewire = { name = libpipewire-module-loopback
"10-network" = { args = {
"context.modules" = [ node.description = "Genelec 4.1 Surround"
{ capture.props = {
"name" = "libpipewire-module-rtp-session"; node.name = "Genelec_Speakers"
"args" = { media.class = "Audio/Sink"
"stream.props" = { audio.position = [ FL FR SL SR LFE ]
"node.name" = "rtp-source"; }
}; 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
}
} }
]; }
}; ]
"surround" = { '';
"context.modules" = [ "pipewire/pipewire-pulse.conf.d/40-upmix.conf".text = upmixConfig;
{ "pipewire/client-rt.conf.d/40-upmix.conf".text = upmixConfig;
"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 let cfg = config.modules.networking.tailscale;
cfg = config.modules.networking.tailscale;
headscale = "https://headscale.vimium.net";
hostname = config.networking.hostName;
in { in {
options.modules.networking.tailscale = { options.modules.networking.tailscale = {
enable = lib.mkOption { enable = lib.mkOption {
@ -17,24 +14,8 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
age.secrets."passwords/services/tailscale/${hostname}-authkey" = { services.tailscale.enable = true;
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.openssh.openFirewall = !cfg.restrictSSH; services.openssh.openFirewall = !cfg.restrictSSH;
networking.firewall = { networking.firewall = {
checkReversePath = "loose"; checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ]; trustedInterfaces = [ "tailscale0" ];

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, self, ... }: { config, lib, pkgs, inputs, ... }:
with lib; with lib;
@ -19,16 +19,16 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
age.secrets."passwords/networks" = { age.secrets."passwords/networks" = {
file = "${self.inputs.secrets}/passwords/networks.age"; file = "${inputs.secrets}/passwords/networks.age";
}; };
networking = { networking = {
wireless = { wireless = {
enable = true; enable = true;
interfaces = cfg.interfaces; interfaces = cfg.interfaces;
secretsFile = config.age.secrets."passwords/networks".path; environmentFile = config.age.secrets."passwords/networks".path;
networks = { networks = {
"Apollo 600 Mbps".pskRaw = "ext:PSK_APOLLO"; "Apollo 600 Mbps".psk = "@PSK_APOLLO@";
}; };
}; };
networkmanager.ensureProfiles.profiles = { networkmanager.ensureProfiles.profiles = {

View File

@ -1,4 +1,4 @@
{ config, options, lib, self, ... }: { config, options, lib, home-manager, inputs, ... }:
with lib; with lib;
{ {
@ -29,14 +29,14 @@ with lib;
}; };
config = { 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 = user =
let user = builtins.getEnv "USER"; let user = builtins.getEnv "USER";
name = if elem user [ "" "root" ] then "jordan" else user; name = if elem user [ "" "root" ] then "jordan" else user;
in { in {
inherit name; inherit name;
isNormalUser = true; isNormalUser = true;
extraGroups = [ "audio" "networkmanager" "wheel" "lxd" ]; extraGroups = [ "networkmanager" "wheel" "lxd" ];
description = "Jordan Holt"; description = "Jordan Holt";
useDefaultShell = true; useDefaultShell = true;
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
@ -66,11 +66,6 @@ with lib;
}; };
dconf.settings = mkAliasDefinitions options.dconf.settings; 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; 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,33 +1,35 @@
{ config, lib, self, ... }: { config, lib, pkgs, inputs, ... }:
with lib;
let let
cfg = config.modules.services.borgmatic; cfg = config.modules.services.borgmatic;
hostname = config.networking.hostName; hostname = config.networking.hostName;
in { in {
options.modules.services.borgmatic = { options.modules.services.borgmatic = {
enable = lib.mkOption { enable = mkOption {
default = false; default = false;
example = true; example = true;
description = lib.mdDoc "Enable backups on this host with `borgmatic`"; description = mdDoc "Enable backups on this host with `borgmatic`";
}; };
directories = lib.mkOption { directories = mkOption {
type = lib.types.listOf lib.types.str; type = types.listOf types.str;
default = []; default = [];
example = [ example = [
"/home/jordan/Documents" "/home/jordan/Documents"
]; ];
description = lib.mdDoc "List of directories to backup"; description = mdDoc "List of directories to backup";
}; };
repoPath = lib.mkOption { repoPath = mkOption {
type = lib.types.str; type = types.str;
example = "ssh://example@example.repo.borgbase.com/./repo"; example = "ssh://example@example.repo.borgbase.com/./repo";
description = lib.mdDoc "Destination borg repository for backup"; description = mdDoc "Destination borg repository for backup";
}; };
}; };
config = lib.mkIf cfg.enable { config = mkIf cfg.enable {
age.secrets."passwords/services/borg/${hostname}-passphrase" = { age.secrets."passwords/services/borg/${hostname}-passphrase" = {
file = "${self.inputs.secrets}/passwords/services/borg/${hostname}-passphrase.age"; file = "${inputs.secrets}/passwords/services/borg/${hostname}-passphrase.age";
}; };
services.borgmatic = { services.borgmatic = {
@ -45,16 +47,6 @@ in {
}; };
}; };
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` # Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true; 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 +1,60 @@
{ config, lib, self, ... }: { config, lib, pkgs, inputs, ... }:
with lib;
let let
cfg = config.modules.services.coturn; cfg = config.modules.services.coturn;
in { in {
options.modules.services.coturn = { options.modules.services.coturn = {
enable = lib.mkOption { enable = mkOption {
default = false; default = false;
example = true; 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 { config = mkIf cfg.enable {
networking.firewall = let networking.firewall = {
range = with config.services.coturn; lib.singleton {
from = min-port;
to = max-port;
};
in {
allowedTCPPorts = [ allowedTCPPorts = [
3478 # TURN listener
5349 # STUN TLS 5349 # STUN TLS
5350 # STUN TLS alt 5350 # STUN TLS alt
]; ];
allowedUDPPorts = [ allowedUDPPortRanges = [
3478 # TURN listener { from = 49152; to = 49999; } # TURN relay
5349 # TLS
5350 # TLS alt
]; ];
allowedUDPPortRanges = range; # TURN peer relays
}; };
security.acme.certs = { security.acme.certs = {
"${config.services.coturn.realm}" = { "turn.vimium.com" = {
group = "turnserver";
reloadServices = [ "coturn" ]; reloadServices = [ "coturn" ];
}; };
}; };
age.secrets = { age.secrets."passwords/services/coturn/shared-secret" = {
"passwords/services/coturn/static-auth-secret" = { file = "${inputs.secrets}/passwords/services/coturn/shared-secret.age";
file = "${self.inputs.secrets}/passwords/services/coturn/static-auth-secret.age"; owner = "turnserver";
owner = "turnserver"; group = "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 { services.coturn = {
enable = true; enable = true;
realm = cfg.realm; lt-cred-mech = true;
use-auth-secret = true; use-auth-secret = true;
static-auth-secret-file = config.age.secrets."passwords/services/coturn/static-auth-secret".path; static-auth-secret-file = config.age.secrets."passwords/services/coturn/shared-secret".path;
cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; realm = "turn.vimium.com";
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; relay-ips = [
min-port = 49000; "198.244.190.160"
max-port = 50000; ];
no-cli = true;
no-tcp-relay = true; no-tcp-relay = true;
extraConfig = '' extraConfig = ''
cipher-list="HIGH" cipher-list="HIGH"
no-loopback-peers
no-multicast-peers 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
''; '';
}; secure-stun = true;
cert = "/var/lib/acme/turn.vimium.com/fullchain.pem";
services.matrix-synapse = lib.mkIf cfg.matrixIntegration { pkey = "/var/lib/acme/turn.vimium.com/key.pem";
settings = with config.services.coturn; { min-port = 49152;
turn_uris = [ max-port = 49999;
"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,17 +1,18 @@
{ config, lib, pkgs, self, ... }: { config, lib, pkgs, inputs, ... }:
with lib;
let let
cfg = config.modules.services.gitea; cfg = config.modules.services.gitea;
in { in {
options.modules.services.gitea = { options.modules.services.gitea = {
enable = lib.mkEnableOption "gitea"; enable = mkOption {
domain = lib.mkOption { default = false;
type = lib.types.string; example = true;
default = "git.vimium.com";
}; };
}; };
config = lib.mkIf cfg.enable { config = mkIf cfg.enable {
users = { users = {
users.git = { users.git = {
isSystemUser = true; isSystemUser = true;
@ -30,7 +31,7 @@ in {
}; };
}; };
virtualHosts = { virtualHosts = {
"${cfg.domain}" = { "git.vimium.com" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/".proxyPass = "http://gitea"; locations."/".proxyPass = "http://gitea";
@ -38,13 +39,6 @@ in {
}; };
}; };
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 { services.gitea = rec {
package = pkgs.unstable.gitea; package = pkgs.unstable.gitea;
enable = true; enable = true;
@ -63,23 +57,19 @@ in {
}; };
settings = { settings = {
server = { server = {
DOMAIN = config.networking.domain; SSH_USER = "git";
LANDING_PAGE = "explore"; SSH_DOMAIN = "git.vimium.com";
SSH_PORT = lib.head config.services.openssh.ports;
OFFLINE_MODE = true; OFFLINE_MODE = true;
PROTOCOL = "http+unix"; PROTOCOL = "http+unix";
SSH_USER = "git"; DOMAIN = config.networking.domain;
SSH_DOMAIN = "${cfg.domain}"; ROOT_URL = "https://git.vimium.com/";
SSH_PORT = lib.head config.services.openssh.ports;
ROOT_URL = "https://${cfg.domain}/";
}; };
service.DISABLE_REGISTRATION = true; service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true; session.COOKIE_SECURE = true;
log = { log.ROOT_PATH = "${stateDir}/log";
ROOT_PATH = "${stateDir}/log";
"logger.router.MODE" = "";
};
ui = { ui = {
THEMES = "gitea,arc-green,github,github-auto,github-dark"; THEMES = "gitea,arc-green,github-dark,bthree-dark";
DEFAULT_THEME = "github-dark"; DEFAULT_THEME = "github-dark";
}; };
actions.ENABLED = true; actions.ENABLED = true;

View File

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

View File

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

View File

@ -1,92 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.services.home-assistant;
in {
config = lib.mkIf cfg.enable {
services.home-assistant = {
config.lovelace.resources = [{
url = "/local/nixos-lovelace-modules/floorplan.js";
type = "module";
}];
customLovelaceModules = [
pkgs.ha-floorplan
];
};
environment.etc."home-assistant/www/floorplan/style.css".source = ./style.css;
environment.etc."home-assistant/www/floorplan/config.yaml".text = builtins.toJSON {
image = {
location = "/local/floorplan/beetham.svg";
cache = false;
};
stylesheet = {
location = "/local/floorplan/style.css";
cache = false;
};
defaults = {
hover_action = "hover-info";
hold_action = "toggle";
tap_action = "more-info";
};
rules = [
{
name = "Rooms";
entities = [
{
entity = "light.bedroom_lamps";
element = "area.bedroom";
}
{
entity = "light.hallway_spots";
element = "area.hallway";
}
{
entity = "light.living_room_lamps";
element = "area.livingroom";
}
{
entity = "light.office_lamps";
element = "area.office";
}
];
tap_action = "light.toggle";
state_action = {
service = "floorplan.class_set";
service_data = ''
if (entity.state === "on") {
return "light-on";
}
return "light-off";
'';
};
}
{
name = "Temperature";
entities = [
"sensor.motion_sensor_temperature"
];
state_action = [
{
service = "floorplan.text_set";
service_data = ''
if (!isNaN(entity.state)) {
return Math.round(entity.state * 10) / 10 + "°";
}
return "Unknown";
'';
}
{
service = "floorplan.class_set";
service_data = {
class = "static-temp";
};
}
];
}
];
};
};
}

View File

@ -1,27 +0,0 @@
#floorplan {
padding: 10px;
}
svg, svg * {
vector-effect: non-scaling-stroke !important;
pointer-events: all !important;
}
path[id*="area."].light-on {
opacity: 0 !important;
}
path[id*="area."] {
opacity: 0.5 !important;
transition: opacity .25s;
-moz-transition: opacity .25s;
-webkit-transition: opacity .25s;
}
svg tspan {
fill: var(--primary-text-color);
}
.static-temp, .static-temp tspan {
fill: #ffffff;
}

View File

@ -1,75 +0,0 @@
{ config, lib, pkgs, self, ... }:
let
cfg = config.modules.services.home-assistant;
in {
config = lib.mkIf cfg.enable {
services.mosquitto = {
enable = true;
listeners = [{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
port = 1883;
settings = {
allow_anonymous = true;
};
}];
};
age.secrets."files/services/zigbee2mqtt/secret.yaml" = {
file = "${self.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;
frontend = true;
device_options = {
retain = true;
};
serial = {
port = "/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0";
};
advanced = {
channel = 20;
network_key = "!secret.yaml network_key";
pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
transmit_power = 20;
};
mqtt = {
version = 5;
server = "mqtt://localhost:1883";
};
};
};
modules.services.borgmatic.directories = [
config.services.mosquitto.dataDir
config.services.zigbee2mqtt.dataDir
];
services.home-assistant = {
config.mqtt = {};
extraComponents = [
"mqtt"
"mqtt_eventstream"
"mqtt_json"
"mqtt_room"
"mqtt_statestream"
];
};
};
}

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

@ -0,0 +1,127 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.matrix-synapse;
matrixClientConfig = {
"m.homeserver" = {
base_url = "https://matrix.vimium.com";
server_name = "vimium.com";
};
"m.identity_server" = {};
};
matrixServerConfig."m.server" = "matrix.vimium.com:443";
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in {
options.modules.services.matrix-synapse = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
8448 # Matrix federation
];
security.acme.certs = {
"matrix.vimium.com" = {
reloadServices = [ "matrix-synapse" ];
};
};
services.nginx.virtualHosts = {
"chat.vimium.com" = {
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"; }
];
};
};
};
};
"matrix.vimium.com" = {
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";
};
};
"vimium.com" = {
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown matrixServerConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown matrixClientConfig);
};
};
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"
# ];
};
};
};
}

View File

@ -1,228 +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";
};
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" = {
"base_url" = "https://vector.im";
};
};
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";
};
};
"${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;
};
};
systemd.services.matrix-synapse.serviceConfig.SupplementaryGroups =
(lib.optional cfg.bridges.whatsapp
config.systemd.services.mautrix-whatsapp.serviceConfig.Group);
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,4 +1,4 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, inputs, ... }:
with lib; with lib;
@ -82,13 +82,6 @@ in {
worker_connections 20000; worker_connections 20000;
multi_accept off; multi_accept off;
''; '';
proxyCachePath = {
"skycam" = {
enable = true;
keysZoneName = "skycam_cache";
maxSize = "100m";
};
};
virtualHosts = { virtualHosts = {
## Static sites ## Static sites
"jellyfin.vimium.com" = { "jellyfin.vimium.com" = {
@ -112,25 +105,6 @@ in {
''; '';
}; };
}; };
"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" = { "pki.vimium.com" = {
addSSL = true; addSSL = true;
forceSSL = false; forceSSL = false;
@ -168,6 +142,7 @@ in {
## Redirects ## Redirects
// (mkRedirect "h0lt.com" "jdholt.com") // (mkRedirect "h0lt.com" "jdholt.com")
// (mkRedirect "jordanholt.xyz" "jdholt.com") // (mkRedirect "jordanholt.xyz" "jdholt.com")
// (mkRedirect "jdholt.com" "vimium.com")
// (mkRedirect "omnimagic.com" "vimium.com") // (mkRedirect "omnimagic.com" "vimium.com")
// (mkRedirect "omnimagic.net" "vimium.com") // (mkRedirect "omnimagic.net" "vimium.com")
// (mkRedirect "thelostlegend.com" "suhailhussain.com") // (mkRedirect "thelostlegend.com" "suhailhussain.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; [ user.packages = with pkgs; [
fd fd
unstable.fzf fzf
jq jq
nix-zsh-completions nix-zsh-completions
nnn 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,22 +1,11 @@
final: prev: self: super:
{ {
gvdb = prev.fetchgit { gnome = super.gnome.overrideScope' (gself: gsuper: {
url = "https://gitlab.gnome.org/GNOME/gvdb.git"; mutter = gsuper.mutter.overrideAttrs (oldAttrs: {
rev = "b54bc5da25127ef416858a3ad92e57159ff565b3"; # From gvdb_wrap src = super.fetchurl {
sha256 = "c56yOepnKPEYFcU1B1TrDl8ydU0JU+z6R8siAQP4d2A="; 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=";
};
mutter = prev.mutter.overrideAttrs (attrs: { });
src = prev.fetchurl {
url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-47/mutter-triple-buffering-v4-47.tar.gz";
sha256 = "oeykTJRcG/SY83U8RYnyFFZ8zKqoyXvtbaS2f/s503U=";
};
postPatch = ''
mkdir -p subprojects/gvdb
cp -r ${final.gvdb}/* subprojects/gvdb/
${attrs.postPatch or ""}
'';
}); });
} }

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,38 +0,0 @@
{
lib,
buildNpmPackage,
fetchFromGitHub
}:
buildNpmPackage rec {
pname = "floorplan";
version = "1.0.44";
src = fetchFromGitHub {
owner = "ExperienceLovelace";
repo = "ha-floorplan";
rev = "refs/tags/${version}";
hash = "sha256-ajEA47H9nFXVcuvhwkDsxc5YYQWMsUXqHQ3t6tuAaxc=";
};
npmDepsHash = "sha256-/6H3XMraD7/usZBwmQaCDpV2n1Eed+U+G0f2YnjyWgk=";
installPhase = ''
runHook preInstall
mkdir $out
cp -R dist/* $out/
runHook postInstall
'';
meta = {
description = "Floorplan for Home Assistant";
longDescription = ''
Bring new life to Home Assistant. By mapping entities to a SVG-object,
you're able to control devices, show states, calling services - and much
more. Add custom styling on top, to visualize whatever you can think of.
Your imagination just became the new limit.
'';
homepage = "https://github.com/ExperienceLovelace/ha-floorplan";
license = lib.licenses.asl20;
};
}

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;
};
})