def stop(self, name=None, sudo=False): '''start an instance. This is done by default when an instance is created. Parameters ========== image: optionally, an image uri (if called as a command from Client) name: a name for the instance sudo: if the user wants to run the command with sudo USAGE: singularity [...] instance.start [...] <container path> <instance name> ''' from spython.utils import (check_install, run_command) check_install() cmd = self._init_command('instance.stop') # If name is provided assume referencing an instance instance_name = self.name if name is not None: instance_name = name cmd = cmd + [instance_name] output = run_command(cmd, sudo=sudo, quiet=True) if output['return_code'] != 0: message = '%s : return code %s' % (output['message'], output['return_code']) bot.error(message) return output['return_code'] return output['return_code']
def stopall(self, sudo=False, quiet=True): """stop ALL instances. This command is only added to the command group as it doesn't make sense to call from a single instance Parameters ========== sudo: if the command should be done with sudo (exposes different set of instances) """ from spython.utils import check_install check_install() subgroup = "instance.stop" if "version 3" in self.version(): subgroup = ["instance", "stop"] cmd = self._init_command(subgroup) cmd = cmd + ["--all"] output = run_command(cmd, sudo=sudo, quiet=quiet) if output["return_code"] != 0: message = "%s : return code %s" % (output["message"], output["return_code"]) bot.error(message) return output["return_code"] return output["return_code"]
def start(self, image=None, name=None, sudo=False, options=[], capture=False): '''start an instance. This is done by default when an instance is created. Parameters ========== image: optionally, an image uri (if called as a command from Client) name: a name for the instance sudo: if the user wants to run the command with sudo capture: capture output, default is False. With True likely to hang. options: a list of tuples, each an option to give to the start command [("--bind", "/tmp"),...] USAGE: singularity [...] instance.start [...] <container path> <instance name> ''' from spython.utils import (run_command, check_install) check_install() # If no name provided, give it an excellent one! if name is None: name = self.RobotNamer.generate() self.name = name.replace('-', '_') # If an image isn't provided, we have an initialized instance if image is None: # Not having this means it was called as a command, without an image if not hasattr(self, "_image"): bot.error('Please provide an image, or create an Instance first.') sys.exit(1) image = self._image cmd = self._init_command('instance.start') # Add options, if they are provided if not isinstance(options, list): options = options.split(' ') # Assemble the command! cmd = cmd + options + [image, self.name] # Save the options and cmd, if the user wants to see them later self.options = options self.cmd = cmd output = run_command(cmd, sudo=sudo, quiet=True, capture=capture) if output['return_code'] == 0: self._update_metadata() else: message = '%s : return code %s' % (output['message'], output['return_code']) bot.error(message) return self
def inspect(self, image=None, json=True, app=None, quiet=True): '''inspect will show labels, defile, runscript, and tests for an image Parameters ========== image: path of image to inspect json: print json instead of raw text (default True) quiet: Don't print result to the screen (default True) app: if defined, return help in context of an app ''' check_install() # No image provided, default to use the client's loaded image if not image: image = self._get_uri() # If there still isn't an image, exit on error if not image: bot.exit('Please provide an image to inspect.') cmd = self._init_command('inspect') if app: cmd = cmd + ['--app', app] options = ['e', 'd', 'l', 'r', 'hf', 't'] # After Singularity 3.0, helpfile was changed to H from if "version 3" in self.version(): options = ['e', 'd', 'l', 'r', 'H', 't'] for x in options: cmd.append('-%s' % x) if json: cmd.append('--json') cmd.append(image) result = run_command(cmd, quiet=quiet) if result['return_code'] == 0: result = jsonp.loads(result['message'][0]) # Unify output to singularity 3 format if "data" in result: result = result['data'] # Fix up labels result = parse_labels(result) if not quiet: print(jsonp.dumps(result, indent=4)) return result
def stop( self, name=None, sudo=False, sudo_options=None, timeout=None, singularity_options=None, quiet=True, ): """stop an instance. This is done by default when an instance is created. Parameters ========== name: a name for the instance sudo: if the user wants to run the command with sudo singularity_options: a list of options to provide to the singularity client quiet: Do not print verbose output. timeout: forcebly kill non-stopped instance after the timeout specified in seconds USAGE: singularity [...] instance.stop [...] <instance name> """ from spython.utils import check_install, run_command check_install() subgroup = "instance.stop" if "version 3" in self.version(): subgroup = ["instance", "stop"] if timeout: subgroup += ["-t", str(timeout)] cmd = self._init_command(subgroup, singularity_options) # If name is provided assume referencing an instance instance_name = self.name if name is not None: instance_name = name cmd = cmd + [instance_name] # Print verbose output if not (quiet or self.quiet): bot.info(" ".join(cmd)) output = run_command(cmd, sudo=sudo, sudo_options=sudo_options, quiet=True) if output["return_code"] != 0: message = "%s : return code %s" % (output["message"], output["return_code"]) bot.error(message) return output["return_code"] return output["return_code"]
def stop(self, name=None, sudo=False): """stop an instance. This is done by default when an instance is created. Parameters ========== name: a name for the instance sudo: if the user wants to run the command with sudo USAGE: singularity [...] instance.stop [...] <instance name> """ from spython.utils import check_install, run_command check_install() subgroup = "instance.stop" if "version 3" in self.version(): subgroup = ["instance", "stop"] cmd = self._init_command(subgroup) # If name is provided assume referencing an instance instance_name = self.name if name is not None: instance_name = name cmd = cmd + [instance_name] output = run_command(cmd, sudo=sudo, quiet=True) if output["return_code"] != 0: message = "%s : return code %s" % (output["message"], output["return_code"]) bot.error(message) return output["return_code"] return output["return_code"]
def stopall(self, sudo=False, quiet=True): '''stop ALL instances. This command is only added to the command group as it doesn't make sense to call from a single instance Parameters ========== sudo: if the command should be done with sudo (exposes different set of instances) ''' from spython.utils import run_command, check_install check_install() cmd = self._init_command('instance.stop') cmd = cmd + ['--all'] output = run_command(cmd, sudo=sudo, quiet=quiet) if output['return_code'] != 0: message = '%s : return code %s' % (output['message'], output['return_code']) bot.error(message) return output['return_code'] return output['return_code']
def instances(self, name=None, return_json=False, quiet=False): '''list instances. For Singularity, this is provided as a command sub group. singularity instance.list Return codes provided are different from standard linux: see https://github.com/singularityware/singularity/issues/1706 Parameters ========== return_json: return a json list of instances instead of objects (False) name: if defined, return the list for just one instance (used to ged pid) Return Code -- Reason 0 -- Instances Found 1 -- No Instances, libexecdir value not found, functions file not found 255 -- Couldn't get UID ''' from spython.instance.cmd.iutils import parse_table from spython.utils import check_install check_install() 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: cmd.append(name) output = run_command(cmd, quiet=True) instances = None # Success, we have instances if output['return_code'] == 0: # Only print the table if we are returning json if quiet is False: print(''.join(output['message'])) # Prepare json result from table header = ['daemon_name', 'pid', 'container_image'] instances = parse_table(output['message'][0], header) # Does the user want instance objects instead? listing = [] if return_json is False: for i in instances: new_instance = self.instance(pid=i['pid'], name=i['daemon_name'], image=i['container_image'], start=False) listing.append(new_instance) instances = listing # Couldn't get UID elif output['return_code'] == 255: bot.error("Couldn't get UID") # Return code of 0 else: bot.info('No instances found.') # If we are given a name, return just one if name is not None and instances is not None: if len(instances) == 1: instances = instances[0] return instances
def list_instances(self, name=None, return_json=False, quiet=False, sudo=False): """list instances. For Singularity, this is provided as a command sub group. singularity instance.list Return codes provided are different from standard linux: see https://github.com/singularityware/singularity/issues/1706 Parameters ========== return_json: return a json list of instances instead of objects (False) name: if defined, return the list for just one instance (used to ged pid) Return Code -- Reason 0 -- Instances Found 1 -- No Instances, libexecdir value not found, functions file not found 255 -- Couldn't get UID """ from spython.instance.cmd.iutils import parse_table from spython.utils import check_install check_install() subgroup = "instance.list" if "version 3" in self.version(): 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: cmd.append(name) output = run_command(cmd, quiet=True, sudo=sudo) instances = [] # Success, we have instances if output["return_code"] == 0: # Only print the table if we are returning json if not quiet: print("".join(output["message"])) # Prepare json result from table # Singularity after 3.5.2 has an added ipaddress try: header = ["daemon_name", "pid", "container_image"] instances = parse_table(output["message"][0], header) except: header = ["daemon_name", "pid", "ip", "container_image"] instances = parse_table(output["message"][0], header) # Does the user want instance objects instead? listing = [] if not return_json: for i in instances: # If the user has provided a name, only add instance matches if name is not None: if name != i["daemon_name"]: continue # Otherwise, add instances to the listing new_instance = self.instance( pid=i["pid"], name=i["daemon_name"], image=i["container_image"], start=False, ) listing.append(new_instance) instances = listing # Couldn't get UID elif output["return_code"] == 255: bot.error("Couldn't get UID") # Return code of 0 else: bot.info("No instances found.") # If we are given a name, return just one if name is not None and instances not in [None, []]: if len(instances) == 1: instances = instances[0] return instances
def inspect(self, image=None, json=True, app=None, quiet=True, singularity_options=None): """inspect will show labels, defile, runscript, and tests for an image Parameters ========== image: path of image to inspect json: print json instead of raw text (default True) quiet: Don't print result to the screen (default True) app: if defined, return help in context of an app singularity_options: a list of options to provide to the singularity client """ check_install() # No image provided, default to use the client's loaded image if not image: image = self._get_uri() # If there still isn't an image, exit on error if not image: bot.exit("Please provide an image to inspect.") cmd = self._init_command("inspect", singularity_options) if app: cmd = cmd + ["--app", app] options = ["e", "d", "l", "r", "hf", "t"] # After Singularity 3.0, helpfile was changed to H from if "version 3" in self.version(): options = ["e", "d", "l", "r", "H", "t"] for x in options: cmd.append("-%s" % x) if json: cmd.append("--json") cmd.append(image) result = run_command(cmd, quiet=quiet) if result["return_code"] == 0: result = jsonp.loads(result["message"][0]) # Unify output to singularity 3 format if "data" in result: result = result["data"] # Fix up labels result = parse_labels(result) if not quiet: print(jsonp.dumps(result, indent=4)) return result
def list_instances( self, name=None, return_json=False, quiet=False, sudo=False, sudo_options=None, singularity_options=None, ): """list instances. For Singularity, this is provided as a command sub group. singularity instance list Return codes provided are different from standard linux: see https://github.com/singularityware/singularity/issues/1706 Since we expect json output, we don't support older versions of Singularity. Parameters ========== return_json: return a json list of instances instead of objects (False) name: if defined, return the list for just one instance (used to ged pid) singularity_options: a list of options to provide to the singularity client Return Code -- Reason 0 -- Instances Found 1 -- No Instances, libexecdir value not found, functions file not found 255 -- Couldn't get UID """ from spython.utils import check_install check_install() subgroup = ["instance", "list", "--json"] if "version 3" not in self.version(): bot.exit("This version of Singularity Python does not support < 3.0.") cmd = self._init_command(subgroup, singularity_options) # If the user has provided a name, we want to see a particular instance if name is not None: cmd.append(name) # Does the user want to see the command printed? if not (quiet or self.quiet): bot.info(" ".join(cmd)) output = run_command(cmd, quiet=True, sudo=sudo, sudo_options=sudo_options) instances = [] # Success, we have instances if output["return_code"] == 0: instances = json.loads(output["message"][0]).get("instances", {}) # Does the user want instance objects instead? listing = [] if not return_json: for i in instances: # If the user has provided a name, only add instance matches if name is not None: if name != i["instance"]: continue # Otherwise, add instances to the listing new_instance = self.instance( pid=i.get("pid"), ip_address=i.get("ip"), name=i.get("instance") or i.get("daemon_name"), log_err_path=i.get("logErrPath"), log_out_path=i.get("logOutPath"), image=i.get("img") or i.get("container_image"), start=False, ) listing.append(new_instance) instances = listing # Couldn't get UID elif output["return_code"] == 255: bot.error("Couldn't get UID") # Return code of 0 else: bot.info("No instances found.") # If we are given a name, return just one if name is not None and instances and len(instances) == 1: instances = instances[0] return instances
def start(self, image=None, name=None, args=None, sudo=False, options=None, capture=False): """start an instance. This is done by default when an instance is created. Parameters ========== image: optionally, an image uri (if called as a command from Client) name: a name for the instance sudo: if the user wants to run the command with sudo capture: capture output, default is False. With True likely to hang. args: arguments to provide to the instance (supported Singularity 3.1+) options: a list of tuples, each an option to give to the start command [("--bind", "/tmp"),...] USAGE: singularity [...] instance.start [...] <container path> <instance name> """ from spython.utils import run_command, check_install check_install() # If name provided, over write robot (default) if name is not None: self.name = name # If an image isn't provided, we have an initialized instance if image is None: # Not having this means it was called as a command, without an image if not hasattr(self, "_image"): bot.exit("Please provide an image, or create an Instance first.") image = self._image # Derive subgroup command based on singularity version subgroup = "instance.start" if "version 3" in self.version(): subgroup = ["instance", "start"] cmd = self._init_command(subgroup) # Add options, if they are provided if not isinstance(options, list): options = [] if options is None else options.split(" ") # Assemble the command! cmd = cmd + options + [image, self.name] # If arguments are provided if args is not None: if not isinstance(args, list): args = [args] cmd = cmd + args # Save the options and cmd, if the user wants to see them later self.options = options self.args = args self.cmd = cmd output = run_command(cmd, sudo=sudo, quiet=True, capture=capture) if output["return_code"] == 0: self._update_metadata() else: message = "%s : return code %s" % (output["message"], output["return_code"]) bot.error(message) return self