Merge branch 'tickets/0.24.x/1622' into 0.24.x
Conflicts: CHANGELOG
This commit is contained in:
Коммит
6bafd106de
|
@ -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
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче