| |
@@ -1,82 +1,18 @@
|
| |
- #!/usr/bin/env python3
|
| |
-
|
| |
import os
|
| |
import argparse
|
| |
import sys
|
| |
|
| |
+ try:
|
| |
+ import tomllib
|
| |
+ except ImportError:
|
| |
+ import tomli as tomllib
|
| |
+
|
| |
import openidc_client
|
| |
import requests.exceptions
|
| |
|
| |
import odcs.client.odcs
|
| |
import json
|
| |
|
| |
- env_config = {
|
| |
- "fedora": {
|
| |
- "prod": {"server_url": "https://odcs.fedoraproject.org"},
|
| |
- "staging": {"server_url": "https://odcs.stg.fedoraproject.org"},
|
| |
- },
|
| |
- "redhat": {
|
| |
- "prod": {"server_url": "https://odcs.engineering.redhat.com"},
|
| |
- "staging": {"server_url": "https://odcs.stage.engineering.redhat.com"},
|
| |
- },
|
| |
- }
|
| |
-
|
| |
- id_provider_config = {
|
| |
- "prod": "https://id.fedoraproject.org/openidc/",
|
| |
- "staging": "https://id.stg.fedoraproject.org/openidc/",
|
| |
- }
|
| |
-
|
| |
- parser = argparse.ArgumentParser(
|
| |
- description="""\
|
| |
- %(prog)s - Command line client.
|
| |
-
|
| |
- If you have problems authenticating with OpenID Connect, try:
|
| |
-
|
| |
- $ rm -rf ~/.openidc/
|
| |
-
|
| |
- Example usage:
|
| |
-
|
| |
- """,
|
| |
- formatter_class=argparse.RawDescriptionHelpFormatter,
|
| |
- )
|
| |
- parser.add_argument(
|
| |
- "--redhat",
|
| |
- action="store_const",
|
| |
- const="redhat",
|
| |
- default="fedora",
|
| |
- dest="infra",
|
| |
- help="Use internal ODCS infra environment. If omitted, Fedora Infra will "
|
| |
- "be used by default.",
|
| |
- )
|
| |
- parser.add_argument(
|
| |
- "--staging",
|
| |
- action="store_const",
|
| |
- const="staging",
|
| |
- default="prod",
|
| |
- dest="env",
|
| |
- help="Use Fedora Infra or internal staging environment, which depends on "
|
| |
- "if --redhat is specified. If omitted, production environment will "
|
| |
- "be used.",
|
| |
- )
|
| |
- parser.add_argument("--server", default=None, help="Use custom ODCS server.")
|
| |
- parser.add_argument(
|
| |
- "--token", default=None, help="OpenIDC token to use or path to token file"
|
| |
- )
|
| |
- parser.add_argument(
|
| |
- "--no-wait",
|
| |
- action="store_true",
|
| |
- help="When used, odcs client will not wait for the action to finish.",
|
| |
- )
|
| |
- parser.add_argument(
|
| |
- "-q", "--quiet", action="store_true", help="Run without detailed log messages"
|
| |
- )
|
| |
- parser.add_argument("--watch", action="store_true", help="Watch compose logs")
|
| |
-
|
| |
- subparsers = parser.add_subparsers(
|
| |
- description="These commands you can use to operate composes with ODCS"
|
| |
- )
|
| |
-
|
| |
-
|
| |
KNOWN_ARGS = {
|
| |
"--flag": dict(
|
| |
default=[], action="append", help="Flag to pass to influence the compose."
|
| |
@@ -154,452 +90,523 @@
|
| |
return parser
|
| |
|
| |
|
| |
- create_command_deprecated = """
|
| |
- Deprecated: Please use create-* commands instead of the deprecated create command.
|
| |
- The create command will be removed and bugs with it are not going to be fixed.
|
| |
- """
|
| |
- create_parser = subparsers.add_parser(
|
| |
- "create",
|
| |
- help="Low-level command to create a new compose (Deprecated)",
|
| |
- description=create_command_deprecated,
|
| |
- )
|
| |
- create_parser.set_defaults(command="create")
|
| |
- create_parser.add_argument(
|
| |
- "source_type",
|
| |
- default=None,
|
| |
- choices=["tag", "module", "raw_config", "pulp", "build"],
|
| |
- help="Type for the source, for example: tag.",
|
| |
- )
|
| |
- create_parser.add_argument(
|
| |
- "source",
|
| |
- default="",
|
| |
- help="Source for the compose. May be a koji tag or a "
|
| |
- "whitespace separated list of modules.",
|
| |
- )
|
| |
- create_parser.add_argument(
|
| |
- "packages",
|
| |
- metavar="package",
|
| |
- nargs="*",
|
| |
- help="Packages to be included in the compose.",
|
| |
- )
|
| |
- create_parser.add_argument(
|
| |
- "builds", metavar="build", nargs="*", help="Builds to be included in the compose."
|
| |
- )
|
| |
- _add_arguments(
|
| |
- create_parser,
|
| |
- "--result",
|
| |
- "--sigkey",
|
| |
- "--koji-event",
|
| |
- "--arch",
|
| |
- "--module-defaults-url",
|
| |
- "--module-defaults-commit",
|
| |
- "--modular-tag",
|
| |
- "--lookaside-repo",
|
| |
- "--label",
|
| |
- "--compose-type",
|
| |
- "--target-dir",
|
| |
- "--flag",
|
| |
- "--scratch-module",
|
| |
+ DEFAULT_CONFIG_FILE = os.path.join(
|
| |
+ os.path.dirname(os.path.realpath(__file__)), "odcs.toml"
|
| |
)
|
| |
|
| |
|
| |
- create_tag_parser = subparsers.add_parser(
|
| |
- "create-tag", help="Create new compose from Koji tag."
|
| |
- )
|
| |
- create_tag_parser.set_defaults(command="create-tag")
|
| |
- create_tag_parser.add_argument("tag", default="", help="Koji tag name.")
|
| |
- create_tag_parser.add_argument(
|
| |
- "packages",
|
| |
- metavar="package",
|
| |
- nargs="*",
|
| |
- help=(
|
| |
- "Koji packages to be included in the compose. If you specify no packages, "
|
| |
- "ODCS will simply include all packages in the tag."
|
| |
- ),
|
| |
- )
|
| |
- _add_arguments(
|
| |
- create_tag_parser,
|
| |
- "--sigkey",
|
| |
- "--koji-event",
|
| |
- "--arch",
|
| |
- "--module-defaults-url",
|
| |
- "--module-defaults-commit",
|
| |
- "--modular-tag",
|
| |
- "--lookaside-repo",
|
| |
- "--target-dir",
|
| |
- "--build",
|
| |
- "--flag",
|
| |
- "--scratch-module",
|
| |
- )
|
| |
+ def _load_cfg():
|
| |
+ "Load client config file."
|
| |
+ cfg_file = os.path.join(os.path.expanduser("~"), ".config", "odcs.toml")
|
| |
+ if not os.path.isfile(cfg_file):
|
| |
+ cfg_file = DEFAULT_CONFIG_FILE
|
| |
+ with open(cfg_file, "rb") as f:
|
| |
+ return tomllib.load(f)
|
| |
|
| |
|
| |
- create_module_parser = subparsers.add_parser(
|
| |
- "create-module", help="Create new compose from modules."
|
| |
- )
|
| |
- create_module_parser.set_defaults(command="create-module")
|
| |
- create_module_parser.add_argument(
|
| |
- "modules",
|
| |
- metavar="modules",
|
| |
- nargs="*",
|
| |
- help="List of modules in N:S, N:S:V or N:S:V:C format.",
|
| |
- )
|
| |
- create_module_parser.add_argument(
|
| |
- "--base-module-br-name",
|
| |
- help="The name of a base module the module buildrequires",
|
| |
- )
|
| |
- create_module_parser.add_argument(
|
| |
- "--base-module-br-stream",
|
| |
- help="The stream of a base module the module buildrequires",
|
| |
- )
|
| |
- create_module_parser.add_argument(
|
| |
- "--base-module-br-stream-version-lte",
|
| |
- type=int,
|
| |
- help=(
|
| |
- "The numeric value of the stream version (el8.3.1 is 80301, f33 is 33) of "
|
| |
- "the buildrequired module specified by --base-module-br-name must be less "
|
| |
- "than equal to the given value."
|
| |
- ),
|
| |
- )
|
| |
- create_module_parser.add_argument(
|
| |
- "--base-module-br-stream-version-gte",
|
| |
- type=int,
|
| |
- help=(
|
| |
- "The numeric value of the stream version (el8.3.1 is 80301, f33 is 33) of "
|
| |
- "the buildrequired module specified by --base-module-br-name must be greater "
|
| |
- "than equal to the given value."
|
| |
- ),
|
| |
- )
|
| |
- _add_arguments(
|
| |
- create_module_parser,
|
| |
- "--sigkey",
|
| |
- "--arch",
|
| |
- "--modular-tag",
|
| |
- "--module-defaults-url",
|
| |
- "--module-defaults-commit",
|
| |
- "--lookaside-repo",
|
| |
- "--target-dir",
|
| |
- "--flag",
|
| |
- "--scratch-module",
|
| |
- )
|
| |
+ def main():
|
| |
+ parser = argparse.ArgumentParser(
|
| |
+ description="""\
|
| |
+ %(prog)s - Command line client.
|
| |
|
| |
+ CONFIGURATION:
|
| |
+ The default configuration file is `{}`,
|
| |
+ and you can copy it to `~/.config/odcs.toml` to add your own configurations.
|
| |
|
| |
- create_pulp_parser = subparsers.add_parser(
|
| |
- "create-pulp", help="Create new compose from Pulp content_sets."
|
| |
- )
|
| |
- create_pulp_parser.set_defaults(command="create-pulp")
|
| |
- create_pulp_parser.add_argument(
|
| |
- "content_sets",
|
| |
- metavar="content_set",
|
| |
- nargs="+",
|
| |
- help="Content sets to be included in the compose.",
|
| |
- )
|
| |
- _add_arguments(create_pulp_parser, "--target-dir", "--flag")
|
| |
+ If you have problems authenticating with OpenID Connect, try:
|
| |
|
| |
+ $ rm -rf ~/.openidc/
|
| |
|
| |
- create_raw_config_parser = subparsers.add_parser(
|
| |
- "create-raw-config", help="Create new compose from Pungi raw configuration."
|
| |
- )
|
| |
- create_raw_config_parser.set_defaults(command="create-raw-config")
|
| |
- create_raw_config_parser.add_argument(
|
| |
- "raw_config_name", help="Name of raw_config compose as defined in ODCS Server."
|
| |
- )
|
| |
- create_raw_config_parser.add_argument(
|
| |
- "raw_config_commit", help="Commit or branch name to get raw_config from."
|
| |
- )
|
| |
- _add_arguments(
|
| |
- create_raw_config_parser,
|
| |
- "--sigkey",
|
| |
- "--label",
|
| |
- "--no-label",
|
| |
- "--compose-type",
|
| |
- "--koji-event",
|
| |
- "--target-dir",
|
| |
- "--build",
|
| |
- )
|
| |
+ Example usage:
|
| |
|
| |
+ """.format(
|
| |
+ DEFAULT_CONFIG_FILE
|
| |
+ ),
|
| |
+ formatter_class=argparse.RawDescriptionHelpFormatter,
|
| |
+ )
|
| |
+ parser.add_argument(
|
| |
+ "--redhat",
|
| |
+ action="store_const",
|
| |
+ const="redhat",
|
| |
+ default="fedora",
|
| |
+ dest="infra",
|
| |
+ help="Use internal ODCS infra environment. If omitted, Fedora Infra will "
|
| |
+ "be used by default.",
|
| |
+ )
|
| |
+ parser.add_argument(
|
| |
+ "--staging",
|
| |
+ action="store_const",
|
| |
+ const="staging",
|
| |
+ default="prod",
|
| |
+ dest="env",
|
| |
+ help="Use Fedora Infra or internal staging environment, which depends on "
|
| |
+ "if --redhat is specified. If omitted, production environment will "
|
| |
+ "be used.",
|
| |
+ )
|
| |
+ parser.add_argument("--server", default=None, help="Use custom ODCS server.")
|
| |
+ parser.add_argument(
|
| |
+ "--token", default=None, help="OpenIDC token to use or path to token file"
|
| |
+ )
|
| |
+ parser.add_argument(
|
| |
+ "--no-wait",
|
| |
+ action="store_true",
|
| |
+ help="When used, odcs client will not wait for the action to finish.",
|
| |
+ )
|
| |
+ parser.add_argument(
|
| |
+ "-q", "--quiet", action="store_true", help="Run without detailed log messages"
|
| |
+ )
|
| |
+ parser.add_argument("--watch", action="store_true", help="Watch compose logs")
|
| |
|
| |
- create_build_parser = subparsers.add_parser(
|
| |
- "create-build", help="Create new compose from Koji builds."
|
| |
- )
|
| |
- create_build_parser.set_defaults(command="create-build")
|
| |
- create_build_parser.add_argument(
|
| |
- "builds", metavar="NVR", nargs="+", help="Koji builds NVRs."
|
| |
- )
|
| |
- _add_arguments(create_build_parser, "--sigkey", "--flag", "--target-dir", "--arch")
|
| |
+ subparsers = parser.add_subparsers(
|
| |
+ description="These commands you can use to operate composes with ODCS"
|
| |
+ )
|
| |
+
|
| |
+ create_command_deprecated = """
|
| |
+ Deprecated: Please use create-* commands instead of the deprecated create command.
|
| |
+ The create command will be removed and bugs with it are not going to be fixed.
|
| |
+ """
|
| |
+ create_parser = subparsers.add_parser(
|
| |
+ "create",
|
| |
+ help="Low-level command to create a new compose (Deprecated)",
|
| |
+ description=create_command_deprecated,
|
| |
+ )
|
| |
+ create_parser.set_defaults(command="create")
|
| |
+ create_parser.add_argument(
|
| |
+ "source_type",
|
| |
+ default=None,
|
| |
+ choices=["tag", "module", "raw_config", "pulp", "build"],
|
| |
+ help="Type for the source, for example: tag.",
|
| |
+ )
|
| |
+ create_parser.add_argument(
|
| |
+ "source",
|
| |
+ default="",
|
| |
+ help="Source for the compose. May be a koji tag or a "
|
| |
+ "whitespace separated list of modules.",
|
| |
+ )
|
| |
+ create_parser.add_argument(
|
| |
+ "packages",
|
| |
+ metavar="package",
|
| |
+ nargs="*",
|
| |
+ help="Packages to be included in the compose.",
|
| |
+ )
|
| |
+ create_parser.add_argument(
|
| |
+ "builds",
|
| |
+ metavar="build",
|
| |
+ nargs="*",
|
| |
+ help="Builds to be included in the compose.",
|
| |
+ )
|
| |
+ _add_arguments(
|
| |
+ create_parser,
|
| |
+ "--result",
|
| |
+ "--sigkey",
|
| |
+ "--koji-event",
|
| |
+ "--arch",
|
| |
+ "--module-defaults-url",
|
| |
+ "--module-defaults-commit",
|
| |
+ "--modular-tag",
|
| |
+ "--lookaside-repo",
|
| |
+ "--label",
|
| |
+ "--compose-type",
|
| |
+ "--target-dir",
|
| |
+ "--flag",
|
| |
+ "--scratch-module",
|
| |
+ )
|
| |
|
| |
+ create_tag_parser = subparsers.add_parser(
|
| |
+ "create-tag", help="Create new compose from Koji tag."
|
| |
+ )
|
| |
+ create_tag_parser.set_defaults(command="create-tag")
|
| |
+ create_tag_parser.add_argument("tag", default="", help="Koji tag name.")
|
| |
+ create_tag_parser.add_argument(
|
| |
+ "packages",
|
| |
+ metavar="package",
|
| |
+ nargs="*",
|
| |
+ help=(
|
| |
+ "Koji packages to be included in the compose. If you specify no packages, "
|
| |
+ "ODCS will simply include all packages in the tag."
|
| |
+ ),
|
| |
+ )
|
| |
+ _add_arguments(
|
| |
+ create_tag_parser,
|
| |
+ "--sigkey",
|
| |
+ "--koji-event",
|
| |
+ "--arch",
|
| |
+ "--module-defaults-url",
|
| |
+ "--module-defaults-commit",
|
| |
+ "--modular-tag",
|
| |
+ "--lookaside-repo",
|
| |
+ "--target-dir",
|
| |
+ "--build",
|
| |
+ "--flag",
|
| |
+ "--scratch-module",
|
| |
+ )
|
| |
|
| |
- wait_parser = subparsers.add_parser("wait", help="wait for a compose to finish")
|
| |
- wait_parser.set_defaults(command="wait")
|
| |
- wait_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
- wait_parser.add_argument("--watch", action="store_true", help="Watch compose logs")
|
| |
+ create_module_parser = subparsers.add_parser(
|
| |
+ "create-module", help="Create new compose from modules."
|
| |
+ )
|
| |
+ create_module_parser.set_defaults(command="create-module")
|
| |
+ create_module_parser.add_argument(
|
| |
+ "modules",
|
| |
+ metavar="modules",
|
| |
+ nargs="*",
|
| |
+ help="List of modules in N:S, N:S:V or N:S:V:C format.",
|
| |
+ )
|
| |
+ create_module_parser.add_argument(
|
| |
+ "--base-module-br-name",
|
| |
+ help="The name of a base module the module buildrequires",
|
| |
+ )
|
| |
+ create_module_parser.add_argument(
|
| |
+ "--base-module-br-stream",
|
| |
+ help="The stream of a base module the module buildrequires",
|
| |
+ )
|
| |
+ create_module_parser.add_argument(
|
| |
+ "--base-module-br-stream-version-lte",
|
| |
+ type=int,
|
| |
+ help=(
|
| |
+ "The numeric value of the stream version (el8.3.1 is 80301, f33 is 33) of "
|
| |
+ "the buildrequired module specified by --base-module-br-name must be less "
|
| |
+ "than equal to the given value."
|
| |
+ ),
|
| |
+ )
|
| |
+ create_module_parser.add_argument(
|
| |
+ "--base-module-br-stream-version-gte",
|
| |
+ type=int,
|
| |
+ help=(
|
| |
+ "The numeric value of the stream version (el8.3.1 is 80301, f33 is 33) of "
|
| |
+ "the buildrequired module specified by --base-module-br-name must be greater "
|
| |
+ "than equal to the given value."
|
| |
+ ),
|
| |
+ )
|
| |
+ _add_arguments(
|
| |
+ create_module_parser,
|
| |
+ "--sigkey",
|
| |
+ "--arch",
|
| |
+ "--modular-tag",
|
| |
+ "--module-defaults-url",
|
| |
+ "--module-defaults-commit",
|
| |
+ "--lookaside-repo",
|
| |
+ "--target-dir",
|
| |
+ "--flag",
|
| |
+ "--scratch-module",
|
| |
+ )
|
| |
|
| |
+ create_pulp_parser = subparsers.add_parser(
|
| |
+ "create-pulp", help="Create new compose from Pulp content_sets."
|
| |
+ )
|
| |
+ create_pulp_parser.set_defaults(command="create-pulp")
|
| |
+ create_pulp_parser.add_argument(
|
| |
+ "content_sets",
|
| |
+ metavar="content_set",
|
| |
+ nargs="+",
|
| |
+ help="Content sets to be included in the compose.",
|
| |
+ )
|
| |
+ _add_arguments(create_pulp_parser, "--target-dir", "--flag")
|
| |
|
| |
- delete_parser = subparsers.add_parser(
|
| |
- "delete",
|
| |
- help="delete compose",
|
| |
- description=(
|
| |
- "Cancel compose in wait state or mark finished compose as expired "
|
| |
- "for ODCS backends to remove compose data later from ODCS storage. "
|
| |
- "Note that compose metadata stored in database won't be removed and always "
|
| |
- "accessable via 'odcs get' command."
|
| |
- ),
|
| |
- )
|
| |
- delete_parser.set_defaults(command="delete")
|
| |
- delete_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
-
|
| |
- renew_parser = subparsers.add_parser(
|
| |
- "renew",
|
| |
- help="renew compose",
|
| |
- description=(
|
| |
- "Extends the compose expiration time or regenerates expired/failed compose "
|
| |
- "or regenerates compose with a new label. "
|
| |
- "The regenerated compose will have the same package versions as the original compose."
|
| |
- ),
|
| |
- )
|
| |
- renew_parser.set_defaults(command="renew")
|
| |
- renew_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
- renew_parser.add_argument(
|
| |
- "--label", default=None, help="New label of regenerated compose"
|
| |
- )
|
| |
- renew_parser.add_argument(
|
| |
- "--seconds-to-live",
|
| |
- default=None,
|
| |
- help="Number of seconds to extends the compose expiration time",
|
| |
- )
|
| |
+ create_raw_config_parser = subparsers.add_parser(
|
| |
+ "create-raw-config", help="Create new compose from Pungi raw configuration."
|
| |
+ )
|
| |
+ create_raw_config_parser.set_defaults(command="create-raw-config")
|
| |
+ create_raw_config_parser.add_argument(
|
| |
+ "raw_config_name", help="Name of raw_config compose as defined in ODCS Server."
|
| |
+ )
|
| |
+ create_raw_config_parser.add_argument(
|
| |
+ "raw_config_commit", help="Commit or branch name to get raw_config from."
|
| |
+ )
|
| |
+ _add_arguments(
|
| |
+ create_raw_config_parser,
|
| |
+ "--sigkey",
|
| |
+ "--label",
|
| |
+ "--no-label",
|
| |
+ "--compose-type",
|
| |
+ "--koji-event",
|
| |
+ "--target-dir",
|
| |
+ "--build",
|
| |
+ )
|
| |
|
| |
- get_parser = subparsers.add_parser("get", help="get compose info")
|
| |
- get_parser.set_defaults(command="get")
|
| |
- get_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
+ create_build_parser = subparsers.add_parser(
|
| |
+ "create-build", help="Create new compose from Koji builds."
|
| |
+ )
|
| |
+ create_build_parser.set_defaults(command="create-build")
|
| |
+ create_build_parser.add_argument(
|
| |
+ "builds", metavar="NVR", nargs="+", help="Koji builds NVRs."
|
| |
+ )
|
| |
+ _add_arguments(create_build_parser, "--sigkey", "--flag", "--target-dir", "--arch")
|
| |
+
|
| |
+ wait_parser = subparsers.add_parser("wait", help="wait for a compose to finish")
|
| |
+ wait_parser.set_defaults(command="wait")
|
| |
+ wait_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
+ wait_parser.add_argument("--watch", action="store_true", help="Watch compose logs")
|
| |
+
|
| |
+ delete_parser = subparsers.add_parser(
|
| |
+ "delete",
|
| |
+ help="delete compose",
|
| |
+ description=(
|
| |
+ "Cancel compose in wait state or mark finished compose as expired "
|
| |
+ "for ODCS backends to remove compose data later from ODCS storage. "
|
| |
+ "Note that compose metadata stored in database won't be removed and always "
|
| |
+ "accessable via 'odcs get' command."
|
| |
+ ),
|
| |
+ )
|
| |
+ delete_parser.set_defaults(command="delete")
|
| |
+ delete_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
+
|
| |
+ renew_parser = subparsers.add_parser(
|
| |
+ "renew",
|
| |
+ help="renew compose",
|
| |
+ description=(
|
| |
+ "Extends the compose expiration time or regenerates expired/failed compose "
|
| |
+ "or regenerates compose with a new label. "
|
| |
+ "The regenerated compose will have the same package versions as the original compose."
|
| |
+ ),
|
| |
+ )
|
| |
+ renew_parser.set_defaults(command="renew")
|
| |
+ renew_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
+ renew_parser.add_argument(
|
| |
+ "--label", default=None, help="New label of regenerated compose"
|
| |
+ )
|
| |
+ renew_parser.add_argument(
|
| |
+ "--seconds-to-live",
|
| |
+ default=None,
|
| |
+ help="Number of seconds to extends the compose expiration time",
|
| |
+ )
|
| |
|
| |
- about_parser = subparsers.add_parser("about", help="Get information about ODCS server")
|
| |
- about_parser.set_defaults(command="about")
|
| |
+ get_parser = subparsers.add_parser("get", help="get compose info")
|
| |
+ get_parser.set_defaults(command="get")
|
| |
+ get_parser.add_argument("compose_id", default=None, help="ODCS compose id")
|
| |
|
| |
- args = parser.parse_args()
|
| |
+ about_parser = subparsers.add_parser(
|
| |
+ "about", help="Get information about ODCS server"
|
| |
+ )
|
| |
+ about_parser.set_defaults(command="about")
|
| |
|
| |
- if not hasattr(args, "command"):
|
| |
- parser.print_help()
|
| |
- sys.exit(0)
|
| |
+ args = parser.parse_args()
|
| |
|
| |
- if args.server is None:
|
| |
- odcs_url = env_config[args.infra][args.env]["server_url"]
|
| |
- else:
|
| |
- odcs_url = args.server
|
| |
+ if not hasattr(args, "command"):
|
| |
+ parser.print_help()
|
| |
+ sys.exit(0)
|
| |
|
| |
- if args.infra == "fedora":
|
| |
- if args.token:
|
| |
- if os.path.exists(args.token):
|
| |
- with open(args.token, "r") as token_file:
|
| |
- token = token_file.readline().strip()
|
| |
- else:
|
| |
- token = args.token
|
| |
+ cfg = _load_cfg()
|
| |
+ if args.server is None:
|
| |
+ odcs_url = cfg[args.infra][args.env]["url"]
|
| |
else:
|
| |
- id_provider = id_provider_config[args.env]
|
| |
-
|
| |
- # Get the auth token using the OpenID client.
|
| |
- oidc = openidc_client.OpenIDCClient(
|
| |
- "odcs",
|
| |
- id_provider,
|
| |
- {"Token": "Token", "Authorization": "Authorization"},
|
| |
- "odcs-authorizer",
|
| |
- "notsecret",
|
| |
- )
|
| |
+ odcs_url = args.server
|
| |
|
| |
- scopes = [
|
| |
- "openid",
|
| |
- "https://id.fedoraproject.org/scope/groups",
|
| |
- "https://pagure.io/odcs/new-compose",
|
| |
- "https://pagure.io/odcs/renew-compose",
|
| |
- "https://pagure.io/odcs/delete-compose",
|
| |
- ]
|
| |
- try:
|
| |
- token = oidc.get_token(scopes, new_token=True)
|
| |
- token = oidc.report_token_issue()
|
| |
- except requests.exceptions.HTTPError as e:
|
| |
- print(e.response.text)
|
| |
- raise
|
| |
-
|
| |
- client = odcs.client.odcs.ODCS(
|
| |
- odcs_url,
|
| |
- auth_mech=odcs.client.odcs.AuthMech.OpenIDC,
|
| |
- openidc_token=token,
|
| |
- )
|
| |
- else:
|
| |
- client = odcs.client.odcs.ODCS(
|
| |
- odcs_url,
|
| |
- auth_mech=odcs.client.odcs.AuthMech.Kerberos,
|
| |
- )
|
| |
-
|
| |
- request_args = {}
|
| |
- if getattr(args, "flag", False):
|
| |
- request_args["flags"] = args.flag
|
| |
- if getattr(args, "arch", False):
|
| |
- request_args["arches"] = args.arch
|
| |
- if getattr(args, "lookaside_repo", False):
|
| |
- request_args["lookaside_repos"] = args.lookaside_repo
|
| |
- if getattr(args, "label", False):
|
| |
- request_args["label"] = args.label
|
| |
- if getattr(args, "no_label", False):
|
| |
- if "flags" in request_args:
|
| |
- request_args["flags"].append("no_label")
|
| |
- else:
|
| |
- request_args["flags"] = ["no_label"]
|
| |
- if getattr(args, "compose_type", False):
|
| |
- request_args["compose_type"] = args.compose_type
|
| |
- if getattr(args, "target_dir", False):
|
| |
- request_args["target_dir"] = args.target_dir
|
| |
-
|
| |
- otel_endpoint = os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT", "")
|
| |
- ctx_token = None
|
| |
- if otel_endpoint:
|
| |
- from opentelemetry import context, trace
|
| |
- from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
| |
- OTLPSpanExporter,
|
| |
- )
|
| |
- from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
| |
- from opentelemetry.sdk.resources import Resource
|
| |
- from opentelemetry.sdk.trace import TracerProvider
|
| |
- from opentelemetry.sdk.trace.export import (
|
| |
- BatchSpanProcessor,
|
| |
- ConsoleSpanExporter,
|
| |
- )
|
| |
- from opentelemetry.trace.propagation.tracecontext import (
|
| |
- TraceContextTextMapPropagator,
|
| |
- )
|
| |
-
|
| |
- provider = TracerProvider(
|
| |
- resource=Resource(attributes={"service.name": "odcs-client"})
|
| |
- )
|
| |
- if "console" == otel_endpoint:
|
| |
- # This is for debugging the tracing locally.
|
| |
- provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
| |
- else:
|
| |
- provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
|
| |
-
|
| |
- trace.set_tracer_provider(provider)
|
| |
- tracer = trace.get_tracer(__name__)
|
| |
- carrier = {}
|
| |
- traceparent = os.environ.get("TRACEPARENT")
|
| |
- ctx = None
|
| |
- if traceparent:
|
| |
- ctx = TraceContextTextMapPropagator().extract(
|
| |
- carrier={"traceparent": traceparent}
|
| |
- )
|
| |
- with tracer.start_as_current_span("odcs-client", context=ctx) as span:
|
| |
- TraceContextTextMapPropagator().inject(carrier)
|
| |
- span.set_attribute("command", " ".join(sys.argv))
|
| |
+ id_provider = cfg[args.infra][args.env]["id_provider"]
|
| |
|
| |
- ctx = TraceContextTextMapPropagator().extract(carrier)
|
| |
- ctx_token = context.attach(ctx)
|
| |
- RequestsInstrumentor().instrument(tracer_provider=provider)
|
| |
+ if args.infra == "fedora":
|
| |
+ if args.token:
|
| |
+ if os.path.exists(args.token):
|
| |
+ with open(args.token, "r") as token_file:
|
| |
+ token = token_file.readline().strip()
|
| |
+ else:
|
| |
+ token = args.token
|
| |
+ else:
|
| |
+ # Get the auth token using the OpenID client.
|
| |
+ oidc = openidc_client.OpenIDCClient(
|
| |
+ "odcs",
|
| |
+ id_provider,
|
| |
+ {"Token": "Token", "Authorization": "Authorization"},
|
| |
+ "odcs-authorizer",
|
| |
+ "notsecret",
|
| |
+ )
|
| |
|
| |
- try:
|
| |
- args.sigkey = [key.replace("none", "") for key in getattr(args, "sigkey", [])]
|
| |
- if args.command == "create":
|
| |
- print(create_command_deprecated, file=sys.stderr)
|
| |
- result = client.new_compose(
|
| |
- source=args.source,
|
| |
- source_type=args.source_type,
|
| |
- packages=args.packages,
|
| |
- results=args.result,
|
| |
- sigkeys=args.sigkey,
|
| |
- koji_event=args.koji_event,
|
| |
- builds=args.builds,
|
| |
- modular_koji_tags=args.modular_tag,
|
| |
- module_defaults_url=args.module_defaults_url,
|
| |
- module_defaults_commit=args.module_defaults_commit,
|
| |
- scratch_modules=args.scratch_module,
|
| |
- **request_args
|
| |
+ scopes = [
|
| |
+ "openid",
|
| |
+ "https://id.fedoraproject.org/scope/groups",
|
| |
+ "https://pagure.io/odcs/new-compose",
|
| |
+ "https://pagure.io/odcs/renew-compose",
|
| |
+ "https://pagure.io/odcs/delete-compose",
|
| |
+ ]
|
| |
+ try:
|
| |
+ token = oidc.get_token(scopes, new_token=True)
|
| |
+ token = oidc.report_token_issue()
|
| |
+ except requests.exceptions.HTTPError as e:
|
| |
+ print(e.response.text)
|
| |
+ raise
|
| |
+
|
| |
+ client = odcs.client.odcs.ODCS(
|
| |
+ odcs_url,
|
| |
+ auth_mech=odcs.client.odcs.AuthMech.OpenIDC,
|
| |
+ openidc_token=token,
|
| |
)
|
| |
- elif args.command == "create-tag":
|
| |
- source = odcs.client.odcs.ComposeSourceTag(
|
| |
- args.tag,
|
| |
- args.packages,
|
| |
- args.build,
|
| |
- args.sigkey,
|
| |
- args.koji_event,
|
| |
- args.modular_tag,
|
| |
- args.module_defaults_url,
|
| |
- args.module_defaults_commit,
|
| |
- args.scratch_module,
|
| |
+ else:
|
| |
+ client = odcs.client.odcs.ODCS(
|
| |
+ odcs_url,
|
| |
+ auth_mech=odcs.client.odcs.AuthMech.Kerberos,
|
| |
)
|
| |
- result = client.request_compose(source, **request_args)
|
| |
- elif args.command == "create-module":
|
| |
- if not args.modules and not args.scratch_module:
|
| |
- create_module_parser.error("Please give a module or --scratch-module")
|
| |
- if (
|
| |
- len(args.modules) + len(args.scratch_module) > 1
|
| |
- and not (
|
| |
- args.base_module_br_stream
|
| |
- or args.base_module_br_stream_version_lte
|
| |
- or args.base_module_br_stream_version_gte
|
| |
- or args.modular_tag
|
| |
- )
|
| |
- and args.infra == "redhat"
|
| |
- ):
|
| |
- print(
|
| |
- "WARNING: Please add --base-module-X or --modular-tag option to the arguments to ensure all composed modules are built for the same release."
|
| |
- )
|
| |
- source = odcs.client.odcs.ComposeSourceModule(
|
| |
- args.modules,
|
| |
- args.sigkey,
|
| |
- args.module_defaults_url,
|
| |
- args.module_defaults_commit,
|
| |
- args.scratch_module,
|
| |
- base_module_br_name=args.base_module_br_name,
|
| |
- base_module_br_stream=args.base_module_br_stream,
|
| |
- base_module_br_stream_version_lte=args.base_module_br_stream_version_lte,
|
| |
- base_module_br_stream_version_gte=args.base_module_br_stream_version_gte,
|
| |
- modular_koji_tags=args.modular_tag,
|
| |
+
|
| |
+ request_args = {}
|
| |
+ if getattr(args, "flag", False):
|
| |
+ request_args["flags"] = args.flag
|
| |
+ if getattr(args, "arch", False):
|
| |
+ request_args["arches"] = args.arch
|
| |
+ if getattr(args, "lookaside_repo", False):
|
| |
+ request_args["lookaside_repos"] = args.lookaside_repo
|
| |
+ if getattr(args, "label", False):
|
| |
+ request_args["label"] = args.label
|
| |
+ if getattr(args, "no_label", False):
|
| |
+ if "flags" in request_args:
|
| |
+ request_args["flags"].append("no_label")
|
| |
+ else:
|
| |
+ request_args["flags"] = ["no_label"]
|
| |
+ if getattr(args, "compose_type", False):
|
| |
+ request_args["compose_type"] = args.compose_type
|
| |
+ if getattr(args, "target_dir", False):
|
| |
+ request_args["target_dir"] = args.target_dir
|
| |
+
|
| |
+ otel_endpoint = os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT", "")
|
| |
+ if otel_endpoint:
|
| |
+ from opentelemetry import context, trace
|
| |
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
| |
+ OTLPSpanExporter,
|
| |
)
|
| |
- result = client.request_compose(source, **request_args)
|
| |
- elif args.command == "create-pulp":
|
| |
- source = odcs.client.odcs.ComposeSourcePulp(args.content_sets)
|
| |
- result = client.request_compose(source, **request_args)
|
| |
- elif args.command == "create-raw-config":
|
| |
- source = odcs.client.odcs.ComposeSourceRawConfig(
|
| |
- args.raw_config_name,
|
| |
- args.raw_config_commit,
|
| |
- args.koji_event,
|
| |
- sigkeys=args.sigkey,
|
| |
- builds=args.build,
|
| |
+ from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
| |
+ from opentelemetry.sdk.resources import Resource
|
| |
+ from opentelemetry.sdk.trace import TracerProvider
|
| |
+ from opentelemetry.sdk.trace.export import (
|
| |
+ BatchSpanProcessor,
|
| |
+ ConsoleSpanExporter,
|
| |
)
|
| |
- result = client.request_compose(source, **request_args)
|
| |
- elif args.command == "create-build":
|
| |
- source = odcs.client.odcs.ComposeSourceBuild(args.builds, args.sigkey)
|
| |
- result = client.request_compose(source, **request_args)
|
| |
- elif args.command == "wait":
|
| |
- result = client.get_compose(args.compose_id)
|
| |
- elif args.command == "delete":
|
| |
- args.no_wait = True
|
| |
- result = client.delete_compose(args.compose_id)
|
| |
- elif args.command == "renew":
|
| |
- result = client.renew_compose(
|
| |
- args.compose_id, label=args.label, seconds_to_live=args.seconds_to_live
|
| |
+ from opentelemetry.trace.propagation.tracecontext import (
|
| |
+ TraceContextTextMapPropagator,
|
| |
)
|
| |
- elif args.command == "get":
|
| |
- result = client.get_compose(args.compose_id)
|
| |
- elif args.command == "about":
|
| |
- result = client.about()
|
| |
- else:
|
| |
- print("Unknown command %s" % args.command)
|
| |
- except requests.exceptions.HTTPError:
|
| |
- # error message gets printed in ODCS class.
|
| |
- sys.exit(-1)
|
| |
-
|
| |
- if args.no_wait or args.command == "about":
|
| |
- print(json.dumps(result, indent=4, sort_keys=True))
|
| |
- else:
|
| |
- if result["state_name"] in ["wait", "generating"]:
|
| |
- if not args.quiet:
|
| |
- print(
|
| |
- "Waiting for command %s on compose %d to finish."
|
| |
- % (args.command, result["id"])
|
| |
+
|
| |
+ provider = TracerProvider(
|
| |
+ resource=Resource(attributes={"service.name": "odcs-client"})
|
| |
+ )
|
| |
+ if "console" == otel_endpoint:
|
| |
+ # This is for debugging the tracing locally.
|
| |
+ provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
| |
+ else:
|
| |
+ provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
|
| |
+
|
| |
+ trace.set_tracer_provider(provider)
|
| |
+ tracer = trace.get_tracer(__name__)
|
| |
+ carrier = {}
|
| |
+ traceparent = os.environ.get("TRACEPARENT")
|
| |
+ ctx = None
|
| |
+ if traceparent:
|
| |
+ ctx = TraceContextTextMapPropagator().extract(
|
| |
+ carrier={"traceparent": traceparent}
|
| |
)
|
| |
- try:
|
| |
- result = client.wait_for_compose(result["id"], 3600, watch_logs=args.watch)
|
| |
- except (KeyboardInterrupt, SystemExit):
|
| |
- pass
|
| |
+ with tracer.start_as_current_span("odcs-client", context=ctx) as span:
|
| |
+ TraceContextTextMapPropagator().inject(carrier)
|
| |
+ span.set_attribute("command", " ".join(sys.argv))
|
| |
+
|
| |
+ ctx = TraceContextTextMapPropagator().extract(carrier)
|
| |
+ context.attach(ctx)
|
| |
+ RequestsInstrumentor().instrument(tracer_provider=provider)
|
| |
+
|
| |
+ try:
|
| |
+ args.sigkey = [key.replace("none", "") for key in getattr(args, "sigkey", [])]
|
| |
+ if args.command == "create":
|
| |
+ print(create_command_deprecated, file=sys.stderr)
|
| |
+ result = client.new_compose(
|
| |
+ source=args.source,
|
| |
+ source_type=args.source_type,
|
| |
+ packages=args.packages,
|
| |
+ results=args.result,
|
| |
+ sigkeys=args.sigkey,
|
| |
+ koji_event=args.koji_event,
|
| |
+ builds=args.builds,
|
| |
+ modular_koji_tags=args.modular_tag,
|
| |
+ module_defaults_url=args.module_defaults_url,
|
| |
+ module_defaults_commit=args.module_defaults_commit,
|
| |
+ scratch_modules=args.scratch_module,
|
| |
+ **request_args
|
| |
+ )
|
| |
+ elif args.command == "create-tag":
|
| |
+ source = odcs.client.odcs.ComposeSourceTag(
|
| |
+ args.tag,
|
| |
+ args.packages,
|
| |
+ args.build,
|
| |
+ args.sigkey,
|
| |
+ args.koji_event,
|
| |
+ args.modular_tag,
|
| |
+ args.module_defaults_url,
|
| |
+ args.module_defaults_commit,
|
| |
+ args.scratch_module,
|
| |
+ )
|
| |
+ result = client.request_compose(source, **request_args)
|
| |
+ elif args.command == "create-module":
|
| |
+ if not args.modules and not args.scratch_module:
|
| |
+ create_module_parser.error("Please give a module or --scratch-module")
|
| |
+ if (
|
| |
+ len(args.modules) + len(args.scratch_module) > 1
|
| |
+ and not (
|
| |
+ args.base_module_br_stream
|
| |
+ or args.base_module_br_stream_version_lte
|
| |
+ or args.base_module_br_stream_version_gte
|
| |
+ or args.modular_tag
|
| |
+ )
|
| |
+ and args.infra == "redhat"
|
| |
+ ):
|
| |
+ print(
|
| |
+ "WARNING: Please add --base-module-X or --modular-tag option to the arguments to ensure all composed modules are built for the same release."
|
| |
+ )
|
| |
+ source = odcs.client.odcs.ComposeSourceModule(
|
| |
+ args.modules,
|
| |
+ args.sigkey,
|
| |
+ args.module_defaults_url,
|
| |
+ args.module_defaults_commit,
|
| |
+ args.scratch_module,
|
| |
+ base_module_br_name=args.base_module_br_name,
|
| |
+ base_module_br_stream=args.base_module_br_stream,
|
| |
+ base_module_br_stream_version_lte=args.base_module_br_stream_version_lte,
|
| |
+ base_module_br_stream_version_gte=args.base_module_br_stream_version_gte,
|
| |
+ modular_koji_tags=args.modular_tag,
|
| |
+ )
|
| |
+ result = client.request_compose(source, **request_args)
|
| |
+ elif args.command == "create-pulp":
|
| |
+ source = odcs.client.odcs.ComposeSourcePulp(args.content_sets)
|
| |
+ result = client.request_compose(source, **request_args)
|
| |
+ elif args.command == "create-raw-config":
|
| |
+ source = odcs.client.odcs.ComposeSourceRawConfig(
|
| |
+ args.raw_config_name,
|
| |
+ args.raw_config_commit,
|
| |
+ args.koji_event,
|
| |
+ sigkeys=args.sigkey,
|
| |
+ builds=args.build,
|
| |
+ )
|
| |
+ result = client.request_compose(source, **request_args)
|
| |
+ elif args.command == "create-build":
|
| |
+ source = odcs.client.odcs.ComposeSourceBuild(args.builds, args.sigkey)
|
| |
+ result = client.request_compose(source, **request_args)
|
| |
+ elif args.command == "wait":
|
| |
+ result = client.get_compose(args.compose_id)
|
| |
+ elif args.command == "delete":
|
| |
+ args.no_wait = True
|
| |
+ result = client.delete_compose(args.compose_id)
|
| |
+ elif args.command == "renew":
|
| |
+ result = client.renew_compose(
|
| |
+ args.compose_id, label=args.label, seconds_to_live=args.seconds_to_live
|
| |
+ )
|
| |
+ elif args.command == "get":
|
| |
+ result = client.get_compose(args.compose_id)
|
| |
+ elif args.command == "about":
|
| |
+ result = client.about()
|
| |
+ else:
|
| |
+ print("Unknown command %s" % args.command)
|
| |
+ except requests.exceptions.HTTPError:
|
| |
+ # error message gets printed in ODCS class.
|
| |
+ sys.exit(-1)
|
| |
|
| |
- print(json.dumps(result, indent=4, sort_keys=True))
|
| |
- if result["state_name"] == "failed":
|
| |
- sys.exit(1)
|
| |
+ if args.no_wait or args.command == "about":
|
| |
+ print(json.dumps(result, indent=4, sort_keys=True))
|
| |
+ else:
|
| |
+ if result["state_name"] in ["wait", "generating"]:
|
| |
+ if not args.quiet:
|
| |
+ print(
|
| |
+ "Waiting for command %s on compose %d to finish."
|
| |
+ % (args.command, result["id"])
|
| |
+ )
|
| |
+ try:
|
| |
+ result = client.wait_for_compose(
|
| |
+ result["id"], 3600, watch_logs=args.watch
|
| |
+ )
|
| |
+ except (KeyboardInterrupt, SystemExit):
|
| |
+ pass
|
| |
+
|
| |
+ print(json.dumps(result, indent=4, sort_keys=True))
|
| |
+ if result["state_name"] == "failed":
|
| |
+ sys.exit(1)
|
| |
JIRA: RHELCMP-13331
Signed-off-by: Haibo Lin hlin@redhat.com