diff options
author | zsdc <taras@vyos.io> | 2023-07-05 14:56:05 +0300 |
---|---|---|
committer | zsdc <taras@vyos.io> | 2023-07-05 19:27:25 +0300 |
commit | d3ead28d1391f1102e6e89de119226557f3fcce3 (patch) | |
tree | 277dc7497ad36e1f91261197178bf40f5b2e810a /python/vyos | |
parent | 5c1865487c5cf1bfb92ff873a97df4b129c9566f (diff) | |
download | vyos-1x-d3ead28d1391f1102e6e89de119226557f3fcce3.tar.gz vyos-1x-d3ead28d1391f1102e6e89de119226557f3fcce3.zip |
util: T1797: Optimized sysctl helpers
- modified `sysctl_read()` to return the whole value
- modified `sysctl_write()` logic to return `True` only in case a value was
changed successfully
- added `sysctl_apply()` to apply a dictionary of values at once
Diffstat (limited to 'python/vyos')
-rw-r--r-- | python/vyos/utils/system.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/python/vyos/utils/system.py b/python/vyos/utils/system.py new file mode 100644 index 000000000..7102d5985 --- /dev/null +++ b/python/vyos/utils/system.py @@ -0,0 +1,82 @@ +# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see <http://www.gnu.org/licenses/>. + +from subprocess import run + + +def sysctl_read(name: str) -> str: + """Read and return current value of sysctl() option + + Args: + name (str): sysctl key name + + Returns: + str: sysctl key value + """ + tmp = run(['sysctl', '-nb', name], capture_output=True) + return tmp.stdout.decode() + + +def sysctl_write(name: str, value: str | int) -> bool: + """Change value via sysctl() + + Args: + name (str): sysctl key name + value (str | int): sysctl key value + + Returns: + bool: True if changed, False otherwise + """ + # convert other types to string before comparison + if not isinstance(value, str): + value = str(value) + # do not change anything if a value is already configured + if sysctl_read(name) == value: + return True + # return False if sysctl call failed + if run(['sysctl', '-wq', f'{name}={value}']).returncode != 0: + return False + # compare old and new values + # sysctl may apply value, but its actual value will be + # different from requested + if sysctl_read(name) == value: + return True + # False in other cases + return False + + +def sysctl_apply(sysctl_dict: dict[str, str], revert: bool = True) -> bool: + """Apply sysctl values. + + Args: + sysctl_dict (dict[str, str]): dictionary with sysctl keys with values + revert (bool, optional): Revert to original values if new were not + applied. Defaults to True. + + Returns: + bool: True if all params configured properly, False in other cases + """ + # get current values + sysctl_original: dict[str, str] = {} + for key_name in sysctl_dict.keys(): + sysctl_original[key_name] = sysctl_read(key_name) + # apply new values and revert in case one of them was not applied + for key_name, value in sysctl_dict.items(): + if not sysctl_write(key_name, value): + if revert: + sysctl_apply(sysctl_original, revert=False) + return False + # everything applied + return True |