[pve-devel] API - GET /nodes/{node}/storage

Andreas Steinel a.steinel at gmail.com
Tue Apr 17 14:02:23 CEST 2018


Thank you Fabian for the in depth analysis.

I tried to use the json representation of the API in order to
automatically extract the schema definitions for a consuming API that
generates the code based on the found definitions of all elements.
This works fine most of the time but failed in this case - maybe
others, yet I only tried a subset of the API. I'm going to switch back
to interfacing and checking the API manually, which also works.

Thanks again for the explanation.

On Tue, Apr 17, 2018 at 8:43 AM, Fabian Grünbichler
<f.gruenbichler at proxmox.com> wrote:
> On Mon, Apr 16, 2018 at 06:03:58PM +0200, Andreas Steinel wrote:
>> Hi all,
>>
>> I tried to access the storage API and looked through [1] to find, that the
>>
>> GET /nodes/{node}/storage
>>
>> returns an array of string according to [2] the excerpt is:
>>
>> "GET" : {
>>    "description" : "Get status for all datastores.",
>>    "method" : "GET",
>>    "name" : "index",
>>    "parameters" : {
>>       "additionalProperties" : 0,
>>       "properties" : {
>>          "content" : {
>>             "description" : "Only list stores which support this content type.",
>>             "format" : "pve-storage-content-list",
>>             "optional" : 1,
>>             "type" : "string",
>>             "typetext" : "<string>"
>>          },
>>          "enabled" : {
>>             "default" : 0,
>>             "description" : "Only list stores which are enabled (not
>> disabled in config).",
>>             "optional" : 1,
>>             "type" : "boolean",
>>             "typetext" : "<boolean>"
>>          },
>>          "node" : {
>>             "description" : "The cluster node name.",
>>             "format" : "pve-node",
>>             "type" : "string",
>>             "typetext" : "<string>"
>>          },
>>          "storage" : {
>>             "description" : "Only list status for  specified storage",
>>             "format" : "pve-storage-id",
>>             "optional" : 1,
>>             "type" : "string",
>>             "typetext" : "<string>"
>>          },
>>          "target" : {
>>             "description" : "If target is different to 'node', we only
>> lists shared storages which content is accessible on this 'node' and
>> the specified 'target' node.",
>>             "format" : "pve-node",
>>             "optional" : 1,
>>             "type" : "string",
>>             "typetext" : "<string>"
>>          }
>>       }
>>    },
>>    "permissions" : {
>>       "description" : "Only list entries where you have
>> 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on
>> '/storage/<storage>'",
>>       "user" : "all"
>>    },
>>    "protected" : 1,
>>    "proxyto" : "node",
>>    "returns" : {
>>       "items" : {
>>          "properties" : {
>>             "storage" : {
>>                "type" : "string"
>>             }
>>          },
>>          "type" : "object"
>>       },
>>       "links" : [
>>          {
>>             "href" : "{storage}",
>>             "rel" : "child"
>>          }
>>       ],
>>       "type" : "array"
>>    }
>> }
>>
>> The return type is a bit more complex:
>
> in PVE's JSONSchema, unless "additionalProperties" is set to false, the
> list of properties is not exhaustive. in this case, we have an 'object'
> that has at least the property "storage" of type "string" - the rest is
> up to the storage plugin. the reason that the "storage" property is
> explicitly defined (besides the fact that it is the only guarantueed
> one) is that the "/nodes/{NODE}/storage/{STORAGE}" API path is defined
> for each of the returned storages, as indicated by the "links" member of
> the "returns" hash.
>
>>
>> root at pve-5-apitest:~# pvesh get /nodes/pve-5-apitest/storage
>> 200 OK
>> [
>>    {
>>       "active" : 1,
>>       "avail" : 23488102400,
>>       "content" : "rootdir,images",
>>       "enabled" : 1,
>>       "shared" : 0,
>>       "storage" : "local-lvm",
>>       "total" : 23488102400,
>>       "type" : "lvmthin",
>>       "used" : 0
>>    },
>>    {
>>       "active" : 1,
>>       "avail" : 2546470912,
>>       "content" : "iso,vztmpl,backup",
>>       "enabled" : 1,
>>       "shared" : 0,
>>       "storage" : "local",
>>       "total" : 4160421888,
>>       "type" : "dir",
>>       "used" : 1382428672
>>    }
>> ]
>>
>> Yet I did not find any format description of this. The API in [1] does
>> e.g. contain only two times the attribute "used" is only found two
>> times, and neither does apply here. Could you point me to the place
>> where it is defined?
>
> the API endpoint is in [1], as you can see it calls
> PVE::Storage::storage_info() and then filters the result based on
> permissions and given parameters. as can be seen in [2], this method in
> turn calls $plugin->status() for each configured storage (via the
> storage type's plugin):
>
> 1069 eval { ($total, $avail, $used, $active) = $plugin->status($storeid, $scfg, $cache); };
> 1070 warn $@ if $@;
> 1071 next if !$active;
> 1072 $info->{$storeid}->{total} = int($total);
> 1073 $info->{$storeid}->{avail} = int($avail);
> 1074 $info->{$storeid}->{used} = int($used);
> 1075 $info->{$storeid}->{active} = $active;
>
> so in fact the 'returns' schema in the API call could be extended to
> mention these four values as well, since there is no possibility for
> storage plugins to provide their own, custom fields. it might make sense
> to make sure "active" is a boolean (e.g., via "$active ? 1 : 0") and
> specify it accordingly.
>
> a bit earlier in the same method, we have the following initialization
> of $info:
>
> 1031 $info->{$storeid} = {
> 1032     type => $type,
> 1033     total => 0,
> 1034     avail => 0,
> 1035     used => 0,
> 1036     shared => $ids->{$storeid}->{shared} ? 1 : 0,
> 1037     content => PVE::Storage::Plugin::content_hash_to_string($ids->{$storeid}->{content}),
> 1038     active => 0,
> 1039     enabled => $storage_enabled ? 1 : 0,
> 1040 };
>
> so we in fact have another 4 well-defined values which come from the
> config directly, bringing the total up to:
>
> total: int
> used: int
> avail: int
> enabled: boolean
> active:boolean (needs to be ensured!)
> shared: boolean
> type: string (see below)
> content: string (with format 'pve-storage-content-list')
>
> all of those are defined in the base plugin (PVE/Storage/Plugin.pm),
> except for "type", which is actually part of the underlying config
> module (pve-common/src/PVE/SectionConfig.pm), where it is defined as
> 'string' with the 'enum' property set to all registered plugin types -
> since those are actually returned by each plugin's "type()" method, and
> custom third-party plugins are supported, we probably don't want to
> overspecify it and a plain "string" is good enough for now.
>
> (hint, patches welcome ;))
>
> 1: https://git.proxmox.com/?p=pve-storage.git;a=blob;f=PVE/API2/Storage/Status.pm;h=ab07146caa8612333e0e5a843df47821c9ecb30e;hb=HEAD#l82
> 2: https://git.proxmox.com/?p=pve-storage.git;a=blob;f=PVE/Storage.pm;h=4140a9993eafa6e539c985174272f3c7c7f68277;hb=HEAD#l1005
>
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



-- 
With kind regards / Mit freundlichen Grüßen

Andreas Steinel
M.Sc. Visual Computing
M.Sc. Informatik



More information about the pve-devel mailing list