chef 0.9.8 → 0.9.10.rc.0

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 (98) hide show
  1. data/README.rdoc +1 -1
  2. data/distro/common/man/man8/knife.8 +89 -79
  3. data/distro/common/markdown/knife.mkd +7 -0
  4. data/distro/debian/etc/default/chef-server +3 -0
  5. data/distro/debian/etc/default/chef-server-webui +3 -0
  6. data/distro/debian/etc/default/chef-solr +3 -0
  7. data/distro/debian/etc/default/chef-solr-indexer +3 -0
  8. data/distro/debian/etc/init.d/chef-server +3 -1
  9. data/distro/debian/etc/init.d/chef-server-webui +3 -1
  10. data/distro/redhat/etc/init.d/chef-client +1 -1
  11. data/lib/chef/application.rb +2 -0
  12. data/lib/chef/application/client.rb +5 -3
  13. data/lib/chef/application/knife.rb +16 -5
  14. data/lib/chef/application/solo.rb +0 -1
  15. data/lib/chef/checksum.rb +65 -1
  16. data/lib/chef/checksum_cache.rb +173 -0
  17. data/lib/chef/client.rb +84 -121
  18. data/lib/chef/cookbook/remote_file_vendor.rb +10 -3
  19. data/lib/chef/cookbook/syntax_check.rb +2 -2
  20. data/lib/chef/cookbook_loader.rb +2 -0
  21. data/lib/chef/cookbook_site_streaming_uploader.rb +29 -0
  22. data/lib/chef/cookbook_uploader.rb +8 -7
  23. data/lib/chef/cookbook_version.rb +155 -114
  24. data/lib/chef/exceptions.rb +5 -0
  25. data/lib/chef/handler.rb +43 -0
  26. data/lib/chef/index_queue/consumer.rb +1 -1
  27. data/lib/chef/index_queue/indexable.rb +1 -1
  28. data/lib/chef/knife.rb +18 -5
  29. data/lib/chef/knife/bootstrap.rb +2 -2
  30. data/lib/chef/knife/bootstrap/archlinux-gems.erb +44 -0
  31. data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
  32. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  33. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -7
  34. data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
  35. data/lib/chef/knife/configure_client.rb +4 -2
  36. data/lib/chef/knife/cookbook_metadata.rb +1 -1
  37. data/lib/chef/knife/cookbook_site_share.rb +2 -1
  38. data/lib/chef/knife/cookbook_site_vendor.rb +6 -0
  39. data/lib/chef/knife/cookbook_test.rb +1 -1
  40. data/lib/chef/knife/ec2_server_create.rb +51 -26
  41. data/lib/chef/knife/exec.rb +52 -0
  42. data/lib/chef/knife/ssh.rb +27 -15
  43. data/lib/chef/knife/status.rb +27 -10
  44. data/lib/chef/knife/windows_bootstrap.rb +154 -0
  45. data/lib/chef/mixin/checksum.rb +2 -2
  46. data/lib/chef/mixin/xml_escape.rb +75 -49
  47. data/lib/chef/node.rb +54 -58
  48. data/lib/chef/node/attribute.rb +61 -53
  49. data/lib/chef/platform.rb +19 -2
  50. data/lib/chef/provider/breakpoint.rb +1 -1
  51. data/lib/chef/provider/cookbook_file.rb +3 -3
  52. data/lib/chef/provider/cron.rb +3 -3
  53. data/lib/chef/provider/cron/solaris.rb +195 -0
  54. data/lib/chef/provider/deploy.rb +3 -3
  55. data/lib/chef/provider/directory.rb +2 -2
  56. data/lib/chef/provider/env.rb +5 -5
  57. data/lib/chef/provider/execute.rb +1 -1
  58. data/lib/chef/provider/file.rb +10 -9
  59. data/lib/chef/provider/git.rb +12 -4
  60. data/lib/chef/provider/group.rb +5 -5
  61. data/lib/chef/provider/http_request.rb +25 -9
  62. data/lib/chef/provider/ifconfig.rb +2 -2
  63. data/lib/chef/provider/link.rb +11 -6
  64. data/lib/chef/provider/log.rb +1 -0
  65. data/lib/chef/provider/mdadm.rb +3 -3
  66. data/lib/chef/provider/mount.rb +5 -5
  67. data/lib/chef/provider/mount/mount.rb +1 -1
  68. data/lib/chef/provider/ohai.rb +41 -0
  69. data/lib/chef/provider/package.rb +5 -5
  70. data/lib/chef/provider/package/yum-dump.py +5 -2
  71. data/lib/chef/provider/remote_directory.rb +11 -5
  72. data/lib/chef/provider/remote_file.rb +2 -2
  73. data/lib/chef/provider/route.rb +154 -133
  74. data/lib/chef/provider/ruby_block.rb +1 -1
  75. data/lib/chef/provider/service.rb +6 -6
  76. data/lib/chef/provider/subversion.rb +12 -9
  77. data/lib/chef/provider/template.rb +2 -2
  78. data/lib/chef/provider/user.rb +7 -7
  79. data/lib/chef/provider/user/useradd.rb +15 -1
  80. data/lib/chef/providers.rb +2 -0
  81. data/lib/chef/resource.rb +164 -58
  82. data/lib/chef/resource/http_request.rb +9 -0
  83. data/lib/chef/resource/ohai.rb +40 -0
  84. data/lib/chef/resource/remote_directory.rb +10 -1
  85. data/lib/chef/resource/rpm_package.rb +34 -0
  86. data/lib/chef/resource_collection.rb +3 -2
  87. data/lib/chef/resources.rb +2 -0
  88. data/lib/chef/rest.rb +13 -7
  89. data/lib/chef/rest/auth_credentials.rb +1 -1
  90. data/lib/chef/rest/rest_request.rb +3 -1
  91. data/lib/chef/runner.rb +31 -55
  92. data/lib/chef/shef/shef_session.rb +1 -1
  93. data/lib/chef/util/windows/net_use.rb +1 -1
  94. data/lib/chef/version.rb +1 -1
  95. data/lib/chef/webui_user.rb +0 -1
  96. metadata +38 -19
  97. data/lib/chef/cache.rb +0 -61
  98. data/lib/chef/cache/checksum.rb +0 -91
@@ -68,7 +68,19 @@ class Chef
68
68
  :description => "The SSH identity file used for authentication"
69
69
 
70
70
  def session
71
- @session ||= Net::SSH::Multi.start(:concurrent_connections => config[:concurrency])
71
+ ssh_error_handler = Proc.new do |server|
72
+ if config[:manual]
73
+ node_name = server.host
74
+ else
75
+ @action_nodes.each do |n|
76
+ node_name = n if format_for_display(n)[config[:attribute]] == server.host
77
+ end
78
+ end
79
+ Chef::Log.warn "Failed to connect to #{node_name} -- #{$!.class.name}: #{$!.message}"
80
+ $!.backtrace.each { |l| Chef::Log.debug(l) }
81
+ end
82
+
83
+ @session ||= Net::SSH::Multi.start(:concurrent_connections => config[:concurrency], :on_error => ssh_error_handler)
72
84
  end
73
85
 
74
86
  def h
@@ -82,10 +94,10 @@ class Chef
82
94
  when false
83
95
  r = Array.new
84
96
  q = Chef::Search::Query.new
85
- q.search(:node, @name_args[0]) do |item|
86
- r << format_for_display(item)[config[:attribute]]
97
+ @action_nodes = q.search(:node, @name_args[0])[0]
98
+ r = @action_nodes.map do |item|
99
+ format_for_display(item)[config[:attribute]]
87
100
  end
88
- r
89
101
  end
90
102
  (Chef::Log.fatal("No nodes returned from search!"); exit 10) if list.length == 0
91
103
  session_from_list(list)
@@ -94,15 +106,15 @@ class Chef
94
106
  def session_from_list(list)
95
107
  list.each do |item|
96
108
  Chef::Log.debug("Adding #{item}")
97
- item = "#{config[:ssh_user]}@#{item}" if config[:ssh_user]
98
109
 
99
- if config[:identity_file]
100
- session.use item, :keys => File.expand_path(config[:identity_file])
101
- elsif config[:password]
102
- session.use item, :password => config[:password]
103
- else
104
- session.use item
105
- end
110
+ hostspec = config[:ssh_user] ? "#{config[:ssh_user]}@#{item}" : item
111
+ session_opts = {}
112
+ session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file]
113
+ session_opts[:password] = config[:ssh_password] if config[:ssh_password]
114
+ session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
115
+
116
+ session.use(hostspec, session_opts)
117
+
106
118
  @longest = item.length if item.length > @longest
107
119
  end
108
120
  session
@@ -268,10 +280,10 @@ class Chef
268
280
  end
269
281
 
270
282
  def load_late_dependencies
271
- require 'net/ssh/multi'
272
283
  require 'readline'
273
- require 'highline'
274
-
284
+ %w[net/ssh/multi highline].each do |dep|
285
+ load_late_dependency dep
286
+ end
275
287
  assert_net_ssh_version_acceptable!
276
288
  end
277
289
 
@@ -24,7 +24,12 @@ class Chef
24
24
  class Knife
25
25
  class Status < Knife
26
26
 
27
- banner "knife status"
27
+ banner "knife status QUERY (options)"
28
+
29
+ option :run_list,
30
+ :short => "-r",
31
+ :long => "--run-list",
32
+ :description => "Show the run list"
28
33
 
29
34
  def highline
30
35
  @h ||= HighLine.new
@@ -32,23 +37,35 @@ class Chef
32
37
 
33
38
  def run
34
39
  all_nodes = []
35
- Chef::Search::Query.new.search(:node, '*:*') do |node|
40
+ q = Chef::Search::Query.new
41
+ query = @name_args[0] || "*:*"
42
+ q.search(:node, query) do |node|
36
43
  all_nodes << node
37
44
  end
38
45
  all_nodes.sort { |n1, n2| n1["ohai_time"] <=> n2["ohai_time"] }.each do |node|
39
- # 59 seconds
40
- # 1000 hours
41
- # date = DateTime.parse(Time.at(node["ohai_time"]).to_s)
46
+ if node.has_key?("ec2")
47
+ fqdn = node['ec2']['public_hostname']
48
+ ipaddress = node['ec2']['public_ipv4']
49
+ else
50
+ fqdn = node['fqdn']
51
+ ipaddress = node['ipaddress']
52
+ end
42
53
  hours, minutes, seconds = time_difference_in_hms(node["ohai_time"])
43
54
  hours_text = "#{hours} hour#{hours == 1 ? ' ' : 's'}"
44
55
  minutes_text = "#{minutes} minute#{minutes == 1 ? ' ' : 's'}"
56
+ run_list = ", #{node.run_list}." if config[:run_list]
45
57
  if hours > 24
46
- highline.say("<%= color('#{hours_text}', RED) %> ago, #{node['fqdn']} checked in as a #{node['platform']} #{node['platform_version']} node.")
47
- elsif hours > 1
48
- highline.say("<%= color('#{hours_text}', YELLOW) %> ago, #{node['fqdn']} checked in as a #{node['platform']} #{node['platform_version']} node.")
49
- elsif hours == 0
50
- highline.say("<%= color('#{minutes_text}', GREEN) %> ago, #{node['fqdn']} checked in as a #{node['platform']} #{node['platform_version']} node.")
58
+ color = "RED"
59
+ text = hours_text
60
+ elsif hours >= 1
61
+ color = "YELLOW"
62
+ text = hours_text
63
+ else
64
+ color = "GREEN"
65
+ text = minutes_text
51
66
  end
67
+
68
+ highline.say("<%= color('#{text}', #{color}) %> ago, #{node.name}, #{node['platform']} #{node['platform_version']}, #{fqdn}, #{ipaddress}#{run_list}")
52
69
  end
53
70
 
54
71
  end
@@ -0,0 +1,154 @@
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 'fileutils'
20
+ require 'chef/knife/bootstrap.rb'
21
+
22
+ class Chef
23
+ class Knife
24
+ class WindowsBootstrap < Chef::Knife::Bootstrap
25
+
26
+ banner "knife windows bootstrap FQDN [RUN LIST...] (options)"
27
+
28
+ option :user,
29
+ :short => "-x USERNAME",
30
+ :long => "--user USERNAME",
31
+ :description => "The Windows username"
32
+
33
+ option :password,
34
+ :short => "-P PASSWORD",
35
+ :long => "--password PASSWORD",
36
+ :description => "The Windows password"
37
+
38
+ option :chef_node_name,
39
+ :short => "-N NAME",
40
+ :long => "--node-name NAME",
41
+ :description => "The Chef node name for your new node"
42
+
43
+ option :distro,
44
+ :short => "-d DISTRO",
45
+ :long => "--distro DISTRO",
46
+ :description => "Bootstrap a distro using a template",
47
+ :default => "windows-gems"
48
+
49
+ option :template_file,
50
+ :long => "--template-file TEMPLATE",
51
+ :description => "Full path to location of template to use",
52
+ :default => false
53
+
54
+ option :run_list,
55
+ :short => "-r RUN_LIST",
56
+ :long => "--run-list RUN_LIST",
57
+ :description => "Comma separated list of roles/recipes to apply",
58
+ :proc => lambda { |o| o.split(",") },
59
+ :default => []
60
+
61
+ def is_mounted
62
+ @net_use ||= Chef::Util::Windows::NetUse.new(@admin_share)
63
+ begin
64
+ @net_use.get_info
65
+ return true
66
+ rescue
67
+ return false
68
+ end
69
+ end
70
+
71
+ def mount_admin_share
72
+ if @add_mount && !is_mounted
73
+ use = {
74
+ :remote => @admin_share, :local => '',
75
+ :username => config[:user], :password => config[:password]
76
+ }
77
+ @net_use.add(use)
78
+ if is_mounted
79
+ Chef::Log.info("Mounted #{@admin_share} for copying files")
80
+ else
81
+ Chef::Log.fatal("Failed to mount #{@admin_share}")
82
+ exit 1
83
+ end
84
+ end
85
+ end
86
+
87
+ def unmount_admin_share
88
+ if @add_mount && is_mounted
89
+ Chef::Log.debug("Unmounting #{@admin_share}")
90
+ @net_use.delete
91
+ end
92
+ end
93
+
94
+ def psexec(args)
95
+ cmd = ['psexec', @unc_path, "-h", "-w", 'c:\chef\tmp']
96
+ if config[:user]
97
+ cmd << "-u" << config[:user]
98
+ end
99
+ if config[:password]
100
+ cmd << "-p" << config[:password]
101
+ end
102
+ cmd << args
103
+ cmd = cmd.join(' ')
104
+ Chef::Log.debug("system #{cmd}")
105
+ system(cmd)
106
+ end
107
+
108
+ def run
109
+ require 'chef/util/windows/net_use'
110
+
111
+ if @name_args.first == nil
112
+ Chef::Log.error("Must pass a node name/ip to windows bootstrap")
113
+ exit 1
114
+ end
115
+
116
+ config[:server_name] = @name_args.first
117
+ if Chef::Config[:http_proxy]
118
+ uri = URI.parse(Chef::Config[:http_proxy])
119
+ config[:proxy] = "#{uri.host}:#{uri.port}"
120
+ end
121
+
122
+ @unc_path = "\\\\#{config[:server_name]}"
123
+ @admin_share = "#{@unc_path}\\c$"
124
+ path = "#{@admin_share}\\chef"
125
+ etc = "#{path}\\etc"
126
+ tmp = "#{path}\\tmp"
127
+
128
+ $stdout.sync = true
129
+
130
+ command = render_template(load_template(config[:bootstrap_template]))
131
+
132
+ Chef::Log.info("Bootstrapping Chef on #{config[:server_name]}")
133
+
134
+ @add_mount = config[:user] != nil && !is_mounted
135
+ mount_admin_share
136
+
137
+ begin
138
+ [etc, tmp, "#{path}\\log"].each do |dir|
139
+ unless File.exists?(dir)
140
+ Chef::Log.debug("mkdir_p #{dir}")
141
+ FileUtils.mkdir_p(dir)
142
+ end
143
+ end
144
+ File.open("#{tmp}\\bootstrap.bat", 'w') {|f| f.write(command) }
145
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'bootstrap', 'client-install.vbs'), tmp)
146
+ FileUtils.cp(Chef::Config[:validation_key], etc)
147
+ psexec("cmd.exe /c bootstrap.bat")
148
+ ensure
149
+ unmount_admin_share
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -17,14 +17,14 @@
17
17
  #
18
18
 
19
19
  require 'digest/sha2'
20
- require 'chef/cache/checksum'
20
+ require 'chef/checksum_cache'
21
21
 
22
22
  class Chef
23
23
  module Mixin
24
24
  module Checksum
25
25
 
26
26
  def checksum(file)
27
- Chef::Cache::Checksum.checksum_for_file(file)
27
+ Chef::ChecksumCache.checksum_for_file(file)
28
28
  end
29
29
 
30
30
  end
@@ -46,69 +46,95 @@
46
46
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
47
  # THE SOFTWARE.
48
48
 
49
+ require 'chef/log'
50
+
51
+ begin
52
+ require 'fast_xs'
53
+ rescue LoadError
54
+ Chef::Log.info "The fast_xs gem is not installed, slower pure ruby XML escaping will be used."
55
+ end
49
56
 
50
57
  class Chef
51
58
  module Mixin
52
59
  module XMLEscape
53
- extend self
54
60
 
55
- CP1252 = {
56
- 128 => 8364, # euro sign
57
- 130 => 8218, # single low-9 quotation mark
58
- 131 => 402, # latin small letter f with hook
59
- 132 => 8222, # double low-9 quotation mark
60
- 133 => 8230, # horizontal ellipsis
61
- 134 => 8224, # dagger
62
- 135 => 8225, # double dagger
63
- 136 => 710, # modifier letter circumflex accent
64
- 137 => 8240, # per mille sign
65
- 138 => 352, # latin capital letter s with caron
66
- 139 => 8249, # single left-pointing angle quotation mark
67
- 140 => 338, # latin capital ligature oe
68
- 142 => 381, # latin capital letter z with caron
69
- 145 => 8216, # left single quotation mark
70
- 146 => 8217, # right single quotation mark
71
- 147 => 8220, # left double quotation mark
72
- 148 => 8221, # right double quotation mark
73
- 149 => 8226, # bullet
74
- 150 => 8211, # en dash
75
- 151 => 8212, # em dash
76
- 152 => 732, # small tilde
77
- 153 => 8482, # trade mark sign
78
- 154 => 353, # latin small letter s with caron
79
- 155 => 8250, # single right-pointing angle quotation mark
80
- 156 => 339, # latin small ligature oe
81
- 158 => 382, # latin small letter z with caron
82
- 159 => 376 # latin capital letter y with diaeresis
83
- }
61
+ module PureRuby
62
+ extend self
63
+
64
+ CP1252 = {
65
+ 128 => 8364, # euro sign
66
+ 130 => 8218, # single low-9 quotation mark
67
+ 131 => 402, # latin small letter f with hook
68
+ 132 => 8222, # double low-9 quotation mark
69
+ 133 => 8230, # horizontal ellipsis
70
+ 134 => 8224, # dagger
71
+ 135 => 8225, # double dagger
72
+ 136 => 710, # modifier letter circumflex accent
73
+ 137 => 8240, # per mille sign
74
+ 138 => 352, # latin capital letter s with caron
75
+ 139 => 8249, # single left-pointing angle quotation mark
76
+ 140 => 338, # latin capital ligature oe
77
+ 142 => 381, # latin capital letter z with caron
78
+ 145 => 8216, # left single quotation mark
79
+ 146 => 8217, # right single quotation mark
80
+ 147 => 8220, # left double quotation mark
81
+ 148 => 8221, # right double quotation mark
82
+ 149 => 8226, # bullet
83
+ 150 => 8211, # en dash
84
+ 151 => 8212, # em dash
85
+ 152 => 732, # small tilde
86
+ 153 => 8482, # trade mark sign
87
+ 154 => 353, # latin small letter s with caron
88
+ 155 => 8250, # single right-pointing angle quotation mark
89
+ 156 => 339, # latin small ligature oe
90
+ 158 => 382, # latin small letter z with caron
91
+ 159 => 376 # latin capital letter y with diaeresis
92
+ }
93
+
94
+ # http://www.w3.org/TR/REC-xml/#dt-chardata
95
+ PREDEFINED = {
96
+ 38 => '&amp;', # ampersand
97
+ 60 => '&lt;', # left angle bracket
98
+ 62 => '&gt;' # right angle bracket
99
+ }
84
100
 
85
- # http://www.w3.org/TR/REC-xml/#dt-chardata
86
- PREDEFINED = {
87
- 38 => '&amp;', # ampersand
88
- 60 => '&lt;', # left angle bracket
89
- 62 => '&gt;' # right angle bracket
90
- }
101
+ # http://www.w3.org/TR/REC-xml/#charsets
102
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
103
+ (0xE000..0xFFFD), (0x10000..0x10FFFF)]
91
104
 
92
- # http://www.w3.org/TR/REC-xml/#charsets
93
- VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
94
- (0xE000..0xFFFD), (0x10000..0x10FFFF)]
105
+ def xml_escape(unescaped_str)
106
+ begin
107
+ unescaped_str.unpack("U*").map {|char| xml_escape_char!(char)}.join
108
+ rescue
109
+ unescaped_str.unpack("C*").map {|char| xml_escape_char!(char)}.join
110
+ end
111
+ end
112
+
113
+ private
95
114
 
96
- def xml_escape(unescaped_str)
97
- begin
98
- unescaped_str.unpack("U*").map {|char| xml_escape_char!(char)}.join
99
- rescue
100
- unescaped_str.unpack("C*").map {|char| xml_escape_char!(char)}.join
115
+ def xml_escape_char!(char)
116
+ char = CP1252[char] || char
117
+ char = 42 unless VALID.detect {|range| range.include? char}
118
+ char = PREDEFINED[char] || (char<128 ? char.chr : "&##{char};")
101
119
  end
102
120
  end
121
+
122
+ module FastXS
123
+ extend self
103
124
 
104
- private
125
+ def xml_escape(string)
126
+ string.fast_xs
127
+ end
105
128
 
106
- def xml_escape_char!(char)
107
- char = CP1252[char] || char
108
- char = 42 unless VALID.detect {|range| range.include? char}
109
- char = PREDEFINED[char] || (char<128 ? char.chr : "&##{char};")
110
129
  end
111
130
 
131
+ if "strings".respond_to?(:fast_xs)
132
+ include FastXS
133
+ extend FastXS
134
+ else
135
+ include PureRuby
136
+ extend PureRuby
137
+ end
112
138
  end
113
139
  end
114
140
  end
@@ -197,7 +197,8 @@ class Chef
197
197
  validate(
198
198
  {:name => arg },
199
199
  {:name => { :kind_of => String,
200
- :cannot_be => :blank}
200
+ :cannot_be => :blank,
201
+ :regex => /^[\-[:alnum:]_:.]+$/}
201
202
  })
202
203
  @name = arg
203
204
  else
@@ -352,6 +353,28 @@ class Chef
352
353
  run_list.detect { |r| r == item } ? true : false
353
354
  end
354
355
 
356
+ # Consume data from ohai and Attributes provided as JSON on the command line.
357
+ def consume_external_attrs(ohai_data, json_cli_attrs)
358
+ Chef::Log.debug("Extracting run list from JSON attributes provided on command line")
359
+ consume_attributes(json_cli_attrs)
360
+
361
+ @automatic_attrs = ohai_data
362
+
363
+ platform, version = Chef::Platform.find_platform_and_version(self)
364
+ Chef::Log.debug("Platform is #{platform} version #{version}")
365
+ @automatic_attrs[:platform] = platform
366
+ @automatic_attrs[:platform_version] = version
367
+ end
368
+
369
+ # Consumes the combined run_list and other attributes in +attrs+
370
+ def consume_attributes(attrs)
371
+ normal_attrs_to_merge = consume_run_list(attrs)
372
+ Chef::Log.debug("Applying attributes from json file")
373
+ @normal_attrs = Chef::Mixin::DeepMerge.merge(@normal_attrs,normal_attrs_to_merge)
374
+ self[:tags] = Array.new unless attribute?(:tags)
375
+ end
376
+
377
+ # Extracts the run list from +attrs+ and applies it. Returns the remaining attributes
355
378
  def consume_run_list(attrs)
356
379
  attrs = attrs ? attrs.dup : {}
357
380
  if new_run_list = attrs.delete("recipes") || attrs.delete("run_list")
@@ -364,13 +387,37 @@ class Chef
364
387
  attrs
365
388
  end
366
389
 
367
- # TODO: this code should be killed and removed, but it is used by shef and
368
- # I don't have time to fix it right now. [Dan - 09/Jun/2010]
369
- def consume_attributes(attrs)
370
- attrs = consume_run_list(attrs)
371
- Chef::Log.debug("Applying attributes from json file")
372
- @normal_attrs = Chef::Mixin::DeepMerge.merge(@normal_attrs,attrs)
390
+ # Clear defaults and overrides, so that any deleted attributes between runs are
391
+ # still gone.
392
+ def reset_defaults_and_overrides
393
+ @default_attrs = Mash.new
394
+ @override_attrs = Mash.new
395
+ end
396
+
397
+ # Expands the node's run list and deep merges the default and
398
+ # override attributes. Also applies stored attributes (from json provided
399
+ # on the command line)
400
+ #
401
+ # Returns the fully-expanded list of recipes.
402
+ #
403
+ # TODO: timh/cw, 5-14-2010: Should this method exist? Should we
404
+ # instead modify default_attrs and override_attrs whenever our
405
+ # run_list is mutated? Or perhaps do something smarter like
406
+ # on-demand generation of default_attrs and override_attrs,
407
+ # invalidated only when run_list is mutated?
408
+ def expand!
409
+ # This call should only be called on a chef-client run.
410
+ expansion = run_list.expand('server')
411
+ raise Chef::Exceptions::MissingRole if expansion.errors?
412
+
373
413
  self[:tags] = Array.new unless attribute?(:tags)
414
+ @default_attrs = Chef::Mixin::DeepMerge.merge(default_attrs, expansion.default_attrs)
415
+ @override_attrs = Chef::Mixin::DeepMerge.merge(override_attrs, expansion.override_attrs)
416
+
417
+ @automatic_attrs[:recipes] = expansion.recipes
418
+ @automatic_attrs[:roles] = expansion.roles
419
+
420
+ expansion.recipes
374
421
  end
375
422
 
376
423
  # Transform the node to a Hash
@@ -550,56 +597,5 @@ class Chef
550
597
  self
551
598
  end
552
599
 
553
- # Consume data from ohai and Attributes provided as JSON on the command line.
554
- # The run_list from the command-line attributes will be applied immediately,
555
- # other attributes from the command line will be saved for later. Ohai data
556
- # is applied immediately
557
- def process_external_attrs(ohai_data, json_cli_attrs)
558
- Chef::Log.debug("Extracting run list from JSON attributes provided on command line")
559
- @json_attrib_for_expansion = consume_run_list(json_cli_attrs)
560
-
561
- node.automatic_attrs = ohai_data
562
-
563
- platform, version = Chef::Platform.find_platform_and_version(self)
564
- Chef::Log.debug("Platform is #{platform} version #{version}")
565
- @automatic_attrs[:platform] = platform
566
- @automatic_attrs[:platform_version] = version
567
- end
568
-
569
- # Clear defaults and overrides, so that any deleted attributes between runs are
570
- # still gone.
571
- def reset_defaults_and_overrides
572
- @default_attrs = Mash.new
573
- @override_attrs = Mash.new
574
- end
575
-
576
- # Expands the node's run list and deep merges the default and
577
- # override attributes. Also applies stored attributes (from json provided
578
- # on the command line)
579
- #
580
- # Returns the fully-expanded list of recipes.
581
- #
582
- # TODO: timh/cw, 5-14-2010: Should this method exist? Should we
583
- # instead modify default_attrs and override_attrs whenever our
584
- # run_list is mutated? Or perhaps do something smarter like
585
- # on-demand generation of default_attrs and override_attrs,
586
- # invalidated only when run_list is mutated?
587
- def expand!
588
- # This call should only be called on a chef-client run.
589
- expansion = run_list.expand('server')
590
- raise Chef::Exceptions::MissingRole if expansion.errors?
591
-
592
- Chef::Log.debug("Applying attributes from json file")
593
- @normal_attrs = Chef::Mixin::DeepMerge.merge(@normal_attrs, @json_attrib_for_expansion)
594
- self[:tags] = Array.new unless attribute?(:tags)
595
- @default_attrs = Chef::Mixin::DeepMerge.merge(default_attrs, expansion.default_attrs)
596
- @override_attrs = Chef::Mixin::DeepMerge.merge(override_attrs, expansion.override_attrs)
597
-
598
- @automatic_attrs[:recipes] = expansion.recipes
599
- @automatic_attrs[:roles] = expansion.roles
600
-
601
- expansion.recipes
602
- end
603
-
604
600
  end
605
601
  end