@@ -223,11 +223,10 @@ def fix_mount_dict(
223223 # handle anonymous or implied volume
224224 if not source :
225225 # missing source
226- vol ["name" ] = "_" .join ([
227- compose .project_name ,
226+ vol ["name" ] = compose .format_name (
228227 srv_name ,
229228 hashlib .sha256 (mount_dict ["target" ].encode ("utf-8" )).hexdigest (),
230- ] )
229+ )
231230 elif not name :
232231 external = vol .get ("external" )
233232 if isinstance (external , dict ):
@@ -374,38 +373,25 @@ def default_network_name_for_project(compose: PodmanCompose, net: str, is_ext: A
374373 PodmanCompose .XPodmanSettingKey .DEFAULT_NET_NAME_COMPAT , False
375374 )
376375 if default_net_name_compat is True :
377- return f"{ compose .project_name .replace ('-' , '' )} _{ net } "
378- return f"{ compose .project_name } _{ net } "
379-
380-
381- # def tr_identity(project_name, given_containers):
382- # pod_name = f'pod_{project_name}'
383- # pod = dict(name=pod_name)
384- # containers = []
385- # for cnt in given_containers:
386- # containers.append(dict(cnt, pod=pod_name))
387- # return [pod], containers
388-
376+ return compose .join_name_parts (compose .project_name .replace ('-' , '' ), net )
377+ return compose .format_name (net )
389378
390- def transform (
391- args : Any , project_name : str , given_containers : list [Any ]
392- ) -> tuple [list [dict ], list [dict ]]:
393- in_pod = str (args .in_pod ).lower ()
394- pod_name = None
395- pods = []
396379
397- if in_pod in ('true' , '1' , 'none' , '' ):
398- pod_name = f"pod_{ project_name } "
399- elif in_pod not in ('false' , '0' ):
400- pod_name = args .in_pod
401-
402- if pod_name :
403- pods = [{"name" : pod_name }]
404-
405- containers = []
406- for cnt in given_containers :
407- containers .append (dict (cnt , pod = pod_name ))
408- return pods , containers
380+ def try_parse_bool (value : Any ) -> bool | None :
381+ if isinstance (value , bool ):
382+ return value
383+ if isinstance (value , str ):
384+ value = value .lower ()
385+ if value in ('true' , '1' ):
386+ return True
387+ if value in ('false' , '0' ):
388+ return False
389+ if isinstance (value , int ):
390+ if value == 1 :
391+ return True
392+ if value == 0 :
393+ return False
394+ return None
409395
410396
411397async def assert_volume (compose : PodmanCompose , mount_dict : dict [str , Any ]) -> None :
@@ -1973,6 +1959,7 @@ class PodmanCompose:
19731959 class XPodmanSettingKey (Enum ):
19741960 DEFAULT_NET_NAME_COMPAT = "default_net_name_compat"
19751961 DEFAULT_NET_BEHAVIOR_COMPAT = "default_net_behavior_compat"
1962+ NAME_SEPARATOR_COMPAT = "name_separator_compat"
19761963 IN_POD = "in_pod"
19771964 POD_ARGS = "pod_args"
19781965
@@ -2065,11 +2052,23 @@ async def run(self, argv: list[str] | None = None) -> None:
20652052 if isinstance (retcode , int ):
20662053 sys .exit (retcode )
20672054
2068- def resolve_in_pod (self ) -> bool :
2069- if self .global_args .in_pod in (None , '' ):
2070- self .global_args .in_pod = self .x_podman .get (PodmanCompose .XPodmanSettingKey .IN_POD , "1" )
2071- # otherwise use `in_pod` value provided by command line
2072- return self .global_args .in_pod
2055+ def resolve_pod_name (self ) -> str | None :
2056+ # Priorities:
2057+ # - Command line --in-pod
2058+ # - docker-compose.yml x-podman.in_pod
2059+ # - Default value of true
2060+ in_pod_arg = self .global_args .in_pod or self .x_podman .get (
2061+ PodmanCompose .XPodmanSettingKey .IN_POD , True
2062+ )
2063+
2064+ in_pod_arg_parsed = try_parse_bool (in_pod_arg )
2065+ if in_pod_arg_parsed is True :
2066+ return f"pod_{ self .project_name } "
2067+ if in_pod_arg_parsed is False :
2068+ return None
2069+
2070+ assert isinstance (in_pod_arg , str ) and in_pod_arg
2071+ return in_pod_arg
20732072
20742073 def resolve_pod_args (self ) -> list [str ]:
20752074 # Priorities:
@@ -2082,6 +2081,18 @@ def resolve_pod_args(self) -> list[str]:
20822081 PodmanCompose .XPodmanSettingKey .POD_ARGS , ["--infra=false" , "--share=" ]
20832082 )
20842083
2084+ def join_name_parts (self , * parts : str ) -> str :
2085+ setting = self .x_podman .get (PodmanCompose .XPodmanSettingKey .NAME_SEPARATOR_COMPAT , False )
2086+ if try_parse_bool (setting ):
2087+ sep = "-"
2088+ else :
2089+ sep = "_"
2090+ return sep .join (parts )
2091+
2092+ def format_name (self , * parts : str ) -> str :
2093+ assert self .project_name is not None
2094+ return self .join_name_parts (self .project_name , * parts )
2095+
20852096 def _parse_x_podman_settings (self , compose : dict [str , Any ], environ : dict [str , str ]) -> None :
20862097 known_keys = {s .value : s for s in PodmanCompose .XPodmanSettingKey }
20872098
@@ -2265,6 +2276,8 @@ def _parse_compose_file(self) -> None:
22652276
22662277 self ._parse_x_podman_settings (compose , self .environ )
22672278
2279+ pod_name = self .resolve_pod_name ()
2280+
22682281 services : dict | None = compose .get ("services" )
22692282 if services is None :
22702283 services = {}
@@ -2352,14 +2365,15 @@ def _parse_compose_file(self) -> None:
23522365
23532366 container_names_by_service [service_name ] = []
23542367 for num in range (1 , replicas + 1 ):
2355- name0 = f" { project_name } _ { service_name } _ { num } "
2368+ name0 = self . format_name ( service_name , str ( num ))
23562369 if num == 1 :
23572370 name = service_desc .get ("container_name" , name0 )
23582371 else :
23592372 name = name0
23602373 container_names_by_service [service_name ].append (name )
23612374 # log(service_name,service_desc)
23622375 cnt = {
2376+ "pod" : pod_name ,
23632377 "name" : name ,
23642378 "num" : num ,
23652379 "service_name" : service_name ,
@@ -2368,7 +2382,7 @@ def _parse_compose_file(self) -> None:
23682382 x_podman = service_desc .get ("x-podman" )
23692383 rootfs_mode = x_podman is not None and x_podman .get ("rootfs" ) is not None
23702384 if "image" not in cnt and not rootfs_mode :
2371- cnt ["image" ] = f" { project_name } _ { service_name } "
2385+ cnt ["image" ] = self . format_name ( service_name )
23722386 labels = norm_as_list (cnt .get ("labels" ))
23732387 cnt ["ports" ] = norm_ports (cnt .get ("ports" ))
23742388 labels .extend (podman_compose_labels )
@@ -2399,12 +2413,9 @@ def _parse_compose_file(self) -> None:
23992413 given_containers .sort (key = lambda c : len (c .get ("_deps" , [])))
24002414 # log("sorted:", [c["name"] for c in given_containers])
24012415
2402- args .in_pod = self .resolve_in_pod ()
2403- args .pod_arg_list = self .resolve_pod_args ()
2404- pods , containers = transform (args , project_name , given_containers )
2405- self .pods = pods
2406- self .containers = containers
2407- self .container_by_name = {c ["name" ]: c for c in containers }
2416+ self .pods = [{"name" : pod_name }] if pod_name else []
2417+ self .containers = given_containers
2418+ self .container_by_name = {c ["name" ]: c for c in given_containers }
24082419
24092420 def _resolve_profiles (
24102421 self , defined_services : dict [str , Any ], requested_profiles : set [str ] | None = None
@@ -2931,17 +2942,16 @@ async def pod_exists(compose: PodmanCompose, name: str) -> bool:
29312942 return exit_code == 0
29322943
29332944
2934- async def create_pods (compose : PodmanCompose , args : argparse . Namespace ) -> None :
2945+ async def create_pods (compose : PodmanCompose ) -> None :
29352946 for pod in compose .pods :
29362947 if await pod_exists (compose , pod ["name" ]):
29372948 continue
29382949
29392950 podman_args = [
29402951 "create" ,
29412952 "--name=" + pod ["name" ],
2942- ] + args .pod_arg_list
2943- # if compose.podman_version and not strverscmp_lt(compose.podman_version, "3.4.0"):
2944- # podman_args.append("--infra-name={}_infra".format(pod["name"]))
2953+ ] + compose .resolve_pod_args ()
2954+
29452955 ports = pod .get ("ports" , [])
29462956 if isinstance (ports , str ):
29472957 ports = [ports ]
@@ -3074,7 +3084,7 @@ async def compose_up(compose: PodmanCompose, args: argparse.Namespace) -> int |
30743084 log .info ("recreating: done\n \n " )
30753085 # args.no_recreate disables check for changes (which is not implemented)
30763086
3077- await create_pods (compose , args )
3087+ await create_pods (compose )
30783088 exit_code = 0
30793089 for cnt in compose .containers :
30803090 if cnt ["_service" ] in excluded :
@@ -3318,7 +3328,7 @@ async def compose_ps(compose: PodmanCompose, args: argparse.Namespace) -> None:
33183328 "create a container similar to a service to run a one-off command" ,
33193329)
33203330async def compose_run (compose : PodmanCompose , args : argparse .Namespace ) -> None :
3321- await create_pods (compose , args )
3331+ await create_pods (compose )
33223332 compose .assert_services (args .service )
33233333 container_names = compose .container_names_by_service [args .service ]
33243334 container_name = container_names [0 ]
@@ -3363,7 +3373,7 @@ def compose_run_update_container_from_args(
33633373 compose : PodmanCompose , cnt : dict , args : argparse .Namespace
33643374) -> None :
33653375 # adjust one-off container options
3366- name0 = "{}_{}_tmp{}" . format ( compose .project_name , args .service , random .randrange (0 , 65536 ))
3376+ name0 = compose .format_name ( args .service , f'tmp { random .randrange (0 , 65536 )} ' )
33673377 cnt ["name" ] = args .name or name0
33683378 if args .entrypoint :
33693379 cnt ["entrypoint" ] = args .entrypoint
0 commit comments