@@ -39,20 +39,12 @@ use std::{
3939    time:: Duration , 
4040} ; 
4141
42- use  crate :: { error:: Error ,  utils,  DefaultExecutor ,  Io ,  LogFormat ,  Runc ,  Spawner } ; 
42+ use  crate :: { error:: Error ,  utils,  DefaultExecutor ,  Io ,  LogFormat ,  Runc ,  RuncGlobalArgs ,   Spawner } ; 
4343
4444// constants for log format 
4545pub  const  JSON :  & str  = "json" ; 
4646pub  const  TEXT :  & str  = "text" ; 
4747
48- // constants for runc global flags 
49- const  DEBUG :  & str  = "--debug" ; 
50- const  LOG :  & str  = "--log" ; 
51- const  LOG_FORMAT :  & str  = "--log-format" ; 
52- const  ROOT :  & str  = "--root" ; 
53- const  ROOTLESS :  & str  = "--rootless" ; 
54- const  SYSTEMD_CGROUP :  & str  = "--systemd-cgroup" ; 
55- 
5648// constants for runc-create/runc-exec flags 
5749const  CONSOLE_SOCKET :  & str  = "--console-socket" ; 
5850const  DETACH :  & str  = "--detach" ; 
@@ -79,7 +71,7 @@ pub trait Args {
7971/// 
8072/// These options will be passed for all subsequent runc calls. 
8173/// See <https://github.com/opencontainers/runc/blob/main/man/runc.8.md#global-options> 
82- #[ derive( Debug ,  Default ) ]  
74+ #[ derive( Debug ,  Default ,   Clone ) ]  
8375pub  struct  GlobalOpts  { 
8476    /// Override the name of the runc binary. If [`None`], `runc` is used. 
8577     command :  Option < PathBuf > , 
@@ -203,64 +195,65 @@ impl GlobalOpts {
203195        self . args ( ) 
204196    } 
205197
206-     fn  output ( & self )  -> Result < ( PathBuf ,  Vec < String > ) ,  Error >  { 
198+     fn  output ( & self )  -> Result < ( PathBuf ,  RuncGlobalArgs ) ,  Error >  { 
207199        let  path = self 
208200            . command 
209201            . clone ( ) 
210202            . unwrap_or_else ( || PathBuf :: from ( "runc" ) ) ; 
211203
212204        let  command = utils:: binary_path ( path) . ok_or ( Error :: NotFound ) ?; 
213205
214-         let  mut  args = Vec :: new ( ) ; 
215- 
206+         let  mut  global_args = RuncGlobalArgs  { 
207+             debug :  None , 
208+             log :  None , 
209+             log_format :  None , 
210+             root :  None , 
211+             systemd_cgroup :  None , 
212+             rootless :  None , 
213+         } ; 
216214        // --root path : Set the root directory to store containers' state. 
217215        if  let  Some ( root)  = & self . root  { 
218-             args. push ( ROOT . into ( ) ) ; 
219-             args. push ( utils:: abs_string ( root) ?) ; 
216+             global_args. root  = Some ( root. to_path_buf ( ) ) ; 
220217        } 
221218
222219        // --debug : Enable debug logging. 
223220        if  self . debug  { 
224-             args . push ( DEBUG . into ( ) ) ; 
221+             global_args . debug  =  Some ( self . debug ) ; 
225222        } 
226223
227224        // --log path : Set the log destination to path. The default is to log to stderr. 
228225        if  let  Some ( log_path)  = & self . log  { 
229-             args. push ( LOG . into ( ) ) ; 
230-             args. push ( utils:: abs_string ( log_path) ?) ; 
226+             global_args. log  = Some ( log_path. to_path_buf ( ) ) ; 
231227        } 
232228
233229        // --log-format text|json : Set the log format (default is text). 
234-         args. push ( LOG_FORMAT . into ( ) ) ; 
235-         args. push ( self . log_format . to_string ( ) ) ; 
230+         global_args. log_format  = Some ( self . log_format . to_string ( ) ) ; 
236231
237-         // --systemd-cgroup : Enable systemd cgroup support. 
238232        if  self . systemd_cgroup  { 
239-             args . push ( SYSTEMD_CGROUP . into ( ) ) ; 
233+             global_args . systemd_cgroup  =  Some ( true ) ; 
240234        } 
241235
242236        // --rootless true|false|auto : Enable or disable rootless mode. 
243237        if  let  Some ( mode)  = self . rootless  { 
244-             let  arg = format ! ( "{}={}" ,  ROOTLESS ,  mode) ; 
245-             args. push ( arg) ; 
238+             global_args. rootless  = Some ( mode) ; 
246239        } 
247-         Ok ( ( command,  args ) ) 
240+         Ok ( ( command,  global_args ) ) 
248241    } 
249242} 
250243
251244impl  Args  for  GlobalOpts  { 
252245    type  Output  = Result < Runc ,  Error > ; 
253246
254247    fn  args ( & self )  -> Self :: Output  { 
255-         let  ( command,  args )  = self . output ( ) ?; 
248+         let  ( command,  global_args )  = self . output ( ) ?; 
256249        let  executor = if  let  Some ( exec)  = self . executor . clone ( )  { 
257250            exec
258251        }  else  { 
259252            Arc :: new ( DefaultExecutor  { } ) 
260253        } ; 
261254        Ok ( Runc  { 
262255            command, 
263-             args , 
256+             global_args , 
264257            spawner :  executor, 
265258        } ) 
266259    } 
@@ -352,6 +345,7 @@ impl CreateOpts {
352345/// Container execution options 
353346#[ derive( Clone ,  Default ) ]  
354347pub  struct  ExecOpts  { 
348+     pub  custom_args :  RuncGlobalArgs , 
355349    pub  io :  Option < Arc < dyn  Io > > , 
356350    /// Path to where a pid file should be created. 
357351     pub  pid_file :  Option < PathBuf > , 
@@ -596,15 +590,11 @@ mod tests {
596590    fn  global_opts_test ( )  { 
597591        let  cfg = GlobalOpts :: default ( ) . command ( "true" ) ; 
598592        let  runc = cfg. build ( ) . unwrap ( ) ; 
599-         let  args = & runc. args ; 
600-         assert_eq ! ( args. len( ) ,  2 ) ; 
601-         assert ! ( args. contains( & LOG_FORMAT . to_string( ) ) ) ; 
602-         assert ! ( args. contains( & TEXT . to_string( ) ) ) ; 
603- 
604-         let  cfg = GlobalOpts :: default ( ) . command ( "/bin/true" ) ; 
605-         let  runc = cfg. build ( ) . unwrap ( ) ; 
606-         assert_eq ! ( runc. args. len( ) ,  2 ) ; 
593+         let  global_args = & runc. global_args ; 
607594
595+         if  let  Some ( log_format)  = & global_args. log_format  { 
596+             assert ! ( TEXT  == log_format) ; 
597+         } 
608598        let  cfg = GlobalOpts :: default ( ) 
609599            . command ( "true" ) 
610600            . root ( "/tmp" ) 
@@ -614,16 +604,25 @@ mod tests {
614604            . systemd_cgroup ( true ) 
615605            . rootless ( true ) ; 
616606        let  runc = cfg. build ( ) . unwrap ( ) ; 
617-         let  args = & runc. args ; 
618-         assert ! ( args. contains( & ROOT . to_string( ) ) ) ; 
619-         assert ! ( args. contains( & DEBUG . to_string( ) ) ) ; 
620-         assert ! ( args. contains( & "/tmp" . to_string( ) ) ) ; 
621-         assert ! ( args. contains( & LOG . to_string( ) ) ) ; 
622-         assert ! ( args. contains( & "/tmp/runc.log" . to_string( ) ) ) ; 
623-         assert ! ( args. contains( & LOG_FORMAT . to_string( ) ) ) ; 
624-         assert ! ( args. contains( & JSON . to_string( ) ) ) ; 
625-         assert ! ( args. contains( & "--rootless=true" . to_string( ) ) ) ; 
626-         assert ! ( args. contains( & SYSTEMD_CGROUP . to_string( ) ) ) ; 
627-         assert_eq ! ( args. len( ) ,  9 ) ; 
607+         let  global_args = & runc. global_args ; 
608+ 
609+         if  let  Some ( root)  = & global_args. root  { 
610+             assert ! ( root. to_string_lossy( )  == "/tmp" ) ; 
611+         } 
612+         if  let  Some ( debug)  = global_args. debug  { 
613+             assert ! ( debug) ; 
614+         } 
615+         if  let  Some ( log)  = & global_args. log  { 
616+             assert ! ( log. to_string_lossy( )  == "/tmp/runc.log" ) ; 
617+         } 
618+         if  let  Some ( log_format)  = & global_args. log_format  { 
619+             assert ! ( log_format == "json" ) ; 
620+         } 
621+         if  let  Some ( root_less)  = global_args. rootless  { 
622+             assert ! ( root_less) ; 
623+         } 
624+         if  let  Some ( systemd_cgroup)  = global_args. systemd_cgroup  { 
625+             assert ! ( systemd_cgroup) ; 
626+         } 
628627    } 
629628} 
0 commit comments