Merge branch 'tickets/0.24.x/1622' into 0.24.x

Conflicts:

	CHANGELOG
This commit is contained in:
James Turnbull 2008-10-02 07:29:44 +10:00
Родитель 99de920833 7da41528e8
Коммит 6bafd106de
10 изменённых файлов: 308 добавлений и 168 удалений

Просмотреть файл

@ -10,6 +10,15 @@
Fixed #1596 - Deploying file resources with ++ generates error
Modified the group and zone resource types to no longer call
'currentpropvalues' as a means of setting all values to absent.
There should be no behaviour change from this change.
Modified the behaviour of resource-level 'retrieve' -- it only
calls 'retrieve' on each property if the resource exists.
Fixed #1622 - Users and their groups should again add in one transaction
Fixed #1610 - Raise "Filebucketed" messages to Notice priority
Added a number of confines to package providers

Просмотреть файл

@ -206,9 +206,18 @@ class DirectoryService < Puppet::Provider::NameService
if ensure_value == :present
@resource.class.validproperties.each do |name|
next if name == :ensure
next unless val = @resource.should(name) || autogen(name)
# JJM: This calls the method.
self.send(name.to_s + "=", val)
# LAK: We use property.sync here rather than directly calling
# the settor method because the properties might do some kind
# of conversion. In particular, the user gid property might
# have a string and need to convert it to a number
if @resource.should(name)
@resource.property(name).sync
elsif value = autogen(name)
self.send(name.to_s + "=", value)
else
next
end
end
end
end

Просмотреть файл

@ -138,8 +138,18 @@ class NetInfo < Puppet::Provider::NameService
if arg == :present
@resource.class.validproperties.each do |name|
next if name == :ensure
next unless val = @resource.should(name) || autogen(name)
self.send(name.to_s + "=", val)
# LAK: We use property.sync here rather than directly calling
# the settor method because the properties might do some kind
# of conversion. In particular, the user gid property might
# have a string and need to convert it to a number
if @resource.should(name)
@resource.property(name).sync
elsif value = autogen(name)
self.send(name.to_s + "=", value)
else
next
end
end
end
end

Просмотреть файл

@ -901,19 +901,31 @@ class Type
# retrieve the current value of all contained properties
def retrieve
return currentpropvalues
return currentpropvalues
end
# get a hash of the current properties.
def currentpropvalues(override_value = nil)
# it's important to use the method here, as it follows the order
# in which they're defined in the object
return properties().inject({}) { | prophash, property|
prophash[property] = override_value.nil? ?
property.retrieve :
override_value
prophash
}
# Get a hash of the current properties. Returns a hash with
# the actual property instance as the key and the current value
# as the, um, value.
def currentpropvalues
# It's important to use the 'properties' method here, as it follows the order
# in which they're defined in the class. It also guarantees that 'ensure'
# is the first property, which is important for skipping 'retrieve' on
# all the properties if the resource is absent.
ensure_state = false
return properties().inject({}) do | prophash, property|
if property.name == :ensure
ensure_state = property.retrieve
prophash[property] = ensure_state
else
if ensure_state == :absent
prophash[property] = :absent
else
prophash[property] = property.retrieve
end
end
prophash
end
end
# Are we running in noop mode?

Просмотреть файл

@ -118,14 +118,6 @@ module Puppet
defaultto false
end
def retrieve
if self.provider and @provider.exists?
return super
else
return currentpropvalues(:absent)
end
end
end
end

Просмотреть файл

@ -49,25 +49,6 @@ module Puppet
return :absent
end
end
# The default 'sync' method only selects among a list of registered
# values.
def sync
# if self.insync?
# self.info "already in sync"
# return nil
#else
#self.info "%s vs %s" % [self.is.inspect, self.should.inspect]
# end
unless self.class.values
self.devfail "No values defined for %s" %
self.class.name
end
# Set ourselves to whatever our should value is.
self.set(self.should)
end
end
newproperty(:uid) do
@ -95,50 +76,26 @@ module Puppet
newproperty(:gid) do
desc "The user's primary group. Can be specified numerically or
by name."
def found?
defined? @found and @found
end
munge do |gid|
method = :getgrgid
case gid
when String
if gid =~ /^[-0-9]+$/
gid = Integer(gid)
else
method = :getgrnam
end
when Symbol
unless gid == :auto or gid == :absent
self.devfail "Invalid GID %s" % gid
end
# these are treated specially by sync()
return gid
end
if group = Puppet::Util.gid(gid)
@found = true
return group
munge do |value|
if value.is_a?(String) and value =~ /^[-0-9]+$/
Integer(value)
else
@found = false
return gid
value
end
end
# *shudder* Make sure that we've looked up the group and gotten
# an ID for it. Yuck-o.
def should
unless defined? @should
return super
def sync
found = false
@should.each do |value|
if number = Puppet::Util.gid(value)
provider.gid = number
found = true
break
end
end
unless found?
@should = @should.each { |val|
next unless val
Puppet::Util.gid(val)
}
end
super
fail "Could not find group(s) %s" % @should.join(",") unless found
end
end
@ -234,29 +191,6 @@ module Puppet
end
end
# these three properties are all implemented differently on each platform,
# so i'm disabling them for now
# FIXME Puppet::Property::UserLocked is currently non-functional
#newproperty(:locked) do
# desc "The expected return code. An error will be returned if the
# executed command returns something else."
#end
# FIXME Puppet::Property::UserExpire is currently non-functional
#newproperty(:expire) do
# desc "The expected return code. An error will be returned if the
# executed command returns something else."
# @objectaddflag = "-e"
#end
# FIXME Puppet::Property::UserInactive is currently non-functional
#newproperty(:inactive) do
# desc "The expected return code. An error will be returned if the
# executed command returns something else."
# @objectaddflag = "-f"
#end
newparam(:name) do
desc "User name. While limitations are determined for
each operating system, it is generally a good idea to keep to
@ -338,7 +272,7 @@ module Puppet
current_value = :absent
if absent
prophash[property] = :absent
prophash[property] = :absent
else
current_value = property.retrieve
prophash[property] = current_value
@ -346,7 +280,6 @@ module Puppet
if property.name == :ensure and current_value == :absent
absent = true
# next
end
prophash
}

Просмотреть файл

@ -377,7 +377,11 @@ end
result = setstatus(hash)
result
else
return currentpropvalues(:absent)
# Return all properties as absent.
return properties().inject({}) do | prophash, property|
prophash[property] = :absent
prophash
end
end
end

Просмотреть файл

@ -0,0 +1,5 @@
class Object
# This is necessary because the RAL has a 'should'
# method.
alias :must :should
end

Просмотреть файл

@ -2,28 +2,63 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Type, " when in a configuration" do
before do
@catalog = Puppet::Node::Catalog.new
@container = Puppet::Type.type(:component).create(:name => "container")
@one = Puppet::Type.type(:file).create(:path => "/file/one")
@two = Puppet::Type.type(:file).create(:path => "/file/two")
@catalog.add_resource @container
@catalog.add_resource @one
@catalog.add_resource @two
@catalog.add_edge @container, @one
@catalog.add_edge @container, @two
describe Puppet::Type do
describe "when retrieving current properties" do
# Use 'mount' as an example, because it doesn't override 'retrieve'
before do
@resource = Puppet::Type.type(:mount).create(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present)
@properties = {}
end
after { Puppet::Type.type(:mount).clear }
it "should return a hash containing values for all set properties" do
values = @resource.retrieve
[@resource.property(:fstype), @resource.property(:pass)].each { |property| values.should be_include(property) }
end
it "should not call retrieve on non-ensure properties if the resource is absent" do
@resource.property(:ensure).expects(:retrieve).returns :absent
@resource.property(:fstype).expects(:retrieve).never
@resource.retrieve[@resource.property(:fstype)]
end
it "should set all values to :absent if the resource is absent" do
@resource.property(:ensure).expects(:retrieve).returns :absent
@resource.retrieve[@resource.property(:fstype)].should == :absent
end
it "should include the result of retrieving each property's current value if the resource is present" do
@resource.property(:ensure).expects(:retrieve).returns :present
@resource.property(:fstype).expects(:retrieve).returns 15
@resource.retrieve[@resource.property(:fstype)].should == 15
end
end
it "should have no parent if there is no in edge" do
@container.parent.should be_nil
end
it "should set its parent to its in edge" do
@one.parent.ref.should == @container.ref
end
describe "when in a catalog" do
before do
@catalog = Puppet::Node::Catalog.new
@container = Puppet::Type.type(:component).create(:name => "container")
@one = Puppet::Type.type(:file).create(:path => "/file/one")
@two = Puppet::Type.type(:file).create(:path => "/file/two")
@catalog.add_resource @container
@catalog.add_resource @one
@catalog.add_resource @two
@catalog.add_edge @container, @one
@catalog.add_edge @container, @two
end
after do
@catalog.clear(true)
it "should have no parent if there is no in edge" do
@container.parent.should be_nil
end
it "should set its parent to its in edge" do
@one.parent.ref.should == @container.ref
end
after do
@catalog.clear(true)
end
end
end

Просмотреть файл

@ -2,55 +2,186 @@
require File.dirname(__FILE__) + '/../../spec_helper'
module UserTestFunctions
def mkuser(name)
user = nil;
lambda {
user = Puppet::Type.type(:user).create(
:name => name,
:comment => "Puppet Testing User",
:gid => Puppet::Util::SUIDManager.gid,
:shell => "/bin/sh",
:home => "/home/%s" % name
) }.should_not raise_error
user.should_not be_nil
user
user = Puppet::Type.type(:user)
describe user do
before do
@provider = stub 'provider'
@resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
end
def test_provider_class(klass)
klass.should_not be_nil
klass.should be_an_instance_of(Class)
superclasses = []
while klass = klass.superclass
superclasses << klass
end
superclasses.should include(Puppet::Provider)
end
end
describe Puppet::Type.type(:user) do
include UserTestFunctions
after { user.clear }
it "should have a default provider inheriting from Puppet::Provider" do
test_provider_class Puppet::Type.type(:user).defaultprovider
user.defaultprovider.ancestors.should be_include(Puppet::Provider)
end
it "should be able to create a instance" do
mkuser "123testuser1"
end
end
describe Puppet::Type.type(:user), "instances" do
include UserTestFunctions
it "should have a valid provider" do
user = mkuser "123testuser2"
user.provider.should_not be_nil
test_provider_class user.provider.class
user.create(:name => "foo").should_not be_nil
end
it "should have an allows_duplicates feature" do
user.provider_feature(:allows_duplicates).should_not be_nil
end
it "should have an manages_homedir feature" do
user.provider_feature(:manages_homedir).should_not be_nil
end
it "should have an manages_passwords feature" do
user.provider_feature(:manages_passwords).should_not be_nil
end
describe "instances" do
it "should have a valid provider" do
user.create(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
end
end
[:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups].each do |property|
it "should have a %s property" % property do
user.attrclass(property).ancestors.should be_include(Puppet::Property)
end
it "should have documentation for its %s property" % property do
user.attrclass(property).doc.should be_instance_of(String)
end
end
describe "when retrieving all current values" do
before do
@user = user.create(:name => "foo", :uid => 10, :gid => 10)
@properties = {}
end
it "should return a hash containing values for all set properties" do
values = @user.retrieve
[@user.property(:uid), @user.property(:gid)].each { |property| values.should be_include(property) }
end
it "should set all values to :absent if the user is absent" do
@user.property(:ensure).expects(:retrieve).returns :absent
@user.property(:uid).expects(:retrieve).never
@user.retrieve[@user.property(:uid)].should == :absent
end
it "should include the result of retrieving each property's current value if the user is present" do
@user.property(:ensure).expects(:retrieve).returns :present
@user.property(:uid).expects(:retrieve).returns 15
@user.retrieve[@user.property(:uid)].should == 15
end
end
describe "when managing the ensure property" do
before do
@ensure = user.attrclass(:ensure).new(:resource => @resource)
end
it "should support a :present value" do
lambda { @ensure.should = :present }.should_not raise_error
end
it "should support an :absent value" do
lambda { @ensure.should = :absent }.should_not raise_error
end
it "should call :create on the provider when asked to sync to the :present state" do
@provider.expects(:create)
@ensure.should = :present
@ensure.sync
end
it "should call :delete on the provider when asked to sync to the :absent state" do
@provider.expects(:delete)
@ensure.should = :absent
@ensure.sync
end
describe "and determining the current state" do
it "should return :present when the provider indicates the user exists" do
@provider.expects(:exists?).returns true
@ensure.retrieve.should == :present
end
it "should return :absent when the provider indicates the user does not exist" do
@provider.expects(:exists?).returns false
@ensure.retrieve.should == :absent
end
end
end
describe "when managing the uid property" do
it "should convert number-looking strings into actual numbers" do
uid = user.attrclass(:uid).new(:resource => @resource)
uid.should = "50"
uid.should.must == 50
end
it "should support UIDs as numbers" do
uid = user.attrclass(:uid).new(:resource => @resource)
uid.should = 50
uid.should.must == 50
end
it "should :absent as a value" do
uid = user.attrclass(:uid).new(:resource => @resource)
uid.should = :absent
uid.should.must == :absent
end
end
describe "when managing the gid" do
it "should :absent as a value" do
gid = user.attrclass(:gid).new(:resource => @resource)
gid.should = :absent
gid.should.must == :absent
end
it "should convert number-looking strings into actual numbers" do
gid = user.attrclass(:gid).new(:resource => @resource)
gid.should = "50"
gid.should.must == 50
end
it "should support GIDs specified as integers" do
gid = user.attrclass(:gid).new(:resource => @resource)
gid.should = 50
gid.should.must == 50
end
it "should support groups specified by name" do
gid = user.attrclass(:gid).new(:resource => @resource)
gid.should = "foo"
gid.should.must == "foo"
end
describe "when syncing" do
before do
@gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
end
it "should use the first found, specified group as the desired value and send it to the provider" do
Puppet::Util.expects(:gid).with("foo").returns nil
Puppet::Util.expects(:gid).with("bar").returns 500
@provider.expects(:gid=).with 500
@gid.sync
end
end
end
describe "when managing passwords" do
before do
@password = user.attrclass(:password).new(:resource => @resource, :should => "mypass")
end
it "should not include the password in the change log when adding the password" do
@password.change_to_s(:absent, "mypass").should_not be_include("mypass")
end
it "should not include the password in the change log when changing the password" do
@password.change_to_s("other", "mypass").should_not be_include("mypass")
end
end
end