def Run(self, args): """This is what ts called when the user runs this command. Args: args: an argparse namespace. All the arguments that were provided to this command invocation. Raises: InvalidImageNameError: If the user specified an invalid image name. Returns: A list of the deleted docker_name.Tag and docker_name.Digest objects """ # IMAGE_NAME: The fully-qualified image name to delete (with a digest). # Deletes the layers. Ex. gcr.io/google-appengine/java(@DIGEST|:TAG). http_obj = http.Http() # collect input/validate digests, tags = self._ProcessImageNames(args.image_names) # print if digests: log.status.Print('Digests:') for digest in digests: self._PrintDigest(digest, http_obj) if tags: log.status.Print('Tags:') for tag in tags: log.status.Print('- ' + str(tag)) for digest in digests: tags.update(util.GetDockerTagsForDigest(digest, http_obj)) # prompt console_io.PromptContinue( 'This operation will delete the above tags ' 'and/or digests. Tag deletions only delete the' 'tag. Digest deletions also delete the ' 'underlying image layers.', default=True, cancel_on_no=True) # delete and collect output result = [] for tag in tags: # tags must be deleted before digests self._DeleteDockerTagOrDigest(tag, http_obj) result.append({'name': str(tag)}) for digest in digests: self._DeleteDockerTagOrDigest(digest, http_obj) result.append({'name': str(digest)}) return result
def Run(self, args): """This is what ts called when the user runs this command. Args: args: an argparse namespace. All the arguments that were provided to this command invocation. Raises: InvalidImageNameError: If the user specified an invalid image name. Returns: A list of the deleted docker_name.Tag and docker_name.Digest objects """ # IMAGE_NAME: The fully-qualified image name to delete (with a digest). # Deletes the layers. Ex. gcr.io/google-appengine/java(@DIGEST|:TAG). http_obj = http.Http() with util.WrapExpectedDockerlessErrors(): # collect input/validate digests, explicit_tags = self._ProcessImageNames(args.image_names) # Resolve tags to digests. for tag in explicit_tags: digests.add(util.GetDigestFromName(str(tag))) # Find all the tags that reference digests to be deleted. all_tags = set() for digest in digests: all_tags.update(util.GetDockerTagsForDigest(digest, http_obj)) # Find all the tags that weren't specified explicitly. implicit_tags = all_tags.difference(explicit_tags) if implicit_tags and not args.force_delete_tags: log.error('Tags:') for tag in explicit_tags: log.error('- ' + six.text_type(tag)) raise exceptions.Error( 'This operation will implicitly delete the tags listed above. ' 'Please manually remove with the `untag` command or re-run with ' '--force-delete-tags to confirm.') # Print the digests to be deleted. if digests: log.status.Print('Digests:') for digest in digests: self._PrintDigest(digest, http_obj) # Print the tags to be deleted. if explicit_tags: log.status.Print('Tags:') for tag in explicit_tags: log.status.Print('- ' + six.text_type(tag)) # Prompt the user for consent to delete all the above. console_io.PromptContinue( 'This operation will delete the tags and images identified by the ' 'digests above.', default=True, cancel_on_no=True) # The user has given explicit consent, merge the tags. explicit_tags.update(implicit_tags) # delete and collect output result = [] for tag in explicit_tags: # tags must be deleted before digests self._DeleteDockerTagOrDigest(tag, http_obj) result.append({'name': str(tag)}) for digest in digests: self._DeleteDockerTagOrDigest(digest, http_obj) result.append({'name': str(digest)}) return result