Skip to content

feat(redis-operator): migrate from archived spotahome to freshworks-oss fork - #3406

Merged
Aleksei Sviridkin (lexfrei) merged 13 commits into
mainfrom
feat/redis-operator-freshworks
Aug 20, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 13 commits into
mainfrom
feat/redis-operator-freshworks

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Jul 21, 2026 •

Copy link
Copy Markdown
Member

What this PR does

spotahome/redis-operator was archived on 2026-06-11 (read-only; last release v1.2.4, 2022). This migrates the operator to the actively-maintained freshworks-oss/redis-operator fork (v3.3.5, Apache-2.0).

Why freshworks-oss

It keeps the same RedisFailover CRD and API group (databases.spotahome.com) — so existing managed Redis is unaffected — and adds a native spec.engine: Redis|Valkey switch, letting managed Valkey drop its Redis-compatibility shim image and run the official valkey/valkey image directly.

Changes

  • Re-vendor the chart from oci://ghcr.io/freshworks-oss/charts/redis-operator (v3.3.5), which carries the engine-aware CRD.
  • Build the operator image from freshworks-oss v3.3.5 source.
  • Re-target the label/annotation-preservation patch onto the freshworks Go module (github.com/freshworks/redis-operator).

Verification

  • freshworks-oss source + our labels.diff patch compiles natively with Go 1.26.3 (service and cmd packages).
  • git apply --check of the re-targeted patch against v3.3.5 succeeds.
  • The operator chart renders with the cozystack-registry image override.
  • The image is built (freshworks-oss v3.3.5 source + our patch, multi-arch amd64/arm64), pushed to ghcr.io/cozystack/cozystack/redis-operator, and pinned by digest in values.yaml.
  • hack/promote-retag_test.bats and hack/nightly-mirror_test.bats pass with the pinned digest.

Note for maintainers

packages/system/redis-operator is not part of the automated make build; its image is built out-of-band and the digest is pinned in values.yaml. That image is already built and pinned in this PR; re-run make -C packages/system/redis-operator image only if you bump the operator version.

Follow-up

The cozystack/redis-operator fork carries cert-manager TLS work (#2729) that freshworks-oss does not have yet; the plan is to upstream it to freshworks-oss so it lands in the shared maintained fork rather than a cozystack-only one.

Release note

feat(redis-operator): migrate from the archived spotahome/redis-operator to the actively-maintained freshworks-oss/redis-operator fork (same RedisFailover CRD, adds native spec.engine: Redis|Valkey)

Summary by CodeRabbit

  • New Features
    • Added support for injecting additional environment variables into the Redis Operator (including a default operator group id).
    • Added default configurable labels for the Redis Operator.
  • Bug Fixes
    • Preserves and merges existing Service labels and annotations during Redis Operator updates.
  • Chores
    • Updated the Redis Operator and Helm chart to the Freshworks-maintained 3.3.5 release, aligned chart/image sources, and simplified Helm chart retrieval.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Redis Operator chart and image now use Freshworks sources at version 3.3.5. Chart configuration adds optional environment variables and labels, removes CRD settings, and Service updates preserve existing labels and annotations.

Changes

Redis Operator refresh

Layer / File(s) Summary
Chart distribution and configuration
packages/system/redis-operator/Makefile, packages/system/redis-operator/charts/redis-operator/*
Helm retrieval now uses the Freshworks OCI registry; chart metadata and defaults target Freshworks sources at version 3.3.5, optional extraEnvVars are rendered into the deployment, and CRD configuration is removed.
Operator image and Service updates
packages/system/redis-operator/images/redis-operator/*, packages/system/redis-operator/values.yaml
The operator image build and deployment use version 3.3.5, the operator group is configured through extraEnvVars, and Service updates merge stored and incoming labels and annotations before updating.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: area/kubernetes, area/build

Suggested reviewers: ivanhunters

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: migrating the Redis operator from Spotahome to the Freshworks fork.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/redis-operator-freshworks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review kind/feature Categorizes issue or PR as related to a new feature size/S This PR changes 10-29 lines, ignoring generated files labels Jul 21, 2026
@kvaps
Andrei Kvapil (kvaps) marked this pull request as ready for review July 21, 2026 19:55
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@dosubot dosubot Bot added the area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) label Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/system/redis-operator/values.yaml`:
- Line 4: Update the image tag value in values.yaml from the floating v3.3.5 tag
to the digest-pinned value generated by the image build/push workflow or make
image, using the resulting v3.3.5@sha256:... format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a7d056ab-c14c-4064-87a7-85d5d71dcf19

📥 Commits

Reviewing files that changed from the base of the PR and between aef9e20 and deb4dff.

📒 Files selected for processing (8)
  • packages/system/redis-operator/Makefile
  • packages/system/redis-operator/charts/redis-operator/Chart.yaml
  • packages/system/redis-operator/charts/redis-operator/crds/databases.spotahome.com_redisfailovers.yaml
  • packages/system/redis-operator/charts/redis-operator/templates/deployment.yaml
  • packages/system/redis-operator/charts/redis-operator/values.yaml
  • packages/system/redis-operator/images/redis-operator/Dockerfile
  • packages/system/redis-operator/images/redis-operator/patches/labels.diff
  • packages/system/redis-operator/values.yaml

Comment thread packages/system/redis-operator/values.yaml Outdated

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with the cozy-review methodology. Verdict: LGTM with non-blocking notes. No blocking findings. A clean re-vendor of the operator. The vendored chart matches helm pull oci://ghcr.io/freshworks-oss/charts/redis-operator --version 3.3.5 byte-for-byte, the CRD and all consumed fields are identical, and child-resource naming and label propagation are identical at the source level between the old spotahome build and the freshworks fork, so existing managed Redis instances are adopted in place on upgrade.

  • Upgrade (Phase 5b.A): child resources rfr-<name> / rfs-<name> are identical to spotahome v1.3.0-rc1; the freshworks statefulset.go copies stored.volumeClaimTemplates on update, so the immutable STS is not rejected. Adoption in place, no duplicate, no split data.
  • Health monitoring: cozystack WorkloadMonitor selectors keep matching, since getLabels merges the RedisFailover's own labels (including app.kubernetes.io/instance) into child objects; the logic is identical between versions.
  • The charts-direct-edit invariant is a false positive on the silent-revert part: Makefile update does rm -rf charts && helm pull, the vendored tree equals the pull output, and the labels.diff patch applies cleanly via git apply --check.

Non-blocking notes

  • A live N-1 to N upgrade was not replayed (hermetic review). Running it on a dev cluster is recommended.
  • The image digest pin v3.3.5@sha256:551f... cannot be verified offline against the sources plus labels.diff (needs an image build/pull).
  • The CRD ships under crds/, which Helm/Flux does not update on existing releases: the new spec.engine: Valkey capability will not work on upgraded clusters until the CRD is replaced (stated as a follow-up).
  • No cozystack-side regression test for the labels.diff behavior (relies on upstream tests).
  • The branch is behind main (merge-base 64097dc4, main at f077420f); no conflicts across the eight touched files, but a rebase before merge is recommended.

@kvaps
Andrei Kvapil (kvaps) force-pushed the feat/redis-operator-freshworks branch from 7d03ed6 to ba310b8 Compare July 24, 2026 12:54
IvanHunters
IvanHunters previously approved these changes Jul 24, 2026

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Independently verified the load-bearing claims (static review, no cluster):

  • freshworks-oss/redis-operator v3.3.5 source: util.MergeLabels/util.MergeAnnotations exist and labels.diff applies + compiles against the real tag.
  • CRD backward-compatible: group/kind/version unchanged (databases.spotahome.com/RedisFailover/v1), new spec.engine is optional (enum Redis|Valkey, omitted == Redis), only required key is still spec. Existing RedisFailover CRs stay valid.
  • Vendored chart is byte-identical to helm pull oci://ghcr.io/freshworks-oss/charts/redis-operator --version 3.3.5 (reproducible make update).
  • helm template renders the pinned digest ref correctly; removed sed '/{{/d' leaves no templating in the CRD.
  • No leftover spotahome/quay refs, no half-migrated managed app.

Non-blocking:

  1. packages/apps/redis/README.md still says 'Spotahome Redis Operator' and links the archived repo — update in a fast follow-up.
  2. Image digest is the one thing not statically verifiable (needs registry pull) — relying on CI.
  3. Follow-up managed-Valkey PR must confirm on an upgraded (not fresh) cluster that the operator's CRD-ensure actually updates the in-cluster CRD to add engine, else spec.engine: Valkey gets pruned.
  4. Cosmetic: subchart Chart.yaml/values.yaml still carry upstream appVersion 1.3.0 / tag v1.3.0 (harmless, overridden by the pinned digest).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/system/redis-operator/images/redis-operator/Dockerfile`:
- Line 10: Update the Dockerfile’s redis-operator source download to use an
immutable commit reference instead of the mutable VERSION tag, and define the
expected archive checksum alongside it. Download the archive to a file, verify
it against the recorded checksum before extraction, then run tar on the verified
file rather than piping curl directly into tar.

In `@packages/system/redis-operator/values.yaml`:
- Around line 9-11: Before enabling OPERATOR_GROUP_ID in extraEnvVars, backfill
existing RedisFailover resources and update all future RedisFailover producers
to set redis-failover.freshworks.com/operator-group to cozystack; otherwise
defer adding OPERATOR_GROUP_ID until labeling is complete.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f71be02-25ae-4b4e-954e-da9a67ac0b6e

📥 Commits

Reviewing files that changed from the base of the PR and between a95fa0e and 41d1153.

📒 Files selected for processing (8)
  • packages/system/redis-operator/Makefile
  • packages/system/redis-operator/charts/redis-operator/Chart.yaml
  • packages/system/redis-operator/charts/redis-operator/crds/databases.spotahome.com_redisfailovers.yaml
  • packages/system/redis-operator/charts/redis-operator/templates/deployment.yaml
  • packages/system/redis-operator/charts/redis-operator/values.yaml
  • packages/system/redis-operator/images/redis-operator/Dockerfile
  • packages/system/redis-operator/images/redis-operator/patches/labels.diff
  • packages/system/redis-operator/values.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/system/redis-operator/charts/redis-operator/Chart.yaml

WORKDIR /workspace

RUN curl -sSL https://github.com/spotahome/redis-operator/archive/refs/tags/${VERSION}.tar.gz | tar -xzvf- --strip=1
RUN curl -sSL https://github.com/freshworks-oss/redis-operator/archive/refs/tags/${VERSION}.tar.gz | tar -xzvf- --strip=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## Locate Dockerfile"
fd -a 'Dockerfile$' . | sed 's#^\./##' | rg 'redis-operator|Dockerfile$' || true

echo
echo "## Target Dockerfile"
if [ -f packages/system/redis-operator/images/redis-operator/Dockerfile ]; then
  cat -n packages/system/redis-operator/images/redis-operator/Dockerfile
fi

echo
echo "## Search for VERSION definitions/usages in redis-operator image area"
rg -n '\bVERSION\b|redis-operator/archive|curl|checksum|sha256|sha512|apk add.*curl|apt.*curl|curl' packages/system/redis-operator || true

echo
echo "## Search GitHub archive/pinned URL patterns in repo"
rg -n 'github\.com/.*/archive/refs/tags|checksum|sha256sum|sha256|sha512sum|tar -xz|curl' packages/system/redis-operator Dockerfile 2>/dev/null || true

Repository: cozystack/cozystack

Length of output: 6055


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## Git diff/stat for relevant files"
git diff --stat -- packages/system/redis-operator/images/redis-operator/Dockerfile || true
git diff -- packages/system/redis-operator/images/redis-operator/Dockerfile | sed -n '1,220p' || true

echo
echo "## Find any checksum/attestation files mentioning redis-operator"
rg -n 'redis-operator|freshworks-oss/redis-operator|sha256|checksum|attest' -S . --glob '!**/.git/**' --glob '!**/node_modules/**' --glob '!**/dist/**' | sed -n '1,160p' || true

Repository: cozystack/cozystack

Length of output: 24217


Pin the source archive commit and verify a recorded checksum before extraction.

Dockerfile line 10 fetches freshworks-oss/redis-operator via a mutable Git tag URL and pipes the archive directly into tar; record the target commit and checksum, then download/verify before tar -x.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/system/redis-operator/images/redis-operator/Dockerfile` at line 10,
Update the Dockerfile’s redis-operator source download to use an immutable
commit reference instead of the mutable VERSION tag, and define the expected
archive checksum alongside it. Download the archive to a file, verify it against
the recorded checksum before extraction, then run tar on the verified file
rather than piping curl directly into tar.

Comment on lines +9 to +11
extraEnvVars:
- name: OPERATOR_GROUP_ID
value: "cozystack"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
rg -n --glob '*.yaml' \
  'OPERATOR_GROUP_ID|kind:[[:space:]]*RedisFailover|redis-failover\.freshworks\.com/operator-group' .

Repository: cozystack/cozystack

Length of output: 584


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== values.yaml =="
sed -n '1,80p' packages/system/redis-operator/values.yaml

echo
echo "== RedisFailover resources =="
for f in \
  packages/apps/redis/templates/redisfailover.yaml \
  packages/system/harbor/templates/redis.yaml \
  hack/e2e-chainsaw/harbor/chainsaw-test.yaml
do
  echo "-- $f --"
  sed -n '1,80p' "$f"
done

echo
echo "== redis-operator chart metadata/values relevant =="
sed -n '1,220p' packages/system/redis-operator/charts/redis-operator/values.yaml

Repository: cozystack/cozystack

Length of output: 10328


🌐 Web query:

freshworks redis-operator v3.3.5 OPERATOR_GROUP_ID redis-failover.freshworks.com/operator-group

💡 Result:

In the Freshworks Redis Operator (v3.3.5), the OPERATOR_GROUP_ID environment variable and the redis-failover.freshworks.com/operator-group label are components of the Label-Sharded Operator feature, which allows a single Kubernetes cluster to run multiple operator instances without configuration overlap [1][2]. Mechanism Overview This feature enables you to partition your RedisFailover custom resources (CRs) so that specific operator instances only manage designated resources [1]. 1. Configuring the Operator Instance To assign an operator to a specific group, set the OPERATOR_GROUP_ID environment variable in the operator deployment [1]: env: - name: OPERATOR_GROUP_ID value: "group-a" The operator requires this variable to be set; it will exit with an error if the value is missing or empty [1][3]. 2. Labeling RedisFailover CRs To ensure the operator reconciles only the intended resources, you must label your RedisFailover CRs with a matching key-value pair [1]: apiVersion: databases.spotahome.com/v1 kind: RedisFailover metadata: name: my-redis labels: redis-failover.freshworks.com/operator-group: group-a spec: #... When this configuration is in place, the operator instance will reconcile only those CRs where metadata.labels["redis-failover.freshworks.com/operator-group"] exactly matches its own OPERATOR_GROUP_ID [1][4]. This provides flexible, server-side filtering that remains compatible with --supported-namespaces-regex restrictions [1].

Citations:


Backfill Freshworks operator-group labels before enabling strict group filtering.

Freshworks redis-operator v3.3.5 only reconciles RedisFailover resources whose redis-failover.freshworks.com/operator-group label matches OPERATOR_GROUP_ID, so existing unlabeled resources will be ignored once this environment variable takes effect. Set redis-failover.freshworks.com/operator-group: cozystack on existing RedisFailover objects and future producers before removing the fallback behavior, or defer enabling OPERATOR_GROUP_ID until the backfill is complete.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/system/redis-operator/values.yaml` around lines 9 - 11, Before
enabling OPERATOR_GROUP_ID in extraEnvVars, backfill existing RedisFailover
resources and update all future RedisFailover producers to set
redis-failover.freshworks.com/operator-group to cozystack; otherwise defer
adding OPERATOR_GROUP_ID until labeling is complete.

@kvaps
Andrei Kvapil (kvaps) force-pushed the feat/redis-operator-freshworks branch from b4906f1 to a0a2115 Compare August 9, 2026 20:38
@kvaps

Copy link
Copy Markdown
Member Author

Round 3 addressed.

No-op ! assertions (blocker): all 8 negations in migration-54-redis-adopt.bats converted to positive [ "$(grep -c…)" -eq 0 ] form. Sanity-checked that they bite — a pin-always regression that clobbers a preset image turns the preset-untouched / label-only tests red.

Round provenance (blocker): dropped the "Round-2 review:" opener from the migration commit; it now states the two defects directly. No "round" text anywhere in the branch.

Comments (blocker): removed the reference to migration-54-fluxcd-orphan.bats (not in this branch); fixed the backwards comment — "removing the label/pin is the whole point" → the migration applies them.

Non-blocking: the fake's per-CR read now exit 1s loudly on a no-match instead of returning empty at rc 0.

Rebased on main (which also clears the inherited talos-diagnostics EXIT-trap red).

…ss fork

spotahome/redis-operator was archived 2026-06-11 (read-only). Switch the
operator to the actively-maintained freshworks-oss/redis-operator fork, which
keeps the same RedisFailover CRD and API group (databases.spotahome.com) and
adds a native Valkey engine (spec.engine: Redis|Valkey) — so managed Redis is
unaffected and managed Valkey no longer needs a Redis-compat shim image.

- re-vendor the chart from oci://ghcr.io/freshworks-oss/charts/redis-operator
- build the operator image from freshworks-oss v3.3.5 source
- re-target the label/annotation-preservation patch onto the freshworks module

The operator image is built out-of-band (make -C packages/system/redis-operator
image) and its digest pinned in values.yaml; a maintainer must rebuild and pin
before merge (tag is a placeholder here).

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
Build the freshworks-oss v3.3.5 operator image (with our label-preservation
patch) and pin its digest in values.yaml, replacing the placeholder tag.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
…s fork

The freshworks-oss fork exits fatal at startup when operator_group_id is
unset, unlike the archived spotahome operator. Pin a stable non-empty value
via extraEnvVars so the operator boots instead of CrashLooping and blocking
the install.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
The freshworks-oss operator filters RedisFailovers by the
redis-failover.freshworks.com/operator-group label matching its
OPERATOR_GROUP_ID; without the label it ignores the CR and no Redis is
provisioned. Stamp the group (cozystack) so the migrated operator adopts
the app's clusters.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
Harbor provisions its own RedisFailover; the freshworks-oss operator
filters by the redis-failover.freshworks.com/operator-group label, so without
it Harbor's Redis is never created and harbor-core CrashLoops. Stamp the same
group (cozystack) as the operator and the redis app.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
The freshworks-oss operator watches RedisFailovers through a server-side
operator-group label selector, so a CR without the label is silently dropped
from its informer. The chart templates now stamp the label, but an existing CR
only gets it when its own HelmRelease next upgrades — after the operator rolls
— leaving a window with no healing, and a suspended/stuck HelmRelease never
gets it at all. Label every RedisFailover in a pre-upgrade migration, ahead of
the new operator.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
The freshworks-oss operator's compiled-in default image moved from
redis:6.2.6-alpine to 7.2.4; Harbor pinned no image at all and apps/redis left
its sentinels unpinned, so an upgrade would move them silently. 7.2.4 rewrites
dump.rdb into a format 6.2.6 refuses to load, so a platform rollback would leave
Harbor's Redis crash-looping on its own data. Pin redis+sentinel (Harbor) and
the sentinel (apps/redis) at the version they run today; bump deliberately and
separately.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
helm-controller skips CRD upgrades by default, so an upgraded cluster would
keep the old spotahome schema and prune the fork's spec.engine field on
admission. The schema diff is additive, so CreateReplace is safe. Also refresh
the harbor e2e wait comment for the freshworks operator.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
…tion 54

Two defects in migration 54's adoption pass:

(1) The label landed before the image pins, so the operator adopted a
labelled CR with empty image fields and rolled Redis to the fork's 7.2.4
default — rewriting dump.rdb into a format the later 6.2.6 chart pin can no
longer load. Pin spec.redis.image/spec.sentinel.image to redis:6.2.6-alpine
in the same pass, only where empty.

(2) The CRD probe used a bare `get crd >/dev/null 2>&1` that could not tell
NotFound from an API blip and stamped anyway; switch to migration 50's
`--ignore-not-found -o name` so a real error aborts under set -e.

Also self-contained the renumber note and qualified the resource.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
…e fail-closed)

Drive migration 54 end-to-end against a fake kubectl in a jq-enabled build of
the migrations image's alpine base (busybox ash, the production interpreter),
mirroring the docker+fake-kubectl migration-test harness.

Pinned properties:
  - an absent CRD stamps 55 without patching anything;
  - a failing CRD probe aborts under set -euo pipefail before stamping (a
    one-off apiserver blip must not read as "absent" and skip adoption);
  - every RedisFailover across namespaces is labelled onto the freshworks
    operator-group, while the engine is pinned to redis:6.2.6-alpine only where
    the image is empty (both roles for Harbor; sentinel only where redis.image
    is preset, which is left untouched; label-only when both are preset);
  - a failed adoption patch aborts before stamping so the Job retries.

Auto-discovered by the Makefile hack/*.bats wildcard; no registration needed.

Assisted-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps
Andrei Kvapil (kvaps) force-pushed the feat/redis-operator-freshworks branch from d0ec44b to 3197c48 Compare August 19, 2026 08:16

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. All three blockers are closed: the eight negations are now the positive-count form, the round opener is out of the commit body, and both comments are fixed. The fake kubectl's no-match read exits 1 too.

I verified the parts worth worrying about rather than the wording. diff -r between the vendored chart and a fresh helm pull oci://ghcr.io/freshworks-oss/charts/redis-operator --version 3.3.5 comes back empty, so dropping the old sed '/{{/d' was right and make update reproduces the tree; extraEnvVars is upstream's own knob, not a local edit to a vendored template. upgradeCRDs is a real enum-validated PackageSource field and it lands on Upgrade.CRDs only, which is what you want given Flux already creates CRDs on install. The pinned digest resolves to a real amd64+arm64 manifest, so the placeholder from the first commit is gone.

One coordination trap. #3379 also adds migrations/54 and also moves targetVersion from 54 to 55. The migration file collides loudly on rebase, but the values.yaml line does not: both sides write the same 55, so git merges it clean. Whichever lands second has to renumber to 55 and bump targetVersion to 56, otherwise the runner stops at 55 and the renumbered migration never runs — the silent skip this migration exists to prevent.

packages/apps/redis and packages/system/redis-operator have no tests directory, so the app's operator-group label and OPERATOR_GROUP_ID: cozystack are the two ends of a coupling that nothing pins. Harbor's side you did pin. Not blocking, since there is no convention to follow in those two packages, but that pair is where a typo costs a silent no-provision.

E2E is red on the kubernetes suites only (node-join). Redis and harbor both passed.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 4385990 into main Aug 20, 2026
42 of 47 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the feat/redis-operator-freshworks branch August 20, 2026 10:11
Andrey Kolkov (androndo) added a commit that referenced this pull request Sep 2, 2026
## What this PR does

Adds a **managed Valkey** service to the catalog, alongside managed
Redis.

> **Stacked on #3406** (redis-operator migration to freshworks-oss).
This PR targets that branch and depends on it; review/merge #3406 first.

### Why

Redis relicensed at 8.x to a source-available family (AGPLv3 / SSPL /
RSALv2), and the managed Redis app currently ships `v8: 8.4.0` with no
BSD-licensed option ≤ 7.2. That is a licensing risk for CNCF Incubation.
[Valkey](https://valkey.io) is the BSD-3-Clause fork of Redis 7.2.4,
governed by the Linux Foundation, and a drop-in replacement for Redis.
This is the same move Argo CD made —
[`cncf/foundation#750`](cncf/foundation#750)
was closed with "no need for exception" after they migrated to Valkey.

### How it works

Valkey runs on the same operator as managed Redis. #3406 migrates that
operator from the archived `spotahome/redis-operator` to the
actively-maintained **freshworks-oss/redis-operator** fork, which adds a
native `spec.engine: Valkey` switch. With it, the operator runs
`valkey-server` / `valkey-cli` natively (in the launch command and in
its liveness / readiness / shutdown probes), so the chart uses the
official `valkey/valkey` image directly — **no Redis-compatibility shim
image**.

The app mirrors managed Redis: same shape/values (`replicas`,
`resources`/`resourcesPreset`, `size`, `storageClass`, `external`,
`version`, `authEnabled`), Sentinel-based HA, metrics exporter,
`WorkloadMonitor`s, dashboard resource map, and `ApplicationDefinition`
(`kind: Valkey`).

Versions offered: `v8 → 8.1.8` (default) and `v7 → 7.2.13` (the
BSD-3-Clause Redis 7.2 line, most conservative drop-in).

### How it was verified

- `helm template` renders cleanly for `v8`, `v7`, and `external: true`;
the `RedisFailover` carries `spec.engine: Valkey` and `image:
valkey/valkey:<version>`. `helm lint` shows only the pre-existing
icon-URL / `cozy-lib` warnings that managed Redis emits too.
- `helm template` of `valkey-rd` renders a valid `ApplicationDefinition`
(`kind: Valkey`, `plural: valkeys`, `category: PaaS`).
- Generated artifacts (`values.schema.json`, `README.md`, `types.go`,
`zz_generated.deepcopy.go`, the ApplicationDefinition `openAPISchema`)
reproduce with the pinned `cozyvalues-gen` v1.6.0 and `controller-gen`
v0.16.4 — root `make generate` and per-app generate both produce no
drift; `go build ./valkey/...` passes.
- A live-cluster e2e was not run from this environment; the Chainsaw
suite `hack/e2e-chainsaw/valkey/` (mirroring the redis suite) is
included and `hack/select-e2e.sh` maps the `valkey-application` source
to it, so it runs in CI once the freshworks operator image is built.

### Notes

- The Valkey logo (`packages/apps/valkey/logos/valkey.svg`) is a
placeholder in Valkey's brand colors, pending the official brand asset.
- A Grafana `db/valkey` dashboard was intentionally left out of this
initial PoC; it can follow.

### Screenshots

N/A — no UI changes.

### Downstream repositories

This adds a new managed-app kind, which likely warrants follow-ups in
`cozystack/website` (user-facing docs for the new service) and possibly
`cozystack/terraform-provider-cozystack`. No follow-up PRs are opened
yet — leaving these for a maintainer to decide, per the template
guidance.

- [ ] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:

### Release note

```release-note
feat(valkey): add managed Valkey service — a BSD-3-Clause, Linux Foundation-governed alternative to managed Redis, running on the freshworks-oss redis-operator via native spec.engine: Valkey (versions 8.1.8 and 7.2.13)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added managed Valkey service support with high availability and
configurable replicas.
* Supports Valkey versions 7 and 8, persistent storage, resource
presets, authentication, and optional external access.
  * Added monitoring metrics and dashboard integration.
  * Added platform package integration and tenant administrator access.
* **Documentation**
* Added Valkey configuration guidance and storage-class immutability
documentation.
* **Tests**
* Added end-to-end coverage for deployment readiness, storage, and
replicas.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Andrei Kvapil (kvaps) pushed a commit that referenced this pull request Sep 7, 2026
…ss fork (#3406)

## What this PR does

`spotahome/redis-operator` was archived on 2026-06-11 (read-only; last
release v1.2.4, 2022). This migrates the operator to the
actively-maintained **freshworks-oss/redis-operator** fork (v3.3.5,
Apache-2.0).

### Why freshworks-oss

It keeps the same `RedisFailover` CRD and API group
(`databases.spotahome.com`) — so existing managed Redis is unaffected —
and adds a native `spec.engine: Redis|Valkey` switch, letting managed
Valkey drop its Redis-compatibility shim image and run the official
`valkey/valkey` image directly.

### Changes

- Re-vendor the chart from
`oci://ghcr.io/freshworks-oss/charts/redis-operator` (v3.3.5), which
carries the `engine`-aware CRD.
- Build the operator image from freshworks-oss v3.3.5 source.
- Re-target the label/annotation-preservation patch onto the freshworks
Go module (`github.com/freshworks/redis-operator`).

### Verification

- freshworks-oss source + our `labels.diff` patch compiles natively with
Go 1.26.3 (`service` and `cmd` packages).
- `git apply --check` of the re-targeted patch against v3.3.5 succeeds.
- The operator chart renders with the cozystack-registry image override.
- The image is built (freshworks-oss v3.3.5 source + our patch,
multi-arch amd64/arm64), pushed to
`ghcr.io/cozystack/cozystack/redis-operator`, and pinned by digest in
`values.yaml`.
- `hack/promote-retag_test.bats` and `hack/nightly-mirror_test.bats`
pass with the pinned digest.

### Note for maintainers

`packages/system/redis-operator` is not part of the automated `make
build`; its image is built out-of-band and the digest is pinned in
`values.yaml`. That image is already built and pinned in this PR; re-run
`make -C packages/system/redis-operator image` only if you bump the
operator version.

### Follow-up

The cozystack/redis-operator fork carries cert-manager TLS work
(#2729) that freshworks-oss does not have yet; the
plan is to upstream it to freshworks-oss so it lands in the shared
maintained fork rather than a cozystack-only one.

### Release note

```release-note
feat(redis-operator): migrate from the archived spotahome/redis-operator to the actively-maintained freshworks-oss/redis-operator fork (same RedisFailover CRD, adds native spec.engine: Redis|Valkey)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for injecting additional environment variables into the
Redis Operator (including a default operator group id).
  * Added default configurable labels for the Redis Operator.
* **Bug Fixes**
* Preserves and merges existing Service labels and annotations during
Redis Operator updates.
* **Chores**
* Updated the Redis Operator and Helm chart to the Freshworks-maintained
3.3.5 release, aligned chart/image sources, and simplified Helm chart
retrieval.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review kind/feature Categorizes issue or PR as related to a new feature size/XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants