};
__PACKAGE__->register_method({
- name => 'vmlist',
- path => '',
+ name => 'vmlist',
+ path => '',
method => 'GET',
description => "Virtual machine index (per node).",
proxyto => 'node',
}});
__PACKAGE__->register_method({
- name => 'create_vm',
- path => '',
+ name => 'create_vm',
+ path => '',
method => 'POST',
description => "Create or restore a virtual machine.",
protected => 1,
optional => 1,
}),
force => {
- optional => 1,
+ optional => 1,
type => 'boolean',
description => "Allow to overwrite existing VM.",
requires => 'archive',
},
unique => {
- optional => 1,
+ optional => 1,
type => 'boolean',
description => "Assign a unique random ethernet address.",
requires => 'archive',
},
}),
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $unique = extract_param($param, 'unique');
my $filename = PVE::QemuServer::config_file($vmid);
-
- my $storecfg = PVE::Storage::config();
+
+ my $storecfg = PVE::Storage::config();
PVE::Cluster::check_cfs_quorum();
- if (!$archive) {
+ if (!$archive) {
&$resolve_cdrom_alias($param);
foreach my $opt (keys %$param) {
if (PVE::QemuServer::valid_drivename($opt)) {
my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
raise_param_exc({ $opt => "unable to parse drive options" }) if !$drive;
-
+
PVE::QemuServer::cleanup_drive_path($opt, $storecfg, $drive);
$param->{$opt} = PVE::QemuServer::print_drive($vmid, $drive);
}
raise_param_exc({ archive => "option conflicts with other options ($keystr)"}) if $keystr;
if ($archive eq '-') {
- die "pipe requires cli environment\n"
+ die "pipe requires cli environment\n"
&& $rpcenv->{type} ne 'cli';
} else {
my $path;
if (PVE::Storage::parse_volume_id($archive, 1)) {
$path = PVE::Storage::path($storecfg, $archive);
} else {
- raise_param_exc({ archive => "Only root can pass arbitrary paths." })
+ raise_param_exc({ archive => "Only root can pass arbitrary paths." })
if $user ne 'root@pam';
$path = abs_path($archive);
my $restorefn = sub {
if (-f $filename) {
- die "unable to restore vm $vmid: config file already exists\n"
+ die "unable to restore vm $vmid: config file already exists\n"
if !$force;
- die "unable to restore vm $vmid: vm is running\n"
+ die "unable to restore vm $vmid: vm is running\n"
if PVE::QemuServer::check_running($vmid);
# destroy existing data - keep empty config
}
my $realcmd = sub {
- PVE::QemuServer::restore_archive($archive, $vmid, {
+ PVE::QemuServer::restore_archive($archive, $vmid, {
storage => $storage,
unique => $unique });
};
my $createfn = sub {
# second test (after locking test is accurate)
- die "unable to create vm $vmid: config file already exists\n"
+ die "unable to create vm $vmid: config file already exists\n"
if -f $filename;
my $realcmd = sub {
}
if (!$param->{bootdisk} && $firstdisk) {
- $param->{bootdisk} = $firstdisk;
+ $param->{bootdisk} = $firstdisk;
}
PVE::QemuServer::create_conf_nolock($vmid, $param);
__PACKAGE__->register_method({
name => 'vmdiridx',
- path => '{vmid}',
+ path => '{vmid}',
method => 'GET',
proxyto => 'node',
description => "Directory index",
{ subdir => 'rrddata' },
{ subdir => 'monitor' },
];
-
+
return $res;
}});
__PACKAGE__->register_method({
- name => 'rrd',
- path => '{vmid}/rrd',
+ name => 'rrd',
+ path => '{vmid}/rrd',
method => 'GET',
protected => 1, # fixme: can we avoid that?
permissions => {
my ($param) = @_;
return PVE::Cluster::create_rrd_graph(
- "pve2-vm/$param->{vmid}", $param->{timeframe},
+ "pve2-vm/$param->{vmid}", $param->{timeframe},
$param->{ds}, $param->{cf});
-
+
}});
__PACKAGE__->register_method({
- name => 'rrddata',
- path => '{vmid}/rrddata',
+ name => 'rrddata',
+ path => '{vmid}/rrddata',
method => 'GET',
protected => 1, # fixme: can we avoid that?
permissions => {
__PACKAGE__->register_method({
- name => 'vm_config',
- path => '{vmid}/config',
+ name => 'vm_config',
+ path => '{vmid}/config',
method => 'GET',
proxyto => 'node',
description => "Get virtual machine configuration.",
vmid => get_standard_option('pve-vmid'),
},
},
- returns => {
+ returns => {
type => "object",
properties => {
digest => {
}});
__PACKAGE__->register_method({
- name => 'update_vm',
- path => '{vmid}/config',
+ name => 'update_vm',
+ path => '{vmid}/config',
method => 'PUT',
protected => 1,
proxyto => 'node',
type => 'string',
description => 'Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.',
maxLength => 40,
- optional => 1,
+ optional => 1,
}
}),
},
}
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
my $delete = extract_param($param, 'delete');
die "no options specified\n" if !$delete && !scalar(keys %$param);
- my $storecfg = PVE::Storage::config();
+ my $storecfg = PVE::Storage::config();
&$resolve_cdrom_alias($param);
my $conf = PVE::QemuServer::load_config($vmid);
- die "checksum missmatch (file change by other user?)\n"
+ die "checksum missmatch (file change by other user?)\n"
if $digest && $digest ne $conf->{digest};
PVE::QemuServer::check_lock($conf) if !$skiplock;
if (!PVE::QemuServer::option_exists($opt)) {
raise_param_exc({ delete => "unknown option '$opt'" });
- }
+ }
next if !defined($conf->{$opt});
__PACKAGE__->register_method({
- name => 'destroy_vm',
- path => '{vmid}',
+ name => 'destroy_vm',
+ path => '{vmid}',
method => 'DELETE',
protected => 1,
proxyto => 'node',
skiplock => get_standard_option('skiplock'),
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = $param->{vmid};
my $skiplock = $param->{skiplock};
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
# test if VM exists
my $conf = PVE::QemuServer::load_config($vmid);
- my $storecfg = PVE::Storage::config();
+ my $storecfg = PVE::Storage::config();
my $realcmd = sub {
my $upid = shift;
}});
__PACKAGE__->register_method({
- name => 'unlink',
- path => '{vmid}/unlink',
+ name => 'unlink',
+ path => '{vmid}/unlink',
method => 'PUT',
protected => 1,
proxyto => 'node',
my $sslcert;
__PACKAGE__->register_method({
- name => 'vncproxy',
- path => '{vmid}/vncproxy',
+ name => 'vncproxy',
+ path => '{vmid}/vncproxy',
method => 'POST',
protected => 1,
permissions => {
vmid => get_standard_option('pve-vmid'),
},
},
- returns => {
+ returns => {
additionalProperties => 0,
properties => {
user => { type => 'string' },
my $port = PVE::Tools::next_vnc_port();
my $remip;
-
+
if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
$remip = PVE::Cluster::remote_node_ip($node);
}
my $remcmd = $remip ? ['/usr/bin/ssh', '-T', '-o', 'BatchMode=yes',
'-c', 'blowfish-cbc', $remip] : [];
- my $timeout = 10;
+ my $timeout = 10;
my $realcmd = sub {
my $upid = shift;
return {
user => $user,
ticket => $ticket,
- port => $port,
- upid => $upid,
- cert => $sslcert,
+ port => $port,
+ upid => $upid,
+ cert => $sslcert,
};
}});
__PACKAGE__->register_method({
name => 'vmcmdidx',
- path => '{vmid}/status',
+ path => '{vmid}/status',
method => 'GET',
proxyto => 'node',
description => "Directory index",
{ subdir => 'start' },
{ subdir => 'stop' },
];
-
+
return $res;
}});
__PACKAGE__->register_method({
- name => 'vm_status',
+ name => 'vm_status',
path => '{vmid}/status/current',
method => 'GET',
proxyto => 'node',
}});
__PACKAGE__->register_method({
- name => 'vm_start',
+ name => 'vm_start',
path => '{vmid}/status/start',
method => 'POST',
protected => 1,
stateuri => get_standard_option('pve-qm-stateuri'),
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $stateuri = extract_param($param, 'stateuri');
- raise_param_exc({ stateuri => "Only root may use this option." })
+ raise_param_exc({ stateuri => "Only root may use this option." })
if $stateuri && $user ne 'root@pam';
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
- my $storecfg = PVE::Storage::config();
+ my $storecfg = PVE::Storage::config();
my $realcmd = sub {
my $upid = shift;
}});
__PACKAGE__->register_method({
- name => 'vm_stop',
+ name => 'vm_stop',
path => '{vmid}/status/stop',
method => 'POST',
protected => 1,
}
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
my $keepActive = extract_param($param, 'keepActive');
- raise_param_exc({ keepActive => "Only root may use this option." })
+ raise_param_exc({ keepActive => "Only root may use this option." })
if $keepActive && $user ne 'root@pam';
my $storecfg = PVE::Storage::config();
syslog('info', "stop VM $vmid: $upid\n");
- PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0,
+ PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0,
$param->{timeout}, 0, 1, $keepActive);
return;
}});
__PACKAGE__->register_method({
- name => 'vm_reset',
+ name => 'vm_reset',
path => '{vmid}/status/reset',
method => 'POST',
protected => 1,
skiplock => get_standard_option('skiplock'),
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
}});
__PACKAGE__->register_method({
- name => 'vm_shutdown',
+ name => 'vm_shutdown',
path => '{vmid}/status/shutdown',
method => 'POST',
protected => 1,
}
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
my $keepActive = extract_param($param, 'keepActive');
- raise_param_exc({ keepActive => "Only root may use this option." })
+ raise_param_exc({ keepActive => "Only root may use this option." })
if $keepActive && $user ne 'root@pam';
my $storecfg = PVE::Storage::config();
syslog('info', "shutdown VM $vmid: $upid\n");
- PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0, $param->{timeout},
+ PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0, $param->{timeout},
1, $param->{forceStop}, $keepActive);
return;
}});
__PACKAGE__->register_method({
- name => 'vm_suspend',
+ name => 'vm_suspend',
path => '{vmid}/status/suspend',
method => 'POST',
protected => 1,
skiplock => get_standard_option('skiplock'),
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
}});
__PACKAGE__->register_method({
- name => 'vm_resume',
+ name => 'vm_resume',
path => '{vmid}/status/resume',
method => 'POST',
protected => 1,
skiplock => get_standard_option('skiplock'),
},
},
- returns => {
+ returns => {
type => 'string',
},
code => sub {
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
}});
__PACKAGE__->register_method({
- name => 'vm_sendkey',
+ name => 'vm_sendkey',
path => '{vmid}/sendkey',
method => 'PUT',
protected => 1,
my $vmid = extract_param($param, 'vmid');
my $skiplock = extract_param($param, 'skiplock');
- raise_param_exc({ skiplock => "Only root may use this option." })
+ raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $user ne 'root@pam';
PVE::QemuServer::vm_sendkey($vmid, $skiplock, $param->{key});
}});
__PACKAGE__->register_method({
- name => 'migrate_vm',
+ name => 'migrate_vm',
path => '{vmid}/migrate',
method => 'POST',
protected => 1,
},
},
},
- returns => {
+ returns => {
type => 'string',
description => "the task ID.",
},
my $vmid = extract_param($param, 'vmid');
- raise_param_exc({ force => "Only root may use this option." })
+ raise_param_exc({ force => "Only root may use this option." })
if $param->{force} && $user ne 'root@pam';
# test if VM exists
PVE::QemuServer::check_lock($conf);
if (PVE::QemuServer::check_running($vmid)) {
- die "cant migrate running VM without --online\n"
+ die "cant migrate running VM without --online\n"
if !$param->{online};
}
}});
__PACKAGE__->register_method({
- name => 'monitor',
- path => '{vmid}/monitor',
+ name => 'monitor',
+ path => '{vmid}/monitor',
method => 'POST',
protected => 1,
proxyto => 'node',
PVE::JSONSchema::register_standard_option('skiplock', {
description => "Ignore locks - only root is allowed to use this option.",
- type => 'boolean',
+ type => 'boolean',
optional => 1,
});
foreach my $o (split(//, $bootorder)) {
$bootindex_hash->{$o} = $i*100;
$i++;
- }
+ }
push @$cmd, '-boot', "menu=on";
if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
push @$vollist, $drive->{file};
}
-
+
$use_virtio = 1 if $ds =~ m/^virtio/;
if (drive_is_cdrom ($drive)) {
$tmpstr .= ",bootindex=$bootindex";
$bootindex_hash->{n} += 1;
}
- push @$cmd, '-device', $tmpstr;
+ push @$cmd, '-device', $tmpstr;
}
}
my $bus;
my $addr;
my $id;
-
+
foreach my $line (@lines) {
$line =~ s/^\s+//;
if ($line =~ m/^Bus (\d+), device (\d+), function (\d+):$/) {
sub vm_deviceplug {
my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
return 1 if !check_running($vmid) || !$conf->{hotplug} || $conf->{$deviceid};
-
+
if ($deviceid =~ m/^(virtio)(\d+)$/) {
return undef if !qemu_driveadd($storecfg, $vmid, $device);
my $devicefull = print_drivedevice_full($storecfg, $vmid, $device);
my $ret = vm_monitor_command($vmid, "device_add $devicefull");
$ret =~ s/^\s+//;
- # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
+ # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
return 1 if $ret eq "";
syslog("err", "error on hotplug device : $ret");
return undef;
}
-
+
sub qemu_devicedel {
my($vmid, $deviceid) = @_;
}
return 1;
}
-
+
sub qemu_drivedel {
my($vmid, $deviceid) = @_;
my $ret = vm_monitor_command($vmid, "drive_del drive-$deviceid");
$ret =~ s/^\s+//;
if ($ret =~ m/Device \'.*?\' not found/s) {
- # NB: device not found errors mean the drive was auto-deleted and we ignore the error
+ # NB: device not found errors mean the drive was auto-deleted and we ignore the error
}
elsif ($ret ne "") {
syslog("err", "deleting drive $deviceid failed : $ret");
my $devices_list = vm_devices_list($vmid);
return 1 if defined($devices_list->{$deviceid});
sleep 1;
- }
+ }
syslog("err", "error on hotplug device $deviceid");
return undef;
}
-
+
sub qemu_devicedelverify {
my ($vmid,$deviceid) = @_;
my $devices_list = vm_devices_list($vmid);
return 1 if !defined($devices_list->{$deviceid});
sleep 1;
- }
+ }
syslog("err", "error on hot-unplugging device $deviceid");
return undef;
}
eval { vm_monitor_command($vmid, "cont"); };
}
}
-
+
# always set migrate speed (overwrite kvm default of 32m)
# we set a very hight default of 8192m which is basically unlimited
my $migrate_speed = $defaults->{migrate_speed} || 8192;
$migrate_speed = $conf->{migrate_speed} || $migrate_speed;
- eval {
+ eval {
my $cmd = "migrate_set_speed ${migrate_speed}m";
- vm_monitor_command($vmid, $cmd);
+ vm_monitor_command($vmid, $cmd);
};
if (my $migrate_downtime =
vm_monitor_command($vmid, "system_powerdown", $nocheck);
} else {
vm_monitor_command($vmid, "quit", $nocheck);
- }
+ }
};
my $err = $@;
warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
kill 15, $pid;
} else {
- die "VM quit/powerdown failed\n";
+ die "VM quit/powerdown failed\n";
}
}
while (($try < $maxtries) && $count) {
$try++;
sleep $wt;
-
+
$vzlist = vzlist();
$count = 0;
foreach my $vmid (keys %$vzlist) {
while (($try < $maxtries) && $count) {
$try++;
sleep $wt;
-
+
$vzlist = vzlist();
$count = 0;
foreach my $vmid (keys %$vzlist) {
$vzlist = vzlist();
foreach my $vmid (keys %$cleanuphash) {
next if $vzlist->{$vmid}->{pid};
- eval {
+ eval {
my $conf = load_config($vmid);
- vm_stop_cleanup($storecfg, $vmid, $conf);
+ vm_stop_cleanup($storecfg, $vmid, $conf);
};
warn $@ if $@;
}
return -d $testdir;
}
-sub print_pci_addr {
+sub print_pci_addr {
my ($id) = @_;
my $res = '';
sub archive_read_firstfile {
my $archive = shift;
-
+
die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
# try to detect archive type first
my $cfg = cfs_read_file('storage.cfg');
PVE::Storage::vdisk_free($cfg, $volid);
}
- print STDERR "temporary volume '$volid' sucessfuly removed\n";
+ print STDERR "temporary volume '$volid' sucessfuly removed\n";
};
print STDERR "unable to cleanup '$volid' - $@" if $@;
} else {
print STDERR "unable to parse line in statfile - $line";
- }
+ }
}
$fd->close();
}
print STDERR "got interrupt - ignored\n";
};
- eval {
+ eval {
# enable interrupts
local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
die "interrupted by signal\n";
my $net = parse_net($netstr);
$net->{macaddr} = PVE::Tools::random_ether_addr() if $net->{macaddr};
$netstr = print_net($net);
- print $outfd "$id: $netstr\n";
+ print $outfd "$id: $netstr\n";
} elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
my $virtdev = $1;
my $value = $2;
};
my $err = $@;
- if ($err) {
+ if ($err) {
unlink $tmpfn;
restore_cleanup("$tmpdir/qmrestore.stat") if !$opts->{info};
-
+
die $err;
- }
+ }
rmtree $tmpdir;