diff --git a/lorax.spec b/lorax.spec index 96eb71eb..a650650b 100644 --- a/lorax.spec +++ b/lorax.spec @@ -117,6 +117,7 @@ rm -f $RPM_BUILD_ROOT/%{_tmpfilesdir}/lorax-composer.conf %{_datadir}/lorax/* %exclude %{_datadir}/lorax/composer %{_mandir}/man1/*.1* +%{_tmpfilesdir}/lorax.conf %changelog * Wed Aug 15 2018 Brian C. Lane 19.7.19-1 diff --git a/setup.py b/setup.py index 62e1ac10..da7d4e1c 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,8 @@ data_files = [("/etc/lorax", ["etc/lorax.conf"]), ("/etc/lorax", ["etc/composer.conf"]), ("/usr/lib/systemd/system", ["systemd/lorax-composer.service", "systemd/lorax-composer.socket"]), - ("/usr/lib/tmpfiles.d/", ["systemd/lorax-composer.conf"])] + ("/usr/lib/tmpfiles.d/", ["systemd/lorax-composer.conf", + "systemd/lorax.conf"])] # shared files for root, dnames, fnames in os.walk("share"): diff --git a/src/sbin/lorax b/src/sbin/lorax index 41f07642..eacdecc5 100755 --- a/src/sbin/lorax +++ b/src/sbin/lorax @@ -30,6 +30,9 @@ pylorax_log = logging.getLogger("pylorax") yum_log = logging.getLogger("yum") +import atexit +import fcntl +from glob import glob import sys import os import shutil @@ -46,6 +49,42 @@ from pylorax import DRACUT_DEFAULT VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), pylorax.vernum) +def exit_handler(tempdir): + """Handle cleanup of tmpdir, if it still exists + """ + if not tempdir: + return + if os.path.exists(tempdir): + log.info("Cleaning up tempdir - %s", tempdir) + shutil.rmtree(tempdir) + + +def remove_tempdirs(): + """Delete all unlocked tempdirs under tempfile.gettempdir + + When lorax crashes it can leave behind tempdirs, which cannot be cleaned up by + systemd-tmpfiles (SELinux restricts a complete cleanup). + + So we lock them while in use and cleanup all the ones that are not locked + when lorax starts. + """ + for d in glob(os.path.join(tempfile.gettempdir(), "lorax.*")): + if not os.path.isdir(d): + continue + try: + dir_fd = os.open(d, os.O_RDONLY|os.O_DIRECTORY) + fcntl.flock(dir_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except IOError: + # lock failed, skip this directory + os.close(dir_fd) + continue + + # Lock succeeded, remove the directory + log.info("Removing old tempdir %s", d) + shutil.rmtree(d) + os.close(dir_fd) + + def setup_logging(opts): # Setup logging to console and to logfile log.setLevel(logging.DEBUG) @@ -134,7 +173,7 @@ def main(args): action="store_false", default=True, dest="doupgrade") optional.add_option("--logfile", default="./lorax.log", help="Path to logfile") - optional.add_option("--tmp", default="/var/tmp", + optional.add_option("--tmp", default="/var/tmp/lorax", help="Top level temporary directory" ) optional.add_option("--add-template", dest="add_templates", action="append", help="Additional template for runtime image", @@ -196,10 +235,20 @@ def main(args): setup_logging(opts) log.info("Lorax %s", pylorax.vernum) + + if not os.path.exists(opts.tmp): + os.makedirs(opts.tmp) + tempfile.tempdir = opts.tmp + # Remove any orphaned lorax tempdirs + remove_tempdirs() + # create the temporary directory for lorax - tempdir = tempfile.mkdtemp(prefix="lorax.", dir=tempfile.gettempdir()) + tempdir = tempfile.mkdtemp(prefix="lorax.") + + # register an exit handler to cleanup the temporary directory + atexit.register(exit_handler, tempdir) # create the yumbase object installtree = os.path.join(tempdir, "installtree") @@ -207,6 +256,10 @@ def main(args): yumtempdir = os.path.join(tempdir, "yum") os.mkdir(yumtempdir) + # Obtain an exclusive lock on the tempdir + dir_fd = os.open(tempdir, os.O_RDONLY|os.O_DIRECTORY) + fcntl.flock(dir_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + yb = get_yum_base_object(installtree, opts.source, opts.mirrorlist, opts.repo_files, yumtempdir, opts.proxy, opts.excludepkgs, @@ -246,6 +299,9 @@ def main(args): remove_temp=True, user_dracut_args=opts.dracut_args) + # Release the lock on the tempdir + os.close(dir_fd) + def get_yum_base_object(installroot, repositories, mirrorlists=None, repo_files=None, tempdir="/var/tmp", proxy=None, excludepkgs=None, diff --git a/systemd/lorax.conf b/systemd/lorax.conf new file mode 100644 index 00000000..f720ceb4 --- /dev/null +++ b/systemd/lorax.conf @@ -0,0 +1,3 @@ +# Prevent systemd from removing installtree files +# This should eventually be fixed by - https://github.com/systemd/systemd/pull/11482 +x /var/tmp/lorax 750 root root