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 }
end
nodes = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all
nodes.each &push
nodes.
flat_map {|n| [ Thread.new( n, &:lxc), Thread.new( n, &:qemu) ] }.
each {|n| n.value.each &push }

View File

@ -9,16 +9,25 @@ def cli_ct
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
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU Mem/MiB Disk/MiB]
nodes = Proxmox::Node.all
nodes = nodes.select {|n| node == n.name } if node
nodes.each do |n|
n.lxc.each &to.method( :virt)
end
to.print order: [3]
}
node &&= /\A#{node}\z/
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
push =
if target
target = /\A#{target}\z/
lambda {|n| to.virt n if n === target }
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|
connect

View File

@ -10,16 +10,25 @@ def cli_qm
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
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU Mem/MiB Disk/MiB]
nodes = Proxmox::Node.all
nodes = nodes.select {|n| node == n.name } if node
nodes.each do |n|
n.qemu.each &to.method( :virt)
end
to.print order: [3]
}
node &&= /\A#{node}\z/
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
push =
if target
target = /\A#{target}\z/
lambda {|n| to.virt n if n === target }
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|
connect

View File

@ -13,17 +13,24 @@ end
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
def bytes1 v
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|
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
return units '%.1f ' % v, m if 512 > v
end
"%d PetiByte" % v
units '%d ' % v, :PetiByte
end
def bytes2 v
@ -40,21 +47,28 @@ class Measured
end
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
i = i.to_i
return '·' if 0 == i
return "%d s" % i if 90 > i
return V.new "\e[1;30m·\e[0m", 1 if 0 == i
return units '%d ' % i, :s if 90 > i
i /= 60
return "%d mi" % i if 90 > i
return units '%d ' % i, :mi if 90 > i
i /= 60
return "%d hou" % i if 36 > i
return units '%d ' % i, :hou if 36 > i
i /= 24
return "%d days" % i if 14 > i
return units '%d ' % i, :days if 14 > i
j = i / 7
return "%d weeks" % j if 25 > j
i /= 365
return "%.1f years" if 550 > i
"%dy" % i
return units '%d ' % j, :weeks if 8 > j
j = i / 30
return units '%d ' % j, :months if 11 > j
i /= 365.0
return units '%.2f ' % i, :years if 550 > i
units '%d ' % i, :years
end
end
end
@ -72,10 +86,8 @@ class ColoredString
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
@ -101,7 +113,7 @@ class TablizedOutput
class V < B
attr_reader :v, :s
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 inspect() "#<TO:V #{@v.inspect} #{@s.inspect}>" end
end
@ -113,11 +125,9 @@ class TablizedOutput
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
@ -139,7 +149,6 @@ class TablizedOutput
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__
@ -149,9 +158,22 @@ class TablizedOutput
}
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] } }
@stdout.puts \
@header.each_with_index.map {|s, i|
"#{' ' * (@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
def virt v