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
@@ -5,7 +5,7 @@ module VpsAdmin::CLI::Commands
|
|
5
5
|
include Curses
|
6
6
|
|
7
7
|
REFRESH_RATE = 10
|
8
|
-
FILTERS = %i
|
8
|
+
FILTERS = %i[limit user environment location node vps network_interface].freeze
|
9
9
|
|
10
10
|
cmd :network, :top
|
11
11
|
args ''
|
@@ -13,10 +13,10 @@ module VpsAdmin::CLI::Commands
|
|
13
13
|
|
14
14
|
def options(opts)
|
15
15
|
@opts = {
|
16
|
-
unit: :bits
|
16
|
+
unit: :bits
|
17
17
|
}
|
18
18
|
|
19
|
-
opts.on('--unit UNIT', %w
|
19
|
+
opts.on('--unit UNIT', %w[bytes bits], 'Select data unit (bytes or bits)') do |v|
|
20
20
|
@opts[:unit] = v.to_sym
|
21
21
|
end
|
22
22
|
|
@@ -24,19 +24,20 @@ module VpsAdmin::CLI::Commands
|
|
24
24
|
@opts[:limit] = v
|
25
25
|
end
|
26
26
|
|
27
|
-
(FILTERS - %i
|
28
|
-
opts.on("--#{f.to_s.gsub(
|
27
|
+
(FILTERS - %i[limit]).each do |f|
|
28
|
+
opts.on("--#{f.to_s.gsub('_', '-')} ID", Integer, "Filter network interfaces by #{f}") do |v|
|
29
29
|
@opts[f] = v
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def exec(
|
34
|
+
def exec(_args)
|
35
35
|
if @global_opts[:list_output]
|
36
|
-
exclude = %i
|
36
|
+
exclude = %i[id network_interface updated_at delta]
|
37
37
|
|
38
38
|
@api.network_interface_monitor.actions[:index].params.each_key do |name|
|
39
39
|
next if exclude.include?(name)
|
40
|
+
|
40
41
|
puts name
|
41
42
|
end
|
42
43
|
|
@@ -48,7 +49,7 @@ module VpsAdmin::CLI::Commands
|
|
48
49
|
start_color
|
49
50
|
crmode
|
50
51
|
stdscr.keypad = true
|
51
|
-
curs_set(0)
|
52
|
+
curs_set(0) # hide cursor
|
52
53
|
use_default_colors
|
53
54
|
|
54
55
|
init_pair(1, COLOR_BLACK, COLOR_WHITE)
|
@@ -88,24 +89,25 @@ module VpsAdmin::CLI::Commands
|
|
88
89
|
clear
|
89
90
|
end
|
90
91
|
end
|
91
|
-
|
92
92
|
rescue Interrupt
|
93
|
+
# break loop and exit
|
93
94
|
ensure
|
94
95
|
close_screen
|
95
96
|
end
|
96
97
|
|
97
98
|
protected
|
99
|
+
|
98
100
|
def set_global_opts
|
99
|
-
if @global_opts[:output]
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
@params = if @global_opts[:output]
|
102
|
+
@global_opts[:output].split(',').map(&:to_sym)
|
103
|
+
else
|
104
|
+
%i[bytes bytes_in bytes_out packets packets_in packets_out]
|
105
|
+
end
|
104
106
|
|
105
107
|
if @global_opts[:sort]
|
106
|
-
|
107
|
-
@sort_desc =
|
108
|
-
@sort_param = (
|
108
|
+
sort_v = @global_opts[:sort]
|
109
|
+
@sort_desc = sort_v.start_with?('-')
|
110
|
+
@sort_param = (sort_v.start_with?('-') ? sort_v[1..] : sort_v).to_sym
|
109
111
|
|
110
112
|
else
|
111
113
|
@sort_desc = true
|
@@ -117,19 +119,21 @@ module VpsAdmin::CLI::Commands
|
|
117
119
|
@params.each do |p|
|
118
120
|
title = p.to_s.split('_').map do |v|
|
119
121
|
if @opts[:unit] == :bits
|
120
|
-
v.to_s.gsub(
|
122
|
+
v.to_s.gsub('bytes', 'bits').capitalize
|
121
123
|
|
122
124
|
else
|
123
125
|
v.capitalize
|
124
126
|
end
|
125
|
-
end.join
|
127
|
+
end.join
|
128
|
+
|
129
|
+
title << '/s'
|
126
130
|
|
127
131
|
size = title.size + 1
|
128
132
|
|
129
133
|
@columns << {
|
130
134
|
name: p,
|
131
|
-
title
|
132
|
-
width: size
|
135
|
+
title:,
|
136
|
+
width: [size, 8].max
|
133
137
|
}
|
134
138
|
end
|
135
139
|
end
|
@@ -137,12 +141,12 @@ module VpsAdmin::CLI::Commands
|
|
137
141
|
def fetch
|
138
142
|
return @data if @data
|
139
143
|
|
140
|
-
limit = @opts[:limit] || lines - 6
|
144
|
+
limit = @opts[:limit] || (lines - 6)
|
141
145
|
|
142
|
-
params =
|
146
|
+
params = {
|
143
147
|
limit: limit > 0 ? limit : 25,
|
144
148
|
order: "#{@sort_desc ? '-' : ''}#{@sort_param}",
|
145
|
-
meta: {includes: 'network_interface'}
|
149
|
+
meta: { includes: 'network_interface' }
|
146
150
|
}
|
147
151
|
|
148
152
|
FILTERS.each do |f|
|
@@ -188,11 +192,11 @@ module VpsAdmin::CLI::Commands
|
|
188
192
|
unless @header
|
189
193
|
fmt = (['%8s', '%-15s'] + @columns.map { |c| "%#{c[:width]}s" }).join(' ')
|
190
194
|
|
191
|
-
@header =
|
195
|
+
@header = format(
|
192
196
|
fmt,
|
193
197
|
'VPS',
|
194
198
|
'Interface',
|
195
|
-
*@columns.map { |c| c[:title] }
|
199
|
+
*@columns.map { |c| c[:title] }
|
196
200
|
)
|
197
201
|
|
198
202
|
@header << (' ' * (cols - @header.size)) << "\n"
|
@@ -202,30 +206,30 @@ module VpsAdmin::CLI::Commands
|
|
202
206
|
end
|
203
207
|
|
204
208
|
def print_row(data)
|
205
|
-
addstr(
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
209
|
+
addstr(format(
|
210
|
+
'%8s %-15s',
|
211
|
+
data.network_interface.vps_id,
|
212
|
+
data.network_interface.name
|
213
|
+
))
|
210
214
|
|
211
215
|
@columns.each do |c|
|
212
216
|
p = c[:name]
|
213
217
|
|
214
218
|
attron(A_BOLD) if p == @sort_param
|
215
|
-
addstr(
|
219
|
+
addstr(format(" %#{c[:width]}s", unitize_param(p, data.send(p), data.delta)))
|
216
220
|
attroff(A_BOLD) if p == @sort_param
|
217
221
|
end
|
218
222
|
end
|
219
223
|
|
220
224
|
def stats
|
221
|
-
fields = %i
|
225
|
+
fields = %i[bytes packets]
|
222
226
|
stats = {}
|
223
227
|
delta_sum = 0
|
224
228
|
|
225
229
|
fields.each do |f|
|
226
230
|
stats[f] = 0
|
227
231
|
|
228
|
-
%i
|
232
|
+
%i[in out].each do |dir|
|
229
233
|
stats[:"#{f}_#{dir}"] = 0
|
230
234
|
end
|
231
235
|
end
|
@@ -236,7 +240,7 @@ module VpsAdmin::CLI::Commands
|
|
236
240
|
fields.each do |f|
|
237
241
|
stats[f] += data.send(f)
|
238
242
|
|
239
|
-
%i
|
243
|
+
%i[in out].each do |dir|
|
240
244
|
stats[:"#{f}_#{dir}"] += data.send("#{f}_#{dir}")
|
241
245
|
end
|
242
246
|
end
|
@@ -244,41 +248,43 @@ module VpsAdmin::CLI::Commands
|
|
244
248
|
|
245
249
|
avg_delta = delta_sum.to_f / fetch.count
|
246
250
|
|
247
|
-
setpos(lines-5, 0)
|
251
|
+
setpos(lines - 5, 0)
|
248
252
|
addstr('─' * cols)
|
249
253
|
|
250
254
|
fmt = '%10s %10s %10s'
|
251
255
|
unit = @opts[:unit].to_s.capitalize
|
252
256
|
|
253
|
-
setpos(lines-4, 0)
|
254
|
-
addstr(
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
257
|
+
setpos(lines - 4, 0)
|
258
|
+
addstr(format(
|
259
|
+
fmt,
|
260
|
+
'',
|
261
|
+
"#{unit}/s",
|
262
|
+
'Packets/s'
|
263
|
+
))
|
260
264
|
|
261
|
-
setpos(lines-3, 0)
|
262
|
-
addstr(
|
265
|
+
setpos(lines - 3, 0)
|
266
|
+
addstr(format(fmt, 'In', *fields.map { |f| unitize_param(f, stats[:"#{f}_in"], avg_delta) }))
|
263
267
|
|
264
|
-
setpos(lines-2, 0)
|
265
|
-
addstr(
|
268
|
+
setpos(lines - 2, 0)
|
269
|
+
addstr(format(fmt, 'Out', *fields.map { |f| unitize_param(f, stats[:"#{f}_out"], avg_delta) }))
|
266
270
|
|
267
|
-
setpos(lines-1, 0)
|
271
|
+
setpos(lines - 1, 0)
|
268
272
|
attron(A_BOLD)
|
269
|
-
addstr(
|
273
|
+
addstr(format(fmt, 'Total', *fields.map do |f|
|
274
|
+
unitize_param(f, stats[:"#{f}_in"] + stats[:"#{f}_out"], avg_delta)
|
275
|
+
end))
|
270
276
|
attroff(A_BOLD)
|
271
277
|
end
|
272
278
|
|
273
279
|
def unitize_bytes(n, delta)
|
274
|
-
if @opts[:unit] == :bytes
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
280
|
+
per_s = if @opts[:unit] == :bytes
|
281
|
+
n / delta.to_f
|
282
|
+
else
|
283
|
+
n * 8 / delta.to_f
|
284
|
+
end
|
279
285
|
|
280
286
|
bits = 39
|
281
|
-
units = %w
|
287
|
+
units = %w[T G M k]
|
282
288
|
|
283
289
|
units.each do |u|
|
284
290
|
threshold = 2 << bits
|
@@ -294,7 +300,7 @@ module VpsAdmin::CLI::Commands
|
|
294
300
|
def unitize_number(n, delta)
|
295
301
|
per_s = n / delta.to_f
|
296
302
|
threshold = 1_000_000_000_000
|
297
|
-
units = %w
|
303
|
+
units = %w[T G M k]
|
298
304
|
|
299
305
|
units.each do |u|
|
300
306
|
return "#{(per_s / threshold).round(2)}#{u}" if per_s >= threshold
|
@@ -312,7 +318,7 @@ module VpsAdmin::CLI::Commands
|
|
312
318
|
when :packets, :packets_in, :packets_out
|
313
319
|
unitize_number(n, delta)
|
314
320
|
else
|
315
|
-
|
321
|
+
raise "unknown param to unitize: #{param.inspect}"
|
316
322
|
end
|
317
323
|
end
|
318
324
|
|
@@ -335,10 +341,10 @@ module VpsAdmin::CLI::Commands
|
|
335
341
|
|
336
342
|
ips = @api.ip_address.list(addr: v)
|
337
343
|
return false if ips.count < 1
|
338
|
-
ips.first.id
|
339
344
|
|
345
|
+
ips.first.id
|
340
346
|
rescue HaveAPI::Client::ActionFailed
|
341
|
-
|
347
|
+
false
|
342
348
|
end
|
343
349
|
end
|
344
350
|
end
|
@@ -9,7 +9,7 @@ module VpsAdmin::CLI::Commands
|
|
9
9
|
delete_after: true,
|
10
10
|
send_mail: false,
|
11
11
|
checksum: true,
|
12
|
-
format: 'archive'
|
12
|
+
format: 'archive'
|
13
13
|
}
|
14
14
|
|
15
15
|
opts.on('-f', '--format FORMAT', 'archive, stream or incremental_stream') do |f|
|
@@ -55,11 +55,11 @@ module VpsAdmin::CLI::Commands
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def exec(args)
|
58
|
-
if args.
|
58
|
+
if args.empty? && $stdin.tty?
|
59
59
|
@opts[:snapshot] = snapshot_chooser
|
60
60
|
|
61
61
|
elsif args.size != 1
|
62
|
-
warn
|
62
|
+
warn 'Provide exactly one SNAPSHOT_ID as an argument'
|
63
63
|
exit(false)
|
64
64
|
|
65
65
|
else
|
@@ -75,7 +75,7 @@ module VpsAdmin::CLI::Commands
|
|
75
75
|
pos = 0
|
76
76
|
|
77
77
|
if @opts[:file] == '-'
|
78
|
-
f =
|
78
|
+
f = $stdout
|
79
79
|
|
80
80
|
elsif @opts[:file]
|
81
81
|
f, action, pos = open_file(@opts[:file])
|
@@ -86,11 +86,11 @@ module VpsAdmin::CLI::Commands
|
|
86
86
|
|
87
87
|
if created
|
88
88
|
if action == :resume
|
89
|
-
warn
|
89
|
+
warn 'Unable to resume the download: the file has been deleted from the server'
|
90
90
|
exit(false)
|
91
91
|
end
|
92
92
|
|
93
|
-
msg
|
93
|
+
msg 'The download is being prepared...'
|
94
94
|
sleep(5)
|
95
95
|
|
96
96
|
else
|
@@ -104,16 +104,14 @@ module VpsAdmin::CLI::Commands
|
|
104
104
|
@api,
|
105
105
|
dl,
|
106
106
|
f,
|
107
|
-
progress: !@opts[:quiet] && (f ==
|
107
|
+
progress: !@opts[:quiet] && (f == $stdout ? $stderr : $stdout),
|
108
108
|
position: pos,
|
109
109
|
max_rate: @opts[:max_rate],
|
110
|
-
checksum: @opts[:checksum]
|
110
|
+
checksum: @opts[:checksum]
|
111
111
|
)
|
112
|
-
|
113
112
|
rescue VpsAdmin::CLI::DownloadError => e
|
114
113
|
warn e.message
|
115
114
|
exit(false)
|
116
|
-
|
117
115
|
ensure
|
118
116
|
f.close
|
119
117
|
end
|
@@ -122,27 +120,28 @@ module VpsAdmin::CLI::Commands
|
|
122
120
|
end
|
123
121
|
|
124
122
|
protected
|
123
|
+
|
125
124
|
def open_file(path)
|
126
125
|
f = action = nil
|
127
126
|
pos = 0
|
128
127
|
|
129
|
-
if File.
|
128
|
+
if File.exist?(path) && File.size(path) > 0
|
130
129
|
if @opts[:resume]
|
131
130
|
action = :resume
|
132
131
|
|
133
132
|
elsif @opts[:force]
|
134
133
|
action = :overwrite
|
135
134
|
|
136
|
-
elsif
|
135
|
+
elsif $stdin.tty?
|
137
136
|
while action.nil?
|
138
|
-
|
139
|
-
|
137
|
+
$stderr.write("'#{path}' already exists. [A]bort, [r]esume or [o]verwrite? [a]: ")
|
138
|
+
$stderr.flush
|
140
139
|
|
141
140
|
action = {
|
142
141
|
'r' => :resume,
|
143
142
|
'o' => :overwrite,
|
144
|
-
'' => false
|
145
|
-
}[
|
143
|
+
'' => false
|
144
|
+
}[$stdin.readline.strip.downcase]
|
146
145
|
end
|
147
146
|
|
148
147
|
else
|
@@ -186,7 +185,7 @@ module VpsAdmin::CLI::Commands
|
|
186
185
|
snapshots = ds.snapshot.index
|
187
186
|
next if snapshots.empty?
|
188
187
|
|
189
|
-
if vps = ds_map[ds.id]
|
188
|
+
if (vps = ds_map[ds.id])
|
190
189
|
puts "VPS ##{vps.id}"
|
191
190
|
|
192
191
|
else
|
@@ -201,15 +200,15 @@ module VpsAdmin::CLI::Commands
|
|
201
200
|
end
|
202
201
|
|
203
202
|
if snap_map.empty?
|
204
|
-
warn
|
203
|
+
warn 'There are no snapshots to choose from, create one first.'
|
205
204
|
exit(false)
|
206
205
|
end
|
207
206
|
|
208
207
|
loop do
|
209
|
-
|
210
|
-
|
208
|
+
$stdout.write('Pick a snapshot for download: ')
|
209
|
+
$stdout.flush
|
211
210
|
|
212
|
-
i =
|
211
|
+
i = $stdin.readline.strip.to_i
|
213
212
|
next if i <= 0 || snap_map[i].nil?
|
214
213
|
|
215
214
|
return snap_map[i].id
|
@@ -10,7 +10,7 @@ module VpsAdmin::CLI::Commands
|
|
10
10
|
@opts = {
|
11
11
|
delete_after: true,
|
12
12
|
send_mail: false,
|
13
|
-
checksum: true
|
13
|
+
checksum: true
|
14
14
|
}
|
15
15
|
|
16
16
|
opts.on('-I', '--from-snapshot SNAPSHOT_ID', Integer, 'Download snapshot incrementally from SNAPSHOT_ID') do |s|
|
@@ -41,7 +41,7 @@ module VpsAdmin::CLI::Commands
|
|
41
41
|
|
42
42
|
def exec(args)
|
43
43
|
if args.size != 1
|
44
|
-
warn
|
44
|
+
warn 'Provide exactly one SNAPSHOT_ID as an argument'
|
45
45
|
exit(false)
|
46
46
|
end
|
47
47
|
|
@@ -58,7 +58,7 @@ module VpsAdmin::CLI::Commands
|
|
58
58
|
dl, created = find_or_create_dl(opts)
|
59
59
|
|
60
60
|
if created
|
61
|
-
warn_msg
|
61
|
+
warn_msg 'The download is being prepared...'
|
62
62
|
sleep(5)
|
63
63
|
|
64
64
|
else
|
@@ -75,11 +75,10 @@ module VpsAdmin::CLI::Commands
|
|
75
75
|
@api,
|
76
76
|
dl,
|
77
77
|
w,
|
78
|
-
progress: !opts[:quiet] &&
|
78
|
+
progress: !opts[:quiet] && $stderr,
|
79
79
|
max_rate: opts[:max_rate],
|
80
|
-
checksum: opts[:checksum]
|
80
|
+
checksum: opts[:checksum]
|
81
81
|
)
|
82
|
-
|
83
82
|
rescue VpsAdmin::CLI::DownloadError => e
|
84
83
|
warn e.message
|
85
84
|
exit(false)
|
@@ -89,7 +88,7 @@ module VpsAdmin::CLI::Commands
|
|
89
88
|
w.close
|
90
89
|
|
91
90
|
gz = Zlib::GzipReader.new(r)
|
92
|
-
|
91
|
+
$stdout.write(gz.readpartial(16 * 1024)) until gz.eof?
|
93
92
|
gz.close
|
94
93
|
|
95
94
|
Process.wait(pid)
|
@@ -42,15 +42,15 @@ module VpsAdmin::CLI::Commands
|
|
42
42
|
|
43
43
|
def exec(args)
|
44
44
|
if args.size < 2
|
45
|
-
puts
|
45
|
+
puts 'provide at least two VPS IDs'
|
46
46
|
exit(false)
|
47
47
|
|
48
48
|
elsif @opts[:dst_node].nil?
|
49
|
-
puts
|
49
|
+
puts 'provide --dst-node'
|
50
50
|
exit(false)
|
51
51
|
end
|
52
52
|
|
53
|
-
puts
|
53
|
+
puts 'Verifying VPS IDs...'
|
54
54
|
vpses = []
|
55
55
|
|
56
56
|
args.each do |vps_id|
|
@@ -66,44 +66,41 @@ module VpsAdmin::CLI::Commands
|
|
66
66
|
|
67
67
|
begin
|
68
68
|
if @opts[:plan]
|
69
|
-
puts
|
69
|
+
puts 'Reusing an existing migration plan...'
|
70
70
|
plan = @api.migration_plan.find(@opts[:plan])
|
71
71
|
|
72
72
|
if plan.state != 'staged'
|
73
|
-
puts
|
73
|
+
puts 'Cannot reuse a plan that has already left the staging phase'
|
74
74
|
exit(false)
|
75
75
|
end
|
76
76
|
|
77
77
|
else
|
78
|
-
puts
|
78
|
+
puts 'Creating a migration plan...'
|
79
79
|
plan = @api.migration_plan.create(@opts)
|
80
80
|
end
|
81
|
-
|
82
81
|
rescue HaveAPI::Client::ActionFailed => e
|
83
82
|
report_error(e)
|
84
83
|
end
|
85
84
|
|
86
|
-
puts
|
85
|
+
puts 'Scheduling VPS migrations...'
|
87
86
|
begin
|
88
87
|
vpses.each do |vps_id|
|
89
88
|
params = {
|
90
89
|
vps: vps_id,
|
91
|
-
dst_node: @opts[:dst_node]
|
90
|
+
dst_node: @opts[:dst_node]
|
92
91
|
}
|
93
92
|
params[:outage_window] = @opts[:outage_window] unless @opts[:outage_window].nil?
|
94
93
|
params[:cleanup_data] = @opts[:cleanup_data] unless @opts[:cleanup_data].nil?
|
95
94
|
|
96
95
|
plan.vps_migration.create(params)
|
97
96
|
end
|
98
|
-
|
99
97
|
rescue HaveAPI::Client::ActionFailed => e
|
100
98
|
report_error(e)
|
101
99
|
end
|
102
100
|
|
103
|
-
puts
|
101
|
+
puts 'Executing the migration plan'
|
104
102
|
begin
|
105
103
|
ret = plan.start
|
106
|
-
|
107
104
|
rescue HaveAPI::Client::ActionFailed => e
|
108
105
|
report_error(e)
|
109
106
|
end
|
@@ -112,6 +109,7 @@ module VpsAdmin::CLI::Commands
|
|
112
109
|
end
|
113
110
|
|
114
111
|
protected
|
112
|
+
|
115
113
|
def report_error(e)
|
116
114
|
puts e.message
|
117
115
|
|