summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-01-29 13:45:29 +0200
committerLars Wirzenius <liw@liw.fi>2022-01-29 13:45:29 +0200
commitaa11e479718aaa79aceb76f4d9760f3e22c70fa8 (patch)
tree2e5d320b77198b5f034d7a86c48717b40f4319f6
parent0f81ce2cf72c33cd7d08f18a8e3a11dc843e3456 (diff)
downloadvmadm-aa11e479718aaa79aceb76f4d9760f3e22c70fa8.tar.gz
feat: allow start, stop, new, delete on multiple specs at once
Sponsored-by: author
-rw-r--r--src/bin/vmadm.rs40
-rw-r--r--vmadm.md61
2 files changed, 83 insertions, 18 deletions
diff --git a/src/bin/vmadm.rs b/src/bin/vmadm.rs
index 5e27761..ab01330 100644
--- a/src/bin/vmadm.rs
+++ b/src/bin/vmadm.rs
@@ -1,7 +1,7 @@
use anyhow::Context;
use directories_next::ProjectDirs;
use log::debug;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use structopt::StructOpt;
use vmadm::cmd;
use vmadm::config::Configuration;
@@ -25,7 +25,7 @@ enum Command {
common: CommonOptions,
#[structopt(parse(from_os_str))]
- spec: PathBuf,
+ specs: Vec<PathBuf>,
},
Config {
@@ -51,7 +51,7 @@ enum Command {
common: CommonOptions,
#[structopt(parse(from_os_str))]
- spec: PathBuf,
+ specs: Vec<PathBuf>,
},
Start {
@@ -59,7 +59,7 @@ enum Command {
common: CommonOptions,
#[structopt(parse(from_os_str))]
- spec: PathBuf,
+ specs: Vec<PathBuf>,
},
Shutdown {
@@ -67,7 +67,7 @@ enum Command {
common: CommonOptions,
#[structopt(parse(from_os_str))]
- spec: PathBuf,
+ specs: Vec<PathBuf>,
},
CloudInit {
@@ -100,9 +100,9 @@ fn main() -> anyhow::Result<()> {
debug!("{:#?}", cli);
match cli.cmd {
- Command::New { common, spec } => {
+ Command::New { common, specs } => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &specs)?;
cmd::new(&specs, &progress)?;
}
@@ -114,7 +114,7 @@ fn main() -> anyhow::Result<()> {
Command::Spec { common, spec } => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &[spec])?;
cmd::spec(&specs, &progress)?;
}
@@ -124,21 +124,21 @@ fn main() -> anyhow::Result<()> {
cmd::list(&config, &progress)?;
}
- Command::Delete { common, spec } => {
+ Command::Delete { common, specs } => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &specs)?;
cmd::delete(&specs, &progress)?;
}
- Command::Start { common, spec } => {
+ Command::Start { common, specs } => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &specs)?;
cmd::start(&specs, &progress)?;
}
- Command::Shutdown { common, spec } => {
+ Command::Shutdown { common, specs } => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &specs)?;
cmd::shutdown(&specs, &progress)?;
}
@@ -148,7 +148,7 @@ fn main() -> anyhow::Result<()> {
dirname,
} => {
let progress = get_progress(&common);
- let specs = get_specs(&common, &spec)?;
+ let specs = get_specs(&common, &[spec])?;
cmd::cloud_init(&specs, &progress, &dirname)?;
}
}
@@ -165,10 +165,14 @@ fn get_progress(common: &CommonOptions) -> Progress {
}
}
-fn get_specs(common: &CommonOptions, spec: &Path) -> anyhow::Result<Vec<Specification>> {
+fn get_specs(common: &CommonOptions, specs: &[PathBuf]) -> anyhow::Result<Vec<Specification>> {
let config = config(common)?;
- let specs = Specification::from_file(&config, spec)?;
- Ok(specs)
+ let mut all_specs = vec![];
+ for spec in specs {
+ let mut specs = Specification::from_file(&config, spec)?;
+ all_specs.append(&mut specs);
+ }
+ Ok(all_specs)
}
fn config(common: &CommonOptions) -> anyhow::Result<Configuration> {
diff --git a/vmadm.md b/vmadm.md
index 8bfd476..aec706f 100644
--- a/vmadm.md
+++ b/vmadm.md
@@ -22,6 +22,10 @@ This section has some data files used by scenarios.
smoke: {}
~~~
+~~~{#other.yaml .file .yaml}
+other: {}
+~~~
+
~~~{#ssh_key .file}
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
@@ -271,6 +275,63 @@ when I run vmadm delete --config config.yaml smoke.yaml
+
+# Manage several specs at once
+
+This scenario verifies that vmadm can manage virtual machines from
+several specifications at once.
+
+First some setup.
+
+~~~scenario
+given an installed vmadm
+given a Debian 10 OpenStack cloud image
+given file smoke.yaml
+given file other.yaml
+given file config.yaml
+given file ca_key
+given file .ssh/id_rsa from ssh_key
+given file .ssh/id_rsa.pub from ssh_key_pub
+given file .ssh/config from ssh_config
+given file .ssh/known_hosts from known_hosts
+when I run chmod -R u=rwX,go= .ssh
+~~~
+
+Then we create the VMs. We don't verify that each works, beyond that
+we can log in.
+
+~~~scenario
+when I run vmadm new --config config.yaml smoke.yaml other.yaml
+when I run ssh -F .ssh/config debian@smoke hostname
+then stdout contains "smoke"
+when I run ssh -F .ssh/config debian@other hostname
+then stdout contains "other"
+~~~
+
+Then we shut them all down.
+
+~~~scenario
+when I run vmadm shutdown --config config.yaml smoke.yaml other.yaml
+~~~
+
+Then we start them back up again and verify we can log in.
+
+~~~scenario
+when I run vmadm start --config config.yaml smoke.yaml other.yaml
+when I run ssh -F .ssh/config debian@smoke hostname
+when I run ssh -F .ssh/config debian@other hostname
+~~~
+
+Finally, we delete them.
+
+~~~scenario
+when I run vmadm delete --config config.yaml smoke.yaml other.yaml
+~~~
+
+
+
+
+
# Give useful error if image for new VM already exists
This scenario verifies that if the VM image file already exists, vmadm