def get_tags(self, return_response=False): '''get_tags will return the tags for a repo using the Docker Version 2.0 Registry API :param namespace: the namespace (eg, "library") :param repo_name: the name for the repo (eg, "ubuntu") :param registry: the docker registry to use (default will use index.docker.io) :param auth: authorization header (default None) ''' registry = self.registry if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url base = "%s/%s/%s/%s/tags/list" % (registry, self.api_version, self.namespace, self.repo_name) bot.verbose("Obtaining tags: %s" % base) # We use get_tags for a testing endpoint in update_token response = self.get(base, return_response=return_response) if return_response: return response try: response = json.loads(response) return response['tags'] except: bot.error("Error obtaining tags: %s" % base) sys.exit(1)
def get_manifest(self,image=None,registry=None): '''get_image will return a json object with image metadata, based on a unique id. :param image: the image name, either an id, or a repo name, tag, etc. :param registry: the registry (hub) to use, if not defined, default is used ''' if image == None: image = self.image if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url # Numeric images have slightly different endpoint from named if is_number(image) == True: base = "%s/containers/%s" %(registry,image) else: base = "%s/container/%s" %(registry,image) # --------------------------------------------------------------- # If we eventually have private images, need to authenticate here # --------------------------------------------------------------- response = self.get(base) try: response = json.loads(response) except: print("Error getting image manifest using url %s" %(base)) sys.exit(1) return response
def get_manifest(self,old_version=False): '''get_manifest should return an image manifest for a particular repo and tag. The image details are extracted when the client is generated. :param old_version: return version 1 (for cmd/entrypoint), default False ''' registry = self.registry if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url base = "%s/%s/%s/%s/manifests" %(registry,self.api_version,self.namespace,self.repo_name) if self.version is not None: base = "%s/%s" %(base,self.version) else: base = "%s/%s" %(base,self.repo_tag) bot.verbose("Obtaining manifest: %s" %base) headers = self.headers if old_version == True: headers['Accept'] = 'application/json' response = self.get(base,headers=self.headers) try: response = json.loads(response) except: # If the call fails, give the user a list of acceptable tags tags = self.get_tags() print("\n".join(tags)) repo_uri = "%s/%s:%s" %(self.namespace,self.repo_name,self.repo_tag) bot.error("Error getting manifest for %s, exiting." %repo_uri) sys.exit(1) return response
def get_tags(self, return_response=False): '''get_tags will return the tags for a repo using the Docker Version 2.0 Registry API ''' registry = self.registry if registry is None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url base = "%s/%s/%s/tags/list" % (registry, self.api_version, self.repo_name) bot.verbose("Obtaining tags: %s" % base) # We use get_tags for a testing endpoint in update_token response = self.get(base, return_response=return_response) if return_response: return response try: response = json.loads(response) return response['tags'] except Exception: bot.error("Error obtaining tags: %s" % base) sys.exit(1)
def get_tags(self,return_response=False): '''get_tags will return the tags for a repo using the Docker Version 2.0 Registry API :param namespace: the namespace (eg, "library") :param repo_name: the name for the repo (eg, "ubuntu") :param registry: the docker registry to use (default will use index.docker.io) :param auth: authorization header (default None) ''' registry = self.registry if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url base = "%s/%s/%s/%s/tags/list" %(registry,self.api_version,self.namespace,self.repo_name) bot.verbose("Obtaining tags: %s" %base) # We use get_tags for a testing endpoint in update_token response = self.get(base, return_response=return_response) if return_response: return response try: response = json.loads(response) return response['tags'] except: bot.error("Error obtaining tags: %s" %base) sys.exit(1)
def get_manifest(self, image=None, registry=None): '''get_image will return a json object with image metadata, based on a unique id. :param image: the image name, either an id, or a repo name, tag, etc. :param registry: the registry (hub) to use, if not defined, default is used ''' if image == None: image = self.image if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url # Numeric images have slightly different endpoint from named if is_number(image) == True: base = "%s/containers/%s" % (registry, image) else: base = "%s/container/%s" % (registry, image) # --------------------------------------------------------------- # If we eventually have private images, need to authenticate here # --------------------------------------------------------------- response = self.get(base) try: response = json.loads(response) except: print("Error getting image manifest using url %s" % (base)) sys.exit(1) return response
def get_layer(self, image_id, download_folder=None, change_perms=False, return_tmp=False): '''get_layer will download an image layer (.tar.gz) to a specified download folder. :param download_folder: if specified, download to folder. Otherwise return response with raw data :param change_perms: change permissions additionally (default False to support multiprocessing) :param return_tmp: If true, return the temporary file name (and don't rename to the file's final name). Default is False, should be True for multiprocessing that requires extra permission changes ''' registry = self.registry if registry is None: registry = self.api_base # make sure we have a complete url registry = add_http(registry) # The <name> variable is the namespace/repo_name base = "%s/%s/%s/%s/blobs/%s" % (registry, self.api_version, self.namespace, self.repo_name, image_id) bot.verbose("Downloading layers from %s" % base) if download_folder is None: download_folder = tempfile.mkdtemp() 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_atomically(url=base, file_name=file_name) bot.debug('Download of raw file (pre permissions fix) is %s' % tar_download) # Step 2: Fix Permissions? if change_perms: tar_download = change_tar_permissions(tar_download) if return_tmp is True: return tar_download try: os.rename(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 get_manifest(self, old_version=False, version=None): '''get_manifest should return an image manifest for a particular repo and tag. The image details are extracted when the client is generated. :param old_version: return version 1 (for cmd/entrypoint), default False ''' registry = self.registry if registry is None: registry = self.api_base # make sure we have a complete url registry = add_http(registry) base = "%s/%s/%s/%s/manifests" % (registry, self.api_version, self.namespace, self.repo_name) # First priority given to calling function if version is not None: base = "%s/%s" % (base, version) elif self.version is not None: base = "%s/%s" % (base, self.version) else: base = "%s/%s" % (base, self.repo_tag) bot.verbose("Obtaining manifest: %s" % base) headers = self.headers.copy() if old_version is True: headers['Accept'] = 'application/json' response = self.get(base, headers=headers) try: response = json.loads(response) except Exception: # If the call fails, give the user a list of acceptable tags tags = self.get_tags() print("\n".join(tags)) repo_uri = "%s/%s:%s" % (self.namespace, self.repo_name, self.repo_tag) bot.error("Error getting manifest for %s, exiting." % repo_uri) sys.exit(1) # If we have errors, don't continue return self.check_errors(response)
def get_layer(self,image_id,download_folder=None,change_perms=False,return_tmp=False): '''get_layer will download an image layer (.tar.gz) to a specified download folder. :param download_folder: if specified, download to folder. Otherwise return response with raw data (not recommended) :param change_perms: change permissions additionally (default False to support multiprocessing) :param return_tmp: If true, return the temporary file name (and don't rename to the file's final name). Default is False, should be True for multiprocessing that requires extra permission changes ''' registry = self.registry if registry == None: registry = self.api_base registry = add_http(registry) # make sure we have a complete url # The <name> variable is the namespace/repo_name base = "%s/%s/%s/%s/blobs/%s" %(registry,self.api_version,self.namespace,self.repo_name,image_id) bot.verbose("Downloading layers from %s" %base) if download_folder is None: download_folder = tempfile.mkdtemp() 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_atomically(url=base, file_name=file_name) bot.debug('Download of raw file (pre permissions fix) is %s' %tar_download) # Step 2: Fix Permissions? if change_perms: tar_download = change_tar_permissions(tar_download) if return_tmp is True: return tar_download try: os.rename(tar_download,download_folder) except: bot.error("Cannot untar layer %s, was there a problem with download?" %tar_download) sys.exit(1) return download_folder
def test_add_http(self): '''test_add_http ensures that http is added to a url ''' from sutils import add_http url_http = 'http://registry.docker.io' url_https = 'https://registry.docker.io' print("Case 1: adding https to url with nothing specified...") # Default is https url = 'registry.docker.io' http = add_http(url) self.assertEqual(url_https, http) # http print("Case 2: adding http to url with nothing specified...") http = add_http(url, use_https=False) self.assertEqual(url_http, http) # This should not change. Note - is url is http, stays http print("Case 3: url already has https, should not change...") url = 'https://registry.docker.io' http = add_http(url) self.assertEqual(url_https, http) # This should not change. Note - is url is http, stays http print("Case 4: url already has http, should not change...") url = 'http://registry.docker.io' http = add_http(url, use_https=False) self.assertEqual(url_http, http) print("Case 5: url has http, should change to https") url = 'http://registry.docker.io' http = add_http(url) self.assertEqual(url_https, http) print("Case 6: url has https, should change to http") url = 'https://registry.docker.io' http = add_http(url, use_https=False) self.assertEqual(url_http, http) print("Case 7: url should have trailing slash stripped") url = 'https://registry.docker.io/' http = add_http(url, use_https=False) self.assertEqual(url_http, http)
def get_manifest(self): '''get_image will return a json object with image metadata based on a unique id. Parameters ========== :param image: the image name, either an id or a repo name, tag, etc. Returns ======= manifest: a json manifest from the registry ''' # make sure we have a complete url registry = add_http(self.image['registry']) base = "%s/api/container/%s/%s:%s" % (registry, self.image['namespace'], self.image['repo_name'], self.image['repo_tag']) # ------------------------------------------------------ # If we need to authenticate, will do it here # ------------------------------------------------------ # If the Hub returns 404, the image name is likely wrong response = self.get(base, return_response=True) if response.code == 404: msg = "Cannot find image." msg += " Is your capitalization correct?" bot.error(msg) sys.exit(1) try: response = response.read().decode('utf-8') response = json.loads(response) except Exception: print("Error getting image manifest using url %s" % base) sys.exit(1) return response