summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-10-17 21:38:30 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-10-17 21:38:30 +0000
commit95f2fe70bf63791fb691d539281f5cfbfd1fb664 (patch)
treebde480ce5ada8ea2abbc5fecf8f5c9aa3ca2aabf
parent86dae84dad4cd5688029c398109b15b6074cf3c4 (diff)
downloadpuppet-95f2fe70bf63791fb691d539281f5cfbfd1fb664.tar.gz
puppet-95f2fe70bf63791fb691d539281f5cfbfd1fb664.tar.xz
puppet-95f2fe70bf63791fb691d539281f5cfbfd1fb664.zip
Ported mount over to using providers
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1801 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r--lib/puppet/metatype/attributes.rb1
-rw-r--r--lib/puppet/metatype/providers.rb2
-rw-r--r--lib/puppet/provider.rb11
-rwxr-xr-xlib/puppet/provider/mount/parsed.rb174
-rwxr-xr-xlib/puppet/type/host.rb2
-rwxr-xr-xlib/puppet/type/mount.rb113
-rwxr-xr-xlib/puppet/type/parsedtype/mount.rb271
-rw-r--r--test/lib/puppettest/fakes.rb30
-rw-r--r--test/lib/puppettest/support/utils.rb13
-rwxr-xr-xtest/providers/parsedmount.rb213
-rwxr-xr-xtest/types/mount.rb274
11 files changed, 622 insertions, 482 deletions
diff --git a/lib/puppet/metatype/attributes.rb b/lib/puppet/metatype/attributes.rb
index d647e174f..764aba8ee 100644
--- a/lib/puppet/metatype/attributes.rb
+++ b/lib/puppet/metatype/attributes.rb
@@ -304,6 +304,7 @@ class Puppet::Type
def self.validattr?(name)
name = symbolize(name)
+ return true if name == :name
@validattrs ||= {}
unless @validattrs.include?(name)
diff --git a/lib/puppet/metatype/providers.rb b/lib/puppet/metatype/providers.rb
index ab7371f10..c59b7f84a 100644
--- a/lib/puppet/metatype/providers.rb
+++ b/lib/puppet/metatype/providers.rb
@@ -167,7 +167,7 @@ class Puppet::Type
provider.suitable?
}.collect { |name, provider|
provider
- }
+ }.reject { |p| p.name == :fake } # For testing
end
def provider=(name)
diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb
index 88a7ba8a6..e0f465159 100644
--- a/lib/puppet/provider.rb
+++ b/lib/puppet/provider.rb
@@ -7,6 +7,7 @@ class Puppet::Provider
class << self
# Include the util module so we have access to things like 'binary'
include Puppet::Util, Puppet::Util::Docs
+ include Puppet::Util::Logging
attr_accessor :name, :model
attr_writer :doc
end
@@ -127,15 +128,18 @@ class Puppet::Provider
when :exists:
values.each do |value|
unless value and FileTest.exists? value
+ debug "Not suitable: missing %s" % value
return false
end
end
when :true:
values.each do |v|
+ debug "Not suitable: false value"
return false unless v
end
when :false:
values.each do |v|
+ debug "Not suitable: true value"
return false if v
end
else # Just delegate everything else to facter
@@ -145,6 +149,7 @@ class Puppet::Provider
found = values.find do |v|
result == v.to_s.downcase.intern
end
+ debug "Not suitable: %s not in %s" [check, values]
return false unless found
else
return false
@@ -155,6 +160,12 @@ class Puppet::Provider
return true
end
+ def self.to_s
+ unless defined? @str
+ @str = "%s provider %s" % [@model.name, self.name]
+ end
+ end
+
dochook(:defaults) do
if @defaults.length > 0
return " Default for " + @defaults.collect do |f, v|
diff --git a/lib/puppet/provider/mount/parsed.rb b/lib/puppet/provider/mount/parsed.rb
new file mode 100755
index 000000000..5e9a6cf1d
--- /dev/null
+++ b/lib/puppet/provider/mount/parsed.rb
@@ -0,0 +1,174 @@
+require 'puppet/provider/parsedfile'
+
+Puppet::Type.type(:mount).provide :parsed, :parent => Puppet::Provider::ParsedFile do
+ @filetype = Puppet::FileType.filetype(:flat)
+
+ commands :mount => "mount", :umount => "umount", :df => "df"
+
+ def self.init
+ @platform = Facter["operatingsystem"].value
+ case @platform
+ when "Solaris":
+ @path = "/etc/vfstab"
+ @fields = [:device, :blockdevice, :path, :fstype, :pass, :atboot,
+ :options]
+ @fielddefaults = [ nil ] * @fields.size
+ when "Darwin":
+ @filetype = Puppet::FileType.filetype(:netinfo)
+ @filetype.format = "fstab"
+ @path = "mounts"
+ @fields = [:device, :path, :fstype, :options, :dump, :pass]
+ @fielddefaults = [ nil ] * @fields.size
+
+ # 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]
+ @fielddefaults = [ nil ] * 4 + [ "0", "2" ]
+ end
+
+ # Allow Darwin to override the default filetype
+ unless defined? @filetype
+ @filetype = Puppet::FileType.filetype(:flat)
+ end
+ end
+
+ init
+
+ # XXX This needs to change to being a netinfo provider
+ unless @platform == "Darwin"
+ confine :exists => @path
+ end
+
+ def self.clear
+ init
+ super
+ end
+
+ # Parse a mount tab.
+ #
+ # This method also stores existing comments, and it stores all
+ # 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)
+ return parseninfo(text)
+ end
+ count = 0
+
+ instances = []
+ text.chomp.split("\n").each { |line|
+ hash = {}
+ case line
+ when /^#/, /^\s*$/:
+ # add comments and blank lines to the list as they are
+ instances << line
+ comment(line)
+ else
+ values = line.split(/\s+/)
+ if @fields.length < values.length
+ raise Puppet::Error, "Could not parse line %s" % line
+ end
+
+ values = @fielddefaults.zip(values).collect { |d, v| v || d }
+ unless @fields.length == values.length
+ raise Puppet::Error, "Could not parse line %s" % line
+ end
+
+ @fields.zip(values).each do |field, value|
+ hash[field] = value
+ end
+
+ instances << hash
+ count += 1
+ end
+ }
+
+ return instances
+ end
+
+ # Parse a netinfo table.
+ def self.parseninfo(text)
+ array = @fileobj.to_array(text)
+
+ instances = []
+ array.each do |record|
+ hash = {}
+ @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
+
+ instances << hash
+ end
+
+ return instances
+ end
+
+ # Convert the current object into an fstab-style string.
+ def self.to_record(hash)
+ self.fields.collect do |field|
+ if value = hash[field]
+ value
+ else
+ raise Puppet::Error,
+ "Could not retrieve value for %s" % field
+ end
+ end.join("\t")
+ end
+
+ # This only works when the mount point is synced to the fstab.
+ def mount
+ output = %x{#{command(:mount)} #{@model[:path]} 2>&1}
+
+ unless $? == 0
+ raise Puppet::Error, "Could not mount %s: %s" % [@model[:path], output]
+ end
+ end
+
+ # This only works when the mount point is synced to the fstab.
+ def unmount
+ output = %x{#{command(:umount)} #{@model[:path]}}
+
+ unless $? == 0
+ raise Puppet::Error, "Could not unmount %s" % @model[:path]
+ end
+ end
+
+ # Is the mount currently mounted?
+ def mounted?
+ platform = Facter["operatingsystem"].value
+ df = command(:df)
+ case Facter["operatingsystem"].value
+ # Solaris's df prints in a very weird format
+ when "Solaris": df = "#{command(:df)} -k"
+ end
+ %x{#{df}}.split("\n").find do |line|
+ fs = line.split(/\s+/)[-1]
+ if platform == "Darwin"
+ fs == "/private/var/automount" + @model[:path] or
+ fs == @model[:path]
+ else
+ fs == @model[:path]
+ end
+ end
+ end
+end
+
+# $Id$
diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb
index d68fe25a2..b2ed848fc 100755
--- a/lib/puppet/type/host.rb
+++ b/lib/puppet/type/host.rb
@@ -3,7 +3,7 @@ require 'puppet/type/parsedtype'
module Puppet
newtype(:host, Puppet::Type::ParsedType) do
newstate(:ip) do
- desc "The host's IP address."
+ desc "The host's IP address, IPv4 or IPv6."
end
newstate(:alias) do
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
new file mode 100755
index 000000000..b92ab735b
--- /dev/null
+++ b/lib/puppet/type/mount.rb
@@ -0,0 +1,113 @@
+require 'puppet/type/parsedtype'
+
+module Puppet
+ newtype(:mount, Puppet::Type::ParsedType) do
+ # Use the normal parent class, because we actually want to
+ # call code when sync() is called.
+ newstate(:ensure, :parent => Puppet::State) do
+ desc "Control what to do with this mount. If the value is
+ ``present``, the mount is entered into the mount table,
+ but not mounted, if it is ``absent``, the entry is removed
+ from the mount table and the filesystem is unmounted if
+ currently mounted, if it is ``mounted``, the filesystem
+ is entered into the mount table and mounted."
+
+ newvalue(:present, :event => :mount_created) do
+ end
+
+ newvalue(:absent, :event => :mount_deleted) do
+ if provider.mounted?
+ provider.unmount
+ end
+ end
+
+ newvalue(:mounted, :event => :mount_mounted) do
+ # We have to flush any changes to disk.
+ @parent.flush
+
+ provider.mount
+ end
+
+ defaultto do
+ if @parent.managed?
+ :mounted
+ else
+ nil
+ end
+ end
+
+ def retrieve
+ if provider.mounted?
+ return :mounted
+ else
+ val = super()
+ return val
+ end
+ end
+ end
+
+ newstate(:device) do
+ desc "The device providing the mount. This can be whatever
+ device is supporting by the mount, including network
+ devices or devices specified by UUID rather than device
+ path, depending on the operating system."
+ end
+
+ # Solaris specifies two devices, not just one.
+ newstate(:blockdevice) do
+ desc "The the device to fsck. This is state is only valid
+ on Solaris, and in most cases will default to the correct
+ value."
+
+ # Default to the device but with "dsk" replaced with "rdsk".
+ defaultto do
+ if Facter["operatingsystem"].value == "Solaris"
+ device = @parent.value(:device)
+ if device =~ %r{/dsk/}
+ device.sub(%r{/dsk/}, "/rdsk/")
+ else
+ nil
+ end
+ else
+ nil
+ end
+ end
+ end
+
+ newstate(:fstype) do
+ desc "The mount type. Valid values depend on the
+ operating system."
+ end
+
+ newstate(:options) do
+ desc "Mount options for the mounts, as they would
+ appear in the fstab."
+ end
+
+ newstate(:pass) do
+ desc "The pass in which the mount is checked."
+ end
+
+ newstate(:atboot) do
+ desc "Whether to mount the mount at boot. Not all platforms
+ support this."
+ end
+
+ newstate(:dump) do
+ desc "Whether to dump the mount. Not all platforms
+ support this."
+ end
+
+ newparam(:path) do
+ desc "The mount path for the mount."
+
+ isnamevar
+ end
+
+ @doc = "Manages mounted mounts, including putting mount
+ information into the mount table. The actual behavior depends
+ on the value of the 'ensure' parameter."
+ end
+end
+
+# $Id$
diff --git a/lib/puppet/type/parsedtype/mount.rb b/lib/puppet/type/parsedtype/mount.rb
deleted file mode 100755
index 3f186ddca..000000000
--- a/lib/puppet/type/parsedtype/mount.rb
+++ /dev/null
@@ -1,271 +0,0 @@
-require 'etc'
-require 'facter'
-require 'puppet/type/parsedtype'
-require 'puppet/type/state'
-
-module Puppet
- newtype(:mount, Puppet::Type::ParsedType) do
- ensurable do
- desc "Control what to do with this mount. If the value is
- ``present``, the mount is entered into the mount table,
- but not mounted, if it is ``absent``, the entry is removed
- from the mount table and the filesystem is unmounted if
- currently mounted, if it is ``mounted``, the filesystem
- is entered into the mount table and mounted."
-
- newvalue(:present) do
- @parent.create()
- end
-
- newvalue(:absent) do
- @parent.destroy()
-
- if @parent.mounted?
- @parent.unmount
- end
-
- :mount_removed
- end
-
- newvalue(:mounted) do
- if @is == :absent
- set_present
- end
-
- @parent.mount
-
- :mount_mounted
- end
-
- def retrieve
- if @parent.mounted?
- @is = :mounted
- else
- val = super()
- @is = val
- end
- end
- end
-
- newstate(:device) do
- desc "The device providing the mount. This can be whatever
- device is supporting by the mount, including network
- devices or devices specified by UUID rather than device
- path, depending on the operating system."
- end
-
- # Solaris specifies two devices, not just one.
- newstate(:blockdevice) do
- desc "The the device to fsck. This is state is only valid
- on Solaris, and in most cases will default to the correct
- value."
-
- # Default to the device but with "dsk" replaced with "rdsk".
- defaultto do
- if Facter["operatingsystem"].value == "Solaris"
- device = @parent.value(:device)
- if device =~ %r{/dsk/}
- device.sub(%r{/dsk/}, "/rdsk/")
- else
- nil
- end
- else
- nil
- end
- end
- end
-
- newstate(:fstype) do
- desc "The mount type. Valid values depend on the
- operating system."
- end
-
- newstate(:options) do
- desc "Mount options for the mounts, as they would
- appear in the fstab."
- end
-
- newstate(:pass) do
- desc "The pass in which the mount is checked."
- end
-
- newstate(:atboot) do
- desc "Whether to mount the mount at boot. Not all platforms
- support this."
- end
-
- newstate(:dump) do
- desc "Whether to dump the mount. Not all platforms
- support this."
- end
-
- newparam(:path) do
- desc "The mount path for the mount."
-
- isnamevar
- end
-
- @doc = "Manages mounted mounts, including putting mount
- information into the mount table. The actual behavior depends
- on the value of the 'ensure' parameter."
-
- def self.init
- @platform = Facter["operatingsystem"].value
- case @platform
- when "Solaris":
- @path = "/etc/vfstab"
- @fields = [:device, :blockdevice, :path, :fstype, :pass, :atboot,
- :options]
- @defaults = [ nil ] * @fields.size
- when "Darwin":
- @filetype = Puppet::FileType.filetype(:netinfo)
- @filetype.format = "fstab"
- @path = "mounts"
- @fields = [:device, :path, :fstype, :options, :dump, :pass]
- @defaults = [ nil ] * @fields.size
-
- # 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]
- @defaults = [ nil ] * 4 + [ "0", "2" ]
- end
-
- # Allow Darwin to override the default filetype
- unless defined? @filetype
- @filetype = Puppet::FileType.filetype(:flat)
- end
- end
-
- init
-
- def self.clear
- init
- super
- end
-
- # Parse a mount tab.
- #
- # This method also stores existing comments, and it stores all
- # 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|
- case line
- when /^#/, /^\s*$/:
- # add comments and blank lines to the list as they are
- comment(line)
- else
- values = line.split(/\s+/)
- if @fields.length < values.length
- raise Puppet::Error, "Could not parse line %s" % line
- end
-
- values = @defaults.zip(values).collect { |d, v| v || d }
- unless @fields.length == values.length
- raise Puppet::Error, "Could not parse line %s" % line
- end
-
- @fields.zip(values).each do |field, value|
- hash[field] = value
- end
-
- hash2obj(hash)
-
- hash.clear
- count += 1
- end
- }
- 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}
-
- unless $? == 0
- raise Puppet::Error, "Could not mount %s: %s" % [self[:path], output]
- end
- end
-
- # This only works when the mount point is synced to the fstab.
- def unmount
- output = %x{umount #{self[:path]}}
-
- unless $? == 0
- raise Puppet::Error, "Could not mount %s" % self[:path]
- end
- end
-
- # Is the mount currently mounted?
- def mounted?
- platform = Facter["operatingsystem"].value
- df = "df"
- case Facter["operatingsystem"].value
- # Solaris's df prints in a very weird format
- when "Solaris": df = "df -k"
- end
- %x{#{df}}.split("\n").find do |line|
- fs = line.split(/\s+/)[-1]
- if platform == "Darwin"
- fs == "/private/var/automount" + self[:path] or
- fs == self[:path]
- else
- fs == self[:path]
- end
- end
- end
-
- # Convert the current object into an fstab-style string.
- def to_record
- self.class.fields.collect do |field|
- if value = self.value(field)
- value
- else
- raise Puppet::Error,
- "Could not retrieve value for %s" % field
- end
- end.join("\t")
- end
- end
-end
-
-# $Id$
diff --git a/test/lib/puppettest/fakes.rb b/test/lib/puppettest/fakes.rb
index f2d424295..40fe96a10 100644
--- a/test/lib/puppettest/fakes.rb
+++ b/test/lib/puppettest/fakes.rb
@@ -3,6 +3,7 @@ require 'puppettest'
module PuppetTest
# A baseclass for the faketypes.
class FakeModel
+ include Puppet::Util
class << self
attr_accessor :name
@name = :fakemodel
@@ -29,7 +30,8 @@ module PuppetTest
end
def []=(param, value)
- unless @realmodel.attrtype(param)
+ param = symbolize(param)
+ unless @realmodel.validattr?(param)
raise Puppet::DevError, "Invalid attribute %s for %s" %
[param, @realmodel.name]
end
@@ -46,7 +48,7 @@ module PuppetTest
@is = {}
@should = {}
@params = {}
- self[:name] = name
+ self[@realmodel.namevar] = name
end
def inspect
@@ -121,6 +123,29 @@ module PuppetTest
end
end
+ class FakeParsedProvider < FakeProvider
+ def hash
+ ret = {}
+ instance_variables.each do |v|
+ v = v.sub("@", '')
+ if val = self.send(v)
+ ret[v.intern] = val
+ end
+ end
+
+ return ret
+ end
+
+ def store(hash)
+ hash.each do |n, v|
+ method = n.to_s + "="
+ if respond_to? method
+ send(method, v)
+ end
+ end
+ end
+ end
+
@@fakemodels = {}
@@fakeproviders = {}
@@ -132,7 +157,6 @@ module PuppetTest
end
obj = @@fakemodels[type].new(name)
- obj[:name] = name
options.each do |name, val|
obj[name] = val
end
diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb
index ea2d5483c..c7d54d5e6 100644
--- a/test/lib/puppettest/support/utils.rb
+++ b/test/lib/puppettest/support/utils.rb
@@ -142,6 +142,19 @@ module PuppetTest
return comp
end
+
+ def setme
+ # retrieve the user name
+ id = %x{id}.chomp
+ if id =~ /uid=\d+\(([^\)]+)\)/
+ @me = $1
+ else
+ puts id
+ end
+ unless defined? @me
+ raise "Could not retrieve user name; 'id' did not work"
+ end
+ end
end
# $Id$
diff --git a/test/providers/parsedmount.rb b/test/providers/parsedmount.rb
new file mode 100755
index 000000000..a4bcb7534
--- /dev/null
+++ b/test/providers/parsedmount.rb
@@ -0,0 +1,213 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet'
+require 'facter'
+
+class TestParsedMounts < Test::Unit::TestCase
+ include PuppetTest
+
+ def setup
+ super
+ @provider = Puppet.type(:mount).provider(:parsed)
+
+ @oldfiletype = @provider.filetype
+ end
+
+ def teardown
+ Puppet::FileType.filetype(:ram).clear
+ @provider.filetype = @oldfiletype
+ super
+ end
+
+ def mkmountargs
+ mount = nil
+
+ if defined? @pcount
+ @pcount += 1
+ else
+ @pcount = 1
+ end
+ args = {
+ :path => "/fspuppet%s" % @pcount,
+ :device => "/dev/dsk%s" % @pcount,
+ }
+
+ @provider.fields.each do |field|
+ unless args.include? field
+ args[field] = "fake%s" % @pcount
+ end
+ end
+
+ return args
+ end
+
+ def mkmount
+ hash = mkmountargs()
+ #hash[:provider] = @provider.name
+
+ fakemodel = fakemodel(:mount, hash[:path])
+
+ mount = @provider.new(fakemodel)
+ #mount = Puppet.type(:mount).create(hash)
+
+ hash.each do |name, val|
+ fakemodel[name] = val
+ end
+ assert(mount, "Could not create provider mount")
+
+ return mount
+ end
+
+ # Here we just create a fake host type that answers to all of the methods
+ # but does not modify our actual system.
+ def mkfaketype
+ @provider.filetype = Puppet::FileType.filetype(:ram)
+ end
+
+ def test_simplemount
+ mkfaketype
+ assert_nothing_raised {
+ assert_equal([], @provider.retrieve)
+ }
+
+ # Now create a provider
+ mount = nil
+ assert_nothing_raised {
+ mount = mkmount
+ }
+
+ # Make sure we're still empty
+ assert_nothing_raised {
+ assert_equal([], @provider.retrieve)
+ }
+
+ hash = mount.model.to_hash
+
+ # Try storing it
+ assert_nothing_raised do
+ mount.store(hash)
+ end
+
+ # Make sure we get the mount back
+ assert_nothing_raised {
+ assert_equal([hash], @provider.retrieve)
+ }
+
+ # Now remove the whole object
+ assert_nothing_raised {
+ mount.store({})
+ assert_equal([], @provider.retrieve)
+ }
+ end
+
+ unless Facter["operatingsystem"].value == "Darwin"
+ def test_mountsparse
+ fakedataparse(fake_fstab) do
+ # Now just make we've got some mounts we know will be there
+ hashes = @provider.retrieve.find_all { |i| i.is_a? Hash }
+ assert(hashes.length > 0, "Did not create any hashes")
+ root = hashes.find { |i| i[:path] == "/" }
+ assert(root, "Could not retrieve root mount")
+ end
+ end
+
+ def test_rootfs
+ fs = nil
+ @provider.path = fake_fstab()
+ fakemodel = fakemodel(:mount, "/")
+ mount = @provider.new(fakemodel)
+ mount.model[:path] = "/"
+ assert(mount.hash, "Could not retrieve root fs")
+
+ assert_nothing_raised {
+ assert(mount.mounted?, "Root is considered not mounted")
+ }
+ end
+ end
+
+ if Puppet::SUIDManager.uid == 0
+ def test_mountfs
+ fs = nil
+ case Facter["hostname"].value
+ when "culain": fs = "/ubuntu"
+ when "atalanta": fs = "/mnt"
+ when "figurehead": fs = "/cg4/net/depts"
+ else
+ $stderr.puts "No mount for mount testing; skipping"
+ return
+ end
+
+ oldtext = @provider.fileobj.read
+
+ ftype = @provider.filetype
+
+ # Make sure the original gets reinstalled.
+ if ftype == Puppet::FileType.filetype(:netinfo)
+ cleanup do
+ IO.popen("niload -r /mounts .", "w") do |file|
+ file.puts oldtext
+ end
+ end
+ else
+ cleanup do
+ @provider.fileobj.write(oldtext)
+ end
+ end
+
+ fakemodel = fakemodel(:mount, "/")
+ obj = @provider.new(fakemodel)
+ obj.model[:path] = fs
+
+ current = nil
+
+ assert_nothing_raised {
+ current = obj.mounted?
+ }
+
+ if current
+ # Make sure the original gets reinstalled.
+ cleanup do
+ unless obj.mounted?
+ obj.mount
+ end
+ end
+ end
+
+ unless current
+ assert_nothing_raised {
+ obj.mount
+ }
+ end
+
+ assert_nothing_raised {
+ obj.unmount
+ }
+ assert(! obj.mounted?, "FS still mounted")
+ assert_nothing_raised {
+ obj.mount
+ }
+ assert(obj.mounted?, "FS not mounted")
+
+ end
+ end
+
+ def fake_fstab
+ os = Facter['operatingsystem']
+ if os == "Solaris"
+ name = "solaris.fstab"
+ elsif os == "FreeBSD"
+ name = "freebsd.fstab"
+ else
+ # Catchall for other fstabs
+ name = "linux.fstab"
+ end
+ oldpath = @provider.path
+ cleanup do @provider.path = oldpath end
+ return fakefile(File::join("data/types/mount", name))
+ end
+end
+
+# $Id$
diff --git a/test/types/mount.rb b/test/types/mount.rb
index 302e2376a..aab80506d 100755
--- a/test/types/mount.rb
+++ b/test/types/mount.rb
@@ -2,43 +2,64 @@
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
-# Test host job creation, modification, and destruction
-
require 'puppettest'
require 'puppet'
-require 'puppet/type/parsedtype/mount'
-require 'facter'
class TestMounts < Test::Unit::TestCase
include PuppetTest
+
+ p = Puppet::Type.type(:mount).provide :fake, :parent => PuppetTest::FakeParsedProvider do
+ @name = :fake
+ apimethods :ensure
+
+ attr_accessor :mounted
+
+ def create
+ @ensure = :present
+ end
+
+ def delete
+ @ensure = :absent
+ @mounted = false
+ end
+
+ def exists?
+ if defined? @ensure and @ensure == :present
+ true
+ else
+ false
+ end
+ end
+
+ def mounted?
+ self.mounted
+ end
+
+ def mount
+ self.mounted = true
+ end
+
+ def unmount
+ self.mounted = false
+ end
+ end
+
+ FakeMountProvider = p
+
+ @@fakeproviders[:mount] = p
+
def setup
super
- @mounttype = Puppet.type(:mount)
- @oldfiletype = @mounttype.filetype
+ @realprovider = Puppet::Type.type(:mount).defaultprovider
+ Puppet::Type.type(:mount).defaultprovider = FakeMountProvider
end
def teardown
- @mounttype.filetype = @oldfiletype
- Puppet.type(:file).clear
+ Puppet.type(:mount).clear
+ Puppet::Type.type(:mount).defaultprovider = nil
super
end
- # Here we just create a fake host type that answers to all of the methods
- # but does not modify our actual system.
- def mkfaketype
- pfile = tempfile()
- old = @mounttype.filetype
- @mounttype.filetype = Puppet::FileType.filetype(:ram)
-
- cleanup do
- @mounttype.filetype = old
- @mounttype.fileobj = nil
- end
-
- # Reset this, just in case
- @mounttype.fileobj = nil
- end
-
def mkmount
mount = nil
@@ -52,7 +73,7 @@ class TestMounts < Test::Unit::TestCase
:device => "/dev/dsk%s" % @pcount,
}
- Puppet.type(:mount).fields.each do |field|
+ @realprovider.fields.each do |field|
unless args.include? field
args[field] = "fake%s" % @pcount
end
@@ -66,178 +87,47 @@ class TestMounts < Test::Unit::TestCase
end
def test_simplemount
- mkfaketype
- host = nil
- assert_nothing_raised {
- assert_nil(Puppet.type(:mount).retrieve)
- }
-
- mount = mkmount
-
+ mount = nil
+ oldprv = Puppet.type(:mount).defaultprovider
+ Puppet.type(:mount).defaultprovider = nil
assert_nothing_raised {
- Puppet.type(:mount).store
- }
+ Puppet.type(:mount).defaultprovider.retrieve
- assert_nothing_raised {
- assert(
- Puppet.type(:mount).to_file.include?(
- Puppet.type(:mount).fileobj.read
- ),
- "File does not include all of our objects"
- )
- }
- end
-
- unless Facter["operatingsystem"].value == "Darwin"
- def test_mountsparse
- use_fake_fstab
- assert_nothing_raised {
- @mounttype.retrieve
- }
-
- # Now just make we've got some mounts we know will be there
- root = @mounttype["/"]
- assert(root, "Could not retrieve root mount")
- end
-
- def test_rootfs
- fs = nil
- use_fake_fstab
- assert_nothing_raised {
- Puppet.type(:mount).retrieve
- }
-
- assert_nothing_raised {
- fs = Puppet.type(:mount)["/"]
- }
- assert(fs, "Could not retrieve root fs")
-
- assert_nothing_raised {
- assert(fs.mounted?, "Root is considered not mounted")
- }
- end
- end
+ count = 0
+ Puppet.type(:mount).each do |h|
+ count += 1
+ end
- # Make sure it reads and writes correctly.
- def test_readwrite
- use_fake_fstab
- assert_nothing_raised {
- Puppet::Type.type(:mount).retrieve
+ assert_equal(0, count, "Found mounts in empty file somehow")
}
+ Puppet.type(:mount).defaultprovider = oldprv
- oldtype = Puppet::Type.type(:mount).filetype
-
- # Now switch to storing in ram
- mkfaketype
-
- fs = mkmount
-
- assert(Puppet::Type.type(:mount).filetype != oldtype)
-
- assert_events([:mount_created], fs)
-
- text = Puppet::Type.type(:mount).fileobj.read
-
- assert(text =~ /#{fs[:path]}/, "Text did not include new fs")
-
- fs[:ensure] = :absent
-
- assert_events([:mount_removed], fs)
- text = Puppet::Type.type(:mount).fileobj.read
-
- assert(text !~ /#{fs[:path]}/, "Text still includes new fs")
-
- fs[:ensure] = :present
-
- assert_events([:mount_created], fs)
-
- text = Puppet::Type.type(:mount).fileobj.read
+ mount = mkmount
- assert(text =~ /#{fs[:path]}/, "Text did not include new fs")
+ assert_apply(mount)
- fs[:options] = "rw,noauto"
+ assert_nothing_raised { mount.retrieve }
- assert_events([:mount_changed], fs)
+ assert_equal(:mounted, mount.is(:ensure))
end
- if Puppet::SUIDManager.uid == 0
+ # Make sure fs mounting behaves appropriately. This is more a test of
+ # whether things get mounted and unmounted based on the value of 'ensure'.
def test_mountfs
- fs = nil
- case Facter["hostname"].value
- when "culain": fs = "/ubuntu"
- when "atalanta": fs = "/mnt"
- when "figurehead": fs = "/cg4/net/depts"
- else
- $stderr.puts "No mount for mount testing; skipping"
- return
- end
-
- assert_nothing_raised {
- Puppet.type(:mount).retrieve
- }
-
- oldtext = Puppet::Type.type(:mount).fileobj.read
-
- ftype = Puppet::Type.type(:mount).filetype
-
- # Make sure the original gets reinstalled.
- 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
-
- obj = Puppet.type(:mount)[fs]
+ obj = mkmount
- assert(obj, "Could not retrieve %s object" % fs)
-
- current = nil
-
- assert_nothing_raised {
- current = obj.mounted?
- }
-
- if current
- # Make sure the original gets reinstalled.
- cleanup do
- unless obj.mounted?
- obj.mount
- end
- end
- end
-
- unless current
- assert_nothing_raised {
- obj.mount
- }
- end
-
- # Now copy all of the states' "is" values to the "should" values
- obj.each do |state|
- state.should = state.is
- end
+ assert_apply(obj)
# Verify we can remove the mount
assert_nothing_raised {
obj[:ensure] = :absent
}
- assert_events([:mount_removed], obj)
+ assert_events([:mount_deleted], obj)
assert_events([], obj)
# And verify it's gone
- assert(!obj.mounted?, "Object is mounted after being removed")
-
- text = Puppet.type(:mount).fileobj.read
-
- assert(text !~ /#{fs}/,
- "Fstab still contains %s" % fs)
+ assert(!obj.provider.mounted?, "Object is mounted after being removed")
assert_nothing_raised {
obj[:ensure] = :present
@@ -246,10 +136,7 @@ class TestMounts < Test::Unit::TestCase
assert_events([:mount_created], obj)
assert_events([], obj)
- text = Puppet::Type.type(:mount).fileobj.read
- assert(text =~ /#{fs}/, "Fstab does not contain %s" % fs)
-
- assert(! obj.mounted?, "Object is mounted incorrectly")
+ assert(! obj.provider.mounted?, "Object is mounted incorrectly")
assert_nothing_raised {
obj[:ensure] = :mounted
@@ -258,33 +145,8 @@ class TestMounts < Test::Unit::TestCase
assert_events([:mount_mounted], obj)
assert_events([], obj)
- text = Puppet::Type.type(:mount).fileobj.read
- assert(text =~ /#{fs}/,
- "Fstab does not contain %s" % fs)
-
obj.retrieve
- assert(obj.mounted?, "Object is not mounted")
-
- unless current
- assert_nothing_raised {
- obj.unmount
- }
- end
- end
- end
-
- def use_fake_fstab
- os = Facter['operatingsystem']
- if os == "Solaris"
- name = "solaris.fstab"
- elsif os == "FreeBSD"
- name = "freebsd.fstab"
- else
- # Catchall for other fstabs
- name = "linux.fstab"
- end
- fstab = fakefile(File::join("data/types/mount", name))
- Puppet::Type.type(:mount).path = fstab
+ assert(obj.provider.mounted?, "Object is not mounted")
end
end