r-train 0.9.1 → 0.9.3
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/.gitignore +3 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +81 -0
- data/Gemfile +3 -1
- data/Rakefile +108 -0
- data/lib/train/extras.rb +1 -0
- data/lib/train/extras/aix_file.rb +37 -0
- data/lib/train/extras/command_wrapper.rb +34 -6
- data/lib/train/extras/file_common.rb +4 -0
- data/lib/train/extras/linux_file.rb +2 -3
- data/lib/train/extras/os_common.rb +4 -1
- data/lib/train/extras/os_detect_linux.rb +34 -12
- data/lib/train/extras/os_detect_windows.rb +11 -0
- data/lib/train/extras/stat.rb +29 -0
- data/lib/train/extras/windows_file.rb +4 -2
- data/lib/train/transports/mock.rb +9 -3
- data/lib/train/transports/ssh_connection.rb +7 -1
- data/lib/train/version.rb +1 -1
- data/test/integration/cookbooks/test/recipes/default.rb +2 -33
- data/test/integration/cookbooks/test/recipes/prep_files.rb +40 -0
- data/test/integration/helper.rb +4 -1
- data/test/integration/sudo/passwd.rb +2 -2
- data/test/integration/test_ssh.rb +17 -2
- data/test/integration/tests/path_folder_test.rb +3 -1
- data/test/unit/extras/command_wrapper_test.rb +15 -0
- data/test/unit/extras/os_common_test.rb +9 -0
- data/test/unit/extras/os_detect_linux_test.rb +188 -0
- data/test/unit/helper.rb +1 -0
- data/test/unit/transports/local_test.rb +26 -12
- data/test/unit/transports/ssh_test.rb +14 -0
- data/train.gemspec +3 -2
- metadata +22 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4bc131b14e564505bfb4b0fe6600a1cb65683ef6
|
|
4
|
+
data.tar.gz: 7c1e8fe171c13417699bac9e79331e2e5106e9d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb2560766fb6136b92589b9b0add7f689a7732583168b1453693552986bd7829d5531e0bf431fb85e5c168b2f03e9fb60bdba34d48aa2ab22da09ccf8191776b
|
|
7
|
+
data.tar.gz: 14fd0c7b1d9c9e68dec01cec7ee0f75a7337760ccbfbbe4caf234200b1638dff93b475841755096692db13adb962d1b46aeb5df6f37ef3126a31bd32f798dba0
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
+
sudo: required
|
|
2
3
|
language: ruby
|
|
3
4
|
cache: bundler
|
|
4
5
|
|
|
6
|
+
# necessary for docker to work
|
|
7
|
+
dist: trusty
|
|
8
|
+
services:
|
|
9
|
+
- docker
|
|
10
|
+
|
|
11
|
+
bundler_args: --without integration tools
|
|
12
|
+
|
|
5
13
|
matrix:
|
|
6
14
|
include:
|
|
7
15
|
- rvm: 1.9.3
|
|
@@ -10,3 +18,6 @@ matrix:
|
|
|
10
18
|
gemfile: Gemfile
|
|
11
19
|
- rvm: 2.2
|
|
12
20
|
gemfile: Gemfile
|
|
21
|
+
- rvm: 2.2
|
|
22
|
+
gemfile: Gemfile
|
|
23
|
+
script: bundle exec rake test:docker config=test/integration/test-runner.yaml
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
## [0.9.3](https://github.com/chef/train/tree/0.9.3) (2016-01-02)
|
|
4
|
+
[Full Changelog](https://github.com/chef/train/compare/v0.9.2...0.9.3)
|
|
5
|
+
|
|
6
|
+
**Implemented enhancements:**
|
|
7
|
+
|
|
8
|
+
- Support for local transport on Windows [\#43](https://github.com/chef/train/pull/43) ([chris-rock](https://github.com/chris-rock))
|
|
9
|
+
- Split integration test preparation from executing [\#42](https://github.com/chef/train/pull/42) ([chris-rock](https://github.com/chris-rock))
|
|
10
|
+
|
|
11
|
+
**Merged pull requests:**
|
|
12
|
+
|
|
13
|
+
- introduce `mounted` as a separate method to retrieve the content [\#44](https://github.com/chef/train/pull/44) ([chris-rock](https://github.com/chris-rock))
|
|
14
|
+
- Support for AIX and targeted SSH testing [\#41](https://github.com/chef/train/pull/41) ([foobarbam](https://github.com/foobarbam))
|
|
15
|
+
|
|
16
|
+
## [v0.9.2](https://github.com/chef/train/tree/v0.9.2) (2015-12-11)
|
|
17
|
+
[Full Changelog](https://github.com/chef/train/compare/v0.9.1...v0.9.2)
|
|
18
|
+
|
|
19
|
+
**Implemented enhancements:**
|
|
20
|
+
|
|
21
|
+
- add changelog [\#38](https://github.com/chef/train/pull/38) ([chris-rock](https://github.com/chris-rock))
|
|
22
|
+
- activate integration tests in travis [\#37](https://github.com/chef/train/pull/37) ([chris-rock](https://github.com/chris-rock))
|
|
23
|
+
- Adding support for Wind River Linux in support of Cisco devices [\#33](https://github.com/chef/train/pull/33) ([adamleff](https://github.com/adamleff))
|
|
24
|
+
|
|
25
|
+
**Fixed bugs:**
|
|
26
|
+
|
|
27
|
+
- Integration test failures [\#34](https://github.com/chef/train/issues/34)
|
|
28
|
+
- Implemented WindowsFile\#exist? [\#36](https://github.com/chef/train/pull/36) ([docwhat](https://github.com/docwhat))
|
|
29
|
+
- adapt integration test to changes in command\_wrapper [\#35](https://github.com/chef/train/pull/35) ([srenatus](https://github.com/srenatus))
|
|
30
|
+
|
|
31
|
+
**Closed issues:**
|
|
32
|
+
|
|
33
|
+
- WinRM plaintext transport is hardcoded \(cannot use SSL\) [\#29](https://github.com/chef/train/issues/29)
|
|
34
|
+
|
|
35
|
+
**Merged pull requests:**
|
|
36
|
+
|
|
37
|
+
- 0.9.2 [\#40](https://github.com/chef/train/pull/40) ([arlimus](https://github.com/arlimus))
|
|
38
|
+
- add rake version helpers [\#39](https://github.com/chef/train/pull/39) ([arlimus](https://github.com/arlimus))
|
|
39
|
+
|
|
40
|
+
## [v0.9.1](https://github.com/chef/train/tree/v0.9.1) (2015-11-03)
|
|
41
|
+
[Full Changelog](https://github.com/chef/train/compare/0.9.0...v0.9.1)
|
|
42
|
+
|
|
43
|
+
**Implemented enhancements:**
|
|
44
|
+
|
|
45
|
+
- R train [\#27](https://github.com/chef/train/pull/27) ([arlimus](https://github.com/arlimus))
|
|
46
|
+
- Update style of readme [\#26](https://github.com/chef/train/pull/26) ([chris-rock](https://github.com/chris-rock))
|
|
47
|
+
- Add Apache 2.0 License [\#25](https://github.com/chef/train/pull/25) ([jamesc](https://github.com/jamesc))
|
|
48
|
+
|
|
49
|
+
## [0.9.0](https://github.com/chef/train/tree/0.9.0) (2015-11-03)
|
|
50
|
+
**Implemented enhancements:**
|
|
51
|
+
|
|
52
|
+
- set windows name in :release [\#23](https://github.com/chef/train/pull/23) ([arlimus](https://github.com/arlimus))
|
|
53
|
+
- basic file transport via winrm [\#21](https://github.com/chef/train/pull/21) ([chris-rock](https://github.com/chris-rock))
|
|
54
|
+
- dont return nil on command errors stdout/stderr [\#20](https://github.com/chef/train/pull/20) ([arlimus](https://github.com/arlimus))
|
|
55
|
+
- skip .delivery in gemspec [\#19](https://github.com/chef/train/pull/19) ([arlimus](https://github.com/arlimus))
|
|
56
|
+
- Verify sudo is working and fail with error messages if it isn't [\#18](https://github.com/chef/train/pull/18) ([arlimus](https://github.com/arlimus))
|
|
57
|
+
- improve file eposure [\#16](https://github.com/chef/train/pull/16) ([chris-rock](https://github.com/chris-rock))
|
|
58
|
+
- add delivery [\#13](https://github.com/chef/train/pull/13) ([arlimus](https://github.com/arlimus))
|
|
59
|
+
- Sudo [\#12](https://github.com/chef/train/pull/12) ([arlimus](https://github.com/arlimus))
|
|
60
|
+
- Extract options handling for transport [\#11](https://github.com/chef/train/pull/11) ([arlimus](https://github.com/arlimus))
|
|
61
|
+
- don't let mock commands return nil on stdout or stderr [\#10](https://github.com/chef/train/pull/10) ([arlimus](https://github.com/arlimus))
|
|
62
|
+
- allow mock command to support sha256 mocking of commands [\#9](https://github.com/chef/train/pull/9) ([arlimus](https://github.com/arlimus))
|
|
63
|
+
- register plugins with both names and symbols [\#8](https://github.com/chef/train/pull/8) ([arlimus](https://github.com/arlimus))
|
|
64
|
+
- split of mock into transport and connection [\#7](https://github.com/chef/train/pull/7) ([arlimus](https://github.com/arlimus))
|
|
65
|
+
- bugfix: add docker dependency to gemspec [\#6](https://github.com/chef/train/pull/6) ([arlimus](https://github.com/arlimus))
|
|
66
|
+
- move train/plugins/common to train/extras [\#2](https://github.com/chef/train/pull/2) ([arlimus](https://github.com/arlimus))
|
|
67
|
+
- add Travis [\#1](https://github.com/chef/train/pull/1) ([arlimus](https://github.com/arlimus))
|
|
68
|
+
|
|
69
|
+
**Fixed bugs:**
|
|
70
|
+
|
|
71
|
+
- bugfix: prevent debugging info to stdout on winrm [\#22](https://github.com/chef/train/pull/22) ([arlimus](https://github.com/arlimus))
|
|
72
|
+
- bugfix: fail ssh connections correctly [\#17](https://github.com/chef/train/pull/17) ([arlimus](https://github.com/arlimus))
|
|
73
|
+
- bugfix: initialize mock transport to correct family [\#14](https://github.com/chef/train/pull/14) ([arlimus](https://github.com/arlimus))
|
|
74
|
+
|
|
75
|
+
**Merged pull requests:**
|
|
76
|
+
|
|
77
|
+
- bump train version to 0.9.0 [\#24](https://github.com/chef/train/pull/24) ([chris-rock](https://github.com/chris-rock))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
data/Gemfile
CHANGED
|
@@ -8,15 +8,17 @@ group :test do
|
|
|
8
8
|
gem 'rake', '~> 10'
|
|
9
9
|
gem 'rubocop', '~> 0.33.0'
|
|
10
10
|
gem 'simplecov', '~> 0.10'
|
|
11
|
+
gem 'concurrent-ruby', '~> 0.9'
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
group :integration do
|
|
15
|
+
gem 'berkshelf', '~> 4.0'
|
|
14
16
|
gem 'test-kitchen', '~> 1.4'
|
|
15
17
|
gem 'kitchen-vagrant'
|
|
16
|
-
gem 'concurrent-ruby', '~> 0.9'
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
group :tools do
|
|
20
21
|
gem 'pry', '~> 0.10'
|
|
21
22
|
gem 'license_finder'
|
|
23
|
+
gem 'github_changelog_generator', '~> 1'
|
|
22
24
|
end
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
|
+
require 'bundler'
|
|
5
|
+
require 'bundler/gem_tasks'
|
|
4
6
|
require 'rake/testtask'
|
|
5
7
|
require 'rubocop/rake_task'
|
|
6
8
|
|
|
@@ -36,4 +38,110 @@ namespace :test do
|
|
|
36
38
|
path = File.join(File.dirname(__FILE__), 'test', 'integration')
|
|
37
39
|
sh('sh', '-c', "cd #{path} && kitchen test -c #{concurrency}")
|
|
38
40
|
end
|
|
41
|
+
|
|
42
|
+
# Target required:
|
|
43
|
+
# rake "test:ssh[user@server]"
|
|
44
|
+
# sh -c cd /home/foobarbam/src/gems/train/test/integration \
|
|
45
|
+
# && target=user@server ruby -I ../../lib test_ssh.rb tests/*
|
|
46
|
+
# ...
|
|
47
|
+
# Turn debug logging back on:
|
|
48
|
+
# debug=1 rake "test:ssh[user@server]"
|
|
49
|
+
# Use a different ssh key:
|
|
50
|
+
# key_files=/home/foobarbam/.ssh/id_rsa2 rake "test:ssh[user@server]"
|
|
51
|
+
# Run with a specific test:
|
|
52
|
+
# test=path_block_device_test.rb rake "test:ssh[user@server]"
|
|
53
|
+
task :ssh, [:target] do |t, args|
|
|
54
|
+
path = File.join(File.dirname(__FILE__), 'test', 'integration')
|
|
55
|
+
key_files = ENV['key_files'] || File.join(ENV['HOME'], '.ssh', 'id_rsa')
|
|
56
|
+
|
|
57
|
+
sh_cmd = "cd #{path} && target=#{args[:target]} key_files=#{key_files}"
|
|
58
|
+
|
|
59
|
+
sh_cmd += " debug=#{ENV['debug']}" if ENV['debug']
|
|
60
|
+
sh_cmd += ' ruby -I ../../lib test_ssh.rb tests/'
|
|
61
|
+
sh_cmd += ENV['test'] || '*'
|
|
62
|
+
|
|
63
|
+
sh('sh', '-c', sh_cmd)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Print the current version of this gem or update it.
|
|
68
|
+
#
|
|
69
|
+
# @param [Type] target the new version you want to set, or nil if you only want to show
|
|
70
|
+
def train_version(target = nil)
|
|
71
|
+
path = 'lib/train/version.rb'
|
|
72
|
+
require_relative path.sub(/.rb$/, '')
|
|
73
|
+
|
|
74
|
+
nu_version = target.nil? ? '' : " -> #{target}"
|
|
75
|
+
puts "Train: #{Train::VERSION}#{nu_version}"
|
|
76
|
+
|
|
77
|
+
unless target.nil?
|
|
78
|
+
raw = File.read(path)
|
|
79
|
+
nu = raw.sub(/VERSION.*/, "VERSION = '#{target}'")
|
|
80
|
+
File.write(path, nu)
|
|
81
|
+
load(path)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Automatically generate a changelog for this project. Only loaded if
|
|
86
|
+
# the necessary gem is installed.
|
|
87
|
+
begin
|
|
88
|
+
require 'github_changelog_generator/task'
|
|
89
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
90
|
+
require_relative 'lib/train/version'
|
|
91
|
+
config.future_release = Train::VERSION
|
|
92
|
+
end
|
|
93
|
+
rescue LoadError
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Check if a command is available
|
|
97
|
+
#
|
|
98
|
+
# @param [Type] x the command you are interested in
|
|
99
|
+
# @param [Type] msg the message to display if the command is missing
|
|
100
|
+
def require_command(x, msg = nil)
|
|
101
|
+
return if system("command -v #{x} || exit 1")
|
|
102
|
+
msg ||= 'Please install it first!'
|
|
103
|
+
puts "\033[31;1mCan't find command #{x.inspect}. #{msg}\033[0m"
|
|
104
|
+
exit 1
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Check if a required environment variable has been set
|
|
108
|
+
#
|
|
109
|
+
# @param [String] x the variable you are interested in
|
|
110
|
+
# @param [String] msg the message you want to display if the variable is missing
|
|
111
|
+
def require_env(x, msg = nil)
|
|
112
|
+
exists = `env | grep "^#{x}="`
|
|
113
|
+
return unless exists.empty?
|
|
114
|
+
puts "\033[31;1mCan't find environment variable #{x.inspect}. #{msg}\033[0m"
|
|
115
|
+
exit 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Check the requirements for running an update of this repository.
|
|
119
|
+
def check_update_requirements
|
|
120
|
+
require_command 'git'
|
|
121
|
+
require_command 'github_changelog_generator', "\n"\
|
|
122
|
+
"For more information on how to install it see:\n"\
|
|
123
|
+
" https://github.com/skywinder/github-changelog-generator\n"
|
|
124
|
+
require_env 'CHANGELOG_GITHUB_TOKEN', "\n"\
|
|
125
|
+
"Please configure this token to make sure you can run all commands\n"\
|
|
126
|
+
"against GitHub.\n\n"\
|
|
127
|
+
"See github_changelog_generator homepage for more information:\n"\
|
|
128
|
+
" https://github.com/skywinder/github-changelog-generator\n"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Show the current version of this gem.
|
|
132
|
+
desc 'Show the version of this gem'
|
|
133
|
+
task :version do
|
|
134
|
+
train_version
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Update the version of this gem and create an updated
|
|
138
|
+
# changelog. It covers everything short of actually releasing
|
|
139
|
+
# the gem.
|
|
140
|
+
desc 'Bump the version of this gem'
|
|
141
|
+
task :bump_version, [:version] do |_, args|
|
|
142
|
+
v = args[:version] || ENV['to']
|
|
143
|
+
fail "You must specify a target version! rake bump_version to=1.2.3" if v.empty?
|
|
144
|
+
check_update_requirements
|
|
145
|
+
train_version(v)
|
|
146
|
+
Rake::Task['changelog'].invoke
|
|
39
147
|
end
|
data/lib/train/extras.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Train::Extras
|
|
|
6
6
|
autoload :CommandWrapper, 'train/extras/command_wrapper'
|
|
7
7
|
autoload :FileCommon, 'train/extras/file_common'
|
|
8
8
|
autoload :LinuxFile, 'train/extras/linux_file'
|
|
9
|
+
autoload :AixFile, 'train/extras/aix_file'
|
|
9
10
|
autoload :WindowsFile, 'train/extras/windows_file'
|
|
10
11
|
autoload :OSCommon, 'train/extras/os_common'
|
|
11
12
|
autoload :Stat, 'train/extras/stat'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
require 'train/extras/stat'
|
|
5
|
+
|
|
6
|
+
module Train::Extras
|
|
7
|
+
class AixFile < LinuxFile
|
|
8
|
+
def initialize(backend, path)
|
|
9
|
+
super(backend, path)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def content
|
|
13
|
+
return @content if defined?(@content)
|
|
14
|
+
@content = case
|
|
15
|
+
when !exist?, directory?
|
|
16
|
+
nil
|
|
17
|
+
when size.nil?, size == 0
|
|
18
|
+
''
|
|
19
|
+
else
|
|
20
|
+
@backend.run_command("cat #{@spath}").stdout || ''
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def link_path
|
|
25
|
+
return nil unless symlink?
|
|
26
|
+
@link_path ||= (
|
|
27
|
+
@backend.run_command("perl -e 'print readlink shift' #{@spath}").stdout.chomp
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def mounted
|
|
32
|
+
@mounted ||= (
|
|
33
|
+
@backend.run_command("lsfs -c #{@spath}")
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -90,16 +90,44 @@ module Train::Extras
|
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
+
# this is required if you run locally on windows,
|
|
94
|
+
# winrm connections provide a PowerShell shell automatically
|
|
95
|
+
# TODO: only activate in local mode
|
|
96
|
+
class PowerShellCommand < CommandWrapperBase
|
|
97
|
+
Train::Options.attach(self)
|
|
98
|
+
|
|
99
|
+
def initialize(backend, options)
|
|
100
|
+
@backend = backend
|
|
101
|
+
validate_options(options)
|
|
102
|
+
|
|
103
|
+
@prefix = 'powershell '
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def run(command)
|
|
107
|
+
@prefix + command
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def to_s
|
|
111
|
+
'PowerShell CommandWrapper'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
93
115
|
class CommandWrapper
|
|
94
116
|
include_options LinuxCommand
|
|
95
117
|
|
|
96
118
|
def self.load(transport, options)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
if transport.os.unix?
|
|
120
|
+
return nil unless LinuxCommand.active?(options)
|
|
121
|
+
res = LinuxCommand.new(transport, options)
|
|
122
|
+
msg = res.verify
|
|
123
|
+
fail Train::UserError, "Sudo failed: #{msg}" unless msg.nil?
|
|
124
|
+
res
|
|
125
|
+
# only use powershell command for local transport. winrm transport
|
|
126
|
+
# uses powershell as default
|
|
127
|
+
elsif transport.os.windows? && transport.class == Train::Transports::Local::Connection
|
|
128
|
+
PowerShellCommand.new(transport, options)
|
|
129
|
+
end
|
|
130
|
+
nil
|
|
103
131
|
end
|
|
104
132
|
end
|
|
105
133
|
end
|
|
@@ -36,7 +36,7 @@ module Train::Extras
|
|
|
36
36
|
|
|
37
37
|
OS = {
|
|
38
38
|
'redhat' => %w{
|
|
39
|
-
redhat oracle centos fedora amazon scientific xenserver
|
|
39
|
+
redhat oracle centos fedora amazon scientific xenserver wrlinux
|
|
40
40
|
},
|
|
41
41
|
'debian' => %w{
|
|
42
42
|
debian ubuntu linuxmint raspbian
|
|
@@ -53,6 +53,9 @@ module Train::Extras
|
|
|
53
53
|
'windows' => %w{
|
|
54
54
|
windows
|
|
55
55
|
},
|
|
56
|
+
'aix' => %w{
|
|
57
|
+
aix
|
|
58
|
+
},
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
OS['linux'] = %w{linux alpine arch coreos exherbo gentoo slackware} +
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
require 'train/extras/linux_lsb'
|
|
12
12
|
|
|
13
13
|
module Train::Extras
|
|
14
|
-
module DetectLinux
|
|
14
|
+
module DetectLinux # rubocop:disable Metrics/ModuleLength
|
|
15
15
|
include Train::Extras::LinuxLSB
|
|
16
16
|
|
|
17
17
|
def detect_linux_via_config # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
@@ -21,7 +21,7 @@ module Train::Extras
|
|
|
21
21
|
elsif !(raw = get_config('/etc/enterprise-release')).nil?
|
|
22
22
|
@platform[:family] = 'oracle'
|
|
23
23
|
@platform[:release] = redhatish_version(raw)
|
|
24
|
-
elsif !(
|
|
24
|
+
elsif !(raw = get_config('/etc/debian_version')).nil?
|
|
25
25
|
case lsb[:id]
|
|
26
26
|
when /ubuntu/i
|
|
27
27
|
@platform[:family] = 'ubuntu'
|
|
@@ -30,11 +30,8 @@ module Train::Extras
|
|
|
30
30
|
@platform[:family] = 'linuxmint'
|
|
31
31
|
@platform[:release] = lsb[:release]
|
|
32
32
|
else
|
|
33
|
-
@platform[:family] = 'debian'
|
|
34
|
-
@platform[:
|
|
35
|
-
unless (rel = get_config('/etc/debian_version')).nil?
|
|
36
|
-
@platform[:release] = rel.chomp
|
|
37
|
-
end
|
|
33
|
+
@platform[:family] = unix_file?('/usr/bin/raspi-config') ? 'raspbian' : 'debian'
|
|
34
|
+
@platform[:release] = raw.chomp
|
|
38
35
|
end
|
|
39
36
|
elsif !(raw = get_config('/etc/parallels-release')).nil?
|
|
40
37
|
@platform[:family] = redhatish_platform(raw)
|
|
@@ -82,12 +79,14 @@ module Train::Extras
|
|
|
82
79
|
@platform[:family] = 'coreos'
|
|
83
80
|
meta = lsb_config(raw)
|
|
84
81
|
@platform[:release] = meta[:release]
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
elsif !(os_info = fetch_os_release).nil?
|
|
83
|
+
if os_info['ID_LIKE'].match('wrlinux')
|
|
84
|
+
@platform[:family] = 'wrlinux'
|
|
85
|
+
@platform[:release] = os_info['VERSION']
|
|
86
|
+
end
|
|
88
87
|
end
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
|
|
89
|
+
!@platform[:family].nil? && !@platform[:release].nil?
|
|
91
90
|
end
|
|
92
91
|
|
|
93
92
|
def uname_s
|
|
@@ -122,5 +121,28 @@ module Train::Extras
|
|
|
122
121
|
# in all other cases we failed the detection
|
|
123
122
|
@platform[:family] = 'unknown'
|
|
124
123
|
end
|
|
124
|
+
|
|
125
|
+
def fetch_os_release
|
|
126
|
+
data = get_config('/etc/os-release')
|
|
127
|
+
return if data.nil?
|
|
128
|
+
|
|
129
|
+
os_info = parse_os_release_info(data)
|
|
130
|
+
cisco_info_file = os_info['CISCO_RELEASE_INFO']
|
|
131
|
+
if cisco_info_file
|
|
132
|
+
os_info.merge!(parse_os_release_info(get_config(cisco_info_file)))
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
os_info
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def parse_os_release_info(raw)
|
|
139
|
+
return {} if raw.nil?
|
|
140
|
+
|
|
141
|
+
raw.lines.each_with_object({}) do |line, memo|
|
|
142
|
+
line.strip!
|
|
143
|
+
key, value = line.split('=', 2)
|
|
144
|
+
memo[key] = value.gsub(/\A"|"\Z/, '') unless value.empty?
|
|
145
|
+
end
|
|
146
|
+
end
|
|
125
147
|
end
|
|
126
148
|
end
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#
|
|
10
10
|
|
|
11
11
|
require 'json'
|
|
12
|
+
require 'winrm'
|
|
12
13
|
|
|
13
14
|
module Train::Extras
|
|
14
15
|
module DetectWindows
|
|
@@ -57,7 +58,16 @@ module Train::Extras
|
|
|
57
58
|
'-Name OS -Value (Get-WmiObject -Class Win32_OperatingSystem) '\
|
|
58
59
|
'-PassThru | Add-Member -MemberType NoteProperty -Name OSVersion '\
|
|
59
60
|
'-Value ([Environment]::OSVersion) -PassThru | ConvertTo-Json'
|
|
61
|
+
|
|
62
|
+
# wrap the script to ensure we always run it via powershell
|
|
63
|
+
# especially in local mode, we cannot be sure that we get a Powershell
|
|
64
|
+
# we may just get a `cmd`. os detection and powershell command wrapper is
|
|
65
|
+
# not available when this code is executed
|
|
66
|
+
script = WinRM::PowershellScript.new(cmd)
|
|
67
|
+
cmd = "powershell -encodedCommand #{script.encoded}"
|
|
68
|
+
|
|
60
69
|
res = @backend.run_command(cmd)
|
|
70
|
+
|
|
61
71
|
# TODO: error as this shouldnt be happening at this point
|
|
62
72
|
return false if res.exit_status != 0 or res.stdout.empty?
|
|
63
73
|
|
|
@@ -67,6 +77,7 @@ module Train::Extras
|
|
|
67
77
|
|
|
68
78
|
@platform[:family] = 'windows'
|
|
69
79
|
@platform[:release] = WINDOWS_VERSIONS[version]
|
|
80
|
+
|
|
70
81
|
true
|
|
71
82
|
end
|
|
72
83
|
end
|
data/lib/train/extras/stat.rb
CHANGED
|
@@ -20,6 +20,7 @@ module Train::Extras
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.stat(shell_escaped_path, backend)
|
|
23
|
+
return aix_stat(shell_escaped_path, backend) if backend.os.aix?
|
|
23
24
|
return bsd_stat(shell_escaped_path, backend) if backend.os.bsd?
|
|
24
25
|
return linux_stat(shell_escaped_path, backend) if backend.os.unix?
|
|
25
26
|
# all other cases we don't handle
|
|
@@ -88,5 +89,33 @@ module Train::Extras
|
|
|
88
89
|
selinux_label: fields[8],
|
|
89
90
|
}
|
|
90
91
|
end
|
|
92
|
+
|
|
93
|
+
def self.aix_stat(shell_escaped_path, backend)
|
|
94
|
+
# Perl here b/c it is default on AIX
|
|
95
|
+
stat_cmd = <<-EOP
|
|
96
|
+
perl -e '
|
|
97
|
+
@a = lstat(shift) or exit 2;
|
|
98
|
+
$u = getpwuid($a[4]);
|
|
99
|
+
$g = getgrgid($a[5]);
|
|
100
|
+
printf("0%o\\n%s\\n%s\\n%d\\n%d\\n", $a[2], $u, $g, $a[9], $a[7])
|
|
101
|
+
' #{shell_escaped_path}
|
|
102
|
+
EOP
|
|
103
|
+
|
|
104
|
+
res = backend.run_command(stat_cmd)
|
|
105
|
+
return {} if res.exit_status != 0
|
|
106
|
+
|
|
107
|
+
fields = res.stdout.split("\n")
|
|
108
|
+
tmask = fields[0].to_i(8)
|
|
109
|
+
|
|
110
|
+
{
|
|
111
|
+
type: find_type(tmask),
|
|
112
|
+
mode: tmask & 00777,
|
|
113
|
+
owner: fields[1],
|
|
114
|
+
group: fields[2],
|
|
115
|
+
mtime: fields[3].to_i,
|
|
116
|
+
size: fields[4].to_i,
|
|
117
|
+
selinux_label: nil,
|
|
118
|
+
}
|
|
119
|
+
end
|
|
91
120
|
end
|
|
92
121
|
end
|
|
@@ -26,7 +26,9 @@ module Train::Extras
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def exist?
|
|
29
|
-
|
|
29
|
+
return @exist if defined?(@exist)
|
|
30
|
+
@exist = @backend.run_command(
|
|
31
|
+
"(Test-Path -Path \"#{@spath}\").ToString()").stdout.chomp == 'True'
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def link_target
|
|
@@ -37,7 +39,7 @@ module Train::Extras
|
|
|
37
39
|
nil
|
|
38
40
|
end
|
|
39
41
|
|
|
40
|
-
def mounted
|
|
42
|
+
def mounted
|
|
41
43
|
nil
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -110,16 +110,22 @@ class Train::Transports::Mock::Connection
|
|
|
110
110
|
class File < FileCommon
|
|
111
111
|
%w{
|
|
112
112
|
exist? mode owner group link_target link_path content mtime size
|
|
113
|
-
selinux_label product_version file_version path
|
|
114
|
-
type
|
|
113
|
+
selinux_label product_version file_version path type
|
|
115
114
|
}.each do |m|
|
|
116
115
|
attr_accessor m.tr('?', '').to_sym
|
|
117
116
|
end
|
|
118
117
|
|
|
119
|
-
def initialize(
|
|
118
|
+
def initialize(runtime, path)
|
|
120
119
|
@path = path
|
|
121
120
|
@type = :unknown
|
|
122
121
|
@exist = false
|
|
122
|
+
@runtime = runtime
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def mounted
|
|
126
|
+
@mounted ||= (
|
|
127
|
+
@runtime.run_command("mount | grep -- ' on #{@path}'")
|
|
128
|
+
)
|
|
123
129
|
end
|
|
124
130
|
end
|
|
125
131
|
end
|
|
@@ -58,7 +58,13 @@ class Train::Transports::SSH
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def file(path)
|
|
61
|
-
@files[path] ||=
|
|
61
|
+
@files[path] ||= \
|
|
62
|
+
case os[:family]
|
|
63
|
+
when 'aix'
|
|
64
|
+
AixFile.new(self, path)
|
|
65
|
+
else
|
|
66
|
+
LinuxFile.new(self, path)
|
|
67
|
+
end
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
# (see Base::Connection#run_command)
|
data/lib/train/version.rb
CHANGED
|
@@ -9,38 +9,7 @@
|
|
|
9
9
|
# Finally (for now), it actually executes the all tests with
|
|
10
10
|
# the local execution backend
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
gid = 'wheel' if node['platform_family'] == 'freebsd'
|
|
14
|
-
|
|
15
|
-
file '/tmp/file' do
|
|
16
|
-
mode '0765'
|
|
17
|
-
owner 'root'
|
|
18
|
-
group gid
|
|
19
|
-
content 'hello world'
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
directory '/tmp/folder' do
|
|
23
|
-
mode '0567'
|
|
24
|
-
owner 'root'
|
|
25
|
-
group gid
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
link '/tmp/symlink'do
|
|
29
|
-
to '/tmp/file'
|
|
30
|
-
owner 'root'
|
|
31
|
-
group gid
|
|
32
|
-
mode '0777'
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
execute 'create pipe/fifo' do
|
|
36
|
-
command 'mkfifo /tmp/pipe'
|
|
37
|
-
not_if 'test -e /tmp/pipe'
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
execute 'create block_device' do
|
|
41
|
-
command "mknod /tmp/block_device b 7 7 && chmod 0666 /tmp/block_device && chown root:#{gid} /tmp/block_device"
|
|
42
|
-
not_if 'test -e /tmp/block_device'
|
|
43
|
-
end
|
|
12
|
+
include_recipe('test::prep_files')
|
|
44
13
|
|
|
45
14
|
# prepare ssh for backend
|
|
46
15
|
execute 'create ssh key' do
|
|
@@ -78,7 +47,7 @@ end
|
|
|
78
47
|
|
|
79
48
|
# execute tests
|
|
80
49
|
execute 'bundle install' do
|
|
81
|
-
command '/opt/chef/embedded/bin/bundle install'
|
|
50
|
+
command '/opt/chef/embedded/bin/bundle install --without integration tools'
|
|
82
51
|
cwd '/tmp/kitchen/data'
|
|
83
52
|
end
|
|
84
53
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Dominik Richter
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
#
|
|
5
|
+
# Helper recipe to create create a few files in the operating
|
|
6
|
+
# systems, which the runner will test against.
|
|
7
|
+
|
|
8
|
+
gid = 'root'
|
|
9
|
+
gid = 'wheel' if node['platform_family'] == 'freebsd'
|
|
10
|
+
gid = 'system' if node['platform_family'] == 'aix'
|
|
11
|
+
|
|
12
|
+
file '/tmp/file' do
|
|
13
|
+
mode '0765'
|
|
14
|
+
owner 'root'
|
|
15
|
+
group gid
|
|
16
|
+
content 'hello world'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
directory '/tmp/folder' do
|
|
20
|
+
mode '0567'
|
|
21
|
+
owner 'root'
|
|
22
|
+
group gid
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
link '/tmp/symlink'do
|
|
26
|
+
to '/tmp/file'
|
|
27
|
+
owner 'root'
|
|
28
|
+
group gid
|
|
29
|
+
mode '0777'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
execute 'create pipe/fifo' do
|
|
33
|
+
command 'mkfifo /tmp/pipe'
|
|
34
|
+
not_if 'test -e /tmp/pipe'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
execute 'create block_device' do
|
|
38
|
+
command "mknod /tmp/block_device b 7 7 && chmod 0666 /tmp/block_device && chown root:#{gid} /tmp/block_device"
|
|
39
|
+
not_if 'test -e /tmp/block_device'
|
|
40
|
+
end
|
data/test/integration/helper.rb
CHANGED
|
@@ -10,8 +10,8 @@ describe 'run_command' do
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it 'is not running sudo without password' do
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
err = ->{Train.create('local', { sudo: true }).connection}.must_raise Train::UserError
|
|
14
|
+
err.message.must_match /Sudo requires a password/
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it 'is running passwd sudo' do
|
|
@@ -3,13 +3,28 @@
|
|
|
3
3
|
|
|
4
4
|
require_relative 'helper'
|
|
5
5
|
require 'train'
|
|
6
|
+
require 'logger'
|
|
6
7
|
|
|
7
8
|
backends = {}
|
|
8
9
|
backend_conf = {
|
|
9
|
-
'target'
|
|
10
|
-
'key_files' => '/root/.ssh/id_rsa',
|
|
10
|
+
'target' => ENV['target'] || 'vagrant@localhost',
|
|
11
|
+
'key_files' => ENV['key_files'] || '/root/.ssh/id_rsa',
|
|
12
|
+
'logger' => Logger.new(STDOUT),
|
|
11
13
|
}
|
|
12
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
|
+
|
|
13
28
|
backends[:ssh] = proc { |*args|
|
|
14
29
|
conf = Train.target_config(backend_conf)
|
|
15
30
|
Train.create('ssh', conf).connection(args[0])
|
|
@@ -18,7 +18,8 @@ describe 'file interface' do
|
|
|
18
18
|
file.type.must_equal(:directory)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
case get_backend.call.os[:family]
|
|
22
|
+
when 'freebsd'
|
|
22
23
|
it 'has freebsd folder content behavior' do
|
|
23
24
|
file.content.must_equal("\u0003\u0000")
|
|
24
25
|
end
|
|
@@ -30,6 +31,7 @@ describe 'file interface' do
|
|
|
30
31
|
it 'has an sha256sum' do
|
|
31
32
|
file.sha256sum.must_equal('9b4fb24edd6d1d8830e272398263cdbf026b97392cc35387b991dc0248a628f9')
|
|
32
33
|
end
|
|
34
|
+
|
|
33
35
|
else
|
|
34
36
|
it 'has no content' do
|
|
35
37
|
file.content.must_equal(nil)
|
|
@@ -39,3 +39,18 @@ describe 'linux command' do
|
|
|
39
39
|
lc.run(cmd).must_equal "echo #{bpw} | base64 -d | sudo -S #{cmd}"
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
|
+
|
|
43
|
+
describe 'powershell command' do
|
|
44
|
+
let(:cls) { Train::Extras::PowerShellCommand }
|
|
45
|
+
let(:cmd) { rand.to_s }
|
|
46
|
+
let(:backend) {
|
|
47
|
+
backend = Train::Transports::Mock.new.connection
|
|
48
|
+
backend.mock_os({ family: 'windows' })
|
|
49
|
+
backend
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
it 'wraps commands in powershell' do
|
|
53
|
+
lc = cls.new(backend, {})
|
|
54
|
+
lc.run(cmd).must_equal "powershell #{cmd}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -172,6 +172,15 @@ describe 'os common plugin' do
|
|
|
172
172
|
it { os.unix?.must_equal(true) }
|
|
173
173
|
end
|
|
174
174
|
|
|
175
|
+
describe 'with platform set to wrlinux' do
|
|
176
|
+
let(:os) { mock_platform('wrlinux') }
|
|
177
|
+
it { os.redhat?.must_equal(true) }
|
|
178
|
+
it { os.debian?.must_equal(false) }
|
|
179
|
+
it { os.suse?.must_equal(false) }
|
|
180
|
+
it { os.linux?.must_equal(true) }
|
|
181
|
+
it { os.unix?.must_equal(true) }
|
|
182
|
+
end
|
|
183
|
+
|
|
175
184
|
describe 'with platform set to linux' do
|
|
176
185
|
let(:os) { mock_platform('linux') }
|
|
177
186
|
it { os.linux?.must_equal(true) }
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
require 'train/extras'
|
|
3
|
+
|
|
4
|
+
class OsDetectLinuxTester
|
|
5
|
+
attr_reader :platform
|
|
6
|
+
include Train::Extras::DetectLinux
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@platform = {}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe 'os_detect_linux' do
|
|
14
|
+
let(:detector) { OsDetectLinuxTester.new }
|
|
15
|
+
|
|
16
|
+
describe '#detect_linux_via_config' do
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
detector.stubs(:get_config)
|
|
20
|
+
detector.stubs(:fetch_os_release)
|
|
21
|
+
detector.stubs(:redhatish_version).returns('redhat-version')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '/etc/enterprise-release' do
|
|
25
|
+
it 'sets the correct family/release for oracle' do
|
|
26
|
+
detector.stubs(:get_config).with('/etc/enterprise-release').returns('data')
|
|
27
|
+
|
|
28
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
29
|
+
detector.platform[:family].must_equal('oracle')
|
|
30
|
+
detector.platform[:release].must_equal('redhat-version')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '/etc/debian_version' do
|
|
35
|
+
|
|
36
|
+
before { detector.stubs(:get_config).with('/etc/debian_version').returns('deb-version') }
|
|
37
|
+
|
|
38
|
+
describe 'ubuntu' do
|
|
39
|
+
it 'sets the correct family/release for ubuntu' do
|
|
40
|
+
detector.stubs(:lsb).returns({ id: 'ubuntu', release: 'ubuntu-release' })
|
|
41
|
+
|
|
42
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
43
|
+
detector.platform[:family].must_equal('ubuntu')
|
|
44
|
+
detector.platform[:release].must_equal('ubuntu-release')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe 'linuxmint' do
|
|
49
|
+
it 'sets the correct family/release for ubuntu' do
|
|
50
|
+
detector.stubs(:lsb).returns({ id: 'linuxmint', release: 'mint-release' })
|
|
51
|
+
|
|
52
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
53
|
+
detector.platform[:family].must_equal('linuxmint')
|
|
54
|
+
detector.platform[:release].must_equal('mint-release')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe 'raspbian' do
|
|
59
|
+
it 'sets the correct family/release for raspbian ' do
|
|
60
|
+
detector.stubs(:lsb).returns({ id: 'something_else', release: 'some_release' })
|
|
61
|
+
detector.expects(:unix_file?).with('/usr/bin/raspi-config').returns(true)
|
|
62
|
+
|
|
63
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
64
|
+
detector.platform[:family].must_equal('raspbian')
|
|
65
|
+
detector.platform[:release].must_equal('deb-version')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe 'everything else' do
|
|
70
|
+
it 'sets the correct family/release for debian ' do
|
|
71
|
+
detector.stubs(:lsb).returns({ id: 'something_else', release: 'some_release' })
|
|
72
|
+
detector.expects(:unix_file?).with('/usr/bin/raspi-config').returns(false)
|
|
73
|
+
|
|
74
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
75
|
+
detector.platform[:family].must_equal('debian')
|
|
76
|
+
detector.platform[:release].must_equal('deb-version')
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '/etc/os-release' do
|
|
82
|
+
describe 'when not on a wrlinux build' do
|
|
83
|
+
it 'does not set a platform family/release' do
|
|
84
|
+
detector.stubs(:fetch_os_release).returns({ 'ID_LIKE' => 'something_else' })
|
|
85
|
+
|
|
86
|
+
detector.detect_linux_via_config.must_equal(false)
|
|
87
|
+
detector.platform[:family].must_equal(nil)
|
|
88
|
+
detector.platform[:release].must_equal(nil)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe 'when on a wrlinux build' do
|
|
93
|
+
let(:data) do
|
|
94
|
+
{
|
|
95
|
+
'ID_LIKE' => 'cisco-wrlinux',
|
|
96
|
+
'VERSION' => 'cisco123'
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'sets the correct family/release for wrlinux' do
|
|
101
|
+
detector.stubs(:fetch_os_release).returns(data)
|
|
102
|
+
|
|
103
|
+
detector.detect_linux_via_config.must_equal(true)
|
|
104
|
+
detector.platform[:family].must_equal('wrlinux')
|
|
105
|
+
detector.platform[:release].must_equal('cisco123')
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe '#fetch_os_release' do
|
|
112
|
+
describe 'when no os-release data is available' do
|
|
113
|
+
it 'returns nil' do
|
|
114
|
+
detector.expects(:get_config).with('/etc/os-release').returns(nil)
|
|
115
|
+
detector.fetch_os_release.must_equal(nil)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe 'when os-release data exists with no CISCO_RELEASE_INFO' do
|
|
120
|
+
let(:os_release) { { 'KEY1' => 'VALUE1' } }
|
|
121
|
+
|
|
122
|
+
it 'returns a correct hash' do
|
|
123
|
+
detector.expects(:get_config).with('/etc/os-release').returns('os-release data')
|
|
124
|
+
detector.expects(:parse_os_release_info).with('os-release data').returns(os_release)
|
|
125
|
+
detector.fetch_os_release['KEY1'].must_equal('VALUE1')
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe 'when os-release data exists with CISCO_RELEASE_INFO' do
|
|
130
|
+
let(:os_release) { { 'KEY1' => 'VALUE1', 'CISCO_RELEASE_INFO' => 'cisco_file' } }
|
|
131
|
+
let(:cisco_release) { { 'KEY1' => 'NEWVALUE1', 'KEY2' => 'VALUE2' } }
|
|
132
|
+
|
|
133
|
+
it 'returns a correct hash' do
|
|
134
|
+
detector.expects(:get_config).with('/etc/os-release').returns('os-release data')
|
|
135
|
+
detector.expects(:get_config).with('cisco_file').returns('cisco data')
|
|
136
|
+
detector.expects(:parse_os_release_info).with('os-release data').returns(os_release)
|
|
137
|
+
detector.expects(:parse_os_release_info).with('cisco data').returns(cisco_release)
|
|
138
|
+
|
|
139
|
+
os_info = detector.fetch_os_release
|
|
140
|
+
os_info['KEY1'].must_equal('NEWVALUE1')
|
|
141
|
+
os_info['KEY2'].must_equal('VALUE2')
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe '#parse_os_release_info' do
|
|
147
|
+
describe 'when nil is supplied' do
|
|
148
|
+
it 'returns an empty hash' do
|
|
149
|
+
detector.parse_os_release_info(nil).must_equal({})
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe 'when unexpectedly-formatted data is supplied' do
|
|
154
|
+
let(:data) do
|
|
155
|
+
<<-EOL
|
|
156
|
+
blah blah
|
|
157
|
+
no good data here
|
|
158
|
+
EOL
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'returns an empty hash' do
|
|
162
|
+
detector.parse_os_release_info(nil).must_equal({})
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe 'when properly-formatted data is supplied' do
|
|
167
|
+
let(:data) do
|
|
168
|
+
<<-EOL
|
|
169
|
+
KEY1=value1
|
|
170
|
+
KEY2=
|
|
171
|
+
KEY3=value3
|
|
172
|
+
KEY4="value4 with spaces"
|
|
173
|
+
KEY5="value5 with a = sign"
|
|
174
|
+
EOL
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'parses the data correctly' do
|
|
178
|
+
parsed_data = detector.parse_os_release_info(data)
|
|
179
|
+
|
|
180
|
+
parsed_data['KEY1'].must_equal('value1')
|
|
181
|
+
parsed_data.key?('KEY2').must_equal(false)
|
|
182
|
+
parsed_data['KEY3'].must_equal('value3')
|
|
183
|
+
parsed_data['KEY4'].must_equal('value4 with spaces')
|
|
184
|
+
parsed_data['KEY5'].must_equal('value5 with a = sign')
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
data/test/unit/helper.rb
CHANGED
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
require 'helper'
|
|
7
7
|
require 'train/transports/local'
|
|
8
8
|
|
|
9
|
+
# overwrite os detection to simplify mock tests, otherwise run_command tries to
|
|
10
|
+
# determine the OS first and fails the tests
|
|
11
|
+
class Train::Transports::Local::Connection
|
|
12
|
+
class OS < OSCommon
|
|
13
|
+
def initialize(backend)
|
|
14
|
+
super(backend, { family: 'train_mock_os' })
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def detect_family
|
|
18
|
+
# no op, we do not need to detect the os
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
9
23
|
describe 'local transport' do
|
|
10
24
|
let(:transport) { Train::Transports::Local.new }
|
|
11
25
|
let(:connection) { transport.connection }
|
|
@@ -31,11 +45,11 @@ describe 'local transport' do
|
|
|
31
45
|
end
|
|
32
46
|
|
|
33
47
|
describe 'when running a local command' do
|
|
34
|
-
let(:
|
|
48
|
+
let(:cmd_runner) { Minitest::Mock.new }
|
|
35
49
|
|
|
36
50
|
def mock_run_cmd(cmd, &block)
|
|
37
|
-
|
|
38
|
-
Mixlib::ShellOut.stub :new,
|
|
51
|
+
cmd_runner.expect :run_command, nil
|
|
52
|
+
Mixlib::ShellOut.stub :new, cmd_runner do |*args|
|
|
39
53
|
block.call()
|
|
40
54
|
end
|
|
41
55
|
end
|
|
@@ -43,9 +57,9 @@ describe 'local transport' do
|
|
|
43
57
|
it 'gets stdout' do
|
|
44
58
|
mock_run_cmd(rand) do
|
|
45
59
|
x = rand
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
cmd_runner.expect :stdout, x
|
|
61
|
+
cmd_runner.expect :stderr, nil
|
|
62
|
+
cmd_runner.expect :exitstatus, nil
|
|
49
63
|
connection.run_command(rand).stdout.must_equal x
|
|
50
64
|
end
|
|
51
65
|
end
|
|
@@ -53,9 +67,9 @@ describe 'local transport' do
|
|
|
53
67
|
it 'gets stderr' do
|
|
54
68
|
mock_run_cmd(rand) do
|
|
55
69
|
x = rand
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
cmd_runner.expect :stdout, nil
|
|
71
|
+
cmd_runner.expect :stderr, x
|
|
72
|
+
cmd_runner.expect :exitstatus, nil
|
|
59
73
|
connection.run_command(rand).stderr.must_equal x
|
|
60
74
|
end
|
|
61
75
|
end
|
|
@@ -63,9 +77,9 @@ describe 'local transport' do
|
|
|
63
77
|
it 'gets exit_status' do
|
|
64
78
|
mock_run_cmd(rand) do
|
|
65
79
|
x = rand
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
80
|
+
cmd_runner.expect :stdout, nil
|
|
81
|
+
cmd_runner.expect :stderr, nil
|
|
82
|
+
cmd_runner.expect :exitstatus, x
|
|
69
83
|
connection.run_command(rand).exit_status.must_equal x
|
|
70
84
|
end
|
|
71
85
|
end
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
require 'helper'
|
|
3
3
|
require 'train/transports/ssh'
|
|
4
4
|
|
|
5
|
+
# overwrite os detection to simplify mock tests, otherwise run_command tries to
|
|
6
|
+
# determine the OS first and fails the tests
|
|
7
|
+
class Train::Transports::SSH::Connection
|
|
8
|
+
class OS < OSCommon
|
|
9
|
+
def initialize(backend)
|
|
10
|
+
super(backend, { family: 'train_mock_os' })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def detect_family
|
|
14
|
+
# no op, we do not need to detect the os
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
5
19
|
describe 'ssh transport' do
|
|
6
20
|
let(:cls) { Train::Transports::SSH }
|
|
7
21
|
let(:conf) {{
|
data/train.gemspec
CHANGED
|
@@ -26,7 +26,8 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.add_dependency 'winrm-transport', '~> 1.0'
|
|
27
27
|
spec.add_dependency 'docker-api', '~> 1.22'
|
|
28
28
|
|
|
29
|
-
spec.add_development_dependency 'rake',
|
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
|
30
30
|
spec.add_development_dependency 'minitest', '~> 5.8'
|
|
31
|
-
spec.add_development_dependency '
|
|
31
|
+
spec.add_development_dependency 'mocha', '~> 1.1'
|
|
32
|
+
spec.add_development_dependency 'rubocop', '~> 0.34'
|
|
32
33
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: r-train
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dominik Richter
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2016-01-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -136,6 +136,20 @@ dependencies:
|
|
|
136
136
|
- - "~>"
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
138
|
version: '5.8'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: mocha
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '1.1'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '1.1'
|
|
139
153
|
- !ruby/object:Gem::Dependency
|
|
140
154
|
name: rubocop
|
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -160,6 +174,7 @@ files:
|
|
|
160
174
|
- ".gitignore"
|
|
161
175
|
- ".rubocop.yml"
|
|
162
176
|
- ".travis.yml"
|
|
177
|
+
- CHANGELOG.md
|
|
163
178
|
- Gemfile
|
|
164
179
|
- LICENSE
|
|
165
180
|
- README.md
|
|
@@ -167,6 +182,7 @@ files:
|
|
|
167
182
|
- lib/train.rb
|
|
168
183
|
- lib/train/errors.rb
|
|
169
184
|
- lib/train/extras.rb
|
|
185
|
+
- lib/train/extras/aix_file.rb
|
|
170
186
|
- lib/train/extras/command_wrapper.rb
|
|
171
187
|
- lib/train/extras/file_common.rb
|
|
172
188
|
- lib/train/extras/linux_file.rb
|
|
@@ -198,6 +214,7 @@ files:
|
|
|
198
214
|
- test/integration/chefignore
|
|
199
215
|
- test/integration/cookbooks/test/metadata.rb
|
|
200
216
|
- test/integration/cookbooks/test/recipes/default.rb
|
|
217
|
+
- test/integration/cookbooks/test/recipes/prep_files.rb
|
|
201
218
|
- test/integration/docker_run.rb
|
|
202
219
|
- test/integration/docker_test.rb
|
|
203
220
|
- test/integration/docker_test_container.rb
|
|
@@ -220,6 +237,7 @@ files:
|
|
|
220
237
|
- test/unit/extras/file_common_test.rb
|
|
221
238
|
- test/unit/extras/linux_file_test.rb
|
|
222
239
|
- test/unit/extras/os_common_test.rb
|
|
240
|
+
- test/unit/extras/os_detect_linux_test.rb
|
|
223
241
|
- test/unit/extras/stat_test.rb
|
|
224
242
|
- test/unit/helper.rb
|
|
225
243
|
- test/unit/plugins/connection_test.rb
|
|
@@ -263,6 +281,7 @@ test_files:
|
|
|
263
281
|
- test/integration/chefignore
|
|
264
282
|
- test/integration/cookbooks/test/metadata.rb
|
|
265
283
|
- test/integration/cookbooks/test/recipes/default.rb
|
|
284
|
+
- test/integration/cookbooks/test/recipes/prep_files.rb
|
|
266
285
|
- test/integration/docker_run.rb
|
|
267
286
|
- test/integration/docker_test.rb
|
|
268
287
|
- test/integration/docker_test_container.rb
|
|
@@ -285,6 +304,7 @@ test_files:
|
|
|
285
304
|
- test/unit/extras/file_common_test.rb
|
|
286
305
|
- test/unit/extras/linux_file_test.rb
|
|
287
306
|
- test/unit/extras/os_common_test.rb
|
|
307
|
+
- test/unit/extras/os_detect_linux_test.rb
|
|
288
308
|
- test/unit/extras/stat_test.rb
|
|
289
309
|
- test/unit/helper.rb
|
|
290
310
|
- test/unit/plugins/connection_test.rb
|
|
@@ -296,4 +316,3 @@ test_files:
|
|
|
296
316
|
- test/unit/transports/mock_test.rb
|
|
297
317
|
- test/unit/transports/ssh_test.rb
|
|
298
318
|
- test/unit/version_test.rb
|
|
299
|
-
has_rdoc:
|