From 54586a77e7c1feb331dc84e959396751f56315a7 Mon Sep 17 00:00:00 2001 From: Michael Raskin <7c6f434c@mail.ru> Date: Mon, 30 Jun 2014 00:39:54 +0400 Subject: Adding a minimal script set to serve store as a dynamical binary cache --- pkgs/servers/http/nix-binary-cache/default.nix | 61 ++++++++++++ .../nix-binary-cache/nix-binary-cache-start.in | 105 +++++++++++++++++++++ .../http/nix-binary-cache/nix-binary-cache.cgi.in | 97 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 4 files changed, 265 insertions(+) create mode 100644 pkgs/servers/http/nix-binary-cache/default.nix create mode 100644 pkgs/servers/http/nix-binary-cache/nix-binary-cache-start.in create mode 100644 pkgs/servers/http/nix-binary-cache/nix-binary-cache.cgi.in (limited to 'pkgs') diff --git a/pkgs/servers/http/nix-binary-cache/default.nix b/pkgs/servers/http/nix-binary-cache/default.nix new file mode 100644 index 000000000000..b007c09b0560 --- /dev/null +++ b/pkgs/servers/http/nix-binary-cache/default.nix @@ -0,0 +1,61 @@ +{stdenv, fetchurl +, coreutils, findutils, nix, xz, bzip2, gnused, gnugrep, openssl +, lighttpd, iproute }: +stdenv.mkDerivation rec { + version = "2014-06-29-1"; + name = "nix-binary-cache-${version}"; + + phases = ["installPhase"]; + + installPhase = '' + mkdir -p "$out/bin" + substitute "${./nix-binary-cache.cgi.in}" "$out"/bin/nix-binary-cache.cgi \ + --replace @out@ "$out/bin" \ + --replace @shell@ "${stdenv.shell}" \ + --replace @coreutils@ "${coreutils}/bin" \ + --replace @findutils@ "${findutils}/bin" \ + --replace @nix@ "${nix}/bin" \ + --replace @xz@ "${xz}/bin" \ + --replace @bzip2@ "${bzip2}/bin" \ + --replace @gnused@ "${gnused}/bin" \ + --replace @gnugrep@ "${gnugrep}/bin" \ + --replace @openssl@ "${openssl}/bin" \ + --replace @lighttpd@ "${lighttpd}/sbin" \ + --replace @iproute@ "${iproute}/sbin" \ + --replace "xXxXx" "xXxXx" + + chmod a+x "$out/bin/nix-binary-cache.cgi" + + substitute "${./nix-binary-cache-start.in}" "$out"/bin/nix-binary-cache-start \ + --replace @out@ "$out/bin" \ + --replace @shell@ "${stdenv.shell}" \ + --replace @coreutils@ "${coreutils}/bin" \ + --replace @findutils@ "${findutils}/bin" \ + --replace @nix@ "${nix}/bin" \ + --replace @xz@ "${xz}/bin" \ + --replace @bzip2@ "${bzip2}/bin" \ + --replace @gnused@ "${gnused}/bin" \ + --replace @gnugrep@ "${gnugrep}/bin" \ + --replace @openssl@ "${openssl}/bin" \ + --replace @lighttpd@ "${lighttpd}/sbin" \ + --replace @iproute@ "${iproute}/sbin" \ + --replace "xXxXx" "xXxXx" + + chmod a+x "$out/bin/nix-binary-cache-start" + ''; + + meta = { + description = ''A set of scripts to serve the Nix store as a binary cache''; + longDescription = '' + This package installs a CGI script that serves Nix store path in the + binary cache format. It also installs a launcher called + nix-binary-cache-start that can be run without any setup to launch + a binary cache and get the example arguments for its usage. + ''; + maintainers = [stdenv.lib.maintainers.raskin]; + license = stdenv.lib.licenses.gpl2Plus; + inherit version; + platforms = stdenv.lib.platforms.all; + hydraPlatforms = []; + }; +} diff --git a/pkgs/servers/http/nix-binary-cache/nix-binary-cache-start.in b/pkgs/servers/http/nix-binary-cache/nix-binary-cache-start.in new file mode 100644 index 000000000000..2a2356f39ab2 --- /dev/null +++ b/pkgs/servers/http/nix-binary-cache/nix-binary-cache-start.in @@ -0,0 +1,105 @@ +#! @shell@ + +parse_opts () { + while @coreutils@/test -n "$1" && @coreutils@/test "x$1" != x-- ; do + case "$1" in + --store-dir) + shift; + echo "STORE_DIR='$1'" + shift; + ;; + --priority) + shift; + echo "PRIORITY=$1"; + shift; + ;; + --compression) + shift; + echo "COMPRESSION=$1"; + shift; + ;; + --key) + shift; + echo "KEY=${1#*:}" + echo "KEYNAME=${1%%:*}" + shift; + ;; + --nix-remote) + shift; + echo "NIX_REMOTE=$1" + shift; + ;; + --mass-query) + shift; + echo "MASS_QUERY=$1" + shift; + ;; + --port) + shift; + echo "PORT=$1" + shift; + ;; + --help) + cat <&2 +"$0": start the Nix binary cache serving the Nix store dynamically. + +Recognized options: + +--port server port +--store-dir served Nix store + +--priority binary cache priority +--mass-query 0 or 1 - whether binary cache expects queries for nix-env -qas + +--compression compression to use: bzip2 or xz +--key name:/path/to/key - key to use for narinfo signing + +--nix-remote 'daemon' or empty string '' - whether to use daemon for store + operations + +--help show help and exit +EOF + exit 1; + ;; + *) shift ;; + esac; + done +} + +workingdir="$(@coreutils@/mktemp -d)" +cd "$workingdir" + +PORT=8080 +(echo "STORE_DIR=${NIX_STORE_DIR:-/nix/store}"; parse_opts "$@" + ) > nix-binary-cache.conf || exit +. "$workingdir/nix-binary-cache.conf" + +echo " +server.port = $PORT +server.modules = ( \"mod_cgi\", \"mod_setenv\", ) +server.document-root = \"$workingdir\" +cgi.assign = ( \".cgi\" => \"@shell@\" ) +setenv.add-request-header = ( \"NIX_BINARY_CACHE_CONFIG\" => \"$workingdir/nix-binary-cache.conf\" ) +" > lighttpd.conf + +cp @out@/nix-binary-cache.cgi . +cp @out@/nix-binary-cache.cgi ./nix-bc.cgi + +ip="$(@iproute@/ip a | @gnugrep@/grep 'inet .* scope global' | @coreutils@/head -n 1)" +ip="${ip%%/*}" +ip="${ip##* }" + +url="http://$ip:$PORT/nix-bc.cgi?" + +echo "Working directory: $workingdir" +echo +echo "Address of the binary cache: $url" +echo +echo "Usage example: NIX_REMOTE= nix-store --option binary-caches '$url'" +echo +echo + +@lighttpd@/lighttpd -D -f "$workingdir/lighttpd.conf" + +cd / +@coreutils@/rm -rf "$workingdir" diff --git a/pkgs/servers/http/nix-binary-cache/nix-binary-cache.cgi.in b/pkgs/servers/http/nix-binary-cache/nix-binary-cache.cgi.in new file mode 100644 index 000000000000..219ab9763ada --- /dev/null +++ b/pkgs/servers/http/nix-binary-cache/nix-binary-cache.cgi.in @@ -0,0 +1,97 @@ +#! @shell@ + +STORE_DIR="${NIX_STORE_DIR:-/nix/store}" +MASS_QUERY=0 +PRIORITY=75 +COMPRESSION=bzip2 +KEY= +KEYNAME=na + +export NIX_REMOTE=daemon + +config="${NIX_BINARY_CACHE_CONFIG:-${HTTP_NIX_BINARY_CACHE_CONFIG:-/etc/nix/nix-binary-cache.cgi.conf}}" +config="$(cd "$(@coreutils@/dirname "$config")"; + @coreutils@/pwd)/$(@coreutils@/basename "$config")" +@coreutils@/test -e "$config" && . "$config" + +header(){ + echo "Content-Type: text/plain; charset=utf-8" + echo +} + +clean_path() { + @gnused@/sed -re "s@^$STORE_DIR/?@@" | @findutils@/xargs +} + +storeq(){ + @nix@/nix-store -q "$@" +} + +sign(){ + test -n "$1" && + @coreutils@/sha256sum | @gnused@/sed -e 's/ .*//' | + @openssl@/openssl rsautl -sign -inkey "$@" | @coreutils@/base64 -w 0 +} + +case "$QUERY_STRING" in + "") + header + echo "Hello, this is a dynamically-generated Nix binary cache" + ;; + /debug) + header + set + ;; + /nix-cache-info) + header + echo "StoreDir: $STORE_DIR" + echo "WantMassQuery: $MASS_QUERY" + echo "Priority: $PRIORITY" + ;; + *.narinfo) + hash=${QUERY_STRING%.narinfo} + hash=${hash#/} + path="$(echo "$STORE_DIR/$hash-"* )" + if [ -n "$path" ] && [ -e "$path" ]; then + header + info="$( + echo "StorePath: $path" + echo "URL: $(@coreutils@/basename "$path" + ).nar.$COMPRESSION" + echo "Compression: $COMPRESSION" + echo "NarHash: $(storeq --hash "$path")" + echo "NarSize: $(storeq --size "$path")" + echo "References: $(storeq --references "$path" | + @coreutils@/tac | clean_path )" + echo "Deriver: $(storeq --deriver "$path" | + clean_path )" + )" + signature="$(echo "$info" | sign "$KEY")" + + echo "$info" + echo "Signature: 1;$KEYNAME;$signature" + + else + exit 1 + fi + ;; + *.nar.xz) + path="$STORE_DIR${QUERY_STRING%.nar.xz}" + if [ -n "$path" ] && [ -e "$path" ]; then + header + @nix@/nix-store --dump "$path" | @xz@/xz + else + exit 1 + fi + ;; + *.nar.bzip2) + path="$STORE_DIR${QUERY_STRING%.nar.bzip2}" + echo "$path" >&2; + if [ -n "$path" ] && [ -e "$path" ]; then + header + @nix@/nix-store --dump "$path" | @bzip2@/bzip2 + else + exit 1 + fi + ;; +esac diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 796da97595ec..cfb4ac4ba823 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6752,6 +6752,8 @@ let ngircd = callPackage ../servers/irc/ngircd { }; + nix-binary-cache = callPackage ../servers/http/nix-binary-cache {}; + nsd = callPackage ../servers/dns/nsd { }; nsq = callPackage ../servers/nsq { }; -- cgit 1.4.1