poise-application 5.0.0

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/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'poise_boiler/rakefile'
data/SUPPORTERS.md ADDED
@@ -0,0 +1,81 @@
1
+ # Supporters
2
+
3
+ This cookbook wouldn't have been possible without the generous support of my
4
+ Kickstarter backers. Thanks so much to every one of you!
5
+
6
+ * @kcunning
7
+ * Alberto Lorenzo Pulido
8
+ * Alex Gaynor
9
+ * Alexander Myasnikov
10
+ * Brooke Schreier Ganz
11
+ * Bryan McLellan
12
+ * Charles Johnson
13
+ * Chef Software, Inc.
14
+ * Chris Adams
15
+ * Christopher Petrilli
16
+ * David Thornton
17
+ * Derek Murawsky
18
+ * Fast Robot, LLC
19
+ * Fatty McAwesome Pants (Kate Heddleston)
20
+ * Greg Albrecht
21
+ * JD Harrington
22
+ * Jake Plimack
23
+ * Jason Cook
24
+ * Jeff Byrnes
25
+ * Jeff Forcier
26
+ * Jeff Lindsay
27
+ * Jennifer Davis
28
+ * John Fitch
29
+ * Jon Stacks
30
+ * Joshua SS Miller
31
+ * Julian Dunn
32
+ * Julien Phalip
33
+ * Kennon Kwok
34
+ * Kevin Duane
35
+ * Krzysztof Wilczynski
36
+ * Linda Goldstein
37
+ * Manny Toledo
38
+ * Marco A Morales
39
+ * Marcus Morris
40
+ * Mark Luntzel
41
+ * Martin B. Smith
42
+ * Mathieu Sauve-Frankel
43
+ * Matt Good
44
+ * Matt Juszczak
45
+ * Matt Ray
46
+ * Matt Stratton
47
+ * Michael Burns
48
+ * Miguel Landaeta
49
+ * Mike Schueler
50
+ * Nathan L Smith
51
+ * Nathen Harvey
52
+ * Paul Welch
53
+ * Peter Kropf
54
+ * Phil Mocek
55
+ * Practice Fusion Inc
56
+ * Ranjib
57
+ * Richard Jones
58
+ * Robert J. Berger
59
+ * Robin Levin
60
+ * Roland Moriz
61
+ * Ruben Orduz
62
+ * Russell Keith-Magee
63
+ * Ryan Hass
64
+ * Sam Clements
65
+ * Sean OMeara
66
+ * Seva Feldman
67
+ * Soo Choi
68
+ * Steven Danna
69
+ * Symonds & Son
70
+ * Todd Michael Bushnell
71
+ * Tracy Osborn
72
+ * Troy Ready
73
+ * Tyler Ball
74
+ * Vicky Tuite
75
+ * Ying Li
76
+ * Yvo van Doorn
77
+ * Zac Stevens
78
+ * lvh
79
+ * oolongtea
80
+ * smeuser
81
+ * tmonk42
@@ -0,0 +1,25 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module PoiseApplication
19
+ autoload :AppMixin, 'poise_application/app_mixin'
20
+ autoload :Error, 'poise_application/error'
21
+ autoload :Resources, 'poise_application/resources'
22
+ autoload :ServiceMixin, 'poise_application/service_mixin'
23
+ autoload :Utils, 'poise_application/utils'
24
+ autoload :VERSION, 'poise_application/version'
25
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'chef/mash'
18
+ require 'poise/provider'
19
+ require 'poise/resource'
20
+ require 'poise/utils'
21
+
22
+
23
+ module PoiseApplication
24
+ # A helper mixin for application resources and providers. These are things
25
+ # intended to be used as subresources of the `application` resource.
26
+ #
27
+ # @since 5.0.0
28
+ module AppMixin
29
+ include Poise::Utils::ResourceProviderMixin
30
+
31
+ # A helper mixin for application resources.
32
+ module Resource
33
+ include Poise::Resource
34
+
35
+ # Set the parent type and optional flag.
36
+ poise_subresource(:application, true)
37
+
38
+ # @!attribute path
39
+ # Base path for the application.
40
+ # @return [String]
41
+ attribute(:path, kind_of: String, name_attribute: true)
42
+
43
+ # A delegator for accessing the application state. If no application
44
+ # parent is found, the state will be tracked internally within the
45
+ # resource.
46
+ #
47
+ # @return [Hash<Symbol, Object>]
48
+ def app_state
49
+ if parent
50
+ parent.app_state
51
+ else
52
+ # If there isn't a parent, just track within the resource.
53
+ @local_app_state ||= Mash.new
54
+ end
55
+ end
56
+
57
+ # Environment variables stored in the application state.
58
+ #
59
+ # @return [Hash<String, String>]
60
+ def app_state_environment
61
+ app_state[:environment] ||= Mash.new
62
+ end
63
+ end
64
+
65
+ module Provider
66
+ include Poise::Provider
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,17 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'poise_application/resources/application'
@@ -0,0 +1,24 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module PoiseApplication
19
+ # Base exception class for poise-application errors.
20
+ #
21
+ # @since 5.0.0
22
+ class Error < Exception
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module PoiseApplication
19
+ module Resources
20
+ autoload :Application, 'poise_application/resources/application'
21
+ end
22
+ end
@@ -0,0 +1,259 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'chef/dsl/recipe' # On 12.4+ this will pull in chef/dsl/resources.
18
+ require 'chef/resource'
19
+ require 'chef/provider'
20
+ require 'poise'
21
+
22
+
23
+ module PoiseApplication
24
+ module Resources
25
+ # (see Application::Resource)
26
+ # @since 5.0.0
27
+ module Application
28
+ # An `application` resource to manage application deployment.
29
+ #
30
+ # @since 5.0.0
31
+ # @provides application
32
+ # @action deploy
33
+ # @action start
34
+ # @action stop
35
+ # @action restart
36
+ # @action reload
37
+ # @example
38
+ # application '/srv/myapp' do
39
+ # git '...'
40
+ # poise_service 'myapp' do
41
+ # command '/srv/myapp/main'
42
+ # end
43
+ # end
44
+ class Resource < Chef::Resource
45
+ include Poise(container: true, container_namespace: false)
46
+ provides(:application)
47
+ actions(:deploy, :start, :stop, :restart, :reload)
48
+
49
+ # @!attribute path
50
+ # Application base path.
51
+ # @return [String]
52
+ attribute(:path, kind_of: String, name_attribute: true)
53
+ # @!attribute environment
54
+ # Environment variables to set for the whole application.
55
+ # @return [Hash<String, String>]
56
+ attribute(:environment, kind_of: Hash, default: lazy { Mash.new })
57
+ # @!attribute owner
58
+ # System user that will own the application. This can be overriden in
59
+ # individual subresources.
60
+ # @return [String]
61
+ attribute(:owner, kind_of: String)
62
+ # @!attribute group
63
+ # System group that will own the application. This can be overriden in
64
+ # individual subresources.
65
+ # @return [String]
66
+ attribute(:group, kind_of: String)
67
+ # @!attribute action_on_update
68
+ # Action to run when any subresource is updated. Defaults to `:restart`.
69
+ # @return [String, Symbol, nil, false]
70
+ attribute(:action_on_update, kind_of: [Symbol, String, NilClass, FalseClass], default: :restart)
71
+ # @!attribute action_on_update_immediately
72
+ # Run the {#action_on_update} notification with `:immediately`.
73
+ # @return [Boolean]
74
+ attribute(:action_on_update_immediately, equal_to: [true, false], default: false)
75
+
76
+ # Run the DSL rewire when the resource object is created.
77
+ # @api private
78
+ def initialize(*args)
79
+ super
80
+ _rewire_dsl! if node
81
+ end
82
+
83
+ # Application-specific state values used as a way to communicate between
84
+ # subresources.
85
+ #
86
+ # @return [Mash]
87
+ # @example
88
+ # if new_resource.parent && new_resource.parent.app_state['gemfile_path']
89
+ def app_state
90
+ @app_state ||= Mash.new(environment: environment)
91
+ end
92
+
93
+ # Override Container#register_subresource to add our action_on_update.
94
+ #
95
+ # @api private
96
+ def register_subresource(resource)
97
+ super.tap do |added|
98
+ if added && action_on_update
99
+ Chef::Log.debug("[#{self}] Registering #{action_on_update_immediately ? 'immediate ' : ''}#{action_on_update} notification from #{resource}")
100
+ resource.notifies action_on_update.to_sym, self, (action_on_update_immediately ? :immediately : :delayed)
101
+ end
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ # Find all resources that need to be rewired. This is anything with a
108
+ # name starting with application_.
109
+ #
110
+ # @return [Array<String>]
111
+ def _rewire_resources
112
+ if defined?(Chef::DSL::Resources)
113
+ # Chef >= 12.4.
114
+ Chef::DSL::Resources.instance_methods
115
+ else
116
+ # Chef < 12.4 >= 12.0.
117
+ Chef::Resource.descendants.map do |klass|
118
+ klass.node_map.instance_variable_get(:@map).keys + if klass.dsl_name.include?('::')
119
+ # Probably not valid.
120
+ # :nocov:
121
+ []
122
+ # :nocov:
123
+ else
124
+ # Needed for things that don't call provides().
125
+ [klass.dsl_name]
126
+ end
127
+ end.flatten
128
+ end.map {|name| name.to_s }.select {|name| name.start_with?('application_') }.uniq
129
+ end
130
+
131
+ # Find all cookbooks that might contain LWRPs matching our name scheme.
132
+ #
133
+ # @return [Array<String>]
134
+ def _rewire_cookbooks
135
+ # Run context might be unset during test setup.
136
+ if run_context
137
+ run_context.cookbook_collection.keys.select {|cookbook_name| cookbook_name.start_with?('application_') }
138
+ else
139
+ []
140
+ end
141
+ end
142
+
143
+ # Build the mapping of new_name => old_name for each resource to rewire.
144
+ #
145
+ # @return [Hash<String, String>]
146
+ def _rewire_map
147
+ application_cookbooks = _rewire_cookbooks
148
+ _rewire_resources.inject({}) do |memo, name|
149
+ # Grab the resource class to check if it is an LWRP.
150
+ klass = Chef::Resource.resource_for_node(name.to_sym, node)
151
+ # Find the part to trim. Check for LWRP first, then just application_.
152
+ trim = if klass < Chef::Resource::LWRPBase
153
+ application_cookbooks.find {|cookbook_name| name.start_with?(cookbook_name) && name != cookbook_name } || 'application'
154
+ else
155
+ # Non-LWRPs are assumed to have a better name.
156
+ 'application'
157
+ end
158
+ # Map trimmed to untrimmed.
159
+ memo[name[trim.length+1..-1]] = name
160
+ memo
161
+ end
162
+ end
163
+
164
+ # Build new DSL methods to implement the foo -> application_foo behavior.
165
+ #
166
+ # @return [void]
167
+ def _rewire_dsl!
168
+ # Generate stub methods for all the rewiring.
169
+ _rewire_map.each do |new_name, old_name|
170
+ # This is defined as a singleton method on self so it looks like
171
+ # the DSL but is scoped to just this context.
172
+ define_singleton_method(new_name) do |name=nil, *args, &block|
173
+ # Store the caller to correct the source_line.
174
+ created_at = caller[0]
175
+ public_send(old_name, name, *args) do
176
+ # Set the declared type to be the native name.
177
+ self.declared_type = self.class.resource_name
178
+ # Fix the source location. For Chef 12.4 we could do this with the
179
+ # declared_at parameter on the initial send.
180
+ self.source_line = created_at
181
+ # Run the original block.
182
+ instance_exec(&block) if block
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ # Provider for `application`.
190
+ #
191
+ # @since 5.0.0
192
+ # @see Resource
193
+ # @provides application
194
+ class Provider < Chef::Provider
195
+ include Poise
196
+ provides(:application)
197
+
198
+ # `deploy` action for `application`. Creates the application base folder.
199
+ #
200
+ # @return [void]
201
+ def action_deploy
202
+ notifying_block do
203
+ directory new_resource.path do
204
+ owner new_resource.owner
205
+ group new_resource.group
206
+ mode '755'
207
+ end
208
+ end
209
+ end
210
+
211
+ # `start` action for `application`. Proxies to subresources.
212
+ #
213
+ # @return [void]
214
+ def action_start
215
+ proxy_action(:start)
216
+ end
217
+
218
+ # `stop` action for `application`. Proxies to subresources.
219
+ #
220
+ # @return [void]
221
+ def action_stop
222
+ proxy_action(:stop)
223
+ end
224
+
225
+ # `restart` action for `application`. Proxies to subresources.
226
+ #
227
+ # @return [void]
228
+ def action_restart
229
+ proxy_action(:restart)
230
+ end
231
+
232
+ # `reload` action for `application`. Proxies to subresources.
233
+ #
234
+ # @return [void]
235
+ def action_reload
236
+ proxy_action(:reload)
237
+ end
238
+
239
+ private
240
+
241
+ # Proxy an action to any subresources that support it.
242
+ #
243
+ # @param action [Symbol] Action to proxy.
244
+ # @return [void]
245
+ def proxy_action(action)
246
+ Chef::Log.debug("[#{new_resource} Running proxied #{action} action")
247
+ new_resource.subresources.each do |r|
248
+ begin
249
+ r.run_action(action) if r.allowed_actions.include?(action)
250
+ rescue Chef::Exceptions::UnsupportedAction
251
+ # Don't care, just move on.
252
+ end
253
+ end
254
+ end
255
+
256
+ end
257
+ end
258
+ end
259
+ end