예제 #1
0
    def _POST(self, *param, **params):
        (host_id, guest_id) = self.chk_guestby1(param)
        if guest_id is None: return web.notfound()

        model = findbyguest1(self.orm, guest_id)

        # virt
        kvc = KaresansuiVirtConnection()
        try:
            domname = kvc.uuid_to_domname(model.uniq_key)
            if not domname: return web.conflict(web.ctx.path)
            virt = kvc.search_kvg_guests(domname)[0]
            nic_info = virt.get_interface_info()

            # -- Nic
            if self.input.device_type == "nic":
                if not validates_nic(self):
                    return web.badrequest(self.view.alert)

                f_chk = True
                for x in nic_info:
                    if x['mac']['address'] == self.input.mac_address:
                        f_chk = False
                        break
                if f_chk is False:
                    return web.badrequest(
                        _('Specified MAC address is already defined.'))

                mac = self.input.mac_address
                bridge = None
                network = None
                if self.input.nic_type == "phydev":
                    bridge = self.input.phydev
                elif self.input.nic_type == "virnet":
                    network = self.input.virnet

                self.logger.debug('spinning off create_nic_job dom=%s, mac=%s, bridge=%s, network=%s' \
                                  % (domname, mac, bridge, network))

                create_nic_job(self, model, domname, mac, bridge, network)
                return web.accepted()

            # -- Disk
            elif self.input.device_type == "disk":
                if not validates_disk(self):
                    return web.badrequest(self.view.alert)

                volume_job = None
                order = 0
                if self.input.pool_type == "dir" or self.input.pool_type == "fs":  # create(dir)
                    disk_type = 'file'
                    pool_name = self.input.pool_dir
                    volume_name = string_from_uuid(generate_uuid())
                    volume_job = create_storage_volume_dir(
                        self, model, domname, volume_name, self.input.pool_dir,
                        self.input.disk_format, self.input.disk_size,
                        self.input.disk_size, 'M', order)
                    order += 1

                elif self.input.pool_type == "block":  # create(iscsi block)
                    disk_type = 'iscsi'
                    (iscsi_pool,
                     iscsi_volume) = self.input.pool_dir.split("/", 2)
                    pool_name = iscsi_pool
                    volume_name = iscsi_volume

                else:
                    return badrequest(_("No storage type specified."))

                # add disk
                disk_job = create_disk_job(self,
                                           guest=model,
                                           domain_name=domname,
                                           pool=pool_name,
                                           volume=volume_name,
                                           bus=self.input.bus_type,
                                           format=self.input.disk_format,
                                           type=disk_type,
                                           order=order)
                order += 1

                if exec_disk_job(obj=self,
                                 guest=model,
                                 disk_job=disk_job,
                                 volume_job=volume_job,
                                 order=order) is True:
                    return web.accepted()
                else:
                    return False

            else:  # Not Found
                return False
        finally:
            kvc.close()
예제 #2
0
    def _POST(self, *param, **params):
        (host_id, guest_id) = self.chk_guestby1(param)
        if guest_id is None: return web.notfound()

        model = findbyguest1(self.orm, guest_id)

        # virt
        kvc = KaresansuiVirtConnection()
        try:
            domname = kvc.uuid_to_domname(model.uniq_key)
            if not domname: return web.conflict(web.ctx.path)
            virt = kvc.search_kvg_guests(domname)[0]
            nic_info = virt.get_interface_info()

            # -- Nic
            if self.input.device_type == "nic":
                if not validates_nic(self):
                    return web.badrequest(self.view.alert)

                f_chk = True
                for x in nic_info:
                    if x['mac']['address'] == self.input.mac_address:
                        f_chk = False
                        break
                if f_chk is False:
                    return web.badrequest(_('Specified MAC address is already defined.'))

                mac = self.input.mac_address
                bridge = None
                network = None
                if self.input.nic_type == "phydev":
                    bridge = self.input.phydev
                elif self.input.nic_type == "virnet":
                    network = self.input.virnet

                self.logger.debug('spinning off create_nic_job dom=%s, mac=%s, bridge=%s, network=%s' \
                                  % (domname, mac, bridge, network))

                create_nic_job(self,model,domname,mac,bridge,network)
                return web.accepted()

            # -- Disk
            elif self.input.device_type == "disk":
                if not validates_disk(self):
                    return web.badrequest(self.view.alert)

                volume_job = None
                order = 0
                if self.input.pool_type == "dir" or self.input.pool_type == "fs": # create(dir)
                    disk_type = 'file'
                    pool_name = self.input.pool_dir
                    volume_name = string_from_uuid(generate_uuid())
                    volume_job = create_storage_volume_dir(self,
                                                           model,
                                                           domname,
                                                           volume_name,
                                                           self.input.pool_dir,
                                                           self.input.disk_format,
                                                           self.input.disk_size,
                                                           self.input.disk_size,
                                                           'M',
                                                           order)
                    order += 1

                elif self.input.pool_type == "block": # create(iscsi block)
                    disk_type = 'iscsi'
                    (iscsi_pool, iscsi_volume) = self.input.pool_dir.split("/", 2)
                    pool_name = iscsi_pool
                    volume_name = iscsi_volume

                else:
                    return badrequest(_("No storage type specified."))

                # add disk
                disk_job = create_disk_job(self,
                                           guest=model,
                                           domain_name=domname,
                                           pool=pool_name,
                                           volume=volume_name,
                                           bus=self.input.bus_type,
                                           format=self.input.disk_format,
                                           type=disk_type,
                                           order=order)
                order += 1

                if exec_disk_job(obj=self,
                                 guest=model,
                                 disk_job=disk_job,
                                 volume_job=volume_job,
                                 order=order
                                 ) is True:
                    return web.accepted()
                else:
                    return False

            else: # Not Found
                return False
        finally:
            kvc.close()
예제 #3
0
    def _POST(self, *param, **params):
        host_id = self.chk_hostby1(param)
        if host_id is None: return web.notfound()

        if not validates_guest_replicate(self):
            self.logger.debug(self.view.alert)
            return web.badrequest(self.view.alert)

        uuid = string_from_uuid(generate_uuid())

        # TODO dest_pool valid
        if not validates_src_id(self):
            self.logger.debug(self.view.alert)
            return web.badrequest(self.view.alert)

        src_guest = findbyguest1(self.orm, self.input.src_id)
        if not src_guest:
            self.view.alert = "Failed to get the data of source domain."
            self.logger.debug(self.view.alert)
            return web.badrequest(self.view.alert)

        # Note
        note_title = None
        if is_param(self.input, "note_title"):
            note_title = self.input.note_title

        note_value = None
        if is_param(self.input, "note_value"):
            note_value = self.input.note_value

        _notebook = n_new(note_title, note_value)

        # Tag
        _tags = None
        if is_param(self.input, "tags"):
            _tags = []
            for x in comma_split(self.input.tags):
                _tags.append(t_new(x))

        # Icon
        icon_filename = None
        if is_param(self.input, "icon_filename", empty=True):
            icon_filename = self.input.icon_filename

        dest_guest = m_new(created_user=self.me,
                           modified_user=self.me,
                           uniq_key=uni_force(uuid),
                           name=self.input.m_name,
                           attribute=MACHINE_ATTRIBUTE['GUEST'],
                           hypervisor=src_guest.hypervisor,
                           notebook=_notebook,
                           tags=_tags,
                           icon=icon_filename,
                           is_deleted=False,
                           parent=src_guest.parent,
                           )


        kvc = KaresansuiVirtConnection()
        try:
            domname = kvc.uuid_to_domname(src_guest.uniq_key)
            if not domname: return web.conflict(web.ctx.path)
            virt = kvc.search_kvg_guests(domname)[0]
            options = {}
            options["src-name"] = virt.get_domain_name()
            if is_param(self.input, "dest_pool"):
                options["pool"] = self.input.dest_pool
            if is_param(self.input, "domain_dest_name"):
                options["dest-name"] = self.input.domain_dest_name
            if is_param(self.input, "vm_vncport"):
                options["vnc-port"] = self.input.vm_vncport
            if is_param(self.input, "vm_mac"):
                options["mac"] = self.input.vm_mac

            options["uuid"] = uuid

            src_pools = kvc.get_storage_pool_name_bydomain(domname)
            if not src_pools:
                self.view.alert = _("Source storage pool is not found.")
                self.logger.debug(self.view.alert)
                return web.badrequest(self.view.alert)

            for src_pool in  src_pools :
                src_pool_type = kvc.get_storage_pool_type(src_pool)
                if src_pool_type != 'dir':
                    self.view.alert = _("'%s' disk contains the image.") % src_pool_type
                    self.logger.debug(self.view.alert)
                    return web.badrequest(self.view.alert)

            # disk check
            target_pool = kvc.get_storage_pool_name_bydomain(domname, 'os')[0]
            target_path = kvc.get_storage_pool_targetpath(target_pool)
            src_disk = "%s/%s/images/%s.img" % \
                                      (target_path, options["src-name"], options["src-name"])

            s_size = os.path.getsize(src_disk) / (1024 * 1024) # a unit 'MB'

            if os.access(target_path, os.F_OK):
                if chk_create_disk(target_path, s_size) is False:
                    partition = get_partition_info(target_path, header=False)
                    self.view.alert = _("No space available to create disk image in '%s' partition.") % partition[5][0]
                    self.logger.debug(self.view.alert)
                    return web.badrequest(self.view.alert)

            #else: # Permission denied
                #TODO:check disk space for root

            active_guests = kvc.list_active_guest()
            inactive_guests = kvc.list_inactive_guest()
            used_vnc_ports = kvc.list_used_vnc_port()
            used_mac_addrs = kvc.list_used_mac_addr()

            conflict_location = "%s/host/%d/guest/%d.json" \
                                % (web.ctx.homepath, src_guest.parent_id, src_guest.id)
            # source guestos
            if not (options["src-name"] in active_guests or options["src-name"] in inactive_guests):
                return web.conflict(conflict_location, "Unable to get the source guest.")

            # Check on whether value has already been used
            # destination guestos
            if (options["dest-name"] in active_guests or options["dest-name"] in inactive_guests):
                return web.conflict(conflict_location, "Destination guest %s is already there." % options["dest-name"])
            # VNC port number
            if(int(self.input.vm_vncport) in used_vnc_ports):
                return web.conflict(conflict_location, "VNC port %s is already used." % self.input.vm_vncport)
            # MAC address
            if(self.input.vm_mac in used_mac_addrs):
                return web.conflict(conflict_location, "MAC address %s is already used." % self.input.vm_mac)

            # Replicate Guest
            order = 0 # job order
            disk_jobs = [] # Add Disk
            volume_jobs = [] # Create Storage Volume
            for disk in virt.get_disk_info():
                if disk['type'] != 'file':
                    self.view.alert = _("The type of the storage pool where the disk is to be added must be 'file'. dev=%s") % disk['target']['dev']
                    self.logger.debug(self.view.alert)
                    return web.badrequest(self.view.alert)

                disk_pool = kvc.get_storage_pool_name_byimage(disk['source']['file'])
                if not disk_pool:
                    self.view.alert = _("Can not find the storage pool.")
                    self.logger.debug(self.view.alert)
                    return web.badrequest(self.view.alert)
                else:
                    disk_pool = disk_pool[0]

                disk_volumes = kvc.get_storage_volume_bydomain(domname, 'disk', 'key')
                volume = None
                for key in disk_volumes.keys():
                    if disk['source']['file'] == os.path.realpath(disk_volumes[key]):
                        volume = key # disk image

                if volume is None: # os image
                    continue

                disk_uuid = string_from_uuid(generate_uuid())

                volume_jobs.append(replicate_storage_volume(self,
                                                     domname,
                                                     disk_pool,
                                                     volume,
                                                     self.input.domain_dest_name,
                                                     #self.input.dest_pool,
                                                     disk_pool, # orig
                                                     disk_uuid,
                                                     order))
                order += 1

                disk_jobs.append(create_disk_job(self,
                                                 dest_guest,
                                                 self.input.domain_dest_name,
                                                 disk_pool,
                                                 disk_uuid,
                                                 bus=disk['target']['bus'],
                                                 format=disk['driver']['type'],
                                                 type=disk['type'],
                                                 target=disk['target']['dev'],
                                                 order=-1))

        finally:
            kvc.close()


        # replicate guest
        guest_job = replicate_guest(self,
                                    dest_guest,
                                    VIRT_COMMAND_REPLICATE_GUEST,
                                    options,
                                    'Replicate Guest',
                                    {"name" : options['dest-name'],
                                     "pool" : options["pool"],
                                     },
                                    order,
                                    )
        order += 1
        for disk_job in disk_jobs:
            disk_job.order = order
            order += 1

        ret = exec_replicate_guest(self,
                                   dest_guest,
                                   icon_filename,
                                   'Replicate Guest',
                                   guest_job,
                                   disk_jobs,
                                   volume_jobs,
                                   )

        if ret is True:
            return web.accepted()
        else:
            return False