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.

Files changed (120) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +135 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +26 -0
  5. data/lib/chef.rb +49 -0
  6. data/lib/chef/application.rb +98 -0
  7. data/lib/chef/application/agent.rb +18 -0
  8. data/lib/chef/application/client.rb +209 -0
  9. data/lib/chef/application/indexer.rb +141 -0
  10. data/lib/chef/application/server.rb +18 -0
  11. data/lib/chef/application/solo.rb +214 -0
  12. data/lib/chef/client.rb +396 -0
  13. data/lib/chef/compile.rb +138 -0
  14. data/lib/chef/config.rb +141 -0
  15. data/lib/chef/cookbook.rb +144 -0
  16. data/lib/chef/cookbook/metadata.rb +407 -0
  17. data/lib/chef/cookbook/metadata/version.rb +87 -0
  18. data/lib/chef/cookbook_loader.rb +168 -0
  19. data/lib/chef/couchdb.rb +172 -0
  20. data/lib/chef/daemon.rb +170 -0
  21. data/lib/chef/exceptions.rb +36 -0
  22. data/lib/chef/file_cache.rb +205 -0
  23. data/lib/chef/log.rb +39 -0
  24. data/lib/chef/mixin/check_helper.rb +31 -0
  25. data/lib/chef/mixin/checksum.rb +37 -0
  26. data/lib/chef/mixin/command.rb +351 -0
  27. data/lib/chef/mixin/create_path.rb +56 -0
  28. data/lib/chef/mixin/deep_merge.rb +36 -0
  29. data/lib/chef/mixin/find_preferred_file.rb +99 -0
  30. data/lib/chef/mixin/from_file.rb +36 -0
  31. data/lib/chef/mixin/generate_url.rb +48 -0
  32. data/lib/chef/mixin/language.rb +79 -0
  33. data/lib/chef/mixin/params_validate.rb +197 -0
  34. data/lib/chef/mixin/template.rb +84 -0
  35. data/lib/chef/node.rb +406 -0
  36. data/lib/chef/node/attribute.rb +412 -0
  37. data/lib/chef/openid_registration.rb +181 -0
  38. data/lib/chef/platform.rb +253 -0
  39. data/lib/chef/provider.rb +40 -0
  40. data/lib/chef/provider/cron.rb +137 -0
  41. data/lib/chef/provider/directory.rb +72 -0
  42. data/lib/chef/provider/execute.rb +58 -0
  43. data/lib/chef/provider/file.rb +191 -0
  44. data/lib/chef/provider/group.rb +120 -0
  45. data/lib/chef/provider/group/groupadd.rb +92 -0
  46. data/lib/chef/provider/group/pw.rb +88 -0
  47. data/lib/chef/provider/http_request.rb +102 -0
  48. data/lib/chef/provider/ifconfig.rb +131 -0
  49. data/lib/chef/provider/link.rb +157 -0
  50. data/lib/chef/provider/mount.rb +121 -0
  51. data/lib/chef/provider/mount/mount.rb +208 -0
  52. data/lib/chef/provider/package.rb +160 -0
  53. data/lib/chef/provider/package/apt.rb +110 -0
  54. data/lib/chef/provider/package/dpkg.rb +113 -0
  55. data/lib/chef/provider/package/freebsd.rb +153 -0
  56. data/lib/chef/provider/package/macports.rb +105 -0
  57. data/lib/chef/provider/package/portage.rb +124 -0
  58. data/lib/chef/provider/package/rpm.rb +99 -0
  59. data/lib/chef/provider/package/rubygems.rb +130 -0
  60. data/lib/chef/provider/package/yum-dump.py +104 -0
  61. data/lib/chef/provider/package/yum.rb +175 -0
  62. data/lib/chef/provider/remote_directory.rb +126 -0
  63. data/lib/chef/provider/remote_file.rb +134 -0
  64. data/lib/chef/provider/route.rb +118 -0
  65. data/lib/chef/provider/ruby_block.rb +15 -0
  66. data/lib/chef/provider/script.rb +42 -0
  67. data/lib/chef/provider/service.rb +129 -0
  68. data/lib/chef/provider/service/debian.rb +64 -0
  69. data/lib/chef/provider/service/freebsd.rb +157 -0
  70. data/lib/chef/provider/service/gentoo.rb +54 -0
  71. data/lib/chef/provider/service/init.rb +126 -0
  72. data/lib/chef/provider/service/redhat.rb +62 -0
  73. data/lib/chef/provider/template.rb +141 -0
  74. data/lib/chef/provider/user.rb +170 -0
  75. data/lib/chef/provider/user/pw.rb +113 -0
  76. data/lib/chef/provider/user/useradd.rb +107 -0
  77. data/lib/chef/queue.rb +145 -0
  78. data/lib/chef/recipe.rb +210 -0
  79. data/lib/chef/resource.rb +256 -0
  80. data/lib/chef/resource/apt_package.rb +34 -0
  81. data/lib/chef/resource/bash.rb +33 -0
  82. data/lib/chef/resource/cron.rb +143 -0
  83. data/lib/chef/resource/csh.rb +33 -0
  84. data/lib/chef/resource/directory.rb +76 -0
  85. data/lib/chef/resource/dpkg_package.rb +34 -0
  86. data/lib/chef/resource/execute.rb +127 -0
  87. data/lib/chef/resource/file.rb +84 -0
  88. data/lib/chef/resource/gem_package.rb +41 -0
  89. data/lib/chef/resource/group.rb +68 -0
  90. data/lib/chef/resource/http_request.rb +52 -0
  91. data/lib/chef/resource/ifconfig.rb +134 -0
  92. data/lib/chef/resource/link.rb +78 -0
  93. data/lib/chef/resource/macports_package.rb +29 -0
  94. data/lib/chef/resource/mount.rb +135 -0
  95. data/lib/chef/resource/package.rb +80 -0
  96. data/lib/chef/resource/perl.rb +33 -0
  97. data/lib/chef/resource/portage_package.rb +33 -0
  98. data/lib/chef/resource/python.rb +33 -0
  99. data/lib/chef/resource/remote_directory.rb +91 -0
  100. data/lib/chef/resource/remote_file.rb +60 -0
  101. data/lib/chef/resource/route.rb +135 -0
  102. data/lib/chef/resource/ruby.rb +33 -0
  103. data/lib/chef/resource/ruby_block.rb +20 -0
  104. data/lib/chef/resource/script.rb +51 -0
  105. data/lib/chef/resource/service.rb +134 -0
  106. data/lib/chef/resource/template.rb +60 -0
  107. data/lib/chef/resource/user.rb +98 -0
  108. data/lib/chef/resource_collection.rb +176 -0
  109. data/lib/chef/resource_definition.rb +67 -0
  110. data/lib/chef/rest.rb +238 -0
  111. data/lib/chef/role.rb +231 -0
  112. data/lib/chef/run_list.rb +156 -0
  113. data/lib/chef/runner.rb +123 -0
  114. data/lib/chef/search.rb +88 -0
  115. data/lib/chef/search/result.rb +64 -0
  116. data/lib/chef/search_index.rb +77 -0
  117. data/lib/chef/tasks/chef_repo.rake +345 -0
  118. data/lib/chef/util/file_edit.rb +125 -0
  119. data/lib/chef/util/fileedit.rb +121 -0
  120. 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