fix: make Crabbox provider names lease-unique

This commit is contained in:
Peter Steinberger 2026-05-05 10:36:24 +01:00
parent 0ca412a8d5
commit 3ffa613b61
No known key found for this signature in database
5 changed files with 11 additions and 6 deletions

View File

@ -11,6 +11,7 @@
### Fixed
- Fixed auto-shell command reconstruction so arguments with spaces stay quoted when shell operators such as `&&` are present.
- Fixed brokered cloud server names so friendly-slug collisions with stale provider VMs do not block new leases.
- Fixed human WebVNC desktop launches to keep browser windows windowed by default and reserve fullscreen for explicit capture/video workflows.
- Fixed WebVNC portal status text and bridge commands so waiting/reset states explain the exact local bridge command to run.
- Fixed Windows WebVNC credential handling so generated portal links preserve special characters and managed TightVNC sessions copy service passwords into the logged-in user's registry profile.

View File

@ -73,7 +73,7 @@ func normalizeLeaseSlug(value string) string {
func leaseProviderName(leaseID, slug string) string {
if slug = normalizeLeaseSlug(slug); slug != "" {
return "crabbox-" + slug
return fmt.Sprintf("crabbox-%s-%08x", slug, leaseSlugHash(leaseID))
}
return strings.ReplaceAll("crabbox-"+leaseID, "_", "-")
}

View File

@ -35,7 +35,7 @@ func TestLeaseSlugFormat(t *testing.T) {
if !regexp.MustCompile(`^[a-z0-9]+-[a-z0-9]+$`).MatchString(slug) {
t.Fatalf("slug %q is not DNS-ish two-word form", slug)
}
if len("crabbox-"+slug) > 63 {
if len(leaseProviderName("cbx_abcdef123456", slug)) > 63 {
t.Fatalf("provider name too long for slug %q", slug)
}
}
@ -62,7 +62,7 @@ func TestAllocateDirectLeaseSlugAddsSuffixOnCollision(t *testing.T) {
}
func TestLeaseProviderNameUsesSlug(t *testing.T) {
if got := leaseProviderName("cbx_abcdef123456", "blue-lobster"); got != "crabbox-blue-lobster" {
if got := leaseProviderName("cbx_abcdef123456", "blue-lobster"); got != "crabbox-blue-lobster-c80c2195" {
t.Fatalf("provider name=%q", got)
}
if got := leaseProviderName("cbx_abcdef123456", ""); got != "crabbox-cbx-abcdef123456" {

View File

@ -50,7 +50,9 @@ export function slugWithCollisionSuffix(base: string, seed: string): string {
export function leaseProviderName(leaseID: string, slug: string | undefined): string {
const normalized = normalizeLeaseSlug(slug);
return normalized ? `crabbox-${normalized}` : `crabbox-${leaseID}`.replaceAll("_", "-");
return normalized
? `crabbox-${normalized}-${slugHash(leaseID).toString(16).padStart(8, "0")}`
: `crabbox-${leaseID}`.replaceAll("_", "-");
}
function slugHash(value: string): number {

View File

@ -12,7 +12,7 @@ describe("lease slugs", () => {
const slug = leaseSlugFromID("cbx_abcdef123456");
expect(leaseSlugFromID("cbx_abcdef123456")).toBe(slug);
expect(slug).toMatch(/^[a-z0-9]+-[a-z0-9]+$/);
expect(`crabbox-${slug}`.length).toBeLessThanOrEqual(63);
expect(leaseProviderName("cbx_abcdef123456", slug).length).toBeLessThanOrEqual(63);
});
it("matches Go golden fixtures", () => {
@ -29,7 +29,9 @@ describe("lease slugs", () => {
});
it("uses slug for provider names while preserving ID fallback", () => {
expect(leaseProviderName("cbx_abcdef123456", "blue-lobster")).toBe("crabbox-blue-lobster");
expect(leaseProviderName("cbx_abcdef123456", "blue-lobster")).toBe(
"crabbox-blue-lobster-c80c2195",
);
expect(leaseProviderName("cbx_abcdef123456", "")).toBe("crabbox-cbx-abcdef123456");
});
});