Skip to content
Browse files

Merge branch '2.6.next' into 2.6.x

* 2.6.next: (102 commits)
  (#5073) Download plugins even if you're filtering on tags
  Fix #5610: Prevent unnecessary RAL lookups
  Revert "Merge branch 'ticket/2.6.x/5605' of git://github.com/stschulte/puppet into 2.6.next"
  (#6723) Fix withenv environment restoration bug
  (#6689) Remove extraneous include of Puppet::Util in InventoryActiveRecord
  Remove extra trailing whitespace from lib/puppet/resource.rb
  (#5428) More fully "stub" Puppet::Resource::Reference for use with storedconfigs
  (#6707) Fix typo in rest_authconfig.rb
  (#6689) Make inventory_active_record terminus search quickly
  (#5392) Give a better error when realizing a non-existant resource
  (#2645) Adding a less-stubby test to verify the "system" attribute's behavior
  maint: Remove serialization of InventoryFact values
  maint: Rename InventoryHost to InventoryNode
  Fixed #2645 - Added support for creating system users
  maint: Remove spec run noise
  maint:Refactor of mount provider integration tests
  (#6338) Support searching on metadata in InventoryActiveRecord terminus
  (#6338) Implement search for InventoryActiveRecord facts terminus
  (#6338) Add an InventoryActiveRecord terminus for Facts
  Added integration tests for the mount provider
  ...
  • Loading branch information...
2 parents 86c6035 + c60c6ca commit de8fea8ac8b25f45ffb07a2ef63a6da0cbaf0c41 Matt Robinson committed Mar 16, 2011
Showing with 4,454 additions and 2,825 deletions.
  1. +1 −1 README.queueing
  2. +1 −1 Rakefile
  3. +0 −2 conf/solaris/smf/svc-puppetd
  4. +0 −2 conf/solaris/smf/svc-puppetmasterd
  5. +0 −2 examples/etc/init.d/sleeper
  6. +2 −2 examples/modules/sample-module/README.txt
  7. +1 −1 ext/puppetstoredconfigclean.rb
  8. +20 −25 install.rb
  9. +2 −2 lib/puppet/application/agent.rb
  10. +2 −2 lib/puppet/application/apply.rb
  11. +27 −11 lib/puppet/application/cert.rb
  12. +1 −1 lib/puppet/application/filebucket.rb
  13. +1 −1 lib/puppet/application/inspect.rb
  14. +2 −2 lib/puppet/application/kick.rb
  15. +1 −1 lib/puppet/application/master.rb
  16. +2 −2 lib/puppet/application/queue.rb
  17. +1 −0 lib/puppet/configurer/downloader.rb
  18. +8 −1 lib/puppet/configurer/plugin_handler.rb
  19. +1 −1 lib/puppet/daemon.rb
  20. +18 −2 lib/puppet/defaults.rb
  21. +0 −2 lib/puppet/external/nagios.rb
  22. +0 −2 lib/puppet/external/nagios/base.rb
  23. +97 −0 lib/puppet/indirector/facts/inventory_active_record.rb
  24. +2 −0 lib/puppet/indirector/facts/rest.rb
  25. +75 −0 lib/puppet/indirector/facts/yaml.rb
  26. +1 −0 lib/puppet/indirector/indirection.rb
  27. +1 −1 lib/puppet/module.rb
  28. +3 −4 lib/puppet/network/http/api/v1.rb
  29. +4 −1 lib/puppet/network/http/compression.rb
  30. +1 −1 lib/puppet/network/http/handler.rb
  31. +1 −1 lib/puppet/network/rest_authconfig.rb
  32. +29 −0 lib/puppet/node/facts.rb
  33. +5 −4 lib/puppet/parser/ast/collection.rb
  34. +1 −1 lib/puppet/parser/ast/leaf.rb
  35. +7 −14 lib/puppet/parser/functions/regsubst.rb
  36. +7 −7 lib/puppet/parser/functions/split.rb
  37. +2 −4 lib/puppet/parser/grammar.ra
  38. +4 −1 lib/puppet/parser/lexer.rb
  39. +2,062 −1,976 lib/puppet/parser/parser.rb
  40. +3 −3 lib/puppet/parser/parser_support.rb
  41. +1 −3 lib/puppet/provider/computer/computer.rb
  42. +12 −16 lib/puppet/provider/mount.rb
  43. +67 −8 lib/puppet/provider/mount/parsed.rb
  44. +3 −1 lib/puppet/provider/parsedfile.rb
  45. +6 −6 lib/puppet/provider/service/daemontools.rb
  46. +0 −2 lib/puppet/provider/service/gentoo.rb
  47. +11 −8 lib/puppet/provider/service/launchd.rb
  48. +4 −4 lib/puppet/provider/service/runit.rb
  49. +6 −1 lib/puppet/provider/user/useradd.rb
  50. +36 −0 lib/puppet/rails/database/004_add_inventory_service_tables.rb
  51. +17 −0 lib/puppet/rails/database/schema.rb
  52. +0 −2 lib/puppet/rails/fact_name.rb
  53. +0 −2 lib/puppet/rails/fact_value.rb
  54. +5 −0 lib/puppet/rails/inventory_fact.rb
  55. +25 −0 lib/puppet/rails/inventory_node.rb
  56. +1 −1 lib/puppet/reference/configuration.rb
  57. +1 −1 lib/puppet/reference/metaparameter.rb
  58. +4 −1 lib/puppet/reports/store.rb
  59. +39 −25 lib/puppet/resource.rb
  60. +5 −5 lib/puppet/type.rb
  61. +4 −4 lib/puppet/type/augeas.rb
  62. +5 −1 lib/puppet/type/computer.rb
  63. +3 −1 lib/puppet/type/exec.rb
  64. +3 −1 lib/puppet/type/file.rb
  65. +13 −15 lib/puppet/type/file/content.rb
  66. +11 −17 lib/puppet/type/file/ensure.rb
  67. +16 −0 lib/puppet/type/file/selcontext.rb
  68. +14 −1 lib/puppet/type/file/target.rb
  69. +0 −2 lib/puppet/type/k5login.rb
  70. +4 −1 lib/puppet/type/macauthorization.rb
  71. +4 −1 lib/puppet/type/mcx.rb
  72. +37 −21 lib/puppet/type/mount.rb
  73. +5 −1 lib/puppet/type/package.rb
  74. +20 −20 lib/puppet/type/schedule.rb
  75. +3 −1 lib/puppet/type/selmodule.rb
  76. +5 −1 lib/puppet/type/ssh_authorized_key.rb
  77. +14 −1 lib/puppet/type/user.rb
  78. +3 −1 lib/puppet/type/zfs.rb
  79. +3 −1 lib/puppet/type/zone.rb
  80. +7 −5 lib/puppet/type/zpool.rb
  81. +5 −0 lib/puppet/util.rb
  82. +1 −1 lib/puppet/util/command_line.rb
  83. +4 −5 lib/puppet/util/execution.rb
  84. +26 −0 lib/puppet/util/execution_stub.rb
  85. +21 −0 lib/puppet/util/monkey_patches.rb
  86. +39 −0 lib/puppet/util/rdoc/code_objects.rb
  87. +18 −0 lib/puppet/util/rdoc/generators/puppet_generator.rb
  88. +5 −3 lib/puppet/util/rdoc/parser.rb
  89. +1 −1 lib/puppet/util/settings.rb
  90. +7 −0 spec/integration/parser/parser_spec.rb
  91. +151 −0 spec/integration/provider/mount_spec.rb
  92. +32 −29 spec/integration/type/file_spec.rb
  93. +2 −0 spec/spec_helper.rb
  94. +3 −7 spec/unit/application/agent_spec.rb
  95. +17 −2 spec/unit/application/apply_spec.rb
  96. +54 −14 spec/unit/application/cert_spec.rb
  97. +1 −1 spec/unit/application/filebucket_spec.rb
  98. +1 −5 spec/unit/application/queue_spec.rb
  99. +22 −10 spec/unit/configurer/downloader_spec.rb
  100. +1 −5 spec/unit/daemon_spec.rb
  101. +163 −0 spec/unit/indirector/facts/inventory_active_record_spec.rb
  102. +216 −2 spec/unit/indirector/facts/yaml_spec.rb
  103. +3 −0 spec/unit/indirector/queue_spec.rb
  104. +2 −2 spec/unit/module_spec.rb
  105. +1 −1 spec/unit/network/handler/fileserver_spec.rb
  106. +28 −0 spec/unit/network/http/api/v1_spec.rb
  107. +1 −1 spec/unit/network/http/compression_spec.rb
  108. +7 −4 spec/unit/network/http/handler_spec.rb
  109. +24 −0 spec/unit/node/facts_spec.rb
  110. +16 −12 spec/unit/parser/ast/collection_spec.rb
  111. +16 −0 spec/unit/parser/lexer_spec.rb
  112. +35 −2 spec/unit/parser/parser_spec.rb
  113. +199 −114 spec/unit/provider/mount/parsed_spec.rb
  114. +54 −53 spec/unit/provider/mount_spec.rb
  115. +1 −0 spec/unit/provider/ssh_authorized_key/parsed_spec.rb
  116. +1 −0 spec/unit/provider/user/user_role_add_spec.rb
  117. +43 −3 spec/unit/provider/user/useradd_spec.rb
  118. +1 −1 spec/unit/reports/store_spec.rb
  119. +39 −13 spec/unit/resource_spec.rb
  120. +38 −137 spec/unit/type/file/content_spec.rb
  121. +5 −0 spec/unit/type/file/selinux_spec.rb
  122. +167 −122 spec/unit/type/mount_spec.rb
  123. +4 −0 spec/unit/type/user_spec.rb
  124. +12 −1 spec/unit/type_spec.rb
  125. +49 −0 spec/unit/util/execution_spec.rb
  126. +35 −0 spec/unit/util/execution_stub_spec.rb
  127. +15 −3 spec/unit/util/rdoc/parser_spec.rb
  128. +11 −2 spec/unit/util/settings_spec.rb
  129. +1 −1 tasks/rake/git_workflow.rake
  130. +0 −2 test/Rakefile
  131. +7 −0 test/data/providers/mount/parsed/aix.mount
  132. +6 −0 test/data/providers/mount/parsed/darwin.mount
  133. +17 −0 test/data/providers/mount/parsed/hpux.mount
  134. +5 −0 test/data/providers/mount/parsed/linux.mount
  135. +6 −0 test/data/providers/mount/parsed/solaris.mount
  136. +1 −0 test/data/types/mount/linux.fstab
  137. +1 −0 test/data/types/mount/solaris.fstab
View
2 README.queueing
@@ -8,7 +8,7 @@ Queue Daemon).
Currently this is only supported for "Storeconfigs" which is
documented at:
-http://reductivelabs.com/trac/puppet/wiki/UsingStoredConfiguration
+http://projects.puppetlabs.com/projects/1/wiki/Using_Stored_Configuration
In the future this feature can be extended to any new puppet
data which involves storage in a database.
View
2 Rakefile
@@ -44,7 +44,7 @@ task :puppetpackages => [:create_gem, :package]
RSpec::Core::RakeTask.new do |t|
t.pattern ='spec/{unit,integration}/**/*.rb'
- t.fail_on_error = false
+ t.fail_on_error = true
end
desc "Run the unit tests"
View
2 conf/solaris/smf/svc-puppetd
@@ -62,5 +62,3 @@ status)
fi
esac
exit 0
-
-# $Id$
View
2 conf/solaris/smf/svc-puppetmasterd
@@ -58,5 +58,3 @@ status)
fi
esac
exit 0
-
-# $Id$
View
2 examples/etc/init.d/sleeper
@@ -1,7 +1,5 @@
#!/bin/bash
-# $Id$
-
script=$0
path=`echo $script | sed 's/etc..*/bin/'`
View
4 examples/modules/sample-module/README.txt
@@ -12,6 +12,6 @@ templates/sample.erb
Note the consistent naming of files for Puppet::Util::Autoload
Reference Documents:
-http://reductivelabs.com/trac/puppet/wiki/ModuleOrganisation
+http://docs.puppetlabs.com/guides/modules.html
http://docs.puppetlabs.com/guides/custom_functions.html
-http://reductivelabs.com/trac/puppet/wiki/FunctionReference
+http://docs.puppetlabs.com/references/latest/function.html
View
2 ext/puppetstoredconfigclean.rb
@@ -3,7 +3,7 @@
# Script to clean up stored configs for (a) given host(s)
#
# Credits:
-# Script was taken from http://reductivelabs.com/trac/puppet/attachment/wiki/UsingStoredConfiguration/kill_node_in_storedconfigs_db.rb
+# Script was taken from http://reductivelabs.com/trac/puppet/attachment/wiki/UsingStoredConfiguration/kill_node_in_storedconfigs_db.rb (link no longer valid),
# which haven been initially posted by James Turnbull
# duritong adapted and improved the script a bit.
View
45 install.rb
@@ -300,34 +300,29 @@ def prepare_installation
mandir = Config::CONFIG['mandir']
end
- # To be deprecated once people move over to using --destdir option
- if (destdir = ENV['DESTDIR'])
- configdir = "#{destdir}#{configdir}"
- bindir = "#{destdir}#{bindir}"
- sbindir = "#{destdir}#{sbindir}"
- mandir = "#{destdir}#{mandir}"
- sitelibdir = "#{destdir}#{sitelibdir}"
-
- FileUtils.makedirs(configdir) if InstallOptions.configs
- FileUtils.makedirs(bindir)
- FileUtils.makedirs(sbindir)
- FileUtils.makedirs(mandir)
- FileUtils.makedirs(sitelibdir)
# This is the new way forward
- elsif (destdir = InstallOptions.destdir)
- configdir = "#{destdir}#{configdir}"
- bindir = "#{destdir}#{bindir}"
- sbindir = "#{destdir}#{sbindir}"
- mandir = "#{destdir}#{mandir}"
- sitelibdir = "#{destdir}#{sitelibdir}"
-
- FileUtils.makedirs(configdir) if InstallOptions.configs
- FileUtils.makedirs(bindir)
- FileUtils.makedirs(sbindir)
- FileUtils.makedirs(mandir)
- FileUtils.makedirs(sitelibdir)
+ if not InstallOptions.destdir.nil?
+ destdir = InstallOptions.destdir
+ # To be deprecated once people move over to using --destdir option
+ elsif ENV['DESTDIR'] != nil?
+ destdir = ENV['DESTDIR']
+ warn "DESTDIR is deprecated. Use --destdir instead."
+ else
+ destdir = ''
end
+ configdir = "#{destdir}#{configdir}"
+ bindir = "#{destdir}#{bindir}"
+ sbindir = "#{destdir}#{sbindir}"
+ mandir = "#{destdir}#{mandir}"
+ sitelibdir = "#{destdir}#{sitelibdir}"
+
+ FileUtils.makedirs(configdir) if InstallOptions.configs
+ FileUtils.makedirs(bindir)
+ FileUtils.makedirs(sbindir)
+ FileUtils.makedirs(mandir)
+ FileUtils.makedirs(sitelibdir)
+
tmpdirs << bindir
InstallOptions.tmp_dirs = tmpdirs.compact
View
4 lib/puppet/application/agent.rb
@@ -9,7 +9,7 @@ class Puppet::Application::Agent < Puppet::Application
def preinit
# Do an initial trap, so that cancels don't get a stack trace.
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Cancelling startup"
exit(0)
end
@@ -119,7 +119,7 @@ def onetime
if not report
exit(1)
- elsif not Puppet[:noop] and options[:detailed_exitcodes] then
+ elsif options[:detailed_exitcodes] then
exit(report.exit_status)
else
exit(0)
View
4 lib/puppet/application/apply.rb
@@ -125,7 +125,7 @@ def main
configurer = Puppet::Configurer.new
report = configurer.run(:skip_plugin_download => true, :catalog => catalog)
- exit( Puppet[:noop] ? 0 : options[:detailed_exitcodes] ? report.exit_status : 0 )
+ exit( options[:detailed_exitcodes] ? report.exit_status : 0 )
rescue => detail
puts detail.backtrace if Puppet[:trace]
$stderr.puts detail.message
@@ -143,7 +143,7 @@ def setup
client = nil
server = nil
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Exiting"
exit(1)
end
View
38 lib/puppet/application/cert.rb
@@ -5,17 +5,19 @@ class Puppet::Application::Cert < Puppet::Application
should_parse_config
run_mode :master
- attr_accessor :cert_mode, :all, :ca, :digest, :signed
+ attr_accessor :all, :ca, :digest, :signed
- def find_mode(opt)
- require 'puppet/ssl/certificate_authority'
- modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS
- tmp = opt.sub("--", '').to_sym
- @cert_mode = modes.include?(tmp) ? tmp : nil
+ def subcommand
+ @subcommand
+ end
+ def subcommand=(name)
+ # Handle the nasty, legacy mapping of "clean" to "destroy".
+ sub = name.to_sym
+ @subcommand = (sub == :clean ? :destroy : sub)
end
option("--clean", "-c") do
- @cert_mode = :destroy
+ self.subcommand = "destroy"
end
option("--all", "-a") do
@@ -37,7 +39,7 @@ def find_mode(opt)
require 'puppet/ssl/certificate_authority/interface'
Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.reject {|m| m == :destroy }.each do |method|
option("--#{method}", "-#{method.to_s[0,1]}") do
- find_mode("--#{method}")
+ self.subcommand = method
end
end
@@ -54,8 +56,8 @@ def main
hosts = command_line.args.collect { |h| h.downcase }
end
begin
- @ca.apply(:revoke, :to => hosts) if @cert_mode == :destroy
- @ca.apply(@cert_mode, :to => hosts, :digest => @digest)
+ @ca.apply(:revoke, :to => hosts) if subcommand == :destroy
+ @ca.apply(subcommand, :to => hosts, :digest => @digest)
rescue => detail
puts detail.backtrace if Puppet[:trace]
puts detail.to_s
@@ -64,11 +66,12 @@ def main
end
def setup
+ require 'puppet/ssl/certificate_authority'
exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
Puppet::Util::Log.newdestination :console
- if [:generate, :destroy].include? @cert_mode
+ if [:generate, :destroy].include? subcommand
Puppet::SSL::Host.ca_location = :local
else
Puppet::SSL::Host.ca_location = :only
@@ -82,4 +85,17 @@ def setup
exit(23)
end
end
+
+ def parse_options
+ # handle the bareword subcommand pattern.
+ result = super
+ unless self.subcommand then
+ if sub = self.command_line.args.shift then
+ self.subcommand = sub
+ else
+ help
+ end
+ end
+ result
+ end
end
View
2 lib/puppet/application/filebucket.rb
@@ -52,7 +52,7 @@ def setup
@client = nil
@server = nil
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Cancelling"
exit(1)
end
View
2 lib/puppet/application/inspect.rb
@@ -82,7 +82,7 @@ def setup
Puppet::Util::Log.newdestination(@report)
Puppet::Util::Log.newdestination(:console) unless options[:logset]
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Exiting"
exit(1)
end
View
4 lib/puppet/application/kick.rb
@@ -151,7 +151,7 @@ def initialize(*args)
def preinit
[:INT, :TERM].each do |signal|
- trap(signal) do
+ Signal.trap(signal) do
$stderr.puts "Cancelling"
exit(1)
end
@@ -195,7 +195,7 @@ def setup
# If we get a signal, then kill all of our children and get out.
[:INT, :TERM].each do |signal|
- trap(signal) do
+ Signal.trap(signal) do
Puppet.notice "Caught #{signal}; shutting down"
@children.each do |pid, host|
Process.kill("INT", pid)
View
2 lib/puppet/application/master.rb
@@ -26,7 +26,7 @@ class Puppet::Application::Master < Puppet::Application
end
def preinit
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Cancelling startup"
exit(0)
end
View
4 lib/puppet/application/queue.rb
@@ -15,13 +15,13 @@ def preinit
# Do an initial trap, so that cancels don't get a stack trace.
# This exits with exit code 1
- trap(:INT) do
+ Signal.trap(:INT) do
$stderr.puts "Caught SIGINT; shutting down"
exit(1)
end
# This is a normal shutdown, so code 0
- trap(:TERM) do
+ Signal.trap(:TERM) do
$stderr.puts "Caught SIGTERM; shutting down"
exit(0)
end
View
1 lib/puppet/configurer/downloader.rb
@@ -50,6 +50,7 @@ def initialize(name, path, source, ignore = nil)
def catalog
catalog = Puppet::Resource::Catalog.new
+ catalog.host_config = false
catalog.add_resource(file)
catalog
end
View
9 lib/puppet/configurer/plugin_handler.rb
@@ -9,7 +9,14 @@ def download_plugins?
# Retrieve facts from the central server.
def download_plugins
return nil unless download_plugins?
- Puppet::Configurer::Downloader.new("plugin", Puppet[:plugindest], Puppet[:pluginsource], Puppet[:pluginsignore]).evaluate.each { |file| load_plugin(file) }
+ plugin_downloader = Puppet::Configurer::Downloader.new(
+ "plugin",
+ Puppet[:plugindest],
+ Puppet[:pluginsource],
+ Puppet[:pluginsignore]
+ )
+
+ plugin_downloader.evaluate.each { |file| load_plugin(file) }
end
def load_plugin(file)
View
2 lib/puppet/daemon.rb
@@ -95,7 +95,7 @@ def set_signal_traps
# extended signals not supported under windows
signals.update({:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs }) unless Puppet.features.microsoft_windows?
signals.each do |signal, method|
- trap(signal) do
+ Signal.trap(signal) do
Puppet.notice "Caught #{signal}; calling #{method}"
send(method)
end
View
20 lib/puppet/defaults.rb
@@ -119,7 +119,17 @@ module Puppet
:node_terminus => ["plain", "Where to find information about nodes."],
:catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
- :facts_terminus => [Puppet.application_name.to_s == "master" ? 'yaml' : 'facter', "The node facts terminus."],
+ :facts_terminus => {
+ :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter',
+ :desc => "The node facts terminus.",
+ :hook => proc do |value|
+ require 'puppet/node/facts'
+ if value.to_s == "rest"
+ Puppet::Node::Facts.cache_class = :yaml
+ end
+ end
+ },
+ :inventory_terminus => [ "$facts_terminus", "Should usually be the same as the facts terminus" ],
:httplog => { :default => "$logdir/http.log",
:owner => "root",
:mode => 0640,
@@ -582,11 +592,17 @@ module Puppet
end
},
:report_server => ["$server",
- "The server to which to send transaction reports."
+ "The server to send transaction reports to."
],
:report_port => ["$masterport",
"The port to communicate with the report_server."
],
+ :inventory_server => ["$server",
+ "The server to send facts to."
+ ],
+ :inventory_port => ["$masterport",
+ "The port to communicate with the inventory_server."
+ ],
:report => [false,
"Whether to send reports after every transaction."
],
View
2 lib/puppet/external/nagios.rb
@@ -3,8 +3,6 @@
#--------------------
# A script to retrieve hosts from ldap and create an importable
# cfservd file from them
-#
-# $Id: nagios.rb,v 1.3 2004/06/09 20:32:46 luke Exp $
require 'digest/md5'
#require 'ldap'
View
2 lib/puppet/external/nagios/base.rb
@@ -470,5 +470,3 @@ def type
end
end
-
-# $Id$
View
97 lib/puppet/indirector/facts/inventory_active_record.rb
@@ -0,0 +1,97 @@
+require 'puppet/rails'
+require 'puppet/rails/inventory_node'
+require 'puppet/rails/inventory_fact'
+require 'puppet/indirector/active_record'
+
+class Puppet::Node::Facts::InventoryActiveRecord < Puppet::Indirector::ActiveRecord
+ def find(request)
+ node = Puppet::Rails::InventoryNode.find_by_name(request.key)
+ return nil unless node
+ facts = Puppet::Node::Facts.new(node.name, node.facts_to_hash)
+ facts.timestamp = node.timestamp
+ facts
+ end
+
+ def save(request)
+ facts = request.instance
+ node = Puppet::Rails::InventoryNode.find_by_name(request.key) || Puppet::Rails::InventoryNode.create(:name => request.key, :timestamp => facts.timestamp)
+ node.timestamp = facts.timestamp
+
+ ActiveRecord::Base.transaction do
+ Puppet::Rails::InventoryFact.delete_all(:node_id => node.id)
+ # We don't want to save internal values as facts, because those are
+ # metadata that belong on the node
+ facts.values.each do |name,value|
+ next if name.to_s =~ /^_/
+ node.facts.build(:name => name, :value => value)
+ end
+ node.save
+ end
+ end
+
+ def search(request)
+ return [] unless request.options
+ matching_nodes = []
+ fact_names = []
+ fact_filters = Hash.new {|h,k| h[k] = []}
+ meta_filters = Hash.new {|h,k| h[k] = []}
+ request.options.each do |key,value|
+ type, name, operator = key.to_s.split(".")
+ operator ||= "eq"
+ if type == "facts"
+ fact_filters[operator] << [name,value]
+ elsif type == "meta" and name == "timestamp"
+ meta_filters[operator] << [name,value]
+ end
+ end
+
+ matching_nodes = nodes_matching_fact_filters(fact_filters) + nodes_matching_meta_filters(meta_filters)
+
+ # to_a because [].inject == nil
+ matching_nodes.inject {|nodes,this_set| nodes & this_set}.to_a.sort
+ end
+
+ private
+
+ def nodes_matching_fact_filters(fact_filters)
+ node_sets = []
+ fact_filters['eq'].each do |name,value|
+ node_sets << Puppet::Rails::InventoryNode.has_fact_with_value(name,value).map {|node| node.name}
+ end
+ fact_filters['ne'].each do |name,value|
+ node_sets << Puppet::Rails::InventoryNode.has_fact_without_value(name,value).map {|node| node.name}
+ end
+ {
+ 'gt' => '>',
+ 'lt' => '<',
+ 'ge' => '>=',
+ 'le' => '<='
+ }.each do |operator_name,operator|
+ fact_filters[operator_name].each do |name,value|
+ facts = Puppet::Rails::InventoryFact.find_by_sql(["SELECT inventory_facts.value, inventory_nodes.name AS node_name
+ FROM inventory_facts INNER JOIN inventory_nodes
+ ON inventory_facts.node_id = inventory_nodes.id
+ WHERE inventory_facts.name = ?", name])
+ node_sets << facts.select {|fact| fact.value.to_f.send(operator, value.to_f)}.map {|fact| fact.node_name}
+ end
+ end
+ node_sets
+ end
+
+ def nodes_matching_meta_filters(meta_filters)
+ node_sets = []
+ {
+ 'eq' => '=',
+ 'ne' => '!=',
+ 'gt' => '>',
+ 'lt' => '<',
+ 'ge' => '>=',
+ 'le' => '<='
+ }.each do |operator_name,operator|
+ meta_filters[operator_name].each do |name,value|
+ node_sets << Puppet::Rails::InventoryNode.find(:all, :select => "name", :conditions => ["timestamp #{operator} ?", value]).map {|node| node.name}
+ end
+ end
+ node_sets
+ end
+end
View
2 lib/puppet/indirector/facts/rest.rb
@@ -3,4 +3,6 @@
class Puppet::Node::Facts::Rest < Puppet::Indirector::REST
desc "Find and save facts about nodes over HTTP via REST."
+ use_server_setting(:inventory_server)
+ use_port_setting(:inventory_port)
end
View
75 lib/puppet/indirector/facts/yaml.rb
@@ -4,4 +4,79 @@
class Puppet::Node::Facts::Yaml < Puppet::Indirector::Yaml
desc "Store client facts as flat files, serialized using YAML, or
return deserialized facts from disk."
+
+ def search(request)
+ node_names = []
+ Dir.glob(yaml_dir_path).each do |file|
+ facts = YAML.load_file(file)
+ node_names << facts.name if node_matches?(facts, request.options)
+ end
+ node_names
+ end
+
+ private
+
+ # Return the path to a given node's file.
+ def yaml_dir_path
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, 'facts', '*.yaml')
+ end
+
+ def node_matches?(facts, options)
+ options.each do |key, value|
+ type, name, operator = key.to_s.split(".")
+ operator ||= 'eq'
+
+ return false unless node_matches_option?(type, name, operator, value, facts)
+ end
+ return true
+ end
+
+ def node_matches_option?(type, name, operator, value, facts)
+ case type
+ when "meta"
+ case name
+ when "timestamp"
+ compare_timestamp(operator, facts.timestamp, Time.parse(value))
+ end
+ when "facts"
+ compare_facts(operator, facts.values[name], value)
+ end
+ end
+
+ def compare_facts(operator, value1, value2)
+ return false unless value1
+
+ case operator
+ when "eq"
+ value1.to_s == value2.to_s
+ when "le"
+ value1.to_f <= value2.to_f
+ when "ge"
+ value1.to_f >= value2.to_f
+ when "lt"
+ value1.to_f < value2.to_f
+ when "gt"
+ value1.to_f > value2.to_f
+ when "ne"
+ value1.to_s != value2.to_s
+ end
+ end
+
+ def compare_timestamp(operator, value1, value2)
+ case operator
+ when "eq"
+ value1 == value2
+ when "le"
+ value1 <= value2
+ when "ge"
+ value1 >= value2
+ when "lt"
+ value1 < value2
+ when "gt"
+ value1 > value2
+ when "ne"
+ value1 != value2
+ end
+ end
end
View
1 lib/puppet/indirector/indirection.rb
@@ -248,6 +248,7 @@ def search(key, *args)
if result = terminus.search(request)
raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
result.each do |instance|
+ next unless instance.respond_to? :expiration
instance.expiration ||= self.expiration
end
return result
View
2 lib/puppet/module.rb
@@ -191,7 +191,7 @@ def subpath(type)
def backward_compatible_plugins_dir
if dir = File.join(path, "plugins") and FileTest.exist?(dir)
- warning "using the deprecated 'plugins' directory for ruby extensions; please move to 'lib'"
+ Puppet.warning "using the deprecated 'plugins' directory for ruby extensions; please move to 'lib'"
return dir
else
return File.join(path, "lib")
View
7 lib/puppet/network/http/api/v1.rb
@@ -60,13 +60,12 @@ def plurality(indirection)
# fix to not need this, and our goal is to move away from the complication
# that leads to the fix being too long.
return :singular if indirection == "facts"
-
- # "status" really is singular
return :singular if indirection == "status"
+ return :plural if indirection == "inventory"
- result = (indirection =~ /s$/) ? :plural : :singular
+ result = (indirection =~ /s$|_search$/) ? :plural : :singular
- indirection.sub!(/s$/, '') if result
+ indirection.sub!(/s$|_search$|es$/, '')
result
end
View
5 lib/puppet/network/http/compression.rb
@@ -75,7 +75,10 @@ def uncompress(chunk)
# in this case, we try with a verbatim (no header)
# deflater.
@uncompressor = Zlib::Inflate.new
- retry if @first
+ if @first then
+ @first = false
+ retry
+ end
raise
end
View
2 lib/puppet/network/http/handler.rb
@@ -131,7 +131,7 @@ def do_head(indirection_request, request, response)
def do_search(indirection_request, request, response)
result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
- if result.nil? or (result.is_a?(Array) and result.empty?)
+ if result.nil?
return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.key}'", 404)
end
View
2 lib/puppet/network/rest_authconfig.rb
@@ -61,7 +61,7 @@ def parse
def insert_default_acl
DEFAULT_ACL.each do |acl|
unless rights[acl[:acl]]
- Puppet.info "Inserting default '#{acl[:acl]}'(#{acl[:authenticated] ? "auth" : "non-auth"}) acl because #{( !exists? ? "#{Puppet[:rest_authconfig]} doesn't exist" : "none where found in '#{@file}'")}"
+ Puppet.info "Inserting default '#{acl[:acl]}'(#{acl[:authenticated] ? "auth" : "non-auth"}) ACL because #{( !exists? ? "#{Puppet[:rest_authconfig]} doesn't exist" : "none were found in '#{@file}'")}"
mk_acl(acl)
end
end
View
29 lib/puppet/node/facts.rb
@@ -1,12 +1,17 @@
+require 'time'
+
require 'puppet/node'
require 'puppet/indirector'
+require 'puppet/util/pson'
+
# Manage a given node's facts. This either accepts facts and stores them, or
# returns facts for a given node.
class Puppet::Node::Facts
# Set up indirection, so that nodes can be looked for in
# the node sources.
extend Puppet::Indirector
+ extend Puppet::Util::Pson
# We want to expire any cached nodes if the facts are saved.
module NodeExpirer
@@ -54,6 +59,30 @@ def ==(other)
strip_internal == other.send(:strip_internal)
end
+ def timestamp=(time)
+ self.values[:_timestamp] = time
+ end
+
+ def timestamp
+ self.values[:_timestamp]
+ end
+
+ def self.from_pson(data)
+ result = new(data['name'], data['values'])
+ result.timestamp = Time.parse(data['timestamp'])
+ result.expiration = Time.parse(data['expiration'])
+ result
+ end
+
+ def to_pson(*args)
+ {
+ 'expiration' => expiration,
+ 'name' => name,
+ 'timestamp' => timestamp,
+ 'values' => strip_internal,
+ }.to_pson(*args)
+ end
+
private
# Add internal data to the facts for storage.
View
9 lib/puppet/parser/ast/collection.rb
@@ -16,6 +16,7 @@ def evaluate(scope)
str, code = query && query.safeevaluate(scope)
resource_type = scope.find_resource_type(@type)
+ fail "Resource type #{@type} doesn't exist" unless resource_type
newcoll = Puppet::Parser::Collector.new(scope, resource_type.name, str, code, self.form)
scope.compiler.add_collection(newcoll)
@@ -26,10 +27,10 @@ def evaluate(scope)
params = @override.collect { |param| param.safeevaluate(scope) }
newcoll.add_override(
:parameters => params,
- :file => @file,
- :line => @line,
- :source => scope.source,
- :scope => scope
+ :file => @file,
+ :line => @line,
+ :source => scope.source,
+ :scope => scope
)
end
View
2 lib/puppet/parser/ast/leaf.rb
@@ -67,7 +67,7 @@ def evaluate(scope)
end
def to_s
- "concat(#{@value.join(',')})"
+ "#{@value.map { |s| s.to_s.gsub(/^"(.*)"$/, '\1') }.join}"
end
end
View
21 lib/puppet/parser/functions/regsubst.rb
@@ -4,25 +4,18 @@ module Puppet::Parser::Functions
:regsubst, :type => :rvalue,
:doc => "
- Perform regexp replacement on a string or array of strings.
+Perform regexp replacement on a string or array of strings.
* *Parameters* (in order):
-
- _target_ The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
-
- _regexp_ The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
-
- _replacement_ Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
-
- _flags_ Optional. String of single letter flags for how the regexp is interpreted:
-
+ * _target_ The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
+ * _regexp_ The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
+ * _replacement_ Replacement string. Can contain backreferences to what was matched using \\0 (whole match), \\1 (first set of parentheses), and so on.
+ * _flags_ Optional. String of single letter flags for how the regexp is interpreted:
- *E* Extended regexps
- *I* Ignore case in regexps
- *M* Multiline regexps
- *G* Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
-
- _lang_ Optional. How to handle multibyte characters. A single-character string with the following values:
-
+ * _encoding_ Optional. How to handle multibyte characters. A single-character string with the following values:
- *N* None
- *E* EUC
- *S* SJIS
@@ -32,7 +25,7 @@ module Puppet::Parser::Functions
Get the third octet from the node's IP address:
- $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
+ $i3 = regsubst($ipaddress,'^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$','\\3')
Put angle brackets around each octet in the node's IP address:
View
14 lib/puppet/parser/functions/split.rb
@@ -6,21 +6,21 @@ module Puppet::Parser::Functions
:doc => "\
Split a string variable into an array using the specified split regexp.
- Usage:
+*Example:*
$string = 'v1.v2:v3.v4'
$array_var1 = split($string, ':')
$array_var2 = split($string, '[.]')
$array_var3 = split($string, '[.:]')
-$array_var1 now holds the result ['v1.v2', 'v3.v4'],
-while $array_var2 holds ['v1', 'v2:v3', 'v4'], and
-$array_var3 holds ['v1', 'v2', 'v3', 'v4'].
+`$array_var1` now holds the result `['v1.v2', 'v3.v4']`,
+while `$array_var2` holds `['v1', 'v2:v3', 'v4']`, and
+`$array_var3` holds `['v1', 'v2', 'v3', 'v4']`.
-Note that in the second example, we split on a string that contains
-a regexp meta-character (.), and that needs protection. A simple
+Note that in the second example, we split on a literal string that contains
+a regexp meta-character (.), which must be escaped. A simple
way to do that for a single character is to enclose it in square
-brackets.") do |args|
+brackets; a backslash will also escape a single character.") do |args|
raise Puppet::ParseError, ("split(): wrong number of arguments (#{args.length}; must be 2)") if args.length != 2
View
6 lib/puppet/parser/grammar.ra
@@ -642,6 +642,7 @@ selectlhand: name
| funcrvalue
| boolean
| undef
+ | hasharrayaccess
| DEFAULT {
result = ast AST::Default, :value => val[0][:value], :line => val[0][:line]
}
@@ -844,7 +845,7 @@ hasharrayaccess: VARIABLE LBRACK rvalue RBRACK {
}
hasharrayaccesses: hasharrayaccess
- | hasharrayaccess LBRACK rvalue RBRACK {
+ | hasharrayaccesses LBRACK rvalue RBRACK {
result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2]
}
@@ -870,6 +871,3 @@ require 'puppet/parser/parser_support'
# Local Variables:
# mode: ruby
# End:
-
-# $Id$
-
View
5 lib/puppet/parser/lexer.rb
@@ -476,9 +476,12 @@ def scan
@expected.pop
end
- if final_token.name == :LBRACE
+ if final_token.name == :LBRACE or final_token.name == :LPAREN
commentpush
end
+ if final_token.name == :RPAREN
+ commentpop
+ end
yield [final_token.name, token_value]
View
4,038 lib/puppet/parser/parser.rb
2,062 additions, 1,976 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
6 lib/puppet/parser/parser_support.rb
@@ -135,19 +135,19 @@ def namesplit(fullname)
# Create a new class, or merge with an existing class.
def newclass(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true).merge(options))
+ known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true, options[:line]).merge(options))
end
# Create a new definition.
def newdefine(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true).merge(options))
+ known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true, options[:line]).merge(options))
end
# Create a new node. Nodes are special, because they're stored in a global
# table, not according to namespaces.
def newnode(names, options = {})
names = [names] unless names.instance_of?(Array)
- context = ast_context(true)
+ context = ast_context(true, options[:line])
names.collect do |name|
known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options)))
end
View
4 lib/puppet/provider/computer/computer.rb
@@ -10,9 +10,7 @@
domain, not in remote directories.
If you wish to manage /etc/hosts on Mac OS X, then simply use the host
- type as per other platforms.
-
- "
+ type as per other platforms."
confine :operatingsystem => :darwin
defaultfor :operatingsystem => :darwin
View
28 lib/puppet/provider/mount.rb
@@ -14,8 +14,11 @@ def mount
args << "-o" << self.options if self.options and self.options != :absent
args << resource[:name]
- flush if respond_to?(:flush)
mountcmd(*args)
+ case get(:ensure)
+ when :absent; set(:ensure => :ghost)
+ when :unmounted; set(:ensure => :mounted)
+ end
end
def remount
@@ -30,24 +33,17 @@ def remount
# This only works when the mount point is synced to the fstab.
def unmount
- umount resource[:name]
+ umount(resource[:name])
+
+ # Update property hash for future queries (e.g. refresh is called)
+ case get(:ensure)
+ when :mounted; set(:ensure => :unmounted)
+ when :ghost; set(:ensure => :absent)
+ end
end
# Is the mount currently mounted?
def mounted?
- platform = Facter.value("operatingsystem")
- name = resource[:name]
- mounts = mountcmd.split("\n").find do |line|
- case platform
- when "Darwin"
- line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris", "HP-UX"
- line =~ /^#{name} on /
- when "AIX"
- line.split(/\s+/)[2] == name
- else
- line =~ / on #{name} /
- end
- end
+ [:mounted, :ghost].include?(get(:ensure))
end
end
View
75 lib/puppet/provider/mount/parsed.rb
@@ -8,21 +8,17 @@
fstab = "/etc/fstab"
end
-
- Puppet::Type.type(:mount).provide(
- :parsed,
+Puppet::Type.type(:mount).provide(
+ :parsed,
:parent => Puppet::Provider::ParsedFile,
:default_target => fstab,
-
:filetype => :flat
) do
include Puppet::Provider::Mount
- #confine :exists => fstab
commands :mountcmd => "mount", :umount => "umount"
- @platform = Facter["operatingsystem"].value
- case @platform
+ case Facter["operatingsystem"]
when "Solaris"
@fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
else
@@ -43,5 +39,68 @@
record_line self.name, :fields => @fields, :separator => /\s+/, :joiner => "\t", :optional => optional_fields
-end
+ # Every entry in fstab is :unmounted until we can prove different
+ def self.prefetch_hook(target_records)
+ target_records.collect do |record|
+ record[:ensure] = :unmounted if record[:record_type] == :parsed
+ record
+ end
+ end
+
+ def self.prefetch(resources = nil)
+ # Get providers for all resources the user defined and that match
+ # a record in /etc/fstab.
+ super
+ # We need to do two things now:
+ # - Update ensure from :unmounted to :mounted if the resource is mounted
+ # - Check for mounted devices that are not in fstab and
+ # set ensure to :ghost (if the user wants to add an entry
+ # to fstab we need to know if the device was mounted before)
+ mountinstances.each do |hash|
+ if mount = resources[hash[:name]]
+ case mount.provider.get(:ensure)
+ when :absent # Mount not in fstab
+ mount.provider.set(:ensure => :ghost)
+ when :unmounted # Mount in fstab
+ mount.provider.set(:ensure => :mounted)
+ end
+ end
+ end
+ end
+ def self.mountinstances
+ # XXX: Will not work for mount points that have spaces in path (does fstab support this anyways?)
+ regex = case Facter.value(:operatingsystem)
+ when "Darwin"
+ / on (?:\/private\/var\/automount)?(\S*)/
+ when "Solaris", "HP-UX"
+ /^(\S*) on /
+ when "AIX"
+ /^(?:\S*\s+\S+\s+)(\S+)/
+ else
+ / on (\S*)/
+ end
+ instances = []
+ mount_output = mountcmd.split("\n")
+ if mount_output.length >= 2 and mount_output[1] =~ /^[- \t]*$/
+ # On some OSes (e.g. AIX) mount output begins with a header line
+ # followed by a line consisting of dashes and whitespace.
+ # Discard these two lines.
+ mount_output[0..1] = []
+ end
+ mount_output.each do |line|
+ if match = regex.match(line) and name = match.captures.first
+ instances << {:name => name, :mounted => :yes} # Only :name is important here
+ else
+ raise Puppet::Error, "Could not understand line #{line} from mount output"
+ end
+ end
+ instances
+ end
+
+ def flush
+ needs_mount = @property_hash.delete(:needs_mount)
+ super
+ mount if needs_mount
+ end
+end
View
4 lib/puppet/provider/parsedfile.rb
@@ -334,7 +334,9 @@ def flush
@property_hash[:target] = @resource.should(:target) || self.class.default_target
self.class.modified(@property_hash[:target])
end
- @property_hash[:name] ||= @resource.name
+ @resource.class.key_attributes.each do |attr|
+ @property_hash[attr] ||= @resource[attr]
+ end
self.class.flush(@property_hash)
View
12 lib/puppet/provider/service/daemontools.rb
@@ -19,10 +19,10 @@
or this can be overriden in the service resource parameters::
- service {
- \"myservice\":
- provider => \"daemontools\", path => \"/path/to/daemons\";
- }
+ service { \"myservice\":
+ provider => \"daemontools\",
+ path => \"/path/to/daemons\",
+ }
This provider supports out of the box:
@@ -31,10 +31,10 @@
* restart
* status
- If a service has ensure => \"running\", it will link /path/to/daemon to
+ If a service has `ensure => \"running\"`, it will link /path/to/daemon to
/path/to/service, which will automatically enable the service.
- If a service has ensure => \"stopped\", it will only down the service, not
+ If a service has `ensure => \"stopped\"`, it will only down the service, not
remove the /path/to/service link.
"
View
2 lib/puppet/provider/service/gentoo.rb
@@ -48,5 +48,3 @@ def enable
raise Puppet::Error, "Could not enable #{self.name}: #{output}"
end
end
-
-# $Id $
View
19 lib/puppet/provider/service/launchd.rb
@@ -3,33 +3,36 @@
Puppet::Type.type(:service).provide :launchd, :parent => :base do
desc "launchd service management framework.
- This provider manages launchd jobs, the default service framework for
- Mac OS X, that has also been open sourced by Apple for possible use on
- other platforms.
+ This provider manages jobs with launchd, which is the default service framework for
+ Mac OS X and is potentially available for use on other platforms.
See:
+
* http://developer.apple.com/macosx/launchd.html
* http://launchd.macosforge.org/
This provider reads plists out of the following directories:
+
* /System/Library/LaunchDaemons
* /System/Library/LaunchAgents
* /Library/LaunchDaemons
* /Library/LaunchAgents
- and builds up a list of services based upon each plists \"Label\" entry.
+ ...and builds up a list of services based upon each plist's \"Label\" entry.
This provider supports:
+
* ensure => running/stopped,
* enable => true/false
* status
* restart
Here is how the Puppet states correspond to launchd states:
- * stopped => job unloaded
- * started => job loaded
- * enabled => 'Disable' removed from job plist file
- * disabled => 'Disable' added to job plist file
+
+ * stopped --- job unloaded
+ * started --- job loaded
+ * enabled --- 'Disable' removed from job plist file
+ * disabled --- 'Disable' added to job plist file
Note that this allows you to do something launchctl can't do, which is to
be in a state of \"stopped/enabled\ or \"running/disabled\".
View
8 lib/puppet/provider/service/runit.rb
@@ -18,10 +18,10 @@
or this can be overriden in the service resource parameters::
- service {
- \"myservice\":
- provider => \"runit\", path => \"/path/to/daemons\";
- }
+ service { \"myservice\":
+ provider => \"runit\",
+ path => \"/path/to/daemons\",
+ }
This provider supports out of the box:
View
7 lib/puppet/provider/user/useradd.rb
@@ -19,7 +19,7 @@
value !~ /\s/
end
- has_features :manages_homedir, :allows_duplicates, :manages_expiry
+ has_features :manages_homedir, :allows_duplicates, :manages_expiry, :system_users
has_features :manages_passwords, :manages_password_age if Puppet.features.libshadow?
@@ -46,6 +46,10 @@ def check_manage_expiry
cmd
end
+ def check_system_users
+ @resource.system? ? ["-r"] : []
+ end
+
def add_properties
cmd = []
Puppet::Type.type(:user).validproperties.each do |property|
@@ -66,6 +70,7 @@ def addcmd
cmd += check_allow_dup
cmd += check_manage_home
cmd += check_manage_expiry
+ cmd += check_system_users
cmd << @resource[:name]
end
View
36 lib/puppet/rails/database/004_add_inventory_service_tables.rb
@@ -0,0 +1,36 @@
+class AddInventoryServiceTables < ActiveRecord::Migration
+ def self.up
+ unless ActiveRecord::Base.connection.tables.include?("inventory_nodes")
+ create_table :inventory_nodes do |t|
+ t.column :name, :string, :null => false
+ t.column :timestamp, :datetime, :null => false
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+
+ add_index :inventory_nodes, :name, :unique => true
+ end
+
+ unless ActiveRecord::Base.connection.tables.include?("inventory_facts")
+ create_table :inventory_facts, :id => false do |t|
+ t.column :node_id, :integer, :null => false
+ t.column :name, :string, :null => false
+ t.column :value, :text, :null => false
+ end
+
+ add_index :inventory_facts, [:node_id, :name], :unique => true
+ end
+ end
+
+ def self.down
+ unless ActiveRecord::Base.connection.tables.include?("inventory_nodes")
+ remove_index :inventory_nodes, :name
+ drop_table :inventory_nodes
+ end
+
+ if ActiveRecord::Base.connection.tables.include?("inventory_facts")
+ remove_index :inventory_facts, [:node_id, :name]
+ drop_table :inventory_facts
+ end
+ end
+end
View
17 lib/puppet/rails/database/schema.rb
@@ -103,6 +103,23 @@ def self.init
t.column :created_at, :datetime
end
add_index :param_names, :name
+
+ create_table :inventory_nodes do |t|
+ t.column :name, :string, :null => false
+ t.column :timestamp, :datetime, :null => false
+ t.column :updated_at, :datetime
+ t.column :created_at, :datetime
+ end
+
+ add_index :inventory_nodes, :name, :unique => true
+
+ create_table :inventory_facts, :id => false do |t|
+ t.column :node_id, :integer, :null => false
+ t.column :name, :string, :null => false
+ t.column :value, :text, :null => false
+ end
+
+ add_index :inventory_facts, [:node_id, :name], :unique => true
end
end
ensure
View
2 lib/puppet/rails/fact_name.rb
@@ -3,5 +3,3 @@
class Puppet::Rails::FactName < ActiveRecord::Base
has_many :fact_values, :dependent => :destroy
end
-
-# $Id: fact_name.rb 1952 2006-12-19 05:47:57Z luke $
View
2 lib/puppet/rails/fact_value.rb
@@ -6,5 +6,3 @@ def to_label
"#{self.fact_name.name}"
end
end
-
-# $Id: fact_value.rb 1952 2006-12-19 05:47:57Z luke $
View
5 lib/puppet/rails/inventory_fact.rb
@@ -0,0 +1,5 @@
+require 'puppet/rails/inventory_node'
+
+class Puppet::Rails::InventoryFact < ::ActiveRecord::Base
+ belongs_to :node, :class_name => "Puppet::Rails::InventoryNode"
+end
View
25 lib/puppet/rails/inventory_node.rb
@@ -0,0 +1,25 @@
+require 'puppet/rails/inventory_fact'
+
+class Puppet::Rails::InventoryNode < ::ActiveRecord::Base
+ has_many :facts, :class_name => "Puppet::Rails::InventoryFact", :foreign_key => :node_id, :dependent => :delete_all
+
+ named_scope :has_fact_with_value, lambda { |name,value|
+ {
+ :conditions => ["inventory_facts.name = ? AND inventory_facts.value = ?", name, value],
+ :joins => :facts
+ }
+ }
+
+ named_scope :has_fact_without_value, lambda { |name,value|
+ {
+ :conditions => ["inventory_facts.name = ? AND inventory_facts.value != ?", name, value],
+ :joins => :facts
+ }
+ }
+
+ def facts_to_hash
+ facts.inject({}) do |fact_hash,fact|
+ fact_hash.merge(fact.name => fact.value)
+ end
+ end
+end
View
2 lib/puppet/reference/configuration.rb
@@ -122,7 +122,7 @@
Puppet can also create user and group accounts for itself (one `puppet` group
and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument:
- $ puppet agent --mkusers
+ $ puppet master --mkusers
## Signals
View
2 lib/puppet/reference/metaparameter.rb
@@ -29,7 +29,7 @@
params.sort { |a,b|
a.to_s <=> b.to_s
}.each { |param|
- str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 4)
+ str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 3)
}
rescue => detail
puts detail.backtrace
View
5 lib/puppet/reports/store.rb
@@ -15,7 +15,10 @@ def process
dir = File.join(Puppet[:reportdir], client)
- Dir.mkdir(dir, 0750) unless FileTest.exists?(dir)
+ if ! FileTest.exists?(dir)
+ FileUtils.mkdir_p(dir)
+ FileUtils.chmod_R(0750, dir)
+ end
# Now store the report.
now = Time.now.gmtime
View
64 lib/puppet/resource.rb
@@ -5,6 +5,11 @@
# The simplest resource class. Eventually it will function as the
# base class for all resource-like behaviour.
class Puppet::Resource
+ # This stub class is only needed for serialization compatibility with 0.25.x.
+ # Specifically, it exists to provide a compatibility API when using YAML
+ # serialized objects loaded from StoreConfigs.
+ Reference = Puppet::Resource
+
include Puppet::Util::Tagging
require 'puppet/resource/type_collection_helper'
@@ -87,7 +92,7 @@ def self.value_to_pson_data(value)
def yaml_property_munge(x)
case x
when Hash
- x.inject({}) { |h,kv|
+ x.inject({}) { |h,kv|
k,v = kv
h[k] = self.class.value_to_pson_data(v)
h
@@ -104,21 +109,21 @@ def to_pson(*args)
# be overridden at some point, but this works for now.
%w{has_key? keys length delete empty? <<}.each do |method|
define_method(method) do |*args|
- @parameters.send(method, *args)
+ parameters.send(method, *args)
end
end
# Set a given parameter. Converts all passed names
# to lower-case symbols.
def []=(param, value)
validate_parameter(param) if validate_parameters
- @parameters[parameter_name(param)] = value
+ parameters[parameter_name(param)] = value
end
# Return a given parameter's value. Converts all passed names
# to lower-case symbols.
def [](param)
- @parameters[parameter_name(param)]
+ parameters[parameter_name(param)]
end
def ==(other)
@@ -140,11 +145,11 @@ def builtin_type?
# Iterate over each param/value pair, as required for Enumerable.
def each
- @parameters.each { |p,v| yield p, v }
+ parameters.each { |p,v| yield p, v }
end
def include?(parameter)
- super || @parameters.keys.include?( parameter_name(parameter) )
+ super || parameters.keys.include?( parameter_name(parameter) )
end
# These two methods are extracted into a Helper
@@ -170,14 +175,6 @@ def environment=(env)
end
end
- # This stub class is only needed for serialization compatibility with 0.25.x
- class Reference
- attr_accessor :type,:title
- def initialize(type,title)
- @type,@title = type,title
- end
- end
-
# Create our resource.
def initialize(type, title = nil, attributes = {})
@parameters = {}
@@ -204,7 +201,7 @@ def initialize(type, title = nil, attributes = {})
tag(self.type)
tag(self.title) if valid_tag?(self.title)
- @reference = Reference.new(@type,@title) # for serialization compatibility with 0.25.x
+ @reference = self # for serialization compatibility with 0.25.x
if strict? and ! resource_type
if @type == 'Class'
raise ArgumentError, "Could not find declared class #{title}"
@@ -234,7 +231,7 @@ def resource_type
# Produce a simple hash of our parameters.
def to_hash
- parse_title.merge @parameters
+ parse_title.merge parameters
end
def to_s
@@ -255,15 +252,26 @@ def key_attributes
# Convert our resource to Puppet code.
def to_manifest
- "%s { '%s':\n%s\n}" % [self.type.to_s.downcase, self.title,
- @parameters.collect { |p, v|
- if v.is_a? Array
- " #{p} => [\'#{v.join("','")}\']"
- else
- " #{p} => \'#{v}\'"
- end
- }.join(",\n")
- ]
+ # Collect list of attributes to align => and move ensure first
+ attr = parameters.keys
+ attr_max = attr.inject(0) { |max,k| k.to_s.length > max ? k.to_s.length : max }
+
+ attr.sort!
+ if attr.first != :ensure && attr.include?(:ensure)
+ attr.delete(:ensure)
+ attr.unshift(:ensure)
+ end
+
+ attributes = attr.collect { |k|
+ v = parameters[k]
+ if v.is_a? Array
+ " %-#{attr_max}s => %s,\n" % [ k, "[\'#{v.join("', '")}\']" ]
+ else
+ " %-#{attr_max}s => %s,\n" % [ k, "\'#{v}\'" ]
+ end
+ }
+
+ "%s { '%s':\n%s}" % [self.type.to_s.downcase, self.title, attributes]
end
def to_ref
@@ -422,4 +430,10 @@ def parse_title
return { :name => title.to_s }
end
end
+
+ def parameters
+ # @parameters could have been loaded from YAML, causing it to be nil (by
+ # bypassing initialize).
+ @parameters ||= {}
+ end
end
View
10 lib/puppet/type.rb
@@ -200,7 +200,7 @@ def self.title_patterns
end
def uniqueness_key
- to_resource.uniqueness_key
+ self.class.key_attributes.sort_by { |attribute_name| attribute_name.to_s }.map{ |attribute_name| self[attribute_name] }
end
# Create a new parameter. Requires a block and a name, stores it in the
@@ -382,8 +382,8 @@ def [](name)
fail("Invalid parameter #{name}(#{name.inspect})") unless self.class.validattr?(name)
- if name == :name
- name = name_var
+ if name == :name && nv = name_var
+ name = nv
end
if obj = @parameters[name]
@@ -403,8 +403,8 @@ def []=(name,value)
fail("Invalid parameter #{name}") unless self.class.validattr?(name)
- if name == :name
- name = name_var
+ if name == :name && nv = name_var
+ name = nv
end
raise Puppet::Error.new("Got nil value for #{name}") if value.nil?
View
8 lib/puppet/type/augeas.rb
@@ -98,10 +98,10 @@
can be either a string which contains a command or an array of commands.
Commands supported are:
- set [PATH] [VALUE] Sets the value VALUE at loction PATH
- rm [PATH] Removes the node at location PATH
- remove [PATH] Synonym for rm
- clear [PATH] Keeps the node at PATH, but removes the value.
+ set [PATH] [VALUE] Sets the value VALUE at loction PATH
+ rm [PATH] Removes the node at location PATH
+ remove [PATH] Synonym for rm
+ clear [PATH] Keeps the node at PATH, but removes the value.
ins [LABEL] [WHERE] [PATH] Inserts an empty node LABEL either [WHERE={before|after}] PATH.
insert [LABEL] [WHERE] [PATH] Synonym for ins
View
6 lib/puppet/type/computer.rb
@@ -14,7 +14,11 @@
type as per other platforms.
This type primarily exists to create localhost Computer objects that MCX
- policy can then be attached to."
+ policy can then be attached to.
+
+ **Autorequires:** If Puppet is managing the plist file representing a
+ Computer object (located at `/var/db/dslocal/nodes/Default/computers/{name}.plist`),
+ the Computer resource will autorequire it."
# ensurable
View
4 lib/puppet/type/exec.rb
@@ -22,7 +22,9 @@ module Puppet
to native Puppet types as quickly as possible. If you find that
you are doing a lot of work with `exec`, please at least notify
us at Puppet Labs what you are doing, and hopefully we can work with
- you to get a native resource type for the work you are doing."
+ you to get a native resource type for the work you are doing.
+
+ **Autorequires:** If Puppet is managing an exec's cwd or the executable file used in an exec's command, the exec resource will autorequire those files. If Puppet is managing the user that an exec should run as, the exec resource will autorequire that user."
require 'open3'
View
4 lib/puppet/type/file.rb
@@ -22,7 +22,9 @@
If you find that you are often copying files in from a central
location, rather than using native resources, please contact
Puppet Labs and we can hopefully work with you to develop a
- native resource to support what you are doing."
+ native resource to support what you are doing.
+
+ **Autorequires:** If Puppet is managing the user or group that owns a file, the file resource will autorequire them. If Puppet is managing any parent directories of a file, the file resource will autorequire them."
def self.title_patterns
[ [ /^(.*?)\/*\Z/m, [ [ :path, lambda{|x| x} ] ] ] ]
View
28 lib/puppet/type/file/content.rb
@@ -17,22 +17,21 @@ module Puppet
desc "Specify the contents of a file as a string. Newlines, tabs, and
spaces can be specified using the escaped syntax (e.g., \\n for a newline). The primary purpose of this parameter is to provide a
- kind of limited templating::
-
- define resolve(nameserver1, nameserver2, domain, search) {
- $str = \"search $search
- domain $domain
- nameserver $nameserver1
- nameserver $nameserver2
- \"
-
- file { \"/etc/resolv.conf\":
- content => $str
+ kind of limited templating:
+
+ define resolve(nameserver1, nameserver2, domain, search) {
+ $str = \"search $search
+ domain $domain
+ nameserver $nameserver1
+ nameserver $nameserver2
+ \"
+
+ file { \"/etc/resolv.conf\":
+ content => $str
+ }
}
- }
- This attribute is especially useful when used with
- `PuppetTemplating templating`:trac:."
+ This attribute is especially useful when used with templating."
# Store a checksum as the value, rather than the actual content.
# Simplifies everything.
@@ -201,7 +200,6 @@ def chunk_file_from_source(source_or_content)
connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
connection.request_get(indirection2uri(request), add_accept_encoding({"Accept" => "raw"})) do |response|