config-dump: Allow dumping config for multi compose
Clone the main config, all referenced parts and included variants or comps files. This requires a new argument: destination directory to which to write the copied files. JIRA: COMPOSE-3289 Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
parent
33471c38bb
commit
217fcd6c02
@ -7,8 +7,11 @@ import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from six.moves import configparser
|
||||
|
||||
import kobo.conf
|
||||
import pungi.checks
|
||||
import pungi.util
|
||||
@ -40,6 +43,93 @@ def validate_definition(value):
|
||||
return value
|
||||
|
||||
|
||||
def dump_multi_config(conf_file, dest, **kwargs):
|
||||
"""Given a multi compose config, clone it and all referenced files to a
|
||||
given directory.
|
||||
"""
|
||||
parser = configparser.RawConfigParser()
|
||||
parser.read(conf_file)
|
||||
|
||||
pungi.util.makedirs(dest)
|
||||
basedir = os.path.dirname(conf_file)
|
||||
|
||||
def copy_local_files(config):
|
||||
"""Helper function called on all loaded Pungi configs that copies local
|
||||
variants or comps files (unless specified by absolute path).
|
||||
"""
|
||||
for opt in "comps_file", "variants_file":
|
||||
val = config.get(opt)
|
||||
if isinstance(val, str) and val[0] != "/":
|
||||
shutil.copy2(os.path.join(basedir, val), dest)
|
||||
|
||||
for section in parser.sections():
|
||||
if section == "general":
|
||||
continue
|
||||
file_path = parser.get(section, "config")
|
||||
dest_file = os.path.splitext(os.path.join(dest, file_path))[0] + ".json"
|
||||
with open(dest_file, "w") as fh:
|
||||
if not process_file(
|
||||
[os.path.join(basedir, file_path)],
|
||||
out=fh,
|
||||
callback=copy_local_files,
|
||||
**kwargs
|
||||
):
|
||||
return False
|
||||
parser.set(section, "config", os.path.basename(dest_file))
|
||||
|
||||
with open(os.path.join(dest, os.path.basename(conf_file)), "w") as fh:
|
||||
parser.write(fh)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def process_file(
|
||||
sources,
|
||||
out=sys.stdout,
|
||||
callback=None,
|
||||
defines=None,
|
||||
just_dump=False,
|
||||
event=None,
|
||||
offline=False,
|
||||
):
|
||||
"""Load Pungi config file, validate it, optionally resolve Git references,
|
||||
and dump created JSON to a given stream.
|
||||
|
||||
:param callable callback: a callable to call with parsed config
|
||||
:param dict defines: mapping of values to define before parsing the config
|
||||
:param bool just_dump: skip validation and adding default values
|
||||
:param int event: Koji event to hardcode into the config
|
||||
:param bool offline: skip resolving Git references
|
||||
:returns: False if validation failed, True otherwise
|
||||
"""
|
||||
conf = kobo.conf.PyConfigParser()
|
||||
conf.load_from_dict(defines or {})
|
||||
|
||||
for source in sources:
|
||||
load_source(source, conf)
|
||||
|
||||
if not just_dump:
|
||||
errors, _ = pungi.checks.validate(conf, offline=offline)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
return False
|
||||
|
||||
if event:
|
||||
conf["koji_event"] = event
|
||||
|
||||
# Clean up defines from the final final config. We don't want to keep them
|
||||
# as they would cause warnings during validation.
|
||||
for key in defines:
|
||||
del conf[key]
|
||||
|
||||
if callback:
|
||||
callback(conf)
|
||||
|
||||
json.dump(conf, out, sort_keys=True, indent=4)
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
@ -84,34 +174,39 @@ def main():
|
||||
group.add_argument(
|
||||
"--offline", action="store_true", help="Do not resolve git references."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--multi",
|
||||
metavar="DIR",
|
||||
help=(
|
||||
"Treat source as config for pungi-orchestrate and store dump into "
|
||||
"given directory."
|
||||
),
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
defines = dict(var.split("=", 1) for var in args.define)
|
||||
|
||||
conf = kobo.conf.PyConfigParser()
|
||||
conf.load_from_dict(defines)
|
||||
if args.multi:
|
||||
if len(args.sources) > 1:
|
||||
parser.error("Only one multi config can be specified.")
|
||||
|
||||
for source in args.sources:
|
||||
load_source(source, conf)
|
||||
return dump_multi_config(
|
||||
args.sources[0],
|
||||
dest=args.multi,
|
||||
defines=defines,
|
||||
just_dump=args.just_dump,
|
||||
event=args.freeze_event,
|
||||
offline=args.offline,
|
||||
)
|
||||
|
||||
if not args.just_dump:
|
||||
errors, _ = pungi.checks.validate(conf, offline=args.offline)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
return False
|
||||
|
||||
if args.freeze_event:
|
||||
conf["koji_event"] = args.freeze_event
|
||||
|
||||
# Clean up defines from the final final config. We don't want to keep them
|
||||
# as they would cause warnings during validation.
|
||||
for key in defines:
|
||||
del conf[key]
|
||||
|
||||
json.dump(conf, sys.stdout, sort_keys=True, indent=4)
|
||||
return True
|
||||
return process_file(
|
||||
args.sources,
|
||||
defines=defines,
|
||||
just_dump=args.just_dump,
|
||||
event=args.freeze_event,
|
||||
offline=args.offline,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user