Skip to main content

timoni

Use when deploying applications to Kubernetes with Timoni. Covers installing and upgrading module instances from OCI registries, composing multi-app deployments with bundles, injecting values from clusters or CI with runtimes, targeting multiple clusters, and authoring, testing, signing and publishing modules with CUE.

Ir para a instalação

Informações da origem

Repositório
stefanprodan/timoni
Última atividade na origem
30 de agosto de 2026 às 22:08
Idioma detectado do SKILL.md
inglês
Estrelas
2.015
Forks
88

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
timoni
description
Use when deploying applications to Kubernetes with Timoni. Covers installing and upgrading module instances from OCI registries, composing multi-app deployments with bundles, injecting values from clusters or CI with runtimes, targeting multiple clusters, and authoring, testing, signing and publishing modules with CUE.
license
Apache-2.0
metadata
{"author":"Stefan Prodan","homepage":"https://timoni.sh","source":"https://github.com/stefanprodan/timoni","version":"0.3.0"}
# Timoni Timoni is a package manager for Kubernetes powered by CUE and inspired by Helm. An app is packaged as a **module** (CUE templates plus a typed config schema) and distributed as an OCI artifact next to the app container images. A module deployed to a cluster is an **instance**. A **bundle** declares a set of instances deployed together, and a **runtime** declares the target clusters and the values read from them at apply time. Helm mapping: chart = module, umbrella chart = bundle, release = instance. Full documentation index: https://timoni.sh/llms.txt ## When to use - Install, upgrade, diff or uninstall an app on Kubernetes from an OCI module. - Deploy several apps as one unit with a `bundle.cue` file. - Vary a bundle per environment or cluster, reading values from Secrets, ConfigMaps, custom resources or CI environment variables. - Deploy the same bundle to a fleet of clusters in one command. - Author a module: define the config schema, template Kubernetes objects, vendor CRD schemas, add test jobs and health checks, sign and publish it. Do not manage resources owned by a Timoni instance with `helm`, `kustomize` or `kubectl apply`. Timoni owns them through server-side apply and prunes what is no longer rendered. With Flux, Timoni is a templating engine only (`timoni build` / `bundle build` output pushed as manifests): lifecycle management, runtime value injection, bundling and multi-cluster delivery do not apply once Flux takes over. ## Quick reference Every CLI command supports `--help` and prints usage examples along with the available flags. Run `timoni <command> --help` for details beyond the tables below. ### Instances | Task | Command | |------|---------| | Install or upgrade | `timoni -n <ns> apply <name> oci://<repo> -v <version> -f values.cue` | | Preview as a server-side diff | `timoni -n <ns> apply <name> oci://<repo> -v <version> --diff` | | Recreate objects with immutable-field changes | `... apply ... --force` | | Take over an instance owned by a bundle | `... apply ... --overwrite-ownership` | | Uninstall | `timoni -n <ns> delete <name>` | | List instances | `timoni list -A` | | Status and readiness | `timoni -n <ns> status <name>` | | Show module or managed resources | `timoni -n <ns> inspect module\|resources <name>` | | Show stored values | `timoni -n <ns> inspect values <name>` | | Render manifests, no cluster needed | `timoni build <name> oci://<repo> -v <version> -f values.cue [--mask-secrets]` | ### Bundles and runtimes | Task | Command | |------|---------| | Validate | `timoni bundle vet -f bundle.cue` | | Validate without a cluster | `timoni bundle vet -f bundle.cue -r runtime.cue --offline` | | Validate and print the computed bundle | `timoni bundle vet -f bundle.cue --print-value` | | Preview | `timoni bundle apply -f bundle.cue --diff` | | Apply | `timoni bundle apply -f bundle.cue [-f bundle_secrets.cue]` | | Render to files | `timoni bundle build -f bundle.cue --output-dir ./manifests` | | Render to stdout without Secret values | `timoni bundle build -f bundle.cue --mask-secrets` | | Status | `timoni bundle status -f bundle.cue` or `timoni bundle status <name>` | | Delete | `timoni bundle delete -f bundle.cue` or `timoni bundle delete <name>` | | Update module versions per policy | `timoni bundle update -f bundle.cue [--level patch\|minor\|major]` | | Preview module updates | `timoni bundle update -f bundle.cue --dry-run` (prints `old -> new` per instance, writes nothing) | | With a runtime | add `-r runtime.cue`; select with `--runtime-cluster <name>` / `--runtime-group <group>` | | Runtime values from CI env vars | add `--runtime-from-env` | | Print resolved runtime values | `timoni runtime build -f runtime.cue [--cluster <name>] [--cluster-group <group>]` | ### Modules and registries | Task | Command | |------|---------| | Log in to a registry | `echo $TOKEN \| timoni registry login ghcr.io -u <user> --password-stdin` | | List published versions | `timoni mod list oci://<repo>` (newest 100; `--limit 0` for all, `--with-digest=false` to skip digests) | | Pull a module to disk | `timoni mod pull oci://<repo> -v <version> -o ./module` | | Show the README | `timoni mod show readme oci://<repo> -v <version>` (or a local `./module` path) | | Show the config schema | `timoni mod show config oci://<repo> -v <version>` (or a local `./module` path) | | Verify signature on pull | `... mod pull ... --verify=cosign --cosign-key=cosign.pub`, or keyless: `--verify=cosign --certificate-identity-regexp=<re> --certificate-oidc-issuer=<url>` | | Create a module | `timoni mod init <name> --blueprint oci://ghcr.io/stefanprodan/timoni/blueprints/starter` | | Validate a module | `timoni mod vet [path] [--debug]` | | Vendor Kubernetes schemas | `timoni mod vendor k8s [-v 1.30]` | | Vendor CRD schemas | `timoni mod vendor crd -f <crds.yaml or URL> [--kind Kind,Kind.group] [-v v1] [--prune]` (`--list` prints the kinds and versions without vendoring) | | Publish | `timoni mod push ./module oci://<repo> -v <semver> [--latest=false] [--sign=cosign [--cosign-key=cosign.key]]` | | Build an OCI archive without a registry | `timoni mod build ./module -v <semver> -o module.oci.tar` | | Generic artifacts | `timoni artifact push oci://<repo> -t <tag> -f ./dir`, `timoni artifact pull oci://<repo>:<tag>`, `timoni artifact build -f ./dir -t <tag> -o out.oci.tar` | | Format CUE | `timoni fmt` | Global flags: `-n/--namespace`, `--kube-context`, `--kubeconfig`, `--timeout`. Registry commands read `~/.docker/config.json`; `--creds user:token` is a per-command flag that exposes the token in shell history and process lists, so prefer `timoni registry login --password-stdin`. ## Values Values are supplied with `-f/--values` as CUE, YAML or JSON files, merged in order, or from stdin with `-f -`. A CUE values file wraps everything in `values:`: ```cue values: { replicas: 2 image: tag: "1.27-alpine" resources: limits: memory: "128Mi" } ``` Values are validated against the module's `#Config`; a type or constraint mismatch fails the build before anything reaches the cluster. To discover the available values, run `timoni mod show config oci://<repo> -v <version>` (or `timoni mod show config ./module` for a local module). ## Bundles ```cue bundle: { apiVersion: "v1alpha1" name: "podinfo" instances: { redis: { module: { url: "oci://ghcr.io/stefanprodan/modules/redis" version: "8.10.1" @timoni(update:semver:8.x) } namespace: "podinfo" values: maxmemory: 256 } podinfo: { module: { url: "oci://ghcr.io/stefanprodan/modules/podinfo" version: "6.14.0" @timoni(update:semver:6.x) } namespace: "podinfo" values: caching: { enabled: true redisURL: "tcp://redis:6379" } } } } ``` - Before adding an instance, read the module docs first: `timoni mod show readme oci://<repo> -v <version>`, then `timoni mod show config oci://<repo> -v <version>` for the full `#Config` schema the `values:` are validated against. - Editing loop: `timoni fmt bundle.cue` formats the file, `timoni bundle vet -f bundle.cue` validates the definition without a cluster (add `--print-value` to inspect the computed bundle), `timoni bundle build -f bundle.cue` renders the manifests offline, and `timoni bundle apply -f bundle.cue --diff` previews the changes against the cluster before applying (exits 1 on drift, 2 on failure). - Instances are applied in declaration order, each waiting for readiness before the next (`--wait=false` disables waiting). Deletion runs in reverse order. - `module.version` defaults to `latest`. A semver tag can be overwritten unless the registry enforces tag immutability; pin `module.digest` when you need deterministic retrieval. - Local modules in a bundle use `module: url: "file://../modules/app"`, relative to the bundle file, or an absolute path as `file:///abs/path/to/module`; `version`/`digest` are ignored and the instance gets version `0.0.0-devel`. - Split a bundle across files and merge with repeated `-f` (for example a `bundle_secrets.cue` kept out of git or piped from stdin with `-f -`). SOPS-encrypted YAML/JSON partials: `sops exec-file --filename secrets.yaml bundle.secrets.yaml 'timoni bundle apply -f bundle.cue -f {}'`. - Instances applied by a bundle are owned by it. `timoni apply` on such an instance, or another bundle claiming it, fails unless `--overwrite-ownership` is passed. - Bundles can import CUE packages from `cue.mod` in the working directory (`--workdir` selects the CUE module root). - `timoni bundle update -f bundle.cue` rewrites the module versions and digests according to the `@timoni(update:semver:<constraint>|digest|none)` attribute on the `version` field; `--level patch|minor|major` updates the references without an attribute, and `--dry-run` only prints the changes. Run `timoni bundle vet` and `timoni bundle build` afterwards, the update does not validate the values against the new module schema. ## Runtimes and multi-cluster A runtime declares clusters and values to read from them: ```cue runtime: { apiVersion: "v1alpha1" name: "fleet" clusters: { "staging": {group: "staging", kubeContext: "eks-staging"} "prod-eu": {group: "production", kubeContext: "eks-prod-eu"} "prod-us": {group: "production", kubeContext: "eks-prod-us"} } values: [ { query: "k8s:v1:Secret:infra:redis-auth" for: {"REDIS_PASS": "obj.data.password"} }, { query: "k8s:v1:ConfigMap:infra:aws-info" for: {"REGION": "obj.data.region"} optional: true }, ] } ``` Bind runtime values in a bundle with `@timoni(runtime:<string|number|bool>:<VAR>)`; a concrete value next to the attribute is the default when the variable is absent: ```cue bundle: { _pass: string @timoni(runtime:string:REDIS_PASS) _region: "eu-west-1" @timoni(runtime:string:REGION) _env: string @timoni(runtime:string:TIMONI_CLUSTER_GROUP) ... } ``` With `--runtime-from-env`, accepted by every `timoni bundle` subcommand, the variables come from the process environment instead of a cluster; no `-r` runtime file is needed: ```shell REDIS_PASS=$SECRET timoni bundle apply -f bundle.cue --runtime-from-env ``` - With `-r runtime.cue`, `bundle apply|vet|status|delete` iterate over the selected clusters, switching kube-context per cluster. `bundle build` requires exactly one selected cluster (`--runtime-cluster`). - `TIMONI_CLUSTER_NAME` and `TIMONI_CLUSTER_GROUP` are set for clusters declared in a runtime, not for the implicit current-context default. - Value precedence: cluster identity values override cluster query results, which override `--runtime-from-env` values. Secret `data` is base64-decoded. - `optional: true` only tolerates the queried object being absent. A missing variable bound to a field without a default still fails with an incomplete value error. - `bundle build -r` reads runtime queries from the selected cluster; only bundles without cluster queries build offline. ## Apply semantics `timoni apply` and `bundle apply`, per instance: 1. Pull the module, merge values, build and validate the objects. 2. Create the namespace if missing. 3. Record the intended inventory (install) or a pending revision (upgrade) in Secret `timoni.<instance>`. 4. Server-side apply the `timoni: apply:` sets one after another, in declaration order (for example CRDs before workloads, tests last), waiting for readiness after each set (kstatus plus module-declared health checks). 5. Prune objects from the previous inventory that are no longer rendered. 6. Commit the final inventory. Applying over objects created by `kubectl apply` or `helm install` takes ownership: field ownership moves to Timoni and the `kubectl.kubernetes.io/last-applied-configuration` and `meta.helm.sh/*` annotations are removed. This is the supported Helm migration path; make sure a name collision is intentional before applying. Per-object behavior is set with annotations in the module templates: | Annotation | Effect | |------------|--------| | `action.timoni.sh/force: "enabled"` | Recreate the object when its immutable fields change (`--force` does this for all objects) | | `action.timoni.sh/one-off: "enabled"` | Apply only if the object does not exist | | `action.timoni.sh/prune: "disabled"` | Never garbage-collect the object, also survives `delete` | | `action.timoni.sh/wait: "disabled"` | Skip readiness waiting for the object | `timoni delete` and `bundle delete` remove the inventory objects (except `prune: disabled` ones) and wait for finalizers; namespaces are left in place. ## Module authoring Typical layout produced by the starter blueprint (a convention, not a contract): ``` myapp/ ├── cue.mod/ │ ├── gen/ # vendored Kubernetes API and CRD schemas │ ├── pkg/ # timoni.sh/core/v1alpha1 schemas │ └── module.cue # module: "timoni.sh/myapp" ├── templates/ │ ├── config.cue # #Config schema with defaults, #Instance │ ├── deployment.cue # #Deployment: {#config: #Config, ...} │ └── service.cue ├── images.cue # container images defaults (repository, tag, digest) ├── timoni.cue # entry point: values, timoni.instance, timoni.apply ├── timoni.ignore # files excluded from mod push ├── values.cue # placeholder for user values ├── README.md └── LICENSE ``` - `#Config` holds defaults (`*value | type`) and constraints (`int & >0`);
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub