Add iallocator to create vm
[ganeti_webmgr.git] / ganeti_web / backend / templates.py
blob59481b0da079d36e0864ce2170f27c9bc24a7141
1 # Copyright (C) 2012 Oregon State University et al.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
16 # USA.
18 """
19 Relatively pure functions for instantiating virtual machines from templates
20 and vice versa.
22 These only depend on Django's ORM and not on any of the view or form
23 machinery.
24 """
26 from object_log.models import LogItem
28 from ganeti_web.caps import has_balloonmem
29 from ganeti_web.models import Job, VirtualMachine, VirtualMachineTemplate
31 log_action = LogItem.objects.log_action
34 def instance_to_template(vm, name):
35 """
36 Create, save, and return a VM template representing all of the information
37 in the VM instance.
39 The name is given to the template to distinguish it from other templates.
40 """
42 template = VirtualMachineTemplate()
44 # Basic stuff first.
45 template.template_name = name
46 template.description = ""
47 template.cluster = vm.cluster
48 template.start = vm.info["admin_state"]
49 template.disk_template = vm.info["disk_template"]
50 template.os = vm.operating_system
52 # Backend parameters.
53 template.vcpus = vm.virtual_cpus
54 template.memory = vm.ram
55 if has_balloonmem(vm.cluster):
56 template.minmem = vm.minram
57 template.disks = [{"size": size} for size in vm.info["disk.sizes"]]
58 template.disk_type = vm.info["hvparams"]["disk_type"]
59 template.nics = [{"mode": mode, "link": link}
60 for mode, link in zip(vm.info["nic.modes"],
61 vm.info["nic.links"])]
62 template.nic_type = vm.info["hvparams"]["nic_type"]
64 # Hypervisor parameters.
65 template.kernel_path = vm.info["hvparams"]["kernel_path"]
66 template.root_path = vm.info["hvparams"]["root_path"]
67 template.serial_console = vm.info["hvparams"]["serial_console"]
68 template.boot_order = vm.info["hvparams"]["boot_order"]
69 template.cdrom_image_path = vm.info["hvparams"]["cdrom_image_path"]
70 template.cdrom2_image_path = vm.info["hvparams"]["cdrom2_image_path"]
72 template.save()
74 return template
77 def template_to_instance(template, hostname, owner):
78 """
79 Instantiate a VM template with a given hostname and owner.
80 """
82 cluster = template.cluster
83 beparams = {
84 "vcpus": template.vcpus,
87 hvparams = {}
88 hv = template.hypervisor
89 kvm = hv == 'kvm'
90 pvm = hv == 'xen-pvm'
91 hvm = hv == 'xen-hvm'
92 kvm_or_hvm = kvm or hvm
93 kvm_or_pvm = kvm or pvm
95 if kvm_or_hvm:
96 hvparams.update(boot_order=template.boot_order)
97 hvparams.update(cdrom_image_path=template.cdrom_image_path)
98 hvparams.update(nic_type=template.nic_type)
99 hvparams.update(disk_type=template.disk_type)
100 if kvm_or_pvm:
101 hvparams.update(kernel_path=template.kernel_path)
102 hvparams.update(root_path=template.root_path)
103 if kvm:
104 hvparams.update(cdrom2_image_path=template.cdrom2_image_path)
105 hvparams.update(serial_console=template.serial_console)
107 memory = template.memory
108 if has_balloonmem(cluster):
109 minram = template.minmem
110 beparams['minmem'] = minram
111 beparams['maxmem'] = memory
112 else:
113 beparams['memory'] = memory
115 vcpus = template.vcpus
116 disk_size = template.disks[0]["size"]
118 kwargs = {
119 "os": template.os,
120 "hypervisor": hv,
121 "ip_check": template.ip_check,
122 "name_check": template.name_check,
123 "beparams": beparams,
124 "no_install": template.no_install,
125 "start": not template.no_start,
126 "hvparams": hvparams,
129 # Using auto allocator
130 if template.iallocator:
131 default_iallocator = cluster.info['default_iallocator']
132 kwargs.update(iallocator=default_iallocator)
133 # Not using allocator, pass pnode
134 else:
135 kwargs.update(pnode=template.pnode)
136 # Also pass in snode if it exists (drdb)
137 if template.snode:
138 kwargs.update(snode=template.snode)
139 # secondary node isn't set but we're using drdb, so programming error
140 # (this shouldn't happen if form validation is done correctly)
141 elif template.disk_template == 'drdb':
142 msg = 'Disk template set to drdb, but no secondary node set'
143 raise RuntimeError(msg)
145 job_id = cluster.rapi.CreateInstance('create', hostname,
146 template.disk_template,
147 template.disks, template.nics,
148 **kwargs)
149 vm = VirtualMachine()
151 vm.cluster = cluster
152 vm.hostname = hostname
153 vm.ram = memory
154 if has_balloonmem(cluster):
155 vm.minram = minram
156 vm.virtual_cpus = vcpus
157 vm.disk_size = disk_size
159 vm.owner = owner
160 vm.ignore_cache = True
162 # Do a dance to get the VM and the job referencing each other.
163 vm.save()
164 job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster)
165 job.save()
166 vm.last_job = job
167 vm.save()
169 # Grant admin permissions to the owner.
170 owner.permissable.grant('admin', vm)
172 return vm