From 66da312f67d4d8b25b2bd9abee3e04b6fccda6fb Mon Sep 17 00:00:00 2001 From: "A. F. Dudley" Date: Wed, 1 Apr 2026 21:50:53 +0000 Subject: [PATCH] fix: base36 IDs for kind-compatible cluster names, test --perform-cluster-management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ids.py: use base36 (lowercase+digits) instead of base62 — kind cluster names must match ^[a-z0-9.-]+$ - k8s deploy test: pass --perform-cluster-management on first start since 'start' defaults to --skip-cluster-management Found by running tests/k8s-deploy/run-deploy-test.sh locally. Co-Authored-By: Claude Opus 4.6 (1M context) --- stack_orchestrator/ids.py | 25 +++++++++++++------------ tests/k8s-deploy/run-deploy-test.sh | 5 +++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/stack_orchestrator/ids.py b/stack_orchestrator/ids.py index e6a67782..97e7cb11 100644 --- a/stack_orchestrator/ids.py +++ b/stack_orchestrator/ids.py @@ -1,11 +1,11 @@ """Sortable timestamp-based ID generation for cluster naming. -Uses base62 encoding with 100ms resolution and a 2024-01-01 epoch -to produce compact, sortable IDs like 'laconic-iqE6Za'. +Uses base36 encoding with 100ms resolution and a 2024-01-01 epoch +to produce compact, sortable IDs like 'laconic-3k7m2ab'. Format: {prefix}-{timestamp}{random} -- timestamp: 5 chars (100ms resolution, ~180 years from 2024) -- random: 2 chars (3,844 unique per 100ms slot) +- timestamp: 7 chars base36 (100ms resolution, ~2500 years from 2024) +- random: 2 chars (1,296 unique per 100ms slot) """ # Adapted from exophial/src/exophial/ids.py @@ -15,23 +15,24 @@ import time # 2024-01-01 00:00:00 UTC in milliseconds EPOCH_2024 = 1704067200000 -# Sortable base62 alphabet (0-9, A-Z, a-z) -ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +# Sortable base36 alphabet (0-9, a-z) — lowercase only to satisfy +# kind cluster name validation (^[a-z0-9.-]+$) +ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz" -def _base62(n: int) -> str: - """Encode integer as base62 string.""" +def _base36(n: int) -> str: + """Encode integer as base36 string.""" if n == 0: return ALPHABET[0] s = "" while n: - n, r = divmod(n, 62) + n, r = divmod(n, len(ALPHABET)) s = ALPHABET[r] + s return s def _random_suffix(length: int = 2) -> str: - """Generate random base62 suffix.""" + """Generate random base36 suffix.""" return "".join(random.choice(ALPHABET) for _ in range(length)) @@ -39,9 +40,9 @@ def _timestamp_id() -> str: """Generate a sortable timestamp ID (100ms resolution, 2024 epoch) with random suffix.""" now_ms = int(time.time() * 1000) offset = (now_ms - EPOCH_2024) // 100 # 100ms resolution - return f"{_base62(offset)}{_random_suffix()}" + return f"{_base36(offset)}{_random_suffix()}" def generate_id(prefix: str) -> str: - """Generate a sortable ID with an arbitrary prefix like 'laconic-iqE6Za'.""" + """Generate a sortable ID with an arbitrary prefix like 'laconic-3k7m2ab'.""" return f"{prefix}-{_timestamp_id()}" diff --git a/tests/k8s-deploy/run-deploy-test.sh b/tests/k8s-deploy/run-deploy-test.sh index cfc03138..9cd28692 100755 --- a/tests/k8s-deploy/run-deploy-test.sh +++ b/tests/k8s-deploy/run-deploy-test.sh @@ -115,8 +115,9 @@ sed -i 's/^secrets: {}$/secrets:\n test-secret:\n - TEST_SECRET_KEY/' ${depl deployment_id=$(cat ${test_deployment_dir}/deployment.yml | cut -d ' ' -f 2) echo "deploy create output file test: passed" -# Try to start the deployment -$TEST_TARGET_SO deployment --dir $test_deployment_dir start +# Try to start the deployment (--perform-cluster-management needed on first start +# because 'start' defaults to --skip-cluster-management) +$TEST_TARGET_SO deployment --dir $test_deployment_dir start --perform-cluster-management wait_for_pods_started # Check logs command works wait_for_log_output