Commit f563c7d7 authored by Jaroslav Škarvada's avatar Jaroslav Škarvada

An attempt to port Tuned to python3 and keeping it python2 compatible

Signed-off-by: default avatarJaroslav Škarvada <jskarvad@redhat.com>
parent 60bb8e29
#!/usr/bin/python -Es
from __future__ import print_function
import os
import Xlib
......@@ -38,8 +40,8 @@ def loop():
else:
if not win in showed:
showed.append(win)
print "Showed:", showed
print "Minimized:", hidden
print("Showed:", showed)
print("Minimized:", hidden)
if __name__ == '__main__':
loop()
......@@ -19,6 +19,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from __future__ import print_function
from builtins import chr
import os
import sys
import tempfile
......@@ -26,8 +28,13 @@ import shutil
import argparse
import codecs
from subprocess import *
from HTMLParser import HTMLParser
from htmlentitydefs import name2codepoint
try:
from html.parser import HTMLParser
from html.entities import name2codepoint
except ImportError:
from HTMLParser import HTMLParser
from htmlentitydefs import name2codepoint
SCRIPT_SH = """#!/bin/sh
......@@ -141,7 +148,7 @@ class PowertopHTMLParser(HTMLParser):
def handle_entityref(self, name):
if self.inScript:
self.currentScript += unichr(name2codepoint[name])
self.currentScript += chr(name2codepoint[name])
def handle_data(self, data):
prefix = self.prefix
......@@ -179,23 +186,23 @@ class PowertopProfile:
def checkPrivs(self):
myuid = os.geteuid()
if myuid != 0:
print >> sys.stderr, 'Run this program as root'
print('Run this program as root', file=sys.stderr)
return False
return True
def generateHTML(self):
print "Running PowerTOP, please wait..."
print("Running PowerTOP, please wait...")
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)
output = proc.communicate()[1]
except (OSError, IOError):
print >> sys.stderr, 'Unable to execute PowerTOP, is PowerTOP installed?'
print('Unable to execute PowerTOP, is PowerTOP installed?', file=sys.stderr)
return -2
if proc.returncode != 0:
print >> sys.stderr, 'PowerTOP returned error code: %d' % proc.returncode
print('PowerTOP returned error code: %d' % proc.returncode, file=sys.stderr)
return -2
prefix = "PowerTOP outputing using base filename "
......@@ -226,31 +233,31 @@ class PowertopProfile:
return parser.getParsedData(), parser.getPlugins()
def generateShellScript(self, data):
print "Generating shell script", os.path.join(self.output, "script.sh")
print("Generating shell script", os.path.join(self.output, "script.sh"))
f = None
try:
f = codecs.open(os.path.join(self.output, "script.sh"), "w", "utf-8")
f.write(SCRIPT_SH % (data, ""))
os.fchmod(f.fileno(), 0755)
os.fchmod(f.fileno(), 0o755)
f.close()
except (OSError, IOError) as e:
print >> sys.stderr, "Error writing shell script: %s" % e
print("Error writing shell script: %s" % e, file=sys.stderr)
if f is not None:
f.close()
return False
return True
def generateTunedConf(self, profile, plugins):
print "Generating Tuned config file", os.path.join(self.output, "tuned.conf")
print("Generating Tuned config file", os.path.join(self.output, "tuned.conf"))
f = codecs.open(os.path.join(self.output, "tuned.conf"), "w", "utf-8")
f.write(TUNED_CONF_PROLOG)
if profile is not None:
if self.profile_name == profile:
print >> sys.stderr, 'New profile has same name as active profile, not including active profile (avoiding circular deps).'
print('New profile has same name as active profile, not including active profile (avoiding circular deps).', file=sys.stderr)
else:
f.write(TUNED_CONF_INCLUDE % ("include=" + profile))
for plugin in plugins.values():
for plugin in list(plugins.values()):
f.write(plugin + "\n")
f.write(TUNED_CONF_EPILOG)
......@@ -274,7 +281,7 @@ class PowertopProfile:
os.unlink(self.name)
if len(data) == 0 and len(plugins) == 0:
print >> sys.stderr, 'Your Powertop version is incompatible (maybe too old) or the generated HTML output is malformed'
print('Your Powertop version is incompatible (maybe too old) or the generated HTML output is malformed', file=sys.stderr)
return self.PARSING_ERROR
if new_profile is False:
......@@ -297,9 +304,9 @@ class PowertopProfile:
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Creates Tuned profile from Powertop HTML output.')
parser.add_argument('profile', metavar='profile_name', type=unicode, nargs='?', help='Name for the profile to be written.')
parser.add_argument('-i', '--input', metavar='input_html', type=unicode, help='Path to Powertop HTML report. If not given, it is generated automatically.')
parser.add_argument('-o', '--output', metavar='output_directory', type=unicode, help='Directory where the profile will be written, default is /etc/tuned/profile_name directory.')
parser.add_argument('profile', metavar='profile_name', type=str, nargs='?', help='Name for the profile to be written.')
parser.add_argument('-i', '--input', metavar='input_html', type=str, help='Path to Powertop HTML report. If not given, it is generated automatically.')
parser.add_argument('-o', '--output', metavar='output_directory', type=str, help='Directory where the profile will be written, default is /etc/tuned/profile_name directory.')
parser.add_argument('-n', '--new-profile', action='store_true', help='Creates new profile, otherwise it merges (include) your current profile.')
parser.add_argument('-m', '--merge-profile', action = 'store', help = 'Merges (includes) the specified profile (can be suppressed by -n option).')
parser.add_argument('-f', '--force', action='store_true', help='Overwrites the output directory if it already exists.')
......@@ -308,7 +315,7 @@ if __name__ == "__main__":
args = vars(args)
if not args['profile'] and not args['output']:
print >> sys.stderr, 'You have to specify the profile_name or output directory using the --output argument.'
print('You have to specify the profile_name or output directory using the --output argument.', file=sys.stderr)
parser.print_help()
sys.exit(-1)
......@@ -322,7 +329,7 @@ if __name__ == "__main__":
args['input'] = ''
if os.path.exists(args['output']) and not args['force']:
print >> sys.stderr, 'Output directory already exists, use --force to overwrite it.'
print('Output directory already exists, use --force to overwrite it.', file=sys.stderr)
sys.exit(-1)
p = PowertopProfile(args['output'], args['profile'], args['input'])
......
......@@ -21,6 +21,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from __future__ import print_function
import os
import signal
import struct
......@@ -47,7 +48,7 @@ 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, 0644)
f = os.open(PIDFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644)
os.write(f, "%d" % os.getpid())
os.close(f)
......@@ -65,7 +66,7 @@ def set_pmqos(name, value):
try:
fd = os.open(filename, os.O_WRONLY)
except OSError:
print >>sys.stderr, "Cannot open (%s)." % filename
print("Cannot open (%s)." % filename, file=sys.stderr)
return None
os.write(fd, bin_value)
return fd
......@@ -86,14 +87,14 @@ def run_daemon(options):
daemonize()
write_pidfile()
signal.signal(signal.SIGTERM, sigterm_handler)
except Exception, e:
print >>sys.stderr, "Cannot daemonize (%s)." % e
except Exception as e:
print("Cannot daemonize (%s)." % e, file=sys.stderr)
return False
global pmqos_fds
pmqos_fds = []
for (name, value) in options.items():
for (name, value) in list(options.items()):
try:
new_fd = set_pmqos(name, value)
if new_fd is not None:
......@@ -111,20 +112,20 @@ def kill_daemon(force = False):
try:
with open(PIDFILE, "r") as pidfile:
daemon_pid = int(pidfile.read())
except IOError, e:
if not force: print >>sys.stderr, "Cannot open PID file (%s)." % e
except IOError as e:
if not force: print("Cannot open PID file (%s)." % e, file=sys.stderr)
return False
try:
os.kill(daemon_pid, signal.SIGTERM)
except OSError, e:
if not force: print >>sys.stderr, "Cannot terminate the daemon (%s)." % e
except OSError as e:
if not force: print("Cannot terminate the daemon (%s)." % e, file=sys.stderr)
return False
try:
os.unlink(PIDFILE)
except OSError, e:
if not force: print >>sys.stderr, "Cannot delete the PID file (%s)." % e
except OSError as e:
if not force: print("Cannot delete the PID file (%s)." % e, file=sys.stderr)
return False
return True
......@@ -148,14 +149,14 @@ if __name__ == "__main__":
if name in ALLOWED_INTERFACES and len(value) > 0:
options[name] = value
else:
print >>sys.stderr, "Invalid option (%s)." % option
print("Invalid option (%s)." % option, file=sys.stderr)
if disable:
sys.exit(0 if kill_daemon() else 1)
if len(options) == 0:
print >>sys.stderr, "No options set. Not starting."
print("No options set. Not starting.", file=sys.stderr)
sys.exit(1)
kill_daemon(True)
......
......@@ -69,7 +69,7 @@ class LoaderTestCase(unittest.TestCase):
profile = self.loader.load("default")
self.assertIn("main", profile.test_config)
self.assertIn("disk", profile.test_config)
self.assertEquals(profile.test_config["network"]["devices"], "em*")
self.assertEqual(profile.test_config["network"]["devices"], "em*")
def test_load_empty(self):
profile = self.loader.load("empty")
......@@ -85,7 +85,7 @@ class LoaderTestCase(unittest.TestCase):
def test_load_order(self):
profile = self.loader.load("custom")
self.assertEquals(profile.test_config["custom"]["type"], "two")
self.assertEqual(profile.test_config["custom"]["type"], "two")
def test_default_load(self):
profile = self.loader.load("empty")
......
......@@ -45,19 +45,19 @@ class LocatorTestCase(unittest.TestCase):
def test_get_config(self):
config_name = self.locator.get_config("custom")
self.assertEquals(config_name, os.path.join(self._tmp_load_dirs[1], "custom", "tuned.conf"))
self.assertEqual(config_name, os.path.join(self._tmp_load_dirs[1], "custom", "tuned.conf"))
def test_get_config_priority(self):
customized = self.locator.get_config("balanced")
self.assertEquals(customized, os.path.join(self._tmp_load_dirs[1], "balanced", "tuned.conf"))
self.assertEqual(customized, os.path.join(self._tmp_load_dirs[1], "balanced", "tuned.conf"))
system = self.locator.get_config("balanced", [customized])
self.assertEquals(system, os.path.join(self._tmp_load_dirs[0], "balanced", "tuned.conf"))
self.assertEqual(system, os.path.join(self._tmp_load_dirs[0], "balanced", "tuned.conf"))
none = self.locator.get_config("balanced", [customized, system])
self.assertIsNone(none)
def test_ignore_nonexistent_dirs(self):
locator = Locator([self._tmp_load_dirs[0], "/tmp/some-dir-which-does-not-exist-for-sure"])
balanced = locator.get_config("balanced")
self.assertEquals(balanced, os.path.join(self._tmp_load_dirs[0], "balanced", "tuned.conf"))
self.assertEqual(balanced, os.path.join(self._tmp_load_dirs[0], "balanced", "tuned.conf"))
known = locator.get_known_names()
self.assertListEqual(known, ["balanced", "powersafe"])
......@@ -20,7 +20,7 @@ class ProfileTestCase(unittest.TestCase):
self.assertIs(type(profile.units), collections.OrderedDict)
self.assertEqual(len(profile.units), 2)
self.assertListEqual(sorted(map(lambda (name, config): name, profile.units)), sorted(["network", "storage"]))
self.assertListEqual(sorted([name_config[0] for name_config in profile.units]), sorted(["network", "storage"]))
def test_create_units_empty(self):
profile = MockProfile("test", {"main":{}})
......@@ -47,7 +47,7 @@ class ProfileTestCase(unittest.TestCase):
})
self.assertIs(type(profile.options), dict)
self.assertEquals(profile.options["anything"], 10)
self.assertEqual(profile.options["anything"], 10)
def test_sets_options_empty(self):
profile = MockProfile("test", {
......@@ -55,4 +55,4 @@ class ProfileTestCase(unittest.TestCase):
})
self.assertIs(type(profile.options), dict)
self.assertEquals(len(profile.options), 0)
self.assertEqual(len(profile.options), 0)
......@@ -19,6 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from __future__ import print_function
import argparse
import sys
import traceback
......@@ -94,7 +95,7 @@ if __name__ == "__main__":
result = admin.action(action_name, **options)
except tuned.admin.TunedAdminException as e:
if not debug:
print >>sys.stderr, e
print(e, file=sys.stderr)
else:
traceback.print_exc()
sys.exit(2)
......
......@@ -24,6 +24,7 @@ Created on Oct 15, 2013
@author: mstana
'''
from __future__ import print_function
try:
import gi
except ImportError:
......@@ -92,7 +93,7 @@ class Base(object):
tuned.admin.DBusController(consts.DBUS_BUS,
consts.DBUS_INTERFACE, consts.DBUS_OBJECT)
self.controller.is_running()
except tuned.admin.exceptions.TunedAdminDBusException, ex:
except tuned.admin.exceptions.TunedAdminDBusException as ex:
response = self.tuned_daemon_exception_dialog.run()
if response == 0:
......@@ -120,7 +121,7 @@ class Base(object):
try:
self.builder.add_from_file(GLADEUI)
except GObject.GError as e:
print >> sys.stderr, "Error loading '%s'" % GLADEUI
print("Error loading '%s'" % GLADEUI, file=sys.stderr)
sys.exit(1)
#
# DIALOGS
......@@ -535,7 +536,7 @@ class Base(object):
)
return
options = '\n'.join('%s = %r' % (key, val) for (key, val) in
plugin._get_config_options().iteritems())
plugin._get_config_options().items())
self.textview_plugin_avaible_text.get_buffer().set_text(options)
self.textview_plugin_documentation_text.get_buffer().set_text(plugin.__doc__)
......@@ -570,7 +571,7 @@ class Base(object):
if item[0] == profile:
iter = self.treestore_profiles.get_iter(item.path)
self.treestore_profiles.remove(iter)
except ManagerException, ex:
except ManagerException as ex:
self.error_dialog('Profile can not be remove', ex.__str__())
def execute_cancel_window_profile_editor(self, button):
......@@ -767,7 +768,7 @@ class Base(object):
# load all values not just normal
for (name, unit) in profile.units.items():
for (name, unit) in list(profile.units.items()):
self.notebook_plugins.append_page_menu(self.treeview_for_data(unit.options),
Gtk.Label(unit.name), Gtk.Label(unit.name))
self.notebook_plugins.show_all()
......@@ -783,7 +784,7 @@ class Base(object):
treestore = Gtk.ListStore(GObject.TYPE_STRING,
GObject.TYPE_STRING)
for (option, value) in data.items():
for (option, value) in list(data.items()):
treestore.append([str(value), option])
treeview = Gtk.TreeView(treestore)
renderer = Gtk.CellRendererText()
......@@ -1021,12 +1022,12 @@ if __name__ == '__main__':
# Explicitly disabling shell to be safe
ec = subprocess.call(['pkexec', EXECNAME] + sys.argv[1:], shell = False)
except (subprocess.CalledProcessError) as e:
print >> sys.stderr, 'Error elevating privileges: %s' % e
print('Error elevating privileges: %s' % e, file=sys.stderr)
else:
# If not pkexec error
if ec not in [126, 127]:
sys.exit(0)
# In case of error elevating privileges
print >> sys.stderr, 'Superuser permissions are required to run the daemon.'
print('Superuser permissions are required to run the daemon.', file=sys.stderr)
sys.exit(1)
base = Base()
......@@ -19,6 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from __future__ import print_function
import argparse
import os
import sys
......@@ -31,7 +32,7 @@ import tuned.version as ver
from tuned.utils.global_config import GlobalConfig
def error(message):
print >>sys.stderr, message
print(message, file=sys.stderr)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description = "Daemon for monitoring and adaptive tuning of system devices.")
......
from admin import *
from exceptions import *
from dbus_controller import *
from .admin import *
from .exceptions import *
from .dbus_controller import *
from __future__ import print_function
import tuned.admin
from tuned.utils.commands import commands
from tuned.profiles import Locator as profiles_locator
from exceptions import TunedAdminDBusException
from .exceptions import TunedAdminDBusException
from tuned.exceptions import TunedException
import tuned.consts as consts
import os
......@@ -94,7 +95,7 @@ class Admin(object):
profile_names = self._controller.profiles2()
except TunedAdminDBusException as e:
# fallback to older API
profile_names = map(lambda profile:(profile, ""), self._controller.profiles())
profile_names = [(profile, "") for profile in self._controller.profiles()]
self._print_profiles(profile_names)
self._action_dbus_active()
return self._controller.exit(True)
......
......@@ -3,7 +3,7 @@ import dbus.exceptions
import time
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib, GObject
from exceptions import TunedAdminDBusException
from .exceptions import TunedAdminDBusException
__all__ = ["DBusController"]
......
from application import *
from controller import *
from daemon import *
from .application import *
from .controller import *
from .daemon import *
from tuned import storage, units, monitors, plugins, profiles, exports, hardware
from tuned.exceptions import TunedException
import tuned.logs
import controller
import daemon
from . import controller
from . import daemon
import signal
import os
import sys
......
import interfaces
import controller
import dbus_exporter as dbus
from . import interfaces
from . import controller
from . import dbus_exporter as dbus
def export(*args, **kwargs):
"""Decorator, use to mark exportable methods."""
......
import interfaces
from . import interfaces
import inspect
import tuned.patterns
......
import interfaces
from . import interfaces
import decorator
import dbus.service
import dbus.mainloop.glib
......@@ -87,7 +87,7 @@ class DBusExporter(interfaces.ExporterInterface):
args[-1] = ""
return method(*args, **kwargs)
wrapper = decorator.decorator(wrapper, method.im_func)
wrapper = decorator.decorator(wrapper, method.__func__)
wrapper = dbus.service.method(self._interface_name, in_signature, out_signature, sender_keyword = "caller")(wrapper)
self._dbus_methods[method_name] = wrapper
......@@ -103,7 +103,7 @@ class DBusExporter(interfaces.ExporterInterface):
def wrapper(wrapped, owner, *args, **kwargs):
return method(*args, **kwargs)
wrapper = decorator.decorator(wrapper, method.im_func)
wrapper = decorator.decorator(wrapper, method.__func__)
wrapper = dbus.service.signal(self._interface_name, out_signature)(wrapper)
self._dbus_methods[method_name] = wrapper
......
......@@ -109,7 +109,7 @@ class GuiProfileLoader(object):
# profile dont have main section
pass
for (name, unit) in profile.units.items():
for (name, unit) in list(profile.units.items()):
config[name] = unit.options
if not os.path.exists(path):
os.makedirs(path)
......@@ -150,7 +150,7 @@ class GuiProfileLoader(object):
# profile dont have main section
pass
for (name, unit) in profile.units.items():
for (name, unit) in list(profile.units.items()):
config[name] = unit.options
if not os.path.exists(path):
......@@ -159,7 +159,7 @@ class GuiProfileLoader(object):
self._refresh_profiles()
def get_names(self):
return self.profiles.keys()
return list(self.profiles.keys())
def get_profile(self, profile):
return self.profiles[profile]
......
from inventory import *
from device_matcher import *
from device_matcher_udev import *
from .inventory import *
from .device_matcher import *
from .device_matcher_udev import *
......@@ -19,10 +19,10 @@ class DeviceMatcher(object):
which matches all devices is added. The device matches if and only
if it matches some positive rule, but no negative rule.
"""
if isinstance(rules, basestring):
if isinstance(rules, str):
rules = re.split(r"\s|,\s*", rules)
positive_rules = filter(lambda rule: not rule.startswith("!") and not rule.strip() == '', rules)
positive_rules = [rule for rule in rules if not rule.startswith("!") and not rule.strip() == '']
negative_rules = [rule[1:] for rule in rules if rule not in positive_rules]
if len(positive_rules) == 0:
......
import device_matcher
from . import device_matcher
import re
__all__ = ["DeviceMatcherUdev"]
......@@ -12,7 +12,7 @@ class DeviceMatcherUdev(device_matcher.DeviceMatcher):
"""
properties = ''
for key, val in device.items():
for key, val in list(device.items()):
properties += key + '=' + val + '\n'
return re.search(regex, properties, re.MULTILINE) is not None
from base import *
from repository import *
from .base import *
from .repository import *
......@@ -99,19 +99,19 @@ class Monitor(object):
self._refresh_updating_devices()
def add_device(self, device):
assert isinstance(device, basestring)
assert isinstance(device, str)
if device in self._available_devices:
self._devices.add(device)
self._updating_devices.add(device)
def remove_device(self, device):
assert isinstance(device, basestring)
assert isinstance(device, str)
if device in self._devices:
self._devices.remove(device)
self._updating_devices.remove(device)
def get_load(self):
return dict(filter(lambda (dev, load): dev in self._devices, self._load.items()))
return dict([dev_load for dev_load in list(self._load.items()) if dev_load[0] in self._devices])
def get_device_load(self, device):
return self._load.get(device, None)
......@@ -32,4 +32,4 @@ class DiskMonitor(tuned.monitors.Monitor):
@classmethod
def _update_disk(cls, dev):
with open("/sys/block/" + dev + "/stat") as statfile:
cls._load[dev] = map(int, statfile.read().split())
cls._load[dev] = list(map(int, statfile.read().split()))
from repository import *
import instance
from .repository import *
from . import instance
......@@ -113,7 +113,7 @@ class Plugin(object):
def destroy_instances(self):
"""Destroy all instances."""
for instance in self._instances.values():
for instance in list(self._instances.values()):
log.debug("destroying instance %s (%s)" % (instance.name, self.name))
self._destroy_instance(instance)
self._instances.clear()
......@@ -151,7 +151,7 @@ class Plugin(object):
log.error("Plugin '%s' does not support the 'devices_udev_regex' option", self.name)
return set()
udev_devices = self._device_matcher_udev.match_list(instance.devices_udev_regex, udev_devices)
return set(map(lambda x: x.sys_name, udev_devices))
return set([x.sys_name for x in udev_devices])
def assign_free_devices(self, instance):
if not self._devices_supported:
......@@ -221,7 +221,7 @@ class Plugin(object):
arguments.append("full_rollback")
arguments.append(dev)
log.info("calling script '%s' with arguments '%s'" % (script, str(arguments)))
log.debug("using environment '%s'" % str(environ.items()))
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)
......@@ -307,7 +307,7 @@ class Plugin(object):
self._cleanup_all_non_device_commands(instance)
def _instance_apply_dynamic(self, instance, device):
for option in filter(lambda opt: self._storage_get(instance, self._commands[opt], device) is None, self._options_used_by_dynamic):
for option in [opt for opt in self._options_used_by_dynamic if self._storage_get(instance, self._commands[opt], device) is None]:
self._check_and_save_value(instance, self._commands[option], device)
self._instance_update_dynamic(instance, device)
......@@ -359,13 +359,13 @@ class Plugin(object):
self._commands[command_name] = info
# sort commands by priority
self._commands = collections.OrderedDict(sorted(self._commands.iteritems(), key=lambda (name, info): info["priority"]))
self._commands = collections.OrderedDict(sorted(iter(self._commands.items()), key=lambda name_info: name_info[1]["priority"]))
def _check_commands(self):
"""
Check if all commands are defined correctly.
"""
for command_name, command in self._commands.items():
for command_name, command in list(self._commands.items()):
# do not check custom commands
if command.get("custom", False):
continue
......@@ -400,13 +400,13 @@ class Plugin(object):
#
def _execute_all_non_device_commands(self, instance):