verify: added ignore-missing mode
The verify command can now be run in ignore-missing mode. In this mode missing/non-supported settings (i.e. those which current value is None) are ignored and not treated as errors. The tuned-adm got new verify options -i and --ignore-missing which enables the ignore-missing mode, usage: tuned-adm verify -i or: tuned-adm verify --ignore-missing The DBus interface got new method 'verify_profile_ignore_missing' which does the verification in ignore-missing mode. Resolves: rhbz#1243807 Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
parent
b556805fe3
commit
a174592cfd
13 changed files with 67 additions and 44 deletions
|
|
@ -56,8 +56,9 @@ if __name__ == "__main__":
|
|||
parser_off = subparsers.add_parser("recommend", help="recommend profile")
|
||||
parser_off.set_defaults(action="recommend_profile")
|
||||
|
||||
parser_off = subparsers.add_parser("verify", help="verify profile")
|
||||
parser_off.set_defaults(action="verify_profile")
|
||||
parser_verify = subparsers.add_parser("verify", help="verify profile")
|
||||
parser_verify.set_defaults(action="verify_profile")
|
||||
parser_verify.add_argument("--ignore-missing", "-i", action="store_true", help="do not treat missing/non-supported tunings as errors")
|
||||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
|
|
|
|||
|
|
@ -180,17 +180,21 @@ class Admin(object):
|
|||
profile = self._cmd.recommend_profile()
|
||||
print profile
|
||||
|
||||
def verify_profile(self):
|
||||
def verify_profile(self, ignore_missing):
|
||||
ret = False
|
||||
if self._controller is None:
|
||||
print "Not supported in no_daemon mode."
|
||||
return False
|
||||
try:
|
||||
ret = self._controller.verify_profile()
|
||||
except TunedAdminDBusException as e:
|
||||
self._error(e)
|
||||
self._error("Cannot verify profile if there is no connection to daemon")
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
if ignore_missing:
|
||||
ret = self._controller.verify_profile_ignore_missing()
|
||||
else:
|
||||
ret = self._controller.verify_profile()
|
||||
except TunedAdminDBusException as e:
|
||||
self._error(e)
|
||||
self._error("Cannot verify profile if there is no compatible running Tuned daemon (or Tuned daemon is too old).")
|
||||
return False
|
||||
|
||||
if ret:
|
||||
print "Verfication succeeded, current system settings match the preset profile."
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ class DBusController(object):
|
|||
def verify_profile(self):
|
||||
return self._call("verify_profile")
|
||||
|
||||
def verify_profile_ignore_missing(self):
|
||||
return self._call("verify_profile_ignore_missing")
|
||||
|
||||
def off(self):
|
||||
return self._call("disable")
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ DBUS_SIGNAL_PROFILE_CHANGED = "profile_changed"
|
|||
STR_VERIFY_PROFILE_DEVICE_VALUE_OK = "verify: passed: device %s: %s = %s"
|
||||
STR_VERIFY_PROFILE_VALUE_OK = "verify: passed: %s = %s"
|
||||
STR_VERIFY_PROFILE_OK = "verify: passed: %s"
|
||||
STR_VERIFY_PROFILE_DEVICE_VALUE_MISSING = "verify: skipped, missing: device %s: %s"
|
||||
STR_VERIFY_PROFILE_VALUE_MISSING = "verify: skipped, missing: %s"
|
||||
STR_VERIFY_PROFILE_DEVICE_VALUE_FAIL = "verify: failed: device %s: %s = %s, expected %s"
|
||||
STR_VERIFY_PROFILE_VALUE_FAIL = "verify: failed: %s = %s, expected %s"
|
||||
STR_VERIFY_PROFILE_FAIL = "verify: failed: %s"
|
||||
|
|
|
|||
|
|
@ -126,4 +126,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
|
|||
|
||||
@exports.export("", "b")
|
||||
def verify_profile(self):
|
||||
return self._daemon.verify_profile()
|
||||
return self._daemon.verify_profile(ignore_missing = False)
|
||||
|
||||
@exports.export("", "b")
|
||||
def verify_profile_ignore_missing(self):
|
||||
return self._daemon.verify_profile(ignore_missing = True)
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ class Daemon(object):
|
|||
self._thread.start()
|
||||
return True
|
||||
|
||||
def verify_profile(self):
|
||||
def verify_profile(self, ignore_missing):
|
||||
if not self.is_running():
|
||||
log.error("tuned is not running")
|
||||
return False
|
||||
|
|
@ -213,7 +213,7 @@ class Daemon(object):
|
|||
# using deamon, the main loop mustn't exit before our completion
|
||||
self._not_used.clear()
|
||||
log.info("verifying profile(s): %s" % self._profile.name)
|
||||
ret = self._unit_manager.verify_tuning()
|
||||
ret = self._unit_manager.verify_tuning(ignore_missing)
|
||||
# main loop is allowed to exit
|
||||
self._not_used.set()
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ class Plugin(object):
|
|||
if instance.has_dynamic_tuning and self._global_cfg.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING):
|
||||
self._run_for_each_device(instance, self._instance_apply_dynamic)
|
||||
|
||||
def instance_verify_tuning(self, instance):
|
||||
def instance_verify_tuning(self, instance, ignore_missing):
|
||||
"""
|
||||
Verify static tuning if the plugin instance is active.
|
||||
"""
|
||||
|
|
@ -200,7 +200,7 @@ class Plugin(object):
|
|||
return None
|
||||
|
||||
if instance.has_static_tuning:
|
||||
return self._instance_verify_static(instance)
|
||||
return self._instance_verify_static(instance, ignore_missing)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -227,11 +227,11 @@ class Plugin(object):
|
|||
self._execute_all_non_device_commands(instance)
|
||||
self._execute_all_device_commands(instance, instance.devices)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
def _instance_verify_static(self, instance, ignore_missing):
|
||||
ret = True
|
||||
if self._verify_all_non_device_commands(instance) == False:
|
||||
if self._verify_all_non_device_commands(instance, ignore_missing) == False:
|
||||
ret = False
|
||||
if self._verify_all_device_commands(instance, instance.devices) == False:
|
||||
if self._verify_all_device_commands(instance, instance.devices, ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
|
|
@ -346,23 +346,23 @@ class Plugin(object):
|
|||
for device in devices:
|
||||
self._execute_device_command(instance, command, device, new_value)
|
||||
|
||||
def _verify_all_non_device_commands(self, instance):
|
||||
def _verify_all_non_device_commands(self, instance, ignore_missing):
|
||||
ret = True
|
||||
for command in filter(lambda command: not command["per_device"], self._commands.values()):
|
||||
new_value = self._variables.expand(instance.options.get(command["name"], None))
|
||||
if new_value is not None:
|
||||
if self._verify_non_device_command(instance, command, new_value) == False:
|
||||
if self._verify_non_device_command(instance, command, new_value, ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def _verify_all_device_commands(self, instance, devices):
|
||||
def _verify_all_device_commands(self, instance, devices, ignore_missing):
|
||||
ret = True
|
||||
for command in filter(lambda command: command["per_device"], self._commands.values()):
|
||||
new_value = instance.options.get(command["name"], None)
|
||||
if new_value is None:
|
||||
continue
|
||||
for device in devices:
|
||||
if self._verify_device_command(instance, command, device, new_value) == False:
|
||||
if self._verify_device_command(instance, command, device, new_value, ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
|
|
@ -423,10 +423,17 @@ class Plugin(object):
|
|||
return re.sub(r'^\s*(0+,)+', "", v)
|
||||
return v
|
||||
|
||||
def _verify_value(self, name, new_value, current_value, device = None):
|
||||
def _verify_value(self, name, new_value, current_value, ignore_missing, device = None):
|
||||
if new_value is None:
|
||||
return None
|
||||
ret = False
|
||||
if current_value is None and ignore_missing:
|
||||
if device is None:
|
||||
log.info(consts.STR_VERIFY_PROFILE_VALUE_MISSING % name)
|
||||
else:
|
||||
log.info(consts.STR_VERIFY_PROFILE_DEVICE_VALUE_MISSING % (device, name))
|
||||
return True
|
||||
|
||||
if current_value is not None:
|
||||
current_value = self._norm_value(current_value)
|
||||
new_value = self._norm_value(new_value)
|
||||
|
|
@ -450,7 +457,7 @@ class Plugin(object):
|
|||
log.error(consts.STR_VERIFY_PROFILE_DEVICE_VALUE_FAIL % (device, name, str(current_value).strip(), str(new_value).strip()))
|
||||
return False
|
||||
|
||||
def _verify_device_command(self, instance, command, device, new_value):
|
||||
def _verify_device_command(self, instance, command, device, new_value, ignore_missing):
|
||||
if command["custom"] is not None:
|
||||
return command["custom"](True, new_value, device, True)
|
||||
current_value = self._get_current_value(command, device)
|
||||
|
|
@ -458,9 +465,9 @@ class Plugin(object):
|
|||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, device, True)
|
||||
return self._verify_value(command["name"], new_value, current_value, device)
|
||||
return self._verify_value(command["name"], new_value, current_value, ignore_missing, device)
|
||||
|
||||
def _verify_non_device_command(self, instance, command, new_value):
|
||||
def _verify_non_device_command(self, instance, command, new_value, ignore_missing):
|
||||
if command["custom"] is not None:
|
||||
return command["custom"](True, new_value, True)
|
||||
current_value = self._get_current_value(command)
|
||||
|
|
@ -468,7 +475,7 @@ class Plugin(object):
|
|||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, True)
|
||||
return self._verify_value(command["name"], new_value, current_value)
|
||||
return self._verify_value(command["name"], new_value, current_value, ignore_missing)
|
||||
|
||||
def _cleanup_all_non_device_commands(self, instance):
|
||||
for command in filter(lambda command: not command["per_device"], self._commands.values()):
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class Instance(object):
|
|||
def apply_tuning(self):
|
||||
self._plugin.instance_apply_tuning(self)
|
||||
|
||||
def verify_tuning(self):
|
||||
return self._plugin.instance_verify_tuning(self)
|
||||
def verify_tuning(self, ignore_missing):
|
||||
return self._plugin.instance_verify_tuning(self, ignore_missing)
|
||||
|
||||
def update_tuning(self):
|
||||
self._plugin.instance_update_tuning(self)
|
||||
|
|
|
|||
|
|
@ -52,11 +52,14 @@ class ScriptPlugin(base.Plugin):
|
|||
super(self.__class__, self)._instance_apply_static(instance)
|
||||
self._call_scripts(instance._scripts, ["start"])
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
def _instance_verify_static(self, instance, ignore_missing):
|
||||
ret = True
|
||||
if super(self.__class__, self)._instance_verify_static(instance) == False:
|
||||
if super(self.__class__, self)._instance_verify_static(instance, ignore_missing) == False:
|
||||
ret = False
|
||||
if self._call_scripts(instance._scripts, ["verify"]) == True:
|
||||
args = ["verify"]
|
||||
if ignore_missing:
|
||||
args += ["ignore_missing"]
|
||||
if self._call_scripts(instance._scripts, args) == True:
|
||||
log.info(consts.STR_VERIFY_PROFILE_OK % instance._scripts)
|
||||
else:
|
||||
log.error(consts.STR_VERIFY_PROFILE_FAIL % instance._scripts)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from decorators import *
|
|||
import tuned.logs
|
||||
from subprocess import *
|
||||
from tuned.utils.commands import commands
|
||||
import tuned.consts as consts
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
|
|
@ -47,16 +48,14 @@ class SysctlPlugin(base.Plugin):
|
|||
|
||||
self._storage.set("options", instance._sysctl_original)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
def _instance_verify_static(self, instance, ignore_missing):
|
||||
ret = True
|
||||
# override, so always skip missing
|
||||
ignore_missing = True
|
||||
for option, value in instance._sysctl.iteritems():
|
||||
curr_val = self._read_sysctl(option)
|
||||
if curr_val is None:
|
||||
log.warn("verify: option '%s' is None, option is probably unavailable/unsupported on your system, skipping it",
|
||||
str(option))
|
||||
else:
|
||||
if self._verify_value(option, self._cmd.remove_ws(self._variables.expand(value)), curr_val) == False:
|
||||
ret = False
|
||||
if self._verify_value(option, self._cmd.remove_ws(self._variables.expand(value)), curr_val, ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def _instance_unapply_static(self, instance, profile_switch = False):
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ class SysfsPlugin(base.Plugin):
|
|||
else:
|
||||
log.error("rejecting write to '%s' (not inside /sys)" % f)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
def _instance_verify_static(self, instance, ignore_missing):
|
||||
ret = True
|
||||
for key, value in instance._sysfs.iteritems():
|
||||
v = self._variables.expand(value)
|
||||
for f in glob.iglob(key):
|
||||
if self._check_sysfs(f):
|
||||
curr_val = self._read_sysfs(f)
|
||||
if self._verify_value(f, v, curr_val) == False:
|
||||
if self._verify_value(f, v, curr_val, ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class VideoPlugin(base.Plugin):
|
|||
if not os.path.exists(sys_files["method"]):
|
||||
if not sim:
|
||||
log.warn("radeon_powersave is not supported on '%s'" % device)
|
||||
return None
|
||||
return None
|
||||
|
||||
if value in ["default", "auto", "low", "mid", "high"]:
|
||||
if not sim:
|
||||
|
|
@ -73,4 +73,4 @@ class VideoPlugin(base.Plugin):
|
|||
elif method == "dynpm":
|
||||
return "dynpm"
|
||||
else:
|
||||
return None
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ class Manager(object):
|
|||
for instance in self._instances:
|
||||
instance.apply_tuning()
|
||||
|
||||
def verify_tuning(self):
|
||||
def verify_tuning(self, ignore_missing):
|
||||
ret = True
|
||||
for instance in self._instances:
|
||||
if instance.verify_tuning() == False:
|
||||
if instance.verify_tuning(ignore_missing) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue