[pve-devel] [PATCH common v3 2/3] section config: implement array support
Dominik Csapak
d.csapak at proxmox.com
Tue Jun 6 15:08:46 CEST 2023
enables section configs in the style of:
----
type: id
property value
property value2
property value3
----
can be combined with property strings
the provided create and update schema just pass through the array type
to the api, so the api call must always contain the complete array
also adds a test case for such array fields
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
src/PVE/SectionConfig.pm | 42 ++++++++++++++++++++++++++++++++-----
test/section_config_test.pl | 26 +++++++++++++++++++++++
2 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm
index f36cede..97492db 100644
--- a/src/PVE/SectionConfig.pm
+++ b/src/PVE/SectionConfig.pm
@@ -254,7 +254,15 @@ sub check_value {
if (!$skipSchemaCheck) {
my $errors = {};
- PVE::JSONSchema::check_prop($value, $schema, '', $errors);
+
+ my $checkschema = $schema;
+
+ if ($ct eq 'array') {
+ die "no item schema for array" if !defined($schema->{items});
+ $checkschema = $schema->{items};
+ }
+
+ PVE::JSONSchema::check_prop($value, $checkschema, '', $errors);
if (scalar(keys %$errors)) {
die "$errors->{$key}\n" if $errors->{$key};
die "$errors->{_root}\n" if $errors->{_root};
@@ -311,6 +319,15 @@ sub parse_config {
}
};
+ my $is_array = sub {
+ my ($type, $key) = @_;
+
+ my $schema = $pdata->{propertyList}->{$key};
+ die "unknown property type\n" if !$schema;
+
+ return $schema->{type} eq 'array';
+ };
+
my $errors = [];
while (@lines) {
my $line = $nextline->();
@@ -352,11 +369,19 @@ sub parse_config {
my ($k, $v) = ($1, $3);
eval {
- die "duplicate attribute\n" if defined($config->{$k});
- if (!$unknown) {
- $v = $plugin->check_value($type, $k, $v, $sectionId);
+ if ($is_array->($type, $k)) {
+ if (!$unknown) {
+ $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);
+ }
+ $config->{$k} = $v;
}
- $config->{$k} = $v;
};
if (my $err = $@) {
warn "$errprefix (section '$sectionId') - unable to parse value of '$k': $err";
@@ -448,6 +473,13 @@ my $format_config_line = sub {
if ($ct eq 'boolean') {
return "\t$key " . ($value ? 1 : 0) . "\n"
if defined($value);
+ } elsif ($ct eq 'array') {
+ die "property '$key' is not an array" if ref($value) ne 'ARRAY';
+ my $result = '';
+ for my $line ($value->@*) {
+ $result .= "\t$key $line\n" if $value ne '';
+ }
+ return $result;
} else {
return "\t$key $value\n" if "$value" ne '';
}
diff --git a/test/section_config_test.pl b/test/section_config_test.pl
index 22a9643..02242bc 100755
--- a/test/section_config_test.pl
+++ b/test/section_config_test.pl
@@ -105,6 +105,25 @@ sub properties {
minimum => 3,
maximum => 9,
},
+ arrayfield => {
+ description => "Array Field with property string",
+ type => 'array',
+ items => {
+ type => 'string',
+ description => 'a property string',
+ format => {
+ subfield1 => {
+ type => 'string',
+ description => 'first subfield'
+ },
+ subfield2 => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ },
+ },
+ },
};
}
@@ -113,6 +132,7 @@ sub options {
common => { optional => 1 },
field2 => {},
another => {},
+ arrayfield => { optional => 1 },
};
}
@@ -190,6 +210,10 @@ my $with_unknown_data = {
type => 'two',
field2 => 5,
another => 'even more text',
+ arrayfield => [
+ 'subfield1=test,subfield2=2',
+ 'subfield1=test2',
+ ],
},
invalid => {
type => 'bad',
@@ -214,6 +238,8 @@ bad: invalid
two: t3
field2 5
another even more text
+ arrayfield subfield1=test,subfield2=2
+ arrayfield subfield1=test2
EOF
Conf->expect_fail('unknown-forbidden', $with_unknown_data, $with_unknown_text);
--
2.30.2
More information about the pve-devel
mailing list