support aliases in property strings
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 15 Oct 2015 10:35:18 +0000 (12:35 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 15 Oct 2015 10:36:07 +0000 (12:36 +0200)
In qemu the 'volume' key maps to 'file', both can be used,
so to support this case in the comma-separated property
list parser we need a way to alias keys to one another.
This allows declaring a key like:

  volume => {
      alias => 'file'
  }
  file => {
      type => 'string',
      format => 'pve-volume-id',
      default_key => 1,
      format_description => 'volume'
  }

With this the following property strings are equivalent and
result in the same datastructure being returned from
parse_property_string:

  local:disk.raw
  file=local:disk.raw
  volume=local:disk.raw

src/PVE/JSONSchema.pm
src/PVE/PodParser.pm

index 09ed6b1..817ff4c 100644 (file)
@@ -500,6 +500,10 @@ sub parse_property_string {
            my ($k, $v) = ($1, $2);
            die "duplicate key in comma-separated list property: $k\n" if defined($res->{$k});
            my $schema = $format->{$k};
+           if (my $alias = $schema->{alias}) {
+               $k = $alias;
+               $schema = $format->{$k};
+           }
            die "invalid key in comma-separated list property: $k\n" if !$schema;
            if ($schema->{type} && $schema->{type} eq 'boolean') {
                $v = 1 if $v =~ m/^(1|on|yes|true)$/i;
@@ -553,7 +557,7 @@ sub print_property_string {
     my %required; # this is a set, all present keys are required regardless of value
     foreach my $key (keys %$format) {
        $allowed{$key} = 1;
-       if (!$format->{$key}->{optional} && !$skipped{$key}) {
+       if (!$format->{$key}->{optional} && !$format->{$key}->{alias} && !$skipped{$key}) {
            $required{$key} = 1;
        }
 
@@ -810,7 +814,7 @@ sub check_prop {
 
     if (!defined ($value)) {
        return if $schema->{type} && $schema->{type} eq 'null';
-       if (!$schema->{optional}) {
+       if (!$schema->{optional} && !$schema->{alias}) {
            add_error($errors, $path, "property is missing and it is not optional");
        }
        return;
@@ -1048,6 +1052,11 @@ my $default_schema_noref = {
            optional => 1,
            description => "Whether this is the default key in a comma separated list property string.",
        },
+       alias => {
+           type => 'string',
+           optional => 1,
+           description => "When a key represents the same property as another it can be an alias to it, causing the parsed datastructure to use the other key to store the current value under.",
+       },
        default => {
            type => "any",
            optional => 1,
index eb443bd..f61317b 100644 (file)
@@ -62,6 +62,10 @@ sub generate_typetext {
        my ($key) = @_;
        $typetext .= $pre;
        my $entry = $schema->{$key};
+       if (my $alias = $entry->{alias}) {
+           $key = $alias;
+           $entry = $schema->{$key};
+       }
        if (my $desc = $entry->{format_description}) {
            $typetext .= $entry->{default_key} ? "[$key=]" : "$key=";
            $typetext .= "<$desc>";