vpsadmin-client 3.0.0.master.20240728.pre.0.dc5474cc → 3.0.0.master.202211181.pre.0.ac358990
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/Gemfile +0 -4
- data/Rakefile +1 -0
- data/lib/{terminal_size.rb → terminal-size.rb} +17 -23
- data/lib/vpsadmin/cli/commands/backup_dataset.rb +98 -96
- 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 +59 -65
- data/lib/vpsadmin/cli/commands/snapshot_download.rb +21 -20
- data/lib/vpsadmin/cli/commands/snapshot_send.rb +7 -6
- data/lib/vpsadmin/cli/commands/vps_migrate_many.rb +12 -10
- data/lib/vpsadmin/cli/commands/vps_remote_console.rb +30 -29
- data/lib/vpsadmin/cli/stream_downloader.rb +45 -38
- data/lib/vpsadmin/cli.rb +2 -2
- data/lib/vpsadmin/client/version.rb +1 -1
- data/lib/vpsadmin/client.rb +3 -2
- data/shell.nix +6 -6
- data/vpsadmin-client.gemspec +10 -7
- metadata +38 -10
@@ -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)
|
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,20 +24,19 @@ 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
|
-
|
41
40
|
puts name
|
42
41
|
end
|
43
42
|
|
@@ -49,7 +48,7 @@ module VpsAdmin::CLI::Commands
|
|
49
48
|
start_color
|
50
49
|
crmode
|
51
50
|
stdscr.keypad = true
|
52
|
-
curs_set(0)
|
51
|
+
curs_set(0) # hide cursor
|
53
52
|
use_default_colors
|
54
53
|
|
55
54
|
init_pair(1, COLOR_BLACK, COLOR_WHITE)
|
@@ -89,25 +88,24 @@ module VpsAdmin::CLI::Commands
|
|
89
88
|
clear
|
90
89
|
end
|
91
90
|
end
|
91
|
+
|
92
92
|
rescue Interrupt
|
93
|
-
# break loop and exit
|
94
93
|
ensure
|
95
94
|
close_screen
|
96
95
|
end
|
97
96
|
|
98
97
|
protected
|
99
|
-
|
100
98
|
def set_global_opts
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
99
|
+
if @global_opts[:output]
|
100
|
+
@params = @global_opts[:output].split(',').map(&:to_sym)
|
101
|
+
else
|
102
|
+
@params = %i(bytes bytes_in bytes_out packets packets_in packets_out)
|
103
|
+
end
|
106
104
|
|
107
105
|
if @global_opts[:sort]
|
108
|
-
|
109
|
-
@sort_desc =
|
110
|
-
@sort_param = (
|
106
|
+
v = @global_opts[:sort]
|
107
|
+
@sort_desc = v.start_with?('-')
|
108
|
+
@sort_param = (v.start_with?('-') ? v[1..-1] : v).to_sym
|
111
109
|
|
112
110
|
else
|
113
111
|
@sort_desc = true
|
@@ -119,21 +117,19 @@ module VpsAdmin::CLI::Commands
|
|
119
117
|
@params.each do |p|
|
120
118
|
title = p.to_s.split('_').map do |v|
|
121
119
|
if @opts[:unit] == :bits
|
122
|
-
v.to_s.gsub(
|
120
|
+
v.to_s.gsub(/bytes/, 'bits').capitalize
|
123
121
|
|
124
122
|
else
|
125
123
|
v.capitalize
|
126
124
|
end
|
127
|
-
end.join
|
128
|
-
|
129
|
-
title << '/s'
|
125
|
+
end.join('') + '/s'
|
130
126
|
|
131
127
|
size = title.size + 1
|
132
128
|
|
133
129
|
@columns << {
|
134
130
|
name: p,
|
135
|
-
title
|
136
|
-
width:
|
131
|
+
title: title,
|
132
|
+
width: size < 8 ? 8 : size,
|
137
133
|
}
|
138
134
|
end
|
139
135
|
end
|
@@ -141,12 +137,12 @@ module VpsAdmin::CLI::Commands
|
|
141
137
|
def fetch
|
142
138
|
return @data if @data
|
143
139
|
|
144
|
-
limit = @opts[:limit] ||
|
140
|
+
limit = @opts[:limit] || lines - 6
|
145
141
|
|
146
|
-
params =
|
142
|
+
params = {
|
147
143
|
limit: limit > 0 ? limit : 25,
|
148
144
|
order: "#{@sort_desc ? '-' : ''}#{@sort_param}",
|
149
|
-
meta: {
|
145
|
+
meta: {includes: 'network_interface'},
|
150
146
|
}
|
151
147
|
|
152
148
|
FILTERS.each do |f|
|
@@ -192,11 +188,11 @@ module VpsAdmin::CLI::Commands
|
|
192
188
|
unless @header
|
193
189
|
fmt = (['%8s', '%-15s'] + @columns.map { |c| "%#{c[:width]}s" }).join(' ')
|
194
190
|
|
195
|
-
@header =
|
191
|
+
@header = sprintf(
|
196
192
|
fmt,
|
197
193
|
'VPS',
|
198
194
|
'Interface',
|
199
|
-
*@columns.map { |c| c[:title] }
|
195
|
+
*@columns.map { |c| c[:title] },
|
200
196
|
)
|
201
197
|
|
202
198
|
@header << (' ' * (cols - @header.size)) << "\n"
|
@@ -206,30 +202,30 @@ module VpsAdmin::CLI::Commands
|
|
206
202
|
end
|
207
203
|
|
208
204
|
def print_row(data)
|
209
|
-
addstr(
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
205
|
+
addstr(sprintf(
|
206
|
+
'%8s %-15s',
|
207
|
+
data.network_interface.vps_id,
|
208
|
+
data.network_interface.name,
|
209
|
+
))
|
214
210
|
|
215
211
|
@columns.each do |c|
|
216
212
|
p = c[:name]
|
217
213
|
|
218
214
|
attron(A_BOLD) if p == @sort_param
|
219
|
-
addstr(
|
215
|
+
addstr(sprintf(" %#{c[:width]}s", unitize_param(p, data.send(p), data.delta)))
|
220
216
|
attroff(A_BOLD) if p == @sort_param
|
221
217
|
end
|
222
218
|
end
|
223
219
|
|
224
220
|
def stats
|
225
|
-
fields = %i
|
221
|
+
fields = %i(bytes packets)
|
226
222
|
stats = {}
|
227
223
|
delta_sum = 0
|
228
224
|
|
229
225
|
fields.each do |f|
|
230
226
|
stats[f] = 0
|
231
227
|
|
232
|
-
%i
|
228
|
+
%i(in out).each do |dir|
|
233
229
|
stats[:"#{f}_#{dir}"] = 0
|
234
230
|
end
|
235
231
|
end
|
@@ -240,7 +236,7 @@ module VpsAdmin::CLI::Commands
|
|
240
236
|
fields.each do |f|
|
241
237
|
stats[f] += data.send(f)
|
242
238
|
|
243
|
-
%i
|
239
|
+
%i(in out).each do |dir|
|
244
240
|
stats[:"#{f}_#{dir}"] += data.send("#{f}_#{dir}")
|
245
241
|
end
|
246
242
|
end
|
@@ -248,43 +244,41 @@ module VpsAdmin::CLI::Commands
|
|
248
244
|
|
249
245
|
avg_delta = delta_sum.to_f / fetch.count
|
250
246
|
|
251
|
-
setpos(lines
|
247
|
+
setpos(lines-5, 0)
|
252
248
|
addstr('─' * cols)
|
253
249
|
|
254
250
|
fmt = '%10s %10s %10s'
|
255
251
|
unit = @opts[:unit].to_s.capitalize
|
256
252
|
|
257
|
-
setpos(lines
|
258
|
-
addstr(
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
253
|
+
setpos(lines-4, 0)
|
254
|
+
addstr(sprintf(
|
255
|
+
fmt,
|
256
|
+
'',
|
257
|
+
"#{unit}/s",
|
258
|
+
'Packets/s',
|
259
|
+
))
|
264
260
|
|
265
|
-
setpos(lines
|
266
|
-
addstr(
|
261
|
+
setpos(lines-3, 0)
|
262
|
+
addstr(sprintf(fmt, 'In', *fields.map { |f| unitize_param(f, stats[:"#{f}_in"], avg_delta) }))
|
267
263
|
|
268
|
-
setpos(lines
|
269
|
-
addstr(
|
264
|
+
setpos(lines-2, 0)
|
265
|
+
addstr(sprintf(fmt, 'Out', *fields.map { |f| unitize_param(f, stats[:"#{f}_out"], avg_delta) }))
|
270
266
|
|
271
|
-
setpos(lines
|
267
|
+
setpos(lines-1, 0)
|
272
268
|
attron(A_BOLD)
|
273
|
-
addstr(
|
274
|
-
unitize_param(f, stats[:"#{f}_in"] + stats[:"#{f}_out"], avg_delta)
|
275
|
-
end))
|
269
|
+
addstr(sprintf(fmt, 'Total', *fields.map { |f| unitize_param(f, stats[:"#{f}_in"] + stats[:"#{f}_out"], avg_delta) }))
|
276
270
|
attroff(A_BOLD)
|
277
271
|
end
|
278
272
|
|
279
273
|
def unitize_bytes(n, delta)
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
274
|
+
if @opts[:unit] == :bytes
|
275
|
+
per_s = n / delta.to_f
|
276
|
+
else
|
277
|
+
per_s = n * 8 / delta.to_f
|
278
|
+
end
|
285
279
|
|
286
280
|
bits = 39
|
287
|
-
units = %w
|
281
|
+
units = %w(T G M k)
|
288
282
|
|
289
283
|
units.each do |u|
|
290
284
|
threshold = 2 << bits
|
@@ -300,7 +294,7 @@ module VpsAdmin::CLI::Commands
|
|
300
294
|
def unitize_number(n, delta)
|
301
295
|
per_s = n / delta.to_f
|
302
296
|
threshold = 1_000_000_000_000
|
303
|
-
units = %w
|
297
|
+
units = %w(T G M k)
|
304
298
|
|
305
299
|
units.each do |u|
|
306
300
|
return "#{(per_s / threshold).round(2)}#{u}" if per_s >= threshold
|
@@ -318,7 +312,7 @@ module VpsAdmin::CLI::Commands
|
|
318
312
|
when :packets, :packets_in, :packets_out
|
319
313
|
unitize_number(n, delta)
|
320
314
|
else
|
321
|
-
|
315
|
+
fail "unknown param to unitize: #{param.inspect}"
|
322
316
|
end
|
323
317
|
end
|
324
318
|
|
@@ -341,10 +335,10 @@ module VpsAdmin::CLI::Commands
|
|
341
335
|
|
342
336
|
ips = @api.ip_address.list(addr: v)
|
343
337
|
return false if ips.count < 1
|
344
|
-
|
345
338
|
ips.first.id
|
339
|
+
|
346
340
|
rescue HaveAPI::Client::ActionFailed
|
347
|
-
false
|
341
|
+
return false
|
348
342
|
end
|
349
343
|
end
|
350
344
|
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.size == 0 && 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,14 +104,16 @@ 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
|
+
|
112
113
|
rescue VpsAdmin::CLI::DownloadError => e
|
113
114
|
warn e.message
|
114
115
|
exit(false)
|
116
|
+
|
115
117
|
ensure
|
116
118
|
f.close
|
117
119
|
end
|
@@ -120,28 +122,27 @@ module VpsAdmin::CLI::Commands
|
|
120
122
|
end
|
121
123
|
|
122
124
|
protected
|
123
|
-
|
124
125
|
def open_file(path)
|
125
126
|
f = action = nil
|
126
127
|
pos = 0
|
127
128
|
|
128
|
-
if File.
|
129
|
+
if File.exists?(path) && File.size(path) > 0
|
129
130
|
if @opts[:resume]
|
130
131
|
action = :resume
|
131
132
|
|
132
133
|
elsif @opts[:force]
|
133
134
|
action = :overwrite
|
134
135
|
|
135
|
-
elsif
|
136
|
+
elsif STDIN.tty?
|
136
137
|
while action.nil?
|
137
|
-
|
138
|
-
|
138
|
+
STDERR.write("'#{path}' already exists. [A]bort, [r]esume or [o]verwrite? [a]: ")
|
139
|
+
STDERR.flush
|
139
140
|
|
140
141
|
action = {
|
141
142
|
'r' => :resume,
|
142
143
|
'o' => :overwrite,
|
143
|
-
'' => false
|
144
|
-
}[
|
144
|
+
'' => false,
|
145
|
+
}[STDIN.readline.strip.downcase]
|
145
146
|
end
|
146
147
|
|
147
148
|
else
|
@@ -185,7 +186,7 @@ module VpsAdmin::CLI::Commands
|
|
185
186
|
snapshots = ds.snapshot.index
|
186
187
|
next if snapshots.empty?
|
187
188
|
|
188
|
-
if
|
189
|
+
if vps = ds_map[ds.id]
|
189
190
|
puts "VPS ##{vps.id}"
|
190
191
|
|
191
192
|
else
|
@@ -200,15 +201,15 @@ module VpsAdmin::CLI::Commands
|
|
200
201
|
end
|
201
202
|
|
202
203
|
if snap_map.empty?
|
203
|
-
warn
|
204
|
+
warn "There are no snapshots to choose from, create one first."
|
204
205
|
exit(false)
|
205
206
|
end
|
206
207
|
|
207
208
|
loop do
|
208
|
-
|
209
|
-
|
209
|
+
STDOUT.write('Pick a snapshot for download: ')
|
210
|
+
STDOUT.flush
|
210
211
|
|
211
|
-
i =
|
212
|
+
i = STDIN.readline.strip.to_i
|
212
213
|
next if i <= 0 || snap_map[i].nil?
|
213
214
|
|
214
215
|
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,10 +75,11 @@ 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
|
+
|
82
83
|
rescue VpsAdmin::CLI::DownloadError => e
|
83
84
|
warn e.message
|
84
85
|
exit(false)
|
@@ -88,7 +89,7 @@ module VpsAdmin::CLI::Commands
|
|
88
89
|
w.close
|
89
90
|
|
90
91
|
gz = Zlib::GzipReader.new(r)
|
91
|
-
|
92
|
+
STDOUT.write(gz.readpartial(16*1024)) while !gz.eof?
|
92
93
|
gz.close
|
93
94
|
|
94
95
|
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,41 +66,44 @@ 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
|
+
|
81
82
|
rescue HaveAPI::Client::ActionFailed => e
|
82
83
|
report_error(e)
|
83
84
|
end
|
84
85
|
|
85
|
-
puts
|
86
|
+
puts "Scheduling VPS migrations..."
|
86
87
|
begin
|
87
88
|
vpses.each do |vps_id|
|
88
89
|
params = {
|
89
90
|
vps: vps_id,
|
90
|
-
dst_node: @opts[:dst_node]
|
91
|
+
dst_node: @opts[:dst_node],
|
91
92
|
}
|
92
93
|
params[:outage_window] = @opts[:outage_window] unless @opts[:outage_window].nil?
|
93
94
|
params[:cleanup_data] = @opts[:cleanup_data] unless @opts[:cleanup_data].nil?
|
94
95
|
|
95
96
|
plan.vps_migration.create(params)
|
96
97
|
end
|
98
|
+
|
97
99
|
rescue HaveAPI::Client::ActionFailed => e
|
98
100
|
report_error(e)
|
99
101
|
end
|
100
102
|
|
101
|
-
puts
|
103
|
+
puts "Executing the migration plan"
|
102
104
|
begin
|
103
105
|
ret = plan.start
|
106
|
+
|
104
107
|
rescue HaveAPI::Client::ActionFailed => e
|
105
108
|
report_error(e)
|
106
109
|
end
|
@@ -109,7 +112,6 @@ module VpsAdmin::CLI::Commands
|
|
109
112
|
end
|
110
113
|
|
111
114
|
protected
|
112
|
-
|
113
115
|
def report_error(e)
|
114
116
|
puts e.message
|
115
117
|
|