fix: hash scheduler-k3s cron-id label to fit Kubernetes' 63-byte cap

The `dokku.com/cron-id` label could exceed Kubernetes' 63-byte cap because the cron ID is `base36(appName === command === schedule)`, which expands roughly 1.5x per byte. The label is now keyed `dokku.com/cron-hash` and holds the `sha1` hex digest of the cron-id, a fixed 40-character value that always fits the cap. The same hex digest is mirrored into the `dokku.com/cron-hash` annotation, and the original base36 cron-id stays in the `dokku.com/cron-id` annotation that `cron:list` reads when surfacing user-facing IDs. Per-task lookups stay server-side via label selectors, so `cron:set --maintenance` and the forbid/replace concurrency checks on `dokku run --cron-id` keep working without any in-memory filtering.
This commit is contained in:
Jose Diaz-Gonzalez
2026-05-24 02:50:09 -04:00
parent 3c8cba08e5
commit bf2cfe1886
10 changed files with 235 additions and 51 deletions

View File

@@ -1,7 +1,7 @@
{
"cron": [
{
"command": "python3 task.py",
"command": "python3 task.py some cron task",
"schedule": "5 5 5 5 5"
}
],

View File

@@ -265,7 +265,7 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_success
assert_output "['task.py']"
assert_output "['task.py', 'some', 'cron', 'task']"
}
@test "(builder-pack) cron:run with Procfile reference" {

View File

@@ -103,11 +103,31 @@ teardown() {
assert_success
assert_output_exists
cron_hash="$(printf '%s' "$cron_id" | sha1sum | awk '{print $1}')"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-id\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_id"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.labels.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "dokku --quiet cron:run $TEST_APP $cron_id"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "['task.py']"
assert_output_contains "['task.py', 'some', 'cron', 'task']"
}
@test "(scheduler-k3s) cnb dokku run uses launcher entrypoint" {

View File

@@ -94,6 +94,26 @@ teardown() {
assert_success
assert_output_exists
cron_hash="$(printf '%s' "$cron_id" | sha1sum | awk '{print $1}')"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-id\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_id"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.labels.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "dokku --quiet cron:run $TEST_APP $cron_id"
echo "output: $output"
echo "status: $status"

View File

@@ -99,6 +99,26 @@ teardown() {
assert_success
assert_output_exists
cron_hash="$(printf '%s' "$cron_id" | sha1sum | awk '{print $1}')"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-id\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_id"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.labels.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "kubectl get cronjob -o json | jq -r '.items[0].metadata.annotations.\"dokku.com/cron-hash\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$cron_hash"
run /bin/bash -c "dokku --quiet cron:run $TEST_APP $cron_id"
echo "output: $output"
echo "status: $status"