Skip to content

Commit f64dfc7

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 1059cad commit f64dfc7

9 files changed

Lines changed: 479 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: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
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,
1622
SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME,
1723
)
@@ -113,3 +119,45 @@ def ssp_spec_templates_scope_function(ssp_resource_scope_function):
113119
@pytest.fixture(scope="session")
114120
def common_templates_scope_session(hyperconverged_status_scope_session):
115121
return hyperconverged_status_scope_session[SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME]
122+
123+
124+
@pytest.fixture(scope="class")
125+
def default_common_template_hco_status(hyperconverged_status_templates_scope_class):
126+
return get_templates_by_type_from_hco_status(
127+
hco_status_templates=hyperconverged_status_templates_scope_class, template_type=COMMON_TEMPLATE
128+
)
129+
130+
131+
@pytest.fixture(scope="class")
132+
def default_common_templates_related_resources(
133+
default_common_template_hco_status,
134+
hyperconverged_resource_scope_class,
135+
worker_architectures,
136+
):
137+
"""Return expected golden image resource names for the current cluster state.
138+
139+
When enableMultiArchBootImageImport is enabled:
140+
- DataImportCrons: arch-specific only (base names are replaced)
141+
- DataSources: both arch-specific and agnostic pointers
142+
- ImageStreams: always base names
143+
When disabled: all base names.
144+
"""
145+
base_resources = get_templates_resources_names_dict(templates=default_common_template_hco_status)
146+
147+
feature_gate_enabled = hyperconverged_resource_scope_class.instance.spec.get(FEATURE_GATES, {}).get(
148+
ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT, False
149+
)
150+
151+
if not feature_gate_enabled:
152+
return base_resources
153+
154+
result = {}
155+
for kind, base_names in base_resources.items():
156+
arch_names = {f"{name}-{arch}" for name in base_names for arch in worker_architectures}
157+
if kind == DataImportCron.kind:
158+
result[kind] = arch_names
159+
elif kind == DataSource.kind:
160+
result[kind] = base_names | arch_names
161+
else:
162+
result[kind] = base_names
163+
return result
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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="session")
60+
def worker_architectures(schedulable_nodes):
61+
return {node.labels[KUBERNETES_ARCH_LABEL] for node in schedulable_nodes}
62+
63+
64+
@pytest.fixture(scope="class")
65+
def control_plane_architecture(control_plane_nodes):
66+
return get_control_plane_architecture(control_plane_nodes=control_plane_nodes)
67+
68+
69+
@pytest.fixture()
70+
def single_arch_node_placement(hyperconverged_resource_scope_function, worker_architectures):
71+
single_arch = sorted(worker_architectures)[0]
72+
LOGGER.info(f"Restricting workloads nodePlacement to single architecture: {single_arch}")
73+
placement = {"nodePlacement": {"nodeSelector": {KUBERNETES_ARCH_LABEL: single_arch}}}
74+
with ResourceEditorValidateHCOReconcile(
75+
patches={hyperconverged_resource_scope_function: {"spec": {"workloads": placement}}},
76+
list_resource_reconcile=MANAGED_CRS_LIST,
77+
wait_for_reconcile_post_update=True,
78+
):
79+
yield
80+
81+
82+
@pytest.fixture()
83+
def hco_with_custom_unsupported_arch_template(
84+
admin_client,
85+
hco_namespace,
86+
hyperconverged_resource_scope_function,
87+
hyperconverged_status_templates_scope_function,
88+
golden_images_namespace,
89+
):
90+
yield from update_hco_templates_spec(
91+
admin_client=admin_client,
92+
hco_namespace=hco_namespace,
93+
hyperconverged_resource=hyperconverged_resource_scope_function,
94+
updated_template=get_unsupported_arch_template(
95+
common_templates=hyperconverged_status_templates_scope_function,
96+
),
97+
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
98+
golden_images_namespace=golden_images_namespace,
99+
)
100+
101+
102+
@pytest.fixture()
103+
def hco_with_custom_no_arch_annotation_template(
104+
admin_client,
105+
hco_namespace,
106+
hyperconverged_resource_scope_function,
107+
hyperconverged_status_templates_scope_function,
108+
golden_images_namespace,
109+
):
110+
yield from update_hco_templates_spec(
111+
admin_client=admin_client,
112+
hco_namespace=hco_namespace,
113+
hyperconverged_resource=hyperconverged_resource_scope_function,
114+
updated_template=get_no_arch_annotation_template(
115+
common_templates=hyperconverged_status_templates_scope_function,
116+
),
117+
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
118+
golden_images_namespace=golden_images_namespace,
119+
)

0 commit comments

Comments
 (0)