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,18 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@opscode.comz>)
|
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
|
+
require 'chef/application'
|
@@ -0,0 +1,209 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@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
|
+
require 'chef/application'
|
19
|
+
require 'chef/client'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/daemon'
|
22
|
+
require 'chef/log'
|
23
|
+
require 'net/http'
|
24
|
+
require 'open-uri'
|
25
|
+
|
26
|
+
|
27
|
+
class Chef::Application::Client < Chef::Application
|
28
|
+
|
29
|
+
option :config_file,
|
30
|
+
:short => "-c CONFIG",
|
31
|
+
:long => "--config CONFIG",
|
32
|
+
:default => "/etc/chef/client.rb",
|
33
|
+
:description => "The configuration file to use"
|
34
|
+
|
35
|
+
option :log_level,
|
36
|
+
:short => "-l LEVEL",
|
37
|
+
:long => "--log_level LEVEL",
|
38
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
39
|
+
:proc => lambda { |l| l.to_sym }
|
40
|
+
|
41
|
+
option :log_location,
|
42
|
+
:short => "-L LOGLOCATION",
|
43
|
+
:long => "--logfile LOGLOCATION",
|
44
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
45
|
+
:proc => nil
|
46
|
+
|
47
|
+
option :help,
|
48
|
+
:short => "-h",
|
49
|
+
:long => "--help",
|
50
|
+
:description => "Show this message",
|
51
|
+
:on => :tail,
|
52
|
+
:boolean => true,
|
53
|
+
:show_options => true,
|
54
|
+
:exit => 0
|
55
|
+
|
56
|
+
option :user,
|
57
|
+
:short => "-u USER",
|
58
|
+
:long => "--user USER",
|
59
|
+
:description => "User to set privilege to",
|
60
|
+
:proc => nil
|
61
|
+
|
62
|
+
option :group,
|
63
|
+
:short => "-g GROUP",
|
64
|
+
:long => "--group GROUP",
|
65
|
+
:description => "Group to set privilege to",
|
66
|
+
:proc => nil
|
67
|
+
|
68
|
+
option :daemonize,
|
69
|
+
:short => "-d",
|
70
|
+
:long => "--daemonize",
|
71
|
+
:description => "Daemonize the process",
|
72
|
+
:proc => lambda { |p| true }
|
73
|
+
|
74
|
+
option :interval,
|
75
|
+
:short => "-i SECONDS",
|
76
|
+
:long => "--interval SECONDS",
|
77
|
+
:description => "Run chef-client periodically, in seconds",
|
78
|
+
:proc => lambda { |s| s.to_i }
|
79
|
+
|
80
|
+
option :json_attribs,
|
81
|
+
:short => "-j JSON_ATTRIBS",
|
82
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
83
|
+
:description => "Load attributes from a JSON file or URL",
|
84
|
+
:proc => nil
|
85
|
+
|
86
|
+
option :node_name,
|
87
|
+
:short => "-N NODE_NAME",
|
88
|
+
:long => "--node-name NODE_NAME",
|
89
|
+
:description => "The node name for this client",
|
90
|
+
:proc => nil
|
91
|
+
|
92
|
+
option :splay,
|
93
|
+
:short => "-s SECONDS",
|
94
|
+
:long => "--splay SECONDS",
|
95
|
+
:description => "The splay time for running at intervals, in seconds",
|
96
|
+
:proc => lambda { |s| s.to_i }
|
97
|
+
|
98
|
+
option :chef_server_url,
|
99
|
+
:short => "-S CHEFSERVERURL",
|
100
|
+
:long => "--server CHEFSERVERURL",
|
101
|
+
:description => "The chef server URL",
|
102
|
+
:proc => nil
|
103
|
+
|
104
|
+
option :validation_token,
|
105
|
+
:short => "-t TOKEN",
|
106
|
+
:long => "--token TOKEN",
|
107
|
+
:description => "Set the openid validation token",
|
108
|
+
:proc => nil
|
109
|
+
|
110
|
+
option :version,
|
111
|
+
:short => "-v",
|
112
|
+
:long => "--version",
|
113
|
+
:description => "Show chef version",
|
114
|
+
:boolean => true,
|
115
|
+
:proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
|
116
|
+
:exit => 0
|
117
|
+
|
118
|
+
def initialize
|
119
|
+
super
|
120
|
+
|
121
|
+
@chef_client = nil
|
122
|
+
@chef_client_json = nil
|
123
|
+
end
|
124
|
+
|
125
|
+
# Reconfigure the chef client
|
126
|
+
# Re-open the JSON attributes and load them into the node
|
127
|
+
def reconfigure
|
128
|
+
super
|
129
|
+
|
130
|
+
Chef::Config[:chef_server_url] = config[:chef_server_url] if config.has_key? :chef_server_url
|
131
|
+
|
132
|
+
if Chef::Config[:daemonize]
|
133
|
+
Chef::Config[:interval] ||= 1800
|
134
|
+
end
|
135
|
+
|
136
|
+
if Chef::Config[:json_attribs]
|
137
|
+
begin
|
138
|
+
json_io = open(Chef::Config[:json_attribs])
|
139
|
+
rescue SocketError => error
|
140
|
+
Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
|
141
|
+
rescue Errno::ENOENT => error
|
142
|
+
Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
|
143
|
+
rescue Errno::EACCES => error
|
144
|
+
Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
|
145
|
+
rescue Exception => error
|
146
|
+
Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
|
147
|
+
end
|
148
|
+
|
149
|
+
begin
|
150
|
+
@chef_client_json = JSON.parse(json_io.read)
|
151
|
+
rescue JSON::ParserError => error
|
152
|
+
Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Setup an instance of the chef client
|
158
|
+
# Why is this so ugly? surely the client should just read out of chef::config instead of needing the values to be assigned like this..
|
159
|
+
def setup_application
|
160
|
+
Chef::Daemon.change_privilege
|
161
|
+
|
162
|
+
@chef_client = Chef::Client.new
|
163
|
+
@chef_client.json_attribs = @chef_client_json
|
164
|
+
@chef_client.validation_token = Chef::Config[:validation_token]
|
165
|
+
@chef_client.node_name = Chef::Config[:node_name]
|
166
|
+
end
|
167
|
+
|
168
|
+
# Run the chef client, optionally daemonizing or looping at intervals.
|
169
|
+
def run_application
|
170
|
+
if Chef::Config[:version]
|
171
|
+
puts "Chef version: #{::Chef::VERSION}"
|
172
|
+
end
|
173
|
+
|
174
|
+
if Chef::Config[:daemonize]
|
175
|
+
Chef::Daemon.daemonize("chef-client")
|
176
|
+
end
|
177
|
+
|
178
|
+
loop do
|
179
|
+
begin
|
180
|
+
if Chef::Config[:splay]
|
181
|
+
splay = rand Chef::Config[:splay]
|
182
|
+
Chef::Log.debug("Splay sleep #{splay} seconds")
|
183
|
+
sleep splay
|
184
|
+
end
|
185
|
+
|
186
|
+
@chef_client.run
|
187
|
+
|
188
|
+
if Chef::Config[:interval]
|
189
|
+
Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
|
190
|
+
sleep Chef::Config[:interval]
|
191
|
+
else
|
192
|
+
Chef::Application.exit! "Exiting", 0
|
193
|
+
end
|
194
|
+
rescue SystemExit => e
|
195
|
+
raise
|
196
|
+
rescue Exception => e
|
197
|
+
if Chef::Config[:interval]
|
198
|
+
Chef::Log.error("#{e.class}")
|
199
|
+
Chef::Log.fatal("#{e}\n#{e.backtrace.join("\n")}")
|
200
|
+
Chef::Log.fatal("Sleeping for #{Chef::Config[:interval]} seconds before trying again")
|
201
|
+
sleep Chef::Config[:interval]
|
202
|
+
retry
|
203
|
+
else
|
204
|
+
raise
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@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
|
+
require 'chef/application'
|
19
|
+
require 'chef/queue'
|
20
|
+
require 'chef/search'
|
21
|
+
require 'chef/search_index'
|
22
|
+
require 'chef/config'
|
23
|
+
require 'chef/daemon'
|
24
|
+
require 'chef/log'
|
25
|
+
|
26
|
+
|
27
|
+
class Chef::Application::Indexer < Chef::Application
|
28
|
+
|
29
|
+
option :config_file,
|
30
|
+
:short => "-c CONFIG",
|
31
|
+
:long => "--config CONFIG",
|
32
|
+
:default => "/etc/chef/server.rb",
|
33
|
+
:description => "The configuration file to use"
|
34
|
+
|
35
|
+
option :log_level,
|
36
|
+
:short => "-l LEVEL",
|
37
|
+
:long => "--log_level LEVEL",
|
38
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
39
|
+
:proc => lambda { |l| l.to_sym }
|
40
|
+
|
41
|
+
option :log_location,
|
42
|
+
:short => "-L LOGLOCATION",
|
43
|
+
:long => "--logfile LOGLOCATION",
|
44
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
45
|
+
:proc => nil
|
46
|
+
|
47
|
+
option :help,
|
48
|
+
:short => "-h",
|
49
|
+
:long => "--help",
|
50
|
+
:description => "Show this message",
|
51
|
+
:on => :tail,
|
52
|
+
:boolean => true,
|
53
|
+
:show_options => true,
|
54
|
+
:exit => 0
|
55
|
+
|
56
|
+
option :user,
|
57
|
+
:short => "-u USER",
|
58
|
+
:long => "--user USER",
|
59
|
+
:description => "User to set privilege to",
|
60
|
+
:proc => nil
|
61
|
+
|
62
|
+
option :group,
|
63
|
+
:short => "-g GROUP",
|
64
|
+
:long => "--group GROUP",
|
65
|
+
:description => "Group to set privilege to",
|
66
|
+
:proc => nil
|
67
|
+
|
68
|
+
option :daemonize,
|
69
|
+
:short => "-d",
|
70
|
+
:long => "--daemonize",
|
71
|
+
:description => "Daemonize the process",
|
72
|
+
:proc => lambda { |p| true }
|
73
|
+
|
74
|
+
option :version,
|
75
|
+
:short => "-v",
|
76
|
+
:long => "--version",
|
77
|
+
:description => "Show chef version",
|
78
|
+
:boolean => true,
|
79
|
+
:proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
|
80
|
+
:exit => 0
|
81
|
+
|
82
|
+
def initialize
|
83
|
+
super
|
84
|
+
|
85
|
+
@chef_search_indexer = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# Create a new search indexer and connect to the stomp queues
|
89
|
+
def setup_application
|
90
|
+
Chef::Daemon.change_privilege
|
91
|
+
|
92
|
+
@chef_search_indexer = Chef::SearchIndex.new
|
93
|
+
Chef::Queue.connect
|
94
|
+
Chef::Queue.subscribe(:queue, "index")
|
95
|
+
Chef::Queue.subscribe(:queue, "remove")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Run the indexer, optionally daemonizing.
|
99
|
+
def run_application
|
100
|
+
if Chef::Config[:daemonize]
|
101
|
+
Chef::Daemon.daemonize("chef-indexer")
|
102
|
+
end
|
103
|
+
|
104
|
+
if Chef::Config[:queue_prefix]
|
105
|
+
queue_prefix = Chef::Config[:queue_prefix]
|
106
|
+
queue_partial_url = "/queue/#{queue_prefix}/chef"
|
107
|
+
else
|
108
|
+
queue_partial_url = "/queue/chef"
|
109
|
+
end
|
110
|
+
|
111
|
+
loop do
|
112
|
+
object, headers = Chef::Queue.receive_msg
|
113
|
+
Chef::Log.info("Headers #{headers.inspect}")
|
114
|
+
if headers["destination"] == "#{queue_partial_url}/index"
|
115
|
+
start_timer = Time.new
|
116
|
+
@chef_search_indexer.add(object)
|
117
|
+
@chef_search_indexer.commit
|
118
|
+
final_timer = Time.new
|
119
|
+
Chef::Log.info("Indexed object from #{headers['destination']} in #{final_timer - start_timer} seconds")
|
120
|
+
elsif headers["destination"] == "#{queue_partial_url}/remove"
|
121
|
+
start_timer = Time.new
|
122
|
+
@chef_search_indexer.delete(object)
|
123
|
+
@chef_search_indexer.commit
|
124
|
+
final_timer = Time.new
|
125
|
+
Chef::Log.info("Removed object from #{headers['destination']} in #{final_timer - start_timer} seconds")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
rescue SystemExit => e
|
129
|
+
raise
|
130
|
+
rescue Exception => e
|
131
|
+
if Chef::Config[:interval]
|
132
|
+
Chef::Log.error("#{e.class}")
|
133
|
+
Chef::Log.fatal("#{e}\n#{e.backtrace.join("\n")}")
|
134
|
+
Chef::Log.fatal("Sleeping for #{Chef::Config[:delay]} seconds before trying again")
|
135
|
+
sleep Chef::Config[:delay]
|
136
|
+
retry
|
137
|
+
else
|
138
|
+
raise
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@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
|
+
require 'chef/application'
|
@@ -0,0 +1,214 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@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
|
+
require 'chef/application'
|
19
|
+
require 'chef/client'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/daemon'
|
22
|
+
require 'chef/log'
|
23
|
+
require 'net/http'
|
24
|
+
require 'open-uri'
|
25
|
+
require 'fileutils'
|
26
|
+
|
27
|
+
class Chef::Application::Solo < Chef::Application
|
28
|
+
|
29
|
+
option :config_file,
|
30
|
+
:short => "-c CONFIG",
|
31
|
+
:long => "--config CONFIG",
|
32
|
+
:default => "/etc/chef/solo.rb",
|
33
|
+
:description => "The configuration file to use"
|
34
|
+
|
35
|
+
option :log_level,
|
36
|
+
:short => "-l LEVEL",
|
37
|
+
:long => "--log_level LEVEL",
|
38
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
39
|
+
:proc => lambda { |l| l.to_sym }
|
40
|
+
|
41
|
+
option :log_location,
|
42
|
+
:short => "-L LOGLOCATION",
|
43
|
+
:long => "--logfile LOGLOCATION",
|
44
|
+
:description => "Set the log file location, defaults to STDOUT",
|
45
|
+
:proc => nil
|
46
|
+
|
47
|
+
option :help,
|
48
|
+
:short => "-h",
|
49
|
+
:long => "--help",
|
50
|
+
:description => "Show this message",
|
51
|
+
:on => :tail,
|
52
|
+
:boolean => true,
|
53
|
+
:show_options => true,
|
54
|
+
:exit => 0
|
55
|
+
|
56
|
+
option :user,
|
57
|
+
:short => "-u USER",
|
58
|
+
:long => "--user USER",
|
59
|
+
:description => "User to set privilege to",
|
60
|
+
:proc => nil
|
61
|
+
|
62
|
+
option :group,
|
63
|
+
:short => "-g GROUP",
|
64
|
+
:long => "--group GROUP",
|
65
|
+
:description => "Group to set privilege to",
|
66
|
+
:proc => nil
|
67
|
+
|
68
|
+
option :daemonize,
|
69
|
+
:short => "-d",
|
70
|
+
:long => "--daemonize",
|
71
|
+
:description => "Daemonize the process",
|
72
|
+
:proc => lambda { |p| true }
|
73
|
+
|
74
|
+
option :interval,
|
75
|
+
:short => "-i SECONDS",
|
76
|
+
:long => "--interval SECONDS",
|
77
|
+
:description => "Run chef-client periodically, in seconds",
|
78
|
+
:proc => lambda { |s| s.to_i }
|
79
|
+
|
80
|
+
option :json_attribs,
|
81
|
+
:short => "-j JSON_ATTRIBS",
|
82
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
83
|
+
:description => "Load attributes from a JSON file or URL",
|
84
|
+
:proc => nil
|
85
|
+
|
86
|
+
option :node_name,
|
87
|
+
:short => "-N NODE_NAME",
|
88
|
+
:long => "--node-name NODE_NAME",
|
89
|
+
:description => "The node name for this client",
|
90
|
+
:proc => nil
|
91
|
+
|
92
|
+
option :splay,
|
93
|
+
:short => "-s SECONDS",
|
94
|
+
:long => "--splay SECONDS",
|
95
|
+
:description => "The splay time for running at intervals, in seconds",
|
96
|
+
:proc => lambda { |s| s.to_i }
|
97
|
+
|
98
|
+
option :json_attribs,
|
99
|
+
:short => "-j JSON_ATTRIBS",
|
100
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
101
|
+
:description => "Load attributes from a JSON file or URL",
|
102
|
+
:proc => nil
|
103
|
+
|
104
|
+
option :recipe_url,
|
105
|
+
:short => "-r RECIPE_URL",
|
106
|
+
:long => "--recipe-url RECIPE_URL",
|
107
|
+
:description => "Pull down a remote gzipped tarball of recipes and untar it to the cookbook cache.",
|
108
|
+
:proc => nil
|
109
|
+
|
110
|
+
option :version,
|
111
|
+
:short => "-v",
|
112
|
+
:long => "--version",
|
113
|
+
:description => "Show chef version",
|
114
|
+
:boolean => true,
|
115
|
+
:proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
|
116
|
+
:exit => 0
|
117
|
+
|
118
|
+
def initialize
|
119
|
+
super
|
120
|
+
@chef_solo = nil
|
121
|
+
@chef_solo_json = nil
|
122
|
+
end
|
123
|
+
|
124
|
+
def reconfigure
|
125
|
+
super
|
126
|
+
|
127
|
+
Chef::Config.solo true
|
128
|
+
|
129
|
+
if Chef::Config[:daemonize]
|
130
|
+
Chef::Config[:interval] ||= 1800
|
131
|
+
end
|
132
|
+
|
133
|
+
if Chef::Config[:json_attribs]
|
134
|
+
begin
|
135
|
+
json_io = open(Chef::Config[:json_attribs])
|
136
|
+
rescue SocketError => error
|
137
|
+
Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
|
138
|
+
rescue Errno::ENOENT => error
|
139
|
+
Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
|
140
|
+
rescue Errno::EACCES => error
|
141
|
+
Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
|
142
|
+
rescue Exception => error
|
143
|
+
Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
|
144
|
+
end
|
145
|
+
|
146
|
+
begin
|
147
|
+
@chef_solo_json = JSON.parse(json_io.read)
|
148
|
+
rescue JSON::ParserError => error
|
149
|
+
Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
if Chef::Config[:recipe_url]
|
154
|
+
cookbooks_path = Chef::Config[:cookbook_path].detect{|e| e =~ /\/cookbooks\/*$/ }
|
155
|
+
recipes_path = File.expand_path(File.join(cookbooks_path, '..'))
|
156
|
+
target_file = File.join(recipes_path, 'recipes.tgz')
|
157
|
+
|
158
|
+
Chef::Log.debug "Creating path #{recipes_path} to extract recipes into"
|
159
|
+
FileUtils.mkdir_p recipes_path
|
160
|
+
path = File.join(recipes_path, 'recipes.tgz')
|
161
|
+
File.open(path, 'wb') do |f|
|
162
|
+
open(Chef::Config[:recipe_url]) do |r|
|
163
|
+
f.write(r.read)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
Chef::Mixin::Command.run_command(:command => "tar zxvfC #{path} #{recipes_path}")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def setup_application
|
171
|
+
Chef::Daemon.change_privilege
|
172
|
+
|
173
|
+
@chef_solo = Chef::Client.new
|
174
|
+
@chef_solo.json_attribs = @chef_solo_json
|
175
|
+
@chef_solo.node_name = Chef::Config[:node_name]
|
176
|
+
end
|
177
|
+
|
178
|
+
def run_application
|
179
|
+
if Chef::Config[:daemonize]
|
180
|
+
Chef::Daemon.daemonize("chef-client")
|
181
|
+
end
|
182
|
+
|
183
|
+
loop do
|
184
|
+
begin
|
185
|
+
if Chef::Config[:splay]
|
186
|
+
splay = rand Chef::Config[:splay]
|
187
|
+
Chef::Log.debug("Splay sleep #{splay} seconds")
|
188
|
+
sleep splay
|
189
|
+
end
|
190
|
+
|
191
|
+
@chef_solo.run_solo
|
192
|
+
|
193
|
+
if Chef::Config[:interval]
|
194
|
+
Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
|
195
|
+
sleep Chef::Config[:interval]
|
196
|
+
else
|
197
|
+
Chef::Application.exit! "Exiting", 0
|
198
|
+
end
|
199
|
+
rescue SystemExit => e
|
200
|
+
raise
|
201
|
+
rescue Exception => e
|
202
|
+
if Chef::Config[:interval]
|
203
|
+
Chef::Log.error("#{e.class}")
|
204
|
+
Chef::Log.fatal("#{e}\n#{e.backtrace.join("\n")}")
|
205
|
+
Chef::Log.fatal("Sleeping for #{Chef::Config[:interval]} seconds before trying again")
|
206
|
+
sleep Chef::Config[:interval]
|
207
|
+
retry
|
208
|
+
else
|
209
|
+
raise
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|