def Run(self, args): """This is what gets 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: Some value that we want to have printed later. """ try: img_name = util.GetDigestFromName(args.image_name) return util.TransformContainerAnalysisData(img_name, args.occurrence_filter) except docker_http.V2DiagnosticException as err: raise util.GcloudifyRecoverableV2Errors( err, { 403: 'Describe failed, access denied: {0}'.format( args.image_name), 404: 'Describe failed, not found: {0}'.format(args.image_name) })
def testDigest(self): repo = 'gcr.io/google-appengine/java-compat' hex_str = '01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b' expected_digest = docker_name.Digest('{repo}@sha256:{hex_str}'.format( repo=repo, hex_str=hex_str)) digest = util.GetDigestFromName(str(expected_digest)) self.assertEqual(expected_digest, digest)
def Run(self, args): """This is what is called when the user runs this command. Args: args: an argparse namespace. All the arguments that were provided to this command invocation. Raises: util.InvalidImageNameError: If the user specified an invalid (or non-existent) image name. Returns: A list of the deleted docker_name.Tag objects """ # IMAGE_NAME: The fully-qualified image name to delete (with a tag). # Removes the tag from the image. Ex. gcr.io/google-appengine/java:TAG. http_obj = util.Http() # collect input/validate tags = self._ParseArgs(args.image_names) digests = dict() with util.WrapExpectedDockerlessErrors(): for tag in tags: try: # Resolve tags to digests. Throws InvalidImageNameError on 404. digests[tag] = util.GetDigestFromName(six.text_type(tag)) except util.InvalidImageNameError: # We already validated the image string in _ParseArgs, this is a 404 raise util.InvalidImageNameError( 'Image could not be found: [{}]'.format( six.text_type(tag))) if not tags: log.warning('No tags found matching image names [%s].', ', '.join(args.image_names)) return for tag, digest in six.iteritems(digests): log.status.Print('Tag: [{}]'.format(six.text_type(tag))) log.status.Print('- referencing digest: [{}]'.format( six.text_type(digest))) log.status.Print('') console_io.PromptContinue( 'This operation will remove the above tags. ' 'Tag removals only delete the tags; ' 'The underlying image layers (referenced by the above digests) will ' 'continue to exist.', cancel_on_no=True) # delete and collect output result = [] for tag in tags: self._DeleteDockerTag(tag, digests, http_obj) result.append({'name': six.text_type(tag)}) return result
def testUnknownRepo(self, list_registry, v2_2_registry, v2_registry): repo = 'gcr.io/google-appengine/java-compat' v2_registry.return_value.__enter__.return_value.exists.return_value = False v2_2_registry.return_value.__enter__.return_value.exists.return_value = ( False) list_registry.return_value.__enter__.return_value.exists.return_value = ( False) with self.assertRaisesRegexp( util.InvalidImageNameError, 'Expected tag in the form "base:tag" or "tag" or digest in the form ' '"sha256:<digest>"'): util.GetDigestFromName(repo)
def testRepoV22(self, list_registry, v2_2_registry, v2_registry): repo = 'gcr.io/google-appengine/java-compat' hex_str = '01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b' expected_digest = docker_name.Digest('{repo}@sha256:{hex_str}'.format( repo=repo, hex_str=hex_str)) v2_registry.return_value.__enter__.return_value.exists.return_value = False v2_2_registry.return_value.__enter__.return_value.exists.return_value = True v2_2_registry.return_value.__enter__.return_value.digest.return_value = ( expected_digest.digest) list_registry.return_value.__enter__.return_value.exists.return_value = ( False) digest = util.GetDigestFromName(repo) self.assertEqual(expected_digest, digest)
def Run(self, args): """This is what gets 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: Some value that we want to have printed later. """ img_name = util.GetDigestFromName(args.image) return util.TransformContainerAnalysisData( img_name, args.occurrence_filter)
def Run(self, args): """This is what gets 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: Some value that we want to have printed later. """ with util.WrapExpectedDockerlessErrors(args.image_name): img_name = util.GetDigestFromName(args.image_name) return container_data_util.ContainerData( registry=img_name.registry, repository=img_name.repository, digest=img_name.digest)
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
def Run(self, args): """This is what gets 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: Some value that we want to have printed later. """ filter_kinds = [] if args.show_build_details: filter_kinds.append('BUILD') if args.show_package_vulnerability: filter_kinds.append('VULNERABILITY') filter_kinds.append('DISCOVERY') if args.show_image_basis: filter_kinds.append('IMAGE') if args.show_deployment: filter_kinds.append('DEPLOYMENT') if args.show_all_metadata: filter_kinds = _DEFAULT_KINDS if filter_kinds or args.metadata_filter: f = filter_util.ContainerAnalysisFilter() f.WithKinds(filter_kinds) f.WithCustomFilter(args.metadata_filter) f.WithResources(['https://{}'.format(args.image_name)]) with util.WrapExpectedDockerlessErrors(args.image_name): img_name = util.GetDigestFromName(args.image_name) data = util.TransformContainerAnalysisData(img_name, f) # Clear out fields that weren't asked for and have no data. if (not data.build_details_summary.build_details and not args.show_build_details and not args.show_all_metadata): del data.build_details_summary if (not data.package_vulnerability_summary.vulnerabilities and not args.show_package_vulnerability and not args.show_all_metadata): del data.package_vulnerability_summary if (not data.discovery_summary.discovery and not args.show_package_vulnerability and not args.show_all_metadata): del data.discovery_summary if (not data.image_basis_summary.base_images and not args.show_image_basis and not args.show_all_metadata): del data.image_basis_summary if (not data.deployment_summary.deployments and not args.show_deployment and not args.show_all_metadata): del data.deployment_summary return data else: with util.WrapExpectedDockerlessErrors(args.image_name): img_name = util.GetDigestFromName(args.image_name) return container_data_util.ContainerData( registry=img_name.registry, repository=img_name.repository, digest=img_name.digest)
def Run(self, args): """This is what gets 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: Some value that we want to have printed later. """ filter_kinds = [] if args.show_build_details: filter_kinds.append('BUILD_DETAILS') if args.show_package_vulnerability: filter_kinds.append('PACKAGE_VULNERABILITY') if args.show_image_basis: filter_kinds.append('IMAGE_BASIS') if args.show_deployment: filter_kinds.append('DEPLOYABLE') if args.show_all_metadata: filter_kinds = _DEFAULT_KINDS if filter_kinds or args.metadata_filter: if filter_kinds: filter_from_flags = ' OR '.join( ['kind = "{kind}"'.format(kind=fk) for fk in filter_kinds]) if not args.metadata_filter: occ_filter = filter_from_flags else: occ_filter = '({occf}) AND ({flagf})'.format( occf=args.metadata_filter, flagf=filter_from_flags) else: occ_filter = args.metadata_filter with RecoverFromDiagnosticException(args.image_name): img_name = util.GetDigestFromName(args.image_name) data = util.TransformContainerAnalysisData( img_name, occ_filter, deployments=(args.show_deployment or args.show_all_metadata)) # Clear out fields that weren't asked for and have no data. if (not data.build_details_summary.build_details and not args.show_build_details and not args.show_all_metadata): del data.build_details_summary if (not data.package_vulnerability_summary.vulnerabilities and not args.show_package_vulnerability and not args.show_all_metadata): del data.package_vulnerability_summary if (not data.image_basis_summary.base_images and not args.show_image_basis and not args.show_all_metadata): del data.image_basis_summary if (not data.deployment_summary.deployments and not args.show_deployment and not args.show_all_metadata): del data.deployment_summary return data else: with RecoverFromDiagnosticException(args.image_name): img_name = util.GetDigestFromName(args.image_name) return container_data_util.ContainerData( registry=img_name.registry, repository=img_name.repository, digest=img_name.digest)