Skip to content

Commit

Permalink
resize root partition and check for room on file systems before allow…
Browse files Browse the repository at this point in the history
…ing install
  • Loading branch information
kwindrem committed Nov 8, 2023
1 parent 54fb396 commit 6a9a574
Show file tree
Hide file tree
Showing 12 changed files with 693 additions and 362 deletions.
39 changes: 23 additions & 16 deletions CommonResources
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,18 @@ backupActiveFile ()
#
# updateActiveFile sourceFile activeFile
# a separate source (replacement) file is specified
# either as a full path to the actual file
# or as the basename of a file to be found in the version directory or FileSets
#
# both sourceFile and activeFile must be a full path to the file
#
# if the update fails, scriptAction is changed to UNINSTALL

updateActiveFile ()
{
sourceFound=false
thisFileUpdated=false

sourceFile="$1"
local sourceFound=false
local baseName
local sourceFile="$1"
local destinationFile

# separate replacement file specified
if [ $# == 2 ]; then
Expand All @@ -199,13 +200,13 @@ updateActiveFile ()

# look for source in FileSets
if ! $sourceFound ; then
sourceFile="$(basename "$sourceFile")"
baseName="$(basename "$sourceFile")"
# found in version directory
if [ -f "$fileSet/$sourceFile" ]; then
sourceFile="$fileSet/$sourceFile"
if [ -f "$fileSet/$baseName" ]; then
sourceFile="$fileSet/$baseName"
sourceFound=true
elif [ -f "$pkgFileSets/$sourceFile" ]; then
sourceFile="$pkgFileSets/$sourceFile"
elif [ -f "$pkgFileSets/$baseName" ]; then
sourceFile="$pkgFileSets/$baseName"
sourceFound=true
fi
fi
Expand All @@ -217,10 +218,8 @@ updateActiveFile ()
return
# if not flagged, this is a fatal error
else
logMessage "ERROR: no replacement file for $sourceFile"
thisFileUpdated=false
logMessage "ERROR: no soure file for replacement - can't continue with install'"
scriptAction='UNINSTALL'
touch "$fileSet/INCOMPLETE"
installFailed=true
fi
return
Expand Down Expand Up @@ -640,9 +639,17 @@ while [ $# -gt 0 ]; do
shift
done

# make sure rootfs is mounted R/W
if [ -f /opt/victronenergy/swupdate-scripts/remount-rw.sh ]; then
/opt/victronenergy/swupdate-scripts/remount-rw.sh
# 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
fi

# make sure the root partition has space for the package
# arbitrary minimum size of 10 MB for now
availableSpace=$(df -m / | tail -1 | awk '{print $4}')
if (( $availableSpace < 10 )); then
logMessage "no room for modified files on /root ($availableSpace MB remaining) - can't continue"
exit $EXIT_ROOT_FULL
fi

# move old installedFlag ("...inInstalled...")
Expand Down
2 changes: 2 additions & 0 deletions EssentialResources
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ EXIT_INCOMPATIBLE_PLATFOM=253
EXIT_FILE_SET_ERROR=252
EXIT_OPTIONS_NOT_SET=251
EXIT_RUN_AGAIN=250
EXIT_ROOT_FULL=249
EXIT_DATA_FULL=248
# old variables - keep for compatibility
exitReboot=$EXIT_REBOOT
exitSuccess=$EXIT_SUCCESS
Expand Down
4 changes: 4 additions & 0 deletions FileSets/PageSettingsPackageEdit.qml
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ MbPage {
return qsTr ("must install\nfrom command line" )
else if (incompatibleReason == 'NO_FILE_SET')
return qsTr ( "no file set for\n" + osVersion )
else if (incompatibleReason == 'ROOT_FULL')
return qsTr ( "no room on root partition" )
else if (incompatibleReason == 'DATA_FULL')
return qsTr ( "no room on data partition" )
else
return qsTr ("incompatible ???" ) // compatible for unknown reason
}
Expand Down
41 changes: 35 additions & 6 deletions PackageManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
# 'VERSION' if the system version is outside the package's acceptable range
# 'PLATFORM' package can not run on this platform
# 'NO_FILE_SET' missing or incomplete file set for Venus OS version
# 'ROOT_FULL' no room on root partition to install package modificaitons
# 'DATA_FULL' no room on /data partition to install package modificaitons
# 'CMDLINE' setup must be run from command line
# currently only for Raspberry PI packages only
#
Expand Down Expand Up @@ -127,6 +129,9 @@
EXIT_FILE_SET_ERROR = 252
EXIT_OPTIONS_NOT_SET = 251
EXIT_RUN_AGAIN = 250
EXIT_ROOT_FULL = 249
EXIT_DATA_FULL = 248

EXIT_ERROR = 255 # generic error
# install states only
ERROR_NO_SETUP_FILE = 999
Expand Down Expand Up @@ -2402,12 +2407,12 @@ def GitHubDownload (self, packageName= None, source=None):

# attempt to locate a directory that contains a version file
# the first directory in the tree starting with tempDicrectory
# is returnd
# is returned
unpackedPath = LocatePackagePath (tempDirectory)
if unpackedPath == None:
PackageClass.UpdateDownloadPending (packageName, False)
shutil.rmtree (tempDirectory)
logging.error ( "GitHubDownload: no archive path for " + packageName)
logging.error ( "GitHubDownload: no archive path for " + packageName )
return False

# move unpacked archive to package location
Expand All @@ -2418,7 +2423,10 @@ def GitHubDownload (self, packageName= None, source=None):
DbusIf.LOCK ()
if os.path.exists (packagePath):
os.rename (packagePath, tempPackagePath)
shutil.move (unpackedPath, packagePath)
try:
shutil.move (unpackedPath, packagePath)
except:
logging.error ( "GitHubDownload: couldn't relocate " + packageName )
if os.path.exists (tempPackagePath):
shutil.rmtree (tempPackagePath, ignore_errors=True) # like rm -rf
DbusIf.UNLOCK ()
Expand Down Expand Up @@ -2713,6 +2721,18 @@ def InstallPackage ( self, packageName=None, source=None , direction='install' )
where=sendStatusTo, logLevel=ERROR )
if source == 'GUI':
DbusIf.SetGuiEditAction ( 'ERROR' )
elif returnCode == EXIT_ROOT_FULL:
package.SetIncompatible ('ROOT_FULL')
DbusIf.UpdateStatus ( message=packageName + " no room on root partition ",
where=sendStatusTo, logLevel=ERROR )
if source == 'GUI':
DbusIf.SetGuiEditAction ( 'ERROR' )
elif returnCode == EXIT_DATA_FULL:
package.SetIncompatible ('DATA_FULL')
DbusIf.UpdateStatus ( message=packageName + " no room on data partition ",
where=sendStatusTo, logLevel=ERROR )
if source == 'GUI':
DbusIf.SetGuiEditAction ( 'ERROR' )
# unknown error
elif returnCode != 0:
DbusIf.UpdateStatus ( message=packageName + " " + direction + " unknown error " + str (returnCode),
Expand Down Expand Up @@ -2907,7 +2927,10 @@ def transferPackage (self, path, autoInstallOverride=False):
shutil.rmtree (tempPackagePath, ignore_errors=True) # like rm -rf
if os.path.exists (packagePath):
os.rename (packagePath, tempPackagePath)
shutil.move (unpackedPath, packagePath)
try:
shutil.move (unpackedPath, packagePath)
except:
logging.error ( "transferPackages: couldn't relocate " + packageName )
if os.path.exists (tempPackagePath):
shutil.rmtree (tempPackagePath, ignore_errors=True) # like rm -rf
# set package one-time install flag so this package is installed regardless of other flags
Expand Down Expand Up @@ -3142,7 +3165,10 @@ def settingsRestore (self, backupPath, settingsOnly = False):
for overlay in overlayFiles:
if overlay[0] == ".":
continue
shutil.copy ( overlaySourceDir + "/" + overlay, overlayDestDir )
try:
shutil.copy ( overlaySourceDir + "/" + overlay, overlayDestDir )
except:
logging.error ("settingsRestore: overlay create failed for " + overlay)
overlayCount += 1

# restore setup script options
Expand All @@ -3154,7 +3180,10 @@ def settingsRestore (self, backupPath, settingsOnly = False):
shutil.rmtree (optionsDestDir)

if os.path.isdir (optionsSourceDir):
shutil.copytree ( optionsSourceDir, optionsDestDir )
try:
shutil.copytree ( optionsSourceDir, optionsDestDir )
except:
logging.error ("settingsRestore: options restore failed")

logging.warning ("settings restore completed - " + str(settingsCount) + " settings and " + str (overlayCount) + " overlays")

Expand Down
18 changes: 16 additions & 2 deletions ReadMe
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ CAUTION:
Note that removal does not actually remove the package so other setup scripts
will continue to function.

Note: You can install other packages using wget as described above.
Or you can download the .tgz file and put that on a USB stick and plug that into the GX device.
PackageManager will detect the file and install the package.


ssh access:

Expand Down Expand Up @@ -110,16 +114,26 @@ Third, if you have terminal or ssh access, try running the package setup scripts

Fourth, try booting to the previous Venus OS version (in Stored backup firmware)
Then perform a fresh Online firmware update to the latest version or use the .swu update via removable media.
These procedures are documented: https://www.victronenergy.com/media/pg/Cerbo_GX/en/gx---how-to-update-firmware.html

Use the Settings / Firmware / Stored backup formware menu if you have GUI access.

If you don't have GUI access, you can also switch to the backup version from the command line:
/opt/victronenergy/swupdate-scripts/set-version.sh 2

You can also force a firmware upate from the command line if you have ssh or terminal access:
For on-line updates:
/opt/victronenergy/swupdate-scripts/check-swupdate.sh -force -update
For updates from removable media:
/opt/victronenergy/swupdate-scripts/check-swupdate.sh -force -update -offline

Fifth, perform the Blind uninstall procedure below.

Finally, if you are running on a Raspberry PI, you can reimage the system SD card.
Finally:
If you are running on a Raspberry PI, you can reimage the system SD card.

If you have a Cerbo, you can reimage it using this procedure:
https://community.victronenergy.com/questions/204255/cerbo-gx-bricked-how-to-recover.html

Note: this will wipe out all settings and you'll need to reconfigure the GX device from scratch.

The Victron "restore factory default" procedure can be used to will wipe out all settings.
Expand Down
2 changes: 1 addition & 1 deletion blindInstall/SetupHelperVersion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v5.10
v5.11
12 changes: 11 additions & 1 deletion changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
v5.11:
check for room on file systems before allowing install
resize root partition before installing a package
the above issues are critical to avoid bricking systems !!!!!!
updateFileSets:
better error checking and more status while running long loops
a replacement file and USE_ORIGINAL flag was incorrectly allowed
the replacement file has priority during package install so
this was not a severe issue, but USE_ORIGINAL is now removed in this case

v5.10:
updateFileSets: check for errors before moving version-independent files

Expand All @@ -8,7 +18,7 @@ v5.8:
fixed bugs in updateFileSets introduced in v5.7

v5.7:
updateFileSets: make changes to the backup of the package
updateFileSets: make changes to the copy of the package
instead of to the main package directory
so package is not updated until changes are accepted
updateFileSets: check for version-independent files in file sets
Expand Down
22 changes: 18 additions & 4 deletions setup
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,33 @@ fi

if [ $scriptAction == 'INSTALL' ] ; then
# modify PageSettings here so SetupHelper is independent of Venus OS verison
origFile=""
if [ -f "$qmlDir/PageSettings.qml.orig" ]; then
origFile="$qmlDir/PageSettings.qml.orig"
else
origFile="$qmlDir/PageSettings.qml"
lineCount=$(wc "$qmlDir/PageSettings.qml.orig" | awk '{print $1}')
if (( $lineCount > 50 )); then
origFile="$qmlDir/PageSettings.qml.orig"
fi
elif [ -z "$origFile" ]; then
lineCount=$(wc "$qmlDir/PageSettings.qml" | awk '{print $1}')
if (( $lineCount > 50 )); then
origFile="$qmlDir/PageSettings.qml"
fi
fi
if (( $(grep -c "PackageManager" $origFile) > 0)); then
if [ -z "$origFile" ]; then
logMessage "ERROR: PageSettings.qml not found - can't continue"
exit $EXIT_ERROR
elif (( $(grep -c "PackageManager" $origFile) > 0)); then
logMessage "WARNING: PageSettings.qml already modified for PackageManager -- skipping that modification"
else
rm -f "/var/volatile/tmp/PageSettings.qml"
echo "//////// modified to insert PackageManager menu" > "/var/volatile/tmp/PageSettings.qml"
# find line with second to last }
insertBefore=$(awk '{print NR " " $s}' "$origFile" | grep '}' | tail -2 | head -n 1 | awk '{print $1}')
((insertBefore -= 1))
if (( $insertBefore < 10 )); then
logMessage "ERROR: PageSettings.qml could not be modified - can't continue"
exit $EXIT_ERROR
fi
# include all lines before that one
head -n $insertBefore $origFile >> "/var/volatile/tmp/PageSettings.qml"
# file with PackageManager menu code includes the last two }
Expand Down
Loading

0 comments on commit 6a9a574

Please sign in to comment.