Refactoring the Settings class to use Puppet::Resource
It also now uses the Catalog instead of the recursive TransObject stuff. Signed-off-by: Luke Kanies <luke@madstop.com>
This commit is contained in:
Родитель
91ff7c1f9c
Коммит
352d7be1a2
|
@ -755,13 +755,6 @@ class Type
|
|||
raise Puppet::Error, "Provider %s is not functional on this platform" % provider.class.name
|
||||
end
|
||||
end
|
||||
#Puppet.err "Evaluating %s" % self.path.join(":")
|
||||
unless defined? @evalcount
|
||||
self.err "No evalcount defined on '%s' of type '%s'" %
|
||||
[self.title,self.class]
|
||||
@evalcount = 0
|
||||
end
|
||||
@evalcount += 1
|
||||
|
||||
if p = self.provider and p.respond_to?(:prefetch)
|
||||
p.prefetch
|
||||
|
|
|
@ -58,20 +58,6 @@ class Puppet::Util::Settings
|
|||
return options
|
||||
end
|
||||
|
||||
def apply
|
||||
trans = self.to_transportable
|
||||
begin
|
||||
config = trans.to_catalog
|
||||
config.store_state = false
|
||||
config.apply
|
||||
rescue => detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
end
|
||||
Puppet.err "Could not configure myself: %s" % detail
|
||||
end
|
||||
end
|
||||
|
||||
# Is our parameter a boolean parameter?
|
||||
def boolean?(param)
|
||||
param = symbolize(param)
|
||||
|
@ -435,10 +421,9 @@ class Puppet::Util::Settings
|
|||
def reuse
|
||||
return unless defined? @used
|
||||
@sync.synchronize do # yay, thread-safe
|
||||
@used.each do |section|
|
||||
@used.delete(section)
|
||||
self.use(section)
|
||||
end
|
||||
new = @used
|
||||
@used = []
|
||||
self.use(*new)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -466,41 +451,6 @@ class Puppet::Util::Settings
|
|||
return sectionlist, sections
|
||||
end
|
||||
|
||||
# Convert a single section into transportable objects.
|
||||
def section_to_transportable(section, done = nil)
|
||||
done ||= Hash.new { |hash, key| hash[key] = {} }
|
||||
objects = []
|
||||
persection(section) do |obj|
|
||||
if @config[:mkusers] and value(:mkusers)
|
||||
objects += add_user_resources(section, obj, done)
|
||||
end
|
||||
|
||||
value = obj.value
|
||||
|
||||
# Only files are convertable to transportable resources.
|
||||
next unless obj.respond_to? :to_transportable and transobjects = obj.to_transportable
|
||||
|
||||
transobjects = [transobjects] unless transobjects.is_a? Array
|
||||
transobjects.each do |trans|
|
||||
# transportable could return nil
|
||||
next unless trans
|
||||
unless done[:file].include? trans.name
|
||||
@created << trans.name
|
||||
objects << trans
|
||||
done[:file][trans.name] = trans
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bucket = Puppet::TransBucket.new
|
||||
bucket.type = "Settings"
|
||||
bucket.name = section
|
||||
bucket.push(*objects)
|
||||
bucket.keyword = "class"
|
||||
|
||||
return bucket
|
||||
end
|
||||
|
||||
# Set a bunch of defaults in a given section. The sections are actually pretty
|
||||
# pointless, but they help break things up a bit, anyway.
|
||||
def setdefaults(section, defs)
|
||||
|
@ -552,10 +502,25 @@ class Puppet::Util::Settings
|
|||
end
|
||||
end
|
||||
|
||||
# Convert our list of objects into a component that can be applied.
|
||||
def to_configuration
|
||||
transport = self.to_transportable
|
||||
return transport.to_catalog
|
||||
# Convert the settings we manage into a catalog full of resources that model those settings.
|
||||
# We currently have to go through Trans{Object,Bucket} instances,
|
||||
# because this hasn't been ported yet.
|
||||
def to_catalog(*sections)
|
||||
sections = nil if sections.empty?
|
||||
|
||||
catalog = Puppet::Resource::Catalog.new("Settings")
|
||||
|
||||
@config.values.find_all { |value| value.is_a?(CFile) }.each do |file|
|
||||
next unless (sections.nil? or sections.include?(file.section))
|
||||
next if catalog.resource(:file, value(file.name))
|
||||
next unless resource = file.to_resource
|
||||
|
||||
catalog.add_resource(resource)
|
||||
end
|
||||
|
||||
add_user_resources(catalog, sections)
|
||||
|
||||
catalog
|
||||
end
|
||||
|
||||
# Convert our list of config elements into a configuration file.
|
||||
|
@ -586,45 +551,13 @@ Generated on #{Time.now}.
|
|||
return str
|
||||
end
|
||||
|
||||
# Convert our configuration into a list of transportable objects.
|
||||
def to_transportable(*sections)
|
||||
done = Hash.new { |hash, key|
|
||||
hash[key] = {}
|
||||
}
|
||||
|
||||
topbucket = Puppet::TransBucket.new
|
||||
if defined? @file.file and @file.file
|
||||
topbucket.name = @file.file
|
||||
else
|
||||
topbucket.name = "top"
|
||||
end
|
||||
topbucket.type = "Settings"
|
||||
topbucket.top = true
|
||||
|
||||
# Now iterate over each section
|
||||
if sections.empty?
|
||||
eachsection do |section|
|
||||
sections << section
|
||||
end
|
||||
end
|
||||
sections.each do |section|
|
||||
obj = section_to_transportable(section, done)
|
||||
topbucket.push obj
|
||||
end
|
||||
|
||||
topbucket
|
||||
end
|
||||
|
||||
# Convert to a parseable manifest
|
||||
def to_manifest
|
||||
transport = self.to_transportable
|
||||
|
||||
manifest = transport.to_manifest + "\n"
|
||||
eachsection { |section|
|
||||
manifest += "include #{section}\n"
|
||||
}
|
||||
|
||||
return manifest
|
||||
catalog = to_catalog
|
||||
# The resource list is a list of references, not actual instances.
|
||||
catalog.resources.collect do |ref|
|
||||
catalog.resource(ref).to_manifest
|
||||
end.join("\n\n")
|
||||
end
|
||||
|
||||
# Create the necessary objects to use a section. This is idempotent;
|
||||
|
@ -635,10 +568,8 @@ Generated on #{Time.now}.
|
|||
|
||||
return if sections.empty?
|
||||
|
||||
bucket = to_transportable(*sections)
|
||||
|
||||
begin
|
||||
catalog = bucket.to_catalog
|
||||
catalog = to_catalog(*sections).to_ral
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not create resources for managing Puppet's files and directories in sections %s: %s" % [sections.inspect, detail]
|
||||
|
@ -799,45 +730,25 @@ Generated on #{Time.now}.
|
|||
end
|
||||
|
||||
# Create the transportable objects for users and groups.
|
||||
def add_user_resources(section, obj, done)
|
||||
resources = []
|
||||
[:owner, :group].each do |attr|
|
||||
type = nil
|
||||
if attr == :owner
|
||||
type = :user
|
||||
else
|
||||
type = attr
|
||||
end
|
||||
# If a user and/or group is set, then make sure we're
|
||||
# managing that object
|
||||
if obj.respond_to? attr and name = obj.send(attr)
|
||||
# Skip root or wheel
|
||||
next if %w{root wheel}.include?(name.to_s)
|
||||
def add_user_resources(catalog, sections)
|
||||
return unless Puppet.features.root?
|
||||
return unless self[:mkusers]
|
||||
|
||||
# Skip owners and groups we've already done, but tag
|
||||
# them with our section if necessary
|
||||
if done[type].include?(name)
|
||||
tags = done[type][name].tags
|
||||
unless tags.include?(section)
|
||||
done[type][name].tags = tags << section
|
||||
end
|
||||
else
|
||||
newobj = Puppet::TransObject.new(name, type.to_s)
|
||||
newobj.tags = ["puppet", "configuration", section]
|
||||
newobj[:ensure] = :present
|
||||
if type == :user
|
||||
newobj[:comment] ||= "%s user" % name
|
||||
end
|
||||
# Set the group appropriately for the user
|
||||
if type == :user
|
||||
newobj[:gid] = Puppet[:group]
|
||||
end
|
||||
done[type][name] = newobj
|
||||
resources << newobj
|
||||
@config.each do |name, element|
|
||||
next unless element.respond_to?(:owner)
|
||||
next unless sections.nil? or sections.include?(element.section)
|
||||
|
||||
if user = element.owner and user != "root" and catalog.resource(:user, user).nil?
|
||||
resource = Puppet::Resource.new(:user, user, :ensure => :present)
|
||||
if self[:group]
|
||||
resource[:gid] = self[:group]
|
||||
end
|
||||
catalog.add_resource resource
|
||||
end
|
||||
if group = element.group and ! %w{root wheel}.include?(group) and catalog.resource(:group, group).nil?
|
||||
catalog.add_resource Puppet::Resource.new(:group, group, :ensure => :present)
|
||||
end
|
||||
end
|
||||
resources
|
||||
end
|
||||
|
||||
# Yield each search source in turn.
|
||||
|
@ -1009,8 +920,9 @@ Generated on #{Time.now}.
|
|||
|
||||
# Create the new element. Pretty much just sets the name.
|
||||
def initialize(args = {})
|
||||
@settings = args.delete(:settings)
|
||||
raise ArgumentError.new("You must refer to a settings object") if @settings.nil? or !@settings.is_a?(Puppet::Util::Settings)
|
||||
unless @settings = args.delete(:settings)
|
||||
raise ArgumentError.new("You must refer to a settings object")
|
||||
end
|
||||
|
||||
args.each do |param, value|
|
||||
method = param.to_s + "="
|
||||
|
@ -1090,6 +1002,11 @@ Generated on #{Time.now}.
|
|||
attr_writer :owner, :group
|
||||
attr_accessor :mode, :create
|
||||
|
||||
# Should we create files, rather than just directories?
|
||||
def create_files?
|
||||
create
|
||||
end
|
||||
|
||||
def group
|
||||
if defined? @group
|
||||
return @settings.convert(@group)
|
||||
|
@ -1135,57 +1052,35 @@ Generated on #{Time.now}.
|
|||
end
|
||||
end
|
||||
|
||||
# Convert the object to a TransObject instance.
|
||||
def to_transportable
|
||||
type = self.type
|
||||
return nil unless type
|
||||
# Turn our setting thing into a Puppet::Resource instance.
|
||||
def to_resource
|
||||
return nil unless type = self.type
|
||||
|
||||
path = self.value
|
||||
|
||||
return nil unless path.is_a?(String)
|
||||
|
||||
# Make sure the paths are fully qualified.
|
||||
path = File.join(Dir.getwd, path) unless path =~ /^\//
|
||||
|
||||
return nil unless type == :directory or create_files? or File.exist?(path)
|
||||
return nil if path =~ /^\/dev/
|
||||
|
||||
objects = []
|
||||
resource = Puppet::Resource.new(:file, path)
|
||||
resource[:mode] = self.mode if self.mode
|
||||
|
||||
# Skip plain files that don't exist, since we won't be managing them anyway.
|
||||
return nil unless self.name.to_s =~ /dir$/ or File.exist?(path) or self.create
|
||||
obj = Puppet::TransObject.new(path, "file")
|
||||
|
||||
# Only create directories, or files that are specifically marked to
|
||||
# create.
|
||||
if type == :directory or self.create
|
||||
obj[:ensure] = type
|
||||
end
|
||||
[:mode].each { |var|
|
||||
if value = self.send(var)
|
||||
# Don't bother converting the mode, since the file type
|
||||
# can handle it any old way.
|
||||
obj[var] = value
|
||||
end
|
||||
}
|
||||
|
||||
# Only chown or chgrp when root
|
||||
if Puppet.features.root?
|
||||
[:group, :owner].each { |var|
|
||||
if value = self.send(var)
|
||||
obj[var] = value
|
||||
end
|
||||
}
|
||||
resource[:owner] = self.owner if self.owner
|
||||
resource[:group] = self.group if self.group
|
||||
end
|
||||
|
||||
# And set the loglevel to debug for everything
|
||||
obj[:loglevel] = "debug"
|
||||
|
||||
# We're not actually modifying any files here, and if we allow a
|
||||
# filebucket to get used here we get into an infinite recursion
|
||||
# trying to set the filebucket up.
|
||||
obj[:backup] = false
|
||||
resource[:ensure] = type
|
||||
resource[:loglevel] = :debug
|
||||
resource[:backup] = false
|
||||
|
||||
if self.section
|
||||
obj.tags += ["puppet", "configuration", self.section, self.name]
|
||||
end
|
||||
objects << obj
|
||||
objects
|
||||
resource.tag(self.section, self.name, "settings")
|
||||
|
||||
resource
|
||||
end
|
||||
|
||||
# Make sure any provided variables look up to something.
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
|
||||
describe Puppet::Util::Settings do
|
||||
def tmpfile(name)
|
||||
source = Tempfile.new(name)
|
||||
source.close!
|
||||
source.path
|
||||
end
|
||||
|
||||
it "should be able to make needed directories" do
|
||||
settings = Puppet::Util::Settings.new
|
||||
settings.setdefaults :main, :maindir => [tmpfile("main"), "a"]
|
||||
|
||||
settings.use(:main)
|
||||
|
||||
File.should be_directory(settings[:maindir])
|
||||
end
|
||||
|
||||
it "should make its directories with the corret modes" do
|
||||
settings = Puppet::Util::Settings.new
|
||||
settings.setdefaults :main, :maindir => {:default => tmpfile("main"), :desc => "a", :mode => 0750}
|
||||
|
||||
settings.use(:main)
|
||||
|
||||
(File.stat(settings[:maindir]).mode & 007777).should == 0750
|
||||
end
|
||||
end
|
|
@ -477,7 +477,154 @@ describe Puppet::Util::Settings do
|
|||
end
|
||||
end
|
||||
|
||||
describe "when being used to manage the host machine" do
|
||||
it "should provide a method for creating a catalog of resources from its configuration" do
|
||||
Puppet::Util::Settings.new.should respond_to(:to_catalog)
|
||||
end
|
||||
|
||||
describe "when creating a catalog" do
|
||||
before do
|
||||
@settings = Puppet::Util::Settings.new
|
||||
end
|
||||
|
||||
it "should add all file resources to the catalog if no sections have been specified" do
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
|
||||
@settings.setdefaults :other, :otherdir => ["/otherdir", "a"]
|
||||
catalog = @settings.to_catalog
|
||||
%w{/maindir /seconddir /otherdir}.each do |path|
|
||||
catalog.resource(:file, path).should be_instance_of(Puppet::Resource)
|
||||
end
|
||||
end
|
||||
|
||||
it "should add only files in the specified sections if section names are provided" do
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"]
|
||||
@settings.setdefaults :other, :otherdir => ["/otherdir", "a"]
|
||||
catalog = @settings.to_catalog(:main)
|
||||
catalog.resource(:file, "/otherdir").should be_nil
|
||||
catalog.resource(:file, "/maindir").should be_instance_of(Puppet::Resource)
|
||||
end
|
||||
|
||||
it "should not try to add the same file twice" do
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"]
|
||||
@settings.setdefaults :other, :otherdir => ["/maindir", "a"]
|
||||
lambda { @settings.to_catalog }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should ignore files whose :to_resource method returns nil" do
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"]
|
||||
@settings.element(:maindir).expects(:to_resource).returns nil
|
||||
|
||||
Puppet::Resource::Catalog.any_instance.expects(:add_resource).never
|
||||
@settings.to_catalog
|
||||
end
|
||||
|
||||
describe "when adding users and groups to the catalog" do
|
||||
before do
|
||||
Puppet.features.stubs(:root?).returns true
|
||||
@settings.setdefaults :foo, :mkusers => [true, "e"]
|
||||
@settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "luke", :group => "johnny"}
|
||||
|
||||
@catalog = @settings.to_catalog
|
||||
end
|
||||
|
||||
it "should add each specified user and group to the catalog if :mkusers is a valid setting, is enabled, and we're running as root" do
|
||||
@catalog.resource(:user, "luke").should be_instance_of(Puppet::Resource)
|
||||
@catalog.resource(:group, "johnny").should be_instance_of(Puppet::Resource)
|
||||
end
|
||||
|
||||
it "should only add users and groups to the catalog from specified sections" do
|
||||
@settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "jane", :group => "billy"}
|
||||
catalog = @settings.to_catalog(:other)
|
||||
catalog.resource(:user, "jane").should be_nil
|
||||
catalog.resource(:group, "billy").should be_nil
|
||||
end
|
||||
|
||||
it "should not add users or groups to the catalog if :mkusers not running as root" do
|
||||
Puppet.features.stubs(:root?).returns false
|
||||
|
||||
catalog = @settings.to_catalog
|
||||
catalog.resource(:user, "luke").should be_nil
|
||||
catalog.resource(:group, "johnny").should be_nil
|
||||
end
|
||||
|
||||
it "should not add users or groups to the catalog if :mkusers is not a valid setting" do
|
||||
Puppet.features.stubs(:root?).returns true
|
||||
settings = Puppet::Util::Settings.new
|
||||
settings.setdefaults :other, :otherdir => {:default => "/otherdir", :desc => "a", :owner => "luke", :group => "johnny"}
|
||||
|
||||
catalog = settings.to_catalog
|
||||
catalog.resource(:user, "luke").should be_nil
|
||||
catalog.resource(:group, "johnny").should be_nil
|
||||
end
|
||||
|
||||
it "should not add users or groups to the catalog if :mkusers is a valid setting but is disabled" do
|
||||
@settings[:mkusers] = false
|
||||
|
||||
catalog = @settings.to_catalog
|
||||
catalog.resource(:user, "luke").should be_nil
|
||||
catalog.resource(:group, "johnny").should be_nil
|
||||
end
|
||||
|
||||
it "should not try to add users or groups to the catalog twice" do
|
||||
@settings.setdefaults :yay, :yaydir => {:default => "/yaydir", :desc => "a", :owner => "luke", :group => "johnny"}
|
||||
|
||||
# This would fail if users/groups were added twice
|
||||
lambda { @settings.to_catalog }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should set :ensure to :present on each created user and group" do
|
||||
@catalog.resource(:user, "luke")[:ensure].should == :present
|
||||
@catalog.resource(:group, "johnny")[:ensure].should == :present
|
||||
end
|
||||
|
||||
it "should set each created user's :gid to the main group if one is available" do
|
||||
@settings.setdefaults :foo, :group => ["yay", 'eh']
|
||||
|
||||
@settings.to_catalog.resource(:user, "luke")[:gid].should == "yay"
|
||||
end
|
||||
|
||||
it "should not set each created user's :gid if no main group is available" do
|
||||
@settings.to_catalog.resource(:user, "luke")[:gid].should be_nil
|
||||
end
|
||||
|
||||
it "should not attempt to manage the root user" do
|
||||
Puppet.features.stubs(:root?).returns true
|
||||
@settings.setdefaults :foo, :foodir => {:default => "/foodir", :desc => "a", :owner => "root", :group => "johnny"}
|
||||
|
||||
@settings.to_catalog.resource(:user, "root").should be_nil
|
||||
end
|
||||
|
||||
it "should not attempt to manage the wheel or root groups" do
|
||||
@settings.setdefaults :foo, :foodir => {:default => "/foodir", :desc => "a", :owner => "root", :group => "root"}
|
||||
@settings.setdefaults :fee, :feedir => {:default => "/feedir", :desc => "a", :owner => "root", :group => "wheel"}
|
||||
|
||||
catalog = @settings.to_catalog
|
||||
catalog.resource(:group, "root").should be_nil
|
||||
catalog.resource(:group, "wheel").should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should be able to be converted to a manifest" do
|
||||
Puppet::Util::Settings.new.should respond_to(:to_manifest)
|
||||
end
|
||||
|
||||
describe "when being converted to a manifest" do
|
||||
it "should produce a string with the code for each resource joined by two carriage returns" do
|
||||
@settings = Puppet::Util::Settings.new
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
|
||||
|
||||
main = stub 'main_resource', :ref => "File[/maindir]"
|
||||
main.expects(:to_manifest).returns "maindir"
|
||||
second = stub 'second_resource', :ref => "File[/seconddir]"
|
||||
second.expects(:to_manifest).returns "seconddir"
|
||||
@settings.element(:maindir).expects(:to_resource).returns main
|
||||
@settings.element(:seconddir).expects(:to_resource).returns second
|
||||
|
||||
@settings.to_manifest.split("\n\n").sort.should == %w{maindir seconddir}
|
||||
end
|
||||
end
|
||||
|
||||
describe "when using sections of the configuration to manage the local host" do
|
||||
before do
|
||||
@settings = Puppet::Util::Settings.new
|
||||
@settings.setdefaults :main, :maindir => ["/maindir", "a"], :seconddir => ["/seconddir", "a"]
|
||||
|
@ -486,19 +633,8 @@ describe Puppet::Util::Settings do
|
|||
@settings.setdefaults :files, :myfile => {:default => "/myfile", :desc => "a", :mode => 0755}
|
||||
end
|
||||
|
||||
def stub_transaction
|
||||
@bucket = mock 'bucket'
|
||||
@config = mock 'config'
|
||||
@trans = mock 'transaction'
|
||||
|
||||
@settings.expects(:to_transportable).with(:whatever).returns(@bucket)
|
||||
@bucket.expects(:to_catalog).returns(@config)
|
||||
@config.expects(:apply).yields(@trans)
|
||||
@config.stubs(:host_config=)
|
||||
end
|
||||
|
||||
it "should provide a method that writes files with the correct modes" do
|
||||
pending "Not converted from test/unit yet"
|
||||
@settings.should respond_to(:write)
|
||||
end
|
||||
|
||||
it "should provide a method that creates directories with the correct modes" do
|
||||
|
@ -507,176 +643,60 @@ describe Puppet::Util::Settings do
|
|||
@settings.mkdir(:otherdir)
|
||||
end
|
||||
|
||||
it "should be able to create needed directories in a single section" do
|
||||
Dir.expects(:mkdir).with("/maindir")
|
||||
Dir.expects(:mkdir).with("/seconddir")
|
||||
it "should create a catalog with the specified sections" do
|
||||
@settings.expects(:to_catalog).with(:main, :other).returns Puppet::Resource::Catalog.new("foo")
|
||||
@settings.use(:main, :other)
|
||||
end
|
||||
|
||||
it "should ignore sections that have already been used" do
|
||||
@settings.expects(:to_catalog).with(:main).returns Puppet::Resource::Catalog.new("foo")
|
||||
@settings.use(:main)
|
||||
end
|
||||
|
||||
it "should be able to create needed directories in multiple sections" do
|
||||
Dir.expects(:mkdir).with("/maindir")
|
||||
Dir.expects(:mkdir).with("/seconddir")
|
||||
Dir.expects(:mkdir).with("/thirddir")
|
||||
@settings.use(:main, :third)
|
||||
end
|
||||
|
||||
it "should provide a method to trigger enforcing of file modes on existing files and directories" do
|
||||
pending "Not converted from test/unit yet"
|
||||
end
|
||||
|
||||
it "should provide a method to convert the file mode enforcement into a Puppet manifest" do
|
||||
pending "Not converted from test/unit yet"
|
||||
end
|
||||
|
||||
it "should create files when configured to do so with the :create parameter"
|
||||
|
||||
it "should provide a method to convert the file mode enforcement into transportable resources" do
|
||||
# Make it think we're root so it tries to manage user and group.
|
||||
Puppet.features.stubs(:root?).returns(true)
|
||||
File.stubs(:exist?).with("/myfile").returns(true)
|
||||
trans = nil
|
||||
trans = @settings.to_transportable
|
||||
resources = []
|
||||
trans.delve { |obj| resources << obj if obj.is_a? Puppet::TransObject }
|
||||
%w{/maindir /seconddir /otherdir /myfile}.each do |path|
|
||||
obj = resources.find { |r| r.type == "file" and r.name == path }
|
||||
if path.include?("dir")
|
||||
obj[:ensure].should == :directory
|
||||
else
|
||||
# Do not create the file, just manage mode
|
||||
obj[:ensure].should be_nil
|
||||
end
|
||||
obj.should be_instance_of(Puppet::TransObject)
|
||||
case path
|
||||
when "/otherdir":
|
||||
obj[:owner].should == "luke"
|
||||
obj[:group].should == "johnny"
|
||||
obj[:mode].should == 0755
|
||||
when "/myfile":
|
||||
obj[:mode].should == 0755
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should not try to manage user or group when not running as root" do
|
||||
Puppet.features.stubs(:root?).returns(false)
|
||||
trans = nil
|
||||
trans = @settings.to_transportable(:other)
|
||||
trans.delve do |obj|
|
||||
next unless obj.is_a?(Puppet::TransObject)
|
||||
obj[:owner].should be_nil
|
||||
obj[:group].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it "should add needed users and groups to the manifest when asked" do
|
||||
# This is how we enable user/group management
|
||||
@settings.setdefaults :main, :mkusers => [true, "w"]
|
||||
Puppet.features.stubs(:root?).returns(false)
|
||||
trans = nil
|
||||
trans = @settings.to_transportable(:other)
|
||||
resources = []
|
||||
trans.delve { |obj| resources << obj if obj.is_a? Puppet::TransObject and obj.type != "file" }
|
||||
|
||||
user = resources.find { |r| r.type == "user" }
|
||||
user.should be_instance_of(Puppet::TransObject)
|
||||
user.name.should == "luke"
|
||||
user[:ensure].should == :present
|
||||
|
||||
# This should maybe be a separate test, but...
|
||||
group = resources.find { |r| r.type == "group" }
|
||||
group.should be_instance_of(Puppet::TransObject)
|
||||
group.name.should == "johnny"
|
||||
group[:ensure].should == :present
|
||||
@settings.expects(:to_catalog).with(:other).returns Puppet::Resource::Catalog.new("foo")
|
||||
@settings.use(:main, :other)
|
||||
end
|
||||
|
||||
it "should ignore tags and schedules when creating files and directories"
|
||||
|
||||
it "should apply all resources in debug mode to reduce logging"
|
||||
|
||||
it "should not try to manage absent files" do
|
||||
# Make it think we're root so it tries to manage user and group.
|
||||
Puppet.features.stubs(:root?).returns(true)
|
||||
trans = nil
|
||||
trans = @settings.to_transportable
|
||||
file = nil
|
||||
trans.delve { |obj| file = obj if obj.name == "/myfile" }
|
||||
file.should be_nil
|
||||
end
|
||||
|
||||
it "should not try to manage files in memory" do
|
||||
main = Puppet::Type.type(:file).create(:path => "/maindir")
|
||||
|
||||
trans = @settings.to_transportable
|
||||
|
||||
lambda { trans.to_catalog }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should do nothing if a catalog cannot be created" do
|
||||
bucket = mock 'bucket'
|
||||
catalog = mock 'catalog'
|
||||
|
||||
@settings.expects(:to_transportable).returns bucket
|
||||
bucket.expects(:to_catalog).raises RuntimeError
|
||||
catalog.expects(:apply).never
|
||||
|
||||
@settings.use(:mysection)
|
||||
end
|
||||
|
||||
it "should do nothing if all specified sections have already been used" do
|
||||
bucket = mock 'bucket'
|
||||
catalog = mock 'catalog'
|
||||
|
||||
@settings.expects(:to_transportable).once.returns(bucket)
|
||||
bucket.expects(:to_catalog).returns catalog
|
||||
catalog.stub_everything
|
||||
|
||||
@settings.use(:whatever)
|
||||
|
||||
@settings.use(:whatever)
|
||||
end
|
||||
|
||||
it "should ignore file settings whose values are not strings" do
|
||||
@settings[:maindir] = false
|
||||
|
||||
lambda { trans = @settings.to_transportable }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should be able to turn the current configuration into a parseable manifest"
|
||||
|
||||
it "should convert octal numbers correctly when producing a manifest"
|
||||
|
||||
it "should be able to provide all of its parameters in a format compatible with GetOpt::Long" do
|
||||
pending "Not converted from test/unit yet"
|
||||
end
|
||||
|
||||
it "should not attempt to manage files within /dev" do
|
||||
pending "Not converted from test/unit yet"
|
||||
end
|
||||
it "should convert the created catalog to a RAL catalog" do
|
||||
@catalog = Puppet::Resource::Catalog.new("foo")
|
||||
@settings.expects(:to_catalog).with(:main).returns @catalog
|
||||
|
||||
it "should not modify the stored state database when managing resources" do
|
||||
Puppet::Util::Storage.expects(:store).never
|
||||
Puppet::Util::Storage.expects(:load).never
|
||||
Dir.expects(:mkdir).with("/maindir")
|
||||
Dir.expects(:mkdir).with("/seconddir")
|
||||
@catalog.expects(:to_ral).returns @catalog
|
||||
@settings.use(:main)
|
||||
end
|
||||
|
||||
it "should convert all relative paths to fully-qualified paths (#795)" do
|
||||
@settings[:myfile] = "unqualified"
|
||||
dir = Dir.getwd
|
||||
@settings[:myfile].should == File.join(dir, "unqualified")
|
||||
it "should specify that it is not managing a host catalog" do
|
||||
catalog = Puppet::Resource::Catalog.new("foo")
|
||||
@settings.expects(:to_catalog).returns catalog
|
||||
|
||||
catalog.stubs(:to_ral).returns catalog
|
||||
|
||||
catalog.expects(:host_config=).with false
|
||||
|
||||
@settings.use(:main)
|
||||
end
|
||||
|
||||
it "should support a method for re-using all currently used sections" do
|
||||
Dir.expects(:mkdir).with("/thirddir").times(2)
|
||||
@settings.use(:third)
|
||||
@settings.expects(:to_catalog).with(:main, :third).times(2).returns Puppet::Resource::Catalog.new("foo")
|
||||
|
||||
@settings.use(:main, :third)
|
||||
@settings.reuse
|
||||
end
|
||||
|
||||
it "should fail with an appropriate message if any resources fail" do
|
||||
stub_transaction
|
||||
@catalog = Puppet::Resource::Catalog.new("foo")
|
||||
@catalog.stubs(:to_ral).returns @catalog
|
||||
@settings.expects(:to_catalog).returns @catalog
|
||||
|
||||
@trans = mock("transaction")
|
||||
@catalog.expects(:apply).yields(@trans)
|
||||
|
||||
@trans.expects(:any_failed?).returns(true)
|
||||
|
||||
report = mock 'report'
|
||||
@trans.expects(:report).returns report
|
||||
|
||||
|
@ -811,3 +831,113 @@ describe Puppet::Util::Settings do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Util::Settings::CFile do
|
||||
it "should be able to be converted into a resource" do
|
||||
Puppet::Util::Settings::CFile.new(:settings => mock("settings"), :desc => "eh").should respond_to(:to_resource)
|
||||
end
|
||||
|
||||
describe "when being converted to a resource" do
|
||||
before do
|
||||
@settings = mock 'settings'
|
||||
@file = Puppet::Util::Settings::CFile.new(:settings => @settings, :desc => "eh", :name => :mydir, :section => "mysect")
|
||||
@settings.stubs(:value).with(:mydir).returns "/my/file"
|
||||
end
|
||||
|
||||
it "should skip files that cannot determine their types" do
|
||||
@file.expects(:type).returns nil
|
||||
@file.to_resource.should be_nil
|
||||
end
|
||||
|
||||
it "should skip non-existent files if 'create_files' is not enabled" do
|
||||
@file.expects(:create_files?).returns false
|
||||
@file.expects(:type).returns :file
|
||||
File.expects(:exist?).with("/my/file").returns false
|
||||
@file.to_resource.should be_nil
|
||||
end
|
||||
|
||||
it "should manage existent files even if 'create_files' is not enabled" do
|
||||
@file.expects(:create_files?).returns false
|
||||
@file.expects(:type).returns :file
|
||||
File.expects(:exist?).with("/my/file").returns true
|
||||
@file.to_resource.should be_instance_of(Puppet::Resource)
|
||||
end
|
||||
|
||||
it "should skip files in /dev" do
|
||||
@settings.stubs(:value).with(:mydir).returns "/dev/file"
|
||||
@file.to_resource.should be_nil
|
||||
end
|
||||
|
||||
it "should skip files whose paths are not strings" do
|
||||
@settings.stubs(:value).with(:mydir).returns :foo
|
||||
@file.to_resource.should be_nil
|
||||
end
|
||||
|
||||
it "should return a file resource with the path set appropriately" do
|
||||
resource = @file.to_resource
|
||||
resource.type.should == "File"
|
||||
resource.title.should == "/my/file"
|
||||
end
|
||||
|
||||
it "should fully qualified returned files if necessary (#795)" do
|
||||
@settings.stubs(:value).with(:mydir).returns "myfile"
|
||||
@file.to_resource.title.should == File.join(Dir.getwd, "myfile")
|
||||
end
|
||||
|
||||
it "should set the mode on the file if a mode is provided" do
|
||||
@file.mode = 0755
|
||||
|
||||
@file.to_resource[:mode].should == 0755
|
||||
end
|
||||
|
||||
it "should set the owner if running as root and the owner is provided" do
|
||||
Puppet.features.expects(:root?).returns true
|
||||
@file.stubs(:owner).returns "foo"
|
||||
@file.to_resource[:owner].should == "foo"
|
||||
end
|
||||
|
||||
it "should set the group if running as root and the group is provided" do
|
||||
Puppet.features.expects(:root?).returns true
|
||||
@file.stubs(:group).returns "foo"
|
||||
@file.to_resource[:group].should == "foo"
|
||||
end
|
||||
|
||||
it "should not set owner if not running as root" do
|
||||
Puppet.features.expects(:root?).returns false
|
||||
@file.stubs(:owner).returns "foo"
|
||||
@file.to_resource[:owner].should be_nil
|
||||
end
|
||||
|
||||
it "should not set group if not running as root" do
|
||||
Puppet.features.expects(:root?).returns false
|
||||
@file.stubs(:group).returns "foo"
|
||||
@file.to_resource[:group].should be_nil
|
||||
end
|
||||
|
||||
it "should set :ensure to the file type" do
|
||||
@file.expects(:type).returns :directory
|
||||
@file.to_resource[:ensure].should == :directory
|
||||
end
|
||||
|
||||
it "should set the loglevel to :debug" do
|
||||
@file.to_resource[:loglevel].should == :debug
|
||||
end
|
||||
|
||||
it "should set the backup to false" do
|
||||
@file.to_resource[:backup].should be_false
|
||||
end
|
||||
|
||||
it "should tag the resource with the settings section" do
|
||||
@file.expects(:section).returns "mysect"
|
||||
@file.to_resource.should be_tagged("mysect")
|
||||
end
|
||||
|
||||
it "should tag the resource with the setting name" do
|
||||
@file.to_resource.should be_tagged("mydir")
|
||||
end
|
||||
|
||||
it "should tag the resource with 'settings'" do
|
||||
@file.to_resource.should be_tagged("settings")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,23 +42,6 @@ class TestSettings < Test::Unit::TestCase
|
|||
assert(count > 0, "Found no users")
|
||||
end
|
||||
|
||||
def test_to_transportable
|
||||
set_configs
|
||||
trans = nil
|
||||
assert_nothing_raised("Could not convert to a transportable") {
|
||||
trans = @config.to_transportable
|
||||
}
|
||||
|
||||
comp = nil
|
||||
assert_nothing_raised("Could not convert transportable to component") {
|
||||
comp = trans.to_ral
|
||||
}
|
||||
|
||||
assert_nothing_raised("Could not retrieve transported config") {
|
||||
comp.retrieve
|
||||
}
|
||||
end
|
||||
|
||||
def test_to_config
|
||||
set_configs
|
||||
|
||||
|
@ -565,7 +548,7 @@ yay = /a/path
|
|||
}
|
||||
)
|
||||
|
||||
config = @config.to_configuration
|
||||
config = @config.to_catalog
|
||||
|
||||
assert(! config.resource(:file, "/dev/testing"), "Created dev file")
|
||||
end
|
||||
|
@ -918,7 +901,7 @@ yay = /a/path
|
|||
# Now enable it so they'll be added
|
||||
config[:mkusers] = true
|
||||
|
||||
comp = config.to_configuration
|
||||
comp = config.to_catalog
|
||||
|
||||
comp.vertices.find_all { |r| r.class.name == :user }.each do |u|
|
||||
assert(u.name != "root", "Tried to manage root user")
|
||||
|
|
Загрузка…
Ссылка в новой задаче