22"""
33
44import os
5- import shutil
65import sys
76
87import DIRAC
98from DIRAC import S_ERROR , gConfig , gLogger
109from DIRAC .Core .Base .Script import Script
10+ from DIRAC .Core .Security .Locations import getCAsLocation , getProxyLocation , getVOMSLocation
1111from DIRAC .Core .Utilities .Subprocess import systemCall
1212
1313CONTAINER_WRAPPER = """#!/bin/bash
1414
15- echo "Starting inner container wrapper scripts (no install) at `date`."
1615export DIRAC=%(dirac_env_var)s
1716export DIRACOS=%(diracos_env_var)s
18- # In any case we need to find a bashrc, and a cfg
17+ export X509_USER_PROXY=/etc/proxy
18+ export X509_CERT_DIR=/etc/grid-security/certificates
19+ export X509_VOMS_DIR=/etc/grid-security/vomsdir
20+ export DIRACSYSCONFIG=%(etc_dir)s/dirac.cfg
1921source %(rc_script)s
2022%(command)s
21- echo "Finishing inner container wrapper scripts at `date`."
2223"""
2324
2425CONTAINER_DEFROOT = "" # Should add something like "/cvmfs/dirac.egi.eu/container/apptainer/alma9/x86_64"
2526
2627
27- def getEnv ():
28- """Gets the environment for use within the container.
29- We blank almost everything to prevent contamination from the host system.
30- """
31-
32- payloadEnv = {k : v for k , v in os .environ .items ()}
33- payloadEnv ["TMP" ] = "/tmp"
34- payloadEnv ["TMPDIR" ] = "/tmp"
35- payloadEnv ["X509_USER_PROXY" ] = os .path .join ("tmp" , "proxy" )
36- payloadEnv ["DIRACSYSCONFIG" ] = os .path .join ("tmp" , "dirac.cfg" )
37-
38- return payloadEnv
39-
40-
4128@Script ()
4229def main ():
4330 Script .registerArgument (" command: Command to execute inside the container" )
@@ -50,41 +37,45 @@ def main():
5037 if switch [0 ].lower () == "i" or switch [0 ].lower () == "image" :
5138 user_image = switch [1 ]
5239
40+ etc_dir = os .path .join (DIRAC .rootPath , "etc" )
41+
5342 wrapSubs = {
5443 "dirac_env_var" : os .environ .get ("DIRAC" , os .getcwd ()),
5544 "diracos_env_var" : os .environ .get ("DIRACOS" , os .getcwd ()),
45+ "etc_dir" : etc_dir ,
5646 }
5747 wrapSubs ["rc_script" ] = os .path .join (os .path .realpath (sys .base_prefix ), "diracosrc" )
5848 wrapSubs ["command" ] = command
59- shutil .copyfile ("dirac.cfg" , os .path .join ("tmp" , "dirac.cfg" ))
6049
61- wrapLoc = os .path .join ("tmp" , "dirac_container.sh" )
62- rawfd = os .open (wrapLoc , os .O_WRONLY | os .O_CREAT , 0o700 )
50+ rawfd = os .open ("dirac_container.sh" , os .O_WRONLY | os .O_CREAT , 0o700 )
6351 fd = os .fdopen (rawfd , "w" )
6452 fd .write (CONTAINER_WRAPPER % wrapSubs )
6553 fd .close ()
6654
67- innerCmd = os .path .join ("tmp" , "dirac_container.sh" )
6855 cmd = ["apptainer" , "exec" ]
6956 cmd .extend (["--contain" ]) # use minimal /dev and empty other directories (e.g. /tmp and $HOME)
7057 cmd .extend (["--ipc" ]) # run container in a new IPC namespace
71- cmd .extend (["--workdir" , "/tmp" ]) # working directory to be used for /tmp, /var/tmp and $HOME
72- cmd .extend (["--home" , "/tmp" ]) # Avoid using small tmpfs for default $HOME and use scratch /tmp instead
73- cmd .extend (["--bind" , "{0}:{0}:ro" .format (os .path .join (os .path .realpath (sys .base_prefix )))])
58+ cmd .extend (["--bind" , f"{ os .getcwd ()} :/mnt" ]) # bind current directory for dirac_container.sh
59+ cmd .extend (["--bind" , f"{ getProxyLocation ()} :/etc/proxy" ]) # bind proxy file
60+ cmd .extend (["--bind" , f"{ getCAsLocation ()} :/etc/grid-security/certificates" ]) # X509_CERT_DIR
61+ cmd .extend (["--bind" , f"{ getVOMSLocation ()} :/etc/grid-security/vomsdir" ]) # X509_VOMS_DIR
62+ cmd .extend (["--bind" , "{0}:{0}:ro" .format (etc_dir )]) # etc dir for dirac.cfg
63+ cmd .extend (["--bind" , "{0}:{0}:ro" .format (os .path .join (os .path .realpath (sys .base_prefix )))]) # code dir
7464
7565 rootImage = user_image or gConfig .getValue ("/Resources/Computing/Singularity/ContainerRoot" ) or CONTAINER_DEFROOT
7666
7767 if os .path .isdir (rootImage ) or os .path .isfile (rootImage ):
78- cmd .extend ([rootImage , innerCmd ])
68+ cmd .extend ([rootImage , "/mnt/dirac_container.sh" ])
7969 else :
8070 # if we are here is because there's no image, or it is not accessible (e.g. not on CVMFS)
8171 gLogger .error ("Apptainer image to exec not found: " , rootImage )
8272 return S_ERROR ("Failed to find Apptainer image to exec" )
8373
84- gLogger .debug (f"Execute Apptainer command: { cmd } " )
85- result = systemCall (0 , cmd , env = getEnv () )
74+ gLogger .debug (f"Execute Apptainer command: { ' ' . join ( cmd ) } " )
75+ result = systemCall (0 , cmd )
8676 if not result ["OK" ]:
8777 DIRAC .exit (1 )
78+ gLogger .notice (result ["Value" ][1 ])
8879
8980
9081if __name__ == "__main__" :
0 commit comments