chef 0.7.10
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chef might be problematic. Click here for more details.
- data/LICENSE +201 -0
- data/README.rdoc +135 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +26 -0
- data/lib/chef.rb +49 -0
- data/lib/chef/application.rb +98 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +209 -0
- data/lib/chef/application/indexer.rb +141 -0
- data/lib/chef/application/server.rb +18 -0
- data/lib/chef/application/solo.rb +214 -0
- data/lib/chef/client.rb +396 -0
- data/lib/chef/compile.rb +138 -0
- data/lib/chef/config.rb +141 -0
- data/lib/chef/cookbook.rb +144 -0
- data/lib/chef/cookbook/metadata.rb +407 -0
- data/lib/chef/cookbook/metadata/version.rb +87 -0
- data/lib/chef/cookbook_loader.rb +168 -0
- data/lib/chef/couchdb.rb +172 -0
- data/lib/chef/daemon.rb +170 -0
- data/lib/chef/exceptions.rb +36 -0
- data/lib/chef/file_cache.rb +205 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +37 -0
- data/lib/chef/mixin/command.rb +351 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +36 -0
- data/lib/chef/mixin/find_preferred_file.rb +99 -0
- data/lib/chef/mixin/from_file.rb +36 -0
- data/lib/chef/mixin/generate_url.rb +48 -0
- data/lib/chef/mixin/language.rb +79 -0
- data/lib/chef/mixin/params_validate.rb +197 -0
- data/lib/chef/mixin/template.rb +84 -0
- data/lib/chef/node.rb +406 -0
- data/lib/chef/node/attribute.rb +412 -0
- data/lib/chef/openid_registration.rb +181 -0
- data/lib/chef/platform.rb +253 -0
- data/lib/chef/provider.rb +40 -0
- data/lib/chef/provider/cron.rb +137 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/execute.rb +58 -0
- data/lib/chef/provider/file.rb +191 -0
- data/lib/chef/provider/group.rb +120 -0
- data/lib/chef/provider/group/groupadd.rb +92 -0
- data/lib/chef/provider/group/pw.rb +88 -0
- data/lib/chef/provider/http_request.rb +102 -0
- data/lib/chef/provider/ifconfig.rb +131 -0
- data/lib/chef/provider/link.rb +157 -0
- data/lib/chef/provider/mount.rb +121 -0
- data/lib/chef/provider/mount/mount.rb +208 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +113 -0
- data/lib/chef/provider/package/freebsd.rb +153 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/portage.rb +124 -0
- data/lib/chef/provider/package/rpm.rb +99 -0
- data/lib/chef/provider/package/rubygems.rb +130 -0
- data/lib/chef/provider/package/yum-dump.py +104 -0
- data/lib/chef/provider/package/yum.rb +175 -0
- data/lib/chef/provider/remote_directory.rb +126 -0
- data/lib/chef/provider/remote_file.rb +134 -0
- data/lib/chef/provider/route.rb +118 -0
- data/lib/chef/provider/ruby_block.rb +15 -0
- data/lib/chef/provider/script.rb +42 -0
- data/lib/chef/provider/service.rb +129 -0
- data/lib/chef/provider/service/debian.rb +64 -0
- data/lib/chef/provider/service/freebsd.rb +157 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +126 -0
- data/lib/chef/provider/service/redhat.rb +62 -0
- data/lib/chef/provider/template.rb +141 -0
- data/lib/chef/provider/user.rb +170 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +107 -0
- data/lib/chef/queue.rb +145 -0
- data/lib/chef/recipe.rb +210 -0
- data/lib/chef/resource.rb +256 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/cron.rb +143 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +84 -0
- data/lib/chef/resource/gem_package.rb +41 -0
- data/lib/chef/resource/group.rb +68 -0
- data/lib/chef/resource/http_request.rb +52 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +91 -0
- data/lib/chef/resource/remote_file.rb +60 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +20 -0
- data/lib/chef/resource/script.rb +51 -0
- data/lib/chef/resource/service.rb +134 -0
- data/lib/chef/resource/template.rb +60 -0
- data/lib/chef/resource/user.rb +98 -0
- data/lib/chef/resource_collection.rb +176 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/rest.rb +238 -0
- data/lib/chef/role.rb +231 -0
- data/lib/chef/run_list.rb +156 -0
- data/lib/chef/runner.rb +123 -0
- data/lib/chef/search.rb +88 -0
- data/lib/chef/search/result.rb +64 -0
- data/lib/chef/search_index.rb +77 -0
- data/lib/chef/tasks/chef_repo.rake +345 -0
- data/lib/chef/util/file_edit.rb +125 -0
- data/lib/chef/util/fileedit.rb +121 -0
- metadata +262 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Stephen Haynes (<sh@nomitor.com>)
|
3
|
+
# Copyright:: Copyright (c) 2009 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/provider/user'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Provider
|
23
|
+
class User
|
24
|
+
class Pw < Chef::Provider::User
|
25
|
+
|
26
|
+
def load_current_resource
|
27
|
+
super
|
28
|
+
raise Chef::Exceptions::User, "Could not find binary /usr/sbin/pw for #{@new_resource}" unless ::File.exists?("/usr/sbin/pw")
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_user
|
32
|
+
command = "pw useradd"
|
33
|
+
command << set_options
|
34
|
+
run_command(:command => command)
|
35
|
+
modify_password
|
36
|
+
end
|
37
|
+
|
38
|
+
def manage_user
|
39
|
+
command = "pw usermod"
|
40
|
+
command << set_options
|
41
|
+
run_command(:command => command)
|
42
|
+
modify_password
|
43
|
+
end
|
44
|
+
|
45
|
+
def remove_user
|
46
|
+
command = "pw userdel #{@new_resource.username}"
|
47
|
+
command << " -r" if @new_resource.supports[:manage_home]
|
48
|
+
run_command(:command => command)
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_lock
|
52
|
+
case @current_resource.password
|
53
|
+
when /^\*LOCKED\*/
|
54
|
+
@locked = true
|
55
|
+
else
|
56
|
+
@locked = false
|
57
|
+
end
|
58
|
+
@locked
|
59
|
+
end
|
60
|
+
|
61
|
+
def lock_user
|
62
|
+
run_command(:command => "pw lock #{@new_resource.username}")
|
63
|
+
end
|
64
|
+
|
65
|
+
def unlock_user
|
66
|
+
run_command(:command => "pw unlock #{@new_resource.username}")
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_options
|
70
|
+
opts = " #{@new_resource.username}"
|
71
|
+
|
72
|
+
field_list = {
|
73
|
+
'comment' => "-c",
|
74
|
+
'home' => "-d",
|
75
|
+
'gid' => "-g",
|
76
|
+
'uid' => "-u",
|
77
|
+
'shell' => "-s"
|
78
|
+
}
|
79
|
+
field_list.sort{ |a,b| a[0] <=> b[0] }.each do |field, option|
|
80
|
+
field_symbol = field.to_sym
|
81
|
+
if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
|
82
|
+
if @new_resource.send(field_symbol)
|
83
|
+
Chef::Log.debug("Setting #{@new_resource} #{field} to #{@new_resource.send(field_symbol)}")
|
84
|
+
opts << " #{option} '#{@new_resource.send(field_symbol)}'"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
if @new_resource.supports[:manage_home]
|
89
|
+
Chef::Log.debug("Managing the home directory for #{@new_resource}")
|
90
|
+
opts << " -m"
|
91
|
+
end
|
92
|
+
opts
|
93
|
+
end
|
94
|
+
|
95
|
+
def modify_password
|
96
|
+
if @current_resource.password != @new_resource.password
|
97
|
+
Chef::Log.debug("#{new_resource}: updating password")
|
98
|
+
command = "pw usermod #{@new_resource.username} -H 0"
|
99
|
+
status = popen4(command, :waitlast => true) do |pid, stdin, stdout, stderr|
|
100
|
+
stdin.puts "#{@new_resource.password}"
|
101
|
+
end
|
102
|
+
|
103
|
+
unless status.exitstatus == 0
|
104
|
+
raise Chef::Exceptions::User, "pw failed - #{status.inspect}!"
|
105
|
+
end
|
106
|
+
else
|
107
|
+
Chef::Log.debug("#{new_resource}: no change needed to password")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/provider/user'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Provider
|
23
|
+
class User
|
24
|
+
class Useradd < Chef::Provider::User
|
25
|
+
def create_user
|
26
|
+
command = "useradd"
|
27
|
+
command << set_options
|
28
|
+
run_command(:command => command)
|
29
|
+
end
|
30
|
+
|
31
|
+
def manage_user
|
32
|
+
command = "usermod"
|
33
|
+
command << set_options
|
34
|
+
run_command(:command => command)
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_user
|
38
|
+
command = "userdel"
|
39
|
+
command << " -r" if @new_resource.supports[:manage_home]
|
40
|
+
command << " #{@new_resource.username}"
|
41
|
+
run_command(:command => command)
|
42
|
+
end
|
43
|
+
|
44
|
+
def check_lock
|
45
|
+
status = popen4("passwd -S #{@new_resource.username}") do |pid, stdin, stdout, stderr|
|
46
|
+
status_line = stdout.gets.split(' ')
|
47
|
+
case status_line[1]
|
48
|
+
when /^P/
|
49
|
+
@locked = false
|
50
|
+
when /^N/
|
51
|
+
@locked = false
|
52
|
+
when /^L/
|
53
|
+
@locked = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
unless status.exitstatus == 0
|
58
|
+
raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!"
|
59
|
+
end
|
60
|
+
|
61
|
+
@locked
|
62
|
+
end
|
63
|
+
|
64
|
+
def lock_user
|
65
|
+
run_command(:command => "usermod -L #{@new_resource.username}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def unlock_user
|
69
|
+
run_command(:command => "usermod -U #{@new_resource.username}")
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_options
|
73
|
+
opts = ''
|
74
|
+
|
75
|
+
field_list = {
|
76
|
+
'comment' => "-c",
|
77
|
+
'gid' => "-g",
|
78
|
+
'uid' => "-u",
|
79
|
+
'shell' => "-s",
|
80
|
+
'password' => "-p"
|
81
|
+
}
|
82
|
+
field_list.sort{ |a,b| a[0] <=> b[0] }.each do |field, option|
|
83
|
+
field_symbol = field.to_sym
|
84
|
+
if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
|
85
|
+
if @new_resource.send(field_symbol)
|
86
|
+
Chef::Log.debug("Setting #{@new_resource} #{field} to #{@new_resource.send(field_symbol)}")
|
87
|
+
opts << " #{option} '#{@new_resource.send(field_symbol)}'"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
if @current_resource.home != @new_resource.home && @new_resource.home
|
92
|
+
if @new_resource.supports[:manage_home]
|
93
|
+
Chef::Log.debug("Managing the home directory for #{@new_resource}")
|
94
|
+
opts << " -d '#{@new_resource.home}' -m"
|
95
|
+
else
|
96
|
+
Chef::Log.debug("Setting #{@new_resource} home to #{@new_resource.home}")
|
97
|
+
opts << " -d '#{@new_resource.home}'"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
opts << " #{@new_resource.username}"
|
101
|
+
opts
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/chef/queue.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/mixin/params_validate'
|
20
|
+
require 'json'
|
21
|
+
require 'stomp'
|
22
|
+
|
23
|
+
class Chef
|
24
|
+
class Queue
|
25
|
+
|
26
|
+
@client = nil
|
27
|
+
@queue_retry_delay = Chef::Config[:queue_retry_delay]
|
28
|
+
@queue_retry_count = Chef::Config[:queue_retry_count]
|
29
|
+
|
30
|
+
class << self
|
31
|
+
include Chef::Mixin::ParamsValidate
|
32
|
+
|
33
|
+
def connect
|
34
|
+
queue_user = Chef::Config[:queue_user]
|
35
|
+
queue_password = Chef::Config[:queue_password]
|
36
|
+
queue_host = Chef::Config[:queue_host]
|
37
|
+
queue_port = Chef::Config[:queue_port]
|
38
|
+
queue_retries = 1 unless queue_retries
|
39
|
+
|
40
|
+
# Connection.open(login = "", passcode = "", host='localhost', port=61613, reliable=FALSE, reconnectDelay=5)
|
41
|
+
@client = Stomp::Connection.open(queue_user, queue_password, queue_host, queue_port, false)
|
42
|
+
|
43
|
+
rescue Errno::ECONNREFUSED
|
44
|
+
Chef::Log.error("Connection refused connecting to stomp queue at #{queue_host}:#{queue_port}, retry #{queue_retries}/#{@queue_retry_count}")
|
45
|
+
sleep(@queue_retry_delay)
|
46
|
+
retry if (queue_retries += 1) < @queue_retry_count
|
47
|
+
raise Errno::ECONNREFUSED, "Connection refused connecting to stomp queue at #{queue_host}:#{queue_port}, giving up"
|
48
|
+
rescue Timeout::Error
|
49
|
+
Chef::Log.error("Timeout connecting to stomp queue at #{queue_host}:#{queue_port}, retry #{queue_retries}/#{@queue_retry_count}")
|
50
|
+
sleep(@queue_retry_delay)
|
51
|
+
retry if (queue_retries += 1) < @queue_retry_count
|
52
|
+
raise Timeout::Error, "Timeout connecting to stomp queue at #{queue_host}:#{queue_port}, giving up"
|
53
|
+
else
|
54
|
+
queue_retries = 1 # reset the number of retries on success
|
55
|
+
end
|
56
|
+
|
57
|
+
def make_url(type, name)
|
58
|
+
validate(
|
59
|
+
{
|
60
|
+
:queue_type => type.to_sym,
|
61
|
+
:queue_name => name.to_sym,
|
62
|
+
},
|
63
|
+
{
|
64
|
+
:queue_type => {
|
65
|
+
:equal_to => [ :topic, :queue ],
|
66
|
+
},
|
67
|
+
:queue_name => {
|
68
|
+
:kind_of => [ String, Symbol ],
|
69
|
+
}
|
70
|
+
}
|
71
|
+
)
|
72
|
+
if Chef::Config[:queue_prefix]
|
73
|
+
queue_prefix = Chef::Config[:queue_prefix]
|
74
|
+
queue_url = "/#{type}/#{queue_prefix}/chef/#{name}"
|
75
|
+
else
|
76
|
+
queue_url = "/#{type}/chef/#{name}"
|
77
|
+
end
|
78
|
+
queue_url
|
79
|
+
end
|
80
|
+
|
81
|
+
def subscribe(type, name)
|
82
|
+
queue_url = make_url(type, name)
|
83
|
+
Chef::Log.debug("Subscribing to #{queue_url}")
|
84
|
+
connect if @client == nil
|
85
|
+
@client.subscribe(queue_url)
|
86
|
+
end
|
87
|
+
|
88
|
+
def send_msg(type, name, msg)
|
89
|
+
queue_retries = 1 unless queue_retries
|
90
|
+
validate(
|
91
|
+
{
|
92
|
+
:message => msg,
|
93
|
+
},
|
94
|
+
{
|
95
|
+
:message => {
|
96
|
+
:respond_to => :to_json
|
97
|
+
}
|
98
|
+
}
|
99
|
+
)
|
100
|
+
queue_url = make_url(type, name)
|
101
|
+
json = msg.to_json
|
102
|
+
connect if @client == nil
|
103
|
+
Chef::Log.debug("Sending to #{queue_url}: #{json}")
|
104
|
+
begin
|
105
|
+
@client.send(queue_url, json)
|
106
|
+
rescue Errno::EPIPE
|
107
|
+
Chef::Log.debug("Lost connection to stomp queue, reconnecting")
|
108
|
+
connect
|
109
|
+
retry if (queue_retries += 1) < @queue_retry_count
|
110
|
+
raise Errno::EPIPE, "Lost connection to stomp queue, giving up"
|
111
|
+
else
|
112
|
+
queue_retries = 1 # reset the number of retries on success
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def receive_msg
|
117
|
+
connect if @client == nil
|
118
|
+
begin
|
119
|
+
raw_msg = @client.receive()
|
120
|
+
Chef::Log.debug("Received Message from #{raw_msg.headers["destination"]} containing: #{raw_msg.body}")
|
121
|
+
rescue
|
122
|
+
Chef::Log.debug("Received nil message from stomp, retrying")
|
123
|
+
retry
|
124
|
+
end
|
125
|
+
msg = JSON.parse(raw_msg.body)
|
126
|
+
return msg, raw_msg.headers
|
127
|
+
end
|
128
|
+
|
129
|
+
def poll_msg
|
130
|
+
connect if @client == nil
|
131
|
+
raw_msg = @client.poll()
|
132
|
+
if raw_msg
|
133
|
+
msg = JSON.parse(raw_msg.body)
|
134
|
+
else
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def disconnect
|
140
|
+
raise ArgumentError, "You must call connect before you can disconnect!" unless @client
|
141
|
+
@client.disconnect
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/chef/recipe.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/resource'
|
20
|
+
Dir[File.join(File.dirname(__FILE__), 'resource/**/*.rb')].sort.each { |lib| require lib }
|
21
|
+
require 'chef/mixin/from_file'
|
22
|
+
require 'chef/mixin/language'
|
23
|
+
require 'chef/resource_collection'
|
24
|
+
require 'chef/cookbook_loader'
|
25
|
+
require 'chef/rest'
|
26
|
+
require 'chef/search/result'
|
27
|
+
|
28
|
+
class Chef
|
29
|
+
class Recipe
|
30
|
+
|
31
|
+
include Chef::Mixin::FromFile
|
32
|
+
include Chef::Mixin::Language
|
33
|
+
|
34
|
+
attr_accessor :cookbook_name, :recipe_name, :recipe, :node, :collection,
|
35
|
+
:definitions, :params, :cookbook_loader
|
36
|
+
|
37
|
+
def initialize(cookbook_name, recipe_name, node, collection=nil, definitions=nil, cookbook_loader=nil)
|
38
|
+
@cookbook_name = cookbook_name
|
39
|
+
@recipe_name = recipe_name
|
40
|
+
@node = node
|
41
|
+
|
42
|
+
if collection
|
43
|
+
@collection = collection
|
44
|
+
else
|
45
|
+
@collection = Chef::ResourceCollection.new()
|
46
|
+
end
|
47
|
+
|
48
|
+
if definitions
|
49
|
+
@definitions = definitions
|
50
|
+
else
|
51
|
+
@definitions = Hash.new
|
52
|
+
end
|
53
|
+
|
54
|
+
if cookbook_loader
|
55
|
+
@cookbook_loader = cookbook_loader
|
56
|
+
else
|
57
|
+
@cookbook_loader = Chef::CookbookLoader.new()
|
58
|
+
end
|
59
|
+
|
60
|
+
@params = Hash.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def include_recipe(*args)
|
64
|
+
args.flatten.each do |recipe|
|
65
|
+
if @node.run_state[:seen_recipes].has_key?(recipe)
|
66
|
+
Chef::Log.debug("I am not loading #{recipe}, because I have already seen it.")
|
67
|
+
next
|
68
|
+
end
|
69
|
+
|
70
|
+
Chef::Log.debug("Loading Recipe #{recipe} via include_recipe")
|
71
|
+
@node.run_state[:seen_recipes][recipe] = true
|
72
|
+
|
73
|
+
rmatch = recipe.match(/(.+?)::(.+)/)
|
74
|
+
if rmatch
|
75
|
+
cookbook = @cookbook_loader[rmatch[1]]
|
76
|
+
cookbook.load_recipe(rmatch[2], @node, @collection, @definitions, @cookbook_loader)
|
77
|
+
else
|
78
|
+
cookbook = @cookbook_loader[recipe]
|
79
|
+
cookbook.load_recipe("default", @node, @collection, @definitions, @cookbook_loader)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def require_recipe(*args)
|
85
|
+
include_recipe(*args)
|
86
|
+
end
|
87
|
+
|
88
|
+
def resources(*args)
|
89
|
+
@collection.resources(*args)
|
90
|
+
end
|
91
|
+
|
92
|
+
def search(type, query, attributes=[], &block)
|
93
|
+
Chef::Log.debug("Searching #{type} index with #{query}")
|
94
|
+
r = Chef::REST.new(Chef::Config[:search_url])
|
95
|
+
|
96
|
+
results = r.get_rest("search/#{type}?q=#{query}&a=#{attributes.join(',')}")
|
97
|
+
Chef::Log.debug("Searching #{type} index with #{query} returned #{results.length} entries")
|
98
|
+
if block
|
99
|
+
results.each do |sr|
|
100
|
+
block.call(sr)
|
101
|
+
end
|
102
|
+
else
|
103
|
+
results
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Sets a tag, or list of tags, for this node. Syntactic sugar for
|
108
|
+
# @node[:tags].
|
109
|
+
#
|
110
|
+
# With no arguments, returns the list of tags.
|
111
|
+
#
|
112
|
+
# === Parameters
|
113
|
+
# tags<Array>:: A list of tags to add - can be a single string
|
114
|
+
#
|
115
|
+
# === Returns
|
116
|
+
# tags<Array>:: The contents of @node[:tags]
|
117
|
+
def tag(*args)
|
118
|
+
if args.length > 0
|
119
|
+
args.each do |tag|
|
120
|
+
@node[:tags] << tag unless @node[:tags].include?(tag)
|
121
|
+
end
|
122
|
+
@node[:tags]
|
123
|
+
else
|
124
|
+
@node[:tags]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns true if the node is tagged with the supplied list of tags.
|
129
|
+
#
|
130
|
+
# === Parameters
|
131
|
+
# tags<Array>:: A list of tags
|
132
|
+
#
|
133
|
+
# === Returns
|
134
|
+
# true<TrueClass>:: If all the parameters are present
|
135
|
+
# false<FalseClass>:: If any of the parameters are missing
|
136
|
+
def tagged?(*args)
|
137
|
+
args.each do |tag|
|
138
|
+
return false unless @node[:tags].include?(tag)
|
139
|
+
end
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
# Removes the list of tags from the node.
|
144
|
+
#
|
145
|
+
# === Parameters
|
146
|
+
# tags<Array>:: A list of tags
|
147
|
+
#
|
148
|
+
# === Returns
|
149
|
+
# tags<Array>:: The current list of @node[:tags]
|
150
|
+
def untag(*args)
|
151
|
+
args.each do |tag|
|
152
|
+
@node[:tags].delete(tag)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def method_missing(method_symbol, *args, &block)
|
157
|
+
resource = nil
|
158
|
+
# If we have a definition that matches, we want to use that instead. This should
|
159
|
+
# let you do some really crazy over-riding of "native" types, if you really want
|
160
|
+
# to.
|
161
|
+
if @definitions.has_key?(method_symbol)
|
162
|
+
# This dupes the high level object, but we still need to dup the params
|
163
|
+
new_def = @definitions[method_symbol].dup
|
164
|
+
new_def.params = new_def.params.dup
|
165
|
+
new_def.node = @node
|
166
|
+
# This sets up the parameter overrides
|
167
|
+
new_def.instance_eval(&block) if block
|
168
|
+
new_recipe = Chef::Recipe.new(@cookbook_name, @recipe_name, @node, @collection, @definitions, @cookbook_loader)
|
169
|
+
new_recipe.params = new_def.params
|
170
|
+
new_recipe.params[:name] = args[0]
|
171
|
+
new_recipe.instance_eval(&new_def.recipe)
|
172
|
+
else
|
173
|
+
method_name = method_symbol.to_s
|
174
|
+
# Otherwise, we're rocking the regular resource call route.
|
175
|
+
rname = nil
|
176
|
+
regexp = %r{^(.+?)(_(.+))?$}
|
177
|
+
|
178
|
+
mn = method_name.match(regexp)
|
179
|
+
if mn
|
180
|
+
rname = "Chef::Resource::#{mn[1].capitalize}"
|
181
|
+
|
182
|
+
while mn && mn[3]
|
183
|
+
mn = mn[3].match(regexp)
|
184
|
+
rname << mn[1].capitalize if mn
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
begin
|
189
|
+
args << @collection
|
190
|
+
args << @node
|
191
|
+
resource = eval(rname).new(*args)
|
192
|
+
# If we have a resource like this one, we want to steal it's state
|
193
|
+
resource.load_prior_resource
|
194
|
+
resource.cookbook_name = @cookbook_name
|
195
|
+
resource.recipe_name = @recipe_name
|
196
|
+
resource.params = @params
|
197
|
+
resource.instance_eval(&block) if block
|
198
|
+
rescue Exception => e
|
199
|
+
if e.kind_of?(NameError) && e.to_s =~ /Chef::Resource/
|
200
|
+
raise NameError, "Cannot find #{rname} for #{method_name}\nOriginal: #{e.to_s}"
|
201
|
+
else
|
202
|
+
raise e
|
203
|
+
end
|
204
|
+
end
|
205
|
+
@collection << resource
|
206
|
+
resource
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|