summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlib/puppet/filetype.rb32
-rwxr-xr-xlib/puppet/type/parsedtype/mount.rb64
-rwxr-xr-xtest/types/mount.rb42
3 files changed, 111 insertions, 27 deletions
diff --git a/lib/puppet/filetype.rb b/lib/puppet/filetype.rb
index c13c740f0..9054fddbe 100755
--- a/lib/puppet/filetype.rb
+++ b/lib/puppet/filetype.rb
@@ -208,19 +208,32 @@ module Puppet
# Treat netinfo tables as a single file, just for simplicity of certain types
newfiletype(:netinfo) do
+ class << self
+ attr_accessor :format
+ end
def read
%x{nidump -r /#{@path} /}
end
# This really only makes sense for cron tabs.
def remove
- raise TypeError, "Cannot remove netinfo tables"
+ %x{nireport / /#{@path} name}.split("\n").each do |name|
+ newname = name.gsub(/\//, '\/').sub(/\s+$/, '')
+ output = %x{niutil -destroy / '/#{@path}/#{newname}'}
+
+ unless $? == 0
+ raise Puppet::Error, "Could not remove %s from %s" %
+ [name, @path]
+ end
+ end
end
# Convert our table to an array of hashes. This only works for handling one
# table at a time.
def to_array(text = nil)
- text ||= read
+ unless text
+ text = read
+ end
hash = nil
@@ -260,9 +273,22 @@ module Puppet
end
def write(text)
- IO.popen("niload -d #{@path} .", "w") { |p|
+ text.gsub!(/^#.*\n/,'')
+ text.gsub!(/^$/,'')
+ if text == "" or text == "\n"
+ self.remove
+ return
+ end
+ unless format = self.class.format
+ raise Puppe::DevError, "You must define the NetInfo format to inport"
+ end
+ IO.popen("niload -d #{format} . 1>/dev/null 2>/dev/null", "w") { |p|
p.print text
}
+
+ unless $? == 0
+ raise ArgumentError, "Failed to write %s" % @path
+ end
end
end
end
diff --git a/lib/puppet/type/parsedtype/mount.rb b/lib/puppet/type/parsedtype/mount.rb
index 08f797f72..5311de1fb 100755
--- a/lib/puppet/type/parsedtype/mount.rb
+++ b/lib/puppet/type/parsedtype/mount.rb
@@ -95,17 +95,36 @@ module Puppet
@instances = []
- case Facter["operatingsystem"].value
+ @platform = Facter["operatingsystem"].value
+ case @platform
when "Solaris":
@path = "/etc/vfstab"
@fields = [:device, :blockdevice, :path, :fstype, :pass, :atboot,
:options]
+ when "Darwin":
+ @filetype = Puppet::FileType.filetype(:netinfo)
+ @filetype.format = "fstab"
+ @path = "mounts"
+ @fields = [:device, :path, :fstype, :options, :dump, :pass]
+
+ # How to map the dumped table to what we want
+ @fieldnames = {
+ "name" => :device,
+ "dir" => :path,
+ "dump_freq" => :dump,
+ "passno" => :pass,
+ "vfstype" => :fstype,
+ "opts" => :options
+ }
else
@path = "/etc/fstab"
@fields = [:device, :path, :fstype, :options, :dump, :pass]
end
- @filetype = Puppet::FileType.filetype(:flat)
+ # Allow Darwin to override the default filetype
+ unless defined? @filetype
+ @filetype = Puppet::FileType.filetype(:flat)
+ end
# Parse a mount tab.
#
@@ -113,6 +132,11 @@ module Puppet
# mounts in order, mostly so that comments are retained in the
# order they were written and in proximity to the same fses.
def self.parse(text)
+ # provide a single exception for darwin & netinfo
+ if @filetype == Puppet::FileType.filetype(:netinfo)
+ parseninfo(text)
+ return
+ end
count = 0
hash = {}
text.chomp.split("\n").each { |line|
@@ -138,6 +162,30 @@ module Puppet
}
end
+ # Parse a netinfo table.
+ def self.parseninfo(text)
+ array = @fileobj.to_array(text)
+
+ hash = {}
+ array.each do |record|
+ @fieldnames.each do |name, field|
+ if value = record[name]
+ if field == :options
+ hash[field] = value.join(",")
+ else
+ hash[field] = value[0]
+ end
+ else
+ raise ArgumentError, "Field %s was not provided" % [name]
+ end
+ end
+
+
+ hash2obj(hash)
+ hash.clear
+ end
+ end
+
# This only works when the mount point is synced to the fstab.
def mount
output = %x{mount #{self[:path]} 2>&1}
@@ -158,9 +206,14 @@ module Puppet
# Is the mount currently mounted?
def mounted?
+ platform = Facter["operatingsystem"].value
%x{df}.split("\n").find do |line|
fs = line.split(/\s+/)[-1]
- fs == self[:path]
+ if platform == "Darwin"
+ fs == "/private/var/automount" + self[:path]
+ else
+ fs == self[:path]
+ end
end
end
@@ -170,11 +223,6 @@ module Puppet
if value = self.value(field)
value
else
- if @states.include? field
- self.warning @states[field].inspect
- else
- self.warning field.inspect
- end
raise Puppet::Error,
"Could not retrieve value for %s" % field
end
diff --git a/test/types/mount.rb b/test/types/mount.rb
index 7641fd2cb..64bfa9300 100755
--- a/test/types/mount.rb
+++ b/test/types/mount.rb
@@ -30,8 +30,8 @@ class TestMounts < Test::Unit::TestCase
# but does not modify our actual system.
def mkfaketype
pfile = tempfile()
- old = @mounttype.path
- @mounttype.path = pfile
+ old = @mounttype.filetype
+ @mounttype.filetype = Puppet::FileType.filetype(:ram)
cleanup do
@mounttype.path = old
@@ -123,12 +123,14 @@ class TestMounts < Test::Unit::TestCase
Puppet::Type.type(:mount).retrieve
}
+ oldtype = Puppet::Type.type(:mount).filetype
+
# Now switch to storing in ram
mkfaketype
fs = mkmount
- assert(Puppet::Type.type(:mount).path != "/etc/fstab")
+ assert(Puppet::Type.type(:mount).filetype != oldtype)
assert_events([:mount_created], fs)
@@ -157,22 +159,33 @@ class TestMounts < Test::Unit::TestCase
fs = nil
case Facter["hostname"].value
when "culain": fs = "/ubuntu"
+ when "atalanta": fs = "/mnt"
else
$stderr.puts "No mount for mount testing; skipping"
return
end
- backup = tempfile()
+ assert_nothing_raised {
+ Puppet.type(:mount).retrieve
+ }
+
+ oldtext = Puppet::Type.type(:mount).fileobj.read
- FileUtils.cp(Puppet::Type.type(:mount).path, backup)
+ ftype = Puppet::Type.type(:mount).filetype
# Make sure the original gets reinstalled.
- cleanup do
- FileUtils.cp(backup, Puppet::Type.type(:mount).path)
+ if ftype == Puppet::FileType.filetype(:netinfo)
+ cleanup do
+ IO.popen("niload -r /mounts .", "w") do |file|
+ file.puts oldtext
+ end
+ end
+ else
+ cleanup do
+ Puppet::Type.type(:mount).fileobj.write(oldtext)
+ end
end
- Puppet.type(:mount).retrieve
-
obj = Puppet.type(:mount)[fs]
assert(obj, "Could not retrieve %s object" % fs)
@@ -218,18 +231,14 @@ class TestMounts < Test::Unit::TestCase
assert(text !~ /#{fs}/,
"Fstab still contains %s" % fs)
- assert_raise(Puppet::Error, "Removed mount did not throw an error") {
- obj.mount
- }
-
assert_nothing_raised {
obj[:ensure] = :present
}
assert_events([:mount_created], obj)
- assert(File.read(Puppet.type(:mount).path) =~ /#{fs}/,
- "Fstab does not contain %s" % fs)
+ text = Puppet::Type.type(:mount).fileobj.read
+ assert(text =~ /#{fs}/, "Fstab does not contain %s" % fs)
assert(! obj.mounted?, "Object is mounted incorrectly")
@@ -239,7 +248,8 @@ class TestMounts < Test::Unit::TestCase
assert_events([:mount_mounted], obj)
- assert(File.read(Puppet.type(:mount).path) =~ /#{fs}/,
+ text = Puppet::Type.type(:mount).fileobj.read
+ assert(text =~ /#{fs}/,
"Fstab does not contain %s" % fs)
assert(obj.mounted?, "Object is not mounted")