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.
- 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
|