Your IP : 3.147.73.117


Current Path : /usr/lib/python3.6/site-packages/syspurpose/__pycache__/
Upload File :
Current File : //usr/lib/python3.6/site-packages/syspurpose/__pycache__/files.cpython-36.opt-1.pyc

3

i�f_r�@sDddlmZmZmZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZm
Z
mZmZddlmZdZejjed�Zejjed�ZdZejjed�Zd	Zd
ZdZdZed	ed
edediZeeeegZdZ ej!e"�Z#dd�Z$Gdd�de%�Z&Gdd�de%�Z'Gdd�de%�Z(ej)dddddddg�Z*d%d d!�Z+d&d#d$�Z,dS)'�)�print_function�division�absolute_importN)�system_exit�
create_dir�create_file�	make_utf8�write_to_file_utf8)�ugettextz/etc/rhsm/syspurposezsyspurpose.jsonzvalid_fields.jsonz/var/lib/rhsm/cache�role�addons�service_level_agreement�usageZaddOnsZserviceLevelZunsupportedcCs`d|kr\d|dkr2|dd|dd<|dd=d|dkr\|dd|dd<|dd=|S)z�
    Try to solve conflicts in keys
     - Server returns key "roles", but it should be "role"
     - Server returns key "support_level", but service_level_agreement is used in syspurpose.json
    :return: modified dictionary
    �systemPurposeAttributesZrolesrZ
support_levelr
�)�datarr�/usr/lib/python3.6/files.py�post_process_received_data?s

rc@sbeZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
ddd�Zeddd��Z
dS)�SyspurposeStorez9
    Represents and maintains a json syspurpose file
    FcCs||_i|_||_dS)N)�path�contents�raise_on_error)�selfrrrrr�__init__VszSyspurposeStore.__init__cCs�y.tj|jddd��}tj|�|_dSQRXWn�tk
rhtjj|j�rdt	tj
td�j|j��dSt
k
r�}zj|jtjkr�|jr�t	tjtd�j|j��|jtjkr�|jr�tjd	j|j|d
��dS|jr�|�WYdd}~XnXdS)aN
        Opens & reads the contents of the store's file based on the 'path' provided to the constructor,
        and stores them on this object. If the user doesn't have access rights to the file, the program exits.
        :return: False if the contents of the file were empty, or the file doesn't exist; otherwise, nothing.
        �rzutf-8)�encodingTNz<Error: Malformed data in file {}; please review and correct.Fz,Cannot read syspurpose file {}
Are you root?z#Unable to read file {file}: {error})�file�error)�io�openr�json�loadr�
ValueError�os�getsizer�	EX_CONFIG�_�format�OSError�errnoZEACCESr�	EX_NOPERM�ENOENT�logr)r�f�errr�	read_file[s$zSyspurposeStore.read_filecCs(ttjj|j��p&|j�p&t|j|j�S)zw
        Create the files necessary for this store
        :return: True if changes were made, false otherwise
        )rr#r�dirnamer/rr)rrrr�createwszSyspurposeStore.createcCs�t|�}t|�}yj|j|}|dk	r<t|t�r<|g|j|<|j|dkrTg|j|<||j|krt|j|j|�ndSWn$ttfk
r�|g|j|<YnXdS)aJ
        Add a value to a list of values specified by key. If the current value specified by the key is scalar/non-list,
        it is not overridden, but maintained in the list, along with the new value.
        :param key: The name of the list
        :param value: The value to append to the list
        :return: None
        NFT)rr�
isinstance�list�append�AttributeError�KeyError)r�key�value�
current_valuerrr�add�s

zSyspurposeStore.addc
Cs�t|�}t|�}yR|j|}|dk	rBt|t�rB||krB|j|�S||kr\|j|j|�ndSdStttfk
r|dSXdS)aN
        Remove a value from a list specified by key.
        If the current value specified by the key is not a list, unset the value.
        :param key: The name of the list parameter to manipulate
        :param value: The value to attempt to remove
        :return: True if the value was in the list, False if it was not
        NFT)	rrr2r3�unset�remover5r6r")rr7r8r9rrrr<�s

zSyspurposeStore.removecCs@t|�}|dkr*|jj|d�}d|j|<n|jj|d�}|dk	S)z\
        Unsets a key
        :param key: The key to unset
        :return: boolean
        r
N�)rr�get�pop)rr7r8rrrr;�szSyspurposeStore.unsetcCs<t|�}t|�}t|jj|d��}||j|<||kp:|dkS)z�
        Set a key (syspurpose parameter) to value
        :param key: The parameter of the syspurpose file to set
        :type key: str

        :param value: The value to set that parameter to
        :return: Whether any change was made
        N)rrr>)rr7r8Zorgrrr�set�s
	
zSyspurposeStore.setNc
CsH|s8tj|jddd��}t||j�|j�WdQRXnt||j�dS)zE
        Write the current contents to the file at self.path
        �wzutf-8)rN)rrrr	r�flush)r�fpr-rrr�write�s
zSyspurposeStore.writecCs0|||d�}tj|tj�s$|j�n|j�|S)aL
        Read the file represented by path. If the file does not exist it is created.
        :param path: The path on the file system to read, should be a json file
        :param raise_on_error: When it is set to True, then exceptions are raised as expected.
        :return: new SyspurposeStore with the contents read in
        )r)r#�access�W_OKr1r/)�clsrrZ	new_storerrr�read�s

zSyspurposeStore.read)F)N)F)�__name__�
__module__�__qualname__�__doc__rr/r1r:r<r;r@rD�classmethodrHrrrrrQs
	
rc@seZdZdZdd�ZdS)�
SyncResultza
    A container class for the results of a sync operation performed by a SyncedStore class.
    cCs||_||_||_||_dS)N)�result�remote_changed�
local_changed�cached_changed)rrOrPrQrRrrrr�szSyncResult.__init__N)rIrJrKrLrrrrrrN�srNc@s�eZdZdZeZeZd2dd�Zdd�Z	dd	�Z
d
d�Zdd
�Zdd�Z
d3dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zed,d-��Zed.d/��Zd0d1�Z dS)4�SyncedStorezz
    Stores values in a local file backed by a cache which is then synced with another source
    of the same values.
    NFcCsx||_|jjd�d|_|j|_|j|_d|_|j�|_	d|_
|j�|_d|_
||_||_|dkrn|j�|_nd|_dS)a8
        Initialization of SyncedStore
        :param uep: object representing connection to candlepin server
        :param on_changed: optional callback method called, during three-way merge
        :param consumer_uuid: UUID of consumer
        :param use_valid_fields: if valid fields are considered
        �/�NFT���)�uep�PATH�split�filenamer�
CACHE_PATH�
cache_pathZ
local_file�get_local_contents�local_contentsZ
cache_file�get_cached_contents�cache_contents�changed�
on_changed�
consumer_uuid�get_valid_fields�valid_fields)rrWrbrcZuse_valid_fieldsrrrrs

zSyncedStore.__init__cCs|S)Nr)rrrr�	__enter__szSyncedStore.__enter__cCs|j�dS)N)�finish)r�exc_typeZexc_valZexc_tbrrr�__exit__szSyncedStore.__exit__cCs|jr|j�dS)z{
        When local content was changed, then try to synchronize local content with remote server
        :return:
        N)ra�sync)rrrrrg"szSyncedStore.finishcs�tjd�y*|jr2|jjd�r2tjd�|j�SWn6tk
rj}ztjdj|d��|j�Sd}~XnX|j�}|j�}|j	�}|j
|||d���fdd	��D�}t�|�kp�|j��|j
|�|j���}tjd
�d|_|S)z�
        Try to synchronize local content with remote server
        :return: instance of SyncResult holding result of synchronization
        z(Attempting to sync syspurpose content...�
syspurposez9Server does not support syspurpose, syncing only locally.zDFailed to detect whether the server has syspurpose capability: {err})�errN)�local�remote�basecsi|]}�|r�||�qSrr)�.0r7)rOrr�
<dictcomp>Dsz$SyncedStore.sync.<locals>.<dictcomp>z#Successfully synced system purpose.F)r,�debugrW�has_capability�_sync_local_only�	Exceptionr'�get_remote_contentsr]r_�mergerN�
update_remote�update_local�update_cachera)rrlZremote_contentsr^Zcached_contentsZlocal_resultZsync_resultr)rOrrj*s2



zSyncedStore.synccCs|j|j��}t|jd|d�S)NF)ryr]rNr^)rZ
local_updatedrrrrtTszSyncedStore._sync_local_onlycCst||||jd�}|S)z�
        Do three-way merge
        :param local: dictionary with local values (syspyrpose.json)
        :param remote: dictionary with values from server
        :param base:
        :return:
        )rmrorn�	on_change)�three_way_mergerb)rrmrnrorOrrrrwXs
zSyncedStore.mergec
Csbytjtj|jddd��|_Wn<tjtt	fk
rZt
jd|j�|ji�i|_YnX|jS)zl
        Try to load local content from file
        :return: dictionary with system purpose values
        rzutf-8)rz+Unable to read local system purpose at "%s")
r r!rrrr^r#rr"�IOErrorr,rrry)rrrrr]hs
zSyncedStore.get_local_contentscCs�|jdks|jdkr"tjd�iS|jjd�s<tjd�iS|jj|j�}i}x"tD]}|jt|�}|||<qTWtjd�|S)zn
        Try to get remote content from server
        :return: dictionary with system purpose values
        NziFailed to read remote syspurpose from server: no available connection, or the consumer is not registered.rkz0Server does not support syspurpose, not syncing.z0Successfully read remote syspurpose from server.)	rWrcr,rrrsZgetConsumer�
ATTRIBUTESr>�LOCAL_TO_REMOTE)rZconsumerrO�attrr8rrrrvus



zSyncedStore.get_remote_contentsc
Csly(tjtj|jddd��|_tjd�Wn<tt	j
tfk
rdtjd|j�i|_|j
i�YnX|jS)zy
        Try to load cached server response from the file
        :return: dictionary with system purpose values
        rzutf-8)rz-Successfully read cached syspurpose contents.z2Unable to read cached syspurpose contents at '%s'.)r r!rrr\r`r,rrr"r#rr}rrz)rrrrr_�szSyncedStore.get_cached_contentscCs||_|j�dS)z�
        Rewrite local content with new data and write data to file syspurpose.json
        :param data: new dictionary with local data
        :return: None
        N)r^�_write_local)rrrrrry�szSyncedStore.update_localcCs|j|j|j�dS)zD
        Write local data to the file
        :return: None
        N)�_update_filerr^)rrrrr��szSyncedStore._write_localcCs||_|j�dS)N)r`�_write_cache)rrrrrrz�szSyncedStore.update_cachecCs|j|j|j�dS)z;
        Write cache to file
        :return: None
        N)r�r\r`)rrrrr��szSyncedStore._write_cachecCs||jdks|jdkr"tjd�dS|jt�}|jj|j|jt�pBd|dk	rN|ng|jt�p\d|jt	�phdd�tjd�dS)NzmFailed to update remote syspurpose on the server: no available connection, or the consumer is not registered.Fr=)rrZ
service_levelrz5Successfully updated remote syspurpose on the server.T)
rWrcr,rrr>�ADDONSZupdateConsumer�ROLE�
SERVICE_LEVEL�USAGE)rrrrrrrx�s


zSyncedStore.update_remotecCs�|jdk	r�||jkrf||j|kr�ttd�j||d��x`|j|D]}t|�dkrDtd|�qDWn4ttd�j|d��x|jj�D]}td|�q�WdS)z�
        Check validity of provided key and value of it is included in valid fields
        :param key: provided key
        :param value: provided value
        :return: None
        NzaWarning: Provided value "{val}" is not included in the list of valid values for attribute {attr}:)�valr�rz - %szHWarning: Provided key "{key}" is not included in the list of valid keys:)r7)re�printr&r'�len�keys)rr7r8Zvalid_valueZ	valid_keyrrr�_check_key_value_validity�s



z%SyncedStore._check_key_value_validitycCs�t|�}t|�}y�|j|}|dk	r<t|t�r<|g|j|<|j|dkrTg|j|<||j|krt|j|j|�ntjd||f�d|_|jSWn$tt	fk
r�|g|j|<YnX|j
||�d|_tjd||f�|jdkr�|j�|jS)aJ
        Add a value to a list of values specified by key. If the current value specified by the key is scalar/non-list,
        it is not overridden, but maintained in the list, along with the new value.
        :param key: The name of the list
        :param value: The value to append to the list
        :return: None
        Nz$Will not add value '%s' to key '%s'.FTzAdding value '%s' to key '%s'.)rr^r2r3r4r,rrrar5r6r�r�)rr7r8r9rrrr:�s*



zSyncedStore.addc
Cs�t|�}t|�}y�|j|}|dk	rBt|t�rB||krB|j|�S||krt|j|j|�d|_tjd||f�nd|_tjd||f�|jSWn2t	t
tfk
r�tjd||f�d|_YnX|jdkr�|j�|jS)aN
        Remove a value from a list specified by key.
        If the current value specified by the key is not a list, unset the value.
        :param key: The name of the list parameter to manipulate
        :param value: The value to attempt to remove
        :return: True if the value was in the list, False if it was not
        NTz"Removing value '%s' from key '%s'.Fz)Will not remove value '%s' from key '%s'.)
rr^r2r3r;r<rar,rrr5r6r"r�)rr7r8Zcurrent_valuesrrrr<
s&



zSyncedStore.removecCs�t|�}|dkr*|jj|d�}d|j|<n0|dkrL|jj|d�}g|j|<n|jj|d�}d|_tjd||f�|dk	|_|jdkr�|j�|jS)z\
        Unsets a key
        :param key: The key to unset
        :return: boolean
        r
Nr=rTz!Unsetting value '%s' of key '%s'.)rr^r>r?rar,rrr�)rr7r8rrrr;,s

zSyncedStore.unsetcCs�t|�}t|�}t|jj|d��}||j|<||ks<|dkrb|j||�d|_tjd||f�n
tjd�||kpz|dk|_|jdkr�|j�|jS)z�
        Set a key (syspurpose parameter) to value
        :param key: The parameter of the syspurpose file to set
        :type key: str

        :param value: The value to set that parameter to
        :return: Whether any change was made
        NTzSetting value '%s' to key '%s'.z#NOT Setting value '%s' to key '%s'.)rr^r>r�rar,rrr�)rr7r8r9rrrr@Is	


zSyncedStore.setcCshtjj|�sdtjd|�ytj|ddd�Wn4tk
rb}ztjd||f�WYdd}~XnXdS)zr
        Try to create missing directory
        :param dir_path: path to directory
        :return: None
        zTrying to create directory: %si�T)�mode�exist_okz)Unable to create directory: %s, error: %sN)r#r�isdirr,rr�makedirsruZwarning)Zdir_pathrlrrr�_create_missing_dirgszSyncedStore._create_missing_dircCs�|jt�|jt�ytj|ddd�}Wn.tk
rV}z|jdkrF�WYdd}~Xn*Xt||�|j�|j	�t
jd|�t
jd|�dS)a
        Write the contents of data to file in the first mode we can (effectively to create or update
        the file)
        :param path: The string path to the file location we should update
        :param data: The data to write to the file
        :return: None
        zw+zutf-8)r�Nz/Successfully updated syspurpose values at '%s'.z+Failed to update syspurpose values at '%s'.)r��USER_SYSPURPOSE_DIR�	CACHE_DIRrrr(r)r	rB�closer,rr)rGrrr-r.rrrr�vs



zSyncedStore._update_filecCs�d}|jdk	r�|jdk	r�|jj|j�}d|kr�|d}y|jj|�}Wn0tk
rv}ztjd|�WYdd}~XnXd|kr�t|�}|d}|S)z�
        Try to get valid fields from server using current owner (organization)
        :return: Dictionary with valid fields
        Nr7z*Unable to get valid fields from server: %sr)rWrcZgetOwnerZgetOwnerSyspurposeValidFieldsrur,rrr)rreZ
current_ownerZ	owner_keyZresponserlrrrrd�s zSyncedStore.get_valid_fields)NNF)NNN)!rIrJrKrL�USER_SYSPURPOSErX�CACHED_SYSPURPOSEr[rrfrirgrjrtrwr]rvr_ryr�rzr�rxr�r:r<r;r@�staticmethodr�rMr�rdrrrrrS�s4
*

	+"rS�
DiffChanger7�previous_value�	new_value�source�in_base�	in_resultrnc	Cs�tjd�i}|pi}|pi}|p$i}|dkr4|}n|dkrB|}ntd��|dkrZdd�}t|j��t|j��Bt|j��B}�x(|D�]}t|||dd�}	t|||d	d�}
|	p�|
o�|
tk}d
}|	|
kr�|	dkr�tjd|�|}||kr�||||<nv|
dk�r,tjd
|�d}||k�rn||||<nB|	�s<|
tk�rn|	dk�rTtjd|�d}||k�rn||||<|r�|j|�}
t|||
|j|�||k||kd�}||�q�W|S)a�
    Performs a three-way merge on the local and remote dictionaries with a given base.
    :param local: The dictionary of the current local values
    :param base: The dictionary with the values we've last seen
    :param remote: The dictionary with "their" values
    :param on_conflict: Either "remote" or "local" or None. If "remote", the remote changes
                               will win any conflict. If "local", the local changes will win any
                               conflict. If anything else, an error will be thrown.
    :param on_change: This is an optional function which will be given each change as it is
                      detected.
    :return: The dictionary of values as merged between the three provided dictionaries.
    zAttempting a three-way merge...rnrmzAkeyword argument "on_conflict" must be either "remote" or "local"NcSs|S)Nr)Zchangerrr�<lambda>�sz!three_way_merge.<locals>.<lambda>)ro�otherr7r��serverroTzLThree way merge conflict: both local and remote values changed for key '%s'.z7Three way merge: remote value was changed for key '%s'.z6Three way merge: local value was changed for key '%s'.)r7r�r�r�r�r�)	r,rrr"r@r��detect_changed�UNSUPPORTEDr>r�)rmrornZon_conflictr{rO�winnerZall_keysr7rQrPrar��originalZdiffrrrr|�sT
$




r|r�cCs�|pi}|pi}||kr$|dkr$tS|j|�}|j|�}||krP|dkrPt|�St|�tkrxt|�tkrxt|�t|�kS|dkr�|dkr�|dkr�dS||kS)aX
    Detect the type of change that has occurred between base and other for a given key.
    :param base: The dictionary of values we are starting with
    :param other: The dictionary of now current values
    :param key: The key that we are interested in knowing how it changed
    :param source: An optional string which indicates where the "other" values came from. Used to
                   make decisions which are one sided. (i.e. only applicable for changes from the
                   server side).
    :return: True if there was a change, false if there was no change
    :rtype: bool
    rmr�Nr=F)r�r>�bool�typer3�sorted)ror�r7r�Zbase_valZ	other_valrrrr��s

r�)rnN)r�)-Z
__future__rrr�collectionsZloggingr r#r)rZsyspurpose.utilsrrrrr	Zsyspurpose.i18nr
r&r�r�joinr�ZVALID_FIELDSr�r�r�r�r�r�rr~r�Z	getLoggerrIr,r�objectrrNrS�
namedtupler�r|r�rrrr�<module>sJ
 1
B

?>