Example #1
0
 def ResolveV2Tag(tag):
     with v2_image.FromRegistry(basic_creds=CredentialProvider(),
                                name=tag,
                                transport=http.Http()) as v2_img:
         if v2_img.exists():
             return v2_img.digest()
         return None
Example #2
0
def StringToDigest(string, overrides, transport):
    """Turn a string into a stringified digest."""
    if string in overrides:
        return str(overrides[string])

    # Attempt to turn the string into a tag, this may throw.
    tag = docker_name.Tag(string)

    def fully_qualify_digest(digest):
        return docker_name.Digest('{registry}/{repo}@{digest}'.format(
            registry=tag.registry, repo=tag.repository, digest=digest))

    # Resolve the tag to digest using the standard
    # Docker keychain logic.
    creds = docker_creds.DefaultKeychain.Resolve(tag)
    with v2_2_image.FromRegistry(tag, creds, transport) as img:
        if img.exists():
            digest = fully_qualify_digest(img.digest())
            overrides[string] = digest
            return str(digest)

    # If the tag doesn't exists as v2.2, then try as v2.
    with v2_image.FromRegistry(tag, creds, transport) as img:
        digest = fully_qualify_digest(img.digest())
        overrides[string] = digest
        return str(digest)
Example #3
0
def pulled_image(
    image_reference: str,
    credentials_lookup: typing.Callable[[image_reference, oa.Privileges, bool],
                                        oa.OciConfig],
):
    _tag_or_digest_reference(image_reference)

    transport = _mk_transport_pool()
    image_reference = ou.normalise_image_reference(image_reference)
    image_reference = docker_name.from_string(image_reference)
    creds = _mk_credentials(
        image_reference=image_reference,
        credentials_lookup=credentials_lookup,
    )

    # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
    # Schema 2. We indicate support for both formats by passing both media types
    # as 'Accept' headers.
    #
    # For reference:
    #   OCI: https://github.com/opencontainers/image-spec
    #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
    accept = docker_http.SUPPORTED_MANIFEST_MIMES

    try:
        logger.info(f'Pulling v2.2 image from {image_reference}..')
        with v2_2_image.FromRegistry(image_reference, creds, transport,
                                     accept) as v2_2_img:
            if v2_2_img.exists():
                yield v2_2_img
                return

        # XXX TODO: use streaming rather than writing to local FS
        # if outfile is given, we must use it instead of an ano
        logger.debug(f'Pulling manifest list from {image_reference}..')
        with image_list.FromRegistry(image_reference, creds,
                                     transport) as img_list:
            if img_list.exists():
                platform = image_list.Platform({
                    'architecture': _PROCESSOR_ARCHITECTURE,
                    'os': _OPERATING_SYSTEM,
                })
                # pytype: disable=wrong-arg-types
                with img_list.resolve(platform) as default_child:
                    yield default_child
                    return

        logger.info(f'Pulling v2 image from {image_reference}..')
        with v2_image.FromRegistry(image_reference, creds,
                                   transport) as v2_img:
            if v2_img.exists():
                with v2_compat.V22FromV2(v2_img) as v2_2_img:
                    yield v2_2_img
                    return

        raise om.OciImageNotFoundException(
            f'failed to retrieve {image_reference=} - does it exist?')

    except Exception as e:
        raise e
Example #4
0
def main():
  args = parser.parse_args()

  if not args.name or not args.directory:
    raise Exception('--name and --directory are required arguments.')

  transport = transport_pool.Http(httplib2.Http, size=_THREADS)

  if '@' in args.name:
    name = docker_name.Digest(args.name)
  else:
    name = docker_name.Tag(args.name)

  # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
  # Schema 2. We indicate support for both formats by passing both media types
  # as 'Accept' headers.
  #
  # For reference:
  #   OCI: https://github.com/opencontainers/image-spec
  #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
  accept = docker_http.SUPPORTED_MANIFEST_MIMES

  # Resolve the appropriate credential to use based on the standard Docker
  # client logic.
  creds = docker_creds.DefaultKeychain.Resolve(name)

  with v2_2_image.FromRegistry(name, creds, transport, accept) as v2_2_img:
    if v2_2_img.exists():
      save.fast(v2_2_img, args.directory, threads=_THREADS)
      return

  with v2_image.FromRegistry(name, creds, transport) as v2_img:
    with v2_compat.V22FromV2(v2_img) as v2_2_img:
      save.fast(v2_2_img, args.directory, threads=_THREADS)
      return
Example #5
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)
Example #6
0
def main():
    args = parser.parse_args()

    if not args.name or not args.tarball:
        raise Exception('--name and --tarball are required arguments.')

    transport = transport_pool.Http(httplib2.Http, size=8)

    if '@' in args.name:
        name = docker_name.Digest(args.name)
    else:
        name = docker_name.Tag(args.name)

    # Resolve the appropriate credential to use based on the standard Docker
    # client logic.
    creds = docker_creds.DefaultKeychain.Resolve(name)

    with tarfile.open(name=args.tarball, mode='w') as tar:
        with v2_2_image.FromRegistry(name, creds, transport) as v2_2_img:
            if v2_2_img.exists():
                save.tarball(_make_tag_if_digest(name), v2_2_img, tar)
                return

        with v2_image.FromRegistry(name, creds, transport) as v2_img:
            with v2_compat.V22FromV2(v2_img) as v2_2_img:
                save.tarball(_make_tag_if_digest(name), v2_2_img, tar)
                return
Example #7
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)
def main():
    args = parser.parse_args()

    if not args.name or not args.directory:
        raise Exception('--name and --directory are required arguments.')

    transport = transport_pool.Http(httplib2.Http, size=_THREADS)

    if '@' in args.name:
        name = docker_name.Digest(args.name)
    else:
        name = docker_name.Tag(args.name)

    # Resolve the appropriate credential to use based on the standard Docker
    # client logic.
    creds = docker_creds.DefaultKeychain.Resolve(name)

    with v2_2_image.FromRegistry(name, creds, transport) as v2_2_img:
        if v2_2_img.exists():
            save.fast(v2_2_img, args.directory, threads=_THREADS)
            return

    with v2_image.FromRegistry(name, creds, transport) as v2_img:
        with v2_compat.V22FromV2(v2_img) as v2_2_img:
            save.fast(v2_2_img, args.directory, threads=_THREADS)
            return
Example #9
0
def to_hash_reference(image_name: str):
  transport = _mk_transport(size=1)

  image_name = normalise_image_reference(image_name)
  image_reference = _parse_image_reference(image_name)
  creds = _mk_credentials(image_reference=image_reference)
  accept = docker_http.SUPPORTED_MANIFEST_MIMES

  digest = None

  with image_list.FromRegistry(image_reference, creds, transport) as img_list:
      if img_list.exists():
          digest = img_list.digest()
      else:
          logger.debug('no manifest found')

  # look for image
  with v2_2_image.FromRegistry(image_reference, creds, transport, accept) as v2_2_img:
      if v2_2_img.exists():
          digest = v2_2_img.digest()
      else:
          logger.debug('no img v2.2 found')

  if not digest:
      # fallback to v2
      with v2_image.FromRegistry(image_reference, creds, transport) as v2_img:
          if v2_img.exists():
              digest = v2_img.digest()
          else:
              logger.debug('no img v2 found')
              raise RuntimeError(f'could not access img-metadata for {image_name}')

  name = image_name.rsplit(':', 1)[0]
  return f'{name}@{digest}'
Example #10
0
def _pull_image(image_reference: str, outfileobj=None):
    import ci.util
    ci.util.not_none(image_reference)

    transport = _mk_transport()

    image_reference = normalise_image_reference(image_reference)
    image_reference = _parse_image_reference(image_reference)
    creds = _mk_credentials(image_reference=image_reference)

    # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
    # Schema 2. We indicate support for both formats by passing both media types
    # as 'Accept' headers.
    #
    # For reference:
    #   OCI: https://github.com/opencontainers/image-spec
    #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
    accept = docker_http.SUPPORTED_MANIFEST_MIMES

    try:
        # XXX TODO: use streaming rather than writing to local FS
        # if outfile is given, we must use it instead of an ano
        outfileobj = outfileobj if outfileobj else tempfile.TemporaryFile()
        with tarfile.open(fileobj=outfileobj, mode='w:') as tar:
            ci.util.verbose(f'Pulling manifest list from {image_reference}..')
            with image_list.FromRegistry(image_reference, creds,
                                         transport) as img_list:
                if img_list.exists():
                    platform = image_list.Platform({
                        'architecture': _PROCESSOR_ARCHITECTURE,
                        'os': _OPERATING_SYSTEM,
                    })
                    # pytype: disable=wrong-arg-types
                    with img_list.resolve(platform) as default_child:
                        save.tarball(_make_tag_if_digest(image_reference),
                                     default_child, tar)
                        return outfileobj
                    # pytype: enable=wrong-arg-types

            ci.util.info(f'Pulling v2.2 image from {image_reference}..')
            with v2_2_image.FromRegistry(image_reference, creds, transport,
                                         accept) as v2_2_img:
                if v2_2_img.exists():
                    save.tarball(_make_tag_if_digest(image_reference),
                                 v2_2_img, tar)
                    return outfileobj

            ci.util.info(f'Pulling v2 image from {image_reference}..')
            with v2_image.FromRegistry(image_reference, creds,
                                       transport) as v2_img:
                with v2_compat.V22FromV2(v2_img) as v2_2_img:
                    save.tarball(_make_tag_if_digest(image_reference),
                                 v2_2_img, tar)
                    return outfileobj
    except Exception as e:
        outfileobj.close()
        ci.util.fail(f'Error pulling and saving image {image_reference}: {e}')
Example #11
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)
Example #12
0
def main():
  logging_setup.DefineCommandLineArgs(parser)
  args = parser.parse_args()
  logging_setup.Init(args=args)

  if not args.name or not args.tarball:
    logging.fatal('--name and --tarball are required arguments.')
    sys.exit(1)

  retry_factory = retry.Factory()
  retry_factory = retry_factory.WithSourceTransportCallable(httplib2.Http)
  transport = transport_pool.Http(retry_factory.Build, size=8)

  if '@' in args.name:
    name = docker_name.Digest(args.name)
  else:
    name = docker_name.Tag(args.name)

  # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
  # Schema 2. We indicate support for both formats by passing both media types
  # as 'Accept' headers.
  #
  # For reference:
  #   OCI: https://github.com/opencontainers/image-spec
  #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
  accept = docker_http.SUPPORTED_MANIFEST_MIMES

  # Resolve the appropriate credential to use based on the standard Docker
  # client logic.
  try:
    creds = docker_creds.DefaultKeychain.Resolve(name)
  # pylint: disable=broad-except
  except Exception as e:
    logging.fatal('Error resolving credentials for %s: %s', name, e)
    sys.exit(1)

  try:
    with tarfile.open(name=args.tarball, mode='w') as tar:
      logging.info('Pulling v2.2 image from %r ...', name)
      with v2_2_image.FromRegistry(name, creds, transport, accept) as v2_2_img:
        if v2_2_img.exists():
          save.tarball(_make_tag_if_digest(name), v2_2_img, tar)
          return

      logging.info('Pulling v2 image from %r ...', name)
      with v2_image.FromRegistry(name, creds, transport) as v2_img:
        with v2_compat.V22FromV2(v2_img) as v2_2_img:
          save.tarball(_make_tag_if_digest(name), v2_2_img, tar)
          return
  # pylint: disable=broad-except
  except Exception as e:
    logging.fatal('Error pulling and saving image %s: %s', name, e)
    sys.exit(1)
def main():
    args = parser.parse_args()

    creds = docker_creds.Anonymous()
    transport = transport_pool.Http(httplib2.Http, size=8)

    name = docker_name.Tag(args.name)

    with tarfile.open(name=args.tarball, mode='w') as tar:
        with v2_2_image.FromRegistry(name, creds, transport) as v2_2_img:
            if v2_2_img.exists():
                with v2_compat.V2FromV22(v2_2_img) as v2_img:
                    with v1_compat.V1FromV2(v2_img) as v1_img:
                        v1_image.save(name, v1_img, tar)
                        return

        with v2_image.FromRegistry(name, creds, transport) as v2_img:
            with v1_compat.V1FromV2(v2_img) as v1_img:
                v1_image.save(name, v1_img, tar)
                return
def main():
  logging_setup.DefineCommandLineArgs(parser)
  args = parser.parse_args()
  logging_setup.Init(args=args)

  if not args.name or not args.directory:
    logging.fatal('--name and --directory are required arguments.')

  retry_factory = retry.Factory()
  retry_factory = retry_factory.WithSourceTransportCallable(httplib2.Http)
  transport = transport_pool.Http(retry_factory.Build, size=_THREADS)

  if '@' in args.name:
    name = docker_name.Digest(args.name)
  else:
    name = docker_name.Tag(args.name)

  # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
  # Schema 2. We indicate support for both formats by passing both media types
  # as 'Accept' headers.
  #
  # For reference:
  #   OCI: https://github.com/opencontainers/image-spec
  #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
  accept = docker_http.SUPPORTED_MANIFEST_MIMES

  # Resolve the appropriate credential to use based on the standard Docker
  # client logic.
  try:
    creds = docker_creds.DefaultKeychain.Resolve(name)
  # pylint: disable=broad-except
  except Exception as e:
    logging.fatal('Error resolving credentials for %s: %s', name, e)
    sys.exit(1)

  try:
    logging.info('Pulling manifest list from %r ...', name)
    with image_list.FromRegistry(name, creds, transport) as img_list:
      if img_list.exists():
        platform = image_list.Platform({
            'architecture': _PROCESSOR_ARCHITECTURE,
            'os': _OPERATING_SYSTEM,
        })
        # pytype: disable=wrong-arg-types
        with img_list.resolve(platform) as default_child:
          save.fast(default_child, args.directory, threads=_THREADS)
          return
        # pytype: enable=wrong-arg-types

    logging.info('Pulling v2.2 image from %r ...', name)
    with v2_2_image.FromRegistry(name, creds, transport, accept) as v2_2_img:
      if v2_2_img.exists():
        save.fast(v2_2_img, args.directory, threads=_THREADS)
        return

    logging.info('Pulling v2 image from %r ...', name)
    with v2_image.FromRegistry(name, creds, transport) as v2_img:
      with v2_compat.V22FromV2(v2_img) as v2_2_img:
        save.fast(v2_2_img, args.directory, threads=_THREADS)
        return
  # pylint: disable=broad-except
  except Exception as e:
    logging.fatal('Error pulling and saving image %s: %s', name, e)
    sys.exit(1)
Example #15
0
def main():
    logging_setup.DefineCommandLineArgs(parser)
    args = parser.parse_args()
    logging_setup.Init(args=args)

    # retry if error acc to retry plan
    retry_factory = retry.Factory()
    retry_factory = retry_factory.WithSourceTransportCallable(httplib2.Http)
    transport = transport_pool.Http(retry_factory.Build, size=_THREADS)

    if '@' in args.name:
        name = docker_name.Digest(args.name)
    else:
        name = docker_name.Tag(args.name)

    # If the user provided a client config directory, instruct the keychain
    # resolver to use it to look for the docker client config
    if args.client_config_dir is not None:
        docker_creds.DefaultKeychain.setCustomConfigDir(args.client_config_dir)

    # OCI Image Manifest is compatible with Docker Image Manifest Version 2,
    # Schema 2. We indicate support for both formats by passing both media types
    # as 'Accept' headers.
    #
    # For reference:
    #   OCI: https://github.com/opencontainers/image-spec
    #   Docker: https://docs.docker.com/registry/spec/manifest-v2-2/
    accept = docker_http.SUPPORTED_MANIFEST_MIMES

    # Resolve the appropriate credential to use based on the standard Docker
    # client logic.
    try:
        # check username/paswd match up
        creds = docker_creds.DefaultKeychain.Resolve(name)
    # pylint: disable=broad-except
    except Exception as e:
        logging.fatal('Error resolving credentials for %s: %s', name, e)
        sys.exit(1)

    try:
        logging.info('Pulling manifest list from %r ...', name)
        # (image, [(.sha, tar)])
        with image_list.FromRegistry(name, creds, transport) as img_list:
            if img_list.exists():
                # populate docker_image_list.Platform object (runtime requirements for an object)
                # from the provided args
                # see: docker image manifest list
                platform = platform_args.FromArgs(args)
                # pytype: disable=wrong-arg-types
                with img_list.resolve(platform) as default_child:
                    #
                    save.fast(
                        # create new filesystem (directory) with config files and sha/tars (_save.py)
                        default_child,
                        args.directory,
                        threads=_THREADS,
                        cache_directory=args.cache)
                    return
                # pytype: enable=wrong-arg-types

        logging.info('Pulling v2.2 image from %r ...', name)
        with v2_2_image.FromRegistry(name, creds, transport,
                                     accept) as v2_2_img:
            if v2_2_img.exists():
                save.fast(v2_2_img,
                          args.directory,
                          threads=_THREADS,
                          cache_directory=args.cache)
                return

        logging.info('Pulling v2 image from %r ...', name)
        with v2_image.FromRegistry(name, creds, transport) as v2_img:
            with v2_compat.V22FromV2(v2_img) as v2_2_img:
                save.fast(v2_2_img,
                          args.directory,
                          threads=_THREADS,
                          cache_directory=args.cache)
                return
    # pylint: disable=broad-except
    except Exception as e:
        logging.fatal('Error pulling and saving image %s: %s', name, e)
        sys.exit(1)