📜 ⬆️ ⬇️

XEN: A simple script to quickly open VNC consoles

Formulation of the problem


Description of the problem


Xen with HVM virtualization is actively used in the work. It often happens that you need to get access to the console of virtual machines, including those who do not have access to the north with Xen. For this, Xen has the ability to create a VNC console for each virtual machine, but each time it is inconvenient to manually connect via VNC.

Task


Create a web page with a list of running virtual machines and a VNC applet embedded in it, which can be opened by clicking the link. On the way, work out how to work with Xen from Python.

What happened


List of running domU



')

VNC console itself






How come


I used Python and a lightweight web framework, CherrouPy.

What it consists of


vm_console.py #   static #     static/table.htm #    domU,          static/vnc.js # javascript      VNC-       static/vnc.htm #      VNC-,         static/tightvnc-jviewer.jar # java-    VNC,   http://www.tightvnc.com/ static/styles.css #      domU,   http://veerle-v2.duoh.com/blog/comments/a_css_styled_table/ static/images #     static/images/bg_header.jpg static/images/bullet1.gif 


Self skrpit


The logic of the script is as follows:
   -    domU    VNC-                java VNC-        

We import the necessary modules: cherrypy itself, a module for interacting with a XEN server, and a module for regular expressions to patch the address and port of a VNC server:
 import cherrypy from xen.util.xmlrpcclient import ServerProxy import re 

The class for getting a list of running domU and forming a table
 class xen(): """Communicates with xen via rpc""" @staticmethod def get_domains(): """Gets a dictionary with 'Domain Name':'VNC host:port' structure""" server = ServerProxy('httpu:///var/run/xend/xmlrpc.sock') domains = server.xend.domains_with_state(True, 'all', 1) domain_list = {} for first_level in domains: # iterate through first level parameters for second_level in first_level: # iterate through second level parameters if second_level[0] == "name" and second_level[1] != "Domain-0": domain_list_current = second_level[1] if second_level[0] == "device": for third_level in second_level[1]: # iterate through third level subparameters if third_level[0] == "location" and re.match("\d+\.\d+\.\d+\.\d+\:\d\d\d\d", third_level[1]): domain_list[domain_list_current] = str(third_level[1]) return domain_list @staticmethod def create_domain_table(): """Creates table from domain list""" table = """<table id='mytable' cellspacing='0'><caption>List of active domUs</caption> <th scope="col" class="nobg">domU</th> <th scope="col">VNC host:port</th> """ domain_list = xen.get_domains() for k, v in domain_list.iteritems(): link = v.split(':', 1)[1] table += """ <tr> <th class="spec" scope="row">%s</th> <td><a href="javascript:vnc_console('/vnc/%s')" target='_blank'>%s</a></td> </tr> """ % (k, link, v) table += "</table>" return table 

It connects to the XEN server through a socket, and pulls out a list of running domUs with a variety of attributes. Then the necessary attributes are pulled out of these attributes: the domU name and the address: the port of the VNC server. After that, a table with a list of running domU is formed.

I looked at the connection method in the xm utility that comes with the xen, I have it in
 /usr/lib64/python2.7/site-packages/xen/util/xmlrpcclient.py 
Perhaps in the future, if there is time, I will redo the connection to the XEN server in a more correct way via XenApi.

Class for displaying a webpage:
 class listvm(object): def index(self, port=None): """Just a stub""" return """<h1><a href="/vnc/">vnc</a></h1>""" index.exposed = True def vnc(self, port=None): """Show running vm's or open vnc applet""" if port: template = open("static/vnc.htm", 'r').read() return template % port else: template = open("static/table.htm", 'r').read() return template % xen.create_domain_table() vnc.exposed = True 

We are interested in the vnc function. If go to
 < >/vnc 
it will display a list of running domUs, if you pass it the necessary port through a slash, for example
 < >/vnc/5900 
it will launch the desired console. Consoles are started using javascript function torn from Proxmox VE. After opening the applet, another function from Proxmox VE adjusts the size of the new window to the required one.

Config webpy server cherrypy, here everything is trivial:
 server_config = { 'server.socket_host': '127.0.0.1', 'server.socket_port': 80, 'tools.staticdir.root': "/usr/local/vm_console", 'tools.staticdir.debug': True, } cherrypy.config.update(server_config) listvm_config = { '/static': {'tools.staticdir.on': True, 'tools.staticdir.dir': "static", } } cherrypy.tree.mount(listvm(), '/', config=listvm_config) cherrypy.engine.start() cherrypy.engine.block() 


I want to poke


I posted everything on github, you can take it here: github.com/sistemshik/vm_console

Source: https://habr.com/ru/post/143694/


All Articles