From ce3788aa59fc84e469fa87d8ee15822f60fbe519 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Mon, 16 Apr 2012 22:07:27 +0200 Subject: [PATCH] [eit] add "eit remote" command --- server/doc/mansrc/eit-remote.1.txt | 58 ++++++++ server/doc/mansrc/eit.1.txt | 9 +- server/eit/commands/remote.py | 225 +++++++++++++++++++++++++++++ 3 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 server/doc/mansrc/eit-remote.1.txt create mode 100644 server/eit/commands/remote.py diff --git a/server/doc/mansrc/eit-remote.1.txt b/server/doc/mansrc/eit-remote.1.txt new file mode 100644 index 000000000..5020a5a8c --- /dev/null +++ b/server/doc/mansrc/eit-remote.1.txt @@ -0,0 +1,58 @@ +eit-remote(1) +============= +:man source: eit {eitversion} +:man manual: eit {eitversion} + + +NAME +---- +eit-remote - manage repositories + + +SYNOPSIS +-------- +eit remote [-h] {list,add} ... + + +INTRODUCTION +------------ +Manage (add, remove, list) configured repositories. + + + +OPTIONS +------- +"eit remote" supports the following options which alters its behaviour. + + +OPTIONAL ARGUMENTS +~~~~~~~~~~~~~~~~~~ +*--help*:: + show this help message and exit + +ACTION +~~~~~~ +*list*:: + list repositories + +*add*:: + add repository + + + +AUTHORS +------- +Eit has been accidentally prototyped during a rainy Sunday by Fabio +Erculiani who was looking for innovative ways of handling package +bumps in Sabayon Entropy repositories. +A few months later, Eit saw the light. + + +REPORTING BUGS +-------------- +Report bugs to https://bugs.sabayon.org or directly to the author at +lxnay@sabayon.org. + +SEE ALSO +-------- + eit(1), eit-status(1) diff --git a/server/doc/mansrc/eit.1.txt b/server/doc/mansrc/eit.1.txt index b8d684399..dab726f80 100644 --- a/server/doc/mansrc/eit.1.txt +++ b/server/doc/mansrc/eit.1.txt @@ -117,6 +117,9 @@ COMMANDS *query [q]*:: miscellaneous package metadata queries +*remote*:: + manage repositories + *remove [rm]*:: remove packages from repository @@ -168,7 +171,7 @@ SEE ALSO eit-commit(1), eit-cp(1), eit-deps(1), eit-files(1), eit-graph(1) eit-init(1), eit-inject(1), eit-list(1), eit-lock(1), eit-log(1) eit-match(1), eit-merge(1), eit-mv(1), eit-notice(1), eit-own(1) - eit-pkgmove(1), eit-pull(1), eit-push(1), eit-query(1), eit-remove(1) - eit-repack(1), eit-repo(1), eit-reset(1), eit-revgraph(1), eit-search(1) - eit-status(1), eit-test(1), eit-unlock(1), eit-vacuum(1) + eit-pkgmove(1), eit-pull(1), eit-push(1), eit-query(1), eit-remote(1) + eit-remove(1), eit-repack(1), eit-repo(1), eit-reset(1), eit-revgraph(1) + eit-search(1), eit-status(1), eit-test(1), eit-unlock(1), eit-vacuum(1) diff --git a/server/eit/commands/remote.py b/server/eit/commands/remote.py new file mode 100644 index 000000000..1c9818055 --- /dev/null +++ b/server/eit/commands/remote.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +""" + + @author: Fabio Erculiani + @contact: lxnay@sabayon.org + @copyright: Fabio Erculiani + @license: GPL-2 + + B{Entropy Infrastructure Toolkit}. + +""" +import sys +import os +import argparse +import codecs + +from entropy.const import etpConst +from entropy.i18n import _ +from entropy.output import darkgreen, teal, brown, purple, blue +from entropy.client.interfaces.db import InstalledPackagesRepository +from entropy.server.interfaces.main import ServerSystemSettingsPlugin + +import entropy.tools + +from eit.commands.descriptor import EitCommandDescriptor +from eit.commands.command import EitCommand + +class EitRemote(EitCommand): + """ + Main Eit remote command. + """ + + NAME = "remote" + ALIASES = [] + ALLOW_UNPRIVILEGED = True + + def _get_parser(self): + """ Overridden from EitCommand """ + descriptor = EitCommandDescriptor.obtain_descriptor( + EitRemote.NAME) + parser = argparse.ArgumentParser( + description=descriptor.get_description(), + formatter_class=argparse.RawDescriptionHelpFormatter, + prog="%s %s" % (sys.argv[0], EitRemote.NAME)) + + subparsers = parser.add_subparsers( + title="action", description=_("execute action"), + help=_("available actions")) + + list_parser = subparsers.add_parser("list", + help=_("list repositories")) + list_parser.set_defaults(func=self._list) + + add_parser = subparsers.add_parser("add", + help=_("add repository")) + add_parser.add_argument("repository", metavar="", + help=_("repository id")) + add_parser.add_argument("--desc", metavar="", + default=None, + help=_("repository description")) + add_parser.add_argument("uri", metavar="", nargs="+", + help=_("repository uri")) + + add_parser.set_defaults(func=self._add) + + return parser + + INTRODUCTION = """\ +Manage (add, remove, list) configured repositories. +""" + SEE_ALSO = "eit-status(1)" + + def man(self): + """ + Overridden from EitCommand. + """ + return self._man() + + def parse(self): + """ Overridden from EitCommand """ + 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._nsargs = nsargs + return self._call_locked, [nsargs.func, None] + + def _add(self, entropy_server): + """ + Add a Repository. + """ + repository_id = self._nsargs.repository + description = self._nsargs.desc + uris = self._nsargs.uri + + if not entropy.tools.validate_repository_id(repository_id): + entropy_server.output( + purple(_("Invalid repository name")), + importance=1, level="error") + return 1 + + if repository_id in entropy_server.repositories(): + entropy_server.output( + purple(_("Repository already available")), + importance=1, level="error") + return 1 + + if description: + description = description.strip() + if not description: + description = None + + for uri in uris: + if not entropy.tools.is_valid_uri(uri): + entropy_server.output( + "%s: %s" % ( + purple(_("Invalid URI")), + uri), + importance=1, level="error") + return 1 + + server_conf = ServerSystemSettingsPlugin.server_conf_path() + enc = etpConst['conf_encoding'] + content = "" + try: + with codecs.open(server_conf, encoding=enc) as server_f: + content = server_f.read() + except IOError as err: + if err.errno == errno.EPERM: + entropy_server.output( + "%s: %s" % ( + purple(_("Cannot read configuration file")), + server_conf,), + importance=1, level="error") + return 1 + if err.errno != errno.ENOENT: + raise + + if not content.endswith("\n") and content: + content += "\n" + elif not content: + content += "default-repository = %s\n" % (repository_id,) + content += "repository = %s|%s|%s\n" % ( + repository_id, description, + " ".join(uris),) + + if not description: + description = _("no description") + entropy_server.output( + "%s: %s [%s]" % ( + darkgreen(_("Adding repository")), + teal(repository_id), + darkgreen(description), + )) + for uri in uris: + entropy_server.output( + "++ %s" % ( + brown(uri), + )) + entropy_server.output( + "%s: %s" % ( + darkgreen(_("Configuration file")), + purple(server_conf), + )) + entropy_server.output( + "%s: '%s %s'" % ( + darkgreen(_("Please initialize the repository using")), + teal("eit init"), + brown(repository_id), + )) + + entropy.tools.atomic_write( + server_conf, content, enc) + + return 0 + + def _list(self, entropy_server): + """ + List Available Repositories. + """ + repositories = entropy_server.repositories() + default_repo = entropy_server.repository() + for repository_id in repositories: + repo_class = entropy_server.get_repository(repository_id) + if repo_class == InstalledPackagesRepository: + continue + + default_str = "" + if repository_id == default_repo: + default_str = " (%s)" % (purple("*"),) + meta = entropy_server.repository_metadata(repository_id) + description = meta['description'] + repo_mirrors = meta['repo_mirrors'] + pkg_mirrors = meta['pkg_mirrors'] + + entropy_server.output( + "%s [%s]%s" % ( + teal(repository_id), + darkgreen(description), + default_str, + )) + for repo_mirror in repo_mirrors: + entropy_server.output( + " %s: %s" % ( + blue(_("repository")), + brown(repo_mirror), + )) + for pkg_mirror in pkg_mirrors: + entropy_server.output( + " %s: %s" % ( + blue(_("packages")), + brown(pkg_mirror), + )) + + return 0 + +EitCommandDescriptor.register( + EitCommandDescriptor( + EitRemote, + EitRemote.NAME, + _('manage repositories')) + )