chef 12.0.0.alpha.0 → 12.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -5
  3. data/lib/chef/api_client.rb +1 -1
  4. data/lib/chef/application.rb +16 -8
  5. data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
  6. data/lib/chef/chef_fs/command_line.rb +1 -1
  7. data/lib/chef/chef_fs/file_system.rb +1 -1
  8. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  9. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +3 -3
  10. data/lib/chef/chef_fs/file_system/cookbook_file.rb +2 -2
  11. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -2
  12. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -4
  13. data/lib/chef/config.rb +6 -5
  14. data/lib/chef/config_fetcher.rb +1 -1
  15. data/lib/chef/cookbook/cookbook_version_loader.rb +126 -43
  16. data/lib/chef/cookbook/metadata.rb +102 -53
  17. data/lib/chef/cookbook/syntax_check.rb +1 -1
  18. data/lib/chef/cookbook_loader.rb +62 -14
  19. data/lib/chef/cookbook_site_streaming_uploader.rb +12 -1
  20. data/lib/chef/cookbook_version.rb +13 -4
  21. data/lib/chef/data_bag.rb +28 -15
  22. data/lib/chef/data_bag_item.rb +5 -7
  23. data/lib/chef/digester.rb +5 -9
  24. data/lib/chef/dsl/recipe.rb +14 -0
  25. data/lib/chef/encrypted_data_bag_item.rb +1 -0
  26. data/lib/chef/encrypted_data_bag_item/assertions.rb +57 -0
  27. data/lib/chef/encrypted_data_bag_item/decryptor.rb +52 -28
  28. data/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb +37 -0
  29. data/lib/chef/encrypted_data_bag_item/encryption_failure.rb +22 -0
  30. data/lib/chef/encrypted_data_bag_item/encryptor.rb +79 -8
  31. data/lib/chef/environment.rb +1 -3
  32. data/lib/chef/exceptions.rb +18 -3
  33. data/lib/chef/formatters/base.rb +7 -0
  34. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
  35. data/lib/chef/handler/json_file.rb +0 -1
  36. data/lib/chef/http/json_output.rb +1 -1
  37. data/lib/chef/json_compat.rb +24 -6
  38. data/lib/chef/knife/bootstrap.rb +2 -2
  39. data/lib/chef/knife/client_delete.rb +1 -1
  40. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  41. data/lib/chef/knife/cookbook_site_list.rb +1 -1
  42. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  43. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  44. data/lib/chef/knife/cookbook_site_show.rb +3 -3
  45. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  46. data/lib/chef/knife/core/node_editor.rb +2 -3
  47. data/lib/chef/knife/core/ui.rb +2 -2
  48. data/lib/chef/knife/deps.rb +2 -3
  49. data/lib/chef/mixin/shell_out.rb +1 -1
  50. data/lib/chef/mixin/windows_architecture_helper.rb +1 -0
  51. data/lib/chef/node.rb +1 -2
  52. data/lib/chef/platform/provider_mapping.rb +33 -6
  53. data/lib/chef/provider.rb +0 -2
  54. data/lib/chef/provider/cookbook_file/content.rb +1 -1
  55. data/lib/chef/provider/cron.rb +11 -0
  56. data/lib/chef/provider/deploy.rb +3 -2
  57. data/lib/chef/provider/deploy/revision.rb +2 -2
  58. data/lib/chef/provider/env.rb +1 -1
  59. data/lib/chef/provider/env/windows.rb +5 -9
  60. data/lib/chef/provider/file.rb +84 -33
  61. data/lib/chef/provider/git.rb +2 -1
  62. data/lib/chef/provider/group/aix.rb +17 -2
  63. data/lib/chef/provider/group/dscl.rb +27 -9
  64. data/lib/chef/provider/group/pw.rb +8 -1
  65. data/lib/chef/provider/http_request.rb +4 -4
  66. data/lib/chef/provider/log.rb +4 -14
  67. data/lib/chef/provider/mount/mount.rb +2 -2
  68. data/lib/chef/provider/package/ips.rb +17 -23
  69. data/lib/chef/provider/package/paludis.rb +2 -2
  70. data/lib/chef/provider/package/rpm.rb +2 -2
  71. data/lib/chef/provider/package/rubygems.rb +2 -0
  72. data/lib/chef/provider/package/yum.rb +2 -0
  73. data/lib/chef/provider/package/zypper.rb +1 -1
  74. data/lib/chef/provider/remote_file/cache_control_data.rb +2 -2
  75. data/lib/chef/provider/service/windows.rb +87 -21
  76. data/lib/chef/provider/user/aix.rb +95 -0
  77. data/lib/chef/provider/user/dscl.rb +544 -156
  78. data/lib/chef/provider/user/useradd.rb +1 -0
  79. data/lib/chef/providers.rb +1 -0
  80. data/lib/chef/resource.rb +4 -3
  81. data/lib/chef/resource/freebsd_package.rb +10 -2
  82. data/lib/chef/resource/paludis_package.rb +1 -0
  83. data/lib/chef/resource/scm.rb +10 -0
  84. data/lib/chef/resource/user.rb +27 -0
  85. data/lib/chef/resource/windows_service.rb +53 -0
  86. data/lib/chef/resource_collection.rb +23 -12
  87. data/lib/chef/resource_reporter.rb +10 -10
  88. data/lib/chef/resources.rb +1 -0
  89. data/lib/chef/role.rb +3 -3
  90. data/lib/chef/run_list.rb +6 -3
  91. data/lib/chef/user.rb +1 -1
  92. data/lib/chef/util/diff.rb +1 -2
  93. data/lib/chef/version.rb +1 -1
  94. data/lib/chef/version_constraint.rb +4 -4
  95. data/spec/data/cookbooks/angrybash/metadata.rb +2 -0
  96. data/spec/data/cookbooks/apache2/metadata.rb +2 -0
  97. data/spec/data/cookbooks/borken/metadata.rb +2 -0
  98. data/spec/data/cookbooks/ignorken/metadata.rb +2 -0
  99. data/spec/data/cookbooks/java/metadata.rb +2 -0
  100. data/spec/data/cookbooks/name-mismatch-versionnumber/README.md +4 -0
  101. data/spec/data/cookbooks/name-mismatch-versionnumber/metadata.rb +8 -0
  102. data/spec/data/cookbooks/name-mismatch-versionnumber/recipes/default.rb +8 -0
  103. data/spec/data/cookbooks/openldap/files/default/remotedir/not_a_template.erb +2 -0
  104. data/spec/data/cookbooks/preseed/metadata.rb +2 -0
  105. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/README.md +4 -0
  106. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/metadata.rb +13 -0
  107. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/recipes/default.rb +8 -0
  108. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/README.md +4 -0
  109. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/metadata.rb +10 -0
  110. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/recipes/default.rb +8 -0
  111. data/spec/data/mac_users/10.7-8.plist.xml +559 -0
  112. data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
  113. data/spec/data/mac_users/10.7.plist.xml +559 -0
  114. data/spec/data/mac_users/10.7.shadow.xml +11 -0
  115. data/spec/data/mac_users/10.8.plist.xml +559 -0
  116. data/spec/data/mac_users/10.8.shadow.xml +21 -0
  117. data/spec/data/mac_users/10.9.plist.xml +560 -0
  118. data/spec/data/mac_users/10.9.shadow.xml +21 -0
  119. data/spec/data/object_loader/environments/test.json +2 -0
  120. data/spec/data/object_loader/environments/test_json_class.json +2 -0
  121. data/spec/data/object_loader/nodes/test.json +2 -0
  122. data/spec/data/object_loader/nodes/test_json_class.json +2 -0
  123. data/spec/data/object_loader/roles/test.json +2 -0
  124. data/spec/data/object_loader/roles/test_json_class.json +2 -0
  125. data/spec/functional/resource/bff_spec.rb +1 -1
  126. data/spec/functional/resource/cron_spec.rb +20 -1
  127. data/spec/functional/resource/env_spec.rb +137 -0
  128. data/spec/functional/resource/group_spec.rb +7 -5
  129. data/spec/functional/resource/remote_file_spec.rb +12 -1
  130. data/spec/functional/resource/user/dscl_spec.rb +198 -0
  131. data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +175 -37
  132. data/spec/integration/client/client_spec.rb +6 -4
  133. data/spec/integration/client/ipv6_spec.rb +16 -14
  134. data/spec/integration/knife/chef_fs_data_store_spec.rb +57 -46
  135. data/spec/integration/knife/chef_repo_path_spec.rb +105 -78
  136. data/spec/integration/knife/chef_repository_file_system_spec.rb +100 -84
  137. data/spec/integration/knife/chefignore_spec.rb +76 -46
  138. data/spec/integration/knife/common_options_spec.rb +16 -21
  139. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -3
  140. data/spec/integration/knife/delete_spec.rb +66 -46
  141. data/spec/integration/knife/deps_spec.rb +145 -94
  142. data/spec/integration/knife/diff_spec.rb +176 -110
  143. data/spec/integration/knife/download_spec.rb +229 -133
  144. data/spec/integration/knife/list_spec.rb +62 -54
  145. data/spec/integration/knife/raw_spec.rb +24 -9
  146. data/spec/integration/knife/redirection_spec.rb +2 -2
  147. data/spec/integration/knife/serve_spec.rb +2 -2
  148. data/spec/integration/knife/show_spec.rb +32 -26
  149. data/spec/integration/knife/upload_spec.rb +308 -165
  150. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +10 -8
  151. data/spec/integration/solo/solo_spec.rb +22 -11
  152. data/spec/spec_helper.rb +3 -0
  153. data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
  154. data/spec/support/platform_helpers.rb +12 -0
  155. data/spec/support/shared/functional/file_resource.rb +10 -0
  156. data/spec/support/shared/integration/chef_zero_support.rb +130 -0
  157. data/spec/support/shared/integration/integration_helper.rb +100 -98
  158. data/spec/support/shared/integration/knife_support.rb +0 -1
  159. data/spec/support/shared/unit/provider/file.rb +6 -4
  160. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +10 -1
  161. data/spec/unit/api_client/registration_spec.rb +83 -74
  162. data/spec/unit/application_spec.rb +32 -9
  163. data/spec/unit/cookbook/cookbook_version_loader_spec.rb +179 -0
  164. data/spec/unit/cookbook/metadata_spec.rb +190 -150
  165. data/spec/unit/cookbook/syntax_check_spec.rb +3 -2
  166. data/spec/unit/cookbook_loader_spec.rb +114 -53
  167. data/spec/unit/{cookbook_site_streaming_uploader.rb → cookbook_site_streaming_uploader_spec.rb} +21 -1
  168. data/spec/unit/data_bag_spec.rb +88 -13
  169. data/spec/unit/deprecation_spec.rb +1 -2
  170. data/spec/unit/encrypted_data_bag_item_spec.rb +145 -9
  171. data/spec/unit/environment_spec.rb +1 -1
  172. data/spec/unit/formatters/base_spec.rb +48 -0
  173. data/spec/unit/json_compat_spec.rb +48 -17
  174. data/spec/unit/knife/client_delete_spec.rb +4 -4
  175. data/spec/unit/knife/client_show_spec.rb +15 -5
  176. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -1
  177. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  178. data/spec/unit/knife/data_bag_from_file_spec.rb +0 -2
  179. data/spec/unit/knife/data_bag_show_spec.rb +23 -14
  180. data/spec/unit/knife/node_show_spec.rb +32 -15
  181. data/spec/unit/knife/role_show_spec.rb +59 -0
  182. data/spec/unit/platform_spec.rb +10 -0
  183. data/spec/unit/provider/deploy_spec.rb +4 -0
  184. data/spec/unit/provider/env_spec.rb +19 -0
  185. data/spec/unit/provider/git_spec.rb +22 -2
  186. data/spec/unit/provider/group/dscl_spec.rb +38 -1
  187. data/spec/unit/provider/group/pw_spec.rb +2 -2
  188. data/spec/unit/provider/http_request_spec.rb +8 -8
  189. data/spec/unit/provider/log_spec.rb +33 -53
  190. data/spec/unit/provider/mount/mount_spec.rb +12 -3
  191. data/spec/unit/provider/package/ips_spec.rb +96 -63
  192. data/spec/unit/provider/package/paludis_spec.rb +5 -5
  193. data/spec/unit/provider/package/rpm_spec.rb +12 -0
  194. data/spec/unit/provider/package/zypper_spec.rb +28 -16
  195. data/spec/unit/provider/service/windows_spec.rb +77 -17
  196. data/spec/unit/provider/user/dscl_spec.rb +659 -264
  197. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  198. data/spec/unit/recipe_spec.rb +41 -0
  199. data/spec/unit/resource/scm_spec.rb +11 -0
  200. data/spec/unit/resource/user_spec.rb +4 -0
  201. data/spec/unit/resource/windows_service_spec.rb +46 -0
  202. data/spec/unit/resource_collection_spec.rb +33 -0
  203. data/spec/unit/resource_reporter_spec.rb +48 -0
  204. data/spec/unit/resource_spec.rb +9 -2
  205. data/spec/unit/role_spec.rb +6 -0
  206. data/spec/unit/version_constraint_spec.rb +28 -0
  207. metadata +61 -4
@@ -150,7 +150,7 @@ class Chef
150
150
 
151
151
  converge_by("checkout ref #{sha_ref} branch #{@new_resource.revision}") do
152
152
  # checkout into a local branch rather than a detached HEAD
153
- shell_out!("git checkout -b #{@new_resource.checkout_branch} #{sha_ref}", run_options(:cwd => @new_resource.destination))
153
+ shell_out!("git checkout -B #{@new_resource.checkout_branch} #{sha_ref}", run_options(:cwd => @new_resource.destination))
154
154
  Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} onto: #{@new_resource.checkout_branch} reference: #{sha_ref}"
155
155
  end
156
156
  end
@@ -283,6 +283,7 @@ class Chef
283
283
  env['GIT_SSH'] = @new_resource.ssh_wrapper if @new_resource.ssh_wrapper
284
284
  run_opts[:log_tag] = @new_resource.to_s
285
285
  run_opts[:timeout] = @new_resource.timeout if @new_resource.timeout
286
+ env.merge!(@new_resource.environment) if @new_resource.environment
286
287
  run_opts[:environment] = env unless env.empty?
287
288
  run_opts
288
289
 
@@ -16,16 +16,18 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/provider/group/usermod'
19
+ require 'chef/provider/group/groupadd'
20
+ require 'chef/mixin/shell_out'
20
21
 
21
22
  class Chef
22
23
  class Provider
23
24
  class Group
24
- class Aix < Chef::Provider::Group::Usermod
25
+ class Aix < Chef::Provider::Group::Groupadd
25
26
 
26
27
  def required_binaries
27
28
  [ "/usr/bin/mkgroup",
28
29
  "/usr/bin/chgroup",
30
+ "/usr/bin/chgrpmem",
29
31
  "/usr/sbin/rmgroup" ]
30
32
  end
31
33
 
@@ -51,6 +53,19 @@ class Chef
51
53
  run_command(:command => "rmgroup #{@new_resource.group_name}")
52
54
  end
53
55
 
56
+ def add_member(member)
57
+ shell_out!("chgrpmem -m + #{member} #{@new_resource.group_name}")
58
+ end
59
+
60
+ def set_members(members)
61
+ return if members.empty?
62
+ shell_out!("chgrpmem -m = #{members.join(',')} #{@new_resource.group_name}")
63
+ end
64
+
65
+ def remove_member(member)
66
+ shell_out!("chgrpmem -m - #{member} #{@new_resource.group_name}")
67
+ end
68
+
54
69
  def set_options
55
70
  opts = ""
56
71
  { :gid => "id" }.sort { |a,b| a[0] <=> b[0] }.each do |field, option|
@@ -39,11 +39,33 @@ class Chef
39
39
  return result[2]
40
40
  end
41
41
 
42
- # This is handled in providers/group.rb by Etc.getgrnam()
43
- # def group_exists?(group)
44
- # groups = safe_dscl("list /Groups")
45
- # !! ( groups =~ Regexp.new("\n#{group}\n") )
46
- # end
42
+ def load_current_resource
43
+ @current_resource = Chef::Resource::Group.new(@new_resource.name)
44
+ @current_resource.group_name(@new_resource.name)
45
+ group_info = nil
46
+ begin
47
+ group_info = safe_dscl("read /Groups/#{@new_resource.name}")
48
+ rescue Chef::Exceptions::Group
49
+ @group_exists = false
50
+ Chef::Log.debug("#{@new_resource} group does not exist")
51
+ end
52
+
53
+ if group_info
54
+ group_info.each_line do |line|
55
+ key, val = line.split(': ')
56
+ val.strip! if val
57
+ case key.downcase
58
+ when 'primarygroupid'
59
+ @new_resource.gid(val) unless @new_resource.gid
60
+ @current_resource.gid(val)
61
+ when 'groupmembership'
62
+ @current_resource.members(val.split(' '))
63
+ end
64
+ end
65
+ end
66
+
67
+ @current_resource
68
+ end
47
69
 
48
70
  # get a free GID greater than 200
49
71
  def get_free_gid(search_limit=1000)
@@ -115,10 +137,6 @@ class Chef
115
137
  end
116
138
  end
117
139
 
118
- def load_current_resource
119
- super
120
- end
121
-
122
140
  def create_group
123
141
  dscl_create_group
124
142
  set_gid
@@ -39,7 +39,14 @@ class Chef
39
39
  def create_group
40
40
  command = "pw groupadd"
41
41
  command << set_options
42
- member_options = set_members_options
42
+
43
+ # pw group[add|mod] -M is used to set the full membership list on a
44
+ # new or existing group. Because pw groupadd does not support the -m
45
+ # and -d options used by manage_group, we treat group creation as a
46
+ # special case and use -M.
47
+ Chef::Log.debug("#{@new_resource} setting group members: #{@new_resource.members.join(',')}")
48
+ member_options = [" -M #{@new_resource.members.join(',')}"]
49
+
43
50
  if member_options.empty?
44
51
  run_command(:command => command)
45
52
  else
@@ -33,13 +33,13 @@ class Chef
33
33
  @http = Chef::HTTP::Simple.new(@new_resource.url)
34
34
  end
35
35
 
36
- # Send a HEAD request to @new_resource.url, with ?message=@new_resource.message
36
+ # Send a HEAD request to @new_resource.url
37
37
  def action_head
38
38
  message = check_message(@new_resource.message)
39
39
  # CHEF-4762: we expect a nil return value from Chef::HTTP for a "200 Success" response
40
40
  # and false for a "304 Not Modified" response
41
41
  modified = @http.head(
42
- "#{@new_resource.url}?message=#{message}",
42
+ "#{@new_resource.url}",
43
43
  @new_resource.headers
44
44
  )
45
45
  Chef::Log.info("#{@new_resource} HEAD to #{@new_resource.url} successful")
@@ -50,13 +50,13 @@ class Chef
50
50
  end
51
51
  end
52
52
 
53
- # Send a GET request to @new_resource.url, with ?message=@new_resource.message
53
+ # Send a GET request to @new_resource.url
54
54
  def action_get
55
55
  converge_by("#{@new_resource} GET to #{@new_resource.url}") do
56
56
 
57
57
  message = check_message(@new_resource.message)
58
58
  body = @http.get(
59
- "#{@new_resource.url}?message=#{message}",
59
+ "#{@new_resource.url}",
60
60
  @new_resource.headers
61
61
  )
62
62
  Chef::Log.info("#{@new_resource} GET to #{@new_resource.url} successful")
@@ -25,8 +25,9 @@ class Chef
25
25
  # Chef log provider, allows logging to chef's logs from recipes
26
26
  class ChefLog < Chef::Provider
27
27
 
28
- # ordered array of the log levels
29
- @@levels = [ :debug, :info, :warn, :error, :fatal ]
28
+ def whyrun_supported?
29
+ true
30
+ end
30
31
 
31
32
  # No concept of a 'current' resource for logs, this is a no-op
32
33
  #
@@ -42,18 +43,7 @@ class Chef
42
43
  # true:: Always return true
43
44
  def action_write
44
45
  Chef::Log.send(@new_resource.level, @new_resource.message)
45
-
46
- # resolve the integers for the current log levels
47
- global_level = Mixlib::Log::LEVELS.fetch(Chef::Log.level)
48
- resource_level = Mixlib::Log::LEVELS.fetch(@new_resource.level)
49
-
50
- # If the resource level is greater than or the same os the global
51
- # level, then it should have been written to the log. Mark the
52
- # resource as updated.
53
- if resource_level >= global_level
54
- @new_resource.updated_by_last_action(true)
55
- end
56
-
46
+ @new_resource.updated_by_last_action(true)
57
47
  end
58
48
 
59
49
  end
@@ -85,7 +85,7 @@ class Chef
85
85
 
86
86
  shell_out!("mount").stdout.each_line do |line|
87
87
  case line
88
- when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(real_mount_point)}/
88
+ when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(real_mount_point)}\s/
89
89
  mounted = true
90
90
  Chef::Log.debug("Special device #{device_logstring} mounted as #{real_mount_point}")
91
91
  when /^([\/\w])+\son\s#{Regexp.escape(real_mount_point)}\s+/
@@ -167,7 +167,7 @@ class Chef
167
167
 
168
168
  found = false
169
169
  ::File.readlines("/etc/fstab").reverse_each do |line|
170
- if !found && line =~ /^#{device_fstab_regex}\s+#{Regexp.escape(@new_resource.mount_point)}/
170
+ if !found && line =~ /^#{device_fstab_regex}\s+#{Regexp.escape(@new_resource.mount_point)}\s/
171
171
  found = true
172
172
  Chef::Log.debug("#{@new_resource} is removed from fstab")
173
173
  next
@@ -39,33 +39,27 @@ class Chef
39
39
  end
40
40
  end
41
41
 
42
- def load_current_resource
43
- @current_resource = Chef::Resource::Package.new(@new_resource.name)
44
- @current_resource.package_name(@new_resource.name)
45
- check_package_state(@new_resource.package_name)
46
- @current_resource
42
+ def get_current_version
43
+ shell_out("pkg info #{@new_resource.package_name}").stdout.each_line do |line|
44
+ return $1.split[0] if line =~ /^\s+Version: (.*)/
45
+ end
46
+ return nil
47
47
  end
48
48
 
49
- def check_package_state(package)
50
- Chef::Log.debug("Checking package status for #{package}")
51
- installed = false
52
- depends = false
53
-
54
- shell_out!("pkg info -r #{package}").stdout.each_line do |line|
55
- case line
56
- when /^\s+State: Installed/
57
- installed = true
58
- when /^\s+Version: (.*)/
59
- @candidate_version = $1.split[0]
60
- if installed
61
- @current_resource.version($1)
62
- else
63
- @current_resource.version(nil)
64
- end
65
- end
49
+ def get_candidate_version
50
+ shell_out!("pkg info -r #{new_resource.package_name}").stdout.each_line do |line|
51
+ return $1.split[0] if line =~ /Version: (.*)/
66
52
  end
53
+ return nil
54
+ end
67
55
 
68
- return installed
56
+ def load_current_resource
57
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
58
+ @current_resource.package_name(@new_resource.package_name)
59
+ Chef::Log.debug("Checking package status for #{@new_resource.name}")
60
+ @current_resource.version(get_current_version)
61
+ @candidate_version = get_candidate_version
62
+ @current_resource
69
63
  end
70
64
 
71
65
  def install_package(name, version)
@@ -34,7 +34,7 @@ class Chef
34
34
  installed = false
35
35
  re = Regexp.new('(.*)[[:blank:]](.*)[[:blank:]](.*)$')
36
36
 
37
- shell_out!("cave -L warning print-ids -m \"*/#{@new_resource.package_name.split('/').last}\" -f \"%c/%p %v %r\n\"").stdout.each_line do |line|
37
+ shell_out!("cave -L warning print-ids -M none -m \"*/#{@new_resource.package_name.split('/').last}\" -f \"%c/%p %v %r\n\"").stdout.each_line do |line|
38
38
  res = re.match(line)
39
39
  unless res.nil?
40
40
  case res[3]
@@ -59,7 +59,7 @@ class Chef
59
59
  else
60
60
  pkg = "#{@new_resource.package_name}"
61
61
  end
62
- shell_out!("cave -L warning resolve -x#{expand_options(@new_resource.options)} \"#{pkg}\"")
62
+ shell_out!("cave -L warning resolve -x#{expand_options(@new_resource.options)} \"#{pkg}\"",:timeout => @new_resource.timeout)
63
63
  end
64
64
 
65
65
  def upgrade_package(name, version)
@@ -60,7 +60,7 @@ class Chef
60
60
  status = popen4("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}") do |pid, stdin, stdout, stderr|
61
61
  stdout.each do |line|
62
62
  case line
63
- when /([\w\d+_.-]+)\s([\w\d_.-]+)/
63
+ when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
64
64
  @current_resource.package_name($1)
65
65
  @new_resource.version($2)
66
66
  @candidate_version = $2
@@ -78,7 +78,7 @@ class Chef
78
78
  @rpm_status = popen4("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
79
79
  stdout.each do |line|
80
80
  case line
81
- when /([\w\d+_.-]+)\s([\w\d_.-]+)/
81
+ when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
82
82
  Chef::Log.debug("#{@new_resource} current version is #{$2}")
83
83
  @current_resource.version($2)
84
84
  end
@@ -273,6 +273,8 @@ class Chef
273
273
  @platform_cache ||= {}
274
274
  end
275
275
 
276
+ include Chef::Mixin::ShellOut
277
+
276
278
  attr_reader :gem_binary_location
277
279
 
278
280
  def initialize(gem_binary_location)
@@ -19,6 +19,7 @@
19
19
  require 'chef/config'
20
20
  require 'chef/provider/package'
21
21
  require 'chef/mixin/command'
22
+ require 'chef/mixin/shell_out'
22
23
  require 'chef/resource/package'
23
24
  require 'singleton'
24
25
  require 'chef/mixin/get_source_from_package'
@@ -645,6 +646,7 @@ class Chef
645
646
  # Cache for our installed and available packages, pulled in from yum-dump.py
646
647
  class YumCache
647
648
  include Chef::Mixin::Command
649
+ include Chef::Mixin::ShellOut
648
650
  include Singleton
649
651
 
650
652
  def initialize
@@ -103,7 +103,7 @@ class Chef
103
103
 
104
104
  private
105
105
  def zypper_package(command, pkgname, version)
106
- version = "=#{version}" unless version.empty?
106
+ version = "=#{version}" unless version.nil? || version.empty?
107
107
  if zypper_version < 1.0
108
108
  shell_out!("zypper#{gpg_checks} #{command} -y #{pkgname}")
109
109
  else
@@ -139,8 +139,8 @@ class Chef
139
139
  end
140
140
 
141
141
  def load_data
142
- Chef::JSONCompat.from_json(load_json_data)
143
- rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError, JSON::ParserError
142
+ Chef::JSONCompat.parse(load_json_data)
143
+ rescue Chef::Exceptions::FileNotFound, Chef::Exceptions::JSON::ParseError
144
144
  false
145
145
  end
146
146
 
@@ -27,6 +27,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
27
27
 
28
28
  #Win32::Service.get_start_type
29
29
  AUTO_START = 'auto start'
30
+ MANUAL = 'demand start'
30
31
  DISABLED = 'disabled'
31
32
 
32
33
  #Win32::Service.get_current_state
@@ -45,11 +46,16 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
45
46
  end
46
47
 
47
48
  def load_current_resource
48
- @current_resource = Chef::Resource::Service.new(@new_resource.name)
49
+ @current_resource = Chef::Resource::WindowsService.new(@new_resource.name)
49
50
  @current_resource.service_name(@new_resource.service_name)
50
51
  @current_resource.running(current_state == RUNNING)
51
52
  Chef::Log.debug "#{@new_resource} running: #{@current_resource.running}"
52
- @current_resource.enabled(start_type == AUTO_START)
53
+ case current_start_type
54
+ when AUTO_START
55
+ @current_resource.enabled(true)
56
+ when DISABLED
57
+ @current_resource.enabled(false)
58
+ end
53
59
  Chef::Log.debug "#{@new_resource} enabled: #{@current_resource.enabled}"
54
60
  @current_resource
55
61
  end
@@ -125,15 +131,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
125
131
 
126
132
  def enable_service
127
133
  if Win32::Service.exists?(@new_resource.service_name)
128
- if start_type == AUTO_START
129
- Chef::Log.debug "#{@new_resource} already enabled - nothing to do"
130
- else
131
- Win32::Service.configure(
132
- :service_name => @new_resource.service_name,
133
- :start_type => Win32::Service::AUTO_START
134
- )
135
- @new_resource.updated_by_last_action(true)
136
- end
134
+ set_startup_type(:automatic)
137
135
  else
138
136
  Chef::Log.debug "#{@new_resource} does not exist - nothing to do"
139
137
  end
@@ -141,26 +139,76 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
141
139
 
142
140
  def disable_service
143
141
  if Win32::Service.exists?(@new_resource.service_name)
144
- if start_type == AUTO_START
145
- Win32::Service.configure(
146
- :service_name => @new_resource.service_name,
147
- :start_type => Win32::Service::DISABLED
148
- )
149
- @new_resource.updated_by_last_action(true)
150
- else
151
- Chef::Log.debug "#{@new_resource} already disabled - nothing to do"
152
- end
142
+ set_startup_type(:disabled)
153
143
  else
154
144
  Chef::Log.debug "#{@new_resource} does not exist - nothing to do"
155
145
  end
156
146
  end
157
147
 
148
+ def action_enable
149
+ if current_start_type != AUTO_START
150
+ converge_by("enable service #{@new_resource}") do
151
+ enable_service
152
+ Chef::Log.info("#{@new_resource} enabled")
153
+ end
154
+ else
155
+ Chef::Log.debug("#{@new_resource} already enabled - nothing to do")
156
+ end
157
+ load_new_resource_state
158
+ @new_resource.enabled(true)
159
+ end
160
+
161
+ def action_disable
162
+ if current_start_type != DISABLED
163
+ converge_by("disable service #{@new_resource}") do
164
+ disable_service
165
+ Chef::Log.info("#{@new_resource} disabled")
166
+ end
167
+ else
168
+ Chef::Log.debug("#{@new_resource} already disabled - nothing to do")
169
+ end
170
+ load_new_resource_state
171
+ @new_resource.enabled(false)
172
+ end
173
+
174
+ def action_configure_startup
175
+ case @new_resource.startup_type
176
+ when :automatic
177
+ if current_start_type != AUTO_START
178
+ converge_by("set service #{@new_resource} startup type to automatic") do
179
+ set_startup_type(:automatic)
180
+ end
181
+ else
182
+ Chef::Log.debug("#{@new_resource} startup_type already automatic - nothing to do")
183
+ end
184
+ when :manual
185
+ if current_start_type != MANUAL
186
+ converge_by("set service #{@new_resource} startup type to manual") do
187
+ set_startup_type(:manual)
188
+ end
189
+ else
190
+ Chef::Log.debug("#{@new_resource} startup_type already manual - nothing to do")
191
+ end
192
+ when :disabled
193
+ if current_start_type != DISABLED
194
+ converge_by("set service #{@new_resource} startup type to disabled") do
195
+ set_startup_type(:disabled)
196
+ end
197
+ else
198
+ Chef::Log.debug("#{@new_resource} startup_type already disabled - nothing to do")
199
+ end
200
+ end
201
+
202
+ # Avoid changing enabled from true/false for now
203
+ @new_resource.enabled(nil)
204
+ end
205
+
158
206
  private
159
207
  def current_state
160
208
  Win32::Service.status(@new_resource.service_name).current_state
161
209
  end
162
210
 
163
- def start_type
211
+ def current_start_type
164
212
  Win32::Service.config_info(@new_resource.service_name).start_type
165
213
  end
166
214
 
@@ -188,4 +236,22 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
188
236
  worker.join
189
237
  end
190
238
  end
239
+
240
+ # Takes Win32::Service start_types
241
+ def set_startup_type(type)
242
+ # Set-Service Startup Type => Win32::Service Constant
243
+ allowed_types = { :automatic => Win32::Service::AUTO_START,
244
+ :manual => Win32::Service::DEMAND_START,
245
+ :disabled => Win32::Service::DISABLED }
246
+ unless allowed_types.keys.include?(type)
247
+ raise Chef::Exceptions::ConfigurationError, "#{@new_resource.name}: Startup type '#{type}' is not supported"
248
+ end
249
+
250
+ Chef::Log.debug "#{@new_resource.name} setting start_type to #{type}"
251
+ Win32::Service.configure(
252
+ :service_name => @new_resource.service_name,
253
+ :start_type => allowed_types[type]
254
+ )
255
+ @new_resource.updated_by_last_action(true)
256
+ end
191
257
  end