Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_base.py @ 572e52bf

History | View | Annotate | Download (7.3 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007, 2008 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Base class for all hypervisors
23

24
"""
25

    
26
import re
27

    
28

    
29
from ganeti import errors
30

    
31

    
32
class BaseHypervisor(object):
33
  """Abstract virtualisation technology interface
34

35
  The goal is that all aspects of the virtualisation technology are
36
  abstracted away from the rest of code.
37

38
  """
39
  PARAMETERS = []
40

    
41
  def __init__(self):
42
    pass
43

    
44
  def StartInstance(self, instance, block_devices):
45
    """Start an instance."""
46
    raise NotImplementedError
47

    
48
  def StopInstance(self, instance, force=False):
49
    """Stop an instance."""
50
    raise NotImplementedError
51

    
52
  def RebootInstance(self, instance):
53
    """Reboot an instance."""
54
    raise NotImplementedError
55

    
56
  def ListInstances(self):
57
    """Get the list of running instances."""
58
    raise NotImplementedError
59

    
60
  def GetInstanceInfo(self, instance_name):
61
    """Get instance properties.
62

63
    @type instance_name: string
64
    @param instance_name: the instance name
65

66
    @return: tuple (name, id, memory, vcpus, state, times)
67

68
    """
69
    raise NotImplementedError
70

    
71
  def GetAllInstancesInfo(self):
72
    """Get properties of all instances.
73

74
    @return: list of tuples (name, id, memory, vcpus, stat, times)
75

76
    """
77
    raise NotImplementedError
78

    
79
  def GetNodeInfo(self):
80
    """Return information about the node.
81

82
    @return: a dict with the following keys (values in MiB):
83
          - memory_total: the total memory size on the node
84
          - memory_free: the available memory on the node for instances
85
          - memory_dom0: the memory used by the node itself, if available
86

87
    """
88
    raise NotImplementedError
89

    
90
  @classmethod
91
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
92
    """Return a command for connecting to the console of an instance.
93

94
    """
95
    raise NotImplementedError
96

    
97
  def Verify(self):
98
    """Verify the hypervisor.
99

100
    """
101
    raise NotImplementedError
102

    
103
  def MigrationInfo(self, instance):
104
    """Get instance information to perform a migration.
105

106
    By default assume no information is needed.
107

108
    @type instance: L{objects.Instance}
109
    @param instance: instance to be migrated
110
    @rtype: string/data (opaque)
111
    @return: instance migration information - serialized form
112

113
    """
114
    return ''
115

    
116
  def AcceptInstance(self, instance, info, target):
117
    """Prepare to accept an instance.
118

119
    By default assume no preparation is needed.
120

121
    @type instance: L{objects.Instance}
122
    @param instance: instance to be accepted
123
    @type info: string/data (opaque)
124
    @param info: migration information, from the source node
125
    @type target: string
126
    @param target: target host (usually ip), on this node
127

128
    """
129
    pass
130

    
131
  def FinalizeMigration(self, instance, info, success):
132
    """Finalized an instance migration.
133

134
    Should finalize or revert any preparation done to accept the instance.
135
    Since by default we do no preparation, we also don't have anything to do
136

137
    @type instance: L{objects.Instance}
138
    @param instance: instance whose migration is being aborted
139
    @type info: string/data (opaque)
140
    @param info: migration information, from the source node
141
    @type success: boolean
142
    @param success: whether the migration was a success or a failure
143

144
    """
145
    pass
146

    
147
  def MigrateInstance(self, name, target, live):
148
    """Migrate an instance.
149

150
    @type name: string
151
    @param name: name of the instance to be migrated
152
    @type target: string
153
    @param target: hostname (usually ip) of the target node
154
    @type live: boolean
155
    @param live: whether to do a live or non-live migration
156

157
    """
158
    raise NotImplementedError
159

    
160
  @classmethod
161
  def CheckParameterSyntax(cls, hvparams):
162
    """Check the given parameters for validity.
163

164
    This should check the passed set of parameters for
165
    validity. Classes should extend, not replace, this function.
166

167
    @type hvparams:  dict
168
    @param hvparams: dictionary with parameter names/value
169
    @raise errors.HypervisorError: when a parameter is not valid
170

171
    """
172
    for key in hvparams:
173
      if key not in cls.PARAMETERS:
174
        raise errors.HypervisorError("Hypervisor parameter '%s'"
175
                                     " not supported" % key)
176
    for key in cls.PARAMETERS:
177
      if key not in hvparams:
178
        raise errors.HypervisorError("Hypervisor parameter '%s'"
179
                                     " missing" % key)
180

    
181
  def ValidateParameters(self, hvparams):
182
    """Check the given parameters for validity.
183

184
    This should check the passed set of parameters for
185
    validity. Classes should extend, not replace, this function.
186

187
    @type hvparams:  dict
188
    @param hvparams: dictionary with parameter names/value
189
    @raise errors.HypervisorError: when a parameter is not valid
190

191
    """
192
    pass
193

    
194
  def GetLinuxNodeInfo(self):
195
    """For linux systems, return actual OS information.
196

197
    This is an abstraction for all non-hypervisor-based classes, where
198
    the node actually sees all the memory and CPUs via the /proc
199
    interface and standard commands. The other case if for example
200
    xen, where you only see the hardware resources via xen-specific
201
    tools.
202

203
    @return: a dict with the following keys (values in MiB):
204
          - memory_total: the total memory size on the node
205
          - memory_free: the available memory on the node for instances
206
          - memory_dom0: the memory used by the node itself, if available
207

208
    """
209
    try:
210
      fh = file("/proc/meminfo")
211
      try:
212
        data = fh.readlines()
213
      finally:
214
        fh.close()
215
    except EnvironmentError, err:
216
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
217

    
218
    result = {}
219
    sum_free = 0
220
    try:
221
      for line in data:
222
        splitfields = line.split(":", 1)
223

    
224
        if len(splitfields) > 1:
225
          key = splitfields[0].strip()
226
          val = splitfields[1].strip()
227
          if key == 'MemTotal':
228
            result['memory_total'] = int(val.split()[0])/1024
229
          elif key in ('MemFree', 'Buffers', 'Cached'):
230
            sum_free += int(val.split()[0])/1024
231
          elif key == 'Active':
232
            result['memory_dom0'] = int(val.split()[0])/1024
233
    except (ValueError, TypeError), err:
234
      raise errors.HypervisorError("Failed to compute memory usage: %s" %
235
                                   (err,))
236
    result['memory_free'] = sum_free
237

    
238
    cpu_total = 0
239
    try:
240
      fh = open("/proc/cpuinfo")
241
      try:
242
        cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
243
                                   fh.read()))
244
      finally:
245
        fh.close()
246
    except EnvironmentError, err:
247
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
248
    result['cpu_total'] = cpu_total
249
    # FIXME: export correct data here
250
    result['cpu_nodes'] = 1
251
    result['cpu_sockets'] = 1
252

    
253
    return result