/
OVA.py
138 lines (115 loc) · 6.35 KB
/
OVA.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# encoding: utf-8
# Copyright 2013 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import uuid
import inspect
from zope.interface import implementer
from imgfac.CloudDelegate import CloudDelegate
from imgfac.PersistentImageManager import PersistentImageManager
from imgfac.TargetImage import TargetImage
from imagefactory_plugins.ovfcommon.ovfcommon import RHEVOVFPackage, VsphereOVFPackage
from imagefactory_plugins.ovfcommon.ovfcommon import VirtualBoxOVFPackage
from imagefactory_plugins.ovfcommon.ovfcommon import LibvirtVagrantOVFPackage
from imagefactory_plugins.ovfcommon.ovfcommon import VMWareFusionVagrantOVFPackage
from imagefactory_plugins.ovfcommon.ovfcommon import HyperVOVFPackage
from imgfac.ImageFactoryException import ImageFactoryException
from oz.ozutil import copyfile_sparse
from oz.TDL import TDL
@implementer(CloudDelegate)
class OVA(object):
def __init__(self):
self.log = logging.getLogger('%s.%s' % (__name__, self.__class__.__name__))
def builder_should_create_target_image(self, builder, target, image_id, template, parameters):
retval = False
if isinstance(builder.base_image, TargetImage):
if builder.base_image.target in ('vsphere', 'rhevm', 'hyperv'):
retval = True
self.log.info('builder_should_create_target_image() called on OVA plugin - returning %s' % retval)
return retval
def builder_did_create_target_image(self, builder, target, image_id, template, parameters):
self.log.info('builder_did_create_target_image() called in OVA plugin')
self.status="BUILDING"
# NOTE: This is unique to the OVA plugin at the moment
# The ID passed in as the "base" image is actually a target image for the cloud
# type that will be the ultimate target of the OVA. This allows us to reuse the
# existing target plugin code for disk format transformation and focus on the OVF
# specific work in this plugin
# The target image containing the disk in the correct format
# Again, the builder things this is a base image but it is actually a target image
self.target_image = builder.base_image
# The base image that this origin target image was created from
self.base_image = PersistentImageManager.default_manager().image_with_id(self.target_image.base_image_id)
# A convenience variable pointing at the target image we are creating
# Take note - self.target_image is the image we are sourcing from
# self.image is us, another target image
self.image = builder.target_image
self.parameters = parameters
# This lets our logging helper know what image is being operated on
self.active_image = self.image
self.generate_ova()
self.percent_complete=100
self.status="COMPLETED"
def generate_ova(self):
if self.target_image.target == 'rhevm':
ova_format = self.parameters.get('rhevm_ova_format', 'rhevm')
if ova_format == 'rhevm':
klass = RHEVOVFPackage
elif ova_format == 'vagrant-libvirt':
klass = LibvirtVagrantOVFPackage
else:
raise ImageFactoryException("Unknown rhevm ova_format (%s) requested - must be 'rhevm' or 'libvirt-vagrant'" % (ova_format) )
elif self.target_image.target == 'vsphere':
ova_format = self.parameters.get('vsphere_ova_format', 'vsphere')
if ova_format == 'vsphere':
klass = VsphereOVFPackage
elif ova_format == 'vagrant-virtualbox':
klass = VirtualBoxOVFPackage
elif ova_format == 'vagrant-vmware-fusion':
klass = VMWareFusionVagrantOVFPackage
else:
raise ImageFactoryException("Unknown vsphere ova_format (%s) requested - must be 'vsphere', 'vagrant-virtualbox' or 'vagrant-vmware-fusion'" % (ova_format) )
elif self.target_image.target == 'hyperv':
ova_format = self.parameters.get('hyperv_ova_format', 'hyperv-vagrant')
if ova_format == 'hyperv-vagrant':
klass = HyperVOVFPackage
elif ova_format == 'hyperv':
klass = HyperVOVFPackage
self.parameters['hyperv_vagrant'] = False
else:
raise ImageFactoryException("Unknown hyperv ova_format (%s) requested - must be 'hyperv-vagrant' or 'hyperv'" % (ova_format) )
else:
raise ImageFactoryException("OVA plugin only supports rhevm and vsphere target images")
tdl = TDL(xmlstring=self.image.template, rootpw_required=False)
if not 'ovf_name' in self.parameters:
self.parameters['ovf_name'] = tdl.name
klass_parameters = dict()
if self.parameters:
params = ['ovf_cpu_count','ovf_memory_mb','ovf_name',
'rhevm_default_display_type','rhevm_description','rhevm_os_descriptor',
'vsphere_product_name','vsphere_product_vendor_name','vsphere_product_version',
'vsphere_virtual_system_type', 'vsphere_scsi_controller_type',
'vsphere_network_controller_type', 'vsphere_nested_virt', 'vsphere_cdrom', 'vsphere_os_type',
'fusion_scsi_controller_type', 'fusion_network_controller_type', 'fusion_nested_virt',
'hyperv_vagrant',
'vagrant_sync_directory']
for param in params:
if (self.parameters.get(param) and
klass.__init__.__code__.co_varnames.__contains__(param)):
klass_parameters[param] = self.parameters.get(param)
pkg = klass(disk=self.image.data, base_image=self.base_image,
**klass_parameters)
ova = pkg.make_ova_package()
copyfile_sparse(ova, self.image.data)
pkg.delete()