Commit Graph
5128 Commits
Author SHA1 Message Date
Arsolitt 3b1df4db70 refactor(kubernetes): extract cpuToMillicores helper to deduplicate parsing
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:56 +03:00
Arsolitt b4ec25a685 chore(kubernetes): regenerate types and CRD after removing CPU default annotations
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:56 +03:00
Arsolitt 19e6f33ce7 test(kubernetes): update test expectations for changed error messages
Update helm unit test expectations to match the corrected CPU regex hint
text and eviction percentage error message wording.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:56 +03:00
Arsolitt eaaba7a662 docs(kubernetes): update CPU reservation docs to reflect auto-computation
CPU reservations are now auto-computed like memory reservations. Remove
misleading static "100m" defaults from the JSON schema, update field
documentation in values.yaml, and update the README table and capacity
annotation section to cover CPU alongside memory.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt 70ac79d3d3 fix(kubernetes): subtract CPU reservations in capacity annotation
The CPU capacity annotation previously reported raw effective CPU
without subtracting system-reserved and kube-reserved. Now it computes
allocatable CPU (effective minus reservations) to match what the cluster
autoscaler uses for scaling decisions.

Also fix the CPU total validation block to use cozy-lib.resources.toFloat
for consistent millicore parsing.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt 76def543e5 fix(kubernetes): correct eviction percent error messages
The validation allows fractional percentages like 0.5%, but the error
message said "between 1 and 100" which implies only integers are valid.
Changed to "greater than 0 and at most 100" to match actual behavior.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt 19bb71c030 fix(kubernetes): tighten CPU regex to reject fractional millicores
The previous pattern `^[0-9]+(\.[0-9]+)?m?$` accepted invalid values
like "1.5m" (fractional millicores are not valid Kubernetes CPU
quantities). The new pattern requires integer-only millicore notation
or decimal core notation without the `m` suffix.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt a5e361c3dc fix(kubernetes): add zero-value validation for kubelet reservation fields
User-supplied memory and CPU reservation values that parse to zero or
negative are now rejected with a clear error message. The format regex
alone cannot catch semantic invalidity like "0Mi" or "0m".

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt 7fe749e2bb fix(kubernetes): use cozy-lib helper for CPU millicore parsing in auto-compute
The auto-compute block used raw `float64` cast on `$effectiveCpu`, which
breaks when the value is in millicore notation like "4000m". Use the
`cozy-lib.resources.toFloat` helper that already handles the `m` suffix.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt 1702c143db feat(kubernetes): auto-compute kubelet CPU reservations from node capacity
Compute $effectiveCpu alongside $effectiveMemory using the same pattern:
5% of node CPU clamped to [50m, 500m], replacing the hardcoded 100m
default. Adds total CPU validation and a guard for CPU overrides
without known node capacity.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:55 +03:00
Arsolitt c968247dd8 fix(kubernetes): harden kubelet reservation validation and add missing tests
Add eviction percentage validation (non-numeric, out-of-range, zero, negative),
guard against overrides without effective memory, use ceil instead of int for
allocatable annotation, remove dead code in capacity annotation branches, fix
README threshold (5.12 GiB -> 5 GiB), and document capacity annotation semantics.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt 4292401d66 test(kubernetes): update reservation validation tests for expanded regex hints
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt 937a27b39b fix(kubernetes): include eviction threshold in allocatable memory calculation
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt 6639e5c316 fix(kubernetes): accept all valid K8s quantity forms in reservation validation
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt 09517c42ec refactor(kubernetes): collapse reservation validation into range loop
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt 3f7e3b737c refactor(kubernetes): use sprig min/max for kubelet reservation clamp
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:54 +03:00
Arsolitt df8663cd3c test(kubernetes): update instanceType test to expect validation failure
The test previously verified silent fallback to 256Mi when instanceType
lookup returned nil. Now that the template validates instanceType
existence, the test expects a failedTemplate error instead.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt c7c7574d7a test(kubernetes): add eviction-reservation interaction tests and document eviction-minimum-reclaim
Add two test cases verifying that the template correctly renders when
eviction thresholds interact with explicit reservations — both an
aggressive absolute eviction on a small node and a typical production
config with reasonable thresholds.

Also add a brief rationale comment for the hardcoded
eviction-minimum-reclaim value in cluster.yaml.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt a9e224e840 fix(kubernetes): raise kubelet reservation floor clamp from 64Mi to 256Mi
The minimum auto-computed kubelet memory reservation is now 256Mi instead
of 64Mi. This provides a safer default for small nodes where 64Mi is
insufficient for system daemons and kubelet runtime overhead.

The 512Mi node test now expects a validation error since the floor clamp
produces 256Mi+256Mi which equals the node memory. The 4Gi node test
expects 256Mi (clamped from 204Mi) instead of the raw 5% value.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt c6b7f3d6e7 fix(kubernetes): clean up kubelet reservation template and add instanceType fallback test
Remove no-op mulf-by-1.0 in total reserved memory calculation, expand
memory quantity regex to accept base-10 suffixes (k, M, G, T, P, E) in
addition to binary suffixes, and remove hard fail on nil instanceType
lookup so the 64Mi floor fallback works in helm unittest.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt 6eb2a7f078 docs(kubernetes): document hardcoded eviction parameters in kubelet defaults table
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt 1f8ada572c fix(kubernetes): validate absolute eviction format and guard against memory over-reservation
Add regex format validation for absolute eviction threshold values before
they reach toFloat conversion, preventing silent zero returns on invalid
input like "banana". Add a check that systemReservedMemory + kubeReservedMemory
does not exceed effective node memory. Include helm unit tests for both
validations.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt d21307a18b docs(kubernetes): fix version range and document kubelet auto-computation
Update the supported Kubernetes version range from 1.28-1.33 to
1.30-1.35 to match the actual values.schema.json enum. Add a new
"Kubelet Resource Reservations" section explaining the auto-computation
formula (5% of effective memory, clamped to [64Mi, 1Gi]), default
values for all kubelet parameters, and a configuration example.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:53 +03:00
Arsolitt b21dedad64 fix(kubernetes): validate reservation formats and reject mixed eviction types
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt fe48c726c8 fix(kubernetes): add absolute eviction threshold validation and remove unrelated changes
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt c2fb855f0e fix(kubernetes): make kubelet field optional and fix description consistency
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt 656792033f test(kubernetes): add helm unit tests for kubelet reservation
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt 546c167041 fix(kubernetes): fix kubelet reservation bugs and add eviction validation
Fix empty instanceType dict truthiness check to prevent nil pointer errors
when instanceType is not set. Add validation that evictionHardMemory is
strictly less than evictionSoftMemory. Fix evictionHardMemory default
from 10% to 7% and add missing evictionSoftMemory field. Remove kubelet
from required array in schema for backwards compatibility.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt a2ba939d49 fix(kubernetes): use pods-only enforce-node-allocatable
Enforcing system-reserved and kube-reserved cgroups requires
pre-created cgroup slices that may not exist in the VM image,
causing kubelet to fail on startup.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:52 +03:00
Arsolitt 63633987e3 feat(kubernetes): make eviction-soft threshold configurable
Add evictionSoftMemory field to kubelet configuration with default 10%.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:51 +03:00
IvanHunters 079ec7c1f5 fix(kubernetes): add kubelet reserved resources and cgroup enforcement
Configure kubelet with proper resource reservations and cgroup enforcement
to prevent OOM kills when memory pressure occurs.

Configuration:
- systemReserved: 100m CPU, 512Mi memory (OS daemons)
- kubeReserved: 100m CPU, 512Mi memory (kubelet, containerd)
- evictionHard: 512Mi threshold (immediate eviction)
- evictionSoft: 1Gi threshold with 90s grace period
- evictionMinimumReclaim: 256Mi (guaranteed reclaim after eviction)
- enforce-node-allocatable: creates hard cgroup limits for reservations
- cgroups-per-qos: enables QoS-based resource isolation
- cgroup-driver: systemd (matches containerd configuration)
- kernel-memcg-notification: faster memory pressure detection

Allocatable calculation for 16Gi VM:
  VM capacity:           16.00 Gi
  - systemReserved:      -0.50 Gi (enforced via cgroup)
  - kubeReserved:        -0.50 Gi (enforced via cgroup)
  - evictionHard buffer: -0.50 Gi
  - kernel/page cache:   -0.25 Gi (implicit)
  ----------------------------------------
  Allocatable (safe):    14.25 Gi

Key improvement: enforce-node-allocatable creates hard cgroup limits,
preventing system/kubelet processes from exceeding reservations and
killing kubelet via OOM.

Related issue: tenant VMs experiencing kubelet crashes after 15-30min
due to insufficient reserved memory (100Mi vs required 1.75Gi total)
and lack of cgroup enforcement.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
2026-04-23 17:02:51 +03:00
Arsolitt c39249233c fix(kubernetes): adjust kubelet reservation defaults
Lower minimum memory reservation clamp from 256Mi to 64Mi to support
smaller instance types. Reduce eviction threshold from 10% to 7%.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:51 +03:00
Arsolitt cbc23a3f3b fix(kubernetes): make kubelet reservation fields optional
Mark all Kubelet struct fields optional in values.yaml so existing
Kubernetes CRs without a kubelet block still pass schema validation
while defaults are injected via the template.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:51 +03:00
Arsolitt 6c11ecd51a feat(kubernetes): add dynamic kubelet memory reservations for worker nodes
Kubelet on worker VMs used to join with empty kubeletExtraArgs, so
allocatable memory equaled guest memory and the OS plus kubelet had
no reservation. Under pressure, Linux OOM killer could terminate
kubelet, taking the node NotReady before graceful pod eviction.

Introduce per-group kubelet reservations with sane defaults:
- system-reserved and kube-reserved memory auto-computed as 5% of
  effective guest memory, clamped to [256Mi, 1Gi]
- CPU reserved 100m for each
- eviction-hard memory.available<10% (scales with VM size)

Effective memory is taken from group.resources.memory when set,
otherwise resolved from instanceType via the existing Helm lookup
already used for capacity annotations. Users can override any field
per node group via nodeGroups[*].kubelet.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 17:02:51 +03:00
Aleksei Sviridkin a78505e932 chore(cilium): refresh image digest for v1.19.3
Built ghcr.io/cozystack/cozystack/cilium from the refreshed upstream
v1.19.3 base image and updated values.yaml with the new digest.

Previously values.yaml still pointed at the v1.19.1 cozystack rebuild
by digest while Chart.yaml and the Dockerfile were on v1.19.3 — with
chart default useDigest=true that would have silently pulled v1.19.1
until the next release-tag rebuild.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 17:01:45 +03:00
Aleksei Sviridkin 0e4b66a70f chore(cilium): bump to v1.19.3
Vendored chart refreshed via make update in packages/system/cilium.

Motivation: v1.19.2 fixes a cert-manager HTTP-01 bug on hostnames with
both HTTP and HTTPS listeners (cilium#44492, backport PR #44517). This
is a prerequisite for upcoming Gateway API work.

v1.19.3 is the latest stable release in the v1.19.x line (15 Apr 2026).

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 17:01:45 +03:00
Aleksei Sviridkin ecd2ead5de docs(agents): document make generate requirement before committing
Pre-commit CI runs make generate in every package and fails with exit
123 on any uncommitted generator output. Add explicit guidance so
agents stage regenerated README.md, values.schema.json and
packages/system/<name>-rd artifacts alongside the hand edits.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 15:55:49 +03:00
Kirill Ilin 0baa93006f chore(hetzner-robotlb): update robotlb chart to appVersion 0.0.6
Pulls the latest robotlb chart (0.1.3) which ships robotlb 0.0.6.
The new appVersion adds RBAC permissions for discovery.k8s.io/endpointslices
needed to support EndpointSlice-based services such as KubeVirt.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-04-23 16:57:23 +05:00
myasnikovdaniil 24d48bd075 fix(ci): harden changelog generation in tags.yaml (v1.3.0 regression) (#2460)
## What this PR does

Fixes the failures that blocked the v1.3.0 release pipeline (workflow
run [24765377017]) and closes the gap in `docs/agents/changelog.md` that
made them possible.

### Bug 1 — pathspec error in `Create changelog branch and commit`

After the Copilot step, the workflow runs `git checkout -b
"$CHANGELOG_BRANCH" origin/main`. Copilot CLI was invoked with
`--allow-all-tools` and had committed the generated changelog onto HEAD
of `main`, so the reset to `origin/main` deleted the tracked file, and
`git add "$CHANGELOG_FILE"` then failed with `fatal: pathspec ... did
not match any files`.

Fix (commit 2):

- Snapshot the file across the branch switch so the checkout cannot drop
it.
- `set -euo pipefail` so any failure surfaces loudly.
- Drop the dead "no changes to commit" soft-branch — the earlier
`check_changelog` step gates this step on the file being absent from
`origin/main`, so `git commit` must produce a diff; if it doesn't (e.g.
empty file), fail loud instead of pushing an empty branch.
- Fail-early file-existence check with `::error::` annotation, and
`VERSION` moved to step `env:`.

### Bug 2 — no timeout on `Generate changelog using AI`

The re-run hung in Copilot for 10+ minutes with zero log output. With no
`timeout-minutes`, a hung Copilot would hold a self-hosted runner for 6
hours (job default).

Fix (commit 2): `timeout-minutes: 30` (the prior successful run took ~26
minutes).

### Root-cause fix — scope the agent prompt

`docs/agents/changelog.md` is the actual prompt driving Copilot. It
ended with "Save the changelog" and gave no boundary, so an agent with
`--allow-all-tools` could reasonably interpret "done" as "commit, push,
open a PR".

Fix (commit 1):

- Add a "Scope and boundaries" section at the top stating the single
deliverable is `docs/changelogs/v<version>.md` and enumerating forbidden
operations (git commit / push / branch / tag / reset / merge / rebase,
PR creation, GitHub API writes, modifying any file other than the
changelog).
- Add an explicit "then exit" at the end of Step 9 with a back-reference
to the scope section.
- Scoped "unless the caller explicitly instructs otherwise" so
interactive IDE use stays flexible.

With the rules in the doc, CI and interactive callers share the same
boundary, and the workflow prompt becomes a one-line invocation
(`--prompt "Generate the release changelog for tag v${VERSION}. Follow
the instructions in @docs/agents/changelog.md exactly, including the
'Scope and boundaries' section at the top. ..."`).

### Files touched

- `docs/agents/changelog.md` — +16 / -0 (scope section + exit rule)
- `.github/workflows/tags.yaml` — +36 / -31 (timeout + rewritten commit
step + simplified prompt)

Other jobs in the workflow (`prepare-release`, `update-website-docs`)
are untouched.

### Release note

```release-note
NONE
```

[24765377017]:
https://github.com/cozystack/cozystack/actions/runs/24765377017

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

* **Chores**
* Improved release automation reliability with stricter verification,
enforced error handling, and a timeout for changelog generation
* Ensured automated commits/pushes occur only after successful output
validation to prevent accidental repository mutations

* **Documentation**
* Clarified agent instructions to produce a single changelog file and
terminate, and to restrict the agent to read-only inspection during
generation
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 16:45:16 +05:00
Myasnikov Daniil 9222b6feda ci(api): pre-fetch k8s.io/code-generator in codegen drift job
hack/update-codegen.sh sources kube_codegen.sh from the Go module
cache at ~/go/pkg/mod/k8s.io/code-generator@vX.Y.Z/, but the module
is not declared in go.mod so a fresh runner has nothing to source
from. Add a workflow step that parses the pinned version out of the
script and pulls the module into the cache before running
make generate.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 14:32:20 +05:00
myasnikovdaniil a92dc769a1 docs(changelog): correct v1.3.0 postgres and linstor-gui entries (#2458)
## What this PR does

Post-release cleanup of `docs/changelogs/v1.3.0.md` so the notes match
what users actually experience in v1.3.0. No code changes.

- **Rewrite the postgres major-features entry** so author
(`@myasnikovdaniil`), PR (`#2369`), and description all line up with the
`17.7-standard-trixie` pin + migration-37 `imageName` rewrite that
actually shipped. The previous entry credited `#2304` with a description
matching a superseded `spec.version=v17` backfill approach.
- **Remove the duplicate `#2364` postgres bug-fix entry** — the same
work is now folded into the single major-features entry above, with
backport references to `#2309` (v1.2.1) and `#2364` (v1.2.2).
- **Remove the `[linstor-gui] Restrict to cozystack-cluster-admin group`
security entry.** The vulnerable state never shipped in a tagged
release, so there is nothing user-facing to announce. The
`cozystack-cluster-admin`-group restriction is already described in the
linstor-gui Feature Highlights section as part of the feature's day-one
shipping behavior.

### Release note

```release-note
[]
```

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

## Summary by CodeRabbit

* **Documentation**
* Updated v1.3.0 changelog with clarified PostgreSQL system version
pinning details and removed redundant entries for improved documentation
clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 14:09:36 +05:00
Myasnikov Daniil c1508940bd fix(etcd): remove destructive post-upgrade cert-regeneration hook
The etcd chart shipped a `post-upgrade` Helm hook that `kubectl delete`d the
etcd TLS chain (`etcd-{ca,peer-ca,client,peer,server}-tls`) and then deleted
etcd pods on every chart upgrade, gated by a semver compare of an
`etcd-deployed-version` ConfigMap against `2.6.1`.

The hook was added as a one-shot migration for the chart `2.6.0 -> 2.6.1`
transition. Since commit f871fbdb ("Remove versions_map logic") all chart
versions are stamped as `0.0.0+<git-hash>`, which per semver is always
`< 2.6.1`. The gate therefore always resolves to "update certs", firing the
destructive hook on every etcd upgrade. On clusters running Kamaji-managed
tenant control planes this wipes the etcd CA, cert-manager re-issues it, and
tenant kube-apiservers hit `x509: certificate signed by unknown authority`
against `etcd.<ns>.svc:2379` until each tenant DataStore is manually
re-reconciled.

Commit 47d81f70 ("Disabled private key rotation in CA certs") already fixed
the underlying `rotationPolicy: Always` issue the migration was papering
over, so the hook has no remaining use. Remove the hook Job, its RBAC, the
version ConfigMap it read, and add a helm-unittest suite under
`packages/extra/etcd/tests/` that guards against re-introducing the hook
or the version ConfigMap.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 13:34:51 +05:00
Myasnikov Daniil 76c4eabdff fix(ci): use a read-only app token for the Copilot step
Review feedback on PR #2460: the Generate changelog using AI step ran
Copilot with --allow-all-tools and GH_TOKEN set to the write-capable
installation token issued to the job (contents: write,
pull-requests: write on all cozystack/* repos). The scope rules in
docs/agents/changelog.md and the step prompt tell the agent not to
use those permissions, but nothing at the token layer prevented it.

Mint a second, read-only installation token from the same app
(same COZYSTACK_CI_APP_ID / COZYSTACK_CI_PRIVATE_KEY, scoped to
contents/pull-requests/metadata read) and pass that one to the AI
step instead. The write-capable token is still used by the checkout,
commit/push, and PR-creation steps that actually need it.

This is defense in depth: even if a future prompt change or agent
misbehavior ignored the scope rules, the token itself has no write
capability on any repository in the cozystack org. No new secret,
no new GitHub App install, no admin-side change — the RO token is
minted in the same workflow from the same app credentials.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 12:26:14 +05:00
Myasnikov Daniil e7e83b0d0b fix(ci): reject empty changelog file before commit
Review feedback on PR #2460: the existing `[ -f ]` check catches
missing files but a zero-byte `docs/changelogs/v${VERSION}.md` would
still be staged and committed — `git add` + `git commit -s` on a new
empty file succeeds and produces a real commit, leaving the
downstream PR with no actual changelog content.

Add a `[ -s ]` guard after the existence check: if the Generate
changelog using AI step produces an empty file, emit a matching
`::error::` annotation and exit 1 before snapshotting.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 12:25:30 +05:00
Myasnikov Daniil 3c95f30521 docs(agents): scope git-write ban to cozystack working tree
Review feedback on PR #2460: the previous "do not write to refs, HEAD,
or remotes" wording contradicted the explicit allowance of `git fetch`
(which updates remote-tracking refs) and the mandatory cross-repo
checks in Step 6, which `cd` into `_repos/<repo>` and run
`git checkout`, `git pull`, etc.

Sharpen the scope paragraph:

- The git-write ban is now explicitly scoped to the cozystack working
  tree — it bans writing to local branches, tags, or HEAD in that
  repo, not "refs/HEAD/remotes" globally.
- `git fetch` is called out as expected.
- Local git operations inside disposable `_repos/` clones
  (`git checkout`, `git pull`, etc.) are explicitly allowed, with
  the remaining rules (no push, no PR creation, no API writes)
  applying to any repository.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 12:25:19 +05:00
myasnikovdaniil f505c4da75 fix(backups): move velero-configmap Role to velero chart (#2459)
## What this PR does

The `backupstrategy-controller` chart declared a `Role` and
`RoleBinding` scoped to the `cozy-velero` namespace (for managing
`ResourceModifier` ConfigMaps consumed by Velero Restore). Because
`cozystack.velero` is an optional package, that namespace does not exist
in bundles that do not enable velero — and `backupstrategy-controller`
is a **default** package. Helm install aborted with:

```
namespaces "cozy-velero" not found
```

which blocked the entire
`cozy-backup-controller/backupstrategy-controller` HelmRelease on any
cluster where velero was not explicitly enabled (including the E2E
environment).

This PR moves that Role/RoleBinding into the velero chart
(`packages/system/velero/templates/backupstrategy-controller-rbac.yaml`),
so the permission grant only exists when velero is actually installed —
where it is useful. The RoleBinding subject points to the stable
`backupstrategy-controller` ServiceAccount in `cozy-backup-controller`.

### Release note

```release-note
fix(backups): moved the velero-namespaced ResourceModifier ConfigMap Role and RoleBinding from the backupstrategy-controller chart into the velero chart. This unblocks installs of backupstrategy-controller on bundles that do not enable velero (previously the HelmRelease failed with `namespaces "cozy-velero" not found`).
```

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

## Summary by CodeRabbit

* **Chores**
* Reorganized RBAC configuration for the backup strategy controller by
consolidating namespace-scoped role definitions in the Velero chart
template
* Updated role bindings and permissions structure across system packages

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 11:57:54 +05:00
Myasnikov Daniil c4477259c7 fix(backups): move velero-configmap Role to velero chart
The backupstrategy-controller chart declared a Role/RoleBinding in the
cozy-velero namespace for ResourceModifier ConfigMap management. Because
velero is an optional package, that namespace does not exist in bundles
without velero, so Helm install aborted with "namespaces \"cozy-velero\"
not found" and blocked the default install of backupstrategy-controller.

Move the Role and RoleBinding into the velero chart so they are created
only when velero is actually installed. The RoleBinding subject points
to the backupstrategy-controller ServiceAccount in its fixed namespace
(cozy-backup-controller).

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 10:41:41 +05:00
Myasnikov Daniil 3720f0f3f2 fix(ci): harden tags.yaml changelog job against agent misbehavior
Three changes to the generate-changelog job to fix the v1.3.0
release pipeline failure (run 24765377017) and make the job robust
to whatever state the Copilot step leaves behind.

1. Add `timeout-minutes: 30` to the Generate changelog using AI
   step. On the v1.3.0 re-run the step hung silently for 10+
   minutes; with no timeout a hung Copilot would hold a self-hosted
   runner for up to 6 hours (job default). The previous successful
   run took ~26 minutes, so 30 is a reasonable ceiling.

2. Replace the terse, ambiguous Copilot prompt with a one-liner
   that invokes docs/agents/changelog.md directly. The "Scope and
   boundaries" section added to that doc in the previous commit is
   now the single source of truth for what the agent may and may
   not do, so the workflow only needs to pass the version and
   point at the relevant doc. VERSION is moved to step env: to
   match GitHub's workflow-injection hardening guidance.

3. Rewrite the Create changelog branch and commit step:
   - add `set -euo pipefail` so any failure is visible
   - validate the file exists up front and fail loud with
     `::error::` if not
   - copy the file to a tempfile BEFORE `git checkout -b`, so the
     checkout to `origin/main` cannot remove it (this is the fix
     for the original pathspec error the v1.3.0 run hit)
   - use `trap` to clean up the tempfile on any exit path
   - move VERSION to env
   - drop the dead "no changes to commit" branch: the check_changelog
     step earlier in the job gates this step on the file being
     absent from origin/main, so `git add` + `git commit` must
     produce a diff. If they don't (e.g. Copilot emitted an empty
     file), fail loud instead of pushing an empty branch.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 10:33:12 +05:00
Myasnikov Daniil e1c6f9c029 docs(agents): scope changelog.md to a file-only deliverable
The v1.3.0 release pipeline broke because Copilot, invoked by
.github/workflows/tags.yaml with --allow-all-tools, committed the
generated changelog onto HEAD of main on its own. The workflow's
next step — `git checkout -b ... origin/main` — then wiped the file,
and `git add` failed with a pathspec error.

The root cause is in this document. The checklist ends with "Save
the changelog", which an agent with broad tool access can reasonably
interpret as "also commit it, push it, and open a PR". There was no
explicit boundary.

Add a "Scope and boundaries" section at the top and an explicit
"then exit" at the end of Step 9:

- The single deliverable is docs/changelogs/v<version>.md.
- Forbidden by default: git commit / push / checkout (to switch
  branches) / branch / tag / reset / merge / rebase; PR creation;
  GitHub API writes (POST/PATCH/DELETE); modifying any file other
  than the changelog.
- Read-only analysis (git log/show/fetch/diff, gh pr view, gh api
  GET) remains expected.
- Auxiliary repo clones under _repos/ remain allowed for cross-repo
  analysis per Step 6.
- Scoped "unless the caller explicitly instructs otherwise" so
  interactive use with an IDE remains flexible.

With the rules in the doc, CI and interactive callers share the
same boundary; the workflow can invoke the doc with a one-line
prompt instead of re-stating the constraints every time.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 10:22:09 +05:00
Myasnikov Daniil 44bc79cef1 docs(changelog): correct v1.3.0 postgres and linstor-gui entries
Post-release cleanup of docs/changelogs/v1.3.0.md so the notes match
what users actually experience in the released v1.3.0:

- Rewrite the postgres major-features entry so author (myasnikovdaniil),
  PR (#2369), and description all match the 17.7-standard-trixie pin +
  migration-37 imageName rewrite that actually shipped. The previous
  entry credited #2304 (superseded spec.version=v17 backfill approach).
- Remove the duplicate #2364 postgres bug-fix entry; the same work is
  now folded into the single major-features entry above, with backport
  references to #2309 (v1.2.1) and #2364 (v1.2.2).
- Remove the [linstor-gui] Restrict to cozystack-cluster-admin group
  security entry. The vulnerable state never shipped in a tagged
  release, so there is nothing user-facing to announce; the restriction
  is already described in the linstor-gui Feature Highlights section
  as part of the feature's day-one behavior.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 10:17:30 +05:00