refactor(mihomo): link geodata from nixpkgs instead of seeding it by hand

`just mihomo-geo` copied geodata into the state dir so a cold start never
fetched it. tmpfiles now links v2ray-rules-dat and the DB-IP lite mmdbs
there, so geo-auto-update moves to the gateway config only.

Assisted-by: Claude Code (claude-opus-5-5)
This commit is contained in:
Ryan Yin authored and ryan4yin | 二花 committed 2026-11-01 11:55:14 -06:00
1 parent c8bbeb708d
commit be592ae75c
7 files changed
+24 -42

No files matched your search

+5 -6
View File
@@ -100,9 +100,8 @@ introduces one, and re-evaluate entries when their `Revisit` trigger comes up.
- `just niri` and `just local` activate the machine you are on through `sudo` and block on a
password prompt; `just darwin-rollback` switches the macOS generation on the machine you are on,
and a bare `sudo systemctl restart <unit>` activates a running service the same way.
`just mihomo-geo` (mihomo's state directory) and `just shoukei-home-wifi` (a persistent
NetworkManager profile) change the local machine through `sudo` too. The user runs these, not an
agent.
`just shoukei-home-wifi` (a persistent NetworkManager profile) changes the local machine through
`sudo` too. The user runs these, not an agent.
- `just shoryu`, `just shushou`, `just youko`, `just aquamarine`, `just ruby`, `just kana`,
`just lab`, `just k3s-test`, and `just col <tag>` activate systems through Colmena. Use the
narrower recipe that matches the intended host scope.
@@ -140,9 +139,9 @@ repository, and cross-link them — no need to be told.
change.
- `~/codes/nix-secrets` — the private agenix store behind `secrets/` and the `mysecrets` input:
ciphertext and recipient rules for the secrets declared here.
- `wallpapers`, `nur-ryan4yin`, `nu_scripts`, `mattpocock-skills`, `i-have-adhd` —
flake inputs from the user's own repositories; bump with `just upp <input>` after their source
changes, do not edit them from here.
- `wallpapers`, `nur-ryan4yin`, `nu_scripts`, `mattpocock-skills`, `i-have-adhd` — flake inputs from
the user's own repositories; bump with `just upp <input>` after their source changes, do not edit
them from here.
## Further Context
-27
View File
@@ -322,33 +322,6 @@ mihomo-gen:
}
print "validated -- restart: sudo systemctl restart mihomo.service"
# Seed mihomo's geodata into the service's state dir, so a cold start needs no DNS.
[linux]
[group('services')]
mihomo-geo:
#!/usr/bin/env nu
# Copy geodata in by hand, so a cold start never has to fetch it. The core
# fetches it while parsing rules, before its own DNS is up and while the link
# DNS points at it -- that fetch can only fail.
let src = ($env.HOME | path join .config mihomo)
let dst = "/var/lib/private/mihomo"
sudo mkdir -p $dst
mut seeded = []
for f in [GeoSite.dat geoip.metadb ASN.mmdb] {
let p = ($src | path join $f)
if ($p | path exists) {
sudo cp $p $dst
$seeded = ($seeded | append ($dst | path join $f))
} else {
print $"(!) ($f) is not in ($src) -- fetch it first: mihomo -t -d ($src) -f ($src)/config.yaml"
}
}
if ($seeded | is-not-empty) {
sudo chmod 644 ...$seeded
let names = ($seeded | path basename | str join ', ')
print $"seeded ($names) -- restart mihomo to pick them up"
}
# Render the mihomo config into a Clash Verge Rev local profile on macOS.
# sources.yaml comes from the encrypted dotfiles sync (nix-secrets `just restore`).
[macos]
@@ -13,10 +13,11 @@ sudo systemctl restart mihomo.service # dashboard: http://127.0.0.1:90
```
`~/.config/mihomo` holds `sources.yaml` and the generated `config.yaml`, which the service loads
through systemd `LoadCredential`; the core's own state — geodata and cache — is in
`/var/lib/private/mihomo` (`StateDirectory`, `DynamicUser`). The generator, `policy.yaml` and
`gateway-config.nu` are run from here and never copied over. `just mihomo-gen` renders the config
and validates it with the core the service runs.
through systemd `LoadCredential`; the core's own state is in `/var/lib/private/mihomo`
(`StateDirectory`, `DynamicUser`), where the module links geodata from nixpkgs (`v2ray-rules-dat`,
`dbip-country-lite`, `dbip-asn-lite`), so it updates with nixpkgs, not at runtime. The generator,
`policy.yaml` and `gateway-config.nu` are run from here and never copied over. `just mihomo-gen`
renders the config and validates it with the core the service runs.
`sources.yaml` holds everything private (subscription URLs, secret, private domains) and stays out
of the repo and the Nix store; the module loads `config.yaml` via `LoadCredential`. Generate the
@@ -69,6 +69,14 @@ in
# and fail with "Failed to set up credentials: No such file or directory".
systemd.services.mihomo.unitConfig.RequiresMountsFor = builtins.dirOf configFile;
# Geodata from nixpkgs: a cold start must not fetch it (its DNS is not up yet).
systemd.tmpfiles.settings.mihomo-geodata = {
"/var/lib/private/mihomo/GeoSite.dat"."L+".argument =
"${pkgs.v2ray-rules-dat}/share/v2ray/geosite.dat";
"/var/lib/private/mihomo/geoip.metadb"."L+".argument = pkgs.dbip-country-lite.mmdb;
"/var/lib/private/mihomo/ASN.mmdb"."L+".argument = pkgs.dbip-asn-lite.mmdb;
};
services.resolved.enable = lib.mkIf cfg.resolvedIntegration true;
networking.networkmanager =
lib.mkIf (cfg.resolvedIntegration && config.networking.networkmanager.enable)
@@ -36,6 +36,9 @@ def main [
| insert external-ui "ui"
| insert external-ui-url $UI_URL
| update secret "GATEWAY-SECRET-PLACEHOLDER"
# desktops take geodata from nixpkgs; the gateway updates its own
| insert geo-auto-update true
| insert geo-update-interval 24
# The gateway uses nftables TProxy for LAN traffic; its desktop-style TUN
# auto-route would capture the gateway's own DIRECT IPv6 dials again.
| upsert tun.enable false
@@ -549,8 +549,6 @@ def main [
"fake-ip-filter": (($priv_filters | append $policy_filters) | uniq)
}
"geodata-mode": false
"geo-auto-update": true
"geo-update-interval": 24
"geox-url": {
geoip: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat"
geosite: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat"
@@ -4,9 +4,9 @@
# rules, the rules from `sources.yaml` and the rules imported from your
# subscriptions, so this file is the tail that closes every config.
#
# GEOSITE categories come from meta-rules-dat, which the module keeps current
# (`geo-auto-update`). `mihomo -t` validates the names: `taobao`, `alipay` and
# `wechat` do not exist in it, hence the hand-written domains below.
# GEOSITE categories come from meta-rules-dat on the gateway and nixpkgs'
# v2ray-rules-dat on the desktops. `mihomo -t` validates the names: `taobao`,
# `alipay` and `wechat` do not exist in it, hence the hand-written domains below.
# Region node groups. Each entry becomes two groups offered inside PROXY:
# "<name> 自动" (url-test, lazy: only health-checked once selected) and