
on 2014/10/22 01:54, Aline Manera wrote:
I'm interested on this. Had a little investigation, ws4py provides Cherrypy plugin and tool to add websocket support. It'll be very nice if we can provide websocket in current Cherrypy server. It solves to authentication, authorization and security problem. On Cherrypy offical site, it also says websocket is supported by using ws4py.
A problem is that ws4py is not packaged in Fedora and RHEL, maybe we'll have to ship the library in our source code. That raise another problem. The license of ws4py is an ad-hoc one. We may have to verify if it is compatible with LGPL3.
Had read the license of ws4py, it does not restrict redistributions and modification, as long as we keep the license message for that piece of code. Looks a good choice, because it can be integrated into cherrypy easily, so we don't have the authentication problem as websockify. If we can use this library, we can easily use virDomain.openConsole() API to get the console stream and forward to websocket.
If we are to use websocket, the nature solution would be as follow host pty -> websockify ---(websocket)--> wspty
There is a potential security risk. If we use websockify to transfer serial port data, we are exposing the serial port to public without any authentication. We have the same problem in VNC/Spice, that's why we add ticket. The VNC ticket is using the password mechanism built in the VNC protocol. However when using serial port, there is no such protocol, it just transfers raw data. A solution is that we use the websocket facility supported by cherrypy and forward the serial port data ourselves, so that we can do authentication as usual. I did a little more investigation. websockify does not support forwarding a file like object (such as /dev/pts/4). Though it support forwarding a Unix socket, the socket path is defined in the command line once, and it does not support loading the socket part in target config file dynamically. So a workaround maybe we firstly use socat to forward the file/socket to/from 127.0.0.1:some_port, then add a token in target config file to ask websockify forward this some_port.
Qemu and libvirt support defining a network backed chardev, so we can use the following XML for the VMs we create to define a serial port.
<serial type='tcp'> <source mode='bind' host='127.0.0.1' service='0'/> <protocol type='raw'/> <target port='0'/> </serial>
Does it mean the text console on Kimchi will not work well with guests created outside Kimchi?
In this case, yes. It'll be a problem.
Then use the following qmp command to retrieve the allocated local port.
virsh qemu-monitor-command domain_name --cmd \ '{"execute": "query-chardev"}'
At last we can add a new token in websockify config dir according to the returned port information.
Another method is that we can do a monkey patch of the "websockify.websocketproxy", and replace the new_websocket_client() method to make it load pty and Unix socket dynamically. In the proxy() method, it uses select.select() to forward between target and client socket, and unfortunately it seems virStream Python binding object does not provide a FD for use to select(). So we can not use "virDomain.openConsole()" but to parse the guest XML in Kimchi, and find the back-end of the first serial device ourselves.
We do not import the websockets code anymore. Instead of that we depends on its package. So I don't think depending on change its code is a good idea.
I feel the same. So the conclusion is that if we want to use websockify, we have to invent some nasty workarounds. For example, use socat or some helper to forward the pty/unix socket to 127.0.0.1:some_port, then have websockify forward this port.