forked from Mirror/pmbootstrap
zap -m: * APKINDEX parsing: parse the "origin" field as well, so we know where a subpackage comes from * pmbootstrap zap -m: properly delete all packages, that do not have an aport or where the aport has another version. This also works with subpackages now, we use the origin field to resolve it. * Only reindex when packages have been deleted in "zap -m" zap in general: * Show the amount of cleared up space after the deletion instead of "Done" * Print "Shutdown complete" to "pmbootstrap log" instead of stdout (we need to call it twice during zap now to get the space calculation right) * Add `--dry` argument to `pmbootstrap zap` (this was very useful for debugging) to list the packages/chroots that would get deleted * Roughly output the command that would get executed to delete files, so it's obvious what's going on in --dry mode. (% rm ...)
97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
"""
|
|
Copyright 2018 Oliver Smith
|
|
|
|
This file is part of pmbootstrap.
|
|
|
|
pmbootstrap is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
pmbootstrap is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
import logging
|
|
import glob
|
|
import os
|
|
import socket
|
|
from contextlib import closing
|
|
|
|
import pmb.chroot
|
|
import pmb.chroot.distccd
|
|
import pmb.helpers.mount
|
|
import pmb.install.losetup
|
|
import pmb.parse.arch
|
|
|
|
|
|
def kill_adb(args):
|
|
"""
|
|
Kill adb daemon if it's running.
|
|
"""
|
|
port = 5038
|
|
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
|
if sock.connect_ex(("127.0.0.1", port)) == 0:
|
|
pmb.chroot.root(args, ["adb", "-P", str(port), "kill-server"])
|
|
|
|
|
|
def shutdown_cryptsetup_device(args, name):
|
|
"""
|
|
:param name: cryptsetup device name, usually "pm_crypt" in pmbootstrap
|
|
"""
|
|
if not os.path.exists(args.work + "/chroot_native/dev/mapper/" + name):
|
|
return
|
|
pmb.chroot.apk.install(args, ["cryptsetup"])
|
|
status = pmb.chroot.root(args, ["cryptsetup", "status", name], check=False,
|
|
return_stdout=True)
|
|
if not status:
|
|
logging.warning("WARNING: Failed to run cryptsetup to get the status"
|
|
" for " + name + ", assuming it is not mounted"
|
|
" (shutdown fails later if it is)!")
|
|
return
|
|
|
|
if status.startswith("/dev/mapper/" + name + " is active."):
|
|
pmb.chroot.root(args, ["cryptsetup", "luksClose", name])
|
|
elif status.startswith("/dev/mapper/" + name + " is inactive."):
|
|
# When "cryptsetup status" fails, the device is not mounted and we
|
|
# have a left over file (#83)
|
|
pmb.chroot.root(args, ["rm", "/dev/mapper/" + name])
|
|
else:
|
|
raise RuntimeError("Failed to parse 'cryptsetup status' output!")
|
|
|
|
|
|
def shutdown(args, only_install_related=False):
|
|
pmb.chroot.distccd.stop(args)
|
|
|
|
# Stop adb server
|
|
kill_adb(args)
|
|
|
|
# Umount installation-related paths (order is important!)
|
|
pmb.helpers.mount.umount_all(args, args.work +
|
|
"/chroot_native/mnt/install")
|
|
shutdown_cryptsetup_device(args, "pm_crypt")
|
|
|
|
# Umount all losetup mounted images
|
|
chroot = args.work + "/chroot_native"
|
|
if pmb.helpers.mount.ismount(chroot + "/dev/loop-control"):
|
|
pattern = chroot + "/home/pmos/rootfs/*.img"
|
|
for path_outside in glob.glob(pattern):
|
|
path = path_outside[len(chroot):]
|
|
pmb.install.losetup.umount(args, path)
|
|
|
|
# Umount device rootfs chroot
|
|
chroot_rootfs = args.work + "/chroot_rootfs_" + args.device
|
|
if os.path.exists(chroot_rootfs):
|
|
pmb.helpers.mount.umount_all(args, chroot_rootfs)
|
|
|
|
if not only_install_related:
|
|
# Clean up the rest
|
|
pmb.helpers.mount.umount_all(args, args.work)
|
|
for arch in pmb.config.build_device_architectures:
|
|
if pmb.parse.arch.cpu_emulation_required(args, arch):
|
|
pmb.chroot.binfmt.unregister(args, arch)
|
|
logging.debug("Shutdown complete")
|