Skip to content

Commit

Permalink
Add support for --include-path on all pilots
Browse files Browse the repository at this point in the history
Allow to provision files/directories. So far only tar
archives could be used to provision arbitrary data to
the instance
  • Loading branch information
schaefi committed Sep 14, 2023
1 parent b3ebc62 commit 78fd9fa
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 22 deletions.
3 changes: 3 additions & 0 deletions common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub enum FlakeError {
#[error("Instance in use by another instance, consider @NAME argument")]
AlreadyRunning,

#[error("Datasync failed, for details rerun with PILOT_DEBUG=1")]
SyncFailed,

/// OperationError pass through
#[error("{}", .0)]
OperationError(#[from] OperationError)
Expand Down
6 changes: 6 additions & 0 deletions doc/flake-ctl-firecracker-register.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SYNOPSIS
OPTIONS:
--app <APP>
--include-tar <INCLUDE_TAR>...
--include-path <INCLUDE_PATH>...
--no-net
--resume
--overlay-size <OVERLAY_SIZE>
Expand Down Expand Up @@ -55,6 +56,11 @@ OPTIONS
Name of a tar file to be included on top of the VM instance.
This option can be specified multiple times

--include-path <INCLUDE_PATH>...

Name of a file or directory to be included on top of the VM instance.
This option can be specified multiple times

--no-net

Disable networking
Expand Down
6 changes: 6 additions & 0 deletions doc/flake-ctl-podman-register.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SYNOPSIS
--base <BASE>
--container <CONTAINER>
--include-tar <INCLUDE_TAR>...
--include-path <INCLUDE_PATH>...
--info
--layer <LAYER>...
--opt <OPT>...
Expand Down Expand Up @@ -73,6 +74,11 @@ OPTIONS
Name of a tar file to be included on top of the container instance.
This option can be specified multiple times

--include-path <INCLUDE_PATH>...

Name of a file or directory to be included on top of the container
instance. This option can be specified multiple times

--info

Print registration information from container if provided
Expand Down
5 changes: 5 additions & 0 deletions firecracker-pilot/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,17 @@ impl<'a> Config<'a> {
pub fn tars(&self) -> Vec<&'a str> {
self.include.tar.as_ref().cloned().unwrap_or_default()
}

pub fn paths(&self) -> Vec<&'a str> {
self.include.path.as_ref().cloned().unwrap_or_default()
}
}

#[derive(Deserialize)]
pub struct IncludeSection<'a> {
#[serde(borrow)]
tar: Option<Vec<&'a str>>,
path: Option<Vec<&'a str>>,
}

#[derive(Deserialize)]
Expand Down
43 changes: 40 additions & 3 deletions firecracker-pilot/src/firecracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ pub fn create(program_name: &String) -> Result<(String, String), FlakeError> {

// check for includes
let tar_includes = config().tars();
let has_includes = !tar_includes.is_empty();
let path_includes = config().paths();
let has_includes = !tar_includes.is_empty() || !path_includes.is_empty();

// Make sure meta dirs exists
init_meta_dirs()?;
Expand Down Expand Up @@ -821,17 +822,18 @@ pub fn delete_file(filename: &String, user: User) -> bool {
true
}

// Todo: unifiy with podman
pub fn sync_includes(
target: &String, user: User
) -> Result<(), FlakeError> {
/*!
Sync custom include data to target path
!*/
let tar_includes = &config().tars();
let path_includes = &config().paths();

for tar in tar_includes {
if Lookup::is_debug() {
debug!("Adding tar include: [{}]", tar);
debug!("Provision tar archive: [{}]", tar);
}
let mut call = user.run("tar");
call.arg("-C").arg(target)
Expand All @@ -845,6 +847,41 @@ pub fn sync_includes(
debug!("{}", &String::from_utf8_lossy(&output.stderr));
}
}
for path in path_includes {
if Lookup::is_debug() {
debug!("Provision path: [{}]", path);
}
sync_data(
path, &format!("{}/{}", target, path),
["--mkpath"].to_vec(), user
)?;
}
Ok(())
}

pub fn sync_data(
source: &str, target: &str, options: Vec<&str>, user: User
) -> Result<(), FlakeError> {
/*!
Sync data from source path to target path
!*/
let mut call = user.run("rsync");
call.arg("-av");
for option in options {
call.arg(option);
}
call.arg(source).arg(target);
if Lookup::is_debug() {
debug!("{:?}", call.get_args());
}
let output = call.output()?;
if Lookup::is_debug() {
debug!("{}", &String::from_utf8_lossy(&output.stdout));
debug!("{}", &String::from_utf8_lossy(&output.stderr));
}
if !output.status.success() {
return Err(FlakeError::SyncFailed)
}
Ok(())
}

Expand Down
4 changes: 4 additions & 0 deletions flake-ctl/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub fn create_container_config(
base: Option<&String>,
layers: Option<Vec<String>>,
includes_tar: Option<Vec<String>>,
includes_path: Option<Vec<String>>,
resume: bool,
attach: bool,
run_as: Option<&String>,
Expand Down Expand Up @@ -129,6 +130,7 @@ pub fn create_container_config(
base,
layers,
includes_tar,
includes_path,
resume,
attach,
run_as,
Expand All @@ -155,6 +157,7 @@ pub fn create_vm_config(
no_net: bool,
resume: bool,
includes_tar: Option<Vec<String>>,
includes_path: Option<Vec<String>>,
) -> bool {
/*!
Create app configuration for the firecracker engine.
Expand Down Expand Up @@ -182,6 +185,7 @@ pub fn create_vm_config(
no_net,
resume,
includes_tar,
includes_path,
) {
Ok(_) => true,
Err(error) => {
Expand Down
13 changes: 13 additions & 0 deletions flake-ctl/src/app_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct AppContainerRuntime {
#[derive(Debug, Serialize, Deserialize)]
pub struct AppInclude {
pub tar: Option<Vec<String>>,
pub path: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -95,6 +96,7 @@ impl AppConfig {
base: Option<&String>,
layers: Option<Vec<String>>,
includes_tar: Option<Vec<String>>,
includes_path: Option<Vec<String>>,
resume: bool,
attach: bool,
run_as: Option<&String>,
Expand Down Expand Up @@ -142,6 +144,11 @@ impl AppConfig {
includes_tar.as_ref().unwrap().to_vec()
);
}
if includes_path.is_some() {
yaml_config.include.path = Some(
includes_path.as_ref().unwrap().to_vec()
);
}
if opts.is_some() {
let mut final_opts: Vec<String> = Vec::new();
for opt in opts.as_ref().unwrap() {
Expand Down Expand Up @@ -176,6 +183,7 @@ impl AppConfig {
no_net: bool,
resume: bool,
includes_tar: Option<Vec<String>>,
includes_path: Option<Vec<String>>,
) -> Result<(), GenericError> {
/*!
save stores an AppConfig to the given file
Expand Down Expand Up @@ -204,6 +212,11 @@ impl AppConfig {
includes_tar.as_ref().unwrap().to_vec()
);
}
if includes_path.is_some() {
yaml_config.include.path = Some(
includes_path.as_ref().unwrap().to_vec()
);
}
if let Some(overlay_size) = overlay_size {
vm_config.runtime.as_mut().unwrap()
.firecracker.as_mut().unwrap()
Expand Down
12 changes: 12 additions & 0 deletions flake-ctl/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ pub enum Firecracker {
/// specified multiple times.
#[clap(long, multiple = true, requires = "overlay-size")]
include_tar: Option<Vec<String>>,

/// Name of a file or directory to be included on top of
/// the VM instance. This option can be
/// specified multiple times.
#[clap(long, multiple = true, requires = "overlay-size")]
include_path: Option<Vec<String>>,
},
/// Remove application registration or entire VM
#[clap(group(
Expand Down Expand Up @@ -254,6 +260,12 @@ pub enum Podman {
#[clap(long, multiple = true)]
include_tar: Option<Vec<String>>,

/// Name of a file or directory to be included on top of
/// the VM instance. This option can be
/// specified multiple times.
#[clap(long, multiple = true)]
include_path: Option<Vec<String>>,

/// Resume the container from previous execution.
/// If the container is still running, the app will be
/// executed inside of this container instance.
Expand Down
9 changes: 6 additions & 3 deletions flake-ctl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
// register
cli::Firecracker::Register {
vm, app, target, run_as, overlay_size, no_net, resume,
include_tar
include_tar, include_path
} => {
if app::init(Some(app)) {
let mut ok = app::register(
Expand All @@ -96,7 +96,8 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
overlay_size.as_ref(),
*no_net,
*resume,
include_tar.as_ref().cloned()
include_tar.as_ref().cloned(),
include_path.as_ref().cloned(),
);
}
if ! ok {
Expand Down Expand Up @@ -140,7 +141,8 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
// register
cli::Podman::Register {
container, app, target, base,
layer, include_tar, resume, attach, run_as, opt, info
layer, include_tar, include_path, resume, attach,
run_as, opt, info
} => {
if *info {
podman::print_container_info(container);
Expand All @@ -157,6 +159,7 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
base.as_ref(),
layer.as_ref().cloned(),
include_tar.as_ref().cloned(),
include_path.as_ref().cloned(),
*resume,
*attach,
run_as.as_ref(),
Expand Down
1 change: 1 addition & 0 deletions flake-ctl/template/container-flake.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include:
tar: ~
path: ~
container:
name: name
target_app_path: path/to/program/in/container
Expand Down
1 change: 1 addition & 0 deletions flake-ctl/template/firecracker-flake.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include:
tar: ~
path: ~
vm:
name: name
target_app_path: path/to/program/in/container
Expand Down
7 changes: 6 additions & 1 deletion podman-pilot/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,17 @@ impl<'a> Config<'a> {
pub fn tars(&self) -> Vec<&'a str> {
self.include.tar.as_ref().cloned().unwrap_or_default()
}

pub fn paths(&self) -> Vec<&'a str> {
self.include.path.as_ref().cloned().unwrap_or_default()
}
}

#[derive(Deserialize)]
pub struct IncludeSection<'a> {
#[serde(borrow)]
tar: Option<Vec<&'a str>>
tar: Option<Vec<&'a str>>,
path: Option<Vec<&'a str>>,
}

#[derive(Deserialize)]
Expand Down
Loading

0 comments on commit 78fd9fa

Please sign in to comment.