Files
entropy/client/kernel-switcher
Sławomir Nizio 41ba9b6d63 [*] be strict about Python modules paths being loaded
For convenience (seemingly, and it really is convenient) equo and other
tools can be run from the checkout, and Entropy modules are loaded from
the checkout. Now there is a strict separation when system paths and
when paths from the checkout are used.

It makes it a bit more robust, secure and preditable at the cost of
a little more complexity.

A pleasant side effect of this change is that it is not required to
change directory to the tool (to use non-system one), as paths in the
checkout are relative to scripts.

Imports in lib/tests were not adjusted.
2018-10-27 13:03:58 +02:00

188 lines
6.2 KiB
Python
Executable File

#!/usr/bin/python
import sys
import os
from os import path as osp
_base = osp.dirname(osp.dirname(osp.realpath(__file__)))
if os.path.isfile(osp.join(_base, "entropy-in-vcs-checkout")):
sys.path.insert(0, osp.join(_base, "entropy_path_loader"))
else:
sys.path.insert(0, "/usr/lib/entropy/entropy_path_loader")
del osp
import entropy_path_loader
import argparse
from entropy.locks import EntropyResourcesLock
from entropy.output import brown, print_warning, print_error, teal
from entropy.i18n import _
from entropy.client.interfaces import Client
import entropy.dep
import entropy.tools
from solo.commands.install import SoloInstall
from solo.utils import print_package_info
import kswitch
if __name__ == "__main__":
app_name = os.path.basename(sys.argv[0])
parser = argparse.ArgumentParser(
description=_("Sabayon Kernel Switcher"),
formatter_class=argparse.RawDescriptionHelpFormatter,
prog=app_name)
def _add_standard_args(_parser, restricted):
_parser.add_argument("--quiet", "-q", action="store_true",
default=False,
help=_("quiet mode"))
_parser.add_argument("--verbose", "-v", action="store_true",
default=False,
help=_("verbose mode"))
if not restricted:
_parser.add_argument("--ask", "-a", action="store_true",
default=False,
help=_("ask confirmation"))
_parser.add_argument("--pretend", "-p", action="store_true",
default=False,
help=_("just show what would be done"))
subparsers = parser.add_subparsers(
title="kernel-switcher",
description=_("available commands"))
def _wrap_locked_api(method, *args, **kwargs):
etp_client = None
acquired = False
lock = EntropyResourcesLock(output=Client)
try:
lock.acquire_shared()
acquired = True
etp_client = Client()
return method(etp_client, *args, **kwargs)
finally:
if etp_client is not None:
etp_client.shutdown()
if acquired:
lock.release()
def _switch_kernel(f_nsargs):
def _install(etp_client, matches):
install = SoloInstall([])
inst_rc, _show_cfgupd = install._install_action(
etp_client, True, True,
f_nsargs.pretend, f_nsargs.ask, f_nsargs.verbose,
f_nsargs.quiet, False, False, False, False, False,
False, False, 1, [], package_matches=list(matches))
if _show_cfgupd:
install._show_config_files_update(etp_client)
install._show_preserved_libraries(etp_client)
if f_nsargs.pretend:
# this won't trigger any post install action
return 1
return inst_rc
def _switch(etp_client):
switcher = kswitch.KernelSwitcher(etp_client)
kernel_package = f_nsargs.kernel
pkg_id, pkg_repo = etp_client.atom_match(kernel_package)
if pkg_id == -1:
print_error("%s: %s" % (
brown(_("Package does not exist")),
teal(kernel_package),))
return 1
kernel_match = (pkg_id, pkg_repo)
kernel_matches = switcher.list()
if kernel_match not in kernel_matches:
print_error(
"%s: %s" % (brown(_("Not a kernel")),
teal(kernel_package),))
return 1
try:
return switcher.switch(
kernel_match, _install,
from_running=f_nsargs.from_running)
except kswitch.CannotFindRunningKernel:
print_error(
brown(_("Cannot find your currently running kernel.")))
print_error(
brown(_("Try without --from-running.")))
return 1
if not entropy.tools.is_root():
print_error(
brown(_("superuser access required")))
return 1
return _wrap_locked_api(_switch)
def _list_kernels(f_nsargs):
def _list(etp_client):
switcher = kswitch.KernelSwitcher(etp_client)
kernels = switcher.list()
if not kernels:
print_warning(_("No kernel packages found"))
return 1
inst_repo = etp_client.installed_repository()
with inst_repo.shared():
for pkg_id, pkg_repo in kernels:
repo = etp_client.open_repository(pkg_repo)
print_package_info(
pkg_id, etp_client, repo,
show_repo_if_quiet = True,
extended=f_nsargs.verbose,
quiet=f_nsargs.quiet)
return 0
return _wrap_locked_api(_list)
switch_parser = subparsers.add_parser(
"switch", help=_("install a new or just another kernel"))
switch_parser.set_defaults(func=_switch_kernel)
switch_parser.add_argument(
"--from-running", action="store_true",
default=False,
help=_("use 'uname -r' to determine the running kernel"))
switch_parser.add_argument(
"kernel", metavar="<kernel>",
help=_("the new kernel package dependency name"))
_add_standard_args(switch_parser, False)
list_parser = subparsers.add_parser(
"list", help=_("list kernels"))
list_parser.set_defaults(func=_list_kernels)
_add_standard_args(list_parser, True)
help_parser = subparsers.add_parser(
"help", help=_("this help"))
def _print_help(*_args):
parser.print_help()
help_parser.set_defaults(func=_print_help)
try:
nsargs = parser.parse_args(sys.argv[1:])
except IOError as err:
parser.print_help()
raise SystemExit(1)
# Python 3.3 bug #16308
if not hasattr(nsargs, "func"):
parser.print_help()
raise SystemExit(1)
try:
rc = nsargs.func(nsargs)
except KeyboardInterrupt:
rc = 1
raise SystemExit(rc)