Commit 845da3e8 authored by Iustin Pop's avatar Iustin Pop
Browse files

Fix unsafe variant initializer in _TryOSFromDisk



In case an OS has inconsistent declarations, we might get into a case
where one node reports a valid variants list (with OS API >=15), and
another node has OS API < 15, in which case its supported_variants gets
the default value of None. This leads to the same variable having
inconsistent data types, which leads to subtle bugs later: instead of
reporting something like "Inconsistent OS API versions", the LU exits
with a run-time exception. Furthermore, in another datapath, variants is
initialized to '[]' in case of OS diagnose failures.

The patch changes _TryOSFromDisk to initialize variants to '[]' for
OS api level below 15, and changes the variants calculation in
DiagnoseOS to be more readable.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 27137e55
...@@ -1851,7 +1851,7 @@ def _TryOSFromDisk(name, base_dir=None): ...@@ -1851,7 +1851,7 @@ def _TryOSFromDisk(name, base_dir=None):
return False, ("File '%s' under path '%s' is not executable" % return False, ("File '%s' under path '%s' is not executable" %
(filename, os_dir)) (filename, os_dir))
variants = None variants = []
if constants.OS_VARIANTS_FILE in os_files: if constants.OS_VARIANTS_FILE in os_files:
variants_file = os_files[constants.OS_VARIANTS_FILE] variants_file = os_files[constants.OS_VARIANTS_FILE]
try: try:
......
...@@ -2782,14 +2782,14 @@ class LUDiagnoseOS(NoHooksLU): ...@@ -2782,14 +2782,14 @@ class LUDiagnoseOS(NoHooksLU):
for osl in os_data.values(): for osl in os_data.values():
valid = valid and osl and osl[0][1] valid = valid and osl and osl[0][1]
if not valid: if not valid:
variants = None variants = set()
break break
if calc_variants: if calc_variants:
node_variants = osl[0][3] node_variants = osl[0][3]
if variants is None: if variants is None:
variants = node_variants variants = set(node_variants)
else: else:
variants = [v for v in variants if v in node_variants] variants.intersection_update(node_variants)
for field in self.op.output_fields: for field in self.op.output_fields:
if field == "name": if field == "name":
...@@ -2802,7 +2802,7 @@ class LUDiagnoseOS(NoHooksLU): ...@@ -2802,7 +2802,7 @@ class LUDiagnoseOS(NoHooksLU):
for node_name, nos_list in os_data.items(): for node_name, nos_list in os_data.items():
val[node_name] = nos_list val[node_name] = nos_list
elif field == "variants": elif field == "variants":
val = variants val = list(variants)
else: else:
raise errors.ParameterError(field) raise errors.ParameterError(field)
row.append(val) row.append(val)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment