Add 'deployment.keys.<key>.keyCommand' support

Fixes #3.
This commit is contained in:
Zhaofeng Li 2021-02-10 18:08:47 -08:00
parent ce9f639a53
commit 52622ecd27
2 changed files with 36 additions and 8 deletions

View file

@ -103,7 +103,7 @@ let
text = lib.mkOption {
description = ''
Content of the key.
Either `keyFile` or `text` must be set.
One of `text`, `keyCommand` and `keyFile` must be set.
'';
default = null;
type = types.nullOr types.str;
@ -111,12 +111,22 @@ let
keyFile = lib.mkOption {
description = ''
Path of the local file to read the key from.
Either `keyFile` or `text` must be set.
One of `text`, `keyCommand` and `keyFile` must be set.
'';
default = null;
apply = value: if value == null then null else toString value;
type = types.nullOr types.path;
};
keyCommand = lib.mkOption {
description = ''
Command to run to generate the key.
One of `text`, `keyCommand` and `keyFile` must be set.
'';
default = null;
type = let
nonEmptyList = types.addCheck (types.listOf types.str) (l: length l > 0);
in types.nullOr nonEmptyList;
};
destDir = lib.mkOption {
description = ''
Destination directory on the host.
@ -190,11 +200,13 @@ let
else pkgs;
evalConfig = import (npkgs.path + "/nixos/lib/eval-config.nix");
assertionModule = { config, ... }: {
assertions = lib.mapAttrsToList (key: opts: {
assertion = (opts.text == null) != (opts.keyFile == null);
assertions = lib.mapAttrsToList (key: opts: let
nonNulls = l: filter (x: x != null) l;
in {
assertion = length (nonNulls [opts.text opts.keyCommand opts.keyFile]) == 1;
message =
let prefix = "${name}.deployment.keys.${key}";
in "Exactly one of `${prefix}.text` and `${prefix}.keyFile` must be set.";
in "Exactly one of `${prefix}.text`, `${prefix}.keyCommand` and `${prefix}.keyFile` must be set.";
}) config.deployment.keys;
};
in evalConfig {

View file

@ -1,11 +1,16 @@
use std::{
io::{self, Cursor},
path::{Path, PathBuf},
process::Stdio,
};
use regex::Regex;
use serde::{Deserialize, Serialize};
use tokio::{fs::File, io::AsyncRead};
use tokio::{
fs::File,
io::AsyncRead,
process::Command,
};
use validator::{Validate, ValidationError};
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -44,8 +49,19 @@ impl Key {
KeySource::Text(content) => {
Ok(Box::new(Cursor::new(content)))
}
KeySource::Command(_command) => {
todo!("Implement keyCommand support")
KeySource::Command(command) => {
let pathname = &command[0];
let argv = &command[1..];
let stdout = Command::new(pathname)
.args(argv)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()?
.stdout.take().unwrap();
Ok(Box::new(stdout))
}
KeySource::File(path) => {
Ok(Box::new(File::open(path).await?))