Files
entropy/client/solo/commands/update.py
T
Sławomir Nizio 7cf7e1f6b7 convert solo imports, with needed changes to entropy_path_loader
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.)
2018-11-26 20:15:36 +01:00

297 lines
8.5 KiB
Python

# -*- coding: utf-8 -*-
"""
@author: Fabio Erculiani <lxnay@sabayon.org>
@contact: lxnay@sabayon.org
@copyright: Fabio Erculiani
@license: GPL-2
B{Entropy Command Line Client}.
"""
import sys
import argparse
from entropy.i18n import _
from entropy.output import darkred, red, brown, purple, teal, blue, \
darkgreen, bold
from entropy.misc import ParallelTask
from entropy.const import etpConst, const_debug_write
from entropy.services.client import WebService
from entropy.client.interfaces.noticeboard import NoticeBoard
import entropy.tools
from _entropy.solo.commands.descriptor import SoloCommandDescriptor
from _entropy.solo.commands.command import SoloCommand
class SoloUpdate(SoloCommand):
"""
Main Solo Update command.
"""
NAME = "update"
ALIASES = ["up"]
ALLOW_UNPRIVILEGED = True
INTRODUCTION = """\
Update Entropy Repositories.
"""
SEE_ALSO = ""
def __init__(self, args):
SoloCommand.__init__(self, args)
self._force = False
self._repositories = []
def man(self):
"""
Overridden from SoloCommand.
"""
return self._man()
def _get_parser(self):
"""
Overridden from SoloCommand.
"""
descriptor = SoloCommandDescriptor.obtain_descriptor(
SoloUpdate.NAME)
parser = argparse.ArgumentParser(
description=descriptor.get_description(),
formatter_class=argparse.RawDescriptionHelpFormatter,
prog="%s %s" % (sys.argv[0], SoloUpdate.NAME))
parser.add_argument("repo", nargs='*', default=None,
metavar="<repo>", help=_("repository"))
parser.add_argument("--force", action="store_true",
default=self._force,
help=_("force update"))
return parser
def parse(self):
"""
Parse command
"""
parser = self._get_parser()
try:
nsargs = parser.parse_args(self._args)
except IOError as err:
sys.stderr.write("%s\n" % (err,))
return parser.print_help, []
self._force = nsargs.force
self._repositories += nsargs.repo
return self._call_exclusive, [self._update]
def bashcomp(self, last_arg):
"""
Overridden from SoloCommand.
"""
import sys
entropy_client = self._entropy_bashcomp()
repos = entropy_client.repositories()
outcome = ["--force"] + repos
return self._bashcomp(sys.stdout, last_arg, outcome)
def _update(self, entropy_client):
"""
Command implementation.
"""
er_txt = "%s: %s" % (
darkred(_("You must be either root or in this group:")),
etpConst['sysgroup'],)
if not entropy.tools.is_user_in_entropy_group():
entropy_client.output(
er_txt,level="error",
importance=1)
return 1
if not entropy.tools.is_root():
rc = self._dbus_update(entropy_client)
else:
rc = self._normal_update(entropy_client)
return rc
def _dbus_update(self, entropy_client):
"""
Execute update through RigoDaemon.
"""
info_txt = \
_("Sending the update request to Entropy Services")
info_txt2 = _("Repositories will be updated in background")
entropy_client.output(purple(info_txt))
entropy_client.output(teal(info_txt2))
def bail_out(err):
entropy_client.output(
"%s%s" % (
darkred(" @@ "),
brown(_("app-admin/rigo-daemon not installed. "
"Update not allowed.")),),
level="error", importance=1)
if err:
entropy_client.output(
"%s" % (err,), level="error", importance=1)
# try with introspection first, Gtk3.x stuff
glib_err = None
try:
from gi.repository import GLib as glib
except ImportError as err:
glib = None
glib_err = err
if glib is None:
# fallback to good old GLib, Gtk2.x style
try:
import glib
except ImportError as err:
glib = None # make things clear
glib_err = err
if glib is None:
bail_out(glib_err)
return 1
try:
import dbus
from dbus.mainloop.glib import DBusGMainLoop
except ImportError as err:
bail_out(err)
return 1
dbus_loop = DBusGMainLoop(set_as_default = True)
loop = glib.MainLoop()
glib.threads_init()
_entropy_dbus_object = None
tries = 5
try:
_system_bus = dbus.SystemBus(mainloop=dbus_loop)
_entropy_dbus_object = _system_bus.get_object(
"org.sabayon.Rigo", "/")
except dbus.exceptions.DBusException as err:
bail_out(err)
return 1
if _entropy_dbus_object is not None:
repos = self._repositories[:]
settings = entropy_client.Settings()
if not repos:
repos = list(settings['repositories']['available'].keys())
iface = dbus.Interface(_entropy_dbus_object,
dbus_interface = "org.sabayon.Rigo")
accepted = False
try:
if repos:
accepted = iface.update_repositories(
repos, self._force)
except dbus.exceptions.DBusException as err:
bail_out(err)
return 1
if accepted:
info_txt = _("Have a nice day")
entropy_client.output(
brown(info_txt))
return 0
else:
info_txt = _("Repositories update not allowed")
entropy_client.output(
brown(info_txt))
return 1
bail_out(None)
return 1
def _normal_update(self, entropy_client):
"""
Execute update from this instance.
"""
repos = self._repositories[:]
settings = entropy_client.Settings()
if not repos:
repos = list(settings['repositories']['available'].keys())
repo_conf = settings.get_setting_files_data()['repositories']
try:
repo_intf = entropy_client.Repositories(
repos, force=self._force)
except AttributeError:
entropy_client.output(
"%s%s %s" % (
darkred(" * "),
purple(_("No repositories specified in")),
repo_conf,),
level="error", importance=1)
return 127
rc = repo_intf.sync()
if not rc:
for repository in repos:
self._show_notice_board_summary(
entropy_client, repository)
return rc
def _check_notice_board_availability(self, entropy_client, repository):
"""
Determine if a NoticeBoard for the given repository is
available.
"""
def show_err():
entropy_client.output(
"%s%s" % (
darkred(" @@ "),
blue(_("Notice board not available"))),
level="error", importance=1)
nb = NoticeBoard(repository)
try:
data = nb.data()
except KeyError:
data = None
show_err()
if not data:
return None
return data
def _show_notice_board_summary(self, entropy_client, repository):
"""
Show NoticeBoard information to user after repository update.
"""
mytxt = "%s %s: %s" % (darkgreen(" @@ "),
brown(_("Notice board")), bold(repository),)
entropy_client.output(mytxt)
mydict = self._check_notice_board_availability(
entropy_client, repository)
if not mydict:
return
for key in sorted(mydict.keys()):
mydata = mydict.get(key)
mytxt = " [%s] [%s] %s: %s" % (
blue(str(key)),
brown(mydata['pubDate']),
_("Title"),
darkred(mydata['title']),
)
entropy_client.output(mytxt)
SoloCommandDescriptor.register(
SoloCommandDescriptor(
SoloUpdate,
SoloUpdate.NAME,
_("update repositories"))
)