352 lines
13 KiB
Bash
352 lines
13 KiB
Bash
#!/bin/sh
|
|
|
|
setup(){
|
|
## Keep the script general by allowing the user to provide the version number to download.
|
|
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
|
|
echo "Usage: ./runtime/bin/update [VersionNumber] [openHAB Dir]"
|
|
echo ""
|
|
echo " e.g. ./runtime/bin/update << Updates to the next version"
|
|
echo " ./runtime/bin/update 2.0.0 << Updates to a specific version"
|
|
echo " ./update 2.1.0 /opt/openHAB2 << Updates a specific root folder"
|
|
echo " ./runtime/bin/update 2.2.0-SNAPSHOT << Updates to latest SNAPSHOT"
|
|
echo ""
|
|
echo "Use this script to change openHAB to another version. Specifying the version allows"
|
|
echo "you to upgrade or downgrade to that version, or to the latest snapshot. Not specifying"
|
|
echo "any parameters will attempt to find the next version for you."
|
|
echo ""
|
|
echo "You can place this script anywhere, but you should run it from inside the openHAB root folder."
|
|
echo "Do not try to run the script from inside the runtime folder."
|
|
echo ""
|
|
exit 0
|
|
fi
|
|
|
|
## Ask to run as root to prevent us from running sudo in this script.
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "Please run this script as root! (e.g. use sudo)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
## Second parameter can be the openHAB path, if not assume the script is called from root!
|
|
if [ -z "$2" ]; then
|
|
if [ -n "$OPENHAB_HOME" ]; then
|
|
WorkingDir="$OPENHAB_HOME"
|
|
DirError="'OPENHAB_HOME' does not point towards openHAB's root directory."
|
|
else
|
|
WorkingDir="."
|
|
DirError="The script must be called from openHAB's root directory."
|
|
fi
|
|
else
|
|
WorkingDir="$2"
|
|
DirError="The specified directory is not openHAB's root directory."
|
|
fi
|
|
|
|
if [ -z "$OPENHAB_CONF" ]; then OPENHAB_CONF="$WorkingDir/conf"; fi
|
|
if [ -z "$OPENHAB_USERDATA" ]; then OPENHAB_USERDATA="$WorkingDir/userdata"; fi
|
|
if [ -z "$OPENHAB_LOGDIR" ]; then OPENHAB_LOGDIR="$OPENHAB_USERDATA/logs"; fi
|
|
|
|
## Test to see if the script is being run non-interactively
|
|
if [ ! -t 0 ] || [ -n "$OPENHAB_NONINTERACT" ] ; then
|
|
exec > "$OPENHAB_LOGDIR/update.log" 2>&1
|
|
OPENHAB_NONINTERACT="true"
|
|
fi
|
|
|
|
## Check two of the standard openHAB folders to make sure we're updating the right thing.
|
|
if [ ! -d "$OPENHAB_USERDATA" ] || [ ! -d "$OPENHAB_CONF" ]; then
|
|
echo "$DirError" >&2
|
|
echo "Either specify a directory or place this update script in and run from openHAB's root folder." >&2
|
|
exit 1
|
|
fi
|
|
|
|
## Check to see if processes are running before updating
|
|
if [ ! -z "$(ps aux | grep "openhab2.*java" | grep -v grep)" ]; then
|
|
echo "openHAB is running! Please stop the process before updating." >&2
|
|
exit 1
|
|
fi
|
|
|
|
CurrentVersion="$(awk '/openhab-distro/{print $3}' "$OPENHAB_USERDATA/etc/version.properties")"
|
|
|
|
OHVersion="$1"
|
|
|
|
## If no OHVersion is specified, try incrementing the second point.
|
|
if [ -z "$OHVersion" ]; then
|
|
FirstPart="$(echo "$CurrentVersion" | awk -F'.' '{print $1}')"
|
|
SecondPart="$(echo "$CurrentVersion" | awk -F'.' '{print $2}')"
|
|
ThirdPart="$(echo "$CurrentVersion" | awk -F'.' '{print $3}')"
|
|
FourthPart="$(echo "$CurrentVersion" | awk -F'.' '{print $4}')"
|
|
if test "${ThirdPart#*-SNAPSHOT}" != "$ThirdPart"; then
|
|
OHVersion="$CurrentVersion"
|
|
elif [ -n "$FourthPart" ]; then
|
|
OHVersion="$FirstPart.$SecondPart.$ThirdPart"
|
|
else
|
|
OHVersion="$FirstPart.$((SecondPart + 1)).$ThirdPart"
|
|
fi
|
|
fi
|
|
|
|
milestoneVersion="$(echo "$OHVersion" | awk -F'.' '{print $4}')"
|
|
## Choose bintray for releases, jenkins for snapshots and artifactory for milestones or release candidates.
|
|
if test "${OHVersion#*-SNAPSHOT}" != "$OHVersion"; then
|
|
DownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab/target/openhab-$OHVersion.zip"
|
|
AddonsDownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab-addons/target/openhab-addons-$OHVersion.kar"
|
|
LegacyAddonsDownloadLocation="https://ci.openhab.org/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab-addons-legacy/target/openhab-addons-legacy-$OHVersion.kar"
|
|
elif [ "$OHVersion" = "$CurrentVersion" ]; then
|
|
echo "You are already on openHAB $CurrentVersion" >&2
|
|
exit 1
|
|
elif [ -n "$milestoneVersion" ]; then
|
|
DownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab/$OHVersion/openhab-$OHVersion.zip"
|
|
AddonsDownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab-addons/$OHVersion/openhab-addons-$OHVersion.kar"
|
|
LegacyAddonsDownloadLocation="https://openhab.jfrog.io/openhab/libs-milestone-local/org/openhab/distro/openhab-addons-legacy/$OHVersion/openhab-addons-legacy-$OHVersion.kar"
|
|
else
|
|
DownloadLocation="https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab%2F$OHVersion%2Fopenhab-$OHVersion.zip"
|
|
AddonsDownloadLocation="https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab-addons%2F$OHVersion%2Fopenhab-addons-$OHVersion.kar"
|
|
LegacyAddonsDownloadLocation="https://bintray.com/openhab/mvn/download_file?file_path=org%2Fopenhab%2Fdistro%2Fopenhab-addons-legacy%2F$OHVersion%2Fopenhab-addons-legacy-$OHVersion.kar"
|
|
fi
|
|
|
|
## Set the temporary directories.
|
|
TempDir="/tmp/openhab"
|
|
OutputFile="$TempDir/openhab-$OHVersion.zip"
|
|
|
|
## Store anything in temporary folders
|
|
echo "Making Temporary Directory"
|
|
mkdir -p "$TempDir" || {
|
|
echo "Failed to make temporary directory: $TempDir" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
## Download the specified version of openHAB and check for an update script.
|
|
download(){
|
|
## Skip this part if the script was called by an older version of itself.
|
|
if [ "$1" != "--skipnew" ]; then
|
|
echo "Downloading openHAB $OHVersion..."
|
|
curl -Lf# "$DownloadLocation" -o "$OutputFile" || {
|
|
echo "Download failed, version $OHVersion does not exist." >&2
|
|
echo "If you believe this to be an error, please check the openHAB website. (www.openhab.org)"
|
|
exit 1
|
|
}
|
|
## First check if there's a newer version of this update script
|
|
unzip -qp "$OutputFile" runtime/bin/update > "$TempDir/update" 2>/dev/null && {
|
|
echo "Update script in .zip archive found, using that instead."
|
|
chmod a+x "$TempDir/update"
|
|
"$TempDir/update" "$OHVersion" "$(cd "$WorkingDir" && pwd -P)" "--skipnew"; exit 0
|
|
}
|
|
fi
|
|
}
|
|
|
|
runCommand() {
|
|
string="$1"
|
|
string="$(echo "$string" | sed "s:\$OPENHAB_USERDATA:${OPENHAB_USERDATA:?}:g")"
|
|
string="$(echo "$string" | sed "s:\$OPENHAB_CONF:${OPENHAB_CONF:?}:g")"
|
|
string="$(echo "$string" | sed "s:\$OPENHAB_HOME:${WorkingDir:?}:g")"
|
|
|
|
command="$(echo "$string" | awk -F';' '{print $1}')"
|
|
param1="$(echo "$string" | awk -F';' '{print $2}')"
|
|
param2="$(echo "$string" | awk -F';' '{print $3}')"
|
|
|
|
case $command in
|
|
'DEFAULT')
|
|
# Just rename the file, the update process adds back the new version
|
|
echo " Adding '.bak' to $param1"
|
|
mv "$param1" "$param1.bak"
|
|
;;
|
|
'DELETE')
|
|
# We should be strict and specific here, i.e only delete one file.
|
|
if [ -f "$param1" ]; then
|
|
echo " Deleting File: $param1"
|
|
rm -f "$param1"
|
|
fi
|
|
;;
|
|
'DELETEDIR')
|
|
# We should be strict and specific here, i.e only delete one directory.
|
|
if [ -d "$param1" ]; then
|
|
echo " Deleting Directory: $param1"
|
|
rm -rf "$param1"
|
|
fi
|
|
;;
|
|
'MOVE')
|
|
echo " Moving: From $param1 to $param2"
|
|
mv "$param1" "$param2"
|
|
;;
|
|
'NOTE') printf ' \033[32mNote:\033[m %s\n' "$param1";;
|
|
'ALERT') printf ' \033[31mWarning:\033[m %s\n' "$param1";;
|
|
esac
|
|
}
|
|
|
|
getVersionNumber() {
|
|
firstPart="$(echo "$1" | awk -F'.' '{print $1}')"
|
|
secondPart="$(echo "$1" | awk -F'.' '{print $2}')"
|
|
thirdPart="$(echo "$1" | awk -F'.' '{print $3}')"
|
|
thirdPart="${thirdPart%%-*}"
|
|
echo $((firstPart*10000+secondPart*100+thirdPart))
|
|
}
|
|
|
|
scanVersioningList() {
|
|
Section="$1"
|
|
VersionMessage="$2"
|
|
InSection=false
|
|
InNewVersion=false
|
|
|
|
## Read the file line by line.
|
|
while IFS= read -r Line
|
|
do
|
|
case $Line in
|
|
'')
|
|
continue
|
|
;;
|
|
## Flag to run the relevant [[section]] only.
|
|
"[[$Section]]")
|
|
InSection=true
|
|
;;
|
|
## Stop reading the file if another [[section]] starts.
|
|
"[["*"]]")
|
|
if $InSection; then
|
|
break
|
|
fi
|
|
;;
|
|
## Detect the [version] and execute the line if relevant.
|
|
'['*'.'*'.'*']')
|
|
if $InSection; then
|
|
LineVersion="$(echo "$Line" | awk -F'[][]' '{print $2}')"
|
|
LineVersionNumber=$(getVersionNumber "$LineVersion")
|
|
if [ "$CurrentVersionNumber" -lt "$LineVersionNumber" ]; then
|
|
InNewVersion=true
|
|
echo ""
|
|
echo "$VersionMessage $LineVersion:"
|
|
else
|
|
InNewVersion=false
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
if $InSection && $InNewVersion; then
|
|
runCommand "$Line"
|
|
fi
|
|
;;
|
|
esac
|
|
done < "$TempDir/$transferFile"
|
|
}
|
|
|
|
echo " "
|
|
echo "#########################################"
|
|
echo " openHAB 2.x.x update script "
|
|
echo "#########################################"
|
|
echo " "
|
|
|
|
SpecifiedVersion="$1"
|
|
SpecifiedDir="$2"
|
|
SkipModifier="$3"
|
|
|
|
##Run the initialisation functions defined above
|
|
setup "$SpecifiedVersion" "$SpecifiedDir"
|
|
download "$SkipModifier"
|
|
|
|
transferFile="update.lst"
|
|
CurrentVersionNumber=$(getVersionNumber "$CurrentVersion")
|
|
case $CurrentVersion in
|
|
*"-"* | *"."*"."*"."*) CurrentVersionNumber=$((CurrentVersionNumber-1));;
|
|
esac
|
|
|
|
|
|
## Go through a list of transitional commands that are stored in the update archive.
|
|
echo "New update list required, extracting from zip..."
|
|
unzip -qp "$OutputFile" "runtime/bin/$transferFile" > "$TempDir/$transferFile" || {
|
|
echo "Additional update commands not found in archive, exiting..."
|
|
exit 1
|
|
}
|
|
|
|
## Notify the user of important changes first
|
|
echo "The script will attempt to update openHAB to version $OHVersion"
|
|
printf 'Please read the following \033[32mnotes\033[m and \033[31mwarnings\033[m:\n'
|
|
scanVersioningList "MSG" "Important notes for version"
|
|
|
|
if [ -z "$OPENHAB_NONINTERACT" ]; then
|
|
printf '\nIs this okay? [y/N]: '
|
|
read -r answer
|
|
case $answer in
|
|
[Yy]*)
|
|
;;
|
|
*)
|
|
echo "Cancelling update..."
|
|
rm -rf "${TempDir:?}"
|
|
exit 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
## Preserve file ownership of old setup.
|
|
FileOwner=$(ls -ld "$OPENHAB_USERDATA" | awk '{print $3}')
|
|
FileGroup=$(ls -ld "$OPENHAB_USERDATA" | awk '{print $4}')
|
|
|
|
## Perform version specific pre-update commands
|
|
scanVersioningList "PRE" "Performing pre-update tasks for version"
|
|
|
|
## Remove only the files that are to be replaced.
|
|
echo ""
|
|
echo "Removing openHAB System Files..."
|
|
mkdir -p "$TempDir/runtime"
|
|
mkdir -p "$TempDir/userdata/etc"
|
|
mv "$WorkingDir/runtime" "$TempDir/runtime/"
|
|
|
|
## Go through a list of system files that are stored in the update archive.
|
|
echo "New system filelist required, extracting from zip..."
|
|
unzip -qp "$OutputFile" runtime/bin/userdata_sysfiles.lst > "$TempDir/filelist.lst" || {
|
|
echo "System Filelist not found in update, exiting..."
|
|
exit 1
|
|
}
|
|
while IFS= read -r fileName
|
|
do
|
|
fullPath="$WorkingDir/userdata/etc/$fileName"
|
|
if [ -f "$fullPath" ]; then
|
|
mv "$fullPath" "$TempDir/userdata/etc/"
|
|
fi
|
|
done < "$TempDir/filelist.lst"
|
|
|
|
## Clearing the cache and tmp folders is necessary for upgrade.
|
|
echo "Clearing cache..."
|
|
rm -rf "${OPENHAB_USERDATA:?}/cache"
|
|
rm -rf "${OPENHAB_USERDATA:?}/tmp"
|
|
|
|
## Unzip the downloaded folder into openHAB's directory WITHOUT replacing any existing files.
|
|
echo "Updating openHAB..."
|
|
unzip -nq "$OutputFile" -d "$WorkingDir/" || {
|
|
echo "Failed to unzip archive, restoring system files..." >&2
|
|
## An error has occured so try to restore openHAB to it's previous state.
|
|
cp -a "$TempDir/runtime" "$WorkingDir/runtime"
|
|
cp -a "$TempDir/userdata/etc/"* "${OPENHAB_USERDATA:?}/etc/"
|
|
exit 1
|
|
}
|
|
|
|
## Perform version specific post-update commands
|
|
scanVersioningList "POST" "Performing post-update tasks for version"
|
|
|
|
## If there's an existing addons file, we need to replace it with the correct version.
|
|
AddonsFile="$WorkingDir/addons/openhab-addons-$CurrentVersion.kar"
|
|
if [ -f "$AddonsFile" ]; then
|
|
echo "Found an openHAB addons file, replacing with new version..."
|
|
rm -f "${AddonsFile:?}"
|
|
curl -Lf# "$AddonsDownloadLocation" -o "$WorkingDir/addons/openhab-addons-$OHVersion.kar" || {
|
|
echo "Download of addons file failed, please find it on the openHAB website (www.openhab.org)" >&2
|
|
}
|
|
fi
|
|
|
|
## Do the same for the legacy addons file.
|
|
LegacyAddonsFile="$WorkingDir/addons/openhab-addons-legacy-$CurrentVersion.kar"
|
|
if [ -f "$LegacyAddonsFile" ]; then
|
|
echo "Found an openHAB legacy addons file, replacing with new version..."
|
|
rm -f "${LegacyAddonsFile:?}"
|
|
curl -Lf# "$LegacyAddonsDownloadLocation" -o "$WorkingDir/addons/openhab-addons-legacy-$OHVersion.kar" || {
|
|
echo "Download of legacy addons file failed, please find it on the openHAB website (www.openhab.org)" >&2
|
|
}
|
|
fi
|
|
echo ""
|
|
## Remove the downloaded zip-file.
|
|
echo "Deleting temporary files..."
|
|
rm -rf "${TempDir:?}"
|
|
|
|
## Restore file ownership.
|
|
echo "Restoring previous file ownership ($FileOwner:$FileGroup)"
|
|
chown -R "$FileOwner:$FileGroup" "$WorkingDir"
|
|
|
|
echo ""
|
|
echo "SUCCESS: openHAB updated from $CurrentVersion to $OHVersion"
|
|
echo ""
|