winrm-transport 1.0.3 → 1.0.4
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 +4 -0
- data/lib/winrm/transport/command_executor.rb +217 -217
- data/lib/winrm/transport/version.rb +1 -1
- data/winrm-transport.gemspec +2 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ca52f34c3f6b0ff2f00ece7df30f643f1550cad
|
4
|
+
data.tar.gz: 6ed1f20e933dc8f8b66e85b7baf8d8b0b2b000c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff8c18ab5f56d00ccc1ba7625de74d7d05c3bd1df2a053454dde0e236e10f808c13443311e77dbe9d31f2da0b7ad743049727925f07724796a4e42450fc24ed4
|
7
|
+
data.tar.gz: de9e5d01d7774e9eb3a76d22ddd12bc56eb1907554f4074ff1d88489be2e02c0cd7fdeb6c8b98024a8b469cc66e090244a0675669fd53b685418ce171b994a5a
|
data/CHANGELOG.md
CHANGED
@@ -1,217 +1,217 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
#
|
3
|
-
# Author:: Matt Wrock (<matt@mattwrock.com>)
|
4
|
-
#
|
5
|
-
# Copyright (C) 2014, Matt Wrock
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
|
19
|
-
require "winrm/transport/logging"
|
20
|
-
|
21
|
-
module WinRM
|
22
|
-
|
23
|
-
module Transport
|
24
|
-
|
25
|
-
# Object which can execute multiple commands and Powershell scripts in
|
26
|
-
# one shared remote shell session. The maximum number of commands per
|
27
|
-
# shell is determined by interrogating the remote host when the session
|
28
|
-
# is opened and the remote shell is automatically recycled before the
|
29
|
-
# threshold is reached.
|
30
|
-
#
|
31
|
-
# @author Matt Wrock <matt@mattwrock.com>
|
32
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
33
|
-
class CommandExecutor
|
34
|
-
|
35
|
-
include Logging
|
36
|
-
|
37
|
-
# @return [Integer,nil] the safe maximum number of commands that can
|
38
|
-
# be executed in one remote shell session, or `nil` if the
|
39
|
-
# threshold has not yet been determined
|
40
|
-
attr_reader :max_commands
|
41
|
-
|
42
|
-
# @return [String,nil] the identifier for the current open remote
|
43
|
-
# shell session, or `nil` if the session is not open
|
44
|
-
attr_reader :shell
|
45
|
-
|
46
|
-
# Creates a CommandExecutor given a `WinRM::WinRMWebService` object.
|
47
|
-
#
|
48
|
-
# @param service [WinRM::WinRMWebService] a winrm web service object
|
49
|
-
# @param logger [#debug,#info] an optional logger/ui object that
|
50
|
-
# responds to `#debug` and `#info` (default: `nil`)
|
51
|
-
# @param closer [ShellCloser] an optional object to automatically
|
52
|
-
# close the active open remote shell when CommandExecutor garbarge
|
53
|
-
# collects
|
54
|
-
def initialize(service, logger = nil, closer = nil)
|
55
|
-
@service = service
|
56
|
-
@logger = logger
|
57
|
-
@closer = closer
|
58
|
-
@command_count = 0
|
59
|
-
end
|
60
|
-
|
61
|
-
# Closes the open remote shell session. This method can be called
|
62
|
-
# multiple times, even if there is no open session.
|
63
|
-
def close
|
64
|
-
return if shell.nil?
|
65
|
-
|
66
|
-
service.close_shell(shell)
|
67
|
-
remove_finalizer
|
68
|
-
@shell = nil
|
69
|
-
end
|
70
|
-
|
71
|
-
# Opens a remote shell session for reuse. The maxiumum
|
72
|
-
# command-per-shell threshold is also determined the first time this
|
73
|
-
# method is invoked and cached for later invocations.
|
74
|
-
#
|
75
|
-
# @return [String] the remote shell session indentifier
|
76
|
-
def open
|
77
|
-
close
|
78
|
-
@shell = service.open_shell
|
79
|
-
add_finalizer(shell)
|
80
|
-
@command_count = 0
|
81
|
-
determine_max_commands unless max_commands
|
82
|
-
shell
|
83
|
-
end
|
84
|
-
|
85
|
-
# Runs a CMD command.
|
86
|
-
#
|
87
|
-
# @param command [String] the command to run on the remote system
|
88
|
-
# @param arguments [Array<String>] arguments to the command
|
89
|
-
# @yield [stdout, stderr] yields more live access the standard
|
90
|
-
# output and standard error streams as they are returns, if
|
91
|
-
# streaming behavior is desired
|
92
|
-
# @return [WinRM::Output] output object with stdout, stderr, and
|
93
|
-
# exit code
|
94
|
-
def run_cmd(command, arguments = [], &block)
|
95
|
-
reset if command_count_exceeded?
|
96
|
-
ensure_open_shell!
|
97
|
-
|
98
|
-
@command_count += 1
|
99
|
-
result = nil
|
100
|
-
service.run_command(shell, command, arguments) do |command_id|
|
101
|
-
result = service.get_command_output(shell, command_id, &block)
|
102
|
-
end
|
103
|
-
result
|
104
|
-
end
|
105
|
-
|
106
|
-
# Run a Powershell script that resides on the local box.
|
107
|
-
#
|
108
|
-
# @param script_file [IO,String] an IO reference for reading the
|
109
|
-
# Powershell script or the actual file contents
|
110
|
-
# @yield [stdout, stderr] yields more live access the standard
|
111
|
-
# output and standard error streams as they are returns, if
|
112
|
-
# streaming behavior is desired
|
113
|
-
# @return [WinRM::Output] output object with stdout, stderr, and
|
114
|
-
# exit code
|
115
|
-
def run_powershell_script(script_file, &block)
|
116
|
-
# this code looks overly compact in an attempt to limit local
|
117
|
-
# variable assignments that may contain large strings and
|
118
|
-
# consequently bloat the Ruby VM
|
119
|
-
run_cmd(
|
120
|
-
"powershell",
|
121
|
-
[
|
122
|
-
"-encodedCommand",
|
123
|
-
::WinRM::PowershellScript.new(
|
124
|
-
script_file.is_a?(IO) ? script_file.read : script_file
|
125
|
-
).encoded
|
126
|
-
],
|
127
|
-
&block
|
128
|
-
)
|
129
|
-
end
|
130
|
-
|
131
|
-
private
|
132
|
-
|
133
|
-
# @return [Integer] the default maximum number of commands which can be
|
134
|
-
# executed in one remote shell session on "older" versions of Windows
|
135
|
-
# @api private
|
136
|
-
LEGACY_LIMIT = 15
|
137
|
-
|
138
|
-
# @return [Integer] the default maximum number of commands which can be
|
139
|
-
# executed in one remote shell session on "modern" versions of Windows
|
140
|
-
# @api private
|
141
|
-
MODERN_LIMIT = 1500
|
142
|
-
|
143
|
-
# @return [String] the PowerShell command used to determine the version
|
144
|
-
# of Windows
|
145
|
-
# @api private
|
146
|
-
PS1_OS_VERSION = "[environment]::OSVersion.Version.tostring()".freeze
|
147
|
-
|
148
|
-
# @return [Integer] the number of executed commands on the remote
|
149
|
-
# shell session
|
150
|
-
# @api private
|
151
|
-
attr_accessor :command_count
|
152
|
-
|
153
|
-
# @return [#debug,#info] the logger
|
154
|
-
# @api private
|
155
|
-
attr_reader :logger
|
156
|
-
|
157
|
-
# @return [WinRM::WinRMWebService] a WinRM web service object
|
158
|
-
# @api private
|
159
|
-
attr_reader :service
|
160
|
-
|
161
|
-
# Creates a finalizer for this connection which will close the open
|
162
|
-
# remote shell session when the object is garabage collected or on
|
163
|
-
# Ruby VM shutdown.
|
164
|
-
#
|
165
|
-
# @param shell_id [String] the remote shell identifier
|
166
|
-
# @api private
|
167
|
-
def add_finalizer(shell_id)
|
168
|
-
ObjectSpace.define_finalizer(self, @closer.for(shell_id)) if @closer
|
169
|
-
end
|
170
|
-
|
171
|
-
# @return [true,false] whether or not the number of exeecuted commands
|
172
|
-
# have exceeded the maxiumum threshold
|
173
|
-
# @api private
|
174
|
-
def command_count_exceeded?
|
175
|
-
command_count > max_commands.to_i
|
176
|
-
end
|
177
|
-
|
178
|
-
# Ensures that there is an open remote shell session.
|
179
|
-
#
|
180
|
-
# @raise [WinRM::WinRMError] if there is no open shell
|
181
|
-
# @api private
|
182
|
-
def ensure_open_shell!
|
183
|
-
if shell.nil?
|
184
|
-
raise ::WinRM::WinRMError, "#{self.class}#open must be called " \
|
185
|
-
"before any run methods are invoked"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Determines the safe maximum number of commands that can be executed
|
190
|
-
# on a remote shell session by interrogating the remote host.
|
191
|
-
#
|
192
|
-
# @api private
|
193
|
-
def determine_max_commands
|
194
|
-
os_version = run_powershell_script(PS1_OS_VERSION).stdout.chomp
|
195
|
-
@max_commands = os_version < "6.2" ? LEGACY_LIMIT : MODERN_LIMIT
|
196
|
-
@max_commands -= 2 # to be safe
|
197
|
-
end
|
198
|
-
|
199
|
-
# Removes any finalizers for this connection.
|
200
|
-
#
|
201
|
-
# @api private
|
202
|
-
def remove_finalizer
|
203
|
-
ObjectSpace.undefine_finalizer(self) if @closer
|
204
|
-
end
|
205
|
-
|
206
|
-
# Closes the remote shell session and opens a new one.
|
207
|
-
#
|
208
|
-
# @api private
|
209
|
-
def reset
|
210
|
-
debug {
|
211
|
-
"Resetting WinRM shell (Max command limit is #{max_commands})"
|
212
|
-
}
|
213
|
-
open
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Matt Wrock (<matt@mattwrock.com>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2014, Matt Wrock
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require "winrm/transport/logging"
|
20
|
+
|
21
|
+
module WinRM
|
22
|
+
|
23
|
+
module Transport
|
24
|
+
|
25
|
+
# Object which can execute multiple commands and Powershell scripts in
|
26
|
+
# one shared remote shell session. The maximum number of commands per
|
27
|
+
# shell is determined by interrogating the remote host when the session
|
28
|
+
# is opened and the remote shell is automatically recycled before the
|
29
|
+
# threshold is reached.
|
30
|
+
#
|
31
|
+
# @author Matt Wrock <matt@mattwrock.com>
|
32
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
33
|
+
class CommandExecutor
|
34
|
+
|
35
|
+
include Logging
|
36
|
+
|
37
|
+
# @return [Integer,nil] the safe maximum number of commands that can
|
38
|
+
# be executed in one remote shell session, or `nil` if the
|
39
|
+
# threshold has not yet been determined
|
40
|
+
attr_reader :max_commands
|
41
|
+
|
42
|
+
# @return [String,nil] the identifier for the current open remote
|
43
|
+
# shell session, or `nil` if the session is not open
|
44
|
+
attr_reader :shell
|
45
|
+
|
46
|
+
# Creates a CommandExecutor given a `WinRM::WinRMWebService` object.
|
47
|
+
#
|
48
|
+
# @param service [WinRM::WinRMWebService] a winrm web service object
|
49
|
+
# @param logger [#debug,#info] an optional logger/ui object that
|
50
|
+
# responds to `#debug` and `#info` (default: `nil`)
|
51
|
+
# @param closer [ShellCloser] an optional object to automatically
|
52
|
+
# close the active open remote shell when CommandExecutor garbarge
|
53
|
+
# collects
|
54
|
+
def initialize(service, logger = nil, closer = nil)
|
55
|
+
@service = service
|
56
|
+
@logger = logger
|
57
|
+
@closer = closer
|
58
|
+
@command_count = 0
|
59
|
+
end
|
60
|
+
|
61
|
+
# Closes the open remote shell session. This method can be called
|
62
|
+
# multiple times, even if there is no open session.
|
63
|
+
def close
|
64
|
+
return if shell.nil?
|
65
|
+
|
66
|
+
service.close_shell(shell)
|
67
|
+
remove_finalizer
|
68
|
+
@shell = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# Opens a remote shell session for reuse. The maxiumum
|
72
|
+
# command-per-shell threshold is also determined the first time this
|
73
|
+
# method is invoked and cached for later invocations.
|
74
|
+
#
|
75
|
+
# @return [String] the remote shell session indentifier
|
76
|
+
def open
|
77
|
+
close
|
78
|
+
@shell = service.open_shell
|
79
|
+
add_finalizer(shell)
|
80
|
+
@command_count = 0
|
81
|
+
determine_max_commands unless max_commands
|
82
|
+
shell
|
83
|
+
end
|
84
|
+
|
85
|
+
# Runs a CMD command.
|
86
|
+
#
|
87
|
+
# @param command [String] the command to run on the remote system
|
88
|
+
# @param arguments [Array<String>] arguments to the command
|
89
|
+
# @yield [stdout, stderr] yields more live access the standard
|
90
|
+
# output and standard error streams as they are returns, if
|
91
|
+
# streaming behavior is desired
|
92
|
+
# @return [WinRM::Output] output object with stdout, stderr, and
|
93
|
+
# exit code
|
94
|
+
def run_cmd(command, arguments = [], &block)
|
95
|
+
reset if command_count_exceeded?
|
96
|
+
ensure_open_shell!
|
97
|
+
|
98
|
+
@command_count += 1
|
99
|
+
result = nil
|
100
|
+
service.run_command(shell, command, arguments) do |command_id|
|
101
|
+
result = service.get_command_output(shell, command_id, &block)
|
102
|
+
end
|
103
|
+
result
|
104
|
+
end
|
105
|
+
|
106
|
+
# Run a Powershell script that resides on the local box.
|
107
|
+
#
|
108
|
+
# @param script_file [IO,String] an IO reference for reading the
|
109
|
+
# Powershell script or the actual file contents
|
110
|
+
# @yield [stdout, stderr] yields more live access the standard
|
111
|
+
# output and standard error streams as they are returns, if
|
112
|
+
# streaming behavior is desired
|
113
|
+
# @return [WinRM::Output] output object with stdout, stderr, and
|
114
|
+
# exit code
|
115
|
+
def run_powershell_script(script_file, &block)
|
116
|
+
# this code looks overly compact in an attempt to limit local
|
117
|
+
# variable assignments that may contain large strings and
|
118
|
+
# consequently bloat the Ruby VM
|
119
|
+
run_cmd(
|
120
|
+
"powershell",
|
121
|
+
[
|
122
|
+
"-encodedCommand",
|
123
|
+
::WinRM::PowershellScript.new(
|
124
|
+
script_file.is_a?(IO) ? script_file.read : script_file
|
125
|
+
).encoded
|
126
|
+
],
|
127
|
+
&block
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# @return [Integer] the default maximum number of commands which can be
|
134
|
+
# executed in one remote shell session on "older" versions of Windows
|
135
|
+
# @api private
|
136
|
+
LEGACY_LIMIT = 15
|
137
|
+
|
138
|
+
# @return [Integer] the default maximum number of commands which can be
|
139
|
+
# executed in one remote shell session on "modern" versions of Windows
|
140
|
+
# @api private
|
141
|
+
MODERN_LIMIT = 1500
|
142
|
+
|
143
|
+
# @return [String] the PowerShell command used to determine the version
|
144
|
+
# of Windows
|
145
|
+
# @api private
|
146
|
+
PS1_OS_VERSION = "[environment]::OSVersion.Version.tostring()".freeze
|
147
|
+
|
148
|
+
# @return [Integer] the number of executed commands on the remote
|
149
|
+
# shell session
|
150
|
+
# @api private
|
151
|
+
attr_accessor :command_count
|
152
|
+
|
153
|
+
# @return [#debug,#info] the logger
|
154
|
+
# @api private
|
155
|
+
attr_reader :logger
|
156
|
+
|
157
|
+
# @return [WinRM::WinRMWebService] a WinRM web service object
|
158
|
+
# @api private
|
159
|
+
attr_reader :service
|
160
|
+
|
161
|
+
# Creates a finalizer for this connection which will close the open
|
162
|
+
# remote shell session when the object is garabage collected or on
|
163
|
+
# Ruby VM shutdown.
|
164
|
+
#
|
165
|
+
# @param shell_id [String] the remote shell identifier
|
166
|
+
# @api private
|
167
|
+
def add_finalizer(shell_id)
|
168
|
+
ObjectSpace.define_finalizer(self, @closer.for(shell_id)) if @closer
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [true,false] whether or not the number of exeecuted commands
|
172
|
+
# have exceeded the maxiumum threshold
|
173
|
+
# @api private
|
174
|
+
def command_count_exceeded?
|
175
|
+
command_count > max_commands.to_i
|
176
|
+
end
|
177
|
+
|
178
|
+
# Ensures that there is an open remote shell session.
|
179
|
+
#
|
180
|
+
# @raise [WinRM::WinRMError] if there is no open shell
|
181
|
+
# @api private
|
182
|
+
def ensure_open_shell!
|
183
|
+
if shell.nil?
|
184
|
+
raise ::WinRM::WinRMError, "#{self.class}#open must be called " \
|
185
|
+
"before any run methods are invoked"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Determines the safe maximum number of commands that can be executed
|
190
|
+
# on a remote shell session by interrogating the remote host.
|
191
|
+
#
|
192
|
+
# @api private
|
193
|
+
def determine_max_commands
|
194
|
+
os_version = run_powershell_script(PS1_OS_VERSION).stdout.chomp
|
195
|
+
@max_commands = os_version < "6.2" ? LEGACY_LIMIT : MODERN_LIMIT
|
196
|
+
@max_commands -= 2 # to be safe
|
197
|
+
end
|
198
|
+
|
199
|
+
# Removes any finalizers for this connection.
|
200
|
+
#
|
201
|
+
# @api private
|
202
|
+
def remove_finalizer
|
203
|
+
ObjectSpace.undefine_finalizer(self) if @closer
|
204
|
+
end
|
205
|
+
|
206
|
+
# Closes the remote shell session and opens a new one.
|
207
|
+
#
|
208
|
+
# @api private
|
209
|
+
def reset
|
210
|
+
debug {
|
211
|
+
"Resetting WinRM shell (Max command limit is #{max_commands})"
|
212
|
+
}
|
213
|
+
open
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/winrm-transport.gemspec
CHANGED
@@ -10,7 +10,8 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ["Fletcher Nichol"]
|
11
11
|
spec.email = ["fnichol@nichol.ca"]
|
12
12
|
|
13
|
-
spec.summary = "
|
13
|
+
spec.summary = "[DEPRECATED] Please use the WinRM gem instead. " \
|
14
|
+
"WinRM transport logic for re-using remote shells " \
|
14
15
|
"and uploading files. The original code was extracted " \
|
15
16
|
"from the Test Kitchen project and remains the " \
|
16
17
|
"primary reference use case."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winrm-transport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fletcher Nichol
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: winrm
|
@@ -198,9 +198,9 @@ dependencies:
|
|
198
198
|
- - '='
|
199
199
|
- !ruby/object:Gem::Version
|
200
200
|
version: 2.6.2
|
201
|
-
description:
|
202
|
-
|
203
|
-
reference use case.
|
201
|
+
description: "[DEPRECATED] Please use the WinRM gem instead. WinRM transport logic
|
202
|
+
for re-using remote shells and uploading files. The original code was extracted
|
203
|
+
from the Test Kitchen project and remains the primary reference use case."
|
204
204
|
email:
|
205
205
|
- fnichol@nichol.ca
|
206
206
|
executables: []
|
@@ -248,11 +248,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
248
|
version: '0'
|
249
249
|
requirements: []
|
250
250
|
rubyforge_project:
|
251
|
-
rubygems_version: 2.
|
251
|
+
rubygems_version: 2.6.8
|
252
252
|
signing_key:
|
253
253
|
specification_version: 4
|
254
|
-
summary:
|
255
|
-
|
256
|
-
reference use case.
|
254
|
+
summary: "[DEPRECATED] Please use the WinRM gem instead. WinRM transport logic for
|
255
|
+
re-using remote shells and uploading files. The original code was extracted from
|
256
|
+
the Test Kitchen project and remains the primary reference use case."
|
257
257
|
test_files: []
|
258
258
|
has_rdoc:
|