def download_task(url, headers, download_to, download_type='layer'): '''download an image layer (.tar.gz) to a specified download folder. This task is done by using local versions of the same download functions that are used for the client. core stream/download functions of the parent client. Parameters ========== image_id: the shasum id of the layer, already determined to not exist repo_name: the image name (library/ubuntu) to retrieve download_to: download to this folder. If not set, uses temp. ''' # Update the user what we are doing bot.verbose("Downloading %s from %s" % (download_type, url)) # Step 1: Download the layer atomically file_name = "%s.%s" % (download_to, next(tempfile._get_candidate_names())) tar_download = download(url, file_name, headers=headers) try: shutil.move(tar_download, download_to) except Exception: msg = "Cannot untar layer %s," % tar_download msg += " was there a problem with download?" bot.error(msg) sys.exit(1) return download_to
def get_manifest(self, repo_name, digest=None, version="v1"): ''' get_manifest should return an image manifest for a particular repo and tag. The image details are extracted when the client is generated. Parameters ========== repo_name: reference to the <username>/<repository>:<tag> to obtain digest: a tag or shasum version version: one of v1, v2, and config (for image config) ''' accepts = {'config': "application/vnd.docker.container.image.v1+json", 'v1': "application/vnd.docker.distribution.manifest.v1+json", 'v2': "application/vnd.docker.distribution.manifest.v2+json" } url = self._get_manifest_selfLink(repo_name, digest) bot.verbose("Obtaining manifest: %s %s" % (url, version)) headers = {'Accept': accepts[version] } try: manifest = self._get(url, headers=headers, quiet=True) manifest['selfLink'] = url except: manifest = None return manifest
def get_layer(self, image_id, repo_name, download_folder=None): '''download an image layer (.tar.gz) to a specified download folder. Parameters ========== download_folder: download to this folder. If not set, uses temp. repo_name: the image name (library/ubuntu) to retrieve ''' url = self._get_layerLink(repo_name, image_id) bot.verbose("Downloading layers from %s" % url) download_folder = get_tmpdir(download_folder) download_folder = "%s/%s.tar.gz" % (download_folder, image_id) # Update user what we are doing bot.debug("Downloading layer %s" % image_id) # Step 1: Download the layer atomically file_name = "%s.%s" % (download_folder, next(tempfile._get_candidate_names())) tar_download = self.download(url, file_name) try: shutil.move(tar_download, download_folder) except Exception: msg = "Cannot untar layer %s," % tar_download msg += " was there a problem with download?" bot.error(msg) sys.exit(1) return download_folder
def getenv(variable_key, default=None, required=False, silent=True): ''' getenv will attempt to get an environment variable. If the variable is not found, None is returned. :param variable_key: the variable name :param required: exit with error if not found :param silent: Do not print debugging information for variable ''' variable = os.environ.get(variable_key, default) if variable is None and required: bot.error("Cannot find environment variable %s, exiting." %variable_key) sys.exit(1) if not silent and variable is not None: bot.verbose("%s found as %s" %(variable_key,variable)) return variable
def get_config(self, key="Entrypoint", delim=None): '''get_config returns a particular key (default is Entrypoint) from a VERSION 1 manifest obtained with get_manifest. Parameters ========== key: the key to return from the manifest config delim: Given a list, the delim to use to join the entries. Default is newline ''' if not hasattr(self,'manifests'): bot.error('Please retrieve manifests for an image first.') sys.exit(1) cmd = None # If we didn't find the config value in version 2 for version in ['config', 'v1']: if cmd is None and 'config' in self.manifests: # First try, version 2.0 manifest config has upper level config manifest = self.manifests['config'] if "config" in manifest: if key in manifest['config']: cmd = manifest['config'][key] # Second try, config manifest (not from verison 2.0 schema blob) if cmd is None and "history" in manifest: for entry in manifest['history']: if 'v1Compatibility' in entry: entry = json.loads(entry['v1Compatibility']) if "config" in entry: if key in entry["config"]: cmd = entry["config"][key] # Standard is to include commands like ['/bin/sh'] if isinstance(cmd, list): if delim is not None: cmd = delim.join(cmd) bot.verbose("Found Docker config (%s) %s" % (key, cmd)) return cmd