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
@@ -72,17 +72,13 @@ class Puppet::Configurer
72
72
  @splayed = false
73
73
  end
74
74
 
75
- def initialize_report
76
- Puppet::Transaction::Report.new
77
- end
78
-
79
75
  # Prepare for catalog retrieval. Downloads everything necessary, etc.
80
- def prepare
76
+ def prepare(options)
81
77
  dostorage
82
78
 
83
- download_plugins
79
+ download_plugins unless options[:skip_plugin_download]
84
80
 
85
- download_fact_plugins
81
+ download_fact_plugins unless options[:skip_plugin_download]
86
82
 
87
83
  execute_prerun_command
88
84
  end
@@ -126,7 +122,7 @@ class Puppet::Configurer
126
122
  # which accepts :tags and :ignoreschedules.
127
123
  def run(options = {})
128
124
  begin
129
- prepare
125
+ prepare(options)
130
126
  rescue SystemExit,NoMemoryError
131
127
  raise
132
128
  rescue Exception => detail
@@ -134,7 +130,7 @@ class Puppet::Configurer
134
130
  Puppet.err "Failed to prepare catalog: #{detail}"
135
131
  end
136
132
 
137
- options[:report] ||= initialize_report
133
+ options[:report] ||= Puppet::Transaction::Report.new("apply")
138
134
  report = options[:report]
139
135
  Puppet::Util::Log.newdestination(report)
140
136
 
@@ -145,6 +141,8 @@ class Puppet::Configurer
145
141
  return
146
142
  end
147
143
 
144
+ report.configuration_version = catalog.version
145
+
148
146
  transaction = nil
149
147
 
150
148
  begin
@@ -172,8 +170,8 @@ class Puppet::Configurer
172
170
  send_report(report, transaction)
173
171
  end
174
172
 
175
- def send_report(report, trans = nil)
176
- trans.generate_report if trans
173
+ def send_report(report, trans)
174
+ report.finalize_report if trans
177
175
  puts report.summary if Puppet[:summarize]
178
176
  report.save if Puppet[:report]
179
177
  rescue => detail
@@ -19,8 +19,6 @@ module Puppet::Configurer::PluginHandler
19
19
  begin
20
20
  Puppet.info "Loading downloaded plugin #{file}"
21
21
  load file
22
- rescue SystemExit,NoMemoryError
23
- raise
24
22
  rescue Exception => detail
25
23
  Puppet.err "Could not load downloaded file #{file}: #{detail}"
26
24
  end
@@ -2,8 +2,8 @@
2
2
  module Puppet
3
3
  setdefaults(:main,
4
4
  :confdir => [Puppet.run_mode.conf_dir, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process
5
- is running as root or the user that `puppet master` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
6
- it defaults to being in `~`."],
5
+ is running as root or the user that Puppet is supposed to run as, it defaults to a system directory, but if it's running as any other user,
6
+ it defaults to being in the user's home directory."],
7
7
  :vardir => [Puppet.run_mode.var_dir, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."],
8
8
  :name => [Puppet.application_name.to_s, "The name of the application, if we are running as one. The
9
9
  default is essentially $0 without the path or `.rb`."],
@@ -14,7 +14,11 @@ module Puppet
14
14
 
15
15
  setdefaults(:main,
16
16
  :trace => [false, "Whether to print stack traces on some errors"],
17
- :autoflush => [false, "Whether log files should always flush to disk."],
17
+ :autoflush => {
18
+ :default => false,
19
+ :desc => "Whether log files should always flush to disk.",
20
+ :hook => proc { |value| Log.autoflush = value }
21
+ },
18
22
  :syslogfacility => ["daemon", "What syslog facility to use when logging to
19
23
  syslog. Syslog has a fixed list of valid facilities, and you must
20
24
  choose one of those; you cannot just make one up."],
@@ -598,6 +602,11 @@ module Puppet
598
602
  compression, but if it supports it, this setting might reduce performance on high-speed LANs."]
599
603
  )
600
604
 
605
+ setdefaults(:inspect,
606
+ :archive_files => [false, "During an inspect run, whether to archive files whose contents are audited to a file bucket."],
607
+ :archive_file_server => ["$server", "During an inspect run, the file bucket server to archive files to if archive_files is set."]
608
+ )
609
+
601
610
  # Plugin information.
602
611
 
603
612
  setdefaults(
@@ -44,34 +44,13 @@ module PSON
44
44
  string << '' # XXX workaround: avoid buffer sharing
45
45
  string.force_encoding(Encoding::ASCII_8BIT)
46
46
  string.gsub!(/["\\\x0-\x1f]/) { MAP[$MATCH] }
47
- string.gsub!(/(
48
- (?:
49
- [\xc2-\xdf][\x80-\xbf] |
50
- [\xe0-\xef][\x80-\xbf]{2} |
51
- [\xf0-\xf4][\x80-\xbf]{3}
52
- )+ |
53
- [\x80-\xc1\xf5-\xff] # invalid
54
- )/nx) { |c|
55
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
56
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
57
- s.gsub!(/.{4}/n, '\\\\u\&')
58
- }
59
- string.force_encoding(Encoding::UTF_8)
60
47
  string
61
48
  rescue Iconv::Failure => e
62
49
  raise GeneratorError, "Caught #{e.class}: #{e}"
63
50
  end
64
51
  else
65
52
  def utf8_to_pson(string) # :nodoc:
66
- string.
67
- gsub(/["\\\x0-\x1f]/n) { MAP[$MATCH] }.
68
- gsub(/((?:
69
- [\xc2-\xdf][\x80-\xbf] |
70
- [\xe0-\xef][\x80-\xbf]{2} |
71
- [\xf0-\xf4][\x80-\xbf]{3}
72
- )+)/nx) { |c|
73
- PSON::UTF8toUTF16.iconv(c).unpack('H*')[0].gsub(/.{4}/n, '\\\\u\&')
74
- }
53
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$MATCH] }
75
54
  end
76
55
  end
77
56
  module_function :utf8_to_pson
@@ -33,10 +33,16 @@ class Puppet::FileBucket::Dipper
33
33
  raise(ArgumentError, "File #{file} does not exist") unless ::File.exist?(file)
34
34
  contents = ::File.read(file)
35
35
  begin
36
- file_bucket_file = Puppet::FileBucket::File.new(contents, :bucket_path => @local_path, :path => absolutize_path(file) )
37
- dest_path = "#{@rest_path}#{file_bucket_file.name}"
36
+ file_bucket_file = Puppet::FileBucket::File.new(contents, :bucket_path => @local_path)
37
+ files_original_path = absolutize_path(file)
38
+ dest_path = "#{@rest_path}#{file_bucket_file.name}#{files_original_path}"
39
+
40
+ # Make a HEAD request for the file so that we don't waste time
41
+ # uploading it if it already exists in the bucket.
42
+ unless Puppet::FileBucket::File.head("#{@rest_path}#{file_bucket_file.checksum_type}/#{file_bucket_file.checksum_data}#{files_original_path}")
43
+ file_bucket_file.save(dest_path)
44
+ end
38
45
 
39
- file_bucket_file.save(dest_path)
40
46
  return file_bucket_file.checksum_data
41
47
  rescue => detail
42
48
  puts detail.backtrace if Puppet[:trace]
@@ -1,10 +1,9 @@
1
1
  require 'puppet/file_bucket'
2
2
  require 'puppet/indirector'
3
3
  require 'puppet/util/checksums'
4
+ require 'digest/md5'
4
5
 
5
6
  class Puppet::FileBucket::File
6
- include Puppet::Util::Checksums
7
-
8
7
  # This class handles the abstract notion of a file in a filebucket.
9
8
  # There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
10
9
  # There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
@@ -12,71 +11,27 @@ class Puppet::FileBucket::File
12
11
  require 'puppet/file_bucket/file/indirection_hooks'
13
12
  indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
14
13
 
15
- attr :path, true
16
- attr :paths, true
17
- attr :contents, true
18
- attr :checksum_type
19
- attr :bucket_path, true
20
-
21
- def self.default_checksum_type
22
- "md5"
23
- end
14
+ attr :contents
15
+ attr :bucket_path
24
16
 
25
17
  def initialize( contents, options = {} )
26
- @bucket_path = options[:bucket_path]
27
- @path = options[:path]
28
- @paths = options[:paths] || []
29
-
30
- @checksum = options[:checksum]
31
- @checksum_type = options[:checksum_type]
32
-
33
- self.contents = contents
34
-
35
- yield(self) if block_given?
36
-
37
- validate!
38
- end
18
+ raise ArgumentError if !contents.is_a?(String)
19
+ @contents = contents
39
20
 
40
- def validate!
41
- validate_checksum_type!(checksum_type)
42
- validate_checksum!(checksum) if checksum
21
+ @bucket_path = options.delete(:bucket_path)
22
+ raise ArgumentError if options != {}
43
23
  end
44
24
 
45
- def contents=(str)
46
- raise "You may not change the contents of a FileBucket File" if @contents
47
- validate_content!(str)
48
- @contents = str
25
+ def checksum_type
26
+ 'md5'
49
27
  end
50
28
 
51
29
  def checksum
52
- return @checksum if @checksum
53
- @checksum = calculate_checksum if contents
54
- @checksum
55
- end
56
-
57
- def checksum=(checksum)
58
- validate_checksum!(checksum)
59
- @checksum = checksum
60
- end
61
-
62
- def checksum_type=( new_checksum_type )
63
- @checksum = nil
64
- @checksum_type = new_checksum_type
65
- end
66
-
67
- def checksum_type
68
- unless @checksum_type
69
- if @checksum
70
- @checksum_type = sumtype(checksum)
71
- else
72
- @checksum_type = self.class.default_checksum_type
73
- end
74
- end
75
- @checksum_type
30
+ "{#{checksum_type}}#{checksum_data}"
76
31
  end
77
32
 
78
33
  def checksum_data
79
- sumdata(checksum)
34
+ @checksum_data ||= Digest::MD5.hexdigest(contents)
80
35
  end
81
36
 
82
37
  def to_s
@@ -84,18 +39,7 @@ class Puppet::FileBucket::File
84
39
  end
85
40
 
86
41
  def name
87
- [checksum_type, checksum_data, path].compact.join('/')
88
- end
89
-
90
- def name=(name)
91
- data = name.split('/',3)
92
- self.path = data.pop
93
- @checksum_type = nil
94
- self.checksum = "{#{data[0]}}#{data[1]}"
95
- end
96
-
97
- def conflict_check?
98
- true
42
+ "#{checksum_type}/#{checksum_data}"
99
43
  end
100
44
 
101
45
  def self.from_s( contents )
@@ -103,34 +47,10 @@ class Puppet::FileBucket::File
103
47
  end
104
48
 
105
49
  def to_pson
106
- hash = { "contents" => contents }
107
- hash["path"] = @path if @path
108
- hash.to_pson
50
+ { "contents" => contents }.to_pson
109
51
  end
110
52
 
111
53
  def self.from_pson( pson )
112
- self.new( pson["contents"], :path => pson["path"] )
113
- end
114
-
115
- private
116
-
117
- def calculate_checksum
118
- "{#{checksum_type}}" + send(checksum_type, contents)
119
- end
120
-
121
- def validate_content!(content)
122
- raise ArgumentError, "Contents must be a string" if content and ! content.is_a?(String)
123
- end
124
-
125
- def validate_checksum!(new_checksum)
126
- newtype = sumtype(new_checksum)
127
-
128
- unless sumdata(new_checksum) == (calc_sum = send(newtype, contents))
129
- raise Puppet::Error, "Checksum #{new_checksum} does not match contents #{calc_sum}"
130
- end
131
- end
132
-
133
- def validate_checksum_type!(type)
134
- raise ArgumentError, "Invalid checksum type #{type}" unless respond_to?(type)
54
+ self.new( pson["contents"] )
135
55
  end
136
56
  end
@@ -50,6 +50,10 @@ module Puppet::Indirector
50
50
  indirection.find(*args)
51
51
  end
52
52
 
53
+ def head(*args)
54
+ indirection.head(*args)
55
+ end
56
+
53
57
  def destroy(*args)
54
58
  indirection.destroy(*args)
55
59
  end
@@ -32,7 +32,7 @@ class Puppet::Resource::Catalog::ActiveRecord < Puppet::Indirector::ActiveRecord
32
32
 
33
33
  if node = Puppet::Node.find(catalog.name)
34
34
  host.ip = node.parameters["ipaddress"]
35
- host.environment = node.environment
35
+ host.environment = node.environment.to_s
36
36
  end
37
37
 
38
38
  host.save
@@ -14,83 +14,102 @@ module Puppet::FileBucketFile
14
14
  end
15
15
 
16
16
  def find( request )
17
- checksum, path = request_to_checksum_and_path( request )
18
- find_by_checksum( checksum, request.options )
17
+ checksum, files_original_path = request_to_checksum_and_path( request )
18
+ dir_path = path_for(request.options[:bucket_path], checksum)
19
+ file_path = ::File.join(dir_path, 'contents')
20
+
21
+ return nil unless ::File.exists?(file_path)
22
+ return nil unless path_match(dir_path, files_original_path)
23
+
24
+ if request.options[:diff_with]
25
+ hash_protocol = sumtype(checksum)
26
+ file2_path = path_for(request.options[:bucket_path], request.options[:diff_with], 'contents')
27
+ raise "could not find diff_with #{request.options[:diff_with]}" unless ::File.exists?(file2_path)
28
+ return `diff #{file_path.inspect} #{file2_path.inspect}`
29
+ else
30
+ contents = ::File.read file_path
31
+ Puppet.info "FileBucket read #{checksum}"
32
+ model.new(contents)
33
+ end
19
34
  end
20
35
 
21
- def save( request )
22
- checksum, path = request_to_checksum_and_path( request )
36
+ def head(request)
37
+ checksum, files_original_path = request_to_checksum_and_path(request)
38
+ dir_path = path_for(request.options[:bucket_path], checksum)
39
+
40
+ ::File.exists?(::File.join(dir_path, 'contents')) and path_match(dir_path, files_original_path)
41
+ end
23
42
 
43
+ def save( request )
24
44
  instance = request.instance
25
- instance.checksum = checksum if checksum
26
- instance.path = path if path
45
+ checksum, files_original_path = request_to_checksum_and_path(request)
27
46
 
28
- save_to_disk(instance)
47
+ save_to_disk(instance, files_original_path)
29
48
  instance.to_s
30
49
  end
31
50
 
32
51
  private
33
52
 
34
- def find_by_checksum( checksum, options )
35
- model.new( nil, :checksum => checksum ) do |bucket_file|
36
- bucket_file.bucket_path = options[:bucket_path]
37
- filename = contents_path_for( bucket_file )
38
-
39
- return nil if ! ::File.exist? filename
40
-
41
- begin
42
- contents = ::File.read filename
43
- Puppet.info "FileBucket read #{bucket_file.checksum}"
44
- rescue RuntimeError => e
45
- raise Puppet::Error, "file could not be read: #{e.message}"
53
+ def path_match(dir_path, files_original_path)
54
+ return true unless files_original_path # if no path was provided, it's a match
55
+ paths_path = ::File.join(dir_path, 'paths')
56
+ return false unless ::File.exists?(paths_path)
57
+ ::File.open(paths_path) do |f|
58
+ f.each do |line|
59
+ return true if line.chomp == files_original_path
46
60
  end
47
-
48
- if ::File.exist?(paths_path_for( bucket_file) )
49
- ::File.open(paths_path_for( bucket_file) ) do |f|
50
- bucket_file.paths = f.readlines.map { |l| l.chomp }
51
- end
52
- end
53
-
54
- bucket_file.contents = contents
55
61
  end
62
+ return false
56
63
  end
57
64
 
58
- def save_to_disk( bucket_file )
59
- # If the file already exists, just return the md5 sum.
60
- if ::File.exist?(contents_path_for( bucket_file) )
65
+ def save_to_disk( bucket_file, files_original_path )
66
+ filename = path_for(bucket_file.bucket_path, bucket_file.checksum_data, 'contents')
67
+ dir_path = path_for(bucket_file.bucket_path, bucket_file.checksum_data)
68
+ paths_path = ::File.join(dir_path, 'paths')
69
+
70
+ # If the file already exists, do nothing.
71
+ if ::File.exist?(filename)
61
72
  verify_identical_file!(bucket_file)
62
73
  else
63
74
  # Make the directories if necessary.
64
- unless ::File.directory?( path_for( bucket_file) )
75
+ unless ::File.directory?(dir_path)
65
76
  Puppet::Util.withumask(0007) do
66
- ::FileUtils.mkdir_p( path_for( bucket_file) )
77
+ ::FileUtils.mkdir_p(dir_path)
67
78
  end
68
79
  end
69
80
 
70
- Puppet.info "FileBucket adding #{bucket_file.path} as #{bucket_file.checksum}"
81
+ Puppet.info "FileBucket adding #{bucket_file.checksum}"
71
82
 
72
83
  # Write the file to disk.
73
84
  Puppet::Util.withumask(0007) do
74
- ::File.open(contents_path_for(bucket_file), ::File::WRONLY|::File::CREAT, 0440) do |of|
85
+ ::File.open(filename, ::File::WRONLY|::File::CREAT, 0440) do |of|
75
86
  of.print bucket_file.contents
76
87
  end
88
+ ::File.open(paths_path, ::File::WRONLY|::File::CREAT, 0640) do |of|
89
+ # path will be written below
90
+ end
77
91
  end
78
92
  end
79
93
 
80
- save_path_to_paths_file(bucket_file)
81
- bucket_file.checksum_data
94
+ unless path_match(dir_path, files_original_path)
95
+ ::File.open(paths_path, 'a') do |f|
96
+ f.puts(files_original_path)
97
+ end
98
+ end
82
99
  end
83
100
 
84
101
  def request_to_checksum_and_path( request )
85
- return [request.key, nil] if checksum?(request.key)
86
-
87
102
  checksum_type, checksum, path = request.key.split(/\//, 3)
88
- return(checksum_type.to_s == "" ? nil : [ "{#{checksum_type}}#{checksum}", path ])
103
+ if path == '' # Treat "md5/<checksum>/" like "md5/<checksum>"
104
+ path = nil
105
+ end
106
+ raise "Unsupported checksum type #{checksum_type.inspect}" if checksum_type != 'md5'
107
+ raise "Invalid checksum #{checksum.inspect}" if checksum !~ /^[0-9a-f]{32}$/
108
+ [checksum, path]
89
109
  end
90
110
 
91
- def path_for(bucket_file, subfile = nil)
92
- bucket_path = bucket_file.bucket_path || Puppet[:bucketdir]
93
- digest = bucket_file.checksum_data
111
+ def path_for(bucket_path, digest, subfile = nil)
112
+ bucket_path ||= Puppet[:bucketdir]
94
113
 
95
114
  dir = ::File.join(digest[0..7].split(""))
96
115
  basedir = ::File.join(bucket_path, dir, digest)
@@ -99,48 +118,18 @@ module Puppet::FileBucketFile
99
118
  ::File.join(basedir, subfile)
100
119
  end
101
120
 
102
- def contents_path_for(bucket_file)
103
- path_for(bucket_file, "contents")
104
- end
105
-
106
- def paths_path_for(bucket_file)
107
- path_for(bucket_file, "paths")
108
- end
109
-
110
- def content_check?
111
- true
112
- end
113
-
114
121
  # If conflict_check is enabled, verify that the passed text is
115
122
  # the same as the text in our file.
116
123
  def verify_identical_file!(bucket_file)
117
- return unless content_check?
118
- disk_contents = ::File.read(contents_path_for(bucket_file))
124
+ disk_contents = ::File.read(path_for(bucket_file.bucket_path, bucket_file.checksum_data, 'contents'))
119
125
 
120
126
  # If the contents don't match, then we've found a conflict.
121
127
  # Unlikely, but quite bad.
122
128
  if disk_contents != bucket_file.contents
123
- raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}", caller
129
+ raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}"
124
130
  else
125
- Puppet.info "FileBucket got a duplicate file #{bucket_file.path} (#{bucket_file.checksum})"
131
+ Puppet.info "FileBucket got a duplicate file #{bucket_file.checksum}"
126
132
  end
127
133
  end
128
-
129
- def save_path_to_paths_file(bucket_file)
130
- return unless bucket_file.path
131
-
132
- # check for dupes
133
- if ::File.exist?(paths_path_for( bucket_file) )
134
- ::File.open(paths_path_for( bucket_file) ) do |f|
135
- return if f.readlines.collect { |l| l.chomp }.include?(bucket_file.path)
136
- end
137
- end
138
-
139
- # if it's a new file, or if our path isn't in the file yet, add it
140
- ::File.open(paths_path_for(bucket_file), ::File::WRONLY|::File::CREAT|::File::APPEND) do |of|
141
- of.puts bucket_file.path
142
- end
143
- end
144
-
145
134
  end
146
135
  end