commit 029bb3be9b51bb6c4d5dc3a627a4e9e44966b51c
Author: W. David Ashley <w.david.ashley(a)gmail.com>
Date: Fri Jul 3 09:56:00 2015 -0500
Domains Chapter
Provisioning and Starting Sections
- Converted to Python
- Added examples 9-14 (Python and XML)
- still more work to do on this section
en-US/Guest_Domains.xml | 557 +++++++++++++++--------------------
en-US/extras/Domains-Example-10.xml | 5 +
en-US/extras/Domains-Example-11.xml | 4 +
en-US/extras/Domains-Example-12.py | 25 ++
en-US/extras/Domains-Example-13.xml | 5 +
en-US/extras/Domains-Example-14.py | 25 ++
en-US/extras/Domains-Example-9.xml | 25 ++
7 files changed, 330 insertions(+), 316 deletions(-)
---
diff --git a/en-US/Guest_Domains.xml b/en-US/Guest_Domains.xml
index dc79b5e..cbf1ba9 100644
--- a/en-US/Guest_Domains.xml
+++ b/en-US/Guest_Domains.xml
@@ -317,361 +317,286 @@
</section>
- <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-config">
- <title>New guest provisioning techniques</title>
-
- <para>
- This section will first illustrate two configurations that
- allow for a provisioning approach that is comparable to those
- used for physical machines. It then outlines a third option
- which is specific to virtualized hardware, but has some
- interesting benefits. For the purposes of illustration, the
- examples that follow will use a XML configuration that sets
- up a KVM fully virtualized guest, with a single disk and
- network interface and a video card using VNC for display.
- </para>
-
- <programlisting>
- <![CDATA[
- <domain type='kvm'>
- <name>demo</name>
- <uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
- <memory>500000</memory>
- <vcpu>1</vcpu>
- .... the <os> block will vary per approach ...
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>destroy</on_crash>
- <devices>
- <emulator>/usr/bin/qemu-kvm</emulator>
- <disk type='file' device='disk'>
- <source file='/var/lib/libvirt/images/demo.img'/>
- <driver name='qemu' type='raw'/>
- <target dev='hda'/>
- </disk>
- <interface type='bridge'>
- <mac address='52:54:00:d8:65:c9'/>
- <source bridge='br0'/>
- </interface>
- <input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1'
listen='127.0.0.1'/>
- </devices>
- </domain>
- ]]>
- </programlisting>
- <important>
- <para>
- Be careful in the choice of initial memory allocation, since
- too low a value may cause mysterious crashes and installation
- failures. Some operating systems need as much as 600 MB of memory
- for initial installation, though this can often be reduced
- post-install.
- </para>
- </important>
-
- <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-ISO">
- <title>CDROM/ISO image provisioning</title>
+ <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-Provisioning_Techniques">
+ <title>New Guest Domain Provisioning Techniques</title>
<para>
- All full virtualization technologies have support for emulating
- a CDROM device in a guest domain, making this an obvious choice
- for provisioning new guest domains. It is, however, fairly rare
- to find a hypervisor which provides CDROM devices for paravirtualized
- guests.
+ This section will first illustrate two configurations that
+ allow for a provisioning approach that is comparable to those
+ used for physical machines. It then outlines a third option
+ which is specific to virtualized hardware, but has some
+ interesting benefits. For the purposes of illustration, the
+ examples that follow will use an XML configuration that sets
+ up a KVM fully virtualized guest, with a single disk and
+ network interface and a video card using VNC for display.
</para>
- <para>
- The first obvious change required to the XML configuration to
- support CDROM installation, is to add a CDROM device. A guest
- domains' CDROM device can be pointed to either a host CDROM
- device, or to a ISO image file. The next change is to determine
- what the BIOS boot order should be, with there being two
- possible options. If the hard disk is listed ahead of the
- CDROM device, then the CDROM media won't be booted unless
- the first boot sector on the hard disk is blank. If the
- CDROM device is listed ahead of the hard disk, then it will
- be necessary to alter the guest config after install to
- make it boot off the installed disk. While both can be made
- to work, the first option is easiest to implement.
- </para>
+ <programlisting language="XML"><xi:include
href="extras/Domains-Example-9.xml" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
+ <important>
+ <para>
+ Be careful in the choice of initial memory allocation, since
+ too low a value may cause mysterious crashes and installation
+ failures. Some operating systems need as much as 600 MB of memory
+ for initial installation, though this can often be reduced
+ post-install.
+ </para>
+ </important>
- <para>
- The guest configuration shown earlier would have the following
- XML chunk inserted:
- </para>
+ <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-ISO">
+ <title>CDROM/ISO image provisioning</title>
- <programlisting>
- <![CDATA[
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
- <boot dev='hd'/>
- <boot dev='cdrom'/>
- </os>
- ]]>
- </programlisting>
+ <para>
+ All full virtualization technologies have support for emulating
+ a CDROM device in a guest domain, making this an obvious choice
+ for provisioning new guest domains. It is, however, fairly rare
+ to find a hypervisor which provides CDROM devices for
paravirtualized
+ guests.
+ </para>
- <para>
- NB, this assumes the hard disk boot sector is blank initially,
- so that the first boot attempt falls through to the CD-ROM drive.
- It will also need a CD-ROM drive device added
- </para>
+ <para>
+ The first obvious change required to the XML configuration to
+ support CDROM installation, is to add a CDROM device. A guest
+ domains' CDROM device can be pointed to either a host CDROM
+ device, or to a ISO image file. The next change is to determine
+ what the BIOS boot order should be, with there being two
+ possible options. If the hard disk is listed ahead of the
+ CDROM device, then the CDROM media won't be booted unless
+ the first boot sector on the hard disk is blank. If the
+ CDROM device is listed ahead of the hard disk, then it will
+ be necessary to alter the guest config after install to
+ make it boot off the installed disk. While both can be made
+ to work, the first option is easiest to implement.
+ </para>
- <programlisting>
- <![CDATA[
- <disk type='file' device='cdrom'>
- <source file='/var/lib/libvirt/images/rhel5-x86_64-dvd.iso'/>
- <target dev='hdc' bus='ide'/>
- </disk>
- ]]>
- </programlisting>
+ <para>
+ The guest configuration shown earlier would have the following
+ XML chunk inserted:
+ </para>
- <para>
- With the configuration determined, it is now possible
- to provision the guest. This is an easy process, simply
- requiring a persistent guest to be defined, and then
- booted.
- </para>
+ <programlisting language="XML"><xi:include
href="extras/Domains-Example-10.xml" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
- <programlisting>
- <![CDATA[
- const char *xml = "<domain>....</domain>";
- virDomainPtr dom;
+ <para>
+ NB, this assumes the hard disk boot sector is blank initially,
+ so that the first boot attempt falls through to the CD-ROM drive.
+ It will also need a CD-ROM drive device added.
+ </para>
- dom = virDomainDefineXML(conn, xml);
- if (!dom) {
- fprintf(stderr, "Unable to define persistent guest configuration");
- return;
- }
+ <programlisting language="XML"><xi:include
href="extras/Domains-Example-11.xml" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
- if (virDomainCreate(dom) < 0) {
- fprintf(stderr, "Unable to boot guest configuration");
- }
- ]]>
- </programlisting>
+ <para>
+ With the configuration determined, it is now possible
+ to provision the guest. This is an easy process, simply
+ requiring a persistent guest to be defined, and then
+ booted.
+ </para>
- <para>
- If it was not possible to guarantee that the boot
- sector of the hard disk is blank, then provisioning
- would have been a two step process. First a transient
- guest would have been booted using CD-ROM drive as the
- primary boot device. Once that completed, then
- a persistent configuration for the guest would be
- defined to boot off the hard disk.
- </para>
+ <example>
+ <title>Defining and Booting a Persistent Guest
Domain</title>
+ <programlisting language="Python"><xi:include
href="extras/Domains-Example-12.py" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
+ </example>
- </section>
+ <para>
+ If it was not possible to guarantee that the boot
+ sector of the hard disk is blank, then provisioning
+ would have been a two step process. First a transient
+ guest would have been booted using CD-ROM drive as the
+ primary boot device. Once that completed, then
+ a persistent configuration for the guest would be
+ defined to boot off the hard disk.
+ </para>
- <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-PXE">
- <title>PXE boot provisioning</title>
+ </section>
- <para>
- Some newer full virtualization technologies provide a BIOS that
- is able to use the PXE boot protocol to boot of the network. If
- an environment already has a PXE boot provisioning server deployed,
- this is a desirable method to use for guest domains.
- </para>
+ <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-PXE">
+ <title>PXE Boot Provisioning</title>
- <para>
- PXE booting a guest obviously requires that the guest has a
- network device configured. The LAN that this network card is
- attached to, also needs a PXE / TFTP server available.
- The next change is to determine
- what the BIOS boot order should be, with there being two
- possible options. If the hard disk is listed ahead of the
- network device, then the network card won't PXE boot unless
- the first boot sector on the hard disk is blank. If the
- network device is listed ahead of the hard disk, then it will
- be necessary to alter the guest config after install to
- make it boot off the installed disk. While both can be made
- to work, the first option is easiest to implement.
- </para>
+ <para>
+ Some newer full virtualization technologies provide a BIOS that
+ is able to use the PXE boot protocol to boot off the network. If
+ an environment already has a PXE boot provisioning server deployed,
+ this is a desirable method to use for guest domains.
+ </para>
- <para>
- The guest configuration shown earlier would have the following
- XML chunk inserted:
- </para>
+ <para>
+ PXE booting a guest obviously requires that the guest has a
+ network device configured. The LAN that this network card is
+ attached to, also needs a PXE / TFTP server available.
+ The next change is to determine
+ what the BIOS boot order should be, with there being two
+ possible options. If the hard disk is listed ahead of the
+ network device, then the network card won't PXE boot unless
+ the first boot sector on the hard disk is blank. If the
+ network device is listed ahead of the hard disk, then it will
+ be necessary to alter the guest config after install to
+ make it boot off the installed disk. While both can be made
+ to work, the first option is easiest to implement.
+ </para>
- <programlisting>
- <![CDATA[
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
- <boot dev='hd'/>
- <boot dev='network'/>
- </os>
- ]]>
- </programlisting>
+ <para>
+ The guest configuration shown earlier would have the following
+ XML chunk inserted:
+ </para>
- <para>
- NB, this assumes the hard disk boot sector is blank initially,
- so that the first boot attempt falls through to the NIC.
- With the configuration determined, it is now possible
- to provision the guest. This is an easy process, simply
- requiring a persistent guest to be defined, and then
- booted.
- </para>
+ <programlisting language="XML"><xi:include
href="extras/Domains-Example-13.xml" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
- <programlisting>
- <![CDATA[
- const char *xml = "<domain>....</domain>";
- virDomainPtr dom;
+ <para>
+ NB, this assumes the hard disk boot sector is blank initially,
+ so that the first boot attempt falls through to the NIC.
+ With the configuration determined, it is now possible
+ to provision the guest. This is an easy process, simply
+ requiring a persistent guest to be defined, and then
+ booted.
+ </para>
- dom = virDomainDefineXML(conn, xml);
- if (!dom) {
- fprintf(stderr, "Unable to define persistent guest configuration");
- return;
- }
+ <example>
+ <title>PXE Boot Provisioning</title>
+ <programlisting language="Python"><xi:include
href="extras/Domains-Example-14.py" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
+ </example>
- if (virDomainCreate(dom) < 0) {
- fprintf(stderr, "Unable to boot guest configuration");
- }
- ]]>
- </programlisting>
+ <para>
+ If it was not possible to guarantee that the boot
+ sector of the hard disk is blank, then provisioning
+ would have been a two step process. First a transient
+ guest would have been booted using network as the
+ primary boot device. Once that completed, then
+ a persistent configuration for the guest would be
+ defined to boot off the hard disk.
+ </para>
+ </section>
- <para>
- If it was not possible to guarantee that the boot
- sector of the hard disk is blank, then provisioning
- would have been a two step process. First a transient
- guest would have been booted using network as the
- primary boot device. Once that completed, then
- a persistent configuration for the guest would be
- defined to boot off the hard disk.
- </para>
- </section>
+ <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-Kernel">
+ <title>Direct kernel boot provisioning</title>
- <section
id="libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Provisioning-Kernel">
- <title>Direct kernel boot provisioning</title>
+ <para>
+ Paravirtualization technologies emulate a fairly restrictive
+ set of hardware, often making it impossible to use the provisioning
+ options just outlined. For such scenarios it is often possible to
+ boot a new guest domain directly from an kernel and initrd image
+ stored on the host file system. This has one interesting advantage,
+ which is that it is possible to directly set kernel command line
+ boot arguments, making it very easy to do fully automated
+ installation. This advantage can be compelling enough that this
+ technique is used even for fully virtualized guest domains with
+ CD-ROM drive/PXE support.
+ </para>
- <para>
- Paravirtualization technologies emulate a fairly restrictive
- set of hardware, often making it impossible to use the provisioning
- options just outlined. For such scenarios it is often possible to
- boot a new guest domain directly from an kernel and initrd image
- stored on the host file system. This has one interesting advantage,
- which is that it is possible to directly set kernel command line
- boot arguments, making it very easy to do fully automated
- installation. This advantage can be compelling enough that this
- technique is used even for fully virtualized guest domains with
- CD-ROM drive/PXE support.
- </para>
+ <para>
+ The one complication with direct kernel booting is that provisioning
+ becomes a two step process. For the first step, it is necessary to
+ configure the guest XML configuration to point to a kernel/initrd.
+ </para>
- <para>
- The one complication with direct kernel booting is that provisioning
- becomes a two step process. For the first step, it is necessary to
- configure the guest XML configuration to point to a kernel/initrd.
- </para>
+ <programlisting>
+ <![CDATA[
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <kernel>/var/lib/libvirt/boot/f11-x86_64-vmlinuz</kernel>
+ <initrd>/var/lib/libvirt/boot/f11-x86_64-initrd.img</initrd>
+
<
cmdline>method=http://download.fedoraproject.org/pub/fedora/linux/rele...
console=ttyS0 console=tty</cmdline>
+ </os>
+ ]]>
+ </programlisting>
- <programlisting>
- <![CDATA[
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
- <kernel>/var/lib/libvirt/boot/f11-x86_64-vmlinuz</kernel>
- <initrd>/var/lib/libvirt/boot/f11-x86_64-initrd.img</initrd>
-
<
cmdline>method=http://download.fedoraproject.org/pub/fedora/linux/rele...
console=ttyS0 console=tty</cmdline>
- </os>
- ]]>
- </programlisting>
+ <para>
+ Notice how the kernel command line provides the URL of download
+ site containing the distro install tree matching the kernel/initrd.
+ This allows the installer to automatically download all its resources
+ without prompting the user for install URL. It could also be used to
+ provide a kickstart file for completely unattended installation.
+ Finally, this command line also tells the kernel to activate both
+ the first serial port and the VGA card as consoles, with the latter
+ being the default. Having kernel messages duplicated on the serial
+ port in this manner can be a useful debugging avenue. Of course
+ valid command line arguments vary according to the particular kernel
+ being booted. Consult the kernel vendor/distributor's
documentation
+ for valid options.
+ </para>
- <para>
- Notice how the kernel command line provides the URL of download
- site containing the distro install tree matching the kernel/initrd.
- This allows the installer to automatically download all its resources
- without prompting the user for install URL. It could also be used to
- provide a kickstart file for completely unattended installation.
- Finally, this command line also tells the kernel to activate both
- the first serial port and the VGA card as consoles, with the latter
- being the default. Having kernel messages duplicated on the serial
- port in this manner can be a useful debugging avenue. Of course
- valid command line arguments vary according to the particular kernel
- being booted. Consult the kernel vendor/distributor's documentation
- for valid options.
- </para>
+ <para>
+ The last XML configuration detail before starting the guest, is to
+ change the 'on_reboot' element action to be 'destroy'.
This ensures
+ that when the guest installer finishes and requests a reboot, the
+ guest is instead powered off. This allows the management application
+ to change the configuration to make it boot off, just installed, the
+ hard disk again. The provisioning process can be started now by
+ creating a transient guest with the first XML configuration
+ </para>
- <para>
- The last XML configuration detail before starting the guest, is to
- change the 'on_reboot' element action to be 'destroy'.
This ensures
- that when the guest installer finishes and requests a reboot, the
- guest is instead powered off. This allows the management application
- to change the configuration to make it boot off, just installed, the
- hard disk again. The provisioning process can be started now by
- creating a transient guest with the first XML configuration
- </para>
+ <programlisting>
+ <![CDATA[
+ const char *xml = "<domain>....</domain>";
+ virDomainPtr dom;
- <programlisting>
- <![CDATA[
- const char *xml = "<domain>....</domain>";
- virDomainPtr dom;
+ dom = virDomainCreateXML(conn, xml);
+ if (!dom) {
+ fprintf(stderr, "Unable to boot transient guest configuration");
+ return;
+ }
+ ]]>
+ </programlisting>
- dom = virDomainCreateXML(conn, xml);
- if (!dom) {
- fprintf(stderr, "Unable to boot transient guest configuration");
- return;
- }
- ]]>
- </programlisting>
+ <para>
+ Once this guest shuts down, the second phase of the provisioning
+ process can be started. For this phase, the 'OS' element will
+ have the kernel/initrd/cmdline elements removed, and replaced
+ by either a reference to a host side bootloader, or a BIOS
+ boot setup. The former is used for Xen paravirtualized guests,
+ while the latter is used for fully virtualized guests.
+ </para>
- <para>
- Once this guest shuts down, the second phase of the provisioning
- process can be started. For this phase, the 'OS' element will
- have the kernel/initrd/cmdline elements removed, and replaced
- by either a reference to a host side bootloader, or a BIOS
- boot setup. The former is used for Xen paravirtualized guests,
- while the latter is used for fully virtualized guests.
- </para>
+ <para>
+ The phase 2 configuration for a Xen paravirtualized guest
+ would thus look like:
+ </para>
- <para>
- The phase 2 configuration for a Xen paravirtualized guest
- would thus look like:
- </para>
+ <programlisting>
+ <![CDATA[
+ <bootloader>/usr/bin/pygrub</bootloader>
+ <os>
+ <type arch='x86_64' machine='pc'>xen</type>
+ </os>
+ ]]>
+ </programlisting>
- <programlisting>
- <![CDATA[
- <bootloader>/usr/bin/pygrub</bootloader>
- <os>
- <type arch='x86_64' machine='pc'>xen</type>
- </os>
- ]]>
- </programlisting>
+ <para>
+ while a fully-virtualized guest would use:
+ </para>
- <para>
- while a fully-virtualized guest would use:
- </para>
+ <programlisting>
+ <![CDATA[
+ <bootloader>/usr/bin/pygrub</bootloader>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ ]]>
+ </programlisting>
- <programlisting>
- <![CDATA[
- <bootloader>/usr/bin/pygrub</bootloader>
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
- <boot dev='hd'/>
- </os>
- ]]>
- </programlisting>
+ <para>
+ With the second phase configuration determined, the guest can
+ be recreated, this time using a persistent configuration
+ </para>
- <para>
- With the second phase configuration determined, the guest can
- be recreated, this time using a persistent configuration
- </para>
+ <programlisting>
+ <![CDATA[
+ const char *xml = "<domain>....</domain>";
+ virDomainPtr dom;
- <programlisting>
- <![CDATA[
- const char *xml = "<domain>....</domain>";
- virDomainPtr dom;
-
- dom = virDomainCreateXML(conn, xml);
- if (!dom) {
- fprintf(stderr, "Unable to define persistent guest configuration\n");
- return;
- }
-
- if (virDomainCreate(dom) < 0) {
- fprintf(stderr, "Unable to boot persistent guest\n");
- return;
- }
-
- fprintf(stderr, "Guest provisoning complete, OS is running\n");
- ]]>
- </programlisting>
- </section>
+ dom = virDomainCreateXML(conn, xml);
+ if (!dom) {
+ fprintf(stderr, "Unable to define persistent guest
configuration\n");
+ return;
+ }
+
+ if (virDomainCreate(dom) < 0) {
+ fprintf(stderr, "Unable to boot persistent guest\n");
+ return;
+ }
+
+ fprintf(stderr, "Guest provisoning complete, OS is running\n");
+ ]]>
+ </programlisting>
+ </section>
</section>
</section>
diff --git a/en-US/extras/Domains-Example-10.xml b/en-US/extras/Domains-Example-10.xml
new file mode 100644
index 0000000..b3a20da
--- /dev/null
+++ b/en-US/extras/Domains-Example-10.xml
@@ -0,0 +1,5 @@
+<os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ <boot dev='cdrom'/>
+</os>
diff --git a/en-US/extras/Domains-Example-11.xml b/en-US/extras/Domains-Example-11.xml
new file mode 100644
index 0000000..bd0f139
--- /dev/null
+++ b/en-US/extras/Domains-Example-11.xml
@@ -0,0 +1,4 @@
+<disk type='file' device='cdrom'>
+ <source file='/var/lib/libvirt/images/rhel5-x86_64-dvd.iso'/>
+ <target dev='hdc' bus='ide'/>
+</disk>
diff --git a/en-US/extras/Domains-Example-12.py b/en-US/extras/Domains-Example-12.py
new file mode 100644
index 0000000..9e9ce00
--- /dev/null
+++ b/en-US/extras/Domains-Example-12.py
@@ -0,0 +1,25 @@
+# Example-12.py
+from __future__ import print_function
+import sys
+import libvirt
+
+xmlconfig = '<domain>........</domain>'
+
+conn = libvirt.open('qemu:///system')
+if conn == None:
+ print('Failed to open connection to qemu:///system', file=sys.stderr)
+ exit(1)
+
+dom = conn.defineXML(xmlconfig, 0)
+if dom == None:
+ print('Failed to define a domain from an XML definition.', file=sys.stderr)
+ exit(1)
+
+if dom.create(dom) < 0:
+ print('Can not boot guest domain.', file=sys.stderr)
+ exit(1)
+
+print('Guest '+dom.name()+' has booted', file=sys.stderr)
+
+conn.close()
+exit(0)
diff --git a/en-US/extras/Domains-Example-13.xml b/en-US/extras/Domains-Example-13.xml
new file mode 100644
index 0000000..1dd3b73
--- /dev/null
+++ b/en-US/extras/Domains-Example-13.xml
@@ -0,0 +1,5 @@
+<os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ <boot dev='network'/>
+</os>
diff --git a/en-US/extras/Domains-Example-14.py b/en-US/extras/Domains-Example-14.py
new file mode 100644
index 0000000..a9a9579
--- /dev/null
+++ b/en-US/extras/Domains-Example-14.py
@@ -0,0 +1,25 @@
+# Example-14.py
+from __future__ import print_function
+import sys
+import libvirt
+
+xmlconfig = '<domain>........</domain>'
+
+conn = libvirt.open('qemu:///system')
+if conn == None:
+ print('Failed to open connection to qemu:///system', file=sys.stderr)
+ exit(1)
+
+dom = conn.defineXML(xmlconfig, 0)
+if dom == None:
+ print('Failed to define a domain from an XML definition.', file=sys.stderr)
+ exit(1)
+
+if dom.create(dom) < 0:
+ print('Can not boot guest domain.', file=sys.stderr)
+ exit(1)
+
+print('Guest '+dom.name()+' has booted', file=sys.stderr)
+
+conn.close()
+exit(0)
diff --git a/en-US/extras/Domains-Example-9.xml b/en-US/extras/Domains-Example-9.xml
new file mode 100644
index 0000000..7191ae4
--- /dev/null
+++ b/en-US/extras/Domains-Example-9.xml
@@ -0,0 +1,25 @@
+<domain type='kvm'>
+ <name>demo</name>
+ <uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory>500000</memory>
+ <vcpu>1</vcpu>
+ .... the <os> block will vary per approach ...
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-kvm</emulator>
+ <disk type='file' device='disk'>
+ <source file='/var/lib/libvirt/images/demo.img'/>
+ <driver name='qemu' type='raw'/>
+ <target dev='hda'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='52:54:00:d8:65:c9'/>
+ <source bridge='br0'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' listen='127.0.0.1'/>
+ </devices>
+</domain>