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:
commit
913e7b41bb
5 changed files with 62 additions and 47 deletions
31
README.md
31
README.md
|
@ -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/)
|
||||||
|
|
|
@ -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")
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
|
@ -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>'
|
||||||
'';
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue