]>
git.proxmox.com Git - qemu-server.git/blob - qm
11 use PVE
::Tools
qw(extract_param);
15 use PVE
::RPCEnvironment
;
18 use PVE
::JSONSchema
qw(get_standard_option);
23 use base
qw(PVE::CLIHandler);
25 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
29 die "please run as root\n" if $> != 0;
31 PVE
::INotify
::inotify_init
();
33 my $rpcenv = PVE
::RPCEnvironment-
>init('cli');
35 $rpcenv->init_request();
36 $rpcenv->set_language($ENV{LANG
});
37 $rpcenv->set_user('root@pam');
41 my $status = PVE
::Tools
::upid_read_status
($upid);
42 exit($status eq 'OK' ?
0 : -1);
45 my $nodename = PVE
::INotify
::nodename
();
51 while ( ++$c < 10 && !-e
$path ) { sleep(1); }
53 my $s = IO
::Socket
::UNIX-
>new(Peer
=> $path, Timeout
=> 120);
55 die "unable to connect to socket '$path' - $!" if !$s;
57 my $select = new IO
::Select
;
59 $select->add(\
*STDIN
);
62 my $timeout = 60*15; # 15 minutes
65 while ($select->count &&
66 scalar(@handles = $select->can_read ($timeout))) {
67 foreach my $h (@handles) {
69 my $n = $h->sysread($buf, 4096);
79 syswrite(\
*STDOUT
, $buf);
89 __PACKAGE__-
>register_method ({
93 description
=> "Show command line which is used to start the VM (debug info).",
95 additionalProperties
=> 0,
97 vmid
=> get_standard_option
('pve-vmid'),
100 returns
=> { type
=> 'null'},
104 my $storecfg = PVE
::Storage
::config
();
105 print PVE
::QemuServer
::vm_commandline
($storecfg, $param->{vmid
}) . "\n";
110 __PACKAGE__-
>register_method ({
114 description
=> "Show VM status.",
116 additionalProperties
=> 0,
118 vmid
=> get_standard_option
('pve-vmid'),
120 description
=> "Verbose output format",
126 returns
=> { type
=> 'null'},
131 my $conf = PVE
::QemuServer
::load_config
($param->{vmid
});
133 my $vmstatus = PVE
::QemuServer
::vmstatus
($param->{vmid
});
134 my $stat = $vmstatus->{$param->{vmid
}};
135 if ($param->{verbose
}) {
136 foreach my $k (sort (keys %$stat)) {
137 next if $k eq 'cpu' || $k eq 'relcpu'; # always 0
139 next if !defined($v);
143 my $status = $stat->{status
} || 'unknown';
144 print "status: $status\n";
150 __PACKAGE__-
>register_method ({
154 description
=> "Proxy VM VNC traffic to stdin/stdout",
156 additionalProperties
=> 0,
158 vmid
=> get_standard_option
('pve-vmid'),
161 returns
=> { type
=> 'null'},
165 my $vmid = $param->{vmid
};
166 my $vnc_socket = PVE
::QemuServer
::vnc_socket
($vmid);
168 if (my $ticket = $ENV{LC_PVE_TICKET
}) { # NOTE: ssh on debian only pass LC_* variables
169 PVE
::QemuServer
::vm_mon_cmd
($vmid, "change", device
=> 'vnc', target
=> "unix:$vnc_socket,password");
170 PVE
::QemuServer
::vm_mon_cmd
($vmid, "set_password", protocol
=> 'vnc', password
=> $ticket);
171 PVE
::QemuServer
::vm_mon_cmd
($vmid, "expire_password", protocol
=> 'vnc', time => "+30");
173 PVE
::QemuServer
::vm_mon_cmd
($vmid, "change", device
=> 'vnc', target
=> "unix:$vnc_socket,x509,password");
176 run_vnc_proxy
($vnc_socket);
181 __PACKAGE__-
>register_method ({
185 description
=> "Unlock the VM.",
187 additionalProperties
=> 0,
189 vmid
=> get_standard_option
('pve-vmid'),
192 returns
=> { type
=> 'null'},
196 my $vmid = $param->{vmid
};
198 PVE
::QemuServer
::lock_config
($vmid, sub {
199 my $conf = PVE
::QemuServer
::load_config
($vmid);
200 delete $conf->{lock};
201 PVE
::QemuServer
::update_config_nolock
($vmid, $conf, 1);
207 __PACKAGE__-
>register_method ({
211 description
=> "Used by qmigrate - do not use manually.",
213 additionalProperties
=> 0,
216 returns
=> { type
=> 'null'},
220 if (!PVE
::Cluster
::check_cfs_quorum
(1)) {
225 print "tunnel online\n";
228 while (my $line = <>) {
230 last if $line =~ m/^quit$/;
236 __PACKAGE__-
>register_method ({
240 description
=> "Wait until the VM is stopped.",
242 additionalProperties
=> 0,
244 vmid
=> get_standard_option
('pve-vmid'),
246 description
=> "Timeout in seconds. Default is to wait forever.",
253 returns
=> { type
=> 'null'},
257 my $vmid = $param->{vmid
};
258 my $timeout = $param->{timeout
};
260 my $pid = PVE
::QemuServer
::check_running
($vmid);
263 print "waiting until VM $vmid stopps (PID $pid)\n";
266 while ((!$timeout || ($count < $timeout)) && PVE
::QemuServer
::check_running
($vmid)) {
271 die "wait failed - got timeout\n" if PVE
::QemuServer
::check_running
($vmid);
276 __PACKAGE__-
>register_method ({
280 description
=> "Enter Qemu Monitor interface.",
282 additionalProperties
=> 0,
284 vmid
=> get_standard_option
('pve-vmid'),
287 returns
=> { type
=> 'null'},
291 my $vmid = $param->{vmid
};
293 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
295 print "Entering Qemu Monitor for VM $vmid - type 'help' for help\n";
297 my $term = new Term
::ReadLine
('qm');
300 while (defined ($input = $term->readline('qm> '))) {
303 next if $input =~ m/^\s*$/;
305 last if $input =~ m/^\s*q(uit)?\s*$/;
308 print PVE
::QemuServer
::vm_human_monitor_command
($vmid, $input);
310 print "ERROR: $@" if $@;
317 __PACKAGE__-
>register_method ({
321 description
=> "Rescan all storages and update disk sizes and unused disk images.",
323 additionalProperties
=> 0,
325 vmid
=> get_standard_option
('pve-vmid', {optional
=> 1}),
328 returns
=> { type
=> 'null'},
332 PVE
::QemuServer
::rescan
($param->{vmid
});
337 __PACKAGE__-
>register_method ({
341 description
=> "Open a terminal using a serial device (The VM need to have a serial device configured, for example 'serial0: socket')",
343 additionalProperties
=> 0,
345 vmid
=> get_standard_option
('pve-vmid'),
347 description
=> "Select the serial device. By default we simply use the first suitable device.",
350 enum
=> [qw(serial0 serial1 serial2 serial3)],
354 returns
=> { type
=> 'null'},
358 my $vmid = $param->{vmid
};
360 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
362 my $iface = $param->{iface
};
365 die "serial interface '$iface' is not configured\n" if !$conf->{$iface};
366 die "wrong serial type on interface '$iface'\n" if $conf->{$iface} ne 'socket';
368 foreach my $opt (qw(serial0 serial1 serial2 serial3)) {
369 if ($conf->{$opt} && ($conf->{$opt} eq 'socket')) {
374 die "unable to find a serial interface\n" if !$iface;
377 die "VM $vmid not running\n" if !PVE
::QemuServer
::check_running
($vmid);
379 my $socket = "/var/run/qemu-server/${vmid}.$iface";
381 my $cmd = "socat UNIX-CONNECT:$socket STDIO,raw,echo=0,escape=0x0f";
383 print "starting serial terminal on interface $iface (press control-O to exit)\n";
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 clone
=> [ "PVE::API2::Qemu", 'clone_vm', ['vmid', 'newid'], { node
=> $nodename }, $upid_exit ],
417 migrate
=> [ "PVE::API2::Qemu", 'migrate_vm', ['vmid', 'target'], { node
=> $nodename }, $upid_exit ],
419 set
=> [ "PVE::API2::Qemu", 'update_vm', ['vmid'], { node
=> $nodename } ],
421 resize
=> [ "PVE::API2::Qemu", 'resize_vm', ['vmid', 'disk', 'size'], { node
=> $nodename } ],
423 move_disk
=> [ "PVE::API2::Qemu", 'move_vm_disk', ['vmid', 'disk', 'storage'], { node
=> $nodename }, $upid_exit ],
425 unlink => [ "PVE::API2::Qemu", 'unlink', ['vmid'], { node
=> $nodename } ],
427 config
=> [ "PVE::API2::Qemu", 'vm_config', ['vmid'],
428 { node
=> $nodename }, sub {
430 foreach my $k (sort (keys %$config)) {
431 next if $k eq 'digest';
432 my $v = $config->{$k};
433 if ($k eq 'description') {
434 $v = PVE
::Tools
::encode_text
($v);
440 showcmd
=> [ __PACKAGE__
, 'showcmd', ['vmid']],
442 status
=> [ __PACKAGE__
, 'status', ['vmid']],
444 snapshot
=> [ "PVE::API2::Qemu", 'snapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
446 delsnapshot
=> [ "PVE::API2::Qemu", 'delsnapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
448 rollback
=> [ "PVE::API2::Qemu", 'rollback', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
450 template
=> [ "PVE::API2::Qemu", 'template', ['vmid'], { node
=> $nodename }],
452 start
=> [ "PVE::API2::Qemu", 'vm_start', ['vmid'], { node
=> $nodename } , $upid_exit ],
454 stop
=> [ "PVE::API2::Qemu", 'vm_stop', ['vmid'], { node
=> $nodename }, $upid_exit ],
456 reset => [ "PVE::API2::Qemu", 'vm_reset', ['vmid'], { node
=> $nodename }, $upid_exit ],
458 shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node
=> $nodename }, $upid_exit ],
460 suspend
=> [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node
=> $nodename }, $upid_exit ],
462 resume
=> [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node
=> $nodename }, $upid_exit ],
464 sendkey
=> [ "PVE::API2::Qemu", 'vm_sendkey', ['vmid', 'key'], { node
=> $nodename } ],
466 vncproxy
=> [ __PACKAGE__
, 'vncproxy', ['vmid']],
468 wait => [ __PACKAGE__
, 'wait', ['vmid']],
470 unlock
=> [ __PACKAGE__
, 'unlock', ['vmid']],
472 rescan
=> [ __PACKAGE__
, 'rescan', []],
474 monitor
=> [ __PACKAGE__
, 'monitor', ['vmid']],
476 mtunnel
=> [ __PACKAGE__
, 'mtunnel', []],
478 terminal
=> [ __PACKAGE__
, 'terminal', ['vmid']],
483 # Note: disable '+' prefix for Getopt::Long (for resize command)
484 use Getopt
::Long
qw(:config no_getopt_compat);
486 PVE
::CLIHandler
::handle_cmd
($cmddef, "qm", $cmd, \
@ARGV, undef, $0);
494 qm - qemu/kvm virtual machine manager
502 qm is a script to manage virtual machines with qemu/kvm. You can
503 create and destroy virtual machines, and control execution
504 (start/stop/suspend/resume). Besides that, you can use qm to set
505 parameters in the associated config file. It is also possible to
506 create and delete virtual disks.
510 All configuration files consists of lines in the form
514 See L<vm.conf|vm.conf> for a complete list of options.
516 Configuration files are stored inside the Proxmox configuration file system, and can be access at F</etc/pve/qemu-server/C<VMID>.conf>.
518 The default for option 'keyboard' is read from
519 F</etc/pve/datacenter.conf>.
523 Online migration and backups (vzdump) set a lock to prevent
524 unintentional action on such VMs. Sometimes you need remove such lock
525 manually (power failure).
531 # create a new VM with 4 GB ide disk
532 qm create 300 -ide0 4 -net0 e1000 -cdrom proxmox-mailgateway_2.1.iso
537 # send shutdown, then wait until VM is stopped
538 qm shutdown 300 && qm wait 300
540 # same as above, but only wait for 40 seconds
541 qm shutdown 300 && qm wait 300 -timeout 40
544 =include pve_copyright