2020import operator
2121import platform
2222import subprocess
23- from subprocess import check_call
23+ from subprocess import check_call , check_output
2424from contextlib import contextmanager
2525from base64 import b64encode
2626import logging
@@ -550,12 +550,14 @@ def filter(self, path, prefix=None):
550550 rules = self ._rules
551551
552552 def norm_path (path , root , filename = None ):
553+ op = os .path .join (root , filename ) if filename else root
553554 p = os .path .relpath (root , path )
554555 if prefix :
555- p = os .path .normpath (os .path .join (prefix , p ))
556- p = os .path .join (p , filename ) if filename else p + os .sep
557- op = os .path .join (root , filename ) if filename else root
558- return op , p
556+ p = os .path .join (prefix , p )
557+ if filename :
558+ p = os .path .normpath (os .path .join (p , filename ))
559+ return op , p
560+ return op , p + os .sep
559561
560562 def apply (path ):
561563 d = True
@@ -806,6 +808,34 @@ def install_pip_requirements(query, requirements_file):
806808 runtime = query .runtime
807809 artifacts_dir = query .artifacts_dir
808810 docker = query .docker
811+ docker_image_tag_id = None
812+
813+ if docker :
814+ docker_file = docker .docker_file
815+ docker_image = docker .docker_image
816+ docker_build_root = docker .docker_build_root
817+
818+ if docker_image :
819+ ok = False
820+ while True :
821+ output = check_output (docker_image_id_command (docker_image ))
822+ if output :
823+ docker_image_tag_id = output .decode ().strip ()
824+ log .debug ("DOCKER TAG ID: %s -> %s" ,
825+ docker_image , docker_image_tag_id )
826+ ok = True
827+ if ok :
828+ break
829+ docker_cmd = docker_build_command (
830+ build_root = docker_build_root ,
831+ docker_file = docker_file ,
832+ tag = docker_image ,
833+ )
834+ check_call (docker_cmd )
835+ ok = True
836+ elif docker_file or docker_build_root :
837+ raise ValueError ('docker_image must be specified '
838+ 'for a custom image future references' )
809839
810840 working_dir = os .getcwd ()
811841
@@ -824,6 +854,7 @@ def install_pip_requirements(query, requirements_file):
824854 '--requirement={}' .format (requirements_filename ),
825855 ]
826856 if docker :
857+ with_ssh_agent = docker .with_ssh_agent
827858 pip_cache_dir = docker .docker_pip_cache
828859 if pip_cache_dir :
829860 if isinstance (pip_cache_dir , str ):
@@ -839,8 +870,10 @@ def install_pip_requirements(query, requirements_file):
839870 chown_mask , '.' ])]
840871 shell_command = [' ' .join (shell_command )]
841872 check_call (docker_run_command (
842- '.' , shell_command , runtime , shell = True ,
843- pip_cache_dir = pip_cache_dir
873+ '.' , shell_command , runtime ,
874+ image = docker_image_tag_id ,
875+ shell = True , ssh_agent = with_ssh_agent ,
876+ pip_cache_dir = pip_cache_dir ,
844877 ))
845878 else :
846879 cmd_log .info (shlex_join (pip_command ))
@@ -851,13 +884,29 @@ def install_pip_requirements(query, requirements_file):
851884 yield temp_dir
852885
853886
854- def docker_build_command ( build_root , docker_file = None , tag = None ):
887+ def docker_image_id_command ( tag ):
855888 """"""
889+ docker_cmd = ['docker' , 'images' , '--format={{.ID}}' , tag ]
890+ cmd_log .info (shlex_join (docker_cmd ))
891+ log_handler and log_handler .flush ()
892+ return docker_cmd
893+
894+
895+ def docker_build_command (tag = None , docker_file = None , build_root = False ):
896+ """"""
897+ if not (build_root or docker_file ):
898+ raise ValueError ('docker_build_root or docker_file must be provided' )
899+
856900 docker_cmd = ['docker' , 'build' ]
857- if docker_file :
858- docker_cmd .extend (['--file' , docker_file ])
901+
859902 if tag :
860903 docker_cmd .extend (['--tag' , tag ])
904+ else :
905+ raise ValueError ('docker_image must be specified' )
906+ if not build_root :
907+ build_root = os .path .dirname (docker_file )
908+ if docker_file :
909+ docker_cmd .extend (['--file' , docker_file ])
861910 docker_cmd .append (build_root )
862911
863912 cmd_log .info (shlex_join (docker_cmd ))
@@ -866,9 +915,12 @@ def docker_build_command(build_root, docker_file=None, tag=None):
866915
867916
868917def docker_run_command (build_root , command , runtime ,
869- image = None , shell = None , interactive = False ,
870- pip_cache_dir = None ):
918+ image = None , shell = None , ssh_agent = False ,
919+ interactive = False , pip_cache_dir = None ):
871920 """"""
921+ if platform .system () not in ('Linux' , 'Darwin' ):
922+ raise RuntimeError ("Unsupported platform for docker building" )
923+
872924 docker_cmd = ['docker' , 'run' , '--rm' ]
873925
874926 if interactive :
@@ -883,27 +935,28 @@ def docker_run_command(build_root, command, runtime,
883935 '-v' , '{}/.ssh/known_hosts:/root/.ssh/known_hosts:z' .format (home ),
884936 ])
885937
886- if platform .system () == 'Darwin' :
887- # https://docs.docker.com/docker-for-mac/osxfs/#ssh-agent-forwarding
888- docker_cmd .extend ([
889- '--mount' , 'type=bind,'
890- 'src=/run/host-services/ssh-auth.sock,'
891- 'target=/run/host-services/ssh-auth.sock' ,
892- '-e' , 'SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock' ,
893- ])
894- elif platform .system () == 'Linux' :
895- sock = os .environ ['SSH_AUTH_SOCK' ] # TODO: Handle missing env var
896- docker_cmd .extend ([
897- '-v' , '{}:/tmp/ssh_sock:z' .format (sock ),
898- '-e' , 'SSH_AUTH_SOCK=/tmp/ssh_sock' ,
899- ])
938+ if ssh_agent :
939+ if platform .system () == 'Darwin' :
940+ # https://docs.docker.com/docker-for-mac/osxfs/#ssh-agent-forwarding
941+ docker_cmd .extend ([
942+ '--mount' , 'type=bind,'
943+ 'src=/run/host-services/ssh-auth.sock,'
944+ 'target=/run/host-services/ssh-auth.sock' ,
945+ '-e' , 'SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock' ,
946+ ])
947+ elif platform .system () == 'Linux' :
948+ sock = os .environ ['SSH_AUTH_SOCK' ] # TODO: Handle missing env var
949+ docker_cmd .extend ([
950+ '-v' , '{}:/tmp/ssh_sock:z' .format (sock ),
951+ '-e' , 'SSH_AUTH_SOCK=/tmp/ssh_sock' ,
952+ ])
953+
954+ if platform .system () == 'Linux' :
900955 if pip_cache_dir :
901956 pip_cache_dir = os .path .abspath (pip_cache_dir )
902957 docker_cmd .extend ([
903958 '-v' , '{}:/root/.cache/pip:z' .format (pip_cache_dir ),
904959 ])
905- else :
906- raise RuntimeError ("Unsupported platform for docker building" )
907960
908961 if not image :
909962 image = 'lambci/lambda:build-{}' .format (runtime )
0 commit comments