Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi-mount support #164

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ autofs::mounts:
mapfile: '/etc/auto.home'
```

### Map Files
### Map Files and Multi-mount Map Files

The module also provides two compatible, built-in mechanisms for managing
Autofs map files: by setting the `mapfiles` parameter of the `autofs`
class, and by declaration of `autofs::mapfile` resources. As with entries
class, and by declaration of `autofs::mapfile` or `autofs::multi-mapfile`resources. As with entries
in the master map, using these is not obligatory. In fact, they are
applicable only to map files written in the default (sun) map format;
some other mechanism must be chosen if map files in some other format are
Expand Down Expand Up @@ -319,6 +319,41 @@ The resulting content of file `/mnt/data` would be
dataA -ro remote.com:/exports/dataA
dataB -rw,noexec remote.com:/exports/dataB
```
#### Multi-mount mapping
The `autofs::multi_mapfile` and `autofs::multi_mapping` resouces are declared simlarily to a standard mapping. Ordering defaults to a numeric 10 instead of alpha-numeric ordering. Ordering 0 and 999999 are reserved for the root path and last line of the mapfile.

The root_path mount should always be order > 0 and less than all other mount points.

Only one multi-mount is supported per mapfile.

```puppet
autofs::multi_mapfile [ '/mnt/data':
root_path => '/data'
}

autofs::multi_mapping { '/mnt/dataRoot':
mapfile => '/mnt/data',
key => '/',
options => 'ro',
fs => 'remote.com:/exports/dataRoot',
order => '1'
}

autofs::multi_mapping { '/mnt/dataB':
mapfile => '/mnt/data',
key => '/dataB',
options => 'rw',
fs => 'remote.com:/exports/dataB'
}
```
The resulting content of file `/mnt/data` would be

```
/data \
/ -ro remote.com:/exports/dataRoot \
/dataB -rw remote.com:/exports/dataB \

```

#### Removing Entries

Expand Down Expand Up @@ -485,8 +520,7 @@ described by the corresponding map file. Defaults to the `title` of this `auto

Data type: Stdlib::Absolutepath or Autofs::MapEntry

This parameter designates the automount map serving this mount. Autofs supports a variety of options
here, but most commonly this is either an absolute path to a map file or the special string `-hosts`.
This parameter designates the automount map serving this mount. Autofs supports a variety of options here, but most commonly this is either an absolute path to a map file or the special string `-hosts`.

#### `options`

Expand Down Expand Up @@ -711,3 +745,7 @@ Authors

* Vox Pupuli: [[email protected]](mailto:[email protected])
* David Hollinger: [[email protected]](mailto:[email protected])
<!--stackedit_data:
eyJoaXN0b3J5IjpbMTc1MTIxNDA2NCwtMTA3MDA1MzU4MCw1MD
g3NTE3MTQsMTEyOTIwODYyNywxMDI5MjkwNDQyXX0=
-->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this is from

6 changes: 6 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ _Private Classes_
* [`autofs::mapfile`](#autofsmapfile): Defined type to manage overall autofs map files
* [`autofs::mapping`](#autofsmapping): Defined type to manage a single filesystem mapping in a single map
file.
* [`autofs::multi_mapfile`](#autofsmapfile): Defined type to manage overall autofs map files with multi-mounts
* [`autofs::multi_mapping`](#autofsmapping): Defined type to manage a single filesystem mapping in a multi-mount map
file.
* [`autofs::mount`](#autofsmount): Defined type to manage mount point definitions in the Autofs master
map.

Expand Down Expand Up @@ -686,3 +689,6 @@ non-empty string or an array of such strings

Alias of `Variant[Pattern[/\A\S+\z/], Array[Pattern[/\A\S+\z/]]]`

<!--stackedit_data:
eyJoaXN0b3J5IjpbLTE5MDI5ODczMTldfQ==
-->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above. I'd rather these not be in the Documentation unless they come from the Vox Pupuli toolset.

103 changes: 103 additions & 0 deletions manifests/multi_mapfile.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# @summary Defined type to manage autofs map files with a single multi-mount entry
#
# @see https://voxpupuli.org/puppet-autofs Home
# @see https://voxpupuli.org/puppet-autofs/puppet_classes/autofs.html puppet_classes::autofs
# @see https://www.github.com/voxpupuli/puppet-autofs Github
# @see https://forge.puppet.com/puppet/autofs Puppet Forge
#
# @author Vox Pupuli <[email protected]>
# @author David Hollinger III <[email protected]>
# @author Chip Schweiss <[email protected]>
#
# @param ensure Whether the mapfile should be present on the target system
# @param path An absolute path to the map file
# @param mappings an array of mappings to enroll in the file. Additional
# mappings can be specified for this mapfile via autofs::mapping resources
# @param replace Whether to replace the contents of any an existing file
# at the specified path
# @param execute Whether to make the mapfile executable or not
#
define autofs::multi_mapfile (
Enum['present', 'absent'] $ensure = 'present',
Stdlib::Absolutepath $path = $title,
Array[Autofs::Fs_mapping] $multi_mappings = [],
Optional[Autofs::Options] $options = undef,
Boolean $replace = true,
Boolean $execute = false,
Pattern[/\A\S+\z/] $root_path,
) {
include 'autofs'

unless $autofs::package_ensure == 'absent' {
if $autofs::reload_command {
Concat {
before => Service[$autofs::service_name],
notify => Exec['automount-reload'],
}
} else {
Concat {
notify => Service[$autofs::service_name],
}
}
}

$mapfile_mode = $execute ? {
true => '0755',
false => '0644'
}

concat { $path:
ensure => $ensure,
owner => $autofs::map_file_owner,
group => $autofs::map_file_group,
mode => $mapfile_mode,
replace => $replace,
order => 'numeric',
require => Class['autofs::package'],
warn => template('autofs/mapfile.banner.erb'),
}

if $ensure == 'present' {

# Format the options string, relying to some extent on the
# $options parameter, if specified, to indeed match the
# Autofs::Options data type
if ($options =~ Undef) or ($options =~ Array[Any,0,0]) { # an empty array
$formatted_options = ''
} else {
$prelim_options = $options ? {
Array => join($options, ','), # a non-empty array
String => $options,
default => fail('Unexpected value for parameter $options')
}
$formatted_options = $prelim_options ? {
# even though the user *shouldn't* provide the hyphen, we accommodate
# them doing so. But only at the head of the option list, not
# internally.
'' => '',
/\A-/ => $prelim_options,
default => "-${prelim_options}",
}
}

concat::fragment { "autofs::multi_mapping/${title}_root-_path":
target => "$path",
content => "${root_path} ${formatted_options} \\\n",
order => 0,
}

concat::fragment { "autofs::multi_mapping/${title}_endline":
target => "$path",
content => "\n",
order => 999999,
}

$multi_mappings.each |$mapping| {
autofs::multi_mapping { "${path}:${mapping[key]}":
ensure => 'present',
mapfile => $path,
* => $mapping,
}
}
}
}
99 changes: 99 additions & 0 deletions manifests/multi_mapping.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# @summary Defined type to manage a multi-mapping filesystem mapping in a single map
# file.
#
# When ensured 'present', a autofs::mapfile resource managing the overall
# target map file must also be present in the catalog. This resource
# implements Autofs's 'sun' map format, which is the default.
#
# It is not supported to declare multiple autofs::mappings with the
# same key, targetting the same map file, and ensured 'present'.
#
# @see https://voxpupuli.org/puppet-autofs Home
# @see https://voxpupuli.org/puppet-autofs/puppet_classes/autofs.html puppet_classes::autofs
# @see https://www.github.com/voxpupuli/puppet-autofs Github
# @see https://forge.puppet.com/puppet/autofs Puppet Forge
#
# @author Vox Pupuli <[email protected]>
# @author David Hollinger III <[email protected]>
# @author Chip Schweiss <[email protected]>
#
# @param ensure Whether the mapping should be present in the target mapfile;
# ensuring 'absent' is not meaningfully different from omitting the
# resource declaration altogether
# @param fs the remote filesystem to mount
# @param key the autofs key for this mappingr. For indirect maps it is the
# basename of the mountpoint directory for $fs (not to be confused with
# an _autofs_ mount point, which is the parent directory). For direct
# maps it is the absolute path to the mountpoint directory.
# @param mapfile the absolute path to the file containing the Autofs map
# to which this mapping belongs
# @param options a comma-delimited mount options string or an array of
# individual mount options; neither individual options nor the overall
# option list should be specified with a leading hyphen (-); that is
# part of the map file format, not of the options themselves, and
# it is provided by this resource
# @param order an integer describing the relative order of the mapping
# represented by this resource within the target map file (default 10).
# The order matters only if the same kay is enrolled more than once
# in the map, in which case only the first is effective.
#
# @example Options given as a string
# autofs::mapping{ '/etc/auto.data_data':
# mapfile => '/etc/auto.data',
# key => 'data',
# options => 'rw,sync,suid',
# fs => 'storage_host.my.com:/path/to/data'
# }
#
# @example Options given as an array
# autofs::mapping{ '/etc/auto.data_data':
# mapfile => '/etc/auto.data',
# key => 'data',
# options => ['ro', 'noexec', 'nodev'],
# fs => 'storage_host.my.com:/path/to/data'
# }
#
# @example No options
# autofs::mapping{ '/etc/auto.data_data':
# mapfile => '/etc/auto.data',
# key => 'data',
# fs => 'storage_host.my.com:/path/to/data'
# }
#
define autofs::multi_mapping (
Stdlib::Absolutepath $mapfile,
Pattern[/\A\S+\z/] $key,
Pattern[/\S/] $fs,
Enum['present', 'absent'] $ensure = 'present',
Optional[Autofs::Options] $options = undef,
Integer $order = 10,
) {
unless $ensure == 'absent' {
# Format the options string, relying to some extent on the
# $options parameter, if specified, to indeed match the
# Autofs::Options data type
if ($options =~ Undef) or ($options =~ Array[Any,0,0]) { # an empty array
$formatted_options = ''
} else {
$prelim_options = $options ? {
Array => join($options, ','), # a non-empty array
String => $options,
default => fail('Unexpected value for parameter $options')
}
$formatted_options = $prelim_options ? {
# even though the user *shouldn't* provide the hyphen, we accommodate
# them doing so. But only at the head of the option list, not
# internally.
/\A-/ => $prelim_options,
default => "-${prelim_options}",
}
}

# Declare an appropriate fragment of the target map file
concat::fragment { "autofs::multi_mapping/${title}":
target => $mapfile,
content => " ${key} ${formatted_options} ${fs} \\\n",
order => $order,
}
}
}