-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add experimental structured advanced copy workflow
Closes #396
- Loading branch information
Showing
11 changed files
with
299 additions
and
3 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 @@ | ||
Added experimental advanced copy API with support for structured copying. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import json | ||
import os | ||
|
||
location = os.path.dirname(os.path.realpath(__file__)) | ||
|
||
with open(os.path.join(location, "copy_config.json")) as copy_config_json: | ||
COPY_CONFIG_SCHEMA = json.load(copy_config_json) |
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,21 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"title": "CopyConfig", | ||
"description": "Config for copying content between repos", | ||
"type": "array", | ||
"minItems": 1, | ||
"items": { | ||
"type": "object", | ||
"additionProperties": false, | ||
"required": [ "source_repo_version", "dest_repo" ], | ||
"properties": { | ||
"source_repo_version": { "type": "string" }, | ||
"dest_repo": { "type": "string" }, | ||
"dest_base_version": { "type": "integer" }, | ||
"content": { | ||
"type": "array", | ||
"items": { "type": "string" } | ||
} | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# flake8: noqa | ||
from .publishing import publish, publish_verbatim | ||
from .synchronizing import synchronize | ||
from .copy import copy_content |
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,119 @@ | ||
from django.db import transaction | ||
from django.db.models import Q | ||
|
||
from pulpcore.plugin.models import Content, RepositoryVersion | ||
|
||
from pulp_deb.app.models import AptRepository, Package, ReleaseArchitecture, PackageReleaseComponent | ||
|
||
import logging | ||
from gettext import gettext as _ | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
def find_structured_publish_attributes(content, src_repo_version): | ||
""" | ||
Finds the content for structured publish from packages to be copied and returns it all together. | ||
Args: | ||
content (iterable): Content for structured publish | ||
src_repo_version (pulpcore.models.RepositoryVersion): Source repo version | ||
Returns: Queryset of Content objects that extends intial set of content for structured publish | ||
""" | ||
# Content in the source repository version | ||
package_release_component_ids = src_repo_version.content.filter( | ||
pulp_type=PackageReleaseComponent.get_pulp_type() | ||
).only("pk") | ||
architecture_ids = src_repo_version.content.filter( | ||
pulp_type=ReleaseArchitecture.get_pulp_type() | ||
).only("pk") | ||
package_release_components = PackageReleaseComponent.objects.filter( | ||
pk__in=package_release_component_ids | ||
) | ||
|
||
children = set() | ||
|
||
# Packages to be copied | ||
packages = Package.objects.filter(pk__in=content) | ||
children.update(packages.values_list("pk", flat=True)) | ||
|
||
if len(content) != len(packages): | ||
log.warning(_("Additional data with packages is provided. Removing from the content list.")) | ||
|
||
# List of all architectures | ||
architectures = ReleaseArchitecture.objects.filter(pk__in=architecture_ids).values_list( | ||
"pk", flat=True | ||
) | ||
children.update(architectures) | ||
|
||
# Package release components, release components, release to be copied based on packages | ||
for pckg in package_release_components.iterator(): | ||
if pckg.package in packages: | ||
children.update([pckg.pk, pckg.release_component.pk, pckg.release_component.release.pk]) | ||
|
||
return Content.objects.filter(pk__in=children) | ||
|
||
|
||
@transaction.atomic | ||
def copy_content(config, structured, dependency_solving): | ||
""" | ||
Copy content from one repo to another. | ||
Args: | ||
source_repo_version_pk: repository version primary key to copy units from | ||
dest_repo_pk: repository primary key to copy units into | ||
criteria: a dict that maps type to a list of criteria to filter content by. Note that this | ||
criteria MUST be validated before being passed to this task. | ||
content_pks: a list of content pks to copy from source to destination | ||
""" | ||
|
||
def process_entry(entry): | ||
source_repo_version = RepositoryVersion.objects.get(pk=entry["source_repo_version"]) | ||
dest_repo = AptRepository.objects.get(pk=entry["dest_repo"]) | ||
|
||
dest_version_provided = bool(entry.get("dest_base_version")) | ||
if dest_version_provided: | ||
dest_repo_version = RepositoryVersion.objects.get(pk=entry["dest_base_version"]) | ||
else: | ||
dest_repo_version = dest_repo.latest_version() | ||
|
||
if entry.get("content") is not None: | ||
content_filter = Q(pk__in=entry.get("content")) | ||
else: | ||
content_filter = Q() | ||
|
||
log.info(_("Copying: {copy} created").format(copy=content_filter)) | ||
|
||
return ( | ||
source_repo_version, | ||
dest_repo_version, | ||
dest_repo, | ||
content_filter, | ||
dest_version_provided, | ||
) | ||
|
||
if not dependency_solving: | ||
# No Dependency Solving Branch | ||
# ============================ | ||
for entry in config: | ||
( | ||
source_repo_version, | ||
dest_repo_version, | ||
dest_repo, | ||
content_filter, | ||
dest_version_provided, | ||
) = process_entry(entry) | ||
|
||
content_to_copy = source_repo_version.content.filter(content_filter) | ||
if structured: | ||
content_to_copy = find_structured_publish_attributes( | ||
content_to_copy, source_repo_version | ||
) | ||
|
||
base_version = dest_repo_version if dest_version_provided else None | ||
|
||
with dest_repo.new_version(base_version=base_version) as new_version: | ||
new_version.add_content(content_to_copy) | ||
else: | ||
raise NotImplementedError("Advanced copy with dependency solving is not yet implemented.") |
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,5 @@ | ||
from django.urls import path | ||
|
||
from .viewsets import CopyViewSet | ||
|
||
urlpatterns = [path("pulp/api/v3/deb/copy/", CopyViewSet.as_view({"post": "create"}))] |
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