Esempio n. 1
0
    def _select_machine(self, context, instance):
        inst_type = instance_types.get_instance_type(instance['instance_type_id'])

        bmm_found = None
        reuse = False

        # create a non autocommit session
        session = get_session_dodai(False)
        session.begin()
        try:
            bmms = db.bmm_get_all_by_instance_type(context, inst_type["name"], session)
            if instance["availability_zone"] == "resource_pool": #Add a machine to resource pool.
                for bmm in bmms:
                    if bmm["availability_zone"] != "resource_pool":
                        continue

                    if bmm["status"] != "inactive":
                        continue

                    bmm_found = bmm
                    break
            else:
                for bmm in bmms:
                    if bmm["availability_zone"] != "resource_pool":
                        continue
    
                    if bmm["status"] != "active":
                        continue 
        
                    instance_ref = db.instance_get(context, bmm["instance_id"])
                    if instance_ref["image_ref"] != instance["image_ref"]:
                        continue
    
                    bmm_found = bmm
                    reuse = True
                    break
   
                if not bmm_found:
                    for bmm in bmms:
                        if bmm["status"] == "used" or bmm["status"] == "processing":
                            continue
    
                        bmm_found = bmm
                        reuse = False
                        break

            if bmm_found:
                db.bmm_update(context, bmm_found["id"], {"status": "processing"}, session)
        except Exception as ex:
            LOG.exception(ex)
            session.rollback()
            raise exception.BareMetalMachineUnavailable() 

        session.commit()

        if bmm_found:
            return bmm_found, reuse

        raise exception.BareMetalMachineUnavailable()
Esempio n. 2
0
    def spawn(self, context, instance,
              network_info=None, block_device_info=None):
        """
        Create a new instance/VM/domain on the virtualization platform.

        Once this successfully completes, the instance should be
        running (power_state.RUNNING).

        If this fails, any partial instance should be completely
        cleaned up, and the virtualization platform should be in the state
        that it was before this call began.

        :param context: security context
        :param instance: Instance object as returned by DB layer.
                         This function should use the data there to guide
                         the creation of the new instance.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info:
        """
        LOG.debug("spawn")

        instance_zone, cluster_name, vlan_id, create_cluster = self._parse_zone(instance["availability_zone"])

        # update instances table
        bmm, reuse = self._select_machine(context, instance)
        instance["display_name"] = bmm["name"]
        instance["availability_zone"] = instance_zone
        db.instance_update(context, 
                           instance["id"], 
                           {"display_name": bmm["name"],
                            "availability_zone": instance_zone})
        if vlan_id:
            db.bmm_update(context, bmm["id"], {"availability_zone": cluster_name, 
                                               "vlan_id": vlan_id,
                                               "service_ip": None})
 
        if instance_zone == "resource_pool":
            self._install_machine(context, instance, bmm, cluster_name, vlan_id)
        else: 
            self._update_ofc(bmm, cluster_name)
            if bmm["instance_id"]:
                db.instance_destroy(context, bmm["instance_id"])

            if reuse:
                db.bmm_update(context, bmm["id"], {"status": "used", 
                                                   "instance_id": instance["id"]}) 
            else:
                self._install_machine(context, instance, bmm, cluster_name, vlan_id)
            
            if instance["key_data"]:
                self._inject_key(bmm["pxe_ip"], str(instance["key_data"]))
Esempio n. 3
0
    def destroy(self, context, instance, network_info, cleanup=True):
        """Destroy (shutdown and delete) the specified instance.

        If the instance is not found (for example if networking failed), this
        function should still succeed.  It's probably a good idea to log a
        warning in that case.

        :param instance: Instance object as returned by DB layer.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param cleanup:

        """
        LOG.debug("destroy")

        bmm = db.bmm_get_by_instance_id(context, instance["id"])
        db.bmm_update(context, bmm["id"], {"status": "processing"})
        mac = self._get_pxe_mac(bmm)

        # update ofc
        self._update_ofc_for_destroy(context, bmm)
        db.bmm_update(context, bmm["id"], {
            "vlan_id": None,
            "availability_zone": "resource_pool"
        })

        # begin to delete os
        self._cp_template(
            "delete.sh",
            self._get_cobbler_instance_path(instance, "delete.sh"), {
                "INSTANCE_ID": instance["id"],
                "COBBLER": FLAGS.cobbler,
                "MONITOR_PORT": FLAGS.dodai_monitor_port
            })
        self._cp_template(
            "pxeboot_action", self._get_pxe_boot_file(mac), {
                "INSTANCE_ID": instance["id"],
                "COBBLER": FLAGS.cobbler,
                "PXE_MAC": bmm["pxe_mac"],
                "ACTION": "delete"
            })
        self._reboot_or_power_on(bmm["ipmi_ip"])

        # wait until starting to delete os
        while self._get_state(context, instance) != "deleted":
            greenthread.sleep(20)
            LOG.debug("Wait until data of instance %s was deleted." %
                      instance["id"])

        utils.execute("rm", "-rf", self._get_cobbler_instance_path(instance))

        # update db
        db.bmm_update(context, bmm["id"], {
            "instance_id": None,
            "service_ip": None
        })

        return db.bmm_get(context, bmm["id"])
Esempio n. 4
0
    def destroy(self, context, instance, network_info, cleanup=True):
        """Destroy (shutdown and delete) the specified instance.

        If the instance is not found (for example if networking failed), this
        function should still succeed.  It's probably a good idea to log a
        warning in that case.

        :param instance: Instance object as returned by DB layer.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param cleanup:

        """
        LOG.debug("destroy")

        bmm = db.bmm_get_by_instance_id(context, instance["id"])
        db.bmm_update(context, bmm["id"], {"status": "processing"})
        mac = self._get_pxe_mac(bmm)

        # update ofc
        self._update_ofc_for_destroy(context, bmm)
        db.bmm_update(context, bmm["id"], {"vlan_id": None,
                                           "availability_zone": "resource_pool"})

        # begin to delete os
        self._cp_template("delete.sh",
                          self._get_cobbler_instance_path(instance, "delete.sh"), 
                          {"INSTANCE_ID": instance["id"],
                           "COBBLER": FLAGS.cobbler,
                           "MONITOR_PORT": FLAGS.dodai_monitor_port})
        self._cp_template("pxeboot_action",
                          self._get_pxe_boot_file(mac),
                          {"INSTANCE_ID": instance["id"], 
                           "COBBLER": FLAGS.cobbler,
                           "PXE_MAC": bmm["pxe_mac"],
                           "ACTION": "delete"})
        self._reboot_or_power_on(bmm["ipmi_ip"])

        # wait until starting to delete os
        while self._get_state(context, instance) != "deleted":
            greenthread.sleep(20)
            LOG.debug("Wait until data of instance %s was deleted." % instance["id"])

        utils.execute("rm", "-rf", self._get_cobbler_instance_path(instance));

        # update db
        db.bmm_update(context, bmm["id"], {"instance_id": None, 
                                           "service_ip": None})

        return db.bmm_get(context, bmm["id"])
Esempio n. 5
0
    def _install_machine(self, context, instance, bmm, cluster_name, vlan_id, update_instance=False):
        db.bmm_update(context, bmm["id"], {"instance_id": instance["id"]})
        mac = self._get_pxe_mac(bmm)

        # fetch image
        image_base_path = self._get_cobbler_image_path()
        if not os.path.exists(image_base_path):
            utils.execute('mkdir', '-p', image_base_path)

        image_path = self._get_cobbler_image_path(instance)
        if not os.path.exists(image_path):
            image_meta = images.fetch(context, 
                                      instance["image_ref"], 
                                      image_path, 
                                      instance["user_id"], 
                                      instance["project_id"])
        else:
            image_meta = images.show(context, instance["image_ref"])

        image_type = "server"
        image_name = image_meta["name"] or image_meta["properties"]["image_location"]
        if image_name.find("dodai-deploy") == -1:
            image_type = "node"

        # begin to install os
        pxe_ip = bmm["pxe_ip"] or "None"
        pxe_mac = bmm["pxe_mac"] or "None"
        storage_ip = bmm["storage_ip"] or "None"
        storage_mac = bmm["storage_mac"] or "None"
        service_mac1 = bmm["service_mac1"] or "None"
        service_mac2 = bmm["service_mac2"] or "None"

        instance_path = self._get_cobbler_instance_path(instance) 
        if not os.path.exists(instance_path):
            utils.execute('mkdir', '-p', instance_path)

        self._cp_template("create.sh", 
                          self._get_cobbler_instance_path(instance, "create.sh"),
                          {"INSTANCE_ID": instance["id"], 
                           "IMAGE_ID": instance["image_ref"], 
                           "COBBLER": FLAGS.cobbler, 
                           "HOST_NAME": bmm["name"], 
                           "STORAGE_IP": storage_ip,
                           "STORAGE_MAC": storage_mac,
                           "PXE_IP": pxe_ip, 
                           "PXE_MAC": pxe_mac,
                           "SERVICE_MAC1": bmm["service_mac1"],
                           "SERVICE_MAC2": bmm["service_mac2"],
                           "IMAGE_TYPE": image_type,
                           "MONITOR_PORT": FLAGS.dodai_monitor_port,
                           "ROOT_SIZE": FLAGS.dodai_partition_root_gb,
                           "SWAP_SIZE": FLAGS.dodai_partition_swap_gb,
                           "EPHEMERAL_SIZE": FLAGS.dodai_partition_ephemeral_gb,
                           "KDUMP_SIZE": FLAGS.dodai_partition_kdump_gb})

        self._cp_template("pxeboot_action",
                          self._get_pxe_boot_file(mac),
                          {"INSTANCE_ID": instance["id"], 
                           "COBBLER": FLAGS.cobbler,
                           "PXE_MAC": pxe_mac,
                           "ACTION": "create"})

        LOG.debug("Reboot or power on.")
        self._reboot_or_power_on(bmm["ipmi_ip"])

        # wait until starting to install os
        while self._get_state(context, instance) != "install":
            greenthread.sleep(20)
            LOG.debug("Wait until begin to install instance %s." % instance["id"])
        self._cp_template("pxeboot_start", self._get_pxe_boot_file(mac), {})

        # wait until starting to reboot 
        while self._get_state(context, instance) != "install_reboot":
            greenthread.sleep(20)
            LOG.debug("Wait until begin to reboot instance %s after os has been installed." % instance["id"])
        power_manager = PowerManager(bmm["ipmi_ip"])
        power_manager.soft_off()
        while power_manager.status() == "on":
            greenthread.sleep(20)
            LOG.debug("Wait unit the instance %s shuts down." % instance["id"])
        power_manager.on()

        # wait until installation of os finished
        while self._get_state(context, instance) != "installed":
            greenthread.sleep(20)
            LOG.debug("Wait until instance %s installation finished." % instance["id"])
 
        if cluster_name == "resource_pool":
            status = "active"
        else:
            status = "used"

        db.bmm_update(context, bmm["id"], {"status": status})

        if update_instance:
            db.instance_update(context, instance["id"], {"vm_state": vm_states.ACTIVE})
Esempio n. 6
0
    def _select_machine(self, context, instance):
        inst_type = instance_types.get_instance_type(
            instance['instance_type_id'])

        bmm_found = None
        reuse = False

        # create a non autocommit session
        session = get_session_dodai(False)
        session.begin()
        try:
            bmms = db.bmm_get_all_by_instance_type(context, inst_type["name"],
                                                   session)
            if instance[
                    "availability_zone"] == "resource_pool":  #Add a machine to resource pool.
                for bmm in bmms:
                    if bmm["availability_zone"] != "resource_pool":
                        continue

                    if bmm["status"] != "inactive":
                        continue

                    bmm_found = bmm
                    break
            else:
                for bmm in bmms:
                    if bmm["availability_zone"] != "resource_pool":
                        continue

                    if bmm["status"] != "active":
                        continue

                    instance_ref = db.instance_get(context, bmm["instance_id"])
                    if instance_ref["image_ref"] != instance["image_ref"]:
                        continue

                    bmm_found = bmm
                    reuse = True
                    break

                if not bmm_found:
                    for bmm in bmms:
                        if bmm["status"] == "used" or bmm[
                                "status"] == "processing":
                            continue

                        bmm_found = bmm
                        reuse = False
                        break

            if bmm_found:
                db.bmm_update(context, bmm_found["id"],
                              {"status": "processing"}, session)
        except Exception as ex:
            LOG.exception(ex)
            session.rollback()
            raise exception.BareMetalMachineUnavailable()

        session.commit()

        if bmm_found:
            return bmm_found, reuse

        raise exception.BareMetalMachineUnavailable()
Esempio n. 7
0
    def _install_machine(self,
                         context,
                         instance,
                         bmm,
                         cluster_name,
                         vlan_id,
                         update_instance=False):
        db.bmm_update(context, bmm["id"], {"instance_id": instance["id"]})
        mac = self._get_pxe_mac(bmm)

        # fetch image
        image_base_path = self._get_cobbler_image_path()
        if not os.path.exists(image_base_path):
            utils.execute('mkdir', '-p', image_base_path)

        image_path = self._get_cobbler_image_path(instance)
        if not os.path.exists(image_path):
            image_meta = images.fetch(context, instance["image_ref"],
                                      image_path, instance["user_id"],
                                      instance["project_id"])
        else:
            image_meta = images.show(context, instance["image_ref"])

        image_type = "server"
        image_name = image_meta["name"] or image_meta["properties"][
            "image_location"]
        if image_name.find("dodai-deploy") == -1:
            image_type = "node"

        # begin to install os
        pxe_ip = bmm["pxe_ip"] or "None"
        pxe_mac = bmm["pxe_mac"] or "None"
        storage_ip = bmm["storage_ip"] or "None"
        storage_mac = bmm["storage_mac"] or "None"
        service_mac1 = bmm["service_mac1"] or "None"
        service_mac2 = bmm["service_mac2"] or "None"

        instance_path = self._get_cobbler_instance_path(instance)
        if not os.path.exists(instance_path):
            utils.execute('mkdir', '-p', instance_path)

        self._cp_template(
            "create.sh",
            self._get_cobbler_instance_path(instance, "create.sh"), {
                "INSTANCE_ID": instance["id"],
                "IMAGE_ID": instance["image_ref"],
                "COBBLER": FLAGS.cobbler,
                "HOST_NAME": bmm["name"],
                "STORAGE_IP": storage_ip,
                "STORAGE_MAC": storage_mac,
                "PXE_IP": pxe_ip,
                "PXE_MAC": pxe_mac,
                "SERVICE_MAC1": bmm["service_mac1"],
                "SERVICE_MAC2": bmm["service_mac2"],
                "IMAGE_TYPE": image_type,
                "MONITOR_PORT": FLAGS.dodai_monitor_port,
                "ROOT_SIZE": FLAGS.dodai_partition_root_gb,
                "SWAP_SIZE": FLAGS.dodai_partition_swap_gb,
                "EPHEMERAL_SIZE": FLAGS.dodai_partition_ephemeral_gb,
                "KDUMP_SIZE": FLAGS.dodai_partition_kdump_gb
            })

        self._cp_template(
            "pxeboot_action", self._get_pxe_boot_file(mac), {
                "INSTANCE_ID": instance["id"],
                "COBBLER": FLAGS.cobbler,
                "PXE_MAC": pxe_mac,
                "ACTION": "create"
            })

        LOG.debug("Reboot or power on.")
        self._reboot_or_power_on(bmm["ipmi_ip"])

        # wait until starting to install os
        while self._get_state(context, instance) != "install":
            greenthread.sleep(20)
            LOG.debug("Wait until begin to install instance %s." %
                      instance["id"])
        self._cp_template("pxeboot_start", self._get_pxe_boot_file(mac), {})

        # wait until starting to reboot
        while self._get_state(context, instance) != "install_reboot":
            greenthread.sleep(20)
            LOG.debug(
                "Wait until begin to reboot instance %s after os has been installed."
                % instance["id"])
        power_manager = PowerManager(bmm["ipmi_ip"])
        power_manager.soft_off()
        while power_manager.status() == "on":
            greenthread.sleep(20)
            LOG.debug("Wait unit the instance %s shuts down." % instance["id"])
        power_manager.on()

        # wait until installation of os finished
        while self._get_state(context, instance) != "installed":
            greenthread.sleep(20)
            LOG.debug("Wait until instance %s installation finished." %
                      instance["id"])

        if cluster_name == "resource_pool":
            status = "active"
        else:
            status = "used"

        db.bmm_update(context, bmm["id"], {"status": status})

        if update_instance:
            db.instance_update(context, instance["id"],
                               {"vm_state": vm_states.ACTIVE})
Esempio n. 8
0
    def spawn(self,
              context,
              instance,
              network_info=None,
              block_device_info=None):
        """
        Create a new instance/VM/domain on the virtualization platform.

        Once this successfully completes, the instance should be
        running (power_state.RUNNING).

        If this fails, any partial instance should be completely
        cleaned up, and the virtualization platform should be in the state
        that it was before this call began.

        :param context: security context
        :param instance: Instance object as returned by DB layer.
                         This function should use the data there to guide
                         the creation of the new instance.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info:
        """
        LOG.debug("spawn")

        instance_zone, cluster_name, vlan_id, create_cluster = self._parse_zone(
            instance["availability_zone"])

        # update instances table
        bmm, reuse = self._select_machine(context, instance)
        instance["display_name"] = bmm["name"]
        instance["availability_zone"] = instance_zone
        db.instance_update(context, instance["id"], {
            "display_name": bmm["name"],
            "availability_zone": instance_zone
        })
        if vlan_id:
            db.bmm_update(
                context, bmm["id"], {
                    "availability_zone": cluster_name,
                    "vlan_id": vlan_id,
                    "service_ip": None
                })

        if instance_zone == "resource_pool":
            self._install_machine(context, instance, bmm, cluster_name,
                                  vlan_id)
        else:
            self._update_ofc(bmm, cluster_name)
            if bmm["instance_id"]:
                db.instance_destroy(context, bmm["instance_id"])

            if reuse:
                db.bmm_update(context, bmm["id"], {
                    "status": "used",
                    "instance_id": instance["id"]
                })
            else:
                self._install_machine(context, instance, bmm, cluster_name,
                                      vlan_id)

            if instance["key_data"]:
                self._inject_key(bmm["pxe_ip"], str(instance["key_data"]))