pungi/bin/pungi-config-validate

193 lines
5.9 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import json
import os
import sys
import six
here = sys.path[0]
if here != '/usr/bin':
# Git checkout
sys.path[0] = os.path.dirname(here)
import pungi.checks
import pungi.compose
import pungi.paths
import pungi.phases
import pungi.wrappers.scm
import pungi.util
from pungi.wrappers.variants import VariantsXmlParser, VariantsValidationError
from pungi_utils import config_utils
class ValidationCompose(pungi.compose.Compose):
def __init__(self, conf, has_old, topdir):
self.topdir = topdir
self.conf = conf
self._logger = None
self.just_phases = []
self.skip_phases = []
self.has_old_composes = has_old
self.paths = pungi.paths.Paths(self)
self.variants = {}
self.all_variants = {}
@property
def old_composes(self):
return '/dummy' if self.has_old_composes else None
@property
def compose_id(self):
return 'Dummy-1.0-20160811.t.0'
@property
def compose_type(self):
return 'test'
@property
def compose_date(self):
return '20160811'
@property
def compose_respin(self):
return '0'
def read_variants(compose, config):
with pungi.util.temp_dir() as tmp_dir:
scm_dict = compose.conf["variants_file"]
if isinstance(scm_dict, six.string_types) and scm_dict[0] != '/':
config_dir = os.path.dirname(config)
scm_dict = os.path.join(config_dir, scm_dict)
files = pungi.wrappers.scm.get_file_from_scm(scm_dict, tmp_dir)
tree_arches = compose.conf.get("tree_arches")
tree_variants = compose.conf.get("tree_variants")
with open(os.path.join(tmp_dir, files[0]), "r") as file_obj:
parser = VariantsXmlParser(file_obj, tree_arches, tree_variants)
compose.variants = parser.parse()
for variant in compose.variants.values():
compose.all_variants[variant.uid] = variant
for child in variant.get_variants():
compose.all_variants[child.uid] = child
def run(config, topdir, has_old, offline, defined_variables):
# Load default values for undefined variables. This is useful for
# validating templates that are supposed to be filled in later with
# pungi-config-dump.
try:
defaults_file = os.path.join(
os.path.dirname(config), ".pungi-config-validate.json"
)
with open(defaults_file) as f:
defined_variables.update(json.load(f))
except IOError:
pass
# Load actual configuration
conf = pungi.util.load_config(config, defined_variables)
# Remove the dummy variables used for defaults.
config_utils.remove_unknown(conf, defined_variables)
errors, warnings = pungi.checks.validate(conf, offline=offline)
if errors or warnings:
for error in errors + warnings:
print(error)
sys.exit(1)
errors = []
compose = ValidationCompose(conf, has_old, topdir)
try:
read_variants(compose, config)
except VariantsValidationError as exc:
errors.extend(str(exc).splitlines())
except RuntimeError as exc:
print("WARNING: Failed to load variants: %s" % exc)
pkgset_phase = pungi.phases.PkgsetPhase(compose)
buildinstall_phase = pungi.phases.BuildinstallPhase(compose)
phases = [
pungi.phases.InitPhase(compose),
buildinstall_phase,
pkgset_phase,
pungi.phases.GatherPhase(compose, pkgset_phase),
pungi.phases.ExtraFilesPhase(compose, pkgset_phase),
pungi.phases.CreaterepoPhase(compose),
pungi.phases.OstreeInstallerPhase(compose, buildinstall_phase),
pungi.phases.OSTreePhase(compose),
pungi.phases.ProductimgPhase(compose, pkgset_phase),
pungi.phases.CreateisoPhase(compose, buildinstall_phase),
pungi.phases.ExtraIsosPhase(compose),
pungi.phases.LiveImagesPhase(compose),
pungi.phases.LiveMediaPhase(compose),
pungi.phases.ImageBuildPhase(compose),
pungi.phases.ImageChecksumPhase(compose),
pungi.phases.TestPhase(compose),
]
for phase in phases:
if phase.skip():
continue
try:
phase.validate()
except ValueError as ex:
for i in str(ex).splitlines():
errors.append("%s: %s" % (phase.name.upper(), i))
return errors
class DumpSchemaAction(argparse.Action):
def __call__(self, parser, ns, values, option_string=None):
json.dump(pungi.checks.make_schema(), sys.stdout,
sort_keys=True, indent=4)
print('')
sys.exit(0)
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('--dump-schema', nargs=0, action=DumpSchemaAction,
help='print JSON Schema of configuration and exit')
parser.add_argument('config', metavar='CONFIG',
help='configuration file to validate')
parser.add_argument('--old-composes', action='store_true',
help='indicate if pungi-koji will be run with --old-composes option')
parser.add_argument(
"--offline",
action="store_true",
help="Do not validate git references in URLs",
)
parser.add_argument(
"-e",
"--define",
action="append",
default=[],
metavar="VAR=VALUE",
type=config_utils.validate_definition,
help=(
"Define a variable on command line and inject it into the config file. "
"Can be used multiple times."
),
)
opts = parser.parse_args(args)
defines = config_utils.extract_defines(opts.define)
with pungi.util.temp_dir() as topdir:
errors = run(opts.config, topdir, opts.old_composes, opts.offline, defines)
for msg in errors:
print(msg)
return bool(errors)
if __name__ == '__main__':
if main():
sys.exit(1)