Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_base.py @ 31d3b918

History | View | Annotate | Download (20.8 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 364e1664 Jose A. Lopes
# must be a file
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 f15a6b03 Jose A. Lopes
# must be a file or a URL
87 364e1664 Jose A. Lopes
_FILE_OR_URL_CHECK = (lambda x: utils.IsNormAbsPath(x) or utils.IsUrl(x),
88 f15a6b03 Jose A. Lopes
                      "must be an absolute normalized path or a URL",
89 364e1664 Jose A. Lopes
                      lambda x: os.path.isfile(x) or utils.IsUrl(x),
90 f15a6b03 Jose A. Lopes
                      "not found or not a file or URL")
91 f15a6b03 Jose A. Lopes
92 205ab586 Iustin Pop
# must be a directory
93 17c61836 Guido Trotter
_DIR_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
94 5ae4945a Iustin Pop
              os.path.isdir, "not found or not a directory")
95 205ab586 Iustin Pop
96 e3ed5316 Balazs Lecz
# CPU mask must be well-formed
97 e3ed5316 Balazs Lecz
# TODO: implement node level check for the CPU mask
98 e3ed5316 Balazs Lecz
_CPU_MASK_CHECK = (_IsCpuMaskWellFormed,
99 e3ed5316 Balazs Lecz
                   "CPU mask definition is not well-formed",
100 e3ed5316 Balazs Lecz
                   None, None)
101 e3ed5316 Balazs Lecz
102 b9511385 Tsachy Shacham
# Multiple CPU mask must be well-formed
103 b9511385 Tsachy Shacham
_MULTI_CPU_MASK_CHECK = (_IsMultiCpuMaskWellFormed,
104 b9511385 Tsachy Shacham
                         "Multiple CPU mask definition is not well-formed",
105 b9511385 Tsachy Shacham
                         None, None)
106 b9511385 Tsachy Shacham
107 e2d14329 Andrea Spadaccini
# Check for validity of port number
108 e2d14329 Andrea Spadaccini
_NET_PORT_CHECK = (lambda x: 0 < x < 65535, "invalid port number",
109 e2d14329 Andrea Spadaccini
                   None, None)
110 e2d14329 Andrea Spadaccini
111 2c368f28 Guido Trotter
# Check that an integer is non negative
112 2c368f28 Guido Trotter
_NONNEGATIVE_INT_CHECK = (lambda x: x >= 0, "cannot be negative", None, None)
113 2c368f28 Guido Trotter
114 205ab586 Iustin Pop
# nice wrappers for users
115 205ab586 Iustin Pop
REQ_FILE_CHECK = (True, ) + _FILE_CHECK
116 205ab586 Iustin Pop
OPT_FILE_CHECK = (False, ) + _FILE_CHECK
117 f15a6b03 Jose A. Lopes
REQ_FILE_OR_URL_CHECK = (True, ) + _FILE_OR_URL_CHECK
118 f15a6b03 Jose A. Lopes
OPT_FILE_OR_URL_CHECK = (False, ) + _FILE_OR_URL_CHECK
119 205ab586 Iustin Pop
REQ_DIR_CHECK = (True, ) + _DIR_CHECK
120 205ab586 Iustin Pop
OPT_DIR_CHECK = (False, ) + _DIR_CHECK
121 e2d14329 Andrea Spadaccini
REQ_NET_PORT_CHECK = (True, ) + _NET_PORT_CHECK
122 e2d14329 Andrea Spadaccini
OPT_NET_PORT_CHECK = (False, ) + _NET_PORT_CHECK
123 e3ed5316 Balazs Lecz
REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK
124 e2d14329 Andrea Spadaccini
OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK
125 b9511385 Tsachy Shacham
REQ_MULTI_CPU_MASK_CHECK = (True, ) + _MULTI_CPU_MASK_CHECK
126 b9511385 Tsachy Shacham
OPT_MULTI_CPU_MASK_CHECK = (False, ) + _MULTI_CPU_MASK_CHECK
127 2c368f28 Guido Trotter
REQ_NONNEGATIVE_INT_CHECK = (True, ) + _NONNEGATIVE_INT_CHECK
128 2c368f28 Guido Trotter
OPT_NONNEGATIVE_INT_CHECK = (False, ) + _NONNEGATIVE_INT_CHECK
129 205ab586 Iustin Pop
130 205ab586 Iustin Pop
# no checks at all
131 205ab586 Iustin Pop
NO_CHECK = (False, None, None, None, None)
132 205ab586 Iustin Pop
133 205ab586 Iustin Pop
# required, but no other checks
134 205ab586 Iustin Pop
REQUIRED_CHECK = (True, None, None, None, None)
135 205ab586 Iustin Pop
136 e71b9ef4 Iustin Pop
# migration type
137 783a6c0b Iustin Pop
MIGRATION_MODE_CHECK = (True, lambda x: x in constants.HT_MIGRATION_MODES,
138 783a6c0b Iustin Pop
                        "invalid migration mode", None, None)
139 e71b9ef4 Iustin Pop
140 d73ef63f Michael Hanselmann
141 205ab586 Iustin Pop
def ParamInSet(required, my_set):
142 205ab586 Iustin Pop
  """Builds parameter checker for set membership.
143 205ab586 Iustin Pop

144 205ab586 Iustin Pop
  @type required: boolean
145 205ab586 Iustin Pop
  @param required: whether this is a required parameter
146 205ab586 Iustin Pop
  @type my_set: tuple, list or set
147 205ab586 Iustin Pop
  @param my_set: allowed values set
148 205ab586 Iustin Pop

149 205ab586 Iustin Pop
  """
150 205ab586 Iustin Pop
  fn = lambda x: x in my_set
151 ab3e6da8 Iustin Pop
  err = ("The value must be one of: %s" % utils.CommaJoin(my_set))
152 205ab586 Iustin Pop
  return (required, fn, err, None, None)
153 f48148c3 Iustin Pop
154 f48148c3 Iustin Pop
155 a3f0f306 Jose A. Lopes
class HvInstanceState(object):
156 a3f0f306 Jose A. Lopes
  RUNNING = 0
157 a3f0f306 Jose A. Lopes
  SHUTDOWN = 1
158 a3f0f306 Jose A. Lopes
159 a3f0f306 Jose A. Lopes
  @staticmethod
160 a3f0f306 Jose A. Lopes
  def IsRunning(s):
161 a3f0f306 Jose A. Lopes
    return s == HvInstanceState.RUNNING
162 a3f0f306 Jose A. Lopes
163 a3f0f306 Jose A. Lopes
  @staticmethod
164 a3f0f306 Jose A. Lopes
  def IsShutdown(s):
165 a3f0f306 Jose A. Lopes
    return s == HvInstanceState.SHUTDOWN
166 a3f0f306 Jose A. Lopes
167 a3f0f306 Jose A. Lopes
168 65a6f9b7 Michael Hanselmann
class BaseHypervisor(object):
169 65a6f9b7 Michael Hanselmann
  """Abstract virtualisation technology interface
170 65a6f9b7 Michael Hanselmann

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

174 205ab586 Iustin Pop
  @cvar PARAMETERS: a dict of parameter name: check type; the check type is
175 205ab586 Iustin Pop
      a five-tuple containing:
176 205ab586 Iustin Pop
          - the required flag (boolean)
177 205ab586 Iustin Pop
          - a function to check for syntax, that will be used in
178 205ab586 Iustin Pop
            L{CheckParameterSyntax}, in the master daemon process
179 205ab586 Iustin Pop
          - an error message for the above function
180 205ab586 Iustin Pop
          - a function to check for parameter validity on the remote node,
181 205ab586 Iustin Pop
            in the L{ValidateParameters} function
182 205ab586 Iustin Pop
          - an error message for the above function
183 d271c6fd Iustin Pop
  @type CAN_MIGRATE: boolean
184 d271c6fd Iustin Pop
  @cvar CAN_MIGRATE: whether this hypervisor can do migration (either
185 d271c6fd Iustin Pop
      live or non-live)
186 205ab586 Iustin Pop

187 65a6f9b7 Michael Hanselmann
  """
188 205ab586 Iustin Pop
  PARAMETERS = {}
189 e1b8653f Guido Trotter
  ANCILLARY_FILES = []
190 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = []
191 d271c6fd Iustin Pop
  CAN_MIGRATE = False
192 f48148c3 Iustin Pop
193 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
194 65a6f9b7 Michael Hanselmann
    """Start an instance."""
195 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
196 65a6f9b7 Michael Hanselmann
197 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
198 07b49e41 Guido Trotter
    """Stop an instance
199 07b49e41 Guido Trotter

200 07b49e41 Guido Trotter
    @type instance: L{objects.Instance}
201 07b49e41 Guido Trotter
    @param instance: instance to stop
202 07b49e41 Guido Trotter
    @type force: boolean
203 07b49e41 Guido Trotter
    @param force: whether to do a "hard" stop (destroy)
204 07b49e41 Guido Trotter
    @type retry: boolean
205 07b49e41 Guido Trotter
    @param retry: whether this is just a retry call
206 bbcf7ad0 Iustin Pop
    @type name: string or None
207 bbcf7ad0 Iustin Pop
    @param name: if this parameter is passed, the the instance object
208 bbcf7ad0 Iustin Pop
        should not be used (will be passed as None), and the shutdown
209 bbcf7ad0 Iustin Pop
        must be done by name only
210 059ed766 Jose A. Lopes
    @raise errors.HypervisorError: when a parameter is not valid or
211 059ed766 Jose A. Lopes
        the instance failed to be stopped
212 07b49e41 Guido Trotter

213 07b49e41 Guido Trotter
    """
214 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
215 65a6f9b7 Michael Hanselmann
216 f28ec899 Guido Trotter
  def CleanupInstance(self, instance_name):
217 f28ec899 Guido Trotter
    """Cleanup after a stopped instance
218 f28ec899 Guido Trotter

219 f28ec899 Guido Trotter
    This is an optional method, used by hypervisors that need to cleanup after
220 f28ec899 Guido Trotter
    an instance has been stopped.
221 f28ec899 Guido Trotter

222 f28ec899 Guido Trotter
    @type instance_name: string
223 f28ec899 Guido Trotter
    @param instance_name: instance name to cleanup after
224 f28ec899 Guido Trotter

225 f28ec899 Guido Trotter
    """
226 f28ec899 Guido Trotter
    pass
227 f28ec899 Guido Trotter
228 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
229 65a6f9b7 Michael Hanselmann
    """Reboot an instance."""
230 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
231 65a6f9b7 Michael Hanselmann
232 58e356a9 Helga Velroyen
  def ListInstances(self, hvparams=None):
233 65a6f9b7 Michael Hanselmann
    """Get the list of running instances."""
234 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
235 65a6f9b7 Michael Hanselmann
236 0bbec3af Helga Velroyen
  def GetInstanceInfo(self, instance_name, hvparams=None):
237 65a6f9b7 Michael Hanselmann
    """Get instance properties.
238 65a6f9b7 Michael Hanselmann

239 cd42d0ad Guido Trotter
    @type instance_name: string
240 c41eea6e Iustin Pop
    @param instance_name: the instance name
241 0bbec3af Helga Velroyen
    @type hvparams: dict of strings
242 0bbec3af Helga Velroyen
    @param hvparams: hvparams to be used with this instance
243 65a6f9b7 Michael Hanselmann

244 9d22cc90 Jose A. Lopes
    @rtype: (string, string, int, int, HvInstanceState, int)
245 c41eea6e Iustin Pop
    @return: tuple (name, id, memory, vcpus, state, times)
246 65a6f9b7 Michael Hanselmann

247 65a6f9b7 Michael Hanselmann
    """
248 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
249 65a6f9b7 Michael Hanselmann
250 0200a1af Helga Velroyen
  def GetAllInstancesInfo(self, hvparams=None):
251 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
252 65a6f9b7 Michael Hanselmann

253 0200a1af Helga Velroyen
    @type hvparams: dict of strings
254 0200a1af Helga Velroyen
    @param hvparams: hypervisor parameter
255 9d22cc90 Jose A. Lopes

256 9d22cc90 Jose A. Lopes
    @rtype: (string, string, int, int, HvInstanceState, int)
257 9d22cc90 Jose A. Lopes
    @return: list of tuples (name, id, memory, vcpus, state, times)
258 c41eea6e Iustin Pop

259 65a6f9b7 Michael Hanselmann
    """
260 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
261 65a6f9b7 Michael Hanselmann
262 fac489a5 Helga Velroyen
  def GetNodeInfo(self, hvparams=None):
263 65a6f9b7 Michael Hanselmann
    """Return information about the node.
264 65a6f9b7 Michael Hanselmann

265 fac489a5 Helga Velroyen
    @type hvparams: dict of strings
266 fac489a5 Helga Velroyen
    @param hvparams: hypervisor parameters
267 fac489a5 Helga Velroyen

268 ef14e128 Bernardo Dal Seno
    @return: a dict with at least the following keys (memory values in MiB):
269 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
270 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
271 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
272 ef14e128 Bernardo Dal Seno
          - cpu_total: total number of CPUs
273 ff05ff94 Bernardo Dal Seno
          - cpu_dom0: number of CPUs used by the node OS
274 ef14e128 Bernardo Dal Seno
          - cpu_nodes: number of NUMA domains
275 ef14e128 Bernardo Dal Seno
          - cpu_sockets: number of physical CPU sockets
276 65a6f9b7 Michael Hanselmann

277 65a6f9b7 Michael Hanselmann
    """
278 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
279 65a6f9b7 Michael Hanselmann
280 637ce7f9 Guido Trotter
  @classmethod
281 c42be2c0 Petr Pudlak
  def GetInstanceConsole(cls, instance, primary_node, node_group,
282 c42be2c0 Petr Pudlak
                         hvparams, beparams):
283 55cc0a44 Michael Hanselmann
    """Return information for connecting to the console of an instance.
284 65a6f9b7 Michael Hanselmann

285 65a6f9b7 Michael Hanselmann
    """
286 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
287 65a6f9b7 Michael Hanselmann
288 e1b8653f Guido Trotter
  @classmethod
289 e1b8653f Guido Trotter
  def GetAncillaryFiles(cls):
290 e1b8653f Guido Trotter
    """Return a list of ancillary files to be copied to all nodes as ancillary
291 e1b8653f Guido Trotter
    configuration files.
292 e1b8653f Guido Trotter

293 69ab2e12 Guido Trotter
    @rtype: (list of absolute paths, list of absolute paths)
294 69ab2e12 Guido Trotter
    @return: (all files, optional files)
295 e1b8653f Guido Trotter

296 e1b8653f Guido Trotter
    """
297 e1b8653f Guido Trotter
    # By default we return a member variable, so that if an hypervisor has just
298 e1b8653f Guido Trotter
    # a static list of files it doesn't have to override this function.
299 69ab2e12 Guido Trotter
    assert set(cls.ANCILLARY_FILES).issuperset(cls.ANCILLARY_FILES_OPT), \
300 69ab2e12 Guido Trotter
      "Optional ancillary files must be a subset of ancillary files"
301 69ab2e12 Guido Trotter
302 69ab2e12 Guido Trotter
    return (cls.ANCILLARY_FILES, cls.ANCILLARY_FILES_OPT)
303 e1b8653f Guido Trotter
304 75bf3149 Helga Velroyen
  def Verify(self, hvparams=None):
305 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
306 65a6f9b7 Michael Hanselmann

307 75bf3149 Helga Velroyen
    @type hvparams: dict of strings
308 75bf3149 Helga Velroyen
    @param hvparams: hypervisor parameters to be verified against
309 75bf3149 Helga Velroyen

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

312 65a6f9b7 Michael Hanselmann
    """
313 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
314 6e7275c0 Iustin Pop
315 b459a848 Andrea Spadaccini
  def MigrationInfo(self, instance): # pylint: disable=R0201,W0613
316 cd42d0ad Guido Trotter
    """Get instance information to perform a migration.
317 cd42d0ad Guido Trotter

318 cd42d0ad Guido Trotter
    By default assume no information is needed.
319 cd42d0ad Guido Trotter

320 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
321 cd42d0ad Guido Trotter
    @param instance: instance to be migrated
322 cd42d0ad Guido Trotter
    @rtype: string/data (opaque)
323 cd42d0ad Guido Trotter
    @return: instance migration information - serialized form
324 cd42d0ad Guido Trotter

325 cd42d0ad Guido Trotter
    """
326 d0c8c01d Iustin Pop
    return ""
327 cd42d0ad Guido Trotter
328 cd42d0ad Guido Trotter
  def AcceptInstance(self, instance, info, target):
329 cd42d0ad Guido Trotter
    """Prepare to accept an instance.
330 cd42d0ad Guido Trotter

331 cd42d0ad Guido Trotter
    By default assume no preparation is needed.
332 cd42d0ad Guido Trotter

333 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
334 cd42d0ad Guido Trotter
    @param instance: instance to be accepted
335 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
336 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
337 cd42d0ad Guido Trotter
    @type target: string
338 cd42d0ad Guido Trotter
    @param target: target host (usually ip), on this node
339 cd42d0ad Guido Trotter

340 cd42d0ad Guido Trotter
    """
341 cd42d0ad Guido Trotter
    pass
342 cd42d0ad Guido Trotter
343 b990eedd Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
344 b990eedd Guido Trotter
    """Balloon an instance memory to a certain value.
345 b990eedd Guido Trotter

346 b990eedd Guido Trotter
    @type instance: L{objects.Instance}
347 b990eedd Guido Trotter
    @param instance: instance to be accepted
348 b990eedd Guido Trotter
    @type mem: int
349 b990eedd Guido Trotter
    @param mem: actual memory size to use for instance runtime
350 b990eedd Guido Trotter

351 b990eedd Guido Trotter
    """
352 b990eedd Guido Trotter
    raise NotImplementedError
353 b990eedd Guido Trotter
354 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
355 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
356 cd42d0ad Guido Trotter

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

360 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
361 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
362 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
363 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
364 cd42d0ad Guido Trotter
    @type success: boolean
365 cd42d0ad Guido Trotter
    @param success: whether the migration was a success or a failure
366 cd42d0ad Guido Trotter

367 cd42d0ad Guido Trotter
    """
368 cd42d0ad Guido Trotter
    pass
369 cd42d0ad Guido Trotter
370 bc0a2284 Helga Velroyen
  def MigrateInstance(self, cluster_name, instance, target, live):
371 6e7275c0 Iustin Pop
    """Migrate an instance.
372 6e7275c0 Iustin Pop

373 bc0a2284 Helga Velroyen
    @type cluster_name: string
374 bc0a2284 Helga Velroyen
    @param cluster_name: name of the cluster
375 3a488770 Iustin Pop
    @type instance: L{objects.Instance}
376 9044275a Michael Hanselmann
    @param instance: the instance to be migrated
377 cd42d0ad Guido Trotter
    @type target: string
378 cd42d0ad Guido Trotter
    @param target: hostname (usually ip) of the target node
379 cd42d0ad Guido Trotter
    @type live: boolean
380 cd42d0ad Guido Trotter
    @param live: whether to do a live or non-live migration
381 6e7275c0 Iustin Pop

382 6e7275c0 Iustin Pop
    """
383 6e7275c0 Iustin Pop
    raise NotImplementedError
384 f48148c3 Iustin Pop
385 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
386 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
387 6a1434d7 Andrea Spadaccini

388 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
389 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
390 6a1434d7 Andrea Spadaccini
    @type success: bool
391 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
392 6a1434d7 Andrea Spadaccini
    @type live: bool
393 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
394 6a1434d7 Andrea Spadaccini

395 6a1434d7 Andrea Spadaccini
    """
396 6a1434d7 Andrea Spadaccini
    pass
397 6a1434d7 Andrea Spadaccini
398 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
399 6a1434d7 Andrea Spadaccini
    """Get the migration status
400 6a1434d7 Andrea Spadaccini

401 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
402 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
403 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
404 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
405 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
406 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
407 6a1434d7 Andrea Spadaccini

408 6a1434d7 Andrea Spadaccini
    """
409 6a1434d7 Andrea Spadaccini
    raise NotImplementedError
410 6a1434d7 Andrea Spadaccini
411 30b12688 Jose A. Lopes
  def _InstanceStartupMemory(self, instance):
412 61eb1a46 Guido Trotter
    """Get the correct startup memory for an instance
413 61eb1a46 Guido Trotter

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

418 61eb1a46 Guido Trotter
    @type instance: L{objects.Instance}
419 61eb1a46 Guido Trotter
    @param instance: the instance that is being started
420 61eb1a46 Guido Trotter
    @rtype: integer
421 61eb1a46 Guido Trotter
    @return: memory the instance should be started with
422 61eb1a46 Guido Trotter

423 61eb1a46 Guido Trotter
    """
424 30b12688 Jose A. Lopes
    free_memory = self.GetNodeInfo(hvparams=instance.hvparams)["memory_free"]
425 61eb1a46 Guido Trotter
    max_start_mem = min(instance.beparams[constants.BE_MAXMEM], free_memory)
426 61eb1a46 Guido Trotter
    start_mem = max(instance.beparams[constants.BE_MINMEM], max_start_mem)
427 61eb1a46 Guido Trotter
    return start_mem
428 61eb1a46 Guido Trotter
429 f48148c3 Iustin Pop
  @classmethod
430 f48148c3 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
431 f48148c3 Iustin Pop
    """Check the given parameters for validity.
432 f48148c3 Iustin Pop

433 f48148c3 Iustin Pop
    This should check the passed set of parameters for
434 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
435 f48148c3 Iustin Pop

436 f48148c3 Iustin Pop
    @type hvparams:  dict
437 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
438 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
439 f48148c3 Iustin Pop

440 f48148c3 Iustin Pop
    """
441 f48148c3 Iustin Pop
    for key in hvparams:
442 f48148c3 Iustin Pop
      if key not in cls.PARAMETERS:
443 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is not supported" % key)
444 205ab586 Iustin Pop
445 205ab586 Iustin Pop
    # cheap tests that run on the master, should not access the world
446 205ab586 Iustin Pop
    for name, (required, check_fn, errstr, _, _) in cls.PARAMETERS.items():
447 205ab586 Iustin Pop
      if name not in hvparams:
448 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is missing" % name)
449 205ab586 Iustin Pop
      value = hvparams[name]
450 205ab586 Iustin Pop
      if not required and not value:
451 205ab586 Iustin Pop
        continue
452 205ab586 Iustin Pop
      if not value:
453 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is required but"
454 205ab586 Iustin Pop
                                     " is currently not defined" % (name, ))
455 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
456 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails syntax"
457 205ab586 Iustin Pop
                                     " check: %s (current value: '%s')" %
458 205ab586 Iustin Pop
                                     (name, errstr, value))
459 205ab586 Iustin Pop
460 205ab586 Iustin Pop
  @classmethod
461 205ab586 Iustin Pop
  def ValidateParameters(cls, hvparams):
462 f48148c3 Iustin Pop
    """Check the given parameters for validity.
463 f48148c3 Iustin Pop

464 f48148c3 Iustin Pop
    This should check the passed set of parameters for
465 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
466 f48148c3 Iustin Pop

467 f48148c3 Iustin Pop
    @type hvparams:  dict
468 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
469 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
470 f48148c3 Iustin Pop

471 f48148c3 Iustin Pop
    """
472 205ab586 Iustin Pop
    for name, (required, _, _, check_fn, errstr) in cls.PARAMETERS.items():
473 205ab586 Iustin Pop
      value = hvparams[name]
474 205ab586 Iustin Pop
      if not required and not value:
475 205ab586 Iustin Pop
        continue
476 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
477 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails"
478 205ab586 Iustin Pop
                                     " validation: %s (current value: '%s')" %
479 205ab586 Iustin Pop
                                     (name, errstr, value))
480 572e52bf Iustin Pop
481 f5118ade Iustin Pop
  @classmethod
482 8ef418bb Helga Velroyen
  def PowercycleNode(cls, hvparams=None):
483 f5118ade Iustin Pop
    """Hard powercycle a node using hypervisor specific methods.
484 f5118ade Iustin Pop

485 f5118ade Iustin Pop
    This method should hard powercycle the node, using whatever
486 f5118ade Iustin Pop
    methods the hypervisor provides. Note that this means that all
487 f5118ade Iustin Pop
    instances running on the node must be stopped too.
488 f5118ade Iustin Pop

489 8ef418bb Helga Velroyen
    @type hvparams: dict of strings
490 8ef418bb Helga Velroyen
    @param hvparams: hypervisor params to be used on this node
491 8ef418bb Helga Velroyen

492 f5118ade Iustin Pop
    """
493 f5118ade Iustin Pop
    raise NotImplementedError
494 f5118ade Iustin Pop
495 94fed7da Iustin Pop
  @staticmethod
496 23cb5697 Michele Tartara
  def GetLinuxNodeInfo(meminfo="/proc/meminfo", cpuinfo="/proc/cpuinfo"):
497 572e52bf Iustin Pop
    """For linux systems, return actual OS information.
498 572e52bf Iustin Pop

499 572e52bf Iustin Pop
    This is an abstraction for all non-hypervisor-based classes, where
500 572e52bf Iustin Pop
    the node actually sees all the memory and CPUs via the /proc
501 572e52bf Iustin Pop
    interface and standard commands. The other case if for example
502 572e52bf Iustin Pop
    xen, where you only see the hardware resources via xen-specific
503 572e52bf Iustin Pop
    tools.
504 572e52bf Iustin Pop

505 23cb5697 Michele Tartara
    @param meminfo: name of the file containing meminfo
506 23cb5697 Michele Tartara
    @type meminfo: string
507 23cb5697 Michele Tartara
    @param cpuinfo: name of the file containing cpuinfo
508 23cb5697 Michele Tartara
    @type cpuinfo: string
509 572e52bf Iustin Pop
    @return: a dict with the following keys (values in MiB):
510 572e52bf Iustin Pop
          - memory_total: the total memory size on the node
511 572e52bf Iustin Pop
          - memory_free: the available memory on the node for instances
512 572e52bf Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
513 ef14e128 Bernardo Dal Seno
          - cpu_total: total number of CPUs
514 ff05ff94 Bernardo Dal Seno
          - cpu_dom0: number of CPUs used by the node OS
515 ef14e128 Bernardo Dal Seno
          - cpu_nodes: number of NUMA domains
516 ef14e128 Bernardo Dal Seno
          - cpu_sockets: number of physical CPU sockets
517 572e52bf Iustin Pop

518 572e52bf Iustin Pop
    """
519 572e52bf Iustin Pop
    try:
520 23cb5697 Michele Tartara
      data = utils.ReadFile(meminfo).splitlines()
521 572e52bf Iustin Pop
    except EnvironmentError, err:
522 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
523 572e52bf Iustin Pop
524 572e52bf Iustin Pop
    result = {}
525 572e52bf Iustin Pop
    sum_free = 0
526 572e52bf Iustin Pop
    try:
527 572e52bf Iustin Pop
      for line in data:
528 572e52bf Iustin Pop
        splitfields = line.split(":", 1)
529 572e52bf Iustin Pop
530 572e52bf Iustin Pop
        if len(splitfields) > 1:
531 572e52bf Iustin Pop
          key = splitfields[0].strip()
532 572e52bf Iustin Pop
          val = splitfields[1].strip()
533 d0c8c01d Iustin Pop
          if key == "MemTotal":
534 e687ec01 Michael Hanselmann
            result["memory_total"] = int(val.split()[0]) / 1024
535 d0c8c01d Iustin Pop
          elif key in ("MemFree", "Buffers", "Cached"):
536 e687ec01 Michael Hanselmann
            sum_free += int(val.split()[0]) / 1024
537 d0c8c01d Iustin Pop
          elif key == "Active":
538 e687ec01 Michael Hanselmann
            result["memory_dom0"] = int(val.split()[0]) / 1024
539 572e52bf Iustin Pop
    except (ValueError, TypeError), err:
540 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to compute memory usage: %s" %
541 572e52bf Iustin Pop
                                   (err,))
542 d0c8c01d Iustin Pop
    result["memory_free"] = sum_free
543 572e52bf Iustin Pop
544 572e52bf Iustin Pop
    cpu_total = 0
545 572e52bf Iustin Pop
    try:
546 23cb5697 Michele Tartara
      fh = open(cpuinfo)
547 572e52bf Iustin Pop
      try:
548 78f99abb Michele Tartara
        cpu_total = len(re.findall(r"(?m)^processor\s*:\s*[0-9]+\s*$",
549 572e52bf Iustin Pop
                                   fh.read()))
550 572e52bf Iustin Pop
      finally:
551 572e52bf Iustin Pop
        fh.close()
552 572e52bf Iustin Pop
    except EnvironmentError, err:
553 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
554 d0c8c01d Iustin Pop
    result["cpu_total"] = cpu_total
555 ff05ff94 Bernardo Dal Seno
    # We assume that the node OS can access all the CPUs
556 ff05ff94 Bernardo Dal Seno
    result["cpu_dom0"] = cpu_total
557 572e52bf Iustin Pop
    # FIXME: export correct data here
558 d0c8c01d Iustin Pop
    result["cpu_nodes"] = 1
559 d0c8c01d Iustin Pop
    result["cpu_sockets"] = 1
560 572e52bf Iustin Pop
561 572e52bf Iustin Pop
    return result
562 f5118ade Iustin Pop
563 f5118ade Iustin Pop
  @classmethod
564 f5118ade Iustin Pop
  def LinuxPowercycle(cls):
565 f5118ade Iustin Pop
    """Linux-specific powercycle method.
566 f5118ade Iustin Pop

567 f5118ade Iustin Pop
    """
568 f5118ade Iustin Pop
    try:
569 f5118ade Iustin Pop
      fd = os.open("/proc/sysrq-trigger", os.O_WRONLY)
570 f5118ade Iustin Pop
      try:
571 f5118ade Iustin Pop
        os.write(fd, "b")
572 f5118ade Iustin Pop
      finally:
573 f5118ade Iustin Pop
        fd.close()
574 f5118ade Iustin Pop
    except OSError:
575 f5118ade Iustin Pop
      logging.exception("Can't open the sysrq-trigger file")
576 f5118ade Iustin Pop
      result = utils.RunCmd(["reboot", "-n", "-f"])
577 f5118ade Iustin Pop
      if not result:
578 f5118ade Iustin Pop
        logging.error("Can't run shutdown: %s", result.output)
579 53fde1ac Iustin Pop
580 53fde1ac Iustin Pop
  @staticmethod
581 53fde1ac Iustin Pop
  def _FormatVerifyResults(msgs):
582 53fde1ac Iustin Pop
    """Formats the verification results, given a list of errors.
583 53fde1ac Iustin Pop

584 53fde1ac Iustin Pop
    @param msgs: list of errors, possibly empty
585 53fde1ac Iustin Pop
    @return: overall problem description if something is wrong,
586 53fde1ac Iustin Pop
        C{None} otherwise
587 53fde1ac Iustin Pop

588 53fde1ac Iustin Pop
    """
589 53fde1ac Iustin Pop
    if msgs:
590 53fde1ac Iustin Pop
      return "; ".join(msgs)
591 53fde1ac Iustin Pop
    else:
592 53fde1ac Iustin Pop
      return None
593 c5708931 Dimitris Aragiorgis
594 50e0f1d9 Dimitris Aragiorgis
  # pylint: disable=R0201,W0613
595 c5708931 Dimitris Aragiorgis
  def HotAddDevice(self, instance, dev_type, device, extra, seq):
596 c5708931 Dimitris Aragiorgis
    """Hot-add a device.
597 c5708931 Dimitris Aragiorgis

598 c5708931 Dimitris Aragiorgis
    """
599 50e0f1d9 Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported by this hypervisor")
600 c5708931 Dimitris Aragiorgis
601 50e0f1d9 Dimitris Aragiorgis
  # pylint: disable=R0201,W0613
602 c5708931 Dimitris Aragiorgis
  def HotDelDevice(self, instance, dev_type, device, extra, seq):
603 c5708931 Dimitris Aragiorgis
    """Hot-del a device.
604 c5708931 Dimitris Aragiorgis

605 c5708931 Dimitris Aragiorgis
    """
606 50e0f1d9 Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported by this hypervisor")
607 c5708931 Dimitris Aragiorgis
608 50e0f1d9 Dimitris Aragiorgis
  # pylint: disable=R0201,W0613
609 c5708931 Dimitris Aragiorgis
  def HotModDevice(self, instance, dev_type, device, extra, seq):
610 c5708931 Dimitris Aragiorgis
    """Hot-mod a device.
611 c5708931 Dimitris Aragiorgis

612 c5708931 Dimitris Aragiorgis
    """
613 50e0f1d9 Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported by this hypervisor")
614 50e0f1d9 Dimitris Aragiorgis
615 50e0f1d9 Dimitris Aragiorgis
  # pylint: disable=R0201,W0613
616 50e0f1d9 Dimitris Aragiorgis
  def VerifyHotplugSupport(self, instance, action, dev_type):
617 50e0f1d9 Dimitris Aragiorgis
    """Verifies that hotplug is supported.
618 c5708931 Dimitris Aragiorgis

619 24711492 Dimitris Aragiorgis
    Given the target device and hotplug action checks if hotplug is
620 24711492 Dimitris Aragiorgis
    actually supported.
621 50e0f1d9 Dimitris Aragiorgis

622 50e0f1d9 Dimitris Aragiorgis
    @type instance: L{objects.Instance}
623 50e0f1d9 Dimitris Aragiorgis
    @param instance: the instance object
624 50e0f1d9 Dimitris Aragiorgis
    @type action: string
625 50e0f1d9 Dimitris Aragiorgis
    @param action: one of the supported hotplug commands
626 50e0f1d9 Dimitris Aragiorgis
    @type dev_type: string
627 50e0f1d9 Dimitris Aragiorgis
    @param dev_type: one of the supported device types to hotplug
628 50e0f1d9 Dimitris Aragiorgis
    @raise errors.HotplugError: if hotplugging is not supported
629 c5708931 Dimitris Aragiorgis

630 c5708931 Dimitris Aragiorgis
    """
631 24711492 Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported.")
632 24711492 Dimitris Aragiorgis
633 24711492 Dimitris Aragiorgis
  def HotplugSupported(self, instance):
634 24711492 Dimitris Aragiorgis
    """Checks if hotplug is supported.
635 24711492 Dimitris Aragiorgis

636 24711492 Dimitris Aragiorgis
    By default is not. Currently only KVM hypervisor supports it.
637 24711492 Dimitris Aragiorgis

638 24711492 Dimitris Aragiorgis
    """
639 50e0f1d9 Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported by this hypervisor")