Skip to content

Commit

Permalink
Add field disk_size to Repository & RepositoryVersion
Browse files Browse the repository at this point in the history
fixes: pulp#2079
  • Loading branch information
gerrod3 committed Sep 13, 2023
1 parent e585547 commit b0372e4
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES/2079.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added field ``disk_size`` to Repository and RepositoryVersion that shows current total size in bytes of files stored on disk.
20 changes: 20 additions & 0 deletions pulpcore/app/models/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ class Meta:
unique_together = ("name", "pulp_domain")
verbose_name_plural = "repositories"

@property
def disk_size(self):
"""Returns the approximate size on disk for all artifacts stored across all versions."""
all_content = (
RepositoryContent.objects.filter(repository=self)
.distinct("content")
.values_list("content")
)
return (
Artifact.objects.filter(content__pk__in=all_content)
.distinct()
.aggregate(size=models.Sum("size"))["size"]
or 0
)

def on_new_version(self, version):
"""Called after a new repository version has been created.
Expand Down Expand Up @@ -795,6 +810,11 @@ def artifacts(self):
"""
return self.repository.cast().artifacts_for_version(self)

@property
def disk_size(self):
"""Returns the size on disk of all the artifacts in this repository version."""
return self.artifacts.distinct().aggregate(size=models.Sum("size"))["size"] or 0

def added(self, base_version=None):
"""
Args:
Expand Down
27 changes: 27 additions & 0 deletions pulpcore/app/serializers/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from rest_framework import fields, serializers
from rest_framework_nested.serializers import NestedHyperlinkedModelSerializer
from drf_spectacular.utils import extend_schema_field

from pulpcore.app import models, settings
from pulpcore.app.serializers import (
Expand Down Expand Up @@ -49,6 +50,18 @@ class RepositorySerializer(ModelSerializer):
required=False,
allow_null=True,
)
disk_size = serializers.SerializerMethodField(
help_text=_(
"Approximate size on disk of all artifacts in the repository across all its versions."
),
)

@extend_schema_field(serializers.IntegerField(read_only=True, allow_null=True))
def get_disk_size(self, obj):
if view := self.context.get("view", None):
if getattr(view, "action", "") == "retrieve":
return obj.disk_size
return None

def validate_remote(self, value):
if value and type(value) not in self.Meta.model.REMOTE_TYPES:
Expand All @@ -66,6 +79,7 @@ class Meta:
"latest_version_href",
"name",
"description",
"disk_size",
"retain_repo_versions",
"remote",
)
Expand Down Expand Up @@ -420,12 +434,25 @@ class RepositoryVersionSerializer(ModelSerializer, NestedHyperlinkedModelSeriali
source="*",
read_only=True,
)
disk_size = serializers.SerializerMethodField(
help_text=_(
"Approximate size on disk of all artifacts in the repository version."
),
)

@extend_schema_field(serializers.IntegerField(read_only=True, allow_null=True))
def get_disk_size(self, obj):
if view := self.context.get("view", None):
if getattr(view, "action", "") == "retrieve":
return obj.disk_size
return None

class Meta:
model = models.RepositoryVersion
fields = ModelSerializer.Meta.fields + (
"pulp_href",
"number",
"disk_size",
"repository",
"base_version",
"content_summary",
Expand Down
55 changes: 55 additions & 0 deletions pulpcore/tests/functional/api/test_repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,58 @@ def test_repository_content_filters(
# but not in its latest version anymore
results = file_repository_api_client.list(latest_with_content=content.pulp_href).results
assert results == []


@pytest.mark.parallel
def test_repo_size(
file_repo,
file_repository_api_client,
file_repository_version_api_client,
file_remote_factory,
basic_manifest_path,
random_artifact_factory,
file_content_api_client,
monitor_task
):
# Check that 'disk_size' is only added on retrieve operations
file_repo = file_repository_api_client.read(file_repo.pulp_href)
assert file_repo.disk_size == 0
repo_ver0 = file_repository_version_api_client.read(file_repo.latest_version_href)
assert repo_ver0.disk_size == 0

listed_repo = file_repository_api_client.list().results[0]
assert listed_repo.disk_size is None
listed_ver = file_repository_version_api_client.list(file_repo.pulp_href).results[0]
assert listed_ver.disk_size is None

# Sync repository with on_demand
remote = file_remote_factory(manifest_path=basic_manifest_path, policy="on_demand")
body = {"remote": remote.pulp_href}
monitor_task(file_repository_api_client.sync(file_repo.pulp_href, body).task)
file_repo = file_repository_api_client.read(file_repo.pulp_href)

# disk_size should still be 0
assert file_repo.disk_size == 0
repo_ver1 = file_repository_version_api_client.read(file_repo.latest_version_href)
assert repo_ver1.disk_size == 0

# Resync with immediate
remote = file_remote_factory(manifest_path=basic_manifest_path, policy="immediate")
body = {"remote": remote.pulp_href}
monitor_task(file_repository_api_client.sync(file_repo.pulp_href, body).task)
file_repo = file_repository_api_client.read(file_repo.pulp_href)

assert file_repo.disk_size == 3072 # 3 * 1024
repo_ver1 = file_repository_version_api_client.read(file_repo.latest_version_href)
assert repo_ver1.disk_size == 3072

# Add content unit w/ same name, but different artifact
art1 = random_artifact_factory()
body = {"repository": file_repo.pulp_href, "artifact": art1.pulp_href, "relative_path": "1.iso"}
monitor_task(file_content_api_client.create(**body).task)
file_repo = file_repository_api_client.read(file_repo.pulp_href)

assert file_repo.disk_size == 3072 + art1.size # All 4 artifacts in repo
repo_ver2 = file_repository_version_api_client.read(file_repo.latest_version_href)
assert repo_ver2.content_summary.present["file.file"]["count"] == 3
assert repo_ver2.disk_size == 2048 + art1.size # New size of 3 artifacts in version

0 comments on commit b0372e4

Please sign in to comment.