diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-01-24 15:30:06 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-01-24 15:30:06 +0200 |
commit | d79286c5adb8b6960ff32afee4fb8d116f0f043b (patch) | |
tree | 3105729257708e00d9b3e9f80f3267abdd78d5f0 | |
parent | 32e73732e2f350818c077846596122f99bd6813b (diff) | |
download | vmadm-d79286c5adb8b6960ff32afee4fb8d116f0f043b.tar.gz |
moar
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/cloudinit.rs | 61 | ||||
-rw-r--r-- | src/image.rs | 1 | ||||
-rw-r--r-- | src/lib.rs | 1 |
4 files changed, 63 insertions, 1 deletions
@@ -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, } @@ -1,2 +1,3 @@ pub mod cloudinit; pub mod image; +pub mod install; |