You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2022/01/31 08:58:16 UTC

[camel-k] 05/40: Converts the upgrade workflow into a composite action

This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 2591b4fa9823af0463f7b0e99e769fb69ded55fc
Author: phantomjinx <p....@phantomjinx.co.uk>
AuthorDate: Tue Nov 16 14:45:36 2021 +0000

    Converts the upgrade workflow into a composite action
    
    * Allows the re-use of the workflow actions in other workflows. This way
      the majority of changes to the workflow remain upstream and not in any
      downstream repositories.
    
    * Splits the image-registry into push and pull registeries since openshift
      uses different URLs for its internal registry when its exposed externally
    
    * Custom action takes a single json config rather than multiple inputs and
      reads them into env vars. This means that the json can be inserted into
      a single secret that is passed in from the workflow (secrets cannot be
      imported directly by actions).
---
 .github/actions/e2e-upgrade/action.yml             | 109 +++++++++++++++++++
 .github/actions/kamel-build-bundle/action.yaml     | 114 ++++++++++++++++++--
 .github/actions/kamel-build/action.yml             |  33 ++++--
 .../actions/kamel-config-cluster-custom/action.yml | 116 ++++++++++++++++++---
 .../actions/kamel-config-cluster-kind/action.yml   |  10 +-
 .../actions/kamel-config-cluster-ocp3/action.yml   |   4 +-
 .github/actions/kamel-config-cluster/action.yaml   |  96 ++++++++++-------
 .github/workflows/upgrade.yml                      |  75 +------------
 8 files changed, 411 insertions(+), 146 deletions(-)

diff --git a/.github/actions/e2e-upgrade/action.yml b/.github/actions/e2e-upgrade/action.yml
new file mode 100644
index 0000000..6edc9b5
--- /dev/null
+++ b/.github/actions/e2e-upgrade/action.yml
@@ -0,0 +1,109 @@
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+name: e2e-upgrade
+description: 'End-to-End tests for upgrading to new version'
+
+inputs:
+  platform-config:
+    description: 'The configuration of the underlying cluster (if cluster-type is custom)'
+    required: false
+
+runs:
+  using: "composite"
+
+  steps:
+  - id: prepare-env
+    name: Prepare Test Environment
+    uses: ./.github/actions/kamel-prepare-env
+    with:
+      install-opm: true
+
+  - id: configure-platform
+    name: Configure Platform
+    uses: ./.github/actions/kamel-config-cluster
+    with:
+      cluster-type: ${{ steps.prepare-env.outputs.cluster-platform }}
+      platform-config: ${{ inputs.platform-config }}
+
+  - name: Get Released Kamel CLI
+    shell: bash
+    run: |
+      export KAMEL_VERSION=$(make get-last-released-version)
+      curl -L https://github.com/apache/camel-k/releases/download/v${KAMEL_VERSION}/camel-k-client-${KAMEL_VERSION}-linux-64bit.tar.gz -o /tmp/kamel.tar.gz
+      pushd /tmp && tar -zxf kamel.tar.gz && popd > /dev/null
+      if [ ! -x /tmp/kamel ]; then
+        echo "Error: No ${KAMEL_VERSION} downloaded correctly"
+        exit 1
+      fi
+
+      #
+      # Note: cannot use GITHUB_ENV vars is same script as it was defined
+      #
+      export RELEASED_KAMEL_BINARY=/tmp/kamel-${KAMEL_VERSION}
+      echo "RELEASED_KAMEL_BINARY=${RELEASED_KAMEL_BINARY}" >> $GITHUB_ENV
+      mv /tmp/kamel ${RELEASED_KAMEL_BINARY}
+      if [ $? == 0 ]; then
+        echo "Info: Kamel version installed: $(${RELEASED_KAMEL_BINARY} version)"
+      else
+        echo "Error: Failed to install kamel binary ${KAMEL_VERSION}"
+        exit 1
+      fi
+
+  - id: build-kamel-binary
+    name: Build Kamel Binary
+    uses: ./.github/actions/kamel-build
+    with:
+      image-registry-push-host: ${{ steps.configure-platform.outputs.image-registry-push-host }}
+      image-registry-pull-host: ${{ steps.configure-platform.outputs.image-registry-pull-host }}
+      image-namespace: ${{ steps.configure-platform.outputs.image-namespace }}
+      # Avoid overwriting last-released version of binary
+      install-kamel-binary: false
+
+  - id: build-kamel-bundle
+    name: Build Kamel Metadata Bundle
+    uses: ./.github/actions/kamel-build-bundle
+    with:
+      image-registry-push-host: ${{ steps.configure-platform.outputs.image-registry-push-host }}
+      image-registry-pull-host: ${{ steps.configure-platform.outputs.image-registry-pull-host }}
+      image-namespace: ${{ steps.configure-platform.outputs.image-namespace }}
+      local-image-name: ${{ steps.build-kamel-binary.outputs.local-image-name }}
+      local-image-version: ${{ steps.build-kamel-binary.outputs.local-image-version }}
+
+  - name: Run IT
+    shell: bash
+    run: |
+      # Use the last released Kamel CLI
+      export RELEASED_KAMEL_BIN=${{ env.RELEASED_KAMEL_BINARY }}
+
+      echo "Kamel version: $(${RELEASED_KAMEL_BIN} version)"
+
+      # Configure install options
+      export CUSTOM_IMAGE=${{ steps.build-kamel-binary.outputs.local-image-name }}
+      export CUSTOM_VERSION=${{ steps.build-kamel-binary.outputs.local-image-version }}
+      export KAMEL_INSTALL_MAVEN_REPOSITORIES=$(make get-staging-repo)
+      export KAMEL_INSTALL_REGISTRY=${{ steps.configure-platform.outputs.image-registry-pull-host }}
+      export KAMEL_INSTALL_REGISTRY_INSECURE=${{ steps.configure-platform.outputs.image-registry-insecure }}
+
+      # Configure test options
+      export CAMEL_K_PREV_IIB=quay.io/operatorhubio/catalog:latest
+      export CAMEL_K_NEW_IIB=${{ steps.build-kamel-bundle.outputs.local-image-bundle-index }}
+      export KAMEL_K_TEST_RELEASE_VERSION=$(make get-last-released-version)
+      export KAMEL_K_TEST_OPERATOR_CURRENT_IMAGE=${CUSTOM_IMAGE}:${CUSTOM_VERSION}
+
+      # Then run integration tests
+      make test-upgrade
diff --git a/.github/actions/kamel-build-bundle/action.yaml b/.github/actions/kamel-build-bundle/action.yaml
index 22b5e69..f0eff2c 100644
--- a/.github/actions/kamel-build-bundle/action.yaml
+++ b/.github/actions/kamel-build-bundle/action.yaml
@@ -19,9 +19,16 @@ name: kamel-build-bundle
 description: 'Builds kamel operator metadata bundle'
 
 inputs:
-  image-registry:
-    description: 'Location of image registry to push bundle'
-    required: true
+  image-registry-push-host:
+    description: 'Location of image registry push host'
+    required: false
+  image-registry-pull-host:
+    description: 'Location of image registry pull host'
+    required: false
+  image-namespace:
+    description: 'Namespace in which to store the image'
+    required: false
+    default: 'apache'
   local-image-name:
     description: 'Reference of the camel-k image'
     required: true
@@ -44,11 +51,32 @@ runs:
           exit 1
         fi
 
-        # replace image
-        $(cd config/manifests && kustomize edit set image "docker.io/apache/camel-k=${{ inputs.local-image-name }}:${{ inputs.local-image-version }}")
+        if [ -z "${{ inputs.local-image-name }}" ]; then
+          echo "Error: local-image-name not defined"
+          exit 1
+        fi
+
+        if [ -z "${{ inputs.local-image-version }}" ]; then
+          echo "Error: local-image-version not defined"
+          exit 1
+        fi
+
+        if [ -z "${{ inputs.image-registry-push-host }}" ]; then
+          echo "Error: image-registry-push-host not defined"
+          exit 1
+        fi
+
+        if [ -z "${{ inputs.image-registry-pull-host }}" ]; then
+          echo "Error: image-registry-pull-host not defined"
+          exit 1
+        fi
 
+        #
+        # Build with the PUSH host to ensure the correct image:tag
+        # for docker to push the image.
+        #
+        export LOCAL_IMAGE_BUNDLE=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }}
         export CUSTOM_IMAGE=${{ inputs.local-image-name }}
-        export LOCAL_IMAGE_BUNDLE=${{ inputs.image-registry }}/apache/camel-k-bundle:${{ inputs.local-image-version }}
 
         export PREV_XY_CHANNEL=stable-$(make get-last-released-version | grep -Po "\d.\d")
         echo "PREV_XY_CHANNEL=${PREV_XY_CHANNEL}" >> $GITHUB_ENV
@@ -62,22 +90,92 @@ runs:
 
         docker push ${LOCAL_IMAGE_BUNDLE}
 
+        #
+        # Use the PULL host to ensure the correct image:tag
+        # is passed into the tests for the deployment to pull from
+        #
+        export LOCAL_IMAGE_BUNDLE=${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }}
         echo "::set-output name=local-image-bundle::$(echo ${LOCAL_IMAGE_BUNDLE})"
 
     - id: build-index-image
       name: Create New Index Image
       shell: bash
       run: |
-        export LOCAL_IIB=${{ inputs.image-registry }}/apache/camel-k-iib:${{ inputs.local-image-version }}
+        export LOCAL_IIB=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k-iib:${{ inputs.local-image-version }}
         if ! command -v opm &> /dev/null
         then
           echo "opm could not be found. Has it not been installed?"
           exit 1
         fi
 
-        opm index add --bundles ${{ steps.build-bundle-image.outputs.local-image-bundle }} -c docker --from-index quay.io/operatorhubio/catalog:latest --tag ${LOCAL_IIB} --skip-tls
+        # Shorten the vars
+        PUSH_REGISTRY=${{ inputs.image-registry-push-host }}
+        PULL_REGISTRY=${{ inputs.image-registry-pull-host }}
+
+        #
+        # opm requires an active pull registry from which to verify (if not download) the bundle image
+        # Since the image-registry-pull-host may not be visible (eg. in the case of openshift), we need
+        # to fake the registry to allow opm to complete its task of creating an index image.
+        #
+        # 1. Add and alias to the hosts file for the name of the image-registry
+        # 2. Run a container of registry:2 docker image on the same port as the image-registry (port 80 if not present)
+        # 3. Tag and them push the image to the registry using docker
+        # 4. Run opm
+        #
+
+        if [ "${PULL_REGISTRY}" != "${PUSH_REGISTRY}" ]; then
+          #
+          # With the registry interfaces different then good chance that
+          # pull registry is not externally accessible, eg. openshift
+          #
+
+          PULL_HOST=$(echo ${PULL_REGISTRY} | sed -e 's/\(.*\):.*/\1/')
+          PULL_PORT=$(echo ${PULL_REGISTRY} | sed -e 's/.*:\([0-9]\+\).*/\1/')
+          if [ -z "${PULL_PORT}" ]; then
+            # Use standard http port
+            PULL_PORT=80
+          fi
+
+          echo "Impersonating registry at ${PULL_HOST}:${PULL_PORT}"
+
+          #
+          # Update both ipv4 and ipv6 addresses if they exist
+          # 127.0.0.1 localhost
+          # ::1     localhost ip6-localhost ip6-loopback
+          sudo sed -i "s/\(localhost.*\)/\1 ${PULL_HOST}/g" /etc/hosts
+
+          #
+          # Bring up the registry:2 instance if not already started
+          #
+          reg=$(docker ps -q -f name=triage-registry)
+          if [ -z "${reg}" ]; then
+            docker run -d -p ${PULL_PORT}:5000 --name triage-registry registry:2
+          fi
+
+          #
+          # Tag the bundle image
+          #
+          docker tag \
+            ${PUSH_REGISTRY}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }} \
+            ${{ steps.build-bundle-image.outputs.local-image-bundle }}
+
+          # Push the bundle image to the registry
+          #
+          docker push ${{ steps.build-bundle-image.outputs.local-image-bundle }}
+        fi
+
+        #
+        # Construct an index image containing the newly built bundle image
+        #
+        opm index add \
+          -c docker --skip-tls \
+          --bundles ${{ steps.build-bundle-image.outputs.local-image-bundle }} \
+          --from-index quay.io/operatorhubio/catalog:latest \
+          --tag ${LOCAL_IIB}
+
         docker push ${LOCAL_IIB}
 
+        export LOCAL_IIB=${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k-iib:${{ inputs.local-image-version }}
         echo "::set-output name=local-image-bundle-index::$(echo ${LOCAL_IIB})"
 
 outputs:
diff --git a/.github/actions/kamel-build/action.yml b/.github/actions/kamel-build/action.yml
index 7414da1..f6af262 100644
--- a/.github/actions/kamel-build/action.yml
+++ b/.github/actions/kamel-build/action.yml
@@ -19,9 +19,16 @@ name: kamel-build
 description: 'Builds kamel operator binary'
 
 inputs:
-  image-registry:
-    description: 'Location of image registry if required'
+  image-registry-push-host:
+    description: 'Location of image registry push host'
     required: false
+  image-registry-pull-host:
+    description: 'Location of image registry pull host'
+    required: false
+  image-namespace:
+    description: 'Namespace in which to store the image'
+    required: false
+    default: 'apache'
   make-rules:
     description: 'Override the default make rules'
     required: false
@@ -39,9 +46,12 @@ runs:
       run: |
         echo "Build Kamel from source"
 
-        if [ -n "${{ inputs.image-registry }}" ]; then
-          export CUSTOM_IMAGE=${{ inputs.image-registry }}/apache/camel-k
-          echo "::set-output name=custom-img::$(echo ${CUSTOM_IMAGE})"
+        if [ -n "${{ inputs.image-registry-push-host }}" ]; then
+          #
+          # Build with the PUSH host to ensure the correct image:tag
+          # for docker to push the image.
+          #
+          export CUSTOM_IMAGE=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k
         fi
 
         RULES="PACKAGE_ARTIFACTS_STRATEGY=download build package-artifacts images"
@@ -49,7 +59,7 @@ runs:
           RULES="${{ inputs.make-rules }}"
         fi
 
-        if [ -n "${{ inputs.image-registry }}" ]; then
+        if [ -n "${{ inputs.image-registry-push-host }}" ]; then
           RULES="${RULES} images-push"
         fi
 
@@ -61,14 +71,15 @@ runs:
           echo "Kamel version installed: $(kamel version)"
         fi
 
-        echo "::set-output name=local-img-name::$(make get-image)"
+        #
+        # Use the PULL host to ensure the correct image:tag
+        # is passed into the tests for the deployment to pull from
+        #
+        export LOCAL_IMAGE_NAME=${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k
+        echo "::set-output name=local-img-name::$(echo ${LOCAL_IMAGE_NAME})"
         echo "::set-output name=local-img-version::$(make get-version)"
 
-
 outputs:
-  custom-image:
-    description: "Reference of the camel-k image"
-    value: ${{ steps.build-operator.outputs.custom-img }}
   local-image-name:
     description: "Reference of the camel-k image"
     value: ${{ steps.build-operator.outputs.local-img-name }}
diff --git a/.github/actions/kamel-config-cluster-custom/action.yml b/.github/actions/kamel-config-cluster-custom/action.yml
index 46bbe5e..56bf532 100644
--- a/.github/actions/kamel-config-cluster-custom/action.yml
+++ b/.github/actions/kamel-config-cluster-custom/action.yml
@@ -21,49 +21,93 @@ description: 'Provides configuration for acessing a custom kubernetes cluster'
 runs:
   using: "composite"
   steps:
+    - name: Read platform-config variable to temporary file & override PLATFORM_TYPE if platform config defined
+      shell: bash
+      run: |
+        export PLATFORM_CONFIG=/tmp/platform-config.json
+
+        touch "${PLATFORM_CONFIG}"
+        if [ -z "${{ env.PLATFORM_CONFIG_DATA }}" ]; then
+          echo "Error: No PLATFORM_CONFIG_DATA has been defined"
+          exit 1
+        fi
+
+        cat << EOF > "${PLATFORM_CONFIG}"
+        ${{ env.PLATFORM_CONFIG_DATA }}
+        EOF
+
+        if [ ! -f "${PLATFORM_CONFIG}" ]; then
+          echo "Error: No file ${PLATFORM_CONFIG} has been created"
+          exit 1
+        fi
+
+        if [ -s "${PLATFORM_CONFIG}" ]; then
+          echo "Info: Platform configuration defined"
+          echo "PLATFORM_CONFIG=${PLATFORM_CONFIG}" >> $GITHUB_ENV
+        else
+          echo "Error: No platform configuration defined"
+          exit 1
+        fi
+
+    - name: Platform-config JSON to variables
+      uses: antifree/json-to-variables@v1.0.1
+      with:
+        filename: ${{ env.PLATFORM_CONFIG }}
+        prefix: 'e2e'
+
     - id: connect-cluster
       name: Connect to cluster
       shell: bash
       run: |
-        if [ -z "${KUBE_CONFIG_DATA}" ]; then
-          echo "Error: KUBE_CONFIG_DATA secret cannot be found"
+        if [ -z "${{ env.e2e_kube-config-data }}" ]; then
+          echo "Error: kube config data property cannot be found"
           exit 1
         fi
 
-        if [ -z "${KUBE_ADMIN_USER_CTX}" ]; then
-          echo "Error: KUBE_ADMIN_USER_CTX secret cannot be found"
+        if [ -z "${{ env.e2e_kube-admin-user-ctx }}" ]; then
+          echo "Error: kube admin context property cannot be found"
           exit 1
         fi
 
-        if [ -z "${KUBE_USER_CTX}" ]; then
-          echo "Error: KUBE_USER_CTX secret cannot be found"
+        if [ -z "${{ env.e2e_kube-user-ctx }}" ]; then
+          echo "Error: kube user context property cannot be found"
           exit 1
         fi
 
-        # IMAGE_REGISTRY & IMAGE_REGISTRY_INSECURE are optional
+        if [ -z "${{ env.e2e_image-registry-pull-host }}" ]; then
+          echo "Error: image registry pull host property cannot be found"
+          exit 1
+        fi
+
+        if [ -z "${{ env.e2e_image-registry-push-host }}" ]; then
+          echo "Error: image registry build host property cannot be found"
+          exit 1
+        fi
+
+        if [ -n "${{ env.e2e_image-registry-user }}" ] && [ -n "${{ env.e2e_image-registry-token }}" ]; then
+          echo "Secured registry in use so login with docker"
+          docker login \
+            -u "${{ env.e2e_image-registry-user }}" \
+            -p "${{ env.e2e_image-registry-token }}" \
+            "${{ env.e2e_image-registry-push-host }}"
+        fi
 
         # Copy the kube config to the correct location for kubectl
         mkdir -p $HOME/.kube
-        echo -n "${KUBE_CONFIG_DATA}" | base64 -d > ${HOME}/.kube/config
+        echo -n "${{ env.e2e_kube-config-data }}" | base64 -d > ${HOME}/.kube/config
         if [ ! -f ${HOME}/.kube/config ]; then
           echo "Error: kube config file not created correctly"
           exit 1
         fi
 
         set -e
-        kubectl config use-context "${KUBE_ADMIN_USER_CTX}"
+        kubectl config use-context "${{ env.e2e_kube-admin-user-ctx }}"
         if [ $? != 0 ]; then
           echo "Error: Failed to select kube admin context. Is the config and context correct?"
           exit 1
         fi
         set +e
 
-        # Export the context variables
-        echo "KUBE_ADMIN_USER_CTX=${KUBE_ADMIN_USER_CTX}" >> $GITHUB_ENV
-        echo "KUBE_USER_CTX=${KUBE_USER_CTX}" >> $GITHUB_ENV
-        echo "IMAGE_REGISTRY=${IMAGE_REGISTRY}" >> $GITHUB_ENV
-        echo "IMAGE_REGISTRY_INSECURE=${IMAGE_REGISTRY_INSECURE}" >> $GITHUB_ENV
-
     - id: info
       name: Info
       shell: bash
@@ -128,4 +172,44 @@ runs:
         EOF
 
         # Set the context to the user
-        kubectl config use-context "${{ env.KUBE_USER_CTX }}"
+        kubectl config use-context "${{ env.e2e_kube-user-ctx }}"
+
+    - id: extract-config
+      shell: bash
+      run: |
+        echo "IMAGE_REGISTRY_PUSH_HOST=${{ env.e2e_image-registry-push-host }}" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PULL_HOST=${{ env.e2e_image-registry-pull-host }}" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_INSECURE=${{ env.e2e_image-registry-insecure }}" >> $GITHUB_ENV
+
+        #
+        # Export the image namespace if defined in the platform config
+        #
+        if [ -n "${{ env.e2e_image-namespace }}" ]; then
+          echo "IMAGE_NAMESPACE=${{ env.e2e_image-namespace }}" >> $GITHUB_ENV
+        fi
+
+        #
+        # Export the context used for admin and user
+        #
+        echo "KUBE_ADMIN_USER_CTX=${{ env.e2e_kube-admin-user-ctx }}" >> $GITHUB_ENV
+        echo "KUBE_USER_CTX=${{ env.e2e_kube-user-ctx }}" >> $GITHUB_ENV
+
+        #
+        # Export the flag for installing olm
+        #
+        echo "INSTALL_OLM=${{ env.e2e_install-olm }}" >> $GITHUB_ENV
+
+        #
+        # Clear out environment variables no longer required
+        #
+        echo "PLATFORM_CONFIG=" >> $GITHUB_ENV
+        echo "e2e_image-registry-push-host=" >> $GITHUB_ENV
+        echo "e2e_image-registry-pull-host=" >> $GITHUB_ENV
+        echo "e2e_image-namespace=" >> $GITHUB_ENV
+        echo "e2e_image-registry-user=" >> $GITHUB_ENV
+        echo "e2e_image-registry-token=" >> $GITHUB_ENV
+        echo "e2e_image-registry-insecure=" >> $GITHUB_ENV
+        echo "e2e_kube-admin-user-ctx=" >> $GITHUB_ENV
+        echo "e2e_kube-config-data=" >> $GITHUB_ENV
+        echo "e2e_kube-user-ctx=" >> $GITHUB_ENV
+        echo "e2e_install-olm=" >> $GITHUB_ENV
diff --git a/.github/actions/kamel-config-cluster-kind/action.yml b/.github/actions/kamel-config-cluster-kind/action.yml
index 48b02bd..e6b62b8 100644
--- a/.github/actions/kamel-config-cluster-kind/action.yml
+++ b/.github/actions/kamel-config-cluster-kind/action.yml
@@ -37,7 +37,9 @@ runs:
     - id: extract-config
       shell: bash
       run: |
-        echo "IMAGE_REGISTRY=${{ env.KIND_REGISTRY }}" >> $GITHUB_ENV
+        # Kind has the same interface for both pushing and pulling images in its registry
+        echo "IMAGE_REGISTRY_PUSH_HOST=${{ env.KIND_REGISTRY }}" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PULL_HOST=${{ env.KIND_REGISTRY }}" >> $GITHUB_ENV
         echo "IMAGE_REGISTRY_INSECURE=true" >> $GITHUB_ENV
 
         #
@@ -46,3 +48,9 @@ runs:
         #
         echo "KUBE_ADMIN_USER_CTX=$(kubectl config current-context)" >> $GITHUB_ENV
         echo "KUBE_USER_CTX=$(kubectl config current-context)" >> $GITHUB_ENV
+
+        #
+        # Export the flag for installing olm
+        #
+        echo "INSTALL_OLM=true" >> $GITHUB_ENV
+
diff --git a/.github/actions/kamel-config-cluster-ocp3/action.yml b/.github/actions/kamel-config-cluster-ocp3/action.yml
index 8d6bfb9..a113361 100644
--- a/.github/actions/kamel-config-cluster-ocp3/action.yml
+++ b/.github/actions/kamel-config-cluster-ocp3/action.yml
@@ -188,5 +188,7 @@ runs:
     - id: extract-kube-config
       shell: bash
       run: |
-        echo "IMAGE_REGISTRY=" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PUSH_HOST=" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PULL_HOST=" >> $GITHUB_ENV
         echo "IMAGE_REGISTRY_INSECURE=false" >> $GITHUB_ENV
+        echo "INSTALL_OLM=false" >> $GITHUB_ENV
diff --git a/.github/actions/kamel-config-cluster/action.yaml b/.github/actions/kamel-config-cluster/action.yaml
index b76b603..393baad 100644
--- a/.github/actions/kamel-config-cluster/action.yaml
+++ b/.github/actions/kamel-config-cluster/action.yaml
@@ -23,29 +23,26 @@ inputs:
     description: 'The type of cluster required: [kind, ocp3, custom]'
     required: true
     default: 'kind'
-  kube-config-data:
-    description: 'The kube-config-data - required for custom config only'
+  platform-config:
+    description: 'The JSON configuration of the platform - required for custom platform type only'
     required: false
-  kube-admin-user-ctx:
-    description: 'The kube-admin-user-ctx - required for custom config only'
-    required: false
-  kube-user-ctx:
-    description: 'The kube-user-ctx - required for custom config only'
-    required: false
-  image-registry:
-    description: 'The image-registry - required for custom config only'
-    required: false
-  image-registry-insecure:
-    description: 'The image-registry-insecure - required for custom config only'
-    required: false
-  olm:
-    description: 'Check for & install OLM alongside cluster for bundle-related operations'
-    required: false
-    default: false
 
 runs:
   using: "composite"
   steps:
+    - name: Override platform type if there is a custom platform-config
+      shell: bash
+      run: |
+        if [ -n "${{ inputs.platform-config }}" ]; then
+          #
+          # Have custom platform-config so override platform-type
+          #
+          echo "PLATFORM_TYPE=custom" >> $GITHUB_ENV
+        else
+          echo "Info: No platform configuration supplied."
+          echo "PLATFORM_TYPE=${{ inputs.cluster-type }}" >> $GITHUB_ENV
+        fi
+
     #
     # TODO
     # Due to lack of if in steps, need to use conditional action which
@@ -57,7 +54,7 @@ runs:
       name: Maybe Execute Kind Cluster
       uses: ./.github/actions/conditional
       with:
-        if: ${{ inputs.cluster-type == 'kind' }}
+        if: ${{ env.PLATFORM_TYPE == 'kind' }}
         step: |
           uses: ./.github/actions/kamel-config-cluster-kind
 
@@ -65,7 +62,7 @@ runs:
       name: Maybe Execute Minishift Cluster
       uses: ./.github/actions/conditional
       with:
-        if: ${{ inputs.cluster-type == 'ocp3' }}
+        if: ${{ env.PLATFORM_TYPE == 'ocp3' }}
         step: |
           uses: ./.github/actions/kamel-config-cluster-ocp3
 
@@ -73,13 +70,9 @@ runs:
       name: Maybe Execute Custom Cluster
       uses: ./.github/actions/conditional
       env:
-        KUBE_CONFIG_DATA: ${{ inputs.kube-config-data }}
-        KUBE_ADMIN_USER_CTX: ${{ inputs.kube-admin-user-ctx }}
-        KUBE_USER_CTX: ${{ inputs.kube-user-ctx }}
-        IMAGE_REGISTRY: ${{ inputs.image-registry }}
-        IMAGE_REGISTRY_INSECURE: ${{ inputs.image-registry-insecure }}
+        PLATFORM_CONFIG_DATA: ${{ inputs.platform-config }}
       with:
-        if: ${{ inputs.cluster-type == 'custom' }}
+        if: ${{ env.PLATFORM_TYPE == 'custom' }}
         step: |
           uses: ./.github/actions/kamel-config-cluster-custom
 
@@ -87,7 +80,7 @@ runs:
       name: Execute Invalid Cluster
       uses: ./.github/actions/conditional
       with:
-        if: ${{ inputs.cluster-type != 'kind' &&  inputs.cluster-type != 'ocp3' &&  inputs.cluster-type != 'custom' }}
+        if: ${{ env.PLATFORM_TYPE != 'kind' &&  env.PLATFORM_TYPE != 'ocp3' &&  env.PLATFORM_TYPE != 'custom' }}
         step: |
           shell: bash
           run: |
@@ -96,11 +89,34 @@ runs:
 
     - id: platform-info
       shell: bash
+      env:
+        DEFAULT_IMAGE_NAMESPACE: 'apache'
       run: |
-        echo "::set-output name=registry::$(echo ${{ env.IMAGE_REGISTRY }})"
-        echo "::set-output name=registry-insecure::$(echo ${{ env.IMAGE_REGISTRY_INSECURE }})"
+        echo "::set-output name=image-registry-push-host::$(echo ${{ env.IMAGE_REGISTRY_PUSH_HOST }})"
+        echo "::set-output name=image-registry-pull-host::$(echo ${{ env.IMAGE_REGISTRY_PULL_HOST }})"
+        echo "::set-output name=image-registry-insecure::$(echo ${{ env.IMAGE_REGISTRY_INSECURE }})"
         echo "::set-output name=kube-admin-user-ctx::$(echo ${{ env.KUBE_ADMIN_USER_CTX }})"
         echo "::set-output name=kube-user-ctx::$(echo ${{ env.KUBE_USER_CTX }})"
+        echo "::set-output name=install-olm::$(echo ${{ env.INSTALL_OLM }})"
+
+        if [ -n "${{ env.IMAGE_NAMESPACE }}" ]; then
+          echo "::set-output name=image-namespace::$(echo ${{ env.IMAGE_NAMESPACE }})"
+        else
+          echo "::set-output name=image-namespace::$(echo ${{ env.DEFAULT_IMAGE_NAMESPACE }})"
+        fi
+
+        #
+        # Clear out environment variables
+        #
+        echo "TEST_PLATFORM_CLUSTER=" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PUSH_HOST=" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_PULL_HOST=" >> $GITHUB_ENV
+        echo "IMAGE_REGISTRY_INSECURE=" >> $GITHUB_ENV
+        echo "KUBE_ADMIN_USER_CTX=" >> $GITHUB_ENV
+        echo "KUBE_USER_CTX=" >> $GITHUB_ENV
+        echo "INSTALL_OLM=" >> $GITHUB_ENV
+        echo "IMAGE_NAMESPACE=" >> $GITHUB_ENV
+        echo "DEFAULT_IMAGE_NAMESPACE=" >> $GITHUB_ENV
 
       #
       # Install opm if required
@@ -122,9 +138,9 @@ runs:
       name: Install OLM
       shell: bash
       run: |
-        if [ "${{ inputs.olm }}" != "true" ]; then
-          # OLM not required
-          echo "OLM not required"
+        if [ "${{ steps.platform-info.outputs.install-olm }}" == "false" ]; then
+          # OLM explicitly not required - installed by default
+          echo "OLM install not required for this cluster"
           exit 0
         fi
 
@@ -162,12 +178,18 @@ runs:
         echo "Complete"
 
 outputs:
-  image-registry:
-    description: "Registry for storing images"
-    value: ${{ steps.platform-info.outputs.registry }}
+  image-registry-push-host:
+    description: "Registry for storing images host push interface"
+    value: ${{ steps.platform-info.outputs.image-registry-push-host }}
+  image-registry-pull-host:
+    description: "Registry for storing images host pull interface"
+    value: ${{ steps.platform-info.outputs.image-registry-pull-host }}
   image-registry-insecure:
-    description: "Whether the image registry require secure/authenticated access"
-    value: ${{ steps.platform-info.outputs.registry-insecure }}
+    description: "Whether the image registry requires secure/authenticated access"
+    value: ${{ steps.platform-info.outputs.image-registry-insecure }}
+  image-namespace:
+    description: "Registry namespace for storing images"
+    value: ${{ steps.platform-info.outputs.image-namespace }}
   kube-admin-user-ctx:
     description: "The admin user context of the cluster"
     value: ${{ steps.platform-info.outputs.kube-admin-user-ctx }}
diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade.yml
index 2432571..8e77dde 100644
--- a/.github/workflows/upgrade.yml
+++ b/.github/workflows/upgrade.yml
@@ -49,7 +49,6 @@ concurrency:
 
 jobs:
   upgrade:
-
     runs-on: ubuntu-20.04
 
     steps:
@@ -59,75 +58,7 @@ jobs:
         persist-credentials: false
         submodules: recursive
 
-    - id: prepare-env
-      name: Prepare Test Environment
-      uses: ./.github/actions/kamel-prepare-env
-      with:
-        install-opm: true
-
-    - id: configure-platform
-      name: Configure Platform
-      uses: ./.github/actions/kamel-config-cluster
+    - name: Execute Upgrade Tests
+      uses: ./.github/actions/e2e-upgrade
       with:
-        cluster-type: ${{ steps.prepare-env.outputs.cluster-platform }}
-        olm: true
-
-    - name: Get Released Kamel CLI
-      shell: bash
-      run: |
-        export KAMEL_VERSION=$(make get-last-released-version)
-        curl -L https://github.com/apache/camel-k/releases/download/v${KAMEL_VERSION}/camel-k-client-${KAMEL_VERSION}-linux-64bit.tar.gz -o /tmp/kamel.tar.gz
-        pushd /tmp && tar -zxf kamel.tar.gz && popd > /dev/null
-        if [ ! -x /tmp/kamel ]; then
-          echo "ERROR: No ${KAMEL_VERSION} downloaded correctly"
-          exit 1
-        fi
-        sudo mv /tmp/kamel /usr/local/bin/
-        if [ $? == 0 ]; then
-          echo "Kamel version installed: $(kamel version)"
-        else
-          echo "ERROR: Failed to install kamel binary ${KAMEL_VERSION}"
-          exit 1
-        fi
-
-    - id: build-kamel-binary
-      name: Build Kamel Binary
-      uses: ./.github/actions/kamel-build
-      with:
-        image-registry: ${{ steps.configure-platform.outputs.image-registry }}
-        # Avoid overwriting last-released version of binary
-        install-kamel-binary: false
-
-    - id: build-kamel-bundle
-      name: Build Kamel Metadata Bundle
-      uses: ./.github/actions/kamel-build-bundle
-      with:
-        image-registry: ${{ steps.configure-platform.outputs.image-registry }}
-        local-image-name: ${{ steps.build-kamel-binary.outputs.local-image-name }}
-        local-image-version: ${{ steps.build-kamel-binary.outputs.local-image-version }}
-
-    - name: Run IT
-      run: |
-        # Use the last released Kamel CLI
-        export RELEASED_KAMEL_BIN=/usr/local/bin/kamel
-
-        echo "Kamel version: $(${RELEASED_KAMEL_BIN} version)"
-
-        # Configure install options
-        export CUSTOM_IMAGE=${{ steps.build-kamel-binary.outputs.local-image-name }}
-        export CUSTOM_VERSION=${{ steps.build-kamel-binary.outputs.local-image-version }}
-        export KAMEL_INSTALL_BUILD_PUBLISH_STRATEGY=Spectrum
-        export KAMEL_INSTALL_MAVEN_REPOSITORIES=$(make get-staging-repo)
-        export KAMEL_INSTALL_REGISTRY=${{ steps.configure-platform.outputs.image-registry }}
-        export KAMEL_INSTALL_REGISTRY_INSECURE=${{ steps.configure-platform.outputs.image-registry-insecure }}
-
-        # Configure test options
-        export CAMEL_K_PREV_IIB=quay.io/operatorhubio/catalog:latest
-        export CAMEL_K_NEW_IIB=${{ steps.build-kamel-bundle.outputs.local-image-bundle-index }}
-        export KAMEL_K_TEST_RELEASE_VERSION=$(make get-last-released-version)
-        export KAMEL_K_TEST_OPERATOR_CURRENT_IMAGE=${CUSTOM_IMAGE}:${CUSTOM_VERSION}
-        export CAMEL_K_PREV_UPGRADE_CHANNEL=${{ env.PREV_XY_CHANNEL }}
-        export CAMEL_K_NEW_UPGRADE_CHANNEL=${{ env.NEW_XY_CHANNEL }}
-
-        # Then run integration tests
-        make test-upgrade
+        platform-config: ${{ secrets.E2E_PLATFORM_CONFIG }}