@@ -18,14 +18,15 @@ use super::{IoStream, IoStreamSource};
18
18
19
19
#[ derive( Clone ) ]
20
20
pub struct Container {
21
- id : String ,
22
21
docker : bollard:: Docker ,
22
+ id : String ,
23
+ user : String ,
23
24
remove_event : Shared < BoxFuture < ' static , Option < EventMessage > > > ,
24
25
cgroup_device_filter : Arc < Mutex < Option < Box < dyn DeviceAccessController + Send > > > > ,
25
26
}
26
27
27
28
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 > {
29
30
let mut remove_events = docker. events ( Some ( bollard:: system:: EventsOptions {
30
31
filters : [
31
32
( "container" . to_owned ( ) , vec ! [ id. to_owned( ) ] ) ,
@@ -43,9 +44,9 @@ impl Container {
43
44
. shared ( ) ;
44
45
45
46
let cgroup_device_filter: Box < dyn DeviceAccessController + Send > =
46
- match DeviceAccessControllerV2 :: new ( id) {
47
+ match DeviceAccessControllerV2 :: new ( & id) {
47
48
Ok ( v) => Box :: new ( v) ,
48
- Err ( err2) => match DeviceAccessControllerV1 :: new ( id) {
49
+ Err ( err2) => match DeviceAccessControllerV1 :: new ( & id) {
49
50
Ok ( v) => Box :: new ( v) ,
50
51
Err ( err1) => {
51
52
log:: error!( "neither cgroup v1 and cgroup v2 works" ) ;
@@ -57,8 +58,14 @@ impl Container {
57
58
} ;
58
59
59
60
Ok ( Self {
60
- id : id. to_owned ( ) ,
61
61
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
+ } ,
62
69
remove_event : remove_evevnt,
63
70
cgroup_device_filter : Arc :: new ( Mutex :: new ( Some ( cgroup_device_filter) ) ) ,
64
71
} )
@@ -114,7 +121,7 @@ impl Container {
114
121
Ok ( ( ) )
115
122
}
116
123
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 > {
118
125
let cmd = cmd. iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
119
126
let options = bollard:: exec:: CreateExecOptions {
120
127
cmd : Some ( cmd) ,
@@ -123,6 +130,7 @@ impl Container {
123
130
attach_stderr : Some ( true ) ,
124
131
tty : Some ( true ) ,
125
132
detach_keys : Some ( "ctrl-c" . to_string ( ) ) ,
133
+ user : Some ( "root" . to_string ( ) ) ,
126
134
..Default :: default ( )
127
135
} ;
128
136
let response = self . docker . create_exec :: < String > ( & self . id , options) . await ?;
@@ -206,9 +214,20 @@ impl Container {
206
214
}
207
215
}
208
216
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
+
209
225
// Note: we use `&str` here instead of `Path` because docker API expects string instead `OsStr`.
210
226
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 ?;
212
231
Ok ( ( ) )
213
232
}
214
233
@@ -222,24 +241,29 @@ impl Container {
222
241
pub async fn mknod ( & self , node : & str , ( major, minor) : ( u32 , u32 ) ) -> Result < ( ) > {
223
242
self . rm ( node) . await ?;
224
243
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 ( ) ] )
226
245
. await ?
227
246
. collect ( )
228
247
. await ?;
248
+ self . chown_to_user ( node) . await ?;
229
249
Ok ( ( ) )
230
250
}
231
251
232
252
pub async fn symlink ( & self , source : & str , link : & str ) -> Result < ( ) > {
233
253
self . mkdir_for ( link) . await ?;
234
- self . exec ( & [ "ln" , "-sf" , source, link] )
254
+ self . exec_as_root ( & [ "ln" , "-sf" , source, link] )
235
255
. await ?
236
256
. collect ( )
237
257
. await ?;
258
+ self . chown_to_user ( link) . await ?;
238
259
Ok ( ( ) )
239
260
}
240
261
241
262
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 ?;
243
267
Ok ( ( ) )
244
268
}
245
269
0 commit comments