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
246 changes: 246 additions & 0 deletions .github/workflows/publish-helm-oci.yaml
Original file line number Diff line number Diff line change
@@ -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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <VERSION>`
- **Solr Cloud**: `helm install solr oci://ghcr.io/apache/solr-operator/helm/solr --version <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)
Expand Down
24 changes: 13 additions & 11 deletions docs/modules/getting-started/pages/local-tutorial.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,27 @@ 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"]
----
# 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.
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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

Expand Down
26 changes: 18 additions & 8 deletions docs/modules/getting-started/pages/running-the-operator.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
Loading
Loading