vpsadmin-client 3.0.0.master.20221118.pre.1.ac358990 → 3.0.0.master.20240728.pre.0.dc5474cc
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/Rakefile +0 -1
- data/lib/{terminal-size.rb → terminal_size.rb} +23 -17
- data/lib/vpsadmin/cli/commands/backup_dataset.rb +96 -98
- data/lib/vpsadmin/cli/commands/backup_vps.rb +1 -1
- data/lib/vpsadmin/cli/commands/base_download.rb +6 -6
- data/lib/vpsadmin/cli/commands/network_top.rb +65 -59
- data/lib/vpsadmin/cli/commands/snapshot_download.rb +20 -21
- data/lib/vpsadmin/cli/commands/snapshot_send.rb +6 -7
- data/lib/vpsadmin/cli/commands/vps_migrate_many.rb +10 -12
- data/lib/vpsadmin/cli/commands/vps_remote_console.rb +29 -30
- data/lib/vpsadmin/cli/stream_downloader.rb +38 -45
- data/lib/vpsadmin/cli.rb +2 -2
- data/lib/vpsadmin/client/version.rb +1 -1
- data/lib/vpsadmin/client.rb +2 -3
- data/shell.nix +6 -6
- data/vpsadmin-client.gemspec +7 -10
- metadata +10 -38
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'thread'
|
2
1
|
require 'time'
|
3
2
|
require 'json'
|
4
3
|
require 'base64'
|
5
|
-
require '
|
4
|
+
require 'io/wait'
|
5
|
+
require 'terminal_size'
|
6
6
|
|
7
7
|
module VpsAdmin::CLI::Commands
|
8
8
|
class VpsRemoteControl < HaveAPI::CLI::Command
|
@@ -14,7 +14,7 @@ module VpsAdmin::CLI::Commands
|
|
14
14
|
def initialize(http_client)
|
15
15
|
@http_client = http_client
|
16
16
|
@private_buffer = ''
|
17
|
-
@end_seq = ["\r", "\e",
|
17
|
+
@end_seq = ["\r", "\e", '.']
|
18
18
|
@end_i = 0
|
19
19
|
@stop = false
|
20
20
|
end
|
@@ -37,6 +37,7 @@ module VpsAdmin::CLI::Commands
|
|
37
37
|
end
|
38
38
|
|
39
39
|
protected
|
40
|
+
|
40
41
|
attr_reader :http_client
|
41
42
|
|
42
43
|
# Data is checked on the presence of the end sequence. The first character
|
@@ -52,10 +53,10 @@ module VpsAdmin::CLI::Commands
|
|
52
53
|
buffer = ''
|
53
54
|
|
54
55
|
data.each_char do |char|
|
55
|
-
if char == @end_seq[
|
56
|
+
if char == @end_seq[@end_i]
|
56
57
|
if @end_i == @end_seq.size - 1
|
57
58
|
@stop = true
|
58
|
-
return
|
59
|
+
return # rubocop:disable Lint/NonLocalExitFromIterator
|
59
60
|
end
|
60
61
|
|
61
62
|
@end_i += 1
|
@@ -111,9 +112,7 @@ module VpsAdmin::CLI::Commands
|
|
111
112
|
@error != false
|
112
113
|
end
|
113
114
|
|
114
|
-
|
115
|
-
@error
|
116
|
-
end
|
115
|
+
attr_reader :error
|
117
116
|
|
118
117
|
def join
|
119
118
|
stop
|
@@ -132,13 +131,14 @@ module VpsAdmin::CLI::Commands
|
|
132
131
|
end
|
133
132
|
|
134
133
|
protected
|
134
|
+
|
135
135
|
attr_reader :vps, :token, :rate, :width, :height, :write_buffer,
|
136
|
-
|
136
|
+
:mutex, :thread
|
137
137
|
|
138
138
|
def run
|
139
139
|
uri = URI("#{vps.node.location.remote_console_server}/console/feed/#{vps.id}")
|
140
140
|
start_args = [uri.host, uri.port, nil, nil, nil, nil, {
|
141
|
-
use_ssl: uri.scheme == 'https'
|
141
|
+
use_ssl: uri.scheme == 'https'
|
142
142
|
}]
|
143
143
|
|
144
144
|
Net::HTTP.start(*start_args) do |http|
|
@@ -164,14 +164,14 @@ module VpsAdmin::CLI::Commands
|
|
164
164
|
'session' => token,
|
165
165
|
'keys' => keys,
|
166
166
|
'width' => width,
|
167
|
-
'height' => height
|
167
|
+
'height' => height
|
168
168
|
)
|
169
169
|
|
170
170
|
res = http.request(req)
|
171
171
|
|
172
172
|
unless res.is_a?(Net::HTTPSuccess)
|
173
173
|
set_error(
|
174
|
-
|
174
|
+
'Console server returned error: ' \
|
175
175
|
"HTTP #{res.code} - #{res.message}\n\n#{res.body}"
|
176
176
|
)
|
177
177
|
stop
|
@@ -182,7 +182,7 @@ module VpsAdmin::CLI::Commands
|
|
182
182
|
|
183
183
|
unless ret[:session]
|
184
184
|
$stdout.write(ret[:data])
|
185
|
-
set_error(
|
185
|
+
set_error('Session closed.')
|
186
186
|
stop
|
187
187
|
return
|
188
188
|
end
|
@@ -216,38 +216,36 @@ module VpsAdmin::CLI::Commands
|
|
216
216
|
|
217
217
|
def exec(args)
|
218
218
|
if args.empty?
|
219
|
-
puts
|
219
|
+
puts 'provide VPS ID as an argument'
|
220
220
|
exit(false)
|
221
221
|
end
|
222
222
|
|
223
223
|
vps_id = args.first.to_i
|
224
224
|
|
225
|
-
write
|
225
|
+
write 'Locating VPS..'
|
226
226
|
begin
|
227
227
|
vps = @api.vps.show(vps_id, meta: { includes: 'node__location' })
|
228
|
-
|
229
228
|
rescue HaveAPI::Client::ActionFailed => e
|
230
|
-
puts
|
229
|
+
puts ' error'
|
231
230
|
puts e.message
|
232
231
|
exit(false)
|
233
232
|
end
|
234
233
|
|
235
234
|
puts " VPS is on #{vps.node.domain_name}, located in #{vps.node.location.label}."
|
236
235
|
puts "Console server URL is #{vps.node.location.remote_console_server}"
|
237
|
-
write
|
236
|
+
write 'Obtaining authentication token...'
|
238
237
|
|
239
238
|
begin
|
240
239
|
t = vps.console_token.create
|
241
|
-
|
242
240
|
rescue HaveAPI::Client::ActionFailed => e
|
243
|
-
puts
|
241
|
+
puts ' error'
|
244
242
|
puts e.message
|
245
243
|
exit(false)
|
246
244
|
end
|
247
245
|
|
248
246
|
puts
|
249
|
-
puts
|
250
|
-
puts
|
247
|
+
puts 'Connecting to the remote console...'
|
248
|
+
puts 'Press ENTER ESC . to exit'
|
251
249
|
puts
|
252
250
|
|
253
251
|
raw_mode do
|
@@ -256,6 +254,7 @@ module VpsAdmin::CLI::Commands
|
|
256
254
|
end
|
257
255
|
|
258
256
|
protected
|
257
|
+
|
259
258
|
attr_reader :client
|
260
259
|
|
261
260
|
def raw_mode
|
@@ -289,19 +288,19 @@ module VpsAdmin::CLI::Commands
|
|
289
288
|
client.start
|
290
289
|
|
291
290
|
loop do
|
292
|
-
res =
|
291
|
+
res = $stdin.wait_readable(1)
|
293
292
|
input.read_from($stdin) if res
|
294
293
|
|
295
|
-
|
296
|
-
client.join
|
294
|
+
next unless input.stop? || client.stop?
|
297
295
|
|
298
|
-
|
299
|
-
write("\n")
|
300
|
-
write(client.error)
|
301
|
-
end
|
296
|
+
client.join
|
302
297
|
|
303
|
-
|
298
|
+
if client.error?
|
299
|
+
write("\n")
|
300
|
+
write(client.error)
|
304
301
|
end
|
302
|
+
|
303
|
+
return
|
305
304
|
end
|
306
305
|
end
|
307
306
|
|
@@ -4,15 +4,15 @@ require 'ruby-progressbar'
|
|
4
4
|
require 'digest'
|
5
5
|
|
6
6
|
module VpsAdmin::CLI
|
7
|
-
class DownloadError < StandardError
|
7
|
+
class DownloadError < StandardError; end
|
8
8
|
|
9
9
|
class StreamDownloader
|
10
|
-
def self.download(
|
11
|
-
new(
|
10
|
+
def self.download(*, **)
|
11
|
+
new(*, **)
|
12
12
|
end
|
13
13
|
|
14
|
-
def initialize(api, dl, io, progress:
|
15
|
-
|
14
|
+
def initialize(api, dl, io, progress: $stdout, position: 0, max_rate: nil,
|
15
|
+
checksum: true)
|
16
16
|
downloaded = position
|
17
17
|
uri = URI(dl.url)
|
18
18
|
digest = Digest::SHA256.new
|
@@ -26,12 +26,12 @@ module VpsAdmin::CLI
|
|
26
26
|
format: '%E %t: [%B] %p%% %r MB/s',
|
27
27
|
rate_scale: ->(rate) { (rate / 1024.0 / 1024.0).round(2) },
|
28
28
|
throttle_rate: 0.2,
|
29
|
-
output: progress
|
29
|
+
output: progress
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
33
|
read = 0
|
34
|
-
step = 1*1024*1024
|
34
|
+
step = 1 * 1024 * 1024
|
35
35
|
io.seek(0)
|
36
36
|
|
37
37
|
while read < position
|
@@ -56,20 +56,20 @@ module VpsAdmin::CLI
|
|
56
56
|
throttle_rate: 0.2,
|
57
57
|
starting_at: downloaded,
|
58
58
|
autofinish: false,
|
59
|
-
output: progress
|
59
|
+
output: progress
|
60
60
|
)
|
61
61
|
end
|
62
62
|
|
63
|
-
args = [uri.host] + Array.new(5, nil) + [{use_ssl: uri.scheme == 'https'}]
|
63
|
+
args = [uri.host] + Array.new(5, nil) + [{ use_ssl: uri.scheme == 'https' }]
|
64
64
|
|
65
65
|
Net::HTTP.start(*args) do |http|
|
66
66
|
loop do
|
67
67
|
begin
|
68
68
|
dl_check = api.snapshot_download.show(dl.id)
|
69
69
|
|
70
|
-
if @pb && (dl_check.ready || (dl_check.size && dl_check.size > 0))
|
70
|
+
if @pb && (dl_check.ready || (dl_check.size && dl_check.size > 0)) # rubocop:disable all
|
71
71
|
total = dl_check.size * 1024 * 1024
|
72
|
-
@pb.total = @pb.progress
|
72
|
+
@pb.total = [@pb.progress, total].max
|
73
73
|
|
74
74
|
@download_size = (dl_check.size / 1024.0).round(2)
|
75
75
|
|
@@ -81,7 +81,6 @@ module VpsAdmin::CLI
|
|
81
81
|
self.format = "%E %t ~#{@download_size} GB: [%B] %p%% %r kB/s"
|
82
82
|
end
|
83
83
|
end
|
84
|
-
|
85
84
|
rescue HaveAPI::Client::ActionFailed => e
|
86
85
|
# The SnapshotDownload object no longer exists, the transaction
|
87
86
|
# responsible for its creation must have failed.
|
@@ -94,36 +93,32 @@ module VpsAdmin::CLI
|
|
94
93
|
|
95
94
|
http.request_get(uri.path, headers) do |res|
|
96
95
|
case res.code
|
97
|
-
when '404'
|
98
|
-
if downloaded > 0
|
99
|
-
# This means that the transaction used for preparing the download
|
100
|
-
# has failed, the file to download does not exist anymore, so fail.
|
101
|
-
raise DownloadError, 'The download has failed, most likely transaction failure'
|
96
|
+
when '404' # Not Found
|
97
|
+
raise DownloadError, 'The download has failed, most likely transaction failure' if downloaded > 0
|
102
98
|
|
103
|
-
|
104
|
-
|
105
|
-
# may be queued and it can take some time before it is processed.
|
106
|
-
pause(10)
|
107
|
-
next
|
108
|
-
end
|
99
|
+
# This means that the transaction used for preparing the download
|
100
|
+
# has failed, the file to download does not exist anymore, so fail.
|
109
101
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
# because the server is busy. Wait and retry.
|
115
|
-
pause(20)
|
116
|
-
next
|
102
|
+
# The file is not available yet, this is normal, the transaction
|
103
|
+
# may be queued and it can take some time before it is processed.
|
104
|
+
pause(10)
|
105
|
+
next
|
117
106
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
107
|
+
when '416' # Range Not Satisfiable
|
108
|
+
raise DownloadError, 'Range not satisfiable' unless downloaded > position
|
109
|
+
|
110
|
+
# We have already managed to download something (at this run, if the trasfer
|
111
|
+
# was resumed) and the server cannot provide more data yet. This can be
|
112
|
+
# because the server is busy. Wait and retry.
|
113
|
+
pause(20)
|
114
|
+
next
|
125
115
|
|
126
|
-
|
116
|
+
# The file is not ready yet - we ask for range that cannot be provided
|
117
|
+
# This happens when we're resuming a download and the file on the
|
118
|
+
# server was deleted meanwhile. The file might not be exactly the same
|
119
|
+
# as the one before, sha256sum would most likely fail.
|
120
|
+
|
121
|
+
when '200', '206' # OK and Partial Content
|
127
122
|
resume
|
128
123
|
|
129
124
|
else
|
@@ -140,10 +135,7 @@ module VpsAdmin::CLI
|
|
140
135
|
downloaded += size
|
141
136
|
|
142
137
|
begin
|
143
|
-
if @pb && (@pb.total.nil? || @pb.progress < @pb.total)
|
144
|
-
@pb.progress += size
|
145
|
-
end
|
146
|
-
|
138
|
+
@pb.progress += size if @pb && (@pb.total.nil? || @pb.progress < @pb.total)
|
147
139
|
rescue ProgressBar::InvalidProgressError
|
148
140
|
# The total value is in MB, it is not precise, so the actual
|
149
141
|
# size may be a little bit bigger.
|
@@ -186,12 +178,13 @@ module VpsAdmin::CLI
|
|
186
178
|
@pb.finish if @pb
|
187
179
|
|
188
180
|
# Verify the checksum
|
189
|
-
|
190
|
-
|
191
|
-
|
181
|
+
return unless checksum && digest.hexdigest != dl_check.sha256sum
|
182
|
+
|
183
|
+
raise DownloadError, 'The sha256sum does not match, retry the download'
|
192
184
|
end
|
193
185
|
|
194
186
|
protected
|
187
|
+
|
195
188
|
def pause(secs)
|
196
189
|
@paused = true
|
197
190
|
|
data/lib/vpsadmin/cli.rb
CHANGED
@@ -3,11 +3,11 @@ require 'vpsadmin/client/version'
|
|
3
3
|
|
4
4
|
module VpsAdmin
|
5
5
|
module CLI
|
6
|
-
module Commands
|
6
|
+
module Commands; end
|
7
7
|
|
8
8
|
class Cli < HaveAPI::CLI::Cli
|
9
9
|
def show_version
|
10
|
-
puts "#{VpsAdmin::Client::VERSION} based on haveapi-client "+
|
10
|
+
puts "#{VpsAdmin::Client::VERSION} based on haveapi-client " +
|
11
11
|
HaveAPI::Client::VERSION
|
12
12
|
end
|
13
13
|
end
|
data/lib/vpsadmin/client.rb
CHANGED
@@ -3,12 +3,11 @@ require 'haveapi/client'
|
|
3
3
|
module VpsAdmin
|
4
4
|
module Client
|
5
5
|
class Client < HaveAPI::Client::Client
|
6
|
-
|
7
6
|
end
|
8
7
|
|
9
8
|
# Shortcut to {VpsAdmin::Client::Client.new}
|
10
|
-
def self.new(*
|
11
|
-
Client.new(*
|
9
|
+
def self.new(*)
|
10
|
+
Client.new(*)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
data/shell.nix
CHANGED
@@ -5,12 +5,12 @@ let
|
|
5
5
|
in stdenv.mkDerivation rec {
|
6
6
|
name = "vpsadmin-client";
|
7
7
|
|
8
|
-
buildInputs = [
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
buildInputs = with pkgs; [
|
9
|
+
ruby_3_2
|
10
|
+
git
|
11
|
+
zlib
|
12
|
+
openssl
|
13
|
+
ncurses
|
14
14
|
];
|
15
15
|
|
16
16
|
shellHook = ''
|
data/vpsadmin-client.gemspec
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
|
2
|
-
lib
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$:.unshift(lib) unless $:.include?(lib)
|
4
3
|
require 'vpsadmin/client/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
@@ -9,19 +8,17 @@ Gem::Specification.new do |spec|
|
|
9
8
|
spec.authors = ['Jakub Skokan']
|
10
9
|
spec.email = ['jakub.skokan@vpsfree.cz']
|
11
10
|
spec.summary =
|
12
|
-
|
11
|
+
spec.description = 'Ruby API and CLI for vpsAdmin API'
|
13
12
|
spec.homepage = ''
|
14
13
|
spec.license = 'GPL'
|
15
14
|
|
15
|
+
spec.required_ruby_version = ">= #{File.read('../.ruby-version').strip}"
|
16
|
+
|
16
17
|
spec.files = `git ls-files -z`.split("\x0")
|
17
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler'
|
22
|
-
spec.add_development_dependency 'rake'
|
23
|
-
|
24
|
-
spec.add_runtime_dependency 'haveapi-client', '~> 0.16.1'
|
25
|
-
spec.add_runtime_dependency 'json'
|
26
21
|
spec.add_runtime_dependency 'curses'
|
22
|
+
spec.add_runtime_dependency 'haveapi-client', '~> 0.23.5'
|
23
|
+
spec.add_runtime_dependency 'json'
|
27
24
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vpsadmin-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.master.
|
4
|
+
version: 3.0.0.master.20240728.pre.0.dc5474cc
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Skokan
|
@@ -11,27 +11,13 @@ cert_chain: []
|
|
11
11
|
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
14
|
+
name: curses
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '0'
|
34
|
-
type: :
|
20
|
+
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
@@ -44,14 +30,14 @@ dependencies:
|
|
44
30
|
requirements:
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
33
|
+
version: 0.23.5
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
40
|
+
version: 0.23.5
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: json
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,20 +52,6 @@ dependencies:
|
|
66
52
|
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: curses
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
55
|
description: Ruby API and CLI for vpsAdmin API
|
84
56
|
email:
|
85
57
|
- jakub.skokan@vpsfree.cz
|
@@ -95,7 +67,7 @@ files:
|
|
95
67
|
- README.md
|
96
68
|
- Rakefile
|
97
69
|
- bin/vpsadminctl
|
98
|
-
- lib/
|
70
|
+
- lib/terminal_size.rb
|
99
71
|
- lib/vpsadmin/cli.rb
|
100
72
|
- lib/vpsadmin/cli/commands/backup_dataset.rb
|
101
73
|
- lib/vpsadmin/cli/commands/backup_vps.rb
|
@@ -122,14 +94,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
94
|
requirements:
|
123
95
|
- - ">="
|
124
96
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
97
|
+
version: 3.2.0
|
126
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
99
|
requirements:
|
128
|
-
- - "
|
100
|
+
- - ">="
|
129
101
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
102
|
+
version: '0'
|
131
103
|
requirements: []
|
132
|
-
rubygems_version: 3.
|
104
|
+
rubygems_version: 3.5.9
|
133
105
|
signing_key:
|
134
106
|
specification_version: 4
|
135
107
|
summary: Ruby API and CLI for vpsAdmin API
|