lorax-composer: Cancel running Anaconda process
It ends up that this isn't as easy as you'd think. Anaconda sets up some signal handlers to handle cleanly exiting, but they are not being run when sent a TERM after package installation has started. I think DNF resets them causing it to get ignored. When the cancel is sent it can take several minutes for it to have an effect. In my testing it usually takes around 2 minutes for anaconda to notice and exit. This sends a TERM to the process and then waits for it to exit. When it returns it then removed any device-mapper devices that were setup for image installations, removes any hanging loop devices. It then kills off any process with pyanaconda. in the cmdline, and anaconda-bus.conf (because anaconda starts a bunch of helpers and if it doesn't shut down cleanly they remain running). Resolves: rhbz#1656691
This commit is contained in:
parent
850ad9845a
commit
42addfc2b5
@ -21,9 +21,9 @@ import glob
|
|||||||
import json
|
import json
|
||||||
from math import ceil
|
from math import ceil
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
# Use the Lorax treebuilder branch for iso creation
|
# Use the Lorax treebuilder branch for iso creation
|
||||||
@ -285,7 +285,10 @@ def novirt_cancel_check(cancel_funcs, proc):
|
|||||||
"""
|
"""
|
||||||
for f in cancel_funcs:
|
for f in cancel_funcs:
|
||||||
if f():
|
if f():
|
||||||
|
log.info("Terminating process %d", proc.pid)
|
||||||
proc.terminate()
|
proc.terminate()
|
||||||
|
|
||||||
|
# NOTE: Have to return and allow execReadlines to call proc.communicate()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -386,6 +389,7 @@ def novirt_install(opts, disk_img, disk_size, cancel_func=None):
|
|||||||
for line in execReadlines("anaconda", args, reset_lang=False,
|
for line in execReadlines("anaconda", args, reset_lang=False,
|
||||||
env_add={"ANACONDA_PRODUCTNAME": opts.project,
|
env_add={"ANACONDA_PRODUCTNAME": opts.project,
|
||||||
"ANACONDA_PRODUCTVERSION": opts.releasever},
|
"ANACONDA_PRODUCTVERSION": opts.releasever},
|
||||||
|
reset_handlers=False,
|
||||||
callback=lambda p: not novirt_cancel_check(cancel_funcs, p)):
|
callback=lambda p: not novirt_cancel_check(cancel_funcs, p)):
|
||||||
log.info(line)
|
log.info(line)
|
||||||
|
|
||||||
@ -441,6 +445,12 @@ def novirt_install(opts, disk_img, disk_size, cancel_func=None):
|
|||||||
log.debug("Removing loop device for %s", disk_img)
|
log.debug("Removing loop device for %s", disk_img)
|
||||||
loop_detach("/dev/"+get_loop_name(disk_img))
|
loop_detach("/dev/"+get_loop_name(disk_img))
|
||||||
|
|
||||||
|
# When anaconda crashes or is canceled it leaves pyanaconda.* running
|
||||||
|
execWithRedirect("pkill", ["-f", "pyanaconda."])
|
||||||
|
|
||||||
|
# It can also leave dbus running
|
||||||
|
execWithRedirect("pkill", ["-f", "anaconda-bus.conf"])
|
||||||
|
|
||||||
# qemu disk image is used by bare qcow2 images and by Vagrant
|
# qemu disk image is used by bare qcow2 images and by Vagrant
|
||||||
if opts.image_type:
|
if opts.image_type:
|
||||||
log.info("Converting %s to %s", disk_img, opts.image_type)
|
log.info("Converting %s to %s", disk_img, opts.image_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user