Can perform basic file copy
This commit is contained in:
@ -123,3 +123,6 @@ pub const QEMU_IMAGE_PROGRAM: &str = "/usr/bin/qemu-img";
|
|||||||
|
|
||||||
/// IP program path
|
/// IP program path
|
||||||
pub const IP_PROGRAM: &str = "/usr/sbin/ip";
|
pub const IP_PROGRAM: &str = "/usr/sbin/ip";
|
||||||
|
|
||||||
|
/// Copy program path
|
||||||
|
pub const COPY_PROGRAM: &str = "/bin/cp";
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use crate::app_config::AppConfig;
|
||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::utils::file_size_utils::FileSize;
|
use crate::utils::file_size_utils::FileSize;
|
||||||
use std::os::linux::fs::MetadataExt;
|
use std::os::linux::fs::MetadataExt;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::time::UNIX_EPOCH;
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
@ -11,9 +12,11 @@ enum DisksError {
|
|||||||
Parse(&'static str),
|
Parse(&'static str),
|
||||||
#[error("DiskCreateError")]
|
#[error("DiskCreateError")]
|
||||||
Create,
|
Create,
|
||||||
|
#[error("DiskConvertError: {0}")]
|
||||||
|
Convert(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Copy, Clone)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize, Copy, Clone, PartialEq, Eq)]
|
||||||
#[serde(tag = "format")]
|
#[serde(tag = "format")]
|
||||||
pub enum DiskFileFormat {
|
pub enum DiskFileFormat {
|
||||||
Raw {
|
Raw {
|
||||||
@ -42,6 +45,7 @@ impl DiskFileFormat {
|
|||||||
/// Disk file information
|
/// Disk file information
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct DiskFileInfo {
|
pub struct DiskFileInfo {
|
||||||
|
pub file_path: PathBuf,
|
||||||
pub file_size: FileSize,
|
pub file_size: FileSize,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub format: DiskFileFormat,
|
pub format: DiskFileFormat,
|
||||||
@ -83,6 +87,7 @@ impl DiskFileInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
file_path: file.to_path_buf(),
|
||||||
name,
|
name,
|
||||||
file_size: FileSize::from_bytes(metadata.len() as usize),
|
file_size: FileSize::from_bytes(metadata.len() as usize),
|
||||||
format,
|
format,
|
||||||
@ -145,7 +150,62 @@ impl DiskFileInfo {
|
|||||||
|
|
||||||
/// Copy / convert file disk image into a new destination with optionally a new file format
|
/// Copy / convert file disk image into a new destination with optionally a new file format
|
||||||
pub fn convert(&self, dest_file: &Path, dest_format: DiskFileFormat) -> anyhow::Result<()> {
|
pub fn convert(&self, dest_file: &Path, dest_format: DiskFileFormat) -> anyhow::Result<()> {
|
||||||
todo!()
|
// Create a temporary directory to perform the operation
|
||||||
|
let temp_dir = tempfile::tempdir_in(&AppConfig::get().temp_dir)?;
|
||||||
|
let temp_file = temp_dir.path().join("temp_file");
|
||||||
|
|
||||||
|
// Prepare the conversion
|
||||||
|
let mut cmd = match (self.format, dest_format) {
|
||||||
|
// Dumb copy of file
|
||||||
|
(a, b) if a == b => {
|
||||||
|
let mut cmd = Command::new(constants::COPY_PROGRAM);
|
||||||
|
cmd.arg("--sparse=auto")
|
||||||
|
.arg(&self.file_path)
|
||||||
|
.arg(&temp_file);
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default, conversion is unsupported
|
||||||
|
(src, dest) => {
|
||||||
|
return Err(DisksError::Convert(format!(
|
||||||
|
"Conversion from {src:?} to {dest:?} is not supported!"
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Execute the conversion
|
||||||
|
let command_s = format!(
|
||||||
|
"{} {}",
|
||||||
|
cmd.get_program().display(),
|
||||||
|
cmd.get_args()
|
||||||
|
.map(|a| format!("'{}'", a.display()))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(" ")
|
||||||
|
);
|
||||||
|
let cmd_output = cmd.output()?;
|
||||||
|
if !cmd_output.status.success() {
|
||||||
|
return Err(DisksError::Convert(format!(
|
||||||
|
"Command failed:\n{command_s}\nStatus: {}\nstdout: {}\nstderr: {}",
|
||||||
|
cmd_output.status,
|
||||||
|
String::from_utf8_lossy(&cmd_output.stdout),
|
||||||
|
String::from_utf8_lossy(&cmd_output.stderr)
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the file was created
|
||||||
|
if !temp_file.is_file() {
|
||||||
|
return Err(DisksError::Convert(
|
||||||
|
"Temporary was not created after execution of command!".to_string(),
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the file to its final location
|
||||||
|
std::fs::rename(temp_file, dest_file)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user