summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-07-04 22:14:37 -0500
committerLuke Kanies <luke@madstop.com>2008-07-04 22:14:37 -0500
commitb0febd263c0cb8e61d512898f7c79868ea77e619 (patch)
tree3f35c4b2d7186d3c69c070c9edc684ccdc51f658 /lib
parentdf528a66cafc8538c3208bf0b52fdbe1065f6e48 (diff)
parent81be1c5c3f85f514505e99fab5b8a2b2ae6fbec8 (diff)
downloadpuppet-b0febd263c0cb8e61d512898f7c79868ea77e619.tar.gz
puppet-b0febd263c0cb8e61d512898f7c79868ea77e619.tar.xz
puppet-b0febd263c0cb8e61d512898f7c79868ea77e619.zip
Merge branch '0.24.x'
Conflicts: lib/puppet/util/settings.rb spec/integration/defaults.rb spec/unit/node/catalog.rb spec/unit/type/interface.rb spec/unit/type/ssh_authorized_key.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/defaults.rb6
-rw-r--r--lib/puppet/event.rb28
-rw-r--r--lib/puppet/indirector/node/ldap.rb15
-rw-r--r--lib/puppet/indirector/yaml.rb3
-rw-r--r--lib/puppet/metatype/evaluation.rb4
-rw-r--r--lib/puppet/node.rb2
-rw-r--r--lib/puppet/node/catalog.rb1
-rw-r--r--lib/puppet/pgraph.rb2
-rw-r--r--lib/puppet/property.rb1
-rw-r--r--lib/puppet/propertychange.rb141
-rw-r--r--lib/puppet/provider/interface/redhat.rb250
-rw-r--r--lib/puppet/provider/interface/sunos.rb133
-rw-r--r--lib/puppet/provider/ssh_authorized_key/parsed.rb16
-rw-r--r--lib/puppet/transaction.rb21
-rw-r--r--lib/puppet/transaction/change.rb94
-rw-r--r--lib/puppet/transaction/event.rb21
-rw-r--r--lib/puppet/type.rb2
-rwxr-xr-xlib/puppet/type/file/ensure.rb5
-rwxr-xr-xlib/puppet/type/file/source.rb20
-rw-r--r--lib/puppet/type/interface.rb60
-rw-r--r--lib/puppet/type/ssh_authorized_key.rb50
-rw-r--r--lib/puppet/type/yumrepo.rb1
-rw-r--r--lib/puppet/util/ldap/connection.rb1
-rw-r--r--lib/puppet/util/settings.rb11
24 files changed, 191 insertions, 697 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index fb4d67a91..fce928ce5 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -63,8 +63,6 @@ module Puppet
:rundir => {
:default => rundir,
:mode => 01777,
- :owner => "$user",
- :group => "$group",
:desc => "Where Puppet PID files are kept."
},
:genconfig => [false,
@@ -382,7 +380,9 @@ module Puppet
# To make sure this directory is created before we try to use it on the server, we need
# it to be in the server section (#1138).
:yamldir => {:default => "$vardir/yaml", :owner => "$user", :group => "$user", :mode => "750",
- :desc => "The directory in which YAML data is stored, usually in a subdirectory."}
+ :desc => "The directory in which YAML data is stored, usually in a subdirectory."},
+ :clientyamldir => {:default => "$vardir/client_yaml", :mode => "750",
+ :desc => "The directory in which client-side YAML data is stored."}
)
self.setdefaults(:puppetd,
diff --git a/lib/puppet/event.rb b/lib/puppet/event.rb
deleted file mode 100644
index c1928a354..000000000
--- a/lib/puppet/event.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require 'puppet'
-require 'puppet/util/methodhelper'
-require 'puppet/util/errors'
-
-module Puppet
- # events are transient packets of information; they result in one or more (or none)
- # subscriptions getting triggered, and then they get cleared
- # eventually, these will be passed on to some central event system
- class Event
- include Puppet
- include Puppet::Util::MethodHelper
- include Puppet::Util::Errors
-
- attr_accessor :event, :source, :transaction
-
- @@events = []
-
- def initialize(args)
- set_options symbolize_options(args)
- requiredopts(:event, :source)
- end
-
- def to_s
- @source.to_s + " -> " + self.event.to_s
- end
- end
-end
-
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index 71d3e3b0e..01010a2af 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -14,7 +14,7 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
end
# Separate this out so it's relatively atomic. It's tempting to call
- # process() instead of entry2hash() here, but it ends up being
+ # process() instead of name2hash() here, but it ends up being
# difficult to test because all exceptions get caught by ldapsearch.
# LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
# but LDAP::ResultError, even on bad connections, so we are rough handed
@@ -35,21 +35,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
node = nil
names.each do |name|
- break if node = process(name)
- end
- return nil unless node
+ next unless info = name2hash(name)
- node.name = request.key
+ break if node = info2node(request.key, info)
+ end
return node
end
- def process(name)
- return nil unless info = name2hash(name)
-
- info2node(name, info)
- end
-
# Find more than one node. LAK:NOTE This is a bit of a clumsy API, because the 'search'
# method currently *requires* a key. It seems appropriate in some cases but not others,
# and I don't really know how to get rid of it as a requirement but allow it when desired.
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index 23bca02b8..3573ba560 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -36,7 +36,8 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
# Return the path to a given node's file.
def path(name)
- File.join(Puppet[:yamldir], self.class.indirection_name.to_s, name.to_s + ".yaml")
+ base = (Puppet[:name] == "puppetmasterd") ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, self.class.indirection_name.to_s, name.to_s + ".yaml")
end
private
diff --git a/lib/puppet/metatype/evaluation.rb b/lib/puppet/metatype/evaluation.rb
index ff1eddb55..18bbb812f 100644
--- a/lib/puppet/metatype/evaluation.rb
+++ b/lib/puppet/metatype/evaluation.rb
@@ -139,7 +139,7 @@ class Puppet::Type
end
if ensureparam and ! ensureparam.insync?(currentvalues[ensureparam])
- changes << Puppet::PropertyChange.new(ensureparam, currentvalues[ensureparam])
+ changes << Puppet::Transaction::Change.new(ensureparam, currentvalues[ensureparam])
# Else, if the 'ensure' property is correctly absent, then do
# nothing
elsif ensureparam and currentvalues[ensureparam] == :absent
@@ -149,7 +149,7 @@ class Puppet::Type
currentvalues[property] ||= :absent
! property.insync?(currentvalues[property])
}.collect { |property|
- Puppet::PropertyChange.new(property, currentvalues[property])
+ Puppet::Transaction::Change.new(property, currentvalues[property])
}
end
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 43a9802d9..3322a9ee7 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -75,6 +75,8 @@ class Puppet::Node
def fact_merge
if facts = Puppet::Node::Facts.find(name)
merge(facts.values)
+ else
+ Puppet.warning "Could not find facts for %s; you probably have a discrepancy between the node and fact names" % name
end
end
diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb
index 9dbdb8d62..852904967 100644
--- a/lib/puppet/node/catalog.rb
+++ b/lib/puppet/node/catalog.rb
@@ -95,6 +95,7 @@ class Puppet::Node::Catalog < Puppet::PGraph
# isn't sufficient.
return if newref == resource.ref
if existing = @resource_table[newref]
+ return if existing == resource
raise(ArgumentError, "Cannot alias %s to %s; resource %s already exists" % [resource.ref, name, newref])
end
@resource_table[newref] = resource
diff --git a/lib/puppet/pgraph.rb b/lib/puppet/pgraph.rb
index 3bcc2ced0..55ad7d2c1 100644
--- a/lib/puppet/pgraph.rb
+++ b/lib/puppet/pgraph.rb
@@ -58,7 +58,7 @@ class Puppet::PGraph < Puppet::SimpleGraph
# to, which is the same thing as saying all edges directly below
# This vertex in the graph.
adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
- edge.match?(event.event)
+ edge.match?(event.name)
end
end.compact.flatten
end
diff --git a/lib/puppet/property.rb b/lib/puppet/property.rb
index fcaa19d48..9e8bae7a4 100644
--- a/lib/puppet/property.rb
+++ b/lib/puppet/property.rb
@@ -2,7 +2,6 @@
# blocks for actually doing work on the system.
require 'puppet'
-require 'puppet/propertychange'
require 'puppet/parameter'
module Puppet
diff --git a/lib/puppet/propertychange.rb b/lib/puppet/propertychange.rb
deleted file mode 100644
index 35bbede1a..000000000
--- a/lib/puppet/propertychange.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-# the class responsible for actually doing any work
-
-# enables no-op and logging/rollback
-
-module Puppet
- # Handle all of the work around performing an actual change,
- # including calling 'sync' on the properties and producing events.
- class PropertyChange
- attr_accessor :is, :should, :type, :path, :property, :transaction, :changed, :proxy
-
- # The log file generated when this object was changed.
- attr_reader :report
-
- # Switch the goals of the property, thus running the change in reverse.
- def backward
- @property.should = @is
- @is = @property.retrieve
-
- unless defined? @transaction
- raise Puppet::Error,
- "PropertyChange '%s' tried to be executed outside of transaction" %
- self
- end
- unless @property.insync?(@is)
- @property.info "Backing %s" % self
- return self.go
- else
- @property.debug "rollback is already in sync: %s vs. %s" %
- [@is, @property.should.inspect]
- return nil
- end
- end
-
- def changed?
- self.changed
- end
-
- # Create our event object.
- def event(name)
- # default to a simple event type
- unless name.is_a?(Symbol)
- @property.warning("Property '%s' returned invalid event '%s'; resetting to default" %
- [@property.class, name])
-
- event = @property.resource.class.name.id2name + "_changed"
- end
-
- Puppet::Event.new(
- :event => name,
- :transaction => @transaction,
- :source => self.source
- )
- end
-
- def initialize(property, currentvalue)
- unless property.is_a?(Puppet::Property)
- raise Puppet::DevError, "Got a %s instead of a property" %
- property.class
- end
- @property = property
- @path = [property.path,"change"].flatten
- @is = currentvalue
-
- @should = property.should
-
- @changed = false
- end
-
- # Perform the actual change. This method can go either forward or
- # backward, and produces an event.
- def go
- if skip?
- if self.noop
- return [event(:noop)]
- else
- return nil
- end
- end
-
- # The transaction catches any exceptions here.
- events = @property.sync
- if events.nil?
- return nil
- end
-
- if events.is_a?(Array)
- if events.empty?
- return nil
- end
- else
- events = [events]
- end
-
- return events.collect { |name|
- @report = @property.log(@property.change_to_s(@is, @should))
- event(name)
- }
- end
-
- def forward
- #@property.debug "moving change forward"
-
- unless defined? @transaction
- raise Puppet::Error,
- "PropertyChange '%s' tried to be executed outside of transaction" %
- self
- end
-
- return self.go
- end
-
- def noop
- return @property.noop
- end
-
- def skip?
- if @property.insync?(@is)
- @property.info "Already in sync"
- return true
- end
-
- if @property.noop
- @property.log "is %s, should be %s (noop)" %
- [property.is_to_s(@is), property.should_to_s(@should)]
- #@property.debug "%s is noop" % @property
- return true
- end
- return false
- end
-
- def source
- self.proxy || @property.resource
- end
-
- def to_s
- return "change %s.%s(%s)" %
- [@transaction.object_id, self.object_id, @property.change_to_s(@is, @should)]
- #return "change %s.%s" % [@transaction.object_id, self.object_id]
- end
- end
-end
diff --git a/lib/puppet/provider/interface/redhat.rb b/lib/puppet/provider/interface/redhat.rb
deleted file mode 100644
index 4a9fcb491..000000000
--- a/lib/puppet/provider/interface/redhat.rb
+++ /dev/null
@@ -1,250 +0,0 @@
-require 'puppet/provider/parsedfile'
-require 'erb'
-
-Puppet::Type.type(:interface).provide(:redhat) do
- desc "Manage network interfaces on Red Hat operating systems. This provider
- parses and generates configuration files in ``/etc/sysconfig/network-scripts``."
-
- INTERFACE_DIR = "/etc/sysconfig/network-scripts"
- confine :exists => INTERFACE_DIR
- defaultfor :operatingsystem => [:fedora, :centos, :redhat]
-
- # Create the setter/gettor methods to match the model.
- mk_resource_methods
-
- @templates = {}
-
- # Register a template.
- def self.register_template(name, string)
- @templates[name] = ERB.new(string)
- end
-
- # Retrieve a template by name.
- def self.template(name)
- @templates[name]
- end
-
- register_template :alias, <<-ALIAS
-DEVICE=<%= self.device %>
-ONBOOT=<%= self.on_boot %>
-BOOTPROTO=none
-IPADDR=<%= self.name %>
-NETMASK=<%= self.netmask %>
-BROADCAST=
-ALIAS
-
-
- register_template :normal, <<-LOOPBACKDUMMY
-DEVICE=<%= self.device %>
-ONBOOT=<%= self.on_boot %>
-BOOTPROTO=static
-IPADDR=<%= self.name %>
-NETMASK=<%= self.netmask %>
-BROADCAST=
-LOOPBACKDUMMY
-
- # maximum number of dummy interfaces
- @max_dummies = 10
-
- # maximum number of aliases per interface
- @max_aliases_per_iface = 10
-
- @@dummies = []
- @@aliases = Hash.new { |hash, key| hash[key] = [] }
-
- # calculate which dummy interfaces are currently already in
- # use prior to needing to call self.next_dummy later on.
- def self.instances
- # parse all of the config files at once
- Dir.glob("%s/ifcfg-*" % INTERFACE_DIR).collect do |file|
- record = parse(file)
-
- # store the existing dummy interfaces
- @@dummies << record[:ifnum] if (record[:interface_type] == :dummy and ! @@dummies.include?(record[:ifnum]))
-
- @@aliases[record[:interface]] << record[:ifnum] if record[:interface_type] == :alias
-
- new(record)
- end
- end
-
- # return the next avaliable dummy interface number, in the case where
- # ifnum is not manually specified
- def self.next_dummy
- @max_dummies.times do |i|
- unless @@dummies.include?(i.to_s)
- @@dummies << i.to_s
- return i.to_s
- end
- end
- end
-
- # return the next available alias on a given interface, in the case
- # where ifnum if not manually specified
- def self.next_alias(interface)
- @max_aliases_per_iface.times do |i|
- unless @@aliases[interface].include?(i.to_s)
- @@aliases[interface] << i.to_s
- return i.to_s
- end
- end
- end
-
- # base the ifnum, for dummy / loopback interface in linux
- # on the last octect of the IP address
-
- # Parse the existing file.
- def self.parse(file)
- instance = new()
- return instance unless FileTest.exist?(file)
-
- File.readlines(file).each do |line|
- if line =~ /^(\w+)=(.+)$/
- instance.send($1.downcase + "=", $2)
- end
- end
-
- return instance
- end
-
- # Prefetch our interface list, yo.
- def self.prefetch(resources)
- instances.each do |prov|
- if resource = resources[prov.name]
- resource.provider = prov
- end
- end
- end
-
- def create
- self.class.resource_type.validproperties.each do |property|
- if value = @resource.should(property)
- @property_hash[property] = value
- end
- end
- @property_hash[:name] = @resource.name
-
- return (@resource.class.name.to_s + "_created").intern
- end
-
- def destroy
- File.unlink(file_path)
- end
-
- def exists?
- FileTest.exist?(file_path)
- end
-
- # generate the content for the interface file, so this is dependent
- # on whether we are adding an alias to a real interface, or a loopback
- # address (also dummy) on linux. For linux it's quite involved, and we
- # will use an ERB template
- def generate
- itype = self.interface_type == :alias ? :alias : :normal
- self.class.template(itype).result(binding)
- end
-
- # Where should the file be written out?
- # This defaults to INTERFACE_DIR/ifcfg-<namevar>, but can have a
- # more symbolic name by setting interface_desc in the type.
- def file_path
- if resource and val = resource[:interface_desc]
- desc = val
- else
- desc = self.name
- end
-
- self.fail("Could not get name for interface") unless desc
-
- if self.interface_type == :alias
- return File.join(INTERFACE_DIR, "ifcfg-" + self.interface + ":" + desc)
- else
- return File.join(INTERFACE_DIR, "ifcfg-" + desc)
- end
- end
-
- # Use the device value to figure out all kinds of nifty things.
- def device=(value)
- case value
- when /:/:
- @property_hash[:interface], @property_hash[:ifnum] = value.split(":")
- @property_hash[:interface_type] = :alias
- when /^dummy/:
- @property_hash[:interface_type] = :loopback
- @property_hash[:interface] = "dummy"
-
- # take the number of the dummy interface, as this is used
- # when working out whether to call next_dummy when dynamically
- # creating these
- @property_hash[:ifnum] = value.sub("dummy",'')
-
- @@dummies << @property_hash[:ifnum].to_s unless @@dummies.include?(@property_hash[:ifnum].to_s)
- else
- @property_hash[:interface_type] = :normal
- @property_hash[:interface] = value
- end
- end
-
- # create the device name, so this based on the IP, and interface + type
- def device
- case @resource.should(:interface_type)
- when :loopback
- @property_hash[:ifnum] ||= self.class.next_dummy
- return "dummy" + @property_hash[:ifnum]
- when :alias
- @property_hash[:ifnum] ||= self.class.next_alias(@resource[:interface])
- return @resource[:interface] + ":" + @property_hash[:ifnum]
- end
- end
-
- # Set the name to our ip address.
- def ipaddr=(value)
- @property_hash[:name] = value
- end
-
- # whether the device is to be brought up on boot or not. converts
- # the true / false of the type, into yes / no values respectively
- # writing out the ifcfg-* files
- def on_boot
- case @property_hash[:onboot].to_s
- when "true"
- return "yes"
- when "false"
- return "no"
- else
- return "neither"
- end
- end
-
- # Mark whether the interface should be started on boot.
- def on_boot=(value)
- # translate whether we come up on boot to true/false
- case value.downcase
- when "yes":
- @property_hash[:onboot] = :true
- else
- @property_hash[:onboot] = :false
- end
- end
-
- # Write the new file out.
- def flush
- # Don't flush to disk if we're removing the config.
- return if self.ensure == :absent
-
- @property_hash.each do |name, val|
- if val == :absent
- raise ArgumentError, "Propety %s must be provided" % val
- end
- end
-
- File.open(file_path, "w") do |f|
- f.puts generate()
- end
- end
-
- def prefetch
- @property_hash = self.class.parse(file_path)
- end
-end
-
diff --git a/lib/puppet/provider/interface/sunos.rb b/lib/puppet/provider/interface/sunos.rb
deleted file mode 100644
index eda21ca3d..000000000
--- a/lib/puppet/provider/interface/sunos.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-require 'puppet/provider/parsedfile'
-require 'erb'
-
-Puppet::Type.type(:interface).provide(:sunos) do
- confine :kernel => "SunOS"
-
- # Add accessor/getter methods for each property/parameter; these methods
- # modify @property_hash.
- mk_resource_methods
-
- # Get a list of interface instances.
- def self.instances
- Dir.glob("/etc/hostname.*").collect do |file|
- device = File.basename(file).split(".").pop
-
- instance = new(:interface => device)
- instance.parse
- instance
- end
- end
-
- def self.match(hash)
- # see if we can match the has against an existing object
- if model.find { |obj| obj.value(:name) == hash[:name] }
- return obj
- else
- return false
- end
- end
-
- # Prefetch our interface list, yo.
- def self.prefetch(resources)
- instances.each do |prov|
- if resource = resources[prov.name]
- resource.provider = prov
- end
- end
- end
-
- def initialize(*args)
- @property_hash = {}
- super
- end
-
- def create
- self.class.resource_type.validproperties.each do |property|
- if value = resource.should(property)
- @property_hash[property] = value
- end
- end
- @property_hash[:name] = resource.name
-
- return (@resource.class.name.to_s + "_created").intern
- end
-
- def destroy
- File.unlink(file_path)
- @property_hash[:ensure] = :absent
- end
-
- def exists?
- FileTest.exist?(file_path)
- end
-
- # Where should the file be written out? Can be overridden by setting
- # :target in the model.
- def file_path
- self.fail("Could not determine interface") unless interface = @property_hash[:interface] || (resource and resource[:interface])
- return File.join("/etc", "hostname." + interface)
- end
-
- def flush
- return if self.ensure == :absent
- File.open(file_path, "w") { |f| f.print generate() + "\n" }
- end
-
- # Turn our record into a line.
- def generate
- ret = []
- if self.interface_type == :alias
- ret << "addif"
- end
- ret << self.name
-
- if self.ifopts != :absent
- if @property_hash[:ifopts].is_a?(Array)
- ret << @property_hash[:ifopts].join(" ")
- else
- ret << @property_hash[:ifopts]
- end
- end
-
- if self.onboot and ! [:absent, :false].include?(self.onboot)
- ret << "up"
- end
-
- return ret.join(" ")
- end
-
- # Parse our interface file.
- def parse
- (@property_hash = {:ensure => :absent} and return) unless FileTest.exist?(file_path)
-
- values = File.read(file_path).chomp.split(/\s+/)
-
- @property_hash[:ensure] = :present
- #@property_hash = {:ensure => :present}
-
- # Are we the primary interface?
- if values[0] == "addif"
- @property_hash[:interface_type] = :alias
- values.shift
- else
- @property_hash[:interface_type] = :normal
- end
-
- # Should the interface be up by default?
- if values[-1] == "up"
- @property_hash[:onboot] = :true
- values.pop
- else
- @property_hash[:onboot] = :false
- end
-
- # Set the interface name.
- @property_hash[:name] = values.shift
-
- # Handle any interface options
- unless values.empty?
- @property_hash[:ifopts] = values.join(" ")
- end
- end
-end
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb
index 7cb6626de..351ebcd1b 100644
--- a/lib/puppet/provider/ssh_authorized_key/parsed.rb
+++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb
@@ -29,21 +29,5 @@ Puppet::Type.type(:ssh_authorized_key).provide(:parsed,
record[:options] = record[:options].join(',')
end
}
-
- def prefetch
- if not @resource.should(:target)
- #
- # Set default target when user is given
- if val = @resource.should(:user)
- target = File.expand_path("~%s/.ssh/authorized_keys" % val)
- Puppet::debug("Setting target to %s" % target)
- @resource[:target] = target
- else
- raise Puppet::Error, "Missing attribute 'user' or 'target'"
- end
- end
-
- super
- end
end
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index fb00a592d..e6dc60681 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -2,10 +2,12 @@
# and performs them
require 'puppet'
-require 'puppet/propertychange'
module Puppet
class Transaction
+ require 'puppet/transaction/change'
+ require 'puppet/transaction/event'
+
attr_accessor :component, :catalog, :ignoreschedules
attr_accessor :sorted_resources, :configurator
@@ -96,7 +98,7 @@ class Transaction
# Create an edge with this resource as both the source and
# target. The triggering method treats these specially for
# logging.
- events = resourceevents.collect { |e| e.event }
+ events = resourceevents.collect { |e| e.name }
set_trigger(Puppet::Relationship.new(resource, resource, :callback => :refresh, :event => events))
end
end
@@ -109,7 +111,6 @@ class Transaction
changes.collect { |change|
@changes << change
@count += 1
- change.transaction = self
events = nil
begin
# use an array, so that changes can return more than one
@@ -278,7 +279,7 @@ class Transaction
# of course, bad.
edge = orig_edge.class.new(orig_edge.source, orig_edge.target)
label = orig_edge.label.dup
- label[:event] = events.collect { |e| e.event }
+ label[:event] = events.collect { |e| e.name }
edge.label = label
set_trigger(edge)
end
@@ -680,11 +681,7 @@ class Transaction
[callback, subs.length]
# And then add an event for it.
- return [Puppet::Event.new(
- :event => :noop,
- :transaction => self,
- :source => resource
- )]
+ return [Puppet::Transaction::Event.new(:noop, resource)]
end
if subs.length == 1 and subs[0].source == resource
@@ -712,11 +709,7 @@ class Transaction
end
# And then add an event for it.
- trigged << Puppet::Event.new(
- :event => :triggered,
- :transaction => self,
- :source => resource
- )
+ trigged << Puppet::Transaction::Event.new(:triggered, resource)
triggered(resource, callback)
end
diff --git a/lib/puppet/transaction/change.rb b/lib/puppet/transaction/change.rb
new file mode 100644
index 000000000..e05c2592c
--- /dev/null
+++ b/lib/puppet/transaction/change.rb
@@ -0,0 +1,94 @@
+require 'puppet/transaction'
+require 'puppet/transaction/event'
+
+# Handle all of the work around performing an actual change,
+# including calling 'sync' on the properties and producing events.
+class Puppet::Transaction::Change
+ attr_accessor :is, :should, :path, :property, :changed, :proxy
+
+ # Switch the goals of the property, thus running the change in reverse.
+ def backward
+ @is, @should = @should, @is
+ @property.should = @should
+
+ @property.info "Reversing %s" % self
+ return self.go
+ end
+
+ def changed?
+ self.changed
+ end
+
+ # Create our event object.
+ def event(name)
+ # default to a simple event type
+ unless name.is_a?(Symbol)
+ @property.warning("Property '%s' returned invalid event '%s'; resetting to default" %
+ [@property.class, name])
+
+ name = @property.event(should)
+ end
+
+ Puppet::Transaction::Event.new(name, self.resource)
+ end
+
+ def initialize(property, currentvalue)
+ @property = property
+ @path = [property.path,"change"].flatten
+ @is = currentvalue
+
+ @should = property.should
+
+ @changed = false
+ end
+
+ # Perform the actual change. This method can go either forward or
+ # backward, and produces an event.
+ def go
+ if self.noop?
+ @property.log "is %s, should be %s (noop)" % [property.is_to_s(@is), property.should_to_s(@should)]
+ return [event(:noop)]
+ end
+
+ # The transaction catches any exceptions here.
+ events = @property.sync
+ if events.nil?
+ return nil
+ end
+
+ if events.is_a?(Array)
+ if events.empty?
+ return nil
+ end
+ else
+ events = [events]
+ end
+
+ return events.collect { |name|
+ @report = @property.log(@property.change_to_s(@is, @should))
+ event(name)
+ }
+ end
+
+ def forward
+ return self.go
+ end
+
+ # Is our property noop? This is used for generating special events.
+ def noop?
+ return @property.noop
+ end
+
+ # The resource that generated this change. This is used for handling events,
+ # and the proxy resource is used for generated resources, since we can't
+ # send an event to a resource we don't have a direct relationship. If we
+ # have a proxy resource, then the events will be considered to be from
+ # that resource, rather than us, so the graph resolution will still work.
+ def resource
+ self.proxy || @property.resource
+ end
+
+ def to_s
+ return "change %s" % @property.change_to_s(@is, @should)
+ end
+end
diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb
new file mode 100644
index 000000000..f1a48b382
--- /dev/null
+++ b/lib/puppet/transaction/event.rb
@@ -0,0 +1,21 @@
+require 'puppet'
+require 'puppet/util/methodhelper'
+require 'puppet/util/errors'
+
+# events are transient packets of information; they result in one or more (or none)
+# subscriptions getting triggered, and then they get cleared
+# eventually, these will be passed on to some central event system
+class Puppet::Transaction::Event
+ include Puppet::Util::MethodHelper
+ include Puppet::Util::Errors
+
+ attr_reader :name, :source
+
+ def initialize(name, source)
+ @name, @source = name, source
+ end
+
+ def to_s
+ source.to_s + " -> " + name.to_s
+ end
+end
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 7deb25fff..a6aff152c 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -1,6 +1,5 @@
require 'puppet'
require 'puppet/util/log'
-require 'puppet/event'
require 'puppet/util/metric'
require 'puppet/property'
require 'puppet/parameter'
@@ -415,7 +414,6 @@ class Type
end # Puppet::Type
end
-require 'puppet/propertychange'
require 'puppet/provider'
# Always load these types.
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index 0d2171216..a9ddc2dba 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -138,11 +138,6 @@ module Puppet
# We have to treat :present specially, because it works with any
# type of file.
def insync?(currentvalue)
- if property = @resource.property(:source) and ! property.described?
- warning "No specified sources exist"
- return true
- end
-
if self.should == :present
if currentvalue.nil? or currentvalue == :absent
return false
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 1b0dd3141..f2704abb6 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -135,18 +135,8 @@ module Puppet
return args
end
- # Have we successfully described the remote source?
- def described?
- ! @stats.nil? and ! @stats[:type].nil? #and @is != :notdescribed
- end
-
# Use the info we get from describe() to check if we're in sync.
def insync?(currentvalue)
- unless described?
- warning "No specified sources exist"
- return true
- end
-
if currentvalue == :nocopy
return true
end
@@ -180,7 +170,11 @@ module Puppet
def pinparams
[:mode, :type, :owner, :group]
end
-
+
+ def found?
+ ! (@stats.nil? or @stats[:type].nil?)
+ end
+
# This basically calls describe() on our file, and then sets all
# of the local states appropriately. If the remote file is a normal
# file then we set it to copy; if it's a directory, then we just mark
@@ -202,8 +196,8 @@ module Puppet
}
end
- if @stats.nil? or @stats[:type].nil?
- return nil # :notdescribed
+ if !found?
+ raise Puppet::Error, "No specified source was found from" + @should.inject("") { |s, source| s + " #{source},"}.gsub(/,$/,"")
end
case @stats[:type]
diff --git a/lib/puppet/type/interface.rb b/lib/puppet/type/interface.rb
deleted file mode 100644
index 2f6c28ad3..000000000
--- a/lib/puppet/type/interface.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-Puppet::Type.newtype(:interface) do
- require 'erb'
-
- @doc = "Create configuration for IP address aliases and loopback addresses."
-
- newparam(:name, :namevar => true) do
- desc "The ipaddress to add to alias or loopback/dummy interface"
- end
-
- ensurable
-
- newparam(:interface) do
- desc "The interface the IP should be added to"
- end
-
- newproperty(:interface_type) do
- desc "The interface type, loopback (also dummy) or alias"
-
- newvalue(:loopback)
- newvalue(:alias)
- newvalue(:normal)
-
- # Make dummy and loopback equivalent
- aliasvalue(:dummy, :loopback)
-
- defaultto :normal
- end
-
- newparam(:interface_desc) do
- desc "On Linux, the description / symbolic name you wish to refer to the
- interface by. When absent, Redhat Linux defaults to uses the namevar
- which will be either the IP address, or hostname."
- end
-
- newproperty(:onboot) do
- desc "Whether the interface should be configured to come up on boot"
- newvalue(:true)
- newvalue(:false)
- end
-
- newproperty(:ifnum) do
- desc "If not automatically configuring the dummy interface or
- and alias. This is use to force a given number to be used"
- end
-
- newproperty(:netmask) do
- desc "The netmask for the interface."
- end
-
- newproperty(:ifopts) do
- desc "Interface options."
- end
-
- newparam(:target) do
- include Puppet::Util::Warnings
- desc "The path to the file this resource creates."
-
- munge { |value| warnonce "Interface targets are deprecated and no longer have any function" }
- end
-end
diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb
index e28fb7cda..3a12e95ad 100644
--- a/lib/puppet/type/ssh_authorized_key.rb
+++ b/lib/puppet/type/ssh_authorized_key.rb
@@ -5,14 +5,14 @@ module Puppet
ensurable
newparam(:name) do
- desc "The ssh key comment."
+ desc "The SSH key comment."
isnamevar
end
newproperty(:type) do
- desc "The encryption type used. Probably ssh-dss or ssh-rsa for
- ssh version 2. Not used for ssh version 1."
+ desc "The encryption type used. Usually ssh-dss or ssh-rsa for
+ SSH version 2. Not used for SSH version 1."
newvalue("ssh-dss")
newvalue("ssh-rsa")
@@ -26,19 +26,55 @@ module Puppet
end
newproperty(:user) do
- desc "The user account in which the ssh key should be installed."
+ desc "The user account in which the SSH key should be installed."
+
+ def value=(value)
+ @resource[:target] = File.expand_path("~%s/.ssh/authorized_keys" % value)
+ super
+ end
end
newproperty(:target) do
- desc "The file in which to store the ssh key."
+ desc "The file in which to store the SSH key."
end
newproperty(:options, :array_matching => :all) do
- desc "Key options, see sshd(8) for possible values. Multiple values
- should be specified as an array."
+ desc "Key options, see sshd(8) for possible values. Multiple values
+ should be specified as an array."
defaultto do :absent end
end
+
+ def generate
+ atype = Puppet::Type.type(:file)
+ target = self.should(:target)
+ dir = File.dirname(target)
+ user = should(:user) ? should(:user) : "root"
+
+ rels = []
+
+ unless catalog.resource(:file, dir)
+ rels << atype.create(:name => dir, :ensure => :directory, :mode => 0700, :owner => user)
+ end
+
+ unless catalog.resource(:file, target)
+ rels << atype.create(:name => target, :ensure => :present, :mode => 0600, :owner => user)
+ end
+
+ rels
+ end
+
+ autorequire(:user) do
+ if should(:user)
+ should(:user)
+ end
+ end
+
+ validate do
+ unless should(:target)
+ raise Puppet::Error, "Attribute 'user' or 'target' is mandatory"
+ end
+ end
end
end
diff --git a/lib/puppet/type/yumrepo.rb b/lib/puppet/type/yumrepo.rb
index 8800dd71d..cb7c7401b 100644
--- a/lib/puppet/type/yumrepo.rb
+++ b/lib/puppet/type/yumrepo.rb
@@ -1,6 +1,5 @@
# Description of yum repositories
-require 'puppet/propertychange'
require 'puppet/util/inifile'
module Puppet
diff --git a/lib/puppet/util/ldap/connection.rb b/lib/puppet/util/ldap/connection.rb
index 861539872..f6530f853 100644
--- a/lib/puppet/util/ldap/connection.rb
+++ b/lib/puppet/util/ldap/connection.rb
@@ -63,7 +63,6 @@ class Puppet::Util::Ldap::Connection
@connection.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
@connection.simple_bind(user, password)
rescue => detail
- puts detail.class
raise Puppet::Error, "Could not connect to LDAP: %s" % detail
end
end
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index aeda88e09..b6855dfa5 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -644,13 +644,10 @@ Generated on #{Time.now}.
begin
catalog.host_config = false
catalog.apply do |transaction|
- if failures = transaction.any_failed?
- # LAK:NOTE We should do something like this for some cases,
- # since it can otherwise be hard to know what failed.
- #transaction.report.logs.find_all { |log| log.level == :err }.each do |log|
- # puts log.message
- #end
- raise "Could not configure myself; got %s failure(s)" % failures
+ if transaction.any_failed?
+ report = transaction.report
+ failures = report.logs.find_all { |log| log.level == :err }
+ raise "Got %s failure(s) while initializing: %s" % [failures.length, failures.collect { |l| l.to_s }.join("; ")]
end
end
end