-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Distinguish between the nature of images
closes #1437
- Loading branch information
Showing
12 changed files
with
344 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Incorporated a notion of container images' characteristics. Users can now filter manifests by their | ||
nature using the ``is_flatpak`` or ``is_bootable`` field on the corresponding Manifest endpoint. |
148 changes: 148 additions & 0 deletions
148
pulp_container/app/migrations/0038_add_manifest_metadata_fields.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# Generated by Django 4.2.10 on 2024-02-29 16:04 | ||
|
||
import json | ||
|
||
from contextlib import suppress | ||
|
||
from django.db import migrations, models | ||
from django.core.paginator import Paginator | ||
from django.core.exceptions import ObjectDoesNotExist | ||
|
||
from pulp_container.constants import MEDIA_TYPE | ||
|
||
PAGE_CHUNK_SIZE = 200 | ||
|
||
|
||
def populate_annotations_and_labels(apps, schema_editor): | ||
Manifest = apps.get_model('container', 'Manifest') | ||
|
||
manifests = Manifest.objects.exclude( | ||
media_type__in=[MEDIA_TYPE.MANIFEST_LIST, MEDIA_TYPE.INDEX_OCI] | ||
).order_by('pulp_id') | ||
update_manifests(manifests) | ||
|
||
manifest_lists = Manifest.objects.filter( | ||
media_type__in=[MEDIA_TYPE.MANIFEST_LIST, MEDIA_TYPE.INDEX_OCI] | ||
).order_by('pulp_id') | ||
update_manifests(manifest_lists) | ||
|
||
|
||
def update_manifests(manifests_qs): | ||
paginator = Paginator(manifests_qs, PAGE_CHUNK_SIZE) | ||
for page_num in paginator.page_range: | ||
|
||
manifests_to_update = [] | ||
page = paginator.page(page_num) | ||
for obj in page.object_list: | ||
if m := update_manifest(obj): | ||
manifests_to_update.append(m) | ||
|
||
if manifests_to_update: | ||
fields_to_update = ['annotations', 'labels', 'is_bootable', 'is_flatpak'] | ||
manifests_qs.model.objects.bulk_update( | ||
manifests_to_update, | ||
fields_to_update, | ||
) | ||
|
||
|
||
def update_manifest(manifest): | ||
with suppress(ObjectDoesNotExist): | ||
artifact = manifest._artifacts.get() | ||
# methods for initializing manifest's metadata are not available at the time of | ||
# running the migration; therefore, the methods are taken from the Model itself | ||
init_metadata(manifest, artifact) | ||
return manifest | ||
|
||
|
||
def init_metadata(manifest, manifest_artifact): | ||
init_annotations(manifest, manifest_artifact) | ||
init_labels(manifest) | ||
init_image_nature(manifest) | ||
|
||
|
||
def get_content_data(saved_artifact): | ||
raw_data = saved_artifact.file.read() | ||
content_data = json.loads(raw_data) | ||
saved_artifact.file.close() | ||
return content_data | ||
|
||
|
||
def init_annotations(manifest, manifest_artifact): | ||
manifest_data = get_content_data(manifest_artifact) | ||
manifest.annotations = manifest_data.get('annotations', {}) | ||
|
||
|
||
def init_labels(manifest): | ||
if manifest.config_blob: | ||
config_artifact = manifest.config_blob._artifacts.get() | ||
config_data = get_content_data(config_artifact) | ||
manifest.labels = config_data.get('config', {}).get('Labels', {}) | ||
|
||
|
||
def init_image_nature(manifest): | ||
if manifest.media_type in [MEDIA_TYPE.INDEX_OCI, MEDIA_TYPE.MANIFEST_LIST]: | ||
init_manifest_list_nature(manifest) | ||
else: | ||
init_manifest_nature(manifest) | ||
|
||
|
||
def init_manifest_list_nature(manifest): | ||
for m in manifest.listed_manifests.all(): | ||
if m.is_bootable: | ||
manifest.is_bootable = True | ||
break | ||
elif m.is_flatpak: | ||
manifest.is_flatpak = True | ||
break | ||
|
||
|
||
def init_manifest_nature(manifest): | ||
if is_bootable_image(manifest.annotations, manifest.labels): | ||
manifest.is_bootable = True | ||
elif is_flatpak_image(manifest.labels): | ||
manifest.is_flatpak = True | ||
|
||
|
||
def is_bootable_image(annotations, labels): | ||
if annotations.get('containers.bootc') == '1' or labels.get('containers.bootc') == '1': | ||
return True | ||
else: | ||
return False | ||
|
||
|
||
def is_flatpak_image(labels): | ||
return True if labels.get('org.flatpak.ref') else False | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('container', '0037_create_pull_through_cache_models'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='manifest', | ||
name='annotations', | ||
field=models.JSONField(default=dict), | ||
), | ||
migrations.AddField( | ||
model_name='manifest', | ||
name='is_bootable', | ||
field=models.BooleanField(default=False), | ||
), | ||
migrations.AddField( | ||
model_name='manifest', | ||
name='is_flatpak', | ||
field=models.BooleanField(default=False), | ||
), | ||
migrations.AddField( | ||
model_name='manifest', | ||
name='labels', | ||
field=models.JSONField(default=dict), | ||
), | ||
migrations.RunPython( | ||
code=populate_annotations_and_labels, | ||
reverse_code=migrations.RunPython.noop, | ||
) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.