Skip to content

Commit

Permalink
Merge pull request #267 from HumairAK/release_docs
Browse files Browse the repository at this point in the history
Release docs
  • Loading branch information
openshift-merge-robot authored Aug 16, 2023
2 parents 61b32f7 + 2bea1f7 commit 613ce0c
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/image-check.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Image-check
on:
pull_request:
branches:
- v*
jobs:
test:
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ Dockerfile.cross
.odo
*.code-workspace
*.vscode

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
22 changes: 11 additions & 11 deletions config/base/params.env
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
IMAGES_APISERVER=quay.io/opendatahub/ds-pipelines-api-server@sha256:4650c62254cd79112de3e4f09270130501d0d86a4dea79b74c2fcb8b5ca567e7
IMAGES_ARTIFACT=quay.io/opendatahub/ds-pipelines-artifact-manager@sha256:58a13845901f8aae5421f640eeebee0abf3b12b27c1f96fbc8ff199b7e4f8d8d
IMAGES_PERSISTENTAGENT=quay.io/opendatahub/ds-pipelines-persistenceagent@sha256:c8b0953c28fd24180ddd24a30c68df411d299ccc7f6bc18ab15f4dba4a84b7d9
IMAGES_SCHEDULEDWORKFLOW=quay.io/opendatahub/ds-pipelines-scheduledworkflow@sha256:31d049e74ab038f3a6d3ff9fa8953a4d0ddb21b0efc43fbb5b07fbaf83817022
IMAGES_MLMDENVOY=quay.io/opendatahub/ds-pipelines-metadata-envoy@sha256:f2d5d430bbc925520f635f35698e604aae391ace39b15a5d601a9c9eb26dec2b
IMAGES_MLMDGRPC=quay.io/opendatahub/ds-pipelines-metadata-grpc@sha256:2490aadb2227cc72fd9e698549a8cd3270b669a2faa24bb0603c37f1c71ac8c4
IMAGES_MLMDWRITER=quay.io/opendatahub/ds-pipelines-metadata-writer@sha256:89fc26374f8e58384628f6b178eb9b8e3ebb111fe395c529d0b65ba8adaa89f5
IMAGES_DSPO=quay.io/opendatahub/data-science-pipelines-operator@sha256:c1d77b668149396a4409926eea279647c817a02868a3d21f9a4b5f30c1e86766
IMAGES_CACHE=registry.access.redhat.com/ubi8/ubi-minimal@sha256:e52fc1de73dc2879516431ff1865e0fb61b1a32f57b6f914bdcddb13c62f84e6
IMAGES_MOVERESULTSIMAGE=registry.access.redhat.com/ubi8/ubi-micro@sha256:443db9a646aaf9374f95d266ba0c8656a52d70d0ffcc386a782cea28fa32e55d
IMAGES_MARIADB=registry.redhat.io/rhel8/mariadb-103@sha256:6c3ae581b754017b335a70388c0010cf729df8a29daeb6651642ebee4e8abfde
IMAGES_APISERVER=quay.io/opendatahub/ds-pipelines-api-server:latest
IMAGES_ARTIFACT=quay.io/opendatahub/ds-pipelines-artifact-manager:latest
IMAGES_PERSISTENTAGENT=quay.io/opendatahub/ds-pipelines-persistenceagent:latest
IMAGES_SCHEDULEDWORKFLOW=quay.io/opendatahub/ds-pipelines-scheduledworkflow:latest
IMAGES_MLMDENVOY=quay.io/opendatahub/ds-pipelines-metadata-envoy:latest
IMAGES_MLMDGRPC=quay.io/opendatahub/ds-pipelines-metadata-grpc:latest
IMAGES_MLMDWRITER=quay.io/opendatahub/ds-pipelines-metadata-writer:latest
IMAGES_DSPO=quay.io/opendatahub/data-science-pipelines-operator:latest
IMAGES_CACHE=registry.access.redhat.com/ubi8/ubi-minimal:8.8
IMAGES_MOVERESULTSIMAGE=registry.access.redhat.com/ubi8/ubi-micro:8.8
IMAGES_MARIADB=registry.redhat.io/rhel8/mariadb-103:1
IMAGES_OAUTHPROXY=registry.redhat.io/openshift4/ose-oauth-proxy@sha256:ab112105ac37352a2a4916a39d6736f5db6ab4c29bad4467de8d613e80e9bb33
36 changes: 36 additions & 0 deletions docs/release/compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!--THIS DOC IS AUTO GENERATED-->
# DSP Version Compatibility Table

This is an auto generated DSP version compatibility table.
Each row outlines the versions for individual subcomponents and images that are leveraged within DSP.

For some components, the versions match with their respective image tags within their respective Quay, GCR, or RedHat image
registries, this is true for the following:

* [ml-metadata]
* [envoy]
* [oauth-proxy]
* for Oauth Proxy DSP follows the same version digest as the Oauth Proxy leveraged within the rest of ODH.
* [mariaDB]
* for MariaDB the entire column represents different tag versions for MariDB Version 10.3, DSP follows the latest digest for the `1` tag
for each DSP release.
* [ubi-minimal]
* Used for default base images during Pipeline Runs
* [ubi-micro]
* Used for default cache image for runs


| dsp | kfp-tekton | ml-metadata | envoy | ocp-pipelines | oauth-proxy | mariadb-103 | ubi-minimal | ubi-micro | openshift |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 1.0.x | 1.5.1 | 1.5.0 | 1.8.4 | v4.10 | v4.12 | 1 | 8.8 | 8.8 | 4.10,4.11,4.12 |
| 1.1.x | 1.5.1 | 1.5.0 | 1.8.4 | v4.10 | v4.12 | 1 | 8.8 | 8.8 | 4.10,4.11,4.12 |
| 1.2.x | 1.5.1 | 1.5.0 | 1.8.4 | v4.10 | v4.10 | 1 | 8.8 | 8.8 | 4.10,4.11,4.12 |



[ml-metadata]: https://github.com/opendatahub-io/data-science-pipelines/blob/master/third-party/ml-metadata/Dockerfile#L15
[envoy]: https://github.com/opendatahub-io/data-science-pipelines/blob/master/third-party/metadata_envoy/Dockerfile#L15
[oauth-proxy]: https://catalog.redhat.com/software/containers/openshift4/ose-oauth-proxy/5cdb2133bed8bd5717d5ae64?tag=v4.13.0-202307271338.p0.g44af5a3.assembly.stream&push_date=1691493453000
[mariaDB]: https://catalog.redhat.com/software/containers/rhel8/mariadb-103/5ba0acf2d70cc57b0d1d9e78
[ubi-minimal]: https://catalog.redhat.com/software/containers/ubi8/ubi-minimal/5c359a62bed8bd75a2c3fba8?architecture=amd64&tag=8.8
[ubi-micro]: https://catalog.redhat.com/software/containers/ubi8-micro/601a84aadd19c7786c47c8ea?architecture=amd64&tag=8.8
30 changes: 30 additions & 0 deletions docs/release/compatibility.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- dsp: 1.0.x
kfp-tekton: 1.5.1
ml-metadata: 1.5.0
envoy: 1.8.4
ocp-pipelines: v4.10
oauth-proxy: v4.12
mariadb-103: 1
ubi-minimal: 8.8
ubi-micro: 8.8
openshift: 4.10,4.11,4.12
- dsp: 1.1.x
kfp-tekton: 1.5.1
ml-metadata: 1.5.0
envoy: 1.8.4
ocp-pipelines: v4.10
oauth-proxy: v4.12
mariadb-103: 1
ubi-minimal: 8.8
ubi-micro: 8.8
openshift: 4.10,4.11,4.12
- dsp: 1.2.x
kfp-tekton: 1.5.1
ml-metadata: 1.5.0
envoy: 1.8.4
ocp-pipelines: v4.10
oauth-proxy: v4.10
mariadb-103: 1
ubi-minimal: 8.8
ubi-micro: 8.8
openshift: 4.10,4.11,4.12
97 changes: 97 additions & 0 deletions docs/release/release_workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# How to create a DSP release

This doc outlines the steps required for manually preparing and performing a DSP release.

Versioning for DSP follows [semver]:

```txt
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes
MINOR version when you add functionality in a backward compatible manner
PATCH version when you make backward compatible bug fixes
```

DSPO and DSP versioning is tied together, and DSP `MAJOR` versions are tied to [kfp-tekton] upstream.

> Note: In main branch all images should point to `latest` and not any specific versions, as `main` is rapidly moving,
> it is likely to quickly become incompatible with any specific tags/shas that are hardcoded.
## Pre-requisites
Need GitHub repo admin permissions for DSPO and DSP repos.

## Release workflow
Steps required for performing releases for `MAJOR`, `MINOR`, or `PATCH` vary depending on type.

### MAJOR Releases
Given that `MAJOR` releases often contain large scale, api breaking, changes. It is likely the release process will vary
between each `MAJOR` release. As such, each `MAJOR` release should have a specifically catered strategy.

### MINOR Releases
Let `x.y.z` be the `latest` release that is highest DSPO/DSP version.

Steps on how to release `x.y+1.z`

1. Ensure `compatibility.yaml` is upto date, and generate a new `compatibility.md`
* Use [release-tools] to accomplish this
2. Cut branch `vx.y+1.x` from `main/master`, the trailing `.x` remains unchanged (e.g. `v1.2.x`, `v1.1.x`, etc.)
* Do this for DSPO and DSP repos
3. Build images. Use the [build-tags] workflow
4. Retrieve the sha images from the resulting workflow (check quay.io for the digests)
* Using [release-tools] generate a `params.env` and submit a new pr to vx.y+1.**x** branch
* For images pulled from registry, ensure latest images are upto date
5. Perform any tests on the branch, confirm stability
* If issues are found, they should be corrected in `main/master` and be cherry-picked into this branch.
6. Create a tag release for `x.y+1.z` in DSPO and DSP (e.g. `v1.3.0`)
7. Add any manifest changes to ODH manifests repo using the [ODH sync workflow]

**Downstream Specifics**

Downstream maintainers of DSP should forward any manifest changes to their odh-manifests downstream

### PATCH Releases
DSP supports bug/security fixes for versions that are at most 1 `MINOR` versions behind the latest `MINOR` release.
For example, if `v1.2` is the `latest` DSP release, DSP will backport bugs/security fixes to `v1.1` as `PATCH` (z) releases.

Let `x.y.z` be the `latest` release that is the highest version.\
Let `x.y-1.a` be the highest version release that is one `MINOR` version behind `x.y.z`

**Example**:
If the latest release that is the highest version is `v1.2.0`\
Then:
```txt
x.y.z = v1.2.0
x.y-1.a = v1.1.0
vx.y.z+1 = v1.2.1
vx.y-1.a+1 = v1.1.1
```

> Note `a` value in `x.y-1.a` is arbitrarily picked here. It is not always the case `z == a`, though it will likely
> be the case most of the time.
Following along our example, suppose a security bug was found in `main`, `x.y.z`, and `x.y-1.a`.
And suppose that commit `08eb98d` in `main` has resolved this issue.

Then the commit `08eb98d` needs to trickle to `vx.y.z` and `vx.y-1.a` as `PATCH` (z) releases: `vx.y.z+1` and `vx.y-1.a+1`

1. Cherry-pick commit `08eb98d` onto relevant minor branches `vx.y.x` and `vx.y-1.x`
* The trailing `.x` in branch names remains unchanged (e.g. `v1.2.x`, `v1.1.x`, etc.)
2. Build images for `vx.y.z+1` and `vx.y-1.a+1` (e.g. `v1.2.1` and `v1.1.1`) DSPO and DSP
* Images should be built off the `vx.y.x` and `vx.y-1.x` branches respectively
* Use the [build-tags] workflow
3. Retrieve the sha image digests from the resulting workflow
* Using [release-tools] generate a params.env and submit a new pr to `vx.y.x` and `vx.y-1.x` branches
4. Cut `vx.y.z+1` and `vx.y-1.a+1` in DSP and DSPO

**Downstream Specifics**

Downstream maintainers of DSP should:
* forward any manifest changes to their odh-manifests downstream
* ensure `odh-stable` branches in DSP/DSPO are upto date with bug/security fixes for the appropriate DSPO/DSP versions,
and forward any changes from `odh-stable` to their downstream DSPO/DSP repos

[semver]: https://semver.org/
[build-tags]: https://github.com/opendatahub-io/data-science-pipelines-operator/actions/workflows/build-tags.yml
[kfp-tekton]: https://github.com/kubeflow/kfp-tekton
[ODH sync workflow]: https://github.com/opendatahub-io/data-science-pipelines-operator/actions/workflows/odh-manifests-PR-sync.yml
[release-tools]: ../../scripts/release/README.md
34 changes: 34 additions & 0 deletions scripts/release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## DSP Release tools

The scripts found in this folder contain tools utilized for performing a DSP release.

### Params Generation
This tool will generate a new `params.env` file based on the upcoming DSP tags.

If images in Red Hat registry have also been updated (e.g. security fixes) without changes to tag version, then the newer
digests will be used. The following command will generate the `params.env`:

**Pre-condition**: All DSP/DSPO images should have been build with tag <DSP_TAG>
```
python release.py params --tag v1.2.0 --out_file params.env \
--override="IMAGES_OAUTHPROXY=registry.redhat.io/openshift4/ose-oauth-proxy@sha256:ab112105ac37352a2a4916a39d6736f5db6ab4c29bad4467de8d613e80e9bb33"
```

See `--help` for more options like specifying tags for images not tied to DSP (ubi, mariadb, oauth proxy, etc.)

### Compatibility Doc generation
Before each release, ensure that the [compatibility doc] is upto date. This doc is auto generated, the version compatibility
is pulled from the [compatibility yaml]. The yaml should be kept upto date by developers (manual).

To generate the version doc run the following:

**Pre-condition**: ensure that [compatibility yaml] has an entry for the latest DSP version to be released, with version
compatibility up to date.

```
python release.py --input_file compatibility.yaml --out_file compatibility.md
```


[compatibility doc]: ../../docs/release/compatibility.md
[compatibility yaml]: ../../docs/release/compatibility.yaml
143 changes: 143 additions & 0 deletions scripts/release/params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import sys

import requests

QUAY_REPOS = {
"IMAGES_APISERVER": "ds-pipelines-api-server",
"IMAGES_ARTIFACT": "ds-pipelines-artifact-manager",
"IMAGES_PERSISTENTAGENT": "ds-pipelines-persistenceagent",
"IMAGES_SCHEDULEDWORKFLOW": "ds-pipelines-scheduledworkflow",
"IMAGES_MLMDENVOY": "ds-pipelines-metadata-envoy",
"IMAGES_MLMDGRPC": "ds-pipelines-metadata-grpc",
"IMAGES_MLMDWRITER": "ds-pipelines-metadata-writer",
"IMAGES_DSPO": "data-science-pipelines-operator",
}

ARCH = "amd64"

# RH Registry Env vars
IMAGES_CACHE = "IMAGES_CACHE"
IMAGES_MOVERESULTSIMAGE = "IMAGES_MOVERESULTSIMAGE"
IMAGES_MARIADB = "IMAGES_MARIADB"
IMAGES_OAUTHPROXY = "IMAGES_OAUTHPROXY"

# RH Registry repos
REPO_UBI_MINIMAL = "ubi8/ubi-minimal"
REPO_UBI_MICRO = "ubi8/ubi-micro"
REPO_MARIADB = "rhel8/mariadb-103"
REPO_OAUTH_PROXY = "openshift4/ose-oauth-proxy"

# RH Registry servers
RH_REGISTRY_ACCESS = "registry.access.redhat.com"
RH_REGISTRY_IO = "registry.redhat.io"


def fetch_quay_repo_tag_digest(quay_repo, quay_org, tag):
api_url = f"https://quay.io/api/v1/repository/{quay_org}/{quay_repo}/tag/?specificTag={tag}"

response = requests.get(api_url).json()
tags = response['tags']

if len(tags) == 0 or 'end_ts' in tags[0]:
print("Tag does not exist or was deleted.", file=sys.stderr)
exit(1)
digest = tags[0].get('manifest_digest')
if not digest:
print("Could not find image digest when retrieving image tag.", file=sys.stderr)
exit(1)
return digest


def fetch_rh_repo_tag_digest(repo, tag):
api_url = f"https://catalog.redhat.com/api/containers/v1/repositories/registry/{RH_REGISTRY_ACCESS}/repository/{repo}/tag/{tag}"

response = requests.get(api_url).json()

amd_img = {}
for img in response['data']:
arch = img.get('architecture')
if not arch:
print(f"No 'architecture' field found when fetching image from RH registry.", file=sys.stderr)
exit(1)
if img['architecture'] == 'amd64':
amd_img = img

if not amd_img:
print(f"AMD64 arch image not found for repo {repo} and tag {tag}", file=sys.stderr)
exit(1)

sha_digest = amd_img['image_id']

return sha_digest


def generate_params(args):
tag = args.tag
quay_org = args.quay_org
file_out = args.out_file
ubi_minimal_tag = args.ubi_minimal_tag
ubi_micro_tag = args.ubi_micro_tag
mariadb_tag = args.mariadb_tag
oauth_proxy_tag = args.oauth_proxy_tag

# Structure: { "ENV_VAR": "IMG_DIGEST",...}
overrides = {}
for override in args.overrides:
entry = override.split('=')
if len(entry) != 2:
print("--override values must be of the form var=digest,\n"
"e.g: IMAGES_OAUTHPROXY=registry.redhat.io/openshift4/ose-oauth-proxy"
"@sha256:ab112105ac37352a2a4916a39d6736f5db6ab4c29bad4467de8d613e80e9bb33", file=sys.stderr)
exit(1)
overrides[entry[0]] = entry[1]

images = []
# Fetch QUAY Images
for image_env_var in QUAY_REPOS:
if image_env_var in overrides:
images.append(f"{image_env_var}={overrides[image_env_var]}")
else:
image_repo = QUAY_REPOS[image_env_var]
digest = fetch_quay_repo_tag_digest(image_repo, quay_org, tag)
image_repo_with_digest = f"{image_repo}@{digest}"
images.append(f"{image_env_var}=quay.io/opendatahub/{image_repo_with_digest}")

# Fetch RH Registry images
rh_registry_images = {
RH_REGISTRY_IO: [
{
"repo": REPO_UBI_MINIMAL,
"tag": ubi_minimal_tag,
"env": IMAGES_CACHE
},
{
"repo": REPO_UBI_MICRO,
"tag": ubi_micro_tag,
"env": IMAGES_MOVERESULTSIMAGE
},
],
RH_REGISTRY_ACCESS: [
{
"repo": REPO_MARIADB,
"tag": mariadb_tag,
"env": IMAGES_MARIADB
},
{
"repo": REPO_OAUTH_PROXY,
"tag": oauth_proxy_tag,
"env": IMAGES_OAUTHPROXY
},
]
}
for registry in rh_registry_images:
for img in rh_registry_images[registry]:
image_env_var, tag, repo = img['env'], img['tag'], img['repo']
if image_env_var in overrides:
images.append(f"{image_env_var}={overrides[image_env_var]}")
else:
digest = fetch_rh_repo_tag_digest(repo, tag)
images.append(f"{image_env_var}={registry}/{repo}@{digest}")

with open(file_out, 'w') as f:
for images in images:
f.write(f"{images}\n")
Loading

0 comments on commit 613ce0c

Please sign in to comment.