
    .                         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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d	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlZd Z	 ddZd Z	 	 ddZ	 ddZy)z5This package provides tools for saving docker images.    )absolute_import)division)print_functionN)docker_name)docker_image)save)	v1_compat)docker_digest)docker_http)	v2_compatc                     	 | j                  |      S # t        $ r) | j                  |      }t        j                  |      cY S w xY wN)diff_id
ValueErroruncompressed_layerr
   SHA256)v1_imgblobunzippeds      6lib/third_party/containerregistry/client/v2_2/save_.py_diff_idr   (   sF    *>>$	 *((.H))*s    /AAc           
         fd}|xs i }g }t        j                  |       D ]  \  }}t        j                  |j	                         j                  d      d      } ||dz   |j	                                t        j                  |j	                               }t        |j                  di       j                  dg             }	|j                  |      }
|
s/t        j                  |      }t        j                  |      }
|
||<   |dz   t        |
j                  |
j!                                     D cg c]H  }t#        |
|      |	v r8t        j                  |
j                  |            j                  d      s|dz   J c}t%        |      gd	}i }t        j                  |j'                               }|d
   }|D ]2  }|d   t(        j*                  k(  s|j-                  |d         }|||<   4 |r||d<   |j/                  |        t1        j2                  |        |dt        j4                  |d             yc c}w )ah  Produce a "docker save" compatible tarball from the DockerImages.

  Args:
    tag_to_image: A dictionary of tags to the images they label.
    tar: the open tarfile into which we are writing the image tarball.
    tag_to_v1_image: A dictionary of tags to the v1 form of the images
        they label.  If this isn't provided, the image is simply converted.
  c                     |j                  d      }t        j                  |       }t        |      |_        j                  |t        j                  |             y )Nutf8)tarinfofileobj)encodetarfileTarInfolensizeaddfileioBytesIO)filenamecontentscontents_bytesinfotars       r   add_filez%multi_image_tarball.<locals>.add_file>   sD    __V,N??8$DN#DIKKbjj&@KA    r    z.jsonrootfsdiff_ids	throwawayz
/layer.tar)ConfigLayersRepoTagslayers	mediaTypedigestLayerSourcesmanifest.jsonT)	sort_keysN)six	iteritemsr
   r   config_filer   jsonloadssetgetr   	V2FromV22r	   V1FromV2reversedancestrytopr   strmanifestr   FOREIGN_LAYER_MIMEdigest_to_diff_idappendv1_savemulti_image_tarballdumps)tag_to_imager)   tag_to_v1_imager*   	manifeststagimager5   cfgdiffsr   v2_imglayer_idrF   layer_sourcesinput_manifestinput_layersinput_layerr   s    `                 r   rK   rK   0   s   B $)r/ )mmL1lsE!!%"3"3"5"<"<V"DbIFVgu0023
**U&&(
)C"%))*b9:E  %F""5)f!!&)f#oc
 W
 %V__VZZ\%BC	
 D)U2

6;;x0155kB |# D	
 XJH MZZ 01N!(+L#	[	![%C%C	C))+h*?@!,g $
 !.h~XS 2Z 
os3
?DJJyDAB;
s   6AIc                 "    t        | |i|i        y)zProduce a "docker save" compatible tarball from the DockerImage.

  Args:
    name: The tag name to write into repositories and manifest.json
    image: a docker image to save.
    tar: the open tarfile into which we are writing the image tarball.
  N)rK   )namerQ   r)   s      r   tarballr\      s     tUmS"-r+   c           	      $    d fd}d d }t         j                  j                  |      5 }i }t        j                  j                  |d      }|j                  | fdd      }	|||	<   |j                  t        j                  j                  |d	       fd
d       |j                  t        j                  j                  |d       fdd       d}
g }t         j                               D ]E  }t        j                  j                  |d|
z        }t        j                  j                  |d|
z        }|dd j                  d      }|j                  |d |      }	|||	<   t        |      }|rt        j                  j                  ||      }t        j                  j                  |      r" |||      r|j                  ||      }	|||	<   nH|j                  || j                  ||      }	|||	<   n#|j                  | j                  |      }	|||	<   |j                  ||f       |
dz  }
H t         j                  j                  |      D ]  }|j                           	 ddd       ||fS # 1 sw Y   fS xY w)a  Produce a FromDisk compatible file layout under the provided directory.

  After calling this, the following filesystem will exist:
    directory/
      config.json   <-- only *.json, the image's config
      digest        <-- sha256 digest of the image's manifest
      manifest.json <-- the image's manifest
      001.tar.gz    <-- the first layer's .tar.gz filesystem delta
      001.sha256    <-- the sha256 of 1.tar.gz with a "sha256:" prefix.
      ...
      N.tar.gz      <-- the Nth layer's .tar.gz filesystem delta
      N.sha256      <-- the sha256 of N.tar.gz with a "sha256:" prefix.

  We pad layer indices to only 3 digits because of a known ceiling on the number
  of filesystem layers Docker supports.

  Args:
    image: a docker image to save.
    directory: an existing empty directory under which to save the layout.
    threads: the number of threads to use when performing the upload.
    cache_directory: directory that stores file cache.

  Returns:
    A tuple whose first element is the path to the config file, and whose second
    element is an ordered list of tuples whose elements are the filenames
    containing: (.sha256, .tar.gz) respectively.
  c                     t        j                  | d      5 }|j                   ||             d d d        y # 1 sw Y   y xY wNwbr#   openwriter[   accessorargfs       r   
write_filezfast.<locals>.write_file   .    	u	gghsm 
			   8Ac                 ,     |||        ||        y r    )r[   re   rf   cached_layerlinkrh   s       r   write_file_and_storez"fast.<locals>.write_file_and_store   s    |Xs+tr+   c                     	 t        j                  | |       y# t        $ rU}|j                  t        j                  k(  r,t        j
                  |       t        j                  | |       n|Y d}~yd}~ww xY w)a  Creates a symbolic link dest pointing to source.

    Unlinks first to remove "old" layers if needed
    e.g., image A latest has layers 1, 2 and 3
    after a while it has layers 1, 2 and 3'.
    Since in both cases the layers are named 001, 002 and 003,
    unlinking promises the correct layers are linked in the image directory.

    Args:
      source: image directory source.
      dest: image directory destination.
    N)ossymlinkOSErrorerrnoEEXISTunlink)sourcedestes      r   rn   zfast.<locals>.link   sX    jj 	
ELL	 
		$


64  	!s    	A7AA22A7c                     t        j                  | d      5 }t        j                  |j	                         d      }d d d        ||k(  S # 1 sw Y   |k(  S xY w)Nrbr,   )r#   rb   r
   r   read)rm   r5   rg   current_digests       r   validzfast.<locals>.valid   sK    	u	%$++AFFHb9n 
&V## 
&V##s   %A		Amax_workersconfig.jsonc                 B    j                         j                  d      S Nr   r;   r   unusedrQ   s    r   <lambda>zfast.<locals>.<lambda>       u'8'8':'A'A&'Ir+   r   r5   c                 B    j                         j                  d      S r   r5   r   r   s    r   r   zfast.<locals>.<lambda>       5<<>#8#8#@r+   r7   c                 B    j                         j                  d      S r   rF   r   r   s    r   r   zfast.<locals>.<lambda>       5>>#3#:#:6#Br+   r   z%03d.tar.gz%03d.sha256   Nr   c                 *    | dd  j                  d      S Nr   r   r   )r   s    r   r   zfast.<locals>.<lambda>   s    tABxv.r+      )
concurrentfuturesThreadPoolExecutorrq   pathjoinsubmitrB   	fs_layersr   rE   existsr   rI   as_completedresult)rQ   	directorythreadscache_directoryro   r~   executorfuture_to_paramsr;   rg   idxr3   r   
layer_namedigest_namer5   
digest_strrm   futurern   rh   s   `                  @@r   fastr      s[   D

,$
 ,,,AX'',,y-8K
KI 	"A &QOOJY A@(LOOJY HB CF*+77<<	=3+>?jGGLLMC,?@kABxv&f
//


.
	a
 (qv;j	ww||OZ@77>>,'E,
,KoodL*=! *
1
oo2J

"L2! *
1
OOJ
EJJE(mm[*-.	Qhc; ,@ $$112BCmmo Da Bf v	g Bf v	s   IJJc                     d }t         j                  j                  |      5 }i }t        j                  j                  |d      }|j                  || fdd      }|||<   |j                  |t        j                  j                  |d       fdd       |j                  |t        j                  j                  |d       fd	d       d
}g }	t         j                               D ]  }
t        j                  j                  |d|z        }|j                  ||d |
      }|||<   t        j                  j                  |d|z        }|j                  || j                  |
      }|||<   |	j                  ||f       |dz  } t         j                  j                  |      D ]  }|j                           	 ddd       ||	fS # 1 sw Y   	fS xY w)aW  Produce a format similar to `fast()`, but with uncompressed blobs.

  After calling this, the following filesystem will exist:
    directory/
      config.json   <-- only *.json, the image's config
      digest        <-- sha256 digest of the image's manifest
      manifest.json <-- the image's manifest
      001.tar       <-- the first layer's .tar filesystem delta
      001.sha256    <-- the sha256 of 001.tar with a "sha256:" prefix.
      ...
      NNN.tar       <-- the NNNth layer's .tar filesystem delta
      NNN.sha256    <-- the sha256 of NNN.tar with a "sha256:" prefix.

  We pad layer indices to only 3 digits because of a known ceiling on the number
  of filesystem layers Docker supports.

  Args:
    image: a docker image to save.
    directory: an existing empty directory under which to save the layout.
    threads: the number of threads to use when performing the upload.

  Returns:
    A tuple whose first element is the path to the config file, and whose second
    element is an ordered list of tuples whose elements are the filenames
    containing: (.sha256, .tar) respectively.
  c                     t        j                  | d      5 }|j                   ||             d d d        y # 1 sw Y   y xY wr_   ra   rd   s       r   rh   z uncompressed.<locals>.write_file*  ri   rj   r   r   c                 B    j                         j                  d      S r   r   r   s    r   r   zuncompressed.<locals>.<lambda>3  r   r+   r   r5   c                 B    j                         j                  d      S r   r   r   s    r   r   zuncompressed.<locals>.<lambda>8  r   r+   r7   c                 B    j                         j                  d      S r   r   r   s    r   r   zuncompressed.<locals>.<lambda>:  r   r+   r   r   c                 *    | dd  j                  d      S r   r   )r   s    r   r   zuncompressed.<locals>.<lambda>F  s    '!"+,,V4r+   z%03d.tarr   N)r   r   r   rq   r   r   r   rB   r.   r   rI   r   r   )rQ   r   r   rh   r   r   r;   rg   r   r3   r   r   r   r   s   `             r   uncompressedr     s   <
 ,,,AX'',,y-8K
KI 	"A &QOOJY A@(LOOJY HB CFENN,-GGLLMC,?@k
//


4
a (q77<<	:+;<j
//*j%2J2J!#a&qmm[*-.	Qhc# .( $$112BCmmo DI BN v	O BN v	s   FGGr   )r   N)r   ) __doc__
__future__r   r   r   rt   r#   r<   rq   r   concurrent.futuresr   containerregistry.clientr   containerregistry.client.v1r   v1_imager   rJ   containerregistry.client.v2r	   containerregistry.client.v2_2r
   r   
v2_2_imager   r9   r   rK   r\   r   r   rl   r+   r   <module>r      sq    < &  %  	  	   0 @ 7 1 7 5 D 3 
* PCf	. 	z~ Jr+   