
                             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J	r	  SSK
Jr  SSKJr  S	rS
rSrSrSr\R&                  " S/ SQ5      r\R&                  " S/ SQ5      rS rS rS rS rSS jrS rS rg)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                     U R                  S5      S:  a  gU R                  SS5      n[        U5      S:X  a  SUS   ;  a  [        U5      $ U S4$ )a_  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                     U R                  S5      n[        U5      S:X  a  SU4$ SUS   ;   d	  SUS   ;   a
  US   USS 4$ SU4$ )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                     U R                  SS5      nUS   R                  S5      n[        U5      S:X  a  US   OSnX#4$ )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   sD     ++c1
%8>>#&.Z1_q$$		r"   c                     [        U 5      u  pUc  [        S5      e[        U5      [        :  a  [        SR	                  [        5      5      e[        U5      u  p4U(       a  [        U5      u  pVSnU H4  n[        R                  " Xx5      b  M  [        SR	                  U5      5      e   Sn	U(       a1  [        R                  " X5      c  [        SR	                  U5      5      eU HH  n
U
(       d  [        S5      eSn[        R                  " X5      b  M0  [        S	R	                  U
5      5      e   U(       aV  [        U5      [        :  a  [        S
R	                  [        5      5      eSn[        R                  " X5      c  [        S5      egg)a?  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/*
:
;;_--
>EE"	$% % 3:>()(3NR'	%	5	=>EEhOQ 	Q (
 J*2
<
C
CH
MO O #iABBBO	xx+3
=
D
DY
OQ Q # 	
3x/!FMM
   'I	xx	'~&& ( 	r"   c                 b   [        U =(       d    [        5      n[        R                  R                  5       R	                  S5      nSR                  [        XE5      nU(       aL  U(       a  SnO U=(       d    [        nSR                  U5      nSR                  XqR                  SS5      U5      $ U$ )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>G*j4 4m&--m<jZc)BJOO	r"   c                 l    [         R                  " SSU R                  5       5      R                  S5      $ )a3  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                 T   SR                  U 5      nUR                  S5      (       d  [        SR                  S5      5      e[        R
                  " SR                  U5      5        [        R                  " U 5      nUS:w  a&  SR                  X!S9n[        R                  " X0U5      eg)	aQ  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"   