itamae 1.0.0.beta26 → 1.0.0.beta27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ee1b1c898ef9f58d8eb6ad84eae7f28f8b8ae3f
4
- data.tar.gz: e972f58336f252920afc143d310b3e8bf606aed2
3
+ metadata.gz: f71dbe4da1c49cacda9dac2d10c5c1cb0263e6b4
4
+ data.tar.gz: 09480bb0d8624135546598f390cabd30428b8ce0
5
5
  SHA512:
6
- metadata.gz: 6e21652210f37850b32b5ad3171a368844f809ff034d9e9122c01a6d8849629af7990104b99773e0ff35886a96061a0166a6026b4dc8d2200d2feeef5c4f7811
7
- data.tar.gz: 5954033e97e6c554a09809a624b7df553f924d8a63e24224f4dc7146c9867ed4f79a429530b2c8feeef75616511d56ee8115117ecff956bf07b18ccf20797452
6
+ metadata.gz: 4238df2db65e2f9a66d5a0021d724e0e1d1f2234f97b62b4e3fab49f8560e92150124221b2a755f450cf782a919e3ad121ae3a8179021eaeba59eaed9fb08d18
7
+ data.tar.gz: ada64866b96afadc1f916e3a4b106e9e4f59acc8c01e5797e6c86f26988a5b6af207d97de8d09e5ee25816c8e31ad4ad6b49f4abcafe4bbb54395e3c5110ca0f
data/Rakefile CHANGED
@@ -45,6 +45,7 @@ namespace :spec do
45
45
  cmd << " -l #{ENV['LOG_LEVEL'] || 'debug'}"
46
46
  cmd << " -j spec/integration/recipes/node.json"
47
47
  cmd << " spec/integration/recipes/default.rb"
48
+ cmd << " spec/integration/recipes/default2.rb"
48
49
 
49
50
  puts cmd
50
51
  system cmd
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/recipe_dependencies"
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 :dependencies
8
- attr_reader :delayed_actions
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
- @dependencies = RecipeDependencies.new
14
- @delayed_actions = []
15
+ @children = RecipeChildren.new
16
+ @delayed_notifications = []
15
17
 
16
- load_dependencies
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 "> Applying recipe... (#{@path})"
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
- @delayed_actions.uniq.each do |action, resource|
36
- resource.run(action, dry_run: options[:dry_run])
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 load_dependencies
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
- @dependencies << resource
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
- @dependencies << recipe
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
@@ -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
- @notifies = []
40
- @subscribes = []
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 "> Executing #{resource_type} (#{attributes})..."
51
+ Logger.info "Executing #{resource_type} (#{attributes})..."
50
52
 
51
53
  if do_not_run_because_of_only_if?
52
- Logger.info "< Execution skipped because of only_if attribute"
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 "< Execution skipped because of not_if attribute"
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 "< Succeeded."
76
+ Logger.info "Succeeded."
77
+ Logger.info ''
75
78
  rescue Backend::CommandExecutionError
76
- Logger.error "< Failed."
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
- @notifies << [action, resource_desc, timing]
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
- @subscribes << [action, resource_desc, timing]
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
- action_resource_timing = notifies_resources + recipe.dependencies.subscribing(self)
253
- action_resource_timing.uniq.each do |action, resource, timing|
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
- resource.run(action)
243
+ notification.run(options)
257
244
  when :delay
258
- @recipe.delayed_actions << [action, resource]
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
- recipe_files.each do |path|
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
 
@@ -1 +1 @@
1
- 1.0.0.beta26
1
+ 1.0.0.beta27
@@ -93,3 +93,7 @@ describe file('/tmp/created_by_itamae_user') do
93
93
  it { should be_owned_by 'itamae' }
94
94
  end
95
95
 
96
+ describe file('/tmp/created_in_default2') do
97
+ it { should be_file }
98
+ end
99
+
@@ -152,3 +152,9 @@ execute "echo Hello > /tmp/created_by_itamae_user" do
152
152
  user "itamae"
153
153
  end
154
154
 
155
+ #####
156
+
157
+ execute "echo 'notify to resource in default2.rb'" do
158
+ notifies :create, "file[put file in default2.rb]"
159
+ end
160
+
@@ -0,0 +1,6 @@
1
+ file "put file in default2.rb" do
2
+ action :nothing
3
+ path "/tmp/created_in_default2"
4
+ content 'Hello'
5
+ end
6
+
@@ -16,6 +16,7 @@ module Itamae
16
16
  describe ".run" do
17
17
  let(:recipes) { %w! ./recipe1.rb ./recipe2.rb ! }
18
18
  it "runs each recipe with the runner" do
19
+ pending "Rewrite later"
19
20
  recipes.each do |r|
20
21
  recipe = double(:recipe)
21
22
  Recipe.stub(:new).with(
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.beta26
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-22 00:00:00.000000000 Z
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/recipe_dependencies.rb
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