コード例 #1
0
def get_all_domains(cu):
    logger.info('Obteniendo dominios')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domains = conn.listAllDomains()
        domains_list = list()
        for dom in domains:
            is_active = True if dom.isActive() == 1 else False
            uuid = dom.UUIDString()
            name = dom.name()
            os_type = dom.OSType()
            total_memory = round(dom.info()[1] / 1024, 2)  # KB to MB
            used_memory = "-" if not is_active else round(
                dom.info()[2] / 1024, 2)  # KB to MB
            memory = dict(total=total_memory, used=used_memory)
            vcpus = dom.info()[3]
            state = dom.info()[0]
            vnc_port = get_vnc_port(dom)

            domains_list.append(
                dict(uuid=uuid,
                     name=name,
                     is_active=is_active,
                     os_type=os_type,
                     memory=memory,
                     vcpus=vcpus,
                     state=state,
                     vnc_port=vnc_port))
        conn.close()
        return json_response(data=domains_list)
    except Exception as e:
        logger.error('No se pudo obtener los dominios: %s', str(e))
        return json_response(status=500)
コード例 #2
0
def get_settings(cu):
    logger.info("Obteniendo parámetros")
    try:
        parameters = models.Config.get()
        return json_response(parameters)
    except Exception as e:
        logger.error('Error obteniendo la configuración: %s', e)
        return json_response(status=500)
コード例 #3
0
def get_logs(cu):
    try:
        with open('dvls.log', 'r') as f:
            log = f.readlines()
        return json_response(data=log)
    except Exception as e:
        logger.error('No se ha podido leer el fichero de logs: %s', str(e))
        return json_response(status=500)
コード例 #4
0
def get_hosts(cu):
    logger.info('Obteniendo los hosts')
    try:
        hosts = Host.get()
        return json_response(data=[h.to_dict() for h in hosts])
    except Exception as e:
        logger.error('No se han podido obtener los hosts: %s', str(e))
        return json_response(status=500)
コード例 #5
0
ファイル: hosts.py プロジェクト: Acova/DIS-vLab-Server-2_0
def get_hosts(cu, lab_uuid):
    logger.info('Obteniendo los hosts del laboratorio %s', lab_uuid)
    try:
        lab = Lab.get(lab_uuid)
        hosts = lab.hosts
        return json_response(data=[h.to_dict() for h in hosts])
    except Exception as e:
        logger.error('No se han podido obtener los hosts: %s', str(e))
        return json_response(status=500)
コード例 #6
0
def add_host(cu):
    logger.info('Añadiendo host')
    try:
        host = Host(request.json)
        host.save()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido añadir el host: %s', str(e))
        return json_response(status=500)
コード例 #7
0
def clone_template(cu, template_uuid):
    logger.info('Desplegando plantilla')
    try:
        template = Template.get(template_uuid).to_dict()
        domain_name = request.json['domain_name']
        lab_uuid = request.json['lab_uuid']

        lab = Lab.get(lab_uuid)
        hosts = lab.hosts

        if hosts.__len__() == 0:
            logger.error('El laboratorio no tiene ningún host asociado')
            return json_response(status=500)

        cmd = [
            'virt-clone', '--connect', app.config['LOCAL_QEMU_URI'],
            '--original-xml', template['xml_path'], '--name', domain_name
        ]

        for count in range(template['images_path'].__len__()):
            cmd.append('--file')
            cmd.append(app.config['DOMAIN_IMAGES_DIR'] + domain_name +
                       '-disk' + str(count) + '.qcow2')

        ssh = paramiko.SSHClient()
        # Surrounds 'known_hosts' error
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        errors = list()
        for h in hosts:
            host = h.ip_address
            username = h.conn_user
            try:
                # NO PASSWORD!! Server SSH key is previously distributed among lab PCs
                ssh.connect(hostname=host.compressed,
                            username=username,
                            timeout=4)
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(
                    ' '.join(cmd))
                errors = [b.rstrip() for b in ssh_stderr.readlines()]
                if len(errors) > 0:
                    logger.error(
                        'No se pudo desplegar la plantilla en el host %s (%s)',
                        h.code, h.ip_address.compressed)
                    logger.error(e for e in errors)
            except Exception as e:
                logger.error(
                    'No se pudo desplegar la plantilla en el host %s (%s): %s',
                    h.code, h.ip_address.compressed, str(e))
                errors = True
            finally:
                ssh.close()
        if errors or len(errors) > 0:
            return json_response(status=500)
        return json_response()
    except Exception as e:
        logger.error('No se pudo desplegar la plantilla: %s', str(e))
        return json_response(status=500)
コード例 #8
0
def delete_host(cu, host_uuid):
    logger.info('Eliminando host %s', host_uuid)
    try:
        host = Host.get(host_uuid)
        Host.delete(host)
        return json_response()
    except Exception as e:
        logger.error('No se ha podido eliminar el host %s: %s', host_uuid,
                     str(e))
コード例 #9
0
def get_templates(cu):
    logger.info('Obteniendo plantillas')
    try:
        templates = Template.get()
        data = [t.to_dict() for t in templates]
        return json_response(data=data)
    except Exception as e:
        logger.error('No se pudo obtener las plantillas: %s', str(e))
        return json_response(status=500)
コード例 #10
0
ファイル: labs.py プロジェクト: albertososa95/DIS-vLab-Server
def get_labs(cu):
    logger.info('Obteniendo laboratorios')
    try:
        labs = Lab.get()
        data = [l.to_dict() for l in labs]
        return json_response(data=data)
    except Exception as e:
        logger.error('No se pudo obtener los laboratorios: %s', str(e))
        return json_response(status=500)
コード例 #11
0
ファイル: base.py プロジェクト: Rgcsh/sanic_frame_demo
async def exception_handler(request, exception):
    """
    意外错误
    :param request:
    :param exception:
    :return:
    """
    logger.error(traceback.format_exc())
    return json_fail_response()
コード例 #12
0
def clear_logs(cu):
    logger.info('Limpiando el fichero de logs')
    try:
        logs_file = open('dvls.log', 'w')
        logs_file.truncate()
        logs_file.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido limpiar el fichero de logs: %s', str(e))
        return json_response(status=500)
コード例 #13
0
ファイル: labs.py プロジェクト: Acova/DIS-vLab-Server-2_0
def update_lab(cu, lab_uuid):
    logger.info('Actualizando laboratorio %s', lab_uuid)
    try:
        lab = Lab.get(lab_uuid)
        lab.update(request.json)
        return json_response()
    except Exception as e:
        logger.error('No se pudo actualizar el laboratorio %s: %s', lab_uuid,
                     e)
        return json_response(status=500)
コード例 #14
0
ファイル: labs.py プロジェクト: albertososa95/DIS-vLab-Server
def delete_lab(cu, lab_uuid):
    logger.info('Eliminando laboratorio')
    try:
        lab = Lab.get(lab_uuid)
        Lab.delete(lab)
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar el laboratorio seleccionado: %s',
                     str(e))
        return json_response(status=500)
コード例 #15
0
def get_dashboard():
    logger.info('Cargando dashboard')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        host_info = get_host_details(conn)
        host_info['templates'] = len(Template.get())
        host_info['labs'] = len(Lab.get())
        conn.close()
        return json_response(data=host_info)
    except Exception as e:
        logger.error('No se pudo obtener el dashboard: %s', libvirt.virGetLastErrorMessage())
        return json_response(status=500)
コード例 #16
0
def delete_template(cu, template_uuid):
    logger.info('Eliminando plantilla')
    try:
        template = Template.get(template_uuid)
        for image_path in pickle.loads(template.images_path):
            subprocess.check_call(['rm', '-f', image_path])
        subprocess.check_call(['rm', '-f', template.xml_path])
        Template.delete(template)
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar la plantilla: %s', str(e))
        return json_response(status=500)
コード例 #17
0
def reboot_domain(cu, domain_uuid):
    logger.info('Reiniciando dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.reboot(libvirt.VIR_DOMAIN_REBOOT_DEFAULT)
        time.sleep(3)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido reiniciar el dominio %s: %s',
                     domain_uuid, str(e))
        return json_response(status=500)
コード例 #18
0
def get_all_domains(cu):
    logger.info('Obteniendo dominios')
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domains = conn.listAllDomains()
        domains_list = list()
        for dom in domains:
            is_active = True if dom.isActive() == 1 else False
            uuid = dom.UUIDString()
            name = dom.name()
            os_type = dom.OSType()
            total_memory = round(dom.info()[1] / 1024, 2)  # KB to MB
            used_memory = "-" if not is_active else round(
                dom.info()[2] / 1024, 2)  # KB to MB
            memory = dict(total=total_memory, used=used_memory)
            vcpus = dom.info()[3]
            state = dom.info()[0]
            vnc_port = get_vnc_port(dom)

            # ADDED SUPPORT FOR DISKS
            xml = ET.fromstring(dom.XMLDesc())
            devices = xml.findall('devices/disk')

            disk = {}

            for d in devices:
                if d.get('device') == 'disk':
                    file_path = d.find('source').get('file')
                    disk_info = dom.blockInfo(file_path)
                    disk['capacity'] = round(disk_info[0] / 1024 / 1024 / 1024,
                                             2)
                    disk['allocation'] = round(
                        disk_info[1] / 1024 / 1024 / 1024, 2)
                    disk['physical'] = round(disk_info[2] / 1024 / 1024 / 1024,
                                             2)

            domains_list.append(
                dict(uuid=uuid,
                     name=name,
                     is_active=is_active,
                     os_type=os_type,
                     memory=memory,
                     vcpus=vcpus,
                     state=state,
                     disk=disk,
                     vnc_port=vnc_port))
        conn.close()
        return json_response(data=domains_list)
    except Exception as e:
        logger.error('No se pudo obtener los dominios: %s', str(e))
        return json_response(status=500)
コード例 #19
0
def update_domain(cu, domain_uuid):
    logger.info('Actualizando el dominio %s', domain_uuid)
    data = request.json
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        dom = conn.lookupByUUIDString(domain_uuid)
        dom.setMaxMemory(int(data['memory']) * 1024)
        dom.setVcpusFlags(
            int(data['vcpus']),
            libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_VCPU_MAXIMUM)
        dom.setVcpusFlags(int(data['vcpus']))
    except Exception as e:
        logger.error("No se ha podido actualizar el dominio %s: %s",
                     domain_uuid, str(e))
    return json_response(status=200)
コード例 #20
0
ファイル: labs.py プロジェクト: albertososa95/DIS-vLab-Server
def create_lab(cu):
    logger.info('Añadiendo laboratorio')
    try:
        lab = Lab(request.json)
        ip_range = ip_range_to_list(lab.start_ip_range, lab.end_ip_range)
        for ip in ip_range:
            data = dict(code=lab.code + '_' + str(ip_range.index(ip)),
                        ip_address=ip,
                        conn_user='******',
                        lab_uuid=lab.uuid)
            lab.add_host(Host(data))
        lab.save()
        return json_response()
    except Exception as e:
        logger.error('No se pudo añadir el laboratorio: %s', str(e))
        return json_response(status=500)
コード例 #21
0
def start_domain(cu, domain_uuid):
    logger.info('Encendiendo dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.create()
        time.sleep(3)
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.info()[0] != libvirt.VIR_DOMAIN_RUNNING:
            logger.error('No se pudo encender el dominio %s', domain_uuid)
            conn.close()
            return json_response(status=500)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se pudo encender el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
コード例 #22
0
 def decorated(*args, **kwargs):
     token = None
     if 'JWT-Token' in request.headers:
         token = request.headers['JWT-Token']
         if not token:
             logger.error(
                 'No se ha encontrado el token de sesión en las cabeceras')
             return json_response(status=401)
     try:
         data = jwt.decode(token, app.config['SECRET_KEY'])
         current_user = data['username']
     except Exception as e:
         exc_type, exc_obj, exc_tb = sys.exc_info()
         fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
         print(exc_type, fname, exc_tb.tb_lineno)
         logger.error('El token de sesión no es válido o ha caducado')
         return json_response(status=401)
     return f(current_user, *args, **kwargs)
コード例 #23
0
def shutdown_domain(cu, domain_uuid):
    logger.info('Apagando el dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        domain.destroy()
        time.sleep(3)
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.info()[0] != libvirt.VIR_DOMAIN_SHUTOFF:
            logger.error('No se pudo apagar el dominio %s', domain_uuid)
            conn.close()
            return json_response(status=500)
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se ha podido apagar el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
コード例 #24
0
def create_domain(cu):
    logger.info('Creando dominio')

    data = request.json
    cmd = [
        'virt-install', '--connect', app.config['LOCAL_QEMU_URI'], '--name',
        data['name'], '--memory',
        str(data['memory']), '--vcpus',
        str(data['vcpus']), '--os-variant', data['os_variant'],
        '--noautoconsole'
    ]
    if data['graphics']['vnc']:
        cmd.append('--graphics')
        cmd.append('vnc,listen=' + data['graphics']['listen'] + ',password='******'graphics']['password'])
    if data['installation_type'] == "iso":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--cdrom')
        cmd.append(data['cdrom'])
    elif data['installation_type'] == "image":
        cmd.append('--disk')
        cmd.append(data['disk']['path'])
        cmd.append('--import')
    elif data['installation_type'] == "network":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--location')
        cmd.append(data['location'])
    elif data['installation_type'] == "pxe":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--network')
        cmd.append(data['network'])
        cmd.append('--pxe')
    else:
        logger.warn('El método de instalación no es correcto')
        return json_response(status=400)
    try:
        subprocess.check_call(cmd)
        return json_response()
    except Exception as e:
        logger.error('No se ha podido crear el dominio: %s', str(e))
        return json_response(status=500)
コード例 #25
0
def delete_domain(cu, domain_uuid):
    logger.info('Eliminando dominio %s', domain_uuid)
    try:
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        xml = ET.fromstring(domain.XMLDesc())
        devices = xml.findall('devices/disk')
        for d in devices:
            if d.get('device') == 'disk':
                file_path = d.find('source').get('file')
                disk = conn.storageVolLookupByPath(file_path)
                disk.delete(libvirt.VIR_STORAGE_VOL_DELETE_NORMAL)
        domain.undefine()
        conn.close()
        return json_response()
    except Exception as e:
        logger.error('No se pudo eliminar el dominio %s: %s', domain_uuid,
                     str(e))
        return json_response(status=500)
コード例 #26
0
ファイル: login.py プロジェクト: Acova/DIS-vLab-Server-2_0
def login():
    logger.debug('Autenticando usuario')
    try:
        auth = request.authorization
        if not auth or not auth.username or not auth.password:
            logger.error(
                'No se ha podido autenticar al usuario: faltan las credenciales!'
            )
            return json_response(status=400)

        p = pam.pam()
        # user = p.authenticate(username=auth.username, password=auth.password, service='dvls')
        user = p.authenticate(username=auth.username, password=auth.password)

        if user and (auth.username == app.config['CONN_USER']):
            token = jwt.encode(
                dict(username=auth.username,
                     exp=datetime.utcnow() + timedelta(minutes=60)),
                app.config['SECRET_KEY'])
            return json_response(data=dict(token=token.decode('UTF-8')))

        logger.error(
            'No se ha podido autenticar al usuario: las credenciales son incorrectas!'
        )
        return json_response(status=403)
    except Exception as e:
        logger.error('No se ha podido autenticar al usuario: %s', str(e))
        return json_response(status=500)
コード例 #27
0
def create_domain(self, data):
    cmd = [
        'virt-install', '--connect', app.config['LOCAL_QEMU_URI'], '--name',
        data['name'], '--memory',
        str(data['memory']), '--vcpus',
        str(data['vcpus']), '--os-variant', data['os_variant'],
        '--noautoconsole'
    ]
    if data['graphics']['vnc']:
        cmd.append('--graphics')
        cmd.append('vnc,listen=' + data['graphics']['listen'] + ',password='******'graphics']['password'])
    if data['installation_type'] == "iso":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--cdrom')
        cmd.append(data['cdrom'])
    elif data['installation_type'] == "image":
        cmd.append('--disk')
        cmd.append(data['disk']['path'])
        cmd.append('--import')
    elif data['installation_type'] == "network":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--location')
        cmd.append(data['location'])
    elif data['installation_type'] == "pxe":
        cmd.append('--disk')
        cmd.append('size=' + str(data['disk']['size']))
        cmd.append('--network')
        cmd.append(data['network'])
        cmd.append('--pxe')
    else:
        logger.warn('El método de instalación no es correcto')
        socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
        socketio.emit(
            'task-finished', {
                'task_type': 'add-domain',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
        return -1
    try:
        subprocess.check_call(cmd)
        logger.info('Dominio creado')
        socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
        socketio.emit(
            'task-finished', {
                'task_type': 'add-domain',
                'task_id': self.request.id.__str__(),
                'status': 0
            })
        return 0
    except Exception as e:
        logger.error('No se ha podido crear el dominio: %s', str(e))
        socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
        socketio.emit(
            'task-finished', {
                'task_type': 'add-domain',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
        return -1
コード例 #28
0
def clone_template(self, template_uuid, data):
    logger.info("Desplegando nueva plantilla")
    socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
    try:
        template = Template.get(template_uuid).to_dict()
        domain_name = data['domain_name']
        lab_uuid = data['lab_uuid']

        lab = Lab.get(lab_uuid)
        hosts = lab.hosts

        if hosts.__len__() == 0:
            logger.error('El laboratorio no tiene ningún host asociado')
            socketio.emit('task-finished', {
                'task_type': 'clone-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        cmd = ['virt-clone',
               '--connect', app.config['LOCAL_QEMU_URI'],
               '--original-xml', template['xml_path'],
               '--name', domain_name]

        for count in range(template['images_path'].__len__()):
            cmd.append('--file')
            cmd.append(app.config['DOMAIN_IMAGES_DIR'] + domain_name + '-disk' + str(count) + '.qcow2')

        ssh = paramiko.SSHClient()
        # Surrounds 'known_hosts' error
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        k = paramiko.RSAKey.from_private_key_file("/home/dvls/.ssh/id_rsa")
        errors = list()
        for h in hosts:
            host = h.ip_address
            username = h.conn_user
            logger.debug('Desplegando en el host %s, IP: %s', h.code, h.ip_address)
            try:
                # NO PASSWORD!! Server SSH key is previously distributed among lab PCs
                logger.debug('Conectando al equipo')
                ssh.connect(hostname=host.compressed, username=username, timeout=4, pkey=k)
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(' '.join(cmd))
                errors = [b.rstrip() for b in ssh_stderr.readlines()]
                if len(errors) > 0:
                    logger.error('No se pudo desplegar la plantilla en el host %s (%s)', h.code, h.ip_address.compressed)
                    logger.error(cmd)
                    logger.error(errors)
            except Exception as e:
                logger.error('No se pudo desplegar la plantilla en el host %s (%s): %s', h.code, h.ip_address.compressed, str(e))
                errors = True
            finally:
                logger.debug('Desplegado en el equipo %s', h.code)
                ssh.close()
        if errors or len(errors) > 0:
            socketio.emit('task-finished', {
                'task_type': 'clone-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        socketio.emit('task-finished', {
            'task_type': 'clone-template',
            'task_id': self.request.id.__str__(),
            'status': 0
        })
        logger.info("Plantilla desplegada correctamente")
        return 0
    except Exception as e:
        logger.error('No se pudo desplegar la plantilla: %s', str(e))
        socketio.emit('task-finished', {
            'task_type': 'clone-template',
            'task_id': self.request.id.__str__(),
            'status': -1
        })
        return -1
コード例 #29
0
def create_template(self, data):
    socketio = SocketIO(message_queue=app.config['CELERY_BROKER_URL'])
    try:
        domain_uuid = data['domain_uuid']
        template_name = data['template_name']
        template_description = data['template_description']
        do_sysprep = data['do_sysprep']

        # Check domain state
        conn = libvirt.open(app.config['LOCAL_QEMU_URI'])
        domain = conn.lookupByUUIDString(domain_uuid)
        if domain.isActive():
            logger.error('No se pudo crear la plantilla: el dominio debe estar apagado')
            socketio.emit('task-finished', {
                'task_type': 'create-template',
                'task_id': self.request.id.__str__(),
                'status': -1
            })
            return -1

        # Domain cloning (get disks paths and some hardware stuff)
        info = domain.info()
        memory = info[2]
        vcpus = info[3]

        xml = ET.fromstring(domain.XMLDesc())
        devices = xml.findall('devices/disk')
        disks = list()
        for d in devices:
            if d.get('device') == 'disk':
                file_path = d.find('source').get('file')
                disks.append(file_path)

        cmd = ['virt-clone',
               '--connect', app.config['LOCAL_QEMU_URI'],
               '--original', domain.name(),
               '--name', template_name]
        template_images_path = list()
        for count in range(disks.__len__()):
            template_image_path = app.config['TEMPLATE_IMAGES_DIR'] + template_name + '-disk' + str(count) + '.qcow2'
            template_images_path.append(template_image_path)
            cmd.append('--file')
            cmd.append(template_image_path)
        subprocess.check_call(cmd)

        if do_sysprep:
            # Decontextualize the template and dumps XML --> USING POLICYKIT WITH 'virt-sysprep'
            subprocess.check_call(['pkexec', '/usr/bin/virt-sysprep',
                                   '--connect', app.config['LOCAL_QEMU_URI'],
                                   '--domain', template_name])
        template_xml = str(app.config['TEMPLATE_DEFINITIONS_DIR'] + template_name + '.xml')
        proc = subprocess.Popen(['virsh', '--connect', app.config['LOCAL_QEMU_URI'], 'dumpxml', template_name],
                                stdout=subprocess.PIPE)
        out = proc.stdout.read().decode('utf-8')
        # print(out)

        file = open(str(template_xml), 'w')
        file.write(out)
        file.close()

        # Undefine template
        template = conn.lookupByName(template_name)
        template.undefine()

        # Add template to database

        data = dict(name=template_name,
                    description=template_description,
                    vcpus=vcpus,
                    memory=memory,
                    xml_path=template_xml,
                    images_path=template_images_path)
        template = Template(data)
        template.save()
        logger.info("Plantilla creada")
        socketio.emit('task-finished', {
            'task_type': 'create-template',
            'task_id': self.request.id.__str__(),
            'status': 0
        })
        return 0
    except Exception as e:
        # TODO - Delete template on fs if Exception is instance of sqlite3.OperationalError
        logger.error('No se pudo crear la plantilla: %s', str(e))
        socketio.emit('task-finished', {
            'task_type': 'create-template',
            'task_id': self.request.id.__str__(),
            'status': -1
        })
        return -1