Add no-virt mode to livemedia-creator
This runs anaconda directly, using the --image install feature. The host system should be the same release as the target system in order to avoid unexpected problems.
This commit is contained in:
parent
bfe5ce2813
commit
7149adee25
@ -36,7 +36,7 @@ to monitor the logs for fatal errors, but may not catch everything.
|
||||
HOW IT WORKS
|
||||
------------
|
||||
The --make-* switches define the final output. Currently only --make-iso
|
||||
is working.
|
||||
and --make-disk are working.
|
||||
|
||||
You then need to either pass --iso and --ks in order to create a disk image
|
||||
using virt-install, or --disk-image to use a disk image from a previous run
|
||||
@ -127,6 +127,33 @@ You can also add an update repo, but don't name it updates. Add --proxy to
|
||||
it as well.
|
||||
|
||||
|
||||
ANACONDA IMAGE INSTALL
|
||||
----------------------
|
||||
You can create images without using virt-install by passing --no-virt on the
|
||||
cmdline. This will use Anaconda's image install feature to handle the install.
|
||||
There are a couple of things to keep in mind when doing this:
|
||||
|
||||
1. It will be most reliable when building images for the same release that the
|
||||
host is running. Because Anaconda has expectations about the system it is
|
||||
running under you may encounter strange bugs if you try to build newer or
|
||||
older releases.
|
||||
|
||||
2. Make sure selinux is set to permissive or disabled. It won't install
|
||||
correctly with selinux set to enforcing yet.
|
||||
|
||||
3. It may totally trash your host. So far I haven't had this happen, but the
|
||||
possibility exists that a bug in Anaconda could result in it operating on
|
||||
real devices. I recommend running it in a virt or on a system that you can
|
||||
afford to lose all data from.
|
||||
|
||||
The logs from anaconda will be placed in an ./anaconda/ directory in either
|
||||
the current directory or in the directory used for --logfile
|
||||
|
||||
Example cmdline:
|
||||
|
||||
sudo livemedia-creator --make-iso --no-virt --ks=./fedora-livemedia.ks
|
||||
|
||||
|
||||
DEBUGGING PROBLEMS
|
||||
------------------
|
||||
Cleaning up an aborted (ctrl-c) virt-install run (as root):
|
||||
@ -144,6 +171,9 @@ You can add --image-only to skip the .iso creation and examine the resulting
|
||||
disk image. Or you can pass --keep-image to keep it around after lorax is
|
||||
run.
|
||||
|
||||
Cleaning up aborted --no-virt installs can sometimes be accomplished by running
|
||||
the anaconda-cleanup script.
|
||||
|
||||
|
||||
THE FUTURE
|
||||
----------
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Live Media Creator
|
||||
#
|
||||
# Copyright (C) 2009 Red Hat, Inc.
|
||||
# Copyright (C) 2011 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -46,12 +46,13 @@ from pykickstart.version import makeVersion
|
||||
from pylorax.base import DataHolder
|
||||
from pylorax.treebuilder import TreeBuilder, RuntimeBuilder
|
||||
from pylorax.sysutils import joinpaths, remove, linktree
|
||||
from pylorax.imgutils import PartitionMount
|
||||
from pylorax.imgutils import PartitionMount, mksparse
|
||||
from pylorax.executils import execWithRedirect, execWithCapture
|
||||
|
||||
|
||||
# Default parameters for rebuilding initramfs, overrice with --dracut-args
|
||||
DRACUT_DEFAULT = ["--xz", "--omit", "plymouth"]
|
||||
DRACUT_DEFAULT = ["--xz", "--add", "livenet", "--add", "dmsquash-live",
|
||||
"--omit", "plymouth"]
|
||||
|
||||
|
||||
class LogRequestHandler(SocketServer.BaseRequestHandler):
|
||||
@ -106,11 +107,14 @@ class LogRequestHandler(SocketServer.BaseRequestHandler):
|
||||
"""
|
||||
Check a line to see if it contains an error indicating install failure
|
||||
"""
|
||||
if line.find("Traceback (") > -1 \
|
||||
or line.find("Out of memory:") > -1 \
|
||||
or line.find("Call Trace:") > -1 \
|
||||
or line.find("insufficient disk space:") > -1:
|
||||
simple_tests = [ "Traceback (",
|
||||
"Out of memory:",
|
||||
"Call Trace:",
|
||||
"insufficient disk space:" ]
|
||||
for t in simple_tests:
|
||||
if line.find( t ) > -1:
|
||||
self.server.log_error = True
|
||||
return
|
||||
|
||||
|
||||
class LogServer(SocketServer.TCPServer):
|
||||
@ -343,6 +347,22 @@ class VirtualInstall( object ):
|
||||
subprocess.call(["virsh","undefine",self.virt_name])
|
||||
|
||||
|
||||
def anaconda_install( disk_img, disk_size, kickstart, repo, args ):
|
||||
"""
|
||||
|
||||
"""
|
||||
# Create the sparse image
|
||||
mksparse( disk_img, disk_size * 1024**3 )
|
||||
|
||||
cmd = [ "anaconda", "--image", disk_img, "--kickstart", kickstart,
|
||||
"--script", "--repo", repo_url ]
|
||||
cmd += args
|
||||
|
||||
log.debug( cmd )
|
||||
|
||||
return execWithRedirect( cmd[0], cmd[1:] )
|
||||
|
||||
|
||||
def get_kernels( boot_dir ):
|
||||
"""
|
||||
Examine the vmlinuz-* versions and return a list of them
|
||||
@ -434,7 +454,7 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser( description="Create Live Install Media",
|
||||
fromfile_prefix_chars="@" )
|
||||
|
||||
# These two are mutually exclusive, one is required
|
||||
# These are mutually exclusive, one is required
|
||||
action = parser.add_mutually_exclusive_group( required=True )
|
||||
action.add_argument( "--make-iso", action="store_true",
|
||||
help="Build a live iso" )
|
||||
@ -445,10 +465,9 @@ if __name__ == '__main__':
|
||||
action.add_argument( "--make-ami", action="store_true",
|
||||
help="Build an ami image" )
|
||||
|
||||
source = parser.add_mutually_exclusive_group( required=True )
|
||||
source.add_argument( "--iso", type=os.path.abspath,
|
||||
parser.add_argument( "--iso", type=os.path.abspath,
|
||||
help="Anaconda installation .iso path to use for virt-install" )
|
||||
source.add_argument( "--disk-image", type=os.path.abspath,
|
||||
parser.add_argument( "--disk-image", type=os.path.abspath,
|
||||
help="Path to disk image to use for creating final image" )
|
||||
|
||||
parser.add_argument( "--ks", action="append", type=os.path.abspath,
|
||||
@ -459,6 +478,11 @@ if __name__ == '__main__':
|
||||
help="Keep raw disk image after .iso creation" )
|
||||
parser.add_argument( "--no-virt", action="store_true",
|
||||
help="Use Anaconda's image install instead of virt-install" )
|
||||
parser.add_argument( "--proxy",
|
||||
help="proxy URL to use for the install" )
|
||||
parser.add_argument( "--anaconda-arg", action="append", dest="anaconda_args",
|
||||
help="Additional argument to pass to anaconda (no-virt "
|
||||
"mode). Pass once for each argument" )
|
||||
|
||||
parser.add_argument( "--logfile", default="./livemedia.log",
|
||||
type=os.path.abspath,
|
||||
@ -551,10 +575,6 @@ if __name__ == '__main__':
|
||||
log.error( "The disk image {0} is missing.".format( opts.disk_image ) )
|
||||
sys.exit( 1 )
|
||||
|
||||
if opts.no_virt:
|
||||
log.error( "--no-virt is not yet implemented." )
|
||||
sys.exit( 1 )
|
||||
|
||||
if opts.make_appliance:
|
||||
log.error( "--make-appliance is not yet implemented." )
|
||||
sys.exit( 1 )
|
||||
@ -563,14 +583,12 @@ if __name__ == '__main__':
|
||||
log.error( "--make-ami is not yet implemented." )
|
||||
sys.exit( 1 )
|
||||
|
||||
# Use virt-install to make the disk image
|
||||
if opts.iso:
|
||||
disk_img = tempfile.mktemp( prefix="disk", suffix=".img", dir=opts.tmp )
|
||||
install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
|
||||
|
||||
log.info( "disk_img = {0}".format(disk_img) )
|
||||
log.info( "install_log = {0}".format(install_log) )
|
||||
if not opts.no_virt and not opts.iso and not opts.disk_image:
|
||||
log.error( "virt-install needs an install iso." )
|
||||
sys.exit( 1 )
|
||||
|
||||
# Make the disk image
|
||||
if not opts.disk_image:
|
||||
# Parse the kickstart to get the partition sizes
|
||||
ks_version = makeVersion()
|
||||
ks = KickstartParser( ks_version, errorsAreFatal=False, missingIncludeIsFatal=False )
|
||||
@ -578,11 +596,52 @@ if __name__ == '__main__':
|
||||
disk_size = 1 + (sum( [p.size for p in ks.handler.partition.partitions] ) / 1024)
|
||||
log.info( "disk_size = {0}GB".format(disk_size) )
|
||||
|
||||
if ks.handler.method.method != "url":
|
||||
log.error( "Only url install method is currently supported. Please "
|
||||
"fix your kickstart file." )
|
||||
sys.exit( 1 )
|
||||
repo_url = ks.handler.method.url
|
||||
|
||||
disk_img = tempfile.mktemp( prefix="disk", suffix=".img", dir=opts.tmp )
|
||||
install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
|
||||
|
||||
log.info( "disk_img = {0}".format(disk_img) )
|
||||
log.info( "install_log = {0}".format(install_log) )
|
||||
|
||||
if opts.no_virt:
|
||||
anaconda_args = []
|
||||
if opts.anaconda_args:
|
||||
for arg in opts.anaconda_args:
|
||||
anaconda_args += arg.split(" ", 1)
|
||||
if opts.proxy:
|
||||
anaconda_args += [ "--proxy", opts.proxy ]
|
||||
|
||||
# Use anaconda's image install
|
||||
install_error = anaconda_install( disk_img, disk_size, opts.ks[0],
|
||||
repo_url, anaconda_args )
|
||||
|
||||
# Move the anaconda logs over to a log directory
|
||||
log_dir = os.path.abspath(os.path.dirname(opts.logfile))
|
||||
log_anaconda = joinpaths( log_dir, "anaconda" )
|
||||
if not os.path.isdir( log_anaconda ):
|
||||
os.mkdir( log_anaconda )
|
||||
for l in ["anaconda.log", "ifcfg.log", "program.log", "storage.log",
|
||||
"yum.log"]:
|
||||
if os.path.exists( "/tmp/"+l ):
|
||||
shutil.copy2( "/tmp/"+l, log_anaconda )
|
||||
os.unlink( "/tmp/"+l )
|
||||
else:
|
||||
iso_mount = IsoMountpoint( opts.iso )
|
||||
log_monitor = LogMonitor( install_log )
|
||||
|
||||
kernel_args = ""
|
||||
if opts.kernel_args:
|
||||
kernel_args += opts.kernel_args
|
||||
if opts.proxy:
|
||||
kernel_args += " proxy="+opts.proxy
|
||||
|
||||
virt = VirtualInstall( iso_mount, opts.ks, disk_img, disk_size,
|
||||
opts.kernel_args, opts.ram, opts.vnc,
|
||||
kernel_args, opts.ram, opts.vnc,
|
||||
log_check = log_monitor.server.log_check,
|
||||
virtio_host = log_monitor.host,
|
||||
virtio_port = log_monitor.port )
|
||||
@ -590,7 +649,9 @@ if __name__ == '__main__':
|
||||
log_monitor.shutdown()
|
||||
iso_mount.umount()
|
||||
|
||||
if log_monitor.server.log_check():
|
||||
install_error = log_monitor.server.log_check()
|
||||
|
||||
if install_error:
|
||||
log.error( "Install failed" )
|
||||
if not opts.keep_image:
|
||||
log.info( "Removing bad disk image" )
|
||||
@ -616,7 +677,7 @@ if __name__ == '__main__':
|
||||
log.info("SUMMARY")
|
||||
log.info("-------")
|
||||
log.info("Logs are in {0}".format(os.path.abspath(os.path.dirname(opts.logfile))))
|
||||
if opts.keep_image:
|
||||
if opts.keep_image or opts.make_disk:
|
||||
log.info("Disk image is at {0}".format(disk_img))
|
||||
else:
|
||||
log.info("Disk image erased")
|
||||
|
Loading…
Reference in New Issue
Block a user