2 # -*- coding: utf-8 -*-
4 # This file is part of Karesansui Core.
6 # Copyright (C) 2009-2010 HDE, Inc.
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
23 @author: Taizo ITO <taizo@karesansui-project.info>
41 from libvirt import VIR_DOMAIN_NOSTATE,VIR_DOMAIN_RUNNING,\
42 VIR_DOMAIN_BLOCKED,VIR_DOMAIN_PAUSED,VIR_DOMAIN_SHUTDOWN,\
43 VIR_DOMAIN_SHUTOFF,VIR_DOMAIN_CRASHED,\
44 VIR_STORAGE_POOL_DELETE_NORMAL,\
45 VIR_STORAGE_POOL_DELETE_ZEROED, \
46 VIR_STORAGE_VOL_DELETE_NORMAL, \
47 VIR_STORAGE_VOL_DELETE_ZEROED
49 if __name__ == '__main__':
50 for y in [os.path.abspath(os.path.dirname(os.path.abspath(__file__))+"/../../.."),"/opt/hde/lib/python"]:
51 if (y in sys.path) is False: sys.path.insert(0, y)
54 import karesansui.lib.locale
56 from karesansui.lib.const import VIRT_LIBVIRT_DATA_DIR, VIRT_DOMAINS_DIR, \
57 VIRT_XML_CONFIG_DIR, VIRT_NETWORK_CONFIG_DIR, VIRT_SNAPSHOT_DIR, \
58 VIRT_XENDOMAINS_AUTO_DIR, VIRT_AUTOSTART_CONFIG_DIR, \
59 KARESANSUI_GROUP, VNC_PORT_MIN_NUMBER, PORT_MAX_NUMBER, \
60 DEFAULT_KEYMAP, VIRT_STORAGE_CONFIG_DIR, \
61 DEFAULT_KVM_DISK_FORMAT, DEFAULT_XEN_DISK_FORMAT, \
62 DISK_USES, GUEST_EXPORT_FILE, KVM_BUS_TYPES, XEN_BUS_TYPES, \
63 VENDOR_DATA_ISCSI_DOMAINS_DIR, ISCSI_DEVICE_DIR
65 from karesansui.lib.const import XEN_VIRT_CONFIG_DIR, \
66 XEN_VIRTUAL_DISK_PREFIX, \
67 XEN_VIRT_URI_RW, XEN_VIRT_URI_RO, \
68 XEN_KARESANSUI_TMP_DIR, \
71 from karesansui.lib.const import KVM_VIRT_CONFIG_DIR, \
72 KVM_VIRTUAL_DISK_PREFIX, \
73 KVM_VIRT_URI_RW, KVM_VIRT_URI_RO, \
74 KVM_KARESANSUI_TMP_DIR, \
77 from karesansui.lib.virt.config import ConfigParam, \
78 XMLConfigGenerator, sync_config_generator, KaresansuiConfigParamException
80 from karesansui.lib.virt.config_network import NetworkConfigParam
81 from karesansui.lib.virt.config_network import NetworkXMLConfigGenerator
83 from karesansui.lib.virt.config_storage import StorageVolumeConfigParam, \
84 StorageVolumeXMLConfigGenerator, StoragePoolConfigParam, \
85 StoragePoolXMLConfigGenerator
87 from karesansui.lib.virt.config_export import ExportConfigParam, ExportXMLGenerator
89 from karesansui.lib.virt.config_capabilities import CapabilitiesConfigParam
91 from karesansui.lib.utils import uniq_sort as UniqSort
92 from karesansui.lib.utils import generate_mac_address as GenMAC
93 from karesansui.lib.utils import execute_command as ExecCmd
94 from karesansui.lib.utils import string_from_uuid as StrFromUUID
95 from karesansui.lib.utils import generate_uuid as GenUUID
96 from karesansui.lib.utils import next_number as NextNumber
97 from karesansui.lib.utils import create_disk_img as MakeDiskImage
98 from karesansui.lib.utils import copy_file as CopyFile
99 from karesansui.lib.net.http import wget as DownloadFile
100 from karesansui.lib.utils import is_uuid, get_ifconfig_info, r_chgrp, r_chmod, \
101 getfilesize_str, get_filesize_MB, get_disk_img_info, available_virt_uris, \
102 is_iso9660_filesystem_format, is_windows_bootable_iso, is_darwin_bootable_iso, \
103 file_contents_replace
105 from karesansui.lib.utils import get_inspect_stack
107 from karesansui.lib.file.configfile import ConfigFile
110 os.environ['LIBVIRT_XM_CONFIG_DIR'] = XEN_VIRT_CONFIG_DIR
112 class KaresansuiVirtException(karesansui.KaresansuiLibException):
115 class KaresansuiVirtConnection:
117 def __init__(self,uri=None,readonly=True):
119 self.logger.debug(get_inspect_stack())
121 self.open(uri,readonly)
123 raise KaresansuiVirtException(_("Cannot open '%s'") % uri)
135 if not os.path.exists(VIRT_DOMAINS_DIR):
136 os.makedirs(VIRT_DOMAINS_DIR)
137 if not os.path.exists(VIRT_XML_CONFIG_DIR):
138 os.makedirs(VIRT_XML_CONFIG_DIR)
139 self.logger = logging.getLogger('karesansui.virt')
141 r_chgrp(VIRT_LIBVIRT_DATA_DIR,KARESANSUI_GROUP)
142 r_chmod(VIRT_DOMAINS_DIR,"o-rwx")
145 if not os.path.exists(self.config_dir):
146 os.makedirs(self.config_dir)
147 self.logger = logging.getLogger('karesansui.virt')
149 r_chgrp(self.config_dir,KARESANSUI_GROUP)
151 def open(self, uri,readonly=True):
154 libvirtのコネクションをOpenします。またそれに伴う初期化も行います。
160 uris = available_virt_uris()
167 raise 'error: you must specify connect uri'
169 if uri.lower()[0:3] == "xen":
170 self.disk_prefix = XEN_VIRTUAL_DISK_PREFIX
171 self.config_dir = XEN_VIRT_CONFIG_DIR
172 self.bus_types = XEN_BUS_TYPES
174 if not os.access("/proc/xen", os.R_OK):
175 raise 'System is not running a Xen kernel'
177 if uri.lower()[0:4] == "qemu":
178 self.disk_prefix = KVM_VIRTUAL_DISK_PREFIX
179 self.config_dir = KVM_VIRT_CONFIG_DIR
180 self.bus_types = KVM_BUS_TYPES
183 raise 'System is not running a kvm module'
188 self.logger.debug('uid=%d' % os.getuid())
189 self.logger.debug('gid=%d' % os.getgid())
194 self.logger.info('libvirt.openReadOnly - %s' % self.uri)
195 self._conn = libvirt.openReadOnly(self.uri)
197 self.logger.info('libvirt.open - %s' % self.uri)
198 self._conn = libvirt.open(self.uri)
200 self.logger.debug('libvirt.open - %s' % self.uri)
201 self._conn = libvirt.open(self.uri)
203 self.logger.error('failed to libvirt open - %s' % self.uri)
205 self.logger.debug('succeed to libvirt open - %s' % self.uri)
206 self.logger.debug('hypervisor_type - %s' % self.get_hypervisor_type())
208 self.guest = KaresansuiVirtGuest(self)
209 self.network = KaresansuiVirtNetwork(self)
210 self.storage_volume = KaresansuiVirtStorageVolume(self)
211 self.storage_pool = KaresansuiVirtStoragePool(self)
214 def close(self, conn=None):
217 libvirtなどの仮想化コネクションをCloseします。
222 self.logger.debug(get_inspect_stack())
230 self.logger.debug('succeed to libvirt close - %s' % self.uri)
232 def get_hypervisor_type(self):
234 使用中のハイパーバイザーの種類を取得する。
236 @return: hypervisor type
237 Xen or QEMU is available now (depend on libvirt API)
238 e.g. Xen QEMU Test LXC phyp OpenVZ VBox UML ONE ESX
240 @rtype: string (see examples in previous field '@return')
245 return self._conn.getType()
247 def get_capabilities(self):
249 param = CapabilitiesConfigParam()
251 param.load_xml_config(self._conn.getCapabilities())
260 def get_version(self):
263 libvirtのバージョン情報を取得します。
268 hypervisior = self.get_hypervisior_type()
269 ret = libvirtmod.virGetVersion(hypervisior)
273 libVersion_major = libVersion / 1000000
274 libVersion %= 1000000
275 libVersion_minor = libVersion / 1000
276 libVersion_rel = libVersion % 1000
277 #print "Using library: libvir %d.%d.%d" %(libVersion_major, libVersion_minor, libVersion_rel)
279 apiVersion_major = apiVersion / 1000000
280 apiVersion %= 1000000
281 apiVersion_minor = apiVersion / 1000
282 apiVersion_rel = apiVersion % 1000
283 #print "Using API: %s %d.%d.%d" %(hypervisior, apiVersion_major, apiVersion_minor, apiVersion_rel)
285 return { "libVersion" : "%d.%d.%d" %(libVersion_major, libVersion_minor, libVersion_rel),
286 "apiVersion" : "%s %d.%d.%d" %(hypervisior, apiVersion_major, apiVersion_minor, apiVersion_rel)
289 def get_nodeinfo(self):
291 data = self._conn.getInfo()
304 def get_mem_info(self):
307 - guest_alloc_mem: ゲストOSに割り当てているメモリサイズ,
308 - host_max_mem: ホストOSのメモリサイズ,
309 - host_free_mem: ホストOSの未割り当てメモリサイズ
316 active_guests = self.list_active_guest()
317 inactive_guests = self.list_inactive_guest()
318 info = self.get_nodeinfo()
319 host_max_mem = info['memory']
323 for domname in active_guests + inactive_guests:
324 if not domname == "Domain-0":
325 virt = self.search_kvg_guests(domname)[0]
326 info = virt.get_info()
327 guest_alloc_mem += int(info["maxMem"])
329 guest_alloc_mem /= 1000 # a unit 'MB'
331 host_free_mem = host_max_mem - guest_alloc_mem
332 if host_free_mem < 0: host_free_mem = 0
335 'guest_alloc_mem' : guest_alloc_mem,
336 'host_max_mem' : host_max_mem,
337 'host_free_mem' : host_free_mem,
341 def is_max_vcpus(self, type=None):
343 ゲストに割り当て可能な仮想CPU数の最大値を取得できるか。
345 @param type: ハイパーバイザー
346 @return: the maximum number of virtual CPUs supported for a
347 guest VM of a specific type.
351 Get the maximum number of vcpu supported for guest.
353 @param type: type of hypervisor
354 @return: the maximum number of vcpus
359 type = self.get_hypervisor_type()
361 max = self._conn.getMaxVcpus(type.lower())
363 except libvirt.libvirtError:
366 def get_max_vcpus(self, type=None):
368 ゲストに割り当て可能な仮想CPU数の最大値を取得する
370 @param type: ハイパーバイザー
371 @return: the maximum number of virtual CPUs supported for a
372 guest VM of a specific type.
376 Get the maximum number of vcpu supported for guest.
378 @param type: type of hypervisor
379 @return: the maximum number of vcpus
384 type = self.get_hypervisor_type()
386 max = self._conn.getMaxVcpus(type.lower())
387 except libvirt.libvirtError:
391 def get_physical_cpus(self):
399 Get the number of phisical CPUs.
401 @return: the number of physical CPUs
405 info = self.get_nodeinfo()
406 return info['nodes'] * info['sockets'] * info['cores'] * info['threads']
411 def set_domain_name(self,name=None):
412 self.guest.set_domain_name(name)
413 def get_domain_name(self):
414 return self.guest.get_domain_name()
416 def uuid_to_domname(self, uuid):
419 ゲストOSのUUIDからドメイン名を取得します。
425 #guest = self._conn.lookupByUUIDString(uuid)
427 for guests in self.search_guests():
428 if uuid == guests.UUIDString():
433 def domname_to_uuid(self, domname):
436 ドメイン名からゲストOSのUUIDを取得します。
442 return self.search_guests(domname)[0].UUIDString()
447 def list_inactive_guest(self):
450 現在起動していないゲストOSを取得します。
455 return self._conn.listDefinedDomains()
457 def list_active_guest(self):
466 for id in self._conn.listDomainsID():
467 dom = self._conn.lookupByID(id);
468 names.append(dom.name())
471 def search_guests(self, name=None):
482 name = self.uuid_to_domname(name)
484 ids = self._conn.listDomainsID()
486 if self._conn.lookupByID(id).name() == "Domain-0" and self.get_hypervisor_type() == 'Xen':
488 guests.append(self._conn.lookupByID(id))
489 names = self.list_inactive_guest()
491 guests.append(self._conn.lookupByName(_name))
497 if guest.name() == name:
501 raise KaresansuiVirtException("guest %s not found" % name)
503 def search_kvg_guests(self, name=None):
505 指定されたゲストOSオブジェクトをKaresansuiVirtGuestオブジェクトのlistにして返却する。
508 TODO: English Comment
513 name = self.uuid_to_domname(name)
516 for guest in self.search_guests(name):
518 KaresansuiVirtGuest(conn=self, name=guest.name()))
522 def list_used_vnc_port(self):
525 すでにシステムで利用しているVNCポート番号を取得します。
532 for guest in self.search_guests(None):
534 param = ConfigParam(guest.name())
535 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, guest.name())
536 if not os.path.exists(xml_file):
537 dom = self._conn.lookupByName(guest.name())
538 ConfigFile(xml_file).write(dom.XMLDesc(0))
539 if os.getuid() == 0 and os.path.exists(xml_file):
540 r_chgrp(xml_file,KARESANSUI_GROUP)
541 param.load_xml_config(xml_file)
543 vnc_port = param.vnc_port
544 if vnc_port and int(vnc_port) > 0:
545 ports.append(int(vnc_port))
547 return UniqSort(ports)
549 def list_used_mac_addr(self):
552 すでにシステムで利用しているMAC Addressを取得します。
559 for guest in self.search_guests(None):
561 param = ConfigParam(guest.name())
562 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, guest.name())
563 if not os.path.exists(xml_file):
564 dom = self._conn.lookupByName(guest.name())
565 ConfigFile(xml_file).write(dom.XMLDesc(0))
566 if os.getuid() == 0 and os.path.exists(xml_file):
567 r_chgrp(xml_file,KARESANSUI_GROUP)
568 param.load_xml_config(xml_file)
570 for info in param.interfaces:
571 mac_addr = info['mac']
572 addrs.append(mac_addr.lower())
576 def set_interface_format(self, format=None):
589 self.interface_format = []
590 for _format in format.split(','):
591 (type, name) = _format.split(':')
594 netinfo = self.search_kvn_networks(name)[0].get_info()
595 self.interface_format.append( {"type": "bridge", "name":netinfo['bridge']['name']} )
599 self.interface_format.append( {"type": "bridge", "name":name} )
601 def make_domain_dir(self, dir, name):
604 'dir'(Storage Pool)で構成されたゲスト用ディレクトリ構成を作成します。
611 domain_dir = "%s/%s" % (dir, name,)
612 domain_images_dir = "%s/images" % (domain_dir,)
613 domain_boot_dir = "%s/boot" % (domain_dir,)
614 domain_disk_dir = "%s/disk" % (domain_dir,)
616 #domain_snapshot_dir = "%s/snapshot" % (domain_dir,)
618 if not os.path.exists(domain_dir):
619 os.makedirs(domain_dir)
620 if not os.path.exists(domain_images_dir):
621 os.makedirs(domain_images_dir)
622 if not os.path.exists(domain_boot_dir):
623 os.makedirs(domain_boot_dir)
624 if not os.path.exists(domain_disk_dir):
625 os.makedirs(domain_disk_dir)
626 #if not os.path.exists(domain_snapshot_dir):
627 # os.makedirs(domain_snapshot_dir)
629 r_chgrp(domain_dir,KARESANSUI_GROUP)
630 r_chmod(domain_dir,"o-rwx")
634 def create_guest(self, name=None, type="xen", ram=256, disk=None, disksize=1024*16,
635 mac=None, uuid=None, kernel=None, initrd=None, iso=None, vnc=None,
636 vcpus=None, extra=None, keymap=DEFAULT_KEYMAP,
637 bus=None, disk_format=None,
638 storage_pool=None, storage_volume=None):
647 param = ConfigParam(name)
650 if type == "kvm" and iso is not None:
651 param.add_disk(iso, "hdc", "cdrom") # install iso image
657 pool_objs = self.search_kvn_storage_pools(storage_pool)
659 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
662 pool_type = pool_objs[0].get_info()['type']
664 if pool_type == 'iscsi':
665 domains_dir = VENDOR_DATA_ISCSI_DOMAINS_DIR
666 domain_dir = self.make_domain_dir(VENDOR_DATA_ISCSI_DOMAINS_DIR, name)
668 domains_dir = pool_objs[0].get_info()["target"]["path"]
669 domain_dir = self.make_domain_dir(domains_dir, name)
672 if pool_type == "iscsi":
674 disk = self.get_storage_volume_path(storage_pool, storage_volume)
677 #disk = "%s/images/%s.img" % (domain_dir, storage_volume)
678 disk = "%s/images/%s.img" % (domain_dir, name)
681 raise KaresansuiVirtException("%s pool=%s,volume=%s" % \
682 (_("Storage path could not be retrieved."),
690 file_format = get_disk_img_info(disk)['file_format']
691 if file_format == "qcow2":
692 driver_type = "qcow2"
696 driver_type = file_format
701 target_dev_prefix = "vd"
703 target_dev_prefix = "sd"
705 target_dev_prefix = self.disk_prefix
708 target_dev_prefix + "a",
711 driver_name=driver_name,
712 driver_type=driver_type)
718 uuid = StrFromUUID(GenUUID())
724 used_ports = self.list_used_vnc_port()
725 vnc = NextNumber(VNC_PORT_MIN_NUMBER,PORT_MAX_NUMBER,used_ports)
727 # if os.path.exists(disk):
730 param.set_domain_type(type)
733 acpi_info_file = "/proc/acpi/info"
734 if os.path.exists(acpi_info_file):
735 param.set_features_acpi(True)
737 param.set_boot_dev("cdrom")
738 if is_windows_bootable_iso(iso) is not False:
739 param.set_features_apic(True)
740 elif is_darwin_bootable_iso(iso) is not False:
741 param.set_features_apic(True)
743 param.set_kernel(kernel)
744 param.set_initrd(initrd)
746 param.set_kernel(kernel)
747 param.set_initrd(initrd)
749 param.set_max_vcpus(vcpus)
750 param.set_memory(str(ram) + 'm')
751 param.set_vnc_keymap(keymap)
755 for _format in self.interface_format:
756 if _format['name'][0:5] == 'xenbr':
757 script = "vif-bridge"
763 param.add_interface(mac,"bridge",_format['name'],script)
765 param.add_interface(mac.lower(),"bridge",_format['name'],script)
768 param.set_vnc_port(vnc)
770 param.append_commandline(extra)
771 param.set_behavior("on_shutoff","destroy")
772 param.set_behavior("on_reboot","destroy")
773 param.set_behavior("on_crash","destroy")
775 r = re.compile(r"""(?:ftp|http)s?://""")
777 domain_boot_dir = "%s/boot" % (domain_dir,)
778 if kernel is not None:
779 (kfd, kfn) = tempfile.mkstemp(prefix="vmlinuz.", dir=domain_boot_dir)
780 m = r.match(param.get_kernel())
783 DownloadFile(param.get_kernel(),kfn)
785 kernel = open(param.get_kernel(),"r")
786 os.write(kfd, kernel.read())
789 param.set_kernel(kfn)
791 if initrd is not None:
792 (ifd, ifn) = tempfile.mkstemp(prefix="initrd.img.", dir=domain_boot_dir)
793 m = r.match(param.get_initrd())
796 DownloadFile(param.get_initrd(),ifn)
798 initrd = open(param.get_initrd(),"r")
799 os.write(ifd, initrd.read())
802 param.set_initrd(ifn)
804 sync_config_generator(param)
806 if self._conn is None:
807 self._conn = self.open(None)
809 generator = XMLConfigGenerator()
811 cfgxml = generator.generate(param)
815 dom = self._conn.createLinux(cfgxml, 0)
817 self._conn.defineXML(cfgxml)
820 self._conn.lookupByID(dom.ID())
821 except libvirt.libvirtError:
822 raise "create_guest() error. name:%s" % (name)
824 if initrd is not None:
825 os.unlink(param.get_initrd())
827 if kernel is not None:
828 os.unlink(param.get_kernel())
830 param.set_kernel(None)
831 param.set_initrd(None)
834 param.set_bootloader("/usr/bin/pygrub")
836 param.set_boot_dev("hd")
838 if type == "kvm" and iso is not None:
839 param.delete_disk("hdc")
840 param.set_behavior("on_reboot","restart")
841 param.set_behavior("on_crash","restart")
843 sync_config_generator(param)
845 config = "%s/%s.xml" %(VIRT_XML_CONFIG_DIR,name,)
846 if os.path.exists(config):
847 f = open(config, "r")
850 self._conn.defineXML(cfgxml)
853 self.search_storage_pools(storage_pool)[0].refresh(True)
857 def start_guest(self,name=None):
866 if not (name is None):
867 self.guest.set_domain_name(name)
869 name = self.guest.get_domain_name()
870 config = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR,name,)
871 if os.path.exists(config):
872 f = open(config, "r")
875 self._conn.defineXML(cfgxml)
879 def shutdown_guest(self,name=None):
888 if not (name is None):
889 self.guest.set_domain_name(name)
890 self.guest.shutdown()
892 def reboot_guest(self,name=None):
901 if not (name is None):
902 self.guest.set_domain_name(name)
905 def destroy_guest(self,name=None):
908 ゲストOSを削除します。(設定ファイルやゲストOS定義は削除されません。)
914 if not (name is None):
915 self.guest.set_domain_name(name)
918 def delete_guest(self, name, pool, volume):
927 name = self.guest.get_domain_name()
928 tmp_pool = self.get_storage_pool_name_bydomain(name, 'os')
930 pool_objs = self.search_kvn_storage_pools(tmp_pool[0])
932 pool_objs = self.search_kvn_storage_pools(pool)
934 pool_type = pool_objs[0].get_info()['type']
935 if pool_type == 'iscsi':
936 domains_dir = VENDOR_DATA_ISCSI_DOMAINS_DIR
937 domain_dir = "%s/%s" % (VENDOR_DATA_ISCSI_DOMAINS_DIR, name)
939 domains_dir = self.get_storage_pool_targetpath(pool)
940 domain_dir = "%s/%s" % (domains_dir, name)
942 vols = self.get_storage_volume_bydomain(name, 'os')
944 vol_path = "%s/%s" % (domains_dir, vols.keys()[0])
946 vol_path = "%s/%s" % (domains_dir, volume)
948 self.destroy_guest(name)
950 self.guest.undefine()
955 if os.path.islink(vol_path):
958 if os.path.exists(domain_dir):
959 #os.removedirs(domain_dir)
960 shutil.rmtree(domain_dir)
962 # delete qemu snapshot
963 domain_snapshot_dir = "%s/%s" % (VIRT_SNAPSHOT_DIR,name,)
964 if os.path.exists(domain_snapshot_dir):
965 #os.removedirs(domain_snapshot_dir)
966 shutil.rmtree(domain_snapshot_dir)
970 self.search_storage_pools(tmp_pool[0])[0].refresh(True)
975 self.search_storage_pools(pool)[0].refresh(True)
979 def suspend_guest(self,name=None):
988 if not (name is None):
989 self.guest.set_domain_name(name)
992 def resume_guest(self,name=None):
995 suspendしているゲストOSを復帰させます。
1001 if not (name is None):
1002 self.guest.set_domain_name(name)
1005 def autostart_guest(self,flag=None,name=None):
1014 if not (name is None):
1015 self.guest.set_domain_name(name)
1016 guests = self.search_guests(self.guest.get_domain_name())
1018 return self.guest.autostart(flag)
1022 def replicate_storage_volume(self, orig_domname, orig_pool, orig_volume,
1023 dest_domname, dest_pool, dest_volume,
1027 @param orig_domname: コピー元ドメイン名
1028 @param orig_pool: コピー元ストレージプール名
1029 @param orig_volume: コピー元ストレージボリューム名
1030 @param dest_domname: コピー先ドメイン名
1031 @param dest_pool: コピー先ストレージプール名
1032 @param dest_volume: コピー先ストレージボリューム名
1033 @param progresscb: コピー方式
1037 TODO: English Documents(en)
1040 orig_symlink_path = self.get_storage_volume_iscsi_rpath_bystorage(orig_pool, orig_volume)
1041 orig_rpath = os.path.realpath(orig_symlink_path)
1046 orig_domains_dir = self.get_storage_pool_targetpath(orig_pool)
1047 orig_domain_dir = "%s/%s" % (orig_domains_dir, orig_domname)
1050 dest_domains_dir = self.get_storage_pool_targetpath(dest_pool)
1051 dest_domain_dir = self.make_domain_dir(dest_domains_dir, dest_domname)
1053 orig_files = [orig_rpath,]
1054 dest_files = ["%s/disk/%s.img" % (dest_domain_dir, dest_volume),]
1055 if os.path.isfile(dest_files[0]) is True:
1056 raise KaresansuiVirtException("Already exists in the destination storage volume.")
1058 if progresscb is not None:
1059 from karesansui.lib.utils import copy_file_cb
1060 copy_file_cb(orig_files, dest_files, progresscb, each=False)
1062 CopyFile(orig_files, dest_files)
1065 os.symlink(dest_files[0], "%s/%s" % (dest_domains_dir, dest_volume))
1067 # Storage Pool refresh
1069 self.search_storage_pools(orig_pool)[0].refresh(True)
1070 self.search_storage_pools(dest_pool)[0].refresh(True)
1076 def replicate_guest(self, name, source_name, pool, mac=None, uuid=None, vnc=None):
1079 すべてのディスクがfile形式のみ実行可能です。
1085 param = ConfigParam(name)
1087 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, source_name)
1088 if not os.path.exists(xml_file):
1089 dom = self._conn.lookupByName(source_name)
1090 ConfigFile(xml_file).write(dom.XMLDesc(0))
1091 if os.getuid() == 0 and os.path.exists(xml_file):
1092 r_chgrp(xml_file,KARESANSUI_GROUP)
1093 param.load_xml_config(xml_file)
1097 guest_obj = self.search_kvg_guests(source_name)[0]
1099 raise KaresansuiVirtException(_("Domain could not be found. name=%s") % source_name)
1100 autostart = guest_obj.autostart()
1104 # Source storage pool dir
1105 src_pool = self.get_storage_pool_name_bydomain(source_name, "os")[0]
1106 src_target_path = self.get_storage_pool_targetpath(src_pool)
1107 source_disk = "%s/%s/images/%s.img" \
1108 % (src_target_path, source_name,source_name)
1110 pool_dir = self.get_storage_pool_targetpath(pool)
1111 disk = "%s/%s/images/%s.img" % (pool_dir, name, name)
1113 src_interfaces = param.interfaces
1114 param.interfaces = []
1115 for ifs in src_interfaces:
1116 script = ifs['script']
1119 param.add_interface(mac,"bridge",ifs['bridge'],script)
1121 param.add_interface(mac.lower(),"bridge",ifs['bridge'],script)
1125 uuid = StrFromUUID(GenUUID())
1128 used_ports = self.list_used_vnc_port()
1129 vnc = NextNumber(VNC_PORT_MIN_NUMBER,PORT_MAX_NUMBER,used_ports)
1131 old_disks = param.disks
1133 # get further informations of disk used by os.
1137 for disk_info in old_disks:
1138 if disk_info['path'] == source_disk:
1140 bus = disk_info['bus']
1144 driver_name = disk_info['driver_name']
1148 driver_type = disk_info['driver_type']
1154 param.set_uuid(uuid)
1155 param.set_vnc_port(vnc)
1156 param.add_disk(disk,
1157 self.disk_prefix + "a",
1159 driver_name=driver_name,
1160 driver_type=driver_type)
1163 self.make_domain_dir(pool_dir, name)
1168 for _disk in old_disks:
1170 s_disk_path = _disk['path']
1171 s_disk_target = _disk['target']
1172 s_disk_bus = _disk['bus']
1174 s_driver_name = _disk['driver_name']
1176 s_driver_name = None
1178 s_driver_type = _disk['driver_type']
1180 s_driver_type = None
1182 m = re.search("/domains/%s/disk/(?P<disk_name>[0-9\.]+\.img)$" % source_name ,s_disk_path)
1184 new_disk_path = "%s/%s/disk/%s" % (pool_dir,name,m.group("disk_name"),)
1186 param.add_disk(new_disk_path,
1190 driver_name=s_driver_name,
1191 driver_type=s_driver_type)
1193 if not os.path.exists(new_disk_path):
1194 CopyFile(s_disk_path,new_disk_path)
1199 # libvirtdの再起動後に認識される。(qemuDomainSnapshotLoad)
1200 s_domain_snapshot_dir = "%s/%s" % (VIRT_SNAPSHOT_DIR,source_name,)
1201 if os.path.exists(s_domain_snapshot_dir):
1202 domain_snapshot_dir = "%s/%s" % (VIRT_SNAPSHOT_DIR,name,)
1203 for snapshot_xml in glob.glob("%s/*.xml" % s_domain_snapshot_dir):
1204 snapshot_xml_name = os.path.basename(snapshot_xml)
1205 new_snapshot_xml = "%s/%s" % (domain_snapshot_dir,snapshot_xml_name,)
1206 if not os.path.exists(domain_snapshot_dir):
1207 os.makedirs(domain_snapshot_dir)
1209 old_pattern = "<uuid>.{36}</uuid>"
1210 new_string = "<uuid>%s</uuid>" % uuid
1211 file_contents_replace(snapshot_xml,new_snapshot_xml,old_pattern,new_string)
1212 if os.getuid() == 0:
1213 if os.path.exists(domain_snapshot_dir):
1214 r_chmod(domain_snapshot_dir,"o-rwx")
1215 r_chgrp(domain_snapshot_dir,KARESANSUI_GROUP)
1217 # This is commented out.
1218 # cos guests that set to autostart flag will be started without intention.
1219 #from karesansui.lib.virt.snapshot import KaresansuiVirtSnapshot
1220 #kvs = KaresansuiVirtSnapshot()
1221 #kvs.refreshSnapshot()
1225 CopyFile(source_disk,disk)
1227 # Storage pool directory, OS image set symlink
1229 "%s/%s" % (pool_dir, uuid))
1231 xml_generator = XMLConfigGenerator()
1232 cfgxml = xml_generator.generate(param)
1233 self._conn.defineXML(cfgxml)
1237 sync_config_generator(param, name)
1239 # set autostart flag
1240 if autostart is True:
1242 guest_obj = self.search_kvg_guests(name)[0]
1244 raise KaresansuiVirtException(_("Domain could not be found. name=%s") % name)
1245 guest_obj.autostart(flag=autostart)
1247 raise KaresansuiVirtException(_("Failed to set autostart flag. - dom=%s flag=%s") % (name,autostart))
1249 # Storage Pool refresh
1250 for p in [src_pool, pool]:
1252 self.search_storage_pools(p)[0].refresh(True)
1258 def export_guest(self, uuid, name, directory, database, realicon, title="", snapshots=None, progresscb=None):
1266 #inactive_pools = self.list_inactive_storage_pool()
1268 active_pools = self.list_active_storage_pool()
1271 for _pool in inactive_pools + active_pools:
1272 path = self.search_kvn_storage_pools(_pool)[0].get_info()["target"]["path"]
1273 if directory == path:
1276 if not os.path.exists(directory):
1277 raise KaresansuiVirtException(_("Directory '%s' not found.") % directory)
1279 if not (name is None):
1280 self.guest.set_domain_name(name)
1282 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, name)
1283 config_file = "%s/%s" % (self.config_dir, name)
1285 src_pool = self.get_storage_pool_name_bydomain(name, "os")[0]
1286 src_path = self.get_storage_pool_targetpath(src_pool)
1288 domain_dir = "%s/%s" % (src_path,name,)
1289 image_file = "%s/images/%s.img" % (domain_dir,name)
1290 domain_snapshot_dir = "%s/%s" % (VIRT_SNAPSHOT_DIR,name,)
1292 export_dir = "%s/%s" % (directory,uuid)
1293 #export_domain_dir = "%s/%s" % (export_dir,name)
1294 export_domain_dir = "%s/domain/%s" % (export_dir,name)
1295 #export_disk_dir = "%s/%s" % (export_dir,name)
1296 export_disk_dir = "%s/disk" % (export_dir)
1298 if os.path.exists(export_domain_dir):
1299 raise KaresansuiVirtException(_("Directory '%s' found.") % export_domain_dir)
1302 if not os.path.exists(export_domain_dir):
1303 os.makedirs(export_domain_dir)
1304 if os.getuid() == 0:
1305 r_chgrp(export_dir,KARESANSUI_GROUP)
1306 r_chmod(export_dir,"o-rwx")
1308 if not os.path.exists(export_disk_dir):
1309 os.makedirs(export_disk_dir)
1310 if os.getuid() == 0:
1311 r_chgrp(export_dir,KARESANSUI_GROUP)
1312 r_chmod(export_dir,"o-rwx")
1314 # -----------------------
1315 # Export information to disk to retrieve.
1316 disk_keys = self.get_storage_volume_bydomain(
1317 self.guest.get_domain_name(), 'disk', 'key')
1320 for key in disk_keys.keys():
1322 _path = disk_keys[key]
1323 _pool_name = self.get_storage_pool_name_byimage(_path)
1326 raise KaresansuiVirtException("'%s' disk storage pool can not be found." % _volume)
1328 _pool_name = _pool_name[0]
1330 _pool = self.search_kvn_storage_pools(_pool_name)
1332 raise KaresansuiVirtException("'%s' disk storage pool(path) can not be found." % _volume)
1336 _pool_path = _pool.get_info()['target']['path']
1337 pool_uuid = _pool.get_info()['uuid']
1339 disks_info.append({"volume" : _volume,
1340 "volume_path" : _path,
1341 "pool_name" : _pool_name,
1342 "domname" : self.guest.get_domain_name(),
1343 "pool_path" : _pool_path,
1344 "pool_uuid" : pool_uuid
1348 for disk_info in disks_info:
1349 disk_dir = "%s/%s" % (disk_info["pool_path"], disk_info["domname"])
1350 if progresscb is not None:
1351 from karesansui.lib.utils import copy_file_cb
1355 for _sub in glob.glob("%s/disk/*" % disk_dir):
1356 if os.path.isfile(_sub):
1357 # {export uuid}/disk/{pool name}/{domname}/[images|boot|disk]
1358 #dst_file = "%s/%s" % (export_disk_dir, os.path.basename(_sub),)
1359 dst_file = "%s/%s/%s/disk/%s" % (export_disk_dir,
1360 disk_info["pool_name"],
1361 disk_info["domname"],
1362 os.path.basename(_sub),
1365 src_files.append(src_file)
1366 dst_files.append(dst_file)
1367 copy_file_cb(src_files,dst_files,progresscb,each=False)
1369 CopyFile(disk_dir, export_disk_dir)
1371 # -----------------------
1373 # copy domain image data
1374 if progresscb is not None:
1375 from karesansui.lib.utils import copy_file_cb
1380 src_files.append("%s/images/%s.img" % (domain_dir, name))
1381 dst_files.append("%s/images/%s.img" % (export_domain_dir, name))
1382 copy_file_cb(src_files,dst_files,progresscb,each=False)
1387 for _sub in glob.glob("%s/boot/*" % domain_dir):
1388 if os.path.isfile(_sub) is True:
1389 dst_file = "%s/boot/%s" % (export_domain_dir,os.path.basename(_sub),)
1390 src_files.append(_sub)
1391 dst_files.append(dst_file)
1393 copy_file_cb(src_files,dst_files,progresscb,each=False)
1395 CopyFile(domain_dir,export_domain_dir)
1397 # copy domain configuration
1398 export_xml_file = "%s/%s.xml" % (export_dir,name,)
1399 CopyFile(xml_file, export_xml_file)
1400 export_config_file = "%s/%s.conf" % (export_dir,name,)
1401 CopyFile(config_file,export_config_file)
1403 # copy snapshot xmls
1404 if os.path.exists(domain_snapshot_dir):
1405 export_snapshot_dir = "%s/snapshot" % (export_domain_dir,)
1408 os.makedirs(export_snapshot_dir)
1412 for snapshot_xml in glob.glob("%s/*.xml" % domain_snapshot_dir):
1413 snapshot_xml_name = os.path.basename(snapshot_xml)
1414 export_snapshot_xml = "%s/%s" % (export_snapshot_dir,snapshot_xml_name,)
1415 CopyFile(snapshot_xml,export_snapshot_xml)
1417 # symlink to recognize as libvirt pool
1418 export_image_file = "%s/images/%s.img" % (export_domain_dir,name)
1419 link_file = "%s/%s-%s.img" % (directory,uuid,name,)
1420 if os.path.exists(link_file) is False:
1421 os.symlink(export_image_file,link_file)
1424 if database['icon']:
1425 CopyFile(realicon, "%s/%s" % (export_dir, database['icon']))
1428 param = ExportConfigParam()
1430 param.set_path("%s/%s" % (export_dir, GUEST_EXPORT_FILE))
1431 param.set_uuid(uuid)
1432 param.set_domain(name)
1433 param.set_title(title)
1434 param.set_created(str(int(time.time())))
1435 param.set_database(database)
1436 param.set_pool(src_pool)
1437 param.set_snapshots(snapshots)
1440 for disk_info in disks_info:
1441 param.add_disk(disk_info['volume'],
1442 disk_info['pool_name'],
1443 disk_info['pool_path'],
1446 generator = ExportXMLGenerator(param.get_path())
1448 cfgxml = generator.generate(param)
1451 generator.writecfg(cfgxml)
1453 if os.getuid() == 0:
1454 r_chgrp(export_dir,KARESANSUI_GROUP)
1455 r_chmod(export_dir,"o-rwx")
1457 if pool_name is not None:
1459 self.search_storage_pools(pool_name)[0].refresh(True)
1466 def import_guest(self, directory, uuid, progresscb):
1475 if not os.path.exists(directory):
1476 raise KaresansuiVirtException(_("Directory '%s' not found.") % directory)
1478 export_dir = directory
1481 param = ExportConfigParam()
1482 info_file = "%s/info.dat" % (export_dir,)
1483 if os.path.exists(info_file):
1485 param.load_xml_config(info_file)
1487 raise KaresansuiVirtException(_("'%s' is invalid format.") % info_file)
1489 raise KaresansuiVirtException(_("'%s' not found.") % info_file)
1491 id = param.get_uuid()
1492 name = param.get_domain()
1493 title = param.get_title()
1494 created = param.get_created()
1496 domains_dir = self.get_storage_pool_targetpath(param.get_pool())
1497 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, name)
1498 config_file = "%s/%s" % (self.config_dir, name)
1499 domain_dir = "%s/%s" % (domains_dir,name,)
1500 image_file = "%s/images/%s.img" % (domain_dir,name)
1501 domain_snapshot_dir = "%s/%s" % (VIRT_SNAPSHOT_DIR,name,)
1503 export_domain_dir = "%s/domain/%s" % (export_dir,name,)
1504 #export_snapshot_dir = "%s/snapshot" % (export_domain_dir,)
1505 export_snapshot_dir = "%s/snapshot" % (export_domain_dir)
1507 if not os.path.exists(export_domain_dir):
1508 raise KaresansuiVirtException(_("Directory '%s' not found.") % export_domain_dir)
1510 if os.path.exists(domain_dir):
1511 raise KaresansuiVirtException(_("guest '%s' already exists.") % name)
1514 from karesansui.lib.utils import copy_file_cb
1515 # copy disks {export dir}/{export uuid}/disk/{pool}/{domname}/disk/{disk uuid}.img
1516 export_disk_dir = "%s/disk" % (export_dir)
1517 export_disks = param.get_disks()
1521 for disk in export_disks:
1522 volume = disk['uuid']
1523 pool_name = disk['name']
1524 pool_path = disk['path']
1525 pool = self.search_kvn_storage_pools(pool_name)
1527 raise KaresansuiVirtException(_("Disk storage pools were found to import. - pool=%s") \
1533 if pool_path != pool.get_json()['target']['path']:
1534 raise KaresansuiVirtException(_("When exporting, there are differences in the storage pool information. (Storage pool path) = export=%s, import=%s") \
1535 % (pool_path, pool.get_json()['target']['path']))
1537 src_file = "%s/%s/%s/disk/%s.img" % (export_disk_dir, pool_name, name, volume)
1538 if os.path.isfile(src_file) is False:
1539 raise KaresansuiVirtException(_("Exporting the disk image can not be found."))
1541 dst_file = "%s/%s/disk/%s.img" % (pool.get_json()['target']['path'], name, volume)
1543 src_files.append(src_file)
1544 dst_files.append(dst_file)
1545 dst_symlinks.append("%s/%s" % (pool.get_json()['target']['path'], volume))
1547 copy_file_cb(src_files,dst_files,progresscb,each=False)
1548 for i in xrange(len(dst_symlinks)):
1549 os.symlink(dst_files[i], dst_symlinks[i])
1552 # copy domain image data
1555 for _sub in glob.glob("%s/*" % export_domain_dir):
1556 if os.path.isdir(_sub):
1557 dst_dir = "%s/%s" % (domain_dir,os.path.basename(_sub),)
1558 for _sub2 in glob.glob("%s/*" % _sub):
1559 if os.path.isfile(_sub2):
1561 dst_file = "%s/%s" % (dst_dir,os.path.basename(_sub2),)
1562 src_files.append(src_file)
1563 dst_files.append(dst_file)
1564 copy_file_cb(src_files,dst_files,progresscb,each=False)
1566 export_xml_file = "%s/%s.xml" % (export_dir,name,)
1568 g_param = ConfigParam(name)
1569 if os.path.isfile(export_xml_file) is False:
1570 raise KaresansuiVirtException(
1571 _("Export corrupt data. (file not found) - path=%s" % export_xml_file))
1572 g_param.load_xml_config(export_xml_file)
1574 os_image_path = "%s/%s/images/%s.img" % (domains_dir, name, name)
1575 if os.path.isfile(os_image_path) is False:
1576 raise KaresansuiVirtException(_("Import failed guest OS image. - path=%s") \
1578 os.symlink(os_image_path, "%s/%s" % (domains_dir, g_param.uuid))
1580 # copy domain configuration
1581 export_config_file = "%s/%s.conf" % (export_dir,name,)
1583 CopyFile(export_xml_file ,xml_file)
1584 CopyFile(export_config_file ,config_file)
1586 old_pattern = "<uuid>.{36}</uuid>"
1587 new_string = "<uuid>%s</uuid>" % uuid
1588 file_contents_replace(export_xml_file,xml_file,old_pattern,new_string)
1589 old_pattern = "^uuid = .*"
1590 new_string = "uuid = '%s'" % str(uuid)
1591 file_contents_replace(export_config_file ,config_file,old_pattern,new_string)
1593 if os.path.exists(xml_file):
1594 self._conn.defineXML("".join(ConfigFile(xml_file).read()))
1596 # copy snapshot xmls
1597 # libvirtdの再起動後に認識される。(qemuDomainSnapshotLoad)
1598 if os.path.exists(export_snapshot_dir):
1600 if not os.path.exists(domain_snapshot_dir):
1601 os.makedirs(domain_snapshot_dir)
1603 for snapshot_xml in glob.glob("%s/*.xml" % export_snapshot_dir):
1604 snapshot_xml_name = os.path.basename(snapshot_xml)
1605 new_snapshot_xml = "%s/%s" % (domain_snapshot_dir,snapshot_xml_name,)
1606 CopyFile(snapshot_xml,new_snapshot_xml)
1609 if os.getuid() == 0:
1610 r_chgrp(domain_dir,KARESANSUI_GROUP)
1611 r_chmod(domain_dir,"o-rwx")
1612 r_chgrp(xml_file, KARESANSUI_GROUP)
1613 r_chgrp(config_file, KARESANSUI_GROUP)
1614 if os.path.exists(domain_snapshot_dir):
1615 r_chmod(domain_snapshot_dir,"o-rwx")
1616 r_chgrp(domain_snapshot_dir,KARESANSUI_GROUP)
1618 # This is commented out.
1619 # cos guests that set to autostart flag will be started without intention.
1620 #from karesansui.lib.virt.snapshot import KaresansuiVirtSnapshot
1621 #kvs = KaresansuiVirtSnapshot()
1622 #kvs.refreshSnapshot()
1624 # Storage Pool refresh
1626 self.search_storage_pools(param.get_pool())[0].refresh(True)
1627 for disk in param.get_disks():
1628 self.search_storage_pools(disk["name"])[0].refresh(True)
1635 def get_hypervisor_type_bydomain(self,name=None):
1637 指定ドメインのハイパーバイザーの種類を取得する。
1639 @return: hypervisor type
1640 xen or kvm is available now (but depend on domain.xml)
1641 e.g. xen kvm hyperv kqemu ldom lxc one openvz phyp qemu test
1642 uml vbox vmware vserver
1643 @rtype: string (lower case only)
1651 if not (name is None):
1652 self.guest.set_domain_name(name)
1655 retval = self.guest.get_info()['VMType']
1656 except libvirt.libvirtError, e:
1664 def list_inactive_network(self):
1667 現在起動していない仮想ネットワークのリストを取得します。
1673 return self._conn.listDefinedNetworks()
1675 def list_active_network(self):
1678 現在起動している仮想ネットワークのリストを取得します。
1685 for name in self._conn.listNetworks():
1689 def search_networks(self, name=None):
1700 names = self._conn.listNetworks()
1701 for __name in names:
1702 networks.append(self._conn.networkLookupByName(__name))
1703 names = self.list_inactive_network()
1704 for __name in names:
1705 networks.append(self._conn.networkLookupByName(__name))
1710 regex_regex = re.compile(r"""^regex:(?P<regex>.*)""")
1711 m = regex_regex.match(name)
1714 for network in networks:
1715 network_name = network.name()
1717 if network_name == name:
1720 regex = m.group('regex')
1721 query_regex = re.compile(r""+regex+"")
1722 n = query_regex.search(network_name)
1724 n_networks.append(network)
1729 raise KaresansuiVirtException("network %s not found" % name)
1731 def search_kvn_networks(self, name=None):
1733 指定された仮想ネットワークオブジェクトをKaresansuiVirtNetworkオブジェクトのlistにして返却する。
1736 TODO: English Comment
1741 name = self.uuid_to_domname(name)
1744 for network in self.search_networks(name):
1746 KaresansuiVirtNetwork(conn=self, name=network.name()))
1750 def create_network(self, name, cidr, dhcp_start=None, dhcp_end=None, forward=None, bridge=None, autostart=None):
1759 param = NetworkConfigParam(name)
1760 param.set_default_networks(cidr,dhcp_start,dhcp_end)
1761 param.set_ipaddr_and_netmask(cidr)
1763 if 'dev' in forward.keys():
1764 param.set_forward_dev(forward['dev'])
1765 if 'mode' in forward.keys():
1766 param.set_forward_mode(forward['mode'])
1768 param.set_bridge(bridge)
1769 uuid = StrFromUUID(GenUUID())
1770 param.set_uuid(uuid)
1772 generator = NetworkXMLConfigGenerator()
1774 cfgxml = generator.generate(param)
1777 generator.writecfg(cfgxml)
1779 ret = libvirtmod.virNetworkCreateXML(self._conn._o,cfgxml)
1781 self._conn.networkDefineXML(cfgxml)
1783 if autostart is not None:
1784 self.network.set_network_name(name)
1785 self.network.autostart(autostart)
1789 def update_network(self, name, cidr=None, dhcp_start=None, dhcp_end=None, forward=None, bridge=None, autostart=None):
1798 # パラメータをリセットする場合と引数が無い場合の区別 => リセットの場合は、空文字列を渡す。
1805 # Not changed, do nothing
1810 param = self.search_kvn_networks(name)[0].get_network_config_param()
1812 raise KaresansuiVirtException("Can't get parameters of network '%s'." % name)
1815 param.set_ipaddr_and_netmask(cidr)
1817 param.set_dhcp_start(dhcp_start)
1819 param.set_dhcp_end(dhcp_end)
1821 if 'dev' in forward.keys():
1822 if forward['dev'] == '':
1823 param.set_forward_dev(None)
1825 param.set_forward_dev(forward['dev'])
1826 if 'mode' in forward.keys():
1827 if forward['mode'] == '':
1828 param.set_forward_mode(None)
1830 param.set_forward_mode(forward['mode'])
1832 param.set_bridge(bridge)
1834 generator = NetworkXMLConfigGenerator()
1836 cfgxml = generator.generate(param)
1840 self.stop_network(name)
1842 generator.writecfg(cfgxml)
1844 ret = libvirtmod.virNetworkCreateXML(self._conn._o,cfgxml)
1846 self._conn.networkDefineXML(cfgxml)
1848 if autostart is not None:
1849 self.network.autostart(autostart)
1853 def start_network(self,name=None):
1862 if not (name is None):
1863 self.network.set_network_name(name)
1864 self.network.start()
1866 def stop_network(self,name=None):
1875 if not (name is None):
1876 self.network.set_network_name(name)
1879 def delete_network(self,name=None):
1888 self.stop_network(name)
1889 if len(self.search_networks(name)) > 0:
1890 self.network.undefine()
1892 config = "%s/%s.xml" %(VIRT_NETWORK_CONFIG_DIR, self.network.get_network_name())
1893 if os.path.exists(config):
1896 config = "%s/autostart/%s.xml" %(VIRT_NETWORK_CONFIG_DIR, self.network.get_network_name())
1897 if os.path.exists(config):
1900 def autostart_network(self,flag=None,name=None):
1903 仮想ネットワークの自動起動を設定します。
1909 if not (name is None):
1910 self.guest.set_domain_name(name)
1911 networks = self.search_networks(self.network.get_network_name())
1913 return self.network.autostart(flag)
1921 def refresh_pools(self):
1924 現在のストレージプール情報をリフレッシュします。
1931 active_pools = self.list_active_storage_pool()
1932 #inactive_pools = self.list_inactive_storage_pool()
1934 for pool_name in active_pools + inactive_pools:
1936 pool = self.search_kvn_storage_pools(pool_name)
1937 path = pool[0].get_info()["target"]["path"]
1938 self.search_storage_pools(pool_name)[0].refresh(True)
1942 def list_inactive_storage_pool(self):
1945 現在起動していないストレージプールのリストを取得します。
1951 pools = self._conn.listDefinedStoragePools()
1953 for i in xrange(len(pools)):
1954 path = "%s/%s.xml" % (VIRT_STORAGE_CONFIG_DIR, pools[i])
1955 if os.path.isfile(path) is False:
1957 ret.append(pools[i])
1960 def list_active_storage_pool(self):
1963 現在起動しているストレージプールのリストを取得します。
1970 for name in self._conn.listStoragePools():
1974 def search_storage_pools(self, name=None, active_only=False):
1985 names = self._conn.listStoragePools()
1986 for __name in names:
1987 pools.append(self._conn.storagePoolLookupByName(__name))
1989 if active_only is False:
1990 names = self.list_inactive_storage_pool()
1991 for __name in names:
1992 pools.append(self._conn.storagePoolLookupByName(__name))
1997 regex_regex = re.compile(r"""^regex:(?P<regex>.*)""")
1998 m = regex_regex.match(name)
2002 pool_name = pool.name()
2004 if pool_name == name:
2007 regex = m.group('regex')
2008 query_regex = re.compile(r""+regex+"")
2009 n = query_regex.search(storage_name)
2011 n_pools.append(pool)
2016 raise KaresansuiVirtException("Storage pool %s not found" % name)
2018 def search_kvn_storage_pools(self, name=None, active_only=False):
2020 指定されたStorage Pool をKaresansuiVirtStoragePoolオブジェクトのlistにして返却する。
2023 TODO: English Comment
2028 name = self.uuid_to_domname(name)
2031 for pool in self.search_storage_pools(name, active_only):
2033 KaresansuiVirtStoragePool(conn=self, name=pool.name()))
2037 def start_storage_pool(self, name):
2046 return self.storage_pool.create(name)
2048 def create_storage_pool(self, name, type,
2050 allocation=0, available=0, capacity=0,
2051 source_f_type=None, source_dev_path=None, source_a_name=None,
2052 source_dir_path=None, source_h_name=None,
2053 target_p_group=None, target_p_label=None,
2054 target_p_mode=None, target_p_owner=None,
2055 target_e_format=None, target_encryption_s_type=None,
2056 #target_encryption_s_uuid=None,
2067 param = StoragePoolConfigParam(name)
2069 uuid = StrFromUUID(GenUUID())
2070 param.set_uuid(uuid)
2072 if type is not None:
2073 param.set_pool_type(type)
2075 if target_path is not None:
2076 param.set_target_path(target_path)
2078 param.set_allocation(allocation)
2079 param.set_available(available)
2080 param.set_capacity(capacity)
2082 if source_f_type is not None:
2083 param.set_source_f_type(source_f_type)
2085 if source_dev_path is not None:
2086 param.set_source_dev_path(source_dev_path)
2088 if source_dir_path is not None:
2089 param.set_source_dir_path(source_dir_path)
2091 if source_f_type is not None:
2092 param.set_source_f_type(source_f_type)
2094 if source_h_name is not None:
2095 param.set_source_h_name(source_h_name)
2097 if target_e_format is not None and \
2098 target_encryption_s_type is not None:
2099 param.set_target_e_format(target_e_format)
2100 param.set_target_encryption_s_type(target_encryption_s_type)
2101 target_encryption_s_uuid = StrFromUUID(GenUUID())
2102 param.set_target_encryption_s_uuid(target_encryption_s_uuid)
2104 if target_p_group is not None:
2105 param.set_target_permissions_group(target_p_group)
2107 if target_p_label is not None:
2108 param.set_target_permissions_label(target_p_label)
2110 if target_p_mode is not None:
2111 param.set_target_permissions_mode(target_p_mode)
2113 if target_p_owner is not None:
2114 param.set_target_permissions_owner(target_p_owner)
2116 generator = StoragePoolXMLConfigGenerator()
2118 cfgxml = generator.generate(param)
2121 generator.writecfg(cfgxml)
2123 if self.storage_pool.start(cfgxml, 0, name) == 0:
2128 def is_autostart_storage_pool(self, name=None):
2131 指定されたストレージプールが自動起動するか。
2137 if not (name is None):
2138 self.storage_pool.set_storage_name(name)
2140 pools = self.search_storage_pools(self.storage_pool.get_storage_name())
2142 ret = self.storage_pool.autostart()
2152 def autostart_storage_pool(self, flag=None, name=None):
2155 ストレージプールの自動起動設定を行います。
2161 if not (name is None):
2162 self.storage_pool.set_storage_name(name)
2164 pools = self.search_storage_pools(self.storage_pool.get_storage_name())
2166 if self.storage_pool.set_autostart(flag) == 0:
2173 def destroy_storage_pool(self,name=None):
2176 ストレージプールの削除を行います。(設定ファイルなどの情報は削除されません)
2182 if name is not None:
2183 self.storage_pool.set_storage_name(name)
2184 if self.storage_pool.destroy() == 0:
2189 def delete_storage_pool(self,name=None, flags=False):
2198 if name is not None:
2199 self.storage_pool.set_storage_name(name)
2202 self.autostart_storage_pool(False)
2204 path = "%s/%s.xml" % (VIRT_STORAGE_CONFIG_DIR, self.storage_pool.get_storage_name())
2205 if os.path.isfile(path) is True:
2208 mode = VIR_STORAGE_POOL_DELETE_NORMAL
2210 mode = VIR_STORAGE_POOL_DELETE_ZEROED
2212 if self.storage_pool.delete(mode) == 0:
2217 def is_storage_volume(self, path):
2219 指定したパスがストレージボリュームに含まれているか。
2222 Storage volume that contains the specified path.
2225 if os.path.isfile(path) is False:
2229 vir_storage_vol = self.storage_volume._conn.storageVolLookupByPath(path)
2231 except libvirt.libvirtError, e:
2232 # _("The specified path is not registered in the storage volume. '%s' (%s)")
2235 def get_storage_volume(self, pool_name, vol_name):
2245 pools = self.search_storage_pools(pool_name)
2248 vol = pools[0].storageVolLookupByName(vol_name)
2250 except libvirt.libvirtError, e:
2253 def get_storage_volume_path(self, pool_name, vol_name):
2256 ストレージボリュームのパスを取得します。
2263 vol = self.get_storage_volume(pool_name, vol_name)
2266 vol_path = vol.path()
2268 except libvirt.libvirtError, e:
2271 def get_storage_pool_UUIDString2kvn_storage_pool(self, uuidstr):
2274 ストレージプールのUUIDをもとに、ストレージプール情報を取得します。
2280 pool_obj = self._conn.storagePoolLookupByUUIDString(uuidstr)
2281 return self.search_kvn_storage_pools(pool_obj.name())
2283 def create_storage_volume(self,
2290 key=None, allocation=0, capacity=0, c_unit=None,
2292 t_p_owner=None,t_p_group=None,t_p_mode=None, t_p_label=None,
2295 b_p_owner=None, b_p_group=None, b_p_mode=None, b_p_label=None):
2304 param = StorageVolumeConfigParam(name)
2306 if volume_name is None:
2307 uuid = StrFromUUID(GenUUID())
2310 param.set_uuid(uuid)
2311 param.set_storage_name(uuid)
2313 self.storage_pool.set_storage_name(pool_name)
2314 self.storage_volume.set_storage_volume_name(uuid)
2316 #if t_path is not None:
2317 # param.set_target_path(t_path)
2319 param.set_target_f_type(t_f_type)
2324 param.set_allocation(allocation)
2325 param.set_capacity(capacity)
2327 if c_unit is not None and (capacity != 0 or allocation != 0):
2328 param.set_c_unit(c_unit)
2330 if source is not None:
2331 param.set_source(source)
2333 if t_p_owner is not None:
2334 param.set_target_permissions_owner(t_p_owner)
2336 if t_p_group is not None:
2337 param.set_target_permissions_group(t_p_group)
2339 if t_p_mode is not None:
2340 param.set_target_permissions_mode(t_p_mode)
2342 if t_p_label is not None:
2343 param.set_target_permissions_label(t_p_label)
2345 if b_path is not None:
2346 param.set_backingStore_path(b_path)
2347 if b_format is not None:
2348 param.set_backingStore_format(b_format)
2350 if b_p_owner is not None:
2351 param.set_backingStore_permissions_owner(b_p_owner)
2353 if b_p_group is not None:
2354 param.set_backingStore_permissions_group(b_p_group)
2356 if b_p_mode is not None:
2357 param.set_backingStore_permissions_mode(b_p_mode)
2359 if b_p_label is not None:
2360 param.set_backingStore_permissions_label(b_p_label)
2362 generator = StorageVolumeXMLConfigGenerator()
2364 cfgxml = generator.generate(param)
2369 #generator.writecfg(cfgxml)
2371 vir_storage_vol = self.storage_pool.vol_createXML(cfgxml, 0)
2373 if not isinstance(vir_storage_vol, libvirt.virStorageVol):
2376 pool_objs = self.search_kvn_storage_pools(pool_name)
2378 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
2381 # TODO iscsi block device
2382 domains_dir = pool_objs[0].get_info()["target"]["path"]
2383 domain_dir = self.make_domain_dir(domains_dir, name)
2386 if use == DISK_USES["IMAGES"]:
2387 disk = "%s/%s/%s.img" % (domain_dir, DISK_USES["IMAGES"], name)
2388 shutil.move("%s/%s" % (domains_dir, param.get_storage_name()),
2392 "%s/%s" % (domains_dir, param.get_storage_name()))
2394 disk = "%s/%s/%s.img" % (domain_dir, DISK_USES["DISK"], uuid)
2395 shutil.move("%s/%s" % (domains_dir, uuid),
2399 "%s/%s" % (domains_dir, uuid))
2401 # Storage Pool refresh
2403 self.search_storage_pools(pool_name)[0].refresh(True)
2409 def delete_storage_volume(self,pool_name, vol_name, use, flags=False):
2412 ストレージボリュームを完全に削除します。
2418 self.storage_volume.set_storage_name(pool_name)
2419 self.storage_volume.set_storage_volume_name(vol_name)
2421 # delete storage dir
2422 pool_objs = self.search_kvn_storage_pools(pool_name)
2424 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
2427 domains_dir = pool_objs[0].get_info()["target"]["path"]
2428 target_path = "%s/%s" % (domains_dir, vol_name)
2429 taget_real_path = os.path.realpath(target_path)
2432 mode = VIR_STORAGE_VOL_DELETE_NORMAL
2434 mode = VIR_STORAGE_VOL_DELETE_ZEROED
2436 if self.storage_volume.delete(mode) != 0:
2440 if use == DISK_USES["IMAGES"]:
2441 os.remove(taget_real_path)
2442 if os.path.exists(target_path) is True:
2443 os.remove(target_path)
2444 elif use == DISK_USES["DISK"]:
2445 os.remove(taget_real_path)
2446 if os.path.exists(target_path) is True:
2447 os.remove(target_path)
2451 def get_storage_pool_type(self, pool_name):
2454 @param pool_name: ストレージプール名
2455 @return: ストレージプールの種別
2459 Get the type of storage pool.
2460 @param pool_name: name of storage pool
2461 @return: type of storage pool
2468 pool_objs = self.search_kvn_storage_pools(pool_name)
2470 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
2472 retval = pool_objs[0].get_info()['type']
2478 def get_storage_pool_targetpath(self, pool_name):
2480 ストレージプールのターゲットパスを取得します。(dir)
2481 @param pool_name: ストレージプール名
2486 Get the target path of storage pool.
2487 @param pool_name: name of storage pool
2488 @return: target path
2495 pool_objs = self.search_kvn_storage_pools(pool_name)
2497 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
2499 retval = pool_objs[0].get_info()['target']['path']
2505 def get_storage_pool_sourcedevicepath(self, pool_name):
2507 ストレージプールのソースデバイスパスを取得します。(iscsi)
2508 @param pool_name: ストレージプール名
2513 Get the source device path of storage pool.
2514 @param pool_name: name of storage pool
2515 @return: source device path
2522 pool_objs = self.search_kvn_storage_pools(pool_name)
2524 raise KaresansuiVirtException(_("Storage pool could not be found. pool=%s") % \
2526 retval = pool_objs[0].get_info()['source']['dev_path']
2532 def get_storage_pool_name_byimage(self, path):
2534 ディスクイメージのパスからストレージプールの名前を取得する
2535 @param path: ディスクイメージのパス
2536 @return: ストレージプールの名前
2540 Get name of storage pool where the specified disk image belongs to.
2541 @param path: path of disk image
2542 @return: list of storage pool name
2549 realpath = os.path.realpath(path)
2551 # Includes realpath as detecting target if it is symbolic link.
2552 if realpath != path:
2553 paths.append(realpath)
2556 pool_objs = self.search_kvn_storage_pools()
2558 raise KaresansuiVirtException(_("No storage pools could be found."))
2560 for pool_obj in pool_objs:
2561 pool_info = pool_obj.get_info()
2562 name = pool_info['name']
2564 for vol_name,vol_path in self.get_storage_volume_bypool(name, attr="path").iteritems():
2566 if ( vol_path == _path or os.path.realpath(vol_path) == _path ) and not name in retval:
2574 def get_storage_pool_name_bydomain(self, domain, image_type=None):
2576 ドメインの名前からストレージプールの名前を取得する
2577 * iscsi is returning the [].
2578 @param domain: ドメイン名
2579 @param image_type: イメージの種別
2580 "os" :ゲストOS本体のイメージファイル
2581 "disk" :拡張ディスクのイメージファイル
2582 未指定またはそれ以外:ドメインに属する全てのイメージファイル
2583 @return: ストレージプールの名前
2587 Get name of storage pool where image files that the specified domain uses belong to.
2589 @param domain: domain name
2590 @return: list of storage pool name
2597 if image_type == "os":
2598 regex.append("%s/images/%s\.img$" % (domain,domain,))
2599 if image_type == "disk":
2600 regex.append("%s/disk/[0-9\.]+\.img$" % (domain,))
2601 regex_str = "|".join(regex)
2604 guest_obj = self.search_kvg_guests(domain)[0]
2606 raise KaresansuiVirtException(_("Domain could not be found. name=%s") % \
2609 os_root = guest_obj.get_info()['os_root']
2611 for info in guest_obj.get_disk_info():
2613 target = info['target']['dev']
2618 source = info['source']['file']
2621 source = info['source']['dev']
2626 if image_type == "os":
2627 if os_root is not None and target == os.path.basename(os_root):
2628 pools = self.get_storage_pool_name_byimage(source)
2629 elif image_type == "disk":
2630 if os_root is not None and target != os.path.basename(os_root):
2631 pools = self.get_storage_pool_name_byimage(source)
2633 pools = self.get_storage_pool_name_byimage(source)
2636 for pool_name in pools:
2637 if not pool_name in retval:
2638 retval.append(pool_name)
2640 # in case that os_root is not specified.
2641 if len(retval) == 0:
2642 for info in guest_obj.get_disk_info():
2643 if re.search(regex_str,info['source']['file']):
2644 for pool_name in self.get_storage_pool_name_byimage(info['source']['file']):
2645 if not pool_name in retval:
2646 retval.append(pool_name)
2654 def get_storage_volume_bypool(self, pool, attr="name"):
2656 ストレージプールの名前からボリュームの一覧を取得する
2659 "name" :ボリュームの名前(UUID形式)
2663 未指定 :nameが指定されたものとする
2665 attr 'info' depends on virStorageVolInfo structure.
2666 int type; virStorageVolType flags
2669 unsigned long long capacity; Logical size bytes
2670 unsigned long long allocation; Current allocation bytes
2671 @return: ストレージボリューム名と対応するデータの辞書配列
2675 Get name of storage volume in the specified pool.
2677 @param pool: name of pool
2678 @param attr: volume attribute that you want to get
2679 "name" :name of volume (UUID style)
2680 "key" :key of volume
2681 "path" :path of volume
2682 "info" :volume information
2683 none :same as 'name' is specified
2685 @return: dict of storage volume
2692 pool_obj = self.search_kvn_storage_pools(pool)[0]
2694 raise KaresansuiVirtException(_("No storage pool '%s' could be found.") % pool)
2696 vols = pool_obj.vol_listVolumes()
2698 vol_obj = pool_obj.vol_storageVolLookupByName(vol)
2700 exec("value = vol_obj.%s()" % attr)
2709 def get_storage_volume_iscsi_rpath_bystorage(self, pool, volume):
2711 ストレージプール名とストレージボリューム名から、ストレージのREAL PATHを取得します。
2714 TODO: To include comments in English
2719 pool_obj = self.search_kvn_storage_pools(pool)[0]
2721 raise KaresansuiVirtException(_("No storage pool '%s' could be found.") % pool)
2723 vol_obj = pool_obj.vol_storageVolLookupByName(volume)
2730 def get_storage_volume_bydomain(self, domain, image_type=None, attr="name"):
2732 ドメインの名前からボリュームの一覧を取得する
2733 @param domain: ドメイン名
2734 @param image_type: イメージの種別
2735 "os" :ゲストOS本体のイメージファイル
2736 "disk" :拡張ディスクのイメージファイル
2737 未指定 :ドメインに属する全てのイメージファイル
2739 "name" :ボリュームの名前(UUID形式)
2743 未指定 :nameが指定されたものとする
2745 attr 'info' depends on virStorageVolInfo structure.
2746 int type; virStorageVolType flags
2749 unsigned long long capacity; Logical size bytes
2750 unsigned long long allocation; Current allocation bytes
2751 @return: ストレージボリューム名と対応するデータの辞書配列
2755 Get name of storage volume in the specified domain.
2757 @param domain: domain name
2758 @param image_type: type of image file
2760 "disk" :extended disk image only
2761 none :all images that domain uses
2762 @param attr: volume attribute that you want to get
2763 "name" :name of volume (UUID style)
2764 "key" :key of volume
2765 "path" :path of volume
2766 "info" :volume information
2767 none :same as 'name' is specified
2769 @return: dict of storage volume
2776 if image_type == "os":
2777 regex.append("%s/images/%s\.img$" % (domain,domain,))
2778 if image_type == "disk":
2779 regex.append("%s/disk/[0-9\.]+\.img$" % (domain,))
2780 regex_str = "|".join(regex)
2783 guest_obj = self.search_kvg_guests(domain)[0]
2785 raise KaresansuiVirtException(_("Domain could not be found. name=%s") % \
2788 os_root = guest_obj.get_info()['os_root']
2790 for info in guest_obj.get_disk_info():
2792 target = info['target']['dev']
2797 source = info['source']['file']
2800 source = info['source']['dev']
2805 if image_type == "os":
2806 if os_root is not None and target == os.path.basename(os_root):
2807 pools = self.get_storage_pool_name_byimage(source)
2808 elif image_type == "disk":
2809 if os_root is not None and target != os.path.basename(os_root):
2810 pools = self.get_storage_pool_name_byimage(source)
2812 pools = self.get_storage_pool_name_byimage(source)
2816 vols = self.get_storage_volume_bypool(_pool, attr=attr)
2817 for vol,value in vols.iteritems():
2818 path = self.get_storage_volume_iscsi_rpath_bystorage(_pool,vol)
2819 if path[0:5] != "/dev/":
2820 path = os.path.realpath(path)
2821 if source == path and not vol in retval.keys():
2830 def get_storage_volume_symlink(self, path):
2832 ディスクイメージのパスからストレージボリューム(symlink)の名前を取得します。
2835 TODO: English Comment
2841 realpath = os.path.realpath(path)
2843 # Includes realpath as detecting target if it is symbolic link.
2844 if realpath != path:
2845 paths.append(realpath)
2848 pool_objs = self.search_kvn_storage_pools()
2850 raise KaresansuiVirtException(_("No storage pools could be found."))
2852 for pool_obj in pool_objs:
2853 pool_info = pool_obj.get_info()
2854 if pool_info['type'] != 'dir' or pool_info['is_active'] is False:
2857 vols = pool_obj.vol_listVolumes()
2859 vol_path = "%s/%s" % (pool_info['target']['path'], vol)
2860 vol_real_path = os.path.realpath(vol_path)
2861 if path == vol_real_path:
2862 #ret.append(vol_real_path)
2868 def get_storage_volume_iscsi_bysymlink(self, symlink):
2870 example形式のiscsiパスからlibvirtのストレージボリューム情報を取得します。
2872 @param symlink: example) 'ip-192.168.100.100:3260-iscsi-iqn.2010-01.info.karesansui-project:iscsi-123-lun-1'
2873 @return: {pool: プール名,volume: ボリューム名,rpath:iscsiのby-path}
2876 TODO: To include comments in English
2879 pools = self.search_kvn_storage_pools()
2880 rpath = "%s/%s" % (ISCSI_DEVICE_DIR, symlink)
2883 name = pool.get_storage_name()
2884 if self.get_storage_pool_type(name) == 'iscsi':
2885 volumes = self.get_storage_volume_bypool(name, 'key')
2886 for vkey in volumes.keys():
2887 if rpath == volumes[vkey]:
2888 ret = {"pool" : name,
2890 "rpath" : volumes[vkey],
2896 class KaresansuiVirtGuest:
2898 def __init__(self, conn, name=None):
2899 self.connection = conn
2900 self._conn = self.connection._conn
2901 self.set_domain_name(name)
2905 JSON形式でKaresansuiVirtGuest情報を返却する。
2908 TODO: English Comment
2913 ret['name'] = self.get_domain_name()
2914 ret.update(self.get_info())
2917 def set_domain_name(self,name=None):
2919 self.domain = conn.uuid_to_domname(name)
2923 def get_domain_name(self):
2927 dom = self._conn.lookupByName(self.get_domain_name())
2930 os_type = dom.OSType()
2934 param = ConfigParam(dom.name())
2935 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
2936 if not os.path.exists(xml_file):
2937 ConfigFile(xml_file).write(dom.XMLDesc(0))
2938 if os.getuid() == 0 and os.path.exists(xml_file):
2939 r_chgrp(xml_file,KARESANSUI_GROUP)
2940 param.load_xml_config(xml_file)
2942 vm_type = param.domain_type
2943 os_root = param.os_root
2944 hypervisor = self.connection.get_hypervisor_type()
2946 hvVersion = libvirtmod.virConnectGetVersion(self._conn._o)
2947 hvVersion_major = hvVersion / 1000000
2948 hvVersion %= 1000000
2949 hvVersion_minor = hvVersion / 1000
2950 hvVersion_rel = hvVersion % 1000
2951 hv_version = "%s %d.%d.%d" %(hypervisor, hvVersion_major, hvVersion_minor, hvVersion_rel)
2958 "nrVirtCpu" : data[3],
2959 "cpuTime" : data[4],
2962 "hypervisor": hypervisor,
2963 "hv_version": hv_version,
2964 "os_root" : os_root,
2967 def get_netinfo(self):
2969 dom = self._conn.lookupByName(self.get_domain_name())
2971 if self.get_info()["VMType"] == "kvm":
2972 eth_info = get_ifconfig_info("regex:^eth")
2973 for dev,value in eth_info.iteritems():
2976 vif_info = get_ifconfig_info("regex:^vif%d\.[0-9]" % dom_id)
2977 for dev,value in vif_info.iteritems():
2978 dev = dev.replace("vif%d." % (dom_id,), "eth")
2982 def get_disk_info(self):
2984 dom = self._conn.lookupByName(self.get_domain_name())
2986 param = ConfigParam(dom.name())
2987 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
2988 if not os.path.exists(xml_file):
2989 ConfigFile(xml_file).write(dom.XMLDesc(0))
2990 if os.getuid() == 0 and os.path.exists(xml_file):
2991 r_chgrp(xml_file,KARESANSUI_GROUP)
2992 param.load_xml_config(xml_file)
2994 for info in param.disks:
2998 type = info['disk_type']
2999 device = info['device']
3002 driver['name'] = info["driver_name"]
3004 driver['name'] = None
3006 driver['type'] = info["driver_type"]
3008 driver['type'] = None
3011 source['dev'] = info['path']
3012 source_path = source['dev']
3014 source['file'] = info['path']
3015 source_path = source['file']
3017 target['dev'] = info['target']
3018 target['bus'] = info['bus']
3020 if os.path.exists(source_path):
3021 img_info = get_disk_img_info(source_path)
3023 img_size = img_info['virtual_size']
3025 img_size = img_info['real_size']
3026 source['size'] = get_filesize_MB(img_size)
3039 def get_vcpus_info(self):
3040 dom = self._conn.lookupByName(self.get_domain_name())
3042 param = ConfigParam(dom.name())
3043 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
3044 if not os.path.exists(xml_file):
3045 ConfigFile(xml_file).write(dom.XMLDesc(1))
3046 if os.getuid() == 0 and os.path.exists(xml_file):
3047 r_chgrp(xml_file,KARESANSUI_GROUP)
3048 param.load_xml_config(xml_file)
3051 max_vcpus = int(param.max_vcpus)
3055 if self.status() != VIR_DOMAIN_SHUTOFF:
3056 vcpus = self.get_info()['nrVirtCpu']
3062 bootup_vcpus = int(param.vcpus)
3067 "max_vcpus" :max_vcpus,
3069 "bootup_vcpus" :bootup_vcpus,
3072 def get_interface_info(self):
3074 dom = self._conn.lookupByName(self.get_domain_name())
3076 param = ConfigParam(dom.name())
3077 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
3078 if not os.path.exists(xml_file):
3079 ConfigFile(xml_file).write(dom.XMLDesc(0))
3080 if os.getuid() == 0 and os.path.exists(xml_file):
3081 r_chgrp(xml_file,KARESANSUI_GROUP)
3082 #param.load_xml_config(xml_file)
3083 param.load_xml_config(dom.XMLDesc(0))
3085 for info in param.interfaces:
3091 mac['address'] = info['mac']
3092 script['path'] = info['script']
3093 target['dev'] = info['target']
3094 if str(type) == "network":
3096 source['network'] = info['network']
3098 source['network'] = None
3101 source['bridge'] = info['bridge']
3103 source['bridge'] = None
3112 infos.append(if_info)
3116 def get_graphics_info(self):
3117 dom = self._conn.lookupByName(self.get_domain_name())
3119 """ current info """
3120 param = ConfigParam(dom.name())
3121 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
3122 if not os.path.exists(xml_file):
3123 ConfigFile(xml_file).write(dom.XMLDesc(0))
3124 if os.getuid() == 0 and os.path.exists(xml_file):
3125 r_chgrp(xml_file,KARESANSUI_GROUP)
3126 param.load_xml_config(xml_file)
3128 type = param.get_graphic_type()
3129 port = param.get_vnc_port()
3130 autoport = param.get_vnc_autoport()
3131 listen = param.get_vnc_listen()
3132 keymap = param.get_vnc_keymap()
3136 "autoport":autoport,
3141 """ current setting """
3142 param = ConfigParam(self.get_domain_name())
3143 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3144 if not os.path.exists(xml_file):
3145 dom = self._conn.lookupByName(self.get_domain_name())
3146 ConfigFile(xml_file).write(dom.XMLDesc(0))
3147 if os.getuid() == 0 and os.path.exists(xml_file):
3148 r_chgrp(xml_file,KARESANSUI_GROUP)
3149 param.load_xml_config(xml_file)
3150 port = param.get_vnc_port()
3151 autoport = param.get_vnc_autoport()
3152 listen = param.get_vnc_listen()
3153 keymap = param.get_vnc_keymap()
3154 passwd = param.get_vnc_passwd()
3157 "autoport":autoport,
3163 return {"info":current_info,"setting":current_setting}
3166 if self.is_creatable() is True:
3168 dom = self._conn.lookupByName(self.get_domain_name())
3170 for x in range(0,5):
3172 if self.status() != VIR_DOMAIN_SHUTOFF:
3176 if self.is_shutdownable() is True:
3178 dom = self._conn.lookupByName(self.get_domain_name())
3180 for x in range(0,120):
3182 if self.status() == VIR_DOMAIN_SHUTOFF:
3186 if self.is_shutdownable() is True:
3188 dom = self._conn.lookupByName(self.get_domain_name())
3194 for x in range(0,480):
3196 if self.status() == VIR_DOMAIN_SHUTOFF:
3200 for x in range(0,30):
3202 if self.status() != VIR_DOMAIN_SHUTOFF:
3206 if self.is_destroyable() is True:
3208 dom = self._conn.lookupByName(self.get_domain_name())
3210 for x in range(0,120):
3212 if self.status() == VIR_DOMAIN_SHUTOFF:
3216 if self.is_suspendable() is True:
3218 dom = self._conn.lookupByName(self.get_domain_name())
3220 for x in range(0,5):
3222 if self.status() == VIR_DOMAIN_PAUSED:
3226 if self.is_resumable() is True:
3228 dom = self._conn.lookupByName(self.get_domain_name())
3230 for x in range(0,5):
3232 if self.status() != VIR_DOMAIN_PAUSED:
3236 dom = self._conn.lookupByName(self.get_domain_name())
3240 return self.get_info()["state"]
3242 def save(self,file):
3243 dom = self._conn.lookupByName(self.get_domain_name())
3245 for x in range(0,120):
3247 if self.status() == VIR_DOMAIN_SHUTOFF:
3251 def set_current_snapshot(self,id=None):
3253 from karesansui.lib.virt.config import ConfigParam
3254 param = ConfigParam(self.get_domain_name())
3256 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3257 if not os.path.exists(xml_file):
3258 dom = self._conn.lookupByName(self.get_domain_name())
3259 ConfigFile(xml_file).write(dom.XMLDesc(0))
3260 if os.getuid() == 0 and os.path.exists(xml_file):
3261 r_chgrp(xml_file,KARESANSUI_GROUP)
3262 param.load_xml_config(xml_file)
3264 param.set_current_snapshot(id)
3266 xml_generator = XMLConfigGenerator()
3267 cfgxml = xml_generator.generate(param)
3268 self._conn.defineXML(cfgxml)
3270 sync_config_generator(param, self.get_domain_name())
3273 def autostart(self, flag=None):
3274 if self.connection.get_hypervisor_type() == "Xen":
3275 autostart_file = "%s/%s" %(VIRT_XENDOMAINS_AUTO_DIR,self.get_domain_name())
3278 if not os.path.exists(autostart_file):
3281 "%s/%s" %(self.connection.config_dir,self.get_domain_name()),
3282 "%s" % VIRT_XENDOMAINS_AUTO_DIR
3284 ret = ExecCmd(command_args)
3286 if os.path.exists(autostart_file):
3287 os.unlink(autostart_file)
3289 return os.path.lexists(autostart_file)
3291 if self.connection.get_hypervisor_type() == "QEMU":
3292 autostart_file = "%s/%s.xml" %(VIRT_AUTOSTART_CONFIG_DIR,self.get_domain_name())
3293 dom = self._conn.lookupByName(self.get_domain_name())
3295 return dom.setAutostart(flag)
3297 return dom.setAutostart(flag)
3299 return os.path.exists(autostart_file)
3301 def next_disk_target(self,bus=None):
3302 dom = self._conn.lookupByName(self.get_domain_name())
3305 param = ConfigParam(dom.name())
3306 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, dom.name())
3307 if not os.path.exists(xml_file):
3308 ConfigFile(xml_file).write(dom.XMLDesc(0))
3309 if os.getuid() == 0 and os.path.exists(xml_file):
3310 r_chgrp(xml_file,KARESANSUI_GROUP)
3311 param.load_xml_config(xml_file)
3314 bus = self.connection.bus_types[0]
3321 prefix_regex = "hd|xvd"
3324 for info in param.disks:
3325 block_name = info['target']
3326 p = re.compile(r"""^(?P<prefix>%s)(?P<serial>[a-z])$""" % prefix_regex)
3327 m = p.match(block_name)
3329 prefix = m.group("prefix")
3330 serials.append(m.group("serial"))
3333 prefix = prefix_regex
3335 for i,_x in enumerate('abcdefghijklmnopqrstuvwxyz'):
3336 if not _x in serials:
3340 return "%s%s" %(prefix, next_serial)
3342 """This is unused method
3343 def add_disk(self, path, target, size, is_sparse=True, bus=None,
3344 driver_name=None, driver_type=None):
3345 name = self.get_domain_name()
3347 # TODO VIRT_DOMAINS_DIR
3348 domain_disk_dir = "%s/%s/disk" % (VIRT_DOMAINS_DIR,name,)
3349 if not os.path.exists(domain_disk_dir):
3350 os.makedirs(domain_disk_dir)
3353 bus = self.connection.bus_types[0]
3355 if driver_type is None:
3356 if driver_name == "qemu":
3357 driver_type = "qcow2"
3362 MakeDiskImage(path,int(size),driver_type, is_sparse)
3363 return self.append_disk(path, target, bus,
3364 driver_name=driver_name, driver_type=driver_type)
3366 if os.path.exists(path) is True:
3371 def append_disk(self, path, target, bus=None, disk_type=None, driver_name=None, driver_type=None):
3373 from karesansui.lib.virt.config import ConfigParam
3374 param = ConfigParam(self.get_domain_name())
3375 dom = self._conn.lookupByName(self.get_domain_name())
3377 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3378 if not os.path.exists(xml_file):
3379 ConfigFile(xml_file).write(dom.XMLDesc(0))
3380 if os.getuid() == 0 and os.path.exists(xml_file):
3381 r_chgrp(xml_file,KARESANSUI_GROUP)
3382 param.load_xml_config(xml_file)
3385 bus = self.connection.bus_types[0]
3387 if disk_type != 'block':
3388 if driver_name is None:
3389 if self.connection.get_hypervisor_type() == "QEMU":
3390 driver_name = "qemu"
3391 if driver_type is None:
3392 if driver_name == "qemu":
3393 driver_type = "qcow2"
3395 param.add_disk(path,
3399 disk_type=disk_type,
3400 driver_name=driver_name,
3401 driver_type=driver_type)
3404 from karesansui.lib.virt.config import XMLDiskConfigGenerator
3405 generator = XMLDiskConfigGenerator()
3406 generator.set_path(path)
3407 generator.set_target(target)
3408 cfg = generator.generate(None)
3410 # qemu: cannot attach device on inactive domain
3411 if self.connection.get_hypervisor_type() == "QEMU" and dom.isActive() == 0:
3413 # qemu: disk bus 'ide' cannot be hotplugged.
3414 elif self.connection.get_hypervisor_type() == "QEMU" and bus is not None and bus == "ide":
3416 """Do not attach device whatever domain is active or not.
3418 dom.attachDevice(cfg)
3421 xml_generator = XMLConfigGenerator()
3422 cfgxml = xml_generator.generate(param)
3423 self._conn.defineXML(cfgxml)
3427 sync_config_generator(param, self.get_domain_name())
3429 def delete_disk(self, target):
3430 status = self.status()
3431 if status == VIR_DOMAIN_PAUSED:
3434 #raise KaresansuiVirtException("Domain %s is suspended." % self.get_domain_name())
3436 from karesansui.lib.virt.config import ConfigParam
3437 param = ConfigParam(self.get_domain_name())
3438 dom = self._conn.lookupByName(self.get_domain_name())
3440 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3441 if not os.path.exists(xml_file):
3442 ConfigFile(xml_file).write(dom.XMLDesc(0))
3443 if os.getuid() == 0 and os.path.exists(xml_file):
3444 r_chgrp(xml_file,KARESANSUI_GROUP)
3445 param.load_xml_config(xml_file)
3447 path = param.get_disk_path(target)
3449 # physical disk remove
3450 if path is not None and os.path.exists(path) is True:
3454 self.logger.info("You do not have a disk file. - %s" % path)
3456 param.delete_disk(target)
3459 from karesansui.lib.virt.config import XMLDiskConfigGenerator
3460 generator = XMLDiskConfigGenerator()
3461 generator.set_target(target)
3462 generator.set_path(path)
3463 cfg = generator.generate(None)
3465 """Do not detach device whatever domain is active or not.
3467 dom.detachDevice(cfg)
3469 xml_generator = XMLConfigGenerator()
3470 cfgxml = xml_generator.generate(param)
3471 self._conn.defineXML(cfgxml)
3473 xml_generator = XMLConfigGenerator()
3474 cfgxml = xml_generator.generate(param)
3475 self._conn.defineXML(cfgxml)
3477 if status == VIR_DOMAIN_PAUSED:
3479 except KaresansuiConfigParamException, e:
3481 except Exception, e:
3484 sync_config_generator(param, self.get_domain_name())
3486 def append_interface(self,mac,bridge=None,network=None):
3488 from karesansui.lib.virt.config import ConfigParam
3489 param = ConfigParam(self.get_domain_name())
3490 dom = self._conn.lookupByName(self.get_domain_name())
3492 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3493 if not os.path.exists(xml_file):
3494 ConfigFile(xml_file).write(dom.XMLDesc(0))
3495 if os.getuid() == 0 and os.path.exists(xml_file):
3496 r_chgrp(xml_file,KARESANSUI_GROUP)
3497 param.load_xml_config(xml_file)
3499 if network is not None:
3500 netinfo = self.connection.search_kvn_networks(network)[0].get_info()
3501 bridge = netinfo['bridge']['name']
3503 if bridge[0:5] == 'xenbr':
3504 script = "vif-bridge"
3508 param.add_interface(mac,"bridge",bridge,script)
3511 from karesansui.lib.virt.config import XMLInterfaceConfigGenerator
3512 generator = XMLInterfaceConfigGenerator()
3513 generator.set_mac(mac)
3514 generator.set_bridge(bridge)
3515 if script is not None:
3516 generator.set_script(script)
3517 cfg = generator.generate(None)
3519 # qemu: cannot attach device on inactive domain
3520 if self.connection.get_hypervisor_type() == "QEMU" and dom.isActive() == 0:
3523 dom.attachDevice(cfg)
3525 xml_generator = XMLConfigGenerator()
3526 cfgxml = xml_generator.generate(param)
3527 self._conn.defineXML(cfgxml)
3532 sync_config_generator(param, self.get_domain_name())
3534 def delete_interface(self,mac,force=False):
3536 status = self.status()
3537 if status == VIR_DOMAIN_PAUSED:
3540 #raise KaresansuiVirtException("Domain %s is suspended." % self.get_domain_name())
3542 from karesansui.lib.virt.config import ConfigParam
3543 param = ConfigParam(self.get_domain_name())
3544 dom = self._conn.lookupByName(self.get_domain_name())
3546 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3547 if not os.path.exists(xml_file):
3548 ConfigFile(xml_file).write(dom.XMLDesc(0))
3549 if os.getuid() == 0 and os.path.exists(xml_file):
3550 r_chgrp(xml_file,KARESANSUI_GROUP)
3551 param.load_xml_config(xml_file)
3553 current_snapshot = param.get_current_snapshot()
3555 param.load_xml_config(dom.XMLDesc(0))
3556 if current_snapshot is not None:
3557 param.set_current_snapshot(current_snapshot)
3560 for info in param.interfaces:
3561 if info["mac"] == mac:
3562 bridge = info['bridge']
3566 param.load_xml_config(dom.XMLDesc(0))
3567 for info in param.interfaces:
3568 if info["mac"] == mac:
3569 bridge = info['bridge']
3572 param.delete_interface(mac)
3575 from karesansui.lib.virt.config import XMLInterfaceConfigGenerator
3576 generator = XMLInterfaceConfigGenerator()
3577 generator.set_mac(mac)
3578 if bridge is not None:
3579 generator.set_bridge(bridge)
3580 cfg = generator.generate(None)
3582 if self.connection.get_hypervisor_type() == "Xen":
3584 dom.detachDevice(cfg)
3588 xml_generator = XMLConfigGenerator()
3589 cfgxml = xml_generator.generate(param)
3590 self._conn.defineXML(cfgxml)
3592 if status == VIR_DOMAIN_PAUSED:
3597 sync_config_generator(param, self.get_domain_name())
3599 def modify_mac_address(self,old,new):
3601 status = self.status()
3602 if status == VIR_DOMAIN_PAUSED:
3605 #raise KaresansuiVirtException("Domain %s is suspended." % self.get_domain_name())
3607 from karesansui.lib.virt.config import ConfigParam
3608 param = ConfigParam(self.get_domain_name())
3609 dom = self._conn.lookupByName(self.get_domain_name())
3611 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3612 if not os.path.exists(xml_file):
3613 ConfigFile(xml_file).write(dom.XMLDesc(0))
3614 if os.getuid() == 0 and os.path.exists(xml_file):
3615 r_chgrp(xml_file,KARESANSUI_GROUP)
3616 param.load_xml_config(xml_file)
3622 for info in param.interfaces:
3623 if info["mac"] == old:
3624 bridge = info['bridge']
3626 new_interfaces.append(info)
3627 param.interfaces = new_interfaces
3632 self.delete_interface(old,True)
3633 self.append_interface(new,bridge)
3635 xml_generator = XMLConfigGenerator()
3636 cfgxml = xml_generator.generate(param)
3637 self._conn.defineXML(cfgxml)
3639 xml_generator = XMLConfigGenerator()
3640 cfgxml = xml_generator.generate(param)
3641 self._conn.defineXML(cfgxml)
3643 if status == VIR_DOMAIN_PAUSED:
3648 sync_config_generator(param, self.get_domain_name())
3650 def set_memory(self,maxmem=None,memory=None):
3652 from karesansui.lib.virt.config import ConfigParam
3653 param = ConfigParam(self.get_domain_name())
3654 dom = self._conn.lookupByName(self.get_domain_name())
3656 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3657 if not os.path.exists(xml_file):
3658 ConfigFile(xml_file).write(dom.XMLDesc(0))
3659 if os.getuid() == 0 and os.path.exists(xml_file):
3660 r_chgrp(xml_file,KARESANSUI_GROUP)
3661 param.load_xml_config(xml_file)
3664 param.set_max_memory(maxmem)
3666 param.set_memory(memory)
3669 dom.setMaxMemory(param.get_max_memory("k"))
3670 dom.setMemory(param.get_memory("k"))
3672 xml_generator = XMLConfigGenerator()
3673 cfgxml = xml_generator.generate(param)
3674 self._conn.defineXML(cfgxml)
3678 sync_config_generator(param, self.get_domain_name())
3680 def set_vcpus(self,max_vcpus=None,vcpus=None):
3682 from karesansui.lib.virt.config import ConfigParam
3683 param = ConfigParam(self.get_domain_name())
3684 dom = self._conn.lookupByName(self.get_domain_name())
3686 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3687 if not os.path.exists(xml_file):
3688 ConfigFile(xml_file).write(dom.XMLDesc(0))
3689 if os.getuid() == 0 and os.path.exists(xml_file):
3690 r_chgrp(xml_file,KARESANSUI_GROUP)
3691 param.load_xml_config(xml_file)
3693 if max_vcpus is not None:
3694 param.set_max_vcpus(int(max_vcpus))
3696 if vcpus is not None:
3697 param.set_vcpus(int(vcpus))
3699 param.set_max_vcpus_limit(int(self.connection.get_max_vcpus()))
3700 param.set_vcpus_limit(int(self.get_vcpus_info()['max_vcpus']))
3703 # qemu: cannot change vcpu count of an active domain
3704 if self.connection.get_hypervisor_type() == "QEMU" and dom.isActive() == 1:
3707 dom.setVcpus(param.get_vcpus())
3709 xml_generator = XMLConfigGenerator()
3710 cfgxml = xml_generator.generate(param)
3711 self._conn.defineXML(cfgxml)
3715 sync_config_generator(param, self.get_domain_name())
3717 def set_vnc(self,port=None,listen=None,passwd=None,keymap=None):
3719 from karesansui.lib.virt.config import ConfigParam
3720 param = ConfigParam(self.get_domain_name())
3721 dom = self._conn.lookupByName(self.get_domain_name())
3723 xml_file = "%s/%s.xml" % (VIRT_XML_CONFIG_DIR, self.get_domain_name())
3724 if not os.path.exists(xml_file):
3725 ConfigFile(xml_file).write(dom.XMLDesc(0))
3726 if os.getuid() == 0 and os.path.exists(xml_file):
3727 r_chgrp(xml_file,KARESANSUI_GROUP)
3728 param.load_xml_config(xml_file)
3730 if port is not None:
3731 param.set_vnc_port(port)
3733 if listen is not None:
3734 param.set_vnc_listen(listen)
3736 if passwd is not None:
3737 param.set_vnc_passwd(passwd)
3739 if keymap is not None:
3740 param.set_vnc_keymap(keymap)
3742 xml_generator = XMLConfigGenerator()
3743 cfgxml = xml_generator.generate(param)
3744 self._conn.defineXML(cfgxml)
3746 sync_config_generator(param, self.get_domain_name())
3748 def is_creatable(self):
3750 ゲストOS(ドメイン)を起動することができるか。
3753 TODO: English Comment
3756 if self.status() == VIR_DOMAIN_SHUTOFF:
3761 def is_shutdownable(self):
3763 ゲストOS(ドメイン)をシャットダウンすることができるか。
3766 TODO: English Comment
3770 status = self.status()
3771 if status == VIR_DOMAIN_RUNNING \
3772 or status == VIR_DOMAIN_BLOCKED \
3773 or status == VIR_DOMAIN_PAUSED:
3778 def is_destroyable(self):
3780 ゲストOS(ドメイン)を強制停止することができるか。
3783 TODO: English Comment
3786 status = self.status()
3787 if status == VIR_DOMAIN_RUNNING \
3788 or status == VIR_DOMAIN_BLOCKED \
3789 or status == VIR_DOMAIN_PAUSED:
3794 def is_suspendable(self):
3796 ゲストOS(ドメイン)の一時停止することができるか。
3799 TODO: English Comment
3802 status = self.status()
3803 if status == VIR_DOMAIN_NOSTATE \
3804 or status ==VIR_DOMAIN_RUNNING \
3805 or status == VIR_DOMAIN_BLOCKED:
3810 def is_resumable(self):
3812 ゲストOS(ドメイン)再開することができるか。
3815 TODO: English Comment
3818 if self.status() == VIR_DOMAIN_PAUSED:
3823 def is_active(self):
3828 TODO: English Comment
3831 return (self.get_domain_name() in self.connection.list_active_guest())
3833 def is_inactive(self):
3838 TODO: English Comment
3841 return (self.get_domain_name() in self.connection.list_inactive_guest())
3843 def is_takable_snapshot(self):
3848 TODO: English Comment
3851 if self.status() == VIR_DOMAIN_SHUTOFF:
3857 class KaresansuiVirtNetwork:
3859 def __init__(self, conn, name=None):
3860 self.connection = conn
3861 self._conn = self.connection._conn
3862 self.set_network_name(name)
3864 def set_network_name(self,name=None):
3865 self.network_name = name
3866 def get_network_name(self):
3867 return self.network_name
3870 param = NetworkConfigParam(self.get_network_name())
3871 param.load_xml_config("%s/%s.xml" % (VIRT_NETWORK_CONFIG_DIR, self.get_network_name()))
3874 net = self._conn.networkLookupByName(self.get_network_name())
3877 except libvirt.libvirtError, e:
3878 raise KaresansuiVirtException(_("Could not start network '%s' (%s)") % (self.network_name, e))
3881 net = self._conn.networkLookupByName(self.get_network_name())
3883 if net.isActive() != 0:
3885 except libvirt.libvirtError, e:
3886 raise KaresansuiVirtException(_("Could not stop network '%s' (%s)") % (self.network_name, e))
3889 net = self._conn.networkLookupByName(self.get_network_name())
3892 def autostart(self, flag=None):
3893 net = self._conn.networkLookupByName(self.get_network_name())
3895 return net.autostart()
3897 return net.setAutostart(flag)
3901 JSON形式でKaresansuiVirtNetwork情報を返却する。
3904 TODO: English Comment
3909 ret['name'] = self.get_network_name()
3910 ret.update(self.get_info())
3915 net = self._conn.networkLookupByName(self.get_network_name())
3916 autostart = net.autostart()
3917 except Exception, e:
3918 raise KaresansuiVirtException("Could not get network: %s"
3921 param = NetworkConfigParam(self.get_network_name())
3922 xml_file = "%s/%s.xml" % (VIRT_NETWORK_CONFIG_DIR, self.get_network_name())
3923 if not os.path.exists(xml_file):
3924 ConfigFile(xml_file).write(net.XMLDesc(0))
3925 if os.getuid() == 0 and os.path.exists(xml_file):
3926 r_chgrp(xml_file,KARESANSUI_GROUP)
3927 param.load_xml_config(xml_file)
3930 name = param.get_network_name()
3931 uuid = param.get_uuid()
3932 bridge_name = param.get_bridge()
3933 bridge_stp = param.get_bridge_stp()
3934 bridge_forwardDelay = param.get_bridge_forwardDelay()
3936 "name" :bridge_name,
3938 "forwardDelay":bridge_forwardDelay,
3941 dhcp_start = param.get_dhcp_start()
3942 dhcp_end = param.get_dhcp_end()
3948 ip_address = param.get_ipaddr()
3949 ip_netmask = param.get_netmask()
3951 "address":ip_address,
3952 "netmask":ip_netmask,
3956 forward_dev = param.get_forward_dev()
3957 forward_mode = param.get_forward_mode()
3959 "mode":forward_mode,
3963 is_active = self.is_active()
3972 "autostart":autostart,
3973 "is_active":is_active,
3976 def get_network_config_param(self):
3977 return NetworkConfigParam(self.get_info())
3979 def is_active(self):
3980 return (self.network_name in self._conn.listNetworks())
3982 def is_inactive(self):
3983 return (self.network_name in self._conn.listDefinedNetworks())
3985 class KaresansuiVirtStorage:
3987 def __init__(self, conn, name=None):
3988 self.connection = conn
3989 self._conn = self.connection._conn
3990 self.set_storage_name(name)
3992 def set_storage_name(self,name=None):
3993 self.storage_name = name
3995 def get_storage_name(self):
3996 return self.storage_name
3998 class KaresansuiVirtStoragePool(KaresansuiVirtStorage):
4001 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4003 return pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
4004 except Exception, e:
4005 raise KaresansuiVirtException("Could not build storage pool: %s"
4008 def create(self, name=None, flags=0):
4009 if name is not None:
4010 self.set_storage_name(name)
4011 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4013 ret = pool.create(flags)
4016 except Exception, e:
4017 raise KaresansuiVirtException("Could not create storage pool: %s"
4020 def start(self, cfgxml, flags, name=None):
4022 self.set_storage_name(name)
4026 ret = self._conn.storagePoolDefineXML(cfgxml, flags) # virStoragePoolDefineXML
4027 #ret = libvirtmod.virStoragePoolCreateXML(self._conn._o,cfgxml, 0)
4028 except libvirt.libvirtError, e:
4029 raise KaresansuiVirtException("Could not start pool '%s' (%s)" \
4030 % (self.get_storage_name, e))
4032 ret2 = self.create()
4036 param = StoragePoolConfigParam(self.get_storage_name())
4037 param.load_xml_config("%s/%s.xml" \
4038 % (VIRT_STORAGE_CONFIG_DIR, self.get_storage_name()))
4042 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4044 return pool.destroy()
4045 except Exception, e:
4046 raise KaresansuiVirtException("Could not destroy storage pool: %s" \
4049 def delete(self, flags):
4050 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4052 return pool.delete(flags)
4053 except Exception, e:
4054 raise KaresansuiVirtException("Could not delete storage pool: %s" \
4057 def autostart(self):
4058 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4059 return pool.autostart()
4061 def is_autostart(self):
4062 ret = self.autostart()
4070 def set_autostart(self, flag=None):
4071 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4072 return pool.setAutostart(flag)
4076 JSON形式でKaresansuiVirtNetwork情報を返却する。
4079 TODO: English Comment
4083 ret['name'] = self.get_storage_name()
4084 ret.update(self.get_info())
4089 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4090 except Exception, e:
4091 raise KaresansuiVirtException("Could not get the storage pool: %s" \
4094 param = StoragePoolConfigParam(self.get_storage_name())
4095 param.load_xml_config(pool.XMLDesc(0))
4096 return {"name" : param.get_storage_name(),
4097 "uuid" : param.get_uuid(),
4098 "type" : param.get_pool_type(),
4099 "allocation" : param.get_allocation(),
4100 "capacity" : param.get_capacity(),
4101 "available" : param.get_available(),
4102 "source" : {"dev_path" : param.get_source_dev_path(),
4103 "dir_path" : param.get_source_dir_path(),
4104 "h_name" : param.get_source_h_name(),
4105 "f_type" : param.get_source_f_type(),
4107 "target" : {"path" : param.get_target_path(),
4108 "p_owner" : param.get_target_permissions_owner(),
4109 "p_group" : param.get_target_permissions_group(),
4110 "p_mode" : param.get_target_permissions_mode(),
4111 "p_label" : param.get_target_permissions_label(),
4112 "e_format" : param.get_target_e_format(),
4113 "e_s_type" : param.get_target_encryption_s_type(),
4114 "e_s_uuid" : param.get_target_encryption_s_uuid(),
4116 "is_active" : self.is_active(),
4117 "is_autostart" : self.is_autostart(),
4120 def is_active(self):
4121 return (self.storage_name in self._conn.listStoragePools())
4123 def is_inactive(self):
4124 return (self.storage_name in self._conn.listdefinedStoragePools())
4126 def vol_createXML(self, xmldesc, flags):
4127 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4129 return pool.createXML(xmldesc, flags)
4130 except Exception, e:
4131 raise KaresansuiVirtException("Could not create storage volume: %s" % str(e))
4133 def vol_numOfVolumes(self):
4134 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4135 return pool.numOfVolumes()
4137 def vol_storageVolLookupByName(self, name):
4138 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4139 return pool.storageVolLookupByName(name)
4141 def vol_listVolumes(self):
4142 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4143 return pool.listVolumes()
4145 def search_kvn_storage_volumes(self, conn):
4147 for vol in self.vol_listVolumes():
4148 vol_obj = KaresansuiVirtStorageVolume(conn)
4149 vol_obj.set_storage_name(self.get_storage_name())
4150 vol_obj.set_storage_volume_name(vol)
4152 vols_obj.append(vol_obj)
4155 class KaresansuiVirtStorageVolume(KaresansuiVirtStorage):
4157 storage_volume_name = None
4159 def set_storage_volume_name(self,name=None):
4160 self.storage_volume_name = name
4162 def get_storage_volume_name(self):
4163 return self.storage_volume_name
4166 param = StorageVolumeConfigParam(self.get_storage_volume_name())
4167 param.load_xml_config("%s/%s.xml" \
4168 % (VIRT_STORAGE_CONFIG_DIR, self.get_storage_volume_name()))
4170 def delete(self, flags):
4171 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4173 vol = pool.storageVolLookupByName(self.get_storage_volume_name())
4174 return vol.delete(flags)
4175 except Exception, e:
4176 raise KaresansuiVirtException("Could not delete storage volume: %s"
4181 JSON形式でKaresansuiVirtNetwork情報を返却する。
4184 TODO: English Comment
4189 #ret['name'] = self.get_network_name()
4190 #ret.update(self.get_info())
4194 pool = self._conn.storagePoolLookupByName(self.get_storage_name())
4196 vol = pool.storageVolLookupByName(self.get_storage_volume_name())
4197 except Exception, e:
4198 raise KaresansuiVirtException("Could not get the storage volume: %s"
4201 param = StorageVolumeConfigParam(self.get_storage_name())
4203 param.load_xml_config(vol.XMLDesc(0))
4204 except libvirt.libvirtError, le:
4206 self.connection.refresh_pools()
4207 param.load_xml_config(vol.XMLDesc(0))
4209 real = param.get_symlink2real()
4210 return {"name" : param.get_storage_name(),
4211 "uuid" : param.get_uuid(),
4212 "key" : param.get_key(),
4213 "allocation" : param.get_allocation(),
4214 "capacity" : param.get_capacity(),
4215 "c_unit" : param.get_c_unit(),
4216 "source" : param.get_source(),
4217 "target" : {"path" : param.get_target_path(),
4218 "f_type" : param.get_target_f_type(),
4219 "p_owner" : param.get_target_permissions_owner(),
4220 "p_group" : param.get_target_permissions_group(),
4221 "p_mode" : param.get_target_permissions_mode(),
4222 "p_label" : param.get_target_permissions_label(),
4223 "b_path" : param.get_backingStore_path(),
4224 "b_format" : param.get_backingStore_format(),
4225 "b_p_owner" : param.get_backingStore_permissions_owner(),
4226 "b_p_group" : param.get_backingStore_permissions_group(),
4227 "b_p_mode" : param.get_backingStore_permissions_mode(),
4228 "b_p_label" : param.get_backingStore_permissions_label(),
4230 "real" : {"dir" : real[0],
4232 "extension" : real[2],
4237 if __name__ == '__main__':
4238 from karesansui.lib.utils import preprint_r
4240 conn = KaresansuiVirtConnection(readonly=False)
4243 #print conn.get_storage_pool_type("default")
4244 #preprint_r(conn.get_capabilities())
4245 #print conn.get_storage_pool_name_bydomain("guest1",image_type='os')
4246 #print conn.get_storage_pool_name_bydomain("guest1",image_type='')
4247 #print conn.get_storage_pool_name_bydomain("centos55",image_type='')
4248 #print conn.get_storage_volume_bypool("default",attr="info")
4249 #print conn.get_storage_volume_bypool("default",attr="name")
4250 #print conn.get_storage_volume_bydomain("centos55",image_type=None, attr="name")
4251 #print conn.get_storage_volume_bydomain("centos55",image_type=None, attr="path")
4252 #print conn.get_storage_volume_bydomain("centos55",image_type="os", attr="info")
4253 #print conn.get_storage_volume_bydomain("centos55",image_type="os", attr="name")
4254 print conn.get_storage_volume_bydomain("centos55",image_type="disk", attr="name")
4255 #print conn.get_storage_pool_name_byimage("/var/opt/hde/libvirt/domains/guest1/images/guest1.img")
4256 #print conn.list_used_vnc_port()
4257 #print conn.list_used_mac_addr()
4259 #kvg = conn.search_kvg_guests("centos55")[0]
4260 #preprint_r(kvg.get_info())
4261 #preprint_r(kvg.get_disk_info())
4262 #conn.import_guest("/var/opt/hde/libvirt/domains/527109d0-cb91-7308-ad39-7738c1893dc9", uuid=None, progresscb=None)
4263 #preprint_r(kvg.get_vcpus_info())
4264 #preprint_r(kvg.get_interface_info())
4265 #preprint_r(kvg.get_graphics_info())
4266 #print kvg.next_disk_target()
4267 #print kvg.delete_interface("52:54:00:0f:cb:6a")
4269 #kvn = conn.search_kvn_networks("default")[0]
4270 #preprint_r(kvn.get_info())
4272 #print conn.get_hypervisor_type()
4273 #print conn.get_hypervisor_type_bydomain("guest1")