#!/bin/sh
#
# linbo_start
# thomas@linuxmuster.net
# 20250801
#


#### functions begin ####

usage(){
  local RC="$1"
  echo
  echo "Starts os defined by start.conf position number or root partition."
  echo
  echo "Usage: linbo_start <#> | [cache] <root> | [help]"
  echo
  echo "\"cache\" parameter is deprecated and will be ignored."
  echo
  exit "$RC"
}


# request macct file to invoke samba password hash ldap upload stuff on the server
# invoke_macct imagebase
invoke_macct(){
  [ -z "$1" ] && return 1
  local imagebase="$1"
  local item
  local imagemacct
  # get image filename from start.conf
  for item in qdiff qcow2; do
    if [ -s "/cache/${imagebase}.${item}" ]; then
      imagemacct="${imagebase}.${item}.macct"
      echo "Initiating machine password update on server $LINBOSERVER ..."
      linbo_download "$imagemacct" &> /dev/null
      return 0
    fi
  done
  return 1
}

#### functions end ####


# print help
[ -z "$1" -o "$1" = "help" ] && usage 0

# get environment
source /usr/share/linbo/shell_functions
echo "### $timestamp $(basename "$0") $@ ###"

# check os number
if isinteger "$1"; then
  source /conf/os.$1 &> /dev/null || usage 1

# check root partition
elif [ -b "$1" ]; then
  [ "$cache" = "$1" ] && shift
  source /conf/os.$(osnr_startconf "$1") &> /dev/null || usage 1

else
  usage 1

fi

# strip leading slash
kernel="${kernel#/}"
initrd="${initrd#/}"

# partition or isofile
ext="$(tolower "${baseimage##*.}")"
if [ "$ext" = "iso" ]; then
  bootpart="/cache/$baseimage"
  cd /cache
  # get iso from server, if not yet present
  linbo_download_image "$baseimage"
  cd
else
  bootpart="$root"
fi

[ -d /sys/firmware/efi/efivars ] && efi="true"
startflag="/tmp/.start"
touch "$startflag"

# get root partition label
label="$(lsblk -n -o LABEL "$root")"
# evaluate label
if [ -n "$label" ]; then
  blkid --label "$label" &> /dev/null || label=""
fi

# mount os partition or isofile
mntpnt="/mnt"
if linbo_mount "$bootpart" "$mntpnt"; then
  if [ -e "$mntpnt/$kernel" ]; then
    echo "Found kernel $kernel on partition $root."
    # add root to append string
    if [ "$ext" = "iso" ]; then
      append="quiet splash noeject noprompt findiso=$baseimage iso-scan/filename=/$baseimage $append"
    elif [ -n "$label" ]; then
      append="root=LABEL=$label $append"
    else
      append="root=$root $append"
    fi
    # load kernel for later warmstart
    if warmstart; then
      kexec --type="bzImage64" --append="$append" --initrd="/mnt/$initrd" --load "/mnt/$kernel" || \
        kexec --append="$append" --initrd="/mnt/$initrd" --load "/mnt/$kernel" || export NOWARMSTART='yes'
    else
      export FORCEGRUB="yes"
    fi
  else
    echo "No kernel $kernel on partition $root. Using \"auto\"."
    kernel="auto"
    export NOWARMSTART='yes'
  fi

  # install/update grub/efi stuff if cache is mounted
  if linbo_mountcache &> /dev/null; then
    # prepare reboot if no warmstart
    if ! warmstart; then
      mk_boot "$root" "$kernel" "$initrd" "$append" ; RC="$?"
      [ "$RC" = "0" ] || exit 1
    fi
    # update linuxmuster-win scripts and install start tasks
    [ "$(linbo_fstype "$root")" = "ntfs" -a -d /cache/linuxmuster-win ] && update_win "$root"
  else
    echo "Unable to mount /cache."
    exit 1
  fi

  # pre start stuff
  if [ -s /mnt/.linbo ]; then
    imagebase="$(cat /mnt/.linbo)"
    prestart="${imagebase}.prestart"
    if ! localmode; then
      linbo_download "images/$imagebase/$prestart" &> /dev/null
      [ -e "$prestart" ] || linbo_download "$prestart" &> /dev/null
      if [ -e "$prestart" ]; then
        mv "$prestart" /cache
      else
        rm -f "/cache/$prestart"
      fi
    fi
    [ -s "/cache/$prestart" ] && source "/cache/$prestart"
  fi
else
  echo "Unable to mount operating system partition $bootpart." >&2
  umount /mnt
  exit 1
fi

# sets machine password on server
invoke_macct "$imagebase"

sync
umount /mnt
sendlog

# skip os boot if FAKESTART is set
[ -n "$FAKESTART" ] && exit 0

# start os directly or reboot into it
if warmstart; then
  kexec -e || exit 1
else
  reboot -f
fi
