diff --git a/CHANGELOG.md b/CHANGELOG.md index ca4a13d5..3a84d995 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ 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 deprecation message for image.export (0.0.60) + - adding --force option to build - fixing warning for files, only relevant for sources (0.0.59) - deprecating pulling by commit or hash, not supported for Singularity (0.0.58) - export command added back, points to build given Singularity 3.x+ diff --git a/spython/image/__init__.py b/spython/image/__init__.py index e4c7302c..0b5a606c 100644 --- a/spython/image/__init__.py +++ b/spython/image/__init__.py @@ -8,6 +8,7 @@ import hashlib import os import re +from spython.utils import get_singularity_version class ImageBase(object): @@ -22,7 +23,6 @@ def __str__(self): def __repr__(self): return self.__str__() - def get_uri(self, image): '''get the uri of an image, or the string (optional) that appears before ://. Optional. If none found, returns '' diff --git a/spython/image/cmd/export.py b/spython/image/cmd/export.py index b76fd09d..a247f9da 100644 --- a/spython/image/cmd/export.py +++ b/spython/image/cmd/export.py @@ -22,6 +22,9 @@ def export(self, image_path, tmptar=None): from spython.utils import check_install check_install() + if 'version 3' in self.version(): + bot.exit('export is deprecated after Singularity 2.*') + if tmptar is None: tmptar = "/%s/tmptar.tar" %(tempfile.mkdtemp()) cmd = ['singularity', 'image.export', '-f', tmptar, image_path] diff --git a/spython/main/__init__.py b/spython/main/__init__.py index 1e2c1a79..499a5b9a 100644 --- a/spython/main/__init__.py +++ b/spython/main/__init__.py @@ -71,10 +71,10 @@ def get_client(quiet=False, debug=False): cli = Client() # Pass on verbosity - cli.image.debug = cli.debug - cli.image.quiet = cli.quiet - cli.instance.debug = cli.debug - cli.instance.quiet = cli.quiet + for subclient in [cli.image, cli.instance]: + subclient.debug = cli.debug + subclient.quiet = cli.quiet + subclient.version = cli.version return cli diff --git a/spython/main/base/sutils.py b/spython/main/base/sutils.py index d9144def..aefcc0c5 100644 --- a/spython/main/base/sutils.py +++ b/spython/main/base/sutils.py @@ -45,17 +45,20 @@ def setenv(self, variable, value): bot.debug('%s set to %s' % (variable, value)) -def get_filename(self, image=None, ext='simg'): - '''return an image filename based on the image uri. If an image uri is - not specified, we look for the loaded image. +def get_filename(self, image, ext='sif', pwd=True): + '''return an image filename based on the image uri. Parameters ========== - image: the uri to base off of ext: the extension to use + pwd: derive a filename for the pwd ''' - return "%s.%s" %(re.sub('^.*://','',image).replace('/','-'), ext) - + if pwd is True: + image = os.path.basename(image) + image = re.sub('^.*://','', image) + if not image.endswith(ext): + image = "%s.%s" %(image, ext) + return image def get_uri(self): diff --git a/spython/main/build.py b/spython/main/build.py index 87a4f725..6e4eef12 100644 --- a/spython/main/build.py +++ b/spython/main/build.py @@ -20,7 +20,8 @@ def build(self, recipe=None, robot_name=False, ext='simg', sudo=True, - stream=False): + stream=False, + force=False): '''build a singularity image, optionally for an isolated build (requires sudo). If you specify to stream, expect the image name @@ -52,6 +53,10 @@ def build(self, recipe=None, if 'version 3' in self.version(): ext = 'sif' + + # Force the build if the image / sandbox exists + if force is True: + cmd.append('--force') # No image provided, default to use the client's loaded image if recipe is None: @@ -76,7 +81,6 @@ def build(self, recipe=None, bot.exit('%s does not exist!' % build_folder) image = os.path.join(build_folder, image) - # The user wants to run an isolated build if isolated is True: cmd.append('--isolated') diff --git a/spython/main/export.py b/spython/main/export.py index b3f8c0c6..49a89442 100644 --- a/spython/main/export.py +++ b/spython/main/export.py @@ -19,6 +19,7 @@ def export(self, output_file=None, command=None, sudo=False): + '''export will export an image, sudo must be used. If we have Singularity versions after 3, export is replaced with building into a sandbox. @@ -32,21 +33,23 @@ def export(self, from spython.utils import check_install check_install() - # If not version 3, run deprecated command if 'version 3' in self.version() or '2.6' in self.version(): + # If export is deprecated, we run a build + bot.warning('Export is not supported for Singularity 3.x. Building to sandbox instead.') + if output_file == None: - output_file = self._get_filename(image_path, 'sandbox') + basename, ext = os.path.splitext(image_path) + output_file = self._get_filename(basename, 'sandbox', pwd=False) return self.build(recipe=image_path, image=output_file, sandbox=True, + force=True, sudo=sudo) + # If not version 3, run deprecated command elif '2.5' in self.version(): - - # Otherwise, we run a build - bot.warning('Export is not supported for Singularity 3.x. Building to sandbox instead.') return self._export(image_path=image_path, pipe=pipe, output_file=output_file, diff --git a/spython/tests/test_client.py b/spython/tests/test_client.py index 8af26738..9c56c03e 100644 --- a/spython/tests/test_client.py +++ b/spython/tests/test_client.py @@ -42,7 +42,7 @@ def test_commands(self): os.remove(container) print('Testing client.export command') - sandbox = "busybox:1.30.1.sandbox" + sandbox = "busybox:1.30.sandbox" created_sandbox = self.cli.export('docker://busybox:1.30.1') self.assertEqual(created_sandbox, sandbox) self.assertTrue(os.path.exists(created_sandbox)) @@ -53,7 +53,7 @@ def test_commands(self): image = self.cli.pull("shub://vsoch/singularity-images", pull_folder=self.tmpdir) self.assertTrue(os.path.exists(image)) - self.assertTrue('vsoch-singularity-images' in image) + self.assertTrue('singularity-images' in image) print(image) print('Testing client.run command') diff --git a/spython/utils/terminal.py b/spython/utils/terminal.py index af88747c..6c79498a 100644 --- a/spython/utils/terminal.py +++ b/spython/utils/terminal.py @@ -48,10 +48,9 @@ def check_install(software='singularity', quiet=True): 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. + '''get the full singularity client version as reported by + singularity --version [...]. For Singularity 3.x, this means: + "singularity version 3.0.1-1" ''' version = os.environ.get('SPYTHON_SINGULARITY_VERSION', "") if version == "": diff --git a/spython/version.py b/spython/version.py index fa2b936a..291b69ac 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.59" +__version__ = "0.0.60" AUTHOR = 'Vanessa Sochat' AUTHOR_EMAIL = 'vsochat@stanford.edu' NAME = 'spython'