train 0.18.0 → 0.19.0

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
  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