Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
155
156
157
158
159
160
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
189
190
191
192
193
194
195
196
197
198
199
# Gerer le cas ou le mdp n'est pa valable
#TODO: catch livbirt disconnection errors and handle it
from kvm import *
from sjrpc.utils import RpcHandler
from sjrpc.utils import pure
from sjrpc.core import RpcError
from exceptions import VMError
import logging
############
## Constants
############
# Logging errors
TAG_METHOD_ERROR = 'No method found in hypervisor to handle tag %s'
TAG_NOT_FOUND_ERROR = 'Tag %s requested but unknown in node handler'
# Tags to method mappings
# Hypervisor
HV_TAG_MAP = {
'hostname' : 'get_name',
'htype' : 'get_hv_type',
'hver' : 'get_hv_version',
'arch' : 'get_arch_type',
'cpus' : 'get_nb_cpu',
'cpu_freq' : 'get_cpu_frequency',
'status' : 'get_status',
'cpu' : 'get_cpu_percent',
'mem_used' : 'get_used_mem',
'mem_avail' : 'get_free_mem',
'mem_total': 'get_total_mem'
}
# Vm
VM_TAG_MAP = {
'vm' : 'get_name',
'vcpus' : 'get_vcpu',
'status' : 'get_status',
'cpu' : 'get_cpu_percent',
'vmem_used' : 'get_used_mem',
'vmem_avail' : 'get_free_mem',
'vmem_total' : 'get_total_mem'
}
class NodeHandler(RpcHandler):
'''
This is the main node handler that exports the hypervisor
capabilities to any connected server. In other terms this is
the node interface to the server.
'''
def __init__(self, connection):
super(RpcHandler, self).__init__()
self._connection = connection
#we set our hypervisor handle
#FIXME: must be aware of hypervisor type
logging.debug('Initializing a handle over the hypervisor')
self.hv_handle = KvmHypervisor()
def _call_hv_method(self, method):
'''
Calls the given method in the :class:`Hypervisor` instance
Returns the result of the method called
:param method: the method to be called
:type method: :class:`str`
'''
result = getattr(self.hv_handle, HV_TAG_MAP[method])()
return result
def _call_vm_method(self, vm, method):
'''
Calls the given method in vm instance
Returns the result of the method called
:param vm: The vm object in which call the method
:vm type: :class:`VM`
:param method: the method to be called
:type method: :class:`str`
'''
result = getattr(vm, VM_TAG_MAP[method])()
return result
@pure
def get_tags(self, tags=None):
'''
Return tags bound to hypervisor specified in tags parameter otherwise
returns all
:param tags: list of tags or None
:type tags: :class:`list`
'''
result = {}
logging.debug('get_tags: Fetching tags -> %s' % tags)
if tags is None:
tags = HV_TAG_MAP.keys()
logging.debug('get_tags: processing tags %s' % tags)
for tag in tags:
try:
result[tag] = self._call_hv_method(tag)
except AttributeError:
logging.warning(TAG_METHOD_ERROR % tag)
except KeyError:
logging.warning(TAG_NOT_FOUND_ERROR % tag)
except NotImplementedError:
logging.debug('get_tags: no method in hypervisor to handle %s' % tag)
logging.debug('get_tags: returning -> %s' % result)
return result
@pure
def list_vm(self, vm_names=None, tags=None):
'''
Return a list of vm tags
:param vm_names: vm names
:type vm_names: :class:`list` of strings
:param tags: tags to be returned
:type tags: :class:`list` of strings
'''
vms_info = []
vm_info = {}
tags = VM_TAG_MAP.keys() if tags is None else tags
logging.debug('list_vm: processing tags %s' % tags)
# ensure that vm name is always returned
if not tags.__contains__('vm'):
tags.insert(0, 'vm')
logging.debug('list_vm: fetching tag list %s' % tags)
for vm in self.hv_handle.get_vms():
for tag in tags:
try:
vm_info[tag] = self._call_vm_method(vm, tag)
except AttributeError:
logging.warning(TAG_METHOD_ERROR % tag)
except KeyError:
logging.warning(TAG_NOT_FOUND_ERROR % tag)
except NotImplementedError:
logging.debug('list_vm: method in vm to handle %s' % tag)
vms_info.append(vm_info)
vm_info = {}
if vm_names:
logging.debug('list_vm: filtering tag results for vms %s' % vm_names)
filterd_vms = [vm for vm in vms_info if vm['vm'] in vm_names]
logging.debug('list_vm: returning -> %s' % filterd_vms)
return filterd_vms
else:
logging.debug('list_vm: returning -> %s' % vms_info)
return vms_info
@pure
def stop_vm(self, vm_names=None, stop_mode=SOFT_VM_POWEROFF):
'''
Stop the specified list of vm names
This method do a soft shutdown on the Virtual Machine
If vm_names is None all vms in hypervisor will be stopped
:param vm_names: the list of vm names to stop
:vm_names type: :class:`list` of strings
:param stop_mode: soft shutown or force poweroff
:type stop_mode: either `FORCE_VM_POWEROFF` or `SOFT_VM_POWEROFF`
default is SOFT_VM_POWEROFF
'''
if vm_names is None:
vm_names = [vm.get_name() for vm in self.hv_handle._vm_list]
logging.debug('stop_vm: stopping vms %s' % vm_names)
for vm in vm_names:
try:
self.hv_handle.stop_vm(vm, stop_mode)
except VMError as err:
logging.warning('Error while stopping %s: %s' % (vm, err))
continue
logging.info('stop_vm: vm %s stopping' % vm)
@pure
def start_vm(self, vm_names=None):
'''
Starts the specified list of vms
If vm_names is None all vms in the hypervisor will be started
:param vm_names: the list of vms to start
:type vm_names: :class:`list` of strings
'''
if vm_names is None:
vm_names = [vm.get_name() for vm in self.hv_handle._vm_list]
logging.debug('start_vm: starting vms %s' % vm_names)
for vm in vm_names:
try:
self.hv_handle.start_vm(vm)
except VMError as err:
logging.warning('Error while starting %s: %s' % (vm ,err))
continue
logging.info('start_vm: vm %s starting' % vm)