Skip to content

Commit

Permalink
<nix/fetchurl.nix>: Support xz-compressed NARs
Browse files Browse the repository at this point in the history
  • Loading branch information
edolstra committed Oct 30, 2015
1 parent dae5dc7 commit 1f735a3
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 2 deletions.
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ PKG_CHECK_MODULES([SODIUM], [libsodium],
AC_SUBST(HAVE_SODIUM, [$have_sodium])


# Look for liblzma, a required dependency.
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])


# Whether to use the Boehm garbage collector.
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]),
Expand Down
2 changes: 1 addition & 1 deletion release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ let
src = tarball;

buildInputs =
[ curl perl bzip2 openssl pkgconfig sqlite boehmgc ]
[ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ]
++ lib.optional stdenv.isLinux libsodium;

configureFlags = ''
Expand Down
3 changes: 3 additions & 0 deletions src/libstore/builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "download.hh"
#include "store-api.hh"
#include "archive.hh"
#include "compression.hh"

namespace nix {

Expand All @@ -28,6 +29,8 @@ void builtinFetchurl(const BasicDerivation & drv)

auto unpack = drv.env.find("unpack");
if (unpack != drv.env.end() && unpack->second == "1") {
if (string(data.data, 0, 6) == string("\xfd" "7zXZ\0", 6))
data.data = decompressXZ(data.data);
StringSource source(data.data);
restorePath(storePath, source);
} else
Expand Down
46 changes: 46 additions & 0 deletions src/libutil/compression.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "compression.hh"
#include "types.hh"

#include <lzma.h>

namespace nix {

std::string decompressXZ(const std::string & in)
{
lzma_stream strm = LZMA_STREAM_INIT;

lzma_ret ret = lzma_stream_decoder(
&strm, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK)
throw Error("unable to initialise lzma decoder");

lzma_action action = LZMA_RUN;
uint8_t outbuf[BUFSIZ];
string res;
strm.next_in = (uint8_t *) in.c_str();
strm.avail_in = in.size();
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);

while (true) {

if (strm.avail_in == 0)
action = LZMA_FINISH;

lzma_ret ret = lzma_code(&strm, action);

if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
res.append((char *) outbuf, sizeof(outbuf) - strm.avail_out);
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
}

if (ret == LZMA_STREAM_END)
return res;

if (ret != LZMA_OK)
throw Error("error while decompressing xz file");
}
}

}
9 changes: 9 additions & 0 deletions src/libutil/compression.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <string>

namespace nix {

std::string decompressXZ(const std::string & in);

}
4 changes: 3 additions & 1 deletion src/libutil/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ libutil_DIR := $(d)

libutil_SOURCES := $(wildcard $(d)/*.cc)

libutil_LDFLAGS = -llzma

ifeq ($(HAVE_OPENSSL), 1)
libutil_LDFLAGS = $(OPENSSL_LIBS)
libutil_LDFLAGS += $(OPENSSL_LIBS)
else
libutil_SOURCES += $(d)/md5.c $(d)/sha1.c $(d)/sha256.c
endif
Expand Down
14 changes: 14 additions & 0 deletions tests/fetchurl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ source common.sh

clearStore

# Test fetching a flat file.
hash=$(nix-hash --flat --type sha256 ./fetchurl.sh)

outPath=$(nix-build '<nix/fetchurl.nix>' --argstr url file://$(pwd)/fetchurl.sh --argstr sha256 $hash --no-out-link)

cmp $outPath fetchurl.sh

# Test unpacking a NAR.
rm -rf $TEST_ROOT/archive
mkdir -p $TEST_ROOT/archive
cp ./fetchurl.sh $TEST_ROOT/archive
Expand All @@ -25,3 +27,15 @@ echo $outPath | grep -q 'xyzzy'

test -x $outPath/fetchurl.sh
test -L $outPath/symlink

nix-store --delete $outPath

# Test unpacking a compressed NAR.
narxz=$TEST_ROOT/archive.nar.xz
rm -f $narxz
xz --keep $nar
outPath=$(nix-build '<nix/fetchurl.nix>' --argstr url file://$narxz --argstr sha256 $hash \
--arg unpack true --argstr name xyzzy --no-out-link)

test -x $outPath/fetchurl.sh
test -L $outPath/symlink

0 comments on commit 1f735a3

Please sign in to comment.