From 67e0540e443706624fff62605f6a632226e95fb4 Mon Sep 17 00:00:00 2001 From: sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> Date: Tue, 13 Apr 2021 23:30:21 +0200 Subject: pkgs/sternenseemann: add release tarball tooling The following nix functions allow easily creating derivations for building a signed releases directory for project(s) to be served via e. g. HTTP. * buildGitTarball: builds a reproducible .tar.gz for a given git revision or tag (similar to git archive, but we don't actually reuse it in favor of fetchgit). * bundleSignedReleases: symlinks tarballs generated using buildGitTarball and accompanying (manually provided) signatures into a directory and verifies the signatures to ensure buildGitTarball is donig what it's supposed to. --- pkgs/sternenseemann/build-git-tarball/default.nix | 41 ++++++++++++++++ .../bundle-signed-release/default.nix | 54 ++++++++++++++++++++++ pkgs/sternenseemann/default.nix | 9 ++++ 3 files changed, 104 insertions(+) create mode 100644 pkgs/sternenseemann/build-git-tarball/default.nix create mode 100644 pkgs/sternenseemann/bundle-signed-release/default.nix (limited to 'pkgs/sternenseemann') diff --git a/pkgs/sternenseemann/build-git-tarball/default.nix b/pkgs/sternenseemann/build-git-tarball/default.nix new file mode 100644 index 00000000..816ad9e2 --- /dev/null +++ b/pkgs/sternenseemann/build-git-tarball/default.nix @@ -0,0 +1,41 @@ +# Build a reproducible tar.gz from a git revision or tag +{ lib +, fetchgit +, runCommandNoCC +, gnutar +, gzip +, getBins +}: + +{ url +, sha256 +, pname +, subDir ? "" +, ... +}@args: + +assert lib.assertMsg (args ? rev || args ? tag) "Need either rev or tag"; + +let + bins = getBins gzip [ "gzip" ] + // getBins gnutar [ "tar" ] + ; + + shortRev = args.tag or args.rev; + realRev = + if args ? tag + then "refs/tags/${args.tag}" + else args.rev; + + source = fetchgit { + inherit url sha256; + rev = realRev; + }; + + basename = "${pname}-${shortRev}"; +in + +runCommandNoCC "${basename}.tar.gz" {} '' + cd ${source}${subDir} + ${bins.tar} -c ./ --transform 's/^\./${basename}/' | ${bins.gzip} > $out +'' diff --git a/pkgs/sternenseemann/bundle-signed-release/default.nix b/pkgs/sternenseemann/bundle-signed-release/default.nix new file mode 100644 index 00000000..5db979b0 --- /dev/null +++ b/pkgs/sternenseemann/bundle-signed-release/default.nix @@ -0,0 +1,54 @@ +# Build a directory containing release tarballs and +# their signatures. Fail if a signature is invalid. +{ lib +, getBins +, signify +, buildGitTarball +, runCommandNoCC +}: + +{ # public key to verify against + publicKey + # directory signature files are located in +, sigs +}: + +{ # project name: + # * tarballs are name ${pname}-${tag}.tar.gz + # * signatures are name ${pname}-${tag}.tar.gz.sig + pname + # information about the git remote to fetch from + # must contain an url attribute and may contain + # a subDir attribute. +, git + # List of releases which are represented as an + # attribute set which contains a sha256 and + # either a tag or rev attribute. +, releases +}: + +let + bins = getBins signify [ "signify" ]; + + tarballs = builtins.map + (args: buildGitTarball (git // args // { + inherit pname; + })) releases; + + sigFor = tarball: "${sigs}/${tarball.name}.sig"; +in + +runCommandNoCC "${pname}-releases" {} ('' + mkdir -p "$out" +'' + lib.concatMapStrings (tarball: '' + # verify tarball and inform user about what's happening + echo -n "${tarball.name}: " + ${bins.signify} -V \ + -p "${publicKey}" \ + -m "${tarball}" \ + -x "${sigFor tarball}" + + # succeeded, so copy tarball and signature + ln -s "${tarball}" "$out/${tarball.name}" + ln -s "${sigFor tarball}" "$out/${baseNameOf (sigFor tarball)}" +'') tarballs) diff --git a/pkgs/sternenseemann/default.nix b/pkgs/sternenseemann/default.nix index b133df65..1a348a08 100644 --- a/pkgs/sternenseemann/default.nix +++ b/pkgs/sternenseemann/default.nix @@ -47,6 +47,15 @@ lib.fix (self: { # nix utilities lib = callPackage ./lib { }; + buildGitTarball = callPackage ./build-git-tarball { + inherit getBins; + }; + + bundleSignedReleases = callPackage ./bundle-signed-release { + inherit getBins; + inherit (self) buildGitTarball; + }; + # packaged sterniware inherit (haskellPackages) emoji-generic; -- cgit 1.4.1