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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The client here will eventually be released as "spython" (and eventually to
singularity on pypi), and the versions here will coincide with these releases.

## [master](https://github.com/singularityhub/singularity-cli/tree/master)
- support for background process with client run (0.2.11)
- parser bugfixes, arg from Docker not properly parsed (0.2.1)
- version checks removed to support Singularity 3.x and above (0.2.0)
- adding support for SIF (oras pull) (0.1.18)
Expand Down
19 changes: 14 additions & 5 deletions spython/main/base/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@


def init_command(self, action, flags=None):
"""return the initial Singularity command with any added flags.
"""
Return the initial Singularity command with any added flags.

Parameters
==========
Expand All @@ -37,7 +38,8 @@ def init_command(self, action, flags=None):


def generate_bind_list(self, bindlist=None):
"""generate bind string will take a single string or list of binds, and
"""
Generate bind string will take a single string or list of binds, and
return a list that can be added to an exec or run command. For example,
the following map as follows:

Expand Down Expand Up @@ -81,7 +83,8 @@ def generate_bind_list(self, bindlist=None):


def send_command(self, cmd, sudo=False, stderr=None, stdout=None):
"""send command is a non interactive version of run_command, meaning
"""
Send command is a non interactive version of run_command, meaning
that we execute the command and return the return value, but don't
attempt to stream any content (text from the screen) back to the
user. This is useful for commands interacting with OCI bundles.
Expand Down Expand Up @@ -109,9 +112,11 @@ def run_command(
return_result=False,
sudo_options=None,
environ=None,
background=False,
):

"""run_command is a wrapper for the global run_command, checking first
"""
Run_command is a wrapper for the global run_command, checking first
for sudo and exiting on error if needed. The message is returned as
a list of lines for the calling function to parse, and stdout uses
the parent process so it appears for the user.
Expand All @@ -124,7 +129,7 @@ def run_command(
return_result: return the result, if not successful (default False).
sudo_options: string or list of strings that will be passed as options to sudo
On success, returns result.

background: run the instance in the background (just Popen)
"""
# First preference to function, then to client setting
if quiet is None:
Expand All @@ -137,8 +142,12 @@ def run_command(
quiet=quiet,
sudo_options=sudo_options,
environ=environ,
background=background,
)

if background:
return

# If one line is returned, squash dimension
if len(result["message"]) == 1:
result["message"] = result["message"][0]
Expand Down
6 changes: 4 additions & 2 deletions spython/main/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def list_instances(
sudo_options=None,
singularity_options=None,
):
"""list instances. For Singularity, this is provided as a command sub
"""
List instances. For Singularity, this is provided as a command sub
group.

singularity instance list
Expand Down Expand Up @@ -106,7 +107,8 @@ def list_instances(


def stopall(self, sudo=False, quiet=True, singularity_options=None):
"""stop ALL instances. This command is only added to the command group
"""
Stop ALL instances. This command is only added to the command group
as it doesn't make sense to call from a single instance

Parameters
Expand Down
6 changes: 5 additions & 1 deletion spython/main/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def run(
singularity_options=None,
return_result=False,
quiet=False,
background=False,
):
"""
run will run the container, with or withour arguments (which
Expand Down Expand Up @@ -100,7 +101,10 @@ def run(
if not quiet:
bot.info(" ".join(cmd))

if not stream:
if background:
return self._run_command(cmd, sudo=sudo, background=True)

elif not stream:
result = self._run_command(cmd, sudo=sudo, return_result=return_result)
else:
return stream_command(cmd, sudo=sudo)
Expand Down
50 changes: 36 additions & 14 deletions spython/utils/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ def _process_sudo_cmd(cmd, sudo, sudo_options):
if sudo and sudo_options is not None:
if isinstance(sudo_options, str):
sudo_options = shlex.split(sudo_options)
cmd = ["sudo"] + sudo_options + cmd
cmd = ["sudo", "-E"] + sudo_options + cmd
elif sudo:
cmd = ["sudo"] + cmd
return cmd
cmd = ["sudo", "-E"] + cmd
return [x for x in cmd if x]


def check_install(software="singularity", quiet=True):
"""check_install will attempt to run the singularity command, and
"""
check_install will attempt to run the singularity command, and
return True if installed. The command line utils will not run
without this check.
"""
Expand Down Expand Up @@ -66,7 +67,8 @@ def which(software="singularity"):


def get_singularity_version():
"""get the full singularity client version as reported by
"""
get the full singularity client version as reported by
singularity --version [...]. For Singularity 3.x, this means:
"singularity version 3.0.1-1"
"""
Expand All @@ -85,17 +87,23 @@ def get_singularity_version():


def get_userhome():
"""get the user home based on the effective uid"""
"""
Get the user home based on the effective uid
"""
return pwd.getpwuid(os.getuid())[5]


def get_username():
"""get the user name based on the effective uid"""
"""
Get the user name based on the effective uid
"""
return pwd.getpwuid(os.getuid())[0]


def get_singularity_version_info():
"""get the full singularity client version as a semantic version" """
"""
Get the full singularity client version as a semantic version"
"""
version_string = get_singularity_version()
prefix = "singularity version "
if version_string.startswith(prefix):
Expand All @@ -106,7 +114,9 @@ def get_singularity_version_info():


def get_installdir():
"""get_installdir returns the installation directory of the application"""
"""
Get_installdir returns the installation directory of the application
"""
return os.path.abspath(os.path.dirname(os.path.dirname(__file__)))


Expand All @@ -117,7 +127,8 @@ def stream_command(
sudo_options=None,
output_type="stdout",
):
"""stream a command (yield) back to the user, as each line is available.
"""
Stream a command (yield) back to the user, as each line is available.

# Example usage:
results = []
Expand Down Expand Up @@ -167,9 +178,11 @@ def run_command(
quiet=False,
sudo_options=None,
environ=None,
background=False,
):

"""run_command uses subprocess to send a command to the terminal. If
"""
run_command uses subprocess to send a command to the terminal. If
capture is True, we use the parent stdout, so the progress bar (and
other commands of interest) are piped to the user. This means we
don't return the output to parse.
Expand All @@ -184,6 +197,7 @@ def run_command(
option can print a progress bar, but won't return the lines
as output.
sudo_options: string or list of strings that will be passed as options to sudo
background: run in background and don't try to get output.
"""
cmd = _process_sudo_cmd(cmd, sudo, sudo_options)

Expand All @@ -192,8 +206,12 @@ def run_command(
stdout = subprocess.PIPE

# Use the parent stdout and stderr
if background:
subprocess.Popen(cmd, env=environ)
return

process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=stdout, env=environ)

lines = []
found_match = False

Expand Down Expand Up @@ -222,7 +240,8 @@ def run_command(


def format_container_name(name, special_characters=None):
"""format_container_name will take a name supplied by the user,
"""
format_container_name will take a name supplied by the user,
remove all special characters (except for those defined by "special-characters"
and return the new image name.
"""
Expand All @@ -232,7 +251,8 @@ def format_container_name(name, special_characters=None):


def split_uri(container):
"""Split the uri of a container into the protocol and image part
"""
Split the uri of a container into the protocol and image part

An empty protocol is returned if none found.
A trailing slash is removed from the image part.
Expand All @@ -247,5 +267,7 @@ def split_uri(container):


def remove_uri(container):
"""remove_uri will remove docker:// or shub:// or library:// from the uri"""
"""
remove_uri will remove docker:// or shub:// or library:// from the uri
"""
return split_uri(container)[1]
2 changes: 1 addition & 1 deletion spython/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.


__version__ = "0.2.1"
__version__ = "0.2.11"
AUTHOR = "Vanessa Sochat"
AUTHOR_EMAIL = "vsoch@users.noreply.github.com"
NAME = "spython"
Expand Down