The module entropy_path_loader (used only for running from within the checkout; otherwise not even installed) is made to provide the _entropy namespace. (Other ideas instead of this entropy_path_loader change would be to reorganise files layout; drop support for running from the checkout as is - and perhaps require virtualenvs; require sourcing a script that sets PYTHONPATH. However, as implemented, it is not intrusive, and the good part is that it is quite isolated, not used in normal usage after installation. Basically, it only does sys.path + provides _entropy namespace.)
186 lines
6.2 KiB
Python
Executable File
186 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"))
|
|
import entropy_path_loader
|
|
del osp
|
|
|
|
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 _entropy.solo.commands.install import SoloInstall
|
|
from _entropy.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)
|