Skip to content

Commit

Permalink
Defer loading task args
Browse files Browse the repository at this point in the history
Encrypted task args are no longer loaded and decrypted in codepaths that
take no care in them. This can also help to clean up broken tasks in case
the encryption key was lost.

[noissue]
  • Loading branch information
mdellweg committed Jul 26, 2024
1 parent c554e2a commit 734335f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGES/+deferred_task_args.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improved performance when handling tasks by deferred loading of encrypted args.
This also allows seeing and purging tasks in case the symmetric db key was lost.
16 changes: 14 additions & 2 deletions pulpcore/app/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ class Meta:
unique_together = ("task", "name")


class TaskManager(models.Manager):
def get_queryset(self):
# Always make encrypted args deferred.
# This will prevent a lot of issues when the fernet key is lost.
# Only task workers need to be able to read these args anyway.
return super().get_queryset().defer("enc_args", "enc_kwargs")


class Task(BaseModel, AutoAddObjPermsMixin):
"""
Represents a task
Expand All @@ -88,6 +96,8 @@ class Task(BaseModel, AutoAddObjPermsMixin):
pulp_domain (models.ForeignKey): The domain the Task is a part of
"""

objects = TaskManager()

state = models.TextField(choices=TASK_CHOICES)
name = models.TextField()
logging_cid = models.TextField(db_index=True)
Expand Down Expand Up @@ -285,8 +295,10 @@ def refresh_from_db(self, using=None, fields=None, **kwargs):
# loaded.
if fields is not None:
fields = set(fields)
deferred_fields = self.get_deferred_fields()
# If any deferred field is going to be loaded
deferred_fields = {
field for field in self.get_deferred_fields() if not field.startswith("enc_")
}
# If any state related deferred field is going to be loaded
if fields.intersection(deferred_fields):
# then load all of them
fields = fields.union(deferred_fields)
Expand Down
3 changes: 2 additions & 1 deletion pulpcore/tasking/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ def perform_task(task_pk, task_working_dir_rel_path):
signal.signal(signal.SIGUSR1, child_signal_handler)
# All processes need to create their own postgres connection
connection.connection = None
task = Task.objects.select_related("pulp_domain").get(pk=task_pk)
# enc_args and enc_kwargs are deferred by default but we actually want them
task = Task.objects.defer(None).select_related("pulp_domain").get(pk=task_pk)
user = get_users_with_perms(task, with_group_users=False).first()
# Isolate from the parent asyncio.
asyncio.set_event_loop(asyncio.new_event_loop())
Expand Down

0 comments on commit 734335f

Please sign in to comment.