chef 0.9.8 → 0.9.10.rc.0

Sign up to get free protection for your applications and to get access to all the features.
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