X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2FPVE%2FSectionConfig.pm;h=a760459276249506e52054675eeeaa3a7bb9ce13;hb=e1fbb779f7dc04be6e8925e790879b770adf0d2a;hp=6f85b228b81ec82c77d64fbbbc8f0197e5274e01;hpb=ebd2b0aca54022f80abfbea0167d1ac2143f4771;p=pve-common.git diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm index 6f85b22..a760459 100644 --- a/src/PVE/SectionConfig.pm +++ b/src/PVE/SectionConfig.pm @@ -44,14 +44,14 @@ sub properties { sub options { return {}; -} +} sub plugindata { return {}; -} +} sub createSchema { - my ($class) = @_; + my ($class, $skip_type) = @_; my $pdata = $class->private(); my $propertyList = $pdata->{propertyList}; @@ -71,6 +71,8 @@ sub createSchema { }; foreach my $p (keys %$propertyList) { + next if $skip_type && $p eq 'type'; + if (!$propertyList->{$p}->{optional}) { $props->{$p} = $propertyList->{$p}; next; @@ -104,7 +106,7 @@ sub createSchema { } sub updateSchema { - my ($class) = @_; + my ($class, $single_class) = @_; my $pdata = $class->private(); my $propertyList = $pdata->{propertyList}; @@ -112,8 +114,15 @@ sub updateSchema { my $props = {}; + my $filter_type = $class->type() if $single_class; + foreach my $p (keys %$propertyList) { next if $p eq 'type'; + + my $copts = $class->options(); + + next if defined($filter_type) && !defined($copts->{$p}); + if (!$propertyList->{$p}->{optional}) { $props->{$p} = $propertyList->{$p}; next; @@ -121,7 +130,6 @@ sub updateSchema { my $modifyable = 0; - my $copts = $class->options(); $modifyable = 1 if defined($copts->{$p}) && !$copts->{$p}->{fixed}; foreach my $t (keys %$plugins) { @@ -184,7 +192,7 @@ sub init { } $propertyList->{type}->{type} = 'string'; - $propertyList->{type}->{enum} = [keys %$plugins]; + $propertyList->{type}->{enum} = [sort keys %$plugins]; } sub lookup { @@ -202,8 +210,8 @@ sub lookup_types { my ($class) = @_; my $pdata = $class->private(); - - return [ keys %{$pdata->{plugins}} ]; + + return [ sort keys %{$pdata->{plugins}} ]; } sub decode_value { @@ -226,7 +234,7 @@ sub check_value { return $value if $key eq 'type' && $type eq $value; my $opts = $pdata->{options}->{$type}; - die "unknown section type '$type'\n" if !$opts; + die "unknown section type '$type'\n" if !$opts; die "unexpected property '$key'\n" if !defined($opts->{$key}); @@ -251,6 +259,10 @@ sub check_value { } } + if ($ct eq 'boolean' || $ct eq 'integer' || $ct eq 'number') { + return $value + 0; # convert to number + } + return $value; } @@ -267,7 +279,7 @@ sub parse_section_header { } sub format_section_header { - my ($class, $type, $sectionId) = @_; + my ($class, $type, $sectionId, $scfg, $done_hash) = @_; return "$type: $sectionId\n"; } @@ -284,19 +296,22 @@ sub parse_config { $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) { + while (defined(my $line = shift @lines)) { $lineno++; - return $line if $line !~ /^\s*(?:#|$)/; + return $line if ($line !~ /^\s*#/); } }; - while (my $line = &$nextline()) { + while (@lines) { + my $line = $nextline->(); + next if !$line; + my $errprefix = "file $filename line $lineno"; my ($type, $sectionId, $errmsg, $config) = $class->parse_section_header($line); @@ -326,7 +341,7 @@ sub parse_config { if ($line =~ m/^\s+(\S+)(\s+(.*\S))?\s*$/) { my ($k, $v) = ($1, $3); - + eval { die "duplicate attribute\n" if defined($config->{$k}); $config->{$k} = $plugin->check_value($type, $k, $v, $sectionId); @@ -367,10 +382,10 @@ sub check_config { foreach my $k (keys %$config) { my $value = $config->{$k}; - + die "can't change value of fixed parameter '$k'\n" - if !$create && $opts->{$k}->{fixed}; - + if !$create && defined($opts->{$k}) && $opts->{$k}->{fixed}; + if (defined($value)) { my $tmp = $class->check_value($type, $k, $value, $sectionId, $skipSchemaCheck); $settings->{$k} = $class->decode_value($type, $k, $tmp); @@ -400,7 +415,8 @@ my $format_config_line = sub { if ($key =~ m/[\n\r]/) || ($value =~ m/[\n\r]/); if ($ct eq 'boolean') { - return $value ? "\t$key\n" : ''; + return "\t$key " . ($value ? 1 : 0) . "\n" + if defined($value); } else { return "\t$key $value\n" if "$value" ne ''; } @@ -419,13 +435,13 @@ sub write_config { my $maxpri = 0; foreach my $sectionId (keys %$ids) { - my $pri = $order->{$sectionId}; + my $pri = $order->{$sectionId}; $maxpri = $pri if $pri && $pri > $maxpri; } foreach my $sectionId (keys %$ids) { if (!defined ($order->{$sectionId})) { $order->{$sectionId} = ++$maxpri; - } + } } foreach my $sectionId (sort {$order->{$a} <=> $order->{$b}} keys %$ids) { @@ -435,18 +451,23 @@ sub write_config { die "unknown section type '$type'\n" if !$opts; - my $data = $class->format_section_header($type, $sectionId); - if ($scfg->{comment}) { + my $done_hash = {}; + + my $data = $class->format_section_header($type, $sectionId, $scfg, $done_hash); + if ($scfg->{comment} && !$done_hash->{comment}) { my $k = 'comment'; my $v = $class->encode_value($type, $k, $scfg->{$k}); $data .= &$format_config_line($propertyList->{$k}, $k, $v); } - $data .= "\tdisable\n" if $scfg->{disable}; + $data .= "\tdisable\n" if $scfg->{disable} && !$done_hash->{disable}; - my $done_hash = { comment => 1, disable => 1}; + $done_hash->{comment} = 1; + $done_hash->{disable} = 1; - foreach my $k (keys %$opts) { + my @option_keys = sort keys %$opts; + foreach my $k (@option_keys) { + next if defined($done_hash->{$k}); next if $opts->{$k}->{optional}; $done_hash->{$k} = 1; my $v = $scfg->{$k}; @@ -456,7 +477,7 @@ sub write_config { $data .= &$format_config_line($propertyList->{$k}, $k, $v); } - foreach my $k (keys %$opts) { + foreach my $k (@option_keys) { next if defined($done_hash->{$k}); my $v = $scfg->{$k}; next if !defined($v);