1
0
Fork 0
mirror of https://cgit.krebsco.de/krops synced 2024-11-26 21:19:47 +01:00

Merge remote-tracking branch 'ni/master' into HEAD

This commit is contained in:
lassulus 2018-09-29 20:44:50 +02:00
commit 913e7b41bb
5 changed files with 62 additions and 47 deletions

View file

@ -1,20 +1,21 @@
# krops (krebs ops) # krops (krebs ops)
krops is a lightweigt toolkit to deploy nixos systems, remotely or locally. krops is a lightweigt toolkit to deploy NixOS systems, remotely or locally.
fancy features include: ## Some Features
- store your secrets in passwordstore
- store your secrets in [password store](https://www.passwordstore.org/)
- build your system remotely - build your system remotely
- minimal overhead - minimal overhead (it's basically just `nixos-rebuild switch`!)
- run from custom nixpkgs branch/checkout/fork - run from custom nixpkgs branch/checkout/fork
minimal example: ## Minimal Example
Create a file named `krops.nix` (name doesn't matter) with following content:
create a krops.nix somewhere
``` ```
let let
#krops = ./.; krops = (import <nixpkgs> {}).fetchgit {
krops = builtins.fetchGit {
url = https://cgit.krebsco.de/krops/; url = https://cgit.krebsco.de/krops/;
ref = "master"; ref = "master";
}; };
@ -24,12 +25,11 @@ let
source = lib.evalSource [{ source = lib.evalSource [{
nixpkgs.git = { nixpkgs.git = {
ref = "origin/nixos-18.03"; ref = "4b4bbce199d3b3a8001ee93495604289b01aaad3";
url = https://github.com/NixOS/nixpkgs-channels; url = https://github.com/NixOS/nixpkgs;
}; };
nixos-config.file = toString (pkgs.writeText "nixos-config" '' nixos-config.file = toString (pkgs.writeText "nixos-config" ''
{ pkgs, ... }: { { pkgs, ... }: {
fileSystems."/" = { device = "/dev/sda1"; }; fileSystems."/" = { device = "/dev/sda1"; };
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
services.openssh.enable = true; services.openssh.enable = true;
@ -47,4 +47,11 @@ in
} }
``` ```
and run `$(nix-build krops.nix)`. This results in a script which deploys the machine via ssh & rsync on the target machine. and run `$(nix-build --no-out-link krops.nix)` to deploy the target machine.
Under the hood, this will make the sources available on the target machine
below `/var/src`, and execute `nixos-rebuild switch -I /var/src`.
## References
- [In-depth example](http://tech.ingolf-wagner.de/nixos/krops/) by [Ingolf Wagner](https://ingolf-wagner.de/)

View file

@ -1,7 +1,15 @@
{ overlays ? [], ... }@args: { overlays ? [], ... }@args:
let
nix-writers = builtins.fetchGit {
url = https://cgit.krebsco.de/nix-writers/;
rev = "c27a9416e8ee04d708b11b48f8cf1a055c0cc079";
};
in
import <nixpkgs> (args // { import <nixpkgs> (args // {
overlays = overlays ++ [ overlays = overlays ++ [
(import ./overlay.nix) (import ./overlay.nix)
(import "${nix-writers}/pkgs")
]; ];
}) })

View file

@ -2,7 +2,19 @@ let
lib = import ../../lib; lib = import ../../lib;
in in
{ nix, openssh, populate, writeDash, writeJSON }: { { exec, nix, openssh, populate, writeDash }: rec {
rebuild = target:
exec "rebuild.${target.host}" rec {
filename = "${openssh}/bin/ssh";
argv = [
filename
"-l" target.user
"-p" target.port
target.host
"nixos-rebuild switch -I ${lib.escapeShellArg target.path}"
];
};
writeDeploy = name: { source, target }: let writeDeploy = name: { source, target }: let
target' = lib.mkTarget target; target' = lib.mkTarget target;
@ -10,9 +22,7 @@ in
writeDash name '' writeDash name ''
set -efu set -efu
${populate { inherit source; target = target'; }} ${populate { inherit source; target = target'; }}
${openssh}/bin/ssh \ ${rebuild target'}
${target'.user}@${target'.host} -p ${target'.port} \
nixos-rebuild switch -I ${target'.path}
''; '';
writeTest = name: { source, target }: let writeTest = name: { source, target }: let
@ -23,12 +33,11 @@ in
set -efu set -efu
${populate { inherit source; target = target'; }} ${populate { inherit source; target = target'; }}
${nix}/bin/nix-build \ ${nix}/bin/nix-build \
-A config.system.build.toplevel \ -A system \
-I ${target'.path} \ -I ${target'.path} \
--arg modules '[<nixos-config>]' \
--no-out-link \ --no-out-link \
--show-trace \ --show-trace \
'<nixpkgs/nixos/lib/eval-config.nix>' '<nixpkgs/nixos>'
''; '';
} }

View file

@ -5,14 +5,4 @@ in
self: super: { self: super: {
krops = self.callPackage ./krops {}; krops = self.callPackage ./krops {};
populate = self.callPackage ./populate {}; populate = self.callPackage ./populate {};
writeDash = name: text: self.writeScript name ''
#! ${self.dash}/bin/dash
${text}
'';
writeJSON = name: value: self.runCommand name {
json = lib.toJSON value;
passAsFile = [ "json" ];
} /* sh */ ''
${self.jq}/bin/jq . "$jsonPath" > "$out"
'';
} }

View file

@ -1,7 +1,7 @@
with import ../../lib; with import ../../lib;
with shell; with shell;
{ coreutils, dash, findutils, git, jq, openssh, rsync, writeDash }: { coreutils, dash, findutils, git, jq, openssh, pass, rsync, writeDash }:
let let
check = { force, target }: let check = { force, target }: let
@ -20,21 +20,21 @@ let
fi fi
''; '';
pop.file = target: file: rsync' target (quote file.path); pop.file = target: source: rsync' target (quote source.path);
pop.git = target: git: shell' target /* sh */ '' pop.git = target: source: shell' target /* sh */ ''
if ! test -e ${quote target.path}; then if ! test -e ${quote target.path}; then
git clone --recurse-submodules ${quote git.url} ${quote target.path} git clone --recurse-submodules ${quote source.url} ${quote target.path}
fi fi
cd ${quote target.path} cd ${quote target.path}
if ! url=$(git config remote.origin.url); then if ! url=$(git config remote.origin.url); then
git remote add origin ${quote git.url} git remote add origin ${quote source.url}
elif test "$url" != ${quote git.url}; then elif test "$url" != ${quote source.url}; then
git remote set-url origin ${quote git.url} git remote set-url origin ${quote source.url}
fi fi
# TODO resolve git_ref to commit hash # TODO resolve git_ref to commit hash
hash=${quote git.ref} hash=${quote source.ref}
if ! test "$(git log --format=%H -1)" = "$hash"; then if ! test "$(git log --format=%H -1)" = "$hash"; then
if ! git log -1 "$hash" >/dev/null 2>&1; then if ! git log -1 "$hash" >/dev/null 2>&1; then
@ -48,8 +48,8 @@ let
git clean -dfx git clean -dfx
''; '';
pop.pass = target: pass: let pop.pass = target: source: let
passPrefix = "${pass.dir}/${pass.name}"; passPrefix = "${source.dir}/${source.name}";
in /* sh */ '' in /* sh */ ''
umask 0077 umask 0077
@ -66,28 +66,28 @@ let
rel_name=''${rel_name%.gpg} rel_name=''${rel_name%.gpg}
pass_date=$( pass_date=$(
${git}/bin/git -C ${quote pass.dir} log -1 --format=%aI "$gpg_path" ${git}/bin/git -C ${quote source.dir} log -1 --format=%aI "$gpg_path"
) )
pass_name=${quote pass.name}/$rel_name pass_name=${quote source.name}/$rel_name
tmp_path=$tmp_dir/$rel_name tmp_path=$tmp_dir/$rel_name
${coreutils}/bin/mkdir -p "$(${coreutils}/bin/dirname "$tmp_path")" ${coreutils}/bin/mkdir -p "$(${coreutils}/bin/dirname "$tmp_path")"
PASSWORD_STORE_DIR=${quote pass.dir} pass show "$pass_name" > "$tmp_path" PASSWORD_STORE_DIR=${quote source.dir} ${pass}/bin/pass show "$pass_name" > "$tmp_path"
${coreutils}/bin/touch -d "$pass_date" "$tmp_path" ${coreutils}/bin/touch -d "$pass_date" "$tmp_path"
done done
${rsync' target /* sh */ "$tmp_dir"} ${rsync' target /* sh */ "$tmp_dir"}
''; '';
pop.pipe = target: pipe: /* sh */ '' pop.pipe = target: source: /* sh */ ''
${quote pipe.command} | { ${quote source.command} | {
${shell' target /* sh */ "cat > ${quote target.path}"} ${shell' target /* sh */ "cat > ${quote target.path}"}
} }
''; '';
# TODO rm -fR instead of ln -f? # TODO rm -fR instead of ln -f?
pop.symlink = target: symlink: shell' target /* sh */ '' pop.symlink = target: source: shell' target /* sh */ ''
ln -fns ${quote symlink.target} ${quote target.path} ln -fns ${quote source.target} ${quote target.path}
''; '';
populate = target: name: source: let populate = target: name: source: let
@ -112,7 +112,8 @@ let
optionalString (!isLocalTarget target) optionalString (!isLocalTarget target)
"${target.user}@${target.host}:" + "${target.user}@${target.host}:" +
target.path target.path
)} )} \
>&2
''; '';
shell' = target: script: shell' = target: script: