Skip to content

Commit

Permalink
KVM: making vdi-agent PEP 8 compliant
Browse files Browse the repository at this point in the history
  • Loading branch information
Seitanas committed Sep 13, 2017
1 parent 8bb934a commit 14ded88
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 45 deletions.
116 changes: 87 additions & 29 deletions KVM/hypervisors/module/VMStartupService.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import threading
import Variables


class VMStartupService(threading.Thread):
def __init__(self, vmname, username, password, os_type, socket_timeout):
threading.Thread.__init__(self)
Expand All @@ -17,72 +18,129 @@ def __init__(self, vmname, username, password, os_type, socket_timeout):
self.os_type = os_type
self.socket_timeout = socket_timeout
self.logger = logging.getLogger('kvm-vdi-agent')

def stop(self):
self._stop.set()

def stopped(self):
return self._stop.isSet()

def run(self):
data = ""
self.logger.info("Starting machine %s", self.vmname)
err = subprocess.Popen("virsh start " + self.vmname, shell=True, stdout=subprocess.PIPE).communicate()
socket_path = subprocess.Popen("virsh dumpxml " + self.vmname + "| xpath -q -e /domain/devices/channel/source/@path|grep kvm-vdi", shell=True, stdout=subprocess.PIPE).communicate() # get current spice channel path. Path changes on each VM startup
socket_path = re.findall(r'"([^"]*)"', socket_path[0]) # remove everythig outside double quotes
err = subprocess.Popen(
"virsh start " + self.vmname,
shell=True,
stdout=subprocess.PIPE).communicate()
""" get current spice channel path
(path changes on each VM startup):
"""
socket_path = subprocess.Popen(
"virsh dumpxml " + self.vmname +
"| xpath -q -e /domain/devices/channel/source/@path|grep kvm-vdi",
shell=True, stdout=subprocess.PIPE).communicate()
""" Remove everythig outside double quotes:
"""
socket_path = re.findall(r'"([^"]*)"', socket_path[0])
try:
self.logger.debug("Opening socket %s",socket_path)
self.logger.debug("Opening socket %s", socket_path)
virtio_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
virtio_socket.connect(socket_path[0])
ready = select.select([virtio_socket], [], [], self.socket_timeout) # Read VMs spice channel for n seconds. We assume that VM must boot in n seconds and start ovirt-agent.
""" Read VMs spice channel for n seconds.
We assume that VM must boot in n seconds and start ovirt-agent:
"""
ready = select.select([virtio_socket], [], [], self.socket_timeout)
is_logged = 0
retries = 0
query_retry = 10
if ready[0] and self.username:
self.logger.debug("oVirt agent is up")
time.sleep(2) # wait for login
serial_message = '{"__name__":"login","username": "' + self.username + '","password": "' + self.password + '"}'+"\n"
time.sleep(2) # wait for login
serial_message = (
'{"__name__":"login","username": "' +
self.username + '","password": "' +
self.password + '"}' + "\n")
while not is_logged and retries < 5:
self.logger.debug("Requesting new data for guest: %s", self.vmname)
virtio_socket.sendall( '{"__name__":"refresh"}'+"\n") # let's ask for data from oVirt agent on guest machine
self.logger.debug(
"Requesting new data for guest: %s",
self.vmname)
""" let's ask for data from oVirt agent on guest machine:
"""
virtio_socket.sendall('{"__name__":"refresh"}'+"\n")
time.sleep(0.5)
self.logger.debug("Reading SPICE channel")
info = virtio_socket.recv(2048)
info_lines = info.split("\n")
got_reply = 1
if not is_logged and got_reply and query_retry > 9: # if there are no logged-in users, execute SSO
self.logger.info ("Trying SSO")
self.logger.debug ("Sending credentials for %s to VM: %s", self.username, self.vmname)
""" if there are no logged-in users, execute SSO:
"""
if not is_logged and got_reply and query_retry > 9:
self.logger.info("Trying SSO")
self.logger.debug(
"Sending credentials for %s to VM: %s",
self.username,
self.vmname)
virtio_socket.sendall(serial_message)
retries += 1
query_retry = 0
elif not got_reply:
self.logger.debug("Got no info about logged-in users from oVirt agent. Retrying.")
for python_line in info_lines: # go through all json responces, search for active-user
if python_line: # if line is not empty
self.logger.debug(
"Got no info about logged-in users"
"from oVirt agent. Retrying.")
""" go through all json responces, search for active-user:
"""
for python_line in info_lines:
if python_line: # if line is not empty
try:
reply_data = json.loads(python_line)
if reply_data['__name__'] == "active-user":
got_reply = 1
query_retry += 1
self.logger.debug ("User query retry: %s", query_retry)
if reply_data["name"] == "None" or reply_data["name"]=="" or reply_data["name"]=="(unknown)":
self.logger.debug ("There are currently no users logged into machine " +self.vmname)
self.logger.debug(
"User query retry: %s",
query_retry)
if (reply_data["name"] == "None" or
reply_data["name"] == "" or
reply_data["name"] == "(unknown)"):
self.logger.debug(
"There are currently "
"no users logged "
"into machine " +
self.vmname)
else:
self.logger.debug ("There's user " + reply_data["name"] + " logged into machine " + self.vmname)
self.logger.info ("User login success")
self.logger.debug(
"There's user " +
reply_data["name"] +
" logged into "
"machine " +
self.vmname)
self.logger.info("User login success")
is_logged = 1
else:
got_reply = 0
except:
self.logger.debug("Non-json data: " + python_line)
if self.os_type == 'linux': # do not wait for users to fully login as on windows
self.logger.debug(
"Non-json data: " +
python_line)
""" Do not wait for users to fully login as on windows:
"""
if self.os_type == 'linux':
query_retry = 10
time.sleep(10)
elif not ready[0]:
self.logger.info ("Socket timeout for VM: %s", self.vmname)
self.logger.info("Socket timeout for VM: %s", self.vmname)
elif not self.username:
self.logger.debug("Username is empty for VM: %s. Skipping SSO", self.vmname)
self.logger.debug(
"Username is empty for VM: %s. Skipping SSO",
self.vmname)
except Exception, e:
self.logger.warning ("Virtio socket %s failure for VM: %s", socket_path, self.vmname)
self.logger.debug ("Closing vm %s, login thread due error %s", self.vmname, e)
self.logger.warning(
"Virtio socket %s failure for VM: %s",
socket_path,
self.vmname)
self.logger.debug(
"Closing vm %s, login thread due error %s",
self.vmname, e)
# cleaning credential information from memory
self.username = None
self.password = None
Expand All @@ -104,7 +162,7 @@ def run(self):
info = virtio_socket.recv(1024)
if not info:
break
self.logger.debug ("Closing socket %s", socket_path)
self.logger.debug("Closing socket %s", socket_path)
virtio_socket.close()
self.logger.info ("Done: %s", self.vmname)
self.logger.debug ("Closing vm %s, login thread", self.vmname)
self.logger.info("Done: %s", self.vmname)
self.logger.debug("Closing vm %s, login thread", self.vmname)
2 changes: 1 addition & 1 deletion KVM/hypervisors/module/Variables.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
global terminate
global terminate
35 changes: 20 additions & 15 deletions KVM/hypervisors/vdi-agent
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import time
import socket
import os, os.path
import os
import json
from ConfigParser import ConfigParser
import logging
Expand All @@ -13,27 +13,30 @@ from module.VMStartupService import VMStartupService

def main():
sockfile = "/usr/local/VDI/kvm-vdi.sock"
logdir = "/var/log/VDI";
logdir = "/var/log/VDI"
if not os.path.exists(logdir):
os.makedirs(logdir)
if os.path.exists( sockfile ):
os.remove( sockfile )
if os.path.exists(sockfile):
os.remove(sockfile)
logging.config.fileConfig('/usr/local/VDI/config')
logger = logging.getLogger('kvm-vdi-agent')
logger.info("Starting KVM-VDI hypervisor agent")
server = socket.socket( socket.AF_UNIX, socket.SOCK_STREAM )
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(sockfile)
os.chmod(sockfile, 0o777)
server.listen(5)
config = ConfigParser()
config.read('/usr/local/VDI/config')
socket_timeout = int(config.get('agent', 'socket_timeout'))
Variables.terminate = 1 # oVirt agent seems to have fixed issue with windows OS. Making login thread exit after login routine
""" oVirt agent seems to have fixed issue with windows OS.
Making login thread exit after login routine:
"""
Variables.terminate = 1
try:
while True:
conn, addr = server.accept()
while True:
data = conn.recv( 1024 )
data = conn.recv(1024)
if not data:
break
else:
Expand All @@ -56,22 +59,24 @@ def main():
except:
fail = 1
if fail == 1:
logger.info ("Illegal json")
logger.debug ("Illegal json: %s", data)
logger.info("Illegal json")
logger.debug("Illegal json: %s", data)
else:
logger.debug("Starting login thread for vm: %s", vmname)
VMStartupService(vmname, username, password, os_type, socket_timeout).start()
VMStartupService(
vmname,
username,
password,
os_type,
socket_timeout).start()
break
except KeyboardInterrupt:
logger.debug("Keyboard interrupt")
Variables.terminate = 1
time.sleep(1)
server.close()
os.remove( sockfile )
os.remove(sockfile)


if __name__ == '__main__':
main()




0 comments on commit 14ded88

Please sign in to comment.