nixos/timezone: support imperative timezone configuration (#26608)

Fixes #26469.

Changed files
+57 -8
nixos
modules
config
tests
+12 -8
nixos/modules/config/timezone.nix
···
time = {
timeZone = mkOption {
-
default = "UTC";
-
type = types.str;
+
default = null;
+
type = types.nullOr types.str;
example = "America/New_York";
description = ''
The time zone used when displaying times and dates. See <link
xlink:href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"/>
for a comprehensive list of possible values for this setting.
+
+
If null, the timezone will default to UTC and can be set imperatively
+
using timedatectl.
'';
};
···
# This way services are restarted when tzdata changes.
systemd.globalEnvironment.TZDIR = tzdir;
-
environment.etc.localtime =
-
{ source = "/etc/zoneinfo/${config.time.timeZone}";
-
mode = "direct-symlink";
+
systemd.services.systemd-timedated.environment = lib.optionalAttrs (config.time.timeZone != null) { NIXOS_STATIC_TIMEZONE = "1"; };
+
+
environment.etc = {
+
zoneinfo.source = tzdir;
+
} // lib.optionalAttrs (config.time.timeZone == null) {
+
localtime.source = "/etc/zoneinfo/${config.time.timeZone}";
+
localtime.mode = "direct-symlink";
};
-
-
environment.etc.zoneinfo.source = tzdir;
-
};
}
+45
nixos/tests/timezone.nix
···
+
{
+
timezone-static = import ./make-test.nix ({ pkgs, ... }: {
+
name = "timezone-static";
+
meta.maintainers = with pkgs.lib.maintainers; [ lheckemann ];
+
+
machine.time.timeZone = "Europe/Amsterdam";
+
+
testScript = ''
+
$machine->waitForUnit("dbus.socket");
+
$machine->fail("timedatectl set-timezone Asia/Tokyo");
+
my @dateResult = $machine->execute('date -d @0 "+%Y-%m-%d %H:%M:%S"');
+
$dateResult[1] eq "1970-01-01 01:00:00\n" or die "Timezone seems to be wrong";
+
'';
+
});
+
+
timezone-imperative = import ./make-test.nix ({ pkgs, ... }: {
+
name = "timezone-imperative";
+
meta.maintainers = with pkgs.lib.maintainers; [ lheckemann ];
+
+
machine.time.timeZone = null;
+
+
testScript = ''
+
$machine->waitForUnit("dbus.socket");
+
+
# Should default to UTC
+
my @dateResult = $machine->execute('date -d @0 "+%Y-%m-%d %H:%M:%S"');
+
print $dateResult[1];
+
$dateResult[1] eq "1970-01-01 00:00:00\n" or die "Timezone seems to be wrong";
+
+
$machine->succeed("timedatectl set-timezone Asia/Tokyo");
+
+
# Adjustment should be taken into account
+
my @dateResult = $machine->execute('date -d @0 "+%Y-%m-%d %H:%M:%S"');
+
print $dateResult[1];
+
$dateResult[1] eq "1970-01-01 09:00:00\n" or die "Timezone was not adjusted";
+
+
# Adjustment should persist across a reboot
+
$machine->shutdown;
+
$machine->waitForUnit("dbus.socket");
+
my @dateResult = $machine->execute('date -d @0 "+%Y-%m-%d %H:%M:%S"');
+
print $dateResult[1];
+
$dateResult[1] eq "1970-01-01 09:00:00\n" or die "Timezone adjustment was not persisted";
+
'';
+
});
+
}