diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efa407c --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/DOCS.md b/DOCS.md new file mode 100644 index 0000000..4d325cb --- /dev/null +++ b/DOCS.md @@ -0,0 +1,67 @@ +# Kernel module data spec + +This part will describe details of what data need to be passed to insert_kernel_module role. + +Example: +```yaml +kernel_modules: + - name: amd_energy + git_repo: https://github.com/amd/amd_energy.git + git_repo_tag: b1033832b817e69f9df49a6a538d5fd2e1f10f6c + force_build: true + cpu_constraints: + cpu_inclusions: + - family: 0x19 + model: 0x55 + cpu_exclusions: + - family: 0x20 + model: 0x56 + patches: + - amd_energy_kernel_version.patch +``` + + +| Attribute | Required | Type | Description | Example | +| --------------- | -------- | ---- | -------------------------------------------------------------------------------------------------- | ------------------------------------- | +| name | true | str | Name of the kernel module to be loaded | amd_energy | +| git_repo | false | str | Repository from whichto build the off-tree module | https://github.com/amd/amd_energy.git | +| git_repo_tag | false | str | Tag, branch or hash to checkout to when cloning git repo. | develop | +| force_build | false | bool | Forces build in case the module is already built/loaded. | True | +| cpu_constraints | false | dict | List of requirements that the CPU must satisfy on order for the module to be installed to the dost | example later | +| patches | false | list | List of names of patches from the files/ directory that will be applied to the fit repo. | ["fix1.patch", "fix2.patch"] | + +## Example of cpu_constraints + +cpu_constraints has two main keys - cpu_inclusions adn cpu_exclusions. +When cpu_inclusion is not met, the module will not be loaded/built. +When cpu_exclusion is met, the module will not be loaded/built. +The same format of family/model is used for cpu_inclusions and for cpu_exclusions. + +When no contraints are defined, the module will be loaded on all hosts! + +```yaml +cpu_constraints: + cpu_inclusions: + # Single values + - family: 0x19 + model: 0x3F + # Closed ranges + - family: + - range: + start: 0x19 + end: 0x55 + model: + - range: + start: 0x10 + end: 0x1F + - range: + start: 0xA0 + end: 0xAF + # Open ranges + - family: + - range: + end: 0x04 + model: + - range: + start: 0x0F +``` \ No newline at end of file diff --git a/roles/insert_kernel_module/files/amd_energy_kernel_version.patch b/files/amd_energy_kernel_version.patch similarity index 100% rename from roles/insert_kernel_module/files/amd_energy_kernel_version.patch rename to files/amd_energy_kernel_version.patch diff --git a/filter_plugins/cpu_contraints.py b/filter_plugins/cpu_contraints.py new file mode 100644 index 0000000..72a2e4b --- /dev/null +++ b/filter_plugins/cpu_contraints.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 +from ansible.errors import AnsibleFilterError + + +def is_in_range(value, start, end): + return start <= value <= end + + +def match_single_constraint(value, constraint): + # Single value specified + if isinstance(constraint, int): + if value == constraint: + return True + + # List of ranges specified + elif isinstance(constraint, list): + for item in constraint: + range = item.get("range") + if not range: + raise AnsibleFilterError( + "Constraints needs to be int or list of ranges!" + ) + if is_in_range(value, range.get("start", float("-inf")), range.get("end", float("inf"))): + return True + + else: + raise AnsibleFilterError( + "Constraints needs to be int or list of ranges!" + ) + + return False + + +def match_cpu_constraints(cpu_family, cpu_model, constraints): + """Return True if CPU family and model are a match in any of the ranges.""" + family_match = False + model_match = False + + for constraint in constraints: + if match_single_constraint(cpu_family, constraint["family"]): + family_match = True + if match_single_constraint(cpu_model, constraint["model"]): + model_match = True + + # Both model and family need to be a match to the constraints + return family_match and model_match + + +def check_cpu_constraints(kernel_module, cpu_family, cpu_model): + """Return True if the checks for constraints are positive and a match.""" + + # Get list of constraints from kernel module data + checks = kernel_module.get("cpu_constraints") + + # No constraints were defined + if not checks: + return True + + try: + cpu_family = int(cpu_family) + cpu_model = int(cpu_model) + except (ValueError, TypeError): + raise AnsibleFilterError( + "Input CPU family and model must be integers!") + + constraint_match = match_cpu_constraints( + cpu_family, cpu_model, checks.get("cpu_inclusions", list())) + exclusion_match = match_cpu_constraints( + cpu_family, cpu_model, checks.get("cpu_exclusions", list())) + + if exclusion_match: + return False + + return constraint_match + + +class FilterModule: + def filters(self): + return { + "check_cpu_constraints": check_cpu_constraints + } diff --git a/group_vars/all.yml b/group_vars/all.yml index a349289..3e46cc3 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -1,5 +1,5 @@ kernel_modules: - # Example of a builtin module + # Example of a builtin module # What should happen: it will not be loaded, because it already is loaded - name: acpi-cpufreq kernel_build_opt: CONFIG_X86_ACPI_CPUFREQ @@ -7,13 +7,50 @@ kernel_modules: - name: amd_pstate kernel_build_opt: CONFIG_X86_AMD_PSTATE - # Example of a pluggable module that ships with kernel - # What should happen: it will be loaded + - name: msr + kernel_build_opt: CONFIG_X86_MSR + + # Example of a pluggable module that ships with kernel + # What should happen: it will be built from source and loaded - name: cpuid - kernel_build_opt: CONFIG_X86_CPUIDA + kernel_build_opt: CONFIG_X86_CPUID + git_repo: https://github.com/erman-dev/cpuid-dkms.git + force_build: True # Example of modules that need to be built # What should happen: it will be built and then loaded - name: amd_hsmp git_repo: https://github.com/amd/amd_hsmp.git git_repo_tag: f34b98fb70b67a7908f32d4d6da5a2ee89857b08 + + - name: amd_energy + git_repo: https://github.com/amd/amd_energy.git + force_build: true + cpu_constraints: + cpu_inclusions: + - family: 0x19 + model: + - range: + start: 0x00 + end: 0x0F + - range: + start: 0x30 + end: 0x3F + - family: 0x19 + model: + - range: + start: 0x10 + end: 0x1F + - range: + start: 0xA0 + end: 0xAF + - range: + start: 0x90 + end: 0x9F + - family: 0x1A + model: + - range: + start: 0x00 + end: 0x1F + patches: + - amd_energy_kernel_version.patch diff --git a/group_vars/family_19h/main.yml b/group_vars/family_19h/main.yml deleted file mode 100644 index ccb6cda..0000000 --- a/group_vars/family_19h/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -kernel_modules: - # Example of a builtin module - # What should happen: it will not be loaded, because it already is loaded - - name: acpi-cpufreq - kernel_build_opt: CONFIG_X86_ACPI_CPUFREQ - - - name: amd_pstate - kernel_build_opt: CONFIG_X86_AMD_PSTATE - - # Example of a pluggable module that ships with kernel - # What should happen: it will be loaded - - name: cpuid - kernel_build_opt: CONFIG_X86_CPUID - - # Example of modules that need to be built - # What should happen: it will be built and then loaded - - name: amd_hsmp - git_repo: https://github.com/amd/amd_hsmp.git - git_repo_tag: f34b98fb70b67a7908f32d4d6da5a2ee89857b08 - - - name: amd_energy - git_repo: https://github.com/amd/amd_energy.git - force_build: True - patches: - - amd_energy_kernel_version.patch diff --git a/hosts.ini b/hosts.ini index 5058ba5..052a3e9 100644 --- a/hosts.ini +++ b/hosts.ini @@ -1,9 +1,5 @@ [all:children] -family_19h -family_other +lab1 -[family_19h] +[lab1] epyc01 ansible_host=10.0.0.197 ansible_user=ubuntu - -[family_other] -epyc02 ansible_host=10.0.0.197 ansible_user=ubuntu diff --git a/lint.sh b/lint.sh new file mode 100755 index 0000000..b4900dd --- /dev/null +++ b/lint.sh @@ -0,0 +1,3 @@ +#/bin/bash + +ansible-lint --exclude without-roles/ -v \ No newline at end of file diff --git a/playbook.yml b/playbook.yml index 53d55d6..f5208f2 100644 --- a/playbook.yml +++ b/playbook.yml @@ -4,16 +4,19 @@ gather_facts: true tasks: # Make sure all tools are present on the machine - - import_role: + - name: Ensure necessary tools are present + ansible.builtin.import_role: name: ensure_tools # Loop over the role and pass the item as "kernel_module" - - include_role: + - name: Load kernel module + ansible.builtin.include_role: name: insert_kernel_module loop: "{{ kernel_modules }}" vars: - kernel_module: "{{ item }}" - + insert_kernel_module_data: "{{ item }}" + # TODO: Make sure the boot params are ok - - import_role: + - name: Check kernel boot options + ansible.builtin.import_role: name: kernel_boot_options diff --git a/roles/ensure_tools/tasks/main.yml b/roles/ensure_tools/tasks/main.yml index 9d4ef3f..a4a182f 100644 --- a/roles/ensure_tools/tasks/main.yml +++ b/roles/ensure_tools/tasks/main.yml @@ -1,8 +1,16 @@ --- +- name: Install additional packages for EL systems + become: true + ansible.builtin.package: + name: + - epel-release + when: ansible_facts["os_family"] == "RedHat" + - name: Ensure the host has necessary tools become: true - package: - name: + ansible.builtin.package: + update_cache: true + name: - dkms - git - - patch \ No newline at end of file + - patch diff --git a/roles/insert_kernel_module/tasks/build_module.yml b/roles/insert_kernel_module/tasks/build_module.yml index d31e8a8..66ca8e8 100644 --- a/roles/insert_kernel_module/tasks/build_module.yml +++ b/roles/insert_kernel_module/tasks/build_module.yml @@ -1,96 +1,104 @@ --- -- fail: +- name: "Fail on missing git_repo : {{ insert_kernel_module_data.name }}" + ansible.builtin.fail: msg: >- - The playbook attempted to build the module "{{ kernel_module.name }}" - To build a module, git_repo attribute must be defined! - This means that the module is missing from the kernel or you've entered - invalid kernel_build_opt parameter. If you belive that this is incorrect, + The playbook attempted to build the module "{{ insert_kernel_module_data.name }}" + To build a module, git_repo attribute must be defined! + This means that the module is missing from the kernel or you've entered + invalid kernel_build_opt parameter. If you belive that this is incorrect, check your config. - when: kernel_module.git_repo is not defined + when: insert_kernel_module_data.git_repo is not defined -- name: "{{ kernel_module.name }} : Create temporary build directory for build" +- name: "Create temporary build directory for build : {{ insert_kernel_module_data.name }}" ansible.builtin.tempfile: state: directory suffix: build register: temp_workdir -- ansible.builtin.set_fact: - module_dir: "{{ temp_workdir.path }}/{{ kernel_module.name }}" +- name: "Set module directory : {{ insert_kernel_module_data.name }}" + ansible.builtin.set_fact: + module_dir: "{{ temp_workdir.path }}/{{ insert_kernel_module_data.name }}" -- name: "{{ kernel_module.name }} : Clone the module repository" - git: - repo: "{{ kernel_module.git_repo }}" +- name: "Clone the module repository : {{ insert_kernel_module_data.name }}" + ansible.builtin.git: + repo: "{{ insert_kernel_module_data.git_repo }}" dest: "{{ module_dir }}" - version: "{{ kernel_module.git_repo_tag | default(omit) }}" + version: "{{ insert_kernel_module_data.git_repo_tag | default(omit) }}" -- name: "{{ kernel_module.name }} : Apply patches" +- name: "Apply patches : {{ insert_kernel_module_data.name }}" ansible.posix.patch: src: "{{ patch }}" basedir: "{{ module_dir }}" strip: 1 - loop: "{{ kernel_module.patches }}" + loop: "{{ insert_kernel_module_data.patches }}" loop_control: loop_var: patch - when: - - kernel_module.patches is defined - - kernel_module.patches is iterable + when: + - insert_kernel_module_data.patches is defined + - insert_kernel_module_data.patches is iterable -- name: "{{ kernel_module.name }} : Detect dkms.conf file" +- name: "Detect dkms.conf file : {{ insert_kernel_module_data.name }}" ansible.builtin.stat: path: "{{ module_dir }}/dkms.conf" register: dmks_file -- fail: +- name: "Fail on missing dkms.conf : {{ insert_kernel_module_data.name }}" + ansible.builtin.fail: msg: >- - The repository {{ kernel_module.git_repo }} is missing the dkms.conf file. + The repository {{ insert_kernel_module_data.git_repo }} is missing the dkms.conf file. These plays are compatible only with kernel modules that support build with DKMS! when: not dmks_file.stat.exists -- name: "{{ kernel_module.name }} : Extract PACKAGE_VERSION using regex" +- name: "Extract PACKAGE_VERSION using regex : {{ insert_kernel_module_data.name }}" ansible.builtin.shell: | + set -o pipefail grep '^PACKAGE_VERSION=' {{ module_dir }}/dkms.conf | awk -F'=' '{print $2}'; + args: + executable: /bin/bash register: package_version_grep changed_when: false -- ansible.builtin.set_fact: +- name: "Set package version : {{ insert_kernel_module_data.name }}" + ansible.builtin.set_fact: package_version: "{{ package_version_grep.stdout }}" -- block: +- name: "Install module : {{ insert_kernel_module_data.name }}" + block: # RC 0 - ok # RC 1 - general error # RC 2 - folder not found # RC 3 - module already added - - name: "{{ kernel_module.name }} : Add module to DKMS tree" - become: True + - name: "Add module to DKMS tree : {{ insert_kernel_module_data.name }}" + become: true ansible.builtin.command: "dkms add {{ module_dir }}" failed_when: dkms_add.rc not in [0,3] changed_when: dkms_add.rc == 0 register: dkms_add - - name: "{{ kernel_module.name }} : Build module using DKMS" - become: True + - name: "Build module using DKMS : {{ insert_kernel_module_data.name }}" + become: true ansible.builtin.command: > - dkms build {% if kernel_module.get('force_build', False) %}--force{% endif %} - -m {{ kernel_module.name }} + dkms build {% if insert_kernel_module_data.get('force_build', False) %}--force{% endif %} + -m {{ insert_kernel_module_data.name }} -v {{ package_version }} args: chdir: "{{ module_dir }}" register: dkms_build changed_when: "'already built for kernel' not in dkms_build.stdout" - - name: "{{ kernel_module.name }} : Install module using DKMS" - become: True + - name: "Install module using DKMS : {{ insert_kernel_module_data.name }}" + become: true ansible.builtin.command: > - dkms install {% if kernel_module.get('force_build', False) %}--force{% endif %} - -m {{ kernel_module.name }} + dkms install --force + -m {{ insert_kernel_module_data.name }} -v {{ package_version }} args: chdir: "{{ module_dir }}" - changed_when: "'already installed on kernel' not in dkms_install.stdout" + changed_when: "'Installation' in dkms_install.stdout" register: dkms_install always: - - name: "{{ kernel_module.name }} : Cleanup temporary directory" + - name: "Cleanup temporary directory : {{ insert_kernel_module_data.name }}" ansible.builtin.file: path: "{{ temp_workdir.path }}" state: absent diff --git a/roles/insert_kernel_module/tasks/detect_module.yml b/roles/insert_kernel_module/tasks/detect_module.yml index 3c52d4c..394aee9 100644 --- a/roles/insert_kernel_module/tasks/detect_module.yml +++ b/roles/insert_kernel_module/tasks/detect_module.yml @@ -1,57 +1,61 @@ --- # Detect what kind of module is being loaded - builtin, loadable or missing -- name: "{{ kernel_module.name }} : Detect if the module is present in kernel config" +- name: "Detect if the module is present in kernel config : {{ insert_kernel_module_data.name }}" vars: kernel_conf_file: "/boot/config-{{ ansible_facts['kernel'] }}" ansible.builtin.shell: | - if grep -q '^{{ kernel_module.kernel_build_opt }}=' {{ kernel_conf_file }}; then - grep '^{{ kernel_module.kernel_build_opt }}=' {{ kernel_conf_file }} | awk -F'=' '{print $2}'; + set -o pipefail + if grep -q '^{{ insert_kernel_module_data.kernel_build_opt }}=' {{ kernel_conf_file }}; then + grep '^{{ insert_kernel_module_data.kernel_build_opt }}=' {{ kernel_conf_file }} | awk -F'=' '{print $2}'; fi + args: + executable: /bin/bash register: kernel_config changed_when: false when: - - kernel_module.kernel_build_opt is defined + - insert_kernel_module_data.kernel_build_opt is defined # If the module was not found in the kernel config, try checking it with modinfo in case # it was already installed with DKMS -- name: "{{ kernel_module.name }} : Get module info with modinfo" - ansible.builtin.command: "modinfo {{ kernel_module.name }}" +- name: "Get module info with modinfo : {{ insert_kernel_module_data.name }}" + ansible.builtin.command: "modinfo {{ insert_kernel_module_data.name }}" register: modinfo failed_when: false changed_when: false when: - - "kernel_module.kernel_build_opt is not defined or kernel_config.stdout == ''" + - "insert_kernel_module_data.kernel_build_opt is not defined or kernel_config.stdout == ''" # Decide what kind of kernel module it is # 1. =y was present in kernel config, so it is a builtin module # 2. =m was present in kernel config, so it is a loadable module that ships with kernel # or module was not found in the kernel config, but found with modinfo, so it was installed already with DKMS, so it can be loaded # 3. module was not found in the kernel config and not found with modinfo, so it is missing -# or kernel_module.kernel_build_opt is not defined -> module was for sure not found as it was expected this module to not be part of kernel when the option was not defined +# or insert_kernel_module_data.kernel_build_opt is not defined -> module was for sure not found as it was expected this module to not be +# part of kernel when the option was not defined # 4. None of the above, the user should examine the module manually -- name: "{{ kernel_module.name }} : Use modinfo results to get the module type" +- name: "Use modinfo results to get the module type : {{ insert_kernel_module_data.name }}" vars: kernel_config_output: "{{ kernel_config.stdout | default('') }}" modinfo_output: "{{ modinfo.stdout | default('') }}" modinfo_error_output: "{{ modinfo.stderr | default('') }}" - set_fact: + ansible.builtin.set_fact: module_type: |- {%- if 'y' in kernel_config_output -%} builtin {%- elif 'm' in kernel_config_output or '/lib/modules' in modinfo_output -%} loadable - {%- elif 'not found' in modinfo_error_output or kernel_module.kernel_build_opt is not defined -%} + {%- elif 'not found' in modinfo_error_output or insert_kernel_module_data.kernel_build_opt is not defined -%} missing - {%- else -%} - error + {%- else -%} + error {%- endif -%} -- name: "{{ kernel_module.name }} : Raise error if the module_type was not detected" - fail: +- name: "Raise error if the module_type was not detected : {{ insert_kernel_module_data.name }}" + ansible.builtin.fail: msg: |- The play was unable to determine the type of the module (builtin, loadable, missing). This is most likely due kernel_build_opt missing from /boot/config or problem with modinfo. - Please check your kernel_module config. Your current config is: + Please check your insert_kernel_module_data config. Your current config is: - {{ kernel_module | to_nice_yaml }} + {{ insert_kernel_module_data | to_nice_yaml }} when: module_type == "error" diff --git a/roles/insert_kernel_module/tasks/insert_module.yml b/roles/insert_kernel_module/tasks/insert_module.yml new file mode 100644 index 0000000..20e6e0b --- /dev/null +++ b/roles/insert_kernel_module/tasks/insert_module.yml @@ -0,0 +1,31 @@ +# Detect what type of kernel module it is - builtin, loadable, or missing +- name: "Import tasks to detect module type : {{ insert_kernel_module_data.name }}" + ansible.builtin.import_tasks: detect_module.yml + +# Sometimes it might be preffered to use the off-tree module instead of the module +# that is already shipped with the kernel. When a force_build flag is set for +# a module a build_module.yml will be called instead of loading it. +- name: "Fail if the user is trying to rebuild builtin module : {{ insert_kernel_module_data.name }}" + ansible.builtin.fail: + msg: >- + Detected module_type is BUILTIN, but the force_build parameter was set to True. + You cannot force build of a builtin module! Please check you kernel module configuration. + when: + - module_type == "builtin" + - insert_kernel_module_data.force_build | default(False) + +# Builds module is the force_build override is true or if the module is missing +- name: "Build module : {{ insert_kernel_module_data.name }}" + ansible.builtin.include_tasks: build_module.yml + when: + - insert_kernel_module_data.force_build | default(False) or module_type == "missing" + +# And lastly the module is loaded, but only if it is loadable or built using DKMS +- name: "Load kernel module : {{ insert_kernel_module_data.name }}" + become: true + community.general.modprobe: + name: "{{ insert_kernel_module_data.name }}" + params: "{{ insert_kernel_module_data.params | default(omit) }}" + persistent: "present" + when: + - module_type in ["loadable", "missing"] diff --git a/roles/insert_kernel_module/tasks/main.yml b/roles/insert_kernel_module/tasks/main.yml index de6a9f2..4f9e097 100644 --- a/roles/insert_kernel_module/tasks/main.yml +++ b/roles/insert_kernel_module/tasks/main.yml @@ -1,39 +1,40 @@ --- -# This role loads one kernel_module specified in "kernel_module" +# This role loads one kernel module specified in "insert_kernel_module_data" -- fail: +- name: "Fail on incorrect input" + ansible.builtin.fail: msg: >- - To run this role, you need to pass kernel_module object with attribute + To run this role, you need to pass insert_kernel_module_data object with attribute "name" defined. - when: kernel_module.name is not defined + when: insert_kernel_module_data.name is not defined -# Detect what type of kernel module it is - builtin, loadable, or missing -- import_tasks: detect_module.yml +- name: "Get CPU data from /proc/cpuinfo : {{ insert_kernel_module_data.name }}" + ansible.builtin.command: "cat /proc/cpuinfo" + register: procinfo + changed_when: false -# Sometimes it might be preffered to use the off-tree module instead of the module -# that is already shipped with the kernel. When a force_build flag is set for -# a module a build_module.yml will be called instead of loading it. -# NOTE(r-krcek): This needs testing, I am not sure if it works as-is!! -- name: "{{ kernel_module.name }} : Fail if the user is trying to rebuild builtin module" - fail: - msg: >- - Detected module_type is BUILTIN, but the force_build parameter was set to True. - You cannot force build of a builtin module! Please check you kernel module configuration. - when: - - module_type == "builtin" - - kernel_module.force_build | default(False) +- name: "Extract attributes from /proc/cpuinfo : {{ insert_kernel_module_data.name }}" + vars: + cpuinfo_family: "{{ procinfo.stdout | regex_search('cpu family\\s+:\\s+(\\d+)', '\\1') }}" + cpuinfo_model: "{{ procinfo.stdout | regex_search('model\\s+:\\s+(\\d+)', '\\1') }}" + ansible.builtin.set_fact: + insert_kernel_module_cpu_family: "{{ cpuinfo_family[0] if cpuinfo_family else -1 | int }}" + insert_kernel_module_cpu_model: "{{ cpuinfo_model[0] if cpuinfo_model else -1 | int }}" + when: procinfo.stdout is defined -- name: "{{ kernel_module.name }} : Build module" - include_tasks: build_module.yml - when: - - kernel_module.force_build | default(False) or module_type == "missing" +- name: "Assert that all required information was gathered : {{ insert_kernel_module_data.name }}" + ansible.builtin.assert: + that: + - insert_kernel_module_cpu_family != "-1" + - insert_kernel_module_cpu_model != "-1" + fail_msg: | + The playbook was unable to gather all CPU information. + Please inspect the result of the previous two tasks, they were supposed + to extract CPU model and family from /proc/cpuinfo and they seem to have failed! -# And lastly the module is loaded, but only if it is loadable or built using DKMS -- name: "{{ kernel_module.name }} : Load kernel module" - become: true - community.general.modprobe: - name: "{{ kernel_module.name }}" - params: "{{ kernel_module.params | default(omit) }}" - persistent: "present" - when: - - module_type in ["loadable", "missing"] +- name: "Import insert module tasks" + ansible.builtin.include_tasks: insert_module.yml + when: | + insert_kernel_module_data | + check_cpu_constraints(insert_kernel_module_cpu_family, insert_kernel_module_cpu_model) | + bool diff --git a/roles/kernel_boot_options/tasks/main.yml b/roles/kernel_boot_options/tasks/main.yml index 38fe014..5d4cecd 100644 --- a/roles/kernel_boot_options/tasks/main.yml +++ b/roles/kernel_boot_options/tasks/main.yml @@ -1,50 +1,45 @@ --- -# This role verifies AMD settings in BIOS and possibly in grub - -- name: Check amd_pstate driver setting in sysfs value and provide fix message if incorrect +- name: Check amd_pstate driver setting in sysfs and GRUB + become: true block: - name: Read amd_pstate sysfs value ansible.builtin.command: cat /sys/devices/system/cpu/amd_pstate/status register: sysfs_amd_pstate_output changed_when: false - - name: Check if amd_pstatet sysfs value is correct - ansible.builtin.assert: - that: - - sysfs_amd_pstate_output.stdout == "passive" - fail_msg: 'The driver amd_pstate setting is not set correctly. Add to /etc/default/grub: GRUB_CMDLINE_LINUX_DEFAULT="amd_pstate=passive" and execute: update-grub; reboot' - success_msg: "The driver amd_pstate setting is set correctly." + - name: Set fact for amd_pstate sysfs check + ansible.builtin.set_fact: + amd_pstate_sysfs_correct: "{{ sysfs_amd_pstate_output.stdout == 'passive' }}" -- name: Check CPU CPPC setting using /proc/cpuinfo - block: - - name: Read cppc in /proc/cpuinfo - ansible.builtin.shell: | - set -o pipefail && grep cppc /proc/cpuinfo | uniq - args: - executable: /bin/bash - register: cpuinfo_cppc_output - changed_when: false + - name: Configure amd_pstate driver in GRUB + when: not amd_pstate_sysfs_correct + block: + - name: Check for correct amd_pstate parameter in GRUB + ansible.builtin.shell: grep -E '^{{ grub_cmdline }}=.*amd_pstate=passive' /etc/default/grub + register: grub_check + changed_when: false + failed_when: false - - name: Verify CPU cppc setting - ansible.builtin.assert: - that: - - cpuinfo_cppc_output.stdout | length > 0 - fail_msg: "BIOS CPPC setting is not correct. Enable CPPC in BIOS." - success_msg: "BIOS CPPC setting is correct." + - name: Add or modify amd_pstate parameter in GRUB + ansible.builtin.lineinfile: + path: /etc/default/grub + regexp: '^{{ grub_cmdline }}=' + line: '{{ grub_cmdline }}="amd_pstate=passive"' + state: present + become: true + when: grub_check.rc != 0 + register: add_parameter -- name: Check CPU Monitor and Mwait setting using /proc/cpuinfo - block: - - name: Read mwaitx in /proc/cpuinfo - ansible.builtin.shell: | - set -o pipefail && grep mwaitx /proc/cpuinfo | uniq - args: - executable: /bin/bash - register: cpuinfo_mwaitx_output - changed_when: false + - name: Update GRUB + ansible.builtin.command: update-grub + become: true + when: add_parameter.changed + changed_when: true + register: grub_updated - - name: Verify CPU mwaitx setting - ansible.builtin.assert: - that: - - cpuinfo_mwaitx_output.stdout | length > 0 - fail_msg: "BIOS Monitor and Mwait setting is not correct. Enable Monitor and Mwait in BIOS." - success_msg: "BIOS Monitor and Mwait setting is correct." + - name: Fail if reboot is required + ansible.builtin.fail: + msg: >- + The driver amd_pstate setting is not set correctly. Added: {{ grub_cmdline }}="amd_pstate=passive" + to /etc/default/grub and executed: update-grub; please execute reboot on host {{ ansible_hostname }} to apply changes + when: (grub_updated is defined and grub_updated.changed) or not amd_pstate_sysfs_correct diff --git a/roles/kernel_boot_options/vars/main.yml b/roles/kernel_boot_options/vars/main.yml new file mode 100644 index 0000000..ce870e1 --- /dev/null +++ b/roles/kernel_boot_options/vars/main.yml @@ -0,0 +1 @@ +grub_cmdline: "GRUB_CMDLINE_LINUX_DEFAULT" diff --git a/test_plugin.py b/test_plugin.py new file mode 100644 index 0000000..be71a85 --- /dev/null +++ b/test_plugin.py @@ -0,0 +1,12 @@ +import filter_plugins.insert_kernel_modules as cpu_filter +import yaml + +cpu_family = 0x06 +cpu_model = 0x86 + +with open('./group_vars/all.yml', 'r') as file: + data = yaml.safe_load(file) + +for module in data["kernel_modules"]: + result = cpu_filter.check_cpu_constraints(module, cpu_family, cpu_model) + print(f"Module {module['name']} cpu inclusion check: {result}") diff --git a/without-roles/build_missing_modules.yml b/without-roles/build_missing_modules.yml deleted file mode 100644 index 9bba1e7..0000000 --- a/without-roles/build_missing_modules.yml +++ /dev/null @@ -1,187 +0,0 @@ -- name: Build missing kernel modules - hosts: all - become: true - roles: - - common - - tasks: - - name: Verify if the missing modules file exists - ansible.builtin.stat: - path: "{{ missing_modules_path }}" - register: missing_modules_file_stat - delegate_to: localhost - - - name: Set missing_modules to an empty list if file is missing - ansible.builtin.set_fact: - missing_modules: [] - when: not missing_modules_file_stat.stat.exists - - - name: Exit playbook if the missing modules file is missing - ansible.builtin.debug: - msg: "Missing modules file is missing for {{ ansible_hostname }}. Skipping all tasks." - when: not missing_modules_file_stat.stat.exists - tags: skip - - - name: Load missing modules list - ansible.builtin.slurp: - src: "{{ missing_modules_path }}" - register: missing_modules_file - delegate_to: localhost - when: missing_modules_file_stat.stat.exists - - - name: Decode JSON content of missing modules - ansible.builtin.set_fact: - missing_modules: "{{ missing_modules_file['content'] | b64decode | from_json }}" - when: missing_modules_file_stat.stat.exists - - - name: Filter modules that are missing and have git_url defined - ansible.builtin.set_fact: - modules_to_build: "{{ kernel_modules | selectattr('name', 'in', missing_modules) | selectattr('git_url', 'defined') | list }}" - - - name: Display modules to be built - ansible.builtin.debug: - msg: "Modules to be built: {{ modules_to_build }}" - - - name: Ensure build directory exists - ansible.builtin.file: - path: "{{ build_dir }}" - state: directory - mode: '0755' - - - name: Ensure directory exists for git repository - ansible.builtin.file: - path: "{{ build_dir }}/{{ item.name }}" - state: directory - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - - - name: Check if directory is a git repository - ansible.builtin.stat: - path: "{{ build_dir }}/{{ item.name }}/.git" - register: git_repo_stat - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - - - name: Reset repository to last commit - ansible.builtin.command: - cmd: "git reset --hard HEAD" - args: - chdir: "{{ build_dir }}/{{ item.name }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - index_var: loop_index - when: item.name == "amd_energy" and git_repo_stat.results[loop_index].stat.exists - register: reset_results - failed_when: reset_results is failed or reset_results.rc != 0 - - - name: Clone module repositories - ansible.builtin.git: - repo: "{{ item.git_url }}" - dest: "{{ build_dir }}/{{ item.name }}" - update: yes - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - - - name: Check if dkms.conf exists and extract PACKAGE_VERSION - ansible.builtin.command: - cmd: "grep '^PACKAGE_VERSION=' {{ build_dir }}/{{ item.name }}/dkms.conf | cut -d '=' -f 2-" - args: - chdir: "{{ build_dir }}/{{ item.name }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - register: version_output - failed_when: false - - - name: Set module version fact - ansible.builtin.set_fact: - module_versions: "{{ module_versions | default({}) | combine({item.item.name: (version_output.results[item.index].stdout | default('1.0')).strip()}) }}" - loop: "{{ version_output.results }}" - loop_control: - label: "{{ item.item.name }}" - - - name: Debug module versions - ansible.builtin.debug: - msg: "Module versions: {{ module_versions }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - - - name: Check DKMS status for modules - ansible.builtin.command: - cmd: "dkms status {{ item.name }}/{{ module_versions[item.name] }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - register: dkms_status - failed_when: false - changed_when: false - - - name: Remove module if added but not installed - ansible.builtin.command: - cmd: "dkms remove {{ item.item.name }}/{{ module_versions[item.item.name] }} --all" - loop: "{{ dkms_status.results }}" - loop_control: - loop_var: item - when: - - item.rc == 0 - - "'added' in item.stdout" - - "'installed' not in item.stdout" - register: dkms_remove_results - - - name: Register module with DKMS - ansible.builtin.command: - cmd: "dkms add ../{{ item.name }}" - args: - chdir: "{{ build_dir }}/{{ item.name }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - register: dkms_add_results - ignore_errors: true - failed_when: "'already contains' not in dkms_add_results.stderr" - - - name: Patch amd_energy source code for kernel version 6.8 - ansible.builtin.command: - cmd: "patch -p1" - stdin: "{{ lookup('file', 'roles/common/files/amd_energy_kernel_version.patch') }}" - args: - chdir: "{{ build_dir }}/{{ item.name }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - when: item.name == "amd_energy" and ansible_kernel is version('6.8.0', 'ge') and ansible_kernel is not version('6.9.0', 'ge') - register: patch_results - failed_when: patch_results is failed or patch_results.rc != 0 - - - name: Build module with DKMS - ansible.builtin.command: - cmd: "dkms build -m {{ item.name }} -v {{ module_versions[item.name] | default('1.0') }}" - args: - chdir: "{{ build_dir }}/{{ item.name }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - register: dkms_build_results - failed_when: dkms_build_results.rc != 0 and 'Error!' in dkms_build_results.stderr - - - - name: Install module with DKMS - ansible.builtin.command: - cmd: "dkms install -m {{ item.name }} -v {{ module_versions[item.name] | default('1.0') }}" - loop: "{{ modules_to_build }}" - loop_control: - loop_var: item - register: dkms_install_results - failed_when: dkms_install_results.rc != 0 and 'Error!' in dkms_install_results.stderr - - - name: Clean up missing modules file - ansible.builtin.file: - path: "{{ missing_modules_path }}" - state: absent - delegate_to: localhost - when: clean_up_list diff --git a/without-roles/check_kernel_config.yml b/without-roles/check_kernel_config.yml deleted file mode 100644 index 7243279..0000000 --- a/without-roles/check_kernel_config.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- name: Check kernel config and out-scope built-in modules - hosts: all - gather_facts: true - roles: - - common - tasks: - - name: Filter modules that have a defined name - ansible.builtin.set_fact: - modules_with_name: "{{ kernel_modules | selectattr('name', 'defined') | list }}" - - - name: Exit playbook if no modules with a defined name are found - ansible.builtin.debug: - msg: "No valid kernel modules with a 'name' defined. Skipping all tasks." - when: modules_with_name | length == 0 - tags: skip - - - name: Gather system facts - ansible.builtin.setup: - when: modules_with_name | length > 0 - - - name: Check if kernel module is built into the kernel (CONFIG_X86_ and CONFIG_) - ansible.builtin.shell: | - # Check for the presence of the module in the kernel config - result=$(grep -E "CONFIG_X86_{{ item.name | upper | replace('_', '_') }}=y" /boot/config-$(uname -r) || echo "Not found") - echo "$result" - register: module_config - changed_when: false - loop: "{{ modules_with_name }}" - loop_control: - loop_var: item - when: modules_with_name | length > 0 - - - name: Initialize missing_modules variable - ansible.builtin.set_fact: - missing_modules: [] - when: modules_with_name | length > 0 - - - name: Set fact for modules not built into the kernel - ansible.builtin.set_fact: - missing_modules: "{{ missing_modules + [item.item.name] }}" - when: - - "'Not found' in item.stdout or 'is not set' in item.stdout" - - modules_with_name | length > 0 - loop: "{{ module_config.results }}" - no_log: true - - - name: Write missing kernel modules to a JSON file for each node - ansible.builtin.copy: - content: "{{ missing_modules | to_json }}" - dest: "{{ managed_modules_path }}" - mode: '0644' - delegate_to: localhost - when: modules_with_name | length > 0 diff --git a/without-roles/generate_inventory.sh b/without-roles/generate_inventory.sh deleted file mode 100755 index 643b973..0000000 --- a/without-roles/generate_inventory.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash - -# Define the output inventory file -INVENTORY_FILE="hosts.ini" - -# Timeout settings (in seconds) for checking cluster and SSH availability -CLUSTER_CHECK_TIMEOUT=10 -SSH_CHECK_TIMEOUT=5 - -# Function to check Kubernetes cluster availability -check_k8s_cluster() { - echo "Checking Kubernetes cluster availability..." - - # Check if the 'kubectl' command is available - if ! command -v kubectl &> /dev/null; then - echo "Error: 'kubectl' command not found. Please ensure Kubernetes CLI is installed." - exit 1 - fi - - # Check the cluster by running 'kubectl get nodes' with a timeout - if ! timeout $CLUSTER_CHECK_TIMEOUT kubectl get nodes &> /dev/null; then - echo "Error: Unable to reach the Kubernetes cluster or cluster is not available." - exit 1 - fi - - echo "Kubernetes cluster is available." -} - -# Function to retrieve worker nodes -get_worker_nodes() { - echo "Retrieving worker nodes from Kubernetes cluster..." - - # Get the list of worker nodes (excluding master/control plane nodes) - #WORKER_NODES=$(kubectl get nodes --selector='!node-role.kubernetes.io/control-plane' -o jsonpath='{range .items[*]}{.metadata.name} {.status.addresses[?(@.type=="InternalIP")].address}{"\n"}{end}') - WORKER_NODES=$(kubectl get nodes -o json |jq -r '.items[] |select([.metadata.labels |keys[] | contains("worker")] | any == true) | "\(.metadata.name) \(.status.addresses[] | select(.type=="InternalIP").address)"') - - - if [ -z "$WORKER_NODES" ]; then - echo "Error: No worker nodes found in the Kubernetes cluster." - exit 1 - fi - - echo "Found the following worker nodes:" - echo "$WORKER_NODES" -} - -# Function to verify SSH access to the worker node -check_ssh_access() { - local WORKER_IP=$1 - local USERNAME=$2 - - echo "Verifying SSH access to $WORKER_IP..." - - # Try SSH with a 5-second timeout for connection - if ! timeout $SSH_CHECK_TIMEOUT ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=$SSH_CHECK_TIMEOUT "$WORKER_IP" "exit" &> /dev/null; then - echo "Error: Unable to SSH into $WORKER_IP. Please ensure SSH access is set up properly for the user '$USERNAME'." - exit 1 - fi - - echo "SSH access to $WORKER_IP verified." -} - -# Function to generate the inventory file -generate_inventory() { - echo "Generating Ansible inventory file..." - - # Begin writing to the inventory file - echo "[workers]" > $INVENTORY_FILE - - # Loop through each worker node and gather the kernel version - echo "$WORKER_NODES" | while read -r WORKER_NAME WORKER_IP; do - # Verify SSH access to the worker node - check_ssh_access "$WORKER_IP" "$USER" - - # Retrieve the kernel version from the worker node using SSH - KERNEL_VERSION=$(ssh "$WORKER_IP" "uname -r") - - # If SSH fails, report the error and exit - if [ $? -ne 0 ]; then - echo "Error: Unable to SSH into $WORKER_NAME ($WORKER_IP). Please check the SSH connection." - exit 1 - fi - - # Write the worker node information to the inventory file - echo "$WORKER_NAME ansible_host=$WORKER_IP kernel_version=$KERNEL_VERSION" >> $INVENTORY_FILE - done - - echo "Inventory file '$INVENTORY_FILE' generated successfully." -} - -# Function to create host_vars directories for each worker node -create_host_vars_directories() { - echo "Creating host_vars directories for each worker node..." - - # Loop through each worker node - echo "$WORKER_NODES" | while read -r WORKER_NAME WORKER_IP; do - # Create the host_vars directory if it does not exist - if [ ! -d "host_vars" ]; then - mkdir host_vars - fi - - # Create the subdirectory for the worker node - if [ ! -d "host_vars/$WORKER_NAME" ]; then - mkdir "host_vars/$WORKER_NAME" - fi - - echo "Created host_vars directory for $WORKER_NAME" - done - - echo "host_vars directories created successfully." -} - -# Ensure script is run by a user who can SSH into the worker nodes -USER=$(whoami) - -# Step 1: Check Kubernetes cluster availability -check_k8s_cluster - -# Step 2: Retrieve the list of worker nodes -get_worker_nodes - -# Step 3: Generate the inventory file -generate_inventory - -# Step 4: Create host_vars directories for each worker node -create_host_vars_directories diff --git a/without-roles/group_vars/all.yml b/without-roles/group_vars/all.yml deleted file mode 120000 index 4827e4f..0000000 --- a/without-roles/group_vars/all.yml +++ /dev/null @@ -1 +0,0 @@ -../kernel_modules.yml \ No newline at end of file diff --git a/without-roles/hosts.ini b/without-roles/hosts.ini deleted file mode 100644 index 7b19cec..0000000 --- a/without-roles/hosts.ini +++ /dev/null @@ -1,3 +0,0 @@ -[workers] -epycpwr02 ansible_host=10.216.178.177 kernel_version=6.8.0-45-generic -epycpwr01 ansible_host=10.216.178.27 kernel_version=6.8.0-45-generic diff --git a/without-roles/kernel_modules.yml b/without-roles/kernel_modules.yml deleted file mode 100644 index e8f8f93..0000000 --- a/without-roles/kernel_modules.yml +++ /dev/null @@ -1,14 +0,0 @@ -# kernel_modules.yml - -kernel_modules: - - name: msr - - name: amd_pstate - - name: amd_hsmp - git_url: https://github.com/amd/amd_hsmp.git - - name: amd_uncore - - name: amd_energy - git_url: https://github.com/amd/amd_energy.git - - name: acpi_cpufreq - #- name: acpi_configfs - #- name: acpi_thermal_rel - diff --git a/without-roles/load_available_modules.yml b/without-roles/load_available_modules.yml deleted file mode 100644 index 8bcfce9..0000000 --- a/without-roles/load_available_modules.yml +++ /dev/null @@ -1,101 +0,0 @@ ---- -- name: Load available kernel modules - hosts: all - become: true - roles: - - common - - tasks: - - name: Verify if the managed modules file exists - ansible.builtin.stat: - path: "{{ managed_modules_path }}" - register: managed_modules_file_stat - delegate_to: localhost - - - name: Set managed_modules to empty list if file is missing - ansible.builtin.set_fact: - managed_modules: [] - when: not managed_modules_file_stat.stat.exists - - - name: Exit playbook if the managed modules file is missing - ansible.builtin.debug: - msg: "Managed modules file is missing for {{ ansible_hostname }}. Skipping all tasks." - when: not managed_modules_file_stat.stat.exists - tags: skip - - - name: Load the list of missing kernel modules - ansible.builtin.slurp: - src: "{{ managed_modules_path }}" - register: managed_modules_file - delegate_to: localhost - when: managed_modules_file_stat.stat.exists - - - name: Decode JSON content of managed modules - ansible.builtin.set_fact: - managed_modules: "{{ managed_modules_file['content'] | b64decode | from_json }}" - when: managed_modules_file_stat.stat.exists - - - name: Skip node if no missing modules are found - ansible.builtin.debug: - msg: "No missing modules for {{ ansible_hostname }}. Skipping." - when: managed_modules | length == 0 - changed_when: false - tags: skip - - - name: Initialize empty list for missing modules - ansible.builtin.set_fact: - missing_modules: [] - - - name: Verify if managed_modules is empty and skip if so - ansible.builtin.debug: - msg: "Modules to be loaded for {{ ansible_hostname }}: {{ managed_modules }}" - when: managed_modules | length > 0 - tags: skip - - - name: Check if each kernel module is available using modinfo - ansible.builtin.command: - cmd: "modinfo {{ item }}" - register: modinfo_status - ignore_errors: true - changed_when: false - loop: "{{ managed_modules }}" - loop_control: - loop_var: item - when: managed_modules | length > 0 - - - name: Collect missing kernel modules (those not available) - ansible.builtin.set_fact: - missing_modules: "{{ missing_modules + [item] }}" - when: modinfo_status.results | selectattr('item', 'equalto', item) | map(attribute='rc') | first != 0 - loop: "{{ managed_modules }}" - loop_control: - loop_var: item - - - name: Verify if any modules are missing and continue loading if found - ansible.builtin.debug: - msg: "Modules to be loaded: {{ managed_modules }}; Missing modules not available in the kernel: {{ missing_modules }}" - when: missing_modules | length > 0 - - - name: Load available kernel modules - community.general.modprobe: - name: "{{ item }}" - state: present - persistent: "present" - when: item not in missing_modules - loop: "{{ managed_modules }}" - loop_control: - loop_var: item - - - name: Write missing kernel modules to file - ansible.builtin.copy: - dest: "{{ missing_modules_path }}" - content: "{{ missing_modules | to_json }}" - mode: '0644' - delegate_to: localhost - - - name: Clean up not-loaded modules file - ansible.builtin.file: - path: "{{ managed_modules_path }}" - state: absent - delegate_to: localhost - when: clean_up_list diff --git a/without-roles/roles/common/files/amd_energy_kernel_version.patch b/without-roles/roles/common/files/amd_energy_kernel_version.patch deleted file mode 100644 index 5a027ca..0000000 --- a/without-roles/roles/common/files/amd_energy_kernel_version.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/amd_energy.c b/amd_energy.c -index 0c8dda1..da35c7b 100644 ---- a/amd_energy.c -+++ b/amd_energy.c -@@ -236,7 +236,7 @@ static int amd_create_sensor(struct device *dev, - * c->x86_max_cores is the linux count of physical cores - * total physical cores/ core per socket gives total number of sockets. - */ --#if LINUX_VERSION_CODE <= KERNEL_VERSION(6, 8, 0) -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(6, 9, 0) - struct cpuinfo_x86 *c = &boot_cpu_data; - sockets = cpus / c->x86_max_cores; - #else diff --git a/without-roles/roles/common/vars/main.yml b/without-roles/roles/common/vars/main.yml deleted file mode 100644 index 21e9893..0000000 --- a/without-roles/roles/common/vars/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -clean_up_list: false -managed_modules_path: "group_vars/{{ ansible_hostname }}-managed_modules.json" -missing_modules_path: "group_vars/{{ ansible_hostname }}-missing_modules.json" -build_dir: "/usr/local/src" diff --git a/without-roles/verify_tools.yml b/without-roles/verify_tools.yml deleted file mode 100644 index b74b825..0000000 --- a/without-roles/verify_tools.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- -- name: Check if git and dkms are installed - hosts: all - become: true - gather_facts: true - - tasks: - - name: Ensure git is installed - ansible.builtin.package: - name: git - state: present - register: git_installation - notify: - - Report git status - - - name: Ensure dkms is installed - ansible.builtin.package: - name: dkms - state: present - register: dkms_installation - notify: - - Report dkms status - - - name: Check kernel version - ansible.builtin.debug: - msg: "Kernel version {{ ansible_kernel }} is lower than 5.8 on {{ ansible_hostname }}" - when: ansible_kernel is version('5.8', '<') - - - name: Fail the playbook if kernel version is lower than 5.8 - ansible.builtin.fail: - msg: "Kernel version {{ ansible_kernel }} is lower than 5.8 on {{ ansible_hostname }}" - when: ansible_kernel is version('5.8', '<') - - handlers: - - name: Report git status - ansible.builtin.debug: - msg: > - {% if git_installation.changed %} - git was not installed on {{ ansible_hostname }} and has been installed now. - {% elif git_installation.failed %} - git installation failed on {{ ansible_hostname }}. - {% else %} - git was already installed on {{ ansible_hostname }}. - {% endif %} - - - name: Report dkms status - ansible.builtin.debug: - msg: > - {% if dkms_installation.changed %} - dkms was not installed on {{ ansible_hostname }} and has been installed now. - {% elif dkms_installation.failed %} - dkms installation failed on {{ ansible_hostname }}. - {% else %} - dkms was already installed on {{ ansible_hostname }}. - {% endif %} diff --git a/without-roles/worker_provisioning.yml b/without-roles/worker_provisioning.yml deleted file mode 100644 index ad77bea..0000000 --- a/without-roles/worker_provisioning.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -# worker_provisioning.yml - -- import_playbook: check_kernel_config.yml - -- import_playbook: load_available_modules.yml - -- import_playbook: verify_tools.yml - -- import_playbook: build_missing_modules.yml -