Move core of livemedia-creator to run_creator()
We need to be able to share the output types from livemedia-creator with lorax-composer, so move the core of the main() function into run_creatoe(). Pass in the cmdline args or a DataHolder with them set.
This commit is contained in:
parent
85ee784efc
commit
59fd3934f3
@ -28,13 +28,17 @@ import glob
|
|||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
from mako.exceptions import text_error_template
|
from mako.exceptions import text_error_template
|
||||||
|
|
||||||
|
# Use pykickstart to calculate disk image size
|
||||||
|
from pykickstart.parser import KickstartParser
|
||||||
|
from pykickstart.version import makeVersion, RHEL7
|
||||||
|
|
||||||
# Use the Lorax treebuilder branch for iso creation
|
# Use the Lorax treebuilder branch for iso creation
|
||||||
from pylorax import ArchData
|
from pylorax import ArchData
|
||||||
from pylorax.base import DataHolder
|
from pylorax.base import DataHolder
|
||||||
from pylorax.treebuilder import TreeBuilder, RuntimeBuilder
|
from pylorax.treebuilder import TreeBuilder, RuntimeBuilder
|
||||||
from pylorax.treebuilder import findkernels
|
from pylorax.treebuilder import findkernels
|
||||||
from pylorax.sysutils import joinpaths, remove
|
from pylorax.sysutils import joinpaths, remove
|
||||||
from pylorax.imgutils import mount, umount
|
from pylorax.imgutils import Mount, PartitionMount, copytree, mount, umount
|
||||||
from pylorax.imgutils import mksquashfs, mkrootfsimg
|
from pylorax.imgutils import mksquashfs, mkrootfsimg
|
||||||
from pylorax.executils import execWithRedirect, runcmd
|
from pylorax.executils import execWithRedirect, runcmd
|
||||||
from pylorax.installer import InstallError, novirt_install, virt_install
|
from pylorax.installer import InstallError, novirt_install, virt_install
|
||||||
@ -46,6 +50,17 @@ DRACUT_DEFAULT = ["--xz", "--add", "livenet dmsquash-live convertfs pollcdrom",
|
|||||||
"--omit", "plymouth", "--no-hostonly", "--no-early-microcode"]
|
"--omit", "plymouth", "--no-hostonly", "--no-early-microcode"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_ks_disk_size(ks):
|
||||||
|
"""Return the size of the kickstart's disk partitions
|
||||||
|
|
||||||
|
:param ks: The kickstart
|
||||||
|
:type ks: Kickstart object
|
||||||
|
:returns: The size of the disk, in GiB
|
||||||
|
"""
|
||||||
|
disk_size = 1 + (sum([p.size for p in ks.handler.partition.partitions]) / 1024)
|
||||||
|
log.info("disk_size = %sGiB", disk_size)
|
||||||
|
return disk_size
|
||||||
|
|
||||||
def is_image_mounted(disk_img):
|
def is_image_mounted(disk_img):
|
||||||
"""
|
"""
|
||||||
Return True if the disk_img is mounted
|
Return True if the disk_img is mounted
|
||||||
@ -390,7 +405,7 @@ def make_squashfs(disk_img, work_dir, compression="xz"):
|
|||||||
remove(joinpaths(work_dir, "runtime"))
|
remove(joinpaths(work_dir, "runtime"))
|
||||||
|
|
||||||
|
|
||||||
def make_image(opts, ks):
|
def make_image(opts, ks, callback_func=None):
|
||||||
"""
|
"""
|
||||||
Install to an image
|
Install to an image
|
||||||
|
|
||||||
@ -398,8 +413,7 @@ def make_image(opts, ks):
|
|||||||
|
|
||||||
Returns the full path of of the image created.
|
Returns the full path of of the image created.
|
||||||
"""
|
"""
|
||||||
disk_size = 1 + (sum([p.size for p in ks.handler.partition.partitions]) / 1024)
|
disk_size = get_ks_disk_size(ks)
|
||||||
log.info("disk_size = %sGB", disk_size)
|
|
||||||
|
|
||||||
if opts.image_name:
|
if opts.image_name:
|
||||||
disk_img = joinpaths(opts.result_dir, opts.image_name)
|
disk_img = joinpaths(opts.result_dir, opts.image_name)
|
||||||
@ -409,7 +423,7 @@ def make_image(opts, ks):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if opts.no_virt:
|
if opts.no_virt:
|
||||||
novirt_install(opts, disk_img, disk_size, ks.handler.method.url)
|
novirt_install(opts, disk_img, disk_size, ks.handler.method.url, callback_func=callback_func)
|
||||||
else:
|
else:
|
||||||
install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
|
install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
|
||||||
log.info("install_log = %s", install_log)
|
log.info("install_log = %s", install_log)
|
||||||
@ -473,3 +487,127 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
|||||||
create_pxe_config(template, work_dir, live_image_name, add_pxe_args)
|
create_pxe_config(template, work_dir, live_image_name, add_pxe_args)
|
||||||
|
|
||||||
return work_dir
|
return work_dir
|
||||||
|
|
||||||
|
def run_creator(opts, callback_func=None):
|
||||||
|
"""Run the image creator process
|
||||||
|
|
||||||
|
:param opts: Commandline options to control the process
|
||||||
|
:type opts: Either a DataHolder or ArgumentParser
|
||||||
|
:returns: The result directory and the disk image path.
|
||||||
|
:rtype: Tuple of str
|
||||||
|
|
||||||
|
This function takes the opts arguments and creates the selected output image.
|
||||||
|
See the cmdline --help for livemedia-creator for the possible options
|
||||||
|
|
||||||
|
(Yes, this is not ideal, but we can fix that later)
|
||||||
|
"""
|
||||||
|
result_dir = None
|
||||||
|
|
||||||
|
# Parse the kickstart
|
||||||
|
if opts.ks:
|
||||||
|
ks_version = makeVersion(RHEL7)
|
||||||
|
ks = KickstartParser( ks_version, errorsAreFatal=False, missingIncludeIsFatal=False )
|
||||||
|
ks.readKickstart( opts.ks[0] )
|
||||||
|
|
||||||
|
# Make the disk or filesystem image
|
||||||
|
if not opts.disk_image and not opts.fs_image:
|
||||||
|
if not opts.ks:
|
||||||
|
raise RuntimeError("Image creation requires a kickstart file")
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
if ks.handler.method.method != "url" and opts.no_virt:
|
||||||
|
errors.append("Only url install method is currently supported. Please "
|
||||||
|
"fix your kickstart file." )
|
||||||
|
|
||||||
|
if ks.handler.displaymode.displayMode is not None:
|
||||||
|
errors.append("The kickstart must not set a display mode (text, cmdline, "
|
||||||
|
"graphical), this will interfere with livemedia-creator.")
|
||||||
|
|
||||||
|
if opts.make_fsimage:
|
||||||
|
# Make sure the kickstart isn't using autopart and only has a / mountpoint
|
||||||
|
part_ok = not any(p for p in ks.handler.partition.partitions
|
||||||
|
if p.mountpoint not in ["/", "swap"])
|
||||||
|
if not part_ok or ks.handler.autopart.seen:
|
||||||
|
errors.append("Filesystem images must use a single / part, not autopart or "
|
||||||
|
"multiple partitions. swap is allowed but not used.")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
raise RuntimeError("\n".join(errors))
|
||||||
|
|
||||||
|
# Make the image. Output of this is either a partitioned disk image or a fsimage
|
||||||
|
# Can also fail with InstallError
|
||||||
|
disk_img = make_image(opts, ks, callback_func=callback_func)
|
||||||
|
|
||||||
|
# Only create the disk image, return that now
|
||||||
|
if opts.image_only:
|
||||||
|
return (result_dir, disk_img)
|
||||||
|
|
||||||
|
if opts.make_iso:
|
||||||
|
work_dir = tempfile.mkdtemp()
|
||||||
|
log.info("working dir is %s", work_dir)
|
||||||
|
|
||||||
|
if (opts.fs_image or opts.no_virt) and not opts.disk_image:
|
||||||
|
# Create iso from a filesystem image
|
||||||
|
disk_img = opts.fs_image or disk_img
|
||||||
|
|
||||||
|
make_squashfs(disk_img, work_dir)
|
||||||
|
with Mount(disk_img, opts="loop") as mount_dir:
|
||||||
|
result_dir = make_livecd(opts, mount_dir, work_dir)
|
||||||
|
else:
|
||||||
|
# Create iso from a partitioned disk image
|
||||||
|
disk_img = opts.disk_image or disk_img
|
||||||
|
with PartitionMount(disk_img) as img_mount:
|
||||||
|
if img_mount and img_mount.mount_dir:
|
||||||
|
make_runtime(opts, img_mount.mount_dir, work_dir)
|
||||||
|
result_dir = make_livecd(opts, img_mount.mount_dir, work_dir)
|
||||||
|
|
||||||
|
# cleanup the mess
|
||||||
|
# cleanup work_dir?
|
||||||
|
if disk_img and not (opts.keep_image or opts.disk_image or opts.fs_image):
|
||||||
|
os.unlink(disk_img)
|
||||||
|
log.info("Disk image erased")
|
||||||
|
disk_img = None
|
||||||
|
elif opts.make_appliance:
|
||||||
|
if not opts.ks:
|
||||||
|
networks = []
|
||||||
|
else:
|
||||||
|
networks = ks.handler.network.network
|
||||||
|
make_appliance(opts.disk_image or disk_img, opts.app_name,
|
||||||
|
opts.app_template, opts.app_file, networks, opts.ram,
|
||||||
|
opts.vcpus, opts.arch, opts.title, opts.project, opts.releasever)
|
||||||
|
elif opts.make_pxe_live:
|
||||||
|
work_dir = tempfile.mkdtemp()
|
||||||
|
log.info("working dir is %s", work_dir)
|
||||||
|
|
||||||
|
if (opts.fs_image or opts.no_virt) and not opts.disk_image:
|
||||||
|
# Create pxe live images from a filesystem image
|
||||||
|
disk_img = opts.fs_image or disk_img
|
||||||
|
with Mount(disk_img, opts="loop") as mnt_dir:
|
||||||
|
result_dir = make_live_images(opts, work_dir, mnt_dir, rootfs_image=disk_img)
|
||||||
|
else:
|
||||||
|
# Create pxe live images from a partitioned disk image
|
||||||
|
disk_img = opts.disk_image or disk_img
|
||||||
|
is_root_part = None
|
||||||
|
if opts.ostree:
|
||||||
|
is_root_part = lambda dir: os.path.exists(dir+"/ostree/deploy")
|
||||||
|
with PartitionMount(disk_img, mount_ok=is_root_part) as img_mount:
|
||||||
|
if img_mount and img_mount.mount_dir:
|
||||||
|
try:
|
||||||
|
mounted_sysroot_boot_dir = None
|
||||||
|
if opts.ostree:
|
||||||
|
mounted_sysroot_boot_dir = mount_boot_part_over_root(img_mount)
|
||||||
|
if opts.live_rootfs_keep_size:
|
||||||
|
size = img_mount.mount_size / 1024**3
|
||||||
|
else:
|
||||||
|
size = opts.live_rootfs_size or None
|
||||||
|
result_dir = make_live_images(opts, work_dir, img_mount.mount_dir, size=size)
|
||||||
|
finally:
|
||||||
|
if mounted_sysroot_boot_dir:
|
||||||
|
umount(mounted_sysroot_boot_dir)
|
||||||
|
|
||||||
|
if opts.result_dir != opts.tmp and result_dir:
|
||||||
|
copytree(result_dir, opts.result_dir, preserve=False)
|
||||||
|
shutil.rmtree( result_dir )
|
||||||
|
result_dir = None
|
||||||
|
|
||||||
|
return (result_dir, disk_img)
|
||||||
|
@ -24,21 +24,12 @@ pylorax_log = logging.getLogger("pylorax")
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
# Use pykickstart to calculate disk image size
|
|
||||||
from pykickstart.parser import KickstartParser
|
|
||||||
from pykickstart.version import makeVersion, RHEL7
|
|
||||||
|
|
||||||
from pylorax import vernum
|
from pylorax import vernum
|
||||||
from pylorax.creator import DRACUT_DEFAULT, mount_boot_part_over_root
|
from pylorax.creator import DRACUT_DEFAULT, run_creator
|
||||||
from pylorax.creator import make_appliance, make_image, make_livecd, make_live_images
|
from pylorax.imgutils import default_image_name
|
||||||
from pylorax.creator import make_runtime, make_squashfs
|
|
||||||
from pylorax.imgutils import copytree, default_image_name
|
|
||||||
from pylorax.imgutils import Mount, PartitionMount, umount
|
|
||||||
from pylorax.installer import InstallError
|
|
||||||
from pylorax.sysutils import joinpaths
|
from pylorax.sysutils import joinpaths
|
||||||
|
|
||||||
VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
|
VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
|
||||||
@ -246,7 +237,7 @@ def main():
|
|||||||
sys.exit( 1 )
|
sys.exit( 1 )
|
||||||
|
|
||||||
if opts.result_dir and os.path.exists(opts.result_dir):
|
if opts.result_dir and os.path.exists(opts.result_dir):
|
||||||
log.error( "The results_dir (%s) should not exist, please delete or "
|
log.error( "The result_dir (%s) should not exist, please delete or "
|
||||||
"move its contents", opts.result_dir)
|
"move its contents", opts.result_dir)
|
||||||
sys.exit( 1 )
|
sys.exit( 1 )
|
||||||
|
|
||||||
@ -347,115 +338,12 @@ def main():
|
|||||||
tempfile.tempdir = opts.tmp
|
tempfile.tempdir = opts.tmp
|
||||||
disk_img = None
|
disk_img = None
|
||||||
|
|
||||||
# Parse the kickstart
|
try:
|
||||||
if opts.ks:
|
# TODO - Better API than passing in opts
|
||||||
ks_version = makeVersion(RHEL7)
|
(result_dir, disk_img) = run_creator(opts)
|
||||||
ks = KickstartParser( ks_version, errorsAreFatal=False, missingIncludeIsFatal=False )
|
except Exception as e:
|
||||||
ks.readKickstart( opts.ks[0] )
|
log.error(str(e))
|
||||||
|
sys.exit(1)
|
||||||
# Make the disk or filesystem image
|
|
||||||
if not opts.disk_image and not opts.fs_image:
|
|
||||||
if not opts.ks:
|
|
||||||
log.error("Image creation requires a kickstart file")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
errors = []
|
|
||||||
if ks.handler.method.method != "url" and opts.no_virt:
|
|
||||||
errors.append("Only url install method is currently supported. Please "
|
|
||||||
"fix your kickstart file." )
|
|
||||||
|
|
||||||
if ks.handler.displaymode.displayMode is not None:
|
|
||||||
errors.append("The kickstart must not set a display mode (text, cmdline, "
|
|
||||||
"graphical), this will interfere with livemedia-creator.")
|
|
||||||
|
|
||||||
if opts.make_fsimage:
|
|
||||||
# Make sure the kickstart isn't using autopart and only has a / mountpoint
|
|
||||||
part_ok = not any(p for p in ks.handler.partition.partitions
|
|
||||||
if p.mountpoint not in ["/", "swap"])
|
|
||||||
if not part_ok or ks.handler.autopart.seen:
|
|
||||||
errors.append("Filesystem images must use a single / part, not autopart or "
|
|
||||||
"multiple partitions. swap is allowed but not used.")
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
for _e in errors:
|
|
||||||
log.error(_e)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Make the image. Output of this is either a partitioned disk image or a fsimage
|
|
||||||
try:
|
|
||||||
disk_img = make_image(opts, ks)
|
|
||||||
except InstallError as e:
|
|
||||||
log.error("ERROR: Image creation failed: %s", e)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not opts.image_only:
|
|
||||||
result_dir = None
|
|
||||||
if opts.make_iso:
|
|
||||||
work_dir = tempfile.mkdtemp()
|
|
||||||
log.info("working dir is %s", work_dir)
|
|
||||||
|
|
||||||
if (opts.fs_image or opts.no_virt) and not opts.disk_image:
|
|
||||||
# Create iso from a filesystem image
|
|
||||||
disk_img = opts.fs_image or disk_img
|
|
||||||
|
|
||||||
make_squashfs(disk_img, work_dir)
|
|
||||||
with Mount(disk_img, opts="loop") as mount_dir:
|
|
||||||
result_dir = make_livecd(opts, mount_dir, work_dir)
|
|
||||||
else:
|
|
||||||
# Create iso from a partitioned disk image
|
|
||||||
disk_img = opts.disk_image or disk_img
|
|
||||||
with PartitionMount(disk_img) as img_mount:
|
|
||||||
if img_mount and img_mount.mount_dir:
|
|
||||||
make_runtime(opts, img_mount.mount_dir, work_dir)
|
|
||||||
result_dir = make_livecd(opts, img_mount.mount_dir, work_dir)
|
|
||||||
|
|
||||||
# cleanup the mess
|
|
||||||
# cleanup work_dir?
|
|
||||||
if disk_img and not (opts.keep_image or opts.disk_image or opts.fs_image):
|
|
||||||
os.unlink(disk_img)
|
|
||||||
log.info("Disk image erased")
|
|
||||||
disk_img = None
|
|
||||||
elif opts.make_appliance:
|
|
||||||
if not opts.ks:
|
|
||||||
networks = []
|
|
||||||
else:
|
|
||||||
networks = ks.handler.network.network
|
|
||||||
make_appliance(opts.disk_image or disk_img, opts.app_name,
|
|
||||||
opts.app_template, opts.app_file, networks, opts.ram,
|
|
||||||
opts.vcpus, opts.arch, opts.title, opts.project, opts.releasever)
|
|
||||||
elif opts.make_pxe_live:
|
|
||||||
work_dir = tempfile.mkdtemp()
|
|
||||||
log.info("working dir is %s", work_dir)
|
|
||||||
|
|
||||||
if (opts.fs_image or opts.no_virt) and not opts.disk_image:
|
|
||||||
# Create pxe live images from a filesystem image
|
|
||||||
disk_img = opts.fs_image or disk_img
|
|
||||||
with Mount(disk_img, opts="loop") as mnt_dir:
|
|
||||||
result_dir = make_live_images(opts, work_dir, mnt_dir, rootfs_image=disk_img)
|
|
||||||
else:
|
|
||||||
# Create pxe live images from a partitioned disk image
|
|
||||||
disk_img = opts.disk_image or disk_img
|
|
||||||
is_root_part = None
|
|
||||||
if opts.ostree:
|
|
||||||
is_root_part = lambda dir: os.path.exists(dir+"/ostree/deploy")
|
|
||||||
with PartitionMount(disk_img, mount_ok=is_root_part) as img_mount:
|
|
||||||
if img_mount and img_mount.mount_dir:
|
|
||||||
try:
|
|
||||||
mounted_sysroot_boot_dir = None
|
|
||||||
if opts.ostree:
|
|
||||||
mounted_sysroot_boot_dir = mount_boot_part_over_root(img_mount)
|
|
||||||
if opts.live_rootfs_keep_size:
|
|
||||||
size = img_mount.mount_size / 1024**3
|
|
||||||
else:
|
|
||||||
size = opts.live_rootfs_size or None
|
|
||||||
result_dir = make_live_images(opts, work_dir, img_mount.mount_dir, size=size)
|
|
||||||
finally:
|
|
||||||
if mounted_sysroot_boot_dir:
|
|
||||||
umount(mounted_sysroot_boot_dir)
|
|
||||||
|
|
||||||
if opts.result_dir != opts.tmp and result_dir:
|
|
||||||
copytree(result_dir, opts.result_dir, preserve=False)
|
|
||||||
shutil.rmtree( result_dir )
|
|
||||||
|
|
||||||
log.info("SUMMARY")
|
log.info("SUMMARY")
|
||||||
log.info("-------")
|
log.info("-------")
|
||||||
@ -464,7 +352,7 @@ def main():
|
|||||||
log.info("Disk image is at %s", disk_img)
|
log.info("Disk image is at %s", disk_img)
|
||||||
if opts.make_appliance:
|
if opts.make_appliance:
|
||||||
log.info("Appliance description is in %s", opts.app_file)
|
log.info("Appliance description is in %s", opts.app_file)
|
||||||
log.info("Results are in %s", opts.result_dir or result_dir)
|
log.info("Results are in %s", result_dir or opts.result_dir)
|
||||||
|
|
||||||
sys.exit( 0 )
|
sys.exit( 0 )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user