itamae 1.0.0.beta26 → 1.0.0.beta27
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.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/lib/itamae.rb +2 -1
- data/lib/itamae/notification.rb +23 -0
- data/lib/itamae/recipe.rb +27 -20
- data/lib/itamae/recipe_children.rb +61 -0
- data/lib/itamae/resource/base.rb +18 -31
- data/lib/itamae/runner.rb +14 -5
- data/lib/itamae/version.txt +1 -1
- data/spec/integration/default_spec.rb +4 -0
- data/spec/integration/recipes/default.rb +6 -0
- data/spec/integration/recipes/default2.rb +6 -0
- data/spec/unit/lib/itamae/runner_spec.rb +1 -0
- metadata +6 -3
- data/lib/itamae/recipe_dependencies.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f71dbe4da1c49cacda9dac2d10c5c1cb0263e6b4
|
4
|
+
data.tar.gz: 09480bb0d8624135546598f390cabd30428b8ce0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4238df2db65e2f9a66d5a0021d724e0e1d1f2234f97b62b4e3fab49f8560e92150124221b2a755f450cf782a919e3ad121ae3a8179021eaeba59eaed9fb08d18
|
7
|
+
data.tar.gz: ada64866b96afadc1f916e3a4b106e9e4f59acc8c01e5797e6c86f26988a5b6af207d97de8d09e5ee25816c8e31ad4ad6b49f4abcafe4bbb54395e3c5110ca0f
|
data/Rakefile
CHANGED
data/lib/itamae.rb
CHANGED
@@ -3,10 +3,11 @@ require "itamae/runner"
|
|
3
3
|
require "itamae/cli"
|
4
4
|
require "itamae/recipe"
|
5
5
|
require "itamae/resource"
|
6
|
-
require "itamae/
|
6
|
+
require "itamae/recipe_children"
|
7
7
|
require "itamae/logger"
|
8
8
|
require "itamae/node"
|
9
9
|
require "itamae/backend"
|
10
|
+
require "itamae/notification"
|
10
11
|
|
11
12
|
module Itamae
|
12
13
|
# Your code goes here...
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'itamae'
|
2
|
+
|
3
|
+
module Itamae
|
4
|
+
class Notification < Struct.new(:runner, :defined_in_resource, :action, :target_resource_desc, :timing)
|
5
|
+
def resource
|
6
|
+
runner.children.find_resource_by_description(target_resource_desc)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(options)
|
10
|
+
action_resource.run(action, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def action_resource
|
14
|
+
resource
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Subscription < Notification
|
19
|
+
def action_resource
|
20
|
+
defined_in_resource
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/itamae/recipe.rb
CHANGED
@@ -2,18 +2,20 @@ require 'itamae'
|
|
2
2
|
|
3
3
|
module Itamae
|
4
4
|
class Recipe
|
5
|
+
NotFoundError = Class.new(StandardError)
|
6
|
+
|
5
7
|
attr_reader :path
|
6
8
|
attr_reader :runner
|
7
|
-
attr_reader :
|
8
|
-
attr_reader :
|
9
|
+
attr_reader :children
|
10
|
+
attr_reader :delayed_notifications
|
9
11
|
|
10
12
|
def initialize(runner, path)
|
11
13
|
@runner = runner
|
12
14
|
@path = path
|
13
|
-
@
|
14
|
-
@
|
15
|
+
@children = RecipeChildren.new
|
16
|
+
@delayed_notifications = []
|
15
17
|
|
16
|
-
|
18
|
+
load_children
|
17
19
|
end
|
18
20
|
|
19
21
|
def node
|
@@ -21,19 +23,14 @@ module Itamae
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def run(options = {})
|
24
|
-
Logger.info "
|
25
|
-
|
26
|
-
@dependencies.each do |resource|
|
27
|
-
case resource
|
28
|
-
when Resource::Base
|
29
|
-
resource.run(nil, dry_run: options[:dry_run])
|
30
|
-
when Recipe
|
31
|
-
resource.run(options)
|
32
|
-
end
|
33
|
-
end
|
26
|
+
Logger.info "Recipe: #{@path}"
|
34
27
|
|
35
|
-
@
|
36
|
-
|
28
|
+
@children.run(options)
|
29
|
+
|
30
|
+
@delayed_notifications.uniq do |notification|
|
31
|
+
[notification.action, notification.action_resource]
|
32
|
+
end.each do |notification|
|
33
|
+
notification.run(options)
|
37
34
|
end
|
38
35
|
|
39
36
|
Logger.info "< Finished. (#{@path})"
|
@@ -41,22 +38,32 @@ module Itamae
|
|
41
38
|
|
42
39
|
private
|
43
40
|
|
44
|
-
def
|
41
|
+
def load_children
|
45
42
|
instance_eval(File.read(@path), @path, 1)
|
46
43
|
end
|
47
44
|
|
48
45
|
def method_missing(method, name, &block)
|
49
46
|
klass = Resource.get_resource_class(method)
|
50
47
|
resource = klass.new(self, name, &block)
|
51
|
-
@
|
48
|
+
@children << resource
|
52
49
|
rescue NameError
|
53
50
|
super
|
54
51
|
end
|
55
52
|
|
56
53
|
def include_recipe(target)
|
57
54
|
target = ::File.expand_path(target, File.dirname(@path))
|
55
|
+
|
56
|
+
unless File.exist?(target)
|
57
|
+
raise NotFoundError, "File not found. (#{target})"
|
58
|
+
end
|
59
|
+
|
60
|
+
if runner.children.find_recipe_by_path(target)
|
61
|
+
Logger.debug "Recipe, #{target}, is skipped because it is already included"
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
58
65
|
recipe = Recipe.new(@runner, target)
|
59
|
-
@
|
66
|
+
@children << recipe
|
60
67
|
end
|
61
68
|
end
|
62
69
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Itamae
|
2
|
+
class RecipeChildren < Array
|
3
|
+
NotFoundError = Class.new(StandardError)
|
4
|
+
|
5
|
+
def find_resource_by_description(desc)
|
6
|
+
# desc is like 'resource_type[name]'
|
7
|
+
resources.find do |resource|
|
8
|
+
type, name = Itamae::Resource.parse_description(desc)
|
9
|
+
resource.resource_type == type && resource.resource_name == name
|
10
|
+
end.tap do |resource|
|
11
|
+
unless resource
|
12
|
+
raise NotFoundError, "'#{desc}' resource is not found."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def subscribing(target)
|
18
|
+
resources.map do |resource|
|
19
|
+
resource.subscriptions.select do |subscription|
|
20
|
+
subscription.resource == target
|
21
|
+
end
|
22
|
+
end.flatten
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_recipe_by_path(path)
|
26
|
+
recipes.find do |recipe|
|
27
|
+
recipe.path == path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def resources
|
32
|
+
self.map do |item|
|
33
|
+
case item
|
34
|
+
when Resource::Base
|
35
|
+
item
|
36
|
+
when Recipe
|
37
|
+
item.children.resources
|
38
|
+
end
|
39
|
+
end.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
def recipes
|
43
|
+
self.select do |item|
|
44
|
+
item.is_a?(Recipe)
|
45
|
+
end.map do |recipe|
|
46
|
+
[recipe] + recipe.children.recipes
|
47
|
+
end.flatten
|
48
|
+
end
|
49
|
+
|
50
|
+
def run(options)
|
51
|
+
self.each do |resource|
|
52
|
+
case resource
|
53
|
+
when Resource::Base
|
54
|
+
resource.run(nil, dry_run: options[:dry_run])
|
55
|
+
when Recipe
|
56
|
+
resource.run(options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/itamae/resource/base.rb
CHANGED
@@ -30,14 +30,16 @@ module Itamae
|
|
30
30
|
attr_reader :resource_name
|
31
31
|
attr_reader :attributes
|
32
32
|
attr_reader :current_attributes
|
33
|
+
attr_reader :subscriptions
|
34
|
+
attr_reader :notifications
|
33
35
|
|
34
36
|
def initialize(recipe, resource_name, &block)
|
35
37
|
@attributes = {}
|
36
38
|
@current_attributes = {}
|
37
39
|
@recipe = recipe
|
38
40
|
@resource_name = resource_name
|
39
|
-
@
|
40
|
-
@
|
41
|
+
@notifications = []
|
42
|
+
@subscriptions = []
|
41
43
|
@updated = false
|
42
44
|
|
43
45
|
instance_eval(&block) if block_given?
|
@@ -46,13 +48,13 @@ module Itamae
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def run(specific_action = nil, options = {})
|
49
|
-
Logger.info "
|
51
|
+
Logger.info "Executing #{resource_type} (#{attributes})..."
|
50
52
|
|
51
53
|
if do_not_run_because_of_only_if?
|
52
|
-
Logger.info "
|
54
|
+
Logger.info "Execution skipped because of only_if attribute"
|
53
55
|
return
|
54
56
|
elsif do_not_run_because_of_not_if?
|
55
|
-
Logger.info "
|
57
|
+
Logger.info "Execution skipped because of not_if attribute"
|
56
58
|
return
|
57
59
|
end
|
58
60
|
|
@@ -69,11 +71,12 @@ module Itamae
|
|
69
71
|
|
70
72
|
updated! if different?
|
71
73
|
|
72
|
-
notify if updated?
|
74
|
+
notify(options) if updated?
|
73
75
|
|
74
|
-
Logger.info "
|
76
|
+
Logger.info "Succeeded."
|
77
|
+
Logger.info ''
|
75
78
|
rescue Backend::CommandExecutionError
|
76
|
-
Logger.error "
|
79
|
+
Logger.error "Failed."
|
77
80
|
exit 2
|
78
81
|
end
|
79
82
|
|
@@ -93,21 +96,6 @@ module Itamae
|
|
93
96
|
humps.join('_')
|
94
97
|
end
|
95
98
|
|
96
|
-
def notifies_resources
|
97
|
-
@notifies.map do |action, resource_desc, timing|
|
98
|
-
resource = recipe.dependencies.find_by_description(resource_desc)
|
99
|
-
[action, resource, timing]
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def subscribes_resources
|
104
|
-
@subscribes.map do |action, resource_desc, timing|
|
105
|
-
resource = recipe.dependencies.find_by_description(resource_desc)
|
106
|
-
[action, resource, timing]
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
99
|
private
|
112
100
|
|
113
101
|
def method_missing(method, *args, &block)
|
@@ -200,11 +188,11 @@ module Itamae
|
|
200
188
|
end
|
201
189
|
|
202
190
|
def notifies(action, resource_desc, timing = :delay)
|
203
|
-
@
|
191
|
+
@notifications << Notification.new(runner, self, action, resource_desc, timing)
|
204
192
|
end
|
205
193
|
|
206
194
|
def subscribes(action, resource_desc, timing = :delay)
|
207
|
-
@
|
195
|
+
@subscriptions << Subscription.new(runner, self, action, resource_desc, timing)
|
208
196
|
end
|
209
197
|
|
210
198
|
def node
|
@@ -248,14 +236,13 @@ module Itamae
|
|
248
236
|
@updated
|
249
237
|
end
|
250
238
|
|
251
|
-
def notify
|
252
|
-
|
253
|
-
|
254
|
-
case timing
|
239
|
+
def notify(options)
|
240
|
+
(notifications + recipe.children.subscribing(self)).each do |notification|
|
241
|
+
case notification.timing
|
255
242
|
when :immediately
|
256
|
-
|
243
|
+
notification.run(options)
|
257
244
|
when :delay
|
258
|
-
@recipe.
|
245
|
+
@recipe.delayed_notifications << notification
|
259
246
|
end
|
260
247
|
end
|
261
248
|
end
|
data/lib/itamae/runner.rb
CHANGED
@@ -10,11 +10,8 @@ module Itamae
|
|
10
10
|
set_backend_from_options(backend_type, options)
|
11
11
|
|
12
12
|
runner = self.new(node_from_options(options))
|
13
|
-
|
14
|
-
|
15
|
-
recipe = Recipe.new(runner, File.expand_path(path))
|
16
|
-
recipe.run(dry_run: options[:dry_run])
|
17
|
-
end
|
13
|
+
runner.load_recipes(recipe_files)
|
14
|
+
runner.run(dry_run: options[:dry_run])
|
18
15
|
end
|
19
16
|
|
20
17
|
private
|
@@ -60,14 +57,26 @@ module Itamae
|
|
60
57
|
|
61
58
|
attr_accessor :node
|
62
59
|
attr_accessor :tmpdir
|
60
|
+
attr_accessor :children
|
63
61
|
|
64
62
|
def initialize(node)
|
65
63
|
@node = node
|
66
64
|
@tmpdir = "/tmp/itamae_tmp"
|
65
|
+
@children = RecipeChildren.new
|
67
66
|
|
68
67
|
Backend.instance.run_command(["mkdir", "-p", @tmpdir])
|
69
68
|
Backend.instance.run_command(["chmod", "777", @tmpdir])
|
70
69
|
end
|
70
|
+
|
71
|
+
def load_recipes(paths)
|
72
|
+
paths.each do |path|
|
73
|
+
children << Recipe.new(self, File.expand_path(path))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def run(options)
|
78
|
+
children.run(options)
|
79
|
+
end
|
71
80
|
end
|
72
81
|
end
|
73
82
|
|
data/lib/itamae/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.beta27
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: itamae
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Arai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -158,8 +158,9 @@ files:
|
|
158
158
|
- lib/itamae/cli.rb
|
159
159
|
- lib/itamae/logger.rb
|
160
160
|
- lib/itamae/node.rb
|
161
|
+
- lib/itamae/notification.rb
|
161
162
|
- lib/itamae/recipe.rb
|
162
|
-
- lib/itamae/
|
163
|
+
- lib/itamae/recipe_children.rb
|
163
164
|
- lib/itamae/resource.rb
|
164
165
|
- lib/itamae/resource/base.rb
|
165
166
|
- lib/itamae/resource/directory.rb
|
@@ -180,6 +181,7 @@ files:
|
|
180
181
|
- spec/integration/Vagrantfile
|
181
182
|
- spec/integration/default_spec.rb
|
182
183
|
- spec/integration/recipes/default.rb
|
184
|
+
- spec/integration/recipes/default2.rb
|
183
185
|
- spec/integration/recipes/hello.erb
|
184
186
|
- spec/integration/recipes/hello.txt
|
185
187
|
- spec/integration/recipes/included.rb
|
@@ -221,6 +223,7 @@ test_files:
|
|
221
223
|
- spec/integration/Vagrantfile
|
222
224
|
- spec/integration/default_spec.rb
|
223
225
|
- spec/integration/recipes/default.rb
|
226
|
+
- spec/integration/recipes/default2.rb
|
224
227
|
- spec/integration/recipes/hello.erb
|
225
228
|
- spec/integration/recipes/hello.txt
|
226
229
|
- spec/integration/recipes/included.rb
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Itamae
|
2
|
-
class RecipeDependencies < Array
|
3
|
-
NotFoundError = Class.new(StandardError)
|
4
|
-
|
5
|
-
def find_by_description(desc)
|
6
|
-
# desc is like 'resource_type[name]'
|
7
|
-
resources.find do |resource|
|
8
|
-
type, name = Itamae::Resource.parse_description(desc)
|
9
|
-
resource.resource_type == type && resource.resource_name == name
|
10
|
-
end.tap do |resource|
|
11
|
-
unless resource
|
12
|
-
raise NotFoundError, "'#{desc}' resource is not found."
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def subscribing(target)
|
18
|
-
resources.map do |resource|
|
19
|
-
resource.subscribes_resources.map do |action, r, timing|
|
20
|
-
if r == target
|
21
|
-
[action, resource, timing]
|
22
|
-
end
|
23
|
-
end.compact
|
24
|
-
end.flatten(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
def resources
|
28
|
-
self.select do |item|
|
29
|
-
item.is_a?(Resource::Base)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def recipes
|
34
|
-
self.select do |item|
|
35
|
-
item.is_a?(Recipe)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|