Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_base.py @ ddc64582

History | View | Annotate | Download (18.7 kB)

1 65a6f9b7 Michael Hanselmann
#
2 65a6f9b7 Michael Hanselmann
#
3 65a6f9b7 Michael Hanselmann
4 53fde1ac Iustin Pop
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012, 2013 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 5ae4945a 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 5ae4945a 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 2c368f28 Guido Trotter
# Check that an integer is non negative
106 2c368f28 Guido Trotter
_NONNEGATIVE_INT_CHECK = (lambda x: x >= 0, "cannot be negative", None, None)
107 2c368f28 Guido Trotter
108 205ab586 Iustin Pop
# nice wrappers for users
109 205ab586 Iustin Pop
REQ_FILE_CHECK = (True, ) + _FILE_CHECK
110 205ab586 Iustin Pop
OPT_FILE_CHECK = (False, ) + _FILE_CHECK
111 205ab586 Iustin Pop
REQ_DIR_CHECK = (True, ) + _DIR_CHECK
112 205ab586 Iustin Pop
OPT_DIR_CHECK = (False, ) + _DIR_CHECK
113 e2d14329 Andrea Spadaccini
REQ_NET_PORT_CHECK = (True, ) + _NET_PORT_CHECK
114 e2d14329 Andrea Spadaccini
OPT_NET_PORT_CHECK = (False, ) + _NET_PORT_CHECK
115 e3ed5316 Balazs Lecz
REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK
116 e2d14329 Andrea Spadaccini
OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK
117 b9511385 Tsachy Shacham
REQ_MULTI_CPU_MASK_CHECK = (True, ) + _MULTI_CPU_MASK_CHECK
118 b9511385 Tsachy Shacham
OPT_MULTI_CPU_MASK_CHECK = (False, ) + _MULTI_CPU_MASK_CHECK
119 2c368f28 Guido Trotter
REQ_NONNEGATIVE_INT_CHECK = (True, ) + _NONNEGATIVE_INT_CHECK
120 2c368f28 Guido Trotter
OPT_NONNEGATIVE_INT_CHECK = (False, ) + _NONNEGATIVE_INT_CHECK
121 205ab586 Iustin Pop
122 205ab586 Iustin Pop
# no checks at all
123 205ab586 Iustin Pop
NO_CHECK = (False, None, None, None, None)
124 205ab586 Iustin Pop
125 205ab586 Iustin Pop
# required, but no other checks
126 205ab586 Iustin Pop
REQUIRED_CHECK = (True, None, None, None, None)
127 205ab586 Iustin Pop
128 e71b9ef4 Iustin Pop
# migration type
129 783a6c0b Iustin Pop
MIGRATION_MODE_CHECK = (True, lambda x: x in constants.HT_MIGRATION_MODES,
130 783a6c0b Iustin Pop
                        "invalid migration mode", None, None)
131 e71b9ef4 Iustin Pop
132 d73ef63f Michael Hanselmann
133 205ab586 Iustin Pop
def ParamInSet(required, my_set):
134 205ab586 Iustin Pop
  """Builds parameter checker for set membership.
135 205ab586 Iustin Pop

136 205ab586 Iustin Pop
  @type required: boolean
137 205ab586 Iustin Pop
  @param required: whether this is a required parameter
138 205ab586 Iustin Pop
  @type my_set: tuple, list or set
139 205ab586 Iustin Pop
  @param my_set: allowed values set
140 205ab586 Iustin Pop

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

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

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

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

180 07b49e41 Guido Trotter
    @type instance: L{objects.Instance}
181 07b49e41 Guido Trotter
    @param instance: instance to stop
182 07b49e41 Guido Trotter
    @type force: boolean
183 07b49e41 Guido Trotter
    @param force: whether to do a "hard" stop (destroy)
184 07b49e41 Guido Trotter
    @type retry: boolean
185 07b49e41 Guido Trotter
    @param retry: whether this is just a retry call
186 bbcf7ad0 Iustin Pop
    @type name: string or None
187 bbcf7ad0 Iustin Pop
    @param name: if this parameter is passed, the the instance object
188 bbcf7ad0 Iustin Pop
        should not be used (will be passed as None), and the shutdown
189 bbcf7ad0 Iustin Pop
        must be done by name only
190 874f6148 Michele Tartara
    @type timeout: int or None
191 874f6148 Michele Tartara
    @param timeout: if the parameter is not None, a soft shutdown operation will
192 874f6148 Michele Tartara
        be killed after the specified number of seconds. A hard (forced)
193 874f6148 Michele Tartara
        shutdown cannot have a timeout
194 07b49e41 Guido Trotter

195 07b49e41 Guido Trotter
    """
196 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
197 65a6f9b7 Michael Hanselmann
198 f28ec899 Guido Trotter
  def CleanupInstance(self, instance_name):
199 f28ec899 Guido Trotter
    """Cleanup after a stopped instance
200 f28ec899 Guido Trotter

201 f28ec899 Guido Trotter
    This is an optional method, used by hypervisors that need to cleanup after
202 f28ec899 Guido Trotter
    an instance has been stopped.
203 f28ec899 Guido Trotter

204 f28ec899 Guido Trotter
    @type instance_name: string
205 f28ec899 Guido Trotter
    @param instance_name: instance name to cleanup after
206 f28ec899 Guido Trotter

207 f28ec899 Guido Trotter
    """
208 f28ec899 Guido Trotter
    pass
209 f28ec899 Guido Trotter
210 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
211 65a6f9b7 Michael Hanselmann
    """Reboot an instance."""
212 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
213 65a6f9b7 Michael Hanselmann
214 58e356a9 Helga Velroyen
  def ListInstances(self, hvparams=None):
215 65a6f9b7 Michael Hanselmann
    """Get the list of running instances."""
216 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
217 65a6f9b7 Michael Hanselmann
218 0bbec3af Helga Velroyen
  def GetInstanceInfo(self, instance_name, hvparams=None):
219 65a6f9b7 Michael Hanselmann
    """Get instance properties.
220 65a6f9b7 Michael Hanselmann

221 cd42d0ad Guido Trotter
    @type instance_name: string
222 c41eea6e Iustin Pop
    @param instance_name: the instance name
223 0bbec3af Helga Velroyen
    @type hvparams: dict of strings
224 0bbec3af Helga Velroyen
    @param hvparams: hvparams to be used with this instance
225 65a6f9b7 Michael Hanselmann

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

228 65a6f9b7 Michael Hanselmann
    """
229 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
230 65a6f9b7 Michael Hanselmann
231 0200a1af Helga Velroyen
  def GetAllInstancesInfo(self, hvparams=None):
232 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
233 65a6f9b7 Michael Hanselmann

234 0200a1af Helga Velroyen
    @type hvparams: dict of strings
235 0200a1af Helga Velroyen
    @param hvparams: hypervisor parameter
236 c41eea6e Iustin Pop
    @return: list of tuples (name, id, memory, vcpus, stat, times)
237 c41eea6e Iustin Pop

238 65a6f9b7 Michael Hanselmann
    """
239 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
240 65a6f9b7 Michael Hanselmann
241 fac489a5 Helga Velroyen
  def GetNodeInfo(self, hvparams=None):
242 65a6f9b7 Michael Hanselmann
    """Return information about the node.
243 65a6f9b7 Michael Hanselmann

244 fac489a5 Helga Velroyen
    @type hvparams: dict of strings
245 fac489a5 Helga Velroyen
    @param hvparams: hypervisor parameters
246 fac489a5 Helga Velroyen

247 ef14e128 Bernardo Dal Seno
    @return: a dict with at least the following keys (memory values in MiB):
248 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
249 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
250 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
251 ef14e128 Bernardo Dal Seno
          - cpu_total: total number of CPUs
252 ff05ff94 Bernardo Dal Seno
          - cpu_dom0: number of CPUs used by the node OS
253 ef14e128 Bernardo Dal Seno
          - cpu_nodes: number of NUMA domains
254 ef14e128 Bernardo Dal Seno
          - cpu_sockets: number of physical CPU sockets
255 65a6f9b7 Michael Hanselmann

256 65a6f9b7 Michael Hanselmann
    """
257 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
258 65a6f9b7 Michael Hanselmann
259 637ce7f9 Guido Trotter
  @classmethod
260 1c3231aa Thomas Thrainer
  def GetInstanceConsole(cls, instance, primary_node, hvparams, beparams):
261 55cc0a44 Michael Hanselmann
    """Return information for connecting to the console of an instance.
262 65a6f9b7 Michael Hanselmann

263 65a6f9b7 Michael Hanselmann
    """
264 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
265 65a6f9b7 Michael Hanselmann
266 e1b8653f Guido Trotter
  @classmethod
267 e1b8653f Guido Trotter
  def GetAncillaryFiles(cls):
268 e1b8653f Guido Trotter
    """Return a list of ancillary files to be copied to all nodes as ancillary
269 e1b8653f Guido Trotter
    configuration files.
270 e1b8653f Guido Trotter

271 69ab2e12 Guido Trotter
    @rtype: (list of absolute paths, list of absolute paths)
272 69ab2e12 Guido Trotter
    @return: (all files, optional files)
273 e1b8653f Guido Trotter

274 e1b8653f Guido Trotter
    """
275 e1b8653f Guido Trotter
    # By default we return a member variable, so that if an hypervisor has just
276 e1b8653f Guido Trotter
    # a static list of files it doesn't have to override this function.
277 69ab2e12 Guido Trotter
    assert set(cls.ANCILLARY_FILES).issuperset(cls.ANCILLARY_FILES_OPT), \
278 69ab2e12 Guido Trotter
      "Optional ancillary files must be a subset of ancillary files"
279 69ab2e12 Guido Trotter
280 69ab2e12 Guido Trotter
    return (cls.ANCILLARY_FILES, cls.ANCILLARY_FILES_OPT)
281 e1b8653f Guido Trotter
282 75bf3149 Helga Velroyen
  def Verify(self, hvparams=None):
283 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
284 65a6f9b7 Michael Hanselmann

285 75bf3149 Helga Velroyen
    @type hvparams: dict of strings
286 75bf3149 Helga Velroyen
    @param hvparams: hypervisor parameters to be verified against
287 75bf3149 Helga Velroyen

288 cd04dfd2 Michael Hanselmann
    @return: Problem description if something is wrong, C{None} otherwise
289 cd04dfd2 Michael Hanselmann

290 65a6f9b7 Michael Hanselmann
    """
291 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
292 6e7275c0 Iustin Pop
293 b459a848 Andrea Spadaccini
  def MigrationInfo(self, instance): # pylint: disable=R0201,W0613
294 cd42d0ad Guido Trotter
    """Get instance information to perform a migration.
295 cd42d0ad Guido Trotter

296 cd42d0ad Guido Trotter
    By default assume no information is needed.
297 cd42d0ad Guido Trotter

298 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
299 cd42d0ad Guido Trotter
    @param instance: instance to be migrated
300 cd42d0ad Guido Trotter
    @rtype: string/data (opaque)
301 cd42d0ad Guido Trotter
    @return: instance migration information - serialized form
302 cd42d0ad Guido Trotter

303 cd42d0ad Guido Trotter
    """
304 d0c8c01d Iustin Pop
    return ""
305 cd42d0ad Guido Trotter
306 cd42d0ad Guido Trotter
  def AcceptInstance(self, instance, info, target):
307 cd42d0ad Guido Trotter
    """Prepare to accept an instance.
308 cd42d0ad Guido Trotter

309 cd42d0ad Guido Trotter
    By default assume no preparation is needed.
310 cd42d0ad Guido Trotter

311 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
312 cd42d0ad Guido Trotter
    @param instance: instance to be accepted
313 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
314 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
315 cd42d0ad Guido Trotter
    @type target: string
316 cd42d0ad Guido Trotter
    @param target: target host (usually ip), on this node
317 cd42d0ad Guido Trotter

318 cd42d0ad Guido Trotter
    """
319 cd42d0ad Guido Trotter
    pass
320 cd42d0ad Guido Trotter
321 b990eedd Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
322 b990eedd Guido Trotter
    """Balloon an instance memory to a certain value.
323 b990eedd Guido Trotter

324 b990eedd Guido Trotter
    @type instance: L{objects.Instance}
325 b990eedd Guido Trotter
    @param instance: instance to be accepted
326 b990eedd Guido Trotter
    @type mem: int
327 b990eedd Guido Trotter
    @param mem: actual memory size to use for instance runtime
328 b990eedd Guido Trotter

329 b990eedd Guido Trotter
    """
330 b990eedd Guido Trotter
    raise NotImplementedError
331 b990eedd Guido Trotter
332 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
333 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
334 cd42d0ad Guido Trotter

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

338 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
339 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
340 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
341 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
342 cd42d0ad Guido Trotter
    @type success: boolean
343 cd42d0ad Guido Trotter
    @param success: whether the migration was a success or a failure
344 cd42d0ad Guido Trotter

345 cd42d0ad Guido Trotter
    """
346 cd42d0ad Guido Trotter
    pass
347 cd42d0ad Guido Trotter
348 bc0a2284 Helga Velroyen
  def MigrateInstance(self, cluster_name, instance, target, live):
349 6e7275c0 Iustin Pop
    """Migrate an instance.
350 6e7275c0 Iustin Pop

351 bc0a2284 Helga Velroyen
    @type cluster_name: string
352 bc0a2284 Helga Velroyen
    @param cluster_name: name of the cluster
353 3a488770 Iustin Pop
    @type instance: L{objects.Instance}
354 9044275a Michael Hanselmann
    @param instance: the instance to be migrated
355 cd42d0ad Guido Trotter
    @type target: string
356 cd42d0ad Guido Trotter
    @param target: hostname (usually ip) of the target node
357 cd42d0ad Guido Trotter
    @type live: boolean
358 cd42d0ad Guido Trotter
    @param live: whether to do a live or non-live migration
359 6e7275c0 Iustin Pop

360 6e7275c0 Iustin Pop
    """
361 6e7275c0 Iustin Pop
    raise NotImplementedError
362 f48148c3 Iustin Pop
363 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
364 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
365 6a1434d7 Andrea Spadaccini

366 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
367 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
368 6a1434d7 Andrea Spadaccini
    @type success: bool
369 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
370 6a1434d7 Andrea Spadaccini
    @type live: bool
371 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
372 6a1434d7 Andrea Spadaccini

373 6a1434d7 Andrea Spadaccini
    """
374 6a1434d7 Andrea Spadaccini
    pass
375 6a1434d7 Andrea Spadaccini
376 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
377 6a1434d7 Andrea Spadaccini
    """Get the migration status
378 6a1434d7 Andrea Spadaccini

379 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
380 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
381 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
382 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
383 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
384 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
385 6a1434d7 Andrea Spadaccini

386 6a1434d7 Andrea Spadaccini
    """
387 6a1434d7 Andrea Spadaccini
    raise NotImplementedError
388 6a1434d7 Andrea Spadaccini
389 30b12688 Jose A. Lopes
  def _InstanceStartupMemory(self, instance):
390 61eb1a46 Guido Trotter
    """Get the correct startup memory for an instance
391 61eb1a46 Guido Trotter

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

396 61eb1a46 Guido Trotter
    @type instance: L{objects.Instance}
397 61eb1a46 Guido Trotter
    @param instance: the instance that is being started
398 61eb1a46 Guido Trotter
    @rtype: integer
399 61eb1a46 Guido Trotter
    @return: memory the instance should be started with
400 61eb1a46 Guido Trotter

401 61eb1a46 Guido Trotter
    """
402 30b12688 Jose A. Lopes
    free_memory = self.GetNodeInfo(hvparams=instance.hvparams)["memory_free"]
403 61eb1a46 Guido Trotter
    max_start_mem = min(instance.beparams[constants.BE_MAXMEM], free_memory)
404 61eb1a46 Guido Trotter
    start_mem = max(instance.beparams[constants.BE_MINMEM], max_start_mem)
405 61eb1a46 Guido Trotter
    return start_mem
406 61eb1a46 Guido Trotter
407 f48148c3 Iustin Pop
  @classmethod
408 f48148c3 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
409 f48148c3 Iustin Pop
    """Check the given parameters for validity.
410 f48148c3 Iustin Pop

411 f48148c3 Iustin Pop
    This should check the passed set of parameters for
412 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
413 f48148c3 Iustin Pop

414 f48148c3 Iustin Pop
    @type hvparams:  dict
415 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
416 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
417 f48148c3 Iustin Pop

418 f48148c3 Iustin Pop
    """
419 f48148c3 Iustin Pop
    for key in hvparams:
420 f48148c3 Iustin Pop
      if key not in cls.PARAMETERS:
421 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is not supported" % key)
422 205ab586 Iustin Pop
423 205ab586 Iustin Pop
    # cheap tests that run on the master, should not access the world
424 205ab586 Iustin Pop
    for name, (required, check_fn, errstr, _, _) in cls.PARAMETERS.items():
425 205ab586 Iustin Pop
      if name not in hvparams:
426 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is missing" % name)
427 205ab586 Iustin Pop
      value = hvparams[name]
428 205ab586 Iustin Pop
      if not required and not value:
429 205ab586 Iustin Pop
        continue
430 205ab586 Iustin Pop
      if not value:
431 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is required but"
432 205ab586 Iustin Pop
                                     " is currently not defined" % (name, ))
433 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
434 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails syntax"
435 205ab586 Iustin Pop
                                     " check: %s (current value: '%s')" %
436 205ab586 Iustin Pop
                                     (name, errstr, value))
437 205ab586 Iustin Pop
438 205ab586 Iustin Pop
  @classmethod
439 205ab586 Iustin Pop
  def ValidateParameters(cls, hvparams):
440 f48148c3 Iustin Pop
    """Check the given parameters for validity.
441 f48148c3 Iustin Pop

442 f48148c3 Iustin Pop
    This should check the passed set of parameters for
443 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
444 f48148c3 Iustin Pop

445 f48148c3 Iustin Pop
    @type hvparams:  dict
446 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
447 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
448 f48148c3 Iustin Pop

449 f48148c3 Iustin Pop
    """
450 205ab586 Iustin Pop
    for name, (required, _, _, check_fn, errstr) in cls.PARAMETERS.items():
451 205ab586 Iustin Pop
      value = hvparams[name]
452 205ab586 Iustin Pop
      if not required and not value:
453 205ab586 Iustin Pop
        continue
454 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
455 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails"
456 205ab586 Iustin Pop
                                     " validation: %s (current value: '%s')" %
457 205ab586 Iustin Pop
                                     (name, errstr, value))
458 572e52bf Iustin Pop
459 f5118ade Iustin Pop
  @classmethod
460 8ef418bb Helga Velroyen
  def PowercycleNode(cls, hvparams=None):
461 f5118ade Iustin Pop
    """Hard powercycle a node using hypervisor specific methods.
462 f5118ade Iustin Pop

463 f5118ade Iustin Pop
    This method should hard powercycle the node, using whatever
464 f5118ade Iustin Pop
    methods the hypervisor provides. Note that this means that all
465 f5118ade Iustin Pop
    instances running on the node must be stopped too.
466 f5118ade Iustin Pop

467 8ef418bb Helga Velroyen
    @type hvparams: dict of strings
468 8ef418bb Helga Velroyen
    @param hvparams: hypervisor params to be used on this node
469 8ef418bb Helga Velroyen

470 f5118ade Iustin Pop
    """
471 f5118ade Iustin Pop
    raise NotImplementedError
472 f5118ade Iustin Pop
473 94fed7da Iustin Pop
  @staticmethod
474 23cb5697 Michele Tartara
  def GetLinuxNodeInfo(meminfo="/proc/meminfo", cpuinfo="/proc/cpuinfo"):
475 572e52bf Iustin Pop
    """For linux systems, return actual OS information.
476 572e52bf Iustin Pop

477 572e52bf Iustin Pop
    This is an abstraction for all non-hypervisor-based classes, where
478 572e52bf Iustin Pop
    the node actually sees all the memory and CPUs via the /proc
479 572e52bf Iustin Pop
    interface and standard commands. The other case if for example
480 572e52bf Iustin Pop
    xen, where you only see the hardware resources via xen-specific
481 572e52bf Iustin Pop
    tools.
482 572e52bf Iustin Pop

483 23cb5697 Michele Tartara
    @param meminfo: name of the file containing meminfo
484 23cb5697 Michele Tartara
    @type meminfo: string
485 23cb5697 Michele Tartara
    @param cpuinfo: name of the file containing cpuinfo
486 23cb5697 Michele Tartara
    @type cpuinfo: string
487 572e52bf Iustin Pop
    @return: a dict with the following keys (values in MiB):
488 572e52bf Iustin Pop
          - memory_total: the total memory size on the node
489 572e52bf Iustin Pop
          - memory_free: the available memory on the node for instances
490 572e52bf Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
491 ef14e128 Bernardo Dal Seno
          - cpu_total: total number of CPUs
492 ff05ff94 Bernardo Dal Seno
          - cpu_dom0: number of CPUs used by the node OS
493 ef14e128 Bernardo Dal Seno
          - cpu_nodes: number of NUMA domains
494 ef14e128 Bernardo Dal Seno
          - cpu_sockets: number of physical CPU sockets
495 572e52bf Iustin Pop

496 572e52bf Iustin Pop
    """
497 572e52bf Iustin Pop
    try:
498 23cb5697 Michele Tartara
      data = utils.ReadFile(meminfo).splitlines()
499 572e52bf Iustin Pop
    except EnvironmentError, err:
500 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
501 572e52bf Iustin Pop
502 572e52bf Iustin Pop
    result = {}
503 572e52bf Iustin Pop
    sum_free = 0
504 572e52bf Iustin Pop
    try:
505 572e52bf Iustin Pop
      for line in data:
506 572e52bf Iustin Pop
        splitfields = line.split(":", 1)
507 572e52bf Iustin Pop
508 572e52bf Iustin Pop
        if len(splitfields) > 1:
509 572e52bf Iustin Pop
          key = splitfields[0].strip()
510 572e52bf Iustin Pop
          val = splitfields[1].strip()
511 d0c8c01d Iustin Pop
          if key == "MemTotal":
512 e687ec01 Michael Hanselmann
            result["memory_total"] = int(val.split()[0]) / 1024
513 d0c8c01d Iustin Pop
          elif key in ("MemFree", "Buffers", "Cached"):
514 e687ec01 Michael Hanselmann
            sum_free += int(val.split()[0]) / 1024
515 d0c8c01d Iustin Pop
          elif key == "Active":
516 e687ec01 Michael Hanselmann
            result["memory_dom0"] = int(val.split()[0]) / 1024
517 572e52bf Iustin Pop
    except (ValueError, TypeError), err:
518 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to compute memory usage: %s" %
519 572e52bf Iustin Pop
                                   (err,))
520 d0c8c01d Iustin Pop
    result["memory_free"] = sum_free
521 572e52bf Iustin Pop
522 572e52bf Iustin Pop
    cpu_total = 0
523 572e52bf Iustin Pop
    try:
524 23cb5697 Michele Tartara
      fh = open(cpuinfo)
525 572e52bf Iustin Pop
      try:
526 78f99abb Michele Tartara
        cpu_total = len(re.findall(r"(?m)^processor\s*:\s*[0-9]+\s*$",
527 572e52bf Iustin Pop
                                   fh.read()))
528 572e52bf Iustin Pop
      finally:
529 572e52bf Iustin Pop
        fh.close()
530 572e52bf Iustin Pop
    except EnvironmentError, err:
531 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
532 d0c8c01d Iustin Pop
    result["cpu_total"] = cpu_total
533 ff05ff94 Bernardo Dal Seno
    # We assume that the node OS can access all the CPUs
534 ff05ff94 Bernardo Dal Seno
    result["cpu_dom0"] = cpu_total
535 572e52bf Iustin Pop
    # FIXME: export correct data here
536 d0c8c01d Iustin Pop
    result["cpu_nodes"] = 1
537 d0c8c01d Iustin Pop
    result["cpu_sockets"] = 1
538 572e52bf Iustin Pop
539 572e52bf Iustin Pop
    return result
540 f5118ade Iustin Pop
541 f5118ade Iustin Pop
  @classmethod
542 f5118ade Iustin Pop
  def LinuxPowercycle(cls):
543 f5118ade Iustin Pop
    """Linux-specific powercycle method.
544 f5118ade Iustin Pop

545 f5118ade Iustin Pop
    """
546 f5118ade Iustin Pop
    try:
547 f5118ade Iustin Pop
      fd = os.open("/proc/sysrq-trigger", os.O_WRONLY)
548 f5118ade Iustin Pop
      try:
549 f5118ade Iustin Pop
        os.write(fd, "b")
550 f5118ade Iustin Pop
      finally:
551 f5118ade Iustin Pop
        fd.close()
552 f5118ade Iustin Pop
    except OSError:
553 f5118ade Iustin Pop
      logging.exception("Can't open the sysrq-trigger file")
554 f5118ade Iustin Pop
      result = utils.RunCmd(["reboot", "-n", "-f"])
555 f5118ade Iustin Pop
      if not result:
556 f5118ade Iustin Pop
        logging.error("Can't run shutdown: %s", result.output)
557 53fde1ac Iustin Pop
558 53fde1ac Iustin Pop
  @staticmethod
559 53fde1ac Iustin Pop
  def _FormatVerifyResults(msgs):
560 53fde1ac Iustin Pop
    """Formats the verification results, given a list of errors.
561 53fde1ac Iustin Pop

562 53fde1ac Iustin Pop
    @param msgs: list of errors, possibly empty
563 53fde1ac Iustin Pop
    @return: overall problem description if something is wrong,
564 53fde1ac Iustin Pop
        C{None} otherwise
565 53fde1ac Iustin Pop

566 53fde1ac Iustin Pop
    """
567 53fde1ac Iustin Pop
    if msgs:
568 53fde1ac Iustin Pop
      return "; ".join(msgs)
569 53fde1ac Iustin Pop
    else:
570 53fde1ac Iustin Pop
      return None