diff --git a/lib/puppet/provider/zfs/zfs.rb b/lib/puppet/provider/zfs/zfs.rb index a88fb7ad5..3c7bd3eb9 100644 --- a/lib/puppet/provider/zfs/zfs.rb +++ b/lib/puppet/provider/zfs/zfs.rb @@ -1,83 +1,84 @@ Puppet::Type.type(:zfs).provide(:zfs) do desc "Provider for zfs." commands :zfs => 'zfs' def self.instances zfs(:list, '-H').split("\n").collect do |line| name,used,avail,refer,mountpoint = line.split(/\s+/) new({:name => name, :ensure => :present}) end end def add_properties properties = [] Puppet::Type.type(:zfs).validproperties.each do |property| next if property == :ensure if value = @resource[property] and value != "" properties << "-o" << "#{property}=#{value}" end end properties end def create zfs *([:create] + add_properties + [@resource[:name]]) end def destroy zfs(:destroy, @resource[:name]) end def exists? - if zfs(:list).split("\n").detect { |line| line.split("\s")[0] == @resource[:name] } + begin + zfs(:list, @resource[:name]) true - else + rescue Puppet::ExecutionFailure false end end PARAMETER_UNSET_OR_NOT_AVAILABLE = '-' # http://docs.oracle.com/cd/E19963-01/html/821-1448/gbscy.html # shareiscsi (added in build 120) was removed from S11 build 136 # aclmode was removed from S11 in build 139 but it may have been added back # http://webcache.googleusercontent.com/search?q=cache:-p74K0DVsdwJ:developers.slashdot.org/story/11/11/09/2343258/solaris-11-released+&cd=13 [:aclmode, :shareiscsi].each do |field| # The zfs commands use the property value '-' to indicate that the # property is not set. We make use of this value to indicate that the # property is not set since it is not avaliable. Conversely, if these # properties are attempted to be unset, and resulted in an error, our # best bet is to catch the exception and continue. define_method(field) do begin zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip rescue PARAMETER_UNSET_OR_NOT_AVAILABLE end end define_method(field.to_s + "=") do |should| begin zfs(:set, "#{field}=#{should}", @resource[:name]) rescue end end end [:aclinherit, :atime, :canmount, :checksum, :compression, :copies, :dedup, :devices, :exec, :logbias, :mountpoint, :nbmand, :primarycache, :quota, :readonly, :recordsize, :refquota, :refreservation, :reservation, :secondarycache, :setuid, :sharenfs, :sharesmb, :snapdir, :version, :volsize, :vscan, :xattr, :zoned].each do |field| define_method(field) do zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip end define_method(field.to_s + "=") do |should| zfs(:set, "#{field}=#{should}", @resource[:name]) end end end diff --git a/spec/unit/provider/zfs/zfs_spec.rb b/spec/unit/provider/zfs/zfs_spec.rb index 49c23a815..c86622197 100755 --- a/spec/unit/provider/zfs/zfs_spec.rb +++ b/spec/unit/provider/zfs/zfs_spec.rb @@ -1,106 +1,106 @@ #! /usr/bin/env ruby require 'spec_helper' describe Puppet::Type.type(:zfs).provider(:zfs) do let(:name) { 'myzfs' } let(:zfs) { '/usr/sbin/zfs' } let(:resource) do Puppet::Type.type(:zfs).new(:name => name, :provider => :zfs) end let(:provider) { resource.provider } before do provider.class.stubs(:which).with('zfs').returns(zfs) end context ".instances" do it "should have an instances method" do provider.class.should respond_to(:instances) end it "should list instances" do provider.class.expects(:zfs).with(:list,'-H').returns File.read(my_fixture('zfs-list.out')) instances = provider.class.instances.map { |p| {:name => p.get(:name), :ensure => p.get(:ensure)} } instances.size.should == 2 instances[0].should == {:name => 'rpool', :ensure => :present} instances[1].should == {:name => 'rpool/ROOT', :ensure => :present} end end context '#add_properties' do it 'should return an array of properties' do resource[:mountpoint] = '/foo' provider.add_properties.should == ['-o', "mountpoint=/foo"] end it 'should return an empty array' do provider.add_properties.should == [] end end context "#create" do it "should execute zfs create" do provider.expects(:zfs).with(:create, name) provider.create end Puppet::Type.type(:zfs).validproperties.each do |prop| next if prop == :ensure it "should include property #{prop}" do resource[prop] = prop provider.expects(:zfs).with(:create, '-o', "#{prop}=#{prop}", name) provider.create end end end context "#destroy" do it "should execute zfs destroy" do provider.expects(:zfs).with(:destroy, name) provider.destroy end end context "#exists?" do it "should return true if the resource exists" do #return stuff because we have to slice and dice it - provider.expects(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\nmyzfs 100K 27.4M /myzfs") + provider.expects(:zfs).with(:list, name) provider.should be_exists end it "should return false if returned values don't match the name" do - provider.expects(:zfs).with(:list).returns("no soup for you") + provider.expects(:zfs).with(:list, name).raises(Puppet::ExecutionFailure, "Failed") provider.should_not be_exists end end describe "zfs properties" do [:aclinherit, :aclmode, :atime, :canmount, :checksum, :compression, :copies, :dedup, :devices, :exec, :logbias, :mountpoint, :nbmand, :primarycache, :quota, :readonly, :recordsize, :refquota, :refreservation, :reservation, :secondarycache, :setuid, :shareiscsi, :sharenfs, :sharesmb, :snapdir, :version, :volsize, :vscan, :xattr, :zoned].each do |prop| it "should get #{prop}" do provider.expects(:zfs).with(:get, '-H', '-o', 'value', prop, name).returns("value\n") provider.send(prop).should == 'value' end it "should set #{prop}=value" do provider.expects(:zfs).with(:set, "#{prop}=value", name) provider.send("#{prop}=", "value") end end end end