1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
require 'puppet/provider/parsedfile'
require 'puppet/provider/mount'
fstab = nil
case Facter.value(:operatingsystem)
when "Solaris"; fstab = "/etc/vfstab"
else
fstab = "/etc/fstab"
end
Puppet::Type.type(:mount).provide(
:parsed,
:parent => Puppet::Provider::ParsedFile,
:default_target => fstab,
:filetype => :flat
) do
include Puppet::Provider::Mount
commands :mountcmd => "mount", :umount => "umount"
case Facter["operatingsystem"]
when "Solaris"
@fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
else
@fields = [:device, :name, :fstype, :options, :dump, :pass]
@fielddefaults = [ nil ] * 4 + [ "0", "2" ]
end
text_line :comment, :match => /^\s*#/
text_line :blank, :match => /^\s*$/
optional_fields = @fields - [:device, :name, :blockdevice]
mandatory_fields = @fields - optional_fields
# fstab will ignore lines that have fewer than the mandatory number of columns,
# so we should, too.
field_pattern = '(\s*(?>\S+))'
text_line :incomplete, :match => /^(?!#{field_pattern}{#{mandatory_fields.length}})/
record_line self.name, :fields => @fields, :separator => /\s+/, :joiner => "\t", :optional => optional_fields
# Every entry in fstab is :unmounted until we can prove different
def self.prefetch_hook(target_records)
target_records.collect do |record|
record[:ensure] = :unmounted if record[:record_type] == :parsed
record
end
end
def self.prefetch(resources = nil)
# Get providers for all resources the user defined and that match
# a record in /etc/fstab.
super
# We need to do two things now:
# - Update ensure from :unmounted to :mounted if the resource is mounted
# - Check for mounted devices that are not in fstab and
# set ensure to :ghost (if the user wants to add an entry
# to fstab we need to know if the device was mounted before)
mountinstances.each do |hash|
if mount = resources[hash[:name]]
case mount.provider.get(:ensure)
when :absent # Mount not in fstab
mount.provider.set(:ensure => :ghost)
when :unmounted # Mount in fstab
mount.provider.set(:ensure => :mounted)
end
end
end
end
def self.mountinstances
# XXX: Will not work for mount points that have spaces in path (does fstab support this anyways?)
regex = case Facter.value(:operatingsystem)
when "Darwin"
/ on (?:\/private\/var\/automount)?(\S*)/
when "Solaris", "HP-UX"
/^(\S*) on /
when "AIX"
/^(?:\S*\s+\S+\s+)(\S+)/
else
/ on (\S*)/
end
instances = []
mount_output = mountcmd.split("\n")
if mount_output.length >= 2 and mount_output[1] =~ /^[- \t]*$/
# On some OSes (e.g. AIX) mount output begins with a header line
# followed by a line consisting of dashes and whitespace.
# Discard these two lines.
mount_output[0..1] = []
end
mount_output.each do |line|
if match = regex.match(line) and name = match.captures.first
instances << {:name => name, :mounted => :yes} # Only :name is important here
else
raise Puppet::Error, "Could not understand line #{line} from mount output"
end
end
instances
end
end
|