diff --git a/Cargo.lock b/Cargo.lock index 0ad8530..1044c16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2776,7 +2776,7 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rooz" -version = "0.154.3" +version = "0.155.0" dependencies = [ "age", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index 236f49f..8310862 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rooz" -version = "0.154.3" +version = "0.155.0" edition = "2024" [dependencies] diff --git a/src/api/exec.rs b/src/api/exec.rs index 6d998ff..5af60c7 100644 --- a/src/api/exec.rs +++ b/src/api/exec.rs @@ -324,6 +324,13 @@ echo '[install] {}: {}' Ok(()) } + pub async fn default_uid(&self, container_id: &str) -> Result { + let output = self + .output("default-uid", container_id, None, Some(vec!["id", "-u"])) + .await?; + Ok(output.trim().parse::()?) + } + pub async fn ensure_user(&self, container_id: &str) -> Result<(), AnyError> { let ensure_user_cmd = inject( format!( diff --git a/src/api/workspace/enter.rs b/src/api/workspace/enter.rs index 83464b7..aeeced3 100644 --- a/src/api/workspace/enter.rs +++ b/src/api/workspace/enter.rs @@ -45,6 +45,7 @@ impl<'a> WorkspaceApi<'a> { shell: Option>, container_name: Option<&str>, root: bool, + chown: bool, ) -> Result { let container_name = container_name.unwrap_or(constants::DEFAULT_CONTAINER_NAME); let enter_labels = Labels::from(&[ @@ -101,25 +102,28 @@ impl<'a> WorkspaceApi<'a> { self.api.exec.ensure_user(container_id).await?; } - let real_mounts = if is_work_container { - &config.real_mounts - } else { - &config.sidecars[container_name].real_mounts - }; - - let chown_uid = if is_work_container { - &config.uid - } else { - &config.sidecars[container_name] - .uid - .unwrap_or_else(|| panic!("TODO: read default uid from the image")) - }; - - for (target, _) in real_mounts { - self.api - .exec - .chown(&container_id, chown_uid, target.as_str()) - .await?; + if chown { + let real_mounts = if is_work_container { + &config.real_mounts + } else { + &config.sidecars[container_name].real_mounts + }; + + let chown_uid = if is_work_container { + config.uid + } else { + match config.sidecars[container_name].uid { + Some(uid) => uid, + None => self.api.exec.default_uid(container_id).await?, + } + }; + + for (target, _) in real_mounts { + self.api + .exec + .chown(&container_id, &chown_uid, target.as_str()) + .await?; + } } } diff --git a/src/cli.rs b/src/cli.rs index 69c4e66..929d018 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -199,6 +199,11 @@ pub struct EnterParams { pub work_dir: Option, #[arg(short, long)] pub container: Option, + #[arg( + long, + help = "Chowns the container's volume mounts to the user the container runs as" + )] + pub chown: bool, } #[derive(Parser, Debug)] diff --git a/src/cmd/new.rs b/src/cmd/new.rs index df9b5d3..6393024 100644 --- a/src/cmd/new.rs +++ b/src/cmd/new.rs @@ -458,6 +458,7 @@ impl<'a> WorkspaceApi<'a> { Some(cfg.shell.iter().map(|v| v.as_str()).collect::>()), None, root, + false, ) .await?; diff --git a/src/main.rs b/src/main.rs index 5d57275..d51a327 100644 --- a/src/main.rs +++ b/src/main.rs @@ -166,6 +166,7 @@ async fn main() -> Result<(), AnyError> { root, work_dir, container, + chown, }), .. } => { @@ -176,6 +177,7 @@ async fn main() -> Result<(), AnyError> { shell.as_deref().map(|v| vec![v.as_ref()]), container.as_deref(), root, + chown, ) .await?; }