Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/hsi #21

Closed
wants to merge 13 commits into from
2 changes: 2 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ API
timetools
jinja
logger
hsi
htar


11 changes: 11 additions & 0 deletions docs/hsi.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. currentmodule:: wxflow.hsi

.. autofunction:: hsi
.. autofunction:: get
.. autofunction:: put
.. autofunction:: chmod
.. autofunction:: chgrp
.. autofunction:: rm
.. autofunction:: mkdir
.. autofunction:: ls
.. autofunction:: exists
8 changes: 8 additions & 0 deletions docs/htar.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. currentmodule:: wxflow.htar

.. autofunction:: htar
.. autofunction:: create
.. autofunction:: extract
.. autofunction:: xvf
.. autofunction:: cvf
.. autofunction:: tell
3 changes: 2 additions & 1 deletion src/wxflow/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import os

from . import hsi, htar
from .attrdict import AttrDict
from .configuration import (Configuration, cast_as_dtype,
cast_strdict_as_dtypedict)
from .exceptions import WorkflowException, msg_except_handle
from .executable import CommandNotFoundError, Executable, ProcessError, which
from .factory import Factory
from .file_utils import FileHandler
from .fsutils import chdir, cp, mkdir, mkdir_p, rm_p, rmdir
from .fsutils import chdir, chgrp, cp, get_gid, mkdir, mkdir_p, rm_p, rmdir
from .jinja import Jinja
from .logger import Logger, logit
from .sqlitedb import SQLiteDB, SQLiteDBError
Expand Down
22 changes: 21 additions & 1 deletion src/wxflow/fsutils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import contextlib
import errno
import grp
import os
import shutil

__all__ = ['mkdir', 'mkdir_p', 'rmdir', 'chdir', 'rm_p', 'cp']
__all__ = ['mkdir', 'mkdir_p', 'rmdir', 'chdir', 'rm_p', 'cp',
'get_gid', 'chgrp']


def mkdir_p(path):
Expand Down Expand Up @@ -85,3 +87,21 @@
raise OSError(f"unable to copy {source} to {target}")
except Exception as exc:
raise Exception(exc)


# Group ID number for a given group name
def get_gid(group_name: str):
try:
group_id = grp.getgrnam(group_name)
except KeyError:
raise KeyError(f"{group_name} is not a valid group name.")

Check warning on line 97 in src/wxflow/fsutils.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/fsutils.py#L94-L97

Added lines #L94 - L97 were not covered by tests

return group_id

Check warning on line 99 in src/wxflow/fsutils.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/fsutils.py#L99

Added line #L99 was not covered by tests


# Change the group of a target file or directory
def chgrp(target, group_name, recursive=False):
# TODO add recursive option
gid = get_gid(group_name)
uid = os.stat(target).st_uid
os.chown(target, uid, gid)

Check warning on line 107 in src/wxflow/fsutils.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/fsutils.py#L105-L107

Added lines #L105 - L107 were not covered by tests
286 changes: 286 additions & 0 deletions src/wxflow/hsi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
from .executable import Executable, which

__all__ = ['hsi', 'get', 'put', 'ls', 'chmod', 'chgrp', 'rm',
'mkdir', 'file_exists']


def hsi(*args) -> str:
"""Direct command builder function for hsi based on the input arguments.

`args` should consist of a set of string arguments to send to hsi
For example, hsi("get","some_local_file : /some/hpss/file") will execute
hsi get some_local_file : /some/hpss/file

Return: str
Concatenated output and error of the hsi command.
"""

cmd = which("hsi", required=True)

Check warning on line 18 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L18

Added line #L18 was not covered by tests

for arg in args:
cmd.add_default_arg(arg)

Check warning on line 21 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L21

Added line #L21 was not covered by tests

output = cmd(output=str.split, error=str.split)

Check warning on line 23 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L23

Added line #L23 was not covered by tests

return output

Check warning on line 25 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L25

Added line #L25 was not covered by tests


def get(source: str, target: str = "", hsi_flags: str = "") -> str:
""" Function to get a file from HPSS via hsi

Parameters
----------
source : str
Full path location on HPSS of the file

target : str
Location on the local machine to place the file. If not specified,
then the file will be placed in the current directory.

hsi_flags : str
String of flags to send to hsi.
"""
args = []

Check warning on line 43 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L43

Added line #L43 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 47 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L47

Added line #L47 was not covered by tests

args.append("get")

Check warning on line 49 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L49

Added line #L49 was not covered by tests
if len(target) == 0:
args.append(source)

Check warning on line 51 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L51

Added line #L51 was not covered by tests
else:
args.append(target + " : " + source)

Check warning on line 53 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L53

Added line #L53 was not covered by tests

output = hsi(*args)

Check warning on line 55 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L55

Added line #L55 was not covered by tests

return output

Check warning on line 57 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L57

Added line #L57 was not covered by tests


def put(source: str, target: str, hsi_flags: str = "",
listing_file: str = None) -> str:
""" Function to put a file onto HPSS via hsi

Parameters
----------
source : str
Location on the local machine of the source file to send to HPSS.

target : str
Full path of the target location of the file on HPSS.

hsi_flags : str
String of flags to send to hsi.
"""
args = []

Check warning on line 75 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L75

Added line #L75 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 79 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L79

Added line #L79 was not covered by tests

args.append("put")
args.append(source + " : " + target)
output = hsi(*args)

Check warning on line 83 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L81-L83

Added lines #L81 - L83 were not covered by tests

return output

Check warning on line 85 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L85

Added line #L85 was not covered by tests


def chmod(mod: str, target: str, hsi_flags: str = "",
chmod_flags: str = "") -> str:
""" Function to change the permissions of a file or directory on HPSS

Parameters
----------
mod : str
Permissions to set for the file or directory,
e.g. "640", "o+r", etc.

target : str
Full path of the target location of the file on HPSS.

hsi_flags : str
String of flags to send to hsi.

chmod_flags : str
Flags to send to chmod. See "hsi chmod -?" for more details.
"""

args = []

Check warning on line 108 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L108

Added line #L108 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 112 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L112

Added line #L112 was not covered by tests

args.append("chmod")

Check warning on line 114 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L114

Added line #L114 was not covered by tests

if len(chmod_flags) > 0:
args.extend(chmod_flags.split(" "))

Check warning on line 117 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L117

Added line #L117 was not covered by tests

args.append(mod)
args.append(target)
output = hsi(*args)

Check warning on line 121 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L119-L121

Added lines #L119 - L121 were not covered by tests

return output

Check warning on line 123 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L123

Added line #L123 was not covered by tests


def chgrp(group_name: str, target: str, hsi_flags: str = "",
chgrp_flags: str = "") -> str:
""" Function to change the group of a file or directory on HPSS

Parameters
----------
group_name : str
The group to which ownership of the file/directory is to be set.

target : str
Full path of the target location of the file on HPSS.

hsi_flags : str
String of flags to send to hsi.

chgrp_flags : str
Flags to send to chgrp. See "hsi chgrp -?" for more details.
"""

args = []

Check warning on line 145 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L145

Added line #L145 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 149 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L149

Added line #L149 was not covered by tests

args.append("chgrp")

Check warning on line 151 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L151

Added line #L151 was not covered by tests

if len(chgrp_flags) > 0:
args.extend(chgrp_flags.split(" "))

Check warning on line 154 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L154

Added line #L154 was not covered by tests

args.append(group_name)
args.append(target)
output = hsi(*args)

Check warning on line 158 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L156-L158

Added lines #L156 - L158 were not covered by tests

return output

Check warning on line 160 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L160

Added line #L160 was not covered by tests


def rm(target: str, hsi_flags: str = "", rm_flags: str = "") -> str:
""" Function to delete a file or directory on HPSS via hsi

Parameters
----------
target : str
Full path of the target location of the file on HPSS.

hsi_flags : str
String of flags to send to hsi.

rm_flags : str
Flags to send to rm. See "hsi rm -?" for more details.
"""

args = []

Check warning on line 178 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L178

Added line #L178 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 182 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L182

Added line #L182 was not covered by tests

args.append("rm")

Check warning on line 184 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L184

Added line #L184 was not covered by tests

if len(rm_flags) > 0:
args.extend(rm_flags.split(" "))

Check warning on line 187 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L187

Added line #L187 was not covered by tests

args.append(target)
output = hsi(*args)

Check warning on line 190 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L189-L190

Added lines #L189 - L190 were not covered by tests

return output

Check warning on line 192 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L192

Added line #L192 was not covered by tests


def mkdir(target: str, hsi_flags: str = "", mkdir_flags: str = "") -> str:
""" Function to delete a file or directory on HPSS via hsi

Parameters
----------
target : str
Full path of the target location of the file on HPSS.

hsi_flags : str
String of flags to send to hsi.

mkdir_flags : str
Flags to send to mkdir (-p is assumed).
See "hsi mkdir -?" for more details.
"""

args = []

Check warning on line 211 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L211

Added line #L211 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 215 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L215

Added line #L215 was not covered by tests

args.extend(["mkdir", "-p"])

Check warning on line 217 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L217

Added line #L217 was not covered by tests

if len(mkdir_flags) > 0:
args.extend(mkdir_flags.split(" "))

Check warning on line 220 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L220

Added line #L220 was not covered by tests

args.append(target)
output = hsi(*args)

Check warning on line 223 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L222-L223

Added lines #L222 - L223 were not covered by tests

return output

Check warning on line 225 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L225

Added line #L225 was not covered by tests


def ls(target: str, hsi_flags: str = "", ls_flags: str = "") -> str:
""" Function to list files/directories on HPSS via hsi

Parameters
----------
target : str
Full path of the target location on HPSS.

hsi_flags : str
String of flags to send to hsi.

ls_flags : str
Flags to send to ls. See "hsi ls -?" for more details.
"""

args = []

Check warning on line 243 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L243

Added line #L243 was not covered by tests

# Parse any hsi flags
if len(hsi_flags) > 0:
args.extend(hsi_flags.split(" "))

Check warning on line 247 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L247

Added line #L247 was not covered by tests

args.append("ls")

Check warning on line 249 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L249

Added line #L249 was not covered by tests

if len(ls_flags) > 0:
args.extend(ls_flags.split(" "))

Check warning on line 252 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L252

Added line #L252 was not covered by tests

args.append(target)
output = hsi(*args)

Check warning on line 255 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L254-L255

Added lines #L254 - L255 were not covered by tests

return output

Check warning on line 257 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L257

Added line #L257 was not covered by tests


def exists(target: str) -> bool:
""" Function to test the existence of a file/directory/glob on HPSS

Parameters
----------
target : str
Full path of the target location on HPSS.

Return: bool
True if the target exists on HPSS.
"""

cmd = which("hsi", required=True)

Check warning on line 272 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L272

Added line #L272 was not covered by tests

for arg in ["ls", target]:
cmd.add_default_arg(arg)

Check warning on line 275 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L275

Added line #L275 was not covered by tests

# Do not exit if the file is not found; do not pipe output to stdout
output = cmd(output=str, error=str, ignore_errors=[64])

Check warning on line 278 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L278

Added line #L278 was not covered by tests

if "HPSS_ENOENT" in output:
return False

Check warning on line 281 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L281

Added line #L281 was not covered by tests
# Catch wildcards
elif f"Warning: No matching names located for '{target}'" in output:
return False

Check warning on line 284 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L284

Added line #L284 was not covered by tests
else:
return True

Check warning on line 286 in src/wxflow/hsi.py

View check run for this annotation

Codecov / codecov/patch

src/wxflow/hsi.py#L286

Added line #L286 was not covered by tests
Loading