def tag_image(self, name, tag, repository, force=False): ''' Tag an image into a repository. :param name: name of the image. required. :param tag: image tag. :param repository: path to the repository. required. :param force: bool. force tagging, even it image already exists with the repository path. :param push: bool. push the image once it's tagged. :return: None ''' repo, repo_tag = utils.parse_repository_tag(repository) image = self.client.find_image(name=repo, tag=repo_tag) found = 'found' if image else 'not found' self.log("image %s was %s" % (repo, found)) if not image or force: self.log("tagging %s:%s to %s" % (name, tag, repository)) self.results['changed'] = True self.results['actions'].append("Tagged image %s:%s to %s" % (name, tag, repository)) if not self.check_mode: try: # Finding the image does not always work, especially running a localhost registry. In those # cases, if we don't set force=True, it errors. image_name = name if tag and not re.search(tag, name): image_name = "%s:%s" % (name, tag) tag_status = self.client.tag(image_name, repository, tag=tag, force=True) if not tag_status: raise Exception("Tag operation failed.") except Exception as exc: self.fail("Error: failed to tag image %s - %s" % (name, str(exc))) self.results['image'] = self.client.find_image(name=repository, tag=tag) self.push_image(repository, tag)
def tag_image(self, name, tag, repository, force=False, push=False): ''' Tag an image into a repository. :param name: name of the image. required. :param tag: image tag. :param repository: path to the repository. required. :param force: bool. force tagging, even it image already exists with the repository path. :param push: bool. push the image once it's tagged. :return: None ''' repo, repo_tag = utils.parse_repository_tag(repository) image = self.client.find_image(name=repo, tag=repo_tag) found = 'found' if image else 'not found' self.log("image %s was %s" % (repo, found)) if not image or force: try: self.log("tagging %s:%s to %s" % (name, tag, repository)) self.results['changed'] = True if not self.check_mode: self.results['actions'].append("Tagged image %s:%s to %s" % (name, tag, repository)) # Finding the image does not always work, especially running a localhost registry. In those # cases, if we don't set force=True, it errors. tag_status = self.client.tag(name, repository, tag=tag, force=True) if not tag_status: raise Exception("Tag operation failed.") image = self.client.find_image(name=repository, tag=tag) if image: self.results['image'] = image except Exception, exc: self.fail("Error: failed to tag image %s - %s" % (name, str(exc))) if push: self.log("push %s with tag %s" % (repository, tag)) self.push_image(repository, tag)
def get_facts(self): ''' Lookup and inspect each image name found in the names parameter. :returns array of image dictionaries ''' results = [] names = self.name if not isinstance(names, list): names = [names] for name in names: if is_image_name_id(name): self.log('Fetching image %s (ID)' % (name)) image = self.client.find_image_by_id(name) else: repository, tag = utils.parse_repository_tag(name) if not tag: tag = 'latest' self.log('Fetching image %s:%s' % (repository, tag)) image = self.client.find_image(name=repository, tag=tag) if image: results.append(image) return results
def test_parse_repository_tag(self): self.assertEqual(parse_repository_tag("root"), ("root", None)) self.assertEqual(parse_repository_tag("root:tag"), ("root", "tag")) self.assertEqual(parse_repository_tag("user/repo"), ("user/repo", None)) self.assertEqual(parse_repository_tag("user/repo:tag"), ("user/repo", "tag")) self.assertEqual(parse_repository_tag("url:5000/repo"), ("url:5000/repo", None)) self.assertEqual(parse_repository_tag("url:5000/repo:tag"), ("url:5000/repo", "tag"))
def __init__(self, name, registry=None): self.name = name self._layers = [] repo, tag = parse_repository_tag(name) reg_domain, repo_name = resolve_repository_name(repo) self.repository = repo_name self.tag = tag or 'latest' if reg_domain == INDEX_NAME: reg_domain = DOCKER_HUP_REGISTRY self.repository = 'library/{}'.format(repo_name) if isinstance(registry, LocalRegistry): self.registry = registry else: self.registry = RemoteRegistry(reg_domain)
def push_image(self, name, tag=None): ''' If the name of the image contains a repository path, then push the image. :param name Name of the image to push. :param tag Use a specific tag. :return: None ''' repository = name if not tag: repository, tag = utils.parse_repository_tag(name) registry, repo_name = auth.resolve_repository_name(repository) if re.search('/', repository): if registry: config = auth.load_config() if not auth.resolve_authconfig(config, registry): self.fail( "Error: configuration for %s not found. Try logging into %s first." % (registry, registry)) self.log("pushing image %s" % repository) self.results['actions'].append( "Pushed image %s to %s:%s" % (self.name, self.repository, self.tag)) self.results['changed'] = True if not self.check_mode: status = None try: for line in self.client.push(repository, tag=tag, stream=True): line = json.loads(line) self.log(line, pretty_print=True) if line.get('errorDetail'): raise Exception(line['errorDetail']['message']) status = line.get('status') except Exception as exc: if re.search('unauthorized', str(exc)): self.fail( "Error pushing image %s: %s. Does the repository exist?" % (repository, str(exc))) self.fail("Error pushing image %s: %s" % (repository, str(exc))) self.results['image'] = self.client.find_image(name=repository, tag=tag) if not self.results['image']: self.results['image'] = dict() self.results['image']['push_status'] = status
def test_parse_repository_tag(self): self.assertEqual(parse_repository_tag("root"), ("root", "")) self.assertEqual(parse_repository_tag("root:tag"), ("root", "tag")) self.assertEqual(parse_repository_tag("user/repo"), ("user/repo", "")) self.assertEqual(parse_repository_tag("user/repo:tag"), ("user/repo", "tag")) self.assertEqual(parse_repository_tag("url:5000/repo"), ("url:5000/repo", "")) self.assertEqual(parse_repository_tag("url:5000/repo:tag"), ("url:5000/repo", "tag"))
def split_tag(image_name: str): """ Split docker image name >>> split_tag('fedora/httpd') ('fedora/httpd', None) >>> split_tag('fedora/httpd:') ('fedora/httpd', '') >>> split_tag('fedora/httpd:version1.0') ('fedora/httpd', 'version1.0') >>> split_tag('fedora/httpd@sha256:12345') ('fedora/httpd', 'sha256:12345') """ warnings.warn("Please use parse_repository_tag from docker.utils", DeprecationWarning) return parse_repository_tag(image_name)
def push_image(self, name, tag=None): ''' If the name of the image contains a repository path, then push the image. :param name Name of the image to push. :param tag Use a specific tag. :return: None ''' repository = name if not tag: repository, tag = utils.parse_repository_tag(name) registry, repo_name = auth.resolve_repository_name(repository) if re.search('/', repository): if registry: config = auth.load_config() if not auth.resolve_authconfig(config, registry): self.fail("Error: configuration for %s not found. Try logging into %s first." % registry) self.log("pushing image %s" % repository) self.results['actions'].append("Pushed image %s to %s:%s" % (self.name, self.repository, self.tag)) self.results['changed'] = True if not self.check_mode: status = None try: for line in self.client.push(repository, tag=tag, stream=True): line = json.loads(line) self.log(line, pretty_print=True) if line.get('errorDetail'): raise Exception(line['errorDetail']['message']) status = line.get('status') except Exception as exc: if re.search('unauthorized', str(exc)): self.fail("Error pushing image %s: %s. Does the repository exist?" % (repository, str(exc))) self.fail("Error pushing image %s: %s" % (repository, str(exc))) self.results['image'] = self.client.find_image(name=repository, tag=tag) if not self.results['image']: self.results['image'] = dict() self.results['image']['push_status'] = status
def push_image(self, name, tag=None): ''' Push an image to a repository. :param name - name of the image to push. Type: str :param tag - use a specific tag. Type: str :return: None ''' repository = name if not tag: repository, tag = utils.parse_repository_tag(name) registry, repo_name = auth.resolve_repository_name(repository) if registry: config = auth.load_config() if not auth.resolve_authconfig(config, registry): self.fail("Error: configuration for %s not found. Try logging into %s first." % registry) try: self.log("pushing image %s" % (repository)) status = None if not self.check_mode: self.results['actions'].append("Pushed image %s to %s:%s" % (self.name, self.repository, self.tag)) for line in self.client.push(repository, tag=tag, stream=True): response = json.loads(line) self.log(response, pretty_print=True) if response.get('errorDetail'): # there was an error raise Exception(response['errorDetail']['message']) status = response.get('status') self.results['changed'] = True image = self.client.find_image(name=repository, tag=tag) if image: self.results['image'] = image self.results['image']['push_status'] = status except Exception, exc: if re.search(r'unauthorized', str(exc)): self.fail("Error pushing image %s: %s. Does the repository exist?" % (repository, str(exc))) self.fail("Error pushing image %s: %s" % (repository, str(exc)))
def get_facts(self): ''' Lookup and inspect each image name found in the names parameter. :returns array of image dictionaries ''' results = [] names = self.name if not isinstance(names, list): names = [names] for name in names: repository, tag = utils.parse_repository_tag(name) if not tag: tag = 'latest' self.log('Fetching image %s:%s' % (repository, tag)) image = self.client.find_image(name=repository, tag=tag) if image: results.append(image) return results
def test_index_image_sha(self): self.assertEqual( parse_repository_tag("root@sha256:{0}".format(self.sha)), ("root", "sha256:{0}".format(self.sha)))
def test_index_image_no_tag(self): assert parse_repository_tag("root") == ("root", None)
def test_index_user_image_no_tag(self): self.assertEqual(parse_repository_tag("user/repo"), ("user/repo", None))
def test_private_reg_image_no_tag(self): self.assertEqual(parse_repository_tag("url:5000/repo"), ("url:5000/repo", None))
def test_index_image_sha(self): self.assertEqual( parse_repository_tag("root@sha256:{0}".format(self.sha)), ("root", "sha256:{0}".format(self.sha)) )
def test_index_image_no_tag(self): self.assertEqual(parse_repository_tag("root"), ("root", None))
def test_index_user_image_no_tag(self): assert parse_repository_tag("user/repo") == ("user/repo", None)
def test_private_reg_image_no_tag(self): self.assertEqual( parse_repository_tag("url:5000/repo"), ("url:5000/repo", None) )
def test_private_reg_image_sha(self): assert parse_repository_tag( f"url:5000/repo@sha256:{self.sha}" ) == ("url:5000/repo", f"sha256:{self.sha}")
def adcm_image_tags(cmd_opts) -> Tuple[str, str]: """Get tag parts of --adcm-image argument (split by ":")""" if not cmd_opts.adcm_image: pytest.fail("CLI parameter adcm_image should be provided") return tuple(parse_repository_tag(cmd_opts.adcm_image)) # type: ignore
def test_index_image_sha(self): assert parse_repository_tag(f"root@sha256:{self.sha}") == ( "root", f"sha256:{self.sha}" )
def test_index_image_sha(self): assert parse_repository_tag("root@sha256:{0}".format(self.sha)) == ( "root", "sha256:{0}".format(self.sha) )
def test_private_reg_image_tag(self): assert parse_repository_tag("url:5000/repo:tag") == ( "url:5000/repo", "tag" )
def test_private_reg_image_no_tag(self): assert parse_repository_tag("url:5000/repo") == ("url:5000/repo", None)
def parse_id(cls, name): reg_repo, tag = parse_repository_tag(name) reg, repo = resolve_repository_name(reg_repo) return reg, repo, tag
def test_index_user_image_tag(self): self.assertEqual( parse_repository_tag("user/repo:tag"), ("user/repo", "tag") )
def test_index_image_tag(self): assert parse_repository_tag("root:tag") == ("root", "tag")
def test_private_reg_image_tag(self): self.assertEqual( parse_repository_tag("url:5000/repo:tag"), ("url:5000/repo", "tag") )
def test_private_reg_image_sha(self): self.assertEqual( parse_repository_tag("url:5000/repo@sha256:{0}".format(self.sha)), ("url:5000/repo", "sha256:{0}".format(self.sha)) )
def test_index_image_tag(self): self.assertEqual(parse_repository_tag("root:tag"), ("root", "tag"))
def test_index_image_sha(self): assert parse_repository_tag("root@sha256:{0}".format( self.sha)) == ("root", "sha256:{0}".format(self.sha))
def test_index_user_image_tag(self): self.assertEqual(parse_repository_tag("user/repo:tag"), ("user/repo", "tag"))
def test_private_reg_image_tag(self): self.assertEqual(parse_repository_tag("url:5000/repo:tag"), ("url:5000/repo", "tag"))
def test_index_image_tag(self): self.assertEqual( parse_repository_tag("root:tag"), ("root", "tag") )
def image(request, cmd_opts, bind_container_ip, adcm_api_credentials, additional_adcm_init_config, adcm_https): """That fixture creates ADCM container, waits until a database becomes initialised and stores that as images with random tag and name local/adcminit That can be useful to use that fixture to make ADCM's container startup time shorter. Operates with cmd-opts: '--staticimage INIT_IMAGE' '--adcm-image IMAGE' '--remote-docker HOST:PORT' '--dontstop' '--nopull' Fixture returns list: repo, tag """ mutually_exclusive_opts = [ ["adcm_image", "adcm_images", "adcm_min_version"], ["staticimage", "adcm_images", "adcm_min_version"], ] # if more than one option that defines image params is used raise exception # pytest don't allow more convenient mechanisms to add mutually exclusive options. for opt_sets in mutually_exclusive_opts: if check_mutually_exclusive(cmd_opts, *opt_sets): raise Exception( f"wrong using of import parameters {', '.join(opt_sets)} are mutually exclusive" ) if cmd_opts.remote_docker: docker_client = docker.DockerClient( base_url=f"tcp://{cmd_opts.remote_docker}", timeout=120) else: docker_client = docker.from_env(timeout=120) params = {} if cmd_opts.staticimage: params["repo"], params["tag"] = parse_repository_tag( cmd_opts.staticimage) # if image fixture was indirectly parametrized # use 'adcm_repo' and 'adcm_tag' from parametrisation if hasattr(request, "param"): adcm_repo, adcm_tag = request.param # if there is no parametrization check if adcm_image option is passed elif cmd_opts.adcm_image: adcm_repo, adcm_tag = parse_repository_tag(cmd_opts.adcm_image) else: adcm_repo, adcm_tag = None, None container_config = ContainerConfig( image=adcm_repo, tag=adcm_tag, bind_ip=bind_container_ip, remove=False, pull=not cmd_opts.nopull, https=adcm_https, ) initializer = ADCMInitializer( container_config=container_config, dc=docker_client, adcm_api_credentials=adcm_api_credentials, **params, **additional_adcm_init_config, ) init_image = initializer.get_initialized_adcm_image() yield init_image["repo"], init_image["tag"] initializer.cleanup() if cmd_opts.dontstop or cmd_opts.staticimage: return # leave image intact remove_docker_image(**init_image, dc=docker_client)
def test_index_user_image_no_tag(self): self.assertEqual( parse_repository_tag("user/repo"), ("user/repo", None) )
def test_index_user_image_tag(self): assert parse_repository_tag("user/repo:tag") == ("user/repo", "tag")
def _parse_image_name(image): repository, tag = docker_utils.parse_repository_tag(image) registry, name = docker_auth.resolve_repository_name(repository) if registry == docker_auth.INDEX_NAME: registry = '' return registry, name, tag
def test_private_reg_image_tag(self): assert parse_repository_tag("url:5000/repo:tag") == ("url:5000/repo", "tag")
def test_index_image_no_tag(self): self.assertEqual( parse_repository_tag("root"), ("root", None) )
def test_private_reg_image_sha(self): assert parse_repository_tag("url:5000/repo@sha256:{0}".format( self.sha)) == ("url:5000/repo", "sha256:{0}".format(self.sha))
def parse_image_name(image): repository, tag = docker_utils.parse_repository_tag(image) registry, name = docker_auth.resolve_repository_name(repository) if registry == docker_auth.INDEX_NAME: registry = '' return registry, name, tag