def stop(self): '''delete the instance, if it exists. Singularity doesn't have delete or remove commands, everyting is a stop. ''' if self.instance: bot.info("Stopping %s" % self) self.instance.stop(sudo=self.sudo) self.instance = None
def create(self, ip_address=None, sudo=False, writable_tmpfs=False): """create an instance, if it doesn't exist. """ image = self.get_image() # Case 1: No build context or image defined if image is None: bot.exit( "Please define an image or build context for instance %s" % self.name) # Case 2: Image not built. if not os.path.exists(image): bot.exit("Image %s not found, please run build first." % image) # Finally, create the instance if not self.exists(): bot.info("Creating %s" % self.name) # Command options options = [] # Volumes options += self._get_bind_commands() if sudo: # Ports options += self._get_network_commands(ip_address) # Hostname options += ["--hostname", self.name] # Writable Temporary Directory if writable_tmpfs: options += ["--writable-tmpfs"] # Show the command to the user commands = "%s %s %s %s" % ( " ".join(options), image, self.name, self.args, ) bot.debug("singularity instance start %s" % commands) self.instance = self.client.instance( name=self.name, sudo=self.sudo, options=options, image=image, args=self.args, )
def get_image(self): '''get the associated instance image name, to be built if it doesn't exit. It can either be defined at the config from self.image, or ultimately generated via a pull from a uri. ''' # If the user gave a direct image if self.image is not None: if os.path.exists(self.image): return self.image context = os.path.abspath(self.context) # if the context directory doesn't exist, create it if not os.path.exists(context): bot.info("Creating image context folder for %s" % self.name) os.mkdir(context) # The sif binary should have a predictible name return os.path.join(context, '%s.sif' % self.name)
def build(self, working_dir): '''build an image if called for based on having a recipe and context. Otherwise, pull a container uri to the instance workspace. ''' sif_binary = self.get_image() # If the final image already exists, don't continue if os.path.exists(sif_binary): return # Case 1: Given an image if self.image is not None: if not os.path.exists(self.image): # Can we pull it? if re.search('(docker|library|shub|http?s)[://]', self.image): bot.info('Pulling %s' % self.image) self.client.pull(self.image, name=sif_binary) else: bot.exit('%s is an invalid unique resource identifier.' % self.image) # Case 2: Given a recipe elif self.recipe is not None: # Change directory to the context context = os.path.abspath(self.context) os.chdir(context) # The recipe is expected to exist in the context folder if not os.path.exists(self.recipe): bot.exit('%s not found for build' % self.recipe) # This will likely require sudo, unless --remote or --fakeroot in options try: options = self.get_build_options() # If remote or fakeroot included, don't need sudo sudo = not ("--fakeroot" in options or "--remote" in options) bot.info('Building %s' % self.name) _, stream = self.client.build(image=sif_binary, recipe=self.recipe, options=options, sudo=sudo, stream=True) for line in stream: print(line) except: build = "sudo singularity build %s %s" % ( os.path.basename(sif_binary), self.recipe) bot.warning("Issue building container, try: %s" % build) # Change back to provided working directory os.chdir(working_dir) else: bot.exit("neither image and build defined for %s" % self.name)