From a70d80b9cc5fb1b2487339bdef4152796ed2ff8d Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Thu, 25 Mar 2021 13:14:50 +0200 Subject: test: don't hide clippy output if it's successful Warnings don't seem to cause a failure. --- check | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check b/check index c488509..c81d919 100755 --- a/check +++ b/check @@ -21,7 +21,7 @@ got_cargo_cmd() } $hideok cargo build --all-targets -got_cargo_cmd clippy && $hideok cargo clippy +got_cargo_cmd clippy && cargo clippy -q got_cargo_cmd fmt && $hideok cargo fmt -- --check $hideok cargo test -- cgit v1.2.1 From 7d906d7f5436705ec3f2f3f5c4d8629c79f98fde Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Thu, 25 Mar 2021 12:50:07 +0200 Subject: refactor: clean up warnings found by clippy --- src/install.rs | 2 +- src/libvirt.rs | 15 ++++++--------- src/sshkeys.rs | 8 ++++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/install.rs b/src/install.rs index e74e6ba..94c703c 100644 --- a/src/install.rs +++ b/src/install.rs @@ -116,7 +116,7 @@ pub fn virt_install(args: &VirtInstallArgs, iso: &Path) -> Result Result { debug!("connecting to libvirtd {}", url); - let conn = Connect::open(url).map_err(|err| VirtError::Connect(err))?; + let conn = Connect::open(url).map_err(VirtError::Connect)?; Ok(Self { conn }) } fn get_domains(&self) -> Result, VirtError> { debug!("listing all domains"); - Ok(self - .conn - .list_all_domains(0) - .map_err(|err| VirtError::Domains(err))?) + Ok(self.conn.list_all_domains(0).map_err(VirtError::Domains)?) } fn get_domain(&self, name: &str) -> Result, VirtError> { @@ -119,7 +116,7 @@ impl Libvirt { let disk = find_iso_xml(&xml); let flags = VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_AFFECT_LIVE; - if disk.len() > 0 { + if disk.is_empty() { domain .detach_device_flags(&disk, flags) .map_err(|err| VirtError::DetachIso(name.to_string(), err))?; @@ -141,7 +138,7 @@ impl Libvirt { } pub fn start(&self, name: &str) -> Result<(), VirtError> { - if let Some(_) = self.get_domain(name)? { + if self.get_domain(name)?.is_some() { self.trigger_start(name)?; wait_for_ssh(name); } @@ -196,7 +193,7 @@ impl Libvirt { } fn get_name(domain: &Domain) -> Result { - let name = domain.get_name().map_err(|err| VirtError::GetName(err))?; + let name = domain.get_name().map_err(VirtError::GetName)?; Ok(name) } @@ -260,7 +257,7 @@ fn find_iso_xml(xml: &str) -> String { } let end = end.unwrap(); let disk = &xml[..end + 7]; - if let Some(_) = disk.find(".iso") { + if disk.contains(".iso") { return disk.to_string(); } xml = &xml[end..]; diff --git a/src/sshkeys.rs b/src/sshkeys.rs index 349cabe..b6a5dd9 100644 --- a/src/sshkeys.rs +++ b/src/sshkeys.rs @@ -110,7 +110,7 @@ impl KeyPair { /// Generate a new key pair of the desired kind. pub fn generate(kind: KeyKind) -> Result { - let dirname = tempdir().map_err(|err| KeyError::TempDir(err))?; + let dirname = tempdir().map_err(KeyError::TempDir)?; let private_key = dirname.path().join("key"); let output = Command::new("ssh-keygen") .arg("-f") @@ -122,7 +122,7 @@ impl KeyPair { .arg("-N") .arg("") .output() - .map_err(|err| KeyError::Run(err))?; + .map_err(KeyError::Run)?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr).into_owned(); @@ -178,7 +178,7 @@ impl CaKey { /// /// Return as a string. pub fn certify_host(&self, host_key: &KeyPair, hostname: &str) -> Result { - let dirname = tempdir().map_err(|err| KeyError::TempDir(err))?; + let dirname = tempdir().map_err(KeyError::TempDir)?; let ca_key = dirname.path().join("ca"); let host_key_pub = dirname.path().join("host.pub"); let cert = dirname.path().join("host-cert.pub"); @@ -196,7 +196,7 @@ impl CaKey { .arg(format!("host key for {}", hostname)) .arg(&host_key_pub) .output() - .map_err(|err| KeyError::Run(err))?; + .map_err(KeyError::Run)?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr).into_owned(); -- cgit v1.2.1 From 00dc4a7a85b32c4337dd3672adec2cbfe3597bfe Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Thu, 25 Mar 2021 12:29:44 +0200 Subject: feat: allow ~/ in config, specification files --- src/config.rs | 12 +++++++++++- src/libvirt.rs | 2 +- src/spec.rs | 10 ++++++---- src/util.rs | 34 ++++++++++++++++++++++++++++++++++ vmadm.md | 12 +++++++++--- 5 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/config.rs b/src/config.rs index 1866971..3f1b341 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ //! Tool configuration. +use crate::util::{expand_optional_pathbuf, expand_optional_pathbufs}; use log::debug; use serde::Deserialize; use std::default::Default; @@ -57,11 +58,20 @@ impl Configuration { debug!("reading configuration file {}", filename.display()); let config = fs::read(filename) .map_err(|err| ConfigurationError::ReadError(filename.to_path_buf(), err))?; - let config: Configuration = serde_yaml::from_slice(&config)?; + let mut config: Configuration = serde_yaml::from_slice(&config)?; + config.expand_tildes(); debug!("config: {:#?}", config); Ok(config) } else { Ok(Self::default()) } } + + fn expand_tildes(&mut self) { + expand_optional_pathbuf(&mut self.default_base_image); + expand_optional_pathbuf(&mut self.image_directory); + expand_optional_pathbuf(&mut self.image_directory); + expand_optional_pathbuf(&mut self.ca_key); + expand_optional_pathbufs(&mut self.authorized_keys) + } } diff --git a/src/libvirt.rs b/src/libvirt.rs index b144d11..4bf8590 100644 --- a/src/libvirt.rs +++ b/src/libvirt.rs @@ -116,7 +116,7 @@ impl Libvirt { let disk = find_iso_xml(&xml); let flags = VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_AFFECT_LIVE; - if disk.is_empty() { + if !disk.is_empty() { domain .detach_device_flags(&disk, flags) .map_err(|err| VirtError::DetachIso(name.to_string(), err))?; diff --git a/src/spec.rs b/src/spec.rs index a1d1c2f..a00a5e8 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -1,6 +1,7 @@ //! Virtual machine specification. use crate::config::Configuration; +use crate::util::expand_tilde; use log::debug; use serde::{Deserialize, Serialize}; @@ -293,8 +294,8 @@ impl Specification { ecdsa_host_cert: input.ecdsa_host_cert.clone(), ed25519_host_key: input.ed25519_host_key.clone(), ed25519_host_cert: input.ed25519_host_cert.clone(), - base: input.base_image(config, name)?, - image: input.image(config, name)?, + base: expand_tilde(&input.base_image(config, name)?), + image: expand_tilde(&input.image(config, name)?), image_size_gib: input.image_size_gib(config, name)?, memory_mib: input.memory_mib(config, name)?, cpus: input.cpus(config, name)?, @@ -311,8 +312,9 @@ impl Specification { fn ssh_keys(filenames: &[PathBuf]) -> Result, SpecificationError> { let mut keys = vec![]; for filename in filenames { - let key = std::fs::read(filename) - .map_err(|e| SpecificationError::SshKeyRead(filename.to_path_buf(), e))?; + let filename = expand_tilde(filename); + let key = + std::fs::read(&filename).map_err(|e| SpecificationError::SshKeyRead(filename, e))?; let key = String::from_utf8(key)?; let key = key.strip_suffix("\n").or(Some(&key)).unwrap(); keys.push(key.to_string()); diff --git a/src/util.rs b/src/util.rs index f3e104b..c641ea6 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,6 +2,7 @@ use log::debug; use std::net::TcpStream; +use std::path::{Path, PathBuf}; const SSH_PORT: i32 = 22; @@ -15,3 +16,36 @@ pub fn wait_for_ssh(name: &str) { } } } + +/// Expand a ~/ at the beginning of a Path to refer to the home directory. +pub fn expand_tilde(path: &Path) -> PathBuf { + if path.starts_with("~/") { + if let Some(home) = std::env::var_os("HOME") { + let mut expanded = PathBuf::from(home); + for comp in path.components().skip(1) { + expanded.push(comp); + } + expanded + } else { + path.to_path_buf() + } + } else { + path.to_path_buf() + } +} + +pub fn expand_optional_pathbuf(maybe_path: &mut Option) { + if let Some(path) = maybe_path { + *maybe_path = Some(expand_tilde(path)); + } +} + +pub fn expand_optional_pathbufs(maybe_paths: &mut Option>) { + if let Some(paths) = maybe_paths { + let mut expanded = vec![]; + for path in paths { + expanded.push(expand_tilde(&path)); + } + *maybe_paths = Some(expanded); + } +} diff --git a/vmadm.md b/vmadm.md index 24ffe5c..2d97876 100644 --- a/vmadm.md +++ b/vmadm.md @@ -36,9 +36,15 @@ V4cecTlFJGBtUOUAAAAMbGl3QGV4b2xvYmUxAQIDBAUGBw== -----END OPENSSH PRIVATE KEY----- ~~~ +Note that we use *tilde expansion* in filenames to indicate they go +into the home directory. The Subplot test runner sets the `HOME` +environment variable to a suitable directory, so that the files don't +go into the actual home directory of the person running the generated +test program + ~~~{#config.yaml .file .yaml} -image_directory: images -default_base_image: base.qcow2 +image_directory: ~/images +default_base_image: ~/base.qcow2 default_image_gib: 5 default_memory_mib: 2048 default_cpus: 1 @@ -46,7 +52,7 @@ default_generate_host_certificate: true default_autostart: true ca_key: ca_key authorized_keys: - - .ssh/id_rsa.pub + - ~/.ssh/id_rsa.pub ~~~ ~~~{#ssh_key_pub .file} -- cgit v1.2.1