Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offer rollback option for interactive upgrading #11771

Merged
merged 19 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add rollback mechanism
  • Loading branch information
nicok1 committed Jan 19, 2024
commit 894bc9af285702c08a415d763c328a84be0cc808
30 changes: 30 additions & 0 deletions cmd/check_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cmd

import (
_ "embed"
"os"

"github.com/spf13/cobra"
)

var checkconfig = &cobra.Command{
Use: "checkconfig",
Short: "Check config file for errors",
Run: runConfigCheck,
}

func init() {
rootCmd.AddCommand(checkconfig)
}

func runConfigCheck(cmd *cobra.Command, args []string) {
cfgErr := loadConfigFile(&conf)

if cfgErr != nil {
log.FATAL.Println("Config not valid")
log.FATAL.Println(cfgErr)
os.Exit(1)
} else {
log.INFO.Println("Config is valid")
}
}
249 changes: 148 additions & 101 deletions packaging/scripts/postinstall.sh
Original file line number Diff line number Diff line change
@@ -1,101 +1,148 @@
#!/bin/sh
set -e

USER_CHOICE_CONFIG="/etc/evcc-userchoices.sh"
ETC_SERVICE="/etc/systemd/system/evcc.service"
USR_LOCAL_BIN="/usr/local/bin/evcc"
RESTART_FLAG_FILE="/tmp/.restartEvccOnUpgrade"

# Usage: askUserKeepFile <file>
# Return: 1 = keep, 0 = delete
askUserKeepFile() {
while true; do
echo "Shall '$1' be deleted? [Y/n]: "
read answer
case "$answer" in
n*|N*)
echo "Ok. We will keep that file. Keep in mind that you may need to alter it if any changes are done upstream. Your answer is saved for the future."
return 1
;;
y*|Y*|"")
echo "The file will be deleted."
return 0
;;
*)
;;
esac
done
}

if [ "$1" = "configure" ]; then
KEEP_ETC_SERVICE=0
KEEP_USR_LOCAL_BIN=0
# If the user once said that he wants to keep the files
# this choice file will include that information
# and the user will no longer be asked if he wants to keep it
if [ -f "$USER_CHOICE_CONFIG" ]; then
. "$USER_CHOICE_CONFIG"
fi

# If the user previously decided that he doesn't want to keep
# the files or if it's the first time, aks whether he want's to
# keep the file
if [ -f "$ETC_SERVICE" ] && [ "$KEEP_ETC_SERVICE" -eq 0 ]; then
echo "An alternate service file was detected under '$ETC_SERVICE'."
echo "This is probably due to a previous manual installation."
echo "You probably want to delete this file now. Your evcc configuration stays untouched!"
askUserKeepFile "$ETC_SERVICE" || KEEP_ETC_SERVICE=$?
fi
if [ -f "$USR_LOCAL_BIN" ] && [ "$KEEP_USR_LOCAL_BIN" -eq 0 ]; then
echo "An alternate evcc binary was detected under '$USR_LOCAL_BIN'."
echo "This is probably due to a previous manual installation."
echo "You probably want to delete this file now. Your evcc configuration stays untouched!"
askUserKeepFile "$USR_LOCAL_BIN" || KEEP_USR_LOCAL_BIN=$?
fi
# Save the user decision
cat > "$USER_CHOICE_CONFIG" <<EOF
#!/bin/sh
KEEP_ETC_SERVICE=$KEEP_ETC_SERVICE
KEEP_USR_LOCAL_BIN=$KEEP_USR_LOCAL_BIN
EOF

# Execute the user decision
if [ -f "$ETC_SERVICE" ] && [ "$KEEP_ETC_SERVICE" -eq 0 ]; then
echo "Deleting old service file '$ETC_SERVICE'"
rm -v "$ETC_SERVICE"
fi

if [ -f "$USR_LOCAL_BIN" ] && [ "$KEEP_USR_LOCAL_BIN" -eq 0 ]; then
echo "Deleting old evcc binary '$USR_LOCAL_BIN'"
rm -v "$USR_LOCAL_BIN"
fi
fi

if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask evcc.service >/dev/null || true

# was-enabled defaults to true, so new installations run enable.
if deb-systemd-helper --quiet was-enabled evcc.service; then
# Enables the unit on first installation, creates new
# symlinks on upgrades if the unit file has changed.
deb-systemd-helper enable evcc.service >/dev/null || true
else
# Update the statefile to add new symlinks (if any), which need to be
# cleaned up on purge. Also remove old symlinks.
deb-systemd-helper update-state evcc.service >/dev/null || true
fi

# Restart only if it was already started
if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
if [ -f $RESTART_FLAG_FILE ]; then
deb-systemd-invoke start evcc.service >/dev/null || true
rm $RESTART_FLAG_FILE
elif [ -n "$2" ]; then
deb-systemd-invoke try-restart evcc.service >/dev/null || true
else
deb-systemd-invoke start evcc.service >/dev/null || true
fi
fi
fi
#!/bin/sh
set -e

USER_CHOICE_CONFIG="/etc/evcc-userchoices.sh"
ETC_SERVICE="/etc/systemd/system/evcc.service"
USR_LOCAL_BIN="/usr/local/bin/evcc"
RESTART_FLAG_FILE="/tmp/.restartEvccOnUpgrade"



# Call /usr/bin/evcc checkconfig and capture the output
# if exit code is 0, then remove /tmp/oldevcc
# if exit code is not 0, then fail installation with error message and copy /tmp/oldevcc back to /etc/evcc
# if /tmp/oldevcc does not exist, then do nothing
failInstallation=0

if [ -d /tmp/oldevcc ]; then
checkConfigOutput=$(/usr/bin/evcc checkconfig)
if [ $? -eq 0 ]; then
rm -rf /tmp/oldevcc
else
echo "--------------------------------------------------------------------------------"
echo "ERROR: your evcc configuration is not compatible with the new version. Please consider reading the release notes: https://github.com/evcc-io/evcc/releases"
echo "checkconfig Output:"
echo $checkConfigOutput
echo "--------------------------------------------------------------------------------"
while true; do
echo "Do you want to keep your old version? [Y/n]: "
read choice
case "$choice" in
n*|N*|"")
echo "Ok. We will keep your old version. Your evcc configuration stays untouched!"
break
;;
y*|Y*)
echo "The old version will be restored."
cp -r /tmp/oldevcc /etc/evcc
failInstallation=1
break
;;
*)
;;
esac
fi
fi





# Usage: askUserKeepFile <file>
# Return: 1 = keep, 0 = delete
askUserKeepFile() {
while true; do
echo "Shall '$1' be deleted? [Y/n]: "
read answer
case "$answer" in
n*|N*)
echo "Ok. We will keep that file. Keep in mind that you may need to alter it if any changes are done upstream. Your answer is saved for the future."
return 1
;;
y*|Y*|"")
echo "The file will be deleted."
return 0
;;
*)
;;
esac
done
}

if [ "$1" = "configure" ]; then
KEEP_ETC_SERVICE=0
KEEP_USR_LOCAL_BIN=0
# If the user once said that he wants to keep the files
# this choice file will include that information
# and the user will no longer be asked if he wants to keep it
if [ -f "$USER_CHOICE_CONFIG" ]; then
. "$USER_CHOICE_CONFIG"
fi

# If the user previously decided that he doesn't want to keep
# the files or if it's the first time, aks whether he want's to
# keep the file
if [ -f "$ETC_SERVICE" ] && [ "$KEEP_ETC_SERVICE" -eq 0 ]; then
echo "An alternate service file was detected under '$ETC_SERVICE'."
echo "This is probably due to a previous manual installation."
echo "You probably want to delete this file now. Your evcc configuration stays untouched!"
askUserKeepFile "$ETC_SERVICE" || KEEP_ETC_SERVICE=$?
fi
if [ -f "$USR_LOCAL_BIN" ] && [ "$KEEP_USR_LOCAL_BIN" -eq 0 ]; then
echo "An alternate evcc binary was detected under '$USR_LOCAL_BIN'."
echo "This is probably due to a previous manual installation."
echo "You probably want to delete this file now. Your evcc configuration stays untouched!"
askUserKeepFile "$USR_LOCAL_BIN" || KEEP_USR_LOCAL_BIN=$?
fi
# Save the user decision
cat > "$USER_CHOICE_CONFIG" <<EOF
#!/bin/sh
KEEP_ETC_SERVICE=$KEEP_ETC_SERVICE
KEEP_USR_LOCAL_BIN=$KEEP_USR_LOCAL_BIN
EOF

# Execute the user decision
if [ -f "$ETC_SERVICE" ] && [ "$KEEP_ETC_SERVICE" -eq 0 ]; then
echo "Deleting old service file '$ETC_SERVICE'"
rm -v "$ETC_SERVICE"
fi

if [ -f "$USR_LOCAL_BIN" ] && [ "$KEEP_USR_LOCAL_BIN" -eq 0 ]; then
echo "Deleting old evcc binary '$USR_LOCAL_BIN'"
rm -v "$USR_LOCAL_BIN"
fi
fi

if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask evcc.service >/dev/null || true

# was-enabled defaults to true, so new installations run enable.
if deb-systemd-helper --quiet was-enabled evcc.service; then
# Enables the unit on first installation, creates new
# symlinks on upgrades if the unit file has changed.
deb-systemd-helper enable evcc.service >/dev/null || true
else
# Update the statefile to add new symlinks (if any), which need to be
# cleaned up on purge. Also remove old symlinks.
deb-systemd-helper update-state evcc.service >/dev/null || true
fi

# Restart only if it was already started
if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
if [ -f $RESTART_FLAG_FILE ]; then
deb-systemd-invoke start evcc.service >/dev/null || true
rm $RESTART_FLAG_FILE
elif [ -n "$2" ]; then
deb-systemd-invoke try-restart evcc.service >/dev/null || true
else
deb-systemd-invoke start evcc.service >/dev/null || true
fi
fi
fi

# Fail installation if checkconfig command failed and the user decided to keep the old version to inform package manager about keeping the old version
if [ failInstallation -eq 1 ]; then
exit 1
fi
37 changes: 20 additions & 17 deletions packaging/scripts/postremove.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
set -e

if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
fi

if [ "$1" = "remove" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper mask evcc.service >/dev/null || true
fi
fi

if [ "$1" = "purge" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge evcc.service >/dev/null || true
deb-systemd-helper unmask evcc.service >/dev/null || true
fi
set -e

if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
fi

if [ "$1" = "remove" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper mask evcc.service >/dev/null || true
fi
fi

if [ "$1" = "purge" ]; then
if [ -d "/tmp/oldevcc" ]; then
rm -rf "/tmp/oldevcc"
fi
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge evcc.service >/dev/null || true
deb-systemd-helper unmask evcc.service >/dev/null || true
fi
fi
Loading