Open ToxicFrog opened 1 year ago
perl.withPackages
is also implemented with the PERL5LIB
environment variable.
The only fix I can think of is to get upstream perl to have another way to configure deps. Then we could use that in perl.withPackages
at least.
For comparison, python.withPackages
has this wrapper:
makeCWrapper '/nix/store/c3cjxhn73xa5s8fm79w95d0879bijp04-python3-3.10.13/bin/python3' \
--set 'NIX_PYTHONPREFIX' '/nix/store/x6hnbzyflpsm1hawwkw9ji4l88n4fx6m-python3-3.10.13-env' \
--set 'NIX_PYTHONEXECUTABLE' '/nix/store/x6hnbzyflpsm1hawwkw9ji4l88n4fx6m-python3-3.10.13-env/bin/python3.10' \
--set 'NIX_PYTHONPATH' '/nix/store/x6hnbzyflpsm1hawwkw9ji4l88n4fx6m-python3-3.10.13-env/lib/python3.10/site-packages' \
--set 'PYTHONNOUSERSITE' 'true'
So it seems to use nixpkgs specific setup.
For me, it is manifesting as munin-cron error Can't locate Date/Parse.pm in @INC (you may need to install the Date::Parse module)
, but I think it is the same cause.
Yep, that's the same issue -- Nix wiggles some environment variables so that Perl knows where to find its libraries, and -T
tells it to (among other things) ignore those environment variables and use the compiled-in @INC
, so this manifests as perl scripts being unable to find perl libraries that are ostensibly in their dependency closure.
Ok, I said that, but after updating, munin-cron is failing in the same way for me even with my patch, and the failing scripts aren't using -T
.
It looks like munin needs Date::Parse
now and that isn't packaged for nixos, so the munin package is just flat broken at head.
Here's my overlay:
final: prev: {
munin = prev.munin.overrideAttrs (old: {
# HACK HACK HACK
# perl -T breaks makeWrapper --set PERL5LIB; see https://github.com/NixOS/nixpkgs/issues/263396
# Copied from pkgs/servers/monitoring/munin/default.nix
buildInputs = old.buildInputs ++ [ final.perlPackages.TimeDate ];
postFixup = ''
# Added this quick hack
echo "Replacing perl -T with perl..."
${final.gnused}/bin/sed -E -i "s/perl -T/perl/" "$out"/www/cgi/*
echo "Removing references to /usr/{bin,sbin}/ from munin plugins..."
find "$out/lib/plugins" -type f -print0 | xargs -0 -L1 \
${final.gnused}/bin/sed -i -e "s|/usr/bin/||g" -e "s|/usr/sbin/||g" -e "s|\<bc\>|${final.bc}/bin/bc|g"
if test -e $out/nix-support/propagated-build-inputs; then
ln -s $out/nix-support/propagated-build-inputs $out/nix-support/propagated-user-env-packages
fi
# Added CGI, CGI::Fast, and TimeDate to the library list
for file in "$out"/bin/munindoc "$out"/sbin/munin-* "$out"/lib/munin-* "$out"/www/cgi/*; do
# don't wrap .jar files
case "$file" in
*.jar) continue;;
esac
wrapProgram "$file" \
--set PERL5LIB "$out/${final.perlPackages.perl.libPrefix}:${with final.perlPackages; makePerlPath [
LogLog4perl IOSocketINET6 Socket6 URI DBFile DateManip TimeDate
HTMLTemplate FileCopyRecursive FCGI NetCIDR NetSNMP NetServer
ListMoreUtils DBDPg LWP final.rrdtool CGI CGIFast
]}"
done
'';
});
}
I should probably turn it into a proper PR, but I've got two others still waiting for merge and if I open too many I tend to lose track of them.
Here's one way to keep track: https://github.com/NixOS/nixpkgs/pulls/toxicfrog
The only fix I can think of is to get upstream perl to have another way to configure deps.
It kind of has with BEGIN { use lib '<PATH>'; };
; although this requires modifying the original file, and cannot really applied in a wrapper, I think.
For munin, I did the following to make cgi-graph
work:
munin = super.munin.overrideAttrs (oldAttrs: let
incText = ''
use strict;
BEGIN {
use lib '$out/${super.perlPackages.perl.libPrefix}';
use lib '${with super.perlPackages; makePerlPath [LogLog4perl]}';
use lib '${with super.perlPackages; makePerlPath [IOSocketINET6]}';
use lib '${with super.perlPackages; makePerlPath [Socket6]}';
use lib '${with super.perlPackages; makePerlPath [URI]}';
use lib '${with super.perlPackages; makePerlPath [DBFile]}';
use lib '${with super.perlPackages; makePerlPath [TimeDate]}';
use lib '${with super.perlPackages; makePerlPath [HTMLTemplate]}';
use lib '${with super.perlPackages; makePerlPath [FileCopyRecursive]}';
use lib '${with super.perlPackages; makePerlPath [FCGI]}';
use lib '${with super.perlPackages; makePerlPath [CGI]}';
use lib '${with super.perlPackages; makePerlPath [CGIFast]}';
use lib '${with super.perlPackages; makePerlPath [NetCIDR]}';
use lib '${with super.perlPackages; makePerlPath [NetSNMP]}';
use lib '${with super.perlPackages; makePerlPath [NetServer]}';
use lib '${with super.perlPackages; makePerlPath [ListMoreUtils]}';
use lib '${with super.perlPackages; makePerlPath [DBDPg]}';
use lib '${with super.perlPackages; makePerlPath [LWP]}';
use lib '${with super.perlPackages; makePerlPath [super.rrdtool]}';
};
'';
in {
postFixup = oldAttrs.postFixup + ''
sed -i -e "s|use strict;|${lib.strings.stringAsChars (x: if x == "\n" then " " else x) incText}|g" $out/www/cgi/.munin-cgi-graph-wrapped
'';
});
Describe the bug
It is conventional to package perl programs using
wrapProgram --set PERL5LIB
, so that they can find their libraries. One example of this is munin.However, if the perl program uses
perl -T
(i.e. run in "taint checking" mode), this environment variable is considered "tainted" and is ignored, causing the program to fail at runtime. You can observe this in munin when running in cgi-graph mode, since the graph generator script usesperl -T
and will die immediately withCan't locate Date/Manip.pm in @INC
if run.Steps To Reproduce
Run any wrapped program in nixpkgs that wraps PERL5LIBS and has a
perl -T
shebang.Expected behavior
wrapProgram
'd perl programs work even if they useperl -T
.Additional context
I'm honestly not sure what the right thing to do here is. I have a workaround for now with an overlay that strips the
-T
from all of the munin scripts, but I don't think that's a good blanket solution. There is a perl library that excludes$PERL5LIB
from taint checking when loaded, but I don't know how to force the wrapped program to load it. I am mostly posting this in the hopes that other people who know more about perl than I do will come up with a solution.Notify maintainers
@bjornfor -- as the munin maintainer, since this breaks common munin use-cases, but I think the actual fix might need to be in nixpkg's perl support.
Metadata
"x86_64-linux"
Linux 6.1.41, NixOS, 23.05 (Stoat), 23.05.20231011.bd1cde4
yes
yes
nix-env (Nix) 2.13.5
"nixos-23.05, nixos-22.11-22.11, nixos-unstable"
/nix/var/nix/profiles/per-user/root/channels/nixos