
                             d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlm	Z	 ddl
mZ ddlmZ d	Zd
ZdZdZdZ ej&                  dg d      Z ej&                  dg d      Zd Zd Zd Zd ZddZd Zd Zy)z(Common utilities to operate with Docker.    )absolute_import)division)unicode_literalsN)errors)
local_util)log      zcloudai-autogeneratedunnamedusPackage)scriptpackage_pathpython_moduleImage)namedefault_homedefault_workdirc                     | j                  d      dkD  ry| j                  dd      }t        |      dk(  rd|d   vrt        |      S | dfS )ao  Parses out the repository and tag from a Docker image name.

  Args:
    image_name: (str) The full name of an image, expected to be in a format of
      "repository[:tag]"

  Returns:
    A (repository, tag) tuple representing the parsed result.
    None repository means the image name is invalid; tag may be None if it isn't
    present in the given image name.
  :   )NN   /N)countrsplitlentuple)
image_namepartss     1lib/googlecloudsdk/command_lib/ai/docker/utils.py_ParseRepositoryTagr!   )   sW     cQ


C
#%Z1_E!H,<	T	    c                     | j                  d      }t        |      dk(  rd|fS d|d   v sd|d   v r
|d   |dd fS d|fS )a  Parses a repository to an optional hostname and a list of path compoentes.

  Args:
    repository_name: (str) A name made up of slash-separated path name
      components, optionally prefixed by a registry hostname.

  Returns:
    A (hostname, components) tuple representing the parsed result.
    The hostname will be None if it isn't present; the components is a list of
    each slash-separated part in the given repository name.
  r   r   N.r   r   )splitr   )repository_name
componentss     r    _ParseRepositoryHostr(   @   sb     $$S)*_JqMSJqM1a=*QR.((	z	r"   c                     | j                  dd      }|d   j                  d      }t        |      dk(  r|d   nd}||fS )a  Parses a registry hostname to a list of components and an optional port.

  Args:
    host: (str) The registry hostname supposed to comply with standard DNS
      rules, optionally be followed by a port number in the format like ":8080".

  Returns:
    A (hostcomponents, port) tuple representing the parsed result.
    The hostcomponents contains each dot-seperated component in the given
    hostname; port may be None if it isn't present.
  r   r   r   r$   r   N)r   r%   r   )hostr   hostcomponentsports       r    _ParseHostPortr-   Y   sF     ++c1
%8>>#&.Z1_q$$		r"   c                    t        |       \  }}|t        d      t        |      t        kD  rt        dj	                  t                    t        |      \  }}|r{t        |      \  }}d}|D ]2  }t        j                  ||      t        dj	                  |             d}	|r0t        j                  |	|      t        dj	                  |            |D ]A  }
|
st        d      d}t        j                  ||
      )t        d	j	                  |
             |rTt        |      t        kD  rt        d
j	                  t                    d}t        j                  ||      t        d      yy)aa  Validate the given image name is a valid repository/tag reference.

  As explained in
  https://docs.docker.com/engine/reference/commandline/tag/#extended-description,
  a valid repository/tag reference should following the below pattern:

  reference             := name [ ":" tag ]
  name                  := [hostname '/'] component ['/' component]*
  hostname              := hostcomponent ['.' hostcomponent]* [':' port-number]
  hostcomponent         := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
  port-number           := /[0-9]+/
  component             := alpha-numeric [separator alpha-numeric]*
  alpha-numeric         := /[a-z0-9]+/
  separator             := /[_.]|__|[-]*/

  tag                   := /[\w][\w.-]{0,127}/

  Args:
    image_name: (str) Full name of a Docker image.

  Raises:
    ValueError if the image name is not valid.
  Nz#Unable to parse repository and tag.z4Repository name must not be more than {} characters.z5^(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])$z.Invalid hostname/port "{}" in repository name.z^[0-9]+$z(Empty path component in repository name.z)^[a-z0-9]+(?:(?:[._]|__|[-]*)[a-z0-9]+)*$z/Invalid path component "{}" in repository name.z-Tag name must not be more than {} characters.z^[\w][\w.-]{0,127}$zInvalid tag.)
r!   
ValueErrorr   _MAX_REPOSITORY_LENGTHformatr(   r-   rematch_MAX_TAG_LENGTH)r   
repositorytaghostnamepath_componentsr+   r,   hostcomponent_regexhostcomponent
port_regex	componentcomponent_regex	tag_regexs                r    ValidateRepositoryAndTagr?   m   s   0 (
3/*c
:
;;_--
>EE"	$% % 3:>(O)(3NDR'	%}	5	=>EEhOQ 	Q (
 JT*2
<
C
CH
MO O #iABBBO	xx+3
=
D
DY
OQ Q # 	
3x/!FMM
   'I	xx	3'~&& ( 	r"   c                 >   t        | xs t              }t        j                  j                         j	                  d      }dj                  t        ||      }|rC|rd}n|xs t        }dj                  |      }dj                  ||j                  dd      |      S |S )zAGenerate a name for the Docker image built by AI platform gcloud.z%Y%m%d.%H.%M.%S.%fz{}/{}:{}zgcr.ioz{}-docker.pkg.devz{}/{}/{}r   r   )	_SanitizeRepositoryName_DEFAULT_IMAGE_NAMEdatetimenowstrftimer1   _AUTONAME_PREFIX_DEFAULT_REPO_REGIONreplace)		base_nameprojectregionis_gcrsanitized_namer6   r   r5   region_prefixs	            r    GenerateImageNamerO      s    *9+K8KL. 	(()=>#  !1>3G*j4 4m&--m<jZc)BJOO	r"   c                 j    t        j                  dd| j                               j                  d      S )aK  Sanitizes the given name to make it valid as an image repository.

  As explained in
  https://docs.docker.com/engine/reference/commandline/tag/#extended-description,
  Valid name may contain only lowercase letters, digits and separators.
  A separator is defined as a period, one or two underscores, or one or more
  dashes. A name component may not start or end with a separator.

  This method will replace the illegal characters in the given name and strip
  starting and ending separator characters.

  Args:
    name: str, the name to sanitize.

  Returns:
    A sanitized name.
  z[._][._]+|[^a-z0-9._-]+r$   z._-)r2   sublowerstrip)r   s    r    rA   rA      s)    $ 
)3

	=	C	CE	JJr"   c                 L   dj                  |       }|j                  d      st        dj                  d            t	        j
                  dj                  |             t        j                  |       }|dk7  r*dj                  ||      }t        j                  || |      y)	aa  Executes Docker CLI commands in subprocess.

  Just calls local_util.ExecuteCommand(cmd,...) and raises error for non-zero
  exit code.

  Args:
    command: (List[str]) Strings to send in as the command.

  Raises:
    ValueError: The input command is not a docker command.
    DockerError: An error occurred when executing the given docker command.
   dockerz`{}` is not a Docker commandzRunning command: {}r   zN
        Docker failed with error code {code}.
        Command: {cmd}
        )codecmdN)
join
startswithr/   r1   r   infor   ExecuteCommandr   DockerError)commandcommand_strreturn_code	error_msgs       r    ExecuteDockerCommandrb      s     !+				)
3::8D
EE(( ''45))'2+A F+  / 
 

Y
== r"   )NNNF)__doc__
__future__r   r   r   collectionsrC   r2   googlecloudsdk.command_lib.air   )googlecloudsdk.command_lib.ai.custom_jobsr   googlecloudsdk.corer   r0   r4   rF   rB   rG   
namedtupler   r   r!   r(   r-   r?   rO   rA   rb    r"   r    <module>rk      s    / &  '   	 0 @ # *   
 +
 
 !LNwJ	L.2(B'J$K*>r"   