]>
git.proxmox.com Git - qemu-server.git/blob - PVE/CLI/qm.pm
6 # Note: disable '+' prefix for Getopt::Long (for resize command)
7 use Getopt
::Long
qw(:config no_getopt_compat);
14 use PVE
::Tools
qw(extract_param);
18 use PVE
::RPCEnvironment
;
21 use PVE
::JSONSchema
qw(get_standard_option);
26 use base
qw(PVE::CLIHandler);
30 my $status = PVE
::Tools
::upid_read_status
($upid);
31 exit($status eq 'OK' ?
0 : -1);
34 my $nodename = PVE
::INotify
::nodename
();
40 while ( ++$c < 10 && !-e
$path ) { sleep(1); }
42 my $s = IO
::Socket
::UNIX-
>new(Peer
=> $path, Timeout
=> 120);
44 die "unable to connect to socket '$path' - $!" if !$s;
46 my $select = new IO
::Select
;
48 $select->add(\
*STDIN
);
51 my $timeout = 60*15; # 15 minutes
54 while ($select->count &&
55 scalar(@handles = $select->can_read ($timeout))) {
56 foreach my $h (@handles) {
58 my $n = $h->sysread($buf, 4096);
68 syswrite(\
*STDOUT
, $buf);
78 __PACKAGE__-
>register_method ({
82 description
=> "Show command line which is used to start the VM (debug info).",
84 additionalProperties
=> 0,
86 vmid
=> get_standard_option
('pve-vmid'),
89 returns
=> { type
=> 'null'},
93 my $storecfg = PVE
::Storage
::config
();
94 print PVE
::QemuServer
::vm_commandline
($storecfg, $param->{vmid
}) . "\n";
99 __PACKAGE__-
>register_method ({
103 description
=> "Show VM status.",
105 additionalProperties
=> 0,
107 vmid
=> get_standard_option
('pve-vmid'),
109 description
=> "Verbose output format",
115 returns
=> { type
=> 'null'},
120 my $conf = PVE
::QemuServer
::load_config
($param->{vmid
});
122 my $vmstatus = PVE
::QemuServer
::vmstatus
($param->{vmid
});
123 my $stat = $vmstatus->{$param->{vmid
}};
124 if ($param->{verbose
}) {
125 foreach my $k (sort (keys %$stat)) {
126 next if $k eq 'cpu' || $k eq 'relcpu'; # always 0
128 next if !defined($v);
132 my $status = $stat->{status
} || 'unknown';
133 print "status: $status\n";
139 __PACKAGE__-
>register_method ({
143 description
=> "Proxy VM VNC traffic to stdin/stdout",
145 additionalProperties
=> 0,
147 vmid
=> get_standard_option
('pve-vmid'),
150 returns
=> { type
=> 'null'},
154 my $vmid = $param->{vmid
};
155 my $vnc_socket = PVE
::QemuServer
::vnc_socket
($vmid);
157 if (my $ticket = $ENV{LC_PVE_TICKET
}) { # NOTE: ssh on debian only pass LC_* variables
158 PVE
::QemuServer
::vm_mon_cmd
($vmid, "change", device
=> 'vnc', target
=> "unix:$vnc_socket,password");
159 PVE
::QemuServer
::vm_mon_cmd
($vmid, "set_password", protocol
=> 'vnc', password
=> $ticket);
160 PVE
::QemuServer
::vm_mon_cmd
($vmid, "expire_password", protocol
=> 'vnc', time => "+30");
162 PVE
::QemuServer
::vm_mon_cmd
($vmid, "change", device
=> 'vnc', target
=> "unix:$vnc_socket,x509,password");
165 run_vnc_proxy
($vnc_socket);
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 delete $conf->{pending
}->{lock} if $conf->{pending
}; # just to be sure
191 PVE
::QemuServer
::update_config_nolock
($vmid, $conf, 1);
197 __PACKAGE__-
>register_method ({
201 description
=> "Used by qmigrate - do not use manually.",
203 additionalProperties
=> 0,
206 returns
=> { type
=> 'null'},
210 if (!PVE
::Cluster
::check_cfs_quorum
(1)) {
215 print "tunnel online\n";
218 while (my $line = <>) {
220 last if $line =~ m/^quit$/;
226 __PACKAGE__-
>register_method ({
230 description
=> "Wait until the VM is stopped.",
232 additionalProperties
=> 0,
234 vmid
=> get_standard_option
('pve-vmid'),
236 description
=> "Timeout in seconds. Default is to wait forever.",
243 returns
=> { type
=> 'null'},
247 my $vmid = $param->{vmid
};
248 my $timeout = $param->{timeout
};
250 my $pid = PVE
::QemuServer
::check_running
($vmid);
253 print "waiting until VM $vmid stopps (PID $pid)\n";
256 while ((!$timeout || ($count < $timeout)) && PVE
::QemuServer
::check_running
($vmid)) {
261 die "wait failed - got timeout\n" if PVE
::QemuServer
::check_running
($vmid);
266 __PACKAGE__-
>register_method ({
270 description
=> "Enter Qemu Monitor interface.",
272 additionalProperties
=> 0,
274 vmid
=> get_standard_option
('pve-vmid'),
277 returns
=> { type
=> 'null'},
281 my $vmid = $param->{vmid
};
283 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
285 print "Entering Qemu Monitor for VM $vmid - type 'help' for help\n";
287 my $term = new Term
::ReadLine
('qm');
290 while (defined ($input = $term->readline('qm> '))) {
293 next if $input =~ m/^\s*$/;
295 last if $input =~ m/^\s*q(uit)?\s*$/;
298 print PVE
::QemuServer
::vm_human_monitor_command
($vmid, $input);
300 print "ERROR: $@" if $@;
307 __PACKAGE__-
>register_method ({
311 description
=> "Rescan all storages and update disk sizes and unused disk images.",
313 additionalProperties
=> 0,
315 vmid
=> get_standard_option
('pve-vmid', {optional
=> 1}),
318 returns
=> { type
=> 'null'},
322 PVE
::QemuServer
::rescan
($param->{vmid
});
327 __PACKAGE__-
>register_method ({
331 description
=> "Open a terminal using a serial device (The VM need to have a serial device configured, for example 'serial0: socket')",
333 additionalProperties
=> 0,
335 vmid
=> get_standard_option
('pve-vmid'),
337 description
=> "Select the serial device. By default we simply use the first suitable device.",
340 enum
=> [qw(serial0 serial1 serial2 serial3)],
344 returns
=> { type
=> 'null'},
348 my $vmid = $param->{vmid
};
350 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
352 my $iface = $param->{iface
};
355 die "serial interface '$iface' is not configured\n" if !$conf->{$iface};
356 die "wrong serial type on interface '$iface'\n" if $conf->{$iface} ne 'socket';
358 foreach my $opt (qw(serial0 serial1 serial2 serial3)) {
359 if ($conf->{$opt} && ($conf->{$opt} eq 'socket')) {
364 die "unable to find a serial interface\n" if !$iface;
367 die "VM $vmid not running\n" if !PVE
::QemuServer
::check_running
($vmid);
369 my $socket = "/var/run/qemu-server/${vmid}.$iface";
371 my $cmd = "socat UNIX-CONNECT:$socket STDIO,raw,echo=0,escape=0x0f";
373 print "starting serial terminal on interface $iface (press control-O to exit)\n";
381 list
=> [ "PVE::API2::Qemu", 'vmlist', [],
382 { node
=> $nodename }, sub {
385 exit 0 if (!scalar(@$vmlist));
387 printf "%10s %-20s %-10s %-10s %12s %-10s\n",
388 qw(VMID NAME STATUS MEM(MB) BOOTDISK
(GB
) PID
);
390 foreach my $rec (sort { $a->{vmid
} <=> $b->{vmid
} } @$vmlist) {
391 printf "%10s %-20s %-10s %-10s %12.2f %-10s\n", $rec->{vmid
}, $rec->{name
},
393 ($rec->{maxmem
} || 0)/(1024*1024),
394 ($rec->{maxdisk
} || 0)/(1024*1024*1024),
401 create
=> [ "PVE::API2::Qemu", 'create_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
403 destroy
=> [ "PVE::API2::Qemu", 'destroy_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
405 clone
=> [ "PVE::API2::Qemu", 'clone_vm', ['vmid', 'newid'], { node
=> $nodename }, $upid_exit ],
407 migrate
=> [ "PVE::API2::Qemu", 'migrate_vm', ['vmid', 'target'], { node
=> $nodename }, $upid_exit ],
409 set
=> [ "PVE::API2::Qemu", 'update_vm', ['vmid'], { node
=> $nodename } ],
411 resize
=> [ "PVE::API2::Qemu", 'resize_vm', ['vmid', 'disk', 'size'], { node
=> $nodename } ],
413 move_disk
=> [ "PVE::API2::Qemu", 'move_vm_disk', ['vmid', 'disk', 'storage'], { node
=> $nodename }, $upid_exit ],
415 unlink => [ "PVE::API2::Qemu", 'unlink', ['vmid'], { node
=> $nodename } ],
417 config
=> [ "PVE::API2::Qemu", 'vm_config', ['vmid'],
418 { node
=> $nodename }, sub {
420 foreach my $k (sort (keys %$config)) {
421 next if $k eq 'digest';
422 my $v = $config->{$k};
423 if ($k eq 'description') {
424 $v = PVE
::Tools
::encode_text
($v);
430 pending
=> [ "PVE::API2::Qemu", 'vm_pending', ['vmid'],
431 { node
=> $nodename }, sub {
433 foreach my $item (sort { $a->{key
} cmp $b->{key
}} @$data) {
434 my $k = $item->{key
};
435 next if $k eq 'digest';
436 my $v = $item->{value
};
437 my $p = $item->{pending
};
438 if ($k eq 'description') {
439 $v = PVE
::Tools
::encode_text
($v) if defined($v);
440 $p = PVE
::Tools
::encode_text
($p) if defined($p);
443 if ($item->{delete}) {
444 print "del $k: $v\n";
445 } elsif (defined($p)) {
446 print "cur $k: $v\n";
447 print "new $k: $p\n";
449 print "cur $k: $v\n";
451 } elsif (defined($p)) {
452 print "new $k: $p\n";
457 showcmd
=> [ __PACKAGE__
, 'showcmd', ['vmid']],
459 status
=> [ __PACKAGE__
, 'status', ['vmid']],
461 snapshot
=> [ "PVE::API2::Qemu", 'snapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
463 delsnapshot
=> [ "PVE::API2::Qemu", 'delsnapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
465 rollback
=> [ "PVE::API2::Qemu", 'rollback', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
467 template
=> [ "PVE::API2::Qemu", 'template', ['vmid'], { node
=> $nodename }],
469 start
=> [ "PVE::API2::Qemu", 'vm_start', ['vmid'], { node
=> $nodename } , $upid_exit ],
471 stop
=> [ "PVE::API2::Qemu", 'vm_stop', ['vmid'], { node
=> $nodename }, $upid_exit ],
473 reset => [ "PVE::API2::Qemu", 'vm_reset', ['vmid'], { node
=> $nodename }, $upid_exit ],
475 shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node
=> $nodename }, $upid_exit ],
477 suspend
=> [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node
=> $nodename }, $upid_exit ],
479 resume
=> [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node
=> $nodename }, $upid_exit ],
481 sendkey
=> [ "PVE::API2::Qemu", 'vm_sendkey', ['vmid', 'key'], { node
=> $nodename } ],
483 vncproxy
=> [ __PACKAGE__
, 'vncproxy', ['vmid']],
485 wait => [ __PACKAGE__
, 'wait', ['vmid']],
487 unlock
=> [ __PACKAGE__
, 'unlock', ['vmid']],
489 rescan
=> [ __PACKAGE__
, 'rescan', []],
491 monitor
=> [ __PACKAGE__
, 'monitor', ['vmid']],
493 mtunnel
=> [ __PACKAGE__
, 'mtunnel', []],
495 terminal
=> [ __PACKAGE__
, 'terminal', ['vmid']],
504 qm - qemu/kvm virtual machine manager
512 qm is a script to manage virtual machines with qemu/kvm. You can
513 create and destroy virtual machines, and control execution
514 (start/stop/suspend/resume). Besides that, you can use qm to set
515 parameters in the associated config file. It is also possible to
516 create and delete virtual disks.
520 All configuration files consists of lines in the form
524 See L<vm.conf|vm.conf> for a complete list of options.
526 Configuration files are stored inside the Proxmox configuration file system, and can be access at F</etc/pve/qemu-server/C<VMID>.conf>.
528 The default for option 'keyboard' is read from
529 F</etc/pve/datacenter.conf>.
533 Online migration and backups (vzdump) set a lock to prevent
534 unintentional action on such VMs. Sometimes you need remove such lock
535 manually (power failure).
541 # create a new VM with 4 GB ide disk
542 qm create 300 -ide0 4 -net0 e1000 -cdrom proxmox-mailgateway_2.1.iso
547 # send shutdown, then wait until VM is stopped
548 qm shutdown 300 && qm wait 300
550 # same as above, but only wait for 40 seconds
551 qm shutdown 300 && qm wait 300 -timeout 40
554 =include pve_copyright