10 use PVE
::Tools
qw(extract_param);
14 use PVE
::RPCEnvironment
;
17 use PVE
::JSONSchema
qw(get_standard_option);
22 use base
qw(PVE::CLIHandler);
24 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
28 die "please run as root\n" if $> != 0;
30 PVE
::INotify
::inotify_init
();
32 my $rpcenv = PVE
::RPCEnvironment-
>init('cli');
34 $rpcenv->init_request();
35 $rpcenv->set_language($ENV{LANG
});
36 $rpcenv->set_user('root@pam');
40 my $status = PVE
::Tools
::upid_read_status
($upid);
41 exit($status eq 'OK' ?
0 : -1);
44 my $nodename = PVE
::INotify
::nodename
();
49 my $path = PVE
::QemuServer
::vnc_socket
($vmid);
51 my $s = IO
::Socket
::UNIX-
>new(Peer
=> $path, Timeout
=> 120);
53 die "unable to connect to socket '$path' - $!" if !$s;
55 my $select = new IO
::Select
;
57 $select->add(\
*STDIN
);
60 my $timeout = 60*15; # 15 minutes
63 while ($select->count &&
64 scalar(@handles = $select->can_read ($timeout))) {
65 foreach my $h (@handles) {
67 my $n = $h->sysread($buf, 4096);
77 syswrite(\
*STDOUT
, $buf);
87 __PACKAGE__-
>register_method ({
91 description
=> "Show command line which is used to start the VM (debug info).",
93 additionalProperties
=> 0,
95 vmid
=> get_standard_option
('pve-vmid'),
98 returns
=> { type
=> 'null'},
102 my $storecfg = PVE
::Storage
::config
();
103 print PVE
::QemuServer
::vm_commandline
($storecfg, $param->{vmid
}) . "\n";
108 __PACKAGE__-
>register_method ({
112 description
=> "Show VM status.",
114 additionalProperties
=> 0,
116 vmid
=> get_standard_option
('pve-vmid'),
118 description
=> "Verbose output format",
124 returns
=> { type
=> 'null'},
129 my $conf = PVE
::QemuServer
::load_config
($param->{vmid
});
131 my $vmstatus = PVE
::QemuServer
::vmstatus
($param->{vmid
});
132 my $stat = $vmstatus->{$param->{vmid
}};
133 if ($param->{verbose
}) {
134 foreach my $k (sort (keys %$stat)) {
135 next if $k eq 'cpu' || $k eq 'relcpu'; # always 0
137 next if !defined($v);
141 my $status = $stat->{status
} || 'unknown';
142 print "status: $status\n";
148 __PACKAGE__-
>register_method ({
152 description
=> "Proxy VM VNC traffic to stdin/stdout",
154 additionalProperties
=> 0,
156 vmid
=> get_standard_option
('pve-vmid'),
159 returns
=> { type
=> 'null'},
163 my $vmid = $param->{vmid
};
165 run_vnc_proxy
($vmid);
170 __PACKAGE__-
>register_method ({
174 description
=> "Unlock the VM.",
176 additionalProperties
=> 0,
178 vmid
=> get_standard_option
('pve-vmid'),
181 returns
=> { type
=> 'null'},
185 my $vmid = $param->{vmid
};
187 PVE
::QemuServer
::lock_config
($vmid, sub {
188 my $conf = PVE
::QemuServer
::load_config
($vmid);
189 delete $conf->{lock};
190 PVE
::QemuServer
::update_config_nolock
($vmid, $conf, 1);
196 __PACKAGE__-
>register_method ({
200 description
=> "Used by qmigrate - do not use manually.",
202 additionalProperties
=> 0,
205 returns
=> { type
=> 'null'},
209 if (!PVE
::Cluster
::check_cfs_quorum
(1)) {
214 print "tunnel online\n";
217 while (my $line = <>) {
219 last if $line =~ m/^quit$/;
225 __PACKAGE__-
>register_method ({
229 description
=> "Start all virtual machines (when onboot=1).",
231 additionalProperties
=> 0,
234 returns
=> { type
=> 'null'},
238 # wait up to 10 seconds for quorum
239 for (my $i = 10; $i >= 0; $i--) {
240 last if PVE
::Cluster
::check_cfs_quorum
($i != 0 ?
1 : 0);
244 my $vzlist = PVE
::QemuServer
::vzlist
();
245 my $storecfg = PVE
::Storage
::config
();
247 my $cc = PVE
::Cluster
::cfs_read_file
('cluster.conf');
250 foreach my $vmid (keys %$vzlist) {
251 next if $vzlist->{$vmid}->{pid
}; # already running
254 eval { $conf = PVE
::QemuServer
::load_config
($vmid); };
260 next if !($conf && $conf->{onboot
});
262 # skip ha managed VMs (started by rgmanager)
263 next if PVE
::Cluster
::cluster_conf_lookup_pvevm
($cc, 0, $vmid, 1);
265 sleep(2) if $count != 0; # reduce load
268 PVE
::Cluster
::check_cfs_quorum
(); # abort when we loose quorum
271 print STDERR
"Starting Qemu VM $vmid\n";
272 PVE
::QemuServer
::vm_start
($storecfg, $vmid);
280 __PACKAGE__-
>register_method ({
284 description
=> "Stop all virtual machines.",
286 additionalProperties
=> 0,
289 description
=> "Timeout in seconds. Default is to wait 3 minutes.",
296 returns
=> { type
=> 'null'},
300 my $timeout = $param->{timeout
};
302 my $storecfg = PVE
::Storage
::config
();
304 PVE
::QemuServer
::vm_stopall
($storecfg, $timeout);
309 __PACKAGE__-
>register_method ({
313 description
=> "Wait until the VM is stopped.",
315 additionalProperties
=> 0,
317 vmid
=> get_standard_option
('pve-vmid'),
319 description
=> "Timeout in seconds. Default is to wait forever.",
326 returns
=> { type
=> 'null'},
330 my $vmid = $param->{vmid
};
331 my $timeout = $param->{timeout
};
333 my $pid = PVE
::QemuServer
::check_running
($vmid);
336 print "waiting until VM $vmid stopps (PID $pid)\n";
339 while ((!$timeout || ($count < $timeout)) && PVE
::QemuServer
::check_running
($vmid)) {
344 die "wait failed - got timeout\n" if PVE
::QemuServer
::check_running
($vmid);
349 __PACKAGE__-
>register_method ({
353 description
=> "Enter Qemu Monitor interface.",
355 additionalProperties
=> 0,
357 vmid
=> get_standard_option
('pve-vmid'),
360 returns
=> { type
=> 'null'},
364 my $vmid = $param->{vmid
};
366 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
368 print "Entering Qemu Monitor for VM $vmid - type 'help' for help\n";
370 my $term = new Term
::ReadLine
('qm');
373 while (defined ($input = $term->readline('qm> '))) {
376 next if $input =~ m/^\s*$/;
378 last if $input =~ m/^\s*q(uit)?\s*$/;
381 print PVE
::QemuServer
::vm_monitor_command
($vmid, $input);
383 print "ERROR: $@" if $@;
391 list
=> [ "PVE::API2::Qemu", 'vmlist', [],
392 { node
=> $nodename }, sub {
395 exit 0 if (!scalar(@$vmlist));
397 printf "%10s %-20s %-10s %-10s %12s %-10s\n",
398 qw(VMID NAME STATUS MEM(MB) BOOTDISK
(GB
) PID
);
400 foreach my $rec (sort { $a->{vmid
} <=> $b->{vmid
} } @$vmlist) {
401 printf "%10s %-20s %-10s %-10s %12.2f %-10s\n", $rec->{vmid
}, $rec->{name
},
403 ($rec->{maxmem
} || 0)/(1024*1024),
404 ($rec->{maxdisk
} || 0)/(1024*1024*1024),
411 create
=> [ "PVE::API2::Qemu", 'create_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
413 destroy
=> [ "PVE::API2::Qemu", 'destroy_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
415 migrate
=> [ "PVE::API2::Qemu", 'migrate_vm', ['vmid', 'target'], { node
=> $nodename }, $upid_exit ],
417 set
=> [ "PVE::API2::Qemu", 'update_vm', ['vmid'], { node
=> $nodename } ],
419 unlink => [ "PVE::API2::Qemu", 'unlink', ['vmid', 'idlist'], { node
=> $nodename } ],
421 config
=> [ "PVE::API2::Qemu", 'vm_config', ['vmid'],
422 { node
=> $nodename }, sub {
424 foreach my $k (sort (keys %$config)) {
425 next if $k eq 'digest';
426 my $v = $config->{$k};
427 if ($k eq 'description') {
428 $v = PVE
::Tools
::encode_text
($v);
434 showcmd
=> [ __PACKAGE__
, 'showcmd', ['vmid']],
436 status
=> [ __PACKAGE__
, 'status', ['vmid']],
438 start
=> [ "PVE::API2::Qemu", 'vm_start', ['vmid'], { node
=> $nodename } , $upid_exit ],
440 stop
=> [ "PVE::API2::Qemu", 'vm_stop', ['vmid'], { node
=> $nodename }, $upid_exit ],
442 reset => [ "PVE::API2::Qemu", 'vm_reset', ['vmid'], { node
=> $nodename }, $upid_exit ],
444 shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node
=> $nodename }, $upid_exit ],
446 suspend
=> [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node
=> $nodename }, $upid_exit ],
448 resume
=> [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node
=> $nodename }, $upid_exit ],
450 sendkey
=> [ "PVE::API2::Qemu", 'vm_sendkey', ['vmid', 'key'], { node
=> $nodename } ],
452 vncproxy
=> [ __PACKAGE__
, 'vncproxy', ['vmid']],
454 wait => [ __PACKAGE__
, 'wait', ['vmid']],
456 unlock
=> [ __PACKAGE__
, 'unlock', ['vmid']],
458 monitor
=> [ __PACKAGE__
, 'monitor', ['vmid']],
460 startall
=> [ __PACKAGE__
, 'startall', []],
462 stopall
=> [ __PACKAGE__
, 'stopall', []],
464 mtunnel
=> [ __PACKAGE__
, 'mtunnel', []],
469 PVE
::CLIHandler
::handle_cmd
($cmddef, "qm", $cmd, \
@ARGV, undef, $0);
477 qm - qemu/kvm virtual machine manager
485 qm is a script to manage virtual machines with qemu/kvm. You can
486 create and destroy virtual machines, and control execution
487 (start/stop/suspend/resume). Besides that, you can use qm to set
488 parameters in the associated config file. It is also possible to
489 create and delete virtual disks.
493 All configuration files consists of lines in the form
497 See L<vm.conf|vm.conf> for a complete list of options.
499 Configuration files are stored inside the Proxmox configuration file system, and can be access at F</etc/pve/qemu-server/C<VMID>.conf>.
501 The default for option 'keyboard' is read from
502 F</etc/pve/datacenter.conf>.
506 Online migration and backups (vzdump) set a lock to prevent
507 unintentional action on such VMs. Sometimes you need remove such lock
508 manually (power failure).
514 # create a new VM with 4 GB ide disk
515 qm create 300 -ide0 4 -net0 e1000 -cdrom proxmox-mailgateway_2.1.iso
520 # send shutdown, then wait until VM is stopped
521 qm shutdown 300 && qm wait 300
523 # same as above, but only wait for 40 seconds
524 qm shutdown 300 && qm wait 300 -timeout 40
527 =include pve_copyright