Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libazureinit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "libazureinit"
version = "0.1.1"
edition = "2021"
rust-version = "1.76"
repository = "https://github.com/Azure/azure-init/"
homepage = "https://github.com/Azure/azure-init/"
license = "MIT"
Expand All @@ -20,6 +21,7 @@ serde_json = "1.0.96"
nix = {version = "0.28.0", features = ["fs", "user"]}
libc = "0.2.146"
block-utils = "0.11.1"
tracing = "0.1.40"

[dev-dependencies]
tempfile = "3"
Expand Down
20 changes: 20 additions & 0 deletions libazureinit/src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use std::process::Command;
use serde::Deserialize;
use serde_xml_rs::from_str;

use tracing;

use crate::error::Error;

#[derive(Debug, Default, Deserialize, PartialEq, Clone)]
Expand Down Expand Up @@ -187,6 +189,24 @@ pub fn parse_ovf_env(ovf_body: &str) -> Result<Environment, Error> {
}
}

// Mount the given device, get OVF environment data, return it.
pub fn mount_parse_ovf_env(dev: String) -> Result<Environment, Error> {
let mount_media =
Media::new(PathBuf::from(dev), PathBuf::from(PATH_MOUNT_POINT));
let mounted = mount_media.mount().inspect_err(
|e| tracing::error!(error = ?e, "Failed to mount media."),
)?;

let ovf_body = mounted.read_ovf_env_to_string()?;
let environment = parse_ovf_env(ovf_body.as_str())?;

mounted.unmount().inspect_err(
|e| tracing::error!(error = ?e, "Failed to remove media."),
)?;

Ok(environment)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
48 changes: 16 additions & 32 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use std::path::PathBuf;
use std::process::ExitCode;

use anyhow::Context;
Expand All @@ -11,33 +10,32 @@ use libazureinit::imds::InstanceMetadata;
use libazureinit::{
error::Error as LibError,
goalstate, imds, media,
media::{Environment, Media},
media::Environment,
reqwest::{header, Client},
user,
};

const VERSION: &str = env!("CARGO_PKG_VERSION");

// Mount the given device, get OVF environment data, return it.
fn mount_parse_ovf_env(dev: String) -> Result<Environment, anyhow::Error> {
let mount_media =
Media::new(PathBuf::from(dev), PathBuf::from(media::PATH_MOUNT_POINT));
let mounted = mount_media
.mount()
.with_context(|| "Failed to mount media.")?;
fn get_environment() -> Result<Environment, anyhow::Error> {
let ovf_devices = media::get_mount_device()?;
let mut environment: Option<Environment> = None;

let ovf_body = mounted.read_ovf_env_to_string()?;
let environment = media::parse_ovf_env(ovf_body.as_str())?;

mounted
.unmount()
.with_context(|| "Failed to remove media.")?;
// loop until it finds a correct device.
for dev in ovf_devices {
environment = match media::mount_parse_ovf_env(dev) {
Ok(env) => Some(env),
Err(_) => continue,
}
}

Ok(environment)
environment
.ok_or_else(|| anyhow::anyhow!("Unable to get list of block devices"))
}

fn get_username(
instance_metadata: &InstanceMetadata,
environment: &Environment,
) -> Result<String, anyhow::Error> {
if instance_metadata
.compute
Expand All @@ -49,22 +47,8 @@ fn get_username(
} else {
// password authentication is enabled

// list of CDROM devices that is available with possible filesystems.
let ovf_devices = media::get_mount_device()?;
let mut environment: Option<Environment> = None;

// loop until it finds a correct device.
for dev in ovf_devices {
environment = match mount_parse_ovf_env(dev) {
Ok(env) => Some(env),
Err(_) => continue,
}
}

Ok(environment
.ok_or_else(|| {
anyhow::anyhow!("Unable to get list of block devices")
})?
.clone()
.provisioning_section
.linux_prov_conf_set
.username)
Expand Down Expand Up @@ -103,7 +87,7 @@ async fn provision() -> Result<(), anyhow::Error> {
.build()?;

let instance_metadata = imds::query(&client).await?;
let username = get_username(&instance_metadata)?;
let username = get_username(&instance_metadata, &get_environment()?)?;

let mut file_path = "/home/".to_string();
file_path.push_str(username.as_str());
Expand Down