chef-deploy-application 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.8.7@chef-deploy-application
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "chef", "~> 0.10.4"
4
+
5
+ # Specify your gem's dependencies in chef-deploy-application.gemspec
6
+ gemspec
@@ -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.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -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,3 @@
1
+
2
+ require 'chef-deploy-application/version'
3
+ require 'chef-deploy-application/application'
@@ -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
@@ -0,0 +1,4 @@
1
+
2
+ module ChefDeployApplicationGem
3
+ VERSION = "0.0.2"
4
+ 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
+