
    C0                        S r SSKJr  SSKJr  SSKJ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.    )absolute_import)division)unicode_literalsN)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   1   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'   6   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=   G   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/   r0   splitextscriptr   )packager   python_commandexec_str_ext
executables          r   _GenerateEntrypointrJ      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/   r0   dirnamerC   r'   r   )rD   
parent_dir	copy_codes      r   _PreparePackageEntryrP      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)r2   r3   r4   r5   r6   )	r   r-   r.   r   r
   r   r=   rP   rJ   )rR   main_packagecontainer_workdirrT   r2   r3   r4   r5   r6   is_training_prebuilt_image_base
dockerfiles              r   _MakeDockerfilerY      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)rC   package_pathrA   )rU   rT   rV   r2   r3   r4   r5    zRunning command: {})	input_strr   zN
        Docker failed with error code {code}.
        Command: {cmd}
        )coder%   )r/   r0   isfiler    _DEFAULT_SETUP_PATH_DEFAULT_REQUIREMENTS_PATH_DEFAULT_HOME_DEFAULT_WORKDIRr   Packagereplacesep	posixpathrY   r	   infor   r   ExecuteCommandImager-   r.   r   DockerError)rR   host_workdirmain_scriptoutput_image_namerA   requirementsr5   rV   rT   no_cachekwargstag_options
cache_argscommandhas_setup_pyr3   has_requirements_txtr2   home_dirwork_dirrU   rX   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__
__future__r   r   r   r   r/   ri   r   r-   googlecloudsdk.command_lib.air   )googlecloudsdk.command_lib.ai.custom_jobsr   $googlecloudsdk.command_lib.ai.dockerr   googlecloudsdk.corer	   	six.movesr
   rd   re   rb   rc   _AUTONAME_PREFIX_AUTOGENERATED_TAG_LENGTHr   r   r'   r=   rJ   rP   rY   r~   r   r   r   <module>r      s    B &  '  	  	  0 @ 6 # ! " 1 *  IF
" */)-"&*.&*"&?D,6$4 '+#'+#'#@N " "!%"U>r   