Set min for commands with same (sort) aliases. Table improvements.
This commit is contained in:
parent
efe4f41eda
commit
8994faad9e
|
@ -153,6 +153,48 @@ class PVE::Cli
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def node_opt node = nil
|
||||||
|
node &&= /\A#{node}\z/
|
||||||
|
node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_opt target = nil, &exe
|
||||||
|
if target
|
||||||
|
target = /\A#{target}\z/
|
||||||
|
lambda {|n| exe.call n if n === target }
|
||||||
|
else
|
||||||
|
exe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def hosting_table target:, status:, sort:
|
||||||
|
connect
|
||||||
|
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%], format: '<<<<<>>>>>>'
|
||||||
|
target &&= /\A#{target}\z/i
|
||||||
|
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'
|
||||||
|
%i[started online running]
|
||||||
|
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
|
||||||
|
raise DenKn::UsageError, "Unknown state #{status}"
|
||||||
|
end
|
||||||
|
push =
|
||||||
|
if target and status
|
||||||
|
lambda {|n| to.virt n if n === target and status.include?( n.state) }
|
||||||
|
elsif target
|
||||||
|
lambda {|n| to.virt n if n === target }
|
||||||
|
elsif status
|
||||||
|
lambda {|n| to.virt n if status.include? n.state }
|
||||||
|
else
|
||||||
|
to.method :virt
|
||||||
|
end
|
||||||
|
yield push
|
||||||
|
to.print order: sort.each_char.map {|c| (2*c.ord[5]-1) * (' sainhucmd'.index( c.downcase)) }
|
||||||
|
end
|
||||||
|
|
||||||
def help cl, *args
|
def help cl, *args
|
||||||
STDERR.puts cl.help( *args)
|
STDERR.puts cl.help( *args)
|
||||||
exit 1 unless interactive?
|
exit 1 unless interactive?
|
||||||
|
|
|
@ -15,26 +15,17 @@ def cli_base
|
||||||
each {|c| puts c }
|
each {|c| puts c }
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.cmd( :status, "Lists Nodes/VMs/CTs with status", &lambda {|target=nil, sort: 'n', node: nil|
|
cli.cmd( :status, "Lists Nodes/VMs/CTs with status", &lambda {|target=nil, sort:, node: nil, status: nil|
|
||||||
connect
|
hosting_table target: target, status: status, sort: sort do |push|
|
||||||
node &&= /\A#{node}\z/
|
node_opt( node).
|
||||||
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
|
each( &push).lazy.
|
||||||
push =
|
flat_map {|n| [ Thread.new( n, &:lxc), Thread.new( n, &:qemu) ] }.
|
||||||
if target
|
each {|n| n.value.each &push }
|
||||||
target = /\A#{target}\z/
|
end
|
||||||
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.each &push
|
|
||||||
nodes.
|
|
||||||
flat_map {|n| [ Thread.new( n, &:lxc), 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( :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)", default: 'n').
|
||||||
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE")
|
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE").
|
||||||
|
opt( :status, '-S', '--status=STATUS', "Filter for status (running, stopped, ...) (default: no filter)")
|
||||||
|
|
||||||
def prepare_show_config cnf
|
def prepare_show_config cnf
|
||||||
r = {}
|
r = {}
|
||||||
|
@ -144,7 +135,7 @@ def cli_base
|
||||||
show_config th.config, old
|
show_config th.config, old
|
||||||
}
|
}
|
||||||
|
|
||||||
ccli.cmd :show, "Show Config of CT/VM", aliases: %w[s], &lambda {|name_or_id|
|
ccli.cmd :show, "Show Config of CT/VM", &lambda {|name_or_id|
|
||||||
connect
|
connect
|
||||||
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
||||||
show_config th.config
|
show_config th.config
|
||||||
|
|
|
@ -9,25 +9,17 @@ def cli_ct
|
||||||
end.sort.each {|c| puts c }
|
end.sort.each {|c| puts c }
|
||||||
}
|
}
|
||||||
|
|
||||||
ct_cli.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: 'n', node: nil|
|
ct_cli.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: nil, node: nil, status: nil|
|
||||||
connect
|
hosting_table target: target, status: status, sort: sort do |push|
|
||||||
node &&= /\A#{node}\z/
|
node_opt( node).
|
||||||
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
|
each( &push).lazy.
|
||||||
push =
|
map {|n| Thread.new n, &:lxc }.
|
||||||
if target
|
each {|n| n.value.each &push }
|
||||||
target = /\A#{target}\z/
|
end
|
||||||
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( :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)", default: 'n').
|
||||||
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE")
|
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE").
|
||||||
|
opt( :status, '-S', '--status=STATUS', "Filter for status (running, stopped, ...) (default: no filter)")
|
||||||
|
|
||||||
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
|
||||||
|
@ -39,7 +31,7 @@ def cli_ct
|
||||||
STDERR.puts "! #{$?.exitstatus}" unless Proxmox::LXC.find!( name_or_id).exec *command
|
STDERR.puts "! #{$?.exitstatus}" unless Proxmox::LXC.find!( name_or_id).exec *command
|
||||||
}
|
}
|
||||||
|
|
||||||
ct_cli.cmd( :start, "Starts CT", min: 3, &lambda {|name_or_id, node: nil, fire:, timeout:, secs:|
|
ct_cli.cmd( :start, "Starts CT", min: 4, &lambda {|name_or_id, node: nil, fire:, timeout:, secs:|
|
||||||
connect
|
connect
|
||||||
ct = Proxmox::LXC.find! name_or_id
|
ct = Proxmox::LXC.find! name_or_id
|
||||||
start ct, node: node, fire: fire, timeout: timeout, secs: secs
|
start ct, node: node, fire: fire, timeout: timeout, secs: secs
|
||||||
|
@ -61,7 +53,7 @@ def cli_ct
|
||||||
opt( :timeout, "-tTIMEOUT", "--timeout=TIMEOUT", "Wait for max TIMEOUT seconds (default: endless)", default: nil).
|
opt( :timeout, "-tTIMEOUT", "--timeout=TIMEOUT", "Wait for max TIMEOUT seconds (default: endless)", default: nil).
|
||||||
opt( :secs, "-sSECONDS", "--seconds=SECONDS", "Check every SECONDS for state (default: 0.2)", default: 0.2)
|
opt( :secs, "-sSECONDS", "--seconds=SECONDS", "Check every SECONDS for state (default: 0.2)", default: 0.2)
|
||||||
|
|
||||||
ct_cli.cmd( :create, "Creates a new container", &lambda {|template, *options| #, fire:, timeout:, secs:, start:|
|
ct_cli.cmd( :create, "Creates a new container", min: 2, &lambda {|template, *options| #, fire:, timeout:, secs:, start:|
|
||||||
if %w[-h --help].include? template
|
if %w[-h --help].include? template
|
||||||
STDERR.puts "Usage: ct create TEMPLATE -h # Shows template-related options"
|
STDERR.puts "Usage: ct create TEMPLATE -h # Shows template-related options"
|
||||||
STDERR.puts " ct create TEMPLATE [OPTIONS] # Creates a container"
|
STDERR.puts " ct create TEMPLATE [OPTIONS] # Creates a container"
|
||||||
|
@ -107,7 +99,7 @@ EOU
|
||||||
create Proxmox::LXC, template, **ctopts
|
create Proxmox::LXC, template, **ctopts
|
||||||
})
|
})
|
||||||
|
|
||||||
ct_cli.cmd( :config, 'Shows current config', aliases: %w[cnf], &lambda {|name_or_id|
|
ct_cli.cmd( :config, 'Shows current config', aliases: %w[cnf], min: 2, &lambda {|name_or_id|
|
||||||
connect
|
connect
|
||||||
ct = Proxmox::LXC.find! name_or_id
|
ct = Proxmox::LXC.find! name_or_id
|
||||||
STDOUT.puts JSON.dump( ct.config)
|
STDOUT.puts JSON.dump( ct.config)
|
||||||
|
|
|
@ -9,7 +9,7 @@ def opts_ha cl
|
||||||
end
|
end
|
||||||
|
|
||||||
def cli_ha
|
def cli_ha
|
||||||
cli.sub :ha, "Inspect High-Availability" do |hacli|
|
cli.sub :ha, "Inspect High-Availability", min: 2 do |hacli|
|
||||||
hacli.cmd( :create, "Create HA for CT/VM", &lambda {|name_or_id, group:, comment: nil, max_relocate:, max_restart:, state:|
|
hacli.cmd( :create, "Create HA for CT/VM", &lambda {|name_or_id, group:, comment: nil, max_relocate:, max_restart:, state:|
|
||||||
connect
|
connect
|
||||||
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
||||||
|
@ -19,7 +19,7 @@ def cli_ha
|
||||||
ha.create group: group, comment: comment, max_relocate: max_relocate, max_restart: max_restart
|
ha.create group: group, comment: comment, max_relocate: max_relocate, max_restart: max_restart
|
||||||
}).tap {|cl| opts_ha cl }
|
}).tap {|cl| opts_ha cl }
|
||||||
|
|
||||||
hacli.cmd :remove, "Remove CT/VM from HA", &lambda {|name_or_id|
|
hacli.cmd :remove, "Remove CT/VM from HA", min: 5, &lambda {|name_or_id|
|
||||||
connect
|
connect
|
||||||
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
||||||
raise UsageError, "Container or VirtualMachine not found: #{name_or_id}" unless th
|
raise UsageError, "Container or VirtualMachine not found: #{name_or_id}" unless th
|
||||||
|
@ -63,7 +63,7 @@ def cli_ha
|
||||||
ha.stopped!
|
ha.stopped!
|
||||||
}
|
}
|
||||||
|
|
||||||
hacli.cmd :reset, "If state of CT/VM is failed, Proxmox will not start/stop it anyway. You have to reset state (state=disabled), first", &lambda {|name_or_id|
|
hacli.cmd :reset, "If state of CT/VM is failed, Proxmox will not start/stop it anyway. You have to reset state (state=disabled), first", min: 3, aliases: [:rst], &lambda {|name_or_id|
|
||||||
connect
|
connect
|
||||||
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
th = Proxmox::LXC.find( name_or_id) || Proxmox::Qemu.find_by_name( name_or_id)
|
||||||
raise UsageError, "Container or VirtualMachine not found: #{name_or_id}" unless th
|
raise UsageError, "Container or VirtualMachine not found: #{name_or_id}" unless th
|
||||||
|
|
|
@ -30,7 +30,7 @@ def cli_node
|
||||||
end
|
end
|
||||||
|
|
||||||
nod_cli.sub :task, "Inspect tasks" do |tcli|
|
nod_cli.sub :task, "Inspect tasks" do |tcli|
|
||||||
tcli.cmd :list, "List done tasks", aliases: [nil, 'ls'], &lambda {|node|
|
tcli.cmd :list, "List done tasks", aliases: [:ls], &lambda {|node|
|
||||||
connect
|
connect
|
||||||
Proxmox::Node.find_by_name!( node).
|
Proxmox::Node.find_by_name!( node).
|
||||||
tasks.
|
tasks.
|
||||||
|
|
|
@ -10,25 +10,17 @@ def cli_qm
|
||||||
end.sort.each {|c| puts c }
|
end.sort.each {|c| puts c }
|
||||||
}
|
}
|
||||||
|
|
||||||
qm.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: 'n', node: nil|
|
qm.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: nil, node: nil, status: nil|
|
||||||
connect
|
hosting_table target: target, state: state, sort: sort do |push|
|
||||||
node &&= /\A#{node}\z/
|
node_opt( node).
|
||||||
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU/% Mem/MiB Mem/% Disk/MiB Disk/%]
|
each( &push).lazy.
|
||||||
push =
|
flat_map {|n| [ Thread.new( n, &:lxc), Thread.new( n, &:qemu) ] }.
|
||||||
if target
|
each {|n| n.value.each &push }
|
||||||
target = /\A#{target}\z/
|
end
|
||||||
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( :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)", default: 'n').
|
||||||
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE")
|
opt( :node, '-n', '--node=NODE', "List only hosted by this NODE").
|
||||||
|
opt( :status, '-S', '--status=STATUS', "Filter for status (running, stopped, ...) (default: no filter)")
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -53,24 +53,24 @@ def cli_storage
|
||||||
connect
|
connect
|
||||||
appliances node, regexp, system, applications
|
appliances node, regexp, system, applications
|
||||||
}).
|
}).
|
||||||
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
||||||
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil).
|
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil).
|
||||||
opt( :system, '-s', '--system', 'Only system templates', default: nil).
|
opt( :system, '-s', '--system', 'Only system templates', default: nil).
|
||||||
opt( :applications, '-a', '--applications', 'Only applications (non system) templates', default: nil)
|
opt( :applications, '-a', '--applications', 'Only applications (non system) templates', default: nil)
|
||||||
|
|
||||||
cli_apl.cmd( :system, "Table of provided systems", aliases: [nil], &lambda {|node:, regexp:|
|
cli_apl.cmd( :system, "Table of provided systems", &lambda {|node:, regexp:|
|
||||||
connect
|
connect
|
||||||
appliances node, regexp, true, nil
|
appliances node, regexp, true, nil
|
||||||
}).
|
}).
|
||||||
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
||||||
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil)
|
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil)
|
||||||
|
|
||||||
cli_apl.cmd( :applications, "Table of provided applications", aliases: [nil], &lambda {|node:, regexp:|
|
cli_apl.cmd( :applications, "Table of provided applications", &lambda {|node:, regexp:|
|
||||||
connect
|
connect
|
||||||
appliances node, regexp, nil, true
|
appliances node, regexp, nil, true
|
||||||
}).
|
}).
|
||||||
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
opt( :node, '-n=NODE', '--node', 'Ask this node for appliances (any node should list the same)', default: nil).
|
||||||
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil)
|
opt( :regexp, '-r=REGEXP', '--regexp', 'Filter by template', default: nil)
|
||||||
|
|
||||||
cli_apl.cmd( :list, "List provided appliances", aliases: ['ls'], &lambda {|node=nil, regexp:|
|
cli_apl.cmd( :list, "List provided appliances", aliases: ['ls'], &lambda {|node=nil, regexp:|
|
||||||
connect
|
connect
|
||||||
|
|
|
@ -94,7 +94,6 @@ class ColoredString
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TablizedOutput
|
class TablizedOutput
|
||||||
def initialize header, stdout: nil, format: nil
|
def initialize header, stdout: nil, format: nil
|
||||||
@header = header.map &:to_s
|
@header = header.map &:to_s
|
||||||
|
@ -125,10 +124,14 @@ class TablizedOutput
|
||||||
def inspect() "#<TO:Percentage #{@v}%>" end
|
def inspect() "#<TO:Percentage #{@v}%>" end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
y = (v*w).round
|
vw = v*w
|
||||||
x = (100*v).round
|
percent = (100*v).round
|
||||||
r = "%*s" % [w, 0==x ? '·' : x]
|
vwi = vw.to_i
|
||||||
"\e[1;4;#{0.75>v ? 32 : 31}m#{r[0...y]}\e[0m#{r[y..-1]}"
|
rounded = (vw+0.5).to_i
|
||||||
|
s = "%*s" % [w, 0==percent ? '·' : percent]
|
||||||
|
pre = "\e[1;4;#{0.75>v ? 32 : 31}m"
|
||||||
|
mid = (vw % 1) > 0.5 ? "\e[2m" : "\e[0m"
|
||||||
|
"#{pre}#{s[0...vwi]}#{mid}#{s[vwi]}\e[0m#{s[(vwi+1)..-1]}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -161,8 +164,8 @@ class TablizedOutput
|
||||||
@stdout.puts \
|
@stdout.puts \
|
||||||
@header.each_with_index.map {|s, i|
|
@header.each_with_index.map {|s, i|
|
||||||
"#{' ' * (@maxs[i] - s.length)}#{s}"
|
"#{' ' * (@maxs[i] - s.length)}#{s}"
|
||||||
}.join( ' ')
|
}.join( ' | ')
|
||||||
ls.each_with_index do |l|
|
ls.each_with_index do |l, i|
|
||||||
@stdout.puts \
|
@stdout.puts \
|
||||||
l.each_with_index.map {|s, i|
|
l.each_with_index.map {|s, i|
|
||||||
pad = ' ' * (@maxs[i] - s.length)
|
pad = ' ' * (@maxs[i] - s.length)
|
||||||
|
@ -172,7 +175,7 @@ class TablizedOutput
|
||||||
else
|
else
|
||||||
"#{pad}#{s}"
|
"#{pad}#{s}"
|
||||||
end
|
end
|
||||||
}.join( ' ')
|
}.join( "\e[3#{i.even? ? 6 : 3}m | \e[0m")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue