From 1724ed46650728544374126a0b1ee86d9f64c7db Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Tue, 4 Feb 2020 21:39:53 +0100 Subject: [PATCH] pmbootstrap status: show if chroots are outdated (!1878) Add new "pmbootstrap status" command, which does a quick health check for the work dir. As first health check, verify that the chroots are not too old. Replace the reminder text at the end of "pmbootstrap init" to tell users to run "pmbootstrap status" instead of "pmbootstrap zap" once a day before working with pmbootstrap. Related: #1829 --- pmb/config/init.py | 10 ++++---- pmb/helpers/frontend.py | 6 +++++ pmb/helpers/status.py | 48 +++++++++++++++++++++++++++++++++++++ pmb/parse/arguments.py | 9 +++++++ test/test_helpers_status.py | 43 +++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 pmb/helpers/status.py create mode 100644 test/test_helpers_status.py diff --git a/pmb/config/init.py b/pmb/config/init.py index 594af7ca..4d6931e3 100644 --- a/pmb/config/init.py +++ b/pmb/config/init.py @@ -419,10 +419,8 @@ def frontend(args): # Do not zap any existing packages or cache_http directories pmb.chroot.zap(args, confirm=False) - logging.info( - "WARNING: The applications in the chroots do not get updated automatically.") - logging.info("Run 'pmbootstrap zap' to delete all chroots once a day before" - " working with pmbootstrap!") - logging.info("It only takes a few seconds, and all packages are cached.") - + logging.info("WARNING: The chroots and git repositories in the work dir do" + " not get updated automatically.") + logging.info("Run 'pmbootstrap status' once a day before working with" + " pmbootstrap to make sure that everything is up-to-date.") logging.info("Done!") diff --git a/pmb/helpers/frontend.py b/pmb/helpers/frontend.py index 4281f164..b0865f6d 100644 --- a/pmb/helpers/frontend.py +++ b/pmb/helpers/frontend.py @@ -24,6 +24,7 @@ import pmb.helpers.repo import pmb.helpers.repo_missing import pmb.helpers.run import pmb.helpers.aportupgrade +import pmb.helpers.status import pmb.install import pmb.parse import pmb.qemu @@ -427,3 +428,8 @@ def lint(args): for package in packages: pmb.helpers.lint.check(args, package) + + +def status(args): + if not pmb.helpers.status.print_status(args, args.details): + sys.exit(1) diff --git a/pmb/helpers/status.py b/pmb/helpers/status.py new file mode 100644 index 00000000..df7bb655 --- /dev/null +++ b/pmb/helpers/status.py @@ -0,0 +1,48 @@ +# Copyright 2020 Oliver Smith +# SPDX-License-Identifier: GPL-3.0-or-later +import logging + +import pmb.config.workdir + + +def print_checks_chroots_outdated(args, details): + """ Check if chroots were zapped recently. + :param details: if True, print each passing check instead of a summary + :returns: list of unresolved checklist items """ + if pmb.config.workdir.chroots_outdated(args): + logging.info("[NOK] Chroots not zapped recently") + return ["Run 'pmbootststrap zap' to delete possibly outdated chroots"] + elif details: + logging.info("[OK ] Chroots zapped recently (or non-existing)") + return [] + + +def print_checks(args, details): + """ :param details: if True, print each passing check instead of a summary + :returns: True if all checks passed, False otherwise """ + logging.info("*** CHECKS ***") + checklist = [] + checklist += print_checks_chroots_outdated(args, details) + + # All OK + if not checklist: + if not details: + logging.info("All checks passed! \\o/") + logging.info("") + return True + + # Some NOK: print checklist + logging.info("") + logging.info("*** CHECKLIST ***") + for item in checklist: + logging.info("- " + item) + logging.info("- Run 'pmbootstrap status' to verify that all is resolved") + return False + + +def print_status(args, details=False): + """ :param details: if True, print each passing check instead of a summary + :returns: True if all checks passed, False otherwise """ + ret = print_checks(args, details) + + return ret diff --git a/pmb/parse/arguments.py b/pmb/parse/arguments.py index dcc305aa..647ac096 100644 --- a/pmb/parse/arguments.py +++ b/pmb/parse/arguments.py @@ -274,6 +274,14 @@ def arguments_lint(subparser): add_packages_arg(lint, nargs="*") +def arguments_status(subparser): + ret = subparser.add_parser("status", + help="quick health check for the work dir") + ret.add_argument("--details", action="store_true", + help="list passing checks in detail, not as summary") + return ret + + def package_completer(prefix, action, parser, parsed_args): args = parsed_args pmb.config.merge_with_args(args) @@ -387,6 +395,7 @@ def arguments(): arguments_aportupgrade(sub) arguments_newapkbuild(sub) arguments_lint(sub) + arguments_status(sub) # Action: log log = sub.add_parser("log", help="follow the pmbootstrap logfile") diff --git a/test/test_helpers_status.py b/test/test_helpers_status.py new file mode 100644 index 00000000..591fd79a --- /dev/null +++ b/test/test_helpers_status.py @@ -0,0 +1,43 @@ +# Copyright 2020 Oliver Smith +# SPDX-License-Identifier: GPL-3.0-or-later +""" Test pmb/helpers/status.py """ +import pytest +import sys + +import pmb_test # noqa +import pmb.config +import pmb.config.workdir + + +@pytest.fixture +def args(request): + import pmb.parse + sys.argv = ["pmbootstrap", "init"] + args = pmb.parse.arguments() + args.log = args.work + "/log_testsuite.txt" + pmb.helpers.logging.init(args) + request.addfinalizer(args.logfd.close) + return args + + +def test_pmbootstrap_status(args, tmpdir): + """ High level testing of 'pmbootstrap status': run it twice, once with + a fine workdir, and once where one check is failing. """ + # Prepare empty workdir + work = str(tmpdir) + with open(work + "/version", "w") as handle: + handle.write(str(pmb.config.work_version)) + + # "pmbootstrap status" succeeds (pmb.helpers.run.user verifies exit 0) + pmbootstrap = pmb.config.pmb_src + "/pmbootstrap.py" + pmb.helpers.run.user(args, [pmbootstrap, "-w", work, "status", + "--details"]) + + # Mark chroot_native as outdated + with open(work + "/workdir.cfg", "w") as handle: + handle.write("[chroot-init-dates]\nnative = 1234\n") + + # "pmbootstrap status" fails + ret = pmb.helpers.run.user(args, [pmbootstrap, "-w", work, "status"], + check=False) + assert ret == 1