train 0.28.0 → 0.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -2
- data/lib/train/extras.rb +0 -5
- data/lib/train/extras/os_common.rb +1 -1
- data/lib/train/extras/os_detect_unix.rb +6 -0
- data/lib/train/{extras/file_common.rb → file.rb} +65 -92
- data/lib/train/file/local.rb +70 -0
- data/lib/train/file/local/unix.rb +77 -0
- data/lib/train/file/local/windows.rb +63 -0
- data/lib/train/file/remote.rb +28 -0
- data/lib/train/file/remote/aix.rb +21 -0
- data/lib/train/file/remote/linux.rb +19 -0
- data/lib/train/file/remote/qnx.rb +41 -0
- data/lib/train/file/remote/unix.rb +110 -0
- data/lib/train/file/remote/windows.rb +94 -0
- data/lib/train/plugins/base_connection.rb +2 -1
- data/lib/train/transports/docker.rb +8 -1
- data/lib/train/transports/local.rb +6 -2
- data/lib/train/transports/mock.rb +7 -6
- data/lib/train/transports/ssh.rb +1 -2
- data/lib/train/transports/ssh_connection.rb +24 -4
- data/lib/train/transports/winrm_connection.rb +11 -5
- data/lib/train/version.rb +1 -1
- data/test/integration/tests/path_block_device_test.rb +2 -2
- data/test/integration/tests/path_character_device_test.rb +2 -2
- data/test/integration/tests/path_file_test.rb +2 -2
- data/test/integration/tests/path_folder_test.rb +5 -5
- data/test/integration/tests/path_missing_test.rb +0 -1
- data/test/integration/tests/path_pipe_test.rb +2 -3
- data/test/integration/tests/path_symlink_test.rb +2 -2
- data/test/unit/extras/os_detect_linux_test.rb +3 -3
- data/test/unit/extras/os_detect_windows_test.rb +1 -1
- data/test/unit/file/local/unix_test.rb +112 -0
- data/test/unit/file/local/windows_test.rb +41 -0
- data/test/unit/file/local_test.rb +110 -0
- data/test/unit/{extras/linux_file_test.rb → file/remote/linux_test.rb} +7 -7
- data/test/unit/file/remote/unix_test.rb +44 -0
- data/test/unit/file/remote_test.rb +62 -0
- data/test/unit/file_test.rb +156 -0
- data/test/unit/plugins/transport_test.rb +1 -1
- data/test/unit/transports/mock_test.rb +3 -3
- data/test/windows/local_test.rb +106 -0
- data/test/windows/winrm_test.rb +125 -0
- metadata +26 -16
- data/lib/train/extras/file_aix.rb +0 -20
- data/lib/train/extras/file_linux.rb +0 -16
- data/lib/train/extras/file_unix.rb +0 -79
- data/lib/train/extras/file_windows.rb +0 -100
- data/lib/train/transports/local_file.rb +0 -98
- data/test/unit/extras/file_common_test.rb +0 -180
- data/test/unit/extras/windows_file_test.rb +0 -44
- data/test/unit/transports/local_file_test.rb +0 -202
@@ -51,7 +51,7 @@ class Train::Transports::WinRM
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def file(path)
|
54
|
-
@files[path] ||=
|
54
|
+
@files[path] ||= Train::File::Remote::Windows.new(self, path)
|
55
55
|
end
|
56
56
|
|
57
57
|
def run_command(command)
|
@@ -84,7 +84,13 @@ class Train::Transports::WinRM
|
|
84
84
|
|
85
85
|
# (see Base::Connection#upload)
|
86
86
|
def upload(locals, remote)
|
87
|
-
|
87
|
+
file_manager.upload(locals, remote)
|
88
|
+
end
|
89
|
+
|
90
|
+
def download(remotes, local)
|
91
|
+
Array(remotes).each do |remote|
|
92
|
+
file_manager.download(remote, local)
|
93
|
+
end
|
88
94
|
end
|
89
95
|
|
90
96
|
# (see Base::Connection#wait_until_ready)
|
@@ -124,10 +130,10 @@ class Train::Transports::WinRM
|
|
124
130
|
content
|
125
131
|
end
|
126
132
|
|
127
|
-
# @return [Winrm::
|
133
|
+
# @return [Winrm::FileManager] a file transporter
|
128
134
|
# @api private
|
129
|
-
def
|
130
|
-
@
|
135
|
+
def file_manager
|
136
|
+
@file_manager ||= WinRM::FS::FileManager.new(session)
|
131
137
|
end
|
132
138
|
|
133
139
|
# Builds a `LoginCommand` for use by Linux-based platforms.
|
data/lib/train/version.rb
CHANGED
@@ -64,11 +64,11 @@ describe 'file interface' do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'has no product_version' do
|
67
|
-
file.product_version.
|
67
|
+
file.product_version.must_be_nil
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'has no file_version' do
|
71
|
-
file.file_version.
|
71
|
+
file.file_version.must_be_nil
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -64,11 +64,11 @@ describe 'file interface' do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'has no product_version' do
|
67
|
-
file.product_version.
|
67
|
+
file.product_version.must_be_nil
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'has no file_version' do
|
71
|
-
file.file_version.
|
71
|
+
file.file_version.must_be_nil
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -69,11 +69,11 @@ describe 'file interface' do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'has no product_version' do
|
72
|
-
file.product_version.
|
72
|
+
file.product_version.must_be_nil
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'has no file_version' do
|
76
|
-
file.file_version.
|
76
|
+
file.file_version.must_be_nil
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'provides a json representation' do
|
@@ -34,15 +34,15 @@ describe 'file interface' do
|
|
34
34
|
|
35
35
|
else
|
36
36
|
it 'has no content' do
|
37
|
-
file.content.
|
37
|
+
file.content.must_be_nil
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'has an md5sum' do
|
41
|
-
file.md5sum.
|
41
|
+
file.md5sum.must_be_nil
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'has an sha256sum' do
|
45
|
-
file.sha256sum.
|
45
|
+
file.sha256sum.must_be_nil
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -80,11 +80,11 @@ describe 'file interface' do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'has no product_version' do
|
83
|
-
file.product_version.
|
83
|
+
file.product_version.must_be_nil
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'has no file_version' do
|
87
|
-
file.file_version.
|
87
|
+
file.file_version.must_be_nil
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -66,13 +66,12 @@ describe 'file interface' do
|
|
66
66
|
file.selinux_label.must_equal(res)
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
69
|
it 'has no product_version' do
|
71
|
-
file.product_version.
|
70
|
+
file.product_version.must_be_nil
|
72
71
|
end
|
73
72
|
|
74
73
|
it 'has no file_version' do
|
75
|
-
file.file_version.
|
74
|
+
file.file_version.must_be_nil
|
76
75
|
end
|
77
76
|
end
|
78
77
|
end
|
@@ -85,11 +85,11 @@ describe 'file interface' do
|
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'has no product_version' do
|
88
|
-
file.product_version.
|
88
|
+
file.product_version.must_be_nil
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'has no file_version' do
|
92
|
-
file.file_version.
|
92
|
+
file.file_version.must_be_nil
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -125,8 +125,8 @@ describe 'os_detect_linux' do
|
|
125
125
|
detector.stubs(:fetch_os_release).returns({ 'ID_LIKE' => 'something_else' })
|
126
126
|
|
127
127
|
detector.detect_linux_via_config.must_equal(false)
|
128
|
-
detector.platform[:family].
|
129
|
-
detector.platform[:release].
|
128
|
+
detector.platform[:family].must_be_nil
|
129
|
+
detector.platform[:release].must_be_nil
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -154,7 +154,7 @@ describe 'os_detect_linux' do
|
|
154
154
|
describe 'when no os-release data is available' do
|
155
155
|
it 'returns nil' do
|
156
156
|
detector.expects(:get_config).with('/etc/os-release').returns(nil)
|
157
|
-
detector.fetch_os_release.
|
157
|
+
detector.fetch_os_release.must_be_nil
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
@@ -97,7 +97,7 @@ describe 'os_detect_windows' do
|
|
97
97
|
detector.detect_windows
|
98
98
|
detector.platform[:family].must_equal('windows')
|
99
99
|
detector.platform[:name].must_equal('Windows 4.10.1998')
|
100
|
-
detector.platform[:arch].
|
100
|
+
detector.platform[:arch].must_be_nil
|
101
101
|
detector.platform[:release].must_equal('4.10.1998')
|
102
102
|
end
|
103
103
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'train/file/local/unix'
|
3
|
+
require 'train/transports/mock'
|
4
|
+
require 'train/transports/local'
|
5
|
+
|
6
|
+
describe Train::File::Local::Unix do
|
7
|
+
let(:cls) { Train::File::Local::Unix }
|
8
|
+
|
9
|
+
let(:backend) {
|
10
|
+
backend = Train::Transports::Mock.new.connection
|
11
|
+
backend.mock_os({ family: 'linux' })
|
12
|
+
backend
|
13
|
+
}
|
14
|
+
|
15
|
+
it 'checks a mounted path' do
|
16
|
+
backend.mock_command("mount | grep -- ' on /mount/path '", rand.to_s)
|
17
|
+
cls.new(backend, '/mount/path').mounted?.must_equal true
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'file metadata' do
|
21
|
+
let(:transport) { Train::Transports::Local.new }
|
22
|
+
let(:connection) { transport.connection }
|
23
|
+
|
24
|
+
let(:stat) { Struct.new(:mode, :size, :mtime, :uid, :gid) }
|
25
|
+
let(:uid) { rand }
|
26
|
+
let(:gid) { rand }
|
27
|
+
let(:statres) { stat.new(00140755, rand, (rand*100).to_i, uid, gid) }
|
28
|
+
|
29
|
+
def meta_stub(method, param, &block)
|
30
|
+
pwres = Struct.new(:name)
|
31
|
+
Etc.stub :getpwuid, pwres.new('owner') do
|
32
|
+
Etc.stub :getgrgid, pwres.new('group') do
|
33
|
+
File.stub method, param do; yield; end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'recognizes type' do
|
39
|
+
meta_stub :stat, statres do
|
40
|
+
connection.file(rand.to_s).stat[:type].must_equal :socket
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'recognizes mode' do
|
45
|
+
meta_stub :stat, statres do
|
46
|
+
connection.file(rand.to_s).stat[:mode].must_equal 00755
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'recognizes mtime' do
|
51
|
+
meta_stub :stat, statres do
|
52
|
+
connection.file(rand.to_s).stat[:mtime].must_equal statres.mtime
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'recognizes size' do
|
57
|
+
meta_stub :stat, statres do
|
58
|
+
connection.file(rand.to_s).stat[:size].must_equal statres.size
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'recognizes uid' do
|
63
|
+
meta_stub :stat, statres do
|
64
|
+
connection.file(rand.to_s).stat[:uid].must_equal uid
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'recognizes gid' do
|
69
|
+
meta_stub :stat, statres do
|
70
|
+
connection.file(rand.to_s).stat[:gid].must_equal gid
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'recognizes owner' do
|
75
|
+
meta_stub :stat, statres do
|
76
|
+
connection.file(rand.to_s).owner.must_equal 'owner'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'recognizes group' do
|
81
|
+
meta_stub :stat, statres do
|
82
|
+
connection.file(rand.to_s).group.must_equal 'group'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'grouped_into' do
|
87
|
+
meta_stub :stat, statres do
|
88
|
+
connection.file(rand.to_s).grouped_into?('group').must_equal true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'recognizes selinux label' do
|
93
|
+
meta_stub :stat, statres do
|
94
|
+
label = rand.to_s
|
95
|
+
res = Train::Extras::CommandResult.new(label, nil, 0)
|
96
|
+
connection.stub :run_command, res do
|
97
|
+
connection.file(rand.to_s).selinux_label.must_equal label
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'recognizes source selinux label' do
|
103
|
+
meta_stub :lstat, statres do
|
104
|
+
label = rand.to_s
|
105
|
+
res = Train::Extras::CommandResult.new(label, nil, 0)
|
106
|
+
connection.stub :run_command, res do
|
107
|
+
connection.file(rand.to_s).source.selinux_label.must_equal label
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
require 'train/transports/mock'
|
5
|
+
require 'train/file/local/windows'
|
6
|
+
|
7
|
+
describe 'file common' do
|
8
|
+
let(:cls) { Train::File::Local::Windows }
|
9
|
+
let(:backend) {
|
10
|
+
backend = Train::Transports::Mock.new.connection
|
11
|
+
backend.mock_os({ family: 'windows' })
|
12
|
+
backend
|
13
|
+
}
|
14
|
+
|
15
|
+
it 'check escaping of invalid chars in path' do
|
16
|
+
wf = cls.new(nil, nil)
|
17
|
+
wf.sanitize_filename('c:/test') .must_equal 'c:/test'
|
18
|
+
wf.sanitize_filename('c:/test directory') .must_equal 'c:/test directory'
|
19
|
+
%w{ < > " * ?}.each do |char|
|
20
|
+
wf.sanitize_filename("c:/test#{char}directory") .must_equal 'c:/testdirectory'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns file version' do
|
25
|
+
out = rand.to_s
|
26
|
+
backend.mock_command('[System.Diagnostics.FileVersionInfo]::GetVersionInfo("path").FileVersion', out)
|
27
|
+
cls.new(backend, 'path').file_version.must_equal out
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns product version' do
|
31
|
+
out = rand.to_s
|
32
|
+
backend.mock_command('[System.Diagnostics.FileVersionInfo]::GetVersionInfo("path").FileVersion', out)
|
33
|
+
cls.new(backend, 'path').file_version.must_equal out
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns owner of file' do
|
37
|
+
out = rand.to_s
|
38
|
+
backend.mock_command('Get-Acl "path" | select -expand Owner', out)
|
39
|
+
cls.new(backend, 'path').owner.must_equal out
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'train/transports/local'
|
3
|
+
|
4
|
+
describe Train::File::Local do
|
5
|
+
let(:transport) { Train::Transports::Local.new }
|
6
|
+
let(:connection) { transport.connection }
|
7
|
+
|
8
|
+
it 'gets file contents' do
|
9
|
+
res = rand.to_s
|
10
|
+
File.stub :read, res do
|
11
|
+
connection.file(rand.to_s).content.must_equal(res)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
{
|
16
|
+
exist?: :exist?,
|
17
|
+
file?: :file?,
|
18
|
+
socket?: :socket?,
|
19
|
+
directory?: :directory?,
|
20
|
+
symlink?: :symlink?,
|
21
|
+
pipe?: :pipe?,
|
22
|
+
character_device?: :chardev?,
|
23
|
+
block_device?: :blockdev?,
|
24
|
+
}.each do |method, file_method|
|
25
|
+
it "checks if file is a #{method}" do
|
26
|
+
File.stub file_method.to_sym, true do
|
27
|
+
connection.file(rand.to_s).method(method.to_sym).call.must_equal(true)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#type' do
|
33
|
+
it 'returns the type block_device if it is block device' do
|
34
|
+
File.stub :ftype, "blockSpecial" do
|
35
|
+
connection.file(rand.to_s).type.must_equal :block_device
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns the type character_device if it is character device' do
|
40
|
+
File.stub :ftype, "characterSpecial" do
|
41
|
+
connection.file(rand.to_s).type.must_equal :character_device
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns the type symlink if it is symlink' do
|
46
|
+
File.stub :ftype, "link" do
|
47
|
+
connection.file(rand.to_s).type.must_equal :symlink
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns the type file if it is file' do
|
52
|
+
File.stub :ftype, "file" do
|
53
|
+
connection.file(rand.to_s).type.must_equal :file
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns the type directory if it is block directory' do
|
58
|
+
File.stub :ftype, "directory" do
|
59
|
+
connection.file(rand.to_s).type.must_equal :directory
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns the type pipe if it is pipe' do
|
64
|
+
File.stub :ftype, "fifo" do
|
65
|
+
connection.file(rand.to_s).type.must_equal :pipe
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns the type socket if it is socket' do
|
70
|
+
File.stub :ftype, "socket" do
|
71
|
+
connection.file(rand.to_s).type.must_equal :socket
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns the unknown if not known' do
|
76
|
+
File.stub :ftype, "unknown" do
|
77
|
+
connection.file(rand.to_s).type.must_equal :unknown
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#path' do
|
83
|
+
it 'returns the path if it is not a symlink' do
|
84
|
+
File.stub :symlink?, false do
|
85
|
+
filename = rand.to_s
|
86
|
+
connection.file(filename).path.must_equal filename
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns the link_path if it is a symlink' do
|
91
|
+
File.stub :symlink?, true do
|
92
|
+
file_obj = connection.file(rand.to_s)
|
93
|
+
file_obj.stub :link_path, '/path/to/resolved_link' do
|
94
|
+
file_obj.path.must_equal '/path/to/resolved_link'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#link_path' do
|
101
|
+
it 'returns file\'s link path' do
|
102
|
+
out = rand.to_s
|
103
|
+
File.stub :realpath, out do
|
104
|
+
File.stub :symlink?, true do
|
105
|
+
connection.file(rand.to_s).link_path.must_equal out
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|