Esempio n. 1
0
    def _libvirt_xml(self):
        net_raw_xml = libvirt_utils.get_template('net_br_template.xml')

        replacements = {
            '@NAME@': self._libvirt_name(),
            '@BR_NAME@': self._libvirt_name(),
        }
        for k, v in replacements.items():
            net_raw_xml = net_raw_xml.replace(k, v, 1)

        return net_raw_xml
Esempio n. 2
0
File: vm.py Progetto: almusil/lago
    def _create_live_snapshot(self, name):
        with LogTask(
            'Creating live snapshot named %s for %s' % (name, self.vm.name()),
            level='debug',
        ):

            self.vm.wait_for_ssh()
            self.vm.guest_agent().start()
            self.vm.ssh('sync'.split(' '))

            dom = self.libvirt_con.lookupByName(self._libvirt_name())
            dom_xml = ET.fromstring(dom.XMLDesc())
            disks = dom_xml.xpath('devices/disk')

            snapshot_xml = ET.fromstring(
                libvirt_utils.get_template('snapshot_template.xml')
            )
            snapshot_disks = snapshot_xml.xpath('disks')[0]

            for disk in disks:
                target_dev = disk.xpath('target')[0].attrib['dev']
                snapshot_disks.append(ET.Element('disk', name=target_dev))

            try:
                dom.snapshotCreateXML(
                    ET.tostring(snapshot_xml),
                    libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
                    | libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE,
                )
            except libvirt.libvirtError:
                LOGGER.exception(
                    'Failed to create snapshot %s for %s',
                    name,
                    self.vm.name(),
                )
                raise

            snap_info = []
            new_disks = ET.fromstring(dom.XMLDesc()).xpath('devices/disk')
            for disk, xml_node in zip(self.vm._spec['disks'], new_disks):
                disk['path'] = xml_node.xpath('source')[0].attrib['file']
                disk['format'] = 'qcow2'
                snap_disk = disk.copy()
                snap_disk['path'] = xml_node.xpath(
                    'backingStore',
                )[0].xpath(
                    'source',
                )[0].attrib['file']
                snap_info.append(snap_disk)

            self._reclaim_disks()
            self.vm._spec['snapshots'][name] = snap_info
Esempio n. 3
0
    def _libvirt_xml(self):
        net_raw_xml = libvirt_utils.get_template('net_nat_template.xml')

        subnet = self.gw().split('.')[2]
        ipv6_prefix = self._ipv6_prefix(subnet=subnet)
        mtu = self.mtu()

        replacements = {
            '@NAME@': self._libvirt_name(),
            '@BR_NAME@': ('%s-nic' % self._libvirt_name())[:12],
            '@GW_ADDR@': self.gw(),
            '@SUBNET@': subnet
        }
        for k, v in replacements.items():
            net_raw_xml = net_raw_xml.replace(k, v, 1)

        parser = ET.XMLParser(remove_blank_text=True)
        net_xml = ET.fromstring(net_raw_xml, parser)

        if mtu != '1500':
            net_xml.append(ET.Element(
                'mtu',
                size=str(mtu),
            ))
        if 'dhcp' in self._spec:
            ipv4 = net_xml.xpath('/network/ip')[0]
            ipv6 = net_xml.xpath('/network/ip')[1]

            def make_ipv4(last):
                return '.'.join(self.gw().split('.')[:-1] + [str(last)])

            dhcp = ET.Element('dhcp')
            dhcpv6 = ET.Element('dhcp')
            ipv4.append(dhcp)
            ipv6.append(dhcpv6)

            dhcp.append(
                ET.Element(
                    'range',
                    start=make_ipv4(self._spec['dhcp']['start']),
                    end=make_ipv4(self._spec['dhcp']['end']),
                ))
            dhcpv6.append(
                ET.Element(
                    'range',
                    start=ipv6_prefix + make_ipv4(self._spec['dhcp']['start']),
                    end=ipv6_prefix + make_ipv4(self._spec['dhcp']['end']),
                ))

            for hostname, ip4 in self._spec['mapping'].items():
                dhcp.append(
                    ET.Element('host',
                               mac=utils.ipv4_to_mac(ip4),
                               ip=ip4,
                               name=hostname))
                dhcpv6.append(
                    ET.Element('host',
                               id='0:3:0:1:' + utils.ipv4_to_mac(ip4),
                               ip=ipv6_prefix + ip4,
                               name=hostname))

        if utils.ver_cmp(self.compat, '0.36.11') >= 0:
            if self.is_management():
                domain_xml = ET.Element('domain',
                                        name=self._spec['dns_domain_name'],
                                        localOnly='yes')
                net_xml.append(domain_xml)
                net_xml.append(
                    self._generate_main_dns(self._spec['dns_records'], subnet))
            else:
                if self.libvirt_con.getLibVersion() < 2002000:
                    net_xml.append(
                        self._generate_dns_forward(self._spec['dns_forward']))
                else:
                    net_xml.append(self._generate_dns_disable())
        else:
            LOGGER.debug(
                'Generating network XML with compatibility prior to %s',
                self.compat)
            # Prior to v0.37, DNS records were only the  mappings of the
            # management network.
            if self.is_management():
                if 'dns_domain_name' in self._spec:
                    domain_xml = ET.Element('domain',
                                            name=self._spec['dns_domain_name'],
                                            localOnly='yes')
                    net_xml.append(domain_xml)

                net_xml.append(
                    self._generate_main_dns(self._spec['mapping'],
                                            subnet,
                                            forward_plain='yes'))
            else:
                dns = ET.Element('dns', forwardPlainNames='yes', enable='yes')
                net_xml.append(dns)

        LOGGER.debug('Generated Network XML\n {0}'.format(
            ET.tostring(net_xml, pretty_print=True)))
        return ET.tostring(net_xml)
Esempio n. 4
0
 def _load_domain_xml(self):
     if self.vm.distro() == 'el6':
         dom_raw_xml = libvirt_utils.get_template('dom_template-el6.xml')
     else:
         dom_raw_xml = libvirt_utils.get_template('dom_template.xml')
     return dom_raw_xml
Esempio n. 5
0
File: vm.py Progetto: gbenhaim/lago
    def _libvirt_xml(self):
        dom_raw_xml = libvirt_utils.get_template('dom_template.xml')

        qemu_kvm_path = self._caps.findtext(
            "guest[os_type='hvm']/arch[@name='x86_64']/domain[@type='kvm']"
            "/emulator")

        if not qemu_kvm_path:
            LOGGER.warning("hardware acceleration not available")
            qemu_kvm_path = self._caps.findtext(
                "guest[os_type='hvm']/arch[@name='x86_64']"
                "/domain[@type='qemu']/../emulator")

        if not qemu_kvm_path:
            raise Exception('kvm executable not found')

        replacements = {
            '@NAME@': self._libvirt_name(),
            '@MEM_SIZE@': self.vm._spec.get('memory', 16 * 1024),
            '@QEMU_KVM@': qemu_kvm_path,
        }

        for key, val in replacements.items():
            dom_raw_xml = dom_raw_xml.replace(key, str(val), 1)

        dom_xml = ET.fromstring(dom_raw_xml)

        for child in self._cpu:
            dom_xml.append(child)

        devices = dom_xml.xpath('/domain/devices')[0]

        disk = devices.xpath('disk')[0]
        devices.remove(disk)

        scsi_con_exists = False
        for disk_order, dev_spec in enumerate(self.vm._spec['disks']):

            # we have to make some adjustments
            # we use iso to indicate cdrom
            # but libvirt wants it named raw
            # and we need to use cdrom device
            disk_device = 'disk'
            bus = 'virtio'
            if dev_spec['format'] == 'iso':
                disk_device = 'cdrom'
                dev_spec['format'] = 'raw'
                bus = 'ide'
            # names converted

            # support virtio-scsi - sdX devices
            if dev_spec['dev'].startswith('sd'):
                bus = 'scsi'
                if not scsi_con_exists:
                    controller = ET.Element(
                        'controller',
                        type='scsi',
                        index='0',
                        model='virtio-scsi',
                    )
                    driver = ET.Element(
                        'driver',
                        queues='{}'.format(self.vm._spec.get('vcpu', 2)),
                    )
                    controller.append(driver)
                    devices.append(controller)
                    scsi_con_exists = True

            disk = ET.Element(
                'disk',
                type='file',
                device=disk_device,
            )

            disk.append(
                ET.Element(
                    'driver',
                    name='qemu',
                    type=dev_spec['format'],
                    discard='unmap',
                ), )

            serial = ET.SubElement(disk, 'serial')
            serial.text = "{}".format(disk_order + 1)
            disk.append(serial)

            disk.append(ET.Element('boot',
                                   order="{}".format(disk_order + 1)), )

            disk.append(
                ET.Element(
                    'source',
                    file=os.path.expandvars(dev_spec['path']),
                ), )
            disk.append(ET.Element(
                'target',
                dev=dev_spec['dev'],
                bus=bus,
            ), )
            devices.append(disk)

        for dev_spec in self.vm._spec['nics']:
            interface = ET.Element(
                'interface',
                type='network',
            )
            interface.append(
                ET.Element(
                    'source',
                    network=self.vm.virt_env.prefixed_name(dev_spec['net'],
                                                           max_length=15),
                ), )
            interface.append(ET.Element(
                'model',
                type='virtio',
            ), )
            if 'ip' in dev_spec:
                interface.append(
                    ET.Element('mac',
                               address=utils.ipv4_to_mac(dev_spec['ip'])), )
            devices.append(interface)

        return ET.tostring(dom_xml, pretty_print=True)
Esempio n. 6
0
    def _libvirt_xml(self):
        net_raw_xml = libvirt_utils.get_template('net_nat_template.xml')

        subnet = self.gw().split('.')[2]
        replacements = {
            '@NAME@': self._libvirt_name(),
            '@BR_NAME@': ('%s-nic' % self._libvirt_name())[:12],
            '@GW_ADDR@': self.gw(),
            '@SUBNET@': subnet,
            '@ENABLE_DNS@':
            'yes' if self._spec.get('enable_dns', True) else 'no',
        }
        for k, v in replacements.items():
            net_raw_xml = net_raw_xml.replace(k, v, 1)

        net_xml = ET.fromstring(net_raw_xml)
        dns_domain_name = self._spec.get('dns_domain_name', None)
        if dns_domain_name is not None:
            domain_xml = ET.Element(
                'domain',
                name=dns_domain_name,
                localOnly='yes',
            )
            net_xml.append(domain_xml)
        if 'dhcp' in self._spec:
            IPV6_PREFIX = 'fd8f:1391:3a82:' + subnet + '::'
            ipv4 = net_xml.xpath('/network/ip')[0]
            ipv6 = net_xml.xpath('/network/ip')[1]
            dns = net_xml.xpath('/network/dns')[0]

            def make_ipv4(last):
                return '.'.join(self.gw().split('.')[:-1] + [str(last)])

            dhcp = ET.Element('dhcp')
            dhcpv6 = ET.Element('dhcp')
            ipv4.append(dhcp)
            ipv6.append(dhcpv6)

            dhcp.append(
                ET.Element(
                    'range',
                    start=make_ipv4(self._spec['dhcp']['start']),
                    end=make_ipv4(self._spec['dhcp']['end']),
                ))
            dhcpv6.append(
                ET.Element(
                    'range',
                    start=IPV6_PREFIX + make_ipv4(self._spec['dhcp']['start']),
                    end=IPV6_PREFIX + make_ipv4(self._spec['dhcp']['end']),
                ))

            if self.is_management():
                for hostname, ip4 in self._spec['mapping'].items():
                    dhcp.append(
                        ET.Element('host',
                                   mac=utils.ipv4_to_mac(ip4),
                                   ip=ip4,
                                   name=hostname))
                    dhcpv6.append(
                        ET.Element('host',
                                   id='0:3:0:1:' + utils.ipv4_to_mac(ip4),
                                   ip=IPV6_PREFIX + ip4,
                                   name=hostname))
                    dns_host = ET.SubElement(dns, 'host', ip=ip4)
                    dns_name = ET.SubElement(dns_host, 'hostname')
                    dns_name.text = hostname
                    dns6_host = ET.SubElement(dns,
                                              'host',
                                              ip=IPV6_PREFIX + ip4)
                    dns6_name = ET.SubElement(dns6_host, 'hostname')
                    dns6_name.text = hostname
                    dns.append(dns_host)
                    dns.append(dns6_host)

        return ET.tostring(net_xml)