train 0.12.1
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 +7 -0
- data/.rubocop.yml +71 -0
- data/CHANGELOG.md +308 -0
- data/Gemfile +30 -0
- data/LICENSE +201 -0
- data/README.md +156 -0
- data/Rakefile +148 -0
- data/lib/train.rb +117 -0
- data/lib/train/errors.rb +23 -0
- data/lib/train/extras.rb +17 -0
- data/lib/train/extras/command_wrapper.rb +148 -0
- data/lib/train/extras/file_aix.rb +20 -0
- data/lib/train/extras/file_common.rb +161 -0
- data/lib/train/extras/file_linux.rb +16 -0
- data/lib/train/extras/file_unix.rb +79 -0
- data/lib/train/extras/file_windows.rb +91 -0
- data/lib/train/extras/linux_lsb.rb +60 -0
- data/lib/train/extras/os_common.rb +136 -0
- data/lib/train/extras/os_detect_darwin.rb +32 -0
- data/lib/train/extras/os_detect_linux.rb +148 -0
- data/lib/train/extras/os_detect_unix.rb +99 -0
- data/lib/train/extras/os_detect_windows.rb +57 -0
- data/lib/train/extras/stat.rb +133 -0
- data/lib/train/options.rb +80 -0
- data/lib/train/plugins.rb +40 -0
- data/lib/train/plugins/base_connection.rb +86 -0
- data/lib/train/plugins/transport.rb +49 -0
- data/lib/train/transports/docker.rb +103 -0
- data/lib/train/transports/local.rb +52 -0
- data/lib/train/transports/local_file.rb +90 -0
- data/lib/train/transports/local_os.rb +51 -0
- data/lib/train/transports/mock.rb +147 -0
- data/lib/train/transports/ssh.rb +163 -0
- data/lib/train/transports/ssh_connection.rb +225 -0
- data/lib/train/transports/winrm.rb +184 -0
- data/lib/train/transports/winrm_connection.rb +194 -0
- data/lib/train/version.rb +7 -0
- data/test/integration/.kitchen.yml +43 -0
- data/test/integration/Berksfile +3 -0
- data/test/integration/bootstrap.sh +17 -0
- data/test/integration/chefignore +1 -0
- data/test/integration/cookbooks/test/metadata.rb +1 -0
- data/test/integration/cookbooks/test/recipes/default.rb +100 -0
- data/test/integration/cookbooks/test/recipes/prep_files.rb +47 -0
- data/test/integration/docker_run.rb +153 -0
- data/test/integration/docker_test.rb +24 -0
- data/test/integration/docker_test_container.rb +24 -0
- data/test/integration/helper.rb +61 -0
- data/test/integration/sudo/customcommand.rb +15 -0
- data/test/integration/sudo/nopasswd.rb +16 -0
- data/test/integration/sudo/passwd.rb +21 -0
- data/test/integration/sudo/reqtty.rb +17 -0
- data/test/integration/sudo/run_as.rb +12 -0
- data/test/integration/test-travis-1.yaml +13 -0
- data/test/integration/test-travis-2.yaml +13 -0
- data/test/integration/test_local.rb +19 -0
- data/test/integration/test_ssh.rb +39 -0
- data/test/integration/tests/path_block_device_test.rb +74 -0
- data/test/integration/tests/path_character_device_test.rb +74 -0
- data/test/integration/tests/path_file_test.rb +79 -0
- data/test/integration/tests/path_folder_test.rb +90 -0
- data/test/integration/tests/path_missing_test.rb +77 -0
- data/test/integration/tests/path_pipe_test.rb +78 -0
- data/test/integration/tests/path_symlink_test.rb +95 -0
- data/test/integration/tests/run_command_test.rb +28 -0
- data/test/unit/extras/command_wrapper_test.rb +78 -0
- data/test/unit/extras/file_common_test.rb +180 -0
- data/test/unit/extras/linux_file_test.rb +167 -0
- data/test/unit/extras/os_common_test.rb +269 -0
- data/test/unit/extras/os_detect_linux_test.rb +189 -0
- data/test/unit/extras/os_detect_windows_test.rb +99 -0
- data/test/unit/extras/stat_test.rb +148 -0
- data/test/unit/extras/windows_file_test.rb +44 -0
- data/test/unit/helper.rb +7 -0
- data/test/unit/plugins/connection_test.rb +44 -0
- data/test/unit/plugins/transport_test.rb +111 -0
- data/test/unit/plugins_test.rb +22 -0
- data/test/unit/train_test.rb +156 -0
- data/test/unit/transports/local_file_test.rb +184 -0
- data/test/unit/transports/local_test.rb +87 -0
- data/test/unit/transports/mock_test.rb +87 -0
- data/test/unit/transports/ssh_test.rb +109 -0
- data/test/unit/version_test.rb +8 -0
- data/test/windows/local_test.rb +46 -0
- data/test/windows/winrm_test.rb +52 -0
- data/train.gemspec +38 -0
- metadata +295 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Jeremy Miller
|
3
|
+
|
4
|
+
require_relative 'run_as'
|
5
|
+
|
6
|
+
describe 'run custom sudo command' do
|
7
|
+
it 'is running as non-root without sudo' do
|
8
|
+
run_as('whoami').stdout.wont_match(/root/i)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is running nopasswd custom sudo command' do
|
12
|
+
run_as('whoami', { sudo: true, sudo_command: 'allyourbase' })
|
13
|
+
.stdout.must_match(/root/i)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
require_relative 'run_as'
|
6
|
+
|
7
|
+
describe 'run_command' do
|
8
|
+
it 'is running as non-root without sudo' do
|
9
|
+
run_as('whoami').stdout.wont_match /root/i
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is running nopasswd sudo' do
|
13
|
+
run_as('whoami', { sudo: true })
|
14
|
+
.stdout.must_match /root/i
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
require_relative 'run_as'
|
6
|
+
|
7
|
+
describe 'run_command' do
|
8
|
+
it 'is running as non-root without sudo' do
|
9
|
+
run_as('whoami').stdout.wont_match /root/i
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is not running sudo without password' do
|
13
|
+
err = ->{Train.create('local', { sudo: true }).connection}.must_raise Train::UserError
|
14
|
+
err.message.must_match /Sudo requires a password/
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is running passwd sudo' do
|
18
|
+
run_as('whoami', { sudo: true, sudo_password: 'password' })
|
19
|
+
.stdout.must_match /root/i
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
# author: Stephan Renatus
|
5
|
+
|
6
|
+
require_relative 'run_as'
|
7
|
+
|
8
|
+
describe 'run_command' do
|
9
|
+
it 'is running as non-root without sudo' do
|
10
|
+
run_as('whoami').stdout.wont_match /root/i
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is throwing an error trying to use sudo' do
|
14
|
+
err = ->{ run_as('whoami', { sudo: true }) }.must_raise Train::UserError
|
15
|
+
err.message.must_match /Sudo failed: Sudo requires a TTY. Please see the README/i
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
|
4
|
+
require_relative 'helper'
|
5
|
+
require 'train'
|
6
|
+
|
7
|
+
backends = {}
|
8
|
+
|
9
|
+
backends[:local] = proc { |*opts|
|
10
|
+
Train.create('local', {}).connection(opts[0])
|
11
|
+
}
|
12
|
+
|
13
|
+
tests = ARGV
|
14
|
+
|
15
|
+
backends.each do |type, get_backend|
|
16
|
+
tests.each do |test|
|
17
|
+
instance_eval(File.read(test), test, 1)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
|
4
|
+
require_relative 'helper'
|
5
|
+
require 'train'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
backends = {}
|
9
|
+
backend_conf = {
|
10
|
+
'target' => ENV['target'] || 'vagrant@localhost',
|
11
|
+
'key_files' => ENV['key_files'] || '/root/.ssh/id_rsa',
|
12
|
+
'logger' => Logger.new(STDOUT),
|
13
|
+
}
|
14
|
+
|
15
|
+
backend_conf['target'] = 'ssh://' + backend_conf['target']
|
16
|
+
backend_conf['logger'].level = \
|
17
|
+
if ENV.key?('debug')
|
18
|
+
case ENV['debug'].to_s
|
19
|
+
when /^false$/i, /^0$/i
|
20
|
+
Logger::INFO
|
21
|
+
else
|
22
|
+
Logger::DEBUG
|
23
|
+
end
|
24
|
+
else
|
25
|
+
Logger::INFO
|
26
|
+
end
|
27
|
+
|
28
|
+
backends[:ssh] = proc { |*args|
|
29
|
+
conf = Train.target_config(backend_conf)
|
30
|
+
Train.create('ssh', conf).connection(args[0])
|
31
|
+
}
|
32
|
+
|
33
|
+
tests = ARGV
|
34
|
+
|
35
|
+
backends.each do |type, get_backend|
|
36
|
+
tests.each do |test|
|
37
|
+
instance_eval(File.read(test), test, 1)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe 'file interface' do
|
4
|
+
let(:backend) { get_backend.call }
|
5
|
+
|
6
|
+
describe 'block device' do
|
7
|
+
let(:file) { backend.file('/tmp/block_device') }
|
8
|
+
|
9
|
+
it 'exists' do
|
10
|
+
file.exist?.must_equal(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is a block device' do
|
14
|
+
file.block_device?.must_equal(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has type :block_device' do
|
18
|
+
file.type.must_equal(:block_device)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has no content' do
|
22
|
+
file.content.must_equal('')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has owner name root' do
|
26
|
+
file.owner.must_equal('root')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has group name' do
|
30
|
+
file.group.must_equal(Test.root_group(backend.os))
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has mode 0666' do
|
34
|
+
file.mode.must_equal(00666)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'checks mode? 0666' do
|
38
|
+
file.mode?(00666).must_equal(true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has no link_path' do
|
42
|
+
file.link_path.must_be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has no md5sum' do
|
46
|
+
file.md5sum.must_equal('d41d8cd98f00b204e9800998ecf8427e')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has no sha256sum' do
|
50
|
+
file.sha256sum.must_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has a modified time' do
|
54
|
+
file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has inode size of 0' do
|
58
|
+
file.size.must_equal(0)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'has selinux label handling' do
|
62
|
+
res = Test.selinux_label(backend, file.path)
|
63
|
+
file.selinux_label.must_equal(res)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'has no product_version' do
|
67
|
+
file.product_version.must_equal(nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'has no file_version' do
|
71
|
+
file.file_version.must_equal(nil)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe 'file interface' do
|
4
|
+
let(:backend) { get_backend.call }
|
5
|
+
|
6
|
+
describe 'character device' do
|
7
|
+
let(:file) { backend.file('/dev/null') }
|
8
|
+
|
9
|
+
it 'exists' do
|
10
|
+
file.exist?.must_equal(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is a character device' do
|
14
|
+
file.character_device?.must_equal(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has type :character_device' do
|
18
|
+
file.type.must_equal(:character_device)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has empty content' do
|
22
|
+
file.content.must_equal('')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has owner name root' do
|
26
|
+
file.owner.must_equal('root')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has group name' do
|
30
|
+
file.group.must_equal(Test.root_group(backend.os))
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has mode 0666' do
|
34
|
+
file.mode.must_equal(00666)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'checks mode? 0666' do
|
38
|
+
file.mode?(00666).must_equal(true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has no link_path' do
|
42
|
+
file.link_path.must_be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has an md5sum' do
|
46
|
+
file.md5sum.must_equal('d41d8cd98f00b204e9800998ecf8427e')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has an sha256sum' do
|
50
|
+
file.sha256sum.must_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has a modified time' do
|
54
|
+
file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has inode size of 0' do
|
58
|
+
file.size.must_equal(0)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'has selinux label handling' do
|
62
|
+
res = Test.selinux_label(backend, file.path)
|
63
|
+
file.selinux_label.must_equal(res)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'has no product_version' do
|
67
|
+
file.product_version.must_equal(nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'has no file_version' do
|
71
|
+
file.file_version.must_equal(nil)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe 'file interface' do
|
4
|
+
let(:backend) { get_backend.call }
|
5
|
+
|
6
|
+
describe 'regular file' do
|
7
|
+
let(:file) { backend.file('/tmp/file') }
|
8
|
+
|
9
|
+
it 'exists' do
|
10
|
+
file.exist?.must_equal(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is a file' do
|
14
|
+
file.file?.must_equal(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has type :file' do
|
18
|
+
file.type.must_equal(:file)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has content' do
|
22
|
+
file.content.must_equal('hello world')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has owner name root' do
|
26
|
+
file.owner.must_equal('root')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has group name' do
|
30
|
+
file.group.must_equal(Test.root_group(backend.os))
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has mode 0765' do
|
34
|
+
file.mode.must_equal(00765)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'checks mode? 0765' do
|
38
|
+
file.mode?(00765).must_equal(true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'doesnt check mode? 0764' do
|
42
|
+
file.mode?(00764).must_equal(false)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has no link_path' do
|
46
|
+
file.link_path.must_be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has an md5sum' do
|
50
|
+
file.md5sum.must_equal('5eb63bbbe01eeed093cb22bb8f5acdc3')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has an sha256sum' do
|
54
|
+
file.sha256sum.must_equal('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has a modified time' do
|
58
|
+
file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'has size' do
|
62
|
+
# Must be around 11 Bytes, +- 4
|
63
|
+
file.size.must_be_close_to(11, 4)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'has selinux label handling' do
|
67
|
+
res = Test.selinux_label(backend, file.path)
|
68
|
+
file.selinux_label.must_equal(res)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'has no product_version' do
|
72
|
+
file.product_version.must_equal(nil)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'has no file_version' do
|
76
|
+
file.file_version.must_equal(nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe 'file interface' do
|
4
|
+
let(:backend) { get_backend.call }
|
5
|
+
|
6
|
+
describe 'a folder' do
|
7
|
+
let(:file) { backend.file('/tmp/folder') }
|
8
|
+
|
9
|
+
it 'exists' do
|
10
|
+
file.exist?.must_equal(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is a directory' do
|
14
|
+
file.directory?.must_equal(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has type :directory' do
|
18
|
+
file.type.must_equal(:directory)
|
19
|
+
end
|
20
|
+
|
21
|
+
case get_backend.call.os[:family]
|
22
|
+
when 'freebsd'
|
23
|
+
it 'has freebsd folder content behavior' do
|
24
|
+
file.content.must_equal("\u0003\u0000")
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has an md5sum' do
|
28
|
+
file.md5sum.must_equal('598f4fe64aefab8f00bcbea4c9239abf')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has an sha256sum' do
|
32
|
+
file.sha256sum.must_equal('9b4fb24edd6d1d8830e272398263cdbf026b97392cc35387b991dc0248a628f9')
|
33
|
+
end
|
34
|
+
|
35
|
+
else
|
36
|
+
it 'has no content' do
|
37
|
+
file.content.must_equal(nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'has an md5sum' do
|
41
|
+
file.md5sum.must_equal(nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has an sha256sum' do
|
45
|
+
file.sha256sum.must_equal(nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has owner name root' do
|
50
|
+
file.owner.must_equal('root')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has group name' do
|
54
|
+
file.group.must_equal(Test.root_group(backend.os))
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has mode 0567' do
|
58
|
+
file.mode.must_equal(00567)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'checks mode? 0567' do
|
62
|
+
file.mode?(00567).must_equal(true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'has no link_path' do
|
66
|
+
file.link_path.must_be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'has a modified time' do
|
70
|
+
file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'has inode size' do
|
74
|
+
file.size.must_be_close_to(4096, 4096)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'has selinux label handling' do
|
78
|
+
res = Test.selinux_label(backend, file.path)
|
79
|
+
file.selinux_label.must_equal(res)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has no product_version' do
|
83
|
+
file.product_version.must_equal(nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'has no file_version' do
|
87
|
+
file.file_version.must_equal(nil)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|