status-output: colored time, nodes (re)added

master
Denis Knauf 2021-12-13 14:28:52 +01:00
parent b2d78971b0
commit ce7a95945c
4 changed files with 82 additions and 41 deletions

View File

@ -27,6 +27,7 @@ def cli_base
lambda {|n| to.virt n } lambda {|n| to.virt n }
end end
nodes = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all nodes = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all
nodes.each &push
nodes. nodes.
flat_map {|n| [ Thread.new( n, &:lxc), Thread.new( n, &:qemu) ] }. flat_map {|n| [ Thread.new( n, &:lxc), Thread.new( n, &:qemu) ] }.
each {|n| n.value.each &push } each {|n| n.value.each &push }

View File

@ -9,16 +9,25 @@ def cli_ct
end.sort.each {|c| puts c } end.sort.each {|c| puts c }
} }
ct_cli.cmd :status, "List CTs with status", aliases: [nil], &lambda {|node=nil| ct_cli.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: 'n', node: nil|
connect connect
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU Mem/MiB Disk/MiB] node &&= /\A#{node}\z/
nodes = Proxmox::Node.all to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
nodes = nodes.select {|n| node == n.name } if node push =
nodes.each do |n| if target
n.lxc.each &to.method( :virt) target = /\A#{target}\z/
end lambda {|n| to.virt n if n === target }
to.print order: [3] else
} lambda {|n| to.virt n }
end
nodes = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all
nodes.
map {|n| Thread.new( n, &:lxc) }.
each {|n| n.value.each &push }
to.print order: sort.each_char.map {|c| (2*c.ord[5]-1) * (' sainhucmd'.index( c.downcase)) }
}).
opt( :sort, '-s', '--sort=COLUMNS', "Sort by COLUMNs eg hn for host and name ([s]tatus, h[a], [i]d, [n]ame (default), [h]ost, [u]ptime, [c]pu, [m]em, [d]isk)").
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE")
ct_cli.cmd :enter, "Enter Console of CT", &lambda {|name_or_id| ct_cli.cmd :enter, "Enter Console of CT", &lambda {|name_or_id|
connect connect

View File

@ -10,16 +10,25 @@ def cli_qm
end.sort.each {|c| puts c } end.sort.each {|c| puts c }
} }
qm.cmd :status, "List VMs with status", aliases: [nil], &lambda {|node=nil| qm.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: 'n', node: nil|
connect connect
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU Mem/MiB Disk/MiB] node &&= /\A#{node}\z/
nodes = Proxmox::Node.all to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
nodes = nodes.select {|n| node == n.name } if node push =
nodes.each do |n| if target
n.qemu.each &to.method( :virt) target = /\A#{target}\z/
end lambda {|n| to.virt n if n === target }
to.print order: [3] else
} lambda {|n| to.virt n }
end
nodes = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all
nodes.
map {|n| Thread.new( n, &:qemu) }.
each {|n| n.value.each &push }
to.print order: sort.each_char.map {|c| (2*c.ord[5]-1) * (' sainhucmd'.index( c.downcase)) }
}).
opt( :sort, '-s', '--sort=COLUMNS', "Sort by COLUMNs eg hn for host and name ([s]tatus, h[a], [i]d, [n]ame (default), [h]ost, [u]ptime, [c]pu, [m]em, [d]isk)").
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE")
qm.cmd :exec, "Executes Command in VM via qemu-guest-agent", min: 4, &lambda {|name_or_id, *command| qm.cmd :exec, "Executes Command in VM via qemu-guest-agent", min: 4, &lambda {|name_or_id, *command|
connect connect

View File

@ -13,17 +13,24 @@ end
class Measured class Measured
class V
attr_reader :value, :length
def initialize( value, length = nil) @value, @length = value, length || value.length end
def inspect() "#<Measured::V #{@value.inspect} (#{@length})>" end
alias :to_s :value
alias :to_str :value
end
class <<self class <<self
def bytes1 v def bytes1 v
v = v.to_f v = v.to_f
return "%d B" % v if 512 > v return units '%d ' % v , :B if 512 > v
%w[KiB MiBy GiByt TiByte ExiByte PetiByte].each_with_index do |m| %w[KiB MiBy GiByt TiByte ExiByte PetiByte].each_with_index do |m|
v /= 1024 v /= 1024
#return "%.1f %s" % [v, m] if 10 > v return units '%.1f ' % v, m if 512 > v
#return "%d %s" % [v, m] if 512 > v
return "%.1f %s" % [v, m] if 512 > v
end end
"%d PetiByte" % v units '%d ' % v, :PetiByte
end end
def bytes2 v def bytes2 v
@ -40,21 +47,28 @@ class Measured
end end
alias bytes bytes2 alias bytes bytes2
def units val, unit
v = "#{val}\e[1;30m#{unit}\e[0m"
V.new v, v.length - 11
end
def seconds i def seconds i
i = i.to_i i = i.to_i
return '·' if 0 == i return V.new "\e[1;30m·\e[0m", 1 if 0 == i
return "%d s" % i if 90 > i return units '%d ' % i, :s if 90 > i
i /= 60 i /= 60
return "%d mi" % i if 90 > i return units '%d ' % i, :mi if 90 > i
i /= 60 i /= 60
return "%d hou" % i if 36 > i return units '%d ' % i, :hou if 36 > i
i /= 24 i /= 24
return "%d days" % i if 14 > i return units '%d ' % i, :days if 14 > i
j = i / 7 j = i / 7
return "%d weeks" % j if 25 > j return units '%d ' % j, :weeks if 8 > j
i /= 365 j = i / 30
return "%.1f years" if 550 > i return units '%d ' % j, :months if 11 > j
"%dy" % i i /= 365.0
return units '%.2f ' % i, :years if 550 > i
units '%d ' % i, :years
end end
end end
end end
@ -72,10 +86,8 @@ class ColoredString
def length() @string.length end def length() @string.length end
alias size length alias size length
#def to_str() self end
def to_s() "\e[#{@color_codes}m#{@string}\e[0m" end def to_s() "\e[#{@color_codes}m#{@string}\e[0m" end
alias to_str to_s alias to_str to_s
#alias inspect to_str
include Comparable include Comparable
def <=>(o) @string <=> o.string end def <=>(o) @string <=> o.string end
@ -101,7 +113,7 @@ class TablizedOutput
class V < B class V < B
attr_reader :v, :s attr_reader :v, :s
def initialize( v, s=nil) @v, @s = v, s || "#{v}" end def initialize( v, s=nil) @v, @s = v, s || "#{v}" end
def to_s() @s end def to_s() @s.to_s end
def length() @s.length end def length() @s.length end
def inspect() "#<TO:V #{@v.inspect} #{@s.inspect}>" end def inspect() "#<TO:V #{@v.inspect} #{@s.inspect}>" end
end end
@ -113,11 +125,9 @@ class TablizedOutput
def inspect() "#<TO:Percentage #{@v}%>" end def inspect() "#<TO:Percentage #{@v}%>" end
def to_s def to_s
#y = w - (v*w).round
y = (v*w).round y = (v*w).round
x = (100*v).round x = (100*v).round
r = "%*s" % [w, 0==x ? '·' : x] 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]}" "\e[1;4;#{0.75>v ? 32 : 31}m#{r[0...y]}\e[0m#{r[y..-1]}"
end end
end end
@ -139,7 +149,6 @@ class TablizedOutput
end end
def print order: nil def print order: nil
format = "#{@format.map {|f| "\e[%%sm%%#{case f when '<' then '-' else ' ' end}%ds\e[0m"}.join( ' ') % @maxs}\n"
ls = @lines ls = @lines
if order if order
eval <<-EOC, binding, __FILE__, 1+__LINE__ eval <<-EOC, binding, __FILE__, 1+__LINE__
@ -149,9 +158,22 @@ class TablizedOutput
} }
EOC EOC
end end
#ls = ls.sort_by {|e| p e; order.map &e.method(:[]) } if order @stdout.puts \
@stdout.printf format, *@header.flat_map {|s|['',s]} @header.each_with_index.map {|s, i|
ls.each {|l| @stdout.printf format, *l.flat_map {|s| s.is_a?(ColoredString) ? [s.color_codes, s.string] : ["", s.to_s] } } "#{' ' * (@maxs[i] - s.length)}#{s}"
}.join( ' ')
ls.each_with_index do |l|
@stdout.puts \
l.each_with_index.map {|s, i|
pad = ' ' * (@maxs[i] - s.length)
case @format[i]
when '<'
"#{s}#{pad}"
else
"#{pad}#{s}"
end
}.join( ' ')
end
end end
def virt v def virt v