File: //proc/self/root/usr/lib/python2.7/site-packages/salt/modules/kmod.py
# -*- coding: utf-8 -*-
'''
Module to manage Linux kernel modules
'''
from __future__ import absolute_import, unicode_literals, print_function
# Import python libs
import os
import re
import logging
# Import salt libs
import salt.utils.files
import salt.utils.path
log = logging.getLogger(__name__)
def __virtual__():
'''
Only runs on Linux systems
'''
return __grains__['kernel'] == 'Linux'
def _new_mods(pre_mods, post_mods):
'''
Return a list of the new modules, pass an lsmod dict before running
modprobe and one after modprobe has run
'''
pre = set()
post = set()
for mod in pre_mods:
pre.add(mod['module'])
for mod in post_mods:
post.add(mod['module'])
return post - pre
def _rm_mods(pre_mods, post_mods):
'''
Return a list of the new modules, pass an lsmod dict before running
modprobe and one after modprobe has run
'''
pre = set()
post = set()
for mod in pre_mods:
pre.add(mod['module'])
for mod in post_mods:
post.add(mod['module'])
return pre - post
def _get_modules_conf():
'''
Return location of modules config file.
Default: /etc/modules
'''
if 'systemd' in __grains__:
return '/etc/modules-load.d/salt_managed.conf'
return '/etc/modules'
def _strip_module_name(mod):
'''
Return module name and strip configuration. It is possible insert modules
in this format:
bonding mode=4 miimon=1000
This method return only 'bonding'
'''
if mod.strip() == '':
return False
return mod.split()[0]
def _set_persistent_module(mod):
'''
Add module to configuration file to make it persistent. If module is
commented uncomment it.
'''
conf = _get_modules_conf()
if not os.path.exists(conf):
__salt__['file.touch'](conf)
mod_name = _strip_module_name(mod)
if not mod_name or mod_name in mod_list(True) or mod_name \
not in available():
return set()
escape_mod = re.escape(mod)
# If module is commented only uncomment it
if __salt__['file.search'](conf,
'^#[\t ]*{0}[\t ]*$'.format(escape_mod),
multiline=True):
__salt__['file.uncomment'](conf, escape_mod)
else:
__salt__['file.append'](conf, mod)
return set([mod_name])
def _remove_persistent_module(mod, comment):
'''
Remove module from configuration file. If comment is true only comment line
where module is.
'''
conf = _get_modules_conf()
mod_name = _strip_module_name(mod)
if not mod_name or mod_name not in mod_list(True):
return set()
escape_mod = re.escape(mod)
if comment:
__salt__['file.comment'](conf, '^[\t ]*{0}[\t ]?'.format(escape_mod))
else:
__salt__['file.sed'](conf, '^[\t ]*{0}[\t ]?'.format(escape_mod), '')
return set([mod_name])
def available():
'''
Return a list of all available kernel modules
CLI Example:
.. code-block:: bash
salt '*' kmod.available
'''
ret = []
mod_dir = os.path.join('/lib/modules/', os.uname()[2])
built_in_file = os.path.join(mod_dir, 'modules.builtin')
if os.path.exists(built_in_file):
with salt.utils.files.fopen(built_in_file, 'r') as f:
for line in f:
# Strip .ko from the basename
ret.append(os.path.basename(line)[:-4])
for root, dirs, files in salt.utils.path.os_walk(mod_dir):
for fn_ in files:
if '.ko' in fn_:
ret.append(fn_[:fn_.index('.ko')].replace('-', '_'))
if 'Arch' in __grains__['os_family']:
# Sadly this path is relative to kernel major version but ignores minor version
mod_dir_arch = '/lib/modules/extramodules-' + os.uname()[2][0:3] + '-ARCH'
for root, dirs, files in salt.utils.path.os_walk(mod_dir_arch):
for fn_ in files:
if '.ko' in fn_:
ret.append(fn_[:fn_.index('.ko')].replace('-', '_'))
return sorted(list(ret))
def check_available(mod):
'''
Check to see if the specified kernel module is available
CLI Example:
.. code-block:: bash
salt '*' kmod.check_available kvm
'''
return mod in available()
def lsmod():
'''
Return a dict containing information about currently loaded modules
CLI Example:
.. code-block:: bash
salt '*' kmod.lsmod
'''
ret = []
for line in __salt__['cmd.run']('lsmod').splitlines():
comps = line.split()
if not len(comps) > 2:
continue
if comps[0] == 'Module':
continue
mdat = {
'size': comps[1],
'module': comps[0],
'depcount': comps[2],
}
if len(comps) > 3:
mdat['deps'] = comps[3].split(',')
else:
mdat['deps'] = []
ret.append(mdat)
return ret
def mod_list(only_persist=False):
'''
Return a list of the loaded module names
only_persist
Only return the list of loaded persistent modules
CLI Example:
.. code-block:: bash
salt '*' kmod.mod_list
'''
mods = set()
if only_persist:
conf = _get_modules_conf()
if os.path.exists(conf):
try:
with salt.utils.files.fopen(conf, 'r') as modules_file:
for line in modules_file:
line = line.strip()
mod_name = _strip_module_name(line)
if not line.startswith('#') and mod_name:
mods.add(mod_name)
except IOError:
log.error('kmod module could not open modules file at %s', conf)
else:
for mod in lsmod():
mods.add(mod['module'])
return sorted(list(mods))
def load(mod, persist=False):
'''
Load the specified kernel module
mod
Name of module to add
persist
Write module to /etc/modules to make it load on system reboot
CLI Example:
.. code-block:: bash
salt '*' kmod.load kvm
'''
pre_mods = lsmod()
res = __salt__['cmd.run_all']('modprobe {0}'.format(mod), python_shell=False)
if res['retcode'] == 0:
post_mods = lsmod()
mods = _new_mods(pre_mods, post_mods)
persist_mods = set()
if persist:
persist_mods = _set_persistent_module(mod)
return sorted(list(mods | persist_mods))
else:
return 'Error loading module {0}: {1}'.format(mod, res['stderr'])
def is_loaded(mod):
'''
Check to see if the specified kernel module is loaded
CLI Example:
.. code-block:: bash
salt '*' kmod.is_loaded kvm
'''
return mod in mod_list()
def remove(mod, persist=False, comment=True):
'''
Remove the specified kernel module
mod
Name of module to remove
persist
Also remove module from /etc/modules
comment
If persist is set don't remove line from /etc/modules but only
comment it
CLI Example:
.. code-block:: bash
salt '*' kmod.remove kvm
'''
pre_mods = lsmod()
res = __salt__['cmd.run_all']('rmmod {0}'.format(mod), python_shell=False)
if res['retcode'] == 0:
post_mods = lsmod()
mods = _rm_mods(pre_mods, post_mods)
persist_mods = set()
if persist:
persist_mods = _remove_persistent_module(mod, comment)
return sorted(list(mods | persist_mods))
else:
return 'Error removing module {0}: {1}'.format(mod, res['stderr'])