2017-05-26 20:08:45 +00:00
|
|
|
"""
|
2020-01-06 01:40:27 +00:00
|
|
|
Copyright 2020 Oliver Smith
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
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
|
2017-08-24 21:07:36 +00:00
|
|
|
import socket
|
|
|
|
from contextlib import closing
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
import pmb.chroot
|
|
|
|
import pmb.chroot.distccd
|
2017-07-26 19:01:44 +00:00
|
|
|
import pmb.helpers.mount
|
|
|
|
import pmb.install.losetup
|
|
|
|
import pmb.parse.arch
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
|
2017-08-24 21:07:36 +00:00
|
|
|
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"])
|
|
|
|
|
|
|
|
|
2017-06-12 23:34:20 +00:00
|
|
|
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"])
|
2018-07-14 01:13:28 +00:00
|
|
|
status = pmb.chroot.root(args, ["cryptsetup", "status", name],
|
|
|
|
output_return=True, check=False)
|
2017-07-21 21:44:28 +00:00
|
|
|
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
|
|
|
|
|
2017-06-12 23:34:20 +00:00
|
|
|
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!")
|
|
|
|
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
def shutdown(args, only_install_related=False):
|
|
|
|
pmb.chroot.distccd.stop(args)
|
|
|
|
|
2017-08-24 21:07:36 +00:00
|
|
|
# Stop adb server
|
|
|
|
kill_adb(args)
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
# Umount installation-related paths (order is important!)
|
|
|
|
pmb.helpers.mount.umount_all(args, args.work +
|
|
|
|
"/chroot_native/mnt/install")
|
2017-06-12 23:34:20 +00:00
|
|
|
shutdown_cryptsetup_device(args, "pm_crypt")
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
# Umount all losetup mounted images
|
|
|
|
chroot = args.work + "/chroot_native"
|
|
|
|
if pmb.helpers.mount.ismount(chroot + "/dev/loop-control"):
|
2017-10-12 20:08:10 +00:00
|
|
|
pattern = chroot + "/home/pmos/rootfs/*.img"
|
2017-05-26 20:08:45 +00:00
|
|
|
for path_outside in glob.glob(pattern):
|
|
|
|
path = path_outside[len(chroot):]
|
|
|
|
pmb.install.losetup.umount(args, path)
|
|
|
|
|
2017-08-18 19:19:48 +00:00
|
|
|
# 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)
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
if not only_install_related:
|
pmb: fix test suite not running through twice
The test suite needed a `pmbootstrap shutdown` after running through,
before it could successfully run again.
Explanation:
This was caused by `test/test_pkgrel_bump.py`, which creates a
temporary work folder with every subfolder ("chroot_native",
"cache_apk_x86_64", ...) linked to the original work folder except for
the "packages" folder. At the end of the test case,
`pmbootstrap shutdown` gets executed and is expected to umount
everything as usual. But it does not umount anything because of the
symlinks, so `work/chroot_native/mnt/pmbootstrap-packages` points to
the fake packages folder of that test case, even after it is finished.
As a result, any test case that tries to access the packages folder in
the native chroot, will fail until `pmbootstrap shutdown` gets called.
Detailed Changes:
* Umount all folders inside the work folder, even if these are symlinks
* Remove obsolete reference to "disable timestamp based rebuilds" in a
comment in `test/test_pkgrel_bump.py`
* Run `pmbootstrap work_migrate` and `pmbootstrap shutdown` at the
beginning of `test/testcases_fast.sh`, in case the pkgrel_bump test
case was aborted before it could properly shutdown and to make it
more robust in general (user may have changed the mountpoints, work
folder may need to be migrated)
2018-07-14 00:38:33 +00:00
|
|
|
# Umount all folders inside args.work
|
|
|
|
# The folders are explicitly iterated over, so folders symlinked inside
|
|
|
|
# args.work get umounted as well (used in test_pkgrel_bump.py, #1595)
|
|
|
|
for path in glob.glob(args.work + "/*"):
|
|
|
|
pmb.helpers.mount.umount_all(args, path)
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
# Clean up the rest
|
2017-10-25 22:54:17 +00:00
|
|
|
for arch in pmb.config.build_device_architectures:
|
|
|
|
if pmb.parse.arch.cpu_emulation_required(args, arch):
|
|
|
|
pmb.chroot.binfmt.unregister(args, arch)
|
2018-01-31 19:34:02 +00:00
|
|
|
logging.debug("Shutdown complete")
|