Skip to content

Commit 13da637

Browse files
razvanadwk67
andauthored
fix: olm scripts updates for SDP 26.3 (#124)
* fix(build-manifests.py): read crds from op output * remove crd handling completely * remove build-manifests.sh and update readme * add run-certification-pipeline.sh * Update olm/README.md Co-authored-by: Andrew Kenworthy <1712947+adwk67@users.noreply.github.com> * mention branch for olm manifests --------- Co-authored-by: Andrew Kenworthy <1712947+adwk67@users.noreply.github.com>
1 parent 05b48cc commit 13da637

File tree

5 files changed

+109
-291
lines changed

5 files changed

+109
-291
lines changed

olm/README.md

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,34 @@ in the corresponding operator repository.
2323
The OLM manifests are usually generated into the [OpenShift Certified Operators Repository](https://github.com/stackabletech/openshift-certified-operators)
2424
which is the source of the certification process.
2525

26+
> [!NOTE]
27+
> Ensure you create a fresh branch called `stackable-<operator>-<release>` in the OpenShift Certified Operators Repository for every operator before generate the manifests as described below.
28+
2629
## Secret and Listener Operators
2730

28-
The manifest generation for these two operators is only partially automated.
29-
You start with the script below and then manually update the cluster service version.
30-
To generate the manifests for the secret operator version 24.11.1, run:
31+
Use the `scripts/generate-olm.py` script in each operator repository (secret and listener) like this:
3132

32-
```bash
33-
./olm/build-manifests.sh -r 24.11.1 \
34-
-c $HOME/repo/stackable/openshift-certified-operators \
35-
-o $HOME/repo/stackable/secret-operator
33+
```shell
34+
# Adapt path as necessary
35+
cd $HOME/repo/openshift/openshift-certified-operators/operators/stackable-secret-operator
36+
37+
./scripts/generate-olm.py \
38+
--output-dir $HOME/repo/openshift/openshift-certified-operators/operators/stackable-secret-operator \
39+
--version <release> \
40+
--openshift-versions v4.18-v4.21
3641
```
3742

3843
Where:
3944

40-
- `-r <release>`: the release number (mandatory). This must be a semver-compatible value to patch-level e.g. 23.1.0.
41-
- `-c <manifest folder>`: the output folder for the manifest files
42-
- `-o <operator-dir>`: directory of the operator repository
43-
44-
Similarly for the listener operator run:
45-
46-
```bash
47-
./olm/build-manifests.sh -r 24.11.1 \
48-
-c $HOME/repo/stackable/openshift-certified-operators \
49-
-o $HOME/repo/stackable/listener-operator
50-
```
45+
- `--version <release>`: the release number (mandatory). Example: `26.3.0`.
46+
- `--output-dir <manifest folder>`: location of the certified operators repository.
47+
- `--openshift-versions <ocp-version-range>`: catalogs where this bundle is published. Example: `v4.18-v4.21`.
5148

5249
## All Other Operators
5350

5451
```bash
5552
./olm/build-manifests.py \
56-
--openshift-versions 'v4.14-v4.16' \
53+
--openshift-versions 'v4.18-v4.21' \
5754
--release 24.11.1 \
5855
--repo-operator ~/repo/stackable/hbase-operator
5956
```
@@ -71,7 +68,7 @@ To build operator bundles run:
7168
```bash
7269
./olm/build-bundles.sh \
7370
-c $HOME/repo/stackable/openshift-certified-operators \
74-
-r 24.11.1 \
71+
-r 26.3.0 \
7572
-o listener \
7673
-d
7774
```

olm/build-manifests.py

Lines changed: 29 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
1-
#!/usr/bin/env python
2-
# vim: filetype=python syntax=python tabstop=4 expandtab
1+
#!/usr/bin/env -S uv run --script
2+
# /// script
3+
# requires-python = ">=3.11"
4+
# dependencies = [
5+
# "pyyaml",
6+
# ]
7+
# ///
8+
"""
9+
(Re)Generate Stackable operator manifests for the Operator Lifecycle Manager (OLM).
10+
11+
The script renders the Helm chart, looks up image digests on
12+
quay.io, and writes a complete OLM bundle under deploy/olm/<version>/.
13+
14+
Usage:
15+
16+
uv run --script olm/generate-olm.py --version 26.3.0 --repo-operator ~/repo/stackable/airflow-operator --output-dir deploy/olm
17+
18+
# Or directly with python3 (PyYAML must be installed):
19+
python3 olm/generate-olm.py --version 26.3.0 --repo-operator ~/repo/stackable/airflow-operator --openshift-versions v4.18-v4.21
20+
21+
Requirements:
22+
- uv (https://docs.astral.sh/uv/) — installs PyYAML automatically
23+
- helm (https://helm.sh)
24+
"""
325

426
import argparse
527
import json
@@ -13,32 +35,20 @@
1335
import urllib.parse
1436
import urllib.request
1537

16-
try:
17-
import yaml
18-
except ModuleNotFoundError:
19-
print(
20-
"Module 'pyyaml' not found. Install using: pip install -r olm/requirements.txt"
21-
)
22-
sys.exit(1)
38+
import yaml
2339

2440
__version__ = "0.0.1"
2541

26-
DESCRIPTION = """
27-
(Re)Generate manifests for the Operator Lifecycle Manager (OLM).
28-
29-
Example:
30-
./olm/build-manifests.py --release 24.3.0 --repo-operator ~/repo/stackable/airflow-operator
31-
"""
32-
33-
3442
class ManifestException(Exception):
3543
pass
3644

3745

3846
def parse_args(argv: list[str]) -> argparse.Namespace:
3947
"""Parse command line args."""
4048
parser = argparse.ArgumentParser(
41-
description=DESCRIPTION, formatter_class=argparse.RawDescriptionHelpFormatter
49+
description="Generate OLM bundle manifests for Stackable operators.",
50+
formatter_class=argparse.RawDescriptionHelpFormatter,
51+
epilog=__doc__,
4252
)
4353
parser.add_argument(
4454
"--version",
@@ -219,8 +229,6 @@ def generate_csv_related_images(
219229

220230
def generate_manifests(args: argparse.Namespace) -> list[dict]:
221231
logging.debug("start generate_manifests")
222-
# Parse CRDs as generated by Rust serde.
223-
crds = generate_crds(args.repo_operator)
224232

225233
# Parse Helm manifests
226234
manifests = generate_helm_templates(args)
@@ -254,19 +262,16 @@ def generate_manifests(args: argparse.Namespace) -> list[dict]:
254262
except KeyError:
255263
pass
256264

257-
owned_crds = to_owned_crds(crds)
258-
259265
# Generate the CSV
260266
csv = generate_csv(
261267
args,
262-
owned_crds,
263268
cluster_permissions,
264269
deployments,
265270
related_images,
266271
)
267272

268273
logging.debug("finish generate_manifests")
269-
return [csv, *crds, *manifests]
274+
return [csv, *manifests]
270275

271276

272277
def filter_op_objects(args: argparse.Namespace, manifests) -> tuple[dict, dict, dict]:
@@ -304,7 +309,6 @@ def write_manifests(args: argparse.Namespace, manifests: list[dict]) -> None:
304309
os.makedirs(manifests_dir)
305310

306311
# The following objects are written as separate files:
307-
# - crds
308312
# - cluster service version
309313
# - cluster roles
310314
# - services
@@ -349,45 +353,8 @@ def write_manifests(args: argparse.Namespace, manifests: list[dict]) -> None:
349353
except FileExistsError:
350354
raise ManifestException("Destintation directory already exists")
351355

352-
353-
def to_owned_crds(crds: list[dict]) -> list[dict]:
354-
logging.debug("start to_owned_crds")
355-
owned_crd_dicts = []
356-
for c in crds:
357-
for v in c["spec"]["versions"]:
358-
### Extract CRD description from different properties
359-
description = "No description available"
360-
try:
361-
# we use this field instead of schema.openAPIV3Schema.description
362-
# because that one is not set by the Rust->CRD serialization
363-
description = v["schema"]["openAPIV3Schema"]["properties"]["spec"][
364-
"description"
365-
]
366-
except KeyError:
367-
pass
368-
try:
369-
# The OPA CRD has this field set
370-
description = v["schema"]["openAPIV3Schema"]["description"]
371-
except KeyError:
372-
pass
373-
374-
owned_crd_dicts.append(
375-
{
376-
"name": c["metadata"]["name"],
377-
"displayName": c["metadata"]["name"],
378-
"kind": c["spec"]["names"]["kind"],
379-
"version": v["name"],
380-
"description": description,
381-
}
382-
)
383-
384-
logging.debug("finish to_owned_crds")
385-
return owned_crd_dicts
386-
387-
388356
def generate_csv(
389357
args: argparse.Namespace,
390-
owned_crds: list[dict],
391358
cluster_permissions: list[tuple[str, dict]],
392359
deployments: list[dict],
393360
related_images: list[dict[str, str]],
@@ -414,12 +381,6 @@ def generate_csv(
414381
f"https://github.com/stackabletech/{args.op_name}"
415382
)
416383

417-
# Commented out as it caused problems with the certification pipeline.
418-
# result["metadata"]["annotations"]["olm.skipRange"] = f'< {args.release}'
419-
420-
### 1. Add list of owned crds
421-
result["spec"]["customresourcedefinitions"]["owned"] = owned_crds
422-
423384
### 2. Add list of related images
424385
result["spec"]["relatedImages"] = related_images
425386

@@ -522,26 +483,6 @@ def generate_helm_templates(args: argparse.Namespace) -> list[dict]:
522483
)
523484

524485

525-
def generate_crds(repo_operator: pathlib.Path) -> list[dict]:
526-
logging.debug(f"start generate_crds for {repo_operator}")
527-
crd_path = (
528-
repo_operator / "deploy" / "helm" / repo_operator.name / "crds" / "crds.yaml"
529-
)
530-
531-
logging.info(f"Reading CRDs from {crd_path}")
532-
crds = list(yaml.load_all(crd_path.read_text(), Loader=yaml.SafeLoader))
533-
for crd in crds:
534-
if crd["kind"] == "CustomResourceDefinition":
535-
# Remove the helm.sh/resource-policy annotation
536-
del crd["metadata"]["annotations"]["helm.sh/resource-policy"]
537-
else:
538-
raise ManifestException(
539-
f'Expected "CustomResourceDefinition" but found kind "{crd["kind"]}" in CRD file "{crd_path}"'
540-
)
541-
logging.debug("finish generate_crds")
542-
return crds
543-
544-
545486
def quay_image(images: list[tuple[str, str]]) -> list[dict[str, str]]:
546487
"""Get the images for the operator from quay.io. See: https://docs.quay.io/api/swagger"""
547488
logging.debug("start op_image")

0 commit comments

Comments
 (0)