File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/states/__pycache__/file.cpython-310.pyc
o
�N�g�� � @ s" d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl
Z
ddlZddlZddl
Z
ddlZddlmZ ddlmZmZ ddlmZmZ ddlmZ ddlZddlZddlZddlZddlZddlZddlZddl Zddl!Zddl"Zddl#Zddl$Zddl%Zddl&Zddl'm(Z( ddl)m*Z* dd l+m,Z- dd
l.m/Z/ ej0j1�2� r�ddl3Zddl4Zddl5Zej0j1�2� r�ddl6Z6ddl7Z8e�9e:�Z;dZ<e=� Z>dd
iZ?dd� Z@dd� ZAdd� ZBdd� ZCdd� ZDd�dd�ZEdd� ZF d�dd�ZGd�dd �ZHd!d"� ZId#d$� ZJd%d&� ZKd'd(� ZL d�d)d*�ZM d�d+d,�ZNd�d-d.�ZOd/d0� ZPd1d2� ZQd3d4� ZRd5d6� ZSd7d8� ZTd9d:� ZUd;d<� ZVd�d=d>�ZW d�d?d@�ZX d�dBdC�ZYd�dDdE�ZZdFdG� Z[dHdI� Z\dJdK� Z]dLdM� Z^ d�dNdO�Z_ d�dPdQ�Z` d�dRdS�ZadTdU� Zb V W Xd�dYdZ�Zcd[d\� Zdd]d^� Ze _ X X _ X X _ _ X ` a X X X X d�dbdc�Zfg dd�Zgdedf� Zhd�dgdh�Zi X X d�didj�Zj X X _ Xd�dkdl�Zkd�dmdn�Zl X X d�dodp�Zm q r s X d�dtdu�Zn v X r d�dwdx�Zo y z A _ s X d�d{d|�Zpd�d~d�Zqd�d�d��Zr A Xd�d�d��Zs A d�d�d��Zt _ d�d�d��Zud�d�d��Zv d�d�d�Zwd�d�d��Zxd�d�� Zy _ X X a d�d�d��Zzd�d�d��Z{d�d�� Z| � �d�d�d��Z} d�d�d��Z~ _ � d�d�d��Zd�d�d��Z�d�d�� Z�d�d�d��Z�dS )�a�!
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
� N��defaultdict)�Iterable�Mapping)�date�datetime)�zip_longest)�CommandExecutionError)�DeserializationError)�get_accumulator_dir)�OrderedDictz^([[:space:]]*){0}[[:space:]]?�copy_�copyc C s* t | t�r| �� �d�S tdd� | D ��S )z;
Check if source or sources is http, https or ftp.
�zhttp:zhttps:zftp:c S s g | ] }|� � �d ��qS )r )�lower�
startswith)�.0�s� r �D/opt/saltstack/salt/lib/python3.10/site-packages/salt/states/file.py�
<listcomp>W s z#_http_ftp_check.<locals>.<listcomp>)�
isinstance�strr r �any)�sourcer r r �_http_ftp_checkQ s
r c C s t j�ttd �t�S )z'
Return accumulator data path.
Zcachedir)�os�path�join�_get_accumulator_dir�__opts__Z__instance_id__r r r r �_get_accumulator_filepathZ s r! c C s"