Skip to content

Commit b8e59ae

Browse files
hmeirclaude
andcommitted
IUO: multiarch automation
Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent f0afa5e commit b8e59ae

9 files changed

Lines changed: 481 additions & 87 deletions

File tree

tests/install_upgrade_operators/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from ocp_resources.cdi import CDI
2+
from ocp_resources.kubevirt import KubeVirt
3+
from ocp_resources.network_addons_config import NetworkAddonsConfig
4+
from ocp_resources.ssp import SSP
5+
16
SECTION_TITLE = "section_title"
27
FILE_SUFFIX = "file_suffix"
38
HCO_CR_CERT_CONFIG_CA_KEY = "ca"
@@ -58,6 +63,7 @@
5863
"containerPathVolumes": FG_DISABLED,
5964
}
6065
CUSTOM_DATASOURCE_NAME = "custom-datasource"
66+
MANAGED_CRS_LIST = [KubeVirt, CDI, NetworkAddonsConfig, SSP]
6167
WORKLOAD_UPDATE_STRATEGY_KEY_NAME = "workloadUpdateStrategy"
6268
KUBEMACPOOL_SERVICE = "kubemacpool-service"
6369

tests/install_upgrade_operators/crypto_policy/constants.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
from ocp_resources.network_addons_config import NetworkAddonsConfig
99
from ocp_resources.ssp import SSP
1010

11-
from tests.install_upgrade_operators.constants import KEY_PATH_SEPARATOR
11+
from tests.install_upgrade_operators.constants import KEY_PATH_SEPARATOR, MANAGED_CRS_LIST
1212
from utilities.constants import TLS_CUSTOM_POLICY, TLS_OLD_POLICY
1313

14-
MANAGED_CRS_LIST = [KubeVirt, CDI, NetworkAddonsConfig, SSP]
1514
MANAGED_CRS_LIST_WITH_AAQ = [*MANAGED_CRS_LIST, AAQ]
1615

1716
TLS_MODERN_POLICY = "modern"

tests/install_upgrade_operators/hco_enablement_golden_image_updates/conftest.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
import pytest
2+
from ocp_resources.data_import_cron import DataImportCron
3+
from ocp_resources.data_source import DataSource
24
from ocp_resources.image_stream import ImageStream
35
from ocp_resources.pod import Pod
46
from ocp_utilities.infra import get_pods_by_name_prefix
57

8+
from tests.install_upgrade_operators.constants import ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT
69
from tests.install_upgrade_operators.hco_enablement_golden_image_updates.utils import (
10+
COMMON_TEMPLATE,
711
CUSTOM_TEMPLATE,
812
HCO_CR_DATA_IMPORT_SCHEDULE_KEY,
913
get_modifed_common_template_names,
1014
get_random_minutes_hours_fields_from_data_import_schedule,
1115
get_templates_by_type_from_hco_status,
16+
get_templates_resources_names_dict,
1217
)
1318
from utilities.constants import (
1419
COMMON_TEMPLATES_KEY_NAME,
20+
FEATURE_GATES,
1521
HCO_OPERATOR,
22+
KUBERNETES_ARCH_LABEL,
1623
SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME,
1724
)
1825
from utilities.ssp import get_ssp_resource
@@ -113,3 +120,50 @@ def ssp_spec_templates_scope_function(ssp_resource_scope_function):
113120
@pytest.fixture(scope="session")
114121
def common_templates_scope_session(hyperconverged_status_scope_session):
115122
return hyperconverged_status_scope_session[SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME]
123+
124+
125+
@pytest.fixture(scope="session")
126+
def worker_architectures(schedulable_nodes):
127+
return {node.labels[KUBERNETES_ARCH_LABEL] for node in schedulable_nodes}
128+
129+
130+
@pytest.fixture(scope="class")
131+
def default_common_template_hco_status(hyperconverged_status_templates_scope_class):
132+
return get_templates_by_type_from_hco_status(
133+
hco_status_templates=hyperconverged_status_templates_scope_class, template_type=COMMON_TEMPLATE
134+
)
135+
136+
137+
@pytest.fixture(scope="class")
138+
def default_common_templates_related_resources(
139+
default_common_template_hco_status,
140+
hyperconverged_resource_scope_class,
141+
worker_architectures,
142+
):
143+
"""Return expected golden image resource names for the current cluster state.
144+
145+
When enableMultiArchBootImageImport is enabled:
146+
- DataImportCrons: arch-specific only (base names are replaced)
147+
- DataSources: both arch-specific and agnostic pointers
148+
- ImageStreams: always base names
149+
When disabled: all base names.
150+
"""
151+
base_resources = get_templates_resources_names_dict(templates=default_common_template_hco_status)
152+
153+
feature_gate_enabled = hyperconverged_resource_scope_class.instance.spec.get(FEATURE_GATES, {}).get(
154+
ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT, False
155+
)
156+
157+
if not feature_gate_enabled:
158+
return base_resources
159+
160+
result = {}
161+
for kind, base_names in base_resources.items():
162+
arch_names = {f"{name}-{arch}" for name in base_names for arch in worker_architectures}
163+
if kind == DataImportCron.kind:
164+
result[kind] = arch_names
165+
elif kind == DataSource.kind:
166+
result[kind] = base_names | arch_names
167+
else:
168+
result[kind] = base_names
169+
return result
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import logging
2+
3+
import pytest
4+
from ocp_resources.cdi import CDI
5+
from ocp_resources.kubevirt import KubeVirt
6+
from ocp_resources.ssp import SSP
7+
8+
from tests.install_upgrade_operators.constants import ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT, MANAGED_CRS_LIST
9+
from tests.install_upgrade_operators.hco_enablement_golden_image_updates.multiarch.utils import (
10+
CUSTOM_MULTIARCH_DATASOURCE_NAME,
11+
get_control_plane_architecture,
12+
get_no_arch_annotation_template,
13+
get_unsupported_arch_template,
14+
)
15+
from utilities.constants import (
16+
FEATURE_GATES,
17+
KUBERNETES_ARCH_LABEL,
18+
)
19+
from utilities.hco import (
20+
ResourceEditorValidateHCOReconcile,
21+
update_hco_templates_spec,
22+
)
23+
24+
LOGGER = logging.getLogger(__name__)
25+
26+
_MULTIARCH_MANAGED_CRS = [SSP, KubeVirt, CDI]
27+
28+
29+
@pytest.fixture(scope="class")
30+
def disabled_multiarch_feature_gate(hyperconverged_resource_scope_class):
31+
with ResourceEditorValidateHCOReconcile(
32+
patches={
33+
hyperconverged_resource_scope_class: {"spec": {FEATURE_GATES: {ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT: False}}}
34+
},
35+
list_resource_reconcile=_MULTIARCH_MANAGED_CRS,
36+
wait_for_reconcile_post_update=True,
37+
):
38+
yield
39+
40+
41+
@pytest.fixture(scope="class")
42+
def enabled_multiarch_feature_gate(hyperconverged_resource_scope_class):
43+
feature_gates = hyperconverged_resource_scope_class.instance.spec.get(FEATURE_GATES, {})
44+
if feature_gates.get(ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT):
45+
yield
46+
else:
47+
with ResourceEditorValidateHCOReconcile(
48+
patches={
49+
hyperconverged_resource_scope_class: {
50+
"spec": {FEATURE_GATES: {ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT: True}}
51+
}
52+
},
53+
list_resource_reconcile=_MULTIARCH_MANAGED_CRS,
54+
wait_for_reconcile_post_update=True,
55+
):
56+
yield
57+
58+
59+
@pytest.fixture(scope="class")
60+
def control_plane_architecture(control_plane_nodes):
61+
return get_control_plane_architecture(control_plane_nodes=control_plane_nodes)
62+
63+
64+
@pytest.fixture()
65+
def single_arch_node_placement(hyperconverged_resource_scope_function, worker_architectures):
66+
single_arch = sorted(worker_architectures)[0]
67+
LOGGER.info(f"Restricting workloads nodePlacement to single architecture: {single_arch}")
68+
placement = {"nodePlacement": {"nodeSelector": {KUBERNETES_ARCH_LABEL: single_arch}}}
69+
with ResourceEditorValidateHCOReconcile(
70+
patches={hyperconverged_resource_scope_function: {"spec": {"workloads": placement}}},
71+
list_resource_reconcile=MANAGED_CRS_LIST,
72+
wait_for_reconcile_post_update=True,
73+
):
74+
yield
75+
76+
77+
@pytest.fixture()
78+
def hco_with_custom_unsupported_arch_template(
79+
admin_client,
80+
hco_namespace,
81+
hyperconverged_resource_scope_function,
82+
hyperconverged_status_templates_scope_function,
83+
golden_images_namespace,
84+
):
85+
yield from update_hco_templates_spec(
86+
admin_client=admin_client,
87+
hco_namespace=hco_namespace,
88+
hyperconverged_resource=hyperconverged_resource_scope_function,
89+
updated_template=get_unsupported_arch_template(
90+
common_templates=hyperconverged_status_templates_scope_function,
91+
),
92+
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
93+
golden_images_namespace=golden_images_namespace,
94+
)
95+
96+
97+
@pytest.fixture()
98+
def hco_with_custom_no_arch_annotation_template(
99+
admin_client,
100+
hco_namespace,
101+
hyperconverged_resource_scope_function,
102+
hyperconverged_status_templates_scope_function,
103+
golden_images_namespace,
104+
):
105+
yield from update_hco_templates_spec(
106+
admin_client=admin_client,
107+
hco_namespace=hco_namespace,
108+
hyperconverged_resource=hyperconverged_resource_scope_function,
109+
updated_template=get_no_arch_annotation_template(
110+
common_templates=hyperconverged_status_templates_scope_function,
111+
),
112+
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
113+
golden_images_namespace=golden_images_namespace,
114+
)

0 commit comments

Comments
 (0)