Visitar URL original
Merge main and resolve proposal metadata conflicts · cozystack/community@79ddf13 · GitHub
Skip to content

Commit 79ddf13

Browse files
Merge main and resolve proposal metadata conflicts
Remove Status and Date from the newly merged platform migrations proposal. Assisted-By: LLM Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2 parents 5692116 + 7b3460b commit 79ddf13

6 files changed

Lines changed: 749 additions & 32 deletions

File tree

‎design-proposals/cozymarketplace-supplementary/README.md‎

Lines changed: 33 additions & 12 deletions
Large diffs are not rendered by default.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# 0001. A Tap is a computed view, and the materializer runs in the operator
2+
3+
- **Number:** `0001`
4+
- **Date:** `2026-09-02`
5+
- **Status:** Accepted
6+
- **Deciders:** `@IvanHunters, @kvaps`
7+
- **Proposal:** [`../README.md`](../README.md)
8+
- **Decided in:** [`cozystack/cozystack#3940`](https://github.com/cozystack/cozystack/pull/3940)
9+
- **Implemented in:** [`cozystack/cozystack#3940`](https://github.com/cozystack/cozystack/pull/3940), [`cozystack/cozystack#4308`](https://github.com/cozystack/cozystack/pull/4308)
10+
11+
## Context
12+
13+
The supplementary proposal designed the marketplace backend as a set of `/marketplace/*` HTTP endpoints added to `cozystack-api`, fronted by a `TapIndex` cache controller in the same binary that would watch each tapped source's artifact revision and serve the catalog from memory. The proposal itself noted that all of the catalog state is derivable from the `PackageSource` resources plus the `ApplicationDefinition`s and chart metadata inside each tapped artifact, and that `cozystack-api` already mediates the dashboard's access to cluster resources under the existing auth and RBAC.
14+
15+
When the feature was built in `#3940`, that observation was taken to its conclusion: if the state is fully derivable, the backend does not need to store or cache it behind its own endpoints.
16+
17+
## Decision
18+
19+
The catalog is a cluster-scoped `Tap` resource served through the aggregated Kubernetes API and computed on read from the labelled Flux source, its `PackageSource`(s) and their `ApplicationDefinition`s. Creating a `Tap` records intent only: it writes the labelled Flux `OCIRepository`, nothing more. A controller in the operator does the materialization, pulling the artifact, creating the `PackageSource`(s), and registering the repository's apps. There are no bespoke `/marketplace/*` HTTP endpoints and no `TapIndex` cache; the dashboard drives the standard aggregated `taps` resource for connect, disconnect and read.
20+
21+
## Why not the alternatives
22+
23+
- **`/marketplace/*` endpoints plus a `TapIndex` cache, as this proposal first drew them** ([Architecture and the endpoint table](../README.md#architecture)). Every value they would serve is already derivable from the `PackageSource` plus the parsed artifact, and the aggregated API already carries auth and RBAC, so a computed, read-only resource gives the same result with no endpoint set to maintain and no cache to invalidate on each revision. This is the rejection that is new here: the proposal argued for the endpoints and the cache, and the implementation did not build them.
24+
- **A dedicated CRD for marketplace state (`Tap`, `TapEntry`, ...).** All the necessary state is derivable, so a stored CRD adds migration cost without adding capability, and `Tap` stays a computed view rather than stored data. The proposal had already rejected this in its own Alternatives section ([_A dedicated CRD for marketplace state_](../README.md#alternatives-considered)); it is recorded here only for completeness.
25+
26+
## Consequences
27+
28+
- No cache to invalidate and no endpoint surface to keep in step with the CRDs: a read recomputes from the live `PackageSource` and the artifact metadata. The cost is paid per read rather than amortised in a cache.
29+
- Because the catalog is the cluster-scoped `taps` resource, it inherits Kubernetes RBAC directly: create and delete are admin-only, read is granted to the tenant base roles. That is also why catalog metadata is cluster-wide readable (see the proposal's Security section).
30+
- Two properties this proposal's re-approval ([`cozystack/community#23` review](https://github.com/cozystack/community/pull/23#pullrequestreview-5007756943)) listed were not built, and are not planned as part of this record:
31+
- **`visibility: private`.** There is no `visibility` field on `Tap` or `PackageSource`; catalog metadata of a private tap is readable by every authenticated user, only the pull credential is protected. This was not a recorded decision: the marker depended on the dropped endpoints and simply did not ship with them. Read it as "dropped together with the endpoints", not as a choice to keep private metadata world-readable; whether to add the control back is open, next to the privilege-model work in the 1.7 marketplace epic ([`cozystack/cozystack#4981`](https://github.com/cozystack/cozystack/issues/4981)).
32+
- **An `OrphanedSource` indicator.** Orphaning on disconnect works (a user `Package` keeps no owner reference back to the source, and the `apps.cozystack.io/tap-materializer` finalizer on the tap's Flux `OCIRepository` orders teardown), but no dedicated orphaned-state condition is surfaced. This too was not a recorded decision: the surfacing was not built, and the orphaning does not depend on it.
33+
- The credential-on-the-Flux-source design (a `secretRef` on the source the tap creates, the admin pre-creating the `Secret` in `cozy-system`) did ship as the proposal wrote it.
34+
35+
## Revisit if
36+
37+
Catalog scale makes per-read recomputation too slow to serve the dashboard, which would justify a cache after all; or a multi-tenant deployment needs per-tap metadata visibility, which would need either the endpoints back or a visibility field on the resource.

0 commit comments

Comments
 (0)