diff --git a/grubby-bls b/grubby-bls new file mode 100755 index 0000000..d94415f --- /dev/null +++ b/grubby-bls @@ -0,0 +1,616 @@ +#!/bin/bash +# +# grubby wrapper to manage BootLoaderSpec files +# +# +# Copyright 2018 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +readonly SCRIPTNAME="${0##*/}" + +CMDLINE_LINUX_DEBUG=" systemd.log_level=debug systemd.log_target=kmsg" +LINUX_DEBUG_VERSION_POSTFIX="_with_debugging" +LINUX_DEBUG_TITLE_POSTFIX=" with debugging" + +declare -a bls_file +declare -a bls_title +declare -a bls_version +declare -a bls_linux +declare -a bls_initrd +declare -a bls_options +declare -a bls_id + +[[ -f /etc/sysconfig/kernel ]] && . /etc/sysconfig/kernel +[[ -f /etc/os-release ]] && . /etc/os-release +read MACHINE_ID < /etc/machine-id +arch=$(uname -m) + +if [[ $arch = 's390' || $arch = 's390x' ]]; then + bootloader="zipl" +else + bootloader="grub2" +fi + +print_error() { + echo "$1" >&2 + exit 1 +} + +if [[ ${#} = 0 ]]; then + print_error "no action specified" +fi + +get_bls_value() { + local bls="$1" && shift + local key="$1" && shift + + echo "$(grep "^${key}[ \t]" "${bls}" | sed -e "s,^${key}[ \t]*,,")" +} + +set_bls_value() { + local bls="$1" && shift + local key="$1" && shift + local value="$1" && shift + + sed -i -e "s,^${key}.*,${key} ${value}," "${bls}" +} + +append_bls_value() { + local bls="$1" && shift + local key="$1" && shift + local value="$1" && shift + + old_value="$(get_bls_value ${bls} ${key})" + set_bls_value "${bls}" "${key}" "${old_value}${value}" +} + +get_bls_values() { + count=0 + for bls in $(ls -vr ${blsdir}/*.conf 2> /dev/null); do + bls_file[$count]="${bls}" + bls_title[$count]="$(get_bls_value ${bls} title)" + bls_version[$count]="$(get_bls_value ${bls} version)" + bls_linux[$count]="$(get_bls_value ${bls} linux)" + bls_initrd[$count]="$(get_bls_value ${bls} initrd)" + bls_options[$count]="$(get_bls_value ${bls} options)" + bls_id[$count]="$(get_bls_value ${bls} id)" + + count=$((count+1)) + done +} + +get_default_index() { + local default="" + local index="-1" + local title="" + local version="" + if [[ $bootloader = "grub2" ]]; then + default="$(grep '^saved_entry=' ${env} | sed -e 's/^saved_entry=//')" + else + default="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')" + fi + + if [[ -z $default ]]; then + index=0 + elif [[ $default =~ ^[0-9]+$ ]]; then + index="$default" + fi + + # GRUB2 and zipl use different fields to set the default entry + if [[ $bootloader = "grub2" ]]; then + title="$default" + else + version="$default" + fi + + for i in ${!bls_file[@]}; do + if [[ $title = ${bls_title[$i]} || $version = ${bls_version[$i]} || + $i -eq $index ]]; then + echo $i + return + fi + done +} + +display_default_value() { + case "$display_default" in + kernel) + echo "${bls_linux[$default_index]}" + exit 0 + ;; + index) + echo "$default_index" + exit 0 + ;; + title) + echo "${bls_title[$default_index]}" + exit 0 + ;; + esac +} + +param_to_indexes() { + local param="$1" + local indexes="" + + if [[ $param = "ALL" ]]; then + for i in ${!bls_file[@]}; do + indexes="$indexes $i" + done + echo -n $indexes + return + fi + + if [[ $param = "DEFAULT" ]]; then + echo -n $default_index + return + fi + + for i in ${!bls_file[@]}; do + if [[ $param = "${bls_linux[$i]}" ]]; then + indexes="$indexes $i" + fi + + if [[ $param = "TITLE=${bls_title[$i]}" ]]; then + indexes="$indexes $i" + fi + + if [[ $param = $i ]]; then + indexes="$indexes $i" + fi + done + + if [[ -n $indexes ]]; then + echo -n $indexes + return + fi + + echo -n "-1" +} + +display_info_values() { + local indexes=($(param_to_indexes "$1")) + + for i in ${indexes[*]}; do + echo "index=$i" + echo "kernel=${bls_linux[$i]}" + echo "args=\"${bls_options[$i]}\"" + echo "initrd=${bls_initrd[$i]}" + echo "title=${bls_title[$i]}" + done + exit 0 +} + +mkbls() { + local kernel=$1 && shift + local kernelver=$1 && shift + local datetime=$1 && shift + + local debugname="" + local flavor="" + + if [[ $kernelver == *\+* ]] ; then + local flavor=-"${kernelver##*+}" + if [[ $flavor == "-debug" ]]; then + local debugname="with debugging" + local debugid="-debug" + fi + fi + + cat < "${bls_target}" + fi + + if [[ -n $title ]]; then + set_bls_value "${bls_target}" "title" "${title}" + fi + + if [[ -n $options ]]; then + set_bls_value "${bls_target}" "options" "${options}" + fi + + if [[ -n $initrd ]]; then + set_bls_value "${bls_target}" "initrd" "${initrd}" + fi + + if [[ -n $extra_initrd ]]; then + append_bls_value "${bls_target}" "initrd" "${extra_initrd}" + fi + + if [[ $MAKEDEBUG = "yes" ]]; then + arch="$(uname -m)" + bls_debug="$(echo ${bls_target} | sed -e "s/\.${arch}/-debug.${arch}/")" + cp -aT "${bls_target}" "${bls_debug}" + append_bls_value "${bls_debug}" "title" "${LINUX_DEBUG_TITLE_POSTFIX}" + append_bls_value "${bls_debug}" "version" "${LINUX_DEBUG_VERSION_POSTFIX}" + append_bls_value "${bls_debug}" "options" "${CMDLINE_LINUX_DEBUG}" + blsid="$(get_bls_value ${bls_debug} "id" | sed -e "s/\.${arch}/-debug.${arch}/")" + set_bls_value "${bls_debug}" "id" "${blsid}" + fi + + get_bls_values + + if [[ $make_default = "true" ]]; then + set_default_bls "TITLE=${title}" + fi + + exit 0 +} + +update_args() { + local args=$1 && shift + local remove_args=($1) && shift + local add_args=($1) && shift + + for arg in ${remove_args[*]}; do + args="$(echo $args | sed -e "s,$arg[^ ]*,,")" + done + + for arg in ${add_args[*]}; do + if [[ $arg = *"="* ]]; then + value=${arg##*=} + key=${arg%%=$value} + exist=$(echo $args | grep "${key}=") + if [[ -n $exist ]]; then + args="$(echo $args | sed -e "s,$key=[^ ]*,$key=$value,")" + else + args="$args $key=$value" + fi + else + exist=$(echo $args | grep $arg) + if ! [[ -n $exist ]]; then + args="$args $arg" + fi + fi + done + + echo ${args} +} + +update_bls_fragment() { + local indexes=($(param_to_indexes "$1")) && shift + local remove_args=$1 && shift + local add_args=$1 && shift + local initrd=$1 && shift + + for i in ${indexes[*]}; do + if [[ -n $remove_args || -n $add_args ]]; then + local new_args="$(update_args "${bls_options[$i]}" "${remove_args}" "${add_args}")" + set_bls_value "${bls_file[$i]}" "options" "${new_args}" + fi + + if [[ -n $initrd ]]; then + set_bls_value "${bls_file[$i]}" "initrd" "${initrd}" + fi + done +} + +set_default_bls() { + local index=($(param_to_indexes "$1")) + + if [[ $bootloader = grub2 ]]; then + grub2-editenv "${env}" set saved_entry="${bls_title[$index]}" + else + local default="${bls_version[$index]}" + local current="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')" + if [[ -n $current ]]; then + sed -i -e "s,^default=.*,default=${default}," "${zipl_config}" + else + echo "default=${default}" >> "${zipl_config}" + fi + fi +} + +remove_var_prefix() { + if [[ -n $remove_kernel && $remove_kernel =~ ^/ ]]; then + remove_kernel="/${remove_kernel##*/}" + fi + + if [[ -n $initrd ]]; then + initrd="/${initrd##*/}" + fi + + if [[ -n $extra_initrd ]]; then + extra_initrd=" /${extra_initrd##*/}" + fi + + if [[ -n $kernel ]]; then + kernel="/${kernel##*/}" + fi + + if [[ -n $update_kernel && $update_kernel =~ ^/ ]]; then + update_kernel="/${update_kernel##*/}" + fi +} + +print_usage() +{ + cat <&2 + echo "Try '${SCRIPTNAME} --help' to list supported options" >&2 + echo + exit 1 + ;; + --) + shift + break + ;; + *) + echo + echo "${SCRIPTNAME}: invalid option \"${1}\"" >&2 + echo "Try '${SCRIPTNAME} --help' for more information" >&2 + echo + exit 1 + ;; + esac + shift +done + +if [[ -z $blsdir ]]; then + blsdir="/boot/loader/entries" +fi + +if [[ -z $env ]]; then + env="/boot/grub2/grubenv" +fi + +if [[ -z $zipl_config ]]; then + zipl_config="/etc/zipl.conf" +fi + +get_bls_values + +default_index="$(get_default_index)" + +if [[ -n $display_default ]]; then + display_default_value +fi + +if [[ -n $display_info ]]; then + display_info_values "${display_info}" +fi + +if [[ $bootloader = grub2 ]]; then + remove_var_prefix +fi + +if [[ -n $kernel ]]; then + if [[ $copy_default = "true" ]]; then + opts="${bls_options[$default_index]}" + if [[ -n $args ]]; then + opts="${opts} ${args}" + fi + else + opts="${args}" + fi + + add_bls_fragment "${kernel}" "${title}" "${opts}" "${initrd}" \ + "${extra_initrd}" +fi + +if [[ -n $remove_kernel ]]; then + remove_bls_fragment "${remove_kernel}" +fi + +if [[ -n $update_kernel ]]; then + update_bls_fragment "${update_kernel}" "${remove_args}" "${args}" "${initrd}" +fi + +if [[ -n $set_default ]]; then + set_default_bls "${set_default}" +fi + +exit 0 diff --git a/grubby.spec b/grubby.spec index c48f3aa..e623107 100644 --- a/grubby.spec +++ b/grubby.spec @@ -1,6 +1,6 @@ Name: grubby Version: 8.40 -Release: 14%{?dist} +Release: 15%{?dist} Summary: Command line tool for updating bootloader configs License: GPLv2+ URL: https://github.com/rhinstaller/grubby @@ -9,6 +9,7 @@ URL: https://github.com/rhinstaller/grubby # git archive --format=tar --prefix=grubby-%%{version}/ HEAD |bzip2 > grubby-%%{version}.tar.bz2 # Source0: %%{name}-%%{version}.tar.bz2 Source0: https://github.com/rhboot/grubby/archive/%{version}-1.tar.gz +Source1: grubby-bls Patch1: drop-uboot-uImage-creation.patch Patch2: 0001-Change-return-type-in-getRootSpecifier.patch Patch3: 0002-Add-btrfs-subvolume-support-for-grub2.patch @@ -35,6 +36,8 @@ and zipl (s390) boot loaders. It is primarily designed to be used from scripts which install new kernels and need to find information about the current boot environment. +%global debug_package %{nil} + %prep %setup -q -n grubby-%{version}-1 @@ -58,27 +61,29 @@ make test %install make install DESTDIR=$RPM_BUILD_ROOT mandir=%{_mandir} -%postun -if [ "$1" = 0 ] ; then - arch=$(uname -m) - if [[ $arch == "s390x" ]]; then - command=zipl-switch-to-blscfg - else - command=grub2-switch-to-blscfg - fi +rm %{buildroot}/sbin/installkernel +rm %{buildroot}/sbin/new-kernel-pkg +cp %{SOURCE1} %{buildroot}/sbin/grubby + +%package bls +Summary: Command line tool for updating BootLoaderSpec files +Obsoletes: %{name} < 8.40-15 +BuildArch: noarch - $command --backup-suffix=.rpmsave &>/dev/null || : -fi +%description bls +This package provides a grubby wrapper that manages BootLoaderSpec files and is +meant to only be used for legacy compatibility users with existing grubby users. -%files +%files bls %{!?_licensedir:%global license %%doc} %license COPYING -/sbin/installkernel -/sbin/new-kernel-pkg /sbin/grubby %{_mandir}/man8/*.8* %changelog +* Fri Jul 13 2018 Javier Martinez Canillas - 8.40-15 +- Add a grubby-bls package that contains grubby-bls script and obsoletes grubby + * Fri Jul 13 2018 Fedora Release Engineering - 8.40-14 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild