¡@

Home 

OpenStack Study: servers.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright 2010-2011 OpenStack Foundation

# Copyright 2011 Piston Cloud Computing, Inc.

# All Rights Reserved.

#

# 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.

import hashlib

from nova.api.openstack import common

from nova.api.openstack.compute.views import addresses as views_addresses

from nova.api.openstack.compute.views import flavors as views_flavors

from nova.api.openstack.compute.views import images as views_images

from nova.compute import flavors

from nova.objects import instance as instance_obj

from nova.openstack.common.gettextutils import _

from nova.openstack.common import log as logging

from nova.openstack.common import timeutils

from nova import utils

LOG = logging.getLogger(__name__)

**** CubicPower OpenStack Study ****

class ViewBuilder(common.ViewBuilder):

"""Model a server API response as a python dictionary."""

_collection_name = "servers"

_progress_statuses = (

"ACTIVE",

"BUILD",

"REBUILD",

"RESIZE",

"VERIFY_RESIZE",

)

_fault_statuses = (

"ERROR", "DELETED"

)

**** CubicPower OpenStack Study ****

    def __init__(self):

        """Initialize view builder."""

        super(ViewBuilder, self).__init__()

        self._address_builder = views_addresses.ViewBuilder()

        self._flavor_builder = views_flavors.ViewBuilder()

        self._image_builder = views_images.ViewBuilder()

**** CubicPower OpenStack Study ****

    def create(self, request, instance):

        """View that should be returned when an instance is created."""

        return {

            "server": {

                "id": instance["uuid"],

                "links": self._get_links(request,

                                         instance["uuid"],

                                         self._collection_name),

            },

        }

**** CubicPower OpenStack Study ****

    def basic(self, request, instance):

        """Generic, non-detailed view of an instance."""

        return {

            "server": {

                "id": instance["uuid"],

                "name": instance["display_name"],

                "links": self._get_links(request,

                                         instance["uuid"],

                                         self._collection_name),

            },

        }

**** CubicPower OpenStack Study ****

    def show(self, request, instance):

        """Detailed view of a single instance."""

        ip_v4 = instance.get('access_ip_v4')

        ip_v6 = instance.get('access_ip_v6')

        server = {

            "server": {

                "id": instance["uuid"],

                "name": instance["display_name"],

                "status": self._get_vm_status(instance),

                "tenant_id": instance.get("project_id") or "",

                "user_id": instance.get("user_id") or "",

                "metadata": self._get_metadata(instance),

                "hostId": self._get_host_id(instance) or "",

                "image": self._get_image(request, instance),

                "flavor": self._get_flavor(request, instance),

                "created": timeutils.isotime(instance["created_at"]),

                "updated": timeutils.isotime(instance["updated_at"]),

                "addresses": self._get_addresses(request, instance),

                "accessIPv4": str(ip_v4) if ip_v4 is not None else '',

                "accessIPv6": str(ip_v6) if ip_v6 is not None else '',

                "links": self._get_links(request,

                                         instance["uuid"],

                                         self._collection_name),

            },

        }

        if server["server"]["status"] in self._fault_statuses:

            _inst_fault = self._get_fault(request, instance)

            if _inst_fault:

                server['server']['fault'] = _inst_fault

        if server["server"]["status"] in self._progress_statuses:

            server["server"]["progress"] = instance.get("progress", 0)

        return server

**** CubicPower OpenStack Study ****

    def index(self, request, instances):

        """Show a list of servers without many details."""

        return self._list_view(self.basic, request, instances)

**** CubicPower OpenStack Study ****

    def detail(self, request, instances):

        """Detailed view of a list of instance."""

        return self._list_view(self.show, request, instances)

**** CubicPower OpenStack Study ****

    def _list_view(self, func, request, servers):

        """Provide a view for a list of servers."""

        server_list = [func(request, server)["server"] for server in servers]

        servers_links = self._get_collection_links(request,

                                                   servers,

                                                   self._collection_name)

        servers_dict = dict(servers=server_list)

        if servers_links:

            servers_dict["servers_links"] = servers_links

        return servers_dict

    @staticmethod

**** CubicPower OpenStack Study ****

    def _get_metadata(instance):

        # FIXME(danms): Transitional support for objects

        metadata = instance.get('metadata')

        if isinstance(instance, instance_obj.Instance):

            return metadata or {}

        else:

            return utils.instance_meta(instance)

    @staticmethod

**** CubicPower OpenStack Study ****

    def _get_vm_status(instance):

        # If the instance is deleted the vm and task states don't really matter

        if instance.get("deleted"):

            return "DELETED"

        return common.status_from_state(instance.get("vm_state"),

                                        instance.get("task_state"))

    @staticmethod

**** CubicPower OpenStack Study ****

    def _get_host_id(instance):

        host = instance.get("host")

        project = str(instance.get("project_id"))

        if host:

            sha_hash = hashlib.sha224(project + host)  # pylint: disable=E1101

            return sha_hash.hexdigest()

**** CubicPower OpenStack Study ****

    def _get_addresses(self, request, instance):

        context = request.environ["nova.context"]

        networks = common.get_networks_for_instance(context, instance)

        return self._address_builder.index(networks)["addresses"]

**** CubicPower OpenStack Study ****

    def _get_image(self, request, instance):

        image_ref = instance["image_ref"]

        if image_ref:

            image_id = str(common.get_id_from_href(image_ref))

            bookmark = self._image_builder._get_bookmark_link(request,

                                                              image_id,

                                                              "images")

            return {

                "id": image_id,

                "links": [{

                    "rel": "bookmark",

                    "href": bookmark,

                }],

            }

        else:

            return ""

**** CubicPower OpenStack Study ****

    def _get_flavor(self, request, instance):

        instance_type = flavors.extract_flavor(instance)

        if not instance_type:

            LOG.warn(_("Instance has had its instance_type removed "

                    "from the DB"), instance=instance)

            return {}

        flavor_id = instance_type["flavorid"]

        flavor_bookmark = self._flavor_builder._get_bookmark_link(request,

                                                                  flavor_id,

                                                                  "flavors")

        return {

            "id": str(flavor_id),

            "links": [{

                "rel": "bookmark",

                "href": flavor_bookmark,

            }],

        }

**** CubicPower OpenStack Study ****

    def _get_fault(self, request, instance):

        # This can result in a lazy load of the fault information

        fault = instance.fault

        if not fault:

            return None

        fault_dict = {

            "code": fault["code"],

            "created": timeutils.isotime(fault["created_at"]),

            "message": fault["message"],

        }

        if fault.get('details', None):

            is_admin = False

            context = request.environ["nova.context"]

            if context:

                is_admin = getattr(context, 'is_admin', False)

            if is_admin or fault['code'] != 500:

                fault_dict['details'] = fault["details"]

        return fault_dict

**** CubicPower OpenStack Study ****

class ViewBuilderV3(ViewBuilder):

"""Model a server V3 API response as a python dictionary."""

**** CubicPower OpenStack Study ****

    def __init__(self):

        """Initialize view builder."""

        super(ViewBuilderV3, self).__init__()

        self._address_builder = views_addresses.ViewBuilderV3()

        self._image_builder = views_images.ViewBuilderV3()

**** CubicPower OpenStack Study ****

    def show(self, request, instance):

        """Detailed view of a single instance."""

        server = {

            "server": {

                "id": instance["uuid"],

                "name": instance["display_name"],

                "status": self._get_vm_status(instance),

                "tenant_id": instance.get("project_id") or "",

                "user_id": instance.get("user_id") or "",

                "metadata": self._get_metadata(instance),

                "host_id": self._get_host_id(instance) or "",

                "image": self._get_image(request, instance),

                "flavor": self._get_flavor(request, instance),

                "created": timeutils.isotime(instance["created_at"]),

                "updated": timeutils.isotime(instance["updated_at"]),

                "addresses": self._get_addresses(request, instance),

                "links": self._get_links(request,

                                         instance["uuid"],

                                         self._collection_name),

            },

        }

        if server["server"]["status"] in self._fault_statuses:

            _inst_fault = self._get_fault(request, instance)

            if _inst_fault:

                server['server']['fault'] = _inst_fault

        if server["server"]["status"] in self._progress_statuses:

            server["server"]["progress"] = instance.get("progress", 0)

        # We should modify the "image" to empty dictionary

        if not server["server"]["image"]:

            server["server"]["image"] = {}

        return server