aboutsummaryrefslogtreecommitdiff
path: root/pkgs/nix-serve
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2018-12-11 18:10:48 +0300
committerIgor Pashev <pashev.igor@gmail.com>2018-12-11 18:10:48 +0300
commit8b0968b2054d3bb8d90b5ac056727f7c2ebeaed3 (patch)
treed03b70f693463fc836a8dbe4240424d2547530c8 /pkgs/nix-serve
parentc4273035cf5876e3ba8ed2c6b492d31c2de290ee (diff)
downloadnixsap-8b0968b2054d3bb8d90b5ac056727f7c2ebeaed3.tar.gz
(* HUGE *) Use nixpkgs overlays
Diffstat (limited to 'pkgs/nix-serve')
-rw-r--r--pkgs/nix-serve/default.nix32
-rw-r--r--pkgs/nix-serve/nix-serve.psgi77
2 files changed, 109 insertions, 0 deletions
diff --git a/pkgs/nix-serve/default.nix b/pkgs/nix-serve/default.nix
new file mode 100644
index 0000000..e5188f0
--- /dev/null
+++ b/pkgs/nix-serve/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, coreutils, pxz, nix, perl, perlPackages }:
+
+let
+ inherit (stdenv.lib)
+ makeBinPath
+ ;
+
+in stdenv.mkDerivation {
+ name = "nix-serve";
+
+ src = "${./nix-serve.psgi}";
+
+ buildInputs = [ perl nix.perl-bindings ]
+ ++ (with perlPackages; [ DBI DBDSQLite Plack Starman ]);
+
+ phases = [ "installPhase" ];
+
+ installPhase = ''
+ mkdir -p $out/libexec/nix-serve
+ perl -c "$src"
+ cat "$src" > "$out/libexec/nix-serve.psgi"
+
+ mkdir -p $out/bin
+ cat > $out/bin/nix-serve <<EOF
+ #! ${stdenv.shell}
+ export PATH=${makeBinPath [ coreutils pxz nix ]}:\$PATH
+ export PERL5LIB=$PERL5LIB
+ exec ${perlPackages.Starman}/bin/starman "$out/libexec/nix-serve.psgi" "\$@"
+ EOF
+ chmod +x $out/bin/nix-serve
+ '';
+}
diff --git a/pkgs/nix-serve/nix-serve.psgi b/pkgs/nix-serve/nix-serve.psgi
new file mode 100644
index 0000000..e368531
--- /dev/null
+++ b/pkgs/nix-serve/nix-serve.psgi
@@ -0,0 +1,77 @@
+# This is nix-serve (https://github.com/edolstra/nix-serve) using pxz instead of bzip2
+use MIME::Base64;
+use Nix::Config;
+use Nix::Manifest;
+use Nix::Store;
+use Nix::Utils;
+use strict;
+
+sub stripPath {
+ my ($x) = @_;
+ $x =~ s/.*\///; $x
+}
+
+my $app = sub {
+ my $env = shift;
+ my $path = $env->{PATH_INFO};
+
+ if ($path eq "/nix-cache-info") {
+ return [200, ['Content-Type' => 'text/plain'], ["StoreDir: $Nix::Config::storeDir\nWantMassQuery: 1\nPriority: 30\n"]];
+ }
+
+ elsif ($path =~ '/([0-9a-z]+)\.narinfo$') {
+ my $hashPart = $1;
+ my $storePath = queryPathFromHashPart($hashPart);
+ return [404, ['Content-Type' => 'text/plain'], ["No such path.\n"]] unless $storePath;
+ my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($storePath, 1) or die;
+ my $compression;
+ my $ext;
+ if ($narSize < 1024) {
+ $compression = 'none';
+ $ext = '';
+ } else {
+ $compression = 'xz';
+ $ext = '.xz';
+ }
+ my $res =
+ "StorePath: $storePath\n" .
+ "URL: nar/$hashPart.nar$ext\n" .
+ "Compression: $compression\n" .
+ "NarHash: $narHash\n" .
+ "NarSize: $narSize\n";
+ $res .= "References: " . join(" ", map { stripPath($_) } @$refs) . "\n"
+ if scalar @$refs > 0;
+ $res .= "Deriver: " . stripPath($deriver) . "\n" if defined $deriver;
+ my $secretKeyFile = $ENV{'NIX_SECRET_KEY_FILE'};
+ if (defined $secretKeyFile) {
+ my $secretKey = readFile $secretKeyFile;
+ chomp $secretKey;
+ my $fingerprint = fingerprintPath($storePath, $narHash, $narSize, $refs);
+ my $sig = signString($secretKey, $fingerprint);
+ $res .= "Sig: $sig\n";
+ }
+ return [200, ['Content-Type' => 'text/x-nix-narinfo'], [$res]];
+ }
+
+ elsif ($path =~ '/nar/([0-9a-z]+)\.nar.xz$') {
+ my $hashPart = $1;
+ my $storePath = queryPathFromHashPart($hashPart);
+ return [404, ['Content-Type' => 'text/plain'], ["No such path.\n"]] unless $storePath;
+ my $fh = new IO::Handle;
+ open $fh, "nix-store --dump '$storePath' | nice -n 19 pxz -0 |";
+ return [200, ['Content-Type' => 'application/x-xz'], $fh];
+ }
+
+ elsif ($path =~ '/nar/([0-9a-z]+)\.nar$') {
+ my $hashPart = $1;
+ my $storePath = queryPathFromHashPart($hashPart);
+ return [404, ['Content-Type' => 'text/plain'], ["No such path.\n"]] unless $storePath;
+ my $fh = new IO::Handle;
+ open $fh, "nix-store --dump '$storePath' |";
+ return [200, ['Content-Type' => 'application/octet-stream'], $fh];
+ }
+
+ else {
+ return [404, ['Content-Type' => 'text/plain'], ["File not found.\n"]];
+ }
+}