def _generate_random_mac(self):
        if self.conn and not self._random_mac:
            found = False
            for ignore in range(256):
                self._random_mac = _util.randomMAC(self.conn.getType().lower())
                ret = self.is_conflict_net(self.conn, self._random_mac)
                if ret[1] is not None:
                    continue
                found = True
                break

            if not found:
                logging.debug("Failed to generate non-conflicting MAC")
        return self._random_mac
    def _generate_random_mac(self):
        if self.conn and not self._random_mac:
            found = False
            for ignore in range(256):
                self._random_mac = _util.randomMAC(self.conn.getType().lower())
                ret = self.is_conflict_net(self.conn, self._random_mac)
                if ret[1] is not None:
                    continue
                found = True
                break

            if not found:
                logging.debug("Failed to generate non-conflicting MAC")
        return self._random_mac
    def setup(self, conn=None):
        """
        DEPRECATED: Please use setup_dev instead
        """
        if not conn:
            conn = self.conn

        if self.macaddr is None:
            while 1:
                self.macaddr = _util.randomMAC(type=conn.getType().lower())
                if self.is_conflict_net(conn)[1] is not None:
                    continue
                else:
                    break
        else:
            ret, msg = self.is_conflict_net(conn)
            if msg is not None:
                if ret is False:
                    logging.warning(msg)
                else:
                    raise RuntimeError(msg)

        if not self.bridge and self.type == "bridge":
            self.bridge = _util.default_bridge2(self.conn)
    def setup(self, conn=None):
        """
        DEPRECATED: Please use setup_dev instead
        """
        if not conn:
            conn = self.conn

        if self.macaddr is None:
            while 1:
                self.macaddr = _util.randomMAC(type=conn.getType().lower())
                if self.is_conflict_net(conn)[1] is not None:
                    continue
                else:
                    break
        else:
            ret, msg = self.is_conflict_net(conn)
            if msg is not None:
                if ret is False:
                    logging.warning(msg)
                else:
                    raise RuntimeError(msg)

        if not self.bridge and self.type == "bridge":
            self.bridge = _util.default_bridge2(self.conn)
Beispiel #5
0
    def setup_clone(self):
        """
        Validate and set up all parameters needed for the new (clone) VM
        """
        logging.debug("Validating clone parameters.")

        self._clone_xml = self.original_xml

        # XXX: Make sure a clone name has been specified? or generate one?

        logging.debug("Clone paths: %s" % (self._clone_devices))

        # We simply edit the original VM xml in place
        doc = libxml2.parseDoc(self._clone_xml)
        ctx = doc.xpathNewContext()

        # changing name
        node = ctx.xpathEval("/domain/name")
        node[0].setContent(self._clone_name)

        # We always have a UUID since one is generated at init time
        node = ctx.xpathEval("/domain/uuid")
        node[0].setContent(self._clone_uuid)

        # changing mac
        count = ctx.xpathEval("count(/domain/devices/interface/mac)")
        for i in range(1, int(count + 1)):
            base_xpath = "/domain/devices/interface[%d]" % i
            base_node = ctx.xpathEval(base_xpath)[0]
            node = ctx.xpathEval(base_xpath + "/mac/@address")
            node = node and node[0] or None

            if not node:
                node = base_node.newChild(None, "mac", None)
                node.setProp("address", "tmp")
                node = ctx.xpathEval(base_xpath + "/mac/@address")[0]

            mac = None
            try:
                mac = self._clone_mac[i - 1]
            except Exception:
                while 1:
                    mac = _util.randomMAC(self.original_conn.getType().lower())
                    dummy, msg = self._check_mac(mac)
                    if msg is not None:
                        continue
                    else:
                        break

            node.setContent(mac)

        if len(self.clone_virtual_disks) < len(self.original_virtual_disks):
            raise ValueError(
                _("More disks to clone than new paths specified. "
                  "(%(passed)d specified, %(need)d needed") % {
                      "passed": len(self.clone_virtual_disks),
                      "need": len(self.original_virtual_disks)
                  })

        # Changing storage XML
        for i in range(0, len(self.original_virtual_disks)):
            orig_disk = self._original_virtual_disks[i]
            clone_disk = self._clone_virtual_disks[i]

            self._change_storage_xml(ctx, orig_disk, clone_disk)

            # Sync 'size' between the two
            if orig_disk.size:
                clone_disk.size = orig_disk.size

            # Setup proper cloning inputs for the new virtual disks
            if orig_disk.vol_object and clone_disk.vol_install:

                # Source and dest are managed. If they share the same pool,
                # replace vol_install with a CloneVolume instance, otherwise
                # simply set input_vol on the dest vol_install
                if (clone_disk.vol_install.pool.name() == orig_disk.vol_object.
                        storagePoolLookupByVolume().name()):
                    newname = clone_disk.vol_install.name
                    clone_disk.vol_install = Storage.CloneVolume(
                        newname, orig_disk.vol_object)

                else:
                    clone_disk.vol_install.input_vol = orig_disk.vol_object

            elif not self.preserve_dest_disks:
                clone_disk.clone_path = orig_disk.path

        # Save altered clone xml
        self._clone_xml = str(doc)

        ctx.xpathFreeContext()
        doc.freeDoc()
    def setup_clone(self):
        """
        Validate and set up all parameters needed for the new (clone) VM
        """
        logging.debug("Validating clone parameters.")

        self._clone_xml = self.original_xml

        if len(self.clone_virtual_disks) < len(self.original_virtual_disks):
            raise ValueError(_("More disks to clone than new paths specified. "
                               "(%(passed)d specified, %(need)d needed") %
                               {"passed" : len(self.clone_virtual_disks),
                                "need"   : len(self.original_virtual_disks) })

        logging.debug("Clone paths: %s", self._clone_devices)

        self._guest.name = self._clone_name
        self._guest.uuid = self._clone_uuid
        self._clone_mac.reverse()
        for dev in self._guest.get_devices("graphics"):
            if dev.port and dev.port != -1:
                logging.warn(_("Setting the graphics device port to autoport, "
                               "in order to avoid conflicting."))
                dev.port = -1
        for iface in self._guest.get_devices("interface"):
            iface.target_dev = None

            if self._clone_mac:
                mac = self._clone_mac.pop()
            else:
                while 1:
                    mac = _util.randomMAC(self.original_conn.getType().lower(),
                                          conn=self.original_conn)
                    dummy, msg = self._check_mac(mac)
                    if msg is not None:
                        continue
                    else:
                        break

            iface.macaddr = mac

        # Changing storage XML
        for i in range(len(self._original_virtual_disks)):
            orig_disk = self._original_virtual_disks[i]
            clone_disk = self._clone_virtual_disks[i]

            for disk in self._guest.get_devices("disk"):
                if disk.target == orig_disk.target:
                    xmldisk = disk

            if clone_disk.vol_object:
                # XXX We could always do this with vol upload?

                # Special case: non remote cloning of a guest using
                # managed block devices: fall back to local cloning if
                # we have permissions to do so. This validation check
                # caused a few bug reports in a short period of time,
                # so must be a common case.
                if (clone_disk.is_remote() or
                    clone_disk.type != clone_disk.TYPE_BLOCK or
                    not orig_disk.path or
                    not os.access(orig_disk.path, os.R_OK) or
                    not clone_disk.path or
                    not os.access(clone_disk.path, os.W_OK)):
                    raise RuntimeError(
                        _("Clone onto existing storage volume is not "
                          "currently supported: '%s'") % clone_disk.path)

            # Sync 'size' between the two
            if orig_disk.size:
                clone_disk.size = orig_disk.size

            # Setup proper cloning inputs for the new virtual disks
            if orig_disk.vol_object and clone_disk.vol_install:

                # Source and dest are managed. If they share the same pool,
                # replace vol_install with a CloneVolume instance, otherwise
                # simply set input_vol on the dest vol_install
                if (clone_disk.vol_install.pool.name() ==
                    orig_disk.vol_object.storagePoolLookupByVolume().name()):
                    newname = clone_disk.vol_install.name
                    clone_disk.vol_install = Storage.CloneVolume(newname,
                                                        orig_disk.vol_object)

                else:
                    clone_disk.vol_install.input_vol = orig_disk.vol_object

            elif not self.preserve_dest_disks:
                clone_disk.clone_path = orig_disk.path

            # Change the XML
            xmldisk.path = None
            xmldisk.type = clone_disk.type
            xmldisk.path = clone_disk.path
            xmldisk.driver_type = orig_disk.driver_type

        # Save altered clone xml
        self._clone_xml = self._guest.get_xml_config()
        logging.debug("Clone guest xml is\n%s", self._clone_xml)
    def setup_clone(self):
        """
        Validate and set up all parameters needed for the new (clone) VM
        """
        logging.debug("Validating clone parameters.")

        self._clone_xml = self.original_xml

        # XXX: Make sure a clone name has been specified? or generate one?

        logging.debug("Clone paths: %s", self._clone_devices)

        # We simply edit the original VM xml in place
        doc = libxml2.parseDoc(self._clone_xml)
        ctx = doc.xpathNewContext()

        # changing name
        node = ctx.xpathEval("/domain/name")
        node[0].setContent(self._clone_name)

        # We always have a UUID since one is generated at init time
        node = ctx.xpathEval("/domain/uuid")
        node[0].setContent(self._clone_uuid)

        # changing mac
        count = ctx.xpathEval("count(/domain/devices/interface/mac)")
        for i in range(1, int(count + 1)):
            base_xpath = "/domain/devices/interface[%d]" % i
            base_node = ctx.xpathEval(base_xpath)[0]
            node = ctx.xpathEval(base_xpath + "/mac/@address")
            node = node and node[0] or None

            if not node:
                node = base_node.newChild(None, "mac", None)
                node.setProp("address", "tmp")
                node = ctx.xpathEval(base_xpath + "/mac/@address")[0]

            mac = None
            try:
                mac = self._clone_mac[i - 1]
            except Exception:
                while 1:
                    mac = _util.randomMAC(self.original_conn.getType().lower())
                    dummy, msg = self._check_mac(mac)
                    if msg is not None:
                        continue
                    else:
                        break

            node.setContent(mac)

        if len(self.clone_virtual_disks) < len(self.original_virtual_disks):
            raise ValueError(_("More disks to clone than new paths specified. "
                               "(%(passed)d specified, %(need)d needed") %
                               {"passed" : len(self.clone_virtual_disks),
                                "need"   : len(self.original_virtual_disks) })

        # Changing storage XML
        for i in range(0, len(self.original_virtual_disks)):
            orig_disk = self._original_virtual_disks[i]
            clone_disk = self._clone_virtual_disks[i]

            self._change_storage_xml(ctx, orig_disk, clone_disk)

            # Sync 'size' between the two
            if orig_disk.size:
                clone_disk.size = orig_disk.size

            # Setup proper cloning inputs for the new virtual disks
            if orig_disk.vol_object and clone_disk.vol_install:

                # Source and dest are managed. If they share the same pool,
                # replace vol_install with a CloneVolume instance, otherwise
                # simply set input_vol on the dest vol_install
                if (clone_disk.vol_install.pool.name() ==
                    orig_disk.vol_object.storagePoolLookupByVolume().name()):
                    newname = clone_disk.vol_install.name
                    clone_disk.vol_install = Storage.CloneVolume(newname,
                                                        orig_disk.vol_object)

                else:
                    clone_disk.vol_install.input_vol = orig_disk.vol_object

            elif not self.preserve_dest_disks:
                clone_disk.clone_path = orig_disk.path

        # Save altered clone xml
        self._clone_xml = str(doc)

        ctx.xpathFreeContext()
        doc.freeDoc()