-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DRAFT pulp_labels POC #5787
base: main
Are you sure you want to change the base?
DRAFT pulp_labels POC #5787
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Generated by Django 4.2.15 on 2024-09-08 23:15 | ||
|
||
import django.contrib.postgres.fields.hstore | ||
from django.db import migrations | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('core', '0122_record_last_replication_timestamp'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='content', | ||
name='pulp_labels', | ||
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -444,8 +444,9 @@ class RepositoryAddRemoveContentSerializer(ModelSerializer, NestedHyperlinkedMod | |
remove_content_units = serializers.ListField( | ||
help_text=_( | ||
"A list of content units to remove from the latest repository version. " | ||
"You may also specify '*' as an entry to remove all content. This content is " | ||
"removed before add_content_units are added." | ||
"You may specify '*' as an entry to remove all content, or 'key=value' pairs " | ||
"to remove content by-label. This content is removed before add_content_units " | ||
"are added." | ||
), | ||
child=serializers.CharField(error_messages={"invalid": "Not a valid URI of a resource."}), | ||
required=False, | ||
|
@@ -474,19 +475,29 @@ def validate_add_content_units(self, value): | |
|
||
def validate_remove_content_units(self, value): | ||
remove_content_units = {} | ||
|
||
# "* must be alone, and means "all-content" | ||
if "*" in value: | ||
if len(value) > 1: | ||
raise serializers.ValidationError("Cannot supply content units and '*'.") | ||
else: | ||
return ["*"] | ||
else: | ||
|
||
# Q: just one label? can label/hrefs be mixed? accept full label-operand-set? | ||
# Current: multiple labels, mixed with hrefs, only '=' | ||
# "x=y" can happen multiple times, and means "all content with label x=y, pass k=v pair" | ||
labels_specified = [s for s in value if "=" in s] | ||
Comment on lines
+486
to
+488
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically you can have a label that is just a key, with no value. So we probably should assume anything that doesn't begin with a slash to be a proper label. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ooof, good point. Pushes us towards @mdellweg 's comment above, to have a |
||
if labels_specified: | ||
value = set(value) - set(labels_specified) | ||
|
||
# Anything remaining means "content HREFs, pass UUIDs" | ||
if value: | ||
for url in value: | ||
remove_content_units[extract_pk(url)] = url | ||
content_units_pks = set(remove_content_units.keys()) | ||
existing_content_units = models.Content.objects.filter(pk__in=content_units_pks) | ||
raise_for_unknown_content_units(existing_content_units, remove_content_units) | ||
return list(remove_content_units.keys()) | ||
|
||
return list(remove_content_units.keys()) + labels_specified | ||
|
||
class Meta: | ||
model = models.RepositoryVersion | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,4 +75,5 @@ class Meta: | |
"content", | ||
"content_ptr", | ||
"timestamp_of_interest", | ||
"pulp_labels", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I can see, that this is still unambiguous. But should we maybe go for a new
remove_q
field?You may for example remove all files from a repository by their
relative_path__startswith
...So the logic could start with
remove_q="pulp_label_select='foo'"
and later we add support forremove_q="pulp_label_select='foo' OR relative_path__startswith='/bar/'
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having said that, should we factor this part (advanced modify) into it's own PR? It would give us time to think this high level api design over.
Given that a user can filter content by labels, they can already compile the set of content hrefs locally to call modify with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - but the user-experience of calling an API with a list of possibly thousands of HREFs, for one label, is...suboptimal. And "remove all the units with a given build id" is the actual requirement we're being asked to respond to, it's the point for doing this at all.
I can see benefits to a more-general Q filter - but I'm not sure the extra flexibility is worth the extra complication?