From 34e1ba09c334e734df8cf0104dc009514a02d21e Mon Sep 17 00:00:00 2001 From: Tom Schoonjans Date: Fri, 28 Jun 2019 14:18:19 +0100 Subject: [PATCH 1/2] spython.main.Client.build: add sudo_options option This allows me to pass '--preserve-env=SINGULARITY_CACHEDIR,SINGULARITY_TMPDIR' to sudo, which I need to deal with my very small /root and /tmp partitions. --- spython/main/base/command.py | 6 ++++-- spython/main/build.py | 7 +++++-- spython/utils/terminal.py | 24 +++++++++++++++++------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/spython/main/base/command.py b/spython/main/base/command.py index b367b6b3..451c4136 100644 --- a/spython/main/base/command.py +++ b/spython/main/base/command.py @@ -106,7 +106,8 @@ def run_command(self, cmd, sudo=False, capture=True, quiet=None, - return_result=False): + return_result=False, + sudo_options=None): '''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 @@ -119,6 +120,7 @@ def run_command(self, cmd, sudo: does the command require sudo? quiet: if quiet set by function, overrides client setting. 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. ''' @@ -126,7 +128,7 @@ def run_command(self, cmd, if quiet is None: quiet = self.quiet - result = run_cmd(cmd, sudo=sudo, capture=capture, quiet=quiet) + result = run_cmd(cmd, sudo=sudo, capture=capture, quiet=quiet, sudo_options=sudo_options) # If one line is returned, squash dimension if len(result['message']) == 1: diff --git a/spython/main/build.py b/spython/main/build.py index 877ea96b..b3fd0a71 100644 --- a/spython/main/build.py +++ b/spython/main/build.py @@ -24,7 +24,8 @@ def build(self, recipe=None, force=False, options=None, quiet=False, - return_result=False): + return_result=False, + sudo_options=None): '''build a singularity image, optionally for an isolated build (requires sudo). If you specify to stream, expect the image name @@ -47,6 +48,7 @@ def build(self, recipe=None, name (with "image") then a fun robot name will be generated instead. Highly recommended :) sudo: give sudo to the command (or not) default is True for build + sudo_options: options to pass to sudo (e.g. --preserve-env=SINGULARITY_CACHEDIR,SINGULARITY_TMPDIR) options: for all other options, specify them in this list. quiet: quiet verbose printing from the client. return_result: if True, return complete error code / message dictionary @@ -105,6 +107,7 @@ def build(self, recipe=None, if not stream: self._run_command(cmd, sudo=sudo, + sudo_options=sudo_options, quiet=quiet, return_result=return_result, capture=False) @@ -112,7 +115,7 @@ def build(self, recipe=None, else: # Here we return the expected image, and an iterator! # The caller must iterate over - return image, stream_command(cmd, sudo=sudo) + return image, stream_command(cmd, sudo=sudo, sudo_options=sudo_options) if os.path.exists(image): return image diff --git a/spython/utils/terminal.py b/spython/utils/terminal.py index 40a4b19f..c76a960e 100644 --- a/spython/utils/terminal.py +++ b/spython/utils/terminal.py @@ -15,11 +15,21 @@ from spython.logger import decodeUtf8String import subprocess import sys +import shlex ################################################################################ # Local commands and requests ################################################################################ +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 + elif sudo: + cmd = ['sudo'] + cmd + return cmd + def check_install(software='singularity', quiet=True): '''check_install will attempt to run the singularity command, and @@ -89,7 +99,7 @@ def get_installdir(): return os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -def stream_command(cmd, no_newline_regexp="Progess", sudo=False): +def stream_command(cmd, no_newline_regexp="Progess", sudo=False, sudo_options=None): '''stream a command (yield) back to the user, as each line is available. # Example usage: @@ -103,10 +113,10 @@ def stream_command(cmd, no_newline_regexp="Progess", sudo=False): cmd: the command to send, should be a list for subprocess no_newline_regexp: the regular expression to determine skipping a newline. Defaults to finding Progress + sudo_options: string or list of strings that will be passed as options to sudo ''' - if sudo: - cmd = ['sudo'] + cmd + cmd = _process_sudo_cmd(cmd, sudo, sudo_options) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, @@ -124,7 +134,8 @@ def run_command(cmd, sudo=False, capture=True, no_newline_regexp="Progess", - quiet=False): + quiet=False, + sudo_options=None): '''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 @@ -140,10 +151,9 @@ def run_command(cmd, capture: if True, don't set stdout and have it go to console. This 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 ''' - - if sudo: - cmd = ['sudo'] + cmd + cmd = _process_sudo_cmd(cmd, sudo, sudo_options) stdout = None if capture: From 86eb56d2a322056d6a66e7c6f28121b2a17af6ed Mon Sep 17 00:00:00 2001 From: Tom Schoonjans Date: Fri, 28 Jun 2019 14:43:28 +0100 Subject: [PATCH 2/2] Update Changelog and bump version --- CHANGELOG.md | 1 + spython/version.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdfff161..af331fc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) + - add sudo_options option to spython.main.Client.build (0.0.73) - list of options and writable added to shell, execute, and run (0.0.72) - client is not honoring quiet for pull (0.0.71) - removing debugging line in pull (0.0.70) diff --git a/spython/version.py b/spython/version.py index 5e0fb736..59db0d50 100644 --- a/spython/version.py +++ b/spython/version.py @@ -6,7 +6,7 @@ # with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -__version__ = "0.0.72" +__version__ = "0.0.73" AUTHOR = 'Vanessa Sochat' AUTHOR_EMAIL = 'vsochat@stanford.edu' NAME = 'spython'