Commit 305a7297 authored by Guido Trotter's avatar Guido Trotter
Browse files

Ship (and display) path for InvalidOS errors too.

- Document the expected change to errors.InvalidOS
- Always pass the additional argument
- Modify DiagnoseOS output to show the path


Reviewed-by: iustinp, imsnah
parent 319856a9
......@@ -887,7 +887,7 @@ def _OSSearch(name, search_path=None):
Args:
name: The name of the OS to look for
search_path: List of dirs to search (defaults to constants.OS_SEARCH_PATH)
Returns:
The base_dir the OS resides in
......@@ -919,11 +919,11 @@ def _OSOndiskVersion(name, os_dir):
try:
st = os.stat(api_file)
except EnvironmentError, err:
raise errors.InvalidOS(name, "'ganeti_api_version' file not"
raise errors.InvalidOS(name, os_dir, "'ganeti_api_version' file not"
" found (%s)" % _ErrnoOrStr(err))
if not stat.S_ISREG(stat.S_IFMT(st.st_mode)):
raise errors.InvalidOS(name, "'ganeti_api_version' file is not"
raise errors.InvalidOS(name, os_dir, "'ganeti_api_version' file is not"
" a regular file")
try:
......@@ -933,14 +933,15 @@ def _OSOndiskVersion(name, os_dir):
finally:
f.close()
except EnvironmentError, err:
raise errors.InvalidOS(name, "error while reading the"
raise errors.InvalidOS(name, os_dir, "error while reading the"
" API version (%s)" % _ErrnoOrStr(err))
api_version = api_version.strip()
try:
api_version = int(api_version)
except (TypeError, ValueError), err:
raise errors.InvalidOS(name, "API version is not integer (%s)" % str(err))
raise errors.InvalidOS(name, os_dir,
"API version is not integer (%s)" % str(err))
return api_version
......@@ -1000,13 +1001,14 @@ def OSFromDisk(name, base_dir=None):
raise errors.InvalidOS(name, "OS not found in base dir %s" % base_dir)
if base_dir is None:
raise errors.InvalidOS(name, "OS dir not found in search path")
raise errors.InvalidOS(name, None, "OS dir not found in search path")
os_dir = os.path.sep.join([base_dir, name])
api_version = _OSOndiskVersion(name, os_dir)
if api_version != constants.OS_API_VERSION:
raise errors.InvalidOS(name, "API version mismatch (found %s want %s)"
raise errors.InvalidOS(name, os_dir, "API version mismatch"
" (found %s want %s)"
% (api_version, constants.OS_API_VERSION))
# OS Scripts dictionary, we will populate it with the actual script names
......@@ -1018,14 +1020,16 @@ def OSFromDisk(name, base_dir=None):
try:
st = os.stat(os_scripts[script])
except EnvironmentError, err:
raise errors.InvalidOS(name, "'%s' script missing (%s)" %
raise errors.InvalidOS(name, os_dir, "'%s' script missing (%s)" %
(script, _ErrnoOrStr(err)))
if stat.S_IMODE(st.st_mode) & stat.S_IXUSR != stat.S_IXUSR:
raise errors.InvalidOS(name, "'%s' script not executable" % script)
raise errors.InvalidOS(name, os_dir, "'%s' script not executable" %
script)
if not stat.S_ISREG(stat.S_IFMT(st.st_mode)):
raise errors.InvalidOS(name, "'%s' is not a regular file" % script)
raise errors.InvalidOS(name, os_dir, "'%s' is not a regular file" %
script)
return objects.OS(name=name, path=os_dir,
......
......@@ -25,7 +25,7 @@ from ganeti import _autoconf
# various versions
CONFIG_VERSION = 3
PROTOCOL_VERSION = 2
PROTOCOL_VERSION = 3
RELEASE_VERSION = _autoconf.PACKAGE_VERSION
OS_API_VERSION = 5
EXPORT_VERSION = 0
......
......@@ -104,8 +104,9 @@ class InvalidOS(GenericError):
This is raised when an OS exists on the master (or is otherwise
requested to the code) but not on the target node.
This exception has two arguments:
This exception has three arguments:
- the name of the os
- the source directory, if any
- the reason why we consider this an invalid OS (text of error message)
"""
......
......@@ -607,8 +607,8 @@ def call_os_diagnose(node_list):
if data:
if isinstance(data, dict):
nr.append(objects.OS.FromDict(data))
elif isinstance(data, tuple) and len(data) == 2:
nr.append(errors.InvalidOS(data[0], data[1]))
elif isinstance(data, tuple) and len(data) == 3:
nr.append(errors.InvalidOS(data[0], data[1], data[2]))
else:
raise errors.ProgrammerError("Invalid data from"
" xcserver.os_diagnose")
......@@ -631,8 +631,8 @@ def call_os_get(node_list, name):
data = result[node_name]
if isinstance(data, dict):
new_result[node_name] = objects.OS.FromDict(data)
elif isinstance(data, tuple) and len(data) == 2:
new_result[node_name] = errors.InvalidOS(data[0], data[1])
elif isinstance(data, tuple) and len(data) == 3:
new_result[node_name] = errors.InvalidOS(data[0], data[1], data[2])
else:
new_result[node_name] = data
return new_result
......
......@@ -114,7 +114,8 @@ def DiagnoseOS(opts, args):
if isinstance(nos[0], objects.OS):
nodes_valid.append(node_name)
elif isinstance(nos[0], errors.InvalidOS):
nodes_bad[node_name] = nos[0].args[1]
nodes_bad[node_name] = ("%s (path: %s)" %
(nos[0].args[2], nos[0].args[1]))
else:
nodes_bad[node_name] = "os dir not found"
......@@ -128,8 +129,8 @@ def DiagnoseOS(opts, args):
logger.ToStdout(format % (max_name, os_name, max_node, status, ""))
nodes_valid = utils.NiceSort(nodes_valid)
for node_name in nodes_valid:
logger.ToStdout(format % (max_name, "", max_node, node_name,
"valid (%s)" % all_os[os_name][node_name][0].path))
logger.ToStdout(format % (max_name, "", max_node, node_name,
"valid (path: %s)" % all_os[os_name][node_name][0].path))
nbk = utils.NiceSort(nodes_bad.keys())
for node_name in nbk:
logger.ToStdout(format % (max_name, "", max_node,
......
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