diff --git a/perl5/PVE/Storage/Custom/TrueNAS.pm b/perl5/PVE/Storage/Custom/TrueNAS.pm index 871413e..3f42242 100644 --- a/perl5/PVE/Storage/Custom/TrueNAS.pm +++ b/perl5/PVE/Storage/Custom/TrueNAS.pm @@ -424,6 +424,12 @@ sub parse_volname { return ('images', $volname, $vmid, undef, undef, $isBase, 'raw'); } + # Cloud-init drive: vm--cloudinit, or base--cloudinit once the + # VM is converted to a template. alloc_image already creates these (#294). + if ($volname =~ /^(vm|base)-(\d+)-cloudinit$/) { + return ('images', $volname, $2, undef, undef, ($1 eq 'base' ? 1 : 0), 'raw'); + } + # RAM snapshot state volume: vm--state- # PVE allocates one of these per snapshot when "Include RAM" is selected. if ($volname =~ /^vm-(\d+)-state-.+$/) { diff --git a/t/volname.t b/t/volname.t new file mode 100644 index 0000000..63c7f5c --- /dev/null +++ b/t/volname.t @@ -0,0 +1,42 @@ +#!/usr/bin/perl +# parse_volname: every volume name the plugin (or PVE on its behalf) creates +# must parse, or later operations on it (destroy, resize, regenerate) fail. + +use strict; +use warnings; + +use FindBin; +use lib "$FindBin::Bin/lib", "$FindBin::Bin/../perl5"; + +use Test::More; + +use PVE::Storage::Custom::TrueNAS; + +my $TN = 'PVE::Storage::Custom::TrueNAS'; + +my @ok = ( + # volname vmid isBase + [ 'vm-100-disk-0', 100, 0 ], + [ 'base-9000-disk-1', 9000, 1 ], + [ 'vm-100-state-pre_upg', 100, 0 ], + [ 'vm-9100-cloudinit', 9100, 0 ], # #294 + [ 'base-9000-cloudinit', 9000, 1 ], # #294 +); + +for my $case (@ok) { + my ($volname, $vmid, $isBase) = @$case; + my @r = eval { $TN->parse_volname($volname) }; + is($@, '', "$volname parses"); + is($r[0], 'images', "$volname vtype"); + is($r[1], $volname, "$volname name"); + is($r[2], $vmid, "$volname owner"); + is($r[5], $isBase, "$volname isBase"); + is($r[6], 'raw', "$volname format"); +} + +for my $bad (qw(vm-100 vm-abc-disk-0 vm-100-cloudinit.qcow2 subvol-100-disk-0 ../vm-100-disk-0)) { + eval { $TN->parse_volname($bad) }; + like($@, qr/unable to parse/, "$bad rejected"); +} + +done_testing();