When this project began we weren't sure what we were getting into. Our first order of business was to figure out how to write successful documentation, store it with version information and get it to the Xen folks and eventually to Citrix.  About 100 manpages into it we knew that there was a lot of repeats and the documentation should be generated from code and either a lookup table or database. However, nobody had the time to learn OCAML and address this issue. We started a large flat table to deal with identifying duplicate item descriptions while thinking the whole time that we needed to move to a data structure that supported hierarchies. 

Here's my current thoughts on this - we should store all commands, items and descriptions as nested key/value pairs much like a Python dictionary or JSON. This way it would be easier for someone who knew OCAML to write code to import the documentation data. However, editing a JSON file is not a very pleasant experience and we'd need a second tool to export the data to a document format. 

Firstly there are several webJSON editors available - https://github.com/jdorn/json-editor. My biggest issue is that I'd want to use the xenapiadmin.com's user database to authenticate the user, remember that information and when they load/write the JSON file it would do a git commit in their name. 

Lastly there are JSON to asciidoc or docbook converters - pandoc comes to mind. This could be used in the interim for creating manpages, PDFs and html pages of each. Late when the OCAML code was compiled the make file would create the documentation. 

All of this takes time which I have little of.

I've always wanted to have online HTML versions of the xenapiadmin manpages and was looking at HP's network switch OS webpage and realized it was asciidoc. That made me look at how they were building a website from asciidoc source and led me to the very small build-website.sh script that's in the mercurial download of asciidoc but not in the Fedora RPM of asciidoc. 

This is a very simple script that basically calls asciidoc for each asciidoc file and creates an html page for it.

asciidoc.py --backend=xhtml11 --conf-file=${LAYOUT}.conf --attribute icons --attribute iconsdir=./images/icons --attribute=badges --attribute=revision=$VERS  --attribute=date=$DATE"  

I'm not sure how this would work for hyperlinks but for our purpose of just hosting the manpages in html format it would be perfect. I'm going to see if I can add this to the createmanpage script quickly as I don't have a ton of time. 


In an effort to help with the automation of manpage generation I'm going to start learning OCaml.  If anyone knows of some good OCaml resources they would be much appreciated.  This is the only resource I have so far.

I haven't written any tools for Xenapi Admin Tools in quite a while. Long enough that I forgot how getcmddata worked. Since ClassStack uses xaptools.lib to manage an XAPI stack I got a refresher do to me wanting a menu that outputed a Student's dom-id and the host their VM was running on in a menu. I wrote this out the quick way not using any functionality of xaptools.lib because that's what you do when you forget about the past.

 for i in $(seq 0 $(( ${#STUSIDS[@]} - 1 )) ) ;do	
        STUCONSOLE[$i]=$(xe vm-list name-label=${STUSIDS[$i]} params=dom-id --minimal)
	CLOUDHOSTUUID=$(xe vm-list name-label=${STUSIDS[$i]} params=resident-on --minimal)
	STUFQDN=$(xe host-list uuid=$CLOUDHOSTUUID params=name-label --minimal)

This is pretty simple - for each Student ID (STUSIDS array) get the VM's dom-id and the host it's resident on. Then get the fully qualified domain name of the host (it's name-label in my case). Use BASH pattern matching to grab the hostname portion of that. Displaying dom-id's for 15 students takes 15 seconds. This includes parsing their data from the Rosterfile, getting input from the user which class to display and executing the code above. When doing repetitive tasks 15 seconds can be pretty painful so I thought about making it faster. Halfway through hacking away at it - which mainly comprised of me trying to get rid of xe calls inside the loop - I remembered doing this before! I created a function in xaptools.lib called getcmddata that made ONE call to xe, returned the output as CSV then used BASH pattern matching to assign each portion of the CSV output to ARRAYs. It's been long enough that I had to go look up getcmddata to figure out how to use it. 

The resulting code using getcmddata from xaptools.lib.


        getcmddata vm-list params=name-label,dom-id,resident-on
	getcmddata host-list params=uuid,name-label
	for i in $(seq 0 $(( ${#vm_name_label[@]} - 1 )) ) ;do
		for j in $(seq 0 $(( ${#host_uuid[@]} - 1 )) ) ;do
			if [[ ${HOSTUUID[$i]} = ${host_uuid[$j]} ]] ;then
	for i in $(seq 0 $(( ${#STUSIDS[@]} - 1 )) ) ;do	
		for j in $(seq 0 $(( ${#VMNAME[@]} - 1 )) ) ;do
			if [[ ${STUSIDS[$i]} = ${VMNAME[$j]} ]] ;then

 Yes, it's much longer and does exactly the same thing as the first code block but it's much faster!

Execution time

  • Method one: 15 seconds
  • Method two using getcmddata: 2.3 seconds


Was it worth it? Absolutely. With a larger class the speed increase is even greater. Method one gets slower as the class gets larger eg. 30 students would have taken 30 seconds and so on. Method two is virtually the same speed no matter how many students there are because the number of xe calls are exactly the same.

Note to self: getvmdata in xaptools.lib is still using the old method and not getcmddata. If you don't look at your code you forget what's in there.