Skip to content
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/timezone: stop using mode direct-symlink for linking localtime #284641

Closed
wants to merge 1 commit into from

Conversation

NickCao
Copy link
Member

@NickCao NickCao commented Jan 29, 2024

Description of changes

This surfaces from #270727 (comment).

We are currently having an unnecessary level of indirection, namely
/etc/localtime -> /etc/zoneinfo/<tz> -> /nix/store/<tzdata>/share/zoneinfo/<tz>
Which was introduced in #26608 for no obvious reasons.

It can be reduced to
/etc/localtime -> /nix/store/<tzdata>/share/zoneinfo/<tz>
and the relevant nixos tests still pass.

This also removed the last in-tree user of the undocumented direct-symlink mode of etc files.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jan 29, 2024
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Jan 29, 2024
@lheckemann
Copy link
Member

The indirection wasn't introduced in my PR, it was introduced before in 0762396 -- with justification.

If this turns out to be fine anyway -- given that it's the last use of direct-symlink in nixpkgs, maybe we should remove or at least deprecate the mode as well?

@NickCao
Copy link
Member Author

NickCao commented Jan 29, 2024

The indirection wasn't introduced in my PR, it was introduced before in 0762396 -- with justification.

This indeed breaks systemd:

❯ timedatectl status
                Time zone: n/a (UTC, +0000)

@NickCao NickCao marked this pull request as draft January 29, 2024 21:17
@NickCao
Copy link
Member Author

NickCao commented Jan 29, 2024

So the solution would now be keeping direct-symlink, but make perlless activation compatible with it.

@MinerSebas MinerSebas mentioned this pull request Feb 2, 2024
13 tasks
@Kiskae
Copy link
Contributor

Kiskae commented Feb 2, 2024

Wouldn't the following code work:

lib.optionalAttrs (config.time.timeZone != null) {
  localtime.source = "/etc/zoneinfo/${config.time.timeZone}";
  localtime.mode = "symlink";
};

This keeps the indirection because the systemd requirements, but fixes perlless activation since creating a symlink to a non-existent absolute path is allowed.

It looks like direct-symlink is a hack to get a symlink but gid or uid was set for some reason:

if (-e "$_.mode") {
my $mode = read_file("$_.mode"); chomp $mode;
if ($mode eq "direct-symlink") {
atomicSymlink readlink("$static/$fn"), $target or warn "could not create symlink $target";
} else {
my $uid = read_file("$_.uid"); chomp $uid;
my $gid = read_file("$_.gid"); chomp $gid;
copy "$static/$fn", "$target.tmp" or warn;
$uid = getpwnam $uid unless $uid =~ /^\+/;
$gid = getgrnam $gid unless $gid =~ /^\+/;
chown int($uid), int($gid), "$target.tmp" or warn;
chmod oct($mode), "$target.tmp" or warn;
unless (rename "$target.tmp", $target) {
warn "could not create target $target";
unlink "$target.tmp";
}
}
push @copied, $fn;
print CLEAN "$fn\n";
} elsif (-l "$_") {
atomicSymlink "$static/$fn", $target or warn "could not create symlink $target";
}

Neither are the case here, so it is likely safe to remove this entirely.

@nyabinary
Copy link
Contributor

Wouldn't the following code work:

lib.optionalAttrs (config.time.timeZone != null) {
  localtime.source = "/etc/zoneinfo/${config.time.timeZone}";
  localtime.mode = "symlink";
};

This keeps the indirection because the systemd requirements, but fixes perlless activation since creating a symlink to a non-existent absolute path is allowed.

It looks like direct-symlink is a hack to get a symlink but gid or uid was set for some reason:

if (-e "$_.mode") {
my $mode = read_file("$_.mode"); chomp $mode;
if ($mode eq "direct-symlink") {
atomicSymlink readlink("$static/$fn"), $target or warn "could not create symlink $target";
} else {
my $uid = read_file("$_.uid"); chomp $uid;
my $gid = read_file("$_.gid"); chomp $gid;
copy "$static/$fn", "$target.tmp" or warn;
$uid = getpwnam $uid unless $uid =~ /^\+/;
$gid = getgrnam $gid unless $gid =~ /^\+/;
chown int($uid), int($gid), "$target.tmp" or warn;
chmod oct($mode), "$target.tmp" or warn;
unless (rename "$target.tmp", $target) {
warn "could not create target $target";
unlink "$target.tmp";
}
}
push @copied, $fn;
print CLEAN "$fn\n";
} elsif (-l "$_") {
atomicSymlink "$static/$fn", $target or warn "could not create symlink $target";
}

Neither are the case here, so it is likely safe to remove this entirely.

I believe the systemd patch will need to be updated too:

+ e = PATH_STARTSWITH_SET(t, "/etc/zoneinfo/", "../etc/zoneinfo/");

@nyabinary
Copy link
Contributor

Any status update on this?

@devurandom
Copy link
Contributor

devurandom commented Mar 6, 2024

I just ran into the same issue:

error: builder for '/nix/store/596cj5v942ms8dbfsmsz5fm69a7yghmr-etc-lowerdir.drv' failed with exit code 1;
       last 1 log lines:
       > cp: cannot stat '/etc/zoneinfo/Europe/Berlin': No such file or directory
       For full logs, run 'nix log /nix/store/596cj5v942ms8dbfsmsz5fm69a7yghmr-etc-lowerdir.drv'.

Is there a workaround? (Apart from unsetting time.timeZone.)

@nyabinary
Copy link
Contributor

I just ran into the same issue:

error: builder for '/nix/store/596cj5v942ms8dbfsmsz5fm69a7yghmr-etc-lowerdir.drv' failed with exit code 1;
       last 1 log lines:
       > cp: cannot stat '/etc/zoneinfo/Europe/Berlin': No such file or directory
       For full logs, run 'nix log /nix/store/596cj5v942ms8dbfsmsz5fm69a7yghmr-etc-lowerdir.drv'.

Is there a workaround? (Apart from unsetting time.timeZone.)

I don't think so, sadly.

@jcfj
Copy link

jcfj commented May 23, 2024

Is there a workaround?

Setting environment.etc.localtime = lib.mkForce { source = "${pkgs.tzdata}/share/zoneinfo/${config.time.timeZone}"; }; works for that build failure, but I'm not sure the resulting system is usable.

@NickCao
Copy link
Member Author

NickCao commented May 26, 2024

Closing in favor of #314579

@NickCao NickCao closed this May 26, 2024
@NickCao NickCao deleted the direct-symlink branch May 26, 2024 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants