microwave 0.1004.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 (206) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +102 -0
  3. data/bin/chef-solo +25 -0
  4. data/lib/chef.rb +41 -0
  5. data/lib/chef/application.rb +147 -0
  6. data/lib/chef/application/solo.rb +181 -0
  7. data/lib/chef/applications.rb +1 -0
  8. data/lib/chef/checksum.rb +83 -0
  9. data/lib/chef/checksum_cache.rb +189 -0
  10. data/lib/chef/client.rb +325 -0
  11. data/lib/chef/config.rb +152 -0
  12. data/lib/chef/cookbook/chefignore.rb +66 -0
  13. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  14. data/lib/chef/cookbook/cookbook_version_loader.rb +173 -0
  15. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  16. data/lib/chef/cookbook/file_vendor.rb +48 -0
  17. data/lib/chef/cookbook/metadata.rb +629 -0
  18. data/lib/chef/cookbook/syntax_check.rb +136 -0
  19. data/lib/chef/cookbook_loader.rb +121 -0
  20. data/lib/chef/cookbook_version.rb +786 -0
  21. data/lib/chef/cookbook_version_selector.rb +151 -0
  22. data/lib/chef/environment.rb +267 -0
  23. data/lib/chef/exceptions.rb +150 -0
  24. data/lib/chef/file_access_control.rb +144 -0
  25. data/lib/chef/file_cache.rb +218 -0
  26. data/lib/chef/handler.rb +206 -0
  27. data/lib/chef/handler/error_report.rb +33 -0
  28. data/lib/chef/handler/json_file.rb +58 -0
  29. data/lib/chef/json_compat.rb +52 -0
  30. data/lib/chef/log.rb +39 -0
  31. data/lib/chef/mash.rb +211 -0
  32. data/lib/chef/mixin/check_helper.rb +31 -0
  33. data/lib/chef/mixin/checksum.rb +32 -0
  34. data/lib/chef/mixin/command.rb +221 -0
  35. data/lib/chef/mixin/command/unix.rb +215 -0
  36. data/lib/chef/mixin/command/windows.rb +76 -0
  37. data/lib/chef/mixin/convert_to_class_name.rb +63 -0
  38. data/lib/chef/mixin/create_path.rb +57 -0
  39. data/lib/chef/mixin/deep_merge.rb +225 -0
  40. data/lib/chef/mixin/deprecation.rb +65 -0
  41. data/lib/chef/mixin/from_file.rb +50 -0
  42. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  43. data/lib/chef/mixin/language.rb +125 -0
  44. data/lib/chef/mixin/language_include_attribute.rb +61 -0
  45. data/lib/chef/mixin/language_include_recipe.rb +52 -0
  46. data/lib/chef/mixin/params_validate.rb +225 -0
  47. data/lib/chef/mixin/recipe_definition_dsl_core.rb +78 -0
  48. data/lib/chef/mixin/shell_out.rb +41 -0
  49. data/lib/chef/mixin/template.rb +95 -0
  50. data/lib/chef/mixin/xml_escape.rb +140 -0
  51. data/lib/chef/mixins.rb +15 -0
  52. data/lib/chef/monkey_patches/dir.rb +36 -0
  53. data/lib/chef/monkey_patches/numeric.rb +15 -0
  54. data/lib/chef/monkey_patches/object.rb +9 -0
  55. data/lib/chef/monkey_patches/regexp.rb +34 -0
  56. data/lib/chef/monkey_patches/string.rb +49 -0
  57. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  58. data/lib/chef/nil_argument.rb +3 -0
  59. data/lib/chef/node.rb +469 -0
  60. data/lib/chef/node/attribute.rb +487 -0
  61. data/lib/chef/platform.rb +409 -0
  62. data/lib/chef/provider.rb +124 -0
  63. data/lib/chef/provider/breakpoint.rb +31 -0
  64. data/lib/chef/provider/cookbook_file.rb +100 -0
  65. data/lib/chef/provider/cron.rb +186 -0
  66. data/lib/chef/provider/cron/solaris.rb +195 -0
  67. data/lib/chef/provider/deploy.rb +343 -0
  68. data/lib/chef/provider/deploy/revision.rb +80 -0
  69. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  70. data/lib/chef/provider/directory.rb +72 -0
  71. data/lib/chef/provider/env.rb +152 -0
  72. data/lib/chef/provider/env/windows.rb +75 -0
  73. data/lib/chef/provider/erl_call.rb +101 -0
  74. data/lib/chef/provider/execute.rb +66 -0
  75. data/lib/chef/provider/file.rb +222 -0
  76. data/lib/chef/provider/git.rb +243 -0
  77. data/lib/chef/provider/group.rb +133 -0
  78. data/lib/chef/provider/group/aix.rb +70 -0
  79. data/lib/chef/provider/group/dscl.rb +121 -0
  80. data/lib/chef/provider/group/gpasswd.rb +53 -0
  81. data/lib/chef/provider/group/groupadd.rb +81 -0
  82. data/lib/chef/provider/group/pw.rb +84 -0
  83. data/lib/chef/provider/group/suse.rb +53 -0
  84. data/lib/chef/provider/group/usermod.rb +57 -0
  85. data/lib/chef/provider/group/windows.rb +79 -0
  86. data/lib/chef/provider/ifconfig.rb +134 -0
  87. data/lib/chef/provider/link.rb +164 -0
  88. data/lib/chef/provider/log.rb +54 -0
  89. data/lib/chef/provider/mdadm.rb +91 -0
  90. data/lib/chef/provider/mount.rb +114 -0
  91. data/lib/chef/provider/mount/mount.rb +240 -0
  92. data/lib/chef/provider/mount/windows.rb +81 -0
  93. data/lib/chef/provider/ohai.rb +42 -0
  94. data/lib/chef/provider/package.rb +163 -0
  95. data/lib/chef/provider/package/apt.rb +135 -0
  96. data/lib/chef/provider/package/dpkg.rb +115 -0
  97. data/lib/chef/provider/package/easy_install.rb +136 -0
  98. data/lib/chef/provider/package/freebsd.rb +125 -0
  99. data/lib/chef/provider/package/macports.rb +105 -0
  100. data/lib/chef/provider/package/pacman.rb +101 -0
  101. data/lib/chef/provider/package/portage.rb +135 -0
  102. data/lib/chef/provider/package/rpm.rb +104 -0
  103. data/lib/chef/provider/package/rubygems.rb +465 -0
  104. data/lib/chef/provider/package/solaris.rb +130 -0
  105. data/lib/chef/provider/package/yum-dump.py +286 -0
  106. data/lib/chef/provider/package/yum.rb +1128 -0
  107. data/lib/chef/provider/package/zypper.rb +144 -0
  108. data/lib/chef/provider/remote_directory.rb +137 -0
  109. data/lib/chef/provider/route.rb +193 -0
  110. data/lib/chef/provider/ruby_block.rb +34 -0
  111. data/lib/chef/provider/script.rb +55 -0
  112. data/lib/chef/provider/service.rb +122 -0
  113. data/lib/chef/provider/service/arch.rb +116 -0
  114. data/lib/chef/provider/service/debian.rb +130 -0
  115. data/lib/chef/provider/service/freebsd.rb +154 -0
  116. data/lib/chef/provider/service/gentoo.rb +53 -0
  117. data/lib/chef/provider/service/init.rb +71 -0
  118. data/lib/chef/provider/service/insserv.rb +52 -0
  119. data/lib/chef/provider/service/redhat.rb +60 -0
  120. data/lib/chef/provider/service/simple.rb +120 -0
  121. data/lib/chef/provider/service/solaris.rb +85 -0
  122. data/lib/chef/provider/service/systemd.rb +102 -0
  123. data/lib/chef/provider/service/upstart.rb +198 -0
  124. data/lib/chef/provider/service/windows.rb +146 -0
  125. data/lib/chef/provider/subversion.rb +197 -0
  126. data/lib/chef/provider/template.rb +104 -0
  127. data/lib/chef/provider/user.rb +186 -0
  128. data/lib/chef/provider/user/dscl.rb +280 -0
  129. data/lib/chef/provider/user/pw.rb +113 -0
  130. data/lib/chef/provider/user/useradd.rb +137 -0
  131. data/lib/chef/provider/user/windows.rb +124 -0
  132. data/lib/chef/providers.rb +93 -0
  133. data/lib/chef/recipe.rb +129 -0
  134. data/lib/chef/resource.rb +584 -0
  135. data/lib/chef/resource/apt_package.rb +34 -0
  136. data/lib/chef/resource/bash.rb +33 -0
  137. data/lib/chef/resource/breakpoint.rb +35 -0
  138. data/lib/chef/resource/cookbook_file.rb +45 -0
  139. data/lib/chef/resource/cron.rb +188 -0
  140. data/lib/chef/resource/csh.rb +33 -0
  141. data/lib/chef/resource/deploy.rb +380 -0
  142. data/lib/chef/resource/deploy_revision.rb +40 -0
  143. data/lib/chef/resource/directory.rb +89 -0
  144. data/lib/chef/resource/dpkg_package.rb +34 -0
  145. data/lib/chef/resource/easy_install_package.rb +57 -0
  146. data/lib/chef/resource/env.rb +58 -0
  147. data/lib/chef/resource/erl_call.rb +83 -0
  148. data/lib/chef/resource/execute.rb +127 -0
  149. data/lib/chef/resource/file.rb +112 -0
  150. data/lib/chef/resource/freebsd_package.rb +35 -0
  151. data/lib/chef/resource/gem_package.rb +53 -0
  152. data/lib/chef/resource/git.rb +46 -0
  153. data/lib/chef/resource/group.rb +70 -0
  154. data/lib/chef/resource/ifconfig.rb +134 -0
  155. data/lib/chef/resource/link.rb +105 -0
  156. data/lib/chef/resource/log.rb +62 -0
  157. data/lib/chef/resource/macports_package.rb +29 -0
  158. data/lib/chef/resource/mdadm.rb +82 -0
  159. data/lib/chef/resource/mount.rb +134 -0
  160. data/lib/chef/resource/ohai.rb +40 -0
  161. data/lib/chef/resource/package.rb +80 -0
  162. data/lib/chef/resource/pacman_package.rb +33 -0
  163. data/lib/chef/resource/perl.rb +33 -0
  164. data/lib/chef/resource/portage_package.rb +33 -0
  165. data/lib/chef/resource/python.rb +33 -0
  166. data/lib/chef/resource/remote_directory.rb +109 -0
  167. data/lib/chef/resource/route.rb +135 -0
  168. data/lib/chef/resource/rpm_package.rb +34 -0
  169. data/lib/chef/resource/ruby.rb +33 -0
  170. data/lib/chef/resource/ruby_block.rb +40 -0
  171. data/lib/chef/resource/scm.rb +147 -0
  172. data/lib/chef/resource/script.rb +60 -0
  173. data/lib/chef/resource/service.rb +160 -0
  174. data/lib/chef/resource/solaris_package.rb +36 -0
  175. data/lib/chef/resource/subversion.rb +36 -0
  176. data/lib/chef/resource/template.rb +69 -0
  177. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  178. data/lib/chef/resource/user.rb +130 -0
  179. data/lib/chef/resource/yum_package.rb +63 -0
  180. data/lib/chef/resource_collection.rb +217 -0
  181. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  182. data/lib/chef/resource_definition.rb +67 -0
  183. data/lib/chef/resource_definition_list.rb +38 -0
  184. data/lib/chef/resources.rb +62 -0
  185. data/lib/chef/role.rb +225 -0
  186. data/lib/chef/run_context.rb +126 -0
  187. data/lib/chef/run_list.rb +161 -0
  188. data/lib/chef/run_list/run_list_expansion.rb +159 -0
  189. data/lib/chef/run_list/run_list_item.rb +92 -0
  190. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  191. data/lib/chef/run_status.rb +121 -0
  192. data/lib/chef/runner.rb +105 -0
  193. data/lib/chef/shell_out.rb +250 -0
  194. data/lib/chef/shell_out/unix.rb +223 -0
  195. data/lib/chef/shell_out/windows.rb +98 -0
  196. data/lib/chef/tasks/chef_repo.rake +330 -0
  197. data/lib/chef/util/file_edit.rb +122 -0
  198. data/lib/chef/util/windows.rb +56 -0
  199. data/lib/chef/util/windows/net_group.rb +101 -0
  200. data/lib/chef/util/windows/net_use.rb +121 -0
  201. data/lib/chef/util/windows/net_user.rb +198 -0
  202. data/lib/chef/util/windows/volume.rb +59 -0
  203. data/lib/chef/version.rb +23 -0
  204. data/lib/chef/version_class.rb +70 -0
  205. data/lib/chef/version_constraint.rb +116 -0
  206. metadata +493 -0
@@ -0,0 +1,124 @@
1
+ #
2
+ # Author:: Doug MacEachern (<dougm@vmware.com>)
3
+ # Copyright:: Copyright (c) 2010 VMware, 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/user'
20
+ if RUBY_PLATFORM =~ /mswin|mingw32|windows/
21
+ require 'chef/util/windows/net_user'
22
+ end
23
+
24
+ class Chef
25
+ class Provider
26
+ class User
27
+ class Windows < Chef::Provider::User
28
+
29
+ def initialize(new_resource,run_context)
30
+ super
31
+ @net_user = Chef::Util::Windows::NetUser.new(@new_resource.name)
32
+ end
33
+
34
+ def load_current_resource
35
+ @current_resource = Chef::Resource::User.new(@new_resource.name)
36
+ @current_resource.username(@new_resource.username)
37
+ user_info = nil
38
+ begin
39
+ user_info = @net_user.get_info
40
+ rescue
41
+ @user_exists = false
42
+ Chef::Log.debug("#{@new_resource} does not exist")
43
+ end
44
+
45
+ if user_info
46
+ @current_resource.uid(user_info[:user_id])
47
+ @current_resource.gid(user_info[:primary_group_id])
48
+ @current_resource.comment(user_info[:full_name])
49
+ @current_resource.home(user_info[:home_dir])
50
+ @current_resource.shell(user_info[:script_path])
51
+ end
52
+
53
+ @current_resource
54
+ end
55
+
56
+ # Check to see if the user needs any changes
57
+ #
58
+ # === Returns
59
+ # <true>:: If a change is required
60
+ # <false>:: If the users are identical
61
+ def compare_user
62
+ unless @net_user.validate_credentials(@new_resource.password)
63
+ Chef::Log.debug("#{@new_resource} password has changed")
64
+ return true
65
+ end
66
+ [ :uid, :gid, :comment, :home, :shell ].any? do |user_attrib|
67
+ !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
68
+ end
69
+ end
70
+
71
+ def create_user
72
+ @net_user.add(set_options)
73
+ end
74
+
75
+ def manage_user
76
+ @net_user.update(set_options)
77
+ end
78
+
79
+ def remove_user
80
+ @net_user.delete
81
+ end
82
+
83
+ def check_lock
84
+ @net_user.check_enabled
85
+ end
86
+
87
+ def lock_user
88
+ @net_user.disable_account
89
+ end
90
+
91
+ def unlock_user
92
+ @net_user.enable_account
93
+ end
94
+
95
+ def set_options
96
+ opts = {:name => @new_resource.username}
97
+
98
+ field_list = {
99
+ 'comment' => 'full_name',
100
+ 'home' => 'home_dir',
101
+ 'gid' => 'primary_group_id',
102
+ 'uid' => 'user_id',
103
+ 'shell' => 'script_path',
104
+ 'password' => 'password'
105
+ }
106
+
107
+ field_list.sort{ |a,b| a[0] <=> b[0] }.each do |field, option|
108
+ field_symbol = field.to_sym
109
+ if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
110
+ if @new_resource.send(field_symbol)
111
+ unless field_symbol == :password
112
+ Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field_symbol)}")
113
+ end
114
+ opts[option.to_sym] = @new_resource.send(field_symbol)
115
+ end
116
+ end
117
+ end
118
+ opts
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,93 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2010 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/breakpoint'
20
+ require 'chef/provider/cookbook_file'
21
+ require 'chef/provider/cron'
22
+ require 'chef/provider/cron/solaris'
23
+ require 'chef/provider/deploy'
24
+ require 'chef/provider/directory'
25
+ require 'chef/provider/env'
26
+ require 'chef/provider/erl_call'
27
+ require 'chef/provider/execute'
28
+ require 'chef/provider/file'
29
+ require 'chef/provider/git'
30
+ require 'chef/provider/group'
31
+ require 'chef/provider/ifconfig'
32
+ require 'chef/provider/link'
33
+ require 'chef/provider/log'
34
+ require 'chef/provider/ohai'
35
+ require 'chef/provider/mdadm'
36
+ require 'chef/provider/mount'
37
+ require 'chef/provider/package'
38
+ require 'chef/provider/remote_directory'
39
+ require 'chef/provider/route'
40
+ require 'chef/provider/ruby_block'
41
+ require 'chef/provider/script'
42
+ require 'chef/provider/service'
43
+ require 'chef/provider/subversion'
44
+ require 'chef/provider/template'
45
+ require 'chef/provider/user'
46
+
47
+ require 'chef/provider/env/windows'
48
+
49
+ require 'chef/provider/package/apt'
50
+ require 'chef/provider/package/dpkg'
51
+ require 'chef/provider/package/easy_install'
52
+ require 'chef/provider/package/freebsd'
53
+ require 'chef/provider/package/macports'
54
+ require 'chef/provider/package/pacman'
55
+ require 'chef/provider/package/portage'
56
+ require 'chef/provider/package/rpm'
57
+ require 'chef/provider/package/rubygems'
58
+ require 'chef/provider/package/yum'
59
+ require 'chef/provider/package/zypper'
60
+ require 'chef/provider/package/solaris'
61
+
62
+ require 'chef/provider/service/arch'
63
+ require 'chef/provider/service/debian'
64
+ require 'chef/provider/service/freebsd'
65
+ require 'chef/provider/service/gentoo'
66
+ require 'chef/provider/service/init'
67
+ require 'chef/provider/service/insserv'
68
+ require 'chef/provider/service/redhat'
69
+ require 'chef/provider/service/simple'
70
+ require 'chef/provider/service/systemd'
71
+ require 'chef/provider/service/upstart'
72
+ require 'chef/provider/service/windows'
73
+ require 'chef/provider/service/solaris'
74
+
75
+ require 'chef/provider/user/dscl'
76
+ require 'chef/provider/user/pw'
77
+ require 'chef/provider/user/useradd'
78
+ require 'chef/provider/user/windows'
79
+
80
+ require 'chef/provider/group/aix'
81
+ require 'chef/provider/group/dscl'
82
+ require 'chef/provider/group/gpasswd'
83
+ require 'chef/provider/group/groupadd'
84
+ require 'chef/provider/group/pw'
85
+ require 'chef/provider/group/suse'
86
+ require 'chef/provider/group/usermod'
87
+ require 'chef/provider/group/windows'
88
+
89
+ require 'chef/provider/mount/mount'
90
+ require 'chef/provider/mount/windows'
91
+
92
+ require 'chef/provider/deploy/revision'
93
+ require 'chef/provider/deploy/timestamped'
@@ -0,0 +1,129 @@
1
+ #--
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ require 'chef/mixin/recipe_definition_dsl_core'
22
+ require 'chef/mixin/from_file'
23
+ require 'chef/mixin/language'
24
+ require 'chef/mixin/language_include_recipe'
25
+
26
+ require 'chef/mixin/deprecation'
27
+
28
+ class Chef
29
+ # == Chef::Recipe
30
+ # A Recipe object is the context in which Chef recipes are evaluated.
31
+ class Recipe
32
+
33
+ include Chef::Mixin::FromFile
34
+ include Chef::Mixin::Language
35
+ include Chef::Mixin::LanguageIncludeRecipe
36
+ include Chef::Mixin::RecipeDefinitionDSLCore
37
+ include Chef::Mixin::Deprecation
38
+
39
+ attr_accessor :cookbook_name, :recipe_name, :recipe, :params, :run_context
40
+
41
+ # Parses a potentially fully-qualified recipe name into its
42
+ # cookbook name and recipe short name.
43
+ #
44
+ # For example:
45
+ # "aws::elastic_ip" returns [:aws, "elastic_ip"]
46
+ # "aws" returns [:aws, "default"]
47
+ #--
48
+ # TODO: Duplicates functionality of RunListItem
49
+ def self.parse_recipe_name(recipe_name)
50
+ rmatch = recipe_name.match(/(.+?)::(.+)/)
51
+ if rmatch
52
+ [ rmatch[1].to_sym, rmatch[2] ]
53
+ else
54
+ [ recipe_name.to_sym, "default" ]
55
+ end
56
+ end
57
+
58
+ def initialize(cookbook_name, recipe_name, run_context)
59
+ @cookbook_name = cookbook_name
60
+ @recipe_name = recipe_name
61
+ @run_context = run_context
62
+ # TODO: 5/19/2010 cw/tim: determine whether this can be removed
63
+ @params = Hash.new
64
+ @node = deprecated_ivar(run_context.node, :node, :warn)
65
+ end
66
+
67
+ # Used in DSL mixins
68
+ def node
69
+ run_context.node
70
+ end
71
+
72
+ # Used by the DSL to look up resources when executing in the context of a
73
+ # recipe.
74
+ def resources(*args)
75
+ run_context.resource_collection.find(*args)
76
+ end
77
+
78
+ # Sets a tag, or list of tags, for this node. Syntactic sugar for
79
+ # run_context.node[:tags].
80
+ #
81
+ # With no arguments, returns the list of tags.
82
+ #
83
+ # === Parameters
84
+ # tags<Array>:: A list of tags to add - can be a single string
85
+ #
86
+ # === Returns
87
+ # tags<Array>:: The contents of run_context.node[:tags]
88
+ def tag(*tags)
89
+ if tags.length > 0
90
+ tags.each do |tag|
91
+ tag = tag.to_s
92
+ run_context.node[:tags] << tag unless run_context.node[:tags].include?(tag)
93
+ end
94
+ run_context.node[:tags]
95
+ else
96
+ run_context.node[:tags]
97
+ end
98
+ end
99
+
100
+ # Returns true if the node is tagged with *all* of the supplied +tags+.
101
+ #
102
+ # === Parameters
103
+ # tags<Array>:: A list of tags
104
+ #
105
+ # === Returns
106
+ # true<TrueClass>:: If all the parameters are present
107
+ # false<FalseClass>:: If any of the parameters are missing
108
+ def tagged?(*tags)
109
+ tags.each do |tag|
110
+ return false unless run_context.node[:tags].include?(tag)
111
+ end
112
+ true
113
+ end
114
+
115
+ # Removes the list of tags from the node.
116
+ #
117
+ # === Parameters
118
+ # tags<Array>:: A list of tags
119
+ #
120
+ # === Returns
121
+ # tags<Array>:: The current list of run_context.node[:tags]
122
+ def untag(*tags)
123
+ tags.each do |tag|
124
+ run_context.node[:tags].delete(tag)
125
+ end
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,584 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/mixin/params_validate'
21
+ require 'chef/mixin/check_helper'
22
+ require 'chef/mixin/language'
23
+ require 'chef/mixin/convert_to_class_name'
24
+ require 'chef/mixin/command'
25
+ require 'chef/resource_collection'
26
+ require 'chef/node'
27
+
28
+ require 'chef/mixin/deprecation'
29
+
30
+ class Chef
31
+ class Resource
32
+ class Notification < Struct.new(:resource, :action, :notifying_resource)
33
+
34
+ def duplicates?(other_notification)
35
+ unless other_notification.respond_to?(:resource) && other_notification.respond_to?(:action)
36
+ msg = "only duck-types of Chef::Resource::Notification can be checked for duplication "\
37
+ "you gave #{other_notification.inspect}"
38
+ raise ArgumentError, msg
39
+ end
40
+ other_notification.resource == resource && other_notification.action == action
41
+ end
42
+
43
+ def resolve_resource_reference(resource_collection)
44
+ return resource if resource.kind_of?(Chef::Resource)
45
+
46
+ matching_resource = resource_collection.find(resource)
47
+ if Array(matching_resource).size > 1
48
+ msg = "Notification #{self} from #{notifying_resource} was created with a reference to multiple resources, "\
49
+ "but can only notify one resource. Notifying resource was defined on #{notifying_resource.source_line}"
50
+ raise Chef::Exceptions::InvalidResourceReference, msg
51
+ end
52
+ self.resource = matching_resource
53
+ rescue Chef::Exceptions::ResourceNotFound => e
54
+ err = Chef::Exceptions::ResourceNotFound.new(<<-FAIL)
55
+ Resource #{notifying_resource} is configured to notify resource #{resource} with action #{action}, \
56
+ but #{resource} cannot be found in the resource collection. #{notifying_resource} is defined in \
57
+ #{notifying_resource.source_line}
58
+ FAIL
59
+ err.set_backtrace(e.backtrace)
60
+ raise err
61
+ rescue Chef::Exceptions::InvalidResourceSpecification => e
62
+ err = Chef::Exceptions::InvalidResourceSpecification.new(<<-F)
63
+ Resource #{notifying_resource} is configured to notify resource #{resource} with action #{action}, \
64
+ but #{resource.inspect} is not valid syntax to look up a resource in the resource collection. Notification \
65
+ is defined near #{notifying_resource.source_line}
66
+ F
67
+ err.set_backtrace(e.backtrace)
68
+ raise err
69
+ end
70
+
71
+ end
72
+
73
+ FORBIDDEN_IVARS = [:@run_context, :@node]
74
+ HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@node]
75
+
76
+ include Chef::Mixin::CheckHelper
77
+ include Chef::Mixin::ParamsValidate
78
+ include Chef::Mixin::Language
79
+ include Chef::Mixin::ConvertToClassName
80
+ include Chef::Mixin::Deprecation
81
+
82
+ attr_accessor :params
83
+ attr_accessor :provider
84
+ attr_accessor :allowed_actions
85
+ attr_accessor :run_context
86
+ attr_accessor :cookbook_name
87
+ attr_accessor :recipe_name
88
+ attr_accessor :enclosing_provider
89
+ attr_accessor :source_line
90
+ attr_accessor :retries
91
+ attr_accessor :retry_delay
92
+
93
+ attr_reader :updated
94
+
95
+ attr_reader :resource_name
96
+ attr_reader :not_if_args
97
+ attr_reader :only_if_args
98
+
99
+ # Each notify entry is a resource/action pair, modeled as an
100
+ # Struct with a #resource and #action member
101
+ attr_reader :immediate_notifications
102
+ attr_reader :delayed_notifications
103
+
104
+ def initialize(name, run_context=nil)
105
+ @name = name
106
+ @run_context = run_context
107
+ @noop = nil
108
+ @before = nil
109
+ @params = Hash.new
110
+ @provider = nil
111
+ @allowed_actions = [ :nothing ]
112
+ @action = :nothing
113
+ @updated = false
114
+ @updated_by_last_action = false
115
+ @supports = {}
116
+ @ignore_failure = false
117
+ @retries = 0
118
+ @retry_delay = 2
119
+ @not_if = nil
120
+ @not_if_args = {}
121
+ @only_if = nil
122
+ @only_if_args = {}
123
+ @immediate_notifications = Array.new
124
+ @delayed_notifications = Array.new
125
+ @source_line = nil
126
+
127
+ @node = run_context ? deprecated_ivar(run_context.node, :node, :warn) : nil
128
+ end
129
+
130
+ def updated=(true_or_false)
131
+ Chef::Log.warn("Chef::Resource#updated=(true|false) is deprecated. Please call #updated_by_last_action(true|false) instead.")
132
+ Chef::Log.warn("Called from:")
133
+ caller[0..3].each {|line| Chef::Log.warn(line)}
134
+ updated_by_last_action(true_or_false)
135
+ @updated = true_or_false
136
+ end
137
+
138
+ def node
139
+ run_context && run_context.node
140
+ end
141
+
142
+ # If an unknown method is invoked, determine whether the enclosing Provider's
143
+ # lexical scope can fulfill the request. E.g. This happens when the Resource's
144
+ # block invokes new_resource.
145
+ def method_missing(method_symbol, *args, &block)
146
+ if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
147
+ enclosing_provider.send(method_symbol, *args, &block)
148
+ else
149
+ raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
150
+ end
151
+ end
152
+
153
+ def load_prior_resource
154
+ begin
155
+ prior_resource = run_context.resource_collection.lookup(self.to_s)
156
+ Chef::Log.debug("Setting #{self.to_s} to the state of the prior #{self.to_s}")
157
+ prior_resource.instance_variables.each do |iv|
158
+ unless iv.to_sym == :@source_line || iv.to_sym == :@action
159
+ self.instance_variable_set(iv, prior_resource.instance_variable_get(iv))
160
+ end
161
+ end
162
+ true
163
+ rescue Chef::Exceptions::ResourceNotFound => e
164
+ true
165
+ end
166
+ end
167
+
168
+ def supports(args={})
169
+ if args.any?
170
+ @supports = args
171
+ else
172
+ @supports
173
+ end
174
+ end
175
+
176
+ def provider(arg=nil)
177
+ klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
178
+ lookup_provider_constant(arg)
179
+ else
180
+ arg
181
+ end
182
+ set_or_return(
183
+ :provider,
184
+ klass,
185
+ :kind_of => [ Class ]
186
+ )
187
+ end
188
+
189
+ def action(arg=nil)
190
+ if arg
191
+ action_list = arg.kind_of?(Array) ? arg : [ arg ]
192
+ action_list = action_list.collect { |a| a.to_sym }
193
+ action_list.each do |action|
194
+ validate(
195
+ {
196
+ :action => action,
197
+ },
198
+ {
199
+ :action => { :kind_of => Symbol, :equal_to => @allowed_actions },
200
+ }
201
+ )
202
+ end
203
+ @action = action_list
204
+ else
205
+ @action
206
+ end
207
+ end
208
+
209
+ def name(name=nil)
210
+ set_if_args(@name, name) do
211
+ raise ArgumentError, "name must be a string!" unless name.kind_of?(String)
212
+ @name = name
213
+ end
214
+ end
215
+
216
+ def noop(tf=nil)
217
+ set_if_args(@noop, tf) do
218
+ raise ArgumentError, "noop must be true or false!" unless tf == true || tf == false
219
+ @noop = tf
220
+ end
221
+ end
222
+
223
+ def ignore_failure(arg=nil)
224
+ set_or_return(
225
+ :ignore_failure,
226
+ arg,
227
+ :kind_of => [ TrueClass, FalseClass ]
228
+ )
229
+ end
230
+
231
+ def retries(arg=nil)
232
+ set_or_return(
233
+ :retries,
234
+ arg,
235
+ :kind_of => Integer
236
+ )
237
+ end
238
+
239
+ def retry_delay(arg=nil)
240
+ set_or_return(
241
+ :retry_delay,
242
+ arg,
243
+ :kind_of => Integer
244
+ )
245
+ end
246
+
247
+ def epic_fail(arg=nil)
248
+ ignore_failure(arg)
249
+ end
250
+
251
+ def notifies(*args)
252
+ unless ( args.size > 0 && args.size < 4)
253
+ raise ArgumentError, "Wrong number of arguments for notifies: should be 1-3 arguments, you gave #{args.inspect}"
254
+ end
255
+
256
+ if args.size > 1 # notifies(:action, resource) OR notifies(:action, resource, :immediately)
257
+ add_notification(*args)
258
+ else
259
+ # This syntax is so weird. surely people will just give us one hash?
260
+ notifications = args.flatten
261
+ notifications.each do |resources_notifications|
262
+ resources_notifications.each do |resource, notification|
263
+ action, timing = notification[0], notification[1]
264
+ Chef::Log.debug "Adding notification from resource #{self} to `#{resource.inspect}' => `#{notification.inspect}'"
265
+ add_notification(action, resource, timing)
266
+ end
267
+ end
268
+ end
269
+ rescue NoMethodError
270
+ Chef::Log.fatal("Error processing notifies(#{args.inspect}) on #{self}")
271
+ raise
272
+ end
273
+
274
+ def add_notification(action, resources, timing=:delayed)
275
+ resources = [resources].flatten
276
+ resources.each do |resource|
277
+ case timing.to_s
278
+ when 'delayed'
279
+ notifies_delayed(action, resource)
280
+ when 'immediate', 'immediately'
281
+ notifies_immediately(action, resource)
282
+ else
283
+ raise ArgumentError, "invalid timing: #{timing} for notifies(#{action}, #{resources.inspect}, #{timing}) resource #{self} "\
284
+ "Valid timings are: :delayed, :immediate, :immediately"
285
+ end
286
+ end
287
+
288
+ true
289
+ end
290
+
291
+ # Iterates over all immediate and delayed notifications, calling
292
+ # resolve_resource_reference on each in turn, causing them to
293
+ # resolve lazy/forward references.
294
+ def resolve_notification_references
295
+ @immediate_notifications.each { |n| n.resolve_resource_reference(run_context.resource_collection) }
296
+ @delayed_notifications.each {|n| n.resolve_resource_reference(run_context.resource_collection) }
297
+ end
298
+
299
+ def notifies_immediately(action, resource_spec)
300
+ @immediate_notifications << Notification.new(resource_spec, action, self)
301
+ end
302
+
303
+ def notifies_delayed(action, resource_spec)
304
+ @delayed_notifications << Notification.new(resource_spec, action, self)
305
+ end
306
+
307
+ def resources(*args)
308
+ run_context.resource_collection.find(*args)
309
+ end
310
+
311
+ def subscribes(action, resources, timing=:delayed)
312
+ resources = [resources].flatten
313
+ resources.each do |resource|
314
+ resource.notifies(action, self, timing)
315
+ end
316
+ true
317
+ end
318
+
319
+ def is(*args)
320
+ if args.size == 1
321
+ args.first
322
+ else
323
+ return *args
324
+ end
325
+ end
326
+
327
+ def to_s
328
+ "#{@resource_name}[#{@name}]"
329
+ end
330
+
331
+ def to_text
332
+ ivars = instance_variables.map { |ivar| ivar.to_sym } - HIDDEN_IVARS
333
+ text = "# Declared in #{@source_line}\n"
334
+ text << convert_to_snake_case(self.class.name, 'Chef::Resource') + "(\"#{name}\") do\n"
335
+ ivars.each do |ivar|
336
+ if (value = instance_variable_get(ivar)) && !(value.respond_to?(:empty?) && value.empty?)
337
+ text << " #{ivar.to_s.sub(/^@/,'')}(#{value.inspect})\n"
338
+ end
339
+ end
340
+ text << "end\n"
341
+ end
342
+
343
+ def inspect
344
+ ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
345
+ ivars.inject("<#{to_s}") do |str, ivar|
346
+ str << " #{ivar}: #{instance_variable_get(ivar).inspect}"
347
+ end << ">"
348
+ end
349
+
350
+ # Serialize this object as a hash
351
+ def to_json(*a)
352
+ safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
353
+ instance_vars = Hash.new
354
+ safe_ivars.each do |iv|
355
+ instance_vars[iv.to_s.sub(/^@/, '')] = instance_variable_get(iv)
356
+ end
357
+ results = {
358
+ 'json_class' => self.class.name,
359
+ 'instance_vars' => instance_vars
360
+ }
361
+ results.to_json(*a)
362
+ end
363
+
364
+ def to_hash
365
+ safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
366
+ instance_vars = Hash.new
367
+ safe_ivars.each do |iv|
368
+ key = iv.to_s.sub(/^@/,'').to_sym
369
+ instance_vars[key] = instance_variable_get(iv)
370
+ end
371
+ instance_vars
372
+ end
373
+
374
+ def only_if(arg=nil, args = {}, &blk)
375
+ if Kernel.block_given?
376
+ @only_if = blk
377
+ @only_if_args = args
378
+ else
379
+ @only_if = arg if arg
380
+ @only_if_args = args if arg
381
+ end
382
+ @only_if
383
+ end
384
+
385
+ def not_if(arg=nil, args = {}, &blk)
386
+ if Kernel.block_given?
387
+ @not_if = blk
388
+ @not_if_args = args
389
+ else
390
+ @not_if = arg if arg
391
+ @not_if_args = args if arg
392
+ end
393
+ @not_if
394
+ end
395
+
396
+ def defined_at
397
+ if cookbook_name && recipe_name && source_line
398
+ "#{cookbook_name}::#{recipe_name} line #{source_line.split(':')[1]}"
399
+ elsif source_line
400
+ file, line_no = source_line.split(':')
401
+ "#{file} line #{line_no}"
402
+ else
403
+ "dynamically defined"
404
+ end
405
+ end
406
+
407
+ def run_action(action)
408
+ Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
409
+
410
+ # ensure that we don't leave @updated_by_last_action set to true
411
+ # on accident
412
+ updated_by_last_action(false)
413
+
414
+ begin
415
+ # Check if this resource has an only_if block -- if it does,
416
+ # evaluate the only_if block and skip the resource if
417
+ # appropriate.
418
+ if only_if
419
+ unless Chef::Mixin::Command.only_if(only_if, only_if_args)
420
+ Chef::Log.debug("Skipping #{self} due to only_if")
421
+ return
422
+ end
423
+ end
424
+
425
+ # Check if this resource has a not_if block -- if it does,
426
+ # evaluate the not_if block and skip the resource if
427
+ # appropriate.
428
+ if not_if
429
+ unless Chef::Mixin::Command.not_if(not_if, not_if_args)
430
+ Chef::Log.debug("Skipping #{self} due to not_if")
431
+ return
432
+ end
433
+ end
434
+
435
+ provider = Chef::Platform.provider_for_resource(self)
436
+ provider.load_current_resource
437
+ provider.send("action_#{action}")
438
+ rescue => e
439
+ if ignore_failure
440
+ Chef::Log.error("#{self} (#{defined_at}) had an error: #{e.message}")
441
+ else
442
+ Chef::Log.error("#{self} (#{defined_at}) has had an error")
443
+ new_exception = e.exception("#{self} (#{defined_at}) had an error: #{e.message}")
444
+ new_exception.set_backtrace(e.backtrace)
445
+ raise new_exception
446
+ end
447
+ end
448
+ end
449
+
450
+ def updated_by_last_action(true_or_false)
451
+ @updated ||= true_or_false
452
+ @updated_by_last_action = true_or_false
453
+ end
454
+
455
+ def updated_by_last_action?
456
+ @updated_by_last_action
457
+ end
458
+
459
+ def updated?
460
+ updated
461
+ end
462
+
463
+ class << self
464
+
465
+ def json_create(o)
466
+ resource = self.new(o["instance_vars"]["@name"])
467
+ o["instance_vars"].each do |k,v|
468
+ resource.instance_variable_set("@#{k}".to_sym, v)
469
+ end
470
+ resource
471
+ end
472
+
473
+ include Chef::Mixin::ConvertToClassName
474
+
475
+ def attribute(attr_name, validation_opts={})
476
+ # This atrocity is the only way to support 1.8 and 1.9 at the same time
477
+ # When you're ready to drop 1.8 support, do this:
478
+ # define_method attr_name.to_sym do |arg=nil|
479
+ # etc.
480
+ shim_method=<<-SHIM
481
+ def #{attr_name}(arg=nil)
482
+ _set_or_return_#{attr_name}(arg)
483
+ end
484
+ SHIM
485
+ class_eval(shim_method)
486
+
487
+ define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
488
+ set_or_return(attr_name.to_sym, arg, validation_opts)
489
+ end
490
+ end
491
+
492
+ def build_from_file(cookbook_name, filename, run_context)
493
+ rname = filename_to_qualified_string(cookbook_name, filename)
494
+
495
+ # Add log entry if we override an existing light-weight resource.
496
+ class_name = convert_to_class_name(rname)
497
+ overriding = Chef::Resource.const_defined?(class_name)
498
+ Chef::Log.info("#{class_name} light-weight resource already initialized -- overriding!") if overriding
499
+
500
+ new_resource_class = Class.new self do |cls|
501
+
502
+ # default initialize method that ensures that when initialize is finally
503
+ # wrapped (see below), super is called in the event that the resource
504
+ # definer does not implement initialize
505
+ def initialize(name, run_context)
506
+ super(name, run_context)
507
+ end
508
+
509
+ @actions_to_create = []
510
+
511
+ class << cls
512
+ include Chef::Mixin::FromFile
513
+
514
+ attr_accessor :run_context
515
+
516
+ def node
517
+ self.run_context.node
518
+ end
519
+
520
+ def actions_to_create
521
+ @actions_to_create
522
+ end
523
+
524
+ define_method(:actions) do |*action_names|
525
+ actions_to_create.push(*action_names)
526
+ end
527
+ end
528
+
529
+ # set the run context in the class instance variable
530
+ cls.run_context = run_context
531
+
532
+ # load resource definition from file
533
+ cls.class_from_file(filename)
534
+
535
+ # create a new constructor that wraps the old one and adds the actions
536
+ # specified in the DSL
537
+ old_init = instance_method(:initialize)
538
+
539
+ define_method(:initialize) do |name, *optional_args|
540
+ args_run_context = optional_args.shift
541
+ @resource_name = rname.to_sym
542
+ old_init.bind(self).call(name, args_run_context)
543
+ allowed_actions.push(self.class.actions_to_create).flatten!
544
+ end
545
+ end
546
+
547
+ # register new class as a Chef::Resource
548
+ class_name = convert_to_class_name(rname)
549
+ Chef::Resource.const_set(class_name, new_resource_class)
550
+ Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
551
+
552
+ new_resource_class
553
+ end
554
+
555
+ # Resources that want providers namespaced somewhere other than
556
+ # Chef::Provider can set the namespace with +provider_base+
557
+ # Ex:
558
+ # class MyResource < Chef::Resource
559
+ # provider_base Chef::Provider::Deploy
560
+ # # ...other stuff
561
+ # end
562
+ def provider_base(arg=nil)
563
+ @provider_base ||= arg
564
+ @provider_base ||= Chef::Provider
565
+ end
566
+
567
+ end
568
+
569
+ private
570
+
571
+ def lookup_provider_constant(name)
572
+ begin
573
+ self.class.provider_base.const_get(convert_to_class_name(name.to_s))
574
+ rescue NameError => e
575
+ if e.to_s =~ /#{Regexp.escape(self.class.provider_base.to_s)}/
576
+ raise ArgumentError, "No provider found to match '#{name}'"
577
+ else
578
+ raise e
579
+ end
580
+ end
581
+ end
582
+
583
+ end
584
+ end