Skip to content

Commit 34b7e41

Browse files
authored
Merge pull request #18 from singularityhub/add/run
adding run command
2 parents 08a0598 + a7d32f5 commit 34b7e41

File tree

6 files changed

+109
-19
lines changed

6 files changed

+109
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
1414
The versions coincide with releases on pypi.
1515

1616
## [0.0.x](https://github.com/singularityhub/singularity-compose/tree/master) (0.0.x)
17+
- adding run command (0.0.15)
1718
- ensuring that builds are streamed (0.0.14)
1819
- adding more build options to build as build-flags (0.0.13)
1920
- when not using sudo, need to set --network=none, and catching exec error (0.0.12)

docs/commands.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,19 @@ usr
9494
var
9595
```
9696

97+
## Run
98+
99+
If a container has a `%runscript` section (or a Docker entrypoint/cmd that
100+
was converted to one), you can run that script easily:
101+
102+
```bash
103+
$ singularity-compose run app
104+
```
105+
106+
If your container didn't have any kind of runscript, the startscript
107+
will be used instead.
108+
109+
97110
## Down
98111

99112
You can bring one or more instances down (meaning, stopping them) by doing:

scompose/client/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def get_parser():
109109
execute = subparsers.add_parser("exec",
110110
help="execute a command to an instance")
111111

112+
run = subparsers.add_parser("run",
113+
help="run an instance runscript.")
114+
112115
shell = subparsers.add_parser("shell",
113116
help="shell into an instance")
114117

@@ -134,7 +137,7 @@ def get_parser():
134137
help='the names of the instances to target')
135138

136139
# Only one name allowed
137-
for sub in [shell, execute]:
140+
for sub in [shell, execute, run]:
138141
sub.add_argument('name', nargs=1,
139142
help='the name of the instance to target')
140143

@@ -195,6 +198,8 @@ def show_help(return_code=0):
195198
from .ps import main
196199
elif args.command == "restart":
197200
from .restart import main
201+
elif args.command == "run":
202+
from .run import main
198203
elif args.command == "shell":
199204
from .shell import main
200205
elif args.command == "up":

scompose/client/run.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'''
2+
3+
Copyright (C) 2019 Vanessa Sochat.
4+
5+
This program is free software: you can redistribute it and/or modify it
6+
under the terms of the GNU Affero General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or (at your
8+
option) any later version.
9+
10+
This program is distributed in the hope that it will be useful, but WITHOUT
11+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
13+
License for more details.
14+
15+
You should have received a copy of the GNU Affero General Public License
16+
along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
'''
19+
20+
from scompose.project import Project
21+
22+
def main(args, parser, extra):
23+
'''execute a command to an instance.
24+
'''
25+
# Initialize the project
26+
project = Project(filename=args.file,
27+
name=args.project_name,
28+
env_file=args.env_file)
29+
30+
project.run(args.name[0])

scompose/project/project.py

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,22 @@ def iter_instances(self, names):
129129
yield self.instances.get(name)
130130

131131

132+
def get_instance(self, name):
133+
'''get a specifically named instance. We first check that the
134+
client has instances defined, and that the name we are looking
135+
for is also included. If not found, we return None.
136+
137+
Parameters
138+
==========
139+
names: the name of instances to get. Must be valid
140+
'''
141+
instance = None
142+
if self.instances:
143+
if name in self.instances:
144+
instance = self.instances[name]
145+
return instance
146+
147+
132148
# Loading Functions
133149

134150
def load(self):
@@ -249,11 +265,34 @@ def shell(self, name):
249265
==========
250266
name: the name of the instance to shell into
251267
'''
252-
if self.instances:
253-
if name in self.instances:
254-
instance = self.instances[name]
255-
if instance.exists():
256-
self.client.shell(instance.instance.get_uri(), sudo=self.sudo)
268+
instance = self.get_instance(name)
269+
if not instance:
270+
bot.exit('Cannot find %s, is it up?' % name)
271+
272+
if instance.exists():
273+
self.client.shell(instance.instance.get_uri(), sudo=self.sudo)
274+
275+
276+
def run(self, name):
277+
'''if an instance exists, run it.
278+
279+
Parameters
280+
==========
281+
name: the name of the instance to run
282+
'''
283+
instance = self.get_instance(name)
284+
if not instance:
285+
bot.exit('Cannot find %s, is it up?' % name)
286+
287+
if instance.exists():
288+
self.client.quiet = True
289+
result = self.client.run(instance.instance.get_uri(),
290+
sudo=self.sudo,
291+
return_result=True)
292+
293+
if result['return_code'] != 0:
294+
bot.exit("Return code %s" % result['return_code'])
295+
print(''.join([x for x in result['message'] if x]))
257296

258297

259298
def execute(self, name, commands):
@@ -264,18 +303,20 @@ def execute(self, name, commands):
264303
name: the name of the instance to exec to
265304
commands: a list of commands to issue
266305
'''
267-
if self.instances:
268-
if name in self.instances:
269-
instance = self.instances[name]
270-
if instance.exists():
271-
try:
272-
for line in self.client.execute(instance.instance.get_uri(),
273-
command=commands,
274-
stream=True,
275-
sudo=self.sudo):
276-
print(line, end='')
277-
except subprocess.CalledProcessError:
278-
bot.exit('Command had non zero exit status.')
306+
instance = self.get_instance(name)
307+
if not instance:
308+
bot.exit('Cannot find %s, is it up?' % name)
309+
310+
if instance.exists():
311+
try:
312+
for line in self.client.execute(instance.instance.get_uri(),
313+
command=commands,
314+
stream=True,
315+
sudo=self.sudo):
316+
print(line, end='')
317+
except subprocess.CalledProcessError:
318+
bot.exit('Command had non zero exit status.')
319+
279320

280321
# Logs
281322

scompose/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
1818
'''
1919

20-
__version__ = "0.0.14"
20+
__version__ = "0.0.15"
2121
AUTHOR = 'Vanessa Sochat'
2222
AUTHOR_EMAIL = '[email protected]'
2323
NAME = 'singularity-compose'

0 commit comments

Comments
 (0)