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,
19 Relatively pure functions for instantiating virtual machines from templates
22 These only depend on Django's ORM and not on any of the view or form
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
):
36 Create, save, and return a VM template representing all of the information
39 The name is given to the template to distinguish it from other templates.
42 template
= VirtualMachineTemplate()
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
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"]
77 def template_to_instance(template
, hostname
, owner
):
79 Instantiate a VM template with a given hostname and owner.
82 cluster
= template
.cluster
84 "vcpus": template
.vcpus
,
88 hv
= template
.hypervisor
92 kvm_or_hvm
= kvm
or hvm
93 kvm_or_pvm
= kvm
or pvm
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
)
101 hvparams
.update(kernel_path
=template
.kernel_path
)
102 hvparams
.update(root_path
=template
.root_path
)
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
113 beparams
['memory'] = memory
115 vcpus
= template
.vcpus
116 disk_size
= template
.disks
[0]["size"]
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
135 kwargs
.update(pnode
=template
.pnode
)
136 # Also pass in snode if it exists (drdb)
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
,
149 vm
= VirtualMachine()
152 vm
.hostname
= hostname
154 if has_balloonmem(cluster
):
156 vm
.virtual_cpus
= vcpus
157 vm
.disk_size
= disk_size
160 vm
.ignore_cache
= True
162 # Do a dance to get the VM and the job referencing each other.
164 job
= Job
.objects
.create(job_id
=job_id
, obj
=vm
, cluster
=cluster
)
169 # Grant admin permissions to the owner.
170 owner
.permissable
.grant('admin', vm
)