puppet 2.6.4 → 2.6.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (221) hide show
  1. data/CHANGELOG +147 -0
  2. data/LICENSE +2 -2
  3. data/Rakefile +3 -4
  4. data/lib/puppet.rb +1 -1
  5. data/lib/puppet/application.rb +22 -5
  6. data/lib/puppet/application/apply.rb +2 -18
  7. data/lib/puppet/application/doc.rb +1 -4
  8. data/lib/puppet/application/inspect.rb +178 -0
  9. data/lib/puppet/configurer.rb +9 -11
  10. data/lib/puppet/configurer/plugin_handler.rb +0 -2
  11. data/lib/puppet/defaults.rb +12 -3
  12. data/lib/puppet/external/pson/pure/generator.rb +1 -22
  13. data/lib/puppet/file_bucket/dipper.rb +9 -3
  14. data/lib/puppet/file_bucket/file.rb +14 -94
  15. data/lib/puppet/indirector.rb +4 -0
  16. data/lib/puppet/indirector/catalog/active_record.rb +1 -1
  17. data/lib/puppet/indirector/file_bucket_file/file.rb +64 -75
  18. data/lib/puppet/indirector/indirection.rb +18 -8
  19. data/lib/puppet/indirector/resource/ral.rb +7 -2
  20. data/lib/puppet/indirector/rest.rb +19 -2
  21. data/lib/puppet/network/http/api/v1.rb +3 -0
  22. data/lib/puppet/network/http/handler.rb +16 -1
  23. data/lib/puppet/network/http/rack/rest.rb +1 -3
  24. data/lib/puppet/network/rest_authconfig.rb +4 -12
  25. data/lib/puppet/network/rights.rb +28 -14
  26. data/lib/puppet/parser/ast.rb +4 -0
  27. data/lib/puppet/parser/compiler.rb +18 -3
  28. data/lib/puppet/parser/functions/defined.rb +28 -6
  29. data/lib/puppet/parser/functions/fqdn_rand.rb +6 -3
  30. data/lib/puppet/parser/templatewrapper.rb +1 -0
  31. data/lib/puppet/property.rb +16 -1
  32. data/lib/puppet/property/keyvalue.rb +0 -2
  33. data/lib/puppet/property/list.rb +0 -2
  34. data/lib/puppet/provider/file/posix.rb +1 -3
  35. data/lib/puppet/provider/file/win32.rb +1 -3
  36. data/lib/puppet/provider/maillist/mailman.rb +3 -5
  37. data/lib/puppet/provider/mount.rb +2 -0
  38. data/lib/puppet/provider/nameservice/directoryservice.rb +2 -2
  39. data/lib/puppet/provider/package/freebsd.rb +2 -2
  40. data/lib/puppet/provider/zone/solaris.rb +1 -1
  41. data/lib/puppet/reference/configuration.rb +2 -2
  42. data/lib/puppet/reference/function.rb +4 -0
  43. data/lib/puppet/relationship.rb +4 -0
  44. data/lib/puppet/reports/store.rb +1 -19
  45. data/lib/puppet/resource.rb +11 -2
  46. data/lib/puppet/resource/status.rb +24 -3
  47. data/lib/puppet/resource/type.rb +24 -16
  48. data/lib/puppet/resource/type_collection.rb +4 -1
  49. data/lib/puppet/simple_graph.rb +4 -0
  50. data/lib/puppet/transaction.rb +1 -28
  51. data/lib/puppet/transaction/event.rb +9 -4
  52. data/lib/puppet/transaction/report.rb +42 -22
  53. data/lib/puppet/transaction/resource_harness.rb +99 -71
  54. data/lib/puppet/type.rb +22 -9
  55. data/lib/puppet/type/cron.rb +1 -5
  56. data/lib/puppet/type/exec.rb +4 -34
  57. data/lib/puppet/type/file.rb +19 -26
  58. data/lib/puppet/type/file/checksum.rb +1 -1
  59. data/lib/puppet/type/file/content.rb +2 -1
  60. data/lib/puppet/type/file/ctime.rb +18 -0
  61. data/lib/puppet/type/file/ensure.rb +1 -1
  62. data/lib/puppet/type/file/mode.rb +10 -44
  63. data/lib/puppet/type/file/mtime.rb +17 -0
  64. data/lib/puppet/type/file/owner.rb +1 -1
  65. data/lib/puppet/type/file/source.rb +0 -1
  66. data/lib/puppet/type/file/target.rb +1 -1
  67. data/lib/puppet/type/file/type.rb +5 -12
  68. data/lib/puppet/type/host.rb +1 -1
  69. data/lib/puppet/type/mount.rb +2 -2
  70. data/lib/puppet/type/package.rb +0 -2
  71. data/lib/puppet/type/service.rb +11 -5
  72. data/lib/puppet/type/user.rb +7 -9
  73. data/lib/puppet/type/yumrepo.rb +2 -2
  74. data/lib/puppet/type/zpool.rb +0 -4
  75. data/lib/puppet/util/checksums.rb +24 -1
  76. data/lib/puppet/util/command_line.rb +6 -2
  77. data/lib/puppet/util/command_line/puppet +5 -1
  78. data/lib/puppet/util/command_line/puppetca +2 -2
  79. data/lib/puppet/util/command_line/puppetd +11 -9
  80. data/lib/puppet/util/command_line/puppetdoc +2 -2
  81. data/lib/puppet/util/command_line/puppetmasterd +5 -0
  82. data/lib/puppet/util/log.rb +15 -8
  83. data/lib/puppet/util/log/destinations.rb +2 -0
  84. data/lib/puppet/util/log_paths.rb +1 -1
  85. data/lib/puppet/util/logging.rb +1 -1
  86. data/lib/puppet/util/metric.rb +1 -0
  87. data/lib/puppet/util/reference.rb +1 -10
  88. data/lib/puppet/util/settings.rb +1 -1
  89. data/lib/puppet/util/zaml.rb +30 -31
  90. data/spec/fixtures/unit/provider/mount/mount-output.aix.txt +7 -0
  91. data/spec/integration/application/apply_spec.rb +1 -2
  92. data/spec/integration/defaults_spec.rb +1 -0
  93. data/spec/integration/indirector/catalog/queue_spec.rb +1 -4
  94. data/spec/integration/indirector/report/rest_spec.rb +13 -17
  95. data/spec/integration/network/formats_spec.rb +2 -5
  96. data/spec/integration/network/server/mongrel_spec.rb +1 -2
  97. data/spec/integration/provider/mailalias/aliases_spec.rb +0 -1
  98. data/spec/integration/provider/package_spec.rb +1 -3
  99. data/spec/integration/provider/service/init_spec.rb +3 -9
  100. data/spec/integration/reference/providers_spec.rb +2 -2
  101. data/spec/integration/resource/catalog_spec.rb +1 -2
  102. data/spec/integration/transaction/report_spec.rb +1 -1
  103. data/spec/monkey_patches/alias_should_to_must.rb +2 -0
  104. data/spec/shared_behaviours/file_server_terminus.rb +1 -1
  105. data/spec/shared_behaviours/file_serving.rb +1 -1
  106. data/spec/shared_behaviours/memory_terminus.rb +1 -1
  107. data/spec/spec_helper.rb +8 -6
  108. data/spec/unit/application/agent_spec.rb +1 -0
  109. data/spec/unit/application/apply_spec.rb +7 -7
  110. data/spec/unit/application/doc_spec.rb +2 -2
  111. data/spec/unit/application/filebucket_spec.rb +1 -0
  112. data/spec/unit/application/inspect_spec.rb +278 -0
  113. data/spec/unit/application/kick_spec.rb +1 -3
  114. data/spec/unit/application/master_spec.rb +1 -3
  115. data/spec/unit/application/queue_spec.rb +1 -0
  116. data/spec/unit/application_spec.rb +63 -5
  117. data/spec/unit/configurer/plugin_handler_spec.rb +5 -1
  118. data/spec/unit/configurer_spec.rb +33 -49
  119. data/spec/unit/file_bucket/dipper_spec.rb +69 -77
  120. data/spec/unit/file_bucket/file_spec.rb +12 -127
  121. data/spec/unit/file_serving/fileset_spec.rb +1 -0
  122. data/spec/unit/file_serving/metadata_spec.rb +4 -4
  123. data/spec/unit/indirector/active_record_spec.rb +1 -0
  124. data/spec/unit/indirector/catalog/active_record_spec.rb +29 -13
  125. data/spec/unit/indirector/facts/active_record_spec.rb +2 -3
  126. data/spec/unit/indirector/facts/couch_spec.rb +1 -2
  127. data/spec/unit/indirector/file_bucket_file/file_spec.rb +202 -218
  128. data/spec/unit/indirector/file_server_spec.rb +6 -7
  129. data/spec/unit/indirector/indirection_spec.rb +71 -2
  130. data/spec/unit/indirector/ldap_spec.rb +2 -6
  131. data/spec/unit/indirector/node/active_record_spec.rb +1 -3
  132. data/spec/unit/indirector/queue_spec.rb +1 -3
  133. data/spec/unit/indirector/rest_spec.rb +37 -1
  134. data/spec/unit/indirector/ssl_file_spec.rb +5 -5
  135. data/spec/unit/indirector_spec.rb +6 -1
  136. data/spec/unit/module_spec.rb +1 -3
  137. data/spec/unit/network/formats_spec.rb +2 -5
  138. data/spec/unit/network/http/api/v1_spec.rb +4 -0
  139. data/spec/unit/network/http/compression_spec.rb +1 -3
  140. data/spec/unit/network/http/handler_spec.rb +39 -0
  141. data/spec/unit/network/http/mongrel/rest_spec.rb +1 -2
  142. data/spec/unit/network/http/mongrel_spec.rb +3 -9
  143. data/spec/unit/network/http/rack/rest_spec.rb +1 -3
  144. data/spec/unit/network/http/rack/xmlrpc_spec.rb +2 -3
  145. data/spec/unit/network/http/rack_spec.rb +2 -3
  146. data/spec/unit/network/http/webrick_spec.rb +1 -0
  147. data/spec/unit/network/rest_authconfig_spec.rb +1 -1
  148. data/spec/unit/network/rights_spec.rb +43 -23
  149. data/spec/unit/network/xmlrpc/client_spec.rb +1 -0
  150. data/spec/unit/parameter_spec.rb +1 -2
  151. data/spec/unit/parser/collector_spec.rb +3 -6
  152. data/spec/unit/parser/compiler_spec.rb +90 -5
  153. data/spec/unit/parser/lexer_spec.rb +3 -2
  154. data/spec/unit/parser/templatewrapper_spec.rb +1 -0
  155. data/spec/unit/property/keyvalue_spec.rb +5 -5
  156. data/spec/unit/property/list_spec.rb +7 -7
  157. data/spec/unit/provider/mount/parsed_spec.rb +1 -2
  158. data/spec/unit/provider/mount_spec.rb +8 -0
  159. data/spec/unit/provider/nameservice/directoryservice_spec.rb +38 -0
  160. data/spec/unit/provider/package/freebsd_spec.rb +55 -0
  161. data/spec/unit/provider/service/init_spec.rb +2 -0
  162. data/spec/unit/rails/host_spec.rb +1 -3
  163. data/spec/unit/rails/param_value_spec.rb +2 -3
  164. data/spec/unit/rails/resource_spec.rb +2 -3
  165. data/spec/unit/rails_spec.rb +5 -15
  166. data/spec/unit/relationship_spec.rb +2 -6
  167. data/spec/unit/reports/http_spec.rb +1 -1
  168. data/spec/unit/reports/store_spec.rb +31 -0
  169. data/spec/unit/reports/tagmail_spec.rb +1 -1
  170. data/spec/unit/resource/catalog_spec.rb +2 -6
  171. data/spec/unit/resource/status_spec.rb +53 -3
  172. data/spec/unit/resource/type_collection_spec.rb +0 -8
  173. data/spec/unit/resource/type_spec.rb +50 -4
  174. data/spec/unit/resource_spec.rb +10 -6
  175. data/spec/unit/ssl/certificate_authority/interface_spec.rb +1 -1
  176. data/spec/unit/transaction/event_spec.rb +21 -2
  177. data/spec/unit/transaction/report_spec.rb +91 -35
  178. data/spec/unit/transaction/resource_harness_spec.rb +289 -208
  179. data/spec/unit/transaction_spec.rb +1 -6
  180. data/spec/unit/type/augeas_spec.rb +1 -3
  181. data/spec/unit/type/file/content_spec.rb +63 -10
  182. data/spec/unit/type/file/ctime.rb +35 -0
  183. data/spec/unit/type/file/ensure_spec.rb +8 -7
  184. data/spec/unit/type/file/group_spec.rb +5 -5
  185. data/spec/unit/type/file/mtime.rb +35 -0
  186. data/spec/unit/type/file/owner_spec.rb +7 -7
  187. data/spec/unit/type/file/selinux_spec.rb +2 -2
  188. data/spec/unit/type/file/source_spec.rb +3 -3
  189. data/spec/unit/type/file/type.rb +20 -0
  190. data/spec/unit/type/file_spec.rb +131 -8
  191. data/spec/unit/type/mount_spec.rb +4 -4
  192. data/spec/unit/type/package_spec.rb +3 -3
  193. data/spec/unit/type/ssh_authorized_key_spec.rb +1 -1
  194. data/spec/unit/type/user_spec.rb +31 -3
  195. data/spec/unit/type/zpool_spec.rb +12 -12
  196. data/spec/unit/type_spec.rb +2 -2
  197. data/spec/unit/util/checksums_spec.rb +9 -1
  198. data/spec/unit/util/command_line_spec.rb +29 -0
  199. data/spec/unit/util/log/destinations_spec.rb +13 -0
  200. data/spec/unit/util/log_spec.rb +24 -12
  201. data/spec/unit/util/logging_spec.rb +1 -1
  202. data/spec/unit/util/metric_spec.rb +7 -7
  203. data/spec/unit/util/pson_spec.rb +15 -0
  204. data/spec/unit/util/queue/stomp_spec.rb +2 -6
  205. data/spec/unit/util/settings/file_setting_spec.rb +1 -3
  206. data/spec/unit/util/zaml_spec.rb +51 -0
  207. data/test/language/snippets.rb +3 -0
  208. data/test/lib/puppettest/fileparsing.rb +2 -0
  209. data/test/lib/puppettest/reporttesting.rb +1 -1
  210. data/test/lib/puppettest/support/utils.rb +1 -1
  211. data/test/network/server/mongrel_test.rb +0 -6
  212. data/test/other/report.rb +1 -1
  213. data/test/ral/providers/cron/crontab.rb +4 -1
  214. data/test/ral/type/file.rb +1 -1
  215. data/test/ral/type/filesources.rb +1 -4
  216. metadata +1119 -1113
  217. data/lib/puppet/transaction/change.rb +0 -87
  218. data/spec/Rakefile +0 -91
  219. data/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb +0 -46
  220. data/spec/spec_specs/runnable_spec.rb +0 -95
  221. data/spec/unit/transaction/change_spec.rb +0 -193
@@ -7,92 +7,138 @@ class Puppet::Transaction::ResourceHarness
7
7
  attr_reader :transaction
8
8
 
9
9
  def allow_changes?(resource)
10
- return true unless resource.purging? and resource.deleting?
11
- return true unless deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? }
12
-
13
- deplabel = deps.collect { |r| r.ref }.join(",")
14
- plurality = deps.length > 1 ? "":"s"
15
- resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
16
- false
17
- end
18
-
19
- def apply_changes(status, changes)
20
- changes.each do |change|
21
- status << change.apply
22
-
23
- cache(change.property.resource, change.property.name, change.is) if change.auditing?
10
+ if resource.purging? and resource.deleting? and deps = relationship_graph.dependents(resource) \
11
+ and ! deps.empty? and deps.detect { |d| ! d.deleting? }
12
+ deplabel = deps.collect { |r| r.ref }.join(",")
13
+ plurality = deps.length > 1 ? "":"s"
14
+ resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
15
+ false
16
+ else
17
+ true
24
18
  end
25
- status.changed = true
26
19
  end
27
20
 
28
- # Used mostly for scheduling at this point.
21
+ # Used mostly for scheduling and auditing at this point.
29
22
  def cached(resource, name)
30
23
  Puppet::Util::Storage.cache(resource)[name]
31
24
  end
32
25
 
33
- # Used mostly for scheduling at this point.
26
+ # Used mostly for scheduling and auditing at this point.
34
27
  def cache(resource, name, value)
35
28
  Puppet::Util::Storage.cache(resource)[name] = value
36
29
  end
37
30
 
38
- def changes_to_perform(status, resource)
31
+ def perform_changes(resource)
39
32
  current = resource.retrieve_resource
40
33
 
41
34
  cache resource, :checked, Time.now
42
35
 
43
36
  return [] if ! allow_changes?(resource)
44
37
 
45
- audited = copy_audited_parameters(resource, current)
46
-
47
- if param = resource.parameter(:ensure)
48
- return [] if absent_and_not_being_created?(current, param)
49
- return [Puppet::Transaction::Change.new(param, current[:ensure])] unless ensure_is_insync?(current, param)
50
- return [] if ensure_should_be_absent?(current, param)
38
+ current_values = current.to_hash
39
+ historical_values = Puppet::Util::Storage.cache(resource).dup
40
+ desired_values = {}
41
+ resource.properties.each do |property|
42
+ desired_values[property.name] = property.should
51
43
  end
44
+ audited_params = (resource[:audit] || []).map { |p| p.to_sym }
45
+ synced_params = []
52
46
 
53
- resource.properties.reject { |p| p.name == :ensure }.reject do |param|
54
- param.should.nil?
55
- end.reject do |param|
56
- param_is_insync?(current, param)
57
- end.collect do |param|
58
- change = Puppet::Transaction::Change.new(param, current[param.name])
59
- change.auditing = true if audited.include?(param.name)
60
- change
47
+ # Record the current state in state.yml.
48
+ audited_params.each do |param|
49
+ cache(resource, param, current_values[param])
61
50
  end
62
- end
63
51
 
64
- def copy_audited_parameters(resource, current)
65
- return [] unless audit = resource[:audit]
66
- audit = Array(audit).collect { |p| p.to_sym }
67
- audited = []
68
- audit.find_all do |param|
69
- next if resource[param]
52
+ # Update the machine state & create logs/events
53
+ events = []
54
+ ensure_param = resource.parameter(:ensure)
55
+ if desired_values[:ensure] && !ensure_param.safe_insync?(current_values[:ensure])
56
+ events << apply_parameter(ensure_param, current_values[:ensure], audited_params.include?(:ensure), historical_values[:ensure])
57
+ synced_params << :ensure
58
+ elsif current_values[:ensure] != :absent
59
+ work_order = resource.properties # Note: only the resource knows what order to apply changes in
60
+ work_order.each do |param|
61
+ if desired_values[param.name] && !param.safe_insync?(current_values[param.name])
62
+ events << apply_parameter(param, current_values[param.name], audited_params.include?(param.name), historical_values[param.name])
63
+ synced_params << param.name
64
+ end
65
+ end
66
+ end
70
67
 
71
- if value = cached(resource, param)
72
- resource[param] = value
73
- audited << param
68
+ # Add more events to capture audit results
69
+ audited_params.each do |param_name|
70
+ if historical_values.include?(param_name)
71
+ if historical_values[param_name] != current_values[param_name] && !synced_params.include?(param_name)
72
+ event = create_change_event(resource.parameter(param_name), current_values[param_name], true, historical_values[param_name])
73
+ event.send_log
74
+ events << event
75
+ end
74
76
  else
75
- resource.debug "Storing newly-audited value #{current[param]} for #{param}"
76
- cache(resource, param, current[param])
77
+ resource.property(param_name).notice "audit change: newly-recorded value #{current_values[param_name]}"
78
+ end
79
+ end
80
+
81
+ events
82
+ end
83
+
84
+ def create_change_event(property, current_value, do_audit, historical_value)
85
+ event = property.event
86
+ event.previous_value = current_value
87
+ event.desired_value = property.should
88
+ event.historical_value = historical_value
89
+
90
+ if do_audit
91
+ event.audited = true
92
+ event.status = "audit"
93
+ if historical_value != current_value
94
+ event.message = "audit change: previously recorded value #{property.is_to_s(historical_value)} has been changed to #{property.is_to_s(current_value)}"
77
95
  end
78
96
  end
79
97
 
80
- audited
98
+ event
99
+ end
100
+
101
+ def apply_parameter(property, current_value, do_audit, historical_value)
102
+ event = create_change_event(property, current_value, do_audit, historical_value)
103
+
104
+ if do_audit && historical_value && historical_value != current_value
105
+ brief_audit_message = " (previously recorded value was #{property.is_to_s(historical_value)})"
106
+ else
107
+ brief_audit_message = ""
108
+ end
109
+
110
+ if property.noop
111
+ event.message = "current_value #{property.is_to_s(current_value)}, should be #{property.should_to_s(property.should)} (noop)#{brief_audit_message}"
112
+ event.status = "noop"
113
+ else
114
+ property.sync
115
+ event.message = [ property.change_to_s(current_value, property.should), brief_audit_message ].join
116
+ event.status = "success"
117
+ end
118
+ event
119
+ rescue => detail
120
+ puts detail.backtrace if Puppet[:trace]
121
+ event.status = "failure"
122
+
123
+ event.message = "change from #{property.is_to_s(current_value)} to #{property.should_to_s(property.should)} failed: #{detail}"
124
+ event
125
+ ensure
126
+ event.send_log
81
127
  end
82
128
 
83
129
  def evaluate(resource)
84
130
  start = Time.now
85
131
  status = Puppet::Resource::Status.new(resource)
86
132
 
87
- if changes = changes_to_perform(status, resource) and ! changes.empty?
88
- status.out_of_sync = true
89
- status.change_count = changes.length
90
- apply_changes(status, changes)
91
- if ! resource.noop?
92
- cache(resource, :synced, Time.now)
93
- resource.flush if resource.respond_to?(:flush)
94
- end
133
+ perform_changes(resource).each do |event|
134
+ status << event
135
+ end
136
+
137
+ if status.changed? && ! resource.noop?
138
+ cache(resource, :synced, Time.now)
139
+ resource.flush if resource.respond_to?(:flush)
95
140
  end
141
+
96
142
  return status
97
143
  rescue => detail
98
144
  resource.fail "Could not create resource status: #{detail}" unless status
@@ -129,22 +175,4 @@ class Puppet::Transaction::ResourceHarness
129
175
  return nil unless name = resource[:schedule]
130
176
  resource.catalog.resource(:schedule, name) || resource.fail("Could not find schedule #{name}")
131
177
  end
132
-
133
- private
134
-
135
- def absent_and_not_being_created?(current, param)
136
- current[:ensure] == :absent and param.should.nil?
137
- end
138
-
139
- def ensure_is_insync?(current, param)
140
- param.insync?(current[:ensure])
141
- end
142
-
143
- def ensure_should_be_absent?(current, param)
144
- param.should == :absent
145
- end
146
-
147
- def param_is_insync?(current, param)
148
- param.insync?(current[param.name])
149
- end
150
178
  end
@@ -446,7 +446,7 @@ class Type
446
446
  # Create a transaction event. Called by Transaction or by
447
447
  # a property.
448
448
  def event(options = {})
449
- Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags, :version => version}.merge(options))
449
+ Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags}.merge(options))
450
450
  end
451
451
 
452
452
  # Let the catalog determine whether a given cached value is
@@ -648,7 +648,7 @@ class Type
648
648
  "The is value is not in the is array for '#{property.name}'"
649
649
  end
650
650
  ensureis = is[property]
651
- if property.insync?(ensureis) and property.should == :absent
651
+ if property.safe_insync?(ensureis) and property.should == :absent
652
652
  return true
653
653
  end
654
654
  end
@@ -660,7 +660,7 @@ class Type
660
660
  end
661
661
 
662
662
  propis = is[property]
663
- unless property.insync?(propis)
663
+ unless property.safe_insync?(propis)
664
664
  property.debug("Not in sync: #{propis.inspect} vs #{property.should.inspect}")
665
665
  insync = false
666
666
  #else
@@ -957,12 +957,25 @@ class Type
957
957
  end
958
958
 
959
959
  newmetaparam(:audit) do
960
- desc "Audit specified attributes of resources over time, and report if any have changed.
961
- This attribute can be used to track changes to any resource over time, and can
962
- provide an audit trail of every change that happens on any given machine.
963
-
964
- Note that you cannot both audit and manage an attribute - managing it guarantees
965
- the value, and any changes already get logged."
960
+ desc "Marks a subset of this resource's unmanaged attributes for auditing. Accepts an
961
+ attribute name or a list of attribute names.
962
+
963
+ Auditing a resource attribute has two effects: First, whenever a catalog
964
+ is applied with puppet apply or puppet agent, Puppet will check whether
965
+ that attribute of the resource has been modified, comparing its current
966
+ value to the previous run; any change will be logged alongside any actions
967
+ performed by Puppet while applying the catalog.
968
+
969
+ Secondly, marking a resource attribute for auditing will include that
970
+ attribute in inspection reports generated by puppet inspect; see the
971
+ puppet inspect documentation for more details.
972
+
973
+ Managed attributes for a resource can also be audited, but note that
974
+ changes made by Puppet will be logged as additional modifications. (I.e.
975
+ if a user manually edits a file whose contents are audited and managed,
976
+ puppet agent's next two runs will both log an audit notice: the first run
977
+ will log the user's edit and then revert the file to the desired state,
978
+ and the second run will log the edit made by Puppet.)"
966
979
 
967
980
  validate do |list|
968
981
  list = Array(list).collect {|p| p.to_sym}
@@ -54,11 +54,7 @@ Puppet::Type.newtype(:cron) do
54
54
  # We have to override the parent method, because we consume the entire
55
55
  # "should" array
56
56
  def insync?(is)
57
- if @should
58
- self.is_to_s(is) == self.should_to_s
59
- else
60
- true
61
- end
57
+ self.is_to_s(is) == self.should_to_s
62
58
  end
63
59
 
64
60
  # A method used to do parameter input handling. Converts integers
@@ -9,41 +9,11 @@ module Puppet
9
9
  commands is to use the checks like `creates` to avoid running the
10
10
  command unless some condition is met.
11
11
 
12
- Note also that you can restrict an `exec` to only run when it receives
12
+ Note that you can restrict an `exec` to only run when it receives
13
13
  events by using the `refreshonly` parameter; this is a useful way to
14
14
  have your configuration respond to events with arbitrary commands.
15
15
 
16
- It is worth noting that `exec` is special, in that it is not
17
- currently considered an error to have multiple `exec` instances
18
- with the same name. This was done purely because it had to be this
19
- way in order to get certain functionality, but it complicates things.
20
- In particular, you will not be able to use `exec` instances that
21
- share their commands with other instances as a dependency, since
22
- Puppet has no way of knowing which instance you mean.
23
-
24
- For example:
25
-
26
- # defined in the production class
27
- exec { \"make\":
28
- cwd => \"/prod/build/dir\",
29
- path => \"/usr/bin:/usr/sbin:/bin\"
30
- }
31
-
32
- . etc. .
33
-
34
- # defined in the test class
35
- exec { \"make\":
36
- cwd => \"/test/build/dir\",
37
- path => \"/usr/bin:/usr/sbin:/bin\"
38
- }
39
-
40
- Any other type would throw an error, complaining that you had
41
- the same instance being managed in multiple places, but these are
42
- obviously different images, so `exec` had to be treated specially.
43
-
44
- It is recommended to avoid duplicate names whenever possible.
45
-
46
- Note that if an `exec` receives an event from another resource,
16
+ Note also that if an `exec` receives an event from another resource,
47
17
  it will get executed again (or execute the command specified in `refresh`, if there is one).
48
18
 
49
19
  There is a strong tendency to use `exec` to do whatever work Puppet
@@ -335,7 +305,7 @@ module Puppet
335
305
  # Pull down the main aliases file
336
306
  file { \"/etc/aliases\":
337
307
  source => \"puppet://server/module/aliases\"
338
- }
308
+ }
339
309
 
340
310
  # Rebuild the database, but only when the file changes
341
311
  exec { newaliases:
@@ -664,7 +634,7 @@ module Puppet
664
634
  def validatecmd(cmd)
665
635
  exe = extractexe(cmd)
666
636
  # if we're not fully qualified, require a path
667
- self.fail "'#{cmd}' is both unqualifed and specified no search path" if File.expand_path(exe) != exe and self[:path].nil?
637
+ self.fail "'#{cmd}' is not qualified and no path was specified. Please qualify the command or specify a path." if File.expand_path(exe) != exe and self[:path].nil?
668
638
  end
669
639
 
670
640
  def extractexe(cmd)
@@ -34,7 +34,7 @@ Puppet::Type.newtype(:file) do
34
34
 
35
35
  validate do |value|
36
36
  # accept various path syntaxes: lone slash, posix, win32, unc
37
- unless (Puppet.features.posix? and (value =~ /^\/$/ or value =~ /^\/[^\/]/)) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/))
37
+ unless (Puppet.features.posix? and value =~ /^\//) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/))
38
38
  fail Puppet::Error, "File paths must be fully qualified, not '#{value}'"
39
39
  end
40
40
  end
@@ -271,17 +271,24 @@ Puppet::Type.newtype(:file) do
271
271
  end
272
272
 
273
273
  CREATORS = [:content, :source, :target]
274
+ SOURCE_ONLY_CHECKSUMS = [:none, :ctime, :mtime]
274
275
 
275
276
  validate do
276
- count = 0
277
+ creator_count = 0
277
278
  CREATORS.each do |param|
278
- count += 1 if self.should(param)
279
+ creator_count += 1 if self.should(param)
279
280
  end
280
- count += 1 if @parameters.include?(:source)
281
- self.fail "You cannot specify more than one of #{CREATORS.collect { |p| p.to_s}.join(", ")}" if count > 1
281
+ creator_count += 1 if @parameters.include?(:source)
282
+ self.fail "You cannot specify more than one of #{CREATORS.collect { |p| p.to_s}.join(", ")}" if creator_count > 1
282
283
 
283
284
  self.fail "You cannot specify a remote recursion without a source" if !self[:source] and self[:recurse] == :remote
284
285
 
286
+ self.fail "You cannot specify source when using checksum 'none'" if self[:checksum] == :none && !self[:source].nil?
287
+
288
+ SOURCE_ONLY_CHECKSUMS.each do |checksum_type|
289
+ self.fail "You cannot specify content when using checksum '#{checksum_type}'" if self[:checksum] == checksum_type && !self[:content].nil?
290
+ end
291
+
285
292
  self.warning "Possible error: recurselimit is set but not recurse, no recursion will happen" if !self[:recurse] and self[:recurselimit]
286
293
  end
287
294
 
@@ -290,25 +297,8 @@ Puppet::Type.newtype(:file) do
290
297
  super(path.gsub(/\/+/, '/').sub(/\/$/, ''))
291
298
  end
292
299
 
293
- # List files, but only one level deep.
294
- def self.instances(base = "/")
295
- return [] unless FileTest.directory?(base)
296
-
297
- files = []
298
- Dir.entries(base).reject { |e|
299
- e == "." or e == ".."
300
- }.each do |name|
301
- path = File.join(base, name)
302
- if obj = self[path]
303
- obj[:audit] = :all
304
- files << obj
305
- else
306
- files << self.new(
307
- :name => path, :audit => :all
308
- )
309
- end
310
- end
311
- files
300
+ def self.instances(base = '/')
301
+ return self.new(:name => base, :recurse => true, :recurselimit => 1, :audit => :all).recurse_local.values
312
302
  end
313
303
 
314
304
  @depthfirst = false
@@ -718,8 +708,9 @@ Puppet::Type.newtype(:file) do
718
708
 
719
709
  mode = self.should(:mode) # might be nil
720
710
  umask = mode ? 000 : 022
711
+ mode_int = mode ? mode.to_i(8) : nil
721
712
 
722
- content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode) { |f| write_content(f) } }
713
+ content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode_int ) { |f| write_content(f) } }
723
714
 
724
715
  # And put our new file in place
725
716
  if use_temporary_file # This is only not true when our file is empty.
@@ -778,7 +769,7 @@ Puppet::Type.newtype(:file) do
778
769
  # Make sure we get a new stat objct
779
770
  expire
780
771
  currentvalue = thing.retrieve
781
- thing.sync unless thing.insync?(currentvalue)
772
+ thing.sync unless thing.safe_insync?(currentvalue)
782
773
  end
783
774
  end
784
775
  end
@@ -796,3 +787,5 @@ require 'puppet/type/file/group'
796
787
  require 'puppet/type/file/mode'
797
788
  require 'puppet/type/file/type'
798
789
  require 'puppet/type/file/selcontext' # SELinux file context
790
+ require 'puppet/type/file/ctime'
791
+ require 'puppet/type/file/mtime'
@@ -9,7 +9,7 @@ Puppet::Type.type(:file).newparam(:checksum) do
9
9
 
10
10
  The default checksum parameter, if checksums are enabled, is md5."
11
11
 
12
- newvalues "md5", "md5lite", "timestamp", "mtime", "time", "none"
12
+ newvalues "md5", "md5lite", "mtime", "ctime", "none"
13
13
 
14
14
  defaultto :md5
15
15
 
@@ -96,7 +96,6 @@ module Puppet
96
96
  end
97
97
 
98
98
  return true if ! @resource.replace?
99
- return true unless self.should
100
99
 
101
100
  result = super
102
101
 
@@ -168,6 +167,8 @@ module Puppet
168
167
  def each_chunk_from(source_or_content)
169
168
  if source_or_content.is_a?(String)
170
169
  yield source_or_content
170
+ elsif source_or_content.nil? && resource.parameter(:ensure) && [:present, :file].include?(resource.parameter(:ensure).value)
171
+ yield ''
171
172
  elsif source_or_content.nil?
172
173
  yield read_file_from_filebucket
173
174
  elsif self.class.standalone?