revert timezoner attempts

This commit is contained in:
RingOfStorms (Joshua Bell) 2026-01-13 14:17:41 -06:00
parent 282208d537
commit 72724ae54a
2 changed files with 48 additions and 192 deletions

View file

@ -1,34 +1,5 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.automatic-timezoned;
persistFile = if cfg.persistDir == null then null else "${cfg.persistDir}/timezone";
tzdata = pkgs.tzdata;
in
{ lib, pkgs, ... }:
{
options.services.automatic-timezoned.persistDir = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Absolute runtime directory used to persist the timezone for impermanence setups.
Important: this must be a normal filesystem path (a string like
"/persist/var/lib/timezone-persist"), not a Nix `path` value, otherwise it
can be coerced into a `/nix/store/...` path and become unwritable at runtime.
When set, the timezone is saved to this directory and restored on boot,
allowing offline boots to use the last known timezone.
Set to null to disable persistence (default).
'';
};
config = {
assertions = [
{
assertion = cfg.persistDir == null || lib.hasPrefix "/" cfg.persistDir;
message = "services.automatic-timezoned.persistDir must be an absolute path";
}
];
services.dbus.enable = lib.mkDefault true;
services.geoclue2.enable = true;
@ -36,10 +7,8 @@ in
services.automatic-timezoned.enable = true;
systemd.services.automatic-timezoned = {
after = [ "dbus.socket" "systemd-timedated.service" "geoclue.service" ]
++ lib.optional (cfg.persistDir != null) "timezone-restore.service";
wants = [ "dbus.socket" "systemd-timedated.service" "geoclue.service" ]
++ lib.optional (cfg.persistDir != null) "timezone-restore.service";
after = [ "dbus.socket" "systemd-timedated.service" "geoclue.service" ];
wants = [ "dbus.socket" "systemd-timedated.service" "geoclue.service" ];
serviceConfig = {
ExecStartPre = "${lib.getExe' pkgs.coreutils "sleep"} 5";
Restart = "on-failure";
@ -52,117 +21,6 @@ in
wants = [ "dbus.socket" ];
};
# Ensure anything using timedate1 sees restored timezone first.
systemd.services.systemd-timedated = lib.mkIf (cfg.persistDir != null) {
after = [ "timezone-restore.service" ];
wants = [ "timezone-restore.service" ];
requires = [ "timezone-restore.service" ];
};
# Restore timezone from persistent storage on boot (fallback for offline boots)
systemd.services.timezone-restore = lib.mkIf (cfg.persistDir != null) {
description = "Restore timezone from persistent storage";
wantedBy = [ "sysinit.target" ];
# NixOS activation may recreate /etc/localtime based on config.
# Run after activation so the restored timezone "wins" on offline boots.
after = [
"local-fs.target"
"systemd-remount-fs.service"
"nixos-activation.service"
];
wants = [ "nixos-activation.service" ];
before = [
"time-sync.target"
"automatic-timezoned.service"
"systemd-timedated.service"
];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
RequiresMountsFor = [ cfg.persistDir ];
ExecStart = pkgs.writeShellScript "timezone-restore" ''
set -euo pipefail
persist_file="${persistFile}"
if [ ! -f "$persist_file" ]; then
echo "No persisted timezone found, skipping restore"
exit 0
fi
tz=$(${pkgs.coreutils}/bin/cat "$persist_file")
if [ -z "$tz" ]; then
echo "Persisted timezone file is empty, skipping restore"
exit 0
fi
tzfile="${tzdata}/share/zoneinfo/$tz"
if [ ! -f "$tzfile" ]; then
echo "Invalid timezone '$tz' in persist file, skipping restore"
exit 0
fi
echo "Restoring timezone: $tz"
${pkgs.coreutils}/bin/ln -sf "$tzfile" /etc/localtime
# Some NixOS setups may generate /etc/timezone as a symlink into the store.
# Replace it so we don't fail the whole restore.
${pkgs.coreutils}/bin/rm -f /etc/timezone
${pkgs.coreutils}/bin/printf '%s\n' "$tz" > /etc/timezone
'';
};
};
# Save timezone whenever it changes
systemd.services.timezone-persist = lib.mkIf (cfg.persistDir != null) {
description = "Persist timezone to storage";
serviceConfig = {
Type = "oneshot";
RequiresMountsFor = [ cfg.persistDir ];
ExecStart = pkgs.writeShellScript "timezone-persist" ''
set -euo pipefail
${pkgs.coreutils}/bin/mkdir -p "${cfg.persistDir}"
# Try to read timezone from /etc/timezone first, fall back to parsing symlink
if [ -f /etc/timezone ]; then
tz=$(${pkgs.coreutils}/bin/cat /etc/timezone | ${pkgs.coreutils}/bin/tr -d '[:space:]')
else
target=$(${pkgs.coreutils}/bin/readlink /etc/localtime 2>/dev/null || true)
if [ -z "$target" ]; then
echo "Cannot determine timezone, skipping persist"
exit 0
fi
# Extract timezone name from path like /nix/store/.../share/zoneinfo/America/Chicago
tz=$(echo "$target" | ${pkgs.gnused}/bin/sed -n 's|.*/zoneinfo/||p')
fi
if [ -z "$tz" ]; then
echo "Cannot determine timezone, skipping persist"
exit 0
fi
persist_file="${persistFile}"
echo "Persisting timezone: $tz"
echo "$tz" > "$persist_file"
'';
};
};
# Watch /etc/localtime and /etc/timezone for changes and trigger persist
systemd.paths.timezone-persist = lib.mkIf (cfg.persistDir != null) {
description = "Watch timezone changes to persist";
wantedBy = [ "multi-user.target" ];
pathConfig = {
PathChanged = [ "/etc/localtime" "/etc/timezone" ];
Unit = "timezone-persist.service";
};
};
systemd.services.fix-localtime-symlink = {
description = "Fix /etc/localtime symlink to be absolute";
wantedBy = [ "multi-user.target" ];
@ -203,5 +61,4 @@ in
Unit = "fix-localtime-symlink.service";
};
};
};
}

View file

@ -84,7 +84,6 @@
inputs.common.nixosModules.hardening
inputs.common.nixosModules.nix_options
inputs.common.nixosModules.timezone_auto
({ services.automatic-timezoned.persistDir = "/persist/var/lib/timezone-persist"; })
inputs.common.nixosModules.tty_caps_esc
inputs.common.nixosModules.zsh
inputs.common.nixosModules.tailnet