train 0.18.0 → 0.19.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bef12aa9d490abb7a8b9e33416f0073bbc4fe3f
4
- data.tar.gz: b66c3e02c956534b72cc9b7b4b3026203abf2f77
3
+ metadata.gz: c99003b292f41d03c790974f1aabd9b0ad7792cf
4
+ data.tar.gz: 7b2ffa667c8eba8fe0440a8a63483f88f19a4aa5
5
5
  SHA512:
6
- metadata.gz: 803a0fdf661f82aefb707e3fe8f6aeba968cf04571ed58b851198a79d2a169ea58a70cc806e06fa7d025eab6e48e56b57192f16865fa83e6cd839933ac9280e6
7
- data.tar.gz: d37fa6a60ce6dc33a12d3d5972a8341b2ee52667c9a4cbd1d733ed7e00504572842d722ac7ae70e344e5e81888489d789731660faafd45944db753137effa3e8
6
+ metadata.gz: df622e11873f9e6583ced3fed9c953a513aa3dd0acdf4bc2c2ec5f60f81f64220691e08a45e729937257e62ab19f38aed9e548614a004cbe471655393e671b06
7
+ data.tar.gz: 709616bea4c244942aa2d0d8929a27a140090b93b55b37e4edcd9cb68033b925d981810328ed69b904cfb323b89ebfecacd75a8bcdf2baf14e205357f05e45a7
data/CHANGELOG.md CHANGED
@@ -1,7 +1,19 @@
1
1
  # Change Log
2
2
 
3
- ## [0.18.0](https://github.com/chef/train/tree/0.18.0) (2016-08-26)
4
- [Full Changelog](https://github.com/chef/train/compare/v0.17.0...0.18.0)
3
+ ## [0.19.0](https://github.com/chef/train/tree/0.19.0) (2016-09-05)
4
+ [Full Changelog](https://github.com/chef/train/compare/v0.18.0...0.19.0)
5
+
6
+ **Fixed bugs:**
7
+
8
+ - use stat -c for alpine linux [\#146](https://github.com/chef/train/pull/146) ([chris-rock](https://github.com/chris-rock))
9
+
10
+ **Merged pull requests:**
11
+
12
+ - support ruby 2.2.1 [\#145](https://github.com/chef/train/pull/145) ([chris-rock](https://github.com/chris-rock))
13
+ - Use winrm v2 implementation [\#122](https://github.com/chef/train/pull/122) ([mwrock](https://github.com/mwrock))
14
+
15
+ ## [v0.18.0](https://github.com/chef/train/tree/v0.18.0) (2016-08-26)
16
+ [Full Changelog](https://github.com/chef/train/compare/v0.17.0...v0.18.0)
5
17
 
6
18
  **Merged pull requests:**
7
19
 
data/Gemfile CHANGED
@@ -8,7 +8,7 @@ if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('1.9.3')
8
8
  gem 'net-ssh', '~> 2.9'
9
9
  end
10
10
 
11
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2')
11
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
12
12
  gem 'json', '< 2.0'
13
13
  gem 'rack', '< 2.0'
14
14
  end
data/README.md CHANGED
@@ -101,6 +101,12 @@ We perform `unit`, `integration` and `windows` tests.
101
101
  * `integration` tests run against VMs and docker containers
102
102
  * `windows` tests that run on appveyor for windows integration tests
103
103
 
104
+ ## Mac/Linux
105
+
106
+ ```
107
+ bundle exec ruby -W -Ilib:test/unit test/unit/extras/stat_test.rb
108
+ ```
109
+
104
110
  ## Windows
105
111
 
106
112
  ```
@@ -3,7 +3,6 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  require 'base64'
6
- require 'winrm'
7
6
  require 'train/errors'
8
7
 
9
8
  module Train::Extras
@@ -114,15 +113,22 @@ module Train::Extras
114
113
  # especially in local mode, we cannot be sure that we get a Powershell
115
114
  # we may just get a `cmd`.
116
115
  # TODO: we may want to opt for powershell.exe -command instead of `encodeCommand`
117
- "powershell -encodedCommand #{WinRM::PowershellScript.new(safe_script(script)).encoded}"
116
+ "powershell -encodedCommand #{encoded(safe_script(script))}"
118
117
  end
119
118
 
120
- # reused from https://github.com/WinRb/WinRM/blob/master/lib/winrm/command_executor.rb
121
119
  # suppress the progress stream from leaking to stderr
122
120
  def safe_script(script)
123
121
  "$ProgressPreference='SilentlyContinue';" + script
124
122
  end
125
123
 
124
+ # Encodes the script so that it can be passed to the PowerShell
125
+ # --EncodedCommand argument.
126
+ # @return [String] The UTF-16LE base64 encoded script
127
+ def encoded(script)
128
+ encoded_script = safe_script(script).encode('UTF-16LE', 'UTF-8')
129
+ Base64.strict_encode64(encoded_script)
130
+ end
131
+
126
132
  def to_s
127
133
  'PowerShell CommandWrapper'
128
134
  end
@@ -34,9 +34,8 @@ module Train::Extras
34
34
 
35
35
  def self.linux_stat(shell_escaped_path, backend, follow_symlink)
36
36
  lstat = follow_symlink ? ' -L' : ''
37
- format = backend.os.esx? ? '-c' : '--printf'
37
+ format = (backend.os.esx? || backend.os[:name] == 'alpine') ? '-c' : '--printf'
38
38
  res = backend.run_command("stat#{lstat} #{shell_escaped_path} 2>/dev/null #{format} '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'")
39
-
40
39
  # ignore the exit_code: it is != 0 if selinux labels are not supported
41
40
  # on the system.
42
41
 
@@ -89,7 +89,7 @@ module Train::Transports
89
89
  opts[:endpoint] = "#{scheme}://#{opts[:host]}:#{port}/#{path}"
90
90
  end
91
91
 
92
- WINRM_FS_SPEC_VERSION = '~> 0.3'.freeze
92
+ WINRM_FS_SPEC_VERSION = '~> 1.0'.freeze
93
93
 
94
94
  # Builds the hash of options needed by the Connection object on
95
95
  # construction.
@@ -100,12 +100,12 @@ module Train::Transports
100
100
  def connection_options(opts)
101
101
  {
102
102
  logger: logger,
103
- winrm_transport: :negotiate,
103
+ transport: :negotiate,
104
104
  disable_sspi: false,
105
105
  basic_auth_only: false,
106
106
  endpoint: opts[:endpoint],
107
107
  user: opts[:user],
108
- pass: opts[:password],
108
+ password: opts[:password],
109
109
  rdp_port: opts[:rdp_port],
110
110
  connection_retries: opts[:connection_retries],
111
111
  connection_retry_sleep: opts[:connection_retry_sleep],
@@ -30,9 +30,7 @@ class Train::Transports::WinRM
30
30
  class Connection < BaseConnection
31
31
  def initialize(options)
32
32
  super(options)
33
- @endpoint = @options.delete(:endpoint)
34
33
  @rdp_port = @options.delete(:rdp_port)
35
- @winrm_transport = @options.delete(:winrm_transport)
36
34
  @connection_retries = @options.delete(:connection_retries)
37
35
  @connection_retry_sleep = @options.delete(:connection_retry_sleep)
38
36
  @max_wait_until_ready = @options.delete(:max_wait_until_ready)
@@ -59,11 +57,11 @@ class Train::Transports::WinRM
59
57
  logger.debug("[WinRM] #{self} (#{command})")
60
58
  out = ''
61
59
 
62
- response = session.run_powershell_script(command) do |stdout, _|
60
+ response = session.run(command) do |stdout, _|
63
61
  out << stdout if stdout
64
62
  end
65
63
 
66
- CommandResult.new(out, response.stderr, response[:exitcode])
64
+ CommandResult.new(out, response.stderr, response.exitcode)
67
65
  end
68
66
 
69
67
  # (see Base::Connection#login_command)
@@ -98,7 +96,7 @@ class Train::Transports::WinRM
98
96
  end
99
97
 
100
98
  def uri
101
- "winrm://#{options[:user]}@#{@endpoint}:#{@rdp_port}"
99
+ "winrm://#{options[:user]}@#{options[:endpoint]}:#{@rdp_port}"
102
100
  end
103
101
 
104
102
  private
@@ -112,7 +110,7 @@ class Train::Transports::WinRM
112
110
  # Mac system
113
111
  # @api private
114
112
  def rdp_doc(opts = {})
115
- host = URI.parse(@endpoint).host
113
+ host = URI.parse(options[:endpoint]).host
116
114
  content = [
117
115
  "full address:s:#{host}:#{@rdp_port}",
118
116
  'prompt for credentials:i:1',
@@ -139,7 +137,7 @@ class Train::Transports::WinRM
139
137
  def login_command_for_linux
140
138
  args = %W( -u #{options[:user]} )
141
139
  args += %W( -p #{options[:pass]} ) if options.key?(:pass)
142
- args += %W( #{URI.parse(@endpoint).host}:#{@rdp_port} )
140
+ args += %W( #{URI.parse(options[:endpoint]).host}:#{@rdp_port} )
143
141
  LoginCommand.new('rdesktop', args)
144
142
  end
145
143
 
@@ -172,10 +170,9 @@ class Train::Transports::WinRM
172
170
  retry_delay: @connection_retry_sleep.to_i,
173
171
  }.merge(retry_options)
174
172
 
175
- service_args = [@endpoint, @winrm_transport, options.merge(opts)]
176
- @service = ::WinRM::WinRMWebService.new(*service_args)
173
+ @service = ::WinRM::Connection.new(options.merge(opts))
177
174
  @service.logger = logger
178
- @service.create_executor
175
+ @service.shell(:powershell)
179
176
  end
180
177
  end
181
178
 
@@ -184,7 +181,7 @@ class Train::Transports::WinRM
184
181
  #
185
182
  # @api private
186
183
  def to_s
187
- "#{@winrm_transport}::#{@endpoint}<#{options.inspect}>"
184
+ "<#{options.inspect}>"
188
185
  end
189
186
 
190
187
  class OS < OSCommon
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 = '0.18.0'.freeze
6
+ VERSION = '0.19.0'.freeze
7
7
  end
@@ -60,19 +60,3 @@ describe 'linux command' do
60
60
  lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | #{sudo_command} -S #{cmd}"
61
61
  end
62
62
  end
63
-
64
- describe 'powershell command' do
65
- let(:cls) { Train::Extras::PowerShellCommand }
66
- let(:cmd) { rand.to_s }
67
- let(:backend) {
68
- backend = Train::Transports::Mock.new.connection
69
- backend.mock_os({ family: 'windows' })
70
- backend
71
- }
72
-
73
- it 'wraps commands in powershell' do
74
- lc = cls.new(backend, {})
75
- tmp =
76
- lc.run(cmd).must_equal "powershell -encodedCommand #{WinRM::PowershellScript.new('$ProgressPreference=\'SilentlyContinue\';' + cmd).encoded}"
77
- end
78
- end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'helper'
3
3
  require 'train/extras'
4
+ require 'train/transports/mock'
4
5
 
5
6
  describe 'stat' do
6
7
  let(:cls) { Train::Extras::Stat }
@@ -42,27 +43,22 @@ describe 'stat' do
42
43
  end
43
44
 
44
45
  describe 'linux stat' do
45
- let(:backend) { Minitest::Mock.new }
46
+ let(:backend) {
47
+ mock = Train::Transports::Mock.new(verbose: true).connection
48
+ mock.mock_os({ name: 'ubuntu', family: 'debian', release: '15.04', arch: 'x86_64' })
49
+ mock.commands = {
50
+ "stat /path 2>/dev/null --printf '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
51
+ "stat /path-stat 2>/dev/null --printf '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
52
+ }
53
+ mock
54
+ }
46
55
 
47
56
  it 'ignores wrong stat results' do
48
- res = Minitest::Mock.new
49
- os = Minitest::Mock.new
50
- res.expect :stdout, ''
51
- os.expect :esx?, false
52
- backend.expect :os, os
53
- backend.expect :run_command, res, [String]
54
57
  cls.linux_stat('/path', backend, false).must_equal({})
55
58
  end
56
59
 
57
60
  it 'reads correct stat results' do
58
- res = Minitest::Mock.new
59
- os = Minitest::Mock.new
60
- # 43ff is 41777; linux_stat strips the 4
61
- res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?"
62
- os.expect :esx?, false
63
- backend.expect :os, os
64
- backend.expect :run_command, res, [String]
65
- cls.linux_stat('/path', backend, false).must_equal({
61
+ cls.linux_stat('/path-stat', backend, false).must_equal({
66
62
  type: :directory,
67
63
  mode: 01777,
68
64
  owner: 'root',
@@ -77,27 +73,52 @@ describe 'stat' do
77
73
  end
78
74
 
79
75
  describe 'esx stat' do
80
- let(:backend) { Minitest::Mock.new }
76
+ let(:backend) {
77
+ mock = Train::Transports::Mock.new(verbose: true).connection
78
+ mock.mock_os({ name: 'vmkernel', family: 'esx', release: '5' })
79
+ mock.commands = {
80
+ "stat /path 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
81
+ "stat /path-stat 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
82
+ }
83
+ mock
84
+ }
81
85
 
82
86
  it 'ignores wrong stat results' do
83
- res = Minitest::Mock.new
84
- os = Minitest::Mock.new
85
- res.expect :stdout, ''
86
- os.expect :esx?, true
87
- backend.expect :os, os
88
- backend.expect :run_command, res, [String]
89
87
  cls.linux_stat('/path', backend, false).must_equal({})
90
88
  end
91
89
 
92
90
  it 'reads correct stat results' do
93
- res = Minitest::Mock.new
94
- os = Minitest::Mock.new
95
- # 43ff is 41777; linux_stat strips the 4
96
- res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\nC"
97
- os.expect :esx?, true
98
- backend.expect :os, os
99
- backend.expect :run_command, res, [String]
100
- cls.linux_stat('/path', backend, false).must_equal({
91
+ cls.linux_stat('/path-stat', backend, false).must_equal({
92
+ type: :directory,
93
+ mode: 01777,
94
+ owner: 'root',
95
+ uid: 0,
96
+ group: 'rootz',
97
+ gid: 1,
98
+ mtime: 1444522445,
99
+ size: 360,
100
+ selinux_label: nil,
101
+ })
102
+ end
103
+ end
104
+
105
+ describe 'alpine stat' do
106
+ let(:backend) {
107
+ mock = Train::Transports::Mock.new(verbose: true).connection
108
+ mock.mock_os({ name: 'alpine', family: 'alpine', release: nil })
109
+ mock.commands = {
110
+ "stat /path 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
111
+ "stat /path-stat 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
112
+ }
113
+ mock
114
+ }
115
+
116
+ it 'ignores wrong stat results' do
117
+ cls.linux_stat('/path', backend, false).must_equal({})
118
+ end
119
+
120
+ it 'reads correct stat results' do
121
+ cls.linux_stat('/path-stat', backend, false).must_equal({
101
122
  type: :directory,
102
123
  mode: 01777,
103
124
  owner: 'root',
data/train.gemspec CHANGED
@@ -30,8 +30,8 @@ Gem::Specification.new do |spec|
30
30
  # 1.9 support is no longer needed here or for Inspec
31
31
  spec.add_dependency 'net-ssh', '>= 2.9', '< 4.0'
32
32
  spec.add_dependency 'net-scp', '~> 1.2'
33
- spec.add_dependency 'winrm', '~> 1.6'
34
- spec.add_dependency 'winrm-fs', '~> 0.3'
33
+ spec.add_dependency 'winrm', '~> 2.0'
34
+ spec.add_dependency 'winrm-fs', '~> 1.0'
35
35
  spec.add_dependency 'docker-api', '~> 1.26'
36
36
 
37
37
  spec.add_development_dependency 'mocha', '~> 1.1'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-26 00:00:00.000000000 Z
11
+ date: 2016-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -84,28 +84,28 @@ dependencies:
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '1.6'
87
+ version: '2.0'
88
88
  type: :runtime
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '1.6'
94
+ version: '2.0'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: winrm-fs
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0.3'
101
+ version: '1.0'
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: '0.3'
108
+ version: '1.0'
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: docker-api
111
111
  requirement: !ruby/object:Gem::Requirement