17
17
18
18
logger = logging .getLogger ("podman.containers" )
19
19
20
- NAMED_VOLUME_PATTERN = re .compile (r' [a-zA-Z0-9][a-zA-Z0-9_.-]*' )
20
+ NAMED_VOLUME_PATTERN = re .compile (r" [a-zA-Z0-9][a-zA-Z0-9_.-]*" )
21
21
22
22
23
23
class CreateMixin : # pylint: disable=too-few-public-methods
@@ -375,7 +375,9 @@ def create(
375
375
payload = api .prepare_body (payload )
376
376
377
377
response = self .client .post (
378
- "/containers/create" , headers = {"content-type" : "application/json" }, data = payload
378
+ "/containers/create" ,
379
+ headers = {"content-type" : "application/json" },
380
+ data = payload ,
379
381
)
380
382
response .raise_for_status (not_found = ImageNotFound )
381
383
@@ -396,14 +398,34 @@ def _convert_env_list_to_dict(env_list):
396
398
Raises:
397
399
ValueError: If any environment variable is not in the correct format
398
400
"""
401
+ if not isinstance (env_list , list ):
402
+ raise TypeError (f"Expected list, got { type (env_list ).__name__ } " )
403
+
399
404
env_dict = {}
405
+
400
406
for env_var in env_list :
401
- if '=' not in env_var :
407
+ if not isinstance (env_var , str ):
408
+ raise TypeError (
409
+ f"Environment variable must be a string, "
410
+ f"got { type (env_var ).__name__ } : { repr (env_var )} "
411
+ )
412
+
413
+ # Handle empty strings
414
+ if not env_var .strip ():
415
+ raise ValueError (f"Environment variable cannot be empty" )
416
+ if "=" not in env_var :
402
417
raise ValueError (
403
418
f"Environment variable '{ env_var } ' is not in the correct format. "
404
419
"Expected format: 'KEY=value'"
405
420
)
406
- key , value = env_var .split ('=' , 1 ) # Split on first '=' only
421
+ key , value = env_var .split ("=" , 1 ) # Split on first '=' only
422
+
423
+ # Validate key is not empty
424
+ if not key .strip ():
425
+ raise ValueError (
426
+ f"Environment variable at index { i } has empty key: '{ env_var } '"
427
+ )
428
+
407
429
env_dict [key ] = value
408
430
return env_dict
409
431
@@ -507,9 +529,9 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
507
529
try :
508
530
return int (size )
509
531
except ValueError as bad_size :
510
- mapping = {'b' : 0 , 'k' : 1 , 'm' : 2 , 'g' : 3 }
511
- mapping_regex = '' .join (mapping .keys ())
512
- search = re .search (rf' ^(\d+)([{ mapping_regex } ])$' , size .lower ())
532
+ mapping = {"b" : 0 , "k" : 1 , "m" : 2 , "g" : 3 }
533
+ mapping_regex = "" .join (mapping .keys ())
534
+ search = re .search (rf" ^(\d+)([{ mapping_regex } ])$" , size .lower ())
513
535
if search :
514
536
return int (search .group (1 )) * (1024 ** mapping [search .group (2 )])
515
537
raise TypeError (
@@ -532,7 +554,9 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
532
554
"cni_networks" : [pop ("network" )],
533
555
"command" : args .pop ("command" , args .pop ("cmd" , None )),
534
556
"conmon_pid_file" : pop ("conmon_pid_file" ), # TODO document, podman only
535
- "containerCreateCommand" : pop ("containerCreateCommand" ), # TODO document, podman only
557
+ "containerCreateCommand" : pop (
558
+ "containerCreateCommand"
559
+ ), # TODO document, podman only
536
560
"devices" : [],
537
561
"dns_option" : pop ("dns_opt" ),
538
562
"dns_search" : pop ("dns_search" ),
@@ -581,7 +605,9 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
581
605
"rootfs_propagation" : pop ("rootfs_propagation" ),
582
606
"sdnotifyMode" : pop ("sdnotifyMode" ), # TODO document, podman only
583
607
"seccomp_policy" : pop ("seccomp_policy" ), # TODO document, podman only
584
- "seccomp_profile_path" : pop ("seccomp_profile_path" ), # TODO document, podman only
608
+ "seccomp_profile_path" : pop (
609
+ "seccomp_profile_path"
610
+ ), # TODO document, podman only
585
611
"secrets" : [], # TODO document, podman only
586
612
"selinux_opts" : pop ("security_opt" ),
587
613
"shm_size" : to_bytes (pop ("shm_size" )),
@@ -597,7 +623,9 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
597
623
"unified" : pop ("unified" ), # TODO document, podman only
598
624
"unmask" : pop ("unmasked_paths" ), # TODO document, podman only
599
625
"use_image_hosts" : pop ("use_image_hosts" ), # TODO document, podman only
600
- "use_image_resolve_conf" : pop ("use_image_resolve_conf" ), # TODO document, podman only
626
+ "use_image_resolve_conf" : pop (
627
+ "use_image_resolve_conf"
628
+ ), # TODO document, podman only
601
629
"user" : pop ("user" ),
602
630
"version" : pop ("version" ),
603
631
"volumes" : [],
@@ -619,9 +647,15 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
619
647
params ["log_configuration" ]["driver" ] = args ["log_config" ].get ("Type" )
620
648
621
649
if "Config" in args ["log_config" ]:
622
- params ["log_configuration" ]["path" ] = args ["log_config" ]["Config" ].get ("path" )
623
- params ["log_configuration" ]["size" ] = args ["log_config" ]["Config" ].get ("size" )
624
- params ["log_configuration" ]["options" ] = args ["log_config" ]["Config" ].get ("options" )
650
+ params ["log_configuration" ]["path" ] = args ["log_config" ]["Config" ].get (
651
+ "path"
652
+ )
653
+ params ["log_configuration" ]["size" ] = args ["log_config" ]["Config" ].get (
654
+ "size"
655
+ )
656
+ params ["log_configuration" ]["options" ] = args ["log_config" ][
657
+ "Config"
658
+ ].get ("options" )
625
659
args .pop ("log_config" )
626
660
627
661
for item in args .pop ("mounts" , []):
@@ -648,7 +682,7 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:
648
682
if _k in bool_options and v is True :
649
683
options .append (option_name )
650
684
elif _k in regular_options :
651
- options .append (f' { option_name } ={ v } ' )
685
+ options .append (f" { option_name } ={ v } " )
652
686
elif _k in simple_options :
653
687
options .append (v )
654
688
@@ -676,7 +710,9 @@ def parse_host_port(_container_port, _protocol, _host):
676
710
result .append (port_map )
677
711
elif isinstance (_host , list ):
678
712
for host_list in _host :
679
- host_list_result = parse_host_port (_container_port , _protocol , host_list )
713
+ host_list_result = parse_host_port (
714
+ _container_port , _protocol , host_list
715
+ )
680
716
result .extend (host_list_result )
681
717
elif isinstance (_host , dict ):
682
718
_host_port = _host .get ("port" )
@@ -750,12 +786,12 @@ def parse_host_port(_container_port, _protocol, _host):
750
786
751
787
for item in args .pop ("volumes" , {}).items ():
752
788
key , value = item
753
- extended_mode = value .get (' extended_mode' , [])
789
+ extended_mode = value .get (" extended_mode" , [])
754
790
if not isinstance (extended_mode , list ):
755
791
raise ValueError ("'extended_mode' value should be a list" )
756
792
757
793
options = extended_mode
758
- mode = value .get (' mode' )
794
+ mode = value .get (" mode" )
759
795
if mode is not None :
760
796
if not isinstance (mode , str ):
761
797
raise ValueError ("'mode' value should be a str" )
@@ -770,10 +806,10 @@ def parse_host_port(_container_port, _protocol, _host):
770
806
params ["volumes" ].append (volume )
771
807
else :
772
808
mount_point = {
773
- "destination" : value [' bind' ],
809
+ "destination" : value [" bind" ],
774
810
"options" : options ,
775
811
"source" : key ,
776
- "type" : ' bind' ,
812
+ "type" : " bind" ,
777
813
}
778
814
params ["mounts" ].append (mount_point )
779
815
@@ -818,7 +854,8 @@ def parse_host_port(_container_port, _protocol, _host):
818
854
819
855
if len (args ) > 0 :
820
856
raise TypeError (
821
- "Unknown keyword argument(s): " + " ," .join (f"'{ k } '" for k in args .keys ())
857
+ "Unknown keyword argument(s): "
858
+ + " ," .join (f"'{ k } '" for k in args .keys ())
822
859
)
823
860
824
861
return params
0 commit comments