1
+ #!/usr/bin/env python
1
2
""" Starts a DIRAC command inside an apptainer container.
2
3
"""
3
4
4
5
import os
5
6
import sys
7
+ from pathlib import Path
6
8
7
9
import DIRAC
8
10
from DIRAC import S_ERROR , gConfig , gLogger
9
11
from DIRAC .Core .Base .Script import Script
10
12
from DIRAC .Core .Security .Locations import getCAsLocation , getProxyLocation , getVOMSLocation
11
13
from DIRAC .Core .Utilities .Subprocess import systemCall
12
14
13
- CONTAINER_WRAPPER = """#!/bin/bash
14
15
15
- export DIRAC=%(dirac_env_var)s
16
- export DIRACOS=%(diracos_env_var)s
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
21
- source %(rc_script)s
22
- %(command)s
23
- """
16
+ def generate_container_wrapper (dirac_env_var , diracos_env_var , etc_dir , rc_script , command , include_proxy = True ):
17
+ lines = [
18
+ "#!/bin/bash" ,
19
+ f"export DIRAC={ dirac_env_var } " ,
20
+ f"export DIRACOS={ diracos_env_var } " ,
21
+ ]
22
+
23
+ if include_proxy :
24
+ lines .append ("export X509_USER_PROXY=/etc/proxy" )
25
+
26
+ lines .extend (
27
+ [
28
+ "export X509_CERT_DIR=/etc/grid-security/certificates" ,
29
+ "export X509_VOMS_DIR=/etc/grid-security/vomsdir" ,
30
+ "export X509_VOMSES=/etc/grid-security/vomses" ,
31
+ f"export DIRACSYSCONFIG={ etc_dir } /dirac.cfg" ,
32
+ f"source { rc_script } " ,
33
+ command ,
34
+ ]
35
+ )
36
+
37
+ return "\n " .join (lines )
38
+
24
39
25
40
CONTAINER_DEFROOT = "" # Should add something like "/cvmfs/dirac.egi.eu/container/apptainer/alma9/x86_64"
26
41
@@ -36,28 +51,37 @@ def main():
36
51
if switch [0 ].lower () == "i" or switch [0 ].lower () == "image" :
37
52
user_image = switch [1 ]
38
53
54
+ dirac_env_var = os .environ .get ("DIRAC" , os .getcwd ())
55
+ diracos_env_var = os .environ .get ("DIRACOS" , os .getcwd ())
39
56
etc_dir = os .path .join (DIRAC .rootPath , "etc" )
40
-
41
- wrapSubs = {
42
- "dirac_env_var" : os .environ .get ("DIRAC" , os .getcwd ()),
43
- "diracos_env_var" : os .environ .get ("DIRACOS" , os .getcwd ()),
44
- "etc_dir" : etc_dir ,
45
- }
46
- wrapSubs ["rc_script" ] = os .path .join (os .path .realpath (sys .base_prefix ), "diracosrc" )
47
- wrapSubs ["command" ] = command
48
-
49
- rawfd = os .open ("dirac_container.sh" , os .O_WRONLY | os .O_CREAT , 0o700 )
50
- fd = os .fdopen (rawfd , "w" )
51
- fd .write (CONTAINER_WRAPPER % wrapSubs )
52
- fd .close ()
53
-
57
+ rc_script = os .path .join (os .path .realpath (sys .base_prefix ), "diracosrc" )
58
+
59
+ include_proxy = True
60
+ proxy_location = getProxyLocation ()
61
+ if not proxy_location :
62
+ include_proxy = False
63
+
64
+ with open ("dirac_container.sh" , "w" , encoding = "utf-8" ) as fd :
65
+ script = generate_container_wrapper (
66
+ dirac_env_var , diracos_env_var , etc_dir , rc_script , command , include_proxy = include_proxy
67
+ )
68
+ fd .write (script )
69
+ fd .close ()
70
+ os .chmod ("dirac_container.sh" , 0o755 )
71
+
72
+ # Now let's construct the apptainer command
54
73
cmd = ["apptainer" , "exec" ]
55
74
cmd .extend (["--contain" ]) # use minimal /dev and empty other directories (e.g. /tmp and $HOME)
56
75
cmd .extend (["--ipc" ]) # run container in a new IPC namespace
76
+ cmd .extend (["--pid" ]) # run container in a new PID namespace
57
77
cmd .extend (["--bind" , f"{ os .getcwd ()} :/mnt" ]) # bind current directory for dirac_container.sh
58
- cmd .extend (["--bind" , f"{ getProxyLocation ()} :/etc/proxy" ]) # bind proxy file
78
+ if proxy_location :
79
+ cmd .extend (["--bind" , f"{ proxy_location } :/etc/proxy" ]) # bind proxy file
59
80
cmd .extend (["--bind" , f"{ getCAsLocation ()} :/etc/grid-security/certificates" ]) # X509_CERT_DIR
60
- cmd .extend (["--bind" , f"{ getVOMSLocation ()} :/etc/grid-security/vomsdir" ]) # X509_VOMS_DIR
81
+ voms_location = Path (getVOMSLocation ())
82
+ cmd .extend (["--bind" , f"{ voms_location } :/etc/grid-security/vomsdir" ]) # X509_VOMS_DIR
83
+ vomses_location = voms_location .parent / "vomses"
84
+ cmd .extend (["--bind" , f"{ vomses_location } :/etc/grid-security/vomses" ]) # X509_VOMSES
61
85
cmd .extend (["--bind" , "{0}:{0}:ro" .format (etc_dir )]) # etc dir for dirac.cfg
62
86
cmd .extend (["--bind" , "{0}:{0}:ro" .format (os .path .join (os .path .realpath (sys .base_prefix )))]) # code dir
63
87
@@ -73,7 +97,11 @@ def main():
73
97
gLogger .debug (f"Execute Apptainer command: { ' ' .join (cmd )} " )
74
98
result = systemCall (0 , cmd )
75
99
if not result ["OK" ]:
100
+ gLogger .error (result ["Message" ])
76
101
DIRAC .exit (1 )
102
+ if result ["Value" ][0 ] != 0 :
103
+ gLogger .error (result ["Value" ][2 ])
104
+ DIRAC .exit (2 )
77
105
gLogger .notice (result ["Value" ][1 ])
78
106
79
107
0 commit comments