train-core 1.4.11 → 1.4.15
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/CHANGELOG.md +15 -7
- data/lib/train/errors.rb +8 -1
- data/lib/train/extras/command_wrapper.rb +11 -8
- data/lib/train/file/local/unix.rb +1 -1
- data/lib/train/file/remote/unix.rb +1 -1
- data/lib/train/platforms/detect/specifications/api.rb +2 -0
- data/lib/train/transports/mock.rb +177 -0
- data/lib/train/version.rb +1 -1
- data/train-core.gemspec +6 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7805799b5b97d3b08f81da4541c45e92387f2fdccd51d7e1acd399d5c3c6fff
|
4
|
+
data.tar.gz: b46ec1e385e9e23a963da63af3e40034bca9ff1e939160dc4314173ff381c212
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f99ac1e603296c34c3442fc6c0d2de422f8c55614b7dec1fbd921d04d64ef53b5e71074ef625834a638e8cf020b1ad93ea2d529f777a78981114272f385e8b7
|
7
|
+
data.tar.gz: f6eb84dcdc248671e1ec0df04ef5f9efc3651d2844962d54e8ac10aaf1cf6d2c0addbb92d7ab76a231cd81e4dbef310fe56652eb02ab891eb0f1b46f48e03d51
|
data/CHANGELOG.md
CHANGED
@@ -1,23 +1,31 @@
|
|
1
|
-
<!-- latest_release 1.4.
|
2
|
-
## [v1.4.
|
1
|
+
<!-- latest_release 1.4.15 -->
|
2
|
+
## [v1.4.15](https://github.com/inspec/train/tree/v1.4.15) (2018-06-14)
|
3
3
|
|
4
4
|
#### Merged Pull Requests
|
5
|
-
-
|
5
|
+
- Don't double-escape paths [#306](https://github.com/inspec/train/pull/306) ([voroniys](https://github.com/voroniys))
|
6
6
|
<!-- latest_release -->
|
7
7
|
|
8
|
-
<!-- release_rollup since=1.4.
|
9
|
-
### Changes since 1.4.
|
8
|
+
<!-- release_rollup since=1.4.11 -->
|
9
|
+
### Changes since 1.4.11 release
|
10
10
|
|
11
11
|
#### Merged Pull Requests
|
12
|
-
-
|
12
|
+
- Don't double-escape paths [#306](https://github.com/inspec/train/pull/306) ([voroniys](https://github.com/voroniys)) <!-- 1.4.15 -->
|
13
|
+
- Add the mock transport to train-core [#308](https://github.com/inspec/train/pull/308) ([jquick](https://github.com/jquick)) <!-- 1.4.14 -->
|
14
|
+
- Adding Oneview to platform detection. [#307](https://github.com/inspec/train/pull/307) ([skpaterson](https://github.com/skpaterson)) <!-- 1.4.13 -->
|
15
|
+
- Allow TrainError to provide a supplement reason [#303](https://github.com/chef/train/pull/303) ([marcparadise](https://github.com/marcparadise)) <!-- 1.4.12 -->
|
13
16
|
<!-- release_rollup -->
|
14
17
|
|
15
18
|
<!-- latest_stable_release -->
|
19
|
+
## [v1.4.11](https://github.com/chef/train/tree/v1.4.11) (2018-05-17)
|
20
|
+
|
21
|
+
#### Merged Pull Requests
|
22
|
+
- Add required env for azure shell msi headers [#302](https://github.com/chef/train/pull/302) ([jquick](https://github.com/jquick))
|
23
|
+
<!-- latest_stable_release -->
|
24
|
+
|
16
25
|
## [v1.4.10](https://github.com/chef/train/tree/v1.4.10) (2018-05-17)
|
17
26
|
|
18
27
|
#### Merged Pull Requests
|
19
28
|
- support sudo passwords for cisco [#301](https://github.com/chef/train/pull/301) ([arlimus](https://github.com/arlimus))
|
20
|
-
<!-- latest_stable_release -->
|
21
29
|
|
22
30
|
## [v1.4.9](https://github.com/chef/train/tree/v1.4.9) (2018-05-16)
|
23
31
|
|
data/lib/train/errors.rb
CHANGED
@@ -10,7 +10,14 @@
|
|
10
10
|
|
11
11
|
module Train
|
12
12
|
# Base exception for any exception explicitly raised by the Train library.
|
13
|
-
class Error < ::StandardError
|
13
|
+
class Error < ::StandardError
|
14
|
+
attr_reader :reason
|
15
|
+
|
16
|
+
def initialize(message = '', reason = :not_provided)
|
17
|
+
super(message)
|
18
|
+
@reason = reason
|
19
|
+
end
|
20
|
+
end
|
14
21
|
|
15
22
|
# Base exception class for all exceptions that are caused by user input
|
16
23
|
# errors.
|
@@ -58,15 +58,15 @@ module Train::Extras
|
|
58
58
|
rawerr = res.stdout + ' ' + res.stderr
|
59
59
|
|
60
60
|
{
|
61
|
-
'Sorry, try again' => 'Wrong sudo password.',
|
61
|
+
'Sorry, try again' => ['Wrong sudo password.', :bad_sudo_password],
|
62
62
|
'sudo: no tty present and no askpass program specified' =>
|
63
|
-
'Sudo requires a password, please configure it.',
|
63
|
+
['Sudo requires a password, please configure it.', :sudo_password_required],
|
64
64
|
'sudo: command not found' =>
|
65
|
-
"Can't find sudo command. Please either install and "\
|
66
|
-
'configure it on the target or deactivate sudo.',
|
65
|
+
["Can't find sudo command. Please either install and "\
|
66
|
+
'configure it on the target or deactivate sudo.', :sudo_command_not_found],
|
67
67
|
'sudo: sorry, you must have a tty to run sudo' =>
|
68
|
-
'Sudo requires a TTY. Please see the README on how to configure '\
|
69
|
-
'sudo to allow for non-interactive usage.',
|
68
|
+
['Sudo requires a TTY. Please see the README on how to configure '\
|
69
|
+
'sudo to allow for non-interactive usage.', :sudo_no_tty],
|
70
70
|
}.each do |sudo, human|
|
71
71
|
rawerr = human if rawerr.include? sudo
|
72
72
|
end
|
@@ -128,8 +128,11 @@ module Train::Extras
|
|
128
128
|
if transport.os.unix?
|
129
129
|
return nil unless LinuxCommand.active?(options)
|
130
130
|
res = LinuxCommand.new(transport, options)
|
131
|
-
|
132
|
-
|
131
|
+
verification_res = res.verify
|
132
|
+
if verification_res
|
133
|
+
msg, reason = verification_res
|
134
|
+
raise Train::UserError.new("Sudo failed: #{msg}", reason)
|
135
|
+
end
|
133
136
|
res
|
134
137
|
end
|
135
138
|
end
|
@@ -11,6 +11,8 @@ module Train::Platforms::Detect::Specifications
|
|
11
11
|
plat.name('aws').in_family('cloud')
|
12
12
|
plat.name('azure').in_family('cloud')
|
13
13
|
plat.name('gcp').in_family('cloud')
|
14
|
+
plat.family('iaas').in_family('api')
|
15
|
+
plat.name('oneview').in_family('iaas')
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'train/plugins'
|
4
|
+
require 'digest'
|
5
|
+
|
6
|
+
module Train::Transports
|
7
|
+
class Mock < Train.plugin(1)
|
8
|
+
name 'mock'
|
9
|
+
|
10
|
+
def initialize(conf = nil)
|
11
|
+
@conf = conf || {}
|
12
|
+
trace_calls if @conf[:trace]
|
13
|
+
end
|
14
|
+
|
15
|
+
def connection
|
16
|
+
@connection ||= Connection.new(@conf)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
'Mock Transport'
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def trace_calls
|
26
|
+
interface_methods = {
|
27
|
+
'Train::Transports::Mock' =>
|
28
|
+
Train::Transports::Mock.instance_methods(false),
|
29
|
+
'Train::Transports::Mock::Connection' =>
|
30
|
+
Connection.instance_methods(false),
|
31
|
+
'Train::Transports::Mock::Connection::File' =>
|
32
|
+
Connection::FileCommon.instance_methods(false),
|
33
|
+
'Train::Transports::Mock::Connection::OS' =>
|
34
|
+
Train::Platform.instance_methods(false),
|
35
|
+
}
|
36
|
+
|
37
|
+
# rubocop:disable Metrics/ParameterLists
|
38
|
+
# rubocop:disable Lint/Eval
|
39
|
+
set_trace_func proc { |event, _file, _line, id, binding, classname|
|
40
|
+
unless classname.to_s.start_with?('Train::Transports::Mock') and
|
41
|
+
event == 'call' and
|
42
|
+
interface_methods[classname.to_s].include?(id)
|
43
|
+
next
|
44
|
+
end
|
45
|
+
# kindly borrowed from the wonderful simple-tracer by matugm
|
46
|
+
arg_names = eval(
|
47
|
+
'method(__method__).parameters.map { |arg| arg[1].to_s }',
|
48
|
+
binding)
|
49
|
+
args = eval("#{arg_names}.map { |arg| eval(arg) }", binding).join(', ')
|
50
|
+
prefix = '-' * (classname.to_s.count(':') - 2) + '> '
|
51
|
+
puts("#{prefix}#{id} #{args}")
|
52
|
+
}
|
53
|
+
# rubocop:enable all
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Train::Transports::Mock
|
59
|
+
class Connection < BaseConnection
|
60
|
+
attr_reader :options
|
61
|
+
|
62
|
+
def initialize(conf = nil)
|
63
|
+
super(conf)
|
64
|
+
mock_os
|
65
|
+
enable_cache(:file)
|
66
|
+
enable_cache(:command)
|
67
|
+
end
|
68
|
+
|
69
|
+
def uri
|
70
|
+
'mock://'
|
71
|
+
end
|
72
|
+
|
73
|
+
def mock_os(value = {})
|
74
|
+
# if a user passes a nil value, set to an empty hash so the merge still succeeds
|
75
|
+
value ||= {}
|
76
|
+
value.each { |k, v| value[k] = 'unknown' if v.nil? }
|
77
|
+
value = { name: 'mock', family: 'mock', release: 'unknown', arch: 'unknown' }.merge(value)
|
78
|
+
|
79
|
+
platform = Train::Platforms.name(value[:name])
|
80
|
+
platform.family_hierarchy = family_hierarchy(platform).flatten
|
81
|
+
platform.platform = value
|
82
|
+
platform.add_platform_methods
|
83
|
+
@platform = platform
|
84
|
+
end
|
85
|
+
|
86
|
+
def commands=(commands)
|
87
|
+
@cache[:command] = commands
|
88
|
+
end
|
89
|
+
|
90
|
+
def commands
|
91
|
+
@cache[:command]
|
92
|
+
end
|
93
|
+
|
94
|
+
def files=(files)
|
95
|
+
@cache[:file] = files
|
96
|
+
end
|
97
|
+
|
98
|
+
def files
|
99
|
+
@cache[:file]
|
100
|
+
end
|
101
|
+
|
102
|
+
def mock_command(cmd, stdout = nil, stderr = nil, exit_status = 0)
|
103
|
+
@cache[:command][cmd] = Command.new(stdout || '', stderr || '', exit_status)
|
104
|
+
end
|
105
|
+
|
106
|
+
def command_not_found(cmd)
|
107
|
+
if @options[:verbose]
|
108
|
+
STDERR.puts('Command not mocked:')
|
109
|
+
STDERR.puts(' '+cmd.to_s.split("\n").join("\n "))
|
110
|
+
STDERR.puts(' SHA: ' + Digest::SHA256.hexdigest(cmd.to_s))
|
111
|
+
end
|
112
|
+
# return a non-zero exit code
|
113
|
+
mock_command(cmd, nil, nil, 1)
|
114
|
+
end
|
115
|
+
|
116
|
+
def file_not_found(path)
|
117
|
+
STDERR.puts('File not mocked: '+path.to_s) if @options[:verbose]
|
118
|
+
File.new(self, path)
|
119
|
+
end
|
120
|
+
|
121
|
+
def to_s
|
122
|
+
'Mock Connection'
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def run_command_via_connection(cmd)
|
128
|
+
@cache[:command][Digest::SHA256.hexdigest cmd.to_s] ||
|
129
|
+
command_not_found(cmd)
|
130
|
+
end
|
131
|
+
|
132
|
+
def file_via_connection(path)
|
133
|
+
file_not_found(path)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Train::Transports::Mock::Connection
|
139
|
+
Command = Struct.new(:stdout, :stderr, :exit_status)
|
140
|
+
end
|
141
|
+
|
142
|
+
class Train::Transports::Mock::Connection
|
143
|
+
class File < Train::File
|
144
|
+
def self.from_json(json)
|
145
|
+
res = new(json['backend'],
|
146
|
+
json['path'],
|
147
|
+
json['follow_symlink'])
|
148
|
+
res.type = json['type']
|
149
|
+
Train::File::DATA_FIELDS.each do |f|
|
150
|
+
m = (f.tr('?', '') + '=').to_sym
|
151
|
+
res.method(m).call(json[f])
|
152
|
+
end
|
153
|
+
res
|
154
|
+
end
|
155
|
+
|
156
|
+
Train::File::DATA_FIELDS.each do |m|
|
157
|
+
attr_accessor m.tr('?', '').to_sym
|
158
|
+
next unless m.include?('?')
|
159
|
+
|
160
|
+
define_method m.to_sym do
|
161
|
+
method(m.tr('?', '').to_sym).call
|
162
|
+
end
|
163
|
+
end
|
164
|
+
attr_accessor :type
|
165
|
+
|
166
|
+
def initialize(backend, path, follow_symlink = true)
|
167
|
+
super(backend, path, follow_symlink)
|
168
|
+
@type = :unknown
|
169
|
+
@exist = false
|
170
|
+
end
|
171
|
+
|
172
|
+
def mounted
|
173
|
+
@mounted ||=
|
174
|
+
@backend.run_command("mount | grep -- ' on #{@path}'")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/lib/train/version.rb
CHANGED
data/train-core.gemspec
CHANGED
@@ -3,6 +3,11 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'train/version'
|
5
5
|
|
6
|
+
CORE_TRANSPORTS = [
|
7
|
+
'lib/train/transports/local.rb',
|
8
|
+
'lib/train/transports/mock.rb',
|
9
|
+
].freeze
|
10
|
+
|
6
11
|
Gem::Specification.new do |spec|
|
7
12
|
spec.name = 'train-core'
|
8
13
|
spec.version = Train::VERSION
|
@@ -15,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
15
20
|
|
16
21
|
spec.files = %w{train-core.gemspec README.md LICENSE Gemfile CHANGELOG.md} + Dir
|
17
22
|
.glob('lib/**/*', File::FNM_DOTMATCH)
|
18
|
-
.reject { |f| f =~
|
23
|
+
.reject { |f| f =~ %r{lib/train/transports} unless CORE_TRANSPORTS.include?(f) }
|
19
24
|
.reject { |f| File.directory?(f) }
|
20
25
|
|
21
26
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: train-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-shellout
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- lib/train/plugins/base_connection.rb
|
88
88
|
- lib/train/plugins/transport.rb
|
89
89
|
- lib/train/transports/local.rb
|
90
|
+
- lib/train/transports/mock.rb
|
90
91
|
- lib/train/version.rb
|
91
92
|
- train-core.gemspec
|
92
93
|
homepage: https://github.com/chef/train/
|