[pve-devel] [RFC qemu-server 1/3] Insert new options in the Qemu config for the PVE Replica.
Thomas Lamprecht
t.lamprecht at proxmox.com
Tue Apr 4 13:00:48 CEST 2017
I did not verified the behavior or have the full picture yet,
but some more general comments from taking a view at the patch inline.
On 04/03/2017 04:53 PM, Wolfgang Link wrote:
> This patch will include all necessary config for the replication.
> Also will it enable and disable a replication job
> when appointed flags are set or deleted.
> ---
> PVE/API2/Qemu.pm | 41 +++++++++++++++++++++++++++++++++++++++++
> PVE/QemuServer.pm | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 72 insertions(+)
>
> diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
> index 616dc48..20491c9 100644
> --- a/PVE/API2/Qemu.pm
> +++ b/PVE/API2/Qemu.pm
> @@ -24,6 +24,7 @@ use PVE::INotify;
> use PVE::Network;
> use PVE::Firewall;
> use PVE::API2::Firewall::VM;
> +use PVE::ReplicaTools;
>
> BEGIN {
> if (!$ENV{PVE_GENERATING_DOCS}) {
> @@ -1028,6 +1029,20 @@ 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 "reptarget") {
> + delete $conf->{$opt};
> + delete $conf->{replica} if $opt eq "reptarget";
does:
delete $conf->{reptarget} if $opt eq "replica";
miss here to be complete?
or in general just delete both options if we take the if branch?
> +
> + #delete replica in snap to permit uncontrolled behavior.
> + foreach my $snap (keys %{$conf->{snapshots}}) {
> + delete $conf->{snapshots}->{$snap}->{replica};
> + }
> +
> + PVE::QemuConfig->write_config($vmid, $conf);
> + PVE::ReplicaTools::job_remove($vmid);
> + } elsif ($opt eq "repinterval" || $opt eq "replimit") {
> + delete $conf->{$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 +1065,15 @@ 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") {
> + PVE::ReplicaTools::get_syncable_guestdisks($conf, 'qemu', 1);
> + $conf->{$opt} = $param->{$opt};
> + } elsif ($opt eq "repinterval" || $opt eq "replimit") {
> + $conf->{$opt} = $param->{$opt};
> + } elsif ($opt eq "reptarget" ) {
> + die "Node: $param->{$opt} does not exists in Cluster.\n"
> + if !PVE::Cluster::check_node_exists($param->{$opt});
> + $conf->{$opt} = $param->{$opt};
> } else {
> $conf->{pending}->{$opt} = $param->{$opt};
> }
> @@ -1057,6 +1081,23 @@ my $update_vm_api = sub {
> PVE::QemuConfig->write_config($vmid, $conf);
> }
>
> + if ($param->{replica}) {
this should be
if (defined($param->{replica}))
else you never take this if branch if replica is , e.g., 0
> +
> + eval {
> + if ($param->{replica} =~ m/^(?i:0|no|off|false)$/) {
AFAIK, we restrict booleans since a few versions to 0/1, at least in
configs, so a
if ($param->{replicas})
should be enough here
> + PVE::ReplicaTools::job_disable($vmid);
> + } else {
> + PVE::ReplicaTools::job_enable($vmid);
> + }
> + };
> + if (my $err = $@) {
> + $conf->{replica} = '0';
> + PVE::QemuConfig->write_config($vmid, $conf);
> + die $err;
> + }
> +
> + }
> +
> # remove pending changes when nothing changed
> $conf = PVE::QemuConfig->load_config($vmid); # update/reload
> my $changes = PVE::QemuServer::vmconfig_cleanup_pending($conf);
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index 6865d60..dbdaf35 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -491,6 +491,31 @@ EODESCR
> maxLength => 256,
> optional => 1,
> },
> + replica => {
> + optional => 1,
> + description => "Enable asyncron replica for local storage.",
> + type => 'boolean',
> + default => 0,
> + },
> + replimit => {
> + optional => 1,
> + description => "Asysncron replica speed limit.",
> + type => 'integer',
> + minimum => 0,
> + },
> + repinterval => {
> + optional => 1,
> + description => "Asyncron replica interval [1-1440] in minutes default 15",
AFAIK, you do not need to state the interval and default in the
description if it's set below,
our api->doc export should handle this.
> + type => 'integer',
> + minimum => 1,
> + maximum => 1440,
> + default => 15,
> + },
> + reptarget => {
> + optional => 1,
> + description => "Asysncron replica taget node.",
> + type => 'string',
> + },
`replica_rate_limit`, `replica_interval` and `replica_target` would be
more descriptive, imo.
> protection => {
> optional => 1,
> type => 'boolean',
> @@ -747,6 +772,12 @@ my %drivedesc_base = (
> description => "Whether the drive should be included when making backups.",
> optional => 1,
> },
> + rep => {
> + type => 'boolean',
> + description => 'Will include this drive to an asyncron replical job when it run.',
> + optional => 1,
> + default => 1,
> + },
IMHO, `rep` is a bit confusing here - as above replicate is used, the
full name `replicate` would be better.
also typo in description s/asyncron/asynchronous/ s/replica/replicate/
In general the description is a bit confusing, maybe:
"Include this drive when running asynchronous replication jobs"
> werror => {
> type => 'string',
> enum => [qw(enospc ignore report stop)],
More information about the pve-devel
mailing list