createSchema: include type property
[pve-common.git] / src / PVE / SectionConfig.pm
index 06ebbe7..71d296e 100644 (file)
@@ -52,11 +52,51 @@ sub createSchema {
 
     my $pdata = $class->private();
     my $propertyList = $pdata->{propertyList};
+    my $plugins = $pdata->{plugins};
+
+    my $props = {};
+
+    my $copy_property = sub {
+       my ($src) = @_;
+
+       my $res = {};
+       foreach my $k (keys %$src) {
+           $res->{$k} = $src->{$k};
+       }
+
+       return $res;
+    };
+
+    foreach my $p (keys %$propertyList) {
+       if (!$propertyList->{$p}->{optional}) {
+           $props->{$p} = $propertyList->{$p};
+           next;
+       }
+
+       my $required = 1;
+
+       my $copts = $class->options();
+       $required = 0 if defined($copts->{$p}) && $copts->{$p}->{optional};
+
+       foreach my $t (keys %$plugins) {
+           my $opts = $pdata->{options}->{$t} || {};
+           $required = 0 if !defined($opts->{$p}) || $opts->{$p}->{optional};
+       }
+
+       if ($required) {
+           # make a copy, because we modify the optional property
+           my $res = &$copy_property($propertyList->{$p});
+           $res->{optional} = 0;
+           $props->{$p} = $res;
+       } else {
+           $props->{$p} = $propertyList->{$p};
+       }
+    }
 
     return {
        type => "object",
        additionalProperties => 0,
-       properties => $propertyList,
+       properties => $props,
     };
 }
 
@@ -75,13 +115,20 @@ sub updateSchema {
            $props->{$p} = $propertyList->{$p};
            next;
        }
+
+       my $modifyable = 0;
+
+       my $copts = $class->options();
+       $modifyable = 1 if defined($copts->{$p}) && !$copts->{$p}->{fixed};
+
        foreach my $t (keys %$plugins) {
-           my $opts = $pdata->{options}->{$t};
+           my $opts = $pdata->{options}->{$t} || {};
            next if !defined($opts->{$p});
-           if (!$opts->{$p}->{fixed}) {
-               $props->{$p} = $propertyList->{$p};
-           }
+           $modifyable = 1 if !$opts->{$p}->{fixed};
        }
+       next if !$modifyable;
+
+       $props->{$p} = $propertyList->{$p};
     }
 
     $props->{digest} = get_standard_option('pve-config-digest');
@@ -231,19 +278,22 @@ sub parse_config {
     my $ids = {};
     my $order = {};
 
-    my $digest = Digest::SHA::sha1_hex(defined($raw) ? $raw : '');
+    $raw = '' if !defined($raw);
+
+    my $digest = Digest::SHA::sha1_hex($raw);
     
     my $pri = 1;
 
     my $lineno = 0;
+    my @lines = split(/\n/, $raw);
+    my $nextline = sub {
+       while (my $line = shift @lines) {
+           $lineno++;
+           return $line if $line !~ /^\s*(?:#|$)/;
+       }
+    };
 
-    while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
-       my $line = $1;
-       $lineno++;
-
-       next if $line =~ m/^\#/;
-       next if $line =~ m/^\s*$/;
-
+    while (my $line = &$nextline()) {
        my $errprefix = "file $filename line $lineno";
 
        my ($type, $sectionId, $errmsg, $config) = $class->parse_section_header($line);
@@ -266,13 +316,7 @@ sub parse_config {
                }
            }
 
-           while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
-               $line = $1;
-               $lineno++;
-
-               next if $line =~ m/^\#/;
-               last if $line =~ m/^\s*$/;
-
+           while ($line = &$nextline()) {
                next if $ignore; # skip
 
                $errprefix = "file $filename line $lineno";