Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ jobs:
run: |
task operator:ci

# TODO(fcanovai): this has been disabled in #85 because the image build there is now Debian based and
# the Red Hat preflight certification fails. It should be re-enabled once we have an image built on Red Hat UBI.
#- name: Run Red Hat preflight certification
# run: |
# # Certify the operator image just built and pushed by operator:ci
# IMAGE=$(jq -r '.default."image.name" | split(",")[0]' operator/metadata.json)
# task olm:preflight-container IMAGE="${IMAGE}"
- name: Run Red Hat preflight certification
run: |
# Certify the UBI variant of the operator image just built and pushed
# by operator:ci. Preflight only accepts a Red Hat UBI base, so the
# distroless variant is not a candidate.
IMAGE=$(jq -r '.ubi."image.name" | split(",")[0]' operator/metadata.json)
task olm:preflight-container IMAGE="${IMAGE}"

integration-tests:
name: Integration Tests
Expand Down
7 changes: 6 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ vars:
# the two must use the same version.
# renovate: datasource=docker depName=quay.io/opdev/preflight versioning=docker
PREFLIGHT_VERSION: 1.20.0@sha256:b8fa820097c088957a00f83b729595d26a9e0a97da568188bdc3361f9346aa26
# Tag suffix of the UBI variant of the operator image, as produced by the
# "ubi" target of operator/docker-bake.hcl. The OLM bundle ships the UBI
# image, since that is the variant submitted to Red Hat certification.
UBI_TAG_SUFFIX: '-ubi9'
ALLOWED_ENVS: [testing, production]

tasks:
Expand Down Expand Up @@ -740,6 +744,7 @@ tasks:
insecure: '{{ if .GITHUB_ACTIONS }}false{{ else }}true{{ end }}'
suffix: '{{ if ( ne .ENVIRONMENT "production" ) }}-testing{{end}}'
tag: '{{ .TAG | default .IMAGE_TAG }}'
ubi_suffix: '{{ .UBI_TAG_SUFFIX }}'
# renovate: datasource=git-refs depName=kustomize lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
DAGGER_KUSTOMIZE_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52
cmds:
Expand All @@ -761,7 +766,7 @@ tasks:
GITHUB_REF= dagger -s call -m github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
edit --source .
--dir operator/config/manifests
set image --image controller=${registry}/klio-operator${suffix}:${tag}
set image --image controller=${registry}/klio-operator${suffix}:${tag}${ubi_suffix}
directory directory --path operator/config/manifests export --path operator/config/manifest-build
- >
GITHUB_REF= dagger -s call -m github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
Expand Down
1 change: 1 addition & 0 deletions documentation/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ deduplicated
deduplication
deployable
dev
distroless
docusaurus
durations
env
Expand Down
18 changes: 9 additions & 9 deletions documentation/web/docs/developer/openshift_testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ certification policies. Two checks cover the two artifacts:

- **`check container`** — static policy checks on the operator image
(labels, layers, license, base image). It needs no cluster and runs
in the Dagger engine via `task olm:preflight-container`.
in the Dagger engine on every PR via `task olm:preflight-container`.
It is run against the UBI variant of the operator image, since the
base-image policy only accepts a Red Hat UBI base.
- **`check operator`** — installs the bundle through OLM into a live
OpenShift cluster and verifies it is deployable. Because it needs a
real OpenShift cluster (OLM and Security Context Constraints), it runs
Expand All @@ -247,14 +249,12 @@ certification policies. Two checks cover the two artifacts:

:::note

Both checks are currently **disabled in CI**. The operator and operand
images are built on Debian instead of Red Hat UBI, which the
`check container` base-image policy rejects, and `check operator` is
parked alongside it. The steps are commented out in
`.github/workflows/ci.yml` and `.github/workflows/openshift-e2e.yml`,
ready to be restored once a UBI-based image variant is built again — see
[issue #85](https://github.com/cloudnative-pg/klio/issues/85). Both
tasks still work when run manually, as described below.
The operator image is built in two variants: a distroless Debian one,
which is the default and carries the plain tag, and a Red Hat UBI one,
tagged with a `-ubi9` suffix. Certification concerns the UBI variant
only: `check container` runs against it, and the OLM bundle references
it, so `check operator` exercises it too. The operand (`klio`) image is
Debian based and is not part of the operator certification.

:::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
alm-examples: '[]'
capabilities: Basic Install
categories: Database
containerImage: ghcr.io/cloudnative-pg/klio-operator:latest
containerImage: ghcr.io/cloudnative-pg/klio-operator:latest-ubi9
createdAt:
description: Enterprise-grade backup and recovery manager for PostgreSQL
clusters managed by CloudNativePG on Kubernetes.
Expand Down
47 changes: 37 additions & 10 deletions operator/docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ variable "base_image" {
default = "gcr.io/distroless/static-debian13:nonroot@sha256:f7f8f729987ad0fdf6b05eeeae94b26e6a0f613bdf46feea7fc40f7bd72953e6"
}

variable "ubi_base_image" {
// renovate image: datasource=docker depName=registry.access.redhat.com/ubi9/ubi-micro versioning=docker
default = "registry.access.redhat.com/ubi9/ubi-micro:9.8-1786321990@sha256:7e7f79ab747bf2b452e3043dd89f388e92be4c7fdcc8b815b58adf6c99c39c95"
}

// The image variants we build. Each one is a separate target of the "default"
// group, built from the same Dockerfile with a different base image. The
// distroless variant is the primary one and keeps the plain tag; the UBI
// variant is the one submitted to Red Hat certification.
distros = {
distroless = {
baseImage = base_image
tagSuffix = ""
}
ubi = {
baseImage = ubi_base_image
tagSuffix = "-ubi9"
}
}

function "getRegistry" {
params = []
result = lower(registry)
Expand All @@ -49,6 +69,11 @@ variable "version" {
}

target "default" {
matrix = {
distro = ["distroless", "ubi"]
}
name = distro

dockerfile = "Dockerfile"
context = "."
platforms = [
Expand All @@ -57,12 +82,12 @@ target "default" {
]

tags = [
latest("${getImageName()}", "${latest}"),
"${getImageName()}:${version}",
latest("${getImageName()}", "${latest}", "${distros[distro].tagSuffix}"),
"${getImageName()}:${version}${distros[distro].tagSuffix}",
]

args = {
"BASE_IMAGE" = "${base_image}",
"BASE_IMAGE" = "${distros[distro].baseImage}",
}

output = [
Expand All @@ -89,8 +114,8 @@ target "default" {
"index,manifest:org.opencontainers.image.documentation=${documentation}",
"index,manifest:org.opencontainers.image.authors=${authors}",
"index,manifest:org.opencontainers.image.licenses=${license}",
"index,manifest:org.opencontainers.image.base.name=${baseName(base_image)}",
"index,manifest:org.opencontainers.image.base.digest=${digest(base_image)}",
"index,manifest:org.opencontainers.image.base.name=${baseName(distros[distro].baseImage)}",
"index,manifest:org.opencontainers.image.base.digest=${digest(distros[distro].baseImage)}",
]
labels = {
"org.opencontainers.image.created" = "${now}",
Expand All @@ -104,8 +129,8 @@ target "default" {
"org.opencontainers.image.documentation" = "${documentation}",
"org.opencontainers.image.authors" = "${authors}",
"org.opencontainers.image.licenses" = "${license}",
"org.opencontainers.image.base.name" = "${baseName(base_image)}",
"org.opencontainers.image.base.digest" = "${digest(base_image)}",
"org.opencontainers.image.base.name" = "${baseName(distros[distro].baseImage)}",
"org.opencontainers.image.base.digest" = "${digest(distros[distro].baseImage)}",
"name" = "${title}",
"maintainer" = "${authors}",
"vendor" = "${authors}",
Expand All @@ -123,13 +148,15 @@ function digest {
}

// We get the image reference without the sha256, so that the base.name label
// is always derived from base_image and cannot drift away from it.
// is always derived from the variant's base image and cannot drift away from it.
function baseName {
params = [ imageNameWithSha ]
result = index(split("@", imageNameWithSha), 0)
}

// The moving tag of each variant: ":latest" for the primary one and
// ":latest<suffix>" for the others, so the variants never collide on it.
function latest {
params = [ image, latest ]
result = (latest == "true") ? "${image}:latest" : ""
params = [ image, latest, tagSuffix ]
result = (latest == "true") ? "${image}:latest${tagSuffix}" : ""
}
Loading