chef 0.10.8 → 0.10.10.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. data/distro/arch/etc/rc.d/chef-client +15 -1
  2. data/distro/common/html/chef-client.8.html +4 -4
  3. data/distro/common/html/chef-expander.8.html +4 -4
  4. data/distro/common/html/chef-expanderctl.8.html +4 -4
  5. data/distro/common/html/chef-server-webui.8.html +4 -4
  6. data/distro/common/html/chef-server.8.html +4 -4
  7. data/distro/common/html/chef-solo.8.html +4 -4
  8. data/distro/common/html/chef-solr.8.html +4 -4
  9. data/distro/common/html/knife-bootstrap.1.html +6 -10
  10. data/distro/common/html/knife-client.1.html +4 -4
  11. data/distro/common/html/knife-configure.1.html +4 -4
  12. data/distro/common/html/knife-cookbook-site.1.html +6 -6
  13. data/distro/common/html/knife-cookbook.1.html +4 -4
  14. data/distro/common/html/knife-data-bag.1.html +4 -4
  15. data/distro/common/html/knife-environment.1.html +4 -4
  16. data/distro/common/html/knife-exec.1.html +4 -4
  17. data/distro/common/html/knife-index.1.html +4 -4
  18. data/distro/common/html/knife-node.1.html +5 -5
  19. data/distro/common/html/knife-role.1.html +4 -4
  20. data/distro/common/html/knife-search.1.html +4 -4
  21. data/distro/common/html/knife-ssh.1.html +5 -6
  22. data/distro/common/html/knife-status.1.html +4 -4
  23. data/distro/common/html/knife-tag.1.html +4 -4
  24. data/distro/common/html/knife.1.html +7 -8
  25. data/distro/common/html/shef.1.html +4 -4
  26. data/distro/common/man/man1/knife-bootstrap.1 +4 -4
  27. data/distro/common/man/man1/knife-client.1 +1 -1
  28. data/distro/common/man/man1/knife-configure.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook-site.1 +4 -4
  30. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  31. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  32. data/distro/common/man/man1/knife-environment.1 +1 -1
  33. data/distro/common/man/man1/knife-exec.1 +1 -1
  34. data/distro/common/man/man1/knife-index.1 +1 -1
  35. data/distro/common/man/man1/knife-node.1 +2 -2
  36. data/distro/common/man/man1/knife-role.1 +1 -1
  37. data/distro/common/man/man1/knife-search.1 +1 -1
  38. data/distro/common/man/man1/knife-ssh.1 +3 -7
  39. data/distro/common/man/man1/knife-status.1 +1 -1
  40. data/distro/common/man/man1/knife-tag.1 +1 -1
  41. data/distro/common/man/man1/knife.1 +5 -9
  42. data/distro/common/man/man1/shef.1 +1 -1
  43. data/distro/common/man/man8/chef-client.8 +1 -1
  44. data/distro/common/man/man8/chef-expander.8 +1 -1
  45. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  46. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  47. data/distro/common/man/man8/chef-server.8 +1 -1
  48. data/distro/common/man/man8/chef-solo.8 +1 -1
  49. data/distro/common/man/man8/chef-solr.8 +1 -1
  50. data/distro/common/markdown/man1/knife-bootstrap.mkd +3 -7
  51. data/distro/common/markdown/man1/knife-cookbook-site.mkd +3 -3
  52. data/distro/common/markdown/man1/knife-node.mkd +2 -2
  53. data/distro/common/markdown/man1/knife-ssh.mkd +2 -5
  54. data/distro/common/markdown/man1/knife.mkd +7 -9
  55. data/distro/debian/etc/init.d/chef-client +22 -1
  56. data/distro/redhat/etc/init.d/chef-client +12 -1
  57. data/distro/windows/service_manager.rb +164 -0
  58. data/lib/chef/application.rb +12 -6
  59. data/lib/chef/application/client.rb +4 -3
  60. data/lib/chef/application/knife.rb +7 -12
  61. data/lib/chef/application/solo.rb +2 -1
  62. data/lib/chef/application/windows_service.rb +224 -0
  63. data/lib/chef/checksum_cache.rb +1 -0
  64. data/lib/chef/client.rb +3 -16
  65. data/lib/chef/config.rb +42 -13
  66. data/lib/chef/cookbook/metadata.rb +1 -1
  67. data/lib/chef/cookbook/syntax_check.rb +2 -2
  68. data/lib/chef/cookbook_version.rb +5 -0
  69. data/lib/chef/daemon.rb +1 -1
  70. data/lib/chef/exceptions.rb +7 -1
  71. data/lib/chef/file_access_control.rb +13 -87
  72. data/lib/chef/file_access_control/unix.rb +119 -0
  73. data/lib/chef/file_access_control/windows.rb +257 -0
  74. data/lib/chef/handler/json_file.rb +7 -1
  75. data/lib/chef/knife.rb +10 -16
  76. data/lib/chef/knife/bootstrap.rb +15 -8
  77. data/lib/chef/knife/bootstrap/centos5-gems.erb +1 -1
  78. data/lib/chef/knife/bootstrap/chef-full.erb +59 -0
  79. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +1 -0
  80. data/lib/chef/knife/configure.rb +2 -2
  81. data/lib/chef/knife/cookbook_site_download.rb +60 -21
  82. data/lib/chef/knife/cookbook_site_install.rb +16 -21
  83. data/lib/chef/knife/cookbook_upload.rb +77 -48
  84. data/lib/chef/knife/core/bootstrap_context.rb +3 -1
  85. data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
  86. data/lib/chef/knife/core/node_editor.rb +1 -1
  87. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  88. data/lib/chef/knife/core/ui.rb +3 -2
  89. data/lib/chef/knife/help_topics.rb +1 -1
  90. data/lib/chef/knife/node_run_list_add.rb +14 -6
  91. data/lib/chef/knife/node_run_list_remove.rb +3 -3
  92. data/lib/chef/knife/ssh.rb +32 -13
  93. data/lib/chef/mash.rb +14 -0
  94. data/lib/chef/mixin/command.rb +1 -0
  95. data/lib/chef/mixin/command/unix.rb +5 -0
  96. data/lib/chef/mixin/convert_to_class_name.rb +2 -0
  97. data/lib/chef/mixin/deep_merge.rb +40 -18
  98. data/lib/chef/mixin/enforce_ownership_and_permissions.rb +39 -0
  99. data/lib/chef/mixin/language.rb +89 -3
  100. data/lib/chef/mixin/language_include_recipe.rb +8 -4
  101. data/lib/chef/mixin/path_sanity.rb +67 -0
  102. data/lib/chef/mixin/recipe_definition_dsl_core.rb +19 -11
  103. data/lib/chef/mixin/securable.rb +152 -0
  104. data/lib/chef/mixin/shell_out.rb +1 -1
  105. data/lib/chef/mixin/template.rb +8 -3
  106. data/lib/chef/mixins.rb +3 -0
  107. data/lib/chef/monkey_patches/moneta.rb +50 -0
  108. data/lib/chef/monkey_patches/string.rb +1 -1
  109. data/lib/chef/node.rb +2 -1
  110. data/lib/chef/platform.rb +34 -0
  111. data/lib/chef/provider.rb +23 -21
  112. data/lib/chef/provider/cron.rb +17 -12
  113. data/lib/chef/provider/cron/solaris.rb +6 -18
  114. data/lib/chef/provider/deploy.rb +14 -15
  115. data/lib/chef/provider/deploy/timestamped.rb +0 -1
  116. data/lib/chef/provider/directory.rb +1 -3
  117. data/lib/chef/provider/execute.rb +2 -2
  118. data/lib/chef/provider/file.rb +1 -75
  119. data/lib/chef/provider/git.rb +11 -9
  120. data/lib/chef/provider/group/gpasswd.rb +14 -9
  121. data/lib/chef/provider/link.rb +28 -59
  122. data/lib/chef/provider/mdadm.rb +2 -2
  123. data/lib/chef/provider/mount/mount.rb +1 -1
  124. data/lib/chef/provider/package.rb +10 -6
  125. data/lib/chef/provider/package/apt.rb +3 -1
  126. data/lib/chef/provider/package/dpkg.rb +1 -1
  127. data/lib/chef/provider/package/portage.rb +6 -3
  128. data/lib/chef/provider/package/rubygems.rb +75 -6
  129. data/lib/chef/provider/package/smartos.rb +84 -0
  130. data/lib/chef/provider/package/yum-dump.py +3 -2
  131. data/lib/chef/provider/package/yum.rb +51 -10
  132. data/lib/chef/provider/remote_directory.rb +24 -3
  133. data/lib/chef/provider/remote_file.rb +0 -6
  134. data/lib/chef/provider/route.rb +3 -3
  135. data/lib/chef/provider/service/debian.rb +2 -2
  136. data/lib/chef/provider/service/freebsd.rb +1 -1
  137. data/lib/chef/provider/service/macosx.rb +125 -0
  138. data/lib/chef/provider/service/windows.rb +5 -1
  139. data/lib/chef/provider/subversion.rb +10 -7
  140. data/lib/chef/providers.rb +3 -0
  141. data/lib/chef/resource.rb +181 -87
  142. data/lib/chef/resource/apt_package.rb +10 -1
  143. data/lib/chef/resource/chef_gem.rb +53 -0
  144. data/lib/chef/resource/conditional.rb +3 -0
  145. data/lib/chef/resource/cookbook_file.rb +12 -6
  146. data/lib/chef/resource/cron.rb +9 -0
  147. data/lib/chef/resource/directory.rb +14 -31
  148. data/lib/chef/resource/execute.rb +11 -9
  149. data/lib/chef/resource/file.rb +9 -33
  150. data/lib/chef/resource/link.rb +13 -8
  151. data/lib/chef/resource/mdadm.rb +10 -1
  152. data/lib/chef/resource/remote_directory.rb +13 -2
  153. data/lib/chef/resource/remote_file.rb +14 -7
  154. data/lib/chef/resource/smartos_package.rb +36 -0
  155. data/lib/chef/resource/template.rb +12 -5
  156. data/lib/chef/resource_platform_map.rb +153 -0
  157. data/lib/chef/resources.rb +2 -0
  158. data/lib/chef/rest.rb +55 -10
  159. data/lib/chef/rest/auth_credentials.rb +1 -0
  160. data/lib/chef/rest/rest_request.rb +24 -8
  161. data/lib/chef/role.rb +8 -2
  162. data/lib/chef/run_list.rb +1 -1
  163. data/lib/chef/run_list/run_list_expansion.rb +2 -2
  164. data/lib/chef/run_list/run_list_item.rb +7 -0
  165. data/lib/chef/runner.rb +4 -0
  166. data/lib/chef/shef.rb +2 -2
  167. data/lib/chef/shef/shef_session.rb +4 -5
  168. data/lib/chef/shell_out.rb +2 -245
  169. data/lib/chef/util/file_edit.rb +99 -89
  170. data/lib/chef/version.rb +1 -1
  171. data/lib/chef/win32/api.rb +349 -0
  172. data/lib/chef/win32/api/error.rb +921 -0
  173. data/lib/chef/win32/api/file.rb +289 -0
  174. data/lib/chef/win32/api/memory.rb +105 -0
  175. data/lib/chef/win32/api/process.rb +40 -0
  176. data/lib/chef/win32/api/psapi.rb +51 -0
  177. data/lib/chef/win32/api/security.rb +341 -0
  178. data/lib/chef/win32/api/system.rb +192 -0
  179. data/lib/chef/win32/api/unicode.rb +178 -0
  180. data/lib/chef/win32/error.rb +73 -0
  181. data/lib/chef/win32/file.rb +117 -0
  182. data/lib/chef/win32/file/info.rb +100 -0
  183. data/lib/chef/win32/handle.rb +48 -0
  184. data/lib/chef/win32/memory.rb +101 -0
  185. data/lib/chef/win32/process.rb +84 -0
  186. data/lib/chef/win32/security.rb +489 -0
  187. data/lib/chef/win32/security/ace.rb +125 -0
  188. data/lib/chef/win32/security/acl.rb +101 -0
  189. data/lib/chef/win32/security/securable_object.rb +109 -0
  190. data/lib/chef/win32/security/security_descriptor.rb +93 -0
  191. data/lib/chef/win32/security/sid.rb +199 -0
  192. data/lib/chef/win32/security/token.rb +64 -0
  193. data/lib/chef/win32/unicode.rb +43 -0
  194. data/lib/chef/win32/version.rb +119 -0
  195. metadata +104 -158
  196. data/lib/chef/shell_out/unix.rb +0 -223
  197. data/lib/chef/shell_out/windows.rb +0 -588
@@ -25,7 +25,7 @@ class Chef
25
25
  class Provider
26
26
  class Package
27
27
  class Dpkg < Chef::Provider::Package::Apt
28
- DPKG_INFO = /([a-z\d\-\+]+)\t([\w\d.~-]+)/
28
+ DPKG_INFO = /([a-z\d\-\+\.]+)\t([\w\d.~-]+)/
29
29
  DPKG_INSTALLED = /^Status: install ok installed/
30
30
  DPKG_VERSION = /^Version: (.+)$/
31
31
 
@@ -24,7 +24,7 @@ class Chef
24
24
  class Provider
25
25
  class Package
26
26
  class Portage < Chef::Provider::Package
27
- PACKAGE_NAME_PATTERN = %r{(([^/]+)/)?([^/]+)}
27
+ PACKAGE_NAME_PATTERN = %r{(?:([^/]+)/)?([^/]+)}
28
28
 
29
29
  def load_current_resource
30
30
  @current_resource = Chef::Resource::Package.new(@new_resource.name)
@@ -32,7 +32,7 @@ class Chef
32
32
 
33
33
  @current_resource.version(nil)
34
34
 
35
- _, category_with_slash, category, pkg = %r{^#{PACKAGE_NAME_PATTERN}$}.match(@new_resource.package_name).to_a
35
+ category, pkg = %r{^#{PACKAGE_NAME_PATTERN}$}.match(@new_resource.package_name)[1,2]
36
36
 
37
37
  possibilities = Dir["/var/db/pkg/#{category || "*"}/#{pkg}-*"].map {|d| d.sub(%r{/var/db/pkg/}, "") }
38
38
  versions = possibilities.map do |entry|
@@ -43,7 +43,10 @@ class Chef
43
43
 
44
44
  if versions.size > 1
45
45
  atoms = versions.map {|v| v.first }.sort
46
- raise Chef::Exceptions::Package, "Multiple packages found for #{@new_resource.package_name}: #{atoms.join(" ")}. Specify a category."
46
+ categories = atoms.map {|v| v.split('/')[0] }.uniq
47
+ if !category && categories.size > 1
48
+ raise Chef::Exceptions::Package, "Multiple packages found for #{@new_resource.package_name}: #{atoms.join(" ")}. Specify a category."
49
+ end
47
50
  elsif versions.size == 1
48
51
  @current_resource.version(versions.first.last)
49
52
  Chef::Log.debug("#{@new_resource} current version #{$1}")
@@ -65,6 +65,17 @@ class Chef
65
65
  raise NotImplementedError
66
66
  end
67
67
 
68
+ ##
69
+ # A rubygems specification object containing the list of gemspecs for all
70
+ # available gems in the gem installation.
71
+ # Implemented by subclasses
72
+ # For rubygems >= 1.8.0
73
+ # === Returns
74
+ # Gem::Specification
75
+ def gem_specification
76
+ raise NotImplementedError
77
+ end
78
+
68
79
  ##
69
80
  # Lists the installed versions of +gem_name+, constrained by the
70
81
  # version spec in +gem_dep+
@@ -74,7 +85,11 @@ class Chef
74
85
  # === Returns
75
86
  # [Gem::Specification] an array of Gem::Specification objects
76
87
  def installed_versions(gem_dep)
77
- gem_source_index.search(gem_dep)
88
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
89
+ gem_specification.find_all_by_name(gem_dep.name, gem_dep)
90
+ else
91
+ gem_source_index.search(gem_dep)
92
+ end
78
93
  end
79
94
 
80
95
  ##
@@ -203,6 +218,10 @@ class Chef
203
218
  Gem.source_index
204
219
  end
205
220
 
221
+ def gem_specification
222
+ Gem::Specification
223
+ end
224
+
206
225
  def candidate_version_from_remote(gem_dependency, *sources)
207
226
  with_gem_sources(*sources) do
208
227
  find_newest_remote_version(gem_dependency, *sources)
@@ -213,7 +232,7 @@ class Chef
213
232
 
214
233
  class AlternateGemEnvironment < GemEnvironment
215
234
  JRUBY_PLATFORM = /(:?universal|x86_64|x86)\-java\-[0-9\.]+/
216
-
235
+
217
236
  def self.gempath_cache
218
237
  @gempath_cache ||= {}
219
238
  end
@@ -246,6 +265,15 @@ class Chef
246
265
  @source_index ||= Gem::SourceIndex.from_gems_in(*gem_paths.map { |p| p + '/specifications' })
247
266
  end
248
267
 
268
+ def gem_specification
269
+ # Only once, dirs calls a reset
270
+ unless @specification
271
+ Gem::Specification.dirs = gem_paths
272
+ @specification = Gem::Specification
273
+ end
274
+ @specification
275
+ end
276
+
249
277
  ##
250
278
  # Attempt to detect the correct platform settings for the target gem
251
279
  # environment.
@@ -311,18 +339,51 @@ class Chef
311
339
  raise ArgumentError, msg
312
340
  end
313
341
  @gem_env = AlternateGemEnvironment.new(new_resource.gem_binary)
342
+ Chef::Log.debug("#{@new_resource} using gem '#{new_resource.gem_binary}'")
343
+ elsif is_omnibus? && (!@new_resource.instance_of? Chef::Resource::ChefGem)
344
+ # Opscode Omnibus - The ruby that ships inside omnibus is only used for Chef
345
+ # Default to installing somewhere more functional
346
+ gem_location = find_gem_by_path
347
+ @gem_env = AlternateGemEnvironment.new(gem_location)
348
+ Chef::Log.debug("#{@new_resource} using gem '#{gem_location}'")
314
349
  else
315
350
  @gem_env = CurrentGemEnvironment.new
351
+ Chef::Log.debug("#{@new_resource} using gem from running ruby environment")
352
+ end
353
+ end
354
+
355
+ def is_omnibus?
356
+ if RbConfig::CONFIG['bindir'] == "/opt/opscode/embedded/bin"
357
+ Chef::Log.debug("#{@new_resource} detected omnibus installation in #{RbConfig::CONFIG['bindir']}")
358
+ # Omnibus installs to a static path because of linking on unix, find it.
359
+ true
360
+ elsif RbConfig::CONFIG['bindir'].sub(/^[\w]:/, '') == "/opscode/chef/embedded/bin"
361
+ Chef::Log.debug("#{@new_resource} detected omnibus installation in #{RbConfig::CONFIG['bindir']}")
362
+ # windows, with the drive letter removed
363
+ true
364
+ else
365
+ false
316
366
  end
317
367
  end
318
368
 
369
+ def find_gem_by_path
370
+ Chef::Log.debug("#{@new_resource} searching for 'gem' binary in path: #{ENV['PATH']}")
371
+ separator = ::File::ALT_SEPARATOR ? ::File::ALT_SEPARATOR : ::File::SEPARATOR
372
+ path_to_first_gem = ENV['PATH'].split(::File::PATH_SEPARATOR).select { |path| ::File.exists?(path + separator + "gem") }.first
373
+ raise Chef::Exceptions::FileNotFound, "Unable to find 'gem' binary in path: #{ENV['PATH']}" if path_to_first_gem.nil?
374
+ path_to_first_gem + separator + "gem"
375
+ end
376
+
319
377
  def gem_dependency
320
378
  Gem::Dependency.new(@new_resource.package_name, @new_resource.version)
321
379
  end
322
380
 
323
381
  def source_is_remote?
324
382
  return true if @new_resource.source.nil?
325
- URI.parse(@new_resource.source).absolute?
383
+ scheme = URI.parse(@new_resource.source).scheme
384
+ # URI.parse gets confused by MS Windows paths with forward slashes.
385
+ scheme = nil if scheme =~ /^[a-z]$/
386
+ %w{http https}.include?(scheme)
326
387
  end
327
388
 
328
389
  def current_version
@@ -384,7 +445,7 @@ class Chef
384
445
  return false unless @current_resource && @current_resource.version
385
446
  return false if @current_resource.version.nil?
386
447
  # in the future we could support squiggly requirements like "~> 1.2.0"
387
- # for now, the behavior when using anything other than exact
448
+ # for now, the behavior when using anything other than exact
388
449
  # requirements is undefined.
389
450
  Gem::Requirement.new(@new_resource.version).satisfied_by?(Gem::Version.new(@current_resource.version))
390
451
  end
@@ -419,8 +480,16 @@ class Chef
419
480
  end
420
481
 
421
482
  def install_via_gem_command(name, version)
422
- src = @new_resource.source && " --source=#{@new_resource.source} --source=http://rubygems.org"
423
- shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
483
+ if @new_resource.source =~ /\.gem$/i
484
+ name = @new_resource.source
485
+ else
486
+ src = @new_resource.source && " --source=#{@new_resource.source} --source=http://rubygems.org"
487
+ end
488
+ if version
489
+ shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
490
+ else
491
+ shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri #{src}#{opts}", :env=>nil)
492
+ end
424
493
  end
425
494
 
426
495
  def upgrade_package(name, version)
@@ -0,0 +1,84 @@
1
+ #
2
+ # Authors:: Trevor O (trevoro@joyent.com)
3
+ # Bryan McLellan (btm@loftninjas.org)
4
+ # Matthew Landauer (matthew@openaustralia.org)
5
+ # Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Notes
21
+ #
22
+ # * Supports installing using a local package name
23
+ # * Otherwise reverts to installing from the pkgsrc repositories URL
24
+
25
+ require 'chef/provider/package'
26
+ require 'chef/mixin/shell_out'
27
+ require 'chef/resource/package'
28
+ require 'chef/mixin/get_source_from_package'
29
+
30
+ class Chef
31
+ class Provider
32
+ class Package
33
+ class SmartOS < Chef::Provider::Package
34
+ include Chef::Mixin::ShellOut
35
+ attr_accessor :is_virtual_package
36
+
37
+
38
+ def load_current_resource
39
+ Chef::Log.debug("#{@new_resource} loading current resource")
40
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
41
+ @current_resource.package_name(@new_resource.package_name)
42
+ @current_resource.version(nil)
43
+ check_package_state(@new_resource.package_name)
44
+ @current_resource # modified by check_package_state
45
+ end
46
+
47
+ def check_package_state(name)
48
+ Chef::Log.debug("#{@new_resource} checking package #{name}")
49
+ # XXX
50
+ version = nil
51
+ info = shell_out!("pkg_info -E \"#{name}*\"", :env => nil, :returns => [0,1])
52
+
53
+ if info.stdout
54
+ version = info.stdout[/^#{@new_resource.package_name}-(.+)/, 1]
55
+ end
56
+
57
+ if !version
58
+ @current_resource.version(nil)
59
+ else
60
+ @current_resource.version(version)
61
+ end
62
+ end
63
+
64
+ def install_package(name, version)
65
+ Chef::Log.debug("#{@new_resource} installing package #{name}-#{version}")
66
+ package = "#{name}-#{version}"
67
+ out = shell_out!("pkgin -y install #{package}", :env => nil)
68
+ end
69
+
70
+ def upgrade_package(name, version)
71
+ Chef::Log.debug("#{@new_resource} upgrading package #{name}-#{version}")
72
+ install_package(name, version)
73
+ end
74
+
75
+ def remove_package(name, version)
76
+ Chef::Log.debug("#{@new_resource} removing package #{name}-#{version}")
77
+ package = "#{name}-#{version}"
78
+ out = shell_out!("pkgin -y remove #{package}", :env => nil)
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -180,14 +180,15 @@ def dump_packages(yb, list, output_provides):
180
180
  else:
181
181
  provides = "[]"
182
182
 
183
- print '%s %s %s %s %s %s %s' % (
183
+ print '%s %s %s %s %s %s %s %s' % (
184
184
  pkg.name,
185
185
  pkg.epoch,
186
186
  pkg.version,
187
187
  pkg.release,
188
188
  pkg.arch,
189
189
  provides,
190
- pkg.type )
190
+ pkg.type,
191
+ pkg.repoid )
191
192
 
192
193
  return 0
193
194
 
@@ -497,12 +497,13 @@ class Chef
497
497
  class RPMDbPackage < RPMPackage
498
498
  # <rpm parts>, installed, available
499
499
  def initialize(*args)
500
+ @repoid = args.pop
500
501
  # state
501
502
  @available = args.pop
502
503
  @installed = args.pop
503
504
  super(*args)
504
505
  end
505
- attr_reader :available, :installed
506
+ attr_reader :repoid, :available, :installed
506
507
  end
507
508
 
508
509
  # Simple storage for RPMPackage objects - keeps them unique and sorted
@@ -712,7 +713,7 @@ class Chef
712
713
  next
713
714
  end
714
715
 
715
- if line =~ %r{^(\S+) ([0-9]+) (\S+) (\S+) (\S+) \[(.*)\] ([i,a,r])$}
716
+ if line =~ %r{^(\S+) ([0-9]+) (\S+) (\S+) (\S+) \[(.*)\] ([i,a,r]) (\S+)$}
716
717
  name = $1
717
718
  epoch = $2
718
719
  version = $3
@@ -720,6 +721,7 @@ class Chef
720
721
  arch = $5
721
722
  provides = parse_provides($6)
722
723
  type = $7
724
+ repoid = $8
723
725
  else
724
726
  Chef::Log.warn("Problem parsing line '#{line}' from yum-dump.py! " +
725
727
  "Please check your yum configuration.")
@@ -740,7 +742,7 @@ class Chef
740
742
  installed = true
741
743
  end
742
744
 
743
- pkg = RPMDbPackage.new(name, epoch, version, release, arch, provides, installed, available)
745
+ pkg = RPMDbPackage.new(name, epoch, version, release, arch, provides, installed, available, repoid)
744
746
  @rpmdb << pkg
745
747
  end
746
748
 
@@ -811,23 +813,36 @@ class Chef
811
813
  @rpmdb.whatprovides(rpmdep)
812
814
  end
813
815
 
816
+ # Check if a package-version.arch is available to install
814
817
  def version_available?(package_name, desired_version, arch=nil)
815
- version(package_name, arch, true, false) do |v|
816
- return true if desired_version == v
817
- end
818
+ version(package_name, arch, true, false) do |v|
819
+ return true if desired_version == v
820
+ end
818
821
 
819
822
  return false
820
823
  end
821
824
 
825
+ # Return the source repository for a package-version.arch
826
+ def package_repository(package_name, desired_version, arch=nil)
827
+ package(package_name, arch, true, false) do |pkg|
828
+ return pkg.repoid if desired_version == pkg.version.to_s
829
+ end
830
+
831
+ return nil
832
+ end
833
+
834
+ # Return the latest available version for a package.arch
822
835
  def available_version(package_name, arch=nil)
823
836
  version(package_name, arch, true, false)
824
837
  end
825
838
  alias :candidate_version :available_version
826
839
 
840
+ # Return the currently installed version for a package.arch
827
841
  def installed_version(package_name, arch=nil)
828
842
  version(package_name, arch, false, true)
829
843
  end
830
844
 
845
+ # Return an array of packages allowed to be installed multiple times, such as the kernel
831
846
  def allow_multi_install
832
847
  refresh
833
848
  @allow_multi_install
@@ -836,6 +851,23 @@ class Chef
836
851
  private
837
852
 
838
853
  def version(package_name, arch=nil, is_available=false, is_installed=false)
854
+ package(package_name, arch, is_available, is_installed) do |pkg|
855
+ if block_given?
856
+ yield pkg.version.to_s
857
+ else
858
+ # first match is latest version
859
+ return pkg.version.to_s
860
+ end
861
+ end
862
+
863
+ if block_given?
864
+ return self
865
+ else
866
+ return nil
867
+ end
868
+ end
869
+
870
+ def package(package_name, arch=nil, is_available=false, is_installed=false)
839
871
  refresh
840
872
  packages = @rpmdb[package_name]
841
873
  if packages
@@ -851,10 +883,10 @@ class Chef
851
883
  end
852
884
 
853
885
  if block_given?
854
- yield pkg.version.to_s
886
+ yield pkg
855
887
  else
856
888
  # first match is latest version
857
- return pkg.version.to_s
889
+ return pkg
858
890
  end
859
891
  end
860
892
  end
@@ -1026,6 +1058,7 @@ class Chef
1026
1058
  # Work around yum not exiting with an error if a package doesn't exist for CHEF-2062
1027
1059
  if @yum.version_available?(name, version, arch)
1028
1060
  method = "install"
1061
+ log_method = "installing"
1029
1062
 
1030
1063
  # More Yum fun:
1031
1064
  #
@@ -1038,6 +1071,7 @@ class Chef
1038
1071
  # Unless they want this...
1039
1072
  if allow_downgrade
1040
1073
  method = "downgrade"
1074
+ log_method = "downgrading"
1041
1075
  else
1042
1076
  # we bail like yum when the package is older
1043
1077
  raise Chef::Exceptions::Package, "Installed package #{name}-#{@current_resource.version} is newer " +
@@ -1046,12 +1080,16 @@ class Chef
1046
1080
  end
1047
1081
  end
1048
1082
 
1083
+ repo = @yum.package_repository(name, version, arch)
1084
+ Chef::Log.info("#{@new_resource} #{log_method} #{name}-#{version}#{yum_arch} from #{repo} repository")
1085
+
1049
1086
  yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{name}-#{version}#{yum_arch}")
1050
1087
  else
1051
1088
  raise Chef::Exceptions::Package, "Version #{version} of #{name} not found. Did you specify both version " +
1052
1089
  "and release? (version-release, e.g. 1.84-10.fc6)"
1053
1090
  end
1054
1091
  end
1092
+
1055
1093
  if flush_cache[:after]
1056
1094
  @yum.reload
1057
1095
  else
@@ -1067,10 +1105,12 @@ class Chef
1067
1105
  #
1068
1106
  # Hacky - better overall solution? Custom compare in Package provider?
1069
1107
  def action_upgrade
1108
+ # Could be uninstalled or have no candidate
1109
+ if @current_resource.version.nil? || candidate_version.nil?
1110
+ super
1070
1111
  # Ensure the candidate is newer
1071
- if RPMVersion.parse(candidate_version) > RPMVersion.parse(@current_resource.version)
1112
+ elsif RPMVersion.parse(candidate_version) > RPMVersion.parse(@current_resource.version)
1072
1113
  super
1073
- # Candidate is older
1074
1114
  else
1075
1115
  Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do")
1076
1116
  end
@@ -1086,6 +1126,7 @@ class Chef
1086
1126
  else
1087
1127
  yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{name}#{yum_arch}")
1088
1128
  end
1129
+
1089
1130
  if flush_cache[:after]
1090
1131
  @yum.reload
1091
1132
  else