Add new role, 'debops.mount'

The role 'debops.mount' allows configuration of local device and bind
mounts. It's included in the 'common.yml' playbook by default.
parent df5f7b0b
......@@ -837,6 +837,14 @@ stages:
JANE_DIFF_PATTERN: '.*/debops.mosquitto/.*'
JANE_LOG_PATTERN: '\[debops\.mosquitto\]'
'mount role':
<<: *test_role_no_deps
variables:
JANE_TEST_PLAY: '${DEBOPS_PLAYBOOKS}/service/mount.yml'
JANE_INVENTORY_GROUPS: 'debops_service_mount'
JANE_DIFF_PATTERN: '.*/debops.mount/.*'
JANE_LOG_PATTERN: '\[debops\.mount\]'
# --- n --- [[[2
......
......@@ -33,6 +33,11 @@ Added
- :ref:`debops.dhcp_probe`, can be used to install and configure
:command:`dhcp_probe` service, which passively detects rogue DHCP servers.
- :ref:`debops.mount`, the role allows configuration of :file:`/etc/fstab`
entries for local devices, bind mounts and can be used to create or modify
directories, to permit access to resources by different applications. The
role is included by default in the ``common.yml`` playbook.
- [debops.users] The role can now configure ACL entries of the user home
directories using the ``item.home_acl`` parameter. This can be used for more
elaborate access restrictions.
......
......@@ -113,6 +113,9 @@
- role: debops.users
tags: [ 'role::users', 'skip::users' ]
- role: debops.mount
tags: [ 'role::mount', 'skip::mount' ]
- role: debops.resources
tags: [ 'role::resources', 'skip::resources' ]
......
---
- name: Manage local device and bind mounts
hosts: [ 'debops_all_hosts', 'debops_service_mount' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
roles:
- role: debops.mount
tags: [ 'role::mount', 'skip::mount' ]
---
- import_playbook: mount.yml
- import_playbook: netbase.yml
- import_playbook: sysnews.yml
......
../service/mount.yml
\ No newline at end of file
debops.mount - Manage local device and bind mounts using Ansible
Copyright (C) 2018 Maciej Delmanowski <drybjed@gmail.com>
Copyright (C) 2018 DebOps https://debops.org/
This Ansible role is part of DebOps.
DebOps is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3, as
published by the Free Software Foundation.
DebOps is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DebOps. If not, see https://www.gnu.org/licenses/.
---
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
# debops.mount default variables
# ==============================
# .. contents:: Sections
# :local:
#
# .. include:: ../../../includes/global.rst
# General configuration [[[
# -------------------------
# .. envvar:: mount__enabled [[[
#
# Enable or disable support for local device mounts, bind mounts and custom
# directories.
mount__enabled: '{{ True
if (((ansible_system_capabilities_enforced|d())|bool and
"cap_sys_admin" in ansible_system_capabilities) or
not (ansible_system_capabilities_enforced|d(True))|bool)
else False }}'
# ]]]
# .. envvar:: mount__base_packages [[[
#
# List of APT packages to install for correct filesystem management.
mount__base_packages: '{{ [ "acl" ]
if (((mount__directories
+ mount__group_directories
+ mount__host_directories)
| flatten) | selectattr("acl", "defined") | list
| subelements("acl"))
else [] }}'
# ]]]
# .. envvar:: mount__packages [[[
#
# List of additional APT packages to install for filesystem management.
mount__packages: []
# ]]]
# ]]]
# Device mounts [[[
# -----------------
# These variables control local device mounts, usually external disk drives,
# LVM block devices or other storage. See :ref:`mount__ref_devices` for
# more details.
# .. envvar:: mount__devices [[[
#
# Define local mounts for all hosts in the Ansible inventory.
mount__devices: []
# ]]]
# .. envvar:: mount__group_devices [[[
#
# Define local mounts for hosts in a specific Ansible inventory group.
mount__group_devices: []
# ]]]
# .. envvar:: mount__host_devices [[[
#
# Define local mounts for specific hosts in the Ansible inventory.
mount__host_devices: []
# ]]]
# ]]]
# Custom directories [[[
# ----------------------
# These variables can be used to create custom directories on mounted
# filesystems with specific permissions, ACLs, etc.
# See :ref:`mount__ref_directories` for more details.
# .. envvar:: mount__directories [[[
#
# List of directories to manage on all hosts in the Ansible inventory.
mount__directories: []
# ]]]
# .. envvar:: mount__group_directories [[[
#
# List of directories to manage on hosts in a specific Ansible inventory group.
mount__group_directories: []
# ]]]
# .. envvar:: mount__host_directories [[[
#
# List of directories to manage on specific hosts in the Ansible inventory.
mount__host_directories: []
# ]]]
# ]]]
# Bind mounts [[[
# ---------------
# These variables define configuration of bind mounts, separately from normal
# filesystems to allow bind-mounting of existing directories.
# See :ref:`mount__ref_binds` for more details.
# .. envvar:: mount__binds [[[
#
# Define bind mounts for all hosts in the Ansible inventory.
mount__binds: []
# ]]]
# .. envvar:: mount__group_binds [[[
#
# Define bind mounts for hosts in a specific Ansible inventory group.
mount__group_binds: []
# ]]]
# .. envvar:: mount__host_binds [[[
#
# Define bind mounts for specific hosts in the Ansible inventory.
mount__host_binds: []
# ]]]
# ]]]
---
dependencies: []
galaxy_info:
role_name: 'mount'
author: 'Maciej Delmanowski'
description: 'Manage local device and bind mounts'
company: 'DebOps'
license: 'GPL-3.0'
min_ansible_version: '2.6.0'
platforms:
- name: Ubuntu
versions:
- precise
- quantal
- raring
- saucy
- trusty
- xenial
- bionic
- name: Debian
versions:
- wheezy
- jessie
- stretch
- buster
galaxy_tags:
- system
- filesystems
- mount
---
- name: Install required packages
package:
name: '{{ (mount__base_packages + mount__packages) | flatten }}'
state: 'present'
when: mount__enabled|bool
# This task allows configuration of the outer mount point attributes, but
# will not change them while the device is mounted.
- name: Ensure that the mount points exist
file:
path: '{{ item.path | d(item.dest | d(item.name)) }}'
owner: '{{ item.owner | d("root") }}'
group: '{{ item.group | d(item.owner | d("root")) }}'
mode: '{{ item.mode | d("0755") }}'
state: 'directory'
loop: '{{ (mount__devices
+ mount__group_devices
+ mount__host_devices)
| flatten }}'
when: (mount__enabled|bool and item.state|d('mounted') in [ 'mounted', 'present', 'unmounted' ] and
(item.device | d(item.src)) not in (ansible_mounts | map(attribute='device') | list))
- name: Stop devices automounted by systemd if requested
systemd:
name: '{{ item.name | regex_replace("^/","") | regex_replace("/","-") + ".automount" }}'
state: 'stopped'
loop: '{{ (mount__devices
+ mount__group_devices
+ mount__host_devices)
| flatten }}'
when: (mount__enabled|bool and ansible_service_mgr == 'systemd' and item.state|d('mounted') in [ 'unmounted', 'absent' ] and
(((item.opts if (item.opts is string) else item.opts | join(',')) if item.opts|d() else 'defaults') is match(".*x-systemd.automount.*")))
- name: Manage device mounts
mount:
src: '{{ item.src }}'
path: '{{ item.path | d(item.dest | d(item.name)) }}'
fstype: '{{ item.fstype | d("auto") }}'
opts: '{{ ((item.opts if (item.opts is string) else (item.opts | join(","))) if item.opts|d() else "defaults") }}'
dump: '{{ item.dump | d(omit) }}'
passno: '{{ item.passno | d(omit) }}'
state: '{{ item.state | d("mounted") }}'
fstab: '{{ item.fstab | d(omit) }}'
loop: '{{ (mount__devices
+ mount__group_devices
+ mount__host_devices)
| flatten }}'
register: mount__register_devices
when: (mount__enabled|bool and
(item.name|d() or item.dest|d() or item.path|d()) and
item.src|d() and item.fstype|d())
- name: Restart 'local-fs.target' systemd unit
systemd:
name: 'local-fs.target'
state: 'restarted'
daemon_reload: True
loop: '{{ mount__register_devices.results }}'
when: (mount__enabled|bool and ansible_service_mgr == 'systemd' and item is changed and
(((item.opts if (item.opts is string) else item.opts | join(',')) if item.opts|d() else 'defaults') is match(".*x-systemd.automount.*")))
- name: Manage directories
file:
path: '{{ item.path | d(item.dest | d(item.name)) }}'
owner: '{{ item.owner | d("root") }}'
group: '{{ item.group | d(item.owner | d("root")) }}'
mode: '{{ item.mode | d("0755") }}'
recurse: '{{ item.recurse | d(omit) }}'
state: '{{ item.state | d("directory") }}'
loop: '{{ (mount__directories
+ mount__group_directories
+ mount__host_directories)
| flatten }}'
when: mount__enabled|bool and (item.path|d() or item.dest|d() or item.name|d()) and
item.state|d('directory') in [ 'directory', 'absent' ]
- name: Manage directory ACLs
acl:
path: '{{ item.0.path | d(item.0.dest | d(item.0.name)) }}'
default: '{{ item.1.default | d(omit) }}'
entity: '{{ item.1.entity | d(omit) }}'
etype: '{{ item.1.etype | d(omit) }}'
permissions: '{{ item.1.permissions | d(omit) }}'
follow: '{{ item.1.follow | d(omit) }}'
recursive: '{{ item.1.recursive | d(omit) }}'
state: '{{ item.1.state | d("present") }}'
loop: '{{ ((mount__directories
+ mount__group_directories
+ mount__host_directories)
| flatten) | selectattr("acl", "defined") | list
| subelements("acl") }}'
loop_control:
label: '{{ {"name": item.0.name, "acl": item.1} }}'
when: mount__enabled|bool and (item.0.path|d() or item.0.dest|d() or item.0.name|d()) and
item.0.state|d('directory') == 'directory' and item.0.acl|d()
- name: Manage bind mounts
mount:
src: '{{ item.src }}'
path: '{{ item.path | d(item.dest | d(item.name)) }}'
fstype: '{{ item.fstype | d("none") }}'
opts: '{{ ((item.opts if (item.opts is string) else (item.opts | join(","))) if item.opts|d() else "bind") }}'
dump: '{{ item.dump | d(omit) }}'
passno: '{{ item.passno | d(omit) }}'
state: '{{ item.state | d("mounted") }}'
fstab: '{{ item.fstab | d(omit) }}'
loop: '{{ (mount__binds
+ mount__group_binds
+ mount__host_binds)
| flatten }}'
when: (mount__enabled|bool and
(item.name|d() or item.dest|d() or item.path|d()) and
item.src|d())
- name: Make sure that Ansible local facts directory exists
file:
path: '/etc/ansible/facts.d'
state: 'directory'
owner: 'root'
group: 'root'
mode: '0755'
- name: Save mount local facts
template:
src: 'etc/ansible/facts.d/mount.fact.j2'
dest: '/etc/ansible/facts.d/mount.fact'
owner: 'root'
group: 'root'
mode: '0755'
#!/usr/bin/python{{ '2' if (ansible_python_version is version_compare('3.5', '<')) else '3' }}
# {{ ansible_managed }}
from __future__ import print_function
from json import loads, dumps
from sys import exit
output = loads('''{{ {'configured': True,
'enabled': mount__enabled|bool
} | to_nice_json }}''')
print(dumps(output, sort_keys=True, indent=4))
......@@ -127,6 +127,7 @@ other hosts.
- :ref:`debops.cryptsetup`
- :ref:`debops.iscsi`
- :ref:`debops.lvm`
- :ref:`debops.mount`
- :ref:`debops.nfs`
- :ref:`debops.nfs_server`
- :ref:`debops.persistent_paths`
......@@ -262,6 +263,7 @@ System configuration
- :ref:`debops.locales`
- :ref:`debops.logrotate`
- :ref:`debops.machine`
- :ref:`debops.mount`
- :ref:`debops.netbase`
- :ref:`debops.nsswitch`
- :ref:`debops.ntp`
......
This diff is collapsed.
Getting started
===============
.. contents::
:local:
Example inventory
-----------------
The ``debops.mount`` role is included by default in the DebOps ``common.yml``
playbook and does not need to be explicitly enabled. It can be disabled if
needed, by setting the :envvar:`mount__enabled` boolean variable to ``False``
in the Ansible inventory.
Example playbook
----------------
If you are using this role without DebOps, here's an example Ansible playbook
that uses the ``debops.mount`` role:
.. literalinclude:: ../../../../ansible/playbooks/service/mount.yml
:language: yaml
Ansible tags
------------
You can use Ansible ``--tags`` or ``--skip-tags`` parameters to limit what
tasks are performed during Ansible run. This can be used after a host was first
configured to speed up playbook execution, when you are sure that most of the
configuration is already in the desired state.
Available role tags:
``role::mount``
Main role tag, should be used in the playbook to execute all of the role
tasks as well as role dependencies.
Other resources
---------------
List of other useful resources related to the ``debops.mount`` Ansible role:
- Manual pages: :man:`fstab(5)`, :man:`systemd.mount(5)`,
:man:`systemd.automount(5)`
- `Ansible 'mount' module documentation`__
.. __: https://docs.ansible.com/ansible/latest/modules/mount_module.html
- `Debian Wiki: fstab`__
.. __: https://wiki.debian.org/fstab
- `Arch Linux Wiki: fstab`__
.. __: https://wiki.archlinux.org/index.php/Fstab
- `StackExchange: What is a bind mount?`__
.. __: https://unix.stackexchange.com/a/198591
.. _debops.mount:
debops.mount
============
The ``debops.mount`` Ansible role can be used to manage local filesystem mounts
as well as bind mounts in the :file:`/etc/fstab` database. Custom directories
can also be created by this role, with support for normal as well as ACL
attributes.
This role is meant to be used to configure local filesystems, for remote
filesystems, you can use the :ref:`debops.nfs` role instead, which will
configure the NFS client service.
.. toctree::
:maxdepth: 2
getting-started
defaults
defaults-detailed
Copyright
---------
.. literalinclude:: ../../../../ansible/roles/debops.mount/COPYRIGHT
..
Local Variables:
mode: rst
ispell-local-dictionary: "american"
End:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment