
    .Ph                        d 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
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mZmZ ddlmZmZmZmZm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8 ddl9m:Z:m;Z; 	  G d de          Z<d.dZ=d Z>d Z?d.dZ@ G d deA          ZB G d d          ZC G d d          ZD G d de#          ZE G d d e"          ZF G d! d"e          ZG G d# d$e2          ZH G d% d&e8          ZI G d' d(e:          ZJd/d*ZKd/d+ZLejM        fd/d,ZNeOd-k    r eN             dS dS )0z)Repo implementation atop OpenStack SWIFT.    N)ConfigParserBytesIO)Optional)
HTTPClient   )GreenThreadsMissingObjectFinder)LRUSizeCache)INFODIRPACKDIRPackBasedObjectStore)S_ISGITLINKBlobCommitTagTree)PackPackDataPackIndexerPackStreamCopier_compute_object_sizecompute_file_sha	iter_sha1load_pack_index_fileread_pack_headerunpack_objectwrite_pack_headerwrite_pack_index_v2write_pack_object)TCP_GIT_PORT)InfoRefsContainerread_info_refssplit_peeled_refswrite_info_refs)	OBJECTDIRBaseRepo)BackendTCPGitServerc                       e Zd Zd ZdS )PackInfoMissingObjectFinderc                    	 | j         sd S | j                                         \  }}}|| j        vrn1|s| j                            |          }|d         t
          j        k    r |                     |d         ddfg           nq|d         t          j        k    r&|                     d |d         D                        n5|d         t          j        k    r|                     |d         d dfg           || j
        v r$|                     | j
        |         d dfg           | j                            |           |                     dt          | j                   d	           ||fS )
NTr   r    Fc                 ,    g | ]}t          |          S  )tuple).0is     U/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/dulwich/contrib/swift.py
<listcomp>z4PackInfoMissingObjectFinder.next.<locals>.<listcomp>m   s    999AuQxx999       zcounting objects: )objects_to_sendpopsha_doneobject_storepack_info_getr   type_numadd_todor   r   _taggedaddprogresslen)selfshanameleafinfos        r2   nextz PackInfoMissingObjectFinder.nexta   s~   	' t $ 4 8 8 : :S$$-''	  		A$22377DAw&/))QU345555aDM))99a999::::aCL((Qu56777dl""S 14>?@@@#A3t}+=+=AAABBBT{r4   N)__name__
__module____qualname__rG   r.   r4   r2   r*   r*   `   s#            r4   r*   c                    t                      }|r?	 |                    ||            n%# t          $ r |                    |           Y nw xY w|S d}| s6	 t          j        d         }n$# t          $ r}t          d          |d}~ww xY w| }t          j        	                    |          st          d|           |
                    |           |S )zLoad configuration in global var CONF.

    Args:
      path: The path to the configuration file
      file: If provided read instead the file like object
    NDULWICH_SWIFT_CFGz(You need to specify a configuration filez"Unable to read configuration file )r   	read_fileAttributeErrorreadfposenvironKeyError	Exceptionpathisfileread)rT   fileconfconfpathexcs        r2   	load_confr[   w   s    >>D 	NN4&&&& 	 	 	KK	 H 	Qz"56HH 	Q 	Q 	QFGGSP	Q 7>>(## IGXGGHHHIIhKs'   ) A
AA( (
B2BBc                     |                      |          5 }t          ||          cddd           S # 1 swxY w Y   dS )zRead a pack index file from Swift.

    Args:
      scon: a `SwiftConnector` instance
      filename: Path to the index file objectise
    Returns: a `PackIndexer` instance
    N)
get_objectr   )sconfilenamefs      r2   swift_load_pack_indexra      s     
	"	" 1a#Ha001 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s   377c                 :   t          j        | |          }i }|                                D ]}|j        t          j        k    r|j        |j        |j        f||j        <   4|j        t          j        k    r0d |	                                D             }|j        |f||j        <   y|j        t          j        k    rd ||j        <   |j        t          j        k    r|j        |j        d         f||j        <   t          j        t          j        |                    S )Nc                 d    g | ]-\  }}}t          |          ||t          j        |           f.S r.   )r   statS_ISDIR)r0   nmss       r2   r3   z$pack_info_create.<locals>.<listcomp>   sL       Aq!"1~~A4<??*+  r4   r5   )r   from_objectsiterobjectsr<   r   parentstreeidr   itemsr   r   objectzlibcompressjsondumps)	pack_data
pack_indexpackrF   objshass         r2   pack_info_createry      s   Y
33DD!! 9 9<6?**L#+sx@DLL\T]** "yy{{  D
  L$/DLL\T]**DLL\S\))L#*Q-8DL=D))***r4   c                 
   |s|                     |           }n|}|sd S 	 t          j        t          j        |                                                    |                                 S # |                                 w xY wN)r]   rr   loadsrp   
decompressrV   close)r_   r^   rW   r`   s       r2   load_pack_infor      st     OOH%% tz$/!&&((3344									s   7A, ,Bc                       e Zd ZdS )SwiftExceptionN)rH   rI   rJ   r.   r4   r2   r   r      s        Dr4   r   c                   r    e Zd ZdZddZd Zd Zdee         fdZ	ddZ
d	 Zd
 ZddZddZddZddZdS )SwiftConnectorzDA Connector to swift that manage authentication and errors catching.returnNc                 
   || _         | j                             dd          | _        | j        dvrt          d          | j                             dd          | _        | j                             dd          | _        | j                             dd          | _        | j                             dd          pd	| _        | j                             dd
          pd| _	        | j                             dd          pd	| _
        | j                             dd          pd| _        | j                             dd          pd| _        | j                             dd          pd| _        | j                             dd          pd| _        || _        d}| j        dk    r"|                                 \  | _        | _        n!|                                 \  | _        | _        dt)          | j                  i}t+          j        t)          | j                  | j
        || j	        | j	        |          | _        t)          t1          j        t5          j        | j                  j        | j                            | _        dS )zInitialize a SwiftConnector.

        Args:
          root: The swift container that will act as Git bare repository
          conf: A ConfigParser Object
        swiftauth_ver)12z.Wrong authentication version use either 1 or 2auth_urlusernamepasswordconcurrency
   http_timeout   http_pool_lengthregion_name	RegionOneendpoint_typeinternalURLcache_lengthchunk_lengthi/  i 0  r   X-Auth-Token)r   
block_sizeconnection_timeoutnetwork_timeoutheadersN)rX   getr   NotImplementedErrorr   userr   getintr   r   r   r   r   r   r   rootswift_auth_v1storage_urltokenswift_auth_v2strr   from_url
httpclient	posixpathjoinurlparserT   	base_path)rB   r   rX   r   token_headers        r2   __init__zSwiftConnector.__init__   s5    		gz::=
**%&VWWW	gz::IMM':66		gz::9++G]CCIr I,,WnEEK $	 0 0:L M M SQS9==-@@OK!Y]]7ODDU I,,WnEEK I,,WnEEN	
=C+/+=+=+?+?(Ddjj+/+=+=+?+?(Ddj&DJ8$- !!-!#0 - 
 
 
 N8,T-=>>CTYOO
 
r4   c           	         | j                             dd          | _         t          j        | j        | j        | j                  }| j         | j        d}t          j        | j                  j        }|	                    d||          }|j
        dk     s|j
        dk    r7t          d	| j         d
|j
         d|                                dz             |d         }|d         }||fS )N;:r   r   )zX-Auth-Userz
X-Auth-KeyGETr      ,  zAUTH v1.0 request failed on  with error code  ()zX-Storage-Urlr   )r   replacer   r   r   r   r   r   rT   requeststatus_coder   rn   )rB   auth_httpclientr   rT   retr   r   s          r2   r   zSwiftConnector.swift_auth_v1   s   I%%c3//	$-M#0 -
 
 

 #')4=II //4%%eT7%CC ?S  COs$:$: .]XXS_XX		XXXY   /*N#E!!r4   c           	           j                             d          \   _         _         i } j          j        d j        d|d<   t	          j        |          }ddi}t          j         j         j	         j	                  }t          j
         j                  j        }|                    d          st          j        |d          }|                    d	|||
          }|j        dk     s|j        dk    rTt#          dt%          |                                          |z    d|j         d|                                dz             t	          j        |                                          }|d         d         d         }|d         d         }	t/          d |	D                       }
|
d         }t/           fd|D                       }| j                 |fS )Nr   )r   r   )passwordCredentials
tenantNameauthzContent-Typezapplication/jsonr   tokensPOSTbodyr   r   r   zAUTH v2.0 request failed on r   r   r   accessr   rm   serviceCatalogc              3   2   K   | ]}|d          dk    |V  dS )typezobject-storeNr.   )r0   o_stores     r2   	<genexpr>z/SwiftConnector.swift_auth_v2.<locals>.<genexpr>*  s9       
 
wv./P/PG/P/P/P/P
 
r4   	endpointsc              3   >   K   | ]}|d          j         k    |V  dS )regionN)r   )r0   endprB   s     r2   r   z/SwiftConnector.swift_auth_v2.<locals>.<genexpr>.  s=       
 
$x.D<L*L*LD*L*L*L*L
 
r4   )r   splittenantr   rr   rs   r   r   r   r   r   rT   endswithr   r   r   r   r   r   get_base_urlrn   r|   rV   rG   r   )rB   	auth_dict	auth_jsonr   r   rT   r   auth_ret_jsonr   catalogsr:   r   endpoints   `            r2   r   zSwiftConnector.swift_auth_v2  s&   !%!5!5TY	 !I M$ $ +
 
	& Jy))	!#56$-M#0 -
 
 

  //4}}X&& 	2>$11D%%fdG%TT?S  COs$:$: .5577884?uuRURauuehenenepepuuuv   
388::..h'06 *+;< 
 
#+
 
 
 
 
 !-	 
 
 
 
&
 
 
 
 
 *+U22r4   c                     | j                             d| j                  }|j        dk    rdS |j        dk     s|j        dk    rt	          d|j                   dS )zYCheck that Swift container exist.

        Returns: True if exist or None it not
        HEAD  Nr   r   $HEAD request failed with error code T)r   r   r   r   r   rB   r   s     r2   test_root_existszSwiftConnector.test_root_exists3  sn    
 o%%fdn==?c!!4?S  COc$9$9 HsHH   tr4   c                     |                                  sM| j                            d| j                  }|j        dk     s|j        dk    rt          d|j                   dS dS )zcCreate the Swift container.

        Raises:
          SwiftException: if unable to create
        PUTr   r   #PUT request failed with error code N)r   r   r   r   r   r   r   s     r2   create_rootzSwiftConnector.create_rootA  sy     $$&& 	/))%@@C$$#(=(=$K#/KK  	 	(=(=r4   c                    d}| j         |z   }| j                            d|          }|j        dk    rdS |j        dk     s|j        dk    rt	          d|j                   |                                }t          j        |          S )zRetrieve objects list in a container.

        Returns: A list of dict that describe objects
                 or None if container does not exist
        z?format=jsonr   r   Nr   r   #GET request failed with error code )r   r   r   r   r   rV   rr   r|   )rB   qsrT   r   contents        r2   get_container_objectsz$SwiftConnector.get_container_objectsN  s     ~"o%%eT22?c!!4?S  COc$9$9 GcoGG   ((**z'"""r4   c                 0   | j         dz   |z   }| j                            d|          }|j        dk    rdS |j        dk     s|j        dk    rt	          d|j                   i }|                                D ]\  }}|||                                <   |S )zRetrieve object stat.

        Args:
          name: The object name
        Returns:
          A dict that describe the object or None if object does not exist
        /r   r   Nr   r   r   )r   r   r   r   r   rn   lower)rB   rD   rT   r   resp_headersheadervalues          r2   get_object_statzSwiftConnector.get_object_stat`  s     ~#d*o%%fd33?c!!4?S  COc$9$9 HsHH    YY[[ 	1 	1MFE+0L((r4   c                 l    |                     d           |                                 j        dz   |z   dt          t	                              i fd}	  |            }n# t
          $ r  |            }Y nw xY w|j        dk     s|j        dk    rt          d|j                   dS )	zPut an object.

        Args:
          name: The object name
          content: A file object
        Raises:
          SwiftException: if unable to create
        r   r   zContent-Lengthc                  D    j                             d          } | S )Nr   r   )r   r   )r   datar   rT   rB   s    r2   _sendz(SwiftConnector.put_object.<locals>._send  s&    /))%D')RRCJr4   r   r   r   N)seekrV   r   r   rA   rS   r   r   )rB   rD   r   r   r   r   r   rT   s   `    @@@r2   
put_objectzSwiftConnector.put_objectu  s     	Q||~~~#d*#ST^^4	 	 	 	 	 	 	 		%''CC 	 	 	%''CCC	 ?S  COc$9$9 GcoGG   %:$9s   "
A- -BBc                 0   i }|rd| |d<   | j         dz   |z   }| j                            d||          }|j        dk    rdS |j        dk     s|j        d	k    rt	          d
|j                   |                                }|r|S t          |          S )a
  Retrieve an object.

        Args:
          name: The object name
          range: A string range like "0-10" to
                 retrieve specified bytes in object content
        Returns:
          A file like instance or bytestring if range is specified
        zbytes=Ranger   r   r   r   Nr   r   r   )r   r   r   r   r   rV   r   )rB   rD   ranger   rT   r   r   s          r2   r]   zSwiftConnector.get_object  s      	0///GG~#d*o%%eT7%CC?c!!4?S  COc$9$9 GcoGG   ((** 	Nwr4   c                     | j         dz   |z   }| j                            d|          }|j        dk     s|j        dk    rt	          d|j                   dS )zDelete an object.

        Args:
          name: The object name
        Raises:
          SwiftException: if unable to delete
        r   DELETEr   r   &DELETE request failed with error code N)r   r   r   r   r   )rB   rD   rT   r   s       r2   
del_objectzSwiftConnector.del_object  sl     ~#d*o%%h55?S  COc$9$9 JJJ   %:$9r4   c                    |                                  D ]}|                     |d                    | j                            d| j                  }|j        dk     s|j        dk    rt          d|j                   dS )zDelete the root container by removing container content.

        Raises:
          SwiftException: if unable to delete
        rD   r   r   r   r   N)r   r   r   r   r   r   r   )rB   rw   r   s      r2   del_rootzSwiftConnector.del_root  s     --// 	) 	)COOCK((((o%%h???S  COc$9$9 JJJ   %:$9r4   r   Nr{   )rH   rI   rJ   __doc__r   r   r   r   boolr   r   r   r   r   r]   r   r   r.   r4   r2   r   r      s        NN'
 '
 '
 '
R" " ".%3 %3 %3N(4.       # # #$  *   <       6        r4   r   c                   8    e Zd ZdZd
dZdd
dZd Zd
dZd	 ZdS )SwiftPackReaderac  A SwiftPackReader that mimic read and sync method.

    The reader allows to read a specified amount of bytes from
    a given offset of a Swift object. A read offset is kept internally.
    The reader will read from Swift a specified amount of data to complete
    its internal buffer. chunk_length specify the amount of data
    to read from Swift.
    r   Nc                 |    || _         || _        || _        d| _        d| _        d| _        | j         j        | _        dS )zInitialize a SwiftPackReader.

        Args:
          scon: a `SwiftConnector` instance
          filename: the pack filename
          pack_length: The size of the pack object
        r   r4   N)r^   r_   pack_lengthoffsetbase_offsetbuffr   buff_length)rB   r^   r_   r  s       r2   r   zSwiftPackReader.__init__  sC     	 &	91r4   Fc                     |r| j         dz  | _         | j        }t          | j        | j         z   | j                  }| j                            | j        | d|           }|| _        d S )Nr   -r   )r	  r  minr  r^   r]   r_   r  )rB   morer  rr   s        r2   _readzSwiftPackReader._read  sp     	4#/!3D! 4#33T5EFFi""4=6A"HH			r4   c                 6   | j         |z   }| j        |z   | j        k    r| j        | j         d         }|| _         |S |t	          | j                  k    r+|                     d           |                     |          S | j        | j         |         }|| _         |S )zRead a specified amount of Bytes form the pack object.

        Args:
          length: amount of bytes to read
        Returns:
          a bytestring
        NT)r  )r  r  r  r  rA   r  rV   )rB   lengthendr   s       r2   rV   zSwiftPackReader.read  s     kF"c!D$4449T[]]+DDKKTYJJDJ!!!99V$$$ys*+r4   c                 J    || _         |                                  d| _        dS )z[Seek to a specified offset.

        Args:
          offset: the offset to seek to
        r   N)r  r  r  )rB   r  s     r2   r   zSwiftPackReader.seek  s$     "

r4   c                 D    | j                             | j        d          S )zSRead the checksum from the pack.

        Returns: the checksum bytestring
        z-20r  )r^   r]   r_   rB   s    r2   read_checksumzSwiftPackReader.read_checksum  s!    
 y##DM#???r4   r   )F)	rH   rI   rJ   r   r   r  rV   r   r  r.   r4   r2   r  r    s         2 2 2 2       *   @ @ @ @ @r4   r  c                   .    e Zd ZdZddZd Zd ZddZdS )	SwiftPackDatazThe data contained in a packfile.

    We use the SwiftPackReader to read bytes from packs stored in Swift
    using the Range header feature of Swift.
    r   Nc                 x   || _         || _        d| _        | j                             | j                  }t	          |d                   | _        t          | j         | j        | j                  }t          |j                  \  }| _	        t          d| j         j        z  t                    | _        d| _        dS )zInitialize a SwiftPackReader.

        Args:
          scon: a `SwiftConnector` instance
          filename: the pack filename
           zcontent-lengthi   )compute_sizeN)r^   	_filename_header_sizer   intr  r  r   rV   _num_objectsr
   r   r   _offset_cacherv   )rB   r^   r_   r   pack_readerversions         r2   r   zSwiftPackData.__init__  s     	!)++DN;;w'7899%diAQRR'78H'I'I$$#)$)00-
 
 
 			r4   c                    || j         v r| j         |         S || j        k    sJ t          | j        | j        | j                  }|                    |           t          |j                  \  }}|j	        |
                                fS r{   )r!  r  r  r^   r  r  r   r   rV   pack_type_num_obj)rB   r  r"  unpacked_s        r2   get_object_atzSwiftPackData.get_object_at0  s    T'''%f--*****%diAQRR   #K$455!&88r4   c                 j    t          | j        | j        | j                  }|                                S r{   )r  r^   r  r  r  )rB   r"  s     r2   get_stored_checksumz!SwiftPackData.get_stored_checksum9  s,    %diAQRR((***r4   c                     d S r{   r.   r  s    r2   r~   zSwiftPackData.close=  s    r4   r   )rH   rI   rJ   r   r   r)  r+  r~   r.   r4   r2   r  r    sd            (9 9 9+ + +     r4   r  c                   :     e Zd ZdZd fdZed             Z xZS )	SwiftPackzA Git pack object.

    Same implementation as pack.Pack except that _idx_load and
    _data_load are bounded to Swift version of load_pack_index and
    PackData.
    r   Nc                      |d          _         |d=  t                      j        |i |  j        dz    _        d  _         fd _         fd _         fd _        d S )Nr^   .infoc                  8    t           j         j                  S r{   )r   _pack_info_pathr^   r  s   r2   <lambda>z$SwiftPack.__init__.<locals>.<lambda>O  s    ~d6JDI'V'V r4   c                  8    t           j         j                  S r{   )ra   r^   	_idx_pathr  s   r2   r3  z$SwiftPack.__init__.<locals>.<lambda>P  s    !6ty$.!Q!Q r4   c                  8    t           j         j                  S r{   )r  r^   
_data_pathr  s   r2   r3  z$SwiftPack.__init__.<locals>.<lambda>Q  s    -	4?"K"K r4   )	r^   superr   	_basenamer2  
_pack_info_pack_info_load	_idx_load
_data_load)rB   argskwargs	__class__s   `  r2   r   zSwiftPack.__init__I  s}    6N	6N$)&)))#~7VVVVQQQQKKKKr4   c                 P    | j         |                                 | _         | j         S )z The pack data object being used.)r:  r;  r  s    r2   	pack_infozSwiftPack.pack_infoS  s'     ?""2244DOr4   r   )rH   rI   rJ   r   r   propertyrB  __classcell__r@  s   @r2   r.  r.  A  sh         L L L L L L   X    r4   r.  c                   ~     e Zd ZdZd fdZd Zd Zd Z e            fdZ	d	 Z
dd
ZdefdZddZd Zd Z xZS )SwiftObjectStorezA Swift Object Store.

    Allow to manage a bare Git repository from Openstack Swift.
    This object store only supports pack files and not loose objects.
    r   Nc                     t                                                       || _        | j        j        | _        t	          j        t          t                    | _        d| _	        dS )z^Open a Swift object store.

        Args:
          scon: A `SwiftConnector` instance
        N)
r8  r   r^   r   r   r   r%   r   pack_dir_alternates)rB   r^   r@  s     r2   r   zSwiftObjectStore.__init__b  sN     		IN	!y'::r4   c                     | j                                         }d |D             }g }|D ]7}t          || j                   }|| j        |<   |                    |           8|S )Nc                 |    g | ]9}|d                               d          |d                              dd          :S )rD   .packr,   )r   r   r0   os     r2   r3   z7SwiftObjectStore._update_pack_cache.<locals>.<listcomp>p  sT     
 
 
y!!'**
fIgr**
 
 
r4   r^   )r^   r   r.  _pack_cacheappend)rB   objects
pack_filesr   basenamerv   s         r2   _update_pack_cachez#SwiftObjectStore._update_pack_cachen  s    )1133
 

 
 


 " 	 	HXDI666D)-DX&JJt
r4   c                     g S )z3Loose objects are not supported by this repository.r.   r  s    r2   _iter_loose_objectsz$SwiftObjectStore._iter_loose_objects|  s    	r4   c                 @    | j         D ]}||v r|j        |         c S d S r{   )packsrB  )rB   rC   rv   s      r2   r;   zSwiftObjectStore.pack_info_get  s>    J 	+ 	+Dd{{~c**** 	+ 	+r4   c                 T     fd}t                      }t                      }g }|                    |           |rj|                    d          }||v r|                    |           n9||vr5|                    |            ||          }|                    |           |j||fS )Nc                 ~    j         D ]3}| |v r-	 |j        |          d         }n# t          $ r g cY c S w xY w|c S 4d S )Nr5   )rZ  rB  rR   )commitrv   rk   rB   s      r2   _find_parentsz:SwiftObjectStore._collect_ancestors.<locals>._find_parents  sw    
 # #T>>""&."8";# " " "!					" #NNN "# #s   $55r   )setextendr8   r?   )	rB   headscommonr^  basescommitsqueueerk   s	   `        r2   _collect_ancestorsz#SwiftObjectStore._collect_ancestors  s    	# 	# 	# 	# 	# %%U 	&		!AF{{		!'!!A'-**W%%%  	& r4   c                 @     t                       fd}dd}||fS )zAdd a new pack to this object store.

        Returns: Fileobject to write to and a commit function to
            call when the pack is finished.
        c                                          d           t          d          } |                                 }|rt          j        j        dt          d |D                                  }t                      }t          ||| 	                                           j
                            |dz                                               j
                            |dz   |           |                                 t          |j
                  }|                                                     ||           |S d S )	Nr   r,   )rW   r_   pack-c              3   &   K   | ]}|d          V  dS r   Nr.   )r0   entrys     r2   r   z<SwiftObjectStore.add_pack.<locals>.commit.<locals>.<genexpr>  s&      %D%D5eAh%D%D%D%D%D%Dr4   rM  .idxrP  )r   r   sorted_entriesr   r   rI  r   r   r   r+  r^   r   r~   r.  check_length_and_checksum_add_cached_pack)rv   entriesrU  index
final_packr`   rB   s        r2   r]  z)SwiftObjectStore.add_pack.<locals>.commit  s9   FF1IIIR000D))++G $>MFI%D%DG%D%D%DDDFF   		#E7D4L4L4N4NOOO	$$X%7;;;				$$X%6>>>&xdi@@@
44666%%h
;;;!!tr4   r   Nc                      d S r{   r.   r.   r4   r2   abortz(SwiftObjectStore.add_pack.<locals>.abort  s    Dr4   r   r   )rB   r]  rv  r`   s   `  @r2   add_packzSwiftObjectStore.add_pack  sP     II	 	 	 	 	 	,	 	 	 	 &%r4   c                 6    |                      |d fg           d S r{   )add_objects)rB   rw   s     r2   
add_objectzSwiftObjectStore.add_object  s0    d	
 	
 	
 	
 	
r4   c                     dS NFr.   r  s    r2   _pack_cache_stalez"SwiftObjectStore._pack_cache_stale  s    ur4   c                     d S r{   r.   )rB   rC   s     r2   _get_loose_objectz"SwiftObjectStore._get_loose_object  s    tr4   c                    t          j        d          \  }}t          j        |d          }	 t	          || j                  }t          ||||          }|                                 |                     ||||          |	                                 t          j
        |           S # |	                                 t          j
        |           w xY w)zRead a thin pack.

        Read it from a stream and complete it in a temporary file.
        Then the pack and the corresponding index file are uploaded to Swift.
        	tmp_pack_)prefixzw+b)resolve_ext_ref)
delta_iter)tempfilemkstemprP   fdopenr   get_rawr   verify_complete_thin_packr~   unlink)rB   read_all	read_somefdrT   r`   indexercopiers           r2   add_thin_packzSwiftObjectStore.add_thin_pack  s     #;777DIb%  	!!T\BBBG%h	1QQQFMMOOO++AtVWEEGGIIIIdOOOO GGIIIIdOOOOs   AB, ,*Cc           
      P   t          |          }|                    d           t          |t          |          t          |                                          z              |                                 t          |d          }|                    dt          j                   |                                D ]n}t          |          dk    sJ | 	                    |          \  }}	|
                                }
t          |||	|          }|                    ||
|f           o|                                }|                    |           |                                 |                                 t!          j        | j        dt          j        t)          d |D                                 z             }| j                            |dz   |           |d	z   }t/                      }t1          |||           | j                            ||           |                    d           t3          d
|          }|                    d           t5          d
|          }t7          ||          }|                                 |                                 t/          |          }|dz   }| j                            ||           |                                 t;          || j                  }|                                 |                     ||           |S )Nr   i)end_ofsr   )rC   rj  c              3   &   K   | ]}|d          V  dS rl  r.   )r0   rf  s     r2   r   z7SwiftObjectStore._complete_thin_pack.<locals>.<genexpr>  s&      +B+BQAaD+B+B+B+B+B+Br4   rM  rn  r,   )r_   rW   r0  rP  ) listr   r   rA   ext_refsflushr   rP   SEEK_CURr  tellr   rR  digestwritesortr   r   rI  fsdecoder   r^   r   r   r   r   r   ry   r~   r.  rp  rq  )rB   r`   rT   r  r  rr  new_shaext_shar<   r   r  crc32pack_shapack_base_namer_   
index_filert   ru   serialized_pack_infopack_info_filert  s                        r2   r  z$SwiftObjectStore._complete_thin_pack  s   w-- 	
q			!S\\C0@0@0B0B,C,CCDDD 	
			 #1c222 	
q"+ '')) 	5 	5Gw<<2%%%%!\\'22NHdVVXXF%a4WEEEENNGVU34444>>##					 	"Mbk)+B+B'+B+B+B"B"BCCC
 
 		^g5q999 "F*YY
J:::	Xz222 	
q			bq111	)"j99
/	:FF				 !566!G+	X~666 ~DI>>>
,,...nj999r4   r   )rH   rI   rJ   r   r   rV  rX  r;   r_  rg  rw  rz  r  r}  r  r  r  rD  rE  s   @r2   rG  rG  [  s        
  
  
  
  
  
     + + +
 03suu        2!  !  ! F
 
 
 
4         ": : : : : : :r4   rG  c                   ^     e Zd ZdZd
 fdZd Zd
dZ	 	 	 	 ddefdZ	 ddefdZ	d	 Z
 xZS )SwiftInfoRefsContainerz&Manage references in info/refs object.r   Nc                     || _         d| _        || _        | j                             | j                  }|st	          d          }t                                          |           d S )Nz	info/refsr4   )r^   r_   storer]   r   r8  r   )rB   r^   r  r`   r@  s       r2   r   zSwiftInfoRefsContainer.__init__  s`    	#
I  // 	Ar4   c                     |                      |           | j                            | j                  }|si S t	          |          }t          |          \  }}|||         |k    rdS |S r|  )_check_refnamer^   r]   r_   r"   r#   )rB   rD   old_refr`   refspeeleds         r2   _load_check_refz&SwiftInfoRefsContainer._load_check_ref(  sw    D!!!I  // 	Ia  *400vDzW$$ur4   c                     t                      }|                    t          || j                             | j                            | j        |           d S r{   )r   
writelinesr$   r  r^   r   r_   )rB   r  r`   s      r2   _write_refsz"SwiftInfoRefsContainer._write_refs4  sI    II	_T4:66777	T]A.....r4   c                     |dk    rdS |                      ||          }t          |t                    sdS |||<   |                     |           || j        |<   dS )z=Set a refname to new_ref only if it currently equals old_ref.r   TFr  
isinstancedictr  _refs)	rB   rD   r  new_ref	committer	timestamptimezonemessager  s	            r2   set_if_equalsz$SwiftInfoRefsContainer.set_if_equals9  sl     6>>4##D'22$%% 	5T
"
4tr4   c                     |dk    rdS |                      ||          }t          |t                    sdS ||= |                     |           | j        |= dS )z5Remove a refname only if it currently equals old_ref.r   TFr  )rB   rD   r  r  r  r  r  r  s           r2   remove_if_equalsz'SwiftInfoRefsContainer.remove_if_equalsN  sh     6>>4##D'22$%% 	5JJttr4   c                     	 | j         d         | j         d<   n# t          $ r Y nw xY w| j                                         S )Nzrefs/heads/masterr   )r  rR   keysr  s    r2   allkeyszSwiftInfoRefsContainer.allkeys\  sP    	!%,?!@DJv 	 	 	D	z   s    
%%r   )NNNN)rH   rI   rJ   r   r   r  r  r  r  r  r  rD  rE  s   @r2   r  r    s        00     
 
 
/ / / /   
   , UY 	   ! ! ! ! ! ! !r4   r  c                   @    e Zd ZddZdefdZddZed             ZdS )	SwiftRepor   Nc                    |                     d          | _        || _        t          | j        | j                  | _        | j                                        }|st          d| j                   d |D             }t          |vrt          d| j         d          d| _        | j        | _	        t          | j                  }t          | j        |          }t          j        | ||           dS )ab  Init a Git bare Repository on top of a Swift container.

        References are managed in info/refs objects by
        `SwiftInfoRefsContainer`. The root attribute is the Swift
        container that contain the Git bare repository.

        Args:
          root: The container which contains the bare repo
          conf: A ConfigParser object
        r   z!There is not any GIT repo here : c                 P    g | ]#}|d                               d          d         $S )rD   r   r   )r   rN  s     r2   r3   z&SwiftRepo.__init__.<locals>.<listcomp>v  s-    <<<q1V9??3''*<<<r4   zThis repository (z) is not bare.TN)lstripr   rX   r   r^   r   rS   r%   bare_controldirrG  r  r&   r   )rB   r   rX   rS  r:   r  s         r2   r   zSwiftRepo.__init__e  s     KK$$		"49di88	)1133 	MK	KKLLL<<G<<<G##I	IIIJJJ	9'	22%di>>$d33333r4   c                     dS )zProbe the file-system to determine whether permissions can be trusted.

        Returns: True if permissions can be trusted, False otherwise.
        Fr.   r  s    r2   _determine_file_modezSwiftRepo._determine_file_mode  s	    
 ur4   c                     t                      5 }|                    |           | j                            ||           ddd           dS # 1 swxY w Y   dS )zPut an object in a Swift container.

        Args:
          filename: the path to the object to put on Swift
          contents: the content as bytestring
        N)r   r  r^   r   )rB   r_   contentsr`   s       r2   _put_named_filezSwiftRepo._put_named_file  s     YY 	.!GGHI  1---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.s   1AAAc                 8   |                                  t          j        t          t                    t          j        t
          d          fD ]%}|                    |t          d                     & | |j        |          }|	                    d           |S )zCreate a new bare repository.

        Args:
          scon: a `SwiftConnector` instance
          conf: a ConfigParser object
        Returns:
          a `SwiftRepo` instance
        r  r4   T)
r   r   r   r%   r   r   r   r   r   _init_files)clsr^   rX   rw   r   s        r2   	init_barezSwiftRepo.init_bare  s     	N9g..N7F++
 	/ 	/C OOC....c$)T""
r4   r   )	rH   rI   rJ   r   r  r  r  classmethodr  r.   r4   r2   r  r  d  sr        4 4 4 44d    	. 	. 	. 	.   [  r4   r  c                       e Zd ZddZd ZdS )SwiftSystemBackendr   Nc                 "    || _         || _        d S r{   )rX   logger)rB   r  rX   s      r2   r   zSwiftSystemBackend.__init__  s    	r4   c                 b    | j                             d|           t          || j                  S )Nzopening repository at %s)r  rF   r  rX   )rB   rT   s     r2   open_repositoryz"SwiftSystemBackend.open_repository  s-    3T:::ty)))r4   r   )rH   rI   rJ   r   r  r.   r4   r2   r  r    s7           * * * * *r4   r  r   c                    ddl }|                                }|                    ddddd           |                    d	d
dt          t          d           |                    ddddd           |                    |           \  }} 	 ddl}ddl}n3# t          $ r& t          d           t          j        d           Y nw xY wddl}|j                                         ddlm} |                    t$                    }t'          |j                  }t+          ||          }	|                                 t/          |	|j        |j                  }
|
                                 dS )z*Entry point for starting a TCP git server.r   Nz-lz--listen_addresslisten_addressz	127.0.0.1zBinding IP address.destdefaulthelpz-pz--portportzBinding TCP port.)r  r   r  r  -c--swift_configswift_configr,   1Path to the configuration file for Swift backend.zOgevent and geventhttpclient libraries are mandatory  for use the Swift backend.r5   )	log_utils)r  )optparseOptionParser
add_optionr  r    
parse_argsgeventgeventhttpclientImportErrorprintsysexitgevent.monkeymonkeypatch_socketdulwichr  	getLoggerrH   r[   r  r  default_logging_configr(   r  r  serve_forever)r>  r  parseroptionsr  r  r  r  rX   backendservers              r2   
cmd_daemonr    s   OOO""$$F
"           @     %%d++MGT   *	
 	
 	
 	 
M   !!!!!!  **FW)**D ..G$$&&&'7#9MMMF
s   B -CCc                 ^   dd l }|                                }|                    ddddd           |                    |           \  }} t	          |j                  }| g k    r|                    d           | d         }t          ||          }t          	                    ||           d S )	Nr   r  r  r  r,   r  r  zmissing repository name)
r  r  r  r  r[   r  errorr   r  r  )r>  r  r  r  rX   repor^   s          r2   cmd_initr    s    OOO""$$F
@     %%d++MGTW)**Drzz.///7D$%%Dd#####r4   c           	         t           t          d}t          t          j                  dk     rlt          d                    t          j        d         d                    |                                                               t          j	        d           t          j        d         }||vr&t          d|            t          j	        d            ||         t          j        dd                     d S )N)initdaemonr   zUsage: {} <{}> [OPTIONS...]r   |r5   zNo such subcommand: )
r  r  rA   r  argvr  formatr   r  r  )r  commandscmds      r2   mainr    s     H
 38}}q)00!chhx}}>W>WXX	
 	
 	
 	
(1+C
(*S**+++HSM#(122,r4   __main__)NNr   )Pr   rr   rP   r   rd   r  r  urllib.parseparser   rp   configparserr   ior   typingr   r  r   greenthreadsr	   	lru_cacher
   r:   r   r   r   rS  r   r   r   r   r   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   protocolr    r  r!   r"   r#   r$   r  r%   r&   r  r'   r(   r*   r[   ra   ry   r   rS   r   r   r  r  r.  rG  r  r  r  r  r  r  r  rH   r.   r4   r2   <module>r     s  0 0 /  				      



         % % % % % %             ' ' ' ' ' ' : : : : : : $ $ $ $ $ $ A A A A A A A A A A : : : : : : : : : : : : : :                              $ # # # # # X X X X X X X X X X X X & & & & & & & & * * * * * * * *8    "A   .   :	1 	1 	1+ + +0
 
 
 
	 	 	 	 	Y 	 	 	@ @ @ @ @ @ @ @FF@ F@ F@ F@ F@ F@ F@ F@R) ) ) ) )H ) ) )X       4~ ~ ~ ~ ~+ ~ ~ ~BE! E! E! E! E!. E! E! E!P? ? ? ? ? ? ? ?D* * * * * * * *1 1 1 1h$ $ $ $* h          & zDFFFFF r4   