auto-format code using perltidy with Proxmox style guide
using the new top-level `make tidy` target, which calls perltidy via our wrapper to enforce the desired style as closely as possible. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
@ -22,119 +22,119 @@ my $NOTES_EXT = PVE::Storage::Plugin::NOTES_EXT;
|
||||
my $tests = [
|
||||
# backup archives
|
||||
{
|
||||
description => 'Backup archive, lxc, tgz, future millenium',
|
||||
archive => "backup/vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-3070_01_01-00_00_00".$LOG_EXT,
|
||||
'notesfilename'=> "vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz".$NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 60*60*24 * (365*1100 + 267),
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
description => 'Backup archive, lxc, tgz, future millenium',
|
||||
archive => "backup/vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-3070_01_01-00_00_00" . $LOG_EXT,
|
||||
'notesfilename' => "vzdump-lxc-$vmid-3070_01_01-00_00_00.tgz" . $NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 60 * 60 * 24 * (365 * 1100 + 267),
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, lxc, tgz, very old',
|
||||
archive => "backup/vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-1970_01_01-02_00_30".$LOG_EXT,
|
||||
'notesfilename'=> "vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz".$NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 60*60*2 + 30,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
description => 'Backup archive, lxc, tgz, very old',
|
||||
archive => "backup/vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-1970_01_01-02_00_30" . $LOG_EXT,
|
||||
'notesfilename' => "vzdump-lxc-$vmid-1970_01_01-02_00_30.tgz" . $NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 60 * 60 * 2 + 30,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, lxc, tgz',
|
||||
archive => "backup/vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-2020_03_30-21_39_30".$LOG_EXT,
|
||||
'notesfilename'=> "vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz".$NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
description => 'Backup archive, lxc, tgz',
|
||||
archive => "backup/vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-lxc-$vmid-2020_03_30-21_39_30" . $LOG_EXT,
|
||||
'notesfilename' => "vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz" . $NOTES_EXT,
|
||||
'type' => 'lxc',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, openvz, tgz',
|
||||
archive => "backup/vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-openvz-$vmid-2020_03_30-21_39_30".$LOG_EXT,
|
||||
'notesfilename'=> "vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz".$NOTES_EXT,
|
||||
'type' => 'openvz',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
description => 'Backup archive, openvz, tgz',
|
||||
archive => "backup/vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-openvz-$vmid-2020_03_30-21_39_30" . $LOG_EXT,
|
||||
'notesfilename' => "vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz" . $NOTES_EXT,
|
||||
'type' => 'openvz',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, custom dump directory, qemu, tgz',
|
||||
archive => "/here/be/Back-ups/vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-qemu-$vmid-2020_03_30-21_39_30".$LOG_EXT,
|
||||
'notesfilename'=> "vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz".$NOTES_EXT,
|
||||
'type' => 'qemu',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
description => 'Backup archive, custom dump directory, qemu, tgz',
|
||||
archive => "/here/be/Back-ups/vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz",
|
||||
'logfilename' => "vzdump-qemu-$vmid-2020_03_30-21_39_30" . $LOG_EXT,
|
||||
'notesfilename' => "vzdump-qemu-$vmid-2020_03_30-21_39_30.tgz" . $NOTES_EXT,
|
||||
'type' => 'qemu',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585604370,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, none, tgz',
|
||||
archive => "backup/vzdump-qemu-$vmid-whatever-the-name_is_here.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-qemu-$vmid-whatever-the-name_is_here.tgz",
|
||||
'type' => 'qemu',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'is_std_name' => 0,
|
||||
},
|
||||
description => 'Backup archive, none, tgz',
|
||||
archive => "backup/vzdump-qemu-$vmid-whatever-the-name_is_here.tgz",
|
||||
expected => {
|
||||
'filename' => "vzdump-qemu-$vmid-whatever-the-name_is_here.tgz",
|
||||
'type' => 'qemu',
|
||||
'format' => 'tar',
|
||||
'decompressor' => ['tar', '-z'],
|
||||
'compression' => 'gz',
|
||||
'is_std_name' => 0,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
# add new compression fromats to test
|
||||
my $decompressor = {
|
||||
tar => {
|
||||
gz => ['tar', '-z'],
|
||||
lzo => ['tar', '--lzop'],
|
||||
zst => ['tar', '--zstd'],
|
||||
bz2 => ['tar', '--bzip2'],
|
||||
gz => ['tar', '-z'],
|
||||
lzo => ['tar', '--lzop'],
|
||||
zst => ['tar', '--zstd'],
|
||||
bz2 => ['tar', '--bzip2'],
|
||||
},
|
||||
vma => {
|
||||
gz => ['zcat'],
|
||||
lzo => ['lzop', '-d', '-c'],
|
||||
zst => ['zstd', '-q', '-d', '-c'],
|
||||
bz2 => ['bzcat', '-q'],
|
||||
gz => ['zcat'],
|
||||
lzo => ['lzop', '-d', '-c'],
|
||||
zst => ['zstd', '-q', '-d', '-c'],
|
||||
bz2 => ['bzcat', '-q'],
|
||||
},
|
||||
};
|
||||
|
||||
my $bkp_suffix = {
|
||||
qemu => [ 'vma', $decompressor->{vma}, ],
|
||||
lxc => [ 'tar', $decompressor->{tar}, ],
|
||||
openvz => [ 'tar', $decompressor->{tar}, ],
|
||||
qemu => ['vma', $decompressor->{vma}],
|
||||
lxc => ['tar', $decompressor->{tar}],
|
||||
openvz => ['tar', $decompressor->{tar}],
|
||||
};
|
||||
|
||||
# create more test cases for backup files matches
|
||||
@ -143,48 +143,48 @@ for my $virt (sort keys %$bkp_suffix) {
|
||||
my $archive_name = "vzdump-$virt-$vmid-2020_03_30-21_12_40";
|
||||
|
||||
for my $suffix (sort keys %$decomp) {
|
||||
push @$tests, {
|
||||
description => "Backup archive, $virt, $format.$suffix",
|
||||
archive => "backup/$archive_name.$format.$suffix",
|
||||
expected => {
|
||||
'filename' => "$archive_name.$format.$suffix",
|
||||
'logfilename' => $archive_name.$LOG_EXT,
|
||||
'notesfilename'=> "$archive_name.$format.$suffix".$NOTES_EXT,
|
||||
'type' => "$virt",
|
||||
'format' => "$format",
|
||||
'decompressor' => $decomp->{$suffix},
|
||||
'compression' => "$suffix",
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585602760,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
};
|
||||
push @$tests,
|
||||
{
|
||||
description => "Backup archive, $virt, $format.$suffix",
|
||||
archive => "backup/$archive_name.$format.$suffix",
|
||||
expected => {
|
||||
'filename' => "$archive_name.$format.$suffix",
|
||||
'logfilename' => $archive_name . $LOG_EXT,
|
||||
'notesfilename' => "$archive_name.$format.$suffix" . $NOTES_EXT,
|
||||
'type' => "$virt",
|
||||
'format' => "$format",
|
||||
'decompressor' => $decomp->{$suffix},
|
||||
'compression' => "$suffix",
|
||||
'vmid' => $vmid,
|
||||
'ctime' => 1585602760,
|
||||
'is_std_name' => 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# add compression formats to test failed matches
|
||||
my $non_bkp_suffix = {
|
||||
'openvz' => [ 'zip', 'tgz.lzo', 'zip.gz', '', ],
|
||||
'lxc' => [ 'zip', 'tgz.lzo', 'zip.gz', '', ],
|
||||
'qemu' => [ 'vma.xz', 'vms.gz', 'vmx.zst', '', ],
|
||||
'none' => [ 'tar.gz', ],
|
||||
'openvz' => ['zip', 'tgz.lzo', 'zip.gz', ''],
|
||||
'lxc' => ['zip', 'tgz.lzo', 'zip.gz', ''],
|
||||
'qemu' => ['vma.xz', 'vms.gz', 'vmx.zst', ''],
|
||||
'none' => ['tar.gz'],
|
||||
};
|
||||
|
||||
# create tests for failed matches
|
||||
for my $virt (sort keys %$non_bkp_suffix) {
|
||||
my $suffix = $non_bkp_suffix->{$virt};
|
||||
for my $s (@$suffix) {
|
||||
my $archive = "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s";
|
||||
push @$tests, {
|
||||
description => "Failed match: Backup archive, $virt, $s",
|
||||
archive => $archive,
|
||||
expected => "ERROR: couldn't determine archive info from '$archive'\n",
|
||||
};
|
||||
my $archive = "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s";
|
||||
push @$tests,
|
||||
{
|
||||
description => "Failed match: Backup archive, $virt, $s",
|
||||
archive => $archive,
|
||||
expected => "ERROR: couldn't determine archive info from '$archive'\n",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
plan tests => scalar @$tests;
|
||||
|
||||
for my $tt (@$tests) {
|
||||
|
||||
@ -23,57 +23,57 @@ sub mocked_run_command {
|
||||
|
||||
my $outputlines = [];
|
||||
if (my $ref = ref($cmd)) {
|
||||
if ($cmd->[0] =~ m/udevadm/i) {
|
||||
# simulate udevadm output
|
||||
my $dev = $cmd->[3];
|
||||
$dev =~ s|/sys/block/||;
|
||||
@$outputlines = split(/\n/, read_test_file("${dev}_udevadm"));
|
||||
if ($cmd->[0] =~ m/udevadm/i) {
|
||||
# simulate udevadm output
|
||||
my $dev = $cmd->[3];
|
||||
$dev =~ s|/sys/block/||;
|
||||
@$outputlines = split(/\n/, read_test_file("${dev}_udevadm"));
|
||||
|
||||
} elsif ($cmd->[0] =~ m/smartctl/i) {
|
||||
# simulate smartctl output
|
||||
my $dev;
|
||||
my $type;
|
||||
if (@$cmd > 3) {
|
||||
$dev = $cmd->[5];
|
||||
$type = 'smart';
|
||||
} else {
|
||||
$dev = $cmd->[2];
|
||||
$type = 'health';
|
||||
}
|
||||
$dev =~ s|/dev/||;
|
||||
@$outputlines = split(/\n/, read_test_file("${dev}_${type}"));
|
||||
} elsif ($cmd->[0] =~ m/sgdisk/i) {
|
||||
# simulate sgdisk
|
||||
die "implement me: @$cmd\n";
|
||||
} elsif ($cmd->[0] =~ m/zpool/i) {
|
||||
# simulate zpool output
|
||||
@$outputlines = split(/\n/, read_test_file('zpool'));
|
||||
} elsif ($cmd->[0] =~ m/smartctl/i) {
|
||||
# simulate smartctl output
|
||||
my $dev;
|
||||
my $type;
|
||||
if (@$cmd > 3) {
|
||||
$dev = $cmd->[5];
|
||||
$type = 'smart';
|
||||
} else {
|
||||
$dev = $cmd->[2];
|
||||
$type = 'health';
|
||||
}
|
||||
$dev =~ s|/dev/||;
|
||||
@$outputlines = split(/\n/, read_test_file("${dev}_${type}"));
|
||||
} elsif ($cmd->[0] =~ m/sgdisk/i) {
|
||||
# simulate sgdisk
|
||||
die "implement me: @$cmd\n";
|
||||
} elsif ($cmd->[0] =~ m/zpool/i) {
|
||||
# simulate zpool output
|
||||
@$outputlines = split(/\n/, read_test_file('zpool'));
|
||||
|
||||
} elsif ($cmd->[0] =~ m/pvs/i) {
|
||||
# simulate lvs output
|
||||
@$outputlines = split(/\n/, read_test_file('pvs'));
|
||||
} elsif ($cmd->[0] =~ m/lvs/i) {
|
||||
@$outputlines = split(/\n/, read_test_file('lvs'));
|
||||
} elsif ($cmd->[0] =~ m/lsblk/i) {
|
||||
my $content = read_test_file('lsblk');
|
||||
if ($content eq '') {
|
||||
$content = '{}';
|
||||
}
|
||||
@$outputlines = split(/\n/, $content);
|
||||
} else {
|
||||
die "unexpected run_command call: '@$cmd', aborting\n";
|
||||
}
|
||||
} elsif ($cmd->[0] =~ m/pvs/i) {
|
||||
# simulate lvs output
|
||||
@$outputlines = split(/\n/, read_test_file('pvs'));
|
||||
} elsif ($cmd->[0] =~ m/lvs/i) {
|
||||
@$outputlines = split(/\n/, read_test_file('lvs'));
|
||||
} elsif ($cmd->[0] =~ m/lsblk/i) {
|
||||
my $content = read_test_file('lsblk');
|
||||
if ($content eq '') {
|
||||
$content = '{}';
|
||||
}
|
||||
@$outputlines = split(/\n/, $content);
|
||||
} else {
|
||||
die "unexpected run_command call: '@$cmd', aborting\n";
|
||||
}
|
||||
} else {
|
||||
print "unexpected run_command call: '@$cmd', aborting\n";
|
||||
die;
|
||||
print "unexpected run_command call: '@$cmd', aborting\n";
|
||||
die;
|
||||
}
|
||||
|
||||
my $outfunc;
|
||||
if ($param{outfunc}) {
|
||||
$outfunc = $param{outfunc};
|
||||
map { &$outfunc(($_)) } @$outputlines;
|
||||
$outfunc = $param{outfunc};
|
||||
map { &$outfunc(($_)) } @$outputlines;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,16 +107,16 @@ sub mocked_dir_glob_foreach {
|
||||
my $lines = [];
|
||||
|
||||
# read lines in from file
|
||||
if ($dir =~ m{^/sys/block$} ) {
|
||||
@$lines = split(/\n/, read_test_file('disklist'));
|
||||
if ($dir =~ m{^/sys/block$}) {
|
||||
@$lines = split(/\n/, read_test_file('disklist'));
|
||||
} elsif ($dir =~ m{^/sys/block/([^/]+)}) {
|
||||
@$lines = split(/\n/, read_test_file('partlist'));
|
||||
@$lines = split(/\n/, read_test_file('partlist'));
|
||||
}
|
||||
|
||||
foreach my $line (@$lines) {
|
||||
if ($line =~ m/$regex/) {
|
||||
&$sub($line);
|
||||
}
|
||||
if ($line =~ m/$regex/) {
|
||||
&$sub($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +125,8 @@ sub mocked_parse_proc_mounts {
|
||||
|
||||
my $mounts = [];
|
||||
|
||||
foreach my $line(split(/\n/, $text)) {
|
||||
push @$mounts, [split(/\s+/, $line)];
|
||||
foreach my $line (split(/\n/, $text)) {
|
||||
push @$mounts, [split(/\s+/, $line)];
|
||||
}
|
||||
|
||||
return $mounts;
|
||||
@ -135,83 +135,85 @@ sub mocked_parse_proc_mounts {
|
||||
sub read_test_file {
|
||||
my ($filename) = @_;
|
||||
|
||||
if (!-f "disk_tests/$testcasedir/$filename") {
|
||||
print "file '$testcasedir/$filename' not found\n";
|
||||
return '';
|
||||
if (!-f "disk_tests/$testcasedir/$filename") {
|
||||
print "file '$testcasedir/$filename' not found\n";
|
||||
return '';
|
||||
}
|
||||
open (my $fh, '<', "disk_tests/$testcasedir/$filename")
|
||||
or die "Cannot open disk_tests/$testcasedir/$filename: $!";
|
||||
open(my $fh, '<', "disk_tests/$testcasedir/$filename")
|
||||
or die "Cannot open disk_tests/$testcasedir/$filename: $!";
|
||||
|
||||
my $output = <$fh> // '';
|
||||
chomp $output if $output;
|
||||
while (my $line = <$fh>) {
|
||||
chomp $line;
|
||||
$output .= "\n$line";
|
||||
chomp $line;
|
||||
$output .= "\n$line";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
sub test_disk_list {
|
||||
my ($testdir) = @_;
|
||||
subtest "Test '$testdir'" => sub {
|
||||
my $testcount = 0;
|
||||
$testcasedir = $testdir;
|
||||
my $testcount = 0;
|
||||
$testcasedir = $testdir;
|
||||
|
||||
my $disks;
|
||||
my $expected_disk_list;
|
||||
eval {
|
||||
$disks = PVE::Diskmanage::get_disks();
|
||||
};
|
||||
warn $@ if $@;
|
||||
$expected_disk_list = decode_json(read_test_file('disklist_expected.json'));
|
||||
my $disks;
|
||||
my $expected_disk_list;
|
||||
eval { $disks = PVE::Diskmanage::get_disks(); };
|
||||
warn $@ if $@;
|
||||
$expected_disk_list = decode_json(read_test_file('disklist_expected.json'));
|
||||
|
||||
print Dumper($disks) if $print;
|
||||
$testcount++;
|
||||
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
|
||||
print Dumper($disks) if $print;
|
||||
$testcount++;
|
||||
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
|
||||
|
||||
foreach my $disk (sort keys %$disks) {
|
||||
my $smart;
|
||||
my $expected_smart;
|
||||
eval {
|
||||
$smart = PVE::Diskmanage::get_smart_data("/dev/$disk");
|
||||
print Dumper($smart) if $print;
|
||||
$expected_smart = decode_json(read_test_file("${disk}_smart_expected.json"));
|
||||
};
|
||||
foreach my $disk (sort keys %$disks) {
|
||||
my $smart;
|
||||
my $expected_smart;
|
||||
eval {
|
||||
$smart = PVE::Diskmanage::get_smart_data("/dev/$disk");
|
||||
print Dumper($smart) if $print;
|
||||
$expected_smart = decode_json(read_test_file("${disk}_smart_expected.json"));
|
||||
};
|
||||
|
||||
if ($smart && $expected_smart) {
|
||||
$testcount++;
|
||||
is_deeply($smart, $expected_smart, "smart data for '$disk' should be the same");
|
||||
} elsif ($smart && -f "disk_tests/$testcasedir/${disk}_smart_expected.json") {
|
||||
$testcount++;
|
||||
ok(0, "could not parse expected smart for '$disk'\n");
|
||||
}
|
||||
my $disk_tmp = {};
|
||||
if ($smart && $expected_smart) {
|
||||
$testcount++;
|
||||
is_deeply($smart, $expected_smart, "smart data for '$disk' should be the same");
|
||||
} elsif ($smart && -f "disk_tests/$testcasedir/${disk}_smart_expected.json") {
|
||||
$testcount++;
|
||||
ok(0, "could not parse expected smart for '$disk'\n");
|
||||
}
|
||||
my $disk_tmp = {};
|
||||
|
||||
# test single disk parameter
|
||||
$disk_tmp = PVE::Diskmanage::get_disks($disk);
|
||||
warn $@ if $@;
|
||||
$testcount++;
|
||||
print Dumper $disk_tmp if $print;
|
||||
is_deeply($disk_tmp->{$disk}, $expected_disk_list->{$disk}, "disk $disk should be the same");
|
||||
# test single disk parameter
|
||||
$disk_tmp = PVE::Diskmanage::get_disks($disk);
|
||||
warn $@ if $@;
|
||||
$testcount++;
|
||||
print Dumper $disk_tmp if $print;
|
||||
is_deeply(
|
||||
$disk_tmp->{$disk},
|
||||
$expected_disk_list->{$disk},
|
||||
"disk $disk should be the same",
|
||||
);
|
||||
|
||||
# test wrong parameter
|
||||
eval { PVE::Diskmanage::get_disks({ test => 1 }); };
|
||||
my $err = $@;
|
||||
$testcount++;
|
||||
is_deeply(
|
||||
$err,
|
||||
"disks is not a string or array reference\n",
|
||||
"error message should be the same",
|
||||
);
|
||||
|
||||
# test wrong parameter
|
||||
eval {
|
||||
PVE::Diskmanage::get_disks( { test => 1 } );
|
||||
};
|
||||
my $err = $@;
|
||||
$testcount++;
|
||||
is_deeply($err, "disks is not a string or array reference\n", "error message should be the same");
|
||||
}
|
||||
# test multi disk parameter
|
||||
$disks = PVE::Diskmanage::get_disks([keys %$disks]);
|
||||
$testcount++;
|
||||
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
|
||||
|
||||
}
|
||||
# test multi disk parameter
|
||||
$disks = PVE::Diskmanage::get_disks( [ keys %$disks ] );
|
||||
$testcount++;
|
||||
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
|
||||
|
||||
done_testing($testcount);
|
||||
done_testing($testcount);
|
||||
};
|
||||
}
|
||||
|
||||
@ -235,24 +237,26 @@ $diskmanage_module->mock('is_iscsi' => \&mocked_is_iscsi);
|
||||
print("\tMocked is_iscsi\n");
|
||||
$diskmanage_module->mock('assert_blockdev' => sub { return 1; });
|
||||
print("\tMocked assert_blockdev\n");
|
||||
$diskmanage_module->mock('dir_is_empty' => sub {
|
||||
# all partitions have a holder dir
|
||||
my $val = shift;
|
||||
if ($val =~ m|^/sys/block/.+/.+/|) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
$diskmanage_module->mock(
|
||||
'dir_is_empty' => sub {
|
||||
# all partitions have a holder dir
|
||||
my $val = shift;
|
||||
if ($val =~ m|^/sys/block/.+/.+/|) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
);
|
||||
print("\tMocked dir_is_empty\n");
|
||||
$diskmanage_module->mock('check_bin' => sub { return 1; });
|
||||
print("\tMocked check_bin\n");
|
||||
my $tools_module= Test::MockModule->new('PVE::ProcFSTools', no_auto => 1);
|
||||
my $tools_module = Test::MockModule->new('PVE::ProcFSTools', no_auto => 1);
|
||||
$tools_module->mock('parse_proc_mounts' => \&mocked_parse_proc_mounts);
|
||||
print("\tMocked parse_proc_mounts\n");
|
||||
print("Done Setting up Mocking\n\n");
|
||||
|
||||
print("Beginning Tests:\n\n");
|
||||
opendir (my $dh, 'disk_tests')
|
||||
opendir(my $dh, 'disk_tests')
|
||||
or die "Cannot open disk_tests: $!";
|
||||
|
||||
while (readdir $dh) {
|
||||
|
||||
@ -16,54 +16,44 @@ my $path = '/some/path';
|
||||
# expected => the array of return values; or the die message
|
||||
my $tests = [
|
||||
{
|
||||
volname => '1234/vm-1234-disk-0.raw',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.raw",
|
||||
'1234',
|
||||
'images'
|
||||
],
|
||||
volname => '1234/vm-1234-disk-0.raw',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.raw", '1234', 'images',
|
||||
],
|
||||
},
|
||||
{
|
||||
volname => '1234/vm-1234-disk-0.raw',
|
||||
snapname => 'my_snap',
|
||||
expected => "can't snapshot this image format\n"
|
||||
volname => '1234/vm-1234-disk-0.raw',
|
||||
snapname => 'my_snap',
|
||||
expected => "can't snapshot this image format\n",
|
||||
},
|
||||
{
|
||||
volname => '1234/vm-1234-disk-0.qcow2',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.qcow2",
|
||||
'1234',
|
||||
'images'
|
||||
],
|
||||
volname => '1234/vm-1234-disk-0.qcow2',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.qcow2", '1234', 'images',
|
||||
],
|
||||
},
|
||||
{
|
||||
volname => '1234/vm-1234-disk-0.qcow2',
|
||||
snapname => 'my_snap',
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.qcow2",
|
||||
'1234',
|
||||
'images'
|
||||
],
|
||||
volname => '1234/vm-1234-disk-0.qcow2',
|
||||
snapname => 'my_snap',
|
||||
expected => [
|
||||
"$path/images/1234/vm-1234-disk-0.qcow2", '1234', 'images',
|
||||
],
|
||||
},
|
||||
{
|
||||
volname => 'iso/my-awesome-proxmox.iso',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/template/iso/my-awesome-proxmox.iso",
|
||||
undef,
|
||||
'iso'
|
||||
],
|
||||
volname => 'iso/my-awesome-proxmox.iso',
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/template/iso/my-awesome-proxmox.iso", undef, 'iso',
|
||||
],
|
||||
},
|
||||
{
|
||||
volname => "backup/vzdump-qemu-1234-2020_03_30-21_12_40.vma",
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/dump/vzdump-qemu-1234-2020_03_30-21_12_40.vma",
|
||||
1234,
|
||||
'backup'
|
||||
],
|
||||
volname => "backup/vzdump-qemu-1234-2020_03_30-21_12_40.vma",
|
||||
snapname => undef,
|
||||
expected => [
|
||||
"$path/dump/vzdump-qemu-1234-2020_03_30-21_12_40.vma", 1234, 'backup',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@ -76,13 +66,11 @@ foreach my $tt (@$tests) {
|
||||
my $scfg = { path => $path };
|
||||
my $got;
|
||||
|
||||
eval {
|
||||
$got = [ PVE::Storage::Plugin->filesystem_path($scfg, $volname, $snapname) ];
|
||||
};
|
||||
eval { $got = [PVE::Storage::Plugin->filesystem_path($scfg, $volname, $snapname)]; };
|
||||
$got = $@ if $@;
|
||||
|
||||
is_deeply($got, $expected, "wantarray: filesystem_path for $volname")
|
||||
|| diag(explain($got));
|
||||
|| diag(explain($got));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -17,21 +17,26 @@ my $vtype_subdirs = PVE::Storage::Plugin::get_vtype_subdirs();
|
||||
# [2] => expected return from get_subdir
|
||||
my $tests = [
|
||||
# failed matches
|
||||
[ $scfg_with_path, 'none', "unknown vtype 'none'\n" ],
|
||||
[ {}, 'iso', "storage definition has no path\n" ],
|
||||
[$scfg_with_path, 'none', "unknown vtype 'none'\n"],
|
||||
[{}, 'iso', "storage definition has no path\n"],
|
||||
];
|
||||
|
||||
# creates additional positive tests
|
||||
foreach my $type (keys %$vtype_subdirs) {
|
||||
my $path = "$scfg_with_path->{path}/$vtype_subdirs->{$type}";
|
||||
push @$tests, [ $scfg_with_path, $type, $path ];
|
||||
push @$tests, [$scfg_with_path, $type, $path];
|
||||
}
|
||||
|
||||
# creates additional tests for overrides
|
||||
foreach my $type (keys %$vtype_subdirs) {
|
||||
my $override = "${type}_override";
|
||||
my $scfg_with_override = { path => '/some/path', 'content-dirs' => { $type => $override } };
|
||||
push @$tests, [ $scfg_with_override, $type, "$scfg_with_override->{path}/$scfg_with_override->{'content-dirs'}->{$type}" ];
|
||||
push @$tests,
|
||||
[
|
||||
$scfg_with_override,
|
||||
$type,
|
||||
"$scfg_with_override->{path}/$scfg_with_override->{'content-dirs'}->{$type}",
|
||||
];
|
||||
}
|
||||
|
||||
plan tests => scalar @$tests;
|
||||
@ -43,7 +48,7 @@ foreach my $tt (@$tests) {
|
||||
eval { $got = PVE::Storage::Plugin->get_subdir($scfg, $type) };
|
||||
$got = $@ if $@;
|
||||
|
||||
is ($got, $expected, "get_subdir for $type") || diag(explain($got));
|
||||
is($got, $expected, "get_subdir for $type") || diag(explain($got));
|
||||
}
|
||||
|
||||
done_testing();
|
||||
|
||||
@ -27,52 +27,52 @@ use constant DEFAULT_CTIME => 1234567890;
|
||||
my $mocked_vmlist = {
|
||||
'version' => 1,
|
||||
'ids' => {
|
||||
'16110' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 4,
|
||||
},
|
||||
'16112' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'lxc',
|
||||
'version' => 7,
|
||||
},
|
||||
'16114' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 2,
|
||||
},
|
||||
'16113' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 5,
|
||||
},
|
||||
'16115' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 1,
|
||||
},
|
||||
'9004' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 6,
|
||||
}
|
||||
}
|
||||
'16110' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 4,
|
||||
},
|
||||
'16112' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'lxc',
|
||||
'version' => 7,
|
||||
},
|
||||
'16114' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 2,
|
||||
},
|
||||
'16113' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 5,
|
||||
},
|
||||
'16115' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 1,
|
||||
},
|
||||
'9004' => {
|
||||
'node' => 'x42',
|
||||
'type' => 'qemu',
|
||||
'version' => 6,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
my $storage_dir = File::Temp->newdir();
|
||||
my $scfg = {
|
||||
'type' => 'dir',
|
||||
'type' => 'dir',
|
||||
'maxfiles' => 0,
|
||||
'path' => $storage_dir,
|
||||
'shared' => 0,
|
||||
'content' => {
|
||||
'iso' => 1,
|
||||
'rootdir' => 1,
|
||||
'vztmpl' => 1,
|
||||
'images' => 1,
|
||||
'snippets' => 1,
|
||||
'backup' => 1,
|
||||
'path' => $storage_dir,
|
||||
'shared' => 0,
|
||||
'content' => {
|
||||
'iso' => 1,
|
||||
'rootdir' => 1,
|
||||
'vztmpl' => 1,
|
||||
'images' => 1,
|
||||
'snippets' => 1,
|
||||
'backup' => 1,
|
||||
},
|
||||
};
|
||||
|
||||
@ -84,389 +84,387 @@ my $scfg = {
|
||||
# (content, ctime, format, parent, size, used, vimd, volid)
|
||||
my @tests = (
|
||||
{
|
||||
description => 'VMID: 16110, VM, qcow2, backup, snippets',
|
||||
vmid => '16110',
|
||||
files => [
|
||||
"$storage_dir/images/16110/vm-16110-disk-0.qcow2",
|
||||
"$storage_dir/images/16110/vm-16110-disk-1.raw",
|
||||
"$storage_dir/images/16110/vm-16110-disk-2.vmdk",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst",
|
||||
"$storage_dir/snippets/userconfig.yaml",
|
||||
"$storage_dir/snippets/hookscript.pl",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'raw',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-1.raw',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'vmdk',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-2.vmdk',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602700,
|
||||
'format' => 'vma.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602765,
|
||||
'format' => 'vma.lzo',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602835,
|
||||
'format' => 'vma',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602835,
|
||||
'format' => 'vma.zst',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/hookscript.pl',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/userconfig.yaml',
|
||||
},
|
||||
],
|
||||
description => 'VMID: 16110, VM, qcow2, backup, snippets',
|
||||
vmid => '16110',
|
||||
files => [
|
||||
"$storage_dir/images/16110/vm-16110-disk-0.qcow2",
|
||||
"$storage_dir/images/16110/vm-16110-disk-1.raw",
|
||||
"$storage_dir/images/16110/vm-16110-disk-2.vmdk",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst",
|
||||
"$storage_dir/snippets/userconfig.yaml",
|
||||
"$storage_dir/snippets/hookscript.pl",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'raw',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-1.raw',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'vmdk',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:16110/vm-16110-disk-2.vmdk',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602700,
|
||||
'format' => 'vma.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602765,
|
||||
'format' => 'vma.lzo',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602835,
|
||||
'format' => 'vma',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585602835,
|
||||
'format' => 'vma.zst',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'qemu',
|
||||
'vmid' => '16110',
|
||||
'volid' => 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/hookscript.pl',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/userconfig.yaml',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: 16112, lxc, raw, backup',
|
||||
vmid => '16112',
|
||||
files => [
|
||||
"$storage_dir/images/16112/vm-16112-disk-0.raw",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_49_30.tar.gz",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_49_30.tar.zst",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_59_30.tgz",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'rootdir',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'raw',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:16112/vm-16112-disk-0.raw',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604370,
|
||||
'format' => 'tar.lzo',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604970,
|
||||
'format' => 'tar.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_49_30.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604970,
|
||||
'format' => 'tar.zst',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_49_30.tar.zst',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585605570,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_59_30.tgz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604370,
|
||||
'format' => 'tar.bz2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'openvz',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2',
|
||||
},
|
||||
],
|
||||
description => 'VMID: 16112, lxc, raw, backup',
|
||||
vmid => '16112',
|
||||
files => [
|
||||
"$storage_dir/images/16112/vm-16112-disk-0.raw",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_49_30.tar.gz",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_49_30.tar.zst",
|
||||
"$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_59_30.tgz",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'rootdir',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'raw',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:16112/vm-16112-disk-0.raw',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604370,
|
||||
'format' => 'tar.lzo',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604970,
|
||||
'format' => 'tar.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_49_30.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604970,
|
||||
'format' => 'tar.zst',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_49_30.tar.zst',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585605570,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-lxc-16112-2020_03_30-21_59_30.tgz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1585604370,
|
||||
'format' => 'tar.bz2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'openvz',
|
||||
'vmid' => '16112',
|
||||
'volid' => 'local:backup/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: 16114, VM, qcow2, linked clone',
|
||||
vmid => '16114',
|
||||
files => [
|
||||
"$storage_dir/images/16114/vm-16114-disk-0.qcow2",
|
||||
"$storage_dir/images/16114/vm-16114-disk-1.qcow2",
|
||||
],
|
||||
parent => [
|
||||
"../9004/base-9004-disk-0.qcow2",
|
||||
"../9004/base-9004-disk-1.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../9004/base-9004-disk-0.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16114',
|
||||
'volid' => 'local:9004/base-9004-disk-0.qcow2/16114/vm-16114-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../9004/base-9004-disk-1.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16114',
|
||||
'volid' => 'local:9004/base-9004-disk-1.qcow2/16114/vm-16114-disk-1.qcow2',
|
||||
},
|
||||
],
|
||||
description => 'VMID: 16114, VM, qcow2, linked clone',
|
||||
vmid => '16114',
|
||||
files => [
|
||||
"$storage_dir/images/16114/vm-16114-disk-0.qcow2",
|
||||
"$storage_dir/images/16114/vm-16114-disk-1.qcow2",
|
||||
],
|
||||
parent => [
|
||||
"../9004/base-9004-disk-0.qcow2", "../9004/base-9004-disk-1.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../9004/base-9004-disk-0.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16114',
|
||||
'volid' => 'local:9004/base-9004-disk-0.qcow2/16114/vm-16114-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../9004/base-9004-disk-1.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '16114',
|
||||
'volid' => 'local:9004/base-9004-disk-1.qcow2/16114/vm-16114-disk-1.qcow2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: 9004, VM, template, qcow2',
|
||||
vmid => '9004',
|
||||
files => [
|
||||
"$storage_dir/images/9004/base-9004-disk-0.qcow2",
|
||||
"$storage_dir/images/9004/base-9004-disk-1.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '9004',
|
||||
'volid' => 'local:9004/base-9004-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '9004',
|
||||
'volid' => 'local:9004/base-9004-disk-1.qcow2',
|
||||
},
|
||||
],
|
||||
description => 'VMID: 9004, VM, template, qcow2',
|
||||
vmid => '9004',
|
||||
files => [
|
||||
"$storage_dir/images/9004/base-9004-disk-0.qcow2",
|
||||
"$storage_dir/images/9004/base-9004-disk-1.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '9004',
|
||||
'volid' => 'local:9004/base-9004-disk-0.qcow2',
|
||||
},
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => undef,
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '9004',
|
||||
'volid' => 'local:9004/base-9004-disk-1.qcow2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: none, templates, snippets, backup',
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/dump/vzdump-lxc-19253-2020_02_03-19_57_43.tar.gz",
|
||||
"$storage_dir/dump/vzdump-lxc-19254-2019_01_21-19_29_19.tar",
|
||||
"$storage_dir/template/iso/archlinux-2020.02.01-x86_64.iso",
|
||||
"$storage_dir/template/iso/debian-8.11.1-amd64-DVD-1.iso",
|
||||
"$storage_dir/template/iso/debian-9.12.0-amd64-netinst.iso",
|
||||
"$storage_dir/template/iso/proxmox-ve_6.1-1.iso",
|
||||
"$storage_dir/template/cache/archlinux-base_20190924-1_amd64.tar.gz",
|
||||
"$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.gz",
|
||||
"$storage_dir/template/cache/debian-11.0-standard_11.0-1_amd64.tar.bz2",
|
||||
"$storage_dir/template/cache/alpine-3.10-default_20190626_amd64.tar.xz",
|
||||
"$storage_dir/snippets/userconfig.yaml",
|
||||
"$storage_dir/snippets/hookscript.pl",
|
||||
"$storage_dir/private/1234/", # fileparse needs / at the end
|
||||
"$storage_dir/private/1234/subvol-1234-disk-0.subvol/", # fileparse needs / at the end
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'txz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/alpine-3.10-default_20190626_amd64.tar.xz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/archlinux-base_20190924-1_amd64.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tbz2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/debian-11.0-standard_11.0-1_amd64.tar.bz2',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/archlinux-2020.02.01-x86_64.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/debian-8.11.1-amd64-DVD-1.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/debian-9.12.0-amd64-netinst.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/proxmox-ve_6.1-1.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1580759863,
|
||||
'format' => 'tar.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '19253',
|
||||
'volid' => 'local:backup/vzdump-lxc-19253-2020_02_03-19_57_43.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1548098959,
|
||||
'format' => 'tar',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '19254',
|
||||
'volid' => 'local:backup/vzdump-lxc-19254-2019_01_21-19_29_19.tar',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/hookscript.pl',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/userconfig.yaml',
|
||||
},
|
||||
],
|
||||
description => 'VMID: none, templates, snippets, backup',
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/dump/vzdump-lxc-19253-2020_02_03-19_57_43.tar.gz",
|
||||
"$storage_dir/dump/vzdump-lxc-19254-2019_01_21-19_29_19.tar",
|
||||
"$storage_dir/template/iso/archlinux-2020.02.01-x86_64.iso",
|
||||
"$storage_dir/template/iso/debian-8.11.1-amd64-DVD-1.iso",
|
||||
"$storage_dir/template/iso/debian-9.12.0-amd64-netinst.iso",
|
||||
"$storage_dir/template/iso/proxmox-ve_6.1-1.iso",
|
||||
"$storage_dir/template/cache/archlinux-base_20190924-1_amd64.tar.gz",
|
||||
"$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.gz",
|
||||
"$storage_dir/template/cache/debian-11.0-standard_11.0-1_amd64.tar.bz2",
|
||||
"$storage_dir/template/cache/alpine-3.10-default_20190626_amd64.tar.xz",
|
||||
"$storage_dir/snippets/userconfig.yaml",
|
||||
"$storage_dir/snippets/hookscript.pl",
|
||||
"$storage_dir/private/1234/", # fileparse needs / at the end
|
||||
"$storage_dir/private/1234/subvol-1234-disk-0.subvol/", # fileparse needs / at the end
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'txz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/alpine-3.10-default_20190626_amd64.tar.xz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/archlinux-base_20190924-1_amd64.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tgz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'vztmpl',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'tbz2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:vztmpl/debian-11.0-standard_11.0-1_amd64.tar.bz2',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/archlinux-2020.02.01-x86_64.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/debian-8.11.1-amd64-DVD-1.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/debian-9.12.0-amd64-netinst.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'iso',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'iso',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:iso/proxmox-ve_6.1-1.iso',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1580759863,
|
||||
'format' => 'tar.gz',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '19253',
|
||||
'volid' => 'local:backup/vzdump-lxc-19253-2020_02_03-19_57_43.tar.gz',
|
||||
},
|
||||
{
|
||||
'content' => 'backup',
|
||||
'ctime' => 1548098959,
|
||||
'format' => 'tar',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'subtype' => 'lxc',
|
||||
'vmid' => '19254',
|
||||
'volid' => 'local:backup/vzdump-lxc-19254-2019_01_21-19_29_19.tar',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/hookscript.pl',
|
||||
},
|
||||
{
|
||||
'content' => 'snippets',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'snippet',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'volid' => 'local:snippets/userconfig.yaml',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: none, parent, non-matching',
|
||||
# string instead of vmid in folder
|
||||
#"$storage_dir/images/ssss/base-4321-disk-0.qcow2/1234/vm-1234-disk-0.qcow2",
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/images/1234/vm-1234-disk-0.qcow2",
|
||||
],
|
||||
parent => [
|
||||
"../ssss/base-4321-disk-0.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../ssss/base-4321-disk-0.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '1234',
|
||||
'volid' => 'local:1234/vm-1234-disk-0.qcow2',
|
||||
}
|
||||
],
|
||||
description => 'VMID: none, parent, non-matching',
|
||||
# string instead of vmid in folder
|
||||
#"$storage_dir/images/ssss/base-4321-disk-0.qcow2/1234/vm-1234-disk-0.qcow2",
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/images/1234/vm-1234-disk-0.qcow2",
|
||||
],
|
||||
parent => [
|
||||
"../ssss/base-4321-disk-0.qcow2",
|
||||
],
|
||||
expected => [
|
||||
{
|
||||
'content' => 'images',
|
||||
'ctime' => DEFAULT_CTIME,
|
||||
'format' => 'qcow2',
|
||||
'parent' => '../ssss/base-4321-disk-0.qcow2',
|
||||
'size' => DEFAULT_SIZE,
|
||||
'used' => DEFAULT_USED,
|
||||
'vmid' => '1234',
|
||||
'volid' => 'local:1234/vm-1234-disk-0.qcow2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'VMID: none, non-matching',
|
||||
# failed matches
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/images/ssss/base-4321-disk-0.raw",
|
||||
"$storage_dir/images/ssss/vm-1234-disk-0.qcow2",
|
||||
"$storage_dir/template/iso/yet-again-a-installation-disk.dvd",
|
||||
"$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.zip.gz",
|
||||
"$storage_dir/private/subvol-19254-disk-0/19254",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.zip.gz",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tgz.lzo",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vma.xz",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vms.gz",
|
||||
],
|
||||
expected => [], # returns empty list
|
||||
description => 'VMID: none, non-matching',
|
||||
# failed matches
|
||||
vmid => undef,
|
||||
files => [
|
||||
"$storage_dir/images/ssss/base-4321-disk-0.raw",
|
||||
"$storage_dir/images/ssss/vm-1234-disk-0.qcow2",
|
||||
"$storage_dir/template/iso/yet-again-a-installation-disk.dvd",
|
||||
"$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.zip.gz",
|
||||
"$storage_dir/private/subvol-19254-disk-0/19254",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.zip.gz",
|
||||
"$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tgz.lzo",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vma.xz",
|
||||
"$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vms.gz",
|
||||
],
|
||||
expected => [], # returns empty list
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
# provide static vmlist for tests
|
||||
my $mock_cluster = Test::MockModule->new('PVE::Cluster', no_auto => 1);
|
||||
$mock_cluster->redefine(get_vmlist => sub { return $mocked_vmlist; });
|
||||
@ -474,26 +472,31 @@ $mock_cluster->redefine(get_vmlist => sub { return $mocked_vmlist; });
|
||||
# populate is File::stat's method to fill all information from CORE::stat into
|
||||
# an blessed array.
|
||||
my $mock_stat = Test::MockModule->new('File::stat', no_auto => 1);
|
||||
$mock_stat->redefine(populate => sub {
|
||||
my (@st) = @_;
|
||||
$st[7] = DEFAULT_SIZE;
|
||||
$st[10] = DEFAULT_CTIME;
|
||||
$mock_stat->redefine(
|
||||
populate => sub {
|
||||
my (@st) = @_;
|
||||
$st[7] = DEFAULT_SIZE;
|
||||
$st[10] = DEFAULT_CTIME;
|
||||
|
||||
my $result = $mock_stat->original('populate')->(@st);
|
||||
my $result = $mock_stat->original('populate')->(@st);
|
||||
|
||||
return $result;
|
||||
});
|
||||
return $result;
|
||||
},
|
||||
);
|
||||
|
||||
# override info provided by qemu-img in file_size_info
|
||||
my $mock_fsi = Test::MockModule->new('PVE::Storage::Plugin', no_auto => 1);
|
||||
$mock_fsi->redefine(file_size_info => sub {
|
||||
my ($size, $format, $used, $parent, $ctime) = $mock_fsi->original('file_size_info')->(@_);
|
||||
$mock_fsi->redefine(
|
||||
file_size_info => sub {
|
||||
my ($size, $format, $used, $parent, $ctime) =
|
||||
$mock_fsi->original('file_size_info')->(@_);
|
||||
|
||||
$size = DEFAULT_SIZE;
|
||||
$used = DEFAULT_USED;
|
||||
$size = DEFAULT_SIZE;
|
||||
$used = DEFAULT_USED;
|
||||
|
||||
return wantarray ? ($size, $format, $used, $parent, $ctime) : $size;
|
||||
});
|
||||
return wantarray ? ($size, $format, $used, $parent, $ctime) : $size;
|
||||
},
|
||||
);
|
||||
|
||||
my $plan = scalar @tests;
|
||||
plan tests => $plan + 1;
|
||||
@ -507,54 +510,56 @@ plan tests => $plan + 1;
|
||||
|
||||
PVE::Storage::Plugin->list_volumes('sid', $scfg_with_type, undef, ['images']);
|
||||
|
||||
is_deeply ($tested_vmlist, $original_vmlist,
|
||||
'PVE::Cluster::vmlist remains unmodified')
|
||||
|| diag ("Expected vmlist to remain\n", explain($original_vmlist),
|
||||
"but it turned to\n", explain($tested_vmlist));
|
||||
is_deeply($tested_vmlist, $original_vmlist, 'PVE::Cluster::vmlist remains unmodified')
|
||||
|| diag(
|
||||
"Expected vmlist to remain\n",
|
||||
explain($original_vmlist),
|
||||
"but it turned to\n",
|
||||
explain($tested_vmlist),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
my $sid = 'local';
|
||||
my $types = [ 'rootdir', 'images', 'vztmpl', 'iso', 'backup', 'snippets' ];
|
||||
my @suffixes = ( 'qcow2', 'raw', 'vmdk', 'vhdx' );
|
||||
my $types = ['rootdir', 'images', 'vztmpl', 'iso', 'backup', 'snippets'];
|
||||
my @suffixes = ('qcow2', 'raw', 'vmdk', 'vhdx');
|
||||
|
||||
# run through test cases
|
||||
foreach my $tt (@tests) {
|
||||
my $vmid = $tt->{vmid};
|
||||
my $files = $tt->{files};
|
||||
my $expected = $tt->{expected};
|
||||
my $description = $tt->{description};
|
||||
my $parent = $tt->{parent};
|
||||
my $vmid = $tt->{vmid};
|
||||
my $files = $tt->{files};
|
||||
my $expected = $tt->{expected};
|
||||
my $description = $tt->{description};
|
||||
my $parent = $tt->{parent};
|
||||
|
||||
# prepare environment
|
||||
my $num = 0; #parent disks
|
||||
for my $file (@$files) {
|
||||
my ($name, $dir, $suffix) = fileparse($file, @suffixes);
|
||||
# prepare environment
|
||||
my $num = 0; #parent disks
|
||||
for my $file (@$files) {
|
||||
my ($name, $dir, $suffix) = fileparse($file, @suffixes);
|
||||
|
||||
make_path($dir, { verbose => 1, mode => 0755 });
|
||||
make_path($dir, { verbose => 1, mode => 0755 });
|
||||
|
||||
if ($name) {
|
||||
# using qemu-img to also be able to represent the backing device
|
||||
my @cmd = ( '/usr/bin/qemu-img', 'create', "$file", DEFAULT_SIZE );
|
||||
push @cmd, ( '-f', $suffix ) if $suffix;
|
||||
push @cmd, ( '-u', '-b', @$parent[$num] ) if $parent;
|
||||
push @cmd, ( '-F', $suffix ) if $parent && $suffix;
|
||||
$num++;
|
||||
if ($name) {
|
||||
# using qemu-img to also be able to represent the backing device
|
||||
my @cmd = ('/usr/bin/qemu-img', 'create', "$file", DEFAULT_SIZE);
|
||||
push @cmd, ('-f', $suffix) if $suffix;
|
||||
push @cmd, ('-u', '-b', @$parent[$num]) if $parent;
|
||||
push @cmd, ('-F', $suffix) if $parent && $suffix;
|
||||
$num++;
|
||||
|
||||
run_command([@cmd]);
|
||||
}
|
||||
}
|
||||
run_command([@cmd]);
|
||||
}
|
||||
}
|
||||
|
||||
my $got;
|
||||
eval { $got = PVE::Storage::Plugin->list_volumes($sid, $scfg, $vmid, $types) };
|
||||
$got = $@ if $@;
|
||||
my $got;
|
||||
eval { $got = PVE::Storage::Plugin->list_volumes($sid, $scfg, $vmid, $types) };
|
||||
$got = $@ if $@;
|
||||
|
||||
is_deeply($got, $expected, $description) || diag(explain($got));
|
||||
is_deeply($got, $expected, $description) || diag(explain($got));
|
||||
|
||||
# clean up after each test case, otherwise
|
||||
# we get wrong results from leftover files
|
||||
remove_tree($storage_dir, { verbose => 1 });
|
||||
# clean up after each test case, otherwise
|
||||
# we get wrong results from leftover files
|
||||
remove_tree($storage_dir, { verbose => 1 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,251 +19,285 @@ my $tests = [
|
||||
# VM images
|
||||
#
|
||||
{
|
||||
description => 'VM disk image, linked, qcow2, vm- as base-',
|
||||
volname => "$vmid/vm-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2",
|
||||
expected => [ 'images', "vm-$vmid-disk-0.qcow2", "$vmid", "vm-$vmid-disk-0.qcow2", "$vmid", undef, 'qcow2', ],
|
||||
description => 'VM disk image, linked, qcow2, vm- as base-',
|
||||
volname => "$vmid/vm-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2",
|
||||
expected => [
|
||||
'images',
|
||||
"vm-$vmid-disk-0.qcow2",
|
||||
"$vmid",
|
||||
"vm-$vmid-disk-0.qcow2",
|
||||
"$vmid",
|
||||
undef,
|
||||
'qcow2',
|
||||
],
|
||||
},
|
||||
#
|
||||
# iso
|
||||
#
|
||||
{
|
||||
description => 'ISO image, iso',
|
||||
volname => 'iso/some-installation-disk.iso',
|
||||
expected => ['iso', 'some-installation-disk.iso', undef, undef, undef, undef, 'raw'],
|
||||
description => 'ISO image, iso',
|
||||
volname => 'iso/some-installation-disk.iso',
|
||||
expected => ['iso', 'some-installation-disk.iso', undef, undef, undef, undef, 'raw'],
|
||||
},
|
||||
{
|
||||
description => 'ISO image, img',
|
||||
volname => 'iso/some-other-installation-disk.img',
|
||||
expected => ['iso', 'some-other-installation-disk.img', undef, undef, undef, undef, 'raw'],
|
||||
description => 'ISO image, img',
|
||||
volname => 'iso/some-other-installation-disk.img',
|
||||
expected =>
|
||||
['iso', 'some-other-installation-disk.img', undef, undef, undef, undef, 'raw'],
|
||||
},
|
||||
#
|
||||
# container templates
|
||||
#
|
||||
{
|
||||
description => 'Container template tar.gz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
expected => ['vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar.gz', undef, undef, undef, undef, 'raw'],
|
||||
description => 'Container template tar.gz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Container template tar.xz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.xz',
|
||||
expected => ['vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar.xz', undef, undef, undef, undef, 'raw'],
|
||||
description => 'Container template tar.xz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.xz',
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'debian-10.0-standard_10.0-1_amd64.tar.xz',
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Container template tar.bz2',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2',
|
||||
expected => ['vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar.bz2', undef, undef, undef, undef, 'raw'],
|
||||
description => 'Container template tar.bz2',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2',
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'debian-10.0-standard_10.0-1_amd64.tar.bz2',
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
#
|
||||
# container rootdir
|
||||
#
|
||||
{
|
||||
description => 'Container rootdir, sub directory',
|
||||
volname => "rootdir/$vmid",
|
||||
expected => ['rootdir', "$vmid", "$vmid"],
|
||||
description => 'Container rootdir, sub directory',
|
||||
volname => "rootdir/$vmid",
|
||||
expected => ['rootdir', "$vmid", "$vmid"],
|
||||
},
|
||||
{
|
||||
description => 'Container rootdir, subvol',
|
||||
volname => "$vmid/subvol-$vmid-disk-0.subvol",
|
||||
expected => [ 'images', "subvol-$vmid-disk-0.subvol", "$vmid", undef, undef, undef, 'subvol' ],
|
||||
description => 'Container rootdir, subvol',
|
||||
volname => "$vmid/subvol-$vmid-disk-0.subvol",
|
||||
expected =>
|
||||
['images', "subvol-$vmid-disk-0.subvol", "$vmid", undef, undef, undef, 'subvol'],
|
||||
},
|
||||
{
|
||||
description => 'Backup archive, no virtualization type',
|
||||
volname => "backup/vzdump-none-$vmid-2020_03_30-21_39_30.tar",
|
||||
expected => ['backup', "vzdump-none-$vmid-2020_03_30-21_39_30.tar", undef, undef, undef, undef, 'raw'],
|
||||
description => 'Backup archive, no virtualization type',
|
||||
volname => "backup/vzdump-none-$vmid-2020_03_30-21_39_30.tar",
|
||||
expected => [
|
||||
'backup',
|
||||
"vzdump-none-$vmid-2020_03_30-21_39_30.tar",
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
#
|
||||
# Snippets
|
||||
#
|
||||
{
|
||||
description => 'Snippets, yaml',
|
||||
volname => 'snippets/userconfig.yaml',
|
||||
expected => ['snippets', 'userconfig.yaml', undef, undef, undef, undef, 'raw'],
|
||||
description => 'Snippets, yaml',
|
||||
volname => 'snippets/userconfig.yaml',
|
||||
expected => ['snippets', 'userconfig.yaml', undef, undef, undef, undef, 'raw'],
|
||||
},
|
||||
{
|
||||
description => 'Snippets, perl',
|
||||
volname => 'snippets/hookscript.pl',
|
||||
expected => ['snippets', 'hookscript.pl', undef, undef, undef, undef, 'raw'],
|
||||
description => 'Snippets, perl',
|
||||
volname => 'snippets/hookscript.pl',
|
||||
expected => ['snippets', 'hookscript.pl', undef, undef, undef, undef, 'raw'],
|
||||
},
|
||||
#
|
||||
# Import
|
||||
#
|
||||
{
|
||||
description => "Import, ova",
|
||||
volname => 'import/import.ova',
|
||||
expected => ['import', 'import.ova', undef, undef, undef ,undef, 'ova'],
|
||||
description => "Import, ova",
|
||||
volname => 'import/import.ova',
|
||||
expected => ['import', 'import.ova', undef, undef, undef, undef, 'ova'],
|
||||
},
|
||||
{
|
||||
description => "Import, ovf",
|
||||
volname => 'import/import.ovf',
|
||||
expected => ['import', 'import.ovf', undef, undef, undef ,undef, 'ovf'],
|
||||
description => "Import, ovf",
|
||||
volname => 'import/import.ovf',
|
||||
expected => ['import', 'import.ovf', undef, undef, undef, undef, 'ovf'],
|
||||
},
|
||||
{
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.qcow2',
|
||||
expected => ['import', 'import.ova/disk.qcow2', undef, undef, undef, undef, 'ova+qcow2'],
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.qcow2',
|
||||
expected =>
|
||||
['import', 'import.ova/disk.qcow2', undef, undef, undef, undef, 'ova+qcow2'],
|
||||
},
|
||||
{
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.vmdk',
|
||||
expected => ['import', 'import.ova/disk.vmdk', undef, undef, undef, undef, 'ova+vmdk'],
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.vmdk',
|
||||
expected => ['import', 'import.ova/disk.vmdk', undef, undef, undef, undef, 'ova+vmdk'],
|
||||
},
|
||||
{
|
||||
description => "Import, innner file of ova with whitespace in name",
|
||||
volname => 'import/import.ova/OS disk.vmdk',
|
||||
expected => ['import', 'import.ova/OS disk.vmdk', undef, undef, undef, undef, 'ova+vmdk'],
|
||||
description => "Import, innner file of ova with whitespace in name",
|
||||
volname => 'import/import.ova/OS disk.vmdk',
|
||||
expected =>
|
||||
['import', 'import.ova/OS disk.vmdk', undef, undef, undef, undef, 'ova+vmdk'],
|
||||
},
|
||||
{
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.raw',
|
||||
expected => ['import', 'import.ova/disk.raw', undef, undef, undef, undef, 'ova+raw'],
|
||||
description => "Import, innner file of ova",
|
||||
volname => 'import/import.ova/disk.raw',
|
||||
expected => ['import', 'import.ova/disk.raw', undef, undef, undef, undef, 'ova+raw'],
|
||||
},
|
||||
#
|
||||
# failed matches
|
||||
#
|
||||
{
|
||||
description => "Failed match: VM disk image, base, raw",
|
||||
volname => "ssss/base-$vmid-disk-0.raw",
|
||||
expected => "unable to parse directory volume name 'ssss/base-$vmid-disk-0.raw'\n",
|
||||
description => "Failed match: VM disk image, base, raw",
|
||||
volname => "ssss/base-$vmid-disk-0.raw",
|
||||
expected => "unable to parse directory volume name 'ssss/base-$vmid-disk-0.raw'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: ISO image, dvd',
|
||||
volname => 'iso/yet-again-a-installation-disk.dvd',
|
||||
expected => "unable to parse directory volume name 'iso/yet-again-a-installation-disk.dvd'\n",
|
||||
description => 'Failed match: ISO image, dvd',
|
||||
volname => 'iso/yet-again-a-installation-disk.dvd',
|
||||
expected =>
|
||||
"unable to parse directory volume name 'iso/yet-again-a-installation-disk.dvd'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: Container template, zip.gz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz',
|
||||
expected => "unable to parse directory volume name 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz'\n",
|
||||
description => 'Failed match: Container template, zip.gz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz',
|
||||
expected =>
|
||||
"unable to parse directory volume name 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: Container rootdir, subvol',
|
||||
volname => "rootdir/subvol-$vmid-disk-0",
|
||||
expected => "unable to parse directory volume name 'rootdir/subvol-$vmid-disk-0'\n",
|
||||
description => 'Failed match: Container rootdir, subvol',
|
||||
volname => "rootdir/subvol-$vmid-disk-0",
|
||||
expected => "unable to parse directory volume name 'rootdir/subvol-$vmid-disk-0'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: VM disk image, linked, vhdx',
|
||||
volname => "$vmid/base-$vmid-disk-0.vhdx/$vmid/vm-$vmid-disk-0.vhdx",
|
||||
expected => "unable to parse volume filename 'base-$vmid-disk-0.vhdx'\n",
|
||||
description => 'Failed match: VM disk image, linked, vhdx',
|
||||
volname => "$vmid/base-$vmid-disk-0.vhdx/$vmid/vm-$vmid-disk-0.vhdx",
|
||||
expected => "unable to parse volume filename 'base-$vmid-disk-0.vhdx'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: VM disk image, linked, qcow2, first vmid',
|
||||
volname => "ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2",
|
||||
expected => "unable to parse directory volume name 'ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2'\n",
|
||||
description => 'Failed match: VM disk image, linked, qcow2, first vmid',
|
||||
volname => "ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2",
|
||||
expected =>
|
||||
"unable to parse directory volume name 'ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2'\n",
|
||||
},
|
||||
{
|
||||
description => 'Failed match: VM disk image, linked, qcow2, second vmid',
|
||||
volname => "$vmid/base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2",
|
||||
expected => "unable to parse volume filename 'base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2'\n",
|
||||
description => 'Failed match: VM disk image, linked, qcow2, second vmid',
|
||||
volname => "$vmid/base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2",
|
||||
expected =>
|
||||
"unable to parse volume filename 'base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2'\n",
|
||||
},
|
||||
{
|
||||
description => "Failed match: import dir but no ova/ovf/disk image",
|
||||
volname => "import/test.foo",
|
||||
expected => "unable to parse directory volume name 'import/test.foo'\n",
|
||||
description => "Failed match: import dir but no ova/ovf/disk image",
|
||||
volname => "import/test.foo",
|
||||
expected => "unable to parse directory volume name 'import/test.foo'\n",
|
||||
},
|
||||
];
|
||||
|
||||
# create more test cases for VM disk images matches
|
||||
my $disk_suffix = [ 'raw', 'qcow2', 'vmdk' ];
|
||||
my $disk_suffix = ['raw', 'qcow2', 'vmdk'];
|
||||
foreach my $s (@$disk_suffix) {
|
||||
my @arr = (
|
||||
{
|
||||
description => "VM disk image, $s",
|
||||
volname => "$vmid/vm-$vmid-disk-1.$s",
|
||||
expected => [
|
||||
'images',
|
||||
"vm-$vmid-disk-1.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
"$s",
|
||||
],
|
||||
},
|
||||
{
|
||||
description => "VM disk image, linked, $s",
|
||||
volname => "$vmid/base-$vmid-disk-0.$s/$vmid/vm-$vmid-disk-0.$s",
|
||||
expected => [
|
||||
'images',
|
||||
"vm-$vmid-disk-0.$s",
|
||||
"$vmid",
|
||||
"base-$vmid-disk-0.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
"$s",
|
||||
],
|
||||
},
|
||||
{
|
||||
description => "VM disk image, base, $s",
|
||||
volname => "$vmid/base-$vmid-disk-0.$s",
|
||||
expected => [
|
||||
'images',
|
||||
"base-$vmid-disk-0.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
undef,
|
||||
'base-',
|
||||
"$s"
|
||||
],
|
||||
},
|
||||
{
|
||||
description => "VM disk image, $s",
|
||||
volname => "$vmid/vm-$vmid-disk-1.$s",
|
||||
expected => [
|
||||
'images', "vm-$vmid-disk-1.$s", "$vmid", undef, undef, undef, "$s",
|
||||
],
|
||||
},
|
||||
{
|
||||
description => "VM disk image, linked, $s",
|
||||
volname => "$vmid/base-$vmid-disk-0.$s/$vmid/vm-$vmid-disk-0.$s",
|
||||
expected => [
|
||||
'images',
|
||||
"vm-$vmid-disk-0.$s",
|
||||
"$vmid",
|
||||
"base-$vmid-disk-0.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
"$s",
|
||||
],
|
||||
},
|
||||
{
|
||||
description => "VM disk image, base, $s",
|
||||
volname => "$vmid/base-$vmid-disk-0.$s",
|
||||
expected => [
|
||||
'images', "base-$vmid-disk-0.$s", "$vmid", undef, undef, 'base-', "$s",
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
push @$tests, @arr;
|
||||
}
|
||||
|
||||
|
||||
# create more test cases for backup files matches
|
||||
my $bkp_suffix = {
|
||||
qemu => [ 'vma', 'vma.gz', 'vma.lzo', 'vma.zst' ],
|
||||
lxc => [ 'tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst', 'tar.bz2' ],
|
||||
openvz => [ 'tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst' ],
|
||||
qemu => ['vma', 'vma.gz', 'vma.lzo', 'vma.zst'],
|
||||
lxc => ['tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst', 'tar.bz2'],
|
||||
openvz => ['tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst'],
|
||||
};
|
||||
|
||||
foreach my $virt (keys %$bkp_suffix) {
|
||||
my $suffix = $bkp_suffix->{$virt};
|
||||
foreach my $s (@$suffix) {
|
||||
my @arr = (
|
||||
{
|
||||
description => "Backup archive, $virt, $s",
|
||||
volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
expected => [
|
||||
'backup',
|
||||
"vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw'
|
||||
],
|
||||
},
|
||||
);
|
||||
my @arr = (
|
||||
{
|
||||
description => "Backup archive, $virt, $s",
|
||||
volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
expected => [
|
||||
'backup',
|
||||
"vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
"$vmid",
|
||||
undef,
|
||||
undef,
|
||||
undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
push @$tests, @arr;
|
||||
push @$tests, @arr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# create more test cases for failed backup files matches
|
||||
my $non_bkp_suffix = {
|
||||
qemu => [ 'vms.gz', 'vma.xz' ],
|
||||
lxc => [ 'zip.gz', 'tgz.lzo' ],
|
||||
qemu => ['vms.gz', 'vma.xz'],
|
||||
lxc => ['zip.gz', 'tgz.lzo'],
|
||||
};
|
||||
foreach my $virt (keys %$non_bkp_suffix) {
|
||||
my $suffix = $non_bkp_suffix->{$virt};
|
||||
foreach my $s (@$suffix) {
|
||||
my @arr = (
|
||||
{
|
||||
description => "Failed match: Backup archive, $virt, $s",
|
||||
volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
expected => "unable to parse directory volume name 'backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s'\n",
|
||||
},
|
||||
);
|
||||
my @arr = (
|
||||
{
|
||||
description => "Failed match: Backup archive, $virt, $s",
|
||||
volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s",
|
||||
expected =>
|
||||
"unable to parse directory volume name 'backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s'\n",
|
||||
},
|
||||
);
|
||||
|
||||
push @$tests, @arr;
|
||||
push @$tests, @arr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# run through test case array
|
||||
#
|
||||
@ -278,12 +312,12 @@ foreach my $t (@$tests) {
|
||||
my $expected = $t->{expected};
|
||||
|
||||
my $got;
|
||||
eval { $got = [ PVE::Storage::Plugin->parse_volname($volname) ] };
|
||||
eval { $got = [PVE::Storage::Plugin->parse_volname($volname)] };
|
||||
$got = $@ if $@;
|
||||
|
||||
is_deeply($got, $expected, $description);
|
||||
|
||||
$seen_vtype->{@$expected[0]} = 1 if ref $expected eq 'ARRAY';
|
||||
$seen_vtype->{ @$expected[0] } = 1 if ref $expected eq 'ARRAY';
|
||||
}
|
||||
|
||||
# to check if all $vtype_subdirs are defined in path_to_volume_id
|
||||
|
||||
@ -17,24 +17,24 @@ use File::Temp;
|
||||
my $storage_dir = File::Temp->newdir();
|
||||
my $scfg = {
|
||||
'digest' => 'd29306346b8b25b90a4a96165f1e8f52d1af1eda',
|
||||
'ids' => {
|
||||
'local' => {
|
||||
'shared' => 0,
|
||||
'path' => "$storage_dir",
|
||||
'type' => 'dir',
|
||||
'maxfiles' => 0,
|
||||
'content' => {
|
||||
'snippets' => 1,
|
||||
'rootdir' => 1,
|
||||
'images' => 1,
|
||||
'iso' => 1,
|
||||
'backup' => 1,
|
||||
'vztmpl' => 1,
|
||||
},
|
||||
},
|
||||
'ids' => {
|
||||
'local' => {
|
||||
'shared' => 0,
|
||||
'path' => "$storage_dir",
|
||||
'type' => 'dir',
|
||||
'maxfiles' => 0,
|
||||
'content' => {
|
||||
'snippets' => 1,
|
||||
'rootdir' => 1,
|
||||
'images' => 1,
|
||||
'iso' => 1,
|
||||
'backup' => 1,
|
||||
'vztmpl' => 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
'order' => {
|
||||
'local' => 1,
|
||||
'local' => 1,
|
||||
},
|
||||
};
|
||||
|
||||
@ -44,219 +44,199 @@ my $scfg = {
|
||||
# expected => the result that path_to_volume_id should return
|
||||
my @tests = (
|
||||
{
|
||||
description => 'Image, qcow2',
|
||||
volname => "$storage_dir/images/16110/vm-16110-disk-0.qcow2",
|
||||
expected => [
|
||||
'images',
|
||||
'local:16110/vm-16110-disk-0.qcow2',
|
||||
],
|
||||
description => 'Image, qcow2',
|
||||
volname => "$storage_dir/images/16110/vm-16110-disk-0.qcow2",
|
||||
expected => [
|
||||
'images', 'local:16110/vm-16110-disk-0.qcow2',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Image, raw',
|
||||
volname => "$storage_dir/images/16112/vm-16112-disk-0.raw",
|
||||
expected => [
|
||||
'images',
|
||||
'local:16112/vm-16112-disk-0.raw',
|
||||
],
|
||||
description => 'Image, raw',
|
||||
volname => "$storage_dir/images/16112/vm-16112-disk-0.raw",
|
||||
expected => [
|
||||
'images', 'local:16112/vm-16112-disk-0.raw',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Image template, qcow2',
|
||||
volname => "$storage_dir/images/9004/base-9004-disk-0.qcow2",
|
||||
expected => [
|
||||
'images',
|
||||
'local:9004/base-9004-disk-0.qcow2',
|
||||
],
|
||||
description => 'Image template, qcow2',
|
||||
volname => "$storage_dir/images/9004/base-9004-disk-0.qcow2",
|
||||
expected => [
|
||||
'images', 'local:9004/base-9004-disk-0.qcow2',
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
description => 'Backup, vma.gz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz',
|
||||
],
|
||||
description => 'Backup, vma.gz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-qemu-16110-2020_03_30-21_11_40.vma.gz',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, vma.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo',
|
||||
],
|
||||
description => 'Backup, vma.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-qemu-16110-2020_03_30-21_12_45.vma.lzo',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, vma',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma',
|
||||
],
|
||||
description => 'Backup, vma',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, tar.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo',
|
||||
],
|
||||
description => 'Backup, tar.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.lzo',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, vma.zst',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst'
|
||||
],
|
||||
description => 'Backup, vma.zst',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-qemu-16110-2020_03_30-21_13_55.vma.zst',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, tar.zst',
|
||||
volname => "$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.zst",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.zst'
|
||||
],
|
||||
description => 'Backup, tar.zst',
|
||||
volname => "$storage_dir/dump/vzdump-lxc-16112-2020_03_30-21_39_30.tar.zst",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-lxc-16112-2020_03_30-21_39_30.tar.zst',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Backup, tar.bz2',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2",
|
||||
expected => [
|
||||
'backup',
|
||||
'local:backup/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2',
|
||||
],
|
||||
description => 'Backup, tar.bz2',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2",
|
||||
expected => [
|
||||
'backup', 'local:backup/vzdump-openvz-16112-2020_03_30-21_39_30.tar.bz2',
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
description => 'ISO file',
|
||||
volname => "$storage_dir/template/iso/yet-again-a-installation-disk.iso",
|
||||
expected => [
|
||||
'iso',
|
||||
'local:iso/yet-again-a-installation-disk.iso',
|
||||
],
|
||||
description => 'ISO file',
|
||||
volname => "$storage_dir/template/iso/yet-again-a-installation-disk.iso",
|
||||
expected => [
|
||||
'iso', 'local:iso/yet-again-a-installation-disk.iso',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'CT template, tar.gz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.gz",
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
],
|
||||
description => 'CT template, tar.gz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.gz",
|
||||
expected => [
|
||||
'vztmpl', 'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'CT template, wrong ending, tar bz2',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.bz2",
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2',
|
||||
],
|
||||
description => 'CT template, wrong ending, tar bz2',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.bz2",
|
||||
expected => [
|
||||
'vztmpl', 'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2',
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
description => 'Rootdir',
|
||||
volname => "$storage_dir/private/1234/", # fileparse needs / at the end
|
||||
expected => [
|
||||
'rootdir',
|
||||
'local:rootdir/1234',
|
||||
],
|
||||
description => 'Rootdir',
|
||||
volname => "$storage_dir/private/1234/", # fileparse needs / at the end
|
||||
expected => [
|
||||
'rootdir', 'local:rootdir/1234',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Rootdir, folder subvol',
|
||||
volname => "$storage_dir/images/1234/subvol-1234-disk-0.subvol/", # fileparse needs / at the end
|
||||
expected => [
|
||||
'images',
|
||||
'local:1234/subvol-1234-disk-0.subvol'
|
||||
],
|
||||
description => 'Rootdir, folder subvol',
|
||||
volname => "$storage_dir/images/1234/subvol-1234-disk-0.subvol/", # fileparse needs / at the end
|
||||
expected => [
|
||||
'images', 'local:1234/subvol-1234-disk-0.subvol',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Snippets, yaml',
|
||||
volname => "$storage_dir/snippets/userconfig.yaml",
|
||||
expected => [
|
||||
'snippets',
|
||||
'local:snippets/userconfig.yaml',
|
||||
],
|
||||
description => 'Snippets, yaml',
|
||||
volname => "$storage_dir/snippets/userconfig.yaml",
|
||||
expected => [
|
||||
'snippets', 'local:snippets/userconfig.yaml',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Snippets, hookscript',
|
||||
volname => "$storage_dir/snippets/hookscript.pl",
|
||||
expected => [
|
||||
'snippets',
|
||||
'local:snippets/hookscript.pl',
|
||||
],
|
||||
description => 'Snippets, hookscript',
|
||||
volname => "$storage_dir/snippets/hookscript.pl",
|
||||
expected => [
|
||||
'snippets', 'local:snippets/hookscript.pl',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'CT template, tar.xz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.xz",
|
||||
expected => [
|
||||
'vztmpl',
|
||||
'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.xz',
|
||||
],
|
||||
description => 'CT template, tar.xz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.tar.xz",
|
||||
expected => [
|
||||
'vztmpl', 'local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.xz',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Import, ova',
|
||||
volname => "$storage_dir/import/import.ova",
|
||||
expected => [
|
||||
'import',
|
||||
'local:import/import.ova',
|
||||
],
|
||||
description => 'Import, ova',
|
||||
volname => "$storage_dir/import/import.ova",
|
||||
expected => [
|
||||
'import', 'local:import/import.ova',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Import, ovf',
|
||||
volname => "$storage_dir/import/import.ovf",
|
||||
expected => [
|
||||
'import',
|
||||
'local:import/import.ovf',
|
||||
],
|
||||
description => 'Import, ovf',
|
||||
volname => "$storage_dir/import/import.ovf",
|
||||
expected => [
|
||||
'import', 'local:import/import.ovf',
|
||||
],
|
||||
},
|
||||
|
||||
# no matches, path or files with failures
|
||||
{
|
||||
description => 'Base template, string as vmid in folder name',
|
||||
volname => "$storage_dir/images/ssss/base-4321-disk-0.raw",
|
||||
expected => [''],
|
||||
description => 'Base template, string as vmid in folder name',
|
||||
volname => "$storage_dir/images/ssss/base-4321-disk-0.raw",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'ISO file, wrong ending',
|
||||
volname => "$storage_dir/template/iso/yet-again-a-installation-disk.dvd",
|
||||
expected => [''],
|
||||
description => 'ISO file, wrong ending',
|
||||
volname => "$storage_dir/template/iso/yet-again-a-installation-disk.dvd",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'CT template, wrong ending, zip.gz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.zip.gz",
|
||||
expected => [''],
|
||||
description => 'CT template, wrong ending, zip.gz',
|
||||
volname => "$storage_dir/template/cache/debian-10.0-standard_10.0-1_amd64.zip.gz",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Rootdir as subvol, wrong path',
|
||||
volname => "$storage_dir/private/subvol-19254-disk-0/",
|
||||
expected => [''],
|
||||
description => 'Rootdir as subvol, wrong path',
|
||||
volname => "$storage_dir/private/subvol-19254-disk-0/",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Backup, wrong format, openvz, zip.gz',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.zip.gz",
|
||||
expected => [''],
|
||||
description => 'Backup, wrong format, openvz, zip.gz',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.zip.gz",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Backup, wrong format, openvz, tgz.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tgz.lzo",
|
||||
expected => [''],
|
||||
description => 'Backup, wrong format, openvz, tgz.lzo',
|
||||
volname => "$storage_dir/dump/vzdump-openvz-16112-2020_03_30-21_39_30.tgz.lzo",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Backup, wrong ending, qemu, vma.xz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vma.xz",
|
||||
expected => [''],
|
||||
description => 'Backup, wrong ending, qemu, vma.xz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vma.xz",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Backup, wrong format, qemu, vms.gz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vms.gz",
|
||||
expected => [''],
|
||||
description => 'Backup, wrong format, qemu, vms.gz',
|
||||
volname => "$storage_dir/dump/vzdump-qemu-16110-2020_03_30-21_12_40.vms.gz",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Image, string as vmid in folder name',
|
||||
volname => "$storage_dir/images/ssss/vm-1234-disk-0.qcow2",
|
||||
expected => [''],
|
||||
description => 'Image, string as vmid in folder name',
|
||||
volname => "$storage_dir/images/ssss/vm-1234-disk-0.qcow2",
|
||||
expected => [''],
|
||||
},
|
||||
{
|
||||
description => 'Import, non ova/ovf/disk image in import dir',
|
||||
volname => "$storage_dir/import/test.foo",
|
||||
expected => [''],
|
||||
description => 'Import, non ova/ovf/disk image in import dir',
|
||||
volname => "$storage_dir/import/test.foo",
|
||||
expected => [''],
|
||||
},
|
||||
);
|
||||
|
||||
@ -275,19 +255,19 @@ foreach my $tt (@tests) {
|
||||
make_path($dir, { verbose => 1, mode => 0755 });
|
||||
|
||||
if ($name) {
|
||||
open(my $fh, ">>", "$file") || die "Error open file: $!";
|
||||
close($fh);
|
||||
open(my $fh, ">>", "$file") || die "Error open file: $!";
|
||||
close($fh);
|
||||
}
|
||||
|
||||
# run tests
|
||||
my $got;
|
||||
eval { $got = [ PVE::Storage::path_to_volume_id($scfg, $file) ] };
|
||||
eval { $got = [PVE::Storage::path_to_volume_id($scfg, $file)] };
|
||||
$got = $@ if $@;
|
||||
|
||||
is_deeply($got, $expected, $description) || diag(explain($got));
|
||||
|
||||
$seen_vtype->{@$expected[0]} = 1
|
||||
if ( @$expected[0] ne '' && scalar @$expected > 1);
|
||||
$seen_vtype->{ @$expected[0] } = 1
|
||||
if (@$expected[0] ne '' && scalar @$expected > 1);
|
||||
}
|
||||
|
||||
# to check if all $vtype_subdirs are defined in path_to_volume_id
|
||||
|
||||
@ -18,183 +18,193 @@ my $mocked_backups_lists = {};
|
||||
my $basetime = 1577881101; # 2020_01_01-12_18_21 UTC
|
||||
|
||||
foreach my $vmid (@vmids) {
|
||||
push @{$mocked_backups_lists->{default}}, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 585*24*60*60 - 60*60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24*60*60 - 60*60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_51.tar.zst",
|
||||
'ctime' => $basetime - 24*60*60 - 60*60 + 30,
|
||||
'vmid' => $vmid,
|
||||
'protected' => 1,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
|
||||
'ctime' => $basetime - 24*60*60 - 60*60 + 60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 60*60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
|
||||
'ctime' => 1234,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
);
|
||||
push @{ $mocked_backups_lists->{default} },
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 585 * 24 * 60 * 60 - 60 * 60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_51.tar.zst",
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60 + 30,
|
||||
'vmid' => $vmid,
|
||||
'protected' => 1,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60 + 60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
|
||||
'ctime' => $basetime - 60 * 60,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
|
||||
'ctime' => 1234,
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
);
|
||||
}
|
||||
push @{$mocked_backups_lists->{year1970}}, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
|
||||
'ctime' => 83,
|
||||
'vmid' => 321,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
|
||||
'ctime' => 60*60*24 * (365*100 + 25) + 60,
|
||||
'vmid' => 321,
|
||||
},
|
||||
);
|
||||
push @{$mocked_backups_lists->{novmid}}, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
|
||||
'ctime' => 1234,
|
||||
},
|
||||
);
|
||||
push @{$mocked_backups_lists->{threeway}}, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 7*24*60*60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24*60*60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
);
|
||||
push @{$mocked_backups_lists->{weekboundary}}, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+2)*24*60*60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+3)*24*60*60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+6)*24*60*60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
);
|
||||
push @{ $mocked_backups_lists->{year1970} },
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
|
||||
'ctime' => 83,
|
||||
'vmid' => 321,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
|
||||
'ctime' => 60 * 60 * 24 * (365 * 100 + 25) + 60,
|
||||
'vmid' => 321,
|
||||
},
|
||||
);
|
||||
push @{ $mocked_backups_lists->{novmid} },
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
|
||||
'ctime' => 1234,
|
||||
},
|
||||
);
|
||||
push @{ $mocked_backups_lists->{threeway} },
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 7 * 24 * 60 * 60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24 * 60 * 60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
);
|
||||
push @{ $mocked_backups_lists->{weekboundary} },
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 2) * 24 * 60 * 60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 3) * 24 * 60 * 60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 6) * 24 * 60 * 60,
|
||||
'vmid' => 7654,
|
||||
},
|
||||
);
|
||||
my $current_list;
|
||||
my $mock_plugin = Test::MockModule->new('PVE::Storage::Plugin');
|
||||
$mock_plugin->redefine(list_volumes => sub {
|
||||
my ($class, $storeid, $scfg, $vmid, $content_types) = @_;
|
||||
$mock_plugin->redefine(
|
||||
list_volumes => sub {
|
||||
my ($class, $storeid, $scfg, $vmid, $content_types) = @_;
|
||||
|
||||
my $list = $mocked_backups_lists->{$current_list};
|
||||
my $list = $mocked_backups_lists->{$current_list};
|
||||
|
||||
return $list if !defined($vmid);
|
||||
return $list if !defined($vmid);
|
||||
|
||||
return [ grep { $_->{vmid} eq $vmid } @{$list} ];
|
||||
});
|
||||
return [grep { $_->{vmid} eq $vmid } @{$list}];
|
||||
},
|
||||
);
|
||||
|
||||
sub generate_expected {
|
||||
my ($vmids, $type, $marks) = @_;
|
||||
|
||||
my @expected;
|
||||
foreach my $vmid (@{$vmids}) {
|
||||
push @expected, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 585*24*60*60 - 60*60,
|
||||
'mark' => $marks->[0],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24*60*60 - 60*60,
|
||||
'mark' => $marks->[1],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_51.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24*60*60 - 60*60 + 30,
|
||||
'mark' => 'protected',
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24*60*60 - 60*60 + 60,
|
||||
'mark' => $marks->[2],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 60*60,
|
||||
'mark' => $marks->[3],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime,
|
||||
'mark' => $marks->[4],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type) || $type eq 'qemu';
|
||||
push @expected, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'type' => 'lxc',
|
||||
'ctime' => $basetime,
|
||||
'mark' => $marks->[5],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type) || $type eq 'lxc';
|
||||
push @expected, (
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
|
||||
'type' => 'unknown',
|
||||
'ctime' => 1234,
|
||||
'mark' => 'renamed',
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type);
|
||||
push @expected,
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 585 * 24 * 60 * 60 - 60 * 60,
|
||||
'mark' => $marks->[0],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60,
|
||||
'mark' => $marks->[1],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_51.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60 + 30,
|
||||
'mark' => 'protected',
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 24 * 60 * 60 - 60 * 60 + 60,
|
||||
'mark' => $marks->[2],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime - 60 * 60,
|
||||
'mark' => $marks->[3],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'type' => 'qemu',
|
||||
'ctime' => $basetime,
|
||||
'mark' => $marks->[4],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type) || $type eq 'qemu';
|
||||
push @expected,
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
|
||||
'type' => 'lxc',
|
||||
'ctime' => $basetime,
|
||||
'mark' => $marks->[5],
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type) || $type eq 'lxc';
|
||||
push @expected,
|
||||
(
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
|
||||
'type' => 'unknown',
|
||||
'ctime' => 1234,
|
||||
'mark' => 'renamed',
|
||||
'vmid' => $vmid,
|
||||
},
|
||||
) if !defined($type);
|
||||
}
|
||||
return [ sort { $a->{volid} cmp $b->{volid} } @expected ];
|
||||
return [sort { $a->{volid} cmp $b->{volid} } @expected];
|
||||
}
|
||||
|
||||
# an array of test cases, each test is comprised of the following keys:
|
||||
@ -208,268 +218,312 @@ sub generate_expected {
|
||||
# most of them are created further below
|
||||
my $tests = [
|
||||
{
|
||||
description => 'last=3, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 3,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['remove', 'remove', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'last=3, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 3,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['remove', 'remove', 'keep', 'keep', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'weekly=2, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-weekly' => 2,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
|
||||
description => 'weekly=2, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-weekly' => 2,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['keep', 'remove', 'remove', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'daily=weekly=monthly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'daily=weekly=monthly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'hourly=4, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-hourly' => 4,
|
||||
'keep-daily' => 0,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'hourly=4, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-hourly' => 4,
|
||||
'keep-daily' => 0,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['keep', 'remove', 'keep', 'keep', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'yearly=2, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-weekly' => 0,
|
||||
'keep-monthly' => 0,
|
||||
'keep-yearly' => 2,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['remove', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'yearly=2, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-weekly' => 0,
|
||||
'keep-monthly' => 0,
|
||||
'keep-yearly' => 2,
|
||||
},
|
||||
expected => generate_expected(
|
||||
\@vmids,
|
||||
undef,
|
||||
['remove', 'remove', 'keep', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'last=2,hourly=2 one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-last' => 2,
|
||||
'keep-hourly' => 2,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'last=2,hourly=2 one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-last' => 2,
|
||||
'keep-hourly' => 2,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['keep', 'remove', 'keep', 'keep', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'last=1,monthly=2, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
'keep-monthly' => 2,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'last=1,monthly=2, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
'keep-monthly' => 2,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'monthly=3, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-monthly' => 3,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'monthly=3, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-monthly' => 3,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['keep', 'remove', 'keep', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'last=daily=weekly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'last=daily=weekly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'last=daily=weekly=1, others zero, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-last' => 1,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'last=daily=weekly=1, others zero, multiple IDs',
|
||||
keep => {
|
||||
'keep-hourly' => 0,
|
||||
'keep-last' => 1,
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'daily=2, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-daily' => 2,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['remove', 'remove', 'keep', 'remove', 'keep', 'keep']),
|
||||
description => 'daily=2, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-daily' => 2,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['remove', 'remove', 'keep', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'weekly=monthly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
|
||||
description => 'weekly=monthly=1, multiple IDs',
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
expected => generate_expected(
|
||||
\@vmids,
|
||||
undef,
|
||||
['keep', 'remove', 'remove', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'weekly=yearly=1, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
|
||||
description => 'weekly=yearly=1, one ID',
|
||||
vmid => $vmids[0],
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
undef,
|
||||
['keep', 'remove', 'remove', 'remove', 'keep', 'keep'],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'weekly=yearly=1, one ID, type qemu',
|
||||
vmid => $vmids[0],
|
||||
type => 'qemu',
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], 'qemu', ['keep', 'remove', 'remove', 'remove', 'keep', '']),
|
||||
description => 'weekly=yearly=1, one ID, type qemu',
|
||||
vmid => $vmids[0],
|
||||
type => 'qemu',
|
||||
keep => {
|
||||
'keep-weekly' => 1,
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
expected => generate_expected(
|
||||
[$vmids[0]],
|
||||
'qemu',
|
||||
['keep', 'remove', 'remove', 'remove', 'keep', ''],
|
||||
),
|
||||
},
|
||||
{
|
||||
description => 'week=yearly=1, one ID, type lxc',
|
||||
vmid => $vmids[0],
|
||||
type => 'lxc',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], 'lxc', ['', '', '', '', '', 'keep']),
|
||||
description => 'week=yearly=1, one ID, type lxc',
|
||||
vmid => $vmids[0],
|
||||
type => 'lxc',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
},
|
||||
expected => generate_expected([$vmids[0]], 'lxc', ['', '', '', '', '', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'yearly=1, year before 2000',
|
||||
keep => {
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
list => 'year1970',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
|
||||
'ctime' => 83,
|
||||
'mark' => 'remove',
|
||||
'type' => 'lxc',
|
||||
'vmid' => 321,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
|
||||
'ctime' => 60*60*24 * (365*100 + 25) + 60,
|
||||
'mark' => 'keep',
|
||||
'type' => 'lxc',
|
||||
'vmid' => 321,
|
||||
},
|
||||
],
|
||||
description => 'yearly=1, year before 2000',
|
||||
keep => {
|
||||
'keep-yearly' => 1,
|
||||
},
|
||||
list => 'year1970',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
|
||||
'ctime' => 83,
|
||||
'mark' => 'remove',
|
||||
'type' => 'lxc',
|
||||
'vmid' => 321,
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
|
||||
'ctime' => 60 * 60 * 24 * (365 * 100 + 25) + 60,
|
||||
'mark' => 'keep',
|
||||
'type' => 'lxc',
|
||||
'vmid' => 321,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'last=1, ne ID, year before 2000',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
},
|
||||
list => 'novmid',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
|
||||
'ctime' => 1234,
|
||||
'mark' => 'renamed',
|
||||
'type' => 'lxc',
|
||||
},
|
||||
],
|
||||
description => 'last=1, ne ID, year before 2000',
|
||||
keep => {
|
||||
'keep-last' => 1,
|
||||
},
|
||||
list => 'novmid',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
|
||||
'ctime' => 1234,
|
||||
'mark' => 'renamed',
|
||||
'type' => 'lxc',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'all missing, multiple IDs',
|
||||
keep => {},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'all missing, multiple IDs',
|
||||
keep => {},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'all zero, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 0,
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-weekly' => 0,
|
||||
'keep-monthyl' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'all zero, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 0,
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-weekly' => 0,
|
||||
'keep-monthyl' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'some zero, some missing, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 0,
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-monthyl' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
description => 'some zero, some missing, multiple IDs',
|
||||
keep => {
|
||||
'keep-last' => 0,
|
||||
'keep-hourly' => 0,
|
||||
'keep-daily' => 0,
|
||||
'keep-monthyl' => 0,
|
||||
'keep-yearly' => 0,
|
||||
},
|
||||
expected =>
|
||||
generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
|
||||
},
|
||||
{
|
||||
description => 'daily=weekly=monthly=1',
|
||||
keep => {
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
list => 'threeway',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 7*24*60*60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24*60*60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'remove', # month is already covered by the backup kept by keep-weekly!
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
],
|
||||
description => 'daily=weekly=monthly=1',
|
||||
keep => {
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
'keep-monthly' => 1,
|
||||
},
|
||||
list => 'threeway',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 7 * 24 * 60 * 60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
|
||||
'ctime' => $basetime - 24 * 60 * 60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'remove', # month is already covered by the backup kept by keep-weekly!
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
|
||||
'ctime' => $basetime,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'daily=weekly=1,weekboundary',
|
||||
keep => {
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
},
|
||||
list => 'weekboundary',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+2)*24*60*60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'remove',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+3)*24*60*60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366-31+6)*24*60*60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
],
|
||||
description => 'daily=weekly=1,weekboundary',
|
||||
keep => {
|
||||
'keep-daily' => 1,
|
||||
'keep-weekly' => 1,
|
||||
},
|
||||
list => 'weekboundary',
|
||||
expected => [
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 2) * 24 * 60 * 60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'remove',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 3) * 24 * 60 * 60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
{
|
||||
'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
|
||||
'ctime' => $basetime + (366 - 31 + 6) * 24 * 60 * 60,
|
||||
'type' => 'qemu',
|
||||
'vmid' => 7654,
|
||||
'mark' => 'keep',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@ -478,9 +532,11 @@ plan tests => scalar @$tests;
|
||||
for my $tt (@$tests) {
|
||||
|
||||
my $got = eval {
|
||||
$current_list = $tt->{list} // 'default';
|
||||
my $res = PVE::Storage::Plugin->prune_backups($tt->{scfg}, $storeid, $tt->{keep}, $tt->{vmid}, $tt->{type}, 1);
|
||||
return [ sort { $a->{volid} cmp $b->{volid} } @{$res} ];
|
||||
$current_list = $tt->{list} // 'default';
|
||||
my $res = PVE::Storage::Plugin->prune_backups(
|
||||
$tt->{scfg}, $storeid, $tt->{keep}, $tt->{vmid}, $tt->{type}, 1,
|
||||
);
|
||||
return [sort { $a->{volid} cmp $b->{volid} } @{$res}];
|
||||
};
|
||||
$got = $@ if $@;
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ use JSON;
|
||||
use PVE::Tools qw(run_command);
|
||||
|
||||
my $pool = "testpool";
|
||||
my $use_existing= undef;
|
||||
my $use_existing = undef;
|
||||
my $namespace = "testspace";
|
||||
my $showhelp = '';
|
||||
my $vmid = 999999;
|
||||
@ -46,7 +46,7 @@ Known options are:
|
||||
-h, --help Print this help message
|
||||
";
|
||||
|
||||
GetOptions (
|
||||
GetOptions(
|
||||
"pool=s" => \$pool,
|
||||
"use-existing" => \$use_existing,
|
||||
"namespace=s" => \$namespace,
|
||||
@ -54,7 +54,7 @@ GetOptions (
|
||||
"h|help" => \$showhelp,
|
||||
"cleanup" => \$cleanup,
|
||||
"d|debug" => \$DEBUG,
|
||||
) or die ($helpstring);
|
||||
) or die($helpstring);
|
||||
|
||||
if ($showhelp) {
|
||||
warn $helpstring;
|
||||
@ -69,6 +69,7 @@ my $vmid_linked_clone = int($vmid) - 2;
|
||||
sub jp {
|
||||
print to_json($_[0], { utf8 => 8, pretty => 1, canonical => 1 }) . "\n";
|
||||
}
|
||||
|
||||
sub dbgvar {
|
||||
jp(@_) if $DEBUG;
|
||||
}
|
||||
@ -77,26 +78,24 @@ sub run_cmd {
|
||||
my ($cmd, $json, $ignore_errors) = @_;
|
||||
|
||||
my $raw = '';
|
||||
my $parser = sub {$raw .= shift;};
|
||||
my $parser = sub { $raw .= shift; };
|
||||
|
||||
eval {
|
||||
run_command($cmd, outfunc => $parser);
|
||||
};
|
||||
eval { run_command($cmd, outfunc => $parser); };
|
||||
if (my $err = $@) {
|
||||
die $err if !$ignore_errors;
|
||||
die $err if !$ignore_errors;
|
||||
}
|
||||
|
||||
if ($json) {
|
||||
my $result;
|
||||
if ($raw eq '') {
|
||||
$result = [];
|
||||
} elsif ($raw =~ m/^(\[.*\])$/s) { # untaint
|
||||
$result = JSON::decode_json($1);
|
||||
} else {
|
||||
die "got unexpected data from command: '$cmd' -> '$raw'\n";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
my $result;
|
||||
if ($raw eq '') {
|
||||
$result = [];
|
||||
} elsif ($raw =~ m/^(\[.*\])$/s) { # untaint
|
||||
$result = JSON::decode_json($1);
|
||||
} else {
|
||||
die "got unexpected data from command: '$cmd' -> '$raw'\n";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return $raw;
|
||||
}
|
||||
|
||||
@ -105,17 +104,15 @@ sub run_test_cmd {
|
||||
|
||||
my $raw = '';
|
||||
my $out = sub {
|
||||
my $line = shift;
|
||||
$raw .= "${line}\n";
|
||||
my $line = shift;
|
||||
$raw .= "${line}\n";
|
||||
};
|
||||
|
||||
eval {
|
||||
run_command($cmd, outfunc => $out);
|
||||
};
|
||||
eval { run_command($cmd, outfunc => $out); };
|
||||
if (my $err = $@) {
|
||||
print $raw;
|
||||
print $err;
|
||||
return 0;
|
||||
print $raw;
|
||||
print $err;
|
||||
return 0;
|
||||
}
|
||||
print $raw;
|
||||
return 1;
|
||||
@ -126,23 +123,23 @@ sub prepare {
|
||||
|
||||
my $pools = run_cmd("ceph osd pool ls --format json", 1);
|
||||
|
||||
my %poolnames = map {$_ => 1} @$pools;
|
||||
my %poolnames = map { $_ => 1 } @$pools;
|
||||
die "Pool '$pool' does not exist!\n"
|
||||
if !exists($poolnames{$pool}) && $use_existing;
|
||||
if !exists($poolnames{$pool}) && $use_existing;
|
||||
|
||||
run_cmd(['pveceph', 'pool', 'create', ${pool}, '--add_storages', 1])
|
||||
if !$use_existing;
|
||||
if !$use_existing;
|
||||
|
||||
my $namespaces = run_cmd(['rbd', '-p', ${pool}, 'namespace', 'ls', '--format', 'json'], 1);
|
||||
dbgvar($namespace);
|
||||
my $ns_found = 0;
|
||||
for my $i (@$namespaces) {
|
||||
$ns_found = 1 if $i->{name} eq $namespace;
|
||||
$ns_found = 1 if $i->{name} eq $namespace;
|
||||
}
|
||||
|
||||
if (!$ns_found) {
|
||||
print "Create namespace '${namespace}' in pool '${pool}'\n";
|
||||
run_cmd(['rbd', 'namespace', 'create', "${pool}/${namespace}"]);
|
||||
print "Create namespace '${namespace}' in pool '${pool}'\n";
|
||||
run_cmd(['rbd', 'namespace', 'create', "${pool}/${namespace}"]);
|
||||
}
|
||||
|
||||
my $storages = run_cmd(['pvesh', 'get', 'storage', '--output-format', 'json'], 1);
|
||||
@ -152,41 +149,67 @@ sub prepare {
|
||||
|
||||
print "Create storage definition\n";
|
||||
for my $stor (@$storages) {
|
||||
$pool_found = 1 if $stor->{storage} eq $pool;
|
||||
$rbd_found = 1 if $stor->{storage} eq $storage_name;
|
||||
$pool_found = 1 if $stor->{storage} eq $pool;
|
||||
$rbd_found = 1 if $stor->{storage} eq $storage_name;
|
||||
|
||||
if ($rbd_found) {
|
||||
run_cmd(['pvesm', 'set', ${storage_name}, '--krbd', '0']);
|
||||
die "Enable the storage '$stor->{storage}'!" if $stor->{disable};
|
||||
}
|
||||
if ($rbd_found) {
|
||||
run_cmd(['pvesm', 'set', ${storage_name}, '--krbd', '0']);
|
||||
die "Enable the storage '$stor->{storage}'!" if $stor->{disable};
|
||||
}
|
||||
}
|
||||
if (!$pool_found) {
|
||||
die "No storage for pool '${pool}' found! Must have same name as pool!\n"
|
||||
if $use_existing;
|
||||
die "No storage for pool '${pool}' found! Must have same name as pool!\n"
|
||||
if $use_existing;
|
||||
|
||||
run_cmd(['pvesm', 'add', 'rbd', $pool, '--pool', $pool, '--content', 'images,rootdir']);
|
||||
run_cmd(['pvesm', 'add', 'rbd', $pool, '--pool', $pool, '--content', 'images,rootdir']);
|
||||
}
|
||||
# create PVE storages (librbd / krbd)
|
||||
run_cmd(['pvesm', 'add', 'rbd', ${storage_name}, '--krbd', '0', '--pool', ${pool}, '--namespace', ${namespace}, '--content', 'images,rootdir'])
|
||||
if !$rbd_found;
|
||||
|
||||
run_cmd(
|
||||
[
|
||||
'pvesm',
|
||||
'add',
|
||||
'rbd',
|
||||
${storage_name},
|
||||
'--krbd',
|
||||
'0',
|
||||
'--pool',
|
||||
${pool},
|
||||
'--namespace',
|
||||
${namespace},
|
||||
'--content',
|
||||
'images,rootdir',
|
||||
],
|
||||
) if !$rbd_found;
|
||||
|
||||
# create test VM
|
||||
print "Create test VM ${vmid}\n";
|
||||
my $vms = run_cmd(['pvesh', 'get', 'cluster/resources', '--type', 'vm', '--output-format', 'json'], 1);
|
||||
my $vms =
|
||||
run_cmd(['pvesh', 'get', 'cluster/resources', '--type', 'vm', '--output-format', 'json'],
|
||||
1);
|
||||
for my $vm (@$vms) {
|
||||
# TODO: introduce a force flag to make this behaviour configurable
|
||||
# TODO: introduce a force flag to make this behaviour configurable
|
||||
|
||||
if ($vm->{vmid} eq $vmid) {
|
||||
print "Test VM '${vmid}' already exists. It will be removed and recreated!\n";
|
||||
run_cmd(['qm', 'stop', ${vmid}], 0, 1);
|
||||
run_cmd(['qm', 'destroy', ${vmid}]);
|
||||
}
|
||||
if ($vm->{vmid} eq $vmid) {
|
||||
print "Test VM '${vmid}' already exists. It will be removed and recreated!\n";
|
||||
run_cmd(['qm', 'stop', ${vmid}], 0, 1);
|
||||
run_cmd(['qm', 'destroy', ${vmid}]);
|
||||
}
|
||||
}
|
||||
run_cmd(['qm', 'create', ${vmid}, '--bios', 'ovmf', '--efidisk0', "${storage_name}:1", '--scsi0', "${storage_name}:2"]);
|
||||
run_cmd(
|
||||
[
|
||||
'qm',
|
||||
'create',
|
||||
${vmid},
|
||||
'--bios',
|
||||
'ovmf',
|
||||
'--efidisk0',
|
||||
"${storage_name}:1",
|
||||
'--scsi0',
|
||||
"${storage_name}:2",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
sub cleanup {
|
||||
print "Cleaning up test environment!\n";
|
||||
print "Removing VMs\n";
|
||||
@ -195,7 +218,21 @@ sub cleanup {
|
||||
run_cmd(['qm', 'stop', ${vmid_clone}], 0, 1);
|
||||
run_cmd(['qm', 'destroy', ${vmid_linked_clone}], 0, 1);
|
||||
run_cmd(['qm', 'destroy', ${vmid_clone}], 0, 1);
|
||||
run_cmd(['for', 'i', 'in', "/dev/rbd/${pool}/${namespace}/*;", 'do', '/usr/bin/rbd', 'unmap', '\$i;', 'done'], 0, 1);
|
||||
run_cmd(
|
||||
[
|
||||
'for',
|
||||
'i',
|
||||
'in',
|
||||
"/dev/rbd/${pool}/${namespace}/*;",
|
||||
'do',
|
||||
'/usr/bin/rbd',
|
||||
'unmap',
|
||||
'\$i;',
|
||||
'done',
|
||||
],
|
||||
0,
|
||||
1,
|
||||
);
|
||||
run_cmd(['qm', 'unlock', ${vmid}], 0, 1);
|
||||
run_cmd(['qm', 'destroy', ${vmid}], 0, 1);
|
||||
|
||||
@ -206,10 +243,10 @@ sub cleanup {
|
||||
run_cmd(['rbd', 'namespace', 'remove', "${pool}/${namespace}"], 0, 1);
|
||||
|
||||
if (!$use_existing) {
|
||||
print "Removing Storage definition for ${pool}\n";
|
||||
run_cmd(['pvesm', 'remove', ${pool}], 0, 1);
|
||||
print "Removing test pool\n";
|
||||
run_cmd(['pveceph', 'pool', 'destroy', $pool]);
|
||||
print "Removing Storage definition for ${pool}\n";
|
||||
run_cmd(['pvesm', 'remove', ${pool}], 0, 1);
|
||||
print "Removing test pool\n";
|
||||
run_cmd(['pveceph', 'pool', 'destroy', $pool]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,102 +266,96 @@ my $tests = [
|
||||
# ],
|
||||
# },
|
||||
{
|
||||
name => 'first VM start',
|
||||
steps => [
|
||||
['qm', 'start', $vmid],
|
||||
],
|
||||
name => 'first VM start',
|
||||
steps => [
|
||||
['qm', 'start', $vmid],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'snapshot/rollback',
|
||||
steps => [
|
||||
['qm', 'snapshot', $vmid, 'test'],
|
||||
['qm', 'rollback', $vmid, 'test'],
|
||||
],
|
||||
cleanup => [
|
||||
['qm', 'unlock', $vmid],
|
||||
],
|
||||
name => 'snapshot/rollback',
|
||||
steps => [
|
||||
['qm', 'snapshot', $vmid, 'test'], ['qm', 'rollback', $vmid, 'test'],
|
||||
],
|
||||
cleanup => [
|
||||
['qm', 'unlock', $vmid],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'remove snapshot',
|
||||
steps => [
|
||||
['qm', 'delsnapshot', $vmid, 'test'],
|
||||
],
|
||||
name => 'remove snapshot',
|
||||
steps => [
|
||||
['qm', 'delsnapshot', $vmid, 'test'],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'moving disk between namespaces',
|
||||
steps => [
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $pool, '--delete', 1],
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $storage_name, '--delete', 1],
|
||||
],
|
||||
name => 'moving disk between namespaces',
|
||||
steps => [
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $pool, '--delete', 1],
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $storage_name, '--delete', 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'switch to krbd',
|
||||
preparations => [
|
||||
['qm', 'stop', $vmid],
|
||||
['pvesm', 'set', $storage_name, '--krbd', 1]
|
||||
],
|
||||
name => 'switch to krbd',
|
||||
preparations => [
|
||||
['qm', 'stop', $vmid], ['pvesm', 'set', $storage_name, '--krbd', 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'start VM with krbd',
|
||||
steps => [
|
||||
['qm', 'start', $vmid],
|
||||
],
|
||||
name => 'start VM with krbd',
|
||||
steps => [
|
||||
['qm', 'start', $vmid],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'snapshot/rollback with krbd',
|
||||
steps => [
|
||||
['qm', 'snapshot', $vmid, 'test'],
|
||||
['qm', 'rollback', $vmid, 'test'],
|
||||
],
|
||||
cleanup => [
|
||||
['qm', 'unlock', $vmid],
|
||||
],
|
||||
name => 'snapshot/rollback with krbd',
|
||||
steps => [
|
||||
['qm', 'snapshot', $vmid, 'test'], ['qm', 'rollback', $vmid, 'test'],
|
||||
],
|
||||
cleanup => [
|
||||
['qm', 'unlock', $vmid],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'remove snapshot with krbd',
|
||||
steps => [
|
||||
['qm', 'delsnapshot', $vmid, 'test'],
|
||||
],
|
||||
name => 'remove snapshot with krbd',
|
||||
steps => [
|
||||
['qm', 'delsnapshot', $vmid, 'test'],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'moving disk between namespaces with krbd',
|
||||
steps => [
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $pool, '--delete', 1],
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $storage_name, '--delete', 1],
|
||||
],
|
||||
name => 'moving disk between namespaces with krbd',
|
||||
steps => [
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $pool, '--delete', 1],
|
||||
['qm', 'move_disk', $vmid, 'scsi0', $storage_name, '--delete', 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'clone VM with krbd',
|
||||
steps => [
|
||||
['qm', 'clone', $vmid, $vmid_clone],
|
||||
],
|
||||
name => 'clone VM with krbd',
|
||||
steps => [
|
||||
['qm', 'clone', $vmid, $vmid_clone],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'switch to non krbd',
|
||||
preparations => [
|
||||
['qm', 'stop', $vmid],
|
||||
['qm', 'stop', $vmid_clone],
|
||||
['pvesm', 'set', $storage_name, '--krbd', 0]
|
||||
],
|
||||
name => 'switch to non krbd',
|
||||
preparations => [
|
||||
['qm', 'stop', $vmid],
|
||||
['qm', 'stop', $vmid_clone],
|
||||
['pvesm', 'set', $storage_name, '--krbd', 0],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'templates and linked clone',
|
||||
steps => [
|
||||
['qm', 'template', $vmid],
|
||||
['qm', 'clone', $vmid, $vmid_linked_clone],
|
||||
['qm', 'start', $vmid_linked_clone],
|
||||
['qm', 'stop', $vmid_linked_clone],
|
||||
],
|
||||
name => 'templates and linked clone',
|
||||
steps => [
|
||||
['qm', 'template', $vmid],
|
||||
['qm', 'clone', $vmid, $vmid_linked_clone],
|
||||
['qm', 'start', $vmid_linked_clone],
|
||||
['qm', 'stop', $vmid_linked_clone],
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'start linked clone with krbd',
|
||||
preparations => [
|
||||
['pvesm', 'set', $storage_name, '--krbd', 1]
|
||||
],
|
||||
steps => [
|
||||
['qm', 'start', $vmid_linked_clone],
|
||||
['qm', 'stop', $vmid_linked_clone],
|
||||
],
|
||||
name => 'start linked clone with krbd',
|
||||
preparations => [['pvesm', 'set', $storage_name, '--krbd', 1]],
|
||||
steps => [
|
||||
['qm', 'start', $vmid_linked_clone], ['qm', 'stop', $vmid_linked_clone],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@ -332,8 +363,8 @@ sub run_prep_cleanup {
|
||||
my ($cmds) = @_;
|
||||
|
||||
for (@$cmds) {
|
||||
print join(' ', @$_). "\n";
|
||||
run_cmd($_);
|
||||
print join(' ', @$_) . "\n";
|
||||
run_cmd($_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +372,7 @@ sub run_steps {
|
||||
my ($steps) = @_;
|
||||
|
||||
for (@$steps) {
|
||||
ok(run_test_cmd($_), join(' ', @$_));
|
||||
ok(run_test_cmd($_), join(' ', @$_));
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,23 +381,23 @@ sub run_tests {
|
||||
|
||||
my $num_tests = 0;
|
||||
for (@$tests) {
|
||||
$num_tests += scalar(@{$_->{steps}}) if defined $_->{steps};
|
||||
$num_tests += scalar(@{ $_->{steps} }) if defined $_->{steps};
|
||||
}
|
||||
|
||||
print("Tests: $num_tests\n");
|
||||
plan tests => $num_tests;
|
||||
|
||||
for my $test (@$tests) {
|
||||
print "Section: $test->{name}\n";
|
||||
run_prep_cleanup($test->{preparations}) if defined $test->{preparations};
|
||||
run_steps($test->{steps}) if defined $test->{steps};
|
||||
run_prep_cleanup($test->{cleanup}) if defined $test->{cleanup};
|
||||
print "Section: $test->{name}\n";
|
||||
run_prep_cleanup($test->{preparations}) if defined $test->{preparations};
|
||||
run_steps($test->{steps}) if defined $test->{steps};
|
||||
run_prep_cleanup($test->{cleanup}) if defined $test->{cleanup};
|
||||
}
|
||||
|
||||
done_testing();
|
||||
|
||||
if (Test::More->builder->is_passing()) {
|
||||
cleanup();
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,23 +51,23 @@ EOF
|
||||
|
||||
my $permissions = {
|
||||
'user1@test' => {},
|
||||
'user2@test' => { '/' => ['Sys.Modify'], },
|
||||
'user3@test' => { '/storage' => ['Datastore.Allocate'], },
|
||||
'user4@test' => { '/storage/d20m40r30' => ['Datastore.Allocate'], },
|
||||
'user2@test' => { '/' => ['Sys.Modify'] },
|
||||
'user3@test' => { '/storage' => ['Datastore.Allocate'] },
|
||||
'user4@test' => { '/storage/d20m40r30' => ['Datastore.Allocate'] },
|
||||
};
|
||||
|
||||
my $pve_cluster_module;
|
||||
$pve_cluster_module = Test::MockModule->new('PVE::Cluster');
|
||||
$pve_cluster_module->mock(
|
||||
cfs_update => sub {},
|
||||
cfs_update => sub { },
|
||||
get_config => sub {
|
||||
my ($file) = @_;
|
||||
if ($file eq 'datacenter.cfg') {
|
||||
return $datacenter_cfg;
|
||||
} elsif ($file eq 'storage.cfg') {
|
||||
return $storage_cfg;
|
||||
}
|
||||
die "TODO: mock get_config($file)\n";
|
||||
my ($file) = @_;
|
||||
if ($file eq 'datacenter.cfg') {
|
||||
return $datacenter_cfg;
|
||||
} elsif ($file eq 'storage.cfg') {
|
||||
return $storage_cfg;
|
||||
}
|
||||
die "TODO: mock get_config($file)\n";
|
||||
},
|
||||
);
|
||||
|
||||
@ -75,136 +75,360 @@ my $rpcenv_module;
|
||||
$rpcenv_module = Test::MockModule->new('PVE::RPCEnvironment');
|
||||
$rpcenv_module->mock(
|
||||
check => sub {
|
||||
my ($env, $user, $path, $perms, $noerr) = @_;
|
||||
return 1 if $user eq 'root@pam';
|
||||
my $userperms = $permissions->{$user}
|
||||
or die "no permissions defined for user $user\n";
|
||||
if (defined(my $pathperms = $userperms->{$path})) {
|
||||
foreach my $pp (@$pathperms) {
|
||||
foreach my $reqp (@$perms) {
|
||||
return 1 if $pp eq $reqp;
|
||||
}
|
||||
}
|
||||
}
|
||||
die "permission denied\n" if !$noerr;
|
||||
return 0;
|
||||
my ($env, $user, $path, $perms, $noerr) = @_;
|
||||
return 1 if $user eq 'root@pam';
|
||||
my $userperms = $permissions->{$user}
|
||||
or die "no permissions defined for user $user\n";
|
||||
if (defined(my $pathperms = $userperms->{$path})) {
|
||||
foreach my $pp (@$pathperms) {
|
||||
foreach my $reqp (@$perms) {
|
||||
return 1 if $pp eq $reqp;
|
||||
}
|
||||
}
|
||||
}
|
||||
die "permission denied\n" if !$noerr;
|
||||
return 0;
|
||||
},
|
||||
);
|
||||
|
||||
my $rpcenv = PVE::RPCEnvironment->init('pub');
|
||||
|
||||
my @tests = (
|
||||
[ user => 'root@pam' ],
|
||||
[ ['unknown', ['nolimit'], undef], 100, 'root / generic default limit, requesting default' ],
|
||||
[ ['move', ['nolimit'], undef], 80, 'root / specific default limit, requesting default (move)' ],
|
||||
[ ['restore', ['nolimit'], undef], 60, 'root / specific default limit, requesting default (restore)' ],
|
||||
[ ['unknown', ['d50m40r30'], undef], 50, 'root / storage default limit' ],
|
||||
[ ['move', ['d50m40r30'], undef], 40, 'root / specific storage limit (move)' ],
|
||||
[ ['restore', ['d50m40r30'], undef], 30, 'root / specific storage limit (restore)' ],
|
||||
[ ['unknown', ['nolimit'], 0], 0, 'root / generic default limit' ],
|
||||
[ ['move', ['nolimit'], 0], 0, 'root / specific default limit (move)' ],
|
||||
[ ['restore', ['nolimit'], 0], 0, 'root / specific default limit (restore)' ],
|
||||
[ ['unknown', ['d50m40r30'], 0], 0, 'root / storage default limit' ],
|
||||
[ ['move', ['d50m40r30'], 0], 0, 'root / specific storage limit (move)' ],
|
||||
[ ['restore', ['d50m40r30'], 0], 0, 'root / specific storage limit (restore)' ],
|
||||
[ ['migrate', undef, 100], 100, 'root / undef storage (migrate)' ],
|
||||
[ ['migrate', [], 100], 100, 'root / no storage (migrate)' ],
|
||||
[ ['migrate', [undef], undef], 100, 'root / [undef] storage no override (migrate)' ],
|
||||
[ ['migrate', [undef, undef], 200], 200, 'root / list of undef storages with override (migrate)' ],
|
||||
[user => 'root@pam'],
|
||||
[['unknown', ['nolimit'], undef], 100, 'root / generic default limit, requesting default'],
|
||||
[
|
||||
['move', ['nolimit'], undef],
|
||||
80,
|
||||
'root / specific default limit, requesting default (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit'], undef],
|
||||
60,
|
||||
'root / specific default limit, requesting default (restore)',
|
||||
],
|
||||
[['unknown', ['d50m40r30'], undef], 50, 'root / storage default limit'],
|
||||
[['move', ['d50m40r30'], undef], 40, 'root / specific storage limit (move)'],
|
||||
[['restore', ['d50m40r30'], undef], 30, 'root / specific storage limit (restore)'],
|
||||
[['unknown', ['nolimit'], 0], 0, 'root / generic default limit'],
|
||||
[['move', ['nolimit'], 0], 0, 'root / specific default limit (move)'],
|
||||
[['restore', ['nolimit'], 0], 0, 'root / specific default limit (restore)'],
|
||||
[['unknown', ['d50m40r30'], 0], 0, 'root / storage default limit'],
|
||||
[['move', ['d50m40r30'], 0], 0, 'root / specific storage limit (move)'],
|
||||
[['restore', ['d50m40r30'], 0], 0, 'root / specific storage limit (restore)'],
|
||||
[['migrate', undef, 100], 100, 'root / undef storage (migrate)'],
|
||||
[['migrate', [], 100], 100, 'root / no storage (migrate)'],
|
||||
[['migrate', [undef], undef], 100, 'root / [undef] storage no override (migrate)'],
|
||||
[
|
||||
['migrate', [undef, undef], 200],
|
||||
200,
|
||||
'root / list of undef storages with override (migrate)',
|
||||
],
|
||||
|
||||
[ user => 'user1@test' ],
|
||||
[ ['unknown', ['nolimit'], undef], 100, 'generic default limit' ],
|
||||
[ ['move', ['nolimit'], undef], 80, 'specific default limit (move)' ],
|
||||
[ ['restore', ['nolimit'], undef], 60, 'specific default limit (restore)' ],
|
||||
[ ['unknown', ['d50m40r30'], undef], 50, 'storage default limit' ],
|
||||
[ ['move', ['d50m40r30'], undef], 40, 'specific storage limit (move)' ],
|
||||
[ ['restore', ['d50m40r30'], undef], 30, 'specific storage limit (restore)' ],
|
||||
[ ['unknown', ['d200m400r300'], undef], 200, 'storage default limit above datacenter limits' ],
|
||||
[ ['move', ['d200m400r300'], undef], 400, 'specific storage limit above datacenter limits (move)' ],
|
||||
[ ['restore', ['d200m400r300'], undef], 300, 'specific storage limit above datacenter limits (restore)' ],
|
||||
[ ['unknown', ['d50'], undef], 50, 'storage default limit' ],
|
||||
[ ['move', ['d50'], undef], 50, 'storage default limit (move)' ],
|
||||
[ ['restore', ['d50'], undef], 50, 'storage default limit (restore)' ],
|
||||
[user => 'user1@test'],
|
||||
[['unknown', ['nolimit'], undef], 100, 'generic default limit'],
|
||||
[['move', ['nolimit'], undef], 80, 'specific default limit (move)'],
|
||||
[['restore', ['nolimit'], undef], 60, 'specific default limit (restore)'],
|
||||
[['unknown', ['d50m40r30'], undef], 50, 'storage default limit'],
|
||||
[['move', ['d50m40r30'], undef], 40, 'specific storage limit (move)'],
|
||||
[['restore', ['d50m40r30'], undef], 30, 'specific storage limit (restore)'],
|
||||
[
|
||||
['unknown', ['d200m400r300'], undef],
|
||||
200,
|
||||
'storage default limit above datacenter limits',
|
||||
],
|
||||
[
|
||||
['move', ['d200m400r300'], undef],
|
||||
400,
|
||||
'specific storage limit above datacenter limits (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d200m400r300'], undef],
|
||||
300,
|
||||
'specific storage limit above datacenter limits (restore)',
|
||||
],
|
||||
[['unknown', ['d50'], undef], 50, 'storage default limit'],
|
||||
[['move', ['d50'], undef], 50, 'storage default limit (move)'],
|
||||
[['restore', ['d50'], undef], 50, 'storage default limit (restore)'],
|
||||
|
||||
[ user => 'user2@test' ],
|
||||
[ ['unknown', ['nolimit'], 0], 0, 'generic default limit with Sys.Modify, passing unlimited' ],
|
||||
[ ['unknown', ['nolimit'], undef], 100, 'generic default limit with Sys.Modify' ],
|
||||
[ ['move', ['nolimit'], undef], 80, 'specific default limit with Sys.Modify (move)' ],
|
||||
[ ['restore', ['nolimit'], undef], 60, 'specific default limit with Sys.Modify (restore)' ],
|
||||
[ ['restore', ['nolimit'], 0], 0, 'specific default limit with Sys.Modify, passing unlimited (restore)' ],
|
||||
[ ['move', ['nolimit'], 0], 0, 'specific default limit with Sys.Modify, passing unlimited (move)' ],
|
||||
[ ['unknown', ['d50m40r30'], undef], 50, 'storage default limit with Sys.Modify' ],
|
||||
[ ['restore', ['d50m40r30'], undef], 30, 'specific storage limit with Sys.Modify (restore)' ],
|
||||
[ ['move', ['d50m40r30'], undef], 40, 'specific storage limit with Sys.Modify (move)' ],
|
||||
[user => 'user2@test'],
|
||||
[
|
||||
['unknown', ['nolimit'], 0],
|
||||
0,
|
||||
'generic default limit with Sys.Modify, passing unlimited',
|
||||
],
|
||||
[['unknown', ['nolimit'], undef], 100, 'generic default limit with Sys.Modify'],
|
||||
[['move', ['nolimit'], undef], 80, 'specific default limit with Sys.Modify (move)'],
|
||||
[['restore', ['nolimit'], undef], 60, 'specific default limit with Sys.Modify (restore)'],
|
||||
[
|
||||
['restore', ['nolimit'], 0],
|
||||
0,
|
||||
'specific default limit with Sys.Modify, passing unlimited (restore)',
|
||||
],
|
||||
[
|
||||
['move', ['nolimit'], 0],
|
||||
0,
|
||||
'specific default limit with Sys.Modify, passing unlimited (move)',
|
||||
],
|
||||
[['unknown', ['d50m40r30'], undef], 50, 'storage default limit with Sys.Modify'],
|
||||
[['restore', ['d50m40r30'], undef], 30, 'specific storage limit with Sys.Modify (restore)'],
|
||||
[['move', ['d50m40r30'], undef], 40, 'specific storage limit with Sys.Modify (move)'],
|
||||
|
||||
[ user => 'user3@test' ],
|
||||
[ ['unknown', ['nolimit'], undef], 100, 'generic default limit with privileges on /' ],
|
||||
[ ['unknown', ['nolimit'], 80], 80, 'generic default limit with privileges on /, passing an override value' ],
|
||||
[ ['unknown', ['nolimit'], 0], 0, 'generic default limit with privileges on /, passing unlimited' ],
|
||||
[ ['move', ['nolimit'], undef], 80, 'specific default limit with privileges on / (move)' ],
|
||||
[ ['move', ['nolimit'], 0], 0, 'specific default limit with privileges on /, passing unlimited (move)' ],
|
||||
[ ['restore', ['nolimit'], undef], 60, 'specific default limit with privileges on / (restore)' ],
|
||||
[ ['restore', ['nolimit'], 0], 0, 'specific default limit with privileges on /, passing unlimited (restore)' ],
|
||||
[ ['unknown', ['d50m40r30'], 0], 0, 'storage default limit with privileges on /, passing unlimited' ],
|
||||
[ ['unknown', ['d50m40r30'], undef], 50, 'storage default limit with privileges on /' ],
|
||||
[ ['unknown', ['d50m40r30'], 0], 0, 'storage default limit with privileges on, passing unlimited /' ],
|
||||
[ ['move', ['d50m40r30'], undef], 40, 'specific storage limit with privileges on / (move)' ],
|
||||
[ ['move', ['d50m40r30'], 0], 0, 'specific storage limit with privileges on, passing unlimited / (move)' ],
|
||||
[ ['restore', ['d50m40r30'], undef], 30, 'specific storage limit with privileges on / (restore)' ],
|
||||
[ ['restore', ['d50m40r30'], 0], 0, 'specific storage limit with privileges on /, passing unlimited (restore)' ],
|
||||
[user => 'user3@test'],
|
||||
[['unknown', ['nolimit'], undef], 100, 'generic default limit with privileges on /'],
|
||||
[
|
||||
['unknown', ['nolimit'], 80],
|
||||
80,
|
||||
'generic default limit with privileges on /, passing an override value',
|
||||
],
|
||||
[
|
||||
['unknown', ['nolimit'], 0],
|
||||
0,
|
||||
'generic default limit with privileges on /, passing unlimited',
|
||||
],
|
||||
[['move', ['nolimit'], undef], 80, 'specific default limit with privileges on / (move)'],
|
||||
[
|
||||
['move', ['nolimit'], 0],
|
||||
0,
|
||||
'specific default limit with privileges on /, passing unlimited (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit'], undef],
|
||||
60,
|
||||
'specific default limit with privileges on / (restore)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit'], 0],
|
||||
0,
|
||||
'specific default limit with privileges on /, passing unlimited (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['d50m40r30'], 0],
|
||||
0,
|
||||
'storage default limit with privileges on /, passing unlimited',
|
||||
],
|
||||
[['unknown', ['d50m40r30'], undef], 50, 'storage default limit with privileges on /'],
|
||||
[
|
||||
['unknown', ['d50m40r30'], 0],
|
||||
0,
|
||||
'storage default limit with privileges on, passing unlimited /',
|
||||
],
|
||||
[['move', ['d50m40r30'], undef], 40, 'specific storage limit with privileges on / (move)'],
|
||||
[
|
||||
['move', ['d50m40r30'], 0],
|
||||
0,
|
||||
'specific storage limit with privileges on, passing unlimited / (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d50m40r30'], undef],
|
||||
30,
|
||||
'specific storage limit with privileges on / (restore)',
|
||||
],
|
||||
[
|
||||
['restore', ['d50m40r30'], 0],
|
||||
0,
|
||||
'specific storage limit with privileges on /, passing unlimited (restore)',
|
||||
],
|
||||
|
||||
[ user => 'user4@test' ],
|
||||
[ ['unknown', ['nolimit'], 10], 10, 'generic default limit with privileges on a different storage, passing lower override' ],
|
||||
[ ['unknown', ['nolimit'], undef], 100, 'generic default limit with privileges on a different storage' ],
|
||||
[ ['unknown', ['nolimit'], 0], 100, 'generic default limit with privileges on a different storage, passing unlimited' ],
|
||||
[ ['move', ['nolimit'], undef], 80, 'specific default limit with privileges on a different storage (move)' ],
|
||||
[ ['restore', ['nolimit'], undef], 60, 'specific default limit with privileges on a different storage (restore)' ],
|
||||
[ ['unknown', ['d50m40r30'], undef], 50, 'storage default limit with privileges on a different storage' ],
|
||||
[ ['move', ['d50m40r30'], undef], 40, 'specific storage limit with privileges on a different storage (move)' ],
|
||||
[ ['restore', ['d50m40r30'], undef], 30, 'specific storage limit with privileges on a different storage (restore)' ],
|
||||
[ ['unknown', ['d20m40r30'], undef], 20, 'storage default limit with privileges on that storage' ],
|
||||
[ ['unknown', ['d20m40r30'], 0], 0, 'storage default limit with privileges on that storage, passing unlimited' ],
|
||||
[ ['move', ['d20m40r30'], undef], 40, 'specific storage limit with privileges on that storage (move)' ],
|
||||
[ ['move', ['d20m40r30'], 0], 0, 'specific storage limit with privileges on that storage, passing unlimited (move)' ],
|
||||
[ ['move', ['d20m40r30'], 10], 10, 'specific storage limit with privileges on that storage, passing low override (move)' ],
|
||||
[ ['move', ['d20m40r30'], 300], 300, 'specific storage limit with privileges on that storage, passing high override (move)' ],
|
||||
[ ['restore', ['d20m40r30'], undef], 30, 'specific storage limit with privileges on that storage (restore)' ],
|
||||
[ ['restore', ['d20m40r30'], 0], 0, 'specific storage limit with privileges on that storage, passing unlimited (restore)' ],
|
||||
[ ['unknown', ['d50m40r30', 'd20m40r30'], 0], 50, 'multiple storages default limit with privileges on one of them, passing unlimited' ],
|
||||
[ ['move', ['d50m40r30', 'd20m40r30'], 0], 40, 'multiple storages specific limit with privileges on one of them, passing unlimited (move)' ],
|
||||
[ ['restore', ['d50m40r30', 'd20m40r30'], 0], 30, 'multiple storages specific limit with privileges on one of them, passing unlimited (restore)' ],
|
||||
[ ['unknown', ['d50m40r30', 'd20m40r30'], undef], 20, 'multiple storages default limit with privileges on one of them' ],
|
||||
[ ['unknown', ['d10', 'd20m40r30'], undef], 10, 'multiple storages default limit with privileges on one of them (storage limited)' ],
|
||||
[ ['move', ['d10', 'd20m40r30'], undef], 10, 'multiple storages specific limit with privileges on one of them (storage limited) (move)' ],
|
||||
[ ['restore', ['d10', 'd20m40r30'], undef], 10, 'multiple storages specific limit with privileges on one of them (storage limited) (restore)' ],
|
||||
[ ['restore', ['d10', 'd20m40r30'], 5], 5, 'multiple storages specific limit (storage limited) (restore), passing lower override' ],
|
||||
[ ['restore', ['d200', 'd200m400r300'], 65], 65, 'multiple storages specific limit (storage limited) (restore), passing lower override' ],
|
||||
[ ['restore', ['d200', 'd200m400r300'], 400], 200, 'multiple storages specific limit (storage limited) (restore), passing higher override' ],
|
||||
[ ['restore', ['d200', 'd200m400r300'], 0], 200, 'multiple storages specific limit (storage limited) (restore), passing unlimited' ],
|
||||
[ ['restore', ['d200', 'd200m400r300'], 1], 1, 'multiple storages specific limit (storage limited) (restore), passing 1' ],
|
||||
[ ['restore', ['d10', 'd20m40r30'], 500], 10, 'multiple storages specific limit with privileges on one of them (storage limited) (restore), passing higher override' ],
|
||||
[ ['unknown', ['nolimit', 'd20m40r30'], 0], 100, 'multiple storages default limit with privileges on one of them, passing unlimited (default limited)' ],
|
||||
[ ['move', ['nolimit', 'd20m40r30'], 0], 80, 'multiple storages specific limit with privileges on one of them, passing unlimited (default limited) (move)' ],
|
||||
[ ['restore', ['nolimit', 'd20m40r30'], 0], 60, 'multiple storages specific limit with privileges on one of them, passing unlimited (default limited) (restore)' ],
|
||||
[ ['unknown', ['nolimit', 'd20m40r30'], undef], 20, 'multiple storages default limit with privileges on one of them (default limited)' ],
|
||||
[ ['move', ['nolimit', 'd20m40r30'], undef], 40, 'multiple storages specific limit with privileges on one of them (default limited) (move)' ],
|
||||
[ ['restore', ['nolimit', 'd20m40r30'], undef], 30, 'multiple storages specific limit with privileges on one of them (default limited) (restore)' ],
|
||||
[ ['restore', ['d20m40r30', 'm50'], 200], 60, 'multiple storages specific limit with privileges on one of them (global default limited) (restore)' ],
|
||||
[ ['move', ['nolimit', undef ], 40] , 40, 'multiple storages one undefined, passing 40 (move)' ],
|
||||
[ ['move', undef, 100] , 80, 'undef storage, passing 100 (move)' ],
|
||||
[ ['move', [undef], 100] , 80, '[undef] storage, passing 100 (move)' ],
|
||||
[ ['move', [undef], undef] , 80, '[undef] storage, no override (move)' ],
|
||||
[user => 'user4@test'],
|
||||
[
|
||||
['unknown', ['nolimit'], 10],
|
||||
10,
|
||||
'generic default limit with privileges on a different storage, passing lower override',
|
||||
],
|
||||
[
|
||||
['unknown', ['nolimit'], undef],
|
||||
100,
|
||||
'generic default limit with privileges on a different storage',
|
||||
],
|
||||
[
|
||||
['unknown', ['nolimit'], 0],
|
||||
100,
|
||||
'generic default limit with privileges on a different storage, passing unlimited',
|
||||
],
|
||||
[
|
||||
['move', ['nolimit'], undef],
|
||||
80,
|
||||
'specific default limit with privileges on a different storage (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit'], undef],
|
||||
60,
|
||||
'specific default limit with privileges on a different storage (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['d50m40r30'], undef],
|
||||
50,
|
||||
'storage default limit with privileges on a different storage',
|
||||
],
|
||||
[
|
||||
['move', ['d50m40r30'], undef],
|
||||
40,
|
||||
'specific storage limit with privileges on a different storage (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d50m40r30'], undef],
|
||||
30,
|
||||
'specific storage limit with privileges on a different storage (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['d20m40r30'], undef],
|
||||
20,
|
||||
'storage default limit with privileges on that storage',
|
||||
],
|
||||
[
|
||||
['unknown', ['d20m40r30'], 0],
|
||||
0,
|
||||
'storage default limit with privileges on that storage, passing unlimited',
|
||||
],
|
||||
[
|
||||
['move', ['d20m40r30'], undef],
|
||||
40,
|
||||
'specific storage limit with privileges on that storage (move)',
|
||||
],
|
||||
[
|
||||
['move', ['d20m40r30'], 0],
|
||||
0,
|
||||
'specific storage limit with privileges on that storage, passing unlimited (move)',
|
||||
],
|
||||
[
|
||||
['move', ['d20m40r30'], 10],
|
||||
10,
|
||||
'specific storage limit with privileges on that storage, passing low override (move)',
|
||||
],
|
||||
[
|
||||
['move', ['d20m40r30'], 300],
|
||||
300,
|
||||
'specific storage limit with privileges on that storage, passing high override (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d20m40r30'], undef],
|
||||
30,
|
||||
'specific storage limit with privileges on that storage (restore)',
|
||||
],
|
||||
[
|
||||
['restore', ['d20m40r30'], 0],
|
||||
0,
|
||||
'specific storage limit with privileges on that storage, passing unlimited (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['d50m40r30', 'd20m40r30'], 0],
|
||||
50,
|
||||
'multiple storages default limit with privileges on one of them, passing unlimited',
|
||||
],
|
||||
[
|
||||
['move', ['d50m40r30', 'd20m40r30'], 0],
|
||||
40,
|
||||
'multiple storages specific limit with privileges on one of them, passing unlimited (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d50m40r30', 'd20m40r30'], 0],
|
||||
30,
|
||||
'multiple storages specific limit with privileges on one of them, passing unlimited (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['d50m40r30', 'd20m40r30'], undef],
|
||||
20,
|
||||
'multiple storages default limit with privileges on one of them',
|
||||
],
|
||||
[
|
||||
['unknown', ['d10', 'd20m40r30'], undef],
|
||||
10,
|
||||
'multiple storages default limit with privileges on one of them (storage limited)',
|
||||
],
|
||||
[
|
||||
['move', ['d10', 'd20m40r30'], undef],
|
||||
10,
|
||||
'multiple storages specific limit with privileges on one of them (storage limited) (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['d10', 'd20m40r30'], undef],
|
||||
10,
|
||||
'multiple storages specific limit with privileges on one of them (storage limited) (restore)',
|
||||
],
|
||||
[
|
||||
['restore', ['d10', 'd20m40r30'], 5],
|
||||
5,
|
||||
'multiple storages specific limit (storage limited) (restore), passing lower override',
|
||||
],
|
||||
[
|
||||
['restore', ['d200', 'd200m400r300'], 65],
|
||||
65,
|
||||
'multiple storages specific limit (storage limited) (restore), passing lower override',
|
||||
],
|
||||
[
|
||||
['restore', ['d200', 'd200m400r300'], 400],
|
||||
200,
|
||||
'multiple storages specific limit (storage limited) (restore), passing higher override',
|
||||
],
|
||||
[
|
||||
['restore', ['d200', 'd200m400r300'], 0],
|
||||
200,
|
||||
'multiple storages specific limit (storage limited) (restore), passing unlimited',
|
||||
],
|
||||
[
|
||||
['restore', ['d200', 'd200m400r300'], 1],
|
||||
1,
|
||||
'multiple storages specific limit (storage limited) (restore), passing 1',
|
||||
],
|
||||
[
|
||||
['restore', ['d10', 'd20m40r30'], 500],
|
||||
10,
|
||||
'multiple storages specific limit with privileges on one of them (storage limited) (restore), passing higher override',
|
||||
],
|
||||
[
|
||||
['unknown', ['nolimit', 'd20m40r30'], 0],
|
||||
100,
|
||||
'multiple storages default limit with privileges on one of them, passing unlimited (default limited)',
|
||||
],
|
||||
[
|
||||
['move', ['nolimit', 'd20m40r30'], 0],
|
||||
80,
|
||||
'multiple storages specific limit with privileges on one of them, passing unlimited (default limited) (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit', 'd20m40r30'], 0],
|
||||
60,
|
||||
'multiple storages specific limit with privileges on one of them, passing unlimited (default limited) (restore)',
|
||||
],
|
||||
[
|
||||
['unknown', ['nolimit', 'd20m40r30'], undef],
|
||||
20,
|
||||
'multiple storages default limit with privileges on one of them (default limited)',
|
||||
],
|
||||
[
|
||||
['move', ['nolimit', 'd20m40r30'], undef],
|
||||
40,
|
||||
'multiple storages specific limit with privileges on one of them (default limited) (move)',
|
||||
],
|
||||
[
|
||||
['restore', ['nolimit', 'd20m40r30'], undef],
|
||||
30,
|
||||
'multiple storages specific limit with privileges on one of them (default limited) (restore)',
|
||||
],
|
||||
[
|
||||
['restore', ['d20m40r30', 'm50'], 200],
|
||||
60,
|
||||
'multiple storages specific limit with privileges on one of them (global default limited) (restore)',
|
||||
],
|
||||
[
|
||||
['move', ['nolimit', undef], 40],
|
||||
40,
|
||||
'multiple storages one undefined, passing 40 (move)',
|
||||
],
|
||||
[['move', undef, 100], 80, 'undef storage, passing 100 (move)'],
|
||||
[['move', [undef], 100], 80, '[undef] storage, passing 100 (move)'],
|
||||
[['move', [undef], undef], 80, '[undef] storage, no override (move)'],
|
||||
);
|
||||
|
||||
foreach my $t (@tests) {
|
||||
my ($args, $expected, $description) = @$t;
|
||||
if (!ref($args)) {
|
||||
if ($args eq 'user') {
|
||||
$rpcenv->set_user($expected);
|
||||
} else {
|
||||
die "not a test specification\n";
|
||||
}
|
||||
next;
|
||||
if ($args eq 'user') {
|
||||
$rpcenv->set_user($expected);
|
||||
} else {
|
||||
die "not a test specification\n";
|
||||
}
|
||||
next;
|
||||
}
|
||||
is(PVE::Storage::get_bandwidth_limit(@$args), $expected, $description);
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ use warnings;
|
||||
|
||||
use TAP::Harness;
|
||||
|
||||
my $harness = TAP::Harness->new( { verbosity => -2 });
|
||||
my $res = $harness->runtests( "disklist_test.pm" );
|
||||
my $harness = TAP::Harness->new({ verbosity => -2 });
|
||||
my $res = $harness->runtests("disklist_test.pm");
|
||||
|
||||
exit -1 if !$res || $res->{failed} || $res->{parse_errors};
|
||||
|
||||
|
||||
@ -10,11 +10,12 @@ use Test::More;
|
||||
|
||||
use Data::Dumper;
|
||||
|
||||
my $test_manifests = join ('/', $Bin, 'ovf_manifests');
|
||||
my $test_manifests = join('/', $Bin, 'ovf_manifests');
|
||||
|
||||
print "parsing ovfs\n";
|
||||
|
||||
my $win2008 = eval { PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win_2008_R2_two-disks.ovf") };
|
||||
my $win2008 =
|
||||
eval { PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win_2008_R2_two-disks.ovf") };
|
||||
if (my $err = $@) {
|
||||
fail('parse win2008');
|
||||
warn("error: $err\n");
|
||||
@ -28,7 +29,8 @@ if (my $err = $@) {
|
||||
} else {
|
||||
ok('parse win10');
|
||||
}
|
||||
my $win10noNs = eval { PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win10-Liz_no_default_ns.ovf") };
|
||||
my $win10noNs =
|
||||
eval { PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win10-Liz_no_default_ns.ovf") };
|
||||
if (my $err = $@) {
|
||||
fail("parse win10 no default rasd NS");
|
||||
warn("error: $err\n");
|
||||
@ -38,26 +40,59 @@ if (my $err = $@) {
|
||||
|
||||
print "testing disks\n";
|
||||
|
||||
is($win2008->{disks}->[0]->{disk_address}, 'scsi0', 'multidisk vm has the correct first disk controller');
|
||||
is($win2008->{disks}->[0]->{backing_file}, "$test_manifests/disk1.vmdk", 'multidisk vm has the correct first disk backing device');
|
||||
is(
|
||||
$win2008->{disks}->[0]->{disk_address},
|
||||
'scsi0',
|
||||
'multidisk vm has the correct first disk controller',
|
||||
);
|
||||
is(
|
||||
$win2008->{disks}->[0]->{backing_file},
|
||||
"$test_manifests/disk1.vmdk",
|
||||
'multidisk vm has the correct first disk backing device',
|
||||
);
|
||||
is($win2008->{disks}->[0]->{virtual_size}, 2048, 'multidisk vm has the correct first disk size');
|
||||
|
||||
is($win2008->{disks}->[1]->{disk_address}, 'scsi1', 'multidisk vm has the correct second disk controller');
|
||||
is($win2008->{disks}->[1]->{backing_file}, "$test_manifests/disk2.vmdk", 'multidisk vm has the correct second disk backing device');
|
||||
is(
|
||||
$win2008->{disks}->[1]->{disk_address},
|
||||
'scsi1',
|
||||
'multidisk vm has the correct second disk controller',
|
||||
);
|
||||
is(
|
||||
$win2008->{disks}->[1]->{backing_file},
|
||||
"$test_manifests/disk2.vmdk",
|
||||
'multidisk vm has the correct second disk backing device',
|
||||
);
|
||||
is($win2008->{disks}->[1]->{virtual_size}, 2048, 'multidisk vm has the correct second disk size');
|
||||
|
||||
is($win10->{disks}->[0]->{disk_address}, 'scsi0', 'single disk vm has the correct disk controller');
|
||||
is($win10->{disks}->[0]->{backing_file}, "$test_manifests/Win10-Liz-disk1.vmdk", 'single disk vm has the correct disk backing device');
|
||||
is(
|
||||
$win10->{disks}->[0]->{backing_file},
|
||||
"$test_manifests/Win10-Liz-disk1.vmdk",
|
||||
'single disk vm has the correct disk backing device',
|
||||
);
|
||||
is($win10->{disks}->[0]->{virtual_size}, 2048, 'single disk vm has the correct size');
|
||||
|
||||
is($win10noNs->{disks}->[0]->{disk_address}, 'scsi0', 'single disk vm (no default rasd NS) has the correct disk controller');
|
||||
is($win10noNs->{disks}->[0]->{backing_file}, "$test_manifests/Win10-Liz-disk1.vmdk", 'single disk vm (no default rasd NS) has the correct disk backing device');
|
||||
is($win10noNs->{disks}->[0]->{virtual_size}, 2048, 'single disk vm (no default rasd NS) has the correct size');
|
||||
is(
|
||||
$win10noNs->{disks}->[0]->{disk_address},
|
||||
'scsi0',
|
||||
'single disk vm (no default rasd NS) has the correct disk controller',
|
||||
);
|
||||
is(
|
||||
$win10noNs->{disks}->[0]->{backing_file},
|
||||
"$test_manifests/Win10-Liz-disk1.vmdk",
|
||||
'single disk vm (no default rasd NS) has the correct disk backing device',
|
||||
);
|
||||
is(
|
||||
$win10noNs->{disks}->[0]->{virtual_size},
|
||||
2048,
|
||||
'single disk vm (no default rasd NS) has the correct size',
|
||||
);
|
||||
|
||||
print "testing nics\n";
|
||||
is($win2008->{net}->{net0}->{model}, 'e1000', 'win2008 has correct nic model');
|
||||
is($win10->{net}->{net0}->{model}, 'e1000e', 'win10 has correct nic model');
|
||||
is($win10noNs->{net}->{net0}->{model}, 'e1000e', 'win10 (no default rasd NS) has correct nic model');
|
||||
is($win10noNs->{net}->{net0}->{model}, 'e1000e',
|
||||
'win10 (no default rasd NS) has correct nic model');
|
||||
|
||||
print "\ntesting vm.conf extraction\n";
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ $ENV{TZ} = 'UTC';
|
||||
|
||||
use TAP::Harness;
|
||||
|
||||
my $harness = TAP::Harness->new( { verbosity => -1 });
|
||||
my $harness = TAP::Harness->new({ verbosity => -1 });
|
||||
my $res = $harness->runtests(
|
||||
"archive_info_test.pm",
|
||||
"parse_volname_test.pm",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user