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
@@ -40,15 +40,20 @@ class Chef
40
40
  )
41
41
  files_to_transfer.each do |cookbook_file_relative_path|
42
42
  create_cookbook_file(cookbook_file_relative_path)
43
- files_to_purge.delete(::File.dirname(::File.join(@new_resource.path, cookbook_file_relative_path)))
43
+ # the file is removed from the purge list
44
44
  files_to_purge.delete(::File.join(@new_resource.path, cookbook_file_relative_path))
45
+ # parent directories are also removed from the purge list
46
+ directories=::File.dirname(::File.join(@new_resource.path, cookbook_file_relative_path)).split(::File::SEPARATOR)
47
+ for i in 0..directories.length-1
48
+ files_to_purge.delete(::File.join(directories[0..i]))
49
+ end
45
50
  end
46
51
  purge_unmanaged_files(files_to_purge)
47
52
  end
48
53
 
49
54
  def action_create_if_missing
50
55
  # if this action is called, ignore the existing overwrite flag
51
- @new_resource.overwrite = false
56
+ @new_resource.overwrite(false)
52
57
  action_create
53
58
  end
54
59
 
@@ -106,6 +111,11 @@ class Chef
106
111
  cookbook_file = Chef::Resource::CookbookFile.new(target_path, run_context)
107
112
  cookbook_file.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
108
113
  cookbook_file.source(::File.join(@new_resource.source, relative_source_path))
114
+ if Chef::Platform.windows? && @new_resource.files_rights
115
+ @new_resource.files_rights.each_pair do |permission, *args|
116
+ cookbook_file.rights(permission, *args)
117
+ end
118
+ end
109
119
  cookbook_file.mode(@new_resource.files_mode) if @new_resource.files_mode
110
120
  cookbook_file.group(@new_resource.files_group) if @new_resource.files_group
111
121
  cookbook_file.owner(@new_resource.files_owner) if @new_resource.files_owner
@@ -125,7 +135,18 @@ class Chef
125
135
  def resource_for_directory(path)
126
136
  dir = Chef::Resource::Directory.new(path, run_context)
127
137
  dir.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
128
- dir.mode(@new_resource.mode)
138
+ if Chef::Platform.windows? && @new_resource.rights
139
+ # rights are only meant to be applied to the toppest-level directory;
140
+ # Windows will handle inheritance.
141
+ if path == @new_resource.path
142
+ @new_resource.rights.each do |rights| #rights is a hash
143
+ permissions = rights.delete(:permissions) #delete will return the value or nil if not found
144
+ principals = rights.delete(:principals)
145
+ dir.rights(permissions, principals, rights)
146
+ end
147
+ end
148
+ end
149
+ dir.mode(@new_resource.mode) if @new_resource.mode
129
150
  dir.group(@new_resource.group)
130
151
  dir.owner(@new_resource.owner)
131
152
  dir.recursive(true)
@@ -63,12 +63,6 @@ class Chef
63
63
  end
64
64
  end
65
65
 
66
- def enforce_ownership_and_permissions
67
- set_owner if @new_resource.owner
68
- set_group if @new_resource.group
69
- set_mode if @new_resource.mode
70
- end
71
-
72
66
  def current_resource_matches_target_checksum?
73
67
  @new_resource.checksum && @current_resource.checksum && @current_resource.checksum =~ /^#{Regexp.escape(@new_resource.checksum)}/
74
68
  end
@@ -130,7 +130,7 @@ class Chef::Provider::Route < Chef::Provider
130
130
  def generate_config
131
131
  conf = Hash.new
132
132
  case node[:platform]
133
- when ("centos" || "redhat" || "fedora")
133
+ when "centos", "redhat", "fedora"
134
134
  # walk the collection
135
135
  run_context.resource_collection.each do |resource|
136
136
  if resource.is_a? Chef::Resource::Route
@@ -143,11 +143,11 @@ class Chef::Provider::Route < Chef::Provider
143
143
 
144
144
  conf[dev] = String.new if conf[dev].nil?
145
145
  if resource.action == :add
146
- conf[dev] = config_file_contents(:add, :target => resource.target, :netmask => resource.netmask, :gateway => resource.gateway)
146
+ conf[dev] << config_file_contents(:add, :target => resource.target, :netmask => resource.netmask, :gateway => resource.gateway)
147
147
  else
148
148
  # need to do this for the case when the last route on an int
149
149
  # is removed
150
- conf[dev] = config_file_contents(:delete)
150
+ conf[dev] << config_file_contents(:delete)
151
151
  end
152
152
  end
153
153
  end
@@ -17,13 +17,13 @@
17
17
  #
18
18
 
19
19
  require 'chef/provider/service'
20
- require 'chef/provider/service/invokercd'
20
+ require 'chef/provider/service/init'
21
21
  require 'chef/mixin/command'
22
22
 
23
23
  class Chef
24
24
  class Provider
25
25
  class Service
26
- class Debian < Chef::Provider::Service::Invokercd
26
+ class Debian < Chef::Provider::Service::Init
27
27
  UPDATE_RC_D_ENABLED_MATCHES = /\/rc[\dS].d\/S|not installed/i
28
28
  UPDATE_RC_D_PRIORITIES = /\/rc([\dS]).d\/([SK])(\d\d)/i
29
29
 
@@ -134,7 +134,7 @@ class Chef
134
134
  def set_service_enable(value)
135
135
  lines = read_rc_conf
136
136
  # Remove line that set the old value
137
- lines.delete_if { |line| line =~ /#{service_enable_variable_name}/ }
137
+ lines.delete_if { |line| line =~ /#{Regexp.escape(service_enable_variable_name)}/ }
138
138
  # And append the line that sets the new value at the end
139
139
  lines << "#{service_enable_variable_name}=\"#{value}\""
140
140
  write_rc_conf(lines)
@@ -0,0 +1,125 @@
1
+ #
2
+ # Author:: Igor Afonov <afonov@gmail.com>
3
+ # Copyright:: Copyright (c) 2011 Igor Afonov
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/service'
20
+
21
+ class Chef
22
+ class Provider
23
+ class Service
24
+ class Macosx < Chef::Provider::Service::Simple
25
+ include Chef::Mixin::ShellOut
26
+
27
+ PLIST_DIRS = %w{~/Library/LaunchAgents
28
+ /Library/LaunchAgents
29
+ /Library/LaunchDaemons
30
+ /System/Library/LaunchAgents
31
+ /System/Library/LaunchDaemons }
32
+
33
+ def load_current_resource
34
+ @current_resource = Chef::Resource::Service.new(@new_resource.name)
35
+ @current_resource.service_name(@new_resource.service_name)
36
+ @plist = find_service_plist
37
+ set_service_status
38
+
39
+ @current_resource
40
+ end
41
+
42
+ def enable_service
43
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :enable"
44
+ end
45
+
46
+ def disable_service
47
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :disable"
48
+ end
49
+
50
+ def start_service
51
+ if @current_resource.running
52
+ Chef::Log.debug("#{@new_resource} already running, not starting")
53
+ else
54
+ if @new_resource.start_command
55
+ super
56
+ else
57
+ shell_out!("launchctl load -w '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
58
+ end
59
+ end
60
+ end
61
+
62
+ def stop_service
63
+ unless @current_resource.running
64
+ Chef::Log.debug("#{@new_resource} not running, not stopping")
65
+ else
66
+ if @new_resource.stop_command
67
+ super
68
+ else
69
+ shell_out!("launchctl unload '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
70
+ end
71
+ end
72
+ end
73
+
74
+ def restart_service
75
+ if @new_resource.restart_command
76
+ super
77
+ else
78
+ stop_service
79
+ sleep 1
80
+ start_service
81
+ end
82
+ end
83
+
84
+ def reload_service
85
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
86
+ end
87
+
88
+ def set_service_status
89
+ @current_resource.enabled(!@plist.nil?)
90
+
91
+ if @current_resource.enabled
92
+ @owner_uid = ::File.stat(@plist).uid
93
+ @owner_gid = ::File.stat(@plist).gid
94
+
95
+ shell_out!("launchctl list", :user => @owner_uid, :group => @owner_gid).stdout.each_line do |line|
96
+ case line
97
+ when /(\d+|-)\s+(?:\d+|-)\s+(.*\.?)#{@current_resource.service_name}/
98
+ pid = $1
99
+ @current_resource.running(!pid.to_i.zero?)
100
+ end
101
+ end
102
+ else
103
+ @current_resource.running(false)
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ def find_service_plist
110
+ plists = PLIST_DIRS.inject([]) do |results, dir|
111
+ entries = Dir.glob("#{::File.expand_path(dir)}/*#{@current_resource.service_name}*.plist")
112
+ entries.any? ? results << entries : results
113
+ end
114
+
115
+ plists.flatten!
116
+ if plists.size > 1
117
+ raise Chef::Exceptions::Service, "Several plist files match service name. Please use full service name."
118
+ end
119
+
120
+ plists.first
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -18,12 +18,16 @@
18
18
  # limitations under the License.
19
19
  #
20
20
 
21
+ require 'chef/mixin/shell_out'
21
22
  require 'chef/provider/service/simple'
22
23
  if RUBY_PLATFORM =~ /mswin|mingw32|windows/
23
24
  require 'win32/service'
24
25
  end
25
26
 
26
27
  class Chef::Provider::Service::Windows < Chef::Provider::Service
28
+
29
+ include Chef::Mixin::ShellOut
30
+
27
31
  RUNNING = 'running'
28
32
  STOPPED = 'stopped'
29
33
  AUTO_START = 'auto start'
@@ -31,7 +35,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
31
35
 
32
36
  def load_current_resource
33
37
  @current_resource = Chef::Resource::Service.new(@new_resource.name)
34
- @current_resource.service_name(@new_resource.service_name)
38
+ @current_resource.service_name(@new_resource.service_name)
35
39
  @current_resource.running(current_state == RUNNING)
36
40
  Chef::Log.debug "#{@new_resource} running: #{@current_resource.running}"
37
41
  @current_resource.enabled(start_type == AUTO_START)
@@ -26,6 +26,8 @@ class Chef
26
26
  class Provider
27
27
  class Subversion < Chef::Provider
28
28
 
29
+ SVN_INFO_PATTERN = /^([\w\s]+): (.+)$/
30
+
29
31
  include Chef::Mixin::Command
30
32
 
31
33
  def load_current_resource
@@ -152,14 +154,15 @@ class Chef
152
154
  end
153
155
 
154
156
  def extract_revision_info(svn_info)
155
- begin
156
- repo_attrs = YAML.load(svn_info)
157
- rescue ArgumentError
158
- # YAML doesn't appreciate input like "svn: '/tmp/deploydir' is not a working copy\n"
159
- return nil
157
+ repo_attrs = svn_info.lines.inject({}) do |attrs, line|
158
+ if line =~ SVN_INFO_PATTERN
159
+ property, value = $1, $2
160
+ attrs[property] = value
161
+ end
162
+ attrs
160
163
  end
161
- raise "Could not parse `svn info` data: #{svn_info}" unless repo_attrs.kind_of?(Hash)
162
- rev = (repo_attrs['Last Changed Rev'] || repo_attrs['Revision']).to_s
164
+ rev = (repo_attrs['Last Changed Rev'] || repo_attrs['Revision'])
165
+ raise "Could not parse `svn info` data: #{svn_info}" if repo_attrs.empty?
163
166
  Chef::Log.debug "#{@new_resource} resolved revision #{@new_resource.revision} to #{rev}"
164
167
  rev
165
168
  end
@@ -60,6 +60,7 @@ require 'chef/provider/package/rubygems'
60
60
  require 'chef/provider/package/yum'
61
61
  require 'chef/provider/package/zypper'
62
62
  require 'chef/provider/package/solaris'
63
+ require 'chef/provider/package/smartos'
63
64
 
64
65
  require 'chef/provider/service/arch'
65
66
  require 'chef/provider/service/debian'
@@ -67,12 +68,14 @@ require 'chef/provider/service/freebsd'
67
68
  require 'chef/provider/service/gentoo'
68
69
  require 'chef/provider/service/init'
69
70
  require 'chef/provider/service/insserv'
71
+ require 'chef/provider/service/invokercd'
70
72
  require 'chef/provider/service/redhat'
71
73
  require 'chef/provider/service/simple'
72
74
  require 'chef/provider/service/systemd'
73
75
  require 'chef/provider/service/upstart'
74
76
  require 'chef/provider/service/windows'
75
77
  require 'chef/provider/service/solaris'
78
+ require 'chef/provider/service/macosx'
76
79
 
77
80
  require 'chef/provider/user/dscl'
78
81
  require 'chef/provider/user/pw'
@@ -23,6 +23,7 @@ require 'chef/mixin/language'
23
23
  require 'chef/mixin/convert_to_class_name'
24
24
  require 'chef/resource/conditional'
25
25
  require 'chef/resource_collection'
26
+ require 'chef/resource_platform_map'
26
27
  require 'chef/node'
27
28
 
28
29
  require 'chef/mixin/deprecation'
@@ -345,8 +346,10 @@ F
345
346
  end << ">"
346
347
  end
347
348
 
348
- # Serialize this object as a hash
349
- def to_json(*a)
349
+ # as_json does most of the to_json heavy lifted. It exists here in case activesupport
350
+ # is loaded. activesupport will call as_json and skip over to_json. This ensure
351
+ # json is encoded as expected
352
+ def as_json(*a)
350
353
  safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
351
354
  instance_vars = Hash.new
352
355
  safe_ivars.each do |iv|
@@ -356,6 +359,11 @@ F
356
359
  'json_class' => self.class.name,
357
360
  'instance_vars' => instance_vars
358
361
  }
362
+ end
363
+
364
+ # Serialize this object as a hash
365
+ def to_json(*a)
366
+ results = as_json
359
367
  results.to_json(*a)
360
368
  end
361
369
 
@@ -434,8 +442,14 @@ F
434
442
 
435
443
  begin
436
444
  return if should_skip?
437
-
438
- provider = Chef::Platform.provider_for_resource(self)
445
+ # leverage new platform => short_name => resource
446
+ # which requires explicitly setting provider in
447
+ # resource class
448
+ if self.provider
449
+ provider = self.provider.new(self, self.run_context)
450
+ else # fall back to old provider resolution
451
+ provider = Chef::Platform.provider_for_resource(self)
452
+ end
439
453
  provider.load_current_resource
440
454
  provider.send("action_#{action}")
441
455
  rescue => e
@@ -485,110 +499,190 @@ F
485
499
  updated
486
500
  end
487
501
 
488
- class << self
502
+ def self.json_create(o)
503
+ resource = self.new(o["instance_vars"]["@name"])
504
+ o["instance_vars"].each do |k,v|
505
+ resource.instance_variable_set("@#{k}".to_sym, v)
506
+ end
507
+ resource
508
+ end
509
+
510
+ # Hook to allow a resource to run specific code after creation
511
+ def after_created
512
+ nil
513
+ end
489
514
 
490
- def json_create(o)
491
- resource = self.new(o["instance_vars"]["@name"])
492
- o["instance_vars"].each do |k,v|
493
- resource.instance_variable_set("@#{k}".to_sym, v)
494
- end
495
- resource
515
+ extend Chef::Mixin::ConvertToClassName
516
+
517
+ def self.attribute(attr_name, validation_opts={})
518
+ # This atrocity is the only way to support 1.8 and 1.9 at the same time
519
+ # When you're ready to drop 1.8 support, do this:
520
+ # define_method attr_name.to_sym do |arg=nil|
521
+ # etc.
522
+ shim_method=<<-SHIM
523
+ def #{attr_name}(arg=nil)
524
+ _set_or_return_#{attr_name}(arg)
525
+ end
526
+ SHIM
527
+ class_eval(shim_method)
528
+
529
+ define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
530
+ set_or_return(attr_name.to_sym, arg, validation_opts)
496
531
  end
532
+ end
497
533
 
498
- include Chef::Mixin::ConvertToClassName
534
+ def self.build_from_file(cookbook_name, filename, run_context)
535
+ rname = filename_to_qualified_string(cookbook_name, filename)
499
536
 
500
- def attribute(attr_name, validation_opts={})
501
- # This atrocity is the only way to support 1.8 and 1.9 at the same time
502
- # When you're ready to drop 1.8 support, do this:
503
- # define_method attr_name.to_sym do |arg=nil|
504
- # etc.
505
- shim_method=<<-SHIM
506
- def #{attr_name}(arg=nil)
507
- _set_or_return_#{attr_name}(arg)
508
- end
509
- SHIM
510
- class_eval(shim_method)
537
+ # Add log entry if we override an existing light-weight resource.
538
+ class_name = convert_to_class_name(rname)
539
+ overriding = Chef::Resource.const_defined?(class_name)
540
+ Chef::Log.info("#{class_name} light-weight resource already initialized -- overriding!") if overriding
541
+
542
+ new_resource_class = Class.new self do |cls|
511
543
 
512
- define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
513
- set_or_return(attr_name.to_sym, arg, validation_opts)
544
+ # default initialize method that ensures that when initialize is finally
545
+ # wrapped (see below), super is called in the event that the resource
546
+ # definer does not implement initialize
547
+ def initialize(name, run_context)
548
+ super(name, run_context)
514
549
  end
515
- end
516
-
517
- def build_from_file(cookbook_name, filename, run_context)
518
- rname = filename_to_qualified_string(cookbook_name, filename)
519
-
520
- # Add log entry if we override an existing light-weight resource.
521
- class_name = convert_to_class_name(rname)
522
- overriding = Chef::Resource.const_defined?(class_name)
523
- Chef::Log.info("#{class_name} light-weight resource already initialized -- overriding!") if overriding
524
-
525
- new_resource_class = Class.new self do |cls|
526
-
527
- # default initialize method that ensures that when initialize is finally
528
- # wrapped (see below), super is called in the event that the resource
529
- # definer does not implement initialize
530
- def initialize(name, run_context)
531
- super(name, run_context)
532
- end
533
550
 
534
- @actions_to_create = []
551
+ @actions_to_create = []
552
+
553
+ class << cls
554
+ include Chef::Mixin::FromFile
535
555
 
536
- class << cls
537
- include Chef::Mixin::FromFile
538
-
539
- attr_accessor :run_context
556
+ attr_accessor :run_context
557
+ attr_reader :action_to_set_default
540
558
 
541
- def node
542
- self.run_context.node
543
- end
559
+ def node
560
+ self.run_context.node
561
+ end
544
562
 
545
- def actions_to_create
546
- @actions_to_create
547
- end
563
+ def actions_to_create
564
+ @actions_to_create
565
+ end
548
566
 
549
- define_method(:actions) do |*action_names|
550
- actions_to_create.push(*action_names)
551
- end
567
+ define_method(:default_action) do |action_name|
568
+ actions_to_create.push(action_name)
569
+ @action_to_set_default = action_name
552
570
  end
553
571
 
554
- # set the run context in the class instance variable
555
- cls.run_context = run_context
556
-
557
- # load resource definition from file
558
- cls.class_from_file(filename)
559
-
560
- # create a new constructor that wraps the old one and adds the actions
561
- # specified in the DSL
562
- old_init = instance_method(:initialize)
563
-
564
- define_method(:initialize) do |name, *optional_args|
565
- args_run_context = optional_args.shift
566
- @resource_name = rname.to_sym
567
- old_init.bind(self).call(name, args_run_context)
568
- allowed_actions.push(self.class.actions_to_create).flatten!
572
+ define_method(:actions) do |*action_names|
573
+ actions_to_create.push(*action_names)
569
574
  end
570
575
  end
571
576
 
572
- # register new class as a Chef::Resource
573
- class_name = convert_to_class_name(rname)
574
- Chef::Resource.const_set(class_name, new_resource_class)
575
- Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
577
+ # set the run context in the class instance variable
578
+ cls.run_context = run_context
579
+
580
+ # load resource definition from file
581
+ cls.class_from_file(filename)
576
582
 
577
- new_resource_class
583
+ # create a new constructor that wraps the old one and adds the actions
584
+ # specified in the DSL
585
+ old_init = instance_method(:initialize)
586
+
587
+ define_method(:initialize) do |name, *optional_args|
588
+ args_run_context = optional_args.shift
589
+ @resource_name = rname.to_sym
590
+ old_init.bind(self).call(name, args_run_context)
591
+ @action = self.class.action_to_set_default || @action
592
+ allowed_actions.push(self.class.actions_to_create).flatten!
593
+ end
578
594
  end
579
595
 
580
- # Resources that want providers namespaced somewhere other than
581
- # Chef::Provider can set the namespace with +provider_base+
582
- # Ex:
583
- # class MyResource < Chef::Resource
584
- # provider_base Chef::Provider::Deploy
585
- # # ...other stuff
586
- # end
587
- def provider_base(arg=nil)
588
- @provider_base ||= arg
589
- @provider_base ||= Chef::Provider
596
+ # register new class as a Chef::Resource
597
+ class_name = convert_to_class_name(rname)
598
+ Chef::Resource.const_set(class_name, new_resource_class)
599
+ Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
600
+
601
+ new_resource_class
602
+ end
603
+
604
+ # Resources that want providers namespaced somewhere other than
605
+ # Chef::Provider can set the namespace with +provider_base+
606
+ # Ex:
607
+ # class MyResource < Chef::Resource
608
+ # provider_base Chef::Provider::Deploy
609
+ # # ...other stuff
610
+ # end
611
+ def self.provider_base(arg=nil)
612
+ @provider_base ||= arg
613
+ @provider_base ||= Chef::Provider
614
+ end
615
+
616
+ def self.platform_map
617
+ @@platform_map ||= PlatformMap.new
618
+ end
619
+
620
+ # Maps a short_name (and optionally a platform and version) to a
621
+ # Chef::Resource. This allows finer grained per platform resource
622
+ # attributes and the end of overloaded resource definitions
623
+ # (I'm looking at you Chef::Resource::Package)
624
+ # Ex:
625
+ # class WindowsFile < Chef::Resource
626
+ # provides :file, :on_platforms => ["windows"]
627
+ # # ...other stuff
628
+ # end
629
+ #
630
+ # TODO: 2011-11-02 schisamo - platform_version support
631
+ def self.provides(short_name, opts={})
632
+ short_name_sym = short_name
633
+ if short_name.kind_of?(String)
634
+ short_name.downcase!
635
+ short_name.gsub!(/\s/, "_")
636
+ short_name_sym = short_name.to_sym
637
+ end
638
+ if opts.has_key?(:on_platforms)
639
+ platforms = [opts[:on_platforms]].flatten
640
+ platforms.each do |p|
641
+ p = :default if :all == p.to_sym
642
+ platform_map.set(
643
+ :platform => p.to_sym,
644
+ :short_name => short_name_sym,
645
+ :resource => self
646
+ )
647
+ end
648
+ else
649
+ platform_map.set(
650
+ :short_name => short_name_sym,
651
+ :resource => self
652
+ )
590
653
  end
654
+ end
655
+
656
+ # Returns a resource based on a short_name anda platform and version.
657
+ #
658
+ #
659
+ # ==== Parameters
660
+ # short_name<Symbol>:: short_name of the resource (ie :directory)
661
+ # platform<Symbol,String>:: platform name
662
+ # version<String>:: platform version
663
+ #
664
+ # === Returns
665
+ # <Chef::Resource>:: returns the proper Chef::Resource class
666
+ def self.resource_for_platform(short_name, platform=nil, version=nil)
667
+ platform_map.get(short_name, platform, version)
668
+ end
591
669
 
670
+ # Returns a resource based on a short_name and a node's
671
+ # platform and version.
672
+ #
673
+ # ==== Parameters
674
+ # short_name<Symbol>:: short_name of the resource (ie :directory)
675
+ # node<Chef::Node>:: Node object to look up platform and version in
676
+ #
677
+ # === Returns
678
+ # <Chef::Resource>:: returns the proper Chef::Resource class
679
+ def self.resource_for_node(short_name, node)
680
+ begin
681
+ platform, version = Chef::Platform.find_platform_and_version(node)
682
+ rescue ArgumentError
683
+ end
684
+ resource = resource_for_platform(short_name, platform, version)
685
+ resource
592
686
  end
593
687
 
594
688
  private