Skip to content

Commit

Permalink
Minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
xDaile committed Feb 1, 2024
1 parent 9675d0a commit 2cc8c5f
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 56 deletions.
74 changes: 56 additions & 18 deletions iib/common/pydantic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,24 @@
]


class PydanticModel(BaseModel):
class PydanticRequestBaseModel(BaseModel):
"""Base model representing IIB request."""

@classmethod
def _get_all_keys_to_check_in_db(cls):
"""Class that returns request specific keys to check."""
raise NotImplementedError("Not implemented")

def get_keys_to_check_in_db(self):
"""Filter keys, which need to be checked in db. Return only a keys that are set to values."""
"""
Filter keys, which need to be checked in db.
Return only a keys that are set to values.
"""
return [k for k in self._get_all_keys_to_check_in_db() if getattr(self, k, None)]


class AddPydanticModel(PydanticModel):
class AddPydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/add API point."""

add_arches: Optional[List[str]] = None
Expand Down Expand Up @@ -76,18 +82,22 @@ class AddPydanticModel(PydanticModel):
BeforeValidator(distribution_scope_lower),
] = None
force_backport: Optional[bool] = False # deprecated
from_index: Annotated[str, AfterValidator(image_format_check)]
from_index: Annotated[Optional[str], AfterValidator(image_format_check)] = None
graph_update_mode: Optional[GRAPH_MODE_LITERAL] = None
organization: Optional[str] = None # deprecated
overwrite_from_index: Optional[bool] = False
overwrite_from_index_token: Optional[SecretStr] = None

_from_index_add_arches_check = model_validator(mode='after')(from_index_add_arches)
@model_validator(mode='after')
def verify_from_index_add_arches_combination(self) -> 'AddPydanticModel':
"""Check the 'overwrite_from_index' parameter with 'overwrite_from_index_token' param."""
from_index_add_arches(self.from_index, self.add_arches)
return self

# TODO remove this comment -> Validator from RequestIndexImageMixin class
@model_validator(mode='after')
def verify_overwrite_from_index_token(self) -> 'AddPydanticModel':
"""Check the 'overwrite_from_index' parameter in combination with 'overwrite_from_index_token' parameter."""
"""Check the 'overwrite_from_index' parameter with 'overwrite_from_index_token' param."""
validate_overwrite_params(self.overwrite_from_index, self.overwrite_from_index_token)
return self

Expand Down Expand Up @@ -138,7 +148,7 @@ def _get_all_keys_to_check_in_db(self):
return ["binary_image", "bundles", "deprecation_list", "from_index"]


class RmPydanticModel(PydanticModel):
class RmPydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/rm API point."""

add_arches: Optional[List[str]] = None
Expand All @@ -151,16 +161,24 @@ class RmPydanticModel(PydanticModel):
Optional[DISTRIBUTION_SCOPE_LITERAL],
BeforeValidator(distribution_scope_lower),
] = None
from_index: Annotated[str, AfterValidator(image_format_check)]
from_index: Annotated[Optional[str], AfterValidator(image_format_check)] = None
operators: Annotated[List[str], AfterValidator(length_validator)]
overwrite_from_index: Optional[bool] = False
overwrite_from_index_token: Optional[SecretStr] = None

_from_index_add_arches_check = model_validator(mode='after')(from_index_add_arches)
@model_validator(mode='after')
def verify_from_index_add_arches_combination(self) -> 'AddPydanticModel':
"""Check the 'overwrite_from_index' parameter with 'overwrite_from_index_token' param."""
from_index_add_arches(self.from_index, self.add_arches)
return self

@model_validator(mode='after')
def verify_overwrite_from_index_token(self) -> 'RmPydanticModel':
validate_overwrite_params(self.overwrite_from_index, self.overwrite_from_index_token)
"""Validate overwrite_from_index and overwrite_from_index_token param combination."""
validate_overwrite_params(
self.overwrite_from_index,
self.overwrite_from_index_token,
)
return self

def get_json_for_request(self):
Expand All @@ -180,19 +198,30 @@ def _get_all_keys_to_check_in_db(self):


class AddRmBatchPydanticModel(BaseModel):
"""Datastructure of the request to /builds/add-rm-batch API point."""

annotations: Dict[str, Any]
build_requests: List[Union[AddPydanticModel, RmPydanticModel]]


class RegistryAuth(BaseModel):
"""Datastructure representing private registry token."""

auth: SecretStr


class RegistryAuths(BaseModel): # is {"auths":{}} allowed?
class RegistryAuths(BaseModel):
"""
Datastructure used within recursive-related-bundles.
Provide the dockerconfig.json for authentication to private registries.
Non-auth information in the dockerconfig.json is not allowed.
"""

auths: Annotated[Dict[SecretStr, RegistryAuth], AfterValidator(length_validator)]


class RegenerateBundlePydanticModel(PydanticModel):
class RegenerateBundlePydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/regenerate-bundle API point."""

# BUNDLE_IMAGE, from_bundle_image_resolved, build_tags?
Expand All @@ -213,12 +242,14 @@ def _get_all_keys_to_check_in_db(self):


class RegenerateBundleBatchPydanticModel(BaseModel):
"""Datastructure of the request to /builds/regenerate-bundle-batch API point."""

build_requests: List[RegenerateBundlePydanticModel]
annotations: Dict[str, Any]


class MergeIndexImagePydanticModel(PydanticModel):
"""Datastructure of the request to /builds/regenerate-bundle API point."""
class MergeIndexImagePydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/merge-index-image API point."""

binary_image: Annotated[
Optional[str],
Expand All @@ -245,11 +276,13 @@ class MergeIndexImagePydanticModel(PydanticModel):

@model_validator(mode='after')
def verify_graph_update_mode_with_target_index(self) -> 'MergeIndexImagePydanticModel':
"""Validate graph_update_mode with target_index param combination."""
validate_graph_mode_index_image(self.graph_update_mode, self.target_index)
return self

@model_validator(mode='after')
def verify_overwrite_from_index_token(self) -> 'MergeIndexImagePydanticModel':
"""Validate overwrite_target_index with overwrite_target_index_token param combination."""
validate_overwrite_params(
self.overwrite_target_index,
self.overwrite_target_index_token,
Expand All @@ -274,8 +307,8 @@ def _get_all_keys_to_check_in_db(self):
]


class CreateEmptyIndexPydanticModel(PydanticModel):
"""Datastructure of the request to /builds/regenerate-bundle API point."""
class CreateEmptyIndexPydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/create-empty-index API point."""

binary_image: Annotated[
Optional[str],
Expand All @@ -302,7 +335,9 @@ def _get_all_keys_to_check_in_db(self):
return ["binary_image", "from_index"]


class RecursiveRelatedBundlesPydanticModel(PydanticModel):
class RecursiveRelatedBundlesPydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/recursive-related-bundles API point."""

organization: Optional[str] = None
parent_bundle_image: Annotated[
str,
Expand All @@ -322,7 +357,9 @@ def _get_all_keys_to_check_in_db(self):
return ["parent_bundle_image"]


class FbcOperationsPydanticModel(PydanticModel):
class FbcOperationsPydanticModel(PydanticRequestBaseModel):
"""Datastructure of the request to /builds/fbc-operations API point."""

add_arches: Optional[List[str]] = []
binary_image: Annotated[
Optional[str],
Expand Down Expand Up @@ -357,6 +394,7 @@ class FbcOperationsPydanticModel(PydanticModel):

@model_validator(mode='after')
def verify_overwrite_from_index_token(self) -> 'FbcOperationsPydanticModel':
"""Validate overwrite_from_index and overwrite_from_index_token param combination."""
validate_overwrite_params(self.overwrite_from_index, self.overwrite_from_index_token)
return self

Expand Down
30 changes: 15 additions & 15 deletions iib/common/pydantic_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@

# TODO add regex in future to not allow following values ":s", "s:", ":"?
def image_format_check(image_name: str) -> str:
"""Check format of the index image."""
if '@' not in image_name and ':' not in image_name:
raise ValidationError(f'Image {image_name} should have a tag or a digest specified.')
return image_name


def images_format_check(image_list: List[str]) -> List[str]:
"""Check multiple image names."""
for image_name in image_list:
image_format_check(image_name)
return image_list


def get_unique_bundles(bundles: List[str]) -> List[str]:
"""Check and possibly remove duplicates from a list of bundles."""
if not bundles:
return bundles

Expand All @@ -42,14 +45,15 @@ def get_unique_bundles(bundles: List[str]) -> List[str]:


# RequestIndexImageMixin
def get_unique_deprecation_list_items(deprecation_list: Optional[List[str]]) -> Optional[List[str]]:
def get_unique_deprecation_list_items(deprecation_list: List[str]) -> List[str]:
"""Return a list of unique items."""
return list(set(deprecation_list))


def validate_graph_mode_index_image(
graph_update_mode: str,
index_image: str,
) -> 'MergeIndexImageRequestPayload':
graph_update_mode: Optional[GRAPH_MODE_LITERAL],
index_image: Optional[str],
) -> Optional[str]:
"""
Validate graph mode and check if index image is allowed to use different graph mode.
Expand All @@ -59,8 +63,7 @@ def validate_graph_mode_index_image(
:raises: Forbidden when graph_mode can't be used for given index image
"""
if graph_update_mode:
# TODO remove this comment, replace value with current_app.config['IIB_GRAPH_MODE_INDEX_ALLOW_LIST']
allowed_from_indexes: List[str] = ["REMOVE_#:r"]
allowed_from_indexes: List[str] = current_app.config['IIB_GRAPH_MODE_INDEX_ALLOW_LIST']
if index_image not in allowed_from_indexes:
raise Forbidden(
'"graph_update_mode" can only be used on the'
Expand All @@ -70,18 +73,15 @@ def validate_graph_mode_index_image(


# RequestIndexImageMixin
def from_index_add_arches(model: 'AddRequestPydanticModel') -> 'AddRequestPydanticModel':
def from_index_add_arches(from_index: Optional[str], add_arches: Optional[List[str]]) -> None:
"""Check if both `from_index` and `add_arches` are not specified."""
if not model.from_index and not model.add_arches:
if not from_index and not add_arches:
raise ValidationError('One of "from_index" or "add_arches" must be specified')
return model


# RequestIndexImageMixin
def binary_image_check(binary_image: str) -> str:
"""
# Validate binary_image is correctly provided.
"""
"""Validate binary_image is correctly provided."""
if not binary_image and not current_app.config['IIB_BINARY_IMAGE_CONFIG']:
raise ValidationError('The "binary_image" value must be a non-empty string')
return binary_image
Expand All @@ -93,9 +93,7 @@ def validate_overwrite_params(
overwrite_index_image_token: Optional[str],
disable_auth_check: Optional[bool] = False,
) -> None:
"""
Check if both `overwrite_index_image` and `overwrite_index_image_token` are specified.
"""
"""Check if both `overwrite_index_image` and `overwrite_index_image_token` are specified."""
if overwrite_index_image_token and not overwrite_index_image:
raise ValidationError(
'The "overwrite_from_index" parameter is required when'
Expand All @@ -114,10 +112,12 @@ def validate_overwrite_params(

# RequestIndexImageMixin
def distribution_scope_lower(distribution_scope: str) -> str:
"""Transform distribution_scope parameter to lowercase."""
return distribution_scope.lower()


def length_validator(model_property: Any) -> Any:
"""Validate length of the given model property."""
if len(model_property) == 0:
raise ValidationError(
f"The {type(model_property)} {model_property} should have at least 1 item."
Expand Down
2 changes: 1 addition & 1 deletion iib/web/iib_static_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Any, Dict, List, NamedTuple, Optional, Union, Sequence, Set
from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Set
from typing_extensions import NotRequired, TypedDict, Literal

from proton._message import Message
Expand Down
28 changes: 16 additions & 12 deletions iib/workers/tasks/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,20 @@ def _update_index_image_pull_spec(
else:
index_image = output_pull_spec

payload: UpdateRequestPayload = {'arches': list(arches), 'index_image': index_image}
update_payload: UpdateRequestPayload = {'arches': list(arches), 'index_image': index_image}

if add_or_rm:
with set_registry_token(overwrite_from_index_token, from_index, append=True):
index_image_resolved = get_resolved_image(index_image)
payload['index_image_resolved'] = index_image_resolved
payload['internal_index_image_copy'] = output_pull_spec
payload['internal_index_image_copy_resolved'] = get_resolved_image(output_pull_spec)
update_payload['index_image_resolved'] = index_image_resolved
update_payload['internal_index_image_copy'] = output_pull_spec
update_payload['internal_index_image_copy_resolved'] = get_resolved_image(output_pull_spec)

update_request(request_id, payload, exc_msg='Failed setting the index image on the request')
update_request(
request_id,
update_payload,
exc_msg='Failed setting the index image on the request',
)


def _get_external_arch_pull_spec(
Expand Down Expand Up @@ -670,7 +674,7 @@ def _update_index_image_build_state(
image.
"""
arches_str = ', '.join(sorted(prebuild_info['arches']))
payload: UpdateRequestPayload = {
update_payload: UpdateRequestPayload = {
'binary_image': prebuild_info['binary_image'],
'binary_image_resolved': prebuild_info['binary_image_resolved'],
'state': 'in_progress',
Expand All @@ -680,26 +684,26 @@ def _update_index_image_build_state(

bundle_mapping: Optional[Dict[str, List[str]]] = prebuild_info.get('bundle_mapping')
if bundle_mapping:
payload['bundle_mapping'] = bundle_mapping
update_payload['bundle_mapping'] = bundle_mapping

from_index_resolved = prebuild_info.get('from_index_resolved')
if from_index_resolved:
payload['from_index_resolved'] = from_index_resolved
update_payload['from_index_resolved'] = from_index_resolved

source_from_index_resolved = prebuild_info.get('source_from_index_resolved')
if source_from_index_resolved:
payload['source_from_index_resolved'] = source_from_index_resolved
update_payload['source_from_index_resolved'] = source_from_index_resolved

target_index_resolved = prebuild_info.get('target_index_resolved')
if target_index_resolved:
payload['target_index_resolved'] = target_index_resolved
update_payload['target_index_resolved'] = target_index_resolved

fbc_fragment_resolved = prebuild_info.get('fbc_fragment_resolved')
if fbc_fragment_resolved:
payload['fbc_fragment_resolved'] = fbc_fragment_resolved
update_payload['fbc_fragment_resolved'] = fbc_fragment_resolved

exc_msg = 'Failed setting the resolved images on the request'
update_request(request_id, payload, exc_msg)
update_request(request_id, update_payload, exc_msg)


@retry(
Expand Down
Loading

0 comments on commit 2cc8c5f

Please sign in to comment.