Skip to content

Commit 2807c03

Browse files
authored
preparing to add support for background run (#196)
* preparing to add support for background run Signed-off-by: vsoch <[email protected]>
1 parent 0433d28 commit 2807c03

File tree

6 files changed

+61
-23
lines changed

6 files changed

+61
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The client here will eventually be released as "spython" (and eventually to
1717
singularity on pypi), and the versions here will coincide with these releases.
1818

1919
## [master](https://github.com/singularityhub/singularity-cli/tree/master)
20+
- support for background process with client run (0.2.11)
2021
- parser bugfixes, arg from Docker not properly parsed (0.2.1)
2122
- version checks removed to support Singularity 3.x and above (0.2.0)
2223
- adding support for SIF (oras pull) (0.1.18)

spython/main/base/command.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616

1717
def init_command(self, action, flags=None):
18-
"""return the initial Singularity command with any added flags.
18+
"""
19+
Return the initial Singularity command with any added flags.
1920
2021
Parameters
2122
==========
@@ -37,7 +38,8 @@ def init_command(self, action, flags=None):
3738

3839

3940
def generate_bind_list(self, bindlist=None):
40-
"""generate bind string will take a single string or list of binds, and
41+
"""
42+
Generate bind string will take a single string or list of binds, and
4143
return a list that can be added to an exec or run command. For example,
4244
the following map as follows:
4345
@@ -81,7 +83,8 @@ def generate_bind_list(self, bindlist=None):
8183

8284

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

114-
"""run_command is a wrapper for the global run_command, checking first
118+
"""
119+
Run_command is a wrapper for the global run_command, checking first
115120
for sudo and exiting on error if needed. The message is returned as
116121
a list of lines for the calling function to parse, and stdout uses
117122
the parent process so it appears for the user.
@@ -124,7 +129,7 @@ def run_command(
124129
return_result: return the result, if not successful (default False).
125130
sudo_options: string or list of strings that will be passed as options to sudo
126131
On success, returns result.
127-
132+
background: run the instance in the background (just Popen)
128133
"""
129134
# First preference to function, then to client setting
130135
if quiet is None:
@@ -137,8 +142,12 @@ def run_command(
137142
quiet=quiet,
138143
sudo_options=sudo_options,
139144
environ=environ,
145+
background=background,
140146
)
141147

148+
if background:
149+
return
150+
142151
# If one line is returned, squash dimension
143152
if len(result["message"]) == 1:
144153
result["message"] = result["message"][0]

spython/main/instances.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ def list_instances(
1919
sudo_options=None,
2020
singularity_options=None,
2121
):
22-
"""list instances. For Singularity, this is provided as a command sub
22+
"""
23+
List instances. For Singularity, this is provided as a command sub
2324
group.
2425
2526
singularity instance list
@@ -106,7 +107,8 @@ def list_instances(
106107

107108

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

spython/main/run.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def run(
2525
singularity_options=None,
2626
return_result=False,
2727
quiet=False,
28+
background=False,
2829
):
2930
"""
3031
run will run the container, with or withour arguments (which
@@ -100,7 +101,10 @@ def run(
100101
if not quiet:
101102
bot.info(" ".join(cmd))
102103

103-
if not stream:
104+
if background:
105+
return self._run_command(cmd, sudo=sudo, background=True)
106+
107+
elif not stream:
104108
result = self._run_command(cmd, sudo=sudo, return_result=return_result)
105109
else:
106110
return stream_command(cmd, sudo=sudo)

spython/utils/terminal.py

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ def _process_sudo_cmd(cmd, sudo, sudo_options):
2727
if sudo and sudo_options is not None:
2828
if isinstance(sudo_options, str):
2929
sudo_options = shlex.split(sudo_options)
30-
cmd = ["sudo"] + sudo_options + cmd
30+
cmd = ["sudo", "-E"] + sudo_options + cmd
3131
elif sudo:
32-
cmd = ["sudo"] + cmd
33-
return cmd
32+
cmd = ["sudo", "-E"] + cmd
33+
return [x for x in cmd if x]
3434

3535

3636
def check_install(software="singularity", quiet=True):
37-
"""check_install will attempt to run the singularity command, and
37+
"""
38+
check_install will attempt to run the singularity command, and
3839
return True if installed. The command line utils will not run
3940
without this check.
4041
"""
@@ -66,7 +67,8 @@ def which(software="singularity"):
6667

6768

6869
def get_singularity_version():
69-
"""get the full singularity client version as reported by
70+
"""
71+
get the full singularity client version as reported by
7072
singularity --version [...]. For Singularity 3.x, this means:
7173
"singularity version 3.0.1-1"
7274
"""
@@ -85,17 +87,23 @@ def get_singularity_version():
8587

8688

8789
def get_userhome():
88-
"""get the user home based on the effective uid"""
90+
"""
91+
Get the user home based on the effective uid
92+
"""
8993
return pwd.getpwuid(os.getuid())[5]
9094

9195

9296
def get_username():
93-
"""get the user name based on the effective uid"""
97+
"""
98+
Get the user name based on the effective uid
99+
"""
94100
return pwd.getpwuid(os.getuid())[0]
95101

96102

97103
def get_singularity_version_info():
98-
"""get the full singularity client version as a semantic version" """
104+
"""
105+
Get the full singularity client version as a semantic version"
106+
"""
99107
version_string = get_singularity_version()
100108
prefix = "singularity version "
101109
if version_string.startswith(prefix):
@@ -106,7 +114,9 @@ def get_singularity_version_info():
106114

107115

108116
def get_installdir():
109-
"""get_installdir returns the installation directory of the application"""
117+
"""
118+
Get_installdir returns the installation directory of the application
119+
"""
110120
return os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
111121

112122

@@ -117,7 +127,8 @@ def stream_command(
117127
sudo_options=None,
118128
output_type="stdout",
119129
):
120-
"""stream a command (yield) back to the user, as each line is available.
130+
"""
131+
Stream a command (yield) back to the user, as each line is available.
121132
122133
# Example usage:
123134
results = []
@@ -167,9 +178,11 @@ def run_command(
167178
quiet=False,
168179
sudo_options=None,
169180
environ=None,
181+
background=False,
170182
):
171183

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

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

194208
# Use the parent stdout and stderr
209+
if background:
210+
subprocess.Popen(cmd, env=environ)
211+
return
195212

196213
process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=stdout, env=environ)
214+
197215
lines = []
198216
found_match = False
199217

@@ -222,7 +240,8 @@ def run_command(
222240

223241

224242
def format_container_name(name, special_characters=None):
225-
"""format_container_name will take a name supplied by the user,
243+
"""
244+
format_container_name will take a name supplied by the user,
226245
remove all special characters (except for those defined by "special-characters"
227246
and return the new image name.
228247
"""
@@ -232,7 +251,8 @@ def format_container_name(name, special_characters=None):
232251

233252

234253
def split_uri(container):
235-
"""Split the uri of a container into the protocol and image part
254+
"""
255+
Split the uri of a container into the protocol and image part
236256
237257
An empty protocol is returned if none found.
238258
A trailing slash is removed from the image part.
@@ -247,5 +267,7 @@ def split_uri(container):
247267

248268

249269
def remove_uri(container):
250-
"""remove_uri will remove docker:// or shub:// or library:// from the uri"""
270+
"""
271+
remove_uri will remove docker:// or shub:// or library:// from the uri
272+
"""
251273
return split_uri(container)[1]

spython/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
66

77

8-
__version__ = "0.2.1"
8+
__version__ = "0.2.11"
99
AUTHOR = "Vanessa Sochat"
1010
AUTHOR_EMAIL = "[email protected]"
1111
NAME = "spython"

0 commit comments

Comments
 (0)