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,49 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ # == String (Patch)
20
+ # On ruby 1.9, Strings are aware of multibyte characters, so +size+ and +length+
21
+ # give the actual number of characters. In Chef::REST, we need the bytesize
22
+ # so we can correctly set the Content-Length headers, but ruby 1.8.6 and lower
23
+ # don't define String#bytesize. Monkey patching time!
24
+
25
+ begin
26
+ require 'enumerator'
27
+ rescue LoadError
28
+ end
29
+
30
+ class String
31
+ unless method_defined?(:bytesize)
32
+ alias :bytesize :size
33
+ end
34
+
35
+ unless method_defined?(:lines)
36
+ def lines
37
+ enum_for(:each)
38
+ end
39
+ end
40
+ end
41
+
42
+ # <= 1.8.6 needs some ord!
43
+ class String
44
+ unless method_defined?(:ord)
45
+ def ord
46
+ self.unpack('c').first
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,64 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ # == Tempfile (Patch)
20
+ # Tempfile has a horrible bug where it causes an IOError: closed stream in its
21
+ # finalizer, leading to intermittent application crashes with confusing stack
22
+ # traces. Here we monkey patch the fix into place. You can track the bug on
23
+ # ruby's redmine: http://redmine.ruby-lang.org/issues/show/3119
24
+ #
25
+ # The patch is slightly different for Ruby 1.8 and Ruby 1.9, both patches are
26
+ # included here.
27
+ class Tempfile # :nodoc:
28
+ # Tempfile has changes between 1.8.x and 1.9.x
29
+ # so we monkey patch separately
30
+ if RUBY_VERSION =~ /^1\.8/
31
+ def unlink
32
+ # keep this order for thread safeness
33
+ begin
34
+ File.unlink(@tmpname) if File.exist?(@tmpname)
35
+ @@cleanlist.delete(@tmpname)
36
+ @tmpname = nil
37
+ ObjectSpace.undefine_finalizer(self)
38
+ rescue Errno::EACCES
39
+ # may not be able to unlink on Windows; just ignore
40
+ end
41
+ end
42
+ alias delete unlink
43
+
44
+
45
+ # There is a patch for this, to be merged into 1.9 at some point.
46
+ # When that happens, we'll want to also check the RUBY_PATCHLEVEL
47
+ elsif RUBY_VERSION =~ /^1\.9/
48
+ def unlink
49
+ # keep this order for thread safeness
50
+ return unless @tmpname
51
+ begin
52
+ if File.exist?(@tmpname)
53
+ File.unlink(@tmpname)
54
+ end
55
+ # remove tmpname from remover
56
+ @data[0] = @data[2] = nil
57
+ @tmpname = nil
58
+ rescue Errno::EACCES
59
+ # may not be able to unlink on Windows; just ignore
60
+ end
61
+ end
62
+ alias delete unlink
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ class Chef
2
+ NIL_ARGUMENT = Object.new
3
+ end
@@ -0,0 +1,469 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Brown (<cb@opscode.com>)
4
+ # Author:: Christopher Walters (<cw@opscode.com>)
5
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
6
+ # Copyright:: Copyright (c) 2008-2011 Opscode, Inc.
7
+ # License:: Apache License, Version 2.0
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+
22
+ require 'forwardable'
23
+ require 'chef/config'
24
+ require 'chef/cookbook/cookbook_collection'
25
+ require 'chef/nil_argument'
26
+ require 'chef/mixin/check_helper'
27
+ require 'chef/mixin/params_validate'
28
+ require 'chef/mixin/from_file'
29
+ require 'chef/mixin/language_include_attribute'
30
+ require 'chef/mixin/deep_merge'
31
+ require 'chef/environment'
32
+ require 'chef/run_list'
33
+ require 'chef/node/attribute'
34
+ require 'chef/mash'
35
+ require 'chef/json_compat'
36
+
37
+ class Chef
38
+ class Node
39
+
40
+ extend Forwardable
41
+
42
+ def_delegators :construct_attributes, :keys, :each_key, :each_value, :key?, :has_key?
43
+
44
+ attr_accessor :recipe_list, :run_state, :run_list
45
+ attr_accessor :override_attrs, :default_attrs, :normal_attrs, :automatic_attrs
46
+
47
+ # TODO: 5/18/2010 cw/timh. cookbook_collection should be removed
48
+ # from here and for any place it's needed, it should be accessed
49
+ # through a Chef::RunContext
50
+ attr_accessor :cookbook_collection
51
+
52
+ include Chef::Mixin::CheckHelper
53
+ include Chef::Mixin::FromFile
54
+ include Chef::Mixin::ParamsValidate
55
+ include Chef::Mixin::LanguageIncludeAttribute
56
+
57
+ # Create a new Chef::Node object.
58
+ def initialize()
59
+ @name = nil
60
+
61
+ @chef_environment = '_default'
62
+ @normal_attrs = Mash.new
63
+ @override_attrs = Mash.new
64
+ @default_attrs = Mash.new
65
+ @automatic_attrs = Mash.new
66
+ @run_list = Chef::RunList.new
67
+
68
+ @run_state = {
69
+ :template_cache => Hash.new,
70
+ :seen_recipes => Hash.new,
71
+ :seen_attributes => Hash.new
72
+ }
73
+ # TODO: 5/20/2010 need this here as long as other objects try to access
74
+ # the cookbook collection via Node, otherwise get NoMethodError on nil.
75
+ @cookbook_collection = CookbookCollection.new
76
+ end
77
+
78
+ # Used by DSL
79
+ def node
80
+ self
81
+ end
82
+
83
+ # Find a recipe for this Chef::Node by fqdn. Will search first for
84
+ # Chef::Config["node_path"]/fqdn.rb, then hostname.rb, then default.rb.
85
+ #
86
+ # Returns a new Chef::Node object.
87
+ #
88
+ # Raises an ArgumentError if it cannot find the node.
89
+ def find_file(fqdn)
90
+ host_parts = fqdn.split(".")
91
+ hostname = host_parts[0]
92
+
93
+ [fqdn, hostname, "default"].each { |fname|
94
+ node_file = File.join(Chef::Config[:node_path], "#{fname.to_s}.rb")
95
+ return self.from_file(node_file) if File.exists?(node_file)
96
+ }
97
+
98
+ raise ArgumentError, "Cannot find a node matching #{fqdn}, not even with default.rb!"
99
+ end
100
+
101
+ # Set the name of this Node, or return the current name.
102
+ def name(arg=nil)
103
+ if arg != nil
104
+ validate(
105
+ {:name => arg },
106
+ {:name => { :kind_of => String,
107
+ :cannot_be => :blank,
108
+ :regex => /^[\-[:alnum:]_:.]+$/}
109
+ })
110
+ @name = arg
111
+ else
112
+ @name
113
+ end
114
+ end
115
+
116
+ def chef_environment(arg=nil)
117
+ set_or_return(
118
+ :chef_environment,
119
+ arg,
120
+ { :regex => /^[\-[:alnum:]_]+$/, :kind_of => String }
121
+ )
122
+ end
123
+
124
+ # Used by the DSL
125
+ def attribute
126
+ construct_attributes
127
+ end
128
+
129
+ def construct_attributes
130
+ Chef::Node::Attribute.new(normal_attrs, default_attrs, override_attrs, automatic_attrs)
131
+ end
132
+
133
+ def attribute=(value)
134
+ self.normal_attrs = value
135
+ end
136
+
137
+ # Return an attribute of this node. Returns nil if the attribute is not found.
138
+ def [](attrib)
139
+ construct_attributes[attrib]
140
+ end
141
+
142
+ # Set an attribute of this node
143
+ def []=(attrib, value)
144
+ construct_attributes[attrib] = value
145
+ end
146
+
147
+ def store(attrib, value)
148
+ self[attrib] = value
149
+ end
150
+
151
+ # Set a normal attribute of this node, but auto-vivifiy any Mashes that
152
+ # might be missing
153
+ def normal
154
+ attrs = construct_attributes
155
+ attrs.set_type = :normal
156
+ attrs.auto_vivifiy_on_read = true
157
+ attrs
158
+ end
159
+
160
+ alias_method :set, :normal
161
+
162
+ # Set a normal attribute of this node, auto-vivifiying any mashes that are
163
+ # missing, but if the final value already exists, don't set it
164
+ def normal_unless
165
+ attrs = construct_attributes
166
+ attrs.set_type = :normal
167
+ attrs.auto_vivifiy_on_read = true
168
+ attrs.set_unless_value_present = true
169
+ attrs
170
+ end
171
+ alias_method :set_unless, :normal_unless
172
+
173
+ # Set a default of this node, but auto-vivifiy any Mashes that might
174
+ # be missing
175
+ def default
176
+ attrs = construct_attributes
177
+ attrs.set_type = :default
178
+ attrs.auto_vivifiy_on_read = true
179
+ attrs
180
+ end
181
+
182
+ # Set a default attribute of this node, auto-vivifiying any mashes that are
183
+ # missing, but if the final value already exists, don't set it
184
+ def default_unless
185
+ attrs = construct_attributes
186
+ attrs.set_type = :default
187
+ attrs.auto_vivifiy_on_read = true
188
+ attrs.set_unless_value_present = true
189
+ attrs
190
+ end
191
+
192
+ # Set an override attribute of this node, but auto-vivifiy any Mashes that
193
+ # might be missing
194
+ def override
195
+ attrs = construct_attributes
196
+ attrs.set_type = :override
197
+ attrs.auto_vivifiy_on_read = true
198
+ attrs
199
+ end
200
+
201
+ # Set an override attribute of this node, auto-vivifiying any mashes that
202
+ # are missing, but if the final value already exists, don't set it
203
+ def override_unless
204
+ attrs = construct_attributes
205
+ attrs.set_type = :override
206
+ attrs.auto_vivifiy_on_read = true
207
+ attrs.set_unless_value_present = true
208
+ attrs
209
+ end
210
+
211
+ # Return true if this Node has a given attribute, false if not. Takes either a symbol or
212
+ # a string.
213
+ #
214
+ # Only works on the top level. Preferred way is to use the normal [] style
215
+ # lookup and call attribute?()
216
+ def attribute?(attrib)
217
+ construct_attributes.attribute?(attrib)
218
+ end
219
+
220
+ # Yield each key of the top level to the block.
221
+ def each(&block)
222
+ construct_attributes.each(&block)
223
+ end
224
+
225
+ # Iterates over each attribute, passing the attribute and value to the block.
226
+ def each_attribute(&block)
227
+ construct_attributes.each_attribute(&block)
228
+ end
229
+
230
+ # Encouraged to only get used for lookups - while you can do sets from here, it's not as explicit
231
+ # as using the normal/default/override interface.
232
+ def method_missing(symbol, *args)
233
+ attrs = construct_attributes
234
+ attrs.send(symbol, *args)
235
+ end
236
+
237
+ # Returns true if this Node expects a given recipe, false if not.
238
+ #
239
+ # First, the run list is consulted to see whether the recipe is
240
+ # explicitly included. If it's not there, it looks in
241
+ # run_state[:seen_recipes], which is populated by include_recipe
242
+ # statements in the DSL (and thus would not be in the run list).
243
+ #
244
+ # NOTE: It's used by cookbook authors
245
+ def recipe?(recipe_name)
246
+ run_list.include?(recipe_name) || run_state[:seen_recipes].include?(recipe_name)
247
+ end
248
+
249
+ # Returns true if this Node expects a given role, false if not.
250
+ def role?(role_name)
251
+ run_list.include?("role[#{role_name}]")
252
+ end
253
+
254
+ # Returns an Array of roles and recipes, in the order they will be applied.
255
+ # If you call it with arguments, they will become the new list of roles and recipes.
256
+ def run_list(*args)
257
+ args.length > 0 ? @run_list.reset!(args) : @run_list
258
+ end
259
+
260
+ # Returns true if this Node expects a given role, false if not.
261
+ def run_list?(item)
262
+ run_list.detect { |r| r == item } ? true : false
263
+ end
264
+
265
+ # Consume data from ohai and Attributes provided as JSON on the command line.
266
+ def consume_external_attrs(ohai_data, json_cli_attrs)
267
+ Chef::Log.debug("Extracting run list from JSON attributes provided on command line")
268
+ consume_attributes(json_cli_attrs)
269
+
270
+ @automatic_attrs = ohai_data
271
+
272
+ platform, version = Chef::Platform.find_platform_and_version(self)
273
+ Chef::Log.debug("Platform is #{platform} version #{version}")
274
+ @automatic_attrs[:platform] = platform
275
+ @automatic_attrs[:platform_version] = version
276
+ end
277
+
278
+ # Consumes the combined run_list and other attributes in +attrs+
279
+ def consume_attributes(attrs)
280
+ normal_attrs_to_merge = consume_run_list(attrs)
281
+ Chef::Log.debug("Applying attributes from json file")
282
+ @normal_attrs = Chef::Mixin::DeepMerge.merge(@normal_attrs,normal_attrs_to_merge)
283
+ self.tags # make sure they're defined
284
+ end
285
+
286
+ # Lazy initializer for tags attribute
287
+ def tags
288
+ self[:tags] = [] unless attribute?(:tags)
289
+ self[:tags]
290
+ end
291
+
292
+ # Extracts the run list from +attrs+ and applies it. Returns the remaining attributes
293
+ def consume_run_list(attrs)
294
+ attrs = attrs ? attrs.dup : {}
295
+ if new_run_list = attrs.delete("recipes") || attrs.delete("run_list")
296
+ if attrs.key?("recipes") || attrs.key?("run_list")
297
+ raise Chef::Exceptions::AmbiguousRunlistSpecification, "please set the node's run list using the 'run_list' attribute only."
298
+ end
299
+ Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from JSON")
300
+ run_list(new_run_list)
301
+ end
302
+ attrs
303
+ end
304
+
305
+ # Clear defaults and overrides, so that any deleted attributes
306
+ # between runs are still gone.
307
+ def reset_defaults_and_overrides
308
+ @default_attrs = Mash.new
309
+ @override_attrs = Mash.new
310
+ end
311
+
312
+ # Expands the node's run list and sets the default and override
313
+ # attributes. Also applies stored attributes (from json provided
314
+ # on the command line)
315
+ #
316
+ # Returns the fully-expanded list of recipes, a RunListExpansion.
317
+ #
318
+ #--
319
+ # TODO: timh/cw, 5-14-2010: Should this method exist? Should we
320
+ # instead modify default_attrs and override_attrs whenever our
321
+ # run_list is mutated? Or perhaps do something smarter like
322
+ # on-demand generation of default_attrs and override_attrs,
323
+ # invalidated only when run_list is mutated?
324
+ def expand!(data_source = 'disk')
325
+ expansion = run_list.expand(chef_environment, data_source)
326
+ raise Chef::Exceptions::MissingRole if expansion.errors?
327
+
328
+ self.tags # make sure they're defined
329
+
330
+ @automatic_attrs[:recipes] = expansion.recipes
331
+ @automatic_attrs[:roles] = expansion.roles
332
+
333
+ expansion
334
+ end
335
+
336
+ # Apply the default and overrides attributes from the expansion
337
+ # passed in, which came from roles.
338
+ def apply_expansion_attributes(expansion)
339
+ load_chef_environment_object = (chef_environment == "_default" ? nil : Chef::Environment.load(chef_environment))
340
+ environment_default_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.default_attributes
341
+ default_before_roles = Chef::Mixin::DeepMerge.merge(default_attrs, environment_default_attrs)
342
+ @default_attrs = Chef::Mixin::DeepMerge.merge(default_before_roles, expansion.default_attrs)
343
+ environment_override_attrs = load_chef_environment_object.nil? ? {} : load_chef_environment_object.override_attributes
344
+ overrides_before_environments = Chef::Mixin::DeepMerge.merge(override_attrs, expansion.override_attrs)
345
+ @override_attrs = Chef::Mixin::DeepMerge.merge(overrides_before_environments, environment_override_attrs)
346
+ end
347
+
348
+ # Transform the node to a Hash
349
+ def to_hash
350
+ index_hash = Hash.new
351
+ index_hash["chef_type"] = "node"
352
+ index_hash["name"] = name
353
+ index_hash["chef_environment"] = chef_environment
354
+ attribute.each do |key, value|
355
+ index_hash[key] = value
356
+ end
357
+ index_hash["recipe"] = run_list.recipe_names if run_list.recipe_names.length > 0
358
+ index_hash["role"] = run_list.role_names if run_list.role_names.length > 0
359
+ index_hash["run_list"] = run_list.run_list if run_list.run_list.length > 0
360
+ index_hash
361
+ end
362
+
363
+ def display_hash
364
+ display = {}
365
+ display["name"] = name
366
+ display["chef_environment"] = chef_environment
367
+ display["automatic"] = automatic_attrs
368
+ display["normal"] = normal_attrs
369
+ display["default"] = default_attrs
370
+ display["override"] = override_attrs
371
+ display["run_list"] = run_list.run_list
372
+ display
373
+ end
374
+
375
+ # Serialize this object as a hash
376
+ def to_json(*a)
377
+ result = {
378
+ "name" => name,
379
+ "chef_environment" => chef_environment,
380
+ 'json_class' => self.class.name,
381
+ "automatic" => automatic_attrs,
382
+ "normal" => normal_attrs,
383
+ "chef_type" => "node",
384
+ "default" => default_attrs,
385
+ "override" => override_attrs,
386
+ "run_list" => run_list.run_list
387
+ }
388
+ result.to_json(*a)
389
+ end
390
+
391
+ def update_from!(o)
392
+ run_list.reset!(o.run_list)
393
+ @automatic_attrs = o.automatic_attrs
394
+ @normal_attrs = o.normal_attrs
395
+ @override_attrs = o.override_attrs
396
+ @default_attrs = o.default_attrs
397
+ chef_environment(o.chef_environment)
398
+ self
399
+ end
400
+
401
+ # Create a Chef::Node from JSON
402
+ def self.json_create(o)
403
+ node = new
404
+ node.name(o["name"])
405
+ node.chef_environment(o["chef_environment"])
406
+ if o.has_key?("attributes")
407
+ node.normal_attrs = o["attributes"]
408
+ end
409
+ node.automatic_attrs = Mash.new(o["automatic"]) if o.has_key?("automatic")
410
+ node.normal_attrs = Mash.new(o["normal"]) if o.has_key?("normal")
411
+ node.default_attrs = Mash.new(o["default"]) if o.has_key?("default")
412
+ node.override_attrs = Mash.new(o["override"]) if o.has_key?("override")
413
+
414
+ if o.has_key?("run_list")
415
+ node.run_list.reset!(o["run_list"])
416
+ else
417
+ o["recipes"].each { |r| node.recipes << r }
418
+ end
419
+ node
420
+ end
421
+
422
+ def self.find_or_create(node_name)
423
+ load(node_name)
424
+ rescue Net::HTTPServerException => e
425
+ raise unless e.response.code == '404'
426
+ node = build(node_name)
427
+ node.create
428
+ end
429
+
430
+ def self.build(node_name)
431
+ node = new
432
+ node.name(node_name)
433
+ node.chef_environment(Chef::Config[:environment]) unless Chef::Config[:environment].nil? || Chef::Config[:environment].chop.empty?
434
+ node
435
+ end
436
+
437
+ def to_s
438
+ "node[#{name}]"
439
+ end
440
+
441
+ # Load all attribute files for all cookbooks associated with this
442
+ # node.
443
+ def load_attributes
444
+ cookbook_collection.values.each do |cookbook|
445
+ cookbook.segment_filenames(:attributes).each do |segment_filename|
446
+ Chef::Log.debug("Node #{name} loading cookbook #{cookbook.name}'s attribute file #{segment_filename}")
447
+ self.from_file(segment_filename)
448
+ end
449
+ end
450
+ end
451
+
452
+ # Used by DSL.
453
+ # Loads the attribute file specified by the short name of the
454
+ # file, e.g., loads specified cookbook's
455
+ # "attributes/mailservers.rb"
456
+ # if passed
457
+ # "mailservers"
458
+ def load_attribute_by_short_filename(name, src_cookbook_name)
459
+ src_cookbook = cookbook_collection[src_cookbook_name]
460
+ raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{src_cookbook_name} while loading attribute #{name}" unless src_cookbook
461
+
462
+ attribute_filename = src_cookbook.attribute_filenames_by_short_filename[name]
463
+ raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{name} in cookbook #{src_cookbook_name}" unless attribute_filename
464
+
465
+ self.from_file(attribute_filename)
466
+ self
467
+ end
468
+ end
469
+ end