use crate::utils::podman::{Podman, PodmanContainerState, PodmanError};
use {clap::Args, thiserror::Error};
use std::path::PathBuf;
#[derive(Debug, Error)]
pub enum SendError {
#[error(transparent)]
Podman(#[from] PodmanError),
#[error("source path '{path}' does not exist")]
SourceMissing { path: PathBuf },
#[error(
"container '{name}' is in state '{state}', not 'running'; run `podcell start {name}` first"
)]
NotRunning {
name: String,
state: PodmanContainerState,
},
}
const INBOX_PATH: &str = "/inbox";
#[derive(Args)]
pub struct Arguments {
#[arg()]
name: String,
#[arg()]
source: PathBuf,
}
fn create_inbox(podman: &Podman, container_id: &str) -> Result<(), PodmanError> {
podman.exec(
container_id,
&[
"sh",
"-c",
&format!("mkdir -p {INBOX_PATH} && chmod 0777 {INBOX_PATH}"),
],
)
}
fn chown_inbox(podman: &Podman, container_id: &str) -> Result<(), PodmanError> {
podman.exec(
container_id,
&[
"sh",
"-c",
&format!("chown -R \"$USER_ID:$GROUP_ID\" {INBOX_PATH}"),
],
)
}
pub fn run(args: Arguments) -> Result<(), SendError> {
if !args.source.exists() {
return Err(SendError::SourceMissing { path: args.source });
}
let podman = Podman::new();
let container = podman.find_by_name(&args.name)?;
if container.state != PodmanContainerState::Running {
return Err(SendError::NotRunning {
name: args.name,
state: container.state,
});
}
println!("Sending '{}' to /inbox...", args.source.display());
create_inbox(&podman, &container.id)?;
podman.cp(&container.id, &args.source, &format!("{INBOX_PATH}/"))?;
chown_inbox(&podman, &container.id)?;
Ok(())
}