Today the way you associate a Compute Offering (CO) or a Disk Offering (DO) with a Primary Storage (PS) is via storage tagging.

This has some benefits and drawbacks.

One benefit is being able to have some level of vendor independence from the point of view of the CO or DO. For example, if the storage tag of a DO is "Fast", then this can be satisfied by PS that describes itself as "Fast", regardless of vendor.

A major drawback with the storage-tagging approach, however, is that you are not easily able to leverage vendor-specific features, which is often why you bought storage from the vendor in question to begin with.

Ideally we do not want to add each vendor's features into the system as properties that can be seen by the admin regardless of whether or not the underlying storage he's actually using supports the feature in question. Traditionally, however, this has been business as usual in the CloudStack codebase.

Going forward, we want to implement a more fine-grain and generic approach.

For example, in the GUI we would like to have a storage provider field for the CO and DO windows (this equates to the name of one and only one storage provider). If the admin inputs a specific storage provider, he can enter in an arbitrary number of key/value pairs in another text field (perhaps we would provide a nice entry dialog to make this easier in the GUI). These key value pairs can be passed into the storage driver when it's asked to create (or update) a volume and the storage driver can decide what each and every key/value pair means, if anything.



Use cases

  • An admin wants to ensure a root or data disk uses the plug-in of a specific storage vendor because he wants to make sure he can leverage vendor-specific properties.
  • The admin creates a Compute or Disk Offering and selects the desired storage plug-in from a combo box. The admin enters in an arbitrary collection of key/value pairs (in the following form: key=value;key=value;key=value). These keys and values are vendor specific and have no meaning to CloudStack (CloudStack simply passes them to the selected storage plug-in and the plug-in decides what, if anything, to do for each key/value pair). We will likely have a dialog in the GUI that makes entry of key/value pairs easier and less error prone than manually entering them in.
  • A user executes such a Compute or Disk Offering, which leads to the creation of a root or data disk (respectively) that was created using the storage plug-in specified in the Compute or Disk Offering and the arbitrary collection of key/value pairs, if any.

High-Level Flow Chart


New API added to PrimaryDataStoreDriver that can be returned to CloudStack clients

In order to help a UI perform checking on the value of a given key as well as what keys are applicable, we intend to add a method to the PrimaryDataStoreDriver interface with the following interface:

Map<String, String> getPropertiesAndTypes();

The key of the returned map is a String representing a given property that is supported by the plug-in. For example, "burstIops". These are vendor specific and have no meaning to CloudStack.

The value of the returned map is a String representing the type of the property. For example, "Integer", "Float", "String". All supported types will be listed as public static final member variables in the PrimaryDataStoreDriver interface.

Example output:

[ ("burstIops", "String"), ("replicas", "Integer") ]

A new API will be added to CloudStack that returns such a map for a given storage plug-in. With the above information, a UI could display to the admin all applicable properties and perform basic type checking on assigned values based on returned types.

GUI changes

Two GUI windows will need to be modified: Add Compute Offering and Add Disk Offering.

In each case, two fields need to be added: 1) a combo box that allows the end user to pick a storage plug-in and 2) a text field which specifies key/value pairs delimited by a semi-colon.

The GUI will likely provide a helper dialog to list all applicable properties for a given storage plug-in as well as performing basic verification of input based on the type the property is (ex. Integer).

Database changes

We will need to add two columns to the cloud.disk_offering table: provider and custom_properties.

The provider value should match one of the provider values in the storage_pool table.

The custom_properties value should be of the following format: key_1=value_1;key_2=value_2;key_3=value_3...key_n=value_n

Existing interface changes

In the PrimaryDataStoreDriver interface, we will need to change the following API:


public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback)


public void createAsync(DataStore dataStore, DataObject dataObject, Map<String, String> customProperties, AsyncCompletionCallback<CreateCmdResult> callback)

Any code in the CloudStack codebase can be changed as part of this process. However, at least one plug-in (from NetApp) does not have its code in the CloudStack codebase, so this is a reminder for me to e-mail them and ask them to make this change.


  • No labels