Exemple #1
0
 def test_boundary_conditions(self):
     """Ensure that no exception happens in boundary cases"""
     components = app_util.validate_and_transform_repo_name('tags')
     self.assertEqual(components, ('', 'tags', 'tags'))
     components = app_util.validate_and_transform_repo_name('tags/')
     self.assertEqual(components, ('', 'tags/', 'tags'))
     components = app_util.validate_and_transform_repo_name('/tags')
     self.assertEqual(components, ('', 'tags', 'tags'))
Exemple #2
0
 def test_boundary_conditions(self):
     """Ensure that no exception happens in boundary cases"""
     components = app_util.validate_and_transform_repo_name('tags')
     self.assertEqual(components, ('', 'tags', 'tags'))
     components = app_util.validate_and_transform_repo_name('tags/')
     self.assertEqual(components, ('', 'tags/', 'tags'))
     components = app_util.validate_and_transform_repo_name('/tags')
     self.assertEqual(components, ('', 'tags', 'tags'))
Exemple #3
0
def name_redirect(name, file_path):
    """
    Redirects the client to the path from where the file can be accessed.

    :param name:    name of the repository. The combination of username and repo specifies
                    a repo id
    :type  name:    basestring

    :param file_path: the relative path
    :type file_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """

    # name, repo_name, path = app_util.validate_and_transform_repo_name(username, repo, file_path)
    full_path = '/'.join([name, file_path])

    name_component, path_component = app_util.validate_and_transform_repo_name(
        full_path)
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'
    url = base_url + path_component
    return redirect(url)
Exemple #4
0
def name_redirect(relative_path):
    """
    Redirects the client to the path from where the file can be accessed.

    :param relative_path: the relative path after /v2/.
    :type relative_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """
    name_component, path_component = app_util.validate_and_transform_repo_name(relative_path)
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'

    schema2_data = repository.get_schema2_data_for_repo(name_component)

    if 'manifests' in path_component and schema2_data is not None:
        manifest_list_data = repository.get_manifest_list_data_for_repo(name_component)
        manifest_list_amd64_tags = repository.get_manifest_list_amd64_for_repo(name_component)
        if schema2_data:
            schema2_data = json.loads(schema2_data)
        if manifest_list_data:
            manifest_list_data = json.loads(manifest_list_data)
        if manifest_list_amd64_tags:
            manifest_list_amd64_tags = json.loads(manifest_list_amd64_tags)
        manifest, identifier = path_component.split('/')
        if schema2_data or manifest_list_data:
            # if it is a newer docker client it sets accept headers to manifest schema 1, 2 and list
            # if it is an older docker client, he doesnot set any of accept headers
            accept_headers = request.headers.get('Accept')
            schema2_mediatype = 'application/vnd.docker.distribution.manifest.v2+json'
            manifest_list_mediatype = 'application/vnd.docker.distribution.manifest.list.v2+json'
            # check first manifest list type
            if manifest_list_mediatype in accept_headers and identifier in manifest_list_data:
                path_component = os.path.join(manifest, 'list', identifier)
            # this is needed for older clients which do not understand manifest list
            elif identifier in manifest_list_amd64_tags.keys():
                if schema2_mediatype in accept_headers:
                    path_component = os.path.join(
                        manifest, str(manifest_list_amd64_tags[identifier][1]),
                        manifest_list_amd64_tags[identifier][0])
                elif manifest_list_amd64_tags[identifier][1] == 1:
                    path_component = os.path.join(
                        manifest, '1', manifest_list_amd64_tags[identifier][0])
                # this is needed in case when there is no amd64 image manifest, but there are within
                # one repo manifest list and image manifest with the same tag
                else:
                    path_component = os.path.join(manifest, '1', identifier)
            elif schema2_mediatype in accept_headers and identifier in schema2_data:
                path_component = os.path.join(manifest, '2', identifier)
            else:
                path_component = os.path.join(manifest, '1', identifier)
        # this is needed for V3Repo which do not have schema2 manifests
        else:
            path_component = os.path.join(manifest, '1', identifier)
    url = base_url + path_component
    return redirect(url)
Exemple #5
0
 def test_funny_image_names(self):
     for image_name in ['tags', 'manifests', 'blobs']:
         for component_type in ['tags', 'manifests', 'blobs']:
             full_path = 'redhat/%s/%s/latest' % (image_name, component_type)
             name, path, component = app_util.validate_and_transform_repo_name(full_path)
             msg = 'Full path: ' + full_path
             self.assertEqual(name, 'redhat/' + image_name, msg=msg)
             self.assertEqual(path, component_type + '/latest', msg=msg)
             self.assertEqual(component, component_type, msg=msg)
Exemple #6
0
 def test_funny_image_names(self):
     for image_name in ['tags', 'manifests', 'blobs']:
         for component_type in ['tags', 'manifests', 'blobs']:
             full_path = 'redhat/%s/%s/latest' % (image_name,
                                                  component_type)
             name, path, component = app_util.validate_and_transform_repo_name(
                 full_path)
             msg = 'Full path: ' + full_path
             self.assertEqual(name, 'redhat/' + image_name, msg=msg)
             self.assertEqual(path, component_type + '/latest', msg=msg)
             self.assertEqual(component, component_type, msg=msg)
Exemple #7
0
def name_redirect(relative_path):
    """
    Redirects the client to the path from where the file can be accessed.

    :param relative_path: the relative path after /v2/.
    :type relative_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """
    name_component, path_component = app_util.validate_and_transform_repo_name(relative_path)
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'
    url = base_url + path_component
    return redirect(url)
Exemple #8
0
def name_redirect(name, file_path):
    """
    Redirects the client to the path from where the file can be accessed.

    :param name:    name of the repository. The combination of username and repo specifies
                    a repo id
    :type  name:    basestring

    :param file_path: the relative path
    :type file_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """

    # name, repo_name, path = app_util.validate_and_transform_repo_name(username, repo, file_path)
    full_path = '/'.join([name, file_path])

    name_component, path_component = app_util.validate_and_transform_repo_name(full_path)
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'
    url = base_url + path_component
    return redirect(url)
Exemple #9
0
 def test_path_without_tags_or_manifest_or_blobs(self):
     with self.assertRaises(exceptions.HTTPError) as assertion:
         app_util.validate_and_transform_repo_name('redhat/rhel7.0/unknown/latest')
     self.assertEquals(assertion.exception.status_code, httplib.NOT_FOUND)
Exemple #10
0
 def test_normal(self):
     name, path, component = app_util.validate_and_transform_repo_name('redhat/rhel7.0/tags/latest') # noqa
     self.assertEqual(name, 'redhat/rhel7.0')
     self.assertEqual(path, 'tags/latest')
     self.assertEqual(component, 'tags')
Exemple #11
0
 def test_path_without_tags_or_manifest_or_blobs(self):
     with self.assertRaises(exceptions.HTTPError) as assertion:
         app_util.validate_and_transform_repo_name(
             'redhat/rhel7.0/unknown/latest')
     self.assertEquals(assertion.exception.status_code, httplib.NOT_FOUND)
Exemple #12
0
 def test_normal(self):
     name, path = app_util.validate_and_transform_repo_name(
         'redhat/rhel7.0/tags/latest')
     self.assertEqual(name, 'redhat/rhel7.0')
     self.assertEqual(path, 'tags/latest')
Exemple #13
0
Fichier : v2.py Projet : pulp/crane
def name_serve_or_redirect(relative_path):
    """
    Redirects the client to the path from where the file can be accessed.
    If 'serve_content' is set to true use send_file to provide the requested file directly,
    taking into account the 'content_dir_v2' parameter.

    :param relative_path: the relative path after /v2/.
    :type relative_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """
    components = app_util.validate_and_transform_repo_name(relative_path)
    name_component, path_component, component_type = components
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'
    schema2_data = repository.get_schema2_data_for_repo(name_component)
    used_mediatype = 'application/json' if component_type != 'blobs' else 'application/octet-stream'

    if component_type == 'manifests' and schema2_data is not None:
        manifest_list_data = repository.get_manifest_list_data_for_repo(name_component)
        manifest_list_amd64_tags = repository.get_manifest_list_amd64_for_repo(name_component)
        if schema2_data:
            schema2_data = json.loads(schema2_data)
        if manifest_list_data:
            manifest_list_data = json.loads(manifest_list_data)
        if manifest_list_amd64_tags:
            manifest_list_amd64_tags = json.loads(manifest_list_amd64_tags)
        manifest, identifier = path_component.split('/')
        if schema2_data or manifest_list_data:
            # if it is a newer docker client it sets accept headers to manifest schema 1, 2 and list
            # if it is an older docker client, he doesnot set any of accept headers
            accept_headers = get_accept_headers(request)
            schema2_mediatype = 'application/vnd.docker.distribution.manifest.v2+json'
            manifest_list_mediatype = 'application/vnd.docker.distribution.manifest.list.v2+json'
            # check first manifest list type
            if manifest_list_mediatype in accept_headers and identifier in manifest_list_data:
                path_component = os.path.join(manifest, 'list', identifier)
                used_mediatype = manifest_list_mediatype
            # this is needed for older clients which do not understand manifest list
            elif identifier in manifest_list_amd64_tags.keys():
                if schema2_mediatype in accept_headers:
                    schema_version = manifest_list_amd64_tags[identifier][1]
                    if schema_version == 2:
                        used_mediatype = schema2_mediatype
                    path_component = os.path.join(
                        manifest, str(schema_version),
                        manifest_list_amd64_tags[identifier][0])
                elif manifest_list_amd64_tags[identifier][1] == 1:
                    path_component = os.path.join(
                        manifest, '1', manifest_list_amd64_tags[identifier][0])
                # this is needed in case when there is no amd64 image manifest, but there are within
                # one repo manifest list and image manifest with the same tag
                else:
                    path_component = os.path.join(manifest, '1', identifier)
            elif schema2_mediatype in accept_headers and identifier in schema2_data:
                path_component = os.path.join(manifest, '2', identifier)
                used_mediatype = schema2_mediatype
            else:
                path_component = os.path.join(manifest, '1', identifier)
        # this is needed for V3Repo which do not have schema2 manifests
        else:
            path_component = os.path.join(manifest, '1', identifier)

    serve_content = current_app.config.get(config.KEY_SC_ENABLE)
    if serve_content:
        base_path = current_app.config.get(config.KEY_SC_CONTENT_DIR_V2)
        repo_name = repository.get_pulp_repository_name(name_component)
        result = os.path.join(base_path, repo_name, path_component)

        try:
            return send_file(result, mimetype=used_mediatype,
                             add_etags=False)
        except OSError:
            raise exceptions.HTTPError(httplib.NOT_FOUND)
    else:
        url = base_url + path_component

        # perform CDN rewrites and auth
        url = cdn_rewrite_redirect_url(url)
        url = cdn_auth_token_url(url)
        return redirect(url)
Exemple #14
0
def name_serve_or_redirect(relative_path):
    """
    Redirects the client to the path from where the file can be accessed.
    If 'serve_content' is set to true use send_file to provide the requested file directly,
    taking into account the 'content_dir_v2' parameter.

    :param relative_path: the relative path after /v2/.
    :type relative_path:  basestring

    :return:    302 redirect response
    :rtype:     flask.Response
    """
    components = app_util.validate_and_transform_repo_name(relative_path)
    name_component, path_component, component_type = components
    base_url = repository.get_path_for_repo(name_component)
    if not base_url.endswith('/'):
        base_url += '/'
    schema2_data = repository.get_schema2_data_for_repo(name_component)
    used_mediatype = 'application/json' if component_type != 'blobs' else 'application/octet-stream'

    if component_type == 'manifests' and schema2_data is not None:
        manifest_list_data = repository.get_manifest_list_data_for_repo(
            name_component)
        manifest_list_amd64_tags = repository.get_manifest_list_amd64_for_repo(
            name_component)
        if schema2_data:
            schema2_data = json.loads(schema2_data)
        if manifest_list_data:
            manifest_list_data = json.loads(manifest_list_data)
        if manifest_list_amd64_tags:
            manifest_list_amd64_tags = json.loads(manifest_list_amd64_tags)
        manifest, identifier = path_component.split('/')
        if schema2_data or manifest_list_data:
            # if it is a newer docker client it sets accept headers to manifest schema 1, 2 and list
            # if it is an older docker client, he doesnot set any of accept headers
            accept_headers = get_accept_headers(request)
            schema2_mediatype = 'application/vnd.docker.distribution.manifest.v2+json'
            manifest_list_mediatype = 'application/vnd.docker.distribution.manifest.list.v2+json'
            # check first manifest list type
            if manifest_list_mediatype in accept_headers and identifier in manifest_list_data:
                path_component = os.path.join(manifest, 'list', identifier)
                used_mediatype = manifest_list_mediatype
            # this is needed for older clients which do not understand manifest list
            elif identifier in manifest_list_amd64_tags.keys():
                if schema2_mediatype in accept_headers:
                    schema_version = manifest_list_amd64_tags[identifier][1]
                    if schema_version == 2:
                        used_mediatype = schema2_mediatype
                    path_component = os.path.join(
                        manifest, str(schema_version),
                        manifest_list_amd64_tags[identifier][0])
                elif manifest_list_amd64_tags[identifier][1] == 1:
                    path_component = os.path.join(
                        manifest, '1', manifest_list_amd64_tags[identifier][0])
                # this is needed in case when there is no amd64 image manifest, but there are within
                # one repo manifest list and image manifest with the same tag
                else:
                    path_component = os.path.join(manifest, '1', identifier)
            elif schema2_mediatype in accept_headers and identifier in schema2_data:
                path_component = os.path.join(manifest, '2', identifier)
                used_mediatype = schema2_mediatype
            else:
                path_component = os.path.join(manifest, '1', identifier)
        # this is needed for V3Repo which do not have schema2 manifests
        else:
            path_component = os.path.join(manifest, '1', identifier)

    serve_content = current_app.config.get(config.KEY_SC_ENABLE)
    if serve_content:
        base_path = current_app.config.get(config.KEY_SC_CONTENT_DIR_V2)
        repo_name = repository.get_pulp_repository_name(name_component)
        result = os.path.join(base_path, repo_name, path_component)

        try:
            return send_file(result, mimetype=used_mediatype, add_etags=False)
        except OSError:
            raise exceptions.HTTPError(httplib.NOT_FOUND)
    else:
        url = base_url + path_component

        # perform CDN rewrites and auth
        url = cdn_rewrite_redirect_url(url)
        url = cdn_auth_token_url(url)
        return redirect(url)