smartos-manager 1.4.2 → 1.5.0
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/lib/smartos-manager/cli.rb +19 -2
- data/lib/smartos-manager/core.rb +126 -66
- data/lib/smartos-manager/version.rb +1 -1
- data/smartos-manager.gemspec +1 -0
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1abebbf74ccc23b8ece6cf0f8ffef49fd9f42dde
|
4
|
+
data.tar.gz: 2f94fb21b2fb5c4402124e4f7fea5c422787aa65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3282a3f79b65c4cf123311726b887251b26d93883c75d124e25f67e6b31b0b7f89b727310ee7e73945d2948dcbc9b2c34e29da04e97ec8d8e8bc99984a0e6c06
|
7
|
+
data.tar.gz: c61f046db1c6f5813ee34601c9e90152dd0ae37ae37340b451d9899af01900056d2816634f8e9e8586d9284d2f859839e1f9e7c384d6b20aa559ea91c5da48ce
|
data/lib/smartos-manager/cli.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require File.expand_path('../core', __FILE__)
|
3
3
|
require 'thor'
|
4
4
|
require 'colored'
|
5
|
+
require 'oj'
|
5
6
|
|
6
7
|
|
7
8
|
class ColorPicker
|
@@ -19,9 +20,25 @@ end
|
|
19
20
|
|
20
21
|
class AppCLI < Thor
|
21
22
|
|
23
|
+
class_option :cache, desc: "Use cached data", default: false, type: :boolean
|
24
|
+
|
25
|
+
no_tasks {
|
26
|
+
def get_registry(path = 'smartos_hosts.toml', **args)
|
27
|
+
if options[:cache] == false
|
28
|
+
begin
|
29
|
+
return SSHRegistry.new(path, **args)
|
30
|
+
rescue Errno::ENETUNREACH
|
31
|
+
puts "SSH error, falling back to cached data"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
CachedRegistry.new(path, **args)
|
36
|
+
end
|
37
|
+
}
|
38
|
+
|
22
39
|
desc "list_images", "List images available"
|
23
40
|
def list_images
|
24
|
-
registry =
|
41
|
+
registry = get_registry(cache_key: 'list_images')
|
25
42
|
ret = registry.list_images()
|
26
43
|
|
27
44
|
rev_colors = ColorPicker.new
|
@@ -38,7 +55,7 @@ class AppCLI < Thor
|
|
38
55
|
|
39
56
|
desc "list", "List all vms"
|
40
57
|
def list
|
41
|
-
registry =
|
58
|
+
registry = get_registry(cache_key: 'list')
|
42
59
|
ret = registry.list_vms()
|
43
60
|
|
44
61
|
rev_colors = ColorPicker.new
|
data/lib/smartos-manager/core.rb
CHANGED
@@ -77,73 +77,50 @@ class Image
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
|
81
|
+
class Registry
|
82
|
+
LIST_COLUMNS = %w(
|
83
|
+
uuid
|
84
|
+
type
|
85
|
+
ram
|
86
|
+
state
|
87
|
+
alias
|
88
|
+
nics.0.ip
|
89
|
+
)
|
90
|
+
|
81
91
|
attr_reader :user_columns
|
82
|
-
|
83
|
-
def initialize(path)
|
92
|
+
|
93
|
+
def initialize(path, cache_key:)
|
84
94
|
@registry = {}
|
85
|
-
@gateways = {}
|
86
95
|
@hosts = {}
|
96
|
+
@config_path = path
|
97
|
+
@cache_path = "#{path}.cache"
|
98
|
+
@cache = load_cache()
|
99
|
+
@cache_key = cache_key
|
87
100
|
|
88
|
-
@
|
89
|
-
|
90
|
-
data = TOML.load_file(path)
|
101
|
+
@config = TOML.load_file(path)
|
91
102
|
|
92
|
-
global_data =
|
93
|
-
user_columns =
|
103
|
+
@global_data = @config.delete('global')
|
104
|
+
@user_columns = @config.delete('user_columns') || {}
|
94
105
|
|
95
|
-
|
96
|
-
host = SSHHost.from_hash(name, opts, global_data)
|
97
|
-
|
106
|
+
@config.each do |name, opts|
|
107
|
+
host = SSHHost.from_hash(name, opts, @global_data)
|
98
108
|
@hosts[host.address] = host
|
99
|
-
|
100
|
-
@connection.use(host.address,
|
101
|
-
via: gateway_for(host.gateway, host.gateway_user),
|
102
|
-
# via: @gateways[host.gateway],
|
103
|
-
user: host.user,
|
104
|
-
timeout: 20,
|
105
|
-
compression: false
|
106
|
-
)
|
107
|
-
|
108
|
-
# user defined columns
|
109
|
-
@user_columns = user_columns
|
110
109
|
end
|
111
|
-
|
112
110
|
end
|
113
111
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
117
|
-
# setthe keys in cas we get nothing back
|
118
|
-
@hosts.each do |_, h|
|
119
|
-
ret[h] = ""
|
120
|
-
end
|
121
|
-
|
122
|
-
channel = @connection.exec(cmd) do |ch, stream, data|
|
123
|
-
host = @hosts[ch[:host]]
|
124
|
-
ret[host] << data
|
125
|
-
end
|
126
|
-
|
127
|
-
channel.wait()
|
128
|
-
ret
|
112
|
+
def find_host(addr)
|
113
|
+
@hosts[addr]
|
129
114
|
end
|
130
115
|
|
131
|
-
LIST_COLUMNS = %w(
|
132
|
-
uuid
|
133
|
-
type
|
134
|
-
ram
|
135
|
-
state
|
136
|
-
alias
|
137
|
-
nics.0.ip
|
138
|
-
)
|
139
|
-
|
140
116
|
def list_vms
|
141
117
|
columns = LIST_COLUMNS + @user_columns.values
|
142
118
|
|
119
|
+
ret = {}
|
143
120
|
rss = {}
|
144
121
|
|
145
122
|
# Memory used for each VM
|
146
|
-
run_on_all("zonememstat").each do |
|
123
|
+
run_on_all("zonememstat").each do |_, data|
|
147
124
|
data.split("\n").each do |line|
|
148
125
|
# ignore headers / global
|
149
126
|
unless line.start_with?(' ')
|
@@ -154,32 +131,33 @@ class HostRegistry
|
|
154
131
|
end
|
155
132
|
|
156
133
|
vms = run_on_all("vmadm list -o #{columns.join(',')} -p")
|
157
|
-
vms.each do |
|
134
|
+
vms.each do |addr, data|
|
135
|
+
host = find_host(addr)
|
158
136
|
if data
|
159
|
-
|
160
|
-
|
137
|
+
ret[host] = data.split("\n").map! do |line|
|
138
|
+
dd = {}
|
161
139
|
line.split(':', 20).each.with_index do |val, n|
|
162
|
-
|
140
|
+
dd[columns[n]] = val
|
163
141
|
end
|
164
142
|
|
165
|
-
VirtualMachine.new(
|
143
|
+
VirtualMachine.new(dd, rss)
|
166
144
|
end
|
167
145
|
else
|
168
|
-
|
146
|
+
ret[host] = []
|
169
147
|
end
|
170
148
|
end
|
171
149
|
|
150
|
+
ret
|
172
151
|
end
|
173
152
|
|
174
|
-
|
175
153
|
def list_images
|
176
154
|
ret = {}
|
177
155
|
|
178
156
|
columns = %w(uuid name version os)
|
179
157
|
|
180
158
|
images = run_on_all("imgadm list -j")
|
181
|
-
images.each do |
|
182
|
-
|
159
|
+
images.each do |addr, data|
|
160
|
+
host = find_host(addr)
|
183
161
|
json = JSON.parse(data)
|
184
162
|
|
185
163
|
ret[host] = json.map do |img_data|
|
@@ -194,7 +172,8 @@ class HostRegistry
|
|
194
172
|
def diag
|
195
173
|
ret = {}
|
196
174
|
|
197
|
-
run_on_all("prtdiag").each do |
|
175
|
+
run_on_all("prtdiag").each do |addr, data|
|
176
|
+
host = find_host(addr)
|
198
177
|
free_memory_banks = 0
|
199
178
|
|
200
179
|
system_id = data.match(/^System Configuration: (.+)$/)[1]
|
@@ -215,18 +194,21 @@ class HostRegistry
|
|
215
194
|
ret = {}
|
216
195
|
|
217
196
|
# Memory size: 8157 Megabytes
|
218
|
-
run_on_all("prtconf | head -3 | grep Mem").each do |
|
197
|
+
run_on_all("prtconf | head -3 | grep Mem").each do |addr, data|
|
198
|
+
host = find_host(addr)
|
219
199
|
_, _, mem, _ = data.split(" ")
|
220
200
|
ret[host] = {memory: mem.to_i.megabytes}
|
221
201
|
end
|
222
202
|
|
223
203
|
# main MAC address
|
224
|
-
run_on_all("ifconfig e1000g0 | grep ether | cut -d ' ' -f 2").each do |
|
204
|
+
run_on_all("ifconfig e1000g0 | grep ether | cut -d ' ' -f 2").each do |addr, data|
|
205
|
+
host = find_host(addr)
|
225
206
|
ret[host][:mac0] = data.strip()
|
226
207
|
end
|
227
208
|
|
228
209
|
# disk infos
|
229
|
-
run_on_all("diskinfo -Hp").each do |
|
210
|
+
run_on_all("diskinfo -Hp").each do |addr, data|
|
211
|
+
host = find_host(addr)
|
230
212
|
ret[host][:disks] = {}
|
231
213
|
|
232
214
|
data.split("\n").each do |line|
|
@@ -236,7 +218,8 @@ class HostRegistry
|
|
236
218
|
end
|
237
219
|
|
238
220
|
# disk size
|
239
|
-
run_on_all("zfs list -Ho name,quota,volsize").each do |
|
221
|
+
run_on_all("zfs list -Ho name,quota,volsize").each do |addr, data|
|
222
|
+
host = find_host(addr)
|
240
223
|
ret[host][:zfs_volumes] = {}
|
241
224
|
|
242
225
|
data.split("\n").each do |line|
|
@@ -248,7 +231,8 @@ class HostRegistry
|
|
248
231
|
# ARC Max Size
|
249
232
|
# zfs:0:arcstats:c:2850704524
|
250
233
|
# zfs:0:arcstats:size:1261112216
|
251
|
-
run_on_all("kstat -C zfs:0:arcstats:c zfs:0:arcstats:size").each do |
|
234
|
+
run_on_all("kstat -C zfs:0:arcstats:c zfs:0:arcstats:size").each do |addr, data|
|
235
|
+
host = find_host(addr)
|
252
236
|
zfs_arc_current = nil
|
253
237
|
zfs_arc_reserved = nil
|
254
238
|
|
@@ -268,14 +252,90 @@ class HostRegistry
|
|
268
252
|
end
|
269
253
|
|
270
254
|
# joyent_20140207T053435Z
|
271
|
-
run_on_all("uname -a | cut -d ' ' -f 4").each do |
|
255
|
+
run_on_all("uname -a | cut -d ' ' -f 4").each do |addr, data|
|
256
|
+
host = find_host(addr)
|
272
257
|
_, rev = data.strip().split('_')
|
273
258
|
ret[host][:smartos_version] = rev
|
274
259
|
end
|
275
260
|
|
276
261
|
ret
|
277
262
|
end
|
263
|
+
|
264
|
+
private
|
265
|
+
def cache_result(cmd, result)
|
266
|
+
@cache[@cache_key] ||= {}
|
267
|
+
@cache[@cache_key][cmd] = result
|
268
|
+
data = Oj.dump(@cache)
|
269
|
+
|
270
|
+
IO.write(@cache_path, data)
|
271
|
+
end
|
278
272
|
|
273
|
+
def load_cache
|
274
|
+
Oj.load_file(@cache_path)
|
275
|
+
rescue Oj::ParseError, IOError => err
|
276
|
+
{}
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
class CachedRegistry < Registry
|
283
|
+
def initialize(*)
|
284
|
+
puts "(( Using cached data ))"
|
285
|
+
super
|
286
|
+
end
|
287
|
+
|
288
|
+
def run_on_all(cmd)
|
289
|
+
if @cache[@cache_key] && @cache[@cache_key][cmd]
|
290
|
+
@cache[@cache_key][cmd]
|
291
|
+
else
|
292
|
+
puts "[#{@cache_key}] missing cache for cmd: '#{cmd}'"
|
293
|
+
{}
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
class SSHRegistry < Registry
|
300
|
+
def initialize(*)
|
301
|
+
puts "(( Using live data ))"
|
302
|
+
super
|
303
|
+
|
304
|
+
@gateways = {}
|
305
|
+
@connection = Net::SSH::Multi.start()
|
306
|
+
|
307
|
+
@hosts.each do |_, host|
|
308
|
+
@connection.use(host.address,
|
309
|
+
via: gateway_for(host.gateway, host.gateway_user),
|
310
|
+
# via: @gateways[host.gateway],
|
311
|
+
user: host.user,
|
312
|
+
timeout: 20,
|
313
|
+
compression: false
|
314
|
+
)
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
def run_on_all(cmd)
|
320
|
+
ret = {}
|
321
|
+
|
322
|
+
# set the keys in cas we get nothing back
|
323
|
+
@hosts.each do |addr, _|
|
324
|
+
ret[addr] = ""
|
325
|
+
end
|
326
|
+
|
327
|
+
channel = @connection.exec(cmd) do |ch, stream, data|
|
328
|
+
host = @hosts[ch[:host]]
|
329
|
+
ret[host.address] << data
|
330
|
+
end
|
331
|
+
|
332
|
+
channel.wait()
|
333
|
+
|
334
|
+
cache_result(cmd, ret)
|
335
|
+
|
336
|
+
ret
|
337
|
+
end
|
338
|
+
|
279
339
|
private
|
280
340
|
def gateway_for(host, user)
|
281
341
|
@gateways[host] ||= Net::SSH::Gateway.new(
|
@@ -284,5 +344,5 @@ private
|
|
284
344
|
compression: false
|
285
345
|
)
|
286
346
|
end
|
287
|
-
|
347
|
+
|
288
348
|
end
|
data/smartos-manager.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smartos-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Ammous
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: oj
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: "..."
|
112
126
|
email:
|
113
127
|
- schmurfy@gmail.com
|