class Guest(Rest): def _post(self, f): ret = Rest._post(self, f) if hasattr(self, "kvc") is True: self.kvc.close() return ret @auth def _GET(self, *param, **params): host_id = self.chk_hostby1(param) if host_id is None: return web.notfound() model = findbyhost1(self.orm, host_id) uris = available_virt_uris() self.kvc = KaresansuiVirtConnection() try: # libvirt connection scope --> # Storage Pool #inactive_pool = self.kvc.list_inactive_storage_pool() inactive_pool = [] active_pool = self.kvc.list_active_storage_pool() pools = inactive_pool + active_pool pools.sort() if not pools: return web.badrequest('One can not start a storage pool.') # Output .input if self.is_mode_input() is True: self.view.pools = pools pools_info = {} pools_vols_info = {} pools_iscsi_blocks = {} already_vols = [] guests = [] guests += self.kvc.list_inactive_guest() guests += self.kvc.list_active_guest() for guest in guests: already_vol = self.kvc.get_storage_volume_bydomain(domain=guest, image_type=None, attr='path') if already_vol: already_vols += already_vol.keys() for pool in pools: pool_obj = self.kvc.search_kvn_storage_pools(pool)[0] if pool_obj.is_active() is True: pools_info[pool] = pool_obj.get_info() blocks = None if pools_info[pool]['type'] == 'iscsi': blocks = self.kvc.get_storage_volume_iscsi_block_bypool(pool) if blocks: pools_iscsi_blocks[pool] = [] vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc) vols_info = {} for vol_obj in vols_obj: vol_name = vol_obj.get_storage_volume_name() vols_info[vol_name] = vol_obj.get_info() if blocks: if vol_name in blocks and vol_name not in already_vols: pools_iscsi_blocks[pool].append(vol_obj.get_info()) pools_vols_info[pool] = vols_info self.view.pools_info = pools_info self.view.pools_vols_info = pools_vols_info self.view.pools_iscsi_blocks = pools_iscsi_blocks bridge_prefix = { "XEN":"xenbr", "KVM":KVM_BRIDGE_PREFIX, } self.view.host_id = host_id self.view.DEFAULT_KEYMAP = DEFAULT_KEYMAP self.view.DISK_NON_QEMU_FORMAT = DISK_NON_QEMU_FORMAT self.view.DISK_QEMU_FORMAT = DISK_QEMU_FORMAT self.view.hypervisors = {} self.view.mac_address = {} self.view.keymaps = {} self.view.phydev = {} self.view.virnet = {} used_ports = {} for k,v in MACHINE_HYPERVISOR.iteritems(): if k in available_virt_mechs(): self.view.hypervisors[k] = v uri = uris[k] mem_info = self.kvc.get_mem_info() active_networks = self.kvc.list_active_network() used_vnc_ports = self.kvc.list_used_vnc_port() bus_types = self.kvc.bus_types self.view.bus_types = bus_types self.view.max_mem = mem_info['host_max_mem'] self.view.free_mem = mem_info['host_free_mem'] self.view.alloc_mem = mem_info['guest_alloc_mem'] self.view.mac_address[k] = generate_mac_address(k) self.view.keymaps[k] = eval("get_keymaps(%s_KEYMAP_DIR)" % k) # Physical device phydev = [] phydev_regex = re.compile(r"%s" % bridge_prefix[k]) for dev,dev_info in get_ifconfig_info().iteritems(): try: if phydev_regex.match(dev): phydev.append(dev) except: pass if len(phydev) == 0: phydev.append("%s0" % bridge_prefix[k]) phydev.sort() self.view.phydev[k] = phydev # Physical device # Virtual device self.view.virnet[k] = sorted(active_networks) used_ports[k] = used_vnc_ports exclude_ports = [] for k, _used_port in used_ports.iteritems(): exclude_ports = exclude_ports + _used_port exclude_ports = sorted(exclude_ports) exclude_ports = [p for p, q in zip(exclude_ports, exclude_ports[1:] + [None]) if p != q] self.view.vnc_port = next_number(VNC_PORT_MIN_NUMBER, PORT_MAX_NUMBER, exclude_ports) else: # .part models = findbyhost1guestall(self.orm, host_id) guests = [] if models: # Physical Guest Info self.view.hypervisors = {} for model in models: for k,v in MACHINE_HYPERVISOR.iteritems(): if k in available_virt_mechs(): self.view.hypervisors[k] = v uri = uris[k] if hasattr(self, "kvc") is not True: self.kvc = KaresansuiVirtConnection(uri) domname = self.kvc.uuid_to_domname(model.uniq_key) #if not domname: return web.conflict(web.ctx.path) _virt = self.kvc.search_kvg_guests(domname) if 0 < len(_virt): guests.append(MergeGuest(model, _virt[0])) else: guests.append(MergeGuest(model, None)) # Exported Guest Info exports = {} for pool_name in pools: files = [] pool = self.kvc.search_kvn_storage_pools(pool_name) path = pool[0].get_info()["target"]["path"] if os.path.exists(path): for _afile in glob.glob("%s/*/info.dat" % (path,)): param = ExportConfigParam() param.load_xml_config(_afile) _dir = os.path.dirname(_afile) uuid = param.get_uuid() name = param.get_domain() created = param.get_created() title = param.get_title() if title != "": title = re.sub("[\r\n]","",title) if title == "": title = _('untitled') if created != "": created_str = time.strftime("%Y/%m/%d %H:%M:%S", \ time.localtime(float(created))) else: created_str = _("N/A") files.append({"dir": _dir, "pool" : pool_name, #"b64dir" : base64_encode(_dir), "uuid" : uuid, "name" : name, "created" : int(created), "created_str" : created_str, "title" : title, "icon" : param.get_database()["icon"], }) exports[pool_name] = files # .json if self.is_json() is True: guests_json = [] for x in guests: guests_json.append(x.get_json(self.me.languages)) self.view.guests = json_dumps(guests_json) else: self.view.exports = exports self.view.guests = guests return True finally: #self.kvc.close() pass # libvirt connection scope --> Guest#_post() @auth def _POST(self, *param, **params): host_id = self.chk_hostby1(param) if host_id is None: return web.notfound() model = findbyhost1(self.orm, host_id) uris = available_virt_uris() if model.attribute == 0 and model.hypervisor == 1: uri = uris["XEN"] elif model.attribute == 0 and model.hypervisor == 2: uri = uris["KVM"] else: uri = None if not validates_guest_add(self): return web.badrequest(self.view.alert) try: try: self.kvc = KaresansuiVirtConnection(uri) active_guests = self.kvc.list_active_guest() inactive_guests = self.kvc.list_inactive_guest() used_vnc_ports = self.kvc.list_used_vnc_port() used_mac_addrs = self.kvc.list_used_mac_addr() mem_info = self.kvc.get_mem_info() if is_param(self.input, "vm_mem_size"): if mem_info['host_free_mem'] < int(self.input.vm_mem_size): return web.badrequest(_("Space not enough to allocate guest memory.")) if is_param(self.input, "pool_type") and \ self.input.pool_type != "block" and \ is_param(self.input, "pool_dir"): target_path = self.kvc.get_storage_pool_targetpath(self.input.pool_dir) if target_path: # disk if not chk_create_disk(target_path, self.input.vm_disk_size): partition = get_partition_info(target_path, header=False) return web.badrequest(_("No space available to create disk image in '%s' partition.") % partition[5][0]) except: raise finally: del self.kvc # Check on whether value has already been used # Guest OS if (self.input.domain_name in active_guests) \ or (self.input.domain_name in inactive_guests): return web.conflict(web.ctx.path, "Guest OS is already there.") # VNC port number if(int(self.input.vm_vncport) in used_vnc_ports): return web.conflict(web.ctx.path, "VNC Port is already there.") # MAC addr if(self.input.vm_mac in used_mac_addrs): return web.conflict(web.ctx.path, "MAC Address is already there.") uuid = string_from_uuid(generate_uuid()) options = {} options['uuid'] = uuid if is_param(self.input, "domain_name"): options['name'] = self.input.domain_name if is_param(self.input, "vm_mem_size"): options['mem-size'] = self.input.vm_mem_size if is_param(self.input, "vm_kernel"): options['kernel'] = self.input.vm_kernel if is_param(self.input, "vm_initrd"): options['initrd'] = self.input.vm_initrd if is_param(self.input, "vm_iso"): options['iso'] = self.input.vm_iso if is_param(self.input, "keymap"): options['keymap'] = self.input.keymap is_create = False if is_param(self.input, "pool_type"): if is_param(self.input, "bus_type"): options['bus'] = self.input.bus_type if self.input.pool_type == "dir" or self.input.pool_type == "fs": # create volume is_create = True options['disk-format'] = self.input.disk_format options["storage-pool"] = self.input.pool_dir options["storage-volume"] = options['name'] # default domain name options['disk-size'] = self.input.vm_disk_size elif self.input.pool_type == "block": # iscsi block device (iscsi_pool, iscsi_volume) = self.input.pool_dir.split("/", 2) options["storage-pool"] = iscsi_pool options["storage-volume"] = iscsi_volume else: return web.badrequest() else: return web.badrequest() 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 if is_param(self.input, "vm_extra"): options['extra'] = self.input.vm_extra if is_param(self.input, "nic_type"): if self.input.nic_type == "phydev": options['interface-format'] = "b:" + self.input.phydev elif self.input.nic_type == "virnet": options['interface-format'] = "n:" + self.input.virnet if int(self.input.m_hypervisor) == MACHINE_HYPERVISOR['XEN']: i_hypervisor = MACHINE_HYPERVISOR['XEN'] options['type'] = u"XEN" elif int(self.input.m_hypervisor) == MACHINE_HYPERVISOR['KVM']: i_hypervisor = MACHINE_HYPERVISOR['KVM'] options['type'] = u"KVM" else: return web.badrequest("This is not the hypervisor.") host = findbyhost1(self.orm, host_id) # notebook 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) # tags _tags = None if is_param(self.input, "tags"): _tags = [] tag_array = comma_split(self.input.tags) tag_array = uniq_sort(tag_array) for x in tag_array: if t_count(self.orm, x) == 0: _tags.append(t_new(x)) else: _tags.append(t_name(self.orm, x)) # Icon icon_filename = None if is_param(self.input, "icon_filename", empty=True): icon_filename = self.input.icon_filename _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=i_hypervisor, notebook=_notebook, tags=_tags, icon=icon_filename, is_deleted=False, parent=host, ) ret = regist_guest(self, _guest, icon_filename, VIRT_COMMAND_CREATE_GUEST, options, ('Create Guest', 'Create Guest'), {"name": options['name'], "pool" : options["storage-pool"], "volume" : options["uuid"], }, is_create, ) if ret is True: return web.accepted() else: return False
def _GET(self, *param, **params): host_id = self.chk_hostby1(param) if host_id is None: return web.notfound() if not validates_src_id(self): self.view.alert = "Failed to get the id of source domain." self.logger.debug(self.view.alert) return web.badrequest(self.view.alert) src_id = self.input.src_id if self.is_mode_input() is False: return web.nomethod() self.view.src_id = src_id self.view.mac_address = generate_mac_address() src_guest = findbyguest1(self.orm, 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) kvc = KaresansuiVirtConnection() try: # Storage Pool #inactive_pool = self.kvc.list_inactive_storage_pool() inactive_pool = [] active_pool = kvc.list_active_storage_pool() pools = inactive_pool + active_pool pools.sort() domname = kvc.uuid_to_domname(src_guest.uniq_key) # TODO 対応するストレージボリュームにiscsiがあった場合はエラーにする 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) non_iscsi_pool = [] for pool in pools: if kvc.get_storage_pool_type(pool) != 'iscsi': non_iscsi_pool.append(pool) self.view.pools = non_iscsi_pool virt = kvc.search_kvg_guests(domname)[0] if virt.is_active() is True: self.view.alert = _("Guest is running. Please stop and try again. name=%s" % domname) self.logger.debug(self.view.alert) return web.badrequest(self.view.alert) self.view.domain_src_name = virt.get_domain_name() used_ports = kvc.list_used_vnc_port() self.view.vnc_port = next_number(VNC_PORT_MIN_NUMBER,PORT_MAX_NUMBER,used_ports) finally: kvc.close() return True
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
def _PUT(self, *param, **params): """<comment-ja> Japanese Comment </comment-ja> <comment-en> TODO: English Comment </comment-en> """ (host_id, guest_id) = self.chk_guestby1(param) if guest_id is None: return web.notfound() if not validates_display(self): return web.badrequest(self.view.alert) 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] info = virt.get_graphics_info()["setting"] used_ports = kvc.list_used_vnc_port() origin_port = info["port"] finally: kvc.close() options = {} options["name"] = domname if self.input.change_passwd == "random": options["random-passwd"] = None elif self.input.change_passwd == "empty": options["passwd"] = "" options["port"] = self.input.port options["listen"] = self.input.listen options["keymap"] = self.input.keymap if int(self.input.port) != origin_port and int(self.input.port) in used_ports: return web.badrequest("VNC port number has been already used by other service. - port=%s" % (self.input.port,)) _cmd = dict2command("%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_SET_VNC), options) cmdname = 'Set vnc' _jobgroup = JobGroup(cmdname, karesansui.sheconf['env.uniqkey']) _jobgroup.jobs.append(Job('%s command' % cmdname, 0, _cmd)) _machine2jobgroup = m2j_new(machine=model, jobgroup_id=-1, uniq_key=karesansui.sheconf['env.uniqkey'], created_user=self.me, modified_user=self.me, ) save_job_collaboration(self.orm, self.pysilhouette.orm, _machine2jobgroup, _jobgroup, ) return web.created(None)