3
# Copyright 2007 Red Hat, Inc.
4
# David Lutterkort <dlutter@redhat.com>
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25
import CapabilitiesParser as Cap
26
from VirtualDisk import VirtualDisk
27
from virtinst import _virtinst as _
29
class ImageInstallerException(Exception):
30
def __init__(self, msg):
31
Exception.__init__(self, msg)
33
class ImageInstaller(Installer.Installer):
34
"""Installer for image-based guests"""
35
def __init__(self, image, capabilities=None, boot_index=None, conn=None):
36
Installer.Installer.__init__(self, conn=conn)
43
self._capabilities = Cap.parse(self.conn.getCapabilities())
45
if not isinstance(capabilities, Cap.Capabilities):
46
raise ValueError(_("'capabilities' must be a "
47
"Capabilities instance."))
48
self._capabilities = capabilities
50
raise ValueError(_("'conn' or 'capabilities' must be specified."))
52
# Set boot _boot_caps/_boot_parameters
53
if boot_index is None:
54
self._boot_caps = match_boots(self._capabilities,
55
self.image.domain.boots)
56
if self._boot_caps is None:
57
raise ImageInstallerException(_("Could not find suitable boot "
58
"descriptor for this host"))
61
(boot_index + 1) > len(image.domain.boots)):
62
raise ValueError(_("boot_index out of range."))
63
self._boot_caps = image.domain.boots[boot_index]
65
# Set up internal caps.guest object
66
self._guest = self._capabilities.guestForOSType(self.boot_caps.type,
68
if self._guest is None:
69
raise PlatformMatchException(_("Unsupported virtualization type: "
70
"%s %s" % (self.boot_caps.type,
71
self.boot_caps.arch)))
73
self.os_type = self.boot_caps.type
74
self._domain = self._guest.bestDomainType()
75
self.type = self._domain.hypervisor_type
76
self.arch = self._guest.arch
79
# Custom ImageInstaller methods
82
if self._boot_caps.type == "hvm":
88
image = property(get_image)
90
def get_boot_caps(self):
91
return self._boot_caps
92
boot_caps = property(get_boot_caps)
95
# General Installer methods
97
def prepare(self, guest, meter, distro = None):
98
self._make_disks(guest)
100
for f in ['pae', 'acpi', 'apic']:
101
if self.boot_caps.features[f] & Cap.FEATURE_ON:
102
guest.features[f] = True
103
elif self.boot_caps.features[f] & Cap.FEATURE_OFF:
104
guest.features[f] = False
106
def get_install_xml(self, guest, isinstall):
108
kernel = { "kernel" : self.boot_caps.kernel,
109
"initrd" : self.boot_caps.initrd,
110
"extrargs" : self.boot_caps.cmdline }
112
if self.boot_caps.kernel:
117
# FYI: self.boot_caps.loader is _not_ analagous to guest loader tag
119
return self._get_osblob_helper(guest, isinstall=isinstall,
121
bootdev=self.boot_caps.bootdev)
123
def post_install_check(self, guest):
129
def _make_disks(self, guest):
130
for m in self.boot_caps.drives:
131
p = self._abspath(m.disk.file)
133
if m.disk.size is not None:
134
s = float(m.disk.size)/1024
136
# FIXME: This is awkward; the image should be able to express
137
# whether the disk is expected to be there or not independently
138
# of its classification, especially for user disks
139
# FIXME: We ignore the target for the mapping in m.target
140
if (m.disk.use == ImageParser.Disk.USE_SYSTEM and
141
not os.path.exists(p)):
142
raise ImageInstallerException(_("System disk %s does not exist")
144
device = VirtualDisk.DEVICE_DISK
145
if m.disk.format == ImageParser.Disk.FORMAT_ISO:
146
device = VirtualDisk.DEVICE_CDROM
147
d = VirtualDisk(p, s,
149
type = VirtualDisk.TYPE_FILE)
152
guest._add_install_dev(d)
154
def _abspath(self, p):
155
return self.image.abspath(p)
157
class PlatformMatchException(Exception):
158
def __init__(self, msg):
159
Exception.__init__(self, msg)
161
def match_boots(capabilities, boots):
163
for g in capabilities.guests:
164
if b.type == g.os_type and b.arch == g.arch:
166
for bf in b.features.names():
167
if not b.features[bf] & g.features[bf]: