From c3c4aac670cf0ac26340061cef1527b3d7f64386 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 1 Feb 2016 03:00:48 +0100 Subject: make deploy2: deploy using nixos-rebuild switch --- krebs/3modules/build.nix | 109 +++++++++++++++++++++++++++++--------------- krebs/default.nix | 7 ++- krebs/populate.nix | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 39 deletions(-) create mode 100644 krebs/populate.nix (limited to 'krebs') diff --git a/krebs/3modules/build.nix b/krebs/3modules/build.nix index 7f004cd8..0f8aec89 100644 --- a/krebs/3modules/build.nix +++ b/krebs/3modules/build.nix @@ -28,48 +28,83 @@ let type = types.user; }; - options.krebs.build.source.dir = mkOption { - type = let - default-host = config.krebs.current.host; - in types.attrsOf (types.submodule ({ config, ... }: { - options = { - host = mkOption { - type = types.host; - default = default-host; - }; - path = mkOption { - type = types.str; - }; - target-path = mkOption { - type = types.str; - default = "/root/${config._module.args.name}"; - }; - url = mkOption { - type = types.str; - default = "file://${config.host.name}${config.path}"; - }; - }; - })); - default = {}; + options.krebs.build.source-version = mkOption { + type = types.enum [ 1 2 ]; + default = 1; }; - options.krebs.build.source.git = mkOption { - type = with types; attrsOf (submodule ({ config, ... }: { - options = { - url = mkOption { - type = types.str; # TODO must be shell safe - }; - rev = mkOption { - type = types.str; - }; - target-path = mkOption { - type = types.str; - default = "/root/${config._module.args.name}"; + options.krebs.build.source = getAttr "v${toString config.krebs.build.source-version}" { + v1 = { + dir = mkOption { + type = let + default-host = config.krebs.current.host; + in types.attrsOf (types.submodule ({ config, ... }: { + options = { + host = mkOption { + type = types.host; + default = default-host; + }; + path = mkOption { + type = types.str; + }; + target-path = mkOption { + type = types.str; + default = "/root/${config._module.args.name}"; + }; + url = mkOption { + type = types.str; + default = "file://${config.host.name}${config.path}"; + }; + }; + })); + default = {}; + }; + + git = mkOption { + type = with types; attrsOf (submodule ({ config, ... }: { + options = { + url = mkOption { + type = types.str; # TODO must be shell safe + }; + rev = mkOption { + type = types.str; + }; + target-path = mkOption { + type = types.str; + default = "/root/${config._module.args.name}"; + }; + }; + })); + default = {}; + }; + }; + + v2 = let + raw = types.either types.str types.path; + url = types.submodule { + options = { + url = mkOption { + type = types.str; + }; + rev = mkOption { + type = types.str; + }; + dev = mkOption { + type = types.str; + }; }; }; - })); - default = {}; + in mkOption { + type = types.attrsOf (types.either types.str url); + apply = let f = mapAttrs (_: value: { + string = value; + path = toString value; + set = f value; + }.${typeOf value}); in f; + default = {}; + }; }; + }; in out diff --git a/krebs/default.nix b/krebs/default.nix index 15d0e8e2..2cdecacc 100644 --- a/krebs/default.nix +++ b/krebs/default.nix @@ -171,9 +171,12 @@ let out = { ${b} ''; - get-config = system: - stockholm.users.${current-user-name}.${system}.config + get-config = system: let + config = stockholm.users.${current-user-name}.${system}.config or (abort "unknown system: ${system}, user: ${current-user-name}"); + in + assert config.krebs.build.source-version == 1; + config; nix-install = { system ? current-host-name diff --git a/krebs/populate.nix b/krebs/populate.nix new file mode 100644 index 00000000..9994fda8 --- /dev/null +++ b/krebs/populate.nix @@ -0,0 +1,115 @@ +{ source +, target-user ? "root" +, target-host +, target-path ? "/var/src" +}: +with import ; +with import ~/stockholm/krebs/4lib { + lib = import ; +}; +with builtins; +let + out = '' + #! /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 + ${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 -- cgit v1.2.3