]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
api: replica: safer config update
[qemu-server.git] / PVE / API2 / Qemu.pm
index 616dc48b88dfcc4541462ac6a8b24eeeadba88c9..80bc141b5817bcc0339bb9f60dfc5633231559a5 100644 (file)
@@ -24,6 +24,7 @@ use PVE::INotify;
 use PVE::Network;
 use PVE::Firewall;
 use PVE::API2::Firewall::VM;
+use PVE::ReplicationTools;
 
 BEGIN {
     if (!$ENV{PVE_GENERATING_DOCS}) {
@@ -1028,6 +1029,16 @@ my $update_vm_api  = sub {
                        if defined($conf->{pending}->{$opt});
                    PVE::QemuServer::vmconfig_delete_pending_option($conf, $opt, $force);
                    PVE::QemuConfig->write_config($vmid, $conf);
+               } elsif ($opt eq "replica" || $opt eq "replica_target") {
+                   delete $conf->{$opt};
+                   delete $conf->{replica} if $opt eq "replica_target";
+
+                   PVE::ReplicationTools::job_remove($vmid);
+                   PVE::QemuConfig->write_config($vmid, $conf);
+               } elsif ($opt eq "replica_interval" || $opt eq "replica_rate_limit") {
+                   delete $conf->{$opt};
+                   PVE::ReplicationTools::update_conf($vmid, $opt, $param->{$opt});
+                   PVE::QemuConfig->write_config($vmid, $conf);
                } else {
                    PVE::QemuServer::vmconfig_delete_pending_option($conf, $opt, $force);
                    PVE::QemuConfig->write_config($vmid, $conf);
@@ -1050,6 +1061,27 @@ my $update_vm_api  = sub {
                        if defined($conf->{pending}->{$opt});
 
                    &$create_disks($rpcenv, $authuser, $conf->{pending}, $storecfg, $vmid, undef, {$opt => $param->{$opt}});
+               } elsif ($opt eq "replica") {
+                   die "Not all volumes are syncable, please check your config\n"
+                       if !PVE::ReplicationTools::check_guest_volumes_syncable($conf, 'qemu');
+                   die "replica_target is required\n"
+                       if !$conf->{replica_target} && !$param->{replica_target};
+                   my $value = $param->{$opt};
+                   if ($value) {
+                       PVE::ReplicationTools::job_enable($vmid);
+                   } else {
+                       PVE::ReplicationTools::job_disable($vmid);
+                   }
+                   $conf->{$opt} = $param->{$opt};
+               } elsif ($opt eq "replica_interval" || $opt eq "replica_rate_limit") {
+                   $conf->{$opt} = $param->{$opt};
+                   PVE::ReplicationTools::update_conf($vmid, $opt, $param->{$opt});
+               } elsif ($opt eq "replica_target" ) {
+                   die "Node: $param->{$opt} does not exists in Cluster.\n"
+                       if !PVE::Cluster::check_node_exists($param->{$opt});
+                   PVE::ReplicationTools::update_conf($vmid, $opt, $param->{$opt})
+                       if defined($conf->{$opt});
+                   $conf->{$opt} = $param->{$opt};
                } else {
                    $conf->{pending}->{$opt} = $param->{$opt};
                }
@@ -1285,6 +1317,9 @@ __PACKAGE__->register_method({
 
            syslog('info', "destroy VM $vmid: $upid\n");
 
+           # return without error if vm has no replica job
+           PVE::ReplicationTools::destroy_replica($vmid);
+
            PVE::QemuServer::vm_destroy($storecfg, $vmid, $skiplock);
 
            PVE::AccessControl::remove_vm_access($vmid);
@@ -1435,6 +1470,7 @@ __PACKAGE__->register_method({
                local $SIG{ALRM} = sub { die "connection timed out\n" };
                alarm $timeout;
                accept(my $cli, $sock) or die "connection failed: $!\n";
+               alarm(0);
                close($sock);
                if (PVE::Tools::run_command($cmd,
                    output => '>&'.fileno($cli),
@@ -2819,7 +2855,12 @@ __PACKAGE__->register_method({
        }
 
        my $storecfg = PVE::Storage::config();
-       PVE::QemuServer::check_storage_availability($storecfg, $conf, $target);
+
+       if( $param->{targetstorage}) {
+           PVE::Storage::storage_check_node($storecfg, $param->{targetstorage}, $target);
+        } else {
+           PVE::QemuServer::check_storage_availability($storecfg, $conf, $target);
+       }
 
        if (PVE::HA::Config::vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {