[virt-tools-list] Re: libosinfo - another try

Cole Robinson crobinso at redhat.com
Thu Oct 22 15:47:25 UTC 2009


On 10/22/2009 05:47 AM, Arjun Roy wrote:

cc-ing a few other folks (rjones, mdbooth)

> Hi all,
> 
> I know there's been some discussion in months past for replacing the OS metadata
> currently stored as a python dict in virtinst, so it can be used by various
> virt applications.
> 

Thanks for picking this up! Some comments inline:

> I refer to Cole Robinson's initial draft of an API called libosinfo linked here:
> 
> http://www.mail-archive.com/et-mgmt-tools@redhat.com/msg02673.html
> 
> While there was a significant amount of discussion on it, there doesn't seem to
> be any progress made on the front so I thought I'd present a refined API for
> consideration.
> 
> Unlike Cole, I haven't done any implementation or figured out any implementation
> details at all. I'm just throwing some ideas out there, based on what the
> previous discussion came up with:
> 
> The basic idea would be as follows:
> 
> 1. All the data stored right now as a python dict would be replaced with a
> collection of xml (or any other kind of markup that works) file encoding the
> same data.
> 2. The data would *not* contain a fixed hierarchy - ie. we wouldn't have a tag
> for vendor followed by a tag for distro, etc. Instead, the data would consist of
> a flat set of distros, with several properties such as vendor or version (etc.)
> that would allow an application using the API to impose any arbitrary sort of
> hierarchy on the data.
> 
> What follows is my take on what form the API and data representation scheme
> could look like:
> 
> ________________________________________
> 
> Data Representation Schema
> ________________________________________
> 
> The primary storage record would be the <distro>. It would consist of a required
> ID, and one or more optional attributes.
> 
> There would be two kinds of attributes:
> 
> 1. Structure Attributes
> 
> These attributes would encode possible relationships between distros. Proposed
> attributes would be:
> <derives-from>
> <clones>
> <upgrades>
> 
> So one could have the following:
> <distro ID=1>
>   <name>Fedora 10</name>
> </distro>
> 
> <distro ID=2>
>   <name>Fedora 11</name>
>   <upgrades ID=1 />
> </distro>
> 

If we are going to use 'ID' here as the unique identifier, I think it
should have some human readable value. Just using numbers will quickly
become confusing if manually navigating the XML.

In the previous discussion, someone mentioned just using <name> as the
unique identifier, however I don't think that is sufficient either,
since it is not very machine friendly. Something like

"Fedora 12" -> "fedora12"
"Red Hat Enterprise Linux 5.4" -> "rhel5.4" or
                                  "red_hat_enterprise_linux_5.4"

Think of using this value from the command line (like virt-install
--os-variant), no one is going to want to have to use spaces and proper
capitalization, or a plain digit.

> This would effectively force our view of the data as a graph, where the set of
> nodes are the set of distros and the edges are described by the structure
> attribute tags. (With a different graph resulting depending on attribute)
> 
> 2. Informative Attributes
> This could refer to things such as name, kernel-type, architecture, or anything
> else that would be useful to track. I suspect that it would be alright to limit
> the kind of data to strings (kernel : linux) and version numbers 
> (kernel-version: 2.6.30).
> 

I kind of wonder if the 'version' distinction is even necessary, but I
don't think I could say for certain until we start trying to use the code.

> In other words, we'd end up with a schema like this:
> <distro ID=2>
>   <upgrades ID=1 />
>   <name type=str>Fedora 11</name>
>   <kernel type=str>linux</kernel>
>   <kernel-version type=ver>2.6.30</kernel-version>
> </distro>
> 
> ________________________________________
> 
> API
> ________________________________________
> 
> 
> The library would be implemented in C, and define a few major types:
> 
> osi_lib_t : an opaque handle to a library instance.
> osi_distro_t : represents a distro object.
> osi_distro_id_t : represents the unique ID for a distro.
> osi_distro_list_t : a list of osi_distro_t objects.
> osi_filter_t: filter for searching through distros.
> 
> And a bunch of methods:
> 
> osi_lib_t osi_getLibHandle();
> 
> /* Setting parameters like libvirt version, etc. */
> int osi_setLibParam(osi_lib_t lib, cstring key, cstring val);
> int osi_getLibParam(osi_lib_t lib, cstring key);
> 
> /* Initializing and closing down the library */
> int osi_initLib(osi_lib_t lib);
> int osi_closeLib(osi_lib_t lib);
> 
> /* Querying for distros and iterating over them */
> osi_distro_list_t osi_getDistrosList(osi_lib_t lib, osi_distro_filter_t filter);
> int osi_putDistrosList(osi_distro_list_t distros);
> int osi_distroListLength(osi_distro_list_t distros);
> 
> /* Methods for filtering results when querying distros */
> osi_filter_t osi_getFilter(osi_lib_t lib);
> int osi_putFilter(osi_filter_t filter);
> int osi_addStringPropertyConstraint(osi_filter_t filter, cstring propName, cstring propVal);
> int osi_addVersionPropertyConstraint(osi_filter_t filter, cstring propName, cstring propVal, enum_t ordering);
> int osi_addLinkedDistroConstraint(osi_filter_t filter, enum_t relationship, os_distro_t distro);
> int osi_clearStringPropertyConstraint(osi_filter_t filter, cstring propName);
> int osi_clearVersionPropertyConstraint(osi_filter_t filter, cstring propName);
> int osi_clearLinkedDistroConstraint(osi_filter_t filter, enum_t relationship);

I think all these calls mean we should break out an 'osi_prop_t'. This
way, we only have one call for addProp, clearProp, getProp, and then a
set of methods to manipulate properties.

Not sure how the implementation details would work out.

> int osi_clearAllConstraints(osi_filter_t filter);
> 
> /* Get a single distro, either from a list or by ID */
> osi_distro_t osi_getDistroByIndex(osi_distro_list_t distros, int index);
> osi_distro_t osi_getDistroById(osi_lib_t lib, osi_distro_id_t id);
> 
> /* Query Properties for a given distro */
> osi_distro_id_t osi_getDistroId(osi_distro_t distro);
> osi_distro_t osi_getLinkedDistro(osi_distro_t distro, enum_t relationship);
> cstring osi_getStringProperty(osi_distro_t distro, cstring propName);
> cstring osi_getVersionProperty(osi_distro_t distro, cstring propName);
> cstring** osi_getAllStringProperties(osi_distro_t distro);
> cstring** osi_getAllVersionProperties(osi_distro_t distro);
> 
> /* Query unique values for a given property */
> cstring *osi_uniqueStringPropertyValues(osi_lib_t lib, cstring propName);
> cstring *osi_uniqueVersionPropertyValues(osi_lib_t lib, cstring propName);
> os_distro_list_t osi_uniqueLinkedDistroValues(osi_lib_t lib, enum_t relationship);
> 
> The general usage is as follows. 
> -We get a library handle, set some parameters like libvirt version and 
> hypervisor type, and initialize it. 
> -We can then get a filter object, configure it to search for all distros with a 
> 'linux' kernel attribute that have kernel version < 2.6.30 that derive from 
> RHEL 5.4.
> -Then we can query other properties, such as the preferred audio
> driver (the answer for which might change based on the hypervisor we specified
> at library init, for example).
> -Then we can query the unique values for the property 'Vendor' to get a list of 
> strings representing vendor names. 
> -Or, we could query unique values for the relationship property DERIVES_FROM to
> get a list of distros that are derived by at least one other distro.
> -At some point we're done looking up data and close the library handle.
> 
> I look forward to any feedback.
> 

Overall it looks good, there seems to be enough here to handle even the
difficult cases

I think some (psuedo)code examples using the API would also go a long
way in helping reviewers wrap their head around the code: it could also
expose some awkwardness in the above methods.

Thanks,
Cole




More information about the virt-tools-list mailing list