Newer
Older
# Gerer le cas ou le mdp n'est pa valable
#TODO: catch livbirt disconnection errors and handle it
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
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
#do not detect hypervisor if connection is disable in configuration
if config[skip_hypervisor]:
logging.debug('Hypervisor detection disabled, running as regular'
' node')
self.hv_handle = Host()
else:
#we set our hypervisor handle
#FIXME: must be aware of hypervisor type
logging.debug('Initializing a connection on the hypervisor')
self.hv_handle = KvmHypervisor()
logging.debug('Initialized connection to a KVM hypervisor')
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
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 = {}
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
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, force=False):
'''
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 force: soft shutown or force poweroff
:type force: either True or False
#fetch all vm names in hypervisor
vm_names = gen_vm_names(self.hv_handle)
logging.debug('stop_vm: stopping vms %s' % vm_names)
for vm in vm_names:
try:
except VMError as err:
logging.warning('Error while stopping %s: %s' % (vm, err))
else:
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 = gen_vm_names(self.hv_handle)
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))
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
else:
logging.info('start_vm: vm %s starting' % vm)
@pure
def suspend_vm(self, vm_names=None):
'''
Suspends the specifed list of vms
If vm_names is None all vms in hypervisor will be suspended
:param vm_names: the list of vms to suspend
:type vm_names: :class:`list` of strings
'''
if vm_names is None:
vm_names = gen_vm_names(self.hv_handle)
logging.debug('suspend_vm: suspending vms %s' % vm_names)
for vm in vm_names:
try:
self.hv_handle.suspend_vm(vm)
except VMError as err:
logging.info('Error while suspending %s: %s' % (vm, err))
else:
logging.info('suspend_vm: vm %s suspended' % vm)
@pure
def resume_vm(self, vm_names=None):
'''
Resumes the specified list of vms
If vm_names is None all vms in hypervisor will be resumed
:param vm_names: the list of vms to resume
:type vm_names: :class:`str`
'''
if vm_names is None:
vm_names = gen_vm_names(self.hv_handle)
logging.debug('resume_vm: resuming vms %s' % vm_names)
for vm in vm_names:
try:
self.hv_handle.resume_vm(vm)
except VMError as err:
logging.info('Error while resuming %s: %s' % (vm, err))
else:
logging.info('resume_vm: vm %s resumed' % vm)
@pure
def execute_command(self, command):
'''
:param command: the command to execute as it would be typed on a shell
prompt
:type command: :class:`str`
'''