%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python2.7/site-packages/salt/states/
Upload File :
Create Path :
Current File : //lib/python2.7/site-packages/salt/states/file.pyo

�
���^c$@@s�dZddlmZmZmZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlmZmZmZddlmZmZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl!Zddl"Zddl#Zddl$m%Z%ddl&m'Z'ddl(m)Z*ej+j,j-�r�ddl.Zddl/Zddl0Zndd	l1m2Z2dd
l3m4Z4ddl5m6Z7ej+j,j-�r:ddl8Z8ddl9Z:nej;e<�Z=dZ>e?�Z@id
d6ZAd�ZBd�ZCd�ZDd�ZEeFd�ZGd�ZHeIeFeFeFeId�ZJeFd�ZKd�ZLd�ZMd�ZNd�ZOeFeFeIeFeFeIeIeFeFeId�
ZPeFeFeFeFeFd�ZQeId�ZRd�ZSd�ZTd �ZUd!�ZVd"�ZWeFd#�ZXeFeFeFeFd$�ZYeFd%eFeFd&�ZZeFd'�Z[d(�Z\d)�Z]d*�Z^d+�Z_eFeFeFeFeFeFeFd,�Z`eIeFeIeFeFeFeFeFeFeFd-�
Zad.�ZbdeFeIdd/�Zcd0�Zdd1�ZeeFd2eFefeFeFeFeFeFeIeFeFefeFd2efefeFd2d2eFeFefd3eFd4efefeFeIeFeFeFefeId5�#Zgd6d7d8d9d:gZhd;�ZieFd<�ZjeFeFeFeFeFeFeIeIeFeFeIeIeFefeIeFeFeFefeId=�ZkefeIeFeFeFeFeFeFeFeFefeFeId2eFeFeFeIeIeFeFeFefd>�ZleFeFd?�ZmeFeFeFeFeFeFefeIeIefeIeFeFeFd@�ZnddAdBeIeIeFdCefeIeIdD�
ZodEdFeFeFd%eFeFeFeFd2eIeIdCefeFdG�ZpdHdCdI�ZqdHdCdJ�ZreFeIeFeFd%eFeFeFeFefdK�
ZseFeIeFeFd%eFeFeFeFeFdL�
ZteFeFeFeIeFeFeFd2eFeFeFdM�ZueFeFeIdN�ZveIeIeIeFeFeFeIdO�ZweIeIdP�ZxdQ�ZyeFeFeFeFeFd2eIefefeIeFd4eFeFdR�ZzddeFeFdSdT�Z{dU�Z|eFeFdVdWdX�Z}eFeFeFeFeIeFeIeFdY�Z~d2eFeIdZd[�ZdZd\�Z�dS(]u�!
Operations on regular files, special files, directories, and symlinks
=====================================================================

Salt States can aggressively manipulate files on a system. There are a number
of ways in which files can be managed.

Regular files can be enforced with the :mod:`file.managed
<salt.states.file.managed>` state. This state downloads files from the salt
master and places them on the target system. Managed files can be rendered as a
jinja, mako, or wempy template, adding a dynamic component to file management.
An example of :mod:`file.managed <salt.states.file.managed>` which makes use of
the jinja templating system would look like this:

.. code-block:: jinja

    /etc/http/conf/http.conf:
      file.managed:
        - source: salt://apache/http.conf
        - user: root
        - group: root
        - mode: 644
        - attrs: ai
        - template: jinja
        - defaults:
            custom_var: "default value"
            other_var: 123
    {% if grains['os'] == 'Ubuntu' %}
        - context:
            custom_var: "override"
    {% endif %}

It is also possible to use the :mod:`py renderer <salt.renderers.py>` as a
templating option. The template would be a Python script which would need to
contain a function called ``run()``, which returns a string. All arguments
to the state will be made available to the Python script as globals. The
returned string will be the contents of the managed file. For example:

.. code-block:: python

    def run():
        lines = ['foo', 'bar', 'baz']
        lines.extend([source, name, user, context])  # Arguments as globals
        return '\n\n'.join(lines)

.. note::

    The ``defaults`` and ``context`` arguments require extra indentation (four
    spaces instead of the normal two) in order to create a nested dictionary.
    :ref:`More information <nested-dict-indentation>`.

If using a template, any user-defined template variables in the file defined in
``source`` must be passed in using the ``defaults`` and/or ``context``
arguments. The general best practice is to place default values in
``defaults``, with conditional overrides going into ``context``, as seen above.

The template will receive a variable ``custom_var``, which would be accessed in
the template using ``{{ custom_var }}``. If the operating system is Ubuntu, the
value of the variable ``custom_var`` would be *override*, otherwise it is the
default *default value*

The ``source`` parameter can be specified as a list. If this is done, then the
first file to be matched will be the one that is used. This allows you to have
a default file on which to fall back if the desired file does not exist on the
salt fileserver. Here's an example:

.. code-block:: jinja

    /etc/foo.conf:
      file.managed:
        - source:
          - salt://foo.conf.{{ grains['fqdn'] }}
          - salt://foo.conf.fallback
        - user: foo
        - group: users
        - mode: 644
        - attrs: i
        - backup: minion

.. note::

    Salt supports backing up managed files via the backup option. For more
    details on this functionality please review the
    :ref:`backup_mode documentation <file-state-backups>`.

The ``source`` parameter can also specify a file in another Salt environment.
In this example ``foo.conf`` in the ``dev`` environment will be used instead.

.. code-block:: yaml

    /etc/foo.conf:
      file.managed:
        - source:
          - 'salt://foo.conf?saltenv=dev'
        - user: foo
        - group: users
        - mode: '0644'
        - attrs: i

.. warning::

    When using a mode that includes a leading zero you must wrap the
    value in single quotes. If the value is not wrapped in quotes it
    will be read by YAML as an integer and evaluated as an octal.

The ``names`` parameter, which is part of the state compiler, can be used to
expand the contents of a single state declaration into multiple, single state
declarations. Each item in the ``names`` list receives its own individual state
``name`` and is converted into its own low-data structure. This is a convenient
way to manage several files with similar attributes.

.. code-block:: yaml

    salt_master_conf:
      file.managed:
        - user: root
        - group: root
        - mode: '0644'
        - names:
          - /etc/salt/master.d/master.conf:
            - source: salt://saltmaster/master.conf
          - /etc/salt/minion.d/minion-99.conf:
            - source: salt://saltmaster/minion.conf

.. note::

    There is more documentation about this feature in the :ref:`Names declaration
    <names-declaration>` section of the :ref:`Highstate docs <states-highstate>`.

Special files can be managed via the ``mknod`` function. This function will
create and enforce the permissions on a special file. The function supports the
creation of character devices, block devices, and FIFO pipes. The function will
create the directory structure up to the special file if it is needed on the
minion. The function will not overwrite or operate on (change major/minor
numbers) existing special files with the exception of user, group, and
permissions. In most cases the creation of some special files require root
permissions on the minion. This would require that the minion to be run as the
root user. Here is an example of a character device:

.. code-block:: yaml

    /var/named/chroot/dev/random:
      file.mknod:
        - ntype: c
        - major: 1
        - minor: 8
        - user: named
        - group: named
        - mode: 660

Here is an example of a block device:

.. code-block:: yaml

    /var/named/chroot/dev/loop0:
      file.mknod:
        - ntype: b
        - major: 7
        - minor: 0
        - user: named
        - group: named
        - mode: 660

Here is an example of a fifo pipe:

.. code-block:: yaml

    /var/named/chroot/var/log/logfifo:
      file.mknod:
        - ntype: p
        - user: named
        - group: named
        - mode: 660

Directories can be managed via the ``directory`` function. This function can
create and enforce the permissions on a directory. A directory statement will
look like this:

.. code-block:: yaml

    /srv/stuff/substuf:
      file.directory:
        - user: fred
        - group: users
        - mode: 755
        - makedirs: True

If you need to enforce user and/or group ownership or permissions recursively
on the directory's contents, you can do so by adding a ``recurse`` directive:

.. code-block:: yaml

    /srv/stuff/substuf:
      file.directory:
        - user: fred
        - group: users
        - mode: 755
        - makedirs: True
        - recurse:
          - user
          - group
          - mode

As a default, ``mode`` will resolve to ``dir_mode`` and ``file_mode``, to
specify both directory and file permissions, use this form:

.. code-block:: yaml

    /srv/stuff/substuf:
      file.directory:
        - user: fred
        - group: users
        - file_mode: 744
        - dir_mode: 755
        - makedirs: True
        - recurse:
          - user
          - group
          - mode

Symlinks can be easily created; the symlink function is very simple and only
takes a few arguments:

.. code-block:: yaml

    /etc/grub.conf:
      file.symlink:
        - target: /boot/grub/grub.conf

Recursive directory management can also be set via the ``recurse``
function. Recursive directory management allows for a directory on the salt
master to be recursively copied down to the minion. This is a great tool for
deploying large code and configuration systems. A state using ``recurse``
would look something like this:

.. code-block:: yaml

    /opt/code/flask:
      file.recurse:
        - source: salt://code/flask
        - include_empty: True

A more complex ``recurse`` example:

.. code-block:: jinja

    {% set site_user = 'testuser' %}
    {% set site_name = 'test_site' %}
    {% set project_name = 'test_proj' %}
    {% set sites_dir = 'test_dir' %}

    django-project:
      file.recurse:
        - name: {{ sites_dir }}/{{ site_name }}/{{ project_name }}
        - user: {{ site_user }}
        - dir_mode: 2775
        - file_mode: '0644'
        - template: jinja
        - source: salt://project/templates_dir
        - include_empty: True

Retention scheduling can be applied to manage contents of backup directories.
For example:

.. code-block:: yaml

    /var/backups/example_directory:
      file.retention_schedule:
        - strptime_format: example_name_%Y%m%dT%H%M%S.tar.bz2
        - retain:
            most_recent: 5
            first_of_hour: 4
            first_of_day: 14
            first_of_week: 6
            first_of_month: 6
            first_of_year: all

i(tabsolute_importtprint_functiontunicode_literalsN(tIterabletMappingtdefaultdict(tdatetimetdate(tCommandExecutionError(tDeserializationError(tget_accumulator_dir(tsix(tzip_longest(turlparseu^([[:space:]]*){0}[[:space:]]?ucopyucopy_cC@stjjttd�t�S(u'
    Return accumulator data path.
    ucachedir(tostpathtjoint_get_accumulator_dirt__opts__t__instance_id__(((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_get_accumulator_filepathRs	
cC@s*d�}|t��}|d|dfS(NcS@s�tjjt�}iid6id6}yBtjjj|d��$}|j|�}|r]|S|SWdQXWntt	fk
r�|SXdS(Nuaccumulatorsuaccumulators_depsurb(
tsalttpayloadtSerialRtutilstfilestfopentloadtIOErrort	NameError(Rtserialtrettftloaded((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_deserialize]suaccumulatorsuaccumulators_deps(R(R"R!((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_load_accumulators\s	cC@svi|d6|d6}tjjt�}y8tjjjt�d��}|j||�WdQXWnt	k
rqnXdS(Nuaccumulatorsuaccumulators_depsuw+b(
RRRRRRRRtdumpR(taccumulatorstaccumulators_depstaccumm_dataRR ((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_persist_accummulatorsms


cC@s�d}|rAtd|�}|dkrA|dj|�7}qAn|r|td|�}|dkr||dj|�7}q|n|S(uF
    Checks if the named user and group are present on the minion
    uufile.user_to_uiduUser {0} is not available ufile.group_to_giduGroup {0} is not available(t__salt__tformat(tusertgroupterrtuidtgid((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_userzscC@sntjtj}}||||||kr3tS|dk	rj|j|�j|�}||krjtSntS(u2
    Performs basic sanity checks on a relative path.

    Requires POSIX-compatible paths (i.e. the kind obtained through
    cp.list_master or other such calls).

    Ensures that the path does not contain directory transversal, and
    that it does not exceed a stated maximum depth (if specified).
    N(t	posixpathtseptpardirtFalsetNonetstriptcounttTrue(trelpathtmaxdepthR2R3t
path_depth((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_is_valid_relpath�scC@s%tjj|jtjtjj��S(ud
    Converts a path from the form received via salt master to the OS's native
    path format.
    (RRtnormpathtreplaceR1R2(R((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_salt_to_os_path�sc@s��fd����������fd�}t�}	t�}
t��t��t��tjjj|�\�}|d
kr�t}n�jtj	�s��tj	�nt
d|��}|r�t
d|��}
|||
�}nx�|D]�}|j�sq�ntjjj
tj|���}t|d��sHq�ntjjj|���siq�n�|�}tjj|�}�j|�|�kr�|
j|��j|�ntjjj|d|�}|	j||f�q�W|r�t
d|��}x�|D]�}tj|��}t|d��s?qntjjj|���s`qn�|�}|r�t}x@|
D]8}|j|d�rtjd	j|��t}PqqW|r�qq�n|
j|��j|�qWn|	|
��fS(u?
    Generate the list of files managed by a recurse state
    c@stjj�t|��S(N(RRRR?(tmaster_relpath(tname(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	full_path�sc@s�x�tj|�D]�\}}tj|��}t|d��sFqntjjj|���sgqnt	|�}xC|D];}|j
|�rztjdj
|��|j|�qzqzW�j||f��j�|��qW�j��|S(NR:u0** skipping file ** {0}, it intersects a symlink(Rt	iteritemsR1R9R<RRtstringutilstcheck_include_excludetlistt
startswithtlogtdebugR*tremovetaddtupdate(t	filenamestsymlinkstlnametltargettsrelpatht
_filenamestfilename(texclude_patRBtinclude_pattkeeptmanaged_symlinksR:tsrcpathtvdir(s4/usr/lib/python2.7/site-packages/salt/states/file.pytprocess_symlinks�s"


ucp.list_masterucp.list_master_symlinksR:tsaltenvucp.list_master_dirsiu5** skipping empty dir ** {0}, it intersects a symlinkN(tsetRRturltparseR5t__env__tendswithR1R2R)R6tdatatdecodeR9R<RDRERRtdirnameRKtcreateR4RGRHRIR*R8(RAtsourcet
keep_symlinksRURTR:t
include_emptytkwargsRZt
managed_filestmanaged_directoriestsenvtfns_RNtfn_trelnametdestRctsrctmdirstmdirtmdesttislinktlink((	RTRBRURVRWR:RARXRYs4/usr/lib/python2.7/site-packages/salt/states/file.pyt_gen_recurse_managed_files�sp$						
!




	
c@s�d�}�fd������fd��d�}t�}t|t�r�g|D]}d|krX|^qX}x|D]}xtD]�}|d|dks�|d|dkr�|d}	|d}
tjj|	�rw||	|�r�|
d	kr2t|�d
}tj	dj
|	|��|j|�qt�r^t���|	��|j��qt|j||	��q�q�|j|	�q�q�Wq}Wntj	dj
t|���t|�S(
u~
    Generate the list of files that need to be kept when a dir based function
    like directory or recurse has a clean.
    cS@sJtjj|�}tjj|�}tjj||�}|jtj�S(uB
        Check whether ``path`` is child of ``directory``
        (RRtabspathR9RGR3(Rt	directorytrelative((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	_is_child.sc@s�t�}tjj|�r��j|ddf�\}}|j|�x*|D]"}|jtjj||��qMWx-|D]"}|jtjj||��qzWn|S(N(((R\RRtisdirtgetRKR(Rt_rettdirsRt_name(twalk_d(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_add_current_path9s	

 
#c@s�tjj|�r��j�|���j|ddf�\}}xF|D];}tjj||�}�j�|���||�qJWndS(N(((RRR{RLR|R(RARR~t_t_dtp(R�t_process_by_walk_dR�twalk_ret(s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�Ds
cS@s�t�}tjj|�r�x�tjjj|�D]v\}}}|j|�x*|D]"}|jtjj||��qTWx*|D]"}|jtjj||��q�Wq1Wn|S(N(	R\RRR{RRtos_walkRKR(RARtrootR~R((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_processMs	%

 
'ufileunameu__id__ufunurecurseiuKeep from {0}: {1}u'Files to keep from required states: {0}(
R\t
isinstanceRFt__lowstate__RRR{RvRHRIR*RLRK(RAtrequireR�RzR�RVtcomptrequired_filestlowtfntfuntfkeep((R�R�R�R�s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_gen_keep_files)s4				%

(

	
cC@sjt}d}tjj|�s6t}dj|�}n*tjj|�s`t}dj|�}n||fS(Nuu*Specified file {0} is not an absolute pathu{0}: file not found(R8RRtisabsR4R*texists(RARtmsg((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_filetscC@s�t�}|j|�t|t�r�x�|D]�}tjj|�sJq,ntjjtjj|��}|j|�xct	r�tjjtjj
|��}|j|�tjj|�\}}|jtj
�sxPqxqxWq,Wn|S(uX
    Compile a list of valid keep files (and directories).
    Used by _clean_dir()
    (R\RKR�RFRRR�tnormcaseRwR8Rct
splitdrivetlstripR2(R�RVt	real_keepRmtdriveR((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_find_keep_files�s	


	
c@s�tjj���t�|��t������fd�}x\tjjj��D]E\}}}x3tj	||�D]}|tjj
||��qzWqXWt��S(u�
    Clean out all of the files and directories in a directory (root) while
    preserving the files in a list (keep) and part of exclude_pat
    c@s�|�kr�tjjjtjj|��d��s:dS�j|�t	ds�ytj
|�Wq�tk
r�td|�q�Xq�ndS(Nutestufile.remove(
RRRDRERRR9R5RKRRJtOSErrorR)(tnfn(RTR�tremovedR�(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_delete_not_kept�s


(RRR�R�R\RRR�t	itertoolstchainRRF(R�RVRTR�trootsR~RRA((RTR�R�R�s4/usr/lib/python2.7/site-packages/salt/states/file.pyt
_clean_dir�s	%!cC@st|d<||d<|S(Nuresultucomment(R4(Rterr_msg((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_error�s

c
@s�i}|s|r]tt�|	��}i}
x-|D]"}|d|df|
|d<q4Wn|r|yt|�}Wn,ttfk
r�}tdj|�|fSXd|kr�d}nd|kr�d}nd|kr�d}d}nd|k}d	|k}xz|D]o\�}}|rx�|D]�}i}tj	j
�|�}td
|d|
�}|dk	r�||jd�kr�||d<n|dk	r�||jd�kr�||d<n|dk	rt
jjj|�t
jjj|jd��kr||d<n|r"|||<q"q"Wn|rxQ|D]F}tj	j
�|�}t|||||
�}|r(|||<q(q(WqqWnt�||||
�}|r�||�<n|r<t�||
������fd�}xb|D]W\�}}x!|D]}|j||��q�Wx!|D]}|j||��qWq�Wntj	j��sbidd
6|�<n|r�dg}xN|D]F}x=tj||�D](\}}|jdj|||��q�WqxWddj
|�|fStdj��|fS(u;
    Check what changes need to be made on a directory
    iiiu{0}uuserugroupumodeuignore_filesuignore_dirsu
file.statsc@sitjj�|�}|�kr%iStjjjtjj|��d��sSiSiidd6|6SdS(NuRemoved due to cleanuremoved(	RRRRRRDRER9R5(tfnameR(RTRVRAR�(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_changes�sunewu	directoryu%The following files will be changed:
u{0}: {1} - {2}
uu)The directory {0} is in the correct stateN(RFt_depth_limited_walkt_get_recurse_sett	TypeErrort
ValueErrorR4R*R5RRRR)R|RRRtnormalize_modet_check_dir_metaR�RLR{RRCtappendR8(RAR+R,trecursetdir_modet	file_modetcleanR�RTt	max_depthtfollow_symlinkstchangestwalk_lR�titrecurse_settexctcheck_filest
check_dirsR~RR�tfchangeRtstatstname_R�tcommentsRmtkeytval((RTRVRAR�s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_directory�sz
#			
!
!
?




	
 $c	C@s�i}tjj|�s/iidd6|6}n=|dk	r�tjjj|�}tjjj	|�}tjjj	|�}	||	ks�||d<q�ntjjj
|�}
|dk	r�x<|D]1}ytjjj|�Wntk
r�q�nXg}t
||dtj�rItjjj||||d�s�||d}q�nRxO||dD]?}
tjjj|||
dt�sX|j||d�qXqXW|r�d|kr�i|d<n||dkr�i|d|<n||d|d<nd||kr	d}n||d}||
kr�tjjj|�}tjjj�jd	|}tjjj�jd	|}d
|
|kr�|
|d
d|ks�d|kr�i|d<n||dkr�i|d|<n||d|d<q�q�q�q�Wn|dk	rGxB|D]7}ytjjj|�Wntk
r<q	nXg}t
||dtj�r�tjjj||||dd�s�||d}q�nUxR||dD]B}
tjjj|||
ddt�s�|j||d�q�q�W|rAd
|kri|d
<n||d
kr,i|d
|<n||d
|d<nd||krZd}n||d}||
kr	tjjj|�}tjjj�jd	|}tjjj�jd	|}d|
|kr@|
|dd|ks=d
|kri|d
<n||d
kr%i|d
|<n||d
|d<q=q@q	q	Wn|dk	r~|tjjj|�ks~||d<q~n|rlx�|
D]�}||kr�d
|
|kr�|
|d
dr�d|kr�i|d<n|dji|
||6�q�n||kr�d|
|kre|
|ddred|krCi|d<n|dji|
||6�qeq�q�Wn|r�ddj|�|fStdj|�|fS(u;
    Check what changes need to be made on a directory
    unewu	directoryuownerupermstexactugrant_permsu
applies_touthis_folder_subfolders_filesufileugrantu
applies toudenyu
deny_permsuinheritanceu	inheriteduremove_permsu#The directory "{0}" will be changedu)The directory {0} is in the correct stateN(RRR{R5RRtwin_daclt	get_ownert
win_functionstget_sid_from_nametget_permissionstget_nameRR�Rtstring_typesthas_permissionR4R�tflagstace_proptget_inheritanceRLR*R8(RAt	win_ownert	win_permstwin_deny_permstwin_inheritancetwin_perms_resetR�t
current_ownertcurrent_owner_sidtexpected_owner_sidtpermsR+tgrant_permstpermt
applies_totat_flagtapplies_to_textt
deny_permst	user_name((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_directory_wins�	


	
"


	
"
#
"#
)cC@s!ytd|d	|�}Wntk
r3i}nXi}|sNd|d<|S|d	k	r�||dkr�||jd�kr�||d<n|d	k	r�||dkr�||jd�kr�||d<ntjjj|d�}tjjj|�}|d	k	r||kr||d<n|S(
u1
    Check the changes in directory metadata
    u
file.statsunewu	directoryuuseruuidugroupugidumodeN(R)R5RR|RRRR�(RAR+R,tmodeR�R�R�tsmode((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��s*





cC@sidd6dd6i|d6d6}tjj|�sJdj|�|d<n�td|dt�}|dk	r�tj|�tj|d	�ks�|dk	r�tj|�tj|d
�kr�dj|�|d<i|d6|d<nt	|d<d
j|�|d<|S(u?
    Check to see if a file needs to be updated or created
    uresultuucommentunewuchangesuFile {0} is set to be createdu
file.statsR�uatimeumtimeu#Times set to be updated on file {0}utouchedu)File {0} exists and has the correct timesN(
R5RRR�R*R)R4Rt	text_typeR8(RAtatimetmtimeRR�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_touch�s ""
cC@s_tjjj�r1tjjj|�}||fStd|dt�td|dt�fSdS(Nu
file.get_userR�ufile.get_group(RRtplatformt
is_windowsR�R�R)R4(Rtowner((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_get_symlink_ownership�s

cC@sHt|�\}}tjjj�r.||kS||koC||kSdS(uM
    Check if the symlink ownership matches the specified user and group
    N(R�RRR�R�(RR+R,R�tcur_usert	cur_group((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_symlink_ownership�s
cC@s�tjjj�rCytjjj||�Wqotk
r?qoXn,ytd|||�Wntk
rnnXt	||||�S(u\
    Set the ownership of a symlink and return a boolean indicating
    success/failure
    ufile.lchown(
RRR�R�R�t	set_ownerRR)R�R�(RR+R,R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_set_symlink_ownership�s

c	C@sJi}tjj|�rMtd|�rM||d<d
dj||�|fStd|�rtd|�|kr�||d<d
dj||�|fSt}dj|�}t||||�sd
}djt|��|d	<|d
j||t|��7}n|||fSn5|r0d
dj||�|fSt	dj|�|fSd
S(u$
    Check the symlink function
    ufile.is_linkunewu&Symlink {0} to {1} is set for creationu
file.readlinkuchangeu+Link {0} target is set to be changed to {1}uThe symlink {0} is presentu{0}:{1}u	ownershipuK, but the ownership of the symlink would be changed from {2}:{3} to {0}:{1}uXThe file or directory {0} is set for removal to make way for a new symlink targeting {1}uTFile or directory exists where the symlink {0} should be. Did you mean to use force?N(
RRR�R)R5R*R8R�R�R4(	RAttargettforceR+R,R�R�tresultR�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_symlink_checks4$
		
				cC@s/|r
|Sd|kr+tjd�|dS|S(u�
    Convert owner to user, since other config management tools use owner,
    no need to punish people coming from other systems.
    PLEASE DO NOT DOCUMENT THIS! WE USE USER, NOT OWNER!!!!
    uowneruBUse of argument owner found, "owner" is invalid, please use "user"(RHtwarning(RhR+((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_test_owner3sc
C@s�|dkrg}n|dkr*g}n|rC|rCtdgfS|r\|r\tdgfS|rxtd||fgfStdtt||t|� ��fS(ub
    Silly little function to give us a standard tuple list for sources and
    source_hashes
    u)source and sources are mutually exclusiveu4source_hash and source_hashes are mutually exclusiveuN(R5R4R8RFRtlen(Retsource_hashtsourcest
source_hashes((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_unify_sources_and_hashesEs		

ujinjacK@s�idd6id6td6dd6gd6}|dkrBt|d�Sg}xt|D]l\}}|rg|ni}	|r�|	j|�ntd	|dd
|dtd|	|�}
d
}tj|j|
|��|
r�d}t	j
jj|
d��7}
|
j
�}t	j
jj|�}|jt�}WdQX|sod}tj|j|
|��||d<t||j|
|��S|jdj|��qOdj|�}tj|�||d<t||�SqOW||d<|S(u�
    Iterate a list of sources and process them as templates.
    Returns a list of 'chunks' containing the rendered templates.
    u_get_template_textsunameuchangesuresultuucommentudatau1_get_template_texts called with empty source_listucp.get_templatettemplateR[tcontextu/cp.get_template returned {0} (Called with: {1})urbNu/Failed to read rendered template file {0} ({1})u Failed to load template file {0}(R8R5R�RLR)R_RHRIR*RRRRtreadRDt
to_unicodet
splitlinesR�R(tsource_listR�tdefaultsR�RhRttxtlReR�ttmpctxtrndrd_templ_fnR�ttmplinestfp_((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_get_template_texts`sP


	



cC@s�t|tj�r3tjjj|d|�g}n�t|tj�rQ|g}n�t|t�r�t|t	�r�g}x[|D]>}t|tj�r�|j
|�q}|j
tj|��q}Wntj|�g}|S(u-
    ensure ``arg`` is a list of strings
    tencoding(R�Rtbinary_typeRRRDR�R�RRR�R�(targR	Rtitem((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_validate_str_list�s!
cC@std|dt�S(Nu
file.get_userR�(R)R4(R((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_get_shortcut_ownership�scC@st|�}||kS(uD
    Check if the shortcut ownership matches the specified user
    (R(RR+R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_check_shortcut_ownership�scC@s6ytd||�Wntk
r(nXt||�S(u]
    Set the ownership of a shortcut and return a boolean indicating
    success/failure
    ufile.lchown(R)R�R(RR+((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_set_shortcut_ownership�s

cC@s+i}tjj|�s;||d<ddj||�|fStjj|�r�tjjj	��t
jjd�}	WdQX|	j
|�}
|
jj�|j�kg}|dk	r�|j|
j|k�n|dk	r�|j|
jj�|j�k�n|dk	r |j|
j|k�n|dk	rQ|j|
jj�|j�k�nt|�s�||d<ddj||�|fSt}dj|�}
t||�s�d}djt|��|d	<|
d
j|t|��7}
n||
|fSn5|rddj||�|fStdj|�|fSdS(
u%
    Check the shortcut function
    unewu+Shortcut "{0}" to "{1}" is set for creationu
WScript.ShellNuchangeu3Shortcut "{0}" target is set to be changed to "{1}"uThe shortcut "{0}" is presentu{0}u	ownershipuD, but the ownership of the shortcut would be changed from {1} to {0}u]The link or directory "{0}" is set for removal to make way for a new shortcut targeting "{1}"uWLink or directory exists where the shortcut "{0}" should be. Did you mean to use force?(RRR�R5R*tisfileRRtwinapitComtwin32comtclienttDispatchtCreateShortcutt
TargetPathtlowerR�t	ArgumentstWorkingDirectorytDescriptiontIconLocationtallR8RRR4(RAR�t	argumentstworking_dirtdescriptiont
icon_locationR�R+R�tshelltscuttstate_checksR�R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_shortcut_check�sP
		
				c
C@s�tjjj�r�tjj|�\}}	tjj|�sKt|��n|rW|n|}t	dd|d|d|d|d|�St	dd|d|d|d	|�Sd
S(u�
    Helper function for creating directories when the ``makedirs`` option is set
    to ``True``. Handles Unix and Windows based systems

    .. versionadded:: 2017.7.8

    Args:
        name (str): The directory path to create
        user (str): The linux user to own the directory
        group (str): The linux group to own the directory
        dir_mode (str): The linux mode to apply to the directory
        win_owner (str): The Windows user to own the directory
        win_perms (dict): A dictionary of grant permissions for Windows
        win_deny_perms (dict): A dictionary of deny permissions for Windows
        win_inheritance (bool): True to inherit permissions on Windows

    Returns:
        bool: True if successful, otherwise False on Windows
        str: Error messages on failure on Linux
        None: On successful creation on Linux

    Raises:
        CommandExecutionError: If the drive is not mounted on Windows
    u
file.makedirsRR�R�R�tinheritanceR+R,R�N(
RRR�R�RRR�R{RR)(
RAR+R,R�R�R�R�R�R�R((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	_makedirss cK@s�tjj|�}tjjj|�}t|d|�}i|d6id6td6dd6}
|snt	|
d�S|d>kr�td}ntjjj
�rtd	|�s�td
�}|s�d}q�n|d>kr�|r�|nd>}n|d>k	rtjdj|��n|}n|d>krLtd
td	|�jdd��}ng}tjjj
�rdytjjj|�Wn)tk
r�}|jdj|��nX|	rxT|	D]I}ytjjj|�Wq�tk
r�}|jdj|��q�Xq�Wn|
r�xT|
D]I}ytjjj|�Wqtk
rY}|jdj|��qXqWq�njtd|�}td|�}|dkr�|jdj|��n|dkr�|jdj|��ntjj|�s�|jdj|��n|r:dj|�}t|�dkr-|d7}nt	|
|�St||||||�\}}}tjjtjj|��si|rtdr�|djtjj|��7}qfy;td|d|d|d|d|d|	d|
d |�Wqftk
r}t	|
d!j|j��SXqitdrD|d"jtjj|��7}qit	|
d#jtjj|���Sntdr�||
d<||
d<||
d<|
Std$|�r$tjjtd%|��tjj|�kr�tj |�q�t!||||�r?tjjj
�r#d&j||�|
d<qd'j|||�|
d<n�t"||||�r�tjjj
�r�d(j||�|
d<||
dd)<qd*j|||�|
d<d+j||�|
dd)<nZt#|
d<tjjj
�r�|
dcd,j||�7<n|
dcd-j|||�7<|
Sn�tjj$|�sHtjj|�r�|d>k	rvtjj|�s�|tjj%|�kr�tjjtjjtjj|��|�}q�t	|
d.j|��Sntjj&|�r|s�t	|
d/j|||��Std0|�nytd1||�Wq�t'k
rr}i|
d<tj(d2||d3t�t	|
d4j|||��SXq�|r�td$|�r�td0|�d5|
dd6<q�td0|�q�tjj$|�r�t	|
d7j|��St	|
d8j|��Sntjj)|�s�ytd9||�Wn7t*k
r]}t#|
d<d:j|||�|
d<|
SXd;j||�|
d<||
dd<<t!||||�s�t"||||�s�t#|
d<|
dcd=j||�7<q�q�n|
S(?uo

    Create a symbolic link (symlink, soft link)

    If the file already exists and is a symlink pointing to any location other
    than the specified target, the symlink will be replaced. If the symlink is
    a regular file or directory then the state will return False. If the
    regular file or directory is desired to be replaced with a symlink pass
    force: True, if it is to be renamed, pass a backupname.

    name
        The location of the symlink to create

    target
        The location that the symlink points to

    force
        If the name of the symlink exists and is not a symlink and
        force is set to False, the state will fail. If force is set to
        True, the file or directory in the way of the symlink file
        will be deleted to make room for the symlink, unless
        backupname is set, when it will be renamed

    backupname
        If the name of the symlink exists and is not a symlink, it will be
        renamed to the backupname. If the backupname already
        exists and force is False, the state will fail. Otherwise, the
        backupname will be removed first.
        An absolute path OR a basename file/directory name must be provided.
        The latter will be placed relative to the symlink destination's parent
        directory.

    makedirs
        If the location of the symlink does not already have a parent directory
        then the state will fail, setting makedirs to True will allow Salt to
        create the parent directory

    user
        The user to own the file, this defaults to the user salt is running as
        on the minion

    group
        The group ownership set for the file, this defaults to the group salt
        is running as on the minion. On Windows, this is ignored

    mode
        The permissions to set on this file, aka 644, 0775, 4664. Not supported
        on Windows.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

    win_owner : None
        The owner of the symlink and directories if ``makedirs`` is True. If
        this is not passed, ``user`` will be used. If ``user`` is not passed,
        the account under which Salt is running will be used.

        .. versionadded:: 2017.7.7

    win_perms : None
        A dictionary containing permissions to grant

        .. versionadded:: 2017.7.7

    win_deny_perms : None
        A dictionary containing permissions to deny

        .. versionadded:: 2017.7.7

    win_inheritance : None
        True to inherit permissions from parent, otherwise False

        .. versionadded:: 2017.7.7
    R+unameuchangesuresultuucommentu!Must provide name to file.symlinkuuseru	user.infouuser.currentuSYSTEMu�The group argument for {0} has been ignored as this is a Windows system. Please use the `win_*` parameters to set permissions in Windows.ufile.gid_to_groupugidiuUser {0} does not existufile.user_to_uidufile.group_to_giduGroup {0} does not existu*Specified file {0} is not an absolute pathu. iu.utestu
{0} will be createdRAR,R�R�R�R�R�uDrive {0} is not mappedu)
Directory {0} for symlink is not presentu(Directory {0} for symlink is not presentufile.is_linku
file.readlinku'Symlink {0} is present and owned by {1}u+Symlink {0} is present and owned by {1}:{2}u#Set ownership of symlink {0} to {1}u	ownershipu'Set ownership of symlink {0} to {1}:{2}u{0}:{1}u-Failed to set ownership of symlink {0} to {1}u1Failed to set ownership of symlink {0} to {1}:{2}u7Backupname must be an absolute path or a file name: {0}uHSymlink & backup dest exists and Force not set. {0} -> {1} - backup: {2}ufile.removeu	file.moveu#Encountered error renaming %s to %stexc_infou+Unable to rename {0} to backup {1} -> : {2}uSymlink was forcibly replaceduforcedu+File exists where the symlink {0} should beu0Directory exists where the symlink {0} should beufile.symlinku,Unable to create new symlink {0} -> {1}: {2}uCreated new symlink {0} -> {1}unewu,, but was unable to set ownership to {0}:{1}N(+RRt
expanduserRRRR�R�R8R�R5RR�R�R)RHR�R*R|R�R�RR�R�RR�R�R{RcR(tmessageR=RJR�R�R4Rtbasenametlexistst	ExceptionRIR�R�(RAR�R�t
backupnametmakedirsR+R,R�R�R�R�R�RhRtpreflight_errorsR�t
name_checkR.R/R�tpresulttpcommenttpchanges((s4/usr/lib/python2.7/site-packages/salt/states/file.pytsymlink7sTW





	"
!
$


"
	



.	


$	





cK@sctjj|�}i|d6id6td6dd6}|sGt|d�Stjj|�sot|dj|��S|dkr�t|d	�Stjj|�s�tjj|�rqt	d
r�d|d<||dd<dj|�|d<|Sy`tjj
j�rtd
|dt�ntd
|�dj|�|d<||dd<|SWqLtk
rm}t|dj|��SXn�tjj|�rLt	d
r�d|d<||dd<dj|�|d<|Sy`tjj
j�r�td
|dt�ntd
|�dj|�|d<||dd<|SWqLttfk
rHt|dj|��SXndj|�|d<|S(u!
    Make sure that the named file or directory is absent. If it exists, it will
    be deleted. This will work to reverse any of the functions in the file
    state module. If a directory is supplied, it will be recursively deleted.

    name
        The path which should be deleted
    unameuchangesuresultuucommentu Must provide name to file.absentu*Specified file {0} is not an absolute pathu/uRefusing to make "/" absentutesturemoveduFile {0} is set for removalufile.removeR�uRemoved file {0}u{0}u Directory {0} is set for removaluRemoved directory {0}uFailed to remove directory {0}uFile {0} is not presentN(RRR*R8R�R�R*RRtRR5RRR�R�R)RR{R�R(RARhRR�((s4/usr/lib/python2.7/site-packages/salt/states/file.pytabsentzsX




$



c@sTtjj|�}i|d6id6id6td6dd6}tjj|�sct|dj|��Stjj|�s�t|dj|��Sg}tj	�}|dkr�d	g}ng�x$|D]}	�jtj
|	��q�W�fd
�}
xPtjd|dt�D]6\}}}
x$|
|D]}d
}d
}t}tjj||�}tjj|�r�t|tjtj|�j��}nq||kr�t|tjtjj|���}|}n7t|tjtjj|���}tjj|�}||ks|j|kr$|
d|�r$|r$|j|�q$q$Wq
W|r=tdr�d|d<dj|�|d<i|d6|d<|Sg|dd<yaxZ|D]R}tjjj�r�td|dt�ntd|�|ddj|�q�WWn&tk
r}t|dj|��SXdjt |�|�|d<ndj|�|d<|S(u�
    Remove unwanted files based on specific criteria. Multiple criteria
    are OR’d together, so a file that is too large but is not old enough
    will still get tidied.

    If neither age nor size is given all files which match a pattern in
    matches will be removed.

    name
        The directory tree that should be tidied

    age
        Maximum age in days after which files are considered for removal

    matches
        List of regular expressions to restrict what gets removed.  Default: ['.*']

    rmdirs
        Whether or not it's allowed to remove directories

    size
        Maximum allowed file size. Files greater or equal to this size are
        removed. Doesn't apply to directories or symbolic links

    .. code-block:: yaml

        cleanup:
          file.tidied:
            - name: /tmp/salt_test
            - rmdirs: True
            - matches:
              - foo
              - b.*r
    unameuchangesupchangesuresultuucommentu*Specified file {0} is not an absolute pathu){0} does not exist or is not a directory.u.*c@s(x!�D]}|j|�rtSqWtS(N(tmatchR8R4(RAtprog(tprogs(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_matches�s
ttopttopdowniRAutestu{0} is set for tidyuremovedufile.removeR�u{0}u3Removed {0} files or directories from directory {1}u$Nothing to remove from directory {0}N(!RRR*R8R�R�R*R{RttodayR5R�tretcompiletwalkR4RRttabst
fromtimestamptlstattst_atimetgetatimetgetsizetdaysRRRR�R�R)RR�(RAtagetmatchestrmdirstsizeRhRttodeleteR>tregexR;R�R~RtelemtmyagetmysizetdeletemeRR�((R:s4/usr/lib/python2.7/site-packages/salt/states/file.pyttidied�sf(


((%	%0


cK@s�tjj|�}i|d6id6td6dd6}|sGt|d�Stjj|�sot|dj|��Sdj|�|d<|S(	ui
    Verify that the named file or directory is present or exists.
    Ensures pre-requisites outside of Salt's purview
    (e.g., keytabs, private keys, etc.) have been previously satisfied before
    deployment.

    This function does not create the file if it doesn't exist, it will return
    an error.

    name
        Absolute path which must exist
    unameuchangesuresultuucommentu Must provide name to file.existsu!Specified path {0} does not existuPath {0} exists(RRR*R8R�R�R*(RARhR((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�3s


cK@s�tjj|�}i|d6id6td6dd6}|sGt|d�Stjj|�rot|dj|��Sdj|�|d<|S(	u�
    Verify that the named file or directory is missing, this returns True only
    if the named file is missing but does not remove the file if it is present.

    name
        Absolute path which must NOT exist
    unameuchangesuresultuucommentu!Must provide name to file.missinguSpecified path {0} existsuPath {0} is missing(RRR*R8R�R�R*(RARhR((s4/usr/lib/python2.7/site-packages/salt/states/file.pytmissingPs	


uu:ustrictc$=3K@s�d|$kr|$jd�ntjj|�}iid6dd6|d6td6}%|rgt|%d�Sn|tk	o�tjj	j
�r�t|%d�Sn|tk	o�tjj	j
�r�t|%d	�Sny%|j�d
k}&|&r�t}nWntk
rt
}&nXtjjj|�}tg|||fD]}'|'tk	rB|'^q*�}(|oZ|(dkrmt|%d�Sn>|&o||(dkr�t|%d
�Sn|(dkr�t|%d�Sn|o�|(dko�|
r�t
}
tjdj|��nd|$kr|%jdg�jd�n|tk	r�t|t�r�g})xY|D]Q}*td|*td|�}+|+tkrwt|%dj|*��Sn|)j|+�q3Wtjj|)�},n>td|td|�},|,tkr�t|%dj|��Snn�|tk	r�t|t�rpg})xY|D]Q}-td|-td|�}+|+tkrJt|%dj|+��Sn|)j|+�qWtjj|)�},n>td|td|�},|,tkr�t|%dj|��Snn|tk	r�|},nt},|,tk	r�|o�|,r5|r�dj|�}.n|rdj|�}.nd}.t|%dj|.��Sny�t|,d|�}/|/rat|%d�Snd}xH|/D]@}0x7|0j�D])}1||1jd�jd �tj7}q�WqnW|o�|jtj�r�|tj7}nWn-t k
r|	rt|%d!�Sn|,}nX|	r�td"|d#|	d$|d%|d&t!�}t|t"j#�r�d|krj|d|%d<n
t
|%d<d|kr�|d|%d<n
d'|%d<|%Snnnt$|$d(|�}tjj	j
�r|tkr�|r�|nt}n|tk	rtjd)j|��n|}n|rRtjj%|�rOd*j|�|%d<|%Snnt&||�}2|2rwt|%|2�Sntjj'|�r�t|%d+j|��Sntjj(|�r�d,j|�|%d<t
|%d<|%Sn|tkr�i}n t|t)�rt|%d-�Sn|o!t|t)�r4t|%d.�Sn|
oJtjj*|�rdi}3tjj	j
�r�td/d0|d1|%d2|d3| d4|!d5|"d6|#�}%n(td/||%|||||�\}%}3t+d7r2t|3t)�o�d8|3ko�||3d8krd9j|||3d8�|%d<nd:j|�|%d<n+|%doD|%dr]d;j|�|%d<n|%Snt,�\}4}5||4kr�|r�i}n|4||d<<ny�t+d7r:
d=tkr�	td=|||||||||	||t!|||&|$�|%d<tjj	j
�r�	y;td/d0|d1|%d2|d3| d4|!d5|"d6|#�}%Wn6t-k
r	}6|6j.j/d>�r|	||%dd?<nnXnnt|%dt0�r�	|%d\|%d<|%d<n|%dr
t|%d<d@j|�|%d<|%dcdA7<dB|%dko�	|r
dC|%ddB<nnt|%d<dDj|�|%d<|%SntdE||t!�\}}Wn4t-k
r�
}6t
|%d<dFj|6�|%d<|%SnXyDtdG||	|||||||t!||||$�
\}7}8}9WnFt1k
r}6i|%d<tj2t3j4��t|%dFj|6��SnXt}:|r�
tjjj5dH|dI|�}:tdJ|�r�ytdK||:�Wn/t1k
r�}6t|%dLj||:|6��SnXnywtdM|:|7|%||8||||t!||
|	||||||&dN|dO| dP|!dQ|"dR|#d|dS||$�}%Wn�t1k
r�}6i|%d<tj2t3j4��tjjj6|:�|r�|7o~|o~t7|�j8dTkr�tdU|t!�}7n|7r�tjjj6|7�nnt|%dVj|6��SnX|%drp
iid6dd6|d6td6}%i};dWt9kr
t9dW|;dW<nt:||:|;�}<t|<t)�rg
|%j;|<�tjjj6|:�|%Sn|:}7n"iid6dd6|d6td6}%n|9o�
|tkr�
t|%|9�Sn@z�yutdM||7|%||8||||t!||
|	||||||&dN|dO| dP|!dQ|"dR|#d|dS||$�SWnFt1k
rw}6i|%d<tj2t3j4��t|%dFj|6��SnXWdX|:r�tjjj6|:�n|r�|7o�|o�t7|�j8dTkr�tdU|t!�}7n|7r�tjjj6|7�nnXdXS(YuAT
    Manage a given file, this function allows for a file to be downloaded from
    the salt master and potentially run through a templating system.

    name
        The location of the file to manage, as an absolute path.

    source
        The source file to download to the minion, this source file can be
        hosted on either the salt master server (``salt://``), the salt minion
        local file system (``/``), or on an HTTP or FTP server (``http(s)://``,
        ``ftp://``).

        Both HTTPS and HTTP are supported as well as downloading directly
        from Amazon S3 compatible URLs with both pre-configured and automatic
        IAM credentials. (see s3.get state documentation)
        File retrieval from Openstack Swift object storage is supported via
        swift://container/object_path URLs, see swift.get documentation.
        For files hosted on the salt file server, if the file is located on
        the master in the directory named spam, and is called eggs, the source
        string is salt://spam/eggs. If source is left blank or None
        (use ~ in YAML), the file will be created as an empty file and
        the content will not be managed. This is also the case when a file
        already exists and the source is undefined; the contents of the file
        will not be changed or managed.

        If the file is hosted on a HTTP or FTP server then the source_hash
        argument is also required.

        A list of sources can also be passed in to provide a default source and
        a set of fallbacks. The first source in the list that is found to exist
        will be used and subsequent entries in the list will be ignored. Source
        list functionality only supports local files and remote files hosted on
        the salt master server or retrievable via HTTP, HTTPS, or FTP.

        .. code-block:: yaml

            file_override_example:
              file.managed:
                - source:
                  - salt://file_that_does_not_exist
                  - salt://file_that_exists

    source_hash
        This can be one of the following:
            1. a source hash string
            2. the URI of a file that contains source hash strings

        The function accepts the first encountered long unbroken alphanumeric
        string of correct length as a valid hash, in order from most secure to
        least secure:

        .. code-block:: text

            Type    Length
            ======  ======
            sha512     128
            sha384      96
            sha256      64
            sha224      56
            sha1        40
            md5         32

        **Using a Source Hash File**
            The file can contain several checksums for several files. Each line
            must contain both the file name and the hash.  If no file name is
            matched, the first hash encountered will be used, otherwise the most
            secure hash with the correct source file name will be used.

            When using a source hash file the source_hash argument needs to be a
            url, the standard download urls are supported, ftp, http, salt etc:

            Example:

            .. code-block:: yaml

                tomdroid-src-0.7.3.tar.gz:
                  file.managed:
                    - name: /tmp/tomdroid-src-0.7.3.tar.gz
                    - source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
                    - source_hash: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.hash

            The following lines are all supported formats:

            .. code-block:: text

                /etc/rc.conf ef6e82e4006dee563d98ada2a2a80a27
                sha254c8525aee419eb649f0233be91c151178b30f0dff8ebbdcc8de71b1d5c8bcc06a  /etc/resolv.conf
                ead48423703509d37c4a90e6a0d53e143b6fc268

            Debian file type ``*.dsc`` files are also supported.

        **Inserting the Source Hash in the SLS Data**

        The source_hash can be specified as a simple checksum, like so:

        .. code-block:: yaml

            tomdroid-src-0.7.3.tar.gz:
              file.managed:
                - name: /tmp/tomdroid-src-0.7.3.tar.gz
                - source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
                - source_hash: 79eef25f9b0b2c642c62b7f737d4f53f

        .. note::
            Releases prior to 2016.11.0 must also include the hash type, like
            in the below example:

            .. code-block:: yaml

                tomdroid-src-0.7.3.tar.gz:
                  file.managed:
                    - name: /tmp/tomdroid-src-0.7.3.tar.gz
                    - source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
                    - source_hash: md5=79eef25f9b0b2c642c62b7f737d4f53f

        Known issues:
            If the remote server URL has the hash file as an apparent
            sub-directory of the source file, the module will discover that it
            has already cached a directory where a file should be cached. For
            example:

            .. code-block:: yaml

                tomdroid-src-0.7.3.tar.gz:
                  file.managed:
                    - name: /tmp/tomdroid-src-0.7.3.tar.gz
                    - source: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz
                    - source_hash: https://launchpad.net/tomdroid/beta/0.7.3/+download/tomdroid-src-0.7.3.tar.gz/+md5

    source_hash_name
        When ``source_hash`` refers to a hash file, Salt will try to find the
        correct hash by matching the filename/URI associated with that hash. By
        default, Salt will look for the filename being managed. When managing a
        file at path ``/tmp/foo.txt``, then the following line in a hash file
        would match:

        .. code-block:: text

            acbd18db4cc2f85cedef654fccc4a4d8    foo.txt

        However, sometimes a hash file will include multiple similar paths:

        .. code-block:: text

            37b51d194a7513e45b56f6524f2d51f2    ./dir1/foo.txt
            acbd18db4cc2f85cedef654fccc4a4d8    ./dir2/foo.txt
            73feffa4b7f6bb68e44cf984c85f6e88    ./dir3/foo.txt

        In cases like this, Salt may match the incorrect hash. This argument
        can be used to tell Salt which filename to match, to ensure that the
        correct hash is identified. For example:

        .. code-block:: yaml

            /tmp/foo.txt:
              file.managed:
                - source: https://mydomain.tld/dir2/foo.txt
                - source_hash: https://mydomain.tld/hashes
                - source_hash_name: ./dir2/foo.txt

        .. note::
            This argument must contain the full filename entry from the
            checksum file, as this argument is meant to disambiguate matches
            for multiple files that have the same basename. So, in the
            example above, simply using ``foo.txt`` would not match.

        .. versionadded:: 2016.3.5

    keep_source : True
        Set to ``False`` to discard the cached copy of the source file once the
        state completes. This can be useful for larger files to keep them from
        taking up space in minion cache. However, keep in mind that discarding
        the source file will result in the state needing to re-download the
        source file if the state is run again.

        .. versionadded:: 2017.7.3

    user
        The user to own the file, this defaults to the user salt is running as
        on the minion

    group
        The group ownership set for the file, this defaults to the group salt
        is running as on the minion. On Windows, this is ignored

    mode
        The permissions to set on this file, e.g. ``644``, ``0775``, or
        ``4664``.

        The default mode for new files and directories corresponds to the
        umask of the salt process. The mode of existing files and directories
        will only be changed if ``mode`` is specified.

        .. note::
            This option is **not** supported on Windows.

        .. versionchanged:: 2016.11.0
            This option can be set to ``keep``, and Salt will keep the mode
            from the Salt fileserver. This is only supported when the
            ``source`` URL begins with ``salt://``, or for files local to the
            minion. Because the ``source`` option cannot be used with any of
            the ``contents`` options, setting the ``mode`` to ``keep`` is also
            incompatible with the ``contents`` options.

        .. note:: keep does not work with salt-ssh.

            As a consequence of how the files are transferred to the minion, and
            the inability to connect back to the master with salt-ssh, salt is
            unable to stat the file as it exists on the fileserver and thus
            cannot mirror the mode on the salt-ssh minion

    attrs
        The attributes to have on this file, e.g. ``a``, ``i``. The attributes
        can be any or a combination of the following characters:
        ``aAcCdDeijPsStTu``.

        .. note::
            This option is **not** supported on Windows.

        .. versionadded:: 2018.3.0

    template
        If this setting is applied, the named templating engine will be used to
        render the downloaded file. The following templates are supported:

        - :mod:`cheetah<salt.renderers.cheetah>`
        - :mod:`genshi<salt.renderers.genshi>`
        - :mod:`jinja<salt.renderers.jinja>`
        - :mod:`mako<salt.renderers.mako>`
        - :mod:`py<salt.renderers.py>`
        - :mod:`wempy<salt.renderers.wempy>`

    makedirs : False
        If set to ``True``, then the parent directories will be created to
        facilitate the creation of the named file. If ``False``, and the parent
        directory of the destination file doesn't exist, the state will fail.

    dir_mode
        If directories are to be created, passing this option specifies the
        permissions for those directories. If this is not set, directories
        will be assigned permissions by adding the execute bit to the mode of
        the files.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

    replace : True
        If set to ``False`` and the file already exists, the file will not be
        modified even if changes would otherwise be made. Permissions and
        ownership will still be enforced, however.

    context
        Overrides default context variables passed to the template.

    defaults
        Default context passed to the template.

    backup
        Overrides the default backup mode for this specific file. See
        :ref:`backup_mode documentation <file-state-backups>` for more details.

    show_changes
        Output a unified diff of the old file and the new file. If ``False``
        return a boolean if any changes were made.

    create : True
        If set to ``False``, then the file will only be managed if the file
        already exists on the system.

    contents
        Specify the contents of the file. Cannot be used in combination with
        ``source``. Ignores hashes and does not use a templating engine.

        This value can be either a single string, a multiline YAML string or a
        list of strings.  If a list of strings, then the strings will be joined
        together with newlines in the resulting file. For example, the below
        two example states would result in identical file contents:

        .. code-block:: yaml

            /path/to/file1:
              file.managed:
                - contents:
                  - This is line 1
                  - This is line 2

            /path/to/file2:
              file.managed:
                - contents: |
                    This is line 1
                    This is line 2


    contents_pillar
        .. versionadded:: 0.17.0
        .. versionchanged:: 2016.11.0
            contents_pillar can also be a list, and the pillars will be
            concatinated together to form one file.


        Operates like ``contents``, but draws from a value stored in pillar,
        using the pillar path syntax used in :mod:`pillar.get
        <salt.modules.pillar.get>`. This is useful when the pillar value
        contains newlines, as referencing a pillar variable using a jinja/mako
        template can result in YAML formatting issues due to the newlines
        causing indentation mismatches.

        For example, the following could be used to deploy an SSH private key:

        .. code-block:: yaml

            /home/deployer/.ssh/id_rsa:
              file.managed:
                - user: deployer
                - group: deployer
                - mode: 600
                - attrs: a
                - contents_pillar: userdata:deployer:id_rsa

        This would populate ``/home/deployer/.ssh/id_rsa`` with the contents of
        ``pillar['userdata']['deployer']['id_rsa']``. An example of this pillar
        setup would be like so:

        .. code-block:: yaml

            userdata:
              deployer:
                id_rsa: |
                    -----BEGIN RSA PRIVATE KEY-----
                    MIIEowIBAAKCAQEAoQiwO3JhBquPAalQF9qP1lLZNXVjYMIswrMe2HcWUVBgh+vY
                    U7sCwx/dH6+VvNwmCoqmNnP+8gTPKGl1vgAObJAnMT623dMXjVKwnEagZPRJIxDy
                    B/HaAre9euNiY3LvIzBTWRSeMfT+rWvIKVBpvwlgGrfgz70m0pqxu+UyFbAGLin+
                    GpxzZAMaFpZw4sSbIlRuissXZj/sHpQb8p9M5IeO4Z3rjkCP1cxI
                    -----END RSA PRIVATE KEY-----

        .. note::
            The private key above is shortened to keep the example brief, but
            shows how to do multiline string in YAML. The key is followed by a
            pipe character, and the mutliline string is indented two more
            spaces.

            To avoid the hassle of creating an indented multiline YAML string,
            the :mod:`file_tree external pillar <salt.pillar.file_tree>` can
            be used instead. However, this will not work for binary files in
            Salt releases before 2015.8.4.

    contents_grains
        .. versionadded:: 2014.7.0

        Operates like ``contents``, but draws from a value stored in grains,
        using the grains path syntax used in :mod:`grains.get
        <salt.modules.grains.get>`. This functionality works similarly to
        ``contents_pillar``, but with grains.

        For example, the following could be used to deploy a "message of the day"
        file:

        .. code-block:: yaml

            write_motd:
              file.managed:
                - name: /etc/motd
                - contents_grains: motd

        This would populate ``/etc/motd`` file with the contents of the ``motd``
        grain. The ``motd`` grain is not a default grain, and would need to be
        set prior to running the state:

        .. code-block:: bash

            salt '*' grains.set motd 'Welcome! This system is managed by Salt.'

    contents_newline : True
        .. versionadded:: 2014.7.0
        .. versionchanged:: 2015.8.4
            This option is now ignored if the contents being deployed contain
            binary data.

        If ``True``, files managed using ``contents``, ``contents_pillar``, or
        ``contents_grains`` will have a newline added to the end of the file if
        one is not present. Setting this option to ``False`` will omit this
        final newline.

    contents_delimiter
        .. versionadded:: 2015.8.4

        Can be used to specify an alternate delimiter for ``contents_pillar``
        or ``contents_grains``. This delimiter will be passed through to
        :py:func:`pillar.get <salt.modules.pillar.get>` or :py:func:`grains.get
        <salt.modules.grains.get>` when retrieving the contents.

    encoding
        If specified, then the specified encoding will be used. Otherwise, the
        file will be encoded using the system locale (usually UTF-8). See
        https://docs.python.org/3/library/codecs.html#standard-encodings for
        the list of available encodings.

        .. versionadded:: 2017.7.0

    encoding_errors : 'strict'
        Error encoding scheme. Default is ```'strict'```.
        See https://docs.python.org/2/library/codecs.html#codec-base-classes
        for the list of available schemes.

        .. versionadded:: 2017.7.0

    allow_empty : True
        .. versionadded:: 2015.8.4

        If set to ``False``, then the state will fail if the contents specified
        by ``contents_pillar`` or ``contents_grains`` are empty.

    follow_symlinks : True
        .. versionadded:: 2014.7.0

        If the desired path is a symlink follow it and make changes to the
        file to which the symlink points.

    check_cmd
        .. versionadded:: 2014.7.0

        The specified command will be run with an appended argument of a
        *temporary* file containing the new managed contents.  If the command
        exits with a zero status the new managed contents will be written to
        the managed destination. If the command exits with a nonzero exit
        code, the state will fail and no changes will be made to the file.

        For example, the following could be used to verify sudoers before making
        changes:

        .. code-block:: yaml

            /etc/sudoers:
              file.managed:
                - user: root
                - group: root
                - mode: 0440
                - attrs: i
                - source: salt://sudoers/files/sudoers.jinja
                - template: jinja
                - check_cmd: /usr/sbin/visudo -c -f

        **NOTE**: This ``check_cmd`` functions differently than the requisite
        ``check_cmd``.

    tmp_dir
        Directory for temp file created by ``check_cmd``. Useful for checkers
        dependent on config file location (e.g. daemons restricted to their
        own config directories by an apparmor profile).

        .. code-block:: yaml

            /etc/dhcp/dhcpd.conf:
              file.managed:
                - user: root
                - group: root
                - mode: 0755
                - tmp_dir: '/etc/dhcp'
                - contents: "# Managed by Salt"
                - check_cmd: dhcpd -t -cf

    tmp_ext
        Suffix for temp file created by ``check_cmd``. Useful for checkers
        dependent on config file extension (e.g. the init-checkconf upstart
        config checker).

        .. code-block:: yaml

            /etc/init/test.conf:
              file.managed:
                - user: root
                - group: root
                - mode: 0440
                - tmp_ext: '.conf'
                - contents:
                  - 'description "Salt Minion"'
                  - 'start on started mountall'
                  - 'stop on shutdown'
                  - 'respawn'
                  - 'exec salt-minion'
                - check_cmd: init-checkconf -f

    skip_verify : False
        If ``True``, hash verification of remote file sources (``http://``,
        ``https://``, ``ftp://``) will be skipped, and the ``source_hash``
        argument will be ignored.

        .. versionadded:: 2016.3.0

    win_owner : None
        The owner of the directory. If this is not passed, user will be used. If
        user is not passed, the account under which Salt is running will be
        used.

        .. versionadded:: 2017.7.0

    win_perms : None
        A dictionary containing permissions to grant and their propagation. For
        example: ``{'Administrators': {'perms': 'full_control'}}`` Can be a
        single basic perm or a list of advanced perms. ``perms`` must be
        specified. ``applies_to`` does not apply to file objects.

        .. versionadded:: 2017.7.0

    win_deny_perms : None
        A dictionary containing permissions to deny and their propagation. For
        example: ``{'Administrators': {'perms': 'full_control'}}`` Can be a
        single basic perm or a list of advanced perms. ``perms`` must be
        specified. ``applies_to`` does not apply to file objects.

        .. versionadded:: 2017.7.0

    win_inheritance : True
        True to inherit permissions from the parent directory, False not to
        inherit permission.

        .. versionadded:: 2017.7.0

    win_perms_reset : False
        If ``True`` the existing DACL will be cleared and replaced with the
        settings defined in this function. If ``False``, new entries will be
        appended to the existing DACL. Default is ``False``.

        .. versionadded:: 2018.3.0

    Here's an example using the above ``win_*`` parameters:

    .. code-block:: yaml

        create_config_file:
          file.managed:
            - name: C:\config\settings.cfg
            - source: salt://settings.cfg
            - win_owner: Administrators
            - win_perms:
                # Basic Permissions
                dev_ops:
                  perms: full_control
                # List of advanced permissions
                appuser:
                  perms:
                    - read_attributes
                    - read_ea
                    - create_folders
                    - read_permissions
                joe_snuffy:
                  perms: read
            - win_deny_perms:
                fred_snuffy:
                  perms: full_control
            - win_inheritance: False
    uenvuchangesuucommentunameuresultu!Destination file name is requiredu-The 'mode' option is not supported on Windowsu.The 'attrs' option is not supported on Windowsukeepiu_'source' cannot be used in combination with 'contents', 'contents_pillar', or 'contents_grains'uhMode preservation cannot be used in combination with 'contents', 'contents_pillar', or 'contents_grains'iuMOnly one of 'contents', 'contents_pillar', and 'contents_grains' is permittedu
State for file: {0} - Neither 'source' nor 'contents' nor 'contents_pillar' nor 'contents_grains' was defined, yet 'replace' was set to 'True'. As there is no source to replace the file with, 'replace' has been set to 'False' to avoid reading the file unnecessarily.u	file_modeuwarningsu]The 'file_mode' argument will be ignored.  Please use 'mode' instead to set file permissions.u
pillar.gett	delimiteruPillar {0} does not existu
grains.getuGrain {0} does not existucontents_pillar {0}ucontents_grains {0}u
'contents'uh{0} value would result in empty contents. Set allow_empty to True to allow the managed file to be empty.R	u�Contents specified by contents/contents_pillar/contents_grains is not a string or list of strings, and is not binary data. SLS is likely malformed.u
u
u�Contents specified by contents/contents_pillar/contents_grains appears to be binary data, and as will not be able to be treated as a Jinja template.ufile.apply_template_on_contentsR�R�RR[u)Error while applying template on contentsR+u�The group argument for {0} has been ignored as this is a Windows system. Please use the `win_*` parameters to set permissions in Windows.u3File {0} is not present and is not set for creationu*Specified file {0} is not an absolute pathu#Specified target {0} is a directoryu Context must be formed as a dictu!Defaults must be formed as a dictufile.check_permsRRR�R�R�R'tresetutestulmodeuKFile {0} will be updated with permissions {1} from its current state of {2}uFile {0} not updatedu9File {0} exists with proper permissions. No changes made.uaccumulatorufile.check_managed_changesuPath not foundunewfileu!The file {0} is set to be changeduL
Note: No changes made, actual changes may
be different due to other states.udiffu<show_changes=False>u$The file {0} is in the correct stateufile.source_listuUnable to manage file: {0}ufile.get_managedtsuffixtdirufile.file_existsu	file.copyu#Unable to copy file {0} to {1}: {2}ufile.manage_fileR�R�R�R�R�tencoding_errorsusaltucp.is_cacheduUnable to check_cmd file: {0}ushellN(<tpopRRR*R8R�R5RRR�R�RtAttributeErrorR4RR�R�RHR�R*t
setdefaultR�R�RFR)t__NOT_FOUNDtlinesepRR
RtrstripR`tUnicodeDecodeErrorR_RR�R�RR0R�R{tdictR�RR#RtstrerrorRGttupleR.RIt	tracebackt
format_exctmkstempRJt	_urlparsetschemet
__grains__tmod_run_check_cmdRL(=RAReR�tsource_hash_nametkeep_sourceR+R,R�tattrsR�R0R�R�R>Rtbackuptshow_changesRdtcontentsttmp_dirttmp_exttcontents_pillartcontents_grainstcontents_newlinetcontents_delimiterR	RYtallow_emptyR�t	check_cmdtskip_verifyR�R�R�R�R�RhRt	keep_modetxtcontents_countt
list_contentstnextptnextctuse_contentstnextgtcontents_idtvalidated_contentstparttlinetu_checkt	ret_permst
accum_dataR�R�tsfnt
source_sumtcomment_ttmp_filenametcheck_cmd_optstcret((s4/usr/lib/python2.7/site-packages/salt/states/file.pytmanagedhs���P










		
			


+


	



	


	


!
	














	


uuserugroupumodeuignore_filesuignore_dirscC@s�|s
t�St|t�s+td��nyt|�}Wntk
rTd}nX|dksttt�|kr�tdjdjd�tD�����nd|kr�d|kr�td��n|S(	u�
    Converse *recurse* definition to a set of strings.

    Raises TypeError or ValueError when *recurse* has wrong structure.
    u-"recurse" must be formed as a list of stringsu#Types for "recurse" limited to {0}.u, cs@s|]}dj|�VqdS(u"{0}"N(R*(t.0trtype((s4/usr/lib/python2.7/site-packages/salt/states/file.pys	<genexpr>�suignore_filesuignore_dirsuUMust not specify "recurse" options "ignore_files" and "ignore_dirs" at the same time.N(	R\R�RFR�R5t_RECURSE_TYPESR�R*R(R�R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��s

	"cc@s�x�tjjj|�D]|\}}}|dk	ro|jtjj�|jtjj�}||kro|2qontj	|�t
|�t
|�fVqWdS(u
    Walk the directory tree under root up till reaching max_depth.
    With max_depth=None (default), do not limit depth.
    N(RRRR�R5R7RR2RR�RF(R<R�R�R~Rt	rel_depth((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��s%(
c1K@s�tjj|�}i|d6id6td6dd6}|sGt|d�S|ddkrp|dkrp|d }n|dJk	r�|r�t|d	�St|d
|�}tjj	j
�r|dJkr�|r�|ntjjj�}n|dJk	rt
jdj|��n|}nd|kr6|r6|jdg�}n|sE|}ntjjj|�}tjjj|�}tjj	j
�r�ytjjj|�Wq�tk
r�}t||�SXn"t||�}|r�t||�Stjj|�st|d
j|��Stjj|�sH|r0tjj|�sH|r�tjj|�r�|
dJk	r�tjj|
�r�|s�t|dj|
��Std|
�ntj||
�q�|r{tjj|�r�tdr�d|dd<qxtj|�d|dd<q�td|�rAtdr"d|dd<qxtd|�d|dd<q�tdr\d|dd<q�td|�d|dd<q�tjj|�r�t|dj|��Stjj|�r�t|dj|��Sntjj	j
�rtd|d|d|d|d|d |�\}}}n9t ||||p.g||||	|
||�\}}}|rl|dj!|�ntds�|dr�||d<||d<|Stjj"|�s�tjj"tjj#|��sR|r9y;t$d|d
|d!|d"|d|d|d|d|�WqOtk
r5}t|d#j|j%��SXqRt|d$j|��Sntjj	j
�r�td%d&|d'|d(|d)|d*|d+|�n td%|d
|d!|d,|�d-|d|<ntjj"|�s�t|d.j|��S|sltjj	j
�rAtd/d&|d0|d'|d(|d)|d*|d+|�}qltd/|||||dJ|�\}}ng}|s~|r�t&t'||��}i}x-|D]"} | d1| d2f|| d3<q�WndJ}!|r!yt(|�}!Wq!t)t*fk
r}t+|d<d4j|�|d<q!Xn|!rA
d5|!kr�|sHt,|t-�r�td6|�}"t,|"t.j/�r�t+|d<d7j|�|d<q�q�t+|d<d8|d<ndJ}d9|!kr'|s�t,|t-�rtd:|�}#t,|#t.j/�r$t+|d<d;j|�|d<q$q-t+|d<d<|d<ndJ}d|!krHdJ}dJ}nd=|!k}$d>|!k}%x�|D]�\}&}'}(|$rX	x�|(D]�})tjj0|&|)�}*yxtjj	j
�r�td/d&|*d0|d'|d(|d)|d*|d+|�}n(td/|*||||dJ|�\}}+Wq�tk
rP	}|j1j2d?�sQ	|j3|j1�qQ	q�Xq�Wn|%rgx�|'D]�},tjj0|&|,�}*yxtjj	j
�r�	td/d&|*d0|d'|d(|d)|d*|d+|�}n(td/|*||||dJ|�\}}+Wqe	tk
r2
}|j1j2d?�s3
|j3|j1�q3
qe	Xqe	WqgqgWn|r�
t4||	|�}-t
j5d@|-�t6|t&|-�|
�}.|.r�
|.|ddA<dBj|�|d<q�
n|ds�
|r�
dCj|�|d<q�
|dr�
dDj|�|d<q�
ntdrdEj|�|d<nn|dr�|dr�dJ}/|drI|d}/ndFj|�|d<|/r�dGj0|d|/g�|d<q�n|r�t+|d<|dcdH7<x*|D]}0|dcdIj|0�7<q�Wn|S(Ku/
    Ensure that a named directory is present and has the right perms

    name
        The location to create or manage a directory, as an absolute path

    user
        The user to own the directory; this defaults to the user salt is
        running as on the minion

    group
        The group ownership set for the directory; this defaults to the group
        salt is running as on the minion. On Windows, this is ignored

    recurse
        Enforce user/group ownership and mode of directory recursively. Accepts
        a list of strings representing what you would like to recurse.  If
        ``mode`` is defined, will recurse on both ``file_mode`` and ``dir_mode`` if
        they are defined.  If ``ignore_files`` or ``ignore_dirs`` is included, files or
        directories will be left unchanged respectively.
        Example:

        .. code-block:: yaml

            /var/log/httpd:
              file.directory:
                - user: root
                - group: root
                - dir_mode: 755
                - file_mode: 644
                - recurse:
                  - user
                  - group
                  - mode

        Leave files or directories unchanged:

        .. code-block:: yaml

            /var/log/httpd:
              file.directory:
                - user: root
                - group: root
                - dir_mode: 755
                - file_mode: 644
                - recurse:
                  - user
                  - group
                  - mode
                  - ignore_dirs

        .. versionadded:: 2015.5.0

    max_depth
        Limit the recursion depth. The default is no limit=None.
        'max_depth' and 'clean' are mutually exclusive.

        .. versionadded:: 2016.11.0

    dir_mode / mode
        The permissions mode to set any directories created. Not supported on
        Windows.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

    file_mode
        The permissions mode to set any files created if 'mode' is run in
        'recurse'. This defaults to dir_mode. Not supported on Windows.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

    makedirs
        If the directory is located in a path without a parent directory, then
        the state will fail. If makedirs is set to True, then the parent
        directories will be created to facilitate the creation of the named
        file.

    clean
        Make sure that only files that are set up by salt and required by this
        function are kept. If this option is set then everything in this
        directory will be deleted unless it is required.
        'clean' and 'max_depth' are mutually exclusive.

    require
        Require other resources such as packages or files

    exclude_pat
        When 'clean' is set to True, exclude this pattern from removal list
        and preserve in the destination.

    follow_symlinks : False
        If the desired path is a symlink (or ``recurse`` is defined and a
        symlink is encountered while recursing), follow it and check the
        permissions of the directory/file to which the symlink points.

        .. versionadded:: 2014.1.4

    force
        If the name of the directory exists and is not a directory and
        force is set to False, the state will fail. If force is set to
        True, the file in the way of the directory will be deleted to
        make room for the directory, unless backupname is set,
        then it will be renamed.

        .. versionadded:: 2014.7.0

    backupname
        If the name of the directory exists and is not a directory, it will be
        renamed to the backupname. If the backupname already
        exists and force is False, the state will fail. Otherwise, the
        backupname will be removed first.

        .. versionadded:: 2014.7.0

    allow_symlink : True
        If allow_symlink is True and the specified path is a symlink, it will be
        allowed to remain if it points to a directory. If allow_symlink is False
        then the state will fail, unless force is also set to True, in which case
        it will be removed or renamed, depending on the value of the backupname
        argument.

        .. versionadded:: 2014.7.0

    children_only : False
        If children_only is True the base of a path is excluded when performing
        a recursive operation. In case of /path/to/base, base will be ignored
        while all of /path/to/base/* are still operated on.

    win_owner : None
        The owner of the directory. If this is not passed, user will be used. If
        user is not passed, the account under which Salt is running will be
        used.

        .. versionadded:: 2017.7.0

    win_perms : None
        A dictionary containing permissions to grant and their propagation. For
        example: ``{'Administrators': {'perms': 'full_control', 'applies_to':
        'this_folder_only'}}`` Can be a single basic perm or a list of advanced
        perms. ``perms`` must be specified. ``applies_to`` is optional and
        defaults to ``this_folder_subfoler_files``.

        .. versionadded:: 2017.7.0

    win_deny_perms : None
        A dictionary containing permissions to deny and their propagation. For
        example: ``{'Administrators': {'perms': 'full_control', 'applies_to':
        'this_folder_only'}}`` Can be a single basic perm or a list of advanced
        perms.

        .. versionadded:: 2017.7.0

    win_inheritance : True
        True to inherit permissions from the parent directory, False not to
        inherit permission.

        .. versionadded:: 2017.7.0

    win_perms_reset : False
        If ``True`` the existing DACL will be cleared and replaced with the
        settings defined in this function. If ``False``, new entries will be
        appended to the existing DACL. Default is ``False``.

        .. versionadded:: 2018.3.0

    Here's an example using the above ``win_*`` parameters:

    .. code-block:: yaml

        create_config_dir:
          file.directory:
            - name: 'C:\config\'
            - win_owner: Administrators
            - win_perms:
                # Basic Permissions
                dev_ops:
                  perms: full_control
                # List of advanced permissions
                appuser:
                  perms:
                    - read_attributes
                    - read_ea
                    - create_folders
                    - read_permissions
                  applies_to: this_folder_only
                joe_snuffy:
                  perms: read
                  applies_to: this_folder_files
            - win_deny_perms:
                fred_snuffy:
                  perms: full_control
            - win_inheritance: False
    unameuchangesuresultuucommentu#Must provide name to file.directoryi����u/u'Cannot specify both max_depth and cleanR+u�The group argument for {0} has been ignored as this is a Windows system. Please use the `win_*` parameters to set permissions in Windows.umodeu*Specified file {0} is not an absolute pathu1File exists where the backup target {0} should goufile.removeutestuFile would be forcibly replaceduforceduFile was forcibly replacedufile.is_linku"Symlink would be forcibly replaceduSymlink was forcibly replacedu$Directory would be forcibly replaceduDirectory was forcibly replacedu+Specified location {0} exists and is a fileu.Specified location {0} exists and is a symlinkRAR�R�R�R�R�R,R�uDrive {0} is not mappeduNo directory to create {0} inu
file.mkdirRR�R�R�R'RVR�uNew DiruFailed to create directory {0}ufile.check_permsRiiiu{0}uuserufile.user_to_uidu>Failed to enforce ownership for user {0} (user does not exist)uQuser not specified, but configured as a target for recursive ownership managementugroupufile.group_to_gidu/Failed to enforce group ownership for group {0}uRgroup not specified, but configured as a target for recursive ownership managementuignore_filesuignore_dirsuPath not foundu9List of kept files when use file.directory with clean: %suremovedu Files cleaned from directory {0}uDirectory {0}/* updateduDirectory {0} updateduDirectory {0} not updatedu%Directory {0} is in the correct stateu
u)

The following errors were encountered:
u
- {0}N(7RRR*R8R�R5R�RRR�R�R�tget_current_userRHR�R*R|RR�R�tget_sidRR0R�RRtR-R)trenameRRJR�R�RLR{RcR(R+RFR�R�R�R�R4R�tintRR�RRbRGR�R�RIR�(1RAR+R,R�R�R�R�R0R�R�RTR�R�R/t
allow_symlinkt
children_onlyR�R�R�R�R�RhRR�R�R3R4R5R�terrorsR�R�R�R�R.R/R�R�R�R~RRmtfullR�tdir_RVR�torig_commentterror((s4/usr/lib/python2.7/site-packages/salt/states/file.pyRx�s��




!
		
+








 
$
#






	

%

%%	




#

 c1@s?d�
kr�
jd�ntjjtjjj����t�
d���tjj	j
�r��d-k	r�tj
dj���n��ni�d6id6td6id6�
d�
kr�t�
d<d	�
d<�
Stg��|	fD]}|d-k	^q��r"tjj	j
�r"t�
d
�Stjjj���y%�j�dk��r[d-�nWntk
rut�nXtjjj���t���}|r�t�
|�Stjj��s�t�
dj���St|�}x-t|�D]\}}|jd
�||<q�Wx3|D]+}|jd�st�
dj|��SqWy td|dt�\}} Wn1tk
r�}!t�
d<dj|!��
d<�
SXtjj j!|�\�}"|"d-kr�t}"ntdd|"�}#�|#kr+t�fd�|#D��r+t�
d<dj�|"��
d<�
Stjj"��s�tjj#��ret�
dj���St$ds�tjj	j
�r�|r�|n�}tdd�d|d|d|d|�q�tdd�d�d �d!��q�n�
fd"����
fd#����������	�
����f
d$�}$������fd%�}%t%�||||||�\}&}'}(})xx|(D]p\}*}+t&tjj'�|*�|+d&td'|d�d �d!|	�},|,s�q�n�tjj'�|*�|,�q�Wx|'D]}-|%|-�qWx$|&D]\}.}/|$|.|/|�q!W�r�|)j(t)�|��t*�t+|)�|�}0|0r�t$dr��
dr�d-�
d<n�d(|0�q�|0�
dd(<q�nd)j'd*�t,j-�
d�D��j.��
d<�
dsd+j���
d<n�
dr;�
dr;d,j���
d<n�
S(.u�
    Recurse through a subdirectory on the master and copy said subdirectory
    over to the specified path.

    name
        The directory to set the recursion in

    source
        The source directory, this directory is located on the salt master file
        server and is specified with the salt:// protocol. If the directory is
        located on the master in the directory named spam, and is called eggs,
        the source string is salt://spam/eggs

    keep_source : True
        Set to ``False`` to discard the cached copy of the source file once the
        state completes. This can be useful for larger files to keep them from
        taking up space in minion cache. However, keep in mind that discarding
        the source file will result in the state needing to re-download the
        source file if the state is run again.

        .. versionadded:: 2017.7.3

    clean
        Make sure that only files that are set up by salt and required by this
        function are kept. If this option is set then everything in this
        directory will be deleted unless it is required.

    require
        Require other resources such as packages or files

    user
        The user to own the directory. This defaults to the user salt is
        running as on the minion

    group
        The group ownership set for the directory. This defaults to the group
        salt is running as on the minion. On Windows, this is ignored

    dir_mode
        The permissions mode to set on any directories created.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

        .. note::
            This option is **not** supported on Windows.

    file_mode
        The permissions mode to set on any files created.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

        .. note::
            This option is **not** supported on Windows.

        .. versionchanged:: 2016.11.0
            This option can be set to ``keep``, and Salt will keep the mode
            from the Salt fileserver. This is only supported when the
            ``source`` URL begins with ``salt://``, or for files local to the
            minion. Because the ``source`` option cannot be used with any of
            the ``contents`` options, setting the ``mode`` to ``keep`` is also
            incompatible with the ``contents`` options.

    sym_mode
        The permissions mode to set on any symlink created.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

        .. note::
            This option is **not** supported on Windows.

    template
        If this setting is applied, the named templating engine will be used to
        render the downloaded file. The following templates are supported:

        - :mod:`cheetah<salt.renderers.cheetah>`
        - :mod:`genshi<salt.renderers.genshi>`
        - :mod:`jinja<salt.renderers.jinja>`
        - :mod:`mako<salt.renderers.mako>`
        - :mod:`py<salt.renderers.py>`
        - :mod:`wempy<salt.renderers.wempy>`

        .. note::

            The template option is required when recursively applying templates.

    replace : True
        If set to ``False`` and the file already exists, the file will not be
        modified even if changes would otherwise be made. Permissions and
        ownership will still be enforced, however.

    context
        Overrides default context variables passed to the template.

    defaults
        Default context passed to the template.

    include_empty
        Set this to True if empty directories should also be created
        (default is False)

    backup
        Overrides the default backup mode for all replaced files. See
        :ref:`backup_mode documentation <file-state-backups>` for more details.

    include_pat
        When copying, include only this pattern from the source. Default
        is glob match; if prefixed with 'E@', then regexp match.
        Example:

        .. code-block:: text

          - include_pat: hello*       :: glob matches 'hello01', 'hello02'
                                         ... but not 'otherhello'
          - include_pat: E@hello      :: regexp matches 'otherhello',
                                         'hello01' ...

    exclude_pat
        Exclude this pattern from the source when copying. If both
        `include_pat` and `exclude_pat` are supplied, then it will apply
        conditions cumulatively. i.e. first select based on include_pat, and
        then within that result apply exclude_pat.

        Also, when 'clean=True', exclude this pattern from the removal
        list and preserve in the destination.
        Example:

        .. code-block:: text

          - exclude_pat: APPDATA*               :: glob matches APPDATA.01,
                                                   APPDATA.02,.. for exclusion
          - exclude_pat: E@(APPDATA)|(TEMPDATA) :: regexp matches APPDATA
                                                   or TEMPDATA for exclusion

    maxdepth
        When copying, only copy paths which are of depth `maxdepth` from the
        source path.
        Example:

        .. code-block:: text

          - maxdepth: 0      :: Only include files located in the source
                                directory
          - maxdepth: 1      :: Only include files located in the source
                                or immediate subdirectories

    keep_symlinks
        Keep symlinks when copying from the source. This option will cause
        the copy operation to terminate at the symlink. If desire behavior
        similar to rsync, then set this to True.

    force_symlinks
        Force symlink creation. This option will force the symlink creation.
        If a file or directory is obstructing symlink creation it will be
        recursively removed so that symlink creation can proceed. This
        option is usually not needed except in special circumstances.

    win_owner : None
        The owner of the symlink and directories if ``makedirs`` is True. If
        this is not passed, ``user`` will be used. If ``user`` is not passed,
        the account under which Salt is running will be used.

        .. versionadded:: 2017.7.7

    win_perms : None
        A dictionary containing permissions to grant

        .. versionadded:: 2017.7.7

    win_deny_perms : None
        A dictionary containing permissions to deny

        .. versionadded:: 2017.7.7

    win_inheritance : None
        True to inherit permissions from parent, otherwise False

        .. versionadded:: 2017.7.7
    uenvR+uHThe group argument for {0} has been ignored as this is a Windows system.unameuchangesuresultucommentumodeuO'mode' is not allowed in 'file.recurse'. Please use 'file_mode' and 'dir_mode'.u+mode management is not supported on Windowsukeepu*Specified file {0} is not an absolute pathu/usalt://u,Invalid source '{0}' (must be a salt:// URI)ufile.source_listuuRecurse failed: {0}ucp.list_master_dirsR[c3@s(|]}|j�d�r|VqdS(u/N(RG(R�R{(RX(s4/usr/lib/python2.7/site-packages/salt/states/file.pys	<genexpr>�suJThe directory '{0}' does not exist on the salt fileserver in saltenv '{1}'u*The path {0} exists and is not a directoryutestufile.makedirs_permsRR�R�R�R'RAR,R�c@sI�dj|g�}t|tj�r8|j|�n
|j|�dS(Nucomment(R\R�RR�R�textend(RtcommentR�(R(s4/usr/lib/python2.7/site-packages/salt/states/file.pytadd_commentsc@s�|dtks �dtkr1|d�d<n|dtk	r_|dr_�||d�n|dr~|d�d|<ndS(Nuresultucommentuchanges(R4R8(RR}(R�R(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	merge_rets 
c@sm�r�tjj|�r�tjj|�r�|r�i�
d6id6td6dd6}tdr�dj|�|d<d|d<�	||�dStd|�id	d
6|d<�	||�ni}ddg}x+�D]#}||kr��|||<q�q�Wt	|d
|d�d�d�d�r&dn�ddd�dtd|d�d�d�|�}�	||�dS(Nunameuchangesuresultuucommentutestu#Replacing directory {0} with a fileufile.removeu"Replaced directory with a new fileudiffumodeumakedirsReRlR+R,R�ukeepRmR�R0R>R�RRn(
RRR�R{R8RR*R5R)R�(RReR>R}tpass_kwargstfaultsR�(
RnR�R�RR�R,RzRlRhR�RAR�R+(s4/usr/lib/python2.7/site-packages/salt/states/file.pytmanage_file+s@0"




	c@stjj|�dkrdS�r�tjj|�r�tjj|�r�i�d6id6td6dd6}tdr�dj|�|d<d|d<�||�dSt	d	|�id
d6|d<�||�nt
|d�d
�dgd�dddtdtdd�}�||�dS(Nu..unameuchangesuresultuucommentutestuReplacing {0} with a directoryufile.removeuReplaced file with a directoryudiffR+R,R�R�R�R0R�R�(RRR,R�R{R8RR*R5R)RxR4(RR}(R�R�R,R�RAR+(s4/usr/lib/python2.7/site-packages/salt/states/file.pytmanage_directoryRs.+"


	R0R�uremovedu
cs@sH|]>\}}dj|t|tj�r0|ndj|��VqdS(u
#### {0} ####
{1}u
N(R*R�RR�R(R�tktv((s4/usr/lib/python2.7/site-packages/salt/states/file.pys	<genexpr>�suRecursively updated {0}u)The directory {0} is in the correct stateN(/RZRRR*RRRaRbR�R�R�R5RHR�R*R8R4tanyR�RR�RR[R0R�R
t	enumerateR_RGR)R_RR]R^R{R�RRvR6RRLR�R�RFRRCR6(1RAReRlR�R�R+R,R�R�tsym_modeR�R�R>RRgRnRURTR:Rftforce_symlinksR�R�R�R�RhR{R�RtidxR�tprecheckR�R�Rktmaster_dirsR�R�t	mng_filestmng_dirstmng_symlinksRVRQRPR}RcRoRpR�((R�RnR�R�RR�R�R,RzRlRhR�RARRXR�R+s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��
s��!
	


.





 
	



3'	 



$
c@sxtjj���i�d6igd6gd6gd6d6td6dd6}�s\t|d	�Stjj��s{t|d
�Std��}tdd
d
����fd�}��fd�}�r�|n|}�fd����}	��}
t�}t�}x�|D]�}
||
�\}}|r�|
|	|j	|j
|j|j|<|j
�d
}|
|
|j	||j�|<|j|
�q
|j|
�q
Wid
d6dd6dd6dd6dd6}�fd����fd��t�}x�|j�D]v\}}d|kr"tjn	t|�}d|kr]d}|�|
||d
�O}q|�|	|||�O}qWt||�}|jdt�itt|�dt�d6|d6tt|�dt�d6}||d<tdr d jt|���|d<|rtd#|d<qtnTx+|D]#}
td!tjj�|
��q'Wd"jt|���|d<||d<|S($u	
    Apply retention scheduling to backup storage directory.

    .. versionadded:: 2016.11.0

    :param name:
        The filesystem path to the directory containing backups to be managed.

    :param retain:
        Delete the backups, except for the ones we want to keep.
        The N below should be an integer but may also be the special value of ``all``,
        which keeps all files matching the criteria.
        All of the retain options default to None,
        which means to not keep files based on this criteria.

        :most_recent N:
            Keep the most recent N files.

        :first_of_hour N:
            For the last N hours from now, keep the first file after the hour.

        :first_of_day N:
            For the last N days from now, keep the first file after midnight.
            See also ``timezone``.

        :first_of_week N:
            For the last N weeks from now, keep the first file after Sunday midnight.

        :first_of_month N:
            For the last N months from now, keep the first file after the start of the month.

        :first_of_year N:
            For the last N years from now, keep the first file after the start of the year.

    :param strptime_format:
        A python strptime format string used to first match the filenames of backups
        and then parse the filename to determine the datetime of the file.
        https://docs.python.org/2/library/datetime.html#datetime.datetime.strptime
        Defaults to None, which considers all files in the directory to be backups eligible for deletion
        and uses ``os.path.getmtime()`` to determine the datetime.

    :param timezone:
        The timezone to use when determining midnight.
        This is only used when datetime is pulled from ``os.path.getmtime()``.
        Defaults to ``None`` which uses the timezone from the locale.

    Usage example:

    .. code-block:: yaml

        /var/backups/example_directory:
          file.retention_schedule:
            - retain:
                most_recent: 5
                first_of_hour: 4
                first_of_day: 7
                first_of_week: 6    # NotImplemented yet.
                first_of_month: 6
                first_of_year: all
            - strptime_format: example_name_%Y%m%dT%H%M%S.tar.bz2
            - timezone: None

    unameuretainedudeleteduignoreduchangesuresultuucommentu,Must provide name to file.retention_scheduleu3Name provided to file.retention must be a directoryufile.readdiri�ic@sRy9tj|��}tjjj|��}||fSWntk
rMdSXdS(N(NN(RtstrptimeRRt	dateutilst
total_secondsR�R5(R ttstts_epoch(tbeginning_of_unix_timetstrptime_format(s4/usr/lib/python2.7/site-packages/salt/states/file.pytget_file_time_from_strptime�s
c@si|dks|dkrdStdtjj�|��}|ra|d}tj|��|fSdSdS(Nu.u..u
file.lstatust_mtime(NN(NN(R5R)RRRRRC(R RDR�(RAttimezone(s4/usr/lib/python2.7/site-packages/salt/states/file.pytget_file_time_from_mtime�s
c@s
t��S(N(R((t
dict_maker(s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�
su
first_of_yeariufirst_of_monthiufirst_of_dayiu
first_of_houriumost_recentc@sDt|t�r3t|j��d}�||�St|g�SdS(Ni(R�RatsortedtkeysR\(tfwtt
first_sub_key(t	get_first(s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�&sc@s�|dkr�|�St�}x^t|j�dt�D]D}|t|�}|dkr^Pn|�|||d|�O}q8W|SdS(Nitreversei(R\R�R�R8R�(R�tdepthtnt
result_setR�tneeded(R�tget_first_n_at_depth(s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�-s
	"uallu
first_of_weekR�utestu.{0} backups would have been removed from {1}.
ufile.removeu#{0} backups were removed from {1}.
N(RRR*R8R�R{R)RR\tyeartmonthtdaythourtisocalendartweekdayRKtitemstsystmaxsizeR�RFtsortR�RR*R�R5R(RAtretainR�R�Rt	all_filesR�R�t
get_file_timetfiles_by_ymdtfiles_by_y_week_dowtrelevant_filest
ignored_filesR R�R�tweek_of_yeartRETAIN_TO_DEPTHtretained_filestretention_rulet
keep_counttfirst_of_week_depthtdeletable_filesR�((R�R�R�R�RAR�R�s4/usr/lib/python2.7/site-packages/salt/states/file.pytretention_schedule�s|@



	
				
&

	!		


!
cC@s�tjj|�}i|d6id6td6dd6}|sGt|d�St|d|d|d	|
d
|dt�t|�\}}|s�t||�S|r�|j�p�|}|dkr�t|d�Sd
g}||kr�|dkr�t|dj
|��S~td||d|d
|d|d|d|d|d|d|	d|
�	}|r�||dd<tdr}d|d<d|d<q�t|d<d|d<nt|d<d|d<|S(u
    Line-based editing of a file.

    .. versionadded:: 2015.8.0

    :param name:
        Filesystem path to the file to be edited.

    :param content:
        Content of the line. Allowed to be empty if mode=delete.

    :param match:
        Match the target line for an action by
        a fragment of a string or regular expression.

        If neither ``before`` nor ``after`` are provided, and ``match``
        is also ``None``, match becomes the ``content`` value.

    :param mode:
        Defines how to edit a line. One of the following options is
        required:

        - ensure
            If line does not exist, it will be added.
        - replace
            If line already exists, it will be replaced.
        - delete
            Delete the line, once found.
        - insert
            Insert a line.

        .. note::

            If ``mode=insert`` is used, at least one of the following
            options must also be defined: ``location``, ``before``, or
            ``after``. If ``location`` is used, it takes precedence
            over the other two options.

    :param location:
        Defines where to place content in the line. Note this option is only
        used when ``mode=insert`` is specified. If a location is passed in, it
        takes precedence over both the ``before`` and ``after`` kwargs. Valid
        locations are:

        - start
            Place the content at the beginning of the file.
        - end
            Place the content at the end of the file.

    :param before:
        Regular expression or an exact case-sensitive fragment of the string.
        This option is only used when either the ``ensure`` or ``insert`` mode
        is defined.

    :param after:
        Regular expression or an exact case-sensitive fragment of the string.
        This option is only used when either the ``ensure`` or ``insert`` mode
        is defined.

    :param show_changes:
        Output a unified diff of the old file and the new file.
        If ``False`` return a boolean if any changes were made.
        Default is ``True``

        .. note::
            Using this option will store two copies of the file in-memory
            (the original version and the edited version) in order to generate the diff.

    :param backup:
        Create a backup of the original file with the extension:
        "Year-Month-Day-Hour-Minutes-Seconds".

    :param quiet:
        Do not raise any exceptions. E.g. ignore the fact that the file that is
        tried to be edited does not exist and nothing really happened.

    :param indent:
        Keep indentation with the previous line. This option is not considered when
        the ``delete`` mode is specified.

    :param create:
        Create an empty file if doesn't exists.

        .. versionadded:: 2016.11.0

    :param user:
        The user to own the file, this defaults to the user salt is running as
        on the minion.

        .. versionadded:: 2016.11.0

    :param group:
        The group ownership set for the file, this defaults to the group salt
        is running as on the minion On Windows, this is ignored.

        .. versionadded:: 2016.11.0

    :param file_mode:
        The permissions to set on this file, aka 644, 0775, 4664. Not supported
        on Windows.

        .. versionadded:: 2016.11.0

    If an equal sign (``=``) appears in an argument to a Salt command, it is
    interpreted as a keyword argument in the format of ``key=val``. That
    processing can be bypassed in order to pass an equal sign through to the
    remote shell command by manually specifying the kwarg:

    .. code-block:: yaml

       update_config:
         file.line:
           - name: /etc/myconfig.conf
           - mode: ensure
           - content: my key = my value
           - before: somekey.*?

    unameuchangesuresultuucommentuMust provide name to file.lineRdR+R,R�R>u.Mode was not defined. How to process the file?udeleteu(Content can only be empty if mode is {0}u	file.lineR8tlocationtbeforetafterRoRntquiettindentudiffutestuChanges would be madeuChanges were madeuNo changes needed to be madeN(
RRR*R8R�R�R4R�RR5R*R)R(RAtcontentR8R�R�R�R�RoRnR�R�RdR+R,R�Rt	check_rest	check_msgtmodeswithemptycontentR�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�csLz




	






iiu.bakc
C@sOtjj|�}i|d6id6td6dd6}
|sGt|
d�St|�\}}|s�|rd|krd|
d<|
St|
|�Sntd	|||d
|d|d|d
|d|d|d|	dtdd|
d|d|�}|r7||
dd<tdr d|
d<d|
d<qKt|
d<d|
d<nt|
d<d|
d<|
S(ua
    Maintain an edit in a file.

    .. versionadded:: 0.17.0

    name
        Filesystem path to the file to be edited. If a symlink is specified, it
        will be resolved to its target.

    pattern
        A regular expression, to be matched using Python's
        :py:func:`re.search`.

        .. note::

            If you need to match a literal string that contains regex special
            characters, you may want to use salt's custom Jinja filter,
            ``regex_escape``.

            .. code-block:: jinja

                {{ 'http://example.com?foo=bar%20baz' | regex_escape }}

    repl
        The replacement text

    count
        Maximum number of pattern occurrences to be replaced.  Defaults to 0.
        If count is a positive integer n, no more than n occurrences will be
        replaced, otherwise all occurrences will be replaced.

    flags
        A list of flags defined in the ``re`` module documentation from the
        Python standard library. Each list item should be a string that will
        correlate to the human-friendly flag name. E.g., ``['IGNORECASE',
        'MULTILINE']``.  Optionally, ``flags`` may be an int, with a value
        corresponding to the XOR (``|``) of all the desired flags. Defaults to
        ``8`` (which equates to ``['MULTILINE']``).

        .. note::

            ``file.replace`` reads the entire file as a string to support
            multiline regex patterns. Therefore, when using anchors such as
            ``^`` or ``$`` in the pattern, those anchors may be relative to
            the line OR relative to the file. The default for ``file.replace``
            is to treat anchors as relative to the line, which is implemented
            by setting the default value of ``flags`` to ``['MULTILINE']``.
            When overriding the default value for ``flags``, if
            ``'MULTILINE'`` is not present then anchors will be relative to
            the file. If the desired behavior is for anchors to be relative to
            the line, then simply add ``'MULTILINE'`` to the list of flags.

    bufsize
        How much of the file to buffer into memory at once. The default value
        ``1`` processes one line at a time. The special value ``file`` may be
        specified which will read the entire file into memory before
        processing.

    append_if_not_found : False
        If set to ``True``, and pattern is not found, then the content will be
        appended to the file.

        .. versionadded:: 2014.7.0

    prepend_if_not_found : False
        If set to ``True`` and pattern is not found, then the content will be
        prepended to the file.

        .. versionadded:: 2014.7.0

    not_found_content
        Content to use for append/prepend if not found. If ``None`` (default),
        uses ``repl``. Useful when ``repl`` uses references to group in
        pattern.

        .. versionadded:: 2014.7.0

    backup
        The file extension to use for a backup of the file before editing. Set
        to ``False`` to skip making a backup.

    show_changes : True
        Output a unified diff of the old file and the new file. If ``False``
        return a boolean if any changes were made. Returns a boolean or a
        string.

        .. note:
            Using this option will store two copies of the file in memory (the
            original version and the edited version) in order to generate the
            diff. This may not normally be a concern, but could impact
            performance if used with large files.

    ignore_if_missing : False
        .. versionadded:: 2016.3.4

        Controls what to do if the file is missing. If set to ``False``, the
        state will display an error raised by the execution module. If set to
        ``True``, the state will simply report no changes.

    backslash_literal : False
        .. versionadded:: 2016.11.7

        Interpret backslashes as literal backslashes for the repl and not
        escape characters.  This will help when using append/prepend so that
        the backslashes are not interpreted for the repl on the second run of
        the state.

    For complex regex patterns, it can be useful to avoid the need for complex
    quoting and escape sequences by making use of YAML's multiline string
    syntax.

    .. code-block:: yaml

        complex_search_and_replace:
          file.replace:
            # <...snip...>
            - pattern: |
                CentOS \(2.6.32[^\\n]+\\n\s+root[^\\n]+\\n\)+

    .. note::

       When using YAML multiline string syntax in ``pattern:``, make sure to
       also use that syntax in the ``repl:`` part, or you might loose line
       feeds.
    unameuchangesuresultuucommentu!Must provide name to file.replaceufile not founduNo changes needed to be madeufile.replaceR7R�tbufsizetappend_if_not_foundtprepend_if_not_foundtnot_found_contentRntdry_runutestRotignore_if_missingtbackslash_literaludiffuChanges would have been madeuChanges were madeN(	RRR*R8R�R�R)RR5(RAtpatterntreplR7R�R�R�R�R�RnRoR�R�RR�R�R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR>sJ�





	






u#-- start managed zone --u#-- end managed zone --c%C@stjj|�}i|d6id6td6dd6}|sGt|d�S|d!kr\g}n|d!krqg}ntd|d|d	|d
|�\}}}|s�t||�St|�\}}|s�t||�St�\}}||kr�||}|j	|g�}g|D],}t
d||kr||kr|^q}|seg|D]}|^qP}nxO|D]D}||}x1|D])}|
dkr�|}
q�|
d|7}
q�WqlWn|r)td
|d|d|d|	�}|ds�|S|d} x0t| �D]\}!}"|
t
j|"�7}
qWnyHtd|||d|
d|d|d|
dtdd|d|�}#Wn4tk
r�}$tjd�dj|$�|d<|SX|#r�|#|dd<tdr�d!|d<d|d<qt|d<d|d<nt|d<d |d<|S("u
    Maintain an edit in a file in a zone delimited by two line markers

    .. versionadded:: 2014.1.0
    .. versionchanged:: 2017.7.5,2018.3.1
        ``append_newline`` argument added. Additionally, to improve
        idempotence, if the string represented by ``marker_end`` is found in
        the middle of the line, the content preceding the marker will be
        removed when the block is replaced. This allows one to remove
        ``append_newline: False`` from the SLS and have the block properly
        replaced if the end of the content block is immediately followed by the
        ``marker_end`` (i.e. no newline before the marker).

    A block of content delimited by comments can help you manage several lines
    entries without worrying about old entries removal. This can help you
    maintaining an un-managed file containing manual edits.

    .. note::
        This function will store two copies of the file in-memory (the original
        version and the edited version) in order to detect changes and only
        edit the targeted file if necessary.

        Additionally, you can use :py:func:`file.accumulated
        <salt.states.file.accumulated>` and target this state. All accumulated
        data dictionaries' content will be added in the content block.

    name
        Filesystem path to the file to be edited

    marker_start
        The line content identifying a line as the start of the content block.
        Note that the whole line containing this marker will be considered, so
        whitespace or extra content before or after the marker is included in
        final output

    marker_end
        The line content identifying the end of the content block. As of
        versions 2017.7.5 and 2018.3.1, everything up to the text matching the
        marker will be replaced, so it's important to ensure that your marker
        includes the beginning of the text you wish to replace.

    content
        The content to be used between the two lines identified by
        ``marker_start`` and ``marker_end``

    source
        The source file to download to the minion, this source file can be
        hosted on either the salt master server, or on an HTTP or FTP server.
        Both HTTPS and HTTP are supported as well as downloading directly
        from Amazon S3 compatible URLs with both pre-configured and automatic
        IAM credentials. (see s3.get state documentation)
        File retrieval from Openstack Swift object storage is supported via
        swift://container/object_path URLs, see swift.get documentation.
        For files hosted on the salt file server, if the file is located on
        the master in the directory named spam, and is called eggs, the source
        string is salt://spam/eggs. If source is left blank or None
        (use ~ in YAML), the file will be created as an empty file and
        the content will not be managed. This is also the case when a file
        already exists and the source is undefined; the contents of the file
        will not be changed or managed.

        If the file is hosted on a HTTP or FTP server then the source_hash
        argument is also required.

        A list of sources can also be passed in to provide a default source and
        a set of fallbacks. The first source in the list that is found to exist
        will be used and subsequent entries in the list will be ignored.

        .. code-block:: yaml

            file_override_example:
              file.blockreplace:
                - name: /etc/example.conf
                - source:
                  - salt://file_that_does_not_exist
                  - salt://file_that_exists

    source_hash
        This can be one of the following:
            1. a source hash string
            2. the URI of a file that contains source hash strings

        The function accepts the first encountered long unbroken alphanumeric
        string of correct length as a valid hash, in order from most secure to
        least secure:

        .. code-block:: text

            Type    Length
            ======  ======
            sha512     128
            sha384      96
            sha256      64
            sha224      56
            sha1        40
            md5         32

        See the ``source_hash`` parameter description for :mod:`file.managed
        <salt.states.file.managed>` function for more details and examples.

    template : jinja
        Templating engine to be used to render the downloaded file. The
        following engines are supported:

        - :mod:`cheetah <salt.renderers.cheetah>`
        - :mod:`genshi <salt.renderers.genshi>`
        - :mod:`jinja <salt.renderers.jinja>`
        - :mod:`mako <salt.renderers.mako>`
        - :mod:`py <salt.renderers.py>`
        - :mod:`wempy <salt.renderers.wempy>`

    context
        Overrides default context variables passed to the template

    defaults
        Default context passed to the template

    append_if_not_found : False
        If markers are not found and this option is set to ``True``, the
        content block will be appended to the file.

    prepend_if_not_found : False
        If markers are not found and this option is set to ``True``, the
        content block will be prepended to the file.

    backup
        The file extension to use for a backup of the file if any edit is made.
        Set this to ``False`` to skip making a backup.

    dry_run : False
        If ``True``, do not make any edits to the file and simply return the
        changes that *would* be made.

    show_changes : True
        Controls how changes are presented. If ``True``, the ``Changes``
        section of the state return will contain a unified diff of the changes
        made. If False, then it will contain a boolean (``True`` if any changes
        were made, otherwise ``False``).

    append_newline
        Controls whether or not a newline is appended to the content block. If
        the value of this argument is ``True`` then a newline will be added to
        the content block. If it is ``False``, then a newline will *not* be
        added to the content block. If it is unspecified, then a newline will
        only be added to the content block if it does not already end in a
        newline.

        .. versionadded:: 2017.7.5,2018.3.1

    Example of usage with an accumulator and with a variable:

    .. code-block:: jinja

        {% set myvar = 42 %}
        hosts-config-block-{{ myvar }}:
          file.blockreplace:
            - name: /etc/hosts
            - marker_start: "# START managed zone {{ myvar }} -DO-NOT-EDIT-"
            - marker_end: "# END managed zone {{ myvar }} --"
            - content: 'First line of content'
            - append_if_not_found: True
            - backup: '.bak'
            - show_changes: True

        hosts-config-block-{{ myvar }}-accumulated1:
          file.accumulated:
            - filename: /etc/hosts
            - name: my-accumulator-{{ myvar }}
            - text: "text 2"
            - require_in:
              - file: hosts-config-block-{{ myvar }}

        hosts-config-block-{{ myvar }}-accumulated2:
          file.accumulated:
            - filename: /etc/hosts
            - name: my-accumulator-{{ myvar }}
            - text: |
                 text 3
                 text 4
            - require_in:
              - file: hosts-config-block-{{ myvar }}

    will generate and maintain a block of content in ``/etc/hosts``:

    .. code-block:: text

        # START managed zone 42 -DO-NOT-EDIT-
        First line of content
        text 2
        text 3
        text 4
        # END managed zone 42 --
    unameuchangesuresultuucommentu&Must provide name to file.blockreplaceReR�R�R�u__id__u
RR�RR�udataufile.blockreplaceR�R�R�RnR�utestRotappend_newlineu Encountered error managing blocku?Encountered error managing block: {0}. See the log for details.udiffuChanges would be madeuChanges were madeuNo changes needed to be madeN(RRR*R4R�R5R�R�R#R|t__low__RR�RR�R)RR.RHt	exceptionR*R8(%RAtmarker_startt
marker_endReR�R�R�R�RR�R�R�R�RnRoR�Rtok_R-tsl_R�R�R�t
accum_depstaccumulatortdepstatfilteredtacctacc_contentR�ttmpretttexttindexRR�R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pytblockreplace�s��


		



,


		












u#c
C@s�tjj|�}i|d6id6td6dd6}|sGt|d�St|�\}}|slt||�Stjdd|�}||}td	||d
t	�r�t	}	nt}	|	s�td	||d
t	�rtd	||d
t	�rd|d<t	|d<|St|dj
|��Sntd
rVd|d|<dj
|�|d<d|d<|St
jjj|d��=}
|
j�}tjr�|jt�}n|jt	�}WdQXtd|||t	|�t
jjj|d��=}
|
j�}tjr	|jt�}n|jt	�}WdQXtd	||d
t	�|d<||kr�td|�shd|dd<q�djtj||��|dd<n|dr�d|d<n
d|d<|S(u�
    Comment out specified lines in a file.

    name
        The full path to the file to be edited
    regex
        A regular expression used to find the lines that are to be commented;
        this pattern will be wrapped in parenthesis and will move any
        preceding/trailing ``^`` or ``$`` characters outside the parenthesis
        (e.g., the pattern ``^foo$`` will be rewritten as ``^(foo)$``)
        Note that you _need_ the leading ^, otherwise each time you run
        highstate, another comment char will be inserted.
    char : ``#``
        The character to be inserted at the beginning of a line in order to
        comment it out
    backup : ``.bak``
        The file will be backed up before edit with this file extension

        .. warning::

            This backup will be overwritten each time ``sed`` / ``comment`` /
            ``uncomment`` is called. Meaning the backup will only be useful
            after the first invocation.

        Set to False/None to not keep a backup.

    Usage:

    .. code-block:: yaml

        /etc/fstab:
          file.comment:
            - regex: ^bind 127.0.0.1

    .. versionadded:: 0.9.5
    unameuchangesuresultuucommentu!Must provide name to file.commentu^(\(\?[iLmsux]\))?\^?(.*?)\$?$u\2ufile.searcht	multilineuPattern already commentedu{0}: Pattern not foundutestuupdateduFile {0} is set to be updatedurbNufile.comment_lineu
files.is_textuReplace binary fileudiffuCommented lines successfullyu"Expected commented lines not found(RRR*R4R�R�R?tsubR)R8R*RR5RRRRR�RtPY3Rbt__salt_system_encoding__Rt	__utils__Rtdifflibtunified_diff(
RARNtcharRnRR�R�tunanchor_regext
comment_regext	commentedRtslinestnlines((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��s\%




	 



		&


c
C@shtjj|�}i|d6id6td6dd6}|sGt|d�St|�\}}|slt||�Std|dj|jd	��d
t	�r�d|d<t	|d<|Std|dj||jd	��d
t	�r�nt|d
j|��St
dr/d|d|<dj|�|d<d|d<|Stj
jj|d��"}tj
jj|j��}WdQXtd|||t|�tj
jj|d��"}tj
jj|j��}	WdQXtd|dj|jd	��d
t	�|d<||	krCtd|�sd|dd<qCdjtj||	��|dd<n|drZd|d<n
d|d<|S(u]
    Uncomment specified commented lines in a file

    name
        The full path to the file to be edited
    regex
        A regular expression used to find the lines that are to be uncommented.
        This regex should not include the comment character. A leading ``^``
        character will be stripped for convenience (for easily switching
        between comment() and uncomment()).  The regex will be searched for
        from the beginning of the line, ignoring leading spaces (we prepend
        '^[ \t]*')
    char : ``#``
        The character to remove in order to uncomment a line
    backup : ``.bak``
        The file will be backed up before edit with this file extension;

        .. warning::

            This backup will be overwritten each time ``sed`` / ``comment`` /
            ``uncomment`` is called. Meaning the backup will only be useful
            after the first invocation.

        Set to False/None to not keep a backup.

    Usage:

    .. code-block:: yaml

        /etc/adduser.conf:
          file.uncomment:
            - regex: EXTRA_GROUPS

    .. versionadded:: 0.9.5
    unameuchangesuresultuucommentu#Must provide name to file.uncommentufile.searchu	^[ 	]*{0}u^RuPattern already uncommentedu{0}[ 	]*{1}u{0}: Pattern not foundutestuupdateduFile {0} is set to be updatedurbNufile.comment_lineu
files.is_textuReplace binary fileudiffuUncommented lines successfullyu$Expected uncommented lines not found(RRR*R4R�R�R)R*R�R8RR5RRRRRaRbt	readlinesR
RRR(
RARNR
RnRR�R�RRR((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	uncommentbsZ$



	

	

!!
&


c	C@s	i|d6id6td6dd6}|s5t|d�Stjj|�}|dkr\g}n|dkrqg}ntd|d|d	|d
|�\}}
}|s�t||
�S|tkr�tjj|�}t	dr�dj
|�|d<d|d<q�td
|�s�ytd|�Wn)t
k
rB}t|dj
|j��SXtjjj�rat|�n	t|�\}}}|s�||d<t||�Sq�nt|�\}}|s�t|d|�}t	dr�|St|�\}}|s�t||�Sn|r;td|d|d|d|	�}|ds.|S|d}nt|�}tjjj|d��:}|j�}tjr�|jt�}n|j �}WdQXg}y�x�|D]�}|
r�td|tjj!j"|�dt�rq�qntd||dt�rq�nx*|j �D]}|j#dj
|��qWq�WWnt$k
rVt|d�SXt	drdj
|�|d<d|d<t%|�}|j&|�||kr�t'd|�s�d|dd<qd j(t)j*||��|dd<nd!j
|�|d<t|d<|S|rAtd"|d#|�d$j
t+|��|d<nd!j
|�|d<tjjj|d��:}|j�}tjr�|jt�}n|j �}WdQX||kr�t'd|�s�d|dd<q�d j(t)j*||��|dd<nt|d<|S(%u�
    Ensure that some text appears at the end of a file.

    The text will not be appended if it already exists in the file.
    A single string of text or a list of strings may be appended.

    name
        The location of the file to append to.

    text
        The text to be appended, which can be a single string or a list
        of strings.

    makedirs
        If the file is located in a path without a parent directory,
        then the state will fail. If makedirs is set to True, then
        the parent directories will be created to facilitate the
        creation of the named file. Defaults to False.

    source
        A single source file to append. This source file can be hosted on either
        the salt master server, or on an HTTP or FTP server. Both HTTPS and
        HTTP are supported as well as downloading directly from Amazon S3
        compatible URLs with both pre-configured and automatic IAM credentials
        (see s3.get state documentation). File retrieval from Openstack Swift
        object storage is supported via swift://container/object_path URLs
        (see swift.get documentation).

        For files hosted on the salt file server, if the file is located on
        the master in the directory named spam, and is called eggs, the source
        string is salt://spam/eggs.

        If the file is hosted on an HTTP or FTP server, the source_hash argument
        is also required.

    source_hash
        This can be one of the following:
            1. a source hash string
            2. the URI of a file that contains source hash strings

        The function accepts the first encountered long unbroken alphanumeric
        string of correct length as a valid hash, in order from most secure to
        least secure:

        .. code-block:: text

            Type    Length
            ======  ======
            sha512     128
            sha384      96
            sha256      64
            sha224      56
            sha1        40
            md5         32

        See the ``source_hash`` parameter description for :mod:`file.managed
        <salt.states.file.managed>` function for more details and examples.

    template
        The named templating engine will be used to render the appended-to file.
        Defaults to ``jinja``. The following templates are supported:

        - :mod:`cheetah<salt.renderers.cheetah>`
        - :mod:`genshi<salt.renderers.genshi>`
        - :mod:`jinja<salt.renderers.jinja>`
        - :mod:`mako<salt.renderers.mako>`
        - :mod:`py<salt.renderers.py>`
        - :mod:`wempy<salt.renderers.wempy>`

    sources
        A list of source files to append. If the files are hosted on an HTTP or
        FTP server, the source_hashes argument is also required.

    source_hashes
        A list of source_hashes corresponding to the sources list specified in
        the sources argument.

    defaults
        Default context passed to the template.

    context
        Overrides default context variables passed to the template.

    ignore_whitespace
        .. versionadded:: 2015.8.4

        Spaces and Tabs in text are ignored by default, when searching for the
        appending content, one space or multiple tabs are the same for salt.
        Set this option to ``False`` if you want to change this behavior.

    Multi-line example:

    .. code-block:: yaml

        /etc/motd:
          file.append:
            - text: |
                Thou hadst better eat salt with the Philosophers of Greece,
                than sugar with the Courtiers of Italy.
                - Benjamin Franklin

    Multiple lines of text:

    .. code-block:: yaml

        /etc/motd:
          file.append:
            - text:
              - Trust no one unless you have eaten much salt with him.
              - "Salt is born of the purest of parents: the sun and the sea."

    Gather text from multiple template files:

    .. code-block:: yaml

        /etc/motd:
          file:
            - append
            - template: jinja
            - sources:
              - salt://motd/devops-messages.tmpl
              - salt://motd/hr-messages.tmpl
              - salt://motd/general-messages.tmpl

    .. versionadded:: 0.9.5
    unameuchangesuresultuucommentu Must provide name to file.appendReR�R�R�utestu"Directory {0} is set to be updatedufile.directory_existsRAuDrive {0} is not mappedR0RR�RR�udataurbNufile.searchRu{0}u)No text found to append. Nothing appendeduFile {0} is set to be updatedu
files.is_textuReplace binary fileudiffu
uFile {0} is in correct stateufile.appendtargsuAppended {0} lines(,R4R�RRR*R5R�R8RcRR*R)R(RR+RRR�R�R�R�R�ttouchRR
RRR�RRRbR	RRDtbuild_whitespace_split_regexR�R�RFR�R
RRRR�(RARR0ReR�R�R�R�RR�tignore_whitespaceRR�R-R�RcR�R�R�t
check_changest	touch_rett	retry_rest	retry_msgRRRtappend_linestchunkt	line_itemR((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��s��


		




	

	
			"



&
	&
c$	C@s�tjj|�}i|d6id6td6dd6}|sGt|d�S|dkr\g}n|dkrqg}ntd|d|d	|d
|�\}}
}|s�t||
�S|tkrotjj|�}t	d|�soyt
d|�Wn)tk
r}t|d
j|j
��SXtjjj�r7t|�n	t|�\}}}|sl||d<t||�Sqont|�\}}|s�t|d|�}tdr�|St|�\}}|s�t||�Sn|rtd|d|d|d|	�}|ds|S|d}nt|�}tjjj|d��=}|j�}tjr_|jt�}n|j t�}WdQXd}g}g}x�|D]�}|
s�t	d|tjj!j"|�dt�r�q�q�n|j �}xe|D]]}tdr#dj|�|d<d|d<|j#dj|��n
|j#|�|d7}q�Wq�Wtdr�||} || kr�t$d|�s�d|dd<n#dj%t&j'|| ��|dd<d|d<nd j|�|d<t|d<|S|
r�tjjj|d���}|j�}!tjr|!jt�}!n|!j t�}!|!dt(|�!}"g}#x|"D]}|#|j �7}#qKW|#|kr�t	d!||�nd}WdQXnt	d!||�tjjj|d��=}|j�} tjr�| jt�} n| j t�} WdQX|| krOt$d|�s)d|dd<qOdj%t&j'|| ��|dd<n|rkd"j|�|d<nd j|�|d<t|d<|S(#u�
    Ensure that some text appears at the beginning of a file

    The text will not be prepended again if it already exists in the file. You
    may specify a single line of text or a list of lines to append.

    name
        The location of the file to append to.

    text
        The text to be appended, which can be a single string or a list
        of strings.

    makedirs
        If the file is located in a path without a parent directory,
        then the state will fail. If makedirs is set to True, then
        the parent directories will be created to facilitate the
        creation of the named file. Defaults to False.

    source
        A single source file to append. This source file can be hosted on either
        the salt master server, or on an HTTP or FTP server. Both HTTPS and
        HTTP are supported as well as downloading directly from Amazon S3
        compatible URLs with both pre-configured and automatic IAM credentials
        (see s3.get state documentation). File retrieval from Openstack Swift
        object storage is supported via swift://container/object_path URLs
        (see swift.get documentation).

        For files hosted on the salt file server, if the file is located on
        the master in the directory named spam, and is called eggs, the source
        string is salt://spam/eggs.

        If the file is hosted on an HTTP or FTP server, the source_hash argument
        is also required.

    source_hash
        This can be one of the following:
            1. a source hash string
            2. the URI of a file that contains source hash strings

        The function accepts the first encountered long unbroken alphanumeric
        string of correct length as a valid hash, in order from most secure to
        least secure:

        .. code-block:: text

            Type    Length
            ======  ======
            sha512     128
            sha384      96
            sha256      64
            sha224      56
            sha1        40
            md5         32

        See the ``source_hash`` parameter description for :mod:`file.managed
        <salt.states.file.managed>` function for more details and examples.

    template
        The named templating engine will be used to render the appended-to file.
        Defaults to ``jinja``. The following templates are supported:

        - :mod:`cheetah<salt.renderers.cheetah>`
        - :mod:`genshi<salt.renderers.genshi>`
        - :mod:`jinja<salt.renderers.jinja>`
        - :mod:`mako<salt.renderers.mako>`
        - :mod:`py<salt.renderers.py>`
        - :mod:`wempy<salt.renderers.wempy>`

    sources
        A list of source files to append. If the files are hosted on an HTTP or
        FTP server, the source_hashes argument is also required.

    source_hashes
        A list of source_hashes corresponding to the sources list specified in
        the sources argument.

    defaults
        Default context passed to the template.

    context
        Overrides default context variables passed to the template.

    ignore_whitespace
        .. versionadded:: 2015.8.4

        Spaces and Tabs in text are ignored by default, when searching for the
        appending content, one space or multiple tabs are the same for salt.
        Set this option to ``False`` if you want to change this behavior.

    Multi-line example:

    .. code-block:: yaml

        /etc/motd:
          file.prepend:
            - text: |
                Thou hadst better eat salt with the Philosophers of Greece,
                than sugar with the Courtiers of Italy.
                - Benjamin Franklin

    Multiple lines of text:

    .. code-block:: yaml

        /etc/motd:
          file.prepend:
            - text:
              - Trust no one unless you have eaten much salt with him.
              - "Salt is born of the purest of parents: the sun and the sea."

    Optionally, require the text to appear exactly as specified
    (order and position). Combine with multi-line or multiple lines of input.

    .. code-block:: yaml

        /etc/motd:
          file.prepend:
            - header: True
            - text:
              - This will be the very first line in the file.
              - The 2nd line, regardless of duplicates elsewhere in the file.
              - These will be written anew if they do not appear verbatim.

    Gather text from multiple template files:

    .. code-block:: yaml

        /etc/motd:
          file:
            - prepend
            - template: jinja
            - sources:
              - salt://motd/devops-messages.tmpl
              - salt://motd/hr-messages.tmpl
              - salt://motd/general-messages.tmpl

    .. versionadded:: 2014.7.0
    unameuchangesuresultuucommentu!Must provide name to file.prependReR�R�R�ufile.directory_existsRAuDrive {0} is not mappedR0utestRR�RR�udataurbNiufile.searchRuFile {0} is set to be updatedu{0}
iu
files.is_textuReplace binary fileudiffuFile {0} is in correct stateufile.prependuPrepended {0} lines()RRR*R4R�R5R�R8RcR)R(RR*R+RRR�R�R�R�R�RRRR
RRR�RRRbR	RRDRR�R
RRRR�($RARR0ReR�R�R�R�RR�theaderRR�R-R�RcR�R�R�RRRRRRRR7t
test_linestprefaceRtlinesR�RRpttarget_headttarget_lines((s4/usr/lib/python2.7/site-packages/salt/states/file.pytprepend�s��


		


	

	
		





#

	
	&
c)@s�i�d6id6td6dd6}
tjjjd�sEd|
d<|
St}�s_d|
d<|
Sytjj���Wn%tk
r�d	j��|
d<|
SXtjj	��s�d
j��|
d<|
Stjj
��s�dj��|
d<|
Stjj��}x?dGD]7}||kr|
jdg�j
dj|��qqW|	d3k	r�ytjj|	�}Wn%tk
r�dj|	�|
d<|
SXtjj	|�s�dj|	�|
d<|
Stjj|�s�dj|	�|
d<|
Sng�tjjj|�}d}t|�d}g}x�||kr�||}t|tj�sVtj|�}nx-dHD]}|j|�r]|}Pq]q]Wd3}|d3k	r�|j
|�n|jd�r�yt|d�}
Wq�tk
r�d|
d<|
SXn�|jd�r�d|krDy t|jdd�d �}
Wq�tk
r@d!|
d<|
SXq�yt||d�}
Wntk
rzd!|
d<|
SX|d7}n
�j
|�|d7}qW|r�d"jd#j|��|
d<|
S�}ytd$||t�d}Wn+tk
r}t|
d<|j|
d<|
SX|d3k	r�tjjj |�\}}|jd%�r�|d3k	r�||kr�|
jdg�j
d&�q�|d'j|�7}q�ng}zvtjj!j"�}|j
|�z�yit#d(}tt#d(<tt$j%td)j&j#d(<t'|d*|d+|d,|d-|d.|d/|d0|�}WnLtk
r�}d1jtjjj(|�|�}t)j*|�||
d<|
SXt)j+d2|�Wd3|t#d(<|t$j%td)j&j#d(<X|ds�t)j+d4tjjj(|��|Sd3t��fd5�} |	d3k	r|	}!ntjj!j"�}!|j
|!�tjj!j"�}"|j
|"�dd|!d|"g}#|r�|
d3k	r�|#j
d6j|
��n| ||#�}$|$d7dkrp| |!d8d9gd:t,�}%|%d7dk}&|&r�d;|
d<t,|
d<|
Sd<|
d<|	d3kr$|
dcd=7<nt-j-t#�}'t|'d><|
dcd?tj.j/|$d@|'dAdB�7<|
Snt#d(r�d3|
d<dC|
d<|$|
d<|
Sg}#|r�|
d3k	r�|#j
d6j|
��n| ||#�|
d<|
dd7dkrdD|
d<t,|
d<n
dE|
d<|
SWd3x`|D]X}(ytj0|(�Wq$t1k
r{}|j2tj2j3kr|t)j4dF|(|�q|q$Xq$WXd3S(Iu
    Ensure that a patch has been applied to the specified file or directory

    .. versionchanged:: 2019.2.0
        The ``hash`` and ``dry_run_first`` options are now ignored, as the
        logic which determines whether or not the patch has already been
        applied no longer requires them. Additionally, this state now supports
        patch files that modify more than one file. To use these sort of
        patches, specify a directory (and, if necessary, the ``strip`` option)
        instead of a file.

    .. note::
        A suitable ``patch`` executable must be available on the minion. Also,
        keep in mind that the pre-check this state does to determine whether or
        not changes need to be made will create a temp file and send all patch
        output to that file. This means that, in the event that the patch would
        not have applied cleanly, the comment included in the state results will
        reference a temp file that will no longer exist once the state finishes
        running.

    name
        The file or directory to which the patch should be applied

    source
        The patch file to apply

        .. versionchanged:: 2019.2.0
            The source can now be from any file source supported by Salt
            (``salt://``, ``http://``, ``https://``, ``ftp://``, etc.).
            Templating is also now supported.

    source_hash
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`.

        .. versionadded:: 2019.2.0

    source_hash_name
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`

        .. versionadded:: 2019.2.0

    skip_verify
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`

        .. versionadded:: 2019.2.0

    template
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`

        .. versionadded:: 2019.2.0

    context
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`

        .. versionadded:: 2019.2.0

    defaults
        Works the same way as in :py:func:`file.managed
        <salt.states.file.managed>`

        .. versionadded:: 2019.2.0

    options
        Extra options to pass to patch. This should not be necessary in most
        cases.

        .. note::
            For best results, short opts should be separate from one another.
            The ``-N`` and ``-r``, and ``-o`` options are used internally by
            this state and cannot be used here. Additionally, instead of using
            ``-pN`` or ``--strip=N``, use the ``strip`` option documented
            below.

    reject_file
        If specified, any rejected hunks will be written to this file. If not
        specified, then they will be written to a temp file which will be
        deleted when the state finishes running.

        .. important::
            The parent directory must exist. Also, this will overwrite the file
            if it is already present.

        .. versionadded:: 2019.2.0

    strip
        Number of directories to strip from paths in the patch file. For
        example, using the below SLS would instruct Salt to use ``-p1`` when
        applying the patch:

        .. code-block:: yaml

            /etc/myfile.conf:
              file.patch:
                - source: salt://myfile.patch
                - strip: 1

        .. versionadded:: 2019.2.0
            In previous versions, ``-p1`` would need to be passed as part of
            the ``options`` value.

    saltenv
        Specify the environment from which to retrieve the patch file indicated
        by the ``source`` parameter. If not provided, this defaults to the
        environment from which the state is being executed.

        .. note::
            Ignored when the patch file is from a non-``salt://`` source.

    **Usage:**

    .. code-block:: yaml

        # Equivalent to ``patch --forward /opt/myfile.txt myfile.patch``
        /opt/myfile.txt:
          file.patch:
            - source: salt://myfile.patch
    unameuchangesuresultuucommentupatchu$patch executable not found on minionu*A file/directory to be patched is requireduInvalid path '{0}'u{0} is not an absolute pathu{0} does not existuhashu
dry_run_firstuwarningsu:The '{0}' argument is no longer used and has been ignored.u"Invalid path '{0}' for reject_fileu'{0}' is not an absolute pathuSParent directory for reject_file '{0}' either does not exist, or is not a directoryiiu-Nu	--forwardu-ru
--reject-fileu-ou--outputu-piuUInvalid format for '-p' CLI option. Consider using the 'strip' option for this state.u--stripu=i����uYInvalid format for '-strip' CLI option. Consider using the 'strip' option for this state.u.The following CLI options are not allowed: {0}u, ufile.source_listusalt://uIIgnoring 'saltenv' option in favor of saltenv included in the source URL.u?saltenv={0}utestu	test.pingReR�RkRyR�R�Ru#Failed to cache patch file {0}: {1}ufile.managed: %sNufailed to download %sc@sHtj��}|dk	r+|j|�ntd�|d|d|�S(Nu
file.patchtoptionsR�(tcopyR5R�R)(t
patch_fileR'R�t
patch_opts(RAtsanitized_options(s4/usr/lib/python2.7/site-packages/salt/states/file.pyt_patchZsu-p{0}uretcodeu-Ru-fR�uPatch was already applieduMPatch would not apply cleanly, no changes made. Results of dry-run are below.uS Run state again using the reject_file option to save rejects to a persistent file.ucoloru

unestedt
nested_indentiuThe patch would be applieduPatch successfully applieduFailed to apply patchu-file.patch: Failed to remove temp file %s: %s(uhashu
dry_run_first(u-Nu	--forwardu-ru
--reject-fileu-ou--output(5R4RRRtwhichRR*R.R*R�R�R{R\R�R5RcRtshlex_splitR�R�RR�R�RGR�trsplitRR)R_RRbR]R^RRfRR�tmodulest
__module__R�tredact_http_basic_authRHR�RIR8R(toutputt
out_formatRJR�terrnotENOENTR�()RAReR�RkRyR�R�RR'treject_fileR6R[RhRtis_dirtdeprecated_argtreject_file_parentRt	max_indextblacklisted_optionstoptionRtblacklistedtsource_matchR�tsource_match_urltsource_match_saltenvtcleanupR)t	orig_testR�R�R,t
patch_rejectstpatch_outputR*t	pre_checktreverse_passtalready_appliedtoptsR((RAR+s4/usr/lib/python2.7/site-packages/salt/states/file.pytpatchsl�"











 












	
	




	





	









cC@s�tjj|�}i|d6id6}|s9t|d�Stjj|�sat|dj|��Stdr�|jt|||��|S|r�yt	d|�Wq�t
k
r�}t|dj|j��SXntjjtjj
|��st|dj|��Stjj|�}td	|||�|d
<|rc|d
rcdj|�|d<||dd
<nO|r�|d
r�djtjj|�r�dnd|�|d<||dd<n|S(u1
    Replicate the 'nix "touch" command to create a new empty
    file or update the atime and mtime of an existing file.

    Note that if you just want to create a file and don't care about atime or
    mtime, you should use ``file.managed`` instead, as it is more
    feature-complete.  (Just leave out the ``source``/``template``/``contents``
    arguments, and it will just create the file and/or check its permissions,
    without messing with contents)

    name
        name of the file

    atime
        atime of the file

    mtime
        mtime of the file

    makedirs
        whether we should create the parent directory/directories in order to
        touch the file

    Usage:

    .. code-block:: yaml

        /var/log/httpd/logrotate.empty:
          file.touch

    .. versionadded:: 0.9.5
    unameuchangesuMust provide name to file.touchu*Specified file {0} is not an absolute pathutestRAuDrive {0} is not mappedu'Directory not present to touch file {0}u
file.touchuresultuCreated empty file {0}ucommentunewuUpdated times on {0} {1}u	directoryufileutouched(RRR*R�R�R*RRLR�R(RR+R{RcR�R)(RAR�R�R0RR�textant((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR�s<!


(c	
K@s�tjj|�}tjj|�}i|d6id6dj||�d6td6}
|set|
d�St}tjj|�s�t|
dj|��Stjj|�s�t|
dj|��S|r�td	|�}td
|�}td|�}n�t	|	d|�}|d&krtd
}ntj
jj�r_|d&k	rVtjdj|��n|}n|d&kr�tdtd|�jdd��}nt||�}|r�t|
|�S|d&kr�td|�}ntjj|�r|rtjj|tjj|��}ntjj|�rtjj|�r|r�tjj|�r�tj
jj|�}
tj
jj|�}|
|kr�t}dj|
ddg�|
d<q�n|s�t}qtdr|rytd|�Wqttfk
r
t|
dj|��SXqntdre|rDdj||�|
d<d&|
d<ndj|�|
d<t|
d<|
S|s�dj|�|
d<t|
d<|
Stjj|�}tjj|�s!|ry#td|d|d|d|�Wqt k
r}t|
dj|j!��SXq!t|
dj|��Sny8tjj|�r�t"j#||dt�x�tj
jj$|�D]w\}}}x1|D])}td tjj||�||�qxWx1|D])}td tjj||�||�q�WqbWnt"j%||�i||6|
d<|sXtj
jj�r;td!d"|d#|
d$|�}
qXtd!||
|||�nWn-ttfk
r�t|
d%j||��SX|
S('u\	
    If the file defined by the ``source`` option exists on the minion, copy it
    to the named path. The file will not be overwritten if it already exists,
    unless the ``force`` option is set to ``True``.

    .. note::
        This state only copies files from one location on a minion to another
        location on the same minion. For copying files from the master, use a
        :py:func:`file.managed <salt.states.file.managed>` state.

    name
        The location of the file to copy to

    source
        The location of the file to copy to the location specified with name

    force
        If the target location is present then the file will not be moved,
        specify "force: True" to overwrite the target file

    makedirs
        If the target subdirectories don't exist create them

    preserve
        .. versionadded:: 2015.5.0

        Set ``preserve: True`` to preserve user/group ownership and mode
        after copying. Default is ``False``. If ``preserve`` is set to ``True``,
        then user/group/mode attributes will be ignored.

    user
        .. versionadded:: 2015.5.0

        The user to own the copied file, this defaults to the user salt is
        running as on the minion. If ``preserve`` is set to ``True``, then
        this will be ignored

    group
        .. versionadded:: 2015.5.0

        The group to own the copied file, this defaults to the group salt is
        running as on the minion. If ``preserve`` is set to ``True`` or on
        Windows this will be ignored

    mode
        .. versionadded:: 2015.5.0

        The permissions to set on the copied file, aka 644, '0775', '4664'.
        If ``preserve`` is set to ``True``, then this will be ignored.
        Not supported on Windows.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

    subdir
        .. versionadded:: 2015.5.0

        If the name is a directory then place the file inside the named
        directory

    .. note::
        The copy function accepts paths that are local to the Salt minion.
        This function does not support salt://, http://, or the other
        additional file paths that are supported by :mod:`states.file.managed
        <salt.states.file.managed>` and :mod:`states.file.recurse
        <salt.states.file.recurse>`.

    unameuchangesuCopied "{0}" to "{1}"ucommenturesultuMust provide name to file.copyu*Specified file {0} is not an absolute pathu Source file "{0}" is not presentu
file.get_userufile.get_groupu
file.get_modeR+uuseruHThe group argument for {0} has been ignored as this is a Windows system.ufile.gid_to_groupu	user.infougidiu u+- files are identical but force flag is setutestufile.removeu5Failed to delete "{0}" in preparation for forced moveu'File "{0}" is set to be copied to "{1}"u8The target file "{0}" exists and will not be overwrittenRAR,R�uDrive {0} is not mappedu'The target directory {0} is not presentRNufile.lchownufile.check_permsRRR�uFailed to copy "{0}" to "{1}"N(&RRR*R*R8R�R�R�R)R�R5RRRR�R�RHR�R|R0R{RR,R-Rt	hashutilstget_hashR4RR�RcR(RR+tshutiltcopytreeR�R((RAReR�R0tpreserveR+R,R�tsubdirRhRtchangedR�thash1thash2tdnameR�R�R~RR�tfile_((s4/usr/lib/python2.7/site-packages/salt/states/file.pytcopy_s�N



	"
$$#	






#%
'
.
!cC@s�tjj|�}tjj|�}i|d6id6dd6td6}|sYt|d�Stjj|�s�t|dj|��Stjj|�s�dj|�|d<|Stjj|�rDtjj|�rD|s�d	j|�|d<t|d<|St	d
sDyt
d|�WqAttfk
r=t|dj|��SXqDnt	d
rrd
j||�|d<d|d<|Stjj|�}tjj|�s�|r�ytd|�Wq�tk
r�}t|dj|j��SXq�t|dj|��SnyUtjj|�r9tj|�}tj||�tj|�ntj||�Wn-ttfk
ryt|dj||��SXdj||�|d<i||6|d<|S(u)
    If the source file exists on the system, rename it to the named file. The
    named file will not be overwritten if it already exists unless the force
    option is set to True.

    name
        The location of the file to rename to

    source
        The location of the file to move to the location specified with name

    force
        If the target location is present then the file will not be moved,
        specify "force: True" to overwrite the target file

    makedirs
        If the target subdirectories don't exist create them

    unameuchangesuucommenturesultu Must provide name to file.renameu*Specified file {0} is not an absolute pathu5Source file "{0}" has already been moved out of placeu8The target file "{0}" exists and will not be overwrittenutestufile.removeu5Failed to delete "{0}" in preparation for forced moveu&File "{0}" is set to be moved to "{1}"RAuDrive {0} is not mappedu'The target directory {0} is not presentuFailed to move "{0}" to "{1}"uMoved "{0}" to "{1}"N(RRR*R8R�R�R*R-R4RR)RR�R5RcR{R(RR+RttreadlinkR6tunlinkROtmove(RAReR�R0RRVR�tlinkto((s4/usr/lib/python2.7/site-packages/salt/states/file.pyR��st


$





c
K@s*i|d6id6td6dd6}|s5t|d�S|dkrYt|d<d|d<|Stjdg�}tjd	g�}||}g|D]}d
|kr�|^q�s�t|d<dj|tdtd
�|d<|St|tj	�r�|f}nt|t
�r|f}nt�\}	}
||	kr<i|	|<n||
krUi|
|<n||
|krvg|
||<nx,|D]$}|
||jtj
|��q}W||	|kr�g|	||<nxP|D]H}||	||kr�|	||j|�dj||�|d<q�q�Wt|	|
�|S(u
    Prepare accumulator which can be used in template in file.managed state.
    Accumulator dictionary becomes available in template. It can also be used
    in file.blockreplace.

    name
        Accumulator name

    filename
        Filename which would receive this accumulator (see file.managed state
        documentation about ``name``)

    text
        String or list for adding in accumulator

    require_in / watch_in
        One of them required for sure we fill up accumulator before we manage
        the file. Probably the same as filename

    Example:

    Given the following:

    .. code-block:: yaml

        animals_doing_things:
          file.accumulated:
            - filename: /tmp/animal_file.txt
            - text: ' jumps over the lazy dog.'
            - require_in:
              - file: animal_file

        animal_file:
          file.managed:
            - name: /tmp/animal_file.txt
            - source: salt://animal_file.txt
            - template: jinja

    One might write a template for ``animal_file.txt`` like the following:

    .. code-block:: jinja

        The quick brown fox{% for animal in accumulator['animals_doing_things'] %}{{ animal }}{% endfor %}

    Collectively, the above states and template file will produce:

    .. code-block:: text

        The quick brown fox jumps over the lazy dog.

    Multiple accumulators can be "chained" together.

    .. note::
        The 'accumulator' data structure is a Python dictionary.
        Do not expect any loop over the keys in a deterministic order!
    unameuchangesuresultuucommentu%Must provide name to file.accumulatedu No text supplied for accumulatoru
require_inuwatch_inufileu#Orphaned accumulator {0} in {1}:{2}u__sls__u__id__u0Accumulator {0} for file {1} was charged by textN(R8R�R5R4R�R|R*R�RR�RaR#R�t
itervaluesR�R((
RARSRRhRt
require_intwatch_inR�R{R�R�R�R((s4/usr/lib/python2.7/site-packages/salt/states/file.pytaccumulated6sV9




%



"

c$K@s_d|kr|jd�ntjj|�}iitd6d6idd6dDd6td	6d
6}iid6id6}|r�|djitd
6�|d
jitd6�niid6dd6|d6td6}|s�t|d�S|	stjj|�sdj	|�|d<|Sn|jdd�j
�}tg||fD]}|r:|^q:�dkrht|d�S|r�td|�}n|d#kr�t|d�Stjjj�r�|d#k	r�tjd|�n|}ndj	|�}dj	|�}|tkr-iid6dj	|j��d6|d6td6S|
r^|j|i�jtjjj|
��n|r�|j|i�jtjjj|��n|
r�tjj|�r�|tkr�iid6d j	|�d6|d6td6Stjjj|d!��d}y#t|||j|i��}Wn7ttfk
rS}t|d<d"j	|�|d<tSXWd#QX|d#k	r�tjjj||�}||kr�t|d<d$j	|�|d<|S|}q�q�n"|r�|jd%g�j d&�nt|||j|i��}|d'7}tjjj!|�}t"d(r�td)d*|d+d#d,id-d#d.|d/|d0|d1d#d2d#d3d#d4d#d5t#d6|d7t|�|d<|dr�d#|d<d8j	|�|d<|s�d9|dd:<q�nt|d<d$j	|�|d<|Std;d*|d<dd=|d+d#d>id.|d/|d0|d1d#d5t#d?|d@|d2d#dA|dB|dC|d6|�S(Eu;
    Serializes dataset and store it into managed file. Useful for sharing
    simple configuration files.

    name
        The location of the file to create

    dataset
        The dataset that will be serialized

    dataset_pillar
        Operates like ``dataset``, but draws from a value stored in pillar,
        using the pillar path syntax used in :mod:`pillar.get
        <salt.modules.pillar.get>`. This is useful when the pillar value
        contains newlines, as referencing a pillar variable using a jinja/mako
        template can result in YAML formatting issues due to the newlines
        causing indentation mismatches.

        .. versionadded:: 2015.8.0

    formatter
        Write the data as this format. See the list of :py:mod:`serializer
        modules <salt.serializers>` for supported output formats.

    encoding
        If specified, then the specified encoding will be used. Otherwise, the
        file will be encoded using the system locale (usually UTF-8). See
        https://docs.python.org/3/library/codecs.html#standard-encodings for
        the list of available encodings.

        .. versionadded:: 2017.7.0

    encoding_errors : 'strict'
        Error encoding scheme. Default is ```'strict'```.
        See https://docs.python.org/2/library/codecs.html#codec-base-classes
        for the list of available schemes.

        .. versionadded:: 2017.7.0

    user
        The user to own the directory, this defaults to the user salt is
        running as on the minion

    group
        The group ownership set for the directory, this defaults to the group
        salt is running as on the minion

    mode
        The permissions to set on this file, e.g. ``644``, ``0775``, or
        ``4664``.

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.

        .. note::
            This option is **not** supported on Windows.

    backup
        Overrides the default backup mode for this specific file.

    makedirs
        Create parent directories for destination file.

        .. versionadded:: 2014.1.3

    show_changes
        Output a unified diff of the old file and the new file. If ``False``
        return a boolean if any changes were made.

    create
        Default is True, if create is set to False then the file will only be
        managed if the file already exists on the system.

    merge_if_exists
        Default is False, if merge_if_exists is True then the existing file will
        be parsed and the dataset passed in will be merged with the existing
        content

        .. versionadded:: 2014.7.0

    serializer_opts
        Pass through options to serializer. For example:

        .. code-block:: yaml

           /etc/dummy/package.yaml
             file.serialize:
               - formatter: yaml
               - serializer_opts:
                 - explicit_start: True
                 - default_flow_style: True
                 - indent: 4

        The valid opts are the additional opts (i.e. not the data being
        serialized) for the function used to serialize the data. Documentation
        for the these functions can be found in the list below:

        - For **yaml**: `yaml.dump()`_
        - For **json**: `json.dumps()`_
        - For **python**: `pprint.pformat()`_

        .. _`yaml.dump()`: https://pyyaml.org/wiki/PyYAMLDocumentation
        .. _`json.dumps()`: https://docs.python.org/2/library/json.html#json.dumps
        .. _`pprint.pformat()`: https://docs.python.org/2/library/pprint.html#pprint.pformat

    deserializer_opts
        Like ``serializer_opts`` above, but only used when merging with an
        existing file (i.e. when ``merge_if_exists`` is set to ``True``).

        The options specified here will be passed to the deserializer to load
        the existing data, before merging with the specified data and
        re-serializing.

        .. code-block:: yaml

           /etc/dummy/package.yaml
             file.serialize:
               - formatter: yaml
               - serializer_opts:
                 - explicit_start: True
                 - default_flow_style: True
                 - indent: 4
               - deserializer_opts:
                 - encoding: latin-1
               - merge_if_exists: True

        The valid opts are the additional opts (i.e. not the data being
        deserialized) for the function used to deserialize the data.
        Documentation for the these functions can be found in the list below:

        - For **yaml**: `yaml.load()`_
        - For **json**: `json.loads()`_

        .. _`yaml.load()`: https://pyyaml.org/wiki/PyYAMLDocumentation
        .. _`json.loads()`: https://docs.python.org/2/library/json.html#json.loads

        However, note that not all arguments are supported. For example, when
        deserializing JSON, arguments like ``parse_float`` and ``parse_int``
        which accept a callable object cannot be handled in an SLS file.

        .. versionadded:: 2019.2.0

    For example, this state:

    .. code-block:: yaml

        /etc/dummy/package.json:
          file.serialize:
            - dataset:
                name: naive
                description: A package using naive versioning
                author: A confused individual <iam@confused.com>
                dependencies:
                  express: '>= 1.2.0'
                  optimist: '>= 0.1.0'
                engine: node 0.4.1
            - formatter: json

    will manage the file ``/etc/dummy/package.json``:

    .. code-block:: json

        {
          "author": "A confused individual <iam@confused.com>",
          "dependencies": {
            "express": ">= 1.2.0",
            "optimist": ">= 0.1.0"
          },
          "description": "A package using naive versioning",
          "engine": "node 0.4.1",
          "name": "naive"
        }
    uenvudefault_flow_styleuyaml.serializeiuindentu,u: u
separatorsu	sort_keysujson.serializeuyaml.deserializeujson.deserializeu
allow_unicodeuensure_asciiuchangesuucommentunameuresultu#Must provide name to file.serializeu3File {0} is not present and is not set for creationu	formatteruyamliu7Only one of 'dataset' and 'dataset_pillar' is permittedu
pillar.getu2Neither 'dataset' nor 'dataset_pillar' was defineduGThe group argument for %s has been ignored as this is a Windows system.u
{0}.serializeu{0}.deserializeu{0} format is not supportedu6merge_if_exists is not supported for the {0} formatteruru(Failed to deserialize existing data: {0}Nu$The file {0} is in the correct stateuwarningsuPThe 'deserializer_opts' option is ignored unless merge_if_exists is set to True.u
utestufile.check_managed_changesRAReR�RkR+R,R�RmR�R�RR[RpRyu.Dataset will be serialized and stored into {0}u<show_changes=False>udiffufile.manage_fileR�RR�RnR0RoR	RY(u,u: ($RZRRR*R4R8RLR�RR*RR�R)R5RRR�R�RHR�t__serializers__t
capitalizeR\Ratrepack_dictlistRRR|R�R	t
dictupdatet
merge_recurseR�R�RR_(RAtdatasettdataset_pillarR+R,R�RnR0RoRdtmerge_if_existsR	RYtserializer_optstdeserializer_optsRhtserializer_optionstdeserializer_optionsRt	formatterR{tserializer_nametdeserializer_nametfhrt
existing_dataR�tmerged_dataRp((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt	serialize�s�




1


	












u0600c
C@sntjj|�}i|d6id6dd6td6}|sGt|d�S|dkretd|�ryd	j|�|d<qjtd
|�s�tdr�dj|�|d<d|d<qbtd
|||||||�}qjtd|�\}}	||f||	fkr"dj|||	�|d<qjtd|d|||�d}|dsjdj|�|d<qjn|dkr�td|�r�dj|�|d<qjtd|�s�tdr�dj|�|d<d|d<q�td
|||||||�}qjtd|�\}}	||f||	fkr@dj|||	�|d<qjtd|d|||�d}|dsjdj|�|d<qjn�|dkrWtd|�r�dj|�|d<qjtd|�stdr�dj|�|d<d|d<qTtd
|||||||�}qjtd|d|||�d}|dsjdj|�|d<qjndj|�|d<|S( uu
    Create a special file similar to the 'nix mknod command. The supported
    device types are ``p`` (fifo pipe), ``c`` (character device), and ``b``
    (block device). Provide the major and minor numbers when specifying a
    character device or block device. A fifo pipe does not require this
    information. The command will create the necessary dirs if needed. If a
    file of the same name not of the same type/major/minor exists, it will not
    be overwritten or unlinked (deleted). This is logically in place as a
    safety measure because you can really shoot yourself in the foot here and
    it is the behavior of 'nix ``mknod``. It is also important to note that not
    just anyone can create special devices. Usually this is only done as root.
    If the state is executed as none other than root on a minion, you may
    receive a permission error.

    name
        name of the file

    ntype
        node type 'p' (fifo pipe), 'c' (character device), or 'b'
        (block device)

    major
        major number of the device
        does not apply to a fifo pipe

    minor
        minor number of the device
        does not apply to a fifo pipe

    user
        owning user of the device/pipe

    group
        owning group of the device/pipe

    mode
        permissions on the device/pipe

    Usage:

    .. code-block:: yaml

        /dev/chr:
          file.mknod:
            - ntype: c
            - major: 180
            - minor: 31
            - user: root
            - group: root
            - mode: 660

        /dev/blk:
          file.mknod:
            - ntype: b
            - major: 8
            - minor: 999
            - user: root
            - group: root
            - mode: 660

        /dev/fifo:
          file.mknod:
            - ntype: p
            - user: root
            - group: root
            - mode: 660

    .. versionadded:: 0.17.0
    unameuchangesuucommenturesultuMust provide name to file.mknoducufile.file_existsuCFile {0} exists and is not a character device. Refusing to continueufile.is_chrdevutestu)Character device {0} is set to be createdu
file.mknodufile.get_devmmuYCharacter device {0} exists and has a different major/minor {1}/{2}. Refusing to continueufile.check_permsiu,Character device {0} is in the correct stateubu?File {0} exists and is not a block device. Refusing to continueufile.is_blkdevu%Block device {0} is set to be createduUBlock device {0} exists and has a different major/minor {1}/{2}. Refusing to continueu(Block device {0} is in the correct stateupu<File {0} exists and is not a fifo pipe. Refusing to continueufile.is_fifou"Fifo pipe {0} is set to be createdu%Fifo pipe {0} is in the correct stateucNode type unavailable: '{0}'. Available node types are character ('c'), block ('b'), and pipe ('p')N(	RRR*R4R�R)R*RR5(
RAtntypetmajortminorR+R,R�Rtdevmajtdevmin((s4/usr/lib/python2.7/site-packages/salt/states/file.pytmknod
s�F






















cK@s�tjd�dj||�}td||�}|ddkr�idd6td6td	6}|jd
�r�|dcd|d
7<n|jd�r�|dcd|d7<n|StS(
u�
    Execute the check_cmd logic.

    Return a result dict if ``check_cmd`` succeeds (check_cmd == 0)
    otherwise return True
    urunning our check_cmdu{0} {1}ucmd.run_alluretcodeiucheck_cmd execution faileducommentu
skip_watchuresultustdoutu
ustderr(RHRIR*R)R8R4R|(tcmdRSR�t_cmdR�R((s4/usr/lib/python2.7/site-packages/salt/states/file.pyRj�s


ubase64umd5cC@s�i|d6id6td6dd6}|p+|s=td��nm|rX|rXtd��nR|rg|}nC|r�td|t�}|tkr�td	��q�ntd
��td|�}|rEtd|�}td
||�}	~td||�}
|	|
kr i|
d6|	d6|d<n|dsEd|d<t|d<|Sntdtkrmd|d<d|d<|Std||�|d<d|d<|ds�idd6td||�d6|d<n|S(u~
    Decode an encoded file and write it to disk

    .. versionadded:: 2016.3.0

    name
        Path of the file to be written.
    encoded_data
        The encoded file. Either this option or ``contents_pillar`` must be
        specified.
    contents_pillar
        A Pillar path to the encoded file. Uses the same path syntax as
        :py:func:`pillar.get <salt.modules.pillar.get>`. The
        :py:func:`hashutil.base64_encodefile
        <salt.modules.hashutil.base64_encodefile>` function can load encoded
        content into Pillar. Either this option or ``encoded_data`` must be
        specified.
    encoding_type : ``base64``
        The type of encoding.
    checksum : ``md5``
        The hashing algorithm to use to generate checksums. Wraps the
        :py:func:`hashutil.digest <salt.modules.hashutil.digest>` execution
        function.

    Usage:

    .. code-block:: yaml

        write_base64_encoded_string_to_a_file:
          file.decode:
            - name: /tmp/new_file
            - encoding_type: base64
            - contents_pillar: mypillar:thefile

        # or

        write_base64_encoded_string_to_a_file:
          file.decode:
            - name: /tmp/new_file
            - encoding_type: base64
            - encoded_data: |
                Z2V0IHNhbHRlZAo=

    Be careful with multi-line strings that the YAML indentation is correct.
    E.g.,

    .. code-block:: jinja

        write_base64_encoded_string_to_a_file:
          file.decode:
            - name: /tmp/new_file
            - encoding_type: base64
            - encoded_data: |
                {{ salt.pillar.get('path:to:data') | indent(8) }}
    unameuchangesuresultuucommentu@Specify either the 'encoded_data' or 'contents_pillar' argument.u>Specify only one 'encoded_data' or 'contents_pillar' argument.u
pillar.getuPillar data not found.uNo contents given.ufile.file_existsuhashutil.base64_decodestringuhashutil.digestuhashutil.digest_fileuoldunewuFile is in the correct state.utestuFile is set to be updated.uhashutil.base64_decodefileuFile was updated.N(R4RR)R8RR5(RAtencoded_dataRst
encoding_typetchecksumRR�tdest_existstinstrtinsumtoutsum((s4/usr/lib/python2.7/site-packages/salt/states/file.pyRb�sJ<"	






c

K@sut|
d|	�}	i|d6id6td6dd6}tjjj�sSt|d�S|sft|d�S|jd	�r�|jd
�r�t|d�Stj	j
tj	j|��}|jd	�r�tj	j
tj	j|��}n|rtj	j
tj	j|��}n|r/tj	j
tj	j|��}n|	d!krHt
d}	ntd
|	�swtd�}	|	swd}	qwng}td|	�}
|
dkr�|jdj|	��ntj	j|�s�|jdj|��n|rdj|�}t|�dkr|d7}nt||�St||||||||	�\}}}t
drt||d<||d<||d<|Stj	jtj	j|��s|r�ytd|d|	�Wqtk
r�}t|dj|j��SXqt|djtj	j|���Sntj	j|�s'tj	j|�rs|d!k	r(tj	j|�r|sat|dj|��Std|�tjd�ntj	jtj	j|��s|r�ytd|�Wqtk
r�}t|dj|j��SXqt|djtj	j|���Sntj||�tjd�qs|rZtd|�d|dd<tjd�qst|dj|��Sntjjj ��t!j"j#d �}Wd!QX|j$|�}|j%j&�|j&�kg}|d!k	r�|j|j'|k�n|d!k	r!|j|j(j&�|j&�k�n|d!k	rF|j|j)|k�n|d!k	rw|j|j*j&�|j&�k�ntd"|�r7t+|�s�tj,|�q7t-||	�r�d#j||	�|d<net.||	�r
d$j||	�|d<d%j|	�|dd&<n&t/|d<|dcd'j||	�7<|Sntj	j0|�sqyw||_%|d!k	rm||_'n|d!k	r�||_(n|d!k	r�||_)n|d!k	r�||_*n|j1�Wn@t2t3j4fk
r}t/|d<d(j|||�|d<|SXd)j||�|d<||dd*<t-||	�sqt.||	�snt/|d<|dcd+j|	�7<qnqqn|S(,u�
    Create a Windows shortcut

    If the file already exists and is a shortcut pointing to any location other
    than the specified target, the shortcut will be replaced. If it is
    a regular file or directory then the state will return False. If the
    regular file or directory is desired to be replaced with a shortcut pass
    force: True, if it is to be renamed, pass a backupname.

    name
        The location of the shortcut to create. Must end with either
        ".lnk" or ".url"

    target
        The location that the shortcut points to

    arguments
        Any arguments to pass in the shortcut

    working_dir
        Working directory in which to execute target

    description
        Description to set on shortcut

    icon_location
        Location of shortcut's icon

    force
        If the name of the shortcut exists and is not a file and
        force is set to False, the state will fail. If force is set to
        True, the link or directory in the way of the shortcut file
        will be deleted to make room for the shortcut, unless
        backupname is set, when it will be renamed

    backupname
        If the name of the shortcut exists and is not a file, it will be
        renamed to the backupname. If the backupname already
        exists and force is False, the state will fail. Otherwise, the
        backupname will be removed first.

    makedirs
        If the location of the shortcut does not already have a parent
        directory then the state will fail, setting makedirs to True will
        allow Salt to create the parent directory. Setting this to True will
        also create the parent for backupname if necessary.

    user
        The user to own the file, this defaults to the user salt is running as
        on the minion

        The default mode for new files and directories corresponds umask of salt
        process. For existing files and directories it's not enforced.
    R+unameuchangesuresultuucommentu'Shortcuts are only supported on Windowsu"Must provide name to file.shortcutu.lnku.urlu*Name must end with either ".lnk" or ".url"uuseru	user.infouuser.currentuSYSTEMufile.user_to_uiduUser {0} does not existu*Specified file {0} is not an absolute pathu. iu.utestRAuDrive {0} is not mappedu+Directory "{0}" for shortcut is not presentu1File exists where the backup target {0} should goufile.removeu,Directory does not exist for backup at "{0}"uShortcut was forcibly replaceduforcedu>Directory or symlink exists where the shortcut "{0}" should beu
WScript.ShellNufile.file_existsu(Shortcut {0} is present and owned by {1}u$Set ownership of shortcut {0} to {1}u{0}u	ownershipu.Failed to set ownership of shortcut {0} to {1}u-Unable to create new shortcut {0} -> {1}: {2}uCreated new shortcut {0} -> {1}unewu(, but was unable to set ownership to {0}(5R�R8RRR�R�R�R`RRtrealpathR*R5RR)R�R*R�RR�R&R{RcR(RR+RtR-ttimetsleepR�RRRRRRRRRRRRRRJRRR4R�tSaveR[t
pywintypest	com_error(RAR�RR R!R"R�R/R0R+RhRR1R.R�R3R4R5R�R#R$R%((s4/usr/lib/python2.7/site-packages/salt/states/file.pytshortcutosB



 
!!!







$

%

	

ubasecC@s-iid6dd6|d6td6}yt|�}Wntk
rPd|d<|SX|r�|r�|jtjjjkr�djtjj	j
|��|d<|S|ry)tdd	|d
|d|d|�}Wn!tk
r�}|j
|d<|SX|sd
j|�|d<|Sni}|jtjjjkr#tjjtjj|j��}	tjj|	�r	|r�|r�td|	|jdtd��}
|
|dkr�t|d<dj|	|
�|d<ndj|	|
|d�|d<|St|d<dj|	�|d<|Sq#dj|	�|d<|Sntd|d|�}|r�td||jdtd��}|r�|r�||dkr�t|d<dj||�|d<q�q�nd}d�}
|
||jd��r1y)td|d|d
|jd��}Wq1tk
r-}tjj	j
|j��|d<|SXn|s]djtjj	j
|��|d<|Std||jdtd��}||kr�i|d6|d6|dd<n|r|r||dkr�t|d<dj||�|d<ndj|||d�|d<|St|d<dj|�|d<|S( u�
    .. versionadded:: 2017.7.3

    Ensures that a file is saved to the minion's cache. This state is primarily
    invoked by other states to ensure that we do not re-download a source file
    if we do not need to.

    name
        The URL of the file to be cached. To cache a file from an environment
        other than ``base``, either use the ``saltenv`` argument or include the
        saltenv in the URL (e.g. ``salt://path/to/file.conf?saltenv=dev``).

        .. note::
            A list of URLs is not supported, this must be a single URL. If a
            local file is passed here, then the state will obviously not try to
            download anything, but it will compare a hash if one is specified.

    source_hash
        See the documentation for this same argument in the
        :py:func:`file.managed <salt.states.file.managed>` state.

        .. note::
            For remote files not originating from the ``salt://`` fileserver,
            such as http(s) or ftp servers, this state will not re-download the
            file if the locally-cached copy matches this hash. This is done to
            prevent unnecessary downloading on repeated runs of this state. To
            update the cached copy of a file, it is necessary to update this
            hash.

    source_hash_name
        See the documentation for this same argument in the
        :py:func:`file.managed <salt.states.file.managed>` state.

    skip_verify
        See the documentation for this same argument in the
        :py:func:`file.managed <salt.states.file.managed>` state.

        .. note::
            Setting this to ``True`` will result in a copy of the file being
            downloaded from a remote (http(s), ftp, etc.) source each time the
            state is run.

    saltenv
        Used to specify the environment from which to download a file from the
        Salt fileserver (i.e. those with ``salt://`` URL).


    This state will in most cases not be useful in SLS files, but it is useful
    when writing a state or remote-execution module that needs to make sure
    that a file at a given URL has been downloaded to the cachedir. One example
    of this is in the :py:func:`archive.extracted <salt.states.file.extracted>`
    state:

    .. code-block:: python

        result = __states__['file.cached'](source_match,
                                           source_hash=source_hash,
                                           source_hash_name=source_hash_name,
                                           skip_verify=skip_verify,
                                           saltenv=__env__)

    This will return a dictionary containing the state's return data, including
    a ``result`` key which will state whether or not the state was successful.
    Note that this will not catch exceptions, so it is best used within a
    try/except.

    Once this state has been run from within another state or remote-execution
    module, the actual location of the cached file can be obtained using
    :py:func:`cp.is_cached <salt.modules.cp.is_cached>`:

    .. code-block:: python

        cached = __salt__['cp.is_cached'](source_match, saltenv=__env__)

    This function will return the cached path of the file, or an empty string
    if the file is not present in the minion cache.
    uchangesuucommentunameuresultu-Only URLs or local file paths are valid inputudUnable to verify upstream hash of source file {0}, please set source_hash or set skip_verify to Trueufile.get_source_sumReR�RkR[u�Failed to get source hash from {0}. This may be a bug. If this error persists, please report it and set skip_verify to True to work around it.u
file.get_hashu	hash_typeuhsumu2File {0} is present on the minion and has hash {1}u]File {0} is present on the minion, but the hash ({1}) does not match the specified hash ({2})u!File {0} is present on the minionu%File {0} is not present on the minionucp.is_cachedu+File is already cached to {0} with hash {1}cS@s�|s|rtStjjjjt|��}|dkr@tSy#tjjj	|d|�|kSWnt
ttfk
r�tSXdS(u8
        This helper is not needed anymore in develop as the fileclient in the
        develop branch now has means of skipping a download if the existing
        hash matches one passed to cp.cache_file. Remove this helper and the
        code that invokes it, once we have merged forward into develop.
        tformN(
R8RRRt
HASHES_REVMAPR|R�R5RMRNRR�R�(RR~R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt
_try_cache0s#u
cp.cache_fileu:Failed to cache {0}, check minion log for more informationuoldunewuhashuQFile is cached to {0}, but the hash ({1}) does not match the specified hash ({2})uFile is cached to {0}N(R4RgR.RhRRRt
REMOTE_PROTOSR*R]R3R)RRbtLOCAL_PROTOSRRR�R*R�R|RR8R5t__str__(RAR�RkRyR[RtparsedR�R�RBt
local_hasht
local_copytpre_hashR�t	post_hash((s4/usr/lib/python2.7/site-packages/salt/states/file.pytcachedos�R







!






	


cC@sYiid6dd6|d6td6}yt|�}Wntk
rPd|d<|SX|jtjjjkr�tj	j
tj	j|j	��}t|d<dj
|�|d<|Std|d	|�}|r8ytj|�Wn/tk
r	}d
j
||j��|d<qUXt|d<t|dd<dj
|�|d<nt|d<d
j
|�|d<|S(u
    .. versionadded:: 2017.7.3

    Ensures that a file is saved to the minion's cache. This state is primarily
    invoked by other states to ensure that we do not re-download a source file
    if we do not need to.

    name
        The URL of the file to be cached. To cache a file from an environment
        other than ``base``, either use the ``saltenv`` argument or include the
        saltenv in the URL (e.g. ``salt://path/to/file.conf?saltenv=dev``).

        .. note::
            A list of URLs is not supported, this must be a single URL. If a
            local file is passed here, the state will take no action.

    saltenv
        Used to specify the environment from which to download a file from the
        Salt fileserver (i.e. those with ``salt://`` URL).
    uchangesuucommentunameuresultu-Only URLs or local file paths are valid inputu)File {0} is a local path, no action takenucp.is_cachedR[uFailed to delete {0}: {1}udeletedu{0} was deletedu{0} is not cached(R4RgR.RhRRRR�RRR�R*R8R*R)RJR�(RAR[RR�RBR�R�((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt
not_cached�s8



!



(�t__doc__t
__future__RRRR(RR�tloggingRR1R?ROR�R�RdtcollectionsRRRRRtsalt.loaderRtsalt.payloadtsalt.utils.datatsalt.utils.dateutilstsalt.utils.dictupdatetsalt.utils.filestsalt.utils.hashutilstsalt.utils.pathtsalt.utils.platformtsalt.utils.stringutilstsalt.utils.templatestsalt.utils.urltsalt.utils.versionstsalt.exceptionsRtsalt.serializersR	t
salt.stateR
RRR�R�tsalt.utils.win_dacltsalt.utils.win_functionstsalt.utils.winapitsalt.extRtsalt.ext.six.movesRtsalt.ext.six.moves.urllib.parseR
RgR�twin32com.clientRt	getLoggert__name__RHt
COMMENT_REGEXtobjectR]t__func_alias__RR#R(R0R5R<R?R4RvR�R�R�R�R�R�R�R�R�R�R�R�R�R�R�RR
RRRR&R(R6R7RSR�RTR8R�R�R�R�RxR�R�R�R>RR�RR�R&RKRRXR�R`RsRyRjRbR�R�R�(((s4/usr/lib/python2.7/site-packages/salt/states/file.pyt<module>s~	
	
		
		uK				W�					$8				>/�8	?w		����	��������nj��*��M�^	i�b�	p��

Zerion Mini Shell 1.0