Martin Peřina has uploaded a new change for review. Change subject: kdump: Add kdump plugin ......................................................................
kdump: Add kdump plugin Adds kdump plugin to install kexec-tools package and configure fence_kdump to enable kdump detection for the host in engine. Change-Id: Idda48cb053c7e8747de5434c3681403f739c06b1 Bug-Url: https://bugzilla.redhat.com/1079821 Signed-off-by: Martin Perina <mper...@redhat.com> --- M configure.ac M po/POTFILES.in M src/ovirt_host_deploy/constants.py M src/plugins/ovirt-host-deploy/Makefile.am A src/plugins/ovirt-host-deploy/kdump/Makefile.am A src/plugins/ovirt-host-deploy/kdump/__init__.py A src/plugins/ovirt-host-deploy/kdump/packages.py 7 files changed, 470 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-host-deploy refs/changes/85/28385/1 diff --git a/configure.ac b/configure.ac index e01d4a0..2b43ea5 100644 --- a/configure.ac +++ b/configure.ac @@ -178,6 +178,7 @@ src/plugins/ovirt-host-deploy/node/Makefile src/plugins/ovirt-host-deploy/gluster/Makefile src/plugins/ovirt-host-deploy/openstack/Makefile + src/plugins/ovirt-host-deploy/kdump/Makefile src/java/Makefile src/java/pom.xml src/interface-3/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index 638005b..b9995c5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,6 +6,8 @@ ./src/plugins/ovirt-host-deploy/core/offlinepackager.py ./src/plugins/ovirt-host-deploy/gluster/__init__.py ./src/plugins/ovirt-host-deploy/gluster/packages.py +./src/plugins/ovirt-host-deploy/kdump/__init__.py +./src/plugins/ovirt-host-deploy/kdump/packages.py ./src/plugins/ovirt-host-deploy/node/detect.py ./src/plugins/ovirt-host-deploy/node/__init__.py ./src/plugins/ovirt-host-deploy/node/persist.py diff --git a/src/ovirt_host_deploy/constants.py b/src/ovirt_host_deploy/constants.py index be2e0b4..6f71311 100644 --- a/src/ovirt_host_deploy/constants.py +++ b/src/ovirt_host_deploy/constants.py @@ -61,6 +61,8 @@ '/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini' NRPE_CONFIG_FILE = '/etc/nagios/nrpe.cfg' + KDUMP_CONFIG_FILE = '/etc/kdump.conf' + @util.export class Defaults(object): @@ -88,6 +90,15 @@ @util.export @util.codegen +class KdumpEnv(object): + ENABLE = 'KDUMP/enable' + DESTINATION_ADDRESS = 'KDUMP/destinationAddress' + DESTINATION_PORT = 'KDUMP/destinationPort' + MESSAGE_INTERVAL = 'KDUMP/messageInterval' + + +@util.export +@util.codegen class VdsmEnv(object): VDSM_MINIMUM_VERSION = 'VDSM/vdsmMinimumVersion' CERTIFICATE_ENROLLMENT = 'VDSM/certificateEnrollment' diff --git a/src/plugins/ovirt-host-deploy/Makefile.am b/src/plugins/ovirt-host-deploy/Makefile.am index 6287580..5b3d47f 100644 --- a/src/plugins/ovirt-host-deploy/Makefile.am +++ b/src/plugins/ovirt-host-deploy/Makefile.am @@ -29,6 +29,7 @@ node \ gluster \ openstack \ + kdump \ $(NULL) install-data-local: diff --git a/src/plugins/ovirt-host-deploy/kdump/Makefile.am b/src/plugins/ovirt-host-deploy/kdump/Makefile.am new file mode 100644 index 0000000..3eb1375 --- /dev/null +++ b/src/plugins/ovirt-host-deploy/kdump/Makefile.am @@ -0,0 +1,38 @@ +# +# ovirt-host-deploy -- ovirt host deployer +# Copyright (C) 2012-2014 Red Hat, Inc. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +include $(top_srcdir)/build/python.inc + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in \ + $(NULL) + +mydir=$(ovirthostdeployplugindir)/ovirt-host-deploy/kdump +dist_my_PYTHON = \ + __init__.py \ + packages.py \ + $(NULL) + +clean-local: \ + python-clean \ + $(NULL) + +all-local: \ + python-syntax-check \ + $(NULL) diff --git a/src/plugins/ovirt-host-deploy/kdump/__init__.py b/src/plugins/ovirt-host-deploy/kdump/__init__.py new file mode 100644 index 0000000..c2e2180 --- /dev/null +++ b/src/plugins/ovirt-host-deploy/kdump/__init__.py @@ -0,0 +1,35 @@ +# +# ovirt-host-deploy -- ovirt host deployer +# Copyright (C) 2012-2014 Red Hat, Inc. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + + +"""fkdump plugin.""" + + +from otopi import util + + +from . import packages + + +@util.export +def createPlugins(context): + packages.Plugin(context=context) + + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/plugins/ovirt-host-deploy/kdump/packages.py b/src/plugins/ovirt-host-deploy/kdump/packages.py new file mode 100644 index 0000000..2cfb3ae --- /dev/null +++ b/src/plugins/ovirt-host-deploy/kdump/packages.py @@ -0,0 +1,382 @@ +# +# ovirt-host-deploy -- ovirt host deployer +# Copyright (C) 2012-2014 Red Hat, Inc. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + + +"""kdump packages plugin.""" + + +import gettext +import optparse +import types + +from distutils.version import LooseVersion + +_ = lambda m: gettext.dgettext(message=m, domain='ovirt-host-deploy') + + +from otopi import util +from otopi import plugin +from otopi import constants as otopicons +from otopi import filetransaction + + +from ovirt_host_deploy import constants as odeploycons + + +@util.export +class Plugin(plugin.PluginBase): + """Required packages installation. + + Environment: + KdumpEnv.ENABLE -- perform kdump detection configuration + + """ + + _KEXEC_TOOLS_RPM = 'kexec-tools' + + # min version of kexec-tools per distribution + _FC20_MIN_VER = '2.0.4-27.fc20' + _EL6_MIN_VER = '2.0.0-274.el6' + + # prefixes marking changes by oVirt + _OVIRT_BACKUP_NODES = '# oVirt backup: fence_kdump_nodes ' + _OVIRT_BACKUP_ARGS = '# oVirt backup: fence_kdump_args ' + + # fence_kdump options + _OPTION_NODES = 'fence_kdump_nodes ' + _OPTION_ARGS = 'fence_kdump_args ' + + # fence_kump_send arguments + _ARG_PORT = '-p' + _ARG_INTERVAL = '-i' + _ARG_COUNT = '-c' + _ARG_FAMILY = '-f' + _ARG_VERBOSE = '-v' + + # arguments default values + _DEFAULT_VALUES = { + _ARG_PORT: '7410', + _ARG_INTERVAL: '10', + _ARG_COUNT: '0', + _ARG_FAMILY: 'auto', + _ARG_VERBOSE: False, + } + + def __init__(self, context): + super(Plugin, self).__init__(context=context) + self._enabled = False + + def _strip_comments_from_line(self, line): + comment_start = line.find('#') + return line[:comment_start - 1] if comment_start != -1 else line + + def _configure_fence_kdump_nodes( + self, + engine_node, + nodes_line, + nodes_backup_line + ): + new_nodes = [] + + self.logger.debug("Existing nodes line '%s'", nodes_line) + self.logger.debug("Existing nodes backup line '%s'", nodes_backup_line) + + if nodes_line is None: + new_nodes.append(self._OPTION_NODES + engine_node + '\n') + + else: + stripped_nodes = self._strip_comments_from_line( + nodes_line.rstrip('\n') + ) + node_list = stripped_nodes[len(self._OPTION_NODES):].split(' ') + if engine_node in set(node_list): + # destination address is already part of existing nodes + if nodes_backup_line is not None: + new_nodes.append(nodes_backup_line) + new_nodes.append(nodes_line) + + else: + # create backup of existing settings + new_nodes.append(self._OVIRT_BACKUP_NODES + ' '.join(node_list)) + # add destination address to existing nodes + new_nodes.append( + stripped_nodes.rstrip('\n') + ' ' + engine_node + '\n' + ) + + self.logger.debug("New nodes lines: '%s'", new_nodes) + + return new_nodes + + def _parse_fence_kdump_args(self, args_line): + parser = optparse.OptionParser() + parser.add_option( + self._ARG_PORT, + '--ipport', + dest=self._ARG_PORT, + default=self._DEFAULT_VALUES[self._ARG_PORT], + ) + parser.add_option( + self._ARG_INTERVAL, + '--interval', + dest=self._ARG_INTERVAL, + default=self._DEFAULT_VALUES[self._ARG_INTERVAL], + ) + parser.add_option( + self._ARG_COUNT, + '--count', + dest=self._ARG_COUNT, + default=self._DEFAULT_VALUES[self._ARG_COUNT], + ) + parser.add_option( + self._ARG_FAMILY, + '--family', + dest=self._ARG_FAMILY, + ) + parser.add_option( + self._ARG_VERBOSE, + '--verbose', + dest=self._ARG_VERBOSE, + default=self._DEFAULT_VALUES[self._ARG_VERBOSE], + action='store_true', + ) + + (args, opts) = parser.parse_args(args_line.split(' ')) + self.logger.debug("Parsed args: '%s'", args) + self.logger.debug("Parsed opts: '%s'", opts) + + # remove unspecified args without default value from args_map + args_map = {} + for item in vars(args).items(): + if item[1] is not None: + args_map[item[0]] = item[1] + self.logger.debug("Reduced args map: '%s'", args_map) + + return args_map + + def _get_fence_kdump_args_line(self, args_map): + items = [] + for item in args_map.items(): + # don't include args with default values + if item[1] != self._DEFAULT_VALUES[item[0]]: + items.append(item[0]) + # don't include value for boolean options + if not isinstance(item[1], types.BooleanType): + items.append(item[1]) + + return self._OPTION_ARGS + ' '.join(items) + '\n' + + def _configure_fence_kdump_args( + self, + port, + interval, + count, + args_line, + args_backup_line + ): + new_args = [] + args_map = {} + + self.logger.debug("Existing args line '%s'", args_line) + self.logger.debug("Existing args backup line '%s'", args_backup_line) + + if args_line is None: + args_map[self._ARG_PORT] = port + args_map[self._ARG_INTERVAL] = interval + + else: + stripped_args = self._strip_comments_from_line( + args_line.rstrip('\n') + ) + args_map = self._parse_fence_kdump_args( + stripped_args[len(self._OPTION_ARGS):] + ) + + if ( + args_map[self._ARG_PORT] != port or + args_map[self._ARG_INTERVAL] != interval or + args_map[self._ARG_COUNT] != count + ): + # fence_kdump args need to be modified + new_args.append( + self._OVIRT_BACKUP_ARGS + + args_line[len(self._OPTION_ARGS):] + ) + + # udpate required args + args_map[self._ARG_PORT] = port + args_map[self._ARG_INTERVAL] = interval + args_map[self._ARG_COUNT] = count + + else: + if args_backup_line is not None: + new_args.append(args_backup_line) + + new_args_line = self._get_fence_kdump_args_line(args_map) + if new_args_line: + new_args.append(new_args_line) + + self.logger.debug("New args lines: '%s'", new_args) + return new_args + + def _update_kdump_conf(self, content): + new_content = [] + nodes_line = None + nodes_backup_line = None + args_line = None + args_backup_line = None + + for line in content: + if line.startswith(self._OPTION_NODES): + nodes_line = line + elif line.startswith(self._OVIRT_BACKUP_NODES): + args_backup_line = line + elif line.startswith(self._OPTION_ARGS): + args_line = line + elif line.startswith(self._OVIRT_BACKUP_ARGS): + args_backup_line = line + else: + new_content.append(line) + + # configure fence_kdump for oVirt + new_content.extend( + self._configure_fence_kdump_nodes( + engine_node=self.environment[ + odeploycons.KdumpEnv.DESTINATION_ADDRESS + ], + nodes_line=nodes_line, + nodes_backup_line=nodes_backup_line, + ) + ) + new_content.extend( + self._configure_fence_kdump_args( + port=str( + self.environment[ + odeploycons.KdumpEnv.DESTINATION_PORT + ] + ), + interval=str( + self.environment[ + odeploycons.KdumpEnv.MESSAGE_INTERVAL + ] + ), + count=self._DEFAULT_VALUES[self._ARG_COUNT], + args_line=args_line, + args_backup_line=args_backup_line, + ) + ) + + return new_content + + @plugin.event( + stage=plugin.Stages.STAGE_INIT, + ) + def _setup(self): + self.environment[odeploycons.KdumpEnv.ENABLE] = False + + @plugin.event( + stage=plugin.Stages.STAGE_VALIDATION, + condition=lambda self: ( + self.environment[odeploycons.KdumpEnv.ENABLE] + ), + ) + def _validation(self): + result = self.packager.queryPackages( + patterns=(self._KEXEC_TOOLS_RPM,), + ) + if not result: + raise RuntimeError( + _( + 'Cannot locate kexec-tools package' + ) + ) + entry = result[0] + self.logger.debug('Found kexec-tools %s', entry) + + cur_version = '%s-%s' % ( + entry['version'], + entry['release'], + ) + + if '.el6' in cur_version: + min_version = self._EL6_MIN_VER + elif '.fc20' in cur_version: + min_version = self._FC20_MIN_VER + else: + min_version = None + + if min_version is None: + raise RuntimeError( + _( + 'Kdump detection is currently supported only in Fedora 20 ' + 'and EL6 based distributions' + ) + ) + + if LooseVersion(min_version) > LooseVersion(cur_version): + raise RuntimeError( + _( + 'kexec-tools package is too old, need {minimum} found ' + '{version}' + ).format( + minimum=min_version, + version=cur_version, + ) + ) + self._enabled = True + + @plugin.event( + stage=plugin.Stages.STAGE_PACKAGES, + condition=lambda self: self._enabled, + ) + def _packages(self): + self.packager.installUpdate( + packages=(self._KEXEC_TOOLS_RPM,), + ) + + @plugin.event( + stage=plugin.Stages.STAGE_MISC, + condition=lambda self: self._enabled + ) + def _reconfigure(self): + with open(odeploycons.FileLocations.KDUMP_CONFIG_FILE, 'r') as f: + content = f.read().splitlines() + new_content = self._update_kdump_conf(content) + if content != new_content: + self.environment[ + otopicons.CoreEnv.MAIN_TRANSACTION + ].append( + filetransaction.FileTransaction( + name=odeploycons.FileLocations.KDUMP_CONFIG_FILE, + content=new_content, + modifiedList=self.environment[ + otopicons.CoreEnv.MODIFIED_FILES + ], + ) + ) + + @plugin.event( + stage=plugin.Stages.STAGE_CLOSEUP, + condition=lambda self: self._enabled + ) + def _closeup(self): + self.logger.info(_('Restarting kdump')) + for state in (False, True): + self.services.state('kdump', state) + +# vim: expandtab tabstop=4 shiftwidth=4 -- To view, visit http://gerrit.ovirt.org/28385 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idda48cb053c7e8747de5434c3681403f739c06b1 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-host-deploy Gerrit-Branch: master Gerrit-Owner: Martin Peřina <mper...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches