chef 0.10.2 → 0.10.4.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/distro/common/html/chef-client.8.html +4 -4
  2. data/distro/common/html/knife-cookbook.1.html +5 -3
  3. data/distro/common/html/knife-node.1.html +4 -4
  4. data/distro/common/man/man1/knife-cookbook.1 +5 -1
  5. data/distro/common/man/man1/knife-node.1 +1 -1
  6. data/distro/common/markdown/man1/knife-cookbook-site.mkd +3 -3
  7. data/distro/common/markdown/man1/knife-cookbook.mkd +7 -0
  8. data/distro/common/markdown/man1/knife-node.mkd +4 -3
  9. data/distro/common/markdown/man1/knife-ssh.mkd +2 -0
  10. data/lib/chef/application.rb +1 -0
  11. data/lib/chef/cookbook_loader.rb +18 -0
  12. data/lib/chef/cookbook_uploader.rb +1 -1
  13. data/lib/chef/data_bag.rb +14 -2
  14. data/lib/chef/data_bag_item.rb +8 -2
  15. data/lib/chef/encrypted_data_bag_item.rb +19 -6
  16. data/lib/chef/environment.rb +12 -6
  17. data/lib/chef/exceptions.rb +1 -0
  18. data/lib/chef/knife.rb +0 -28
  19. data/lib/chef/knife/bootstrap.rb +7 -0
  20. data/lib/chef/knife/bootstrap/archlinux-gems.erb +14 -12
  21. data/lib/chef/knife/bootstrap/centos5-gems.erb +8 -5
  22. data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -0
  23. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +16 -9
  24. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -3
  25. data/lib/chef/knife/client_bulk_delete.rb +28 -6
  26. data/lib/chef/knife/cookbook_site_install.rb +2 -2
  27. data/lib/chef/knife/cookbook_upload.rb +71 -0
  28. data/lib/chef/knife/core/bootstrap_context.rb +13 -3
  29. data/lib/chef/knife/core/cookbook_scm_repo.rb +2 -3
  30. data/lib/chef/knife/core/node_presenter.rb +5 -2
  31. data/lib/chef/knife/help.rb +13 -12
  32. data/lib/chef/knife/help_topics.rb +4 -0
  33. data/lib/chef/knife/ssh.rb +25 -4
  34. data/lib/chef/mixin/create_path.rb +3 -2
  35. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  36. data/lib/chef/mixin/language.rb +8 -11
  37. data/lib/chef/monkey_patches/numeric.rb +9 -1
  38. data/lib/chef/monkey_patches/string.rb +21 -0
  39. data/lib/chef/platform.rb +2 -1
  40. data/lib/chef/provider.rb +1 -1
  41. data/lib/chef/provider/git.rb +16 -3
  42. data/lib/chef/provider/group/suse.rb +53 -0
  43. data/lib/chef/provider/mount/mount.rb +28 -20
  44. data/lib/chef/provider/package/apt.rb +39 -24
  45. data/lib/chef/provider/package/dpkg.rb +5 -2
  46. data/lib/chef/provider/package/easy_install.rb +2 -2
  47. data/lib/chef/provider/package/freebsd.rb +5 -2
  48. data/lib/chef/provider/package/macports.rb +4 -4
  49. data/lib/chef/provider/package/rpm.rb +4 -1
  50. data/lib/chef/provider/package/rubygems.rb +3 -0
  51. data/lib/chef/provider/package/solaris.rb +3 -0
  52. data/lib/chef/provider/package/yum-dump.py +239 -81
  53. data/lib/chef/provider/package/yum.rb +977 -110
  54. data/lib/chef/provider/package/zypper.rb +20 -3
  55. data/lib/chef/provider/remote_directory.rb +0 -1
  56. data/lib/chef/provider/service/arch.rb +35 -28
  57. data/lib/chef/provider/service/systemd.rb +102 -0
  58. data/lib/chef/provider/service/upstart.rb +8 -2
  59. data/lib/chef/providers.rb +2 -0
  60. data/lib/chef/resource.rb +31 -2
  61. data/lib/chef/resource/git.rb +9 -0
  62. data/lib/chef/resource/mount.rb +1 -2
  63. data/lib/chef/resource/yum_package.rb +20 -0
  64. data/lib/chef/rest.rb +1 -1
  65. data/lib/chef/role.rb +1 -1
  66. data/lib/chef/run_context.rb +3 -3
  67. data/lib/chef/runner.rb +15 -2
  68. data/lib/chef/shell_out.rb +1 -1
  69. data/lib/chef/shell_out/windows.rb +2 -2
  70. data/lib/chef/solr_query.rb +1 -1
  71. data/lib/chef/tasks/chef_repo.rake +1 -1
  72. data/lib/chef/version.rb +1 -1
  73. metadata +425 -441
@@ -35,8 +35,9 @@ class Chef
35
35
 
36
36
  if file_path.kind_of?(String)
37
37
  file_path = File.expand_path(file_path).split(File::SEPARATOR)
38
- file_path.shift if file_path[0] = ''
39
- unless file_path[0].match("^#{File::SEPARATOR}")
38
+ file_path.shift if file_path[0] == ''
39
+ # Check if path starts with a separator or drive letter (Windows)
40
+ unless file_path[0].match("^#{File::SEPARATOR}|^[a-zA-Z]:")
40
41
  file_path[0] = "#{File::SEPARATOR}#{file_path[0]}"
41
42
  end
42
43
  end
@@ -0,0 +1,42 @@
1
+ # Author:: Lamont Granquist (<lamont@opscode.com>)
2
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+
19
+ #
20
+ # mixin to make this syntax work without specifying a source:
21
+ #
22
+ # gem_pacakge "/tmp/foo-x.y.z.gem"
23
+ # rpm_package "/tmp/foo-x.y-z.rpm"
24
+ # dpkg_package "/tmp/foo-x.y.z.deb"
25
+ #
26
+
27
+ class Chef
28
+ module Mixin
29
+ module GetSourceFromPackage
30
+ def initialize(new_resource, run_context)
31
+ super
32
+ # if we're passed something that looks like a filesystem path, with no source, use it
33
+ # - require at least one '/' in the path to avoid gem_package "foo" breaking if a file named 'foo' exists in the cwd
34
+ if new_resource.source.nil? && new_resource.package_name.match(/#{::File::SEPARATOR}/) && ::File.exists?(new_resource.package_name)
35
+ Chef::Log.debug("No package source specified, but #{new_resource.package_name} exists on the filesystem, copying to package source")
36
+ new_resource.source(@new_resource.package_name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -69,24 +69,21 @@ class Chef
69
69
  @values["default"] = value
70
70
  else
71
71
  assert_valid_platform_values!(platforms, value)
72
- Array(platforms).each { |platform| @values[platform.to_s] = format_values(value)}
72
+ Array(platforms).each { |platform| @values[platform.to_s] = normalize_keys(value)}
73
73
  value
74
74
  end
75
75
  end
76
76
 
77
- def format_values(hash)
78
- formatted_array = flatten_one_level(hash.map { |key, value| [key.to_s, value]})
79
- Hash[*formatted_array]
80
- end
81
-
82
- def flatten_one_level(array)
83
- array.inject([]) do |flatter_array, values|
84
- Array(values).each {|value| flatter_array << value }
85
- flatter_array
77
+ def normalize_keys(hash)
78
+ hash.inject({}) do |h, key_value|
79
+ keys, value = *key_value
80
+ Array(keys).each do |key|
81
+ h[key.to_s] = value
82
+ end
83
+ h
86
84
  end
87
85
  end
88
86
 
89
-
90
87
  def assert_valid_platform_values!(platforms, value)
91
88
  unless value.kind_of?(Hash)
92
89
  msg = "platform dependent values must be specified in the format :platform => {:version => value} "
@@ -4,4 +4,12 @@ unless 0.respond_to?(:fdiv)
4
4
  to_f / other
5
5
  end
6
6
  end
7
- end
7
+ end
8
+
9
+ # String elements referenced with [] <= 1.8.6 return a Fixnum. Cheat to allow
10
+ # for the simpler "test"[2].ord construct
11
+ class Numeric
12
+ def ord
13
+ return self
14
+ end
15
+ end
@@ -21,8 +21,29 @@
21
21
  # give the actual number of characters. In Chef::REST, we need the bytesize
22
22
  # so we can correctly set the Content-Length headers, but ruby 1.8.6 and lower
23
23
  # don't define String#bytesize. Monkey patching time!
24
+
25
+ begin
26
+ require 'enumerator'
27
+ rescue LoadError
28
+ end
29
+
24
30
  class String
25
31
  unless method_defined?(:bytesize)
26
32
  alias :bytesize :size
27
33
  end
34
+
35
+ unless method_defined?(:lines)
36
+ def lines
37
+ enum_for(:each)
38
+ end
39
+ end
40
+ end
41
+
42
+ # <= 1.8.6 needs some ord!
43
+ class String
44
+ unless method_defined?(:ord)
45
+ def ord
46
+ self.unpack('c').first
47
+ end
48
+ end
28
49
  end
@@ -126,7 +126,8 @@ class Chef
126
126
  :default => {
127
127
  :service => Chef::Provider::Service::Redhat,
128
128
  :cron => Chef::Provider::Cron,
129
- :package => Chef::Provider::Package::Zypper
129
+ :package => Chef::Provider::Package::Zypper,
130
+ :group => Chef::Provider::Group::Suse
130
131
  }
131
132
  },
132
133
  :redhat => {
@@ -81,7 +81,7 @@ class Chef
81
81
  class << self
82
82
  include Chef::Mixin::ConvertToClassName
83
83
 
84
- def build_from_file(cookbook_name, filename)
84
+ def build_from_file(cookbook_name, filename, run_context)
85
85
  pname = filename_to_qualified_string(cookbook_name, filename)
86
86
 
87
87
  # Add log entry if we override an existing light-weight provider.
@@ -38,10 +38,11 @@ class Chef
38
38
  def action_checkout
39
39
  assert_target_directory_valid!
40
40
 
41
- if target_dir_non_existant_or_empty?
41
+ if target_dir_non_existent_or_empty?
42
42
  clone
43
43
  checkout
44
44
  enable_submodules
45
+ add_remotes
45
46
  @new_resource.updated_by_last_action(true)
46
47
  else
47
48
  Chef::Log.debug "#{@new_resource} checkout destination #{@new_resource.destination} already exists or is a non-empty directory"
@@ -66,7 +67,7 @@ class Chef
66
67
  Chef::Log.info "#{@new_resource} updated to revision #{target_revision}"
67
68
  @new_resource.updated_by_last_action(true)
68
69
  end
69
-
70
+ add_remotes
70
71
  else
71
72
  action_checkout
72
73
  @new_resource.updated_by_last_action(true)
@@ -85,7 +86,7 @@ class Chef
85
86
  ::File.exist?(::File.join(@new_resource.destination, ".git"))
86
87
  end
87
88
 
88
- def target_dir_non_existant_or_empty?
89
+ def target_dir_non_existent_or_empty?
89
90
  !::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination).sort == ['.','..']
90
91
  end
91
92
 
@@ -98,6 +99,18 @@ class Chef
98
99
  sha_hash?(result) ? result : nil
99
100
  end
100
101
 
102
+ def add_remotes
103
+ if (@new_resource.additional_remotes.length > 0)
104
+ @new_resource.additional_remotes.each_pair do |remote_name, remote_url|
105
+ Chef::Log.info "#{@new_resource} adding git remote #{remote_name} = #{remote_url}"
106
+ command = "git remote add #{remote_name} #{remote_url}"
107
+ if shell_out(command, run_options(:cwd => @new_resource.destination, :command_log_level => :info)).exitstatus != 0
108
+ @new_resource.updated_by_last_action(true)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
101
114
  def clone
102
115
  remote = @new_resource.remote
103
116
 
@@ -0,0 +1,53 @@
1
+ #
2
+ # Author:: AJ Christensen (<aj@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 OpsCode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/provider/group/groupadd'
20
+ require 'chef/mixin/shell_out'
21
+
22
+ class Chef
23
+ class Provider
24
+ class Group
25
+ class Suse < Chef::Provider::Group::Groupadd
26
+
27
+ include Chef::Mixin::ShellOut
28
+
29
+ def load_current_resource
30
+ super
31
+
32
+ raise Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{@new_resource}" unless ::File.exists?("/usr/sbin/groupmod")
33
+ end
34
+
35
+ def modify_group_members
36
+ unless @new_resource.members.empty?
37
+ if(@new_resource.append)
38
+ @new_resource.members.each do |member|
39
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
40
+ shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
41
+ end
42
+ else
43
+ Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
44
+ shell_out!("groupmod -A #{@new_resource.members.join(',')} #{@new_resource.group_name}")
45
+ end
46
+ else
47
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -36,29 +36,21 @@ class Chef
36
36
  @current_resource = Chef::Resource::Mount.new(@new_resource.name)
37
37
  @current_resource.mount_point(@new_resource.mount_point)
38
38
  @current_resource.device(@new_resource.device)
39
- Chef::Log.debug("Checking for mount point #{@current_resource.mount_point}")
40
-
39
+ mounted?
40
+ enabled?
41
+ end
42
+
43
+ def mountable?
41
44
  # only check for existence of non-remote devices
42
45
  if (device_should_exist? && !::File.exists?(device_real) )
43
46
  raise Chef::Exceptions::Mount, "Device #{@new_resource.device} does not exist"
44
47
  elsif( !::File.exists?(@new_resource.mount_point) )
45
48
  raise Chef::Exceptions::Mount, "Mount point #{@new_resource.mount_point} does not exist"
46
49
  end
47
-
48
- # Check to see if the volume is mounted. Last volume entry wins.
49
- mounted = false
50
- shell_out!("mount").stdout.each_line do |line|
51
- case line
52
- when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(@new_resource.mount_point)}/
53
- mounted = true
54
- Chef::Log.debug("Special device #{device_logstring} mounted as #{@new_resource.mount_point}")
55
- when /^([\/\w])+\son\s#{Regexp.escape(@new_resource.mount_point)}\s+/
56
- mounted = false
57
- Chef::Log.debug("Special device #{$~[1]} mounted as #{@new_resource.mount_point}")
58
- end
59
- end
60
- @current_resource.mounted(mounted)
61
-
50
+ return true
51
+ end
52
+
53
+ def enabled?
62
54
  # Check to see if there is a entry in /etc/fstab. Last entry for a volume wins.
63
55
  enabled = false
64
56
  ::File.foreach("/etc/fstab") do |line|
@@ -72,16 +64,33 @@ class Chef
72
64
  @current_resource.dump($3.to_i)
73
65
  @current_resource.pass($4.to_i)
74
66
  Chef::Log.debug("Found mount #{device_fstab} to #{@new_resource.mount_point} in /etc/fstab")
75
- when /^[\/\w]+\s+#{Regexp.escape(@new_resource.mount_point)}/
67
+ next
68
+ when /^[\/\w]+\s+#{Regexp.escape(@new_resource.mount_point)}\s+/
76
69
  enabled = false
77
70
  Chef::Log.debug("Found conflicting mount point #{@new_resource.mount_point} in /etc/fstab")
78
71
  end
79
72
  end
80
73
  @current_resource.enabled(enabled)
81
74
  end
75
+
76
+ def mounted?
77
+ mounted = false
78
+ shell_out!("mount").stdout.each_line do |line|
79
+ case line
80
+ when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(@new_resource.mount_point)}/
81
+ mounted = true
82
+ Chef::Log.debug("Special device #{device_logstring} mounted as #{@new_resource.mount_point}")
83
+ when /^([\/\w])+\son\s#{Regexp.escape(@new_resource.mount_point)}\s+/
84
+ mounted = false
85
+ Chef::Log.debug("Special device #{$~[1]} mounted as #{@new_resource.mount_point}")
86
+ end
87
+ end
88
+ @current_resource.mounted(mounted)
89
+ end
82
90
 
83
91
  def mount_fs
84
92
  unless @current_resource.mounted
93
+ mountable?
85
94
  command = "mount -t #{@new_resource.fstype}"
86
95
  command << " -o #{@new_resource.options.join(',')}" unless @new_resource.options.nil? || @new_resource.options.empty?
87
96
  command << case @new_resource.device_type
@@ -112,7 +121,6 @@ class Chef
112
121
  def remount_fs
113
122
  if @current_resource.mounted and @new_resource.supports[:remount]
114
123
  shell_out!("mount -o remount #{@new_resource.mount_point}")
115
-
116
124
  @new_resource.updated_by_last_action(true)
117
125
  Chef::Log.debug("#{@new_resource} is remounted at #{@new_resource.mount_point}")
118
126
  elsif @current_resource.mounted
@@ -165,7 +173,7 @@ class Chef
165
173
  end
166
174
 
167
175
  def device_should_exist?
168
- @new_resource.device !~ /:/ && @new_resource.device !~ /\/\// && @new_resource.device != "tmpfs"
176
+ @new_resource.device !~ /:/ && @new_resource.device !~ /\/\// && @new_resource.device != "tmpfs" && @new_resource.fstype != 'fuse'
169
177
  end
170
178
 
171
179
  private
@@ -25,44 +25,57 @@ class Chef
25
25
  class Package
26
26
  class Apt < Chef::Provider::Package
27
27
 
28
+ include Chef::Mixin::ShellOut
29
+ attr_accessor :virtual
30
+
28
31
  def load_current_resource
29
32
  @current_resource = Chef::Resource::Package.new(@new_resource.name)
30
33
  @current_resource.package_name(@new_resource.package_name)
34
+ check_package_state(@new_resource.package_name)
35
+ @current_resource
36
+ end
37
+
38
+ def check_package_state(package)
39
+ Chef::Log.debug("Checking package status for #{package}")
40
+ installed = false
41
+ depends = false
31
42
 
32
- Chef::Log.debug("#{@new_resource} checking apt-cache policy")
33
- status = popen4("apt-cache policy #{@new_resource.package_name}") do |pid, stdin, stdout, stderr|
34
- stdout.each do |line|
35
- case line
36
- when /^\s{2}Installed: (.+)$/
37
- installed_version = $1
38
- if installed_version == '(none)'
39
- Chef::Log.debug("#{@new_resource} current version is nil")
40
- @current_resource.version(nil)
41
- else
42
- Chef::Log.debug("#{@new_resource} current version is #{installed_version}")
43
- @current_resource.version(installed_version)
44
- end
45
- when /^\s{2}Candidate: (.+)$/
46
- Chef::Log.debug("#{@new_resource} candidate version is #{$1}")
47
- @candidate_version = $1
43
+ shell_out!("aptitude show #{package}").stdout.each_line do |line|
44
+ case line
45
+ when /^State: installed/
46
+ installed = true
47
+ when /^Version: (.*)/
48
+ @candidate_version = $1
49
+ if installed
50
+ @current_resource.version($1)
51
+ else
52
+ @current_resource.version(nil)
48
53
  end
54
+ when /Depends: ([^\s]*) /
55
+ depends = $1
56
+ when /Provided by: ([\w\d\-\.]*)/
57
+ next if installed
58
+ virtual_provider = $1
59
+ virtual_provider = depends if depends
60
+ Chef::Log.debug("Virtual package provided by #{virtual_provider}")
61
+ @virtual = true
62
+ installed = check_package_state(virtual_provider)
63
+ @candidate_version = virtual_provider
49
64
  end
50
65
  end
51
66
 
52
- unless status.exitstatus == 0
53
- raise Chef::Exceptions::Package, "apt-cache failed - #{status.inspect}!"
54
- end
55
-
56
- if @candidate_version == "(none)"
67
+ if @candidate_version.nil?
57
68
  raise Chef::Exceptions::Package, "apt does not have a version of package #{@new_resource.package_name}"
58
69
  end
59
70
 
60
- @current_resource
71
+ return installed
61
72
  end
62
73
 
63
74
  def install_package(name, version)
75
+ package_name = "#{name}=#{version}"
76
+ package_name = "#{name} #{@candidate_version}" if @virtual
64
77
  run_command_with_systems_locale(
65
- :command => "apt-get -q -y#{expand_options(@new_resource.options)} install #{name}=#{version}",
78
+ :command => "apt-get -q -y#{expand_options(@new_resource.options)} install #{package_name}",
66
79
  :environment => {
67
80
  "DEBIAN_FRONTEND" => "noninteractive"
68
81
  }
@@ -74,8 +87,10 @@ class Chef
74
87
  end
75
88
 
76
89
  def remove_package(name, version)
90
+ package_name = "#{name}"
91
+ package_name = "#{name} #{@candidate_version}" if @virtual
77
92
  run_command_with_systems_locale(
78
- :command => "apt-get -q -y#{expand_options(@new_resource.options)} remove #{@new_resource.package_name}",
93
+ :command => "apt-get -q -y#{expand_options(@new_resource.options)} remove #{package_name}",
79
94
  :environment => {
80
95
  "DEBIAN_FRONTEND" => "noninteractive"
81
96
  }
@@ -19,15 +19,18 @@
19
19
  require 'chef/provider/package'
20
20
  require 'chef/mixin/command'
21
21
  require 'chef/resource/package'
22
+ require 'chef/mixin/get_source_from_package'
22
23
 
23
24
  class Chef
24
25
  class Provider
25
26
  class Package
26
27
  class Dpkg < Chef::Provider::Package::Apt
27
- DPKG_INFO = /([a-z\d\-\+]+)\t([\w\d.-]+)/
28
+ DPKG_INFO = /([a-z\d\-\+]+)\t([\w\d.~-]+)/
28
29
  DPKG_INSTALLED = /^Status: install ok installed/
29
30
  DPKG_VERSION = /^Version: (.+)$/
30
-
31
+
32
+ include Chef::Mixin::GetSourceFromPackage
33
+
31
34
  def load_current_resource
32
35
  @current_resource = Chef::Resource::Package.new(@new_resource.name)
33
36
  @current_resource.package_name(@new_resource.package_name)