Index: cho.sh =================================================================== diff -u --- cho.sh (revision 0) +++ cho.sh (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -0,0 +1,30 @@ +#!/bin/bash + +branch="$1" +if [ "$1" = "" ]; then + echo "branch is empty" + exit 1 +else + echo "branch is $1" +fi + +function checkout() { + local repository="$1" + out=$(git -C "$repository" checkout -b "$branch" 2>&1 || git -C "$repository" checkout "$branch" 2>&1 ) + if [ ! -z $? ]; then + echo " *** $repository checkout failed *** " + echo "$out" + echo "" + else + out=$(git -C "$repository" pull 2>&1) + if [ ! -z $? ]; then + echo " *** $repository pull failed *** " + echo "$out" + echo "" + fi + fi +} + +checkout "../ui.scripts" +checkout "../ui.config" +checkout "../common" Index: main.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- main.cpp (.../main.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ main.cpp (.../main.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -102,6 +102,7 @@ QString gActiveCANBus = "can0"; bool gEnableManufacturing = false ; +bool gEnableUpdating = false ; bool gUseRootHome = false ; QString gParserErrorText = ""; @@ -271,6 +272,12 @@ QCoreApplication::translate("main", "In case the application is not in Manufacturing Setup but needs to use root home folder for configurations.")); parser.addOption(optionUseRootHome); + // --- -U : Update mode + QCommandLineOption optionEnableUpdating( + QStringList() << "U" << "enable-Update-mode", + QCoreApplication::translate("main", "Enables the update mode to update only necessary files during the update and keep the rest.")); + parser.addOption(optionEnableUpdating); + // --- parse command lines if ( ! parser.parse(qApp->arguments()) ) { gParserErrorText = parser.errorText(); @@ -294,6 +301,7 @@ gEnableDryDemo = parser.isSet(optionEnableDryDemo ); gEnableManufacturing = parser.isSet(optionEnableManufacturing ); + gEnableUpdating = parser.isSet(optionEnableUpdating ); gUseRootHome = parser.isSet(optionUseRootHome ); if ( parser.isSet(optionActiveCANBus ) ) { @@ -376,16 +384,16 @@ * \brief lockdown * \details runs the lockdown shellscript as a detached process * and ment to be executed just before the application quits - * and only when application running in manufacturing mode. + * and only when application running in manufacturing or update mode. * Must not stop application shutdown in any way. * If any error happens it only logs. */ void lockdown() { // there are two setup scenarios: - // only during setup mode which is -E (manufacturing setup) application is running under the root user permissions + // only during setup mode which is -E (manufacturing setup) or -U -E (update setup) application is running under the root user permissions // and all the files are copied to the /home/root/ te later be copied to secured locations // and that will be done by lockdown.sh script running within application after the user is done with the setup and QUIT s the application. - if ( gEnableManufacturing ) { + if ( gEnableManufacturing || gEnableUpdating ) { QString scriptName = Storage::Device_Lockdown; quint16 errorCode; QString errorText; Index: sources/ApplicationController.cpp =================================================================== diff -u -r9171bf54844dcec41ee5e6feb7ee4d87ef5ebbb4 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 9171bf54844dcec41ee5e6feb7ee4d87ef5ebbb4) +++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -621,12 +621,12 @@ void ApplicationController::onPOSTDone(bool /*vPass*/) { LOG_DEBUG("ApplicationPOST Done"); - /// in manufacturing mode the configurations must reside in /root/home + /// in manufacturing or update mode the configurations must reside in /root/home /// therefore the settings can be initialized after POST. #ifdef BUILD_FOR_DESKTOP initSettings(); #else - if ( gEnableManufacturing ) initSettings(); + if ( gEnableManufacturing || gEnableUpdating ) initSettings(); #endif } Index: sources/ApplicationController.h =================================================================== diff -u -rab150ad8b7a72e49de84e11343927d83fbbf7ba0 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/ApplicationController.h (.../ApplicationController.h) (revision ab150ad8b7a72e49de84e11343927d83fbbf7ba0) +++ sources/ApplicationController.h (.../ApplicationController.h) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -162,7 +162,7 @@ /*! * \brief didPOSTPass * \details This signal will be emitted when UI is done with the POST and will let other layers to know the result. - * As an example the Manufacturing will not start if the POST failed since it needs POST info for the Encrypted partition. + * As an example the Manufacturing or update will not start if the POST failed since it needs POST info for the Encrypted partition. * \param vPass - true if passed. */ void didPOSTPass (bool vPass); Index: sources/device/DeviceController.cpp =================================================================== diff -u -r9171bf54844dcec41ee5e6feb7ee4d87ef5ebbb4 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 9171bf54844dcec41ee5e6feb7ee4d87ef5ebbb4) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -659,13 +659,16 @@ if ( _deviceCryptSetupRequest._data.mCommand == "mount" ) emit didCryptSetupMount(model._data.mAccepted); - // move the configuration files if the encrypted partition creation was successful. - if ( _deviceCryptSetupRequest._data.mCommand != "setup" ) return; - if ( ! model._data.mAccepted ) return; QString msg = ""; int err = 0 ; //TODO The Settings shall be the Singleton SettingsController and modify the MSettings like the others. Storage::Settings settings; + // moving the configuration files if the encrypted partition creation was successful. + if ( ! model._data.mAccepted ) goto lErr; + if ( gEnableUpdating ) goto lMove; + if ( _deviceCryptSetupRequest._data.mCommand != "setup" ) goto lOut; + +lMove: err = settings.configurationsMove(&msg); if ( err ) { model._data.mAccepted = false ; @@ -674,6 +677,12 @@ emit didAttributeResponse(model.data()); LOG_APPED_UI(model.data().mMessage); } + +lOut: + return; + +lErr: + LOG_DEBUG(QString("Encrypted Partition %1 failed").arg(_deviceCryptSetupRequest._data.mCommand)); } ///////////////////////////////////////////// DeviceBluetoothPaired @@ -860,11 +869,11 @@ */ void DeviceController::checkConfugurationMountReady() { - /// in manufacturing the system is logged with root and configurations are in /home/root + /// in manufacturing or updating the system is logged with root and configurations are in /home/root /// therefore no need to mount the cononfiguraiton partition. - /// also for in manufacturing the partition is being set up + /// also for manufacturing the partition is being set up /// and is less steps for setup if the partition is not mounted. - if ( gEnableManufacturing ) return; + if ( gEnableManufacturing ) return; // it should do the mount when gEnableUpdating, therefore here should not add gEnableUpdating. if ( ! ( _hasThread && _hasSalt ) ) return; DeviceCryptSetupRequestData data; Index: sources/gui/GuiView.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -393,10 +393,11 @@ return Storage::FileHandler::isPathSymLink(vFilePath); } -void GuiView::onPOSTPass(bool vPass) +void GuiView::onPOSTPass(bool vPassed) { - manufactMode( gEnableManufacturing && vPass ); - postPass(vPass); + manufactMode( gEnableManufacturing && vPassed ); + updateMode ( gEnableUpdating && vPassed ); + postPass(vPassed); } /*! Index: sources/gui/GuiView.h =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/gui/GuiView.h (.../GuiView.h) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/gui/GuiView.h (.../GuiView.h) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -80,7 +80,9 @@ READONLY(bool , dryDemoMode , gEnableDryDemo ) READONLY(bool , manufactSetup , gEnableManufacturing ) + READONLY(bool , updateSetup , gEnableUpdating ) READONLY(bool , manufactMode , false ) + READONLY(bool , updateMode , false ) TRIGGER (bool , postPass , false ) @@ -105,7 +107,7 @@ void onSDCardSpaceTooLow(quint8 vAvailablePercent); void onSDCardSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent); - void onPOSTPass (bool vPass); + void onPOSTPass (bool vPassed); public slots: // is public since will be used in the UI and is in the same thread. void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG Index: sources/gui/qml/main.qml =================================================================== diff -u -r889145432dfc3211c5f1bbcf38e548cbbe6b90a8 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/gui/qml/main.qml (.../main.qml) (revision 889145432dfc3211c5f1bbcf38e548cbbe6b90a8) +++ sources/gui/qml/main.qml (.../main.qml) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -259,7 +259,7 @@ function isManager () { _mainMenu.itemPressed(1) } function isSettings () { _mainMenu.itemPressed(2) } - disable : _GuiView.manufactSetup + disable : _GuiView.manufactSetup || _GuiView.updateSetup hidden : true // it should be hidden by default since the landing screen changed to init and it does not have the main menu until the POST passes. titles : [ qsTr("Treatment") , qsTr("Manager") , qsTr("Settings") ] visibleItems : [ true , false , true ] Index: sources/gui/qml/pages/MainStack.qml =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/gui/qml/pages/MainStack.qml (.../MainStack.qml) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/gui/qml/pages/MainStack.qml (.../MainStack.qml) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -38,7 +38,7 @@ // DEBUG: this property can mostly be used for debugging to get pass the initial screen property var initialItem: _postModeScreen - property var _startupScreen: _GuiView.manufactSetup ? _settingsStack : _mainHome + property var _startupScreen: ( _GuiView.manufactSetup || _GuiView.updateSetup ) ? _settingsStack : _mainHome stackView.initialItem : _root.initialItem Index: sources/gui/qml/pages/settings/SettingsStack.qml =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -39,6 +39,36 @@ property bool serviceMode : false + readonly property bool normalMode : ! ( _GuiView.manufactSetup || _GuiView.updateSetup ) + readonly property bool setupMode : _GuiView.manufactSetup || _GuiView.updateSetup + readonly property bool onlyManufacturing : _GuiView.manufactMode && ! _GuiView.updateMode // <...>Mode is true if the POST passes + readonly property bool onlyUpdating : ! _GuiView.manufactMode && _GuiView.updateMode // <...>Mode is true if the POST passes + readonly property bool loggedIn : serviceMode + + + readonly property bool visibleLanguage : false + readonly property bool visibleSWUpdate : false + readonly property bool visibleDGScheduling : false + readonly property bool visibleCalibration : false + + readonly property bool visibleInformation : true + readonly property bool visibleVolumeBrightness : true + readonly property bool visibleWiFi : true + readonly property bool visibleBluetooth : true + readonly property bool visibleExportLogs : true + + readonly property bool visibleServicePassword : normalMode && ! loggedIn + readonly property bool visibleDGCleaning : normalMode + readonly property bool visibleRoInput : normalMode + readonly property bool visibleRootSSHAccess : loggedIn + readonly property bool visibleFactoryReset : loggedIn + readonly property bool visibleDecommission : loggedIn + readonly property bool visibleSetDateTime : loggedIn + readonly property bool visibleDeviceConfiguration : onlyManufacturing && loggedIn + readonly property bool visibleDeviceRegistration : onlyManufacturing && loggedIn + + + enum ItemsIndex { Information , VolumeBrightness , @@ -79,54 +109,57 @@ qsTr("Factory Reset" ), // FactoryReset qsTr("Decommissioning" ), // Decommission ] - property var itemsEnabled : [ - true , // Information - true , // VolumeBrightness - true , // WiFi - true , // Bluetooth - true , // DGCleaning - true , // DGScheduling - true , // ServicePassword - true , // SetDateTime - true , // ExportLogs - false , // Language - true , // RoInput - false , // Calibration - _GuiView.manufactMode , // Device Configuration - true , // DeviceRegistration - false , // SWUpdate - serviceMode , // RootSSHAccess - serviceMode , // FactoryReset - serviceMode , // Decommission + property var itemsEnabled : [ + true , // Information + true , // VolumeBrightness + true , // WiFi + true , // Bluetooth + true , // DGCleaning + true , // DGScheduling + true , // ServicePassword + true , // SetDateTime + true , // ExportLogs + true , // Language + true , // RoInput + true , // Calibration + true , // Device Configuration + true , // DeviceRegistration + true , // SWUpdate + true , // RootSSHAccess + true , // FactoryReset + true , // Decommission ] property var itemsVisible : [ - true , // Information - true , // VolumeBrightness - true , // WiFi - true , // Bluetooth - ! _GuiView.manufactSetup , // DGCleaning - false /* serviceMode phase 1B */ , // DGScheduling - ! serviceMode && ! _GuiView.manufactSetup , // ServicePassword - serviceMode , // SetDateTime - true , // ExportLogs - false /* serviceMode phase 1 */ , // Language - ! _GuiView.manufactSetup , // RoInput - false /* serviceMode phase 1 */ , // Calibration - _GuiView.manufactMode && serviceMode , // Device Configuration // && serviceMode added to make sure the service mode is confirmed by HD - _GuiView.manufactMode && serviceMode , // DeviceRegistration // && serviceMode added to make sure the service mode is confirmed by HD - false /* serviceMode phase 1 */ , // SWUpdate - serviceMode , // RootSSHAccess - serviceMode , // FactoryReset - serviceMode , // Decommission + visibleInformation , // Information + visibleVolumeBrightness , // VolumeBrightness + visibleWiFi , // WiFi + visibleBluetooth , // Bluetooth + visibleDGCleaning , // DGCleaning + visibleDGScheduling , // DGScheduling + visibleServicePassword , // ServicePassword + visibleSetDateTime , // SetDateTime + visibleExportLogs , // ExportLogs + visibleLanguage , // Language + visibleRoInput , // RoInput + visibleCalibration , // Calibration + visibleDeviceConfiguration , // Device Configuration + visibleDeviceRegistration , // DeviceRegistration + visibleSWUpdate , // SWUpdate + visibleRootSSHAccess , // RootSSHAccess + visibleFactoryReset , // FactoryReset + visibleDecommission , // Decommission ] SettingsHome { id : _settingsHome - title : _GuiView.manufactSetup ? qsTr("Manufacturing Setup") : serviceMode ? qsTr("Service") : qsTr("Device Settings") + title : _GuiView.manufactSetup ? qsTr("Manufacturing Setup") : serviceMode ? qsTr("Service") : _GuiView.updateSetup ? qsTr("Software Update") : qsTr("Device Settings") backVisible : false - confirmVisible : serviceMode - confirmText.text: _GuiView.manufactSetup ? qsTr("QUIT") : qsTr("SHUTDOWN") + //TODO on graceful shutdown, the applicaiton quit shall be used for any applicaiton termination + // and needs to be distinguished between the QUIT or SHUTDOWN touch, + // to know whether to run the lockdown scropt or just quit the app. + confirmVisible : serviceMode || _GuiView.updateMode + confirmText.text: _GuiView.manufactMode || _GuiView.updateMode ? qsTr("COMPLETE") : qsTr("SHUTDOWN") onConfirmClicked: { - if ( _GuiView.manufactSetup ) { + if ( _GuiView.manufactSetup || _GuiView.updateSetup ) { _GuiView.doQuitApplication() } else { @@ -268,9 +301,20 @@ //DEBUG console.log (" 1 ---------- ", _GuiView.manufactMode, _GuiView.manufactSetup, vPass, stackView.initialItem, stackView.currentItem, stackView.depth) if ( _GuiView.manufactSetup ) { - _settingsHome.notificationText = vPass ? "" : qsTr("Application POST Failed") + _settingsHome.notificationText = vPass ? "" : qsTr("Application POST Failed, please shutdown and retry") } } + function onUpdateModeChanged( vPass ) { + if ( _GuiView.UpdateMode ) { + stackView.initialItem = _settingsHome + } + push(stackView.initialItem) + + //DEBUG console.log (" 1 ---------- ", _GuiView.manufactMode, _GuiView.manufactSetup, vPass, stackView.initialItem, stackView.currentItem, stackView.depth) + if ( _GuiView.updateSetup ) { + _settingsHome.notificationText = vPass ? "" : qsTr("Application POST Failed, please shutdown and retry") + } + } } onVisibleChanged: { Index: sources/main.h =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/main.h (.../main.h) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/main.h (.../main.h) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -101,6 +101,7 @@ extern bool gEnableDryDemo ; extern QString gActiveCANBus ; extern bool gEnableManufacturing ; +extern bool gEnableUpdating ; extern bool gUseRootHome ; Index: sources/storage/Settings.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/storage/Settings.cpp (.../Settings.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/storage/Settings.cpp (.../Settings.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -230,12 +230,12 @@ QString src = Settings::location(Location_Enum ::eInit ) ; QString dst = Settings::location(Location_Enum ::eSecured ) ; QString msg = ""; - if ( ! Settings ::configurationsPOST(loc )) { msg = errorMessage(err ); LOG_DEBUG(msg); err = Settings_Error::eError_POST ; goto lOut; } - if ( ! FileHandler ::makeFolder ( dst )) { msg = errorMessage(err ); LOG_DEBUG(msg); err = Settings_Error::eError_MkDir ; goto lOut; } + if ( ! Settings ::configurationsPOST(loc )) { err = Settings_Error::eError_Remove; msg = errorMessage(err ); LOG_DEBUG(msg); goto lOut; } + if ( ! FileHandler ::makeFolder ( dst )) { err = Settings_Error::eError_Copy ; msg = errorMessage(err ); LOG_DEBUG(msg); goto lOut; } for( QString dir : FileHandler::subFolders(src)) { QString sub = src + dir; - if ( FileHandler ::copyFolder (sub, dst )) { msg = errorMessage(err, dir); LOG_DEBUG(msg); err = Settings_Error::eError_Copy ; goto lOut; } - if ( FileHandler ::removeFolder (sub )) { msg = errorMessage(err, dir); LOG_DEBUG(msg); err = Settings_Error::eError_Remove ; goto lOut; } + if ( FileHandler ::copyFolder (sub, dst )) { err = Settings_Error::eError_MkDir ; msg = errorMessage(err, dir); LOG_DEBUG(msg); goto lOut; } + if ( FileHandler ::removeFolder (sub )) { err = Settings_Error::eError_POST ; msg = errorMessage(err, dir); LOG_DEBUG(msg); goto lOut; } } Storage::Settings_Secured(); Index: sources/storage/StorageGlobals.cpp =================================================================== diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec --- sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803) +++ sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 8d5fe7d63e3d86e9d89d5f824347d34479e4e9ec) @@ -20,6 +20,7 @@ #include "StorageGlobals.h" extern bool gEnableManufacturing ; +extern bool gEnableUpdating ; extern bool gUseRootHome ; /*! @@ -71,12 +72,12 @@ // Settings static bool settings_secured = false; - const char *Settings_Path () { return gUseRootHome ? Settings_Path_Init : ( gEnableManufacturing ? ( settings_secured ? Settings_Path_Name: Settings_Path_Init ) : Settings_Path_Name ); } + const char *Settings_Path () { return gUseRootHome ? Settings_Path_Init : ( ( gEnableManufacturing || gEnableUpdating ) ? ( settings_secured ? Settings_Path_Name: Settings_Path_Init ) : Settings_Path_Name ); } void Settings_Secured() { settings_secured = true; } #ifdef BUILD_FOR_TARGET //WARNING: This has to match with the crypt_setup.sh - const char *Settings_Path_Init = "/home/root/.config/"; // this is the manufacturing setup and the user is root. + const char *Settings_Path_Init = "/home/root/.config/"; // this is the manufacturing or update setup and the user is root. const char *Settings_Path_Name = "/var/configurations/"; #else // should be in the project application folder. [is tracking by git] @@ -114,15 +115,10 @@ // Scripts const QString Scripts_Path_Name() { #ifdef BUILD_FOR_TARGET - //TODO The manufacturing mode has to run as root - // after the lockdown.sh ran there would be no root user access - // and I am not sure how we reenable the root ssh - // and if it is a security risk to give denali access to sshd_config to enable the root ssh within UI App - - // lockdown script suppose to be the last thing to do, + // lockdown script suppose to be the last thing to run, // and it is the lockdown.sh script which moves the scripts from root to denali home folder, - // therefore in manufacturing mode we are still running as root. - return QCoreApplication::applicationDirPath() + (gEnableManufacturing ? "/scripts/" : "/scripts/"); + // therefore in manufacturing or update mode we are still running scripts as root. + return QCoreApplication::applicationDirPath() + ( ( gEnableManufacturing || gEnableUpdating )? "/scripts/" : "/scripts/"); #else return "/home/denali/Projects/application/scripts/"; #endif