From 8dda896e4b2c4baa69b5e1b839bfaf47b9b36320 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 30 Nov 2022 11:11:29 +0100 Subject: [PATCH] guix: Linux reproducible builds of the daemon --- Cargo.toml | 3 -- contrib/guix/build.sh | 21 ++++++++++ contrib/guix/guix-build.sh | 78 ++++++++++++++++++++++++++++++++++++++ contrib/guix/manifest.scm | 5 +++ 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100755 contrib/guix/build.sh create mode 100755 contrib/guix/guix-build.sh create mode 100644 contrib/guix/manifest.scm diff --git a/Cargo.toml b/Cargo.toml index ddd3b20a..197ea29d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,3 @@ libc = "0.2" # Used for PSBTs base64 = "0.13" - -[patch.crates-io] - diff --git a/contrib/guix/build.sh b/contrib/guix/build.sh new file mode 100755 index 00000000..a3d8f396 --- /dev/null +++ b/contrib/guix/build.sh @@ -0,0 +1,21 @@ +set -ex + +# Guix comes with Cargo 1.52 but --config was stabilized in 1.63, so we need +# to specify unstable-options. +# We use the --config to redirect cargo toward our vendored source directory +# for our dependencies. +# TODO: build in release mode +cargo -Z unstable-options -vvv \ + --color always \ + --frozen \ + --offline \ + rustc \ + --release \ + --target-dir "$TARGET_DIR" \ + --config source.vendored_sources.directory=\""$VENDOR_DIR"\" \ + --config source.crates-io.replace-with=\"vendored_sources\" \ + --config source.\"https://github.com/darosior/rust-miniscript\".replace-with=\"vendored_sources\" \ + --config source.\"https://github.com/darosior/rust-miniscript\".git=\"https://github.com/darosior/rust-miniscript\" \ + --config source.\"https://github.com/darosior/rust-miniscript\".branch=\"multipath_descriptors_on_8.0\" + +set +ex diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh new file mode 100755 index 00000000..d7325245 --- /dev/null +++ b/contrib/guix/guix-build.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env sh + +set -ex + +# How many cores to allocate to Guix building. +JOBS="${JOBS:-$(nproc)}" + +# The binary to check the hash of downloaded archives. +SHASUM_BIN="${SHASUM_BIN:-sha256sum}" + +# We do everything in a single directory. That's the root of it, configurable +# through the environment. +BUILD_ROOT="${BUILD_ROOT:-$(mktemp -d)}" + +# Various folders we expose to the container. The vendor directory will contain +# the sources of all our dependencies. Because we restrict network access from +# within the container, this is pulled beforehand. +# The out directory will contain the resulting binaries. It's wired to the --target-dir +# for a cargo build. +VENDOR_DIR="$BUILD_ROOT/vendor" +OUT_DIR="${OUT_DIR:-"$BUILD_ROOT/out"}" +BIN_DIR="${BIN_DIR:-"$BUILD_ROOT/bin"}" + +# Create the various folders if the root build directory is fresh. +for d in "$OUT_DIR" "$BIN_DIR"; do + if ! [ -d "$d" ]; then + mkdir -p "$d" + fi +done + +# That's what Guix comes with. +RUST_VERSION="1.52.0" +CARGO_BIN="$BIN_DIR/cargo" + +# First off get the cargo binary to run on the host to vendor dependencies. +# We assume the host is a 64bit Linux system. +if ! [ -f "$CARGO_BIN" ]; then + ARCHIVE_PATH="$BIN_DIR/rust-for-cargo.tar.gz" + curl -o "$ARCHIVE_PATH" "https://static.rust-lang.org/dist/rust-$RUST_VERSION-x86_64-unknown-linux-gnu.tar.gz" + echo "c082b5eea81206ff207407b41a10348282362dd972e93c86b054952b66ca0e2b $ARCHIVE_PATH" | $SHASUM_BIN -c + # Path of the cargo binary within the archive + CARGO_BIN_PATH="rust-$RUST_VERSION-x86_64-unknown-linux-gnu/cargo/bin/cargo" + ( cd $BIN_DIR && tar -xzf $ARCHIVE_PATH $CARGO_BIN_PATH && mv $CARGO_BIN_PATH $CARGO_BIN ) +fi + +# Pull the sources of our dependencies before building them in the container. +if ! [ -d "$VENDOR_DIR" ]; then + $CARGO_BIN vendor $VENDOR_DIR +fi + +# Execute "$@" in a pinned, possibly older version of Guix, for reproducibility +# across time. +time_machine() { + guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \ + --commit=059d38dc3f8b087f4a42df586daeb05761ee18d7 \ + --cores="$JOBS" \ + --keep-failed \ + --fallback \ + -- "$@" +} + +# Bootstrap a reproducible environment as specified by the manifest in an isolated +# container, and build the project. +time_machine shell --no-cwd \ + --expose="$PWD/src=/liana/src" \ + --expose="$PWD/Cargo.toml=/liana/Cargo.toml" \ + --expose="$PWD/Cargo.lock=/liana/Cargo.lock" \ + --expose="$PWD/contrib/guix/build.sh=/liana/build.sh" \ + --expose="$VENDOR_DIR=$VENDOR_DIR" \ + --share="$OUT_DIR=$OUT_DIR" \ + --container \ + -m $PWD/contrib/guix/manifest.scm \ + -- env CC=clang VENDOR_DIR="$VENDOR_DIR" TARGET_DIR="$OUT_DIR" \ + /bin/sh -c "cd /liana && ./build.sh" + +set +ex + +echo "Build successful. Output available at $OUT_DIR" diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm new file mode 100644 index 00000000..564884a3 --- /dev/null +++ b/contrib/guix/manifest.scm @@ -0,0 +1,5 @@ +(specifications->manifest + (list "rust" + "rust-cargo" + "coreutils" + "clang-toolchain"))