diff options
author | tv <tv@krebsco.de> | 2016-02-02 01:53:38 +0100 |
---|---|---|
committer | tv <tv@krebsco.de> | 2016-02-02 01:57:32 +0100 |
commit | 2497533b90ce901a39d6642923738b2a337ad9aa (patch) | |
tree | 82618fd54256582b24fe77321bbdae119e1abcc1 /krebs/v2/default.nix | |
parent | 07fa0d989609faca2e9f9847165db61428206ef7 (diff) |
krebs/populate.nix -> krebs/v2 populate
Diffstat (limited to 'krebs/v2/default.nix')
-rw-r--r-- | krebs/v2/default.nix | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/krebs/v2/default.nix b/krebs/v2/default.nix new file mode 100644 index 000000000..7eb60103f --- /dev/null +++ b/krebs/v2/default.nix @@ -0,0 +1,120 @@ +{ source +, target-user ? "root" +, target-host +, target-path ? "/var/src" +}: +with import <nixpkgs/lib>; +with import ~/stockholm/krebs/4lib { + lib = import <nixpkgs/lib>; +}; +with builtins; +let + out = { + inherit populate; + }; + + populate = '' + #! /bin/sh + set -efu + + echo ${shell.escape git-script} \ + | ssh ${shell.escape "${target-user}@${target-host}"} -T + + tmpdir=$(mktemp -dt stockholm.XXXXXXXX) + trap ' + set +f + rm "$tmpdir"/* + rmdir "$tmpdir" + trap - EXIT INT QUIT + ' EXIT INT QUIT + chmod 0755 "$tmpdir" + ${concatStringsSep "\n" + (mapAttrsToList + (name: spec: let dst = removePrefix "symlink:" (get-url spec); in + "ln -s ${shell.escape dst} $tmpdir/${shell.escape name}") + symlink-specs)} + + proot \ + -b $tmpdir:${shell.escape target-path} \ + ${concatStringsSep " \\\n " + (mapAttrsToList + (name: spec: + "-b ${shell.escape "${get-url spec}:${target-path}/${name}"}") + file-specs)} \ + rsync \ + -f ${shell.escape "P /*"} \ + ${concatMapStringsSep " \\\n " + (name: "-f ${shell.escape "R /${name}"}") + (attrNames file-specs)} \ + --delete \ + -vFrlptD \ + ${shell.escape target-path}/ \ + ${shell.escape "${target-user}@${target-host}:${target-path}"} + ''; + + get-schema = uri: + if substring 0 1 uri == "/" + then "file" + else head (splitString ":" uri); + + has-schema = schema: uri: get-schema uri == schema; + + get-url = spec: { + string = spec; + path = toString spec; + set = get-url spec.url; + }.${typeOf spec}; + + git-specs = + filterAttrs (_: spec: has-schema "https" (get-url spec)) source // + filterAttrs (_: spec: has-schema "http" (get-url spec)) source // + filterAttrs (_: spec: has-schema "git" (get-url spec)) source; + + file-specs = + filterAttrs (_: spec: has-schema "file" (get-url spec)) source; + + symlink-specs = + filterAttrs (_: spec: has-schema "symlink" (get-url spec)) source; + + git-script = '' + fetch_git() {( + dst_dir=$1 + src_url=$2 + src_ref=$3 + + if ! test -e "$dst_dir"; then + git clone "$src_url" "$dst_dir" + fi + + cd "$dst_dir" + + if ! url=$(git config remote.origin.url); then + git remote add origin "$src_url" + elif test "$url" != "$src_url"; then + git remote set-url origin "$src_url" + fi + + # TODO resolve src_ref to commit hash + hash=$src_ref + + if ! test "$(git log --format=%H -1)" = "$hash"; then + git fetch origin + git checkout "$hash" -- "$dst_dir" + git checkout "$hash" + fi + + git clean -dxf + )} + + ${concatStringsSep "\n" + (mapAttrsToList + (name: spec: toString (map shell.escape [ + "fetch_git" + "${target-path}/${name}" + spec.url + spec.rev + ])) + git-specs)} + ''; + +in out |