Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_base.py @ d271c6fd

History | View | Annotate | Download (12.8 kB)

1 65a6f9b7 Michael Hanselmann
#
2 65a6f9b7 Michael Hanselmann
#
3 65a6f9b7 Michael Hanselmann
4 65a6f9b7 Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 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 205ab586 Iustin Pop
48 205ab586 Iustin Pop
49 205ab586 Iustin Pop
# Read the BaseHypervisor.PARAMETERS docstring for the syntax of the
50 205ab586 Iustin Pop
# _CHECK values
51 205ab586 Iustin Pop
52 205ab586 Iustin Pop
# must be afile
53 17c61836 Guido Trotter
_FILE_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
54 205ab586 Iustin Pop
              os.path.isfile, "not found or not a file")
55 205ab586 Iustin Pop
56 205ab586 Iustin Pop
# must be a directory
57 17c61836 Guido Trotter
_DIR_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
58 205ab586 Iustin Pop
             os.path.isdir, "not found or not a directory")
59 205ab586 Iustin Pop
60 205ab586 Iustin Pop
# nice wrappers for users
61 205ab586 Iustin Pop
REQ_FILE_CHECK = (True, ) + _FILE_CHECK
62 205ab586 Iustin Pop
OPT_FILE_CHECK = (False, ) + _FILE_CHECK
63 205ab586 Iustin Pop
REQ_DIR_CHECK = (True, ) + _DIR_CHECK
64 205ab586 Iustin Pop
OPT_DIR_CHECK = (False, ) + _DIR_CHECK
65 78411c60 Iustin Pop
NET_PORT_CHECK = (True, lambda x: x > 0 and x < 65535, "invalid port number",
66 78411c60 Iustin Pop
                  None, None)
67 205ab586 Iustin Pop
68 205ab586 Iustin Pop
# no checks at all
69 205ab586 Iustin Pop
NO_CHECK = (False, None, None, None, None)
70 205ab586 Iustin Pop
71 205ab586 Iustin Pop
# required, but no other checks
72 205ab586 Iustin Pop
REQUIRED_CHECK = (True, None, None, None, None)
73 205ab586 Iustin Pop
74 d73ef63f Michael Hanselmann
75 205ab586 Iustin Pop
def ParamInSet(required, my_set):
76 205ab586 Iustin Pop
  """Builds parameter checker for set membership.
77 205ab586 Iustin Pop

78 205ab586 Iustin Pop
  @type required: boolean
79 205ab586 Iustin Pop
  @param required: whether this is a required parameter
80 205ab586 Iustin Pop
  @type my_set: tuple, list or set
81 205ab586 Iustin Pop
  @param my_set: allowed values set
82 205ab586 Iustin Pop

83 205ab586 Iustin Pop
  """
84 205ab586 Iustin Pop
  fn = lambda x: x in my_set
85 ab3e6da8 Iustin Pop
  err = ("The value must be one of: %s" % utils.CommaJoin(my_set))
86 205ab586 Iustin Pop
  return (required, fn, err, None, None)
87 f48148c3 Iustin Pop
88 f48148c3 Iustin Pop
89 65a6f9b7 Michael Hanselmann
class BaseHypervisor(object):
90 65a6f9b7 Michael Hanselmann
  """Abstract virtualisation technology interface
91 65a6f9b7 Michael Hanselmann

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

95 205ab586 Iustin Pop
  @cvar PARAMETERS: a dict of parameter name: check type; the check type is
96 205ab586 Iustin Pop
      a five-tuple containing:
97 205ab586 Iustin Pop
          - the required flag (boolean)
98 205ab586 Iustin Pop
          - a function to check for syntax, that will be used in
99 205ab586 Iustin Pop
            L{CheckParameterSyntax}, in the master daemon process
100 205ab586 Iustin Pop
          - an error message for the above function
101 205ab586 Iustin Pop
          - a function to check for parameter validity on the remote node,
102 205ab586 Iustin Pop
            in the L{ValidateParameters} function
103 205ab586 Iustin Pop
          - an error message for the above function
104 d271c6fd Iustin Pop
  @type CAN_MIGRATE: boolean
105 d271c6fd Iustin Pop
  @cvar CAN_MIGRATE: whether this hypervisor can do migration (either
106 d271c6fd Iustin Pop
      live or non-live)
107 205ab586 Iustin Pop

108 65a6f9b7 Michael Hanselmann
  """
109 205ab586 Iustin Pop
  PARAMETERS = {}
110 e1b8653f Guido Trotter
  ANCILLARY_FILES = []
111 d271c6fd Iustin Pop
  CAN_MIGRATE = False
112 f48148c3 Iustin Pop
113 65a6f9b7 Michael Hanselmann
  def __init__(self):
114 65a6f9b7 Michael Hanselmann
    pass
115 65a6f9b7 Michael Hanselmann
116 07813a9e Iustin Pop
  def StartInstance(self, instance, block_devices):
117 65a6f9b7 Michael Hanselmann
    """Start an instance."""
118 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
119 65a6f9b7 Michael Hanselmann
120 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
121 07b49e41 Guido Trotter
    """Stop an instance
122 07b49e41 Guido Trotter

123 07b49e41 Guido Trotter
    @type instance: L{objects.Instance}
124 07b49e41 Guido Trotter
    @param instance: instance to stop
125 07b49e41 Guido Trotter
    @type force: boolean
126 07b49e41 Guido Trotter
    @param force: whether to do a "hard" stop (destroy)
127 07b49e41 Guido Trotter
    @type retry: boolean
128 07b49e41 Guido Trotter
    @param retry: whether this is just a retry call
129 bbcf7ad0 Iustin Pop
    @type name: string or None
130 bbcf7ad0 Iustin Pop
    @param name: if this parameter is passed, the the instance object
131 bbcf7ad0 Iustin Pop
        should not be used (will be passed as None), and the shutdown
132 bbcf7ad0 Iustin Pop
        must be done by name only
133 07b49e41 Guido Trotter

134 07b49e41 Guido Trotter
    """
135 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
136 65a6f9b7 Michael Hanselmann
137 f28ec899 Guido Trotter
  def CleanupInstance(self, instance_name):
138 f28ec899 Guido Trotter
    """Cleanup after a stopped instance
139 f28ec899 Guido Trotter

140 f28ec899 Guido Trotter
    This is an optional method, used by hypervisors that need to cleanup after
141 f28ec899 Guido Trotter
    an instance has been stopped.
142 f28ec899 Guido Trotter

143 f28ec899 Guido Trotter
    @type instance_name: string
144 f28ec899 Guido Trotter
    @param instance_name: instance name to cleanup after
145 f28ec899 Guido Trotter

146 f28ec899 Guido Trotter
    """
147 f28ec899 Guido Trotter
    pass
148 f28ec899 Guido Trotter
149 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
150 65a6f9b7 Michael Hanselmann
    """Reboot an instance."""
151 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
152 65a6f9b7 Michael Hanselmann
153 65a6f9b7 Michael Hanselmann
  def ListInstances(self):
154 65a6f9b7 Michael Hanselmann
    """Get the list of running instances."""
155 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
156 65a6f9b7 Michael Hanselmann
157 65a6f9b7 Michael Hanselmann
  def GetInstanceInfo(self, instance_name):
158 65a6f9b7 Michael Hanselmann
    """Get instance properties.
159 65a6f9b7 Michael Hanselmann

160 cd42d0ad Guido Trotter
    @type instance_name: string
161 c41eea6e Iustin Pop
    @param instance_name: the instance name
162 65a6f9b7 Michael Hanselmann

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

165 65a6f9b7 Michael Hanselmann
    """
166 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
167 65a6f9b7 Michael Hanselmann
168 65a6f9b7 Michael Hanselmann
  def GetAllInstancesInfo(self):
169 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
170 65a6f9b7 Michael Hanselmann

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

173 65a6f9b7 Michael Hanselmann
    """
174 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
175 65a6f9b7 Michael Hanselmann
176 65a6f9b7 Michael Hanselmann
  def GetNodeInfo(self):
177 65a6f9b7 Michael Hanselmann
    """Return information about the node.
178 65a6f9b7 Michael Hanselmann

179 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
180 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
181 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
182 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
183 65a6f9b7 Michael Hanselmann

184 65a6f9b7 Michael Hanselmann
    """
185 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
186 65a6f9b7 Michael Hanselmann
187 637ce7f9 Guido Trotter
  @classmethod
188 5431b2e4 Guido Trotter
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
189 65a6f9b7 Michael Hanselmann
    """Return a command for connecting to the console of an instance.
190 65a6f9b7 Michael Hanselmann

191 65a6f9b7 Michael Hanselmann
    """
192 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
193 65a6f9b7 Michael Hanselmann
194 e1b8653f Guido Trotter
  @classmethod
195 e1b8653f Guido Trotter
  def GetAncillaryFiles(cls):
196 e1b8653f Guido Trotter
    """Return a list of ancillary files to be copied to all nodes as ancillary
197 e1b8653f Guido Trotter
    configuration files.
198 e1b8653f Guido Trotter

199 e1b8653f Guido Trotter
    @rtype: list of strings
200 e1b8653f Guido Trotter
    @return: list of absolute paths of files to ship cluster-wide
201 e1b8653f Guido Trotter

202 e1b8653f Guido Trotter
    """
203 e1b8653f Guido Trotter
    # By default we return a member variable, so that if an hypervisor has just
204 e1b8653f Guido Trotter
    # a static list of files it doesn't have to override this function.
205 e1b8653f Guido Trotter
    return cls.ANCILLARY_FILES
206 e1b8653f Guido Trotter
207 65a6f9b7 Michael Hanselmann
  def Verify(self):
208 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
209 65a6f9b7 Michael Hanselmann

210 65a6f9b7 Michael Hanselmann
    """
211 65a6f9b7 Michael Hanselmann
    raise NotImplementedError
212 6e7275c0 Iustin Pop
213 7260cfbe Iustin Pop
  def MigrationInfo(self, instance): # pylint: disable-msg=R0201,W0613
214 cd42d0ad Guido Trotter
    """Get instance information to perform a migration.
215 cd42d0ad Guido Trotter

216 cd42d0ad Guido Trotter
    By default assume no information is needed.
217 cd42d0ad Guido Trotter

218 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
219 cd42d0ad Guido Trotter
    @param instance: instance to be migrated
220 cd42d0ad Guido Trotter
    @rtype: string/data (opaque)
221 cd42d0ad Guido Trotter
    @return: instance migration information - serialized form
222 cd42d0ad Guido Trotter

223 cd42d0ad Guido Trotter
    """
224 cd42d0ad Guido Trotter
    return ''
225 cd42d0ad Guido Trotter
226 cd42d0ad Guido Trotter
  def AcceptInstance(self, instance, info, target):
227 cd42d0ad Guido Trotter
    """Prepare to accept an instance.
228 cd42d0ad Guido Trotter

229 cd42d0ad Guido Trotter
    By default assume no preparation is needed.
230 cd42d0ad Guido Trotter

231 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
232 cd42d0ad Guido Trotter
    @param instance: instance to be accepted
233 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
234 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
235 cd42d0ad Guido Trotter
    @type target: string
236 cd42d0ad Guido Trotter
    @param target: target host (usually ip), on this node
237 cd42d0ad Guido Trotter

238 cd42d0ad Guido Trotter
    """
239 cd42d0ad Guido Trotter
    pass
240 cd42d0ad Guido Trotter
241 cd42d0ad Guido Trotter
  def FinalizeMigration(self, instance, info, success):
242 cd42d0ad Guido Trotter
    """Finalized an instance migration.
243 cd42d0ad Guido Trotter

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

247 cd42d0ad Guido Trotter
    @type instance: L{objects.Instance}
248 cd42d0ad Guido Trotter
    @param instance: instance whose migration is being aborted
249 cd42d0ad Guido Trotter
    @type info: string/data (opaque)
250 cd42d0ad Guido Trotter
    @param info: migration information, from the source node
251 cd42d0ad Guido Trotter
    @type success: boolean
252 cd42d0ad Guido Trotter
    @param success: whether the migration was a success or a failure
253 cd42d0ad Guido Trotter

254 cd42d0ad Guido Trotter
    """
255 cd42d0ad Guido Trotter
    pass
256 cd42d0ad Guido Trotter
257 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
258 6e7275c0 Iustin Pop
    """Migrate an instance.
259 6e7275c0 Iustin Pop

260 3a488770 Iustin Pop
    @type instance: L{objects.Instance}
261 9044275a Michael Hanselmann
    @param instance: the instance to be migrated
262 cd42d0ad Guido Trotter
    @type target: string
263 cd42d0ad Guido Trotter
    @param target: hostname (usually ip) of the target node
264 cd42d0ad Guido Trotter
    @type live: boolean
265 cd42d0ad Guido Trotter
    @param live: whether to do a live or non-live migration
266 6e7275c0 Iustin Pop

267 6e7275c0 Iustin Pop
    """
268 6e7275c0 Iustin Pop
    raise NotImplementedError
269 f48148c3 Iustin Pop
270 f48148c3 Iustin Pop
  @classmethod
271 f48148c3 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
272 f48148c3 Iustin Pop
    """Check the given parameters for validity.
273 f48148c3 Iustin Pop

274 f48148c3 Iustin Pop
    This should check the passed set of parameters for
275 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
276 f48148c3 Iustin Pop

277 f48148c3 Iustin Pop
    @type hvparams:  dict
278 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
279 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
280 f48148c3 Iustin Pop

281 f48148c3 Iustin Pop
    """
282 f48148c3 Iustin Pop
    for key in hvparams:
283 f48148c3 Iustin Pop
      if key not in cls.PARAMETERS:
284 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is not supported" % key)
285 205ab586 Iustin Pop
286 205ab586 Iustin Pop
    # cheap tests that run on the master, should not access the world
287 205ab586 Iustin Pop
    for name, (required, check_fn, errstr, _, _) in cls.PARAMETERS.items():
288 205ab586 Iustin Pop
      if name not in hvparams:
289 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is missing" % name)
290 205ab586 Iustin Pop
      value = hvparams[name]
291 205ab586 Iustin Pop
      if not required and not value:
292 205ab586 Iustin Pop
        continue
293 205ab586 Iustin Pop
      if not value:
294 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' is required but"
295 205ab586 Iustin Pop
                                     " is currently not defined" % (name, ))
296 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
297 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails syntax"
298 205ab586 Iustin Pop
                                     " check: %s (current value: '%s')" %
299 205ab586 Iustin Pop
                                     (name, errstr, value))
300 205ab586 Iustin Pop
301 205ab586 Iustin Pop
  @classmethod
302 205ab586 Iustin Pop
  def ValidateParameters(cls, hvparams):
303 f48148c3 Iustin Pop
    """Check the given parameters for validity.
304 f48148c3 Iustin Pop

305 f48148c3 Iustin Pop
    This should check the passed set of parameters for
306 f48148c3 Iustin Pop
    validity. Classes should extend, not replace, this function.
307 f48148c3 Iustin Pop

308 f48148c3 Iustin Pop
    @type hvparams:  dict
309 f48148c3 Iustin Pop
    @param hvparams: dictionary with parameter names/value
310 f48148c3 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
311 f48148c3 Iustin Pop

312 f48148c3 Iustin Pop
    """
313 205ab586 Iustin Pop
    for name, (required, _, _, check_fn, errstr) in cls.PARAMETERS.items():
314 205ab586 Iustin Pop
      value = hvparams[name]
315 205ab586 Iustin Pop
      if not required and not value:
316 205ab586 Iustin Pop
        continue
317 205ab586 Iustin Pop
      if check_fn is not None and not check_fn(value):
318 205ab586 Iustin Pop
        raise errors.HypervisorError("Parameter '%s' fails"
319 205ab586 Iustin Pop
                                     " validation: %s (current value: '%s')" %
320 205ab586 Iustin Pop
                                     (name, errstr, value))
321 572e52bf Iustin Pop
322 f5118ade Iustin Pop
  @classmethod
323 f5118ade Iustin Pop
  def PowercycleNode(cls):
324 f5118ade Iustin Pop
    """Hard powercycle a node using hypervisor specific methods.
325 f5118ade Iustin Pop

326 f5118ade Iustin Pop
    This method should hard powercycle the node, using whatever
327 f5118ade Iustin Pop
    methods the hypervisor provides. Note that this means that all
328 f5118ade Iustin Pop
    instances running on the node must be stopped too.
329 f5118ade Iustin Pop

330 f5118ade Iustin Pop
    """
331 f5118ade Iustin Pop
    raise NotImplementedError
332 f5118ade Iustin Pop
333 94fed7da Iustin Pop
  @staticmethod
334 94fed7da Iustin Pop
  def GetLinuxNodeInfo():
335 572e52bf Iustin Pop
    """For linux systems, return actual OS information.
336 572e52bf Iustin Pop

337 572e52bf Iustin Pop
    This is an abstraction for all non-hypervisor-based classes, where
338 572e52bf Iustin Pop
    the node actually sees all the memory and CPUs via the /proc
339 572e52bf Iustin Pop
    interface and standard commands. The other case if for example
340 572e52bf Iustin Pop
    xen, where you only see the hardware resources via xen-specific
341 572e52bf Iustin Pop
    tools.
342 572e52bf Iustin Pop

343 572e52bf Iustin Pop
    @return: a dict with the following keys (values in MiB):
344 572e52bf Iustin Pop
          - memory_total: the total memory size on the node
345 572e52bf Iustin Pop
          - memory_free: the available memory on the node for instances
346 572e52bf Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
347 572e52bf Iustin Pop

348 572e52bf Iustin Pop
    """
349 572e52bf Iustin Pop
    try:
350 3374afa9 Guido Trotter
      data = utils.ReadFile("/proc/meminfo").splitlines()
351 572e52bf Iustin Pop
    except EnvironmentError, err:
352 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
353 572e52bf Iustin Pop
354 572e52bf Iustin Pop
    result = {}
355 572e52bf Iustin Pop
    sum_free = 0
356 572e52bf Iustin Pop
    try:
357 572e52bf Iustin Pop
      for line in data:
358 572e52bf Iustin Pop
        splitfields = line.split(":", 1)
359 572e52bf Iustin Pop
360 572e52bf Iustin Pop
        if len(splitfields) > 1:
361 572e52bf Iustin Pop
          key = splitfields[0].strip()
362 572e52bf Iustin Pop
          val = splitfields[1].strip()
363 572e52bf Iustin Pop
          if key == 'MemTotal':
364 572e52bf Iustin Pop
            result['memory_total'] = int(val.split()[0])/1024
365 572e52bf Iustin Pop
          elif key in ('MemFree', 'Buffers', 'Cached'):
366 572e52bf Iustin Pop
            sum_free += int(val.split()[0])/1024
367 572e52bf Iustin Pop
          elif key == 'Active':
368 572e52bf Iustin Pop
            result['memory_dom0'] = int(val.split()[0])/1024
369 572e52bf Iustin Pop
    except (ValueError, TypeError), err:
370 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to compute memory usage: %s" %
371 572e52bf Iustin Pop
                                   (err,))
372 572e52bf Iustin Pop
    result['memory_free'] = sum_free
373 572e52bf Iustin Pop
374 572e52bf Iustin Pop
    cpu_total = 0
375 572e52bf Iustin Pop
    try:
376 572e52bf Iustin Pop
      fh = open("/proc/cpuinfo")
377 572e52bf Iustin Pop
      try:
378 572e52bf Iustin Pop
        cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
379 572e52bf Iustin Pop
                                   fh.read()))
380 572e52bf Iustin Pop
      finally:
381 572e52bf Iustin Pop
        fh.close()
382 572e52bf Iustin Pop
    except EnvironmentError, err:
383 572e52bf Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
384 572e52bf Iustin Pop
    result['cpu_total'] = cpu_total
385 572e52bf Iustin Pop
    # FIXME: export correct data here
386 572e52bf Iustin Pop
    result['cpu_nodes'] = 1
387 572e52bf Iustin Pop
    result['cpu_sockets'] = 1
388 572e52bf Iustin Pop
389 572e52bf Iustin Pop
    return result
390 f5118ade Iustin Pop
391 f5118ade Iustin Pop
  @classmethod
392 f5118ade Iustin Pop
  def LinuxPowercycle(cls):
393 f5118ade Iustin Pop
    """Linux-specific powercycle method.
394 f5118ade Iustin Pop

395 f5118ade Iustin Pop
    """
396 f5118ade Iustin Pop
    try:
397 f5118ade Iustin Pop
      fd = os.open("/proc/sysrq-trigger", os.O_WRONLY)
398 f5118ade Iustin Pop
      try:
399 f5118ade Iustin Pop
        os.write(fd, "b")
400 f5118ade Iustin Pop
      finally:
401 f5118ade Iustin Pop
        fd.close()
402 f5118ade Iustin Pop
    except OSError:
403 f5118ade Iustin Pop
      logging.exception("Can't open the sysrq-trigger file")
404 f5118ade Iustin Pop
      result = utils.RunCmd(["reboot", "-n", "-f"])
405 f5118ade Iustin Pop
      if not result:
406 f5118ade Iustin Pop
        logging.error("Can't run shutdown: %s", result.output)