Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (10.8 kB)

1 65a6f9b7 Michael Hanselmann
#
2 65a6f9b7 Michael Hanselmann
#
3 65a6f9b7 Michael Hanselmann
4 ef14e128 Bernardo Dal Seno
# Copyright (C) 2006, 2007, 2008, 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
"""Fake hypervisor
23 65a6f9b7 Michael Hanselmann

24 65a6f9b7 Michael Hanselmann
"""
25 65a6f9b7 Michael Hanselmann
26 65a6f9b7 Michael Hanselmann
import os
27 65a6f9b7 Michael Hanselmann
import os.path
28 94fed7da Iustin Pop
import logging
29 65a6f9b7 Michael Hanselmann
30 65a6f9b7 Michael Hanselmann
from ganeti import utils
31 65a6f9b7 Michael Hanselmann
from ganeti import constants
32 65a6f9b7 Michael Hanselmann
from ganeti import errors
33 55cc0a44 Michael Hanselmann
from ganeti import objects
34 9d9bded1 Michael Hanselmann
from ganeti import pathutils
35 a2d32034 Michael Hanselmann
from ganeti.hypervisor import hv_base
36 65a6f9b7 Michael Hanselmann
37 65a6f9b7 Michael Hanselmann
38 a2d32034 Michael Hanselmann
class FakeHypervisor(hv_base.BaseHypervisor):
39 65a6f9b7 Michael Hanselmann
  """Fake hypervisor interface.
40 65a6f9b7 Michael Hanselmann

41 65a6f9b7 Michael Hanselmann
  This can be used for testing the ganeti code without having to have
42 65a6f9b7 Michael Hanselmann
  a real virtualisation software installed.
43 65a6f9b7 Michael Hanselmann

44 65a6f9b7 Michael Hanselmann
  """
45 d76880d8 Thomas Thrainer
  PARAMETERS = {
46 d76880d8 Thomas Thrainer
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
47 d76880d8 Thomas Thrainer
    }
48 d76880d8 Thomas Thrainer
49 d271c6fd Iustin Pop
  CAN_MIGRATE = True
50 d271c6fd Iustin Pop
51 9d9bded1 Michael Hanselmann
  _ROOT_DIR = pathutils.RUN_DIR + "/fake-hypervisor"
52 65a6f9b7 Michael Hanselmann
53 65a6f9b7 Michael Hanselmann
  def __init__(self):
54 a2d32034 Michael Hanselmann
    hv_base.BaseHypervisor.__init__(self)
55 98c98ab9 Guido Trotter
    utils.EnsureDirs([(self._ROOT_DIR, constants.RUN_DIRS_MODE)])
56 65a6f9b7 Michael Hanselmann
57 58e356a9 Helga Velroyen
  def ListInstances(self, hvparams=None):
58 65a6f9b7 Michael Hanselmann
    """Get the list of running instances.
59 65a6f9b7 Michael Hanselmann

60 65a6f9b7 Michael Hanselmann
    """
61 65a6f9b7 Michael Hanselmann
    return os.listdir(self._ROOT_DIR)
62 65a6f9b7 Michael Hanselmann
63 0bbec3af Helga Velroyen
  def GetInstanceInfo(self, instance_name, hvparams=None):
64 65a6f9b7 Michael Hanselmann
    """Get instance properties.
65 65a6f9b7 Michael Hanselmann

66 0bbec3af Helga Velroyen
    @type instance_name: string
67 c41eea6e Iustin Pop
    @param instance_name: the instance name
68 0bbec3af Helga Velroyen
    @type hvparams: dict of strings
69 0bbec3af Helga Velroyen
    @param hvparams: hvparams to be used with this instance
70 c41eea6e Iustin Pop

71 c41eea6e Iustin Pop
    @return: tuple of (name, id, memory, vcpus, stat, times)
72 65a6f9b7 Michael Hanselmann

73 65a6f9b7 Michael Hanselmann
    """
74 3b80eb2c Iustin Pop
    file_name = self._InstanceFile(instance_name)
75 65a6f9b7 Michael Hanselmann
    if not os.path.exists(file_name):
76 65a6f9b7 Michael Hanselmann
      return None
77 65a6f9b7 Michael Hanselmann
    try:
78 bfc30ec0 Iustin Pop
      fh = open(file_name, "r")
79 65a6f9b7 Michael Hanselmann
      try:
80 65a6f9b7 Michael Hanselmann
        inst_id = fh.readline().strip()
81 bfc30ec0 Iustin Pop
        memory = utils.TryConvert(int, fh.readline().strip())
82 4c4b5058 Iustin Pop
        vcpus = utils.TryConvert(int, fh.readline().strip())
83 a3f0f306 Jose A. Lopes
        stat = hv_base.HvInstanceState.RUNNING
84 3fe7d670 Hrvoje Ribicic
        times = 0
85 65a6f9b7 Michael Hanselmann
        return (instance_name, inst_id, memory, vcpus, stat, times)
86 65a6f9b7 Michael Hanselmann
      finally:
87 65a6f9b7 Michael Hanselmann
        fh.close()
88 65a6f9b7 Michael Hanselmann
    except IOError, err:
89 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to list instance %s: %s" %
90 65a6f9b7 Michael Hanselmann
                                   (instance_name, err))
91 65a6f9b7 Michael Hanselmann
92 0200a1af Helga Velroyen
  def GetAllInstancesInfo(self, hvparams=None):
93 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
94 65a6f9b7 Michael Hanselmann

95 0200a1af Helga Velroyen
    @type hvparams: dict of strings
96 0200a1af Helga Velroyen
    @param hvparams: hypervisor parameter
97 c41eea6e Iustin Pop
    @return: list of tuples (name, id, memory, vcpus, stat, times)
98 c41eea6e Iustin Pop

99 65a6f9b7 Michael Hanselmann
    """
100 65a6f9b7 Michael Hanselmann
    data = []
101 65a6f9b7 Michael Hanselmann
    for file_name in os.listdir(self._ROOT_DIR):
102 65a6f9b7 Michael Hanselmann
      try:
103 3b80eb2c Iustin Pop
        fh = open(utils.PathJoin(self._ROOT_DIR, file_name), "r")
104 65a6f9b7 Michael Hanselmann
        inst_id = "-1"
105 bfc30ec0 Iustin Pop
        memory = 0
106 bfc30ec0 Iustin Pop
        vcpus = 1
107 a3f0f306 Jose A. Lopes
        stat = hv_base.HvInstanceState.SHUTDOWN
108 3fe7d670 Hrvoje Ribicic
        times = -1
109 65a6f9b7 Michael Hanselmann
        try:
110 65a6f9b7 Michael Hanselmann
          inst_id = fh.readline().strip()
111 bfc30ec0 Iustin Pop
          memory = utils.TryConvert(int, fh.readline().strip())
112 bfc30ec0 Iustin Pop
          vcpus = utils.TryConvert(int, fh.readline().strip())
113 a3f0f306 Jose A. Lopes
          stat = hv_base.HvInstanceState.RUNNING
114 3fe7d670 Hrvoje Ribicic
          times = 0
115 65a6f9b7 Michael Hanselmann
        finally:
116 65a6f9b7 Michael Hanselmann
          fh.close()
117 65a6f9b7 Michael Hanselmann
        data.append((file_name, inst_id, memory, vcpus, stat, times))
118 65a6f9b7 Michael Hanselmann
      except IOError, err:
119 65a6f9b7 Michael Hanselmann
        raise errors.HypervisorError("Failed to list instances: %s" % err)
120 65a6f9b7 Michael Hanselmann
    return data
121 65a6f9b7 Michael Hanselmann
122 3b80eb2c Iustin Pop
  @classmethod
123 3b80eb2c Iustin Pop
  def _InstanceFile(cls, instance_name):
124 94fed7da Iustin Pop
    """Compute the instance file for an instance name.
125 94fed7da Iustin Pop

126 94fed7da Iustin Pop
    """
127 3b80eb2c Iustin Pop
    return utils.PathJoin(cls._ROOT_DIR, instance_name)
128 94fed7da Iustin Pop
129 94fed7da Iustin Pop
  def _IsAlive(self, instance_name):
130 94fed7da Iustin Pop
    """Checks if an instance is alive.
131 94fed7da Iustin Pop

132 94fed7da Iustin Pop
    """
133 94fed7da Iustin Pop
    file_name = self._InstanceFile(instance_name)
134 94fed7da Iustin Pop
    return os.path.exists(file_name)
135 94fed7da Iustin Pop
136 cfb5f9da Guido Trotter
  def _MarkUp(self, instance, memory):
137 94fed7da Iustin Pop
    """Mark the instance as running.
138 94fed7da Iustin Pop

139 94fed7da Iustin Pop
    This does no checks, which should be done by its callers.
140 94fed7da Iustin Pop

141 94fed7da Iustin Pop
    """
142 94fed7da Iustin Pop
    file_name = self._InstanceFile(instance.name)
143 94fed7da Iustin Pop
    fh = file(file_name, "w")
144 94fed7da Iustin Pop
    try:
145 94fed7da Iustin Pop
      fh.write("0\n%d\n%d\n" %
146 cfb5f9da Guido Trotter
               (memory,
147 94fed7da Iustin Pop
                instance.beparams[constants.BE_VCPUS]))
148 94fed7da Iustin Pop
    finally:
149 94fed7da Iustin Pop
      fh.close()
150 94fed7da Iustin Pop
151 bbcf7ad0 Iustin Pop
  def _MarkDown(self, instance_name):
152 94fed7da Iustin Pop
    """Mark the instance as running.
153 94fed7da Iustin Pop

154 94fed7da Iustin Pop
    This does no checks, which should be done by its callers.
155 94fed7da Iustin Pop

156 94fed7da Iustin Pop
    """
157 bbcf7ad0 Iustin Pop
    file_name = self._InstanceFile(instance_name)
158 94fed7da Iustin Pop
    utils.RemoveFile(file_name)
159 94fed7da Iustin Pop
160 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
161 65a6f9b7 Michael Hanselmann
    """Start an instance.
162 65a6f9b7 Michael Hanselmann

163 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, it just creates a file in the base dir,
164 65a6f9b7 Michael Hanselmann
    creating an exception if it already exists. We don't actually
165 65a6f9b7 Michael Hanselmann
    handle race conditions properly, since these are *FAKE* instances.
166 65a6f9b7 Michael Hanselmann

167 65a6f9b7 Michael Hanselmann
    """
168 94fed7da Iustin Pop
    if self._IsAlive(instance.name):
169 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
170 65a6f9b7 Michael Hanselmann
                                   (instance.name, "already running"))
171 65a6f9b7 Michael Hanselmann
    try:
172 61eb1a46 Guido Trotter
      self._MarkUp(instance, self._InstanceStartupMemory(instance))
173 65a6f9b7 Michael Hanselmann
    except IOError, err:
174 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
175 65a6f9b7 Michael Hanselmann
                                   (instance.name, err))
176 65a6f9b7 Michael Hanselmann
177 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
178 65a6f9b7 Michael Hanselmann
    """Stop an instance.
179 65a6f9b7 Michael Hanselmann

180 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, this just removes the file in the base
181 65a6f9b7 Michael Hanselmann
    dir, if it exist, otherwise we raise an exception.
182 65a6f9b7 Michael Hanselmann

183 65a6f9b7 Michael Hanselmann
    """
184 bbcf7ad0 Iustin Pop
    if name is None:
185 bbcf7ad0 Iustin Pop
      name = instance.name
186 bbcf7ad0 Iustin Pop
    if not self._IsAlive(name):
187 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to stop instance %s: %s" %
188 bbcf7ad0 Iustin Pop
                                   (name, "not running"))
189 bbcf7ad0 Iustin Pop
    self._MarkDown(name)
190 65a6f9b7 Michael Hanselmann
191 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
192 65a6f9b7 Michael Hanselmann
    """Reboot an instance.
193 65a6f9b7 Michael Hanselmann

194 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, this does nothing.
195 65a6f9b7 Michael Hanselmann

196 65a6f9b7 Michael Hanselmann
    """
197 65a6f9b7 Michael Hanselmann
    return
198 65a6f9b7 Michael Hanselmann
199 cfb5f9da Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
200 cfb5f9da Guido Trotter
    """Balloon an instance memory to a certain value.
201 cfb5f9da Guido Trotter

202 cfb5f9da Guido Trotter
    @type instance: L{objects.Instance}
203 cfb5f9da Guido Trotter
    @param instance: instance to be accepted
204 cfb5f9da Guido Trotter
    @type mem: int
205 cfb5f9da Guido Trotter
    @param mem: actual memory size to use for instance runtime
206 cfb5f9da Guido Trotter

207 cfb5f9da Guido Trotter
    """
208 cfb5f9da Guido Trotter
    if not self._IsAlive(instance.name):
209 cfb5f9da Guido Trotter
      raise errors.HypervisorError("Failed to balloon memory for %s: %s" %
210 cfb5f9da Guido Trotter
                                   (instance.name, "not running"))
211 cfb5f9da Guido Trotter
    try:
212 cfb5f9da Guido Trotter
      self._MarkUp(instance, mem)
213 cfb5f9da Guido Trotter
    except EnvironmentError, err:
214 cfb5f9da Guido Trotter
      raise errors.HypervisorError("Failed to balloon memory for %s: %s" %
215 cfb5f9da Guido Trotter
                                   (instance.name, utils.ErrnoOrStr(err)))
216 cfb5f9da Guido Trotter
217 fac489a5 Helga Velroyen
  def GetNodeInfo(self, hvparams=None):
218 65a6f9b7 Michael Hanselmann
    """Return information about the node.
219 65a6f9b7 Michael Hanselmann

220 ef14e128 Bernardo Dal Seno
    See L{BaseHypervisor.GetLinuxNodeInfo}.
221 65a6f9b7 Michael Hanselmann

222 65a6f9b7 Michael Hanselmann
    """
223 572e52bf Iustin Pop
    result = self.GetLinuxNodeInfo()
224 bfc30ec0 Iustin Pop
    # substract running instances
225 bfc30ec0 Iustin Pop
    all_instances = self.GetAllInstancesInfo()
226 d0c8c01d Iustin Pop
    result["memory_free"] -= min(result["memory_free"],
227 bfc30ec0 Iustin Pop
                                 sum([row[2] for row in all_instances]))
228 65a6f9b7 Michael Hanselmann
    return result
229 65a6f9b7 Michael Hanselmann
230 637ce7f9 Guido Trotter
  @classmethod
231 c42be2c0 Petr Pudlak
  def GetInstanceConsole(cls, instance, primary_node, node_group,
232 c42be2c0 Petr Pudlak
                         hvparams, beparams):
233 55cc0a44 Michael Hanselmann
    """Return information for connecting to the console of an instance.
234 65a6f9b7 Michael Hanselmann

235 65a6f9b7 Michael Hanselmann
    """
236 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
237 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
238 55cc0a44 Michael Hanselmann
                                   message=("Console not available for fake"
239 55cc0a44 Michael Hanselmann
                                            " hypervisor"))
240 65a6f9b7 Michael Hanselmann
241 75bf3149 Helga Velroyen
  def Verify(self, hvparams=None):
242 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
243 65a6f9b7 Michael Hanselmann

244 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, it just checks the existence of the base
245 65a6f9b7 Michael Hanselmann
    dir.
246 65a6f9b7 Michael Hanselmann

247 75bf3149 Helga Velroyen
    @type hvparams: dict of strings
248 75bf3149 Helga Velroyen
    @param hvparams: hypervisor parameters to be verified against; not used
249 75bf3149 Helga Velroyen
      for fake hypervisors
250 75bf3149 Helga Velroyen

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

253 65a6f9b7 Michael Hanselmann
    """
254 cd04dfd2 Michael Hanselmann
    if os.path.exists(self._ROOT_DIR):
255 cd04dfd2 Michael Hanselmann
      return None
256 cd04dfd2 Michael Hanselmann
    else:
257 cd04dfd2 Michael Hanselmann
      return "The required directory '%s' does not exist" % self._ROOT_DIR
258 f5118ade Iustin Pop
259 f5118ade Iustin Pop
  @classmethod
260 8ef418bb Helga Velroyen
  def PowercycleNode(cls, hvparams=None):
261 f5118ade Iustin Pop
    """Fake hypervisor powercycle, just a wrapper over Linux powercycle.
262 f5118ade Iustin Pop

263 8ef418bb Helga Velroyen
    @type hvparams: dict of strings
264 8ef418bb Helga Velroyen
    @param hvparams: hypervisor params to be used on this node
265 8ef418bb Helga Velroyen

266 f5118ade Iustin Pop
    """
267 f5118ade Iustin Pop
    cls.LinuxPowercycle()
268 94fed7da Iustin Pop
269 94fed7da Iustin Pop
  def AcceptInstance(self, instance, info, target):
270 94fed7da Iustin Pop
    """Prepare to accept an instance.
271 94fed7da Iustin Pop

272 94fed7da Iustin Pop
    @type instance: L{objects.Instance}
273 94fed7da Iustin Pop
    @param instance: instance to be accepted
274 94fed7da Iustin Pop
    @type info: string
275 94fed7da Iustin Pop
    @param info: instance info, not used
276 94fed7da Iustin Pop
    @type target: string
277 94fed7da Iustin Pop
    @param target: target host (usually ip), on this node
278 94fed7da Iustin Pop

279 94fed7da Iustin Pop
    """
280 94fed7da Iustin Pop
    if self._IsAlive(instance.name):
281 94fed7da Iustin Pop
      raise errors.HypervisorError("Can't accept instance, already running")
282 94fed7da Iustin Pop
283 bc0a2284 Helga Velroyen
  def MigrateInstance(self, cluster_name, instance, target, live):
284 94fed7da Iustin Pop
    """Migrate an instance.
285 94fed7da Iustin Pop

286 bc0a2284 Helga Velroyen
    @type cluster_name: string
287 bc0a2284 Helga Velroyen
    @param cluster_name: name of the cluster
288 3a488770 Iustin Pop
    @type instance: L{objects.Instance}
289 94fed7da Iustin Pop
    @param instance: the instance to be migrated
290 94fed7da Iustin Pop
    @type target: string
291 94fed7da Iustin Pop
    @param target: hostname (usually ip) of the target node
292 94fed7da Iustin Pop
    @type live: boolean
293 94fed7da Iustin Pop
    @param live: whether to do a live or non-live migration
294 94fed7da Iustin Pop

295 94fed7da Iustin Pop
    """
296 94fed7da Iustin Pop
    logging.debug("Fake hypervisor migrating %s to %s (live=%s)",
297 94fed7da Iustin Pop
                  instance, target, live)
298 94fed7da Iustin Pop
299 60af751d Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
300 60af751d Andrea Spadaccini
    """Finalize the instance migration on the target node.
301 94fed7da Iustin Pop

302 94fed7da Iustin Pop
    For the fake hv, this just marks the instance up.
303 94fed7da Iustin Pop

304 94fed7da Iustin Pop
    @type instance: L{objects.Instance}
305 94fed7da Iustin Pop
    @param instance: instance whose migration is being finalized
306 60af751d Andrea Spadaccini
    @type info: string/data (opaque)
307 60af751d Andrea Spadaccini
    @param info: migration information, from the source node
308 60af751d Andrea Spadaccini
    @type success: boolean
309 60af751d Andrea Spadaccini
    @param success: whether the migration was a success or a failure
310 94fed7da Iustin Pop

311 94fed7da Iustin Pop
    """
312 94fed7da Iustin Pop
    if success:
313 61eb1a46 Guido Trotter
      self._MarkUp(instance, self._InstanceStartupMemory(instance))
314 94fed7da Iustin Pop
    else:
315 94fed7da Iustin Pop
      # ensure it's down
316 bbcf7ad0 Iustin Pop
      self._MarkDown(instance.name)
317 60af751d Andrea Spadaccini
318 60af751d Andrea Spadaccini
  def PostMigrationCleanup(self, instance):
319 60af751d Andrea Spadaccini
    """Clean-up after a migration.
320 60af751d Andrea Spadaccini

321 60af751d Andrea Spadaccini
    To be executed on the source node.
322 60af751d Andrea Spadaccini

323 60af751d Andrea Spadaccini
    @type instance: L{objects.Instance}
324 60af751d Andrea Spadaccini
    @param instance: the instance that was migrated
325 60af751d Andrea Spadaccini

326 60af751d Andrea Spadaccini
    """
327 60af751d Andrea Spadaccini
    pass
328 60af751d Andrea Spadaccini
329 60af751d Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
330 60af751d Andrea Spadaccini
    """Finalize the instance migration on the source node.
331 60af751d Andrea Spadaccini

332 60af751d Andrea Spadaccini
    @type instance: L{objects.Instance}
333 60af751d Andrea Spadaccini
    @param instance: the instance that was migrated
334 60af751d Andrea Spadaccini
    @type success: bool
335 60af751d Andrea Spadaccini
    @param success: whether the migration succeeded or not
336 60af751d Andrea Spadaccini
    @type live: bool
337 60af751d Andrea Spadaccini
    @param live: whether the user requested a live migration or not
338 60af751d Andrea Spadaccini

339 60af751d Andrea Spadaccini
    """
340 60af751d Andrea Spadaccini
    # pylint: disable=W0613
341 60af751d Andrea Spadaccini
    if success:
342 60af751d Andrea Spadaccini
      self._MarkDown(instance.name)
343 60af751d Andrea Spadaccini
344 60af751d Andrea Spadaccini
  def GetMigrationStatus(self, instance):
345 60af751d Andrea Spadaccini
    """Get the migration status
346 60af751d Andrea Spadaccini

347 60af751d Andrea Spadaccini
    The fake hypervisor migration always succeeds.
348 60af751d Andrea Spadaccini

349 60af751d Andrea Spadaccini
    @type instance: L{objects.Instance}
350 60af751d Andrea Spadaccini
    @param instance: the instance that is being migrated
351 60af751d Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
352 60af751d Andrea Spadaccini
    @return: the status of the current migration (one of
353 60af751d Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
354 60af751d Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
355 60af751d Andrea Spadaccini

356 60af751d Andrea Spadaccini
    """
357 60af751d Andrea Spadaccini
    return objects.MigrationStatus(status=constants.HV_MIGRATION_COMPLETED)