From 79b7870a6a427fc15778b24e960f64aedb0f2634 Mon Sep 17 00:00:00 2001 From: "A. F. Dudley" Date: Sun, 25 Jan 2026 16:57:28 -0500 Subject: [PATCH] feat(k8s): enable relative volume paths for kind deployments Makes kind deployments use the same volume pattern as Docker Compose: ./data/{volume-name} relative to deployment directory. Changes: - Allow relative paths for kind (single host, like Docker Compose) - Default kind volumes to ./data/ instead of provisioner-managed PVCs - Update Caddy manifest to use hostPath /mnt/caddy-data - Add caddy-data infrastructure volume support in kind mounts This enables Caddy certificate persistence across cluster recreation without requiring system-level directories like /opt/caddy-data. Co-Authored-By: Claude Opus 4.5 --- .../ingress/ingress-caddy-kind-deploy.yaml | 20 +++----------- .../deploy/deployment_create.py | 27 ++++++++++++------- stack_orchestrator/deploy/k8s/helpers.py | 12 +++++++++ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/stack_orchestrator/data/k8s/components/ingress/ingress-caddy-kind-deploy.yaml b/stack_orchestrator/data/k8s/components/ingress/ingress-caddy-kind-deploy.yaml index d681b3e8..2511947f 100644 --- a/stack_orchestrator/data/k8s/components/ingress/ingress-caddy-kind-deploy.yaml +++ b/stack_orchestrator/data/k8s/components/ingress/ingress-caddy-kind-deploy.yaml @@ -243,26 +243,12 @@ spec: mountPath: /config volumes: - name: caddy-data - persistentVolumeClaim: - claimName: caddy-data-pvc + hostPath: + path: /mnt/caddy-data + type: DirectoryOrCreate - name: caddy-config emptyDir: {} --- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: caddy-data-pvc - namespace: caddy-system - labels: - app.kubernetes.io/name: caddy-ingress-controller - app.kubernetes.io/instance: caddy-ingress -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index 601f6c77..cb22d75a 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -452,17 +452,21 @@ def init_operation( volume_descriptors = {} configmap_descriptors = {} for named_volume in named_volumes["rw"]: - if "k8s" in deployer_type: + if deployer_type == "k8s": + # Full k8s: use provisioner-managed volumes volume_descriptors[named_volume] = None else: + # Docker Compose and kind: use relative paths volume_descriptors[named_volume] = f"./data/{named_volume}" for named_volume in named_volumes["ro"]: - if "k8s" in deployer_type: + if deployer_type == "k8s": + # Full k8s: configmaps or provisioner-managed if "config" in named_volume: configmap_descriptors[named_volume] = f"./configmaps/{named_volume}" else: volume_descriptors[named_volume] = None else: + # Docker Compose and kind: use relative paths volume_descriptors[named_volume] = f"./data/{named_volume}" if volume_descriptors: spec_file_content["volumes"] = volume_descriptors @@ -509,14 +513,17 @@ def _create_deployment_file(deployment_dir: Path): def _check_volume_definitions(spec): - if spec.is_kubernetes_deployment(): - for volume_name, volume_path in spec.get_volumes().items(): - if volume_path: - if not os.path.isabs(volume_path): - raise Exception( - f"Relative path {volume_path} for volume {volume_name} not " - f"supported for deployment type {spec.get_deployment_type()}" - ) + # Kind allows relative paths (single host, like Docker Compose) + # Full k8s requires absolute paths (pods could run on any node) + if not spec.is_kubernetes_deployment() or spec.is_kind_deployment(): + return + + for volume_name, volume_path in spec.get_volumes().items(): + if volume_path and not os.path.isabs(volume_path): + raise Exception( + f"Relative path {volume_path} for volume {volume_name} not " + f"supported for deployment type {spec.get_deployment_type()}" + ) @click.command() diff --git a/stack_orchestrator/deploy/k8s/helpers.py b/stack_orchestrator/deploy/k8s/helpers.py index a125d4f5..66ba2f4c 100644 --- a/stack_orchestrator/deploy/k8s/helpers.py +++ b/stack_orchestrator/deploy/k8s/helpers.py @@ -238,6 +238,18 @@ def _make_absolute_host_path(data_mount_path: Path, deployment_dir: Path) -> Pat def _generate_kind_mounts(parsed_pod_files, deployment_dir, deployment_context): volume_definitions = [] volume_host_path_map = _get_host_paths_for_volumes(deployment_context) + + # Add infrastructure volumes (not defined in compose files) + for infra_volume in ["caddy-data"]: + if infra_volume in volume_host_path_map and volume_host_path_map[infra_volume]: + host_path = _make_absolute_host_path( + volume_host_path_map[infra_volume], deployment_dir + ) + container_path = get_kind_pv_bind_mount_path(infra_volume) + volume_definitions.append( + f" - hostPath: {host_path}\n" f" containerPath: {container_path}\n" + ) + # Note these paths are relative to the location of the pod files (at present) # So we need to fix up to make them correct and absolute because kind assumes # relative to the cwd.