Newer
Older
from cloudcontrol.server.handlers import listed
from cloudcontrol.server.clients import Client, RegisteredCCHandler
from cloudcontrol.server.clients.host import HostClient
from cloudcontrol.server.db import RemoteTag
from cloudcontrol.common.tql.db.object import TqlObject
from cloudcontrol.common.tql.db.tag import StaticTag
from functools import partial
class HypervisorHandler(RegisteredCCHandler):
""" Handler binded to an hv client.
"""
@listed
def register(self, obj_id, role):
""" Register an object managed by the calling node.
.. note:
the obj_id argument passed to this handler is the object id of the
registered object (not the fully qualified id, the server will
preprend the id by "node_id." itself).
:param obj_id: the id of the object to register
:param role: the role of the object to register
self.client.register(obj_id, role)
@listed
def unregister(self, obj_id):
""" Unregister an object managed by the calling node.
.. note:
the obj_id argument passed to this handler is the object id of the
unregistered object (not the fully qualified id, the server will
preprend the id by "node_id." itself).
:param obj_id: the id of the object to unregister
self.client.unregister(obj_id)
@listed
def sub_tags_register(self, obj_id, name, ttl=None, value=None):
""" Register a new remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to register
:param ttl: TTL of the tag if applicable (None = no TTL, the tag will
never expire)
:param value: value of the tag
"""
self.client.sub_tags_register(obj_id, name, ttl, value)
@listed
def sub_tags_unregister(self, obj_id, name):
""" Unregister a remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to unregister
"""
self.client.sub_tags_unregister(obj_id, name)
@listed
def sub_tags_drop(self, obj_id, name):
""" Drop the cached value of a remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to drop
"""
self.client.sub_tags_drop(obj_id, name)
@listed
def sub_tags_update(self, obj_id, name, value=None, ttl=None):
""" Update a remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to update
:param value: new value of the tag
:param ttl: new ttl of the tag
"""
self.client.sub_tags_update(obj_id, name, value, ttl)
class HvClient(HostClient):
""" A hv client connected to the cc-server.
"""
ROLE = 'hv'
RPC_HANDLER = HypervisorHandler
def __init__(self, *args, **kwargs):
super(HvClient, self).__init__(*args, **kwargs)
self._children = {}
self._hv_lock = threading.RLock()
@property
def hvlock(self):
""" The lock used on hypervirsors for migration.
"""
return self._hv_lock
#
# Children specific methods:
#
def shutdown(self):
# Unregister all children:
for child in self._children.copy():
self.unregister(child)
super(HvClient, self).shutdown()
def execute(self, command):
return self.conn.call('execute_command', command)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def get_child_remote_tags(self, obj_id, tag):
return self.conn.call('sub_tags', obj_id, (tag,))[tag]
def register(self, obj_id, role):
""" Register a new child.
"""
child = '%s.%s' % (self.login, obj_id)
# Register the children in the tags database:
obj = TqlObject(child)
obj.register(StaticTag('r', role))
obj.register(StaticTag('p', self.login))
self._server.db.register(obj)
self._children[obj_id] = obj
def unregister(self, obj_id):
""" Unregister a child.
"""
child = '%s.%s' % (self.login, obj_id)
del self._children[obj_id]
# Unregister the children from the tags database:
self._server.db.unregister(child)
def vm_action(self, action, vms):
return self.conn.call(action, vms)
def sub_tags_register(self, obj_id, name, ttl=None, value=None):
""" Register a new remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to register
:param ttl: TTL of the tag if applicable (None = no TTL, the tag will
never expire)
:param value: value of the tag
"""
callback = partial(self.async_remote_sub_tags, obj_id)
tag = RemoteTag(name, callback, ttl=ttl)
self._children[obj_id].register(tag)
def sub_tags_unregister(self, obj_id, name):
""" Unregister a remote tag for a child of the client.
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
:param obj_id: child name
:param name: name of the tag to unregister
"""
self._children[obj_id].unregister(name)
def sub_tags_drop(self, obj_id, name):
""" Drop the cached value of a remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to drop
"""
tag = self._children[obj_id].get(name)
if tag is not None:
tag.invalidate()
def sub_tags_update(self, obj_id, name, value=None, ttl=None):
""" Update a remote tag for a child of the client.
:param obj_id: child name
:param name: name of the tag to update
:param value: new value of the tag
:param ttl: new ttl of the tag
"""
tag = self._children[obj_id].get(name)
if tag is not None:
if value is not None:
if ttl is not None:
tag.ttl = ttl
def async_remote_sub_tags(self, obj_id, watcher, robj, tags):
""" Asynchronously update sub tags from the remote client using
specified watcher.
"""
watcher.register(self.conn, 'sub_tags', obj_id, tags, _data=(tags, robj))
Client.register_client_class(HvClient)