feat: add sunbeam build integration target
Builds the integration-service Docker image from the sunbeam/ root context (needs both integration/packages/ for the widget source and integration-service/ for nginx config and logos), pushes to Gitea, pre-seeds into k3s containerd, and rolls the deployment.
This commit is contained in:
@@ -50,8 +50,8 @@ def main() -> None:
|
||||
|
||||
# sunbeam build <what>
|
||||
p_build = sub.add_parser("build", help="Build and push an artifact")
|
||||
p_build.add_argument("what", choices=["proxy", "kratos-admin"],
|
||||
help="What to build (proxy, kratos-admin)")
|
||||
p_build.add_argument("what", choices=["proxy", "integration", "kratos-admin"],
|
||||
help="What to build (proxy, integration, kratos-admin)")
|
||||
|
||||
# sunbeam check [ns[/name]]
|
||||
p_check = sub.add_parser("check", help="Functional service health checks")
|
||||
|
||||
@@ -272,9 +272,11 @@ def _trust_registry_in_docker_vm(registry: str):
|
||||
|
||||
|
||||
def cmd_build(what: str):
|
||||
"""Build and push an image. Supports 'proxy' and 'kratos-admin'."""
|
||||
"""Build and push an image. Supports 'proxy', 'integration', and 'kratos-admin'."""
|
||||
if what == "proxy":
|
||||
_build_proxy()
|
||||
elif what == "integration":
|
||||
_build_integration()
|
||||
elif what == "kratos-admin":
|
||||
_build_kratos_admin()
|
||||
else:
|
||||
@@ -364,6 +366,103 @@ def _build_proxy():
|
||||
ok("Pingora redeployed.")
|
||||
|
||||
|
||||
def _build_integration():
|
||||
ip = get_lima_ip()
|
||||
domain = f"{ip}.sslip.io"
|
||||
|
||||
b64 = kube_out("-n", "devtools", "get", "secret",
|
||||
"gitea-admin-credentials", "-o=jsonpath={.data.password}")
|
||||
if not b64:
|
||||
die("gitea-admin-credentials secret not found -- run seed first.")
|
||||
admin_pass = base64.b64decode(b64).decode()
|
||||
|
||||
if not shutil.which("docker"):
|
||||
die("docker not found -- is the Lima docker VM running?")
|
||||
|
||||
# Build context is the sunbeam/ root so Dockerfile can reach both
|
||||
# integration/packages/ (upstream widget + logos) and integration-service/.
|
||||
sunbeam_dir = Path(__file__).resolve().parents[2]
|
||||
integration_service_dir = sunbeam_dir / "integration-service"
|
||||
dockerfile = integration_service_dir / "Dockerfile"
|
||||
dockerignore = integration_service_dir / ".dockerignore"
|
||||
|
||||
if not dockerfile.exists():
|
||||
die(f"integration-service Dockerfile not found at {dockerfile}")
|
||||
if not (sunbeam_dir / "integration" / "packages" / "widgets").is_dir():
|
||||
die(f"integration repo not found at {sunbeam_dir / 'integration'} -- "
|
||||
"run: cd sunbeam && git clone https://github.com/suitenumerique/integration.git")
|
||||
|
||||
registry = f"src.{domain}"
|
||||
image = f"{registry}/studio/integration:latest"
|
||||
|
||||
step(f"Building integration -> {image} ...")
|
||||
|
||||
_trust_registry_in_docker_vm(registry)
|
||||
|
||||
ok("Logging in to Gitea registry...")
|
||||
r = subprocess.run(
|
||||
["docker", "login", registry,
|
||||
"--username", GITEA_ADMIN_USER, "--password-stdin"],
|
||||
input=admin_pass, text=True, capture_output=True,
|
||||
)
|
||||
if r.returncode != 0:
|
||||
die(f"docker login failed:\n{r.stderr.strip()}")
|
||||
|
||||
ok("Building image (linux/arm64, push)...")
|
||||
# --file points to integration-service/Dockerfile; context is sunbeam/ root.
|
||||
# Docker resolves .dockerignore relative to the build context root, but since
|
||||
# --file is outside the context root we provide it explicitly via env or flag.
|
||||
# Workaround: copy .dockerignore to sunbeam/ root temporarily, then remove.
|
||||
root_ignore = sunbeam_dir / ".dockerignore"
|
||||
copied_ignore = False
|
||||
if not root_ignore.exists():
|
||||
shutil.copy(str(dockerignore), str(root_ignore))
|
||||
copied_ignore = True
|
||||
try:
|
||||
_run(["docker", "buildx", "build",
|
||||
"--platform", "linux/arm64",
|
||||
"--push",
|
||||
"-f", str(dockerfile),
|
||||
"-t", image,
|
||||
str(sunbeam_dir)])
|
||||
finally:
|
||||
if copied_ignore and root_ignore.exists():
|
||||
root_ignore.unlink()
|
||||
|
||||
ok(f"Pushed {image}")
|
||||
|
||||
# Pre-seed into k3s containerd (same pattern as other custom images).
|
||||
nodes = kube_out("get", "nodes", "-o=jsonpath={.items[*].metadata.name}").split()
|
||||
if len(nodes) == 1:
|
||||
ok("Single-node cluster: pre-seeding image into k3s containerd...")
|
||||
save = subprocess.Popen(
|
||||
["docker", "save", image],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
ctr = subprocess.run(
|
||||
["limactl", "shell", LIMA_VM, "--",
|
||||
"sudo", "ctr", "-n", "k8s.io", "images", "import", "-"],
|
||||
stdin=save.stdout,
|
||||
capture_output=True,
|
||||
)
|
||||
save.stdout.close()
|
||||
save.wait()
|
||||
if ctr.returncode != 0:
|
||||
warn(f"containerd import failed (will fall back to registry pull):\n"
|
||||
f"{ctr.stderr.decode().strip()}")
|
||||
else:
|
||||
ok("Image pre-seeded.")
|
||||
|
||||
from sunbeam.manifests import cmd_apply
|
||||
cmd_apply()
|
||||
|
||||
ok("Rolling integration deployment...")
|
||||
kube("rollout", "restart", "deployment/integration", "-n", "lasuite")
|
||||
kube("rollout", "status", "deployment/integration", "-n", "lasuite",
|
||||
"--timeout=120s")
|
||||
ok("Integration redeployed.")
|
||||
|
||||
|
||||
def _build_kratos_admin():
|
||||
ip = get_lima_ip()
|
||||
domain = f"{ip}.sslip.io"
|
||||
|
||||
Reference in New Issue
Block a user