116 lines
4.6 KiB
Ruby
116 lines
4.6 KiB
Ruby
|
class PVE::Cli
|
||
|
def cli_ct
|
||
|
cli.sub :ct, "Containers", aliases: %w[lx lxc] do |ct_cli|
|
||
|
ct_cli.cmd :list, "List CT-IDs", aliases: ['ls'], &lambda {|node=nil|
|
||
|
connect
|
||
|
nodes = Proxmox::Node.all
|
||
|
nodes = nodes.select {|n| node == n.name } if node
|
||
|
nodes.flat_map do |n|
|
||
|
n.lxc.map {|c| c.vmid.to_i }
|
||
|
end.sort.each {|c| puts c }
|
||
|
}
|
||
|
|
||
|
ct_cli.cmd :status, "List CTs with status", aliases: [nil], &lambda {|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]
|
||
|
}
|
||
|
|
||
|
ct_cli.cmd :enter, "Enter Console of CT", &lambda {|name_or_id|
|
||
|
connect
|
||
|
STDERR.puts "! #{$?.exitstatus}" unless Proxmox::LXC.find!( name_or_id).enter
|
||
|
}
|
||
|
|
||
|
ct_cli.cmd :exec, "Executes Command in CT", min: 4, &lambda {|name_or_id, *command|
|
||
|
connect
|
||
|
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:|
|
||
|
connect
|
||
|
ct = Proxmox::LXC.find! name_or_id
|
||
|
start ct, node: node, fire: fire, timeout: timeout, secs: secs
|
||
|
}).
|
||
|
opt( :node, "-nNODE", "--node=NODE", "On NODE (default, as is, so without migration)").
|
||
|
tap {|c| opts_wait c }
|
||
|
|
||
|
ct_cli.cmd( :stop, "Stops CT", min: 3, &lambda {|name_or_id, fire: nil, timeout:, secs:|
|
||
|
connect
|
||
|
ct = Proxmox::LXC.find! name_or_id
|
||
|
stop ct, fire: fire, timeout: timeout, secs: secs
|
||
|
}).tap {|c| opts_wait c }
|
||
|
|
||
|
ct_cli.cmd( :wait, "Wait till CT is in state", &lambda {|name_or_id, state, timeout: nil, secs: nil|
|
||
|
connect
|
||
|
ct = Proxmox::LXC.find! name_or_id
|
||
|
wait ct, state, timeout: timeout, secs: secs
|
||
|
}).
|
||
|
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)
|
||
|
|
||
|
ct_cli.cmd( :create, "Creates a new container", &lambda {|template, *options| #, fire:, timeout:, secs:, start:|
|
||
|
if %w[-h --help].include? template
|
||
|
STDERR.puts "Usage: ct create TEMPLATE -h # Shows template-related options"
|
||
|
STDERR.puts " ct create TEMPLATE [OPTIONS] # Creates a container"
|
||
|
exit 1
|
||
|
end
|
||
|
ctopts = {}
|
||
|
OptionParser.new do |opts|
|
||
|
opts.banner = <<EOU
|
||
|
Usage: ct create #{template} [options]
|
||
|
|
||
|
Options: (*=Required)
|
||
|
EOU
|
||
|
opts.on '-h', '--help', " Help!" do
|
||
|
STDERR.puts opts
|
||
|
exit 1 unless interactive?
|
||
|
return
|
||
|
end
|
||
|
opts.on( '-r', '--[no-]-start', " Start container after creation") {|v| ctopts[:start] = v }
|
||
|
opts.on( '-f', '--[no-]-fire', " Do not wait till running") {|v| ctopts[:start] = v }
|
||
|
opts.on( '-t', '--timeout=TIMEOUT', " Wait for max TIMEOUT seconds (default: endless)") {|v| ctopts[:timeout] = v }
|
||
|
opts.on( '-s', '--seconds=SECONDS', " Check every SECONDS for state (default: 0.2)") {|v| ctopts[:seconds] = v }
|
||
|
ctt = PVE::CTTemplate.const_get template.classify
|
||
|
ctt.requirements.each do |name, (type, req, desc, *args)|
|
||
|
req = req ? "*" : " "
|
||
|
case type
|
||
|
when :boolean
|
||
|
opts.on( "--[no-]#{name}", "#{req}#{desc}") {|v| ctopts[name] = v }
|
||
|
when :string, :numeric
|
||
|
opts.on( "--#{name}=#{type.upcase}", "#{req}#{desc}") {|v| ctopts[name] = v }
|
||
|
when :enum
|
||
|
opts.on( "--#{name}=#{type.upcase}", "#{req}#{desc} (#{args.first.join ', '})") do |v|
|
||
|
ctopts[name] = v
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end.parse! options
|
||
|
connect
|
||
|
create Proxmox::LXC, template, **ctopts
|
||
|
})
|
||
|
|
||
|
ct_cli.cmd( :config, '', &lambda {|name_or_id|
|
||
|
connect
|
||
|
ct = Proxmox::LXC.find! name_or_id
|
||
|
STDOUT.puts ct.config.to_json
|
||
|
})
|
||
|
|
||
|
ct_cli.cmd( :destroy, '', min: 7, &lambda {|name_or_id, fire:, secs:, timeout:, i_really_want_to_destroy:|
|
||
|
raise UsageError, "Name/ID is not what you want to destroy" unless name_or_id == i_really_want_to_destroy
|
||
|
connect
|
||
|
ct = Proxmox::LXC.find! name_or_id
|
||
|
raise UsageError, "Container is not stopped" unless ct.stopped?
|
||
|
destroy ct, fire: fire, timeout: timeout, secs: secs
|
||
|
}).tap {|c| opts_wait c }.
|
||
|
opt( :i_really_want_to_destroy, "--i-really-want-to-destroy=NAMEORID", "Repeat the name/ID")
|
||
|
|
||
|
ct_cli.cmd( :help, '', aliases: ['-h', '--help']) {|*args| help ct_cli, *args }
|
||
|
end
|
||
|
end
|
||
|
end
|