Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_base.py @ eb70f6cf

History | View | Annotate | Download (16.5 kB)

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

24 205ab586 Iustin Pop
The syntax for the _CHECK variables and the contents of the PARAMETERS
25 205ab586 Iustin Pop
dict is the same, see the docstring for L{BaseHypervisor.PARAMETERS}.
26 205ab586 Iustin Pop

27 205ab586 Iustin Pop
@var _FILE_CHECK: stub for file checks, without the required flag
28 205ab586 Iustin Pop
@var _DIR_CHECK: stub for directory checks, without the required flag
29 205ab586 Iustin Pop
@var REQ_FILE_CHECK: mandatory file parameter
30 205ab586 Iustin Pop
@var OPT_FILE_CHECK: optional file parameter
31 205ab586 Iustin Pop
@var REQ_DIR_CHECK: mandatory directory parametr
32 205ab586 Iustin Pop
@var OPT_DIR_CHECK: optional directory parameter
33 205ab586 Iustin Pop
@var NO_CHECK: parameter without any checks at all
34 205ab586 Iustin Pop
@var REQUIRED_CHECK: parameter required to exist (and non-false), but
35 205ab586 Iustin Pop
    without other checks; beware that this can't be used for boolean
36 205ab586 Iustin Pop
    parameters, where you should use NO_CHECK or a custom checker
37 205ab586 Iustin Pop

38 65a6f9b7 Michael Hanselmann
"""
39 65a6f9b7 Michael Hanselmann
40 205ab586 Iustin Pop
import os
41 572e52bf Iustin Pop
import re
42 29921401 Iustin Pop
import logging
43 572e52bf Iustin Pop
44 572e52bf Iustin Pop
45 f48148c3 Iustin Pop
from ganeti import errors
46 205ab586 Iustin Pop
from ganeti import utils
47 e71b9ef4 Iustin Pop
from ganeti import constants
48 205ab586 Iustin Pop
49 205ab586 Iustin Pop
50 e3ed5316 Balazs Lecz
def _IsCpuMaskWellFormed(cpu_mask):
51 b9511385 Tsachy Shacham
  """Verifies if the given single CPU mask is valid
52 b9511385 Tsachy Shacham

53 b9511385 Tsachy Shacham
  The single CPU mask should be in the form "a,b,c,d", where each
54 b9511385 Tsachy Shacham
  letter is a positive number or range.
55 b9511385 Tsachy Shacham

56 b9511385 Tsachy Shacham
  """
57 e3ed5316 Balazs Lecz
  try:
58 e3ed5316 Balazs Lecz
    cpu_list = utils.ParseCpuMask(cpu_mask)
59 e3ed5316 Balazs Lecz
  except errors.ParseError, _:
60 e3ed5316 Balazs Lecz
    return False
61 e3ed5316 Balazs Lecz
  return isinstance(cpu_list, list) and len(cpu_list) > 0
62 e3ed5316 Balazs Lecz
63 e3ed5316 Balazs Lecz
64 b9511385 Tsachy Shacham
def _IsMultiCpuMaskWellFormed(cpu_mask):
65 b9511385 Tsachy Shacham
  """Verifies if the given multiple CPU mask is valid
66 b9511385 Tsachy Shacham

67 b9511385 Tsachy Shacham
  A valid multiple CPU mask is in the form "a:b:c:d", where each
68 b9511385 Tsachy Shacham
  letter is a single CPU mask.
69 b9511385 Tsachy Shacham

70 b9511385 Tsachy Shacham
  """
71 b9511385 Tsachy Shacham
  try:
72 b9511385 Tsachy Shacham
    utils.ParseMultiCpuMask(cpu_mask)
73 b9511385 Tsachy Shacham
  except errors.ParseError, _:
74 b9511385 Tsachy Shacham
    return False
75 b9511385 Tsachy Shacham
76 b9511385 Tsachy Shacham
  return True
77 b9511385 Tsachy Shacham
78 b9511385 Tsachy Shacham
79 205ab586 Iustin Pop
# Read the BaseHypervisor.PARAMETERS docstring for the syntax of the
80 205ab586 Iustin Pop
# _CHECK values
81 205ab586 Iustin Pop
82 205ab586 Iustin Pop
# must be afile
83 17c61836 Guido Trotter
_FILE_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
84 205ab586 Iustin Pop
              os.path.isfile, "not found or not a file")
85 205ab586 Iustin Pop
86 205ab586 Iustin Pop
# must be a directory
87 17c61836 Guido Trotter
_DIR_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
88 205ab586 Iustin Pop
             os.path.isdir, "not found or not a directory")
89 205ab586 Iustin Pop
90 e3ed5316 Balazs Lecz
# CPU mask must be well-formed
91 e3ed5316 Balazs Lecz
# TODO: implement node level check for the CPU mask
92 e3ed5316 Balazs Lecz
_CPU_MASK_CHECK = (_IsCpuMaskWellFormed,
93 e3ed5316 Balazs Lecz
                   "CPU mask definition is not well-formed",
94 e3ed5316 Balazs Lecz
                   None, None)
95 e3ed5316 Balazs Lecz
96 b9511385 Tsachy Shacham
# Multiple CPU mask must be well-formed
97 b9511385 Tsachy Shacham
_MULTI_CPU_MASK_CHECK = (_IsMultiCpuMaskWellFormed,
98 b9511385 Tsachy Shacham
                         "Multiple CPU mask definition is not well-formed",
99 b9511385 Tsachy Shacham
                         None, None)
100 b9511385 Tsachy Shacham
101 e2d14329 Andrea Spadaccini
# Check for validity of port number
102 e2d14329 Andrea Spadaccini
_NET_PORT_CHECK = (lambda x: 0 < x < 65535, "invalid port number",
103 e2d14329 Andrea Spadaccini
                   None, None)
104 e2d14329 Andrea Spadaccini
105 205ab586 Iustin Pop
# nice wrappers for users
106 205ab586 Iustin Pop
REQ_FILE_CHECK = (True, ) + _FILE_CHECK
107 205ab586 Iustin Pop
OPT_FILE_CHECK = (False, ) + _FILE_CHECK
108 205ab586 Iustin Pop
REQ_DIR_CHECK = (True, ) + _DIR_CHECK
109 205ab586 Iustin Pop
OPT_DIR_CHECK = (False, ) + _DIR_CHECK
110 e2d14329 Andrea Spadaccini
REQ_NET_PORT_CHECK = (True, ) + _NET_PORT_CHECK
111 e2d14329 Andrea Spadaccini
OPT_NET_PORT_CHECK = (False, ) + _NET_PORT_CHECK
112 e3ed5316 Balazs Lecz
REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK
113 e2d14329 Andrea Spadaccini
OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK
114 b9511385 Tsachy Shacham
REQ_MULTI_CPU_MASK_CHECK = (True, ) + _MULTI_CPU_MASK_CHECK
115 b9511385 Tsachy Shacham
OPT_MULTI_CPU_MASK_CHECK = (False, ) + _MULTI_CPU_MASK_CHECK
116 205ab586 Iustin Pop
117 205ab586 Iustin Pop
# no checks at all
118 205ab586 Iustin Pop
NO_CHECK = (False, None, None, None, None)
119 205ab586 Iustin Pop
120 205ab586 Iustin Pop
# required, but no other checks
121 205ab586 Iustin Pop
REQUIRED_CHECK = (True, None, None, None, None)
122 205ab586 Iustin Pop
123 e71b9ef4 Iustin Pop
# migration type
124 783a6c0b Iustin Pop
MIGRATION_MODE_CHECK = (True, lambda x: x in constants.HT_MIGRATION_MODES,
125 783a6c0b Iustin Pop
                        "invalid migration mode", None, None)
126 e71b9ef4 Iustin Pop
127 d73ef63f Michael Hanselmann
128 205ab586 Iustin Pop
def ParamInSet(required, my_set):
129 205ab586 Iustin Pop
  """Builds parameter checker for set membership.
130 205ab586 Iustin Pop

131 205ab586 Iustin Pop
  @type required: boolean
132 205ab586 Iustin Pop
  @param required: whether this is a required parameter
133 205ab586 Iustin Pop
  @type my_set: tuple, list or set
134 205ab586 Iustin Pop
  @param my_set: allowed values set
135 205ab586 Iustin Pop

136 205ab586 Iustin Pop
  """
137 205ab586 Iustin Pop
  fn = lambda x: x in my_set
138 ab3e6da8 Iustin Pop
  err = ("The value must be one of: %s" % utils.CommaJoin(my_set))
139 205ab586 Iustin Pop
  return (required, fn, err, None, None)
140 f48148c3 Iustin Pop
141 f48148c3 Iustin Pop
142 65a6f9b7 Michael Hanselmann
class BaseHypervisor(object):
143 65a6f9b7 Michael Hanselmann
  """Abstract virtualisation technology interface
144 65a6f9b7 Michael Hanselmann

145 f48148c3 Iustin Pop
  The goal is that all aspects of the virtualisation technology are
146 f48148c3 Iustin Pop
  abstracted away from the rest of code.
147 65a6f9b7 Michael Hanselmann

148 205ab586 Iustin Pop
  @cvar PARAMETERS: a dict of parameter name: check type; the check type is
149 205ab586 Iustin Pop
      a five-tuple containing:
150 205ab586 Iustin Pop
          - the required flag (boolean)
151 205ab586 Iustin Pop
          - a function to check for syntax, that will be used in
152 205ab586 Iustin Pop
            L{CheckParameterSyntax}, in the master daemon process
153 205ab586 Iustin Pop
          - an error message for the above function
154 205ab586 Iustin Pop
          - a function to check for parameter validity on the remote node,
155 205ab586 Iustin Pop
            in the L{ValidateParameters} function
156 205ab586 Iustin Pop
          - an error message for the above function
157 d271c6fd Iustin Pop
  @type CAN_MIGRATE: boolean
158 d271c6fd Iustin Pop
  @cvar CAN_MIGRATE: whether this hypervisor can do migration (either
159 d271c6fd Iustin Pop
      live or non-live)
160 205ab586 Iustin Pop

161 65a6f9b7 Michael Hanselmann
  """
162 205ab586 Iustin Pop
  PARAMETERS = {}
163 e1b8653f Guido Trotter
  ANCILLARY_FILES = []
164 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = []
165 d271c6fd Iustin Pop
  CAN_MIGRATE = False
166 f48148c3 Iustin Pop
167 65a6f9b7 Michael Hanselmann
  def __init__(self):
168 65a6f9b7 Michael Hanselmann
    pass
169 65a6f9b7 Michael Hanselmann
170 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
171 65a6f9b7 Michael Hanselmann
    """Start an instance."""
172 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
173 65a6f9b7 Michael Hanselmann
174 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
175 07b49e41 Guido Trotter
    """Stop an instance
176 07b49e41 Guido Trotter

177 07b49e41 Guido Trotter
    @type instance: L{objects.Instance}
178 07b49e41 Guido Trotter
    @param instance: instance to stop
179 07b49e41 Guido Trotter
    @type force: boolean
180 07b49e41 Guido Trotter
    @param force: whether to do a "hard" stop (destroy)
181 07b49e41 Guido Trotter
    @type retry: boolean
182 07b49e41 Guido Trotter
    @param retry: whether this is just a retry call
183 bbcf7ad0 Iustin Pop
    @type name: string or None
184 bbcf7ad0 Iustin Pop
    @param name: if this parameter is passed, the the instance object
185 bbcf7ad0 Iustin Pop
        should not be used (will be passed as None), and the shutdown
186 bbcf7ad0 Iustin Pop
        must be done by name only
187 07b49e41 Guido Trotter

188 07b49e41 Guido Trotter
    """
189 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
190 65a6f9b7 Michael Hanselmann
191 f28ec899 Guido Trotter
  def CleanupInstance(self, instance_name):
192 f28ec899 Guido Trotter
    """Cleanup after a stopped instance
193 f28ec899 Guido Trotter

194 f28ec899 Guido Trotter
    This is an optional method, used by hypervisors that need to cleanup after
195 f28ec899 Guido Trotter
    an instance has been stopped.
196 f28ec899 Guido Trotter

197 f28ec899 Guido Trotter
    @type instance_name: string
198 f28ec899 Guido Trotter
    @param instance_name: instance name to cleanup after
199 f28ec899 Guido Trotter

200 f28ec899 Guido Trotter
    """
201 f28ec899 Guido Trotter
    pass
202 f28ec899 Guido Trotter
203 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
204 65a6f9b7 Michael Hanselmann
    """Reboot an instance."""
205 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
206 65a6f9b7 Michael Hanselmann
207 65a6f9b7 Michael Hanselmann
  def ListInstances(self):
208 65a6f9b7 Michael Hanselmann
    """Get the list of running instances."""
209 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
210 65a6f9b7 Michael Hanselmann
211 65a6f9b7 Michael Hanselmann
  def GetInstanceInfo(self, instance_name):
212 65a6f9b7 Michael Hanselmann
    """Get instance properties.
213 65a6f9b7 Michael Hanselmann

214 cd42d0ad Guido Trotter
    @type instance_name: string
215 c41eea6e Iustin Pop
    @param instance_name: the instance name
216 65a6f9b7 Michael Hanselmann

217 c41eea6e Iustin Pop
    @return: tuple (name, id, memory, vcpus, state, times)
218 65a6f9b7 Michael Hanselmann

219 65a6f9b7 Michael Hanselmann
    """
220 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
221 65a6f9b7 Michael Hanselmann
222 65a6f9b7 Michael Hanselmann
  def GetAllInstancesInfo(self):
223 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
224 65a6f9b7 Michael Hanselmann

225 c41eea6e Iustin Pop
    @return: list of tuples (name, id, memory, vcpus, stat, times)
226 c41eea6e Iustin Pop

227 65a6f9b7 Michael Hanselmann
    """
228 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
229 65a6f9b7 Michael Hanselmann
230 65a6f9b7 Michael Hanselmann
  def GetNodeInfo(self):
231 65a6f9b7 Michael Hanselmann
    """Return information about the node.
232 65a6f9b7 Michael Hanselmann

233 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
234 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
235 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
236 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
237 65a6f9b7 Michael Hanselmann

238 65a6f9b7 Michael Hanselmann
    """
239 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
240 65a6f9b7 Michael Hanselmann
241 637ce7f9 Guido Trotter
  @classmethod
242 55cc0a44 Michael Hanselmann
  def GetInstanceConsole(cls, instance, hvparams, beparams):
243 55cc0a44 Michael Hanselmann
    """Return information for connecting to the console of an instance.
244 65a6f9b7 Michael Hanselmann

245 65a6f9b7 Michael Hanselmann
    """
246 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
247 65a6f9b7 Michael Hanselmann
248 e1b8653f Guido Trotter
  @classmethod
249 e1b8653f Guido Trotter
  def GetAncillaryFiles(cls):
250 e1b8653f Guido Trotter
    """Return a list of ancillary files to be copied to all nodes as ancillary
251 e1b8653f Guido Trotter
    configuration files.
252 e1b8653f Guido Trotter

253 69ab2e12 Guido Trotter
    @rtype: (list of absolute paths, list of absolute paths)
254 69ab2e12 Guido Trotter
    @return: (all files, optional files)
255 e1b8653f Guido Trotter

256 e1b8653f Guido Trotter
    """
257 e1b8653f Guido Trotter
    # By default we return a member variable, so that if an hypervisor has just
258 e1b8653f Guido Trotter
    # a static list of files it doesn't have to override this function.
259 69ab2e12 Guido Trotter
    assert set(cls.ANCILLARY_FILES).issuperset(cls.ANCILLARY_FILES_OPT), \
260 69ab2e12 Guido Trotter
      "Optional ancillary files must be a subset of ancillary files"
261 69ab2e12 Guido Trotter
262 69ab2e12 Guido Trotter
    return (cls.ANCILLARY_FILES, cls.ANCILLARY_FILES_OPT)
263 e1b8653f Guido Trotter
264 65a6f9b7 Michael Hanselmann
  def Verify(self):
265 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
266 65a6f9b7 Michael Hanselmann

267 65a6f9b7 Michael Hanselmann
    """
268 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
269 6e7275c0 Iustin Pop
270 b459a848 Andrea Spadaccini
  def MigrationInfo(self, instance): # pylint: disable=R0201,W0613
271 cd42d0ad Guido Trotter
    """Get instance information to perform a migration.
272 cd42d0ad Guido Trotter

273 cd42d0ad Guido Trotter
    By default assume no information is needed.
274 cd42d0ad Guido Trotter

275 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
276 cd42d0ad Guido Trotter
    @param instance: instance to be migrated
277 cd42d0ad Guido Trotter
    @rtype: string/data (opaque)
278 cd42d0ad Guido Trotter
    @return: instance migration information - serialized form
279 cd42d0ad Guido Trotter

280 cd42d0ad Guido Trotter
    """
281 d0c8c01d Iustin Pop
    return ""
282 cd42d0ad Guido Trotter
283 cd42d0ad Guido Trotter
  def AcceptInstance(self, instance, info, target):
284 cd42d0ad Guido Trotter
    """Prepare to accept an instance.
285 cd42d0ad Guido Trotter

286 cd42d0ad Guido Trotter
    By default assume no preparation is needed.
287 cd42d0ad Guido Trotter

288 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
289 cd42d0ad Guido Trotter
    @param instance: instance to be accepted
290 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
291 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
292 cd42d0ad Guido Trotter
    @type target: string
293 cd42d0ad Guido Trotter
    @param target: target host (usually ip), on this node
294 cd42d0ad Guido Trotter

295 cd42d0ad Guido Trotter
    """
296 cd42d0ad Guido Trotter
    pass
297 cd42d0ad Guido Trotter
298 b990eedd Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
299 b990eedd Guido Trotter
    """Balloon an instance memory to a certain value.
300 b990eedd Guido Trotter

301 b990eedd Guido Trotter
    @type instance: L{objects.Instance}
302 b990eedd Guido Trotter
    @param instance: instance to be accepted
303 b990eedd Guido Trotter
    @type mem: int
304 b990eedd Guido Trotter
    @param mem: actual memory size to use for instance runtime
305 b990eedd Guido Trotter

306 b990eedd Guido Trotter
    """
307 b990eedd Guido Trotter
    raise NotImplementedError
308 b990eedd Guido Trotter
309 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
310 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
311 cd42d0ad Guido Trotter

312 cd42d0ad Guido Trotter
    Should finalize or revert any preparation done to accept the instance.
313 cd42d0ad Guido Trotter
    Since by default we do no preparation, we also don't have anything to do
314 cd42d0ad Guido Trotter

315 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
316 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
317 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
318 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
319 cd42d0ad Guido Trotter
    @type success: boolean
320 cd42d0ad Guido Trotter
    @param success: whether the migration was a success or a failure
321 cd42d0ad Guido Trotter

322 cd42d0ad Guido Trotter
    """
323 cd42d0ad Guido Trotter
    pass
324 cd42d0ad Guido Trotter
325 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
326 6e7275c0 Iustin Pop
    """Migrate an instance.
327 6e7275c0 Iustin Pop

328 3a488770 Iustin Pop
    @type instance: L{objects.Instance}
329 9044275a Michael Hanselmann
    @param instance: the instance to be migrated
330 cd42d0ad Guido Trotter
    @type target: string
331 cd42d0ad Guido Trotter
    @param target: hostname (usually ip) of the target node
332 cd42d0ad Guido Trotter
    @type live: boolean
333 cd42d0ad Guido Trotter
    @param live: whether to do a live or non-live migration
334 6e7275c0 Iustin Pop

335 6e7275c0 Iustin Pop
    """
336 6e7275c0 Iustin Pop
    raise NotImplementedError
337 f48148c3 Iustin Pop
338 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
339 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
340 6a1434d7 Andrea Spadaccini

341 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
342 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
343 6a1434d7 Andrea Spadaccini
    @type success: bool
344 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
345 6a1434d7 Andrea Spadaccini
    @type live: bool
346 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
347 6a1434d7 Andrea Spadaccini

348 6a1434d7 Andrea Spadaccini
    """
349 6a1434d7 Andrea Spadaccini
    pass
350 6a1434d7 Andrea Spadaccini
351 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
352 6a1434d7 Andrea Spadaccini
    """Get the migration status
353 6a1434d7 Andrea Spadaccini

354 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
355 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
356 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
357 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
358 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
359 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
360 6a1434d7 Andrea Spadaccini

361 6a1434d7 Andrea Spadaccini
    """
362 6a1434d7 Andrea Spadaccini
    raise NotImplementedError
363 6a1434d7 Andrea Spadaccini
364 61eb1a46 Guido Trotter
  def _InstanceStartupMemory(self, instance):
365 61eb1a46 Guido Trotter
    """Get the correct startup memory for an instance
366 61eb1a46 Guido Trotter

367 61eb1a46 Guido Trotter
    This function calculates how much memory an instance should be started
368 61eb1a46 Guido Trotter
    with, making sure it's a value between the minimum and the maximum memory,
369 61eb1a46 Guido Trotter
    but also trying to use no more than the current free memory on the node.
370 61eb1a46 Guido Trotter

371 61eb1a46 Guido Trotter
    @type instance: L{objects.Instance}
372 61eb1a46 Guido Trotter
    @param instance: the instance that is being started
373 61eb1a46 Guido Trotter
    @rtype: integer
374 61eb1a46 Guido Trotter
    @return: memory the instance should be started with
375 61eb1a46 Guido Trotter

376 61eb1a46 Guido Trotter
    """
377 61eb1a46 Guido Trotter
    free_memory = self.GetNodeInfo()["memory_free"]
378 61eb1a46 Guido Trotter
    max_start_mem = min(instance.beparams[constants.BE_MAXMEM], free_memory)
379 61eb1a46 Guido Trotter
    start_mem = max(instance.beparams[constants.BE_MINMEM], max_start_mem)
380 61eb1a46 Guido Trotter
    return start_mem
381 61eb1a46 Guido Trotter
382 f48148c3 Iustin Pop
  @classmethod
383 f48148c3 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
384 f48148c3 Iustin Pop
    """Check the given parameters for validity.
385 f48148c3 Iustin Pop

386 f48148c3 Iustin Pop
    This should check the passed set of parameters for
387 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
388 f48148c3 Iustin Pop

389 f48148c3 Iustin Pop
    @type hvparams:  dict
390 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
391 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
392 f48148c3 Iustin Pop

393 f48148c3 Iustin Pop
    """
394 f48148c3 Iustin Pop
    for key in hvparams:
395 f48148c3 Iustin Pop
      if key not in cls.PARAMETERS:
396 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is not supported" % key)
397 205ab586 Iustin Pop
398 205ab586 Iustin Pop
    # cheap tests that run on the master, should not access the world
399 205ab586 Iustin Pop
    for name, (required, check_fn, errstr, _, _) in cls.PARAMETERS.items():
400 205ab586 Iustin Pop
      if name not in hvparams:
401 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is missing" % name)
402 205ab586 Iustin Pop
      value = hvparams[name]
403 205ab586 Iustin Pop
      if not required and not value:
404 205ab586 Iustin Pop
        continue
405 205ab586 Iustin Pop
      if not value:
406 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is required but"
407 205ab586 Iustin Pop
                                     " is currently not defined" % (name, ))
408 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
409 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails syntax"
410 205ab586 Iustin Pop
                                     " check: %s (current value: '%s')" %
411 205ab586 Iustin Pop
                                     (name, errstr, value))
412 205ab586 Iustin Pop
413 205ab586 Iustin Pop
  @classmethod
414 205ab586 Iustin Pop
  def ValidateParameters(cls, hvparams):
415 f48148c3 Iustin Pop
    """Check the given parameters for validity.
416 f48148c3 Iustin Pop

417 f48148c3 Iustin Pop
    This should check the passed set of parameters for
418 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
419 f48148c3 Iustin Pop

420 f48148c3 Iustin Pop
    @type hvparams:  dict
421 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
422 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
423 f48148c3 Iustin Pop

424 f48148c3 Iustin Pop
    """
425 205ab586 Iustin Pop
    for name, (required, _, _, check_fn, errstr) in cls.PARAMETERS.items():
426 205ab586 Iustin Pop
      value = hvparams[name]
427 205ab586 Iustin Pop
      if not required and not value:
428 205ab586 Iustin Pop
        continue
429 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
430 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails"
431 205ab586 Iustin Pop
                                     " validation: %s (current value: '%s')" %
432 205ab586 Iustin Pop
                                     (name, errstr, value))
433 572e52bf Iustin Pop
434 f5118ade Iustin Pop
  @classmethod
435 f5118ade Iustin Pop
  def PowercycleNode(cls):
436 f5118ade Iustin Pop
    """Hard powercycle a node using hypervisor specific methods.
437 f5118ade Iustin Pop

438 f5118ade Iustin Pop
    This method should hard powercycle the node, using whatever
439 f5118ade Iustin Pop
    methods the hypervisor provides. Note that this means that all
440 f5118ade Iustin Pop
    instances running on the node must be stopped too.
441 f5118ade Iustin Pop

442 f5118ade Iustin Pop
    """
443 f5118ade Iustin Pop
    raise NotImplementedError
444 f5118ade Iustin Pop
445 94fed7da Iustin Pop
  @staticmethod
446 94fed7da Iustin Pop
  def GetLinuxNodeInfo():
447 572e52bf Iustin Pop
    """For linux systems, return actual OS information.
448 572e52bf Iustin Pop

449 572e52bf Iustin Pop
    This is an abstraction for all non-hypervisor-based classes, where
450 572e52bf Iustin Pop
    the node actually sees all the memory and CPUs via the /proc
451 572e52bf Iustin Pop
    interface and standard commands. The other case if for example
452 572e52bf Iustin Pop
    xen, where you only see the hardware resources via xen-specific
453 572e52bf Iustin Pop
    tools.
454 572e52bf Iustin Pop

455 572e52bf Iustin Pop
    @return: a dict with the following keys (values in MiB):
456 572e52bf Iustin Pop
          - memory_total: the total memory size on the node
457 572e52bf Iustin Pop
          - memory_free: the available memory on the node for instances
458 572e52bf Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
459 572e52bf Iustin Pop

460 572e52bf Iustin Pop
    """
461 572e52bf Iustin Pop
    try:
462 3374afa9 Guido Trotter
      data = utils.ReadFile("/proc/meminfo").splitlines()
463 572e52bf Iustin Pop
    except EnvironmentError, err:
464 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
465 572e52bf Iustin Pop
466 572e52bf Iustin Pop
    result = {}
467 572e52bf Iustin Pop
    sum_free = 0
468 572e52bf Iustin Pop
    try:
469 572e52bf Iustin Pop
      for line in data:
470 572e52bf Iustin Pop
        splitfields = line.split(":", 1)
471 572e52bf Iustin Pop
472 572e52bf Iustin Pop
        if len(splitfields) > 1:
473 572e52bf Iustin Pop
          key = splitfields[0].strip()
474 572e52bf Iustin Pop
          val = splitfields[1].strip()
475 d0c8c01d Iustin Pop
          if key == "MemTotal":
476 e687ec01 Michael Hanselmann
            result["memory_total"] = int(val.split()[0]) / 1024
477 d0c8c01d Iustin Pop
          elif key in ("MemFree", "Buffers", "Cached"):
478 e687ec01 Michael Hanselmann
            sum_free += int(val.split()[0]) / 1024
479 d0c8c01d Iustin Pop
          elif key == "Active":
480 e687ec01 Michael Hanselmann
            result["memory_dom0"] = int(val.split()[0]) / 1024
481 572e52bf Iustin Pop
    except (ValueError, TypeError), err:
482 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to compute memory usage: %s" %
483 572e52bf Iustin Pop
                                   (err,))
484 d0c8c01d Iustin Pop
    result["memory_free"] = sum_free
485 572e52bf Iustin Pop
486 572e52bf Iustin Pop
    cpu_total = 0
487 572e52bf Iustin Pop
    try:
488 572e52bf Iustin Pop
      fh = open("/proc/cpuinfo")
489 572e52bf Iustin Pop
      try:
490 572e52bf Iustin Pop
        cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
491 572e52bf Iustin Pop
                                   fh.read()))
492 572e52bf Iustin Pop
      finally:
493 572e52bf Iustin Pop
        fh.close()
494 572e52bf Iustin Pop
    except EnvironmentError, err:
495 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
496 d0c8c01d Iustin Pop
    result["cpu_total"] = cpu_total
497 572e52bf Iustin Pop
    # FIXME: export correct data here
498 d0c8c01d Iustin Pop
    result["cpu_nodes"] = 1
499 d0c8c01d Iustin Pop
    result["cpu_sockets"] = 1
500 572e52bf Iustin Pop
501 572e52bf Iustin Pop
    return result
502 f5118ade Iustin Pop
503 f5118ade Iustin Pop
  @classmethod
504 f5118ade Iustin Pop
  def LinuxPowercycle(cls):
505 f5118ade Iustin Pop
    """Linux-specific powercycle method.
506 f5118ade Iustin Pop

507 f5118ade Iustin Pop
    """
508 f5118ade Iustin Pop
    try:
509 f5118ade Iustin Pop
      fd = os.open("/proc/sysrq-trigger", os.O_WRONLY)
510 f5118ade Iustin Pop
      try:
511 f5118ade Iustin Pop
        os.write(fd, "b")
512 f5118ade Iustin Pop
      finally:
513 f5118ade Iustin Pop
        fd.close()
514 f5118ade Iustin Pop
    except OSError:
515 f5118ade Iustin Pop
      logging.exception("Can't open the sysrq-trigger file")
516 f5118ade Iustin Pop
      result = utils.RunCmd(["reboot", "-n", "-f"])
517 f5118ade Iustin Pop
      if not result:
518 f5118ade Iustin Pop
        logging.error("Can't run shutdown: %s", result.output)