New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/geoip-updater: new service #16027
Conversation
By analyzing the blame information on this pull request, we identified @edolstra, @offlinehacker and @lethalman to be potential reviewers |
I guess there is little point in this service without any of the geolite-legacy users (packages) moving over to it. Hence this is WIP for now; it needs testing, community feedback and moving some packages over to use this runtime dependency, instead of using the current "geolite-legacy" Nix attribute (which breaks every month). |
My suggestions:
|
What about nix outside nixos? |
I guess we can expose the updater script to the user (make a package), so it can be run manually. |
@bjornfor Is missing adoption the only argument holding this back from merging? What about the use cases where the geolite DB is referenced in |
If people find this useful as is, I'm fine with merging (of course). |
I could use this with the graylog module, for example. |
41171ba
to
0e53d08
Compare
I noticed that the service would fail started at boot. It seems to be running before the network is up. I looked at - after = [ "network.target" ];
+ after = [ "network-online.target" "nss-lookup.target" ];
+ wants = [ "network-online.target" ]; It doesn't make a difference, it still fails. Also had a look at https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ (suggested by the man page). But not liking the options. Any ideas? I guess either I'll add a "try a few times" loop or dig into the systemd special targets and how they are implemented on NixOS. (Perhaps we have a network-online.target dependency bug?) (I added some error handling so that we'll know when the service fails.) |
@bjornfor I think
dhcpcd does not fit into this. |
3113df6
to
45082c9
Compare
{ description = "GeoIP Updater Service Timer"; | ||
partOf = [ "geoip-updater.service" ]; | ||
wantedBy = [ "timers.target" ]; | ||
timerConfig.OnCalendar = cfg.interval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid peaks on maxmind's server backend, we should use a random delay here:
RandomizedDelaySec=3600
or an Interval between updates instead of fixed dates:
OnBootSec=15min
OnUnitActiveSec=1w
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I added RandomizedDelaySec=3600.
f721512
to
666e1c4
Compare
Hm, looks like I introduced a regression when adding syslog priority levels with "logger". systemd doesn't understand which unit the messages come from. So "systemctl status geoip-updater" doesn't show any messages. But the journal contains all messages (with proper error levels). I'll see if I can make it work with "logger", or else find another solution. I really want to have "journalctl -b -perr". |
Doh, it's as simple as @danbst: Do you mind if I squash all commits into one? I'll write a small changelog in the commit message and describe your changes. |
@bjornfor |
Looks like systemd-cat is for when you want to log from a program running outside of systemd. We're a systemd service, so our output is already directed to the log. Only the priority was missing (now fixed). |
@bjornfor i'm ok |
780bba3
to
3ed23ef
Compare
Updated again. From commit message:
|
Perhaps we should bring back proxy service, that has |
a8869ac
to
240db1e
Compare
Another update:
|
Hm, I'm doing some testing and get this on rebuild
This line |
Btw, really nice log output!
|
240db1e
to
ac95f09
Compare
Another strange consequence of setting |
I noticed some timer weirdness too, with short interval. Just pushed an update with RemainAfterExit=true. I guess it's better that way. (Still, the design with the two services and the "conflict" feels a bit odd...) Is having a test for this service really needed? I was under the impression that tests couldn't use (external) networking, so either I'm wrong and we can write a test (if wanted) or else we have to write the test so that it creates a fake maxmind.com server. |
The only thing we can do with timers and short intervals is to specify in As for test, I think you're right, it will be hard to write such test. ping @kampfschlaefer for his opinion on using fake maxmind server. |
ac95f09
to
34ab4f0
Compare
(closed by accident) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using this module now on staging machine, let's see in a week how it goes. I've tested basic features (setting interval, changing database list, booting VM, rebooting VM) and all of these now work just like advertised.
I personally would prefer to do the update at a fixed time, preferably at night. |
MaxMind say the (open source) databases are updated on the first tuesday of the month. So we actually only need to download once a month. Because I don't like that the current service run on every boot, I've been thinking of this:
Pro:
Con:
I really like /var/lib/geoip-databases to be as accurate to the configuration as possible. But even with the current scheme (run every week, run on every boot), there is no guarantee that things are OK. You still have to check if the service ran successfully. It's doing impure IO, after all :-) Hence, I'm thinking it might be OK to just run the initial setup service once. If it fails that time, then oh well, look at "systemctl --failed" and restart it. Thoughts? |
34ab4f0
to
c80c21d
Compare
The GeoIP databases from MaxMind have no stable URLs and change every month (or so). Our current method of packaging these database in Nix and playing catch-up with ever-changing file hashes is a bad idea. For instance, it makes it impossible to realize old NixOS configurations. This patch adds a NixOS service that periodically updates the GeoIP databases in /var/lib/geoip-databases. Moving NixOS modules over can be done in later patches. I tried adding MD5 check, but not all databases have them, so i skipped it. We are downloading over HTTPS though, it should be good. I also tried adding zip support, but the first zip file I extracted had a different filename inside than the archive name, which breaks an assumption in this service, so I skipped that too. Changes v9 -> v10: - Pass "--max-time" to curl to set upper bound on downloads (ensures no indefinite hanging if there's problem with networking). Timeout for network connectivity check: 60s. Timeout for geoip database (each): 15m. Changes v8 -> v9: - Mention the random timer delay in the documentation for the 'interval' option. Changes v7 -> v8: - Add "RemainAfterExit=true" for the setup service, so it won't be restarted needlessly. (Thanks @danbst!) Changes v6 -> v7: - Add --skip-existing flag to geoip-updater, which skips updating existing database files. Pass that flag when we run the service on boot (and on any NixOS configuration change). (IMHO, this is somewhat a workaround for systemd persistent timers not being triggered immediately when a timer has never expired before. But it does have the nice side effect of ensuring that the installed databases always correspond to the configured ones, since the service is now always run after configuration changes.) Changes v5 -> v6: - Update database files atomically (per DB) - If a database is removed from the configuration, it'll be removed from /var/lib/geoip-databases too (on next run). - Add NixOS module assertion so that if user inputs non- .gz or .xz file there will be a build time error instead of runtime. - Run updater as user "nobody" instead of "root". - Rename NixOS service from "geoip-databases" to "geoip-updater". - Drop RemainAfterExit, or else the timer won't trigger the unit. - Bring back "curl --fail", or else we won't catch and log curl failures. Changes v4 -> v5: - Add "GeoLite2-City.mmdb.gz" to default database list. Changes v3 -> v4: - Remove unneeded geoip-updater-setup.service after adding 'wantedBy = [ "multi-user.target" ]' directly to geoip-updater.service - Drop unneeded "Service" name from service descriptions. Changes v2 -> v3: - Network may be down when starting from a cold boot, so try a few times. Possibly, if using systemd-networkd, it'll pass on the first try. But with default DHCP on NixOS, the service is started before hostnames can be resolved and thus we need a few extra seconds. - Add error handling and mark service as failed if fatal error. - Add proper syslog log levels. - Add RandomizedDelaySec=3600 to the timer to not put high load on the MaxMind servers. Suggested by @Mic92. - Set RemainAfterExit on geoip-updater.service instead of geoip-updater-setup.service. (The latter is only a proxy that pulls in the former service). Changes v1 -> v2: From Данило Глинський (Danylo Hlynskyi) <abcz2.uprola@gmail.com>: nixos/geoip-databases: add `databases` option and fix initial setup There were two great issues when using this service: - When you just enable service, databases aren't downloaded, they are downloaded when timer triggers. Fixed this with automatic download on first system activation. - When there is no internet, updater outputs nothing to logs, which is IMO misbehavior. Fixed this with removing `--fail` option, better be explicit here.
c80c21d
to
8aadc16
Compare
Can this be merged as-is, and tunings/thoughts separated to another issue? I find this service useful in it's current form (and I use it on-top of 16.09). |
Applied to master: 824d82f I see no problem with cherry-picking this to release-16.09. I'll do that later if nobody objects. |
Awesome! btw, much thanks @bjornfor for your initiative. |
The GeoIP Legacy databases from MaxMind have no stable URLs and change
every month (or so). Our current method of packaging these database in
Nix and playing catch-up with the ever-changing file hashes is a bad
idea. For instance, it makes it impossible to realize old NixOS
configurations.
This patch adds a NixOS service that periodically updates the GeoIP
databases in /var/lib/geoip-databases. Future patches will move users
over.