r-train 0.9.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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +45 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +137 -0
  8. data/Rakefile +39 -0
  9. data/lib/train.rb +100 -0
  10. data/lib/train/errors.rb +23 -0
  11. data/lib/train/extras.rb +15 -0
  12. data/lib/train/extras/command_wrapper.rb +105 -0
  13. data/lib/train/extras/file_common.rb +131 -0
  14. data/lib/train/extras/linux_file.rb +74 -0
  15. data/lib/train/extras/linux_lsb.rb +60 -0
  16. data/lib/train/extras/os_common.rb +131 -0
  17. data/lib/train/extras/os_detect_darwin.rb +32 -0
  18. data/lib/train/extras/os_detect_linux.rb +126 -0
  19. data/lib/train/extras/os_detect_unix.rb +77 -0
  20. data/lib/train/extras/os_detect_windows.rb +73 -0
  21. data/lib/train/extras/stat.rb +92 -0
  22. data/lib/train/extras/windows_file.rb +85 -0
  23. data/lib/train/options.rb +80 -0
  24. data/lib/train/plugins.rb +40 -0
  25. data/lib/train/plugins/base_connection.rb +86 -0
  26. data/lib/train/plugins/transport.rb +49 -0
  27. data/lib/train/transports/docker.rb +102 -0
  28. data/lib/train/transports/local.rb +52 -0
  29. data/lib/train/transports/local_file.rb +77 -0
  30. data/lib/train/transports/local_os.rb +51 -0
  31. data/lib/train/transports/mock.rb +125 -0
  32. data/lib/train/transports/ssh.rb +163 -0
  33. data/lib/train/transports/ssh_connection.rb +216 -0
  34. data/lib/train/transports/winrm.rb +187 -0
  35. data/lib/train/transports/winrm_connection.rb +258 -0
  36. data/lib/train/version.rb +7 -0
  37. data/test/integration/.kitchen.yml +43 -0
  38. data/test/integration/Berksfile +3 -0
  39. data/test/integration/bootstrap.sh +17 -0
  40. data/test/integration/chefignore +1 -0
  41. data/test/integration/cookbooks/test/metadata.rb +1 -0
  42. data/test/integration/cookbooks/test/recipes/default.rb +101 -0
  43. data/test/integration/docker_run.rb +153 -0
  44. data/test/integration/docker_test.rb +24 -0
  45. data/test/integration/docker_test_container.rb +24 -0
  46. data/test/integration/helper.rb +58 -0
  47. data/test/integration/sudo/nopasswd.rb +16 -0
  48. data/test/integration/sudo/passwd.rb +21 -0
  49. data/test/integration/sudo/run_as.rb +12 -0
  50. data/test/integration/test-runner.yaml +24 -0
  51. data/test/integration/test_local.rb +19 -0
  52. data/test/integration/test_ssh.rb +24 -0
  53. data/test/integration/tests/path_block_device_test.rb +74 -0
  54. data/test/integration/tests/path_character_device_test.rb +74 -0
  55. data/test/integration/tests/path_file_test.rb +79 -0
  56. data/test/integration/tests/path_folder_test.rb +88 -0
  57. data/test/integration/tests/path_missing_test.rb +77 -0
  58. data/test/integration/tests/path_pipe_test.rb +78 -0
  59. data/test/integration/tests/path_symlink_test.rb +83 -0
  60. data/test/integration/tests/run_command_test.rb +28 -0
  61. data/test/unit/extras/command_wrapper_test.rb +41 -0
  62. data/test/unit/extras/file_common_test.rb +133 -0
  63. data/test/unit/extras/linux_file_test.rb +98 -0
  64. data/test/unit/extras/os_common_test.rb +258 -0
  65. data/test/unit/extras/stat_test.rb +105 -0
  66. data/test/unit/helper.rb +6 -0
  67. data/test/unit/plugins/connection_test.rb +44 -0
  68. data/test/unit/plugins/transport_test.rb +111 -0
  69. data/test/unit/plugins_test.rb +22 -0
  70. data/test/unit/train_test.rb +132 -0
  71. data/test/unit/transports/local_file_test.rb +112 -0
  72. data/test/unit/transports/local_test.rb +73 -0
  73. data/test/unit/transports/mock_test.rb +76 -0
  74. data/test/unit/transports/ssh_test.rb +95 -0
  75. data/test/unit/version_test.rb +8 -0
  76. data/train.gemspec +32 -0
  77. metadata +299 -0
@@ -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
+ run_as('whoami', { sudo: true })
14
+ .exit_status.wont_equal 0
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,12 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require_relative '../helper'
6
+ require 'train'
7
+
8
+ def run_as(cmd, opts = {})
9
+ Train.create('local', opts)
10
+ .connection
11
+ .run_command(cmd)
12
+ end
@@ -0,0 +1,24 @@
1
+ images:
2
+ - centos:6.6
3
+ - centos:6.7
4
+ - centos:7.1.1503
5
+ - debian:7.9
6
+ - debian:8.2
7
+ - fedora:21
8
+ - fedora:22
9
+ - ubuntu:12.04
10
+ - ubuntu:14.04
11
+ - ubuntu:15.04
12
+ # extra
13
+ - centos:5.11
14
+ - centos:7.0.1406
15
+ - debian:6.0.10
16
+ - fedora:20
17
+ - oraclelinux:5.11
18
+ - oraclelinux:6.7
19
+ - oraclelinux:7.1
20
+ - ubuntu:10.04
21
+ - ubuntu:13.04
22
+ - ubuntu:15.10
23
+ provision:
24
+ - script: bootstrap.sh
@@ -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,24 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+
4
+ require_relative 'helper'
5
+ require 'train'
6
+
7
+ backends = {}
8
+ backend_conf = {
9
+ 'target' => 'ssh://vagrant@localhost',
10
+ 'key_files' => '/root/.ssh/id_rsa',
11
+ }
12
+
13
+ backends[:ssh] = proc { |*args|
14
+ conf = Train.target_config(backend_conf)
15
+ Train.create('ssh', conf).connection(args[0])
16
+ }
17
+
18
+ tests = ARGV
19
+
20
+ backends.each do |type, get_backend|
21
+ tests.each do |test|
22
+ instance_eval(File.read(test), test, 1)
23
+ end
24
+ 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,88 @@
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
+ if get_backend.call.os[:family] == 'freebsd'
22
+ it 'has freebsd folder content behavior' do
23
+ file.content.must_equal("\u0003\u0000")
24
+ end
25
+
26
+ it 'has an md5sum' do
27
+ file.md5sum.must_equal('598f4fe64aefab8f00bcbea4c9239abf')
28
+ end
29
+
30
+ it 'has an sha256sum' do
31
+ file.sha256sum.must_equal('9b4fb24edd6d1d8830e272398263cdbf026b97392cc35387b991dc0248a628f9')
32
+ end
33
+ else
34
+ it 'has no content' do
35
+ file.content.must_equal(nil)
36
+ end
37
+
38
+ it 'has an md5sum' do
39
+ file.md5sum.must_equal(nil)
40
+ end
41
+
42
+ it 'has an sha256sum' do
43
+ file.sha256sum.must_equal(nil)
44
+ end
45
+ end
46
+
47
+ it 'has owner name root' do
48
+ file.owner.must_equal('root')
49
+ end
50
+
51
+ it 'has group name' do
52
+ file.group.must_equal(Test.root_group(backend.os))
53
+ end
54
+
55
+ it 'has mode 0567' do
56
+ file.mode.must_equal(00567)
57
+ end
58
+
59
+ it 'checks mode? 0567' do
60
+ file.mode?(00567).must_equal(true)
61
+ end
62
+
63
+ it 'has no link_path' do
64
+ file.link_path.must_be_nil
65
+ end
66
+
67
+ it 'has a modified time' do
68
+ file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
69
+ end
70
+
71
+ it 'has inode size' do
72
+ file.size.must_be_close_to(4096, 4096)
73
+ end
74
+
75
+ it 'has selinux label handling' do
76
+ res = Test.selinux_label(backend, file.path)
77
+ file.selinux_label.must_equal(res)
78
+ end
79
+
80
+ it 'has no product_version' do
81
+ file.product_version.must_equal(nil)
82
+ end
83
+
84
+ it 'has no file_version' do
85
+ file.file_version.must_equal(nil)
86
+ end
87
+ end
88
+ end