Better error handling, Efforts to run non-root with occasional sudo

This commit is contained in:
ahmadbilalkhalid 2019-12-29 23:14:39 +05:00
commit f980cdb464
7 changed files with 90 additions and 47 deletions

View file

@ -91,6 +91,14 @@ class VMM:
self.vmm_backend = vmm_backend
self.socket_dir = os.path.join(self.vmm_backend, 'sock')
if not os.path.isdir(self.vmm_backend):
logger.info('{} does not exists. Creating it...'.format(self.vmm_backend))
os.makedirs(self.vmm_backend, exist_ok=True)
if not os.path.isdir(self.socket_dir):
logger.info('{} does not exists. Creating it...'.format(self.socket_dir))
os.makedirs(self.socket_dir, exist_ok=True)
def is_running(self, uuid):
sock_path = os.path.join(self.vmm_backend, uuid)
try:
@ -99,8 +107,8 @@ class VMM:
recv = sock.recv(4096)
except Exception as err:
# unix sock doesn't exists or it is closed
logger.info('VM %s sock either don\' exists or it is closed.', uuid,
'It mean VM is stopped.', exc_info=err)
logger.debug('VM {} sock either don\' exists or it is closed. It mean VM is stopped.'.format(uuid),
exc_info=err)
else:
# if we receive greetings from qmp it mean VM is running
if len(recv) > 0:
@ -120,16 +128,34 @@ class VMM:
if self.is_running(uuid):
logger.warning('Cannot start VM. It is already running.')
else:
qmp_arg = ('-qmp', 'unix:{}/{},server,nowait'.format(self.vmm_backend, uuid))
qmp_arg = ('-qmp', 'unix:{},server,nowait'.format(join_path(self.vmm_backend, uuid)))
vnc_arg = ('-vnc', 'unix:{}'.format(tempfile.NamedTemporaryFile().name))
command = [self.qemu_path, *args, *qmp_arg, *migration_args, *vnc_arg, '-daemonize']
command = ['sudo', '-p', 'Enter password to start VM {}: '.format(uuid),
self.qemu_path, *args, *qmp_arg, *migration_args, *vnc_arg, '-daemonize']
try:
sp.check_output(command, stderr=sp.PIPE)
except sp.CalledProcessError as err:
logger.exception('Error occurred while starting VM.\nDetail %s', err.stderr.decode('utf-8'))
else:
time.sleep(2)
with suppress(sp.CalledProcessError):
sp.check_output([
'sudo', '-p',
'Enter password to correct permission for uncloud-vmm\'s directory',
'chmod', '-R', 'o=rwx,g=rwx', self.vmm_backend
])
# TODO: Find some good way to check whether the virtual machine is up and
# running without relying on non-guarenteed ways.
for _ in range(10):
time.sleep(2)
status = self.get_status(uuid)
if status in ['running', 'inmigrate']:
return status
logger.warning('Timeout on VM\'s status. Shutting down VM %s', uuid)
self.stop(uuid)
# TODO: What should we do more. VM can still continue to run in background.
# If we have pid of vm we can kill it using OS.
def execute_command(self, uuid, command, **kwargs):
# execute_command -> sucess?, output
@ -141,12 +167,12 @@ class VMM:
}
sock_handle.sendall(json.dumps(command_to_execute).encode('utf-8'))
output = file_handle.readline()
except Exception as err:
except Exception:
logger.exception('Error occurred while executing command and getting valid output from qmp')
else:
try:
output = json.loads(output)
except:
except Exception:
logger.exception('QMP Output isn\'t valid JSON. %s', output)
else:
return 'return' in output, output
@ -161,6 +187,7 @@ class VMM:
if success:
return output['return']['status']
else:
# TODO: Think about this for a little more
return 'STOPPED'
def discover(self):