The main Puppet class. Everything is contained here.
@api public
The majority of Puppet’s configuration settings are set in this file.
see the bottom of the file for the rest of the inclusions
Manage file modes. This state should support different formats for specification (e.g., u+rwx, or -0011), but for now only supports specifying the full mode.
Manage SELinux context of files.
This code actually manages three pieces of data in the context.
[root@delenn files]# ls -dZ / drwxr-xr-x root root system_u:object_r:root_t /
The context of ‘/’ here is ‘system_u:object_r:root_t’. This is three seperate fields:
system_u is the user context object_r is the role context root_t is the type context
All three of these fields are returned in a single string by the output of the stat command, but set individually with the chcon command. This allows the user to specify a subset of the three values while leaving the others alone.
See www.nsa.gov/selinux/ for complete docs on SELinux.
Simple module for logging messages on the client-side
Manage a router abstraction
This is our main way of managing processes right now.
a service is distinct from a process in that services can only be managed through the interface of an init script which is why they have a search path for initscripts and such
A common module for converting between constants and file names.
This system manages an extensible set of metadata about plugins which it
collects by searching for files named "plugin_init.rb" in a series of directories. Initially, these are simply the $LOAD_PATH.
The contents of each file found is executed in the context of a Puppet::Plugins
object (and thus scoped). An example file might contain:
@name = "Greet the CA" @description = %q{ This plugin causes a friendly greeting to print out on a master that is operating as the CA, after it has been set up but before it does anything. } def after_application_setup(options) if options[:application_object].is_a?(Puppet::Application::Master) && Puppet::SSL::CertificateAuthority.ca? puts "Hey, this is the CA!" end end
Note that the instance variables are local to this Puppet::Plugin (and so may be used
for maintaining state, etc.) but the plugin system does not provide any thread safety assurances, so they may not be adequate for some complex use cases.
The version method and constant are isolated in puppet/version.rb so that a simple `require ‘puppet/version’` allows a rubygems gemspec or bundler Gemfile to get the Puppet version of the gem install.
The version is programatically settable because we want to allow the Raketasks and such to set the version based on the output of `git describe`
Doc string for properties that can be made ‘absent’
Pass feedback to the user. Log levels are modeled after syslog’s, and it is expected that that will be the most common log destination. Supports multiple destinations, one of which is a remote server.
A class for handling metrics. This is currently ridiculously hackish.
The writer is only used for testing, there should be no need to change yumconf or inifile in any other context
Get the value for a setting
@param [Symbol] param the setting to retrieve
@api public
# File lib/puppet.rb, line 60 def self.[](param) if param == :debug return Puppet::Util::Log.level == :debug else return @@settings[param] end end
configuration parameter access and stuff
# File lib/puppet.rb, line 69 def self.[]=(param,value) @@settings[param] = value end
# File lib/puppet/type/exec.rb, line 41 def self.checks @checks.keys end
# File lib/puppet.rb, line 73 def self.clear @@settings.clear end
# File lib/puppet.rb, line 77 def self.debug=(value) if value Puppet::Util::Log.level=(:debug) else Puppet::Util::Log.level=(:notice) end end
Store a new default value.
# File lib/puppet.rb, line 51 def self.define_settings(section, hash) @@settings.define_settings(section, hash) end
# File lib/puppet.rb, line 107 def self.genmanifest if Puppet[:genmanifest] puts Puppet.settings.to_manifest exit(0) end end
Return the Puppet::Util::IniConfig::File for the whole yum config
# File lib/puppet/type/yumrepo.rb, line 105 def self.inifile if @inifile.nil? @inifile = read main = @inifile['main'] raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil? reposdir = main['reposdir'] reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d" reposdir.gsub!(/[\n,]/, " ") reposdir.split.each do |dir| Dir::glob("#{dir}/*.repo").each do |file| @inifile.read(file) if ::File.file?(file) end end reposdir.split.each do |dir| if ::File.directory?(dir) && ::File.writable?(dir) @defaultrepodir = dir break end end end @inifile end
Initialize puppet’s settings. This is intended only for use by external tools that are not
built off of the Faces API or the Puppet::Util::Application class. It may also be used to initialize state so that a Face may be used programatically, rather than as a stand-alone command-line tool.
@api public @param args [Array<String>] the command line arguments to use for initialization @return [void]
# File lib/puppet.rb, line 129 def self.initialize_settings(args = []) do_initialize_settings_for_run_mode(:user, args) end
Initialize puppet’s settings for a specified run_mode.
@deprecated Use {#initialize_settings}
# File lib/puppet.rb, line 136 def self.initialize_settings_for_run_mode(run_mode) Puppet.deprecation_warning("initialize_settings_for_run_mode may be removed in a future release, as may run_mode itself") do_initialize_settings_for_run_mode(run_mode, []) end
# File lib/puppet/type/exec.rb, line 485 def self.instances [] end
Create a default filebucket.
# File lib/puppet/type/filebucket.rb, line 79 def self.mkdefaultbucket new(:name => "puppet", :path => Puppet[:clientbucketdir]) end
# File lib/puppet/type/schedule.rb, line 422 def self.mkdefaultschedules result = [] Puppet.debug "Creating default schedules" result << self.new( :name => "puppet", :period => :hourly, :repeat => "2" ) # And then one for every period @parameters.find { |p| p.name == :period }.value_collection.values.each { |value| result << self.new( :name => value.to_s, :period => value ) } result end
Create a new check mechanism. It’s basically just a parameter that provides one extra ‘check’ method.
# File lib/puppet/type/exec.rb, line 34 def self.newcheck(name, options = {}, &block) @checks ||= {} check = newparam(name, options, &block) @checks[name] = check end
Create a new type. Just proxy to the Type class. The mirroring query code was deprecated in 2008, but this is still in heavy use. I suppose this can count as a soft deprecation for the next dev. –daniel 2011-04-12
# File lib/puppet.rb, line 153 def self.newtype(name, options = {}, &block) Puppet::Type.newtype(name, options, &block) end
Parse the config file for this process. @deprecated Use {#initialize_settings}
# File lib/puppet.rb, line 116 def self.parse_config() Puppet.deprecation_warning("Puppet.parse_config is deprecated; please use Faces API (which will handle settings and state management for you), or (less desirable) call Puppet.initialize_settings") Puppet.initialize_settings end
Parse the yum config files. Only exposed for the tests Non-test code should use self.inifile to get at the underlying file
# File lib/puppet/type/yumrepo.rb, line 131 def self.read result = Puppet::Util::IniConfig::File.new result.read(yumconf) main = result['main'] raise Puppet::Error, "File #{yumconf} does not contain a main section" if main.nil? reposdir = main['reposdir'] reposdir ||= "/etc/yum.repos.d, /etc/yum/repos.d" reposdir.gsub!(/[\n,]/, " ") reposdir.split.each do |dir| Dir::glob("#{dir}/*.repo").each do |file| result.read(file) if ::File.file?(file) end end if @defaultrepodir.nil? reposdir.split.each do |dir| if ::File.directory?(dir) && ::File.writable?(dir) @defaultrepodir = dir break end end end result end
# File lib/puppet.rb, line 90 def self.run_mode # This sucks (the existence of this method); there are a lot of places in our code that branch based the value of # "run mode", but there used to be some really confusing code paths that made it almost impossible to determine # when during the lifecycle of a puppet application run the value would be set properly. A lot of the lifecycle # stuff has been cleaned up now, but it still seems frightening that we rely so heavily on this value. # # I'd like to see about getting rid of the concept of "run_mode" entirely, but there are just too many places in # the code that call this method at the moment... so I've settled for isolating it inside of the Settings class # (rather than using a global variable, as we did previously...). Would be good to revisit this at some point. # # --cprice 2012-03-16 Puppet::Util::RunMode[@@settings.preferred_run_mode] end
Return the Puppet::Util::IniConfig::Section with name NAME from the yum config
# File lib/puppet/type/yumrepo.rb, line 157 def self.section(name) result = inifile[name] if result.nil? # Brand new section path = yumconf path = ::File.join(@defaultrepodir, "#{name}.repo") unless @defaultrepodir.nil? Puppet::info "create new repo #{name} in file #{path}" result = inifile.add_section(name, path) end result end
# File lib/puppet.rb, line 85 def self.settings @@settings end
Store all modifications back to disk
# File lib/puppet/type/yumrepo.rb, line 170 def self.store inifile.store unless Puppet[:noop] target_mode = 0644 # FIXME: should be configurable inifile.each_file do |file| current_mode = ::File.stat(file).mode & 0777 unless current_mode == target_mode Puppet::info "changing mode of #{file} from %03o to %03o" % [current_mode, target_mode] ::File.chmod(target_mode, file) end end end end
version is a public API method intended to always provide a fast and lightweight way to determine the version of Puppet.
The intent is that software external to Puppet be able to determine the Puppet version with no side-effects. The expected use is:
require 'puppet/version' version = Puppet.version
This function has the following ordering precedence. This precedence list is designed to facilitate automated packaging tasks by simply writing to the VERSION file in the same directory as this source file.
1. If a version has been explicitly assigned using the Puppet.version= method, return that version. 2. If there is a VERSION file, read the contents, trim any trailing whitespace, and return that version string. 3. Return the value of the Puppet::PUPPETVERSION constant hard-coded into the source code.
If there is no VERSION file, the method must return the version string of the nearest parent version that is an officially released version. That is to say, if a branch named 3.1.x contains 25 patches on top of the most recent official release of 3.1.1, then the version method must return the string “3.1.1” if no “VERSION” file is present.
By design the version identifier is not intended to vary during the life a process. There is no guarantee provided that writing to the VERSION file while a Puppet process is running will cause the version string to be updated. On the contrary, the contents of the VERSION are cached to reduce filesystem accesses.
The VERSION file is intended to be used by package maintainers who may be applying patches or otherwise changing the software version in a manner that warrants a different software version identifier. The VERSION file is intended to be managed and owned by the release process and packaging related tasks, and as such should not reside in version control. The PUPPETVERSION constant is intended to be version controlled in history.
Ideally, this behavior will allow package maintainers to precisely specify the version of the software they’re packaging as in the following example:
$ git describe --match "3.0.*" > lib/puppet/VERSION $ ruby -r puppet -e 'puts Puppet.version' 3.0.1-260-g9ca4e54
@api public
@return [String] containing the puppet version, e.g. “3.0.1”
# File lib/puppet/version.rb, line 62 def self.version version_file = File.join(File.dirname(__FILE__), 'VERSION') return @puppet_version if @puppet_version if version = read_version_file(version_file) @puppet_version = version end @puppet_version ||= PUPPETVERSION end
# File lib/puppet/version.rb, line 71 def self.version=(version) @puppet_version = version end
# File lib/puppet/type/filebucket.rb, line 83 def bucket mkbucket unless defined?(@bucket) @bucket end
Make output a bit prettier
# File lib/puppet/type/exec.rb, line 63 def change_to_s(currentvalue, newvalue) "executed successfully" end
We always fail this test, because we’re only supposed to run on refresh.
# File lib/puppet/type/exec.rb, line 304 def check(value) # We have to invert the values. if value == :true false else true end end
Verify that we pass all of the checks. The argument determines whether we skip the :refreshonly check, which is necessary because we now check within refresh
# File lib/puppet/type/exec.rb, line 492 def check_all_attributes(refreshing = false) self.class.checks.each { |check| next if refreshing and check == :refreshonly if @parameters.include?(check) val = @parameters[check].value val = [val] unless val.is_a? Array val.each do |value| return false unless @parameters[check].check(value) end end } true end
# File lib/puppet/type/file/source.rb, line 95 def checksum metadata && metadata.checksum end
# File lib/puppet/type/file/content.rb, line 75 def checksum_type if source = resource.parameter(:source) result = source.checksum else checksum = resource.parameter(:checksum) result = resource[:checksum] end if result =~ /^\{(\w+)\}.+/ return $1.to_sym else return result end end
# File lib/puppet/type/file/content.rb, line 195 def chunk_file_from_disk(source_or_content) File.open(source_or_content.full_path, "rb") do |src| while chunk = src.read(8192) yield chunk end end end
# File lib/puppet/type/file/content.rb, line 213 def chunk_file_from_source(source_or_content) get_from_source(source_or_content) do |response| case response.code when /^2/; uncompress(response) { |uncompressor| response.read_body { |chunk| yield uncompressor.uncompress(chunk) } } else # Raise the http error if we didn't get a 'success' of some kind. message = "Error #{response.code} on SERVER: #{(response.body||'').empty? ? response.message : uncompress_body(response)}" raise Net::HTTPError.new(message, response) end end end
This only exists for testing.
# File lib/puppet/type/package.rb, line 362 def clear if obj = @parameters[:ensure] obj.latest = nil end end
# File lib/puppet/type/file/content.rb, line 92 def content self.should end
# File lib/puppet/type/file/content.rb, line 191 def content_is_really_a_checksum? checksum?(should) end
Copy the values from the source to the resource. Yay.
# File lib/puppet/type/file/source.rb, line 111 def copy_source_values devfail "Somehow got asked to copy source values without any metadata" unless metadata # Take each of the stats and set them as states on the local file # if a value has not already been provided. [:owner, :mode, :group, :checksum].each do |metadata_method| param_name = (metadata_method == :checksum) ? :content : metadata_method next if metadata_method == :owner and !Puppet.features.root? next if metadata_method == :checksum and metadata.ftype == "directory" next if metadata_method == :checksum and metadata.ftype == "link" and metadata.links == :manage if Puppet.features.microsoft_windows? next if [:owner, :group].include?(metadata_method) and !local? end if resource[param_name].nil? or resource[param_name] == :absent resource[param_name] = metadata.send(metadata_method) end end if resource[:ensure] == :absent # We know all we need to elsif metadata.ftype != "link" resource[:ensure] = metadata.ftype elsif @resource[:links] == :follow resource[:ensure] = :present else resource[:ensure] = "link" resource[:target] = metadata.destination end end
# File lib/puppet/type/group.rb, line 122 def delimiter " " end
# File lib/puppet/type/file/mode.rb, line 74 def desired_mode_from_current(desired, current) current = current.to_i(8) if current.is_a? String is_a_directory = @resource.stat and @resource.stat.directory? symbolic_mode_to_int(desired, current, is_a_directory) end
If we’re a directory, we need to be executable for all cases that are readable. This should probably be selectable, but eh.
# File lib/puppet/type/file/mode.rb, line 82 def dirmask(value) orig = value if FileTest.directory?(resource[:path]) and value =~ /^\d+$/ then value = value.to_i(8) value |= 0100 if value & 0400 != 0 value |= 010 if value & 040 != 0 value |= 01 if value & 04 != 0 value = value.to_s(8) end value end
the content is munged so if it’s a checksum source_or_content is nil unless the checksum indirectly comes from source
# File lib/puppet/type/file/content.rb, line 173 def each_chunk_from(source_or_content) if source_or_content.is_a?(String) yield source_or_content elsif content_is_really_a_checksum? && source_or_content.nil? yield read_file_from_filebucket elsif source_or_content.nil? yield '' elsif Puppet[:default_file_terminus] == :file_server yield source_or_content.content elsif source_or_content.local? chunk_file_from_disk(source_or_content) { |chunk| yield chunk } else chunk_file_from_source(source_or_content) { |chunk| yield chunk } end end
# File lib/puppet/type/exec.rb, line 51 def event_name :executed_command end
This method has been exposed for puppet to manage users and groups of files in its settings and should not be considered available outside of puppet.
(see Puppet::Settings#service_group_available?)
@returns [Boolean] if the group exists on the system @api private
# File lib/puppet/type/group.rb, line 157 def exists? provider.exists? end
Store modifications to this yumrepo resource back to disk
# File lib/puppet/type/yumrepo.rb, line 197 def flush self.class.store end
# File lib/puppet/type/file/source.rb, line 143 def found? ! (metadata.nil? or metadata.ftype.nil?) end
# File lib/puppet/type/file/source.rb, line 174 def full_path Puppet::Util.uri_to_path(uri) if found? end
# File lib/puppet/type/maillist.rb, line 48 def generate if provider.respond_to?(:aliases) should = self.should(:ensure) || :present if should == :purged should = :absent end atype = Puppet::Type.type(:mailalias) provider.aliases. reject { |name,recipient| catalog.resource(:mailalias, name) }. collect { |name,recipient| atype.new(:name => name, :recipient => recipient, :ensure => should) } end end
# File lib/puppet/type/file/content.rb, line 203 def get_from_source(source_or_content, &block) request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path.sub(/^\//,''), nil, :environment => resource.catalog.environment) request.do_request(:fileserver) do |req| connection = Puppet::Network::HttpPool.http_instance(req.server, req.port) connection.request_get(indirection2uri(req), add_accept_encoding({"Accept" => "raw"}), &block) end end
# File lib/puppet/type/host.rb, line 41 def inclusive? true end
Override this method to provide diffs if asked for. Also, fix #872: when content is used, and replace is true, the file should be insync when it exists
# File lib/puppet/type/file/content.rb, line 99 def insync?(is) if resource.should_be_file? return false if is == :absent else return true end return true if ! @resource.replace? result = super if ! result and Puppet[:show_diff] write_temporarily do |path| notice "\n" + diff(@resource[:path], path) end end result end
We want to print names, not numbers
# File lib/puppet/type/file/group.rb, line 33 def is_to_s(currentvalue) provider.gid2name(currentvalue) || currentvalue end
# File lib/puppet/type/file/content.rb, line 88 def length (actual_content and actual_content.length) || 0 end
# File lib/puppet/type/file/source.rb, line 170 def local? found? and scheme == "file" end
# File lib/puppet/type/schedule.rb, line 130 def match?(previous, now) # The lowest-level array is of the hour, minute, second triad # then it's an array of two of those, to present the limits # then it's array of those ranges @value = [@value] unless @value[0][0].is_a?(Array) @value.each do |value| limits = value.collect do |range| ary = [now.year, now.month, now.day, range[0]] if range[1] ary << range[1] else ary << 0 end if range[2] ary << range[2] else ary << 0 end time = Time.local(*ary) unless time.hour == range[0] self.devfail( "Incorrectly converted time: #{time}: #{time.hour} vs #{range[0]}" ) end time end unless limits[0] < limits[1] self.info( "Assuming upper limit should be that time the next day" ) # Find midnight between the two days. Adding one second # to the end of the day is easier than dealing with dates. ary = limits[0].to_a ary[0] = 59 ary[1] = 59 ary[2] = 23 midnight = Time.local(*ary)+1 # If it is currently between the range start and midnight # we consider that a successful match. if now.between?(limits[0], midnight) # We have to check the weekday match here as it is special-cased # to support day-spanning ranges. if @resource[:weekday] return false unless @resource[:weekday].has_key?(now.wday) end return true end # If we didn't match between the starting time and midnight # we must now move our midnight back 24 hours and try # between the new midnight (24 hours prior) and the # ending time. midnight -= 86400 # Now we compare the current time between midnight and the # end time. if now.between?(midnight, limits[1]) # This case is the reason weekday matching is special cased # in the range parameter. If we match a range that has spanned # past midnight we want to match against the weekday when the range # started, not when it currently is. if @resource[:weekday] return false unless @resource[:weekday].has_key?((now - 86400).wday) end return true end # If neither of the above matched then we don't match the # range schedule. return false end # Check to see if a weekday parameter was specified and, if so, # do we match it or not. If we fail we can stop here. # This is required because spanning ranges forces us to check # weekday within the range parameter. if @resource[:weekday] return false unless @resource[:weekday].has_key?(now.wday) end return true if now.between?(*limits) end # Else, return false, since our current time isn't between # any valid times false end
# File lib/puppet/type/group.rb, line 118 def membership :attribute_membership end
Provide, and retrieve if necessary, the metadata for this file. Fail if we can’t find data about this host, and fail if there are any problems in our query.
# File lib/puppet/type/file/source.rb, line 152 def metadata return @metadata if @metadata return nil unless value value.each do |source| begin if data = Puppet::FileServing::Metadata.indirection.find(source, :environment => resource.catalog.environment) @metadata = data @metadata.source = source break end rescue => detail fail detail, "Could not retrieve file metadata for #{source}: #{detail}" end end fail "Could not retrieve information from environment #{resource.catalog.environment} source(s) #{value.join(", ")}" unless @metadata @metadata end
# File lib/puppet/type/filebucket.rb, line 90 def mkbucket # Default is a local filebucket, if no server is given. # If the default path has been removed, too, then # the puppetmaster is used as default server type = "local" args = {} if self[:path] args[:Path] = self[:path] else args[:Server] = self[:server] args[:Port] = self[:port] end begin @bucket = Puppet::FileBucket::Dipper.new(args) rescue => detail message = "Could not create #{type} filebucket: #{detail}" self.log_exception(detail, message) self.fail(message) end @bucket.name = self.name end
Create our link.
# File lib/puppet/type/file/target.rb, line 34 def mklink raise Puppet::Error, "Cannot symlink on Microsoft Windows" if Puppet.features.microsoft_windows? target = self.should # Clean up any existing objects. The argument is just for logging, # it doesn't determine what's removed. @resource.remove_existing(target) raise Puppet::Error, "Could not remove existing file" if FileTest.exists?(@resource[:path]) Dir.chdir(File.dirname(@resource[:path])) do Puppet::Util::SUIDManager.asuser(@resource.asuser) do mode = @resource.should(:mode) if mode Puppet::Util.withumask(000) do File.symlink(target, @resource[:path]) end else File.symlink(target, @resource[:path]) end end @resource.send(:property_fix) :link_created end end
# File lib/puppet/type/exec.rb, line 507 def output if self.property(:returns).nil? return nil else return self.property(:returns).output end end
# File lib/puppet/type/file/source.rb, line 186 def port (uri and uri.port) or Puppet.settings[:masterport] end
# File lib/puppet/type/file/mode.rb, line 106 def property_matches?(current, desired) return false unless current current_bits = normalize_symbolic_mode(current) desired_bits = desired_mode_from_current(desired, current).to_s(8) current_bits == desired_bits end
# File lib/puppet/type/file/content.rb, line 225 def read_file_from_filebucket raise "Could not get filebucket from file" unless dipper = resource.bucket sum = should.sub(/\{\w+\}/, '') dipper.getfile(sum) rescue => detail fail "Could not retrieve content for #{should} from filebucket: #{detail}" end
Run the command, or optionally run a separately-specified command.
# File lib/puppet/type/exec.rb, line 516 def refresh if self.check_all_attributes(true) if cmd = self[:refresh] provider.run(cmd) else self.property(:returns).sync end end end
First verify that all of our checks pass.
# File lib/puppet/type/exec.rb, line 68 def retrieve # We need to return :notrun to trigger evaluation; when that isn't # true, we *LIE* about what happened and return a "success" for the # value, which causes us to be treated as in_sync?, which means we # don't actually execute anything. I think. --daniel 2011-03-10 if @resource.check_all_attributes return :notrun else return self.should end end
# File lib/puppet/type/file/source.rb, line 191 def scheme (uri and uri.scheme) end
Return the Puppet::Util::IniConfig::Section for this yumrepo resource
# File lib/puppet/type/yumrepo.rb, line 192 def section self.class.section(self[:name]) end
# File lib/puppet/type/file/source.rb, line 182 def server (uri and uri.host) or Puppet.settings[:server] end
# File lib/puppet/type/file/source.rb, line 178 def server? uri and uri.host end
# File lib/puppet/type/mailalias.rb, line 23 def should @should end
Make sure we’re also managing the checksum property.
# File lib/puppet/type/file/content.rb, line 132 def should=(value) @resource.newattr(:checksum) unless @resource.parameter(:checksum) super end
# File lib/puppet/type/file/group.rb, line 37 def should_to_s(newvalue) provider.gid2name(newvalue) || newvalue end
Actually execute the command.
# File lib/puppet/type/exec.rb, line 81 def sync olddir = nil # We need a dir to change to, even if it's just the cwd dir = self.resource[:cwd] || Dir.pwd event = :executed_command tries = self.resource[:tries] try_sleep = self.resource[:try_sleep] begin tries.times do |try| # Only add debug messages for tries > 1 to reduce log spam. debug("Exec try #{try+1}/#{tries}") if tries > 1 @output, @status = provider.run(self.resource[:command]) break if self.should.include?(@status.exitstatus.to_s) if try_sleep > 0 and tries > 1 debug("Sleeping for #{try_sleep} seconds between tries") sleep try_sleep end end rescue Timeout::Error self.fail "Command exceeded timeout" % value.inspect end if log = @resource[:logoutput] case log when :true log = @resource[:loglevel] when :on_failure unless self.should.include?(@status.exitstatus.to_s) log = @resource[:loglevel] else log = :false end end unless log == :false @output.split(/\n/).each { |line| self.send(log, line) } end end unless self.should.include?(@status.exitstatus.to_s) self.fail("#{self.resource[:command]} returned #{@status.exitstatus} instead of one of [#{self.should.join(",")}]") end event end
# File lib/puppet/type/mount.rb, line 97 def syncothers # We have to flush any changes to disk. currentvalues = @resource.retrieve_resource # Determine if there are any out-of-sync properties. oos = @resource.send(:properties).find_all do |prop| unless currentvalues.include?(prop) raise Puppet::DevError, "Parent has property %s but it doesn't appear in the current values", [prop.name] end if prop.name == :ensure false else ! prop.safe_insync?(currentvalues[prop]) end end.each { |prop| prop.sync }.length @resource.flush if oos > 0 end
# File lib/puppet/type/file/source.rb, line 195 def uri @uri ||= URI.parse(URI.escape(metadata.source)) end
# File lib/puppet/type/host.rb, line 11 def valid_v4?(addr) if /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ =~ addr return $~.captures.all? {|i| i = i.to_i; i >= 0 and i <= 255 } end return false end
# File lib/puppet/type/host.rb, line 18 def valid_v6?(addr) # http://forums.dartware.com/viewtopic.php?t=452 # ...and, yes, it is this hard. Doing it programatically is harder. return true if addr =~ /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ return false end
# File lib/puppet/type/mount.rb, line 223 def value(name) name = name.intern ret = nil if property = @parameters[name] return property.value end end
Support both arrays and colon-separated fields.
# File lib/puppet/type/exec.rb, line 148 def value=(*values) @value = values.flatten.collect { |val| val.split(File::PATH_SEPARATOR) }.flatten end
# File lib/puppet/type/file/content.rb, line 162 def write(file) resource.parameter(:checksum).sum_stream { |sum| each_chunk_from(actual_content || resource.parameter(:source)) { |chunk| sum << chunk file.print chunk } } end
# File lib/puppet/type/file/content.rb, line 149 def write_temporarily tempfile = Tempfile.new("puppet-file") tempfile.open write(tempfile) tempfile.close yield tempfile.path tempfile.delete end