def clone(self, domains, name): """perform screenshot on specified domains :param domains: either a label, uuid, id, a virDomain, a dict (to specify flags) or a list of label, uuid, id, virDomain object or a list of dict. :param name: default name value if not specified otherwise :param screen: default screen value if not specified otherwise :returns: False if failed, True if success if domains is a label, an uuid, an id, a virDomain or a tuple if domains is a list. When domain is None, returns None. """ if not name: reason = "'name' field value '{0}' is invalid".format(name) raise DomainManagerError(reason) result = None if isinstance(domains, libvirt.virDomain): try: if domains and not domains.isActive(): orig_xml = domains.XMLDesc(0) orig_dict = xmltodict.parse(orig_xml) # modify configuration clone_dict = orig_dict dom = self.lookup(name) if dom: reason = "domain '{0}' already exists".format(name) raise DomainManagerError(reason) while True: uuid = UUID.generate() if not self.lookup(uuid): break clone_dict['domain']['name'] = name clone_dict['domain']['uuid'] = uuid # change devices for type, dev in clone_dict['domain']['devices'].items(): if type == 'interface': if isinstance(dev, list): interfaces = dev else: interfaces = [dev] for interface in interfaces: interface['mac']['@address'] = MAC.generate() elif type == 'disk': if isinstance(dev, list): disks = dev else: disks = [dev] for disk in disks: disk_path = disk['source']['@file'] volman = StorageVolumeManager(self._drv, None) poolman = StoragePoolManager(self._drv) vol = volman.lookup(disk_path) volman.pool = poolman.lookupByVolume(vol) # TODO: handle case when pool is not defined # have to create one volume = volman.info(disk_path) vol_type = volume.target['format']['@type'] new_name = '.'.join([clone, vol_type]) old_name = orig_dict['domain']['name'] new_vol = volman.clone(old_name, new_name) disk['source']['@file'] = new_vol.path() self.create(clone_dict) except libvirt.libvirtError as e: result = False log.error('{0}'.format(e)) elif isinstance(domains, dict): if 'domain' in domains: domain = domains.get('domain', None) name = domains.get('name', None) result = self.clone(domain, name) elif isinstance(domains, (basestring, int)): result = self.clone(self.lookup(domains), name) elif isinstance(domains, (list, tuple)): result = list() for domain in domains: result.append(self.clone(domain), name) result = tuple(result) return result
def test_mac(self): mac = MAC.generate() self.assertTrue(MAC.validate(mac)) self.assertEqual(len(mac), 17) self.assertEqual(mac.count(":"), 5)
def test_mac_generate(self): mac = MAC.generate(oui=[0x12, 0x34, 0x56]) mac = MAC.normalize(mac) self.assertTrue(MAC.validate(mac)) self.assertTrue(mac.startswith("12:34:56"))
def clone(self, domains, name): """perform screenshot on specified domains :param domains: either a label, uuid, id, a virDomain, a dict (to specify flags) or a list of label, uuid, id, virDomain object or a list of dict. :param name: default name value if not specified otherwise :param screen: default screen value if not specified otherwise :returns: False if failed, True if success if domains is a label, an uuid, an id, a virDomain or a tuple if domains is a list. When domain is None, returns None. """ if not name: reason = "'name' field value '{0}' is invalid".format(name) raise DomainManagerError(reason) result = None if isinstance(domains, libvirt.virDomain): try: if domains and not domains.isActive(): orig_xml = domains.XMLDesc(0) orig_dict = xmltodict.parse(orig_xml) # modify configuration clone_dict = orig_dict dom = self.lookup(name) if dom: reason = "domain '{0}' already exists".format(name) raise DomainManagerError(reason) while True: uuid = UUID.generate() if not self.lookup(uuid): break clone_dict['domain']['name'] = name clone_dict['domain']['uuid'] = uuid # change devices devices = clone_dict['domain']['devices'] for type, dev in list(devices.items()): if type == 'interface': if isinstance(dev, list): interfaces = dev else: interfaces = [dev] for interface in interfaces: interface['mac']['@address'] = MAC.generate() elif type == 'disk': if isinstance(dev, list): disks = dev else: disks = [dev] for disk in disks: disk_path = disk['source']['@file'] volman = StorageVolumeManager(self._drv, None) poolman = StoragePoolManager(self._drv) vol = volman.lookup(disk_path) volman.pool = poolman.lookupByVolume(vol) # TODO: handle case when pool is not defined # have to create one volume = volman.info(disk_path) vol_type = volume.target['format']['@type'] new_name = '.'.join([clone, vol_type]) old_name = orig_dict['domain']['name'] new_vol = volman.clone(old_name, new_name) disk['source']['@file'] = new_vol.path() self.create(clone_dict) except libvirt.libvirtError as e: result = False log.error('{0}'.format(e)) elif isinstance(domains, dict): if 'domain' in domains: domain = domains.get('domain', None) name = domains.get('name', None) result = self.clone(domain, name) elif isinstance(domains, (str, int)): result = self.clone(self.lookup(domains), name) elif isinstance(domains, (list, tuple)): result = list() for domain in domains: result.append(self.clone(domain), name) result = tuple(result) return result
def clone(self, origin, clone, use_backing_file=True): """ Clone a machine :param src_label: source machine name :param dst_label: destination machine name :raise IrmaMachineManagerError: if the machine exists or is currently running """ # TODO: move checking in the lib.virt.core api state, desc = self._domain.state(origin) if state != DomainManager.SHUTOFF: reason = "{0} should be off, {1} instead".format(origin, desc) raise IrmaMachineManagerError(reason) if self._domain.lookup(clone): reason = "clone {0} already exists".format(clone, desc) raise IrmaMachineManagerError(reason) try: orig_dict = self._domain.info(origin) # if we do not want to use backing files, simply clone if not use_backing_file: self._domain.clone(origin, clone) # we want backing files, check for disks else: clone_dict = orig_dict # generate a new uuid while True: uuid = UUID.generate() if not self._domain.lookup(uuid): break # set new name and new uuid clone_dict['name'] = clone clone_dict['uuid'] = uuid # change devices for type, device in clone_dict['devices'].items(): if type == 'interface': interfaces = device if not isinstance(interfaces, list): interfaces = [interfaces] for interface in interfaces: interface['mac']['@address'] = MAC.generate() elif type == 'disk': disks = device if not isinstance(disks, list): disks = [disks] for disk in disks: disk_path = disk['source']['@file'] vman = StorageVolumeManager(self._connection, None) pman = StoragePoolManager(self._connection) volume = vman.lookup(disk_path) vman.pool = pman.lookupByVolume(volume) # TODO: pool is not defined, have to create one volume = vman.info(disk_path) # check if has a backing storage if volume.backingstore is not None: from_disk = orig_dict['name'] disk_ext = volume.target['format']['@type'] to_disk = '.'.join([clone, disk_ext]) new_vol = vman.clone(from_disk, to_disk) disk['source']['@file'] = new_vol.path() # create a backing storage else: backingvol = volume backingvol.key = None # retreive path basedir = backingvol.target['path'] basedir = os.path.dirname(basedir) disk_ext = volume.target['format']['@type'] disk_name = '.'.join([clone, disk_ext]) backingvol.target['path'] = \ os.path.join(basedir, disk_name) backingvol.backingstore = \ {'path': disk_path, 'format': {'@type': disk_ext}} backingvol.name = '.'.join([clone, disk_ext]) new_vol = vman.create(backingvol) disk['source']['@file'] = new_vol.path() self._domain.create(clone_dict) except DomainManagerError as e: raise IrmaMachineManagerError(e)