Merge branch 'develop' into feature/search_autocomplete_haste
[ganeti_webmgr.git] / ganeti / utilities.py
blob740d7be4941de570476a74b6c5258016e625a7aa
1 # Copyright (C) 2010 Oregon State University et al.
2 # Copyright (C) 2010 Greek Research and Technology Network
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 # USA.
19 from collections import defaultdict
20 from ganeti import constants
22 def cluster_default_info(cluster, hypervisor=None):
23 """
24 Returns a dictionary containing the following
25 default values set on a cluster:
26 iallocator, hypervisors, vcpus, ram, nictype,
27 nicmode, kernelpath, rootpath, serialconsole,
28 bootorder, imagepath
29 """
30 # Create variables so that dictionary lookups are not so horrendous.
31 info = cluster.info
32 beparams = info['beparams']['default']
33 hvs = info['enabled_hypervisors']
35 if hypervisor is not None:
36 if hypervisor not in hvs:
37 return -1
38 else:
39 hv = hypervisor
40 else:
41 hv = info['default_hypervisor']
43 hvparams = info['hvparams'][hv]
44 if hv == 'kvm':
45 c = constants.KVM_CHOICES
46 elif hv == 'xen-hvm' or hv == 'xen-pvm':
47 c = constants.HVM_CHOICES
48 if hv == 'xen-pvm':
49 # PVM does not have disk types or nic types, so these options get
50 # taken from HVM. This does not affect forms as pvm ignores
51 # the disk_type and nic_type fields.
52 hvparams['disk_type'] = info['hvparams']['xen-hvm']['disk_type']
53 hvparams['nic_type'] = info['hvparams']['xen-hvm']['nic_type']
54 else:
55 c = constants.NO_CHOICES
57 disktypes = c['disk_type']
58 nictypes = c['nic_type']
59 bootdevices = c['boot_order']
61 try:
62 iallocator_info = info['default_iallocator']
63 except:
64 iallocator_info = None
66 if 'nicparams' in info:
67 nic_mode = info['nicparams']['default']['mode']
68 nic_link = info['nicparams']['default']['link']
69 else:
70 nic_mode = None
71 nic_link = None
73 extraparams = {
74 'boot_devices': bootdevices,
75 'disk_types': disktypes,
76 'hypervisor': hv,
77 'hypervisors': zip(hvs, hvs),
78 'iallocator': iallocator_info,
79 'nic_types': nictypes,
80 'nic_mode': nic_mode,
81 'nic_link': nic_link,
82 'memory': beparams['memory'],
83 'vcpus': beparams['vcpus'],
85 return dict(hvparams, **extraparams)
88 def cluster_os_list(cluster):
89 """
90 Create a detailed manifest of available operating systems on the cluster.
91 """
93 return os_prettify(cluster.rapi.GetOperatingSystems())
96 def os_prettify(oses):
97 """
98 Pretty-print and format a list of operating systems.
100 The actual format is a list of tuples of tuples. The first entry in the
101 outer tuple is a label, and then each successive entry is a tuple of the
102 actual Ganeti OS name, and a prettified display name. For example:
105 ("Image",
106 ("image+obonto-hungry-hydralisk", "Obonto Hungry Hydralisk"),
107 ("image+fodoro-core", "Fodoro Core"),
109 ("Dobootstrop",
110 ("dobootstrop+dobion-lotso", "Dobion Lotso"),
115 # In order to convince Django to make optgroups, we need to nest our
116 # iterables two-deep. (("header", ("value, "label"), ("value", "label")))
117 # http://docs.djangoproject.com/en/dev/ref/models/fields/#choices
118 # We do this by making a dict of lists.
119 d = defaultdict(list)
121 for name in oses:
122 try:
123 # Split into type and flavor.
124 t, flavor = name.split("+", 1)
125 # Prettify flavors. "this-boring-string" becomes "This Boring String"
126 flavor = " ".join(word.capitalize() for word in flavor.split("-"))
127 d[t.capitalize()].append((name, flavor))
128 except ValueError:
129 d["Unknown"].append((name, name))
131 l = d.items()
132 l.sort()
134 return l
137 def compare(x, y):
139 Using the python cmp function, returns a string detailing the change in
140 difference
142 i = cmp(x,y)
143 if isinstance(x, basestring) and i != 0:
144 if x == "":
145 return "set to %s" % (y)
146 elif y == "":
147 return "removed"
148 return "changed from %s to %s" % (x, y)
149 elif isinstance(x, bool) and i != 0:
150 if y:
151 return "enabled"
152 else:
153 return "disabled"
154 if i == -1:
155 return "increased from %s to %s" % (x, y)
156 elif i == 1:
157 return "decreased from %s to %s" % (x, y)
158 else:
159 return ""
161 def contains(e, t):
163 Determine whether or not the element e is contained within the list of tuples t
165 return any(e == v[0] for v in t)
167 def get_hypervisor(vm):
169 Given a VirtualMachine object, return its hypervisor depending on what hvparam fields
170 it contains.
172 if vm.info:
173 info = vm.info['hvparams']
174 if 'serial_console' in info:
175 return 'kvm'
176 elif 'initrd_path' in info:
177 return 'xen-pvm'
178 elif 'acpi' in info:
179 return 'xen-hvm'
180 return None