From 17b614cb4df5b5740f439e2e4455e16a51e114d4 Mon Sep 17 00:00:00 2001 From: prathamesh0 <42446521+prathamesh0@users.noreply.github.com> Date: Tue, 14 Apr 2026 11:30:27 +0530 Subject: [PATCH] Fix configmap source path resolution for user-defined spec paths (#741) --- .../deploy/deployment_create.py | 20 ++++++++++++++++--- stack_orchestrator/deploy/k8s/cluster_info.py | 12 ++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index 65dbd5b5..074b6ba8 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -1110,10 +1110,24 @@ def _write_deployment_files( # Copy configmap directories for k8s deployments (outside the pod loop # so this works for jobs-only stacks too) if parsed_spec.is_kubernetes_deployment(): - for configmap in parsed_spec.get_configmaps(): - source_config_dir = resolve_config_dir(stack_name, configmap) + configmaps = parsed_spec.get_configmaps() + for configmap_name, configmap_path in configmaps.items(): + # Spec values starting with ./ are deployment-dir destination + # paths (written by deploy init for auto-discovered configmaps). + # Other values are source paths relative to the stack root + # (user-defined in spec.yml). Fall back to the config/ dir + # convention if no value is provided. + if configmap_path and not str(configmap_path).startswith("./"): + # configmap_path is relative to the repo root (cwd during + # restart). get_stack_path gives us a path like + # "stack-orchestrator/stacks/dumpster" — also relative to + # repo root. The configmap_path is already repo-relative, + # so use it directly (cwd is repo root during restart). + source_config_dir = Path(configmap_path) + else: + source_config_dir = resolve_config_dir(stack_name, configmap_name) if os.path.exists(source_config_dir): - destination_config_dir = target_dir.joinpath("configmaps", configmap) + destination_config_dir = target_dir.joinpath("configmaps", configmap_name) copytree(source_config_dir, destination_config_dir, dirs_exist_ok=True) # Copy the job files into the target dir diff --git a/stack_orchestrator/deploy/k8s/cluster_info.py b/stack_orchestrator/deploy/k8s/cluster_info.py index d2fd396a..88cb2a21 100644 --- a/stack_orchestrator/deploy/k8s/cluster_info.py +++ b/stack_orchestrator/deploy/k8s/cluster_info.py @@ -392,11 +392,17 @@ class ClusterInfo: print(f"{cfg_map_name} not in pod files") continue - cfg_map_path = os.path.expanduser(cfg_map_path) - if not cfg_map_path.startswith("/") and self.spec.file_path is not None: + # ConfigMap files live in {deployment_dir}/configmaps/{name}/, + # copied there by deploy create / restart from the source path + # specified in the spec. + if self.spec.file_path is not None: cfg_map_path = os.path.join( - os.path.dirname(str(self.spec.file_path)), cfg_map_path + os.path.dirname(str(self.spec.file_path)), + "configmaps", + cfg_map_name, ) + else: + cfg_map_path = os.path.expanduser(cfg_map_path) # Read in all the files at a single-level of the directory. # This mimics the behavior of