diff --git a/kdump-anaconda-addon/Makefile b/kdump-anaconda-addon/Makefile new file mode 100644 index 0000000..affd8f5 --- /dev/null +++ b/kdump-anaconda-addon/Makefile @@ -0,0 +1,81 @@ +NAME = kdump-anaconda-addon + +VERSION = 0.1 + +ADDON = com_redhat_kdump +TESTS = test + +FILES = $(ADDON) \ + po \ + Makefile \ + README + +EXCLUDES = \ + *~ \ + *.pyc + +all: + @echo "usage: make dist" + @echo " make test" + @echo " make install" + @echo " make uninstall" + +DISTNAME = $(NAME)-$(VERSION) +ADDONDIR = /usr/share/anaconda/addons/ +DISTBALL = $(DISTNAME).tar.gz +NUM_PROCS = $$(getconf _NPROCESSORS_ONLN) + +install: + mkdir -p $(DESTDIR)$(ADDONDIR) + cp -rv $(ADDON) $(DESTDIR)$(ADDONDIR) + make install-po-files + +uninstall: + rm -rfv $(DESTDIR)$(ADDONDIR) + +dist: + rm -rf $(DISTNAME) + mkdir -p $(DISTNAME) + @if test -d ".git"; \ + then \ + echo Creating ChangeLog && \ + ( cd "$(top_srcdir)" && \ + echo '# Generate automatically. Do not edit.'; echo; \ + git log --stat --date=short ) > ChangeLog.tmp \ + && mv -f ChangeLog.tmp $(DISTNAME)/ChangeLog \ + || ( rm -f ChangeLog.tmp ; \ + echo Failed to generate ChangeLog >&2 ); \ + else \ + echo A git clone is required to generate a ChangeLog >&2; \ + fi + for file in $(FILES); do \ + cp -rpv $$file $(DISTNAME)/$$file; \ + done + for excl in $(EXCLUDES); do \ + find $(DISTNAME) -name "$$excl" -delete; \ + done + tar -czvf ../$(DISTBALL) $(DISTNAME) + rm -rf $(DISTNAME) + +potfile: + $(MAKE) DESTDIR=$(DESTDIR) -C po potfile + +po-pull: + tx pull -a --disable-overwrite + +install-po-files: + $(MAKE) -C po install + +test: + @echo "***Running pylint checks***" + @find . -name '*.py' -print|xargs -n1 --max-procs=$(NUM_PROCS) pylint -E 2> /dev/null + @echo "[ OK ]" + @echo "***Running unittests checks***" + @PYTHONPATH=. nosetests --processes=-1 -vw tests/ + +runpylint: + @find . -name '*.py' -print|xargs -n1 --max-procs=$(NUM_PROCS) pylint -E 2> /dev/null + @echo "[ OK ]" + +unittest: + PYTHONPATH=. nosetests --processes=-1 -vw tests/ diff --git a/kdump-anaconda-addon/README b/kdump-anaconda-addon/README new file mode 100644 index 0000000..50a7c97 --- /dev/null +++ b/kdump-anaconda-addon/README @@ -0,0 +1,29 @@ +This is an anaconda addon for configuring kdump. To use, copy the +com_redhat_kdump directory into /usr/share/anaconda/addons on your +installation media. + +The syntax of the addon's kickstart section is: + +%addon com_redhat_kdump (--enable|--disable) --reserve-mb=("auto"|) +%end + +Note that support for arguments on the %addon line was added in +anaconda-21.23. See anaconda commit 3a512e4f9e15977f0ce2d0bbe39e841b881398f3, +https://bugzilla.redhat.com/show_bug.cgi?id=1065674 + +How to test the kdump-anaconda-addon? +You can provide an updates image in the kernel boot arguments as updates=, +and the contents will be added to the stage2 filesystem. +https://fedoraproject.org/wiki/Anaconda/Updates has more details, but usually +the easiest is to make it available via HTTP or FTP and provide a url to updates=. + +The file is a gzip-compressed cpio archive, and the files need to be put into +stage2 in /usr/share/anaconda/addons, so something like this will work to create +an updates.img: + +mkdir -p updates/usr/share/anaconda/addons +cp -r com_redhat_kdump updates/usr/share/anaconda/addons/ +( cd updates; find . | cpio -oc | gzip -c9 ) > updates.img + +then you can upload the updates.img to some http or ftp server so the anaconda +can get it by boot parameter as updates=http://some.website.com/path/to/updates.img. diff --git a/kdump-anaconda-addon/com_redhat_kdump/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/common.py b/kdump-anaconda-addon/com_redhat_kdump/common.py new file mode 100644 index 0000000..cd37131 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/common.py @@ -0,0 +1,88 @@ +# Kdump configuration common methods +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# +import os +__all__ = ["getReservedMemory", "getTotalMemory", "getMemoryBounds", "getOS"] + +from pyanaconda.isys import total_memory +from pyanaconda.flags import flags +from com_redhat_kdump.constants import OS_RELEASE + +_reservedMemory = None +def getReservedMemory(): + """Return the amount of memory currently reserved for kdump in MB.""" + global _reservedMemory + + # Check if the value has already been read + if _reservedMemory is not None: + return _reservedMemory + + try: + with open("/sys/kernel/kexec_crash_size", "r") as fobj: + _reservedMemory = int(fobj.read()) / (1024*1024) + return _reservedMemory + except (ValueError, IOError): + return 0 + +def getTotalMemory(): + """Return the total amount of system memory in MB + + This is the amount reported by /proc/meminfo plus the aount + currently reserved for kdump. + """ + + # total_memory return memory in KB, convert to MB + availMem = total_memory() / 1024 + + return availMem + getReservedMemory() + +def getMemoryBounds(): + """Return a tuple of (lower, upper, step) for kdump reservation limits. + + If there is not enough memory available to use kdump, both lower and + upper will be 0. + """ + + totalMemory = getTotalMemory() + + if flags.targetarch == 'ppc64': + lowerBound = 256 + minUsable = 1024 + step = 1 + else: + lowerBound = 128 + minUsable = 256 + step = 1 + + upperBound = (totalMemory - minUsable) - (totalMemory % step) + + if upperBound < lowerBound: + upperBound = lowerBound = 0 + + return (lowerBound, upperBound, step) + +def getOS(): + with open(os.path.normpath(OS_RELEASE), "r") as fobj: + line = fobj.readline() + + if not "Fedora" in line: + return "redhat" + else: + return "fedora" diff --git a/kdump-anaconda-addon/com_redhat_kdump/constants.py b/kdump-anaconda-addon/com_redhat_kdump/constants.py new file mode 100644 index 0000000..aab9537 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/constants.py @@ -0,0 +1,23 @@ +# Kdump configuration constants +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# + +# The location of the kdump config file +OS_RELEASE = "/etc/os-release" diff --git a/kdump-anaconda-addon/com_redhat_kdump/gui/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/gui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/RHEL.glade b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/RHEL.glade new file mode 100644 index 0000000..272f745 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/RHEL.glade @@ -0,0 +1,274 @@ + + + + + + + filler + False + filler + KDUMP + + + + False + vertical + 6 + + + True + False + + + False + 6 + 6 + 6 + + + + + False + False + 0 + + + + + False + 0 + + + False + vertical + 6 + + + True + False + 10 + vertical + 10 + + + True + False + 0 + Kdump is a kernel crash dumping mechanism. In the event of a system crash, kdump will capture information from your system that can be invaluable in determining the cause of the crash. Note that kdump does require reserving a portion of system memory that will be unavailable for other uses. + True + + + False + True + 0 + + + + + True + False + + + _Enable kdump? + True + True + False + True + 0 + 0 + True + + + + 0 + 0 + 3 + 1 + + + + + True + False + 0 + Kdump Memory Reservation: + + + 0 + 1 + 1 + 1 + + + + + _Automatic + True + True + False + True + 0 + True + True + + + + 1 + 1 + 1 + 1 + + + + + _Manual + True + True + False + True + 0 + True + True + autoButton + + + + 2 + 1 + 1 + 1 + + + + + True + False + 0 + Memory To Be _Reserved (MB): + True + toBeReservedSpin + + + 0 + 3 + 1 + 1 + + + + + True + True + digits + if-valid + + + + 1 + 3 + 1 + 1 + + + + + True + False + 0 + Total System Memory (MB): + + + 0 + 4 + 1 + 1 + + + + + True + False + 0 + + + 1 + 4 + 1 + 1 + + + + + True + False + 0 + Usable System Memory (MB): + + + 0 + 5 + 1 + 1 + + + + + True + False + 0 + + + 1 + 5 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + + + True + True + 1 + + + + + + + + + diff --git a/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/fedora.glade b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/fedora.glade new file mode 100644 index 0000000..55442a8 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/fedora.glade @@ -0,0 +1,218 @@ + + + + + + + filler + False + filler + KDUMP + + + + False + vertical + 6 + + + True + False + + + False + 6 + 6 + 6 + + + + + False + False + 0 + + + + + False + 0 + + + False + vertical + 6 + + + True + False + 10 + vertical + 10 + + + True + False + 0 + Kdump is a kernel crash dumping mechanism. In the event of a system crash, kdump will capture information from your system that can be invaluable in determining the cause of the crash. Note that kdump does require reserving a portion of system memory that will be unavailable for other uses. + True + + + False + True + 0 + + + + + True + False + + + True + False + 0 + Memory To Be _Reserved (MB): + True + toBeReservedSpin + + + 0 + 3 + 1 + 1 + + + + + True + True + digits + if-valid + + + + 1 + 3 + 1 + 1 + + + + + True + False + 0 + Total System Memory (MB): + + + 0 + 4 + 1 + 1 + + + + + True + False + 0 + + + 1 + 4 + 1 + 1 + + + + + True + False + 0 + Usable System Memory (MB): + + + 0 + 5 + 1 + 1 + + + + + True + False + 0 + + + 1 + 5 + 1 + 1 + + + + + _Enable kdump? + True + True + False + True + 0 + 0 + True + + + + 0 + 0 + 1 + 1 + + + + + + + + + + + + + + + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + + + True + True + 1 + + + + + + + + + diff --git a/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/kdump.py b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/kdump.py new file mode 100644 index 0000000..cec6b06 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/gui/spokes/kdump.py @@ -0,0 +1,192 @@ +# Kdump anaconda configuration +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# + +"""Kdump anaconda GUI configuration""" + +from gi.repository import Gtk + +from pyanaconda.ui.gui.categories.system import SystemCategory +from pyanaconda.ui.gui.spokes import NormalSpoke +from pyanaconda.ui.gui.utils import fancy_set_sensitive + +from com_redhat_kdump.i18n import _, N_ +from com_redhat_kdump.common import getReservedMemory, getTotalMemory, getMemoryBounds, getOS + +__all__ = ["KdumpSpoke"] + +class KdumpSpoke(NormalSpoke): + """Kdump configuration spoke""" + + builderObjects = ["KdumpWindow", "advancedConfigBuffer"] + mainWidgetName = "KdumpWindow" + uiFile = "RHEL.glade" + translationDomain = "kdump-anaconda-addon" + + icon = "computer-fail-symbolic" + title = N_("KDUMP") + category = SystemCategory + OS = "redhat" + def __init__(self, data, storage, payload, instclass): + KdumpSpoke.OS = getOS() + if KdumpSpoke.OS == "fedora": + KdumpSpoke.uiFile = "fedora.glade" + NormalSpoke.__init__(self, data, storage, payload, instclass) + self._reserveMem = 0 + + def initialize(self): + NormalSpoke.initialize(self) + self._enableButton = self.builder.get_object("enableKdumpCheck") + KdumpSpoke.OS = getOS() + if KdumpSpoke.OS == "redhat": + self._reservationTypeLabel = self.builder.get_object("reservationTypeLabel") + self._autoButton = self.builder.get_object("autoButton") + self._manualButton = self.builder.get_object("manualButton") + + self._toBeReservedLabel = self.builder.get_object("toBeReservedLabel") + self._toBeReservedSpin = self.builder.get_object("toBeReservedSpin") + self._totalMemLabel = self.builder.get_object("totalMemLabel") + self._totalMemMB = self.builder.get_object("totalMemMB") + self._usableMemLabel = self.builder.get_object("usableMemLabel") + self._usableMemMB = self.builder.get_object("usableMemMB") + + # Set an initial value and adjustment on the spin button + lower, upper, step = getMemoryBounds() + adjustment = Gtk.Adjustment(lower, lower, upper, step, step, 0) + self._toBeReservedSpin.set_adjustment(adjustment) + self._toBeReservedSpin.set_value(lower) + + def refresh(self): + # If a reserve amount is requested, set it in the spin button + if self.data.addons.com_redhat_kdump.reserveMB != "auto": + # Strip the trailing 'M' + reserveMB = self.data.addons.com_redhat_kdump.reserveMB + if reserveMB and reserveMB[-1] == 'M': + reserveMB = reserveMB[:-1] + if reserveMB: + self._toBeReservedSpin.set_value(int(reserveMB)) + + # Set the various labels. Use the spin button signal handler to set the + # usable memory label once the other two have been set. + self._totalMemMB.set_text("%d" % getTotalMemory()) + self._toBeReservedSpin.emit("value-changed") + + # Set the states on the toggle buttons and let the signal handlers set + # the sensitivities on the related widgets. Set the radio button first, + # since the radio buttons' bailiwick is a subset of that of the + # enable/disable checkbox. + if KdumpSpoke.OS == "redhat": + if self.data.addons.com_redhat_kdump.reserveMB == "auto": + self._autoButton.set_active(True) + self._manualButton.set_active(False) + else: + self._autoButton.set_active(False) + self._manualButton.set_active(True) + + if self.data.addons.com_redhat_kdump.enabled: + self._enableButton.set_active(True) + else: + self._enableButton.set_active(False) + + # Force a toggled signal on the button in case it's state has not changed + self._enableButton.emit("toggled") + + def apply(self): + # Copy the GUI state into the AddonData object + self.data.addons.com_redhat_kdump.enabled = self._enableButton.get_active() + + if KdumpSpoke.OS == "redhat" and self._autoButton.get_active(): + reserveMem = "auto" + else: + reserveMem = "%dM" % self._toBeReservedSpin.get_value_as_int() + + self.data.addons.com_redhat_kdump.reserveMB = reserveMem + + + @property + def ready(self): + return True + + @property + def completed(self): + # Always treat as completed + return True + + @property + def mandatory(self): + return False + + @property + def status(self): + if self.data.addons.com_redhat_kdump.enabled: + state = _("Kdump is enabled") + else: + state = _("Kdump is disabled") + + return state + + # SIGNAL HANDLERS + + def on_enable_kdump_toggled(self, checkbutton, user_data=None): + status = checkbutton.get_active() + + # If disabling, set everything to insensitve. Otherwise, only set the radio + # button and currently reserved widgets to sensitive and then fake a + # toggle event on the radio button to set the state on the reserve + # amount spin button and total/usable mem display. + if KdumpSpoke.OS == "redhat": + self._autoButton.set_sensitive(status) + self._manualButton.set_sensitive(status) + self._reservationTypeLabel.set_sensitive(status) + + if not status: + fancy_set_sensitive(self._toBeReservedSpin, status) + self._totalMemLabel.set_sensitive(status) + self._totalMemMB.set_sensitive(status) + self._usableMemLabel.set_sensitive(status) + self._usableMemMB.set_sensitive(status) + elif KdumpSpoke.OS == "redhat": + self._autoButton.emit("toggled") + else: + fancy_set_sensitive(self._toBeReservedSpin, True) + self._totalMemLabel.set_sensitive(True) + self._totalMemMB.set_sensitive(True) + self._usableMemLabel.set_sensitive(True) + self._usableMemMB.set_sensitive(True) + + def on_reservation_toggled(self, radiobutton, user_data=None): + status = self._manualButton.get_active() + + # If setting to auto, disable the manual config spinner and + # the total/usable memory labels + fancy_set_sensitive(self._toBeReservedSpin, status) + self._totalMemLabel.set_sensitive(status) + self._totalMemMB.set_sensitive(status) + self._usableMemLabel.set_sensitive(status) + self._usableMemMB.set_sensitive(status) + + def on_reserved_value_changed(self, spinbutton, user_data=None): + reserveMem = spinbutton.get_value_as_int() + totalMemText = self._totalMemMB.get_text() + + # If no total memory is available yet, do nothing + if totalMemText: + totalMem = int(self._totalMemMB.get_text()) + self._usableMemMB.set_text("%d" % (totalMem - reserveMem)) diff --git a/kdump-anaconda-addon/com_redhat_kdump/i18n.py b/kdump-anaconda-addon/com_redhat_kdump/i18n.py new file mode 100644 index 0000000..a8cd27a --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/i18n.py @@ -0,0 +1,27 @@ +# Kdump configuration translation functions +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# + +__all__ = ["_", "N_"] + +import gettext + +_ = lambda x: gettext.ldgettext("kdump-anaconda-addon", x) +N_ = lambda x: x diff --git a/kdump-anaconda-addon/com_redhat_kdump/ks/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/ks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/ks/kdump.py b/kdump-anaconda-addon/com_redhat_kdump/ks/kdump.py new file mode 100644 index 0000000..b4b346c --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/ks/kdump.py @@ -0,0 +1,128 @@ +# Kdump anaconda configuration +# +# Copyright (C) 2014 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# + +import os + +from pyanaconda.addons import AddonData +from pyanaconda.constants import ROOT_PATH +from pyanaconda import iutil + +from pykickstart.options import KSOptionParser +from pykickstart.errors import KickstartParseError, formatErrorMsg +from com_redhat_kdump.common import getOS, getMemoryBounds +from com_redhat_kdump.i18n import _ + +__all__ = ["KdumpData"] + +class KdumpData(AddonData): + """Addon data for the kdump configuration""" + + def __init__(self, name): + AddonData.__init__(self, name) + + self.enabled = True + self.reserveMB = "auto" + if getOS() == "fedora": + self.enabled = False + lower, upper, step = getMemoryBounds() + self.reserveMB = "%d" % lower + + def __str__(self): + addon_str = "%%addon %s" % self.name + + if self.enabled: + addon_str += " --enable" + else: + addon_str += " --disable" + + if self.reserveMB: + addon_str += " --reserve-mb='%s'" % self.reserveMB + + addon_str += "\n%s\n%%end\n" % self.content.strip() + + return addon_str + + def setup(self, storage, ksdata, instClass): + # Clear any existing crashkernel bootloader arguments + if ksdata.bootloader.appendLine: + ksdata.bootloader.appendLine = ' '.join( + (arg for arg in ksdata.bootloader.appendLine.split() \ + if not arg.startswith('crashkernel='))) + + # Copy our reserved amount to the bootloader arguments + if self.enabled: + # Ensure that the amount is "auto" or an amount in MB + if self.reserveMB != "auto" and self.reserveMB[-1] != 'M': + self.reserveMB += 'M' + ksdata.bootloader.appendLine += ' crashkernel=%s' % self.reserveMB + + # Do the same thing with the storage.bootloader.boot_args set + if storage.bootloader.boot_args: + crashargs = [arg for arg in storage.bootloader.boot_args \ + if arg.startswith('crashkernel=')] + storage.bootloader.boot_args -= set(crashargs) + + if self.enabled: + storage.bootloader.boot_args.add('crashkernel=%s' % self.reserveMB) + ksdata.packages.packageList.append("kexec-tools") + + def handle_header(self, lineno, args): + op = KSOptionParser() + op.add_option("--enable", action="store_true", default=True, + dest="enabled", help="Enable kdump") + op.add_option("--disable", action="store_false", + dest="enabled", help="Disable kdump") + op.add_option("--reserve-mb", type="string", dest="reserveMB", + default="auto", help="Amount of memory in MB to reserve for kdump, or auto") + + (opts, extra) = op.parse_args(args=args, lineno=lineno) + + # Reject any additional arguments + if extra: + AddonData.handle_header(self, lineno, extra) + + # Validate the reserve-mb argument + if opts.reserveMB != "auto": + # Allow a final 'M' for consistency with the crashkernel kernel + # parameter. Strip it if found. + if opts.reserveMB and opts.reserveMB[-1] == 'M': + opts.reserveMB = opts.reserveMB[:-1] + + try: + _test = int(opts.reserveMB) + except ValueError: + msg = _("Invalid value %s for --reserve-mb") % opts.reserveMB + if lineno != None: + raise KickstartParseError(formatErrorMsg(lineno, msg=msg)) + else: + raise KickstartParseError(msg) + + # Store the parsed arguments + self.enabled = opts.enabled + self.reserveMB =opts.reserveMB + + def execute(self, storage, ksdata, instClass, users): + if self.enabled: + action = "enable" + else: + action = "disable" + + iutil.execWithRedirect("systemctl", [action, "kdump.service"], root=ROOT_PATH) diff --git a/kdump-anaconda-addon/com_redhat_kdump/tui/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/tui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/tui/spokes/__init__.py b/kdump-anaconda-addon/com_redhat_kdump/tui/spokes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kdump-anaconda-addon/com_redhat_kdump/tui/spokes/kdump.py b/kdump-anaconda-addon/com_redhat_kdump/tui/spokes/kdump.py new file mode 100644 index 0000000..23e8040 --- /dev/null +++ b/kdump-anaconda-addon/com_redhat_kdump/tui/spokes/kdump.py @@ -0,0 +1,87 @@ +# Kdump anaconda configuration +# +# Copyright (C) 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): David Shea +# + +"""Kdump anaconda TUI configuration""" + +import re + +from pyanaconda.ui.tui.spokes import EditTUISpoke +from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry +from com_redhat_kdump.common import getOS, getMemoryBounds +from com_redhat_kdump.i18n import N_, _ + +__all__ = ["KdumpSpoke"] + +class _re: + def __init__(self, patten, low, up): + self.re = re.compile(patten) + self.low = low + self.up = up + + def match(self, key): + if self.re.match(key): + if key == "auto": + return True + if key[-1] == 'M': + key = key[:-1] + key = int(key) + if key <= self.up and key >= self.low : + return True + return False + +lower, upper ,step = getMemoryBounds() +# Allow either "auto" or a string of digits optionally followed by 'M' +RESERVE_VALID = _re(r'^((auto)|(\d+M?))$', lower, upper) +FEDORA_RESERVE_VALID = _re(r'^(\d+M?)$', lower, upper) + +class KdumpSpoke(EditTUISpoke): + title = N_("Kdump") + category = "system" + + edit_fields = [ + Entry("Enable kdump", "enabled", EditTUISpoke.CHECK, True), + Entry("Reserve amount", "reserveMB", RESERVE_VALID, lambda self,args: args.enabled) + ] + + def __init__(self, app, data, storage, payload, instclass): + if getOS() == "fedora": + KdumpSpoke.edit_fields = [ + Entry("Enable kdump", "enabled", EditTUISpoke.CHECK, True), + Entry("Reserve amount", "reserveMB", FEDORA_RESERVE_VALID, lambda self,args: args.enabled) + ] + + EditTUISpoke.__init__(self, app, data, storage, payload, instclass) + self.args = self.data.addons.com_redhat_kdump + + def apply(self): + pass + + @property + def completed(self): + return True + + @property + def status(self): + if self.args.enabled: + state = _("Kdump is enabled") + else: + state = _("Kdump is disabled") + return state diff --git a/kdump-anaconda-addon/po/Makefile b/kdump-anaconda-addon/po/Makefile new file mode 100644 index 0000000..b82cca4 --- /dev/null +++ b/kdump-anaconda-addon/po/Makefile @@ -0,0 +1,75 @@ +# +# Makefile for the PO files (translation) catalog +# +# $Id$ + +TOP = ../.. + +# What is this package? +NLSPACKAGE = kdump-anaconda-addon +POTFILE = $(NLSPACKAGE).pot +INSTALL = /usr/bin/install -c +INSTALL_DATA = $(INSTALL) -m 644 +INSTALL_DIR = /usr/bin/install -d + +# destination directory +INSTALL_NLS_DIR = $(DESTDIR)/usr/share/locale +# PO catalog handling +MSGMERGE = msgmerge -v +XGETTEXT = xgettext --default-domain=$(NLSPACKAGE) \ + --add-comments +MSGFMT = msgfmt --statistics --verbose + +# What do we need to do +POFILES = $(wildcard ./*.po) +MOFILES = $(patsubst %.po,%.mo,$(POFILES)) +PYSRC = $(wildcard ../com_redhat_kdump/*.py ../com_redhat_kdump/*/*.py ../com_redhat_kdump/*/*/*.py) +GLADEFILES = $(wildcard ../com_redhat_kdump/gui/spokes/*.glade) + +all:: update-po $(MOFILES) + +potfile: $(PYSRC) glade-po + $(XGETTEXT) -L Python --keyword=_ --keyword=N_ $(PYSRC) tmp/*.h + @if cmp -s $(NLSPACKAGE).po $(POTFILE); then \ + rm -f $(NLSPACKAGE).po; \ + else \ + mv -f $(NLSPACKAGE).po $(POTFILE); \ + fi; \ + rm -rf tmp/ + +glade-po: $(GLADEFILES) + rm -rf tmp/ + for f in $(GLADEFILES); do \ + intltool-extract --type=gettext/glade -l $$f ;\ + done + +update-po: Makefile refresh-po potfile + +refresh-po: Makefile + for cat in $(POFILES); do \ + if $(MSGMERGE) $$cat $(POTFILE) --out=$$cat ; then \ + echo "$(MSGMERGE) of $$cat succeeded" ; \ + else \ + echo "$(MSGMERGE) of $$cat failed" ; \ + fi \ + done + +clean: + @rm -fv *mo *~ .depend + @rm -rf tmp + +install: $(MOFILES) + @for n in $(MOFILES); do \ + l=`basename $$n .mo`; \ + $(INSTALL_DIR) $(INSTALL_NLS_DIR)/$$l/LC_MESSAGES; \ + $(INSTALL_DATA) --verbose $$n $(INSTALL_NLS_DIR)/$$l/LC_MESSAGES/$(NLSPACKAGE).mo; \ + done + +uninstall: + rm -rfv $(INSTALL_NLS_DIR)/*/LC_MESSAGES/$(NLSPACKAGE).mo + +%.mo: %.po + $(MSGFMT) -o $@ $< + +.PHONY: missing depend + diff --git a/kdump-anaconda-addon/po/kdump-anaconda-addon.pot b/kdump-anaconda-addon/po/kdump-anaconda-addon.pot new file mode 100644 index 0000000..3b9b641 --- /dev/null +++ b/kdump-anaconda-addon/po/kdump-anaconda-addon.pot @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-04-09 15:07+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../com_redhat_kdump/ks/kdump.py:112 +#, python-format +msgid "Invalid value %s for --reserve-mb" +msgstr "" + +#: ../com_redhat_kdump/tui/spokes/kdump.py:56 +msgid "Kdump" +msgstr "" + +#: ../com_redhat_kdump/tui/spokes/kdump.py:84 +#: ../com_redhat_kdump/gui/spokes/kdump.py:138 +msgid "Kdump is enabled" +msgstr "" + +#: ../com_redhat_kdump/tui/spokes/kdump.py:86 +#: ../com_redhat_kdump/gui/spokes/kdump.py:140 +msgid "Kdump is disabled" +msgstr "" + +#: ../com_redhat_kdump/gui/spokes/kdump.py:43 +msgid "_KDUMP" +msgstr "" + +#: tmp/fedora.glade.h:1 tmp/kdump.glade.h:1 +msgid "KDUMP" +msgstr "" + +#: tmp/fedora.glade.h:2 tmp/kdump.glade.h:2 +msgid "" +"Kdump is a kernel crash dumping mechanism. In the event of a system crash, " +"kdump will capture information from your system that can be invaluable in " +"determining the cause of the crash. Note that kdump does require reserving a " +"portion of system memory that will be unavailable for other uses." +msgstr "" + +#: tmp/fedora.glade.h:3 tmp/kdump.glade.h:7 +msgid "Memory To Be Reserved (MB):" +msgstr "" + +#: tmp/fedora.glade.h:4 tmp/kdump.glade.h:8 +msgid "Total System Memory (MB):" +msgstr "" + +#: tmp/fedora.glade.h:5 tmp/kdump.glade.h:9 +msgid "Usable System Memory (MB):" +msgstr "" + +#: tmp/fedora.glade.h:6 tmp/kdump.glade.h:3 +msgid "_Enable kdump?" +msgstr "" + +#: tmp/kdump.glade.h:4 +msgid "Kdump Memory Reservation:" +msgstr "" + +#: tmp/kdump.glade.h:5 +msgid "_Automatic" +msgstr "" + +#: tmp/kdump.glade.h:6 +msgid "_Manual" +msgstr ""