cobbler/koan-rhel7-virtinst.patch

1167 lines
41 KiB
Diff

diff -rupN cobbler-2.0.7-old/koan/app.py cobbler-2.0.7-new/koan/app.py
--- cobbler-2.0.7-old/koan/app.py 2013-11-21 14:02:54.303559201 -0500
+++ cobbler-2.0.7-new/koan/app.py 2013-11-22 17:54:23.691918000 -0500
@@ -28,6 +28,7 @@ import random
import os
import traceback
import tempfile
+import shlex
ANCIENT_PYTHON = 0
try:
@@ -536,10 +537,13 @@ class Koan:
if not os.path.exists("/usr/bin/qemu-img"):
raise InfoException("qemu package needs to be installed")
# is libvirt new enough?
- cmd = sub_process.Popen("rpm -q python-virtinst", stdout=sub_process.PIPE, shell=True)
- version_str = cmd.communicate()[0]
- if version_str.find("virtinst-0.1") != -1 or version_str.find("virtinst-0.0") != -1:
- raise InfoException("need python-virtinst >= 0.2 to do installs for qemu/kvm")
+ # Note: in some newer distros (like Fedora 19) the python-virtinst package has been
+ # subsumed into virt-install. If we don't have one check to see if we have the other.
+ rc, version_str = utils.subprocess_get_response(shlex.split('rpm -q virt-install'), True)
+ if rc != 0:
+ rc, version_str = utils.subprocess_get_response(shlex.split('rpm -q python-virtinst'), True)
+ if rc != 0 or version_str.find("virtinst-0.1") != -1 or version_str.find("virtinst-0.0") != -1:
+ raise InfoException("need python-virtinst >= 0.2 or virt-install package to do installs for qemu/kvm (depending on your OS)")
# for vmware
if self.virt_type == "vmware" or self.virt_type == "vmwarew":
@@ -1106,7 +1110,10 @@ class Koan:
Invoke virt guest-install (or tweaked copy thereof)
"""
pd = profile_data
- self.load_virt_modules()
+ # importing can't throw exceptions any more, don't put it in a sub-method
+ import xencreate
+ import qcreate
+ import imagecreate
arch = self.safe_load(pd,'arch','x86')
kextra = self.calc_kernel_args(pd)
@@ -1180,17 +1187,6 @@ class Koan:
#---------------------------------------------------
- def load_virt_modules(self):
- try:
- import xencreate
- import qcreate
- import imagecreate
- except:
- traceback.print_exc()
- raise InfoException("no virtualization support available, install python-virtinst?")
-
- #---------------------------------------------------
-
def virt_choose(self, pd):
fullvirt = False
can_poll = None
@@ -1438,6 +1434,10 @@ class Koan:
return "%s/%s-disk%s" % (location, name, offset)
elif not os.path.exists(location) and os.path.isdir(os.path.dirname(location)):
return location
+ elif not os.path.exists(os.path.dirname(location)):
+ print "- creating: %s" % os.path.dirname(location)
+ os.makedirs(os.path.dirname(location))
+ return location
else:
raise InfoException, "invalid location: %s" % location
elif location.startswith("/dev/"):
diff -rupN cobbler-2.0.7-old/koan/imagecreate.py cobbler-2.0.7-new/koan/imagecreate.py
--- cobbler-2.0.7-old/koan/imagecreate.py 2013-11-21 14:02:54.303559201 -0500
+++ cobbler-2.0.7-new/koan/imagecreate.py 2013-11-21 14:08:24.214897902 -0500
@@ -1,7 +1,7 @@
"""
Virtualization installation functions for image based deployment
-Copyright 2008 Red Hat, Inc.
+Copyright 2008 Red Hat, Inc and Others.
Bryan Kearney <bkearney@redhat.com>
Original version based on virt-image
@@ -23,169 +23,9 @@ Foundation, Inc., 51 Franklin Street, Fi
02110-1301 USA
"""
-import os, sys, time, stat
-import shutil
-import random
-import exceptions
-import errno
-import virtinst
-try:
- from virtinst import ImageParser, Guest, CapabilitiesParser, VirtualNetworkInterface
-except:
- # if this fails, this is ok, the user just won't be able to use image objects...
- # keeping this dynamic allows this to work on older EL.
- pass
-import libvirt
-
-import app as koan
-
-#FIXME this was copied
-def random_mac():
- """
- from xend/server/netif.py
- Generate a random MAC address.
- Uses OUI 00-16-3E, allocated to
- Xensource, Inc. Last 3 fields are random.
- return: MAC address string
- """
- mac = [ 0x00, 0x16, 0x3e,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff) ]
- return ':'.join(map(lambda x: "%02x" % x, mac))
-
-
-def transform_arch(arch):
- if arch == "i386":
- return "i686"
- else:
- return arch
-
-def copy_image(original_file, new_location):
- shutil.copyfile(original_file, new_location)
- return new_location
-
-
-def process_disk(image, boot, file, location, target):
- image_location = copy_image(file, location)
- # Create the disk
- disk = ImageParser.Disk()
- disk.format = "raw"
- disk.file = image_location
- disk.use = "user"
- disk.id = image_location
- image.storage[disk.id] = disk
-
- #Create the drive
- drive = ImageParser.Drive()
- drive.id = image_location
- drive.target = target
- drive.disk = disk
- boot.disks.append(drive)
- #dev api
- #boot.drives.append(drive)
-
-
-def process_networks(domain, guest, profile_data, bridge):
- # Create a bridge or default network for every requested nic. If there are more
- # bridges then nics discard the last one.
- domain.interface = int(profile_data["network_count"])
- bridges = []
- #use the provided bridge first
- guest_bridge = bridge
- if guest_bridge is None:
- guest_bridge = profile_data["virt_bridge"]
-
- # Look for commas
- if (guest_bridge is not None) and (len(guest_bridge.strip()) > 0):
- if guest_bridge.find(",") == -1:
- bridges.append(guest_bridge)
- else:
- bridges == guest_bridge.split(",")
-
- for cnt in range(0,domain.interface):
- if cnt < len(bridges):
- nic = VirtualNetworkInterface(random_mac(), type="bridge", bridge = bridges[cnt])
- #dev api
- #nic = VirtualNetworkInterface(random_mac(), type="bridge", bridge = bridge, conn=guest.conn)
- else:
- default_network = virtinst.util.default_network()
- #dev api
- #default_network = virtinst.util.default_network(guest.conn)
- nic = VirtualNetworkInterface(random_mac(), type=default_network[0], network=default_network[1])
- guest.nics.append(nic)
-
-def start_install(name=None,
- ram=None,
- disks=None,
- uuid=None,
- extra=None,
- vcpus=None,
- profile_data=None,
- arch=None,
- no_gfx=False,
- fullvirt=False,
- bridge=None,
- virt_type=None,
- virt_auto_boot=None):
-
- #FIXME how to do a non-default connection
- #Can we drive off of virt-type?
- connection = None
-
- if (virt_type is None ) or (virt_type == "auto"):
- connection = virtinst.util.default_connection()
- elif virt_type.lower()[0:3] == "xen":
- connection = "xen"
- else:
- connection = "qemu:///system"
-
- connection = libvirt.open(connection)
- capabilities = virtinst.CapabilitiesParser.parse(connection.getCapabilities())
- image_arch = transform_arch(arch)
-
- image = ImageParser.Image()
- #dev api
- #image = ImageParser.Image(filename="") #FIXME, ImageParser should take in None
- image.name = name
-
- domain = ImageParser.Domain()
- domain.vcpu = vcpus
- domain.memory = ram
- image.domain = domain
-
- boot = ImageParser.Boot()
- boot.type = "hvm" #FIXME HARDCODED
- boot.loader = "hd" #FIXME HARDCODED
- boot.arch = image_arch
- domain.boots.append(boot)
-
- #FIXME Several issues. Single Disk, type is hardcoded
- #And there is no way to provision with access to "file"
- process_disk(image, boot, profile_data["file"], disks[0][0], "hda")
-
- #FIXME boot_index??
- installer = virtinst.ImageInstaller(boot_index = 0, image=image, capabilities=capabilities)
- guest = virtinst.FullVirtGuest(connection = connection, installer=installer, arch=image_arch)
-
- extra = extra.replace("&","&amp;")
-
- guest.extraargs = extra
- guest.set_name(name)
- guest.set_memory(ram)
- guest.set_vcpus(vcpus)
-
- if not no_gfx:
- guest.set_graphics("vnc")
- else:
- guest.set_graphics(False)
-
- if uuid is not None:
- guest.set_uuid(uuid)
-
- process_networks(domain, guest, profile_data, bridge)
-
- guest.start_install()
-
- return "use virt-manager or reconnect with virsh console %s" % name
-
+import utils
+import virtinstall
+
+def start_install(*args, **kwargs):
+ cmd = virtinstall.build_commandline("import", *args, **kwargs)
+ utils.subprocess_call(cmd)
diff -rupN cobbler-2.0.7-old/koan/qcreate.py cobbler-2.0.7-new/koan/qcreate.py
--- cobbler-2.0.7-old/koan/qcreate.py 2013-11-21 14:02:54.304559209 -0500
+++ cobbler-2.0.7-new/koan/qcreate.py 2013-12-05 18:49:06.355883703 -0500
@@ -1,8 +1,8 @@
"""
-Virtualization installation functions.
+Virtualization installation functions.
-Copyright 2007-2008 Red Hat, Inc.
-Michael DeHaan <mdehaan@redhat.com>
+Copyright 2007-2008 Red Hat, Inc and Others.
+Michael DeHaan <michael.dehaan AT gmail>
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
@@ -20,192 +20,32 @@ Foundation, Inc., 51 Franklin Street, Fi
02110-1301 USA
module for creating fullvirt guests via KVM/kqemu/qemu
-requires python-virtinst-0.200.
+requires python-virtinst-0.200 (or virt-install in later distros).
"""
-import os, sys, time, stat
-import tempfile
-import random
-from optparse import OptionParser
-import exceptions
-import errno
-import re
-import tempfile
-import shutil
-import virtinst
-import app as koan
-try:
- import subprocess
-except:
- import sub_process as subprocess
import utils
+import virtinstall
+from xml.dom.minidom import parseString
-def random_mac():
- """
- from xend/server/netif.py
- Generate a random MAC address.
- Uses OUI 00-16-3E, allocated to
- Xensource, Inc. Last 3 fields are random.
- return: MAC address string
- """
- mac = [ 0x00, 0x16, 0x3e,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff) ]
- return ':'.join(map(lambda x: "%02x" % x, mac))
-
-
-def start_install(name=None,
- ram=None,
- disks=None,
- mac=None,
- uuid=None,
- extra=None,
- vcpus=None,
- profile_data=None,
- arch=None,
- no_gfx=False,
- fullvirt=True,
- bridge=None,
- virt_type=None,
- virt_auto_boot=False):
-
- vtype = "qemu"
- if virtinst.util.is_kvm_capable():
- vtype = "kvm"
- arch = None # let virtinst.FullVirtGuest() default to the host arch
- elif virtinst.util.is_kqemu_capable():
- vtype = "kqemu"
- print "- using qemu hypervisor, type=%s" % vtype
-
- if arch is not None and arch.lower() in ["x86","i386"]:
- arch = "i686"
-
- guest = virtinst.FullVirtGuest(hypervisorURI="qemu:///system",type=vtype, arch=arch)
-
- if not profile_data.has_key("file"):
- # images don't need to source this
- if not profile_data.has_key("install_tree"):
- raise koan.InfoException("Cannot find install source in kickstart file, aborting.")
-
-
- if not profile_data["install_tree"].endswith("/"):
- profile_data["install_tree"] = profile_data["install_tree"] + "/"
-
- # virt manager doesn't like nfs:// and just wants nfs:
- # (which cobbler should fix anyway)
- profile_data["install_tree"] = profile_data["install_tree"].replace("nfs://","nfs:")
-
- if profile_data.has_key("file"):
- # this is an image based installation
- input_path = profile_data["file"]
- print "- using image location %s" % input_path
- if input_path.find(":") == -1:
- # this is not an NFS path
- guest.cdrom = input_path
- else:
- (tempdir, filename) = utils.nfsmount(input_path)
- guest.cdrom = os.path.join(tempdir, filename)
-
- kickstart = profile_data.get("kickstart","")
- if kickstart != "":
- # we have a (windows?) answer file we have to provide
- # to the ISO.
- print "I want to make a floppy for %s" % kickstart
- floppy_path = utils.make_floppy(kickstart)
- guest.disks.append(virtinst.VirtualDisk(device=virtinst.VirtualDisk.DEVICE_FLOPPY, path=floppy_path))
-
-
- else:
- guest.location = profile_data["install_tree"]
-
- extra = extra.replace("&","&amp;")
- guest.extraargs = extra
-
- if profile_data.has_key("breed"):
- breed = profile_data["breed"]
- if breed != "other" and breed != "":
- if breed in [ "debian", "suse", "redhat" ]:
- guest.set_os_type("linux")
- elif breed in [ "windows" ]:
- guest.set_os_type("windows")
- else:
- guest.set_os_type("unix")
- if profile_data.has_key("os_version"):
- # FIXME: when os_version is not defined and it's linux, do we use generic24/generic26 ?
- version = profile_data["os_version"]
- if version != "other" and version != "":
- try:
- guest.set_os_variant(version)
- except:
- print "- virtinst library does not understand variant %s, treating as generic" % version
- pass
-
- guest.set_name(name)
- guest.set_memory(ram)
- guest.set_vcpus(vcpus)
- # for KVM, we actually can't disable this, since it's the only
- # console it has other than SDL
- guest.set_graphics("vnc")
-
- if uuid is not None:
- guest.set_uuid(uuid)
-
- for d in disks:
- print "- adding disk: %s of size %s" % (d[0], d[1])
- if d[1] != 0 or d[0].startswith("/dev"):
- guest.disks.append(virtinst.VirtualDisk(d[0], size=d[1]))
- else:
- raise koan.InfoException("this virtualization type does not work without a disk image, set virt-size in Cobbler to non-zero")
-
- if profile_data.has_key("interfaces"):
-
- counter = 0
- interfaces = profile_data["interfaces"].keys()
- interfaces.sort()
- vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+")
- for iname in interfaces:
- intf = profile_data["interfaces"][iname]
-
- if intf["bonding"] == "master" or vlanpattern.match(iname) or iname.find(":") != -1:
- continue
-
- mac = intf["mac_address"]
- if mac == "":
- mac = random_mac()
-
- if bridge is None:
- profile_bridge = profile_data["virt_bridge"]
-
- intf_bridge = intf["virt_bridge"]
- if intf_bridge == "":
- if profile_bridge == "":
- raise koan.InfoException("virt-bridge setting is not defined in cobbler")
- intf_bridge = profile_bridge
- else:
- if bridge.find(",") == -1:
- intf_bridge = bridge
- else:
- bridges = bridge.split(",")
- intf_bridge = bridges[counter]
- nic_obj = virtinst.VirtualNetworkInterface(macaddr=mac, bridge=intf_bridge)
- guest.nics.append(nic_obj)
- counter = counter + 1
-
- else:
-
- if bridge is not None:
- profile_bridge = bridge
- else:
- profile_bridge = profile_data["virt_bridge"]
-
- if profile_bridge == "":
- raise koan.InfoException("virt-bridge setting is not defined in cobbler")
-
- nic_obj = virtinst.VirtualNetworkInterface(macaddr=random_mac(), bridge=profile_bridge)
- guest.nics.append(nic_obj)
-
- guest.start_install()
-
- return "use virt-manager and connect to qemu to manage guest: %s" % name
-
+def start_install(*args, **kwargs):
+ # See http://post-office.corp.redhat.com/archives/satellite-dept-list/2013-December/msg00039.html for discussion on this hack.
+ if 'arch' in kwargs.keys():
+ kwargs['arch'] = None # use host arch for kvm acceleration
+
+ # Use kvm acceleration if available
+ try:
+ import libvirt
+ except:
+ raise koan.InfoException("package libvirt is required for installing virtual guests")
+ conn = libvirt.openReadOnly(None)
+ # See http://libvirt.org/formatcaps.html
+ capabilities = parseString(conn.getCapabilities())
+ for domain in capabilities.getElementsByTagName("domain"):
+ attributes = dict(domain.attributes.items())
+ if 'type' in attributes.keys() and attributes['type'] == 'kvm':
+ kwargs['virt_type'] = 'kvm'
+ break
+
+ virtinstall.create_image_file(*args, **kwargs)
+ cmd = virtinstall.build_commandline("qemu:///system", *args, **kwargs)
+ utils.subprocess_call(cmd)
diff -rupN cobbler-2.0.7-old/koan/utils.py cobbler-2.0.7-new/koan/utils.py
--- cobbler-2.0.7-old/koan/utils.py 2013-11-21 14:02:54.303559201 -0500
+++ cobbler-2.0.7-new/koan/utils.py 2013-12-03 16:14:43.732007939 -0500
@@ -178,6 +178,27 @@ def subprocess_call(cmd,ignore_rc=0):
raise InfoException, "command failed (%s)" % rc
return rc
+def subprocess_get_response(cmd, ignore_rc=False):
+ """
+ Wrapper around subprocess.check_output(...)
+ """
+ print "- %s" % cmd
+ rc = 0
+ result = ""
+ if not ANCIENT_PYTHON:
+ try:
+ result = sub_process.check_output(cmd).strip()
+ except sub_process.CalledProcessError, e:
+ rc = e.returncode
+ result = e.output
+ else:
+ cmd = string.join(cmd, " ")
+ print "cmdstr=(%s)" % cmd
+ rc = os.system(cmd)
+ if not ignore_rc and rc != 0:
+ raise InfoException, "command failed (%s)" % rc
+ return rc, result
+
def input_string_or_hash(options,delim=None,allow_multiples=True):
"""
Older cobbler files stored configurations in a flat way, such that all values for strings.
@@ -267,7 +288,7 @@ def nfsmount(input_path):
shutil.rmtree(tempdir, ignore_errors=True)
raise koan.InfoException("nfs mount failed: %s" % dirpath)
# NOTE: option for a blocking install might be nice, so we could do this
- # automatically, if supported by python-virtinst
+ # automatically, if supported by virt-install
print "after install completes, you may unmount and delete %s" % tempdir
return (tempdir, filename)
@@ -516,7 +537,7 @@ def make_floppy(kickstart):
if not rc == 0:
raise InfoException("umount failed")
- # return the path to the completed disk image to pass to virtinst
+ # return the path to the completed disk image to pass to virt-install
return floppy_path
diff -rupN cobbler-2.0.7-old/koan/virtinstall.py cobbler-2.0.7-new/koan/virtinstall.py
--- cobbler-2.0.7-old/koan/virtinstall.py 1969-12-31 19:00:00.000000000 -0500
+++ cobbler-2.0.7-new/koan/virtinstall.py 2013-12-05 17:06:04.469953236 -0500
@@ -0,0 +1,413 @@
+"""
+Virtualization installation functions.
+Currently somewhat Xen/paravirt specific, will evolve later.
+
+Copyright 2006-2008 Red Hat, Inc.
+Michael DeHaan <mdehaan@redhat.com>
+
+Original version based on virtguest-install
+Jeremy Katz <katzj@redhat.com>
+Option handling added by Andrew Puch <apuch@redhat.com>
+Simplified for use as library by koan, Michael DeHaan <mdehaan@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 os
+import re
+import shlex
+
+import app as koan
+import utils
+
+# The virtinst module will no longer be availabe to import in some
+# distros. We need to get all the info we need from the virt-install
+# command line tool. This should work on both old and new variants,
+# as the virt-install command line tool has always been provided by
+# python-virtinst (and now the new virt-install rpm).
+rc, response = utils.subprocess_get_response(
+ shlex.split('virt-install --version'), True)
+if rc == 0:
+ virtinst_version = response
+else:
+ virtinst_version = None
+
+# This one's trickier. We need a list of supported os varients, but
+# the man page explicitly says not to parse the result of this command.
+# But we need it, and there's no other way to get it. I spoke with the
+# virt-install maintainers and they said the point of that message
+# is that you can't absolutely depend on the output not changing, but
+# at the moment it's the only option for us. Long term plans are for
+# virt-install to switch to libosinfo for OS metadata tracking, which
+# provides a library and tools for querying valid OS values. Until
+# that's available and pervasive the best we can do is to use the
+# module if it's availabe and if not parse the command output.
+supported_variants = set()
+try:
+ from virtinst import osdict
+ for ostype in osdict.OS_TYPES.keys():
+ for variant in osdict.OS_TYPES[ostype]["variants"].keys():
+ supported_variants.add(variant)
+except:
+ try:
+ rc, response = utils.subprocess_get_response(
+ shlex.split('virt-install --os-variant list'))
+ variants = response.split('\n')
+ for variant in variants:
+ supported_variants.add(variant.split()[0])
+ except:
+ pass # No problem, we'll just use generic
+
+def _sanitize_disks(disks):
+ ret = []
+ for d in disks:
+ driver_type = None
+ if len(d) > 2:
+ driver_type = d[2]
+
+ if d[1] != 0 or d[0].startswith("/dev"):
+ ret.append((d[0], d[1], driver_type))
+ else:
+ raise koan.InfoException("this virtualization type does not work without a disk image, set virt-size in Cobbler to non-zero")
+
+ return ret
+
+def _sanitize_nics(nics, bridge, profile_bridge, network_count):
+ ret = []
+
+ if network_count is not None and not nics:
+ # Fill in some stub nics so we can take advantage of the loop logic
+ nics = {}
+ for i in range(int(network_count)):
+ nics["foo%s" % i] = {
+ "interface_type" : "na",
+ "mac_address": None,
+ "virt_bridge": None,
+ }
+
+ if not nics:
+ return ret
+
+ interfaces = nics.keys()
+ interfaces.sort()
+ counter = -1
+ vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+")
+
+ for iname in interfaces:
+ counter = counter + 1
+ intf = nics[iname]
+
+ if (intf["bonding"] == "master" or vlanpattern.match(iname) or iname.find(":") != -1):
+ continue
+
+ mac = intf["mac_address"]
+
+ if not bridge:
+ intf_bridge = intf["virt_bridge"]
+ if intf_bridge == "":
+ if profile_bridge == "":
+ raise koan.InfoException("virt-bridge setting is not defined in cobbler")
+ intf_bridge = profile_bridge
+
+ else:
+ if bridge.find(",") == -1:
+ intf_bridge = bridge
+ else:
+ bridges = bridge.split(",")
+ intf_bridge = bridges[counter]
+
+ ret.append((intf_bridge, mac))
+
+ return ret
+
+def create_image_file(disks=None, **kwargs):
+ disks = _sanitize_disks(disks)
+ for path, size, driver_type in disks:
+ if driver_type is None:
+ continue
+ if os.path.isdir(path) or os.path.exists(path):
+ continue
+ if str(size) == "0":
+ continue
+ utils.create_qemu_image_file(path, size, driver_type)
+
+def build_commandline(uri,
+ name=None,
+ ram=None,
+ disks=None,
+ uuid=None,
+ extra=None,
+ vcpus=None,
+ profile_data=None,
+ arch=None,
+ no_gfx=False,
+ fullvirt=False,
+ bridge=None,
+ virt_type=None,
+ virt_auto_boot=False,
+ virt_pxe_boot=False,
+ qemu_driver_type=None,
+ qemu_net_type=None,
+ qemu_machine_type=None,
+ wait=0,
+ noreboot=False,
+ osimport=False):
+
+ # Set flags for CLI arguments based on the virtinst_version
+ # tuple above. Older versions of python-virtinst don't have
+ # a version easily accessible, so it will be None and we can
+ # easily disable features based on that (RHEL5 and older usually)
+
+ disable_autostart = False
+ disable_virt_type = False
+ disable_boot_opt = False
+ disable_driver_type = False
+ disable_net_model = False
+ disable_machine_type = False
+ oldstyle_macs = False
+ oldstyle_accelerate = False
+
+ if not virtinst_version:
+ print ("- warning: old virt-install detected, a lot of features will be disabled")
+ disable_autostart = True
+ disable_boot_opt = True
+ disable_virt_type = True
+ disable_driver_type = True
+ disable_net_model = True
+ disable_machine_type = True
+ oldstyle_macs = True
+ oldstyle_accelerate = True
+
+ import_exists = False # avoid duplicating --import parameter
+ disable_extra = False # disable --extra-args on --import
+ if osimport:
+ disable_extra = True
+
+ is_import = uri.startswith("import")
+ if is_import:
+ # We use the special value 'import' for imagecreate.py. Since
+ # it is connection agnostic, just let virt-install choose the
+ # best hypervisor.
+ uri = ""
+ fullvirt = None
+
+ is_xen = uri.startswith("xen")
+ is_qemu = uri.startswith("qemu")
+ if is_qemu:
+ if virt_type != "kvm":
+ fullvirt = True
+ else:
+ fullvirt = None
+
+ floppy = None
+ cdrom = None
+ location = None
+ importpath = None
+
+ if is_import:
+ importpath = profile_data.get("file")
+ if not importpath:
+ raise koan.InfoException("Profile 'file' required for image "
+ "install")
+
+ elif profile_data.has_key("file"):
+ if is_xen:
+ raise koan.InfoException("Xen does not work with --image yet")
+
+ # this is an image based installation
+ input_path = profile_data["file"]
+ print "- using image location %s" % input_path
+ if input_path.find(":") == -1:
+ # this is not an NFS path
+ cdrom = input_path
+ else:
+ (tempdir, filename) = utils.nfsmount(input_path)
+ cdrom = os.path.join(tempdir, filename)
+
+ kickstart = profile_data.get("kickstart","")
+ if kickstart != "":
+ # we have a (windows?) answer file we have to provide
+ # to the ISO.
+ print "I want to make a floppy for %s" % kickstart
+ floppy = utils.make_floppy(kickstart)
+ elif is_qemu or is_xen:
+ # images don't need to source this
+ if not profile_data.has_key("install_tree"):
+ raise koan.InfoException("Cannot find install source in kickstart file, aborting.")
+
+ if not profile_data["install_tree"].endswith("/"):
+ profile_data["install_tree"] = profile_data["install_tree"] + "/"
+
+ location = profile_data["install_tree"]
+
+
+ disks = _sanitize_disks(disks)
+ nics = _sanitize_nics(profile_data.get("interfaces"),
+ bridge,
+ profile_data.get("virt_bridge"),
+ profile_data.get("network_count"))
+ if not nics:
+ # for --profile you get one NIC, go define a system if you want more.
+ # FIXME: can mac still be sent on command line in this case?
+
+ if bridge is None:
+ bridge = profile_data["virt_bridge"]
+
+ if bridge == "":
+ raise koan.InfoException("virt-bridge setting is not defined in cobbler")
+ nics = [(bridge, None)]
+
+
+ kernel = profile_data.get("kernel_local")
+ initrd = profile_data.get("initrd_local")
+ breed = profile_data.get("breed")
+ os_version = profile_data.get("os_version")
+ if os_version and breed == "ubuntu":
+ os_version = "ubuntu%s" % os_version
+ if os_version and breed == "debian":
+ os_version = "debian%s" % os_version
+
+ net_model = None
+ disk_bus = None
+ machine_type = None
+
+ if is_qemu:
+ net_model = qemu_net_type
+ disk_bus = qemu_driver_type
+ machine_type = qemu_machine_type
+
+ if machine_type is None:
+ machine_type = "pc"
+
+ cmd = "virt-install "
+ if uri:
+ cmd += "--connect %s " % uri
+
+ cmd += "--name %s " % name
+ cmd += "--ram %s " % ram
+ cmd += "--vcpus %s " % vcpus
+
+ if uuid:
+ cmd += "--uuid %s " % uuid
+
+ if virt_auto_boot and not disable_autostart:
+ cmd += "--autostart "
+
+ if no_gfx:
+ cmd += "--nographics "
+ else:
+ cmd += "--vnc "
+
+ if is_qemu and virt_type:
+ if not disable_virt_type:
+ cmd += "--virt-type %s " % virt_type
+
+ if is_qemu and machine_type and not disable_machine_type:
+ cmd += "--machine %s " % machine_type
+
+ if fullvirt or is_qemu or is_import:
+ if fullvirt is not None:
+ cmd += "--hvm "
+ elif oldstyle_accelerate:
+ cmd += "--accelerate "
+
+ if is_qemu and extra and not(virt_pxe_boot) and not(disable_extra):
+ cmd += ("--extra-args=\"%s\" " % (extra))
+
+ if virt_pxe_boot or is_xen:
+ cmd += "--pxe "
+ elif cdrom:
+ cmd += "--cdrom %s " % cdrom
+ elif location:
+ cmd += "--location %s " % location
+ elif importpath:
+ cmd += "--import "
+ import_exists = True
+
+ if arch:
+ cmd += "--arch %s " % arch
+ else:
+ cmd += "--paravirt "
+ if not disable_boot_opt:
+ cmd += ("--boot kernel=%s,initrd=%s,kernel_args=\"%s\" " %
+ (kernel, initrd, extra))
+ else:
+ if location:
+ cmd += "--location %s " % location
+ if extra:
+ cmd += "--extra-args=\"%s\" " % extra
+
+ if breed and breed != "other":
+ if os_version and os_version != "other":
+ if breed == "suse":
+ suse_version_re = re.compile("^(opensuse[0-9]+)\.([0-9]+)$")
+ if suse_version_re.match(os_version):
+ os_version = suse_version_re.match(os_version).groups()[0]
+ # make sure virt-install knows about our os_version,
+ # otherwise default it to generic26
+ found = False
+ if os_version in supported_variants:
+ cmd += "--os-variant %s " % os_version
+ else:
+ print ("- warning: virt-install doesn't know this os_version, defaulting to generic26")
+ cmd += "--os-variant generic26 "
+ else:
+ distro = "unix"
+ if breed in [ "debian", "suse", "redhat" ]:
+ distro = "linux"
+ elif breed in [ "windows" ]:
+ distro = "windows"
+
+ cmd += "--os-type %s " % distro
+
+ if importpath:
+ # This needs to be the first disk for import to work
+ cmd += "--disk path=%s " % importpath
+
+ for path, size, driver_type in disks:
+ print ("- adding disk: %s of size %s (driver type=%s)" %
+ (path, size, driver_type))
+ cmd += "--disk path=%s" % (path)
+ if str(size) != "0":
+ cmd += ",size=%s" % size
+ if disk_bus:
+ cmd += ",bus=%s" % disk_bus
+ if driver_type and not disable_driver_type:
+ cmd += ",format=%s" % driver_type
+ cmd += " "
+
+ if floppy:
+ cmd += "--disk path=%s,device=floppy " % floppy
+
+ for bridge, mac in nics:
+ cmd += "--network bridge=%s" % bridge
+ if net_model and not disable_net_model:
+ cmd += ",model=%s" % net_model
+ if mac:
+ if oldstyle_macs:
+ cmd += " --mac=%s" % mac
+ else:
+ cmd += ",mac=%s" % mac
+ cmd += " "
+
+ cmd += "--wait %d " % int(wait)
+ if noreboot:
+ cmd += "--noreboot "
+ if osimport and not(import_exists):
+ cmd += "--import "
+ cmd += "--noautoconsole "
+
+ return shlex.split(cmd.strip())
diff -rupN cobbler-2.0.7-old/koan/xencreate.py cobbler-2.0.7-new/koan/xencreate.py
--- cobbler-2.0.7-old/koan/xencreate.py 2013-11-21 14:02:54.304559209 -0500
+++ cobbler-2.0.7-new/koan/xencreate.py 2013-11-21 14:05:56.006847361 -0500
@@ -1,14 +1,14 @@
"""
-Virtualization installation functions.
+Virtualization installation functions.
Currently somewhat Xen/paravirt specific, will evolve later.
-Copyright 2006-2008 Red Hat, Inc.
-Michael DeHaan <mdehaan@redhat.com>
+Copyright 2006-2008 Red Hat, Inc and Others.
+Michael DeHaan <michael.dehaan AT gmail>
Original version based on virtguest-install
Jeremy Katz <katzj@redhat.com>
Option handling added by Andrew Puch <apuch@redhat.com>
-Simplified for use as library by koan, Michael DeHaan <mdehaan@redhat.com>
+Simplified for use as library by koan, Michael DeHaan <michael.dehaan AT gmail>
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
@@ -26,180 +26,9 @@ Foundation, Inc., 51 Franklin Street, Fi
02110-1301 USA
"""
-import os, sys, time, stat
-import tempfile
-import random
-import exceptions
-import errno
-import re
-import virtinst
-import app as koan
-
-try:
- from virtinst.DistroManager import PXEInstaller
- pxe_installer = PXEInstaller()
-except ImportError:
- try:
- from virtinst import PXEInstaller
- pxe_installer = PXEInstaller(os_type='hvm')
- except:
- # older virtinst, this is probably ok
- # but we know we can't do Xen fullvirt installs
- pass
-import traceback
-
-def random_mac():
- """
- from xend/server/netif.py
- Generate a random MAC address.
- Uses OUI 00-16-3E, allocated to
- Xensource, Inc. Last 3 fields are random.
- return: MAC address string
- """
- mac = [ 0x00, 0x16, 0x3e,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff) ]
- return ':'.join(map(lambda x: "%02x" % x, mac))
-
-
-def start_install(name=None,
- ram=None,
- disks=None,
- uuid=None,
- extra=None,
- vcpus=None,
- profile_data=None,
- arch=None,
- no_gfx=False,
- fullvirt=False,
- bridge=None,
- virt_type=None,
- virt_auto_boot=False):
-
- if profile_data.has_key("file"):
- raise koan.InfoException("Xen does not work with --image yet")
-
- if fullvirt:
- # FIXME: add error handling here to explain when it's not supported
- guest = virtinst.FullVirtGuest(installer=pxe_installer)
- else:
- guest = virtinst.ParaVirtGuest()
-
- extra = extra.replace("&","&amp;")
-
- if not fullvirt:
- guest.set_boot((profile_data["kernel_local"], profile_data["initrd_local"]))
- # fullvirt OS's will get this from the PXE config (managed by Cobbler)
- guest.extraargs = extra
- else:
- print "- fullvirt mode"
- if profile_data.has_key("breed"):
- breed = profile_data["breed"]
- if breed != "other" and breed != "":
- if breed in [ "debian", "suse", "redhat" ]:
- guest.set_os_type("linux")
- elif breed in [ "windows" ]:
- guest.set_os_type("windows")
- else:
- guest.set_os_type("unix")
- if profile_data.has_key("os_version"):
- # FIXME: when os_version is not defined and it's linux, do we use generic24/generic26 ?
- version = profile_data["os_version"]
- if version != "other" and version != "":
- try:
- guest.set_os_variant(version)
- except:
- print "- virtinst library does not understand variant %s, treating as generic" % version
- pass
-
-
- guest.set_name(name)
- guest.set_memory(ram)
- guest.set_vcpus(vcpus)
-
- if not no_gfx:
- guest.set_graphics("vnc")
- else:
- guest.set_graphics(False)
-
- if uuid is not None:
- guest.set_uuid(uuid)
-
- for d in disks:
- if d[1] != 0 or d[0].startswith("/dev"):
- virtdisk = virtinst.XenDisk(d[0], size=d[1])
-
- # Set driver_name to tap for Xen PV guests
- if guest.installer and guest.installer.os_type in ('xen', 'linux'):
- if virtdisk.type == virtinst.XenDisk.TYPE_FILE and \
- virtinst._util.is_blktap_capable():
- virtdisk.driver_name = virtinst.XenDisk.DRIVER_TAP
-
- guest.disks.append(virtdisk)
- else:
- raise koan.InfoException("this virtualization type does not work without a disk image, set virt-size in Cobbler to non-zero")
-
- counter = 0
-
- if profile_data.has_key("interfaces"):
-
- interfaces = profile_data["interfaces"].keys()
- interfaces.sort()
- counter = -1
- vlanpattern = re.compile("[a-zA-Z0-9]+\.[0-9]+")
-
- for iname in interfaces:
- counter = counter + 1
- intf = profile_data["interfaces"][iname]
-
- if intf["bonding"] == "master" or vlanpattern.match(iname) or iname.find(":") != -1:
- continue
-
- mac = intf["mac_address"]
- if mac == "":
- mac = random_mac()
-
- if not bridge:
- profile_bridge = profile_data["virt_bridge"]
-
- intf_bridge = intf["virt_bridge"]
- if intf_bridge == "":
- if profile_bridge == "":
- raise koan.InfoException("virt-bridge setting is not defined in cobbler")
- intf_bridge = profile_bridge
-
- else:
- if bridge.find(",") == -1:
- intf_bridge = bridge
- else:
- bridges = bridge.split(",")
- intf_bridge = bridges[counter]
-
-
- nic_obj = virtinst.XenNetworkInterface(macaddr=mac, bridge=intf_bridge)
- guest.nics.append(nic_obj)
- counter = counter + 1
-
- else:
- # for --profile you just get one NIC, go define a system if you want more.
- # FIXME: can mac still be sent on command line in this case?
-
- if bridge is None:
- profile_bridge = profile_data["virt_bridge"]
- else:
- profile_bridge = bridge
-
- if profile_bridge == "":
- raise koan.InfoException("virt-bridge setting is not defined in cobbler")
-
- nic_obj = virtinst.XenNetworkInterface(macaddr=random_mac(), bridge=profile_bridge)
- guest.nics.append(nic_obj)
-
-
-
-
- guest.start_install()
-
- return "use virt-manager or reconnect with virsh console %s" % name
-
+import utils
+import virtinstall
+
+def start_install(*args, **kwargs):
+ cmd = virtinstall.build_commandline("xen:///", *args, **kwargs)
+ utils.subprocess_call(cmd)