Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
python -c "import rda_python_common; print(rda_python_common.__version__)"
```

You should see the installed version (currently `2.1.9`). If the import
You should see the installed version (currently `2.1.10`). If the import
fails, double-check that the active Python environment is the one where you
ran `pip install`.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "rda_python_common"
version = "2.1.9"
version = "2.1.10"
authors = [
{ name="Zaihua Ji", email="zji@ucar.edu" },
]
Expand Down
2 changes: 1 addition & 1 deletion src/rda_python_common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from . import PgLOG, PgUtil, PgDBI, PgFile, PgLock, PgCMD, PgSIG, PgOPT, PgSplit

__version__ = "2.1.9"
__version__ = "2.1.10"

__all__ = [
"PgLOG",
Expand Down
8 changes: 7 additions & 1 deletion src/rda_python_common/pg_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def get_partition_control(self, pgpart, pgrqst=None, pgctl=None, logact=0):
if pgrqst: pgctl = self.get_dsrqst_control(pgrqst, logact)
return pgctl

def get_dynamic_options(self, cmd, oindex, otype):
def get_dynamic_options(self, cmd, oindex, otype, hostname=None):
"""Runs cmd to retrieve dynamic option strings, retrying on timeout.

Executes the command up to three times, retrying when a connection
Expand All @@ -401,13 +401,19 @@ def get_dynamic_options(self, cmd, oindex, otype):
oindex (int or None): Object index appended to cmd when truthy.
otype (str or None): Object type appended to cmd when truthy;
'R' selects the first option from a slash-separated pair.
hostname (str or None): If provided, the command is executed
remotely via ``ssh <hostname> ...`` instead of locally; the
leading command name is resolved to its absolute path via
``command_path`` so the remote shell does not depend on its
own PATH.

Returns:
str: The parsed option string, or '' if the command produced no
usable output (error details are appended to PGLOG['SYSERR']).
"""
if oindex: cmd += " {}".format(oindex)
if otype: cmd += ' ' + otype
if hostname: cmd = "ssh {} {}".format(hostname, self.command_path(cmd))
ret = options = ''
for loop in range(3):
ret = self.pgsystem(cmd, self.LOGWRN, 1299) # 1+2+16+256+1024
Expand Down
19 changes: 12 additions & 7 deletions src/rda_python_common/pg_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def __init__(self):
self.BCHCMDS = {'PBS': 'qsub'}
# global dists to cashe information
self.COMMANDS = {}
self.CMDPATHS = {} # cache of bare command name -> full path (or '' if not found)
self.PBSHOSTS = []
self.PBSSTATS = {}
# set additional common PGLOG values
Expand Down Expand Up @@ -1197,15 +1198,19 @@ def command_path(self, cmdstr):
Returns:
String with the leading command resolved to its full path, or the
original *cmdstr* if the command already contains a path separator
or cannot be found via ``shutil.which``.
or cannot be found via ``shutil.which``. Results of the
``shutil.which`` lookup are cached in ``self.CMDPATHS``.
"""
if not cmdstr: return ''
ary = cmdstr.split(' ', 1)
cmd = ary[0]
if re.search(r'[\\/]', cmd): return cmdstr
optstr = (' ' + ary[1]) if len(ary) > 1 else ''
pcmd = shutil.which(cmd)
return (pcmd+optstr) if pcmd else cmdstr
sp = cmdstr.find(' ')
cmd = cmdstr if sp < 0 else cmdstr[:sp]
if '/' in cmd or '\\' in cmd: return cmdstr
pcmd = self.CMDPATHS.get(cmd)
if pcmd is None:
pcmd = shutil.which(cmd) or ''
self.CMDPATHS[cmd] = pcmd
if not pcmd: return cmdstr
return pcmd if sp < 0 else pcmd + cmdstr[sp:]

def add_carbon_copy(self, cc=None, isstr=None, exclude=0, specialist=None):
"""Update the Cc address list in ``PGLOG['CCDADDR']``.
Expand Down
Loading