r-lib / callr

Call R from R
https://callr.r-lib.org/
Other
297 stars 36 forks source link

Subprocess isolation #258

Closed king-of-poppk closed 1 year ago

king-of-poppk commented 1 year ago

Is there any relatively simple way to leverage Linux namespaces to run the created subprocess in isolation?

gaborcsardi commented 1 year ago

callr does not do anything with Linux namespaces. I guess you can call unshare() etc. from the subprocess if you want to change the namespace of the subprocess.

king-of-poppk commented 1 year ago

Is it possible to do that outside of the function supplied to callr? For instance replacing the default R -f command by unshare -f ... R -f?

gaborcsardi commented 1 year ago

Oh, yeah, like this:

ps::ps_uids()

#>     real effective     saved
#>     1000      1000      1000

callr::r(
  function() ps::ps_uids(), 
  arch = Sys.which("unshare"), 
  cmdargs = c(
    "-r",
    file.path(R.home("bin"), "R")
  )
)

#>     real effective     saved
#>        0         0         0
king-of-poppk commented 1 year ago

OK! Thanks. Is there a different logic than file.path(R.home("bin"), "R") to get the R interpreter when using callr::r_session? On macOS for instance, compare

> callr::r_bg(\() {})$get_cmdline()
[1] "/bin/sh"                                                                            
[2] "/Library/Frameworks/R.framework/Resources/bin/R"                                    
[3] "--slave"                                                                            
[4] "--no-save"                                                                          
[5] "--no-restore"                                                                       
[6] "-f"                                                                                 
[7] "/var/folders/..."

to

> rs <- callr::r_session$new()
> rs$get_cmdline()
[1] "/Library/Frameworks/R.framework/Resources/bin/exec/R" "--no-readline"                                       
[3] "--slave"                                              "--no-save"                                           
[5] "--no-restore" 

PS: Also, it seems that if I want to replicate the original behavior, I need to re-add the flags from the default cmdargs.

PPS: FYI --slave is now --no-echo.

gaborcsardi commented 1 year ago

file.path(R.home("bin"), "R") is the correct way to look up the R interpreter on Unix.

If you want the default command line options, do

❯ callr::r_process_options()$cmdargs
[1] "--slave"      "--no-save"    "--no-restore"

❯ callr::r_session_options()$cmdargs
[1] "--no-readline" "--slave"       "--no-save"     "--no-restore"

# etc.

PPS: FYI --slave is now --no-echo.

That does not work on older R versions.

king-of-poppk commented 1 year ago

Thanks! Seems to work so far. Feel free to close.