diff --git a/content/en/docs/next/marketplace/_index.md b/content/en/docs/next/marketplace/_index.md new file mode 100644 index 00000000..a8134912 --- /dev/null +++ b/content/en/docs/next/marketplace/_index.md @@ -0,0 +1,48 @@ +--- +title: "Application Marketplace" +linkTitle: "Marketplace" +description: "Extend the Cozystack application catalog with external repositories using the PackageSource model and the cozypkg CLI." +weight: 48 +--- + +The Cozystack marketplace lets an administrator extend the built-in application catalog with applications published in external repositories. Once a repository is connected to a cluster, its applications appear in the same dashboard catalog and behave like the standard managed applications platform users already know. + +A repository is a self-contained, versioned bundle published as an OCI artifact. It is authored and validated with the `cozypkg` CLI, connected to a cluster with a single command (or from the dashboard), and, optionally, listed in a community index so operators can discover it. + +{{% note %}} + +The marketplace is built on the `PackageSource` model, a different and newer mechanism than the Git-and-HelmRelease bootstrap described in [Adding External Applications]({{% ref "/docs/next/applications/external" %}}). The two can coexist on a cluster; new repositories should use the marketplace model. + +{{% /note %}} + +## How it works + +A marketplace repository ships one or more `PackageSource` resources. Each `PackageSource` declares variants and components; a component is a Helm chart plus, for user-installable applications, an `ApplicationDefinition` that registers the application with the Cozystack API and dashboard. + +The lifecycle has two sides: + +- **Publishing** turns a repository into an OCI artifact: `cozypkg init` scaffolds it, `cozypkg validate` lints it offline, and `cozypkg push` bundles the `packages/` tree into a single versioned artifact in any OCI registry. +- **Connecting** registers that artifact on a cluster: `cozypkg tap` (or the dashboard) creates a Flux `OCIRepository` and materializes the repository's `PackageSource` resources. `cozypkg add` then installs individual applications from the connected repository, and they show up in the catalog. + +## Key objects + +| Object | Group | Role | +| --- | --- | --- | +| `PackageSource` | `cozystack.io/v1alpha1` | Declares a repository's variants and components. | +| `ApplicationDefinition` | `cozystack.io/v1alpha1` | Registers a component as a user-installable application in the API and dashboard. | +| `Tap` | `core.cozystack.io/v1alpha1` | Virtual resource backing the dashboard "Repositories" view: connect, list, and disconnect repositories. | +| `OCIRepository` | `source.toolkit.fluxcd.io/v1` | Flux source Cozystack creates for a connected repository's artifact. | + +A connected repository keeps its own declared `PackageSource` name. If that name (or an application it registers) would collide with a core component, the connect is rejected, so an external package can never shadow an official one. + +## Trust model + +Connecting a third-party repository runs its charts in your management cluster, so connect only sources you trust. + +Signature verification happens at **publication** time, not at connect time. `cozypkg tap` and the dashboard connect flow validate an artifact's structure but do not verify its cosign signature. The verification points are the community index CI gate, which pins each release to the entry's recorded cosign identity, and, optionally, Flux `OCIRepository` verification at pull time. See [Publishing a Repository]({{% ref "/docs/next/marketplace/publishing" %}}#the-community-index) for details. + +## Where to go next + +- [Publishing a Repository]({{% ref "/docs/next/marketplace/publishing" %}}): scaffold, validate, push, and list a repository in the community index. +- [Connecting a Repository]({{% ref "/docs/next/marketplace/connecting" %}}): discover, connect, install, and disconnect repositories on a cluster. +- [`cozypkg` Reference]({{% ref "/docs/next/marketplace/cozypkg" %}}): every command and flag. diff --git a/content/en/docs/next/marketplace/connecting.md b/content/en/docs/next/marketplace/connecting.md new file mode 100644 index 00000000..057806cf --- /dev/null +++ b/content/en/docs/next/marketplace/connecting.md @@ -0,0 +1,104 @@ +--- +title: "Connecting a Repository" +linkTitle: "Connecting" +description: "Discover, connect, install from, and disconnect external application repositories on a Cozystack cluster." +weight: 20 +--- + +This guide is for **operators**: cluster administrators who connect external repositories and install their applications. It covers discovering repositories, connecting them from the CLI or the dashboard, installing applications, and disconnecting. + +For the publisher side (packaging and pushing a repository), see [Publishing a Repository]({{% ref "/docs/next/marketplace/publishing" %}}). + +## Prerequisites + +- The `cozypkg` CLI and a kubeconfig for the target cluster. Creating cluster-scoped resources requires cluster-admin. +- Cozystack with the marketplace enabled on the management cluster. + +{{% warning %}} + +Connecting a repository runs its charts in your management cluster. Connect only sources you trust, or repositories listed in a curated index whose gate verifies signatures. See the [Trust model]({{% ref "/docs/next/marketplace" %}}#trust-model). + +{{% /warning %}} + +## Discover repositories + +`cozypkg search` queries the community index and lists matching repositories without connecting them. Point it at an index with `--index` or the `COZYPKG_INDEX` environment variable (a local directory or an `oci://` reference): + +```bash +export COZYPKG_INDEX=oci://ghcr.io/cozystack/packages-index:latest +cozypkg search database +``` + +## Connect from the CLI + +`cozypkg tap` registers a published repository. It creates a Flux `OCIRepository` pointing at the artifact and materializes the `PackageSource` resources the artifact carries under their declared names. If a name (or an application it registers) would collide with a core component or another connected repository, the tap is rejected instead of overwriting it, so an external package cannot shadow an official one. Nothing is installed yet: + +```bash +cozypkg tap oci://ghcr.io/acme/hello:v1.0.0 +``` + +Tapping is idempotent. Use `--tag` to override the tag in the reference, and `--skip-validate` to skip validating the artifact structure before tapping (not recommended). + +If the repository is listed in an index, you can tap it by its short name and let the index resolve the reference: + +```bash +cozypkg tap acme.hello --index "$COZYPKG_INDEX" +``` + +### Private repositories + +For a private registry, pre-create a pull-credential `Secret` in the `cozy-system` namespace and point the tap at it with `--secret`. Cozystack attaches it as the `OCIRepository`'s `secretRef`: + +```bash +kubectl create secret docker-registry acme-pull \ + --namespace cozy-system \ + --docker-server=ghcr.io \ + --docker-username= \ + --docker-password= + +cozypkg tap oci://ghcr.io/acme/hello:v1.0.0 --secret acme-pull +``` + +## Connect from the dashboard + +The dashboard "Repositories" view is backed by the `Tap` resource and covers the same flow without the CLI. Open it from the sidebar, choose **Connect**, and provide the `oci://` reference and, for a private repository, the name of a pull-credential `Secret` in `cozy-system`. Connected repositories are listed with their status; a tapped repository still connecting or blocked by a name collision shows its message there, and tapped repositories can be disconnected from the same view. + +## Install applications + +Once a repository is connected, install an application from it with `cozypkg add`, naming the materialized `PackageSource`. A tapped repository keeps its own declared name, so run `cozypkg list` first to see the exact name to use: + +```bash +cozypkg list +cozypkg add acme.hello +``` + +`cozypkg add` installs the `PackageSource` and its dependencies. If a component is privileged, it asks for confirmation first; pass `--allow-privileged` to install privileged components without the interactive prompt. + +Installed applications appear in the dashboard catalog alongside the built-in ones, and platform users deploy them the same way. + +## List what is connected and installed + +`cozypkg list` shows connected `PackageSource` resources; `--installed` shows installed `Package` resources instead, and `--components` breaks components onto separate lines: + +```bash +cozypkg list +cozypkg list --installed +``` + +## Disconnect + +Disconnecting has two independent steps, mirroring the two connect steps. + +Remove installed applications with `cozypkg del`. This deletes the `Package` and its resources but leaves the connected source in place: + +```bash +cozypkg del acme.hello +``` + +Then remove the source itself with `cozypkg untap`. This deletes the tapped `PackageSource` (identified by its marketplace-tap marker, not a name prefix) and its Flux source, and refuses official sources. Already-installed `Package` resources are left untouched, so untap warns if any remain; pass `--yes` to untap anyway: + +```bash +cozypkg untap acme.hello +``` + +From the dashboard, disconnecting a tapped repository in the "Repositories" view removes the `PackageSource` and its Flux source in one step; it does not remove already-installed applications. diff --git a/content/en/docs/next/marketplace/cozypkg.md b/content/en/docs/next/marketplace/cozypkg.md new file mode 100644 index 00000000..d4db158c --- /dev/null +++ b/content/en/docs/next/marketplace/cozypkg.md @@ -0,0 +1,156 @@ +--- +title: "cozypkg Reference" +linkTitle: "cozypkg Reference" +description: "Command and flag reference for the cozypkg marketplace CLI." +weight: 30 +--- + +`cozypkg` is the CLI for authoring, publishing, and managing Cozystack marketplace repositories. This page is a reference for its commands; for task-oriented walkthroughs see [Publishing a Repository]({{% ref "/docs/next/marketplace/publishing" %}}) and [Connecting a Repository]({{% ref "/docs/next/marketplace/connecting" %}}). + +Commands that create or read cluster resources accept `--kubeconfig` and otherwise fall back to `~/.kube/config` or the `KUBECONFIG` environment variable. Creating cluster-scoped resources requires cluster-admin. + +## Environment variables + +- `COZYPKG_INDEX`: default index location for `search` and short-name `tap`. A local directory or an `oci://` reference. Overridden by `--index`. + +## Authoring and publishing + +### `cozypkg init [directory]` + +Scaffold a new repository built around the `PackageSource` model: a `PackageSource` with one variant and a paired app / `-rd` component, ready to validate and push. The generated tree passes `cozypkg validate` as-is. + +| Flag | Description | +| --- | --- | +| `--app