def _pull(self, <EOL>file_name, <EOL>names, <EOL>save=True, <EOL>force=False, <EOL>uri="<STR_LIT>", <EOL>**kwargs):
<EOL>if file_name is None:<EOL><INDENT>file_name = self._get_storage_name(names)<EOL><DEDENT>if os.path.exists(file_name) and force is False:<EOL><INDENT>bot.error('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>digest = names['<STR_LIT:version>'] or names['<STR_LIT>']<EOL>sandbox = get_tmpdir(prefix="<STR_LIT>")<EOL>layers = self._download_layers(names['<STR_LIT:url>'], digest)<EOL>url = self._get_manifest_selfLink(names['<STR_LIT:url>'], digest)<EOL>envtar = self._get_environment_tar()<EOL>layers = [envtar] + layers<EOL>for layer in layers:<EOL><INDENT>bot.info('<STR_LIT>' %layer)<EOL>result = extract_tar(layer, sandbox, handle_whiteout=True)<EOL>if result['<STR_LIT>'] != <NUM_LIT:0>:<EOL><INDENT>bot.error(result['<STR_LIT:message>'])<EOL>sys.exit(<NUM_LIT:1>)        <EOL><DEDENT><DEDENT>sudo = kwargs.get('<STR_LIT>', False)<EOL>image_file = Singularity.build(image=file_name,<EOL>recipe=sandbox,<EOL>sudo=sudo)<EOL>if image_file is None:<EOL><INDENT>bot.info('<STR_LIT>')<EOL>image = image.replace('<STR_LIT>', uri)<EOL>image_file = Singularity.pull(image, pull_folder=sandbox)<EOL><DEDENT>if save is True:<EOL><INDENT>manifests = {}<EOL>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>manifests = self.manifests<EOL><DEDENT>container = self.add(image_path = image_file,<EOL>image_uri = names['<STR_LIT>'],<EOL>metadata = manifests,<EOL>url = url)<EOL>image_file = container.image<EOL><DEDENT>if os.path.exists(image_file):<EOL><INDENT>bot.debug('<STR_LIT>' %image_file)<EOL>bot.custom(prefix="<STR_LIT>", message=image_file)<EOL><DEDENT>shutil.rmtree(sandbox)<EOL>return image_file<EOL>
pull an image from a docker hub. This is a (less than ideal) workaround
       that actually does the following:

       - creates a sandbox folder
       - adds docker layers, metadata folder, and custom metadata to it
       - converts to a squashfs image with build

    the docker manifests are stored with registry metadata.

    Parameters
    ==========
    images: refers to the uri given by the user to pull in the format
    <collection>/<namespace>. You should have an API that is able to 
    retrieve a container based on parsing this uri.
    file_name: the user's requested name for the file. It can 
               optionally be None if the user wants a default.
    save: if True, you should save the container to the database
          using self.add()

    Returns
    =======
    finished: a single container path, or list of paths