Skip to content

Commit 671961e

Browse files
authored
Fix validator for LSO (#2548)
* add group.yml fields * add LSO <=4.17 validation
1 parent 0cf7982 commit 671961e

File tree

3 files changed

+167
-1
lines changed

3 files changed

+167
-1
lines changed

ocp-build-data-validator/validator/json_schemas/assembly_group_config.schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@
540540
"multi_arch": {"type": "object"},
541541
"new_payload_versioning_scheme": {"type": "boolean"},
542542
"operator_image_ref_mode": {"type": "string"},
543+
"operator_channel_stable": {"type": "string"},
543544
"signing_advisory": {"type": "integer"},
544545
"assemblies": {"type": "object"},
545546
"check_external_packages": {"type": "array"},

ocp-build-data-validator/validator/json_schemas/repos.schema.json

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,56 @@
66
"repo": {
77
"type": "object",
88
"properties": {
9+
"content_set": {
10+
"type": "object",
11+
"properties": {
12+
"default": {
13+
"type": "string"
14+
},
15+
"x86_64": {
16+
"type": "string"
17+
},
18+
"aarch64": {
19+
"type": "string"
20+
},
21+
"ppc64le": {
22+
"type": "string"
23+
},
24+
"s390x": {
25+
"type": "string"
26+
},
27+
"optional": {
28+
"type": "boolean"
29+
}
30+
},
31+
"additionalProperties": false
32+
},
33+
"content_set!": {
34+
"$ref": "#/$defs/repo/properties/content_set"
35+
},
36+
"content_set?": {
37+
"$ref": "#/$defs/repo/properties/content_set"
38+
},
39+
"content_set-": {},
40+
"reposync": {
41+
"type": "object",
42+
"properties": {
43+
"enabled": {
44+
"type": "boolean"
45+
},
46+
"latest_only": {
47+
"type": "boolean"
48+
}
49+
},
50+
"additionalProperties": false
51+
},
52+
"reposync!": {
53+
"$ref": "#/$defs/repo/properties/reposync"
54+
},
55+
"reposync?": {
56+
"$ref": "#/$defs/repo/properties/reposync"
57+
},
58+
"reposync-": {},
959
"conf": {
1060
"type": "object",
1161
"properties": {
@@ -17,7 +67,63 @@
1767
},
1868
"baseurl?": {
1969
"$ref": "#/$defs/repo/properties/conf/properties/baseurl"
20-
}
70+
},
71+
"ci_alignment": {
72+
"type": "object",
73+
"properties": {
74+
"profiles": {
75+
"type": "array",
76+
"items": {
77+
"type": "string"
78+
}
79+
},
80+
"localdev": {
81+
"type": "object",
82+
"properties": {
83+
"enabled": {
84+
"type": "boolean"
85+
}
86+
},
87+
"additionalProperties": false
88+
}
89+
},
90+
"additionalProperties": false
91+
},
92+
"ci_alignment!": {
93+
"$ref": "#/$defs/repo/properties/conf/properties/ci_alignment"
94+
},
95+
"ci_alignment?": {
96+
"$ref": "#/$defs/repo/properties/conf/properties/ci_alignment"
97+
},
98+
"ci_alignment-": {},
99+
"extra_options": {
100+
"type": "object",
101+
"properties": {
102+
"module_hotfixes": {
103+
"type": "integer"
104+
},
105+
"excludepkgs": {
106+
"type": "string"
107+
},
108+
"includepkgs": {
109+
"type": "string"
110+
},
111+
"gpgcheck": {
112+
"oneOf": [
113+
{"type": "string"},
114+
{"type": "integer"}
115+
]
116+
}
117+
},
118+
"additionalProperties": false
119+
},
120+
"extra_options!": {
121+
"$ref": "#/$defs/repo/properties/conf/properties/extra_options"
122+
},
123+
"extra_options?": {
124+
"$ref": "#/$defs/repo/properties/conf/properties/extra_options"
125+
},
126+
"extra_options-": {}
21127
},
22128
"anyOf": [
23129
{

ocp-build-data-validator/validator/schema/image_schema.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ def _get_valid_repos(ocp_build_data_dir: str) -> Set[str]:
5252
return valid_repos
5353

5454

55+
def _get_group_version(ocp_build_data_dir: str) -> tuple[int, int] | None:
56+
"""
57+
Gets the MAJOR.MINOR version from group.yml.
58+
59+
Arg(s):
60+
ocp_build_data_dir (str): Path to the ocp-build-data directory containing group.yml
61+
62+
Return Value(s):
63+
tuple[int, int] | None: (MAJOR, MINOR) version tuple, or None if not found
64+
"""
65+
group_yml = Path(ocp_build_data_dir) / 'group.yml'
66+
if not group_yml.exists():
67+
return None
68+
69+
yaml = YAML(typ='safe')
70+
try:
71+
with open(group_yml) as f:
72+
group_data = yaml.load(f)
73+
if group_data and 'vars' in group_data:
74+
major = group_data['vars'].get('MAJOR')
75+
minor = group_data['vars'].get('MINOR')
76+
if major is not None and minor is not None:
77+
return (int(major), int(minor))
78+
except Exception:
79+
pass
80+
81+
return None
82+
83+
5584
def validate(file, data, images_dir=None):
5685
# Load Json schemas
5786
path = importlib_resources.files("validator") / "json_schemas"
@@ -115,4 +144,34 @@ def validate(file, data, images_dir=None):
115144
f"or in the 'repos' section of {ocp_build_data_dir}/group.yml"
116145
)
117146

147+
# Validate LSO (Local Storage Operator) images have correct branch targets
148+
# LSO images must use release-4.18 for OCP <= 4.17, and should not use it for > 4.17
149+
lso_images = {"local-storage-diskmaker", "local-storage-mustgather", "local-storage-operator"}
150+
image_name = os.path.splitext(os.path.basename(file))[0] if file else None
151+
152+
if image_name in lso_images and images_dir:
153+
ocp_build_data_dir = os.path.dirname(images_dir)
154+
version = _get_group_version(ocp_build_data_dir)
155+
156+
if version:
157+
major, minor = version
158+
git_branch_target = (
159+
data.get("content", {}).get("source", {}).get("git", {}).get("branch", {}).get("target")
160+
)
161+
162+
# For OCP <= 4.17: LSO images MUST use release-4.18
163+
if (major, minor) <= (4, 17):
164+
if git_branch_target != "release-4.18":
165+
errors.append(
166+
f"content.source.git.branch.target: LSO image '{image_name}' in OCP {major}.{minor} "
167+
f"must use 'release-4.18' branch target (found: '{git_branch_target}'). "
168+
f"Ref: https://issues.redhat.com/browse/ART-14558"
169+
)
170+
# For OCP > 4.17: LSO images SHOULD NOT use hardcoded release-4.18
171+
elif git_branch_target == "release-4.18":
172+
errors.append(
173+
f"content.source.git.branch.target: LSO image '{image_name}' in OCP {major}.{minor} "
174+
f"should not use hardcoded 'release-4.18'. Use 'release-{{MAJOR}}.{{MINOR}}' instead."
175+
)
176+
118177
return '\n'.join(errors) if errors else None

0 commit comments

Comments
 (0)