N
Портал сборок NiceOS
Корпоративный портал наблюдаемости для опубликованных сборок пакетов NiceOS.

input/linux.spec

raw · 26.9 KiB

#niceos-cloud-virt-ultimate.fragment
#niceos-fs-everything.fragment

%bcond_without zfs
%bcond_without gost

%define debug_package %{nil}
%global kernel_srcdir %{_usrsrc}/kernel

%global zfs_version 2.4.0
%global zfs_moddir extra/zfs
%global modulesloaddir %{_prefix}/lib/modules-load.d

# ========================= Arch mapping (RPM arch vs Kbuild ARCH) =========================
# В Kbuild для x86_64 используется ARCH=x86 (каталог arch/x86)
%ifarch x86_64
%define arch x86_64
%define archdir x86
%global karch x86
%endif

%global localversion -%{release}.%{_target_cpu}
%global uname_r %{version}%{localversion}
%define _modulesdir /lib/modules/%{uname_r}

%global bootdir /boot
%global kimg    %{bootdir}/vmlinuz-%{uname_r}
%global initrd  %{bootdir}/initramfs-%{uname_r}.img
%global sysmap  %{bootdir}/System.map-%{uname_r}
%global kconf   %{bootdir}/config-%{uname_r}


Name:           linux
Version:        6.12.90
Release:        1%{?dist}
Summary:        Ядро операционной системы NiceOS / Linux operating system kernel
License:        GPLv2
Group:          System Environment/Kernel
Vendor:         NiceSOFT
Packager:       ООО "НАЙС СОФТ ГРУПП" 5024245440 <niceos@ncsgp.ru>
Distribution:   NiceOS.Core
BugURL:         https://niceos.ru/package/%{name}
URL:            https://www.kernel.org

# Исходники ядра и ваш .config
Source0:        https://www.kernel.org/pub/linux/kernel/v6.x/linux-%{version}.tar.xz

Source1:        LINUX6.12.87-host
Source2: 	https://www.kernel.org/pub/linux/kernel/v6.x/linux-%{version}.tar.sign
Source19:       %{name}-dracut-%{_arch}.conf

Source1000:     linux-crypto.tar.gz
Source1001:     build_gost_kernel.md

%if %{with zfs}
Source2000:     https://github.com/openzfs/zfs/releases/download/zfs-%{zfs_version}/zfs-%{zfs_version}.tar.gz
Patch2000:         zfs-2.2.2-import-by-disk-id.patch
%endif

Source56:       signing_key.x509

# ================== BuildRequires (ядро + tools) ==================
BuildRequires:  gcc
BuildRequires:  make
BuildRequires:  bc
BuildRequires:  bison
BuildRequires:  flex
BuildRequires:  perl
BuildRequires:  openssl-devel
BuildRequires:  elfutils-libelf-devel
BuildRequires:  elfutils-devel
BuildRequires:  binutils-devel
BuildRequires:  zlib-devel
BuildRequires:  zstd-devel
BuildRequires:  libcap-devel
BuildRequires:  libtraceevent-devel
BuildRequires:  python3-devel
BuildRequires:  python3-setuptools
# только x86_64:
BuildRequires:  pciutils-devel
BuildRequires:  ncurses-devel
BuildRequires:  dwarves >= 1.23

# OpenZFS (kernel-only) build deps
BuildRequires:  autoconf
BuildRequires:  automake
BuildRequires:  libtool
BuildRequires:  pkgconfig
BuildRequires:  libuuid-devel
BuildRequires:  libblkid-devel
BuildRequires:  libtirpc-devel
BuildRequires:  libaio-devel
BuildRequires:  libattr-devel

Requires:        kmod
Requires:        filesystem
Requires(pre):    coreutils >= 9.1-7
Requires(preun):  coreutils >= 9.1-7
Requires(post):   coreutils >= 9.1-7
Requires(postun): coreutils >= 9.1-7
Requires(posttrans): zstd

# Для корректного installonly поведения в менеджере пакетов
Provides:       installonlypkg(kernel)
Provides:       kernel-uname-r = %{uname_r}

ExclusiveArch:  x86_64

%description
Ядро Linux — основная часть ОС, управляющая аппаратными ресурсами и предоставляющая базовые сервисы. Пакет содержит ядро и его модули. Инструменты perf/turbostat/cpupower поставляются в подпакетах.

# ========================= Subpackages =========================

%package tools
Summary:        Набор инструментов ядра (perf, turbostat, cpupower)
Group:          System/Tools
Requires:       %{name} = %{version}-%{release}
Requires:       audit elfutils-libelf binutils-libs
Requires:       xz-libs
Requires:       slang
Requires:       python3
Requires:       traceevent-plugins
%ifarch x86_64
Requires:       pciutils
%endif
%description tools
Инструменты анализа производительности и питания: perf, turbostat, cpupower.

# python-расширения perf отдельно
%package python3-perf
Summary:        Python-модули и расширения для perf
Group:          Development/Languages
Requires:       %{name}-tools = %{version}-%{release}
Requires:       python3
%description python3-perf
Python-биндинги и вспомогательные скрипты для perf (site-packages).

%package devel
Summary:        Заголовки и файлы для сборки внешних модулей ядра (%{uname_r})
Group:          Development/System
Requires:       %{name} = %{version}-%{release}
Provides:       kernel-devel = %{version}-%{release}
Provides:       kernel-devel-uname-r = %{uname_r}
Obsoletes:      kernel-devel < %{version}-%{release}

%description devel
Подготовленное дерево исходников/заголовков для сборки внешних модулей:
/usr/src/linux-headers-%{uname_r} и симлинк /usr/lib/modules/%{uname_r}/build.
Содержит include/*, arch/x86/include/*, scripts/, Module.symvers, .config, Makefile
и инструменты objtool/fixdep, необходимые Kbuild.

%package tools-devel
Summary:        Заголовки и файлы для сборки tools (%{uname_r})
Group:          Development/System
Requires:       %{name}-devel = %{version}-%{release}

%description tools-devel
Файлы ядра для cpufreq.h cpuidle.h perf_dlfilter.h powercap.h.

%if %{with gost}
%package        -n gost-source-%{name}
Summary:        GOST cryptographic algorithms sources
Summary(ru):    Исходники модулей ядра ГОСТ криптографии
BuildArch:      noarch
Requires:       build-essential

%package crypto-gost
Summary:        Linux Kernel GOST crypto modules for %{uname_r}
Group:          System Environment/Kernel
Requires:       %{name} = %{version}-%{release}
Requires:       kmod
# нужно, чтобы можно было держать несколько версий рядом под разные installonly ядра
Provides:       kernel-modules-gost = %{uname_r}

%description crypto-gost
Набор внешних (out-of-tree) модулей ядра linux-crypto, добавляющих поддержку российских криптоалгоритмов семейства GOST через Linux Kernel Crypto API.
Модули должны быть собраны строго под вашу версию ядра (%{uname_r}).
%endif

%if %{with zfs}
%package kmod-zfs
Summary:        Linux Kernel ZFS modules (OpenZFS) for %{uname_r}
Group:          System Environment/Kernel
Requires:       %{name} = %{version}-%{release}
Requires:       kmod
Recommends:     zfs = %{zfs_version}
Recommends:     zfs-utils = %{zfs_version}
Recommends:     zfs-zed = %{zfs_version}
# удобно для поиска/политик, и чтобы явно было видно соответствие uname -r
Provides:       kernel-modules-zfs = %{uname_r}
Provides:       zfs-kmod-uname-r = %{uname_r}


%description kmod-zfs
Модули OpenZFS (только .ko), собранные строго под это ядро (%{uname_r}). Утилиты zpool/zfs поставляются отдельным пакетом.
%endif

%description -n gost-source-%{name}
This is a set of Linux kernel modules implementing GOST cryptographic algorithms.

%description -l ru -n gost-source-%{name}
linux-crypto — набор внешних модулей ядра Linux (out-of-tree) для подсистемы Kernel Crypto API, добавляющий реализации криптографических алгоритмов ГОСТ.

Состав реализованных алгоритмов:
- ГОСТ 28147-89 (блочный шифр) и режимы/варианты применения (в т.ч. MAC “имитовставка”);
- ГОСТ Р 34.11-94 (хэш), включая HMAC на его основе;
- ГОСТ Р 34.12-2015: «Магма» и «Кузнечик», включая CMAC;
- ГОСТ Р 34.11-2012 (Стрибог) — сборка может быть включена/отключена отдельно.


%package drivers-gpu
Summary:        Kernel GPU Drivers
Group:          System Environment/Kernel
Requires:       %{name} = %{version}-%{release}
%description drivers-gpu
The Linux package contains the Linux kernel drivers for GPU

%package drivers-sound
Summary:        Kernel Sound modules
Group:          System Environment/Kernel
Requires:       %{name} = %{version}-%{release}
%description drivers-sound
The Linux package contains the Linux kernel sound support

# ========================= BUILD =========================

%prep
%setup -q -n linux-%{version}
%make_build ARCH=%{karch} mrproper

cp -v %{SOURCE1} .config
%make_build ARCH=%{karch} LOCALVERSION=%{localversion} olddefconfig

echo "==== CONFIG DIFF AFTER olddefconfig ===="
scripts/diffconfig %{SOURCE1} .config || :
echo "========================================"

install -m 700 -d certs

if [ -n "${NICEOS_KERNEL_SIGNING_KEY:-}" ]; then
    if [ ! -r "$NICEOS_KERNEL_SIGNING_KEY" ]; then
        echo "ERROR: NICEOS_KERNEL_SIGNING_KEY is set but not readable: $NICEOS_KERNEL_SIGNING_KEY" >&2
        exit 1
    fi

    echo "Using external NiceOS kernel module signing key" >&2
    cat "$NICEOS_KERNEL_SIGNING_KEY" %{SOURCE56} > certs/signing_key.pem
    chmod 0600 certs/signing_key.pem
else
    echo "ERROR: NICEOS_KERNEL_SIGNING_KEY is not set" >&2
    echo "Official NiceOS kernel builds must provide private key outside dist-git." >&2
    exit 1
fi

# linux-crypto sources (out-of-tree modules)
# Распаковываем внутрь дерева ядра, чтобы KSRC указывал на собираемое ядро, а не на загруженное.
mkdir -p linux-crypto
# Вариант с strip-components=1 удобен для git-archive с корневым каталогом; fallback — без strip.
tar -xf %{SOURCE1000} -C linux-crypto --strip-components=1 2>/dev/null || tar -xf %{SOURCE1000} -C linux-crypto

# OpenZFS sources (out-of-tree, kernel modules)
# Распаковываем рядом с деревом ядра: сборка будет указывать на KSRC текущей сборки, а не на uname -r билд-хоста.
%if %{with zfs}
tar -xf %{SOURCE2000}
%patch 2000 -p1 -d zfs-%{zfs_version}
# Fix OpenZFS lookup_bdev() detection only if kernel has moved the file
if [ -f "%{_builddir}/linux-%{version}/block/bdev.c" ]; then
  sed -i 's@fs/block_dev\.c@block/bdev.c@g' zfs-%{zfs_version}/config/kernel-blkdev.m4
fi
%endif


%build
# Ядро и модули (LOCALVERSION влияет на /usr/lib/modules/*)
%make_build KBUILD_EXTMOD= KBUILD_BUILD_VERSION="%{release}" \
    KBUILD_BUILD_HOST="niceos" \
    ARCH=%{karch} LOCALVERSION=%{localversion}

# После modules_prepare дерево готово к сборке внешних модулей
krel=$(make -s -C %{_builddir}/linux-%{version} \
        ARCH=%{karch} LOCALVERSION=%{localversion} kernelrelease)
echo "Kernel release from tree: $krel"
test "$krel" = "%{uname_r}"

# linux-crypto (GOST) — собираем строго под текущее дерево ядра, независимо от uname -r сборочной системы
%if %{with gost}
sed -i \
  -e 's|^ccflags-y[[:space:]]*:= -I[[:space:]]*$(PWD)|ccflags-y := -I$(src)|' \
  -e 's|M=$(PWD)|M=$(CURDIR)|g' \
  linux-crypto/Makefile

%make_build -C %{_builddir}/linux-%{version} \
  M=%{_builddir}/linux-%{version}/linux-crypto \
  ARCH=%{karch} LOCALVERSION=%{localversion} \
  CONFIG_CRYPTO_STREEBOG=n \
  modules
%endif


%if %{with zfs}
pushd zfs-%{zfs_version}
./autogen.sh

./configure \
    --with-config=kernel \
    --with-linux=%{_builddir}/linux-%{version} \
    --with-linux-obj=%{_builddir}/linux-%{version}

# Собираем модули
%make_build -C module \
    KERNEL_SRC=%{_builddir}/linux-%{version} \
    KERNEL_BUILD=%{_builddir}/linux-%{version}

popd
%endif


# perf: отключаем Werror и самые проблемные предупреждения
%make_build -C tools/perf \
    PYTHON=python3 \
    NO_LIBPERL=1 NO_SLANG=1 NO_GTK2=1 \
    WERROR=0 NO_WERROR=1 \
    EXTRA_CFLAGS='-Wno-error=alloc-size -Wno-error=calloc-transposed-args -Wno-error=deprecated-declarations'

%make_build ARCH=%{karch} -C tools turbostat cpupower PYTHON=python3

# ========================= INSTALL =========================

%install
# Модули ядра
%make_build KBUILD_EXTMOD= ARCH=%{karch} INSTALL_MOD_PATH=%{buildroot} LOCALVERSION=%{localversion} modules_install

# Автозагрузка: грузим верхний модуль zfs, зависимости подтянутся автоматически
%if %{with zfs}
install -m 755 -d %{buildroot}%{modulesloaddir}
cat > %{buildroot}%{modulesloaddir}/zfs-%{uname_r}.conf <<'EOF'
zfs
EOF
%endif

# Образ ядра и сопутствующие файлы
# Для installonly НЕ ставим общие /boot/vmlinuz, /boot/System.map, /boot/config (иначе конфликт версий).
install -m 755 -d %{buildroot}%{bootdir}
install -m 644 arch/%{archdir}/boot/bzImage %{buildroot}%{kimg}
install -m 400 System.map                   %{buildroot}%{sysmap}
install -m 644 .config                      %{buildroot}%{kconf}

# modprobe.d пример (версионируем, чтобы не конфликтовало между installonly ядрами)
install -m755 -d %{buildroot}/etc/modprobe.d
cat > %{buildroot}/etc/modprobe.d/usb-%{uname_r}.conf <<'EOF'
install ohci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i ohci_hcd ; true
install uhci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i uhci_hcd ; true
EOF

# ---------- kernel-devel (linux-headers) ----------
install -m 755 -d %{buildroot}%{_usrsrc}/linux-headers-%{uname_r}

# Register myself to initramfs (директории общие, конфликтов не создают)
mkdir -p %{buildroot}%{_localstatedir}/lib/initramfs/kernel

# Cleanup dangling symlinks from modules_install (создадим свои в -devel)
rm -rf %{buildroot}%{_modulesdir}/source \
       %{buildroot}%{_modulesdir}/build

# Копируем файлы, необходимые Kbuild для внешних модулей (включая generated/config)
hdrdst=%{buildroot}%{_usrsrc}/linux-headers-%{uname_r}

# Базовые Makefile/Kconfig/скрипты
find . \
  \( -name 'Makefile*' \
     -o -name 'Kbuild*' \
     -o -name 'Kconfig*' \
     -o -name '*.pl' \
     -o -name '*.sh' \
     -o -name '*.awk' \
     -o -name '*.lds' \) \
  -type f -print0 | xargs -0 -r cp --parents -t "$hdrdst"

# include + arch includes
find include arch/%{archdir}/include -type f -print0 \
  | xargs -0 -r cp --parents -t "$hdrdst"

# generated (после modules_prepare)
find include/generated include/config arch/%{archdir}/include/generated -type f -print0 2>/dev/null \
  | xargs -0 -r cp --parents -t "$hdrdst"

# scripts (включая modpost/genksyms и прочее)
find scripts -type f -print0 \
  | xargs -0 -r cp --parents -t "$hdrdst"

# Символы экспортов
install -m 644 Module.symvers "$hdrdst/Module.symvers"

# .config туда, где его ожидают внешние сборки
install -m 644 .config "$hdrdst/.config"

# после сборки ядра: objtool и fixdep (явно)
install -m 755 -d "$hdrdst/tools/objtool"
install -m 755 tools/objtool/objtool "$hdrdst/tools/objtool/objtool"

install -m 755 -d "$hdrdst/scripts/basic"
install -m 755 scripts/basic/fixdep "$hdrdst/scripts/basic/fixdep"

# modpost/genksyms (если собраны)
if [ -x scripts/mod/modpost ]; then
  install -m 755 -d "$hdrdst/scripts/mod"
  install -m 755 scripts/mod/modpost "$hdrdst/scripts/mod/modpost"
fi
if [ -x scripts/genksyms/genksyms ]; then
  install -m 755 -d "$hdrdst/scripts/genksyms"
  install -m 755 scripts/genksyms/genksyms "$hdrdst/scripts/genksyms/genksyms"
fi

# Ссылки /lib/modules/<uname_r>/{build,source} -> /usr/src/linux-headers-<uname_r>
ln -snf "%{_usrsrc}/linux-headers-%{uname_r}" "%{buildroot}%{_modulesdir}/build"
ln -snf "%{_usrsrc}/linux-headers-%{uname_r}" "%{buildroot}%{_modulesdir}/source"

%if %{with gost}
# linux-crypto (GOST) — устанавливаем модули в отдельный подкаталог extra/
%make_build -C %{_builddir}/linux-%{version} \
  M=%{_builddir}/linux-%{version}/linux-crypto \
  INSTALL_MOD_PATH=%{buildroot} \
  INSTALL_MOD_DIR=extra/linux-crypto-gost \
  modules_install

# Автозагрузка модулей (modules-load.d), как рекомендовано в README linux-crypto
install -m 755 -d %{buildroot}%{modulesloaddir}
cat > %{buildroot}%{modulesloaddir}/linux-crypto-gost-%{uname_r}.conf <<'EOF'
# GOST crypto modules
gost28147_generic
gosthash94_generic
magma_generic
kuznyechik_generic
# streebog_generic
EOF
%endif

# OpenZFS — установка модулей в /lib/modules/%{uname_r}/extra/zfs
# В buildroot depmod запускать не нужно (и часто вредно), depmod делаем в %post.
%if %{with zfs}
krel=$(make -s -C %{_builddir}/linux-%{version} \
        ARCH=%{karch} LOCALVERSION=%{localversion} kernelrelease)
test "$krel" = "%{uname_r}"

%make_build -C zfs-%{zfs_version}/module \
  KERNEL_SRC=%{_builddir}/linux-%{version} \
  KERNEL_BUILD=%{_builddir}/linux-%{version} \
  INSTALL_MOD_PATH=%{buildroot} \
  INSTALL_MOD_DIR=%{zfs_moddir} \
  DEPMOD=/usr/bin/true \
  modules_install
%endif


# Устанавливаем perf напрямую из подкаталога, с теми же флагами
%make_build -C tools/perf \
    DESTDIR=%{buildroot} prefix=%{_prefix} PYTHON=python3 \
    NO_LIBPERL=1 NO_SLANG=1 NO_GTK2=1 \
    WERROR=0 NO_WERROR=1 \
    EXTRA_CFLAGS='-Wno-error=alloc-size -Wno-error=calloc-transposed-args -Wno-error=deprecated-declarations' \
    install-bin install-python_ext

%make_build -C tools ARCH=%{karch} DESTDIR=%{buildroot} \
    prefix=%{_prefix} mandir=%{_mandir} turbostat_install cpupower_install PYTHON=python3

# dracut conf (версионируем, чтобы не конфликтовало между installonly ядрами)
install -m 755 -d %{buildroot}/usr/lib/dracut/dracut.conf.d
install -m 644 %{SOURCE19} %{buildroot}/usr/lib/dracut/dracut.conf.d/%{name}-%{uname_r}.conf

# GOST sources (версионируем, чтобы не конфликтовало между installonly ядрами)
install -pDm0644 %{SOURCE1000} %{buildroot}%{kernel_srcdir}/%{name}-%{uname_r}.tar.gz
install -pDm0644 %{SOURCE1001} %{buildroot}%{kernel_srcdir}/build_gost_kernel-%{uname_r}.md

# ========================= FILES =========================

%triggerin -- initramfs
mkdir -pv %{_sharedstatedir}/rpm-state/initramfs/pending
touch %{_sharedstatedir}/rpm-state/initramfs/pending/%{uname_r}
echo "initrd generation of kernel %{uname_r} will be triggered later" >&2

%post
/sbin/depmod -a %{uname_r} || :
mkdir -p %{_localstatedir}/lib/rpm-state/initramfs/pending
: > %{_localstatedir}/lib/rpm-state/initramfs/pending/%{uname_r}

%if %{with gost}
%post crypto-gost
/sbin/depmod -a %{uname_r} || :

%postun crypto-gost
[ -d "/lib/modules/%{uname_r}" ] && /sbin/depmod -a %{uname_r} || :
%endif

%if %{with zfs}
%post kmod-zfs
/sbin/depmod -a %{uname_r} || :

%postun kmod-zfs
[ -d "/lib/modules/%{uname_r}" ] && /sbin/depmod -a %{uname_r} || :
%endif

%post drivers-gpu
/sbin/depmod -a %{uname_r} || :

%post drivers-sound
/sbin/depmod -a %{uname_r} || :

%posttrans
set -eu

bootdir="%{bootdir}"
kver="%{uname_r}"
kimg="%{kimg}"
initrd="%{initrd}"

grubcfg="/boot/grub2/grub.cfg"

# 1) Гарантируем initramfs под конкретный uname_r
if [ -x /usr/bin/dracut ]; then
    /usr/bin/dracut --force --kver "$kver" "$initrd" || :
fi

# 2) Обновляем GRUB (BLS нет → kernel-install не используем вообще)
if [ -x /usr/sbin/grub2-mkconfig ] && [ -d /boot/grub2 ]; then
    /usr/sbin/grub2-mkconfig -o "$grubcfg" || :
fi

# 2.1) Сделать новое ядро дефолтным (без grubby)
# Ищем menuentry-id для "Linux $kver" и пишем его в saved_entry в grubenv
grubenv=""
[ -f /boot/grub2/grubenv ] && grubenv="/boot/grub2/grubenv"
[ -z "$grubenv" -a -f /boot/grub/grubenv ] && grubenv="/boot/grub/grubenv"

entry_id="$(
  awk -v k="$kver" '
    $0 ~ /^menuentry / && $0 ~ ("Linux " k) {
      n=split($0, a, "'\''");
      for (i=1; i<=n; i++) if (a[i] ~ /^gnulinux-/) { print a[i]; exit }
    }
  ' "$grubcfg" 2>/dev/null || true
)"

if [ -n "${entry_id:-}" ]; then
  if [ -x /usr/sbin/grub2-set-default ]; then
    /usr/sbin/grub2-set-default "$entry_id" || :
  elif [ -n "$grubenv" ] && [ -x /usr/bin/grub2-editenv ]; then
    /usr/bin/grub2-editenv "$grubenv" set "saved_entry=$entry_id" || :
  fi
fi


# (опционально) grubby: можно добавить entry явно, но mkconfig обычно достаточно.
if [ -x /usr/sbin/grubby ]; then
    /usr/sbin/grubby \
        --add-kernel="$kimg" \
        --initrd="$initrd" \
        --title="NiceOS Linux ($kver)" \
        --copy-default || :
fi

# 3) Обратная совместимость: “текущие” симлинки (не пакетим их в %files)
ln -snf "vmlinuz-$kver"            "$bootdir/vmlinuz"        2>/dev/null || :
ln -snf "initramfs-$kver.img"      "$bootdir/initramfs.img"  2>/dev/null || :
ln -snf "System.map-$kver"         "$bootdir/System.map"     2>/dev/null || :
ln -snf "config-$kver"             "$bootdir/config"         2>/dev/null || :

# dracut conf link для старых обвязок (если надо)
if [ -d /usr/lib/dracut/dracut.conf.d ]; then
    if [ -f "/usr/lib/dracut/dracut.conf.d/%{name}-$kver.conf" ]; then
        ln -snf "%{name}-$kver.conf" "/usr/lib/dracut/dracut.conf.d/%{name}.conf" 2>/dev/null || :
    fi
fi

exit 0


%postun
set -eu

bootdir="%{bootdir}"
kver="%{uname_r}"
kimg="%{kimg}"
grubcfg="/boot/grub2/grub.cfg"

# $1 == 0 означает erase (а не upgrade)
if [ "${1}" -eq 0 ]; then
    # 1) Удаляем entry через grubby, если он есть (удобно, но не обязательно)
    if [ -x /usr/sbin/grubby ]; then
        /usr/sbin/grubby --remove-kernel="$kimg" || :
    fi

    # 2) Пересобираем grub.cfg (главное!)
    if [ -x /usr/sbin/grub2-mkconfig ] && [ -d /boot/grub2 ]; then
        /usr/sbin/grub2-mkconfig -o "$grubcfg" || :
    fi

    # 3) Если “текущие” симлинки указывали на удалённое — переназначим на самый новый оставшийся
    if [ -L "$bootdir/vmlinuz" ] && [ ! -e "$bootdir/$(readlink "$bootdir/vmlinuz")" ]; then
        newest="$(ls -1 "$bootdir"/vmlinuz-* 2>/dev/null | sort -V | tail -n 1 || true)"
        [ -n "$newest" ] && ln -snf "$(basename "$newest")" "$bootdir/vmlinuz" || :
    fi

    if [ -L "$bootdir/initramfs.img" ] && [ ! -e "$bootdir/$(readlink "$bootdir/initramfs.img")" ]; then
        newest="$(ls -1 "$bootdir"/initramfs-*.img 2>/dev/null | sort -V | tail -n 1 || true)"
        [ -n "$newest" ] && ln -snf "$(basename "$newest")" "$bootdir/initramfs.img" || :
    fi

    if [ -L "$bootdir/System.map" ] && [ ! -e "$bootdir/$(readlink "$bootdir/System.map")" ]; then
        newest="$(ls -1 "$bootdir"/System.map-* 2>/dev/null | sort -V | tail -n 1 || true)"
        [ -n "$newest" ] && ln -snf "$(basename "$newest")" "$bootdir/System.map" || :
    fi

    if [ -L "$bootdir/config" ] && [ ! -e "$bootdir/$(readlink "$bootdir/config")" ]; then
        newest="$(ls -1 "$bootdir"/config-* 2>/dev/null | sort -V | tail -n 1 || true)"
        [ -n "$newest" ] && ln -snf "$(basename "$newest")" "$bootdir/config" || :
    fi
fi

exit 0


%files
%license COPYING
%dir %{_localstatedir}/lib/initramfs
%dir %{_localstatedir}/lib/initramfs/kernel
/usr/lib/dracut/dracut.conf.d/%{name}-%{uname_r}.conf
/boot/vmlinuz-%{uname_r}
/boot/System.map-%{uname_r}
/boot/config-%{uname_r}
%{_modulesdir}
%dir /etc/modprobe.d
/etc/modprobe.d/usb-%{uname_r}.conf
%exclude %{_modulesdir}/build
%exclude %{_modulesdir}/source
%if %{with gost}
%exclude %{_modulesdir}/extra/linux-crypto-gost
%endif
%if %{with zfs}
%exclude %{_modulesdir}/%{zfs_moddir}
%endif
%exclude %{_modulesdir}/kernel/drivers/gpu
%exclude %{_modulesdir}/kernel/sound

%if %{with gost}
%files crypto-gost
%defattr(-,root,root)
%{_modulesdir}/extra/linux-crypto-gost
%{modulesloaddir}/linux-crypto-gost-%{uname_r}.conf
%endif

%if %{with zfs}
%files kmod-zfs
%defattr(-,root,root)
%{_modulesdir}/%{zfs_moddir}
%{modulesloaddir}/zfs-%{uname_r}.conf
%endif

# ---------- tools (perf + cpupower + turbostat) ----------
%files tools
%defattr(-,root,root)
# perf
%{_bindir}/perf
%{_sysconfdir}/bash_completion.d/perf
%{_libexecdir}/perf-core
%{_datadir}/perf-core
%{_docdir}/perf-tip
# cpupower / turbostat
%{_bindir}/cpufreq-bench_plot.sh
%{_bindir}/cpupower
%{_bindir}/trace
%{_bindir}/turbostat
%{_libdir}/libcpupower.so*
%{_docdir}/packages/cpupower
%{_datadir}/bash-completion/completions/cpupower
%config(noreplace) %{_sysconfdir}/cpufreq-bench.conf
%{_sbindir}/cpufreq-bench
%{_datadir}/locale/*/LC_MESSAGES/cpupower.mo
%{_mandir}/man1/cpupower*
%{_mandir}/man8/turbostat*

# ---------- python3-perf ----------
%files python3-perf
%defattr(-,root,root)
%{python3_sitelib}/*

# ---------- devel (linux-headers) ----------
%files devel
%defattr(-,root,root)
%{_modulesdir}/build
%{_modulesdir}/source
%{_usrsrc}/linux-headers-%{uname_r}

%files tools-devel
%{_includedir}/cpufreq.h
%{_includedir}/cpuidle.h
%{_includedir}/perf/perf_dlfilter.h
%{_includedir}/powercap.h

%files drivers-gpu
%defattr(-,root,root)
%{_modulesdir}/kernel/drivers/gpu

%files drivers-sound
%defattr(-,root,root)
%{_modulesdir}/kernel/sound

%files -n gost-source-%{name}
%{kernel_srcdir}/%{name}-%{uname_r}.tar.gz
%{kernel_srcdir}/build_gost_kernel-%{uname_r}.md

%changelog
* Sun May 24 2026 Stanislav Belikov <niceos@ncsgp.ru> - 6.12.90-1
- Update Linux kernel from 6.12.87 to 6.12.90.
* Sat May 09 2026 Stanislav Belikov <sbelikov@ncsgp.ru> - 6.12.87-1
- Update Linux kernel from 6.12.65 to 6.12.87.
- Pull latest upstream 6.12.y longterm stable fixes from kernel.org.
- Include security-sensitive networking/IPsec fixes, including xfrm ESP handling
  for shared skb fragments.
- Include stable fixes for networking, netfilter/nftables, IPv6, bridge,
  bonding, MPTCP, RXRPC, QRTR and MCTP.
- Include stable fixes for memory management, scheduler, CPU frequency handling,
  crypto, block/storage, filesystems and driver core.
- Include stable driver fixes for DRM/AMDGPU, USB, ALSA, SPI, PHY and platform
  drivers.
- Refresh NiceOS host kernel configuration for Linux 6.12.87.
- Keep kernel ABI package provides based on the full NiceOS kernel release
  string.
* Mon Mar 31 2025 Stanislav Belikov <sbelikov@ncsgp.ru> - 6.12.65-1
- Ядро: сборка с согласованным LOCALVERSION
- Добавлены подпакеты: tools (perf/turbostat/cpupower), python3-perf, cpupower-libs, turbostat
- Реализована сборка и установка perf (+python_ext), cpupower, turbостат из tools