summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <paul@puppetlabs.com>2011-02-28 13:30:54 -0800
committerPaul Berry <paul@puppetlabs.com>2011-02-28 13:31:07 -0800
commit721ace5007eb670651acb3b49f3e5b84a1a4f15c (patch)
tree95de42dd013b16a2cf5bd42bdcb0b38457d6a665
parenta0abd8d5db6a756a585259467db5547d193de238 (diff)
parentecb953646b2defbab3bbc53a58ce7ba98d560b50 (diff)
downloadpuppet-721ace5007eb670651acb3b49f3e5b84a1a4f15c.tar.gz
puppet-721ace5007eb670651acb3b49f3e5b84a1a4f15c.tar.xz
puppet-721ace5007eb670651acb3b49f3e5b84a1a4f15c.zip
Merge branch 'ticket/2.6.next/4914' into 2.6.next
* ticket/2.6.next/4914: Revert "(#6309) Ensure the correct device is mounted when managing mounts" (#4914) Improved stubbing in mount/parsed_spec tests. (#4914) Improved parsed_spec for mount (#4914) Remove mount specs (#4914) Specs for mounted? match new behaviour (#4914) Add specs for modified mount provider (#4914) Add specs for modified mount type (#4914) Update property blocks (#4914) Query property_hash for mountstate (#4914) Prefetch mountstate (#4914) Join lines for better readability
-rw-r--r--lib/puppet/provider/mount.rb72
-rwxr-xr-xlib/puppet/provider/mount/parsed.rb62
-rwxr-xr-xlib/puppet/type/mount.rb64
-rw-r--r--spec/fixtures/unit/provider/mount/mount-output.other.txt14
-rw-r--r--spec/fixtures/unit/provider/mount/mount-output.solaris.txt16
-rwxr-xr-xspec/unit/provider/mount/parsed_spec.rb307
-rwxr-xr-xspec/unit/provider/mount_spec.rb206
-rwxr-xr-xspec/unit/type/mount_spec.rb287
-rw-r--r--test/data/providers/mount/parsed/aix.mount7
-rw-r--r--test/data/providers/mount/parsed/darwin.mount (renamed from spec/fixtures/unit/provider/mount/mount-output.darwin.txt)1
-rw-r--r--test/data/providers/mount/parsed/hpux.mount (renamed from spec/fixtures/unit/provider/mount/mount-output.hp-ux.txt)1
-rw-r--r--test/data/providers/mount/parsed/linux.mount5
-rw-r--r--test/data/providers/mount/parsed/solaris.mount6
-rw-r--r--test/data/types/mount/linux.fstab1
-rw-r--r--test/data/types/mount/solaris.fstab1
15 files changed, 603 insertions, 447 deletions
diff --git a/lib/puppet/provider/mount.rb b/lib/puppet/provider/mount.rb
index 81d93b5c1..65296eed2 100644
--- a/lib/puppet/provider/mount.rb
+++ b/lib/puppet/provider/mount.rb
@@ -6,36 +6,19 @@ require 'puppet'
# A module just to store the mount/unmount methods. Individual providers
# still need to add the mount commands manually.
module Puppet::Provider::Mount
- def mount
- # Make sure the fstab file & entry exists
- create
-
- if correctly_mounted?
- # Nothing to do!
- else
- if anything_mounted?
- unmount
-
- # We attempt to create the mount point here, because unmounting
- # certain file systems/devices can cause the mount point to be
- # deleted
- ::FileUtils.mkdir_p(resource[:name])
- end
-
- mount!
- end
- end
-
# This only works when the mount point is synced to the fstab.
- def mount!
+ def mount
# Manually pass the mount options in, since some OSes *cough*OS X*cough* don't
# read from /etc/fstab but still want to use this type.
args = []
args << "-o" << self.options if self.options and self.options != :absent
args << resource[:name]
- flush if respond_to?(:flush)
mountcmd(*args)
+ case get(:ensure)
+ when :absent; set(:ensure => :ghost)
+ when :unmounted; set(:ensure => :mounted)
+ end
end
def remount
@@ -50,46 +33,17 @@ module Puppet::Provider::Mount
# This only works when the mount point is synced to the fstab.
def unmount
- umount resource[:name]
- end
+ umount(resource[:name])
- # Is anything currently mounted at this point?
- def anything_mounted?
- platform = Facter.value("operatingsystem")
- name = resource[:name]
- mounts = mountcmd.split("\n").find do |line|
- case platform
- when "Darwin"
- line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris", "HP-UX"
- # Yes, Solaris does list mounts as "mount_point on device"
- line =~ /^#{name} on /
- when "AIX"
- line.split(/\s+/)[2] == name
- else
- line =~ / on #{name} /
- end
+ # Update property hash for future queries (e.g. refresh is called)
+ case get(:ensure)
+ when :mounted; set(:ensure => :unmounted)
+ when :ghost; set(:ensure => :absent)
end
end
- # Is the desired thing mounted at this point?
- def correctly_mounted?
- platform = Facter.value("operatingsystem")
- name = resource[:name]
- device = resource[:device]
- mounts = mountcmd.split("\n").find do |line|
- case platform
- when "Darwin"
- line =~ /^#{device} on #{name} / or line =~ %r{^#{device} on /private/var/automount#{name}}
- when "Solaris", "HP-UX"
- # Yes, Solaris does list mounts as "mount_point on device"
- line =~ /^#{name} on #{device}/
- when "AIX"
- line.split(/\s+/)[2] == name &&
- line.split(/\s+/)[1] == device
- else
- line =~ /^#{device} on #{name} /
- end
- end
+ # Is the mount currently mounted?
+ def mounted?
+ [:mounted, :ghost].include?(get(:ensure))
end
end
diff --git a/lib/puppet/provider/mount/parsed.rb b/lib/puppet/provider/mount/parsed.rb
index 69a6fc06b..42e543c15 100755
--- a/lib/puppet/provider/mount/parsed.rb
+++ b/lib/puppet/provider/mount/parsed.rb
@@ -18,8 +18,7 @@ Puppet::Type.type(:mount).provide(
commands :mountcmd => "mount", :umount => "umount"
- @platform = Facter["operatingsystem"].value
- case @platform
+ case Facter["operatingsystem"]
when "Solaris"
@fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
else
@@ -39,4 +38,63 @@ Puppet::Type.type(:mount).provide(
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
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index 10eed5373..98a1f2509 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -21,6 +21,11 @@ module Puppet
fstab and mount it. Set to `present` to add to fstab but not change
mount/unmount status"
+ # IS -> SHOULD In Sync Action
+ # ghost -> present NO create
+ # absent -> present NO create
+ # (mounted -> present YES)
+ # (unmounted -> present YES)
newvalue(:defined) do
provider.create
return :mount_created
@@ -28,50 +33,65 @@ module Puppet
aliasvalue :present, :defined
+ # IS -> SHOULD In Sync Action
+ # ghost -> unmounted NO create, unmount
+ # absent -> unmounted NO create
+ # mounted -> unmounted NO unmount
newvalue(:unmounted) do
- if provider.anything_mounted?
- syncothers
+ case self.retrieve
+ when :ghost # (not in fstab but mounted)
+ provider.create
+ @resource.flush
provider.unmount
return :mount_unmounted
- else
+ when nil, :absent # (not in fstab and not mounted)
provider.create
return :mount_created
+ when :mounted # (in fstab and mounted)
+ provider.unmount
+ syncothers # I guess it's more likely that the mount was originally mounted with
+ # the wrong attributes so I sync AFTER the umount
+ return :mount_unmounted
+ else
+ raise Puppet::Error, "Unexpected change from #{current_value} to unmounted}"
end
end
+ # IS -> SHOULD In Sync Action
+ # ghost -> absent NO unmount
+ # mounted -> absent NO provider.destroy AND unmount
+ # unmounted -> absent NO provider.destroy
newvalue(:absent, :event => :mount_deleted) do
- provider.unmount if provider.anything_mounted?
-
- provider.destroy
+ current_value = self.retrieve
+ provider.unmount if provider.mounted?
+ provider.destroy unless current_value == :ghost
end
+ # IS -> SHOULD In Sync Action
+ # ghost -> mounted NO provider.create
+ # absent -> mounted NO provider.create AND mount
+ # unmounted -> mounted NO mount
newvalue(:mounted, :event => :mount_mounted) do
+ # Create the mount point if it does not already exist.
+ current_value = self.retrieve
+ provider.create if [nil, :absent, :ghost].include?(current_value)
+
syncothers
- provider.mount
+ # The fs can be already mounted if it was absent but mounted
+ provider.mount unless provider.mounted?
end
+ # insync: mounted -> present
+ # unmounted -> present
def insync?(is)
- if should == :defined and is != :absent
+ if should == :defined and [:mounted,:unmounted].include?(is)
true
else
super
end
end
- def retrieve
- # We need to special case :mounted; if we're absent, we still
- # want
- curval = super()
- if curval == :absent
- return :absent
- elsif provider.correctly_mounted?
- return :mounted
- else
- return :unmounted
- end
- end
-
def syncothers
# We have to flush any changes to disk.
currentvalues = @resource.retrieve_resource
@@ -205,7 +225,7 @@ module Puppet
def refresh
# Only remount if we're supposed to be mounted.
- provider.remount if self.should(:fstype) != "swap" and provider.anything_mounted?
+ provider.remount if self.should(:fstype) != "swap" and provider.mounted?
end
def value(name)
diff --git a/spec/fixtures/unit/provider/mount/mount-output.other.txt b/spec/fixtures/unit/provider/mount/mount-output.other.txt
deleted file mode 100644
index 0e4dff0c5..000000000
--- a/spec/fixtures/unit/provider/mount/mount-output.other.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-/dev/sda1 on / type ext4 (rw,errors=remount-ro,commit=0)
-proc on /proc type proc (rw,noexec,nosuid,nodev)
-none on /sys type sysfs (rw,noexec,nosuid,nodev)
-fusectl on /sys/fs/fuse/connections type fusectl (rw)
-none on /sys/kernel/debug type debugfs (rw)
-none on /sys/kernel/security type securityfs (rw)
-none on /dev type devtmpfs (rw,mode=0755)
-none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
-none on /dev/shm type tmpfs (rw,nosuid,nodev)
-none on /var/run type tmpfs (rw,nosuid,mode=0755)
-none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
-none on /proc/fs/vmblock/mountPoint type vmblock (rw)
-binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
-/dev/sda2 on /usr type ext4 (rw,errors=remount-ro,commit=0)
diff --git a/spec/fixtures/unit/provider/mount/mount-output.solaris.txt b/spec/fixtures/unit/provider/mount/mount-output.solaris.txt
deleted file mode 100644
index 477926138..000000000
--- a/spec/fixtures/unit/provider/mount/mount-output.solaris.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-/ on rpool/ROOT/opensolaris read/write/setuid/devices/dev=2d90002 on Wed Dec 31 16:00:00 1969
-/devices on /devices read/write/setuid/devices/dev=4a00000 on Thu Feb 17 14:34:02 2011
-/dev on /dev read/write/setuid/devices/dev=4a40000 on Thu Feb 17 14:34:02 2011
-/system/contract on ctfs read/write/setuid/devices/dev=4ac0001 on Thu Feb 17 14:34:02 2011
-/proc on proc read/write/setuid/devices/dev=4b00000 on Thu Feb 17 14:34:02 2011
-/etc/mnttab on mnttab read/write/setuid/devices/dev=4b40001 on Thu Feb 17 14:34:02 2011
-/etc/svc/volatile on swap read/write/setuid/devices/xattr/dev=4b80001 on Thu Feb 17 14:34:02 2011
-/system/object on objfs read/write/setuid/devices/dev=4bc0001 on Thu Feb 17 14:34:02 2011
-/etc/dfs/sharetab on sharefs read/write/setuid/devices/dev=4c00001 on Thu Feb 17 14:34:02 2011
-/lib/libc.so.1 on /usr/lib/libc/libc_hwcap1.so.1 read/write/setuid/devices/dev=2d90002 on Thu Feb 17 14:34:14 2011
-/dev/fd on fd read/write/setuid/devices/dev=4d00001 on Thu Feb 17 14:34:18 2011
-/tmp on swap read/write/setuid/devices/xattr/dev=4b80002 on Thu Feb 17 14:34:19 2011
-/var/run on swap read/write/setuid/devices/xattr/dev=4b80003 on Thu Feb 17 14:34:19 2011
-/export on rpool/export read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90006 on Thu Feb 17 14:37:48 2011
-/export/home on rpool/export/home read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90007 on Thu Feb 17 14:37:48 2011
-/rpool on rpool read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011
diff --git a/spec/unit/provider/mount/parsed_spec.rb b/spec/unit/provider/mount/parsed_spec.rb
index 069d9495a..cf29bd358 100755
--- a/spec/unit/provider/mount/parsed_spec.rb
+++ b/spec/unit/provider/mount/parsed_spec.rb
@@ -5,15 +5,17 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'puppet_spec/files'
require 'puppettest/support/utils'
require 'puppettest/fileparsing'
module ParsedMountTesting
include PuppetTest::Support::Utils
include PuppetTest::FileParsing
+ include PuppetSpec::Files
def fake_fstab
- os = Facter['operatingsystem']
+ os = Facter.value(:operatingsystem)
if os == "Solaris"
name = "solaris.fstab"
elsif os == "FreeBSD"
@@ -22,161 +24,254 @@ module ParsedMountTesting
# Catchall for other fstabs
name = "linux.fstab"
end
- oldpath = @provider_class.default_target
fakefile(File::join("data/types/mount", name))
end
- def mkmountargs
- mount = nil
-
- if defined?(@pcount)
- @pcount += 1
+ def fake_mountoutput
+ os = Facter.value(:operatingsystem)
+ if os == "Darwin"
+ name = "darwin.mount"
+ elsif os == "HP-UX"
+ name = "hpux.mount"
+ elsif os == "Solaris"
+ name = "solaris.mount"
+ elsif os == "AIX"
+ name = "aix.mount"
else
- @pcount = 1
- end
- args = {
- :name => "/fspuppet#{@pcount}",
- :device => "/dev/dsk#{@pcount}",
- }
-
- @provider_class.fields(:parsed).each do |field|
- args[field] = "fake#{field}#{@pcount}" unless args.include? field
+ # Catchall for other fstabs
+ name = "linux.mount"
end
-
- args
+ fakefile(File::join("data/providers/mount/parsed", name))
end
- def mkmount
- hash = mkmountargs
- #hash[:provider] = @provider_class.name
-
- fakeresource = stub :type => :mount, :name => hash[:name]
- fakeresource.stubs(:[]).with(:name).returns(hash[:name])
- fakeresource.stubs(:should).with(:target).returns(nil)
-
- mount = @provider_class.new(fakeresource)
- hash[:record_type] = :parsed
- hash[:ensure] = :present
- mount.property_hash = hash
-
- 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.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- end
end
provider_class = Puppet::Type.type(:mount).provider(:parsed)
describe provider_class do
+
before :each do
@mount_class = Puppet::Type.type(:mount)
- @provider_class = @mount_class.provider(:parsed)
+ @provider = @mount_class.provider(:parsed)
end
+ # LAK:FIXME I can't mock Facter because this test happens at parse-time.
+ it "should default to /etc/vfstab on Solaris" do
+ pending "This test only works on Solaris" unless Facter.value(:operatingsystem) == 'Solaris'
+ Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/vfstab'
+ end
- describe provider_class do
- include ParsedMountTesting
+ it "should default to /etc/fstab on anything else" do
+ pending "This test does not work on Solaris" if Facter.value(:operatingsystem) == 'Solaris'
+ Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/fstab'
+ end
- it "should be able to parse all of the example mount tabs" do
- tab = fake_fstab
- @provider = @provider_class
+ describe "when parsing a line" do
- # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
- # I suppose this is more of an integration test? I dunno.
- fakedataparse(tab) do
- # Now just make we've got some mounts we know will be there
- hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
- (hashes.length > 0).should be_true
- root = hashes.find { |i| i[:name] == "/" }
+ it "should not crash on incomplete lines in fstab" do
+ parse = @provider.parse <<-FSTAB
+/dev/incomplete
+/dev/device name
+FSTAB
+ lambda{ @provider.to_line(parse[0]) }.should_not raise_error
+ end
+
+
+ describe "on Solaris", :if => Facter.value(:operatingsystem) == 'Solaris' do
- proc { @provider_class.to_file(hashes) }.should_not raise_error
+ before :each do
+ @example_line = "/dev/dsk/c0d0s0 /dev/rdsk/c0d0s0 \t\t / \t ufs 1 no\t-"
end
- end
- # LAK:FIXME I can't mock Facter because this test happens at parse-time.
- it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
- should = case Facter.value(:operatingsystem)
- when "Solaris"; "/etc/vfstab"
- else
- "/etc/fstab"
- end
- Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
- end
+ it "should extract device from the first field" do
+ @provider.parse_line(@example_line)[:device].should == '/dev/dsk/c0d0s0'
+ end
- it "should not crash on incomplete lines in fstab" do
- parse = @provider_class.parse <<-FSTAB
-/dev/incomplete
-/dev/device name
- FSTAB
+ it "should extract blockdevice from second field" do
+ @provider.parse_line(@example_line)[:blockdevice].should == "/dev/rdsk/c0d0s0"
+ end
+
+ it "should extract name from third field" do
+ @provider.parse_line(@example_line)[:name].should == "/"
+ end
+
+ it "should extract fstype from fourth field" do
+ @provider.parse_line(@example_line)[:fstype].should == "ufs"
+ end
+
+ it "should extract pass from fifth field" do
+ @provider.parse_line(@example_line)[:pass].should == "1"
+ end
+
+ it "should extract atboot from sixth field" do
+ @provider.parse_line(@example_line)[:atboot].should == "no"
+ end
+
+ it "should extract options from seventh field" do
+ @provider.parse_line(@example_line)[:options].should == "-"
+ end
- lambda{ @provider_class.to_line(parse[0]) }.should_not raise_error
end
- end
- describe provider_class, " when mounting an absent filesystem" do
- include ParsedMountTesting
+ describe "on other platforms than Solaris", :if => Facter.value(:operatingsystem) != 'Solaris' do
+
+ before :each do
+ @example_line = "/dev/vg00/lv01\t/spare \t \t ext3 defaults\t1 2"
+ end
+
+ it "should extract device from the first field" do
+ @provider.parse_line(@example_line)[:device].should == '/dev/vg00/lv01'
+ end
+
+ it "should extract name from second field" do
+ @provider.parse_line(@example_line)[:name].should == "/spare"
+ end
+
+ it "should extract fstype from third field" do
+ @provider.parse_line(@example_line)[:fstype].should == "ext3"
+ end
- # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
- it "should flush the fstab to disk" do
- mount = mkmount
+ it "should extract options from fourth field" do
+ @provider.parse_line(@example_line)[:options].should == "defaults"
+ end
- # Mark the mount as absent
- mount.property_hash[:ensure] = :absent
+ it "should extract dump from fifth field" do
+ @provider.parse_line(@example_line)[:dump].should == "1"
+ end
- mount.stubs(:mountcmd) # just so we don't actually try to mount anything
+ it "should extract options from sixth field" do
+ @provider.parse_line(@example_line)[:pass].should == "2"
+ end
- mount.expects(:flush)
- mount.mount!
end
+
end
- describe provider_class, " when modifying the filesystem tab" do
+ describe "mountinstances" do
include ParsedMountTesting
- before do
- Puppet.settings.stubs(:use)
- # Never write to disk, only to RAM.
- #@provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- @provider_class.stubs(:target_object).returns(Puppet::Util::FileType.filetype(:ram).new("eh"))
- @provider_class.clear
- @mount = mkmount
- @target = @provider_class.default_target
+ it "should get name from mountoutput found on Solaris" do
+ Facter.stubs(:value).with(:operatingsystem).returns 'Solaris'
+ @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+ mounts = @provider.mountinstances
+ mounts.size.should == 6
+ mounts[0].should == { :name => '/', :mounted => :yes }
+ mounts[1].should == { :name => '/proc', :mounted => :yes }
+ mounts[2].should == { :name => '/etc/mnttab', :mounted => :yes }
+ mounts[3].should == { :name => '/tmp', :mounted => :yes }
+ mounts[4].should == { :name => '/export/home', :mounted => :yes }
+ mounts[5].should == { :name => '/ghost', :mounted => :yes }
+ end
+
+ it "should get name from mountoutput found on HP-UX" do
+ Facter.stubs(:value).with(:operatingsystem).returns 'HP-UX'
+ @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+ mounts = @provider.mountinstances
+ mounts.size.should == 17
+ mounts[0].should == { :name => '/', :mounted => :yes }
+ mounts[1].should == { :name => '/devices', :mounted => :yes }
+ mounts[2].should == { :name => '/dev', :mounted => :yes }
+ mounts[3].should == { :name => '/system/contract', :mounted => :yes }
+ mounts[4].should == { :name => '/proc', :mounted => :yes }
+ mounts[5].should == { :name => '/etc/mnttab', :mounted => :yes }
+ mounts[6].should == { :name => '/etc/svc/volatile', :mounted => :yes }
+ mounts[7].should == { :name => '/system/object', :mounted => :yes }
+ mounts[8].should == { :name => '/etc/dfs/sharetab', :mounted => :yes }
+ mounts[9].should == { :name => '/lib/libc.so.1', :mounted => :yes }
+ mounts[10].should == { :name => '/dev/fd', :mounted => :yes }
+ mounts[11].should == { :name => '/tmp', :mounted => :yes }
+ mounts[12].should == { :name => '/var/run', :mounted => :yes }
+ mounts[13].should == { :name => '/export', :mounted => :yes }
+ mounts[14].should == { :name => '/export/home', :mounted => :yes }
+ mounts[15].should == { :name => '/rpool', :mounted => :yes }
+ mounts[16].should == { :name => '/ghost', :mounted => :yes }
+ end
+
+ it "should get name from mountoutput found on Darwin" do
+ Facter.stubs(:value).with(:operatingsystem).returns 'Darwin'
+ @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+ mounts = @provider.mountinstances
+ mounts.size.should == 6
+ mounts[0].should == { :name => '/', :mounted => :yes }
+ mounts[1].should == { :name => '/dev', :mounted => :yes }
+ mounts[2].should == { :name => '/net', :mounted => :yes }
+ mounts[3].should == { :name => '/home', :mounted => :yes }
+ mounts[4].should == { :name => '/usr', :mounted => :yes }
+ mounts[5].should == { :name => '/ghost', :mounted => :yes }
end
- it "should write the mount to disk when :flush is called" do
- old_text = @provider_class.target_object(@provider_class.default_target).read
+ it "should get name from mountoutput found on Linux" do
+ Facter.stubs(:value).with(:operatingsystem).returns 'Gentoo'
+ @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+ mounts = @provider.mountinstances
+ mounts[0].should == { :name => '/', :mounted => :yes }
+ mounts[1].should == { :name => '/lib64/rc/init.d', :mounted => :yes }
+ mounts[2].should == { :name => '/sys', :mounted => :yes }
+ mounts[3].should == { :name => '/usr/portage', :mounted => :yes }
+ mounts[4].should == { :name => '/ghost', :mounted => :yes }
+ end
- @mount.flush
+ it "should get name from mountoutput found on AIX" do
+ Facter.stubs(:value).with(:operatingsystem).returns 'AIX'
+ @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+ mounts = @provider.mountinstances
+ mounts[0].should == { :name => '/', :mounted => :yes }
+ mounts[1].should == { :name => '/tmp', :mounted => :yes }
+ mounts[2].should == { :name => '/home', :mounted => :yes }
+ mounts[3].should == { :name => '/usr', :mounted => :yes }
+ mounts[4].should == { :name => '/usr/code', :mounted => :yes }
+ end
- text = @provider_class.target_object(@provider_class.default_target).read
- text.should == old_text + @mount.class.to_line(@mount.property_hash) + "\n"
+ it "should raise an error if a line is not understandable" do
+ @provider.stubs(:mountcmd).returns("bazinga!")
+ lambda { @provider.mountinstances }.should raise_error Puppet::Error
end
+
end
- describe provider_class, " when parsing information about the root filesystem", :if => Facter["operatingsystem"].value != "Darwin" do
+ describe "when prefetching" do
include ParsedMountTesting
- before do
- @mount = @mount_class.new :name => "/"
- @provider = @mount.provider
+ before :each do
+ # Note: we have to stub default_target before creating resources
+ # because it is used by Puppet::Type::Mount.new to populate the
+ # :target property.
+ @provider.stubs(:default_target).returns fake_fstab
+
+ @res_ghost = Puppet::Type::Mount.new(:name => '/ghost') # in no fake fstab
+ @res_mounted = Puppet::Type::Mount.new(:name => '/') # in every fake fstab
+ @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab
+ @res_absent = Puppet::Type::Mount.new(:name => '/absent') # in no fake fstab
+
+ # Simulate transaction.rb:prefetch
+ @resource_hash = {}
+ [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource|
+ @resource_hash[resource.name] = resource
+ end
+
+ @provider.stubs(:mountcmd).returns File.read(fake_mountoutput)
end
- it "should have a filesystem tab" do
- FileTest.should be_exist(@provider_class.default_target)
+ it "should set :ensure to :unmounted if found in fstab but not mounted" do
+ @provider.prefetch(@resource_hash)
+ @res_unmounted.provider.get(:ensure).should == :unmounted
end
- it "should find the root filesystem" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.property_hash[:ensure].should == :present
+ it "should set :ensure to :mounted if found in fstab and mounted" do
+ @provider.prefetch(@resource_hash)
+ @res_ghost.provider.get(:ensure).should == :ghost
end
- it "should determine that the root fs is mounted" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.should be_anything_mounted
+ it "should set :ensure to :ghost if not found in fstab but mounted" do
+ @provider.prefetch(@resource_hash)
+ @res_mounted.provider.get(:ensure).should == :mounted
end
+
+ it "should set :ensure to :absent if not found in fstab and not mounted" do
+ @provider.prefetch(@resource_hash)
+ @res_absent.provider.get(:ensure).should == :absent
+ end
+
end
+
end
diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index 1f2501765..3fc8a8664 100755
--- a/spec/unit/provider/mount_spec.rb
+++ b/spec/unit/provider/mount_spec.rb
@@ -2,201 +2,145 @@
require File.dirname(__FILE__) + '/../../spec_helper'
-require 'puppet_spec/files'
require 'puppet/provider/mount'
describe Puppet::Provider::Mount do
- include PuppetSpec::Files
-
before :each do
+ @mounter = Object.new
+ @mounter.extend(Puppet::Provider::Mount)
+
@name = "/"
- @resource = Puppet::Type.type(:mount).new(
- :name => '/',
- :device => '/dev/sda1',
- :target => tmpfile("mount_provider")
- )
+ @resource = stub 'resource'
+ @resource.stubs(:[]).with(:name).returns(@name)
- @mounter = Puppet::Type.type(:mount).defaultprovider().new(@resource)
+ @mounter.stubs(:resource).returns(@resource)
end
- describe "when calling mount!" do
- it "should use the 'mountcmd' method to mount" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd)
+ describe Puppet::Provider::Mount, " when mounting" do
- @mounter.mount!
+ before :each do
+ @mounter.stubs(:get).with(:ensure).returns(:mounted)
end
- it "should flush before mounting if a flush method exists" do
- @mounter.meta_def(:flush) { }
- @mounter.expects(:flush)
- @mounter.stubs(:mountcmd)
+ it "should use the 'mountcmd' method to mount" do
@mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd)
- @mounter.mount!
+ @mounter.mount
end
it "should add the options following '-o' if they exist and are not set to :absent" do
@mounter.stubs(:options).returns("ro")
@mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
- @mounter.mount!
+ @mounter.mount
end
it "should specify the filesystem name to the mount command" do
@mounter.stubs(:options).returns(nil)
@mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
- @mounter.mount!
+ @mounter.mount
+ end
+
+ it "should update the :ensure state to :mounted if it was :unmounted before" do
+ @mounter.expects(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:get).with(:ensure).returns(:unmounted)
+ @mounter.expects(:set).with(:ensure => :mounted)
+ @mounter.mount
+ end
+
+ it "should update the :ensure state to :ghost if it was :absent before" do
+ @mounter.expects(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:get).with(:ensure).returns(:absent)
+ @mounter.expects(:set).with(:ensure => :ghost)
+ @mounter.mount
end
+
end
- describe "when remounting" do
+ describe Puppet::Provider::Mount, " when remounting" do
+
it "should use '-o remount' if the resource specifies it supports remounting" do
@mounter.stubs(:info)
- @resource[:remounts] = true
+ @resource.stubs(:[]).with(:remounts).returns(:true)
@mounter.expects(:mountcmd).with("-o", "remount", @name)
@mounter.remount
end
it "should unmount and mount if the resource does not specify it supports remounting" do
@mounter.stubs(:info)
- @resource[:remounts] = false
+ @resource.stubs(:[]).with(:remounts).returns(false)
@mounter.expects(:unmount)
@mounter.expects(:mount)
@mounter.remount
end
it "should log that it is remounting" do
- @resource[:remounts] = true
+ @resource.stubs(:[]).with(:remounts).returns(:true)
@mounter.stubs(:mountcmd)
@mounter.expects(:info).with("Remounting")
@mounter.remount
end
end
- describe "when unmounting" do
+ describe Puppet::Provider::Mount, " when unmounting" do
+
+ before :each do
+ @mounter.stubs(:get).with(:ensure).returns(:unmounted)
+ end
+
it "should call the :umount command with the resource name" do
@mounter.expects(:umount).with(@name)
@mounter.unmount
end
- end
- %w{Darwin Solaris HP-UX AIX Other}.each do |platform|
- describe "on #{platform}" do
- before :each do
- case platform
- when 'Darwin'
- mount_fixture = 'mount-output.darwin.txt'
- @mount_device = '/dev/disk0s3'
- @mount_point = '/usr'
- when 'Solaris'
- mount_fixture = 'mount-output.solaris.txt'
- @mount_device = 'swap'
- @mount_point = '/tmp'
- when 'HP-UX'
- mount_fixture = 'mount-output.hp-ux.txt'
- @mount_device = 'swap'
- @mount_point = '/tmp'
- when 'AIX'
- mount_fixture = 'mount-output.aix.txt'
- @mount_device = '/dev/hd2'
- @mount_point = '/usr'
- when 'Other'
- mount_fixture = 'mount-output.other.txt'
- @mount_device = '/dev/sda2'
- @mount_point = '/usr'
- end
- @mount_data = File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'unit', 'provider', 'mount', mount_fixture))
- Facter.stubs(:value).with("operatingsystem").returns(platform)
- end
-
- describe "when the correct thing is mounted" do
- before :each do
- @mounter.expects(:mountcmd).returns(@mount_data)
- @resource.stubs(:[]).with(:name).returns(@mount_point)
- @resource.stubs(:[]).with(:device).returns(@mount_device)
- end
-
- it "should say anything_mounted?" do
- @mounter.should be_anything_mounted
- end
-
- it "should say correctly_mounted?" do
- @mounter.should be_correctly_mounted
- end
- end
-
- describe "when the wrong thing is mounted" do
- before :each do
- @mounter.expects(:mountcmd).returns(@mount_data)
- @resource.stubs(:[]).with(:name).returns(@mount_point)
- @resource.stubs(:[]).with(:device).returns('/dev/bogus/thing')
- end
-
- it "should say anything_mounted?" do
- @mounter.should be_anything_mounted
- end
-
- it "should not say correctly_mounted?" do
- @mounter.should_not be_correctly_mounted
- end
- end
-
- describe "when nothing is mounted" do
- before :each do
- @mounter.expects(:mountcmd).returns(@mount_data)
- @resource.stubs(:[]).with(:name).returns('/bogus/location')
- @resource.stubs(:[]).with(:device).returns(@mount_device)
- end
-
- it "should not say anything_mounted?" do
- @mounter.should_not be_anything_mounted
- end
-
- it "should not say correctly_mounted?" do
- @mounter.should_not be_correctly_mounted
- end
- end
+ it "should update the :ensure state to :absent if it was :ghost before" do
+ @mounter.expects(:umount).with(@name).returns true
+ @mounter.expects(:get).with(:ensure).returns(:ghost)
+ @mounter.expects(:set).with(:ensure => :absent)
+ @mounter.unmount
end
- end
-
- describe "when mounting a device" do
- it "should not mount! or unmount anything when the correct device is mounted" do
- @mounter.stubs(:correctly_mounted?).returns(true)
- @mounter.expects(:anything_mounted?).never
- @mounter.expects(:create).once
- @mounter.expects(:mount!).never
- @mounter.expects(:unmount).never
- FileUtils.expects(:mkdir_p).never
-
- @mounter.mount
+ it "should update the :ensure state to :unmounted if it was :mounted before" do
+ @mounter.expects(:umount).with(@name).returns true
+ @mounter.expects(:get).with(:ensure).returns(:mounted)
+ @mounter.expects(:set).with(:ensure => :unmounted)
+ @mounter.unmount
end
- it "should mount the device when nothing is mounted at the desired point" do
- @mounter.stubs(:correctly_mounted?).returns(false)
- @mounter.stubs(:anything_mounted?).returns(false)
+ end
- @mounter.expects(:create).once
- @mounter.expects(:mount!).once
- @mounter.expects(:unmount).never
- FileUtils.expects(:mkdir_p).never
+ describe Puppet::Provider::Mount, " when determining if it is mounted" do
- @mounter.mount
+ it "should query the property_hash" do
+ @mounter.expects(:get).with(:ensure).returns(:mounted)
+ @mounter.mounted?
+ end
+
+ it "should return true if prefetched value is :mounted" do
+ @mounter.stubs(:get).with(:ensure).returns(:mounted)
+ @mounter.mounted? == true
end
- it "should unmount the incorrect device and mount the correct device" do
- @mounter.stubs(:correctly_mounted?).returns(false)
- @mounter.stubs(:anything_mounted?).returns(true)
+ it "should return true if prefetched value is :ghost" do
+ @mounter.stubs(:get).with(:ensure).returns(:ghost)
+ @mounter.mounted? == true
+ end
- @mounter.expects(:create).once
- @mounter.expects(:mount!).once
- @mounter.expects(:unmount).once
- FileUtils.expects(:mkdir_p).with(@name).returns(true)
+ it "should return false if prefetched value is :absent" do
+ @mounter.stubs(:get).with(:ensure).returns(:absent)
+ @mounter.mounted? == false
+ end
- @mounter.mount
+ it "should return false if prefetched value is :unmounted" do
+ @mounter.stubs(:get).with(:ensure).returns(:unmounted)
+ @mounter.mounted? == false
end
+
end
+
end
diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb
index c6d2b5ba0..7f9a0eba6 100755
--- a/spec/unit/type/mount_spec.rb
+++ b/spec/unit/type/mount_spec.rb
@@ -11,10 +11,14 @@ describe Puppet::Type.type(:mount) do
mount = Puppet::Type.type(:mount).new(:name => "yay")
mount.should(:ensure).should be_nil
end
+
+ it "should have :name as the only keyattribut" do
+ Puppet::Type.type(:mount).key_attributes.should == [:name]
+ end
end
describe Puppet::Type.type(:mount), "when validating attributes" do
- [:name, :remounts].each do |param|
+ [:name, :remounts, :provider].each do |param|
it "should have a #{param} parameter" do
Puppet::Type.type(:mount).attrtype(param).should == :param
end
@@ -38,9 +42,16 @@ describe Puppet::Type.type(:mount)::Ensure, "when validating values" do
mount.should(:ensure).should == :defined
end
+ it "should support :present as a value to :ensure" do
+ Puppet::Type.type(:mount).new(:name => "yay", :ensure => :present)
+ end
+
+ it "should support :defined as a value to :ensure" do
+ Puppet::Type.type(:mount).new(:name => "yay", :ensure => :defined)
+ end
+
it "should support :unmounted as a value to :ensure" do
- mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
- mount.should(:ensure).should == :unmounted
+ Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
end
it "should support :absent as a value to :ensure" do
@@ -74,123 +85,161 @@ describe Puppet::Type.type(:mount)::Ensure do
end
end
- describe "when retrieving its current state" do
- it "should return the provider's value if it is :absent" do
- @provider.expects(:ensure).returns(:absent)
- @ensure.retrieve.should == :absent
- end
+ describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do
- it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:correctly_mounted?).returns(true)
- @ensure.retrieve.should == :mounted
- end
+ def test_ensure_change(options)
+ @provider.stubs(:get).with(:ensure).returns options[:from]
+ @provider.stubs(:ensure).returns options[:from]
+ @provider.stubs(:mounted?).returns([:mounted,:ghost].include? options[:from])
+ @provider.expects(:create).times(options[:create] || 0)
+ @provider.expects(:destroy).times(options[:destroy] || 0)
+ @provider.expects(:mount).times(options[:mount] || 0)
+ @provider.expects(:unmount).times(options[:unmount] || 0)
+ @ensure.stubs(:syncothers)
+ @ensure.should = options[:to]
+ @ensure.sync
+ end
+
+ it "should create itself when changing from :ghost to :present" do
+ test_ensure_change(:from => :ghost, :to => :present, :create => 1)
+ end
+
+ it "should create itself when changing from :absent to :present" do
+ test_ensure_change(:from => :absent, :to => :present, :create => 1)
+ end
- it "should return :unmounted if the provider indicates it is not mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:correctly_mounted?).returns(false)
- @ensure.retrieve.should == :unmounted
- end
- end
+ it "should create itself and unmount when changing from :ghost to :unmounted" do
+ test_ensure_change(:from => :ghost, :to => :unmounted, :create => 1, :unmount => 1)
+ end
- describe "when changing the host" do
- it "should destroy itself if it should be absent" do
- @provider.stubs(:anything_mounted?).returns(false)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
+ it "should unmount resource when changing from :mounted to :unmounted" do
+ test_ensure_change(:from => :mounted, :to => :unmounted, :unmount => 1)
+ end
+
+ it "should create itself when changing from :absent to :unmounted" do
+ test_ensure_change(:from => :absent, :to => :unmounted, :create => 1)
+ end
+
+ it "should unmount resource when changing from :ghost to :absent" do
+ test_ensure_change(:from => :ghost, :to => :absent, :unmount => 1)
+ end
+
+ it "should unmount and destroy itself when changing from :mounted to :absent" do
+ test_ensure_change(:from => :mounted, :to => :absent, :destroy => 1, :unmount => 1)
+ end
+
+ it "should destroy itself when changing from :unmounted to :absent" do
+ test_ensure_change(:from => :unmounted, :to => :absent, :destroy => 1)
+ end
- it "should unmount itself before destroying if it is mounted and should be absent" do
- @provider.expects(:anything_mounted?).returns(true)
- @provider.expects(:unmount)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
+ it "should create itself when changing from :ghost to :mounted" do
+ test_ensure_change(:from => :ghost, :to => :mounted, :create => 1)
+ end
- it "should create itself if it is absent and should be defined" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:anything_mounted?).returns(true)
+ it "should create itself and mount when changing from :absent to :mounted" do
+ test_ensure_change(:from => :absent, :to => :mounted, :create => 1, :mount => 1)
+ end
- @provider.stubs(:anything_mounted?).returns(false)
- @provider.expects(:create)
- @ensure.should = :defined
- @ensure.sync
- end
+ it "should mount resource when changing from :unmounted to :mounted" do
+ test_ensure_change(:from => :unmounted, :to => :mounted, :mount => 1)
+ end
- it "should not unmount itself if it is mounted and should be defined" do
- @provider.stubs(:ensure).returns(:mounted)
- @provider.stubs(:anything_mounted?).returns(true)
- @provider.stubs(:create)
- @provider.expects(:mount).never
- @provider.expects(:unmount).never
- @ensure.should = :defined
- @ensure.sync
- end
+ it "should be in sync if it is :absent and should be :absent" do
+ @ensure.should = :absent
+ @ensure.safe_insync?(:absent).should == true
+ end
- it "should not mount itself if it is unmounted and should be defined" do
- @provider.stubs(:ensure).returns(:unmounted)
- @provider.stubs(:anything_mounted?).returns(false)
+ it "should be out of sync if it is :absent and should be :defined" do
+ @ensure.should = :defined
+ @ensure.safe_insync?(:absent).should == false
+ end
- @ensure.stubs(:syncothers)
- @provider.stubs(:create)
- @provider.expects(:mount).never
- @provider.expects(:unmount).never
- @ensure.should = :present
- @ensure.sync
- end
+ it "should be out of sync if it is :absent and should be :mounted" do
+ @ensure.should = :mounted
+ @ensure.safe_insync?(:absent).should == false
+ end
- it "should unmount itself if it is mounted and should be unmounted" do
- @provider.stubs(:ensure).returns(:present)
- @provider.stubs(:anything_mounted?).returns(true)
+ it "should be out of sync if it is :absent and should be :unmounted" do
+ @ensure.should = :unmounted
+ @ensure.safe_insync?(:absent).should == false
+ end
- @ensure.stubs(:syncothers)
- @provider.expects(:unmount)
- @ensure.should = :unmounted
- @ensure.sync
- end
+ it "should be out of sync if it is :mounted and should be :absent" do
+ @ensure.should = :absent
+ @ensure.safe_insync?(:mounted).should == false
+ end
- it "should ask the provider to mount itself" do
- @provider.stubs(:ensure).returns(:present)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
+ it "should be in sync if it is :mounted and should be :defined" do
+ @ensure.should = :defined
+ @ensure.safe_insync?(:mounted).should == true
+ end
- it "should be insync if it is mounted and should be defined" do
- @ensure.should = :defined
- @ensure.safe_insync?(:mounted).should == true
- end
+ it "should be in sync if it is :mounted and should be :mounted" do
+ @ensure.should = :mounted
+ @ensure.safe_insync?(:mounted).should == true
+ end
- it "should be insync if it is unmounted and should be defined" do
- @ensure.should = :defined
- @ensure.safe_insync?(:unmounted).should == true
- end
+ it "should be out in sync if it is :mounted and should be :unmounted" do
+ @ensure.should = :unmounted
+ @ensure.safe_insync?(:mounted).should == false
+ end
- it "should be insync if it is mounted and should be present" do
- @ensure.should = :present
- @ensure.safe_insync?(:mounted).should == true
- end
- it "should be insync if it is unmounted and should be present" do
- @ensure.should = :present
- @ensure.safe_insync?(:unmounted).should == true
- end
- end
+ it "should be out of sync if it is :unmounted and should be :absent" do
+ @ensure.should = :absent
+ @ensure.safe_insync?(:unmounted).should == false
+ end
+
+ it "should be in sync if it is :unmounted and should be :defined" do
+ @ensure.should = :defined
+ @ensure.safe_insync?(:unmounted).should == true
+ end
+
+ it "should be out of sync if it is :unmounted and should be :mounted" do
+ @ensure.should = :mounted
+ @ensure.safe_insync?(:unmounted).should == false
+ end
+
+ it "should be in sync if it is :unmounted and should be :unmounted" do
+ @ensure.should = :unmounted
+ @ensure.safe_insync?(:unmounted).should == true
+ end
+
+
+ it "should be out of sync if it is :ghost and should be :absent" do
+ @ensure.should = :absent
+ @ensure.safe_insync?(:ghost).should == false
+ end
+
+ it "should be out of sync if it is :ghost and should be :defined" do
+ @ensure.should = :defined
+ @ensure.safe_insync?(:ghost).should == false
+ end
+
+ it "should be out of sync if it is :ghost and should be :mounted" do
+ @ensure.should = :mounted
+ @ensure.safe_insync?(:ghost).should == false
+ end
+
+ it "should be out of sync if it is :ghost and should be :unmounted" do
+ @ensure.should = :unmounted
+ @ensure.safe_insync?(:ghost).should == false
+ end
+
+ end
+
+ describe Puppet::Type.type(:mount), "when responding to events" do
- describe "when responding to events" do
it "should remount if it is currently mounted" do
- @provider.expects(:anything_mounted?).returns(true)
+ @provider.expects(:mounted?).returns(true)
@provider.expects(:remount)
@mount.refresh
end
it "should not remount if it is not currently mounted" do
- @provider.expects(:anything_mounted?).returns(false)
+ @provider.expects(:mounted?).returns(false)
@provider.expects(:remount).never
@mount.refresh
@@ -218,8 +267,7 @@ describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do
@mount[param] = value
end
- @mount.provider.stubs(:anything_mounted?).returns true
- @mount.provider.stubs(:correctly_mounted?).returns true
+ @mount.provider.stubs(:mounted?).returns true
# stub this to not try to create state.yaml
Puppet::Util::Storage.stubs(:store)
@@ -236,4 +284,49 @@ describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do
@catalog.apply
end
+
+ it "should flush changes before mounting" do
+ syncorder = sequence('syncorder')
+ @mount.provider.expects(:options).returns 'soft'
+ @mount.provider.expects(:ensure).returns :unmounted
+ @mount.provider.expects(:mounted?).returns false
+
+ @mount.provider.expects(:options=).in_sequence(syncorder).with 'hard'
+ @mount.expects(:flush).in_sequence(syncorder) # Have to write with no options
+ @mount.provider.expects(:mount).in_sequence(syncorder)
+ @mount.expects(:flush).in_sequence(syncorder) # Call flush again cause we changed everything
+
+ @mount[:ensure] = :mounted
+ @mount[:options] = 'hard'
+
+ @catalog.apply
+ end
+
+ it "should not flush before mounting if there are no other changes" do
+ syncorder = sequence('syncorder')
+ @mount.provider.expects(:ensure).returns :unmounted
+ @mount.provider.expects(:mounted?).returns false
+ @mount.provider.expects(:mount).in_sequence(syncorder)
+ @mount.expects(:flush).in_sequence(syncorder) # Call flush cause we changed everything
+
+ @mount[:ensure] = :mounted
+ @catalog.apply
+ end
+
+ it "should umount before flushing changes to disk" do
+ syncorder = sequence('syncorder')
+ @mount.provider.expects(:options).returns 'soft'
+ @mount.provider.expects(:ensure).returns :mounted
+
+ @mount.provider.expects(:unmount).in_sequence(syncorder)
+ @mount.provider.expects(:options=).in_sequence(syncorder).with 'hard'
+ @mount.expects(:flush).in_sequence(syncorder) # Call inside syncothers
+ @mount.expects(:flush).in_sequence(syncorder) # I guess transaction or anything calls flush again
+
+ @mount[:ensure] = :unmounted
+ @mount[:options] = 'hard'
+
+ @catalog.apply
+ end
+
end
diff --git a/test/data/providers/mount/parsed/aix.mount b/test/data/providers/mount/parsed/aix.mount
new file mode 100644
index 000000000..380dbc5ae
--- /dev/null
+++ b/test/data/providers/mount/parsed/aix.mount
@@ -0,0 +1,7 @@
+node mounted mounted over vfs date options
+---- ------- ------------ --- ------------ -------------------
+ /dev/hd0 / jfs Dec 17 08:04 rw, log =/dev/hd8
+ /dev/hd3 /tmp jfs Dec 17 08:04 rw, log =/dev/hd8
+ /dev/hd1 /home jfs Dec 17 08:06 rw, log =/dev/hd8
+ /dev/hd2 /usr jfs Dec 17 08:06 rw, log =/dev/hd8
+sue /home/local/src /usr/code nfs Dec 17 08:06 ro, log =/dev/hd8
diff --git a/spec/fixtures/unit/provider/mount/mount-output.darwin.txt b/test/data/providers/mount/parsed/darwin.mount
index fbb9d9832..1bdfcf89a 100644
--- a/spec/fixtures/unit/provider/mount/mount-output.darwin.txt
+++ b/test/data/providers/mount/parsed/darwin.mount
@@ -3,3 +3,4 @@ devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk0s3 on /usr (hfs, local, journaled)
+/dev/fake on /ghost (hfs, local, journaled)
diff --git a/spec/fixtures/unit/provider/mount/mount-output.hp-ux.txt b/test/data/providers/mount/parsed/hpux.mount
index 477926138..d414fa47a 100644
--- a/spec/fixtures/unit/provider/mount/mount-output.hp-ux.txt
+++ b/test/data/providers/mount/parsed/hpux.mount
@@ -14,3 +14,4 @@
/export on rpool/export read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90006 on Thu Feb 17 14:37:48 2011
/export/home on rpool/export/home read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90007 on Thu Feb 17 14:37:48 2011
/rpool on rpool read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011
+/ghost on /dev/fake read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011
diff --git a/test/data/providers/mount/parsed/linux.mount b/test/data/providers/mount/parsed/linux.mount
new file mode 100644
index 000000000..75dd71fd4
--- /dev/null
+++ b/test/data/providers/mount/parsed/linux.mount
@@ -0,0 +1,5 @@
+/dev/root on / type jfs (rw,noatime)
+rc-svcdir on /lib64/rc/init.d type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755)
+sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
+/dev/sda9 on /usr/portage type jfs (rw)
+/dev/fake on /ghost type jfs (rw)
diff --git a/test/data/providers/mount/parsed/solaris.mount b/test/data/providers/mount/parsed/solaris.mount
new file mode 100644
index 000000000..26fabc575
--- /dev/null
+++ b/test/data/providers/mount/parsed/solaris.mount
@@ -0,0 +1,6 @@
+/ on /dev/dsk/c0t0d0s0 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Mon Mar 18 08:48:45 2002
+/proc on /proc read/write/setuid/dev=4300000 on Mon Mar 18 08:48:44 2002
+/etc/mnttab on mnttab read/write/setuid/dev=43c0000 on Mon Mar 18 08:48:44 2002
+/tmp on swap read/write/setuid/xattr/dev=2 on Mon Mar 18 08:48:52 2002
+/export/home on /dev/dsk/c0t0d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18
+/ghost on /dev/dsk/c0t1d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18
diff --git a/test/data/types/mount/linux.fstab b/test/data/types/mount/linux.fstab
index b1debff9c..c94ec7fa8 100644
--- a/test/data/types/mount/linux.fstab
+++ b/test/data/types/mount/linux.fstab
@@ -9,3 +9,4 @@ proc /proc proc defaults 0 0
/dev/vg00/lv01 /spare ext3 defaults 1 2
sysfs /sys sysfs defaults 0 0
LABEL=SWAP-hda6 swap swap defaults 0 0
+/dev/sda1 /usr xfs noatime 0 0
diff --git a/test/data/types/mount/solaris.fstab b/test/data/types/mount/solaris.fstab
index 54afc898c..348b9d50b 100644
--- a/test/data/types/mount/solaris.fstab
+++ b/test/data/types/mount/solaris.fstab
@@ -9,3 +9,4 @@ fd - /dev/fd fd - no -
ctfs - /system/contract ctfs - no -
objfs - /system/object objfs - no -
#swap - /tmp tmpfs - yes -
+/dev/dsk/c0d0s2 /dev/rdsk/c0d0s2 /usr ufs 1 no -