Files
cozystack/packages/system
Timofei Larkin 8f19910988 chore(platform)!: remove the HTTPCache application (#4200)
## What this PR does

Removes the HTTPCache application.

Telemetry says it is the least installed app we ship: 3 instances in
June, July and August 2026, 4 so far in September, out of 1162-1418
clusters reporting per month. That is not zero, so I am not going to
claim nobody uses it. The maintenance side is what does not hold up.

`make update` in this package is broken. All eight sed lines in the
`update` target patch `images/nginx/Dockerfile`, but the image lives in
`images/nginx-cache/Dockerfile`, so the target fails on the first line.
It is the only package under `packages/apps/` pointing at a Dockerfile
that does not exist. The pins show what that cost us:

```
nginx              1.25.3   -> 1.31.5
ngx_cache_purge    2.5.3    -> 3.0.2
nginx-module-vts   0.2.2    -> 0.2.7
ip2proxy-c         4.1.2    -> 4.3.0
IP2Location-C      8.6.1    -> 8.7.0
ip2location-nginx  8.6.0    -> 8.7.0
ip2proxy-nginx     8.1.1    -> 8.2.0
51Degrees          3.2.21.1 -> 3.2.21.1 (frozen upstream)
```

So we ship an old nginx with third party C modules compiled into it, and
nothing tests it: no chainsaw suite, no `helm unittest` target. I don't
think we should keep carrying that for 4 instances.

Removed: the chart in `packages/apps/http-cache`, its ResourceDefinition
in `packages/system/http-cache-rd`, the values type in
`api/apps/v1alpha1/httpcache`, the `cozystack.http-cache-application`
PackageSource, its line in the `naas` bundle, the `httpcaches` entry in
`cozy:tenant:admin:base`, the dashboard icon, and the entry in the root
`Makefile` build list.

`cozy:tenant:admin:base` enumerates the `apps.cozystack.io` resources a
tenant owner may write, so `httpcaches` comes out of it with the rest of
the application. A cluster that freezes gets the grant back from the
migration instead, which keeps the chart's list tracking the catalog and
leaves no entry behind for a later sweep to read as dead config.

### Existing installations

A cluster that still runs an HTTPCache keeps it, served from a frozen
source. A cluster that never created one keeps nothing.

Without a migration an upgrade would break both.
`templates/sources.yaml` is a bare glob with no keep annotation, so Helm
prunes the http-cache PackageSource; the ArtifactGenerator is owned by
it and goes too, and both ExternalArtifacts go with the generator. Those
are the `chartRef` targets of `hr/http-cache-rd` and of every tenant
`http-cache-<name>` release, so all of them would sit `Ready=False` for
good and `HelmReleaseNotReady` would fire on every cluster with the naas
bundle.

Migration 58 runs as a pre-upgrade hook, before that prune, and branches
on whether any instance exists. Its header comment carries the mechanism
in full; this is the summary.

If one does, it copies the packages `OCIRepository` and pins the copy to
the manifest digest that object resolves at hook time, which is the
release the instances are rendering from right then. `spec.ref.digest`
is used when the installer pinned one; a tag or semver ref goes through
`status.artifact.revision`, whose digest half is the manifest digest.
`status.artifact.digest` is the checksum of the downloaded tarball and
cannot stand in, and a source with neither aborts the migration rather
than publishing a source that points nowhere. Reading the digest live
rather than baking one into the script makes the freeze a no-op by
construction and asks no question about which release was the last to
ship the chart.

The copy takes the url, the pull secret, the interval and any
verification block from the live object, so an air-gapped or mirrored
registry keeps serving exactly what it already served. It is written
with no owner references and no Helm metadata, and with the
`platform.cozystack.io/no-delete` label the platform chart puts on the
original, because it becomes the only chart source those instances have.
The PackageSource is then repointed at the copy, annotated
`helm.sh/resource-policy: keep` and stripped of its release metadata, so
neither Helm nor a later release adopts or prunes it. Helm re-reads that
annotation off the live object when it prunes, which is what makes
disowning from inside a pre-upgrade hook work.

Names stay as they are, deliberately. The ApplicationDefinition inside
that artifact hardcodes its `chartRef`, so a renamed PackageSource would
leave every release pointing at an artifact nobody produces. Because the
names hold, `hr/http-cache-rd` and every tenant release keep the
`chartRef` they already have and nothing goes not ready. What changes is
where the chart comes from: a pinned digest that no later release moves.

The migration also applies `cozy:tenant:admin:http-cache-frozen`, a
ClusterRole labelled `rbac.cozystack.io/aggregate-to-tenant-admin`,
granting the verbs `cozy:tenant:admin:base` used to carry on
`httpcaches`. The hook applies it before the upgrade drops the rule from
the chart, so an owner's access never lapses and nothing changes for
them. Without it a frozen instance would be visible and undeletable by
the person who owns it: the wildcard over `apps.cozystack.io` lives in
`cozy:tenant:base`, which aggregates into `cozy:tenant` and not into
`cozy:tenant:admin`, `cozy:tenant:view:base` is read only, and no role
in the tenant chain carries a verb on `helm.toolkit.fluxcd.io`.

If no instance exists, the migration removes the platform side instead:
the Package first and waited on, because the operator reconciles off an
informer cache and re-creates the release it owns while that Package is
still there, then the release, its ApplicationDefinition and its Helm
storage. Nothing is pinned or granted on a cluster that never used the
application.

Every path is fail-closed. A failed fleet scan, a failed read of the
source OCIRepository, a source with no digest to freeze on, a failed
patch or a failed delete stops the migration before it stamps the
version.

The migration is numbered 58, because main already carries a 57 from the
SeaweedFS volume-size-limit change and its `targetVersion` is already
58. #4287 wants 58 as well, so whichever of the two lands second
renumbers and bumps `targetVersion` with it. main is merged in rather
than rebased, because the branch carries commits that are not mine to
rewrite; the one conflict was `migrations.targetVersion`, resolved as
59, one past this branch's migration number.

### The procedure, written down

`docs/deprecating-applications.md` is new, and is the point of doing
this one carefully. It covers how to choose between migrating instances
onto a successor and freezing them, the chain that makes a bare chart
deletion strand every surviving instance, how the freeze reads its
digest off the cluster's own source, what the migration owes a cluster
on each branch, and where the tenant RBAC grant goes. `AGENTS.md` points
at it so the next retirement starts there rather than rediscovering it.

### If you run HTTPCache

Nothing changes on upgrade. Your instance keeps running and stays
manageable through the Cozystack API and the dashboard, and `kubectl get
httpcaches` keeps working.

What changes is that it is frozen. The chart now comes from the packages
artifact your cluster was already running, pinned by digest, and gets no
further updates from us, including security updates to the nginx build.
There is no replacement in the catalog. Delete the HTTPCache object when
you no longer need it, the way you always did; the migration keeps the
tenant permission that lets you.

### Verification

`helm template` on `packages/core/platform` before and after, for
`isp-full`, `isp-full-generic` and `isp-hosted`. In all three the
differences are the `http-cache` Package and PackageSource going away
and `migrations.targetVersion` moving from 57 to 58, which on a cluster
below 58 also renders the migration hook Job and its RBAC.

The migration suite `hack/migration-58-http-cache-freeze.bats` covers
both branches, the order of every step and each fail-closed path.
Freezing on the tarball checksum instead of the manifest digest,
dropping the `no-delete` label, dropping the `managed-by` null, dropping
the tenant grant, returning from the Package delete without waiting,
freezing unconditionally and granting on a cluster with no instance each
turn the matching test red.
`packages/system/cozystack-basics/tests/clusterroles-tenant-admin-aggregation_test.yaml`
pins the aggregation label the migration's ClusterRole reaches tenant
admins through, so renaming it fails in the chart rather than silently
on the clusters that need the grant.

Green: `helm unittest` for `packages/core/platform` and
`packages/system/cozystack-basics`, `make migrations-target-check`,
`hack/cozystack-version-stamp.bats`, `go test
./internal/controller/cacert/...`, `go build ./...` in the
`api/apps/v1alpha1` module, the console `ServicesTab` and
`sidebar-icons` suites with `tsc --noEmit`, `make rd-presets-check`, and
the bats suites that enumerate packages and image refs.

### Screenshots

The catalog entry and its nginx sidebar icon are gone. Nothing new to
show.

### Downstream repositories

Two repos are affected. No follow-up is open yet, so no box is ticked.

`cozystack/website` carries `content/en/docs/*/networking/http-cache.md`
in eight doc versions and lists `http-cache` in the hardcoded
`NETWORKING` list in its Makefile. The `next` page and the Makefile
entry are what need to go, released versions stay as history.

`cozystack/terraform-provider-cozystack` has a `cozystack_httpcache`
resource and data source. The resource keeps working after this: it is
hand written against its own terraform-plugin-framework model and
imports nothing from here. What breaks, once that repo bumps its
`api/apps/v1alpha1` pin past this release, is
`internal/provider/httpcache_model_test.go`, the per kind schema guard,
which is the only file over there importing this module. The resource
and the guard should go together.

The other repos have no reference to the package.

- [ ] 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:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
chore(http-cache)!: remove the HTTPCache application from the catalog. New instances can no longer be created from the catalog and the `HTTPCache` values type is gone from the `api/apps/v1alpha1` Go module. A platform migration keeps existing instances working: on a cluster that runs one, the application is frozen on the packages artifact that cluster was already rendering from, pinned by digest, and stays manageable through the Cozystack API and the dashboard, but receives no further updates, including security updates to the nginx build. On a cluster with no instance the application is removed outright. There is no replacement in the catalog; delete the HTTPCache object when you no longer need it.
```


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

* **Removed**
* Removed the HTTP Cache application and its deployment, configuration,
dashboard metadata, and packaging from the platform.
  * The HTTP Cache application is no longer included in the NaaS bundle.
* HTTP Cache resources and related API definitions are no longer
available.

* **Migration**
* Existing HTTP Cache installations are frozen during migration;
environments without instances are cleaned up.
  * Platform migration target advanced to version 58.

* **Documentation**
* Updated storage immutability documentation to reflect Valkey instead
of HTTP Cache.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-18 17:03:21 +04:00
..
2026-03-25 15:57:25 +05:00
…