use strict;
use warnings;
use POSIX qw(strftime);
+use JSON;
use PVE::Tools;
use PVE::Cluster;
+use PVE::DataCenterConfig;
+use PVE::ReplicationState;
my $msg2text = sub {
my ($level, $msg) = @_;
my ($self, $func, @param) = @_;
eval {
- local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {
- $self->{delayed_interrupt} = 0;
- die "interrupted by signal\n";
- };
- local $SIG{PIPE} = sub {
- $self->{delayed_interrupt} = 0;
- die "interrupted by signal\n";
+ local $SIG{INT} =
+ local $SIG{TERM} =
+ local $SIG{QUIT} =
+ local $SIG{HUP} =
+ local $SIG{PIPE} = sub {
+ $self->{delayed_interrupt} = 0;
+ die "interrupted by signal\n";
};
my $di = $self->{delayed_interrupt};
};
};
-my @ssh_opts = ('-o', 'BatchMode=yes');
-my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
-
# FIXME: nodeip is now unused
sub migrate {
my ($class, $node, $nodeip, $vmid, $opts) = @_;
$class = ref($class) || $class;
+ my $dc_conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
+
my $migration_network = $opts->{migration_network};
if (!defined($migration_network)) {
- my $dc_conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
$migration_network = $dc_conf->{migration}->{network};
}
my $ssh_info = PVE::Cluster::get_ssh_info($node, $migration_network);
$nodeip = $ssh_info->{ip};
+ my $migration_type = 'secure';
+ if (defined($opts->{migration_type})) {
+ $migration_type = $opts->{migration_type};
+ } elsif (defined($dc_conf->{migration}->{type})) {
+ $migration_type = $dc_conf->{migration}->{type};
+ }
+ $opts->{migration_type} = $migration_type;
+
my $self = {
delayed_interrupt => 0,
opts => $opts,
my $starttime = time();
- local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
- $self->log('err', "received interrupt - delayed");
- $self->{delayed_interrupt} = 1;
+ local $SIG{INT} =
+ local $SIG{TERM} =
+ local $SIG{QUIT} =
+ local $SIG{HUP} =
+ local $SIG{PIPE} = sub {
+ $self->log('err', "received interrupt - delayed");
+ $self->{delayed_interrupt} = 1;
};
# lock container during migration
die "abstract method - implement me";
}
+# transfer replication state helper - call this before moving the guest config
+# - just log the error is something fails
+sub transfer_replication_state {
+ my ($self) = @_;
+
+ my $local_node = PVE::INotify::nodename();
+
+ eval {
+ my $stateobj = PVE::ReplicationState::read_state();
+ my $vmstate = PVE::ReplicationState::extract_vmid_tranfer_state($stateobj, $self->{vmid}, $self->{node}, $local_node);
+ # This have to be quoted when it run it over ssh.
+ my $state = PVE::Tools::shellquote(encode_json($vmstate));
+ my $cmd = [ @{$self->{rem_ssh}}, 'pvesr', 'set-state', $self->{vmid}, $state];
+ $self->cmd($cmd);
+ };
+ if (my $err = $@) {
+ $self->log('err', "transfer replication state failed - $err");
+ $self->{errors} = 1;
+ }
+}
+
+# switch replication job target - call this after moving the guest config
+# - does nothing if there is no relevant replication job
+# - just log the error is something fails
+sub switch_replication_job_target {
+ my ($self) = @_;
+
+ my $local_node = PVE::INotify::nodename();
+
+ eval { PVE::ReplicationConfig::switch_replication_job_target($self->{vmid}, $self->{node}, $local_node); };
+ if (my $err = $@) {
+ $self->log('err', "switch replication job target failed - $err");
+ $self->{errors} = 1;
+ }
+}
+
1;