summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-01-24 15:30:06 +0200
committerLars Wirzenius <liw@liw.fi>2021-01-24 15:30:06 +0200
commitd79286c5adb8b6960ff32afee4fb8d116f0f043b (patch)
tree3105729257708e00d9b3e9f80f3267abdd78d5f0
parent32e73732e2f350818c077846596122f99bd6813b (diff)
downloadvmadm-d79286c5adb8b6960ff32afee4fb8d116f0f043b.tar.gz
moar
-rw-r--r--Cargo.toml1
-rw-r--r--src/cloudinit.rs61
-rw-r--r--src/image.rs1
-rw-r--r--src/lib.rs1
4 files changed, 63 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 77bb5c4..9e49642 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,3 +8,4 @@ edition = "2018"
[dependencies]
thiserror = "1"
+tempfile = "3.2" \ No newline at end of file
diff --git a/src/cloudinit.rs b/src/cloudinit.rs
index de256d8..6c52eff 100644
--- a/src/cloudinit.rs
+++ b/src/cloudinit.rs
@@ -1,6 +1,22 @@
use std::default::Default;
+use std::fs::write;
+use std::path::Path;
+use std::process::Command;
+use tempfile::tempdir;
-#[derive(Default, Debug)]
+#[derive(Debug, thiserror::Error)]
+pub enum CloudInitError {
+ #[error("failed to create ISO image with genisoimage: {0}")]
+ IsoFailed(String),
+
+ #[error(transparent)]
+ IoError(#[from] std::io::Error),
+
+ #[error(transparent)]
+ StringError(#[from] std::string::FromUtf8Error),
+}
+
+#[derive(Default, Debug, Clone)]
pub struct CloudInitConfig {
hostname: String,
authorized_keys: String,
@@ -22,6 +38,49 @@ impl CloudInitConfig {
pub fn set_authorized_keys(&mut self, keys: &str) {
self.authorized_keys = keys.to_string();
}
+
+ fn write(&self, dir: &Path) -> std::io::Result<()> {
+ let metadata = dir.join("meta-data");
+ let userdata = dir.join("user-data");
+
+ write(
+ &metadata,
+ format!(
+ "# Amazon EC2 style metadata\nlocal-hostname: {}\n",
+ self.hostname()
+ ),
+ )?;
+ write(
+ &userdata,
+ format!(
+ "#cloud-config\nssh_authorized_keys:\n- {}",
+ self.authorized_keys()
+ ),
+ )?;
+
+ Ok(())
+ }
+
+ pub fn create_iso(&self, filename: &Path) -> Result<(), CloudInitError> {
+ let dir = tempdir()?;
+ self.write(dir.path())?;
+
+ let r = Command::new("genisoimage")
+ .arg("-quiet")
+ .arg("-volid")
+ .arg("cidata")
+ .arg("-joliet")
+ .arg("-rock")
+ .arg("-output")
+ .arg(filename)
+ .arg(dir.path())
+ .output()?;
+ if !r.status.success() {
+ let stderr = String::from_utf8(r.stderr)?;
+ return Err(CloudInitError::IsoFailed(stderr));
+ }
+ Ok(())
+ }
}
#[cfg(test)]
diff --git a/src/image.rs b/src/image.rs
index e0b5a98..9d30ca0 100644
--- a/src/image.rs
+++ b/src/image.rs
@@ -15,6 +15,7 @@ pub enum ImageError {
StringError(#[from] std::string::FromUtf8Error),
}
+#[derive(Debug, Clone)]
pub struct VirtualMachineImage {
filename: PathBuf,
}
diff --git a/src/lib.rs b/src/lib.rs
index 16a21b3..5ea98ac 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,2 +1,3 @@
pub mod cloudinit;
pub mod image;
+pub mod install;