1
0
Fork 0

Merge pull request #760 from zacikpa/prepend-variables

variables: Add an option to prepend child variables before parent ones
This commit is contained in:
Jaroslav Škarvada 2025-07-25 21:06:24 +02:00 committed by GitHub
commit b38f56efc2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 31 additions and 14 deletions

View file

@ -21,6 +21,7 @@ USER_PROFILES_DIR = "/etc/tuned/profiles"
SYSTEM_PROFILES_DIR = "/usr/lib/tuned/profiles"
PERSISTENT_STORAGE_DIR = "/var/lib/tuned"
PLUGIN_MAIN_UNIT_NAME = "main"
PLUGIN_VARIABLES_UNIT_NAME = "variables"
# Magic section header because ConfigParser does not support "headerless" config
MAGIC_HEADER_NAME = "this_is_some_magic_section_header_because_of_compatibility"
RECOMMEND_DIRECTORIES = ["/usr/lib/tuned/recommend.d", "/etc/tuned/recommend.d"]

View file

@ -51,15 +51,9 @@ class Loader(object):
processed_files = []
self._load_profile(profile_names, profiles, processed_files)
if len(profiles) > 1:
final_profile = self._profile_merger.merge(profiles)
else:
final_profile = profiles[0]
final_profile = self._profile_merger.merge(profiles)
final_profile.name = " ".join(profile_names)
if "variables" in final_profile.units:
self._variables.add_from_cfg(final_profile.units["variables"].options)
del(final_profile.units["variables"])
self._variables.add_from_cfg(final_profile.variables)
# FIXME hack, do all variable expansions in one place
self._expand_vars_in_devices(final_profile)
self._expand_vars_in_regexes(final_profile)

View file

@ -1,5 +1,6 @@
import collections
import tuned.consts as consts
from functools import reduce
from tuned.profiles.profile import Profile
class Merger(object):
"""
@ -14,7 +15,7 @@ class Merger(object):
Merge multiple configurations into one. If there are multiple units of the same type, option 'devices'
is set for each unit with respect to eliminating any duplicate devices.
"""
merged_config = reduce(self._merge_two, configs)
merged_config = reduce(self._merge_two, configs, Profile())
return merged_config
def _merge_two(self, profile_a, profile_b):
@ -23,11 +24,22 @@ class Merger(object):
from the newer profile. If the 'replace' options of the newer unit is 'True', all options from the
older unit are dropped.
"""
if profile_a.name is None:
profile_a.name = profile_b.name
profile_a.options.update(profile_b.options)
for unit_name, unit in list(profile_b.units.items()):
if unit.replace or unit_name not in profile_a.units:
if unit.type == consts.PLUGIN_VARIABLES_UNIT_NAME:
if unit.replace:
profile_a.variables.clear()
overwritten_variables = set(profile_a.variables.keys()) & set(unit.options.keys())
profile_a.variables.update(unit.options)
if unit.prepend:
for variable in reversed(unit.options):
if variable not in overwritten_variables:
profile_a.variables.move_to_end(variable, last=False)
elif unit.replace or unit_name not in profile_a.units:
profile_a.units[unit_name] = unit
else:
profile_a.units[unit_name].type = unit.type

View file

@ -7,10 +7,11 @@ class Profile(object):
Representation of a tuning profile.
"""
__slots__ = ["_name", "_options", "_units"]
__slots__ = ["_name", "_options", "_variables", "_units"]
def __init__(self, name, config):
def __init__(self, name=None, config={}):
self._name = name
self._variables = collections.OrderedDict()
self._init_options(config)
self._init_units(config)
@ -40,6 +41,10 @@ class Profile(object):
def name(self, value):
self._name = value
@property
def variables(self):
return self._variables
@property
def units(self):
"""

View file

@ -6,7 +6,7 @@ class Unit(object):
Unit description.
"""
__slots__ = [ "_name", "_priority", "_type", "_enabled", "_replace", "_drop", "_devices", "_devices_udev_regex", \
__slots__ = [ "_name", "_priority", "_type", "_enabled", "_replace", "_prepend", "_drop", "_devices", "_devices_udev_regex", \
"_cpuinfo_regex", "_uname_regex", "_script_pre", "_script_post", "_options" ]
def __init__(self, name, config):
@ -15,6 +15,7 @@ class Unit(object):
self._type = config.pop("type", self._name)
self._enabled = config.pop("enabled", True) in [True, "True", "true", 1, "1"]
self._replace = config.pop("replace", False) in [True, "True", "true", 1, "1"]
self._prepend = config.pop("prepend", False) in [True, "True", "true", 1, "1"]
self._drop = config.pop("drop", None)
if self._drop is not None:
self._drop = re.split(r"\b\s*[,;]\s*", str(self._drop))
@ -58,6 +59,10 @@ class Unit(object):
def replace(self):
return self._replace
@property
def prepend(self):
return self._prepend
@property
def drop(self):
return self._drop