chef-deploy-application 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +6 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/bin/chef-deploy-application +25 -0
- data/chef-deploy-application.gemspec +23 -0
- data/lib/chef-deploy-application.rb +3 -0
- data/lib/chef-deploy-application/application.rb +251 -0
- data/lib/chef-deploy-application/version.rb +4 -0
- metadata +90 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use 1.8.7@chef-deploy-application
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
Application cookbook
|
2
|
+
====================
|
3
|
+
|
4
|
+
See the opscode community cookbook site.
|
5
|
+
|
6
|
+
Requirements
|
7
|
+
============
|
8
|
+
|
9
|
+
* Chef 0.10.4 or higher required
|
10
|
+
* Working chef server
|
11
|
+
* Application cookbook and an apps data bag
|
12
|
+
|
13
|
+
Usage
|
14
|
+
=====
|
15
|
+
|
16
|
+
shell> chef-deploy-application APPNAME
|
17
|
+
|
18
|
+
|
19
|
+
License and Author
|
20
|
+
==================
|
21
|
+
|
22
|
+
Author:: Daniel Porter (wolfpakz@gmail.com)
|
23
|
+
|
24
|
+
Author:: AJ Christensen (<aj@opscode.com)
|
25
|
+
Author:: Christopher Brown (<cb@opscode.com>)
|
26
|
+
|
27
|
+
Copyright 2009-2011, Opscode, Inc.
|
28
|
+
|
29
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
30
|
+
you may not use this file except in compliance with the License.
|
31
|
+
You may obtain a copy of the License at
|
32
|
+
|
33
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
34
|
+
|
35
|
+
Unless required by applicable law or agreed to in writing, software
|
36
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
37
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
38
|
+
See the License for the specific language governing permissions and
|
39
|
+
limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# ./chef-deploy-application - Deploy the application
|
4
|
+
#
|
5
|
+
# Author:: AJ Christensen (<aj@opscode.com>)
|
6
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
7
|
+
# License:: Apache License, Version 2.0
|
8
|
+
#
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
10
|
+
# you may not use this file except in compliance with the License.
|
11
|
+
# You may obtain a copy of the License at
|
12
|
+
#
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
14
|
+
#
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
18
|
+
# See the License for the specific language governing permissions and
|
19
|
+
# limitations under the License.
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
|
23
|
+
require 'chef-deploy-application'
|
24
|
+
|
25
|
+
Chef::Application::DeployApplication.new.run
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "chef-deploy-application/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "chef-deploy-application"
|
7
|
+
s.version = ::ChefDeployApplicationGem::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Daniel Porter"]
|
10
|
+
s.email = ["wolfpakz@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Deploy a single application using the application community cookbook.}
|
13
|
+
s.description = %q{Executes a chef-client run with only the application's role and the application cookbook in the run list. For example, for the application "foo" the run list would be: role:foo application}
|
14
|
+
|
15
|
+
s.rubyforge_project = "chef-deploy-application"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('chef', '~> 0.10.4')
|
23
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
|
2
|
+
require 'chef'
|
3
|
+
require 'chef/application'
|
4
|
+
require 'chef/client'
|
5
|
+
require 'chef/config'
|
6
|
+
require 'chef/daemon'
|
7
|
+
require 'chef/log'
|
8
|
+
require 'chef/rest'
|
9
|
+
require 'chef/handler/error_report'
|
10
|
+
|
11
|
+
require "chef-deploy-application/version"
|
12
|
+
|
13
|
+
class Chef::Application::DeployApplication < Chef::Application
|
14
|
+
|
15
|
+
# Mimic self_pipe sleep from Unicorn to capture signals safely
|
16
|
+
SELF_PIPE = []
|
17
|
+
|
18
|
+
option :config_file,
|
19
|
+
:short => "-c CONFIG",
|
20
|
+
:long => "--config CONFIG",
|
21
|
+
:default => "/etc/chef/client.rb",
|
22
|
+
:description => "The configuration file to use"
|
23
|
+
|
24
|
+
option :log_level,
|
25
|
+
:short => "-l LEVEL",
|
26
|
+
:long => "--log_level LEVEL",
|
27
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
28
|
+
:proc => lambda { |l| l.to_sym }
|
29
|
+
|
30
|
+
option :log_location,
|
31
|
+
:short => "-L LOGLOCATION",
|
32
|
+
:long => "--logfile LOGLOCATION",
|
33
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
34
|
+
:proc => nil
|
35
|
+
|
36
|
+
option :help,
|
37
|
+
:short => "-h",
|
38
|
+
:long => "--help",
|
39
|
+
:description => "Show this message",
|
40
|
+
:on => :tail,
|
41
|
+
:boolean => true,
|
42
|
+
:show_options => true,
|
43
|
+
:exit => 0
|
44
|
+
|
45
|
+
option :user,
|
46
|
+
:short => "-u USER",
|
47
|
+
:long => "--user USER",
|
48
|
+
:description => "User to set privilege to",
|
49
|
+
:proc => nil
|
50
|
+
|
51
|
+
option :group,
|
52
|
+
:short => "-g GROUP",
|
53
|
+
:long => "--group GROUP",
|
54
|
+
:description => "Group to set privilege to",
|
55
|
+
:proc => nil
|
56
|
+
|
57
|
+
option :json_attribs,
|
58
|
+
:short => "-j JSON_ATTRIBS",
|
59
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
60
|
+
:description => "Load attributes from a JSON file or URL",
|
61
|
+
:proc => nil
|
62
|
+
|
63
|
+
option :node_name,
|
64
|
+
:short => "-N NODE_NAME",
|
65
|
+
:long => "--node-name NODE_NAME",
|
66
|
+
:description => "The node name for this client",
|
67
|
+
:proc => nil
|
68
|
+
|
69
|
+
option :chef_server_url,
|
70
|
+
:short => "-S CHEFSERVERURL",
|
71
|
+
:long => "--server CHEFSERVERURL",
|
72
|
+
:description => "The chef server URL",
|
73
|
+
:proc => nil
|
74
|
+
|
75
|
+
option :validation_key,
|
76
|
+
:short => "-K KEY_FILE",
|
77
|
+
:long => "--validation_key KEY_FILE",
|
78
|
+
:description => "Set the validation key file location, used for registering new clients",
|
79
|
+
:proc => nil
|
80
|
+
|
81
|
+
option :client_key,
|
82
|
+
:short => "-k KEY_FILE",
|
83
|
+
:long => "--client_key KEY_FILE",
|
84
|
+
:description => "Set the client key file location",
|
85
|
+
:proc => nil
|
86
|
+
|
87
|
+
option :environment,
|
88
|
+
:short => '-E ENVIRONMENT',
|
89
|
+
:long => '--environment ENVIRONMENT',
|
90
|
+
:description => 'Set the Chef Environment on the node'
|
91
|
+
|
92
|
+
option :version,
|
93
|
+
:short => "-v",
|
94
|
+
:long => "--version",
|
95
|
+
:description => "Show chef version",
|
96
|
+
:boolean => true,
|
97
|
+
:proc => lambda {|v| puts "Chef Deploy Application: #{::ChefDeployApplicationGem::VERSION}"},
|
98
|
+
:exit => 0
|
99
|
+
|
100
|
+
attr_reader :chef_client_json
|
101
|
+
|
102
|
+
def initialize
|
103
|
+
super
|
104
|
+
|
105
|
+
@chef_client = nil
|
106
|
+
@chef_client_json = nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# Reconfigure the chef client
|
110
|
+
# Re-open the JSON attributes and load them into the node
|
111
|
+
def reconfigure
|
112
|
+
super
|
113
|
+
|
114
|
+
Chef::Config[:chef_server_url] = config[:chef_server_url] if config.has_key? :chef_server_url
|
115
|
+
unless Chef::Config[:exception_handlers].any? {|h| Chef::Handler::ErrorReport === h}
|
116
|
+
Chef::Config[:exception_handlers] << Chef::Handler::ErrorReport.new
|
117
|
+
end
|
118
|
+
|
119
|
+
# Run chef once and exit
|
120
|
+
Chef::Config[:interval] = nil
|
121
|
+
Chef::Config[:splay] = nil
|
122
|
+
|
123
|
+
if Chef::Config[:json_attribs]
|
124
|
+
begin
|
125
|
+
json_io = case Chef::Config[:json_attribs]
|
126
|
+
when /^(http|https):\/\//
|
127
|
+
@rest = Chef::REST.new(Chef::Config[:json_attribs], nil, nil)
|
128
|
+
@rest.get_rest(Chef::Config[:json_attribs], true).open
|
129
|
+
else
|
130
|
+
open(Chef::Config[:json_attribs])
|
131
|
+
end
|
132
|
+
rescue SocketError => error
|
133
|
+
Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
|
134
|
+
rescue Errno::ENOENT => error
|
135
|
+
Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
|
136
|
+
rescue Errno::EACCES => error
|
137
|
+
Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
|
138
|
+
rescue Exception => error
|
139
|
+
Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
|
140
|
+
end
|
141
|
+
|
142
|
+
begin
|
143
|
+
@chef_client_json = Chef::JSONCompat.from_json(json_io.read)
|
144
|
+
json_io.close unless json_io.closed?
|
145
|
+
rescue JSON::ParserError => error
|
146
|
+
Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def configure_logging
|
152
|
+
super
|
153
|
+
Mixlib::Authentication::Log.use_log_devices( Chef::Log )
|
154
|
+
Ohai::Log.use_log_devices( Chef::Log )
|
155
|
+
end
|
156
|
+
|
157
|
+
def setup_application
|
158
|
+
Chef::Daemon.change_privilege
|
159
|
+
end
|
160
|
+
|
161
|
+
# Run the chef client, optionally daemonizing or looping at intervals.
|
162
|
+
def run_application
|
163
|
+
if no_app_name_given?
|
164
|
+
puts "You must provide the name of an application to deploy."
|
165
|
+
exit 1
|
166
|
+
end
|
167
|
+
|
168
|
+
begin
|
169
|
+
Chef::Log.info("*** Chef #{Chef::VERSION} ***")
|
170
|
+
|
171
|
+
# Make sure the client knows this is not chef solo
|
172
|
+
Chef::Config[:solo] = false
|
173
|
+
|
174
|
+
# Rebuild node
|
175
|
+
client = Chef::Client.new
|
176
|
+
client.run_ohai
|
177
|
+
client.register
|
178
|
+
client.build_node
|
179
|
+
|
180
|
+
|
181
|
+
# Shorten node inspection
|
182
|
+
node = client.node
|
183
|
+
def node.inspect
|
184
|
+
"<Chef::Node:0x#{self.object_id.to_s(16)} @name=\"#{self.name}\">"
|
185
|
+
end
|
186
|
+
|
187
|
+
# Rebuild context
|
188
|
+
run_status = Chef::RunStatus.new(node)
|
189
|
+
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, Chef::REST.new(Chef::Config[:server_url])) }
|
190
|
+
cookbook_hash = client.sync_cookbooks
|
191
|
+
cookbooks = Chef::CookbookCollection.new(cookbook_hash)
|
192
|
+
|
193
|
+
run_context = Chef::RunContext.new(node, cookbooks)
|
194
|
+
run_context.load(Chef::RunList::RunListExpansionFromAPI.new(node.chef_environment, []))
|
195
|
+
run_status.run_context = run_context
|
196
|
+
|
197
|
+
# Merge json
|
198
|
+
node.consume_attributes(@chef_client_json) if @chef_client_json
|
199
|
+
|
200
|
+
# Setup the recipe
|
201
|
+
app_name = application_name
|
202
|
+
recipe = Chef::Recipe.new(nil, nil, run_context)
|
203
|
+
recipe.instance_eval do
|
204
|
+
# Run the applications cookbook
|
205
|
+
node.run_state[:seen_recipes].delete(app_name)
|
206
|
+
include_recipe app_name
|
207
|
+
|
208
|
+
app = search(:apps, "id:#{app_name}").first
|
209
|
+
raise "Cannot find an application named #{app_name}" unless app
|
210
|
+
|
211
|
+
server_roles = (app["server_roles"] & node.run_list.roles)
|
212
|
+
if server_roles.empty?
|
213
|
+
Chef::Log.info("None of this server's roles match the app's server_roles.")
|
214
|
+
else
|
215
|
+
server_roles.each do |app_role|
|
216
|
+
app["type"][app_role].each do |thing|
|
217
|
+
recipe_name = "application::#{thing}"
|
218
|
+
node.run_state[:current_app] = app
|
219
|
+
node.run_state[:seen_recipes].delete(recipe_name)
|
220
|
+
include_recipe recipe_name
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
node.run_state.delete(:current_app)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Run the recipe
|
229
|
+
Chef::Runner.new(run_context).converge
|
230
|
+
|
231
|
+
Chef::Application.exit! "Exiting", 0
|
232
|
+
rescue SystemExit => e
|
233
|
+
raise
|
234
|
+
rescue Exception => e
|
235
|
+
Chef::Application.debug_stacktrace(e)
|
236
|
+
Chef::Application.fatal!("#{e.class}: #{e.message}", 1)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def application_name
|
243
|
+
return nil if no_app_name_given?
|
244
|
+
ARGV[0]
|
245
|
+
end
|
246
|
+
|
247
|
+
def no_app_name_given?
|
248
|
+
ARGV.empty?
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chef-deploy-application
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Daniel Porter
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-14 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: chef
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 63
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 10
|
32
|
+
- 4
|
33
|
+
version: 0.10.4
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: "Executes a chef-client run with only the application's role and the application cookbook in the run list. For example, for the application \"foo\" the run list would be: role:foo application"
|
37
|
+
email:
|
38
|
+
- wolfpakz@gmail.com
|
39
|
+
executables:
|
40
|
+
- chef-deploy-application
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- .rvmrc
|
48
|
+
- Gemfile
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- bin/chef-deploy-application
|
52
|
+
- chef-deploy-application.gemspec
|
53
|
+
- lib/chef-deploy-application.rb
|
54
|
+
- lib/chef-deploy-application/application.rb
|
55
|
+
- lib/chef-deploy-application/version.rb
|
56
|
+
homepage: ""
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: chef-deploy-application
|
85
|
+
rubygems_version: 1.8.10
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Deploy a single application using the application community cookbook.
|
89
|
+
test_files: []
|
90
|
+
|