Skip to content

Commit 157840c

Browse files
committed
Support configuration repositories when using mount
This patch only comes into play when using the `mount_method` of `mount` rather than the default autofs. It is now possible to specify that one particular repository on a client is the configuration repository and must be mounted first before all other repositories. This should happen during puppets initial configuration of CvmFS and also at reboot. ```puppet class{'cvmfs': mount_method => 'mount', config_repo => 'cvmfs-config.example.org', } cmvfs::mount{'myrepo.example.org':} cmvfs::mount{'cvmfs-config.example.org':} ``` In this example the repository `cvmfs-config.example.org` will be mounted before `myrepo.example.org`. Note there is all ways at most one configuration repository per client. Fixes: voxpupuli#176
1 parent 5125aa1 commit 157840c

File tree

5 files changed

+197
-46
lines changed

5 files changed

+197
-46
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ cvmfs::domain{'example.net'
4444

4545
To use puppet's mount type rather that autofs
4646
a typical configuration might be the following. This
47-
examples configures a cvmfs domain, a configuration
47+
example configures a cvmfs domain for common settings, a configuration
4848
repository and finally a particular repository for
49-
mount.
49+
mount. In this example the `cvmfs-config.example.org` has
50+
been marked as the per client configuration repository and will always
51+
be mounted first.
5052

5153
```puppet
5254
class{'cvmfs':
5355
mount_method => 'mount',
56+
config_repo => 'cvmfs-config.example.org',
5457
}
5558
cvmfs::domain{'example.org':
5659
cvmfs_server_url => 'http://web.example.org/cvmfs/@fqrn@'

REFERENCE.md

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class{'cvmfs':
109109
The following parameters are available in the `cvmfs` class:
110110

111111
* [`mount_method`](#-cvmfs--mount_method)
112+
* [`config_repo`](#-cvmfs--config_repo)
112113
* [`manage_autofs_service`](#-cvmfs--manage_autofs_service)
113114
* [`cvmfs_quota_limit`](#-cvmfs--cvmfs_quota_limit)
114115
* [`cvmfs_quota_ratio`](#-cvmfs--cvmfs_quota_ratio)
@@ -187,6 +188,17 @@ skips all mounting. Note that migrating between for instance *autofs* and then
187188

188189
Default value: `'autofs'`
189190

191+
##### <a name="-cvmfs--config_repo"></a>`config_repo`
192+
193+
Data type: `Optional[Stdlib::Fqdn]`
194+
195+
When using the `mount_method` as `mount` it may be nescessary to specify a CvmFS located configuration_repository.
196+
This is a repository containing extra cvmfs configuration required to be mounted before any other
197+
repositories. There is at most one config_repo client. In addition the config_repo must actually be mounted
198+
explicitly with a `cvmfs::mount{$config_repo:}`, this is **not** automatic.
199+
200+
Default value: `undef`
201+
190202
##### <a name="-cvmfs--manage_autofs_service"></a>`manage_autofs_service`
191203

192204
Data type: `Boolean`
@@ -961,6 +973,27 @@ cvmfs::mount{'foobar.example.org':
961973
}
962974
```
963975

976+
##### Mount a repository with mount (not automount)
977+
978+
```puppet
979+
class{ 'cvmfs':
980+
mount_method => 'mount',
981+
}
982+
cvmfs::mount{'quark.example.org':}
983+
```
984+
985+
##### Mount a repository with mount and a config_repo as well.
986+
987+
```puppet
988+
989+
class{ 'cvmfs':
990+
mount_method => 'mount',
991+
config_mount => 'cvmfs-config.example.org',
992+
}
993+
cvmfs::mount{'cvmfs-config.example.org':}
994+
cvmfs::mount{'down.example.org':}
995+
```
996+
964997
#### Parameters
965998

966999
The following parameters are available in the `cvmfs::mount` defined type:
@@ -1091,11 +1124,11 @@ Default value: `undef`
10911124

10921125
##### <a name="-cvmfs--mount--mount_method"></a>`mount_method`
10931126

1094-
Data type: `Enum['autofs','mount','none']`
1127+
Data type: `Optional[String[1]]`
10951128

1096-
Should the mount attempt be made with autofs or tranditional fstab mount. Do no use this.
1129+
Deprecated, do not set this, set mount_method for the whole client only on the main class.
10971130

1098-
Default value: `$cvmfs::mount_method`
1131+
Default value: `undef`
10991132

11001133
##### <a name="-cvmfs--mount--cvmfs_repo_list"></a>`cvmfs_repo_list`
11011134

@@ -1203,9 +1236,9 @@ Default value: `undef`
12031236

12041237
##### <a name="-cvmfs--mount--mount_options"></a>`mount_options`
12051238

1206-
Data type: `String[1]`
1239+
Data type: `Variant[String[1],Array[String[1]]]`
12071240

1208-
Mount options to use for fstab style mounting.
1241+
Mount options to use for fstab style mounting. mount_method==mount only
12091242

1210-
Default value: `'defaults,_netdev,nodev'`
1243+
Default value: `['defaults','_netdev','nodev']`
12111244

manifests/init.pp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@
5454
# The `autofs` option will configure cvmfs to be mounted with autofs. The `mount` option will
5555
# use puppet's mount type, currently adding a line to /etc/fstab. The *none* option
5656
# skips all mounting. Note that migrating between for instance *autofs* and then *mount* is not supported.
57+
# @param config_repo
58+
# When using the `mount_method` as `mount` it may be nescessary to specify a CvmFS located configuration_repository.
59+
# This is a repository containing extra cvmfs configuration required to be mounted before any other
60+
# repositories. There is at most one config_repo client. In addition the config_repo must actually be mounted
61+
# explicitly with a `cvmfs::mount{$config_repo:}`, this is **not** automatic.
5762
# @param manage_autofs_service should the autofs service be maintained.
5863
# @param cvmfs_quota_limit The cvmfs quota size in megabytes.
5964
# @param cvmfs_quota_ratio
@@ -143,6 +148,7 @@
143148
Variant[Undef,String] $cvmfs_http_proxy,
144149
Optional[Variant[Enum['absent'], Array[String[1]]]] $repo_includepkgs,
145150
Enum['autofs','mount','none'] $mount_method = 'autofs',
151+
Optional[Stdlib::Fqdn] $config_repo = undef,
146152
Boolean $manage_autofs_service = true,
147153
Integer $default_cvmfs_partsize = 10000,
148154
Variant[Enum['auto'],Integer] $cvmfs_quota_limit = 1000,

manifests/mount.pp

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@
1717
# }
1818
# }
1919
#
20+
# @example Mount a repository with mount (not automount)
21+
# class{ 'cvmfs':
22+
# mount_method => 'mount',
23+
# }
24+
# cvmfs::mount{'quark.example.org':}
25+
#
26+
# @example Mount a repository with mount and a config_repo as well.
27+
#
28+
# class{ 'cvmfs':
29+
# mount_method => 'mount',
30+
# config_mount => 'cvmfs-config.example.org',
31+
# }
32+
# cvmfs::mount{'cvmfs-config.example.org':}
33+
# cvmfs::mount{'down.example.org':}
34+
#
2035
# @param repo The fully qualified repository name to mount
2136
# @param cvmfs_quota_limit Per mount quota limit, not relavent to shared cache. Sets cvmfs_quota_limit
2237
# @param cvmfs_server_url Stratum 1 list, typically `;` delimited. Sets CVMFS_SERVER_URL parameter.
@@ -29,7 +44,7 @@
2944
# @param cvmfs_max_ttl Maximum effective TTL in seconds for DNS queries of proxy server names. Sets CVMFS_MAX_TTL
3045
# @param cvmfs_env_variables Sets per repo environments variables for magic links.
3146
# @param cvmfs_use_geoapi Set CVMFS_MAX_GEOAPI
32-
# @param mount_method Should the mount attempt be made with autofs or tranditional fstab mount. Do no use this.
47+
# @param mount_method Deprecated, do not set this, set mount_method for the whole client only on the main class.
3348
# @param cvmfs_repo_list If true the repository will added to the list of repositories maintained in `/etc/cvmfs/default.local`
3449
# @param cvmfs_mount_rw sets CVMFS_MOUNT_RW
3550
# @param cvmfs_memcache_size Sets CVMFS_MEMCACHE_SIZE in Megabytes.
@@ -43,7 +58,7 @@
4358
# @param cvmfs_external_timeout_direct Sets CVMFS_EXTERNAL_TIMEOUT_DIRECT
4459
# @param cvmfs_external_url Sets CVMFS_EXTERNAL_URL
4560
# @param cvmfs_repository_tag Sets CVMFS_REPOSITORY_TAG
46-
# @param mount_options Mount options to use for fstab style mounting.
61+
# @param mount_options Mount options to use for fstab style mounting. mount_method==mount only
4762
#
4863
define cvmfs::mount (
4964
Stdlib::Fqdn $repo = $name,
@@ -65,8 +80,8 @@
6580
Optional[Hash[Variant[Integer,String],Integer, 1]] $cvmfs_uid_map = undef,
6681
Optional[Hash[Variant[Integer,String],Integer, 1]] $cvmfs_gid_map = undef,
6782
Optional[Stdlib::Yes_no] $cvmfs_follow_redirects = undef,
68-
String[1] $mount_options = 'defaults,_netdev,nodev',
69-
Enum['autofs','mount','none'] $mount_method = $cvmfs::mount_method,
83+
Variant[String[1],Array[String[1]]] $mount_options = ['defaults','_netdev','nodev'],
84+
Optional[String[1]] $mount_method = undef,
7085
Optional[String] $cvmfs_external_fallback_proxy = undef,
7186
Optional[String] $cvmfs_external_http_proxy = undef,
7287
Optional[Integer] $cvmfs_external_timeout = undef,
@@ -76,6 +91,19 @@
7691
) {
7792
include cvmfs
7893

94+
#
95+
# deprecations
96+
#
97+
if $mount_method {
98+
deprecation("mount_method on cvmfs::mount{${repo}:}", 'Never set mount method on a cvmfs::mount. It should only ever be set on the main class for the whole client')
99+
}
100+
if $mount_options =~ String {
101+
deprecation("mount_options on cvmfs::mount{${repo}:}", 'Setting mount_options as a string is deprecated, set as an array of options instead')
102+
$_mount_options = $mount_options.split(',')
103+
} else {
104+
$_mount_options = $mount_options
105+
}
106+
79107
$_cvmfs_id_map_file_prefix = "/etc/cvmfs/config.d/${repo}"
80108
if $cvmfs_uid_map {
81109
cvmfs::id_map { "${_cvmfs_id_map_file_prefix}.uid_map":
@@ -130,18 +158,29 @@
130158
content => "${repo},",
131159
}
132160
}
133-
if $mount_method == 'mount' {
161+
if $cvmfs::mount_method == 'mount' {
134162
file { "/cvmfs/${repo}":
135163
ensure => directory,
136164
owner => 'cvmfs',
137165
group => 'cvmfs',
138166
require => Package['cvmfs'],
139167
}
168+
169+
#
170+
# Require the config repo for all repos except the config_repo
171+
#
172+
if $cvmfs::config_repo and $cvmfs::config_repo != $repo {
173+
$_my_mount_options = $_mount_options + ["x-systemd.requires-mounts-for=/cvmfs/${cvmfs::config_repo}"]
174+
Mount["/cvmfs/${cvmfs::config_repo}"] -> Mount["/cvmfs/${repo}"]
175+
} else {
176+
$_my_mount_options = $_mount_options
177+
}
178+
140179
mount { "/cvmfs/${repo}":
141180
ensure => mounted,
142181
device => $repo,
143182
fstype => 'cvmfs',
144-
options => $mount_options,
183+
options => $_my_mount_options.unique.join(','),
145184
atboot => true,
146185
require => [File["/cvmfs/${repo}"],File["/etc/cvmfs/config.d/${repo}.local"],Concat['/etc/cvmfs/default.local'],File['/etc/fuse.conf']],
147186
}

spec/defines/mount_spec.rb

Lines changed: 102 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
require 'spec_helper'
44

55
describe 'cvmfs::mount' do
6-
let(:pre_condition) do
7-
'class{"cvmfs": cvmfs_http_proxy => undef}'
8-
end
96
let(:title) { 'files.example.org' }
107

118
on_supported_os.each do |os, facts|
129
context "on #{os}" do
10+
let(:pre_condition) do
11+
['class{"cvmfs": cvmfs_http_proxy => undef}']
12+
end
13+
1314
let(:facts) do
1415
facts
1516
end
@@ -22,19 +23,25 @@
2223
it { is_expected.to compile.with_all_deps }
2324

2425
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local') }
25-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with_content("# cvmfs files.example.org.local file installed with puppet.\n# this files overrides and extends the values contained\n# within the files.example.org.conf file.\n\n") }
26-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without_content(%r{.*CVMFS_MEMCACHE_SIZE.*$}) }
27-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without_content(%r{.*CVMFS_USE_GEOAPI.*$}) }
28-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without_content(%r{.*CVMFS_FOLLOW_REDIRECTS.*$}) }
29-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without_content(%r{.*CVMFS_CLAIM_OWNERSHIP.*$}) }
30-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without_content(%r{.*CVMFS_REPOSITORY_TAG.*$}) }
31-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_HTTP_PROXY.*$}) }
32-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_QUOTA_LIMIT.*$}) }
33-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_EXTERNAL_FALLBACK_PROXY=.*$}) }
34-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_EXTERNAL_HTTP_PROXY=.*$}) }
35-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_EXTERNAL_TIMEOUT=.*$}) }
36-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_EXTERNAL_TIMEOUT_DIRECT=.*$}) }
37-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').without('content' => %r{^CVMFS_EXTERNAL_URL=.*$}) }
26+
27+
it {
28+
is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').
29+
without_content(%r{.*CVMFS_MEMCACHE_SIZE.*$}).
30+
without_content(%r{.*CVMFS_USE_GEOAPI.*$}).
31+
without_content(%r{.*CVMFS_FOLLOW_REDIRECTS.*$}).
32+
without_content(%r{.*CVMFS_CLAIM_OWNERSHIP.*$}).
33+
without_content(%r{.*CVMFS_REPOSITORY_TAG.*$}).
34+
without_content(%r{^CVMFS_HTTP_PROXY.*$}).
35+
without_content(%r{^CVMFS_QUOTA_LIMIT.*$}).
36+
without_content(%r{^CVMFS_EXTERNAL_FALLBACK_PROXY=.*$}).
37+
without_content(%r{^CVMFS_EXTERNAL_HTTP_PROXY=.*$}).
38+
without_content(%r{^CVMFS_EXTERNAL_TIMEOUT=.*$}).
39+
without_content(%r{^CVMFS_EXTERNAL_TIMEOUT_DIRECT=.*$}).
40+
without_content(%r{^CVMFS_EXTERNAL_URL=.*$}).
41+
with_content("# cvmfs files.example.org.local file installed with puppet.\n# this files overrides and extends the values contained\n# within the files.example.org.conf file.\n\n")
42+
}
43+
44+
it { is_expected.not_to contain_mount('/cvmfs/files.example.org') }
3845

3946
context 'with lots of parameters set' do
4047
let(:params) do
@@ -56,23 +63,86 @@
5663
}
5764
end
5865

59-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_MEMCACHE_SIZE=2000$}) }
60-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_USE_GEOAPI='yes'$}) }
61-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_FOLLOW_REDIRECTS='yes'$}) }
62-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_CLAIM_OWNERSHIP='yes'$}) }
63-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_REPOSITORY_TAG='testing'$}) }
64-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_UID_MAP='/etc/cvmfs/config.d/files.example.org.uid_map'$}) }
65-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_GID_MAP='/etc/cvmfs/config.d/files.example.org.gid_map'$}) }
66-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_QUOTA_LIMIT='54321'$}) }
67-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_KEYS_DIR='/etc/cvmfs/keys/example.org'$}) }
68-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_EXTERNAL_FALLBACK_PROXY='http://external-fallback.example.org:3128'$}) }
69-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_EXTERNAL_HTTP_PROXY='http://http-proxy.example.org:2138'$}) }
70-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_EXTERNAL_TIMEOUT='100'$}) }
71-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_EXTERNAL_TIMEOUT_DIRECT='450'$}) }
72-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with('content' => %r{^CVMFS_EXTERNAL_URL='http://external-url.example.org:80'$}) }
73-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.uid_map').with('content' => %r{^123 12$}) }
74-
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.gid_map').with('content' => %r{^137 42$}) }
66+
it {
67+
is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.local').with_content(%r{^CVMFS_MEMCACHE_SIZE=2000$}).
68+
with_content(%r{^CVMFS_USE_GEOAPI='yes'$}).
69+
with_content(%r{^CVMFS_FOLLOW_REDIRECTS='yes'$}).
70+
with_content(%r{^CVMFS_CLAIM_OWNERSHIP='yes'$}).
71+
with_content(%r{^CVMFS_REPOSITORY_TAG='testing'$}).
72+
with_content(%r{^CVMFS_UID_MAP='/etc/cvmfs/config.d/files.example.org.uid_map'$}).
73+
with_content(%r{^CVMFS_GID_MAP='/etc/cvmfs/config.d/files.example.org.gid_map'$}).
74+
with_content(%r{^CVMFS_QUOTA_LIMIT='54321'$}).
75+
with_content(%r{^CVMFS_KEYS_DIR='/etc/cvmfs/keys/example.org'$}).
76+
with_content(%r{^CVMFS_EXTERNAL_FALLBACK_PROXY='http://external-fallback.example.org:3128'$}).
77+
with_content(%r{^CVMFS_EXTERNAL_HTTP_PROXY='http://http-proxy.example.org:2138'$}).
78+
with_content(%r{^CVMFS_EXTERNAL_TIMEOUT='100'$}).
79+
with_content(%r{^CVMFS_EXTERNAL_TIMEOUT_DIRECT='450'$}).
80+
with_content(%r{^CVMFS_EXTERNAL_URL='http://external-url.example.org:80'$})
81+
}
82+
83+
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.uid_map').with_content(%r{^123 12$}) }
84+
it { is_expected.to contain_file('/etc/cvmfs/config.d/files.example.org.gid_map').with_content(%r{^137 42$}) }
85+
end
86+
end
87+
88+
context 'with mount_method mount set on main class' do
89+
let(:pre_condition) do
90+
'class{"cvmfs": cvmfs_http_proxy => undef, mount_method => "mount"}'
7591
end
92+
93+
it { is_expected.to compile.with_all_deps }
94+
95+
it {
96+
is_expected.to contain_mount('/cvmfs/files.example.org').with(
97+
options: 'defaults,_netdev,nodev',
98+
device: 'files.example.org'
99+
)
100+
}
101+
102+
context 'with mount_options set to an array' do
103+
let(:params) do
104+
{
105+
mount_options: %w[one two three],
106+
}
107+
end
108+
109+
it { is_expected.to contain_mount('/cvmfs/files.example.org').with_options('one,two,three') }
110+
end
111+
112+
context 'with mount_options set to a string' do
113+
let(:params) do
114+
{
115+
mount_options: 'four,five,six',
116+
}
117+
end
118+
119+
it { is_expected.to contain_mount('/cvmfs/files.example.org').with_options('four,five,six') }
120+
end
121+
end
122+
123+
context 'with mount_method mount and a config_repo set on main class' do
124+
let(:pre_condition) do
125+
[
126+
'class{"cvmfs": cvmfs_http_proxy => undef, mount_method => "mount", config_repo => "cvmfs-config.example.org"}',
127+
'cvmfs::mount{"cvmfs-config.example.org":}',
128+
]
129+
end
130+
131+
it { is_expected.to compile.with_all_deps }
132+
133+
it {
134+
is_expected.to contain_mount('/cvmfs/files.example.org').with(
135+
options: 'defaults,_netdev,nodev,x-systemd.requires-mounts-for=/cvmfs/cvmfs-config.example.org',
136+
device: 'files.example.org'
137+
)
138+
}
139+
140+
it {
141+
is_expected.to contain_mount('/cvmfs/cvmfs-config.example.org').with(
142+
options: 'defaults,_netdev,nodev',
143+
device: 'cvmfs-config.example.org'
144+
)
145+
}
76146
end
77147
end
78148
end

0 commit comments

Comments
 (0)