Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow "binary_image" to receive "scratch" #767

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading