Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_fake.py @ 47387b1e

History | View | Annotate | Download (6.5 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 e8a4c138 Iustin Pop
import re
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 65a6f9b7 Michael Hanselmann
    Args:
60 65a6f9b7 Michael Hanselmann
      instance_name: the instance name
61 65a6f9b7 Michael Hanselmann

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

86 65a6f9b7 Michael Hanselmann
    Returns:
87 65a6f9b7 Michael Hanselmann
      [(name, id, memory, vcpus, stat, times),...]
88 65a6f9b7 Michael Hanselmann
    """
89 65a6f9b7 Michael Hanselmann
    data = []
90 65a6f9b7 Michael Hanselmann
    for file_name in os.listdir(self._ROOT_DIR):
91 65a6f9b7 Michael Hanselmann
      try:
92 65a6f9b7 Michael Hanselmann
        fh = file(self._ROOT_DIR+"/"+file_name, "r")
93 65a6f9b7 Michael Hanselmann
        inst_id = "-1"
94 65a6f9b7 Michael Hanselmann
        memory = "0"
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 65a6f9b7 Michael Hanselmann
          memory = fh.readline().strip()
100 65a6f9b7 Michael Hanselmann
          vcpus = 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 a5f723a2 Guido Trotter
  def StartInstance(self, instance, block_devices, extra_args):
111 65a6f9b7 Michael Hanselmann
    """Start an instance.
112 65a6f9b7 Michael Hanselmann

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

117 65a6f9b7 Michael Hanselmann
    """
118 65a6f9b7 Michael Hanselmann
    file_name = self._ROOT_DIR + "/%s" % instance.name
119 65a6f9b7 Michael Hanselmann
    if os.path.exists(file_name):
120 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
121 65a6f9b7 Michael Hanselmann
                                   (instance.name, "already running"))
122 65a6f9b7 Michael Hanselmann
    try:
123 65a6f9b7 Michael Hanselmann
      fh = file(file_name, "w")
124 65a6f9b7 Michael Hanselmann
      try:
125 8b3fd458 Iustin Pop
        fh.write("0\n%d\n%d\n" %
126 8b3fd458 Iustin Pop
                 (instance.beparams[constants.BE_MEMORY],
127 8b3fd458 Iustin Pop
                  instance.beparams[constants.BE_VCPUS]))
128 65a6f9b7 Michael Hanselmann
      finally:
129 65a6f9b7 Michael Hanselmann
        fh.close()
130 65a6f9b7 Michael Hanselmann
    except IOError, err:
131 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to start instance %s: %s" %
132 65a6f9b7 Michael Hanselmann
                                   (instance.name, err))
133 65a6f9b7 Michael Hanselmann
134 65a6f9b7 Michael Hanselmann
  def StopInstance(self, instance, force=False):
135 65a6f9b7 Michael Hanselmann
    """Stop an instance.
136 65a6f9b7 Michael Hanselmann

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

140 65a6f9b7 Michael Hanselmann
    """
141 65a6f9b7 Michael Hanselmann
    file_name = self._ROOT_DIR + "/%s" % instance.name
142 65a6f9b7 Michael Hanselmann
    if not os.path.exists(file_name):
143 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to stop instance %s: %s" %
144 65a6f9b7 Michael Hanselmann
                                   (instance.name, "not running"))
145 65a6f9b7 Michael Hanselmann
    utils.RemoveFile(file_name)
146 65a6f9b7 Michael Hanselmann
147 65a6f9b7 Michael Hanselmann
  def RebootInstance(self, instance):
148 65a6f9b7 Michael Hanselmann
    """Reboot an instance.
149 65a6f9b7 Michael Hanselmann

150 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, this does nothing.
151 65a6f9b7 Michael Hanselmann

152 65a6f9b7 Michael Hanselmann
    """
153 65a6f9b7 Michael Hanselmann
    return
154 65a6f9b7 Michael Hanselmann
155 65a6f9b7 Michael Hanselmann
  def GetNodeInfo(self):
156 65a6f9b7 Michael Hanselmann
    """Return information about the node.
157 65a6f9b7 Michael Hanselmann

158 65a6f9b7 Michael Hanselmann
    The return value is a dict, which has to have the following items:
159 65a6f9b7 Michael Hanselmann
      (all values in MiB)
160 65a6f9b7 Michael Hanselmann
      - memory_total: the total memory size on the node
161 65a6f9b7 Michael Hanselmann
      - memory_free: the available memory on the node for instances
162 65a6f9b7 Michael Hanselmann
      - memory_dom0: the memory used by the node itself, if available
163 65a6f9b7 Michael Hanselmann

164 65a6f9b7 Michael Hanselmann
    """
165 65a6f9b7 Michael Hanselmann
    # global ram usage from the xm info command
166 65a6f9b7 Michael Hanselmann
    # memory                 : 3583
167 65a6f9b7 Michael Hanselmann
    # free_memory            : 747
168 65a6f9b7 Michael Hanselmann
    # note: in xen 3, memory has changed to total_memory
169 65a6f9b7 Michael Hanselmann
    try:
170 65a6f9b7 Michael Hanselmann
      fh = file("/proc/meminfo")
171 65a6f9b7 Michael Hanselmann
      try:
172 65a6f9b7 Michael Hanselmann
        data = fh.readlines()
173 65a6f9b7 Michael Hanselmann
      finally:
174 65a6f9b7 Michael Hanselmann
        fh.close()
175 65a6f9b7 Michael Hanselmann
    except IOError, err:
176 65a6f9b7 Michael Hanselmann
      raise errors.HypervisorError("Failed to list node info: %s" % err)
177 65a6f9b7 Michael Hanselmann
178 65a6f9b7 Michael Hanselmann
    result = {}
179 65a6f9b7 Michael Hanselmann
    sum_free = 0
180 65a6f9b7 Michael Hanselmann
    for line in data:
181 65a6f9b7 Michael Hanselmann
      splitfields = line.split(":", 1)
182 65a6f9b7 Michael Hanselmann
183 65a6f9b7 Michael Hanselmann
      if len(splitfields) > 1:
184 65a6f9b7 Michael Hanselmann
        key = splitfields[0].strip()
185 65a6f9b7 Michael Hanselmann
        val = splitfields[1].strip()
186 65a6f9b7 Michael Hanselmann
        if key == 'MemTotal':
187 65a6f9b7 Michael Hanselmann
          result['memory_total'] = int(val.split()[0])/1024
188 65a6f9b7 Michael Hanselmann
        elif key in ('MemFree', 'Buffers', 'Cached'):
189 65a6f9b7 Michael Hanselmann
          sum_free += int(val.split()[0])/1024
190 65a6f9b7 Michael Hanselmann
        elif key == 'Active':
191 65a6f9b7 Michael Hanselmann
          result['memory_dom0'] = int(val.split()[0])/1024
192 65a6f9b7 Michael Hanselmann
    result['memory_free'] = sum_free
193 e8a4c138 Iustin Pop
194 e8a4c138 Iustin Pop
    cpu_total = 0
195 e8a4c138 Iustin Pop
    try:
196 e8a4c138 Iustin Pop
      fh = open("/proc/cpuinfo")
197 e8a4c138 Iustin Pop
      try:
198 e8a4c138 Iustin Pop
        cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
199 e8a4c138 Iustin Pop
                                   fh.read()))
200 e8a4c138 Iustin Pop
      finally:
201 e8a4c138 Iustin Pop
        fh.close()
202 e8a4c138 Iustin Pop
    except EnvironmentError, err:
203 3b9e6a30 Iustin Pop
      raise errors.HypervisorError("Failed to list node info: %s" % err)
204 e8a4c138 Iustin Pop
    result['cpu_total'] = cpu_total
205 e8a4c138 Iustin Pop
206 65a6f9b7 Michael Hanselmann
    return result
207 65a6f9b7 Michael Hanselmann
208 65a6f9b7 Michael Hanselmann
  @staticmethod
209 65a6f9b7 Michael Hanselmann
  def GetShellCommandForConsole(instance):
210 65a6f9b7 Michael Hanselmann
    """Return a command for connecting to the console of an instance.
211 65a6f9b7 Michael Hanselmann

212 65a6f9b7 Michael Hanselmann
    """
213 65a6f9b7 Michael Hanselmann
    return "echo Console not available for fake hypervisor"
214 65a6f9b7 Michael Hanselmann
215 65a6f9b7 Michael Hanselmann
  def Verify(self):
216 65a6f9b7 Michael Hanselmann
    """Verify the hypervisor.
217 65a6f9b7 Michael Hanselmann

218 65a6f9b7 Michael Hanselmann
    For the fake hypervisor, it just checks the existence of the base
219 65a6f9b7 Michael Hanselmann
    dir.
220 65a6f9b7 Michael Hanselmann

221 65a6f9b7 Michael Hanselmann
    """
222 65a6f9b7 Michael Hanselmann
    if not os.path.exists(self._ROOT_DIR):
223 65a6f9b7 Michael Hanselmann
      return "The required directory '%s' does not exist." % self._ROOT_DIR