summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2016-02-01 03:00:48 +0100
committertv <tv@krebsco.de>2016-02-01 03:32:30 +0100
commitc3c4aac670cf0ac26340061cef1527b3d7f64386 (patch)
tree6d504709b7f1fa2274d2867b4cdbad4966f0c622
parent1a4437cb26a29400d33486d6c8a220a9e88f4132 (diff)
make deploy2: deploy using nixos-rebuild switch
-rw-r--r--.rsync-filter2
-rw-r--r--Makefile19
-rw-r--r--krebs/3modules/build.nix109
-rw-r--r--krebs/default.nix7
-rw-r--r--krebs/populate.nix115
-rw-r--r--nixpkgs/default.nix1
-rw-r--r--nixpkgs/nixos/default.nix65
l---------nixpkgs/nixos/modules1
-rw-r--r--tv/1systems/cd.nix5
-rw-r--r--tv/2configs/default.nix36
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
diff --git a/Makefile b/Makefile
index 5b898c54c..3798240e1 100644
--- a/Makefile
+++ b/Makefile
@@ -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 = {