Manifest parsing: skip invalid manifest files (#32467)
* catch json schema errors and reraise as property of SpackError * no need to catch subclass of given error * Builtin json library for Python 2 uses more generic type * Correct instantiation of SpackError (requires a string rather than an exception) * Use exception chaining (where possible)
This commit is contained in:
parent
ebb20eb8f8
commit
7971985a06
@ -219,7 +219,7 @@ def _collect_and_consume_cray_manifest_files(
|
|||||||
tty.debug("Reading manifest file: " + path)
|
tty.debug("Reading manifest file: " + path)
|
||||||
try:
|
try:
|
||||||
cray_manifest.read(path, not dry_run)
|
cray_manifest.read(path, not dry_run)
|
||||||
except (spack.compilers.UnknownCompilerError, spack.error.SpackError) as e:
|
except spack.error.SpackError as e:
|
||||||
if fail_on_error:
|
if fail_on_error:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
|
import jsonschema.exceptions
|
||||||
import six
|
import six
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
@ -161,10 +163,21 @@ def entries_to_specs(entries):
|
|||||||
|
|
||||||
|
|
||||||
def read(path, apply_updates):
|
def read(path, apply_updates):
|
||||||
with open(path, "r") as json_file:
|
if sys.version_info >= (3, 0):
|
||||||
json_data = json.load(json_file)
|
decode_exception_type = json.decoder.JSONDecodeError
|
||||||
|
else:
|
||||||
|
decode_exception_type = ValueError
|
||||||
|
|
||||||
jsonschema.validate(json_data, manifest_schema)
|
try:
|
||||||
|
with open(path, "r") as json_file:
|
||||||
|
json_data = json.load(json_file)
|
||||||
|
|
||||||
|
jsonschema.validate(json_data, manifest_schema)
|
||||||
|
except (jsonschema.exceptions.ValidationError, decode_exception_type) as e:
|
||||||
|
raise six.raise_from(
|
||||||
|
ManifestValidationError("error parsing manifest JSON:", str(e)),
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
|
||||||
specs = entries_to_specs(json_data["specs"])
|
specs = entries_to_specs(json_data["specs"])
|
||||||
tty.debug("{0}: {1} specs read from manifest".format(path, str(len(specs))))
|
tty.debug("{0}: {1} specs read from manifest".format(path, str(len(specs))))
|
||||||
@ -179,3 +192,8 @@ def read(path, apply_updates):
|
|||||||
if apply_updates:
|
if apply_updates:
|
||||||
for spec in specs.values():
|
for spec in specs.values():
|
||||||
spack.store.db.add(spec, directory_layout=None)
|
spack.store.db.add(spec, directory_layout=None)
|
||||||
|
|
||||||
|
|
||||||
|
class ManifestValidationError(spack.error.SpackError):
|
||||||
|
def __init__(self, msg, long_msg=None):
|
||||||
|
super(ManifestValidationError, self).__init__(msg, long_msg)
|
||||||
|
@ -365,3 +365,38 @@ def test_read_old_manifest_v1_2(tmpdir, mutable_config, mock_packages, mutable_d
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
cray_manifest.read(manifest_file_path, True)
|
cray_manifest.read(manifest_file_path, True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_validation_error(tmpdir, mutable_config, mock_packages, mutable_database):
|
||||||
|
manifest_dir = str(tmpdir.mkdir("manifest_dir"))
|
||||||
|
# Does not parse as valid JSON
|
||||||
|
invalid_json_path = os.path.join(manifest_dir, "invalid-json.json")
|
||||||
|
with open(invalid_json_path, "w") as f:
|
||||||
|
f.write(
|
||||||
|
"""\
|
||||||
|
{
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
with pytest.raises(cray_manifest.ManifestValidationError) as e:
|
||||||
|
cray_manifest.read(invalid_json_path, True)
|
||||||
|
str(e)
|
||||||
|
|
||||||
|
# Valid JSON, but does not conform to schema (schema-version is not a string
|
||||||
|
# of length > 0)
|
||||||
|
invalid_schema_path = os.path.join(manifest_dir, "invalid-schema.json")
|
||||||
|
with open(invalid_schema_path, "w") as f:
|
||||||
|
f.write(
|
||||||
|
"""\
|
||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"file-type": "cray-pe-json",
|
||||||
|
"system-type": "EX",
|
||||||
|
"schema-version": ""
|
||||||
|
},
|
||||||
|
"specs": []
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
with pytest.raises(cray_manifest.ManifestValidationError) as e:
|
||||||
|
cray_manifest.read(invalid_schema_path, True)
|
||||||
|
str(e)
|
||||||
|
Loading…
Reference in New Issue
Block a user