specinfra 2.0.0.beta31 → 2.0.0.beta32
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/lib/specinfra/backend/base.rb +5 -19
- data/lib/specinfra/backend/docker.rb +51 -53
- data/lib/specinfra/backend/dockerfile.rb +14 -16
- data/lib/specinfra/backend/exec.rb +52 -54
- data/lib/specinfra/backend/lxc.rb +30 -32
- data/lib/specinfra/backend/shellscript.rb +17 -19
- data/lib/specinfra/backend/ssh.rb +115 -116
- data/lib/specinfra/backend/winrm.rb +16 -19
- data/lib/specinfra/command/base.rb +1 -1
- data/lib/specinfra/command/base/file.rb +3 -3
- data/lib/specinfra/command/solaris/base/file.rb +2 -2
- data/lib/specinfra/helper/detect_os.rb +3 -0
- data/lib/specinfra/helper/os.rb +5 -28
- data/lib/specinfra/processor.rb +16 -12
- data/lib/specinfra/runner.rb +26 -3
- data/lib/specinfra/version.rb +1 -1
- data/spec/backend/exec/build_command_spec.rb +6 -0
- data/spec/command/base/file_spec.rb +8 -8
- data/spec/command/base_spec.rb +2 -2
- data/spec/command/redhat/interface_spec.rb +1 -1
- data/spec/command/redhat/package_spec.rb +3 -3
- data/spec/helper/os_spec.rb +6 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bdf29071ca5229cf86e2c3652d9e5aff5a95adf
|
4
|
+
data.tar.gz: 3316f09764ff4c1bdf3e77ca77d1e1b50473fbbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d47a9c0b81348438f99b5d9f8074c6442b0d7e35ce86e802b24c7a5350ef93c1994dba0b4d66d71b99c7fd52febdc580de8b9dddc2c0daa23421ec17b67de137
|
7
|
+
data.tar.gz: cf65c9ea30eb98dd69890127ecdfc1ce1649eaa02787db878a95ac6156ca61b9fee07c422602f0cfa2382e735b72f4b2fc628357d42acc90ee010b6d35c2e8e2
|
@@ -1,26 +1,12 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'specinfra/command_result'
|
3
3
|
|
4
|
-
module Specinfra
|
5
|
-
|
6
|
-
|
7
|
-
include Singleton
|
4
|
+
module Specinfra::Backend
|
5
|
+
class Base
|
6
|
+
include Singleton
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def check_zero(cmd, *args)
|
14
|
-
run_command(Specinfra.command.send(cmd, *args)).success?
|
15
|
-
end
|
16
|
-
|
17
|
-
def method_missing(meth, *args, &block)
|
18
|
-
if meth.to_s =~ /^check/
|
19
|
-
check_zero(meth, *args)
|
20
|
-
else
|
21
|
-
run_command(Specinfra.command.send(meth, *args))
|
22
|
-
end
|
23
|
-
end
|
8
|
+
def set_example(e)
|
9
|
+
@example = e
|
24
10
|
end
|
25
11
|
end
|
26
12
|
end
|
@@ -1,69 +1,67 @@
|
|
1
|
-
module Specinfra
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
fail "Docker client library is not available. Try installing `docker-api' gem."
|
9
|
-
end
|
10
|
-
|
11
|
-
@images = []
|
12
|
-
::Docker.url = Specinfra.configuration.docker_url
|
1
|
+
module Specinfra::Backend
|
2
|
+
class Docker < Exec
|
3
|
+
def initialize
|
4
|
+
begin
|
5
|
+
require 'docker' unless defined?(::Docker)
|
6
|
+
rescue LoadError
|
7
|
+
fail "Docker client library is not available. Try installing `docker-api' gem."
|
13
8
|
end
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
docker_run!(cmd)
|
19
|
-
end
|
10
|
+
@images = []
|
11
|
+
::Docker.url = Specinfra.configuration.docker_url
|
12
|
+
end
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
def run_command(cmd, opts={})
|
15
|
+
cmd = build_command(cmd)
|
16
|
+
cmd = add_pre_command(cmd)
|
17
|
+
docker_run!(cmd)
|
18
|
+
end
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
def build_command(cmd)
|
21
|
+
cmd
|
22
|
+
end
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
def add_pre_command(cmd)
|
25
|
+
cmd
|
26
|
+
end
|
32
27
|
|
33
|
-
|
28
|
+
def copy_file(from, to)
|
29
|
+
@images << current_image.insert_local('localPath' => from, 'outputPath' => to)
|
30
|
+
end
|
34
31
|
|
35
|
-
|
36
|
-
@base_image ||= ::Docker::Image.get(Specinfra.configuration.docker_image)
|
37
|
-
end
|
32
|
+
private
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
34
|
+
def base_image
|
35
|
+
@base_image ||= ::Docker::Image.get(Specinfra.configuration.docker_image)
|
36
|
+
end
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
'Cmd' => %W{/bin/sh -c #{cmd}},
|
47
|
-
}.merge(opts)
|
38
|
+
def current_image
|
39
|
+
@images.last || base_image
|
40
|
+
end
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
def docker_run!(cmd, opts={})
|
43
|
+
opts = {
|
44
|
+
'Image' => current_image.id,
|
45
|
+
'Cmd' => %W{/bin/sh -c #{cmd}},
|
46
|
+
}.merge(opts)
|
47
|
+
|
48
|
+
if path = Specinfra::configuration::path
|
49
|
+
(opts['Env'] ||= {})['PATH'] = path
|
50
|
+
end
|
52
51
|
|
53
|
-
|
52
|
+
container = ::Docker::Container.create(opts)
|
53
|
+
begin
|
54
|
+
container.start
|
54
55
|
begin
|
55
|
-
container.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
rescue
|
62
|
-
container.kill
|
63
|
-
end
|
64
|
-
ensure
|
65
|
-
container.delete
|
56
|
+
stdout, stderr = container.attach
|
57
|
+
result = container.wait
|
58
|
+
return CommandResult.new :stdout => stdout.join, :stderr => stderr.join,
|
59
|
+
:exit_status => result['StatusCode']
|
60
|
+
rescue
|
61
|
+
container.kill
|
66
62
|
end
|
63
|
+
ensure
|
64
|
+
container.delete
|
67
65
|
end
|
68
66
|
end
|
69
67
|
end
|
@@ -1,21 +1,19 @@
|
|
1
|
-
module Specinfra
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
1
|
+
module Specinfra::Backend
|
2
|
+
class Dockerfile < Specinfra::Backend::Base
|
3
|
+
def initialize
|
4
|
+
@lines = []
|
5
|
+
ObjectSpace.define_finalizer(self) {
|
6
|
+
File.write("Dockerfile", @lines.join("\n"))
|
7
|
+
}
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def run_command(cmd, opts={})
|
11
|
+
@lines << "RUN #{cmd}"
|
12
|
+
CommandResult.new
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
15
|
+
def from(base)
|
16
|
+
@lines << "FROM #{base}"
|
19
17
|
end
|
20
18
|
end
|
21
19
|
end
|
@@ -2,76 +2,74 @@ require 'singleton'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require 'shellwords'
|
4
4
|
|
5
|
-
module Specinfra
|
6
|
-
|
7
|
-
class Exec < Base
|
5
|
+
module Specinfra::Backend
|
6
|
+
class Exec < Base
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
if @example
|
19
|
-
@example.metadata[:command] = cmd
|
20
|
-
@example.metadata[:stdout] = stdout
|
21
|
-
end
|
8
|
+
def run_command(cmd, opts={})
|
9
|
+
cmd = build_command(cmd)
|
10
|
+
cmd = add_pre_command(cmd)
|
11
|
+
stdout = with_env do
|
12
|
+
`#{build_command(cmd)} 2>&1`
|
13
|
+
end
|
14
|
+
# In ruby 1.9, it is possible to use Open3.capture3, but not in 1.8
|
15
|
+
# stdout, stderr, status = Open3.capture3(cmd)
|
22
16
|
|
23
|
-
|
17
|
+
if @example
|
18
|
+
@example.metadata[:command] = cmd
|
19
|
+
@example.metadata[:stdout] = stdout
|
24
20
|
end
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
RUBYOPT GEM_HOME GEM_PATH GEM_CACHE]
|
22
|
+
CommandResult.new :stdout => stdout, :exit_status => $?.exitstatus
|
23
|
+
end
|
29
24
|
|
30
|
-
|
25
|
+
def with_env
|
26
|
+
keys = %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE
|
27
|
+
RUBYOPT GEM_HOME GEM_PATH GEM_CACHE]
|
31
28
|
|
32
|
-
|
33
|
-
env[:LANG] ||= 'C'
|
29
|
+
keys.each { |key| ENV["_SPECINFRA_#{key}"] = ENV[key] ; ENV.delete(key) }
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
ENV["_SPECINFRA_#{key}"] = ENV[key];
|
38
|
-
ENV[key] = value
|
39
|
-
end
|
31
|
+
env = Specinfra.configuration.env || {}
|
32
|
+
env[:LANG] ||= 'C'
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
key = key.to_s
|
46
|
-
ENV[key] = ENV.delete("_SPECINFRA_#{key}");
|
47
|
-
end
|
34
|
+
env.each do |key, value|
|
35
|
+
key = key.to_s
|
36
|
+
ENV["_SPECINFRA_#{key}"] = ENV[key];
|
37
|
+
ENV[key] = value
|
48
38
|
end
|
49
39
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
yield
|
41
|
+
ensure
|
42
|
+
keys.each { |key| ENV[key] = ENV.delete("_SPECINFRA_#{key}") }
|
43
|
+
env.each do |key, value|
|
44
|
+
key = key.to_s
|
45
|
+
ENV[key] = ENV.delete("_SPECINFRA_#{key}");
|
46
|
+
end
|
47
|
+
end
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
def build_command(cmd)
|
50
|
+
shell = Specinfra.configuration.shell || '/bin/sh'
|
51
|
+
cmd = cmd.shelljoin if cmd.is_a?(Array)
|
52
|
+
cmd = "#{shell.shellescape} -c #{cmd.shellescape}"
|
59
53
|
|
60
|
-
|
54
|
+
path = Specinfra.configuration.path
|
55
|
+
if path
|
56
|
+
cmd = %Q{env PATH="#{path}" #{cmd}}
|
61
57
|
end
|
62
58
|
|
63
|
-
|
64
|
-
|
65
|
-
pre_cmd = build_command(Specinfra.configuration.pre_command)
|
66
|
-
"#{pre_cmd} && #{cmd}"
|
67
|
-
else
|
68
|
-
cmd
|
69
|
-
end
|
70
|
-
end
|
59
|
+
cmd
|
60
|
+
end
|
71
61
|
|
72
|
-
|
73
|
-
|
62
|
+
def add_pre_command(cmd)
|
63
|
+
if Specinfra.configuration.pre_command
|
64
|
+
pre_cmd = build_command(Specinfra.configuration.pre_command)
|
65
|
+
"#{pre_cmd} && #{cmd}"
|
66
|
+
else
|
67
|
+
cmd
|
74
68
|
end
|
75
69
|
end
|
70
|
+
|
71
|
+
def copy_file(from, to)
|
72
|
+
FileUtils.cp(from, to)
|
73
|
+
end
|
76
74
|
end
|
77
75
|
end
|
@@ -1,42 +1,40 @@
|
|
1
|
-
module Specinfra
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
fail "LXC client library is not available. Try installing `lxc-extra' gem"
|
9
|
-
end
|
1
|
+
module Specinfra::Backend
|
2
|
+
class Lxc < Exec
|
3
|
+
def initialize
|
4
|
+
begin
|
5
|
+
require 'lxc/extra' unless defined?(::LXC::Extra)
|
6
|
+
rescue LoadError
|
7
|
+
fail "LXC client library is not available. Try installing `lxc-extra' gem"
|
10
8
|
end
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
if @example
|
20
|
-
@example.metadata[:command] = cmd
|
21
|
-
@example.metadata[:stdout] = out
|
22
|
-
end
|
23
|
-
CommandResult.new :stdout => out, :exit_status => ret.exitstatus
|
11
|
+
def run_command(cmd, opts={})
|
12
|
+
cmd = build_command(cmd)
|
13
|
+
cmd = add_pre_command(cmd)
|
14
|
+
out, ret = ct.execute do
|
15
|
+
out = `#{cmd} 2>&1`
|
16
|
+
[out, $?.dup]
|
24
17
|
end
|
25
|
-
|
26
|
-
cmd
|
18
|
+
if @example
|
19
|
+
@example.metadata[:command] = cmd
|
20
|
+
@example.metadata[:stdout] = out
|
27
21
|
end
|
22
|
+
CommandResult.new :stdout => out, :exit_status => ret.exitstatus
|
23
|
+
end
|
24
|
+
def build_command(cmd)
|
25
|
+
cmd
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def add_pre_command(cmd)
|
29
|
+
cmd
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def copy_file(from, to)
|
33
|
+
FileUtils.cp(from, File.join(ct.config_item('lxc.rootfs'), to))
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
36
|
+
def ct
|
37
|
+
@ct ||= ::LXC::Container.new(Specinfra.configuration.lxc)
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
@@ -1,27 +1,25 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
|
3
|
-
module Specinfra
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
3
|
+
module Specinfra::Backend
|
4
|
+
class ShellScript < Base
|
5
|
+
def initialize
|
6
|
+
@lines = [ "#!/bin/sh", "" ]
|
7
|
+
ObjectSpace.define_finalizer(self, Writer.new("spec.sh", @lines))
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def run_command(cmd, opts={})
|
11
|
+
@lines << cmd
|
12
|
+
CommandResult.new
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
class Writer
|
16
|
+
def initialize(file, lines)
|
17
|
+
@file = file
|
18
|
+
@lines = lines
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
def call(*args)
|
22
|
+
File.write(@file, @lines.join("\n"))
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -1,155 +1,154 @@
|
|
1
1
|
require 'specinfra/backend/exec'
|
2
2
|
require 'net/ssh'
|
3
3
|
require 'net/scp'
|
4
|
-
module Specinfra
|
5
|
-
module Backend
|
6
|
-
class Ssh < Exec
|
7
|
-
def prompt
|
8
|
-
'Password: '
|
9
|
-
end
|
10
4
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
5
|
+
module Specinfra::Backend
|
6
|
+
class Ssh < Exec
|
7
|
+
def prompt
|
8
|
+
'Password: '
|
9
|
+
end
|
17
10
|
|
18
|
-
|
11
|
+
def run_command(cmd, opt={})
|
12
|
+
cmd = build_command(cmd)
|
13
|
+
cmd = add_pre_command(cmd)
|
14
|
+
ret = with_env do
|
15
|
+
ssh_exec!(cmd)
|
16
|
+
end
|
19
17
|
|
20
|
-
|
21
|
-
@example.metadata[:command] = cmd
|
22
|
-
@example.metadata[:stdout] = ret[:stdout]
|
23
|
-
end
|
18
|
+
ret[:stdout].gsub!(/\r\n/, "\n")
|
24
19
|
|
25
|
-
|
20
|
+
if @example
|
21
|
+
@example.metadata[:command] = cmd
|
22
|
+
@example.metadata[:stdout] = ret[:stdout]
|
26
23
|
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
env[:LANG] ||= 'C'
|
25
|
+
CommandResult.new ret
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
|
28
|
+
def with_env
|
29
|
+
env = Specinfra.configuration.env || {}
|
30
|
+
env[:LANG] ||= 'C'
|
34
31
|
|
35
|
-
|
36
|
-
|
37
|
-
ENV["_SPECINFRA_#{key}"] = ENV[key];
|
38
|
-
ENV[key] = value
|
39
|
-
ssh_options[:send_env] << key
|
40
|
-
end
|
32
|
+
ssh_options = Specinfra.configuration.ssh_options || {}
|
33
|
+
ssh_options[:send_env] ||= []
|
41
34
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
35
|
+
env.each do |key, value|
|
36
|
+
key = key.to_s
|
37
|
+
ENV["_SPECINFRA_#{key}"] = ENV[key];
|
38
|
+
ENV[key] = value
|
39
|
+
ssh_options[:send_env] << key
|
48
40
|
end
|
49
41
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
cmd = "#{sudo} -p '#{prompt}' #{cmd}"
|
56
|
-
end
|
57
|
-
cmd
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
env.each do |key, value|
|
45
|
+
key = key.to_s
|
46
|
+
ENV[key] = ENV.delete("_SPECINFRA_#{key}");
|
58
47
|
end
|
48
|
+
end
|
59
49
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
scp.upload!(from, to)
|
50
|
+
def build_command(cmd)
|
51
|
+
cmd = super(cmd)
|
52
|
+
user = Specinfra.configuration.ssh_options[:user]
|
53
|
+
disable_sudo = Specinfra.configuration.disable_sudo
|
54
|
+
if user != 'root' && !disable_sudo
|
55
|
+
cmd = "#{sudo} -p '#{prompt}' #{cmd}"
|
67
56
|
end
|
57
|
+
cmd
|
58
|
+
end
|
68
59
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
Specinfra.configuration.host,
|
73
|
-
Specinfra.configuration.ssh_options[:user],
|
74
|
-
Specinfra.configuration.ssh_options
|
75
|
-
)
|
60
|
+
def copy_file(from, to)
|
61
|
+
if Specinfra.configuration.scp.nil?
|
62
|
+
Specinfra.configuration.scp = create_scp
|
76
63
|
end
|
77
64
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
65
|
+
scp = Specinfra.configuration.scp
|
66
|
+
scp.upload!(from, to)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def create_ssh
|
71
|
+
Net::SSH.start(
|
72
|
+
Specinfra.configuration.host,
|
73
|
+
Specinfra.configuration.ssh_options[:user],
|
74
|
+
Specinfra.configuration.ssh_options
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_scp
|
79
|
+
ssh = Specinfra.configuration.ssh
|
80
|
+
if ssh.nil?
|
81
|
+
ssh = create_ssh
|
84
82
|
end
|
83
|
+
Net::SCP.new(ssh)
|
84
|
+
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
def ssh_exec!(command)
|
87
|
+
stdout_data = ''
|
88
|
+
stderr_data = ''
|
89
|
+
exit_status = nil
|
90
|
+
exit_signal = nil
|
91
|
+
|
92
|
+
if Specinfra.configuration.ssh.nil?
|
93
|
+
Specinfra.configuration.ssh = create_ssh
|
94
|
+
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
96
|
+
ssh = Specinfra.configuration.ssh
|
97
|
+
ssh.open_channel do |channel|
|
98
|
+
if Specinfra.configuration.sudo_password or Specinfra.configuration.request_pty
|
99
|
+
channel.request_pty do |ch, success|
|
100
|
+
abort "Could not obtain pty " if !success
|
102
101
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
102
|
+
end
|
103
|
+
channel.exec("#{command}") do |ch, success|
|
104
|
+
abort "FAILED: couldn't execute command (ssh.channel.exec)" if !success
|
105
|
+
channel.on_data do |ch, data|
|
106
|
+
if data.match /^#{prompt}/
|
107
|
+
channel.send_data "#{Specinfra.configuration.sudo_password}\n"
|
108
|
+
else
|
109
|
+
stdout_data += data
|
111
110
|
end
|
111
|
+
end
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
if data.match /^sudo: no tty present and no askpass program specified/
|
119
|
-
abort "Please set sudo password by using SUDO_PASSWORD or ASK_SUDO_PASSWORD environment variable"
|
120
|
-
else
|
121
|
-
stderr_data += data
|
122
|
-
end
|
113
|
+
channel.on_extended_data do |ch, type, data|
|
114
|
+
if data.match /you must have a tty to run sudo/
|
115
|
+
abort 'Please set "Specinfra.configuration.request_pty = true" or "c.request_pty = true" in your spec_helper.rb or other appropriate file.'
|
123
116
|
end
|
124
117
|
|
125
|
-
|
126
|
-
|
118
|
+
if data.match /^sudo: no tty present and no askpass program specified/
|
119
|
+
abort "Please set sudo password by using SUDO_PASSWORD or ASK_SUDO_PASSWORD environment variable"
|
120
|
+
else
|
121
|
+
stderr_data += data
|
127
122
|
end
|
123
|
+
end
|
128
124
|
|
129
|
-
|
130
|
-
|
131
|
-
end
|
125
|
+
channel.on_request("exit-status") do |ch, data|
|
126
|
+
exit_status = data.read_long
|
132
127
|
end
|
133
|
-
end
|
134
|
-
ssh.loop
|
135
|
-
{ :stdout => stdout_data, :stderr => stderr_data, :exit_status => exit_status, :exit_signal => exit_signal }
|
136
|
-
end
|
137
128
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
else
|
142
|
-
sudo_path = 'sudo'
|
129
|
+
channel.on_request("exit-signal") do |ch, data|
|
130
|
+
exit_signal = data.read_long
|
131
|
+
end
|
143
132
|
end
|
133
|
+
end
|
134
|
+
ssh.loop
|
135
|
+
{ :stdout => stdout_data, :stderr => stderr_data, :exit_status => exit_status, :exit_signal => exit_signal }
|
136
|
+
end
|
144
137
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
138
|
+
def sudo
|
139
|
+
if sudo_path = Specinfra.configuration.sudo_path
|
140
|
+
sudo_path += '/sudo'
|
141
|
+
else
|
142
|
+
sudo_path = 'sudo'
|
143
|
+
end
|
150
144
|
|
151
|
-
|
145
|
+
sudo_options = Specinfra.configuration.sudo_options
|
146
|
+
if sudo_options
|
147
|
+
sudo_options = sudo_options.shelljoin if sudo_options.is_a?(Array)
|
148
|
+
sudo_options = ' ' + sudo_options
|
152
149
|
end
|
150
|
+
|
151
|
+
"#{sudo_path.shellescape}#{sudo_options}"
|
153
152
|
end
|
154
153
|
end
|
155
154
|
end
|
@@ -1,26 +1,23 @@
|
|
1
|
-
module Specinfra
|
2
|
-
|
3
|
-
|
4
|
-
include PowerShell::ScriptHelper
|
1
|
+
module Specinfra::Backend
|
2
|
+
class WinRM < Base
|
3
|
+
include PowerShell::ScriptHelper
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def run_command(cmd, opts={})
|
6
|
+
script = create_script(cmd)
|
7
|
+
winrm = Specinfra.configuration.winrm
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if @example
|
17
|
-
@example.metadata[:command] = script
|
18
|
-
@example.metadata[:stdout] = stdout + stderr
|
19
|
-
end
|
9
|
+
result = winrm.powershell(script)
|
10
|
+
stdout, stderr = [:stdout, :stderr].map do |s|
|
11
|
+
result[:data].select {|item| item.key? s}.map {|item| item[s]}.join
|
12
|
+
end
|
13
|
+
result[:exitcode] = 1 if result[:exitcode] == 0 and !stderr.empty?
|
20
14
|
|
21
|
-
|
22
|
-
|
15
|
+
if @example
|
16
|
+
@example.metadata[:command] = script
|
17
|
+
@example.metadata[:stdout] = stdout + stderr
|
23
18
|
end
|
19
|
+
|
20
|
+
CommandResult.new :stdout => stdout, :stderr => stderr, :exit_status => result[:exitcode]
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -13,7 +13,7 @@ class Specinfra::Command::Base::File < Specinfra::Command::Base
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def check_contains(file, expected_pattern)
|
16
|
-
"#{
|
16
|
+
"#{check_contains_with_regexp(file, expected_pattern)} || #{check_contains_with_fixed_strings(file, expected_pattern)}"
|
17
17
|
end
|
18
18
|
|
19
19
|
def check_is_grouped(file, group)
|
@@ -35,8 +35,8 @@ class Specinfra::Command::Base::File < Specinfra::Command::Base
|
|
35
35
|
from ||= '1'
|
36
36
|
to ||= '$'
|
37
37
|
sed = "sed -n #{escape(from)},#{escape(to)}p #{escape(file)}"
|
38
|
-
checker_with_regexp =
|
39
|
-
checker_with_fixed =
|
38
|
+
checker_with_regexp = check_contains_with_regexp("-", expected_pattern)
|
39
|
+
checker_with_fixed = check_contains_with_fixed_strings("-", expected_pattern)
|
40
40
|
"#{sed} | #{checker_with_regexp} || #{sed} | #{checker_with_fixed}"
|
41
41
|
end
|
42
42
|
|
@@ -4,8 +4,8 @@ class Specinfra::Command::Solaris::Base::File < Specinfra::Command::Base::File
|
|
4
4
|
from ||= '1'
|
5
5
|
to ||= '$'
|
6
6
|
sed = "sed -n #{escape(from)},#{escape(to)}p #{escape(file)}"
|
7
|
-
checker_with_regexp =
|
8
|
-
checker_with_fixed =
|
7
|
+
checker_with_regexp = check_contains_with_regexp("/dev/stdin", expected_pattern)
|
8
|
+
checker_with_fixed = check_contains_with_fixed_strings("/dev/stdin", expected_pattern)
|
9
9
|
"#{sed} | #{checker_with_regexp} || #{sed} | #{checker_with_fixed}"
|
10
10
|
end
|
11
11
|
|
data/lib/specinfra/helper/os.rb
CHANGED
@@ -2,43 +2,20 @@ require 'specinfra/helper/detect_os'
|
|
2
2
|
|
3
3
|
module Specinfra::Helper::Os
|
4
4
|
def os
|
5
|
-
property[:
|
6
|
-
|
7
|
-
|
8
|
-
if property[:os_by_host][host_port]
|
9
|
-
os_by_host = property[:os_by_host][host_port]
|
10
|
-
else
|
11
|
-
# Set command object explicitly to avoid `stack too deep`
|
12
|
-
os_by_host = detect_os
|
13
|
-
property[:os_by_host][host_port] = os_by_host
|
5
|
+
property[:os] = {} if ! property[:os]
|
6
|
+
if ! property[:os].include?(:family)
|
7
|
+
property[:os] = detect_os
|
14
8
|
end
|
15
|
-
|
9
|
+
property[:os]
|
16
10
|
end
|
17
11
|
|
18
12
|
private
|
19
|
-
|
20
|
-
# put this in a module for better reuse
|
21
|
-
def current_host_and_port
|
22
|
-
if Specinfra.configuration.ssh
|
23
|
-
"#{Specinfra.configuration.ssh.host}:#{Specinfra.configuration.ssh.options[:port]}"
|
24
|
-
elsif Specinfra.configuration.ssh_options
|
25
|
-
|
26
|
-
"#{Specinfra.configuration.host}:#{Specinfra.configuration.ssh_options[:port]}"
|
27
|
-
else
|
28
|
-
"#{Specinfra.configuration.host}:0"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def run_command(cmd)
|
33
|
-
Specinfra.backend.run_command(cmd)
|
34
|
-
end
|
35
|
-
|
36
13
|
def detect_os
|
37
14
|
return Specinfra.configuration.os if Specinfra.configuration.os
|
38
15
|
Specinfra::Helper::DetectOs.subclasses.each do |c|
|
39
16
|
res = c.detect
|
40
17
|
if res
|
41
|
-
res[:arch] ||= run_command('uname -m').stdout.strip
|
18
|
+
res[:arch] ||= Specinfra.backend.run_command('uname -m').stdout.strip
|
42
19
|
return res
|
43
20
|
end
|
44
21
|
end
|
data/lib/specinfra/processor.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
module Specinfra
|
2
2
|
class Processor
|
3
|
-
def self.method_missing(meth, *args, &block)
|
4
|
-
Specinfra.backend.send(meth, *args)
|
5
|
-
end
|
6
|
-
|
7
3
|
def self.check_service_is_running(service)
|
8
|
-
|
4
|
+
cmd = Specinfra.command.get(:check_service_is_running, service)
|
5
|
+
ret = Specinfra.backend.run_command(cmd)
|
9
6
|
|
10
7
|
# In Ubuntu, some services are under upstart and "service foo status" returns
|
11
8
|
# exit status 0 even though they are stopped.
|
@@ -14,14 +11,16 @@ module Specinfra
|
|
14
11
|
|
15
12
|
# If the service is not registered, check by ps command
|
16
13
|
if ret.exit_status == 1
|
17
|
-
|
14
|
+
cmd = Specinfra.command.get(:check_process_is_running, service)
|
15
|
+
ret = Specinfra.backend.run_command(cmd)
|
18
16
|
end
|
19
17
|
|
20
18
|
ret.success?
|
21
19
|
end
|
22
20
|
|
23
21
|
def self.check_service_is_monitored_by_monit(process)
|
24
|
-
|
22
|
+
cmd = Specinfra.command.get(:check_service_is_monitored_by_monit, process)
|
23
|
+
ret = Specinfra.backend.run_command(cmd)
|
25
24
|
return false unless ret.stdout != nil && ret.success?
|
26
25
|
|
27
26
|
retlines = ret.stdout.split(/[\r\n]+/).map(&:strip)
|
@@ -32,7 +31,8 @@ module Specinfra
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def self.check_file_is_readable(file, by_whom)
|
35
|
-
|
34
|
+
cmd = Specinfra.command.get(:get_file_mode, file)
|
35
|
+
mode = sprintf('%04s',Specinfra.backend.run_command(cmd).stdout.strip)
|
36
36
|
mode = mode.split('')
|
37
37
|
mode_octal = mode[0].to_i * 512 + mode[1].to_i * 64 + mode[2].to_i * 8 + mode[3].to_i * 1
|
38
38
|
case by_whom
|
@@ -48,7 +48,8 @@ module Specinfra
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def self.check_file_is_writable(file, by_whom)
|
51
|
-
|
51
|
+
cmd = Specinfra.command.get(:get_file_mode, file)
|
52
|
+
mode = sprintf('%04s',Specinfra.backend.run_command(cmd).stdout.strip)
|
52
53
|
mode = mode.split('')
|
53
54
|
mode_octal = mode[0].to_i * 512 + mode[1].to_i * 64 + mode[2].to_i * 8 + mode[3].to_i * 1
|
54
55
|
case by_whom
|
@@ -64,7 +65,8 @@ module Specinfra
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def self.check_file_is_executable(file, by_whom)
|
67
|
-
|
68
|
+
cmd = Specinfra.command.get(:get_file_mode, file)
|
69
|
+
mode = sprintf('%04s',Specinfra.backend.run_command(cmd).stdout.strip)
|
68
70
|
mode = mode.split('')
|
69
71
|
mode_octal = mode[0].to_i * 512 + mode[1].to_i * 64 + mode[2].to_i * 8 + mode[3].to_i * 1
|
70
72
|
case by_whom
|
@@ -80,7 +82,8 @@ module Specinfra
|
|
80
82
|
end
|
81
83
|
|
82
84
|
def self.check_file_is_mounted(path, expected_attr, only_with)
|
83
|
-
|
85
|
+
cmd = Specinfra.command.get(:check_file_is_mounted, path)
|
86
|
+
ret = Specinfra.backend.run_command(cmd)
|
84
87
|
if expected_attr.nil? || ret.failure?
|
85
88
|
return ret.success?
|
86
89
|
end
|
@@ -114,7 +117,8 @@ module Specinfra
|
|
114
117
|
|
115
118
|
def self.check_routing_table_has_entry(expected_attr)
|
116
119
|
return false if ! expected_attr[:destination]
|
117
|
-
|
120
|
+
cmd = Specinfra.command.get(:get_routing_table_entry, expected_attr[:destination])
|
121
|
+
ret = Specinfra.backend.run_command(cmd)
|
118
122
|
return false if ret.failure?
|
119
123
|
|
120
124
|
ret.stdout.gsub!(/\r\n/, "\n")
|
data/lib/specinfra/runner.rb
CHANGED
@@ -1,11 +1,34 @@
|
|
1
1
|
module Specinfra
|
2
2
|
class Runner
|
3
|
-
def self.method_missing(meth, *args
|
3
|
+
def self.method_missing(meth, *args)
|
4
4
|
if os.include?(:family) && os[:family] == 'windows'
|
5
|
-
|
5
|
+
run(meth, *args)
|
6
6
|
else
|
7
|
-
Specinfra::Processor
|
7
|
+
processor = Specinfra::Processor
|
8
|
+
backend = Specinfra.backend
|
9
|
+
if processor.respond_to?(meth)
|
10
|
+
processor.send(meth, *args)
|
11
|
+
elsif backend.respond_to?(meth)
|
12
|
+
backend.send(meth, *args)
|
13
|
+
else
|
14
|
+
run(meth, *args)
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
18
|
+
|
19
|
+
def self.run_command(cmd)
|
20
|
+
Specinfra.backend.run_command(cmd)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def self.run(meth, *args)
|
25
|
+
cmd = Specinfra.command.get(meth, *args)
|
26
|
+
if meth.to_s =~ /^check/
|
27
|
+
Specinfra.backend.run_command(cmd).success?
|
28
|
+
else
|
29
|
+
Specinfra.backend.run_command(cmd)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
10
33
|
end
|
11
34
|
end
|
data/lib/specinfra/version.rb
CHANGED
@@ -99,6 +99,9 @@ describe 'os' do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
context 'test ubuntu with /etc/lsb-release' do
|
102
|
+
before do
|
103
|
+
property[:os] = nil
|
104
|
+
end
|
102
105
|
subject { os }
|
103
106
|
it do
|
104
107
|
expect(Specinfra.backend).to receive(:run_command).at_least(1).times do |args|
|
@@ -124,6 +127,9 @@ EOF
|
|
124
127
|
end
|
125
128
|
|
126
129
|
context 'test debian (no lsb_release or lsb-release)' do
|
130
|
+
before do
|
131
|
+
property[:os] = nil
|
132
|
+
end
|
127
133
|
subject { os }
|
128
134
|
it do
|
129
135
|
expect(Specinfra.backend).to receive(:run_command).at_least(1).times do |args|
|
@@ -7,35 +7,35 @@ describe 'File related commands' do
|
|
7
7
|
property[:os_by_host] = nil
|
8
8
|
end
|
9
9
|
|
10
|
-
context Specinfra.command.check_file_is_directory
|
10
|
+
context Specinfra.command.get(:check_file_is_directory, '/tmp') do
|
11
11
|
it { should eq 'test -d /tmp' }
|
12
12
|
end
|
13
13
|
|
14
|
-
context Specinfra.command.change_file_mode
|
14
|
+
context Specinfra.command.get(:change_file_mode, '/tmp', '0644') do
|
15
15
|
it { should eq 'chmod 0644 /tmp' }
|
16
16
|
end
|
17
17
|
|
18
|
-
context Specinfra.command.change_file_owner
|
18
|
+
context Specinfra.command.get(:change_file_owner, '/tmp', 'root') do
|
19
19
|
it { should eq 'chown root /tmp' }
|
20
20
|
end
|
21
21
|
|
22
|
-
context Specinfra.command.change_file_owner
|
22
|
+
context Specinfra.command.get(:change_file_owner, '/tmp', 'root', 'root') do
|
23
23
|
it { should eq 'chown root:root /tmp' }
|
24
24
|
end
|
25
25
|
|
26
|
-
context Specinfra.command.change_file_group
|
26
|
+
context Specinfra.command.get(:change_file_group, '/tmp', 'root') do
|
27
27
|
it { should eq 'chgrp root /tmp' }
|
28
28
|
end
|
29
29
|
|
30
|
-
context Specinfra.command.create_file_as_directory
|
30
|
+
context Specinfra.command.get(:create_file_as_directory, '/tmp') do
|
31
31
|
it { should eq 'mkdir -p /tmp' }
|
32
32
|
end
|
33
33
|
|
34
|
-
context Specinfra.command.get_file_owner_user
|
34
|
+
context Specinfra.command.get(:get_file_owner_user, '/tmp') do
|
35
35
|
it { should eq 'stat -c %U /tmp' }
|
36
36
|
end
|
37
37
|
|
38
|
-
context Specinfra.command.get_file_owner_group
|
38
|
+
context Specinfra.command.get(:get_file_owner_group, '/tmp') do
|
39
39
|
it { should eq 'stat -c %G /tmp' }
|
40
40
|
end
|
41
41
|
end
|
data/spec/command/base_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
property[:
|
3
|
+
property[:os] = nil
|
4
4
|
set :os, { :family => 'redhat' }
|
5
5
|
|
6
|
-
describe Specinfra.command.check_package_is_installed
|
6
|
+
describe Specinfra.command.get(:check_package_is_installed, 'httpd') do
|
7
7
|
after do
|
8
|
-
property[:
|
8
|
+
property[:os] = nil
|
9
9
|
end
|
10
10
|
|
11
11
|
it { should eq 'rpm -q httpd' }
|
data/spec/helper/os_spec.rb
CHANGED
@@ -6,44 +6,44 @@ end
|
|
6
6
|
|
7
7
|
describe 'no ssh connection without cache' do
|
8
8
|
before do
|
9
|
+
property[:os] = nil
|
9
10
|
set_stub_chain(:ssh, nil)
|
10
11
|
set_stub_chain(:ssh_options, nil)
|
11
12
|
set_stub_chain(:host, 'localhost')
|
12
13
|
set_stub_chain(:os, :family => 'redhat')
|
13
14
|
end
|
14
15
|
|
15
|
-
it { expect(property[:os_by_host]).to eq nil }
|
16
16
|
it { expect(os[:family]).to eq 'redhat' }
|
17
17
|
end
|
18
18
|
|
19
19
|
describe 'no ssh connection with cache' do
|
20
|
-
it { expect(property[:
|
20
|
+
it { expect(property[:os]).to eq(:family => 'redhat') }
|
21
21
|
end
|
22
22
|
|
23
23
|
describe 'ssh_options without cache' do
|
24
24
|
before do
|
25
|
+
property[:os] = nil
|
25
26
|
set_stub_chain(:ssh, nil)
|
26
27
|
set_stub_chain(:ssh_options, :port => 22)
|
27
28
|
set_stub_chain(:host, 'localhost')
|
28
29
|
set_stub_chain(:os, :family => 'ubuntu')
|
29
30
|
end
|
30
31
|
|
31
|
-
it { expect(property[:os_by_host]['localhost:22']).to eq nil }
|
32
32
|
it { expect(os[:family]).to eq 'ubuntu' }
|
33
33
|
end
|
34
34
|
|
35
35
|
describe 'ssh_options with cache' do
|
36
|
-
it { expect(property[:
|
36
|
+
it { expect(property[:os]).to eq(:family => 'ubuntu') }
|
37
37
|
end
|
38
38
|
|
39
39
|
describe 'ssh_connection without cache' do
|
40
40
|
before do
|
41
|
+
property[:os] = nil
|
41
42
|
set_stub_chain([:ssh, :host], 'localhost')
|
42
43
|
set_stub_chain([:ssh, :options], :port => 2222)
|
43
44
|
set_stub_chain(:os, :family => 'nixos')
|
44
45
|
end
|
45
46
|
|
46
|
-
it { expect(property[:os_by_host]['localhost:2222']).to eq nil }
|
47
47
|
it { expect(os[:family]).to eq 'nixos' }
|
48
48
|
end
|
49
49
|
|
@@ -54,5 +54,5 @@ describe 'ssh_connection wit cache' do
|
|
54
54
|
set_stub_chain(:os, :family => 'nixos')
|
55
55
|
end
|
56
56
|
|
57
|
-
it { expect(property[:
|
57
|
+
it { expect(property[:os]).to eq(:family => 'nixos') }
|
58
58
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: specinfra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.beta32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gosuke Miyashita
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-ssh
|