chimeraos icon indicating copy to clipboard operation
chimeraos copied to clipboard

Notify when an OS update is available, allow user to initiate updates and show download/installation progress

Open alkazar opened this issue 2 years ago • 6 comments

This is blocked until big picture mode is removed.

alkazar avatar May 12 '22 02:05 alkazar

Possibly relevant files:

From jupiter-hw-support:

/usr/bin/polkit-helpers/steamos_update

#!/bin/bash

set -eu

if [[ $EUID -ne 0 ]];
then
    exec pkexec --disable-internal-agent "$0" "$@"
fi

exec /usr/bin/steamos-update "$@"

From steamos-customizations-jupiter:

/usr/bin/steamos-update-os

#!/bin/bash
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# vim: et sts=4 sw=4

#  SPDX-License-Identifier: LGPL-2.1+
#
#  Copyright © 2019-2020 Collabora Ltd.
#  Copyright © 2019-2020 Valve Corporation.
#
#  This file is part of steamos-customizations.
#
#  steamos-customizations is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation; either version 2.1 of the License,
#  or (at your option) any later version.

set -e
set -u

usage() {
    cat <<EOF
Usage: ${0##*/} now [ATOMUPD-OPTIONS]
       ${0##*/} after-reboot
       ${0##*/} -h|--help
EOF
}

update_now() {
    if ! steamos-atomupd-client "$@"; then
        echo "SteamOS cannot be updated!" >&2
        sleep 5s
    fi

    if grep -q 'systemd.unit=steamos-update-os.target' /proc/cmdline; then
        steamos-logger "Rebooting in 5 seconds...";
        sleep 5s
        reboot
    else
        echo "Reboot to run the new version of SteamOS." >&2
    fi
}

update_after_reboot() {
    /usr/sbin/steamos-set-bootmode update-other
    echo "Reboot to start the update of SteamOS." >&2
}

if [[ $# -eq 0 ]]; then
    usage
    exit 1
fi

case "$1" in
    (now)
        shift
        update_now "$@"
        ;;
    (after-reboot)
        shift
        update_after_reboot
        ;;
    (-h|--help)
        usage
        exit 0
    (*)
        usage
        exit 1
        ;;
esac

/usr/lib/steamos/steamos-update-os-progress

#!/bin/bash
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# vim: et sts=4 sw=4

#  SPDX-License-Identifier: LGPL-2.1+
#
#  Copyright © 2020 Collabora Ltd.
#  Copyright © 2020 Valve Corporation.
#
#  This file is part of steamos-customizations.
#
#  steamos-customizations is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation; either version 2.1 of the License,
#  or (at your option) any later version.

set -e
set -u

progress() {
    if plymouth --ping 2>/dev/null
    then
        plymouth system-update --progress "$1"
    fi
    echo "$1%"
}

while [[ "$#" -ne 0 ]]
do
    if [[ "$1" =~ ^(-h|--help)$ ]]
    then
        echo "Usage: ${0##*/} [-h|--help] [--debug]"
        exit 0
    elif [[ "$1" == "--debug" ]]
    then
        debug=true
    else
        echo "$1: Invalid argument" >&2
        exit 1
    fi
    shift
done

while read -r -a words
do
    # Empty line: skip it!
    if [[ "${#words[@]}" -eq 0 ]]
    then
        continue
    fi

    # Print the journal to stderr
    if [[ "${debug:-}" ]]
    then
        echo "${words[@]}" >&2
    fi

    # Slot needs to be updated with /run/rauc/bundle/*.img.caibx
    if [[ "${words[0]}" =~ "Slot" ]]
    then
        slot="${words[6]##*/}"
        slot="${slot%*.img.caibx}"
    # Seeding... ##%
    elif [[ "${words[0]}" =~ "seeding" ]] && [[ "${slot:-}" == "rootfs" ]]
    then
        if [[ "${words[1]}" =~ [0-9]+%$ ]]
        then
            percentage="${words[1]%\%}"
            percentage="$(((percentage*25*90/100)/100))"
            percentage="$((percentage+5))"
            progress "$percentage" "${words[@]}"
        fi
    # Downloading chunks ##%
    elif [[ "${words[0]}" == "downloading" ]] && [[ "${slot:-}" == "rootfs" ]]
    then
        if [[ "${words[2]}" =~ [0-9]+%$ ]]
        then
            percentage="${words[2]%\%}"
            percentage="$(((percentage*75*90/100)/100))"
            percentage="$((percentage+5+(25*90/100)))"
            progress "$percentage" "${words[@]}"
        fi
    # installing: ...: All slots updated
    elif [[ "${words[0]}" == "installing" ]] &&
         [[ "${words[*]:2}" == "All slots updated" ]]
    then
        percentage="95"
        progress "$percentage" "${words[@]}"
    # installing: ...: finished
    elif [[ "${words[0]}" == "installing" ]] &&
         [[ "${words[*]:2}" == "finished" ]]
    then
        percentage="99"
        progress "$percentage" "${words[@]}"
    # installing: ...: started
    elif [[ "${words[0]}" == "installing" ]] &&
         [[ "${words[*]:2}" == "started" ]]
    then
        if plymouth --ping 2>/dev/null
        then
            plymouth change-mode --system-upgrade
            percentage="0"
            progress "$percentage" "${words[@]}"
        fi
    # installing: ...: failed: ...
    elif [[ "${words[0]}" == "installing" ]] &&
         [[ "${words[*]:2}" =~ "failed: " ]]
    then
        if plymouth --ping 2>/dev/null
        then
            plymouth change-mode --boot-up
            plymouth display-message --text="Error: System upgrade failed!"
        fi
    # installing: ...: succeeded
    elif [[ "${words[0]}" == "installing" ]] &&
         [[ "${words[*]:2}" == "succeeded" ]]
    then
        percentage="100"
        progress "$percentage" "${words[@]}"
        if plymouth --ping 2>/dev/null
        then
            plymouth change-mode --boot-up
            plymouth display-message --text="System upgrade completed!"
        fi
    # Stopped Rauc Update Service.
    elif [[ "${words[*]}" == "Stopped Rauc Update Service." ]]
    then
        if plymouth --ping 2>/dev/null
        then
            plymouth change-mode --boot-up
            plymouth display-message --text=
        fi
    # Started Rauc Update Service.
    elif [[ "${words[*]}" == "Started Rauc Update Service." ]]
    then
        if plymouth --ping 2>/dev/null
        then
            plymouth change-mode --system-upgrade
            percentage="0"
            progress "$percentage" "${words[@]}"
        fi
    fi
done < <(journalctl --unit rauc.service --follow --output cat)

pastaq avatar May 12 '22 05:05 pastaq

From @pastaq post. Seems like plymouth would be a nice integration to have to notify the user about updates. And also we can use it for the chimera-data download step before quitting plymouth. What do you think? We could have a chimera-customizations package to ship all our system specific libraries and quirks.

Samsagax avatar May 13 '22 15:05 Samsagax

From @pastaq post. Seems like plymouth would be a nice integration to have to notify the user about updates. And also we can use it for the chimera-data download step before quitting plymouth. What do you think? We could have a chimera-customizations package to ship all our system specific libraries and quirks.

It is an interesting idea, but I am pretty negative on plymouth. It has caused constant problems when we were using it in the past.

alkazar avatar May 26 '22 12:05 alkazar

I know your pain. But since Nvidia was the worst offender on non-kms/drm mode setting then it should work now. We just need drm and KMS to work anyway.

Samsagax avatar May 26 '22 14:05 Samsagax

Is this still relevant?

If you use DeckUI. Your updater should be invoked in /usr/bin/steamos-update

How does Steam Deck detect update status?

When pressing "Check For Updates", steamclient64 invokes steamos-update check

Which should return:

a) exit status 0 and echo-ed text when update is available b) exit status 7 when system is up-to-date c) Anything else or exit status 1 reports an "Update error" popup

In case of (a):

Steam Deck prepares for updating by showing "Apply" button and preparing command steamos-update now for use, by this point i'd suggest you to create an persistence sentinel, to send automatic "Yes, i will update NOW" reply on "Apply" button

Update detected: image

Start update: image

After pressing 'Apply' button:

Following variable is creating for storing progressbar status: $percentage Example entry in $percentage: n% (Make sure to append percent sign, else your status won't be rendered in DeckUI)

Here starts your entire updater script which can invoke possibly everything you want, quite literally

When your updater finishes updating, make sure you exit without any status, if any status would be set, an entire different sequence will be initiated in Deck client logic, which relates to cases mentioned above.

If you need any help, be sure to reply to this comment/PM me ^^

theVakhovskeIsTaken avatar Jul 18 '22 20:07 theVakhovskeIsTaken

@theVakhovskeIsTaken thanks for that information, that will be useful.

alkazar avatar Jul 26 '22 11:07 alkazar

I think this is now supported. Also, there is a new package in Valve's repository that seems to be a wrapper around notifyd. I'll look into it to have a complete solution.

Samsagax avatar Feb 07 '23 15:02 Samsagax

This is implemented in v39

alkazar avatar Feb 18 '23 17:02 alkazar