public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 common 2/3] section config: implement array support
Date: Fri, 12 May 2023 14:23:49 +0200	[thread overview]
Message-ID: <20230512122355.3244212-3-d.csapak@proxmox.com> (raw)
In-Reply-To: <20230512122355.3244212-1-d.csapak@proxmox.com>

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@proxmox.com>
---
changes from v1:
* don't special encode arrays anymore, but instead have always the whole
  array as parameter in the create/updateSchema
 src/PVE/SectionConfig.pm    | 64 +++++++++++++++++++++++++++----------
 test/section_config_test.pl | 26 +++++++++++++++
 2 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm
index f36cede..03f6a52 100644
--- a/src/PVE/SectionConfig.pm
+++ b/src/PVE/SectionConfig.pm
@@ -51,6 +51,17 @@ sub plugindata {
     return {};
 }
 
+my $copy_property = sub {
+    my ($src) = @_;
+
+    my $res = {};
+    foreach my $k (keys %$src) {
+	$res->{$k} = $src->{$k};
+    }
+
+    return $res;
+};
+
 sub createSchema {
     my ($class, $skip_type) = @_;
 
@@ -60,17 +71,6 @@ sub createSchema {
 
     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) {
 	next if $skip_type && $p eq 'type';
 
@@ -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





  parent reply	other threads:[~2023-05-12 12:24 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-12 12:23 [pve-devel] [PATCH common/manager/http/guest/qemu-server] schema/config " Dominik Csapak
2023-05-12 12:23 ` [pve-devel] [PATCH common 1/3] JSONSchema: add support for array parameter in api calls, cli and config Dominik Csapak
2023-06-05  8:36   ` Wolfgang Bumiller
2023-05-12 12:23 ` Dominik Csapak [this message]
2023-05-15  9:07   ` [pve-devel] [PATCH v2 common 2/3] section config: implement array support Wolfgang Bumiller
2023-05-15  9:19     ` Dominik Csapak
2023-05-12 12:23 ` [pve-devel] [PATCH common 3/3] JSONSchema: disable '-alist' format Dominik Csapak
2023-06-05  8:36   ` Wolfgang Bumiller
2023-05-12 12:23 ` [pve-devel] [PATCH manager 1/1] vzdump: prepare 'exclude-path' for array format Dominik Csapak
2023-06-05  7:36   ` Wolfgang Bumiller
2023-06-05  7:54     ` Dominik Csapak
2023-06-05  7:59       ` Wolfgang Bumiller
2023-06-05  8:03   ` [pve-devel] applied: " Wolfgang Bumiller
2023-05-12 12:23 ` [pve-devel] [PATCH http-server 1/2] proxy request: forward json content type and parameters Dominik Csapak
2023-06-05  8:42   ` Wolfgang Bumiller
2023-05-12 12:23 ` [pve-devel] [PATCH http-server 2/2] use proper arrays for array parameter Dominik Csapak
2023-05-12 12:23 ` [pve-devel] [PATCH guest-common 1/1] vzdump: change 'exclude-path' from alist to an array format Dominik Csapak
2023-06-05  8:37   ` [pve-devel] [PATCH guest-common 1/1] vzdump: change 'exclude-path' from alist to an array formaty Wolfgang Bumiller
2023-05-12 12:23 ` [pve-devel] [PATCH qemu-server 1/1] api: switch agent api call to 'array' type Dominik Csapak
2023-06-05  8:38   ` Wolfgang Bumiller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230512122355.3244212-3-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal