Remove virt-image, as scheduled
As promised with the last release, remove virt-image. In 6 months I didn't hear a peep from any actual users that cared.
This commit is contained in:
parent
2e7d477156
commit
5aafe008bc
|
@ -14,9 +14,7 @@ po/virt-manager.pot
|
|||
/man/virt-manager.1
|
||||
/man/virt-install.1
|
||||
/man/virt-clone.1
|
||||
/man/virt-image.1
|
||||
/man/virt-convert.1
|
||||
/man/virt-image.5
|
||||
/man/virt-xml.1
|
||||
|
||||
/virt-manager.spec
|
||||
|
|
|
@ -1,240 +0,0 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
virt-image - Format of the virtual image XML descriptor
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<virt-image(1)> relies on an XML descriptor to create virtual machines from
|
||||
virtual machine images. In general, a virtual machine image consists of the
|
||||
XML descriptor (usually in a file F<image.xml>) and a number of files for
|
||||
the virtual machine's disks.
|
||||
|
||||
In the following explanation of the structure of the image descriptor,
|
||||
mandatory XML elements are marked as B<element>, whereas optional elements
|
||||
are marked as I<element>.
|
||||
|
||||
All file names in the image descriptor are relative to the location of the
|
||||
descriptor itself. Generally, disk files are either kept in the same
|
||||
directory as the image descriptor, or in a subdirectory.
|
||||
|
||||
=head1 HOST MATCHING
|
||||
|
||||
The image descriptor contains information on the requirements a guest has
|
||||
on the host platform through one or more the F</image/domain/boot>
|
||||
descriptors (see section L</BOOT>). The image can only be used if at least
|
||||
one of the boot descriptors is suitable for the host platform; a boot
|
||||
descriptor is suitable if:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The CPU architecture of the boot descriptor, given by the
|
||||
F<boot/guest/arch> element, is supported by the host
|
||||
|
||||
=item *
|
||||
|
||||
The host supports a guest with the features requested in the
|
||||
F<boot/guest/features> element, such as providing an APIC, or having ACPI
|
||||
turned off
|
||||
|
||||
=back
|
||||
|
||||
If a suitable boot descriptor is found, the guest is created and booted
|
||||
according to the information about booting the OS from the F<boot/os>
|
||||
element and with the disks specified in the F<boot/drive> element. If more
|
||||
than one suitable boot descriptor is found, one of them is chosen based on
|
||||
a heuristic, generally preferring paravirtualized guests over full
|
||||
virtualized ones, though this is an implementation detail of the tool
|
||||
creating the virtual machine.
|
||||
|
||||
=head1 STRUCTURE
|
||||
|
||||
The image descriptor consists of three sections, all contained in the
|
||||
toplevel B<image> element:
|
||||
|
||||
=over 4
|
||||
|
||||
=item General metadata about the image
|
||||
|
||||
A number of elements like I<label>, B<name>, and I<description> that give
|
||||
some simple information about the image. The B<name> must be a string
|
||||
suitable as a name for the virtual machine, the I<label> is a short
|
||||
human-readable string suitable for display in graphical UI's, and the
|
||||
I<description> should be a longer, free-form description of the purpose of
|
||||
the image. The B<name> is mandatory.
|
||||
|
||||
=item Virtual machine attributes
|
||||
|
||||
The B<domain> element contains instructions on how to boot the image, and
|
||||
device attributes such as the number of virtual CPU's and the size of the
|
||||
memory. (see section L</DOMAIN>)
|
||||
|
||||
=item Storage layout
|
||||
|
||||
The B<storage> element lists the files to back the virtual machine's disks
|
||||
and some information about their format and use. (see section L</STORAGE>)
|
||||
|
||||
=back
|
||||
|
||||
=head1 DOMAIN
|
||||
|
||||
The B<domain> element contains one or more B<boot> descriptors (see section
|
||||
L</BOOT>) and a B<devices> element. The B<Devices> element lists the
|
||||
recommended number of virtual CPU's in the B<vcpu> element and the
|
||||
recommended amount of memory in kB in the B<memory> element. It also
|
||||
indicates whether the virtual machine should have a network interface
|
||||
through the I<interface> element and whether the virtual machine has a
|
||||
graphical interface through the I<graphics> element.
|
||||
|
||||
=head2 BOOT
|
||||
|
||||
Each B<boot> descriptor details how the virtual machine should be started
|
||||
on a certain hypervisor. The B<type> attribute of the B<boot> element,
|
||||
which can either be C<xen> or C<hvm>, depending on whether the boot
|
||||
descriptor is for a paravirtualized Xen(tm) guest or a fully-virtualized
|
||||
guest.
|
||||
|
||||
The B<boot> element contains three subelements:
|
||||
|
||||
=over 4
|
||||
|
||||
=item The platform requirements of the guest
|
||||
|
||||
The platform requirements, contained in the B<guest> element, consist of
|
||||
the B<arch> element and the I<features> element. The B<arch> element
|
||||
indicates the CPU architecture the guest expects, e.g. C<i686>, C<x86_64>,
|
||||
or C<ppc>.
|
||||
|
||||
The I<features> element indicates whether certain platform features should
|
||||
be on or off. Currently, the platform features are I<pae>, I<acpi>, and
|
||||
I<apic>. Omitting a togglable feature tag turns it off.
|
||||
|
||||
=item The details of booting the image's operating system
|
||||
|
||||
The B<os> element for fully-virtualized C<hvm> guests contains a B<loader>
|
||||
element whose B<dev> attribute indicates whether to boot off a hard disk
|
||||
(C<dev='hd'>) or off a CD-ROM (C<dev='cdrom'>)
|
||||
|
||||
For paravirtualized guests, the B<os> element either contains a
|
||||
C<< <loader>pygrub</loader> >> element, indicating that the guest should be
|
||||
booted with F<pygrub>, or B<kernel>, I<initrd> and I<cmdline> elements. The
|
||||
contents of the B<kernel> and I<initrd> elements are the names of the
|
||||
kernel and initrd files, whereas the I<cmdline> element contains the
|
||||
command line that should be passed to the kernel on boot.
|
||||
|
||||
=item The mapping of disk files as devices into the guest
|
||||
|
||||
The mapping of disk files into the guest is performed by a list of B<drive>
|
||||
elements inside the B<boot> element. Each B<drive> element references the
|
||||
name of a disk file from the L</STORAGE> section through its B<disk>
|
||||
attribute and can optionally specify as what device that disk file should
|
||||
appear in the guest through its I<target> attribute. If the I<target> is
|
||||
omitted, device names are assigned in the order in which the B<drive>
|
||||
elements appear, skipping already assigned devices.
|
||||
|
||||
=back
|
||||
|
||||
=head1 STORAGE
|
||||
|
||||
The B<storage> element lists the disk image files that are part of the
|
||||
virtual machine image in a list of one or more B<disk> elements. Each
|
||||
B<disk> element can contain the following attributes:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
the B<file> attribute giving the name of the disk file
|
||||
|
||||
=item *
|
||||
|
||||
an optional I<id> attribute. The name given with that attribute is used to
|
||||
reference the disk from the B<drive> element of a B<boot> descriptor. If
|
||||
the I<id> attribute is missing, it defaults to the B<file> attribute.
|
||||
|
||||
=item *
|
||||
|
||||
the B<use> attribute indicating whether the disk file is a C<system>,
|
||||
C<user>, or C<scratch> disk. The B<use> attribute differentiates disk files
|
||||
so that an update based on replacing disk files can replace C<system>
|
||||
disks, but leave C<user> disks untouched.
|
||||
|
||||
Generally, C<system> disks contain application code, C<user> disks contain
|
||||
the application's data, and C<scratch> disks contain temporary state that
|
||||
can be erased between runs of the guest.
|
||||
|
||||
The virtual machine image must contain files for all C<system> disks, and
|
||||
may contain files for the C<user> and C<scratch> disks. If the latter are
|
||||
not part of the image, they are initialized as empty files when a guest is
|
||||
created, with the size given by the I<size> attribute.
|
||||
|
||||
=item *
|
||||
|
||||
the I<size> attribute giving the size of the disk in MB.
|
||||
|
||||
=item *
|
||||
|
||||
the I<format> attribute giving the format of the disk file. Currently, this
|
||||
can be one of: C<raw> C<iso>, C<qcow>, C<qcow2>, or C<vmdk>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
The image descriptor below can be used to create a virtual machine running
|
||||
the System Rescue CD (C<http://www.sysresccd.org/>) Besides the descriptor,
|
||||
you only need the ISO image from the System Rescue CD website.
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<image>
|
||||
<name>sysresccd</name>
|
||||
<domain>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
</guest>
|
||||
<os>
|
||||
<loader dev="cdrom"/>
|
||||
</os>
|
||||
<drive disk="root.raw" target="hda"/>
|
||||
<drive disk="sysresc"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>1</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="root.raw" use="scratch" size="100" format="raw"/>
|
||||
<disk id="sysresc" file="isos/systemrescuecd.iso"
|
||||
use="system" format="iso"/>
|
||||
</storage>
|
||||
</image>
|
||||
|
||||
To create a virtual machine, save the above XML in F<image.xml> and run:
|
||||
|
||||
# virt-image --vnc image.xml
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please see C<http://virt-manager.org/page/BugReporting>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) Red Hat, Inc, and various contributors.
|
||||
This is free software. You may redistribute copies of it under the terms
|
||||
of the GNU General Public License C<http://www.gnu.org/licenses/gpl.html>.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<virt-image(1)>, L<virt-install(1)>, the project website
|
||||
C<http://virt-manager.org>, the Relax-NG grammar for image XML C<image.rng>
|
||||
|
||||
=cut
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
virt-image - create virtual machines from an image descriptor
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<virt-image> [OPTION]... IMAGE.XML
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
WARNING: B<virt-image> is planned for removal in the near future. If you are depending on this tool, please contact the developers at virt-tools-list@redhat.com
|
||||
|
||||
|
||||
B<virt-image> is a command line tool for creating virtual machines from an
|
||||
XML image descriptor C<IMAGE.XML> (L<virt-image(5)>). Most attributes of
|
||||
the virtual machine are taken from the XML descriptor (e.g., where the
|
||||
files to back the virtual machine's disks are and how to map them into the
|
||||
guest), though certain information must be added on the command line, such
|
||||
as the name of the guest.
|
||||
|
||||
The XML descriptor defines most attributes of the guest, making it possible
|
||||
to bundle and distribute it together with the files backing the guest's
|
||||
disks.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
Most options can be omitted, in which case B<virt-image> will use defaults
|
||||
from the XML descriptor. When defaults are taken from the XML descriptor,
|
||||
they are indicated below as a path. --name is the only required command
|
||||
line option.
|
||||
|
||||
=over 4
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Show the help message and exit
|
||||
|
||||
=item --version
|
||||
|
||||
Show program's version number and exit
|
||||
|
||||
=item --connect=URI
|
||||
|
||||
Connect to a non-default hypervisor. See L<virt-install(1)> for details
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
=head2 General Options
|
||||
|
||||
General configuration parameters that apply to all types of guest installs.
|
||||
|
||||
=over 2
|
||||
|
||||
=item -n NAME, --name=NAME
|
||||
|
||||
Name of the guest instance
|
||||
|
||||
=item --memory=MEMORY
|
||||
|
||||
Memory to allocate for the guest, in MiB. Defaults to C</image/devices/memory> in the XML descriptor. This deprecates the -r/--ram option.
|
||||
|
||||
See L<virt-install(1)> for more details.
|
||||
|
||||
=item --vcpus=VCPUS
|
||||
|
||||
Number of vcpus to configure for your guest. Defaults to
|
||||
C</image/devices/vcpu> in the XML descriptor. This option can also be
|
||||
used to set CPU topology, please see L<virt-install(1)> for more info.
|
||||
|
||||
=item --cpu
|
||||
|
||||
Configure the CPU and CPU features exposed to the guest. Please see
|
||||
L<virt-install(1)> for more info.
|
||||
|
||||
=item --os-variant=OS_VARIANT
|
||||
|
||||
Optimize the guest configuration for a specific operating system (ex.
|
||||
'fedora18', 'rhel7', 'winxp'). While not requires, specifying this
|
||||
options is HIGHLY RECOMMENDED, as it can greatly increase performance
|
||||
by specifying virtio among other guest tweaks.
|
||||
See L<virt-install(1)> for valid values.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=head2 Networking Configuration
|
||||
|
||||
=over 2
|
||||
|
||||
=item -w NETWORK, --network=NETWORK
|
||||
|
||||
Connect the guest to the host network. This deprecates the -m/--mac and -b/--bridge options. See L<virt-install(1)> for details.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
=head2 Graphics Configuration
|
||||
|
||||
If no graphics option is specified, C<virt-image> will default to
|
||||
'--graphics vnc' if the DISPLAY environment variable is set, otherwise
|
||||
'--graphics none' is used.
|
||||
|
||||
=over 2
|
||||
|
||||
=item --graphics TYPE,opt1=arg1,opt2=arg2,...
|
||||
|
||||
Specifies the graphical display configuration. This does not configure any
|
||||
virtual hardware, just how the guest's graphical display can be accessed.
|
||||
See L<virt-install(1)> for details usage info.
|
||||
|
||||
This deprecates the following options: --vnc, --vncport, --vnclisten, -k/--keymap, --sdl, --nographics
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=head2 Miscellaneous Options
|
||||
|
||||
=over 2
|
||||
|
||||
=item --print-xml
|
||||
|
||||
Print the libvirt XML, but do not start the guest.
|
||||
|
||||
=item --boot=BOOT
|
||||
|
||||
The zero-based index of the boot record to use. The XML descriptor can
|
||||
contain multiple C</image/domain/boot> elements for use on different
|
||||
hypervisors. By default, the one that is most appropriate for the current
|
||||
hypervisor is selected.
|
||||
|
||||
=item --replace
|
||||
|
||||
Shutdown and remove any existing guest with the passed C<--name> before
|
||||
installing from the image.
|
||||
|
||||
=item --noreboot
|
||||
|
||||
Prevent the domain automatically booting after importing the image.
|
||||
|
||||
=item --skip-checksum
|
||||
|
||||
Do not check disk images against checksums (if they are listed in the
|
||||
image xml).
|
||||
|
||||
=item -d, --debug
|
||||
|
||||
Print debugging information.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
Create and start a guest called C<example> with a VNC console from
|
||||
C<image.xml>:
|
||||
|
||||
# virt-image --name example --vnc image.xml
|
||||
|
||||
Print the libvirt XML for a guest called C<example> without graphics, but
|
||||
do not create or start a virtual machine:
|
||||
|
||||
# virt-image --print --name example --nographics image.xml
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please see http://virt-manager.org/page/BugReporting
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) Red Hat, Inc, and various contributors.
|
||||
This is free software. You may redistribute copies of it under the terms
|
||||
of the GNU General Public License C<http://www.gnu.org/licenses/gpl.html>.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<virt-image(5)>, L<virt-install(1)>, the project website
|
||||
C<http://virt-manager.org>
|
||||
|
||||
=cut
|
||||
|
21
setup.py
21
setup.py
|
@ -32,7 +32,7 @@ def _generate_potfiles_in():
|
|||
return ret
|
||||
|
||||
scripts = ["virt-manager", "virt-install",
|
||||
"virt-clone", "virt-image", "virt-convert", "virt-xml"]
|
||||
"virt-clone", "virt-convert", "virt-xml"]
|
||||
|
||||
potfiles = "\n".join(scripts) + "\n\n"
|
||||
potfiles += "\n".join(find("virtManager", "*.py")) + "\n\n"
|
||||
|
@ -145,7 +145,7 @@ class my_build(build):
|
|||
|
||||
def _make_bin_wrappers(self):
|
||||
cmds = ["virt-manager", "virt-install", "virt-clone",
|
||||
"virt-image", "virt-convert", "virt-xml"]
|
||||
"virt-convert", "virt-xml"]
|
||||
|
||||
if not os.path.exists("build"):
|
||||
os.mkdir("build")
|
||||
|
@ -164,16 +164,9 @@ class my_build(build):
|
|||
def _make_man_pages(self):
|
||||
for path in glob.glob("man/*.pod"):
|
||||
base = os.path.basename(path)
|
||||
|
||||
mantype = "1"
|
||||
newbase = base
|
||||
if base == "virt-image-xml.pod":
|
||||
mantype = "5"
|
||||
newbase = "virt-image.pod"
|
||||
|
||||
appname = os.path.splitext(newbase)[0]
|
||||
appname = os.path.splitext(base)[0]
|
||||
newpath = os.path.join(os.path.dirname(path),
|
||||
appname + "." + mantype)
|
||||
appname + ".1")
|
||||
|
||||
print "Generating %s" % newpath
|
||||
ret = os.system('pod2man '
|
||||
|
@ -566,7 +559,7 @@ class CheckPylint(Command):
|
|||
pass
|
||||
|
||||
def run(self):
|
||||
files = ["setup.py", "virt-install", "virt-clone", "virt-image",
|
||||
files = ["setup.py", "virt-install", "virt-clone",
|
||||
"virt-convert", "virt-xml", "virt-manager",
|
||||
"virtcli", "virtinst", "virtconv", "virtManager",
|
||||
"tests"]
|
||||
|
@ -597,7 +590,6 @@ setup(
|
|||
"build/virt-manager",
|
||||
"build/virt-clone",
|
||||
"build/virt-install",
|
||||
"build/virt-image",
|
||||
"build/virt-convert",
|
||||
"build/virt-xml"]),
|
||||
|
||||
|
@ -606,7 +598,6 @@ setup(
|
|||
"virt-manager",
|
||||
"virt-install",
|
||||
"virt-clone",
|
||||
"virt-image",
|
||||
"virt-convert",
|
||||
"virt-xml",
|
||||
]),
|
||||
|
@ -618,11 +609,9 @@ setup(
|
|||
"man/virt-manager.1",
|
||||
"man/virt-install.1",
|
||||
"man/virt-clone.1",
|
||||
"man/virt-image.1",
|
||||
"man/virt-convert.1",
|
||||
"man/virt-xml.1"
|
||||
]),
|
||||
("share/man/man5", ["man/virt-image.5"]),
|
||||
|
||||
("share/virt-manager/virtManager", glob.glob("virtManager/*.py")),
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ def _cleanup_imports_cb():
|
|||
|
||||
atexit.register(_cleanup_imports_cb)
|
||||
virtinstall = _import("virtinstall", "virt-install")
|
||||
virtimage = _import("virtimage", "virt-image")
|
||||
virtclone = _import("virtclone", "virt-clone")
|
||||
virtconvert = _import("virtconvert", "virt-convert")
|
||||
virtxml = _import("virtxml", "virt-xml")
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>foobar</name>
|
||||
<uuid>00000000-1111-2222-3333-444444444444</uuid>
|
||||
<memory>262144</memory>
|
||||
<currentMemory>131072</currentMemory>
|
||||
<vcpu>7</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<pae/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/__virtinst__cli_root.raw"/>
|
||||
<target dev="xvda" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/__virtinst__cli_scratch.raw"/>
|
||||
<target dev="xvdc" bus="xen"/>
|
||||
</disk>
|
||||
<controller type="usb" index="0" model="ich9-ehci1"/>
|
||||
<controller type="usb" index="0" model="ich9-uhci1">
|
||||
<master startport="0"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci2">
|
||||
<master startport="2"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci3">
|
||||
<master startport="4"/>
|
||||
</controller>
|
||||
<interface type="user">
|
||||
<mac address="00:11:22:33:44:55"/>
|
||||
</interface>
|
||||
<input type="mouse" bus="xen"/>
|
||||
<graphics type="vnc" port="-1" keymap="en-us"/>
|
||||
<video>
|
||||
<model type="vga"/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,44 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>foobar</name>
|
||||
<uuid>00000000-1111-2222-3333-444444444444</uuid>
|
||||
<memory>65536</memory>
|
||||
<currentMemory>65536</currentMemory>
|
||||
<vcpu>7</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/test-hv</emulator>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/__virtinst__cli_root.raw"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
</disk>
|
||||
<controller type="usb" index="0" model="ich9-ehci1"/>
|
||||
<controller type="usb" index="0" model="ich9-uhci1">
|
||||
<master startport="0"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci2">
|
||||
<master startport="2"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci3">
|
||||
<master startport="4"/>
|
||||
</controller>
|
||||
<interface type="user">
|
||||
<mac address="00:11:22:33:44:55"/>
|
||||
<model type="e1000"/>
|
||||
</interface>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="vnc" port="-1" keymap="en-us"/>
|
||||
<console type="pty"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,38 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>foobar</name>
|
||||
<uuid>00000000-1111-2222-3333-444444444444</uuid>
|
||||
<memory>65536</memory>
|
||||
<currentMemory>65536</currentMemory>
|
||||
<vcpu>7</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<pae/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/__virtinst__cli_root.raw"/>
|
||||
<target dev="xvda" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/__virtinst__cli_scratch.raw"/>
|
||||
<target dev="xvdc" bus="xen"/>
|
||||
</disk>
|
||||
<controller type="usb" index="0" model="ich9-ehci1"/>
|
||||
<controller type="usb" index="0" model="ich9-uhci1">
|
||||
<master startport="0"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci2">
|
||||
<master startport="2"/>
|
||||
</controller>
|
||||
<controller type="usb" index="0" model="ich9-uhci3">
|
||||
<master startport="4"/>
|
||||
</controller>
|
||||
<interface type="user">
|
||||
<mac address="00:11:22:33:44:55"/>
|
||||
</interface>
|
||||
<input type="mouse" bus="xen"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,37 +0,0 @@
|
|||
<image>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<loader>pygrub</loader>
|
||||
</os>
|
||||
<drive disk="/tmp/__virtinst__cli_root.raw" target="xvda"/>
|
||||
<drive disk="/tmp/__virtinst__cli_scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader dev="hd"/>
|
||||
</os>
|
||||
<drive disk="/tmp/__virtinst__cli_root.raw" target="hda"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="/tmp/__virtinst__cli_root.raw" format="raw" size="4096" use="system"/>
|
||||
<disk file="/tmp/__virtinst__cli_scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
|
@ -1,38 +0,0 @@
|
|||
<image>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<loader>pygrub</loader>
|
||||
</os>
|
||||
<drive disk="/tmp/__virtinst__cli_root.raw" target="xvda"/>
|
||||
<drive disk="/tmp/__virtinst__cli_scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader dev="hd"/>
|
||||
</os>
|
||||
<drive disk="/tmp/__virtinst__cli_root.raw" target="hda"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="/tmp/__virtinst__cli_root.raw" format="raw" size="4096" use="system"/>
|
||||
<disk file="/tmp/__virtinst__cli_scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
|
@ -29,7 +29,7 @@ import StringIO
|
|||
|
||||
from virtinst import support
|
||||
|
||||
from tests import virtinstall, virtimage, virtclone, virtconvert, virtxml
|
||||
from tests import virtinstall, virtclone, virtconvert, virtxml
|
||||
from tests import utils
|
||||
|
||||
os.environ["LANG"] = "en_US.UTF-8"
|
||||
|
@ -68,20 +68,12 @@ exist_images = [
|
|||
ro_img,
|
||||
]
|
||||
|
||||
# Images that need to exist ahead of time for virt-image
|
||||
virtimage_exist = ["/tmp/__virtinst__cli_root.raw"]
|
||||
|
||||
# Images created by virt-image
|
||||
virtimage_new = ["/tmp/__virtinst__cli_scratch.raw"]
|
||||
|
||||
# Fake iso for --location iso mounting
|
||||
fake_iso = ["/tmp/fake.iso"]
|
||||
|
||||
exist_files = exist_images + virtimage_exist + fake_iso
|
||||
new_files = new_images + virtimage_new
|
||||
clean_files = (new_images + exist_images +
|
||||
virtimage_exist + virtimage_new + [ro_dir]
|
||||
+ fake_iso)
|
||||
exist_files = exist_images + fake_iso
|
||||
new_files = new_images
|
||||
clean_files = (new_images + exist_images + [ro_dir] + fake_iso)
|
||||
|
||||
promptlist = []
|
||||
|
||||
|
@ -167,8 +159,6 @@ class Command(object):
|
|||
ret = virtinstall.main(conn=conn)
|
||||
elif app.count("virt-clone"):
|
||||
ret = virtclone.main(conn=conn)
|
||||
elif app.count("virt-image"):
|
||||
ret = virtimage.main(conn=conn)
|
||||
elif app.count("virt-convert"):
|
||||
ret = virtconvert.main(conn=conn)
|
||||
elif app.count("virt-xml"):
|
||||
|
@ -397,10 +387,6 @@ class App(object):
|
|||
not cli.count("--quiet")):
|
||||
args += " --print-step all"
|
||||
|
||||
elif self.appname == "virt-image":
|
||||
if not cli.count("--print"):
|
||||
args += " --print"
|
||||
|
||||
elif self.appname == "virt-clone":
|
||||
if not cli.count("--print-xml"):
|
||||
args += " --print-xml"
|
||||
|
@ -687,7 +673,7 @@ c.add_invalid("--mac 22:22:33:12:34:AB") # Colliding macaddr
|
|||
c = vinst.add_category("storage", "--pxe --nographics --noautoconsole --hvm")
|
||||
c.add_valid("--file %(EXISTIMG1)s --nonsparse --file-size 4") # Existing file, other opts
|
||||
c.add_valid("--file %(EXISTIMG1)s") # Existing file, no opts
|
||||
c.add_valid("--file %(EXISTIMG1)s --file virt-image --file virt-clone") # Multiple existing files
|
||||
c.add_valid("--file %(EXISTIMG1)s --file virt-clone --file virt-clone") # Multiple existing files
|
||||
c.add_valid("--file %(NEWIMG1)s --file-size .00001 --nonsparse") # Nonexistent file
|
||||
c.add_valid("--disk path=%(EXISTIMG1)s,perms=ro,size=.0001,cache=writethrough,io=threads") # Existing disk, lots of opts
|
||||
c.add_valid("--disk path=%(EXISTIMG1)s,perms=rw") # Existing disk, rw perms
|
||||
|
@ -868,42 +854,6 @@ c.add_compare("--remove-device --disk /dev/null", "remove-disk-path")
|
|||
c.add_compare("--remove-device --video all", "remove-video-all")
|
||||
|
||||
|
||||
vimag = App("virt-image")
|
||||
c = vimag.add_category("graphics", "--name test-image --boot 0 %(IMAGE_XML)s")
|
||||
c.add_valid("--sdl") # SDL
|
||||
c.add_valid("--vnc --keymap ja --vncport 5950 --vnclisten 1.2.3.4") # VNC w/ lots of options
|
||||
|
||||
|
||||
c = vimag.add_category("misc", "")
|
||||
c.add_valid("--network=?") # Make sure introspection doesn't blow up
|
||||
c.add_compare("--name foobar --memory 128,maxmemory=256 --os-variant winxp --boot 0 %(IMAGE_XML)s", "image-boot0")
|
||||
c.add_compare("--name foobar --ram 64 --network user,model=e1000 --boot 1 %(IMAGE_XML)s", "image-boot1")
|
||||
c.add_compare("--name foobar --ram 64 --boot 0 %(IMAGE_NOGFX_XML)s", "image-nogfx")
|
||||
c.add_valid("--name test --replace %(IMAGE_XML)s") # Colliding VM name w/ --replace
|
||||
c.add_invalid("%(IMAGE_XML)s") # No name specified, and no prompt flag
|
||||
c.add_invalid("--name test %(IMAGE_XML)s") # Colliding VM name without --replace
|
||||
|
||||
|
||||
c = vimag.add_category("network", "--name test-image --boot 0 --nographics %(IMAGE_XML)s")
|
||||
c.add_valid("--network=user") # user networking
|
||||
c.add_valid("--network network:default --mac RANDOM") # VirtualNetwork with a random macaddr
|
||||
c.add_valid("--network network:default --mac 00:11:22:33:44:55") # VirtualNetwork with a random macaddr
|
||||
c.add_valid("--network=user,model=e1000") # with NIC model
|
||||
c.add_valid("--network=network:default,model=e1000 --network=user,model=virtio") # several networks
|
||||
c.add_invalid("--network=FOO") # Nonexistent network
|
||||
c.add_invalid("--network=network:default --mac 1234") # Invalid mac
|
||||
|
||||
|
||||
c = vimag.add_category("general", "--name test-image %(IMAGE_XML)s")
|
||||
c.add_valid("") # All default values
|
||||
c.add_valid("--print") # Print default
|
||||
c.add_valid("--boot 0") # Manual boot idx 0
|
||||
c.add_valid("--boot 1") # Manual boot idx 1
|
||||
c.add_valid("--name foobar --ram 64 --os-variant winxp") # Lots of options
|
||||
c.add_valid("--name foobar --ram 64 --os-variant none") # OS variant 'none'
|
||||
c.add_invalid("--boot 10") # Out of bounds index
|
||||
|
||||
|
||||
|
||||
|
||||
vconv = App("virt-convert")
|
||||
|
@ -1026,7 +976,6 @@ def maketest(cmd):
|
|||
_cmdlist = promptlist[:]
|
||||
_cmdlist += vinst.cmds
|
||||
_cmdlist += vclon.cmds
|
||||
_cmdlist += vimag.cmds
|
||||
_cmdlist += vconv.cmds
|
||||
_cmdlist += vixml.cmds
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<image>
|
||||
<name>test-image</name>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i386</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<loader>pygrub</loader>
|
||||
</os>
|
||||
<drive disk="root.raw" target="xvda"/>
|
||||
<drive disk="data.raw" target="xvdb"/>
|
||||
<drive disk="scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="disk.img"/>
|
||||
<disk size="4096" use="system">
|
||||
<partition file="boot.img"/>
|
||||
<partition file="root.img"/>
|
||||
</disk>
|
||||
<disk file="root.raw" format="raw" size="4096" use="system"/>
|
||||
<disk file="data.raw" format="raw" size='2048' use="data"/>
|
||||
<disk file="scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
|
@ -1,27 +0,0 @@
|
|||
<image>
|
||||
<name>demo</name>
|
||||
<domain>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
</guest>
|
||||
<os>
|
||||
<loader dev="hd"/>
|
||||
</os>
|
||||
<drive disk="mydisk1" target="hda"/>
|
||||
<drive disk="mydisk2" target="hdb"/>
|
||||
<drive disk="mydisk3" target="hdc"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>1</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk id="mydisk1" file="image-kernel.xml" use="system" format="qcow2"/>
|
||||
<disk id="mydisk2" file="image.xml" use="system" format="qcow"/>
|
||||
<disk id="mydisk3" file="image-format.xml" use="system" format="vmdk"/>
|
||||
</storage>
|
||||
</image>
|
|
@ -1,37 +0,0 @@
|
|||
<image>
|
||||
<name>test-image</name>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<kernel>/foo/kernel</kernel>
|
||||
<initrd>/foo/initrd</initrd>
|
||||
<cmdline>ro quiet</cmdline>
|
||||
</os>
|
||||
<drive disk="root.raw" target="xvda"/>
|
||||
<drive disk="data.raw" target="xvdb"/>
|
||||
<drive disk="scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="disk.img"/>
|
||||
<disk size="4096" use="system">
|
||||
<partition file="boot.img"/>
|
||||
<partition file="root.img"/>
|
||||
</disk>
|
||||
<disk file="root.raw" format="raw" size="4096" use="scratch"/>
|
||||
<disk file="data.raw" format="raw" size='2048' use="scratch"/>
|
||||
<disk file="scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
|
@ -1,48 +0,0 @@
|
|||
<image>
|
||||
<name>test-image</name>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<loader>pygrub</loader>
|
||||
</os>
|
||||
<drive disk="root.raw" target="xvda"/>
|
||||
<drive disk="data.raw" target="xvdb"/>
|
||||
<drive disk="scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader dev="hd"/>
|
||||
</os>
|
||||
<drive disk="root.raw" target="hda"/>
|
||||
<drive disk="data.raw" target="hdb"/>
|
||||
<drive disk="scratch.raw" target="hdd"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="disk.img"/>
|
||||
<disk size="4096" use="system">
|
||||
<partition file="boot.img"/>
|
||||
<partition file="root.img"/>
|
||||
</disk>
|
||||
<disk file="root.raw" format="raw" size="4096" use="scratch"/>
|
||||
<disk file="data.raw" format="raw" size='2048' use="scratch"/>
|
||||
<disk file="scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
|
@ -1,40 +0,0 @@
|
|||
<domain type="kvm">
|
||||
<name>TestGuest</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu>5</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<disk type="file" device="disk">
|
||||
<driver name="qemu" type="qcow2"/>
|
||||
<source file="/tmp/tests/image-xml/image-kernel.xml"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<driver name="qemu" type="qcow"/>
|
||||
<source file="/tmp/tests/image-xml/image.xml"/>
|
||||
<target dev="hdb" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<driver name="qemu" type="vmdk"/>
|
||||
<source file="/tmp/tests/image-xml/image-format.xml"/>
|
||||
<target dev="hdc" bus="ide"/>
|
||||
</disk>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="vnc" port="-1" keymap="ja"/>
|
||||
<console type="pty"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,38 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>TestGuest</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu>5</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/root.raw"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/data.raw"/>
|
||||
<target dev="hdb" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/scratch.raw"/>
|
||||
<target dev="hdd" bus="ide"/>
|
||||
</disk>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="vnc" port="-1" keymap="ja"/>
|
||||
<console type="pty"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,35 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>TestGuest</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu>5</vcpu>
|
||||
<os>
|
||||
<type arch="i686">xen</type>
|
||||
<kernel>/foo/kernel</kernel>
|
||||
<initrd>/foo/initrd</initrd>
|
||||
<cmdline>ro quiet</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<pae/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/root.raw"/>
|
||||
<target dev="xvda" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/data.raw"/>
|
||||
<target dev="xvdb" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/scratch.raw"/>
|
||||
<target dev="xvdc" bus="xen"/>
|
||||
</disk>
|
||||
<input type="mouse" bus="xen"/>
|
||||
<graphics type="vnc" port="-1" keymap="ja"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,30 +0,0 @@
|
|||
<domain type="test">
|
||||
<name>TestGuest</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu>5</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<pae/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/root.raw"/>
|
||||
<target dev="xvda" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/data.raw"/>
|
||||
<target dev="xvdb" bus="xen"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/tests/image-xml/scratch.raw"/>
|
||||
<target dev="xvdc" bus="xen"/>
|
||||
</disk>
|
||||
<input type="mouse" bus="xen"/>
|
||||
<graphics type="vnc" port="-1" keymap="ja"/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -1,49 +0,0 @@
|
|||
<image>
|
||||
<name>test-image</name>
|
||||
<label>A simple test image</label>
|
||||
<domain>
|
||||
<boot type='xen'>
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<loader>pygrub</loader>
|
||||
</os>
|
||||
<drive disk="root.raw" target="xvda"/>
|
||||
<drive disk="data.raw" target="xvdb"/>
|
||||
<drive disk="scratch.raw" target="xvdc"/>
|
||||
</boot>
|
||||
<boot type="hvm">
|
||||
<guest>
|
||||
<arch>i686</arch>
|
||||
<features><pae/></features>
|
||||
</guest>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader dev="hd"/>
|
||||
</os>
|
||||
<drive disk="root.raw" target="hda"/>
|
||||
<drive disk="data.raw" target="hdb"/>
|
||||
<drive disk="scratch.raw" target="hdd"/>
|
||||
</boot>
|
||||
<devices>
|
||||
<vcpu>7</vcpu>
|
||||
<memory>262144</memory>
|
||||
<interface/>
|
||||
<interface/>
|
||||
<graphics/>
|
||||
</devices>
|
||||
</domain>
|
||||
<storage>
|
||||
<disk file="disk.img"/>
|
||||
<disk size="4096" use="system">
|
||||
<partition file="boot.img"/>
|
||||
<partition file="root.img"/>
|
||||
</disk>
|
||||
<disk file="root.raw" format="raw" size="4096" use="system"/>
|
||||
<disk file="data.raw" format="raw" size='2048' use="data"/>
|
||||
<disk file="scratch.raw" format="raw" size='100' use='scratch'/>
|
||||
</storage>
|
||||
</image>
|
110
tests/image.py
110
tests/image.py
|
@ -1,110 +0,0 @@
|
|||
# Copyright (C) 2013 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from virtinst import virtimage
|
||||
|
||||
from tests import utils
|
||||
|
||||
qemuuri = "__virtinst_test__test:///default,caps=%s/tests/capabilities-xml/capabilities-kvm.xml,qemu,predictable" % os.getcwd()
|
||||
|
||||
|
||||
# pylint: disable=protected-access
|
||||
# Access to protected member, needed to unittest stuff
|
||||
|
||||
class TestImageParser(unittest.TestCase):
|
||||
basedir = "tests/image-xml/"
|
||||
conn = utils.open_testdefault()
|
||||
qemuconn = utils.openconn(qemuuri)
|
||||
|
||||
def testImageParsing(self):
|
||||
f = open(os.path.join(self.basedir, "image.xml"), "r")
|
||||
xml = f.read()
|
||||
f.close()
|
||||
|
||||
img = virtimage.parse(xml, ".")
|
||||
self.assertEqual("test-image", img.name)
|
||||
self.assertTrue(img.domain)
|
||||
self.assertEqual(5, len(img.storage))
|
||||
self.assertEqual(2, len(img.domain.boots))
|
||||
self.assertEqual(1, img.domain.interface)
|
||||
boot = img.domain.boots[0]
|
||||
self.assertEqual("xvdb", boot.drives[1].target)
|
||||
|
||||
def testMultipleNics(self):
|
||||
f = open(os.path.join(self.basedir, "image2nics.xml"), "r")
|
||||
xml = f.read()
|
||||
f.close()
|
||||
|
||||
img = virtimage.parse(xml, ".")
|
||||
self.assertEqual(2, img.domain.interface)
|
||||
|
||||
def testBadArch(self):
|
||||
"""Makes sure we sanitize i386->i686"""
|
||||
image = virtimage.parse_file(self.basedir + "image-bad-arch.xml")
|
||||
virtimage.ImageInstaller(self.conn, image, 0)
|
||||
self.assertTrue(True)
|
||||
|
||||
def testStorageFormat(self):
|
||||
self._image2XMLhelper("image-format.xml", "image-format-out.xml",
|
||||
qemu=True)
|
||||
|
||||
def _image2XMLhelper(self, image_xml, output_xmls, qemu=False):
|
||||
image2guestdir = self.basedir + "image2guest/"
|
||||
image = virtimage.parse_file(self.basedir + image_xml)
|
||||
if type(output_xmls) is not list:
|
||||
output_xmls = [output_xmls]
|
||||
|
||||
conn = qemu and self.qemuconn or self.conn
|
||||
gtype = qemu and "qemu" or "xen"
|
||||
|
||||
for idx in range(len(output_xmls)):
|
||||
fname = output_xmls[idx]
|
||||
inst = virtimage.ImageInstaller(conn, image, boot_index=idx)
|
||||
capsguest, capsdomain = inst.get_caps_guest()
|
||||
if capsguest.os_type == "hvm":
|
||||
g = utils.get_basic_fullyvirt_guest(typ=gtype)
|
||||
else:
|
||||
g = utils.get_basic_paravirt_guest()
|
||||
|
||||
utils.set_conn(conn)
|
||||
g.os.os_type = capsguest.os_type
|
||||
g.type = capsdomain.hypervisor_type
|
||||
g.os.arch = capsguest.arch
|
||||
|
||||
g.installer = inst
|
||||
# pylint: disable=unpacking-non-sequence
|
||||
ignore, actual_out = g.start_install(return_xml=True, dry=True)
|
||||
|
||||
actual_out = g.get_install_xml(install=False)
|
||||
expect_file = os.path.join(image2guestdir + fname)
|
||||
|
||||
actual_out = actual_out.replace(os.getcwd(), "/tmp")
|
||||
utils.diff_compare(actual_out, expect_file)
|
||||
|
||||
utils.reset_conn()
|
||||
|
||||
def testImage2XML(self):
|
||||
# Build guest XML from the image xml
|
||||
self._image2XMLhelper("image.xml", ["image-xenpv32.xml",
|
||||
"image-xenfv32.xml"])
|
||||
self._image2XMLhelper("image-kernel.xml", ["image-xenpv32-kernel.xml"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -82,7 +82,7 @@ class TestMisc(unittest.TestCase):
|
|||
"""
|
||||
Make sure virtinst doesn't pull in any gnome modules
|
||||
"""
|
||||
files = ["virt-install", "virt-clone", "virt-convert", "virt-image"]
|
||||
files = ["virt-install", "virt-clone", "virt-convert"]
|
||||
files += _find_py("virtinst")
|
||||
files += _find_py("virtconv")
|
||||
files += _find_py("virtcli")
|
||||
|
|
172
virt-image
172
virt-image
|
@ -1,172 +0,0 @@
|
|||
#!/usr/bin/python2 -tt
|
||||
#
|
||||
# Create a virtual machine from an XML image description
|
||||
#
|
||||
# Copyright 2007, 2014 Red Hat, Inc.
|
||||
# David Lutterkort <dlutter@redhat.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import urlgrabber.progress as progress
|
||||
|
||||
import virtinst.cli as cli
|
||||
from virtinst.cli import fail, print_stdout, print_stderr
|
||||
from virtinst import virtimage
|
||||
|
||||
|
||||
# Option parsing
|
||||
def parse_args():
|
||||
parser = cli.setupParser(
|
||||
"%(prog)s image.xml [OPTIONS]",
|
||||
_("Create a virtual machine from a virt-image(5) image descriptor."),
|
||||
introspection_epilog=True)
|
||||
cli.add_connect_option(parser)
|
||||
|
||||
parser.add_argument("image", metavar="image.xml", nargs='?',
|
||||
help=_("virt-image(5) image descriptor"))
|
||||
|
||||
geng = parser.add_argument_group(_("General Options"))
|
||||
geng.add_argument("-n", "--name", help=_("Name of the guest instance"))
|
||||
geng.add_argument("-u", "--uuid", help=argparse.SUPPRESS)
|
||||
cli.add_memory_option(geng, backcompat=True)
|
||||
cli.vcpu_cli_options(geng)
|
||||
cli.add_distro_options(geng)
|
||||
cli.add_old_feature_options(geng)
|
||||
|
||||
cli.network_option_group(parser)
|
||||
cli.graphics_option_group(parser)
|
||||
|
||||
misc = parser.add_argument_group(_("Miscellaneous Options"))
|
||||
misc.add_argument("--boot", type=int,
|
||||
help=_("The zero-based index of the boot record to use"))
|
||||
misc.add_argument("--skip-checksum", action="store_true",
|
||||
help=_("Skip disk checksum verification process"))
|
||||
|
||||
cli.add_misc_options(misc, prompt=True, replace=True, printxml=True,
|
||||
noreboot=True)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main(conn=None):
|
||||
cli.earlyLogging()
|
||||
options = parse_args()
|
||||
|
||||
options.quiet = options.xmlonly or options.quiet
|
||||
cli.setupLogging("virt-image", options.debug, options.quiet)
|
||||
cli.set_prompt(options.prompt)
|
||||
|
||||
cli.convert_old_features(options)
|
||||
parsermap = cli.build_parser_map(options,
|
||||
only=["memory", "vcpus", "cpu", "network", "graphics", "features"])
|
||||
if cli.check_option_introspection(options, parsermap):
|
||||
return 0
|
||||
|
||||
if not options.image:
|
||||
fail(_("You need to provide an image XML descriptor"))
|
||||
|
||||
if conn is None:
|
||||
conn = cli.getConnection(options.connect)
|
||||
|
||||
try:
|
||||
image = virtimage.parse_file(options.image)
|
||||
except RuntimeError, msg:
|
||||
fail("%s '%s': %s" % (_("Cannot parse"), options.image, msg))
|
||||
|
||||
if options.boot is not None:
|
||||
nboots = len(image.domain.boots)
|
||||
if options.boot < 0 or options.boot >= nboots:
|
||||
fail(_("The index for --boot must be between 0 and %d") %
|
||||
(nboots - 1))
|
||||
|
||||
# Build the Installer instance
|
||||
installer = virtimage.ImageInstaller(conn, image, boot_index=options.boot)
|
||||
guest = conn.caps.build_virtinst_guest(conn, *installer.get_caps_guest())
|
||||
guest.installer = installer
|
||||
|
||||
cli.convert_old_memory(options)
|
||||
cli.convert_old_networks(options, image.domain.interface)
|
||||
cli.convert_old_graphics(guest, options,
|
||||
default_override=bool(image.domain.graphics))
|
||||
cli.convert_old_cpuset(options)
|
||||
if not options.vcpus:
|
||||
options.vcpus = image.domain.vcpu or ""
|
||||
if not options.memory and image.domain.memory:
|
||||
options.memory = image.domain.memory
|
||||
|
||||
guest.replace = options.replace
|
||||
cli.set_os_variant(guest, options.distro_type, options.distro_variant)
|
||||
|
||||
name = options.name or image.name
|
||||
if not name:
|
||||
fail(cli.name_missing)
|
||||
guest.name = name
|
||||
if options.uuid:
|
||||
guest.uuid = options.uuid
|
||||
|
||||
cli.parse_option_strings(parsermap, options, guest, None)
|
||||
|
||||
guest.add_default_devices()
|
||||
|
||||
msg = _("\nvirt-image is planned for removal in the near future. "
|
||||
"If you are depending on this tool, please contact the developers "
|
||||
"at virt-tools-list@redhat.com\n")
|
||||
logging.warning(msg)
|
||||
if "VIRTINST_TEST_SUITE" not in os.environ:
|
||||
if options.quiet:
|
||||
print msg
|
||||
time.sleep(3)
|
||||
|
||||
# we've got everything -- try to start the install
|
||||
if options.xmlonly:
|
||||
start_xml, final_xml = guest.start_install(return_xml=True)
|
||||
print_stdout(start_xml or final_xml, do_force=True)
|
||||
return 0
|
||||
|
||||
meter = progress.TextMeter(fo=sys.stdout)
|
||||
|
||||
if not options.skip_checksum:
|
||||
for disk in image.storage.values():
|
||||
disk.check_disk_signature(meter=meter)
|
||||
|
||||
try:
|
||||
print_stdout("\n")
|
||||
print_stdout(_("Creating guest %s...") % guest.name)
|
||||
|
||||
guest.start_install(meter=meter, noboot=options.noreboot)
|
||||
except RuntimeError:
|
||||
raise
|
||||
except Exception, e:
|
||||
fail(e, do_exit=False)
|
||||
cli.install_fail(guest)
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
sys.exit(main())
|
||||
except SystemExit, sys_e:
|
||||
sys.exit(sys_e.code)
|
||||
except KeyboardInterrupt:
|
||||
print_stderr(_("Installation aborted at user request"))
|
||||
except Exception, main_e:
|
||||
fail(main_e)
|
|
@ -88,7 +88,6 @@ Requires: virt-manager-common = %{verrel}
|
|||
|
||||
Provides: virt-install
|
||||
Provides: virt-clone
|
||||
Provides: virt-image
|
||||
Provides: virt-convert
|
||||
Provides: virt-xml
|
||||
Obsoletes: python-virtinst
|
||||
|
@ -193,18 +192,14 @@ fi
|
|||
%{_mandir}/man1/virt-clone.1*
|
||||
%{_mandir}/man1/virt-convert.1*
|
||||
%{_mandir}/man1/virt-xml.1*
|
||||
%{_mandir}/man1/virt-image.1*
|
||||
%{_mandir}/man5/virt-image.5*
|
||||
|
||||
%{_datadir}/%{name}/virt-install
|
||||
%{_datadir}/%{name}/virt-clone
|
||||
%{_datadir}/%{name}/virt-image
|
||||
%{_datadir}/%{name}/virt-convert
|
||||
%{_datadir}/%{name}/virt-xml
|
||||
|
||||
%{_bindir}/virt-install
|
||||
%{_bindir}/virt-clone
|
||||
%{_bindir}/virt-image
|
||||
%{_bindir}/virt-convert
|
||||
%{_bindir}/virt-xml
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ def add_gfx_option(devg):
|
|||
|
||||
def graphics_option_group(parser):
|
||||
"""
|
||||
Register vnc + sdl options for virt-install and virt-image
|
||||
Register vnc + sdl options for virt-install
|
||||
"""
|
||||
vncg = parser.add_argument_group(_("Graphics Configuration"))
|
||||
add_gfx_option(vncg)
|
||||
|
@ -674,7 +674,7 @@ def graphics_option_group(parser):
|
|||
|
||||
def network_option_group(parser):
|
||||
"""
|
||||
Register common network options for virt-install and virt-image
|
||||
Register common network options for virt-install
|
||||
"""
|
||||
netg = parser.add_argument_group(_("Networking Configuration"))
|
||||
|
||||
|
|
|
@ -1,429 +0,0 @@
|
|||
# Sample code to parse an image XML description and
|
||||
# spit out libvirt XML
|
||||
#
|
||||
# Copyright 2007, 2013, 2014 Red Hat, Inc.
|
||||
# David Lutterkort <dlutter@redhat.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import urlgrabber
|
||||
|
||||
from virtinst import CapabilitiesParser
|
||||
from virtinst import Installer
|
||||
from virtinst import VirtualDisk
|
||||
from virtinst import util
|
||||
|
||||
|
||||
class Image(object):
|
||||
"""The toplevel object representing a VM image"""
|
||||
def __init__(self, node=None, base=None, filename=None):
|
||||
self.storage = {}
|
||||
self.domain = None
|
||||
if filename is None:
|
||||
self.filename = None
|
||||
else:
|
||||
self.filename = os.path.abspath(filename)
|
||||
if base is None:
|
||||
if filename is not None:
|
||||
self.base = os.path.dirname(filename)
|
||||
if self.base == '':
|
||||
self.base = "."
|
||||
else:
|
||||
self.base = "."
|
||||
else:
|
||||
self.base = base
|
||||
self.name = None
|
||||
self.label = None
|
||||
self.descr = None
|
||||
self.version = None
|
||||
self.release = None
|
||||
if node is not None:
|
||||
self.parseXML(node)
|
||||
|
||||
def abspath(self, p):
|
||||
"""Turn P into an absolute path. Relative paths are taken relative
|
||||
to self.BASE"""
|
||||
return os.path.abspath(os.path.join(self.base, p))
|
||||
|
||||
def parseXML(self, node):
|
||||
self.name = xpathString(node, "name")
|
||||
self.label = xpathString(node, "label")
|
||||
self.descr = xpathString(node, "description")
|
||||
self.version = xpathString(node, "name/@version")
|
||||
self.release = xpathString(node, "name/@release")
|
||||
for d in node.xpathEval("storage/disk"):
|
||||
disk = Disk(d)
|
||||
if disk.file is None:
|
||||
disk.id = "disk%d.img" % len(self.storage)
|
||||
disk.file = "disk%d.img" % (len(self.storage) + 1)
|
||||
if disk.id in self.storage:
|
||||
raise RuntimeError("Disk file '%s' defined twice" % disk.file)
|
||||
self.storage[disk.id] = disk
|
||||
lm = node.xpathEval("domain")
|
||||
if len(lm) == 1:
|
||||
self.domain = Domain(lm[0])
|
||||
else:
|
||||
raise RuntimeError(_("Expected exactly one 'domain' element"))
|
||||
# Connect the disk maps to the disk definitions
|
||||
for boot in self.domain.boots:
|
||||
for d in boot.drives:
|
||||
if d.disk_id not in self.storage:
|
||||
raise RuntimeError(_("Disk entry for '%s' not found")
|
||||
% d.disk_id)
|
||||
d.disk = self.storage[d.disk_id]
|
||||
|
||||
|
||||
class Domain(object):
|
||||
"""The description of a virtual domain as part of an image"""
|
||||
def __init__(self, node=None):
|
||||
self.boots = []
|
||||
self.vcpu = None
|
||||
self.memory = None
|
||||
self.interface = 0
|
||||
self.graphics = None
|
||||
if node is not None:
|
||||
self.parseXML(node)
|
||||
|
||||
def parseXML(self, node):
|
||||
self.boots = [Boot(b) for b in node.xpathEval("boot")]
|
||||
self.vcpu = xpathString(node, "devices/vcpu", 1)
|
||||
tmpmem = xpathString(node, "devices/memory")
|
||||
self.interface = int(node.xpathEval("count(devices/interface)"))
|
||||
self.graphics = node.xpathEval("count(devices/graphics)") > 0
|
||||
|
||||
if tmpmem is not None:
|
||||
try:
|
||||
self.memory = int(tmpmem)
|
||||
except ValueError:
|
||||
raise RuntimeError(_("Memory must be an integer, "
|
||||
"but is '%s'") % self.memory)
|
||||
else:
|
||||
tmpmem = 0
|
||||
|
||||
|
||||
class ImageFeatures(CapabilitiesParser.Features):
|
||||
def __init__(self, node=None):
|
||||
CapabilitiesParser.Features.__init__(self, node)
|
||||
|
||||
def _extractFeature(self, feature, d, n):
|
||||
state = xpathString(n, "@state", "on")
|
||||
|
||||
if state == "on":
|
||||
d[feature] = CapabilitiesParser.FEATURE_ON
|
||||
elif state == "off":
|
||||
d[feature] = CapabilitiesParser.FEATURE_OFF
|
||||
else:
|
||||
raise RuntimeError("The state for feature %s must be "
|
||||
"either 'on' or 'off', but is '%s'" %
|
||||
(feature, state))
|
||||
|
||||
|
||||
class Boot(object):
|
||||
"""The overall description of how the image can be booted, including
|
||||
required capabilities of the host and mapping of disks into the VM"""
|
||||
def __init__(self, node=None):
|
||||
# 'xen' or 'hvm'
|
||||
self.type = None
|
||||
# Either 'pygrub' or nothing; might have others in the future
|
||||
# For HVM, figure outhte right loader based on the guest
|
||||
self.loader = None
|
||||
# Only used for hvm
|
||||
self.bootdev = None
|
||||
self.kernel = None
|
||||
self.initrd = None
|
||||
self.cmdline = None
|
||||
self.drives = []
|
||||
self.arch = None
|
||||
self.features = ImageFeatures()
|
||||
if node is not None:
|
||||
self.parseXML(node)
|
||||
|
||||
def parseXML(self, node):
|
||||
self.type = xpathString(node, "@type")
|
||||
self.loader = xpathString(node, "os/loader")
|
||||
self.bootdev = xpathString(node, "os/loader/@dev")
|
||||
self.kernel = xpathString(node, "os/kernel")
|
||||
self.initrd = xpathString(node, "os/initrd")
|
||||
self.cmdline = xpathString(node, "os/cmdline")
|
||||
self.arch = util.sanitize_arch(xpathString(node, "guest/arch"))
|
||||
|
||||
fl = node.xpathEval("guest/features")
|
||||
if len(fl) > 1:
|
||||
raise RuntimeError("Expected at most one <features> element "
|
||||
"in %s boot descriptor for %s" %
|
||||
(self.type, self.arch))
|
||||
elif len(fl) == 1:
|
||||
self.features = ImageFeatures(fl[0])
|
||||
|
||||
for d in node.xpathEval("drive"):
|
||||
self.drives.append(Drive(d))
|
||||
|
||||
validate(self.type is not None,
|
||||
"The boot type must be provided")
|
||||
validate(self.type == "hvm" or self.type == "xen",
|
||||
"Boot type must be 'xen' or 'hvm', but is %s" % self.type)
|
||||
validate(self.arch is not None, "Missing guest arch")
|
||||
validate(self.loader is None or self.loader == "pygrub",
|
||||
"Invalid loader %s" % self.loader)
|
||||
validate([None, "hd", "cdrom"].count(self.bootdev) > 0,
|
||||
"Invalid bootdev %s" % self.bootdev)
|
||||
# We should make sure that kernel/initrd/cmdline are only used for pv
|
||||
# and without a loader
|
||||
|
||||
|
||||
class Drive(object):
|
||||
"""The mapping of a disk from the storage section to a virtual drive
|
||||
in a guest"""
|
||||
def __init__(self, node=None):
|
||||
self.disk_id = None
|
||||
self.target = None
|
||||
self.disk = None # Will point to the underlying Disk object
|
||||
if node:
|
||||
self.parseXML(node)
|
||||
|
||||
def parseXML(self, node):
|
||||
self.disk_id = xpathString(node, "@disk")
|
||||
self.target = xpathString(node, "@target")
|
||||
|
||||
|
||||
class Disk(object):
|
||||
FORMAT_RAW = "raw"
|
||||
FORMAT_ISO = "iso"
|
||||
FORMAT_QCOW = "qcow"
|
||||
FORMAT_QCOW2 = "qcow2"
|
||||
FORMAT_VMDK = "vmdk"
|
||||
FORMAT_VDI = "vdi"
|
||||
|
||||
USE_SYSTEM = "system"
|
||||
USE_USER = "user"
|
||||
USE_SCRATCH = "scratch"
|
||||
|
||||
def __init__(self, node=None):
|
||||
self.id = None
|
||||
self.file = None
|
||||
self.format = None
|
||||
self.size = None
|
||||
self.use = None
|
||||
self.csum = {}
|
||||
if node is not None:
|
||||
self.parseXML(node)
|
||||
|
||||
def parseXML(self, node):
|
||||
self.file = xpathString(node, "@file")
|
||||
self.id = xpathString(node, "@id", self.file)
|
||||
self.format = xpathString(node, "@format", Disk.FORMAT_RAW)
|
||||
self.size = xpathString(node, "@size")
|
||||
self.use = xpathString(node, "@use", Disk.USE_SYSTEM)
|
||||
|
||||
for d in node.xpathEval("checksum"):
|
||||
csumtype = xpathString(d, "@type")
|
||||
csumvalue = xpathString(d, "")
|
||||
self.csum[csumtype] = csumvalue
|
||||
formats = [Disk.FORMAT_RAW,
|
||||
Disk.FORMAT_QCOW,
|
||||
Disk.FORMAT_QCOW2,
|
||||
Disk.FORMAT_VMDK,
|
||||
Disk.FORMAT_ISO,
|
||||
Disk.FORMAT_VDI]
|
||||
validate(formats.count(self.format) > 0,
|
||||
_("The format for disk %s must be one of %s") %
|
||||
(self.file, ",".join(formats)))
|
||||
|
||||
def check_disk_signature(self, meter=None):
|
||||
try:
|
||||
import hashlib
|
||||
sha = None
|
||||
except:
|
||||
import sha
|
||||
hashlib = None
|
||||
|
||||
if meter is None:
|
||||
meter = urlgrabber.progress.BaseMeter()
|
||||
|
||||
m = None
|
||||
if hashlib:
|
||||
if "sha256" in self.csum:
|
||||
csumvalue = self.csum["sha256"]
|
||||
m = hashlib.sha256()
|
||||
|
||||
elif "sha1" in self.csum:
|
||||
csumvalue = self.csum["sha1"]
|
||||
m = hashlib.sha1()
|
||||
else:
|
||||
if "sha1" in self.csum:
|
||||
csumvalue = self.csum["sha1"]
|
||||
m = sha.new()
|
||||
|
||||
if not m:
|
||||
return
|
||||
|
||||
meter_ct = 0
|
||||
disk_size = os.path.getsize(self.file)
|
||||
meter.start(size=disk_size,
|
||||
text=_("Checking disk signature for %s" % self.file))
|
||||
|
||||
f = file(self.file)
|
||||
while 1:
|
||||
chunk = f.read(65536)
|
||||
if not chunk:
|
||||
break
|
||||
meter.update(meter_ct)
|
||||
meter_ct = meter_ct + 65536
|
||||
m.update(chunk)
|
||||
checksum = m.hexdigest()
|
||||
if checksum != csumvalue:
|
||||
logging.debug(_("Disk signature for %s does not match "
|
||||
"Expected: %s Received: %s" % (self.file,
|
||||
csumvalue, checksum)))
|
||||
raise ValueError(_("Disk signature for %s does not "
|
||||
"match" % self.file))
|
||||
|
||||
|
||||
def validate(cond, msg):
|
||||
if not cond:
|
||||
raise RuntimeError(msg)
|
||||
|
||||
|
||||
def xpathString(node, path, default=None):
|
||||
result = node.xpathEval("string(%s)" % path)
|
||||
if len(result) == 0:
|
||||
result = default
|
||||
return result
|
||||
|
||||
|
||||
def parse(xml, filename):
|
||||
"""Parse the XML description of a VM image into a data structure. Returns
|
||||
an object of class Image. BASE should be the directory where the disk
|
||||
image files for this image can be found"""
|
||||
def cb(x):
|
||||
return Image(x, filename=filename)
|
||||
return util.parse_node_helper(xml, "image", cb, RuntimeError)
|
||||
|
||||
|
||||
def parse_file(filename):
|
||||
f = open(filename, "r")
|
||||
xml = f.read()
|
||||
f.close()
|
||||
return parse(xml, filename=filename)
|
||||
|
||||
|
||||
class ImageInstaller(Installer):
|
||||
"""
|
||||
Installer for virt-image-based guests
|
||||
"""
|
||||
_has_install_phase = False
|
||||
|
||||
def __init__(self, conn, image, boot_index=None):
|
||||
Installer.__init__(self, conn)
|
||||
|
||||
self._image = image
|
||||
|
||||
# Set boot _boot_caps/_boot_parameters
|
||||
if boot_index is None:
|
||||
self._boot_caps = match_boots(self.conn.caps,
|
||||
self.image.domain.boots)
|
||||
if self._boot_caps is None:
|
||||
raise RuntimeError(_("Could not find suitable boot "
|
||||
"descriptor for this host"))
|
||||
else:
|
||||
if (boot_index < 0 or
|
||||
(boot_index + 1) > len(image.domain.boots)):
|
||||
raise ValueError(_("boot_index out of range."))
|
||||
self._boot_caps = image.domain.boots[boot_index]
|
||||
|
||||
# Set up internal caps.guest object
|
||||
self._guest, self._domain = self.conn.caps.guest_lookup(
|
||||
os_type=self.boot_caps.type, arch=self.boot_caps.arch)
|
||||
|
||||
|
||||
# Custom ImageInstaller methods
|
||||
def get_caps_guest(self):
|
||||
return self._guest, self._domain
|
||||
|
||||
def get_image(self):
|
||||
return self._image
|
||||
image = property(get_image)
|
||||
|
||||
def get_boot_caps(self):
|
||||
return self._boot_caps
|
||||
boot_caps = property(get_boot_caps)
|
||||
|
||||
|
||||
# General Installer methods
|
||||
def _prepare(self, guest, meter, scratchdir):
|
||||
ignore = scratchdir
|
||||
ignore = meter
|
||||
|
||||
self._make_disks()
|
||||
|
||||
for f in ['pae', 'acpi', 'apic']:
|
||||
if self.boot_caps.features[f] & CapabilitiesParser.FEATURE_ON:
|
||||
setattr(guest.features, f, True)
|
||||
elif self.boot_caps.features[f] & CapabilitiesParser.FEATURE_OFF:
|
||||
setattr(guest.features, f, False)
|
||||
|
||||
guest.os.kernel = self.boot_caps.kernel
|
||||
guest.os.initrd = self.boot_caps.initrd
|
||||
guest.os.kernel_args = self.boot_caps.cmdline
|
||||
|
||||
# Private methods
|
||||
def _get_bootdev(self, isinstall, guest):
|
||||
return self.boot_caps.bootdev
|
||||
|
||||
def _make_disks(self):
|
||||
for drive in self.boot_caps.drives:
|
||||
path = self.image.abspath(drive.disk.file)
|
||||
size = None
|
||||
if drive.disk.size is not None:
|
||||
size = float(drive.disk.size) / 1024
|
||||
|
||||
# FIXME: This is awkward; the image should be able to express
|
||||
# whether the disk is expected to be there or not independently
|
||||
# of its classification, especially for user disks
|
||||
# FIXME: We ignore the target for the mapping in m.target
|
||||
if (drive.disk.use == Disk.USE_SYSTEM and
|
||||
not os.path.exists(path)):
|
||||
raise RuntimeError(_("System disk %s does not exist") % path)
|
||||
|
||||
device = VirtualDisk.DEVICE_DISK
|
||||
if drive.disk.format == Disk.FORMAT_ISO:
|
||||
device = VirtualDisk.DEVICE_CDROM
|
||||
|
||||
disk = VirtualDisk(self.conn)
|
||||
disk.path = path
|
||||
disk.device = device
|
||||
disk.target = drive.target
|
||||
|
||||
disk.set_create_storage(size=size, fmt=drive.disk.format)
|
||||
disk.validate()
|
||||
self.install_devices.append(disk)
|
||||
|
||||
|
||||
def match_boots(capabilities, boots):
|
||||
for b in boots:
|
||||
for g in capabilities.guests:
|
||||
if b.type == g.os_type and b.arch == g.arch:
|
||||
found = True
|
||||
for bf in b.features.names():
|
||||
if not b.features[bf] & g.features[bf]:
|
||||
found = False
|
||||
break
|
||||
if found:
|
||||
return b
|
||||
return None
|
Loading…
Reference in New Issue