Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cave"
version = "0.1.6"
version = "0.1.7"
authors = ["Simvia <basile.marchand@simvia.tech>"]
edition = "2021"
description = "CLI for managing code_aster versions"
Expand Down
2 changes: 2 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub enum Command {
#[arg(value_name = "ARGS")]
args: Vec<String>,
},
///Start an interactive shell in the container
Shell,
///List downloaded images
List {
///Optionnal Expression to match, ex : "cave list 16"
Expand Down
46 changes: 31 additions & 15 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,29 +209,35 @@ pub fn pull_version(version: &str) -> Result<(), CaveError> {
}


/// Runs code_aster with Docker with the given version, optional export file, and arguments.
/// Envoie ensuite les données d'exécution via gRPC si l'exécution n'est pas interactive.
pub enum DockerMode<'a> {
RunAster { export_file: &'a Option<String>, args: &'a Vec<String> },
Shell,
}

/// Runs code_aster with Docker with the given version and mode.
///
/// - [`DockerMode::RunAster`]: sources the activate script and runs `run_aster` with the given args and export file.
/// - [`DockerMode::Shell`]: drops the user into an interactive bash shell inside the container.
///
/// # Example
/// ```
/// docker_aster("22.0", &Some("output.msh".to_string()), &vec!["command".to_string()])
/// docker_aster("22.0", DockerMode::RunAster { export_file: &Some("output.msh".to_string()), args: &vec![] })
/// .expect("Failed to run Code_Aster in Docker");
/// docker_aster("22.0", DockerMode::Shell).expect("Failed to start shell");
/// ```
pub fn docker_aster(version: &str, export_file: &Option<String>, args: &Vec<String>) -> Result<(), CaveError> {
pub fn docker_aster(version: &str, mode: DockerMode) -> Result<(), CaveError> {
let start = std::time::Instant::now();

let current_dir = std::env::current_dir().map_err(CaveError::IoError)?;
let volume_arg = format!("{}:/home/user/data", current_dir.display());
let image = format!("simvia/code_aster:{}", version);
let export = export_file.clone().unwrap_or_default();
let docker_command = format!("source /opt/activate.sh && run_aster {} {}", args.join(" "), export);

// Get the current user's UID and GID to avoid permission issues
let (uid, gid) = get_uid_gid();
let user_arg = format!("{}:{}", uid, gid);

let mut child = Command::new("docker")
.arg("run")
let mut cmd = Command::new("docker");
cmd.arg("run")
.arg("--rm")
.arg("-it")
.arg("--user")
Expand All @@ -240,11 +246,22 @@ pub fn docker_aster(version: &str, export_file: &Option<String>, args: &Vec<Stri
.arg(&volume_arg)
.arg("-w")
.arg("/home/user/data")
.arg(&image)
.arg("/bin/bash")
.arg("-i")
.arg("-c")
.arg(&docker_command)
.arg(&image);

let is_shell = matches!(mode, DockerMode::Shell);

match mode {
DockerMode::RunAster { export_file, args } => {
let export = export_file.clone().unwrap_or_default();
let docker_command = format!("source /opt/activate.sh && run_aster {} {}", args.join(" "), export);
cmd.arg("/bin/bash").arg("-i").arg("-c").arg(docker_command);
}
DockerMode::Shell => {
cmd.arg("/bin/bash");
}
}

let mut child = cmd
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
Expand All @@ -258,9 +275,8 @@ pub fn docker_aster(version: &str, export_file: &Option<String>, args: &Vec<Stri
})?;

let status = child.wait().map_err(CaveError::IoError)?;
let interactive = args.contains(&"-i".to_string());

if !interactive {
if !is_shell {
debug!("Début de la telemetry");
debug!("Début de la collecte des données du run");

Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fn main() -> io::Result<()> {
Command::Use { version } => set_version(version, true),
Command::Pin { version } => set_version(version, false),
Command::Run { args } => run_aster(&args),
Command::Shell {} => shell_aster(),
Command::List { prefix } => print_local_versions(prefix.unwrap_or_default()),
Command::Available { prefix } => print_remote_versions(prefix.unwrap_or_default()),
Command::Config { action } => {
Expand Down
20 changes: 19 additions & 1 deletion src/manage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,28 @@ pub fn run_aster(args: &Vec<String>) -> Result<(), CaveError> {
_ => (None, args.to_vec()),
};

docker_aster(&version, &export, &rest_args)?;
docker_aster(&version, DockerMode::RunAster { export_file: &export, args: &rest_args })?;
Ok(())
}

/// Start interactive shell in the container
///
/// # Errors
/// - [`CaveError::VersionNotInstalled`] if the configured version is not installed locally.
/// - [`CaveError::FileNotFound`] if the `.export` file does not exist.
/// - Any error returned by [`docker_aster`].

pub fn shell_aster() -> Result<(), CaveError> {
let version = read_cave_version()?;
if !exists_locally(&version)? {
return Err(CaveError::VersionNotInstalled(version));
}

docker_aster(&version, DockerMode::Shell)?;
Ok(())
}


/// Prints a list of locally available versions filtered by an optionnal prefix.
///
/// # Example
Expand Down
Loading