diff options
| author | tv <tv@krebsco.de> | 2016-02-01 03:00:48 +0100 | 
|---|---|---|
| committer | tv <tv@krebsco.de> | 2016-02-01 03:32:30 +0100 | 
| commit | c3c4aac670cf0ac26340061cef1527b3d7f64386 (patch) | |
| tree | 6d504709b7f1fa2274d2867b4cdbad4966f0c622 | |
| parent | 1a4437cb26a29400d33486d6c8a220a9e88f4132 (diff) | |
make deploy2: deploy using nixos-rebuild switch
| -rw-r--r-- | .rsync-filter | 2 | ||||
| -rw-r--r-- | Makefile | 19 | ||||
| -rw-r--r-- | krebs/3modules/build.nix | 109 | ||||
| -rw-r--r-- | krebs/default.nix | 7 | ||||
| -rw-r--r-- | krebs/populate.nix | 115 | ||||
| -rw-r--r-- | nixpkgs/default.nix | 1 | ||||
| -rw-r--r-- | nixpkgs/nixos/default.nix | 65 | ||||
| l--------- | nixpkgs/nixos/modules | 1 | ||||
| -rw-r--r-- | tv/1systems/cd.nix | 5 | ||||
| -rw-r--r-- | tv/2configs/default.nix | 36 | 
10 files changed, 302 insertions, 58 deletions
| diff --git a/.rsync-filter b/.rsync-filter new file mode 100644 index 000000000..d7657cd00 --- /dev/null +++ b/.rsync-filter @@ -0,0 +1,2 @@ +- /.git +- /.graveyard @@ -26,6 +26,25 @@ deploy infest:;@  	export filter=json  	make -s eval | sh +.PHONY: deploy2 +ifdef target +deploy2: export target-host = $(target) +else +deploy2: export target-host = $(system) +endif +deploy2:;@ +	target=$${target-$$system} +	result=$$(nix-instantiate \ +			--json \ +			--eval \ +			krebs/populate.nix \ +			--arg source 'with (import ~/stockholm {}).users.$(LOGNAME).$(system).config.krebs.build; assert source-version == 2; source' \ +			--argstr target-host "$$target" \ +			--argstr target-path /var/src) +	script=$$(echo "$$result" | jq -r .) +	echo "$$script" | sh +	ssh root@$$target nixos-rebuild switch -I /var/src +  .PHONY: eval  eval:  	@ diff --git a/krebs/3modules/build.nix b/krebs/3modules/build.nix index 7f004cd81..0f8aec89d 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 15d0e8e2e..2cdecaccb 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 000000000..9994fda82 --- /dev/null +++ b/krebs/populate.nix @@ -0,0 +1,115 @@ +{ 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 = '' +    #! /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 diff --git a/nixpkgs/default.nix b/nixpkgs/default.nix new file mode 100644 index 000000000..92da82c35 --- /dev/null +++ b/nixpkgs/default.nix @@ -0,0 +1 @@ +import <upstream-nixpkgs> diff --git a/nixpkgs/nixos/default.nix b/nixpkgs/nixos/default.nix new file mode 100644 index 000000000..6c5adf365 --- /dev/null +++ b/nixpkgs/nixos/default.nix @@ -0,0 +1,65 @@ +{ configuration ? import <upstream-nixpkgs/nixos/lib/from-env.nix> "NIXOS_CONFIG" <nixos-config> +, system ? builtins.currentSystem +}: + +let +  eval-config = modules: import <upstream-nixpkgs/nixos/lib/eval-config.nix> { +    inherit system; +    modules = modules ++ [({ config, lib, ... }: with lib; { +      imports = filter dir.has-default-nix (concatLists [ +        (map (p: p + "/2configs") [ <stockholm-private> ]) +        (map (p: p + "/3modules") [ <stockholm-krebs> <stockholm-private> ]) +      ]); + +      krebs.current = { +        enable = true; +        host = config.krebs.hosts.${readFile /proc/sys/kernel/hostname}; +        user = config.krebs.users.${getEnv "LOGNAME"}; +      }; + +      nixpkgs.config.packageOverrides = pkgs: let +        kpkgs = import <stockholm-krebs/5pkgs> { inherit lib pkgs; }; +        upkgs = import <stockholm-private/5pkgs> { inherit lib; pkgs = pkgs // kpkgs; }; +      in kpkgs // upkgs; +    })]; +    specialArgs = { +      lib = let +        nlib = import <upstream-nixpkgs/lib> // builtins; +        klib = nlib // import <stockholm-krebs/4lib> { lib = nlib; }; +        ulib = klib // (with klib; let p = <stockholm-private> + "/4lib"; in +          optionalAttrs (dir.has-default-nix p) +                        (import p { lib = klib; })); +      in ulib; +    }; +  }; + +  eval = eval-config [ +    configuration +  ]; + +  # This is for `nixos-rebuild build-vm'. +  vm = eval-config [ +    configuration +    <upstream-nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> +  ]; + +  # This is for `nixos-rebuild build-vm-with-bootloader'. +  vm-with-bootloader = eval-config [ +    configuration +    <upstream-nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> +    { virtualisation.useBootLoader = true; } +  ]; +in + +{ +  inherit (eval) config options; + +  system = eval.config.system.build.toplevel; + +  vm = vm.config.system.build.vm; + +  vmWithBootLoader = vm-with-bootloader.config.system.build.vm; + +  # The following are used by nixos-rebuild. +  nixFallback = eval.pkgs.nixUnstable; +} diff --git a/nixpkgs/nixos/modules b/nixpkgs/nixos/modules new file mode 120000 index 000000000..8fbc4373e --- /dev/null +++ b/nixpkgs/nixos/modules @@ -0,0 +1 @@ +../../upstream-nixpkgs/nixos/modules
\ No newline at end of file diff --git a/tv/1systems/cd.nix b/tv/1systems/cd.nix index 8c2a9ae43..b69d7655a 100644 --- a/tv/1systems/cd.nix +++ b/tv/1systems/cd.nix @@ -6,6 +6,11 @@ with lib;    krebs.build.host = config.krebs.hosts.cd;    krebs.build.target = "root@cd.internet"; +  krebs.build.source.upstream-nixpkgs = { +    url = https://github.com/NixOS/nixpkgs; +    rev = "b7ff030"; +  }; +    imports = [      ../2configs/hw/CAC-Developer-2.nix      ../2configs/fs/CAC-CentOS-7-64bit.nix diff --git a/tv/2configs/default.nix b/tv/2configs/default.nix index dc55a4330..e7197c4c4 100644 --- a/tv/2configs/default.nix +++ b/tv/2configs/default.nix @@ -8,20 +8,23 @@ with lib;    krebs.build = {      user = config.krebs.users.tv;      target = mkDefault "root@${config.krebs.build.host.name}"; -    source = { -      git.nixpkgs = { -        url = mkDefault https://github.com/NixOS/nixpkgs; -        rev = mkDefault "77f8f35d57618c1ba456d968524f2fb2c3448295"; -        target-path = mkDefault "/var/src/nixpkgs"; +    source-version = 2; +    source = mapAttrs (_: mkDefault) ({ +      nixos-config = "symlink:stockholm-private/1systems/${config.krebs.build.host.name}.nix"; +      nixpkgs = symlink:stockholm-nixpkgs; +      secrets = "/home/tv/secrets/${config.krebs.build.host.name}"; +      secrets-common = "/home/tv/secrets/common"; +      stockholm-krebs = "/home/tv/stockholm/krebs"; +      stockholm-nixpkgs = "/home/tv/stockholm/nixpkgs"; +      stockholm-private = "/home/tv/stockholm/tv"; +      upstream-nixpkgs = { +        url = https://github.com/NixOS/nixpkgs; +        rev = "77f8f35d57618c1ba456d968524f2fb2c3448295"; +        dev = "/home/tv/nixpkgs";        }; -      dir.secrets = { -        path = mkDefault "/home/tv/secrets/${config.krebs.build.host.name}"; -      }; -      dir.stockholm = { -        path = mkDefault "/home/tv/stockholm"; -        target-path = mkDefault "/var/src/stockholm"; -      }; -    }; +    } // optionalAttrs config.krebs.build.host.secure { +      secrets-master = "/home/tv/secrets/master"; +    });    };    networking.hostName = config.krebs.build.host.name; @@ -98,12 +101,7 @@ with lib;        };        environment.variables = { -        NIX_PATH = -          with config.krebs.build.source; with dir; with git; -          mkForce (concatStringsSep ":" [ -            "nixpkgs=${nixpkgs.target-path}" -            "secrets=${stockholm.target-path}/null" -          ]); +        NIX_PATH = mkForce "/var/src";        };        programs.bash = { | 
