itamae 1.6.3 → 1.7.0.pre
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/CHANGELOG.md +11 -0
- data/Gemfile +3 -1
- data/Rakefile +37 -25
- data/lib/itamae/backend.rb +16 -1
- data/lib/itamae/cli.rb +3 -2
- data/lib/itamae/notification.rb +2 -2
- data/lib/itamae/recipe.rb +5 -5
- data/lib/itamae/recipe_children.rb +2 -7
- data/lib/itamae/resource/base.rb +16 -10
- data/lib/itamae/resource/execute.rb +0 -1
- data/lib/itamae/resource/file.rb +5 -4
- data/lib/itamae/runner.rb +26 -8
- data/lib/itamae/version.txt +1 -1
- data/spec/integration/Vagrantfile +1 -0
- data/spec/integration/recipes/dry_run.rb +6 -0
- data/spec/integration/spec_helper.rb +3 -6
- data/spec/unit/lib/itamae/resource/base_spec.rb +3 -10
- data/wercker.yml +5 -13
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c693dfeb747bd80dffef33f292b26a2a8e075f81
|
4
|
+
data.tar.gz: b11be7c402d731d2444cf79600b63e82987b2c1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85df294c1e5860f42b81ddcff13ef64245504d65a063a0061ac72a513af4af3d5d0fe1d416b095d9b8cf11c12e67aa9a1f5dc5cba711e08c9427cdd9cde4223c
|
7
|
+
data.tar.gz: 11d1f27227fa148d113222f3bc03a14058edcdc071e93dcc5a026928aae06c78ab3e3a4160c08b4671e3636da53168572f9fe1f31186ba9a4a59d2d2b9e5277f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## v1.6.4.pre
|
2
|
+
|
3
|
+
Features
|
4
|
+
|
5
|
+
- `--profile` option (experimental)
|
6
|
+
- `--profile PATH` saves executed commands to `PATH` in JSON format
|
7
|
+
|
8
|
+
Bugfixes
|
9
|
+
|
10
|
+
- [Suppress errors of `edit` action of `file` resource when the target file doesn't exist in `dry-run` mode](https://github.com/itamae-kitchen/itamae/pull/144)
|
11
|
+
|
1
12
|
## v1.6.3
|
2
13
|
|
3
14
|
Features
|
data/Gemfile
CHANGED
@@ -3,6 +3,9 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in itamae.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
gem 'vagrant', github: 'mitchellh/vagrant'
|
7
|
+
gem 'vagrant-digitalocean'
|
8
|
+
|
6
9
|
path = Pathname.new("Gemfile.local")
|
7
10
|
eval(path.read) if path.exist?
|
8
11
|
|
@@ -11,4 +14,3 @@ group :test do
|
|
11
14
|
gem 'growl'
|
12
15
|
end
|
13
16
|
end
|
14
|
-
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ require 'rspec/core/rake_task'
|
|
3
3
|
require 'tempfile'
|
4
4
|
require 'net/ssh'
|
5
5
|
|
6
|
-
vagrant_bin =
|
6
|
+
vagrant_bin = 'vagrant'
|
7
7
|
|
8
8
|
desc 'Run unit and integration specs.'
|
9
9
|
task :spec => ['spec:unit', 'spec:integration:all']
|
@@ -16,10 +16,13 @@ namespace :spec do
|
|
16
16
|
|
17
17
|
namespace :integration do
|
18
18
|
targets = []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
status = `cd spec/integration && #{vagrant_bin} status`
|
20
|
+
unless $?.exitstatus == 0
|
21
|
+
raise "vagrant status failed.\n#{status}"
|
22
|
+
end
|
23
|
+
|
24
|
+
status.split("\n\n")[1].each_line do |line|
|
25
|
+
targets << line.match(/^[^ ]+/)[0]
|
23
26
|
end
|
24
27
|
|
25
28
|
task :all => targets
|
@@ -30,27 +33,37 @@ namespace :spec do
|
|
30
33
|
|
31
34
|
namespace :provision do
|
32
35
|
task target do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
options = Net::SSH::Config.for(target, [config.path])
|
36
|
+
config = Tempfile.new('', Dir.tmpdir)
|
37
|
+
env = {"VAGRANT_CWD" => File.expand_path('./spec/integration')}
|
38
|
+
system env, "#{vagrant_bin} up #{target}"
|
39
|
+
system env, "#{vagrant_bin} ssh-config #{target} > #{config.path}"
|
40
|
+
options = Net::SSH::Config.for(target, [config.path])
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
suites = [
|
43
|
+
[
|
44
|
+
"spec/integration/recipes/default.rb",
|
45
|
+
"spec/integration/recipes/default2.rb",
|
46
|
+
"spec/integration/recipes/redefine.rb",
|
47
|
+
],
|
48
|
+
[
|
49
|
+
"--dry-run",
|
50
|
+
"spec/integration/recipes/dry_run.rb",
|
51
|
+
],
|
52
|
+
]
|
53
|
+
suites.each do |suite|
|
54
|
+
cmd = %w!bundle exec bin/itamae ssh!
|
55
|
+
cmd << "-h" << options[:host_name]
|
56
|
+
cmd << "-u" << options[:user]
|
57
|
+
cmd << "-p" << options[:port].to_s
|
58
|
+
cmd << "-i" << options[:keys].first
|
59
|
+
cmd << "-l" << (ENV['LOG_LEVEL'] || 'debug')
|
60
|
+
cmd << "-j" << "spec/integration/recipes/node.json"
|
61
|
+
cmd += suite
|
50
62
|
|
51
|
-
|
52
|
-
system
|
53
|
-
|
63
|
+
p cmd
|
64
|
+
unless system(*cmd)
|
65
|
+
raise "#{cmd} failed"
|
66
|
+
end
|
54
67
|
end
|
55
68
|
end
|
56
69
|
end
|
@@ -86,4 +99,3 @@ namespace :release do
|
|
86
99
|
system "git commit -m 'Bump up version'"
|
87
100
|
end
|
88
101
|
end
|
89
|
-
|
data/lib/itamae/backend.rb
CHANGED
@@ -35,9 +35,12 @@ module Itamae
|
|
35
35
|
end
|
36
36
|
|
37
37
|
class Base
|
38
|
+
attr_reader :executed_commands
|
39
|
+
|
38
40
|
def initialize(options)
|
39
41
|
@options = options
|
40
42
|
@backend = create_specinfra_backend
|
43
|
+
@executed_commands = []
|
41
44
|
end
|
42
45
|
|
43
46
|
def run_command(commands, options = {})
|
@@ -50,7 +53,9 @@ module Itamae
|
|
50
53
|
|
51
54
|
Itamae.logger.with_indent do
|
52
55
|
reset_output_handler
|
53
|
-
|
56
|
+
|
57
|
+
result = run_command_with_profiling(command)
|
58
|
+
|
54
59
|
flush_output_handler_buffer
|
55
60
|
|
56
61
|
if result.exit_status == 0 || !options[:error]
|
@@ -186,6 +191,16 @@ module Itamae
|
|
186
191
|
def shell
|
187
192
|
@options[:shell]
|
188
193
|
end
|
194
|
+
|
195
|
+
def run_command_with_profiling(command)
|
196
|
+
start_at = Time.now
|
197
|
+
result = @backend.run_command(command)
|
198
|
+
duration = Time.now.to_f - start_at.to_f
|
199
|
+
|
200
|
+
@executed_commands << {command: command, duration: duration}
|
201
|
+
|
202
|
+
result
|
203
|
+
end
|
189
204
|
end
|
190
205
|
|
191
206
|
class Local < Base
|
data/lib/itamae/cli.rb
CHANGED
@@ -15,12 +15,13 @@ module Itamae
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.define_exec_options
|
18
|
-
option :dot, type: :string, default: nil, desc: "Only write dependency graph in DOT", banner: "PATH"
|
18
|
+
option :dot, type: :string, default: nil, desc: "[EXPERIMENTAL] Only write dependency graph in DOT", banner: "PATH"
|
19
19
|
option :node_json, type: :string, aliases: ['-j']
|
20
20
|
option :node_yaml, type: :string, aliases: ['-y']
|
21
21
|
option :dry_run, type: :boolean, aliases: ['-n']
|
22
22
|
option :shell, type: :string, default: "/bin/sh"
|
23
|
-
option :ohai, type: :boolean, default: false, desc: "This option is DEPRECATED and will be
|
23
|
+
option :ohai, type: :boolean, default: false, desc: "This option is DEPRECATED and will be unavailable."
|
24
|
+
option :profile, type: :string, desc: "[EXPERIMENTAL] Save profiling data", banner: "PATH"
|
24
25
|
end
|
25
26
|
|
26
27
|
desc "local RECIPE [RECIPE...]", "Run Itamae locally"
|
data/lib/itamae/notification.rb
CHANGED
data/lib/itamae/recipe.rb
CHANGED
@@ -58,24 +58,24 @@ module Itamae
|
|
58
58
|
context.instance_eval(File.read(path), path, 1)
|
59
59
|
end
|
60
60
|
|
61
|
-
def run
|
61
|
+
def run
|
62
62
|
show_banner
|
63
63
|
|
64
64
|
Itamae.logger.with_indent do
|
65
|
-
@children.run
|
66
|
-
run_delayed_notifications
|
65
|
+
@children.run
|
66
|
+
run_delayed_notifications
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
private
|
71
71
|
|
72
|
-
def run_delayed_notifications
|
72
|
+
def run_delayed_notifications
|
73
73
|
@delayed_notifications.uniq! do |notification|
|
74
74
|
[notification.action, notification.action_resource]
|
75
75
|
end
|
76
76
|
|
77
77
|
while notification = @delayed_notifications.shift
|
78
|
-
notification.run
|
78
|
+
notification.run
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -53,14 +53,9 @@ module Itamae
|
|
53
53
|
end.flatten
|
54
54
|
end
|
55
55
|
|
56
|
-
def run
|
56
|
+
def run
|
57
57
|
self.each do |resource|
|
58
|
-
|
59
|
-
when Resource::Base
|
60
|
-
resource.run(nil, dry_run: options[:dry_run])
|
61
|
-
when Recipe
|
62
|
-
resource.run(options)
|
63
|
-
end
|
58
|
+
resource.run
|
64
59
|
end
|
65
60
|
end
|
66
61
|
|
data/lib/itamae/resource/base.rb
CHANGED
@@ -120,7 +120,7 @@ module Itamae
|
|
120
120
|
process_attributes
|
121
121
|
end
|
122
122
|
|
123
|
-
def run(specific_action = nil
|
123
|
+
def run(specific_action = nil)
|
124
124
|
Itamae.logger.debug "#{resource_type}[#{resource_name}]"
|
125
125
|
|
126
126
|
Itamae.logger.with_indent_if(Itamae.logger.debug?) do
|
@@ -133,11 +133,11 @@ module Itamae
|
|
133
133
|
end
|
134
134
|
|
135
135
|
[specific_action || attributes.action].flatten.each do |action|
|
136
|
-
run_action(action
|
136
|
+
run_action(action)
|
137
137
|
end
|
138
138
|
|
139
|
-
verify unless
|
140
|
-
notify
|
139
|
+
verify unless runner.dry_run?
|
140
|
+
notify if updated?
|
141
141
|
end
|
142
142
|
|
143
143
|
@updated = false
|
@@ -146,7 +146,7 @@ module Itamae
|
|
146
146
|
exit 2
|
147
147
|
end
|
148
148
|
|
149
|
-
def action_nothing
|
149
|
+
def action_nothing
|
150
150
|
# do nothing
|
151
151
|
end
|
152
152
|
|
@@ -166,7 +166,7 @@ module Itamae
|
|
166
166
|
|
167
167
|
alias_method :current, :current_attributes
|
168
168
|
|
169
|
-
def run_action(action
|
169
|
+
def run_action(action)
|
170
170
|
original_attributes = @attributes # preserve and restore later
|
171
171
|
@current_action = action
|
172
172
|
|
@@ -187,12 +187,18 @@ module Itamae
|
|
187
187
|
show_differences
|
188
188
|
|
189
189
|
method_name = "action_#{action}"
|
190
|
-
if
|
190
|
+
if runner.dry_run?
|
191
191
|
unless respond_to?(method_name)
|
192
192
|
Itamae.logger.error "action #{action.inspect} is unavailable"
|
193
193
|
end
|
194
194
|
else
|
195
|
-
|
195
|
+
args = [method_name]
|
196
|
+
if method(method_name).arity == 1
|
197
|
+
# for plugin compatibility
|
198
|
+
args << runner.options
|
199
|
+
end
|
200
|
+
|
201
|
+
public_send(*args)
|
196
202
|
end
|
197
203
|
|
198
204
|
updated! if different?
|
@@ -327,7 +333,7 @@ module Itamae
|
|
327
333
|
@updated
|
328
334
|
end
|
329
335
|
|
330
|
-
def notify
|
336
|
+
def notify
|
331
337
|
(notifications + recipe.children.subscribing(self)).each do |notification|
|
332
338
|
message = "Notifying #{notification.action} to #{notification.action_resource.resource_type} resource '#{notification.action_resource.resource_name}'"
|
333
339
|
|
@@ -346,7 +352,7 @@ module Itamae
|
|
346
352
|
if notification.delayed?
|
347
353
|
@recipe.delayed_notifications << notification
|
348
354
|
elsif notification.immediately?
|
349
|
-
notification.run
|
355
|
+
notification.run
|
350
356
|
end
|
351
357
|
end
|
352
358
|
end
|
data/lib/itamae/resource/file.rb
CHANGED
@@ -20,9 +20,11 @@ module Itamae
|
|
20
20
|
when :edit
|
21
21
|
attributes.exist = true
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
unless runner.dry_run?
|
24
|
+
content = backend.receive_file(attributes.path)
|
25
|
+
attributes.block.call(content)
|
26
|
+
attributes.content = content
|
27
|
+
end
|
26
28
|
end
|
27
29
|
|
28
30
|
send_tempfile
|
@@ -163,4 +165,3 @@ module Itamae
|
|
163
165
|
end
|
164
166
|
end
|
165
167
|
end
|
166
|
-
|
data/lib/itamae/runner.rb
CHANGED
@@ -13,18 +13,20 @@ module Itamae
|
|
13
13
|
runner.load_recipes(recipe_files)
|
14
14
|
|
15
15
|
if dot_file = options[:dot]
|
16
|
-
|
17
|
-
open(dot_file, 'w') do |f|
|
18
|
-
f.write(runner.children.deps_in_dot)
|
19
|
-
end
|
16
|
+
runner.save_dependency_graph(dot_file)
|
20
17
|
return
|
21
18
|
end
|
22
19
|
|
23
|
-
runner.run
|
20
|
+
runner.run
|
21
|
+
|
22
|
+
if profile = options[:profile]
|
23
|
+
runner.save_profile(profile)
|
24
|
+
end
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
28
|
attr_reader :backend
|
29
|
+
attr_reader :options
|
28
30
|
attr_reader :node
|
29
31
|
attr_reader :tmpdir
|
30
32
|
attr_reader :children
|
@@ -55,11 +57,28 @@ module Itamae
|
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
def run
|
59
|
-
children.run
|
60
|
+
def run
|
61
|
+
children.run
|
60
62
|
@backend.finalize
|
61
63
|
end
|
62
64
|
|
65
|
+
def dry_run?
|
66
|
+
@options[:dry_run]
|
67
|
+
end
|
68
|
+
|
69
|
+
def save_dependency_graph(path)
|
70
|
+
Itamae.logger.info "Writing dependency graph in DOT to #{path}..."
|
71
|
+
open(path, 'w') do |f|
|
72
|
+
f.write(runner.children.deps_in_dot)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def save_profile(path)
|
77
|
+
open(path, 'w', 0600) do |f|
|
78
|
+
f.write(@backend.executed_commands.to_json)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
63
82
|
private
|
64
83
|
def create_node
|
65
84
|
hash = {}
|
@@ -91,4 +110,3 @@ module Itamae
|
|
91
110
|
end
|
92
111
|
end
|
93
112
|
end
|
94
|
-
|
data/lib/itamae/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.7.0.pre
|
@@ -5,10 +5,8 @@ require 'tempfile'
|
|
5
5
|
set :backend, :ssh
|
6
6
|
|
7
7
|
def vagrant(cmd)
|
8
|
-
|
9
|
-
|
10
|
-
system env, "/usr/bin/vagrant #{cmd}"
|
11
|
-
end
|
8
|
+
env = {"VAGRANT_CWD" => File.dirname(__FILE__)}
|
9
|
+
system(env, "vagrant #{cmd}")
|
12
10
|
end
|
13
11
|
|
14
12
|
if ENV['ASK_SUDO_PASSWORD']
|
@@ -38,8 +36,7 @@ set :ssh_options, options
|
|
38
36
|
# set :disable_sudo, true
|
39
37
|
|
40
38
|
# Set environment variables
|
41
|
-
# set :env, :LANG => 'C', :LC_MESSAGES => 'C'
|
39
|
+
# set :env, :LANG => 'C', :LC_MESSAGES => 'C'
|
42
40
|
|
43
41
|
# Set PATH
|
44
42
|
# set :path, '/sbin:/usr/local/sbin:$PATH'
|
45
|
-
|
@@ -102,7 +102,9 @@ describe TestResource do
|
|
102
102
|
|
103
103
|
let(:commands) { double(:commands) }
|
104
104
|
let(:runner) do
|
105
|
-
|
105
|
+
instance_double(Itamae::Runner).tap do |r|
|
106
|
+
allow(r).to receive(:dry_run?).and_return(false)
|
107
|
+
end
|
106
108
|
end
|
107
109
|
let(:recipe) do
|
108
110
|
double(:recipe).tap do |r|
|
@@ -120,14 +122,5 @@ describe TestResource do
|
|
120
122
|
expect(subject).to receive(:action_name)
|
121
123
|
subject.run
|
122
124
|
end
|
123
|
-
|
124
|
-
context 'with dry_run' do
|
125
|
-
context 'when specified action is unavailable' do
|
126
|
-
it 'logs error' do
|
127
|
-
expect(Itamae.logger).to receive(:error).with(/action :name is unavailable/)
|
128
|
-
subject.run(nil, dry_run: true)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
125
|
end
|
133
126
|
end
|
data/wercker.yml
CHANGED
@@ -47,25 +47,17 @@ build:
|
|
47
47
|
name: chmod 600 id_rsa
|
48
48
|
code: chmod 600 $HOME/.ssh/id_rsa.vagrant
|
49
49
|
|
50
|
-
- script:
|
51
|
-
name: download vagrant
|
52
|
-
code: wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.3_x86_64.deb
|
53
|
-
|
54
|
-
- script:
|
55
|
-
name: install vagrant
|
56
|
-
code: sudo dpkg -i vagrant_1.6.3_x86_64.deb
|
57
|
-
|
58
50
|
- script:
|
59
51
|
name: install libxml and libxslt
|
60
52
|
code: sudo apt-get install libxml2-dev libxslt1-dev
|
61
53
|
|
62
54
|
- script:
|
63
|
-
name: install
|
64
|
-
code:
|
55
|
+
name: bundle install
|
56
|
+
code: bundle install --deployment -j4
|
65
57
|
|
66
58
|
- script:
|
67
59
|
name: start vm
|
68
|
-
code: vagrant up --provider=digital_ocean
|
60
|
+
code: bundle exec vagrant up --provider=digital_ocean
|
69
61
|
cwd: spec/integration
|
70
62
|
|
71
63
|
# Add more steps here:
|
@@ -76,10 +68,10 @@ build:
|
|
76
68
|
after-steps:
|
77
69
|
- script:
|
78
70
|
name: shutdown vm
|
79
|
-
code: vagrant destroy -f
|
71
|
+
code: bundle exec vagrant destroy -f
|
80
72
|
cwd: spec/integration
|
81
73
|
|
82
74
|
- script:
|
83
75
|
name: shutdown old vms
|
84
|
-
code: ruby ci/destroy_old_droplets.rb
|
76
|
+
code: bundle exec ruby ci/destroy_old_droplets.rb
|
85
77
|
|
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.
|
4
|
+
version: 1.7.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Arai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- spec/integration/recipes/default2.rb
|
245
245
|
- spec/integration/recipes/define/default.rb
|
246
246
|
- spec/integration/recipes/define/files/remote_file_in_definition
|
247
|
+
- spec/integration/recipes/dry_run.rb
|
247
248
|
- spec/integration/recipes/files/remote_file_auto
|
248
249
|
- spec/integration/recipes/hello.erb
|
249
250
|
- spec/integration/recipes/hello.txt
|
@@ -276,9 +277,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
276
277
|
version: '0'
|
277
278
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
278
279
|
requirements:
|
279
|
-
- - "
|
280
|
+
- - ">"
|
280
281
|
- !ruby/object:Gem::Version
|
281
|
-
version:
|
282
|
+
version: 1.3.1
|
282
283
|
requirements: []
|
283
284
|
rubyforge_project:
|
284
285
|
rubygems_version: 2.4.5
|
@@ -292,6 +293,7 @@ test_files:
|
|
292
293
|
- spec/integration/recipes/default2.rb
|
293
294
|
- spec/integration/recipes/define/default.rb
|
294
295
|
- spec/integration/recipes/define/files/remote_file_in_definition
|
296
|
+
- spec/integration/recipes/dry_run.rb
|
295
297
|
- spec/integration/recipes/files/remote_file_auto
|
296
298
|
- spec/integration/recipes/hello.erb
|
297
299
|
- spec/integration/recipes/hello.txt
|