Repository navigation
fix(apps): keep Job and CronJob names within the Kubernetes limits - #4945
Conversation
The apps API admits release names of up to 53 characters, and several charts name a Job <release>-<suffix>. Kubernetes copies a Job name into the job-name label of its pods, and a label value takes at most 63 characters, so the apiserver refused these Jobs for the longest names. A Kafka whose name has 42 to 44 characters could not be installed, a VMDisk of 37 or more could not grow, a VMInstance of 40 or 41 could not take an instance type, profile or external change, and a Bucket of 44 or more or a Qdrant of 42 or more failed its post-delete hook. Those Job names, and the pod label vm-instance copies from one, are now cut to 63 characters. A release name is never longer than 53, so only the fixed suffix is cut and two releases still get two Jobs. A CronJob name is refused over 52 characters, because the controller names each Job it starts <cronjob>-<timestamp>. With the backup CronJob on, a MariaDB whose name has 38 characters or more and a ClickHouse of 35 or more failed the whole release. A cut there reaches into the release name and could give two releases one CronJob, so a name that does not fit becomes the release name cut to 38 characters, a hash of the full release name and -backup, the way the ClickHouse Keeper name is already shortened. The tenant cleanup Job is named after the tenant namespace, which a nested tenant can fill to 63 characters by itself. The Job runs in cozy-system next to that of every other tenant, where a plain cut could give a parent and its child one name and let the child's before-hook-creation delete the parent's Job while it runs, so it is shortened with a hash of the namespace the same way. Names that fit render exactly as before, and a name that did not fit never produced an object, so nothing is renamed on upgrade. The hook ServiceAccounts, Roles and RoleBindings have no such limit and keep their names. Assisted-by: LLM Signed-off-by: Yan Bondarenko <[email protected]>
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes.
|
| Layer / File(s) | Summary |
|---|---|
63-character hook Job names packages/apps/bucket/..., packages/apps/kafka/..., packages/apps/qdrant/..., packages/apps/vm-disk/..., packages/apps/vm-instance/... |
Hook and cleanup Job names are limited to 63 characters and have a trailing hyphen removed. The VM update hook uses the computed name for the Job and its pod app label. Tests cover short, boundary, and longer names, plus related resource names that retain their full names. |
Hashed backup CronJob names packages/apps/clickhouse/..., packages/apps/mariadb/... |
Backup CronJob names retain the <release>-backup form within the 52-character limit. Longer names use a trimmed release prefix, a six-character hash of the full release name, and the -backup suffix. Tests cover boundaries, hash differences, and dash trimming. |
Tenant cleanup Job name packages/apps/tenant/templates/cleanup-job.yaml, packages/apps/tenant/tests/job_name_budget_test.yaml |
The cleanup Job uses its computed name for both the Job and pod template. Names over 63 characters use a trimmed tenant prefix, a six-character hash, and the cleanup suffix. Tests also check parent-child names and full namespace and release names in RBAC resources. |
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Bug fix
Merge Risk: 
Minimal · previous review a2c9c
-
This change shortens over-long Job and CronJob names so they can be created, and names that already fit are unchanged. No merge-blocking risk was found.
Pre-merge checks: 
5
-
Full details: Docstring Coverage
-
Explanation
No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (16 skipped: 16 unsupported.)
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
ℹ️ Recent review info
-
⚙️ Run configuration
-
- Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml
- Review profile: CHILL
- Plan: Advanced
- Run ID:
4c125c4c-232c-4192-b2d8-f8edcdf1a498
📒 Files selected for processing: 16
-
packages/apps/bucket/templates/hooks/cleanup-acme.yaml
packages/apps/bucket/tests/job_name_budget_test.yaml
packages/apps/clickhouse/templates/backup-cronjob.yaml
packages/apps/clickhouse/tests/cronjob_name_budget_test.yaml
packages/apps/kafka/templates/migration-hook.yaml
packages/apps/kafka/tests/job_name_budget_test.yaml
packages/apps/mariadb/templates/backup-cronjob.yaml
packages/apps/mariadb/tests/cronjob_name_budget_test.yaml
packages/apps/qdrant/templates/hooks/cleanup-pvc.yaml
packages/apps/qdrant/tests/job_name_budget_test.yaml
packages/apps/tenant/templates/cleanup-job.yaml
packages/apps/tenant/tests/job_name_budget_test.yaml
packages/apps/vm-disk/templates/pvc-resize-hook.yaml
packages/apps/vm-disk/tests/job_name_budget_test.yaml
packages/apps/vm-instance/templates/vm-update-hook.yaml
packages/apps/vm-instance/tests/job_name_budget_test.yaml
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.
ℹ️ Recent review info
-
⚙️ Run configuration
-
- Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml
- Review profile: CHILL
- Plan: Advanced
- Run ID:
4c125c4c-232c-4192-b2d8-f8edcdf1a498
📒 Files selected for processing: 16
-
packages/apps/bucket/templates/hooks/cleanup-acme.yamlpackages/apps/bucket/tests/job_name_budget_test.yamlpackages/apps/clickhouse/templates/backup-cronjob.yamlpackages/apps/clickhouse/tests/cronjob_name_budget_test.yamlpackages/apps/kafka/templates/migration-hook.yamlpackages/apps/kafka/tests/job_name_budget_test.yamlpackages/apps/mariadb/templates/backup-cronjob.yamlpackages/apps/mariadb/tests/cronjob_name_budget_test.yamlpackages/apps/qdrant/templates/hooks/cleanup-pvc.yamlpackages/apps/qdrant/tests/job_name_budget_test.yamlpackages/apps/tenant/templates/cleanup-job.yamlpackages/apps/tenant/tests/job_name_budget_test.yamlpackages/apps/vm-disk/templates/pvc-resize-hook.yamlpackages/apps/vm-disk/tests/job_name_budget_test.yamlpackages/apps/vm-instance/templates/vm-update-hook.yamlpackages/apps/vm-instance/tests/job_name_budget_test.yaml
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.
-
IvanHunters
left a comment
There was a problem hiding this comment.
Traced the 53-char release-name cap to its enforcement (pkg/registry/apps/application/rest.go:1525), so Pattern A (trunc 63) never cuts into the release name and cannot collide; Pattern B (trunc + sha256[:6]) is used exactly where a naive cut would collide (CronJobs, and the tenant parent/child pair that share cozy-system), and the renders produce distinct names. RBAC objects keep full names, so the bindings are unaffected. Built helm-unittest 1.1.2 and ran all 8 charts (718 tests, 0 failures). No blocking issues.
Non-blocking:
- Three mechanical checks flagged unbounded cleanup Jobs (
qdrant,tenant) and ahook-succeededdelete policy (bucket), but all are on pre-existing lines this PR does not touch. Possible separate follow-up, out of scope here. clickhouse/templates/backup-cronjob.yaml:20:$image := .Files.Get "images/backup.json"looks like dead code (the real image comes from the.tagfile). Pre-existing.
Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
|
europrinter (@yankawai) I merged main into your branch (b5543d8) so CI runs against the current base. Your commits are unchanged. |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
europrinter (@yankawai) LGTM, CI and E2E are green on this head.
What this PR does
The apps API admits release names of up to 53 characters, the release prefix included (less for Kafka and Kubernetes, which cap their own names). Kubernetes copies a Job name into the
job-namelabel of its pods, and a label value takes at most 63 characters, so the apiserver refuses a Job with a longer name. A CronJob name is refused over 52 characters, because the controller names each Job it starts<cronjob>-<timestamp>. I rendered every Job and CronJob inpackages/appsandpackages/extrawith the longest release name each application admits, and eight of them go over.<release>-cleanup-acme<release>-qdrant-cleanup<release>-kafka-migration<release>-volume-resize-hookapplabel of its pod<release>-update-hook<release>-backup<release>-backupcozy-system<tenant namespace>-cleanupCounted in characters of the application name, a Kafka of 42 to 44 cannot be installed today, a VMDisk of 37 or more cannot grow, and a VMInstance of 40 or 41 cannot take an instance type, profile or external change. Deleting a Bucket of 44 or more or a Qdrant of 42 or more fails in the post-delete hook. With the backup CronJob enabled, a MariaDB of 38 or more and a ClickHouse of 35 or more fail the whole release. A nested tenant whose namespace is longer than 55 characters cannot be deleted.
The Jobs of bucket, qdrant, kafka, vm-disk and vm-instance are now named
printf "%s-<suffix>" .Release.Name | trunc 63 | trimSuffix "-", and vm-instance uses the same value for the pod label. A release name is never longer than 53, so only the fixed suffix is cut, and a brute-force check over every pair of release name lengths found no two release names that render the same Job name.A plain cut to 52 would reach into the release name of a CronJob, and two 53-character names that differ in the last character would share one. So a CronJob name that does not fit becomes the release name cut to 38 characters, the first six hex characters of its sha256 and
-backup, the shape #4133 gave the ClickHouse Keeper name. The tenant cleanup Job takes the same form with the namespace cut to 48, because it runs incozy-systemnext to the cleanup Job of every other tenant. There a plain cut gives a parent and a child namedcleathe same name, and the child'sbefore-hook-creationwould delete the parent's Job while it runs.Names that fit render exactly as before. The hook documents rendered from main and from this branch with the short release names the tests use are identical in all eight charts. A name that did not fit never produced an object, so nothing is renamed on upgrade. The ServiceAccounts, Roles and RoleBindings of these hooks keep their names, since they have no such limit, so the ones a pre-install hook left behind are replaced rather than orphaned. Helm runs the delete hooks stored with a release, so an existing Bucket, Qdrant or tenant picks up the fix with its next upgrade.
Every other Job and CronJob fits at the longest name. The cleanup Jobs of clickhouse, harbor, mariadb and opensearch and the Kafka pre-delete Job reach 61, the Postgres init Job 62, and the Kubernetes and KubernetesNodes Jobs either stay under 63 or already cut their names. The etcd and monitoring modules require their chart name as the release name, and the gateway and seaweedfs cleanup Jobs reach 61.
Each of the eight charts gets a new helm-unittest suite. It pins a short name, a name that lands exactly on the limit and the longest admitted name, a cut that would end in a dash wherever one can happen, and for the hooks the unchanged ServiceAccount and RBAC names. The CronJob suites also pin two 53-character names that differ in the last character, and the tenant suite pins the parent and child pair. Against the templates on main, 18 of the 41 new cases fail, every one with a name over the limit. With the hash forms replaced by a plain cut, the tenant parent and child both render
tenant-abcdefghijklmnopqrstuvwxyz-0123456789abcdefghijklmn-cleaand the two MariaDB names both rendermariadb-abcdefghijklmnopqrstuvwxyz0123456789abcdefgh.hack/helm-unit-tests.shpasses over all 106 packages with tests. The Bats files that exercise these hooks and charts (app-cleanup-hooks_test,kafka-migration-hook,kafka-pre-delete-hook,tenant-pre-delete-hook,check-hook-request-timeout,pod-label-census_test,mariadb-first-boot-waits,check-render-matrix) give 96 ok on main and on this branch.make generatewith cozyvalues-gen v1.7.0 in the eight packages changes nothing. A local kube-apiserver v1.35.0 refuses the longest name each chart renders on main, withmust be no more than 63 byteson the job-name label ormust be no more than 52 characterson the CronJob, and creates the name from this branch. For vm-disk and vm-instance, whose hooks render only after a live lookup, that check used a Job with the same name and labels.This is related to #4875 but does not depend on it. #4875 adds a cozy-lib cleanup Job and cuts its name to 63 the same way, while this PR covers the Jobs already on main. Neither needs the other, and the two merge cleanly.
Screenshots
Not a UI change.
Downstream repositories
Templates and tests only. No values, schema, README, defaults,
ApplicationDefinition, Secret or Service name changes, and none of the changed Job or CronJob names appears in the website, the Terraform provider, the Ansible collection or the other repositories on the list.Release note
Summary by CodeRabbit