diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/copy-from-other-stores.pl.in | 1 | ||||
-rw-r--r-- | scripts/download-from-binary-cache.pl.in | 10 | ||||
-rwxr-xr-x | scripts/nix-build.in | 69 | ||||
-rwxr-xr-x | scripts/nix-install-package.in | 2 | ||||
-rwxr-xr-x | scripts/nix-push.in | 26 |
5 files changed, 88 insertions, 20 deletions
diff --git a/scripts/copy-from-other-stores.pl.in b/scripts/copy-from-other-stores.pl.in index cf36bae9e803..8ce5a9d4049f 100755 --- a/scripts/copy-from-other-stores.pl.in +++ b/scripts/copy-from-other-stores.pl.in @@ -9,6 +9,7 @@ my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@"; STDOUT->autoflush(1); +binmode STDERR, ":encoding(utf8)"; my @remoteStoresAll = split ':', ($ENV{"NIX_OTHER_STORES"} or ""); diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in index 6285a0503682..bb63eafca522 100644 --- a/scripts/download-from-binary-cache.pl.in +++ b/scripts/download-from-binary-cache.pl.in @@ -47,11 +47,17 @@ $caBundle = "/etc/ssl/certs/ca-certificates.crt" if !$caBundle && -f "/etc/ssl/c my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name"; +my $userAgent = "Nix/$Nix::Config::version"; + sub isTrue { my ($x) = @_; return $x eq "true" || $x eq "1"; } +# FIXME: this should be cache URLs required to have valid signatures, +# or "*" to require signatures on all binary caches. +# FIXME: should binary caches using a key in +# ‘binary-cache-public-keys’ be trusted by default? my $requireSignedBinaryCaches = ($Nix::Config::config{"signed-binary-caches"} // "0") ne "0"; my $curlConnectTimeout = int( @@ -75,7 +81,7 @@ sub addRequest { $curl->setopt(CURLOPT_FOLLOWLOCATION, 1); $curl->setopt(CURLOPT_CAINFO, $caBundle) if defined $caBundle; $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0) unless isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1"); - $curl->setopt(CURLOPT_USERAGENT, "Nix/$Nix::Config::version"); + $curl->setopt(CURLOPT_USERAGENT, $userAgent); $curl->setopt(CURLOPT_NOBODY, 1) if $head; $curl->setopt(CURLOPT_FAILONERROR, 1); $curl->setopt(CURLOPT_CONNECTTIMEOUT, $curlConnectTimeout); @@ -555,7 +561,7 @@ sub downloadBinary { die if $requireSignedBinaryCaches && !defined $info->{signedBy}; print STDERR "\n*** Downloading ‘$url’ ", ($requireSignedBinaryCaches ? "(signed by ‘$info->{signedBy}’) " : ""), "to ‘$storePath’...\n"; checkURL $url; - if (system("$Nix::Config::curl --fail --location --insecure --connect-timeout $curlConnectTimeout '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) { + if (system("$Nix::Config::curl --fail --location --insecure --connect-timeout $curlConnectTimeout -A '$userAgent' '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) { warn "download of ‘$url’ failed" . ($! ? ": $!" : "") . "\n"; next; } diff --git a/scripts/nix-build.in b/scripts/nix-build.in index 9127d90b24dd..19de6feb6080 100755 --- a/scripts/nix-build.in +++ b/scripts/nix-build.in @@ -5,6 +5,8 @@ use strict; use Nix::Config; use Nix::Store; use Nix::Utils; +use File::Basename; +use Cwd; binmode STDERR, ":encoding(utf8)"; @@ -14,6 +16,7 @@ my $runEnv = $0 =~ /nix-shell$/; my $pure = 0; my $fromArgs = 0; my $packages = 0; +my $interactive = 1; my @instArgs = (); my @buildArgs = (); @@ -25,6 +28,9 @@ my @envExclude = (); my $myName = $runEnv ? "nix-shell" : "nix-build"; +my $inShebang = 0; +my $script; +my @savedArgs; my $tmpDir = mkTempDir($myName); @@ -35,6 +41,30 @@ my $drvLink = "$tmpDir/derivation"; $SIG{'INT'} = sub { exit 1 }; +# Heuristic to see if we're invoked as a shebang script, namely, if we +# have a single argument, it's the name of an executable file, and it +# starts with "#!". +if ($runEnv && $ARGV[0] !~ /nix-shell/) { + $script = $ARGV[0]; + if (-f $script && -x $script) { + open SCRIPT, "<$script" or die "$0: cannot open ‘$script’: $!\n"; + my $first = <SCRIPT>; + if ($first =~ /^\#\!/) { + $inShebang = 1; + @savedArgs = @ARGV; shift @savedArgs; + @ARGV = (); + while (<SCRIPT>) { + chomp; + if (/^\#\!\s*nix-shell (.*)$/) { + @ARGV = split / /, $1; + } + } + } + close SCRIPT; + } +} + + for (my $n = 0; $n < scalar @ARGV; $n++) { my $arg = $ARGV[$n]; @@ -131,10 +161,11 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $runEnv = 1; } - elsif ($arg eq "--command") { + elsif ($arg eq "--command" || $arg eq "--run") { $n++; die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $envCommand = "$ARGV[$n]\nexit $!"; + $envCommand = "$ARGV[$n]\nexit"; + $interactive = 0 if $arg eq "--run"; } elsif ($arg eq "--exclude") { @@ -155,10 +186,32 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $packages = 1; } + elsif ($inShebang && $arg eq "-i") { + $n++; + die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; + my $interpreter = $ARGV[$n]; + # Überhack to support Perl. Perl examines the shebang and + # executes it unless it contains the string "perl" or "indir", + # or (undocumented) argv[0] does not contain "perl". Exploit + # the latter by doing "exec -a". + my $execArgs = $interpreter =~ /perl/ ? "-a PERL" : ""; + sub shellEscape { + my $s = $_; + $s =~ s/'/'\\''/g; + return "'" . $s . "'"; + } + $envCommand = "exec $execArgs $interpreter $script ${\(join ' ', (map shellEscape, @savedArgs))}"; + } + elsif (substr($arg, 0, 1) eq "-") { push @buildArgs, $arg; } + elsif ($arg eq "-Q" || $arg eq "--no-build-output") { + push @buildArgs, $arg; + push @instArgs, $arg; + } + else { push @exprs, $arg; } @@ -182,6 +235,11 @@ foreach my $expr (@exprs) { # Instantiate. my @drvPaths; if ($expr !~ /^\/.*\.drv$/) { + # If we're in a #! script, interpret filenames relative to the + # script. + $expr = dirname(Cwd::abs_path($script)) . "/" . $expr + if $inShebang && !$packages && $expr !~ /^\//; + # !!! would prefer the perl 5.8.0 pipe open feature here. my $pid = open(DRVPATHS, "-|") || exec "$Nix::Config::binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr; while (<DRVPATHS>) {chomp; push @drvPaths, $_;} @@ -232,17 +290,20 @@ foreach my $expr (@exprs) { ($pure ? '' : 'p=$PATH; ' ) . 'dontAddDisableDepTrack=1; ' . '[ -e $stdenv/setup ] && source $stdenv/setup; ' . - 'if [ "$(type -t runHook)" = function ]; then runHook shellHook; fi; ' . ($pure ? '' : 'PATH=$PATH:$p; unset p; ') . 'set +e; ' . '[ -n "$PS1" ] && PS1="\n\[\033[1;32m\][nix-shell:\w]$\[\033[0m\] "; ' . + 'if [ "$(type -t runHook)" = function ]; then runHook shellHook; fi; ' . 'unset NIX_ENFORCE_PURITY; ' . 'unset NIX_INDENT_MAKE; ' . 'shopt -u nullglob; ' . 'unset TZ; ' . (defined $ENV{'TZ'} ? "export TZ='${ENV{'TZ'}}'; " : '') . $envCommand); $ENV{BASH_ENV} = $rcfile; - exec($ENV{NIX_BUILD_SHELL} // "bash", "--rcfile", $rcfile); + my @args = ($ENV{NIX_BUILD_SHELL} // "bash"); + push @args, "--rcfile" if $interactive; + push @args, $rcfile; + exec @args; die; } diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in index c109652d1fca..b442c708b1a2 100755 --- a/scripts/nix-install-package.in +++ b/scripts/nix-install-package.in @@ -71,7 +71,7 @@ sub barf { my $pkgFile = $source; if ($fromURL) { $pkgFile = "$tmpDir/tmp.nixpkg"; - system("@curl@", "--silent", $source, "-o", $pkgFile) == 0 + system("@curl@", "-L", "--silent", $source, "-o", $pkgFile) == 0 or barf "curl failed: $?"; } diff --git a/scripts/nix-push.in b/scripts/nix-push.in index c6d187704bc7..d5d3bc1e7e79 100755 --- a/scripts/nix-push.in +++ b/scripts/nix-push.in @@ -6,11 +6,11 @@ use File::Basename; use File::Path qw(mkpath); use File::stat; use File::Copy; +use MIME::Base64; use Nix::Config; use Nix::Store; use Nix::Manifest; use Nix::Utils; -use Nix::Crypto; binmode STDERR, ":encoding(utf8)"; @@ -27,8 +27,7 @@ my $writeManifest = 0; my $manifestPath; my $archivesURL; my $link = 0; -my $privateKeyFile; -my $keyName; +my $secretKeyFile; my @roots; for (my $n = 0; $n < scalar @ARGV; $n++) { @@ -61,14 +60,10 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $archivesURL = $ARGV[$n]; } elsif ($arg eq "--link") { $link = 1; - } elsif ($arg eq "--key") { + } elsif ($arg eq "--key-file") { $n++; die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $privateKeyFile = $ARGV[$n]; - } elsif ($arg eq "--key-name") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $keyName = $ARGV[$n]; + $secretKeyFile = $ARGV[$n]; } elsif (substr($arg, 0, 1) eq "-") { die "$0: unknown flag ‘$arg’\n"; } else { @@ -110,7 +105,7 @@ my %narFiles; foreach my $storePath (@storePaths) { my $pathHash = substr(basename($storePath), 0, 32); my $narInfoFile = "$destDir/$pathHash.narinfo"; - if (-e $narInfoFile) { + if (!$force && -e $narInfoFile) { my $narInfo = parseNARInfo($storePath, readFile($narInfoFile), 0, $narInfoFile) or die "cannot read ‘$narInfoFile’\n"; my $narFile = "$destDir/$narInfo->{url}"; if (-e $narFile) { @@ -257,9 +252,14 @@ for (my $n = 0; $n < scalar @storePaths2; $n++) { } } - if (defined $privateKeyFile && defined $keyName) { - my $sig = signString($privateKeyFile, $info); - $info .= "Signature: 1;$keyName;$sig\n"; + if (defined $secretKeyFile) { + my $s = readFile $secretKeyFile; + chomp $s; + my ($keyName, $secretKey) = split ":", $s; + die "invalid secret key file ‘$secretKeyFile’\n" unless defined $keyName && defined $secretKey; + my $fingerprint = fingerprintPath($storePath, $narHash, $narSize, $refs); + my $sig = encode_base64(signString(decode_base64($secretKey), $fingerprint), ""); + $info .= "Sig: $keyName:$sig\n"; } my $pathHash = substr(basename($storePath), 0, 32); |