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)
- adding support for instance list (0.0.47)
- ENV variables in Dockerfile can be empty (like unsetting) (0.0.46)
- COPY can handle multiple sources to one destination for Dockerfile parser (0.0.45)
- Adding DockerRecipe, SingularityRecipe "load" action to load file
Expand Down
17 changes: 17 additions & 0 deletions docs/pages/commands-instances.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This section will discuss interaction with container instances, which generally
includes starting, stopping and running. From within python, you can instantiate
an sphython client, and then use the following functions to control an Instance:

- [version](#singularity-version): control the instance command subgroup
- [Shell](#shell) gives you an interactive python shell with a client
- [Start](#create-an-instance) create a Singularity instance!
- [Commands](#commands) how to interact with your instance (run, exec)
Expand All @@ -23,6 +24,22 @@ have created, you can find based on the name (shown later in the documentation).

<hr>

## Singularity Version
After Singularity 3.0, the instances command subgroup changed so that the original
call to interact with instances might have looked like "instances.list". After 3.0,
the [instances subgroup](https://github.com/sylabs/singularity/blob/master/CHANGELOG.md#v300---20181008)
changed to be of the format "instances list." Singularity Python determines this
automatically by looking at your Singularity version, however if you want to control
the final command that is used (for one reason or another) you can also export
the environment variable:

```bash
export SPYTHON_SINGULARITY_VERSION=2.6
```

Would change behavior of the client for Singularity instances. This currently
only has this changed behavior for the instances subgroup.

## Shell
All of the commands below start with creating an spython client:

Expand Down
2 changes: 0 additions & 2 deletions spython/image/cmd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,3 @@ class ImageClient(object):

cli = ImageClient()
return cli

image_group = generate_image_commands()
1 change: 0 additions & 1 deletion spython/instance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.


from spython.image import ImageBase
import os

Expand Down
2 changes: 0 additions & 2 deletions spython/instance/cmd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,3 @@ def generate_instance_commands():
Instance.instance = Instance

return Instance

instance_group = generate_instance_commands()
10 changes: 8 additions & 2 deletions spython/instance/cmd/iutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ def get(self, name, return_json=False, quiet=False):
'''get is a list for a single instance. It is assumed to be running,
and we need to look up the PID, etc.
'''
from spython.utils import check_install
from spython.utils import ( check_install, get_singularity_version )
check_install()

cmd = self._init_command('instance.list')
# Ensure compatible for singularity prior to 3.0, and after 3.0
subgroup = "instance.list"
if get_singularity_version().find("version 3"):
subgroup = ["instance", "list"]

cmd = self._init_command(subgroup)

cmd.append(name)
output = run_command(cmd, quiet=True)

Expand Down
11 changes: 9 additions & 2 deletions spython/instance/cmd/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ def start(self, image=None, name=None, sudo=False, options=[], capture=False):
singularity [...] instance.start [...] <container path> <instance name>

'''
from spython.utils import ( run_command, check_install )
from spython.utils import ( run_command,
check_install,
get_singularity_version )
check_install()

# If no name provided, give it an excellent one!
Expand All @@ -52,7 +54,12 @@ def start(self, image=None, name=None, sudo=False, options=[], capture=False):

image = self._image

cmd = self._init_command('instance.start')
# Derive subgroup command based on singularity version
subgroup = 'instance.start'
if get_singularity_version().find("version 3"):
subgroup = ["instance", "start"]

cmd = self._init_command(subgroup)

# Add options, if they are provided
if not isinstance(options, list):
Expand Down
10 changes: 8 additions & 2 deletions spython/instance/cmd/stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,16 @@ def stop(self, name=None, sudo=False):
singularity [...] instance.start [...] <container path> <instance name>

'''
from spython.utils import ( check_install, run_command )
from spython.utils import ( check_install,
run_command,
get_singularity_version )
check_install()

cmd = self._init_command('instance.stop')
subgroup = 'instance.stop'
if get_singularity_version().find("version 3"):
subgroup = ["instance", "stop"]

cmd = self._init_command(subgroup)

# If name is provided assume referencing an instance
instance_name = self.name
Expand Down
8 changes: 4 additions & 4 deletions spython/main/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ def get_client(quiet=False, debug=False):
Client.pull = pull

# Command Groups, Images
from spython.image.cmd import image_group # deprecated image commands
Client.image = image_group
from spython.image.cmd import generate_image_commands # deprecated
Client.image = generate_image_commands()

# Commands Groups, Instances
from spython.instance.cmd import instance_group # instance level commands
Client.instance = instance_group
from spython.instance.cmd import generate_instance_commands # instance level commands
Client.instance = generate_instance_commands()
Client.instance_stopall = stopall

# Initialize
Expand Down
19 changes: 9 additions & 10 deletions spython/main/base/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@


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
==========
action: the main action to perform (e.g., build)
flags: one or more additional flags (e.g, volumes)
not implemented yet.

Parameters
==========
action: the main action to perform (e.g., build)
flags: one or more additional flags (e.g, volumes)
not implemented yet.
'''

cmd = ['singularity', action ]
if not isinstance(action, list):
action = [action]
cmd = ['singularity'] + action

if self.quiet is True:
cmd.insert(1, '--quiet')
Expand Down Expand Up @@ -123,4 +123,3 @@ def run_command(self, cmd, sudo=False, capture=True):
if self.quiet is False:
bot.error("Return Code %s: %s" %(return_code,
message))

8 changes: 6 additions & 2 deletions spython/main/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


from spython.logger import bot
from spython.utils import run_command, check_install
from spython.utils import ( run_command, check_install, get_singularity_version )

def instances(self, name=None, return_json=False, quiet=False):
'''list instances. For Singularity, this is provided as a command sub
Expand All @@ -42,7 +42,11 @@ def instances(self, name=None, return_json=False, quiet=False):
from spython.utils import check_install
check_install()

cmd = self._init_command('instance.list')
subgroup = 'instance.list'
if get_singularity_version().find("version 3"):
subgroup = ["instance", "list"]

cmd = self._init_command(subgroup)

# If the user has provided a name, we want to see a particular instance
if name is not None:
Expand Down
11 changes: 11 additions & 0 deletions spython/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ def test_check_install(self):
self.assertTrue(not is_not_installed)


def test_check_get_singularity_version(self):
'''check that the singularity version is found to be that installed'''
print("Testing utils.get_singularity_version")
from spython.utils import get_singularity_version
version = get_singularity_version()
self.assertTrue(version != "")
os.environ['SPYTHON_SINGULARITY_VERSION'] = "3.0"
version = get_singularity_version()
self.assertTrue(version == "3.0")


def test_get_installdir(self):
'''get install directory should return the base of where singularity
is installed
Expand Down
1 change: 1 addition & 0 deletions spython/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .terminal import (
check_install,
get_installdir,
get_singularity_version,
stream_command,
run_command,
format_container_name,
Expand Down
19 changes: 19 additions & 0 deletions spython/utils/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ def check_install(software='singularity', quiet=True):
return found


def get_singularity_version():
'''get the singularity client version. Useful in the case that functionality
has changed, etc. Can be "hacked" if needed by exporting
SPYTHON_SINGULARITY_VERSION, which is checked before checking on the
command line.
'''
version = os.environ.get('SPYTHON_SINGULARITY_VERSION', "")
if version == "":
try:
version = run_command(["singularity", '--version'], quiet=True)
except: # FileNotFoundError
return version

if version['return_code'] == 0:
if len(version['message']) > 0:
version = version['message'][0].strip('\n')

return version

def get_installdir():
'''get_installdir returns the installation directory of the application
'''
Expand Down
2 changes: 1 addition & 1 deletion spython/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@



__version__ = "0.0.46"
__version__ = "0.0.47"
AUTHOR = 'Vanessa Sochat'
AUTHOR_EMAIL = 'vsochat@stanford.edu'
NAME = 'spython'
Expand Down