Exemple #1
0
  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.
    """

    repository = util.ValidateRepositoryPath(args.image)
    http_obj = http.Http()
    with docker_image.FromRegistry(
        basic_creds=util.CredentialProvider(),
        name=repository,
        transport=http_obj) as image:
      try:
        return util.TransformManifests(
            image.manifests(),
            repository,
            show_occurrences=args.show_occurrences,
            occurrence_filter=args.occurrence_filter)
      except docker_http.V2DiagnosticException as err:
        raise util.GcloudifyRecoverableV2Errors(err, {
            403: 'Access denied: {0}'.format(repository),
            404: 'Not found: {0}'.format(repository)
        })
Exemple #2
0
def ImageDigestForContainerImage(name, tag):
  """Given a container image and tag, returns the digest for that image version.

  Args:
    name: the gcr.io registry name plus the image name
    tag: the image tag

  Returns:
    The digest of the image, or None if there is no such image.

  Raises:
    googlecloudsdk.core.UnsupportedRegistryError: If the path is valid,
      but belongs to an unsupported registry.
    i_util.InvalidImageNameError: If the image name is invalid.
    i_util.TokenRefreshError: If there is an error refreshing credentials
      needed to access the GCR repo.
    i_util.UserRecoverableV2Error: If a user-recoverable error occurs accessing
      the GCR repo.
  """

  def _TaggedImage():
    """Display the fully-qualified name."""
    return '{}:{}'.format(name, tag)

  name = i_util.ValidateRepositoryPath(name)
  with i_util.WrapExpectedDockerlessErrors(name):
    with docker_image.FromRegistry(
        basic_creds=i_util.CredentialProvider(),
        name=docker_name.Tag(_TaggedImage()),
        transport=http.Http()) as r:
      return r.digest()
Exemple #3
0
    def Run(self, args):
        def Push(image, dest_name, creds, http_obj, src_name,
                 session_push_type):
            with session_push_type(dest_name, creds, http_obj) as push:
                push.upload(image)
                log.CreatedResource(dest_name)
            log.UpdatedResource(src_name)

        http_obj = http.Http()

        src_name = util.GetDockerImageFromTagOrDigest(args.src_image)
        dest_name = docker_name.Tag(args.dest_image)

        console_io.PromptContinue('This will tag {0} with {1}'.format(
            src_name, dest_name),
                                  default=True,
                                  cancel_on_no=True)
        creds = util.CredentialProvider()

        with v2_2_image.FromRegistry(src_name, creds, http_obj) as v2_2_img:
            if v2_2_img.exists():
                Push(v2_2_img, dest_name, creds, http_obj, src_name,
                     v2_2_session.Push)
                return

        with v2_image.FromRegistry(src_name, creds, http_obj) as v2_img:
            Push(v2_img, dest_name, creds, http_obj, src_name, v2_session.Push)
Exemple #4
0
    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.

    Returns:
      Some value that we want to have printed later.
    """
        repository_arg = args.repository
        if not repository_arg:
            repository_arg = 'gcr.io/{0}'.format(
                properties.VALUES.core.project.Get(required=True))

        # Throws if invalid.
        repository = util.ValidateRepositoryPath(repository_arg)

        def _DisplayName(c):
            """Display the fully-qualified name."""
            return '{0}/{1}'.format(repository, c)

        http_obj = http.Http()
        with docker_image.FromRegistry(basic_creds=util.CredentialProvider(),
                                       name=repository,
                                       transport=http_obj) as r:
            images = [{'name': _DisplayName(c)} for c in r.children()]
            return images
 def _DeleteDockerTag(self, tag, digests, http_obj):
     # calling Delete on an image referenced by tag only deletes the tag
     docker_session.Delete(creds=util.CredentialProvider(),
                           name=tag,
                           transport=http_obj)
     log.DeletedResource('[{tag}] (referencing [{digest}])'.format(
         tag=tag, digest=digests[tag]))
Exemple #6
0
    def Run(self, args):
        # pylint: disable=missing-docstring
        def Push(image, dest_name, creds, http_obj, src_name,
                 session_push_type):
            try:
                with session_push_type(dest_name, creds, http_obj) as push:
                    push.upload(image)
                    log.CreatedResource(dest_name)
                log.UpdatedResource(src_name)
            except docker_http.V2DiagnosticException as err:
                raise util.GcloudifyRecoverableV2Errors(
                    err, {
                        403:
                        'Tagging failed, access denied: {0}'.format(dest_name)
                    })

        http_obj = http.Http()

        src_name = util.GetDockerImageFromTagOrDigest(args.src_image)
        dest_name = docker_name.Tag(args.dest_image)

        console_io.PromptContinue('This will tag {0} with {1}'.format(
            src_name, dest_name),
                                  default=True,
                                  cancel_on_no=True)
        creds = util.CredentialProvider()

        with v2_2_image.FromRegistry(src_name, creds, http_obj) as v2_2_img:
            if v2_2_img.exists():
                Push(v2_2_img, dest_name, creds, http_obj, src_name,
                     v2_2_session.Push)
                return

        with v2_image.FromRegistry(src_name, creds, http_obj) as v2_img:
            Push(v2_img, dest_name, creds, http_obj, src_name, v2_session.Push)
Exemple #7
0
 def _DeleteDockerTagOrDigest(self, tag_or_digest, http_obj):
     try:
         docker_session.Delete(creds=util.CredentialProvider(),
                               name=tag_or_digest,
                               transport=http_obj)
         log.DeletedResource(tag_or_digest)
     except docker_http.V2DiagnosticException as err:
         raise self._MapDeleteErr(err, tag_or_digest)
Exemple #8
0
 def _DeleteDigestAndAssociatedTags(self, digest, http_obj):
     # digest must not have any tags in order to be deleted
     util.DeleteTagsFromDigest(digest, http_obj)
     tag_list = util.GetTagNamesForDigest(digest, http_obj)
     for tag in tag_list:
         log.DeletedResource(tag)
     docker_session.Delete(creds=util.CredentialProvider(),
                           name=digest,
                           transport=http_obj)
     log.DeletedResource(digest)
Exemple #9
0
    def Run(self, args):
        # pylint: disable=missing-docstring
        def Push(image, dest_names, creds, http_obj, src_name,
                 session_push_type):
            for dest_name in dest_names:
                with session_push_type(dest_name, creds, http_obj) as push:
                    push.upload(image)
                    log.CreatedResource(dest_name)
            log.UpdatedResource(src_name)

        http_obj = http.Http()

        src_name = util.GetDockerImageFromTagOrDigest(args.src_image)

        dest_names = []
        for dest_image in args.dest_image:
            try:
                dest_name = docker_name.Tag(dest_image)
            except docker_name.BadNameException as e:
                raise util.InvalidImageNameError(six.text_type(e))

            if '/' not in dest_name.repository:
                raise exceptions.Error(
                    'Pushing to project root-level images is disabled. '
                    'Please designate an image within a project, '
                    'e.g. gcr.io/project-id/my-image:tag')
            dest_names.append(dest_name)

        console_io.PromptContinue('This will tag {} with:\n{}'.format(
            src_name,
            '\n'.join(six.text_type(dest_name) for dest_name in dest_names)),
                                  default=True,
                                  cancel_on_no=True)
        creds = util.CredentialProvider()
        with util.WrapExpectedDockerlessErrors():
            with docker_image_list.FromRegistry(src_name, creds,
                                                http_obj) as manifest_list:
                if manifest_list.exists():
                    Push(manifest_list, dest_names, creds, http_obj, src_name,
                         v2_2_session.Push)
                    return

            with v2_2_image.FromRegistry(src_name,
                                         creds,
                                         http_obj,
                                         accepted_mimes=docker_http.
                                         SUPPORTED_MANIFEST_MIMES) as v2_2_img:
                if v2_2_img.exists():
                    Push(v2_2_img, dest_names, creds, http_obj, src_name,
                         v2_2_session.Push)
                    return

            with v2_image.FromRegistry(src_name, creds, http_obj) as v2_img:
                Push(v2_img, dest_names, creds, http_obj, src_name,
                     v2_session.Push)
Exemple #10
0
    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.

    Returns:
      Some value that we want to have printed later.

    Raises:
      exceptions.Error: If the repository could not be found, or access was
      denied.
      docker_http.V2DiagnosticException: Any other error occurred while
      accessing GCR.
    """
        repository_arg = args.repository
        self._epilog = None
        if not repository_arg:
            project_id = properties.VALUES.core.project.Get(required=True)
            # Handle domain-scoped projects...
            project_id = project_id.replace(':', '/', 1)
            repository_arg = 'gcr.io/{0}'.format(project_id)
            self._epilog = 'Only listing images in {0}. '.format(
                repository_arg)
            self._epilog += 'Use --repository to list images in other repositories.'

        # Throws if invalid.
        repository = util.ValidateRepositoryPath(repository_arg)

        def _DisplayName(c):
            """Display the fully-qualified name."""
            return '{0}/{1}'.format(repository, c)

        http_obj = http.Http()
        try:
            with docker_image.FromRegistry(
                    basic_creds=util.CredentialProvider(),
                    name=repository,
                    transport=http_obj) as r:
                try:
                    images = [{'name': _DisplayName(c)} for c in r.children()]
                    return images
                except docker_http.V2DiagnosticException as err:
                    if err.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
                        raise exceptions.Error(
                            'Access denied: {0}'.format(repository))
                    elif err.status == httplib.NOT_FOUND:
                        raise exceptions.Error(
                            'Not found: {0}'.format(repository))
                    else:
                        raise
        except docker_http.BadStateException as e:
            raise exceptions.Error(e)
Exemple #11
0
    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:
      ArgumentError: If the user provided the flag --show-occurrences-from but
        --show-occurrences=False.
      InvalidImageNameError: If the user specified an invalid image name.
    Returns:
      Some value that we want to have printed later.
    """
        # Verify that --show-occurrences-from is set iff --show-occurrences=True.
        if args.IsSpecified(
                'show_occurrences_from') and not args.show_occurrences:
            raise ArgumentError(
                '--show-occurrences-from may only be set if --show-occurrences=True'
            )

        repository = util.ValidateRepositoryPath(args.image_name)
        http_obj = http.Http()
        with docker_image.FromRegistry(basic_creds=util.CredentialProvider(),
                                       name=repository,
                                       transport=http_obj) as image:
            try:
                manifests = image.manifests()
                # Only consider the top _DEFAULT_SHOW_OCCURRENCES_FROM images
                # to reduce computation time.
                most_recent_resource_urls = None
                if args.show_occurrences_from:
                    # This block is skipped when the user provided
                    # --show-occurrences-from=unlimited on the CLI.
                    most_recent_resource_urls = [
                        'https://%s@%s' % (args.image_name, k)
                        for k in heapq.nlargest(
                            args.show_occurrences_from,
                            manifests,
                            key=lambda k: manifests[k]['timeCreatedMs'])
                    ]
                return util.TransformManifests(
                    manifests,
                    repository,
                    show_occurrences=args.show_occurrences,
                    occurrence_filter=args.occurrence_filter,
                    resource_urls=most_recent_resource_urls)
            except docker_http.V2DiagnosticException as err:
                raise util.GcloudifyRecoverableV2Errors(
                    err, {
                        403: 'Access denied: {0}'.format(repository),
                        404: 'Not found: {0}'.format(repository)
                    })
Exemple #12
0
    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:
      ArgumentError: If the user provided the flag --show-occurrences-from but
        --show-occurrences=False.
      InvalidImageNameError: If the user specified an invalid image name.
    Returns:
      Some value that we want to have printed later.
    """
        # Verify that --show-occurrences-from is set iff --show-occurrences=True.
        if args.IsSpecified(
                'show_occurrences_from') and not args.show_occurrences:
            raise ArgumentError(
                '--show-occurrences-from may only be set if --show-occurrences=True'
            )

        repository = util.ValidateRepositoryPath(args.image_name)
        http_obj = http.Http()
        with util.WrapExpectedDockerlessErrors(repository):
            with docker_image.FromRegistry(
                    basic_creds=util.CredentialProvider(),
                    name=repository,
                    transport=http_obj) as image:
                manifests = image.manifests()
                # Only consider the top _DEFAULT_SHOW_OCCURRENCES_FROM images
                # to reduce computation time.
                most_recent_resource_urls = None
                occ_filter = filter_util.ContainerAnalysisFilter()
                occ_filter.WithCustomFilter(args.occurrence_filter)
                occ_filter.WithResourcePrefix('https://{}'.format(repository))
                if args.show_occurrences_from:
                    # This block is skipped when the user provided
                    # --show-occurrences-from=unlimited on the CLI.
                    most_recent_resource_urls = [
                        'https://%s@%s' % (args.image_name, k)
                        for k in heapq.nlargest(
                            args.show_occurrences_from,
                            manifests,
                            key=lambda k: manifests[k]['timeCreatedMs'])
                    ]
                    occ_filter.WithResources(most_recent_resource_urls)
                return util.TransformManifests(
                    manifests,
                    repository,
                    show_occurrences=args.show_occurrences,
                    occurrence_filter=occ_filter)
Exemple #13
0
  def _DeleteDigestAndAssociatedTags(self, digest, http_obj):
    # Digest must not have any tags in order to be deleted.
    # Errors raised from tag deletion are deliberately uncaught.
    util.DeleteTagsFromDigest(digest, http_obj)
    tag_list = util.GetTagNamesForDigest(digest, http_obj)
    for tag in tag_list:
      log.DeletedResource(tag)

    try:
      docker_session.Delete(
          creds=util.CredentialProvider(), name=digest, transport=http_obj)
      log.DeletedResource(digest)
    except docker_http.V2DiagnosticException as err:
      raise self._MapDeleteErr(err, digest)
Exemple #14
0
    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.
    """
        repository = util.ValidateRepositoryPath(args.image_name)
        http_obj = http.Http()
        with util.WrapExpectedDockerlessErrors(repository):
            with docker_image.FromRegistry(
                    basic_creds=util.CredentialProvider(),
                    name=repository,
                    transport=http_obj) as image:
                manifests = image.manifests()
                return util.TransformManifests(manifests, repository)
Exemple #15
0
 def _DeleteDockerTagOrDigest(self, tag_or_digest, http_obj):
     docker_session.Delete(creds=util.CredentialProvider(),
                           name=tag_or_digest,
                           transport=http_obj)
     log.DeletedResource(tag_or_digest)