summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-03-25 11:18:33 +0000
committerLars Wirzenius <liw@liw.fi>2021-03-25 11:18:33 +0000
commit228758b795b3c27d5fd146e380774b29db73432f (patch)
tree20df497a743e8442f9725c2f5ab552747363a9d1
parenta45450a42e4cdcd7f2d5671984c9c7f3945131fd (diff)
parent00dc4a7a85b32c4337dd3672adec2cbfe3597bfe (diff)
downloadvmadm-228758b795b3c27d5fd146e380774b29db73432f.tar.gz
Merge branch 'tilde' into 'main'
test: don't hide clippy output if it's successful See merge request larswirzenius/vmadm!30
-rwxr-xr-xcheck2
-rw-r--r--src/config.rs12
-rw-r--r--src/install.rs2
-rw-r--r--src/libvirt.rs15
-rw-r--r--src/spec.rs10
-rw-r--r--src/sshkeys.rs8
-rw-r--r--src/util.rs34
-rw-r--r--vmadm.md12
8 files changed, 72 insertions, 23 deletions
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
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/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<PathBuf, VirtI
.arg("--noautoconsole")
.arg("--quiet")
.output()
- .map_err(|err| VirtInstallError::Run(err))?;
+ .map_err(VirtInstallError::Run)?;
if !r.status.success() {
let stderr = String::from_utf8(r.stderr)?;
return Err(VirtInstallError::VirtInstallFailed(stderr));
diff --git a/src/libvirt.rs b/src/libvirt.rs
index e65ea1e..4bf8590 100644
--- a/src/libvirt.rs
+++ b/src/libvirt.rs
@@ -66,16 +66,13 @@ pub struct Libvirt {
impl Libvirt {
pub fn connect(url: &str) -> Result<Self, VirtError> {
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<Vec<Domain>, 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<Option<Domain>, 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<String, VirtError> {
- 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/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<Vec<String>, 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/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<Self, KeyError> {
- 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<String, KeyError> {
- 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();
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<PathBuf>) {
+ if let Some(path) = maybe_path {
+ *maybe_path = Some(expand_tilde(path));
+ }
+}
+
+pub fn expand_optional_pathbufs(maybe_paths: &mut Option<Vec<PathBuf>>) {
+ 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}