UPID-Parser, Task status & monitoring
This commit is contained in:
parent
83211a817f
commit
6530c40749
|
@ -380,9 +380,9 @@ class PVE::Cli
|
|||
end
|
||||
status =
|
||||
case status
|
||||
when /\Asta(r(t(ed?)?)?)?\z/i, /\Aon(l(i(ne?)?)?)?\z/i, /\Ar(u(n(n(i(ng?)?)?)?)?)?\z/i, '1'
|
||||
when /\Asta(?:r(?:t(?:ed?)?)?)?\z/i, /\Aon(?:l(?:i(?:ne?)?)?)?\z/i, /\Ar(?:u(?:n(?:n(?:i(?:ng?)?)?)?)?)?\z/i, '1'
|
||||
%i[started online running]
|
||||
when /\Asto(p(p(ed?)?)?)?\z/i, /\Aof(f(l(i(ne?)?)?)?)?\z/i, '0'
|
||||
when /\Asto(?:p(?:p(?:ed?)?)?)?\z/i, /\Aof(?:f(?:l(?:i(?:ne?)?)?)?)?\z/i, '0'
|
||||
%i[stopped offline]
|
||||
when nil, '', /\Aa(ll?)?\z/i then nil
|
||||
else
|
||||
|
@ -533,7 +533,7 @@ class PVE::Cli
|
|||
end
|
||||
[
|
||||
case v.status
|
||||
when :running, :online then ColoredString.new v.status, "32"
|
||||
when :running, :online then ColoredString.new v.status, "32"
|
||||
when :stopped, :offline then ColoredString.new v.status, "31"
|
||||
else v.status
|
||||
end,
|
||||
|
@ -546,14 +546,14 @@ class PVE::Cli
|
|||
end,
|
||||
v.name, node,
|
||||
v.respond_to?(:uptime) ? TablizedOutput::V.new( v.uptime, Measured.seconds( v.uptime)) : unknown,
|
||||
v.respond_to?(:cpu) ? TablizedOutput::Percentage.new( v.cpu) : unknown,
|
||||
v.respond_to?(:mem) ? TablizedOutput::V.new( v.mem, Measured.bytes( v.mem)) : unknown,
|
||||
v.respond_to?(:cpu) ? TablizedOutput::Percentage.new( v.cpu) : unknown,
|
||||
v.respond_to?(:mem) ? TablizedOutput::V.new( v.mem, Measured.bytes( v.mem)) : unknown,
|
||||
v.respond_to?(:maxmem) ? TablizedOutput::Percentage.new( v.mem/v.maxmem.to_f) : unknown,
|
||||
v.respond_to?(:disk) ? TablizedOutput::V.new( v.disk.to_i, Measured.bytes( v.disk.to_i)) : unknown,
|
||||
v.respond_to?(:disk) ? TablizedOutput::V.new( v.disk.to_i, Measured.bytes( v.disk.to_i)) : unknown,
|
||||
if v.respond_to?(:maxdisk) and 0 < v.maxdisk.to_i
|
||||
TablizedOutput::Percentage.new( v.disk.to_f/v.maxdisk.to_f)
|
||||
else unknown end,
|
||||
v.respond_to?(:tags) ? v.tags.join(', ') : '',
|
||||
v.respond_to?(:tags) ? v.tags.join(', ') : '',
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,33 @@
|
|||
class PVE::Cli
|
||||
def task_table order: nil, &exe
|
||||
to = TablizedOutput.new %w[S Starttime Node SID Type UPID], format: '<<<<<<'
|
||||
hosted = {}
|
||||
Proxmox::Hosted.all.each {|h| hosted[h.vmid.to_i] = h }
|
||||
hosted.delete nil
|
||||
exe.call lambda {|t|
|
||||
u = t.upid
|
||||
v = u.id ? hosted[u.id.to_i] : t.node
|
||||
to.push [
|
||||
case t.status.state
|
||||
when :running then ColoredString.new '...', '30'
|
||||
when :success then ColoredString.new 'OK', '32'
|
||||
when :failed then ColoredString.new 'failed', '31'
|
||||
end,
|
||||
u.starttime.strftime( '%Y-%m-%d %H:%M:%S'),
|
||||
u.node,
|
||||
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'
|
||||
when nil then u.id.inspect
|
||||
else v.sid
|
||||
end,
|
||||
u.dtype, u.upid
|
||||
]
|
||||
}
|
||||
to.print order: order
|
||||
end
|
||||
|
||||
def cli_task
|
||||
cli.sub :task, "Inspect tasks" do |tcli|
|
||||
tcli.cmd :list, "List done tasks", &lambda {|node=nil|
|
||||
|
@ -7,7 +36,7 @@ def cli_task
|
|||
nodes = nodes.select {|n| node == n.name } if node
|
||||
nodes.flat_map do |n|
|
||||
n.tasks.map &:upid
|
||||
end.sort.each {|upid| puts upid }
|
||||
end.sort_by(&:upid).each {|upid| puts upid }
|
||||
}
|
||||
|
||||
tcli.cmd :get, "Inspect a task", &lambda {|upid|
|
||||
|
@ -22,21 +51,39 @@ def cli_task
|
|||
end
|
||||
}
|
||||
|
||||
tcli.cmd :status, "Shows tasks states", &lambda {|upid|
|
||||
}
|
||||
tcli.cmd( :status, "Lists tasks with status", aliases: [nil], &lambda {|target=nil, sort: nil, node: nil, status: nil|
|
||||
connect
|
||||
task_table order: [2] do |push|
|
||||
Proxmox::Node.all.each {|n| n.tasks.each {|t| p t; push.call t } }
|
||||
end
|
||||
})
|
||||
|
||||
tcli.cmd :monitor, "Monitors running tasks", &lambda {|node: nil|
|
||||
tcli.cmd( :monitor, "Monitors running tasks", &lambda {|node: nil|
|
||||
connect
|
||||
nodes = Proxmox::Node.all
|
||||
nodes = nodes.select {|n| node == n.name } if node
|
||||
tasks = {}
|
||||
loop do
|
||||
nodes.flat_map do |n|
|
||||
n.tasks.map &:upid
|
||||
end.sort.each do |upid|
|
||||
nodes.each {|n| n.tasks.each {|t| tasks[t.upid.upid] = true } }
|
||||
begin
|
||||
loop do
|
||||
task_table order: [2] do |push|
|
||||
begin
|
||||
nodes.
|
||||
flat_map {|n| n.tasks }.
|
||||
select {|t| tasks[t.upid.upid] != true or t.running? }.
|
||||
each( &push)
|
||||
STDERR.print "\e[2J\e[1;1H"
|
||||
rescue RestClient::InternalServerError
|
||||
end
|
||||
end
|
||||
sleep 1
|
||||
end
|
||||
rescue Interrupt
|
||||
STDERR.print "\e[2J\e[1;1H"
|
||||
end
|
||||
}
|
||||
})
|
||||
|
||||
tcli.cmd( :help, '', aliases: ['-h', '--help']) {|*args| help ct_cli, *args }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,8 @@ module Proxmox
|
|||
end
|
||||
class AlreadyLocked < Exception
|
||||
end
|
||||
class UnparsableUPID < Exception
|
||||
end
|
||||
|
||||
def self.cnfstr2hash str
|
||||
str.
|
||||
|
@ -84,7 +86,7 @@ module Proxmox
|
|||
end
|
||||
|
||||
def self.find_by_vmid vmid
|
||||
Proxmox::LXC.find_by_vmid( vmid) || Proxmox::Qemu.find_by_vmid( vmid) || Proxmox::Node.find_by_vmid( vmid)
|
||||
Proxmox::LXC.find_by_vmid( vmid) || Proxmox::Qemu.find_by_vmid( vmid)
|
||||
end
|
||||
|
||||
def self.find name_or_id
|
||||
|
@ -299,12 +301,22 @@ module Proxmox
|
|||
def refresh!
|
||||
d = rest_get @rest_prefix
|
||||
d[:starttime] &&= Time.at d[:starttime]
|
||||
d = {exitstatus: nil}.merge d
|
||||
__update__ d.merge( node: @node, upid: @upid, task: @task)
|
||||
end
|
||||
|
||||
def __update__ **data
|
||||
data = data.merge t: 'status'
|
||||
data[:status] = data[:status]&.to_sym
|
||||
data[:exitstatus] = data[:exitstatus]&.to_sym
|
||||
data[:state] =
|
||||
case data[:status]
|
||||
when :running then :running
|
||||
when :stopped
|
||||
case data[:exitstatus]
|
||||
when :OK then :success
|
||||
else :failed
|
||||
end
|
||||
end
|
||||
super **data
|
||||
end
|
||||
|
||||
|
@ -319,11 +331,51 @@ module Proxmox
|
|||
"#<#{self.class.name}|#{@upid} node=#{@node.node} #{h.join ' '}>"
|
||||
end
|
||||
|
||||
def running?() 'running' == @status end
|
||||
def finished?() 'stopped' == @status end
|
||||
def running?() :running == @status end
|
||||
def finished?() :stopped == @status end
|
||||
alias stopped? finished?
|
||||
def successfull?() stopped? ? 'OK' == @exitstatus : nil end
|
||||
def failed?() stopped? ? 'OK' != @exitstatus : nil end
|
||||
def successfull?() stopped? ? :OK == @exitstatus : nil end
|
||||
def failed?() stopped? ? :OK != @exitstatus : nil end
|
||||
end
|
||||
|
||||
def running?() status.running? end
|
||||
def finished?() status.finished? end
|
||||
alias stopped? finished?
|
||||
def successfull?() status.successfull? end
|
||||
def failed?() status.failed? end
|
||||
|
||||
class UPID
|
||||
RE =
|
||||
/^
|
||||
UPID :
|
||||
(?<node>[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?) :
|
||||
(?<pid>[0-9A-Fa-f]{8}) :
|
||||
(?<pstart>[0-9A-Fa-f]{8,9}) :
|
||||
(?<starttime>[0-9A-Fa-f]{8}) :
|
||||
(?<dtype>[^:\s]+) :
|
||||
(?<id>[^:\s]*) :
|
||||
(?<user>[^:\s]+) :
|
||||
$/x
|
||||
|
||||
attr_reader :upid, :node, :pid, :pstart, :starttime, :dtype, :id, :user
|
||||
alias to_s upid
|
||||
|
||||
def initialize upid
|
||||
m = RE.match upid
|
||||
raise UnparsableUPID, "UPID cannot be parsed: #{upid.inspect} (#{upid.class})" unless m
|
||||
@upid = upid
|
||||
@node = m[:node]
|
||||
@pid = m[:pid].to_i 16
|
||||
@pstart = m[:pstart].to_i 16
|
||||
@starttime = Time.at m[:starttime].to_i( 16)
|
||||
@dtype = m[:dtype]
|
||||
@id = case m[:id] when '' then nil else m[:id].to_i end
|
||||
@user = m[:user]
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class.name} #{@upid}>"
|
||||
end
|
||||
end
|
||||
|
||||
def rest_prefix
|
||||
|
@ -332,7 +384,7 @@ module Proxmox
|
|||
|
||||
def initialize
|
||||
rest_prefix
|
||||
@sid = upid
|
||||
@sid, @upid = upid, UPID.new( upid)
|
||||
end
|
||||
|
||||
def inspect
|
||||
|
@ -349,6 +401,10 @@ module Proxmox
|
|||
end
|
||||
|
||||
class Hosted < Base
|
||||
def self.all
|
||||
Node.all.flat_map {|n| n.qemu + n.lxc }
|
||||
end
|
||||
|
||||
def refresh!
|
||||
__updata__ rest_get( "#{@rest_prefix}/status/current").merge( node: @node, t: @t)
|
||||
end
|
||||
|
@ -450,25 +506,23 @@ module Proxmox
|
|||
rest_put "#{@rest_prefix}/config", **r
|
||||
end
|
||||
|
||||
# it is only allowed to lock local guests, because it is only possible to unlock local guests.
|
||||
def lock reason, &exe
|
||||
cnf = config
|
||||
raise Proxmox::AlreadyLocked, "Machine #{self} Already locked for: #{cnf[:lock].inspect}" unless cnf[:lock].nil?
|
||||
r = rest_put "#{@rest_prefix}/config", {lock: reason}
|
||||
if block_given?
|
||||
begin
|
||||
return yield
|
||||
ensure
|
||||
unlock
|
||||
begin return yield
|
||||
ensure unlock
|
||||
end
|
||||
else
|
||||
r
|
||||
else r
|
||||
end
|
||||
end
|
||||
|
||||
def unlock
|
||||
system 'pct', 'unlock', @vmid.to_s
|
||||
raise Proxmox::UnlockFailed unless $?.success?
|
||||
#rest_put "#{@rest_prefix}/config", {delete: %w[lock]}
|
||||
#rest_put "#{@rest_prefix}/config", {delete: %w[lock], skiplock: 1}
|
||||
end
|
||||
|
||||
def resize disk, size
|
||||
|
|
Loading…
Reference in a new issue