Controlling files on a minion is a common operation that SaltStack does well. The basic principle is that if the file is changed on the minion, then a state run should return it back to a known State as dictated by the Salt Master. However, you can also use the file as a template and dynamically populate it with gains and state data from the master.
Example 1 – Basic managed file state.
In this example, we download one file and set its ownership and permissions. The “ID” field is the target, but we set the target name anyway with the “- name: “ key. It is also worth to note this is the old format which has been replaced with file.managed syntax:
/etc/modprobe.d/lustre.conf:
file:
- managed
- source: salt://roles/hpc/lnet/conf/lustre.conf
- name: /etc/modprobe.d/lustre.conf
- user: root
- group: root
- mode: 644
Example 2 – Multiple file downloads
In this example, we need to move a number of files in a directory from the Master to /opt/client/rpms on the minion, we can set the ownership but Salt will set the individual permissions based on the source file(s). We also use a variable from the pillar data, explained below:
upload-directory:
file.recurse:
- name: /opt/client/rpms
- source: salt://servers/{{ pillar['server_name'] }}/client/rpms/
- include_empty: True
- user: root
- group: root
- file_mode: keep
Pillar data – quick introduction
Its not often desirable to hardcode into a State file fixed value like a “server name”, instead we can store this data in an SLS file as YAML in the /srv/pillar directory and in the /srv/pillar/top.sls file reference ALL the pillar data to a host. There will be another post of Pillar data.
Example 3 – Templated file download
The following example state file uses a basic “for” loop to show how a block of code can be called repetitively to download files to a client. To avoid hard coding the list of files in the state file, a pillar could be used. The immediate disadvantage is the file ownership and perms, but we could use a more complex pillar structure to hold that information as well.
{% for FILE in [‘test1.rpm’,’test2.rpm’,’dev-test3.rpm’] %}
/opt/client/{{ FILE }}:
file.managed:
– source: salt://servers/{{ pillar[‘server_name’] }}/client/{{ FILE }}
– user: root
– group: root
– mode: ‘0664’
{% endfor %}
-oOo-