yep, more dotfiles

Compare changes

Choose any two refs to compare.

Changed files
+3213 -2182
.github
workflows
apps
home-manager
hosts
lib
modules
nixos
overlays
pkgs
secrets
templates
blank
c
rust
rust-pkg
+1 -1
.github/workflows/nix.yml
···
name: Check flake
runs-on: ubuntu-latest
steps:
-
- uses: actions/checkout@v4
+
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@v31
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
+1
.ignore
···
+
*.age
+18 -12
Justfile
···
@just --list --unsorted --list-heading '' --list-prefix '—— '
[linux]
-
switch PROFILE="" *ARGS:
-
sudo nixos-rebuild switch --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
switch profile="" *args:
+
sudo nixos-rebuild switch --show-trace --flake .#{{profile}} {{args}}
[macos]
-
switch PROFILE="" *ARGS:
-
darwin-rebuild switch --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
switch profile="" *args:
+
darwin-rebuild switch --show-trace --flake .#{{profile}} {{args}}
[linux]
-
build PROFILE="" *ARGS:
-
nixos-rebuild build --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
build profile="" *args:
+
nixos-rebuild build --show-trace --flake .#{{profile}} {{args}}
[macos]
-
build PROFILE="" *ARGS:
-
darwin-rebuild build --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
build profile="" *args:
+
darwin-rebuild build --show-trace --flake .#{{profile}} {{args}}
-
home-build PROFILE *ARGS:
-
home-manager build --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
home-build profile *args:
+
home-manager build --show-trace --flake .#{{profile}} {{args}}
+
+
home-switch profile *args:
+
home-manager switch --show-trace --flake .#{{profile}} {{args}}
-
home-switch PROFILE *ARGS:
-
home-manager switch --show-trace --flake .#{{PROFILE}} {{ARGS}}
+
switch-target host *args:
+
nixos-rebuild switch \
+
--flake .#{{host}} \
+
--target-host {{host}} \
+
--sudo {{args}}
+10 -1
README.md
···
- `fragments`: Home Manager configuration fragments
- `options`: Home Manager configuration flags
- `profiles`: Base Home Manager configurations to build upon (e.g. `desktop`, `minimal`)
-
- `lib`: Additional custom lib and flake helpers
+
- `lib`: Additional custom lib and flake helpers
- `modules`: modules that fill a missing feature of NixOS or Home Manager
- `nixos`: NixOS related config
- `hardware/<hostname>.nix`: Device-specific settings like settings generated by `nixos-generate-config`
···
--target-host 2a01:4f8:c2c:76d2::1 \
--use-remote-sudo
```
+
+
## LUKS reminders
+
+
- [Backup and Restore LUKS header](https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#Backup_and_restore)
+
+
## Secure boot
+
+
- Lanzaboote
+
- [SystemD cryptenroll](https://wiki.archlinux.org/title/Systemd-cryptenroll)
---
+1 -1
apps/flash-installer.nix
···
fi
echo "Flashing to $dev"
-
+
# Format selected disk
pv -tpreb "${isoPath}" | sudo dd bs=4M of="$dev" iflag=fullblock conv=notrunc,noerror oflag=sync
'';
+2 -1
configurations.nix
···
# Servers
"weird-row-server" = createSystem pkgs [
-
(system "weird-row-server" "server")
+
(host "weird-row-server")
(managedDiskLayout "ext4-hetzner" { device = "sda"; swapSize = 2; })
+
# TODO: should we keep a real user there?
(user "milomoisson" { description = "Milo Moisson"; profile = "server"; keys = keys.users; })
];
};
+565 -101
flake.lock
···
{
"nodes": {
+
"actor-typeahead-src": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1762835797,
+
"narHash": "sha256-heizoWUKDdar6ymfZTnj3ytcEv/L4d4fzSmtr0HlXsQ=",
+
"ref": "refs/heads/main",
+
"rev": "677fe7f743050a4e7f09d4a6f87bbf1325a06f6b",
+
"revCount": 6,
+
"type": "git",
+
"url": "https://tangled.org/@jakelazaroff.com/actor-typeahead"
+
},
+
"original": {
+
"type": "git",
+
"url": "https://tangled.org/@jakelazaroff.com/actor-typeahead"
+
}
+
},
"agenix": {
"inputs": {
"darwin": "darwin",
···
"systems": "systems"
},
"locked": {
-
"lastModified": 1754433428,
-
"narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=",
+
"lastModified": 1762618334,
+
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm",
"repo": "agenix",
-
"rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d",
+
"rev": "fcdea223397448d35d9b31f798479227e80183f6",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"base16": {
+
"inputs": {
+
"fromYaml": "fromYaml"
+
},
+
"locked": {
+
"lastModified": 1755819240,
+
"narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
+
"owner": "SenchoPens",
+
"repo": "base16.nix",
+
"rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
+
"type": "github"
+
},
+
"original": {
+
"owner": "SenchoPens",
+
"repo": "base16.nix",
+
"type": "github"
+
}
+
},
+
"base16-fish": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1754405784,
+
"narHash": "sha256-l9xHIy+85FN+bEo6yquq2IjD1rSg9fjfjpyGP1W8YXo=",
+
"owner": "tomyun",
+
"repo": "base16-fish",
+
"rev": "23ae20a0093dca0d7b39d76ba2401af0ccf9c561",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tomyun",
+
"repo": "base16-fish",
+
"rev": "23ae20a0093dca0d7b39d76ba2401af0ccf9c561",
+
"type": "github"
+
}
+
},
+
"base16-helix": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1752979451,
+
"narHash": "sha256-0CQM+FkYy0fOO/sMGhOoNL80ftsAzYCg9VhIrodqusM=",
+
"owner": "tinted-theming",
+
"repo": "base16-helix",
+
"rev": "27cf1e66e50abc622fb76a3019012dc07c678fac",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "base16-helix",
+
"type": "github"
+
}
+
},
+
"base16-vim": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1732806396,
+
"narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=",
+
"owner": "tinted-theming",
+
"repo": "base16-vim",
+
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "base16-vim",
+
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
+
"type": "github"
+
}
+
},
+
"crane": {
+
"locked": {
+
"lastModified": 1754269165,
+
"narHash": "sha256-0tcS8FHd4QjbCVoxN9jI+PjHgA4vc/IjkUSp+N3zy0U=",
+
"owner": "ipetkov",
+
"repo": "crane",
+
"rev": "444e81206df3f7d92780680e45858e31d2f07a08",
+
"type": "github"
+
},
+
"original": {
+
"owner": "ipetkov",
+
"repo": "crane",
+
"type": "github"
+
}
+
},
"darwin": {
"inputs": {
"nixpkgs": [
···
]
},
"locked": {
-
"lastModified": 1758287904,
-
"narHash": "sha256-IGmaEf3Do8o5Cwp1kXBN1wQmZwQN3NLfq5t4nHtVtcU=",
+
"lastModified": 1764627417,
+
"narHash": "sha256-D6xc3Rl8Ab6wucJWdvjNsGYGSxNjQHzRc2EZ6eeQ6l4=",
"owner": "nix-community",
"repo": "disko",
-
"rev": "67ff9807dd148e704baadbd4fd783b54282ca627",
+
"rev": "5a88a6eceb8fd732b983e72b732f6f4b8269bef3",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"firefox-gnome-theme": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1758112371,
+
"narHash": "sha256-lizRM2pj6PHrR25yimjyFn04OS4wcdbc38DCdBVa2rk=",
+
"owner": "rafaelmardojai",
+
"repo": "firefox-gnome-theme",
+
"rev": "0909cfe4a2af8d358ad13b20246a350e14c2473d",
+
"type": "github"
+
},
+
"original": {
+
"owner": "rafaelmardojai",
+
"repo": "firefox-gnome-theme",
+
"type": "github"
+
}
+
},
"flake-compat": {
"flake": false,
"locked": {
+
"lastModified": 1761588595,
+
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
+
"type": "github"
+
},
+
"original": {
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"type": "github"
+
}
+
},
+
"flake-compat_2": {
+
"locked": {
+
"lastModified": 1761588595,
+
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
+
"type": "github"
+
},
+
"original": {
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"type": "github"
+
}
+
},
+
"flake-compat_3": {
+
"flake": false,
+
"locked": {
"lastModified": 1751685974,
"narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=",
"rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1",
···
"url": "https://git.lix.systems/lix-project/flake-compat/archive/main.tar.gz"
}
},
-
"flake-utils": {
+
"flake-parts": {
"inputs": {
-
"systems": "systems_2"
+
"nixpkgs-lib": [
+
"stylix",
+
"nixpkgs"
+
]
},
"locked": {
-
"lastModified": 1731533236,
-
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
-
"owner": "numtide",
-
"repo": "flake-utils",
-
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+
"lastModified": 1756770412,
+
"narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=",
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
+
"rev": "4524271976b625a4a605beefd893f270620fd751",
"type": "github"
},
"original": {
-
"owner": "numtide",
-
"repo": "flake-utils",
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
"type": "github"
}
},
-
"flake-utils_2": {
+
"flake-utils": {
"inputs": {
"systems": "systems_3"
},
···
"type": "github"
}
},
+
"fromYaml": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1731966426,
+
"narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
+
"owner": "SenchoPens",
+
"repo": "fromYaml",
+
"rev": "106af9e2f715e2d828df706c386a685698f3223b",
+
"type": "github"
+
},
+
"original": {
+
"owner": "SenchoPens",
+
"repo": "fromYaml",
+
"type": "github"
+
}
+
},
"git-leave": {
"inputs": {
"gitignore": "gitignore",
···
"rust-overlay": "rust-overlay"
},
"locked": {
-
"lastModified": 1747139554,
-
"narHash": "sha256-CpjdfdzyN0tAcBvtg9AQk+mDlNSb+NAZPUBpx/4VzvA=",
+
"lastModified": 1764804992,
+
"narHash": "sha256-6XIwDQwquGUfiwoTsukMyE6DcXW4Cx0fjE4cLTgQ7RM=",
"owner": "mrnossiom",
"repo": "git-leave",
-
"rev": "bf125663fa992097620ca034ec57ebd20ed50532",
+
"rev": "3c09ab6afafae76be08956cc7bf563f80e0f8394",
"type": "github"
},
"original": {
···
]
},
"locked": {
+
"lastModified": 1762808025,
+
"narHash": "sha256-XmjITeZNMTQXGhhww6ed/Wacy2KzD6svioyCX7pkUu4=",
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"rev": "cb5e3fdca1de58ccbc3ef53de65bd372b48f567c",
+
"type": "github"
+
},
+
"original": {
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"type": "github"
+
}
+
},
+
"gitignore_2": {
+
"inputs": {
+
"nixpkgs": [
+
"hypixel-bank-tracker",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1762808025,
+
"narHash": "sha256-XmjITeZNMTQXGhhww6ed/Wacy2KzD6svioyCX7pkUu4=",
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"rev": "cb5e3fdca1de58ccbc3ef53de65bd372b48f567c",
+
"type": "github"
+
},
+
"original": {
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"type": "github"
+
}
+
},
+
"gitignore_3": {
+
"inputs": {
+
"nixpkgs": [
+
"lanzaboote",
+
"pre-commit",
+
"nixpkgs"
+
]
+
},
+
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
···
"type": "github"
}
},
-
"gitignore_2": {
+
"gitignore_4": {
"inputs": {
"nixpkgs": [
"wakatime-ls",
···
"type": "github"
}
},
+
"gnome-shell": {
+
"flake": false,
+
"locked": {
+
"host": "gitlab.gnome.org",
+
"lastModified": 1762869044,
+
"narHash": "sha256-nwm/GJ2Syigf7VccLAZ66mFC8mZJFqpJmIxSGKl7+Ds=",
+
"owner": "GNOME",
+
"repo": "gnome-shell",
+
"rev": "680e3d195a92203f28d4bf8c6e8bb537cc3ed4ad",
+
"type": "gitlab"
+
},
+
"original": {
+
"host": "gitlab.gnome.org",
+
"owner": "GNOME",
+
"ref": "gnome-49",
+
"repo": "gnome-shell",
+
"type": "gitlab"
+
}
+
},
"gomod2nix": {
"inputs": {
-
"flake-utils": "flake-utils_2",
+
"flake-utils": "flake-utils",
"nixpkgs": [
"tangled",
"nixpkgs"
···
"type": "github"
}
},
-
"helix": {
-
"inputs": {
-
"nixpkgs": [
-
"unixpkgs"
-
],
-
"rust-overlay": "rust-overlay_2"
-
},
-
"locked": {
-
"lastModified": 1759201995,
-
"narHash": "sha256-3STv6fITv8Ar/kl0H7vIA7VV0d2gyLh8UL0BOiVacXg=",
-
"owner": "helix-editor",
-
"repo": "helix",
-
"rev": "bfcbef10c513108c7b43317569416c2eefc4ed44",
-
"type": "github"
-
},
-
"original": {
-
"owner": "helix-editor",
-
"repo": "helix",
-
"type": "github"
-
}
-
},
"home-manager": {
"inputs": {
"nixpkgs": [
···
]
},
"locked": {
-
"lastModified": 1747556831,
-
"narHash": "sha256-Qb84nbYFFk0DzFeqVoHltS2RodAYY5/HZQKE8WnBDsc=",
+
"lastModified": 1764398914,
+
"narHash": "sha256-YPrpwlVQidzQlMh0OnquaJR+58rKe9YNnuRis293Ilo=",
"owner": "nix-community",
"repo": "home-manager",
-
"rev": "d0bbd221482c2713cccb80220f3c9d16a6e20a33",
+
"rev": "d0c5fdc48db6f19471b8adc954eca09194e68036",
"type": "github"
},
"original": {
"owner": "nix-community",
-
"ref": "release-25.05",
+
"ref": "release-25.11",
"repo": "home-manager",
"type": "github"
}
···
"url": "https://cdn.jsdelivr.net/npm/htmx-ext-ws@2.0.2"
}
},
+
"hypixel-bank-tracker": {
+
"inputs": {
+
"gitignore": "gitignore_2",
+
"nixpkgs": [
+
"nixpkgs"
+
],
+
"rust-overlay": "rust-overlay_2"
+
},
+
"locked": {
+
"lastModified": 1764455123,
+
"narHash": "sha256-ePlZ3OHBLTRlRa9zs2IeHNA8CuiMLyu5ZUzxoGI5Hp0=",
+
"owner": "pixilie",
+
"repo": "hypixel-bank-tracker",
+
"rev": "8e4e91b1a8fa264895fa40dda93c3363be33a958",
+
"type": "github"
+
},
+
"original": {
+
"owner": "pixilie",
+
"repo": "hypixel-bank-tracker",
+
"type": "github"
+
}
+
},
"ibm-plex-mono-src": {
"flake": false,
"locked": {
···
"url": "https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip"
}
},
-
"jujutsu": {
+
"lanzaboote": {
"inputs": {
-
"flake-utils": "flake-utils",
+
"crane": "crane",
"nixpkgs": [
"unixpkgs"
],
+
"pre-commit": "pre-commit",
"rust-overlay": "rust-overlay_3"
},
"locked": {
-
"lastModified": 1759360197,
-
"narHash": "sha256-OW8kSDBBSZr0G3U27AAkZ3cH3TJmSARbg9Pc4qZ6tA0=",
-
"owner": "jj-vcs",
-
"repo": "jj",
-
"rev": "22900c9a9ba362efa442fed2dd4e6e1d5c22cc7a",
+
"lastModified": 1764622702,
+
"narHash": "sha256-HggOVvg2U3EwT44wPHEwFKromf9qR9rTqfV1i3q7rYs=",
+
"owner": "nix-community",
+
"repo": "lanzaboote",
+
"rev": "6242b3b2b5e5afcf329027ed4eb5fa6e2eab10f1",
"type": "github"
},
"original": {
-
"owner": "jj-vcs",
-
"repo": "jj",
+
"owner": "nix-community",
+
"repo": "lanzaboote",
"type": "github"
}
},
···
"url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip"
}
},
+
"nix-alien": {
+
"inputs": {
+
"flake-compat": "flake-compat_2",
+
"nix-index-database": "nix-index-database",
+
"nixpkgs": [
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1764061716,
+
"narHash": "sha256-xKnIoMPv2kIsWhjRhJayqMWU2xkjeq2pyPmR1dLFPHs=",
+
"owner": "thiagokokada",
+
"repo": "nix-alien",
+
"rev": "9bc9c1ab671eb1b610f549e15bc0b750ab987409",
+
"type": "github"
+
},
+
"original": {
+
"owner": "thiagokokada",
+
"repo": "nix-alien",
+
"type": "github"
+
}
+
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
···
]
},
"locked": {
-
"lastModified": 1748004251,
-
"narHash": "sha256-XodjkVWTth3A2JpBqGBkdLD9kkWn94rnv98l3xwKukg=",
-
"owner": "LnL7",
+
"lastModified": 1764161084,
+
"narHash": "sha256-HN84sByg9FhJnojkGGDSrcjcbeioFWoNXfuyYfJ1kBE=",
+
"owner": "nix-darwin",
"repo": "nix-darwin",
-
"rev": "33220d4791784e4dd4739edd3f6c028020082f91",
+
"rev": "e95de00a471d07435e0527ff4db092c84998698e",
"type": "github"
},
"original": {
-
"owner": "LnL7",
+
"owner": "nix-darwin",
+
"ref": "nix-darwin-25.11",
"repo": "nix-darwin",
"type": "github"
}
},
+
"nix-index-database": {
+
"inputs": {
+
"nixpkgs": [
+
"nix-alien",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1762660502,
+
"narHash": "sha256-C9F1C31ys0V7mnp4EcDy7L1cLZw/sCTEXqqTtGnvu08=",
+
"owner": "nix-community",
+
"repo": "nix-index-database",
+
"rev": "15c5451c63f4c612874a43846bfe3fa828b03eee",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"repo": "nix-index-database",
+
"type": "github"
+
}
+
},
"nixos-hardware": {
"locked": {
-
"lastModified": 1758663926,
-
"narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=",
+
"lastModified": 1764440730,
+
"narHash": "sha256-ZlJTNLUKQRANlLDomuRWLBCH5792x+6XUJ4YdFRjtO4=",
"owner": "nixos",
"repo": "nixos-hardware",
-
"rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1",
+
"rev": "9154f4569b6cdfd3c595851a6ba51bfaa472d9f3",
"type": "github"
},
"original": {
···
},
"nixpkgs": {
"locked": {
-
"lastModified": 1747953325,
-
"narHash": "sha256-y2ZtlIlNTuVJUZCqzZAhIw5rrKP4DOSklev6c8PyCkQ=",
+
"lastModified": 1764406085,
+
"narHash": "sha256-CYbMp8hwuOf4umokSNp+t1s4Hjd4vxXq4S5CD+xvgNs=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "55d1f923c480dadce40f5231feb472e81b0bab48",
+
"rev": "9561691c9f450fad7c3526916e1c4f44be0d1192",
"type": "github"
},
"original": {
"owner": "nixos",
-
"ref": "nixos-25.05",
+
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
+
"nur": {
+
"inputs": {
+
"flake-parts": [
+
"stylix",
+
"flake-parts"
+
],
+
"nixpkgs": [
+
"stylix",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1758998580,
+
"narHash": "sha256-VLx0z396gDCGSiowLMFz5XRO/XuNV+4EnDYjdJhHvUk=",
+
"owner": "nix-community",
+
"repo": "NUR",
+
"rev": "ba8d9c98f5f4630bcb0e815ab456afd90c930728",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"repo": "NUR",
+
"type": "github"
+
}
+
},
+
"pre-commit": {
+
"inputs": {
+
"flake-compat": "flake-compat",
+
"gitignore": "gitignore_3",
+
"nixpkgs": [
+
"lanzaboote",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1763988335,
+
"narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=",
+
"owner": "cachix",
+
"repo": "pre-commit-hooks.nix",
+
"rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
+
"type": "github"
+
},
+
"original": {
+
"owner": "cachix",
+
"repo": "pre-commit-hooks.nix",
+
"type": "github"
+
}
+
},
"root": {
"inputs": {
"agenix": "agenix",
"disko": "disko",
"git-leave": "git-leave",
-
"helix": "helix",
"home-manager": "home-manager",
-
"jujutsu": "jujutsu",
+
"hypixel-bank-tracker": "hypixel-bank-tracker",
+
"lanzaboote": "lanzaboote",
+
"nix-alien": "nix-alien",
"nix-darwin": "nix-darwin",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"srvos": "srvos",
+
"stylix": "stylix",
"tangled": "tangled",
"unixpkgs": "unixpkgs",
-
"wakatime-ls": "wakatime-ls"
+
"wakatime-ls": "wakatime-ls",
+
"zen-browser": "zen-browser"
}
},
"rust-overlay": {
···
]
},
"locked": {
-
"lastModified": 1744599145,
-
"narHash": "sha256-yzaDPkJwZdUtRj/dzdOeB74yryWzpngYaD7BedqFKk8=",
+
"lastModified": 1764557621,
+
"narHash": "sha256-kX5PoY8hQZ80+amMQgOO9t8Tc1JZ70gYRnzaVD4AA+o=",
"owner": "oxalica",
"repo": "rust-overlay",
-
"rev": "fd6795d3d28f956de01a0458b6fa7baae5c793b4",
+
"rev": "93316876c2229460a5d6f5f052766cc4cef538ce",
"type": "github"
},
"original": {
···
"rust-overlay_2": {
"inputs": {
"nixpkgs": [
-
"helix",
+
"hypixel-bank-tracker",
"nixpkgs"
]
},
"locked": {
-
"lastModified": 1740623427,
-
"narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=",
+
"lastModified": 1763087910,
+
"narHash": "sha256-eB9Z1mWd1U6N61+F8qwDggX0ihM55s4E0CluwNukJRU=",
"owner": "oxalica",
"repo": "rust-overlay",
-
"rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab",
+
"rev": "cf4a68749733d45c0420726596367acd708eb2e8",
"type": "github"
},
"original": {
···
"rust-overlay_3": {
"inputs": {
"nixpkgs": [
-
"jujutsu",
+
"lanzaboote",
"nixpkgs"
]
},
"locked": {
-
"lastModified": 1755139244,
-
"narHash": "sha256-SN1BFA00m+siVAQiGLtTwjv9LV9TH5n8tQcSziV6Nv4=",
+
"lastModified": 1761791894,
+
"narHash": "sha256-myRIDh+PxaREz+z9LzbqBJF+SnTFJwkthKDX9zMyddY=",
"owner": "oxalica",
"repo": "rust-overlay",
-
"rev": "aeae248beb2a419e39d483dd9b7fec924aba8d4d",
+
"rev": "59c45eb69d9222a4362673141e00ff77842cd219",
"type": "github"
},
"original": {
···
]
},
"locked": {
-
"lastModified": 1748746145,
-
"narHash": "sha256-bwkCAK9pOyI2Ww4Q4oO1Ynv7O9aZPrsIAMMASmhVGp4=",
+
"lastModified": 1761705569,
+
"narHash": "sha256-dqljv29XldlKvdTwFw8GkxOQHrz3/13yxdwHW8+nzBI=",
"owner": "oxalica",
"repo": "rust-overlay",
-
"rev": "12a0d94a2f2b06714f747ab97b2fa546f46b460c",
+
"rev": "bca7909cb02f5139e0a490b0ff4bae775ea3ebf6",
"type": "github"
},
"original": {
···
]
},
"locked": {
-
"lastModified": 1759107752,
-
"narHash": "sha256-VEdL1J4rk+Z/5wHhLSsvj5QmXWKHHDeN1P8YLGLa1RM=",
+
"lastModified": 1764205213,
+
"narHash": "sha256-VWKPkM4m5kGgJ0HY1WKfvlPkKka6tYwUR8snetAFTu8=",
"owner": "nix-community",
"repo": "srvos",
-
"rev": "97708379b1f3b64224632eb49a56e45fe6995e6f",
+
"rev": "8b90cbaadae462563297a2d08870cccfd986ca28",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"stylix": {
+
"inputs": {
+
"base16": "base16",
+
"base16-fish": "base16-fish",
+
"base16-helix": "base16-helix",
+
"base16-vim": "base16-vim",
+
"firefox-gnome-theme": "firefox-gnome-theme",
+
"flake-parts": "flake-parts",
+
"gnome-shell": "gnome-shell",
+
"nixpkgs": [
+
"nixpkgs"
+
],
+
"nur": "nur",
+
"systems": "systems_2",
+
"tinted-foot": "tinted-foot",
+
"tinted-kitty": "tinted-kitty",
+
"tinted-schemes": "tinted-schemes",
+
"tinted-tmux": "tinted-tmux",
+
"tinted-zed": "tinted-zed"
+
},
+
"locked": {
+
"lastModified": 1764193603,
+
"narHash": "sha256-guX30TWe8HRG2qPFiM9893F2uTw4B8D/xkE6Mq7MiYg=",
+
"owner": "nix-community",
+
"repo": "stylix",
+
"rev": "9bf8725a3d65b3ff0ba68ce13779657f5095e36b",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"ref": "release-25.11",
+
"repo": "stylix",
+
"type": "github"
+
}
+
},
"systems": {
"locked": {
"lastModified": 1681028828,
···
},
"tangled": {
"inputs": {
-
"flake-compat": "flake-compat",
+
"actor-typeahead-src": "actor-typeahead-src",
+
"flake-compat": "flake-compat_3",
"gomod2nix": "gomod2nix",
"htmx-src": "htmx-src",
"htmx-ws-src": "htmx-ws-src",
···
"sqlite-lib-src": "sqlite-lib-src"
},
"locked": {
-
"lastModified": 1759247161,
-
"narHash": "sha256-Th0+karP19f0BC4cYBI27adn+lGFYCWq5C+FfQFrHXA=",
+
"lastModified": 1764005195,
+
"narHash": "sha256-PzuWiW/nMxwQTX0i1bHwGazQF4ptLNI9OGwpmhDb9i0=",
"ref": "refs/heads/master",
-
"rev": "5c9bf597da9a0f19635187a10f6711dd1917a9d7",
-
"revCount": 1467,
+
"rev": "7358ec6edfa4d17b8b8f543d99e83a4705901148",
+
"revCount": 1687,
"type": "git",
-
"url": "https://tangled.org/@tangled.org/core"
+
"url": "https://tangled.org/tangled.org/core"
},
"original": {
"type": "git",
-
"url": "https://tangled.org/@tangled.org/core"
+
"url": "https://tangled.org/tangled.org/core"
+
}
+
},
+
"tinted-foot": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1726913040,
+
"narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
+
"owner": "tinted-theming",
+
"repo": "tinted-foot",
+
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "tinted-foot",
+
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
+
"type": "github"
+
}
+
},
+
"tinted-kitty": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1735730497,
+
"narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=",
+
"owner": "tinted-theming",
+
"repo": "tinted-kitty",
+
"rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "tinted-kitty",
+
"type": "github"
+
}
+
},
+
"tinted-schemes": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1757716333,
+
"narHash": "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM=",
+
"owner": "tinted-theming",
+
"repo": "schemes",
+
"rev": "317a5e10c35825a6c905d912e480dfe8e71c7559",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "schemes",
+
"type": "github"
+
}
+
},
+
"tinted-tmux": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1757811970,
+
"narHash": "sha256-n5ZJgmzGZXOD9pZdAl1OnBu3PIqD+X3vEBUGbTi4JiI=",
+
"owner": "tinted-theming",
+
"repo": "tinted-tmux",
+
"rev": "d217ba31c846006e9e0ae70775b0ee0f00aa6b1e",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "tinted-tmux",
+
"type": "github"
+
}
+
},
+
"tinted-zed": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1757811247,
+
"narHash": "sha256-4EFOUyLj85NRL3OacHoLGEo0wjiRJzfsXtR4CZWAn6w=",
+
"owner": "tinted-theming",
+
"repo": "base16-zed",
+
"rev": "824fe0aacf82b3c26690d14e8d2cedd56e18404e",
+
"type": "github"
+
},
+
"original": {
+
"owner": "tinted-theming",
+
"repo": "base16-zed",
+
"type": "github"
}
},
"unixpkgs": {
"locked": {
-
"lastModified": 1759036355,
-
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
+
"lastModified": 1764950072,
+
"narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
+
"rev": "f61125a668a320878494449750330ca58b78c557",
"type": "github"
},
"original": {
···
},
"wakatime-ls": {
"inputs": {
-
"gitignore": "gitignore_2",
+
"gitignore": "gitignore_4",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay_4"
},
"locked": {
-
"lastModified": 1752245636,
-
"narHash": "sha256-T6nLp1UsnKwrL7coEgH+aTcTavM5OIiNRufA3sM2okk=",
+
"lastModified": 1761849542,
+
"narHash": "sha256-5fNSKIUG54TD5jq5hgsCmB4FB0mO8teiBE18fU81mfc=",
"owner": "mrnossiom",
"repo": "wakatime-ls",
-
"rev": "711644814c8e6842499c6c0852407321e9901597",
+
"rev": "89e4091ef5e4c1830dd9bd463f8b063f8335bfad",
"type": "github"
},
"original": {
"owner": "mrnossiom",
"repo": "wakatime-ls",
+
"type": "github"
+
}
+
},
+
"zen-browser": {
+
"inputs": {
+
"home-manager": [
+
"home-manager"
+
],
+
"nixpkgs": [
+
"unixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1764414951,
+
"narHash": "sha256-pZ2m2JmTTMyqiKB8WSigsSvAeoShI6OSRhzBuRO9SVY=",
+
"owner": "0xc000022070",
+
"repo": "zen-browser-flake",
+
"rev": "10d2aa53ada9b14f6df2f9877d6a057f0a2b262f",
+
"type": "github"
+
},
+
"original": {
+
"owner": "0xc000022070",
+
"repo": "zen-browser-flake",
"type": "github"
}
}
+26 -14
flake.nix
···
description = "NixOS and Home Manager configuration for Milo's laptops";
inputs = {
-
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
+
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
unixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
-
home-manager.url = "github:nix-community/home-manager/release-25.05";
+
home-manager.url = "github:nix-community/home-manager/release-25.11";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
-
nix-darwin.url = "github:LnL7/nix-darwin";
+
nix-darwin.url = "github:nix-darwin/nix-darwin/nix-darwin-25.11";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
+
stylix.url = "github:nix-community/stylix/release-25.11";
+
stylix.inputs.nixpkgs.follows = "nixpkgs";
+
+
## Miscellaneous
+
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
agenix.inputs.home-manager.follows = "home-manager";
···
nixos-hardware.url = "github:nixos/nixos-hardware";
+
lanzaboote.url = "github:nix-community/lanzaboote";
+
lanzaboote.inputs.nixpkgs.follows = "unixpkgs";
+
srvos.url = "github:nix-community/srvos";
-
# srvos.inputs.nixpkgs.follows = "srvos/nixpkgs";
srvos.inputs.nixpkgs.follows = "nixpkgs";
-
# ——— Packages
+
## Packages
+
git-leave.url = "github:mrnossiom/git-leave";
git-leave.inputs.nixpkgs.follows = "nixpkgs";
-
helix.url = "github:helix-editor/helix";
-
helix.inputs.nixpkgs.follows = "unixpkgs";
+
hypixel-bank-tracker.url = "github:pixilie/hypixel-bank-tracker";
+
hypixel-bank-tracker.inputs.nixpkgs.follows = "nixpkgs";
-
jujutsu.url = "github:jj-vcs/jj";
-
jujutsu.inputs.nixpkgs.follows = "unixpkgs";
+
nix-alien.url = "github:thiagokokada/nix-alien";
+
nix-alien.inputs.nixpkgs.follows = "nixpkgs";
-
tangled.url = "git+https://tangled.org/@tangled.org/core";
+
tangled.url = "git+https://tangled.org/tangled.org/core";
tangled.inputs.nixpkgs.follows = "unixpkgs";
wakatime-ls.url = "github:mrnossiom/wakatime-ls";
wakatime-ls.inputs.nixpkgs.follows = "nixpkgs";
+
+
zen-browser.url = "github:0xc000022070/zen-browser-flake";
+
zen-browser.inputs.nixpkgs.follows = "unixpkgs";
+
zen-browser.inputs.home-manager.follows = "home-manager";
};
outputs = { self, nixpkgs, ... }:
···
flake-lib = import ./lib/flake (nixpkgs // { inherit self; });
-
forAllPkgs = func: forAllSystems (system: func pkgs.${system});
-
# This should be the only constructed nixpkgs instances in this flake
-
pkgs = forAllSystems (system: (import nixpkgs {
+
allPkgs = forAllSystems (system: (import nixpkgs {
inherit system;
config.allowUnfreePredicate = import ./lib/unfree.nix { lib = nixpkgs.lib; };
overlays = [ outputs.overlays.all ];
}));
+
+
forAllPkgs = func: forAllSystems (system: func allPkgs.${system});
in
{
formatter = forAllPkgs (pkgs: pkgs.nixpkgs-fmt);
···
lib = forAllPkgs (import ./lib);
templates = import ./templates;
-
apps = forAllPkgs (import ./apps { pkgs-per-system = pkgs; });
+
apps = forAllPkgs (import ./apps { pkgs-per-system = allPkgs; });
devShells = forAllPkgs (import ./shells.nix);
overlays = import ./overlays (nixpkgs // { inherit self; });
packages = forAllPkgs (import ./pkgs);
-3
home-manager/fragments/agenix.nix
···
inherit (self.inputs) agenix;
cfg = config.local.fragment.agenix;
-
-
all-secrets = import ../../secrets;
in
{
options.local.fragment.agenix.enable = lib.mkEnableOption ''
···
imports = [ agenix.homeManagerModules.default ];
config = lib.mkIf cfg.enable {
-
age.secrets = all-secrets.home-manager;
# This allows us to decrypt user space secrets without having to use a
# passwordless ssh key as you cannot interact with age in the service.
age.identityPaths = [ "${config.home.homeDirectory}/.ssh/id_home_manager" ];
+147
home-manager/fragments/compose-key.nix
···
+
{ self
+
, config
+
, lib
+
, ...
+
}:
+
+
+
let
+
inherit (self.outputs) homeManagerModules;
+
+
cfg = config.local.fragment.compose-key;
+
in
+
{
+
imports = [ homeManagerModules.xcompose ];
+
+
options.local.fragment.compose-key.enable = lib.mkEnableOption ''
+
Compose key related
+
'';
+
+
config.programs.xcompose = lib.mkIf cfg.enable {
+
enable = true;
+
includeLocaleCompose = true;
+
loadConfigInEnv = false;
+
+
sequences.Multi_key = {
+
e.grave = "è";
+
E.grave = "È";
+
e.apostrophe = "é";
+
E.apostrophe = "É";
+
a.grave = "à";
+
A.grave = "À";
+
u.grave = "ù";
+
U.grave = "Ù";
+
e.quotedbl = "ë";
+
E.quotedbl = "Ë";
+
a.quotedbl = "ä";
+
A.quotedbl = "Ä";
+
+
quotedbl.quotedbl = "¨";
+
apostrophe.apostrophe = "´";
+
+
s.s = "ß";
+
+
# Lower case [g]reek letters
+
g = {
+
a = "α";
+
b = "β";
+
g = "γ";
+
d = "δ";
+
e = "ε";
+
z = "ζ";
+
h = "η";
+
u = "θ";
+
i = "ι";
+
k = "κ";
+
l = "λ";
+
m = "μ";
+
n = "ν";
+
x = "ξ";
+
q.o = "ο";
+
p = "π";
+
r = "ρ";
+
s = "σ";
+
t = "τ";
+
y = "υ";
+
f = "φ";
+
o = "ω";
+
};
+
# Upper case [G]reek letters
+
G = {
+
A = "Α";
+
B = "Β";
+
G = "Γ";
+
D = "Δ";
+
E = "Ε";
+
Z = "Ζ";
+
H = "Η";
+
U = "Θ";
+
I = "Ι";
+
K = "Κ";
+
L = "Λ";
+
M = "Μ";
+
N = "Ν";
+
X = "Ξ";
+
Q.O = "Ο";
+
P = "Π";
+
R = "Ρ";
+
S = "Σ";
+
T = "Τ";
+
Y = "Υ";
+
F = "Φ";
+
O = "Ω";
+
};
+
+
# Math
+
l.equal = "≤";
+
g.equal = "≥";
+
s.u.m = "∑";
+
asciitilde.asciitilde = "≈";
+
+
# Math double-struck symbols
+
M = {
+
A = "𝔸";
+
B = "𝔹";
+
C = "ℂ";
+
D = "𝔻";
+
E = "𝔼";
+
F = "𝔽";
+
G = "𝔾";
+
H = "ℍ";
+
I = "𝕀";
+
J = "𝕁";
+
K = "𝕂";
+
L = "𝕃";
+
M = "𝕄";
+
N = "ℕ";
+
O = "𝕆";
+
P = "ℙ";
+
Q = "ℚ";
+
R = "ℝ";
+
S = "𝕊";
+
T = "𝕋";
+
U = "𝕌";
+
V = "𝕍";
+
X = "𝕏";
+
Y = "𝕐";
+
Z = "ℤ";
+
};
+
+
# Symbols
+
o.o = "∞";
+
# Irony point
+
question.question = "⸮";
+
+
minus.greater = "→";
+
less.minus = "←";
+
less.greater.minus = "↔";
+
+
equal.greater = "⇒";
+
less.equal = "⇐";
+
less.greater.equal = "⇔";
+
+
"0"."0" = "°";
+
minus.minus = "—";
+
};
+
};
+
}
+8 -4
home-manager/fragments/default.nix
···
./agenix.nix
./aws.nix
./chromium.nix
+
./compose-key.nix
./epita.nix
./firefox.nix
./foot.nix
···
./helix.nix
./imv.nix
./jujutsu.nix
+
./kanshi.nix
./kitty.nix
+
./launcher.nix
./rust.nix
./shell.nix
+
./stylix.nix
+
./swaybar.nix
+
./sway.nix
./thunderbird.nix
./tools.nix
-
./vm-bar.nix
-
./vm-compose.nix
-
./vm.nix
-
./vm-search.nix
./vscodium.nix
+
./waybar.nix
./xdg-mime.nix
+
./zed.nix
./zellij
];
+9 -13
home-manager/fragments/epita.nix
···
{
options.local.fragment.epita.enable = lib.mkEnableOption ''
EPITA related
-
-
Depends on:
-
- `ssh` program: Mount AFS script needs SSH
'';
config = lib.mkIf cfg.enable {
-
assertions = [
-
{ assertion = config.programs.ssh.enable; message = "`epita` fragment depends on `ssh` program"; }
-
];
+
programs.ssh = {
+
package = pkgs.openssh_gssapi;
-
programs.ssh.package = pkgs.openssh_gssapi;
-
-
# Needed for sshfs
-
programs.ssh.matchBlocks."ssh.cri.epita.fr" = {
-
extraOptions = {
-
GSSAPIAuthentication = "yes";
-
GSSAPIDelegateCredentials = "yes";
+
# Needed for sshfs
+
enable = true;
+
matchBlocks."ssh.cri.epita.fr" = {
+
extraOptions = {
+
GSSAPIAuthentication = "yes";
+
GSSAPIDelegateCredentials = "yes";
+
};
};
};
+97 -50
home-manager/fragments/firefox.nix
···
-
{ config
+
{ self
+
, config
, lib
, pkgs
, ...
}:
let
+
inherit (self.inputs) zen-browser;
+
+
policies = {
+
DisableTelemetry = true;
+
DisableFirefoxStudies = true;
+
DontCheckDefaultBrowser = true;
+
DisablePocket = true;
+
SearchBar = "unified";
+
};
+
+
settings = {
+
# Privacy and default bloat
+
"extensions.pocket.enabled" = false;
+
"browser.newtabpage.pinned" = "";
+
"browser.topsites.contile.enabled" = false;
+
"browser.newtabpage.activity-stream.showSponsored" = false;
+
"browser.newtabpage.activity-stream.system.showSponsored" = false;
+
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
+
+
# Reopen previous session
+
"browser.startup.page" = true;
+
+
# Use vertical tabs
+
"sidebar.revamp" = true;
+
"sidebar.verticalTabs" = true;
+
+
# Disable swipe gesture
+
"browser.gesture.swipe.left" = "";
+
"browser.gesture.swipe.right" = "";
+
+
"browser.search.defaultenginename" = "DuckDuckGo";
+
"browser.search.order.1" = "DuckDuckGo";
+
+
"signon.rememberSignons" = false;
+
"widget.use-xdg-desktop-portal.file-picker" = 1;
+
"browser.aboutConfig.showWarning" = false;
+
+
# Enable meta devtools to inspect Firefox Chrome UI
+
"devtools.chrome.enabled" = true;
+
"devtools.debugger.remote-enabled" = true;
+
+
# Pickup userChrome styles at startup
+
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+
+
# Firefox 75+ remembers the last workspace it was opened on as part of its session management.
+
# This is annoying, because I can have a blank workspace, click Firefox from the launcher, and
+
# then have Firefox open on some other workspace.
+
"widget.disable-workspace-management" = true;
+
};
+
+
userContent = ''
+
/* Darken PDFs in viewer to match system color scheme */
+
@media (prefers-color-scheme: dark) {
+
#viewerContainer > #viewer > .page > .canvasWrapper > canvas,
+
#viewerContainer > #viewer > div.spread > .page > .canvasWrapper > canvas {
+
filter: grayscale(1) invert(1) sepia(1);
+
}
+
}
+
'';
+
cfg = config.local.fragment.firefox;
in
{
···
Firefox related
'';
+
imports = [
+
zen-browser.homeModules.beta
+
];
+
config = lib.mkIf cfg.enable {
-
home.sessionVariables.BROWSER = lib.getExe pkgs.firefox;
+
home.sessionVariables.BROWSER = lib.getExe config.programs.zen-browser.package;
+
+
stylix.targets.firefox = {
+
enable = false;
+
profileNames = [ "default" ];
+
};
+
stylix.targets.zen-browser = {
+
enable = false;
+
profileNames = [ "default" ];
+
};
-
programs.firefox = {
+
programs.zen-browser = {
enable = true;
-
policies = {
-
DisableTelemetry = true;
-
DisableFirefoxStudies = true;
-
DontCheckDefaultBrowser = true;
-
DisablePocket = true;
-
SearchBar = "unified";
-
};
+
inherit policies;
profiles.default = {
isDefault = true;
-
settings = {
-
# Privacy and default bloat
-
"extensions.pocket.enabled" = false;
-
"browser.newtabpage.pinned" = "";
-
"browser.topsites.contile.enabled" = false;
-
"browser.newtabpage.activity-stream.showSponsored" = false;
-
"browser.newtabpage.activity-stream.system.showSponsored" = false;
-
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
+
inherit
+
settings
+
userContent;
+
};
+
};
-
# Use vertical tabs
-
"sidebar.revamp" = true;
-
"sidebar.verticalTabs" = true;
+
programs.firefox = {
+
enable = true;
-
# Disable swipe gesture
-
"browser.gesture.swipe.left" = "";
-
"browser.gesture.swipe.right" = "";
+
inherit policies;
-
"browser.search.defaultenginename" = "DuckDuckGo";
-
"browser.search.order.1" = "DuckDuckGo";
-
-
"signon.rememberSignons" = false;
-
"widget.use-xdg-desktop-portal.file-picker" = 1;
-
"browser.aboutConfig.showWarning" = false;
-
-
# Enable meta devtools to inspect Firefox Chrome UI
-
"devtools.chrome.enabled" = true;
-
"devtools.debugger.remote-enabled" = true;
+
profiles.default = {
+
isDefault = true;
-
# Pickup userChrome styles at startup
-
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+
settings = settings // {
+
"zen.view.experimental-no-window-controls" = true;
+
"zen.view.show-newtab-button-top" = false;
-
# Firefox 75+ remembers the last workspace it was opened on as part of its session management.
-
# This is annoying, because I can have a blank workspace, click Firefox from the launcher, and
-
# then have Firefox open on some other workspace.
-
"widget.disable-workspace-management" = true;
+
"zen.welcome-screen.seen" = true;
+
"zen.workspaces.continue-where-left-off" = true;
+
"zen.view.compact.enable-at-startup" = true;
+
"zen.view.window.scheme" = 2; # 0 dark theme, 1 light theme, 2 auto
};
+
+
inherit userContent;
# <https://www.userchrome.org/how-create-userchrome-css.html>
userChrome = ''
/* Hide close button */
.titlebar-close { display: none !important; }
-
'';
-
-
userContent = ''
-
/* Darken PDFs in viewer to match system color scheme */
-
@media (prefers-color-scheme: dark) {
-
#viewerContainer > #viewer > .page > .canvasWrapper > canvas,
-
#viewerContainer > #viewer > div.spread > .page > .canvasWrapper > canvas {
-
filter: grayscale(1) invert(1) sepia(1);
-
}
-
}
'';
search = {
-10
home-manager/fragments/foot.nix
···
# TODO: promising but too buggy
# server.enable = true;
-
-
settings = {
-
main = {
-
font = "monospace:size=10";
-
};
-
colors = {
-
background = "000000";
-
foreground = "ffffff";
-
};
-
};
};
};
}
+56 -62
home-manager/fragments/git.nix
···
{
options.local.fragment.git.enable = lib.mkEnableOption ''
Git related
-
-
Depends on:
-
- `agenix` fragment: Need for GPG key and GitGuardian API key
'';
config = lib.mkIf cfg.enable {
-
assertions = [
-
{ assertion = config.local.fragment.agenix.enable; message = "`git` fragment depends on `agenix` fragment"; }
-
];
-
home.sessionVariables = {
# Disable annoying warning message
GIT_DISCOVERY_ACROSS_FILESYSTEM = 0;
···
enable = true;
lfs.enable = true;
-
userName = "Milo Moisson";
-
# TODO: this email should be behind a secret or at least a config
-
userEmail = "milo@wiro.world";
-
signing.signByDefault = true;
signing.key = "~/.ssh/id_ed25519.pub";
···
"result"
];
-
aliases = {
-
b = "branch --all";
-
brm = "branch --delete";
+
settings = {
+
user = {
+
name = "Milo Moisson";
+
# TODO: this email should be behind a secret or at least a config
+
email = "milo@wiro.world";
+
};
-
ll = "log --graph --oneline --pretty=custom";
-
lla = "log --graph --oneline --pretty=custom --all";
-
last = "log -1 HEAD --stat";
+
alias = {
+
b = "branch --all";
+
brm = "branch --delete";
-
st = "status --short --branch";
+
ll = "log --graph --oneline --pretty=custom";
+
lla = "log --graph --oneline --pretty=custom --all";
+
last = "log -1 HEAD --stat";
-
cm = "commit --message";
-
oups = "commit --amend";
+
st = "status --short --branch";
-
ui = "!lazygit";
+
cm = "commit --message";
+
oups = "commit --amend";
-
rv = "remote --verbose";
+
ui = "!lazygit";
-
ri = "rebase --interactive";
-
ris = "!git ri $(git slc)";
-
rc = "rebase --continue";
-
rs = "rebase --skip";
-
ra = "rebase --abort";
+
rv = "remote --verbose";
-
# Select commit
-
slc = "!git log --oneline --pretty=custom | fzf | awk '{printf $1}'";
+
ri = "rebase --interactive";
+
ris = "!git ri $(git slc)";
+
rc = "rebase --continue";
+
rs = "rebase --skip";
+
ra = "rebase --abort";
-
a = "add";
-
al = "add --all";
-
ac = "add .";
-
ap = "add --patch";
+
# Select commit
+
slc = "!git log --oneline --pretty=custom | fzf | awk '{printf $1}'";
-
pu = "push";
-
put = "push --follow-tags";
-
puf = "push --force-with-lease";
-
pl = "pull";
+
a = "add";
+
al = "add --all";
+
ac = "add .";
+
ap = "add --patch";
-
f = "fetch";
+
pu = "push";
+
put = "push --follow-tags";
+
puf = "push --force-with-lease";
+
pl = "pull";
-
s = "switch";
-
sc = "switch --create";
+
f = "fetch";
-
ck = "checkout";
+
s = "switch";
+
sc = "switch --create";
-
cp = "cherry-pick";
+
ck = "checkout";
-
df = "diff";
-
dfs = "diff --staged";
-
dfc = "diff --cached";
+
cp = "cherry-pick";
-
m = "merge";
+
df = "diff";
+
dfs = "diff --staged";
+
dfc = "diff --cached";
-
rms = "restore --staged";
-
res = "restore";
+
m = "merge";
-
sh = "stash";
-
shl = "stash list";
-
sha = "stash apply";
-
shp = "stash pop";
-
};
+
rms = "restore --staged";
+
res = "restore";
-
hooks = {
-
git-guardian = pkgs.writeShellScript "git-guardian" ''
-
export GITGUARDIAN_API_KEY="$(cat ${config.age.secrets.api-gitguardian.path})"
-
${lib.getExe' pkgs.ggshield "ggshield"} secret scan pre-commit "$@"
-
'';
-
};
+
sh = "stash";
+
shl = "stash list";
+
sha = "stash apply";
+
shp = "stash pop";
+
};
-
extraConfig = {
fetch.prune = true;
color.ui = true;
init.defaultBranch = "main";
···
"credentials \"https://github.com\"".helper = "!${lib.getExe pkgs.gh} auth git-credential";
# TODO: change to $PROJECTS env var?
-
leaveTool.defaultFolder = "~/Development";
+
leaveTool = {
+
defaultFolder = "${config.home.homeDirectory}/Development";
+
checks = [ "dirty" "ahead-branches" ];
+
};
};
};
···
showCommandLog = false;
border = "single";
};
+
git = {
-
paging.externalDiffCommand = "difft --color=always";
+
pagers = [
+
{ externalDiffCommand = "difft --color=always"; }
+
];
};
# to be declarative or not to be declarative?
+11 -5
home-manager/fragments/helix.nix
···
{ self
, config
, pkgs
+
, upkgs
, lpkgs
, lib
, ...
···
{ assertion = config.local.fragment.agenix.enable; message = "`helix` fragment depends on `agenix` fragment"; }
];
+
stylix.targets.helix.enable = false;
+
programs.helix = {
enable = true;
-
package = if flags.onlyCached then pkgs.helix else lpkgs.helix;
+
package = upkgs.helix;
defaultEditor = true;
settings = {
-
theme = "monokai_pro_octagon";
+
theme = lib.mkDefault "monokai_pro_octagon";
editor = {
auto-format = true;
···
# Toggle inlay hints
"A-u" = ":toggle lsp.display-inlay-hints";
-
# Toogle wrapping
+
# Toggle wrapping
# TODO: change to `soft-wrap.enable` when supported by `:toggle`
"A-w" = ":toggle soft-wrap.wrap-at-text-width";
};
···
};
extraPackages = with pkgs; [
-
ansible-language-server
clang-tools
gopls
kotlin-language-server
···
};
};
+
age.secrets.api-wakatime.file = ../../secrets/api-wakatime.age;
+
age.secrets.api-wakapi.file = ../../secrets/api-wakapi.age;
programs.wakatime = {
enable = true;
-
apiKeyFile = secrets.api-wakatime.path;
+
apiKeyFile = secrets.api-wakapi.path;
settings = {
+
api_url = "https://wakapi.dev/api";
+
exclude_unknown_project = true;
};
};
+4 -6
home-manager/fragments/jujutsu.nix
···
{ config
, lib
, pkgs
-
, lpkgs
+
, upkgs
, ...
}:
let
-
flags = config.local.flags;
-
keys = import ../../secrets/keys.nix;
cfg = config.local.fragment.jujutsu;
···
config = lib.mkIf cfg.enable {
programs.jujutsu = {
enable = true;
-
package = if flags.onlyCached then pkgs.jujutsu else lpkgs.jujutsu;
+
package = upkgs.jujutsu;
settings = {
user = {
···
signing = {
behavior = "own";
backend = "ssh";
-
key = keys.milomoisson;
-
+
key = keys.milo-ed25519;
git.sign-on-push = true;
};
···
templates = {
log = "custom_log_compact";
+
git_push_bookmark = ''"push-" ++ change_id.short()'';
};
ui = {
+55
home-manager/fragments/kanshi.nix
···
+
{ config
+
, lib
+
+
, isDarwin
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.kanshi;
+
in
+
{
+
options.local.fragment.kanshi.enable = lib.mkEnableOption ''
+
Kanshi related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
assertions = [
+
{ assertion = !isDarwin; message = "this is a non-darwin fragment"; }
+
];
+
+
services.kanshi = {
+
enable = true;
+
+
settings = [
+
{ output = { criteria = "eDP-1"; scale = 2.0; }; }
+
+
{
+
profile.name = "undocked";
+
profile.outputs = [
+
{ criteria = "eDP-1"; }
+
];
+
}
+
+
{
+
profile.name = "eizo-dock";
+
# position external screen centered above
+
profile.outputs = [
+
{ criteria = "Eizo Nanao Corporation CG222W 29804118"; position = "0,0"; }
+
{ criteria = "eDP-1"; position = "120,1050"; }
+
];
+
}
+
+
{
+
profile.name = "hdmi-default";
+
# position external screen right
+
profile.outputs = [
+
{ criteria = "eDP-1"; position = "0,0"; }
+
{ criteria = "HDMI"; position = "1440,0"; }
+
];
+
}
+
];
+
};
+
};
+
}
+
+1 -1
home-manager/fragments/kitty.nix
···
Kitty related
Depends on:
-
- (Darwin) `fish` program: lauches fish on startup
+
- (Darwin) `fish` program: launches fish on startup
Has weird behavior if set as login shell
'';
+65
home-manager/fragments/launcher.nix
···
+
{ config
+
, lib
+
, pkgs
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.sway;
+
+
colors = config.lib.stylix.colors.withHashtag;
+
in
+
{
+
config = lib.mkIf cfg.enable {
+
wayland.windowManager.sway.config.menu =
+
let
+
tofi-drun = lib.getExe' pkgs.tofi "tofi-drun";
+
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
+
jq = lib.getExe pkgs.jq;
+
in
+
"${tofi-drun} --output `${swaymsg} -t get_outputs| ${jq} -r '.[] | select(.focused).name'` | xargs ${swaymsg} exec --";
+
+
programs.tofi = {
+
enable = true;
+
settings = {
+
anchor = "top";
+
horizontal = true;
+
height = 52;
+
width = "100%";
+
+
outline-width = 0;
+
border-width = 0;
+
+
min-input-width = 100;
+
result-spacing = 30;
+
+
padding-top = 12;
+
padding-bottom = 12;
+
padding-left = 20;
+
padding-right = 20;
+
+
prompt-text = " ";
+
prompt-padding = 30;
+
prompt-background-padding = "5, 10";
+
prompt-background-corner-radius = 5;
+
+
input-background-padding = "5, 10";
+
input-background-corner-radius = 5;
+
+
selection-color = lib.mkForce colors.base07;
+
selection-match-color = colors.base0A;
+
selection-background = lib.mkForce colors.base02;
+
selection-background-padding = "5, 10";
+
selection-background-corner-radius = 8;
+
+
default-result-background = lib.mkForce colors.base01;
+
default-result-background-corner-radius = 8;
+
default-result-background-padding = "5, 10";
+
+
font = lib.mkForce "Sans";
+
+
clip-to-padding = false;
+
};
+
};
+
};
+
}
+1
home-manager/fragments/rust.nix
···
home.sessionPath = [ "${config.home.sessionVariables.CARGO_HOME}/bin" ];
# cargo config
+
age.secrets.api-crates-io.file = ../../secrets/api-crates-io.age;
home.file."${config.home.sessionVariables.CARGO_HOME}/config.toml".source =
let
clang = lib.getExe pkgs.llvmPackages.clang;
+20 -20
home-manager/fragments/shell.nix
···
{ config
, lib
, pkgs
+
, upkgs
, lpkgs
, isDarwin
···
git_status.disabled = true;
nix_shell = {
-
format = "via [$symbol$state]($style) "; # Remove nix shell name
+
# remove nix shell name
+
format = "via [$symbol]($style)";
symbol = " ";
};
};
···
programs.direnv = {
enable = true;
silent = true;
+
nix-direnv.enable = true;
-
};
-
programs.nushell = {
-
enable = true;
-
-
extraConfig = ''
-
$env.config = {
-
show_banner: false,
-
}
+
stdlib = ''
+
use angrr
'';
};
+
# TODO: depend on osConfig
+
xdg.configFile."direnv/lib/angrr.sh".text = ''
+
use_angrr() {
+
layout_dir="$(direnv_layout_dir)"
+
log_status "angrr: touch GC roots $layout_dir"
+
RUST_LOG="''${ANGRR_DIRENV_LOG:-angrr=error}" ${lib.getExe upkgs.angrr} touch "$layout_dir" --silent
+
}
+
'';
programs.zoxide = {
enable = true;
···
# This is also a more pure version than using `__fish_ls_*` variables
# that depends on fish internal ls wrappers and can be overridden by
# bad configuration. (e.g. NixOS `environment.shellAliases` default)
-
ls = "${lib.getExe pkgs.eza} --color=auto --icons=auto --hyperlink";
+
ls = "${lib.getExe upkgs.lsr}";
pasters = "${lib.getExe pkgs.curl} --data-binary @- https://paste.rs/";
+
+
mkcd = "mkdir $argv[1] && builtin cd $argv[1]";
};
shellAbbrs = {
···
tp = "trash-put";
# Listing utilities
-
l = "ls -aF";
-
ll = "ls -lhaF";
-
tree = "ls -T";
+
l = "ls -A1";
+
ll = "ls -Al";
# Nix-related
ur = " unlink result";
-
-
# Use newer tools
-
clear = "#"; # <ctrl-l>
-
cat = "#"; # bat
-
rm = "#"; # trash-put
-
tr = "#"; # srgn
# Do not keep these commands in history
exit = " exit";
···
'';
# Quickly explore a derivation (using registry syntax)
-
# e.g. `cdd nixpkgs#fontforge` or `cdd unixpkgs#fontforge`
+
# e.g. `cdd nixpkgs#fontforge` or `cdd unixpkgs#fontforge`
cdd = "cd (nix build --no-link --print-out-paths $argv | ${lib.getExe pkgs.fzf})";
} // lib.optionalAttrs (!flags.onlyCached) {
# Quickly get outta here to test something
+68
home-manager/fragments/stylix.nix
···
+
{ self
+
, config
+
, lib
+
, pkgs
+
, ...
+
}:
+
+
let
+
inherit (self.inputs) stylix;
+
+
cfg = config.local.fragment.stylix;
+
in
+
{
+
imports = [
+
stylix.homeModules.stylix
+
# issues a warning because we use `useGlobalPkgs`
+
{ config.stylix.overlays.enable = false; }
+
];
+
+
options.local.fragment.stylix.enable = lib.mkEnableOption ''
+
Stylix related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
# TODO: take a lot of build time
+
# specialisation.light.configuration = {
+
# stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/one-light.yaml";
+
# };
+
+
stylix = {
+
enable = true;
+
base16Scheme = lib.mkDefault "${pkgs.base16-schemes}/share/themes/onedark-dark.yaml";
+
+
image = ../../assets/wallpaper-binary-cloud.png;
+
+
fonts = {
+
sansSerif = { package = pkgs.inter; name = "Inter"; };
+
serif = { package = pkgs.merriweather; name = "Merriweather"; };
+
monospace = { package = pkgs.nerd-fonts.jetbrains-mono; name = "JetBrainsMono Nerd Font"; };
+
+
sizes = {
+
applications = 12;
+
terminal = 10;
+
+
desktop = 12;
+
popups = 14;
+
};
+
};
+
+
opacity = {
+
popups = 0.8;
+
};
+
+
cursor = {
+
name = "Bibata-Modern-Ice";
+
package = pkgs.bibata-cursors;
+
size = 24;
+
};
+
+
icons = {
+
enable = true;
+
package = pkgs.papirus-icon-theme;
+
light = "Papirus-Light";
+
dark = "Papirus-Dark";
+
};
+
};
+
};
+
}
+312
home-manager/fragments/sway.nix
···
+
{ config
+
, lib
+
, pkgs
+
+
, isDarwin
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.sway;
+
cfg-sway = config.wayland.windowManager.sway.config;
+
+
workspacesRange = lib.zipListsWith (key-idx: workspace-idx: { inherit key-idx workspace-idx; }) [ 1 2 3 4 5 6 7 8 9 0 ] (lib.range 1 10);
+
in
+
{
+
options.local.fragment.sway.enable = lib.mkEnableOption ''
+
Sway related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
assertions = [
+
{ assertion = !isDarwin; message = "this is a non-darwin fragment"; }
+
];
+
+
programs.swaylock = {
+
enable = true;
+
settings = {
+
daemonize = true;
+
ignore-empty-password = true;
+
show-failed-attempts = true;
+
+
# relies on custom swaylock version in `overlays/patches.nix`
+
indicator-y-position = -100;
+
indicator-x-position = 100;
+
};
+
};
+
+
programs.fish.loginShellInit = ''
+
if test (id --user $USER) -ge 1000 && test (tty) = "/dev/tty1"
+
exec sway 2> /tmp/sway.(date -u +%Y-%m-%dT%H:%M:%S).log
+
end
+
'';
+
+
services.mako = {
+
enable = true;
+
settings = {
+
width = 500;
+
max-visible = 5;
+
sort = "-priority";
+
+
default-timeout = 3 * 1000;
+
+
layer = "overlay";
+
+
border-size = 2;
+
border-radius = 5;
+
+
"mode=dnd".invisible = 1;
+
+
"urgency=critical" = {
+
invisible = 0;
+
default-timeout = 0;
+
};
+
};
+
};
+
+
gtk = {
+
enable = true;
+
gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
+
};
+
+
services.swayidle =
+
let
+
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
+
loginctl = lib.getExe' pkgs.systemd "loginctl";
+
systemctl = lib.getExe' pkgs.systemd "systemctl";
+
in
+
{
+
enable = true;
+
timeouts = [
+
# TODO: this doesn't work find a way to quickly cut output when locked and idle
+
# {
+
# timeout = 10;
+
# command = "if ${pgrep} -x swaylock; then ${swaymsg} \"output * power off\"; fi";
+
# resumeCommand = "${swaymsg} \"output * power on\"";
+
# }
+
+
{
+
timeout = 60 * 5;
+
# ——————————————— Dims the screen for n seconds ↓↓ and then switch it off
+
command = ''${lib.getExe pkgs.chayang} -d${toString 10} && ${swaymsg} "output * power off"'';
+
resumeCommand = ''${swaymsg} "output * power on"'';
+
}
+
{ timeout = 60 * 10; command = "${loginctl} lock-session"; }
+
{ timeout = 60 * 15; command = "${systemctl} suspend"; }
+
];
+
events = [
+
{ event = "before-sleep"; command = "${lib.getExe pkgs.playerctl} pause"; }
+
{ event = "before-sleep"; command = "${loginctl} lock-session"; }
+
# Can be triggered with `loginctl lock-session`
+
{ event = "lock"; command = lib.getExe pkgs.swaylock; }
+
];
+
};
+
+
wayland.windowManager.sway = {
+
enable = true;
+
+
xwayland = true; # explicit, op is true by default
+
+
config = {
+
modifier = "Mod4"; # Super key
+
terminal = config.home.sessionVariables.TERMINAL;
+
+
defaultWorkspace = "workspace number 1";
+
+
left = "h";
+
down = "j";
+
up = "k";
+
right = "l";
+
+
window = {
+
titlebar = false;
+
commands = [
+
# Tag of shame
+
{
+
# Equivalent to `[shell="xwayland"] title_format "%title [XWayland]"` but for all other shells
+
criteria.shell = "^((?!xdg_shell).)*$";
+
command = ''title_format "%title <small>[%shell]</small>"'';
+
}
+
+
# Toggle floating mode for some specific windows
+
{
+
# TODO: Bitwarden window glitches on opening
+
criteria = { app_id = "^firefox$"; title = "Bitwarden Password Manager"; };
+
command = ''floating enable'';
+
}
+
{
+
# Toggles floating for every Unity window but the main one
+
# Only the main window begins with `Unity - `
+
criteria = { title = "^((?!^Unity - ).)*$"; class = "^Unity$"; instance = "^Unity$"; };
+
command = ''floating enable'';
+
}
+
+
# Inhibit IDLE when these are fullscreen
+
{ criteria.app_id = "firefox"; command = "inhibit_idle fullscreen"; }
+
{ criteria.app_id = "mpv"; command = "inhibit_idle fullscreen"; }
+
{ criteria.app_id = "spotify"; command = "inhibit_idle fullscreen"; }
+
{ criteria.app_id = "zen-beta"; command = "inhibit_idle fullscreen"; }
+
];
+
};
+
+
focus.followMouse = false;
+
+
gaps.smartBorders = "no_gaps";
+
+
input = {
+
"type:keyboard" = {
+
xkb_layout = "us,fr(ergol),fr";
+
+
# List of all options: https://www.mankier.com/7/xkeyboard-config#Options
+
xkb_options = "grp:menu_toggle,compose:caps";
+
+
repeat_delay = toString 300;
+
repeat_rate = toString 30;
+
};
+
+
"type:touchpad" = {
+
dwt = "enabled";
+
tap = "enabled";
+
tap_button_map = "lrm";
+
};
+
+
# Split keyboard also acts as a mouse
+
# "type:touchpad" = { events = "disabled_on_external_mouse"; };
+
+
# Disable touchscreen by default
+
"type:touch" = { events = "disabled"; };
+
};
+
+
output."*".bg = lib.mkForce "#000000 solid_color";
+
+
seat."*" = {
+
# disable cursor when typing or on purpose
+
hide_cursor = "when-typing enable";
+
};
+
+
bindkeysToCode = true;
+
keybindings =
+
let
+
pamixer = lib.getExe pkgs.pamixer;
+
playerctl = lib.getExe pkgs.playerctl;
+
brightnessctl = lib.getExe pkgs.brightnessctl;
+
makoctl = lib.getExe' pkgs.mako "makoctl";
+
+
grim = lib.getExe pkgs.grim;
+
slurp = lib.getExe pkgs.slurp;
+
wl-copy = lib.getExe' pkgs.wl-clipboard "wl-copy";
+
wl-paste = lib.getExe' pkgs.wl-clipboard "wl-paste";
+
in
+
lib.foldl (acc: val: acc // val) { }
+
(map
+
(modifier: {
+
"${modifier}+Return" = "exec ${cfg-sway.terminal}";
+
"${modifier}+Shift+Return" = "exec ${lib.getExe' pkgs.nautilus "nautilus"}";
+
"${modifier}+Shift+q" = "kill";
+
"${modifier}+d" = "exec ${cfg-sway.menu}";
+
"${modifier}+Space" = "exec ${makoctl} dismiss";
+
+
"${modifier}+Escape" = "exec ${lib.getExe' pkgs.systemd "loginctl"} lock-session";
+
"${modifier}+Alt+Escape" = "exec ${pkgs.writeShellScript "lock-screenshot.sh" ''
+
tmpimg=$(${lib.getExe' pkgs.coreutils "mktemp"} /tmp/lock-bg.XXX)
+
+
# Give some time to hide the bar
+
sleep 1
+
+
${grim} $tmpimg
+
${lib.getExe pkgs.swaylock} --image $tmpimg
+
+
rm $tmpimg
+
''}";
+
+
"${modifier}+t" = ''input "type:touch" events toggle'';
+
+
"${modifier}+${cfg-sway.left}" = "focus left";
+
"${modifier}+${cfg-sway.down}" = "focus down";
+
"${modifier}+${cfg-sway.up}" = "focus up";
+
"${modifier}+${cfg-sway.right}" = "focus right";
+
+
"${modifier}+Shift+${cfg-sway.left}" = "move left";
+
"${modifier}+Shift+${cfg-sway.down}" = "move down";
+
"${modifier}+Shift+${cfg-sway.up}" = "move up";
+
"${modifier}+Shift+${cfg-sway.right}" = "move right";
+
"${modifier}+b" = "split vertical";
+
"${modifier}+n" = "split horizontal";
+
+
"${modifier}+Alt+${cfg-sway.left}" = "resize shrink width 60 px";
+
"${modifier}+Alt+${cfg-sway.down}" = "resize grow height 60 px";
+
"${modifier}+Alt+${cfg-sway.up}" = "resize shrink height 60 px";
+
"${modifier}+Alt+${cfg-sway.right}" = "resize grow width 60 px";
+
"${modifier}+f" = "fullscreen toggle";
+
"${modifier}+Shift+space" = "floating toggle";
+
# Change between tiling and floating focus
+
"${modifier}+Alt+space" = "focus mode_toggle";
+
"${modifier}+Alt+c" = "move position cursor";
+
"${modifier}+p" = "sticky toggle";
+
+
# Screenshotting
+
"${modifier}+s" = ''exec ${grim} -g "$(${slurp})" - | ${wl-copy}'';
+
"${modifier}+Shift+s" = "exec ${wl-paste} | ${lib.getExe pkgs.swappy} --file - --output-file - | ${wl-copy}";
+
+
# Soundcontrol Keys
+
"--locked XF86AudioPrev" = "exec ${playerctl} previous";
+
"--locked XF86AudioNext" = "exec ${playerctl} next";
+
"--locked XF86AudioPlay" = "exec ${playerctl} play-pause";
+
"--locked XF86AudioStop" = "exec ${playerctl} stop";
+
"--locked XF86AudioRaiseVolume" = "exec ${pamixer} --unmute --increase 5";
+
"--locked XF86AudioLowerVolume" = "exec ${pamixer} --unmute --decrease 5";
+
"--locked XF86AudioMute" = "exec ${pamixer} --toggle-mute";
+
"--locked XF86AudioMicMute" = "exec ${pamixer} --default-source --toggle-mute";
+
"--locked XF86MonBrightnessUp" = "exec ${brightnessctl} --exponent set 5%+";
+
"--locked XF86MonBrightnessDown" = "exec ${brightnessctl} --exponent set 5%- --min-value=1";
+
"--locked XF86TouchpadToggle" = ''input "type:touchpad" events toggle enabled disabled_on_external_mouse'';
+
}
+
// lib.listToAttrs (lib.flatten (map
+
({ key-idx, workspace-idx }: [
+
{ name = "${modifier}+${toString key-idx}"; value = "workspace number ${toString workspace-idx}"; }
+
{ name = "${modifier}+Alt+${toString key-idx}"; value = "move container to workspace number ${toString workspace-idx}"; }
+
{ name = "${modifier}+Shift+${toString key-idx}"; value = "move container to workspace number ${toString workspace-idx}; workspace number ${toString workspace-idx}"; }
+
])
+
workspacesRange))
+
) [ cfg-sway.modifier ]);
+
};
+
};
+
+
services.blueman-applet.enable = true;
+
+
services.poweralertd.enable = true;
+
+
services.darkman = {
+
enable = true;
+
settings.usegeoclue = true;
+
+
darkModeScripts.gtk-theme = ''
+
# Change system theme scheme to dark
+
${lib.getExe pkgs.dconf} write /org/gnome/desktop/interface/color-scheme "'prefer-dark'"
+
+
# Do not change brightness as I'm usually on my computer as this time
+
'';
+
+
lightModeScripts.gtk-theme = ''
+
# Change system theme scheme to light
+
${lib.getExe pkgs.dconf} write /org/gnome/desktop/interface/color-scheme "'prefer-light'"
+
+
# TODO: change config specialization
+
+
# Prepare laptop for wake: set full brightness and disable kbd backlight
+
${lib.getExe pkgs.brightnessctl} --class backlight set 100%
+
${lib.getExe pkgs.brightnessctl} --class leds --device "*::kbd_backlight" set 0%
+
'';
+
};
+
+
services.gammastep = {
+
enable = true;
+
tray = true;
+
provider = "geoclue2";
+
settings.general = {
+
adjustment-method = "wayland";
+
gamma = 0.8;
+
};
+
};
+
};
+
}
+95
home-manager/fragments/swaybar.nix
···
+
{ config
+
, lib
+
, pkgs
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.swaybar;
+
+
integrated-keyboard-id = "1:1:AT_Translated_Set_2_keyboard";
+
integrated-keyboard-id-bis = "1:1:kanata";
+
+
swaymsg = lib.getExe' pkgs.sway "swaymsg";
+
in
+
{
+
options.local.fragment.swaybar.enable = lib.mkEnableOption ''
+
Swaybar related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
programs.i3status-rust = {
+
enable = true;
+
+
bars.default = {
+
theme = "modern";
+
icons = "awesome6";
+
+
settings.icon_format = " <span font_family='FontAwesome6'>{icon}</span> ";
+
+
blocks = [
+
{
+
block = "custom";
+
command = ''
+
echo 󰌌 $(swaymsg --raw --type get_inputs \
+
| jq --raw-output '
+
.[]
+
| select(.identifier=="${integrated-keyboard-id}")
+
| .libinput.send_events')
+
'';
+
click = [{
+
button = "left";
+
cmd = ''
+
${swaymsg} input ${integrated-keyboard-id} events toggle;
+
${swaymsg} input ${integrated-keyboard-id-bis} events toggle
+
'';
+
update = true;
+
}];
+
interval = "once";
+
}
+
+
{
+
block = "custom";
+
command = "echo  $(${lib.getExe' pkgs.mako "makoctl"} mode)";
+
click = [{
+
button = "left";
+
# Toggle DND mode
+
cmd = "${lib.getExe' pkgs.mako "makoctl"} mode -t dnd";
+
update = true;
+
}];
+
interval = "once";
+
}
+
+
{ block = "music"; }
+
{
+
format = " 󰌌 $variant";
+
block = "keyboard_layout";
+
driver = "sway";
+
}
+
{ block = "backlight"; device = "intel_backlight"; }
+
{ block = "sound"; }
+
{ block = "battery"; }
+
{
+
block = "time";
+
interval = 60;
+
format = " $timestamp.datetime(f:'%a %d/%m %R') ";
+
}
+
];
+
};
+
};
+
+
wayland.windowManager.sway.config.bars = [
+
({
+
statusCommand = "${lib.getExe pkgs.i3status-rust} ${config.home.homeDirectory}/${config.xdg.configFile."i3status-rust/config-default.toml".target}";
+
+
hiddenState = "hide";
+
mode = "hide";
+
+
# TODO: fix color theme on the bar
+
# TODO: would be nice to have rounded corners and padding when appearing
+
+
extraConfig = "icon_theme Papirus";
+
} // config.stylix.targets.sway.exportedBarConfig)
+
];
+
};
+
}
+15 -6
home-manager/fragments/tools.nix
···
{ config
, lib
, pkgs
-
, lpkgs
, ...
}:
···
# CLIs
asciinema
calc
+
csvlens
delta
dogdns
-
du-dust
+
dust
encfs
fastfetch
fd
ffmpeg
file
fzf
+
gemini-cli
inetutils
jq
just
···
lsof
mediainfo
openssl
+
otree
ouch
parallel
+
perf
pv
restic
ripgrep
···
tlrc
tokei
trash-cli
+
uni
unzip
vlock
-
wcurl
wormhole-rs
-
]) ++ lib.optionals (!flags.onlyCached) [
-
lpkgs.otree
-
];
+
]) ++ lib.optionals (!flags.onlyCached) [ ];
+
+
programs.fish.shellAbbrs = {
+
# Use newer tools
+
clear = "#"; # <ctrl-l>
+
cat = "#"; # bat
+
rm = "#"; # trash-put
+
tr = "#"; # srgn
+
};
programs.bat = {
enable = true;
-128
home-manager/fragments/vm-bar.nix
···
-
{ config
-
, lib
-
, pkgs
-
, ...
-
}:
-
-
let
-
cfg = config.local.fragment.vm;
-
-
integrated-keyboard-id = "1:1:AT_Translated_Set_2_keyboard";
-
integrated-keyboard-id-bis = "1:1:kanata";
-
swaymsg = lib.getExe' pkgs.sway "swaymsg";
-
-
theme = config.local.colorScheme.palette;
-
in
-
{
-
config = lib.mkIf cfg.enable {
-
programs.i3status-rust = {
-
enable = true;
-
-
bars.default = {
-
theme = "modern";
-
icons = "awesome6";
-
blocks = [
-
{
-
block = "custom";
-
command = ''
-
echo 󰌌 $(swaymsg --raw --type get_inputs \
-
| jq --raw-output '
-
.[]
-
| select(.identifier=="${integrated-keyboard-id}")
-
| .libinput.send_events')
-
'';
-
click = [{
-
button = "left";
-
cmd = ''
-
${swaymsg} input ${integrated-keyboard-id} events toggle;
-
${swaymsg} input ${integrated-keyboard-id-bis} events toggle
-
'';
-
update = true;
-
}];
-
interval = "once";
-
}
-
-
{
-
block = "custom";
-
command = "echo  $(${lib.getExe' pkgs.mako "makoctl"} mode)";
-
click = [{
-
button = "left";
-
cmd = "${lib.getExe' pkgs.mako "makoctl"} mode -t dnd";
-
update = true;
-
}];
-
interval = "once";
-
}
-
-
{ block = "music"; }
-
{
-
block = "memory";
-
format = " $icon $mem_used_percents.eng(w:2) ";
-
}
-
{
-
format = " 󰌌 $variant";
-
block = "keyboard_layout";
-
driver = "sway";
-
}
-
{ block = "backlight"; device = "intel_backlight"; }
-
{ block = "sound"; }
-
{ block = "battery"; }
-
{
-
block = "time";
-
interval = 60;
-
format = " $timestamp.datetime(f:'%a %d/%m %R') ";
-
}
-
];
-
};
-
};
-
-
wayland.windowManager.sway.config.bars = [{
-
statusCommand = "${lib.getExe pkgs.i3status-rust} ${config.home.homeDirectory}/${config.xdg.configFile."i3status-rust/config-default.toml".target}";
-
hiddenState = "hide";
-
mode = "hide";
-
fonts.size = 11.0;
-
-
colors = {
-
background = "#${theme.base00}";
-
focusedBackground = "#${theme.base00}";
-
separator = "#cccccc";
-
focusedSeparator = "#cccccc";
-
statusline = "#cccccc";
-
focusedStatusline = "#cccccc";
-
-
focusedWorkspace = rec {
-
text = "#${theme.base07}";
-
background = "#${theme.base0C}";
-
border = background;
-
};
-
-
inactiveWorkspace = rec {
-
text = "#${theme.base05}";
-
background = "#${theme.base01}";
-
border = background;
-
};
-
-
activeWorkspace = rec {
-
text = "#${theme.base08}";
-
background = "#${theme.base0C}";
-
border = background;
-
};
-
-
urgentWorkspace = rec {
-
text = "#ffffff";
-
background = "#${theme.base0F}";
-
border = background;
-
};
-
-
bindingMode = rec {
-
text = "#ffffff";
-
background = "#${theme.base0F}";
-
border = background;
-
};
-
};
-
-
# Would be nice to have rounded corners and padding when appearing
-
-
extraConfig = "icon_theme Papirus";
-
}];
-
};
-
}
-141
home-manager/fragments/vm-compose.nix
···
-
{ self
-
, config
-
, lib
-
, ...
-
}:
-
-
-
let
-
inherit (self.outputs) homeManagerModules;
-
-
cfg = config.local.fragment.vm;
-
in
-
{
-
imports = [ homeManagerModules.xcompose ];
-
-
config.programs.xcompose = lib.mkIf cfg.enable {
-
enable = true;
-
includeLocaleCompose = true;
-
loadConfigInEnv = false;
-
-
sequences.Multi_key = {
-
e.grave = "è";
-
E.grave = "È";
-
e.apostrophe = "é";
-
E.apostrophe = "É";
-
a.grave = "à";
-
A.grave = "À";
-
u.grave = "ù";
-
U.grave = "Ù";
-
e.quotedbl = "ë";
-
E.quotedbl = "Ë";
-
a.quotedbl = "ä";
-
A.quotedbl = "Ä";
-
-
quotedbl.quotedbl = "¨";
-
apostrophe.apostrophe = "´";
-
-
s.s = "ß";
-
-
# Lower case [g]reek letters
-
g = {
-
a = "α";
-
b = "β";
-
g = "γ";
-
d = "δ";
-
e = "ε";
-
z = "ζ";
-
h = "η";
-
u = "θ";
-
i = "ι";
-
k = "κ";
-
l = "λ";
-
m = "μ";
-
n = "ν";
-
x = "ξ";
-
q.o = "ο";
-
p = "π";
-
r = "ρ";
-
s = "σ";
-
t = "τ";
-
y = "υ";
-
f = "φ";
-
o = "ω";
-
};
-
# Upper case [G]reek letters
-
G = {
-
A = "Α";
-
B = "Β";
-
G = "Γ";
-
D = "Δ";
-
E = "Ε";
-
Z = "Ζ";
-
H = "Η";
-
U = "Θ";
-
I = "Ι";
-
K = "Κ";
-
L = "Λ";
-
M = "Μ";
-
N = "Ν";
-
X = "Ξ";
-
Q.O = "Ο";
-
P = "Π";
-
R = "Ρ";
-
S = "Σ";
-
T = "Τ";
-
Y = "Υ";
-
F = "Φ";
-
O = "Ω";
-
};
-
-
# Math
-
l.equal = "≤";
-
g.equal = "≥";
-
s.u.m = "∑";
-
asciitilde.asciitilde = "≈";
-
-
# Math double-struck symbols
-
M = {
-
A = "𝔸";
-
B = "𝔹";
-
C = "ℂ";
-
D = "𝔻";
-
E = "𝔼";
-
F = "𝔽";
-
G = "𝔾";
-
H = "ℍ";
-
I = "𝕀";
-
J = "𝕁";
-
K = "𝕂";
-
L = "𝕃";
-
M = "𝕄";
-
N = "ℕ";
-
O = "𝕆";
-
P = "ℙ";
-
Q = "ℚ";
-
R = "ℝ";
-
S = "𝕊";
-
T = "𝕋";
-
U = "𝕌";
-
V = "𝕍";
-
X = "𝕏";
-
Y = "𝕐";
-
Z = "ℤ";
-
};
-
-
# Symbols
-
o.o = "∞";
-
-
minus.greater = "→";
-
less.minus = "←";
-
less.greater.minus = "↔";
-
-
equal.greater = "⇒";
-
less.equal = "⇐";
-
less.greater.equal = "⇔";
-
-
"0"."0" = "°";
-
minus.minus = "—";
-
};
-
};
-
}
-66
home-manager/fragments/vm-search.nix
···
-
{ config
-
, lib
-
, pkgs
-
, ...
-
}:
-
-
let
-
cfg = config.local.fragment.vm;
-
-
theme = config.local.colorScheme.palette;
-
keyValueFormat = lib.generators.toKeyValue { };
-
in
-
{
-
config = lib.mkIf cfg.enable {
-
wayland.windowManager.sway.config.menu =
-
let
-
tofi-drun = lib.getExe' pkgs.tofi "tofi-drun";
-
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
-
-
jetbrains-nerd-font-regular = "${pkgs.nerd-fonts.jetbrains-mono}/share/fonts/truetype/JetBrainsMonoNerdFont-Regular.ttf";
-
in
-
"${tofi-drun} --font ${jetbrains-nerd-font-regular} | xargs ${swaymsg} exec --";
-
-
xdg.configFile."tofi/config".text = keyValueFormat {
-
font-size = 14;
-
-
horizontal = true;
-
anchor = "top";
-
width = "100%";
-
height = 48;
-
-
outline-width = 0;
-
border-width = 0;
-
-
min-input-width = 100;
-
result-spacing = 20;
-
-
padding-top = 12;
-
padding-bottom = 12;
-
padding-left = 20;
-
padding-right = 20;
-
-
text-color = "#${theme.base06}";
-
background-color = "#${theme.base00}";
-
-
prompt-text = " ";
-
prompt-padding = 30;
-
prompt-background = "#${theme.base01}";
-
prompt-background-padding = "5, 10";
-
prompt-background-corner-radius = 5;
-
-
input-color = "#${theme.base07}";
-
input-background = "#${theme.base01}";
-
input-background-padding = "5, 10";
-
input-background-corner-radius = 5;
-
-
selection-color = "#${theme.base0E}";
-
selection-background = "#${theme.base01}";
-
selection-background-padding = "5, 10";
-
selection-background-corner-radius = 8;
-
selection-match-color = "#${theme.base08}";
-
-
clip-to-padding = false;
-
};
-
};
-
}
-383
home-manager/fragments/vm.nix
···
-
{ self
-
, config
-
, lib
-
, pkgs
-
-
, isDarwin
-
, ...
-
}:
-
-
let
-
inherit (self.outputs) homeManagerModules;
-
-
cfg = config.local.fragment.vm;
-
-
theme = config.local.colorScheme.palette;
-
cfg-sway = config.wayland.windowManager.sway.config;
-
-
workspacesRange = lib.zipListsWith (key-idx: workspace-idx: { inherit key-idx workspace-idx; }) [ 1 2 3 4 5 6 7 8 9 0 ] (lib.range 1 10);
-
in
-
{
-
imports = [
-
homeManagerModules.wl-clip-persist
-
];
-
-
options.local.fragment.vm.enable = lib.mkEnableOption ''
-
Sway related
-
'';
-
-
config = lib.mkIf cfg.enable {
-
assertions = [
-
{ assertion = !isDarwin; message = "this is a non-darwin fragment"; }
-
];
-
-
programs.swaylock = {
-
enable = true;
-
settings = {
-
daemonize = true;
-
ignore-empty-password = true;
-
show-failed-attempts = true;
-
-
image = toString ../../assets/wallpaper-binary-cloud.png;
-
-
indicator-y-position = -100;
-
indicator-x-position = 100;
-
};
-
};
-
-
programs.fish.loginShellInit = ''
-
if test (id --user $USER) -ge 1000 && test (tty) = "/dev/tty1"
-
exec sway 2> /tmp/sway.(date -u +%Y-%m-%dT%H:%M:%S).log
-
end
-
'';
-
-
services.mako = {
-
enable = true;
-
settings = {
-
font = "sans-serif 10";
-
background-color = "#${theme.base0D}";
-
text-color = "#ffffff";
-
-
icons = true;
-
-
width = 500;
-
max-visible = 3;
-
sort = "-priority";
-
-
default-timeout = 5000;
-
-
layer = "overlay";
-
-
border-size = 0;
-
border-radius = 5;
-
-
"urgency=low" = {
-
background-color = "#${theme.base0A}";
-
};
-
"urgency=critical" = {
-
background-color = "#${theme.base0F}";
-
};
-
-
"mode=dnd" = {
-
invisible = 1;
-
};
-
};
-
};
-
-
gtk = {
-
enable = true;
-
-
gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
-
-
theme = {
-
name = "Arc-Dark";
-
package = pkgs.arc-theme;
-
};
-
cursorTheme = {
-
name = "Bibata-Modern-Ice";
-
package = pkgs.bibata-cursors;
-
};
-
iconTheme = {
-
name = "Papirus";
-
package = pkgs.papirus-icon-theme;
-
};
-
};
-
-
services.swayidle =
-
let
-
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
-
loginctl = lib.getExe' pkgs.systemd "loginctl";
-
systemctl = lib.getExe' pkgs.systemd "systemctl";
-
in
-
{
-
enable = true;
-
timeouts = [
-
# TODO: this doesn't work find a way to quickly cut output when locked and idle
-
# {
-
# timeout = 10;
-
# command = "if ${pgrep} -x swaylock; then ${swaymsg} \"output * power off\"; fi";
-
# resumeCommand = "${swaymsg} \"output * power on\"";
-
# }
-
-
{
-
timeout = 60 * 5;
-
# ——————————————— Dims the screen for n seconds ↓↓ and then switch it off
-
command = ''${lib.getExe pkgs.chayang} -d${toString 10} && ${swaymsg} "output * power off"'';
-
resumeCommand = ''${swaymsg} "output * power on"'';
-
}
-
{ timeout = 60 * 10; command = "${loginctl} lock-session"; }
-
{ timeout = 60 * 15; command = "${systemctl} suspend"; }
-
];
-
events = [
-
{ event = "before-sleep"; command = "${lib.getExe pkgs.playerctl} pause"; }
-
{ event = "before-sleep"; command = "${loginctl} lock-session"; }
-
# Can be triggered with `loginctl lock-session`
-
{ event = "lock"; command = lib.getExe pkgs.swaylock; }
-
];
-
};
-
-
wayland.windowManager.sway = {
-
enable = true;
-
-
xwayland = true; # explicit, op is true by default
-
-
config = {
-
modifier = "Mod4"; # Super key
-
terminal = config.home.sessionVariables.TERMINAL;
-
-
defaultWorkspace = "workspace number 1";
-
-
left = "h";
-
down = "j";
-
up = "k";
-
right = "l";
-
-
fonts = { names = [ "sans-serif" ]; size = 11.0; };
-
-
window = {
-
titlebar = false;
-
commands = [
-
# Tag of shame
-
{
-
# Equivalent to `[shell="xwayland"] title_format "%title [XWayland]"` but for all other shells
-
criteria.shell = "^((?!xdg_shell).)*$";
-
command = ''title_format "%title <small>[%shell]</small>"'';
-
}
-
-
# Toggle floating mode for some specific windows
-
{
-
# TODO: Bitwarden window glitches on opening
-
criteria = { app_id = "^firefox$"; title = "Bitwarden Password Manager"; };
-
command = ''floating enable'';
-
}
-
{
-
# Toggles floating for every Unity window but the main one
-
# Only the main window begins with `Unity - `
-
criteria = { title = "^((?!^Unity - ).)*$"; class = "^Unity$"; instance = "^Unity$"; };
-
command = ''floating enable'';
-
}
-
-
# Inhibit IDLE when these are fullscreen
-
{ criteria.app_id = "firefox"; command = "inhibit_idle fullscreen"; }
-
{ criteria.app_id = "mpv"; command = "inhibit_idle fullscreen"; }
-
{ criteria.app_id = "spotify"; command = "inhibit_idle fullscreen"; }
-
];
-
};
-
-
focus.followMouse = false;
-
-
gaps.smartBorders = "no_gaps";
-
-
colors = {
-
background = "#${theme.base00}";
-
-
focused = {
-
background = "#285577";
-
border = "#4c7899";
-
childBorder = "#285577";
-
indicator = "#2e9ef4";
-
text = "#ffffff";
-
};
-
-
focusedInactive = {
-
background = "#5f676a";
-
border = "#333333";
-
childBorder = "#5f676a";
-
indicator = "#484e50";
-
text = "#ffffff";
-
};
-
-
placeholder = {
-
background = "#0c0c0c";
-
border = "#000000";
-
childBorder = "#0c0c0c";
-
indicator = "#000000";
-
text = "#ffffff";
-
};
-
-
unfocused = {
-
background = "#222222";
-
border = "#333333";
-
childBorder = "#222222";
-
indicator = "#292d2e";
-
text = "#888888";
-
};
-
-
urgent = {
-
background = "#900000";
-
border = "#2f343a";
-
childBorder = "#900000";
-
indicator = "#900000";
-
text = "#ffffff";
-
};
-
};
-
-
input = {
-
"type:keyboard" = {
-
xkb_layout = "us,fr(ergol),fr";
-
-
# List of all options: https://www.mankier.com/7/xkeyboard-config#Options
-
xkb_options = "grp:menu_toggle,compose:caps";
-
-
repeat_delay = toString 300;
-
repeat_rate = toString 30;
-
};
-
-
# Split keyboard also acts as a mouse
-
# "type:touchpad" = { events = "disabled_on_external_mouse"; };
-
-
# Disable touchscreen by default
-
"type:touch" = { events = "disabled"; };
-
};
-
-
output."*".bg = "#000000 solid_color";
-
-
seat = {
-
"seat0" = {
-
xcursor_theme = "Bibata-Modern-Ice";
-
# disable cursor when typing or on purpose
-
hide_cursor = "when-typing enable";
-
};
-
};
-
-
bindkeysToCode = true;
-
keybindings =
-
let
-
pamixer = lib.getExe pkgs.pamixer;
-
playerctl = lib.getExe pkgs.playerctl;
-
brightnessctl = lib.getExe pkgs.brightnessctl;
-
makoctl = lib.getExe' pkgs.mako "makoctl";
-
-
grim = lib.getExe pkgs.grim;
-
slurp = lib.getExe pkgs.slurp;
-
wl-copy = lib.getExe' pkgs.wl-clipboard "wl-copy";
-
wl-paste = lib.getExe' pkgs.wl-clipboard "wl-paste";
-
in
-
lib.foldl (acc: val: acc // val) { }
-
(map
-
(modifier: {
-
"${modifier}+Return" = "exec ${cfg-sway.terminal}";
-
"${modifier}+Shift+Return" = "exec ${lib.getExe' pkgs.nautilus "nautilus"}";
-
"${modifier}+Shift+q" = "kill";
-
"${modifier}+d" = "exec ${cfg-sway.menu}";
-
"${modifier}+Space" = "exec ${makoctl} dismiss";
-
-
"${modifier}+Escape" = "exec ${lib.getExe' pkgs.systemd "loginctl"} lock-session";
-
"${modifier}+Alt+Escape" = "exec ${pkgs.writeShellScript "lock-screenshot.sh" ''
-
tmpimg=$(${lib.getExe' pkgs.coreutils "mktemp"} /tmp/lock-bg.XXX)
-
-
# Give some time to hide the bar
-
sleep 1
-
-
${grim} $tmpimg
-
${lib.getExe pkgs.swaylock} --image $tmpimg
-
-
rm $tmpimg
-
''}";
-
-
"${modifier}+${cfg-sway.left}" = "focus left";
-
"${modifier}+${cfg-sway.down}" = "focus down";
-
"${modifier}+${cfg-sway.up}" = "focus up";
-
"${modifier}+${cfg-sway.right}" = "focus right";
-
-
"${modifier}+Shift+${cfg-sway.left}" = "move left";
-
"${modifier}+Shift+${cfg-sway.down}" = "move down";
-
"${modifier}+Shift+${cfg-sway.up}" = "move up";
-
"${modifier}+Shift+${cfg-sway.right}" = "move right";
-
"${modifier}+b" = "split vertical";
-
"${modifier}+n" = "split horizontal";
-
-
"${modifier}+Alt+${cfg-sway.left}" = "resize shrink width 60 px";
-
"${modifier}+Alt+${cfg-sway.down}" = "resize grow height 60 px";
-
"${modifier}+Alt+${cfg-sway.up}" = "resize shrink height 60 px";
-
"${modifier}+Alt+${cfg-sway.right}" = "resize grow width 60 px";
-
"${modifier}+f" = "fullscreen toggle";
-
"${modifier}+Shift+space" = "floating toggle";
-
# Change between tiling and floating focus
-
"${modifier}+Alt+space" = "focus mode_toggle";
-
"${modifier}+Alt+c" = "move position cursor";
-
"${modifier}+p" = "sticky toggle";
-
-
# Screenshotting
-
"${modifier}+s" = ''exec ${grim} -g "$(${slurp})" - | ${wl-copy}'';
-
"${modifier}+Shift+s" = "exec ${wl-paste} | ${lib.getExe pkgs.swappy} --file - --output-file - | ${wl-copy}";
-
-
# Soundcontrol Keys
-
"--locked XF86AudioPrev" = "exec ${playerctl} previous";
-
"--locked XF86AudioNext" = "exec ${playerctl} next";
-
"--locked XF86AudioPlay" = "exec ${playerctl} play-pause";
-
"--locked XF86AudioStop" = "exec ${playerctl} stop";
-
"--locked XF86AudioRaiseVolume" = "exec ${pamixer} --unmute --increase 5";
-
"--locked XF86AudioLowerVolume" = "exec ${pamixer} --unmute --decrease 5";
-
"--locked XF86AudioMute" = "exec ${pamixer} --toggle-mute";
-
"--locked XF86AudioMicMute" = "exec ${pamixer} --default-source --toggle-mute";
-
"--locked XF86MonBrightnessUp" = "exec ${brightnessctl} --exponent set 5%+";
-
"--locked XF86MonBrightnessDown" = "exec ${brightnessctl} --exponent set 5%- --min-value=1";
-
"--locked XF86TouchpadToggle" = ''input "type:touchpad" events toggle enabled disabled_on_external_mouse'';
-
}
-
// lib.listToAttrs (lib.flatten (map
-
({ key-idx, workspace-idx }: [
-
{ name = "${modifier}+${toString key-idx}"; value = "workspace number ${toString workspace-idx}"; }
-
{ name = "${modifier}+Alt+${toString key-idx}"; value = "move container to workspace number ${toString workspace-idx}"; }
-
{ name = "${modifier}+Shift+${toString key-idx}"; value = "move container to workspace number ${toString workspace-idx}; workspace number ${toString workspace-idx}"; }
-
])
-
workspacesRange))
-
) [ cfg-sway.modifier ]);
-
};
-
};
-
-
services.blueman-applet.enable = true;
-
-
services.poweralertd.enable = true;
-
-
services.darkman = {
-
enable = true;
-
settings.usegeoclue = true;
-
-
darkModeScripts.gtk-theme = ''
-
# Change system theme scheme to dark
-
${lib.getExe pkgs.dconf} write /org/gnome/desktop/interface/color-scheme "'prefer-dark'"
-
-
# Do not change brightness as I'm usually on my computer as this time
-
'';
-
-
lightModeScripts.gtk-theme = ''
-
# Change system theme scheme to light
-
${lib.getExe pkgs.dconf} write /org/gnome/desktop/interface/color-scheme "'prefer-light'"
-
-
# Prepare laptop for wake: set full brightness and disable kbd backlight
-
${lib.getExe pkgs.brightnessctl} --class backlight set 100%
-
${lib.getExe pkgs.brightnessctl} --class leds --device "*::kbd_backlight" set 0%
-
'';
-
};
-
-
services.gammastep = {
-
enable = true;
-
provider = "geoclue2";
-
settings.general = {
-
adjustment-method = "wayland";
-
gamma = 0.8;
-
};
-
};
-
};
-
}
+277
home-manager/fragments/waybar.nix
···
+
{ config
+
, lib
+
, pkgs
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.waybar;
+
+
makoctl = lib.getExe' config.services.mako.package "makoctl";
+
in
+
{
+
options.local.fragment.waybar.enable = lib.mkEnableOption ''
+
Waybar related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
stylix.targets.waybar = {
+
font = "sansSerif";
+
addCss = false;
+
};
+
+
services.playerctld.enable = true;
+
+
programs.waybar = {
+
enable = true;
+
+
settings =
+
let
+
modules-settings = {
+
"sway/workspaces" = {
+
disable-scroll = true;
+
format = "{name} {icon}";
+
format-icons = {
+
default = " ";
+
+
"1" = " ";
+
"2" = " ";
+
"3" = " ";
+
"4" = " ";
+
"9" = " ";
+
"10" = " ";
+
};
+
};
+
+
"group/misc" = {
+
orientation = "inherit";
+
modules = [
+
"custom/notifications"
+
"tray"
+
"idle_inhibitor"
+
];
+
+
drawer = {
+
transition-duration = 250;
+
transition-left-to-right = false;
+
};
+
};
+
+
"custom/notifications" = {
+
format = "{icon}";
+
format-icons = {
+
normal = " ";
+
dnd = " ";
+
};
+
tooltip = false;
+
+
interval = "once";
+
return-type = "json";
+
exec = ''${makoctl} mode | rg dnd >/dev/null; if [ $? == 0 ]; then echo '{"alt":"dnd"}'; else echo '{"alt":"normal"}'; fi'';
+
on-click = "${makoctl} mode -t dnd; pkill -SIGRTMIN+10 waybar";
+
signal = 10;
+
# rely on on click pkill signal
+
exec-on-event = false;
+
};
+
+
idle_inhibitor = {
+
format = "{icon}";
+
format-icons = {
+
activated = " ";
+
deactivated = " ";
+
};
+
tooltip = false;
+
};
+
+
tray.spacing = 10;
+
+
clock = {
+
format = "{:%d %b %H:%M}";
+
tooltip = false;
+
};
+
+
battery = {
+
states = {
+
good = 95;
+
warning = 30;
+
critical = 15;
+
};
+
+
format = "{capacity}% {icon}";
+
format-full = "{capacity}% {icon}";
+
format-charging = "{capacity}% ";
+
format-plugged = "{capacity}% ";
+
format-icons = [ " " " " " " " " " " ];
+
};
+
+
pulseaudio = {
+
scroll-step = 5;
+
tooltip = false;
+
+
format = "{volume}% {icon}{format_source}";
+
format-bluetooth = "{volume}% {icon}{format_source}";
+
format-bluetooth-muted = " {icon} {format_source}";
+
format-muted = " {format_source}";
+
format-source = "";
+
format-source-muted = "  ";
+
+
format-icons = {
+
headset = " ";
+
headphone = " ";
+
hands-free = " ";
+
phone = " ";
+
portable = " ";
+
car = " ";
+
default = [ "" " " " " ];
+
};
+
+
on-click = "pavucontrol";
+
};
+
+
mpris = {
+
format = "{title:.30} - {artist:.30}";
+
tooltip-format = "{album} ({player})";
+
};
+
+
cava = {
+
bars = 6;
+
format-icons = [ "▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" ];
+
bar_delimiter = 0;
+
hide_on_silence = true;
+
};
+
};
+
+
in
+
{
+
primary = {
+
mode = "hide";
+
ipc = true;
+
position = "bottom";
+
output = [ "eDP-1" ];
+
+
modules-left = [
+
"sway/workspaces"
+
];
+
+
modules-center = [ ];
+
+
modules-right = [
+
"cava"
+
"mpris"
+
"pulseaudio"
+
"battery"
+
"clock"
+
"group/misc"
+
];
+
} // modules-settings;
+
+
additional = {
+
mode = "hide";
+
ipc = true;
+
position = "bottom";
+
output = [
+
"DP-1"
+
"DP-2"
+
"DP-3"
+
"DP-4"
+
"HDMI-1"
+
"HDMI-2"
+
"HDMI-3"
+
"HDMI-4"
+
];
+
+
modules-left = [
+
"sway/workspaces"
+
];
+
+
modules-right = [
+
"clock"
+
"group/misc"
+
];
+
} // modules-settings;
+
};
+
+
style = ''
+
#waybar { color: @base00; }
+
tooltip { border-color: @base0D; background-color: @base00; }
+
tooltip label { color: @base05; }
+
+
#workspaces button { border-bottom: 3px solid transparent; }
+
#workspaces button.focused, workspaces button.active { border-bottom: 3px solid @base05; }
+
+
#tray { background-color: @base03; }
+
#idle_inhibitor { background-color: @base03; }
+
#custom-notifications { background-color: @base03; }
+
+
#clock { background-color: @base03; }
+
+
#battery { color: @base00; background-color: @base0D; }
+
#battery.charging { background-color: @base0E; }
+
+
#pulseaudio { color: @base00; background-color: @base09; }
+
#pulseaudio.muted { background-color: @base0C; }
+
+
#mpris { color: @base00; background-color: @base0B; }
+
+
#cava { color: @base00; background-color: @base0D; }
+
''
+
+ ''
+
* {
+
border-radius: 0;
+
}
+
+
/* Apply transparency to the bar */
+
#waybar { background: alpha(white, 0); }
+
+
/* Apply margin to all module groups */
+
.modules-left, .modules-center, .modules-right {
+
/*margin: .5rem .8rem;*/
+
}
+
+
/* Apply padding to all modules */
+
.modules-right widget .module {
+
padding: 0 1rem;
+
+
color: @base07;
+
}
+
+
/* Round first and last child of left, right and center modules. Disable rounding on the sides*/
+
.modules-left > widget:last-child .module,
+
.modules-center > widget:last-child .module/*,
+
.modules-right > widget:last-child .module*/ {
+
border-top-right-radius: 5px;
+
}
+
/*.modules-left > widget:first-child .module,*/
+
.modules-center > widget:first-child .module,
+
.modules-right > widget:first-child .module {
+
border-top-left-radius: 5px;
+
}
+
+
/* Round first and last child of workspaces. */
+
#workspaces > button:first-child {
+
/*border-top-left-radius: 5px;*/
+
}
+
#workspaces > button:last-child {
+
border-top-right-radius: 5px;
+
}
+
+
#workspaces button {
+
color: @base07;
+
background-color: @base03;
+
}
+
#workspaces button:hover {
+
color: @base07;
+
background-color: @base03;
+
}
+
#workspaces button.urgent { color: @base08; }
+
'';
+
};
+
+
wayland.windowManager.sway.config.bars = [{
+
command = lib.getExe pkgs.waybar;
+
+
mode = "hide";
+
hiddenState = "hide";
+
}];
+
};
+
}
+3 -1
home-manager/fragments/xdg-mime.nix
···
{ assertion = lib.lists.count (drv: (drv.pname or "") == pkgs.nautilus.pname) config.home.packages > 0; message = "`xdg-mime` fragment depends on `nautilus` program"; }
];
+
xdg.enable = true;
+
xdg.mimeApps = {
enable = true;
defaultApplications =
let
files = [ "org.gnome.Nautilus.desktop" ];
-
browser = [ "firefox.desktop" ];
+
browser = [ "zen-beta.desktop" ];
images = [ "imv.desktop" ];
in
{
+30
home-manager/fragments/zed.nix
···
+
{ lib
+
, config
+
, upkgs
+
, ...
+
}:
+
+
let
+
cfg = config.local.fragment.zed;
+
in
+
{
+
options.local.fragment.zed.enable = lib.mkEnableOption ''
+
Zed related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
programs.zed-editor = {
+
enable = true;
+
package = upkgs.zed-editor;
+
+
userSettings = {
+
theme = lib.mkForce "Alabaster Dark";
+
+
helix_mode = true;
+
disable_ai = true;
+
+
autosave = "on_focus_change";
+
};
+
};
+
};
+
}
+25 -44
home-manager/profiles/desktop.nix
···
-
{ self
-
, config
-
, llib
+
{ config
, pkgs
, isDarwin
, ...
}:
-
let
-
inherit (self.outputs) homeManagerModules;
-
-
toml-format = pkgs.formats.toml { };
-
in
{
-
imports = [
-
homeManagerModules.color-scheme
-
{ config.local.colorScheme = llib.colorSchemes.oneDark; }
-
];
-
config = {
assertions = [
{ assertion = !isDarwin; message = "this is a HM non-darwin config"; }
];
local.fragment = {
-
agenix.enable = true;
-
aws.enable = true;
+
# Interface
chromium.enable = true;
+
compose-key.enable = true;
epita.enable = true;
firefox.enable = true;
-
foot.enable = true;
+
imv.enable = true;
+
kanshi.enable = true;
+
stylix.enable = true;
+
sway.enable = true;
+
thunderbird.enable = true;
+
waybar.enable = true;
+
xdg-mime.enable = true;
+
+
# Tools
+
agenix.enable = true;
+
aws.enable = true;
git.enable = true;
helix.enable = true;
-
imv.enable = true;
jujutsu.enable = true;
+
kitty.enable = true;
rust.enable = true;
shell.enable = true;
-
thunderbird.enable = true;
tools.enable = true;
-
vm.enable = true;
vscodium.enable = true;
-
xdg-mime.enable = true;
+
zed.enable = true;
zellij.enable = true;
};
home = {
sessionVariables = {
# Quick access to `~/Development` folder
-
DEV = "${config.home.homeDirectory}/Development";
+
dev = "${config.home.homeDirectory}/Development";
-
# Would love to get rid of the Desktop folder
+
# Would love to get rid of the Desktop folder ☹
XDG_DESKTOP_DIR = "$HOME";
# Makes electron apps use ozone and not crash because xwayland is not there
···
jetbrains-toolbox
spotify
-
# Game
-
superTuxKart
-
# GUIs
audacity
baobab
···
figma-linux
file-roller
gnome-disk-utility
-
# TODO: move and embed config in nix
-
halloy
-
heroic
insomnia
kicad
-
ldtk
+
legcord
libreoffice-qt
localsend
mpv
···
pavucontrol
prismlauncher
rawtherapee
-
showmethekey
simple-scan
-
sonic-pi
transmission_4-gtk
-
vesktop
wdisplays
wireshark
+
zulip
# Needed for libreoffice spellchecking
hunspell
···
programs.broot.enable = true;
-
# TODO: move out
-
programs.ssh = {
-
enable = true;
-
-
matchBlocks."weird-row-server" = {
-
hostname = "weird-row.portal.wiro.world";
-
# TODO: reduce automated load on ssh port by changing to a random port
-
# port = ""
-
};
-
};
-
programs.go = {
enable = true;
-
goPath = ".local/share/go";
+
env.GOPATH = "${config.home.homeDirectory}/.local/share/go";
};
programs.gpg = {
···
enableFishIntegration = false;
enableZshIntegration = false;
};
+
+
programs.ssh.enableDefaultConfig = false;
+
+
services.tailscale-systray.enable = true;
};
}
+2 -8
home-manager/profiles/lightweight.nix
···
{ self
, config
-
, llib
, pkgs
, isDarwin
···
}:
let
-
inherit (self.outputs) homeManagerModules;
-
-
toml-format = pkgs.formats.toml { };
+
inherit (self.inputs) stylix;
in
{
-
imports = [
-
homeManagerModules.color-scheme
-
{ config.local.colorScheme = llib.colorSchemes.oneDark; }
-
];
+
imports = [ ];
config = {
assertions = [
-8
home-manager/profiles/macintosh.nix
···
{ self
, config
-
, llib
, pkgs
, isDarwin
···
}:
let
-
inherit (self.outputs) homeManagerModules;
inherit (self.inputs) agenix;
-
-
all-secrets = import ../../secrets;
in
{
imports = [
agenix.homeManagerModules.default
{
-
age.secrets = all-secrets.home-manager;
# This allows us to decrypt user space secrets without having to use a
# passwordless ssh key as you cannot interact with age in the service.
age.identityPaths = [ "${config.home.homeDirectory}/.ssh/id_home_manager" ];
}
-
-
homeManagerModules.color-scheme
-
{ config.local.colorScheme = llib.colorSchemes.oneDark; }
];
config = {
+163
hosts/weird-row-server/authelia.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
authelia-port = 3008;
+
authelia-hostname = "auth.wiro.world";
+
+
authelia-metrics-port = 9004;
+
headscale-hostname = "headscale.wiro.world";
+
grafana-hostname = "console.net.wiro.world";
+
miniflux-hostname = "news.wiro.world";
+
in
+
{
+
config = {
+
age.secrets.authelia-jwt-secret = { file = secrets/authelia-jwt-secret.age; owner = config.services.authelia.instances.main.user; };
+
age.secrets.authelia-issuer-private-key = { file = secrets/authelia-issuer-private-key.age; owner = config.services.authelia.instances.main.user; };
+
age.secrets.authelia-storage-key = { file = secrets/authelia-storage-key.age; owner = config.services.authelia.instances.main.user; };
+
age.secrets.authelia-ldap-password = { file = secrets/authelia-ldap-password.age; owner = config.services.authelia.instances.main.user; };
+
age.secrets.authelia-smtp-password = { file = secrets/authelia-smtp-password.age; owner = config.services.authelia.instances.main.user; };
+
services.authelia.instances.main = {
+
enable = true;
+
+
secrets = {
+
jwtSecretFile = config.age.secrets.authelia-jwt-secret.path;
+
oidcIssuerPrivateKeyFile = config.age.secrets.authelia-issuer-private-key.path;
+
storageEncryptionKeyFile = config.age.secrets.authelia-storage-key.path;
+
};
+
environmentVariables = {
+
AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = config.age.secrets.authelia-ldap-password.path;
+
AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = config.age.secrets.authelia-smtp-password.path;
+
};
+
settings = {
+
server.address = "localhost:${toString authelia-port}";
+
storage.local.path = "/var/lib/authelia-main/db.sqlite3";
+
telemetry.metrics = {
+
enabled = true;
+
address = "tcp://:${toString authelia-metrics-port}/metrics";
+
};
+
+
session = {
+
cookies = [{
+
domain = "wiro.world";
+
authelia_url = "https://${authelia-hostname}";
+
default_redirection_url = "https://wiro.world";
+
}];
+
};
+
+
authentication_backend.ldap = {
+
address = "ldap://localhost:3890";
+
timeout = "5m"; # replace with systemd dependency
+
+
user = "uid=authelia,ou=people,dc=wiro,dc=world";
+
# Set in `AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE`.
+
# password = "";
+
+
base_dn = "dc=wiro,dc=world";
+
users_filter = "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))";
+
additional_users_dn = "ou=people";
+
groups_filter = "(&(member={dn})(objectClass=groupOfNames))";
+
additional_groups_dn = "ou=groups";
+
+
attributes = {
+
username = "uid";
+
display_name = "cn";
+
given_name = "givenname";
+
family_name = "last_name";
+
mail = "mail";
+
picture = "avatar";
+
+
group_name = "cn";
+
};
+
};
+
+
access_control = {
+
default_policy = "deny";
+
# Rules are sequential and do not apply to OIDC
+
rules = [
+
{
+
domain = "headscale.wiro.world";
+
policy = "two_factor";
+
+
}
+
{
+
domain = "news.wiro.world";
+
policy = "one_factor";
+
+
subject = [ [ "group:miniflux" "oauth2:client:miniflux" ] ];
+
}
+
{
+
domain = "*.wiro.world";
+
policy = "two_factor";
+
}
+
];
+
};
+
+
identity_providers.oidc = {
+
enforce_pkce = "always";
+
+
authorization_policies =
+
let
+
mkStrictPolicy = policy: subject:
+
{ default_policy = "deny"; rules = [{ inherit policy subject; }]; };
+
in
+
{
+
headscale = mkStrictPolicy "two_factor" [ "group:headscale" ];
+
tailscale = mkStrictPolicy "two_factor" [ "group:headscale" ];
+
grafana = mkStrictPolicy "one_factor" [ "group:grafana" ];
+
miniflux = mkStrictPolicy "one_factor" [ "group:miniflux" ];
+
};
+
+
claims_policies.headscale = { id_token = [ "email" "name" "preferred_username" "picture" "groups" ]; };
+
+
clients = [
+
{
+
client_name = "Headscale";
+
client_id = "headscale";
+
client_secret = "$pbkdf2-sha256$310000$XY680D9gkSoWhD0UtYHNFg$ptWB3exOYCga6uq1N.oimuV3ILjK3F8lBWBpsBpibos";
+
redirect_uris = [ "https://${headscale-hostname}/oidc/callback" ];
+
authorization_policy = "headscale";
+
claims_policy = "headscale";
+
}
+
{
+
client_name = "Tailscale";
+
client_id = "tailscale";
+
client_secret = "$pbkdf2-sha256$310000$PcUaup9aWKI9ZLeCF6.avw$FpsTxkDaxcoQlBi8aIacegXpjEDiCI6nXcaHyZ2Sxyc";
+
redirect_uris = [ "https://login.tailscale.com/a/oauth_response" ];
+
authorization_policy = "tailscale";
+
}
+
{
+
client_name = "Grafana Console";
+
client_id = "grafana";
+
client_secret = "$pbkdf2-sha256$310000$UkwrqxTZodGMs9.Ca2cXAA$HCWFgQbFHGXZpuz.I3HHdkTZLUevRVGlhKEFaOlPmKs";
+
redirect_uris = [ "https://${grafana-hostname}/login/generic_oauth" ];
+
authorization_policy = "grafana";
+
}
+
{
+
client_name = "Miniflux";
+
client_id = "miniflux";
+
client_secret = "$pbkdf2-sha256$310000$uPqbWfCOBXDY6nV1vsx3uA$HOWG2hL.c/bs9Dwaee3b9DxjH7KFO.SaZMbasXV9Vdw";
+
redirect_uris = [ "https://${miniflux-hostname}/oauth2/oidc/callback" ];
+
authorization_policy = "miniflux";
+
}
+
];
+
};
+
+
notifier.smtp = {
+
address = "smtp://smtp.resend.com:2587";
+
username = "resend";
+
# Set in `AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE`.
+
# password = "";
+
sender = "authelia@wiro.world";
+
};
+
};
+
};
+
+
services.caddy = {
+
virtualHosts.${authelia-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString authelia-port}
+
'';
+
};
+
};
+
}
+143
hosts/weird-row-server/default.nix
···
+
{ self
+
, config
+
, pkgs
+
, ...
+
}:
+
+
let
+
inherit (self.inputs) srvos;
+
+
ext-if = "eth0";
+
external-ip = "91.99.55.74";
+
external-netmask = 27;
+
external-gw = "144.x.x.255";
+
external-ip6 = "2a01:4f8:c2c:76d2::1";
+
external-netmask6 = 64;
+
external-gw6 = "fe80::1";
+
+
website-hostname = "wiro.world";
+
+
static-hostname = "static.wiro.world";
+
in
+
{
+
imports = [
+
srvos.nixosModules.server
+
srvos.nixosModules.hardware-hetzner-cloud
+
srvos.nixosModules.mixins-terminfo
+
+
./authelia.nix
+
./goatcounter.nix
+
./grafana.nix
+
./headscale.nix
+
./hypixel-bank-tracker.nix
+
./lldap.nix
+
./miniflux.nix
+
./pds.nix
+
./tangled.nix
+
./thelounge.nix
+
./tuwunel.nix
+
./vaultwarden.nix
+
./warrior.nix
+
./webfinger.nix
+
];
+
+
config = {
+
boot.loader.grub.enable = true;
+
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" "ext4" ];
+
+
# Single network card is `eth0`
+
networking.usePredictableInterfaceNames = false;
+
+
networking.nameservers = [ "2001:4860:4860::8888" "2001:4860:4860::8844" ];
+
+
networking = {
+
interfaces.${ext-if} = {
+
ipv4.addresses = [{ address = external-ip; prefixLength = external-netmask; }];
+
ipv6.addresses = [{ address = external-ip6; prefixLength = external-netmask6; }];
+
};
+
defaultGateway = { interface = ext-if; address = external-gw; };
+
defaultGateway6 = { interface = ext-if; address = external-gw6; };
+
+
# Reflect firewall configuration on Hetzner
+
firewall.allowedTCPPorts = [ 22 80 443 ];
+
};
+
+
services.qemuGuest.enable = true;
+
+
services.openssh.enable = true;
+
+
# age.secrets.tailscale-authkey.file = secrets/tailscale-authkey.age;
+
services.tailscale = {
+
enable = true;
+
extraSetFlags = [ "--advertise-exit-node" ];
+
# authKeyFile = config.age.secrets.tailscale-authkey.path;
+
authKeyParameters = {
+
baseURL = "https://headscale.wiro.world";
+
ephemeral = true;
+
preauthorized = true;
+
};
+
};
+
+
security.sudo.wheelNeedsPassword = false;
+
+
local.fragment.nix.enable = true;
+
+
programs.fish.enable = true;
+
+
services.fail2ban = {
+
enable = true;
+
+
maxretry = 5;
+
ignoreIP = [ ];
+
+
bantime = "24h";
+
bantime-increment = {
+
enable = true;
+
multipliers = "1 2 4 8 16 32 64";
+
maxtime = "168h";
+
overalljails = true;
+
};
+
+
jails = { };
+
};
+
+
age.secrets.caddy-env.file = secrets/caddy-env.age;
+
services.caddy = {
+
enable = true;
+
package = pkgs.caddy.withPlugins {
+
plugins = [
+
"github.com/caddy-dns/hetzner/v2@v2.0.0-preview-1"
+
"github.com/tailscale/caddy-tailscale@v0.0.0-20251016213337-01d084e119cb"
+
];
+
hash = "sha256-muKwDYs5Jp4ib/psZxpp1Kyfsqz6wPz/lpHFGtx67uY=";
+
};
+
+
environmentFile = config.age.secrets.caddy-env.path;
+
+
globalConfig = ''
+
tailscale {
+
# this caddy instance already proxies headscale but needs to access headscale to start
+
# control_url https://headscale.wiro.world
+
control_url http://localhost:3006
+
+
ephemeral
+
}
+
'';
+
+
virtualHosts.${website-hostname}.extraConfig =
+
# TODO: host website on server with automatic deployment
+
''
+
reverse_proxy https://mrnossiom.github.io {
+
header_up Host {http.request.host}
+
}
+
'';
+
+
virtualHosts.${static-hostname}.extraConfig = ''
+
root /var/www/static
+
file_server browse
+
'';
+
};
+
+
# TODO: use bind to declare dns records declaratively
+
};
+
}
+25
hosts/weird-row-server/goatcounter.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
goatcounter-port = 3010;
+
goatcounter-hostname = "stats.wiro.world";
+
in
+
{
+
config = {
+
services.goatcounter = {
+
enable = true;
+
+
port = goatcounter-port;
+
proxy = true;
+
extraArgs = [ "-automigrate" ];
+
};
+
+
services.caddy = {
+
virtualHosts.${goatcounter-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString config.services.goatcounter.port}
+
'';
+
};
+
};
+
}
+85
hosts/weird-row-server/grafana.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
grafana-port = 3002;
+
grafana-hostname = "console.net.wiro.world";
+
+
prometheus-port = 9001;
+
prometheus-node-exporter-port = 9002;
+
caddy-metrics-port = 2019;
+
authelia-metrics-port = 9004;
+
headscale-metrics-port = 9003;
+
in
+
{
+
config = {
+
age.secrets.grafana-oidc-secret = { file = secrets/grafana-oidc-secret.age; owner = "grafana"; };
+
services.grafana = {
+
enable = true;
+
+
settings = {
+
server = {
+
http_port = grafana-port;
+
domain = grafana-hostname;
+
root_url = "https://${grafana-hostname}";
+
};
+
+
"auth.generic_oauth" = {
+
enable = true;
+
name = "Authelia";
+
icon = "signin";
+
+
client_id = "grafana";
+
client_secret_path = config.age.secrets.grafana-oidc-secret.path;
+
auto_login = true;
+
+
scopes = [ "openid" "profile" "email" "groups" ];
+
auth_url = "https://auth.wiro.world/api/oidc/authorization";
+
token_url = "https://auth.wiro.world/api/oidc/token";
+
api_url = "https://auth.wiro.world/api/oidc/userinfo";
+
use_pkce = true;
+
};
+
};
+
};
+
+
services.prometheus = {
+
enable = true;
+
port = prometheus-port;
+
+
exporters.node = {
+
enable = true;
+
port = prometheus-node-exporter-port;
+
};
+
+
scrapeConfigs = [
+
{
+
job_name = "caddy";
+
static_configs = [{ targets = [ "localhost:${toString caddy-metrics-port}" ]; }];
+
}
+
{
+
job_name = "node-exporter";
+
static_configs = [{ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; }];
+
}
+
{
+
job_name = "headscale";
+
static_configs = [{ targets = [ "localhost:${toString headscale-metrics-port}" ]; }];
+
}
+
{
+
job_name = "authelia";
+
static_configs = [{ targets = [ "localhost:${toString authelia-metrics-port}" ]; }];
+
}
+
];
+
};
+
+
services.caddy = {
+
globalConfig = ''
+
metrics { per_host }
+
'';
+
virtualHosts."http://${grafana-hostname}".extraConfig = ''
+
bind tailscale/console
+
reverse_proxy http://localhost:${toString grafana-port}
+
'';
+
};
+
};
+
}
+84
hosts/weird-row-server/headscale.nix
···
+
{ pkgs
+
, config
+
, ...
+
}:
+
+
let
+
json-format = pkgs.formats.json { };
+
+
headscale-port = 3006;
+
headscale-derp-port = 3478;
+
headscale-hostname = "headscale.wiro.world";
+
+
headscale-metrics-port = 9003;
+
in
+
{
+
config = {
+
networking.firewall.allowedUDPPorts = [ headscale-derp-port ];
+
+
age.secrets.headscale-oidc-secret = { file = secrets/headscale-oidc-secret.age; owner = config.services.headscale.user; };
+
services.headscale = {
+
enable = true;
+
+
port = headscale-port;
+
settings = {
+
server_url = "https://${headscale-hostname}";
+
metrics_listen_addr = "127.0.0.1:${toString headscale-metrics-port}";
+
+
policy.path = json-format.generate "policy.json" {
+
acls = [
+
{
+
action = "accept";
+
src = [ "autogroup:member" ];
+
dst = [ "autogroup:self:*" ];
+
}
+
];
+
ssh = [
+
{
+
action = "accept";
+
src = [ "autogroup:member" ];
+
dst = [ "autogroup:self" ];
+
# Adding root here is privilege escalation as a feature :)
+
users = [ "autogroup:nonroot" ];
+
}
+
];
+
};
+
+
# disable TLS
+
tls_cert_path = null;
+
tls_key_path = null;
+
+
dns = {
+
magic_dns = true;
+
base_domain = "net.wiro.world";
+
+
override_local_dns = true;
+
# Quad9 nameservers
+
nameservers.global = [ "9.9.9.9" "149.112.112.112" "2620:fe::fe" "2620:fe::9" ];
+
};
+
+
oidc = {
+
only_start_if_oidc_is_available = true;
+
issuer = "https://auth.wiro.world";
+
client_id = "headscale";
+
client_secret_path = config.age.secrets.headscale-oidc-secret.path;
+
scope = [ "openid" "profile" "email" "groups" ];
+
pkce.enabled = true;
+
};
+
+
derp.server = {
+
enable = true;
+
stun_listen_addr = "0.0.0.0:${toString headscale-derp-port}";
+
};
+
};
+
};
+
# headscale only starts if oidc is available
+
systemd.services.headscale.after = [ "authelia-main.service" ];
+
+
services.caddy = {
+
virtualHosts.${headscale-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString headscale-port}
+
'';
+
};
+
};
+
}
+42
hosts/weird-row-server/hypixel-bank-tracker.nix
···
+
{ self
+
, config
+
, ...
+
}:
+
+
let
+
inherit (self.inputs) hypixel-bank-tracker;
+
+
hbt-main-port = 3013;
+
hbt-banana-port = 3014;
+
in
+
{
+
imports = [ hypixel-bank-tracker.nixosModules.default ];
+
+
config = {
+
age.secrets.hypixel-bank-tracker-main.file = secrets/hypixel-bank-tracker-main.age;
+
services.hypixel-bank-tracker.instances.main = {
+
enable = true;
+
+
port = hbt-main-port;
+
environmentFile = config.age.secrets.hypixel-bank-tracker-main.path;
+
};
+
+
age.secrets.hypixel-bank-tracker-banana.file = secrets/hypixel-bank-tracker-banana.age;
+
services.hypixel-bank-tracker.instances.banana = {
+
enable = true;
+
+
port = hbt-banana-port;
+
environmentFile = config.age.secrets.hypixel-bank-tracker-banana.path;
+
};
+
+
services.caddy = {
+
virtualHosts."hypixel-bank-tracker.xyz".extraConfig = ''
+
reverse_proxy http://localhost:${toString config.services.hypixel-bank-tracker.instances.main.port}
+
'';
+
+
virtualHosts."banana.hypixel-bank-tracker.xyz".extraConfig = ''
+
reverse_proxy http://localhost:${toString config.services.hypixel-bank-tracker.instances.banana.port}
+
'';
+
};
+
};
+
}
+39
hosts/weird-row-server/lldap.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
lldap-port = 3007;
+
lldap-hostname = "ldap.net.wiro.world";
+
in
+
{
+
config = {
+
age.secrets.lldap-env.file = secrets/lldap-env.age;
+
users.users.lldap = { isSystemUser = true; group = "lldap"; };
+
users.groups.lldap = { };
+
age.secrets.lldap-user-pass = { file = secrets/lldap-user-pass.age; owner = "lldap"; };
+
services.lldap = {
+
enable = true;
+
+
silenceForceUserPassResetWarning = true;
+
+
settings = {
+
http_url = "https://${lldap-hostname}";
+
http_port = lldap-port;
+
+
ldap_user_pass_file = config.age.secrets.lldap-user-pass.path;
+
force_ldap_user_pass_reset = false;
+
+
ldap_base_dn = "dc=wiro,dc=world";
+
};
+
environmentFile = config.age.secrets.lldap-env.path;
+
};
+
+
services.caddy = {
+
virtualHosts."http://${lldap-hostname}".extraConfig = ''
+
bind tailscale/ldap
+
reverse_proxy http://localhost:${toString config.services.lldap.settings.http_port}
+
'';
+
};
+
};
+
}
+52
hosts/weird-row-server/miniflux.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
miniflux-port = 3012;
+
miniflux-hostname = "news.wiro.world";
+
in
+
{
+
config = {
+
users.users.miniflux = { isSystemUser = true; group = "miniflux"; };
+
users.groups.miniflux = { };
+
age.secrets.miniflux-oidc-secret = { file = secrets/miniflux-oidc-secret.age; owner = "miniflux"; };
+
services.miniflux = {
+
enable = true;
+
+
createDatabaseLocally = true;
+
config = {
+
BASE_URL = "https://${miniflux-hostname}/";
+
LISTEN_ADDR = "127.0.0.1:${toString miniflux-port}";
+
CREATE_ADMIN = 0;
+
+
METRICS_COLLECTOR = 1;
+
+
OAUTH2_PROVIDER = "oidc";
+
OAUTH2_OIDC_PROVIDER_NAME = "wiro.world SSO";
+
OAUTH2_CLIENT_ID = "miniflux";
+
OAUTH2_CLIENT_SECRET_FILE = config.age.secrets.miniflux-oidc-secret.path;
+
OAUTH2_REDIRECT_URL = "https://${miniflux-hostname}/oauth2/oidc/callback";
+
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://auth.wiro.world";
+
OAUTH2_USER_CREATION = 1;
+
DISABLE_LOCAL_AUTH = 1;
+
+
RUN_MIGRATIONS = 1;
+
+
# NetNewsWire is a very good iOS oss client that integrates well
+
# https://b.j4.lc/2025/05/05/setting-up-netnewswire-with-miniflux/
+
};
+
};
+
+
services.prometheus.scrapeConfigs = [{
+
job_name = "miniflux";
+
static_configs = [{ targets = [ "localhost:${toString miniflux-port}" ]; }];
+
}];
+
+
services.caddy = {
+
virtualHosts.${miniflux-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString miniflux-port}
+
'';
+
};
+
};
+
}
+43
hosts/weird-row-server/pds.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
pds-port = 3001;
+
pds-hostname = "pds.wiro.world";
+
in
+
{
+
config = {
+
age.secrets.pds-env.file = secrets/pds-env.age;
+
services.bluesky-pds = {
+
enable = true;
+
+
settings = {
+
PDS_HOSTNAME = "pds.wiro.world";
+
PDS_PORT = pds-port;
+
# is in systemd /tmp subfolder
+
LOG_DESTINATION = "/tmp/pds.log";
+
};
+
+
environmentFiles = [
+
config.age.secrets.pds-env.path
+
];
+
};
+
+
services.caddy = {
+
globalConfig = ''
+
on_demand_tls {
+
ask http://localhost:${toString pds-port}/tls-check
+
}
+
'';
+
+
virtualHosts.${pds-hostname} = {
+
serverAliases = [ "*.${pds-hostname}" ];
+
extraConfig = ''
+
tls { on_demand }
+
reverse_proxy http://localhost:${toString config.services.bluesky-pds.settings.PDS_HOSTNAME}
+
'';
+
};
+
};
+
};
+
}
hosts/weird-row-server/secrets/authelia-issuer-private-key.age

This is a binary file and will not be displayed.

hosts/weird-row-server/secrets/authelia-jwt-secret.age

This is a binary file and will not be displayed.

hosts/weird-row-server/secrets/authelia-ldap-password.age

This is a binary file and will not be displayed.

+9
hosts/weird-row-server/secrets/authelia-smtp-password.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg 0duJYaUlZd2G3tYi7CuV+c7KNaqWusLoMpoILvaajgc
+
AnAlDVzRdeoXGXvyllhSNCoDQjZ+nucLGHCfPWR8IBQ
+
-> ssh-ed25519 SmMcWg oX82fe4sQmKyjJqv9AFRY6Bww43V/8myNRsN9/M8Sho
+
Et6ycO8hm2XV36X5q7iO+nJCtjkYoq6mDBEssrjt/70
+
-> ssh-ed25519 Q8rMFA /gU1tIVjqExV8NXB1gSDsWIXpVfxm3zPJX7xOAqeqWM
+
szrd67kHWslLO+jMCuDmzYR0LPVVzd7idgl3AKt+USU
+
--- ojxyQVhx4rX+x5gzEEx8KFiorwywqEEyTNWUJY39jIk
+
�������ş* l��1����= n�Ŏ��(� �Iamz~B����������� 鰦�.�.Z>�',p��
+11
hosts/weird-row-server/secrets/authelia-storage-key.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg PYC6LaFo/DTQlRMewqbVtS4lzVtKyuFZQSqCrQwwEyg
+
kj0sHy8IpnBsMBQy/XYtj2pLXlk6wprF3MxjFTOiZ6E
+
-> ssh-ed25519 SmMcWg rvlLGzf6D96Dh1lL8as2vjc3PB7G/86U8AR7/lAELT0
+
qcdOqVV6o+5OfJYj5pfZ62hOnrBQwY0DAeIJkLoyYss
+
-> ssh-ed25519 Q8rMFA eALgQVN5OA0EuYYEyEbFnju/Yii71e+xcs98LkXnyyo
+
Rbxu60qvXKdFaJ7lfs7LeYx37TIKYK2Gxw2QcxF3soA
+
--- ryt5q5lXn1Cyn4T6RSU1IR7dHZOTbyanaG6ZqeYYGBQ
+
�G���* \�ʕ�|���
+
�S�T���z�! �FIG͍��,��2Q��+�s�76Z�D`��Q�hM�],��E7�2<Q�
+
?ׯ�t��u\���xpe/rrR��L}��S��g�%�:�Oj����{T%h��D�~�+DЫ��W%� �ŗ�r�v$%m$
hosts/weird-row-server/secrets/caddy-env.age

This is a binary file and will not be displayed.

+27
hosts/weird-row-server/secrets/default.nix
···
+
keys:
+
let
+
inherit (keys) servers users;
+
deploy = servers ++ users;
+
in
+
{
+
# Defines `PDS_JWT_SECRET`, `PDS_ADMIN_PASSWORD`, `PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX`, `PDS_EMAIL_SMTP_URL`, `PDS_EMAIL_FROM_ADDRESS`.
+
"pds-env.age".publicKeys = deploy;
+
# Defines `LLDAP_JWT_SECRET`, `LLDAP_KEY_SEED`.
+
"lldap-env.age".publicKeys = deploy;
+
"lldap-user-pass.age".publicKeys = deploy;
+
"headscale-oidc-secret.age".publicKeys = deploy;
+
"grafana-oidc-secret.age".publicKeys = deploy;
+
"authelia-jwt-secret.age".publicKeys = deploy;
+
"authelia-issuer-private-key.age".publicKeys = deploy;
+
"authelia-storage-key.age".publicKeys = deploy;
+
"authelia-ldap-password.age".publicKeys = deploy;
+
"authelia-smtp-password.age".publicKeys = deploy;
+
"tuwunel-registration-tokens.age".publicKeys = deploy;
+
# Defines `SMTP_PASSWORD`
+
"vaultwarden-env.age".publicKeys = deploy;
+
"miniflux-oidc-secret.age".publicKeys = deploy;
+
# Defines `HYPIXEL_API_KEY`, `PROFILE_UUID`
+
"hypixel-bank-tracker-main.age".publicKeys = deploy;
+
"hypixel-bank-tracker-banana.age".publicKeys = deploy;
+
"caddy-env.age".publicKeys = deploy;
+
}
+9
hosts/weird-row-server/secrets/grafana-oidc-secret.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg 2+JZ3WMnTgnnNYmJqdqAtOsEIk9pAefHfwLcXZQpqlg
+
yE0R9b0mSzoT6mvoWUG829UmkgGkm6vg0i7WLORaTis
+
-> ssh-ed25519 SmMcWg c8goAmCIPQ5rsTwoOej9ndGc0uBpWILSn/wy6XJHK14
+
ArjlEl4hxi4N6Py1emxgxUFKvSXIwLWsy6HrWNqJUHw
+
-> ssh-ed25519 Q8rMFA t72V+A0n5Tnb0VqvBrzt3j75CbcfvQltodKMhF64SXY
+
V+Ynzd4tIUI8JPy9uyoi+frW6wJnQxDavHAqnp/lem8
+
--- mzRky/dA1MDArnDSSaGyZP9yAQgD2va4MfopbrdM0iU
+
��*�٪l����a5�QE£ uަ��"�;��3�l.!` �u� _+)$��d ��ˤ����ff�F��mѳc�a�EV��Nߧ��,�@����
hosts/weird-row-server/secrets/headscale-oidc-secret.age

This is a binary file and will not be displayed.

hosts/weird-row-server/secrets/hypixel-bank-tracker-banana.age

This is a binary file and will not be displayed.

+12
hosts/weird-row-server/secrets/hypixel-bank-tracker-main.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg B3wX5eWrSUivBKJzdiSOVvWEdGuZvGJHVDCCSFa29kw
+
F1H0QzBPS1FPvactH7z3OvR5wPdawkMzIj1awUmkrqA
+
-> ssh-ed25519 SmMcWg DtmTaO1Ox4y+AyZbOgaJU2PxMRdHloHECLOrvdI/g28
+
my6GKU1rxPyClyos0efuInWok5w3xwwoJ4p3M6roBIw
+
-> ssh-ed25519 Q8rMFA LKyAN4v78N/OcleCPuYpPlZ0se5Dmp4qiWynY4zTfDo
+
2lOqk3QF2lB/b7Md6yWq4R2jn+J3PiATIkrFUxgt104
+
-> OR`n;K-grease
+
lWGBER6K10zAcNHyiUMJAnJ84h1ppo5MJ5ztgw
+
--- abe4RLNH3d9h7UpWD3PRIBgHWagt8cU+AHIFbX1D9/E
+
�LJu���k؜��_��%��|�J]��KN��?]��tR�<�]�|���ߟ��¾FzU��������:�Y��TX����p,9v6q �7�~�y�]X���͇ǷR5՚>[������#�#�-
+
cM,1Ǜ"M��"'F�W�3o�
hosts/weird-row-server/secrets/lldap-env.age

This is a binary file and will not be displayed.

+11
hosts/weird-row-server/secrets/lldap-user-pass.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg rkX6nxV4pATfwzkzJtI08/Z0bvi0wYwnLJsppUAsz20
+
X+znUc5AKAunPqr1jdq10obvQBU+rqs/LmeQaZzI+F4
+
-> ssh-ed25519 SmMcWg xaZtLP6GOocdiMf3hgoujWigGgi7KxDUMGuPYNqS8WU
+
00Y+8L4QssKFqRlGB2e0yiv9SyoqbxeZ/lWL6DCLlpo
+
-> ssh-ed25519 Q8rMFA kHA5wVVhmpodSn3OcZuc78xttymjOoy9voa8GqIE+F8
+
a7HpZf6sjmxr49QoV9tXrATheu8u20JmKCEIkmAZdhA
+
-> U=6S`1*-grease \8na]onc
+
PP5XQ1vbpadHeiMBOkmEccTIAg
+
--- 1hkJN6ZLX8GJ8y0WuFcMEv66om+Phc0wYJFKCB8Amzg
+
�M� ��}ޘ*;f��y��]����2ef���}�d��� ���J�\��8�h��1�u� ������SHN��yS�D>W��x�J���yh������
+9
hosts/weird-row-server/secrets/miniflux-oidc-secret.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg E4UVPOuq5ZUSxGvIvr0Tod9PQRqDdqHu2Byv4fKi2io
+
FcdCyfLmRCmK5rmoLQ/m1KOJe9Etu9N/GHCM5lWCIPE
+
-> ssh-ed25519 SmMcWg wrKv3V6uSLnWQqIp65Rgi0qv7lQtyOXaxnahMo+s3EU
+
mXsJ1CbS3pzstf3xaWWF150+aXxW2kY2J5kAZWqtl+A
+
-> ssh-ed25519 Q8rMFA 91npFfTkw9Ur6aZp/pLzLUOIwwPJ9OA1peaZyTlROBU
+
12sib8HLjvgN06X6H0/AN4wMewQ8xup813DauZKQ+QY
+
--- /AGwAMAsPvvuRH6PPNrizBCsJedclYzdj6Kq4V3mx0o
+
zN��0�=�YP������rլ�!U�n;���n���/��}mCo�F��������ž!z���r������)u��o�3�>��>Z�f�񡤙1Ň ����
hosts/weird-row-server/secrets/pds-env.age

This is a binary file and will not be displayed.

+9
hosts/weird-row-server/secrets/tuwunel-registration-tokens.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 sMF1bg TVYRDtTe5khTJo0q8ShrR5o1WBrbK2htHjYCvi5QYAA
+
kx6Hke5RAZFfugR4aU28SRh4U8e4ymzeIY/+kYlAWhw
+
-> ssh-ed25519 SmMcWg AyJOM5lQHETeGiI/V5vUtu2vD6PqCZNnuTPvfnU90zE
+
9vM7/8JUbScHaeDWig16MgqtULryofSrRqhw2OMWfBs
+
-> ssh-ed25519 Q8rMFA TeUNtmHquyhhDrXf+zXY56oTGvzkhkaReIoBx5Yb+TE
+
DLfVy9cO1JrVln9CHV1ag66z2kIMrVzhcaIugLytojE
+
--- nr/3KZTVXNdemLdmp2bO2bjxKDHvcy3gezZKYN5Z1qI
+
�"��Z8��ԛ�GvJ�{��(�V9��1�N"��o���o����Х�oJ�~�1�!�}Egd�!�
hosts/weird-row-server/secrets/vaultwarden-env.age

This is a binary file and will not be displayed.

+54
hosts/weird-row-server/tangled.nix
···
+
{ self
+
, config
+
, ...
+
}:
+
+
let
+
inherit (self.inputs) tangled;
+
+
tangled-owner = "did:plc:xhgrjm4mcx3p5h3y6eino6ti";
+
tangled-knot-port = 3003;
+
tangled-knot-hostname = "knot.wiro.world";
+
tangled-spindle-port = 3004;
+
tangled-spindle-hostname = "spindle.wiro.world";
+
in
+
{
+
imports = [
+
tangled.nixosModules.knot
+
tangled.nixosModules.spindle
+
];
+
+
config = {
+
services.tangled.knot = {
+
enable = true;
+
openFirewall = true;
+
+
motd = "Welcome to @wiro.world's knot!\n";
+
server = {
+
listenAddr = "localhost:${toString tangled-knot-port}";
+
hostname = tangled-knot-hostname;
+
owner = tangled-owner;
+
};
+
};
+
+
services.tangled.spindle = {
+
enable = true;
+
+
server = {
+
listenAddr = "localhost:${toString tangled-spindle-port}";
+
hostname = tangled-spindle-hostname;
+
owner = tangled-owner;
+
};
+
};
+
+
services.caddy = {
+
virtualHosts.${tangled-knot-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString tangled-knot-port}
+
'';
+
+
virtualHosts.${tangled-spindle-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString tangled-spindle-port}
+
'';
+
};
+
};
+
}
+31
hosts/weird-row-server/thelounge.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
thelounge-port = 3005;
+
thelounge-hostname = "irc-lounge.net.wiro.world";
+
in
+
{
+
config = {
+
services.thelounge = {
+
enable = true;
+
port = thelounge-port;
+
public = false;
+
+
extraConfig = {
+
host = "127.0.0.1";
+
reverseProxy = true;
+
+
# TODO: use ldap, find a way to hide password
+
};
+
};
+
+
services.caddy = {
+
virtualHosts."http://${thelounge-hostname}".extraConfig = ''
+
bind tailscale/irc-lounge
+
reverse_proxy http://localhost:${toString config.services.thelounge.port}
+
'';
+
};
+
};
+
}
+45
hosts/weird-row-server/tuwunel.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
matrix-port = 3009;
+
matrix-hostname = "matrix.wiro.world";
+
+
website-hostname = "wiro.world";
+
in
+
{
+
config = {
+
age.secrets.tuwunel-registration-tokens = { file = secrets/tuwunel-registration-tokens.age; owner = config.services.matrix-tuwunel.user; };
+
services.matrix-tuwunel = {
+
enable = true;
+
+
settings.global = {
+
address = [ "127.0.0.1" ];
+
port = [ matrix-port ];
+
+
server_name = "wiro.world";
+
well_known = {
+
client = "https://matrix.wiro.world";
+
server = "matrix.wiro.world:443";
+
};
+
+
grant_admin_to_first_user = true;
+
new_user_displayname_suffix = "";
+
+
allow_registration = true;
+
registration_token_file = config.age.secrets.tuwunel-registration-tokens.path;
+
};
+
};
+
+
services.caddy = {
+
virtualHosts.${matrix-hostname}.extraConfig = ''
+
reverse_proxy /_matrix/* http://localhost:${toString matrix-port}
+
'';
+
+
virtualHosts.${website-hostname}.extraConfig = ''
+
reverse_proxy /.well-known/matrix/* http://localhost:${toString matrix-port}
+
'';
+
};
+
};
+
}
+38
hosts/weird-row-server/vaultwarden.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
vaultwarden-port = 3011;
+
vaultwarden-hostname = "vault.wiro.world";
+
in
+
{
+
config = {
+
age.secrets.vaultwarden-env.file = secrets/vaultwarden-env.age;
+
services.vaultwarden = {
+
enable = true;
+
+
environmentFile = config.age.secrets.vaultwarden-env.path;
+
config = {
+
ROCKET_PORT = vaultwarden-port;
+
DOMAIN = "https://${vaultwarden-hostname}";
+
SIGNUPS_ALLOWED = false;
+
ADMIN_TOKEN = "$argon2id$v=19$m=65540,t=3,p=4$YIe9wmrTsmjgZNPxe8m34O/d3XW3Fl/uZPPLQs79dAc$mjDVQSdBJqz2uBJuxtAvCIoHPzOnTDhNPuhER3dhHrY";
+
+
SMTP_HOST = "smtp.resend.com";
+
SMTP_PORT = 2465;
+
SMTP_SECURITY = "force_tls";
+
SMTP_USERNAME = "resend";
+
# SMTP_PASSWORD = ...; # Via secret env
+
SMTP_FROM = "bitwarden@wiro.world";
+
SMTP_FROM_NAME = "Bitwarden wiro.world";
+
};
+
};
+
+
services.caddy = {
+
virtualHosts.${vaultwarden-hostname}.extraConfig = ''
+
reverse_proxy http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT}
+
'';
+
};
+
};
+
}
+24
hosts/weird-row-server/warrior.nix
···
+
{ config
+
, ...
+
}:
+
+
let
+
warrior-port = 3015;
+
warrior-hostname = "warrior.net.wiro.world";
+
in
+
{
+
config = {
+
virtualisation.oci-containers.containers.archive-warrior = {
+
image = "atdr.meo.ws/archiveteam/warrior-dockerfile";
+
ports = [ "127.0.0.1:${toString warrior-port}:8001" ];
+
pull = "newer";
+
};
+
+
services.caddy = {
+
virtualHosts."http://${warrior-hostname}".extraConfig = ''
+
bind tailscale/warrior
+
reverse_proxy http://localhost:${toString warrior-port}
+
'';
+
};
+
};
+
}
+77
hosts/weird-row-server/webfinger.nix
···
+
{ pkgs
+
, config
+
, ...
+
}:
+
+
let
+
webfinger-dir = pkgs.writeTextDir ".well-known/webfinger" ''
+
{
+
"subject": "acct:milo@wiro.world",
+
"aliases": [
+
"mailto:milo@wiro.world",
+
"https://wiro.world/"
+
],
+
"links": [
+
{
+
"rel": "http://wiro.world/rel/avatar",
+
"href": "https://wiro.world/logo.jpg",
+
"type": "image/jpeg"
+
},
+
{
+
"rel": "http://webfinger.net/rel/profile-page",
+
"href": "https://wiro.world/",
+
"type": "text/html"
+
},
+
{
+
"rel": "http://openid.net/specs/connect/1.0/issuer",
+
"href": "https://auth.wiro.world"
+
}
+
]
+
}
+
'';
+
+
well-known-discord-dir = pkgs.writeTextDir ".well-known/discord" ''
+
dh=919234284ceb2aba439d15b9136073eb2308989b
+
'';
+
+
website-hostname = "wiro.world";
+
in
+
{
+
config = {
+
services.caddy = {
+
virtualHosts.${website-hostname}.extraConfig = ''
+
@webfinger {
+
path /.well-known/webfinger
+
method GET HEAD
+
query resource=acct:milo@wiro.world
+
query resource=mailto:milo@wiro.world
+
query resource=https://wiro.world
+
query resource=https://wiro.world/
+
}
+
route @webfinger {
+
header {
+
Content-Type "application/jrd+json"
+
Access-Control-Allow-Origin "*"
+
X-Robots-Tag "noindex"
+
}
+
root ${webfinger-dir}
+
file_server
+
}
+
'' +
+
''
+
@discord {
+
path /.well-known/discord
+
method GET HEAD
+
}
+
route @discord {
+
header {
+
Access-Control-Allow-Origin "*"
+
X-Robots-Tag "noindex"
+
}
+
root ${well-known-discord-dir}
+
file_server
+
}
+
'';
+
};
+
};
+
}
-37
lib/colorSchemes.nix
···
-
{
-
# Found in <https://github.com/tinted-theming/schemes/blob/spec-0.11/base24/one-dark.yaml>
-
# Transformed using `yaml2nix`
-
oneDark = {
-
name = "One Dark";
-
author = "FredHappyface (https://github.com/FredHappyface)";
-
variant = "dark";
-
# system = "base24";
-
palette = {
-
base00 = "282c34";
-
base01 = "3f4451";
-
base02 = "4f5666";
-
base03 = "545862";
-
base04 = "9196a1";
-
base05 = "abb2bf";
-
base06 = "e6e6e6";
-
base07 = "ffffff";
-
base08 = "e05561";
-
base09 = "d18f52";
-
base0A = "e6b965";
-
base0B = "8cc265";
-
base0C = "42b3c2";
-
base0D = "4aa5f0";
-
base0E = "c162de";
-
base0F = "bf4034";
-
base10 = "21252b";
-
base11 = "181a1f";
-
base12 = "ff616e";
-
base13 = "f0a45d";
-
base14 = "a5e075";
-
base15 = "4cd1e0";
-
base16 = "4dc4ff";
-
base17 = "de73ff";
-
};
-
};
-
-
}
+1 -3
lib/default.nix
···
# This flake library is available to modules via the `llib` arg
-
pkgs: {
-
colorSchemes = import ./colorSchemes.nix;
-
}
+
pkgs: { }
+12 -2
lib/flake/default.nix
···
# local packages set
lpkgs = import ../../pkgs pkgs;
# unstable nixpkgs set
-
upkgs = import unixpkgs { inherit (pkgs) system config; };
+
upkgs = import unixpkgs {
+
config = pkgs.config;
+
system = pkgs.stdenv.hostPlatform.system;
+
};
# indicates if system is darwin
isDarwin = pkgs.stdenv.isDarwin;
};
···
../../nixos/hardware/${hostName}.nix
../../nixos/profiles/${profile}.nix
];
-
networking.hostName = hostName;
+
config.networking.hostName = hostName;
+
};
+
host = hostName: {
+
imports = [
+
../../nixos/hardware/${hostName}.nix
+
../../hosts/${hostName}/default.nix
+
];
+
config.networking.hostName = hostName;
};
user = import ./user.nix;
managedDiskLayout = import ./managedDiskLayout.nix;
+1 -1
lib/flake/managedDiskLayout.nix
···
The recommended amount from RedHat is:
-
Amount of RAM Recommended swap space Recommended swap space
+
Amount of RAM Recommended swap space Recommended swap space
in the system if allowing for hibernation
—————————————— —————————————————————————— ———————————————————————————
⩽ 2 GB 2 times the amount of RAM 3 times the amount of RAM
+1
lib/flake/user.nix
···
} else {
home = "/home/${name}";
extraGroups = [
+
# TODO: remove or put under an condition
"wheel" # sudo access
"networkmanager" # needed for nm
];
-101
modules/home-manager/color-scheme.nix
···
-
{ config
-
, lib
-
, ...
-
}:
-
-
let
-
cfg = config.colorScheme;
-
-
hexColorType = with lib; mkOptionType {
-
name = "hex-color";
-
descriptionClass = "noun";
-
description = "RGB color in hex format";
-
check = x: isString x && !(hasPrefix "#" x);
-
};
-
in
-
{
-
options.local.colorScheme = with lib; {
-
slug = mkOption {
-
type = types.str;
-
example = "awesome-scheme";
-
description = ''
-
Color scheme slug (sanitized name)
-
'';
-
};
-
name = mkOption {
-
type = types.str;
-
default = "";
-
example = "Awesome Scheme";
-
description = ''
-
Color scheme (pretty) name
-
'';
-
};
-
description = mkOption {
-
type = types.str;
-
default = "";
-
example = "A very nice theme";
-
description = ''
-
Color scheme author
-
'';
-
};
-
author = mkOption {
-
type = types.str;
-
default = "";
-
example = "Gabriel Fontes (https://m7.rs)";
-
description = ''
-
Color scheme author
-
'';
-
};
-
variant = mkOption {
-
type = types.enum [ "dark" "light" ];
-
default =
-
if builtins.substring 0 1 cfg.palette.base00 < "5" then
-
"dark"
-
else
-
"light";
-
description = ''
-
Whether the scheme is dark or light
-
'';
-
};
-
-
palette = mkOption {
-
type = with types; attrsOf (
-
coercedTo str (removePrefix "#") hexColorType
-
);
-
default = { };
-
example = literalExpression ''
-
{
-
base00 = "002635";
-
base01 = "00384d";
-
base02 = "517F8D";
-
base03 = "6C8B91";
-
base04 = "869696";
-
base05 = "a1a19a";
-
base06 = "e6e6dc";
-
base07 = "fafaf8";
-
base08 = "ff5a67";
-
base09 = "f08e48";
-
base0A = "ffcc1b";
-
base0B = "7fc06e";
-
base0C = "14747e";
-
base0D = "5dd7b9";
-
base0E = "9a70a4";
-
base0F = "c43060";
-
}
-
'';
-
description = ''
-
Atribute set of hex colors.
-
-
These are usually base00-base0F, but you may use any name you want.
-
For example, these can have meaningful names (bg, fg), or be base24.
-
-
The colorschemes provided by nix-colors follow the base16 standard.
-
Some might leverage base24 and have 24 colors, but these can be safely
-
used as if they were base16.
-
-
You may include a leading #, but it will be stripped when accessed from
-
config.colorscheme.palette.
-
'';
-
};
-
};
-
}
+2 -4
modules/home-manager/default.nix
···
{
-
color-scheme = import ./color-scheme.nix;
-
wakatime = import ./wakatime.nix;
-
wl-clip-persist = import ./wl-clip-persist.nix;
-
xcompose = import ./xcompose.nix;
+
wakatime = ./wakatime.nix;
+
xcompose = ./xcompose.nix;
}
-99
modules/home-manager/wl-clip-persist.nix
···
-
{ config
-
, lib
-
, pkgs
-
, ...
-
}:
-
-
let
-
cfg = config.services.wl-clip-persist;
-
in
-
{
-
options.services.wl-clip-persist = with lib; {
-
enable = mkEnableOption "";
-
-
package = mkPackageOption pkgs "wl-clip-persist" { };
-
-
clipboard = mkOption {
-
description = "The clipboard type to operate on";
-
default = "regular";
-
type = types.enum [ "regular" "primary" "both" ];
-
};
-
-
display = mkOption {
-
description = "The wayland display to operate on";
-
default = null;
-
type = types.nullOr types.str;
-
};
-
-
ignoreEventOnError = mkOption {
-
description = "Only handle selection events where no error occurred";
-
default = null;
-
type = types.nullOr types.bool;
-
};
-
-
allMimeTypeRegex = mkOption {
-
description = "Only handle selection events where all offered MIME types have a match for the regex";
-
default = null;
-
type = types.nullOr types.str;
-
};
-
-
interruptOldClipboardRequests = mkOption {
-
description = "Interrupt trying to send the old clipboard to other programs when the clipboard has been updated";
-
default = null;
-
type = types.nullOr types.bool;
-
};
-
-
selectionSizeLimit = mkOption {
-
description = "Only handle selection events whose total data size does not exceed the size limit";
-
default = null;
-
type = types.nullOr types.int;
-
};
-
-
readTimeout = mkOption {
-
description = "Timeout for trying to get the current clipboard";
-
default = 500;
-
type = types.int;
-
};
-
-
ignoreEventOnTimeout = mkOption {
-
description = "Only handle selection events where no timeout occurred";
-
default = null;
-
type = types.nullOr types.bool;
-
};
-
-
writeTimeout = mkOption {
-
description = "Timeout for trying to send the current clipboard to other programs";
-
default = 3000;
-
type = types.int;
-
};
-
};
-
-
config = lib.mkIf cfg.enable {
-
systemd.user.services.wl-clip-persist = {
-
Unit = {
-
Description = "wl-clip-persist system service";
-
PartOf = [ "graphical-session.target" ];
-
BindsTo = [ "graphical-session.target" ];
-
};
-
-
Service = {
-
Type = "simple";
-
ExecStart = "${lib.getExe cfg.package} ${lib.cli.toGNUCommandLineShell {} {
-
clipboard = cfg.clipboard;
-
display = cfg.display;
-
ignore-event-on-error = cfg.ignoreEventOnError;
-
all-mime-type-regex = cfg.allMimeTypeRegex;
-
interrupt-old-clipboard-requests = cfg.interruptOldClipboardRequests;
-
selection-size-limit = cfg.selectionSizeLimit;
-
read-timeout = cfg.readTimeout;
-
ignore-event-on-timeout = cfg.ignoreEventOnTimeout;
-
write-timeout = cfg.writeTimeout;
-
}}";
-
Restart = "on-failure";
-
TimeoutStopSec = 15;
-
};
-
-
Install.WantedBy = lib.mkDefault [ "graphical-session.target" ];
-
};
-
};
-
}
+2 -2
modules/home-manager/xcompose.nix
···
loadConfigInEnv = mkOption {
description = ''
Load the XCompose file by passing the `XCOMPOSEFILE` environment variable instead of linking to ~/.XCompose.
-
+
That is nice to avoid cluttering the HOME directory, it's preferable to disable it when experimenting
-
with your compose config to reload faster than having to reload your VM
+
with your compose config to reload faster than having to reload your VM.
'';
default = true;
type = types.bool;
-1
modules/nixos/default.nix
···
{
-
geoclue2 = ./geoclue2.nix;
logiops = ./logiops.nix;
}
-324
modules/nixos/geoclue2.nix
···
-
# Adapted from the original nixpkgs repo
-
#
-
# It supports static location fallback. This is a workaround waiting for an
-
# alternative to MLS (Mozilla Location Services).
-
-
# Target interface to manage the static file would be:
-
# static = {
-
# latitude = 48.8;
-
# logitude = 2.3;
-
# };
-
#
-
# I spent way too much time getting this to work with a submodule.
-
-
{ config
-
, lib
-
, pkgs
-
, ...
-
}:
-
-
let
-
package = pkgs.geoclue2.override { withDemoAgent = config.services.geoclue2.enableDemoAgent; };
-
-
cfg = config.services.geoclue2;
-
-
defaultWhitelist = [ "gnome-shell" "io.elementary.desktop.agent-geoclue2" ];
-
-
appConfigModule = lib.types.submodule ({ name, ... }: with lib; {
-
options = {
-
desktopID = mkOption {
-
type = types.str;
-
description = "Desktop ID of the application.";
-
};
-
-
isAllowed = mkOption {
-
type = types.bool;
-
description = ''
-
Whether the application will be allowed access to location information.
-
'';
-
};
-
-
isSystem = mkOption {
-
type = types.bool;
-
description = ''
-
Whether the application is a system component or not.
-
'';
-
};
-
-
users = mkOption {
-
type = types.listOf types.str;
-
default = [ ];
-
description = ''
-
List of UIDs of all users for which this application is allowed location
-
info access, Defaults to an empty string to allow it for all users.
-
'';
-
};
-
};
-
-
config.desktopID = mkDefault name;
-
});
-
-
# staticModule = types.submodule ({ name, ... }: {
-
# options = {
-
# latitude = mkOption {
-
# type = types.float;
-
# example = 40.6893129;
-
# };
-
-
# longitude = mkOption {
-
# type = types.float;
-
# example = -74.0445531;
-
# };
-
-
# altitude = mkOption {
-
# type = types.float;
-
# default = 0;
-
# example = 96;
-
# };
-
-
# accuracyRadius = mkOption {
-
# type = types.float;
-
# default = 0;
-
# example = 1.83;
-
# };
-
# };
-
# });
-
-
appConfigToINICompatible = _: { desktopID, isAllowed, isSystem, users, ... }: {
-
name = desktopID;
-
value = {
-
allowed = isAllowed;
-
system = isSystem;
-
users = lib.concatStringsSep ";" users;
-
};
-
};
-
-
in
-
{
-
disabledModules = [ "services/desktops/geoclue2.nix" ];
-
-
options.services.geoclue2 = with lib; {
-
enable = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Whether to enable GeoClue 2 daemon, a DBus service
-
that provides location information for accessing.
-
'';
-
};
-
-
enableDemoAgent = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to use the GeoClue demo agent. This should be
-
overridden by desktop environments that provide their own
-
agent.
-
'';
-
};
-
-
enableNmea = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to fetch location from NMEA sources on local network.
-
'';
-
};
-
-
enable3G = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to enable 3G source.
-
'';
-
};
-
-
enableCDMA = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to enable CDMA source.
-
'';
-
};
-
-
enableModemGPS = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to enable Modem-GPS source.
-
'';
-
};
-
-
enableWifi = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Whether to enable WiFi source.
-
'';
-
};
-
-
geoProviderUrl = mkOption {
-
type = types.str;
-
default = "https://location.services.mozilla.com/v1/geolocate?key=geoclue";
-
example = "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_KEY";
-
description = ''
-
The url to the wifi GeoLocation Service.
-
'';
-
};
-
-
submitData = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Whether to submit data to a GeoLocation Service.
-
'';
-
};
-
-
submissionUrl = mkOption {
-
type = types.str;
-
default = "https://location.services.mozilla.com/v1/submit?key=geoclue";
-
description = ''
-
The url to submit data to a GeoLocation Service.
-
'';
-
};
-
-
submissionNick = mkOption {
-
type = types.str;
-
default = "geoclue";
-
description = ''
-
A nickname to submit network data with.
-
Must be 2-32 characters long.
-
'';
-
};
-
-
appConfig = mkOption {
-
type = types.attrsOf appConfigModule;
-
default = { };
-
example = {
-
"com.github.app" = {
-
isAllowed = true;
-
isSystem = true;
-
users = [ "300" ];
-
};
-
};
-
description = ''
-
Specify extra settings per application.
-
'';
-
};
-
-
# static = mkOption {
-
# type = types.nullOr (types.attrsOf staticModule);
-
# default = null;
-
# description = ''
-
# Add a fallback location that will be overriden by other location services
-
# '';
-
# };
-
-
staticFile = mkOption {
-
type = types.nullOr (types.str);
-
default = null;
-
description = ''
-
Add a fallback location that will be overriden by other location services
-
'';
-
};
-
};
-
-
config = lib.mkIf cfg.enable {
-
environment.systemPackages = [ package ];
-
-
services.dbus.packages = [ package ];
-
-
systemd.packages = [ package ];
-
-
# we cannot use DynamicUser as we need the the geoclue user to exist for the
-
# dbus policy to work
-
users = {
-
users.geoclue = {
-
isSystemUser = true;
-
home = "/var/lib/geoclue";
-
group = "geoclue";
-
description = "Geoinformation service";
-
};
-
-
groups.geoclue = { };
-
};
-
-
systemd.services.geoclue = {
-
wants = lib.optionals cfg.enableWifi [ "network-online.target" ];
-
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
-
# restart geoclue service when the configuration changes
-
restartTriggers = [
-
config.environment.etc."geoclue/geoclue.conf".source
-
];
-
serviceConfig.StateDirectory = "geoclue";
-
};
-
-
# this needs to run as a user service, since it's associated with the
-
# user who is making the requests
-
systemd.user.services = lib.mkIf cfg.enableDemoAgent {
-
geoclue-agent = {
-
description = "Geoclue agent";
-
# this should really be `partOf = [ "geoclue.service" ]`, but
-
# we can't be part of a system service, and the agent should
-
# be okay with the main service coming and going
-
wantedBy = [ "default.target" ];
-
wants = lib.optionals cfg.enableWifi [ "network-online.target" ];
-
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
-
unitConfig.ConditionUser = "!@system";
-
serviceConfig = {
-
Type = "exec";
-
ExecStart = "${package}/libexec/geoclue-2.0/demos/agent";
-
Restart = "on-failure";
-
PrivateTmp = true;
-
};
-
};
-
};
-
-
services.geoclue2.appConfig = {
-
epiphany = { isAllowed = true; isSystem = false; };
-
firefox = { isAllowed = true; isSystem = false; };
-
};
-
-
environment.etc."geoclue/geoclue.conf".text =
-
lib.generators.toINI { } ({
-
agent = {
-
whitelist = lib.concatStringsSep ";"
-
(lib.optional cfg.enableDemoAgent "geoclue-demo-agent" ++ defaultWhitelist);
-
};
-
network-nmea = {
-
enable = cfg.enableNmea;
-
};
-
"3g" = {
-
enable = cfg.enable3G;
-
};
-
cdma = {
-
enable = cfg.enableCDMA;
-
};
-
modem-gps = {
-
enable = cfg.enableModemGPS;
-
};
-
wifi = {
-
enable = cfg.enableWifi;
-
url = cfg.geoProviderUrl;
-
submit-data = lib.boolToString cfg.submitData;
-
submission-url = cfg.submissionUrl;
-
submission-nick = cfg.submissionNick;
-
};
-
} // lib.mapAttrs' appConfigToINICompatible cfg.appConfig);
-
-
# environment.etc."geolocation" = mkIf (cfg.static != null) {
-
# text = ''
-
# ${toString cfg.static.latitude}
-
# ${toString cfg.static.longitude}
-
# ${toString cfg.static.altitude}
-
# ${toString cfg.static.accuracyRadius}
-
# '';
-
# };
-
-
environment.etc."geolocation" = lib.mkIf (cfg.staticFile != null) { text = cfg.staticFile; };
-
};
-
-
meta = with lib; {
-
maintainers = with maintainers; [ ] ++ teams.pantheon.members;
-
};
-
}
+5 -7
modules/nixos/logiops.nix
···
rendered-config = libconfig-format.generate "logid.cfg" cfg.settings;
in
{
-
options.services.logiops = with lib; {
-
enable = mkEnableOption (mdDoc "Logiops HID++ configuration");
+
options.services.logiops = {
+
enable = lib.mkEnableOption "Logiops HID++ configuration";
-
package = mkPackageOption pkgs "logiops" { };
+
package = lib.mkPackageOption pkgs "logiops_0_2_3" { };
-
settings = mkOption {
+
settings = lib.mkOption {
type = libconfig-format.type;
default = { };
example = {
···
];
}];
};
-
description = mdDoc ''
+
description = lib.mdDoc ''
Logid configuration. Refer to
[the `logiops` wiki](https://github.com/PixlOne/logiops/wiki/Configuration)
for details on supported values.
···
restartTriggers = [ rendered-config ];
};
};
-
-
meta.maintainers = with lib.maintainers; [ ckie ];
}
+3 -3
nixos/fragments/agenix.nix
···
inherit (self.inputs) agenix;
cfg = config.local.fragment.agenix;
-
all-secrets = import ../../secrets;
in
{
imports = [
···
config = lib.mkIf cfg.enable {
assertions = [
-
{ assertion = config.services.openssh.enable; message = "`agenix` fragement depends on `openssh` program"; }
+
{ assertion = config.services.openssh.enable; message = "`agenix` fragment depends on `openssh` program"; }
];
age = {
···
# be located on luks protected partitions.
# identityPaths = [ ];
-
secrets = all-secrets.nixos;
+
# Secrets are defined in the fragments that use it
+
# secrets = ...;
};
};
}
+63 -56
nixos/fragments/backup.nix
···
Backup related
'';
-
# TODO: fix module
-
config.assertions = lib.optional cfg.enable { assertion = false; message = "module is broken"; };
-
config.services.restic.backups = lib.mkIf cfg.enable {
-
# Backup documents and repos code
-
google-drive = {
-
repository = "rclone:googledrive:/Backups/${hostname}";
-
passwordFile = secrets.backup-restic-key.path;
-
rcloneConfigFile = secrets.backup-rclone-googledrive.path;
-
initialize = true;
-
paths = [
-
"/home/${mainUsername}/Documents"
-
# Equivalent of `~/Development` but needs extra handling as explained below
-
"/home/${mainUsername}/.local/backup/repos"
-
];
+
config = lib.mkIf cfg.enable {
+
# TODO: fix module
+
assertions = [{ assertion = false; message = "module is broken"; }];
-
# Extra handling for Development folder to respect `.gitignore` files.
-
#
-
# Backup folder should be stored somewhere to avoid changing ctimes
-
# which would cause otherwise unchanged files to be backed up again.
-
# Since `--link-dest` is used, file contents won't be duplicated on disk.
-
backupPrepareCommand = ''
-
# Remove stale Restic locks
-
${lib.getExe pkgs.restic} unlock || true
+
age.secrets.backup-restic-key.file = ../../secrets/backup/restic-key.age;
+
age.secrets.backup-rclone-google-drive.file = ../../secrets/backup/rclone-googledrive.age;
-
${lib.getExe pkgs.rsync} \
-
${"\\" /* Archive mode and delete files that are not in the source directory. `--mkpath` is like `mkdir`'s `-p` option */}
-
--archive --delete --mkpath \
-
${"\\" /* `:-` operator uses .gitignore files as exclude patterns */}
-
--filter=':- .gitignore' \
-
${"\\" /* Exclude nixpkgs repository because they have some weird symlink test files that break rsync */}
-
--exclude 'nixpkgs' \
-
${"\\" /* Hardlink files to avoid taking up more space */}
-
--link-dest=/home/${mainUsername}/Development \
-
/home/${mainUsername}/Development/ /home/${mainUsername}/.local/backup/repos
-
'';
+
services.restic.backups = {
+
# Backup documents and repos code
+
google-drive = {
+
repository = "rclone:googledrive:/Backups/${hostname}";
+
passwordFile = secrets.backup-restic-key.path;
+
rcloneConfigFile = secrets.backup-rclone-googledrive.path;
+
initialize = true;
+
+
paths = [
+
"/home/${mainUsername}/Documents"
+
# Equivalent of `~/Development` but needs extra handling as explained below
+
"/home/${mainUsername}/.local/backup/repos"
+
];
+
+
# Extra handling for Development folder to respect `.gitignore` files.
+
#
+
# Backup folder should be stored somewhere to avoid changing ctimes
+
# which would cause otherwise unchanged files to be backed up again.
+
# Since `--link-dest` is used, file contents won't be duplicated on disk.
+
backupPrepareCommand = ''
+
# Remove stale Restic locks
+
${lib.getExe pkgs.restic} unlock || true
+
+
${lib.getExe pkgs.rsync} \
+
${"\\" /* Archive mode and delete files that are not in the source directory. `--mkpath` is like `mkdir`'s `-p` option */}
+
--archive --delete --mkpath \
+
${"\\" /* `:-` operator uses .gitignore files as exclude patterns */}
+
--filter=':- .gitignore' \
+
${"\\" /* Exclude nixpkgs repository because they have some weird symlink test files that break rsync */}
+
--exclude 'nixpkgs' \
+
${"\\" /* Hardlink files to avoid taking up more space */}
+
--link-dest=/home/${mainUsername}/Development \
+
/home/${mainUsername}/Development/ /home/${mainUsername}/.local/backup/repos
+
'';
-
pruneOpts = [
-
"--keep-daily 7"
-
"--keep-weekly 5"
-
"--keep-yearly 10"
-
];
+
pruneOpts = [
+
"--keep-daily 7"
+
"--keep-weekly 5"
+
"--keep-yearly 10"
+
];
-
# TODO: fix config
-
timerConfig = null;
-
# timerConfig = {
-
# OnCalendar = "00:05";
-
# RandomizedDelaySec = "5h";
-
# };
-
};
+
# TODO: fix config
+
timerConfig = null;
+
# timerConfig = {
+
# OnCalendar = "00:05";
+
# RandomizedDelaySec = "5h";
+
# };
+
};
-
# Backup documents and large files
-
archaic-bak = {
-
repository = "/run/media/${mainUsername}/ArchaicBak/Backups/${hostname}";
-
passwordFile = secrets.backup-restic-key.path;
-
initialize = true;
+
# Backup documents and large files
+
archaic-bak = {
+
repository = "/run/media/${mainUsername}/ArchaicBak/Backups/${hostname}";
+
passwordFile = secrets.backup-restic-key.path;
+
initialize = true;
-
# this would fix issue that folder is created as root
-
# but we cannot access the backup key
-
user = config.local.user.username;
+
# this would fix issue that folder is created as root
+
# but we cannot access the backup key
+
user = config.local.user.username;
-
paths = [ "/home/${mainUsername}/Documents" ];
+
paths = [ "/home/${mainUsername}/Documents" ];
-
# Should only be ran manually when the backup Disk is attached
-
timerConfig = null;
+
# Should only be ran manually when the backup Disk is attached
+
timerConfig = null;
+
};
};
};
}
+1 -1
nixos/fragments/default.nix
···
./kanata
./logiops.nix
./nix.nix
-
./sddm.nix
+
./secure-boot.nix
./security.nix
./virtualisation.nix
./wireless.nix
+1 -1
nixos/fragments/kanata/arsenik.kbd.lisp
···
;; Numrow layer
(deflayer numrow
XX XX XX XX XX XX XX XX XX XX XX
-
XX XX XX XX XX XX XX XX XX XX
+
XX XX XX XX XX XX XX XX XX XX
@1 @2 @3 @4 @5 @6 @7 @8 @9 @0
XX XX XX XX XX XX XX XX XX XX XX
XX XX XX XX XX
+2 -4
nixos/fragments/logiops.nix
···
{ self
, config
, lib
-
, pkgs
, ...
}:
···
config.services.logiops = lib.mkIf cfg.enable {
enable = true;
-
package = pkgs.logiops_0_2_3;
settings =
let
cid = {
# Control IDs │ reprog? │ fn key? │ mouse key? │ gesture support?
-
leftMouse = 80; # 0x50 │ │ │ YES │
-
rightMouse = 81; # 0x51 │ │ │ YES │
+
leftMouse = 80; # 0x50 │ │ │ YES │
+
rightMouse = 81; # 0x51 │ │ │ YES │
middleMouse = 81; # 0x52 │ YES │ │ YES │ YES
back = 83; # 0x53 │ YES │ │ YES │ YES
forward = 86; # 0x56 │ YES │ │ YES │ YES
+9 -1
nixos/fragments/nix.nix
···
# Make NixOS system's legacy channels consistent with registry and flake inputs
else lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry;
-
gc = {
automatic = true;
# absolute disk space saver, if you forget to run GC
···
# avoid network calls at each nix invoation.
flake-registry = "";
+
use-xdg-base-directories = true;
+
keep-going = true;
extra-platforms = config.boot.binfmt.emulatedSystems;
···
extra-substituters = [ "https://nix-community.cachix.org" ];
extra-trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ];
};
+
};
+
+
# other disk space saver
+
services.angrr = {
+
enable = true;
+
period = "2weeks";
+
enableNixGcIntegration = true;
};
};
}
-33
nixos/fragments/sddm.nix
···
-
{ config
-
, lib
-
, pkgs
-
, lpkgs
-
, ...
-
}:
-
-
let
-
cfg = config.local.fragment.sddm;
-
in
-
-
{
-
options.local.fragment.sddm.enable = lib.mkEnableOption ''
-
SDDM related
-
'';
-
-
# Hours wasted trying to add a working SDDM theme: 3h + 3h
-
-
config = lib.mkIf cfg.enable {
-
services.displayManager.sddm = {
-
enable = true;
-
wayland.enable = true;
-
# theme = "where_is_my_sddm_theme";
-
theme = "catppuccin-mocha";
-
};
-
-
environment.systemPackages = [
-
lpkgs.where-is-my-sddm-theme
-
pkgs.catppuccin-sddm
-
];
-
};
-
}
-
+41
nixos/fragments/secure-boot.nix
···
+
{ self
+
, config
+
, lib
+
, upkgs
+
, ...
+
}:
+
+
# https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md
+
+
let
+
inherit (self.inputs) lanzaboote;
+
+
cfg = config.local.fragment.secure-boot;
+
in
+
{
+
imports = [
+
lanzaboote.nixosModules.lanzaboote
+
];
+
+
options.local.fragment.secure-boot.enable = lib.mkEnableOption ''
+
Secure boot related
+
'';
+
+
config = lib.mkIf cfg.enable {
+
boot.loader.systemd-boot.enable = lib.mkForce false;
+
+
boot.lanzaboote = {
+
enable = true;
+
pkiBundle = "/var/lib/sbctl";
+
};
+
+
boot.initrd.systemd.enable = true;
+
+
environment.systemPackages = [
+
# For debugging and troubleshooting Secure Boot
+
upkgs.sbctl
+
];
+
};
+
}
+
+
+9 -8
nixos/fragments/security.nix
···
security.rtkit.enable = true;
# Systemd Login
-
services.logind = {
-
lidSwitch = "suspend";
-
extraConfig = lib.generators.toKeyValue { } {
-
IdleAction = "lock";
-
# Don’t shutdown when power button is short-pressed
-
HandlePowerKey = "lock";
-
HandlePowerKeyLongPress = "suspend";
-
};
+
services.logind.settings.Login = {
+
HandleLidSwitch = "suspend";
+
IdleAction = "lock";
+
# Don’t shutdown when power button is short-pressed
+
HandlePowerKey = "lock";
+
HandlePowerKeyLongPress = "suspend";
};
# `swaylock` pam service must be at least declared to work properly
···
# Signing
programs.gnupg.agent.enable = true;
services.gnome.gnome-keyring.enable = true;
+
services.gnome.gcr-ssh-agent.enable = false;
# SSH
services.openssh = {
···
};
programs.ssh.startAgent = true;
+
+
services.fwupd.enable = true;
};
}
+9 -21
nixos/profiles/laptop.nix
···
-
{ self
-
, config
+
{ config
, pkgs
-
, upkgs
, ...
}:
-
let
-
inherit (self.outputs) nixosModules;
-
in
{
-
imports = [
-
# Replaces nixpkgs module with a custom one that support fallback static location
-
nixosModules.geoclue2
-
];
-
config = {
local.fragment = {
agenix.enable = true;
···
kanata.enable = true;
logiops.enable = true;
nix.enable = true;
-
sddm.enable = true;
+
secure-boot.enable = true;
security.enable = true;
virtualisation.enable = true;
wireless.enable = true;
···
kernel.sysctl."kernel.perf_event_paranoid" = -1;
kernelPackages = pkgs.linuxKernel.packages.linux_zen;
-
extraModulePackages = with config.boot.kernelPackages; [ perf xone ];
+
extraModulePackages = with config.boot.kernelPackages; [ xone ];
loader = {
systemd-boot.enable = true;
···
# Once in a while, the session stop job hangs and lasts the full default
# time (1min30). I just want to shutdown my computer please.
-
systemd.extraConfig = ''
-
DefaultTimeoutStopSec = 10s
-
'';
+
systemd.settings.Manager.DefaultTimeoutStopSec = "10s";
programs.dconf.enable = true;
···
LC_TIME = french-locale;
};
};
-
-
programs.command-not-found.enable = false;
# This is needed for services like `darkman` and `gammastep`
services.geoclue2 = {
enable = true;
-
# Fallback using custom geoclue2 module waitng for an alternative to MLS
+
# Fallback using custom geoclue2 module waiting for an alternative to MLS
# (Mozilla Location Services). See related module in repo.
# INFO: lat vvvv vvv long → Paris rough location
-
staticFile = "48.8\n2.3\n0\n0\n";
+
# staticFile = "48.8\n2.3\n0\n0\n";
};
programs.wireshark = {
···
};
users.users.${config.local.user.username}.extraGroups = [ "wireshark" "plugdev" ];
-
# This option is already filled with aliases that snowball and have
+
# This option is already filled with aliases that snowball and have
# priority on fish internal `ls` aliases
environment.shellAliases = { ls = null; ll = null; l = null; };
programs.fish.enable = true;
···
obs-pipewire-audio-capture
];
};
+
+
services.earlyoom.enable = true;
};
}
-220
nixos/profiles/server.nix
···
-
{ self
-
, config
-
, pkgs
-
, upkgs
-
, ...
-
}:
-
-
let
-
inherit (self.inputs) srvos agenix tangled;
-
-
all-secrets = import ../../secrets;
-
-
ext-if = "eth0";
-
external-ip = "91.99.55.74";
-
external-netmask = 27;
-
external-gw = "144.x.x.255";
-
external-ip6 = "2a01:4f8:c2c:76d2::1";
-
external-netmask6 = 64;
-
external-gw6 = "fe80::1";
-
-
pds-port = 3001;
-
pds-hostname = "pds.wiro.world";
-
-
tangled-owner = "did:plc:xhgrjm4mcx3p5h3y6eino6ti";
-
tangled-knot-port = 3002;
-
tangled-knot-hostname = "knot.wiro.world";
-
tangled-spindle-port = 3003;
-
tangled-spindle-hostname = "spindle.wiro.world";
-
-
grafana-port = 9000;
-
grafana-hostname = "console.wiro.world";
-
prometheus-port = 9001;
-
prometheus-node-exporter-port = 9002;
-
-
thelounge-port = 3004;
-
thelounge-hostname = "lounge.wiro.world";
-
in
-
{
-
imports = [
-
srvos.nixosModules.server
-
srvos.nixosModules.hardware-hetzner-cloud
-
srvos.nixosModules.mixins-terminfo
-
-
agenix.nixosModules.default
-
-
tangled.nixosModules.knot
-
tangled.nixosModules.spindle
-
];
-
-
config = {
-
age.secrets = all-secrets.deploy;
-
-
boot.loader.grub.enable = true;
-
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" "ext4" ];
-
-
# Single network card is `eth0`
-
networking.usePredictableInterfaceNames = false;
-
-
networking.nameservers = [ "2001:4860:4860::8888" "2001:4860:4860::8844" ];
-
-
networking = {
-
interfaces.${ext-if} = {
-
ipv4.addresses = [{ address = external-ip; prefixLength = external-netmask; }];
-
ipv6.addresses = [{ address = external-ip6; prefixLength = external-netmask6; }];
-
};
-
defaultGateway = { interface = ext-if; address = external-gw; };
-
defaultGateway6 = { interface = ext-if; address = external-gw6; };
-
-
# TODO: rely on Hetzner firewall instead?
-
# firewall.enable = false;
-
firewall.allowedTCPPorts = [ 22 80 443 ];
-
};
-
-
services.openssh.enable = true;
-
-
services.qemuGuest.enable = true;
-
-
services.fail2ban = {
-
enable = true;
-
-
maxretry = 5;
-
ignoreIP = [ ];
-
-
bantime = "24h";
-
bantime-increment = {
-
enable = true;
-
multipliers = "1 2 4 8 16 32 64";
-
maxtime = "168h";
-
overalljails = true;
-
};
-
-
jails = { };
-
};
-
-
services.tailscale.enable = true;
-
-
services.pds = {
-
enable = true;
-
package = upkgs.bluesky-pds;
-
-
settings = {
-
PDS_HOSTNAME = "pds.wiro.world";
-
PDS_PORT = pds-port;
-
# is in systemd /tmp subfolder
-
LOG_DESTINATION = "/tmp/pds.log";
-
};
-
-
environmentFiles = [
-
config.age.secrets.pds-config.path
-
];
-
};
-
-
services.caddy = {
-
enable = true;
-
package = pkgs.caddy;
-
-
globalConfig = ''
-
metrics { per_host }
-
-
on_demand_tls {
-
ask http://localhost:${toString pds-port}/tls-check
-
}
-
'';
-
-
# Grafana has its own auth
-
virtualHosts.${grafana-hostname}.extraConfig = ''
-
reverse_proxy http://localhost:${toString grafana-port}
-
'';
-
-
virtualHosts.${pds-hostname} = {
-
serverAliases = [ "*.${pds-hostname}" ];
-
extraConfig = ''
-
tls { on_demand }
-
reverse_proxy http://localhost:${toString pds-port}
-
'';
-
};
-
-
virtualHosts.${tangled-knot-hostname}.extraConfig = ''
-
reverse_proxy http://localhost:${toString tangled-knot-port}
-
'';
-
-
virtualHosts.${tangled-spindle-hostname}.extraConfig = ''
-
reverse_proxy http://localhost:${toString tangled-spindle-port}
-
'';
-
-
virtualHosts.${thelounge-hostname}.extraConfig = ''
-
reverse_proxy http://localhost:${toString thelounge-port}
-
'';
-
};
-
-
security.sudo.wheelNeedsPassword = false;
-
-
local.fragment.nix.enable = true;
-
-
programs.fish.enable = true;
-
-
services.tangled-knot = {
-
enable = true;
-
openFirewall = true;
-
-
motd = "Welcome to @wiro.world's knot!\n";
-
server = {
-
listenAddr = "localhost:${toString tangled-knot-port}";
-
hostname = tangled-knot-hostname;
-
owner = tangled-owner;
-
};
-
};
-
-
-
services.tangled-spindle = {
-
enable = true;
-
-
server = {
-
listenAddr = "localhost:${toString tangled-spindle-port}";
-
hostname = tangled-spindle-hostname;
-
owner = tangled-owner;
-
};
-
};
-
-
services.grafana = {
-
enable = true;
-
-
settings.server = {
-
http_port = grafana-port;
-
domain = grafana-hostname;
-
};
-
};
-
-
services.prometheus = {
-
enable = true;
-
port = prometheus-port;
-
-
scrapeConfigs = [
-
{
-
job_name = "caddy";
-
static_configs = [{ targets = [ "localhost:${toString 2019}" ]; }];
-
}
-
{
-
job_name = "node";
-
static_configs = [{ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; }];
-
}
-
];
-
-
exporters.node = {
-
enable = true;
-
port = prometheus-node-exporter-port;
-
};
-
};
-
-
services.thelounge = {
-
enable = true;
-
port = thelounge-port;
-
public = false;
-
extraConfig = {
-
host = "127.0.0.1";
-
reverseProxy = true;
-
};
-
};
-
};
-
}
+2 -2
overlays/patches.nix
···
src = prev.fetchFromGitHub {
owner = "mrnossiom";
repo = "swaylock";
-
rev = "5aebb558663bebb09b86d6c4ca9b760791507b88";
-
hash = "sha256-1XotT0XKoDyg7ytzoqgxdHHA64oce4b8CZU53luI5j0=";
+
rev = "1e949610081ea0788d9fba6f0d7c909d7b62e9e0";
+
hash = "sha256-3YN6n5mYB7r1Xk22AGYMusNbA6aBD6OMU3Gn9OOuS6o=";
};
});
}
+20 -11
pkgs/default.nix
···
-
{ self, system, ... }@pkgs:
+
{ self
+
+
, stdenv
+
, callPackage
+
, ...
+
}:
let
-
inherit (self.inputs) agenix git-leave helix jujutsu wakatime-ls;
+
inherit (stdenv.hostPlatform) system;
+
+
inherit (self.inputs)
+
agenix
+
git-leave
+
nix-alien
+
wakatime-ls
+
;
in
{
-
asak = pkgs.callPackage ./asak.nix { };
-
ebnfer = pkgs.callPackage ./ebnfer.nix { };
-
find-unicode = pkgs.callPackage ./find-unicode.nix { };
-
names = pkgs.callPackage ./names.nix { };
-
otree = pkgs.callPackage ./otree.nix { };
-
probe-rs-udev-rules = pkgs.callPackage ./probe-rs-udev-rules.nix { };
-
where-is-my-sddm-theme = pkgs.callPackage ./where-is-my-sddm-theme.nix { };
+
asak = callPackage ./asak.nix { };
+
ebnfer = callPackage ./ebnfer.nix { };
+
find-unicode = callPackage ./find-unicode.nix { };
+
names = callPackage ./names.nix { };
+
probe-rs-udev-rules = callPackage ./probe-rs-udev-rules.nix { };
# Import packages defined in foreign repositories
inherit (agenix.packages.${system}) agenix;
inherit (git-leave.packages.${system}) git-leave;
-
inherit (helix.packages.${system}) helix;
-
inherit (jujutsu.packages.${system}) jujutsu;
+
inherit (nix-alien.packages.${system}) nix-alien;
inherit (wakatime-ls.packages.${system}) wakatime-ls;
}
+1 -1
pkgs/find-unicode.nix
···
hash = "sha256-hfTOUrFSlqOEzh2X3SnRx4UkmgCNDDfOjUT9325XSP8=";
};
-
cargoHash = "sha256-Ap7aLgmwh1xJWUxL/PQcPo6KxlJNE47LFs+WNxLFWi8=";
+
cargoHash = "sha256-b+fRwdEI97Cljlz6r4sukPvkb9/x6UBKEhUDmLONh2w=";
meta = with lib; {
description = "Find Unicode characters, the easy way! A simple command line application to find unicode characters with minimum effort.";
-38
pkgs/otree.nix
···
-
{ lib
-
-
, stdenv
-
, rustPlatform
-
, fetchFromGitHub
-
, darwin
-
}:
-
-
rustPlatform.buildRustPackage rec {
-
pname = "otree";
-
version = "0.1.0";
-
-
src = fetchFromGitHub {
-
owner = "fioncat";
-
repo = pname;
-
# rev = "v${version}";
-
rev = "bbaf9d53659e242eb7e85517c2d8aacefcac7d25";
-
hash = "sha256-xqTfNFot8wXSTxsQVwM+4hD+z0BIbblC/lpd9uBJf8I=";
-
};
-
-
cargoLock = {
-
lockFile = "${src}/Cargo.lock";
-
outputHashes = {
-
"tui-tree-widget-0.20.0" = "sha256-/uLp63J4FoMT1rMC9cv49JAX3SuPvFWPtvdS8pspsck=";
-
};
-
};
-
-
buildInputs = [ ]
-
++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.IOKit ];
-
-
meta = with lib; {
-
description = "A command line tool to view objects (JSON/YAML/TOML) in TUI tree widget";
-
homepage = "https://github.com/fioncat/otree";
-
license = licenses.mit;
-
maintainers = with maintainers; [ mrnossiom ];
-
mainProgram = "otree";
-
};
-
}
-21
pkgs/where-is-my-sddm-theme.nix
···
-
{ stdenv
-
, fetchFromGitHub
-
}:
-
-
stdenv.mkDerivation rec {
-
pname = "where-is-my-sddm-theme";
-
version = "v1.12.0";
-
-
src = fetchFromGitHub {
-
owner = "stepanzubkov";
-
repo = "where-is-my-sddm-theme";
-
rev = version;
-
hash = "sha256-+R0PX84SL2qH8rZMfk3tqkhGWPR6DpY1LgX9bifNYCg=";
-
};
-
-
dontBuild = true;
-
installPhase = ''
-
mkdir -p $out/share/sddm/themes
-
cp -aR $src/where_is_my_sddm_theme/ $out/share/sddm/themes/
-
'';
-
}
-9
secrets/api-digital-ocean.age
···
-
age-encryption.org/v1
-
-> X25519 QjkxfMP9vtiSZ+Y/7jkOURnuAdVCtQ/Rt1FAalv9Ijs
-
f4YwmiPs/u9A0x0tQ6UNK0697l6E6FrGhmyLJOZGsmI
-
-> ssh-ed25519 SmMcWg 7U9uVnJECX84xjSV1v18pzIb7GDd1zjaLNWfx1SWFBI
-
QZq9+tEJOh9C6XOiZdg4ISE8qt6Dzw9ABKZd6XAwZkk
-
-> ssh-ed25519 Q8rMFA wSgLP9znMedYlvWIJUmm9crT6nmItaxH2ajilON45gE
-
LqWiMQ4wJVVdUQZKXrJINFvVfQAK51vd0F4ENQgnZ7Y
-
--- iGtdwVDXIMUcgytMAUDg0hvcI2mJpupSIrhEaZZxi18
-
�k�UR�H��Jr�e���]�$��U����DT���\9;`o\<N�f�N���K�M�!'���������;���}߯�L���۟:v����@׫�X/�
-9
secrets/api-gitguardian.age
···
-
age-encryption.org/v1
-
-> X25519 P02aVaHZQ2qXu3isJo+EYi3l+8ah016KyFnmSMYZjzk
-
LhVoE334CQuJQkX983mH6HH7zr1UWe3xc+Mz6O0FzDk
-
-> ssh-ed25519 SmMcWg n8gZ++y3KQag3oTL/57CX+/X1wRvDT88hKxVE0CxRVQ
-
Ntsbw27gg3qsnCsx0myrsp08Er+KDL2okMI5wsC5NPU
-
-> ssh-ed25519 Q8rMFA fiOu3mPZzZDRNCKERYeqiVt4dcR1Jbzk0BUF0h2bPCM
-
97jBhXpNGD/p6VmfOZJWn+XMdZlKv/OqbVwfUuha1Qc
-
--- Q1AjMGJdUTSjfkYBSiZBrh5ra7rhfSKW/+f4daXP1iU
-
J��n�AL�����g<�7�En��kM�tk�����c*���L��P�R���M�P��::%�x��������x��V<$�M���\�4�r����6g�r���]
+9
secrets/api-wakapi.age
···
+
age-encryption.org/v1
+
-> X25519 P3dUySI4VwJJUWjpuvnNgNOc5qm+tts7ZJuvWUYgeS4
+
kEVQQz087nplbJ9GkZUe0MqxLPwrH1T6KpsZWiZL2mo
+
-> ssh-ed25519 SmMcWg F5mQDfhuSx6OBGeIM+um+ieZcTFEKJE7lXjVT+uAnBk
+
Cy2b9Nn4ssEAtqLF5Vz3nUmmf8OXMuMWrnVcDvS3kKE
+
-> ssh-ed25519 Q8rMFA JQXHaBwrI1W+vUjShzXegUk1+Ljp3ri6LIs29koks0g
+
SU3a1I74g2lh+/cXa5tXxC5HzedLcaOdp1e7IFUb6/Y
+
--- z7a/0fV4R8019GUsAsZ5TX1g2wLl34UBHvzE/7Cz3WM
+
L٦h|� ��e�S���H����n4\̵����G͵���8ư*M`>���S� @R�p҂ �l�>�3C�
secrets/backup/rclone-googledrive.age

This is a binary file and will not be displayed.

-11
secrets/backup/restic-key.age
···
-
age-encryption.org/v1
-
-> ssh-ed25519 y5GeNA 1N1OVMREI3zSaiCLoQxMQ9Wr86qZY8VyjozUISnWCW0
-
2FN3NfQPL/kwY7aYqrVpCtmLukgr9i7kx0JGPnYhxAw
-
-> ssh-ed25519 eJgqzQ TTEr023Bnn3aoRkBa323tMiaNRdrRxyACSpx54IR9xw
-
4E1qMVjoITuAgIxU+LxOWcaifiMSW4CG9do9Difx364
-
-> ssh-ed25519 SmMcWg r5x4S4NKIChSblXmCIKOECKGyIF+nviiFH4wICWjaC4
-
yGmvndLj+skZHqXMWME3VWOM8J/FTnf/GpDx5mqmask
-
-> ssh-ed25519 Q8rMFA Qqn/Mn1LePKebEC/yVPFL8mVQ//yYI4W/A+suQ3JWxg
-
cogONQEq9n053vHfBFc+WGU34m1jrnwwvWF6VXapA2U
-
--- ikgNePR9NDxtZrxZCEhww8eMUxoo43GUq09qxNtmNOY
-
y���f�ж?�,7򻌮9���̕ JL����_�^Q�BۖN�P�ṭ��K �Di�Op��&��⁺A���O�T-�%��u'TݼVZ��>ƭ+�{}��M�B�$�����$�k(PR�r�m���LQ����=�r/���rh�]t>e��F�S/���� �����"_s'������`����-3�4@ª�E�}���Q{&.�^��'�
secrets/backup-rclone-googledrive.age

This is a binary file and will not be displayed.

+11
secrets/backup-restic-key.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 y5GeNA 1N1OVMREI3zSaiCLoQxMQ9Wr86qZY8VyjozUISnWCW0
+
2FN3NfQPL/kwY7aYqrVpCtmLukgr9i7kx0JGPnYhxAw
+
-> ssh-ed25519 eJgqzQ TTEr023Bnn3aoRkBa323tMiaNRdrRxyACSpx54IR9xw
+
4E1qMVjoITuAgIxU+LxOWcaifiMSW4CG9do9Difx364
+
-> ssh-ed25519 SmMcWg r5x4S4NKIChSblXmCIKOECKGyIF+nviiFH4wICWjaC4
+
yGmvndLj+skZHqXMWME3VWOM8J/FTnf/GpDx5mqmask
+
-> ssh-ed25519 Q8rMFA Qqn/Mn1LePKebEC/yVPFL8mVQ//yYI4W/A+suQ3JWxg
+
cogONQEq9n053vHfBFc+WGU34m1jrnwwvWF6VXapA2U
+
--- ikgNePR9NDxtZrxZCEhww8eMUxoo43GUq09qxNtmNOY
+
y���f�ж?�,7򻌮9���̕ JL����_�^Q�BۖN�P�ṭ��K �Di�Op��&��⁺A���O�T-�%��u'TݼVZ��>ƭ+�{}��M�B�$�����$�k(PR�r�m���LQ����=�r/���rh�]t>e��F�S/���� �����"_s'������`����-3�4@ª�E�}���Q{&.�^��'�
+18 -21
secrets/default.nix
···
+
keys:
+
+
let
+
inherit (keys) sessions systems users;
+
+
nixos = systems ++ users;
+
home-manager = sessions ++ users;
+
in
{
-
nixos = {
-
backup-rclone-googledrive.file = ./backup/rclone-googledrive.age;
-
backup-restic-key.file = ./backup/restic-key.age;
-
};
+
# Used in NixOS config
+
"backup-rclone-googledrive.age".publicKeys = nixos;
+
"backup-restic-key.age".publicKeys = nixos;
-
home-manager = {
-
api-crates-io.file = ./api-crates-io.age;
-
api-digital-ocean.file = ./api-digital-ocean.age;
-
api-gitguardian.file = ./api-gitguardian.age;
-
api-wakatime.file = ./api-wakatime.age;
-
};
+
# Used in Home Manager
+
"api-crates-io.age".publicKeys = home-manager;
+
"api-wakatime.age".publicKeys = home-manager;
+
"api-wakapi.age".publicKeys = home-manager;
-
deploy = {
-
# Defines `PDS_JWT_SECRET`, `PDS_ADMIN_PASSWORD`,
-
# `PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX`, `PDS_EMAIL_SMTP_URL` and
-
# `PDS_EMAIL_FROM_ADDRESS`
-
pds-config.file = ./pds-env.age;
-
};
-
-
none = {
-
pgp-ca5e.file = ./pgp-ca5e.age;
-
ssh-uxgi.file = ./ssh-uxgi.age;
-
};
+
# Not used in config but useful
+
"pgp-ca5e.age".publicKeys = users;
+
"ssh-uxgi.age".publicKeys = users;
}
+10 -10
secrets/keys.nix
···
rec {
# Machine SSH key (/etc/ssh/ssh_host_ed25519_key.pub)
-
archaic = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDuBHC0f7N0q1KRczJMoaBVdY0JFOtcpPy6WlYsoxUh";
-
neo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINR1/9o1HLnSRkXt3xxAM5So1YCCNdJpBN1leSu7giuR";
-
systems = [ archaic neo ];
+
archaic-wiro-laptop = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDuBHC0f7N0q1KRczJMoaBVdY0JFOtcpPy6WlYsoxUh";
+
neo-wiro-laptop = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINR1/9o1HLnSRkXt3xxAM5So1YCCNdJpBN1leSu7giuR";
+
systems = [ archaic-wiro-laptop neo-wiro-laptop ];
-
weird-row = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5sThvKuIj8yfeZzUPYfxWxnjTTdNtSID2OL4czE8AL";
-
servers = [ weird-row ];
+
weird-row-server = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5sThvKuIj8yfeZzUPYfxWxnjTTdNtSID2OL4czE8AL";
+
servers = [ weird-row-server ];
# Sessions specific age key (~/.ssh/id_home_manager.pub)
-
neo-milomoisson = "age1vz2zmduaqhaw5jrqh277pmp36plyth8rz5k9ccxeftfcl2nlhalqwvx5xz";
-
sessions = [ neo-milomoisson ];
+
neo-milo = "age1vz2zmduaqhaw5jrqh277pmp36plyth8rz5k9ccxeftfcl2nlhalqwvx5xz";
+
sessions = [ neo-milo ];
-
# User keys (~/.ssh/id_ed25519.pub)
-
milomoisson = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJdt7atyPTOfaBIsgDYYb0DG1yid2u78abaCDji6Uxgi";
+
# User keys (~/.ssh/id_{ed25519,ecdsa}.pub)
+
milo-ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJdt7atyPTOfaBIsgDYYb0DG1yid2u78abaCDji6Uxgi";
wirody = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdW6ijH9oTsrswUJmQBF2LQkhjrMFkJ1LktnirPuL2S";
-
users = [ milomoisson wirody ];
+
users = [ milo-ed25519 wirody ];
}
secrets/pds-env.age

This is a binary file and will not be displayed.

-24
secrets/secrets.nix
···
-
let
-
inherit (import ./keys.nix) servers sessions systems users;
-
-
nixos = systems ++ users;
-
home-manager = sessions ++ users;
-
deploy = servers ++ users;
-
in
-
{
-
# Used in NixOS config
-
"backup/rclone-googledrive.age".publicKeys = nixos;
-
"backup/restic-key.age".publicKeys = nixos;
-
-
# Used in Home Manager
-
"api-crates-io.age".publicKeys = home-manager;
-
"api-digital-ocean.age".publicKeys = home-manager;
-
"api-gitguardian.age".publicKeys = home-manager;
-
"api-wakatime.age".publicKeys = home-manager;
-
-
"pds-env.age".publicKeys = deploy;
-
-
# Not used in config but useful
-
"pgp-ca5e.age".publicKeys = users;
-
"ssh-uxgi.age".publicKeys = users;
-
}
+9 -2
secrets.nix
···
let
inherit (builtins) listToAttrs attrNames;
+
+
# Map the name and value of all items of an attrset
mapAttrs' =
f:
set:
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
+
+
keys = import ./secrets/keys.nix;
+
+
prependAttrsName = prefix: mapAttrs' (name: value: { name = prefix + name; inherit value; });
+
secretsDir = path: prependAttrsName (path + "/") ((import ./${path}/default.nix) keys);
in
-
# You can use agenix directly at repo top-level instead of having to change directory into `secrets/`
-
mapAttrs' (name: value: { name = ("secrets/" + name); inherit value; }) (import ./secrets/secrets.nix)
+
secretsDir "secrets"
+
// secretsDir "hosts/weird-row-server/secrets"
+1 -1
templates/blank/flake.nix
···
{
inputs = {
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
+1 -1
templates/c/flake.nix
···
{
inputs = {
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
+1 -1
templates/rust/flake.nix
···
{
inputs = {
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
+1 -1
templates/rust-pkg/flake.nix
···
{
inputs = {
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";