Exemplo n.º 1
0
def r_resume(uuids):

    args_rules = [Rules.UUIDS.value]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids})

        guest = Guest()
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            message = {
                '_object': 'guest',
                'action': 'resume',
                'uuid': uuid,
                'node_id': guest.node_id
            }

            Utils.emit_instruction(message=json.dumps(message))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 2
0
def rsvp():
    error = None
    formfilled = request.cookies.get('rsvpstat')
    if formfilled == '1':
        return redirect(url_for('thankyou'))
    if request.method == 'POST':
        if 'inputName' in request.form:
            if request.form['inputName'] == '':
                error = "Name field cannot be blank."
                return render_template('rsvp.html', error=error)
            else:
                inputName = request.form['inputName']
        if 'inputGuest' in request.form:
            inputGuest = request.form['inputGuest']
        if 'inputEmail' in request.form:
            inputEmail = request.form['inputEmail']
        if 'decision' in request.form:
            if request.form['decision'] == 'attending':
                inputDecision = "Yes"
            else:
                inputDecision = "No"
        if 'inputComment' in request.form:
            inputComment = request.form['inputComment']
        guest = Guest(name=inputName,
                      email=inputEmail,
                      invitename=inputGuest,
                      comments=inputComment,
                      decision=inputDecision)
        db_session.add(guest)
        db_session.commit()
        #flash(message)
        resp = make_response(redirect(url_for('thankyou')))
        resp.set_cookie('rsvpstat', '1')
        return resp
    return render_template('rsvp.html', error=error)
Exemplo n.º 3
0
def r_update(uuid):

    args_rules = [Rules.UUID.value]

    if 'remark' in request.json:
        args_rules.append(Rules.REMARK.value, )

    if args_rules.__len__() < 2:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    request.json['uuid'] = uuid

    try:
        ji.Check.previewing(args_rules, request.json)
        guest = Guest()
        guest.uuid = uuid
        guest.get_by('uuid')

        guest.remark = request.json.get('remark', guest.label)

        guest.update()
        guest.get()

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        ret['data'] = guest.__dict__
        return ret
    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 4
0
def r_get_boot_jobs(uuids):

    args_rules = [Rules.UUIDS.value]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids})

        guest = Guest()

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        if uuids.split(',').__len__() > 1:
            ret['data'] = dict()
            for uuid in uuids.split(','):
                guest.uuid = uuid
                boot_jobs = dict()
                boot_jobs['ttl'], boot_jobs['boot_jobs'] = guest.get_boot_jobs(
                )
                ret['data'][uuid] = boot_jobs

        else:
            guest.uuid = uuids
            ret['data'] = dict()
            ret['data']['ttl'], ret['data']['boot_jobs'] = guest.get_boot_jobs(
            )

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 5
0
def r_migrate(uuids, destination_host):

    args_rules = [
        Rules.UUIDS.value,
        Rules.DESTINATION_HOST.value
    ]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids, 'destination_host': destination_host})

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        # 取全部活着的 hosts
        available_hosts = Host.get_available_hosts(nonrandom=None)

        if available_hosts.__len__() == 0:
            ret['state'] = ji.Common.exchange_state(50351)
            return ret

        available_hosts_mapping_by_node_id = dict()

        for host in available_hosts:
            if host['node_id'] not in available_hosts_mapping_by_node_id:
                available_hosts_mapping_by_node_id[host['node_id']] = host

        guest = Guest()
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        config = Config()
        config.id = 1
        config.get()

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            # 忽略宕机计算节点 上面的 虚拟机 迁移请求
            # 忽略目标计算节点 等于 当前所在 计算节点 的虚拟机 迁移请求
            if guest.node_id not in available_hosts_mapping_by_node_id or \
                    available_hosts_mapping_by_node_id[guest.node_id]['hostname'] == destination_host:
                continue

            message = {
                '_object': 'guest',
                'action': 'migrate',
                'uuid': uuid,
                'node_id': guest.node_id,
                'storage_mode': config.storage_mode,
                'duri': 'qemu+ssh://' + destination_host + '/system'
            }

            Utils.emit_instruction(message=json.dumps(message))

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 6
0
def r_reset_password(uuids, password):

    args_rules = [Rules.UUIDS.value, Rules.PASSWORD.value]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids, 'password': password})

        guest = Guest()
        # 检测所指定的 UUDIs 实例都存在
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        # 重置密码的 boot job id 固定为 1
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')
            guest.password = password
            guest.update()

            guest.add_boot_jobs(boot_jobs_id=['1'])

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 7
0
def r_delete_boot_jobs(uuids, boot_jobs_id):

    args_rules = [Rules.UUIDS.value, Rules.BOOT_JOBS_ID.value]

    try:
        ji.Check.previewing(args_rules, {
            'uuids': uuids,
            'boot_jobs_id': boot_jobs_id
        })

        guest = Guest()
        # 检测所指定的 UUDIs 实例都存在
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.delete_boot_jobs(boot_jobs_id=boot_jobs_id.split(','))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 8
0
def add():
    name = request.form.get('name')
    domain = request.form.get('domain')

    guest = Guest(name, domain, request.remote_addr)
    guest.commit()
    return redirect('/manage/')
Exemplo n.º 9
0
def r_force_reboot(uuids):

    args_rules = [Rules.UUIDS.value]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids})

        guest = Guest()
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')
            disks, _ = Disk.get_by_filter(
                filter_str=':'.join(['guest_uuid', 'eq', guest.uuid]))

            message = {
                '_object': 'guest',
                'action': 'force_reboot',
                'uuid': uuid,
                'node_id': guest.node_id,
                'disks': disks
            }

            Utils.emit_instruction(message=json.dumps(message))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 10
0
def r_get_uuids_of_all_had_boot_job():
    guest = Guest()
    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        ret['data'] = guest.get_uuids_of_all_had_boot_job()
        return ret
    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 11
0
def guests_add(request, event_id):
    event = get_object_or_404(Event, id=event_id)
    guest = Guest(event=event)
    form = GuestAddForm(instance=guest, data=(request.POST or None))
    if form.is_valid():
        form.save()
        return redirect(event)
    template = "events/_guests_add.html" if request.is_ajax() else "events/guests_add.html"
    return render_to_response(template, locals(), context_instance=RequestContext(request))
Exemplo n.º 12
0
def r_detach_disk(disk_uuid):

    args_rules = [Rules.DISK_UUID.value]

    try:
        ji.Check.previewing(args_rules, {'disk_uuid': disk_uuid})

        disk = Disk()
        disk.uuid = disk_uuid
        disk.get_by('uuid')

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        if disk.state != DiskState.mounted.value or disk.sequence == 0:
            # 表示未被任何实例使用,已被分离
            # 序列为 0 的表示实例系统盘,系统盘不可以被分离
            # TODO: 系统盘单独范围其它状态
            return ret

        guest = Guest()
        guest.uuid = disk.guest_uuid
        guest.get_by('uuid')

        # 判断 Guest 是否处于可用状态
        if guest.status in (status.GuestState.no_state.value,
                            status.GuestState.dirty.value):
            ret['state'] = ji.Common.exchange_state(41259)
            return ret

        config = Config()
        config.id = 1
        config.get()

        guest_xml = GuestXML(guest=guest, disk=disk, config=config)

        message = {
            '_object': 'guest',
            'action': 'detach_disk',
            'uuid': disk.guest_uuid,
            'node_id': guest.node_id,
            'xml': guest_xml.get_disk(),
            'passback_parameters': {
                'disk_uuid': disk.uuid
            }
        }

        Utils.emit_instruction(message=json.dumps(message))

        disk.state = DiskState.unloading.value
        disk.update()

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 13
0
def update_ssh_key(uuid):

    guest = Guest()
    guest.uuid = uuid
    guest.get_by('uuid')

    # 不支持更新离线虚拟机的 SSH-KEY
    if guest.status != GuestState.running.value:
        return

    os_template_image = OSTemplateImage()
    os_template_profile = OSTemplateProfile()

    os_template_image.id = guest.os_template_image_id
    os_template_image.get()

    os_template_profile.id = os_template_image.os_template_profile_id
    os_template_profile.get()

    # 不支持更新 Windows 虚拟机的 SSH-KEY
    if os_template_profile.os_type == 'windows':
        return

    rows, _ = SSHKeyGuestMapping.get_by_filter(
        filter_str=':'.join(['guest_uuid', 'eq', uuid]))

    ssh_keys_id = list()
    for row in rows:
        ssh_keys_id.append(row['ssh_key_id'].__str__())

    ssh_keys = list()

    if ssh_keys_id.__len__() > 0:
        rows, _ = SSHKey.get_by_filter(
            filter_str=':'.join(['id', 'in', ','.join(ssh_keys_id)]))
        for row in rows:
            ssh_keys.append(row['public_key'])

    else:
        ssh_keys.append('')

    message = {
        '_object': 'guest',
        'uuid': uuid,
        'node_id': guest.node_id,
        'action': 'update_ssh_key',
        'ssh_keys': ssh_keys,
        'os_type': os_template_profile.os_type,
        'passback_parameters': {
            'uuid': uuid,
            'ssh_keys': ssh_keys,
            'os_type': os_template_profile.os_type
        }
    }

    Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))
Exemplo n.º 14
0
def register_guest():
    from models import Guest
    name = request.form.get('name')
    email = request.form.get('email')

    guest = Guest(name, email)
    db.session.add(guest)
    db.session.commit()

    return render_template('guest_confirmation.html', name=name, email=email)
Exemplo n.º 15
0
def r_reset_password(uuids, password):

    args_rules = [
        Rules.UUIDS.value,
        Rules.PASSWORD.value
    ]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids, 'password': password})

        guest = Guest()
        os_template_image = OSTemplateImage()
        os_template_profile = OSTemplateProfile()

        # 检测所指定的 UUDIs 实例都存在
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            os_template_image.id = guest.os_template_image_id
            os_template_image.get()

            os_template_profile.id = os_template_image.os_template_profile_id
            os_template_profile.get()

            user = '******'

            if os_template_profile.os_type == 'windows':
                user = '******'

            # guest.password 由 guest 事件处理机更新。参见 @models/event_processory.py:189 附近。

            message = {
                '_object': 'guest',
                'action': 'reset_password',
                'uuid': guest.uuid,
                'node_id': guest.node_id,
                'os_type': os_template_profile.os_type,
                'user': user,
                'password': password,
                'passback_parameters': {'password': password}
            }

            Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 16
0
def r_adjust_ability(uuids, cpu, memory):
    args_rules = [
        Rules.UUIDS.value,
        Rules.CPU.value,
        Rules.MEMORY.value,
    ]

    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        cpu = int(cpu)
        memory = int(memory)

        ji.Check.previewing(args_rules, {'uuids': uuids, 'cpu': cpu, 'memory': memory})

        not_ready_yet_of_guests = list()

        guest = Guest()

        # 检测所指定的 UUDIs 实例都存在。且状态都为可以操作状态(即关闭状态)。
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            if guest.status != status.GuestState.shutoff.value:
                not_ready_yet_of_guests.append(guest.__dict__)

        if not_ready_yet_of_guests.__len__() > 0:
            ret['state'] = ji.Common.exchange_state(41261)
            ret['data'] = not_ready_yet_of_guests
            return ret

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')
            guest.cpu = cpu
            guest.memory = memory

            message = {
                '_object': 'guest',
                'action': 'adjust_ability',
                'uuid': guest.uuid,
                'node_id': guest.node_id,
                'cpu': guest.cpu,
                'memory': guest.memory,
                'passback_parameters': {'cpu': guest.cpu, 'memory': guest.memory}
            }

            Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 17
0
def r_delete(snapshots_id):

    args_rules = [
        Rules.SNAPSHOTS_ID.value
    ]

    try:
        ji.Check.previewing(args_rules, {'snapshots_id': snapshots_id})

        snapshot = Snapshot()
        guest = Guest()

        # 检测所指定的 快照 都存在
        for snapshot_id in snapshots_id.split(','):
            snapshot.snapshot_id = snapshot_id
            snapshot.get_by('snapshot_id')

            guest.uuid = snapshot.guest_uuid
            guest.get_by('uuid')

        # 执行删除操作
        for snapshot_id in snapshots_id.split(','):
            snapshot.snapshot_id = snapshot_id
            snapshot.get_by('snapshot_id')

            guest.uuid = snapshot.guest_uuid
            guest.get_by('uuid')

            message = {
                '_object': 'snapshot',
                'action': 'delete',
                'uuid': snapshot.guest_uuid,
                'snapshot_id': snapshot.snapshot_id,
                'node_id': guest.node_id,
                'passback_parameters': {'id': snapshot.id}
            }

            Utils.emit_instruction(message=json.dumps(message))

            # 删除创建失败的 快照
            if snapshot.progress == 255:
                SnapshotDiskMapping.delete_by_filter(filter_str=':'.join(['snapshot_id', 'eq', snapshot.snapshot_id]))
                snapshot.delete()

            else:
                snapshot.progress = 254
                snapshot.update()

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 18
0
def r_delete(uuids):

    args_rules = [
        Rules.UUIDS.value
    ]

    # TODO: 加入是否删除使用的数据磁盘开关,如果为True,则顺便删除使用的磁盘。否则解除该磁盘被使用的状态。
    try:
        ji.Check.previewing(args_rules, {'uuids': uuids})

        guest = Guest()
        # 检测所指定的 UUDIs 实例都存在
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        config = Config()
        config.id = 1
        config.get()

        # 执行删除操作
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            message = {
                '_object': 'guest',
                'action': 'delete',
                'uuid': uuid,
                'storage_mode': config.storage_mode,
                'dfs_volume': config.dfs_volume,
                'node_id': guest.node_id
            }

            Utils.emit_instruction(message=json.dumps(message))

            # 删除创建失败的 Guest
            if guest.status == status.GuestState.dirty.value:
                disk = Disk()
                disk.uuid = guest.uuid
                disk.get_by('uuid')

                if disk.state == status.DiskState.pending.value:
                    disk.delete()
                    guest.delete()
                    SSHKeyGuestMapping.delete_by_filter(filter_str=':'.join(['guest_uuid', 'eq', guest.uuid]))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 19
0
def new_guest():
    form = GuestForm(request.form)
    form.city.choices = [(city.id, city.desc)
                         for city in db.session.query(City).all()]
    if request.method == 'POST' and form.validate():
        guest = form.getObj(Guest())
        guest.user_id = current_user.id
        guest.picture = 'picna.jpg'
        db.session.add(guest)
        db.session.commit()
        flash('Anúncio adicionado'.decode('utf-8'), 'success')
        return redirect(url_for('dashboard'))
    return render_template('guest/edit_guest.html',
                           form=form,
                           action='Adicionar')
Exemplo n.º 20
0
def guest_new():
    guest = Guest()
    if request.method == 'POST':
        form = GuestForm(request.form, obj=guest)
        if form.validate():
            try:
                form.populate_obj(guest)
                validate_guest(guest)
                guest.save()
                flash('Yes, hóspede cadastrado com sucesso.', 'success')
                return redirect(url_for('guests.guest_index'))
            except AttributeError as e:
                flash(str(e), 'warning')
    else:
        form = GuestForm(obj=guest)
    return render_template('guests/new.html', form=form)
Exemplo n.º 21
0
def r_create():

    args_rules = [
        Rules.GUEST_UUID.value
    ]

    if 'label' in request.json:
        args_rules.append(
            Rules.LABEL.value,
        )

    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        ji.Check.previewing(args_rules, request.json)

        snapshot = Snapshot()
        guest = Guest()
        guest.uuid = request.json.get('guest_uuid')
        guest.get_by('uuid')

        snapshot.label = request.json.get('label', '')
        snapshot.status = guest.status
        snapshot.guest_uuid = guest.uuid
        snapshot.snapshot_id = '_'.join(['tmp', ji.Common.generate_random_code(length=8)])
        snapshot.parent_id = '-'
        snapshot.progress = 0

        snapshot.create()
        snapshot.get_by('snapshot_id')

        message = {
            '_object': 'snapshot',
            'action': 'create',
            'uuid': guest.uuid,
            'node_id': guest.node_id,
            'passback_parameters': {'id': snapshot.id}
        }

        Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))

        ret['data'] = snapshot.__dict__
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 22
0
Arquivo: app.py Projeto: Rangot/tceh_2
def create():
    from models import Guest
    from forms import PostForm

    if request.method == 'POST':
        print(request.form)
        form = PostForm(request.form)

        if form.validate():
            post = Guest(**form.data)
            db.session.add(post)
            db.session.commit()

            flash('Post created!')
        else:
            flash('Form is not valid! Post was not created.')
            flash(str(form.errors))

    return index()
Exemplo n.º 23
0
def r_boot(uuids):
    # TODO: 做好关系依赖判断,比如boot不可以对suspend的实例操作。

    args_rules = [
        Rules.UUIDS.value
    ]

    try:
        ji.Check.previewing(args_rules, {'uuids': uuids})

        guest = Guest()
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        config = Config()
        config.id = 1
        config.get()

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            disks, _ = Disk.get_by_filter(filter_str=':'.join(['guest_uuid', 'eq', guest.uuid]))

            message = {
                '_object': 'guest',
                'action': 'boot',
                'uuid': uuid,
                'node_id': guest.node_id,
                'passback_parameters': {},
                'disks': disks
            }

            Utils.emit_instruction(message=json.dumps(message))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 24
0
def r_migrate(uuids, destination_host):

    args_rules = [Rules.UUIDS.value, Rules.DESTINATION_HOST.value]

    try:
        ji.Check.previewing(args_rules, {
            'uuids': uuids,
            'destination_host': destination_host
        })

        guest = Guest()
        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

        config = Config()
        config.id = 1
        config.get()

        for uuid in uuids.split(','):
            guest.uuid = uuid
            guest.get_by('uuid')

            message = {
                '_object': 'guest',
                'action': 'migrate',
                'uuid': uuid,
                'node_id': guest.node_id,
                'storage_mode': config.storage_mode,
                'duri': 'qemu+ssh://' + destination_host + '/system'
            }

            Utils.emit_instruction(message=json.dumps(message))

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 25
0
def r_revert(snapshot_id):

    args_rules = [
        Rules.SNAPSHOT_ID.value
    ]

    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        ji.Check.previewing(args_rules, {'snapshot_id': snapshot_id})

        snapshot = Snapshot()
        guest = Guest()

        snapshot.snapshot_id = snapshot_id
        snapshot.get_by('snapshot_id')
        snapshot.progress = 253
        snapshot.update()
        snapshot.get()

        guest.uuid = snapshot.guest_uuid
        guest.get_by('uuid')

        message = {
            '_object': 'snapshot',
            'action': 'revert',
            'uuid': guest.uuid,
            'snapshot_id': snapshot.snapshot_id,
            'node_id': guest.node_id,
            'passback_parameters': {'id': snapshot.id}
        }

        Utils.emit_instruction(message=json.dumps(message, ensure_ascii=False))

        ret['data'] = snapshot.__dict__
        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 26
0
class EventProcessor(object):
    message = None
    log = Log()
    guest = Guest()
    guest_migrate_info = GuestMigrateInfo()
    disk = Disk()
    config = Config()
    cpu_memory = CPUMemory()
    traffic = Traffic()
    disk_io = DiskIO()
    host_cpu_memory = HostCPUMemory()
    host_traffic = HostTraffic()
    host_disk_usage_io = HostDiskUsageIO()

    @classmethod
    def log_processor(cls):
        cls.log.set(type=cls.message['type'],
                    timestamp=cls.message['timestamp'],
                    host=cls.message['host'],
                    message=cls.message['message'],
                    full_message='' if cls.message['message'].__len__() < 255
                    else cls.message['message'])

        cls.log.create()

    @classmethod
    def guest_event_processor(cls):
        cls.guest.uuid = cls.message['message']['uuid']
        cls.guest.get_by('uuid')
        cls.guest.on_host = cls.message['host']
        last_status = cls.guest.status
        cls.guest.status = cls.message['type']

        if cls.message['type'] == GuestState.update.value:
            # 更新事件不改变 Guest 的状态
            cls.guest.status = last_status
            cls.guest.xml = cls.message['message']['xml']

        elif cls.guest.status == GuestState.migrating.value:
            try:
                cls.guest_migrate_info.uuid = cls.guest.uuid
                cls.guest_migrate_info.get_by('uuid')

                cls.guest_migrate_info.type = cls.message['message'][
                    'migrating_info']['type']
                cls.guest_migrate_info.time_elapsed = cls.message['message'][
                    'migrating_info']['time_elapsed']
                cls.guest_migrate_info.time_remaining = cls.message['message'][
                    'migrating_info']['time_remaining']
                cls.guest_migrate_info.data_total = cls.message['message'][
                    'migrating_info']['data_total']
                cls.guest_migrate_info.data_processed = cls.message['message'][
                    'migrating_info']['data_processed']
                cls.guest_migrate_info.data_remaining = cls.message['message'][
                    'migrating_info']['data_remaining']
                cls.guest_migrate_info.mem_total = cls.message['message'][
                    'migrating_info']['mem_total']
                cls.guest_migrate_info.mem_processed = cls.message['message'][
                    'migrating_info']['mem_processed']
                cls.guest_migrate_info.mem_remaining = cls.message['message'][
                    'migrating_info']['mem_remaining']
                cls.guest_migrate_info.file_total = cls.message['message'][
                    'migrating_info']['file_total']
                cls.guest_migrate_info.file_processed = cls.message['message'][
                    'migrating_info']['file_processed']
                cls.guest_migrate_info.file_remaining = cls.message['message'][
                    'migrating_info']['file_remaining']

                cls.guest_migrate_info.update()

            except ji.PreviewingError as e:
                ret = json.loads(e.message)
                if ret['state']['code'] == '404':
                    cls.guest_migrate_info.type = cls.message['message'][
                        'migrating_info']['type']
                    cls.guest_migrate_info.time_elapsed = cls.message[
                        'message']['migrating_info']['time_elapsed']
                    cls.guest_migrate_info.time_remaining = cls.message[
                        'message']['migrating_info']['time_remaining']
                    cls.guest_migrate_info.data_total = cls.message['message'][
                        'migrating_info']['data_total']
                    cls.guest_migrate_info.data_processed = cls.message[
                        'message']['migrating_info']['data_processed']
                    cls.guest_migrate_info.data_remaining = cls.message[
                        'message']['migrating_info']['data_remaining']
                    cls.guest_migrate_info.mem_total = cls.message['message'][
                        'migrating_info']['mem_total']
                    cls.guest_migrate_info.mem_processed = cls.message[
                        'message']['migrating_info']['mem_processed']
                    cls.guest_migrate_info.mem_remaining = cls.message[
                        'message']['migrating_info']['mem_remaining']
                    cls.guest_migrate_info.file_total = cls.message['message'][
                        'migrating_info']['file_total']
                    cls.guest_migrate_info.file_processed = cls.message[
                        'message']['migrating_info']['file_processed']
                    cls.guest_migrate_info.file_remaining = cls.message[
                        'message']['migrating_info']['file_remaining']

                    cls.guest_migrate_info.create()

        elif cls.guest.status == GuestState.creating.value:
            cls.guest.progress = cls.message['message']['progress']

        cls.guest.update()

        # 限定特殊情况下更新磁盘所属 Guest,避免迁移、创建时频繁被无意义的更新
        if cls.guest.status in [
                GuestState.running.value, GuestState.shutoff.value
        ]:
            cls.disk.update_by_filter({'on_host': cls.guest.on_host},
                                      filter_str='guest_uuid:eq:' +
                                      cls.guest.uuid)

    @classmethod
    def host_event_processor(cls):
        key = cls.message['message']['node_id']
        value = {
            'hostname': cls.message['host'],
            'cpu': cls.message['message']['cpu'],
            'system_load': cls.message['message']['system_load'],
            'memory': cls.message['message']['memory'],
            'memory_available': cls.message['message']['memory_available'],
            'interfaces': cls.message['message']['interfaces'],
            'disks': cls.message['message']['disks'],
            'boot_time': cls.message['message']['boot_time'],
            'timestamp': ji.Common.ts()
        }

        db.r.hset(app.config['hosts_info'],
                  key=key,
                  value=json.dumps(value, ensure_ascii=False))

    @classmethod
    def response_processor(cls):
        _object = cls.message['message']['_object']
        action = cls.message['message']['action']
        uuid = cls.message['message']['uuid']
        state = cls.message['type']
        data = cls.message['message']['data']
        hostname = cls.message['host']

        if _object == 'guest':
            if action == 'create':
                if state == ResponseState.success.value:
                    # 系统盘的 UUID 与其 Guest 的 UUID 相同
                    cls.disk.uuid = uuid
                    cls.disk.get_by('uuid')
                    cls.disk.guest_uuid = uuid
                    cls.disk.state = DiskState.mounted.value
                    # disk_info['virtual-size'] 的单位为Byte,需要除以 1024 的 3 次方,换算成单位为 GB 的值
                    cls.disk.size = data['disk_info']['virtual-size'] / (1024**
                                                                         3)
                    cls.disk.update()

                else:
                    cls.guest.uuid = uuid
                    cls.guest.get_by('uuid')
                    cls.guest.status = GuestState.dirty.value
                    cls.guest.update()

            elif action == 'migrate':
                pass

            elif action == 'delete':
                if state == ResponseState.success.value:
                    cls.config.id = 1
                    cls.config.get()
                    cls.guest.uuid = uuid
                    cls.guest.get_by('uuid')

                    if IP(cls.config.start_ip).int() <= IP(
                            cls.guest.ip).int() <= IP(cls.config.end_ip).int():
                        if db.r.srem(app.config['ip_used_set'], cls.guest.ip):
                            db.r.sadd(app.config['ip_available_set'],
                                      cls.guest.ip)

                    if (cls.guest.vnc_port - cls.config.start_vnc_port) <= \
                            (IP(cls.config.end_ip).int() - IP(cls.config.start_ip).int()):
                        if db.r.srem(app.config['vnc_port_used_set'],
                                     cls.guest.vnc_port):
                            db.r.sadd(app.config['vnc_port_available_set'],
                                      cls.guest.vnc_port)

                    cls.guest.delete()

                    # TODO: 加入是否删除使用的数据磁盘开关,如果为True,则顺便删除使用的磁盘。否则解除该磁盘被使用的状态。
                    cls.disk.uuid = uuid
                    cls.disk.get_by('uuid')
                    cls.disk.delete()
                    cls.disk.update_by_filter(
                        {
                            'guest_uuid': '',
                            'sequence': -1,
                            'state': DiskState.idle.value
                        },
                        filter_str='guest_uuid:eq:' + cls.guest.uuid)

            elif action == 'attach_disk':
                cls.disk.uuid = cls.message['message']['passback_parameters'][
                    'disk_uuid']
                cls.disk.get_by('uuid')
                if state == ResponseState.success.value:
                    cls.disk.guest_uuid = uuid
                    cls.disk.sequence = cls.message['message'][
                        'passback_parameters']['sequence']
                    cls.disk.state = DiskState.mounted.value
                    cls.disk.update()

            elif action == 'detach_disk':
                cls.disk.uuid = cls.message['message']['passback_parameters'][
                    'disk_uuid']
                cls.disk.get_by('uuid')
                if state == ResponseState.success.value:
                    cls.disk.guest_uuid = ''
                    cls.disk.sequence = -1
                    cls.disk.state = DiskState.idle.value
                    cls.disk.update()

            elif action == 'boot':
                boot_jobs_id = cls.message['message']['passback_parameters'][
                    'boot_jobs_id']

                if state == ResponseState.success.value:
                    cls.guest.uuid = uuid
                    cls.guest.delete_boot_jobs(boot_jobs_id=boot_jobs_id)

        elif _object == 'disk':
            if action == 'create':
                cls.disk.uuid = uuid
                cls.disk.get_by('uuid')
                cls.disk.on_host = hostname
                if state == ResponseState.success.value:
                    cls.disk.state = DiskState.idle.value

                else:
                    cls.disk.state = DiskState.dirty.value

                cls.disk.update()

            elif action == 'resize':
                if state == ResponseState.success.value:
                    cls.disk.uuid = uuid
                    cls.disk.get_by('uuid')
                    cls.disk.size = cls.message['message'][
                        'passback_parameters']['size']
                    cls.disk.update()

            elif action == 'delete':
                cls.disk.uuid = uuid
                cls.disk.get_by('uuid')
                cls.disk.delete()

        else:
            pass

    @classmethod
    def collection_performance_processor(cls):
        data_kind = cls.message['type']
        timestamp = ji.Common.ts()
        timestamp -= (timestamp % 60)
        data = cls.message['message']['data']

        if data_kind == CollectionPerformanceDataKind.cpu_memory.value:
            for item in data:
                cls.cpu_memory.guest_uuid = item['guest_uuid']
                cls.cpu_memory.cpu_load = item['cpu_load']
                cls.cpu_memory.memory_available = item['memory_available']
                cls.cpu_memory.memory_unused = item['memory_unused']
                cls.cpu_memory.timestamp = timestamp
                cls.cpu_memory.create()

        if data_kind == CollectionPerformanceDataKind.traffic.value:
            for item in data:
                cls.traffic.guest_uuid = item['guest_uuid']
                cls.traffic.name = item['name']
                cls.traffic.rx_bytes = item['rx_bytes']
                cls.traffic.rx_packets = item['rx_packets']
                cls.traffic.rx_errs = item['rx_errs']
                cls.traffic.rx_drop = item['rx_drop']
                cls.traffic.tx_bytes = item['tx_bytes']
                cls.traffic.tx_packets = item['tx_packets']
                cls.traffic.tx_errs = item['tx_errs']
                cls.traffic.tx_drop = item['tx_drop']
                cls.traffic.timestamp = timestamp
                cls.traffic.create()

        if data_kind == CollectionPerformanceDataKind.disk_io.value:
            for item in data:
                cls.disk_io.disk_uuid = item['disk_uuid']
                cls.disk_io.rd_req = item['rd_req']
                cls.disk_io.rd_bytes = item['rd_bytes']
                cls.disk_io.wr_req = item['wr_req']
                cls.disk_io.wr_bytes = item['wr_bytes']
                cls.disk_io.timestamp = timestamp
                cls.disk_io.create()

        else:
            pass

    @classmethod
    def host_collection_performance_processor(cls):
        data_kind = cls.message['type']
        timestamp = ji.Common.ts()
        timestamp -= (timestamp % 60)
        data = cls.message['message']['data']

        if data_kind == HostCollectionPerformanceDataKind.cpu_memory.value:
            cls.host_cpu_memory.node_id = data['node_id']
            cls.host_cpu_memory.cpu_load = data['cpu_load']
            cls.host_cpu_memory.memory_available = data['memory_available']
            cls.host_cpu_memory.timestamp = timestamp
            cls.host_cpu_memory.create()

        if data_kind == HostCollectionPerformanceDataKind.traffic.value:
            for item in data:
                cls.host_traffic.node_id = item['node_id']
                cls.host_traffic.name = item['name']
                cls.host_traffic.rx_bytes = item['rx_bytes']
                cls.host_traffic.rx_packets = item['rx_packets']
                cls.host_traffic.rx_errs = item['rx_errs']
                cls.host_traffic.rx_drop = item['rx_drop']
                cls.host_traffic.tx_bytes = item['tx_bytes']
                cls.host_traffic.tx_packets = item['tx_packets']
                cls.host_traffic.tx_errs = item['tx_errs']
                cls.host_traffic.tx_drop = item['tx_drop']
                cls.host_traffic.timestamp = timestamp
                cls.host_traffic.create()

        if data_kind == HostCollectionPerformanceDataKind.disk_usage_io.value:
            for item in data:
                cls.host_disk_usage_io.node_id = item['node_id']
                cls.host_disk_usage_io.mountpoint = item['mountpoint']
                cls.host_disk_usage_io.used = item['used']
                cls.host_disk_usage_io.rd_req = item['rd_req']
                cls.host_disk_usage_io.rd_bytes = item['rd_bytes']
                cls.host_disk_usage_io.wr_req = item['wr_req']
                cls.host_disk_usage_io.wr_bytes = item['wr_bytes']
                cls.host_disk_usage_io.timestamp = timestamp
                cls.host_disk_usage_io.create()

        else:
            pass

    @classmethod
    def launch(cls):
        logger.info(msg='Thread EventProcessor is launched.')
        while True:
            if Utils.exit_flag:
                msg = 'Thread EventProcessor say bye-bye'
                print msg
                logger.info(msg=msg)

                return

            try:
                report = db.r.lpop(app.config['upstream_queue'])

                if report is None:
                    time.sleep(1)
                    continue

                cls.message = json.loads(report)

                if cls.message['kind'] == EmitKind.log.value:
                    cls.log_processor()

                elif cls.message['kind'] == EmitKind.guest_event.value:
                    cls.guest_event_processor()

                elif cls.message['kind'] == EmitKind.host_event.value:
                    cls.host_event_processor()

                elif cls.message['kind'] == EmitKind.response.value:
                    cls.response_processor()

                elif cls.message[
                        'kind'] == EmitKind.collection_performance.value:
                    cls.collection_performance_processor()

                elif cls.message[
                        'kind'] == EmitKind.host_collection_performance.value:
                    cls.host_collection_performance_processor()

                else:
                    pass

            except Exception as e:
                logger.error(traceback.format_exc())
Exemplo n.º 27
0
def guests(id=None):
    if request.method == 'GET':
        if id is not None:
            guest = Guest.query.get(id)
            if guest:
                return jsonify(guest.serialize()), 200
            else:
                return jsonify({"msg": "guest not found"}), 404
        else:
            guests = Guest.query.all()
            guests = list(map(lambda guest: guest.serialize(), guests))
            return jsonify(guests), 200

    if request.method == 'POST':

        fullname = request.json.get('fullname', None)
        email = request.json.get('email', None)
        rol = request.json.get('rol', None)
        meeting_id = request.json.get('meeting_id', None)

        if not fullname:
            return jsonify({"msg": "fullname is required"}), 422

        guest = Guest()
        guest.fullname = fullname
        guest.email = email
        guest.rol = rol
        guest.meeting_id = meeting_id

        db.session.add(guest)
        db.session.commit()

        return jsonify(guest.serialize()), 201

    if request.method == 'PUT':

        fullname = request.json.get('fullname', None)
        email = request.json.get('email', None)
        rol = request.json.get('rol', None)
        meeting_id = request.json.get('meeting_id', None)

        if not fullname:
            return jsonify({"msg": "fullname is required"}), 422

        guest = Guest.query.get(id)

        if not guest:
            return jsonify({"msg": "guest not found"}), 404

        guest.fullname = fullname
        guest.email = email
        guest.rol = rol
        guest.meeting_id = meeting_id

        db.session.commit()

        return jsonify(guest.serialize()), 200

    if request.method == 'DELETE':
        guest = Guest.query.get(id)

        if not guest:
            return jsonify({"msg": "guest not found"}), 404

        db.session.delete(guest)
        db.session.commit()

        return jsonify({"msg": "guest deleted"}), 200
Exemplo n.º 28
0
def meetings(id=None):
    if request.method == 'GET':
        if id is not None:
            meeting = Meeting.query.get(id)
            if meeting:
                return jsonify(meeting.serialize()), 200
            else:
                return jsonify({"msg": "meeting not found"}), 404
        else:
            meetings = Meeting.query.all()
            meetings = list(map(lambda meeting: meeting.serialize(), meetings))
            return jsonify(meetings), 200

    if request.method == 'POST':

        #create_date = request.json.get('create_date', None)
        meeting_date = request.json.get('meeting_date', None)
        meeting_hour = request.json.get('meeting_hour', None)
        project_name = request.json.get('project_name', None)
        title = request.json.get('title', None)
        topics = request.json.get('topics', None)
        guests = request.json.get('guests', None)
        place = request.json.get('place', None)
        description = request.json.get('description', None)
        target = request.json.get('target', None)
        done = request.json.get('done', None)
        user_id = request.json.get('user_id', None)

        if not meeting_date:
            return jsonify({"msg": "date is required"}), 422
        if not meeting_hour:
            return jsonify({"msg": "hour is required"}), 422
        if not project_name:
            return jsonify({"msg": "project name is required"}), 422
        if not title:
            return jsonify({"msg": "title is required"}), 422
        if not place:
            return jsonify({"msg": "place is required"}), 422

        meeting = Meeting()
        #meeting.create_date = create_date
        meeting.meeting_date = meeting_date
        meeting.meeting_hour = meeting_hour
        meeting.project_name = project_name
        meeting.title = title
        meeting.place = place
        meeting.description = description
        meeting.target = target
        meeting.done = done
        meeting.user_id = user_id

        db.session.add(meeting)
        db.session.commit()

        if topics:
            if len(topics) > 1:
                for x in range(len(topics)):
                    top = Topic()
                    top.title = topics[x]["title"]
                    top.priority = topics[x]["priority"]
                    top.notes = topics[x]["notes"]
                    top.care = topics[x]["care"]
                    top.tracking = topics[x]["tracking"]
                    top.duration = topics[x]["duration"]
                    top.meeting_id = meeting.id
                    db.session.add(top)
            else:
                top = Topic()
                top.title = topics[0]["title"]
                top.priority = topics[0]["priority"]
                top.notes = topics[0]["notes"]
                top.care = topics[0]["care"]
                top.tracking = topics[0]["tracking"]
                top.duration = topics[0]["duration"]
                top.meeting_id = meeting.id
                db.session.add(top)

            db.session.commit()

        if guests:
            if len(guests) > 1:
                for x in range(len(guests)):
                    gue = Guest()
                    gue.fullname = guests[x]["fullname"]
                    gue.email = guests[x]["email"]
                    gue.rol = guests[x]["rol"]
                    gue.meeting_id = meeting.id
                    db.session.add(gue)
            else:
                gue = Guest()
                gue.fullname = guests[0]["fullname"]
                gue.email = guests[0]["email"]
                gue.rol = guests[0]["rol"]
                gue.meeting_id = meeting.id
                db.session.add(gue)

            db.session.commit()

        return jsonify(meeting.serialize()), 201

    if request.method == 'PUT':

        #create_date = request.json.get('create_date', None)
        meeting_date = request.json.get('meeting_date', None)
        meeting_hour = request.json.get('meeting_hour', None)
        project_name = request.json.get('project_name', None)
        title = request.json.get('title', None)
        topics = request.json.get('topics', None)
        guests = request.json.get('guests', None)
        place = request.json.get('place', None)
        description = request.json.get('description', None)
        target = request.json.get('target', None)
        done = request.json.get('done', None)
        user_id = request.json.get('user_id', None)

        # if not meeting_date:
        #     return jsonify({"msg": "date is required"}), 422
        # if not meeting_hour:
        #     return jsonify({"msg": "hour is required"}), 422
        # if not project_name:
        #     return jsonify({"msg": "project name is required"}), 422
        # if not title:
        #     return jsonify({"msg": "title is required"}), 422
        # if not place:
        #     return jsonify({"msg": "place is required"}), 422

        meeting = Meeting.query.get(id)

        if not meeting:
            return jsonify({"msg": "meeting not found"}), 404

        #meeting.create_date = create_date
        meeting.meeting_date = meeting_date
        meeting.meeting_hour = meeting_hour
        meeting.project_name = project_name
        meeting.title = title
        meeting.place = place
        meeting.description = description
        meeting.target = target
        meeting.done = done
        meeting.user_id = user_id

        db.session.commit()

        if topics:
            if len(topics) > 0:
                for x in range(len(topics)):
                    if topics[x]["id"] == 0:
                        top = Topic()
                        top.title = topics[x]["title"]
                        top.priority = topics[x]["priority"]
                        top.notes = topics[x]["notes"]
                        top.care = topics[x]["care"]
                        top.tracking = topics[x]["tracking"]
                        top.duration = topics[x]["duration"]
                        top.meeting_id = meeting.id
                        db.session.add(top)
                    else:
                        top = Topic.query.get(topics[x]["id"])
                        top.title = topics[x]["title"]
                        top.priority = topics[x]["priority"]
                        top.notes = topics[x]["notes"]
                        top.care = topics[x]["care"]
                        top.tracking = topics[x]["tracking"]
                        top.duration = topics[x]["duration"]
                        top.meeting_id = meeting.id

            db.session.commit()

        if guests:
            if len(guests) > 0:
                for x in range(len(guests)):
                    if guests[x]["id"] == 0:
                        gue = Guest()
                        gue.fullname = guests[x]["fullname"]
                        gue.email = guests[x]["email"]
                        gue.rol = guests[x]["rol"]
                        gue.meeting_id = meeting.id
                        db.session.add(gue)
                    else:
                        gue = Guest.query.get(guests[x]["id"])
                        gue.fullname = guests[x]["fullname"]
                        gue.email = guests[x]["email"]
                        gue.rol = guests[x]["rol"]
                        gue.meeting_id = meeting.id

            db.session.commit()

        return jsonify(meeting.serialize()), 200

    if request.method == 'DELETE':

        Topic.query.filter_by(meeting_id=id).delete()
        Guest.query.filter_by(meeting_id=id).delete()
        meeting = Meeting.query.get(id)

        if not meeting:
            return jsonify({"msg": "meeting not found"}), 404

        db.session.delete(meeting)
        db.session.commit()
        return jsonify({"msg": "meeting deleted"}), 200
Exemplo n.º 29
0
def r_attach_disk(uuid, disk_uuid):

    args_rules = [Rules.UUID.value, Rules.DISK_UUID.value]

    try:
        ji.Check.previewing(args_rules, {'uuid': uuid, 'disk_uuid': disk_uuid})

        guest = Guest()
        guest.uuid = uuid
        guest.get_by('uuid')

        disk = Disk()
        disk.uuid = disk_uuid
        disk.get_by('uuid')

        config = Config()
        config.id = 1
        config.get()

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        # 判断欲挂载的磁盘是否空闲
        if disk.guest_uuid.__len__() > 0 or disk.state != DiskState.idle.value:
            ret['state'] = ji.Common.exchange_state(41258)
            return ret

        # 判断 Guest 是否处于可用状态
        if guest.status in (status.GuestState.no_state.value,
                            status.GuestState.dirty.value):
            ret['state'] = ji.Common.exchange_state(41259)
            return ret

        # 判断 Guest 与 磁盘是否在同一宿主机上
        if config.storage_mode in [
                status.StorageMode.local.value,
                status.StorageMode.shared_mount.value
        ]:
            if guest.node_id != disk.node_id:
                ret['state'] = ji.Common.exchange_state(41260)
                return ret

        # 通过检测未被使用的序列,来确定当前磁盘在目标 Guest 身上的序列
        disk.guest_uuid = guest.uuid
        disks, count = disk.get_by_filter(filter_str='guest_uuid:in:' +
                                          guest.uuid)

        already_used_sequence = list()

        for _disk in disks:
            already_used_sequence.append(_disk['sequence'])

        for sequence in range(0, dev_table.__len__()):
            if sequence not in already_used_sequence:
                disk.sequence = sequence
                break

        disk.state = DiskState.mounting.value

        guest_xml = GuestXML(guest=guest, disk=disk, config=config)

        message = {
            '_object': 'guest',
            'action': 'attach_disk',
            'uuid': uuid,
            'node_id': guest.node_id,
            'xml': guest_xml.get_disk(),
            'passback_parameters': {
                'disk_uuid': disk.uuid,
                'sequence': disk.sequence
            },
            'disks': [disk.__dict__]
        }

        Utils.emit_instruction(message=json.dumps(message))
        disk.update()

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 30
0
def r_create():

    args_rules = [
        Rules.CPU.value, Rules.MEMORY.value, Rules.OS_TEMPLATE_ID.value,
        Rules.QUANTITY.value, Rules.REMARK.value, Rules.PASSWORD.value,
        Rules.LEASE_TERM.value
    ]

    if 'node_id' in request.json:
        args_rules.append(Rules.NODE_ID.value, )

    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        ji.Check.previewing(args_rules, request.json)

        config = Config()
        config.id = 1
        config.get()

        os_template = OSTemplate()
        os_template.id = request.json.get('os_template_id')
        if not os_template.exist():
            ret['state'] = ji.Common.exchange_state(40450)
            ret['state']['sub']['zh-cn'] = ''.join(
                [ret['state']['sub']['zh-cn'], ': ',
                 os_template.id.__str__()])
            return ret

        os_template.get()
        # 重置密码的 boot job id 固定为 1
        boot_jobs_id = [1, os_template.boot_job_id]

        boot_jobs, boot_jobs_count = OperateRule.get_by_filter(
            filter_str='boot_job_id:in:' + ','.join(
                ['{0}'.format(boot_job_id)
                 for boot_job_id in boot_jobs_id]).__str__())

        if db.r.scard(app.config['ip_available_set']) < 1:
            ret['state'] = ji.Common.exchange_state(50350)
            return ret

        node_id = request.json.get('node_id', None)

        # 默认只取可随机分配虚拟机的 hosts
        available_hosts = Host.get_available_hosts(nonrandom=False)

        # 当指定了 host 时,取全部活着的 hosts
        if node_id is not None:
            available_hosts = Host.get_available_hosts(nonrandom=None)

        if available_hosts.__len__() == 0:
            ret['state'] = ji.Common.exchange_state(50351)
            return ret

        if node_id is not None and node_id not in [
                host['node_id'] for host in available_hosts
        ]:
            ret['state'] = ji.Common.exchange_state(50351)
            return ret

        quantity = request.json.get('quantity')

        while quantity:
            quantity -= 1
            guest = Guest()
            guest.uuid = uuid4().__str__()
            guest.cpu = request.json.get('cpu')
            # 虚拟机内存单位,模板生成方法中已置其为GiB
            guest.memory = request.json.get('memory')
            guest.os_template_id = request.json.get('os_template_id')
            guest.label = ji.Common.generate_random_code(length=8)
            guest.remark = request.json.get('remark', '')

            guest.password = request.json.get('password')
            if guest.password is None or guest.password.__len__() < 1:
                guest.password = ji.Common.generate_random_code(length=16)

            guest.ip = db.r.spop(app.config['ip_available_set'])
            db.r.sadd(app.config['ip_used_set'], guest.ip)

            guest.network = config.vm_network
            guest.manage_network = config.vm_manage_network

            guest.vnc_port = db.r.spop(app.config['vnc_port_available_set'])
            db.r.sadd(app.config['vnc_port_used_set'], guest.vnc_port)

            guest.vnc_password = ji.Common.generate_random_code(length=16)

            disk = Disk()
            disk.uuid = guest.uuid
            disk.remark = guest.label.__str__() + '_SystemImage'
            disk.format = 'qcow2'
            disk.sequence = 0
            disk.size = 0
            disk.path = config.storage_path + '/' + disk.uuid + '.' + disk.format
            disk.guest_uuid = ''
            # disk.node_id 由 guest 事件处理机更新。涉及迁移时,其所属 node_id 会变更。参见 models/event_processory.py:111 附近。
            disk.node_id = 0
            disk.quota(config=config)
            disk.create()

            guest_xml = GuestXML(guest=guest,
                                 disk=disk,
                                 config=config,
                                 os_type=os_template.os_type)
            guest.xml = guest_xml.get_domain()

            # 在可用计算节点中平均分配任务
            chosen_host = available_hosts[quantity % available_hosts.__len__()]
            guest.node_id = chosen_host['node_id']

            if node_id is not None:
                guest.node_id = node_id

            guest.node_id = int(guest.node_id)
            guest.create()

            # 替换占位符为有效内容
            _boot_jobs = copy.deepcopy(boot_jobs)
            for k, v in enumerate(_boot_jobs):
                _boot_jobs[k]['content'] = v['content'].replace('{IP}', guest.ip).\
                    replace('{HOSTNAME}', guest.label). \
                    replace('{PASSWORD}', guest.password). \
                    replace('{NETMASK}', config.netmask).\
                    replace('{GATEWAY}', config.gateway).\
                    replace('{DNS1}', config.dns1).\
                    replace('{DNS2}', config.dns2)

                _boot_jobs[k]['command'] = v['command'].replace('{IP}', guest.ip). \
                    replace('{HOSTNAME}', guest.label). \
                    replace('{PASSWORD}', guest.password). \
                    replace('{NETMASK}', config.netmask). \
                    replace('{GATEWAY}', config.gateway). \
                    replace('{DNS1}', config.dns1). \
                    replace('{DNS2}', config.dns2)

            message = {
                '_object': 'guest',
                'action': 'create',
                'uuid': guest.uuid,
                'storage_mode': config.storage_mode,
                'dfs_volume': config.dfs_volume,
                'node_id': guest.node_id,
                'name': guest.label,
                'template_path': os_template.path,
                'os_type': os_template.os_type,
                'disk': disk.__dict__,
                # disk 将被废弃,由 disks 代替,暂时保留它的目的,是为了保持与 JimV-N 的兼容性
                'disks': [disk.__dict__],
                'xml': guest_xml.get_domain(),
                'boot_jobs': _boot_jobs,
                'passback_parameters': {
                    'boot_jobs_id': boot_jobs_id
                }
            }

            Utils.emit_instruction(
                message=json.dumps(message, ensure_ascii=False))

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)