def validate(manifest: Dict, index: Index) -> ValidationResult: """Validate a OSBuild manifest This function will validate a OSBuild manifest, including all its stages and assembler and build manifests. It will try to validate as much as possible and not stop on errors. The result is a `ValidationResult` object that can be used to check the overall validation status and iterate all the individual validation errors. """ schema = index.get_schema("Manifest") result = schema.validate(manifest) # main pipeline pipeline = manifest.get("pipeline", {}) # recursively validate the build pipeline as a "normal" # pipeline in order to validate its stages and assembler # options; for this it is being re-parented in a new plain # {"pipeline": ...} dictionary. NB: Any nested structural # errors might be detected twice, but de-duplicated by the # `ValidationResult.merge` call build = pipeline.get("build", {}).get("pipeline") if build: res = validate({"pipeline": build}, index=index) result.merge(res, path=["pipeline", "build"]) stages = pipeline.get("stages", []) for i, stage in enumerate(stages): name = stage["name"] schema = index.get_schema("Stage", name) res = schema.validate(stage) result.merge(res, path=["pipeline", "stages", i]) asm = pipeline.get("assembler", {}) if asm: name = asm["name"] schema = index.get_schema("Assembler", name) res = schema.validate(asm) result.merge(res, path=["pipeline", "assembler"]) # sources sources = manifest.get("sources", {}) for name, source in sources.items(): if name == "org.osbuild.files": name = "org.osbuild.curl" schema = index.get_schema("Source", name) res = schema.validate(source) result.merge(res, path=["sources", name]) return result
def validate(manifest: Dict, index: Index) -> ValidationResult: schema = index.get_schema("Manifest", version="2") result = schema.validate(manifest) def validate_module(mod, klass, path): name = mod.get("type") if not name: return schema = index.get_schema(klass, name, version="2") res = schema.validate(mod) result.merge(res, path=path) def validate_stage_modules(klass, stage, path): group = ModuleInfo.MODULES[klass] items = stage.get(group, {}) if isinstance(items, list): items = {i["name"]: i for i in items} for name, mod in items.items(): validate_module(mod, klass, path + [group, name]) def validate_stage(stage, path): name = stage["type"] schema = index.get_schema("Stage", name, version="2") res = schema.validate(stage) result.merge(res, path=path) for mod in ("Device", "Input", "Mount"): validate_stage_modules(mod, stage, path) def validate_pipeline(pipeline, path): stages = pipeline.get("stages", []) for i, stage in enumerate(stages): validate_stage(stage, path + ["stages", i]) # sources sources = manifest.get("sources", {}) for name, source in sources.items(): schema = index.get_schema("Source", name, version="2") res = schema.validate(source) result.merge(res, path=["sources", name]) # pipelines pipelines = manifest.get("pipelines", []) for i, pipeline in enumerate(pipelines): validate_pipeline(pipeline, path=["pipelines", i]) return result
def validate(manifest: Dict, index: Index) -> ValidationResult: schema = index.get_schema("Manifest", version="2") result = schema.validate(manifest) def validate_input(ip, path): name = ip["type"] schema = index.get_schema("Input", name, version="2") res = schema.validate(ip) result.merge(res, path=path) def validate_stage(stage, path): name = stage["type"] schema = index.get_schema("Stage", name, version="2") res = schema.validate(stage) result.merge(res, path=path) inputs = stage.get("inputs", {}) for name, ip in inputs.items(): validate_input(ip, path + ["inputs", name]) def validate_pipeline(pipeline, path): stages = pipeline.get("stages", []) for i, stage in enumerate(stages): validate_stage(stage, path + ["stages", i]) # sources sources = manifest.get("sources", {}) for name, source in sources.items(): schema = index.get_schema("Source", name, version="2") res = schema.validate(source) result.merge(res, path=["sources", name]) # pipelines pipelines = manifest.get("pipelines", []) for i, pipeline in enumerate(pipelines): validate_pipeline(pipeline, path=["pipelines", i]) return result