
    /                         S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJr  SSKJr  SrS	rS
rSrSrSrS rS rSS jr      SS jrSS jrS r     SS jr      SS jrg)z;Functions required to interact with Docker to build images.    N)errors)
local_util)utils)log)shlex_quotez/homez/usr/app
./setup.py./requirements.txtzcloudai-autogenerated   c                 6    Sn[         R                  " X5      SL$ )z<Checks whether the image is pre-built by Vertex AI training.zY^(us|europe|asia)-docker.pkg.dev/vertex-ai/training/(tf|scikit-learn|pytorch|xgboost)-.+$N)re	fullmatch)
image_nameprebuilt_image_name_regexs     1lib/googlecloudsdk/command_lib/ai/docker/build.py_IsVertexTrainingPrebuiltImager   &   s"     H 
/	<D	HH    c                     U (       a  S$ S$ )znReturns a Dockerfile entry that removes `sitecustomize` if it's Vertex AI Training pre-built container images.zRUN rm -rf /var/sitecustomize  )is_prebuilt_images    r   _SitecustomizeRemovalEntryr   .   s    ,=	(E2Er   c                     SR                  [        R                  " X/5      5      nUb1  SR                  UR	                  S5      5      nSR                  XC5      $ U$ )zReturns a Dockerfile entry that copies a file from host to container.

Args:
  from_path: (str) Path of the source in host.
  to_path: (str) Path to the destination in the container.
  comment: (str) A comment explaining the copy operation.
zCOPY {}
z
# 
z# {}
{})formatjsondumpsjoinsplit)	from_pathto_pathcommentcmdformatted_comments        r   _GenerateCopyCommandr$   3   sU     	4::y&:;<#GMM$$78.44	*r   c                    SnU (       a  SOSnUb2  U[         R                  " SR                  [        USSS9U5      5      -  nUb2  U[         R                  " SR                  [        US	S
S9U5      5      -  nUbd  U H^  n[        R
                  R                  U5      n	U[         R                  " SR                  [        X5      U[        U	5      5      5      -  nM`     Ub;  U H5  n
U[         R                  " SR                  U[        U
5      5      5      -  nM7     Ub&  U H   nUSR                  [        X5      5      -  nM"     U$ )a  Returns the Dockerfile entries required to install dependencies.

Args:
  is_prebuilt_image: (bool) Whether the base image is pre-built and provided
    by Vertex AI.
  requirements_path: (str) Path that points to a requirements.txt file
  setup_path: (str) Path that points to a setup.py
  extra_requirements: (List[str]) Required dependencies to be installed from
    remote resource archives.
  extra_packages: (List[str]) User custom dependency packages to install.
  extra_dirs: (List[str]) Directories other than the work_dir required.
r   pip3pipz<
        {}
        RUN {} install --no-cache-dir .
        r   z:Found setup.py file, thus copy it to the docker container.r!   zP
        {}
        RUN {} install --no-cache-dir -r ./requirements.txt
        r	   z:Found requirements.txt file, thus to the docker container.z=
        {}
        RUN {} install --no-cache-dir {}
        z<
        RUN {} install --no-cache-dir --upgrade {}
        
{}
)textwrapdedentr   r$   ospathbasenamer   )r   requirements_path
setup_pathextra_requirementsextra_packages
extra_dirsretpip_versionextrapackage_namerequirement	directorys               r   _DependencyEntriesr:   D   se   $ 	#++8??  F T  C "8??  F !$T  C WW%%e,l	X__  F 5{%'( (c   #)	X__ F;K 89; ;c *
 		X__1)GHHc   
*r   c                 P   U(       a  SOSnU R                   b$  [        R                  " USU R                   /5      nOZ[        R                  R                  U R                  5      u  pEUS:X  a  U/OS/n[        R                  " X`R                  /-   5      nSR                  U5      $ )a2  Generates dockerfile entry to set the container entrypoint.

Args:
  package: (Package) Represents the main application copied to the container.
  is_prebuilt_image: (bool) Whether the base image is pre-built and provided
    by Vertex AI.

Returns:
  A string with Dockerfile directives to set ENTRYPOINT
python3pythonz-mz.pyz	/bin/bashz
ENTRYPOINT {})python_moduler   r   r,   r-   splitextscriptr   )packager   python_commandexec_str_ext
executables          r   _GenerateEntrypointrG      s     !29x. &zz>41F1FGHHWWgnn-FA%(E\.!}Jzz*'778H		!	!(	++r   c                     [         R                  R                  U R                  5      =(       d    Sn[	        UUSS9nSR                  U5      $ )ad  Returns the Dockerfile entries required to append at the end before entrypoint.

Including:
- copy the parent directory of the main executable into a docker container.
- inject an entrypoint that executes a script or python module inside that
  directory.

Args:
  package: (Package) Represents the main application copied to and run in the
    container.
.z4Copy the source directory into the docker container.r(   r)   )r,   r-   dirnamer@   r$   r   )rA   
parent_dir	copy_codes      r   _PreparePackageEntryrM      sD     www~~.5#*"DF)
 
	##r   c	           
         [        U 5      n	[        R                  " SR                  U [	        U5      [	        U5      S95      n
U
[        U	5      -  n
U
[        U	UUUUUS9-  n
U
[        U5      -  n
U
[        UU	5      -  n
U
$ )aC  Generates a Dockerfile for building an image.

It builds on a specified base image to create a container that:
- installs any dependency specified in a requirements.txt or a setup.py file,
and any specified dependency packages existing locally or found from PyPI
- copies all source needed by the main module, and potentially injects an
entrypoint that, on run, will run that main module

Args:
  base_image: (str) ID or name of the base image to initialize the build
    stage.
  main_package: (Package) Represents the main application to execute.
  container_workdir: (str) Working directory in the container.
  container_home: (str) $HOME directory in the container.
  requirements_path: (str) Rath of a requirements.txt file.
  setup_path: (str) Path of a setup.py file
  extra_requirements: (List[str]) Required dependencies to install from PyPI.
  extra_packages: (List[str]) User custom dependency packages to install.
  extra_dirs: (List[str]) Directories other than the work_dir required to be
    in the container.

Returns:
  A string that represents the content of a Dockerfile.
ab  
      FROM {base_image}
      # The directory is created by root. This sets permissions so that any user can
      # access the folder.
      RUN mkdir -m 777 -p {workdir} {container_home}
      WORKDIR {workdir}
      ENV HOME={container_home}

      # Keeps Python from generating .pyc files in the container
      ENV PYTHONDONTWRITEBYTECODE=1
      )
base_imageworkdircontainer_home)r/   r0   r1   r2   r3   )	r   r*   r+   r   r   r   r:   rM   rG   )rO   main_packagecontainer_workdirrQ   r/   r0   r1   r2   r3   is_training_prebuilt_image_base
dockerfiles              r   _MakeDockerfilerV      s    B %C:$N! 
 
 &/0$^4  67* *+JKK*"%)+# * $\22*#L$CE E* 
r   c
                    SU/nU	(       a  S/O/ nSS/U-   U-   SSU/-   n[         R                  R                  [         R                  R                  U[        5      5      nU(       a  [        OSn[         R                  R                  [         R                  R                  U[
        5      5      nU(       a  [
        OSnU=(       d    [        nU=(       d    [        n[        R                  " UR                  [         R                  [        R                  5      UR                  [         R                  [        R                  5      US9n[        U 4UUUUUUUS	.U
D6nS
R                  U5      n[        R                  " SR!                  U5      5        ["        R$                  " UUS9nUS:X  a  [        R&                  " UUU5      $ [(        R*                  " SR!                  UUS95      n[,        R.                  " UUU5      e)a|  Builds a Docker image.

Generates a Dockerfile and passes it to `docker build` via stdin.
All output from the `docker build` process prints to stdout.

Args:
  base_image: (str) ID or name of the base image to initialize the build
    stage.
  host_workdir: (str) A path indicating where all the required sources
    locates.
  main_script: (str) A string that identifies the executable script under the
    working directory.
  output_image_name: (str) Name of the built image.
  python_module: (str) Represents the executable main_script in form of a
    python module, if applicable.
  requirements: (List[str]) Required dependencies to install from PyPI.
  extra_packages: (List[str]) User custom dependency packages to install.
  container_workdir: (str) Working directory in the container.
  container_home: (str) the $HOME directory in the container.
  no_cache: (bool) Do not use cache when building the image.
  **kwargs: Other arguments to pass to underlying method that generates the
    Dockerfile.

Returns:
  A Image class that contains info of the built image.

Raises:
  DockerError: An error occurred when executing `docker build`
z-tz
--no-cachedockerbuildz--rmz-f-N)r@   package_pathr>   )rR   rQ   rS   r/   r0   r1   r2    zRunning command: {})	input_strr   zN
        Docker failed with error code {code}.
        Command: {cmd}
        )coder"   )r,   r-   isfiler   _DEFAULT_SETUP_PATH_DEFAULT_REQUIREMENTS_PATH_DEFAULT_HOME_DEFAULT_WORKDIRr   Packagereplacesep	posixpathrV   r   infor   r   ExecuteCommandImager*   r+   r   DockerError)rO   host_workdirmain_scriptoutput_image_namer>   requirementsr2   rS   rQ   no_cachekwargstag_options
cache_argscommandhas_setup_pyr0   has_requirements_txtr/   home_dirwork_dirrR   rU   joined_commandreturn_code	error_msgs                            r   
BuildImager{      s   R ()+!)~r*w (),2E<+HI' \;N OP,&2"*ggll<!;<>4H0d,}(2"2(   7''	>!#,
 	 )%#	 		* 88G$.(( ''78))'ZH+A;;((H== ! FF8:I 

Y
==r   )N)FNNNNN)F)NNNNN)NNNNNT)__doc__r   r,   rf   r   r*   googlecloudsdk.command_lib.air   )googlecloudsdk.command_lib.ai.custom_jobsr   $googlecloudsdk.command_lib.ai.dockerr   googlecloudsdk.corer   	six.movesr   ra   rb   r_   r`   _AUTONAME_PREFIX_AUTOGENERATED_TAG_LENGTHr   r   r$   r:   rG   rM   rV   r{   r   r   r   <module>r      s    B  	  	  0 @ 6 # ! " 1 *  IF
" */)-"&*.&*"&?D,6$4 '+#'+#'#@N " "!%"U>r   