From 0314cbd0e89caaf87da8c307f0a58d70fc78246f Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 31 May 2018 10:06:31 -0700 Subject: [PATCH] Add support for sources to composer-cli This adds the sources command which can be used to list, add, change, and delete sources using the TOML formatted source file. (cherry picked from commit 6f6ce410c092fca589e0318b50110b82a2cab01e) --- src/composer/cli/__init__.py | 5 +- src/composer/cli/cmdline.py | 130 +++++++++++++++++++++++-------- src/composer/cli/sources.py | 143 +++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+), 32 deletions(-) create mode 100644 src/composer/cli/sources.py diff --git a/src/composer/cli/__init__.py b/src/composer/cli/__init__.py index 3b731ffc..d313067f 100644 --- a/src/composer/cli/__init__.py +++ b/src/composer/cli/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # # composer-cli # @@ -24,12 +23,14 @@ from composer.cli.blueprints import blueprints_cmd from composer.cli.modules import modules_cmd from composer.cli.projects import projects_cmd from composer.cli.compose import compose_cmd +from composer.cli.sources import sources_cmd command_map = { "blueprints": blueprints_cmd, "modules": modules_cmd, "projects": projects_cmd, - "compose": compose_cmd + "compose": compose_cmd, + "sources": sources_cmd } diff --git a/src/composer/cli/cmdline.py b/src/composer/cli/cmdline.py index a60da2f9..d9ff5e50 100644 --- a/src/composer/cli/cmdline.py +++ b/src/composer/cli/cmdline.py @@ -24,36 +24,106 @@ VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum) # Documentation for the commands epilog = """ -compose start Start a compose using the selected blueprint and output type. - types List the supported output types. - status List the status of all running and finished composes. - log [kB] Show the last 1kB of the compose log. - cancel Cancel a running compose and delete any intermediate results. - delete Delete the listed compose results. - info Show detailed information on the compose. - metadata Download the metadata use to create the compose to -metadata.tar - logs Download the compose logs to -logs.tar - results Download all of the compose results; metadata, logs, and image to .tar - image Download the output image from the compose. Filename depends on the type. -blueprints list List the names of the available blueprints. - show Display the blueprint in TOML format. - changes Display the changes for each blueprint. - diff Display the differences between 2 versions of a blueprint. - Commit hash or NEWEST - Commit hash, NEWEST, or WORKSPACE - save Save the blueprint to a file, .toml - delete Delete a blueprint from the server - depsolve Display the packages needed to install the blueprint. - push Push a blueprint TOML file to the server. - freeze Display the frozen blueprint's modules and packages. - freeze show Display the frozen blueprint in TOML format. - freeze save Save the frozen blueprint to a file, .frozen.toml. - tag Tag the most recent blueprint commit as a release. - undo Undo changes to a blueprint by reverting to the selected commit. - workspace Push the blueprint TOML to the temporary workspace storage. -modules list List the available modules. -projects list List the available projects. -projects info Show details about the listed projects. +compose start + Start a compose using the selected blueprint and output type. + +compose types + List the supported output types. + +compose status + List the status of all running and finished composes. + +compose log [] + Show the last SIZE kB of the compose log. + +compose cancel + Cancel a running compose and delete any intermediate results. + +compose delete + Delete the listed compose results. + +compose info + Show detailed information on the compose. + +compose metadata + Download the metadata use to create the compose to -metadata.tar + +compose logs + Download the compose logs to -logs.tar + +compose results + Download all of the compose results; metadata, logs, and image to .tar + +compose image + Download the output image from the compose. Filename depends on the type. + +blueprints list + List the names of the available blueprints. + +blueprints show + Display the blueprint in TOML format. + +blueprints changes + Display the changes for each blueprint. + +blueprints diff + Display the differences between 2 versions of a blueprint. + FROM-COMMIT can be a commit hash or NEWEST + TO-COMMIT can be a commit hash, NEWEST, or WORKSPACE + +blueprints save + Save the blueprint to a file, .toml + +blueprints delete + Delete a blueprint from the server + +blueprints depsolve + Display the packages needed to install the blueprint. + +blueprints push + Push a blueprint TOML file to the server. + +blueprints freeze + Display the frozen blueprint's modules and packages. + +blueprints freeze show + Display the frozen blueprint in TOML format. + +blueprints freeze save + Save the frozen blueprint to a file, .frozen.toml. + +blueprints tag + Tag the most recent blueprint commit as a release. + +blueprints undo + Undo changes to a blueprint by reverting to the selected commit. + +blueprints workspace + Push the blueprint TOML to the temporary workspace storage. + +modules list + List the available modules. + +projects list + List the available projects. + +projects info + Show details about the listed projects. + +sources list + List the available sources + +sources info + Details about the source. + +sources add + Add a package source to the server. + +sources change + Change an existing source + +sources delete + Delete a package source. """ def composer_cli_parser(): diff --git a/src/composer/cli/sources.py b/src/composer/cli/sources.py new file mode 100644 index 00000000..c8ba3baa --- /dev/null +++ b/src/composer/cli/sources.py @@ -0,0 +1,143 @@ +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +import logging +log = logging.getLogger("composer-cli") + +import os +import json + +from composer import http_client as client +from composer.cli.utilities import argify, handle_api_result + +def sources_cmd(opts): + """Process sources commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + """ + cmd_map = { + "list": sources_list, + "info": sources_info, + "add": sources_add, + "change": sources_add, + "delete": sources_delete, + } + if opts.args[1] not in cmd_map: + log.error("Unknown sources command: %s", opts.args[1]) + return 1 + + return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json) + +def sources_list(socket_path, api_version, args, show_json=False): + """Output the list of available sources + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources list + """ + api_route = client.api_url(api_version, "/projects/source/list") + result = client.get_url_json(socket_path, api_route) + if show_json: + print(json.dumps(result, indent=4)) + return 0 + + print("Sources: %s" % ", ".join(result["sources"])) + return 0 + +def sources_info(socket_path, api_version, args, show_json=False): + """Output info on a list of projects + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources info + """ + if len(args) == 0: + log.error("sources info is missing the name of the source") + return 1 + + if show_json: + api_route = client.api_url(api_version, "/projects/source/info/%s" % ",".join(args)) + result = client.get_url_json(socket_path, api_route) + print(json.dumps(result, indent=4)) + return 0 + else: + api_route = client.api_url(api_version, "/projects/source/info/%s?format=toml" % ",".join(args)) + result = client.get_url_raw(socket_path, api_route) + print(result) + return 0 + +def sources_add(socket_path, api_version, args, show_json=False): + """Add or change a source + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources add + """ + api_route = client.api_url(api_version, "/projects/source/new") + rval = 0 + for source in argify(args): + if not os.path.exists(source): + log.error("Missing source file: %s", source) + continue + source_toml = open(source, "r").read() + + result = client.post_url_toml(socket_path, api_route, source_toml) + if handle_api_result(result, show_json): + rval = 1 + return rval + +def sources_delete(socket_path, api_version, args, show_json=False): + """Delete a source + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources delete + """ + api_route = client.api_url(api_version, "/projects/source/delete/%s" % args[0]) + result = client.delete_url_json(socket_path, api_route) + + return handle_api_result(result, show_json)