feat(k8s): support init containers via compose labels
Add support for k8s init containers defined in docker-compose files
using the `laconic.init-container` label. Services with this label
set to "true" are built as init containers instead of regular
containers in the pod spec.
This enables stacks to fetch runtime-created ConfigMaps (e.g. from
deployer jobs) before the main containers start, without requiring
manual operator steps between deployments.
Example compose usage:
services:
fetch-config:
image: bitnami/kubectl:latest
labels:
laconic.init-container: "true"
command: ["sh", "-c", "kubectl get configmap ..."]
volumes:
- shared-config:/config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5af6a83fa2
commit
dcba9e74d9
@ -446,12 +446,16 @@ class ClusterInfo:
|
||||
) -> tuple:
|
||||
"""Build k8s container specs from parsed compose YAML.
|
||||
|
||||
Returns a tuple of (containers, services, volumes) where:
|
||||
Returns a tuple of (containers, init_containers, services, volumes)
|
||||
where:
|
||||
- containers: list of V1Container objects
|
||||
- init_containers: list of V1Container objects for init containers
|
||||
(compose services with label ``laconic.init-container: "true"``)
|
||||
- services: the last services dict processed (used for annotations/labels)
|
||||
- volumes: list of V1Volume objects
|
||||
"""
|
||||
containers = []
|
||||
init_containers = []
|
||||
services = {}
|
||||
global_resources = self.spec.get_container_resources()
|
||||
if not global_resources:
|
||||
@ -571,15 +575,29 @@ class ClusterInfo:
|
||||
),
|
||||
resources=to_k8s_resource_requirements(container_resources),
|
||||
)
|
||||
containers.append(container)
|
||||
# Services with laconic.init-container label become
|
||||
# k8s init containers instead of regular containers.
|
||||
svc_labels = service_info.get("labels", {})
|
||||
if isinstance(svc_labels, list):
|
||||
# docker-compose labels can be a list of "key=value"
|
||||
svc_labels = dict(
|
||||
l.split("=", 1) for l in svc_labels
|
||||
)
|
||||
is_init = str(
|
||||
svc_labels.get("laconic.init-container", "")
|
||||
).lower() in ("true", "1", "yes")
|
||||
if is_init:
|
||||
init_containers.append(container)
|
||||
else:
|
||||
containers.append(container)
|
||||
volumes = volumes_for_pod_files(
|
||||
parsed_yaml_map, self.spec, self.app_name
|
||||
)
|
||||
return containers, services, volumes
|
||||
return containers, init_containers, services, volumes
|
||||
|
||||
# TODO: put things like image pull policy into an object-scope struct
|
||||
def get_deployment(self, image_pull_policy: Optional[str] = None):
|
||||
containers, services, volumes = self._build_containers(
|
||||
containers, init_containers, services, volumes = self._build_containers(
|
||||
self.parsed_pod_yaml_map, image_pull_policy
|
||||
)
|
||||
registry_config = self.spec.get_image_registry_config()
|
||||
@ -650,6 +668,7 @@ class ClusterInfo:
|
||||
metadata=client.V1ObjectMeta(annotations=annotations, labels=labels),
|
||||
spec=client.V1PodSpec(
|
||||
containers=containers,
|
||||
init_containers=init_containers or None,
|
||||
image_pull_secrets=image_pull_secrets,
|
||||
volumes=volumes,
|
||||
affinity=affinity,
|
||||
@ -695,8 +714,8 @@ class ClusterInfo:
|
||||
for job_file in self.parsed_job_yaml_map:
|
||||
# Build containers for this single job file
|
||||
single_job_map = {job_file: self.parsed_job_yaml_map[job_file]}
|
||||
containers, _services, volumes = self._build_containers(
|
||||
single_job_map, image_pull_policy
|
||||
containers, init_containers, _services, volumes = (
|
||||
self._build_containers(single_job_map, image_pull_policy)
|
||||
)
|
||||
|
||||
# Derive job name from file path: docker-compose-<name>.yml -> <name>
|
||||
@ -722,6 +741,7 @@ class ClusterInfo:
|
||||
),
|
||||
spec=client.V1PodSpec(
|
||||
containers=containers,
|
||||
init_containers=init_containers or None,
|
||||
image_pull_secrets=image_pull_secrets,
|
||||
volumes=volumes,
|
||||
restart_policy="Never",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user