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.
- data/README.rdoc +1 -1
- data/distro/common/man/man8/knife.8 +89 -79
- data/distro/common/markdown/knife.mkd +7 -0
- data/distro/debian/etc/default/chef-server +3 -0
- data/distro/debian/etc/default/chef-server-webui +3 -0
- data/distro/debian/etc/default/chef-solr +3 -0
- data/distro/debian/etc/default/chef-solr-indexer +3 -0
- data/distro/debian/etc/init.d/chef-server +3 -1
- data/distro/debian/etc/init.d/chef-server-webui +3 -1
- data/distro/redhat/etc/init.d/chef-client +1 -1
- data/lib/chef/application.rb +2 -0
- data/lib/chef/application/client.rb +5 -3
- data/lib/chef/application/knife.rb +16 -5
- data/lib/chef/application/solo.rb +0 -1
- data/lib/chef/checksum.rb +65 -1
- data/lib/chef/checksum_cache.rb +173 -0
- data/lib/chef/client.rb +84 -121
- data/lib/chef/cookbook/remote_file_vendor.rb +10 -3
- data/lib/chef/cookbook/syntax_check.rb +2 -2
- data/lib/chef/cookbook_loader.rb +2 -0
- data/lib/chef/cookbook_site_streaming_uploader.rb +29 -0
- data/lib/chef/cookbook_uploader.rb +8 -7
- data/lib/chef/cookbook_version.rb +155 -114
- data/lib/chef/exceptions.rb +5 -0
- data/lib/chef/handler.rb +43 -0
- data/lib/chef/index_queue/consumer.rb +1 -1
- data/lib/chef/index_queue/indexable.rb +1 -1
- data/lib/chef/knife.rb +18 -5
- data/lib/chef/knife/bootstrap.rb +2 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +44 -0
- data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -7
- data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
- data/lib/chef/knife/configure_client.rb +4 -2
- data/lib/chef/knife/cookbook_metadata.rb +1 -1
- data/lib/chef/knife/cookbook_site_share.rb +2 -1
- data/lib/chef/knife/cookbook_site_vendor.rb +6 -0
- data/lib/chef/knife/cookbook_test.rb +1 -1
- data/lib/chef/knife/ec2_server_create.rb +51 -26
- data/lib/chef/knife/exec.rb +52 -0
- data/lib/chef/knife/ssh.rb +27 -15
- data/lib/chef/knife/status.rb +27 -10
- data/lib/chef/knife/windows_bootstrap.rb +154 -0
- data/lib/chef/mixin/checksum.rb +2 -2
- data/lib/chef/mixin/xml_escape.rb +75 -49
- data/lib/chef/node.rb +54 -58
- data/lib/chef/node/attribute.rb +61 -53
- data/lib/chef/platform.rb +19 -2
- data/lib/chef/provider/breakpoint.rb +1 -1
- data/lib/chef/provider/cookbook_file.rb +3 -3
- data/lib/chef/provider/cron.rb +3 -3
- data/lib/chef/provider/cron/solaris.rb +195 -0
- data/lib/chef/provider/deploy.rb +3 -3
- data/lib/chef/provider/directory.rb +2 -2
- data/lib/chef/provider/env.rb +5 -5
- data/lib/chef/provider/execute.rb +1 -1
- data/lib/chef/provider/file.rb +10 -9
- data/lib/chef/provider/git.rb +12 -4
- data/lib/chef/provider/group.rb +5 -5
- data/lib/chef/provider/http_request.rb +25 -9
- data/lib/chef/provider/ifconfig.rb +2 -2
- data/lib/chef/provider/link.rb +11 -6
- data/lib/chef/provider/log.rb +1 -0
- data/lib/chef/provider/mdadm.rb +3 -3
- data/lib/chef/provider/mount.rb +5 -5
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/ohai.rb +41 -0
- data/lib/chef/provider/package.rb +5 -5
- data/lib/chef/provider/package/yum-dump.py +5 -2
- data/lib/chef/provider/remote_directory.rb +11 -5
- data/lib/chef/provider/remote_file.rb +2 -2
- data/lib/chef/provider/route.rb +154 -133
- data/lib/chef/provider/ruby_block.rb +1 -1
- data/lib/chef/provider/service.rb +6 -6
- data/lib/chef/provider/subversion.rb +12 -9
- data/lib/chef/provider/template.rb +2 -2
- data/lib/chef/provider/user.rb +7 -7
- data/lib/chef/provider/user/useradd.rb +15 -1
- data/lib/chef/providers.rb +2 -0
- data/lib/chef/resource.rb +164 -58
- data/lib/chef/resource/http_request.rb +9 -0
- data/lib/chef/resource/ohai.rb +40 -0
- data/lib/chef/resource/remote_directory.rb +10 -1
- data/lib/chef/resource/rpm_package.rb +34 -0
- data/lib/chef/resource_collection.rb +3 -2
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +13 -7
- data/lib/chef/rest/auth_credentials.rb +1 -1
- data/lib/chef/rest/rest_request.rb +3 -1
- data/lib/chef/runner.rb +31 -55
- data/lib/chef/shef/shef_session.rb +1 -1
- data/lib/chef/util/windows/net_use.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/webui_user.rb +0 -1
- metadata +38 -19
- data/lib/chef/cache.rb +0 -61
- data/lib/chef/cache/checksum.rb +0 -91
data/lib/chef/knife/ssh.rb
CHANGED
@@ -68,7 +68,19 @@ class Chef
|
|
68
68
|
:description => "The SSH identity file used for authentication"
|
69
69
|
|
70
70
|
def session
|
71
|
-
|
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])
|
86
|
-
|
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
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
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
|
|
data/lib/chef/knife/status.rb
CHANGED
@@ -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
|
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
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
data/lib/chef/mixin/checksum.rb
CHANGED
@@ -17,14 +17,14 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'digest/sha2'
|
20
|
-
require 'chef/
|
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::
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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 => '&', # ampersand
|
97
|
+
60 => '<', # left angle bracket
|
98
|
+
62 => '>' # right angle bracket
|
99
|
+
}
|
84
100
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
60 => '<', # left angle bracket
|
89
|
-
62 => '>' # 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
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
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
|
data/lib/chef/node.rb
CHANGED
@@ -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
|
-
#
|
368
|
-
#
|
369
|
-
def
|
370
|
-
|
371
|
-
|
372
|
-
|
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
|