golden hour
/opt/saltstack/salt/lib/python3.10/site-packages/salt/states
⬆️ Go Up
Upload
File/Folder
Size
Actions
__init__.py
25 B
Del
OK
__pycache__
-
Del
OK
acme.py
5.08 KB
Del
OK
alias.py
2.49 KB
Del
OK
alternatives.py
6.75 KB
Del
OK
ansiblegate.py
7.93 KB
Del
OK
apache.py
3.95 KB
Del
OK
apache_conf.py
2.72 KB
Del
OK
apache_module.py
2.73 KB
Del
OK
apache_site.py
2.66 KB
Del
OK
aptpkg.py
1.42 KB
Del
OK
archive.py
68.24 KB
Del
OK
artifactory.py
6.84 KB
Del
OK
at.py
7.48 KB
Del
OK
augeas.py
10.57 KB
Del
OK
aws_sqs.py
2.59 KB
Del
OK
azurearm_compute.py
11.78 KB
Del
OK
azurearm_dns.py
26.05 KB
Del
OK
azurearm_network.py
89.12 KB
Del
OK
azurearm_resource.py
28.23 KB
Del
OK
beacon.py
7.58 KB
Del
OK
bigip.py
96.63 KB
Del
OK
blockdev.py
5.13 KB
Del
OK
boto3_elasticache.py
48.01 KB
Del
OK
boto3_elasticsearch.py
32.58 KB
Del
OK
boto3_route53.py
37.54 KB
Del
OK
boto3_sns.py
12.69 KB
Del
OK
boto_apigateway.py
82.83 KB
Del
OK
boto_asg.py
31.93 KB
Del
OK
boto_cfn.py
11.53 KB
Del
OK
boto_cloudfront.py
6.01 KB
Del
OK
boto_cloudtrail.py
13.18 KB
Del
OK
boto_cloudwatch_alarm.py
6.4 KB
Del
OK
boto_cloudwatch_event.py
12.33 KB
Del
OK
boto_cognitoidentity.py
13.69 KB
Del
OK
boto_datapipeline.py
18.5 KB
Del
OK
boto_dynamodb.py
29.32 KB
Del
OK
boto_ec2.py
71.98 KB
Del
OK
boto_elasticache.py
16.75 KB
Del
OK
boto_elasticsearch_domain.py
12.27 KB
Del
OK
boto_elb.py
55.1 KB
Del
OK
boto_elbv2.py
12.19 KB
Del
OK
boto_iam.py
69.16 KB
Del
OK
boto_iam_role.py
27.12 KB
Del
OK
boto_iot.py
25.33 KB
Del
OK
boto_kinesis.py
16.69 KB
Del
OK
boto_kms.py
12.11 KB
Del
OK
boto_lambda.py
35.52 KB
Del
OK
boto_lc.py
11.04 KB
Del
OK
boto_rds.py
26 KB
Del
OK
boto_route53.py
19.49 KB
Del
OK
boto_s3.py
9.32 KB
Del
OK
boto_s3_bucket.py
24.67 KB
Del
OK
boto_secgroup.py
32.62 KB
Del
OK
boto_sns.py
8.92 KB
Del
OK
boto_sqs.py
7.97 KB
Del
OK
boto_vpc.py
62.23 KB
Del
OK
bower.py
8.26 KB
Del
OK
btrfs.py
10.34 KB
Del
OK
cabal.py
5.73 KB
Del
OK
ceph.py
1.9 KB
Del
OK
chef.py
3.76 KB
Del
OK
chocolatey.py
16.15 KB
Del
OK
chronos_job.py
4.6 KB
Del
OK
cimc.py
14.32 KB
Del
OK
cisconso.py
3.14 KB
Del
OK
cloud.py
14.4 KB
Del
OK
cmd.py
40.92 KB
Del
OK
composer.py
8.38 KB
Del
OK
consul.py
5.4 KB
Del
OK
cron.py
23.39 KB
Del
OK
cryptdev.py
6.17 KB
Del
OK
csf.py
9.98 KB
Del
OK
cyg.py
7.05 KB
Del
OK
ddns.py
4.2 KB
Del
OK
debconfmod.py
6.33 KB
Del
OK
dellchassis.py
24.49 KB
Del
OK
disk.py
6.49 KB
Del
OK
docker_container.py
85.27 KB
Del
OK
docker_image.py
16.7 KB
Del
OK
docker_network.py
36.78 KB
Del
OK
docker_volume.py
6.72 KB
Del
OK
drac.py
4.17 KB
Del
OK
dvs.py
26.29 KB
Del
OK
elasticsearch.py
20.38 KB
Del
OK
elasticsearch_index.py
3.25 KB
Del
OK
elasticsearch_index_template.py
3.67 KB
Del
OK
environ.py
5.81 KB
Del
OK
eselect.py
2.27 KB
Del
OK
esxcluster.py
22.4 KB
Del
OK
esxdatacenter.py
4.44 KB
Del
OK
esxi.py
63.07 KB
Del
OK
esxvm.py
20.11 KB
Del
OK
etcd_mod.py
11 KB
Del
OK
ethtool.py
9.88 KB
Del
OK
event.py
2.48 KB
Del
OK
file.py
316.7 KB
Del
OK
firewall.py
1.33 KB
Del
OK
firewalld.py
26.08 KB
Del
OK
gem.py
7.13 KB
Del
OK
git.py
123.85 KB
Del
OK
github.py
27.25 KB
Del
OK
glance_image.py
2.26 KB
Del
OK
glassfish.py
21.47 KB
Del
OK
glusterfs.py
12.21 KB
Del
OK
gnomedesktop.py
7.47 KB
Del
OK
gpg.py
5.28 KB
Del
OK
grafana.py
12.11 KB
Del
OK
grafana4_dashboard.py
17.31 KB
Del
OK
grafana4_datasource.py
6.15 KB
Del
OK
grafana4_org.py
7.73 KB
Del
OK
grafana4_user.py
5.52 KB
Del
OK
grafana_dashboard.py
17.74 KB
Del
OK
grafana_datasource.py
5.31 KB
Del
OK
grains.py
15.57 KB
Del
OK
group.py
9.84 KB
Del
OK
heat.py
9.69 KB
Del
OK
helm.py
10.39 KB
Del
OK
hg.py
6.33 KB
Del
OK
highstate_doc.py
1.41 KB
Del
OK
host.py
8.64 KB
Del
OK
http.py
7.46 KB
Del
OK
icinga2.py
9.07 KB
Del
OK
idem.py
3.91 KB
Del
OK
ifttt.py
2.12 KB
Del
OK
incron.py
5.71 KB
Del
OK
influxdb08_database.py
2.85 KB
Del
OK
influxdb08_user.py
3.39 KB
Del
OK
influxdb_continuous_query.py
2.83 KB
Del
OK
influxdb_database.py
2.11 KB
Del
OK
influxdb_retention_policy.py
4.82 KB
Del
OK
influxdb_user.py
4.84 KB
Del
OK
infoblox_a.py
4.24 KB
Del
OK
infoblox_cname.py
4.19 KB
Del
OK
infoblox_host_record.py
6.59 KB
Del
OK
infoblox_range.py
6.85 KB
Del
OK
ini_manage.py
12.67 KB
Del
OK
ipmi.py
8.42 KB
Del
OK
ipset.py
9.66 KB
Del
OK
iptables.py
27.65 KB
Del
OK
jboss7.py
23.95 KB
Del
OK
jenkins.py
3.36 KB
Del
OK
junos.py
17.78 KB
Del
OK
kapacitor.py
6.46 KB
Del
OK
kernelpkg.py
6.42 KB
Del
OK
keyboard.py
2.01 KB
Del
OK
keystone.py
27.12 KB
Del
OK
keystone_domain.py
2.81 KB
Del
OK
keystone_endpoint.py
4.69 KB
Del
OK
keystone_group.py
3.25 KB
Del
OK
keystone_project.py
3.36 KB
Del
OK
keystone_role.py
2.33 KB
Del
OK
keystone_role_grant.py
4.08 KB
Del
OK
keystone_service.py
2.89 KB
Del
OK
keystone_user.py
3.47 KB
Del
OK
keystore.py
5.67 KB
Del
OK
kmod.py
8.59 KB
Del
OK
kubernetes.py
24.87 KB
Del
OK
layman.py
2.44 KB
Del
OK
ldap.py
19.78 KB
Del
OK
libcloud_dns.py
5.7 KB
Del
OK
libcloud_loadbalancer.py
5.66 KB
Del
OK
libcloud_storage.py
5.13 KB
Del
OK
linux_acl.py
24.42 KB
Del
OK
locale.py
2.52 KB
Del
OK
logadm.py
4.67 KB
Del
OK
logrotate.py
3.86 KB
Del
OK
loop.py
7.74 KB
Del
OK
lvm.py
13.33 KB
Del
OK
lvs_server.py
6.28 KB
Del
OK
lvs_service.py
4.38 KB
Del
OK
lxc.py
22.17 KB
Del
OK
lxd.py
7.88 KB
Del
OK
lxd_container.py
22.25 KB
Del
OK
lxd_image.py
10.59 KB
Del
OK
lxd_profile.py
7.11 KB
Del
OK
mac_assistive.py
1.55 KB
Del
OK
mac_keychain.py
5.59 KB
Del
OK
mac_xattr.py
3.15 KB
Del
OK
macdefaults.py
2.65 KB
Del
OK
macpackage.py
6.76 KB
Del
OK
makeconf.py
6.87 KB
Del
OK
marathon_app.py
4.45 KB
Del
OK
mdadm_raid.py
6.41 KB
Del
OK
memcached.py
3.95 KB
Del
OK
modjk.py
2.84 KB
Del
OK
modjk_worker.py
6.49 KB
Del
OK
module.py
18.64 KB
Del
OK
mongodb_database.py
1.65 KB
Del
OK
mongodb_user.py
6.26 KB
Del
OK
monit.py
2.68 KB
Del
OK
mount.py
50.32 KB
Del
OK
mssql_database.py
3 KB
Del
OK
mssql_login.py
3.64 KB
Del
OK
mssql_role.py
2.37 KB
Del
OK
mssql_user.py
3.51 KB
Del
OK
msteams.py
2.53 KB
Del
OK
mysql_database.py
6.05 KB
Del
OK
mysql_grants.py
8.49 KB
Del
OK
mysql_query.py
13.07 KB
Del
OK
mysql_user.py
9.51 KB
Del
OK
net_napalm_yang.py
9.15 KB
Del
OK
netacl.py
31.92 KB
Del
OK
netconfig.py
33.42 KB
Del
OK
netntp.py
12.51 KB
Del
OK
netsnmp.py
11.33 KB
Del
OK
netusers.py
16.1 KB
Del
OK
network.py
23.97 KB
Del
OK
neutron_network.py
3.96 KB
Del
OK
neutron_secgroup.py
4 KB
Del
OK
neutron_secgroup_rule.py
4.75 KB
Del
OK
neutron_subnet.py
4.29 KB
Del
OK
nexus.py
4.97 KB
Del
OK
nfs_export.py
4.92 KB
Del
OK
nftables.py
19.5 KB
Del
OK
npm.py
11.21 KB
Del
OK
ntp.py
2.12 KB
Del
OK
nxos.py
10.37 KB
Del
OK
nxos_upgrade.py
3.5 KB
Del
OK
openstack_config.py
3.26 KB
Del
OK
openvswitch_bridge.py
4.36 KB
Del
OK
openvswitch_db.py
2.24 KB
Del
OK
openvswitch_port.py
17.24 KB
Del
OK
opsgenie.py
4.07 KB
Del
OK
pagerduty.py
1.89 KB
Del
OK
pagerduty_escalation_policy.py
5.42 KB
Del
OK
pagerduty_schedule.py
6.09 KB
Del
OK
pagerduty_service.py
3.93 KB
Del
OK
pagerduty_user.py
1.18 KB
Del
OK
panos.py
48.13 KB
Del
OK
pbm.py
20.46 KB
Del
OK
pcs.py
36.46 KB
Del
OK
pdbedit.py
3.43 KB
Del
OK
pecl.py
3.65 KB
Del
OK
pip_state.py
38.55 KB
Del
OK
pkg.py
138.08 KB
Del
OK
pkgbuild.py
11.37 KB
Del
OK
pkgng.py
685 B
Del
OK
pkgrepo.py
27.53 KB
Del
OK
portage_config.py
5.01 KB
Del
OK
ports.py
5.65 KB
Del
OK
postgres_cluster.py
4.19 KB
Del
OK
postgres_database.py
6.08 KB
Del
OK
postgres_extension.py
5.68 KB
Del
OK
postgres_group.py
8.52 KB
Del
OK
postgres_initdb.py
2.84 KB
Del
OK
postgres_language.py
3.94 KB
Del
OK
postgres_privileges.py
7.86 KB
Del
OK
postgres_schema.py
4.34 KB
Del
OK
postgres_tablespace.py
6.62 KB
Del
OK
postgres_user.py
9.49 KB
Del
OK
powerpath.py
2.34 KB
Del
OK
probes.py
15.06 KB
Del
OK
process.py
1.32 KB
Del
OK
proxy.py
4.94 KB
Del
OK
pushover.py
3.13 KB
Del
OK
pyenv.py
6.07 KB
Del
OK
pyrax_queues.py
2.97 KB
Del
OK
quota.py
1.4 KB
Del
OK
rabbitmq_cluster.py
1.84 KB
Del
OK
rabbitmq_plugin.py
2.77 KB
Del
OK
rabbitmq_policy.py
4.59 KB
Del
OK
rabbitmq_upstream.py
7.9 KB
Del
OK
rabbitmq_user.py
8.89 KB
Del
OK
rabbitmq_vhost.py
3.04 KB
Del
OK
rbac_solaris.py
6.67 KB
Del
OK
rbenv.py
7.36 KB
Del
OK
rdp.py
1.28 KB
Del
OK
redismod.py
4.76 KB
Del
OK
reg.py
19.22 KB
Del
OK
restconf.py
6.41 KB
Del
OK
rsync.py
4.45 KB
Del
OK
rvm.py
6.56 KB
Del
OK
salt_proxy.py
1.34 KB
Del
OK
saltmod.py
33.12 KB
Del
OK
saltutil.py
8.91 KB
Del
OK
schedule.py
12.47 KB
Del
OK
selinux.py
18.61 KB
Del
OK
serverdensity_device.py
6.41 KB
Del
OK
service.py
37.89 KB
Del
OK
slack.py
4.98 KB
Del
OK
smartos.py
44.83 KB
Del
OK
smtp.py
2.3 KB
Del
OK
snapper.py
7.24 KB
Del
OK
solrcloud.py
4.48 KB
Del
OK
splunk.py
4.32 KB
Del
OK
splunk_search.py
3.17 KB
Del
OK
sqlite3.py
14.7 KB
Del
OK
ssh_auth.py
19.57 KB
Del
OK
ssh_known_hosts.py
7.92 KB
Del
OK
stateconf.py
494 B
Del
OK
status.py
2.21 KB
Del
OK
statuspage.py
17.29 KB
Del
OK
supervisord.py
10.48 KB
Del
OK
svn.py
8.14 KB
Del
OK
sysctl.py
4.11 KB
Del
OK
sysfs.py
2.13 KB
Del
OK
syslog_ng.py
2.97 KB
Del
OK
sysrc.py
2.82 KB
Del
OK
telemetry_alert.py
7.04 KB
Del
OK
test.py
13.09 KB
Del
OK
testinframod.py
1.35 KB
Del
OK
timezone.py
3.42 KB
Del
OK
tls.py
1.81 KB
Del
OK
tomcat.py
9.72 KB
Del
OK
trafficserver.py
8.82 KB
Del
OK
tuned.py
3.32 KB
Del
OK
uptime.py
1.87 KB
Del
OK
user.py
38.63 KB
Del
OK
vagrant.py
11.4 KB
Del
OK
vault.py
3.28 KB
Del
OK
vbox_guest.py
4.05 KB
Del
OK
victorops.py
3.32 KB
Del
OK
virt.py
80.41 KB
Del
OK
virtualenv_mod.py
11.21 KB
Del
OK
webutil.py
3.89 KB
Del
OK
win_certutil.py
4.8 KB
Del
OK
win_dacl.py
7.96 KB
Del
OK
win_dism.py
14.97 KB
Del
OK
win_dns_client.py
8.32 KB
Del
OK
win_firewall.py
6.87 KB
Del
OK
win_iis.py
31.56 KB
Del
OK
win_lgpo.py
24.99 KB
Del
OK
win_lgpo_reg.py
10.96 KB
Del
OK
win_license.py
1.6 KB
Del
OK
win_network.py
14.18 KB
Del
OK
win_path.py
6.39 KB
Del
OK
win_pki.py
5.56 KB
Del
OK
win_powercfg.py
3.79 KB
Del
OK
win_servermanager.py
10.4 KB
Del
OK
win_shortcut.py
7.81 KB
Del
OK
win_smtp_server.py
10.01 KB
Del
OK
win_snmp.py
6.64 KB
Del
OK
win_system.py
13.78 KB
Del
OK
win_wua.py
16.27 KB
Del
OK
win_wusa.py
3.53 KB
Del
OK
winrepo.py
2.74 KB
Del
OK
wordpress.py
4.82 KB
Del
OK
x509.py
27.86 KB
Del
OK
x509_v2.py
64.78 KB
Del
OK
xml.py
1.75 KB
Del
OK
xmpp.py
2.61 KB
Del
OK
zabbix_action.py
9.35 KB
Del
OK
zabbix_host.py
27.25 KB
Del
OK
zabbix_hostgroup.py
5.64 KB
Del
OK
zabbix_mediatype.py
16.89 KB
Del
OK
zabbix_template.py
35.14 KB
Del
OK
zabbix_user.py
17.6 KB
Del
OK
zabbix_usergroup.py
9.64 KB
Del
OK
zabbix_usermacro.py
9.69 KB
Del
OK
zabbix_valuemap.py
8.11 KB
Del
OK
zcbuildout.py
5.16 KB
Del
OK
zenoss.py
2.89 KB
Del
OK
zfs.py
34.48 KB
Del
OK
zk_concurrency.py
5.81 KB
Del
OK
zone.py
46.48 KB
Del
OK
zookeeper.py
11.55 KB
Del
OK
zpool.py
13.4 KB
Del
OK
Edit: mount.py
""" Mounting of filesystems ======================= Mount any type of mountable filesystem with the mounted function: .. code-block:: yaml /mnt/sdb: mount.mounted: - device: /dev/sdb1 - fstype: ext4 - mkmnt: True - opts: - defaults /srv/bigdata: mount.mounted: - device: UUID=066e0200-2867-4ebe-b9e6-f30026ca2314 - fstype: xfs - opts: nobootwait,noatime,nodiratime,nobarrier,logbufs=8 - dump: 0 - pass_num: 2 - persist: True - mkmnt: True /var/lib/bigdata: mount.mounted: - device: /srv/bigdata - fstype: none - opts: bind - dump: 0 - pass_num: 0 - persist: True - mkmnt: True """ import logging import os.path import re log = logging.getLogger(__name__) def _size_convert(_re_size): converted_size = int(_re_size.group("size_value")) if _re_size.group("size_unit") == "m": converted_size = int(converted_size) * 1024 if _re_size.group("size_unit") == "g": converted_size = int(converted_size) * 1024 * 1024 return converted_size def mounted( name, device, fstype, mkmnt=False, opts="defaults", dump=0, pass_num=0, config="/etc/fstab", persist=True, mount=True, user=None, match_on="auto", device_name_regex=None, extra_mount_invisible_options=None, extra_mount_invisible_keys=None, extra_mount_ignore_fs_keys=None, extra_mount_translate_options=None, hidden_opts=None, bind_mount_copy_active_opts=True, **kwargs ): """ Verify that a device is mounted name The path to the location where the device is to be mounted device The device name, typically the device node, such as ``/dev/sdb1`` or ``UUID=066e0200-2867-4ebe-b9e6-f30026ca2314`` or ``LABEL=DATA`` fstype The filesystem type, this will be ``xfs``, ``ext2/3/4`` in the case of classic filesystems, ``fuse`` in the case of fuse mounts, and ``nfs`` in the case of nfs mounts mkmnt If the mount point is not present then the state will fail, set ``mkmnt: True`` to create the mount point if it is otherwise not present opts A list object of options or a comma delimited list dump The dump value to be passed into the fstab, Default is ``0`` pass_num The pass value to be passed into the fstab, Default is ``0`` config Set an alternative location for the fstab, Default is ``/etc/fstab`` persist Set if the mount should be saved in the fstab, Default is ``True`` mount Set if the mount should be mounted immediately, Default is ``True`` user The account used to execute the mount; this defaults to the user salt is running as on the minion match_on A name or list of fstab properties on which this state should be applied. Default is ``auto``, a special value indicating to guess based on fstype. In general, ``auto`` matches on name for recognized special devices and device otherwise. device_name_regex A list of device exact names or regular expressions which should not force a remount. For example, glusterfs may be mounted with a comma-separated list of servers in fstab, but the /proc/self/mountinfo will show only the first available server. .. code-block:: jinja {% set glusterfs_ip_list = ['10.0.0.1', '10.0.0.2', '10.0.0.3'] %} mount glusterfs volume: mount.mounted: - name: /mnt/glusterfs_mount_point - device: {{ glusterfs_ip_list|join(',') }}:/volume_name - fstype: glusterfs - opts: _netdev,rw,defaults,direct-io-mode=disable - mkmnt: True - persist: True - dump: 0 - pass_num: 0 - device_name_regex: - ({{ glusterfs_ip_list|join('|') }}):/volume_name .. versionadded:: 2016.11.0 extra_mount_invisible_options A list of extra options that are not visible through the ``/proc/self/mountinfo`` interface. If a option is not visible through this interface it will always remount the device. This option extends the builtin ``mount_invisible_options`` list. extra_mount_invisible_keys A list of extra key options that are not visible through the ``/proc/self/mountinfo`` interface. If a key option is not visible through this interface it will always remount the device. This option extends the builtin ``mount_invisible_keys`` list. A good example for a key option is the password option:: password=badsecret extra_mount_ignore_fs_keys A dict of filesystem options which should not force a remount. This will update the internal dictionary. The dict should look like this:: { 'ramfs': ['size'] } extra_mount_translate_options A dict of mount options that gets translated when mounted. To prevent a remount add additional options to the default dictionary. This will update the internal dictionary. The dictionary should look like this:: { 'tcp': 'proto=tcp', 'udp': 'proto=udp' } hidden_opts A list of mount options that will be ignored when considering a remount as part of the state application .. versionadded:: 2015.8.2 bind_mount_copy_active_opts If set to ``False``, this option disables the default behavior of copying the options from the bind mount if it was found to be active. .. versionadded:: 3006.0 """ ret = {"name": name, "changes": {}, "result": True, "comment": ""} update_mount_cache = False if not name: ret["result"] = False ret["comment"] = "Must provide name to mount.mounted" return ret if not device: ret["result"] = False ret["comment"] = "Must provide device to mount.mounted" return ret if not fstype: ret["result"] = False ret["comment"] = "Must provide fstype to mount.mounted" return ret if device_name_regex is None: device_name_regex = [] # Defaults is not a valid option on Mac OS if __grains__["os"] in ["MacOS", "Darwin"] and opts == "defaults": opts = "noowners" # Defaults is not a valid option on AIX if __grains__["os"] in ["AIX"]: if opts == "defaults": opts = "" # Make sure that opts is correct, it can be a list or a comma delimited # string if isinstance(opts, str): opts = opts.split(",") if isinstance(hidden_opts, str): hidden_opts = hidden_opts.split(",") # remove possible trailing slash if not name == "/": name = name.rstrip("/") device_list = [] # Get the active data active = __salt__["mount.active"](extended=True) real_name = os.path.realpath(name) # real_name for comparisons to the active mount list comp_real_name = real_name.replace(" ", "\\040") if device.startswith("/"): if "bind" in opts and comp_real_name in active: _device = device.replace(" ", "\\040") if active[comp_real_name]["device"].startswith("/"): # Find the device that the bind really points at. while True: if _device in active: _real_device = active[_device]["device"] if bind_mount_copy_active_opts: opts = sorted( set( opts + active[_device]["opts"] + active[_device]["superopts"] ) ) active[comp_real_name]["opts"].append("bind") break _device = os.path.dirname(_device.replace("\\040", " ")) real_device = _real_device else: # Remote file systems act differently. if _device in active: if bind_mount_copy_active_opts: opts = sorted( set( opts + active[_device]["opts"] + active[_device]["superopts"] ) ) active[comp_real_name]["opts"].append("bind") real_device = active[comp_real_name]["device"] else: real_device = os.path.realpath(device) elif device.upper().startswith("UUID="): real_device = device.split("=")[1].strip('"').lower() elif device.upper().startswith("LABEL="): _label = device.split("=")[1] cmd = "blkid -t LABEL={}".format(_label) res = __salt__["cmd.run_all"]("{}".format(cmd)) if res["retcode"] > 0: ret["comment"] = "Unable to find device with label {}.".format(_label) ret["result"] = False return ret else: # output is a list of entries like this: # /dev/sda: LABEL="<label>" UUID="<uuid>" UUID_SUB="<uuid>" TYPE="btrfs" # exact list of properties varies between filesystems, but we're # only interested in the device in the first column for line in res["stdout"]: dev_with_label = line.split(":")[0] device_list.append(dev_with_label) real_device = device_list[0] else: real_device = device # LVS devices have 2 names under /dev: # /dev/mapper/vg--name-lv--name and /dev/vg-name/lv-name # No matter what name is used for mounting, # mount always displays the device as /dev/mapper/vg--name-lv--name # Note the double-dash escaping. # So, let's call that the canonical device name # We should normalize names of the /dev/vg-name/lv-name type to the canonical name lvs_match = re.match(r"^/dev/(?P<vg_name>[^/]+)/(?P<lv_name>[^/]+$)", device) if lvs_match: double_dash_escaped = { k: re.sub(r"-", "--", v) for k, v in lvs_match.groupdict().items() } mapper_device = "/dev/mapper/{vg_name}-{lv_name}".format(**double_dash_escaped) if os.path.exists(mapper_device): real_device = mapper_device # When included in a Salt state file, FUSE devices are prefaced by the # filesystem type and a hash, e.g. sshfs. In the mount list only the # hostname is included. So if we detect that the device is a FUSE device # then we remove the prefaced string so that the device in state matches # the device in the mount list. fuse_match = re.match(r"^\w+\#(?P<device_name>.+)", device) if fuse_match: if "device_name" in fuse_match.groupdict(): real_device = fuse_match.group("device_name") if comp_real_name in active: if "superopts" not in active[comp_real_name]: active[comp_real_name]["superopts"] = [] if mount: device_list.append(active[comp_real_name]["device"]) device_list.append(os.path.realpath(device_list[0])) alt_device = ( active[comp_real_name]["alt_device"] if "alt_device" in active[comp_real_name] else None ) uuid_device = ( active[comp_real_name]["device_uuid"] if "device_uuid" in active[comp_real_name] else None ) label_device = ( active[comp_real_name]["device_label"] if "device_label" in active[comp_real_name] else None ) if alt_device and alt_device not in device_list: device_list.append(alt_device) if uuid_device and uuid_device not in device_list: device_list.append(uuid_device) if label_device and label_device not in device_list: device_list.append(label_device) if opts: mount_invisible_options = [ "_netdev", "actimeo", "bg", "comment", "defaults", "delay_connect", "direct-io-mode", "intr", "loop", "nointr", "nobootwait", "nofail", "password", "reconnect", "retry", "soft", "auto", "users", "bind", "nonempty", "transform_symlinks", "port", "backup-volfile-servers", ] if extra_mount_invisible_options: mount_invisible_options.extend(extra_mount_invisible_options) if hidden_opts: mount_invisible_options = list( set(mount_invisible_options) | set(hidden_opts) ) # options which are provided as key=value (e.g. password=Zohp5ohb) mount_invisible_keys = [ "actimeo", "comment", "credentials", "direct-io-mode", "password", "port", "retry", "secretfile", ] if extra_mount_invisible_keys: mount_invisible_keys.extend(extra_mount_invisible_keys) # Some filesystems have options which should not force a remount. mount_ignore_fs_keys = {"ramfs": ["size"]} if extra_mount_ignore_fs_keys: mount_ignore_fs_keys.update(extra_mount_ignore_fs_keys) # Some options are translated once mounted mount_translate_options = { "tcp": "proto=tcp", "udp": "proto=udp", } if extra_mount_translate_options: mount_translate_options.update(extra_mount_translate_options) trigger_remount = [] for opt in opts: if opt in mount_translate_options: opt = mount_translate_options[opt] keyval_option = opt.split("=")[0] if keyval_option in mount_invisible_keys: opt = keyval_option size_match = re.match( r"size=(?P<size_value>[0-9]+)(?P<size_unit>k|m|g)", opt ) if size_match: converted_size = _size_convert(size_match) opt = "size={}k".format(converted_size) # make cifs option user synonym for option username which is reported by /proc/mounts if fstype in ["cifs"] and opt.split("=")[0] == "user": opt = "username={}".format(opt.split("=")[1]) if opt.split("=")[0] in mount_ignore_fs_keys.get(fstype, []): opt = opt.split("=")[0] # convert uid/gid to numeric value from user/group name name_id_opts = {"uid": "user.info", "gid": "group.info"} if opt.split("=")[0] in name_id_opts and len(opt.split("=")) > 1: _givenid = opt.split("=")[1] _param = opt.split("=")[0] _id = _givenid if not re.match("[0-9]+$", _givenid): _info = __salt__[name_id_opts[_param]](_givenid) if _info and _param in _info: _id = _info[_param] opt = _param + "=" + str(_id) _active_superopts = active[comp_real_name].get("superopts", []) for _active_opt in _active_superopts: size_match = re.match( r"size=(?P<size_value>[0-9]+)(?P<size_unit>k|m|g)", _active_opt, ) if size_match: converted_size = _size_convert(size_match) opt = "size={}k".format(converted_size) _active_superopts.remove(_active_opt) _active_opt = "size={}k".format(converted_size) _active_superopts.append(_active_opt) if ( opt not in active[comp_real_name]["opts"] and opt not in _active_superopts and opt not in mount_invisible_options and opt not in mount_ignore_fs_keys.get(fstype, []) and opt not in mount_invisible_keys ): trigger_remount.append(opt) if trigger_remount: if __opts__["test"]: ret["result"] = None ret[ "comment" ] = "Remount would be forced because options ({}) changed".format( ",".join(sorted(trigger_remount)) ) return ret else: # Some file systems require umounting and mounting if options change # add others to list that require similiar functionality if fstype in ["nfs", "cvfs"] or fstype.startswith("fuse"): ret["changes"]["umount"] = ( "Forced unmount and mount because " + "options ({}) changed".format( ",".join(sorted(trigger_remount)) ) ) unmount_result = __salt__["mount.umount"](real_name) if unmount_result is True: mount_result = __salt__["mount.mount"]( real_name, device, mkmnt=mkmnt, fstype=fstype, opts=opts, ) ret["result"] = mount_result else: ret["result"] = False ret["comment"] = "Unable to unmount {}: {}.".format( real_name, unmount_result ) return ret else: ret["changes"]["umount"] = ( "Forced remount because " + "options ({}) changed".format( ",".join(sorted(trigger_remount)) ) ) remount_result = __salt__["mount.remount"]( real_name, device, mkmnt=mkmnt, fstype=fstype, opts=opts, ) ret["result"] = remount_result # Cleanup after the remount, so we # don't write remount into fstab if "remount" in opts: opts.remove("remount") # Update the cache update_mount_cache = True mount_cache = __salt__["mount.read_mount_cache"](real_name) if "opts" in mount_cache: _missing = [opt for opt in mount_cache["opts"] if opt not in opts] if _missing: if __opts__["test"]: ret["result"] = None ret["comment"] = ( "Remount would be forced because" " options ({})" "changed".format(",".join(_missing)) ) return ret else: # Some file systems require umounting and mounting if options change # add others to list that require similiar functionality if fstype in ["nfs", "cvfs"] or fstype.startswith("fuse"): ret["changes"]["umount"] = ( "Forced unmount and mount because " + "options ({}) changed".format(opt) ) unmount_result = __salt__["mount.umount"](real_name) if unmount_result is True: mount_result = __salt__["mount.mount"]( real_name, device, mkmnt=mkmnt, fstype=fstype, opts=opts, ) ret["result"] = mount_result else: ret["result"] = False ret["comment"] = "Unable to unmount {}: {}.".format( real_name, unmount_result ) return ret else: ret["changes"]["umount"] = ( "Forced remount because " + "options ({}) changed".format(opt) ) remount_result = __salt__["mount.remount"]( real_name, device, mkmnt=mkmnt, fstype=fstype, opts=opts, ) ret["result"] = remount_result # Cleanup after the remount, so we # don't write remount into fstab if "remount" in opts: opts.remove("remount") update_mount_cache = True else: update_mount_cache = True if real_device not in device_list: # name matches but device doesn't - need to umount _device_mismatch_is_ignored = None for regex in list(device_name_regex): for _device in device_list: if re.match(regex, _device): _device_mismatch_is_ignored = _device break if _device_mismatch_is_ignored: ret["result"] = True ret["comment"] = ( "An umount will not be forced " + "because device matched device_name_regex: " + _device_mismatch_is_ignored ) elif __opts__["test"]: ret["result"] = None ret["comment"] = ( "An umount would have been forced " + "because devices do not match. Watched: " + device ) else: ret["changes"]["umount"] = ( "Forced unmount because devices " + "don't match. Wanted: " + device ) if real_device != device: ret["changes"]["umount"] += " (" + real_device + ")" ret["changes"]["umount"] += ", current: " + ", ".join(device_list) out = __salt__["mount.umount"](real_name, user=user) active = __salt__["mount.active"](extended=True) if comp_real_name in active: ret["comment"] = "Unable to unmount" ret["result"] = None return ret update_mount_cache = True else: ret["comment"] = "Target was already mounted" # using a duplicate check so I can catch the results of a umount if comp_real_name not in active: if mount: # The mount is not present! Mount it if __opts__["test"]: ret["result"] = None if os.path.exists(name): ret["comment"] = "{} would be mounted".format(name) elif mkmnt: ret["comment"] = "{} would be created and mounted".format(name) else: ret[ "comment" ] = "{} does not exist and would not be created".format(name) return ret if not os.path.exists(name) and not mkmnt: ret["result"] = False ret["comment"] = "Mount directory is not present" return ret out = __salt__["mount.mount"](name, device, mkmnt, fstype, opts, user=user) active = __salt__["mount.active"](extended=True) update_mount_cache = True if isinstance(out, str): # Failed to (re)mount, the state has failed! ret["comment"] = out ret["result"] = False return ret elif comp_real_name in active: # (Re)mount worked! ret["comment"] = "Target was successfully mounted" ret["changes"]["mount"] = True elif not os.path.exists(name): if __opts__["test"]: ret["result"] = None if mkmnt: ret["comment"] = "{} would be created, but not mounted".format(name) else: ret[ "comment" ] = "{} does not exist and would neither be created nor mounted".format( name ) elif mkmnt: __salt__["file.mkdir"](name, user=user) ret["comment"] = "{} was created, not mounted".format(name) else: ret["comment"] = "{} not present and not mounted".format(name) else: if __opts__["test"]: ret["comment"] = "{} would not be mounted".format(name) else: ret["comment"] = "{} not mounted".format(name) if persist: if "/etc/fstab" == config: # Override default for Mac OS if __grains__["os"] in ["MacOS", "Darwin"]: config = "/etc/auto_salt" # Override default for AIX elif "AIX" in __grains__["os"]: config = "/etc/filesystems" if __opts__["test"]: if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.set_automaster"]( name, device, fstype, opts, config, test=True ) elif __grains__["os"] in ["AIX"]: out = __salt__["mount.set_filesystems"]( name, device, fstype, opts, mount, config, test=True, match_on=match_on, ) else: out = __salt__["mount.set_fstab"]( name, device, fstype, opts, dump, pass_num, config, test=True, match_on=match_on, ) if out != "present": ret["result"] = None if out == "new": if mount: comment = ( "{} is mounted, but needs to be " "written to the fstab in order to be " "made persistent.".format(name) ) else: comment = ( "{} needs to be " "written to the fstab in order to be " "made persistent.".format(name) ) elif out == "change": if mount: comment = "{} is mounted, but its fstab entry must be updated.".format( name ) else: comment = "The {} fstab entry must be updated.".format(name) else: ret["result"] = False comment = ( "Unable to detect fstab status for " "mount point {} due to unexpected " "output '{}' from call to " "mount.set_fstab. This is most likely " "a bug.".format(name, out) ) if "comment" in ret: ret["comment"] = "{}. {}".format(ret["comment"], comment) else: ret["comment"] = comment return ret else: if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.set_automaster"]( name, device, fstype, opts, config ) elif __grains__["os"] in ["AIX"]: out = __salt__["mount.set_filesystems"]( name, device, fstype, opts, mount, config, match_on=match_on ) else: out = __salt__["mount.set_fstab"]( name, device, fstype, opts, dump, pass_num, config, match_on=match_on, ) if update_mount_cache: cache_result = __salt__["mount.write_mount_cache"]( real_name, device, mkmnt=mkmnt, fstype=fstype, mount_opts=opts ) if out == "present": ret["comment"] += ". Entry already exists in the fstab." return ret if out == "new": ret["changes"]["persist"] = "new" ret["comment"] += ". Added new entry to the fstab." return ret if out == "change": ret["changes"]["persist"] = "update" ret["comment"] += ". Updated the entry in the fstab." return ret if out == "bad config": ret["result"] = False ret["comment"] += ". However, the fstab was not found." return ret return ret def swap(name, persist=True, config="/etc/fstab"): """ Activates a swap device .. code-block:: yaml /root/swapfile: mount.swap .. note:: ``swap`` does not currently support LABEL """ ret = {"name": name, "changes": {}, "result": True, "comment": ""} on_ = __salt__["mount.swaps"]() if __salt__["file.is_link"](name): real_swap_device = __salt__["file.readlink"](name) if not real_swap_device.startswith("/"): real_swap_device = "/dev/{}".format(os.path.basename(real_swap_device)) else: real_swap_device = name if real_swap_device in on_: ret["comment"] = "Swap {} already active".format(name) elif __opts__["test"]: ret["result"] = None ret["comment"] = "Swap {} is set to be activated".format(name) else: __salt__["mount.swapon"](real_swap_device) on_ = __salt__["mount.swaps"]() if real_swap_device in on_: ret["comment"] = "Swap {} activated".format(name) ret["changes"] = on_[real_swap_device] else: ret["comment"] = "Swap {} failed to activate".format(name) ret["result"] = False if persist: device_key_name = "device" if "AIX" in __grains__["os"]: device_key_name = "dev" if "/etc/fstab" == config: # Override default for AIX config = "/etc/filesystems" fstab_data = __salt__["mount.filesystems"](config) else: fstab_data = __salt__["mount.fstab"](config) if __opts__["test"]: if name not in fstab_data and name not in [ fstab_data[item]["device"] for item in fstab_data ]: ret["result"] = None if name in on_: ret[ "comment" ] = "Swap {} is set to be added to the fstab and to be activated".format( name ) return ret if "none" in fstab_data: if ( fstab_data["none"][device_key_name] == name and fstab_data["none"]["fstype"] != "swap" ): return ret if "AIX" in __grains__["os"]: out = None ret["result"] = False ret["comment"] += ". swap not present in /etc/filesystems on AIX." return ret else: # present, new, change, bad config # Make sure the entry is in the fstab out = __salt__["mount.set_fstab"]( "none", name, "swap", ["defaults"], 0, 0, config ) if out == "present": return ret if out == "new": ret["changes"]["persist"] = "new" ret["comment"] += ". Added new entry to the fstab." return ret if out == "change": ret["changes"]["persist"] = "update" ret["comment"] += ". Updated the entry in the fstab." return ret if out == "bad config": ret["result"] = False ret["comment"] += ". However, the fstab was not found." return ret return ret def unmounted( name, device=None, config="/etc/fstab", persist=False, user=None, **kwargs ): """ .. versionadded:: 0.17.0 Verify that a device is not mounted name The path to the location where the device is to be unmounted from device The device to be unmounted. This is optional because the device could be mounted in multiple places. .. versionadded:: 2015.5.0 config Set an alternative location for the fstab, Default is ``/etc/fstab`` persist Set if the mount should be purged from the fstab, Default is ``False`` user The user to own the mount; this defaults to the user salt is running as on the minion """ ret = {"name": name, "changes": {}, "result": True, "comment": ""} update_mount_cache = False if not name: ret["result"] = False ret["comment"] = "Must provide name to mount.unmounted" return ret # Get the active data active = __salt__["mount.active"](extended=True) comp_name = name.replace(" ", "\\040") if comp_name not in active: # Nothing to unmount ret["comment"] = "Target was already unmounted" if comp_name in active: # The mount is present! Unmount it if __opts__["test"]: ret["result"] = None ret["comment"] = "Mount point {} is mounted but should not be".format(name) return ret if device: out = __salt__["mount.umount"](name, device, user=user) update_mount_cache = True else: out = __salt__["mount.umount"](name, user=user) update_mount_cache = True if isinstance(out, str): # Failed to umount, the state has failed! ret["comment"] = out ret["result"] = False elif out is True: # umount worked! ret["comment"] = "Target was successfully unmounted" ret["changes"]["umount"] = True else: ret["comment"] = "Execute set to False, Target was not unmounted" ret["result"] = True if update_mount_cache: cache_result = __salt__["mount.delete_mount_cache"](name) if persist: device_key_name = "device" # Override default for Mac OS if __grains__["os"] in ["MacOS", "Darwin"] and config == "/etc/fstab": config = "/etc/auto_salt" fstab_data = __salt__["mount.automaster"](config) elif "AIX" in __grains__["os"]: device_key_name = "dev" if config == "/etc/fstab": config = "/etc/filesystems" fstab_data = __salt__["mount.filesystems"](config) else: fstab_data = __salt__["mount.fstab"](config) if name not in fstab_data: ret["comment"] += ". fstab entry not found" else: if device: if fstab_data[name][device_key_name] != device: ret["comment"] += ". fstab entry for device {} not found".format( device ) return ret if __opts__["test"]: ret["result"] = None ret["comment"] = ( "Mount point {} is unmounted but needs to " "be purged from {} to be made " "persistent".format(name, config) ) return ret else: if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.rm_automaster"](name, device, config) elif "AIX" in __grains__["os"]: out = __salt__["mount.rm_filesystems"](name, device, config) else: out = __salt__["mount.rm_fstab"](name, device, config) if out is not True: ret["result"] = False ret["comment"] += ". Failed to persist purge" else: ret["comment"] += ". Removed target from fstab" ret["changes"]["persist"] = "purged" return ret def mod_watch(name, user=None, **kwargs): """ The mounted watcher, called to invoke the watch command. .. note:: This state exists to support special handling of the ``watch`` :ref:`requisite <requisites>`. It should not be called directly. Parameters for this function should be set by the state being triggered. name The name of the mount point """ ret = {"name": name, "changes": {}, "result": True, "comment": ""} if kwargs["sfun"] == "mounted": out = __salt__["mount.remount"]( name, kwargs["device"], False, kwargs["fstype"], kwargs["opts"], user=user ) if out: ret["comment"] = "{} remounted".format(name) else: ret["result"] = False ret["comment"] = "{} failed to remount: {}".format(name, out) else: ret["comment"] = "Watch not supported in {} at this time".format(kwargs["sfun"]) return ret def _convert_to(maybe_device, convert_to): """ Convert a device name, UUID or LABEL to a device name, UUID or LABEL. Return the fs_spec required for fstab. """ # Fast path. If we already have the information required, we can # save one blkid call if ( not convert_to or (convert_to == "device" and maybe_device.startswith("/")) or maybe_device.startswith("{}=".format(convert_to.upper())) ): return maybe_device # Get the device information if maybe_device.startswith("/"): blkid = __salt__["disk.blkid"](maybe_device) else: blkid = __salt__["disk.blkid"](token=maybe_device) result = None if len(blkid) == 1: if convert_to == "device": result = next(iter(blkid)) else: key = convert_to.upper() result = "{}={}".format(key, next(iter(blkid.values()))[key]) return result def fstab_present( name, fs_file, fs_vfstype, fs_mntops="defaults", fs_freq=0, fs_passno=0, mount_by=None, config="/etc/fstab", mount=True, match_on="auto", not_change=False, fs_mount=True, ): """Makes sure that a fstab mount point is present. name The name of block device. Can be any valid fs_spec value. fs_file Mount point (target) for the filesystem. fs_vfstype The type of the filesystem (e.g. ext4, xfs, btrfs, ...) fs_mntops The mount options associated with the filesystem. Default is ``defaults``. fs_freq Field is used by dump to determine which fs need to be dumped. Default is ``0`` fs_passno Field is used by fsck to determine the order in which filesystem checks are done at boot time. Default is ``0`` fs_mount Field is used only in AIX systems to determine if the filesystem will be mounted by ``mount all`` mount_by Select the final value for fs_spec. Can be [``None``, ``device``, ``label``, ``uuid``, ``partlabel``, ``partuuid``]. If ``None``, the value for fs_spect will be the parameter ``name``, in other case will search the correct value based on the device name. For example, for ``uuid``, the value for fs_spec will be of type 'UUID=xxx' instead of the device name set in ``name``. config Place where the fstab file lives. Default is ``/etc/fstab`` mount Set if the mount should be mounted immediately. Default is ``True`` match_on A name or list of fstab properties on which this state should be applied. Default is ``auto``, a special value indicating to guess based on fstype. In general, ``auto`` matches on name for recognized special devices and device otherwise. not_change By default, if the entry is found in the fstab file but is different from the expected content (like different options), the entry will be replaced with the correct content. If this parameter is set to ``True`` and the line is found, the original content will be preserved. """ ret = { "name": name, "result": False, "changes": {}, "comment": [], } # Adjust fs_mntops based on the OS if fs_mntops == "defaults": if __grains__["os"] in ["MacOS", "Darwin"]: fs_mntops = "noowners" elif __grains__["os"] == "AIX": fs_mntops = "" # Adjust the config file based on the OS if config == "/etc/fstab": if __grains__["os"] in ["MacOS", "Darwin"]: config = "/etc/auto_salt" elif __grains__["os"] == "AIX": config = "/etc/filesystems" if not fs_file == "/": fs_file = fs_file.rstrip("/") fs_spec = _convert_to(name, mount_by) # Validate that the device is valid after the conversion if not fs_spec: msg = "Device {} cannot be converted to {}" ret["comment"].append(msg.format(name, mount_by)) return ret if __opts__["test"]: if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.set_automaster"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, config=config, test=True, not_change=not_change, ) elif __grains__["os"] == "AIX": out = __salt__["mount.set_filesystems"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, mount=fs_mount, config=config, test=True, match_on=match_on, not_change=not_change, ) else: out = __salt__["mount.set_fstab"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, dump=fs_freq, pass_num=fs_passno, config=config, test=True, match_on=match_on, not_change=not_change, ) ret["result"] = None if out == "present": msg = "{} entry is already in {}." ret["comment"].append(msg.format(fs_file, config)) elif out == "new": msg = "{} entry will be written in {}." ret["comment"].append(msg.format(fs_file, config)) if mount: msg = "Will mount {} on {}".format(name, fs_file) ret["comment"].append(msg) elif out == "change": msg = "{} entry will be updated in {}." ret["comment"].append(msg.format(fs_file, config)) else: ret["result"] = False msg = "{} entry cannot be created in {}: {}." ret["comment"].append(msg.format(fs_file, config, out)) return ret if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.set_automaster"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, config=config, not_change=not_change, ) elif __grains__["os"] == "AIX": out = __salt__["mount.set_filesystems"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, mount=fs_mount, config=config, match_on=match_on, not_change=not_change, ) else: out = __salt__["mount.set_fstab"]( name=fs_file, device=fs_spec, fstype=fs_vfstype, opts=fs_mntops, dump=fs_freq, pass_num=fs_passno, config=config, match_on=match_on, not_change=not_change, ) ret["result"] = True if out == "present": msg = "{} entry was already in {}." ret["comment"].append(msg.format(fs_file, config)) elif out == "new": ret["changes"]["persist"] = out msg = "{} entry added in {}." ret["comment"].append(msg.format(fs_file, config)) if mount: out = __salt__["mount.mount"](fs_file) if type(out) == str: ret["result"] = False msg = "Error while mounting {}".format(out.split(":", maxsplit=1)[1]) else: msg = "Mounted {} on {}".format(name, fs_file) ret["comment"].append(msg) elif out == "change": ret["changes"]["persist"] = out msg = "{} entry updated in {}." ret["comment"].append(msg.format(fs_file, config)) else: ret["result"] = False msg = "{} entry cannot be changed in {}: {}." ret["comment"].append(msg.format(fs_file, config, out)) return ret def fstab_absent(name, fs_file, mount_by=None, config="/etc/fstab"): """ Makes sure that a fstab mount point is absent. name The name of block device. Can be any valid fs_spec value. fs_file Mount point (target) for the filesystem. mount_by Select the final value for fs_spec. Can be [``None``, ``device``, ``label``, ``uuid``, ``partlabel``, ``partuuid``]. If ``None``, the value for fs_spect will be the parameter ``name``, in other case will search the correct value based on the device name. For example, for ``uuid``, the value for fs_spec will be of type 'UUID=xxx' instead of the device name set in ``name``. config Place where the fstab file lives """ ret = { "name": name, "result": False, "changes": {}, "comment": [], } # Adjust the config file based on the OS if config == "/etc/fstab": if __grains__["os"] in ["MacOS", "Darwin"]: config = "/etc/auto_salt" elif __grains__["os"] == "AIX": config = "/etc/filesystems" if not fs_file == "/": fs_file = fs_file.rstrip("/") fs_spec = _convert_to(name, mount_by) if __grains__["os"] in ["MacOS", "Darwin"]: fstab_data = __salt__["mount.automaster"](config) elif __grains__["os"] == "AIX": fstab_data = __salt__["mount.filesystems"](config) else: fstab_data = __salt__["mount.fstab"](config) if __opts__["test"]: ret["result"] = None if fs_file not in fstab_data: msg = "{} entry is already missing in {}." ret["comment"].append(msg.format(fs_file, config)) else: msg = "{} entry will be removed from {}." ret["comment"].append(msg.format(fs_file, config)) return ret if fs_file in fstab_data: if __grains__["os"] in ["MacOS", "Darwin"]: out = __salt__["mount.rm_automaster"]( name=fs_file, device=fs_spec, config=config ) elif __grains__["os"] == "AIX": out = __salt__["mount.rm_filesystems"]( name=fs_file, device=fs_spec, config=config ) else: out = __salt__["mount.rm_fstab"]( name=fs_file, device=fs_spec, config=config ) if out is not True: ret["result"] = False msg = "{} entry failed when removing from {}." ret["comment"].append(msg.format(fs_file, config)) else: ret["result"] = True ret["changes"]["persist"] = "removed" msg = "{} entry removed from {}." ret["comment"].append(msg.format(fs_file, config)) else: ret["result"] = True msg = "{} entry is already missing in {}." ret["comment"].append(msg.format(fs_file, config)) return ret
Save