Skip to content
Open
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
103 changes: 101 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
name = "omnect-cli"
readme = "README.md"
repository = "https://github.com/omnect/omnect-cli"
version = "0.27.1"
version = "0.27.2"

[dependencies]
actix-web = "4.11"
Expand Down Expand Up @@ -37,6 +37,8 @@ filemagic = { version = "0.13", default-features = false, features = [
"pkg-config",
] }
flate2 = { version = "1.1", default-features = false }
gptman = { version = "1.1", default-features = false }
mbrman = { version = "0.5", default-features = false }
omnect-crypto = { git = "https://github.com/omnect/omnect-crypto.git", tag = "0.4.0" }
keyring = { version = "3.6", default-features = false }
libfs = { version = "0.9", default-features = false }
Expand Down Expand Up @@ -85,5 +87,5 @@ tar = "0.4"

# metadata for building with cargo-deb (https://crates.io/crates/cargo-deb)
[package.metadata.deb]
depends = "bmap-tools, e2tools, fdisk, keychain, libc6 (>= 2.34), libmagic1, libssl3 (>= 3.0.0), mtools"
depends = "bmap-tools, e2tools, keychain, libc6 (>= 2.34), libmagic1, libssl3 (>= 3.0.0), mtools"
revision = ""
94 changes: 28 additions & 66 deletions src/file/functions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{Context, Result};
use log::{debug, warn};
use regex::Regex;
use std::collections::HashMap;
use std::fmt::{self, Display};
use std::fs;
Expand All @@ -22,9 +21,9 @@ pub enum Partition {

#[derive(Debug)]
struct PartitionInfo {
num: String,
start: String,
end: String,
num: u32,
start: u64,
count: u64,
}

impl Display for Partition {
Expand Down Expand Up @@ -184,23 +183,6 @@ macro_rules! try_exec_cmd {
};
}

macro_rules! exec_cmd_with_output {
($cmd:expr) => {{
let res = $cmd
.output()
.context(format!("{}: spawn {:?}", function_name!(), $cmd))?;

let output =
String::from_utf8(res.stdout).context(format!("{}: get output", function_name!()))?;

let output = output.trim();

debug!("{}: {:?}", function_name!(), $cmd);

output.to_string()
}};
}

pub fn copy_to_image(file_copy_params: &[FileCopyToParams], image_file: &Path) -> Result<()> {
// we use the folder the image is located in
// the caller is responsible to create a /tmp/ directory if needed
Expand Down Expand Up @@ -381,59 +363,39 @@ pub fn read_file_from_image(
}

fn get_partition_info(image_file: &str, partition: &Partition) -> Result<PartitionInfo> {
let mut fdisk = Command::new("fdisk");
fdisk
.arg("-l")
.arg("-o")
.arg("Device,Start,End")
.arg(image_file);
let fdisk_out = exec_cmd_with_output!(fdisk);
use crate::file::partition::{get_partition_data, is_gpt};

let partition_num = match partition {
let gpt =
is_gpt(image_file).context("get_partition_info: failed to detect partition table type")?;

let partition_num: u32 = match partition {
Partition::boot => 1,
Partition::rootA => 2,
p @ (Partition::factory | Partition::cert) => {
let re = Regex::new(r"Disklabel type: (\D{3})").unwrap();

let matches = re
.captures(&fdisk_out)
.context("get_partition_info: regex no matches found")?;
anyhow::ensure!(
matches.len() == 2,
"'get_partition_info: regex contains unexpected number of matches"
);

let partition_type = &matches[1];

debug!("partition type: {partition_type}");

match (p, partition_type) {
(Partition::factory, "gpt") => 4,
(Partition::factory, "dos") => 5,
(Partition::cert, "gpt") => 5,
(Partition::cert, "dos") => 6,
_ => anyhow::bail!("get_partition_info: unhandled partition type"),
Partition::factory => {
if gpt {
4
} else {
5
}
}
Partition::cert => {
if gpt {
5
} else {
6
}
}
};

let re = Regex::new(format!(r"{image_file}{partition_num}\s+(\d+)\s+(\d+)").as_str())
.context("get_partition_info: failed to create regex")?;

let matches = re
.captures(&fdisk_out)
.context("get_partition_info: regex no matches found")?;
anyhow::ensure!(
matches.len() == 3,
"'get_partition_info: regex contains unexpected number of matches"
);
debug!("get_partition_info: partition={partition}, num={partition_num}, gpt={gpt}");

let partition_offset = (matches[1].to_string(), matches[2].to_string());
let data = get_partition_data(image_file, partition_num)
.with_context(|| format!("get_partition_info: failed to read partition {partition_num}"))?;
Comment on lines +366 to +393

let info = PartitionInfo {
num: partition_num.to_string(),
start: partition_offset.0,
end: partition_offset.1,
num: data.num,
start: data.start,
count: data.count,
};

debug!("get_partition_info: {:?}", info);
Expand All @@ -455,7 +417,7 @@ fn read_partition(
.arg(format!("of={partition_file}"))
.arg("bs=512")
.arg(format!("skip={}", partition_info.start))
.arg(format!("count={}", partition_info.end))
.arg(format!("count={}", partition_info.count))
.arg("conv=sparse")
.arg("status=none");
exec_cmd!(dd);
Expand All @@ -476,7 +438,7 @@ fn write_partition(
.arg(format!("of={image_file}"))
.arg("bs=512")
.arg(format!("seek={}", partition_info.start))
.arg(format!("count={}", partition_info.end))
.arg(format!("count={}", partition_info.count))
.arg("conv=notrunc,sparse")
.arg("status=none");
exec_cmd!(dd);
Expand Down
1 change: 1 addition & 0 deletions src/file/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod compression;
pub mod functions;
mod partition;
use super::validators::{
device_update,
identity::{IdentityConfig, IdentityType, validate_identity},
Expand Down
Loading
Loading