~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/objects/aggregate.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2013-09-09 13:11:11 UTC
  • mfrom: (1.1.74)
  • Revision ID: package-import@ubuntu.com-20130909131111-aw02ice50wac9tma
Tags: 1:2013.2~b3-0ubuntu1
* New usptream release. 
* debian/patches/avoid_requirements_cheetah.patch: Dropped
* debian/patches/fix-sqlalchemy-0.7.9-usage.patch: Dropped
* debian/patches/fix-requirements.patch: Refreshed.
* debian/patches/path-to-the-xenhost.conf-fixup.patch: Refreshed
* debian/control: Add python-jinja2
* debian/control: Dropped python-cheetah

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#    Copyright 2013 IBM Corp.
 
2
#
 
3
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
4
#    not use this file except in compliance with the License. You may obtain
 
5
#    a copy of the License at
 
6
#
 
7
#         http://www.apache.org/licenses/LICENSE-2.0
 
8
#
 
9
#    Unless required by applicable law or agreed to in writing, software
 
10
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
11
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
12
#    License for the specific language governing permissions and limitations
 
13
#    under the License.
 
14
 
 
15
from nova.compute import utils as compute_utils
 
16
from nova import db
 
17
from nova import exception
 
18
from nova.objects import base
 
19
from nova.objects import utils
 
20
 
 
21
 
 
22
class Aggregate(base.NovaObject):
 
23
    fields = {
 
24
        'id': int,
 
25
        'name': str,
 
26
        'hosts': utils.list_of_strings_or_none,
 
27
        'metadata': utils.dict_of_strings_or_none,
 
28
        }
 
29
 
 
30
    obj_extra_fields = ['availability_zone']
 
31
 
 
32
    @staticmethod
 
33
    def _from_db_object(context, aggregate, db_aggregate):
 
34
        for key in aggregate.fields:
 
35
            if key == 'metadata':
 
36
                db_key = 'metadetails'
 
37
            else:
 
38
                db_key = key
 
39
            aggregate[key] = db_aggregate[db_key]
 
40
        aggregate._context = context
 
41
        aggregate.obj_reset_changes()
 
42
        return aggregate
 
43
 
 
44
    def _assert_no_hosts(self, action):
 
45
        if 'hosts' in self.obj_what_changed():
 
46
            raise exception.ObjectActionError(
 
47
                action=action,
 
48
                reason='hosts updated inline')
 
49
 
 
50
    @base.remotable_classmethod
 
51
    def get_by_id(cls, context, aggregate_id):
 
52
        db_aggregate = db.aggregate_get(context, aggregate_id)
 
53
        return cls._from_db_object(context, cls(), db_aggregate)
 
54
 
 
55
    @base.remotable
 
56
    def create(self, context):
 
57
        self._assert_no_hosts('create')
 
58
        updates = {}
 
59
        for key in self.obj_what_changed():
 
60
            updates[key] = self[key]
 
61
        payload = dict(updates)
 
62
        if 'metadata' in updates:
 
63
            # NOTE(danms): For some reason the notification format is weird
 
64
            payload['meta_data'] = payload.pop('metadata')
 
65
        compute_utils.notify_about_aggregate_update(context,
 
66
                                                    "create.start",
 
67
                                                    payload)
 
68
        metadata = updates.pop('metadata', None)
 
69
        db_aggregate = db.aggregate_create(context, updates, metadata=metadata)
 
70
        self._from_db_object(context, self, db_aggregate)
 
71
        payload['aggregate_id'] = self.id
 
72
        compute_utils.notify_about_aggregate_update(context,
 
73
                                                    "create.end",
 
74
                                                    payload)
 
75
 
 
76
    @base.remotable
 
77
    def save(self, context):
 
78
        self._assert_no_hosts('save')
 
79
        updates = {}
 
80
        for key in self.obj_what_changed():
 
81
            updates[key] = self[key]
 
82
 
 
83
        payload = {'aggregate_id': self.id}
 
84
        if 'metadata' in updates:
 
85
            payload['meta_data'] = updates['metadata']
 
86
        compute_utils.notify_about_aggregate_update(context,
 
87
                                                    "updateprop.start",
 
88
                                                    payload)
 
89
        updates.pop('id', None)
 
90
        db_aggregate = db.aggregate_update(context, self.id, updates)
 
91
        compute_utils.notify_about_aggregate_update(context,
 
92
                                                    "updateprop.end",
 
93
                                                    payload)
 
94
        return self._from_db_object(context, self, db_aggregate)
 
95
 
 
96
    @base.remotable
 
97
    def update_metadata(self, context, updates):
 
98
        payload = {'aggregate_id': self.id,
 
99
                   'meta_data': updates}
 
100
        compute_utils.notify_about_aggregate_update(context,
 
101
                                                    "updatemetadata.start",
 
102
                                                    payload)
 
103
        to_add = {}
 
104
        for key, value in updates.items():
 
105
            if value is None:
 
106
                try:
 
107
                    db.aggregate_metadata_delete(context, self.id, key)
 
108
                except exception.AggregateMetadataNotFound:
 
109
                    pass
 
110
                try:
 
111
                    self.metadata.pop(key)
 
112
                except KeyError:
 
113
                    pass
 
114
            else:
 
115
                to_add[key] = value
 
116
                self.metadata[key] = value
 
117
        db.aggregate_metadata_add(context, self.id, to_add)
 
118
        payload['meta_data'] = to_add
 
119
        compute_utils.notify_about_aggregate_update(context,
 
120
                                                    "updatemetadata.end",
 
121
                                                    payload)
 
122
        self.obj_reset_changes(fields=['metadata'])
 
123
 
 
124
    @base.remotable
 
125
    def destroy(self, context):
 
126
        db.aggregate_delete(context, self.id)
 
127
 
 
128
    @base.remotable
 
129
    def add_host(self, context, host):
 
130
        db.aggregate_host_add(context, self.id, host)
 
131
        if self.hosts is None:
 
132
            self.hosts = []
 
133
        self.hosts.append(host)
 
134
        self.obj_reset_changes(fields=['hosts'])
 
135
 
 
136
    @base.remotable
 
137
    def delete_host(self, context, host):
 
138
        db.aggregate_host_delete(context, self.id, host)
 
139
        self.hosts.remove(host)
 
140
        self.obj_reset_changes(fields=['hosts'])
 
141
 
 
142
    @property
 
143
    def availability_zone(self):
 
144
        return self.metadata.get('availability_zone', None)
 
145
 
 
146
 
 
147
class AggregateList(base.ObjectListBase, base.NovaObject):
 
148
    @base.remotable_classmethod
 
149
    def get_all(cls, context):
 
150
        db_aggregates = db.aggregate_get_all(context)
 
151
        return base.obj_make_list(context, AggregateList(), Aggregate,
 
152
                                  db_aggregates)
 
153
 
 
154
    @base.remotable_classmethod
 
155
    def get_by_host(cls, context, host):
 
156
        db_aggregates = db.aggregate_get_by_host(context, host)
 
157
        return base.obj_make_list(context, AggregateList(), Aggregate,
 
158
                                  db_aggregates)