greatly improved upgrade system
This commit is contained in:
@@ -39,24 +39,27 @@ export UPDT_URL="$BASE_URL/raw/branch/master"
|
|||||||
export ARCH_URL="$BASE_URL/archive/master.tar.gz"
|
export ARCH_URL="$BASE_URL/archive/master.tar.gz"
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Check for profile updates
|
# Check whether a newer profile version is available
|
||||||
# Usage: check_updates [-q]
|
# Usage: check_updates [-q]
|
||||||
# If -q is specified, the function will operate in quiet mode (internal use only)
|
# If -q is specified, the function will operate in quiet mode (internal use only)
|
||||||
check_updates()
|
check_updates()
|
||||||
{
|
{
|
||||||
local quiet=0
|
local quiet=0 result=5 PARSED
|
||||||
local PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
|
local vfile="" lastver=""
|
||||||
|
|
||||||
|
PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
disp E "Invalid options, use \"check_updates --help\" to display usage."
|
disp E "Invalid options, use \"check_updates --help\" to display usage."
|
||||||
return 1
|
return 2
|
||||||
fi
|
fi
|
||||||
eval set -- "$PARSED"
|
eval set -- "$PARSED"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-h|--help)
|
-h|--help)
|
||||||
printf "check_updates: Check for new versions.\n\n"
|
printf "check_updates: Check whether a newer profile version is available.\n\n"
|
||||||
printf "Usage: check_updates\n"
|
printf "Usage: check_updates [-q|--quiet]\n"
|
||||||
|
printf "This command only checks availability; it does not modify the installation.\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
-q|--quiet)
|
-q|--quiet)
|
||||||
@@ -73,28 +76,35 @@ check_updates()
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
(( $quiet != 1 )) && disp I "Checking for updates..."
|
(( quiet != 1 )) && disp I "Checking for updates..."
|
||||||
local vfile="/tmp/version"
|
|
||||||
wget "$UPDT_URL/version" -O $vfile >/dev/null 2>&1 || {
|
vfile=$(mktemp /tmp/profile_version.XXXXXX) || {
|
||||||
disp E "Can't download version file, impossible to proceed!"
|
disp E "Failed to create a temporary file."
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
|
||||||
|
dwl "$UPDT_URL/version" "$vfile" >/dev/null 2>&1 || {
|
||||||
|
rm -f "$vfile"
|
||||||
|
disp E "Cannot download version file; unable to continue."
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ -s $vfile ]]; then
|
if [[ -s $vfile ]]; then
|
||||||
local lastver=$(cat $vfile)
|
lastver=$(<"$vfile")
|
||||||
if [[ $lastver != $PROFVERSION ]]; then
|
if [[ "$lastver" != "$PROFVERSION" ]]; then
|
||||||
disp I "You have version $PROFVERSION installed. Version $lastver is available."
|
disp I "Installed: $PROFVERSION. Available: $lastver."
|
||||||
(( $quiet != 1 )) && disp I "You should upgrade to last version when possible."
|
(( quiet != 1 )) && disp I "You should upgrade when possible."
|
||||||
result=1
|
result=1
|
||||||
else
|
else
|
||||||
(( $quiet != 1 )) && disp I "Your version is up-to-date."
|
(( quiet != 1 )) && disp I "Your version is up-to-date."
|
||||||
result=0
|
result=0
|
||||||
fi
|
fi
|
||||||
rm -f $vfile
|
rm -f "$vfile"
|
||||||
else
|
else
|
||||||
disp E "Impossible to read temporary file, impossible to proceed."
|
rm -f "$vfile"
|
||||||
|
disp E "Temporary file is unreadable; unable to continue."
|
||||||
fi
|
fi
|
||||||
unset lastver vfile
|
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
export -f check_updates
|
export -f check_updates
|
||||||
@@ -102,23 +112,63 @@ export -f check_updates
|
|||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Apply update to profile
|
# Apply the available profile upgrade
|
||||||
# Usage: profile_upgrade
|
# Usage: profile_upgrade [options]
|
||||||
profile_upgrade()
|
profile_upgrade()
|
||||||
{
|
{
|
||||||
local PARSED=$(getopt -o h --long help -n 'profile_upgrade' -- "$@")
|
local PARSED
|
||||||
|
local check_rc=0 dry_run=0 force_git=0 switch_to_git=0
|
||||||
|
local archive_file="" tmpbase="" use_archive=0 branch=""
|
||||||
|
local tmpdir="" archive="" extracted_root=""
|
||||||
|
|
||||||
|
PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@")
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
printf "Invalid options, use \"profile_upgrade --help\" to display usage."
|
disp E "Invalid options, use \"profile_upgrade --help\" to display usage."
|
||||||
return 1
|
return 2
|
||||||
fi
|
fi
|
||||||
eval set -- "$PARSED"
|
eval set -- "$PARSED"
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-h|--help)
|
-h|--help)
|
||||||
printf "profile_upgrade: Upgrade the profile to the latest version.\n\n"
|
printf "profile_upgrade: Apply the available profile upgrade.\n\n"
|
||||||
printf "Usage: profile_upgrade\n"
|
printf "Usage: profile_upgrade [options]\n\n"
|
||||||
|
printf "Options:\n"
|
||||||
|
printf "\t-h, --help\t\tDisplay this help screen\n"
|
||||||
|
printf "\t-f, --file ARCHIVE\tUse a local archive file for the upgrade\n"
|
||||||
|
printf "\t-t, --tmpdir DIR\tCreate the temporary working directory under DIR\n"
|
||||||
|
printf "\t-b, --branch NAME\tUse NAME as the target Git branch\n"
|
||||||
|
printf "\t-g, --switch-to-git\tReplace current install with a fresh Git clone\n"
|
||||||
|
printf "\t-n, --dry-run\t\tDisplay what would be done without changing anything\n"
|
||||||
|
printf "\t-F, --force\t\tDiscard local changes before upgrading\n\n"
|
||||||
|
printf "If the profile is installed from Git, the upgrade uses 'git pull'.\n"
|
||||||
|
printf "Otherwise, it downloads or applies an archive and refreshes the files.\n"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
-f|--file)
|
||||||
|
archive_file="$2"
|
||||||
|
use_archive=1
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-t|--tmpdir)
|
||||||
|
tmpbase="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-b|--branch)
|
||||||
|
branch="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-g|--switch-to-git)
|
||||||
|
switch_to_git=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-n|--dry-run)
|
||||||
|
dry_run=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-F|--force)
|
||||||
|
force_git=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--)
|
--)
|
||||||
shift
|
shift
|
||||||
break
|
break
|
||||||
@@ -130,59 +180,229 @@ profile_upgrade()
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if check_updates -q; then
|
if (( ! use_archive && ! switch_to_git )); then
|
||||||
disp "No update available."
|
check_updates -q
|
||||||
|
check_rc=$?
|
||||||
|
if (( check_rc == 0 )); then
|
||||||
|
disp I "No update available."
|
||||||
return 0
|
return 0
|
||||||
|
elif (( check_rc > 1 )); then
|
||||||
|
disp E "Unable to check whether an update is available."
|
||||||
|
return "$check_rc"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -s $MYPATH/profile.sh ]]; then
|
if [[ ! -s $MYPATH/profile.sh ]]; then
|
||||||
disp E "Installation path detection failed, cannot upgrade automatically."
|
disp E "Install path detection failed; cannot upgrade automatically."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -d $MYPATH/.git ]] && (( use_archive )) && (( ! force_git )); then
|
||||||
|
disp E "Refusing archive upgrade on a Git install without --force."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( switch_to_git )); then
|
||||||
|
command -v git >/dev/null 2>&1 || {
|
||||||
|
disp E "Git is required to switch this install to a Git clone."
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] rm -rf \"$MYPATH\"/.git"
|
||||||
|
disp I "[dry-run] git clone "$BASE_URL" \"$MYPATH\""
|
||||||
|
[[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout "$branch""
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -d $MYPATH/.git ]]; then
|
if [[ -d $MYPATH/.git ]]; then
|
||||||
|
disp W "Git repository already present; no switch is needed."
|
||||||
|
else
|
||||||
|
local backup_dir="${MYPATH}.pre-git.$$.bak"
|
||||||
|
mv "$MYPATH" "$backup_dir" || {
|
||||||
|
disp E "Failed to move current install out of the way."
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
git clone "$BASE_URL" "$MYPATH" || {
|
||||||
|
disp E "Git clone failed; previous install kept in $backup_dir."
|
||||||
|
mv "$backup_dir" "$MYPATH" 2>/dev/null || true
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
[[ -n "$branch" ]] && (
|
||||||
|
cd "$MYPATH" && git checkout "$branch"
|
||||||
|
) || true
|
||||||
|
disp I "Switched installation to Git source."
|
||||||
|
disp I "Previous install kept in $backup_dir."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d $MYPATH/.git ]] && (( ! use_archive )); then
|
||||||
disp I "Git installation detected, applying git pull."
|
disp I "Git installation detected, applying git pull."
|
||||||
pushd "$MYPATH" || {
|
command -v git >/dev/null 2>&1 || {
|
||||||
|
disp E "Git is required for this upgrade but is not available."
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
pushd "$MYPATH" >/dev/null || {
|
||||||
disp E "Failed to change directory to $MYPATH."
|
disp E "Failed to change directory to $MYPATH."
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
git pull || {
|
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
|
||||||
disp E "Git pull failed, upgrade not applyed."
|
disp E "Install directory is not a valid Git working tree."
|
||||||
popd
|
popd >/dev/null || return 1
|
||||||
return 2
|
return 3
|
||||||
}
|
}
|
||||||
disp I "Successfully upgraded using git."
|
if ! git diff --quiet || ! git diff --cached --quiet || [[ -n $(git ls-files --others --exclude-standard) ]]; then
|
||||||
popd
|
if (( force_git )); then
|
||||||
|
disp W "Force mode: local Git changes and untracked files will be lost."
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] git fetch --all --prune"
|
||||||
|
disp I "[dry-run] git reset --hard HEAD"
|
||||||
|
disp I "[dry-run] git clean -fd"
|
||||||
else
|
else
|
||||||
disp I "No Git detected. Downloading and applying upgrade from archive..."
|
git fetch --all --prune || {
|
||||||
local tmpdir="/tmp/profile_upg.$$"
|
disp E "Git fetch failed, upgrade not applied."
|
||||||
mkdir -p "$tmpdir" || {
|
popd >/dev/null || return 1
|
||||||
disp E "Failed to create temporary directory."
|
|
||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
git reset --hard HEAD || {
|
||||||
|
disp E "Git reset failed, upgrade not applied."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
git clean -fd || {
|
||||||
|
disp E "Git clean failed, upgrade not applied."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
disp W "The Git working tree contains local changes."
|
||||||
|
disp W "Consider committing or stashing them before upgrading, or use --force."
|
||||||
|
disp W "Upgrade may fail if the changes conflict with the upgrade."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -n "$branch" ]]; then
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] git fetch origin $branch"
|
||||||
|
disp I "[dry-run] git checkout $branch"
|
||||||
|
else
|
||||||
|
git fetch origin "$branch" || {
|
||||||
|
disp E "Git fetch failed for branch $branch."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
git checkout "$branch" || {
|
||||||
|
disp E "Git checkout failed for branch $branch."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
local archive="$tmpdir/profile.tar.gz"
|
if (( dry_run )); then
|
||||||
wget -q "$ARCH_URL" -O "$archive" || {
|
if [[ -n "$branch" ]]; then
|
||||||
disp E "Failed to download archive."
|
disp I "[dry-run] git pull origin $branch"
|
||||||
rm -rf "$tmpdir"
|
else
|
||||||
|
disp I "[dry-run] git pull"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -n "$branch" ]]; then
|
||||||
|
git pull origin "$branch" || {
|
||||||
|
disp E "Git pull failed, upgrade not applied."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
else
|
||||||
|
git pull || {
|
||||||
|
disp E "Git pull failed, upgrade not applied."
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
disp I "Successfully upgraded using git."
|
||||||
|
fi
|
||||||
|
popd >/dev/null || return 1
|
||||||
|
else
|
||||||
|
if (( use_archive )); then
|
||||||
|
[[ -r "$archive_file" ]] || {
|
||||||
|
disp E "Local archive '$archive_file' is missing or unreadable."
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
disp I "Using local archive $archive_file."
|
||||||
|
else
|
||||||
|
disp W "No Git repo found. Git is the recommended source."
|
||||||
|
disp I "Applying upgrade from archive..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$tmpbase" ]]; then
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] mkdir -p \"$tmpbase\""
|
||||||
|
disp I "[dry-run] mktemp -d \"$tmpbase/profile_upg.XXXXXX\""
|
||||||
|
tmpdir="$tmpbase/profile_upg.DRYRUN"
|
||||||
|
else
|
||||||
|
mkdir -p "$tmpbase" || {
|
||||||
|
disp E "Failed to create temporary directory base $tmpbase."
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
tmpdir=$(mktemp -d "$tmpbase/profile_upg.XXXXXX") || {
|
||||||
|
disp E "Failed to create temp working directory under $tmpbase."
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] mktemp -d /tmp/profile_upg.XXXXXX"
|
||||||
|
tmpdir="/tmp/profile_upg.DRYRUN"
|
||||||
|
else
|
||||||
|
tmpdir=$(mktemp -d /tmp/profile_upg.XXXXXX) || {
|
||||||
|
disp E "Failed to create temporary directory."
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
tar -xzf "$archive" -C "$tmpdir" || {
|
if (( use_archive )); then
|
||||||
disp E "Archive extraction failed."
|
archive="$archive_file"
|
||||||
|
else
|
||||||
|
archive="$tmpdir/profile.tar.gz"
|
||||||
|
if (( dry_run )); then
|
||||||
|
disp I "[dry-run] dwl \"$ARCH_URL\" \"$archive\""
|
||||||
|
else
|
||||||
|
dwl "$ARCH_URL" "$archive" || {
|
||||||
|
disp E "Failed to download archive."
|
||||||
rm -rf "$tmpdir"
|
rm -rf "$tmpdir"
|
||||||
return 6
|
return 6
|
||||||
}
|
}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
disp I "Installing new version..."
|
if (( dry_run )); then
|
||||||
cp -r "$tmpdir"/profile/* "$MYPATH"/ || {
|
disp I "[dry-run] tar -xzf \"$archive\" -C \"$tmpdir\""
|
||||||
disp E "Failed to copy new files to $MYPATH."
|
disp I "[dry-run] cp -a <extracted_profile>/. \"$MYPATH\"/"
|
||||||
|
else
|
||||||
|
tar -xzf "$archive" -C "$tmpdir" || {
|
||||||
|
disp E "Archive extraction failed."
|
||||||
rm -rf "$tmpdir"
|
rm -rf "$tmpdir"
|
||||||
return 7
|
return 7
|
||||||
}
|
}
|
||||||
|
|
||||||
disp I "Upgrade complete. You should now logout and login again."
|
extracted_root=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d ! -name '.*' | head -n 1)
|
||||||
|
if [[ -z "$extracted_root" ]]; then
|
||||||
|
disp E "Could not find extracted profile files."
|
||||||
rm -rf "$tmpdir"
|
rm -rf "$tmpdir"
|
||||||
|
return 8
|
||||||
|
fi
|
||||||
|
|
||||||
|
disp I "Installing new version..."
|
||||||
|
cp -a "$extracted_root"/. "$MYPATH"/ || {
|
||||||
|
disp E "Failed to copy new files into $MYPATH."
|
||||||
|
rm -rf "$tmpdir"
|
||||||
|
return 9
|
||||||
|
}
|
||||||
|
|
||||||
|
disp I "Upgrade complete. Please log out and log in again."
|
||||||
|
rm -rf "$tmpdir"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
export -f profile_upgrade
|
export -f profile_upgrade
|
||||||
|
|||||||
Reference in New Issue
Block a user