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 = node ? Proxmox::Node.find_by_name( name) : Proxmox::Node.all nodes.flat_map do |n| n.lxc.map {|c| c.vmid.to_i } end.sort.each {|c| puts c } } ct_cli.cmd( :status, "Lists CTs with status", aliases: [nil], &lambda {|target=nil, sort: nil, node: nil, status: nil| hosting_table target: target, status: status, sort: sort do |push| node_opt( node). each( &push).lazy. map {|n| Thread.new n, &:lxc }. each {|n| n.value.each &push } end }). 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( :status, '-S', '--status=STATUS', "Filter for status (running, stopped, ...) (default: no filter)") 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( :migrate, "Migrates halted CT(s) to an other host", min: 2, &lambda {|target, *names_or_ids, fire:, timeout:, secs:| connect node = Proxmox::Node.find_by_name! target per_argument names_or_ids, print: "\e[1;34mMigrate CT %s:\e[0m" do |name_or_id| ct = Proxmox::LXC.find! name_or_id task = ct.migrate node wait task, text: "Migrating", timeout: timeout unless fire end }).tap {|c| opts_wait c } ct_cli.cmd( :start, "Starts CT(s)", min: 4, &lambda {|*names_or_ids, node: nil, fire:, timeout:, secs:| connect per_argument names_or_ids, print: "\e[1;34mStart CT %s:\e[0m" do |name_or_id| ct = Proxmox::LXC.find! name_or_id start ct, node: node, fire: fire, timeout: timeout, secs: secs end }).tap {|c| opts_wait c } ct_cli.cmd( :stop, "Stops CT(s)", min: 3, &lambda {|*names_or_ids, fire: nil, timeout:, secs:| connect per_argument names_or_ids, print: "\e[1;34mStart CT %s:\e[0m" do |name_or_id| ct = Proxmox::LXC.find! name_or_id stop ct, fire: fire, timeout: timeout, secs: secs end }).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", min: 2, &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" STDERR.puts " ct create -l # Listing available templates" exit 1 elsif %w[-l --list].include? template STDERR.puts PVE::CTTemplate.constants.reject {|c|:Base==c}.map {|c|c.to_s.titlecase.dasherize.downcase} exit 0 end ctopts = {} OptionParser.new do |opts| ctt = PVE::CTTemplate.const_get template.classify opts.banner = <