From 9ca2e68f84188686a916d87ebe7288d0ba174eec Mon Sep 17 00:00:00 2001 From: Kevin Pouget Date: Tue, 12 May 2026 15:07:14 +0200 Subject: [PATCH] [fournos_launcher] sanitize the job name before submitting it --- projects/fournos_launcher/orchestration/submit.py | 6 ++++-- .../toolbox/submit_and_wait/main.py | 15 ++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/projects/fournos_launcher/orchestration/submit.py b/projects/fournos_launcher/orchestration/submit.py index 2611f343..4a1bc671 100644 --- a/projects/fournos_launcher/orchestration/submit.py +++ b/projects/fournos_launcher/orchestration/submit.py @@ -7,6 +7,7 @@ import traceback from datetime import datetime +from projects.core.dsl.utils.k8s import sanitize_k8s_name from projects.core.library import config, env, run, vault from projects.core.library.run_parallel import Parallel from projects.fournos_launcher.orchestration import job_management, pr_args @@ -159,6 +160,7 @@ def submit_job(): # Generate timestamp for parallel job names (shared across all parallel jobs) timestamp = datetime.now().strftime("%Y%m%d-%H%M%S") raw_name = f"forge-{project_name}-{timestamp}" + raw_name = sanitize_k8s_name(raw_name) # Track failures and job names across parallel jobs failure_lock = threading.Lock() @@ -179,7 +181,7 @@ def submit_parallel_job(job_index, job_args_list): parallel_display_name = f"{project_name} {args_str} (job {job_index})".strip() # Create unique job name with timestamp and index - unique_job_name = f"{raw_name}-{job_index}" + unique_job_name = sanitize_k8s_name(f"{raw_name}-{job_index}") try: # Track the job name for cleanup (job gets submitted even if waiting fails) @@ -240,7 +242,7 @@ def submit_parallel_job(job_index, job_args_list): # Generate unique job name for single job timestamp = datetime.now().strftime("%Y%m%d-%H%M%S") - single_job_name = f"forge-{project_name}-{timestamp}" + single_job_name = sanitize_k8s_name(f"forge-{project_name}-{timestamp}") try: submit_and_wait( diff --git a/projects/fournos_launcher/toolbox/submit_and_wait/main.py b/projects/fournos_launcher/toolbox/submit_and_wait/main.py index 6693ef42..818fa126 100755 --- a/projects/fournos_launcher/toolbox/submit_and_wait/main.py +++ b/projects/fournos_launcher/toolbox/submit_and_wait/main.py @@ -18,7 +18,7 @@ task, template, ) -from projects.core.dsl.utils.k8s import sanitize_k8s_name +from projects.core.dsl.utils.k8s import is_valid_k8s_name, sanitize_k8s_name from projects.core.library import env as env_mod logger = logging.getLogger(__name__) @@ -133,14 +133,19 @@ def generate_job_name(args, ctx): """Generate job name if not provided and ensure K8s compatibility""" if args.job_name: - # Sanitize user-provided job name - raw_name = args.job_name + # Validate that user-provided job name is already normalized + if not is_valid_k8s_name(args.job_name): + normalized_name = sanitize_k8s_name(args.job_name) + raise ValueError( + f"Job name '{args.job_name}' is not valid for Kubernetes. " + f"Please use the normalized name: '{normalized_name}'" + ) + ctx.final_job_name = args.job_name else: # Generate and sanitize auto job name timestamp = datetime.now().strftime("%Y%m%d-%H%M%S") raw_name = f"forge-{args.project}-{timestamp}" - - ctx.final_job_name = sanitize_k8s_name(raw_name) + ctx.final_job_name = sanitize_k8s_name(raw_name) return f"Job name: {ctx.final_job_name}"