Skip to content

Commit e8fa517

Browse files
committed
Execute mknod and symlink as root and chown
1 parent d66ed3e commit e8fa517

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

src/docker/container.rs

+34-10
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ use super::{IoStream, IoStreamSource};
1818

1919
#[derive(Clone)]
2020
pub struct Container {
21-
id: String,
2221
docker: bollard::Docker,
22+
id: String,
23+
user: String,
2324
remove_event: Shared<BoxFuture<'static, Option<EventMessage>>>,
2425
cgroup_device_filter: Arc<Mutex<Option<Box<dyn DeviceAccessController + Send>>>>,
2526
}
2627

2728
impl Container {
28-
pub(super) fn new(id: &str, docker: &bollard::Docker) -> Result<Self> {
29+
pub(super) fn new(docker: &bollard::Docker, id: String, user: String) -> Result<Self> {
2930
let mut remove_events = docker.events(Some(bollard::system::EventsOptions {
3031
filters: [
3132
("container".to_owned(), vec![id.to_owned()]),
@@ -43,9 +44,9 @@ impl Container {
4344
.shared();
4445

4546
let cgroup_device_filter: Box<dyn DeviceAccessController + Send> =
46-
match DeviceAccessControllerV2::new(id) {
47+
match DeviceAccessControllerV2::new(&id) {
4748
Ok(v) => Box::new(v),
48-
Err(err2) => match DeviceAccessControllerV1::new(id) {
49+
Err(err2) => match DeviceAccessControllerV1::new(&id) {
4950
Ok(v) => Box::new(v),
5051
Err(err1) => {
5152
log::error!("neither cgroup v1 and cgroup v2 works");
@@ -57,8 +58,14 @@ impl Container {
5758
};
5859

5960
Ok(Self {
60-
id: id.to_owned(),
6161
docker: docker.clone(),
62+
id,
63+
user: if user.is_empty() {
64+
// If user is not specified, use root.
65+
"root".to_owned()
66+
} else {
67+
user
68+
},
6269
remove_event: remove_evevnt,
6370
cgroup_device_filter: Arc::new(Mutex::new(Some(cgroup_device_filter))),
6471
})
@@ -114,7 +121,7 @@ impl Container {
114121
Ok(())
115122
}
116123

117-
pub async fn exec<T: ToString>(&self, cmd: &[T]) -> Result<IoStream> {
124+
pub async fn exec_as_root<T: ToString>(&self, cmd: &[T]) -> Result<IoStream> {
118125
let cmd = cmd.iter().map(|s| s.to_string()).collect();
119126
let options = bollard::exec::CreateExecOptions {
120127
cmd: Some(cmd),
@@ -123,6 +130,7 @@ impl Container {
123130
attach_stderr: Some(true),
124131
tty: Some(true),
125132
detach_keys: Some("ctrl-c".to_string()),
133+
user: Some("root".to_string()),
126134
..Default::default()
127135
};
128136
let response = self.docker.create_exec::<String>(&self.id, options).await?;
@@ -206,9 +214,20 @@ impl Container {
206214
}
207215
}
208216

217+
pub async fn chown_to_user(&self, path: &str) -> Result<()> {
218+
self.exec_as_root(&["chown", &format!("{}:", self.user), path])
219+
.await?
220+
.collect()
221+
.await?;
222+
Ok(())
223+
}
224+
209225
// Note: we use `&str` here instead of `Path` because docker API expects string instead `OsStr`.
210226
pub async fn mkdir(&self, path: &str) -> Result<()> {
211-
self.exec(&["mkdir", "-p", path]).await?.collect().await?;
227+
self.exec_as_root(&["mkdir", "-p", path])
228+
.await?
229+
.collect()
230+
.await?;
212231
Ok(())
213232
}
214233

@@ -222,24 +241,29 @@ impl Container {
222241
pub async fn mknod(&self, node: &str, (major, minor): (u32, u32)) -> Result<()> {
223242
self.rm(node).await?;
224243
self.mkdir_for(node).await?;
225-
self.exec(&["mknod", node, "c", &major.to_string(), &minor.to_string()])
244+
self.exec_as_root(&["mknod", node, "c", &major.to_string(), &minor.to_string()])
226245
.await?
227246
.collect()
228247
.await?;
248+
self.chown_to_user(node).await?;
229249
Ok(())
230250
}
231251

232252
pub async fn symlink(&self, source: &str, link: &str) -> Result<()> {
233253
self.mkdir_for(link).await?;
234-
self.exec(&["ln", "-sf", source, link])
254+
self.exec_as_root(&["ln", "-sf", source, link])
235255
.await?
236256
.collect()
237257
.await?;
258+
self.chown_to_user(link).await?;
238259
Ok(())
239260
}
240261

241262
pub async fn rm(&self, node: &str) -> Result<()> {
242-
self.exec(&["rm", "-f", node]).await?.collect().await?;
263+
self.exec_as_root(&["rm", "-f", node])
264+
.await?
265+
.collect()
266+
.await?;
243267
Ok(())
244268
}
245269

src/docker/docker.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ impl Docker {
1212
pub async fn get<T: AsRef<str>>(&self, name: T) -> Result<Container> {
1313
let response = self.0.inspect_container(name.as_ref(), None).await?;
1414
let id = response.id.context("Failed to obtain container ID")?;
15-
Container::new(&id, &self.0)
15+
let config = response
16+
.config
17+
.context("Failed to obtain container config")?;
18+
let user = config.user.context("Failed to obtain container user")?;
19+
Container::new(&self.0, id, user)
1620
}
1721

1822
pub async fn run<U: AsRef<str>, T: AsRef<[U]>>(&self, args: T) -> Result<Container> {

0 commit comments

Comments
 (0)