
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
yb                 @   s  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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Zd dlZd dlZd dlmZmZ ddlmZ ddlmZ ddlT ddlmZ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m"Z" ddlm#Z# ddl$m%Z%m&Z& ddlm'Z' ddl(m)Z) ddl*m+Z+m,Z, ddl-m.Z. e%e/Z$dZ0e+eZ1dP\Z2Z3Z4Z5dZ6dZ7dd Z8G dd  d eZ9G d!d" d"e9Z:G d#d$ d$eZ;G d%d& d&eZ<G d'd( d(eZ=G d)d* d*eZ>dQdRf f f dSdTdUdVdWf f dXdYf dZd;Z?d<d= Z@G d>d? d?ZAG d@dA dAZBdBdC ZCG dDdE dEZDdFdG ZEG dHdI dIZFG dJdK dKeFZGdLddddLdMdNdOZHdS )[    N)PopenPIPE   )__version__)LZ4)*)ErrorIntegrityError)
bin_to_hex)get_base_dir)get_limited_unpacker)hostname_is_unique)replace_placeholders)sysinfo)format_file_size)safe_unlink)prepare_subprocess_env)create_loggersetup_logging)msgpack)
Repository)parse_versionformat_version)xxh64      i   m   a   rd   g?c             C   sN   t | }}x<|rHtj| |}||8 }|s,P ||d }tj|d  qW |S )z;os.write wrapper so we do not lose data for partial writes.Ng&.>)lenoswritetimesleep)fddataZamountZ	remainingcount r(   /usr/lib64/python3.6/remote.pyos_write1   s    r*   c               @   s   e Zd ZdZdS )ConnectionClosedz Connection closed by remote hostN)__name__
__module____qualname____doc__r(   r(   r(   r)   r+   D   s   r+   c               @   s   e Zd ZdZdS )ConnectionClosedWithHintz$Connection closed by remote host. {}N)r,   r-   r.   r/   r(   r(   r(   r)   r0   H   s   r0   c               @   s   e Zd ZdZdS )PathNotAllowedzRepository path not allowed: {}N)r,   r-   r.   r/   r(   r(   r(   r)   r1   L   s   r1   c               @   s   e Zd ZdZdS )InvalidRPCMethodzRPC method {} is not validN)r,   r-   r.   r/   r(   r(   r(   r)   r2   P   s   r2   c               @   s   e Zd ZdZdS )!UnexpectedRPCDataFormatFromClientz4Borg {}: Got unexpected RPC data format from client.N)r,   r-   r.   r/   r(   r(   r(   r)   r3   T   s   r3   c                   s    e Zd ZdZ fddZ  ZS )!UnexpectedRPCDataFormatFromServerz.Got unexpected RPC data format from server:
{}c                sf   y|j  d d }W n@ tk
rT   |d d }dd |D }tjdj|d}Y nX t j| d S )N   c             S   s   g | ]}d | qS )z%02Xr(   ).0Zbyter(   r(   r)   
<listcomp>`   s    z>UnexpectedRPCDataFormatFromServer.__init__.<locals>.<listcomp>       0   )decodeUnicodeDecodeErrortextwrapZfilljoinsuper__init__)selfr&   )	__class__r(   r)   rA   [   s    z*UnexpectedRPCDataFormatFromServer.__init__)r,   r-   r.   r/   rA   __classcell__r(   r(   )rC   r)   r4   X   s   r4   repair
save_spacelimitmarkeridr&   keydataclient_datapathcreate	lock_waitlock	exclusiveappend_onlynext_unreservedstart_nonce)checkcommitrollbackdestroy__len__listputgetdeletesave_keyload_key
break_lock	negotiateopenget_free_noncecommit_nonce_reservationc                s    fdd D S )Nc                s   i | ]} | |j  qS r(   )r<   )r6   k)dr(   r)   
<dictcomp>   s    zdecode_keys.<locals>.<dictcomp>r(   )re   r(   )re   r)   decode_keys   s    rg   c               @   sR   e Zd Zd&Zdd Zdd Zdd Zdd Zdd Zdd Z	d'd"d#Z
d$d% Zd S )(RepositoryServerrX   rT   rU   r\   rW   r[   rY   scanr`   ra   rZ   rV   r]   r^   r_   rb   rc   inject_exceptionc             C   s,   d | _ || _|| _|| _|| _td| _d S )Nz1.0.8)
repositoryrestrict_to_pathsrestrict_to_repositoriesrQ   storage_quotar   client_version)rB   rl   rm   rQ   rn   r(   r(   r)   rA      s    zRepositoryServer.__init__c                sn   y fddt t| D S  tk
rh   |dkrPt dkrPt| dd }n  fddt |D S X dS )z5Translate from positional protocol to named protocol.c                s   i | ]\}} | |qS r(   r(   )r6   posname)argvr(   r)   rf      s    z8RepositoryServer.positional_to_named.<locals>.<dictcomp>ra      Nc                s   i | ]\}} | |qS r(   r(   )r6   rp   rq   )rr   r(   r)   rf      s    )	enumerate	compatMap
IndexErrorr    )rB   methodrr   mappingr(   )rr   r)   positional_to_named   s    z$RepositoryServer.positional_to_namedc                s$   t tj|j  fddD S )zWRemove unknown named parameters from call, because client did (implicitly) say it's ok.c                s   i | ]}| kr| |qS r(   r(   )r6   rq   )knownkwargsr(   r)   rf      s    z0RepositoryServer.filter_args.<locals>.<dictcomp>)setinspect	signature
parameters)rB   fr{   r(   )rz   r{   r)   filter_args   s    zRepositoryServer.filter_argsc          "   C   s  t jj }t jj }t jj }tj|tj}tj|tj|tjB  tj|tj}tj|tj|tj @  tj|tj}tj|tj|tj @  t	d}xvt
j
|gg g d\}}}|rtj|t}	|	s| jd k	r| jj  nt|djtj  d S |j|	 x|D ]}
t|
tr@d}|
t }|
t j }t|
t }n^t|
trt|
dkrd}|
\}}}}|j }| j||}n| jd k	r| jj  ttyb|| jkrt |yt!| |}W n" t"k
r   t!| j|}Y nX | j#||}|f |}W n t$k
r } z|rt%j&|j'|}t%j(t j)  }d}t|t*rX|j+ g}|j%}t|t,j-t,j.t/frpnt0j1dj2| y2t3j4t|d|j'j5d	|j6d
|d|d|dt7 i}W nN t8k
r    t3j4t|d|j'j5d	dd |j6D d
|d|d|dt7 i}Y nX t|| nt|t,j-t,j.t/fr&ndt|t*rP|j%r@t0j9nt0j:}|j+ }nt0j9}d|j'j5 }dt%j; t7 f }t0j<| t0j=|| d}t|t3j4d||j'j5|f W Y d d }~X n:X |rt|t3j4t|t>|i nt|t3j4d|d |f qW |r| jj  d S qW d S )NZserver
   z<Borg {}: Got connection close before repository was opened.
Trs   F
s   exception_classs   exception_argss   exception_fulls   exception_shorts   exception_traces   sysinfoc             S   s$   g | ]}t |tttfr|nd qS )N)
isinstancestrbytesint)r6   xr(   r(   r)   r7     s   z*RepositoryServer.serve.<locals>.<listcomp>z%s Exception in RPC callz%s
%sz3Remote Exception (see remote log for the traceback)r   )?sysstdinfilenostdoutfcntlF_GETFLF_SETFLr!   
O_NONBLOCKr   selectreadBUFSIZErk   closer*   formatr   encodefeedr   dictMSGIDMSGr<   rg   ARGStupler    ry   r3   rpc_methodsr2   getattrAttributeErrorr   BaseException	tracebackformat_exception_onlyrC   format_exceptionexc_infor   get_messager   DoesNotExistAlreadyExistsr1   loggingdebugr?   r   packbr,   argsr   	TypeErrorERRORDEBUG
format_excerrorlogRESULT)rB   stdin_fd	stdout_fd	stderr_fdZflunpackerrwZesr&   unpacked
dictFormatmsgidrw   r   _r   reseZex_shortZex_fullZex_tracemsgZtb_log_leveltbexcr(   r(   r)   serve   s    








.
zRepositoryServer.servec             C   sZ   |t krt S t|trL|d | _tjtjdj}tdd|d t	j
d nt| _dtiS )Ns   client_version T)Zis_servejsonlevelz2Initialized logging system for JSON-based protocolserver_version)RPC_PROTOCOL_VERSIONr   r   ro   r   ZgetLevelName	getLoggerr   r   loggerr   BORG_VERSION)rB   rK   r   r(   r(   r)   r`   6  s    

zRepositoryServer.negotiatec             C   s   t |trtj|}|jdr8tjjt |dd  }nr|jdr\tjjt |dd  }nN|jdr|tjj|dd  }n.|jdrtjj|}n|jdr|dd  }tjj	|S )	Nz/~/r:   z~/r   z/~r   ~z/./)
r   r   r!   fsdecode
startswithrL   r?   r   
expanduserrealpath)rB   rL   r(   r(   r)   _resolve_pathG  s    






zRepositoryServer._resolve_pathFNTc          
   C   s   t jd| | j|}t jd| tjj|d}| jrpx8| jD ]&}	tjjtjj|	d}
|j|
r>P q>W t	|| j
rx6| j
D ]$}tjjtjj|d}||kr~P q~W t	|| r| jp|}t|||||| j||d| _| jj  | jjS )NzResolving repository path %rzResolved repository path to %rr   )rN   rO   rQ   rn   rP   make_parent_dirs)r   r   r   r!   rL   r?   rl   r   r   r1   rm   rQ   r   rn   rk   	__enter__rI   )rB   rL   rM   rN   rO   rP   rQ   r   Zpath_with_sepZrestrict_to_pathZrestrict_to_path_with_sepZrestrict_to_repositoryZrestrict_to_repository_with_sepr(   r(   r)   ra   W  s0    




zRepositoryServer.openc             C   s   |j  }d}d}|dkr$tj|n|dkr8tj|np|dkrLtj|n\|dkr^t|nJ|dkrptdn8|d	krtj||n"|d
krt|n|dkrdd  d S )Nztest stringztest string2r   r   CheckNeededr	   r1   ZfooObjectNotFoundr2   Zdivider   )	r<   r   r   r   r   r	   r1   r   r2   )rB   Zkinds1s2r(   r(   r)   rj   z  s&    


z!RepositoryServer.inject_exception)rX   rT   rU   r\   rW   r[   rY   ri   r`   ra   rZ   rV   r]   r^   r_   rb   rc   rj   )FNTNFF)r,   r-   r.   r   rA   ry   r   r   r`   r   ra   rj   r(   r(   r(   r)   rh      s6                    q 
"rh   c               @   s   e Zd Zdd Zdd ZdS )SleepingBandwidthLimiterc             C   s0   |r&t |t | _tj | _| j| _nd | _d S )N)r   RATELIMIT_PERIOD	ratelimitr#   	monotonicratelimit_lastratelimit_quota)rB   rG   r(   r(   r)   rA     s
    

z!SleepingBandwidthLimiter.__init__c             C   s   | j rtj }| jt |krN|  j| j 7  _| jd| j  krHd| j  | _|| _| jdkr| jt | }tj| |  j| j 7  _tj | _t|| jkr|d | j }tj	||}| j r|  j|8  _|S )Nr   r   )
r   r#   r   r   r   r   r$   r    r!   r"   )rB   r%   to_sendZnowZtosleepwrittenr(   r(   r)   r"     s$    


zSleepingBandwidthLimiter.writeN)r,   r-   r.   rA   r"   r(   r(   r(   r)   r     s   r   c                s    fdd}|S )a~  Check version requirements and use self.call to do the remote method call.

    <since> specifies the version in which borg introduced this method,
    calling this method when connected to an older version will fail without transmiting
    anything to the server.

    Further kwargs can be used to encode version specific restrictions.
    If a previous hardcoded behaviour is parameterized in a version, this allows calls that
    use the previously hardcoded behaviour to pass through and generates an error if another
    behaviour is requested by the client.

    e.g. when 'append_only' was introduced in 1.0.7 the previous behaviour was what now is append_only=False.
    Thus @api(..., append_only={'since': parse_version('1.0.7'), 'previously': False}) allows calls
    with append_only=False for all version but rejects calls using append_only=True on versions older than 1.0.7.
    c                s   t j  fdd}|S )Nc       
         s   t j }|j| f||}i }i }xh|jj D ]Z\}}|dkrBq0||jkrt|dkrd|j| ||< q|j| ||< q0|j|jk	r0|j||< q0W | jk r| j	 j
txbj D ]V\}}	|	d | jkrqd|	kr|| |	d krq| j	dj j
||| t|	d qW | j j
|f|S )NrB   waitsince
previouslyz{0} {1}={2!s})r}   r~   Zbindr   itemsZ	argumentsdefaultemptyr   RPCServerOutdatedr,   r   r   call)
rB   r   r{   ZsigZ
bound_argsZnamedZextrarq   ZparamZrestriction)r   kwargs_decoratorr   r(   r)   do_rpc  s.    


z&api.<locals>.decorator.<locals>.do_rpc)	functoolswraps)r   r   )r   r   )r   r)   	decorator  s    zapi.<locals>.decoratorr(   )r   r   r   r(   )r   r   r)   api  s    !r   c               @   s0  e Zd Zg ZG dd deZG dd deZdZdMdd	Z	d
d Z
dd Zdd Zdd Zedd Zdd Zdd Zdd Zdd ZdNddZeededdd ed!dd d"dOd#d$Zeedd%dPd&d'Zeedd%dQd(d)Zeedd%d*d+ Zeedd%d,d- Zeedd%d.d/ Zeedd%dRd0d1Zeed2d%dSd3d4Zd5d6 ZdTd7d8Z eedd%dUd9d:Z!eedd%dVd;d<Z"eedd%d=d> Z#eedd%d?d@ Z$eedd%dAdB Z%eedd%dCdD Z&eedd%dEdF Z'dGdH Z(dWdIdJZ)dKdL Z*dS )XRemoteRepositoryc               @   sL   e Zd Zdd Zdd Zedd Zedd Zed	d
 Zedd Z	dS )zRemoteRepository.RPCErrorc             C   s
   || _ d S )N)r   )rB   r   r(   r(   r)   rA     s    z"RemoteRepository.RPCError.__init__c             C   s(   d| j krdj| j d j S | jS d S )Ns   exception_short   
)r   r?   r<   exception_class)rB   r(   r(   r)   r     s    
z%RemoteRepository.RPCError.get_messagec             C   s   | j jddS )Ns   exception_traceT)r   r[   )rB   r(   r(   r)   r     s    z#RemoteRepository.RPCError.tracebackc             C   s   | j d j S )Ns   exception_class)r   r<   )rB   r(   r(   r)   r     s    z)RemoteRepository.RPCError.exception_classc             C   s.   d| j krdj| j d j S | j d S d S )Ns   exception_fullr   z4
Remote Exception (see remote log for the traceback))r   r?   r<   r   )rB   r(   r(   r)   exception_full  s    
z(RemoteRepository.RPCError.exception_fullc             C   s    d| j kr| j d j S dS d S )Ns   sysinfor   )r   r<   )rB   r(   r(   r)   r      s    
z!RemoteRepository.RPCError.sysinfoN)
r,   r-   r.   rA   r   propertyr   r   r   r   r(   r(   r(   r)   RPCError  s   r   c               @   s(   e Zd ZdZedd Zedd ZdS )z"RemoteRepository.RPCServerOutdatedz2Borg server is too old for {}. Required version {}c             C   s
   | j d S )Nr   )r   )rB   r(   r(   r)   rw   
  s    z)RemoteRepository.RPCServerOutdated.methodc             C   s
   | j d S )Nr   )r   )rB   r(   r(   r)   required_version  s    z3RemoteRepository.RPCServerOutdated.required_versionN)r,   r-   r.   r/   r   rw   r   r(   r(   r(   r)   r     s   r   FNTc	                s  | _ _g _d_d_d_d_d_i _t	 _
i _i _d _t|rf|jrf|jd nd_td_td_d _|_|jdk}	t|	 d}
j||	}|	sj|| }tjd| t|dttt|
d	_jjj  _!jj"j  _#jj$j  _%t&j&j!t&j't&j&j!t&j(t)j*B  t&j&j#t&j't&j&j#t&j(t)j*B  t&j&j%t&j't&j&j%t&j(t)j*B  j#j%g_+j!j#j%g_,yyj-d
ddt.ii}W n  t/k
r   t0dd Y nX |t1krd_2n4t3|t4rd|krd_2|d _nt5d|  fdd}j2rF|  nhy
|  W n\ j6k
r } z<|j7dkrt d}t8j$j9| td_dt:d< |  W Y d d }~X nX W n  t5k
r   j;   Y nX d S )Nr       i   Zclientz1.0.8Z__testsuite__)systemzSSH command line: %s)bufsizer   r   stderrenvr`   rK   s   client_versionzIs borg working on the server?Fs   server_versionTz8Server insisted on using unsupported protocol version %sc            	      s"   j jj d_d S )N)rL   rM   rN   rO   rP   rQ   r   )ra   locationrL   rI   r(   )rQ   rM   rP   rO   rN   r   rB   r(   r)   do_openI  s    z*RemoteRepository.__init__.<locals>.do_openr   ao  Please note:
If you see a TypeError complaining about the number of positional arguments
given to open(), you can ignore it if it comes from a borg version < 1.0.7.
This TypeError is a cosmetic side effect of the compatibility code borg
clients >= 1.0.7 have to support older borg servers.
This problem will go away as soon as the server has been upgraded to 1.0.7+.
z1.0.6rL   rM   rN   rO   ra   )rL   rM   rN   rO   )<r   Z	_locationpreload_idsr   rx_bytestx_bytesr   stderr_receivedchunkid_to_msgidsr|   ignore_responses	responsesasync_responsesshutdown_timer   Zremote_ratelimitr   r   r   r   r   p_argshostr   borg_cmdssh_cmdr   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r_fdsx_fdsr   r   r+   r0   r   r   r   r   	Exceptionr   r   r   r"   ru   r   )rB   r   rM   rP   rN   rO   rQ   r   r   testingr   r  versionr   errr   r(   )rQ   rM   rP   rO   rN   r   rB   r)   rA     sx    


$$$


zRemoteRepository.__init__c             C   s>   t | jr tjdt | jf  | jr:| j  ds:tdd S )Nz2still %d cached responses left in RemoteRepositoryFz&cleanup happened in Repository.__del__)r    r  r   r   r  r   AssertionError)rB   r(   r(   r)   __del__i  s
    
zRemoteRepository.__del__c             C   s   d| j j| jj f S )Nz<%s %s>)rC   r,   r   Zcanonical_path)rB   r(   r(   r)   __repr__p  s    zRemoteRepository.__repr__c             C   s   | S )Nr(   )rB   r(   r(   r)   r   s  s    zRemoteRepository.__enter__c             C   sP   z"|d k	r t j d | _| j  W d tjdt| jt| j| j	 | j
  X d S )N   zDRemoteRepository: %s bytes sent, %s bytes received, %d messages sent)r#   r   r  rV   r   r   r   r   r   r   r   )rB   exc_typeexc_valexc_tbr(   r(   r)   __exit__v  s    zRemoteRepository.__exit__c             C   s
   t | jS )N)r
   rI   )rB   r(   r(   r)   id_str  s    zRemoteRepository.id_strc             C   sX  g }|dk	r|j d|j  tj }|jtjr<|j d n^|jtjrT|j d nF|jtjrbn8|jtjrz|j d n |jtj	r|j d nt
dx4|jD ]*}d|krd	| }d
|kr|j d|  qW d|kr|jr|j d|j  g }t s|j d |r&|tjdddg | | j S |jp:tjjdd}t|}||dg | S dS )z return a borg serve command lineNz--umask=%03oz--debugz--infoz--errorz
--criticalz log level missing, fix this code.zborg.debug.rk   z--debug-topic=%srn   z--storage-quota=%szBORG_HOSTNAME_IS_UNIQUE=noz-mzborg.archiverr   ZBORG_REMOTE_PATHborg)appendumaskr   r   ZisEnabledForr   INFOZWARNINGr   CRITICAL
ValueErrorZdebug_topicsrn   r   r   
executableextra_test_argsremote_pathr!   environr[   r   )rB   r   r  ZoptsZroot_loggerZtopicZenv_varsr!  r(   r(   r)   r    s<    
zRemoteRepository.borg_cmdc             C   sj   | j jptjjdd}tj|}|jr8|dt|jg7 }|j	rV|j
d|j	|jf  n|j
d|j  |S )zEreturn a ssh command line that can be prefixed to a borg command lineZBORG_RSHZsshz-pz%s@%sz%s)r  rshr!   r"  r[   shlexsplitZportr   userr  r  )rB   r   r#  r   r(   r(   r)   r    s    
zRemoteRepository.ssh_cmdc                s    fddt | D S )Nc                s   g | ]} | qS r(   r(   )r6   rq   )r{   r(   r)   r7     s    z8RemoteRepository.named_to_positional.<locals>.<listcomp>)ru   )rB   rw   r{   r(   )r{   r)   named_to_positional  s    z$RemoteRepository.named_to_positionalc             K   s"   x| j ||gf|D ]}|S W d S )N)	call_many)rB   cmdr   kwrespr(   r(   r)   r     s    zRemoteRepository.callc             #   s  | r|dkrd S  fdd} fdd}t |}g }x>|sD|rv jrttj  jkrttjdt|t j d S xj|ryJ jj	|d }	|j	d d|	kr||	 n|	t
 V  | r| rd S W qv tk
r   P Y qvX qvW |dkrNxby jj \}
}	W n, tk
r*   |r" jr"P nd S Y qX d|	kr@||	 q|	t
 V  qW  jsr|sd jr|t|tk r| jg}ng }tj j| jd	\}}}|rtd
x|D ]}| jkrtj|t}|st   jt|7  _ jj| xȈ jD ]}	t|	tr|	t  }
nPt|	t!rbt|	dkrb|	\}}
}}|rTt |
d|i}	nt |
t
|i}	nt"||
 jkr jj#|
 d|	kr|	 j|
< n|	t
 d k	r|	 j|
< n
|	 j|
< q W n| j$krtj|d}|st   jt|7  _ j%r j%| }d _%|j&dd}|r@|d j'd r@|j	  _%x|D ]}t(|j)d qFW qW |r:x j r|s jrt|tk r|rr|r|dkst*d|d d  j+krr|j,||j	dd  n|j	d}|dkr|d  j+kr|j,||d  n\  j-d	7  _-|j, j-  j.rTt/j0t  j-t1|t2|i _nt/j0d	 j-| j3||f _ j rl jrl jj	d}d|i}  j-d	7  _- j+j4|g j, j-  j.rt/j0t  j-t1dt2|i _nt/j0d	 j-d j3d|f _qlW  jr:y4 j5j6 j j}  j7|7  _7 j|d   _W q: t8k
rr } z|j9t9j:krb W Y d d }~X q:X q:W   jt;|O  _d S )Nr  c                s&    j |  jd} j |  s" j | = |S )Nr   )r   pop)Zchunkidr   )rB   r(   r)   pop_preload_msgid  s    
z5RemoteRepository.call_many.<locals>.pop_preload_msgidc                s|  | d j  }d| k}| jd}|dkr8tj jjn@|dkrRtj jjn&|dkrltj jjn|dkr|rtdnt|d j  n|d	kr|rtj	dntj	|d j  n|d
kr|rt
dnt
|d j  n|dkrtj|d j  nr|dkrB|r(tjd jjntj|d j   jjn6|dkrn|r\tdnt|d j  n
 j| d S )Ns   exception_classs   exception_argsr   r   r   r	   z(not available)r   AtticRepositoryr1   z	(unknown)ParentPathDoesNotExistr   r2   )r<   r[   r   r   r   Z	processedr   r   r	   r.  r1   r/  r   r2   r   )r   r   Z
old_serverr   )rB   r(   r)   handle_error  s@    






z0RemoteRepository.call_many.<locals>.handle_errorzPshutdown_time reached, shutting down with %d waiting_for and %d async_responses.r   s   exception_classr   zFD exception occurredrs   i   r   T)keepends   r   zutf-8r[   z&is_preload is only supported for 'get'rI   )r2  r   )<rY   r  r#   r   r   r   r    r  r  r,  r   KeyErrorpopitemr   r   r   MAX_INFLIGHTr   r   r	  r
  r  r   r!   r   r   r+   r   r   r   r   r   r   r   r4   remover   r   
splitlinesendswithhandle_remote_liner<   r  r   r  r   r   r   r   r   r   r'  
setdefaultr   r"   r   OSErrorerrnoZEAGAINr|   )rB   r)  callsr   is_preloaded
async_waitr-  r0  Zwaiting_forr   r   Zw_fdsr   r   r   r%   r&   r   r   r   linesliner   Zchunk_idr   r   r(   )rB   r)   r(    s    )






$





*
$zRemoteRepository.call_manyz1.0.0z1.0.7)r   r   z1.1.9)r   rQ   r   c             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rL   rM   rN   rO   rP   rQ   r   r(   r(   r)   ra     s    zRemoteRepository.open)r   c             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rE   rF   r(   r(   r)   rT     s    zRemoteRepository.checkc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rF   r(   r(   r)   rU     s    zRemoteRepository.commitc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   rV     s    zRemoteRepository.rollbackc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   rW     s    zRemoteRepository.destroyc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   rX     s    zRemoteRepository.__len__c             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rG   rH   r(   r(   r)   rY     s    zRemoteRepository.listz1.1.0b3c             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rG   rH   r(   r(   r)   ri     s    zRemoteRepository.scanc             C   s   x| j |gD ]}|S W d S )N)get_many)rB   rI   r+  r(   r(   r)   r[     s    zRemoteRepository.getc             c   s.   x(| j ddd |D |dD ]
}|V  qW d S )Nr[   c             S   s   g | ]}d |iqS )rI   r(   )r6   rI   r(   r(   r)   r7     s    z-RemoteRepository.get_many.<locals>.<listcomp>)r?  )r(  )rB   idsr?  r+  r(   r(   r)   rC    s     zRemoteRepository.get_manyc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rI   r&   r   r(   r(   r)   rZ     s    zRemoteRepository.putc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rI   r   r(   r(   r)   r\     s    zRemoteRepository.deletec             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rJ   r(   r(   r)   r]     s    zRemoteRepository.save_keyc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   r^     s    zRemoteRepository.load_keyc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   rb     s    zRemoteRepository.get_free_noncec             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   rR   rS   r(   r(   r)   rc     s    z)RemoteRepository.commit_nonce_reservationc             C   s   dS )z;actual remoting is done via self.call in the @api decoratorNr(   )rB   r(   r(   r)   r_     s    zRemoteRepository.break_lockc             C   s2   | j r.| j jj  | j jj  | j j  d | _ d S )N)r  r   r   r   r   )rB   r(   r(   r)   r     s
    
zRemoteRepository.closec             C   s"   x| j dg d|dD ]}|S W d S )Nr  T)r>  r   r@  )r(  )rB   r   r+  r(   r(   r)   async_response  s    zRemoteRepository.async_responsec             C   s   |  j |7  _ d S )N)r   )rB   rD  r(   r(   r)   preload  s    zRemoteRepository.preload)FFNTFFN)TFT)FNTFFF)FF)F)NN)NN)F)T)T)T)+r,   r-   r.   r   r  r   r   r   r   rA   r  r  r   r  r   r  r  r  r'  r   r(  r   r   ra   rT   rU   rV   rW   rX   rY   ri   r[   rC  rZ   r\   r]   r^   rb   rc   r_   r   rE  rF  r(   r(   r(   r)   r     s^   " 
S1
 7 

r   c             C   s  | j dst| jdrbtj| }|d dkrFtjd|d |  d	S |d dkrtt|d
 tj	}t
|tsrttj|d }d|d  |d< tjdjr||j krtjjtj|d  n|j|d|d  n|d jdrtjd}|j tjkrtjdjr>d|kr&d|d  |d< tjjtj|d  n"d|krtjjd|d  d  n| jdr| jdd\}}}tt|tj	}|jdrtj||j  n&|jdd\}}tj|j||j  n8tjdjrtjdjd| j   ntjjd|   d	S )zv
    Handle a remote log line.

    This function is remarkably complex because it handles multiple wire formats.
    r   {typeprogress_messageprogress_percentlog_messagez3Dropped remote log message with unknown type %r: %sNZ	levelnamerq   zRemote: messager  z%sZ	progress_zborg.output.progressz$LOG r8   r   zRemote:r   r   )rG  r   )rJ  rK  rL  )r9  r  r   r   loadsr   Zwarningr   r   r  r   r   r   ZgetEffectiveLevelr   r   r"   dumpsr   r  r%  rstripstrip)rB  r   r   Ztarget_loggerZprogress_loggerr   Zlognamer(   r(   r)   r:    sB    



r:  c               @   sL   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdddZ	dd Z
dS )RepositoryNoCacheaR  A not caching Repository wrapper, passes through to repository.

    Just to have same API (including the context manager) as RepositoryCache.

    *transform* is a callable taking two arguments, key and raw repository data.
    The return value is returned from get()/get_many(). By default, the raw
    repository data is returned.
    Nc             C   s   || _ |pdd | _d S )Nc             S   s   |S )Nr(   )keyr&   r(   r(   r)   <lambda>,  s    z,RepositoryNoCache.__init__.<locals>.<lambda>)rk   	transform)rB   rk   rU  r(   r(   r)   rA   *  s    zRepositoryNoCache.__init__c             C   s   d S )Nr(   )rB   r(   r(   r)   r   .  s    zRepositoryNoCache.closec             C   s   | S )Nr(   )rB   r(   r(   r)   r   1  s    zRepositoryNoCache.__enter__c             C   s   | j   d S )N)r   )rB   r  r  r  r(   r(   r)   r  4  s    zRepositoryNoCache.__exit__c             C   s   t | j|gddS )NF)cache)nextrC  )rB   rS  r(   r(   r)   r[   7  s    zRepositoryNoCache.getTc             c   s2   x,t || jj|D ]\}}| j||V  qW d S )N)ziprk   rC  rU  )rB   keysrV  rS  r&   r(   r(   r)   rC  :  s    zRepositoryNoCache.get_manyc             C   s   d S )Nr(   )rB   r(   r(   r)   log_instrumentation>  s    z%RepositoryNoCache.log_instrumentation)N)T)r,   r-   r.   r/   rA   r   r   r  r[   rC  rZ  r(   r(   r(   r)   rR  !  s   

rR  c                   s\   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dddZ  ZS )RepositoryCacheaf  
    A caching Repository wrapper.

    Caches Repository GET operations locally.

    *pack* and *unpack* complement *transform* of the base class.
    *pack* receives the output of *transform* and should return bytes,
    which are stored in the cache. *unpack* receives these bytes and
    should return the initial data (as returned by *transform*).
    Nc                sv   t  j|| |pdd | _|p&dd | _t | _tjdd| _| j	  d| _
d| _d| _d| _d| _d| _d| _d S )Nc             S   s   | S )Nr(   )r&   r(   r(   r)   rT  P  s    z*RepositoryCache.__init__.<locals>.<lambda>c             S   s   | S )Nr(   )r&   r(   r(   r)   rT  Q  s    zborg-cache-)prefixr   g        )r@   rA   packunpackr|   rV  tempfileZmkdtempbasedirquery_size_limitsizehitsmissesslow_missesslow_lat	evictionsenospc)rB   rk   r]  r^  rU  )rC   r(   r)   rA   N  s    zRepositoryCache.__init__c             C   s0   t j| j}|j|j }tt|d d| _d S )Ng      ?r      l        )r!   statvfsr`  f_bavailf_frsizer   min
size_limit)rB   Zstat_fsZavailable_spacer(   r(   r)   ra  ^  s    z RepositoryCache.query_size_limitc             C   s   t jj| jt|S )N)r!   rL   r?   r`  r
   )rB   rS  r(   r(   r)   key_filenamec  s    zRepositoryCache.key_filenamec             C   sr   | j   td| j }xV| j|krl| jrl| jj }| j|}|  jtj|j	8  _tj
| |  jd7  _qW d S )Ng?r   )ra  r   rn  rb  rV  r,  ro  r!   statst_sizeunlinkrg  )rB   Ztarget_sizerS  filer(   r(   r)   backofff  s    


zRepositoryCache.backoffc       	      C   s   | j ||}|s|S | j|}| j|}y$t|d}|j| W d Q R X W nj tk
r } zNyt| W n tk
r~   Y nX |jtj	kr|  j
d7  _
| j  n W Y d d }~X n4X |  jt|7  _| jj| | j| jkr| j  |S )Nwbr   )rU  r]  ro  ra   r"   r<  r   FileNotFoundErrorr=  ZENOSPCrh  rt  rb  r    rV  addrn  )	rB   rS  r&   rV  transformedZpackedrs  r%   Zos_errorr(   r(   r)   	add_entryp  s,    


zRepositoryCache.add_entryc             C   s>   t jdt| jt| jt| j| j| j| j	| j
| j| j
 d S )NzyRepositoryCache: current items %d, size %s / %s, %d hits, %d misses, %d slow misses (+%.1fs), %d evictions, %d ENOSPC hit)r   r   r    rV  r   rb  rn  rc  rd  re  rf  rg  rh  )rB   r(   r(   r)   rZ    s    z#RepositoryCache.log_instrumentationc             C   s"   | j   | jj  tj| j d S )N)rZ  rV  clearshutilZrmtreer`  )rB   r(   r(   r)   r     s    
zRepositoryCache.closeTc             #   s   fdd|D }t | jj|}x|D ]}| jkrx j|}t|d$}  jd7  _ j|j V  W d Q R X q*x|D ]4\}}	||kr~ j	||	|}
  j
d7  _
|
V  P q~W tj } jj|}	  jtj | 7  _ j	||	|}
  jd7  _|
V  q*W x|D ]}qW d S )Nc                s   g | ]}| j kr|qS r(   )rV  )r6   rS  )rB   r(   r)   r7     s    z,RepositoryCache.get_many.<locals>.<listcomp>rbr   )rX  rk   rC  rV  ro  ra   rc  r^  r   ry  rd  r#   Zperf_counterr[   rf  re  )rB   rY  rV  Zunknown_keysZrepository_iteratorrS  rs  r%   Zkey_r&   rx  Zt0r   r(   )rB   r)   rC    s,    




zRepositoryCache.get_many)NNN)T)r,   r-   r.   r/   rA   ra  ro  rt  ry  rZ  r   rC  rD   r(   r(   )rC   r)   r[  B  s   

r[  F)decrypted_cacher]  r^  rU  force_cachec               s   |r|s|s|rt dn@|rZ|tjd t  fdd} fdd}fdd}t| tsh|rvt| |||S t| |S d	S )
a  
    Return a Repository(No)Cache for *repository*.

    If *decrypted_cache* is a key object, then get and get_many will return a tuple
    (csize, plaintext) instead of the actual data in the repository. The cache will
    store decrypted data, which increases CPU efficiency (by avoiding repeatedly decrypting
    and more importantly MAC and ID checking cached objects).
    Internally, objects are compressed with LZ4.
    z:decrypted_cache and pack/unpack/transform are incompatiblez=I8sc                s&   | \}}j |} j|t|| S )N)compressr]  r   )r&   csize	decrypted
compressed)cache_struct
compressorr(   r)   r]    s    
zcache_if_remote.<locals>.packc                sP   t | }  j| d  j \}}|  jd  }|t|krBtd|j|fS )Nz)detected corrupted data in metadata cache)
memoryviewr^  rb  r   r	   Z
decompress)r&   r  Zchecksumr  )r  r  r(   r)   r^    s    zcache_if_remote.<locals>.unpackc                s   t |} j| |}||fS )N)r    Zdecrypt)Zid_r&   r  r  )rS  r(   r)   rU    s    z"cache_if_remote.<locals>.transformN)r  structStructr   r   r   r[  rR  )rk   r}  r]  r^  rU  r~  r(   )r  r  rS  r)   cache_if_remote  s    


r  )r   r   r   r   )rE   rF   )rF   )rG   rH   )rI   r&   )rI   )rI   )rJ   )rK   )rL   rM   rN   rO   rP   rQ   )rR   rS   )Ir=  r   r   r}   r   r   r!   r   r$  r{  r  r   r_  r>   r#   r   
subprocessr   r   r   r   r  r   Z	constantsZhelpersr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   rk   r   r  r   r   Zalgorithms.checksumsr   r,   r   r   r   r   r   r   r6  r   r*   r+   r0   r1   r2   r3   r4   ru   rg   rh   r   r   r   r:  rR  r[  r  r(   r(   r(   r)   <module>   s   #   4   xJ!q