Add deployment.privilegeEscalationCommand
This adds a NixOps-equivalent option for non-root deployment on remote hosts. Fixes #27.
This commit is contained in:
parent
2581f33dad
commit
960af8f793
3 changed files with 28 additions and 0 deletions
|
@ -155,6 +155,16 @@ let
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
privilegeEscalationCommand = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Command to use to elevate privileges when activating the new profiles on SSH hosts.
|
||||||
|
|
||||||
|
This is used on SSH hosts when `deployment.targetUser` is not `root`.
|
||||||
|
The user must be allowed to use the command non-interactively.
|
||||||
|
'';
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "sudo" "-H" "--" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,9 @@ pub struct Ssh {
|
||||||
/// Local path to a ssh_config file.
|
/// Local path to a ssh_config file.
|
||||||
ssh_config: Option<PathBuf>,
|
ssh_config: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Command to elevate privileges with.
|
||||||
|
privilege_escalation_command: Vec<String>,
|
||||||
|
|
||||||
friendly_name: String,
|
friendly_name: String,
|
||||||
progress_bar: TaskProgress,
|
progress_bar: TaskProgress,
|
||||||
logs: String,
|
logs: String,
|
||||||
|
@ -107,6 +110,7 @@ impl Ssh {
|
||||||
port: None,
|
port: None,
|
||||||
ssh_config: None,
|
ssh_config: None,
|
||||||
friendly_name,
|
friendly_name,
|
||||||
|
privilege_escalation_command: Vec::new(),
|
||||||
progress_bar: TaskProgress::default(),
|
progress_bar: TaskProgress::default(),
|
||||||
logs: String::new(),
|
logs: String::new(),
|
||||||
}
|
}
|
||||||
|
@ -120,6 +124,10 @@ impl Ssh {
|
||||||
self.ssh_config = Some(ssh_config);
|
self.ssh_config = Some(ssh_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_privilege_escalation_command(&mut self, command: Vec<String>) {
|
||||||
|
self.privilege_escalation_command = command;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn upcast(self) -> Box<dyn Host> {
|
pub fn upcast(self) -> Box<dyn Host> {
|
||||||
Box::new(self)
|
Box::new(self)
|
||||||
}
|
}
|
||||||
|
@ -128,6 +136,11 @@ impl Ssh {
|
||||||
pub fn ssh(&self, command: &[&str]) -> Command {
|
pub fn ssh(&self, command: &[&str]) -> Command {
|
||||||
let options = self.ssh_options();
|
let options = self.ssh_options();
|
||||||
let options_str = options.join(" ");
|
let options_str = options.join(" ");
|
||||||
|
let privilege_escalation_command = if self.user != "root" {
|
||||||
|
self.privilege_escalation_command.as_slice()
|
||||||
|
} else {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
|
|
||||||
let mut cmd = Command::new("ssh");
|
let mut cmd = Command::new("ssh");
|
||||||
|
|
||||||
|
@ -135,6 +148,7 @@ impl Ssh {
|
||||||
.arg(self.ssh_target())
|
.arg(self.ssh_target())
|
||||||
.args(&options)
|
.args(&options)
|
||||||
.arg("--")
|
.arg("--")
|
||||||
|
.args(privilege_escalation_command)
|
||||||
.args(command)
|
.args(command)
|
||||||
.env("NIX_SSHOPTS", options_str);
|
.env("NIX_SSHOPTS", options_str);
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,9 @@ pub struct NodeConfig {
|
||||||
#[serde(rename = "replaceUnknownProfiles")]
|
#[serde(rename = "replaceUnknownProfiles")]
|
||||||
replace_unknown_profiles: bool,
|
replace_unknown_profiles: bool,
|
||||||
|
|
||||||
|
#[serde(rename = "privilegeEscalationCommand")]
|
||||||
|
privilege_escalation_command: Vec<String>,
|
||||||
|
|
||||||
#[validate(custom = "validate_keys")]
|
#[validate(custom = "validate_keys")]
|
||||||
keys: HashMap<String, Key>,
|
keys: HashMap<String, Key>,
|
||||||
}
|
}
|
||||||
|
@ -132,6 +135,7 @@ impl NodeConfig {
|
||||||
pub fn to_ssh_host(&self) -> Option<Ssh> {
|
pub fn to_ssh_host(&self) -> Option<Ssh> {
|
||||||
self.target_host.as_ref().map(|target_host| {
|
self.target_host.as_ref().map(|target_host| {
|
||||||
let mut host = Ssh::new(self.target_user.clone(), target_host.clone());
|
let mut host = Ssh::new(self.target_user.clone(), target_host.clone());
|
||||||
|
host.set_privilege_escalation_command(self.privilege_escalation_command.clone());
|
||||||
|
|
||||||
if let Some(target_port) = self.target_port {
|
if let Some(target_port) = self.target_port {
|
||||||
host.set_port(target_port);
|
host.set_port(target_port);
|
||||||
|
|
Loading…
Reference in a new issue