The "mount' module and adding a mount option

I’ve got a variety of mounts that I want to ensure specific flags are set on each. For other reasons, the mounts don’t have the same flags.

I mistakenly thought the ‘mount’ module would ensure each had the flag, but instead it set the flags of the mount to ONLY the ‘opts’ parameter.

For instance, I have a test system with these two mounts:
/tmp/mount01 /tmp/mounts/mount01 xfs defaults,noatime,nodev 0 0
/tmp/mount02 /tmp/mounts/mount02 xfs defaults,relatime,noexec 0 0

Note the changes in the mount options.

I setup this play in a playbook:

  • name: “Add nodev to /tmp/mounts/mount*”
    mount:
    path: ‘/tmp/mounts/{{ item }}’
    src: ‘/tmp/{{ item }}’
    fstype: xfs
    opts: ‘nodev’
    state: present
    passno: ‘0’
    dump: ‘0’
    backup: yes
    with_items:
  • mount01
  • mount02

But ended up getting the mounts (in /etc/fstab) like this:
/tmp/mount01 /tmp/mounts/mount01 xfs nodev 0 0
/tmp/mount02 /tmp/mounts/mount02 xfs nodev 0 0

Since I’m ‘gathering_facts’, I thought I could use the ‘ansible_mounts’ list, but the options are just a simple string:
{

“fstype”: “xfs”,

“mount”: “/tmp/mounts/mount01”,
“options”: “rw,seclabel,nodev,noatime,attr2,inode64,noquota”,

}

In a much more complex playbook, I have pulled out the individual ‘options’ parameters and could append the new ‘opts’ parameters to each - but that ends up doing a simple appending which ends up in the /etc/fstab file so each run adds another value.

My question: Is there a simpler way that I’m overlooking to ensure that ‘nodev’ - or any single parameter is provided to ‘opts’ - is in each mount without having to define the entier (and potentially unique) ‘opts’ string for each mount?

If the ‘options’ within the ‘gather_facts’ was also a list, then adding the ‘nodev’ element wouldn’t lead to the duplication issue… If the ‘mount’ ‘opts’ parameter took a list, then it would be possible to convert the CSV string to a list, then append the single ‘opt’ to the list.

You don’t have to split the opts by comma, just checking if ‘nodev’ is enough.
If it isn’t there, you can then append it:

  • name: “Add nodev to /tmp/mounts/mount*”
    mount:
    path: ‘/tmp/mounts/{{ item }}’
    src: ‘/tmp/{{ item }}’
    fstype: xfs
    opts: '{{ (ansible_mounts|selectattr(‘mount’, ‘equalto’, ‘/tmp/mounts/’ ~ item)).0.options }},nodev"
    state: present
    passno: ‘0’
    dump: ‘0’
    backup: yes
    with_items:
  • mount01
  • mount02

when: “‘nodev’ not in (ansible_mounts|selectattr(‘mount’, ‘equalto’, ‘/tmp/mounts/’ ~ item)).0.options”

The only thing with this approach is that it explicitly sets all the flags that are reported by ansible_mounts - but this might be a good idea anyway.

Dick

Thanks, I’ll give that a shot.

I don’t like the “explicitly sets all the flags that are reported by ansible_mount” feature either so I might have to think about this more.

I guess I could note which mounts are missing “nodev”, then use the lineinfile: to rewrite the affected /etc/fstab lines and add the “nodev” flag. (That’s about 33% serious, 66% tongue-in-cheek…)

Something like:

  • name: “Setup some of the mount flag variables”
    set_fact:
    mount_flags:

  • ‘nodev’

  • ‘noexec’
    mount_point:

  • ‘mount01’

  • ‘mount02’

  • name: “Ensure mount flags are set”
    lineinfile:
    path: /etc/fstab2
    regexp: ‘(\S+\s+\S*/tmp/mounts/{{ item.0 }}\S*\s+\S+\s+)(\S+)(\s+\S+\s+\S+)’
    line: ‘\1\2,{{ item.1 }}\3’
    backrefs: yes
    backup: yes
    when: “‘{{ item.1 }}’ not in (ansible_mounts|selectattr(‘mount’, ‘equalto’, ‘/tmp/mounts/’ ~ item.0)).0.options”

loop: “{{ mount_point|product(mount_flags)|list }}”

NOTE: item.0 are the ‘mount_point’ entries, and item.1 are the ‘mount_flags’ entries.

Now I know it can be done, but should it be done…or will this end up being a playbook that only I can support at 3AM… :-/

Dan