Add cancel_func to virt and novirt_install functions
In addition to monitoring the logs for errors, call a function (or
functions) that tell it to cancel the anaconda process and cleanup.
Also check for a cancel after creating the squashfs image for live-iso
since that's a long running process.
This required adding a new argument to a number of existing functions,
passing it down to VirtualInstall and novirt_install where the function
is called.
(cherry picked from commit 4b84475612
)
Resolves: rhbz#1659129
This commit is contained in:
parent
ade25f34b3
commit
48c8ae6819
@ -241,7 +241,7 @@ def make_compose(cfg, results_dir):
|
|||||||
else:
|
else:
|
||||||
open(joinpaths(results_dir, install_cfg.image_name), "w").write("TEST IMAGE")
|
open(joinpaths(results_dir, install_cfg.image_name), "w").write("TEST IMAGE")
|
||||||
else:
|
else:
|
||||||
run_creator(install_cfg, callback_func=cancel_build)
|
run_creator(install_cfg, cancel_func=cancel_build)
|
||||||
|
|
||||||
# Extract the results of the compose into results_dir and cleanup the compose directory
|
# Extract the results of the compose into results_dir and cleanup the compose directory
|
||||||
move_compose_results(install_cfg, results_dir)
|
move_compose_results(install_cfg, results_dir)
|
||||||
|
@ -405,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, callback_func=None):
|
def make_image(opts, ks, cancel_func=None):
|
||||||
"""
|
"""
|
||||||
Install to an image
|
Install to an image
|
||||||
|
|
||||||
@ -423,12 +423,12 @@ def make_image(opts, ks, callback_func=None):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if opts.no_virt:
|
if opts.no_virt:
|
||||||
novirt_install(opts, disk_img, disk_size, ks.handler.method.url, callback_func=callback_func)
|
novirt_install(opts, disk_img, disk_size, ks.handler.method.url, cancel_func=cancel_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)
|
||||||
|
|
||||||
virt_install(opts, install_log, disk_img, disk_size)
|
virt_install(opts, install_log, disk_img, disk_size, cancel_func=cancel_func)
|
||||||
except InstallError as e:
|
except InstallError as e:
|
||||||
log.error("Install failed: %s", e)
|
log.error("Install failed: %s", e)
|
||||||
if not opts.keep_image:
|
if not opts.keep_image:
|
||||||
@ -489,7 +489,7 @@ def make_live_images(opts, work_dir, root_dir, rootfs_image=None, size=None):
|
|||||||
|
|
||||||
return work_dir
|
return work_dir
|
||||||
|
|
||||||
def run_creator(opts, callback_func=None):
|
def run_creator(opts, cancel_func=None):
|
||||||
"""Run the image creator process
|
"""Run the image creator process
|
||||||
|
|
||||||
:param opts: Commandline options to control the process
|
:param opts: Commandline options to control the process
|
||||||
@ -537,7 +537,10 @@ def run_creator(opts, callback_func=None):
|
|||||||
|
|
||||||
# Make the image. Output of this is either a partitioned disk image or a fsimage
|
# Make the image. Output of this is either a partitioned disk image or a fsimage
|
||||||
# Can also fail with InstallError
|
# Can also fail with InstallError
|
||||||
disk_img = make_image(opts, ks, callback_func=callback_func)
|
disk_img = make_image(opts, ks, cancel_func=cancel_func)
|
||||||
|
|
||||||
|
if cancel_func and cancel_func():
|
||||||
|
raise RuntimeError("image creation canceled")
|
||||||
|
|
||||||
# Only create the disk image, return that now
|
# Only create the disk image, return that now
|
||||||
if opts.image_only:
|
if opts.image_only:
|
||||||
@ -552,6 +555,10 @@ def run_creator(opts, callback_func=None):
|
|||||||
disk_img = opts.fs_image or disk_img
|
disk_img = opts.fs_image or disk_img
|
||||||
|
|
||||||
make_squashfs(disk_img, work_dir)
|
make_squashfs(disk_img, work_dir)
|
||||||
|
|
||||||
|
if cancel_func and cancel_func():
|
||||||
|
raise RuntimeError("ISO creation canceled")
|
||||||
|
|
||||||
with Mount(disk_img, opts="loop") as mount_dir:
|
with Mount(disk_img, opts="loop") as mount_dir:
|
||||||
result_dir = make_livecd(opts, mount_dir, work_dir)
|
result_dir = make_livecd(opts, mount_dir, work_dir)
|
||||||
else:
|
else:
|
||||||
|
@ -18,6 +18,7 @@ import logging
|
|||||||
log = logging.getLogger("pylorax")
|
log = logging.getLogger("pylorax")
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import glob
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -116,7 +117,7 @@ class VirtualInstall( object ):
|
|||||||
"""
|
"""
|
||||||
def __init__( self, iso, ks_paths, disk_img, img_size=2,
|
def __init__( self, iso, ks_paths, disk_img, img_size=2,
|
||||||
kernel_args=None, memory=1024, vnc=None, arch=None,
|
kernel_args=None, memory=1024, vnc=None, arch=None,
|
||||||
log_check=None, virtio_host="127.0.0.1", virtio_port=6080,
|
cancel_func=None, virtio_host="127.0.0.1", virtio_port=6080,
|
||||||
qcow2=False, boot_uefi=False, ovmf_path=None):
|
qcow2=False, boot_uefi=False, ovmf_path=None):
|
||||||
"""
|
"""
|
||||||
Start the installation
|
Start the installation
|
||||||
@ -211,14 +212,14 @@ class VirtualInstall( object ):
|
|||||||
# TODO: If vnc has been passed, we should look up the port and print that
|
# TODO: If vnc has been passed, we should look up the port and print that
|
||||||
# for the user at this point
|
# for the user at this point
|
||||||
|
|
||||||
while dom.isActive() and not log_check():
|
while dom.isActive() and not (cancel_func and cancel_func()):
|
||||||
sys.stdout.write(".")
|
sys.stdout.write(".")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
sleep(10)
|
sleep(10)
|
||||||
print
|
print
|
||||||
|
|
||||||
if log_check():
|
if cancel_func and cancel_func():
|
||||||
log.info( "Installation error detected. See logfile." )
|
log.info( "Installation error or cancel detected. See logfile." )
|
||||||
else:
|
else:
|
||||||
log.info( "Install finished. Or at least virt shut down." )
|
log.info( "Install finished. Or at least virt shut down." )
|
||||||
|
|
||||||
@ -234,7 +235,8 @@ class VirtualInstall( object ):
|
|||||||
# Undefine the virt, UEFI installs need to have --nvram passed
|
# Undefine the virt, UEFI installs need to have --nvram passed
|
||||||
subprocess.call(["virsh", "undefine", self.virt_name, "--nvram"])
|
subprocess.call(["virsh", "undefine", self.virt_name, "--nvram"])
|
||||||
|
|
||||||
def novirt_install(opts, disk_img, disk_size, repo_url, callback_func=None):
|
|
||||||
|
def novirt_install(opts, disk_img, disk_size, repo_url, cancel_func=None):
|
||||||
"""
|
"""
|
||||||
Use Anaconda to install to a disk image
|
Use Anaconda to install to a disk image
|
||||||
"""
|
"""
|
||||||
@ -282,10 +284,14 @@ def novirt_install(opts, disk_img, disk_size, repo_url, callback_func=None):
|
|||||||
# Create the sparse image
|
# Create the sparse image
|
||||||
mksparse(disk_img, disk_size * 1024**3)
|
mksparse(disk_img, disk_size * 1024**3)
|
||||||
|
|
||||||
|
cancel_funcs = []
|
||||||
|
if cancel_func is not None:
|
||||||
|
cancel_funcs.append(cancel_func)
|
||||||
|
|
||||||
# Make sure anaconda has the right product and release
|
# Make sure anaconda has the right product and release
|
||||||
os.environ["ANACONDA_PRODUCTNAME"] = opts.project
|
os.environ["ANACONDA_PRODUCTNAME"] = opts.project
|
||||||
os.environ["ANACONDA_PRODUCTVERSION"] = opts.releasever
|
os.environ["ANACONDA_PRODUCTVERSION"] = opts.releasever
|
||||||
rc = execWithRedirect("anaconda", args, callback_func=callback_func)
|
rc = execWithRedirect("anaconda", args, callback_func=lambda : any(f() for f in cancel_funcs))
|
||||||
|
|
||||||
# Move the anaconda logs over to a log directory
|
# Move the anaconda logs over to a log directory
|
||||||
log_dir = os.path.abspath(os.path.dirname(opts.logfile))
|
log_dir = os.path.abspath(os.path.dirname(opts.logfile))
|
||||||
@ -306,10 +312,13 @@ def novirt_install(opts, disk_img, disk_size, repo_url, callback_func=None):
|
|||||||
|
|
||||||
if disk_img:
|
if disk_img:
|
||||||
dm_name = os.path.splitext(os.path.basename(disk_img))[0]
|
dm_name = os.path.splitext(os.path.basename(disk_img))[0]
|
||||||
dm_path = "/dev/mapper/"+dm_name
|
|
||||||
if os.path.exists(dm_path):
|
log.debug("Removing device-mapper setup on %s", dm_name)
|
||||||
dm_detach(dm_path)
|
for d in sorted(glob.glob("/dev/mapper/"+dm_name+"*"), reverse=True):
|
||||||
loop_detach(get_loop_name(disk_img))
|
dm_detach(d)
|
||||||
|
|
||||||
|
log.debug("Removing loop device for %s", disk_img)
|
||||||
|
loop_detach("/dev/"+get_loop_name(disk_img))
|
||||||
|
|
||||||
# if selinux_enforcing:
|
# if selinux_enforcing:
|
||||||
# selinux.security_setenforce(1)
|
# selinux.security_setenforce(1)
|
||||||
@ -342,7 +351,7 @@ def novirt_install(opts, disk_img, disk_size, repo_url, callback_func=None):
|
|||||||
execWithRedirect("mv", ["-f", qcow2_img, disk_img], raise_err=True)
|
execWithRedirect("mv", ["-f", qcow2_img, disk_img], raise_err=True)
|
||||||
|
|
||||||
|
|
||||||
def virt_install(opts, install_log, disk_img, disk_size):
|
def virt_install(opts, install_log, disk_img, disk_size, cancel_func=None):
|
||||||
"""
|
"""
|
||||||
Use virt-install to install to a disk image
|
Use virt-install to install to a disk image
|
||||||
|
|
||||||
@ -352,6 +361,9 @@ def virt_install(opts, install_log, disk_img, disk_size):
|
|||||||
"""
|
"""
|
||||||
iso_mount = IsoMountpoint(opts.iso, opts.location)
|
iso_mount = IsoMountpoint(opts.iso, opts.location)
|
||||||
log_monitor = LogMonitor(install_log)
|
log_monitor = LogMonitor(install_log)
|
||||||
|
cancel_funcs = [log_monitor.server.log_check]
|
||||||
|
if cancel_func is not None:
|
||||||
|
cancel_funcs.append(cancel_func)
|
||||||
|
|
||||||
kernel_args = ""
|
kernel_args = ""
|
||||||
if opts.kernel_args:
|
if opts.kernel_args:
|
||||||
@ -375,7 +387,7 @@ def virt_install(opts, install_log, disk_img, disk_size):
|
|||||||
try:
|
try:
|
||||||
virt = VirtualInstall(iso_mount, opts.ks, diskimg_path, disk_size,
|
virt = VirtualInstall(iso_mount, opts.ks, diskimg_path, disk_size,
|
||||||
kernel_args, opts.ram, opts.vnc, opts.arch,
|
kernel_args, opts.ram, opts.vnc, opts.arch,
|
||||||
log_check = log_monitor.server.log_check,
|
cancel_func = lambda : any(f() for f in cancel_funcs),
|
||||||
virtio_host = log_monitor.host,
|
virtio_host = log_monitor.host,
|
||||||
virtio_port = log_monitor.port,
|
virtio_port = log_monitor.port,
|
||||||
qcow2=opts.qcow2, boot_uefi=opts.virt_uefi,
|
qcow2=opts.qcow2, boot_uefi=opts.virt_uefi,
|
||||||
@ -391,7 +403,9 @@ def virt_install(opts, install_log, disk_img, disk_size):
|
|||||||
iso_mount.umount()
|
iso_mount.umount()
|
||||||
|
|
||||||
if log_monitor.server.log_check():
|
if log_monitor.server.log_check():
|
||||||
raise InstallError("virt_install failed")
|
raise InstallError("virt_install failed. See logfile.")
|
||||||
|
elif cancel_func and cancel_func():
|
||||||
|
raise InstallError("virt_install canceled by cancel_func")
|
||||||
|
|
||||||
if opts.make_fsimage:
|
if opts.make_fsimage:
|
||||||
mkdiskfsimage(diskimg_path, disk_img, label=opts.fs_label)
|
mkdiskfsimage(diskimg_path, disk_img, label=opts.fs_label)
|
||||||
|
Loading…
Reference in New Issue
Block a user