diff --git a/CommonResources b/CommonResources index ab45060..b22aadc 100755 --- a/CommonResources +++ b/CommonResources @@ -35,12 +35,15 @@ source "$setupHelperDir/DbusSettingsResources" scriptAction='NONE' installFailed=false +installExitReason=$EXIT_SUCCESS -# flags to control setup script exit behavior +# flags to control setup script behavior rebootNeeded=false runAgain=false filesUpdated=false restartGui=false +guiV1present=true +guiV1required=true # yesNoPrompt provides user prompting requesting a yes/no response # @@ -142,6 +145,29 @@ standardActionPrompt () done } + +# setInstallFailed sets flags to prevent further install steps +# and insure the package is uninstalled completely +# +# $1 indicates the reason for the failure and will evenutally be uused +# report the failure reason when exiting the script +# +# any remaining paremeters are passed to logMessage + +setInstallFailed () +{ + installFailed=true + scriptAction='UNINSTALL' + if [ ! -z "$1" ]; then + installExitReason=$1 + fi + message="${@:2}" + if [ ! -z "$message" ]; then + logMessage "$message" + fi +} + + # backupActiveFile makes a copy of the active file in file.orig # if the original file does not exist, no backup is made # BUT sets a flag file that will cause restoreFile to delete the active copy @@ -150,6 +176,11 @@ standardActionPrompt () backupActiveFile () { + # don't do any work if install has already failed + if $installFailed ; then + return + fi + backupExisted=false baseName=$(basename $1) if [ -e "$1.orig" ] || [ -e "$1.NO_ORIG" ]; then @@ -181,35 +212,60 @@ backupActiveFile () updateActiveFile () { + # don't do any work if install has already failed + if $installFailed ; then + return + fi + thisFileUpdated=false local sourceFound=false - local baseName local sourceFile="$1" - local destinationFile + local activeFile - # separate replacement file specified + # separate source and replacement files specified if [ $# == 2 ]; then if [ -f "$sourceFile" ]; then sourceFound=true else - logMessage "ERROR: specified soure file $sourceFile does not exist - can't continue with install" - scriptAction='UNINSTALL' - installFailed=true + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: specified soure file $sourceFile does not exist - can't continue with install" return fi - destinationFile="$2" + activeFile="$2" # use active file for both source and destination else - destinationFile="$1" + activeFile="$1" fi - - # look for source in FileSets + + local baseName=$(basename "$activeFile") + + # replacement files are not be needed for some versions + # if so marked, leave original untouched + if [ -f "$fileSet/$baseName.USE_ORIGINAL" ]; then + return + fi + + local pathToFile=$(dirname "$activeFile") + if [ ! -e "$pathToFile" ]; then + # fatal if GUI v1 not present and needed for install + if [[ "$pathToFile" == "/opt/victronenergy/gui/"* ]]; then + if $guiV1required ; then + setInstallFailed $EXIT_NO_GUI_V1 "ERROR $packageName requires GUI v1 which is not on the system - can't continue" + return + # GUI v1 not needed - proceed + fi + # active file is not in GUI v1 part of file system + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: path to $activeFile does not exist - can't continue with install" + return + fi + fi + if ! $sourceFound ; then - baseName="$(basename "$sourceFile")" - # found in version directory + # look for source in FileSet if [ -f "$fileSet/$baseName" ]; then sourceFile="$fileSet/$baseName" sourceFound=true + # look for version-independent source elif [ -f "$pkgFileSets/$baseName" ]; then sourceFile="$pkgFileSets/$baseName" sourceFound=true @@ -217,31 +273,23 @@ updateActiveFile () fi if ! $sourceFound; then - # replacement files are not be needed for some versions - # if so marked, leave original untouched - if [ -f "$fileSet/$(basename $sourceFile).USE_ORIGINAL" ]; then - return - # if not flagged, this is a fatal error - else - logMessage "ERROR: no soure file for replacement $destinationFile - can't continue with install" - scriptAction='UNINSTALL' - installFailed=true - fi + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: no soure file for $baseName - can't continue with install" return fi + mayHaveBeenUpdated=false - backupActiveFile "$destinationFile" + backupActiveFile "$activeFile" # package may already have been installed - check to see needToUpdate=true if $mayHaveBeenUpdated ; then - cmp -s "$sourceFile" "$destinationFile" > /dev/null + cmp -s "$sourceFile" "$activeFile" > /dev/null # already updated - no change to active file if (( $? == 0 )); then needToUpdate=false fi fi if $needToUpdate ; then - cp "$sourceFile" "$destinationFile" + cp "$sourceFile" "$activeFile" filesUpdated=true thisFileUpdated=true fi @@ -283,7 +331,7 @@ restoreActiveFile () # If the new active files for the new version all match another version # the new file set is populated automatically with replacement files from the other version # and may be used with no further action -# If not, new file set is marked INCOMPLETE and scriptAction is set to EXIT +# If not, new file set is marked INCOMPLETE and installation fail information is set # The package can not be installed on this Venus OS version # # Replacement files that have no original specify an "alternate original" that is used @@ -429,32 +477,13 @@ _checkFileSets () done if [ -f "$fileSet/INCOMPLETE" ]; then - logMessage "ERROR: incomplete file set for $venusVersion - can't continue" - exit $EXIT_FILE_SET_ERROR + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: incomplete file set for $venusVersion - can't continue" # if we get this far and fs is not marked INCOMPLETE, then the file set does not need to be checked again next pass else touch "$fileSet/COMPLETE" fi } -# restart the GUI service -# begining at about v3.20~18, changes were made to accommodate the gui-v2 -# and these changes require different handling of a GUI service restart - -restartGuiService () -{ - - # start-gui is the new service which supports gui-v2 - # that service will start gui-v2 if selected in Settings or run the older gui if not - if [ -e "/service/start-gui" ]; then - svc -t "/service/start-gui" - # gui is the older service that runs GUI v1 - else - svc -t "/service/gui" - fi -} - - # determine how startup script should exit based on $scriptAction and other flags # may EXIT or REBOOT within the function - DOES NOT RETURN TO CALLER @@ -525,14 +554,8 @@ endScript () # if installation was attempted but failed, exit without checking anything else # or signaling GUI restart or reboot if $installFailed ; then - logMessage "installation failed - package uninstalled - exiting" - exit $EXIT_FILE_SET_ERROR - elif $versionNotCompatible ; then - logMessage "version not compatible - exiting" - exit $EXIT_INCOMPATIBLE_VERSION - elif $platformNotCompatible ; then - logMessage "platform not compatible - exiting" - exit $EXIT_INCOMPATIBLE_PLATFOM + logMessage "installation failed - package has been uninstalled - exiting" + exit $installExitReason elif $rebootNeeded ; then if $userInteraction ; then yesNoPrompt "Reboot system now (y) or do it manually later (n): " @@ -602,8 +625,19 @@ endScript () # It is set to false here the 'auto' parameter is passed on the command line # which indicates this script is NOT being run from the command line -# initialize version strings and numbers for future checks +# move old installedFlag ("...inInstalled...") +# to its new name ...installedVersionFile... +if [ ! -f "$installedVersionFile" ] && [ -f "$installedFlag" ]; then + installedVersion=$(cat "$installedFlag") + if [ -z $installedVersion ]; then + installedVersion="" + else + echo $installedVersion > "$installedVersionFile" + fi +fi +rm -f "$installedFlag" +# initialize version strings and numbers for future checks if [ -f "$installedVersionFile" ]; then installedVersion=$(cat "$installedVersionFile") versionStringToNumber $(cat "$installedVersionFile") @@ -662,8 +696,14 @@ while [ $# -gt 0 ]; do done # make sure rootfs is mounted R/W & and resized to allow space for replacement files -if [ -f /opt/victronenergy/swupdate-scripts/resize2fs.sh ]; then - /opt/victronenergy/swupdate-scripts/resize2fs.sh +if (( $(mount | grep ' / ' | grep -c 'ro') != 0 )); then + if [ -f /opt/victronenergy/swupdate-scripts/resize2fs.sh ]; then + logMessage "remounting root read-write" + /opt/victronenergy/swupdate-scripts/resize2fs.sh + else + logMessage "ERROR: can't remount root read-write - can't continue" + exit $EXIT_ROOT_FULL + fi fi # make sure the root partition has space for the package @@ -674,18 +714,6 @@ if (( $availableSpace < 10 )); then exit $EXIT_ROOT_FULL fi -# move old installedFlag ("...inInstalled...") -# to its new name ...installedVersionFile... -if [ ! -f "$installedVersionFile" ] && [ -f "$installedFlag" ]; then - installedVersion=$(cat "$installedFlag") - if [ -z $installedVersion ]; then - installedVersion="" - else - echo $installedVersion > "$installedVersionFile" - fi -fi -rm -f "$installedFlag" - # packages that require options to proceed unattended # must include the optionsRequried flag file in their package directory # if the flag is present and options haven't been previously set, @@ -756,33 +784,20 @@ if [ ! -z $obsoleteVersion ] && [ ! -f "$scriptDir/obsoleteVersion" ]; then fi # prevent installing Raspberry Pi packages on other platforms -platformNotCompatible=false if [ -f "$scriptDir/raspberryPiOnly" ]; then if [ -f /etc/venus/machine ]; then machine=$(cat /etc/venus/machine) + else + machine="" fi if [ -z $machine ]; then - if $isInstalled ; then - logMessage "can't determine Venus device type - uninstalling" - scriptAction='UNINSTALL' - else - logMessage "can't determine Venus device type - exiting" - exit $EXIT_INCOMPATIBLE_PLATFOM - fi - elif [ $machine != "raspberrypi2" ] && [ $machine != "raspberrypi4" ]; then - platformNotCompatible=true - if $isInstalled ; then - logMessage "$packageName not compatible with $machine - uninstalling" - scriptAction='UNINSTALL' - else - logMessage "$packageName not compatible with $machine - exiting" - exit $EXIT_INCOMPATIBLE_PLATFOM - fi + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "can't determine Venus device type - uninstalling" + elif [[ $machine != *"raspberrypi"* ]]; then + setInstallFailed $EXIT_INCOMPATIBLE_PLATFOM "$packageName not compatible with $machine" fi fi # check to see if package is compatible with this Venus version -versionNotCompatible=false if [ -f "$scriptDir/firstCompatibleVersion" ]; then firstCompatibleVersion=$(cat "$scriptDir/firstCompatibleVersion") # no first compatible version specified - use the default @@ -793,47 +808,61 @@ fi versionStringToNumber $firstCompatibleVersion firstCompatibleVersionNumber=$versionNumber if (( $venusVersionNumber < $firstCompatibleVersionNumber )); then - versionNotCompatible=true + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "ERROR $venusVersion before first compatible $firstCompatibleVersion" elif [ -f "$scriptDir/obsoleteVersion" ]; then - versionStringToNumber $(cat "$scriptDir/obsoleteVersion") + obsoleteVersion=$(cat "$scriptDir/obsoleteVersion") + versionStringToNumber $obsoleteVersion obsoleteVersionNumber=$versionNumber if (( $venusVersionNumber >= $obsoleteVersionNumber )); then - versionNotCompatible=true + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "ERROR $venusVersion after last compatible $obsoleteVersion" fi fi -if $versionNotCompatible ; then - # if not installed, log message and exit - if ! $isInstalled ; then - logMessage "$packageName not compatible with Venus $venusVersion - can't install" - exit $EXIT_INCOMPATIBLE_VERSION - else - logMessage "$packageName not compatible with Venus $venusVersion - uninstalling" - scriptAction='UNINSTALL' - fi -else - if [ ! -d "$setupOptionsRoot" ]; then - logMessage "creating root setup options directory $setupOptionsRoot" - mkdir $setupOptionsRoot - fi - +if ! $installFailed ; then if [ ! -d "$setupOptionsDir" ]; then logMessage "creating package options directory $setupOptionsDir" - mkdir $setupOptionsDir + mkdir -p $setupOptionsDir fi fi # attempting an install without the comand line prompting -# and needed options have not been set yet -# can't continue +# and needed options have not been set yet - can't continue if [ $scriptAction == 'INSTALL' ]; then if ! $optionsSet ; then - logMessage "ERROR required options have not been set - can't install" - exit $EXIT_OPTIONS_NOT_SET + setInstallFailed $EXIT_OPTIONS_NOT_SET "ERROR required options have not been set - can't install" fi fi -# if forcing an uninstall, skip file set checks +# if checks failed or uninstall specified on command line, skip file set checks if [ $scriptAction != 'UNINSTALL' ]; then - # note _checkFileSets will exit if file set error exists + # check file sets for this version, attempt to created it if it does not exist _checkFileSets fi +# determine if GUI v1 is installed and selected to run +if [ ! -d "/opt/victronenergy/gui" ]; then + guiV1present=false +else + # a value of 2 indicates gui-v2 is selected to run + selectedGui=$(dbus-send --system --print-reply=literal --dest=com.victronenergy.settings\ + /Settings/Gui/RunningVersion com.victronenergy.BusItem.GetValue 2> /dev/null | awk '{print $3}') + if [ "$selectedGui" == "2" ]; then + guiV1present=false + fi +fi + +# packages can bypass GUI v1 checks and allow installs +if [ -f "$scriptDir/GUI_V1_NOT_REQUIRED" ]; then + guiV1required=false +# otherwise, files in the GUI v1 directory are considered mandatory +elif (( $(grep 'updateActiveFile' "$scriptDir/setup" | grep -c '$qmlDir') > 0 )); then + guiV1required=true +else + guiV1required=false +fi + +# block installs if any GUI files would be modified and GUI v1 is not present +if ! $guiV1present && $guiV1required ; then + setInstallFailed $EXIT_NO_GUI_V1 "ERROR $packageName requires GUI v1 which is not on the system - can't install" +fi + + + diff --git a/DbusSettingsResources b/DbusSettingsResources index a87a989..c38ed3a 100755 --- a/DbusSettingsResources +++ b/DbusSettingsResources @@ -45,6 +45,11 @@ source "/data/SetupHelper/LogHandler" updateDbusStringSetting () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ com.victronenergy.BusItem.GetValue &> /dev/null if (( $? != 0 )); then @@ -58,6 +63,11 @@ updateDbusStringSetting () updateDbusIntSetting () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ com.victronenergy.BusItem.GetValue &> /dev/null if (( $? != 0 )); then @@ -71,6 +81,11 @@ updateDbusIntSetting () updateDbusRealSetting () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ com.victronenergy.BusItem.GetValue &> /dev/null if (( $? != 0 )); then @@ -105,6 +120,11 @@ removeDbusSettings () setSetting () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + dbus -y com.victronenergy.settings $2 SetValue $1 &> /dev/null } @@ -125,6 +145,11 @@ setSetting () moveSetting () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + local setupOption="$1" local oldDbusPath=$2 local newDbusPath=$3 diff --git a/EssentialResources b/EssentialResources index 103a16b..7acd1a0 100755 --- a/EssentialResources +++ b/EssentialResources @@ -47,6 +47,7 @@ EXIT_OPTIONS_NOT_SET=251 EXIT_RUN_AGAIN=250 EXIT_ROOT_FULL=249 EXIT_DATA_FULL=248 +EXIT_NO_GUI_V1=247 # old variables - keep for compatibility exitReboot=$EXIT_REBOOT exitSuccess=$EXIT_SUCCESS @@ -138,4 +139,25 @@ function versionStringToNumber () versionNumber=$number } +# restart the GUI service +# begining at about v3.20~18, changes were made to accommodate the gui-v2 +# and these changes require different handling of a GUI service restart +# +# this is in EssentialResorces because it is used in reinstallMods and ServiceResources is overkill there + +restartGuiService () +{ + # start-gui is the new service which supports gui-v2 + # that service will start gui-v2 if selected in Settings or run the older gui if not + if [ -e "/service/start-gui" ]; then + svc -t "/service/start-gui" + # gui is the older service that runs GUI v1 + elif [ -e "/service/gui" ]; then + svc -t "/service/gui" + fi +} + + + + diff --git a/FileSets/MbDisplayPackageVersion.qml b/FileSets/MbDisplayPackageVersion.qml index f262cac..b84c4b0 100644 --- a/FileSets/MbDisplayPackageVersion.qml +++ b/FileSets/MbDisplayPackageVersion.qml @@ -47,6 +47,12 @@ MbItem { return qsTr ( " no file set for " + osVersion ) else if (incompatibleReason == 'CMDLINE' && installedVersion.item.value == "") return qsTr ( " must install from command line" ) + else if (incompatibleReason == 'ROOT_FULL') + return qsTr ( " no space on root partition" ) + else if (incompatibleReason == 'DATA_FULL') + return qsTr ( " no space on /data partition" ) + else if (incompatibleReason == 'GUI_V1_MISSING') + return qsTr ( " GUI v1 not installed" ) else return "" } diff --git a/FileSets/PageSettingsPackageEdit.qml b/FileSets/PageSettingsPackageEdit.qml index 48d5947..7df9db8 100644 --- a/FileSets/PageSettingsPackageEdit.qml +++ b/FileSets/PageSettingsPackageEdit.qml @@ -208,6 +208,8 @@ MbPage { return qsTr ( "no room on root partition" ) else if (incompatibleReason == 'DATA_FULL') return qsTr ( "no room on data partition" ) + else if (incompatibleReason == 'GUI_V1_MISSING') + return qsTr ( "GUI v1\nnot installed" ) else return qsTr ("incompatible ???" ) // compatible for unknown reason } diff --git a/PackageManager.py b/PackageManager.py index dcaadd4..c9e9356 100755 --- a/PackageManager.py +++ b/PackageManager.py @@ -131,6 +131,7 @@ EXIT_RUN_AGAIN = 250 EXIT_ROOT_FULL = 249 EXIT_DATA_FULL = 248 +EXIT_NO_GUI_V1 = 247 EXIT_ERROR = 255 # generic error # install states only @@ -153,6 +154,7 @@ # nanopi Multi/Easy Solar GX # raspberrypi2 Raspberry Pi 2/3 # raspberrypi4 Raspberry Pi 4 +# ekrano Ekrano GX # # /ActionNeeded informs GUI if further action is needed following a manual operation # the operator has the option to defer reboots and GUI restarts (by choosing "Later) @@ -1166,7 +1168,7 @@ def __init__(self): 'autoInstall': [ '/Settings/PackageManager/AutoInstall', 0, 0, 0 ], } self.DbusSettings = SettingsDevice(bus=dbus.SystemBus(), supportedSettings=settingsList, - timeout = 10, eventCallback=None ) + timeout = 30, eventCallback=None ) self.DbusService = VeDbusService ('com.victronenergy.packageManager', bus = dbus.SystemBus()) self.DbusService.add_mandatory_paths ( @@ -2174,7 +2176,7 @@ def run (self): command = "" # do initial refreshes quickly if fastRefresh: - delay = 2.0 + delay = 0.5 # otherwise scan one version every 10 minutes else: delay = 600.0 @@ -2733,6 +2735,12 @@ def InstallPackage ( self, packageName=None, source=None , direction='install' ) where=sendStatusTo, logLevel=ERROR ) if source == 'GUI': DbusIf.SetGuiEditAction ( 'ERROR' ) + elif returnCode == EXIT_NO_GUI_V1: + package.SetIncompatible ('GUI_V1_MISSING') + DbusIf.UpdateStatus ( message=packageName + " GUI v1 not installed", + where=sendStatusTo, logLevel=ERROR ) + if source == 'GUI': + DbusIf.SetGuiEditAction ( 'ERROR' ) # unknown error elif returnCode != 0: DbusIf.UpdateStatus ( message=packageName + " " + direction + " unknown error " + str (returnCode), @@ -3426,26 +3434,44 @@ def mainLoop(): currentDownloadMode = DbusIf.GetAutoDownloadMode () autoInstall = DbusIf.GetAutoInstall () - # UpdateGitHubVersion is responsible for fetching GitHub versions - # so we can update the download mode - # skip all package processing until the update is complete + # check to see if reinstallMods is running + # to prevent conflicts with it's installs and those done here + proc = subprocess.Popen ( "pgrep reinstallMods", shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + proc.wait() + stdout, stderr = proc.communicate () + # convert from binary to string + stdout = stdout.decode ().strip () + if stdout == "": + waitForReinstall = False + else: + waitForReinstall = True # setup status messages - if currentDownloadMode == AUTO_DOWNLOADS_OFF: - if autoInstall: - idleMessage = "checking for installs" - else: - idleMessage = "" + idleMessage = "" + actionMessage = "" + statusMessage = "" + # no updates has highest prioroity + if currentDownloadMode == AUTO_DOWNLOADS_OFF and not autoInstall: + idleMessage = "" + # hold-off of processing has next highest priority elif WaitForGitHubVersions: idleMessage = "refreshing GitHub version information" + elif waitForReinstall: + idleMessage = "waiting for boot reinstall to complete" + # finally, set idleMessage based on download and install states + elif currentDownloadMode != AUTO_DOWNLOADS_OFF and autoInstall: + idleMessage = "checking for downloads and installs" + elif currentDownloadMode == AUTO_DOWNLOADS_OFF and autoInstall: + idleMessage = "checking for installs" + elif currentDownloadMode != AUTO_DOWNLOADS_OFF and not autoInstall: + idleMessage = "checking for downloads" + + # hold off all package processing until the GitHub versions have been updated + # and reinstallMods has finished reinstalling packages after Venus OS update + if waitForReinstall or WaitForGitHubVersions: PackageScanComplete = False PackageIndex = 0 # make sure new scan starts at beginning - else: - idleMessage = "checking for downloads" - if autoInstall: - idleMessage += " and installs" - actionMessage = "" - statusMessage = "" # after a complete scan, change modes if appropirate if PackageScanComplete: @@ -3462,7 +3488,7 @@ def mainLoop(): PackageIndex = 0 PackageScanComplete = False UpdateGitHubVersion.GitHubVersionQueue.put ('REFRESH') - downloadDelay = 10.0 + downloadDelay = 2.0 PackageClass.AddStoredPackages () @@ -3479,11 +3505,12 @@ def mainLoop(): PackageIndex = 0 PackageScanComplete = False - # hold off other processing until Git Hub version refresh is complete + # hold off other processing until boot package reinstall and Git Hub version refresh is complete # this insures download checks are based on up to date Git Hub versions # installs are also held off to prevent install of older version, # then another install of the more recent version - if not WaitForGitHubVersions: + # waiting for reinstallMods to finish prevents conflicts between these two processes + if not waitForReinstall and not WaitForGitHubVersions: package = PackageClass.PackageList [PackageIndex] packageName = package.PackageName PackageIndex += 1 @@ -3582,7 +3609,13 @@ def mainLoop(): logging.warning ("restarting GUI") statusMessage = "restarting GUI ..." try: - proc = subprocess.Popen ( [ 'svc', '-t', '/service/gui' ] ) + # with gui-v2 present, GUI v1 runs from start-gui service not gui service + if os.path.exists ('/service/start-gui'): + proc = subprocess.Popen ( [ 'svc', '-t', '/service/start-gui' ] ) + elif os.path.exists ('/service/gui'): + proc = subprocess.Popen ( [ 'svc', '-t', '/service/gui' ] ) + else: + logging.critical ("GUI restart failed") except: logging.critical ("GUI restart failed") GuiRestart = False @@ -3687,7 +3720,7 @@ def main(): PackageIndex = 0 noActionCount = 0 LastAutoDownloadTime = 0.0 - WaitForGitHubVersions = False + WaitForGitHubVersions = True # hold off package processing until first GitHub version refresh pass downloadDelay = 600.0 # set logging level to include info level entries @@ -3755,6 +3788,8 @@ def main(): Platform = "Raspberry Pi 2/3" elif machine == "raspberrypi4": Platform = "Raspberry Pi 4" + elif machine == "ekrano": + Platform = "Ekrano GX" else: Platform = machine file.close() diff --git a/ServiceResources b/ServiceResources index 6884d83..ed303e1 100755 --- a/ServiceResources +++ b/ServiceResources @@ -143,6 +143,11 @@ removeService () installService () { + # don't do any work if install has already failed + if $installFailed; then + return + fi + local serviceName="" if (( $# >= 1 )); then serviceName=$1 diff --git a/blindInstall/SetupHelperVersion b/blindInstall/SetupHelperVersion index 0b880fd..305e209 100644 --- a/blindInstall/SetupHelperVersion +++ b/blindInstall/SetupHelperVersion @@ -1 +1 @@ -v5.15 +v5.16 diff --git a/changes b/changes index 3c505ef..c22540c 100644 --- a/changes +++ b/changes @@ -1,3 +1,8 @@ +v5.16: + fixed: white/black screen on first boot after firmware update + incorporate changes for GUI v1 and gui-v2 selection, + mainly to prevent package install if GUI v1 is needed and missing + v5.15: fixed: PackageManager isn't in menus after v5.14 install updateFileSets: fixed: NO_REPLACEMENT in existing file sets that should link to other sets diff --git a/reinstallMods b/reinstallMods index e18c62e..d9ddf48 100755 --- a/reinstallMods +++ b/reinstallMods @@ -5,7 +5,6 @@ # some setup scripts access dbus Settings which are not up early in the boot process # therefore, this script is run as a background task and waits for dbus Settings # -# Refer to the ReadMe for more details setupHelperDir="/data/SetupHelper" source "$setupHelperDir/EssentialResources" @@ -25,7 +24,7 @@ logMessage "reinstallMods starting" # and call each script rebootNeeded=false guiRestartNeeded=false -settingsAlive=false +okToInstall=false while read -u 9 line ; do # ignore blank and comment lines @@ -34,6 +33,11 @@ while read -u 9 line ; do command=$(awk '{print var $1}' <<< $line) scriptDir=$(dirname $command) packageName=$(basename $scriptDir) + if [ ! -f $command ] ; then + logMessage "Error: $packageName setup script not found - skipping reinstall" + continue + fi + packageVersionFile="$scriptDir/version" installedVersionFile="$installedVersionPrefix$packageName" doReinstall=false @@ -54,40 +58,40 @@ while read -u 9 line ; do fi if $doReinstall ; then - if [ -f $command ] ; then - fullCommand=$(echo "$command reinstall auto deferReboot deferGuiRestart") - # wait until dbus settings are active before calling setup script - while ! $settingsAlive ; do - if [ $(dbus -y | grep -c "com.victronenergy.settings") == 0 ]; then - logMessage "waiting for dBus settings" - else - settingsAlive=true - fi + # wait until dbus settings and GUI are active before calling setup script + # this is done before first reinstall so PackageManager isn't held off if there are no reinstalls + while ! $okToInstall ; do + if [ $(dbus -y | grep -c "com.victronenergy.settings") == 0 ]; then + logMessage "waiting for dBus settings" sleep 2 - done - - $fullCommand - returnCode=$? - if (( $returnCode == $EXIT_REBOOT )) ; then - logMessage "$packageName reinstall requested reboot" - rebootNeeded=true - elif (( $returnCode == $EXIT_RESTART_GUI )) ; then - logMessage "$packageName reinstall requested GUI restart" - guiRestartNeeded=true + else + okToInstall=true fi - else - logMessage "Error: $packageName setup script not found" + done + + # run setup script + fullCommand=$(echo "$command reinstall auto deferReboot deferGuiRestart") + $fullCommand + returnCode=$? + if (( $returnCode == $EXIT_REBOOT )) ; then + logMessage "$packageName reinstall requested reboot" + rebootNeeded=true + elif (( $returnCode == $EXIT_RESTART_GUI )) ; then + logMessage "$packageName reinstall requested GUI restart" + guiRestartNeeded=true fi fi fi done 9< "$reinstallScriptsList" -# reboot now if any script reboots were indicated +logMessage "reinstallMods complete" + +# reboot or restart GUI now if any script reboots were indicated if $rebootNeeded ; then logMessage "rebooting ..." reboot elif $guiRestartNeeded ; then logMessage "restarting GUI" - svc -t /service/gui + restartGuiService fi -logMessage "reinstallMods complete" + diff --git a/setup b/setup index 7e72485..95e6a59 100755 --- a/setup +++ b/setup @@ -92,15 +92,16 @@ if [ $scriptAction == 'INSTALL' ] ; then rm -f "/var/volatile/tmp/PageSettings.qml" fi - updateActiveFile "$qmlDir/PageSettingsPackageManager.qml" updateActiveFile "$qmlDir/PageSettingsPackageVersions.qml" updateActiveFile "$qmlDir/PageSettingsPackageEdit.qml" - updateActiveFile "$qmlDir/MbDisplayPackageVersion.qml" updateActiveFile "$qmlDir/PageSettingsAddPackageList.qml" updateActiveFile "$qmlDir/PageSettingsPackageAdd.qml" - updateActiveFile "$qmlDir/MbDisplayDefaultPackage.qml" updateActiveFile "$qmlDir/PageSettingsPmBackup.qml" updateActiveFile "$qmlDir/PageSettingsPmInitialize.qml" + updateActiveFile "$qmlDir/PageSettingsPackageManager.qml" + updateActiveFile "$qmlDir/MbDisplayPackageVersion.qml" + updateActiveFile "$qmlDir/MbDisplayDefaultPackage.qml" + # revert to VisualItemModel if before v3.00~14 (v3.00~14 uses VisibleItemModel) versionStringToNumber "v3.00~14" @@ -118,7 +119,6 @@ if [ $scriptAction == 'INSTALL' ] ; then done fi - installService PackageManager cleanup @@ -129,12 +129,12 @@ if [ $scriptAction == 'UNINSTALL' ] ; then restoreActiveFile "$qmlDir/PageSettingsPackageManager.qml" restoreActiveFile "$qmlDir/PageSettingsPackageVersions.qml" restoreActiveFile "$qmlDir/PageSettingsPackageEdit.qml" - restoreActiveFile "$qmlDir/MbDisplayPackageVersion.qml" restoreActiveFile "$qmlDir/PageSettingsAddPackageList.qml" restoreActiveFile "$qmlDir/PageSettingsPackageAdd.qml" - restoreActiveFile "$qmlDir/MbDisplayDefaultPackage.qml" restoreActiveFile "$qmlDir/PageSettingsPmBackup.qml" restoreActiveFile "$qmlDir/PageSettingsPmInitialize.qml" + restoreActiveFile "$qmlDir/MbDisplayPackageVersion.qml" + restoreActiveFile "$qmlDir/MbDisplayDefaultPackage.qml" removeService PackageManager diff --git a/updateFileSets b/updateFileSets index 54c9ebd..b58901b 100755 --- a/updateFileSets +++ b/updateFileSets @@ -685,6 +685,7 @@ for package in $packageList; do realFileVersions=() linksOnlyVersionCount=0 realFilesVersionCount=0 + guiV1FilesExist=false ######################### beginProgress "$package: final checks" for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" diff --git a/updateFileSets (original) b/updateFileSets (original) deleted file mode 100755 index bf027e2..0000000 --- a/updateFileSets (original) +++ /dev/null @@ -1,912 +0,0 @@ -#!/bin/bash - -# this script updates file sets for all packages in the list below -# it scans all Venus OS versions in the stockFiles directory -# -# This is a unix bash script and should be run on a host computer, not a GX device -# Windows will not run this script natively. -# However Windows 10 apparently supports bash: -# https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/ -# -# packages to be evaulated may be specified on the command line -# use 'all' to process all packages in the allPackages list below -# -# file sets which contain real files (not just links and flags) -# for a version NOT contained in StockFiles will be flagged with UNUSED_FILE_SET -# this can occur if you remove versions from StockFiles. -# For example, you may wish to remove beta versions after a beta test cycle. -# file sets which do not contain any real files (just symbolic links or flag files) are removed - -# stockFiles contains excerpts from Venus OS file systems -# and must be stored on the host -# within a directory with name of the exact Venus OS version -# and within the stockFiles directory defined below. -# -# 1) missing file set directories are created -# 2) if any files in fileList don't exist (eg, a new file was added to file list), -# the original file in stockFiles is copied to the version directory -# 3) if the original file does not exist, the file is so marked with .NO_STOCK_FILE -# this situation must be corrected: -# version-dependent files without an original MUST use an "alternate original" -# specified in FileSets. This permits version checks for these files too -# replacement files that do not replace a stock file should be placed in version-indpendent file storage -# (FileSets/). -# If these replacement files vary with Venus OS versions, they MUST include an "alternate original". -# This permits version checks for these files too -# -# when a stock file set does not exist, this script will check files from existing file sets -# for a matching original file. -# If a match is found, the replacement file is automatically placed in the new file set -# If no match is found, the missing replacement is flagged and a suitable replacement must be created manually. -# -# existing file sets not in the stockFiles are checked. If empty, they are removed. -# If not empty they are marked UNUSED_FILE_SET and flagged for manual removal. -# -# file sets will include all files listed in fileList. -# this allows the setup script to always have a replacement for known versions -# without searching other file sets for a matching original file -# (there have been cases where installation fails because the search for a matching original could not be found) -# if the stock file matches a previous version, a symbolic link for the replacement is created -# rather than duplicating the file -# this also makes maintanence easier since matching replacement can be identified -# -# original files in the file set are not normally used when installing the package -# however, they are retained so that the setup script can attempt to create a file set for an unknown Venus OS version -# this of course may fail if a matching original file can not be found -# -# if no end action is specified on the command line, the user is prompted for how to proceed for each package processed -# end actions specified will bypass this prompt and proceed with the next package -# end actions: -# -p do not update the package but preserve the working copy -# -d do not update the package and deete the working copy -# -u update the package with changes in the working copy's file sets -# -# -r restore package from backup if present - no processing is performed on the packge, backup or working copy -# backups are automatically created when updating a package -# Note: the restore option is not offered at the end prompt since the update has not been applied yet. -# -# if errors occur, the needed corrections may be more obvious by comparing the package and the working copy -# for this reason, preserving the working copy is recommended if errors are expected - -# set allPackages to all packages this script should evalueate if no options are included -allPackages="SetupHelper GuiMods ExtTransferSwitch ShutdownMonitor VeCanSetup RpiDisplaySetup RpiGpioSetup" -## GeneratorConnector TankRepeater are obsolete and file sets should not be updated. - -# set these as appropriate to your system -packageRoot="/Users/Kevin/GitHub" -stockFiles="$packageRoot/StockVenusOsFiles" - -totalErrors=0 -totalWarnings=0 -packageErrors=0 -packageWarnings=0 - -outputtingProgress=false - -function logMessage () -{ - if $outputtingProgress ; then - clearProgress - fi - echo "$*" - if [[ "$*" == "ERROR"* ]]; then - ((totalErrors++)) - ((packageErrors++)) - elif [[ "$*" == "WARNING"* ]]; then - ((totalWarnings++)) - ((packageWarnings++)) - fi -} - -function outputProgressTick () -{ - if ! $outputtingProgress ; then - echo -en "$beginProgressString" - fi - echo -en "$1" - outputtingProgress=true -} - -function clearProgress () -{ - echo -ne "\r\033[2K" - outputtingProgress=false -} - -beginProgressString="" - -function beginProgress () -{ - # erase the line but stay on it - if $outputtingProgress ; then - echo -ne "\r\033[2K" - fi - if [ ! -z "$1" ]; then - beginProgressString="$1 " - echo -en "$beginProgressString" - - outputtingProgress=true - fi -} - - -function versionStringToNumber () -{ - local local p4="" ; local p5="" ; local p6="" - local major=""; local minor="" - - # first character should be 'v' so first awk parameter will be empty and is not prited into the read command - # - # version number formats: v2.40, v2.40~6, v2.40-large-7, v2.40~6-large-7 - # so we must adjust how we use paramters read from the version string - # and parsed by awk - # if no beta make sure release is greater than any beta (i.e., a beta portion of 999) - - read major minor p4 p5 p6 <<< $(echo $1 | awk -v FS='[v.~-]' '{print $2, $3, $4, $5, $6}') - ((versionNumber = major * 1000000 + minor * 1000)) - if [ -z $p4 ] || [ $p4 = "large" ]; then - ((versionNumber += 999)) - else - ((versionNumber += p4)) - fi - if [ ! -z $p4 ] && [ $p4 = "large" ]; then - ((versionNumber += p5 * 1000)) - large=$p5 - elif [ ! -z $p6 ]; then - ((versionNumber += p6 * 1000)) - fi -} - -# removing a nested set of directories sometimes results in permission denied the first time - # so try several times to be sure - -function deleteNestedDirectories () -{ - rm -rf "$1" &> /dev/null - if [ -d "$1" ] ; then - rm -rf "$1" &> /dev/null - if [ -d "$1" ] ; then - rm -rf "$1" - fi - fi -} - - -yesNoPrompt () -{ - response='' - while true; do - /bin/echo -n "$*" - read response - case $response in - [yY]*) - yesResponse=true - break - ;; - [nN]*) - yesResponse=false - break - ;; - *) - esac - done -} - - -#### script code begins here -packageList="" -doAllPackages=false -globalEndAction='' -for param in $* ; do - case $param in - -[pP]*) - logMessage "working copies will be preserved - packages will not be updated" - globalEndAction='preserve' - ;; - -[dD]*) - logMessage "working copies will be deleted - packages will not be updated" - globalEndAction='delete' - ;; - -[uU]*) - logMessage "packages will be updated without prompting" - globalEndAction='update' - ;; - -[rR]*) - logMessage "packages will be restored from backups" - globalEndAction='restore' - ;; - all) - doAllPackages=true - ;; - *) - packageList+=" "$1 - esac - shift -done -if $doAllPackages ; then - packageList=$allPackages -elif [ -z "$packageList" ]; then - logMessage "ERROR no packages specified - use 'all' for all packages" - exit -fi - -if [ "$globalEndAction" == "restore" ]; then - for package in $packageList; do - sourceDirectory="$packageRoot/$package" - sourceFiles="$sourceDirectory/FileSets" - backupDirectory="$packageRoot/$package.backup" - backupFiles="$backupDirectory/FileSets" - if [ ! -d "$backupDirectory" ]; then - logMessage "WARNING $package: no backup found - package NOT restored" - continue - fi - logMessage "WARNING $package: restored from backup" - deleteNestedDirectories "$sourceFiles" - mv "$backupFiles" "$sourceFiles" - if [ -f "$backupFiles/obsoleteVersion" ]; then - mv -f "$backupFiles/obsoleteVersion" "$sourceDirectory" - fi - if [ -f "$backupFiles/firstCompatibleVersion" ]; then - mv -f "$backupFiles/firstCompatibleVersion" "$sourceDirectory" - fi - deleteNestedDirectories $backupDirectory - done - exit -fi - -# make the version list from the directories in stock files -# version lists are sorted so the most recent version is first -tempList=() -stockVersionList=($(ls -d "$stockFiles"/v* 2> /dev/null)) -for entry in ${stockVersionList[@]} ; do - version=$(basename $entry) - versionFile="$stockFiles/$version/opt/victronenergy/version" - realVersion=$(cat "$versionFile" | head -n 1) - - if [ $version != $realVersion ]; then - directoryName=$(basename $stockFiles)/$version - logMessage "ERROR $directoryName name does not mactch Venus $realVersion - can't continue" - exit - fi - versionStringToNumber $version - tempList+=("$version:$versionNumber") -done -stockVersionList=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) ) - -for package in $packageList; do - packageErrors=0 - packageWarnings=0 - sourceDirectory="$packageRoot/$package" - sourceFiles="$sourceDirectory/FileSets" - workingDirectory="$packageRoot/$package.copy" - workingFiles="$workingDirectory/FileSets" - - if [ ! -d "$sourceDirectory" ] || [ ! -f "$sourceDirectory/version" ]; then - logMessage "$sourceDirectory - not a package directory" - continue - fi - if [ ! -d "$sourceFiles" ]; then - logMessage "$package: no file sets" - continue - fi - if [ ! -f "$sourceFiles/fileList" ]; then - logMessage "$package: no version-dependent files" - continue - fi - fileList=$(cat "$sourceFiles/fileList") - if [ -z "$fileList" ]; then - logMessage "WARNING $package: empty file list" - continue - fi - - # make copy of source package FileSets - beginProgress "$package: making working copy" - deleteNestedDirectories "$workingDirectory" - mkdir -p "$workingDirectory" - cp -pR "$sourceFiles" "$workingFiles" - if [ -f "$sourceDirectory/obsoleteVersion" ]; then - cp -p "$sourceDirectory/obsoleteVersion" "$workingDirectory" - fi - if [ -f "$sourceDirectory/firstCompatibleVersion" ]; then - cp -p "$sourceDirectory/firstCompatibleVersion" "$workingDirectory" - fi - # compute compatible version range - if [ -f "$workingDirectory/obsoleteVersion" ]; then - versionStringToNumber $(cat "$workingDirectory/obsoleteVersion") - obsoleteVersion=$versionNumber - else - obsoleteVersion=999999999 - fi - if [ -f "$workingDirectory/firstCompatibleVersion" ]; then - versionStringToNumber $(cat "$workingDirectory/firstCompatibleVersion") - firstVersion=$versionNumber - else - firstVersion=0 - fi - - # append the package's existing file sets NOT in the stock versions - # to the END of the stock files list - # this insures these file sets contain only files used by that or other unused versions - sourceFileSets=($(ls -d "$sourceFiles"/v* 2> /dev/null)) - tempList=() - for entry in ${sourceFileSets[@]} ; do - version=$(basename $entry) - if [ ! -d "$stockFiles/$version" ]; then - versionStringToNumber $version - tempList+=($version:$versionNumber) - fi - done - existingFileSets=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) ) - allFileSets=(${stockVersionList[@]}) - allFileSets+=(${existingFileSets[@]}) - - # move incompatible versions to the end of the list - # so that real files end up in a supported file set - obsoleteFileSets=() - tempList=() - for entry in ${allFileSets[@]} ; do - IFS=':' read version versionNumber <<< "$entry" - if (( $versionNumber >= $obsoleteVersion )) || (( $versionNumber < $firstVersion )); then - obsoleteFileSets+=($version:$versionNumber) - else - tempList+=($version:$versionNumber) - fi - done - allFileSets=(${tempList[@]}) - allFileSets+=(${obsoleteFileSets[@]}) - allFileSetsLength=${#allFileSets[@]} - - # clean up flag files from a previous run - rm -f "$workingFiles"/*/INCOMPATIBLE_VERSION - rm -f "$workingFiles"/*/UNUSED_FILE_SET - rm -f "$workingFiles"/*/INCOMPLETE - rm -f "$workingFiles"/*/COMPLETE - rm -f "$workingFiles"/*/LINKS_ONLY - rm -f "$workingFiles"/*/*.NO_ORIG - rm -f "$workingFiles"/*/*.NO_REPLACEMENT - rm -f "$workingFiles"/*/*.NO_REPLACEMENT_LINK - rm -f "$workingFiles"/*/*.CHECK_REPLACEMENT - rm -f "$workingFiles"/*/NEW_FILE_SET - rm -f "$workingFiles"/*/*.MATCHES_PREVIOUS - - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version versionNumber <<< "${allFileSets[$i1]}" - - fileSet1="$workingFiles/$version" - if [ ! -d "$fileSet1" ]; then - mkdir "$fileSet1" - touch "$fileSet1/NEW_FILE_SET" - fi - # check to see if package is compatible with this Venus version - if (( $versionNumber >= $obsoleteVersion )) || (( $versionNumber < $firstVersion )); then - touch "$fileSet1/INCOMPATIBLE_VERSION" - fi - - done - - beginProgress "$package: updating file sets" - for file in $fileList ; do - baseName=$(basename "$file") - outputProgressTick "." - # use alternate original if present - if [ -f "$workingFiles/$baseName.ALT_ORIG" ]; then - useAltOrig=true - altOrigFile=$(cat "$workingFiles/$baseName.ALT_ORIG") - else - useAltOrig=false - altOrigFile="" - fi - - # move real files to newest file set - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - stockFileSet1="$stockFiles/$version1" - # if stock file set does not exist, or this is an incompatible version - # don't move files here - # this will allow file sets for versions no longer supported to be removed - # an error result if a replacement in this version is needed for other file sets - if [ ! -d "$stockFileSet1" ] || [ -f "$fileSet1/INCOMPATIBLE_VERSION" ]; then - continue - fi - - replacement1="$fileSet1/$baseName" - if [ -f "$replacement1" ] && [ ! -L "$replacement1" ]; then - replacement1exists=true - else - replacement1exists=false - fi - orig1="$fileSet1/$baseName.orig" - # select appropirate stock file - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - else - stockFile1="$stockFileSet1$file" - fi - - if [ ! -f "$stockFile1" ]; then - if $useAltOrig ; then - logMessage "ERROR $package: $version1 $baseName stock file missing (move) - check ALT_ORIG" - touch "$fileSet1/$baseName.CHECK_ALT_ORIG" - else - logMessage "ERROR $package: $version1 $baseName stock file missing (move) - consider using an ALT_ORIG" - fi - touch "$fileSet1/$baseName.NO_STOCK_FILE" - touch "$fileSet1/INCOMPLETE" - logMessage "can't continue" - exit - fi - - # look for a match (stock files) in older file sets - # and relocate if found - checkLinks=false - for (( i2 = $i1 + 1; i2 < $allFileSetsLength; i2++ )); do - IFS=':' read version2 version2number <<< "${allFileSets[$i2]}" - fileSet2="$workingFiles/$version2" - replacement2="$fileSet2/$baseName" - orig2="$fileSet2/$baseName.orig" - - if [ -L "$replacement2" ] ; then - replacement2isLink=true - replacement2isRealFile=false - elif [ -f "$replacement2" ] ; then - replacement2isRealFile=true - replacement2isLink=false - else - replacement2isRealFile=false - replacement2isLink=false - fi - # USE_ORIGINAL is valid only if the original file also exists (and is not a sym link) - if [ -f "$replacement2.USE_ORIGINAL" ] && [ -f $orig2 ] && [ ! -L $orig2 ]; then - useOrigFlag2=true - else - useOrigFlag2=false - fi - if $replacement2isRealFile || $useOrigFlag2 || [ -f "$fileSet2/NEW_FILE_SET" ]; then - doStockCheck=true - else - doStockCheck=false - fi - - stockMatch=false - if $doStockCheck ; then - if [ -d "$stockFiles/$version2" ]; then - # select appropirate original file - if $useAltOrig ; then - stockFile2="$stockFiles/$version2$altOrigFile" - else - stockFile2="$stockFiles/$version2$file" - fi - if [ ! -f "$stockFile2" ]; then - if $useAltOrig ; then - logMessage "ERROR $package: $version2 $baseName stock file missing - check ALT_ORIG" - touch "$fileSet2/$baseName.CHECK_ALT_ORIG" - else - logMessage "ERROR $package: $version2 $baseName stock file missing - consider using an ALT_ORIG" - fi - touch "$fileSet2/$baseName.NO_STOCK_FILE" - touch "$fileSet2/INCOMPLETE" - logMessage "can't continue" - exit - fi - - # stock files match - cmp -s "$stockFile2" "$stockFile1" > /dev/null - if [ $? -eq 0 ]; then - stockMatch=true - fi - # no stock files but existing file set - elif $replacement2isRealFile && [ -f "$orig2" ] ; then - # existing orig matches stock - cmp -s "$orig2" "$stockFile1" - if [ $? -eq 0 ] ;then - stockMatch=true - fi - fi - fi - if $stockMatch ; then - moveReplacement=true - if $replacement2isRealFile ; then - if $replacement1exists ; then - cmp -s "$replacement1" "$replacement2" /dev/null - if [ $? -ne 0 ]; then - logMessage "ERROR $package: $baseName $version1 and $version2 replacements differ but same stock files" - touch "$fileSet1/$baseName.CHECK_REPLACEMENT" - touch "$fileSet2/$baseName.CHECK_REPLACEMENT" - moveReplacement=false - fi - fi - if $moveReplacement ; then - mv -f "$replacement2" "$replacement1" - rm -f "$fileSet1/$baseName.USE_ORIGINAL" - ln -sf "../$version1/$baseName" "$replacement2" - cp -f "$stockFile1" "$orig1" - previousLink="../$version2/$baseName" - checkLinks=true - fi - elif $useOrigFlag2 ; then - touch "$replacement1.USE_ORIGINAL" - touch "$replacement2.USE_ORIGINAL" - fi - - if [ -f "$orig2" ]; then - mv -f "$orig2" "$orig1" - fi - fi - - # relink replacement to new location - if $checkLinks && $replacement2isLink ; then - if [ "$(readlink "$replacement2")" == "$previousLink" ]; then - ln -sf "../$version1/$baseName" "$replacement2" - fi - fi - done # for i2 - done # for i1 (update) - - # make another pass and fill in links that were missed in the first past - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - replacement1="$fileSet1/$baseName" - # must be a real replacement (not link) - if [ ! -f "$replacement1" ] || [ -L "$replacement1" ]; then - continue - fi - - stockFileSet1="$stockFiles/$version1" - if [ ! -d "$stockFileSet1" ]; then - continue - fi - - # if no replacement, search for one that we can link to - for (( i2 = $i1 + 1; i2 < $allFileSetsLength; i2++ )); do - IFS=':' read version2 version2number <<< "${allFileSets[$i2]}" - fileSet2="$workingFiles/$version2" - replacement2="$fileSet2/$baseName" - # skip if replacement already exists - if [ -e "$replacement2" ] ; then - continue - fi - - # select appropirate stock files - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - stockFile2="$stockFiles/$version2$altOrigFile" - else - stockFile1="$stockFileSet1$file" - stockFile2="$stockFiles/$version2$file" - fi - # stock files match - create link - cmp -s "$stockFile2" "$stockFile1" > /dev/null - if [ $? -eq 0 ]; then - ln -sf "../$version1/$baseName" "$replacement2" - fi - done # for i2 - done # for i1 (missing sym links) - done # for file - - # check to see if a non-versioned file is appropriate -- but only if no errors were found - reloadFileList=false - if (( $packageErrors == 0 )) ; then - for file in $fileList ; do - realFileCount=0 - baseName=$(basename "$file") - - # file must be be using an alternate stock file - if [ ! -f "$workingFiles/$baseName.ALT_ORIG" ]; then - continue - fi - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - replacement1="$fileSet1/$baseName" - if [ -f "$replacement1" ] && [ ! -L "$replacement1" ]; then - (( realFileCount += 1 )) - - fi - done - - if (( realFileCount == 1 )); then - yesNoPrompt "$package: $baseName - make version-independent (y / n)?: " - if $yesResponse ; then - logMessage "$baseName.ALT_ORIG.UNUSED and $(basename $fileListFile.old) can be removed" - mv -f "$workingFiles/$baseName.ALT_ORIG" "$workingFiles/$baseName.ALT_ORIG.UNUSED" - fileListFile="$workingFiles/fileList" - grep -v "$file" "$fileListFile" > "$fileListFile.tmp" - mv -f "$fileListFile" "$fileListFile.old" - mv -f "$fileListFile.tmp" "$fileListFile" - reloadFileList=true - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - if [ ! -d "$fileSet1" ]; then - continue - fi - replacementFile="$fileSet1/$baseName" - if [ -L "$replacementFile" ]; then - rm -f "$replacementFile" - elif [ -f "$replacementFile" ]; then - mv "$replacementFile" "$workingFiles" - rm -f "$replacementFile.orig" - fi - done - else - logMessage "$baseName remains in version-dependent file sets" - fi - fi - done # for file (version independent check) - fi - - # reload fileList if changed above - if $reloadFileList ; then - fileList=$(cat "$workingFiles/fileList") - if [ -z "$fileList" ]; then - logMessage "WARNING $package: empty file list" - continue - fi - fi - - linksOnlyVersions=() - realFileVersions=() - linksOnlyVersionCount=0 - realFilesVersionCount=0 - beginProgress "$package: final checks" - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - if [ ! -d "$fileSet1" ]; then - continue - fi - outputProgressTick "." - - replacementFilesExist=false - replacmentSymLinksExist=false - for file in $fileList ; do - baseName=$(basename "$file") - - if [ -f "$workingFiles/$baseName.ALT_ORIG" ]; then - useAltOrig=true - altOrigFile=$(cat "$workingFiles/$baseName.ALT_ORIG") - else - useAltOrig=false - altOrigFile="" - fi - - replacement1="$fileSet1/$baseName" - orig1="$fileSet1/$baseName.orig" - - # do final checks for -- must be file, link or USE_ORIG but not more than one - if [ -L "$replacement1" ]; then - symLinkReplacement=true - realReplacement=false - anyReplacement=true - elif [ -f "$replacement1" ]; then - realReplacement=true - symLinkReplacement=false - anyReplacement=true - else - realReplacement=false - symLinkReplacement=false - anyReplacement=false - fi - if [ -f "$orig1" ]; then - origExists=true - else - origExists=false - fi - if [ -f "$replacement1.USE_ORIGINAL" ]; then - useOrigFlag=true - else - useOrigFlag=false - fi - - if ! $anyReplacement && ! $useOrigFlag; then - logMessage "ERROR $package: $baseName $version1 no replacement" - touch "$replacement1.NO_REPLACEMENT" - stockFileSet1="$stockFiles/$version1" - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - else - stockFile1="$stockFileSet1$file" - fi - # fill in missing original file if it exists - if [ ! -f "$orig1" ] && [ -f "$stockFile1" ]; then - cp "$stockFile1" "$orig1" - fi - elif $anyReplacement && $useOrigFlag; then - logMessage "WARNING $package $version1 $baseName replacement exists - removing USE_ORIGINAL flag" - rm "$replacement1.USE_ORIGINAL" - fi - if $symLinkReplacement && $origExists ; then - logMessage "WARNING $package: $baseName $version1 should NOT contain link AND orig file" - elif $realReplacement && ! $origExists ; then - logMessage "ERROR $package: $baseName $version1 must contain real file AND orig file" - touch "$replacement1.NO_ORIG" - fi - - if [ -f "$replacement1.NO_REPLACEMENT" ] \ - || [ -f "$replacement1.CHECK_REPLACEMENT" ] \ - || [ -f "$replacement1.NO_ORIG" ] ; then - touch "$fileSet1/INCOMPLETE" - fi - - # identify real file & symlink in file set for later - if $symLinkReplacement ; then - replacmentSymLinksExist=true - fi - if $realReplacement || ( $useOrigFlag && $origExists ) ; then - replacementFilesExist=true - fi - done # for file - - # if all replacement files are in place, mark the file set COMPLETE - # so _checkFileSets can skip all checks - # COMPLETE tells _checkFileSets to skip all checks and accept the file set as is - if [ -f "$fileSet1/INCOMPLETE" ]; then - rm -f "$fileSet1/COMPLETE" - else - touch "$fileSet1/COMPLETE" - fi - - if ! $replacementFilesExist && $replacmentSymLinksExist ; then - touch "$fileSet1/LINKS_ONLY" - linksOnlyVersions+=" $version1" - ((linksOnlyVersionCount++)) - elif $replacementFilesExist ; then - realFileVersions+=" $version1" - ((realFilesVersionCount++)) - fi - - # remove file sets for incompatible Venus OS versions - if [ -e "$fileSet1/INCOMPATIBLE_VERSION" ]; then - if $replacementFilesExist ; then - logMessage "WARNING $package: not compatible with Venus $version1 but not empty - consider manual removal" - else - if [ ! -f "$fileSet1/NEW_FILE_SET" ]; then - logMessage "WARNING $package: not compatible with Venus $version1 - file set will not be included in update" - fi - rm -Rf "$fileSet1" - - fi - # not in stock files list - elif [ ! -d "$stockFiles/$version1" ]; then - if $replacementFilesExist ; then - logMessage "WARNING $package: $version1 no longer used but not empty - manual remove is OK" - touch "$fileSet1/UNUSED_FILE_SET" - # no files (empty file set) - else - # log removal of a previous file set if not created with this run - # if it was created with this run, delete it silently - if [ ! -f "$fileSet1/NEW_FILE_SET" ]; then - logMessage "WARNING $package: $version1 no longer used and contains only links - removing file set" - fi - rm -rf "$fileSet1" - fi - fi - - if [ -f "$fileSet1/NEW_FILE_SET" ]; then - logMessage "$package: new file set $version1" - fi - - # remove temporary files - done # for i1 (final checks) - rm -f "$workingFiles/v"*/*tmp - rm -f "$workingFiles/v"*/NEW_FILE_SET - - if [ ! -z "$realFileVersions" ]; then - logMessage "$package: $realFilesVersionCount file sets containing real files:$realFileVersions" - fi - if [ ! -z "$linksOnlyVersions" ]; then - logMessage "$package: $linksOnlyVersionCount file sets containing only links:$linksOnlyVersions" - fi - - if [ "$packageErrors" == 0 ]; then - errorText="no errors " - else - errorText="$totalErrors ERRORS " - fi - if [ "$packageWarnings" == 0 ]; then - warningText="no warnings" - else - warningText="$totalWarnings WARNINGS" - fi - - logMessage "$package complete $errorText $warningText" - - baseName=$(basename $workingDirectory) - - if [ -z "$globalEndAction" ]; then - echo - echo "select to finish:" - echo " update $package (u)" - echo " preserve working copy for inspection (p)" - echo " discard working copy (d)" - while true ; do - read -p "choose action from list above (u / p / d): " response - case $response in - [uU]*) - endAction='update' - break - ;; - [pP]*) - endAction='preserve' - break - ;; - [dD]*) - endAction='delete' - break - ;; - *) - esac - done - else - endAction=$globalEndAction - fi - - case $endAction in - preserve) - logMessage "$package unchanged - changes preserved as $baseName" - ;; - delete) - logMessage "$package unchanged - $baseName removed" - deleteNestedDirectories "$workingDirectory" - ;; - update) - logMessage "$package: updating file sets - backup in $package.backup" - deleteNestedDirectories "$package.backup" - mkdir "$package.backup" - mv "$sourceFiles" "$package.backup" - if [ -f "$sourceDirectory/obsoleteVersion" ]; then - mv -f "$sourceDirectory/obsoleteVersion" "$package.backup" - fi - if [ -f "$sourceDirectory/firstCompatibleVersion" ]; then - mv -f "$sourceDirectory/firstCompatibleVersion" "$package.backup" - fi - - deleteNestedDirectories "$sourceFiles" - mv "$workingFiles" "$sourceFiles" - if [ -f "$workingDirectory/obsoleteVersion" ]; then - mv -f "$workingDirectory/obsoleteVersion" "$sourceDirectory" - fi - if [ -f "$workingDirectory/firstCompatibleVersion" ]; then - mv -f "$workingDirectory/firstCompatibleVersion" "$sourceDirectory" - fi - deleteNestedDirectories $workingDirectory - ;; - *) - logMessage "ERROR: invalid end action $endAction" - esac -done # for package - -# review all file sets and report any that only contain sym links across all packages -# it would be possile to remove those verions from stock files without loosing any data -# this check is only done if updating all file sets and there are no errors -if $doAllPackages && [ "$totalErrors" == 0 ]; then - for entry in ${stockVersionList[@]} ; do - IFS=':' read version versionNumber <<< "$entry" - linksOnly=true - for package in $packageList; do - fileSet="$packageRoot/$package/FileSets/$version" - if [ ! -e "$fileSet/LINKS_ONLY" ]; then - linksOnly=false - break - fi - done - if $linksOnly ; then - logMessage "$version: only links in all packages - stock version could be removed" - fi - done -fi - -if [ "$totalErrors" == 0 ]; then - errorText="no errors " -else - errorText="$totalErrors ERRORS " -fi -if [ "$totalWarnings" == 0 ]; then - warningText="no warnings" -else - warningText="$totalWarnings WARNINGS" -fi - -logMessage "updateFileSets complete $errorText $warningText" diff --git a/updateFileSets-partilaFileSets b/updateFileSets-partialFileSets similarity index 100% rename from updateFileSets-partilaFileSets rename to updateFileSets-partialFileSets diff --git a/venus-data.UninstallPackages.tgz b/venus-data.UninstallPackages.tgz index f82b966..91a8419 100644 Binary files a/venus-data.UninstallPackages.tgz and b/venus-data.UninstallPackages.tgz differ diff --git a/venus-data.tgz b/venus-data.tgz index 1f3a550..0f6d04a 100644 Binary files a/venus-data.tgz and b/venus-data.tgz differ diff --git a/version b/version index 0b880fd..305e209 100644 --- a/version +++ b/version @@ -1 +1 @@ -v5.15 +v5.16