Statistics
| Branch: | Tag: | Revision:

root / doc / examples / dumb-allocator @ 298fe380

History | View | Annotate | Download (2.6 kB)

1 298fe380 Iustin Pop
#!/usr/bin/python
2 298fe380 Iustin Pop
#
3 298fe380 Iustin Pop
4 298fe380 Iustin Pop
# Copyright (C) 2008 Google Inc.
5 298fe380 Iustin Pop
#
6 298fe380 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 298fe380 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 298fe380 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 298fe380 Iustin Pop
# (at your option) any later version.
10 298fe380 Iustin Pop
#
11 298fe380 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 298fe380 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 298fe380 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 298fe380 Iustin Pop
# General Public License for more details.
15 298fe380 Iustin Pop
#
16 298fe380 Iustin Pop
# You should have received a copy of the GNU General Public License
17 298fe380 Iustin Pop
# along with this program; if not, write to the Free Software
18 298fe380 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 298fe380 Iustin Pop
# 02110-1301, USA.
20 298fe380 Iustin Pop
21 298fe380 Iustin Pop
"""Simple first-fit allocator for ganeti instance allocation framework.
22 298fe380 Iustin Pop
23 298fe380 Iustin Pop
This allocator just iterates over the nodes and selects the first one
24 298fe380 Iustin Pop
that fits in both memory and disk space, without any consideration for
25 298fe380 Iustin Pop
equal spread or VCPU oversubscription.
26 298fe380 Iustin Pop
27 298fe380 Iustin Pop
"""
28 298fe380 Iustin Pop
import simplejson
29 298fe380 Iustin Pop
import sys
30 298fe380 Iustin Pop
31 298fe380 Iustin Pop
32 298fe380 Iustin Pop
def SelectNode(nodes, request, to_skip):
33 298fe380 Iustin Pop
  """Select a node for the given instance
34 298fe380 Iustin Pop
35 298fe380 Iustin Pop
  """
36 298fe380 Iustin Pop
  disk_size = request["disk_space_total"]
37 298fe380 Iustin Pop
  selected = None
38 298fe380 Iustin Pop
  for nname, ninfo in nodes.iteritems():
39 298fe380 Iustin Pop
    if nname in to_skip:
40 298fe380 Iustin Pop
      continue
41 298fe380 Iustin Pop
    if request["memory"] > ninfo["free_memory"]:
42 298fe380 Iustin Pop
      continue
43 298fe380 Iustin Pop
    if disk_size > ninfo["free_disk"]:
44 298fe380 Iustin Pop
      continue
45 298fe380 Iustin Pop
    selected = nname
46 298fe380 Iustin Pop
    break
47 298fe380 Iustin Pop
  return selected
48 298fe380 Iustin Pop
49 298fe380 Iustin Pop
50 298fe380 Iustin Pop
def OutputError(text):
51 298fe380 Iustin Pop
  """Builds an error response with a given info message.
52 298fe380 Iustin Pop
53 298fe380 Iustin Pop
  """
54 298fe380 Iustin Pop
  error = {
55 298fe380 Iustin Pop
    "success": False,
56 298fe380 Iustin Pop
    "info": text,
57 298fe380 Iustin Pop
    }
58 298fe380 Iustin Pop
  print simplejson.dumps(error, indent=2)
59 298fe380 Iustin Pop
  return 1
60 298fe380 Iustin Pop
61 298fe380 Iustin Pop
62 298fe380 Iustin Pop
def main():
63 298fe380 Iustin Pop
  """Main function.
64 298fe380 Iustin Pop
65 298fe380 Iustin Pop
  """
66 298fe380 Iustin Pop
  if len(sys.argv) < 2:
67 298fe380 Iustin Pop
    print >> sys.stderr, "Usage: %s cluster.json" % (sys.argv[0])
68 298fe380 Iustin Pop
    return 1
69 298fe380 Iustin Pop
70 298fe380 Iustin Pop
  data = simplejson.load(open(sys.argv[1]))
71 298fe380 Iustin Pop
72 298fe380 Iustin Pop
  nodes =  data["nodes"]
73 298fe380 Iustin Pop
  request = data["request"]
74 298fe380 Iustin Pop
  req_type = request["type"]
75 298fe380 Iustin Pop
  if req_type != "allocate":
76 298fe380 Iustin Pop
    print >> sys.stderr, "Unsupported allocator mode '%s'" % req_type
77 298fe380 Iustin Pop
    return 1
78 298fe380 Iustin Pop
79 298fe380 Iustin Pop
  npri = SelectNode(nodes, request, [])
80 298fe380 Iustin Pop
  if npri is None:
81 298fe380 Iustin Pop
    return OutputError("Can't find a suitable primary node")
82 298fe380 Iustin Pop
83 298fe380 Iustin Pop
  result_nodes = [npri]
84 298fe380 Iustin Pop
  if request["disk_template"] == "drbd":
85 298fe380 Iustin Pop
    nsec = SelectNode(nodes, request, result_nodes)
86 298fe380 Iustin Pop
    if nsec is None:
87 298fe380 Iustin Pop
      return OutputError("Can't find a suitable secondary node (%s selected"
88 298fe380 Iustin Pop
                         " as primary)" % npri)
89 298fe380 Iustin Pop
    result_nodes.append(nsec)
90 298fe380 Iustin Pop
91 298fe380 Iustin Pop
  result = {
92 298fe380 Iustin Pop
          "success": True,
93 298fe380 Iustin Pop
          "info": "Allocation successful",
94 298fe380 Iustin Pop
          "nodes": result_nodes,
95 298fe380 Iustin Pop
          }
96 298fe380 Iustin Pop
  print simplejson.dumps(result, indent=2)
97 298fe380 Iustin Pop
  return 0
98 298fe380 Iustin Pop
99 298fe380 Iustin Pop
if __name__ == "__main__":
100 298fe380 Iustin Pop
    sys.exit(main())