Blob Blame History Raw
#!/bin/bash -e

Red="$(tput setaf 1)$(tput bold)"
red=$(tput setaf 1)
grn=$(tput setaf 2)
brn=$(tput setaf 3)
blu=$(tput setaf 4)
nrm=$(tput sgr0)

sn="${0##*/}"
usage() {
    printf "${Red}usage:${nrm} %s [-h] [-g <kgraft_prj> | -G] [-t tbranch] branch\n" "$sn"
    #rintf "usage: "
    printf "       Arg          Example\n"
    printf "       -g kgraft_prj   SLE15-SP5_Update_9\n"
    printf "       -G              no livepatch submission (e.g. when resubmitting)\n"
    printf "       -t tbranch      SLE15-SP5 (specify target when branch is a user branch)\n"
    printf "          branch       SLE15-SP5\n"
}

OPTS=$(getopt -o g:Gt:h -n "$sn" -- "$@")
eval set -- "$OPTS"
unset OPTS

nolp=
while true ; do
    case "$1" in
    '-g')
        lp_proj="$2"
        shift 2
    ;;
    '-G')
        nolp=1
        shift 1
    ;;
    '-t')
        tbranch="$2"
        shift 2
    ;;
    '-h')
        usage >&2
        exit 0
    ;;
    '--')
        shift
        break
    ;;
    *)
        printf "${Red}Args parsing error${nrm}\n" >&2
        exit 1
        ;;
    esac
    continue
done
if [ $# -ne 1 ]; then
    usage >&2
    exit 1
elif [ -n "$lp_proj" -a -n "$nolp" ] ; then
    printf "${Red}-g and -G cannot be combined.${nrm}\n" >&2
    exit 1
fi

branch="$1"
tbranch="${tbranch:-${branch}}"
if [[ "${tbranch}" =~ / ]] ; then
    printf "${Red}Specify target branch explicitly without user prefix${nrm}\n" >&2
    exit 1
fi

OSC_DIR="${OSC_DIR:-/tmp}"
OSC="osc -A https://api.suse.de/"
prod="${tbranch%-LTSS}"
target="SUSE:SLE-${prod#SLE}:Update" # this may be a parameter in future
prj="Devel:Kernel:${tbranch}:Submit"
kgraft_dir="Devel:kGraft:patches"

if [ ! -d "$KSOURCE_GIT" ]; then
    printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$KSOURCE_GIT" >&2
    echo "Please set KSOURCE_GIT to the location of local kernel-source repository." >&2
    exit 1
fi
if [ ! -d "$OSC_DIR" ]; then
    printf "${Red}Error: directory '%s' does not exist${nrm}\n" "$OSC_DIR" >&2
    echo "Please set OSC_DIR to a directory to use for OBS/IBS checkouts." >&2
    exit 1
fi
if ! $OSC api /about >/dev/null ; then
    echo "${Red}Error: Cannot login to OBS${nrm}" >&2
    printf "Check your SSH key setup in .oscrc for '%s'\n" "$OSC" >&2
    exit 1
fi

cd "$KSOURCE_GIT"
git checkout "$branch"
git pull --ff-only >/dev/null
version=$(rpm/compute-PATCHVERSION.sh --patches .)
if [ -n "$lp_proj" ] ; then
    upd="${lp_proj##*_}"
else
    upd=$($OSC se -s --project "${kgraft_dir}:${prod}" \
        | sed -rne "/^${kgraft_dir}:${prod}_Update_[[:digit:]]+\$/ { s/^.*_// ; p }" \
        | sort -n | tail -1)
    lp_proj="${prod}_Update_${upd}"
fi

printf "Product:           ${blu}%s${nrm}\n" "$prod"
printf "Target branch:     ${blu}%s${nrm}\n" "$tbranch"
printf "Submission branch: ${blu}%s${nrm}\n" "$branch"
printf "Commit:            ${grn}%s${nrm}\n" \
  $(git --no-pager show -s --pretty='%h' "$branch")
printf "Version:           ${blu}%s${nrm}\n" "$version"
if [ -z "$nolp" ] ; then
    printf "Kgraft prj:        ${blu}%s${nrm}\n" "$lp_proj"
fi
echo

if ! git merge-base --is-ancestor "$branch" "$tbranch"; then
    printf "${Red}Warning: %s not merged into %s${nrm}\n\n" "$branch" "$tbranch" >&2
fi

printf "${grn}* Delete old %s IBS project...${nrm}\n" "$prj"
$OSC rdelete -f -r -m "drop old maintenance update" "$prj" || printf "Note: %s likely does not exist\n"
rm -rf "${OSC_DIR}/${prj}"

echo "${grn}* Clean WC and pack kernel-source...${nrm}"
cd $KSOURCE_GIT
git clean -dxi
scripts/tar-up.sh
printf "${grn}* Create %s and upload kernel-source to IBS...${nrm}\n" "$prj"
scripts/osc_wrapper upload --ibs --debug "$prj"

cd "$OSC_DIR"
chanprj="SUSE:Channels"
smlp="SLE-Module-Live-Patching_${prod#SLE}_"
archs=''
while read a; do
    archs="${archs}${archs:+ }${a#${smlp}}"
done < <($OSC ls "$chanprj" | egrep "^$smlp")

if [ -z "$nolp" ] ; then
    kgraft_prj="${kgraft_dir}:${lp_proj}"
    printf "${grn}* Copy kernel-livepatch-%s_Update_%u package...${nrm}\n" \
        "$prod" "$upd"
    $OSC copypac "$kgraft_prj" \
        "kernel-livepatch-${prod}_Update_${upd}" "$prj"

    inc_upd="s/${prod}_Update_[[:digit:]]+/${prod}_Update_${upd}/g"
    fixme="s/(${version//./_})-[[:digit:]_]+-/\1-FIXME-/"
    printf "${grn}* Branch %s* and update _channel...${nrm}\n" "$smlp"
    for a in $archs; do
        printf "${grn}  * architecture %s...${nrm}\n" "$a"
        $OSC bco "$chanprj" "${smlp}${a}" "$prj"
        pushd "${prj}/${smlp}${a}" >/dev/null
        # Copy last bunch packages of given product, update their versions and
        # paste them in one block after last package
        last_pkg=$(grep  -E "${prod}_Update_[[:digit:]]+" _channel | tail -1)
        last_upd=$(echo "$last_pkg" | grep -oE "${prod}_Update_[[:digit:]]+" | tail -1)
        prev_pkgs=$(grep -E "${last_upd}" _channel)
        new_pkgs=$(echo -n "$prev_pkgs" | sed -re "${inc_upd} ; ${fixme} ; s/\$/\\\/")
        # Assume no '|' in XML rows, escaping magic not to insert a trailing newline
        sed -re "\|${last_pkg}| a \\
    ${new_pkgs%\\}
    " -i _channel
        $OSC commit -m "update channel file"
        popd >/dev/null
    done
fi

echo -e "\n\nTo submit the update, run\n"
printf "${red}  %s mr %s \\\\\n" "$OSC" "$prj"
printf "      kernel-source \\\\\n"
if [ -z "$nolp" ] ; then
    printf "      kernel-livepatch-%s_Update_%u \\\\\n" "$prod" "$upd"
    while read p; do
        printf "      %s \\\\\n" "$p"
    done < <($OSC ls "$prj" | egrep "^$smlp")
fi
printf "      %s${nrm}\n\n" "$target"