Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_fake.py @ 07b49e41

History | View | Annotate | Download (5.8 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007, 2008 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Fake hypervisor
23

24
"""
25

    
26
import os
27
import os.path
28

    
29
from ganeti import utils
30
from ganeti import constants
31
from ganeti import errors
32
from ganeti.hypervisor import hv_base
33

    
34

    
35
class FakeHypervisor(hv_base.BaseHypervisor):
36
  """Fake hypervisor interface.
37

38
  This can be used for testing the ganeti code without having to have
39
  a real virtualisation software installed.
40

41
  """
42
  _ROOT_DIR = constants.RUN_DIR + "/ganeti-fake-hypervisor"
43

    
44
  def __init__(self):
45
    hv_base.BaseHypervisor.__init__(self)
46
    if not os.path.exists(self._ROOT_DIR):
47
      os.mkdir(self._ROOT_DIR)
48

    
49
  def ListInstances(self):
50
    """Get the list of running instances.
51

52
    """
53
    return os.listdir(self._ROOT_DIR)
54

    
55
  def GetInstanceInfo(self, instance_name):
56
    """Get instance properties.
57

58
    @param instance_name: the instance name
59

60
    @return: tuple of (name, id, memory, vcpus, stat, times)
61

62
    """
63
    file_name = "%s/%s" % (self._ROOT_DIR, instance_name)
64
    if not os.path.exists(file_name):
65
      return None
66
    try:
67
      fh = open(file_name, "r")
68
      try:
69
        inst_id = fh.readline().strip()
70
        memory = utils.TryConvert(int, fh.readline().strip())
71
        vcpus = utils.TryConvert(fh.readline().strip())
72
        stat = "---b-"
73
        times = "0"
74
        return (instance_name, inst_id, memory, vcpus, stat, times)
75
      finally:
76
        fh.close()
77
    except IOError, err:
78
      raise errors.HypervisorError("Failed to list instance %s: %s" %
79
                                   (instance_name, err))
80

    
81
  def GetAllInstancesInfo(self):
82
    """Get properties of all instances.
83

84
    @return: list of tuples (name, id, memory, vcpus, stat, times)
85

86
    """
87
    data = []
88
    for file_name in os.listdir(self._ROOT_DIR):
89
      try:
90
        fh = open(self._ROOT_DIR + "/" + file_name, "r")
91
        inst_id = "-1"
92
        memory = 0
93
        vcpus = 1
94
        stat = "-----"
95
        times = "-1"
96
        try:
97
          inst_id = fh.readline().strip()
98
          memory = utils.TryConvert(int, fh.readline().strip())
99
          vcpus = utils.TryConvert(int, fh.readline().strip())
100
          stat = "---b-"
101
          times = "0"
102
        finally:
103
          fh.close()
104
        data.append((file_name, inst_id, memory, vcpus, stat, times))
105
      except IOError, err:
106
        raise errors.HypervisorError("Failed to list instances: %s" % err)
107
    return data
108

    
109
  def StartInstance(self, instance, block_devices):
110
    """Start an instance.
111

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

116
    """
117
    file_name = self._ROOT_DIR + "/%s" % instance.name
118
    if os.path.exists(file_name):
119
      raise errors.HypervisorError("Failed to start instance %s: %s" %
120
                                   (instance.name, "already running"))
121
    try:
122
      fh = file(file_name, "w")
123
      try:
124
        fh.write("0\n%d\n%d\n" %
125
                 (instance.beparams[constants.BE_MEMORY],
126
                  instance.beparams[constants.BE_VCPUS]))
127
      finally:
128
        fh.close()
129
    except IOError, err:
130
      raise errors.HypervisorError("Failed to start instance %s: %s" %
131
                                   (instance.name, err))
132

    
133
  def StopInstance(self, instance, force=False, retry=False):
134
    """Stop an instance.
135

136
    For the fake hypervisor, this just removes the file in the base
137
    dir, if it exist, otherwise we raise an exception.
138

139
    """
140
    file_name = self._ROOT_DIR + "/%s" % instance.name
141
    if not os.path.exists(file_name):
142
      raise errors.HypervisorError("Failed to stop instance %s: %s" %
143
                                   (instance.name, "not running"))
144
    utils.RemoveFile(file_name)
145

    
146
  def RebootInstance(self, instance):
147
    """Reboot an instance.
148

149
    For the fake hypervisor, this does nothing.
150

151
    """
152
    return
153

    
154
  def GetNodeInfo(self):
155
    """Return information about the node.
156

157
    This is just a wrapper over the base GetLinuxNodeInfo method.
158

159
    @return: a dict with the following keys (values in MiB):
160
          - memory_total: the total memory size on the node
161
          - memory_free: the available memory on the node for instances
162
          - memory_dom0: the memory used by the node itself, if available
163

164
    """
165
    result = self.GetLinuxNodeInfo()
166
    # substract running instances
167
    all_instances = self.GetAllInstancesInfo()
168
    result['memory_free'] -= min(result['memory_free'],
169
                                 sum([row[2] for row in all_instances]))
170
    return result
171

    
172
  @classmethod
173
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
174
    """Return a command for connecting to the console of an instance.
175

176
    """
177
    return "echo Console not available for fake hypervisor"
178

    
179
  def Verify(self):
180
    """Verify the hypervisor.
181

182
    For the fake hypervisor, it just checks the existence of the base
183
    dir.
184

185
    """
186
    if not os.path.exists(self._ROOT_DIR):
187
      return "The required directory '%s' does not exist." % self._ROOT_DIR
188

    
189
  @classmethod
190
  def PowercycleNode(cls):
191
    """Fake hypervisor powercycle, just a wrapper over Linux powercycle.
192

193
    """
194
    cls.LinuxPowercycle()