Пример #1
0
def update_storage_list(db: Session, model: TaskModel):
    nodes = db.query(NodeModel).all()

    token = time()

    for node in nodes:
        if node.status != 10:
            continue
        try:
            logger.info(f'ノードへ接続します: {node.user_name + "@" + node.domain}')
            manager = virtlib.VirtManager(node_model=node)
        except:
            logger.error(f'ノードへの接続に失敗しました: {node.name}')
            continue

        logger.debug('ノードに接続しました')

        storages = manager.storage_data(token=token)
        for storage in storages:
            for image in storage["image"]:
                image = ImageModel(**image.dict())
                image.storage_uuid = storage["storage"].uuid
                db.merge(image)
            db.merge(storage["storage"])
    db.commit()
    # トークンで除外
    db.query(StorageModel).filter(StorageModel.update_token != token).delete()
    db.query(ImageModel).filter(ImageModel.update_token != token).delete()
    db.commit()
    return model
Пример #2
0
def change_domain_base(db: Session, model: TaskModel):
    request: DomainPatch = DomainPatch(**model.request)

    try:
        domain: DomainModel = db.query(DomainModel).filter(DomainModel.uuid == request.uuid).one()
    except:
        raise Exception("domain not found")

    try:
        node: NodeModel = db.query(NodeModel).filter(NodeModel.name == domain.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)

    # 電源
    if request.status == "on":
        manager.domain_poweron(uuid=request.uuid)
    elif request.status == "off":
        manager.domain_destroy(uuid=request.uuid)
    
    # CDROM 
    if request.status == "mount":
        manager.domain_cdrom(request.uuid, request.target, request.path)
    elif request.status == "unmount":
        manager.domain_cdrom(request.uuid, request.target)

    update_domain_list(db=db, model=TaskModel())

    return model
Пример #3
0
def update_network_list(db: Session, model: TaskModel):
    nodes = db.query(NodeModel).all()

    token = time()

    for node in nodes:
        if node.status != 10:
            continue
        try:
            logger.info(f'ノードへ接続します: {node.user_name + "@" + node.domain}')
            manager = virtlib.VirtManager(node_model=node)
        except:
            logger.error(f'ノードへの接続に失敗しました: {node.name}')
            continue

        for network in manager.network_data(token=token):
            network: NetworkModel
            network.node_name = node.name
            db.merge(network)
            print(network)

    db.commit()
    # トークンで削除
    db.query(NetworkModel).filter(NetworkModel.update_token!=token).delete()
    db.commit()
    return model
Пример #4
0
def update_storage_list(db: Session, model: TaskModel):
    nodes = db.query(NodeModel).all()

    token = time()

    for node in nodes:
        if node.status != 10:
            continue

        logger.info(f'connectiong node: {node.user_name + "@" + node.domain}')
        manager = virtlib.VirtManager(node_model=node)

        storages = manager.storage_data(token=token)
        for storage in storages:
            for image in storage["image"]:
                image = ImageModel(**image.dict())
                image.storage_uuid = storage["storage"].uuid
                # イメージを登録
                db.merge(image)
            # ストレージを登録
            db.merge(storage["storage"])
    db.commit()
    # トークンで除外
    db.query(StorageModel).filter(
        StorageModel.update_token != str(token)).delete()
    db.query(ImageModel).filter(ImageModel.update_token != str(token)).delete()
    db.commit()
    return model
Пример #5
0
def delete_storage_base(db: Session, model: TaskModel):
    request: StorageDelete = StorageDelete(**model.request)

    try:
        node: NodeModel = db.query(NodeModel).filter(
            NodeModel.name == request.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)
    manager.storage_undefine(request.uuid)

    # update_storage_list(db=db, model=TaskModel())

    db.query(StorageModel).filter(StorageModel.uuid == request.uuid).delete()
    db.commit()

    return model
Пример #6
0
def delete_network_ovs(db: Session, model: TaskModel):
    request: NetworkOVSDelete = NetworkOVSDelete(**model.request)

    try:
        network: NetworkModel = db.query(NetworkModel).filter(
            NetworkModel.uuid == request.uuid).one()
    except:
        raise Exception("network not found")
    try:
        node: NodeModel = db.query(NodeModel).filter(
            NodeModel.name == network.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)
    manager.network_ovs_delete(uuid=network.uuid, name=request.name)

    return model
Пример #7
0
def delete_domain_base(db: Session, model: TaskModel):
    request: DomainInsert = DomainDelete(**model.request)

    try:
        domain: DomainModel = db.query(DomainModel).filter(DomainModel.uuid == request.uuid).one()
    except:
        raise Exception("domain not found")

    try:
        node: NodeModel = db.query(NodeModel).filter(NodeModel.name == domain.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)
    manager.domain_undefine(request.uuid)

    update_domain_list(db=db, model=TaskModel())

    return model
Пример #8
0
def change_domain_network(db: Session, model: TaskModel):
    request: DomainNetworkChange = DomainNetworkChange(**model.request)

    try:
        domain: DomainModel = db.query(DomainModel).filter(DomainModel.uuid == request.uuid).one()
    except:
        raise Exception("domain not found")

    try:
        node: NodeModel = db.query(NodeModel).filter(NodeModel.name == domain.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)
    manager.domain_network(uuid=request.uuid, network=request.network_name, port=request.port, mac=request.mac)

    update_domain_list(db=db, model=TaskModel())

    return model
Пример #9
0
def add_storage_base(db: Session, model: TaskModel):
    request: StorageInsert = StorageInsert(**model.request)

    try:
        node: NodeModel = db.query(NodeModel).filter(
            NodeModel.name == request.node_name).one()
    except:
        raise Exception("node not found")

    # XMLを定義、設定
    editor = xmllib.XmlEditor("static", "storage_dir")
    editor.storage_base_edit(name=request.name, path=request.path)

    # ソイや!
    manager = virtlib.VirtManager(node_model=node)
    manager.storage_define(xml_str=editor.dump_str())

    update_storage_list(db=db, model=TaskModel())

    return model
Пример #10
0
def delete_network_base(db: Session, model: TaskModel):
    request: NetworkDelete = NetworkDelete(**model.request)

    try:
        network: NetworkModel = db.query(NetworkModel).filter(
            NetworkModel.uuid == request.uuid).one()
    except:
        raise Exception("network not found")

    try:
        node: NodeModel = db.query(NodeModel).filter(
            NodeModel.name == network.node_name).one()
    except:
        raise Exception("node not found")

    manager = virtlib.VirtManager(node_model=node)
    manager.network_undefine(request.uuid)

    update_network_list(db=db, model=TaskModel())

    return model
Пример #11
0
def update_domain_list(db: Session, model: TaskModel):
    nodes:NodeModel = db.query(NodeModel).filter(NodeModel.roles.any(name="libvirt"))
    token = time()

    for node in nodes:
        if node.status != 10:
            continue
        logger.info(f'connecting node: {node.user_name + "@" + node.domain}')
        try:
            manager = virtlib.VirtManager(node_model=node)
        except Exception as e:
            logger.error(f'{e}')
            continue

        domains = manager.domain_data()

        for domain in domains:
            editor = xmllib.XmlEditor("str",domain['xml'])
            editor.dump_file("domain")
            temp = editor.domain_parse()
            
            row = DomainModel(
                uuid = temp.uuid,
                name = temp.name,
                core = temp.vcpu,
                memory = temp.memory,
                status = domain['status'],
                node_name = node.name,
                update_token = token
            )
            db.merge(row)
        # ノードが変わる前に一度コミット
        db.commit()
    db.query(DomainModel).filter(DomainModel.update_token!=str(token)).delete()
    db.commit()
    return model
Пример #12
0
def add_network_base(db: Session, model: TaskModel):
    request: NetworkInsert = NetworkInsert(**model.request)

    try:
        node: NodeModel = db.query(NodeModel).filter(
            NodeModel.name == request.node_name).one()
    except:
        raise Exception("node not found")

    if request.type == "bridge":
        # XMLを定義、設定
        editor = xmllib.XmlEditor("static", "net_bridge")
        editor.network_bridge_edit(name=request.name,
                                   bridge=request.bridge_device)
        xml = editor.dump_str()
    elif request.type == "ovs":
        xml = f'''
        <network>
            <name>{request.name}</name>
            <forward mode="bridge" />
            <bridge name="{request.bridge_device}" />
            <virtualport type="openvswitch" />
            <portgroup name="untag" default="yes">
            </portgroup>
        </network>
        '''
    else:
        raise Exception("Type is incorrect")

    # ソイや!
    manager = virtlib.VirtManager(node_model=node)
    manager.network_define(xml_str=xml)

    update_network_list(db=db, model=TaskModel())

    return model
Пример #13
0
def add_domain_base(db: Session, model: TaskModel):
    task_model:TaskModel = model
    model: DomainInsert = DomainInsert(**task_model.request)

    domains: DomainModel = db.query(DomainModel).filter(DomainModel.name==model.name).all()

    try:
        node: NodeModel = db.query(NodeModel).filter(NodeModel.name==model.node_name).one()
    except:
        raise Exception("node not found")
    
    if domains != []:
        raise Exception("domain name is duplicated")

    manager = virtlib.VirtManager(node_model=node)
    editor = xmllib.XmlEditor("static","domain_base")

    editor.domain_emulator_edit(node.os_like)
    editor.domain_base_edit(
        domain_name=model.name,
        memory_mega_byte=model.memory_mega_byte,
        core=model.cpu,
        vnc_port=0,
        vnc_passwd=None
    )
    
    # ネットワークインターフェイス
    for interface in model.interface:
        interface: DomainInsertInterface
        editor.domain_interface_add(network_name=interface.network_name, mac_address=None)

    img_device_names = ["vda","vdb","vdc"]
    
    # ブロックデバイス
    for device, device_name in zip(model.disks, img_device_names):
        # 型定義
        device: DomainInsertDisk
        # 作成先のプールを参照
        try:
            new_pool: StorageModel = db.query(StorageModel).filter(StorageModel.uuid==device.save_pool_uuid).one()
        except:
            raise Exception("request pool uuid not found")
        # ファイル名決めてる
        create_image_path = new_pool.path +"/"+ model.name + "_" + device_name + '.img'
        # XMLに追加
        editor.domain_device_image_add(image_path=create_image_path, target_device=device_name)

        # 新規ディスクの場合
        if device.type == "empty":
            # 空のディスク作成
            ssh_manager = sshlib.SSHManager(user=node.user_name, domain=node.domain)
            ssh_manager.qemu_create(
                size_giga_byte=device.size_giga_byte,
                path=create_image_path
            )
        # 既存ディスクのコピー
        elif device.type == "copy":
            # コピー元のプール情報参照
            try:
                pool_model:StorageModel = db.query(StorageModel).filter(StorageModel.uuid==device.original_pool_uuid).one()
            except:
                raise Exception("request src pool uuid not found")
            pool_path = pool_model.path
            file_name = device.original_name
            from_image_path = pool_path + '/' + file_name

            logger.info(f'{from_image_path}を{create_image_path}へコピーします')
            ssh_manager = sshlib.SSHManager(user=node.user_name, domain=node.domain)
            ssh_manager.file_copy(
                from_path=from_image_path,
                to_path=create_image_path
            )

    # libvirtでXMLを登録
    manager.domain_define(xml_str=editor.dump_str())

    return task_model
Пример #14
0
def add_domain_base(db: Session, model: TaskModel):
    # 受け取ったデータをモデルに型付け
    task_model:TaskModel = model
    model: DomainInsert = DomainInsert(**task_model.request)

    # データベースから情報とってきて確認も行う
    domains: DomainModel = db.query(DomainModel).filter(DomainModel.name==model.name).all()
    try:
        node: NodeModel = db.query(NodeModel).filter(NodeModel.name==model.node_name).one()
    except:
        raise Exception("node not found")

    if domains != []:
        raise Exception("domain name is duplicated")


    # XMLのベース読み込んで編集開始
    editor = xmllib.XmlEditor("static","domain_base")

    editor.domain_emulator_edit(node.os_like)
    editor.domain_base_edit(
        domain_name=model.name,
        memory_mega_byte=model.memory_mega_byte,
        core=model.cpu,
        vnc_port=0,
        vnc_passwd=None
    )

    domain_uuid = editor.domain_uuid_generate()
    
    # ネットワークインターフェイス
    for interface in model.interface:
        interface: DomainInsertInterface
        editor.domain_interface_add(
            network_name=interface.network_name, 
            mac_address=None, 
            port=interface.port
        )

    img_device_names = ["vda","vdb","vdc"]
    
    # ブロックデバイス
    for device, device_name in zip(model.disks, img_device_names):
        # 型定義
        device: DomainInsertDisk
        # 作成先のプールを参照
        try:
            new_pool: StorageModel = db.query(StorageModel).filter(StorageModel.uuid==device.save_pool_uuid).one()
        except:
            raise Exception("request storage pool uuid not found")
        # ファイル名決めてる
        create_image_path = new_pool.path +"/"+ model.name + "_" + device_name + '.img'
        # XMLに追加
        editor.domain_device_image_add(image_path=create_image_path, target_device=device_name)

        # 新規ディスクの場合
        if device.type == "empty":
            # 空のディスク作成
            ssh_manager = sshlib.SSHManager(user=node.user_name, domain=node.domain, port=node.port)
            ssh_manager.qemu_create(
                size_giga_byte=device.size_giga_byte,
                path=create_image_path
            )
        # 既存ディスクのコピー
        elif device.type == "copy":
            # コピー元のプール情報参照
            try:
                pool_model:StorageModel = db.query(StorageModel).filter(StorageModel.uuid==device.original_pool_uuid).one()
            except:
                raise Exception("request src pool uuid not found")
            pool_path = pool_model.path
            file_name = device.original_name
            from_image_path = pool_path + '/' + file_name

            logger.info(f'{from_image_path}を{create_image_path}へコピーします')
            ssh_manager = sshlib.SSHManager(user=node.user_name, domain=node.domain, port=node.port)
            ssh_manager.file_copy(
                from_path=from_image_path,
                to_path=create_image_path
            )

    # Cloud-init
    if model.cloud_init != None:
        # iso作成
        cloudinit_manager = cloudinitlib.CloudInitManager(domain_uuid,model.cloud_init.hostname)
        cloudinit_manager.custom_user_data(model.cloud_init.userData)
        iso_path = cloudinit_manager.make_iso()

        # cloud-initのisoを保存するpoolを探す
        try:
            query = db.query(StorageModel).join(NodeModel).outerjoin(StorageMetadataModel)
            query = query.filter(NodeModel.name==node.name).filter(StorageMetadataModel.rool=="init-iso")
            init_pool_model:StorageModel = query.one()
        except:
            raise Exception("cloud-init pool not found")

        # 生成したisoをノードに転送
        send_path = f"{init_pool_model.path}/{domain_uuid}.iso"
        ansible_manager = ansiblelib.AnsibleManager(user=node.user_name, domain=node.domain)
        ansible_manager.file_copy_to_node(src=iso_path,dest=send_path)
        editor.domain_cdrom(target=None,path=send_path)


    # ノードに接続してlibvirtでXMLを登録
    node = virtlib.VirtManager(node_model=node)
    node.domain_define(xml_str=editor.dump_str())

    # 情報の更新
    update_domain_list(db=db, model=TaskModel())

    domain = db.query(DomainModel).filter(DomainModel.uuid==domain_uuid).one()
    domain.owner_user_id = task_model.user_id
    db.commit()

    return task_model