mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-05 06:01:32 +00:00
feat: oci tar format support
This commit is contained in:
@ -1,13 +1,13 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::{Parser, ValueEnum};
|
||||||
use krata::{
|
use krata::{
|
||||||
events::EventStream,
|
events::EventStream,
|
||||||
v1::{
|
v1::{
|
||||||
common::{
|
common::{
|
||||||
guest_image_spec::Image, GuestImageSpec, GuestOciImageFormat, GuestOciImageSpec,
|
guest_image_spec::Image, GuestImageSpec, GuestOciImageSpec, GuestSpec, GuestStatus,
|
||||||
GuestSpec, GuestStatus, GuestTaskSpec, GuestTaskSpecEnvVar,
|
GuestTaskSpec, GuestTaskSpecEnvVar, OciImageFormat,
|
||||||
},
|
},
|
||||||
control::{
|
control::{
|
||||||
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
||||||
@ -21,13 +21,17 @@ use tonic::{transport::Channel, Request};
|
|||||||
|
|
||||||
use crate::{console::StdioConsoleStream, pull::pull_interactive_progress};
|
use crate::{console::StdioConsoleStream, pull::pull_interactive_progress};
|
||||||
|
|
||||||
use super::pull::PullImageFormat;
|
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum LaunchImageFormat {
|
||||||
|
Squashfs,
|
||||||
|
Erofs,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(about = "Launch a new guest")]
|
#[command(about = "Launch a new guest")]
|
||||||
pub struct LauchCommand {
|
pub struct LauchCommand {
|
||||||
#[arg(short = 'S', long, default_value = "squashfs", help = "Image format")]
|
#[arg(short = 'S', long, default_value = "squashfs", help = "Image format")]
|
||||||
image_format: PullImageFormat,
|
image_format: LaunchImageFormat,
|
||||||
#[arg(short, long, help = "Name of the guest")]
|
#[arg(short, long, help = "Name of the guest")]
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
#[arg(
|
#[arg(
|
||||||
@ -78,8 +82,8 @@ impl LauchCommand {
|
|||||||
.pull_image(PullImageRequest {
|
.pull_image(PullImageRequest {
|
||||||
image: self.oci.clone(),
|
image: self.oci.clone(),
|
||||||
format: match self.image_format {
|
format: match self.image_format {
|
||||||
PullImageFormat::Squashfs => GuestOciImageFormat::Squashfs.into(),
|
LaunchImageFormat::Squashfs => OciImageFormat::Squashfs.into(),
|
||||||
PullImageFormat::Erofs => GuestOciImageFormat::Erofs.into(),
|
LaunchImageFormat::Erofs => OciImageFormat::Erofs.into(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use krata::v1::{
|
use krata::v1::{
|
||||||
common::GuestOciImageFormat,
|
common::OciImageFormat,
|
||||||
control::{control_service_client::ControlServiceClient, PullImageRequest},
|
control::{control_service_client::ControlServiceClient, PullImageRequest},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ use crate::pull::pull_interactive_progress;
|
|||||||
pub enum PullImageFormat {
|
pub enum PullImageFormat {
|
||||||
Squashfs,
|
Squashfs,
|
||||||
Erofs,
|
Erofs,
|
||||||
|
Tar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@ -30,8 +31,9 @@ impl PullCommand {
|
|||||||
.pull_image(PullImageRequest {
|
.pull_image(PullImageRequest {
|
||||||
image: self.image.clone(),
|
image: self.image.clone(),
|
||||||
format: match self.image_format {
|
format: match self.image_format {
|
||||||
PullImageFormat::Squashfs => GuestOciImageFormat::Squashfs.into(),
|
PullImageFormat::Squashfs => OciImageFormat::Squashfs.into(),
|
||||||
PullImageFormat::Erofs => GuestOciImageFormat::Erofs.into(),
|
PullImageFormat::Erofs => OciImageFormat::Erofs.into(),
|
||||||
|
PullImageFormat::Tar => OciImageFormat::Tar.into(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -6,7 +6,7 @@ use krata::{
|
|||||||
IdmMetricsRequest,
|
IdmMetricsRequest,
|
||||||
},
|
},
|
||||||
v1::{
|
v1::{
|
||||||
common::{Guest, GuestOciImageFormat, GuestState, GuestStatus},
|
common::{Guest, GuestState, GuestStatus, OciImageFormat},
|
||||||
control::{
|
control::{
|
||||||
control_service_server::ControlService, ConsoleDataReply, ConsoleDataRequest,
|
control_service_server::ControlService, ConsoleDataReply, ConsoleDataRequest,
|
||||||
CreateGuestReply, CreateGuestRequest, DestroyGuestReply, DestroyGuestRequest,
|
CreateGuestReply, CreateGuestRequest, DestroyGuestReply, DestroyGuestRequest,
|
||||||
@ -362,9 +362,10 @@ impl ControlService for DaemonControlService {
|
|||||||
message: err.to_string(),
|
message: err.to_string(),
|
||||||
})?;
|
})?;
|
||||||
let format = match request.format() {
|
let format = match request.format() {
|
||||||
GuestOciImageFormat::Unknown => OciPackedFormat::Squashfs,
|
OciImageFormat::Unknown => OciPackedFormat::Squashfs,
|
||||||
GuestOciImageFormat::Squashfs => OciPackedFormat::Squashfs,
|
OciImageFormat::Squashfs => OciPackedFormat::Squashfs,
|
||||||
GuestOciImageFormat::Erofs => OciPackedFormat::Erofs,
|
OciImageFormat::Erofs => OciPackedFormat::Erofs,
|
||||||
|
OciImageFormat::Tar => OciPackedFormat::Tar,
|
||||||
};
|
};
|
||||||
let (sender, mut receiver) = channel::<OciProgress>(100);
|
let (sender, mut receiver) = channel::<OciProgress>(100);
|
||||||
let context = OciProgressContext::new(sender);
|
let context = OciProgressContext::new(sender);
|
||||||
@ -388,7 +389,7 @@ impl ControlService for DaemonControlService {
|
|||||||
let reply = PullImageReply {
|
let reply = PullImageReply {
|
||||||
progress: Some(convert_oci_progress(progress)),
|
progress: Some(convert_oci_progress(progress)),
|
||||||
digest: String::new(),
|
digest: String::new(),
|
||||||
format: GuestOciImageFormat::Unknown.into(),
|
format: OciImageFormat::Unknown.into(),
|
||||||
};
|
};
|
||||||
yield reply;
|
yield reply;
|
||||||
}
|
}
|
||||||
@ -405,8 +406,9 @@ impl ControlService for DaemonControlService {
|
|||||||
progress: None,
|
progress: None,
|
||||||
digest: packed.digest,
|
digest: packed.digest,
|
||||||
format: match packed.format {
|
format: match packed.format {
|
||||||
OciPackedFormat::Squashfs => GuestOciImageFormat::Squashfs.into(),
|
OciPackedFormat::Squashfs => OciImageFormat::Squashfs.into(),
|
||||||
OciPackedFormat::Erofs => GuestOciImageFormat::Erofs.into(),
|
OciPackedFormat::Erofs => OciImageFormat::Erofs.into(),
|
||||||
|
_ => OciImageFormat::Unknown.into(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
yield reply;
|
yield reply;
|
||||||
|
@ -9,7 +9,7 @@ use krata::launchcfg::LaunchPackedFormat;
|
|||||||
use krata::v1::{
|
use krata::v1::{
|
||||||
common::{
|
common::{
|
||||||
guest_image_spec::Image, Guest, GuestErrorInfo, GuestExitInfo, GuestNetworkState,
|
guest_image_spec::Image, Guest, GuestErrorInfo, GuestExitInfo, GuestNetworkState,
|
||||||
GuestOciImageFormat, GuestState, GuestStatus,
|
GuestState, GuestStatus, OciImageFormat,
|
||||||
},
|
},
|
||||||
control::GuestChangedEvent,
|
control::GuestChangedEvent,
|
||||||
};
|
};
|
||||||
@ -244,9 +244,12 @@ impl GuestReconciler {
|
|||||||
.recall(
|
.recall(
|
||||||
&oci.digest,
|
&oci.digest,
|
||||||
match oci.format() {
|
match oci.format() {
|
||||||
GuestOciImageFormat::Unknown => OciPackedFormat::Squashfs,
|
OciImageFormat::Unknown => OciPackedFormat::Squashfs,
|
||||||
GuestOciImageFormat::Squashfs => OciPackedFormat::Squashfs,
|
OciImageFormat::Squashfs => OciPackedFormat::Squashfs,
|
||||||
GuestOciImageFormat::Erofs => OciPackedFormat::Erofs,
|
OciImageFormat::Erofs => OciPackedFormat::Erofs,
|
||||||
|
OciImageFormat::Tar => {
|
||||||
|
return Err(anyhow!("tar image format is not supported for guests"));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -29,15 +29,17 @@ message GuestImageSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum GuestOciImageFormat {
|
enum OciImageFormat {
|
||||||
GUEST_OCI_IMAGE_FORMAT_UNKNOWN = 0;
|
OCI_IMAGE_FORMAT_UNKNOWN = 0;
|
||||||
GUEST_OCI_IMAGE_FORMAT_SQUASHFS = 1;
|
OCI_IMAGE_FORMAT_SQUASHFS = 1;
|
||||||
GUEST_OCI_IMAGE_FORMAT_EROFS = 2;
|
OCI_IMAGE_FORMAT_EROFS = 2;
|
||||||
|
// Tar format is not launchable, and is intended for kernel images.
|
||||||
|
OCI_IMAGE_FORMAT_TAR = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GuestOciImageSpec {
|
message GuestOciImageSpec {
|
||||||
string digest = 1;
|
string digest = 1;
|
||||||
GuestOciImageFormat format = 2;
|
OciImageFormat format = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GuestTaskSpec {
|
message GuestTaskSpec {
|
||||||
|
@ -124,11 +124,11 @@ message PullImageProgress {
|
|||||||
|
|
||||||
message PullImageRequest {
|
message PullImageRequest {
|
||||||
string image = 1;
|
string image = 1;
|
||||||
krata.v1.common.GuestOciImageFormat format = 2;
|
krata.v1.common.OciImageFormat format = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PullImageReply {
|
message PullImageReply {
|
||||||
PullImageProgress progress = 1;
|
PullImageProgress progress = 1;
|
||||||
string digest = 2;
|
string digest = 2;
|
||||||
krata.v1.common.GuestOciImageFormat format = 3;
|
krata.v1.common.OciImageFormat format = 3;
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,13 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use tokio::{pin, process::Command, select};
|
use tokio::{fs::File, pin, process::Command, select};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum OciPackerBackendType {
|
pub enum OciPackerBackendType {
|
||||||
MkSquashfs,
|
MkSquashfs,
|
||||||
MkfsErofs,
|
MkfsErofs,
|
||||||
|
Tar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OciPackerBackendType {
|
impl OciPackerBackendType {
|
||||||
@ -20,6 +21,7 @@ impl OciPackerBackendType {
|
|||||||
match self {
|
match self {
|
||||||
OciPackerBackendType::MkSquashfs => OciPackedFormat::Squashfs,
|
OciPackerBackendType::MkSquashfs => OciPackedFormat::Squashfs,
|
||||||
OciPackerBackendType::MkfsErofs => OciPackedFormat::Erofs,
|
OciPackerBackendType::MkfsErofs => OciPackedFormat::Erofs,
|
||||||
|
OciPackerBackendType::Tar => OciPackedFormat::Tar,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +33,7 @@ impl OciPackerBackendType {
|
|||||||
OciPackerBackendType::MkfsErofs => {
|
OciPackerBackendType::MkfsErofs => {
|
||||||
Box::new(OciPackerMkfsErofs {}) as Box<dyn OciPackerBackend>
|
Box::new(OciPackerMkfsErofs {}) as Box<dyn OciPackerBackend>
|
||||||
}
|
}
|
||||||
|
OciPackerBackendType::Tar => Box::new(OciPackerTar {}) as Box<dyn OciPackerBackend>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,3 +202,30 @@ impl OciPackerBackend for OciPackerMkfsErofs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct OciPackerTar {}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl OciPackerBackend for OciPackerTar {
|
||||||
|
async fn pack(&self, progress: OciBoundProgress, vfs: Arc<VfsTree>, file: &Path) -> Result<()> {
|
||||||
|
progress
|
||||||
|
.update(|progress| {
|
||||||
|
progress.phase = OciProgressPhase::Packing;
|
||||||
|
progress.total = 1;
|
||||||
|
progress.value = 0;
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let file = File::create(file).await?;
|
||||||
|
vfs.write_to_tar(file).await?;
|
||||||
|
|
||||||
|
progress
|
||||||
|
.update(|progress| {
|
||||||
|
progress.phase = OciProgressPhase::Packing;
|
||||||
|
progress.total = 1;
|
||||||
|
progress.value = 1;
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@ pub enum OciPackedFormat {
|
|||||||
#[default]
|
#[default]
|
||||||
Squashfs,
|
Squashfs,
|
||||||
Erofs,
|
Erofs,
|
||||||
|
Tar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OciPackedFormat {
|
impl OciPackedFormat {
|
||||||
@ -21,6 +22,7 @@ impl OciPackedFormat {
|
|||||||
match self {
|
match self {
|
||||||
OciPackedFormat::Squashfs => "squashfs",
|
OciPackedFormat::Squashfs => "squashfs",
|
||||||
OciPackedFormat::Erofs => "erofs",
|
OciPackedFormat::Erofs => "erofs",
|
||||||
|
OciPackedFormat::Tar => "tar",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ impl OciPackedFormat {
|
|||||||
match self {
|
match self {
|
||||||
OciPackedFormat::Squashfs => OciPackerBackendType::MkSquashfs,
|
OciPackedFormat::Squashfs => OciPackerBackendType::MkSquashfs,
|
||||||
OciPackedFormat::Erofs => OciPackerBackendType::MkfsErofs,
|
OciPackedFormat::Erofs => OciPackerBackendType::MkfsErofs,
|
||||||
|
OciPackedFormat::Tar => OciPackerBackendType::Tar,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user