Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_fake.py @ 56452af7

History | View | Annotate | Download (7.7 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
"""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 a2d32034 Michael Hanselmann
from ganeti.hypervisor import hv_base
34 65a6f9b7 Michael Hanselmann
35 65a6f9b7 Michael Hanselmann
36 a2d32034 Michael Hanselmann
class FakeHypervisor(hv_base.BaseHypervisor):
37 65a6f9b7 Michael Hanselmann
  """Fake hypervisor interface.
38 65a6f9b7 Michael Hanselmann

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

42 65a6f9b7 Michael Hanselmann
  """
43 65a6f9b7 Michael Hanselmann
  _ROOT_DIR = constants.RUN_DIR + "/ganeti-fake-hypervisor"
44 65a6f9b7 Michael Hanselmann
45 65a6f9b7 Michael Hanselmann
  def __init__(self):
46 a2d32034 Michael Hanselmann
    hv_base.BaseHypervisor.__init__(self)
47 65a6f9b7 Michael Hanselmann
    if not os.path.exists(self._ROOT_DIR):
48 65a6f9b7 Michael Hanselmann
      os.mkdir(self._ROOT_DIR)
49 65a6f9b7 Michael Hanselmann
50 65a6f9b7 Michael Hanselmann
  def ListInstances(self):
51 65a6f9b7 Michael Hanselmann
    """Get the list of running instances.
52 65a6f9b7 Michael Hanselmann

53 65a6f9b7 Michael Hanselmann
    """
54 65a6f9b7 Michael Hanselmann
    return os.listdir(self._ROOT_DIR)
55 65a6f9b7 Michael Hanselmann
56 65a6f9b7 Michael Hanselmann
  def GetInstanceInfo(self, instance_name):
57 65a6f9b7 Michael Hanselmann
    """Get instance properties.
58 65a6f9b7 Michael Hanselmann

59 c41eea6e Iustin Pop
    @param instance_name: the instance name
60 c41eea6e Iustin Pop

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

63 65a6f9b7 Michael Hanselmann
    """
64 65a6f9b7 Michael Hanselmann
    file_name = "%s/%s" % (self._ROOT_DIR, instance_name)
65 65a6f9b7 Michael Hanselmann
    if not os.path.exists(file_name):
66 65a6f9b7 Michael Hanselmann
      return None
67 65a6f9b7 Michael Hanselmann
    try:
68 bfc30ec0 Iustin Pop
      fh = open(file_name, "r")
69 65a6f9b7 Michael Hanselmann
      try:
70 65a6f9b7 Michael Hanselmann
        inst_id = fh.readline().strip()
71 bfc30ec0 Iustin Pop
        memory = utils.TryConvert(int, fh.readline().strip())
72 4c4b5058 Iustin Pop
        vcpus = utils.TryConvert(int, fh.readline().strip())
73 65a6f9b7 Michael Hanselmann
        stat = "---b-"
74 65a6f9b7 Michael Hanselmann
        times = "0"
75 65a6f9b7 Michael Hanselmann
        return (instance_name, inst_id, memory, vcpus, stat, times)
76 65a6f9b7 Michael Hanselmann
      finally:
77 65a6f9b7 Michael Hanselmann
        fh.close()
78 65a6f9b7 Michael Hanselmann
    except IOError, err:
79 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to list instance %s: %s" %
80 65a6f9b7 Michael Hanselmann
                                   (instance_name, err))
81 65a6f9b7 Michael Hanselmann
82 65a6f9b7 Michael Hanselmann
  def GetAllInstancesInfo(self):
83 65a6f9b7 Michael Hanselmann
    """Get properties of all instances.
84 65a6f9b7 Michael Hanselmann

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

87 65a6f9b7 Michael Hanselmann
    """
88 65a6f9b7 Michael Hanselmann
    data = []
89 65a6f9b7 Michael Hanselmann
    for file_name in os.listdir(self._ROOT_DIR):
90 65a6f9b7 Michael Hanselmann
      try:
91 d73ef63f Michael Hanselmann
        fh = open(self._ROOT_DIR + "/" + file_name, "r")
92 65a6f9b7 Michael Hanselmann
        inst_id = "-1"
93 bfc30ec0 Iustin Pop
        memory = 0
94 bfc30ec0 Iustin Pop
        vcpus = 1
95 65a6f9b7 Michael Hanselmann
        stat = "-----"
96 65a6f9b7 Michael Hanselmann
        times = "-1"
97 65a6f9b7 Michael Hanselmann
        try:
98 65a6f9b7 Michael Hanselmann
          inst_id = fh.readline().strip()
99 bfc30ec0 Iustin Pop
          memory = utils.TryConvert(int, fh.readline().strip())
100 bfc30ec0 Iustin Pop
          vcpus = utils.TryConvert(int, fh.readline().strip())
101 65a6f9b7 Michael Hanselmann
          stat = "---b-"
102 65a6f9b7 Michael Hanselmann
          times = "0"
103 65a6f9b7 Michael Hanselmann
        finally:
104 65a6f9b7 Michael Hanselmann
          fh.close()
105 65a6f9b7 Michael Hanselmann
        data.append((file_name, inst_id, memory, vcpus, stat, times))
106 65a6f9b7 Michael Hanselmann
      except IOError, err:
107 65a6f9b7 Michael Hanselmann
        raise errors.HypervisorError("Failed to list instances: %s" % err)
108 65a6f9b7 Michael Hanselmann
    return data
109 65a6f9b7 Michael Hanselmann
110 94fed7da Iustin Pop
111 94fed7da Iustin Pop
  def _InstanceFile(self, instance_name):
112 94fed7da Iustin Pop
    """Compute the instance file for an instance name.
113 94fed7da Iustin Pop

114 94fed7da Iustin Pop
    """
115 94fed7da Iustin Pop
    return self._ROOT_DIR + "/%s" % instance_name
116 94fed7da Iustin Pop
117 94fed7da Iustin Pop
  def _IsAlive(self, instance_name):
118 94fed7da Iustin Pop
    """Checks if an instance is alive.
119 94fed7da Iustin Pop

120 94fed7da Iustin Pop
    """
121 94fed7da Iustin Pop
    file_name = self._InstanceFile(instance_name)
122 94fed7da Iustin Pop
    return os.path.exists(file_name)
123 94fed7da Iustin Pop
124 94fed7da Iustin Pop
  def _MarkUp(self, instance):
125 94fed7da Iustin Pop
    """Mark the instance as running.
126 94fed7da Iustin Pop

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

129 94fed7da Iustin Pop
    """
130 94fed7da Iustin Pop
    file_name = self._InstanceFile(instance.name)
131 94fed7da Iustin Pop
    fh = file(file_name, "w")
132 94fed7da Iustin Pop
    try:
133 94fed7da Iustin Pop
      fh.write("0\n%d\n%d\n" %
134 94fed7da Iustin Pop
               (instance.beparams[constants.BE_MEMORY],
135 94fed7da Iustin Pop
                instance.beparams[constants.BE_VCPUS]))
136 94fed7da Iustin Pop
    finally:
137 94fed7da Iustin Pop
      fh.close()
138 94fed7da Iustin Pop
139 94fed7da Iustin Pop
  def _MarkDown(self, instance):
140 94fed7da Iustin Pop
    """Mark the instance as running.
141 94fed7da Iustin Pop

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

144 94fed7da Iustin Pop
    """
145 94fed7da Iustin Pop
    file_name = self._InstanceFile(instance.name)
146 94fed7da Iustin Pop
    utils.RemoveFile(file_name)
147 94fed7da Iustin Pop
148 07813a9e Iustin Pop
  def StartInstance(self, instance, block_devices):
149 65a6f9b7 Michael Hanselmann
    """Start an instance.
150 65a6f9b7 Michael Hanselmann

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

155 65a6f9b7 Michael Hanselmann
    """
156 94fed7da Iustin Pop
    if self._IsAlive(instance.name):
157 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
158 65a6f9b7 Michael Hanselmann
                                   (instance.name, "already running"))
159 65a6f9b7 Michael Hanselmann
    try:
160 94fed7da Iustin Pop
      self._MarkUp(instance)
161 65a6f9b7 Michael Hanselmann
    except IOError, err:
162 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
163 65a6f9b7 Michael Hanselmann
                                   (instance.name, err))
164 65a6f9b7 Michael Hanselmann
165 07b49e41 Guido Trotter
  def StopInstance(self, instance, force=False, retry=False):
166 65a6f9b7 Michael Hanselmann
    """Stop an instance.
167 65a6f9b7 Michael Hanselmann

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

171 65a6f9b7 Michael Hanselmann
    """
172 94fed7da Iustin Pop
    if not self._IsAlive(instance.name):
173 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to stop instance %s: %s" %
174 65a6f9b7 Michael Hanselmann
                                   (instance.name, "not running"))
175 94fed7da Iustin Pop
    self._MarkDown(instance)
176 65a6f9b7 Michael Hanselmann
177 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
178 65a6f9b7 Michael Hanselmann
    """Reboot an instance.
179 65a6f9b7 Michael Hanselmann

180 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, this does nothing.
181 65a6f9b7 Michael Hanselmann

182 65a6f9b7 Michael Hanselmann
    """
183 65a6f9b7 Michael Hanselmann
    return
184 65a6f9b7 Michael Hanselmann
185 65a6f9b7 Michael Hanselmann
  def GetNodeInfo(self):
186 65a6f9b7 Michael Hanselmann
    """Return information about the node.
187 65a6f9b7 Michael Hanselmann

188 572e52bf Iustin Pop
    This is just a wrapper over the base GetLinuxNodeInfo method.
189 572e52bf Iustin Pop

190 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
191 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
192 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
193 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
194 65a6f9b7 Michael Hanselmann

195 65a6f9b7 Michael Hanselmann
    """
196 572e52bf Iustin Pop
    result = self.GetLinuxNodeInfo()
197 bfc30ec0 Iustin Pop
    # substract running instances
198 bfc30ec0 Iustin Pop
    all_instances = self.GetAllInstancesInfo()
199 bfc30ec0 Iustin Pop
    result['memory_free'] -= min(result['memory_free'],
200 bfc30ec0 Iustin Pop
                                 sum([row[2] for row in all_instances]))
201 65a6f9b7 Michael Hanselmann
    return result
202 65a6f9b7 Michael Hanselmann
203 637ce7f9 Guido Trotter
  @classmethod
204 5431b2e4 Guido Trotter
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
205 65a6f9b7 Michael Hanselmann
    """Return a command for connecting to the console of an instance.
206 65a6f9b7 Michael Hanselmann

207 65a6f9b7 Michael Hanselmann
    """
208 65a6f9b7 Michael Hanselmann
    return "echo Console not available for fake hypervisor"
209 65a6f9b7 Michael Hanselmann
210 65a6f9b7 Michael Hanselmann
  def Verify(self):
211 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
212 65a6f9b7 Michael Hanselmann

213 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, it just checks the existence of the base
214 65a6f9b7 Michael Hanselmann
    dir.
215 65a6f9b7 Michael Hanselmann

216 65a6f9b7 Michael Hanselmann
    """
217 65a6f9b7 Michael Hanselmann
    if not os.path.exists(self._ROOT_DIR):
218 65a6f9b7 Michael Hanselmann
      return "The required directory '%s' does not exist." % self._ROOT_DIR
219 f5118ade Iustin Pop
220 f5118ade Iustin Pop
  @classmethod
221 f5118ade Iustin Pop
  def PowercycleNode(cls):
222 f5118ade Iustin Pop
    """Fake hypervisor powercycle, just a wrapper over Linux powercycle.
223 f5118ade Iustin Pop

224 f5118ade Iustin Pop
    """
225 f5118ade Iustin Pop
    cls.LinuxPowercycle()
226 94fed7da Iustin Pop
227 94fed7da Iustin Pop
  def AcceptInstance(self, instance, info, target):
228 94fed7da Iustin Pop
    """Prepare to accept an instance.
229 94fed7da Iustin Pop

230 94fed7da Iustin Pop
    @type instance: L{objects.Instance}
231 94fed7da Iustin Pop
    @param instance: instance to be accepted
232 94fed7da Iustin Pop
    @type info: string
233 94fed7da Iustin Pop
    @param info: instance info, not used
234 94fed7da Iustin Pop
    @type target: string
235 94fed7da Iustin Pop
    @param target: target host (usually ip), on this node
236 94fed7da Iustin Pop

237 94fed7da Iustin Pop
    """
238 94fed7da Iustin Pop
    if self._IsAlive(instance.name):
239 94fed7da Iustin Pop
      raise errors.HypervisorError("Can't accept instance, already running")
240 94fed7da Iustin Pop
241 94fed7da Iustin Pop
  def MigrateInstance(self, instance, target, live):
242 94fed7da Iustin Pop
    """Migrate an instance.
243 94fed7da Iustin Pop

244 94fed7da Iustin Pop
    @type instance: L{object.Instance}
245 94fed7da Iustin Pop
    @param instance: the instance to be migrated
246 94fed7da Iustin Pop
    @type target: string
247 94fed7da Iustin Pop
    @param target: hostname (usually ip) of the target node
248 94fed7da Iustin Pop
    @type live: boolean
249 94fed7da Iustin Pop
    @param live: whether to do a live or non-live migration
250 94fed7da Iustin Pop

251 94fed7da Iustin Pop
    """
252 94fed7da Iustin Pop
    logging.debug("Fake hypervisor migrating %s to %s (live=%s)",
253 94fed7da Iustin Pop
                  instance, target, live)
254 94fed7da Iustin Pop
255 94fed7da Iustin Pop
    self._MarkDown(instance)
256 94fed7da Iustin Pop
257 94fed7da Iustin Pop
  def FinalizeMigration(self, instance, info, success):
258 94fed7da Iustin Pop
    """Finalize an instance migration.
259 94fed7da Iustin Pop

260 94fed7da Iustin Pop
    For the fake hv, this just marks the instance up.
261 94fed7da Iustin Pop

262 94fed7da Iustin Pop
    @type instance: L{objects.Instance}
263 94fed7da Iustin Pop
    @param instance: instance whose migration is being finalized
264 94fed7da Iustin Pop

265 94fed7da Iustin Pop
    """
266 94fed7da Iustin Pop
    if success:
267 94fed7da Iustin Pop
      self._MarkUp(instance)
268 94fed7da Iustin Pop
    else:
269 94fed7da Iustin Pop
      # ensure it's down
270 94fed7da Iustin Pop
      self._MarkDown(instance)