From d79286c5adb8b6960ff32afee4fb8d116f0f043b Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 24 Jan 2021 15:30:06 +0200 Subject: moar --- Cargo.toml | 1 + src/cloudinit.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/image.rs | 1 + src/lib.rs | 1 + 4 files changed, 63 insertions(+), 1 deletion(-) 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; -- cgit v1.2.1