File sapconf.spec of Package sapconf.16016

#
# spec file for package sapconf
#
# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via https://bugs.opensuse.org/
#


%if ! %{defined _fillupdir}
  %define _fillupdir /var/adm/fillup-templates
%endif

Name:           sapconf
Version:        5.0.0
Release:        0
Summary:        Kernel Parameter Initializiation for SAP Systems
License:        LGPL-2.1-or-later
Group:          Productivity/Other
URL:            https://www.suse.com/partners/alliance/sap/
PreReq:         %fillup_prereq
Source0:        %name-%version.tar.gz
BuildArch:      noarch
Requires:       bc
%if 0%{?sle_version} == 120100
Requires:       sapinit-systemd-compat
%else
Requires:       systemd >= 228-142.1
%endif
Requires:       /usr/bin/cpupower
Requires:       logrotate
Requires:       sysstat
Requires:       uuidd
Suggests:       cron
%{?systemd_requires}

%description 
The utility adjusts operating system parameters, such as kernel 
tuning settings and resource limits, to allow running various
SAP solutions at satisfactory performance.

Authors:
--------
    Angela Briel, Howard Guo

%prep
%setup -q

%build

%install
mkdir -p %{buildroot}%{_libexecdir}/%{name}/
install -m 0644 lib/common.sh %{buildroot}%{_libexecdir}/%{name}/
install -m 0644 lib/profiles.sh %{buildroot}%{_libexecdir}/%{name}/
install -m 0644 lib/util.sh %{buildroot}%{_libexecdir}/%{name}/
install -m 0755 lib/sccu.sh %{buildroot}%{_libexecdir}/%{name}/
install -m 0755 lib/mv_tuned_conf.sh %{buildroot}%{_libexecdir}/%{name}/

mkdir -p %{buildroot}%{_localstatedir}/lib/%{name}/saved_configs
mkdir -p %{buildroot}%{_unitdir}/systemd/system/ %{buildroot}%{_sbindir}/
install -m 0644 sapconf.service %{buildroot}%{_unitdir}/
install -m 0755 bin/* %{buildroot}%{_sbindir}/
ln -s /usr/sbin/service %{buildroot}%{_sbindir}/rcsapconf

mkdir -p %{buildroot}%{_mandir}/{man5,man7,man8}/
install -m 0644 man/*.5 %{buildroot}%{_mandir}/man5/
install -m 0644 man/*.7 %{buildroot}%{_mandir}/man7/
install -m 0644 man/*.8 %{buildroot}%{_mandir}/man8/

mkdir -p %{buildroot}/%{_sysconfdir}/logrotate.d
install -m 0644 logrotate/%{name} %{buildroot}/%{_sysconfdir}/logrotate.d/

mkdir -p %{buildroot}/%{_fillupdir}/
pushd sysconfig
for file in *; do
    cp "$file" "%{buildroot}/%{_fillupdir}/sysconfig.$file"
done
popd

%pre
%service_add_pre sapconf.service
touch /run/sapconf_during_pkg_inst
if [ $1 -eq 1 ]; then
    # package initial install
    # check, if old config files from a former installation still exist
    SC=/etc/sysconfig
    for f in sapconf sapnote-1557506 sapnote-1680803; do
        if [ -f "${SC}${f}" ]; then
            mv "${SC}${f}" "${SC}${f}".rpmold || :
        fi
    done
else
    # package update
    # to prevent sapconf related tuned error messages anytime after this
    # sapconf package installation switch off tuned to remove the 'active'
    # sapconf profile
    # 'tuned-adm off' is sadly the only possibility to remove an 'active'
    # sapconf profile
    systemctl -q is-active tuned && [[ $(cat /etc/tuned/active_profile) == sap-* ]] && (touch /run/sapconf_tuned_removal_started; sed "s/sap-/sapconf-/" /etc/tuned/active_profile > /var/lib/sapconf/act_profile; tuned-adm off) || :
    ([ ! -f /run/sapconf_tuned_removal_started ] && [ -f /usr/lib/tuned/sap-hana/script.sh ]) && touch /run/sapconf_tuned_removal_started || :
    if ([ -f /etc/sysconfig/sapnote-155750 ] || ([ -f /etc/sysconfig/sapnote-1680803 ] && [ ! -f /etc/sysconfig/sapnote-bobj ])); then
        touch /tmp/sapconf_remove_nofile || :
    fi
    # rewrite old sapconf profile names to the new ones
    [ -f /var/lib/sapconf/act_profile ] && sed -i "s/sap-/sapconf-/" /var/lib/sapconf/act_profile || :
    [ -f /var/lib/sapconf/last_profile ] && sed -i "s/sap-/sapconf-/" /var/lib/sapconf/last_profile || :
fi

%post
%fillup_only -n sapnote-1680803
%fillup_only -n sapnote-bobj

if [ $1 -eq 1 ]; then
    # package initial install
    %fillup_only -n sapconf
    touch /tmp/initial_sapconf_inst || :
else
    # package update
    SN1557506=/etc/sysconfig/sapnote-1557506
    # check, if /etc/sysconfig/sapnote-1557506 still exists and contains an
    # active pagecache configuration. If yes, move the active configuration
    # to /etc/sysconfig/sapconf, rewrite variable names and remove the no
    # longer used file /etc/sysconfig/sapnote-1557506
    if [ -f $SN1557506 ]; then
        # covers updates up to 4.1.12 and later
        SN=/etc/sysconfig/sapconf
        mv $SN ${SN}.rpmsave || :
        %fillup_only -n sapconf
        if [[ `grep "ENABLE_PAGECACHE_LIMIT=" $SN1557506 | awk -F = '{print $2}'` =~ yes ]]; then
            for pat in "ENABLE_PAGECACHE_LIMIT=" "PAGECACHE_LIMIT_IGNORE_DIRTY=" "PAGECACHE_LIMIT_MB="; do
                if [ "$pat" == "PAGECACHE_LIMIT_MB=" ]; then
                    # rewrite variable name
                    PLMB=`grep $pat $SN1557506 | grep "^[^#]" | awk -F = '{print $2}'`
                    NLINE=$pat$PLMB
                    SCPAT=`echo $pat | sed "s/=/ = /"`
                elif [ "$pat" == "PAGECACHE_LIMIT_IGNORE_DIRTY=" ]; then
                    NLINE=`grep $pat $SN1557506 | grep "^[^#]"`
                    SCPAT=`echo $pat | sed "s/=/ = /"`
                else
                    NLINE=`grep $pat $SN1557506 | grep "^[^#]"`
                    SCPAT=$pat
                fi
                if [ -n "$NLINE" ]; then
                    echo "Updating $SN with line '$NLINE' from $SN1557506..."
                    sed -i "s/.*$SCPAT.*/$NLINE/" $SN || :
                fi
            done
        fi
        rm $SN1557506 2>/dev/null && echo "Removing obsolete $SN1557506..." || :
    else
        # covers updates starting from 4.1.12 or later
        # to update the comment sections in /etc/sysconfig/sapconf
        # does not work with /bin/fillup, but is mandatory for SAP
        %{_libexecdir}/%{name}/sccu.sh || :

        %fillup_only -n sapconf
    fi

    # move custom specific sapconf related tuned profiles from /etc/tuned/
    # to /var/lib/sapconf/saved_configs
    %{_libexecdir}/%{name}/mv_tuned_conf.sh || :
    # remove nofile related limits.conf entries for @sapsys @sdba @dba
    if [ -f /tmp/sapconf_remove_nofile ]; then
        lim_chg=false
        for ulimit_group in @sapsys @sdba @dba; do
            for ulimit_type in soft hard; do
                limits_line=$(grep -E "^${ulimit_group}[[:space:]]+${ulimit_type}[[:space:]]+nofile.+" /etc/security/limits.conf)
                if [ -n "$limits_line" ]; then
                    sed -i "/$limits_line/d" /etc/security/limits.conf || :
                    lim_chg=true
                fi
            done
        done
        [[ $lim_chg ]] && echo "Updating /etc/security/limits.conf..." || :
        rm -f /tmp/sapconf_remove_nofile || :
    fi
fi

sed -i '/^[^#].*[[:blank:]][[:blank:]]*=[[:blank:]][[:blank:]]*.*/s;[[:blank:]];;g' /etc/sysconfig/sapconf >/dev/null 2>&1 || :
%service_add_post sapconf.service

%if 0%{?sle_version} > 120100
    # Amend logind's behaviour (bsc#1031355, bsc#1039309, bsc#1043844), there is no rollback.
    SAP_LOGIN_FILE=/etc/systemd/logind.conf.d/sap.conf
    if [ ! -f $SAP_LOGIN_FILE ]; then
        mkdir -p /etc/systemd/logind.conf.d || :
        echo "[Login]
UserTasksMax=infinity" > $SAP_LOGIN_FILE || :
        echo "Set the maximum number of OS tasks each user may run concurrently (UserTasksMax) to 'infinity'"
        echo "With this setting your system is vulnerable to fork bomb attacks."
        echo "Please reboot the system for the UserTasksMax change to become effective"
    else
        # bsc#1111243
        if ! (grep 'UserTasksMax=infinity' $SAP_LOGIN_FILE > /dev/null 2>&1); then
            echo "ATTENTION: File '$SAP_LOGIN_FILE' does not include the setting for"
            echo "           'UserTasksMax=infinity'. Please check"
        else
            echo "File '$SAP_LOGIN_FILE' already exists, nothing to do."
        fi
    fi
%endif

%preun
%service_del_preun sapconf.service
test -n "$FIRST_ARG" || FIRST_ARG=$1
if [ $FIRST_ARG -eq 0 ]; then
    # Package removal, not upgrade
    # revert settings - not needed, done by service_del_preun

    # clean up custom specific sapconf tuned configuration
    # move custom specific sapconf related tuned profiles from /etc/tuned/
    # to /var/lib/sapconf/saved_configs
    [ ! -d /var/lib/sapconf/saved_configs ] && mkdir -p /var/lib/sapconf/saved_configs
    for prof in sap-hana sap-netweaver sap-ase sap-bobj; do
        if [ -f /etc/tuned/"$prof"/tuned.conf ]; then
            echo "moving custom profile /etc/tuned/$prof to /var/lib/sapconf/saved_configs"
            mv /etc/tuned/"$prof" /var/lib/sapconf/saved_configs || :
        fi
    done
fi

%postun
%service_del_postun sapconf.service
test -n "$FIRST_ARG" || FIRST_ARG=$1
if [ $FIRST_ARG -eq 0 ]; then
    # remove drop-in file for ulimit settings
    if [ -f /etc/security/limits.d/sapconf-nofile.conf ]; then
        echo "removing no longer needed file '/etc/security/limits.d/sapconf-nofile.conf'"
        rm -f /etc/security/limits.d/sapconf-nofile.conf
    fi
fi

%posttrans -p /bin/bash
# Use a real bash script with an explicit "exit 0" at the end to be by default fail safe
# an explicit "exit 1" must be use to enforce package install/upgrade/erase failure where needed
# see the "Shared_libraries" section in http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
# Begin refresh systemd units and clean up possibly obsolete systemd units
# The following is a generic way how to refresh and/or clean up systemd units.
# A systemd unit may need a refresh after updating a package when the new package
# had installed a changed systemd unit file for an enabled systemd unit.
# A systemd unit may become obsolete by updating a package (see bnc#904215).
# A systemd unit is considered to have become obsolete when the systemd
# symlink /etc/systemd/system/.../unit_name -> /path/to/unit_file is broken.
# When during package update the new package does no longer provide a unit file
# then the systemd symlink becomes broken after the files of the old package
# had been actually removed by RPM.
# According to /usr/share/doc/packages/rpm/manual/triggers and according
# to https://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets#Scriptlet_Ordering
# and http://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Scriptlet_Ordering
# from the new package only "posttrans of new package" is run after "removal of old package"
# so that the new package must do the clean up as RPM posttrans scriptlet.
if systemctl --quiet is-enabled sapconf.service 2>/dev/null; then
    # Refresh still valid enabled systemd units and clean up possibly obsoleted systemd units:
    # Enforce systemd to use the current unit file which is usually the unit file of the new package
    # but also in case of custom units (that use other unit files) a "reenable" won't hurt because
    # "reenable" does not implicitly stop a running service which is "the right thing" because
    # a RPM package installation must not automatically disrupt (restart) a running service.
    # Using "--force reenable" is essential to clean up possibly conflicting/broken symlinks.
    # (without "|| :" build fails with "Failed to get D-Bus connection: No connection to service manager. posttrans script ... failed"):
    systemctl --quiet --force reenable sapconf.service 2>/dev/null || :
else
    # Refresh still valid disabled systemd units and clean up possibly obsoleted systemd units:
    # First using "--force reenable" is essential to clean up possibly conflicting/broken symlinks
    # because there is no "--force disable" that would clean up possibly conflicting/broken symlinks
    # see https://bugzilla.opensuse.org/show_bug.cgi?id=904215#c34
    # so that first the unit has a clean state and then it is set back to disabled (as it was before).
    # If a disabled systemd unit has become obsoleted, "systemctl --force reenable" will clean it up
    # which means the unit gets removed and the subsequent "systemctl disable" will do nothing.
    # (without "|| :" build fails with "Failed to get D-Bus connection: No connection to service manager. posttrans script ... failed"):
    systemctl --quiet --force reenable sapconf.service 2>/dev/null || :
    systemctl --quiet disable sapconf.service 2>/dev/null || :
fi
rm -f /run/sapconf_during_pkg_inst
if [ -f /tmp/initial_sapconf_inst ]; then
    # package initial install
    rm -f /tmp/initial_sapconf_inst || :
    [[ $(cat /etc/tuned/active_profile 2>/dev/null) == "" && ! -f /var/lib/sapconf/act_profile ]] && systemctl start sapconf.service || :
else
    # package update
    # if sapconf with tuned support was not used - stop and disable sapconf service
    # (jsc#SLE-10987 decision)
    ([ ! -f /var/lib/sapconf/act_profile ] && [ -f /run/sapconf_tuned_removal_started ]) && (systemctl stop sapconf.service; systemctl disable sapconf.service) || :
    # if sapconf with tuned support was used - stop and disable tuned service
    # (jsc#SLE-10987 decision)
    ([ -f /var/lib/sapconf/act_profile ] && [ -f /run/sapconf_tuned_removal_started ]) && (systemctl stop tuned.service; systemctl disable tuned.service) || :
    # if saptune is active - stop and disable sapconf service
    # (jsc#SLE-10987 decision)
    [[ $(cat /etc/tuned/active_profile 2>/dev/null) == "saptune" || $(ls -A /var/lib/saptune/saved_state 2>/dev/null) ]] && (systemctl stop sapconf.service; systemctl disable sapconf.service) || :

    # cleanup 'sapconf with tuned support' indicator
    rm -f /run/sapconf_tuned_removal_started || :

    # if sapconf is/was active - reload new configuration
    (systemctl -q is-active sapconf && [ -f /var/lib/sapconf/act_profile ] ) && systemctl reload sapconf.service || :
fi
exit 0

%files 
%defattr(-,root,root)
%{_sbindir}/SAPconf
%{_sbindir}/sapconf
%{_sbindir}/rcsapconf
%dir %{_libexecdir}/%{name}
%{_libexecdir}/%{name}/*
%{_unitdir}/sapconf.service
%{_mandir}/man*/*
%{_fillupdir}/*
%dir %{_localstatedir}/lib/%{name}
%dir %{_localstatedir}/lib/%{name}/saved_configs
#noreplace - to get sapconf.rpmnew, if file on disk has changed
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
# Created at run-time by sapconf
%attr(0755,root,root) %ghost %{_localstatedir}/lib/%{name}/last_profile
%attr(0755,root,root) %ghost %dir %{_localstatedir}/lib/%{name}/saved_state

%changelog
openSUSE Build Service is sponsored by