From 09dfe23805b036f8719595cf5fb7d9bc2e745fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:19 +0100 Subject: [PATCH 01/12] Drop TunedLogger.set_level() Drop TunedLogger.set_level(). It doesn't appear to be used anywhere and it causes problems with Python3, because logging._levelNames doesn't exist anymore. --- tuned/logs.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tuned/logs.py b/tuned/logs.py index eaad009..b34c002 100644 --- a/tuned/logs.py +++ b/tuned/logs.py @@ -40,12 +40,6 @@ class TunedLogger(logging.getLoggerClass()): self.setLevel(logging.INFO) self.switch_to_console() - def set_level(self, level, default = logging.NOTSET): - """Set logging level. The 'level' parameter can be str or logging module constant.""" - if type(level) is str: - level = logging._levelNames.get(level.upper(), logging.NOTSET) - self.level = level - def switch_to_console(self): self._setup_console_handler() self.remove_all_handlers() From 560913b6e4b5e1bea6979377316cf7cb13074a19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:24 +0100 Subject: [PATCH 02/12] Deal with invalid uses of os.write() In python3, os.write() expects a bytestring, not a string as in python2. --- libexec/pmqos-static.py | 5 ++--- tuned/daemon/application.py | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libexec/pmqos-static.py b/libexec/pmqos-static.py index bf3d703..c6dc2c6 100755 --- a/libexec/pmqos-static.py +++ b/libexec/pmqos-static.py @@ -48,9 +48,8 @@ def close_fds(): os.dup2(s_err.fileno(), sys.stderr.fileno()) def write_pidfile(): - f = os.open(PIDFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644) - os.write(f, "%d" % os.getpid()) - os.close(f) + with os.fdopen(os.open(PIDFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644), "w") as f: + f.write("%d" % os.getpid()) def daemonize(): do_fork() diff --git a/tuned/daemon/application.py b/tuned/daemon/application.py index 9984d44..c8239a7 100644 --- a/tuned/daemon/application.py +++ b/tuned/daemon/application.py @@ -7,6 +7,7 @@ import signal import os import sys import select +import struct import tuned.consts as consts from tuned.utils.global_config import GlobalConfig @@ -89,7 +90,11 @@ class Application(object): if len(response) == 0: raise TunedException("Cannot daemonize, no response from child process received.") - if response != ("%c" % True): + try: + val = struct.unpack("?", response)[0] + except struct.error: + raise TunedException("Cannot daemonize, invalid response from child process received.") + if val != True: raise TunedException("Cannot daemonize, child process reports failure.") def write_pid_file(self, pid_file = consts.PID_FILE): @@ -100,9 +105,8 @@ class Application(object): if not os.path.exists(dir_name): os.makedirs(dir_name) - fd = os.open(self._pid_file, os.O_CREAT|os.O_TRUNC|os.O_WRONLY , 0o644) - os.write(fd, "%d" % os.getpid()) - os.close(fd) + with os.fdopen(os.open(self._pid_file, os.O_CREAT|os.O_TRUNC|os.O_WRONLY , 0o644), "w") as f: + f.write("%d" % os.getpid()) except (OSError,IOError) as error: log.critical("cannot write the PID to %s: %s" % (self._pid_file, str(error))) @@ -130,7 +134,8 @@ class Application(object): sys.exit(0) except OSError as error: log.critical("cannot daemonize, fork() error: %s" % str(error)) - os.write(child_out_fd, "%c" % False) + val = struct.pack("?", False) + os.write(child_out_fd, val) os.close(child_out_fd) raise TunedException("Cannot daemonize, second fork() failed.") @@ -144,7 +149,8 @@ class Application(object): self.write_pid_file(pid_file) log.debug("successfully daemonized") - os.write(child_out_fd, "%c" % True) + val = struct.pack("?", True) + os.write(child_out_fd, val) os.close(child_out_fd) def daemonize(self, pid_file = consts.PID_FILE): From e3ed58e16008a3b77e8838472902322f12a019cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:27 +0100 Subject: [PATCH 03/12] Fix calling methods of parent classes This fixes Pylint errors such as the following: tuned/logs.py:39: [E1003(bad-super-call), TunedLogger.__init__] \ Bad first argument 'self.__class__' given to super() This prevents infinite recursion errors, see https://stackoverflow.com/a/18208725 This does introduce name duplication, but when we drop python2 support in the future, we can use super() without arguments. --- tuned/daemon/controller.py | 2 +- tuned/exports/controller.py | 2 +- tuned/logs.py | 2 +- tuned/monitors/repository.py | 2 +- tuned/plugins/plugin_bootloader.py | 2 +- tuned/plugins/plugin_cpu.py | 6 +++--- tuned/plugins/plugin_disk.py | 8 ++++---- tuned/plugins/plugin_eeepc_she.py | 2 +- tuned/plugins/plugin_modules.py | 2 +- tuned/plugins/plugin_net.py | 2 +- tuned/plugins/plugin_scheduler.py | 6 +++--- tuned/plugins/plugin_script.py | 6 +++--- tuned/plugins/plugin_scsi_host.py | 8 ++++---- tuned/plugins/plugin_selinux.py | 2 +- tuned/plugins/plugin_sysctl.py | 2 +- tuned/plugins/plugin_sysfs.py | 2 +- tuned/plugins/plugin_systemd.py | 2 +- tuned/plugins/repository.py | 2 +- tuned/profiles/functions/function_assertion.py | 4 ++-- tuned/profiles/functions/function_assertion_non_equal.py | 4 ++-- tuned/profiles/functions/function_cpulist2hex.py | 4 ++-- tuned/profiles/functions/function_cpulist2hex_invert.py | 4 ++-- tuned/profiles/functions/function_cpulist_invert.py | 4 ++-- tuned/profiles/functions/function_cpulist_online.py | 4 ++-- tuned/profiles/functions/function_cpulist_pack.py | 4 ++-- tuned/profiles/functions/function_cpulist_present.py | 4 ++-- tuned/profiles/functions/function_cpulist_unpack.py | 4 ++-- tuned/profiles/functions/function_exec.py | 4 ++-- tuned/profiles/functions/function_hex2cpulist.py | 4 ++-- tuned/profiles/functions/function_kb2s.py | 4 ++-- tuned/profiles/functions/function_s2kb.py | 4 ++-- tuned/profiles/functions/function_strip.py | 4 ++-- tuned/profiles/functions/function_virt_check.py | 4 ++-- tuned/profiles/functions/repository.py | 2 +- tuned/units/manager.py | 2 +- 35 files changed, 62 insertions(+), 62 deletions(-) diff --git a/tuned/daemon/controller.py b/tuned/daemon/controller.py index c0adb75..9cde2d6 100644 --- a/tuned/daemon/controller.py +++ b/tuned/daemon/controller.py @@ -17,7 +17,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface): """ def __init__(self, daemon, global_config): - super(self.__class__, self).__init__() + super(Controller, self).__init__() self._daemon = daemon self._global_config = global_config self._terminate = threading.Event() diff --git a/tuned/exports/controller.py b/tuned/exports/controller.py index b33497d..611e9b4 100644 --- a/tuned/exports/controller.py +++ b/tuned/exports/controller.py @@ -8,7 +8,7 @@ class ExportsController(tuned.patterns.Singleton): """ def __init__(self): - super(self.__class__, self).__init__() + super(ExportsController, self).__init__() self._exporters = [] self._objects = [] self._exports_initialized = False diff --git a/tuned/logs.py b/tuned/logs.py index b34c002..e3da574 100644 --- a/tuned/logs.py +++ b/tuned/logs.py @@ -36,7 +36,7 @@ class TunedLogger(logging.getLoggerClass()): _file_handler = None def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(TunedLogger, self).__init__(*args, **kwargs) self.setLevel(logging.INFO) self.switch_to_console() diff --git a/tuned/monitors/repository.py b/tuned/monitors/repository.py index 445da16..cc89e0d 100644 --- a/tuned/monitors/repository.py +++ b/tuned/monitors/repository.py @@ -9,7 +9,7 @@ __all__ = ["Repository"] class Repository(PluginLoader): def __init__(self): - super(self.__class__, self).__init__() + super(Repository, self).__init__() self._monitors = set() @property diff --git a/tuned/plugins/plugin_bootloader.py b/tuned/plugins/plugin_bootloader.py index 9987c90..a0dca11 100644 --- a/tuned/plugins/plugin_bootloader.py +++ b/tuned/plugins/plugin_bootloader.py @@ -22,7 +22,7 @@ class BootloaderPlugin(base.Plugin): def __init__(self, *args, **kwargs): if not os.path.isfile(consts.GRUB2_TUNED_TEMPLATE_PATH): raise exceptions.NotSupportedPluginException("Required GRUB2 template not found, disabling plugin.") - super(self.__class__, self).__init__(*args, **kwargs) + super(BootloaderPlugin, self).__init__(*args, **kwargs) self._cmd = commands() def _instance_init(self, instance): diff --git a/tuned/plugins/plugin_cpu.py b/tuned/plugins/plugin_cpu.py index 624b782..6a5ea36 100644 --- a/tuned/plugins/plugin_cpu.py +++ b/tuned/plugins/plugin_cpu.py @@ -19,7 +19,7 @@ class CPULatencyPlugin(base.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(CPULatencyPlugin, self).__init__(*args, **kwargs) self._has_pm_qos = True self._has_energy_perf_bias = True @@ -142,7 +142,7 @@ class CPULatencyPlugin(base.Plugin): return v def _instance_apply_static(self, instance): - super(self.__class__, self)._instance_apply_static(instance) + super(CPULatencyPlugin, self)._instance_apply_static(instance) if not instance._first_instance: return @@ -156,7 +156,7 @@ class CPULatencyPlugin(base.Plugin): self._no_turbo_save = self._getset_intel_pstate_attr("no_turbo", instance.options["no_turbo"]) def _instance_unapply_static(self, instance, full_rollback = False): - super(self.__class__, self)._instance_unapply_static(instance, full_rollback) + super(CPULatencyPlugin, self)._instance_unapply_static(instance, full_rollback) if instance._first_instance and self._has_intel_pstate: self._set_intel_pstate_attr("min_perf_pct", self._min_perf_pct_save) diff --git a/tuned/plugins/plugin_disk.py b/tuned/plugins/plugin_disk.py index c1f743a..04f2dee 100644 --- a/tuned/plugins/plugin_disk.py +++ b/tuned/plugins/plugin_disk.py @@ -15,7 +15,7 @@ class DiskPlugin(hotplug.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(DiskPlugin, self).__init__(*args, **kwargs) self._power_levels = [254, 225, 195, 165, 145, 125, 105, 85, 70, 55, 30, 20] self._spindown_levels = [0, 250, 230, 210, 190, 170, 150, 130, 110, 90, 70, 60] @@ -51,17 +51,17 @@ class DiskPlugin(hotplug.Plugin): def _hardware_events_callback(self, event, device): if self._device_is_supported(device): - super(self.__class__, self)._hardware_events_callback(event, device) + super(DiskPlugin, self)._hardware_events_callback(event, device) def _added_device_apply_tuning(self, instance, device_name): if instance._load_monitor is not None: instance._load_monitor.add_device(device_name) - super(self.__class__, self)._added_device_apply_tuning(instance, device_name) + super(DiskPlugin, self)._added_device_apply_tuning(instance, device_name) def _removed_device_unapply_tuning(self, instance, device_name): if instance._load_monitor is not None: instance._load_monitor.remove_device(device_name) - super(self.__class__, self)._removed_device_unapply_tuning(instance, device_name) + super(DiskPlugin, self)._removed_device_unapply_tuning(instance, device_name) @classmethod def _get_config_options(cls): diff --git a/tuned/plugins/plugin_eeepc_she.py b/tuned/plugins/plugin_eeepc_she.py index 73572ae..3733a81 100644 --- a/tuned/plugins/plugin_eeepc_she.py +++ b/tuned/plugins/plugin_eeepc_she.py @@ -18,7 +18,7 @@ class EeePCSHEPlugin(base.Plugin): self._control_file = "/sys/devices/platform/eeepc-wmi/cpufv" if not os.path.isfile(self._control_file): raise exceptions.NotSupportedPluginException("Plugin is not supported on your hardware.") - super(self.__class__, self).__init__(*args, **kwargs) + super(EeePCSHEPlugin, self).__init__(*args, **kwargs) @classmethod def _get_config_options(self): diff --git a/tuned/plugins/plugin_modules.py b/tuned/plugins/plugin_modules.py index 2d117f0..241a58b 100644 --- a/tuned/plugins/plugin_modules.py +++ b/tuned/plugins/plugin_modules.py @@ -15,7 +15,7 @@ class ModulesPlugin(base.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(ModulesPlugin, self).__init__(*args, **kwargs) self._has_dynamic_options = True self._cmd = commands() diff --git a/tuned/plugins/plugin_net.py b/tuned/plugins/plugin_net.py index ed1ac2d..d4a3dac 100644 --- a/tuned/plugins/plugin_net.py +++ b/tuned/plugins/plugin_net.py @@ -16,7 +16,7 @@ class NetTuningPlugin(base.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(NetTuningPlugin, self).__init__(*args, **kwargs) self._load_smallest = 0.05 self._level_steps = 6 self._cmd = commands() diff --git a/tuned/plugins/plugin_scheduler.py b/tuned/plugins/plugin_scheduler.py index 0ad96ed..4939cd2 100644 --- a/tuned/plugins/plugin_scheduler.py +++ b/tuned/plugins/plugin_scheduler.py @@ -29,7 +29,7 @@ class SchedulerPlugin(base.Plugin): "SCHED_OTHER":"o", "SCHED_IDLE":"i"} def __init__(self, monitor_repository, storage_factory, hardware_inventory, device_matcher, device_matcher_udev, plugin_instance_factory, global_cfg, variables): - super(self.__class__, self).__init__(monitor_repository, storage_factory, hardware_inventory, device_matcher, device_matcher_udev, plugin_instance_factory, global_cfg, variables) + super(SchedulerPlugin, self).__init__(monitor_repository, storage_factory, hardware_inventory, device_matcher, device_matcher_udev, plugin_instance_factory, global_cfg, variables) self._has_dynamic_options = True self._daemon = consts.CFG_DEF_DAEMON self._sleep_interval = int(consts.CFG_DEF_SLEEP_INTERVAL) @@ -240,7 +240,7 @@ class SchedulerPlugin(base.Plugin): self._set_affinity(pid, affinity, no_error) def _instance_apply_static(self, instance): - super(self.__class__, self)._instance_apply_static(instance) + super(SchedulerPlugin, self)._instance_apply_static(instance) ps = self.get_processes() if ps is None: log.error("error applying tuning, cannot get information about running processes") @@ -275,7 +275,7 @@ class SchedulerPlugin(base.Plugin): instance._thread.start() def _instance_unapply_static(self, instance, full_rollback = False): - super(self.__class__, self)._instance_unapply_static(instance, full_rollback) + super(SchedulerPlugin, self)._instance_unapply_static(instance, full_rollback) ps = self.get_processes() if self._daemon and instance._runtime_tuning: instance._terminate.set() diff --git a/tuned/plugins/plugin_script.py b/tuned/plugins/plugin_script.py index 8685025..05d3eeb 100644 --- a/tuned/plugins/plugin_script.py +++ b/tuned/plugins/plugin_script.py @@ -49,12 +49,12 @@ class ScriptPlugin(base.Plugin): return True def _instance_apply_static(self, instance): - super(self.__class__, self)._instance_apply_static(instance) + super(ScriptPlugin, self)._instance_apply_static(instance) self._call_scripts(instance._scripts, ["start"]) def _instance_verify_static(self, instance, ignore_missing): ret = True - if super(self.__class__, self)._instance_verify_static(instance, ignore_missing) == False: + if super(ScriptPlugin, self)._instance_verify_static(instance, ignore_missing) == False: ret = False args = ["verify"] if ignore_missing: @@ -71,4 +71,4 @@ class ScriptPlugin(base.Plugin): if full_rollback: args = args + ["full_rollback"] self._call_scripts(reversed(instance._scripts), args) - super(self.__class__, self)._instance_unapply_static(instance, full_rollback) + super(ScriptPlugin, self)._instance_unapply_static(instance, full_rollback) diff --git a/tuned/plugins/plugin_scsi_host.py b/tuned/plugins/plugin_scsi_host.py index 49fdee5..adca07b 100644 --- a/tuned/plugins/plugin_scsi_host.py +++ b/tuned/plugins/plugin_scsi_host.py @@ -15,7 +15,7 @@ class SCSIHostPlugin(hotplug.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(SCSIHostPlugin, self).__init__(*args, **kwargs) self._cmd = commands() @@ -43,13 +43,13 @@ class SCSIHostPlugin(hotplug.Plugin): def _hardware_events_callback(self, event, device): if self._device_is_supported(device): - super(self.__class__, self)._hardware_events_callback(event, device) + super(SCSIHostPlugin, self)._hardware_events_callback(event, device) def _added_device_apply_tuning(self, instance, device_name): - super(self.__class__, self)._added_device_apply_tuning(instance, device_name) + super(SCSIHostPlugin, self)._added_device_apply_tuning(instance, device_name) def _removed_device_unapply_tuning(self, instance, device_name): - super(self.__class__, self)._removed_device_unapply_tuning(instance, device_name) + super(SCSIHostPlugin, self)._removed_device_unapply_tuning(instance, device_name) @classmethod def _get_config_options(cls): diff --git a/tuned/plugins/plugin_selinux.py b/tuned/plugins/plugin_selinux.py index 0faec87..b244d3c 100644 --- a/tuned/plugins/plugin_selinux.py +++ b/tuned/plugins/plugin_selinux.py @@ -27,7 +27,7 @@ class SelinuxPlugin(base.Plugin): if self._selinux_path is None: raise exceptions.NotSupportedPluginException("SELinux is not enabled on your system or incompatible version is used.") self._cache_threshold_path = os.path.join(self._selinux_path, "avc", "cache_threshold") - super(self.__class__, self).__init__(*args, **kwargs) + super(SelinuxPlugin, self).__init__(*args, **kwargs) @classmethod def _get_config_options(self): diff --git a/tuned/plugins/plugin_sysctl.py b/tuned/plugins/plugin_sysctl.py index 4e8904a..e4e573b 100644 --- a/tuned/plugins/plugin_sysctl.py +++ b/tuned/plugins/plugin_sysctl.py @@ -14,7 +14,7 @@ class SysctlPlugin(base.Plugin): """ def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(SysctlPlugin, self).__init__(*args, **kwargs) self._has_dynamic_options = True self._cmd = commands() diff --git a/tuned/plugins/plugin_sysfs.py b/tuned/plugins/plugin_sysfs.py index c7f56ab..e0b9f80 100644 --- a/tuned/plugins/plugin_sysfs.py +++ b/tuned/plugins/plugin_sysfs.py @@ -17,7 +17,7 @@ class SysfsPlugin(base.Plugin): # TODO: resolve possible conflicts with sysctl settings from other plugins def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) + super(SysfsPlugin, self).__init__(*args, **kwargs) self._has_dynamic_options = True self._cmd = commands() diff --git a/tuned/plugins/plugin_systemd.py b/tuned/plugins/plugin_systemd.py index da11252..472a800 100644 --- a/tuned/plugins/plugin_systemd.py +++ b/tuned/plugins/plugin_systemd.py @@ -20,7 +20,7 @@ class SystemdPlugin(base.Plugin): def __init__(self, *args, **kwargs): if not os.path.isfile(consts.SYSTEMD_SYSTEM_CONF_FILE): raise exceptions.NotSupportedPluginException("Required systemd '%s' configuration file not found, disabling plugin." % consts.SYSTEMD_SYSTEM_CONF_FILE) - super(self.__class__, self).__init__(*args, **kwargs) + super(SystemdPlugin, self).__init__(*args, **kwargs) self._cmd = commands() def _instance_init(self, instance): diff --git a/tuned/plugins/repository.py b/tuned/plugins/repository.py index e1ef9e6..94b137d 100644 --- a/tuned/plugins/repository.py +++ b/tuned/plugins/repository.py @@ -9,7 +9,7 @@ __all__ = ["Repository"] class Repository(PluginLoader): def __init__(self, monitor_repository, storage_factory, hardware_inventory, device_matcher, device_matcher_udev, plugin_instance_factory, global_cfg, variables): - super(self.__class__, self).__init__() + super(Repository, self).__init__() self._plugins = set() self._monitor_repository = monitor_repository self._storage_factory = storage_factory diff --git a/tuned/profiles/functions/function_assertion.py b/tuned/profiles/functions/function_assertion.py index 375bb5c..b8e118b 100644 --- a/tuned/profiles/functions/function_assertion.py +++ b/tuned/profiles/functions/function_assertion.py @@ -14,10 +14,10 @@ class assertion(base.Function): """ def __init__(self): # 2 arguments - super(self.__class__, self).__init__("assertion", 3) + super(assertion, self).__init__("assertion", 3) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(assertion, self).execute(args): return None if args[1] != args[2]: log.error("assertion '%s' failed: '%s' != '%s'" % (args[0], args[1], args[2])) diff --git a/tuned/profiles/functions/function_assertion_non_equal.py b/tuned/profiles/functions/function_assertion_non_equal.py index 1fbeb00..eb6874f 100644 --- a/tuned/profiles/functions/function_assertion_non_equal.py +++ b/tuned/profiles/functions/function_assertion_non_equal.py @@ -14,10 +14,10 @@ class assertion_non_equal(base.Function): """ def __init__(self): # 2 arguments - super(self.__class__, self).__init__("assertion_non_equal", 3) + super(assertion_non_equal, self).__init__("assertion_non_equal", 3) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(assertion_non_equal, self).execute(args): return None if args[1] == args[2]: log.error("assertion '%s' failed: '%s' == '%s'" % (args[0], args[1], args[2])) diff --git a/tuned/profiles/functions/function_cpulist2hex.py b/tuned/profiles/functions/function_cpulist2hex.py index d5db650..4a6c548 100644 --- a/tuned/profiles/functions/function_cpulist2hex.py +++ b/tuned/profiles/functions/function_cpulist2hex.py @@ -11,9 +11,9 @@ class cpulist2hex(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist2hex", 0) + super(cpulist2hex, self).__init__("cpulist2hex", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist2hex, self).execute(args): return None return self._cmd.cpulist2hex(",,".join(args)) diff --git a/tuned/profiles/functions/function_cpulist2hex_invert.py b/tuned/profiles/functions/function_cpulist2hex_invert.py index 42a3a77..72e4968 100644 --- a/tuned/profiles/functions/function_cpulist2hex_invert.py +++ b/tuned/profiles/functions/function_cpulist2hex_invert.py @@ -11,10 +11,10 @@ class cpulist2hex_invert(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist2hex_invert", 0) + super(cpulist2hex_invert, self).__init__("cpulist2hex_invert", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist2hex_invert, self).execute(args): return None # current implementation inverts the CPU list and then converts it to hexmask return self._cmd.cpulist2hex(",".join(str(v) for v in self._cmd.cpulist_invert(",,".join(args)))) diff --git a/tuned/profiles/functions/function_cpulist_invert.py b/tuned/profiles/functions/function_cpulist_invert.py index b102cf5..375eb67 100644 --- a/tuned/profiles/functions/function_cpulist_invert.py +++ b/tuned/profiles/functions/function_cpulist_invert.py @@ -14,9 +14,9 @@ class cpulist_invert(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist_invert", 0) + super(cpulist_invert, self).__init__("cpulist_invert", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist_invert, self).execute(args): return None return ",".join(str(v) for v in self._cmd.cpulist_invert(",,".join(args))) diff --git a/tuned/profiles/functions/function_cpulist_online.py b/tuned/profiles/functions/function_cpulist_online.py index 7315b8a..1badf3d 100644 --- a/tuned/profiles/functions/function_cpulist_online.py +++ b/tuned/profiles/functions/function_cpulist_online.py @@ -12,10 +12,10 @@ class cpulist_online(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist_online", 0) + super(cpulist_online, self).__init__("cpulist_online", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist_online, self).execute(args): return None cpus = self._cmd.cpulist_unpack(",".join(args)) online = self._cmd.cpulist_unpack(self._cmd.read_file("/sys/devices/system/cpu/online")) diff --git a/tuned/profiles/functions/function_cpulist_pack.py b/tuned/profiles/functions/function_cpulist_pack.py index 3ce0537..5ca3970 100644 --- a/tuned/profiles/functions/function_cpulist_pack.py +++ b/tuned/profiles/functions/function_cpulist_pack.py @@ -13,9 +13,9 @@ class cpulist_pack(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist_pack", 0) + super(cpulist_pack, self).__init__("cpulist_pack", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist_pack, self).execute(args): return None return ",".join(str(v) for v in self._cmd.cpulist_pack(",,".join(args))) diff --git a/tuned/profiles/functions/function_cpulist_present.py b/tuned/profiles/functions/function_cpulist_present.py index 211afdf..79a945f 100644 --- a/tuned/profiles/functions/function_cpulist_present.py +++ b/tuned/profiles/functions/function_cpulist_present.py @@ -12,10 +12,10 @@ class cpulist_present(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist_present", 0) + super(cpulist_present, self).__init__("cpulist_present", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist_present, self).execute(args): return None cpus = self._cmd.cpulist_unpack(",,".join(args)) present = self._cmd.cpulist_unpack(self._cmd.read_file("/sys/devices/system/cpu/present")) diff --git a/tuned/profiles/functions/function_cpulist_unpack.py b/tuned/profiles/functions/function_cpulist_unpack.py index 088ca4b..cf07efe 100644 --- a/tuned/profiles/functions/function_cpulist_unpack.py +++ b/tuned/profiles/functions/function_cpulist_unpack.py @@ -11,9 +11,9 @@ class cpulist_unpack(base.Function): """ def __init__(self): # arbitrary number of arguments - super(self.__class__, self).__init__("cpulist_unpack", 0) + super(cpulist_unpack, self).__init__("cpulist_unpack", 0) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(cpulist_unpack, self).execute(args): return None return ",".join(str(v) for v in self._cmd.cpulist_unpack(",,".join(args))) diff --git a/tuned/profiles/functions/function_exec.py b/tuned/profiles/functions/function_exec.py index 6abbf91..45886fe 100644 --- a/tuned/profiles/functions/function_exec.py +++ b/tuned/profiles/functions/function_exec.py @@ -9,10 +9,10 @@ class execute(base.Function): """ def __init__(self): # unlimited number of arguments, min 1 argument (the name of executable) - super(self.__class__, self).__init__("exec", 0, 1) + super(execute, self).__init__("exec", 0, 1) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(execute, self).execute(args): return None (ret, out) = self._cmd.execute(args) if ret == 0: diff --git a/tuned/profiles/functions/function_hex2cpulist.py b/tuned/profiles/functions/function_hex2cpulist.py index 3a32064..449186c 100644 --- a/tuned/profiles/functions/function_hex2cpulist.py +++ b/tuned/profiles/functions/function_hex2cpulist.py @@ -11,9 +11,9 @@ class hex2cpulist(base.Function): """ def __init__(self): # one argument - super(self.__class__, self).__init__("hex2cpulist", 1) + super(hex2cpulist, self).__init__("hex2cpulist", 1) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(hex2cpulist, self).execute(args): return None return ",".join(str(v) for v in self._cmd.hex2cpulist(args[0])) diff --git a/tuned/profiles/functions/function_kb2s.py b/tuned/profiles/functions/function_kb2s.py index af5f39b..7506aec 100644 --- a/tuned/profiles/functions/function_kb2s.py +++ b/tuned/profiles/functions/function_kb2s.py @@ -9,10 +9,10 @@ class kb2s(base.Function): """ def __init__(self): # one argument - super(self.__class__, self).__init__("kb2s", 1) + super(kb2s, self).__init__("kb2s", 1) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(kb2s, self).execute(args): return None try: return str(int(args[0]) * 2) diff --git a/tuned/profiles/functions/function_s2kb.py b/tuned/profiles/functions/function_s2kb.py index 79209c1..27e3ad7 100644 --- a/tuned/profiles/functions/function_s2kb.py +++ b/tuned/profiles/functions/function_s2kb.py @@ -9,10 +9,10 @@ class s2kb(base.Function): """ def __init__(self): # one argument - super(self.__class__, self).__init__("s2kb", 1) + super(s2kb, self).__init__("s2kb", 1) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(s2kb, self).execute(args): return None try: return str(int(args[0]) / 2) diff --git a/tuned/profiles/functions/function_strip.py b/tuned/profiles/functions/function_strip.py index 3af41e8..2b2f4de 100644 --- a/tuned/profiles/functions/function_strip.py +++ b/tuned/profiles/functions/function_strip.py @@ -9,9 +9,9 @@ class strip(base.Function): """ def __init__(self): # unlimited number of arguments, min 1 argument - super(self.__class__, self).__init__("strip", 0, 1) + super(strip, self).__init__("strip", 0, 1) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(strip, self).execute(args): return None return "".join(args).strip() diff --git a/tuned/profiles/functions/function_virt_check.py b/tuned/profiles/functions/function_virt_check.py index 7ea3817..91df3ee 100644 --- a/tuned/profiles/functions/function_virt_check.py +++ b/tuned/profiles/functions/function_virt_check.py @@ -11,10 +11,10 @@ class virt_check(base.Function): """ def __init__(self): # 2 arguments - super(self.__class__, self).__init__("virt_check", 2) + super(virt_check, self).__init__("virt_check", 2) def execute(self, args): - if not super(self.__class__, self).execute(args): + if not super(virt_check, self).execute(args): return None (ret, out) = self._cmd.execute(["virt-what"]) if ret == 0 and len(out) > 0: diff --git a/tuned/profiles/functions/repository.py b/tuned/profiles/functions/repository.py index aa7cfd3..0dc1d43 100644 --- a/tuned/profiles/functions/repository.py +++ b/tuned/profiles/functions/repository.py @@ -9,7 +9,7 @@ log = tuned.logs.get() class Repository(PluginLoader): def __init__(self): - super(self.__class__, self).__init__() + super(Repository, self).__init__() self._functions = {} @property diff --git a/tuned/units/manager.py b/tuned/units/manager.py index d48fe9d..77355e7 100644 --- a/tuned/units/manager.py +++ b/tuned/units/manager.py @@ -14,7 +14,7 @@ class Manager(object): """ def __init__(self, plugins_repository, monitors_repository, def_instance_priority): - super(self.__class__, self).__init__() + super(Manager, self).__init__() self._plugins_repository = plugins_repository self._monitors_repository = monitors_repository self._def_instance_priority = def_instance_priority From be9440fb07adc551c7d2c0359d4bd06ba1b50ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:29 +0100 Subject: [PATCH 04/12] Pass universal_newlines = True to Popen() Use universal_newlines = True in calls to Popen(), in order to get the output of the executed program as a string in Python3. --- experiments/powertop2tuned.py | 9 +++++++-- tuned/plugins/base.py | 6 ++++-- tuned/plugins/plugin_mounts.py | 5 ++++- tuned/plugins/plugin_script.py | 7 +++++-- tuned/utils/commands.py | 6 +++++- tuned/utils/nettool.py | 9 +++++++-- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/experiments/powertop2tuned.py b/experiments/powertop2tuned.py index dd29d10..1c527e3 100755 --- a/experiments/powertop2tuned.py +++ b/experiments/powertop2tuned.py @@ -182,7 +182,8 @@ class PowertopProfile: self.output = output def currentActiveProfile(self): - proc = Popen(["tuned-adm", "active"], stdout=PIPE) + proc = Popen(["tuned-adm", "active"], stdout=PIPE, \ + universal_newlines = True) output = proc.communicate()[0] if output and output.find("Current active profile: ") == 0: return output[len("Current active profile: "):output.find("\n")] @@ -200,7 +201,11 @@ class PowertopProfile: environment = os.environ.copy() environment["LC_ALL"] = "C" try: - proc = Popen(["/usr/sbin/powertop", "--html=/tmp/powertop", "--time=1"], stdout=PIPE, stderr=PIPE, env=environment) + proc = Popen(["/usr/sbin/powertop", \ + "--html=/tmp/powertop", "--time=1"], \ + stdout=PIPE, stderr=PIPE, \ + env=environment, \ + universal_newlines = True) output = proc.communicate()[1] except (OSError, IOError): print('Unable to execute PowerTOP, is PowerTOP installed?', file=sys.stderr) diff --git a/tuned/plugins/base.py b/tuned/plugins/base.py index d669ad3..9ea10cc 100644 --- a/tuned/plugins/base.py +++ b/tuned/plugins/base.py @@ -223,8 +223,10 @@ class Plugin(object): log.info("calling script '%s' with arguments '%s'" % (script, str(arguments))) log.debug("using environment '%s'" % str(list(environ.items()))) try: - proc = Popen([script] + arguments, stdout=PIPE, stderr=PIPE, close_fds=True, env=environ, \ - cwd = dir_name) + proc = Popen([script] + arguments, \ + stdout=PIPE, stderr=PIPE, \ + close_fds=True, env=environ, \ + cwd = dir_name, universal_newlines = True) out, err = proc.communicate() if proc.returncode: log.error("script '%s' error: %d, '%s'" % (script, proc.returncode, err[:-1])) diff --git a/tuned/plugins/plugin_mounts.py b/tuned/plugins/plugin_mounts.py index b579c74..8e2eacc 100644 --- a/tuned/plugins/plugin_mounts.py +++ b/tuned/plugins/plugin_mounts.py @@ -23,7 +23,10 @@ class MountsPlugin(base.Plugin): mountpoint_topology = {} current_disk = None - stdout, stderr = Popen(["lsblk", "-rno", "TYPE,RM,KNAME,FSTYPE,MOUNTPOINT"], stdout=PIPE, stderr=PIPE, close_fds=True).communicate() + stdout, stderr = Popen(["lsblk", "-rno", \ + "TYPE,RM,KNAME,FSTYPE,MOUNTPOINT"], \ + stdout=PIPE, stderr=PIPE, close_fds=True, \ + universal_newlines = True).communicate() for columns in [line.split() for line in stdout.splitlines()]: if len(columns) < 3: continue diff --git a/tuned/plugins/plugin_script.py b/tuned/plugins/plugin_script.py index 05d3eeb..ac0a205 100644 --- a/tuned/plugins/plugin_script.py +++ b/tuned/plugins/plugin_script.py @@ -37,8 +37,11 @@ class ScriptPlugin(base.Plugin): log.info("calling script '%s' with arguments '%s'" % (script, str(arguments))) log.debug("using environment '%s'" % str(list(environ.items()))) try: - proc = Popen([script] + arguments, stdout=PIPE, stderr=PIPE, close_fds=True, env=environ, \ - cwd = os.path.dirname(script)) + proc = Popen([script] + arguments, \ + stdout=PIPE, stderr=PIPE, \ + close_fds=True, env=environ, \ + universal_newlines = True, \ + cwd = os.path.dirname(script)) out, err = proc.communicate() if proc.returncode: log.error("script '%s' error: %d, '%s'" % (script, proc.returncode, err[:-1])) diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py index a23a1b6..96a3dde 100644 --- a/tuned/utils/commands.py +++ b/tuned/utils/commands.py @@ -211,7 +211,11 @@ class commands: out = "" err_msg = None try: - proc = Popen(args, stdout = PIPE, stderr = PIPE, env = self._environment, shell = shell, cwd = cwd, close_fds = True) + proc = Popen(args, stdout = PIPE, stderr = PIPE, \ + env = self._environment, \ + shell = shell, cwd = cwd, \ + close_fds = True, \ + universal_newlines = True) out, err = proc.communicate() retcode = proc.returncode diff --git a/tuned/utils/nettool.py b/tuned/utils/nettool.py index 28fdf89..26e39ad 100644 --- a/tuned/utils/nettool.py +++ b/tuned/utils/nettool.py @@ -113,8 +113,13 @@ class Nettool: # run ethtool and preprocess output - p_ethtool = Popen(["ethtool", self._interface], stdout=PIPE, stderr=PIPE, close_fds=True) - p_filter = Popen(["sed", "s/^\s*//;s/:\s*/:\\n/g"], stdin=p_ethtool.stdout, stdout=PIPE, close_fds=True) + p_ethtool = Popen(["ethtool", self._interface], \ + stdout=PIPE, stderr=PIPE, close_fds=True, \ + universal_newlines = True) + p_filter = Popen(["sed", "s/^\s*//;s/:\s*/:\\n/g"], \ + stdin=p_ethtool.stdout, stdout=PIPE, \ + universal_newlines = True, \ + close_fds=True) output = p_filter.communicate()[0] errors = p_ethtool.communicate()[1] From e039f07a9603616d599331e236054a8949d3bfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:32 +0100 Subject: [PATCH 05/12] Use the errno attribute of an exception instead of indices Obtaining the errno from an exception using e[0] is no longer possible in Python3. --- tuned/plugins/plugin_scheduler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tuned/plugins/plugin_scheduler.py b/tuned/plugins/plugin_scheduler.py index 4939cd2..21c6cee 100644 --- a/tuned/plugins/plugin_scheduler.py +++ b/tuned/plugins/plugin_scheduler.py @@ -207,7 +207,7 @@ class SchedulerPlugin(base.Plugin): else: return 1 except IOError as e: - if e[0] == errno.ENOENT or e[0] == errno.ESRCH: + if e.errno == errno.ENOENT or e.errno == errno.ESRCH: log.debug("Unable to set affinity for PID %s, the task vanished." % pid) return -1 else: From fba15bf0f66f2acdc80e52ae9918cbac8af1b415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:35 +0100 Subject: [PATCH 06/12] Use open() instead of file() to open files file() has been removed in Python3. Also, drop buffering=0 from the call - it doesn't work in text mode in Python3. --- libexec/defirqaffinity.py | 5 ++--- libexec/pmqos-static.py | 10 ++++------ tuned/daemon/application.py | 10 ++++------ 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/libexec/defirqaffinity.py b/libexec/defirqaffinity.py index 39721a6..54fcc42 100755 --- a/libexec/defirqaffinity.py +++ b/libexec/defirqaffinity.py @@ -41,9 +41,8 @@ def parse_def_affinity(fname): if os.getuid() != 0: return try: - f = file(fname) - line = f.readline() - f.close() + with open(fname, 'r') as f: + line = f.readline() return bitmasklist(line) except IOError: return [ 0 ] diff --git a/libexec/pmqos-static.py b/libexec/pmqos-static.py index c6dc2c6..d97a866 100755 --- a/libexec/pmqos-static.py +++ b/libexec/pmqos-static.py @@ -40,12 +40,10 @@ def do_fork(): sys.exit(0) def close_fds(): - s_in = file('/dev/null', 'r') - s_out = file('/dev/null', 'a+') - s_err = file('/dev/null', 'a+', 0) - os.dup2(s_in.fileno(), sys.stdin.fileno()) - os.dup2(s_out.fileno(), sys.stdout.fileno()) - os.dup2(s_err.fileno(), sys.stderr.fileno()) + f = open('/dev/null', 'w+') + os.dup2(f.fileno(), sys.stdin.fileno()) + os.dup2(f.fileno(), sys.stdout.fileno()) + os.dup2(f.fileno(), sys.stderr.fileno()) def write_pidfile(): with os.fdopen(os.open(PIDFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644), "w") as f: diff --git a/tuned/daemon/application.py b/tuned/daemon/application.py index c8239a7..3822729 100644 --- a/tuned/daemon/application.py +++ b/tuned/daemon/application.py @@ -139,12 +139,10 @@ class Application(object): os.close(child_out_fd) raise TunedException("Cannot daemonize, second fork() failed.") - si = file("/dev/null", "r") - so = file("/dev/null", "a+") - se = file("/dev/null", "a+", 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) + fd = open("/dev/null", "w+") + os.dup2(fd.fileno(), sys.stdin.fileno()) + os.dup2(fd.fileno(), sys.stdout.fileno()) + os.dup2(fd.fileno(), sys.stderr.fileno()) self.write_pid_file(pid_file) From ee657bc73319ff6115580d31e920a5984a28a015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:37 +0100 Subject: [PATCH 07/12] Use new syntax for catching exceptions --- systemtap/varnetload | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/systemtap/varnetload b/systemtap/varnetload index d8d3009..e3fcad5 100755 --- a/systemtap/varnetload +++ b/systemtap/varnetload @@ -43,8 +43,8 @@ url = "http://myhost.mydomain/index.html" try: opts, args = getopt.getopt(sys.argv[1:], "d:t:u:") -except getopt.error, e: - print("Error parsing command-line arguments: %s" % e) +except getopt.error as e: + print("Error parsing command-line arguments: %s" % e) usage() sys.exit(1) @@ -89,7 +89,7 @@ try: urlopen(url).read(409600) time.sleep(delay) count += 1 -except URLError, e: +except URLError as e: print("Downloading failed: %s" % e.reason) sys.exit(2) From 633726723e4a3766965bb1543525f44e313758f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:41 +0100 Subject: [PATCH 08/12] Fix a syntax error --- tuned/plugins/plugin_scheduler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tuned/plugins/plugin_scheduler.py b/tuned/plugins/plugin_scheduler.py index 21c6cee..43a35f6 100644 --- a/tuned/plugins/plugin_scheduler.py +++ b/tuned/plugins/plugin_scheduler.py @@ -442,7 +442,8 @@ class SchedulerPlugin(base.Plugin): affinity = self._cmd.cpulist_invert(value) sa = set(affinity) if set(cpus).intersection(sa) != sa: - log.error("invalid isolated_cores specified, '%s' don't match available cores '%s'" % (value, ",".cpus)) + str_cpus = ",".join([str(x) for x in cpus]) + log.error("invalid isolated_cores specified, '%s' don't match available cores '%s'" % (value, str_cpus)) return None self._set_ps_affinity(affinity, True) else: From 609f49ec8ab6540743c35a41c2d2121d00ee74fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:43 +0100 Subject: [PATCH 09/12] spec: Use versioned python macros For some reason this fixes the following errors during mockbuild: sh: /usr/bin/python: No such file or directory The versioned macro is provided by python-devel. --- tuned.spec | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tuned.spec b/tuned.spec index fc5b4a1..cefacba 100644 --- a/tuned.spec +++ b/tuned.spec @@ -35,7 +35,8 @@ Source1: https://git.kernel.org/pub/scm/virt/kvm/kvm-unit-tests.git/snapshot/kvm %endif URL: http://www.tuned-project.org/ BuildArch: noarch -BuildRequires: python, systemd, desktop-file-utils +BuildRequires: python, python-devel +BuildRequires: systemd, desktop-file-utils %if %{with tscdeadline_latency} BuildRequires: gcc-x86_64-linux-gnu %endif @@ -304,8 +305,8 @@ fi %exclude %{docdir}/README.NFV %doc %{docdir} %{_datadir}/bash-completion/completions/tuned-adm -%exclude %{python_sitelib}/tuned/gtk -%{python_sitelib}/tuned +%exclude %{python2_sitelib}/tuned/gtk +%{python2_sitelib}/tuned %{_sbindir}/tuned %{_sbindir}/tuned-adm %exclude %{_sysconfdir}/tuned/realtime-variables.conf @@ -357,7 +358,7 @@ fi %files gtk %defattr(-,root,root,-) %{_sbindir}/tuned-gui -%{python_sitelib}/tuned/gtk +%{python2_sitelib}/tuned/gtk %{_datadir}/tuned/ui %{_datadir}/polkit-1/actions/com.redhat.tuned.gui.policy %{_datadir}/icons/hicolor/scalable/apps/tuned.svg From b716ebfe55b81d26043565f42d7df43eacec9c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:45 +0100 Subject: [PATCH 10/12] Makefile: support python3 installation You can now specify the python runtime using the PYTHON variable. E.g. you can use make PYTHON=python3 install to install tuned modules to the python3 directory and rewrite shebangs on executable Python files to use Python3. --- INSTALL | 4 ++++ Makefile | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/INSTALL b/INSTALL index 9f66da0..6127a60 100644 --- a/INSTALL +++ b/INSTALL @@ -4,3 +4,7 @@ Installation instructions The tuned daemon is written in pure Python. Nothing requires to be built. For installation use 'make install'. Optionally DESTDIR can be appended. +By default, the tuned modules are installed to the Python2 destination +(e.g. /usr/lib/python2.7/site-packages/) and shebangs in executable +Python files are modified to use Python2. If you want tuned to use Python3 +instead, use 'make PYTHON=python3 install'. diff --git a/Makefile b/Makefile index 70a911c..02b096e 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,16 @@ VERSIONED_NAME = $(NAME)-$(VERSION)$(GIT_PSUFFIX) SYSCONFDIR = /etc DATADIR = /usr/share DOCDIR = $(DATADIR)/doc/$(NAME) -PYTHON_SITELIB = $(shell python -c 'from distutils.sysconfig import get_python_lib; print get_python_lib();' || echo /usr/lib/python2.7/site-packages) +PYTHON = python2 +PYLINT = pylint-2 +ifeq ($(PYTHON),python3) +PYLINT = pylint-3 +endif +SHEBANG_REWRITE_REGEX= '1s/^(\#!\/usr\/bin\/)\/\1$(PYTHON)/' +PYTHON_SITELIB = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib());') +ifeq ($(PYTHON_SITELIB),) +$(error Failed to determine python library directory) +endif TUNED_PROFILESDIR = /usr/lib/tuned TUNED_RECOMMEND_DIR = $(TUNED_PROFILESDIR)/recommend.d TUNED_USER_RECOMMEND_DIR = $(SYSCONFDIR)/tuned/recommend.d @@ -118,17 +127,30 @@ install: install-dirs cp -a tuned $(DESTDIR)$(PYTHON_SITELIB) # binaries - install -Dpm 0755 tuned.py $(DESTDIR)/usr/sbin/tuned - install -Dpm 0755 tuned-adm.py $(DESTDIR)/usr/sbin/tuned-adm - install -Dpm 0755 tuned-gui.py $(DESTDIR)/usr/sbin/tuned-gui + install -Dm 0755 tuned.py $(DESTDIR)/usr/sbin/tuned + install -Dm 0755 tuned-adm.py $(DESTDIR)/usr/sbin/tuned-adm + install -Dm 0755 tuned-gui.py $(DESTDIR)/usr/sbin/tuned-gui + sed -i -r -e $(SHEBANG_REWRITE_REGEX) \ + $(DESTDIR)/usr/sbin/tuned \ + $(DESTDIR)/usr/sbin/tuned-adm \ + $(DESTDIR)/usr/sbin/tuned-gui + touch -r tuned.py $(DESTDIR)/usr/sbin/tuned + touch -r tuned-adm.py $(DESTDIR)/usr/sbin/tuned-adm + touch -r tuned-gui.py $(DESTDIR)/usr/sbin/tuned-gui $(foreach file, $(wildcard systemtap/*), \ install -Dpm 0755 $(file) $(DESTDIR)/usr/sbin/$(notdir $(file));) + sed -i -r -e $(SHEBANG_REWRITE_REGEX) \ + $(DESTDIR)/usr/sbin/varnetload + touch -r systemtap/varnetload $(DESTDIR)/usr/sbin/varnetload # glade install -Dpm 0644 tuned-gui.glade $(DESTDIR)$(DATADIR)/tuned/ui/tuned-gui.glade # tools - install -Dpm 0755 experiments/powertop2tuned.py $(DESTDIR)/usr/bin/powertop2tuned + install -Dm 0755 experiments/powertop2tuned.py $(DESTDIR)/usr/bin/powertop2tuned + sed -i -r -e $(SHEBANG_REWRITE_REGEX) \ + $(DESTDIR)/usr/bin/powertop2tuned + touch -r experiments/powertop2tuned.py $(DESTDIR)/usr/bin/powertop2tuned # configuration files install -Dpm 0644 tuned-main.conf $(DESTDIR)$(SYSCONFDIR)/tuned/tuned-main.conf @@ -181,7 +203,11 @@ install: install-dirs # libexec scripts $(foreach file, $(wildcard libexec/*), \ - install -Dpm 0755 $(file) $(DESTDIR)/usr/libexec/tuned/$(notdir $(file));) + install -Dm 0755 $(file) $(DESTDIR)/usr/libexec/tuned/$(notdir $(file)); \ + sed -i -r -e $(SHEBANG_REWRITE_REGEX) \ + $(DESTDIR)/usr/libexec/tuned/$(notdir $(file)); \ + touch -r $(file) $(DESTDIR)/usr/libexec/tuned/$(notdir $(file)); \ + ) # icon install -Dpm 0644 icons/tuned.svg $(DESTDIR)$(DATADIR)/icons/hicolor/scalable/apps/tuned.svg @@ -195,9 +221,9 @@ clean: rm -rf $(VERSIONED_NAME) rpm-build-dir test: - python -m unittest discover tests + $(PYTHON) -m unittest discover tests lint: - pylint -E -f parseable tuned *.py + $(PYLINT) -E -f parseable tuned *.py .PHONY: clean archive srpm tag test lint From 1823a7de6462f4574b44293690917286d3b95526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:48 +0100 Subject: [PATCH 11/12] Makefile: install to python3 destination by default --- INSTALL | 8 ++++---- Makefile | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/INSTALL b/INSTALL index 6127a60..c258e75 100644 --- a/INSTALL +++ b/INSTALL @@ -4,7 +4,7 @@ Installation instructions The tuned daemon is written in pure Python. Nothing requires to be built. For installation use 'make install'. Optionally DESTDIR can be appended. -By default, the tuned modules are installed to the Python2 destination -(e.g. /usr/lib/python2.7/site-packages/) and shebangs in executable -Python files are modified to use Python2. If you want tuned to use Python3 -instead, use 'make PYTHON=python3 install'. +By default, the tuned modules are installed to the Python3 destination +(e.g. /usr/lib/python3.6/site-packages/) and shebangs in executable +Python files are modified to use Python3. If you want tuned to use Python2 +instead, use 'make PYTHON=python2 install'. diff --git a/Makefile b/Makefile index 02b096e..b964973 100644 --- a/Makefile +++ b/Makefile @@ -33,10 +33,10 @@ VERSIONED_NAME = $(NAME)-$(VERSION)$(GIT_PSUFFIX) SYSCONFDIR = /etc DATADIR = /usr/share DOCDIR = $(DATADIR)/doc/$(NAME) -PYTHON = python2 -PYLINT = pylint-2 -ifeq ($(PYTHON),python3) +PYTHON = python3 PYLINT = pylint-3 +ifeq ($(PYTHON),python2) +PYLINT = pylint-2 endif SHEBANG_REWRITE_REGEX= '1s/^(\#!\/usr\/bin\/)\/\1$(PYTHON)/' PYTHON_SITELIB = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib());') From 5816256f9375f483fa1e953a501410e4a6ae77c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Sun, 14 Jan 2018 15:13:50 +0100 Subject: [PATCH 12/12] spec: Use python3 on Fedora > 27 and RHEL > 7 As of this writing, python3-perf is not yet available, but hopefully it soon will be. --- tuned.spec | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/tuned.spec b/tuned.spec index cefacba..38ec1ea 100644 --- a/tuned.spec +++ b/tuned.spec @@ -24,6 +24,10 @@ %global prerel1 %{?prerelease:.%{prerelease}%{prereleasenum}} %global prerel2 %{?prerelease:-%{prerelease}.%{prereleasenum}} +%if 0%{?fedora} > 27 || 0%{?rhel} > 7 +%global with_python3 1 +%endif + Summary: A dynamic adaptive system tuning daemon Name: tuned Version: 2.9.0 @@ -35,7 +39,6 @@ Source1: https://git.kernel.org/pub/scm/virt/kvm/kvm-unit-tests.git/snapshot/kvm %endif URL: http://www.tuned-project.org/ BuildArch: noarch -BuildRequires: python, python-devel BuildRequires: systemd, desktop-file-utils %if %{with tscdeadline_latency} BuildRequires: gcc-x86_64-linux-gnu @@ -43,10 +46,19 @@ BuildRequires: gcc-x86_64-linux-gnu Requires(post): systemd, virt-what Requires(preun): systemd Requires(postun): systemd -Requires: python-decorator, dbus-python, pygobject3-base, python-pyudev -Requires: virt-what, python-configobj, ethtool, gawk, hdparm -Requires: util-linux, python-perf, dbus, polkit, python-linux-procfs -Requires: python-schedutils +%if 0%{?with_python3} == 1 +BuildRequires: python3, python3-devel +Requires: python3-decorator, python3-dbus, python3-pygobject3-base +Requires: python3-pyudev, python3-configobj, python3-schedutils +Requires: python3-linux-procfs, python3-perf +%else +BuildRequires: python, python-devel +Requires: python-decorator, dbus-python, pygobject3-base +Requires: python-pyudev, python-configobj, python-schedutils +Requires: python-linux-procfs, python-perf +%endif +Requires: virt-what, ethtool, gawk, hdparm +Requires: util-linux, dbus, polkit %if 0%{?fedora} > 22 || 0%{?rhel} > 7 Recommends: kernel-tools %endif @@ -205,7 +217,12 @@ x86_64-linux-gnu-strip x86/tscdeadline_latency.flat %endif %install -make install DESTDIR=%{buildroot} DOCDIR=%{docdir} +make install DESTDIR=%{buildroot} DOCDIR=%{docdir} \ +%if 0%{?with_python3} == 1 + PYTHON=python3 +%else + PYTHON=python2 +%endif %if 0%{?rhel} sed -i 's/\(dynamic_tuning[ \t]*=[ \t]*\).*/\10/' %{buildroot}%{_sysconfdir}/tuned/tuned-main.conf %endif @@ -305,8 +322,13 @@ fi %exclude %{docdir}/README.NFV %doc %{docdir} %{_datadir}/bash-completion/completions/tuned-adm +%if 0%{?with_python3} == 1 +%exclude %{python3_sitelib}/tuned/gtk +%{python3_sitelib}/tuned +%else %exclude %{python2_sitelib}/tuned/gtk %{python2_sitelib}/tuned +%endif %{_sbindir}/tuned %{_sbindir}/tuned-adm %exclude %{_sysconfdir}/tuned/realtime-variables.conf @@ -358,7 +380,11 @@ fi %files gtk %defattr(-,root,root,-) %{_sbindir}/tuned-gui +%if 0%{?with_python3} == 1 +%{python3_sitelib}/tuned/gtk +%else %{python2_sitelib}/tuned/gtk +%endif %{_datadir}/tuned/ui %{_datadir}/polkit-1/actions/com.redhat.tuned.gui.policy %{_datadir}/icons/hicolor/scalable/apps/tuned.svg