train-core 1.4.11 → 1.4.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff59e268df6e0644952fce6ab783058d6be0ca2077272ca3a78c1060c23563f4
4
- data.tar.gz: 1a90a57d1ad91feb1778f114d319982d4f70560d29e98b38256b52b38f3d9bd3
3
+ metadata.gz: d7805799b5b97d3b08f81da4541c45e92387f2fdccd51d7e1acd399d5c3c6fff
4
+ data.tar.gz: b46ec1e385e9e23a963da63af3e40034bca9ff1e939160dc4314173ff381c212
5
5
  SHA512:
6
- metadata.gz: 88c791a6d0742f4ebf8eab8c665087c10fd0d43cb7db2ff51602e19dcc913c1af5043b58c8e51d6b4365e9c9438a574a37da567a2daac3675dc53747477bd418
7
- data.tar.gz: e9911e47a0a2ccccdb96bc92b3ac0bd8802be2080d42dcd45b5e548b057bcc13393e40b5f0b232081823b22721090e98b46577af542647484195bf36bb54585d
6
+ metadata.gz: 1f99ac1e603296c34c3442fc6c0d2de422f8c55614b7dec1fbd921d04d64ef53b5e71074ef625834a638e8cf020b1ad93ea2d529f777a78981114272f385e8b7
7
+ data.tar.gz: f6eb84dcdc248671e1ec0df04ef5f9efc3651d2844962d54e8ac10aaf1cf6d2c0addbb92d7ab76a231cd81e4dbef310fe56652eb02ab891eb0f1b46f48e03d51
data/CHANGELOG.md CHANGED
@@ -1,23 +1,31 @@
1
- <!-- latest_release 1.4.11 -->
2
- ## [v1.4.11](https://github.com/chef/train/tree/v1.4.11) (2018-05-17)
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
- - Add required env for azure shell msi headers [#302](https://github.com/chef/train/pull/302) ([jquick](https://github.com/jquick))
5
+ - Don&#39;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.10 -->
9
- ### Changes since 1.4.10 release
8
+ <!-- release_rollup since=1.4.11 -->
9
+ ### Changes since 1.4.11 release
10
10
 
11
11
  #### Merged Pull Requests
12
- - Add required env for azure shell msi headers [#302](https://github.com/chef/train/pull/302) ([jquick](https://github.com/jquick)) <!-- 1.4.11 -->
12
+ - Don&#39;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; end
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
- msg = res.verify
132
- fail Train::UserError, "Sudo failed: #{msg}" unless msg.nil?
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
@@ -47,7 +47,7 @@ module Train
47
47
 
48
48
  def mounted
49
49
  @mounted ||=
50
- @backend.run_command("mount | grep -- ' on #{@spath} '")
50
+ @backend.run_command("mount | grep -- ' on #{@path} '")
51
51
  end
52
52
 
53
53
  def grouped_into?(sth)
@@ -33,7 +33,7 @@ module Train
33
33
 
34
34
  def mounted
35
35
  @mounted ||=
36
- @backend.run_command("mount | grep -- ' on #{@spath} '")
36
+ @backend.run_command("mount | grep -- ' on #{@path} '")
37
37
  end
38
38
 
39
39
  %w{
@@ -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
@@ -3,5 +3,5 @@
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
 
5
5
  module Train
6
- VERSION = '1.4.11'.freeze
6
+ VERSION = '1.4.15'.freeze
7
7
  end
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 =~ /^(?!.*(local.rb)).*transports/ }
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.11
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-05-17 00:00:00.000000000 Z
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/