]>
git.proxmox.com Git - qemu-server.git/blob - qm
1340d226f429bba8a32e08233e548dfdae28d339
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);
52 while ( ++$c < 10 && !-e
$path ) { sleep(1); }
54 my $s = IO
::Socket
::UNIX-
>new(Peer
=> $path, Timeout
=> 120);
56 die "unable to connect to socket '$path' - $!" if !$s;
58 my $select = new IO
::Select
;
60 $select->add(\
*STDIN
);
63 my $timeout = 60*15; # 15 minutes
66 while ($select->count &&
67 scalar(@handles = $select->can_read ($timeout))) {
68 foreach my $h (@handles) {
70 my $n = $h->sysread($buf, 4096);
80 syswrite(\
*STDOUT
, $buf);
90 __PACKAGE__-
>register_method ({
94 description
=> "Show command line which is used to start the VM (debug info).",
96 additionalProperties
=> 0,
98 vmid
=> get_standard_option
('pve-vmid'),
101 returns
=> { type
=> 'null'},
105 my $storecfg = PVE
::Storage
::config
();
106 print PVE
::QemuServer
::vm_commandline
($storecfg, $param->{vmid
}) . "\n";
111 __PACKAGE__-
>register_method ({
115 description
=> "Show VM status.",
117 additionalProperties
=> 0,
119 vmid
=> get_standard_option
('pve-vmid'),
121 description
=> "Verbose output format",
127 returns
=> { type
=> 'null'},
132 my $conf = PVE
::QemuServer
::load_config
($param->{vmid
});
134 my $vmstatus = PVE
::QemuServer
::vmstatus
($param->{vmid
});
135 my $stat = $vmstatus->{$param->{vmid
}};
136 if ($param->{verbose
}) {
137 foreach my $k (sort (keys %$stat)) {
138 next if $k eq 'cpu' || $k eq 'relcpu'; # always 0
140 next if !defined($v);
144 my $status = $stat->{status
} || 'unknown';
145 print "status: $status\n";
151 __PACKAGE__-
>register_method ({
155 description
=> "Proxy VM VNC traffic to stdin/stdout",
157 additionalProperties
=> 0,
159 vmid
=> get_standard_option
('pve-vmid'),
162 returns
=> { type
=> 'null'},
166 my $vmid = $param->{vmid
};
168 run_vnc_proxy
($vmid);
173 __PACKAGE__-
>register_method ({
177 description
=> "Unlock the VM.",
179 additionalProperties
=> 0,
181 vmid
=> get_standard_option
('pve-vmid'),
184 returns
=> { type
=> 'null'},
188 my $vmid = $param->{vmid
};
190 PVE
::QemuServer
::lock_config
($vmid, sub {
191 my $conf = PVE
::QemuServer
::load_config
($vmid);
192 delete $conf->{lock};
193 PVE
::QemuServer
::update_config_nolock
($vmid, $conf, 1);
199 __PACKAGE__-
>register_method ({
203 description
=> "Used by qmigrate - do not use manually.",
205 additionalProperties
=> 0,
208 returns
=> { type
=> 'null'},
212 if (!PVE
::Cluster
::check_cfs_quorum
(1)) {
217 print "tunnel online\n";
220 while (my $line = <>) {
222 last if $line =~ m/^quit$/;
228 __PACKAGE__-
>register_method ({
232 description
=> "Wait until the VM is stopped.",
234 additionalProperties
=> 0,
236 vmid
=> get_standard_option
('pve-vmid'),
238 description
=> "Timeout in seconds. Default is to wait forever.",
245 returns
=> { type
=> 'null'},
249 my $vmid = $param->{vmid
};
250 my $timeout = $param->{timeout
};
252 my $pid = PVE
::QemuServer
::check_running
($vmid);
255 print "waiting until VM $vmid stopps (PID $pid)\n";
258 while ((!$timeout || ($count < $timeout)) && PVE
::QemuServer
::check_running
($vmid)) {
263 die "wait failed - got timeout\n" if PVE
::QemuServer
::check_running
($vmid);
268 __PACKAGE__-
>register_method ({
272 description
=> "Enter Qemu Monitor interface.",
274 additionalProperties
=> 0,
276 vmid
=> get_standard_option
('pve-vmid'),
279 returns
=> { type
=> 'null'},
283 my $vmid = $param->{vmid
};
285 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
287 print "Entering Qemu Monitor for VM $vmid - type 'help' for help\n";
289 my $term = new Term
::ReadLine
('qm');
292 while (defined ($input = $term->readline('qm> '))) {
295 next if $input =~ m/^\s*$/;
297 last if $input =~ m/^\s*q(uit)?\s*$/;
300 print PVE
::QemuServer
::vm_human_monitor_command
($vmid, $input);
302 print "ERROR: $@" if $@;
309 __PACKAGE__-
>register_method ({
313 description
=> "Rescan all storages and update disk sizes and unused disk images.",
315 additionalProperties
=> 0,
317 vmid
=> get_standard_option
('pve-vmid', {optional
=> 1}),
320 returns
=> { type
=> 'null'},
324 PVE
::QemuServer
::rescan
($param->{vmid
});
329 __PACKAGE__-
>register_method ({
333 description
=> "Open a terminal using a serial device (The VM need to have a serial device configured, for example 'serial0: socket')",
335 additionalProperties
=> 0,
337 vmid
=> get_standard_option
('pve-vmid'),
339 description
=> "Select the serial device. By default we simply use the first suitable device.",
342 enum
=> [qw(serial0 serial1 serial2 serial3)],
346 returns
=> { type
=> 'null'},
350 my $vmid = $param->{vmid
};
352 my $conf = PVE
::QemuServer
::load_config
($vmid); # check if VM exists
354 my $iface = $param->{iface
};
357 die "serial interface '$iface' is not configured\n" if !$conf->{$iface};
358 die "wrong serial type on interface '$iface'\n" if $conf->{$iface} ne 'socket';
360 foreach my $opt (qw(serial0 serial1 serial2 serial3)) {
361 if ($conf->{$opt} && ($conf->{$opt} eq 'socket')) {
366 die "unable to find a serial interface\n" if !$iface;
369 die "VM $vmid not running\n" if !PVE
::QemuServer
::check_running
($vmid);
371 my $socket = "/var/run/qemu-server/${vmid}.$iface";
373 my $cmd = "socat UNIX-CONNECT:$socket STDIO,raw,echo=0,escape=0x0f";
375 print "starting serial terminal on interface $iface (press control-O to exit)\n";
383 list
=> [ "PVE::API2::Qemu", 'vmlist', [],
384 { node
=> $nodename }, sub {
387 exit 0 if (!scalar(@$vmlist));
389 printf "%10s %-20s %-10s %-10s %12s %-10s\n",
390 qw(VMID NAME STATUS MEM(MB) BOOTDISK
(GB
) PID
);
392 foreach my $rec (sort { $a->{vmid
} <=> $b->{vmid
} } @$vmlist) {
393 printf "%10s %-20s %-10s %-10s %12.2f %-10s\n", $rec->{vmid
}, $rec->{name
},
395 ($rec->{maxmem
} || 0)/(1024*1024),
396 ($rec->{maxdisk
} || 0)/(1024*1024*1024),
403 create
=> [ "PVE::API2::Qemu", 'create_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
405 destroy
=> [ "PVE::API2::Qemu", 'destroy_vm', ['vmid'], { node
=> $nodename }, $upid_exit ],
407 clone
=> [ "PVE::API2::Qemu", 'clone_vm', ['vmid', 'newid'], { node
=> $nodename }, $upid_exit ],
409 migrate
=> [ "PVE::API2::Qemu", 'migrate_vm', ['vmid', 'target'], { node
=> $nodename }, $upid_exit ],
411 set
=> [ "PVE::API2::Qemu", 'update_vm', ['vmid'], { node
=> $nodename } ],
413 resize
=> [ "PVE::API2::Qemu", 'resize_vm', ['vmid', 'disk', 'size'], { node
=> $nodename } ],
415 move_disk
=> [ "PVE::API2::Qemu", 'move_vm_disk', ['vmid', 'disk', 'storage'], { node
=> $nodename }, $upid_exit ],
417 unlink => [ "PVE::API2::Qemu", 'unlink', ['vmid', 'idlist'], { node
=> $nodename } ],
419 config
=> [ "PVE::API2::Qemu", 'vm_config', ['vmid'],
420 { node
=> $nodename }, sub {
422 foreach my $k (sort (keys %$config)) {
423 next if $k eq 'digest';
424 my $v = $config->{$k};
425 if ($k eq 'description') {
426 $v = PVE
::Tools
::encode_text
($v);
432 showcmd
=> [ __PACKAGE__
, 'showcmd', ['vmid']],
434 status
=> [ __PACKAGE__
, 'status', ['vmid']],
436 snapshot
=> [ "PVE::API2::Qemu", 'snapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
438 delsnapshot
=> [ "PVE::API2::Qemu", 'delsnapshot', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
440 rollback
=> [ "PVE::API2::Qemu", 'rollback', ['vmid', 'snapname'], { node
=> $nodename } , $upid_exit ],
442 template
=> [ "PVE::API2::Qemu", 'template', ['vmid'], { node
=> $nodename }],
444 start
=> [ "PVE::API2::Qemu", 'vm_start', ['vmid'], { node
=> $nodename } , $upid_exit ],
446 stop
=> [ "PVE::API2::Qemu", 'vm_stop', ['vmid'], { node
=> $nodename }, $upid_exit ],
448 reset => [ "PVE::API2::Qemu", 'vm_reset', ['vmid'], { node
=> $nodename }, $upid_exit ],
450 shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node
=> $nodename }, $upid_exit ],
452 suspend
=> [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node
=> $nodename }, $upid_exit ],
454 resume
=> [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node
=> $nodename }, $upid_exit ],
456 sendkey
=> [ "PVE::API2::Qemu", 'vm_sendkey', ['vmid', 'key'], { node
=> $nodename } ],
458 vncproxy
=> [ __PACKAGE__
, 'vncproxy', ['vmid']],
460 wait => [ __PACKAGE__
, 'wait', ['vmid']],
462 unlock
=> [ __PACKAGE__
, 'unlock', ['vmid']],
464 rescan
=> [ __PACKAGE__
, 'rescan', []],
466 monitor
=> [ __PACKAGE__
, 'monitor', ['vmid']],
468 mtunnel
=> [ __PACKAGE__
, 'mtunnel', []],
470 terminal
=> [ __PACKAGE__
, 'terminal', ['vmid']],
475 # Note: disable '+' prefix for Getopt::Long (for resize command)
476 use Getopt
::Long
qw(:config no_getopt_compat);
478 PVE
::CLIHandler
::handle_cmd
($cmddef, "qm", $cmd, \
@ARGV, undef, $0);
486 qm - qemu/kvm virtual machine manager
494 qm is a script to manage virtual machines with qemu/kvm. You can
495 create and destroy virtual machines, and control execution
496 (start/stop/suspend/resume). Besides that, you can use qm to set
497 parameters in the associated config file. It is also possible to
498 create and delete virtual disks.
502 All configuration files consists of lines in the form
506 See L<vm.conf|vm.conf> for a complete list of options.
508 Configuration files are stored inside the Proxmox configuration file system, and can be access at F</etc/pve/qemu-server/C<VMID>.conf>.
510 The default for option 'keyboard' is read from
511 F</etc/pve/datacenter.conf>.
515 Online migration and backups (vzdump) set a lock to prevent
516 unintentional action on such VMs. Sometimes you need remove such lock
517 manually (power failure).
523 # create a new VM with 4 GB ide disk
524 qm create 300 -ide0 4 -net0 e1000 -cdrom proxmox-mailgateway_2.1.iso
529 # send shutdown, then wait until VM is stopped
530 qm shutdown 300 && qm wait 300
532 # same as above, but only wait for 40 seconds
533 qm shutdown 300 && qm wait 300 -timeout 40
536 =include pve_copyright