vpsadmin-client 3.0.0.master.20190517.pre.0.3ab5ddfe → 3.0.0.master.20220121.pre.0.b5a81113

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
  SHA256:
3
- metadata.gz: e88be4aa43616fcca48c5a44a608568bbe5a17a820b601a4750b559e306eb789
4
- data.tar.gz: 93a4a8389faa06c619633113e3992deb7cbea545e0b5ee1814344d3d01f5fd83
3
+ metadata.gz: ce5635948bc213752357b413d4e92f8b7f2089306b9a3e02194b76f44f3617c3
4
+ data.tar.gz: 4304acd24bbecf0389a954d61ce680fece999e1128651f84e75306cf61889195
5
5
  SHA512:
6
- metadata.gz: 431461ad20a69847e7d4c52d0731b0691b9745e4f16e448e1bbcfbe43c44cfd8bbe16ca7c9fe2257a9fc285b1b97fbebff8821f610fb8bc409cb3ec7fc5c7443
7
- data.tar.gz: 9adafa55fa0e00c99159f60a049014b866eb41a4a7bad8f4a4b84efd9bddede771d4d7bfbeeb9ed5aabd20d035165b79269df800a53e017920c895038bda8717
6
+ metadata.gz: b3c0c9029f6d14639adb9f901f4b1cc133d1518360be85d8e506e8aa285fa5a1b3e8be5cfa475ae87d8147fadf78dd55bd168593e945f59c1dc237412f714705
7
+ data.tar.gz: 35e2c3b730bf246d1a14c0a6a7cdf77c08910efa4d460aeb878a52a9d4a0210058a7450c556c7e30a08199b011464a45b17b155b13d965c2da057e14a3878309
data/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # vpsAdmin client
2
2
 
3
- TODO: Write a gem description
3
+ vpsAdmin client is a Ruby CLI and client library for vpsAdmin API. It is based
4
+ on [haveapi-client](https://github.com/vpsfreecz/haveapi/tree/master/clients/ruby).
5
+
6
+ vpsAdmin client extends `haveapi-client` with several command-line operations
7
+ specific to vpsAdmin, including:
8
+
9
+ - VPS remote console
10
+ - Snapshot downloads, either ZFS streams or tar archives
11
+ - Automated utility for local backups using ZFS
12
+ - Live IP traffic monitor
4
13
 
5
14
  ## Installation
6
15
 
@@ -17,13 +26,6 @@ Or install it yourself as:
17
26
  $ gem install vpsadmin-client
18
27
 
19
28
  ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it ( https://github.com/[my-github-username]/vpsadminctl/fork )
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create a new Pull Request
29
+ See
30
+ [haveapi-client](https://github.com/vpsfreecz/haveapi/tree/master/clients/ruby)
31
+ for usage information.
@@ -1,5 +1,4 @@
1
- require 'eventmachine'
2
- require 'em-http'
1
+ require 'thread'
3
2
  require 'time'
4
3
  require 'json'
5
4
  require 'base64'
@@ -11,16 +10,35 @@ module VpsAdmin::CLI::Commands
11
10
  args 'VPS_ID'
12
11
  desc 'Open VPS remote console'
13
12
 
14
- class InputHandler < EventMachine::Connection
15
- attr_accessor :buffer
16
-
17
- def initialize
13
+ class InputHandler
14
+ def initialize(http_client)
15
+ @http_client = http_client
18
16
  @private_buffer = ''
19
- @buffer = ''
20
17
  @end_seq = ["\r", "\e", "."]
21
18
  @end_i = 0
19
+ @stop = false
20
+ end
21
+
22
+ def read_from(io)
23
+ begin
24
+ data = io.read_nonblock(4096)
25
+ rescue IO::WaitReadable
26
+ return
27
+ rescue Errno::EIO
28
+ stop
29
+ return
30
+ end
31
+
32
+ write(data)
22
33
  end
23
34
 
35
+ def stop?
36
+ @stop
37
+ end
38
+
39
+ protected
40
+ attr_reader :http_client
41
+
24
42
  # Data is checked on the presence of the end sequence. The first character
25
43
  # in the sequence (ENTER) can be read multiple times in a row and it is
26
44
  # to be forwarded.
@@ -29,38 +47,160 @@ module VpsAdmin::CLI::Commands
29
47
  # but stored in a private buffer. If the sequence is later broken, the private
30
48
  # buffer is forwarded and reset.
31
49
  #
32
- # If the whole end sequence is read, EM event loop is stopped.
33
- def receive_data(data)
50
+ # If the whole end sequence is read, we exit.
51
+ def write(data)
52
+ buffer = ''
53
+
34
54
  data.each_char do |char|
35
55
  if char == @end_seq[ @end_i ]
36
- if @end_i == @end_seq.size-1
37
- EM.stop
56
+ if @end_i == @end_seq.size - 1
57
+ @stop = true
38
58
  return
39
59
  end
40
60
 
41
61
  @end_i += 1
42
62
 
43
63
  if @end_i == 1
44
- @buffer += char
45
-
64
+ buffer += char
46
65
  else
47
66
  @private_buffer += char
48
67
  end
49
68
 
50
69
  elsif char == @end_seq.first
51
- @buffer += char
52
-
70
+ buffer += char
53
71
  else
54
72
  @end_i = 0
55
73
 
56
74
  unless @private_buffer.empty?
57
- @buffer += @private_buffer
75
+ buffer += @private_buffer
58
76
  @private_buffer.clear
59
77
  end
60
78
 
61
- @buffer += char
79
+ buffer += char
62
80
  end
63
81
  end
82
+
83
+ http_client.write(buffer) unless buffer.empty?
84
+ end
85
+ end
86
+
87
+ class HttpClient
88
+ def initialize(vps, token, rate)
89
+ @vps = vps
90
+ @token = token
91
+ @rate = rate
92
+ @mutex = Mutex.new
93
+ @write_buffer = ''
94
+ @stop = false
95
+ @error = false
96
+ end
97
+
98
+ def start
99
+ @thread = Thread.new { run }
100
+ end
101
+
102
+ def stop
103
+ @stop = true
104
+ end
105
+
106
+ def stop?
107
+ @stop
108
+ end
109
+
110
+ def error?
111
+ @error != false
112
+ end
113
+
114
+ def error
115
+ @error
116
+ end
117
+
118
+ def join
119
+ stop
120
+ thread.join
121
+ end
122
+
123
+ def write(data)
124
+ mutex.synchronize do
125
+ write_buffer << data
126
+ end
127
+ end
128
+
129
+ def resize(width, height)
130
+ @width = width
131
+ @height = height
132
+ end
133
+
134
+ protected
135
+ attr_reader :vps, :token, :rate, :width, :height, :write_buffer,
136
+ :mutex, :thread
137
+
138
+ def run
139
+ uri = URI("#{vps.node.location.remote_console_server}/console/feed/#{vps.id}")
140
+ start_args = [uri.host, uri.port, nil, nil, nil, nil, {
141
+ use_ssl: uri.scheme == 'https',
142
+ }]
143
+
144
+ Net::HTTP.start(*start_args) do |http|
145
+ loop do
146
+ break if stop? || error?
147
+
148
+ rate_limit { send_request(http, uri) }
149
+ end
150
+ end
151
+ end
152
+
153
+ def send_request(http, uri)
154
+ req = Net::HTTP::Post.new(uri)
155
+
156
+ keys =
157
+ mutex.synchronize do
158
+ s = write_buffer.dup
159
+ write_buffer.clear
160
+ s
161
+ end
162
+
163
+ req.set_form_data(
164
+ 'session' => token,
165
+ 'keys' => keys,
166
+ 'width' => width,
167
+ 'height' => height,
168
+ )
169
+
170
+ res = http.request(req)
171
+
172
+ unless res.is_a?(Net::HTTPSuccess)
173
+ set_error(
174
+ "Console server returned error: "+
175
+ "HTTP #{res.code} - #{res.message}\n\n#{res.body}"
176
+ )
177
+ stop
178
+ return
179
+ end
180
+
181
+ ret = JSON.parse(res.body, symbolize_names: true)
182
+
183
+ unless ret[:session]
184
+ $stdout.write(ret[:data])
185
+ set_error("Session closed.")
186
+ stop
187
+ return
188
+ end
189
+
190
+ $stdout.write(Base64.decode64(ret[:data]))
191
+ end
192
+
193
+ def rate_limit
194
+ t1 = Time.now
195
+ yield
196
+ t2 = Time.now
197
+
198
+ cooldown = rate - (t2 - t1)
199
+ sleep(cooldown) if cooldown > 0
200
+ end
201
+
202
+ def set_error(str)
203
+ @error = str
64
204
  end
65
205
  end
66
206
 
@@ -93,7 +233,7 @@ module VpsAdmin::CLI::Commands
93
233
  end
94
234
 
95
235
  puts " VPS is on #{vps.node.domain_name}, located in #{vps.node.location.label}."
96
- puts "Console router URL is #{vps.node.location.remote_console_server}"
236
+ puts "Console server URL is #{vps.node.location.remote_console_server}"
97
237
  write "Obtaining authentication token..."
98
238
 
99
239
  begin
@@ -105,30 +245,18 @@ module VpsAdmin::CLI::Commands
105
245
  exit(false)
106
246
  end
107
247
 
108
- @token = t.token
109
-
110
248
  puts
111
- puts "Connecting to remote console..."
249
+ puts "Connecting to the remote console..."
112
250
  puts "Press ENTER ESC . to exit"
113
251
  puts
114
252
 
115
253
  raw_mode do
116
- EventMachine.run do
117
- @input = EventMachine.open_keyboard(InputHandler)
118
-
119
- @http = EventMachine::HttpRequest.new(
120
- "#{vps.node.location.remote_console_server}/console/feed/#{vps_id}"
121
- )
122
- communicate
123
- end
254
+ run_console(vps, t.token)
124
255
  end
125
256
  end
126
257
 
127
258
  protected
128
- def write(s)
129
- $stdout.write(s)
130
- $stdout.flush
131
- end
259
+ attr_reader :client
132
260
 
133
261
  def raw_mode
134
262
  state = `stty -g`
@@ -139,6 +267,7 @@ module VpsAdmin::CLI::Commands
139
267
 
140
268
  Signal.trap('WINCH') do
141
269
  @size = Terminal.size!
270
+ client.resize(@size[:width], @size[:height]) if client
142
271
  end
143
272
 
144
273
  yield
@@ -150,38 +279,35 @@ module VpsAdmin::CLI::Commands
150
279
  puts
151
280
  end
152
281
 
153
- def communicate
154
- post = @http.post(
155
- body: {
156
- session: @token,
157
- keys: @input.buffer,
158
- width: @size[:width],
159
- height: @size[:height],
160
- },
161
- keepalive: true
162
- )
282
+ def run_console(vps, token)
283
+ Thread.abort_on_exception = true
163
284
 
164
- @input.buffer = ''
285
+ @client = HttpClient.new(vps, token, @opts[:rate])
286
+ client.resize(@size[:width], @size[:height])
165
287
 
166
- post.errback do
167
- puts "Error: connection to console router failed"
168
- EventMachine.stop
169
- end
288
+ input = InputHandler.new(client)
289
+ client.start
170
290
 
171
- post.callback do
172
- ret = JSON.parse(post.response, symbolize_names: true)
291
+ loop do
292
+ res = IO.select([$stdin], [], [], 1)
293
+ input.read_from($stdin) if res
173
294
 
174
- unless ret[:session]
175
- $stdout.write(ret[:data])
176
- puts "\nSession closed."
177
- EM.stop
178
- next
179
- end
295
+ if input.stop? || client.stop?
296
+ client.join
180
297
 
181
- $stdout.write(Base64.decode64(ret[:data]))
298
+ if client.error?
299
+ write("\n")
300
+ write(client.error)
301
+ end
182
302
 
183
- EM.add_timer(@opts[:rate]) { communicate }
303
+ return
304
+ end
184
305
  end
185
306
  end
307
+
308
+ def write(s)
309
+ $stdout.write(s)
310
+ $stdout.flush
311
+ end
186
312
  end
187
313
  end
@@ -1,5 +1,5 @@
1
1
  module VpsAdmin
2
2
  module Client
3
- VERSION = '3.0.0.master.20190517-0.3ab5ddfe'
3
+ VERSION = '3.0.0.master.20220121-0.b5a81113'
4
4
  end
5
5
  end
@@ -21,9 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'bundler'
22
22
  spec.add_development_dependency 'rake'
23
23
 
24
- spec.add_runtime_dependency 'haveapi-client', '~> 0.13.0'
25
- spec.add_runtime_dependency 'eventmachine', '~> 1.0.3'
26
- spec.add_runtime_dependency 'em-http-request', '~> 1.1.3'
24
+ spec.add_runtime_dependency 'haveapi-client', '~> 0.15.1'
27
25
  spec.add_runtime_dependency 'json'
28
26
  spec.add_runtime_dependency 'curses'
29
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vpsadmin-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.master.20190517.pre.0.3ab5ddfe
4
+ version: 3.0.0.master.20220121.pre.0.b5a81113
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Skokan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-17 00:00:00.000000000 Z
11
+ date: 1980-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,42 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.13.0
47
+ version: 0.15.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.13.0
55
- - !ruby/object:Gem::Dependency
56
- name: eventmachine
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.0.3
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.0.3
69
- - !ruby/object:Gem::Dependency
70
- name: em-http-request
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 1.1.3
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 1.1.3
54
+ version: 0.15.1
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: json
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -142,7 +114,7 @@ homepage: ''
142
114
  licenses:
143
115
  - GPL
144
116
  metadata: {}
145
- post_install_message:
117
+ post_install_message:
146
118
  rdoc_options: []
147
119
  require_paths:
148
120
  - lib
@@ -157,9 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
129
  - !ruby/object:Gem::Version
158
130
  version: 1.3.1
159
131
  requirements: []
160
- rubyforge_project:
161
- rubygems_version: 2.7.6.2
162
- signing_key:
132
+ rubygems_version: 3.2.26
133
+ signing_key:
163
134
  specification_version: 4
164
135
  summary: Ruby API and CLI for vpsAdmin API
165
136
  test_files: []