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
incron: init at 0.5.12 #45638
incron: init at 0.5.12 #45638
Conversation
pkgs/tools/system/incron/default.nix
Outdated
patchPhase = '' | ||
sed -i "s|PREFIX = /usr/local|PREFIX = $out|g" Makefile | ||
sed -i "s|/bin/bash|${bash}/bin/bash|g" usertable.cpp | ||
sed -i "s|/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin|/run/current-system/sw/bin|g" usertable.cpp |
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 have some concerns whether line 13 is correct or not. For context see
https://github.com/ar-/incron/blob/master/usertable.cpp#L47 and
https://github.com/ar-/incron/blob/master/usertable.cpp#L605
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.
Yes, this seems weird. Also, here https://github.com/ar-/incron/blob/1eedfbc9b318372efd119fd17f4abdbde561a53d/usertable.cpp#L605
What's the expected behaviour here? Am I reading it right that it clears PATH and then sets it according to line 13? Is that sensible at all compared to actually inheriting PATH?
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.
@srhb my assumption is that since the user defined command runs as the user it doesn't seem entirely crazy to clear any unwanted extras out of the environment. By adding PATH back in as the standard list of installed software the command can execute in a clean state I guess?
Is the path I used valid to grant the command access to the full list of software available to the user? Even if the path is valid does it make sense in the context of nixos? We want to balance changing the intended behavior of the software and what users would expect vs. what makes sense for nixos.
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.
Yes, this might be a case of conflicting logic especially with NixOS.
The path you added adds in the system profile, but not the user's profile, which is what seems like what incron should really be doing (or possibly both of them.) I'm not really sure how to do this in a sensible way aside from using ~/.nix-profile/bin
on PATH as well. I feel like it isn't correct to try to reconstruct the user's PATH by manually adding these things onto it. After all, that's what the normal login process would take care of, so I guess I don't have any terribly good ideas on how to deal with the assumptions in this program.
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.
@srhb I recall the issue now. The process is run as root and therefore it can't simply inherit PATH. So the issue becomes how to best reproduce what PATH would look like for a given user.
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.
@srhb I've modified the PATH to better match what NixOS provides as the user path... which as you mentioned is unfortunately best guess manually reconstructing the users PATH variable. I believe this new code to be most inline with what existing users might expect if using this software, and what is most aligned with the intention of the software developer.
pkgs/tools/system/incron/default.nix
Outdated
patches = [ ./default_path.patch ]; | ||
|
||
prePatch = '' | ||
sed -i "s|PREFIX = /usr/local|PREFIX = $out|g" Makefile |
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.
Is it not possible to use makeFlags = [ "PREFIX=$(out)" ];
?
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.
Unfortunately this would get overridden:
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.
Would it? It usually works.
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 just tested and in this case it does not.
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.
Ok, found it: https://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding makeFlags
really have greater priority.
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 not sure what the issue is then... I pasted your suggested makeFlags in but get this error:
install -m 0755 -d /usr/local/share/man/man1
install: cannot create directory '/usr': Permission denied
It appears to me in this case the value is not being overridden.
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.
Right, the issue is that you are overriding installPhase
. The default installPhase
does something like make $makeFlags $installFlags $installTargets
.
You could switch to something like the following:
installFlags = [ "PREFIX=$(out)" ];
installTargets = [ "install-man" ];
preInstall = ''
mkdir -p $out/bin
# make install doesn't work because setuid and permissions
# just manually install the binaries instead
cp incrond incrontab $out/bin/
'';
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.
This can be removed now
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.
Yeah missed that on the last commit. Thanks for the explanation, that makes sense.
pkgs/tools/system/incron/default.nix
Outdated
|
||
stdenv.mkDerivation rec { | ||
name = "incron-0.5.12"; | ||
src = fetchurl { |
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.
Why not use fetchFromGitLab
?
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.
Generally speaking, is fetchFromGitLab/fetchFromGitHub preferred over fetchurl?
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.
Yes. There can be some better caching done or something.
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.
Thank you for explaining. I've adjusted as recommended. Thank you.
if (clearenv() != 0) | ||
goto failed; | ||
|
||
+ // try to recreate the user path as best as possible |
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.
The profiles are arbitrary. NIX_PROFILES
environment variable would contain all of them but that probably will not be available to the systemd service. Instead, it is common to provide extraPackages
option in the NixOS module and then add them to the service (example).
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.
How would you recommend doing this on a per user basis? Or are you just suggesting to skip that entirely and have the extraPackages cover all users? If so, would that not restrict users somewhat as they can't modify configuration.nix?
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.
Well would not be able to install packages to global profiles either, would they?
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.
No, but that is why ~/.nix-profile/bin is included in the path as well.
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.
Oh right, pwd->pw_name
is probably the user’s name. Maybe this would be good enough until the upstream adds user service support, if a comment that this is does not support other profiles than the common ones is added.
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've added a comment... please suggest any changes to wording.
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've modified this so the user can explicitly set the path for the system incrontab. Each users incrontab will still rely on the packages available to that user, but that can still work out reasonably well considering the users.users..packages option.
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.
On the other hand, the original code also does not try to emulate user’s PATH, so maybe we can just take the config.system.path
from the service.
pkgs/tools/system/incron/default.nix
Outdated
src = fetchFromGitHub { | ||
owner = "ar-"; | ||
repo = "incron"; | ||
rev = "incron-0.5.12"; |
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.
You can re-use name
here so that updating is easier.
|
||
# make install doesn't work because setuid and permissions | ||
# just manually install the binaries instead | ||
cp incrond incrontab $out/bin/ |
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.
Use of install
for mkdir -p
and cp
here might be slightly better, but this is a minor nit and should work as is.
systemd.services.incron = { | ||
description = "File system events scheduler"; | ||
wantedBy = [ "multi-user.target" ]; | ||
path = [ config.system.path ]; |
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.
This path is likely overbroad, and can enable accidental dependencies - e.g. if incron depends on foo
being in path, which it is on your system and a test system, this will work, but on someone's minimal system, that might be missing.
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.
Thanks for the suggestion. I've modified this so the user can explicitly set the path for the system incrontab.
…wouldn't be unused as per recommended by @maurer
|| setenv("HOME", pwd->pw_dir, 1) != 0 | ||
|| setenv("SHELL", pwd->pw_shell, 1) != 0 | ||
- || setenv("PATH", DEFAULT_PATH, 1) != 0) | ||
+ || setenv("PATH", DEFAULT_PATH.c_str(), 1) != 0) |
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.
Maybe instead of the patch to add PATH entries, we should instead delete this PATH-setting code and defer to some other PATH loading mechanism. This seems hairy and prone to problems.
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 think that sounds like a fairly large change which would really belong upstream.
I went with the logic as I thought it best preserves the intended behaviour of the application.
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.
config = mkIf cfg.enable { | ||
|
||
warnings = optional (cfg.allow != null && cfg.deny != null) | ||
''If `services.incron.allow` is set then `services.incron.deny` will be ignored.''; |
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.
Minor nitpick: "
is enough here.
Great review, thanks. |
Motivation for this change
The incron package is available on many other distributions but lacking in NixOS.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)