ca44934546
The interactive shell provides tab-completion for LXC-/VM-/Node-names and IDs. CLI provides storage-management, including listing storages and there contents. Also added: Listing and downloading of APLs to storages.
185 lines
4.7 KiB
Ruby
185 lines
4.7 KiB
Ruby
module IPAddress::ToSWithNetmaskForNetworks
|
|
refine IPAddress::IPv6 do
|
|
def to_s
|
|
128 == prefix ? super() : to_string
|
|
end
|
|
end
|
|
refine IPAddress::IPv4 do
|
|
def to_s
|
|
32 == prefix ? super() : to_string
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
class Measured
|
|
class <<self
|
|
def bytes1 v
|
|
v = v.to_f
|
|
return "%d B" % v if 512 > v
|
|
%w[KiB MiBy GiByt TiByte ExiByte PetiByte].each_with_index do |m|
|
|
v /= 1024
|
|
#return "%.1f %s" % [v, m] if 10 > v
|
|
#return "%d %s" % [v, m] if 512 > v
|
|
return "%.1f %s" % [v, m] if 512 > v
|
|
end
|
|
"%d PetiByte" % v
|
|
end
|
|
|
|
def bytes2 v
|
|
r = (v.to_i / 1024 / 1024).to_s
|
|
return '·' if 0 == r
|
|
r.
|
|
reverse.
|
|
each_char.
|
|
each_slice( 3).
|
|
to_a.
|
|
reverse.
|
|
map {|a| a.reverse.join }.
|
|
join " "
|
|
end
|
|
alias bytes bytes2
|
|
|
|
def seconds i
|
|
i = i.to_i
|
|
return '·' if 0 == i
|
|
return "%d s" % i if 90 > i
|
|
i /= 60
|
|
return "%d mi" % i if 90 > i
|
|
i /= 60
|
|
return "%d hou" % i if 36 > i
|
|
i /= 24
|
|
return "%d days" % i if 14 > i
|
|
j = i / 7
|
|
return "%d weeks" % j if 25 > j
|
|
i /= 365
|
|
return "%.1f years" if 550 > i
|
|
"%dy" % i
|
|
end
|
|
end
|
|
end
|
|
|
|
class ColoredString
|
|
attr_reader :string, :color_codes
|
|
|
|
def initialize string, color_codes
|
|
@string, @color_codes = string, color_codes
|
|
end
|
|
|
|
def inspect
|
|
"#<ColoredString #{@color_codes} #{@string.inspect}>"
|
|
end
|
|
|
|
def length() @string.length end
|
|
alias size length
|
|
#def to_str() self end
|
|
def to_s() "\e[#{@color_codes}m#{@string}\e[0m" end
|
|
alias to_str to_s
|
|
#alias inspect to_str
|
|
|
|
include Comparable
|
|
def <=>(o) @string <=> o.string end
|
|
end
|
|
|
|
|
|
|
|
class TablizedOutput
|
|
def initialize header, stdout: nil, format: nil
|
|
@header = header.map &:to_s
|
|
@columnc = header.size
|
|
@format = format || ['>']*@columnc
|
|
@maxs = header.map &:length
|
|
@stdout ||= STDOUT
|
|
@lines = []
|
|
end
|
|
|
|
class B
|
|
include Comparable
|
|
def <=>(o) @v <=> o.v end
|
|
end
|
|
|
|
class V < B
|
|
attr_reader :v, :s
|
|
def initialize( v, s=nil) @v, @s = v, s || "#{v}" end
|
|
def to_s() @s end
|
|
def length() @s.length end
|
|
def inspect() "#<TO:V #{@v.inspect} #{@s.inspect}>" end
|
|
end
|
|
|
|
class Percentage < B
|
|
attr_reader :v, :w
|
|
def initialize( v, w=nil) @v, @w = v, w || 10 end
|
|
def length() @w end
|
|
def inspect() "#<TO:Percentage #{@v}%>" end
|
|
|
|
def to_s
|
|
#y = w - (v*w).round
|
|
y = (v*w).round
|
|
x = (100*v).round
|
|
r = "%*s" % [w, 0==x ? '·' : x]
|
|
#"\e[0m#{r[0...y]}\e[1;4;#{0.75>v ? 32 : 31}m#{r[y..-1]}\e[0m"
|
|
"\e[1;4;#{0.75>v ? 32 : 31}m#{r[0...y]}\e[0m#{r[y..-1]}"
|
|
end
|
|
end
|
|
|
|
def push fields
|
|
fields =
|
|
fields.map do |x|
|
|
case x
|
|
when String, ColoredString, B then x
|
|
else V.new x
|
|
end
|
|
end
|
|
@maxs = @columnc.times.map {|i| [@maxs[i], fields[i].length].max }
|
|
@lines.push fields
|
|
end
|
|
|
|
def pushs lines
|
|
lines.each &method( :push)
|
|
end
|
|
|
|
def print order: nil
|
|
format = "#{@format.map {|f| "\e[%%sm%%#{case f when '<' then '-' else ' ' end}%ds\e[0m"}.join( ' ') % @maxs}\n"
|
|
ls = @lines
|
|
if order
|
|
eval <<-EOC, binding, __FILE__, 1+__LINE__
|
|
ls = ls.sort {|a,b|
|
|
[#{order.map {|i| 0 < i ? "a[#{i-1}]" : "b[#{-i-1}]" }.join ', '}] <=>
|
|
[#{order.map {|i| 0 < i ? "b[#{i-1}]" : "a[#{-i-1}]" }.join ', '}]
|
|
}
|
|
EOC
|
|
end
|
|
#ls = ls.sort_by {|e| p e; order.map &e.method(:[]) } if order
|
|
@stdout.printf format, *@header.flat_map {|s|['',s]}
|
|
ls.each {|l| @stdout.printf format, *l.flat_map {|s| s.is_a?(ColoredString) ? [s.color_codes, s.string] : ["", s.to_s] } }
|
|
end
|
|
|
|
def virt v
|
|
ha = v.respond_to?( :ha) ? v.ha : nil
|
|
unknown = V.new 0, '-'
|
|
push [
|
|
case v.status
|
|
when "running", "online" then ColoredString.new v.status, "32"
|
|
when "stopped" then ColoredString.new v.status, "31"
|
|
else v.status
|
|
end,
|
|
ha&.state || '·',
|
|
case v.t
|
|
when "nd" then ColoredString.new v.sid, "33"
|
|
when "qm" then ColoredString.new v.sid, "35"
|
|
when "ct" then ColoredString.new v.sid, "36"
|
|
else v.sid
|
|
end,
|
|
v.name, v.node.is_a?(String) ? v.node : v.node.node,
|
|
v.respond_to?(:uptime) ? V.new( v.uptime, Measured.seconds( v.uptime)) : unknown,
|
|
v.respond_to?(:cpu) ? Percentage.new( v.cpu) : unknown,
|
|
v.respond_to?(:mem) ? V.new( v.mem, Measured.bytes( v.mem)) : unknown,
|
|
v.respond_to?(:maxmem) ? Percentage.new( v.mem/v.maxmem.to_f) : unknown,
|
|
v.respond_to?(:disk) ? V.new( v.disk.to_i, Measured.bytes( v.disk.to_i)) : unknown,
|
|
if v.respond_to?(:maxdisk) and 0 < v.maxdisk.to_i
|
|
Percentage.new( v.disk.to_f/v.maxdisk.to_f)
|
|
else unknown end,
|
|
]
|
|
end
|
|
end
|