From 4eba2347c59e6d9818b3ded2eb9d2aa13d5e1780 Mon Sep 17 00:00:00 2001 From: Sebastien Luttringer <sebastien.luttringer@smartjog.com> Date: Thu, 15 Dec 2011 12:28:06 +0100 Subject: [PATCH] add istrick file in {,un}prepare_chroot functions prepare and uprepare chroot functions now track non existant files preparing are now done more carrefully about tricks --- installsystems/tools.py | 99 +++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 29 deletions(-) diff --git a/installsystems/tools.py b/installsystems/tools.py index 757ffd2..c15e189 100644 --- a/installsystems/tools.py +++ b/installsystems/tools.py @@ -373,27 +373,38 @@ def prepare_chroot(path, mount=True): check_call(["mount", "--bind", origin, target], close_fds=True) except CalledProcessError as e: warn("Mount failed: %s.\n" % e) - arrow("Cheating") + arrow("Tricks") + exists = os.path.exists + join = os.path.join # check path is a kind of linux FHS - if not os.path.exists(os.path.join(path, "etc")) or not os.path.exists(os.path.join(path, "usr")): + if not exists(join(path, "etc")) or not exists(join(path, "usr")): return # trick resolv.conf try: - if os.path.exists("/etc/resolv.conf"): + resolv_path = join(path, "etc", "resolv.conf") + resolv_backup_path = join(path, "etc", "resolv.conf.isbackup") + resolv_trick_path = join(path, "etc", "resolv.conf.istrick") + if (exists("/etc/resolv.conf") + and not exists(resolv_backup_path) + and not exists(resolv_trick_path)): arrow("resolv.conf", 1) - resolv_path = os.path.join(path, "etc", "resolv.conf") - if os.path.exists(resolv_path): - os.rename(resolv_path, "%s.isbackup" % resolv_path) + if exists(resolv_path): + os.rename(resolv_path, resolv_backup_path) + else: + open(resolv_trick_path, "wb") shutil.copy("/etc/resolv.conf", resolv_path) except Exception as e: warn("resolv.conf tricks fail: %s" % e) # trick mtab try: - mtab_path = os.path.join(path, "etc", "mtab") - arrow("mtab", 1) - if os.path.exists(mtab_path): - os.rename(mtab_path, "%s.isbackup" % mtab_path) - os.symlink("/proc/self/mounts", mtab_path) + mtab_path = join(path, "etc", "mtab") + mtab_backup_path = join(path, "etc", "mtab.isbackup") + mtab_trick_path = join(path, "etc", "mtab.istrick") + if not exists(mtab_backup_path) and not exists(mtab_trick_path): + arrow("mtab", 1) + if os.path.exists(mtab_path): + os.rename(mtab_path, mtab_backup_path) + os.symlink("/proc/self/mounts", mtab_path) except Exception as e: warn("mtab tricks fail: %s" % e) # try to guest distro @@ -402,10 +413,10 @@ def prepare_chroot(path, mount=True): if distro == "debian": arrow("Debian specific", 1) # create a chroot header - try: open(os.path.join(path, "etc", "debian_chroot"), "w").write("CHROOT") + try: open(join(path, "etc", "debian_chroot"), "w").write("CHROOT") except: pass # fake policy-rc.d. It must exit 101, it's an expected exitcode. - policy_path = os.path.join(path, "usr", "sbin", "policy-rc.d") + policy_path = join(path, "usr", "sbin", "policy-rc.d") try: open(policy_path, "w").write("#!/bin/bash\nexit 101\n") except: pass # policy-rc.d needs to be executable @@ -415,38 +426,68 @@ def unprepare_chroot(path, mount=True): ''' Rollback preparation of a chroot environment inside a directory ''' - arrow("Uncheating") + arrow("Untricks") + exists = os.path.exists + join = os.path.join # check path is a kind of linux FHS - if os.path.exists(os.path.join(path, "etc")) and os.path.exists(os.path.join(path, "usr")): + if exists(os.path.join(path, "etc")) and exists(os.path.join(path, "usr")): # untrick mtab - mtab_path = os.path.join(path, "etc", "mtab") - arrow("mtab", 1) - if os.path.exists(mtab_path): - os.unlink(mtab_path) - if os.path.exists("%s.isbackup" % mtab_path): - os.rename("%s.isbackup" % mtab_path, mtab_path) + mtab_path = join(path, "etc", "mtab") + mtab_backup_path = join(path, "etc", "mtab.isbackup") + mtab_trick_path = join(path, "etc", "mtab.istrick") + if exists(mtab_backup_path) or exists(mtab_trick_path): + arrow("mtab", 1) + # order matter ! + if exists(mtab_trick_path): + try: os.unlink(mtab_path) + except OSError: pass + try: + os.unlink(mtab_trick_path) + except OSError: + warn("Unable to remove %s" % mtab_trick_path) + if exists(mtab_backup_path): + try: os.unlink(mtab_path) + except OSError: pass + try: + os.rename(mtab_backup_path, mtab_path) + except OSError: + warn("Unable to restore %s" % mtab_backup_path) + # untrick resolv.conf - if os.path.exists("/etc/resolv.conf"): + resolv_path = join(path, "etc", "resolv.conf") + resolv_backup_path = join(path, "etc", "resolv.conf.isbackup") + resolv_trick_path = join(path, "etc", "resolv.conf.istrick") + if exists(resolv_backup_path) or exists(resolv_trick_path): arrow("resolv.conf", 1) - resolv_path = os.path.join(path, "etc", "resolv.conf") - if os.path.exists(resolv_path): - os.unlink(resolv_path) - if os.path.exists("%s.isbackup" % resolv_path): - os.rename("%s.isbackup" % resolv_path, resolv_path) + # order matter ! + if exists(resolv_trick_path): + try: os.unlink(resolv_path) + except OSError: pass + try: + os.unlink(resolv_trick_path) + except OSError: + warn("Unable to remove %s" % resolv_trick_path) + if exists(resolv_backup_path): + try: os.unlink(resolv_path) + except OSError: pass + try: + os.rename(resolv_backup_path, resolv_path) + except OSError: + warn("Unable to restore %s" % resolv_backup_path) # try to guest distro distro = guess_distro(path) # cleaning debian stuff if distro == "debian": arrow("Debian specific", 1) for f in ("etc/debian_chroot", "usr/sbin/policy-rc.d"): - try: os.unlink(os.path.join(path, f)) + try: os.unlink(join(path, f)) except: pass # unmounting if mount: mps = ("proc", "sys", "dev", "dev/pts", "dev/shm") arrow("Unmouting filesystems") for mp in reversed(mps): - target = os.path.join(path, mp) + target = join(path, mp) if os.path.ismount(target): arrow(target, 1) call(["umount", target], close_fds=True) -- GitLab