Skip to content

Commit 7f61353

Browse files
committed
adding work for today, still needs fixing up of tests
1 parent 1a4a940 commit 7f61353

File tree

13 files changed

+158
-26
lines changed

13 files changed

+158
-26
lines changed

spython/image/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ def remove_uri(self, image):
5656
image = image or ''
5757
uri = self.get_uri(image) or ''
5858
image = image.replace('%s://' %uri,'', 1)
59-
print(image)
6059
return image.strip('-').strip('/')
6160

6261

spython/instance/__init__.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818

1919
from spython.image import ImageBase
20+
import os
2021

2122
class Instance(ImageBase):
2223

@@ -33,9 +34,66 @@ def __init__(self, image, start=True, **kwargs):
3334
'''
3435
super(ImageBase, self).__init__()
3536
self.parse_image_name(image)
36-
self.status = 'stopped'
37+
38+
# Update metadats from arguments
39+
self._update_metadata(kwargs)
40+
self.options = []
41+
self.cmd = []
3742

3843
# Start the instance
3944
if start is True:
40-
self.start(**kwargs)
45+
self._start(**kwargs)
46+
47+
# Unique resource identifier
48+
49+
def parse_image_name(self, image):
50+
'''
51+
simply split the uri from the image. Singularity handles
52+
parsing of registry, namespace, image.
53+
54+
Parameters
55+
==========
56+
image: the complete image uri to load (e.g., docker://ubuntu)
57+
58+
'''
59+
self._image = image
60+
self.uri = 'instance://'
61+
62+
63+
def get_uri(self):
64+
'''return the image uri (instance://) along with it's name
65+
'''
66+
return self.__str__()
67+
68+
# Metadata
69+
70+
def _update_metadata(self, kwargs=None):
71+
'''Extract any additional attributes to hold with the instance
72+
from kwargs
73+
'''
74+
75+
# If not given metadata, use instance.list to get it for container
76+
if kwargs is None:
77+
kwargs = self._list(self.name, quiet=True, return_json=True)
78+
79+
# Add acceptable arguments
80+
for arg in ['pid', 'name']:
81+
82+
# Skip over non-iterables:
83+
if arg in kwargs:
84+
setattr(self, arg, kwargs[arg])
85+
86+
if "image" in kwargs:
87+
self._image = kwargs['image']
88+
elif "container_image" in kwargs:
89+
self._image = kwargs['container_image']
90+
91+
92+
def __str__(self):
93+
if hasattr(self, 'uri'):
94+
if self.uri:
95+
return "%s%s" %(self.uri, self.name)
96+
return os.path.basename(self._image)
4197

98+
def __repr__(self):
99+
return self.__str__()

spython/main/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def get_client(quiet=False, debug=False):
3939
from .execute import execute
4040
from .help import help
4141
from .inspect import inspect
42-
from .instances import instances
42+
from .instances import ( instances, stopall ) # global instance commands
4343
from .run import run
4444
from .pull import pull
4545

@@ -53,12 +53,16 @@ def get_client(quiet=False, debug=False):
5353
Client.run = run
5454
Client.pull = pull
5555

56-
# Command Groups
56+
# Command Groups, Images
5757
from spython.image.cmd import image_group # deprecated image commands
58-
from spython.instance.cmd import instance_group # returns Instance objects
5958
Client.image = image_group
60-
Client.image.check_install = Client.check_install
59+
Client.image._check_install = Client._check_install
60+
61+
# Commands Groups, Instances
62+
from spython.instance.cmd import instance_group # instance level commands
6163
Client.instance = instance_group
64+
Client.instance._check_install = Client._check_install
65+
Client.instance_stopall = stopall
6266

6367
# Initialize
6468
cli = Client()

spython/main/apps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def apps(self, image=None, full_path=False, root=''):
3232
image_path: full path to the image
3333
3434
'''
35-
self.check_install()
35+
self._check_install()
3636

3737
# No image provided, default to use the client's loaded image
3838
if image is None:

spython/main/base/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def version(self):
6565
return version
6666

6767

68-
def check_install(self):
68+
def _check_install(self):
6969
'''ensure that singularity is installed, and exit if not.
7070
'''
7171
if check_install() is not True:

spython/main/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def build(self, recipe=None,
5656
sudo: give sudo to the command (or not) default is True for build
5757
5858
'''
59-
self.check_install()
59+
self._check_install()
6060
cmd = self._init_command('build')
6161

6262
# No image provided, default to use the client's loaded image

spython/main/execute.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ def execute(self,
4848
directories within your container using bind mounts
4949
5050
'''
51-
5251
cmd = self._init_command('exec')
53-
self.check_install()
52+
self._check_install()
5453

5554
# If the image is given as a list, it's probably the command
5655
if isinstance(image, list):
@@ -62,6 +61,11 @@ def execute(self,
6261
# No image provided, default to use the client's loaded image
6362
if image is None:
6463
image = self._get_uri()
64+
self.quiet = True
65+
66+
# If an instance is provided, grab it's name
67+
if isinstance(image, self.instance):
68+
image = image.get_uri()
6569

6670
# Does the user want to use bind paths option?
6771
if bind is not None:

spython/main/help.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def help(self, command=None):
3333
command: the command to get help for, if none, prints general help
3434
3535
'''
36-
self.check_install()
36+
self._check_install()
3737

3838
cmd = ['singularity','--help']
3939
if command != None:

spython/main/inspect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def inspect(self,image=None, json=True, app=None):
3030
app: if defined, return help in context of an app
3131
3232
'''
33-
self.check_install()
33+
self._check_install()
3434

3535
# No image provided, default to use the client's loaded image
3636
if image is None:

spython/main/instances.py

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818

1919

2020
from spython.logger import bot
21-
from spython.utils import run_command
21+
from spython.utils import run_command, check_install
2222

23-
24-
def instances(self):
23+
def instances(self, name=None, return_json=False, quiet=False):
2524
'''list instances. For Singularity, this is provided as a command sub
2625
group.
2726
@@ -30,33 +29,92 @@ def instances(self):
3029
Return codes provided are different from standard linux:
3130
see https://github.com/singularityware/singularity/issues/1706
3231
32+
Parameters
33+
==========
34+
return_json: return a json list of instances instead of objects (False)
35+
name: if defined, return the list for just one instance (used to ged pid)
36+
3337
Return Code -- Reason
3438
0 -- Instances Found
3539
1 -- No Instances, libexecdir value not found, functions file not found
3640
255 -- Couldn't get UID
3741
3842
'''
43+
from spython.instance.cmd.iutils import parse_table
44+
self._check_install()
45+
cmd = self._init_command('instance.list')
3946

40-
self.check_install()
47+
# If the user has provided a name, we want to see a particular instance
48+
if name is not None:
49+
cmd.append(name)
4150

42-
cmd = self._init_command('instance.list')
4351
output = run_command(cmd, quiet=True)
4452
instances = None
4553

4654
# Success, we have instances
4755

4856
if output['return_code'] == 0:
49-
print(''.join(output['message']))
50-
instances = output['message'][1:]
57+
58+
# Only print the table if we are returning json
59+
if quiet is False:
60+
print(''.join(output['message']))
61+
62+
# Prepare json result from table
63+
64+
header = ['daemon_name','pid','container_image']
65+
instances = parse_table(output['message'][0], header)
66+
67+
# Does the user want instance objects instead?
68+
listing = []
69+
if return_json is False:
70+
for i in instances:
71+
72+
new_instance = self.instance(pid=i['pid'],
73+
name=i['daemon_name'],
74+
image=i['container_image'],
75+
start=False)
76+
77+
listing.append(new_instance)
78+
instances = listing
5179

5280
# Couldn't get UID
5381

5482
elif output['return_code'] == 255:
5583
bot.error("Couldn't get UID")
5684

57-
5885
# Return code of 0
5986
else:
6087
bot.info('No instances found.')
6188

89+
# If we are given a name, return just one
90+
if name is not None and instances is not None:
91+
if len(instances) == 1:
92+
instances = instances[0]
93+
6294
return instances
95+
96+
97+
def stopall(self, sudo=False, quiet=True):
98+
'''stop ALL instances. This command is only added to the command group
99+
as it doesn't make sense to call from a single instance
100+
101+
Parameters
102+
==========
103+
sudo: if the command should be done with sudo (exposes different set of
104+
instances)
105+
106+
'''
107+
from spython.utils import run_command, check_install
108+
check_install()
109+
110+
cmd = self._init_command('instance.stop')
111+
cmd = cmd + ['--all']
112+
output = run_command(cmd, sudo=sudo, quiet=quiet)
113+
114+
if output['return_code'] != 0:
115+
message = '%s : return code %s' %(output['message'],
116+
output['return_code'])
117+
bot.error(message)
118+
return output['return_code']
119+
120+
return output['return_code']

0 commit comments

Comments
 (0)