public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Fiona Ebner <f.ebner@proxmox.com>
To: Daniel Kral <d.kral@proxmox.com>, pve-devel@lists.proxmox.com
Subject: Re: [PATCH ha-manager v3 09/21] crm command: support JSON-style migrate command
Date: Tue, 13 Oct 2026 16:10:11 +0200	[thread overview]
Message-ID: <c30f6de7-67f0-4732-a178-7f23378db448@proxmox.com> (raw)
In-Reply-To: <DM0CKGG0L6QJ.4F6E6S24639S@proxmox.com>

Am 09.10.26 um 3:38 PM schrieb Daniel Kral:
> On Fri Sep 18, 2026 at 6:08 PM CEST, Fiona Ebner wrote:
>> To pass along opaque migration options from the resource-specific
>> migration API endpoint to the resource plugin implementation, the
>> options will be encoded as JSON. Instead of just adding an extra
>> positional argument with those, support having the full CRM command be
>> recorded as JSON in the queued commands file.
>>
>> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
>> ---
>>
>> New in v3.
>>
>>  src/PVE/HA/Manager.pm | 73 +++++++++++++++++++++++++++++++++----------
>>  1 file changed, 56 insertions(+), 17 deletions(-)
>>
>> diff --git a/src/PVE/HA/Manager.pm b/src/PVE/HA/Manager.pm
>> index 555ea0d..25026d6 100644
>> --- a/src/PVE/HA/Manager.pm
>> +++ b/src/PVE/HA/Manager.pm
>> @@ -4,6 +4,7 @@ use strict;
>>  use warnings;
>>  
>>  use Digest::MD5 qw(md5_base64);
>> +use JSON qw();
>>  
>>  use PVE::Tools;
>>  
>> @@ -670,6 +671,36 @@ sub any_resource_motion_queued_or_running {
>>      return 0;
>>  }
>>  
>> +my sub crm_cmd_migrate_relocate {
> 
> Hm, queue_resource_motion() 'queues' the resource motion command to
> $sd->{cmd}, which is handled in next_state_{started,stopped}().
> 
> Maybe we should call this handle_crm_motion_command() or some
> permutation of that? Or assert_and_queue_resource_motion()?
> 
> The term 'command' is already quite overloaded in the HA stack, but at
> least in the Manager we can discern between crm_*_command (crm_commands
> stack) and resource_*_command ($sd->{cmd}), what do you think?

I'll go with handle_crm_motion_command().

> 
>> +    my ($self, $task, $sid, $node, $options) = @_;
>> +
>> +    my $cmd = "$task $sid $node";
>> +
>> +    if (defined($options) && scalar(keys($options->%*))) {
>> +        $cmd .= ' ' . JSON::encode_json($options);
>> +    }
>> +
>> +    my ($haenv, $ms, $ns, $sc, $ss) = $self->@{qw(haenv ms ns sc ss)};
>> +
>> +    if (my $sd = $ss->{$sid}) {
>> +        if (!$ns->node_is_online($node)) {
>> +            $haenv->log('err', "crm command error - node not online: $cmd");
>> +        } else {
>> +            if ($node eq $sd->{node}) {
>> +                $haenv->log(
>> +                    'info', "ignore crm command - service already on target node: $cmd",
>> +                );
>> +            } else {
>> +                $self->queue_resource_motion($cmd, $task, $sid, $node, $options);
>> +            }
>> +        }
>> +    } else {
>> +        $haenv->log('err', "crm command error - no such service: $cmd");
>> +    }
> 
> If we factor out the logic to a assert_valid_resource_motion() helper as
> suggested in patch #4, then we could use it here, but not a blocker for
> this at all.

I'm doing this for v4.

> 
>> +
>> +    return;
>> +}
>> +
>>  # read new crm commands and save them into crm master status
>>  sub update_crm_commands {
>>      my ($self) = @_;
>> @@ -681,25 +712,33 @@ sub update_crm_commands {
>>      foreach my $cmd (split(/\n/, $cmdlist)) {
>>          chomp $cmd;
>>  
>> -        if ($cmd =~ m/^(migrate|relocate)\s+(\S+)\s+(\S+)$/) {
>> -            my ($task, $sid, $node) = ($1, $2, $3);
>> -            if (my $sd = $ss->{$sid}) {
>> -                if (!$ns->node_is_online($node)) {
>> -                    $haenv->log('err', "crm command error - node not online: $cmd");
>> -                } else {
>> -                    if ($node eq $sd->{node}) {
>> -                        $haenv->log(
>> -                            'info',
>> -                            "ignore crm command - service already on target node: $cmd",
>> -                        );
>> -                    } else {
>> -                        $self->queue_resource_motion($cmd, $task, $sid, $node, {});
>> -                    }
>> -                }
>> -            } else {
>> -                $haenv->log('err', "crm command error - no such service: $cmd");
>> +        if ($cmd =~ m/^{/) {
>> +            # New-style JSON-encoded command. Currently only 'migrate' is supported, allowing for
>> +            # additional options.
>> +
>> +            my $command_info = eval { JSON::decode_json($cmd) };
>> +            if (my $err = $@) {
>> +                $haenv->log('err', "unable to decode command as JSON: '$cmd' - $err");
> 
> nit: unable to decode JSON command: '$cmd' - $err
> 
>> +                next;
>>              }
>>  
>> +            my $kind = $command_info->{kind};
>> +            if (defined($kind) && $kind eq 'migrate') {
> 
> nit: maybe move the defined($kind) check above this already, because
> otherwise any other branch that checks for $kind eq 'something' would
> need it as well.
> 

Will do!

>> +                my ($sid, $node, $options) = $command_info->@{qw(sid node options)};
>> +                if (!defined($sid) || !defined($node)) {
>> +                    $haenv->log('err', "'migrate' JSON command without sid or node");
>> +                    next;
>> +                }
>> +                crm_cmd_migrate_relocate($self, $kind, $sid, $node, $options);
>> +            } else {
>> +                $haenv->log('err', "unable to handle unknown JSON command: '$cmd'");
>> +            }
>> +
>> +            next;
>> +        }
>> +
>> +        if ($cmd =~ m/^(migrate|relocate)\s+(\S+)\s+(\S+)$/) {
>> +            crm_cmd_migrate_relocate($self, $1, $2, $3, {});
> 
> Nice!
> 
>>          } elsif ($cmd =~ m/^stop\s+(\S+)\s+(\S+)$/) {
>>              my ($sid, $timeout) = ($1, $2);
>>              if (my $sd = $ss->{$sid}) {
> 
> 





  reply	other threads:[~2026-10-13 14:10 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18 16:08 [PATCH-SERIES common/cluster/ha-manager/qemu-server/container v3 00/21] migration: strict config check for intra-cluster migration Fiona Ebner
2026-09-18 16:08 ` [PATCH common v3 01/21] tools: move version_cmp() helper from qemu-server Fiona Ebner
2026-09-18 16:08 ` [PATCH common v3 02/21] rest handler: handle: respect schema's 'type-property' when resolving type Fiona Ebner
2026-09-18 16:08 ` [PATCH cluster v3 03/21] cluster: move pvecfg node version helpers from qemu-server Fiona Ebner
2026-09-18 16:08 ` [PATCH ha-manager v3 04/21] next state {stopped,started}: factor out helper to handle motion command Fiona Ebner
2026-10-09 13:32   ` Daniel Kral
2026-09-18 16:08 ` [PATCH ha-manager v3 05/21] lrm: resource migration: support extra migration options Fiona Ebner
2026-10-09 13:34   ` Daniel Kral
2026-10-13 13:57     ` Fiona Ebner
2026-09-18 16:08 ` [PATCH ha-manager v3 06/21] change service state: support hash as a parameter value Fiona Ebner
2026-09-18 16:08 ` [PATCH ha-manager v3 07/21] next state: handle motion command: support migration options Fiona Ebner
2026-10-09 13:35   ` Daniel Kral
2026-09-18 16:08 ` [PATCH ha-manager v3 08/21] queue resource motion: " Fiona Ebner
2026-10-13 12:22   ` Daniel Kral
2026-09-18 16:08 ` [PATCH ha-manager v3 09/21] crm command: support JSON-style migrate command Fiona Ebner
2026-10-09 13:38   ` Daniel Kral
2026-10-13 14:10     ` Fiona Ebner [this message]
2026-09-18 16:08 ` [PATCH ha-manager v3 10/21] api: resources: migration: support additional migration options Fiona Ebner
2026-09-18 16:21   ` Fiona Ebner
2026-10-12  9:59   ` Daniel Kral
2026-10-13 14:34     ` Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 11/21] helpers: move version_cmp() helper to pve-common Fiona Ebner
2026-10-08 14:46   ` Michael Köppl
2026-10-08 14:49     ` Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 12/21] helpers: move pvecfg node version helpers to pve-cluster Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 13/21] api: migrate: allow forwarding certain migration properties to HA Fiona Ebner
2026-10-13 12:25   ` Daniel Kral
2026-09-18 16:08 ` [PATCH qemu-server v3 14/21] fix #7053: api: migrate: pass 'with-conntrack-state' flag to HA migration Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 15/21] qm: mtunnel: reply when a command is unknown Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 16/21] qm: mtunnel: add 'conf' command to do strict configuration parsing Fiona Ebner
2026-09-18 16:08 ` [PATCH qemu-server v3 17/21] migration: intra-cluster: check config can be parsed on target node Fiona Ebner
2026-09-18 16:08 ` [PATCH container v3 18/21] api: migrate: allow forwarding certain migration properties to HA Fiona Ebner
2026-09-18 16:08 ` [PATCH container v3 19/21] pct: introduce mtunnel command Fiona Ebner
2026-09-18 16:08 ` [PATCH container v3 20/21] d/control: bump versioned build dependency for libpve-common-perl to 9.0.12 Fiona Ebner
2026-09-18 16:08 ` [PATCH container v3 21/21] migration: intra-cluster: check config can be parsed on target node Fiona Ebner
2026-10-13 12:40 ` [PATCH-SERIES common/cluster/ha-manager/qemu-server/container v3 00/21] migration: strict config check for intra-cluster migration Daniel Kral

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c30f6de7-67f0-4732-a178-7f23378db448@proxmox.com \
    --to=f.ebner@proxmox.com \
    --cc=d.kral@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal