o
    Uh                     @   s>  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 deZ<d5ddZ=dd Z>dd Z?d5ddZ@G dd deAZBG dd dZCG dd  d ZDG d!d" d"e#ZEG d#d$ d$e"ZFG d%d& d&eZGG d'd( d(e2ZHG d)d* d*e8ZIG d+d, d,e:ZJd6d.d/ZKd6d0d1ZLejMfd6d2d3ZNeOd4kreN  dS dS )7z)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                   @   s   e Zd Zdd ZdS )PackInfoMissingObjectFinderc                 C   s   	 | j sd S | j  \}}}|| jvrnq|sg| j|}|d tjkr0| |d ddfg n&|d tjkrD| dd |d D  n|d t	jkrV| |d d dfg || j
v rg| | j
| d dfg | j| | d	t| j d
 ||fS )NTr   r    Fc                 S   s   g | ]}t |qS  )tuple).0ir*   r*   i/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/dulwich/contrib/swift.py
<listcomp>m   s    z4PackInfoMissingObjectFinder.next.<locals>.<listcomp>   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infor*   r*   r.   nexta   s(   

z PackInfoMissingObjectFinder.nextN)__name__
__module____qualname__rB   r*   r*   r*   r.   r(   `   s    r(   c              
   C   s   t  }|rz	|||  W |S  ty   || Y |S w d}| s;ztjd }W n ty: } ztd|d}~ww | }tj	|sJt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)rN   fileconfconfpathexcr*   r*   r.   	load_confw   s,   

rU   c                 C   s8   |  |}t||W  d   S 1 s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fr*   r*   r.   swift_load_pack_index   s   $rZ   c                 C   s   t | |}i }| D ]I}|jtjkr |j|j|jf||j< q|jtjkr8dd |	 D }|j|f||j< q|jt
jkrDd ||j< q|jtjkrU|j|jd f||j< qtt|S )Nc                 S   s,   g | ]\}}}t |s||t| fqS r*   )r   statS_ISDIR)r,   nmsr*   r*   r.   r/      s    z$pack_info_create.<locals>.<listcomp>r0   )r   from_objectsiterobjectsr7   r   parentstreeidr   itemsr   r   objectzlibcompressjsondumps)	pack_data
pack_indexpackrA   objshasr*   r*   r.   pack_info_create   s    rp   c                 C   sF   |s| | }n|}|sd S ztt| W |  S |  w N)rV   ri   loadsrg   
decompressrP   close)rX   rW   rQ   rY   r*   r*   r.   load_pack_info   s   ru   c                   @   s   e Zd ZdS )SwiftExceptionN)rC   rD   rE   r*   r*   r*   r.   rv      s    rv   c                   @   s~   e Zd ZdZdddZdd Zdd	 Zdee fd
dZ	dddZ
dd Zdd ZdddZdddZdddZdddZdS )SwiftConnectorzDA Connector to swift that manage authentication and errors catching.returnNc                 C   sn  || _ | j dd| _| jdvrtd| j dd| _| j dd| _| j dd| _| j ddp4d	| _| j dd
p>d| _	| j ddpHd	| _
| j ddpRd| _| j ddp\d| _| j ddpfd| _| j ddppd| _|| _d}| jdkr|  \| _| _n|  \| _| _dt| ji}tjt| j| j
|| j	| j	|d| _ttt| 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)rR   getrz   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urlparserN   	base_path)r=   r   rR   r   token_headerr*   r*   r.   __init__   s>   


zSwiftConnector.__init__c                 C   s   | j dd| _ tj| j| j| jd}| j | jd}t| jj}|j	d||d}|j
dk s3|j
dkrFtd	| j d
|j
 d| d |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   rN   requeststatus_coderv   re   )r=   auth_httpclientr   rN   retr   r   r*   r*   r.   r      s$   zSwiftConnector.swift_auth_v1c                    s<   j d\ _ _ i } j  jd jd|d< t|}ddi}tj j j	 j	d}t

 jj}|ds?t|d}|jd	|||d
}|jdk sR|jdkrjtdt| |  d|j d| d t| }|d d d }|d d }	tdd |	D }
|
d }t fd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   rd   serviceCatalogc                 s   s     | ]}|d  dkr|V  qdS )typezobject-storeNr*   )r,   o_storer*   r*   r.   	<genexpr>*  s    z/SwiftConnector.swift_auth_v2.<locals>.<genexpr>	endpointsc                 3   s"    | ]}|d   j kr|V  qdS )regionN)r   )r,   endpr=   r*   r.   r   .  s    )r   splittenantr   ri   rj   r   r   r}   r   r   rN   endswithr   r   r   r   rv   r   get_base_urlre   rr   rP   rB   r   )r=   	auth_dict	auth_jsonr   r   rN   r   auth_ret_jsonr   catalogsr5   r   endpointr*   r   r.   r     sF   


&zSwiftConnector.swift_auth_v2c                 C   sF   | 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   rv   r=   r   r*   r*   r.   test_root_exists3  s   

zSwiftConnector.test_root_existsc                 C   sD   |   s| 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   rv   r   r*   r*   r.   create_rootA  s   
zSwiftConnector.create_rootc                 C   s`   d}| j | }| jd|}|jdkrdS |jdk s|jdkr'td|j | }t|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   rv   rP   ri   rr   )r=   qsrN   r   contentr*   r*   r.   get_container_objectsN  s   



z$SwiftConnector.get_container_objectsc                 C   st   | j d | }| jd|}|jdkrdS |jdk s|jdkr'td|j i }| D ]
\}}||| < q-|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   rv   re   lower)r=   r?   rN   r   resp_headersheadervaluer*   r*   r.   get_object_stat`  s   

zSwiftConnector.get_object_statc                    s   | d |  jd | dtt i fdd}z| }W n ty2   | }Y nw |jdk s=|jdkrEt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                     s   j jd d} | S )Nr   r   )r   r   )r   datar   rN   r=   r*   r.   _send  s   z(SwiftConnector.put_object.<locals>._sendr   r   r   N)seekrP   r   r   r<   rM   r   rv   )r=   r?   r   r   r   r*   r   r.   
put_objectu  s   
	


zSwiftConnector.put_objectc                 C   s   i }|rd| |d< | j d | }| jjd||d}|jdkr"dS |jdk s,|jd	kr4t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   rv   rP   r   )r=   r?   ranger   rN   r   r   r*   r*   r.   rV     s   


zSwiftConnector.get_objectc                 C   sD   | j d | }| 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   rv   )r=   r?   rN   r   r*   r*   r.   
del_object  s   
zSwiftConnector.del_objectc                 C   sT   |   D ]	}| |d  q| 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
        r?   r   r   r   r   N)r   r   r   r   r   r   rv   )r=   rn   r   r*   r*   r.   del_root  s   
zSwiftConnector.del_rootrx   Nrq   )rC   rD   rE   __doc__r   r   r   r   boolr   r   r   r   r   rV   r   r   r*   r*   r*   r.   rw      s    
)'



rw   c                   @   s@   e Zd ZdZdddZddddZd	d
 ZdddZd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.
    rx   Nc                 C   s2   || _ || _|| _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       N)rW   rX   pack_lengthoffsetbase_offsetbuffr   buff_length)r=   rW   rX   r   r*   r*   r.   r     s   zSwiftPackReader.__init__Fc                 C   sP   |r| j d | _ | j}t| j| j  | j}| jj| j| d| d}|| _d S )Nr   -r   )r   r   minr   rW   rV   rX   r   )r=   morer   rr   r*   r*   r.   _read  s   
zSwiftPackReader._readc                 C   sr   | j | }| j| | jkr| j| j d }|| _ |S |t| jkr,| jd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   r<   r   rP   )r=   lengthendr   r*   r*   r.   rP     s   

zSwiftPackReader.readc                 C   s   || _ |   d| _dS )z[Seek to a specified offset.

        Args:
          offset: the offset to seek to
        r   N)r   r   r   )r=   r   r*   r*   r.   r     s   
zSwiftPackReader.seekc                 C   s   | j j| jddS )zSRead the checksum from the pack.

        Returns: the checksum bytestring
        z-20r   )rW   rV   rX   r   r*   r*   r.   read_checksum  s   zSwiftPackReader.read_checksumr   )F)	rC   rD   rE   r   r   r   rP   r   r   r*   r*   r*   r.   r     s    
	

r   c                   @   s4   e Zd ZdZdddZdd Zdd	 Zd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.
    rx   Nc                 C   sp   || _ || _d| _| j | j}t|d | _t| j | j| j}t|j\}| _	t
d| j j td| _d| _dS )zInitialize a SwiftPackReader.

        Args:
          scon: a `SwiftConnector` instance
          filename: the pack filename
           zcontent-lengthi   )compute_sizeN)rW   	_filename_header_sizer   intr   r   r   rP   _num_objectsr	   r   r   _offset_cacherm   )r=   rW   rX   r   pack_readerversionr*   r*   r.   r     s   

zSwiftPackData.__init__c                 C   sZ   || j v r
| j | S || jksJ t| j| j| j}|| t|j\}}|j	|
 fS rq   )r  r   r   rW   r   r   r   r   rP   pack_type_num_obj)r=   r   r  unpacked_r*   r*   r.   get_object_at0  s   


zSwiftPackData.get_object_atc                 C   s   t | j| j| j}| S rq   )r   rW   r   r   r   )r=   r  r*   r*   r.   get_stored_checksum9  s   z!SwiftPackData.get_stored_checksumc                 C      d S rq   r*   r   r*   r*   r.   rt   =     zSwiftPackData.closer   )rC   rD   rE   r   r   r  r	  rt   r*   r*   r*   r.   r     s    
	r   c                       s.   e Zd ZdZd fddZedd Z  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.
    rx   Nc                    sb   |d  _ |d= t j|i |  jd  _d  _ fdd _ fdd _ fdd _d S )NrW   .infoc                         t  j jS rq   )ru   _pack_info_pathrW   r*   r   r*   r.   <lambda>O      z$SwiftPack.__init__.<locals>.<lambda>c                      r  rq   )rZ   rW   	_idx_pathr*   r   r*   r.   r  P  r  c                      r  rq   )r   rW   
_data_pathr*   r   r*   r.   r  Q  r  )	rW   superr   	_basenamer  
_pack_info_pack_info_load	_idx_load
_data_load)r=   argskwargs	__class__r   r.   r   I  s   
zSwiftPack.__init__c                 C   s   | j du r
|  | _ | j S )z The pack data object being used.N)r  r  r   r*   r*   r.   	pack_infoS  s   

zSwiftPack.pack_infor   )rC   rD   rE   r   r   propertyr  __classcell__r*   r*   r  r.   r  A  s
    
r  c                       s   e Zd ZdZd fddZdd Zdd	 Zd
d Ze fddZ	dd Z
dddZdefddZdddZdd Zdd Z  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.
    rx   Nc                    s2   t    || _| jj| _ttt| _d| _	dS )z^Open a Swift object store.

        Args:
          scon: A `SwiftConnector` instance
        N)
r  r   rW   r   r   r   r$   r   pack_dir_alternates)r=   rW   r  r*   r.   r   b  s
   


zSwiftObjectStore.__init__c                 C   sL   | j  }dd |D }g }|D ]}t|| j d}|| j|< || q|S )Nc                 S   s*   g | ]}|d   dr|d  ddqS )r?   .packr)   )r   r   r,   or*   r*   r.   r/   p  s    z7SwiftObjectStore._update_pack_cache.<locals>.<listcomp>rW   )rW   r   r  _pack_cacheappend)r=   objects
pack_filesr   basenamerm   r*   r*   r.   _update_pack_cachen  s   

z#SwiftObjectStore._update_pack_cachec                 C   s   g S )z3Loose objects are not supported by this repository.r*   r   r*   r*   r.   _iter_loose_objects|  s   z$SwiftObjectStore._iter_loose_objectsc                 C   s&   | j D ]}||v r|j|   S qd S rq   )packsr  )r=   r>   rm   r*   r*   r.   r6     s
   
zSwiftObjectStore.pack_info_getc           	         sx    fdd}t  }t  }g }|| |r8|d}||v r$|| n||vr6|| ||}|| |s||fS )Nc              	      sL    j D ] }| |v r#z|j|  d }W |  S  ty"   g  Y   S w qd S )Nr0   )r/  r  rL   )commitrm   rb   r   r*   r.   _find_parents  s   
z:SwiftObjectStore._collect_ancestors.<locals>._find_parentsr   )setextendr3   r:   )	r=   headscommonr1  basescommitsqueueerb   r*   r   r.   _collect_ancestors  s   




z#SwiftObjectStore._collect_ancestorsc                    s(   t    fdd}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                     s     d t dd} |  }|rZtjdtdd |D  }t }t||| 	  j
|d      j
|d | |  t|j
d	}|  || |S d S )
Nr   r)   )rQ   rX   pack-c                 s       | ]}|d  V  qdS r   Nr*   )r,   entryr*   r*   r.   r         z<SwiftObjectStore.add_pack.<locals>.commit.<locals>.<genexpr>r$  .idxr'  )r   r   sorted_entriesr   r   r"  r   r   r   r	  rW   r   rt   r  check_length_and_checksum_add_cached_pack)rm   entriesr,  index
final_packrY   r=   r*   r.   r0    s&   
z)SwiftObjectStore.add_pack.<locals>.commitrx   Nc                   S   r
  rq   r*   r*   r*   r*   r.   abort  r  z(SwiftObjectStore.add_pack.<locals>.abortr   r   )r=   r0  rH  r*   rG  r.   add_pack  s   

zSwiftObjectStore.add_packc                 C   s   |  |d fg d S rq   )add_objects)r=   rn   r*   r*   r.   
add_object  s   zSwiftObjectStore.add_objectc                 C      dS NFr*   r   r*   r*   r.   _pack_cache_stale  r  z"SwiftObjectStore._pack_cache_stalec                 C   r
  rq   r*   )r=   r>   r*   r*   r.   _get_loose_object  r  z"SwiftObjectStore._get_loose_objectc              	   C   s|   t jdd\}}t|d}z%t|| jd}t||||d}|  | ||||W |	  t
| S |	  t
| 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mkstemprJ   fdopenr   get_rawr   verify_complete_thin_packrt   unlink)r=   read_all	read_somefdrN   rY   indexercopierr*   r*   r.   add_thin_pack  s   zSwiftObjectStore.add_thin_packc              	   C   s  t |}|d t|t|t|   |  t|dd}|dtj | D ]%}t|dks5J | 	|\}}	|
 }
t|||	|d}|||
|f q+| }|| |  |  t| jdttdd |D  }| j|d	 | |d
 }t }t||| | j|| |d td|d}|d td|}t||}|  |  t|}|d }| j|| |  t|| jd}|  | || |S )Nr   i)end_ofsr   )r>   r;  c                 s   r<  r=  r*   )r,   r9  r*   r*   r.   r     r?  z7SwiftObjectStore._complete_thin_pack.<locals>.<genexpr>r$  r@  r)   )rX   rQ   r  r'  ) listr   r   r<   ext_refsflushr   rJ   SEEK_CURrW  tellr   r)  digestwritesortr   r   r"  fsdecoder   rW   r   r   r   r   r   rp   rt   r  rB  rC  )r=   rY   rN   r_  r^  rD  new_shaext_shar7   r   r   crc32pack_shapack_base_namerX   
index_filerk   rl   serialized_pack_infopack_info_filerF  r*   r*   r.   rY    sP   





z$SwiftObjectStore._complete_thin_packr   )rC   rD   rE   r   r   r-  r.  r6   r2  r:  rI  rK  r   rN  rO  r`  rY  r   r*   r*   r  r.   r!  [  s    
#
r!  c                       sf   e Zd ZdZd fddZdd Zddd	Z				ddefd
dZ	ddefddZ	dd Z
  ZS )SwiftInfoRefsContainerz&Manage references in info/refs object.rx   Nc                    s<   || _ d| _|| _| j | j}|std}t | d S )Nz	info/refsr   )rW   rX   storerV   r   r  r   )r=   rW   rt  rY   r  r*   r.   r     s   zSwiftInfoRefsContainer.__init__c                 C   sP   |  | | j| j}|si S t|}t|\}}|d ur&|| |kr&dS |S rM  )_check_refnamerW   rV   rX   r!   r"   )r=   r?   old_refrY   refspeeledr*   r*   r.   _load_check_ref(  s   
z&SwiftInfoRefsContainer._load_check_refc                 C   s,   t  }|t|| j | j| j| d S rq   )r   
writelinesr#   rt  rW   r   rX   )r=   rw  rY   r*   r*   r.   _write_refs4  s   z"SwiftInfoRefsContainer._write_refsc           	      C   sF   |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ry  
isinstancedictr{  _refs)	r=   r?   rv  new_ref	committer	timestamptimezonemessagerw  r*   r*   r.   set_if_equals9  s   


z$SwiftInfoRefsContainer.set_if_equalsc                 C   sB   |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|  )r=   r?   rv  r  r  r  r  rw  r*   r*   r.   remove_if_equalsN  s   

z'SwiftInfoRefsContainer.remove_if_equalsc                 C   s2   z
| j d | j d< W n	 ty   Y nw | j  S )Nzrefs/heads/masterr   )r  rL   keysr   r*   r*   r.   allkeys\  s   
zSwiftInfoRefsContainer.allkeysr   )NNNN)rC   rD   rE   r   r   ry  r{  r   r  r  r  r   r*   r*   r  r.   rs    s"    	

	

rs  c                   @   s:   e Zd ZdddZdefddZdddZed	d
 ZdS )	SwiftReporx   Nc                 C   s   | d| _|| _t| j| j| _| j }|s td| j dd |D }t|vr4td| j dd| _| j| _	t
| j}t| j|}t| || 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                 S   s   g | ]}|d   dd qS )r?   r   r   )r   r%  r*   r*   r.   r/   v  s    z&SwiftRepo.__init__.<locals>.<listcomp>zThis repository (z) is not bare.TN)lstripr   rR   rw   rW   r   rM   r$   bare_controldirr!  rs  r%   r   )r=   r   rR   r*  r5   rw  r*   r*   r.   r   e  s   

zSwiftRepo.__init__c                 C   rL  )zProbe the file-system to determine whether permissions can be trusted.

        Returns: True if permissions can be trusted, False otherwise.
        Fr*   r   r*   r*   r.   _determine_file_mode  s   zSwiftRepo._determine_file_modec                 C   sD   t  }|| | j|| W d   dS 1 s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   rh  rW   r   )r=   rX   contentsrY   r*   r*   r.   _put_named_file  s   
"zSwiftRepo._put_named_filec                 C   sP   |   tttttdfD ]
}||td q| |j|}|	d |S )zCreate a new bare repository.

        Args:
          scon: a `SwiftConnector` instance
          conf: a ConfigParser object
        Returns:
          a `SwiftRepo` instance
        rw  r   T)
r   r   r   r$   r   r
   r   r   r   _init_files)clsrW   rR   rn   r   r*   r*   r.   	init_bare  s   



zSwiftRepo.init_barer   )	rC   rD   rE   r   r   r  r  classmethodr  r*   r*   r*   r.   r  d  s    

r  c                   @   s   e Zd ZdddZdd ZdS )SwiftSystemBackendrx   Nc                 C   s   || _ || _d S rq   )rR   logger)r=   r  rR   r*   r*   r.   r     s   
zSwiftSystemBackend.__init__c                 C   s   | j d| t|| jS )Nzopening repository at %s)r  rA   r  rR   )r=   rN   r*   r*   r.   open_repository  s   z"SwiftSystemBackend.open_repositoryr   )rC   rD   rE   r   r  r*   r*   r*   r.   r    s    
r  rx   c                 C   s   ddl }| }|jdddddd |jd	d
dttdd |jdddddd || \}} z
ddl}ddl}W n tyJ   t	d t
d Y nw ddl}|j  ddlm} |t}t|j}t||}	|  t|	|j|jd}
|
  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.r0   )	log_utils)r  )optparseOptionParser
add_optionr   r   
parse_argsgeventgeventhttpclientImportErrorprintsysexitgevent.monkeymonkeypatch_socketdulwichr  	getLoggerrC   rU   r  r  default_logging_configr'   r  r  serve_forever)r  r  parseroptionsr  r  r  r  rR   backendserverr*   r*   r.   
cmd_daemon  sV   



r  c                 C   sp   dd l }| }|jd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  rU   r  errorrw   r  r  )r  r  r  r  rR   reporW   r*   r*   r.   cmd_init  s    


r  c                 C   s   t td}ttjdk r!tdtjd d|  t	d tjd }||vr6td|  t	d || tjdd   d S )N)initdaemonr   zUsage: {} <{}> [OPTIONS...]r   |r0   zNo such subcommand: )
r  r  r<   r  argvr  formatr   r  r  )r  commandscmdr*   r*   r.   main  s   


r  __main__)NNr   )Pr   ri   rJ   r   r[   r  rT  urllib.parseparser   rg   configparserr   ior   typingr   r  r   greenthreadsr   	lru_cacher	   r5   r
   r   r   r*  r   r   r   r   r   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   protocolr   rw  r    r!   r"   r#   r  r$   r%   r  r&   r'   r(   rU   rZ   rp   ru   rM   rv   rw   r   r   r  r!  rs  r  r  r  r  r  r  rC   r*   r*   r*   r.   <module>   s\   <

  I, BHB


4

