refactor(git-gate): centralize hostname qualification in globalize_slug
Adds globalize_slug(slug) to bottle_state alongside bottle_identity.
git_gate_provision now calls globalize_slug(slug) instead of inlining
socket.gethostname(), so the hostname-qualification logic has a single,
named home. Assumes slug is a mint_slug output.
Title format changes from bot-bottle:{host}:{slug}:{name}
to bot-bottle:{host}-{slug}:{name} to match the globalize_slug contract.
This commit is contained in:
@@ -31,6 +31,7 @@ from __future__ import annotations
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
import json
|
import json
|
||||||
import secrets
|
import secrets
|
||||||
|
import socket
|
||||||
import string
|
import string
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -87,6 +88,14 @@ def bottle_identity(agent_name: str) -> str:
|
|||||||
return f"{slug}-{suffix}"
|
return f"{slug}-{suffix}"
|
||||||
|
|
||||||
|
|
||||||
|
def globalize_slug(slug: str) -> str:
|
||||||
|
"""Return a globally-unique slug qualified with the current hostname.
|
||||||
|
|
||||||
|
Assumes slug is a value returned from mint_slug. Use wherever a slug
|
||||||
|
must be unique across hosts (e.g. deploy-key titles)."""
|
||||||
|
return f"{socket.gethostname()}-{slug}"
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class BottleMetadata:
|
class BottleMetadata:
|
||||||
"""Persistent record of how a bottle was launched, written at
|
"""Persistent record of how a bottle was launched, written at
|
||||||
@@ -340,6 +349,7 @@ __all__ = [
|
|||||||
"BottleMetadata",
|
"BottleMetadata",
|
||||||
"agent_state_dir",
|
"agent_state_dir",
|
||||||
"bottle_identity",
|
"bottle_identity",
|
||||||
|
"globalize_slug",
|
||||||
"bottle_state_dir",
|
"bottle_state_dir",
|
||||||
"cleanup_state",
|
"cleanup_state",
|
||||||
"clear_preserve_marker",
|
"clear_preserve_marker",
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import socket
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from .bottle_state import globalize_slug
|
||||||
from .errors import MissingEnvVarError
|
from .errors import MissingEnvVarError
|
||||||
from .log import info
|
from .log import info
|
||||||
from .manifest import ManifestBottle, ManifestGitEntry
|
from .manifest import ManifestBottle, ManifestGitEntry
|
||||||
@@ -47,7 +47,7 @@ def _provision_dynamic_key(
|
|||||||
owner_repo = entry.UpstreamPath
|
owner_repo = entry.UpstreamPath
|
||||||
if owner_repo.endswith(".git"):
|
if owner_repo.endswith(".git"):
|
||||||
owner_repo = owner_repo[:-4]
|
owner_repo = owner_repo[:-4]
|
||||||
title = f"bot-bottle:{socket.gethostname()}:{slug}:{entry.Name}"
|
title = f"bot-bottle:{globalize_slug(slug)}:{entry.Name}"
|
||||||
|
|
||||||
info(f"provisioning deploy key for git-gate.repos[{entry.Name!r}]")
|
info(f"provisioning deploy key for git-gate.repos[{entry.Name!r}]")
|
||||||
key_id, private_key_bytes = provisioner.create(owner_repo, title)
|
key_id, private_key_bytes = provisioner.create(owner_repo, title)
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ class TestProvisionDynamicKey(unittest.TestCase):
|
|||||||
self.assertEqual(b"PRIVATE-KEY-BYTES", key_file.read_bytes())
|
self.assertEqual(b"PRIVATE-KEY-BYTES", key_file.read_bytes())
|
||||||
id_file = Path(d) / "repo-deploy-key-id"
|
id_file = Path(d) / "repo-deploy-key-id"
|
||||||
self.assertEqual("kid123", id_file.read_text())
|
self.assertEqual("kid123", id_file.read_text())
|
||||||
# owner_repo had .git stripped; title carries hostname + slug + name
|
# owner_repo had .git stripped; title carries globalize_slug(slug) + name
|
||||||
hostname = socket.gethostname()
|
hostname = socket.gethostname()
|
||||||
self.assertEqual([("o/r", f"bot-bottle:{hostname}:myslug:repo")], fake.created)
|
self.assertEqual([("o/r", f"bot-bottle:{hostname}-myslug:repo")], fake.created)
|
||||||
|
|
||||||
def test_missing_token_raises(self) -> None:
|
def test_missing_token_raises(self) -> None:
|
||||||
with tempfile.TemporaryDirectory() as d, \
|
with tempfile.TemporaryDirectory() as d, \
|
||||||
|
|||||||
Reference in New Issue
Block a user