diff --git a/.github/workflows/publish-helm-oci.yaml b/.github/workflows/publish-helm-oci.yaml new file mode 100644 index 00000000..bb74fcaf --- /dev/null +++ b/.github/workflows/publish-helm-oci.yaml @@ -0,0 +1,246 @@ +# +# 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: Publish Helm Charts to OCI Registry + +# Publishes already-released, already-voted-on Helm charts from dist.apache.org to the +# GitHub Container Registry, as OCI artifacts. +# +# The charts on dist.apache.org remain the canonical, signed release artifacts; the OCI +# copies are convenience binaries. This workflow therefore never builds a chart, it only +# re-publishes a verified copy of one that has already been released. +# +# This workflow is also used to backfill previously released versions. + +on: + workflow_dispatch: + inputs: + solr-operator-chart-url: + description: 'URL to solr-operator Helm chart tarball (e.g., https://dist.apache.org/repos/dist/release/solr/solr-operator/v0.10.0/helm-charts/solr-operator-0.10.0.tgz)' + required: true + type: string + solr-chart-url: + description: 'URL to solr Helm chart tarball (e.g., https://dist.apache.org/repos/dist/release/solr/solr-operator/v0.10.0/helm-charts/solr-0.10.0.tgz)' + required: true + type: string + dry-run: + description: 'Dry run - download and verify charts but do not push to the OCI registry' + required: false + type: boolean + default: false + +permissions: + contents: read + packages: write + +env: + # 'helm push' appends the chart name from Chart.yaml to this target, producing: + # ghcr.io/apache/solr-operator/helm/solr-operator + # ghcr.io/apache/solr-operator/helm/solr + # The charts are namespaced under the repository name because ghcr.io/apache/* is a + # single namespace shared by every ASF project. Keeping the charts here also leaves + # 'apache/solr' free for a future Solr server image. + OCI_TARGET: oci://ghcr.io/apache/solr-operator/helm + ASF_KEYS_URL: https://dist.apache.org/repos/dist/release/solr/KEYS + +jobs: + publish-oci: + name: Publish Helm Charts to OCI Registry + runs-on: ubuntu-latest + steps: + - name: Install Helm + uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1 + with: + version: 'latest' + + # Inputs are passed through the environment rather than interpolated into the + # script body, so that a malicious input cannot inject shell commands. + - name: Validate input URLs + id: inputs + env: + OPERATOR_CHART_URL: ${{ inputs.solr-operator-chart-url }} + SOLR_CHART_URL: ${{ inputs.solr-chart-url }} + run: | + set -euo pipefail + + for url in "${OPERATOR_CHART_URL}" "${SOLR_CHART_URL}"; do + if [[ ! "${url}" =~ ^https://dist\.apache\.org/repos/dist/(release|dev)/solr/ ]]; then + echo "Error: chart URLs must be from dist.apache.org: ${url}" >&2 + exit 1 + fi + done + + # The .sha512 and .prov files both reference the chart's original filename, so + # the downloads must keep their basenames rather than being renamed. + OPERATOR_CHART_FILE="$(basename "${OPERATOR_CHART_URL}")" + SOLR_CHART_FILE="$(basename "${SOLR_CHART_URL}")" + + if [[ ! "${OPERATOR_CHART_FILE}" =~ ^solr-operator-[0-9][A-Za-z0-9.+_-]*\.tgz$ ]]; then + echo "Error: unexpected solr-operator chart filename: ${OPERATOR_CHART_FILE}" >&2 + exit 1 + fi + if [[ ! "${SOLR_CHART_FILE}" =~ ^solr-[0-9][A-Za-z0-9.+_-]*\.tgz$ ]]; then + echo "Error: unexpected solr chart filename: ${SOLR_CHART_FILE}" >&2 + exit 1 + fi + + echo "operator-chart-file=${OPERATOR_CHART_FILE}" >> "$GITHUB_OUTPUT" + echo "solr-chart-file=${SOLR_CHART_FILE}" >> "$GITHUB_OUTPUT" + echo "URLs validated" + echo " solr-operator chart: ${OPERATOR_CHART_FILE}" + echo " solr chart: ${SOLR_CHART_FILE}" + + - name: Download charts, checksums, signatures and provenance + env: + OPERATOR_CHART_URL: ${{ inputs.solr-operator-chart-url }} + SOLR_CHART_URL: ${{ inputs.solr-chart-url }} + run: | + set -euo pipefail + mkdir -p charts && cd charts + + # The .prov file is what makes 'helm install --verify' work against the OCI + # copy: 'helm push' uploads it automatically when it sits next to the chart. + for url in "${OPERATOR_CHART_URL}" "${SOLR_CHART_URL}"; do + for suffix in "" .sha512 .asc .prov; do + curl --fail --show-error --silent --location --retry 3 --retry-delay 5 \ + -O "${url}${suffix}" + done + done + + echo "Downloaded:" + ls -lh + + - name: Verify SHA512 checksums + working-directory: charts + run: | + set -euo pipefail + sha512sum -c ./*.tgz.sha512 + echo "SHA512 checksums verified" + + # The checksums come from the same host as the charts, so on their own they only + # prove the download was not corrupted. The detached GPG signatures are what prove + # the artifacts are the ones the PMC voted on. + - name: Verify GPG signatures + working-directory: charts + run: | + set -euo pipefail + curl --fail --show-error --silent --location "${ASF_KEYS_URL}" | gpg --import --quiet + for asc in ./*.tgz.asc; do + gpg --verify "${asc}" "${asc%.asc}" + done + echo "GPG signatures verified" + + - name: Extract chart versions + id: versions + working-directory: charts + env: + OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }} + SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }} + run: | + set -euo pipefail + OPERATOR_VERSION="$(tar -xzOf "${OPERATOR_CHART_FILE}" solr-operator/Chart.yaml | awk '$1 == "version:" {print $2; exit}')" + SOLR_VERSION="$(tar -xzOf "${SOLR_CHART_FILE}" solr/Chart.yaml | awk '$1 == "version:" {print $2; exit}')" + + echo "operator-version=${OPERATOR_VERSION}" >> "$GITHUB_OUTPUT" + echo "solr-version=${SOLR_VERSION}" >> "$GITHUB_OUTPUT" + echo "Solr Operator chart version: ${OPERATOR_VERSION}" + echo "Solr chart version: ${SOLR_VERSION}" + + - name: Log in to GitHub Container Registry + if: ${{ !inputs.dry-run }} + run: | + set -euo pipefail + echo "${{ secrets.GITHUB_TOKEN }}" | \ + helm registry login ghcr.io -u "${{ github.actor }}" --password-stdin + echo "Logged in to ghcr.io" + + - name: Push charts to OCI registry + if: ${{ !inputs.dry-run }} + working-directory: charts + env: + OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }} + SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }} + run: | + set -euo pipefail + # helm appends each chart's name, so both charts share one push target. + helm push "${OPERATOR_CHART_FILE}" "${OCI_TARGET}" + helm push "${SOLR_CHART_FILE}" "${OCI_TARGET}" + + # Packages are created private by default on ghcr.io. Re-pulling anonymously is what + # catches that: it fails loudly rather than leaving a chart nobody can install. + - name: Verify published charts are anonymously pullable + if: ${{ !inputs.dry-run }} + env: + OPERATOR_VERSION: ${{ steps.versions.outputs.operator-version }} + SOLR_VERSION: ${{ steps.versions.outputs.solr-version }} + OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }} + SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }} + run: | + set -euo pipefail + helm registry logout ghcr.io || true + + # 'helm pull --verify' reads the pushed .prov, so this also proves provenance + # survived the round-trip. helm looks for the legacy public keyring. + gpg --export > ~/.gnupg/pubring.gpg + + mkdir -p pulled + helm pull --verify "${OCI_TARGET}/solr-operator" --version "${OPERATOR_VERSION}" -d pulled + helm pull --verify "${OCI_TARGET}/solr" --version "${SOLR_VERSION}" -d pulled + + # The pulled charts must be byte-identical to the released ones. + cmp "pulled/${OPERATOR_CHART_FILE}" "charts/${OPERATOR_CHART_FILE}" + cmp "pulled/${SOLR_CHART_FILE}" "charts/${SOLR_CHART_FILE}" + echo "Charts are public, verifiable and identical to the released artifacts" + + - name: Summary + if: ${{ success() }} + env: + OPERATOR_VERSION: ${{ steps.versions.outputs.operator-version }} + SOLR_VERSION: ${{ steps.versions.outputs.solr-version }} + run: | + set -euo pipefail + REGISTRY="${OCI_TARGET}" + + if [[ "${{ inputs.dry-run }}" == "true" ]]; then + echo "## Dry run - nothing was published" >> "$GITHUB_STEP_SUMMARY" + else + echo "## Helm charts published" >> "$GITHUB_STEP_SUMMARY" + fi + { + echo "" + echo "| Check | Result |" + echo "| --- | --- |" + echo "| URLs from dist.apache.org | passed |" + echo "| SHA512 checksums | verified |" + echo "| GPG signatures | verified |" + echo "| solr-operator chart version | \`${OPERATOR_VERSION}\` |" + echo "| solr chart version | \`${SOLR_VERSION}\` |" + echo "" + } >> "$GITHUB_STEP_SUMMARY" + + if [[ "${{ inputs.dry-run }}" == "true" ]]; then + echo "Re-run with **dry-run = false** to publish." >> "$GITHUB_STEP_SUMMARY" + else + { + echo "Anonymously pulled back and verified against the released artifacts." + echo "" + echo '```bash' + echo "helm install solr-operator ${REGISTRY}/solr-operator --version ${OPERATOR_VERSION}" + echo "helm install example ${REGISTRY}/solr --version ${SOLR_VERSION}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + fi diff --git a/README.md b/README.md index d3a0f36e..2bf751a7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,12 @@ Join us on the [#solr-operator](https://kubernetes.slack.com/messages/solr-opera Please visit the following pages for documentation on using and developing the Solr Operator: - [Local Tutorial](https://solr.apache.org/guide/operator/latest/getting-started/local-tutorial.html) -- [Helm Instructions via Artifact Hub](https://artifacthub.io/packages/helm/apache-solr/solr-operator) +- **Helm Chart Installation** + - The Helm charts are published as OCI artifacts (recommended): + - **Solr Operator**: `helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version ` + - **Solr Cloud**: `helm install solr oci://ghcr.io/apache/solr-operator/helm/solr --version ` + - Or via the deprecated HTTPS repository: [Helm Instructions via Artifact Hub](https://artifacthub.io/packages/helm/apache-solr/solr-operator) + - Charts are published to both locations throughout the 0.x releases. Starting with `v1.0.0`, charts will be published to the OCI registry only. - The released helm charts and their instructions should be used for all safe and stable deployments. The charts found in `helm/` are not guaranteed to be compatible with the last stable release, and should only be used for development purposes. - [Running the Solr Operator](https://solr.apache.org/guide/operator/latest/getting-started/running-the-operator.html) diff --git a/docs/modules/getting-started/pages/local-tutorial.adoc b/docs/modules/getting-started/pages/local-tutorial.adoc index c1da57b9..42a86a50 100644 --- a/docs/modules/getting-started/pages/local-tutorial.adoc +++ b/docs/modules/getting-started/pages/local-tutorial.adoc @@ -79,15 +79,10 @@ You can follow along here, or follow the instructions in the https://artifacthub Now that we have the prerequisites setup, let us install Solr Operator which will let us easily manage a large Solr cluster: -Now add the Solr Operator Helm repository. (You should only need to do this once) +The Helm charts are published to the GitHub Container Registry as OCI artifacts, so there is +no Helm repository to add and no credentials to configure. -[source,bash] ----- -$ helm repo add apache-solr https://solr.apache.org/charts -$ helm repo update ----- - -Next, install the Solr Operator chart. Note this is using Helm v3, in order to use Helm v2 please consult the https://hub.helm.sh/charts/solr-operator/solr-operator[Helm Chart documentation]. +Install the Solr Operator chart with the commands below. This will install the https://github.com/pravega/zookeeper-operator[Zookeeper Operator] by default. [source,bash,subs="verbatim,attributes"] @@ -95,9 +90,16 @@ This will install the https://github.com/pravega/zookeeper-operator[Zookeeper Op # Install the Solr & Zookeeper CRDs $ kubectl create -f https://solr.apache.org/operator/downloads/crds/v{operator-version}/all-with-dependencies.yaml # Install the Solr operator and Zookeeper Operator -$ helm install solr-operator apache-solr/solr-operator --version {operator-version} +$ helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version {operator-version} ---- +[NOTE] +==== +The charts are also still served from the HTTPS Helm repository at `https://solr.apache.org/charts`, +which is deprecated. Charts are published to both locations throughout the 0.x releases. +Starting with `v1.0.0`, charts will be published to the OCI registry only. +==== + _Note that the Helm chart version does not contain a `v` prefix, which the downloads version does. The Helm chart version is the only part of the Solr Operator release that does not use the `v` prefix._ After installing, you can check to see what lives in the cluster to make sure that the Solr and ZooKeeper operators have started correctly. @@ -128,7 +130,7 @@ To start a Solr Cloud cluster, we will create a yaml that will tell the Solr Ope [source,bash,subs="verbatim,attributes"] ---- # Create a 3-node cluster v9.10.0 with 300m Heap each: -helm install example-solr apache-solr/solr --version {operator-version} \ +helm install example-solr oci://ghcr.io/apache/solr-operator/helm/solr --version {operator-version} \ --set image.tag=9.10.0 \ --set solrOptions.javaMemory="-Xms300m -Xmx300m" \ --set addressability.external.method=Ingress \ @@ -224,7 +226,7 @@ So we wish to upgrade to a newer Solr version: curl -s http://default-example-solrcloud.ing.local.domain/solr/admin/info/system | grep solr-i # Update the solrCloud configuration with the new version, keeping all previous settings and the number of nodes set by the autoscaler. -helm upgrade example-solr apache-solr/solr --version {operator-version} \ +helm upgrade example-solr oci://ghcr.io/apache/solr-operator/helm/solr --version {operator-version} \ --reuse-values \ --set image.tag=9.10.0 diff --git a/docs/modules/getting-started/pages/running-the-operator.adoc b/docs/modules/getting-started/pages/running-the-operator.adoc index 93fc388a..02d3bc34 100644 --- a/docs/modules/getting-started/pages/running-the-operator.adoc +++ b/docs/modules/getting-started/pages/running-the-operator.adoc @@ -26,23 +26,33 @@ The helm chart provides abstractions over the Input Arguments described below, a The official documentation for installing the Solr Operator Helm chart can be found on https://artifacthub.io/packages/helm/apache-solr/solr-operator[Artifact Hub]. -The first step is to add the Solr Operator helm repository. +The chart is published to the GitHub Container Registry as an OCI artifact. +Nothing needs to be added or configured first, and no credentials are required. -[source,bash] +Install the Solr Operator chart with the command below. +This will install the https://github.com/pravega/zookeeper-operator[Zookeeper Operator] by default. + +[source,bash,subs="verbatim,attributes"] ---- -$ helm repo add apache-solr https://solr.apache.org/charts -$ helm repo update +$ kubectl create -f https://solr.apache.org/operator/downloads/crds/v{operator-version}/all-with-dependencies.yaml +$ helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version {operator-version} ---- -Next, install the Solr Operator chart. Note this is using Helm v3, use the official Helm chart documentation linked to above. -This will install the https://github.com/pravega/zookeeper-operator[Zookeeper Operator] by default. +[NOTE] +==== +The chart is also still served from the HTTPS Helm repository at `https://solr.apache.org/charts`, which is deprecated: [source,bash,subs="verbatim,attributes"] ---- -$ kubectl create -f https://solr.apache.org/operator/downloads/crds/v{operator-version}/all-with-dependencies.yaml +$ helm repo add apache-solr https://solr.apache.org/charts +$ helm repo update $ helm install solr-operator apache-solr/solr-operator --version {operator-version} ---- +Charts are published to both locations throughout the 0.x releases. +Starting with `v1.0.0`, charts will be published to the OCI registry only. +==== + _Note that the Helm chart version does not contain a `v` prefix, which the downloads version does. The Helm chart version is the only part of the Solr Operator release that does not use the `v` prefix._ After installing, you can check to see what lives in the cluster to make sure that the Solr and ZooKeeper operators have started correctly. @@ -75,7 +85,7 @@ This can be done with the `--skip-crds` helm option. [source,bash] ---- -helm install solr-operator apache-solr/solr-operator --skip-crds --namespace solr +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --skip-crds --namespace solr ---- *Helm will not upgrade CRDs once they have been installed. diff --git a/docs/modules/upgrade-notes/pages/upgrade-notes.adoc b/docs/modules/upgrade-notes/pages/upgrade-notes.adoc index e0d5a26c..e76679e9 100644 --- a/docs/modules/upgrade-notes/pages/upgrade-notes.adoc +++ b/docs/modules/upgrade-notes/pages/upgrade-notes.adoc @@ -97,6 +97,30 @@ It is always encouraged to upgrade to the latest patch version of the minor and There is no need to upgrade one patch version at a time (e.g. `v0.2.5` -> `v0.2.6` -> `v0.2.7` -> `v0.2.8`), instead you can leap to the latest patch version (e.g. `v0.2.5` -> `v0.2.8`). +== Where the Helm charts are published + +The Solr Operator and Solr Helm charts are published as OCI artifacts to the GitHub Container Registry: + +[source,bash,subs="verbatim,attributes"] +---- +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version {operator-version} +helm install example oci://ghcr.io/apache/solr-operator/helm/solr --version {operator-version} +---- + +Installing from an OCI registry requires no `helm repo add`, and no credentials. + +[WARNING] +==== +The HTTPS Helm repository at `https://solr.apache.org/charts` is *deprecated*. + +Charts are published to both the OCI registry and the HTTPS repository throughout the 0.x releases, +so there is no rush to migrate. Starting with `v1.0.0`, charts will be published to the OCI registry +only, and the HTTPS repository will receive no further releases. + +If you install or upgrade the charts through automation, update it to use the `oci://` URLs above +before upgrading to `v1.0.0`. +==== + == Installing the Solr Operator vs Solr CRDs Installing the Solr Operator, especially via the https://artifacthub.io/packages/helm/apache-solr/solr-operator[Helm Chart], @@ -127,7 +151,7 @@ If you are using the Solr Helm chart to deploy the Zookeeper operator, then you ---- # Just replace the Solr CRDs and all CRDs it might depend on (e.g. ZookeeperCluster) kubectl replace -f "http://solr.apache.org/operator/downloads/crds/v{operator-version}/all-with-dependencies.yaml" -helm upgrade solr-operator apache-solr/solr-operator --version {operator-version} +helm upgrade solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version {operator-version} ---- _Note that the Helm chart version does not contain a `v` prefix, which the downloads version does. The Helm chart version is the only part of the Solr Operator release that does not use the `v` prefix._ @@ -136,6 +160,13 @@ _Note that the Helm chart version does not contain a `v` prefix, which the downl === v0.10.0 +* *Helm charts are now published to an OCI registry* ++ +The charts are published as OCI artifacts to `oci://ghcr.io/apache/solr-operator/helm`, alongside the +existing HTTPS Helm repository. The HTTPS repository at `https://solr.apache.org/charts` is deprecated +and will receive no further releases starting with `v1.0.0`. +See <>. + * *Logging now defaults to JSON format* + The new default for CLI flag `--zap-devel` is now `false`, causing log encoding to be `json` and log level to be `info`. diff --git a/hack/release/smoke_test/test_cluster.sh b/hack/release/smoke_test/test_cluster.sh index b99e7227..75c0b30b 100755 --- a/hack/release/smoke_test/test_cluster.sh +++ b/hack/release/smoke_test/test_cluster.sh @@ -23,7 +23,7 @@ set -u show_help() { cat << EOF -Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k KUBERNETES_VERSION] [-t SOLR_IMAGE] [-g GPG_KEY] -v VERSION -l LOCATION +Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k KUBERNETES_VERSION] [-t SOLR_IMAGE] [-g GPG_KEY] [-o OCI_REGISTRY] -v VERSION -l LOCATION Test the release candidate in a Kind cluster @@ -34,11 +34,14 @@ Test the release candidate in a Kind cluster -g GPG Key (fingerprint) used to sign the artifacts (Optional, if not provided then the helm chart will not be verified) -k Kubernetes Version to test with (full tag, e.g. v1.26.6) (Optional, defaults to a compatible version) -t Full solr image, or image tag (for the official Solr image), to test with (e.g. apache/solr-nightly:9.0.0, 9.10.0). (Optional, defaults to a compatible version) + -o OCI registry to install the Helm charts from, e.g. oci://ghcr.io/apache/solr-operator/helm (Optional) + Use this after a release has been published, to smoke test the published OCI artifacts. + The CRDs are still taken from LOCATION, since they are not part of the OCI artifacts. EOF } OPTIND=1 -while getopts hv:i:l:g:k:t: opt; do +while getopts hv:i:l:g:k:t:o: opt; do case $opt in h) show_help @@ -56,6 +59,8 @@ while getopts hv:i:l:g:k:t: opt; do ;; t) SOLR_IMAGE=$OPTARG ;; + o) OCI_REGISTRY=$OPTARG + ;; *) show_help >&2 exit 1 @@ -86,14 +91,15 @@ fi export LOCATION="$LOCATION" export VERSION="$VERSION" +# An OCI registry is never a helm repo, so there is nothing to add or remove for it. function add_solr_helm_repo() { - if (echo "${LOCATION}" | grep "http"); then + if [[ -z "${OCI_REGISTRY:-}" ]] && (echo "${LOCATION}" | grep "http"); then helm repo add --force-update "apache-solr-test-${VERSION}" "${LOCATION}/helm-charts" fi } function remove_solr_helm_repo() { - if (echo "${LOCATION}" | grep "http"); then + if [[ -z "${OCI_REGISTRY:-}" ]] && (echo "${LOCATION}" | grep "http"); then helm repo remove "apache-solr-test-${VERSION}" fi } @@ -113,6 +119,16 @@ else SOLR_HELM_CHART="apache-solr-test-${VERSION}/solr" fi +# The charts published to an OCI registry are the same artifacts that were staged at +# LOCATION, so only where the charts are pulled from changes. CRDs still come from LOCATION. +# Unlike a helm repo, an OCI reference has no index, so the version must be given explicitly. +CHART_VERSION_ARG=() +if [[ -n "${OCI_REGISTRY:-}" ]]; then + OP_HELM_CHART="${OCI_REGISTRY}/solr-operator" + SOLR_HELM_CHART="${OCI_REGISTRY}/solr" + CHART_VERSION_ARG=(--version "${VERSION#v}") +fi + if ! (which kind); then echo "Install Kind (Kubernetes in Docker)" GO111MODULE="on" go install sigs.k8s.io/kind@v0.20.0 @@ -163,13 +179,13 @@ add_solr_helm_repo # Install the Solr Operator kubectl create -f "${LOCATION}/crds/all-with-dependencies.yaml" || kubectl replace -f "${LOCATION}/crds/all-with-dependencies.yaml" -helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} solr-operator "${OP_HELM_CHART}" \ +helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} solr-operator "${OP_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"} \ --set-string image.tag="${IMAGE##*:}" \ --set image.repository="${IMAGE%%:*}" \ --set image.pullPolicy="Never" printf "\nInstall a test Solr Cluster\n" -helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example "${SOLR_HELM_CHART}" \ +helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example "${SOLR_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"} \ --set replicas=2 \ --set image.repository="${SOLR_IMAGE%%:*}" \ --set-string image.tag="${SOLR_IMAGE##*:}" \ @@ -291,7 +307,7 @@ fi printf "\nDo a rolling restart and make sure the cluster is healthy afterwards\n" add_solr_helm_repo -helm upgrade --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example "${SOLR_HELM_CHART}" --reuse-values \ +helm upgrade --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example "${SOLR_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"} --reuse-values \ --set-string podOptions.annotations.restart="true" printf '\nWait for the rolling restart to begin.\n\n' grep -q "2 [[:digit:]] [[:digit:]] 0" <(exec kubectl get solrcloud example -w); kill $! diff --git a/hack/release/wizard/releaseWizard.yaml b/hack/release/wizard/releaseWizard.yaml index ee3b9eb7..14a5c2d6 100644 --- a/hack/release/wizard/releaseWizard.yaml +++ b/hack/release/wizard/releaseWizard.yaml @@ -1120,6 +1120,64 @@ groups: cmd: ./hack/release/upload/upload_helm.sh -g "{{ gpg_key | default("", True) }}" -a "{{ gpg.apache_id | default("", True) }}" -c "{{ official_helm_charts_url }}" -r "{{ dist_release_url }}" logfile: upload_helm.log tee: true + - !Todo + id: publish_helm_charts_oci + title: Publish Helm charts to the OCI registry (GHCR) + depends: publish_helm_charts + vars: + dist_release_url: https://dist.apache.org/repos/dist/release/solr/solr-operator/{{ release_version }} + solr_operator_chart_url: '{{ dist_release_url }}/helm-charts/solr-operator-{{ release_version[1:] }}.tgz' + solr_chart_url: '{{ dist_release_url }}/helm-charts/solr-{{ release_version[1:] }}.tgz' + workflow_url: https://github.com/apache/solr-operator/actions/workflows/publish-helm-oci.yaml + description: | + Publish the released Helm charts as OCI artifacts to the GitHub Container Registry, + using the "Publish Helm Charts to OCI Registry" GitHub Actions workflow. + + The charts on dist.apache.org remain the canonical, signed release artifacts. + The OCI copies are convenience binaries, published to: + - oci://ghcr.io/apache/solr-operator/helm/solr-operator + - oci://ghcr.io/apache/solr-operator/helm/solr + + Steps to publish: + 1. Navigate to the GitHub Actions workflow: + {{ workflow_url }} + + 2. Click the "Run workflow" button on the right side + + 3. Fill in the workflow inputs: + - solr-operator-chart-url: {{ solr_operator_chart_url }} + - solr-chart-url: {{ solr_chart_url }} + - dry-run: true + + 4. The dry-run verifies, without publishing anything, that: + - The URLs are valid and point at dist.apache.org + - The charts, checksums, signatures and provenance files all download + - The SHA512 checksums match + - The GPG signatures verify against the Solr KEYS file + - The chart versions are what you expect + + 5. Re-run the workflow with dry-run = false to actually publish + + 6. Monitor the workflow execution for any errors. After pushing, the workflow logs + out of the registry and pulls both charts back anonymously, verifying their + provenance and checking they are byte-identical to the released artifacts. + If this step fails with an authorization error, the ghcr.io packages are still + private and INFRA needs to make them public - see the note below. + + 7. Confirm for yourself that the charts are installable, with no credentials: + + helm registry logout ghcr.io + helm show chart oci://ghcr.io/apache/solr-operator/helm/solr-operator --version {{ release_version[1:] }} + helm show chart oci://ghcr.io/apache/solr-operator/helm/solr --version {{ release_version[1:] }} + + Note: the workflow authenticates with the built-in GITHUB_TOKEN, so no secrets need + to be configured. However, ghcr.io creates new packages as *private*. The very first + time a chart name is published, an INFRA ticket is needed to make the package public. + This is a one-time action per chart name; later versions inherit the visibility. + links: + - '{{ workflow_url }}' + - '{{ solr_operator_chart_url }}' + - '{{ solr_chart_url }}' - !Todo id: publish_crds title: Publish the staged CRDs @@ -1179,11 +1237,15 @@ groups: depends: - publish_docker_image - publish_helm_charts + - publish_helm_charts_oci description: | Check to make sure that ArtifactHub has successfully loaded the {{ release_version }} version of the Solr Operator and Solr Helm Charts. Mark this as complete when you have confirmed all aspects of the chart in artifactHub. The ChangeLog is very finicky, so make sure that it renders correctly. + + Note that ArtifactHub still indexes the HTTPS chart repository, not the OCI registry, + so the OCI copies published in the previous step will not show up here. links: - https://artifacthub.io/packages/helm/apache-solr/solr-operator - https://artifacthub.io/packages/helm/apache-solr/solr diff --git a/helm/solr-operator/README.md b/helm/solr-operator/README.md index 79acc1a4..cd185d5e 100644 --- a/helm/solr-operator/README.md +++ b/helm/solr-operator/README.md @@ -31,19 +31,39 @@ If you do not wish to use the Zookeeper Operator, set: - `zookeeper-operator.use: false` -### Adding the Solr Operator Helm Chart Repository -You should only need to add the solr operator helm chart repository once, by running the following command: +### Installing the Chart + +The Solr Operator Helm chart can be installed either from the OCI registry (recommended) or from the deprecated HTTPS repository. + +> **Note:** The HTTPS Helm repository at `https://solr.apache.org/charts` is deprecated. +> Charts are published to both locations throughout the 0.x releases. +> Starting with `v1.0.0`, charts will be published to the OCI registry only. + +#### Installation via OCI Registry (Recommended) + +The Helm chart is published to the GitHub Container Registry as an OCI artifact. +No repository needs to be added, and no credentials are required. ```bash -helm repo add apache-solr https://solr.apache.org/charts +# Install CRDs first +kubectl create -f https://solr.apache.org/operator/downloads/crds/v0.10.0-prerelease/all-with-dependencies.yaml + +# Install the Solr Operator from OCI registry +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease ``` -### Installing the Chart +#### Installation via HTTPS Repository (Deprecated) -To install the Solr Operator for the first time in your cluster, you can use the latest version or a specific version, run with the following commands: +The chart is also still served from the deprecated HTTPS Helm repository. ```bash +# Add the repository (only needed once) +helm repo add apache-solr https://solr.apache.org/charts + +# Install CRDs first kubectl create -f https://solr.apache.org/operator/downloads/crds/v0.10.0-prerelease/all-with-dependencies.yaml + +# Install the Solr Operator from the HTTPS repository helm install solr-operator apache-solr/solr-operator --version 0.10.0-prerelease ``` @@ -57,7 +77,13 @@ _Note that the Helm chart version does not contain a `v` prefix, which the downl If you are upgrading your Solr Operator deployment, you should always use a specific version of the chart and pre-install the Solr CRDS: ```bash +# Upgrade CRDs first kubectl replace -f https://solr.apache.org/operator/downloads/crds/v0.10.0-prerelease/all-with-dependencies.yaml + +# Upgrade via OCI registry (recommended) +helm upgrade solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease + +# Or upgrade via the deprecated HTTPS repository helm upgrade solr-operator apache-solr/solr-operator --version 0.10.0-prerelease ``` @@ -67,18 +93,20 @@ If you want to specify the namespace for the installation, use the `--namespace` All resources will be deployed to the given namespace. ```bash -helm install solr-operator apache-solr/solr-operator --namespace solr +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease --namespace solr ``` If you want to only watch that namespace, or others, then you will have to provide the `watchNamespaces` option. ```bash # Watch the namespace where the operator is deployed to (just pass the boolean true) -helm install solr-operator apache-solr/solr-operator --namespace solr --set watchNamespaces=true +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease --namespace solr --set watchNamespaces=true + # Watch a single namespace different than the one being deployed to -helm install solr-operator apache-solr/solr-operator --namespace solr --set watchNamespaces=other -# Watch multiple namespaces (commmas must be escaped in the set string) -helm install solr-operator apache-solr/solr-operator --namespace solr --set watchNamespaces="team1\,team2\,team3" +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease --namespace solr --set watchNamespaces=other + +# Watch multiple namespaces (commas must be escaped in the set string) +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease --namespace solr --set watchNamespaces="team1\,team2\,team3" ``` Note: Passing `false` or `""` to the `watchNamespaces` variable will both result in the operator watchting all namespaces in the Kube cluster. @@ -91,7 +119,11 @@ If you have solr operator installations in multiple namespaces that are managed This can be done with the `--skip-crds` helm option. ```bash -helm install solr-operator apache-solr/solr-operator --skip-crds --namespace solr +# Via OCI registry +helm install solr-operator oci://ghcr.io/apache/solr-operator/helm/solr-operator --version 0.10.0-prerelease --skip-crds --namespace solr + +# Or via HTTPS repository +helm install solr-operator apache-solr/solr-operator --version 0.10.0-prerelease --skip-crds --namespace solr ``` **Helm will not upgrade CRDs once they have been installed. diff --git a/helm/solr/README.md b/helm/solr/README.md index 52eaa4cf..ffae7b49 100644 --- a/helm/solr/README.md +++ b/helm/solr/README.md @@ -33,9 +33,19 @@ There may be breaking changes between the version you are using and the version ### Installing the Chart -To install a SolrCloud for the first time in your cluster, you can use the latest version or a specific version, run with the following commands: +The Solr Helm chart can be installed either from the OCI registry (recommended) or from the deprecated HTTPS helm repository. + +> **Note:** The HTTPS Helm repository at `https://solr.apache.org/charts` is deprecated. +> Charts are published to both locations throughout the 0.x releases. +> Starting with `v1.0.0`, charts will be published to the OCI registry only. + +To install a SolrCloud for the first time in your cluster, you can use the latest version or a specific version: ```bash +# Via OCI registry (recommended) +helm install example oci://ghcr.io/apache/solr-operator/helm/solr --version 0.10.0-prerelease --set image.tag=9.10.0 + +# Or via the deprecated HTTPS helm repository helm install example apache-solr/solr --version 0.10.0-prerelease --set image.tag=9.10.0 ``` @@ -50,6 +60,10 @@ _Note that the Helm chart version does not contain a `v` prefix, which the Solr If you are upgrading your SolrCloud deployment, you should always use a specific version of the chart and upgrade **after [upgrading the Solr Operator](https://artifacthub.io/packages/helm/apache-solr/solr-operator#upgrading-the-solr-operator) to the same version**: ```bash +# Via OCI registry (recommended) +helm upgrade example oci://ghcr.io/apache/solr-operator/helm/solr --version 0.10.0-prerelease --reuse-values --set image.tag=9.10.0 + +# Or via the deprecated HTTPS helm repository helm upgrade example apache-solr/solr --version 0.10.0-prerelease --reuse-values --set image.tag=9.10.0 ```