[one-users] another vnc port discussion

Claude Noshpitz cnoshpitz at attinteractive.com
Wed Feb 24 18:09:36 PST 2010


Hi,

I've been thinking about how to manage vnc ports using libvirt.  Turns out (perhaps I'm the last to discover this) that libvirt will accept -1 as a port value and then assign a free port automatically.  So that helps a bit with the problem of the port namespace itself (presumably one can run fewer VMs on a given host than there are ports available).

But what about getting the assigned port back out to the UI?  Rogier has provided a handy solution for OneMC (the reading of which nudged me to compose this  message :-).

I'm using the OCCI interface quite a bit, partly because it has at least an aroma of standardization, partly because it's easy to hack the templates and get interesting results.  It wasn't obvious how folks in the community were addressing this problem, so here are some ideas...

In OCCIServer::post_compute, we say

    vm_info['VNC_PORT'] = -1

and then add a stanza like this to e.g. etc/occi_templates/small.erb:

GRAPHICS = [
    keymap = "en-us",
    type = "vnc",
    listen = "0.0.0.0",
    port = "<%= vm_info['VNC_PORT'] %>"
]

so the template does the right thing by asking for port -1.  Note that it would be easy to override this value by providing an explicit one, perhaps relevant to another VM provider.

To get the port that's eventually assigned by kvm, the VM driver has to poke at libvirt.  Turns out that virsh seems to report it only in an xmldump, so here's one way (not claiming nokogiri is the most efficient approach, but it's concise):

--- a/src/vmm_mad/kvm/one_vmm_kvm.rb
+++ b/src/vmm_mad/kvm/one_vmm_kvm.rb
@@ -38,6 +38,7 @@ end
 $: << RUBY_LIB_LOCATION

 require 'pp'
+require 'rubygems'; require 'nokogiri'
 require "VirtualMachineDriver"

 # ---------------------------------------------------------------------- #
@@ -182,6 +183,15 @@ class LibVirtDriver < VirtualMachineDriver
             end
         }

+        # get assigned vnc console port
+        xml_cmd = "virsh --connect #{LIBVIRT_URI} dumpxml"
+        exe  = SSHCommand.run("#{xml_cmd} #{deploy_id}", host, log_method(id))
+        if exe.code == 0
+            doc = Nokogiri::XML(exe.stdout)
+            port = doc.xpath("//domain//graphics/@port").first.value
+            info << " VNC_PORT=#{port}"
+        end
+
         send_message(ACTION[:poll], RESULT[:success], id, info)
     end
 end

Now the poll result (as seen in onevm.log) will also contain VNC_PORT.  This can get picked up in the OCCI xml output by adding something like

             <GRAPHICS port="<%=template['VNC_PORT']%>" />

to the little erb template in VirtualMachineOCCI.rb.

Not clear how to extend these ideas beyond libvirt btw - probably there's a cleaner approach for the more general problem but this approach met my use case nicely :)

Does this all make sense?

Thanks!

--Claude



More information about the Users mailing list