~ubuntu-branches/ubuntu/raring/nova/raring-proposed

« back to all changes in this revision

Viewing changes to nova/api/openstack/compute/contrib/fping.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:04:58 UTC
  • mfrom: (1.1.66)
  • Revision ID: package-import@ubuntu.com-20121123090458-91565o7aev1i1h71
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/control: Ensure novaclient is upgraded with nova,
  require python-keystoneclient >= 1:2.9.0. (LP: #1073289)
* debian/patches/{ubuntu/*, rbd-security.patch}: Dropped, applied
  upstream.
* debian/control: Add python-testtools to Build-Depends.

[ Chuck Short ]
* New upstream version.
* Refreshed debian/patches/avoid_setuptools_git_dependency.patch.
* debian/rules: FTBFS if missing binaries.
* debian/nova-scheudler.install: Add missing rabbit-queues and
  nova-rpc-zmq-receiver.
* Remove nova-volume since it doesnt exist anymore, transition to cinder-*.
* debian/rules: install apport hook in the right place.
* debian/patches/ubuntu-show-tests.patch: Display test failures.
* debian/control: Add depends on genisoimage
* debian/control: Suggest guestmount.
* debian/control: Suggest websockify. (LP: #1076442)
* debian/nova.conf: Disable nova-volume service.
* debian/control: Depend on xen-system-* rather than the hypervisor.
* debian/control, debian/mans/nova-conductor.8, debian/nova-conductor.init,
  debian/nova-conductor.install, debian/nova-conductor.logrotate
  debian/nova-conductor.manpages, debian/nova-conductor.postrm
  debian/nova-conductor.upstart.in: Add nova-conductor service.
* debian/control: Add python-fixtures as a build deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright 2011 Grid Dynamics
 
4
# Copyright 2011 OpenStack LLC.
 
5
# All Rights Reserved.
 
6
#
 
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
8
#    not use this file except in compliance with the License. You may obtain
 
9
#    a copy of the License at
 
10
#
 
11
#         http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
#    Unless required by applicable law or agreed to in writing, software
 
14
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
15
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
16
#    License for the specific language governing permissions and limitations
 
17
#    under the License.
 
18
 
 
19
import itertools
 
20
import os
 
21
import time
 
22
 
 
23
from webob import exc
 
24
 
 
25
from nova.api.openstack import common
 
26
from nova.api.openstack import extensions
 
27
from nova import compute
 
28
from nova import exception
 
29
from nova.openstack.common import cfg
 
30
from nova.openstack.common import log as logging
 
31
from nova import utils
 
32
 
 
33
 
 
34
LOG = logging.getLogger(__name__)
 
35
authorize = extensions.extension_authorizer('compute', 'fping')
 
36
authorize_all_tenants = extensions.extension_authorizer(
 
37
    'compute', 'fping:all_tenants')
 
38
fping_opts = [
 
39
    cfg.StrOpt("fping_path",
 
40
               default="/usr/sbin/fping",
 
41
               help="Full path to fping."),
 
42
]
 
43
 
 
44
CONF = cfg.CONF
 
45
CONF.register_opts(fping_opts)
 
46
 
 
47
 
 
48
class FpingController(object):
 
49
 
 
50
    def __init__(self, network_api=None):
 
51
        self.compute_api = compute.API()
 
52
        self.last_call = {}
 
53
 
 
54
    def check_fping(self):
 
55
        if not os.access(CONF.fping_path, os.X_OK):
 
56
            raise exc.HTTPServiceUnavailable(
 
57
                explanation=_("fping utility is not found."))
 
58
 
 
59
    @staticmethod
 
60
    def fping(ips):
 
61
        fping_ret = utils.execute(CONF.fping_path, *ips,
 
62
                                  check_exit_code=False)
 
63
        if not fping_ret:
 
64
            return set()
 
65
        alive_ips = set()
 
66
        for line in fping_ret[0].split("\n"):
 
67
            ip = line.split(" ", 1)[0]
 
68
            if "alive" in line:
 
69
                alive_ips.add(ip)
 
70
        return alive_ips
 
71
 
 
72
    @staticmethod
 
73
    def _get_instance_ips(context, instance):
 
74
        ret = []
 
75
        for network in common.get_networks_for_instance(
 
76
                context, instance).values():
 
77
            all_ips = itertools.chain(network["ips"], network["floating_ips"])
 
78
            ret += [ip["address"] for ip in all_ips]
 
79
        return ret
 
80
 
 
81
    def index(self, req):
 
82
        context = req.environ["nova.context"]
 
83
        search_opts = dict(deleted=False)
 
84
        if "all_tenants" in req.GET:
 
85
            authorize_all_tenants(context)
 
86
        else:
 
87
            authorize(context)
 
88
            if context.project_id:
 
89
                search_opts["project_id"] = context.project_id
 
90
            else:
 
91
                search_opts["user_id"] = context.user_id
 
92
        self.check_fping()
 
93
        include = req.GET.get("include", None)
 
94
        if include:
 
95
            include = set(include.split(","))
 
96
            exclude = set()
 
97
        else:
 
98
            include = None
 
99
            exclude = req.GET.get("exclude", None)
 
100
            if exclude:
 
101
                exclude = set(exclude.split(","))
 
102
            else:
 
103
                exclude = set()
 
104
 
 
105
        instance_list = self.compute_api.get_all(
 
106
            context, search_opts=search_opts)
 
107
        ip_list = []
 
108
        instance_ips = {}
 
109
        instance_projects = {}
 
110
 
 
111
        for instance in instance_list:
 
112
            uuid = instance["uuid"]
 
113
            if uuid in exclude or (include is not None and
 
114
                                   uuid not in include):
 
115
                continue
 
116
            ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
 
117
            instance_ips[uuid] = ips
 
118
            instance_projects[uuid] = instance["project_id"]
 
119
            ip_list += ips
 
120
        alive_ips = self.fping(ip_list)
 
121
        res = []
 
122
        for instance_uuid, ips in instance_ips.iteritems():
 
123
            res.append({
 
124
                "id": instance_uuid,
 
125
                "project_id": instance_projects[instance_uuid],
 
126
                "alive": bool(set(ips) & alive_ips),
 
127
            })
 
128
        return {"servers": res}
 
129
 
 
130
    def show(self, req, id):
 
131
        try:
 
132
            context = req.environ["nova.context"]
 
133
            authorize(context)
 
134
            self.check_fping()
 
135
            instance = self.compute_api.get(context, id)
 
136
            ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
 
137
            alive_ips = self.fping(ips)
 
138
            return {
 
139
                "server": {
 
140
                    "id": instance["uuid"],
 
141
                    "project_id": instance["project_id"],
 
142
                    "alive": bool(set(ips) & alive_ips),
 
143
                }
 
144
            }
 
145
        except exception.NotFound:
 
146
            raise exc.HTTPNotFound()
 
147
 
 
148
 
 
149
class Fping(extensions.ExtensionDescriptor):
 
150
    """Fping Management Extension."""
 
151
 
 
152
    name = "Fping"
 
153
    alias = "os-fping"
 
154
    namespace = "http://docs.openstack.org/compute/ext/fping/api/v1.1"
 
155
    updated = "2012-07-06T00:00:00+00:00"
 
156
 
 
157
    def get_resources(self):
 
158
        res = extensions.ResourceExtension(
 
159
            "os-fping",
 
160
            FpingController())
 
161
        return [res]