Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ a705dc05

History | View | Annotate | Download (2.9 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007 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
"""QA configuration.
23

24
"""
25

    
26

    
27
from ganeti import utils
28
from ganeti import serializer
29

    
30
import qa_error
31

    
32

    
33
cfg = None
34
options = None
35

    
36

    
37
def Load(path):
38
  """Loads the passed configuration file.
39

40
  """
41
  global cfg
42

    
43
  cfg = serializer.LoadJson(utils.ReadFile(path))
44

    
45
  Validate()
46

    
47

    
48
def Validate():
49
  if len(cfg['nodes']) < 1:
50
    raise qa_error.Error("Need at least one node")
51
  if len(cfg['instances']) < 1:
52
    raise qa_error.Error("Need at least one instance")
53
  if len(cfg["disk"]) != len(cfg["disk-growth"]):
54
    raise qa_error.Error("Config options 'disk' and 'disk-growth' must have"
55
                         " the same number of items")
56

    
57

    
58
def get(name, default=None):
59
  return cfg.get(name, default)
60

    
61

    
62
def TestEnabled(test):
63
  """Returns True if the given test is enabled."""
64
  return cfg.get('tests', {}).get(test, False)
65

    
66

    
67
def GetMasterNode():
68
  return cfg['nodes'][0]
69

    
70

    
71
def AcquireInstance():
72
  """Returns an instance which isn't in use.
73

74
  """
75
  # Filter out unwanted instances
76
  tmp_flt = lambda inst: not inst.get('_used', False)
77
  instances = filter(tmp_flt, cfg['instances'])
78
  del tmp_flt
79

    
80
  if len(instances) == 0:
81
    raise qa_error.OutOfInstancesError("No instances left")
82

    
83
  inst = instances[0]
84
  inst['_used'] = True
85
  return inst
86

    
87

    
88
def ReleaseInstance(inst):
89
  inst['_used'] = False
90

    
91

    
92
def AcquireNode(exclude=None):
93
  """Returns the least used node.
94

95
  """
96
  master = GetMasterNode()
97

    
98
  # Filter out unwanted nodes
99
  # TODO: Maybe combine filters
100
  if exclude is None:
101
    nodes = cfg['nodes'][:]
102
  elif isinstance(exclude, (list, tuple)):
103
    nodes = filter(lambda node: node not in exclude, cfg['nodes'])
104
  else:
105
    nodes = filter(lambda node: node != exclude, cfg['nodes'])
106

    
107
  tmp_flt = lambda node: node.get('_added', False) or node == master
108
  nodes = filter(tmp_flt, nodes)
109
  del tmp_flt
110

    
111
  if len(nodes) == 0:
112
    raise qa_error.OutOfNodesError("No nodes left")
113

    
114
  # Get node with least number of uses
115
  def compare(a, b):
116
    result = cmp(a.get('_count', 0), b.get('_count', 0))
117
    if result == 0:
118
      result = cmp(a['primary'], b['primary'])
119
    return result
120

    
121
  nodes.sort(cmp=compare)
122

    
123
  node = nodes[0]
124
  node['_count'] = node.get('_count', 0) + 1
125
  return node
126

    
127

    
128
def ReleaseNode(node):
129
  node['_count'] = node.get('_count', 0) - 1