• View Communities
    • Citrix Communities
      Visit the Citrix Communities to get and share technical information and best practices about desktop delivery, datacenter, networking and cloud computing solutions.
    • Citrix Blogs
      Learn the latest from the Citrix employees who are building the future of virtual computing.
    • Citrix Developer Network
      The place for unfiltered straight talk on Citrix products. Find related blogs, best practices, code downloads, APIs and more.
    • Citrix Ready Community Verified
      Does it work with Citrix? Application compatibility questions are a thing of the past with the new Citrix Community Verified site.
  •  Sign In
Citrix Developer Network

Exploring XAPI

 It may seem as though the method names VM.get_name_label() and VM.get_is_a_template() from the previous example Hello XAPI were pulled out of a hat. Especially since the python help system can't tell you the names.

However take a look at: Xen Enterprise Management API . It's automatically generated from the source code, and as such is both an accurate source of useful information, and largely unreadable. On the first page are the 'Class relationship diagram' and the list of fields and methods, represented by a clickable tree. Keep them in front of you whilst reading the rest of this article.

If you look at the tree, you'll find at API/Classes/VM/Fields, that there are fields in a VM object called name_label, and is_a_template. These imply the existence of corresponding get methods.

The key abstraction with XAPI is the representation of everything as an object in database. The objects in the database are related to one another by one-to-one and one-to-many relations. These are represented on the diagram by funny looking arrows.

Take a look at the ring of squares in the Class relationship diagram. Let's go exploring...

(It can help to have a copy of XenCenter, our GUI, open, so you can see that view of the XenServer and its VMs, networks and disks, and also to have an ssh session to the server open, so that you can explore with the command line tool xe. However neither is necessary if you're not familiar with them.)

 I'm going to describe the results of interrogating my server 'ivory'. Try the same commands on your server, mutatis mutandis, and see what you get.

Firstly we need to start python, import XenAPI, and log in. See [Xen Server API Test Page] if you're not sure how. In summary:

$ python
Python 2.5.2
Type "help", "copyright", "credits" or "license" for more information.
>>> import XenAPI
>>> session = XenAPI.Session('https://ivory')
>>> session.login_with_password('root','password')

Once we have the session object, let's see how many hosts we have in our pool of servers.

>>> hosts=session.xenapi.host.get_all()
>>> hosts
['OpaqueRef:ddf74d62-5ebe-d922-a3e5-d7c0472231aa', 'OpaqueRef:2b820f43-1722-d5cc-c697-eb1d5bbf7eb8']

My server ivory has a friend, sapphire, in its pool, so I've got back two 'OpaqueRef:' strings, each of which identifies one of them. Your server may be part of a larger pool, or just a single box on its own in a pool of one.

 The host object is one of the orange squares (the one on the left) in the diagram in Xen Enterprise Management API , and it represents a physical server box. If we click on the orange square 'host', we should get a big index of fields and methods. Since 'name_label' is one of the fields, there will be a get_name_label method for the host object.

Try it using the strings returned by host.get_all()

>>> [session.xenapi.host.get_name_label(x) for x in hosts]
['ivory', 'sapphire']

Let's make them their own variables:

>>> ivory, sapphire=hosts

 Now try:

>>> session.xenapi.host.get_record(ivory)
{'PBDs': ['OpaqueRef:96ddcf60-9306-8be4-592c-98404c8a4c80', 'OpaqueRef:0ae8ce08-b213-75bb-84a6-65667fc090cf', 'OpaqueRef:6eacacb4-c696-6239-37bc-d0344c331996', 'OpaqueRef:7430e505-1c4b-39aa-b833-22c613d08933', 'OpaqueRef:9ed60d05-fdb4-09fd-6ce7-4d48022acc6e', 'OpaqueRef:f07959a8-2399-b6af-fac0-6b79281f448b'], 'supported_bootloaders': ['pygrub', 'eliloader'], 'host_CPUs': ['OpaqueRef:6f969e45-520d-8d9a-05cf-cf5305ba9df9', 'OpaqueRef:9a3bd7d2-8b4e-2e33-2b83-5a05c0118c02'], 'API_version_minor': '2', 'allowed_operations': ['provision'], 'API_version_vendor_implementation': {}, 'name_description': 'Default install of XenServer', 'API_version_vendor': 'XenSource', 'uuid': '5fa5e9b3-9700-492f-ba7b-d8f00892074f', 'hostname': 'ivory', 'name_label': 'ivory', 'capabilities': ['xen-3.0-x86_64', 'xen-3.0-x86_32p', 'hvm-3.0-x86_32', 'hvm-3.0-x86_32p', 'hvm-3.0-x86_64', ''], 'PIFs': ['OpaqueRef:39e27ed6-8f85-3954-7e41-efc38b620a58'], 'crash_dump_sr': 'OpaqueRef:f1b28f51-8d14-c9c8-633c-341dcf4f8b4d', 'cpu_configuration': {}, 'license_params': {'productcode': 'b1a8-c0c4-b545-1b04-101a-412c', 'restrict_pooling': 'false', 'address2': '', 'name': 'Citrix XenServer Engineering', 'restrict_qos': 'false', 'city': '', 'address1': '', 'company': 'Citrix Systems, Inc.', 'serialnumber': 'e904e417-4bde-c27a-9289-f514b4a7503a', 'sku_marketing_name': 'Citrix XenServer Enterprise Edition', 'sku_type': 'XE Enterprise', 'expiry': '20090102T00:00:00Z', 'restrict_connection': 'false', 'state': '', 'version': '4.0.0', 'restrict_pool_attached_storage': 'false', 'country': '', 'postalcode': '', 'restrict_vlan': 'false', 'enable_xha': 'false', 'sockets': '2'}, 'software_version': {'hostname': 'kiffu-2', 'build_number': '7843c', 'xapi': '1.1', 'xen': '3.1.0', 'product_version': '4.1.0', 'hg_id': 'ecf1e2c6eaea tip', 'package-linux': 'installed', 'product_brand': 'XenServer', 'xencenter_max': '1.1', 'linux': '2.6.18-53.1.13.el5.xs4.1.0.254.273xen', 'date': '2008-03-21', 'xencenter_min': '1.0'}, 'metrics': 'OpaqueRef:fa3a96b0-299c-40c9-8e8f-3c0fcbe6ced3', 'address': '10.80.224.67', 'crashdumps': [], 'patches': [], 'current_operations': {}, 'logging': {}, 'sched_policy': 'credit', 'other_config': {'iscsi_iqn': 'iqn.2008-04.com.xensource.uk:b9ca3a43', 'agent_start_time': '1214497420.', 'loadavg': '0.', 'boot_time': '1214301988.', 'ha_armed': 'false'}, 'enabled': True, 'suspend_image_sr': 'OpaqueRef:f1b28f51-8d14-c9c8-633c-341dcf4f8b4d', 'API_version_major': '1', 'resident_VMs': ['OpaqueRef:fbf68d09-ef01-0bb9-5fe7-62b9f72afb7b', 'OpaqueRef:e72e51aa-cf02-aa87-1697-878226e3efa0', 'OpaqueRef:0b6a735a-a381-23c3-2b06-d252ab28116d', 'OpaqueRef:7237b8af-b80c-c021-fbdc-68146d98d7f5']}

giving us the entire database record as a dictionary. We can make this a little more readable with the pretty-printer:

>>> from pprint import pprint
>>> pprint(session.xenapi.host.get_record(ivory))
a fair bit of output....

There's also the nuclear option, which returns all the host records in a dictionary, with one entry per host. The keys are the host's 'OpaqueRef', the values are the records.

>>> pprint(session.xenapi.host.get_all_records())
lots of output....

As well as examining the host-specific data, we can also chase round the ring of objects. The networking direction is easiest to understand, so let's go anti-clockwise on the diagram:

>>> session.xenapi.host.get_PIFs(ivory)
['OpaqueRef:39e27ed6-8f85-3954-7e41-efc38b620a58']
>>> ivorypif=_[0]


We've asked for the list of PIFs (physical interfaces) on ivory. In this case there's only one, the single ethernet card, so the list has only one element. We'll name that element ivorypif. Again, it's an 'OpaqueRef:', a unique ID for that element in the database.

Again, the PIF object has a get_record() method (we see from Xen Enterprise Management API), but the record structure is much simpler than that for a host. I've deleted some of the output for readability:

>>> pprint(session.xenapi.PIF.get_record(ivorypif))
{'DNS': '',
 'IP': '',
 'MAC': '00:19:d1:e5:93:07',
 'currently_attached': True,
 'device': 'eth0',
 'gateway': '',
 'host': 'OpaqueRef:2b820f43-1722-d5cc-c697-eb1d5bbf7eb8',
 'ip_configuration_mode': 'DHCP',
 'management': True,
 'metrics': 'OpaqueRef:b8d6999c-db30-02e9-3e0b-8e2a319f4314',
 'netmask': '',
 'network': 'OpaqueRef:03ac5006-4bb2-187b-21a1-fda7fdf1af02',
 'other_config': {},
 'physical': True,
 'uuid': 'f3bd29b9-bb64-f8d1-052a-04402bdb3258'}

 There's not a great deal of useful info here, but we can tell that the host's ip address is set dynamically rather than being forced, and we have further links to a metrics and a network object, which corresponds with our orange diagram.

>>> pprint(session.xenapi.PIF_metrics.get_record(session.xenapi.PIF.get_record(ivorypif)['metrics']))
{'carrier': True,
 'device_id': '104b',
 'device_name': '82566DC Gigabit Network Connection',
 'duplex': True,
 'io_read_kbs': 9.5076171874999993,
 'io_write_kbs': 3.1568359374999999,
 'last_updated': <DateTime '20080707T13:08:24Z' at b765b6ac>,
 'pci_bus_path': '0000:00:19.0',
 'speed': '100',
 'uuid': 'a5c5a72e-4e3f-8784-755f-df76bb02747b',
 'vendor_id': '8086',
 'vendor_name': 'Intel Corporation'}

 It is a convention not universally acknowledged that data read from things goes in separate 'metrics' objects, which have their own sets of fields and methods. So here we are taking the 'metrics' opaque reference from the PIF, and using it as the argument in a call to PIF_metrics.get_record(). Our reward is to discover that ivory's network card has recently been reading data at 9.5 kb/s and sending it at 3.1 kb/s. Since its top speed is 100Mb/s, it's not terribly busy. We could get the same information from XenCenter's performance tab. Indeed, this is how XenCenter gets it.

We can also see that sapphire's PIF is connected to the same network object as ivory's:

>>> session.xenapi.PIF.get_record(session.xenapi.host.get_PIFs(ivory)[0])['network']
'OpaqueRef:03ac5006-4bb2-187b-21a1-fda7fdf1af02'
>>> session.xenapi.PIF.get_record(session.xenapi.host.get_PIFs(sapphire)[0])['network']
'OpaqueRef:03ac5006-4bb2-187b-21a1-fda7fdf1af02'

You should carry on, chasing the various links about, figuring out what each object is for.

In another article I'll describe how to get the computer to produce a nice overview of your server's current database. This is the diagram I wish I'd had when I was trying to figure it all out. See Drawing a graph of the database






Tags

xapi xapi Delete
Enter tags to add to this page:
Please wait 
Looking for a tag? Just start typing.
Related Links