Merge tag '0.10.2'
[ganeti_webmgr.git] / ganeti_web / utilities.py
blob4085741e820768cbb0b1544e7622ba0968483357
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.
18 from collections import defaultdict
19 from ganeti_web import constants
20 from ganeti_web.caps import has_balloonmem
22 from ganeti_web.util.client import GanetiApiError
25 def cluster_default_info(cluster, hypervisor=None):
26 """
27 Returns a dictionary containing the following
28 default values set on a cluster:
29 iallocator, hypervisors, vcpus, ram, nictype,
30 nicmode, kernelpath, rootpath, serialconsole,
31 bootorder, imagepath
32 """
33 # Create variables so that dictionary lookups are not so horrendous.
34 info = cluster.info
35 beparams = info['beparams']['default']
36 hvs = info['enabled_hypervisors']
38 if hypervisor is not None:
39 if hypervisor not in hvs:
40 raise RuntimeError("Was asked to deal with a cluster/HV mismatch")
41 else:
42 hv = hypervisor
43 else:
44 hv = info['default_hypervisor']
46 hvparams = info['hvparams'][hv]
47 if hv == 'kvm':
48 c = constants.KVM_CHOICES
49 elif hv == 'xen-hvm' or hv == 'xen-pvm':
50 c = constants.HVM_CHOICES
51 if hv == 'xen-pvm':
52 # PVM does not have disk types or nic types, so these options get
53 # taken from HVM. This does not affect forms as pvm ignores
54 # the disk_type and nic_type fields.
55 hvparams['disk_type'] = info['hvparams']['xen-hvm']['disk_type']
56 hvparams['nic_type'] = info['hvparams']['xen-hvm']['nic_type']
57 else:
58 c = constants.NO_CHOICES
60 disktypes = c['disk_type']
61 nictypes = c['nic_type']
62 bootdevices = c['boot_order']
64 try:
65 iallocator_info = info['default_iallocator']
66 except:
67 iallocator_info = None
69 if 'nicparams' in info:
70 nic_mode = info['nicparams']['default']['mode']
71 nic_link = info['nicparams']['default']['link']
72 else:
73 nic_mode = None
74 nic_link = None
76 extraparams = {
77 'boot_devices': bootdevices,
78 'disk_types': disktypes,
79 'hypervisor': hv,
80 'hypervisors': zip(hvs, hvs),
81 'iallocator': iallocator_info,
82 'nic_types': nictypes,
83 'nic_mode': nic_mode,
84 'nic_link': nic_link,
85 'vcpus': beparams['vcpus'],
88 if has_balloonmem(cluster):
89 extraparams['memory'] = beparams['maxmem']
90 else:
91 extraparams['memory'] = beparams['memory']
93 return dict(hvparams, **extraparams)
96 def hv_prettify(hv):
97 """
98 Prettify a hypervisor name, if we know about it.
99 """
101 prettified = {
102 "kvm": "KVM",
103 "lxc": "Linux Containers (LXC)",
104 "xen-hvm": "Xen (HVM)",
105 "xen-pvm": "Xen (PVM)",
108 return prettified.get(hv, hv)
111 def cluster_os_list(cluster):
113 Create a detailed manifest of available operating systems on the cluster.
115 try:
116 return os_prettify(cluster.rapi.GetOperatingSystems())
117 except GanetiApiError:
118 return []
121 def os_prettify(oses):
123 Pretty-print and format a list of operating systems.
125 The actual format is a list of tuples of tuples. The first entry in the
126 outer tuple is a label, and then each successive entry is a tuple of the
127 actual Ganeti OS name, and a prettified display name. For example:
130 ("Image",
131 ("image+obonto-hungry-hydralisk", "Obonto Hungry Hydralisk"),
132 ("image+fodoro-core", "Fodoro Core"),
134 ("Dobootstrop",
135 ("dobootstrop+dobion-lotso", "Dobion Lotso"),
140 # In order to convince Django to make optgroups, we need to nest our
141 # iterables two-deep. (("header", ("value, "label"), ("value", "label")))
142 # http://docs.djangoproject.com/en/dev/ref/models/fields/#choices
143 # We do this by making a dict of lists.
144 d = defaultdict(list)
146 for name in oses:
147 try:
148 # Split into type and flavor.
149 t, flavor = name.split("+", 1)
150 # Prettify flavors. "this-boring-string" becomes
151 #"This Boring String"
152 flavor = " ".join(word.capitalize() for word in flavor.split("-"))
153 d[t.capitalize()].append((name, flavor))
154 except ValueError:
155 d["Unknown"].append((name, name))
157 l = d.items()
158 l.sort()
160 return l
163 def compare(x, y):
165 Using the python cmp function, returns a string detailing the change in
166 difference
168 i = cmp(x, y)
169 if y is None and i != 0:
170 return "removed"
171 if isinstance(x, basestring) and i != 0:
172 if x == "":
173 return "set to %s" % (y)
174 elif y == "":
175 return "removed"
176 return "changed from %s to %s" % (x, y)
177 elif isinstance(x, bool) and i != 0:
178 if y:
179 return "enabled"
180 else:
181 return "disabled"
182 if i == -1:
183 return "increased from %s to %s" % (x, y)
184 elif i == 1:
185 return "decreased from %s to %s" % (x, y)
186 else:
187 return ""
190 def contains(e, t):
192 Determine whether or not the element e is contained within
193 the list of tuples t
195 return any(e == v[0] for v in t)
198 def get_hypervisor(vm):
200 Given a VirtualMachine object,
201 return its hypervisor depending on what hvparam fields
202 it contains.
204 if vm.info:
205 info = vm.info['hvparams']
206 if 'serial_console' in info:
207 return 'kvm'
208 elif 'initrd_path' in info:
209 return 'xen-pvm'
210 elif 'acpi' in info:
211 return 'xen-hvm'
212 return None