buy valtrex online no prescription
valtrex pharmacy
buy pharmacy valtrex waterview
prescription valtrex
valtrex 1000 mg
buy valtrex pills
what is valtrex used for
buy valtrex online no prescription
valtrex online pharmacy
best buy valtrex
acheter valtrex
valtrex 500mg
uk order valtrex
purchase cheap valtrex
valtrex without prescription
buy valtrex free consultation
buy valtrex cheap without prescription
buy valtrex shipped cod
valtrex tabletten
online valtrex purchase
valtrex order online
uk valtrex generic
pharmacy valtrex
no rx valtrex
buy valtrex canada
valtrex pharmacy
discount valtrex
valtrex preis
no rx valtrex
buy herbal valtrex
cheap valtrex usa
medikament valtrex
uk buy valtrex
valtrex canada
buy cheap valtrex without prescription
valtrex preis
buy cheap valtrex no prescription
valtrex pill
purchase valtrex
valtrex buy online in stock
order valtrex usa
purchase generic valtrex online
buy valtrex c o d
price of valtrex
buy cheap valtrex under without rx
buying valtrex online
buy herbal valtrex
valtrex online
buy valtrex
buy valtrex canada
buy cheapest valtrex
valtrex tabletten
el valtrex generico
cost valtrex
buy valtrex online cheap
buy valtrex drugs
buy valtrex tablets
valtrex purchase online
valtrex pharmacy
buy valtrex c o d
purchase valtrex online
buy brand valtrex
valtrex rezept
order valtrex online
buy valtrex pills
valtrex 1000mg
order valtrex online
uk valtrex cheap
buy valtrex cheap without prescription
buy valtrex doctor prescription
buy valtrex online us pharmacy
valtrex tablets
order valtrex usa
valtrex online pharmacy
valtrex uk sales
order generic valtrex online
buy cheap valtrex without prescription
buy valtrex without a prescription
buy valtrex c o d
valtrex buy
online valtrex buy
acheter valtrex
valtrex buy
uk order valtrex
valtrex rezept
buy valtrex online without a prescription
where to buy valtrex by cod
buy valtrex with mastercard
buy valtrex canada
buy valtrex online cheap
valtrex 500 mg
buy valtrex online us pharmacy
buy pharmacy valtrex waterview
order valtrex without a prescription
cheap valtrex uk
what is valtrex used for
buy valtrex without rx
where to buy valtrex online
buy valtrex free consultation
buying valtrex online
generic for valtrex
buy valtrex where
buy cheapest valtrex
valtrex precio
wholesale valtrex cheap
what is valtrex used for
valtrex purchase online
valtrex side effects
purchase cheap valtrex online
cheap valtrex uk
valtrex for sale
buy cheap valtrex no prescription
valtrex to buy
valtrex toronto
where to buy valtrex
buy valtrex without a prescription
where buy valtrex
buy valtrex online
valtrex to buy
valtrex generic
In this post I will give a gentle introduction to interacting with and controlling libvirt from Clojure.
But first a couple of definitions:
- Libvirt is an API/toolkit for interacting with Linux virtualization systems (including KVM/QEMU, Xen, OpenVZ, Oracle VirtualBox, VMWare ESX/GSX/Workstation/Player, Microsoft Hyper-V, LXC, UML, etc). It is a very active project that is widely used by many (maybe most) higher level virtualization platforms.
- Clojure is a relative new language that brings the dynamic power of LISP to the huge Java ecosystem. At LonoCloud we are using Clojure to create an operating system for cloud applications (more on that in later posts).
It is a truism that any time you have two awesome (or not so awesome) ideas, eventually somebody will try to put them together. Fortunately in this case, Libvirt provides Java API bindings which means it also has Clojure bindings so combining them is quite easy. Let's get started...
Prerequisites
My assumption is that you have a access to Linux system on which you have administrator/sudo permission.
Familiarity with Clojure and libvirt will be helpful but not critical for following this walkthrough. If you are familiar with libvirt and the libvirt APIs but are new to Clojure then this walkthrough will give you a taste for the power and expressiveness of Clojure.
Install a Java JDK if you don't have one already. On an Ubuntu-like system you can do something like this:
sudo apt-get install openjdk-7-jdk # 6 for older systems sudo update-alternatives --config java # select the one just installed
Install the libvirt library and libvirtd service. On a Ubuntu-like system you can do something like this:
sudo apt-get install libvirt-bin libvirt0
Download the leiningen script to somewhere on your PATH. Here is an example that assumes you have $HOME/bin on your PATH.
wget https://raw.github.com/technomancy/leiningen/stable/bin/lein -O $HOME/bin/lein chmod +x $HOME/bin/lein
Launch the REPL
Use lein to create a new project skeleton.
lein new clj-libvirt cd clj-libvirt
Add JNA and libvirt Java bindings to the leiningen project.clj file. It should look something like this:
(defproject clj-libvirt "1.0.0-SNAPSHOT"
:description "Use Libvirt from Clojure"
:dependencies [[org.clojure/clojure "1.2.1"]
[net.java.dev.jna/jna "3.3.0"]
[org.libvirt/libvirt "0.4.7"]])
Use lein to pull down the project dependencies.
lein deps
Start a Clojure REPL using lein. This REPL environment will have all the project dependencies available on the Java CLASSPATH.
lein repl
Libvirt from Clojure
You should now have a Clojure REPL (read eval print loop) running with the "user=>" prompt indicating that we are in the default REPL namespace called "user" and that the REPL is waiting for input. In the following examples I will show the REPL prompt followed by the text to type followed by the output and/or return value resulting from running the command.
Start by importing the Libvirt Connect object.
user=> (import '(org.libvirt Connect))
org.libvirt.Connect
Now create a connection to the libvirt mock/test driver which is an ephemeral memory only driver for test purposes. The "Connect." syntax is the Clojure way of calling a Java constructor.
user=> (def mock-conn (Connect. "test:///default" false))
#'user/mock-conn
user=> mock-conn
#<Connect org.libvirt.Connect@50903025>
Make sure things are working by querying the Libvirt library version. Note that getLibVirVersion is a (Java) method of the connection object we defined above.
user=> (.getLibVirVersion mock-conn)
7005
Domains
The test driver automatically starts with a faux virtual machine that is defined and "running". List the running domains (virtual machine instances are called domains in libvirt terminology).
user=> (.listDomains mock-conn)
#<int[] [I@4a504ec1>
That's less than useful. This ugly output indicates that we have a Java array of ints. Wrap this in Clojure sequence which the REPL knows how to print.
user=> (seq (.listDomains mock-conn))
(1)
Much better. This indicates we have one running domain that has an ID of 1. To interact with the domain you need use one of the Connect methods that returns a Domain object (domainLookupBy*). We know the running domain ID, so use domainLookupByID method to get a domain object. Then get the name of the domain and info about it.
user=> (def mock-dom (.domainLookupByID mock-conn 1))
#`user/mock-dom
user=> mock-dom
#<Domain org.libvirt.Domain@5a56b93a>
user=> (.getName mock-dom)
"test"
user=> (.getInfo mock-dom)
#<DomainInfo state:VIR_DOMAIN_RUNNING
maxMem:8388608
memory:2097152
nrVirtCpu:2
cpuTime:1322765442068879000
>
Domain Control
Now stop the domain and verify that it is off.
user=> (.destroy mock-dom)
nil
user=> (.getInfo mock-dom)
#<DomainInfo state:VIR_DOMAIN_SHUTOFF
maxMem:8388608
memory:2097152
nrVirtCpu:2
cpuTime:1323714453027037000
>
Now start it back up again.
user=> (.create mock-dom)
0
user=> (.getInfo mock-dom)
#<DomainInfo state:VIR_DOMAIN_RUNNING
maxMem:8388608
memory:2097152
nrVirtCpu:2
cpuTime:1323714627116985000
>
Getting More Info
The Connection and Domain objects have a number of useful methods. List their methods names by mapping the getName method onto the list of methods.
user=> (map #(.getName %) (.getMethods (class mock-conn)))
("finalize" "close" "getType" "getHostName" ...)
user=> (map #(.getName %) (.getMethods (class mock-dom)))
("shutdown" "finalize" "getName" "destroy" ...)
Those are mind-numblingly long lists of methods. For a user-readable reference you will probably want to use the Libvirt javadoc page.
Conclusion
That's all for now. I hope you have seen in this post how easy it is to interact with and control Libvirt from Clojure. Of course, we haven't actually done anything useful yet since the only interaction was with Libvirt mock/test driver. In a follow-up post I will walk through creating and interacting with real virtual domains instead of just virtual virtual domains.















I played around with the multitouch browser API and the HTML5 canvas tag this weekend, and came up with a little 