Skip to content

Commit 0636a2d

Browse files
committed
fix: Use systemCall instead of shellCall wherever possible
1 parent cc22f94 commit 0636a2d

6 files changed

Lines changed: 49 additions & 65 deletions

File tree

src/DIRAC/Core/Security/VOMS.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
from datetime import datetime
55
import os
66
import tempfile
7-
import shlex
87
import shutil
98

109
from DIRAC import S_OK, S_ERROR, gConfig, rootPath, gLogger
1110
from DIRAC.Core.Utilities import DErrno
1211
from DIRAC.Core.Security import Locations
1312
from DIRAC.Core.Security.ProxyFile import multiProxyArgument, deleteMultiProxy
1413
from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error
15-
from DIRAC.Core.Utilities.Subprocess import shellCall
14+
from DIRAC.Core.Utilities.Subprocess import systemCall
1615
from DIRAC.Core.Utilities import List
1716

1817
# This is a variable so it can be monkeypatched in tests
@@ -267,9 +266,9 @@ def setVOMSAttributes(self, proxy, attribute=None, vo=None):
267266

268267
cmd = voms_init_cmd(vo, attribute, chain, proxyLocation, newProxyLocation, self.getVOMSESLocation())
269268

270-
result = shellCall(
269+
result = systemCall(
271270
self._secCmdTimeout,
272-
shlex.join(cmd),
271+
cmd,
273272
env=os.environ
274273
| {
275274
"X509_CERT_DIR": Locations.getCAsLocation(),
@@ -313,7 +312,7 @@ def vomsInfoAvailable(self):
313312
if not vpInfoCmd:
314313
return S_ERROR(DErrno.EVOMS, "Missing voms-proxy-info")
315314
cmd = f"{vpInfoCmd} -h"
316-
result = shellCall(self._secCmdTimeout, cmd)
315+
result = systemCall(self._secCmdTimeout, cmd.split())
317316
if not result["OK"]:
318317
return False
319318
status, _output, _error = result["Value"]

src/DIRAC/Core/Utilities/Grid.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44

55
from DIRAC.Core.Utilities.ReturnValues import S_ERROR, S_OK
6-
from DIRAC.Core.Utilities.Subprocess import shellCall
6+
from DIRAC.Core.Utilities.Subprocess import systemCall
77

88

99
def ldapsearchBDII(filt=None, attr=None, host=None, base=None, selectionString="Glue"):
@@ -34,8 +34,8 @@ def ldapsearchBDII(filt=None, attr=None, host=None, base=None, selectionString="
3434
if isinstance(attr, list):
3535
attr = " ".join(attr)
3636

37-
cmd = f'ldapsearch -x -LLL -o ldif-wrap=no -H ldap://{host} -b {base} "{filt}" {attr}'
38-
result = shellCall(0, cmd)
37+
cmd = ["ldapsearch", "-x", "-LLL", "-o", "ldif-wrap=no", "-H", f"ldap://{host}", "-b", base, filt, attr]
38+
result = systemCall(0, cmd)
3939

4040
response = []
4141

src/DIRAC/Core/Utilities/Os.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import DIRAC
1010
from DIRAC.Core.Utilities import List
11-
from DIRAC.Core.Utilities.Subprocess import shellCall, systemCall
11+
from DIRAC.Core.Utilities.Subprocess import systemCall
1212

1313
DEBUG = 0
1414

@@ -36,19 +36,17 @@ def getDiskSpace(path=".", exclude=None):
3636

3737
if not os.path.exists(path):
3838
return -1
39-
comm = f"df -P -m {path} "
39+
comm = ["df", "-P", "-m", path]
4040
if exclude:
41-
comm += f"-x {exclude} "
42-
comm += "| tail -1"
43-
resultDF = shellCall(10, comm)
41+
comm.extend(["-x", exclude])
42+
resultDF = systemCall(10, comm)
4443
if not resultDF["OK"] or resultDF["Value"][0]:
4544
return -1
46-
output = resultDF["Value"][1]
45+
output = resultDF["Value"][1].strip().splitlines()[-1]
4746
if output.find(" /afs") >= 0: # AFS disk space
48-
comm = "fs lq | tail -1"
49-
resultAFS = shellCall(10, comm)
47+
resultAFS = systemCall(10, ["fs", "lq"])
5048
if resultAFS["OK"] and not resultAFS["Value"][0]:
51-
output = resultAFS["Value"][1]
49+
output = resultAFS["Value"][1].strip().splitlines()[-1]
5250
fields = output.split()
5351
quota = int(fields[1])
5452
used = int(fields[2])
@@ -67,8 +65,7 @@ def getDiskSpace(path=".", exclude=None):
6765
def getDirectorySize(path):
6866
"""Get the total size of the given directory in MB"""
6967

70-
comm = f"du -s -m {path}"
71-
result = shellCall(10, comm)
68+
result = systemCall(10, ["du", "-s", "-m", path])
7269
if not result["OK"] or result["Value"][0] != 0:
7370
return 0
7471
output = result["Value"][1]

src/DIRAC/FrameworkSystem/Service/SystemAdministratorHandler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from DIRAC.Core.Utilities import Os
2626
from DIRAC.Core.Utilities.Extensions import extensionsByPriority, getExtensionMetadata
2727
from DIRAC.Core.Utilities.File import mkLink
28-
from DIRAC.Core.Utilities.Subprocess import shellCall
28+
from DIRAC.Core.Utilities.Subprocess import systemCall
2929
from DIRAC.Core.Utilities.ThreadScheduler import gThreadScheduler
3030
from DIRAC.Core.Utilities.TimeUtilities import day, fromString, hour
3131
from DIRAC.FrameworkSystem.Client.ComponentInstaller import gComponentInstaller
@@ -471,7 +471,7 @@ def export_addOptionToDiracCfg(self, option, value):
471471

472472
def export_executeCommand(self, command):
473473
"""Execute a command locally and return its output"""
474-
result = shellCall(60, command)
474+
result = systemCall(60, command.split())
475475
return result
476476

477477
types_checkComponentLog = [[str, list]]

src/DIRAC/Resources/Storage/RFIOStorage.py

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from DIRAC import gLogger, S_OK, S_ERROR
99
from DIRAC.Resources.Storage.Utilities import checkArgumentFormat
1010
from DIRAC.Resources.Storage.StorageBase import StorageBase
11-
from DIRAC.Core.Utilities.Subprocess import shellCall
11+
from DIRAC.Core.Utilities.Subprocess import systemCall
1212
from DIRAC.Core.Utilities.List import breakListIntoChunks
1313
from DIRAC.Core.Utilities.File import getSize
1414

@@ -47,10 +47,7 @@ def exists(self, path):
4747
return res
4848
urls = res["Value"]
4949
gLogger.debug(f"RFIOStorage.exists: Determining the existance of {len(urls)} files.")
50-
comm = "nsls -d"
51-
for url in urls:
52-
comm = f" {comm} {url}"
53-
res = shellCall(self.timeout, comm)
50+
res = systemCall(self.timeout, ["nsls", "-d"] + urls)
5451
successful = {}
5552
failed = {}
5653
if res["OK"]:
@@ -83,10 +80,7 @@ def isFile(self, path):
8380
gLogger.debug(f"RFIOStorage.isFile: Determining whether {len(urls)} paths are files.")
8481
successful = {}
8582
failed = {}
86-
comm = "nsls -ld"
87-
for url in urls:
88-
comm = f" {comm} {url}"
89-
res = shellCall(self.timeout, comm)
83+
res = systemCall(self.timeout, ["nsls", "-ld"] + urls)
9084
if not res["OK"]:
9185
return res
9286
returncode, stdout, stderr = res["Value"]
@@ -110,10 +104,7 @@ def isFile(self, path):
110104

111105
def __getPathMetadata(self, urls):
112106
gLogger.debug(f"RFIOStorage.__getPathMetadata: Attempting to get metadata for {len(urls)} paths.")
113-
comm = "nsls -ld"
114-
for url in urls:
115-
comm = f" {comm} {url}"
116-
res = shellCall(self.timeout, comm)
107+
res = systemCall(self.timeout, ["nsls", "-ld"] + urls)
117108
successful = {}
118109
failed = {}
119110
if not res["OK"]:
@@ -155,12 +146,12 @@ def __permissionsToInt(self, permissions):
155146
def __getFileMetadata(self, urls):
156147
gLogger.debug(f"RFIOStorage.__getPathMetadata: Attempting to get additional metadata for {len(urls)} files.")
157148
# Check whether the files that exist are staged
158-
comm = f"stager_qry -S {self.spaceToken}"
149+
cmd = ["stager_qry", "-S", self.spaceToken]
159150
successful = {}
160151
for pfn in urls:
161152
successful[pfn] = {}
162-
comm = f"{comm} -M {pfn}"
163-
res = shellCall(self.timeout, comm)
153+
cmd.extend(["-M", pfn])
154+
res = systemCall(self.timeout, cmd)
164155
if not res["OK"]:
165156
errStr = "RFIOStorage.__getFileMetadata: Completely failed to get cached status."
166157
gLogger.error(errStr, res["Message"])
@@ -177,10 +168,8 @@ def __getFileMetadata(self, urls):
177168
successful[pfn]["Cached"] = False
178169

179170
# Now for the files that exist get the tape segment (i.e. whether they have been migrated) and related checksum
180-
comm = "nsls -lT --checksum"
181-
for pfn in urls:
182-
comm = f"{comm} {pfn}"
183-
res = shellCall(self.timeout, comm)
171+
cmd = ["nsls", "-lT", "--checksum"] + list(urls)
172+
res = systemCall(self.timeout, cmd)
184173
if not res["OK"]:
185174
errStr = "RFIOStorage.__getFileMetadata: Completely failed to get migration status."
186175
gLogger.error(errStr, res["Message"])
@@ -240,8 +229,8 @@ def __getFile(self, src_url, dest_file):
240229
MIN_BANDWIDTH = 1024 * 100 # 100 KB/s
241230
timeout = int(remoteSize / MIN_BANDWIDTH + 300)
242231
gLogger.debug(f"RFIOStorage.getFile: Executing transfer of {src_url} to {dest_file}")
243-
comm = f"rfcp {src_url} {dest_file}"
244-
res = shellCall(timeout, comm)
232+
comm = ["rfcp", src_url, dest_file]
233+
res = systemCall(timeout, comm)
245234
if res["OK"]:
246235
returncode, _stdout, stderr = res["Value"]
247236
if returncode == 0:
@@ -317,8 +306,8 @@ def __putFile(self, src_file, dest_url, sourceSize):
317306
MIN_BANDWIDTH = 1024 * 100 # 100 KB/s
318307
timeout = sourceSize / MIN_BANDWIDTH + 300
319308
gLogger.debug(f"RFIOStorage.putFile: Executing transfer of {src_file} to {turl}")
320-
comm = f"rfcp {src_file} '{turl}'"
321-
res = shellCall(timeout, comm)
309+
comm = ["rfcp", src_file, turl]
310+
res = systemCall(timeout, comm)
322311
if res["OK"]:
323312
returncode, _stdout, stderr = res["Value"]
324313
if returncode == 0:
@@ -357,17 +346,17 @@ def removeFile(self, path):
357346
listOfLists = breakListIntoChunks(urls, 100)
358347
for urls in listOfLists:
359348
gLogger.debug(f"RFIOStorage.removeFile: Attempting to remove {len(urls)} files.")
360-
comm = f"stager_rm -S {self.spaceToken}"
349+
comm = ["stager_rm", "-S", self.spaceToken]
361350
for url in urls:
362-
comm = f"{comm} -M {url}"
363-
res = shellCall(100, comm)
351+
comm.extend(["-M", url])
352+
res = systemCall(100, comm)
364353
if res["OK"]:
365354
returncode, _stdout, stderr = res["Value"]
366355
if returncode in [0, 1]:
367-
comm = "nsrm -f"
356+
comm = ["nsrm", "-f"]
368357
for url in urls:
369-
comm = f"{comm} {url}"
370-
res = shellCall(100, comm)
358+
comm.append(url)
359+
res = systemCall(100, comm)
371360
if res["OK"]:
372361
returncode, _stdout, stderr = res["Value"]
373362
if returncode in [0, 1]:
@@ -461,10 +450,10 @@ def prestageFile(self, path):
461450
return res
462451
urls = res["Value"]
463452
userTag = f"{self.spaceToken}-{time.time()}"
464-
comm = f"stager_get -S {self.spaceToken} -U {userTag} "
453+
comm = ["stager_get", "-S", self.spaceToken, "-U", userTag]
465454
for url in urls:
466-
comm = f"{comm} -M {url}"
467-
res = shellCall(100, comm)
455+
comm.extend(["-M", url])
456+
res = systemCall(100, comm)
468457
successful = {}
469458
failed = {}
470459
if res["OK"]:
@@ -502,8 +491,8 @@ def prestageFileStatus(self, path):
502491
requestFiles[requestID] = []
503492
requestFiles[requestID].append(url)
504493
for requestID, urls in requestFiles.items():
505-
comm = f"stager_qry -S {self.spaceToken} -U {requestID} "
506-
res = shellCall(100, comm)
494+
comm = ["stager_qry", "-S", self.spaceToken, "-U", requestID]
495+
res = systemCall(100, comm)
507496
if res["OK"]:
508497
returncode, stdout, stderr = res["Value"]
509498
if returncode in [0, 1]:
@@ -799,8 +788,8 @@ def createDirectory(self, path):
799788

800789
def __makeDir(self, path):
801790
# First create a local file that will be used as a directory place holder in storage name space
802-
comm = f"nsmkdir -m 775 {path}"
803-
res = shellCall(100, comm)
791+
comm = ["nsmkdir", "-m", "775", path]
792+
res = systemCall(100, comm)
804793
if not res["OK"]:
805794
return res
806795
returncode, _stdout, stderr = res["Value"]
@@ -841,8 +830,8 @@ def removeDirectory(self, path, recursive=False):
841830
successful = {}
842831
failed = {}
843832
for url in urls:
844-
comm = f"nsrm -r {url}"
845-
res = shellCall(100, comm)
833+
comm = ["nsrm", "-r", url]
834+
res = systemCall(100, comm)
846835
if res["OK"]:
847836
returncode, _stdout, stderr = res["Value"]
848837
if returncode == 0:
@@ -880,8 +869,8 @@ def listDirectory(self, path):
880869
failed[url] = errStr
881870

882871
for directory in directories:
883-
comm = f"nsls -l {directory}"
884-
res = shellCall(self.timeout, comm)
872+
comm = ["nsls", "-l", directory]
873+
res = systemCall(self.timeout, comm)
885874
if res["OK"]:
886875
returncode, stdout, stderr = res["Value"]
887876
if not returncode == 0:

src/DIRAC/TransformationSystem/Client/TransformationCLI.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from DIRAC.Core.Base.CLI import CLI
88
from DIRAC.Core.Base.API import API
9-
from DIRAC.Core.Utilities.Subprocess import shellCall
9+
from DIRAC.Core.Utilities.Subprocess import systemCall
1010
from DIRAC.TransformationSystem.Client import TransformationFilesStatus
1111
from DIRAC.TransformationSystem.Client.Transformation import Transformation
1212
from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
@@ -73,8 +73,7 @@ def do_shell(self, args):
7373
7474
usage !<shell_command>
7575
"""
76-
comm = args
77-
res = shellCall(0, comm)
76+
res = systemCall(0, args.split())
7877
if res["OK"] and res["Value"][0] == 0:
7978
_returnCode, stdOut, stdErr = res["Value"]
8079
print(f"{stdOut}\n{stdErr}")

0 commit comments

Comments
 (0)