Build the Olm bundle and test it in CI (#10949)

* Building the OLM bundle

* kustomize the main CRD for the OLM bundle

* minor fixes
This commit is contained in:
Andrea Peruffo 2022-04-08 09:22:01 +01:00 committed by GitHub
parent d952669f69
commit 7816e69e38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 539 additions and 35 deletions

View file

@ -17,30 +17,58 @@ concurrency:
jobs: jobs:
build: build:
name: Build name: Build distribution
if: ${{ ( github.event_name != 'schedule' ) || ( github.event_name == 'schedule' && github.repository == 'keycloak/keycloak' ) }} if: ${{ ( github.event_name != 'schedule' ) || ( github.event_name == 'schedule' && github.repository == 'keycloak/keycloak' ) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set outputs
id: vars
run: echo "::set-output name=version::0.0.1-$(git rev-parse --short HEAD)"
- name: Update maven settings - name: Update maven settings
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/ run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
- uses: actions/setup-java@v2 - uses: actions/setup-java@v2
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: ${{ env.JDK_VERSION }} java-version: ${{ env.JDK_VERSION }}
- name: Cache Maven packages cache: 'maven'
id: cache
uses: actions/cache@v3
with:
path: |
~/.m2/repository
key: cache-1-${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: cache-1-${{ runner.os }}-m2
- name: Create the Keycloak distribution - name: Create the Keycloak distribution
run: | run: |
mvn clean install -Pdistribution -DskipTests -DskipExamples -DskipTestsuite mvn clean install -Pdistribution -DskipTests -DskipExamples -DskipTestsuite
- name: Login to docker registry
uses: docker/login-action@v1.14.1
with:
registry: ${{ secrets.TEST_DOCKER_REGISTRY }}
username: ${{ secrets.TEST_DOCKER_USERNAME }}
password: ${{ secrets.TEST_DOCKER_TOKEN }}
- name: Build and push the Keycloak Docker image
working-directory: quarkus/container
run: |
cp ../dist/target/keycloak-*.tar.gz ./
docker build --label "quay.expires-after=20h" --build-arg KEYCLOAK_DIST=$(ls keycloak-*.tar.gz) . -t ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak:${{ steps.vars.outputs.version }}
docker push ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak:${{ steps.vars.outputs.version }}
- name: Build and push a custom pre-augmented Keycloak Docker image
working-directory: operator
run: |
./scripts/build-testing-docker-images.sh ${{ steps.vars.outputs.version }} ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/custom-keycloak
docker push ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/custom-keycloak:${{ steps.vars.outputs.version }}
test-local:
name: Test local
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v3
- name: Set outputs
id: vars
run: echo "::set-output name=version::0.0.1-$(git rev-parse --short HEAD)"
- name: Update maven settings
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: ${{ env.JDK_VERSION }}
cache: 'maven'
- name: Setup Minikube-Kubernetes - name: Setup Minikube-Kubernetes
uses: manusa/actions-setup-minikube@v2.4.3 uses: manusa/actions-setup-minikube@v2.4.3
with: with:
@ -50,38 +78,121 @@ jobs:
driver: docker driver: docker
start args: '--addons=ingress' start args: '--addons=ingress'
- name: Build the Keycloak Docker image
run: |
cd quarkus
cp dist/target/keycloak-*.tar.gz container/
cd container
eval $(minikube -p minikube docker-env)
docker build --build-arg KEYCLOAK_DIST=$(ls keycloak-*.tar.gz) . -t keycloak:${GITHUB_SHA}
- name: Build a custom pre-augmented Keycloak Docker image
working-directory: operator
run: |
eval $(minikube -p minikube docker-env)
./scripts/build-testing-docker-images.sh ${GITHUB_SHA} keycloak
- name: Test operator running locally - name: Test operator running locally
working-directory: operator working-directory: operator
run: | run: |
mvn clean verify \ mvn clean verify \
-Dquarkus.kubernetes.deployment-target=kubernetes \ -Dquarkus.kubernetes.deployment-target=kubernetes \
-Doperator.keycloak.image=keycloak:${GITHUB_SHA} \ -Doperator.keycloak.image=${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak:${{ steps.vars.outputs.version }} \
-Doperator.keycloak.image-pull-policy=Never \ -Dtest.operator.custom.image=${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/custom-keycloak:${{ steps.vars.outputs.version }} \
-Dtest.operator.kubernetes.ip=$(minikube ip) \ -Dtest.operator.kubernetes.ip=$(minikube ip)
-Dtest.operator.custom.image=custom-keycloak:${GITHUB_SHA}
test-remote:
name: Test remote
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v3
- name: Set outputs
id: vars
run: echo "::set-output name=version::0.0.1-$(git rev-parse --short HEAD)"
- name: Update maven settings
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: ${{ env.JDK_VERSION }}
cache: 'maven'
- name: Setup Minikube-Kubernetes
uses: manusa/actions-setup-minikube@v2.4.3
with:
minikube version: v1.24.0
kubernetes version: v1.22.3
github token: ${{ secrets.GITHUB_TOKEN }}
driver: docker
start args: '--addons=ingress'
- name: Test operator running in cluster - name: Test operator running in cluster
working-directory: operator working-directory: operator
run: | run: |
eval $(minikube -p minikube docker-env) eval $(minikube -p minikube docker-env)
mvn clean verify \ mvn clean verify \
-Dquarkus.container-image.build=true -Dquarkus.container-image.tag=test \ -Dquarkus.container-image.build=true \
-Dquarkus.kubernetes.deployment-target=kubernetes \ -Dquarkus.kubernetes.deployment-target=kubernetes \
-Dquarkus.jib.jvm-arguments="-Djava.util.logging.manager=org.jboss.logmanager.LogManager","-Doperator.keycloak.image=keycloak:${GITHUB_SHA}","-Doperator.keycloak.image-pull-policy=Never" \ -Dquarkus.jib.jvm-arguments="-Djava.util.logging.manager=org.jboss.logmanager.LogManager","-Doperator.keycloak.image=${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak:${{ steps.vars.outputs.version }}" \
-Dtest.operator.custom.image=${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/custom-keycloak:${{ steps.vars.outputs.version }} \
--no-transfer-progress -Dtest.operator.deployment=remote \ --no-transfer-progress -Dtest.operator.deployment=remote \
-Dtest.operator.kubernetes.ip=$(minikube ip) \ -Dtest.operator.kubernetes.ip=$(minikube ip)
-Dtest.operator.custom.image=custom-keycloak:${GITHUB_SHA}
test-olm:
name: Test OLM installation
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v3
- name: Set outputs
id: vars
run: echo "::set-output name=version::0.0.1-$(git rev-parse --short HEAD)"
- name: Update maven settings
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: ${{ env.JDK_VERSION }}
cache: 'maven'
- name: Setup Minikube-Kubernetes
uses: manusa/actions-setup-minikube@v2.4.3
with:
minikube version: v1.24.0
kubernetes version: v1.22.3
github token: ${{ secrets.GITHUB_TOKEN }}
driver: docker
start args: '--addons=ingress'
- name: Login to docker registry
uses: docker/login-action@v1.14.1
with:
registry: ${{ secrets.TEST_DOCKER_REGISTRY }}
username: ${{ secrets.TEST_DOCKER_USERNAME }}
password: ${{ secrets.TEST_DOCKER_TOKEN }}
- name: Build and push the operator image
working-directory: operator
run: |
mvn clean package \
-Dquarkus.container-image.build=true \
-Dquarkus.container-image.push=true \
-Dquarkus.container-image.image="${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }}/keycloak-operator:${{ steps.vars.outputs.version }}" \
-Dquarkus.container-image.labels."\"quay.expires-after\""="20h" \
-DskipTests
- name: Install OPM
uses: redhat-actions/openshift-tools-installer@v1
with:
source: "github"
opm: "1.21.0"
- name: Install Yq
run: sudo snap install yq
- name: Install OLM
working-directory: operator
run: ./scripts/install-olm.sh
- name: Prepare resources for testing on OLM
working-directory: operator
run: |
./scripts/prepare-olm-test.sh ${{ secrets.TEST_DOCKER_REGISTRY }}/${{ secrets.TEST_DOCKER_REPOSITORY }} ${{ steps.vars.outputs.version }} NONE
- name: Install the operator with OLM
working-directory: operator
run: ./scripts/install-keycloak-operator.sh
- name: Deploy an example Keycloak and wait for it to be ready
working-directory: operator
run: |
kubectl apply -f src/main/resources/example-postgres.yaml
./scripts/check-crds-installed.sh
kubectl apply -f src/main/resources/example-keycloak.yml
kubectl apply -f src/main/resources/example-realm.yaml
# Wait for the CRs to be ready
./scripts/check-examples-installed.sh

1
operator/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
olm

View file

@ -0,0 +1,14 @@
FROM scratch
# Core bundle labels.
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
LABEL operators.operatorframework.io.bundle.package.v1=keycloak-operator
LABEL operators.operatorframework.io.bundle.channels.v1=candidate
LABEL operators.operatorframework.io.bundle.channel.default.v1=candidate
LABEL com.redhat.openshift.versions=v4.6
# Copy files to locations specified by labels.
COPY manifests /manifests/
COPY metadata /metadata/

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
annotations:
# Core bundle annotations.
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
operators.operatorframework.io.bundle.manifests.v1: manifests/
operators.operatorframework.io.bundle.metadata.v1: metadata/
operators.operatorframework.io.bundle.package.v1: keycloak-operator
operators.operatorframework.io.bundle.channels.v1: candidate
operators.operatorframework.io.bundle.channel.default.v1: candidate
com.redhat.openshift.versions: "v4.6"

View file

@ -1,7 +1,9 @@
#!/usr/bin/env bash #! /bin/bash
set -euxo pipefail
VERSION="${1:-latest}" VERSION="${1:-latest}"
KEYCLOAK_IMAGE="${2:-quay.io/keycloak/keycloak}" KEYCLOAK_IMAGE="${2:-quay.io/keycloak/keycloak}"
KEYCLOAK_CUSTOM_IMAGE="${3:-quay.io/keycloak/custom-keycloak}"
echo "Using version: $VERSION" echo "Using version: $VERSION"
@ -10,4 +12,4 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -f ${SCRIPT_DIR}/Dockerfile-custom-image \ docker build -f ${SCRIPT_DIR}/Dockerfile-custom-image \
--build-arg IMAGE=${KEYCLOAK_IMAGE} \ --build-arg IMAGE=${KEYCLOAK_IMAGE} \
--build-arg VERSION=${VERSION} \ --build-arg VERSION=${VERSION} \
-t custom-keycloak:${VERSION} ${SCRIPT_DIR} -t ${KEYCLOAK_CUSTOM_IMAGE}:${VERSION} ${SCRIPT_DIR}

View file

@ -0,0 +1,19 @@
#! /bin/bash
set -euxo pipefail
max_retries=240
c=0
while ! kubectl get keycloaks
do
echo "waiting for Keycloak CRD"
((c++)) && ((c==max_retries)) && exit -1
sleep 1
done
c=0
while ! kubectl get keycloakrealmimports
do
echo "waiting for Keycloak Realm Import CRD"
((c++)) && ((c==max_retries)) && exit -1
sleep 1
done

View file

@ -0,0 +1,19 @@
#! /bin/bash
set -euxo pipefail
max_retries=240
c=0
while [[ $(kubectl get keycloaks/example-kc -o jsonpath="{.status.conditions[?(@.type == 'Ready')].status}") != "true" ]]
do
echo "waiting for Keycloak example-kc status"
((c++)) && ((c==max_retries)) && exit -1
sleep 1
done
c=0
while [[ $(kubectl get keycloakrealmimports/example-count0-kc -o jsonpath="{.status.conditions[?(@.type == 'Done')].status}") != "true" ]]
do
echo "waiting for Keycloak Realm Import example-count0-kc status"
((c++)) && ((c==max_retries)) && exit -1
sleep 1
done

View file

@ -0,0 +1,40 @@
#! /bin/bash
set -euxo pipefail
VERSION=$1
REPLACES_VERSION=$2
OPERATOR_DOCKER_IMAGE=$3
CREATED_AT=$(date "+%D %T")
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
echo "Creating OLM bundle for version $VERSION replacing version $REPLACES_VERSION"
rm -rf $SCRIPT_DIR/../olm/$VERSION
mkdir -p $SCRIPT_DIR/../olm/$VERSION
cp -r $SCRIPT_DIR/../olm-base/* $SCRIPT_DIR/../olm/$VERSION
# Inject RBAC rules
yq ea '.rules as $item ireduce ({}; .rules += $item)' $SCRIPT_DIR/../target/kubernetes/kubernetes.yml | \
yq ea -i 'select(fileIndex==0).spec.install.spec.permissions[0] = select(fileIndex==1) | select(fileIndex==0)' $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml - && \
yq ea -i '.spec.install.spec.permissions[0].serviceAccountName = "keycloak-operator"' $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml && \
yq ea -i ".metadata.annotations.containerImage = \"$OPERATOR_DOCKER_IMAGE:$VERSION\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml && \
yq ea -i ".metadata.annotations.createdAt = \"$CREATED_AT\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml && \
yq ea -i ".metadata.name = \"keycloak-operator.v$VERSION\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml && \
yq ea -i ".spec.install.spec.deployments[0].spec.template.spec.containers[0].image = \"$OPERATOR_DOCKER_IMAGE:$VERSION\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml && \
yq ea -i ".spec.version = \"$VERSION\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml
if [[ $REPLACES_VERSION = "NONE" ]]
then
yq ea -i "del(.spec.replaces)" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml
else
yq ea -i ".spec.replaces = \"keycloak-operator.v$REPLACES_VERSION\"" $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml
fi
mv $SCRIPT_DIR/../olm/$VERSION/manifests/clusterserviceversion.yaml "$SCRIPT_DIR/../olm/$VERSION/manifests/keycloak-operator.v$VERSION.clusterserviceversion.yaml"
# Include the old CRD version
( cd $SCRIPT_DIR/../ && kubectl kustomize target | yq ea "select(.metadata.name == \"keycloaks.keycloak.org\")" > $SCRIPT_DIR/../olm/$VERSION/manifests/keycloaks.keycloak.org-v1.yml )
cp $SCRIPT_DIR/../target/kubernetes/keycloakrealmimports.keycloak.org-v1.yml $SCRIPT_DIR/../olm/$VERSION/manifests

View file

@ -0,0 +1,34 @@
#! /bin/bash
set -euxo pipefail
VERSION=$1
BUNDLE_IMAGE=$2
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
rm -rf $SCRIPT_DIR/../olm/catalog
mkdir -p $SCRIPT_DIR/../olm/catalog/test-catalog
(
cd $SCRIPT_DIR/../olm/catalog
opm generate dockerfile test-catalog
opm init keycloak-operator \
--default-channel=alpha \
--output yaml > test-catalog/operator.yaml
opm render $BUNDLE_IMAGE:$VERSION \
--output=yaml >> test-catalog/operator.yaml
cat << EOF >> test-catalog/operator.yaml
---
schema: olm.channel
package: keycloak-operator
name: alpha
entries:
- name: keycloak-operator.v$VERSION
EOF
opm validate test-catalog
)

View file

@ -0,0 +1,55 @@
#! /bin/bash
set -euxo pipefail
VERSION=$1
DOCKER_REGISTRY=$2
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
rm -rf $SCRIPT_DIR/../olm/testing-resources
mkdir -p $SCRIPT_DIR/../olm/testing-resources
cat << EOF >> $SCRIPT_DIR/../olm/testing-resources/catalog.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: test-catalog
namespace: default
spec:
sourceType: grpc
image: $DOCKER_REGISTRY/keycloak-test-catalog:$VERSION
displayName: Keycloak Test Catalog
publisher: Me
updateStrategy:
registryPoll:
interval: 10m
EOF
cat << EOF >> $SCRIPT_DIR/../olm/testing-resources/operatorgroup.yaml
kind: OperatorGroup
apiVersion: operators.coreos.com/v1
metadata:
name: og-single
namespace: default
spec:
targetNamespaces:
- default
EOF
cat << EOF >> $SCRIPT_DIR/../olm/testing-resources/subscription.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: keycloak-operator
namespace: default
spec:
installPlanApproval: Automatic
name: keycloak-operator
source: test-catalog
sourceNamespace: default
startingCSV: keycloak-operator.v$VERSION
config:
env:
- name: "OPERATOR_KEYCLOAK_IMAGE"
value: "$DOCKER_REGISTRY/keycloak:$VERSION"
EOF

View file

@ -0,0 +1,9 @@
#! /bin/bash
set -euxo pipefail
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# Delete the default catalog if it exists
sh -c "kubectl delete catalogsources operatorhubio-catalog -n olm | true"
kubectl apply -f $SCRIPT_DIR/../olm/testing-resources

View file

@ -0,0 +1,7 @@
#! /bin/bash
set -euxo pipefail
mkdir -p /tmp/olm/
curl -L https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.20.0/install.sh -o /tmp/olm/install.sh
chmod +x /tmp/olm/install.sh
/tmp/olm/install.sh v0.20.0

View file

@ -0,0 +1,32 @@
#! /bin/bash
set -euxo pipefail
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
DOCKER_REGISTRY="$1"
VERSION="$2"
PREV_VERSION="$3"
OPERATOR_IMAGE_NAME="keycloak-operator"
OPERATOR_DOCKER_IMAGE="$DOCKER_REGISTRY/$OPERATOR_IMAGE_NAME"
# Create OLM bundle
$SCRIPT_DIR/create-olm-bundle.sh $VERSION $PREV_VERSION $OPERATOR_DOCKER_IMAGE
(cd $SCRIPT_DIR/../olm/$VERSION && \
docker build --label "quay.expires-after=20h" -t $DOCKER_REGISTRY/keycloak-operator-bundle:$VERSION -f bundle.Dockerfile . && \
docker push $DOCKER_REGISTRY/keycloak-operator-bundle:$VERSION)
# Verify the bundle
opm alpha bundle validate --tag $DOCKER_REGISTRY/keycloak-operator-bundle:$VERSION --image-builder docker
# Create the test-catalog
$SCRIPT_DIR/create-olm-test-catalog.sh $VERSION $DOCKER_REGISTRY/keycloak-operator-bundle
(cd $SCRIPT_DIR/../olm/catalog && \
docker build --label "quay.expires-after=20h" -f test-catalog.Dockerfile -t $DOCKER_REGISTRY/keycloak-test-catalog:$VERSION . && \
docker push $DOCKER_REGISTRY/keycloak-test-catalog:$VERSION)
# Create testing resources
$SCRIPT_DIR/create-olm-test-resources.sh $VERSION $DOCKER_REGISTRY

View file

@ -1092,7 +1092,7 @@
- version - version
type: object type: object
type: object type: object
served: false served: true
storage: false storage: false
subresources: subresources:
status: {} status: {}

View file

@ -5,6 +5,9 @@ metadata:
rules: rules:
- apiGroups: - apiGroups:
- apps - apps
# Extensions enabled for backward compatibility:
# https://github.com/fabric8io/kubernetes-client/issues/3996
- extensions
resources: resources:
- deployments - deployments
verbs: verbs:

View file

@ -5,6 +5,7 @@ namespace: keycloak
resources: resources:
- kubernetes/keycloaks.keycloak.org-v1.yml - kubernetes/keycloaks.keycloak.org-v1.yml
- kubernetes/keycloakrealmimports.keycloak.org-v1.yml
- kubernetes/kubernetes.yml - kubernetes/kubernetes.yml
# patchesStrategicMerge # patchesStrategicMerge