11 use PVE
::Tools
qw(file_set_contents file_get_contents run_command);
13 my $QM_LIB_PATH = '..';
14 my $MIGRATE_LIB_PATH = '..';
15 my $RUN_DIR_PATH = './MigrationTest/run/';
17 # test configuration shared by all tests
19 my $replication_config = {
35 my $storage_config = {
41 path
=> "/var/lib/vz",
67 monhost
=> "127.0.0.42,127.0.0.21,::1",
68 fsid
=> 'fc4181a6-56eb-4f68-b452-8ba1f381ca2a',
88 path
=> "/some/other/dir/",
114 'bootdisk' => 'scsi0',
116 'ide0' => 'local-zfs:vm-105-disk-1,size=103M',
117 'ide2' => 'none,media=cdrom',
119 'name' => 'Copy-of-VM-newapache',
120 'net0' => 'virtio=4A:A3:E4:4C:CF:F0,bridge=vmbr0,firewall=1',
123 'parent' => 'ohsnap',
125 'scsi0' => 'local-zfs:vm-105-disk-0,size=4G',
126 'scsihw' => 'virtio-scsi-pci',
127 'smbios1' => 'uuid=1ddfe18b-77e0-47f6-a4bd-f1761bf6d763',
130 'bootdisk' => 'scsi0',
132 'ide2' => 'none,media=cdrom',
134 'name' => 'Copy-of-VM-newapache',
135 'net0' => 'virtio=4A:A3:E4:4C:CF:F0,bridge=vmbr0,firewall=1',
138 'scsi0' => 'local-zfs:vm-105-disk-0,size=4G',
139 'scsihw' => 'virtio-scsi-pci',
140 'smbios1' => 'uuid=1ddfe18b-77e0-47f6-a4bd-f1761bf6d763',
141 'snaptime' => 1580976924,
143 'startup' => 'order=2',
144 'vmgenid' => '4eb1d535-9381-4ddc-a8aa-af50c4d9177b'
148 'startup' => 'order=2',
149 'vmgenid' => '4eb1d535-9381-4ddc-a8aa-af50c4d9177b',
152 'bootdisk' => 'scsi0',
154 'ide0' => 'local-lvm:vm-111-disk-0,size=4096M',
155 'ide2' => 'none,media=cdrom',
157 'name' => 'pending-test',
158 'net0' => 'virtio=4A:A3:E4:4C:CF:F0,bridge=vmbr0,firewall=1',
162 'scsi0' => 'local-zfs:vm-111-disk-0,size=103M',
164 'scsihw' => 'virtio-scsi-pci',
166 'smbios1' => 'uuid=5ad71d4d-8f73-4377-853e-2d22c10c96a5',
168 'vmgenid' => '2c00c030-0b5b-4988-a371-6ab259893f22',
171 'bootdisk' => 'scsi0',
173 'scsi0' => 'zfs-alias-1:vm-123-disk-0,size=4096M',
174 'scsi1' => 'zfs-alias-2:vm-123-disk-0,size=4096M',
175 'ide2' => 'none,media=cdrom',
177 'name' => 'alias-test',
178 'net0' => 'virtio=4A:A3:E4:4C:CF:F0,bridge=vmbr0,firewall=1',
182 'scsihw' => 'virtio-scsi-pci',
184 'smbios1' => 'uuid=5ad71d4d-8f73-4377-853e-2d22c10c96a5',
186 'vmgenid' => '2c00c030-0b5b-4988-a371-6ab259893f22',
190 'bootdisk' => 'scsi0',
192 'hotplug' => 'disk,network,usb,memory,cpu',
193 'ide2' => 'none,media=cdrom',
196 'net0' => 'virtio=52:5D:7E:62:85:97,bridge=vmbr1',
199 'scsi0' => 'local-lvm:vm-149-disk-0,format=raw,size=4G',
200 'scsi1' => 'local-dir:149/vm-149-disk-0.qcow2,format=qcow2,size=1G',
201 'scsihw' => 'virtio-scsi-pci',
203 'smbios1' => 'uuid=e980bd43-a405-42e2-b5f4-31efe6517460',
205 'startup' => 'order=2',
206 'vmgenid' => '36c6c50c-6ef5-4adc-9b6f-6ba9c8071db0',
210 'bootdisk' => 'scsi0',
212 'efidisk0' => 'local-lvm:vm-341-disk-0',
213 'ide2' => 'none,media=cdrom',
214 'ipconfig0' => 'ip=103.214.69.10/25,gw=103.214.69.1',
217 'net0' => 'virtio=4E:F1:82:6D:D7:4B,bridge=vmbr0,firewall=1,rate=10',
220 'scsi0' => 'rbd-store:vm-341-disk-0,size=1G',
221 'scsihw' => 'virtio-scsi-pci',
223 'smbios1' => 'uuid=e01e4c73-46f1-47c8-af79-288fdf6b7462',
225 'vmgenid' => 'af47c000-eb0c-48e8-8991-ca4593cd6916',
228 'bootdisk' => 'scsi0',
230 'ide0' => 'rbd-store:vm-1033-cloudinit,media=cdrom,size=4M',
231 'ide2' => 'none,media=cdrom',
232 'ipconfig0' => 'ip=103.214.69.10/25,gw=103.214.69.1',
235 'net0' => 'virtio=4E:F1:82:6D:D7:4B,bridge=vmbr0,firewall=1,rate=10',
238 'scsi0' => 'rbd-store:vm-1033-disk-1,size=1G',
239 'scsihw' => 'virtio-scsi-pci',
241 'smbios1' => 'uuid=e01e4c73-46f1-47c8-af79-288fdf6b7462',
243 'vmgenid' => 'af47c000-eb0c-48e8-8991-ca4593cd6916',
246 'bootdisk' => 'scsi0',
248 'ide2' => 'none,media=cdrom',
251 'net0' => 'virtio=A6:D1:F1:EB:7B:C2,bridge=vmbr0,firewall=1',
256 'scsi0' => 'local-dir:4567/vm-4567-disk-0.qcow2,size=4G',
257 'scsihw' => 'virtio-scsi-pci',
258 'smbios1' => 'uuid=2925fdec-a066-4228-b46b-eef8662f5e74',
261 'bootdisk' => 'scsi0',
263 'ide2' => 'none,media=cdrom',
266 'net0' => 'virtio=A6:D1:F1:EB:7B:C2,bridge=vmbr0,firewall=1',
269 'runningcpu' => 'kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep',
270 'runningmachine' => 'pc-i440fx-5.0+pve0',
271 'scsi0' => 'local-dir:4567/vm-4567-disk-0.qcow2,size=4G',
272 'scsihw' => 'virtio-scsi-pci',
273 'smbios1' => 'uuid=2925fdec-a066-4228-b46b-eef8662f5e74',
274 'snaptime' => 1595928799,
276 'startup' => 'order=2',
277 'vmgenid' => '932b227a-8a39-4ede-955a-dbd4bc4385ed',
278 'vmstate' => 'local-dir:4567/vm-4567-state-snap1.raw',
281 'bootdisk' => 'scsi0',
283 'ide2' => 'none,media=cdrom',
286 'net0' => 'virtio=A6:D1:F1:EB:7B:C2,bridge=vmbr0,firewall=1',
290 'runningcpu' => 'kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep',
291 'runningmachine' => 'pc-i440fx-5.0+pve0',
292 'scsi0' => 'local-dir:4567/vm-4567-disk-0.qcow2,size=4G',
293 'scsi1' => 'local-zfs:vm-4567-disk-0,size=1G',
294 'scsihw' => 'virtio-scsi-pci',
295 'smbios1' => 'uuid=2925fdec-a066-4228-b46b-eef8662f5e74',
296 'snaptime' => 1595928871,
298 'startup' => 'order=2',
299 'vmgenid' => '932b227a-8a39-4ede-955a-dbd4bc4385ed',
300 'vmstate' => 'local-dir:4567/vm-4567-state-snap2.raw',
304 'startup' => 'order=2',
305 'unused0' => 'local-zfs:vm-4567-disk-0',
306 'vmgenid' => 'e698e60c-9278-4dd9-941f-416075383f2a',
310 my $source_vdisks = {
313 'ctime' => 1589439681,
316 'size' => 1073741824,
319 'volid' => 'local-dir:149/vm-149-disk-0.qcow2',
322 'ctime' => 1595928898,
325 'size' => 4294967296,
326 'used' => 1811664896,
328 'volid' => 'local-dir:4567/vm-4567-disk-0.qcow2',
331 'ctime' => 1595928800,
337 'volid' => 'local-dir:4567/vm-4567-state-snap1.raw',
340 'ctime' => 1595928872,
346 'volid' => 'local-dir:4567/vm-4567-state-snap2.raw',
351 'ctime' => '1589277334',
353 'size' => 4294967296,
355 'volid' => 'local-lvm:vm-149-disk-0',
358 'ctime' => '1589277334',
362 'volid' => 'local-lvm:vm-341-disk-0',
365 'ctime' => '1589277334',
367 'size' => 4294967296,
369 'volid' => 'local-lvm:vm-111-disk-0',
374 'ctime' => '1589277334',
376 'size' => 4294967296,
378 'volid' => 'local-zfs:vm-105-disk-0',
381 'ctime' => '1589277334',
385 'volid' => 'local-zfs:vm-105-disk-1',
388 'ctime' => '1589277334',
392 'volid' => 'local-zfs:vm-111-disk-0',
396 'name' => 'vm-4567-disk-0',
398 'size' => 1073741824,
400 'volid' => 'local-zfs:vm-4567-disk-0',
405 'ctime' => '1589277334',
407 'size' => 1073741824,
409 'volid' => 'rbd-store:vm-1033-disk-1',
412 'ctime' => '1589277334',
414 'size' => 1073741824,
416 'volid' => 'rbd-store:vm-1033-cloudinit',
421 'ctime' => '1589277334',
423 'size' => 4294967296,
425 'volid' => 'zfs-alias-1:vm-123-disk-0',
430 'ctime' => '1589277334',
432 'size' => 4294967296,
434 'volid' => 'zfs-alias-2:vm-123-disk-0',
439 my $default_expected_calls_online = {
440 move_config_to_node
=> 1,
445 my $default_expected_calls_offline = {
446 move_config_to_node
=> 1,
449 my $replicated_expected_calls_online = {
450 %{$default_expected_calls_online},
451 transfer_replication_state
=> 1,
452 switch_replication_job_target
=> 1,
455 my $replicated_expected_calls_offline = {
456 %{$default_expected_calls_offline},
457 transfer_replication_state
=> 1,
458 switch_replication_job_target
=> 1,
463 sub get_patched_config
{
464 my ($vmid, $patch) = @_;
466 my $new_config = { %{$vm_configs->{$vmid}} };
467 patch_config
($new_config, $patch) if defined($patch);
473 my ($config, $patch) = @_;
475 foreach my $key (keys %{$patch}) {
476 if ($key eq 'snapshots' && defined($patch->{$key})) {
477 my $new_snapshot_configs = {};
478 foreach my $snap (keys %{$patch->{snapshots
}}) {
479 my $new_snapshot_config = { %{$config->{snapshots
}->{$snap}} };
480 patch_config
($new_snapshot_config, $patch->{snapshots
}->{$snap});
481 $new_snapshot_configs->{$snap} = $new_snapshot_config;
483 $config->{snapshots
} = $new_snapshot_configs;
484 } elsif (defined($patch->{$key})) {
485 $config->{$key} = $patch->{$key};
486 } else { # use undef value for deletion
487 delete $config->{$key};
492 sub local_volids_for_vm
{
496 foreach my $storeid (keys %{$source_vdisks}) {
497 next if $storage_config->{ids
}->{$storeid}->{shared
};
500 map { $_->{vmid
} eq $vmid ?
($_->{volid
} => 1) : () } @{$source_vdisks->{$storeid}}
507 # each test consists of the following:
508 # name - unique name for the test which also serves as a dir name.
509 # NOTE: gets passed to make, so don't use whitespace or slash
510 # and adapt buildsys (regex) on code structure changes
511 # target - hostname of target node
512 # vmid - ID of the VM to migrate
513 # opts - options for the migrate() call
514 # target_volids - hash of volids on the target at the beginning
515 # vm_status - hash with running, runningmachine and optionally runningcpu
516 # expected_calls - hash whose keys are calls which are required
517 # to be made if the migration gets far enough
518 # expect_die - expect the migration call to fail, and an error message
519 # matching the specified text in the log
520 # expected - hash consisting of:
521 # source_volids - hash of volids expected on the source
522 # target_volids - hash of volids expected on the target
523 # vm_config - vm configuration hash
524 # vm_status - hash with running, runningmachine and optionally runningcpu
526 # NOTE get_efivars_size is mocked and returns 128K
527 name
=> '341_running_efidisk_targetstorage_dir',
532 runningmachine
=> 'pc-q35-5.0+pve0',
536 'with-local-disks' => 1,
537 targetstorage
=> 'local-dir',
539 expected_calls
=> $default_expected_calls_online,
543 'local-dir:341/vm-341-disk-10.raw' => 1,
545 vm_config
=> get_patched_config
(341, {
546 efidisk0
=> 'local-dir:341/vm-341-disk-10.raw,format=raw,size=128K',
550 runningmachine
=> 'pc-q35-5.0+pve0',
555 # NOTE get_efivars_size is mocked and returns 128K
556 name
=> '341_running_efidisk',
561 runningmachine
=> 'pc-q35-5.0+pve0',
565 'with-local-disks' => 1,
567 expected_calls
=> $default_expected_calls_online,
571 'local-lvm:vm-341-disk-10' => 1,
573 vm_config
=> get_patched_config
(341, {
574 efidisk0
=> 'local-lvm:vm-341-disk-10,format=raw,size=128K',
578 runningmachine
=> 'pc-q35-5.0+pve0',
583 name
=> '149_running_vdisk_alloc_and_pvesm_free_fail',
588 runningmachine
=> 'pc-q35-5.0+pve0',
592 'with-local-disks' => 1,
595 vdisk_alloc
=> 'local-dir:149/vm-149-disk-11.qcow2',
596 pvesm_free
=> 'local-lvm:vm-149-disk-10',
598 expected_calls
=> {},
599 expect_die
=> "remote command failed with exit code",
601 source_volids
=> local_volids_for_vm
(149),
603 'local-lvm:vm-149-disk-10' => 1,
605 vm_config
=> $vm_configs->{149},
608 runningmachine
=> 'pc-q35-5.0+pve0',
613 name
=> '149_running_vdisk_alloc_fail',
618 runningmachine
=> 'pc-q35-5.0+pve0',
622 'with-local-disks' => 1,
625 vdisk_alloc
=> 'local-lvm:vm-149-disk-10',
627 expected_calls
=> {},
628 expect_die
=> "remote command failed with exit code",
630 source_volids
=> local_volids_for_vm
(149),
632 vm_config
=> $vm_configs->{149},
635 runningmachine
=> 'pc-q35-5.0+pve0',
640 name
=> '149_vdisk_free_fail',
647 'with-local-disks' => 1,
650 'vdisk_free' => 'local-lvm:vm-149-disk-0',
652 expected_calls
=> $default_expected_calls_offline,
653 expect_die
=> "vdisk_free 'local-lvm:vm-149-disk-0' error",
656 'local-lvm:vm-149-disk-0' => 1,
658 target_volids
=> local_volids_for_vm
(149),
659 vm_config
=> $vm_configs->{149},
666 name
=> '105_replicated_run_replication_fail',
672 target_volids
=> local_volids_for_vm
(105),
674 run_replication
=> 1,
676 expected_calls
=> {},
677 expect_die
=> 'run_replication error',
679 source_volids
=> local_volids_for_vm
(105),
680 target_volids
=> local_volids_for_vm
(105),
681 vm_config
=> $vm_configs->{105},
688 name
=> '1033_running_query_migrate_fail',
693 runningmachine
=> 'pc-q35-5.0+pve0',
699 'query-migrate' => 1,
701 expected_calls
=> {},
702 expect_die
=> 'online migrate failure - aborting',
706 vm_config
=> $vm_configs->{1033},
709 runningmachine
=> 'pc-q35-5.0+pve0',
714 name
=> '4567_targetstorage_dirotherdir',
721 targetstorage
=> 'local-dir:other-dir,local-zfs:local-zfs',
723 storage_migrate_map
=> {
724 'local-dir:4567/vm-4567-disk-0.qcow2' => '4567/vm-4567-disk-0.qcow2',
725 'local-dir:4567/vm-4567-state-snap1.raw' => '4567/vm-4567-state-snap1.raw',
726 'local-dir:4567/vm-4567-state-snap2.raw' => '4567/vm-4567-state-snap2.raw',
728 expected_calls
=> $default_expected_calls_offline,
732 'other-dir:4567/vm-4567-disk-0.qcow2' => 1,
733 'other-dir:4567/vm-4567-state-snap1.raw' => 1,
734 'other-dir:4567/vm-4567-state-snap2.raw' => 1,
735 'local-zfs:vm-4567-disk-0' => 1,
737 vm_config
=> get_patched_config
(4567, {
738 'scsi0' => 'other-dir:4567/vm-4567-disk-0.qcow2,size=4G',
741 'scsi0' => 'other-dir:4567/vm-4567-disk-0.qcow2,size=4G',
742 'vmstate' => 'other-dir:4567/vm-4567-state-snap1.raw',
745 'scsi0' => 'other-dir:4567/vm-4567-disk-0.qcow2,size=4G',
746 'scsi1' => 'local-zfs:vm-4567-disk-0,size=1G',
747 'vmstate' => 'other-dir:4567/vm-4567-state-snap2.raw',
757 name
=> '4567_running',
762 runningmachine
=> 'pc-i440fx-5.0+pve0',
766 'with-local-disks' => 1,
768 expected_calls
=> {},
769 expect_die
=> 'online storage migration not possible if non-replicated snapshot exists',
771 source_volids
=> local_volids_for_vm
(4567),
773 vm_config
=> $vm_configs->{4567},
776 runningmachine
=> 'pc-i440fx-5.0+pve0',
781 name
=> '4567_offline',
787 expected_calls
=> $default_expected_calls_offline,
790 target_volids
=> local_volids_for_vm
(4567),
791 vm_config
=> $vm_configs->{4567},
798 name
=> '149_running_orphaned_disk_targetstorage_zfs',
803 runningmachine
=> 'pc-q35-5.0+pve0',
807 'with-local-disks' => 1,
808 targetstorage
=> 'local-zfs',
813 storage_migrate_map
=> {
814 'local-dir:149/vm-149-disk-0.qcow2' => 'vm-149-disk-0',
816 expected_calls
=> $default_expected_calls_online,
819 'local-dir:149/vm-149-disk-0.qcow2' => 1,
822 'local-zfs:vm-149-disk-10' => 1,
824 vm_config
=> get_patched_config
(149, {
825 scsi0
=> 'local-zfs:vm-149-disk-10,format=raw,size=4G',
830 runningmachine
=> 'pc-q35-5.0+pve0',
835 name
=> '149_running_orphaned_disk',
840 runningmachine
=> 'pc-q35-5.0+pve0',
844 'with-local-disks' => 1,
849 storage_migrate_map
=> {
850 'local-dir:149/vm-149-disk-0.qcow2' => '149/vm-149-disk-0.qcow2',
852 expected_calls
=> $default_expected_calls_online,
855 'local-dir:149/vm-149-disk-0.qcow2' => 1,
858 'local-lvm:vm-149-disk-10' => 1,
860 vm_config
=> get_patched_config
(149, {
861 scsi0
=> 'local-lvm:vm-149-disk-10,format=raw,size=4G',
866 runningmachine
=> 'pc-q35-5.0+pve0',
871 # FIXME: This test is not (yet) a realistic situation, because
872 # storage_migrate currently never changes the format (AFAICT)
873 # But if such migrations become possible, we need to either update
874 # the 'format' property or simply remove it for drives migrated
875 # with storage_migrate (the property is optional, so it shouldn't be a problem)
876 name
=> '149_targetstorage_map_lvmzfs_defaultlvm',
883 targetstorage
=> 'local-lvm:local-zfs,local-lvm',
885 storage_migrate_map
=> {
886 'local-lvm:vm-149-disk-0' => 'vm-149-disk-0',
887 'local-dir:149/vm-149-disk-0.qcow2' => 'vm-149-disk-0',
889 expected_calls
=> $default_expected_calls_offline,
893 'local-zfs:vm-149-disk-0' => 1,
894 'local-lvm:vm-149-disk-0' => 1,
896 vm_config
=> get_patched_config
(149, {
897 scsi0
=> 'local-zfs:vm-149-disk-0,format=raw,size=4G',
898 scsi1
=> 'local-lvm:vm-149-disk-0,format=qcow2,size=1G',
906 # FIXME same as for the previous test
907 name
=> '149_targetstorage_map_dirzfs_lvmdir',
915 'with-local-disks' => 1,
916 targetstorage
=> 'local-dir:local-zfs,local-lvm:local-dir',
918 storage_migrate_map
=> {
919 'local-lvm:vm-149-disk-0' => '149/vm-149-disk-0.raw',
920 'local-dir:149/vm-149-disk-0.qcow2' => 'vm-149-disk-0',
922 expected_calls
=> $default_expected_calls_offline,
926 'local-dir:149/vm-149-disk-0.raw' => 1,
927 'local-zfs:vm-149-disk-0' => 1,
929 vm_config
=> get_patched_config
(149, {
930 scsi0
=> 'local-dir:149/vm-149-disk-0.raw,format=raw,size=4G',
931 scsi1
=> 'local-zfs:vm-149-disk-0,format=qcow2,size=1G',
939 name
=> '149_running_targetstorage_map_lvmzfs_defaultlvm',
944 runningmachine
=> 'pc-q35-5.0+pve0',
948 'with-local-disks' => 1,
949 targetstorage
=> 'local-lvm:local-zfs,local-lvm',
951 expected_calls
=> $default_expected_calls_online,
955 'local-zfs:vm-149-disk-10' => 1,
956 'local-lvm:vm-149-disk-11' => 1,
958 vm_config
=> get_patched_config
(149, {
959 scsi0
=> 'local-zfs:vm-149-disk-10,format=raw,size=4G',
960 scsi1
=> 'local-lvm:vm-149-disk-11,format=raw,size=1G',
964 runningmachine
=> 'pc-q35-5.0+pve0',
969 name
=> '149_running_targetstorage_map_lvmzfs_dirdir',
974 runningmachine
=> 'pc-q35-5.0+pve0',
978 'with-local-disks' => 1,
979 targetstorage
=> 'local-lvm:local-zfs,local-dir:local-dir',
981 expected_calls
=> $default_expected_calls_online,
985 'local-zfs:vm-149-disk-10' => 1,
986 'local-dir:149/vm-149-disk-11.qcow2' => 1,
988 vm_config
=> get_patched_config
(149, {
989 scsi0
=> 'local-zfs:vm-149-disk-10,format=raw,size=4G',
990 scsi1
=> 'local-dir:149/vm-149-disk-11.qcow2,format=qcow2,size=1G',
994 runningmachine
=> 'pc-q35-5.0+pve0',
999 name
=> '149_running_targetstorage_zfs',
1004 runningmachine
=> 'pc-q35-5.0+pve0',
1008 'with-local-disks' => 1,
1009 targetstorage
=> 'local-zfs',
1011 expected_calls
=> $default_expected_calls_online,
1013 source_volids
=> {},
1015 'local-zfs:vm-149-disk-10' => 1,
1016 'local-zfs:vm-149-disk-11' => 1,
1018 vm_config
=> get_patched_config
(149, {
1019 scsi0
=> 'local-zfs:vm-149-disk-10,format=raw,size=4G',
1020 scsi1
=> 'local-zfs:vm-149-disk-11,format=raw,size=1G',
1024 runningmachine
=> 'pc-q35-5.0+pve0',
1029 name
=> '149_running_wrong_size',
1034 runningmachine
=> 'pc-q35-5.0+pve0',
1038 'with-local-disks' => 1,
1041 scsi0
=> 'local-lvm:vm-149-disk-0,size=123T',
1043 expected_calls
=> $default_expected_calls_online,
1045 source_volids
=> {},
1047 'local-lvm:vm-149-disk-10' => 1,
1048 'local-dir:149/vm-149-disk-11.qcow2' => 1,
1050 vm_config
=> get_patched_config
(149, {
1051 scsi0
=> 'local-lvm:vm-149-disk-10,format=raw,size=4G',
1052 scsi1
=> 'local-dir:149/vm-149-disk-11.qcow2,format=qcow2,size=1G',
1056 runningmachine
=> 'pc-q35-5.0+pve0',
1061 name
=> '149_running_missing_size',
1066 runningmachine
=> 'pc-q35-5.0+pve0',
1070 'with-local-disks' => 1,
1073 scsi0
=> 'local-lvm:vm-149-disk-0',
1075 expected_calls
=> $default_expected_calls_online,
1077 source_volids
=> {},
1079 'local-lvm:vm-149-disk-10' => 1,
1080 'local-dir:149/vm-149-disk-11.qcow2' => 1,
1082 vm_config
=> get_patched_config
(149, {
1083 scsi0
=> 'local-lvm:vm-149-disk-10,format=raw,size=4G',
1084 scsi1
=> 'local-dir:149/vm-149-disk-11.qcow2,format=qcow2,size=1G',
1088 runningmachine
=> 'pc-q35-5.0+pve0',
1093 name
=> '105_local_device_shared',
1100 ide2
=> '/dev/sde,shared=1',
1102 expected_calls
=> $default_expected_calls_offline,
1104 source_volids
=> {},
1105 target_volids
=> local_volids_for_vm
(105),
1106 vm_config
=> get_patched_config
(105, {
1107 ide2
=> '/dev/sde,shared=1',
1115 name
=> '105_local_device_in_snapshot',
1128 expected_calls
=> {},
1129 expect_die
=> "can't migrate local disk '/dev/sde': local file/device",
1131 source_volids
=> local_volids_for_vm
(105),
1132 target_volids
=> {},
1133 vm_config
=> get_patched_config
(105, {
1146 name
=> '105_local_device',
1155 expected_calls
=> {},
1156 expect_die
=> "can't migrate local disk '/dev/sde': local file/device",
1158 source_volids
=> local_volids_for_vm
(105),
1159 target_volids
=> {},
1160 vm_config
=> get_patched_config
(105, {
1169 name
=> '105_cdrom_in_snapshot',
1178 ide2
=> 'cdrom,media=cdrom',
1182 expected_calls
=> {},
1183 expect_die
=> "can't migrate local cdrom drive (referenced in snapshot - ohsnap",
1185 source_volids
=> local_volids_for_vm
(105),
1186 target_volids
=> {},
1187 vm_config
=> get_patched_config
(105, {
1190 ide2
=> 'cdrom,media=cdrom',
1200 name
=> '105_cdrom',
1207 ide2
=> 'cdrom,media=cdrom',
1209 expected_calls
=> {},
1210 expect_die
=> "can't migrate local cdrom drive",
1212 source_volids
=> local_volids_for_vm
(105),
1213 target_volids
=> {},
1214 vm_config
=> get_patched_config
(105, {
1215 ide2
=> 'cdrom,media=cdrom',
1223 name
=> '149_running_missing_option_withlocaldisks',
1228 runningmachine
=> 'pc-q35-5.0+pve0',
1233 expected_calls
=> {},
1234 expect_die
=> "can't live migrate attached local disks without with-local-disks option",
1236 source_volids
=> local_volids_for_vm
(149),
1237 target_volids
=> {},
1238 vm_config
=> $vm_configs->{149},
1241 runningmachine
=> 'pc-q35-5.0+pve0',
1246 name
=> '149_running_missing_option_online',
1251 runningmachine
=> 'pc-q35-5.0+pve0',
1254 'with-local-disks' => 1,
1256 expected_calls
=> {},
1257 expect_die
=> "can't migrate running VM without --online",
1259 source_volids
=> local_volids_for_vm
(149),
1260 target_volids
=> {},
1261 vm_config
=> $vm_configs->{149},
1264 runningmachine
=> 'pc-q35-5.0+pve0',
1269 name
=> '1033_running_customcpu',
1274 runningmachine
=> 'pc-q35-5.0+pve0',
1275 runningcpu
=> 'host,+kvm_pv_eoi,+kvm_pv_unhalt',
1281 cpu
=> 'custom-mycpu',
1283 expected_calls
=> $default_expected_calls_online,
1285 source_volids
=> {},
1286 target_volids
=> {},
1287 vm_config
=> get_patched_config
(1033, {
1288 cpu
=> 'custom-mycpu',
1292 runningmachine
=> 'pc-q35-5.0+pve0',
1293 runningcpu
=> 'host,+kvm_pv_eoi,+kvm_pv_unhalt',
1298 name
=> '105_replicated_to_non_replication_target',
1304 target_volids
=> {},
1305 expected_calls
=> $replicated_expected_calls_offline,
1307 source_volids
=> {},
1308 target_volids
=> local_volids_for_vm
(105),
1309 vm_config
=> $vm_configs->{105},
1316 name
=> '105_running_replicated',
1321 runningmachine
=> 'pc-i440fx-5.0+pve0',
1325 'with-local-disks' => 1,
1327 target_volids
=> local_volids_for_vm
(105),
1329 %{$replicated_expected_calls_online},
1330 'block-dirty-bitmap-add-drive-scsi0' => 1,
1331 'block-dirty-bitmap-add-drive-ide0' => 1,
1334 source_volids
=> local_volids_for_vm
(105),
1335 target_volids
=> local_volids_for_vm
(105),
1336 vm_config
=> $vm_configs->{105},
1339 runningmachine
=> 'pc-i440fx-5.0+pve0',
1344 name
=> '105_replicated',
1350 target_volids
=> local_volids_for_vm
(105),
1351 expected_calls
=> $replicated_expected_calls_offline,
1353 source_volids
=> local_volids_for_vm
(105),
1354 target_volids
=> local_volids_for_vm
(105),
1355 vm_config
=> $vm_configs->{105},
1362 name
=> '105_running_replicated_without_snapshot',
1367 runningmachine
=> 'pc-i440fx-5.0+pve0',
1374 'with-local-disks' => 1,
1376 target_volids
=> local_volids_for_vm
(105),
1378 %{$replicated_expected_calls_online},
1379 'block-dirty-bitmap-add-drive-scsi0' => 1,
1380 'block-dirty-bitmap-add-drive-ide0' => 1,
1383 source_volids
=> local_volids_for_vm
(105),
1384 target_volids
=> local_volids_for_vm
(105),
1385 vm_config
=> get_patched_config
(105, {
1390 runningmachine
=> 'pc-i440fx-5.0+pve0',
1395 name
=> '105_replicated_without_snapshot',
1407 target_volids
=> local_volids_for_vm
(105),
1408 expected_calls
=> $replicated_expected_calls_offline,
1410 source_volids
=> local_volids_for_vm
(105),
1411 target_volids
=> local_volids_for_vm
(105),
1412 vm_config
=> get_patched_config
(105, {
1421 name
=> '1033_running',
1426 runningmachine
=> 'pc-q35-5.0+pve0',
1431 expected_calls
=> $default_expected_calls_online,
1433 source_volids
=> {},
1434 target_volids
=> {},
1435 vm_config
=> $vm_configs->{1033},
1438 runningmachine
=> 'pc-q35-5.0+pve0',
1443 name
=> '149_locked',
1452 expected_calls
=> {},
1453 expect_die
=> "VM is locked",
1455 source_volids
=> local_volids_for_vm
(149),
1456 target_volids
=> {},
1457 vm_config
=> get_patched_config
(149, {
1466 name
=> '149_storage_not_available',
1472 expected_calls
=> {},
1473 expect_die
=> "storage 'local-lvm' is not available on node 'pve2'",
1475 source_volids
=> local_volids_for_vm
(149),
1476 target_volids
=> {},
1477 vm_config
=> $vm_configs->{149},
1484 name
=> '149_running',
1489 runningmachine
=> 'pc-q35-5.0+pve0',
1493 'with-local-disks' => 1,
1495 expected_calls
=> $default_expected_calls_online,
1497 source_volids
=> {},
1499 'local-lvm:vm-149-disk-10' => 1,
1500 'local-dir:149/vm-149-disk-11.qcow2' => 1,
1502 vm_config
=> get_patched_config
(149, {
1503 scsi0
=> 'local-lvm:vm-149-disk-10,format=raw,size=4G',
1504 scsi1
=> 'local-dir:149/vm-149-disk-11.qcow2,format=qcow2,size=1G',
1508 runningmachine
=> 'pc-q35-5.0+pve0',
1513 name
=> '149_running_drive_mirror_fail',
1518 runningmachine
=> 'pc-q35-5.0+pve0',
1522 'with-local-disks' => 1,
1524 expected_calls
=> {},
1525 expect_die
=> "qemu_drive_mirror 'scsi1' error",
1527 'qemu_drive_mirror' => 'scsi1',
1530 source_volids
=> local_volids_for_vm
(149),
1531 target_volids
=> {},
1532 vm_config
=> $vm_configs->{149},
1535 runningmachine
=> 'pc-q35-5.0+pve0',
1540 name
=> '149_running_unused_block_job_cancel_fail',
1545 runningmachine
=> 'pc-q35-5.0+pve0',
1549 'with-local-disks' => 1,
1553 unused0
=> 'local-dir:149/vm-149-disk-0.qcow2',
1555 expected_calls
=> {},
1556 expect_die
=> "qemu_drive_mirror_monitor 'cancel' error",
1557 # note that 'cancel' is also used to finish and that's what this test is about
1559 'qemu_drive_mirror_monitor' => 'cancel',
1562 source_volids
=> local_volids_for_vm
(149),
1563 target_volids
=> {},
1564 vm_config
=> get_patched_config
(149, {
1566 unused0
=> 'local-dir:149/vm-149-disk-0.qcow2',
1570 runningmachine
=> 'pc-q35-5.0+pve0',
1575 name
=> '149_offline',
1582 'with-local-disks' => 1,
1584 expected_calls
=> $default_expected_calls_offline,
1586 source_volids
=> {},
1587 target_volids
=> local_volids_for_vm
(149),
1588 vm_config
=> $vm_configs->{149},
1595 name
=> '149_storage_migrate_fail',
1602 'with-local-disks' => 1,
1605 'storage_migrate' => 'local-lvm:vm-149-disk-0',
1607 expected_calls
=> {},
1608 expect_die
=> "storage_migrate 'local-lvm:vm-149-disk-0' error",
1610 source_volids
=> local_volids_for_vm
(149),
1611 target_volids
=> {},
1612 vm_config
=> $vm_configs->{149},
1619 name
=> '111_running_pending',
1624 runningmachine
=> 'pc-q35-5.0+pve0',
1628 'with-local-disks' => 1,
1630 expected_calls
=> $default_expected_calls_online,
1632 source_volids
=> {},
1634 'local-zfs:vm-111-disk-0' => 1,
1635 'local-lvm:vm-111-disk-10' => 1,
1637 vm_config
=> get_patched_config
(111, {
1638 ide0
=> 'local-lvm:vm-111-disk-10,format=raw,size=4G',
1640 scsi0
=> 'local-zfs:vm-111-disk-0,size=103M',
1645 runningmachine
=> 'pc-q35-5.0+pve0',
1650 name
=> '123_alias_fail',
1657 'with-local-disks' => 1,
1659 expected_calls
=> {},
1660 expect_die
=> "detected not supported aliased volumes",
1662 source_volids
=> local_volids_for_vm
(123),
1663 target_volids
=> {},
1664 vm_config
=> $vm_configs->{123},
1672 my $single_test_name = shift;
1674 mkdir $RUN_DIR_PATH;
1676 foreach my $test (@{$tests}) {
1677 my $name = $test->{name
};
1678 next if defined($single_test_name) && $name ne $single_test_name;
1680 my $run_dir = "${RUN_DIR_PATH}/${name}";
1683 file_set_contents
("${run_dir}/replication_config", to_json
($replication_config));
1684 file_set_contents
("${run_dir}/storage_config", to_json
($storage_config));
1685 file_set_contents
("${run_dir}/source_vdisks", to_json
($source_vdisks));
1687 my $expect_die = $test->{expect_die
};
1688 my $expected = $test->{expected
};
1690 my $source_volids = local_volids_for_vm
($test->{vmid
});
1691 my $target_volids = $test->{target_volids
} // {};
1693 my $config_patch = $test->{config_patch
};
1694 my $vm_config = get_patched_config
($test->{vmid
}, $test->{config_patch
});
1696 my $fail_config = $test->{fail_config
} // {};
1697 my $storage_migrate_map = $test->{storage_migrate_map
} // {};
1699 if (my $targetstorage = $test->{opts
}->{targetstorage
}) {
1700 $test->{opts
}->{storagemap
} = PVE
::JSONSchema
::parse_idmap
($targetstorage, 'pve-storage-id');
1703 my $migrate_params = {
1704 target
=> $test->{target
},
1705 vmid
=> $test->{vmid
},
1706 opts
=> $test->{opts
},
1709 file_set_contents
("${run_dir}/nbd_info", to_json
({}));
1710 file_set_contents
("${run_dir}/source_volids", to_json
($source_volids));
1711 file_set_contents
("${run_dir}/target_volids", to_json
($target_volids));
1712 file_set_contents
("${run_dir}/vm_config", to_json
($vm_config));
1713 file_set_contents
("${run_dir}/vm_status", to_json
($test->{vm_status
}));
1714 file_set_contents
("${run_dir}/expected_calls", to_json
($test->{expected_calls
}));
1715 file_set_contents
("${run_dir}/fail_config", to_json
($fail_config));
1716 file_set_contents
("${run_dir}/storage_migrate_map", to_json
($storage_migrate_map));
1717 file_set_contents
("${run_dir}/migrate_params", to_json
($migrate_params));
1719 $ENV{QM_LIB_PATH
} = $QM_LIB_PATH;
1720 $ENV{RUN_DIR_PATH
} = $run_dir;
1721 my $exitcode = run_command
([
1723 "-I${MIGRATE_LIB_PATH}",
1724 "-I${MIGRATE_LIB_PATH}/test",
1725 "${MIGRATE_LIB_PATH}/test/MigrationTest/QemuMigrateMock.pm",
1726 ], noerr
=> 1, errfunc
=> sub {print "#$name - $_[0]\n"} );
1728 if (defined($expect_die) && $exitcode) {
1729 my $log = file_get_contents
("${run_dir}/log");
1730 my @lines = split /\n/, $log;
1733 foreach my $line (@lines) {
1734 $matched = 1 if $line =~ m/^err:.*\Q${expect_die}\E/;
1735 $matched = 1 if $line =~ m/^warn:.*\Q${expect_die}\E/;
1739 note
("expected error message is not present in log");
1741 } elsif (defined($expect_die) && !$exitcode) {
1743 note
("mocked migrate call didn't fail, but it was expected to - check log");
1744 } elsif (!defined($expect_die) && $exitcode) {
1746 note
("mocked migrate call failed, but it was not expected - check log");
1749 my $expected_calls = decode_json
(file_get_contents
("${run_dir}/expected_calls"));
1750 foreach my $call (keys %{$expected_calls}) {
1752 note
("expected call '$call' was not made");
1755 if (!defined($expect_die)) {
1756 my $nbd_info = decode_json
(file_get_contents
("${run_dir}/nbd_info"));
1757 foreach my $drive (keys %{$nbd_info}) {
1759 note
("drive '$drive' was not mirrored");
1764 source_volids
=> decode_json
(file_get_contents
("${run_dir}/source_volids")),
1765 target_volids
=> decode_json
(file_get_contents
("${run_dir}/target_volids")),
1766 vm_config
=> decode_json
(file_get_contents
("${run_dir}/vm_config")),
1767 vm_status
=> decode_json
(file_get_contents
("${run_dir}/vm_status")),
1770 is_deeply
($actual, $expected, $name);