From c2033df432af87d0176347858c7d11acfe2ed89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 3 Dec 2012 23:04:47 +0100 Subject: build: Include a copy of Nix's libstore and daemon; build it. * configure.ac: Call `AC_USE_SYSTEM_EXTENSIONS', and `GUIX_SYSTEM_TYPE'. Add `--with-store-dir' option, and substitute `storedir'. Include `config-daemon.ac'. * config-daemon.ac: New file. * Makefile.am [BUILD_DAEMON]: Include `daemon.am'. * daemon.am: New file. * m4/guix.m4 (GUIX_SYSTEM_TYPE): New macro. * nix/libutil/gcrypt-hash.cc, nix/libutil/gcrypt-hash.hh, nix/libutil/md5.h, nix/libutil/sha1.h, nix/libutil/sha256.h, nix/nix-daemon/guix-daemon.cc, nix/nix-daemon/shared.hh: New files. --- .gitignore | 10 +++ Makefile.am | 6 ++ config-daemon.ac | 64 ++++++++++++++++++ configure.ac | 15 ++++- daemon.am | 152 ++++++++++++++++++++++++++++++++++++++++++ m4/guix.m4 | 29 ++++++++ nix/.gitignore | 4 ++ nix/boost/.gitignore | 3 + nix/libstore/.gitignore | 3 + nix/libutil/.gitignore | 2 + nix/libutil/gcrypt-hash.cc | 50 ++++++++++++++ nix/libutil/gcrypt-hash.hh | 39 +++++++++++ nix/libutil/md5.h | 35 ++++++++++ nix/libutil/sha1.h | 35 ++++++++++ nix/libutil/sha256.h | 35 ++++++++++ nix/nix-daemon/guix-daemon.cc | 115 ++++++++++++++++++++++++++++++++ nix/nix-daemon/shared.hh | 37 ++++++++++ 17 files changed, 633 insertions(+), 1 deletion(-) create mode 100644 config-daemon.ac create mode 100644 daemon.am create mode 100644 nix/.gitignore create mode 100644 nix/boost/.gitignore create mode 100644 nix/libstore/.gitignore create mode 100644 nix/libutil/.gitignore create mode 100644 nix/libutil/gcrypt-hash.cc create mode 100644 nix/libutil/gcrypt-hash.hh create mode 100644 nix/libutil/md5.h create mode 100644 nix/libutil/sha1.h create mode 100644 nix/libutil/sha256.h create mode 100644 nix/nix-daemon/guix-daemon.cc create mode 100644 nix/nix-daemon/shared.hh diff --git a/.gitignore b/.gitignore index 1fe15621e2..89f0ae797c 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,13 @@ config.cache /guix-package /guix/config.scm /guix-import +/nix/nix-daemon/nix-daemon.cc +/nix/config.h +/nix/config.h.in +stamp-h[0-9] +/nix/AUTHORS +/nix/COPYING +/libformat.a +/libstore.a +/libutil.a +/guix-daemon diff --git a/Makefile.am b/Makefile.am index 8bb3b55634..7e5be0be2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -222,6 +222,12 @@ SUBDIRS = po info_TEXINFOS = doc/guix.texi EXTRA_DIST += doc/fdl-1.3.texi +if BUILD_DAEMON + +include daemon.am + +endif BUILD_DAEMON + ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = \ --with-libgcrypt-prefix="$(LIBGCRYPT_PREFIX)" \ diff --git a/config-daemon.ac b/config-daemon.ac new file mode 100644 index 0000000000..7570814705 --- /dev/null +++ b/config-daemon.ac @@ -0,0 +1,64 @@ +dnl -*- Autoconf -*- fragment for the C++ daemon. + +AC_ARG_ENABLE([daemon], + [AS_HELP_STRING([--enable-daemon], [build the Nix daemon (C++)])], + [guix_build_daemon="$enableval"], + [guix_build_daemon="no"]) + +AC_MSG_CHECKING([whether to build daemon]) +AC_MSG_RESULT([$guix_build_daemon]) + +dnl C++ environment. This macro must be used unconditionnaly. +AC_PROG_CXX + +if test "x$guix_build_daemon" = "xyes"; then + + AC_PROG_RANLIB + AC_CONFIG_HEADER([nix/config.h]) + + dnl Use 64-bit file system calls so that we can support files > 2 GiB. + AC_SYS_LARGEFILE + + dnl Look for libbz2, a required dependency. + AC_CHECK_LIB([bz2], [BZ2_bzWriteOpen], [true], + [AC_MSG_ERROR([Guix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])]) + AC_CHECK_HEADERS([bzlib.h], [true], + [AC_MSG_ERROR([Guix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])]) + + dnl Look for SQLite, a required dependency. + PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19]) + + AC_DEFINE([NIX_VERSION], ["0.0.0"], [Fake Nix version number.]) + AC_DEFINE_UNQUOTED([SYSTEM], ["\"$guix_system\""], + [Guix host system type--i.e., platform and OS kernel tuple.]) + + case "$LIBGCRYPT_PREFIX" in + no) + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + ;; + *) + LIBGCRYPT_CFLAGS="-I$LIBGCRYPT_PREFIX/include" + LIBGCRYPT_LIBS="-L$LIBGCRYPT_PREFIX/lib -lgcrypt" + ;; + esac + AC_SUBST([LIBGCRYPT_CFLAGS]) + AC_SUBST([LIBGCRYPT_LIBS]) + + save_CFLAGS="$CFLAGS" + save_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBGCRYPT_LDFLAGS" + + have_gcrypt=yes + AC_CHECK_LIB([gcrypt], [gcry_md_open], [:], [have_gcrypt=no]) + AC_CHECK_HEADER([gcrypt.h], [:], [have_gcrypt=no]) + if test "x$have_gcrypt" != "xyes"; then + AC_MSG_ERROR([GNU libgcrypt not found; please install it.]) + fi + + CFLAGS="$save_CFLAGS" + LDFLAGS="$save_LDFLAGS" +fi + +AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"]) diff --git a/configure.ac b/configure.ac index 65fc01857f..6c7be59895 100644 --- a/configure.ac +++ b/configure.ac @@ -12,13 +12,23 @@ AM_INIT_AUTOMAKE([1.11 gnu silent-rules subdir-objects \ AC_CONFIG_SRCDIR([guix.scm]) AC_CONFIG_MACRO_DIR([m4]) +dnl For the C++ code. This must be used early. +AC_USE_SYSTEM_EXTENSIONS + AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.18.1]) guilemoduledir="${datarootdir}/guile/site/2.0" AC_SUBST([guilemoduledir]) -AC_CANONICAL_HOST +GUIX_SYSTEM_TYPE + +AC_ARG_WITH(store-dir, + AC_HELP_STRING([--with-store-dir=PATH], + [path of the store (defaults to /nix/store)]), + [storedir="$withval"], + [storedir="/nix/store"]) +AC_SUBST(storedir) PKG_CHECK_MODULES([GUILE], [guile-2.0]) AC_PATH_PROG([GUILE], [guile]) @@ -83,6 +93,9 @@ AC_SUBST([LIBGCRYPT_PREFIX]) GUIX_ASSERT_LIBGCRYPT_USABLE +AC_CACHE_SAVE + +m4_include([config-daemon.ac]) AC_CONFIG_FILES([Makefile po/Makefile.in diff --git a/daemon.am b/daemon.am new file mode 100644 index 0000000000..e150e54d6b --- /dev/null +++ b/daemon.am @@ -0,0 +1,152 @@ +# Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +# Copyright (C) 2012 Ludovic Courtès +# +# This file is part of Guix. +# +# Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Guix. If not, see . + +# +# Integration of the `guix-daemon' code taken from upstream Nix. +# + +BUILT_SOURCES = nix/libstore/schema.sql.hh +CLEANFILES += $(BUILT_SOURCES) + +noinst_LIBRARIES = libformat.a libutil.a libstore.a + +libformat_a_SOURCES = \ + nix/boost/format/free_funcs.cc \ + nix/boost/format/parsing.cc \ + nix/boost/format/format_implementation.cc + +libformat_headers = \ + nix/boost/weak_ptr.hpp \ + nix/boost/throw_exception.hpp \ + nix/boost/checked_delete.hpp \ + nix/boost/shared_ptr.hpp \ + nix/boost/format.hpp \ + nix/boost/assert.hpp \ + nix/boost/format/macros_default.hpp \ + nix/boost/format/format_fwd.hpp \ + nix/boost/format/format_class.hpp \ + nix/boost/format/exceptions.hpp \ + nix/boost/format/group.hpp \ + nix/boost/format/feed_args.hpp \ + nix/boost/format/internals_fwd.hpp \ + nix/boost/format/internals.hpp \ + nix/boost/detail/workaround.hpp \ + nix/boost/detail/shared_count.hpp \ + nix/boost/enable_shared_from_this.hpp + +libformat_a_CPPFLAGS = \ + -I$(top_srcdir)/nix + +libutil_a_SOURCES = \ + nix/libutil/archive.cc \ + nix/libutil/serialise.cc \ + nix/libutil/immutable.cc \ + nix/libutil/util.cc \ + nix/libutil/xml-writer.cc \ + nix/libutil/hash.cc \ + nix/libutil/gcrypt-hash.cc + +libutil_headers = \ + nix/libutil/immutable.hh \ + nix/libutil/hash.hh \ + nix/libutil/serialise.hh \ + nix/libutil/xml-writer.hh \ + nix/libutil/util.hh \ + nix/libutil/archive.hh \ + nix/libutil/types.hh \ + nix/libutil/gcrypt-hash.hh \ + nix/libutil/md5.h \ + nix/libutil/sha1.h \ + nix/libutil/sha256.h + +libutil_a_CPPFLAGS = \ + -I$(top_builddir)/nix \ + -I$(top_srcdir)/nix/libutil \ + $(libformat_a_CPPFLAGS) + +libstore_a_SOURCES = \ + nix/libstore/gc.cc \ + nix/libstore/globals.cc \ + nix/libstore/misc.cc \ + nix/libstore/references.cc \ + nix/libstore/store-api.cc \ + nix/libstore/optimise-store.cc \ + nix/libstore/local-store.cc \ + nix/libstore/remote-store.cc \ + nix/libstore/build.cc \ + nix/libstore/pathlocks.cc \ + nix/libstore/derivations.cc + +libstore_headers = \ + nix/libstore/references.hh \ + nix/libstore/pathlocks.hh \ + nix/libstore/globals.hh \ + nix/libstore/schema.sql.hh \ + nix/libstore/worker-protocol.hh \ + nix/libstore/remote-store.hh \ + nix/libstore/derivations.hh \ + nix/libstore/misc.hh \ + nix/libstore/local-store.hh \ + nix/libstore/store-api.hh + +libstore_a_CPPFLAGS = \ + $(libutil_a_CPPFLAGS) \ + -I$(top_srcdir)/nix/libstore \ + -DNIX_STORE_DIR=\"$(storedir)\" \ + -DNIX_DATA_DIR=\"$(datadir)\" \ + -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ + -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ + -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ + -DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \ + -DNIX_BIN_DIR=\"$(bindir)\" \ + -DOPENSSL_PATH="\"FIXME--no OpenSSL support\"" + +libstore_a_CFLAGS = \ + $(SQLITE3_CFLAGS) $(LIBGCRYPT_CFLAGS) + +bin_PROGRAMS = guix-daemon + +guix_daemon_SOURCES = \ + nix/nix-daemon/nix-daemon.cc \ + nix/nix-daemon/guix-daemon.cc + +guix_daemon_CPPFLAGS = \ + $(libutil_a_CPPFLAGS) \ + -I$(top_srcdir)/nix/libstore + +guix_daemon_LDADD = \ + libstore.a libutil.a libformat.a -lbz2 \ + $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) + + +noinst_HEADERS = \ + $(libformat_headers) $(libutil_headers) $(libstore_headers) + +nix/libstore/schema.sql.hh: nix/libstore/schema.sql + $(GUILE) --no-auto-compile -c \ + "(use-modules (rnrs io ports)) \ + (call-with-output-file \"$@\" \ + (lambda (out) \ + (call-with-input-file \"$^\" \ + (lambda (in) \ + (write (get-string-all in) out)))))" + +EXTRA_DIST += \ + nix/libstore/schema.sql \ + nix/AUTHORS \ + nix/COPYING diff --git a/m4/guix.m4 b/m4/guix.m4 index 29f928f653..9b5184ff55 100644 --- a/m4/guix.m4 +++ b/m4/guix.m4 @@ -33,3 +33,32 @@ AC_DEFUN([GUIX_ASSERT_LIBGCRYPT_USABLE], if test "x$guix_cv_libgcrypt_usable_p" != "xyes"; then AC_MSG_ERROR([GNU libgcrypt does not appear to be usable; see `--with-libgcrypt-prefix' and `README'.]) fi]) + +dnl GUIX_SYSTEM_TYPE +dnl +dnl Determine the Guix host system type, and store it in the +dnl `guix_system' variable. +AC_DEFUN([GUIX_SYSTEM_TYPE], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM], + [Platform identifier (e.g., `i686-linux').]), + [guix_system="$withval"], + [case "$host_cpu" in + i*86) + machine_name="i686";; + amd64) + machine_name="x86_64";; + *) + machine_name="$host_cpu";; + esac + + case "$host_os" in + linux-gnu*) + # For backward compatibility, strip the `-gnu' part. + guix_system="$machine_name-linux";; + *) + # Strip the version number from names such as `gnu0.3', + # `darwin10.2.0', etc. + guix_system="$machine_name-`echo $host_os | "$SED" -e's/@<:@0-9.@:>@*$//g'`";; + esac]) +]) diff --git a/nix/.gitignore b/nix/.gitignore new file mode 100644 index 0000000000..92d0520cc7 --- /dev/null +++ b/nix/.gitignore @@ -0,0 +1,4 @@ +*.a +*.o +.deps +.dirstamp diff --git a/nix/boost/.gitignore b/nix/boost/.gitignore new file mode 100644 index 0000000000..1f188e3b65 --- /dev/null +++ b/nix/boost/.gitignore @@ -0,0 +1,3 @@ +*.hpp +*.cpp +*.cc diff --git a/nix/libstore/.gitignore b/nix/libstore/.gitignore new file mode 100644 index 0000000000..512a0d022f --- /dev/null +++ b/nix/libstore/.gitignore @@ -0,0 +1,3 @@ +*.cc +*.hh +/schema.sql diff --git a/nix/libutil/.gitignore b/nix/libutil/.gitignore new file mode 100644 index 0000000000..e539428b1b --- /dev/null +++ b/nix/libutil/.gitignore @@ -0,0 +1,2 @@ +*.cc +*.hh diff --git a/nix/libutil/gcrypt-hash.cc b/nix/libutil/gcrypt-hash.cc new file mode 100644 index 0000000000..de7e5afc1a --- /dev/null +++ b/nix/libutil/gcrypt-hash.cc @@ -0,0 +1,50 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#include +#include + +extern "C" { + +void +guix_hash_init (struct guix_hash_context *ctx, gcry_md_algo_t algo) +{ + gcry_error_t err; + + err = gcry_md_open (&ctx->md_handle, algo, 0); + assert (err == GPG_ERR_NO_ERROR); +} + +void +guix_hash_update (struct guix_hash_context *ctx, const void *buffer, size_t len) +{ + gcry_md_write (ctx->md_handle, buffer, len); +} + +void +guix_hash_final (void *resbuf, struct guix_hash_context *ctx, + gcry_md_algo_t algo) +{ + memcpy (resbuf, gcry_md_read (ctx->md_handle, algo), + gcry_md_get_algo_dlen (algo)); + gcry_md_close (ctx->md_handle); +} + +} diff --git a/nix/libutil/gcrypt-hash.hh b/nix/libutil/gcrypt-hash.hh new file mode 100644 index 0000000000..1e26398540 --- /dev/null +++ b/nix/libutil/gcrypt-hash.hh @@ -0,0 +1,39 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +/* An OpenSSL-like interface to GNU libgcrypt cryptographic hash + functions. */ + +#pragma once +#include +#include + +extern "C" { + +struct guix_hash_context +{ + gcry_md_hd_t md_handle; +}; + +extern void guix_hash_init (struct guix_hash_context *ctx, gcry_md_algo_t algo); +extern void guix_hash_update (struct guix_hash_context *ctx, const void *buffer, + size_t len); +extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx, + gcry_md_algo_t algo); + +} diff --git a/nix/libutil/md5.h b/nix/libutil/md5.h new file mode 100644 index 0000000000..c275e381f8 --- /dev/null +++ b/nix/libutil/md5.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define MD5_CTX guix_hash_context + +static inline void +MD5_Init (struct MD5_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_MD5); +} + +#define MD5_Update guix_hash_update + +static inline void +MD5_Final (void *resbuf, struct MD5_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_MD5); +} diff --git a/nix/libutil/sha1.h b/nix/libutil/sha1.h new file mode 100644 index 0000000000..8af92725ea --- /dev/null +++ b/nix/libutil/sha1.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define SHA_CTX guix_hash_context + +static inline void +SHA1_Init (struct SHA_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_SHA1); +} + +#define SHA1_Update guix_hash_update + +static inline void +SHA1_Final (void *resbuf, struct SHA_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_SHA1); +} diff --git a/nix/libutil/sha256.h b/nix/libutil/sha256.h new file mode 100644 index 0000000000..c436d6402c --- /dev/null +++ b/nix/libutil/sha256.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define SHA256_CTX guix_hash_context + +static inline void +SHA256_Init (struct SHA256_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_SHA256); +} + +#define SHA256_Update guix_hash_update + +static inline void +SHA256_Final (void *resbuf, struct SHA256_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_SHA256); +} diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc new file mode 100644 index 0000000000..43d4113493 --- /dev/null +++ b/nix/nix-daemon/guix-daemon.cc @@ -0,0 +1,115 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#include +#include "shared.hh" +#include + +#include +#include + +/* Variables used by `nix-daemon.cc'. */ +volatile ::sig_atomic_t blockInt; +char **argvSaved; + +using namespace nix; + +/* Entry point in `nix-daemon.cc'. */ +extern void run (Strings args); + + +/* Command-line options. */ + +const char *argp_program_version = + "guix-daemon (" PACKAGE_NAME ") " PACKAGE_VERSION; +const char *argp_program_bug_address = PACKAGE_BUGREPORT; + +static char doc[] = +"guix-daemon -- perform derivation builds and store accesses\ +\v\ +This program is a daemon meant to run in the background. It serves \ +requests sent over a Unix-domain socket. It accesses the store, and \ +builds derivations on behalf of its clients."; + +#define GUIX_OPT_SYSTEM 1 +#define GUIX_OPT_DISABLE_CHROOT 2 +#define GUIX_OPT_DISABLE_LOG_COMPRESSION 3 + +static const struct argp_option options[] = + { + { "system", GUIX_OPT_SYSTEM, "SYSTEM", 0, + "Assume SYSTEM as the current system type" }, + { "build-cores", 'C', "N", 0, + "Use N CPU cores to build each derivation; 0 means as many as available" }, + { "max-jobs", 'M', "N", 0, + "Allow at most N build jobs" }, + { "disable-chroot", GUIX_OPT_DISABLE_CHROOT, 0, 0, + "Disable chroot builds" }, + { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0, + "Disable compression of the build logs" }, + { 0, 0, 0, 0, 0 } + }; + +/* Parse a single option. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case GUIX_OPT_DISABLE_CHROOT: + settings.useChroot = false; + break; + case GUIX_OPT_DISABLE_LOG_COMPRESSION: + settings.compressLog = false; + break; + case 'C': + settings.buildCores = atoi (arg); + break; + case 'M': + settings.maxBuildJobs = atoi (arg); + break; + case GUIX_OPT_SYSTEM: + settings.thisSystem = arg; + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +/* Argument parsing. */ +static struct argp argp = { options, parse_opt, 0, doc }; + + + +int +main (int argc, char *argv[]) +{ + Strings nothing; + + settings.useChroot = true; + settings.processEnvironment (); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + argvSaved = argv; + run (nothing); +} diff --git a/nix/nix-daemon/shared.hh b/nix/nix-daemon/shared.hh new file mode 100644 index 0000000000..a03c09c036 --- /dev/null +++ b/nix/nix-daemon/shared.hh @@ -0,0 +1,37 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +/* Replacement for Nix's libmain/shared.hh. */ + +#pragma once + +#include + +#include +#include + +static inline void +showManPage (const char *name) +{ + /* This idea is evil. Abort. */ + abort (); +} + +extern volatile ::sig_atomic_t blockInt; + +extern char **argvSaved; -- cgit v1.2.3 From e05385192ca201d44d607af162f197ad39fd1987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sun, 2 Dec 2012 22:54:19 +0100 Subject: build: Add Nix as a sub-module. * .gitmodules, nix-upstream: New files. --- .gitmodules | 3 +++ nix-upstream | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 nix-upstream diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..0c3b046608 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "nix-upstream"] + path = nix-upstream + url = http://github.com/NixOS/nix.git diff --git a/nix-upstream b/nix-upstream new file mode 160000 index 0000000000..8eed07cda4 --- /dev/null +++ b/nix-upstream @@ -0,0 +1 @@ +Subproject commit 8eed07cda4c193bfcdd6ac4345ac6fb54aee0269 -- cgit v1.2.3 From b49ffe2d678b5df4192fb9be4ad50bed9d6d5b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 3 Dec 2012 22:43:26 +0100 Subject: build: Add `bootstrap' and `sync-with-upstream' scripts. * bootstrap, nix/sync-with-upstream: New files. * Makefile.am (EXTRA_DIST): Add `bootstrap'. * daemon.am (EXTRA_DIST): Add `nix/sync-with-upstream'. --- Makefile.am | 1 + bootstrap | 16 +++++++++++++ daemon.am | 1 + nix/sync-with-upstream | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100755 bootstrap create mode 100755 nix/sync-with-upstream diff --git a/Makefile.am b/Makefile.am index 7e5be0be2a..147ba1949e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -194,6 +194,7 @@ EXTRA_DIST = \ srfi/srfi-64.upstream.scm \ tests/test.drv \ build-aux/config.rpath \ + bootstrap \ release.nix \ $(TESTS) diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000000..e445af2f2c --- /dev/null +++ b/bootstrap @@ -0,0 +1,16 @@ +#!/bin/sh + +# Import missing source files and create the build system. + +set -e -x + +top_srcdir="$PWD" +export top_srcdir + +if [ ! -d nix-upstream ] +then + git submodule init +fi +git submodule update + +exec autoreconf -vfi diff --git a/daemon.am b/daemon.am index e150e54d6b..79e2715c74 100644 --- a/daemon.am +++ b/daemon.am @@ -147,6 +147,7 @@ nix/libstore/schema.sql.hh: nix/libstore/schema.sql (write (get-string-all in) out)))))" EXTRA_DIST += \ + nix/sync-with-upstream \ nix/libstore/schema.sql \ nix/AUTHORS \ nix/COPYING diff --git a/nix/sync-with-upstream b/nix/sync-with-upstream new file mode 100755 index 0000000000..324dcb27c9 --- /dev/null +++ b/nix/sync-with-upstream @@ -0,0 +1,64 @@ +#!/bin/sh +# Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +# Copyright (C) 2012 Ludovic Courtès +# +# This file is part of Guix. +# +# Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Guix. If not, see . + +# +# Update the local copy of Nix source code needed to build the daemon. +# Assume GNU Coreutils and Git are available. +# + +top_srcdir="${top_srcdir:-..}" + +log() +{ + echo "sync-with-upstream: $@" >&2 +} + +# checked_in_p FILE +checked_in_p() +{ + ( cd "$top_srcdir" ; + git ls-tree HEAD -- "nix/$1" | grep "$1" > /dev/null ) +} + +if [ ! -d "$top_srcdir/build-aux" ] +then + log "\`$top_srcdir' is not the valid top-level source directory" + exit 1 +fi + +set -e +for upstream_file in `cd "$top_srcdir/nix-upstream/src" ; + find . -name \*.c -or -name \*.h -or -name \*.cc -or -name \*.hh \ + -or -name \*.cpp -or -name \*.hpp -or -name \*.sql` +do + if grep "$upstream_file" "$top_srcdir/daemon.am" > /dev/null + then + if checked_in_p "$upstream_file" + then + log "skipping \`$upstream_file', which has a checked-in copy" + else + ( cd "$top_srcdir/nix-upstream/src" && \ + cp -v --parents "$upstream_file" ../../nix ) + fi + else + log "skipping \`$upstream_file', which is not used" + fi +done + +cp -v "$top_srcdir/nix-upstream/"{COPYING,AUTHORS} "$top_srcdir/nix" -- cgit v1.2.3 From 0adb527600a40055383970330f572e9f0399cd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 4 Dec 2012 23:10:54 +0100 Subject: daemon: Fix typo in libgcrypt bindings. * nix/libutil/md5.h (MD5_Final): Pass RESBUF as the first argument to `guix_hash_final'. * nix/libutil/sha1.h (SHA1_Final): Likewise. * nix/libutil/sha256.h (SHA256_Final): Likewise. --- nix/libutil/md5.h | 2 +- nix/libutil/sha1.h | 2 +- nix/libutil/sha256.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nix/libutil/md5.h b/nix/libutil/md5.h index c275e381f8..7fa29087d7 100644 --- a/nix/libutil/md5.h +++ b/nix/libutil/md5.h @@ -31,5 +31,5 @@ MD5_Init (struct MD5_CTX *ctx) static inline void MD5_Final (void *resbuf, struct MD5_CTX *ctx) { - guix_hash_final (ctx, ctx, GCRY_MD_MD5); + guix_hash_final (resbuf, ctx, GCRY_MD_MD5); } diff --git a/nix/libutil/sha1.h b/nix/libutil/sha1.h index 8af92725ea..0eca8e310d 100644 --- a/nix/libutil/sha1.h +++ b/nix/libutil/sha1.h @@ -31,5 +31,5 @@ SHA1_Init (struct SHA_CTX *ctx) static inline void SHA1_Final (void *resbuf, struct SHA_CTX *ctx) { - guix_hash_final (ctx, ctx, GCRY_MD_SHA1); + guix_hash_final (resbuf, ctx, GCRY_MD_SHA1); } diff --git a/nix/libutil/sha256.h b/nix/libutil/sha256.h index c436d6402c..a91f18f689 100644 --- a/nix/libutil/sha256.h +++ b/nix/libutil/sha256.h @@ -31,5 +31,5 @@ SHA256_Init (struct SHA256_CTX *ctx) static inline void SHA256_Final (void *resbuf, struct SHA256_CTX *ctx) { - guix_hash_final (ctx, ctx, GCRY_MD_SHA256); + guix_hash_final (resbuf, ctx, GCRY_MD_SHA256); } -- cgit v1.2.3 From ca8dbb7d4e663bcd9aed91606c253ac384124fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 4 Dec 2012 23:12:40 +0100 Subject: build: daemon: Remove extraneous quotes in CPP macro `SYSTEM'. * config-daemon.ac: Remove extraneous quotes in definition of `SYSTEM'. --- config-daemon.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-daemon.ac b/config-daemon.ac index 7570814705..6420c86116 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -29,7 +29,7 @@ if test "x$guix_build_daemon" = "xyes"; then PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19]) AC_DEFINE([NIX_VERSION], ["0.0.0"], [Fake Nix version number.]) - AC_DEFINE_UNQUOTED([SYSTEM], ["\"$guix_system\""], + AC_DEFINE_UNQUOTED([SYSTEM], ["$guix_system"], [Guix host system type--i.e., platform and OS kernel tuple.]) case "$LIBGCRYPT_PREFIX" in -- cgit v1.2.3 From 2606bbcf917c0bc1b2ed10a104acfbbe151a941b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 4 Dec 2012 23:13:59 +0100 Subject: build: daemon: Add missing feature tests. * config-daemon.ac: Add feature tests needed for the daemon code. Taken from Nix's `configure.ac'. --- config-daemon.ac | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/config-daemon.ac b/config-daemon.ac index 6420c86116..a10be14632 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -59,6 +59,38 @@ if test "x$guix_build_daemon" = "xyes"; then CFLAGS="$save_CFLAGS" LDFLAGS="$save_LDFLAGS" + + dnl Chroot support. + AC_CHECK_FUNCS([chroot unshare]) + AC_CHECK_HEADERS([sched.h sys/param.h sys/mount.h]) + + dnl Check for lutimes, optionally used for changing the mtime of + dnl symlinks. + AC_CHECK_FUNCS([lutimes]) + + dnl Check whether the store optimiser can optimise symlinks. + AC_MSG_CHECKING([whether it is possible to create a link to a symlink]) + ln -s bla tmp_link + if ln tmp_link tmp_link2 2> /dev/null; then + AC_MSG_RESULT(yes) + AC_DEFINE(CAN_LINK_SYMLINK, 1, [Whether link() works on symlinks.]) + else + AC_MSG_RESULT(no) + fi + rm -f tmp_link tmp_link2 + + dnl Check for . + AC_LANG_PUSH(C++) + AC_CHECK_HEADERS([locale]) + AC_LANG_POP(C++) + + + dnl Check whether we have the `personality' syscall, which allows us + dnl to do i686-linux builds on x86_64-linux machines. + AC_CHECK_HEADERS([sys/personality.h]) + + dnl Check for (for immutable file support). + AC_CHECK_HEADERS([linux/fs.h]) fi AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"]) -- cgit v1.2.3 From d23077dc5ca1517bd6d1600664fe2303b86eb16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 4 Dec 2012 23:16:11 +0100 Subject: daemon: Add test. * daemon.am (test_root, AM_TESTS_ENVIRONMENT): New variables. (clean-local): New target. * tests/guix-daemon.sh: New file. --- .gitignore | 1 + daemon.am | 12 ++++++++++++ tests/guix-daemon.sh | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 tests/guix-daemon.sh diff --git a/.gitignore b/.gitignore index 89f0ae797c..d39ad6ed96 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ stamp-h[0-9] /libstore.a /libutil.a /guix-daemon +/test-tmp diff --git a/daemon.am b/daemon.am index 79e2715c74..48b0871a97 100644 --- a/daemon.am +++ b/daemon.am @@ -151,3 +151,15 @@ EXTRA_DIST += \ nix/libstore/schema.sql \ nix/AUTHORS \ nix/COPYING + +# Temporary directory used to store the daemon's data. +test_root = $(abs_top_builddir)/test-tmp + +AM_TESTS_ENVIRONMENT += \ + TEST_ROOT="$(test_root)" + +TESTS += \ + tests/guix-daemon.sh + +clean-local: + -rm -rf "$(test_root)" diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh new file mode 100644 index 0000000000..d7926b2376 --- /dev/null +++ b/tests/guix-daemon.sh @@ -0,0 +1,46 @@ +# Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +# Copyright (C) 2012 Ludovic Courtès +# +# This file is part of Guix. +# +# Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Guix. If not, see . + +# +# Test the daemon. +# + +set -e + +NIX_SUBSTITUTERS="" # don't resort to substituters +NIX_IGNORE_SYMLINK_STORE=1 # in case the store is a symlink +NIX_STORE_DIR="$TEST_ROOT/store" +NIX_LOCALSTATE_DIR="$TEST_ROOT/var" +NIX_LOG_DIR="$TEST_ROOT/var/log/nix" +NIX_STATE_DIR="$TEST_ROOT/var/nix" +NIX_DB_DIR="$TEST_ROOT/db" +export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ + NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR + +guix-daemon --version +guix-build --version + +# Launch the daemon without chroot support because is may be +# unavailable, for instance if we're not running as root. +guix-daemon --disable-chroot & + +daemon_pid=$! +trap "kill $daemon_pid" EXIT + +guix-build -e '(@ (distro packages bootstrap) %bootstrap-guile)' +guix-build coreutils -n -- cgit v1.2.3 From 8b15ac6700f1345e9efa709dea6e4efcbdaf6d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 5 Dec 2012 15:22:28 +0100 Subject: daemon: Disable use of chroots when support is lacking. * nix/nix-daemon/guix-daemon.cc (options)[!HAVE_CHROOT]: Mention that `--disable-chroot' has no effect. (main)[!HAVE_CHROOT]: Set `useChroot' to false. --- nix/nix-daemon/guix-daemon.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc index 43d4113493..7a3b178eab 100644 --- a/nix/nix-daemon/guix-daemon.cc +++ b/nix/nix-daemon/guix-daemon.cc @@ -61,7 +61,12 @@ static const struct argp_option options[] = { "max-jobs", 'M', "N", 0, "Allow at most N build jobs" }, { "disable-chroot", GUIX_OPT_DISABLE_CHROOT, 0, 0, - "Disable chroot builds" }, + "Disable chroot builds" +#ifndef HAVE_CHROOT + " (chroots are not supported in this configuration, so " + "this option has no effect)" +#endif + }, { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0, "Disable compression of the build logs" }, { 0, 0, 0, 0, 0 } @@ -105,7 +110,12 @@ main (int argc, char *argv[]) { Strings nothing; +#ifdef HAVE_CHROOT settings.useChroot = true; +#else + settings.useChroot = false; +#endif + settings.processEnvironment (); argp_parse (&argp, argc, argv, 0, 0, 0); -- cgit v1.2.3 From f5c82e15e0e76b855bc4cc88ffb79331b7083f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 5 Dec 2012 16:29:28 +0100 Subject: daemon: Add `list-runtime-roots' script. * nix/scripts/list-runtime-roots.in: New file. * config-daemon.ac: Add `AC_CONFIG_FILES' invocation for it. * daemon.am (nodist_pkglibexec_SCRIPTS): New variable. (AM_TESTS_ENVIRONMENT): Define `top_builddir'. * tests/guix-daemon.sh: Export `NIX_ROOT_FINDER'. * nix/sync-with-upstream: Substitute the path to the root finder in libstore/gc.cc. --- .gitignore | 1 + config-daemon.ac | 3 + daemon.am | 4 ++ nix/scripts/list-runtime-roots.in | 116 ++++++++++++++++++++++++++++++++++++++ nix/sync-with-upstream | 4 ++ tests/guix-daemon.sh | 4 +- 6 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 nix/scripts/list-runtime-roots.in diff --git a/.gitignore b/.gitignore index d39ad6ed96..3ef17152ba 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ stamp-h[0-9] /libutil.a /guix-daemon /test-tmp +/nix/scripts/list-runtime-roots diff --git a/config-daemon.ac b/config-daemon.ac index a10be14632..946f6e453d 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -91,6 +91,9 @@ if test "x$guix_build_daemon" = "xyes"; then dnl Check for (for immutable file support). AC_CHECK_HEADERS([linux/fs.h]) + + AC_CONFIG_FILES([nix/scripts/list-runtime-roots], + [chmod +x nix/scripts/list-runtime-roots]) fi AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"]) diff --git a/daemon.am b/daemon.am index 48b0871a97..f5d58ea275 100644 --- a/daemon.am +++ b/daemon.am @@ -146,6 +146,9 @@ nix/libstore/schema.sql.hh: nix/libstore/schema.sql (lambda (in) \ (write (get-string-all in) out)))))" +nodist_pkglibexec_SCRIPTS = \ + nix/scripts/list-runtime-roots + EXTRA_DIST += \ nix/sync-with-upstream \ nix/libstore/schema.sql \ @@ -156,6 +159,7 @@ EXTRA_DIST += \ test_root = $(abs_top_builddir)/test-tmp AM_TESTS_ENVIRONMENT += \ + top_builddir="$(abs_top_builddir)" \ TEST_ROOT="$(test_root)" TESTS += \ diff --git a/nix/scripts/list-runtime-roots.in b/nix/scripts/list-runtime-roots.in new file mode 100644 index 0000000000..5c21ae543d --- /dev/null +++ b/nix/scripts/list-runtime-roots.in @@ -0,0 +1,116 @@ +#!@GUILE@ -ds +!# +;;; Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +;;; Copyright (C) 2012 Ludovic Courtès +;;; +;;; This file is part of Guix. +;;; +;;; Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Guix. If not, see . + +;;; +;;; List files being used at run time; these files are garbage collector +;;; roots. This is equivalent to `find-runtime-roots.pl' in Nix. +;;; + +(use-modules (ice-9 ftw) + (ice-9 regex) + (ice-9 rdelim) + (ice-9 popen) + (srfi srfi-1) + (srfi srfi-26)) + +(define %proc-directory + ;; Mount point of Linuxish /proc file system. + "/proc") + +(define (proc-file-roots dir file) + "Return a one-element list containing the file pointed to by DIR/FILE, +or the empty list." + (or (and=> (false-if-exception (readlink (string-append dir "/" file))) + list) + '())) + +(define proc-exe-roots (cut proc-file-roots <> "exe")) +(define proc-cwd-roots (cut proc-file-roots <> "cwd")) + +(define (proc-fd-roots dir) + "Return the list of store files referenced by DIR, which is a +/proc/XYZ directory." + (let ((dir (string-append dir "/fd"))) + (filter-map (lambda (file) + (let ((target (false-if-exception + (readlink (string-append dir "/" file))))) + (and target + (string-prefix? "/" target) + target))) + (scandir dir string->number)))) + +(define (proc-maps-roots dir) + "Return the list of store files referenced by DIR, which is a +/proc/XYZ directory." + (define %file-mapping-line + (make-regexp "^.*[[:blank:]]+/([^ ]+)$")) + + (call-with-input-file (string-append dir "/maps") + (lambda (maps) + (let loop ((line (read-line maps)) + (roots '())) + (cond ((eof-object? line) + roots) + ((regexp-exec %file-mapping-line line) + => + (lambda (match) + (let ((file (string-append "/" + (match:substring match 1)))) + (loop (read-line maps) + (cons file roots))))) + (else + (loop (read-line maps) roots))))))) + +(define (lsof-roots) + "Return the list of roots as found by calling `lsof'." + (catch 'system + (lambda () + (let ((pipe (open-pipe* OPEN_READ "lsof" "-n" "-w" "-F" "n"))) + (define %file-rx + (make-regexp "^n/(.*)$")) + + (let loop ((line (read-line pipe)) + (roots '())) + (cond ((eof-object? line) + (begin + (close-pipe pipe) + roots)) + ((regexp-exec %file-rx line) + => + (lambda (match) + (loop (read-line pipe) + (cons (string-append "/" + (match:substring match 1)) + roots)))) + (else + (loop (read-line pipe) roots)))))) + (lambda _ + '()))) + +(let ((proc (format #f "~a/~a" %proc-directory (getpid)))) + (for-each (cut simple-format #t "~a~%" <>) + (delete-duplicates + (let ((proc-roots (if (file-exists? proc) + (append (proc-exe-roots proc) + (proc-cwd-roots proc) + (proc-fd-roots proc) + (proc-maps-roots proc)) + '()))) + (append proc-roots (lsof-roots)))))) diff --git a/nix/sync-with-upstream b/nix/sync-with-upstream index 324dcb27c9..69bd1fbee7 100755 --- a/nix/sync-with-upstream +++ b/nix/sync-with-upstream @@ -62,3 +62,7 @@ do done cp -v "$top_srcdir/nix-upstream/"{COPYING,AUTHORS} "$top_srcdir/nix" + +# Substitutions. +sed -i "$top_srcdir/nix/libstore/gc.cc" \ + -e 's|/nix/find-runtime-roots\.pl|/guix/list-runtime-roots|g' diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh index d7926b2376..b6b92a78d4 100644 --- a/tests/guix-daemon.sh +++ b/tests/guix-daemon.sh @@ -29,8 +29,10 @@ NIX_LOCALSTATE_DIR="$TEST_ROOT/var" NIX_LOG_DIR="$TEST_ROOT/var/log/nix" NIX_STATE_DIR="$TEST_ROOT/var/nix" NIX_DB_DIR="$TEST_ROOT/db" +NIX_ROOT_FINDER="$top_builddir/nix/scripts/list-runtime-roots" export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ - NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR + NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \ + NIX_ROOT_FINDER guix-daemon --version guix-build --version -- cgit v1.2.3 From b980f0f9fd6f926f2a1130f77bd3cdb70e741429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 5 Dec 2012 22:41:58 +0100 Subject: tests: Remove hard-coded /nix/store. * tests/utils.scm ("store-path-package-name"): Use (%store-prefix) instead of a hard-coded "/nix/store". --- tests/utils.scm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/utils.scm b/tests/utils.scm index 0a6e8a0833..ba04e281eb 100644 --- a/tests/utils.scm +++ b/tests/utils.scm @@ -18,7 +18,7 @@ (define-module (test-utils) #:use-module (guix utils) - #:use-module ((guix store) #:select (store-path-package-name)) + #:use-module ((guix store) #:select (%store-prefix store-path-package-name)) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-64) @@ -127,7 +127,8 @@ (test-equal "store-path-package-name" "bash-4.2-p24" (store-path-package-name - "/nix/store/qvs2rj2ia5vci3wsdb7qvydrmacig4pg-bash-4.2-p24")) + (string-append (%store-prefix) + "/qvs2rj2ia5vci3wsdb7qvydrmacig4pg-bash-4.2-p24"))) (test-end) -- cgit v1.2.3 From 69cfce50dbb2000c5f5d98f0f364fe324004bf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 00:03:26 +0100 Subject: build: Run all the tests against the just-built daemon. * test-env.in: New file. * configure.ac: Add it to `AC_CONFIG_FILES' and `commands-exec'. * config-daemon.ac: Set and substitute `GUIX_TEST_ROOT'. * Makefile.am (SCM_LOG_COMPILER, SH_LOG_COMPILER): Use it in lieu of `pre-inst-env'. * daemon.am (test_root): Remove (AM_TESTS_ENVIRONMENT): Remove `TEST_ROOT'. (clean-local): Use $(GUIX_TEST_ROOT); make files writable before removing them.guix_test_root * tests/guix-daemon.sh: Remove `NIX_' variable settings; don't launch `guix-daemon'. --- .gitignore | 1 + Makefile.am | 4 ++-- config-daemon.ac | 6 ++++++ configure.ac | 5 +++-- daemon.am | 9 +++------ test-env.in | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/guix-daemon.sh | 19 ------------------- 7 files changed, 68 insertions(+), 29 deletions(-) create mode 100644 test-env.in diff --git a/.gitignore b/.gitignore index 3ef17152ba..8f224467c9 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ stamp-h[0-9] /guix-daemon /test-tmp /nix/scripts/list-runtime-roots +/test-env diff --git a/Makefile.am b/Makefile.am index 101ac1dfdb..bb5dfbe0f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -181,10 +181,10 @@ TEST_EXTENSIONS = .scm .sh AM_TESTS_ENVIRONMENT = abs_top_srcdir="$(abs_top_srcdir)" -SCM_LOG_COMPILER = $(top_builddir)/pre-inst-env $(GUILE) +SCM_LOG_COMPILER = $(top_builddir)/test-env $(GUILE) AM_SCM_LOG_FLAGS = --no-auto-compile -L "$(top_srcdir)" -SH_LOG_COMPILER = $(top_builddir)/pre-inst-env $(SHELL) +SH_LOG_COMPILER = $(top_builddir)/test-env $(SHELL) AM_SH_LOG_FLAGS = -x -e EXTRA_DIST = \ diff --git a/config-daemon.ac b/config-daemon.ac index 946f6e453d..edd372fba9 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -92,6 +92,12 @@ if test "x$guix_build_daemon" = "xyes"; then dnl Check for (for immutable file support). AC_CHECK_HEADERS([linux/fs.h]) + dnl Temporary directory used to store the daemon's data. + AC_MSG_CHECKING([for unit test root]) + GUIX_TEST_ROOT="`pwd`/test-tmp" + AC_MSG_RESULT([$GUIX_TEST_ROOT]) + AC_SUBST([GUIX_TEST_ROOT]) + AC_CONFIG_FILES([nix/scripts/list-runtime-roots], [chmod +x nix/scripts/list-runtime-roots]) fi diff --git a/configure.ac b/configure.ac index 6c7be59895..5509735d8e 100644 --- a/configure.ac +++ b/configure.ac @@ -104,9 +104,10 @@ AC_CONFIG_FILES([Makefile guix-download guix-import guix-package - pre-inst-env]) + pre-inst-env + test-env]) AC_CONFIG_COMMANDS([commands-exec], - [chmod +x guix-build guix-download guix-import guix-package pre-inst-env]) + [chmod +x guix-build guix-download guix-import guix-package pre-inst-env test-env]) AC_OUTPUT diff --git a/daemon.am b/daemon.am index f5d58ea275..8c2c22dd88 100644 --- a/daemon.am +++ b/daemon.am @@ -155,15 +155,12 @@ EXTRA_DIST += \ nix/AUTHORS \ nix/COPYING -# Temporary directory used to store the daemon's data. -test_root = $(abs_top_builddir)/test-tmp - AM_TESTS_ENVIRONMENT += \ - top_builddir="$(abs_top_builddir)" \ - TEST_ROOT="$(test_root)" + top_builddir="$(abs_top_builddir)" TESTS += \ tests/guix-daemon.sh clean-local: - -rm -rf "$(test_root)" + -find "$(GUIX_TEST_ROOT)" | xargs chmod +w + -rm -rf "$(GUIX_TEST_ROOT)" diff --git a/test-env.in b/test-env.in new file mode 100644 index 0000000000..9eb03dd498 --- /dev/null +++ b/test-env.in @@ -0,0 +1,53 @@ +#!/bin/sh + +# Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +# Copyright (C) 2012 Ludovic Courtès +# +# This file is part of Guix. +# +# Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Guix. If not, see . + +# Usage: ./test-env COMMAND ARG... +# +# Run the daemon in the build directory, and run COMMAND within +# `pre-inst-env'. This is used to run unit tests with the just-built +# daemon, unless `--disable-daemon' was passed at configure time. + +if [ -x "@abs_top_builddir@/guix-daemon" ] +then + NIX_SUBSTITUTERS="" # don't resort to substituters + NIX_IGNORE_SYMLINK_STORE=1 # in case the store is a symlink + NIX_STORE_DIR="@GUIX_TEST_ROOT@/store" + NIX_LOCALSTATE_DIR="@GUIX_TEST_ROOT@/var" + NIX_LOG_DIR="@GUIX_TEST_ROOT@/var/log/nix" + NIX_STATE_DIR="@GUIX_TEST_ROOT@/var/nix-$$" # allow for parallel tests + NIX_DB_DIR="@GUIX_TEST_ROOT@/db" + NIX_ROOT_FINDER="@abs_top_builddir@/nix/scripts/list-runtime-roots" + export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ + NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \ + NIX_ROOT_FINDER + + # Do that because store.scm calls `canonicalize-path' on it. + mkdir -p "$NIX_STORE_DIR" + + # Launch the daemon without chroot support because is may be + # unavailable, for instance if we're not running as root. + "@abs_top_builddir@/guix-daemon" --disable-chroot & + + daemon_pid=$! + trap "kill $daemon_pid ; rm -rf $NIX_STATE_DIR" EXIT +fi + +"@abs_top_builddir@/pre-inst-env" "$@" +exit $? diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh index b6b92a78d4..b942cbd546 100644 --- a/tests/guix-daemon.sh +++ b/tests/guix-daemon.sh @@ -22,27 +22,8 @@ set -e -NIX_SUBSTITUTERS="" # don't resort to substituters -NIX_IGNORE_SYMLINK_STORE=1 # in case the store is a symlink -NIX_STORE_DIR="$TEST_ROOT/store" -NIX_LOCALSTATE_DIR="$TEST_ROOT/var" -NIX_LOG_DIR="$TEST_ROOT/var/log/nix" -NIX_STATE_DIR="$TEST_ROOT/var/nix" -NIX_DB_DIR="$TEST_ROOT/db" -NIX_ROOT_FINDER="$top_builddir/nix/scripts/list-runtime-roots" -export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ - NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \ - NIX_ROOT_FINDER - guix-daemon --version guix-build --version -# Launch the daemon without chroot support because is may be -# unavailable, for instance if we're not running as root. -guix-daemon --disable-chroot & - -daemon_pid=$! -trap "kill $daemon_pid" EXIT - guix-build -e '(@ (distro packages bootstrap) %bootstrap-guile)' guix-build coreutils -n -- cgit v1.2.3 From d8eea3d2bce9c9e834210237090947de4600cfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 5 Dec 2012 23:02:47 +0100 Subject: build: Capture configure-time settings in (guix config). * configure.ac: Compute and substitute `guix_localstatedir'. * m4/guix.m4: Substitute `guix_system'. * guix/config.scm.in (%store-directory, %store-directory, %system): New variables. * guix/store.scm (%nix-state-dir): Remove. (%default-socket-path): Use %STATE-DIRECTORY as the default. (%store-prefix): Use %STORE-DIRECTORY as the default. * guix/utils.scm (%current-system): Default to %SYSTEM. --- configure.ac | 5 +++++ guix/config.scm.in | 12 ++++++++++++ guix/store.scm | 8 ++++---- guix/utils.scm | 3 ++- m4/guix.m4 | 1 + 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 5509735d8e..fdc1931b3c 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,11 @@ AC_ARG_WITH(store-dir, [storedir="/nix/store"]) AC_SUBST(storedir) +# Prepare a version of $localstatedir that does not contain references +# to shell variables. +guix_localstatedir="`eval echo $localstatedir | sed -e "s|NONE|/usr/local|g"`" +AC_SUBST([guix_localstatedir]) + PKG_CHECK_MODULES([GUILE], [guile-2.0]) AC_PATH_PROG([GUILE], [guile]) AC_PATH_PROG([GUILD], [guild]) diff --git a/guix/config.scm.in b/guix/config.scm.in index 462dcd0ed1..4717b1c967 100644 --- a/guix/config.scm.in +++ b/guix/config.scm.in @@ -20,6 +20,9 @@ #:export (%guix-package-name %guix-version %guix-bug-report-address + %store-directory + %state-directory + %system %libgcrypt %nixpkgs %nix-instantiate)) @@ -39,6 +42,15 @@ (define %guix-bug-report-address "@PACKAGE_BUGREPORT@") +(define %store-directory + "@storedir@") + +(define %state-directory + "@guix_localstatedir@") + +(define %system + "@guix_system@") + (define %libgcrypt "@LIBGCRYPT@") diff --git a/guix/store.scm b/guix/store.scm index 9aafb332dc..3bfb03e6b5 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -18,6 +18,7 @@ (define-module (guix store) #:use-module (guix utils) + #:use-module (guix config) #:use-module (rnrs bytevectors) #:use-module (rnrs io ports) #:use-module (srfi srfi-1) @@ -111,10 +112,9 @@ (sha1 2) (sha256 3)) -(define %nix-state-dir - (or (getenv "NIX_STATE_DIR") "/nix/var/nix")) (define %default-socket-path - (string-append %nix-state-dir "/daemon-socket/socket")) + (string-append (or (getenv "NIX_STATE_DIR") %state-directory) + "/daemon-socket/socket")) ;; serialize.cc @@ -439,7 +439,7 @@ file name. Return #t on success." (define %store-prefix ;; Absolute path to the Nix store. (make-parameter (or (and=> (getenv "NIX_STORE_DIR") canonicalize-path) - "/nix/store"))) + %store-directory))) (define (store-path? path) "Return #t if PATH is a store path." diff --git a/guix/utils.scm b/guix/utils.scm index 5ec8f3736d..4089b11cb1 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -342,7 +342,8 @@ returned by `config.guess'." (define %current-system ;; System type as expected by Nix, usually ARCHITECTURE-KERNEL. - (make-parameter (gnu-triplet->nix-system %host-type))) + ;; By default, this is equal to (gnu-triplet->nix-system %host-type). + (make-parameter %system)) (define (package-name->name+version name) "Given NAME, a package name like \"foo-0.9.1b\", return two values: diff --git a/m4/guix.m4 b/m4/guix.m4 index 9b5184ff55..7d7d7381a0 100644 --- a/m4/guix.m4 +++ b/m4/guix.m4 @@ -61,4 +61,5 @@ AC_DEFUN([GUIX_SYSTEM_TYPE], [ # `darwin10.2.0', etc. guix_system="$machine_name-`echo $host_os | "$SED" -e's/@<:@0-9.@:>@*$//g'`";; esac]) + AC_SUBST([guix_system]) ]) -- cgit v1.2.3 From 351782e2f1b1f82b91bbb2af0b9735c930645488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 00:04:00 +0100 Subject: build: Add missing daemon header to the distribution. * daemon.am (guix_daemon_headers): New variable. (noinst_HEADERS): Add it. --- daemon.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/daemon.am b/daemon.am index 8c2c22dd88..b2c0e649eb 100644 --- a/daemon.am +++ b/daemon.am @@ -133,9 +133,12 @@ guix_daemon_LDADD = \ libstore.a libutil.a libformat.a -lbz2 \ $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) +guix_daemon_headers = \ + nix/nix-daemon/shared.hh noinst_HEADERS = \ - $(libformat_headers) $(libutil_headers) $(libstore_headers) + $(libformat_headers) $(libutil_headers) $(libstore_headers) \ + $(guix_daemon_headers) nix/libstore/schema.sql.hh: nix/libstore/schema.sql $(GUILE) --no-auto-compile -c \ -- cgit v1.2.3 From aca54b395e8778e85cd8fcda2724b7a5f67169fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 00:04:43 +0100 Subject: build: Run `distcheck' with `--enable-daemon'. * Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Add `--enable-daemon'. --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index bb5dfbe0f9..49e0c3016a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -236,4 +236,5 @@ endif BUILD_DAEMON ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = \ --with-libgcrypt-prefix="$(LIBGCRYPT_PREFIX)" \ - --with-nix-prefix="$(NIX_PREFIX)" + --with-nix-prefix="$(NIX_PREFIX)" \ + --enable-daemon -- cgit v1.2.3 From 29833b26eba0b02fd25d84b9999be3048c3f60d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 00:05:11 +0100 Subject: build: Update skip count in `tests/derivations.scm'. * tests/derivations.scm: When %STORE if #f, skip 11 tests. --- tests/derivations.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/derivations.scm b/tests/derivations.scm index 14e1863a12..203bd9032f 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -76,7 +76,7 @@ (and (equal? b1 b2) (equal? d1 d2)))) -(test-skip (if %store 0 4)) +(test-skip (if %store 0 11)) (test-assert "add-to-store, flat" (let* ((file (search-path %load-path "language/tree-il/spec.scm")) -- cgit v1.2.3 From 5c403e351844e5aa07428431c3d15e70431a3807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 22:21:45 +0100 Subject: daemon: Add more options. * nix/nix-daemon/guix-daemon.cc (GUIX_OPT_BUILD_USERS_GROUP, GUIX_OPT_CACHE_FAILURES, GUIX_OPT_LOSE_LOGS, GUIX_OPT_DISABLE_STORE_OPTIMIZATION, GUIX_OPT_IMPERSONATE_LINUX_26): New macros. (options)["build-users-group", "cache-failures", "lose-logs", "disable-store-optimization", "impersonate-linux-2.6"]: New options. (parse_opt): Handle them. --- nix/nix-daemon/guix-daemon.cc | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc index 7a3b178eab..6bbea52196 100644 --- a/nix/nix-daemon/guix-daemon.cc +++ b/nix/nix-daemon/guix-daemon.cc @@ -50,7 +50,12 @@ builds derivations on behalf of its clients."; #define GUIX_OPT_SYSTEM 1 #define GUIX_OPT_DISABLE_CHROOT 2 -#define GUIX_OPT_DISABLE_LOG_COMPRESSION 3 +#define GUIX_OPT_BUILD_USERS_GROUP 3 +#define GUIX_OPT_CACHE_FAILURES 4 +#define GUIX_OPT_LOSE_LOGS 5 +#define GUIX_OPT_DISABLE_LOG_COMPRESSION 6 +#define GUIX_OPT_DISABLE_STORE_OPTIMIZATION 7 +#define GUIX_OPT_IMPERSONATE_LINUX_26 8 static const struct argp_option options[] = { @@ -67,8 +72,22 @@ static const struct argp_option options[] = "this option has no effect)" #endif }, + { "build-users-group", GUIX_OPT_BUILD_USERS_GROUP, "GROUP", 0, + "Perform builds as a user of GROUP" }, + { "cache-failures", GUIX_OPT_CACHE_FAILURES, 0, 0, + "Cache build failures" }, + { "lose-logs", GUIX_OPT_LOSE_LOGS, 0, 0, + "Do not keep build logs" }, { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0, "Disable compression of the build logs" }, + { "disable-store-optimization", GUIX_OPT_DISABLE_STORE_OPTIMIZATION, 0, 0, + "Disable automatic file \"deduplication\" in the store" }, + { "impersonate-linux-2.6", GUIX_OPT_IMPERSONATE_LINUX_26, 0, 0, + "Impersonate Linux 2.6" +#ifndef HAVE_SYS_PERSONALITY_H + " (this option has no effect in this configuration)" +#endif + }, { 0, 0, 0, 0, 0 } }; @@ -84,6 +103,21 @@ parse_opt (int key, char *arg, struct argp_state *state) case GUIX_OPT_DISABLE_LOG_COMPRESSION: settings.compressLog = false; break; + case GUIX_OPT_BUILD_USERS_GROUP: + settings.buildUsersGroup = arg; + break; + case GUIX_OPT_DISABLE_STORE_OPTIMIZATION: + settings.autoOptimiseStore = false; + break; + case GUIX_OPT_CACHE_FAILURES: + settings.cacheFailure = true; + break; + case GUIX_OPT_IMPERSONATE_LINUX_26: + settings.impersonateLinux26 = true; + break; + case GUIX_OPT_LOSE_LOGS: + settings.keepLog = false; + break; case 'C': settings.buildCores = atoi (arg); break; -- cgit v1.2.3 From e9f6d6dd451e0e1a4eea2cbcdf4bfc9d4133344d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 6 Dec 2012 22:54:10 +0100 Subject: doc: Add new dependencies in `README'. * README (Hacking): Rename to... (Requirements): ... this. Add the daemon's dependencies. --- README | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README b/README index 9fdcc0effe..d2bbfacd5a 100644 --- a/README +++ b/README @@ -16,14 +16,23 @@ Guix. Guix is based on the [[http://nixos.org/nix/][Nix]] package manager. -* Hacking +* Requirements GNU Guix currently depends on the following packages: - [[http://gnu.org/software/guile/][GNU Guile 2.0.x]] - - [[http://nixos.org/nix/][Nix]] - [[http://gnupg.org/][GNU libgcrypt]] +Unless `--disable-daemon' was passed, the following packages are needed: + + - [[http://sqlite.org/][SQLite 3]] + - [[http://www.bzip.org][libbz2]] + - [[http://gcc.gnu.org][GCC's g++]] + +When `--disable-daemon' was passed, you instead need the following: + + - [[http://nixos.org/nix/][Nix]] + Optionally, packages from Nixpkgs may be transparently reused from Guix. For this to work, you need to have a checkout of the Nixpkgs repository; the `--with-nixpkgs' option allows you to let `configure' know where the -- cgit v1.2.3 From 4ce823c4241ff941ca301c39db23ab91eeaa1ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sun, 9 Dec 2012 14:54:01 +0100 Subject: daemon: Update to Nix 1.2-1-ge087bfe. --- nix-upstream | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix-upstream b/nix-upstream index 8eed07cda4..e087bfef5f 160000 --- a/nix-upstream +++ b/nix-upstream @@ -1 +1 @@ -Subproject commit 8eed07cda4c193bfcdd6ac4345ac6fb54aee0269 +Subproject commit e087bfef5f36f309b1c8d01bfe297e4cf4decb34 -- cgit v1.2.3 From a9128eac414e56882a12571e4856873a19ff6ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 12 Dec 2012 15:32:35 +0100 Subject: daemon: Use `openssl' from $PATH. * daemon.am (-DOPENSSL_PATH): Default to "openssl". * TODO: Mention removal of OpenSSL dependency. --- TODO | 9 +++++++++ daemon.am | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 1579504ea5..5510ee8c76 100644 --- a/TODO +++ b/TODO @@ -14,6 +14,15 @@ and GC-related tasks. The daemon mainly uses ‘libstore’ from Nix. Integrating it in Guix itself will make Guix self-contained, thereby simplifying our users’ lives. +** Remove dependency on OpenSSL + +The ‘openssl’ command-line tool is used in libstore to sign store paths +to be exported, and to check such signatures. The signing keys are +usually in /etc/nix/signing-key.{pub,sec}. They are a PKCS#8-encoded +X.509 SubjectPublicKeyInfo. These can be decoded with the [[http://lists.gnu.org/archive/html/help-gnutls/2012-12/msg00012.html][C API of +GnuTLS]], but not yet with its Guile bindings. There’s also +‘gnutls_privkey_sign_data’ to sign, and related functions. + * infrastructure ** have a Hydra instance build Guix packages diff --git a/daemon.am b/daemon.am index b2c0e649eb..aa75c6ed29 100644 --- a/daemon.am +++ b/daemon.am @@ -114,7 +114,7 @@ libstore_a_CPPFLAGS = \ -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ -DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \ -DNIX_BIN_DIR=\"$(bindir)\" \ - -DOPENSSL_PATH="\"FIXME--no OpenSSL support\"" + -DOPENSSL_PATH="\"openssl\"" libstore_a_CFLAGS = \ $(SQLITE3_CFLAGS) $(LIBGCRYPT_CFLAGS) -- cgit v1.2.3 From fdb50f8d8aba87e48c00a9633ed3e43b13792c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 00:23:20 +0100 Subject: tests: base32: Work around `system*' bug. * tests/base32.scm (%nix-hash): When `getenv' returns the empty string, ignore it. (%have-nix-hash?): New variable. Update `test-skip' clause to use it. --- tests/base32.scm | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/base32.scm b/tests/base32.scm index b8b9ebb0dd..d1bbaa1764 100644 --- a/tests/base32.scm +++ b/tests/base32.scm @@ -23,15 +23,24 @@ #:use-module (srfi srfi-64) #:use-module (ice-9 rdelim) #:use-module (ice-9 popen) + #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (rnrs io ports)) ;; Test the (guix base32) module. (define %nix-hash - (or (getenv "NIX_HASH") + (or (and=> (getenv "NIX_HASH") + (match-lambda + ("" #f) + (val val))) "nix-hash")) +(define %have-nix-hash? + ;; Note: Use `system', not `system*', because of . + (false-if-exception + (zero? (system (string-append %nix-hash " --version"))))) + (test-begin "base32") (test-assert "bytevector->base32-string" @@ -67,10 +76,9 @@ ;; Examples from RFC 4648. (map string->utf8 '("" "f" "fo" "foo" "foob" "fooba" "foobar")))) -;; The following tests requires `nix-hash' in $PATH. -(test-skip (if (false-if-exception (system* %nix-hash "--version")) - 0 - 1)) +;; The following test requires `nix-hash' in $PATH. +(unless %have-nix-hash? + (test-skip 1)) (test-assert "sha256 & bytevector->nix-base32-string" (let ((file (search-path %load-path "tests/test.drv"))) -- cgit v1.2.3 From 8a9451c89e23d12c88d12557a0b612b851def528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 00:24:27 +0100 Subject: tests: Arrange to have the socket file name fit in `sun_path'. * test-env.in (NIX_STATE_DIR): Choose a slightly smaller directory name. --- test-env.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test-env.in b/test-env.in index 9eb03dd498..4e388053f9 100644 --- a/test-env.in +++ b/test-env.in @@ -31,9 +31,15 @@ then NIX_STORE_DIR="@GUIX_TEST_ROOT@/store" NIX_LOCALSTATE_DIR="@GUIX_TEST_ROOT@/var" NIX_LOG_DIR="@GUIX_TEST_ROOT@/var/log/nix" - NIX_STATE_DIR="@GUIX_TEST_ROOT@/var/nix-$$" # allow for parallel tests NIX_DB_DIR="@GUIX_TEST_ROOT@/db" NIX_ROOT_FINDER="@abs_top_builddir@/nix/scripts/list-runtime-roots" + + # Choose a PID-dependent name to allow for parallel builds. Note + # that the directory name must be chosen so that the socket's file + # name is less than 108-char long (the size of `sun_path' in glibc). + # Currently, in Nix builds, we're at ~106 chars... + NIX_STATE_DIR="@GUIX_TEST_ROOT@/var/$$" # allow for parallel tests + export NIX_SUBSTITUTERS NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \ NIX_ROOT_FINDER -- cgit v1.2.3 From 3a61f8017a11c2a482faef58861d7dc1d37a082e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 00:26:41 +0100 Subject: build: When `--enable-daemon', don't error out when Nix programs are missing. * config-daemon.ac: Move AC_ARG_ENABLE([daemon]...)... * configure.ac: ... here. When Nix programs are not found, error out only when $guix_build_daemon is no. --- config-daemon.ac | 5 ----- configure.ac | 7 ++++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config-daemon.ac b/config-daemon.ac index edd372fba9..f48741dfda 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -1,10 +1,5 @@ dnl -*- Autoconf -*- fragment for the C++ daemon. -AC_ARG_ENABLE([daemon], - [AS_HELP_STRING([--enable-daemon], [build the Nix daemon (C++)])], - [guix_build_daemon="$enableval"], - [guix_build_daemon="no"]) - AC_MSG_CHECKING([whether to build daemon]) AC_MSG_RESULT([$guix_build_daemon]) diff --git a/configure.ac b/configure.ac index fdc1931b3c..0ea216e9d5 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,11 @@ AC_ARG_WITH(store-dir, [storedir="/nix/store"]) AC_SUBST(storedir) +AC_ARG_ENABLE([daemon], + [AS_HELP_STRING([--enable-daemon], [build the Nix daemon (C++)])], + [guix_build_daemon="$enableval"], + [guix_build_daemon="no"]) + # Prepare a version of $localstatedir that does not contain references # to shell variables. guix_localstatedir="`eval echo $localstatedir | sed -e "s|NONE|/usr/local|g"`" @@ -56,7 +61,7 @@ AC_ARG_WITH([nix-prefix], AC_PATH_PROG([NIX_INSTANTIATE], [nix-instantiate]) AC_PATH_PROG([NIX_HASH], [nix-hash]) -if test "x$NIX_INSTANTIATE$NIX_HASH" = "x"; then +if test "x$guix_build_daemon$NIX_INSTANTIATE$NIX_HASH" = "xno"; then AC_MSG_ERROR([Nix programs not found; please install Nix or use `--with-nix-prefix'.]) fi -- cgit v1.2.3 From c9b70836d080150046633edc782fdaaff9fc6d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 00:27:27 +0100 Subject: build: Make `--enable-daemon' the default. * configure.ac: Have $guix_build_daemon default to "yes". --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0ea216e9d5..bebb9885c4 100644 --- a/configure.ac +++ b/configure.ac @@ -31,9 +31,9 @@ AC_ARG_WITH(store-dir, AC_SUBST(storedir) AC_ARG_ENABLE([daemon], - [AS_HELP_STRING([--enable-daemon], [build the Nix daemon (C++)])], + [AS_HELP_STRING([--disable-daemon], [build the Nix daemon (C++)])], [guix_build_daemon="$enableval"], - [guix_build_daemon="no"]) + [guix_build_daemon="yes"]) # Prepare a version of $localstatedir that does not contain references # to shell variables. -- cgit v1.2.3 From 5fb868033fd8620eb6339df33fac00df21027790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 00:28:51 +0100 Subject: release.nix: Build the daemon. * release.nix (tarball): Add `preAutoconf'. Augment `buildInputs' and `configureFlags' to allow daemon builds. (build): Likewise. --- release.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/release.nix b/release.nix index 1b913b497b..fecbfb69d7 100644 --- a/release.nix +++ b/release.nix @@ -48,11 +48,12 @@ let pkgs.releaseTools.sourceTarball { name = "guix-tarball"; src = ; - buildInputs = with pkgs; [ guile ]; + buildInputs = with pkgs; [ guile sqlite bzip2 git libgcrypt ]; buildNativeInputs = with pkgs; [ texinfo gettext cvs pkgconfig ]; + preAutoconf = ''git config submodule.gnulib.url "${}"''; configureFlags = - [ "--with-nix-prefix=${pkgs.nix}" - "--with-libgcrypt-prefix=${pkgs.libgcrypt}" + [ "--with-libgcrypt-prefix=${pkgs.libgcrypt}" + "--localstatedir=/nix/var/nix" ]; }; @@ -62,12 +63,12 @@ let let pkgs = import nixpkgs { inherit system; }; in pkgs.releaseTools.nixBuild { name = "guix"; - buildInputs = [ pkgs.guile ]; + buildInputs = with pkgs; [ guile sqlite bzip2 libgcrypt ]; buildNativeInputs = [ pkgs.pkgconfig ]; src = jobs.tarball; configureFlags = - [ "--with-nix-prefix=${pkgs.nix}" - "--with-libgcrypt-prefix=${pkgs.libgcrypt}" + [ "--with-libgcrypt-prefix=${pkgs.libgcrypt}" + "--localstatedir=/nix/var/nix" ]; preBuild = -- cgit v1.2.3 From ad1ebab379dbd68e006197e8609c67de4734dbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 22:06:45 +0100 Subject: tests: Skip network-dependent tests when the network is unreachable. * tests/builders.scm (network-reachable?): New variable. ("url-fetch", "gnu-build"): Skip unless NETWORK-REACHABLE?. * tests/derivations.scm (%coreutils): Check for network access. ("build-expression->derivation with one input"): Skip when %COREUTILS is #f. * tests/guix-package.sh: Skip installation of GNU Make when the network is unreachable. * tests/packages.scm ("GNU Make, bootstrap"): Likewise. * tests/union.scm ("union-build"): Likewise. --- tests/builders.scm | 5 +++++ tests/derivations.scm | 6 ++++-- tests/guix-package.sh | 46 +++++++++++++++++++++++++--------------------- tests/packages.scm | 2 ++ tests/union.scm | 6 +++++- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/tests/builders.scm b/tests/builders.scm index 12841d5690..6035032d5d 100644 --- a/tests/builders.scm +++ b/tests/builders.scm @@ -50,9 +50,13 @@ (list name (package-derivation %store package)))) (@@ (distro packages base) %boot0-inputs)))) +(define network-reachable? + (false-if-exception (getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV))) + (test-begin "builders") +(unless network-reachable? (test-skip 1)) (test-assert "url-fetch" (let* ((url '("http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz" "ftp://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz")) @@ -69,6 +73,7 @@ (and (build-system? gnu-build-system) (eq? gnu-build (build-system-builder gnu-build-system)))) +(unless network-reachable? (test-skip 1)) (test-assert "gnu-build" (let* ((url "http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz") (hash (nix-base32-string->bytevector diff --git a/tests/derivations.scm b/tests/derivations.scm index 203bd9032f..46bab4e19d 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -290,8 +290,9 @@ (define %coreutils (false-if-exception - (or (package-derivation %store %bootstrap-coreutils&co) - (nixpkgs-derivation "coreutils")))) + (and (getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV) + (or (package-derivation %store %bootstrap-coreutils&co) + (nixpkgs-derivation "coreutils"))))) (test-skip (if %coreutils 0 1)) @@ -385,6 +386,7 @@ (and (equal? '(hello) (call-with-input-file one read)) (equal? '(world) (call-with-input-file two read))))))) +(test-skip (if %coreutils 0 1)) (test-assert "build-expression->derivation with one input" (let* ((builder '(call-with-output-file %output (lambda (p) diff --git a/tests/guix-package.sh b/tests/guix-package.sh index 2bc8c573ec..598ea62aaa 100644 --- a/tests/guix-package.sh +++ b/tests/guix-package.sh @@ -31,31 +31,35 @@ test -L "$profile" && test -L "$profile-1-link" test -f "$profile/bin/guile" -guix-package -b -p "$profile" \ - -i `guix-build -e '(@@ (distro packages base) gnu-make-boot0)'` -test -L "$profile-2-link" -test -f "$profile/bin/make" && test -f "$profile/bin/guile" +# Check whether we have network access. +if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null +then + guix-package -b -p "$profile" \ + -i `guix-build -e '(@@ (distro packages base) gnu-make-boot0)'` + test -L "$profile-2-link" + test -f "$profile/bin/make" && test -f "$profile/bin/guile" -# Check whether `--list-installed' works. -# XXX: Change the tests when `--install' properly extracts the package -# name and version string. -installed="`guix-package -p "$profile" --list-installed | cut -f1 | xargs echo | sort`" -case "x$installed" in - "guile-bootstrap make-boot0") - true;; - "make-boot0 guile-bootstrap") - true;; - "*") - false;; -esac + # Check whether `--list-installed' works. + # XXX: Change the tests when `--install' properly extracts the package + # name and version string. + installed="`guix-package -p "$profile" --list-installed | cut -f1 | xargs echo | sort`" + case "x$installed" in + "guile-bootstrap make-boot0") + true;; + "make-boot0 guile-bootstrap") + true;; + "*") + false;; + esac -test "`guix-package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap" + test "`guix-package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap" -# Remove a package. -guix-package -b -p "$profile" -r "guile-bootstrap-2.0" -test -L "$profile-3-link" -test -f "$profile/bin/make" && ! test -f "$profile/bin/guile" + # Remove a package. + guix-package -b -p "$profile" -r "guile-bootstrap-2.0" + test -L "$profile-3-link" + test -f "$profile/bin/make" && ! test -f "$profile/bin/guile" +fi # Make sure the `:' syntax works. guix-package -b -i "libsigsegv:lib" -n diff --git a/tests/packages.scm b/tests/packages.scm index c89f6e7721..5b0cd79b0f 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -125,6 +125,8 @@ (let ((p (pk 'drv d (derivation-path->output-path d)))) (eq? 'hello (call-with-input-file p read)))))) +(unless (false-if-exception (getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)) + (test-skip 1)) (test-assert "GNU Make, bootstrap" ;; GNU Make is the first program built during bootstrap; we choose it ;; here so that the test doesn't last for too long. diff --git a/tests/union.scm b/tests/union.scm index 73b95c49b8..c839855ef4 100644 --- a/tests/union.scm +++ b/tests/union.scm @@ -64,7 +64,11 @@ (bin make) (share (doc (make README)))))) -(test-skip (if %store 0 1)) +(test-skip (if (and %store + (false-if-exception + (getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV))) + 0 + 1)) (test-assert "union-build" (let* ((inputs (map (match-lambda -- cgit v1.2.3 From 6a95fa501f1d399433c56e2ee9fc2c52f79119df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 22:08:13 +0100 Subject: release.nix: build: Allow builds within a chroot. * release.nix (build): Remove `__noChroot' and `preConfigure'. --- release.nix | 5 ----- 1 file changed, 5 deletions(-) diff --git a/release.nix b/release.nix index fecbfb69d7..4c54f75b0a 100644 --- a/release.nix +++ b/release.nix @@ -81,11 +81,6 @@ let distro/packages/bootstrap/x86_64-linux/guile-bootstrap-2.0.6.tar.xz ''; - # XXX: Since we need to talk to a running daemon, for the benefit of - # `nixpkgs-derivation*' & co., we need to escape the chroot. - preConfigure = "export NIX_REMOTE=daemon"; - __noChroot = true; - inherit succeedOnFailure keepBuildDirectory buildOutOfSourceTree; }; -- cgit v1.2.3 From b35c0f866c83288e64dcf5839d908705d416c317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 13 Dec 2012 22:08:33 +0100 Subject: release.nix: Add `build_disable_daemon'. * release.nix (build_disable_daemon): New job. --- release.nix | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/release.nix b/release.nix index 4c54f75b0a..2d3a70f524 100644 --- a/release.nix +++ b/release.nix @@ -86,6 +86,23 @@ let }; + build_disable_daemon = + { system ? builtins.currentSystem }: + + let + pkgs = import nixpkgs { inherit system; }; + build = jobs.build { inherit system; }; + in + pkgs.lib.overrideDerivation build ({ configureFlags, ... }: { + configureFlags = configureFlags ++ [ "--disable-daemon" ]; + buildInputs = with pkgs; [ guile nixUnstable pkgconfig ]; + + # Since we need to talk to a running daemon, we need to escape + # the chroot. + preConfigure = "export NIX_REMOTE=daemon"; + __noChroot = true; + }); + # Jobs to test the distro. distro = { hello = -- cgit v1.2.3