Merge pull request #2465 from coreos-inc/force_push
Allow force push for app
This commit is contained in:
commit
0ce68706ee
4 changed files with 53 additions and 55 deletions
|
@ -350,7 +350,7 @@ class OCIAppModel(AppRegistryDataInterface):
|
||||||
repo_kind='application')
|
repo_kind='application')
|
||||||
tag_name = package.release
|
tag_name = package.release
|
||||||
oci_model.release.create_app_release(repo, tag_name, package.manifest(),
|
oci_model.release.create_app_release(repo, tag_name, package.manifest(),
|
||||||
data['content']['digest'])
|
data['content']['digest'], force)
|
||||||
|
|
||||||
def delete_release(self, package_name, release, media_type):
|
def delete_release(self, package_name, release, media_type):
|
||||||
""" Remove/Delete an app-release from an app-repository.
|
""" Remove/Delete an app-release from an app-repository.
|
||||||
|
|
|
@ -32,55 +32,6 @@ def get_app_release(repo, tag_name, media_type):
|
||||||
return (tag, manifest, blob)
|
return (tag, manifest, blob)
|
||||||
|
|
||||||
|
|
||||||
def create_app_release(repo, tag_name, manifest, digest):
|
|
||||||
""" Create a new application release, it includes creating a new Tag, ManifestList,
|
|
||||||
ManifestListManifests, Manifest, ManifestBlob.
|
|
||||||
|
|
||||||
To deduplicate the ManifestList, the manifestlist_json is kept ordered by the manifest.id.
|
|
||||||
To find the insert point in the ManifestList it uses bisect on the manifest-ids list.
|
|
||||||
"""
|
|
||||||
with db_transaction():
|
|
||||||
# Create/get the package manifest
|
|
||||||
manifest = manifest_model.get_or_create_manifest(manifest, manifest['mediaType'])
|
|
||||||
# get the tag
|
|
||||||
tag = tag_model.get_or_initialize_tag(repo, tag_name)
|
|
||||||
|
|
||||||
if tag.manifest_list is None:
|
|
||||||
tag.manifest_list = ManifestList(media_type=ManifestList.media_type.get_id(LIST_MEDIA_TYPE),
|
|
||||||
schema_version=SCHEMA_VERSION,
|
|
||||||
manifest_list_json=[])
|
|
||||||
|
|
||||||
elif tag_model.tag_media_type_exists(tag, manifest.media_type):
|
|
||||||
raise PackageAlreadyExists("package exists already")
|
|
||||||
|
|
||||||
list_json = tag.manifest_list.manifest_list_json
|
|
||||||
mlm_query = (ManifestListManifest
|
|
||||||
.select()
|
|
||||||
.where(ManifestListManifest.manifest_list == tag.manifest_list))
|
|
||||||
list_manifest_ids = sorted([mlm.manifest_id for mlm in mlm_query])
|
|
||||||
insert_point = bisect.bisect_left(list_manifest_ids, manifest.id)
|
|
||||||
list_json.insert(insert_point, manifest.manifest_json)
|
|
||||||
list_manifest_ids.insert(insert_point, manifest.id)
|
|
||||||
manifestlist = manifest_list_model.get_or_create_manifest_list(list_json, LIST_MEDIA_TYPE,
|
|
||||||
SCHEMA_VERSION)
|
|
||||||
manifest_list_model.create_manifestlistmanifest(manifestlist, list_manifest_ids, list_json)
|
|
||||||
|
|
||||||
tag = tag_model.create_or_update_tag(repo, tag_name, manifest_list=manifestlist,
|
|
||||||
tag_kind="release")
|
|
||||||
blob_digest = digest
|
|
||||||
|
|
||||||
try:
|
|
||||||
(ManifestBlob
|
|
||||||
.select()
|
|
||||||
.join(Blob)
|
|
||||||
.where(ManifestBlob.manifest == manifest,
|
|
||||||
Blob.digest == _ensure_sha256_header(blob_digest)).get())
|
|
||||||
except ManifestBlob.DoesNotExist:
|
|
||||||
blob = blob_model.get_blob(blob_digest)
|
|
||||||
ManifestBlob.create(manifest=manifest, blob=blob)
|
|
||||||
return tag
|
|
||||||
|
|
||||||
|
|
||||||
def delete_app_release(repo, tag_name, media_type):
|
def delete_app_release(repo, tag_name, media_type):
|
||||||
""" Delete a Tag/media-type couple """
|
""" Delete a Tag/media-type couple """
|
||||||
media_type_id = ManifestListManifest.media_type.get_id(manifest_media_type(media_type))
|
media_type_id = ManifestListManifest.media_type.get_id(manifest_media_type(media_type))
|
||||||
|
@ -114,6 +65,58 @@ def delete_app_release(repo, tag_name, media_type):
|
||||||
return tag
|
return tag
|
||||||
|
|
||||||
|
|
||||||
|
def create_app_release(repo, tag_name, manifest, digest, force=False):
|
||||||
|
""" Create a new application release, it includes creating a new Tag, ManifestList,
|
||||||
|
ManifestListManifests, Manifest, ManifestBlob.
|
||||||
|
|
||||||
|
To deduplicate the ManifestList, the manifestlist_json is kept ordered by the manifest.id.
|
||||||
|
To find the insert point in the ManifestList it uses bisect on the manifest-ids list.
|
||||||
|
"""
|
||||||
|
with db_transaction():
|
||||||
|
# Create/get the package manifest
|
||||||
|
manifest = manifest_model.get_or_create_manifest(manifest, manifest['mediaType'])
|
||||||
|
# get the tag
|
||||||
|
tag = tag_model.get_or_initialize_tag(repo, tag_name)
|
||||||
|
|
||||||
|
if tag.manifest_list is None:
|
||||||
|
tag.manifest_list = ManifestList(media_type=ManifestList.media_type.get_id(LIST_MEDIA_TYPE),
|
||||||
|
schema_version=SCHEMA_VERSION,
|
||||||
|
manifest_list_json=[])
|
||||||
|
|
||||||
|
elif tag_model.tag_media_type_exists(tag, manifest.media_type):
|
||||||
|
if force:
|
||||||
|
delete_app_release(repo, tag_name, manifest.media_type.name)
|
||||||
|
else:
|
||||||
|
raise PackageAlreadyExists("package exists already")
|
||||||
|
|
||||||
|
list_json = tag.manifest_list.manifest_list_json
|
||||||
|
mlm_query = (ManifestListManifest
|
||||||
|
.select()
|
||||||
|
.where(ManifestListManifest.manifest_list == tag.manifest_list))
|
||||||
|
list_manifest_ids = sorted([mlm.manifest_id for mlm in mlm_query])
|
||||||
|
insert_point = bisect.bisect_left(list_manifest_ids, manifest.id)
|
||||||
|
list_json.insert(insert_point, manifest.manifest_json)
|
||||||
|
list_manifest_ids.insert(insert_point, manifest.id)
|
||||||
|
manifestlist = manifest_list_model.get_or_create_manifest_list(list_json, LIST_MEDIA_TYPE,
|
||||||
|
SCHEMA_VERSION)
|
||||||
|
manifest_list_model.create_manifestlistmanifest(manifestlist, list_manifest_ids, list_json)
|
||||||
|
|
||||||
|
tag = tag_model.create_or_update_tag(repo, tag_name, manifest_list=manifestlist,
|
||||||
|
tag_kind="release")
|
||||||
|
blob_digest = digest
|
||||||
|
|
||||||
|
try:
|
||||||
|
(ManifestBlob
|
||||||
|
.select()
|
||||||
|
.join(Blob)
|
||||||
|
.where(ManifestBlob.manifest == manifest,
|
||||||
|
Blob.digest == _ensure_sha256_header(blob_digest)).get())
|
||||||
|
except ManifestBlob.DoesNotExist:
|
||||||
|
blob = blob_model.get_blob(blob_digest)
|
||||||
|
ManifestBlob.create(manifest=manifest, blob=blob)
|
||||||
|
return tag
|
||||||
|
|
||||||
|
|
||||||
def get_releases(repo, media_type=None):
|
def get_releases(repo, media_type=None):
|
||||||
""" Returns an array of Tag.name for a repo, can filter by media_type. """
|
""" Returns an array of Tag.name for a repo, can filter by media_type. """
|
||||||
release_query = (Tag
|
release_query = (Tag
|
||||||
|
|
|
@ -196,7 +196,6 @@ def push(namespace, package_name):
|
||||||
{"package": reponame, "scopes": ['create']})
|
{"package": reponame, "scopes": ['create']})
|
||||||
Package.create_repository(reponame, private, owner)
|
Package.create_repository(reponame, private, owner)
|
||||||
|
|
||||||
|
|
||||||
if not ModifyRepositoryPermission(namespace, package_name).can():
|
if not ModifyRepositoryPermission(namespace, package_name).can():
|
||||||
raise UnauthorizedAccess("Unauthorized access for: %s" % reponame,
|
raise UnauthorizedAccess("Unauthorized access for: %s" % reponame,
|
||||||
{"package": reponame, "scopes": ['push']})
|
{"package": reponame, "scopes": ['push']})
|
||||||
|
|
|
@ -187,10 +187,6 @@ class TestQuayModels(CnrTestModels):
|
||||||
def load_db(self, appconfig):
|
def load_db(self, appconfig):
|
||||||
return appconfig
|
return appconfig
|
||||||
|
|
||||||
@pytest.mark.xfail
|
|
||||||
def test_save_package_exists_force(self, newdb, package_b64blob):
|
|
||||||
CnrTestModels.test_save_package_exists_force(self, newdb, package_b64blob)
|
|
||||||
|
|
||||||
@pytest.mark.xfail
|
@pytest.mark.xfail
|
||||||
def test_channel_delete_releases(self, db_with_data1):
|
def test_channel_delete_releases(self, db_with_data1):
|
||||||
""" Can't remove a release from the channel, only delete the channel entirely """
|
""" Can't remove a release from the channel, only delete the channel entirely """
|
||||||
|
|
Reference in a new issue