Skip to content

Commit

Permalink
Allow "binary_image" to receive "scratch"
Browse files Browse the repository at this point in the history
This commit changes IIB to accept string "scratch" as `binary_image` in
order to support the binaryless build in the future.

With this change IIB accept string "scratch" as binary image:

- defined in IIB_BINARY_IMAGE_CONFIG
- passed by binary_image parameter

Refers to CLOUDDST-23094
  • Loading branch information
JAVGan committed Jan 22, 2025
1 parent 40e5cf7 commit 1716ce0
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 33 deletions.
6 changes: 5 additions & 1 deletion iib/web/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ def get_or_create(cls, pull_specification: str) -> Image:
:rtype: Image
:raise ValidationError: if pull_specification for the image is invalid
"""
if '@' not in pull_specification and ':' not in pull_specification:
if (
'@' not in pull_specification
and ':' not in pull_specification
and pull_specification != "scratch"
):
raise ValidationError(
f'Image {pull_specification} should have a tag or a digest specified.'
)
Expand Down
17 changes: 17 additions & 0 deletions iib/workers/tasks/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,15 @@ def handle_add_request(
),
)
from_index_resolved = prebuild_info['from_index_resolved']

# FIXME: To be removed when the binaryless image build support is implemented
is_binaryless = prebuild_info['binary_image'] == "scratch"
if is_binaryless:
_cleanup()
log.warning("IIB is not yet able to process binaryless images.")
set_request_state(request_id, 'failed', 'IIB is not yet able to process binaryless images')
return

Opm.set_opm_version(from_index_resolved)
with set_registry_token(overwrite_from_index_token, from_index_resolved):
is_fbc = is_image_fbc(from_index_resolved) if from_index else False
Expand Down Expand Up @@ -1061,6 +1070,14 @@ def handle_rm_request(
_update_index_image_build_state(request_id, prebuild_info)

from_index_resolved = prebuild_info['from_index_resolved']
# FIXME: To be removed when the binaryless image build support is implemented
is_binaryless = prebuild_info['binary_image'] == "scratch"
if is_binaryless:
_cleanup()
log.warning("IIB is not yet able to process binaryless images.")
set_request_state(request_id, 'failed', 'IIB is not yet able to process binaryless images')
return

Opm.set_opm_version(from_index_resolved)

with tempfile.TemporaryDirectory(prefix=f'iib-{request_id}-') as temp_dir:
Expand Down
7 changes: 7 additions & 0 deletions iib/workers/tasks/build_create_empty_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def handle_create_empty_index_request(
)
from_index_resolved = prebuild_info['from_index_resolved']
prebuild_info['labels'] = labels
# FIXME: To be removed when the binaryless image build support is implemented
is_binaryless = prebuild_info['binary_image'] == "scratch"
if is_binaryless:
_cleanup()
log.warning("IIB is not yet able to process binaryless images.")
set_request_state(request_id, 'failed', 'IIB is not yet able to process binaryless images')
return
Opm.set_opm_version(from_index_resolved)

if not output_fbc and is_image_fbc(from_index_resolved):
Expand Down
8 changes: 8 additions & 0 deletions iib/workers/tasks/build_fbc_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ def handle_fbc_operation_request(

from_index_resolved = prebuild_info['from_index_resolved']
binary_image_resolved = prebuild_info['binary_image_resolved']
# FIXME: To be removed when the binaryless image build support is implemented
is_binaryless = prebuild_info['binary_image'] == "scratch"
if is_binaryless:
_cleanup()
log.warning("IIB is not yet able to process binaryless images.")
set_request_state(request_id, 'failed', 'IIB is not yet able to process binaryless images')
return

Opm.set_opm_version(from_index_resolved)

prebuild_info['fbc_fragment_resolved'] = resolved_fbc_fragment
Expand Down
8 changes: 8 additions & 0 deletions iib/workers/tasks/build_merge_index_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ def handle_merge_request(
)
source_from_index_resolved = prebuild_info['source_from_index_resolved']
target_index_resolved = prebuild_info['target_index_resolved']
# FIXME: To be removed when the binaryless image build support is implemented
is_binaryless = prebuild_info['binary_image'] == "scratch"
if is_binaryless:
_cleanup()
log.warning("IIB is not yet able to process binaryless images.")
set_request_state(request_id, 'failed', 'IIB is not yet able to process binaryless images')
return

Opm.set_opm_version(target_index_resolved)

_update_index_image_build_state(request_id, prebuild_info)
Expand Down
43 changes: 25 additions & 18 deletions iib/workers/tasks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,20 @@ def add_max_ocp_version_property(resolved_bundles: List[str], temp_dir: str) ->
def get_binary_image_from_config(
ocp_version: str,
distribution_scope: str,
binary_image_config: Dict[str, Dict[str, str]] = {},
) -> str:
binary_image_config: Dict[str, Dict[str, str]],
) -> Optional[str]:
"""
Determine the binary image to be used to build the index image.
:param str ocp_version: the ocp_version label value of the index image.
:param str distribution_scope: the distribution_scope label value of the index image.
:param dict binary_image_config: the dict of config required to identify the appropriate
``binary_image`` to use.
:return: pull specification of the binary_image to be used for this build.
:return: pull specification of the binary_image to be used for this build when found.
:rtype: str
:raises IIBError: when the config value for the ocp_version and distribution_scope is missing.
"""
binary_image_config = binary_image_config or {}
binary_image = binary_image_config.get(distribution_scope, {}).get(ocp_version, None)
if not binary_image:
raise IIBError(
'IIB does not have a configured binary_image for'
f' distribution_scope : {distribution_scope} and ocp_version: {ocp_version}.'
' Please specify a binary_image value in the request.'
)

return binary_image


Expand Down Expand Up @@ -270,11 +263,22 @@ def __repr__(self) -> str:

def binary_image(self, index_info: IndexImageInfo, distribution_scope: str) -> str:
"""Get binary image based on self configuration, index image info and distribution scope."""
ocp_version = index_info['ocp_version']
config_binary_image = get_binary_image_from_config(
ocp_version, distribution_scope, self.binary_image_config
)
if not self._binary_image:
binary_image_ocp_version = index_info['ocp_version']
return get_binary_image_from_config(
binary_image_ocp_version, distribution_scope, self.binary_image_config
)
if not config_binary_image:
raise IIBError(
'IIB does not have a configured binary_image for'
f' distribution_scope : {distribution_scope} and ocp_version: {ocp_version}.'
' Please specify a binary_image value in the request.'
)
return config_binary_image
if self._binary_image == "scratch" and config_binary_image != "scratch":
raise IIBError(f"The index image should not be binaryless for {ocp_version}.")
elif self._binary_image != "scratch" and config_binary_image == "scratch":
raise IIBError(f"The index image must be built as a binaryless for {ocp_version}.")
return self._binary_image


Expand Down Expand Up @@ -1192,9 +1196,12 @@ def prepare_request_for_build(
)

binary_image = build_request_config.binary_image(request_index, distribution_scope)

binary_image_resolved = get_resolved_image(binary_image)
binary_image_arches = get_image_arches(binary_image_resolved)
if binary_image == "scratch": # binaryless image mode
binary_image_resolved = binary_image
binary_image_arches = arches
else:
binary_image_resolved = get_resolved_image(binary_image)
binary_image_arches = get_image_arches(binary_image_resolved)

if not arches.issubset(binary_image_arches):
raise IIBError(
Expand Down
32 changes: 19 additions & 13 deletions tests/test_web/test_api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ def test_add_bundle_from_index_and_add_arches_missing(mock_smfsc, db, auth_env,

@pytest.mark.parametrize(
(
'binary_image',
'overwrite_from_index',
'overwrite_from_index_token',
'bundles',
Expand All @@ -822,11 +823,11 @@ def test_add_bundle_from_index_and_add_arches_missing(mock_smfsc, db, auth_env,
'graph_update_mode',
),
(
(False, None, ['some:thing'], None, None, None),
(False, None, ['some:thing'], 'some:thing', None, 'semver'),
(False, None, [], 'some:thing', 'Prod', 'semver-skippatch'),
(True, 'username:password', ['some:thing'], 'some:thing', 'StagE', 'replaces'),
(True, 'username:password', [], 'some:thing', 'DeV', 'semver'),
('binary:image', False, None, ['some:thing'], None, None, None),
('binary:image', False, None, ['some:thing'], 'some:thing', None, 'semver'),
('binary:image', False, None, [], 'some:thing', 'Prod', 'semver-skippatch'),
('scratch', True, 'username:password', ['some:thing'], 'some:thing', 'StagE', 'replaces'),
('scratch', True, 'username:password', [], 'some:thing', 'DeV', 'semver'),
),
)
@mock.patch('iib.web.api_v1.handle_add_request')
Expand All @@ -844,10 +845,11 @@ def test_add_bundle_success(
from_index,
distribution_scope,
graph_update_mode,
binary_image,
):
app.config['IIB_GRAPH_MODE_INDEX_ALLOW_LIST'] = [from_index]
data = {
'binary_image': 'binary:image',
'binary_image': binary_image,
'add_arches': ['s390x'],
'organization': 'org',
'cnr_token': 'token',
Expand All @@ -872,7 +874,7 @@ def test_add_bundle_success(
'arches': [],
'batch': 1,
'batch_annotations': None,
'binary_image': 'binary:image',
'binary_image': binary_image,
'binary_image_resolved': None,
'build_tags': [],
'bundle_mapping': {},
Expand Down Expand Up @@ -1414,20 +1416,21 @@ def test_patch_request_regenerate_bundle_success(
mock_smfsc.assert_called_once_with(mock.ANY)


@pytest.mark.parametrize("binary_image", ('binary:image', 'scratch'))
@mock.patch('iib.web.api_v1.handle_rm_request')
@mock.patch('iib.web.api_v1.messaging.send_message_for_state_change')
def test_remove_operator_success(mock_smfsc, mock_rm, db, auth_env, client):
def test_remove_operator_success(mock_smfsc, mock_rm, binary_image, db, auth_env, client):
data = {
'operators': ['some:thing'],
'binary_image': 'binary:image',
'binary_image': binary_image,
'from_index': 'index:image',
}

response_json = {
'arches': [],
'batch': 1,
'batch_annotations': None,
'binary_image': 'binary:image',
'binary_image': binary_image,
'binary_image_resolved': None,
'bundle_mapping': {},
'distribution_scope': None,
Expand Down Expand Up @@ -1960,16 +1963,17 @@ def test_regenerate_add_rm_batch_invalid_input(payload, error_msg, app, auth_env
assert rv.json == {'error': error_msg}


@pytest.mark.parametrize("binary_image", ('binary:image', 'scratch'))
@pytest.mark.parametrize('distribution_scope', (None, 'stage'))
@mock.patch('iib.web.api_v1.handle_merge_request')
@mock.patch('iib.web.api_v1.messaging.send_message_for_state_change')
def test_merge_index_image_success(
mock_smfsc, mock_merge, app, db, auth_env, client, distribution_scope
mock_smfsc, mock_merge, binary_image, app, db, auth_env, client, distribution_scope
):
app.config['IIB_GRAPH_MODE_INDEX_ALLOW_LIST'] = ['target_index:image']
data = {
'deprecation_list': ['some@sha256:bundle'],
'binary_image': 'binary:image',
'binary_image': binary_image,
'source_from_index': 'source_index:image',
'target_index': 'target_index:image',
'build_tags': [],
Expand All @@ -1983,7 +1987,7 @@ def test_merge_index_image_success(
'arches': [],
'batch': 1,
'batch_annotations': None,
'binary_image': 'binary:image',
'binary_image': binary_image,
'binary_image_resolved': None,
'build_tags': [],
'deprecation_list': ['some@sha256:bundle'],
Expand Down Expand Up @@ -2199,7 +2203,9 @@ def test_merge_index_image_fail_on_invalid_params(
(
('some:thing', 'from:variable', None),
('some:thing', 'binary:image', {'version': 'v4.6'}),
('some:thing', 'scratch', {'version': 'v4.6'}),
('some:thing', 'binary:image', None),
('some:thing', 'scratch', None),
),
)
@mock.patch('iib.web.api_v1.handle_create_empty_index_request.apply_async')
Expand Down
Loading

0 comments on commit 1716ce0

Please sign in to comment.