itamae 1.0.0.beta3 → 1.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/itamae.gemspec +2 -2
- data/lib/itamae.rb +1 -1
- data/lib/itamae/backend.rb +86 -0
- data/lib/itamae/cli.rb +2 -0
- data/lib/itamae/recipe.rb +4 -3
- data/lib/itamae/resource.rb +1 -1
- data/lib/itamae/resource/base.rb +31 -49
- data/lib/itamae/resource/directory.rb +6 -5
- data/lib/itamae/resource/file.rb +12 -3
- data/lib/itamae/resource/link.rb +17 -0
- data/lib/itamae/resource/mail_alias.rb +2 -2
- data/lib/itamae/resource/service.rb +2 -1
- data/lib/itamae/runner.rb +24 -14
- data/lib/itamae/version.rb +1 -1
- data/spec/integration/default_spec.rb +9 -2
- data/spec/integration/recipes/default.rb +7 -3
- data/spec/unit/lib/itamae/resource/base_spec.rb +8 -24
- data/spec/unit/lib/itamae/resource/link_spec.rb +24 -0
- data/spec/unit/lib/itamae/resource/remote_file_spec.rb +15 -2
- data/spec/unit/lib/itamae/runner_spec.rb +3 -1
- metadata +10 -7
- data/lib/itamae/specinfra.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4aeeda7470e3841a47a420c875efb9d332f5359e
|
4
|
+
data.tar.gz: 48fe841ad7c50ab056314b47e33835d506bc5e10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 553a0d69d5f583903f5f09226a9084165a389efa9481a94ea057e74da50d40a1828b57f60bcf4448ccc46366d5ac6aed10504bda68fb07adea2b7d1a5668c854
|
7
|
+
data.tar.gz: e14ac9b44bc9672014ef0c8d3d38eeca1a3dcbf496c07769c4a51f7c46166c9db4a6b723d5da328dcc87a24bb550e6a51d4495bec280e41048f8d593f7fea50a
|
data/itamae.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_runtime_dependency "thor"
|
21
|
-
spec.add_runtime_dependency "specinfra", "2.0.0.
|
21
|
+
spec.add_runtime_dependency "specinfra", "2.0.0.beta35"
|
22
22
|
spec.add_runtime_dependency "hashie"
|
23
23
|
spec.add_runtime_dependency "ansi"
|
24
24
|
|
@@ -28,6 +28,6 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "bundler", "~> 1.3"
|
29
29
|
spec.add_development_dependency "rake"
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
-
spec.add_development_dependency "serverspec", "2.0.0.
|
31
|
+
spec.add_development_dependency "serverspec", "2.0.0.beta20"
|
32
32
|
spec.add_development_dependency "pry-byebug"
|
33
33
|
end
|
data/lib/itamae.rb
CHANGED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'specinfra'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module Itamae
|
5
|
+
class Backend
|
6
|
+
UnknownBackendTypeError = Class.new(StandardError)
|
7
|
+
CommandExecutionError = Class.new(StandardError)
|
8
|
+
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def set_type(type, options = {})
|
12
|
+
case type
|
13
|
+
when :local
|
14
|
+
Specinfra.configuration.backend = :exec
|
15
|
+
when :ssh
|
16
|
+
Specinfra.configuration.request_pty = true
|
17
|
+
Specinfra.configuration.host = options.delete(:host)
|
18
|
+
Specinfra.configuration.ssh_options = options
|
19
|
+
|
20
|
+
Specinfra.configuration.backend = :ssh
|
21
|
+
else
|
22
|
+
raise UnknownBackendTypeError, "'#{type}' backend is unknown."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def run_command(commands, options = {})
|
27
|
+
options = {error: true}.merge(options)
|
28
|
+
|
29
|
+
if commands.is_a?(Array)
|
30
|
+
command = commands.map do |cmd|
|
31
|
+
Shellwords.escape(cmd)
|
32
|
+
end.join(' ')
|
33
|
+
else
|
34
|
+
command = commands
|
35
|
+
end
|
36
|
+
|
37
|
+
result = Specinfra::Runner.run_command(command)
|
38
|
+
exit_status = result.exit_status
|
39
|
+
|
40
|
+
if exit_status == 0 || !options[:error]
|
41
|
+
method = :debug
|
42
|
+
message = " Command `#{command}` exited with #{exit_status}"
|
43
|
+
else
|
44
|
+
method = :error
|
45
|
+
message = " Command `#{command}` failed. (exit status: #{exit_status})"
|
46
|
+
end
|
47
|
+
|
48
|
+
Logger.public_send(method, message)
|
49
|
+
|
50
|
+
{"stdout" => result.stdout, "stderr" => result.stderr}.each_pair do |name, value|
|
51
|
+
if value && value != ''
|
52
|
+
value.each_line do |line|
|
53
|
+
# remove control chars
|
54
|
+
case line.encoding
|
55
|
+
when Encoding::UTF_8
|
56
|
+
line = line.tr("\u0000-\u001f\u007f\u2028",'')
|
57
|
+
end
|
58
|
+
|
59
|
+
Logger.public_send(method, " #{name} | #{line}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if options[:error] && exit_status != 0
|
65
|
+
raise CommandExecutionError
|
66
|
+
end
|
67
|
+
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def run_specinfra(type, *args)
|
72
|
+
command = Specinfra.command.get(type, *args)
|
73
|
+
|
74
|
+
if type.to_s.start_with?("check_")
|
75
|
+
result = run_command(command, error: false)
|
76
|
+
result.exit_status == 0
|
77
|
+
else
|
78
|
+
run_command(command)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def copy_file(*args)
|
83
|
+
Specinfra::Runner.copy_file(*args)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/itamae/cli.rb
CHANGED
@@ -13,12 +13,14 @@ module Itamae
|
|
13
13
|
|
14
14
|
desc "local RECIPE [RECIPE...]", "Run Itamae locally"
|
15
15
|
option :node_json, type: :string, aliases: ['-j']
|
16
|
+
option :dry_run, type: :string, aliases: ['-n']
|
16
17
|
def local(*recipe_files)
|
17
18
|
Runner.run(recipe_files, :local, options)
|
18
19
|
end
|
19
20
|
|
20
21
|
desc "ssh RECIPE [RECIPE...]", "Run Itamae via ssh"
|
21
22
|
option :node_json, type: :string, aliases: ['-j']
|
23
|
+
option :dry_run, type: :string, aliases: ['-n']
|
22
24
|
option :host, required: true, type: :string, aliases: ['-h']
|
23
25
|
option :user, type: :string, aliases: ['-u']
|
24
26
|
option :key, type: :string, aliases: ['-i']
|
data/lib/itamae/recipe.rb
CHANGED
@@ -20,13 +20,14 @@ module Itamae
|
|
20
20
|
@runner.node
|
21
21
|
end
|
22
22
|
|
23
|
-
def run
|
23
|
+
def run(options = {})
|
24
24
|
@resources.each do |resource|
|
25
|
-
|
25
|
+
# do action specified in the recipe
|
26
|
+
resource.run(nil, dry_run: options[:dry_run])
|
26
27
|
end
|
27
28
|
|
28
29
|
@delayed_actions.uniq.each do |action, resource|
|
29
|
-
resource.run(action)
|
30
|
+
resource.run(action, dry_run: options[:dry_run])
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
data/lib/itamae/resource.rb
CHANGED
@@ -8,11 +8,11 @@ require 'itamae/resource/template'
|
|
8
8
|
require 'itamae/resource/execute'
|
9
9
|
require 'itamae/resource/mail_alias'
|
10
10
|
require 'itamae/resource/service'
|
11
|
+
require 'itamae/resource/link'
|
11
12
|
|
12
13
|
module Itamae
|
13
14
|
module Resource
|
14
15
|
Error = Class.new(StandardError)
|
15
|
-
CommandExecutionError = Class.new(StandardError)
|
16
16
|
AttributeMissingError = Class.new(StandardError)
|
17
17
|
InvalidTypeError = Class.new(StandardError)
|
18
18
|
ParseError = Class.new(StandardError)
|
data/lib/itamae/resource/base.rb
CHANGED
@@ -43,7 +43,7 @@ module Itamae
|
|
43
43
|
process_attributes
|
44
44
|
end
|
45
45
|
|
46
|
-
def run(specific_action = nil)
|
46
|
+
def run(specific_action = nil, options = {})
|
47
47
|
Logger.info "> Executing #{resource_type} (#{attributes})..."
|
48
48
|
|
49
49
|
if do_not_run_because_of_only_if?
|
@@ -57,16 +57,18 @@ module Itamae
|
|
57
57
|
set_current_attributes
|
58
58
|
show_differences
|
59
59
|
|
60
|
-
|
60
|
+
unless options[:dry_run]
|
61
61
|
public_send("#{specific_action || action}_action".to_sym)
|
62
|
-
rescue Resource::CommandExecutionError
|
63
|
-
Logger.error "< Failed."
|
64
|
-
exit 2
|
65
62
|
end
|
66
63
|
|
64
|
+
updated! if different?
|
65
|
+
|
67
66
|
notify if updated?
|
68
67
|
|
69
68
|
Logger.info "< Succeeded."
|
69
|
+
rescue Backend::CommandExecutionError
|
70
|
+
Logger.error "< Failed."
|
71
|
+
exit 2
|
70
72
|
end
|
71
73
|
|
72
74
|
def nothing_action
|
@@ -112,12 +114,23 @@ module Itamae
|
|
112
114
|
end
|
113
115
|
|
114
116
|
def set_current_attributes
|
117
|
+
# do nothing
|
118
|
+
end
|
119
|
+
|
120
|
+
def different?
|
121
|
+
@current_attributes.each_pair.any? do |key, current_value|
|
122
|
+
current_value != @attributes[key]
|
123
|
+
end
|
115
124
|
end
|
116
125
|
|
117
126
|
def show_differences
|
118
127
|
@current_attributes.each_pair do |key, current_value|
|
119
128
|
value = @attributes[key]
|
120
|
-
|
129
|
+
if current_value == value
|
130
|
+
Logger.info " #{key} will not change (current value is '#{current_value}')"
|
131
|
+
else
|
132
|
+
Logger.info " #{key} will change from '#{current_value}' to '#{value}'"
|
133
|
+
end
|
121
134
|
end
|
122
135
|
end
|
123
136
|
|
@@ -136,48 +149,6 @@ module Itamae
|
|
136
149
|
end
|
137
150
|
end
|
138
151
|
|
139
|
-
def run_specinfra(type, *args)
|
140
|
-
command = Specinfra.command.get(type, *args)
|
141
|
-
|
142
|
-
if type.to_s.start_with?("check_")
|
143
|
-
result = run_command(command, error: false)
|
144
|
-
result.exit_status == 0
|
145
|
-
else
|
146
|
-
run_command(command)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def run_command(command, options = {})
|
151
|
-
options = {error: true}.merge(options)
|
152
|
-
|
153
|
-
result = backend.run_command(command)
|
154
|
-
exit_status = result.exit_status
|
155
|
-
|
156
|
-
if exit_status == 0 || !options[:error]
|
157
|
-
method = :debug
|
158
|
-
message = " Command `#{command}` exited with #{exit_status}"
|
159
|
-
else
|
160
|
-
method = :error
|
161
|
-
message = " Command `#{command}` failed. (exit status: #{exit_status})"
|
162
|
-
end
|
163
|
-
|
164
|
-
Logger.public_send(method, message)
|
165
|
-
|
166
|
-
if result.stdout && result.stdout != ''
|
167
|
-
Logger.public_send(method, " STDOUT> #{result.stdout.chomp}")
|
168
|
-
end
|
169
|
-
|
170
|
-
if result.stderr && result.stderr != ''
|
171
|
-
Logger.public_send(method, " STDERR> #{result.stderr.chomp}")
|
172
|
-
end
|
173
|
-
|
174
|
-
if options[:error] && exit_status != 0
|
175
|
-
raise CommandExecutionError
|
176
|
-
end
|
177
|
-
|
178
|
-
result
|
179
|
-
end
|
180
|
-
|
181
152
|
def copy_file(src, dst)
|
182
153
|
Logger.debug " Copying a file from '#{src}' to '#{dst}'..."
|
183
154
|
unless ::File.exist?(src)
|
@@ -217,7 +188,7 @@ module Itamae
|
|
217
188
|
end
|
218
189
|
|
219
190
|
def backend
|
220
|
-
|
191
|
+
Backend.instance
|
221
192
|
end
|
222
193
|
|
223
194
|
def runner
|
@@ -228,11 +199,22 @@ module Itamae
|
|
228
199
|
@recipe.resources
|
229
200
|
end
|
230
201
|
|
202
|
+
def run_command(*args)
|
203
|
+
backend.run_command(*args)
|
204
|
+
end
|
205
|
+
|
206
|
+
def run_specinfra(*args)
|
207
|
+
backend.run_specinfra(*args)
|
208
|
+
end
|
209
|
+
|
231
210
|
def shell_escape(str)
|
232
211
|
Shellwords.escape(str)
|
233
212
|
end
|
234
213
|
|
235
214
|
def updated!
|
215
|
+
unless @updated
|
216
|
+
Logger.debug " This resource is updated."
|
217
|
+
end
|
236
218
|
@updated = true
|
237
219
|
end
|
238
220
|
|
@@ -10,11 +10,12 @@ module Itamae
|
|
10
10
|
define_attribute :group, type: String
|
11
11
|
|
12
12
|
def set_current_attributes
|
13
|
-
|
14
|
-
|
15
|
-
@current_attributes[:
|
16
|
-
@current_attributes[:
|
17
|
-
|
13
|
+
if run_specinfra(:check_file_is_directory, path)
|
14
|
+
@current_attributes[:mode] = run_specinfra(:get_file_mode, path).stdout.chomp
|
15
|
+
@current_attributes[:owner] = run_specinfra(:get_file_owner_user, path).stdout.chomp
|
16
|
+
@current_attributes[:group] = run_specinfra(:get_file_owner_group, path).stdout.chomp
|
17
|
+
else
|
18
|
+
updated!
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
data/lib/itamae/resource/file.rb
CHANGED
@@ -21,14 +21,23 @@ module Itamae
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
temppath = ::File.join(runner.tmpdir, Time.now.to_f.to_s)
|
25
|
+
copy_file(src, temppath)
|
25
26
|
|
26
27
|
if mode
|
27
|
-
|
28
|
+
run_specinfra(:change_file_mode, temppath, mode)
|
28
29
|
end
|
29
30
|
if owner || group
|
30
|
-
|
31
|
+
run_specinfra(:change_file_owner, temppath, owner, group)
|
31
32
|
end
|
33
|
+
|
34
|
+
if run_specinfra(:check_file_is_file, path)
|
35
|
+
# TODO: specinfra
|
36
|
+
run_command(["cp", path, "#{path}.bak"])
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: specinfra
|
40
|
+
run_command(["mv", temppath, path])
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'itamae'
|
2
|
+
|
3
|
+
module Itamae
|
4
|
+
module Resource
|
5
|
+
class Link < Base
|
6
|
+
define_attribute :action, default: :create
|
7
|
+
define_attribute :link, type: String, default_name: true
|
8
|
+
define_attribute :to, type: String, required: true
|
9
|
+
|
10
|
+
def create_action
|
11
|
+
if ! run_specinfra(:check_file_is_linked_to, link, to)
|
12
|
+
run_specinfra(:link_file_to, link, to)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -8,8 +8,8 @@ module Itamae
|
|
8
8
|
define_attribute :recipient, type: String, required: true
|
9
9
|
|
10
10
|
def create_action
|
11
|
-
if !
|
12
|
-
|
11
|
+
if !run_specinfra(:check_mail_alias_is_aliased_to, mail_alias, recipient)
|
12
|
+
run_specinfra(:add_mail_alias, mail_alias, recipient)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/itamae/runner.rb
CHANGED
@@ -3,14 +3,14 @@ require 'itamae'
|
|
3
3
|
module Itamae
|
4
4
|
class Runner
|
5
5
|
class << self
|
6
|
-
def run(recipe_files,
|
7
|
-
|
8
|
-
|
9
|
-
runner
|
6
|
+
def run(recipe_files, backend_type, options)
|
7
|
+
set_backend_from_options(backend_type, options)
|
8
|
+
|
9
|
+
runner = self.new(node_from_options(options))
|
10
10
|
|
11
11
|
recipe_files.each do |path|
|
12
12
|
recipe = Recipe.new(runner, File.expand_path(path))
|
13
|
-
recipe.run
|
13
|
+
recipe.run(dry_run: options[:dry_run])
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -27,23 +27,33 @@ module Itamae
|
|
27
27
|
Node.new(hash)
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def set_backend_from_options(type, options)
|
31
|
+
opts = {}
|
32
|
+
|
31
33
|
case type
|
32
34
|
when :local
|
33
|
-
|
35
|
+
# do nothing
|
34
36
|
when :ssh
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
ssh_options[:port] = options[:port] if options[:port]
|
40
|
-
|
41
|
-
Itamae.create_ssh_backend(ssh_options)
|
37
|
+
opts[:host] = options[:host]
|
38
|
+
opts[:user] = options[:user] || Etc.getlogin
|
39
|
+
opts[:keys] = [options[:key]] if options[:key]
|
40
|
+
opts[:port] = options[:port] if options[:port]
|
42
41
|
end
|
42
|
+
|
43
|
+
Backend.instance.set_type(type, opts)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
47
|
attr_accessor :node
|
48
|
+
attr_accessor :tmpdir
|
49
|
+
|
50
|
+
def initialize(node)
|
51
|
+
@node = node
|
52
|
+
@tmpdir = "/tmp/itamae_tmp"
|
53
|
+
|
54
|
+
Backend.instance.run_command(["mkdir", "-p", @tmpdir])
|
55
|
+
Backend.instance.run_command(["chmod", "777", @tmpdir])
|
56
|
+
end
|
47
57
|
end
|
48
58
|
end
|
49
59
|
|
data/lib/itamae/version.rb
CHANGED
@@ -28,6 +28,7 @@ end
|
|
28
28
|
describe file('/tmp/file') do
|
29
29
|
it { should be_file }
|
30
30
|
its(:content) { should match(/Hello World/) }
|
31
|
+
it { should be_mode 777 }
|
31
32
|
end
|
32
33
|
|
33
34
|
describe file('/tmp/execute') do
|
@@ -56,14 +57,20 @@ end
|
|
56
57
|
describe file('/tmp/cron_stopped') do
|
57
58
|
it { should be_file }
|
58
59
|
its(:content) do
|
59
|
-
expect(subject.content.lines.size).to eq
|
60
|
+
expect(subject.content.lines.size).to eq 1
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
64
|
describe file('/tmp/cron_running') do
|
64
65
|
it { should be_file }
|
65
66
|
its(:content) do
|
66
|
-
expect(subject.content.lines.size).to eq
|
67
|
+
expect(subject.content.lines.size).to eq 2
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
71
|
+
describe file('/tmp-link') do
|
72
|
+
it { should be_linked_to '/tmp' }
|
73
|
+
its(:content) do
|
74
|
+
expect(subject.content.lines.size).to eq 0
|
75
|
+
end
|
76
|
+
end
|
@@ -49,7 +49,7 @@ remote_file "/tmp/remote_file" do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
directory "/tmp/directory" do
|
52
|
-
mode "
|
52
|
+
mode "700"
|
53
53
|
owner "vagrant"
|
54
54
|
group "vagrant"
|
55
55
|
end
|
@@ -60,6 +60,7 @@ end
|
|
60
60
|
|
61
61
|
file "/tmp/file" do
|
62
62
|
content "Hello World"
|
63
|
+
mode "777"
|
63
64
|
end
|
64
65
|
|
65
66
|
execute "echo 'Hello Execute' > /tmp/execute"
|
@@ -78,13 +79,16 @@ service "cron" do
|
|
78
79
|
action :stop
|
79
80
|
end
|
80
81
|
|
81
|
-
execute "ps
|
82
|
+
execute "ps -C cron > /tmp/cron_stopped; true"
|
82
83
|
|
83
84
|
service "cron" do
|
84
85
|
action :start
|
85
86
|
end
|
86
87
|
|
87
|
-
execute "ps
|
88
|
+
execute "ps -C cron > /tmp/cron_running; true"
|
88
89
|
|
89
90
|
######
|
90
91
|
|
92
|
+
link "/tmp-link" do
|
93
|
+
to "/tmp"
|
94
|
+
end
|
@@ -86,6 +86,8 @@ class TestResource < Itamae::Resource::Base
|
|
86
86
|
end
|
87
87
|
|
88
88
|
describe TestResource do
|
89
|
+
subject(:resource) { described_class.new(recipe, "name") }
|
90
|
+
|
89
91
|
let(:commands) { double(:commands) }
|
90
92
|
let(:runner) do
|
91
93
|
double(:runner)
|
@@ -95,15 +97,16 @@ describe TestResource do
|
|
95
97
|
r.stub(:runner).and_return(runner)
|
96
98
|
end
|
97
99
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
before do
|
102
|
-
Itamae.backend = double(:backend).tap do |b|
|
100
|
+
let(:backend) do
|
101
|
+
double(:backend).tap do |b|
|
103
102
|
b.stub(:commands).and_return(commands)
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
106
|
+
before do
|
107
|
+
Backend.stub(:instance).and_return(backend)
|
108
|
+
end
|
109
|
+
|
107
110
|
describe "#run" do
|
108
111
|
before do
|
109
112
|
subject.action :action_name
|
@@ -113,23 +116,4 @@ describe TestResource do
|
|
113
116
|
subject.run
|
114
117
|
end
|
115
118
|
end
|
116
|
-
|
117
|
-
describe "#run_specinfra" do
|
118
|
-
it "runs specinfra's command by specinfra's backend" do
|
119
|
-
expect(Specinfra.command).to receive(:get).with(:cmd).and_return("command")
|
120
|
-
expect(Itamae.backend).to receive(:run_command).with("command").
|
121
|
-
and_return(Specinfra::CommandResult.new(exit_status: 0))
|
122
|
-
subject.send(:run_specinfra, :cmd)
|
123
|
-
end
|
124
|
-
context "when the command execution failed" do
|
125
|
-
it "raises CommandExecutionError" do
|
126
|
-
expect(Specinfra.command).to receive(:get).with(:cmd).and_return("command")
|
127
|
-
expect(Itamae.backend).to receive(:run_command).with("command").
|
128
|
-
and_return(Specinfra::CommandResult.new(exit_status: 1))
|
129
|
-
expect do
|
130
|
-
subject.send(:run_specinfra, :cmd)
|
131
|
-
end.to raise_error(Itamae::Resource::CommandExecutionError)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
119
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'itamae'
|
2
|
+
|
3
|
+
module Itamae
|
4
|
+
describe Resource::Link do
|
5
|
+
let(:recipe) { double(:recipe) }
|
6
|
+
|
7
|
+
subject(:resource) do
|
8
|
+
described_class.new(recipe, "name") do
|
9
|
+
to "/path/to/target"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#create_action" do
|
14
|
+
it "runs install command of specinfra" do
|
15
|
+
subject.link :link_name
|
16
|
+
expect(subject).to receive(:run_specinfra).with(:check_file_is_linked_to, :link_name, "/path/to/target").and_return(false)
|
17
|
+
expect(subject).to receive(:run_specinfra).with(:link_file_to, :link_name, "/path/to/target")
|
18
|
+
subject.create_action
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
@@ -2,7 +2,17 @@ require 'itamae'
|
|
2
2
|
|
3
3
|
module Itamae
|
4
4
|
describe Resource::RemoteFile do
|
5
|
-
let(:
|
5
|
+
let(:runner) do
|
6
|
+
double(:runner).tap do |r|
|
7
|
+
r.stub(:tmpdir).and_return("/tmp/itamae")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:recipe) do
|
11
|
+
double(:recipe).tap do |r|
|
12
|
+
r.stub(:runner).and_return(runner)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
6
16
|
subject(:resource) do
|
7
17
|
described_class.new(recipe, "name") do
|
8
18
|
source "source.file"
|
@@ -13,7 +23,10 @@ module Itamae
|
|
13
23
|
describe "#create_action" do
|
14
24
|
it "copies a file" do
|
15
25
|
recipe.stub(:path).and_return("/recipe_dir/recipe_file")
|
16
|
-
expect(subject).to receive(:copy_file).with("/recipe_dir/source.file",
|
26
|
+
expect(subject).to receive(:copy_file).with("/recipe_dir/source.file", %r{^/tmp/itamae/[\d\.]+$})
|
27
|
+
expect(subject).to receive(:run_specinfra).with(:check_file_is_file, "/path/to/dst").and_return(true)
|
28
|
+
expect(subject).to receive(:run_command).with(["cp", "/path/to/dst", "/path/to/dst.bak"])
|
29
|
+
expect(subject).to receive(:run_command).with(["mv", %r{/tmp/itamae/[\d\.]+}, "/path/to/dst"])
|
17
30
|
subject.create_action
|
18
31
|
end
|
19
32
|
end
|
@@ -3,6 +3,8 @@ require 'tmpdir'
|
|
3
3
|
|
4
4
|
module Itamae
|
5
5
|
describe Runner do
|
6
|
+
subject { described_class.new(double(:node)) }
|
7
|
+
|
6
8
|
around do |example|
|
7
9
|
Dir.mktmpdir do |dir|
|
8
10
|
Dir.chdir(dir) do
|
@@ -22,7 +24,7 @@ module Itamae
|
|
22
24
|
).and_return(recipe)
|
23
25
|
expect(recipe).to receive(:run)
|
24
26
|
end
|
25
|
-
described_class.run(recipes, :
|
27
|
+
described_class.run(recipes, :local, {})
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
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.beta4
|
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-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.0.0.
|
33
|
+
version: 2.0.0.beta35
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.0.0.
|
40
|
+
version: 2.0.0.beta35
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hashie
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - '='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 2.0.0.
|
131
|
+
version: 2.0.0.beta20
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 2.0.0.
|
138
|
+
version: 2.0.0.beta20
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: pry-byebug
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- bin/itamae
|
169
169
|
- itamae.gemspec
|
170
170
|
- lib/itamae.rb
|
171
|
+
- lib/itamae/backend.rb
|
171
172
|
- lib/itamae/cli.rb
|
172
173
|
- lib/itamae/logger.rb
|
173
174
|
- lib/itamae/node.rb
|
@@ -177,6 +178,7 @@ files:
|
|
177
178
|
- lib/itamae/resource/directory.rb
|
178
179
|
- lib/itamae/resource/execute.rb
|
179
180
|
- lib/itamae/resource/file.rb
|
181
|
+
- lib/itamae/resource/link.rb
|
180
182
|
- lib/itamae/resource/mail_alias.rb
|
181
183
|
- lib/itamae/resource/package.rb
|
182
184
|
- lib/itamae/resource/remote_file.rb
|
@@ -184,7 +186,6 @@ files:
|
|
184
186
|
- lib/itamae/resource/template.rb
|
185
187
|
- lib/itamae/resource_collection.rb
|
186
188
|
- lib/itamae/runner.rb
|
187
|
-
- lib/itamae/specinfra.rb
|
188
189
|
- lib/itamae/version.rb
|
189
190
|
- spec/integration/Vagrantfile
|
190
191
|
- spec/integration/default_spec.rb
|
@@ -197,6 +198,7 @@ files:
|
|
197
198
|
- spec/unit/lib/itamae/node_spec.rb
|
198
199
|
- spec/unit/lib/itamae/recipe_spec.rb
|
199
200
|
- spec/unit/lib/itamae/resource/base_spec.rb
|
201
|
+
- spec/unit/lib/itamae/resource/link_spec.rb
|
200
202
|
- spec/unit/lib/itamae/resource/package_spec.rb
|
201
203
|
- spec/unit/lib/itamae/resource/remote_file_spec.rb
|
202
204
|
- spec/unit/lib/itamae/resource_spec.rb
|
@@ -238,6 +240,7 @@ test_files:
|
|
238
240
|
- spec/unit/lib/itamae/node_spec.rb
|
239
241
|
- spec/unit/lib/itamae/recipe_spec.rb
|
240
242
|
- spec/unit/lib/itamae/resource/base_spec.rb
|
243
|
+
- spec/unit/lib/itamae/resource/link_spec.rb
|
241
244
|
- spec/unit/lib/itamae/resource/package_spec.rb
|
242
245
|
- spec/unit/lib/itamae/resource/remote_file_spec.rb
|
243
246
|
- spec/unit/lib/itamae/resource_spec.rb
|
data/lib/itamae/specinfra.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'specinfra'
|
2
|
-
|
3
|
-
# TODO: move to specinfra
|
4
|
-
|
5
|
-
module Itamae
|
6
|
-
def self.backend=(backend)
|
7
|
-
@backend = backend
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.backend
|
11
|
-
@backend
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.create_local_backend
|
15
|
-
create_backend(:exec)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.create_ssh_backend(options)
|
19
|
-
Specinfra.configuration.request_pty = true
|
20
|
-
|
21
|
-
Specinfra.configuration.host = options.delete(:host)
|
22
|
-
Specinfra.configuration.ssh_options = options
|
23
|
-
create_backend(:ssh)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
def self.create_backend(type)
|
28
|
-
Specinfra.configuration.backend = type
|
29
|
-
Itamae.backend = Specinfra::Runner
|
30
|
-
end
|
31
|
-
|
32
|
-
module SpecinfraHelpers
|
33
|
-
module RunCommand
|
34
|
-
def backend
|
35
|
-
Itamae.backend
|
36
|
-
end
|
37
|
-
|
38
|
-
def run_command(cmd)
|
39
|
-
backend.run_command(cmd)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|