]> git.proxmox.com Git - pve-common.git/commitdiff
SectionConfig: fix handling unknown sections
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 16 Aug 2023 09:09:11 +0000 (11:09 +0200)
committerFiona Ebner <f.ebner@proxmox.com>
Wed, 16 Aug 2023 09:19:26 +0000 (11:19 +0200)
if we're parsing an unknown section, we cannot check the schema with
`is_array` to check if it's an array type or not, thus we have to
handle that separately.

fix this by handling data in unknown sections like an array similar to
"cb2646c7b4974e33f4148752deec71f0d589b0f3" in proxmox-section-config.
This way we can write unknown section out again like we parsed it.

Add a regression test for an unknown field not in the schema.

This fixes an issue, where calling `qm destroy ID --purge` removed much
of the configs ob backup jobs (since there we parse an 'unknown' section
and run into the `is_array` error)
(Reported in the forum: https://forum.proxmox.com/threads/132091)

Suggested-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
src/PVE/SectionConfig.pm
test/section_config_test.pl

index 2b75e6a8cc94d0737a18743625b0b0ca895d6079..569047640cbee770bb1fa2a07fa997d6921b0b3c 100644 (file)
@@ -369,17 +369,22 @@ sub parse_config {
                    my ($k, $v) = ($1, $3);
 
                    eval {
-                       if ($is_array->($type, $k)) {
-                           if (!$unknown) {
-                               $v = $plugin->check_value($type, $k, $v, $sectionId);
+                       if ($unknown) {
+                           if (!defined($config->{$k})) {
+                               $config->{$k} = $v;
+                           } else {
+                               if (!ref($config->{$k})) {
+                                   $config->{$k} = [$config->{$k}];
+                               }
+                               push $config->{$k}->@*, $v;
                            }
+                       } elsif ($is_array->($type, $k)) {
+                           $v = $plugin->check_value($type, $k, $v, $sectionId);
                            $config->{$k} = [] if !defined($config->{$k});
                            push $config->{$k}->@*, $v;
                        } else {
                            die "duplicate attribute\n" if defined($config->{$k});
-                           if (!$unknown) {
-                               $v = $plugin->check_value($type, $k, $v, $sectionId);
-                           }
+                           $v = $plugin->check_value($type, $k, $v, $sectionId);
                            $config->{$k} = $v;
                        }
                    };
@@ -525,7 +530,12 @@ sub write_config {
                next if defined($done_hash->{$k});
                $done_hash->{$k} = 1;
                my $v = $scfg->{$k};
-               $data .= "\t$k $v\n";
+               my $ref = ref($v);
+               if (defined($ref) && $ref eq 'ARRAY') {
+                   $data .= "\t$k $_\n" for $v->@*;
+               } else {
+                   $data .= "\t$k $v\n";
+               }
            }
            $out .= "$data\n";
            next;
index 02242bc85b4e0312614eb65617ccdc2d1e45e118..ccb364d6f0c66149f740ba7c79bf290764ed51d9 100755 (executable)
@@ -218,6 +218,7 @@ my $with_unknown_data = {
        invalid => {
            type => 'bad',
            common => 'omg',
+           unknownfield => 'shouldnotbehere',
        },
     },
     order => enum(qw(t1 t2 invalid t3)),
@@ -234,6 +235,7 @@ one: t2
 
 bad: invalid
        common omg
+       unknownfield shouldnotbehere
 
 two: t3
        field2 5