Better error handling, Efforts to run non-root with occasional sudo
This commit is contained in:
parent
808271f3e0
commit
f980cdb464
7 changed files with 90 additions and 47 deletions
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue