<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
# Copyright (c) 2010 Citrix Systems, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
A dodai hypervisor.

"""
import os
import tempfile

from nova import exception
from nova import log as logging
from nova import utils
from nova.compute import power_state
from nova.compute import instance_types
from nova.virt import driver
from nova import db
from nova.virt import images
from nova import flags
from nova.virt.dodai import ofc_utils
from nova.compute import vm_states

from eventlet import greenthread

LOG = logging.getLogger('nova.virt.dodai')
FLAGS = flags.FLAGS

flags.DEFINE_string('cobbler', None, 'IP address of cobbler')
flags.DEFINE_string('cobbler_path', '/var/www/cobbler', 'Path of cobbler')
flags.DEFINE_string('pxe_boot_path', '/var/lib/tftpboot/pxelinux.cfg', 'Path of pxeboot folder')
flags.DEFINE_string('ofc_service_url', None, 'URL of open flow controller service.')
flags.DEFINE_integer('bmm_port', 3333, '')
flags.DEFINE_string('bmm_status_path', "status", '')
flags.DEFINE_string('bmm_action_path', "action", '')
flags.DEFINE_string('ipmi_username', "", '')
flags.DEFINE_string('ipmi_password', "", '')
flags.DEFINE_integer('dodai_default_image', 13, '')
flags.DEFINE_integer('dodai_monitor_port', 7070, '')
flags.DEFINE_integer('dodai_partition_root_gb', 10, '')
flags.DEFINE_integer('dodai_partition_swap_gb', 2, '')
flags.DEFINE_integer('dodai_partition_ephemeral_gb', 10, '')
flags.DEFINE_integer('dodai_partition_kdump_gb', 10, '')

def get_connection(_):
    # The read_only parameter is ignored.
    return DodaiConnection.instance()


class DodaiInstance(object):

    def __init__(self, name, state):
        self.name = name
        self.state = state

class DodaiConnection(driver.ComputeDriver):
    """Dodai hypervisor driver"""

    def __init__(self):
        self.instances = {}

    @classmethod
    def instance(cls):
        if not hasattr(cls, '_instance'):
            cls._instance = cls()
        return cls._instance

    def init_host(self, host):
        """Initialize anything that is necessary for the driver to function,
        including catching up with currently running VM's on the given host."""
        LOG.debug("init_host")


    def get_info(self, instance_name):
        """Get the current status of an instance, by name (not ID!)

        Returns a dict containing:

        :state:           the running state, one of the power_state codes
        :max_mem:         (int) the maximum memory in KBytes allowed
        :mem:             (int) the memory in KBytes used by the domain
        :num_cpu:         (int) the number of virtual CPUs for the domain
        :cpu_time:        (int) the CPU time used in nanoseconds
        """
        LOG.debug("get_info")
        if instance_name not in self.instances:
            raise exception.InstanceNotFound(instance_id=instance_name)

        i = self.instances[instance_name]
        return {'state': i.state,
                'max_mem': 0,
                'mem': 0,
                'num_cpu': 2,
                'cpu_time': 0}

    def list_instances(self):
        """
        Return the names of all the instances known to the virtualization
        layer, as a list.
        """
        LOG.debug("list_instances")

        instance_ids = []
        bmms = db.bmm_get_all(None)
        for bmm in bmms:
            if bmm["status"] != "active":
                continue
            instance_ids.append(bmm["instance_id"])

        return instance_ids

    def list_instances_detail(self):
        """Return a list of InstanceInfo for all registered VMs"""
        LOG.debug("list_instances_detail")

        info_list = []
        bmms = db.bmm_get_all(None)
        for bmm in bmms:
            if bmm["status"] != "active":
                continue
            info_list.append(driver.InstanceInfo(bmm["instance_id"], "running"))

        return info_list        

    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 = self._get_a_bare_metal_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 instance_zone == "resource_pool":
            self._install_machine(context, instance, bmm, cluster_name, vlan_id)
        else: 
            if bmm["availability_zone"] == "resource_pool" and bmm["status"] == "active":
                db.instance_destroy(context, bmm["instance_id"])
                self._update_ofc(bmm, cluster_name, vlan_id, create_cluster)
            else:
                self._install_machine(context, instance, bmm, cluster_name, vlan_id)
                self._update_ofc(bmm, cluster_name, vlan_id, create_cluster)

    def _parse_zone(self, zone):
        create_cluster = False
        vlan_id = None
        cluster_name = "resource_pool" 
        instance_zone = zone 
        parts = zone.split(",")
        if len(parts) >= 2:
            if parts[0] == "C":
                parts.pop(0)
                create_cluster = True

            cluster_name, vlan_id = parts
            vlan_id = int(vlan_id)
            instance_zone = ",".join(parts)

        return instance_zone, cluster_name, vlan_id, create_cluster

    def _install_machine(self, context, instance, bmm, cluster_name, vlan_id, update_instance=False):
        mac = self._get_pxe_mac(bmm)

        # fetch image
        utils.execute('mkdir', '-p', self._get_cobbler_path(instance))
        image_path = self._get_cobbler_path(instance, "disk")
        images.fetch(context, 
                     instance["image_ref"], 
                     image_path, <commit_msg>Fixed the bug, bmm table wasn't updated when starting machine in resource pool<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
# Copyright (c) 2010 Citrix Systems, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
A dodai hypervisor.

"""
import os
import tempfile

from nova import exception
from nova import log as logging
from nova import utils
from nova.compute import power_state
from nova.compute import instance_types
from nova.virt import driver
from nova import db
from nova.virt import images
from nova import flags
from nova.virt.dodai import ofc_utils
from nova.compute import vm_states

from eventlet import greenthread

LOG = logging.getLogger('nova.virt.dodai')
FLAGS = flags.FLAGS

flags.DEFINE_string('cobbler', None, 'IP address of cobbler')
flags.DEFINE_string('cobbler_path', '/var/www/cobbler', 'Path of cobbler')
flags.DEFINE_string('pxe_boot_path', '/var/lib/tftpboot/pxelinux.cfg', 'Path of pxeboot folder')
flags.DEFINE_string('ofc_service_url', None, 'URL of open flow controller service.')
flags.DEFINE_integer('bmm_port', 3333, '')
flags.DEFINE_string('bmm_status_path', "status", '')
flags.DEFINE_string('bmm_action_path', "action", '')
flags.DEFINE_string('ipmi_username', "", '')
flags.DEFINE_string('ipmi_password', "", '')
flags.DEFINE_integer('dodai_default_image', 13, '')
flags.DEFINE_integer('dodai_monitor_port', 7070, '')
flags.DEFINE_integer('dodai_partition_root_gb', 10, '')
flags.DEFINE_integer('dodai_partition_swap_gb', 2, '')
flags.DEFINE_integer('dodai_partition_ephemeral_gb', 10, '')
flags.DEFINE_integer('dodai_partition_kdump_gb', 10, '')

def get_connection(_):
    # The read_only parameter is ignored.
    return DodaiConnection.instance()


class DodaiInstance(object):

    def __init__(self, name, state):
        self.name = name
        self.state = state

class DodaiConnection(driver.ComputeDriver):
    """Dodai hypervisor driver"""

    def __init__(self):
        self.instances = {}

    @classmethod
    def instance(cls):
        if not hasattr(cls, '_instance'):
            cls._instance = cls()
        return cls._instance

    def init_host(self, host):
        """Initialize anything that is necessary for the driver to function,
        including catching up with currently running VM's on the given host."""
        LOG.debug("init_host")


    def get_info(self, instance_name):
        """Get the current status of an instance, by name (not ID!)

        Returns a dict containing:

        :state:           the running state, one of the power_state codes
        :max_mem:         (int) the maximum memory in KBytes allowed
        :mem:             (int) the memory in KBytes used by the domain
        :num_cpu:         (int) the number of virtual CPUs for the domain
        :cpu_time:        (int) the CPU time used in nanoseconds
        """
        LOG.debug("get_info")
        if instance_name not in self.instances:
            raise exception.InstanceNotFound(instance_id=instance_name)

        i = self.instances[instance_name]
        return {'state': i.state,
                'max_mem': 0,
                'mem': 0,
                'num_cpu': 2,
                'cpu_time': 0}

    def list_instances(self):
        """
        Return the names of all the instances known to the virtualization
        layer, as a list.
        """
        LOG.debug("list_instances")

        instance_ids = []
        bmms = db.bmm_get_all(None)
        for bmm in bmms:
            if bmm["status"] != "active":
                continue
            instance_ids.append(bmm["instance_id"])

        return instance_ids

    def list_instances_detail(self):
        """Return a list of InstanceInfo for all registered VMs"""
        LOG.debug("list_instances_detail")

        info_list = []
        bmms = db.bmm_get_all(None)
        for bmm in bmms:
            if bmm["status"] != "active":
                continue
            info_list.append(driver.InstanceInfo(bmm["instance_id"], "running"))

        return info_list        

    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 = self._get_a_bare_metal_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 instance_zone == "resource_pool":
            self._install_machine(context, instance, bmm, cluster_name, vlan_id)
        else: 
            if bmm["availability_zone"] == "resource_pool" and bmm["status"] == "active":
                db.instance_destroy(context, bmm["instance_id"])
                db.bmm_update(bmm["id"], {"availability_zone": cluster_name, "status": "used"}) 
                self._update_ofc(bmm, cluster_name, vlan_id, create_cluster)
            else:
                self._install_machine(context, instance, bmm, cluster_name, vlan_id)
                self._update_ofc(bmm, cluster_name, vlan_id, create_cluster)

    def _parse_zone(self, zone):
        create_cluster = False
        vlan_id = None
        cluster_name = "resource_pool" 
        instance_zone = zone 
        parts = zone.split(",")
        if len(parts) >= 2:
            if parts[0] == "C":
                parts.pop(0)
                create_cluster = True

            cluster_name, vlan_id = parts
            vlan_id = int(vlan_id)
            instance_zone = ",".join(parts)

        return instance_zone, cluster_name, vlan_id, create_cluster

    def _install_machine(self, context, instance, bmm, cluster_name, vlan_id, update_instance=False):
        mac = self._get_pxe_mac(bmm)

        # fetch image
        utils.execute('mkdir', '-p', self._get_cobbler_path(instance))
        image_path = self._get_cobbler_path(instance, "disk")
        images.fetch(context, 
                     instance["image_ref"], 
                     image_path, 
{'fraction_non_alphanumeric': 0.09512227189061268, 'fraction_numerical': 0.005127530896660531, 'mean_word_length': 2.6429597701149423, 'pattern_counts': {'":': 16, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3283639', 'n_tokens_mistral': 4429, 'n_tokens_neox': 4225, 'n_words': 1243}