def test_dhcp_xml(self): """ Test network dhcp xml """ dhcp_range = {'start': '192.168.122.100', 'end': '192.168.122.254'} host1 = { 'mac': '00:16:3e:77:e2:ed', 'name': 'foo.example.com', 'ip': '192.168.122.10', } host2 = { 'mac': '00:16:3e:3e:a9:1a', 'name': 'bar.example.com', 'ip': '192.168.122.11', } params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEqual(None, dhcp) params['range'] = dhcp_range xml = ET.tostring(nxml._get_dhcp_elem(**params)) start = xpath_get_text(xml, '/dhcp/range/@start') end = xpath_get_text(xml, '/dhcp/range/@end') self.assertEqual(dhcp_range['start'], start[0]) self.assertEqual(dhcp_range['end'], end[0]) params['hosts'] = [host1, host2] xml = ET.tostring(nxml._get_dhcp_elem(**params)) ip = xpath_get_text(xml, '/dhcp/host/@ip') self.assertEqual(ip, [host1['ip'], host2['ip']])
def test_ip_xml(self): """ Test network ip xml """ dhcp_range = {'start': '192.168.122.100', 'end': '192.168.122.254'} params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEqual(None, dhcp) params['net'] = '192.168.122.0/255.255.255.0' params['dhcp'] = {'range': dhcp_range} xml = ET.tostring(nxml._get_ip_elem(**params), encoding='unicode') start = xpath_get_text(xml, '/ip/dhcp/range/@start')[0] end = xpath_get_text(xml, '/ip/dhcp/range/@end')[0] self.assertEqual(dhcp_range['start'], start) self.assertEqual(dhcp_range['end'], end) address = xpath_get_text(xml, '/ip/@address')[0] netmask = xpath_get_text(xml, '/ip/@netmask')[0] self.assertEqual(address, params['net'].split('/')[0]) self.assertEqual(netmask, params['net'].split('/')[1]) # test _get_ip_xml can accepts strings: '192.168.122.0/24', # which is same as "192.168.122.0/255.255.255.0" params['net'] = '192.168.122.0/24' xml = ET.tostring(nxml._get_ip_elem(**params), encoding='unicode') netmask = xpath_get_text(xml, '/ip/@netmask')[0] self.assertEqual(netmask, str( ipaddress.IPv4Network(params['net'], False).netmask))
def test_ip_xml(self): """ Test network ip xml """ dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"} params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEquals(None, dhcp) params["net"] = "192.168.122.0/255.255.255.0" params["dhcp"] = {'range': dhcp_range} xml = ET.tostring(nxml._get_ip_elem(**params)) start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0] end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0] self.assertEquals(dhcp_range['start'], start) self.assertEquals(dhcp_range['end'], end) address = xpath_get_text(xml, "/ip/@address")[0] netmask = xpath_get_text(xml, "/ip/@netmask")[0] self.assertEquals(address, params["net"].split("/")[0]) self.assertEquals(netmask, params["net"].split("/")[1]) # test _get_ip_xml can accepts strings: '192.168.122.0/24', # which is same as "192.168.122.0/255.255.255.0" params["net"] = "192.168.122.0/24" xml = ET.tostring(nxml._get_ip_elem(**params)) netmask = xpath_get_text(xml, "/ip/@netmask")[0] self.assertEquals(netmask, str(ipaddr.IPNetwork(params["net"]).netmask))
def test_dhcp_xml(self): """ Test network dhcp xml """ dhcp_range = {'start': '192.168.122.100', 'end': '192.168.122.254'} host1 = { 'mac': '00:16:3e:77:e2:ed', 'name': 'foo.example.com', 'ip': '192.168.122.10', } host2 = { 'mac': '00:16:3e:3e:a9:1a', 'name': 'bar.example.com', 'ip': '192.168.122.11', } params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEqual(None, dhcp) params['range'] = dhcp_range xml = ET.tostring(nxml._get_dhcp_elem(**params), encoding='unicode') start = xpath_get_text(xml, '/dhcp/range/@start') end = xpath_get_text(xml, '/dhcp/range/@end') self.assertEqual(dhcp_range['start'], start[0]) self.assertEqual(dhcp_range['end'], end[0]) params['hosts'] = [host1, host2] xml = ET.tostring(nxml._get_dhcp_elem(**params), encoding='unicode') ip = xpath_get_text(xml, '/dhcp/host/@ip') self.assertEqual(ip, [host1['ip'], host2['ip']])
def test_ip_xml(self): """ Test network ip xml """ dhcp_range = {'start': '192.168.122.100', 'end': '192.168.122.254'} params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEqual(None, dhcp) params['net'] = '192.168.122.0/255.255.255.0' params['dhcp'] = {'range': dhcp_range} xml = ET.tostring(nxml._get_ip_elem(**params)) start = xpath_get_text(xml, '/ip/dhcp/range/@start')[0] end = xpath_get_text(xml, '/ip/dhcp/range/@end')[0] self.assertEqual(dhcp_range['start'], start) self.assertEqual(dhcp_range['end'], end) address = xpath_get_text(xml, '/ip/@address')[0] netmask = xpath_get_text(xml, '/ip/@netmask')[0] self.assertEqual(address, params['net'].split('/')[0]) self.assertEqual(netmask, params['net'].split('/')[1]) # test _get_ip_xml can accepts strings: '192.168.122.0/24', # which is same as "192.168.122.0/255.255.255.0" params['net'] = '192.168.122.0/24' xml = ET.tostring(nxml._get_ip_elem(**params)) netmask = xpath_get_text(xml, '/ip/@netmask')[0] self.assertEqual(netmask, str(ipaddr.IPNetwork(params['net']).netmask))
def test_dhcp_xml(self): """ Test network dhcp xml """ dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"} host1 = { "mac": "00:16:3e:77:e2:ed", "name": "foo.example.com", "ip": "192.168.122.10" } host2 = { "mac": "00:16:3e:3e:a9:1a", "name": "bar.example.com", "ip": "192.168.122.11" } params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEquals(None, dhcp) params["range"] = dhcp_range xml = ET.tostring(nxml._get_dhcp_elem(**params)) start = xpath_get_text(xml, "/dhcp/range/@start") end = xpath_get_text(xml, "/dhcp/range/@end") self.assertEquals(dhcp_range['start'], start[0]) self.assertEquals(dhcp_range['end'], end[0]) params["hosts"] = [host1, host2] xml = ET.tostring(nxml._get_dhcp_elem(**params)) ip = xpath_get_text(xml, "/dhcp/host/@ip") self.assertEquals(ip, [host1['ip'], host2['ip']])
def test_dhcp_xml(self): """ Test network dhcp xml """ dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"} host1 = {"mac": "00:16:3e:77:e2:ed", "name": "foo.example.com", "ip": "192.168.122.10"} host2 = {"mac": "00:16:3e:3e:a9:1a", "name": "bar.example.com", "ip": "192.168.122.11"} params = {} dhcp = nxml._get_dhcp_elem(**params) self.assertEquals(None, dhcp) params["range"] = dhcp_range xml = ET.tostring(nxml._get_dhcp_elem(**params)) start = xpath_get_text(xml, "/dhcp/range/@start") end = xpath_get_text(xml, "/dhcp/range/@end") self.assertEquals(dhcp_range['start'], start[0]) self.assertEquals(dhcp_range['end'], end[0]) params["hosts"] = [host1, host2] xml = ET.tostring(nxml._get_dhcp_elem(**params)) ip = xpath_get_text(xml, "/dhcp/host/@ip") self.assertEquals(ip, [host1['ip'], host2['ip']])
def get_network_from_xml(xml): address = xpath_get_text(xml, "/network/ip/@address") address = address and address[0] or '' netmask = xpath_get_text(xml, "/network/ip/@netmask") netmask = netmask and netmask[0] or '' net = address and netmask and "/".join([address, netmask]) or '' dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start") dhcp_start = dhcp_start and dhcp_start[0] or '' dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end") dhcp_end = dhcp_end and dhcp_end[0] or '' dhcp = {'start': dhcp_start, 'end': dhcp_end} forward_mode = xpath_get_text(xml, "/network/forward/@mode") forward_mode = forward_mode and forward_mode[0] or '' forward_if = xpath_get_text(xml, "/network/forward/interface/@dev") forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev") bridge = xpath_get_text(xml, "/network/bridge/@name") bridge = bridge and bridge[0] or '' return { 'subnet': net, 'dhcp': dhcp, 'bridge': bridge, 'forward': { 'mode': forward_mode, 'interface': forward_if, 'pf': forward_pf } }
def test_to_xml(self): graphics = {'type': 'spice', 'listen': '127.0.0.1'} vm_uuid = str(uuid.uuid4()).replace('-', '') t = VMTemplate({'name': 'test-template', 'cdrom': self.iso}) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('3', xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory" self.assertEquals(str((1024 * 4) << 10), xpath_get_text(xml, expr)[0]) if hasattr(psutil, 'virtual_memory'): host_memory = psutil.virtual_memory().total >> 10 else: host_memory = psutil.TOTAL_PHYMEM >> 10 t = VMTemplate({ 'name': 'test-template', 'cdrom': self.iso, 'memory': (host_memory >> 10) - 512 }) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) expr = "/domain/maxMemory" self.assertEquals(str(host_memory), xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('1', xpath_get_text(xml, expr)[0])
def test_to_xml(self): graphics = {'type': 'spice', 'listen': '127.0.0.1'} vm_uuid = str(uuid.uuid4()).replace('-', '') t = VMTemplate({'name': 'test-template', 'cdrom': self.iso}) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('3', xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory" self.assertEquals(str((1024 * 4) << 10), xpath_get_text(xml, expr)[0]) if hasattr(psutil, 'virtual_memory'): host_memory = psutil.virtual_memory().total >> 10 else: host_memory = psutil.TOTAL_PHYMEM >> 10 t = VMTemplate({'name': 'test-template', 'cdrom': self.iso, 'memory': (host_memory >> 10) - 512}) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) expr = "/domain/maxMemory" self.assertEquals(str(host_memory), xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('1', xpath_get_text(xml, expr)[0])
def lookup(self, name): pool = self.get_storagepool(name, self.conn) info = pool.info() autostart = True if pool.autostart() else False persistent = True if pool.isPersistent() else False xml = pool.XMLDesc(0) path = xpath_get_text(xml, '/pool/target/path')[0] pool_type = xpath_get_text(xml, '/pool/@type')[0] source = self._get_storage_source(pool_type, xml) # FIXME: nfs workaround - prevent any libvirt operation # for a nfs if the corresponding NFS server is down. if pool_type == 'netfs' and not self._nfs_status_online(pool): wok_log.debug( 'NFS pool %s is offline, reason: NFS ' 'server %s is unreachable.', name, source['addr'], ) # Mark state as '4' => inaccessible. info[0] = 4 # skip calculating volumes nr_volumes = 0 else: nr_volumes = self._get_storagepool_vols_num(pool) res = { 'state': POOL_STATE_MAP[info[0]], 'path': path, 'source': source, 'type': pool_type, 'autostart': autostart, 'capacity': info[1], 'allocated': info[2], 'available': info[3], 'nr_volumes': nr_volumes, 'persistent': persistent, 'in_use': self._pool_used_by_template(name), } if not pool.isPersistent(): # Deal with deep scan generated pool try: with self.objstore as session: task_id = session.get('scanning', name) res['task_id'] = str(task_id) res['type'] = 'kimchi-iso' except NotFoundError: # User created normal pool pass return res
def get_network_from_xml(xml): address = xpath_get_text(xml, '/network/ip/@address') address = address and address[0] or '' netmask = xpath_get_text(xml, '/network/ip/@netmask') netmask = netmask and netmask[0] or '' net = address and netmask and '/'.join([address, netmask]) or '' dhcp_start = xpath_get_text(xml, '/network/ip/dhcp/range/@start') dhcp_start = dhcp_start and dhcp_start[0] or '' dhcp_end = xpath_get_text(xml, '/network/ip/dhcp/range/@end') dhcp_end = dhcp_end and dhcp_end[0] or '' dhcp = {'start': dhcp_start, 'end': dhcp_end} forward_mode = xpath_get_text(xml, '/network/forward/@mode') forward_mode = forward_mode and forward_mode[0] or '' forward_if = xpath_get_text(xml, '/network/forward/interface/@dev') forward_pf = xpath_get_text(xml, '/network/forward/pf/@dev') bridge = xpath_get_text(xml, '/network/bridge/@name') bridge = bridge and bridge[0] or '' return { 'subnet': net, 'dhcp': dhcp, 'bridge': bridge, 'forward': { 'mode': forward_mode, 'interface': forward_if, 'pf': forward_pf, }, }
def get_network_from_xml(xml): address = xpath_get_text(xml, "/network/ip/@address") address = address and address[0] or "" netmask = xpath_get_text(xml, "/network/ip/@netmask") netmask = netmask and netmask[0] or "" net = address and netmask and "/".join([address, netmask]) or "" dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start") dhcp_start = dhcp_start and dhcp_start[0] or "" dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end") dhcp_end = dhcp_end and dhcp_end[0] or "" dhcp = {"start": dhcp_start, "end": dhcp_end} forward_mode = xpath_get_text(xml, "/network/forward/@mode") forward_mode = forward_mode and forward_mode[0] or "" forward_if = xpath_get_text(xml, "/network/forward/interface/@dev") forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev") bridge = xpath_get_text(xml, "/network/bridge/@name") bridge = bridge and bridge[0] or "" return { "subnet": net, "dhcp": dhcp, "bridge": bridge, "forward": {"mode": forward_mode, "interface": forward_if, "pf": forward_pf}, }
def _get_vms_attach_to_storagepool(self, storagepool): conn = self.conn.get() # get storage pool path pool = self.get_storagepool(storagepool, self.conn) path = "".join(xpath_get_text(pool.XMLDesc(), "/pool/target/path")) # activate and deactive quickly to get volumes vms = [] for dom in conn.listAllDomains(0): xml = dom.XMLDesc(0) files = "/domain/devices/disk[@device='disk']/source/@file" for file in xpath_get_text(xml, files): if file not in vms and file.startswith(path): vms.append(dom.name()) return vms
def deactivate(self, name): if self._pool_used_by_template(name): raise InvalidOperation('KCHPOOL0034E', {'name': name}) pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not try to deactivate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type == 'netfs' and not self._nfs_status_online(pool): # block the user from dactivating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed("KCHPOOL0033E", {'name': name, 'server': source['addr']}) return try: persistent = pool.isPersistent() pool.destroy() except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0010E", {'name': name, 'err': e.get_error_message()}) # If pool was not persistent, then it was erased by destroy() and # must return nothing here, to trigger _redirect() and avoid errors if not persistent: return ""
def test_forward_xml(self): """ Test network forward xml """ params = {'mode': None} forward = nxml._get_forward_elem(**params) self.assertEqual(None, forward) params['mode'] = 'nat' params['dev'] = 'eth0' xml = ET.tostring(nxml._get_forward_elem(**params)) mode = xpath_get_text(xml, '/forward/@mode')[0] dev = xpath_get_text(xml, '/forward/@dev')[0] self.assertEqual(params['mode'], mode) self.assertEqual(params['dev'], dev)
def test_forward_xml(self): """ Test network forward xml """ params = {"mode": None} forward = nxml._get_forward_elem(**params) self.assertEquals(None, forward) params["mode"] = 'nat' params["dev"] = 'eth0' xml = ET.tostring(nxml._get_forward_elem(**params)) mode = xpath_get_text(xml, "/forward/@mode")[0] dev = xpath_get_text(xml, "/forward/@dev")[0] self.assertEquals(params['mode'], mode) self.assertEquals(params['dev'], dev)
def test_forward_xml(self): """ Test network forward xml """ params = {'mode': None} forward = nxml._get_forward_elem(**params) self.assertEqual(None, forward) params['mode'] = 'nat' params['dev'] = 'eth0' xml = ET.tostring(nxml._get_forward_elem(**params), encoding='unicode') mode = xpath_get_text(xml, '/forward/@mode')[0] dev = xpath_get_text(xml, '/forward/@dev')[0] self.assertEqual(params['mode'], mode) self.assertEqual(params['dev'], dev)
def deactivate(self, name): if self._pool_used_by_template(name): raise InvalidOperation('KCHPOOL0034E', {'name': name}) pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not try to deactivate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type == 'netfs' and not self._nfs_status_online(pool): # block the user from dactivating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed("KCHPOOL0033E", { 'name': name, 'server': source['addr'] }) return try: persistent = pool.isPersistent() pool.destroy() except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0010E", { 'name': name, 'err': e.get_error_message() }) # If pool was not persistent, then it was erased by destroy() and # must return nothing here, to trigger _redirect() and avoid errors if not persistent: return ""
def _get_ipaddr_info(libvirt_interface_xml): search_ip = \ xpath_get_text(libvirt_interface_xml, "/interface/protocol[@family='ipv4']" "/ip/@address") if not len(search_ip): return '', '' search_prefix = \ xpath_get_text(libvirt_interface_xml, "/interface/protocol[@family='ipv4']" "/ip/@prefix") ip_obj = ipaddr.IPv4Network('%s/%s' % (search_ip[0], search_prefix[0])) return str(ip_obj.ip), str(ip_obj.netmask)
def test_mem_dev_slots(self): vm_uuid = str(uuid.uuid4()).replace('-', '') t = VMTemplate({'name': 'test-template', 'cdrom': self.iso, 'memory': {'current': 2048, 'maxmemory': 3072}}) xml = t.to_vm_xml('test-vm', vm_uuid) expr = "/domain/maxMemory/@slots" slots = str(MEM_DEV_SLOTS[os.uname()[4]]) self.assertEquals(slots, xpath_get_text(xml, expr)[0])
def _get_storage_type(self, pool_uri=None): try: pool = self._get_storage_pool(pool_uri) except: return '' xml = pool.XMLDesc(0) return xpath_get_text(xml, "/pool/@type")[0]
def test_to_xml(self): graphics = {'type': 'spice', 'listen': '127.0.0.1'} vm_uuid = str(uuid.uuid4()).replace('-', '') if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']: maxmem = 3328 else: maxmem = 3072 t = VMTemplate({'name': 'test-template', 'cdrom': self.iso, 'max_memory': maxmem << 10}) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('2', xpath_get_text(xml, expr)[0])
def _get_storage_path(self, pool_uri=None): try: pool = self._get_storage_pool(pool_uri) except Exception: return '' xml = pool.XMLDesc(0) return xpath_get_text(xml, '/pool/target/path')[0]
def lookup(self, name): pool = self.get_storagepool(name, self.conn) info = pool.info() autostart = True if pool.autostart() else False persistent = True if pool.isPersistent() else False xml = pool.XMLDesc(0) path = xpath_get_text(xml, "/pool/target/path")[0] pool_type = xpath_get_text(xml, "/pool/@type")[0] source = self._get_storage_source(pool_type, xml) # FIXME: nfs workaround - prevent any libvirt operation # for a nfs if the corresponding NFS server is down. if pool_type == "netfs" and not self._nfs_status_online(pool): wok_log.debug("NFS pool %s is offline, reason: NFS " "server %s is unreachable.", name, source["addr"]) # Mark state as '4' => inaccessible. info[0] = 4 # skip calculating volumes nr_volumes = 0 else: nr_volumes = self._get_storagepool_vols_num(pool) res = { "state": POOL_STATE_MAP[info[0]], "path": path, "source": source, "type": pool_type, "autostart": autostart, "capacity": info[1], "allocated": info[2], "available": info[3], "nr_volumes": nr_volumes, "persistent": persistent, } if not pool.isPersistent(): # Deal with deep scan generated pool try: with self.objstore as session: task_id = session.get("scanning", name) res["task_id"] = str(task_id) res["type"] = "kimchi-iso" except NotFoundError: # User created normal pool pass return res
def revert(self, vm_name, name): try: vir_dom = VMModel.get_vm(vm_name, self.conn) vir_snap = self.get_vmsnapshot(vm_name, name) vir_dom.revertToSnapshot(vir_snap, 0) # get vm name recorded in the snapshot and return new uri params vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0), "domain/name")[0] return [vm_new_name, name] except libvirt.libvirtError, e: raise OperationFailed("KCHSNAP0009E", {"name": name, "vm": vm_name, "err": e.message})
def test_to_xml(self): graphics = {'type': 'spice', 'listen': '127.0.0.1'} vm_uuid = str(uuid.uuid4()).replace('-', '') if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']: maxmem = 3328 else: maxmem = 3072 t = VMTemplate({ 'name': 'test-template', 'cdrom': self.iso, 'max_memory': maxmem << 10 }) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" self.assertEquals('2', xpath_get_text(xml, expr)[0])
def test_to_xml(self): graphics = {"type": "spice", "listen": "127.0.0.1"} vm_uuid = str(uuid.uuid4()).replace("-", "") t = VMTemplate({"name": "test-template", "cdrom": self.iso}) xml = t.to_vm_xml("test-vm", vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals("test-vm", xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics["type"], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics["listen"], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" # The default is memory and maxmemory have the same value, so # max memory tag is not set self.assertEquals(0, len(xpath_get_text(xml, expr))) expr = "/domain/memory" self.assertEquals(str(1024), xpath_get_text(xml, expr)[0]) if hasattr(psutil, "virtual_memory"): host_memory = psutil.virtual_memory().total >> 10 else: host_memory = psutil.TOTAL_PHYMEM >> 10 t = VMTemplate({"name": "test-template", "cdrom": self.iso, "memory": {"current": (host_memory >> 10) - 512}}) try: xml = t.to_vm_xml("test-vm", vm_uuid, graphics=graphics) except Exception as e: # Test current memory greater than maxmemory (1024/default) self.assertTrue("KCHVM0041E" in e.message)
def test_to_xml(self): graphics = {'type': 'spice', 'listen': '127.0.0.1'} vm_uuid = str(uuid.uuid4()).replace('-', '') t = VMTemplate({'name': 'test-template', 'cdrom': self.iso}) xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0]) self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0]) expr = "/domain/devices/graphics/@type" self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0]) expr = "/domain/devices/graphics/@listen" self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0]) expr = "/domain/maxMemory/@slots" # The default is memory and maxmemory have the same value, so # max memory tag is not set self.assertEquals(0, len(xpath_get_text(xml, expr))) expr = "/domain/memory" self.assertEquals(str(1024), xpath_get_text(xml, expr)[0]) if hasattr(psutil, 'virtual_memory'): host_memory = psutil.virtual_memory().total >> 10 else: host_memory = psutil.TOTAL_PHYMEM >> 10 t = VMTemplate({'name': 'test-template', 'cdrom': self.iso, 'memory': {'current': (host_memory >> 10) - 512}}) try: xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics) except Exception as e: # Test current memory greater than maxmemory (1024/default) self.assertTrue('KCHVM0041E' in e.message)
def _get_storage_source(self, pool_type, pool_xml): source = {} if pool_type not in STORAGE_SOURCES: return source for key, val in STORAGE_SOURCES[pool_type].items(): res = xpath_get_text(pool_xml, val) if len(res) == 1: source[key] = res[0] elif len(res) == 0: source[key] = "" else: source[key] = res return source
def revert(self, vm_name, name): try: vir_dom = VMModel.get_vm(vm_name, self.conn) vir_snap = self.get_vmsnapshot(vm_name, name) vir_dom.revertToSnapshot(vir_snap, 0) # get vm name recorded in the snapshot and return new uri params vm_new_name = xpath_get_text( vir_snap.getXMLDesc(0), 'domain/name')[0] return [vm_new_name, name] except libvirt.libvirtError as e: raise OperationFailed( 'KCHSNAP0009E', {'name': name, 'vm': vm_name, 'err': str(e)} )
def activate(self, name): pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not activate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type == "netfs" and not self._nfs_status_online(pool): # block the user from activating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed("KCHPOOL0032E", {"name": name, "server": source["addr"]}) return try: pool.create(0) except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0009E", {"name": name, "err": e.get_error_message()})
def revert(self, vm_name, name): try: vir_dom = VMModel.get_vm(vm_name, self.conn) vir_snap = self.get_vmsnapshot(vm_name, name) vir_dom.revertToSnapshot(vir_snap, 0) # get vm name recorded in the snapshot and return new uri params vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0), 'domain/name')[0] return [vm_new_name, name] except libvirt.libvirtError as e: raise OperationFailed('KCHSNAP0009E', { 'name': name, 'vm': vm_name, 'err': str(e) })
def _nfs_status_online(self, pool, poolArgs=None): if not poolArgs: xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] source = self._get_storage_source(pool_type, xml) poolArgs = {} poolArgs["name"] = pool.name() poolArgs["type"] = pool_type poolArgs["source"] = {"path": source["path"], "host": source["addr"]} conn = self.conn.get() poolDef = StoragePoolDef.create(poolArgs) try: poolDef.prepare(conn) return True except Exception: return False
def lookup(self, name): # import pdb # pdb.set_trace() network = self.get_network(self.conn.get(), name) xml = network.XMLDesc(0) net_dict = self.get_network_from_xml(xml) subnet = net_dict['subnet'] dhcp = net_dict['dhcp'] forward = net_dict['forward'] interface = net_dict['bridge'] connection = forward['mode'] or "isolated" # FIXME, if we want to support other forward mode well. if connection == 'bridge': # macvtap bridge interface = interface or forward['interface'][0] if netinfo.is_nic(interface) or netinfo.is_bonding(interface): connection = 'macvtap' # exposing the network on linux bridge or macvtap interface interface_subnet = knetwork.get_dev_netaddr(interface) subnet = subnet if subnet else interface_subnet # libvirt use format 192.168.0.1/24, standard should be 192.168.0.0/24 # http://www.ovirt.org/File:Issue3.png if subnet: subnet = ipaddr.IPNetwork(subnet) subnet = "%s/%s" % (subnet.network, subnet.prefixlen) if connection in ['passthrough', 'vepa']: interfaces = xpath_get_text( xml, "/network/forward/interface/@dev" ) else: interfaces = [interface] return {'connection': connection, 'interfaces': interfaces, 'subnet': subnet, 'dhcp': dhcp, 'vms': self._get_vms_attach_to_a_network(name), 'in_use': self._is_network_in_use(name), 'autostart': network.autostart() == 1, 'state': network.isActive() and "active" or "inactive", 'persistent': True if network.isPersistent() else False}
def update(self, name, params): pool = self.get_storagepool(name, self.conn) if "autostart" in params: if params["autostart"]: pool.setAutostart(1) else: pool.setAutostart(0) if "disks" in params: # check if pool is type 'logical' xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type != "logical": raise InvalidOperation("KCHPOOL0029E") self._update_lvm_disks(name, params["disks"]) ident = pool.name() return ident.decode("utf-8")
def _nfs_status_online(self, pool, poolArgs=None): if not poolArgs: xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] source = self._get_storage_source(pool_type, xml) poolArgs = {} poolArgs['name'] = pool.name() poolArgs['type'] = pool_type poolArgs['source'] = {'path': source['path'], 'host': source['addr']} conn = self.conn.get() poolDef = StoragePoolDef.create(poolArgs) try: poolDef.prepare(conn) return True except Exception: return False
def activate(self, name): pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not activate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type == 'netfs' and not self._nfs_status_online(pool): # block the user from activating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed("KCHPOOL0032E", {'name': name, 'server': source['addr']}) return try: pool.create(0) except libvirt.libvirtError as e: raise OperationFailed("KCHPOOL0009E", {'name': name, 'err': e.get_error_message()})
def update(self, name, params): pool = self.get_storagepool(name, self.conn) if 'autostart' in params: if params['autostart']: pool.setAutostart(1) else: pool.setAutostart(0) if 'disks' in params: # check if pool is type 'logical' xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, "/pool/@type")[0] if pool_type != 'logical': raise InvalidOperation('KCHPOOL0029E') self._update_lvm_disks(name, params['disks']) ident = pool.name() return ident.decode('utf-8')
def _get_devices_fc_host(self): conn = self.conn.get() # Libvirt < 1.0.5 does not support fc_host capability if not self.caps.fc_host_support: ret = [] scsi_hosts = self._get_devices_with_capability('scsi_host') for host in scsi_hosts: xml = conn.nodeDeviceLookupByName(host).XMLDesc(0) path = '/device/capability/capability/@type' if 'fc_host' in xpath_get_text(xml, path): ret.append(host) return ret # Double verification to catch the case where the libvirt # supports fc_host but does not, for some reason, recognize # the libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST # attribute. if not self.cap_map['fc_host']: return conn.listDevices('fc_host', 0) return self._get_devices_with_capability('fc_host')
def upgrade_objectstore_template_disks(libv_conn): """ Upgrade the value of a given JSON's item of all Templates. Removes 'storagepool' entry and adds 'pool: { name: ..., type: ... }' """ total = 0 try: conn = sqlite3.connect(config.get_object_store(), timeout=10) cursor = conn.cursor() sql = "SELECT id, json FROM objects WHERE type='template'" cursor.execute(sql) for row in cursor.fetchall(): template = json.loads(row[1]) # Get pool info pool_uri = template['storagepool'] pool_name = pool_name_from_uri(pool_uri) pool = libv_conn.get().storagePoolLookupByName( pool_name.encode('utf-8')) pool_type = xpath_get_text(pool.XMLDesc(0), '/pool/@type')[0] # Update json new_disks = [] for disk in template['disks']: disk['pool'] = {'name': pool_uri, 'type': pool_type} new_disks.append(disk) template['disks'] = new_disks del template['storagepool'] sql = 'UPDATE objects SET json=? WHERE id=?' cursor.execute(sql, (json.dumps(template), row[0])) conn.commit() total += 1 except sqlite3.Error as e: if conn: conn.rollback() wok_log.error('Error while upgrading objectstore data: %s', e.args[0]) raise OperationFailed('KCHUTILS0006E') finally: if conn: conn.close() wok_log.info("%d 'template' entries upgraded in objectstore.", total)
def activate(self, name): pool = self.get_storagepool(name, self.conn) # FIXME: nfs workaround - do not activate a NFS pool # if the NFS server is not reachable. xml = pool.XMLDesc(0) pool_type = xpath_get_text(xml, '/pool/@type')[0] if pool_type == 'netfs' and not self._nfs_status_online(pool): # block the user from activating the pool. source = self._get_storage_source(pool_type, xml) raise OperationFailed( 'KCHPOOL0032E', {'name': name, 'server': source['addr']} ) try: pool.create(0) except libvirt.libvirtError as e: raise OperationFailed( 'KCHPOOL0009E', {'name': name, 'err': e.get_error_message()} )
def template_volume_validate(self, tmp_volumes, pool): kwargs = {'conn': self.conn, 'objstore': self.objstore} pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0] pool_name = unicode(pool.name(), 'utf-8') # as we discussion, we do not mix disks from 2 different types of # storage pools, for instance: we do not create a template with 2 # disks, where one comes from a SCSI pool and other is a .img in # a DIR pool. if pool_type in ['iscsi', 'scsi']: if not tmp_volumes: raise InvalidParameter("KCHTMPL0018E") storagevolumes = __import__("kimchi.model.storagevolumes", fromlist=['']) pool_volumes = storagevolumes.StorageVolumesModel( **kwargs).get_list(pool_name) vols = set(tmp_volumes) - set(pool_volumes) if vols: raise InvalidParameter("KCHTMPL0019E", { 'pool': pool_name, 'volume': vols })
def _get_storage_type(self): pool = self._storage_validate() xml = pool.XMLDesc(0) return xpath_get_text(xml, "/pool/@type")[0]
def test_network_xml(self): """ Test network xml """ params = { "name": "test", "forward": { "mode": "nat", "dev": "" }, "net": "192.168.0.0/255.255.255.0" } xml = nxml.to_network_xml(**params) name = xpath_get_text(xml, "/network/name")[0] self.assertEquals(name, params['name']) forward_mode = xpath_get_text(xml, "/network/forward/@mode")[0] self.assertEquals(forward_mode, params['forward']['mode']) forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0] self.assertEquals(forward_dev, '') address = xpath_get_text(xml, "/network/ip/@address")[0] self.assertEquals(address, params["net"].split("/")[0]) netmask = xpath_get_text(xml, "/network/ip/@netmask")[0] self.assertEquals(netmask, params["net"].split("/")[1]) dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start") self.assertEquals(dhcp_start, []) dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end") self.assertEquals(dhcp_end, []) # test optional params params['forward']['dev'] = "eth0" params['dhcp'] = { "range": { 'start': '192.168.0.1', 'end': '192.168.0.254' } } xml = nxml.to_network_xml(**params) forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0] self.assertEquals(forward_dev, params['forward']['dev']) dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")[0] self.assertEquals(dhcp_start, params['dhcp']['range']['start']) dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")[0] self.assertEquals(dhcp_end, params['dhcp']['range']['end']) # test _get_ip_xml can accepts strings: '192.168.122.0/24', # which is same as "192.168.122.0/255.255.255.0" params["net"] = "192.168.0.0/24" xml = nxml.to_network_xml(**params) netmask = xpath_get_text(xml, "/network/ip/@netmask")[0] self.assertEquals(netmask, str(ipaddr.IPNetwork(params["net"]).netmask))
def _vm_get_networks(self, dom): xml = dom.XMLDesc(0) xpath = "/domain/devices/interface[@type='network']/source/@network" return xpath_get_text(xml, xpath)
def lookup(self, pool, name): vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn) path = vol.path() info = vol.info() xml = vol.XMLDesc(0) try: fmt = xpath_get_text(xml, "/volume/target/format/@type")[0] except IndexError: # Not all types of libvirt storage can provide volume format # infomation. When there is no format information, we assume # it's 'raw'. fmt = 'raw' iso_img = None # 'raw' volumes from 'logical' pools may actually be 'iso'; # libvirt always reports them as 'raw' pool_info = self.storagepool.lookup(pool) if pool_info['type'] == 'logical' and fmt == 'raw': try: iso_img = IsoImage(path) except IsoFormatError: # not 'iso' afterall pass else: fmt = 'iso' # 'raw' volumes can not be valid image disks (e.g. XML, PDF, TXT are # raw files), so it's necessary check the 'content' of them isvalid = True if fmt == 'raw': try: ms = magic.open(magic.NONE) ms.load() if ms.file(path).lower() not in VALID_RAW_CONTENT: isvalid = False ms.close() except UnicodeDecodeError: isvalid = False used_by = get_disk_used_by(self.objstore, self.conn, path) res = dict(type=VOLUME_TYPE_MAP[info[0]], capacity=info[1], allocation=info[2], path=path, used_by=used_by, format=fmt, isvalid=isvalid) if fmt == 'iso': if os.path.islink(path): path = os.path.join(os.path.dirname(path), os.readlink(path)) os_distro = os_version = 'unknown' try: if iso_img is None: iso_img = IsoImage(path) os_distro, os_version = iso_img.probe() bootable = True except IsoFormatError: bootable = False res.update( dict(os_distro=os_distro, os_version=os_version, path=path, bootable=bootable)) return res