]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
Fix #1924: add snapshot parameter
[qemu-server.git] / PVE / API2 / Qemu.pm
index 3a59058672587fc99219e8f31ff0ee263bb2e94e..7f737bf8eaf3725ebde21290f52a7a10a28866f1 100644 (file)
@@ -130,7 +130,7 @@ my $check_storage_access_clone = sub {
 # Note: $pool is only needed when creating a VM, because pool permissions
 # are automatically inherited if VM already exists inside a pool.
 my $create_disks = sub {
-    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $default_storage) = @_;
+    my ($rpcenv, $authuser, $conf, $arch, $storecfg, $vmid, $pool, $settings, $default_storage) = @_;
 
     my $vollist = [];
 
@@ -175,7 +175,7 @@ my $create_disks = sub {
 
            my $volid;
            if ($ds eq 'efidisk0') {
-               ($volid, $size) = PVE::QemuServer::create_efidisk($storecfg, $storeid, $vmid, $fmt);
+               ($volid, $size) = PVE::QemuServer::create_efidisk($storecfg, $storeid, $vmid, $fmt, $arch);
            } else {
                $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, $size);
            }
@@ -589,7 +589,7 @@ __PACKAGE__->register_method({
 
                eval {
 
-                   $vollist = &$create_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $param, $storage);
+                   $vollist = &$create_disks($rpcenv, $authuser, $conf, $arch, $storecfg, $vmid, $pool, $param, $storage);
 
                    if (!$conf->{bootdisk}) {
                        my $firstdisk = PVE::QemuServer::resolve_first_disk($conf);
@@ -648,8 +648,7 @@ __PACKAGE__->register_method({
                if (my $err = $@) {
                    eval {
                        my $conffile = PVE::QemuConfig->config_file($vmid);
-                       unlink($conffile)
-                           or die "failed to remove config file: $@\n";
+                       unlink($conffile) or die "failed to remove config file: $!\n";
                    };
                    warn $@ if $@;
                    die $err;
@@ -830,6 +829,14 @@ __PACKAGE__->register_method({
                default => 0,
                type => 'boolean',
             },
+           snapshot => get_standard_option('pve-snapshot-name', {
+               description => "Fetch config values from given snapshot.",
+               optional => 1,
+               completion => sub {
+                   my ($cmd, $pname, $cur, $args) = @_;
+                   PVE::QemuConfig->snapshot_list($args->[0]);
+               },
+           }),
        },
     },
     returns => {
@@ -847,6 +854,17 @@ __PACKAGE__->register_method({
 
        my $conf = PVE::QemuConfig->load_config($param->{vmid});
 
+       my $snapname = $param->{snapshot};
+       if ($snapname) {
+           my $snapshot = $conf->{snapshots}->{$snapname};
+           die "snapshot '$snapname' does not exist\n"
+               if !defined($snapshot);
+
+           # we need the digest of the file
+           $snapshot->{digest} = $conf->{digest};
+           $conf = $snapshot;
+       }
+
        delete $conf->{snapshots};
 
        if (!$param->{current}) {
@@ -1180,6 +1198,8 @@ my $update_vm_api  = sub {
                $conf = PVE::QemuConfig->load_config($vmid); # update/reload
                next if defined($conf->{pending}->{$opt}) && ($param->{$opt} eq $conf->{pending}->{$opt}); # skip if nothing changed
 
+               my ($arch, undef) = PVE::QemuServer::get_basic_machine_info($conf);
+
                if (PVE::QemuServer::is_valid_drivename($opt)) {
                    my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
                    # FIXME: cloudinit: CDROM or Disk?
@@ -1191,7 +1211,7 @@ my $update_vm_api  = sub {
                    PVE::QemuServer::vmconfig_register_unused_drive($storecfg, $vmid, $conf, PVE::QemuServer::parse_drive($opt, $conf->{pending}->{$opt}))
                        if defined($conf->{pending}->{$opt});
 
-                   &$create_disks($rpcenv, $authuser, $conf->{pending}, $storecfg, $vmid, undef, {$opt => $param->{$opt}});
+                   &$create_disks($rpcenv, $authuser, $conf->{pending}, $arch, $storecfg, $vmid, undef, {$opt => $param->{$opt}});
                } else {
                    $conf->{pending}->{$opt} = $param->{$opt};
                }
@@ -1523,6 +1543,7 @@ __PACKAGE__->register_method({
        my $websocket = $param->{websocket};
 
        my $conf = PVE::QemuConfig->load_config($vmid, $node); # check if VM exists
+       my $use_serial = ($conf->{vga} && ($conf->{vga} =~ m/^serial\d+$/));
 
        my $authpath = "/vms/$vmid";
 
@@ -1531,13 +1552,14 @@ __PACKAGE__->register_method({
        $sslcert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192)
            if !$sslcert;
 
-       my ($remip, $family);
+       my $family;
        my $remcmd = [];
 
        if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
-           ($remip, $family) = PVE::Cluster::remote_node_ip($node);
+           (undef, $family) = PVE::Cluster::remote_node_ip($node);
+           my $sshinfo = PVE::Cluster::get_ssh_info($node);
            # NOTE: kvm VNC traffic is already TLS encrypted or is known unsecure
-           $remcmd = ['/usr/bin/ssh', '-e', 'none', '-T', '-o', 'BatchMode=yes', $remip];
+           $remcmd = PVE::Cluster::ssh_info_to_command($sshinfo, $use_serial ? '-t' : '-T');
        } else {
            $family = PVE::Tools::get_host_address_family($node);
        }
@@ -1553,8 +1575,7 @@ __PACKAGE__->register_method({
 
            my $cmd;
 
-           if ($conf->{vga} && ($conf->{vga} =~ m/^serial\d+$/)) {
-
+           if ($use_serial) {
 
                my $termcmd = [ '/usr/sbin/qm', 'terminal', $vmid, '-iface', $conf->{vga}, '-escape', '0' ];
 
@@ -1671,19 +1692,20 @@ __PACKAGE__->register_method({
 
        my $ticket = PVE::AccessControl::assemble_vnc_ticket($authuser, $authpath);
 
-       my ($remip, $family);
+       my $family;
+       my $remcmd = [];
 
        if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
-           ($remip, $family) = PVE::Cluster::remote_node_ip($node);
+           (undef, $family) = PVE::Cluster::remote_node_ip($node);
+           my $sshinfo = PVE::Cluster::get_ssh_info($node);
+           $remcmd = PVE::Cluster::ssh_info_to_command($sshinfo, '-t');
+           push @$remcmd, '--';
        } else {
            $family = PVE::Tools::get_host_address_family($node);
        }
 
        my $port = PVE::Tools::next_vnc_port($family);
 
-       my $remcmd = $remip ?
-           ['/usr/bin/ssh', '-e', 'none', '-t', $remip, '--'] : [];
-
        my $termcmd = [ '/usr/sbin/qm', 'terminal', $vmid, '-escape', '0'];
        push @$termcmd, '-iface', $serial if $serial;