1167 lines
41 KiB
Diff
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("&","&")
|
|
-
|
|
- 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("&","&")
|
|
- 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("&","&")
|
|
-
|
|
- 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)
|