Refactor the update process: streamline code. When WAIT button is not

active, the a clone or a fix of a defunct repository is possible, but
not more.
If WAIT button is active, the at least the opkg_commnds are executed. If
there are chenged files, they are handkled as wll.
This commit is contained in:
Gerhard Hoffmann 2023-10-30 15:25:49 +01:00
parent 72a2fc781c
commit bef0d4fe12

View File

@ -234,19 +234,23 @@ bool Worker::isRepositoryCorrupted() {
bool Worker::repairCorruptedRepository() {
QDir customerRepository(m_customerRepository);
if (!customerRepository.removeRecursively()) {
Utils::printCriticalErrorMsg("ERROR REMOVING CORR. CUST-REPOSITORY");
m_updateStatus = UpdateStatus(UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED,
QString("REMOVAL OF GIT-REPOSITORY %1 FAILED").arg(m_customerRepository));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription));
emit showErrorMessage("apism sanity check", m_updateStatus.m_statusDescription);
//m_updateStatus = UpdateStatus(UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED,
// QString("REMOVAL OF GIT-REPOSITORY %1 FAILED").arg(m_customerRepository));
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") +
// m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
// m_updateStatus.m_statusDescription));
//emit showErrorMessage("apism sanity check", m_updateStatus.m_statusDescription);
return false;
}
return true;
}
#if 0
int Worker::sendCloneAndCheckoutFailure() {
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE,
QString("CLONE OR CHECKOUT FAILED: ") + m_customerRepository);
@ -360,20 +364,21 @@ int Worker::sendFoundFilesToUpdateSuccess() {
}
int Worker::sendUpdateSucceededAndActivated() {
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSASucceeded(""));
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_SUCCEEDED));
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_ACTIVATED));
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") +
// m_ismasClient.updateOfPSASucceeded(""));
//m_ismasClient.setProgressInPercent(100);
// mark update as activated -> this resets the WAIT button
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAActivated());
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") +
// m_ismasClient.updateOfPSAActivated());
return UPDATE_SUCCESS_AND_ACTIVATED;
}
int Worker::sendFinalResult() {
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_SUCCESS,
QString("Update process succeeded. Reset WAIT."));
@ -386,49 +391,61 @@ int Worker::sendFinalResult() {
return 0;
}
#endif
void Worker::privateUpdate() {
if (!m_mainWindow) {
Utils::printCriticalErrorMsg("m_mainWindow NOT SET");
return;
}
QString func(__PRETTY_FUNCTION__);
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::STARTED));
m_updateProcessRunning = true;
bool sentIsmasLastVersionNotification = false;
emit disableExit();
m_returnCode = -1;
startProgressLoop();
QScopedPointer<UpdateProcessRunning> upr(new UpdateProcessRunning(this));
QDir customerRepository(m_customerRepository);
QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
CONSOLE() << UPDATE_STEP::CHECK_SANITY;
bool initialClone = false; // the customer repository is cloned without
// checking the ISMAS-trigger (WAIT-)button.
// but if there was a sane repository
// available, then the trigger-button must
m_clone = false;
m_repairClone = false;
m_initialClone = false;
// the customer repository is cloned or
// repaired/re-cloned without checking the
// ISMAS-trigger (WAIT-)button.
// Case 1: no existing repository:
// if there was a sane repository
// available, then the trigger-button is
// checked:
// 1: trigger == WAIT: then
// have been activated in ISMAS.
bool continueUpdate = true; // check if git-clone command has timed-out,
// resulting in a corrupted git-repository, which
// does not contain an ./etc-directory
if (isRepositoryCorrupted()) {
if (isRepositoryCorrupted()) { // a not-existing repository is not meant
// to be corrupted
CONSOLE() << UPDATE_STEP::CHECK_SANITY_FAILURE;
if ((continueUpdate = repairCorruptedRepository()) == true) {
m_repairClone = true;
CONSOLE() << UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS;
} else {
CONSOLE() << UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE;
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE));
return;
}
} else {
CONSOLE() << UPDATE_STEP::CHECK_SANITY_SUCCESS;
}
CONSOLE() << UPDATE_STEP::CHECK_SANITY_SUCCESS;
if (continueUpdate) {
if ((continueUpdate = customerRepository.exists()) == false) {
m_initialClone = (m_repairClone == false);
GUI() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY);
for (int i = 0; i < 5; ++i) { // try to checkout git repository
setProgress(i); // and switch to branch
@ -436,7 +453,7 @@ void Worker::privateUpdate() {
if (!isRepositoryCorrupted()) {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY_SUCCESS));
continueUpdate = true;
initialClone = true;
m_clone = true;
break;
}
}
@ -444,155 +461,127 @@ void Worker::privateUpdate() {
}
if (continueUpdate == false) {
GUI() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY_FAILURE);
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY_FAILURE));
return;
}
Q_ASSERT_X(m_clone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "clone failed");
} else {
Q_ASSERT_X(!m_clone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_clone not false");
Q_ASSERT_X(!m_initialClone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_initialClone not false");
Q_ASSERT_X(!m_repairClone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_repairClone not false");
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY;
if (isRepositoryCorrupted()) {
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_FAILURE;
continueUpdate = false;
} else {
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_SUCCESS;
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_FAILURE));
return;
}
}
} // repository is existent and not corrupted.
// check now if the ISMAS-trigger (WAIT-button)
if (continueUpdate) { // is activated even in case of initial checkout
if ((continueUpdate = updateTriggerSet()) == false) {
// if (initialClone) {
//
//}
m_returnCode = sendIsmasTriggerFailure();
}
if (continueUpdate) { // configure customer environment -> checkout
// branch in case someone has change the zone_nr
//qDebug() << UPDATE_STEP::CHECK_ISMAS_TRIGGER;
if ((continueUpdate = customerEnvironment(30)) == false) {
m_returnCode = sendCustomerEnvironmentConfigurationFailed();
} // determine which files has to be updated:
} // either sent to the hardware or rsynced with
if (continueUpdate) { // the filesystem in case of tariff-files
//qDebug() << UPDATE_STEP::CHECKED_OUT_BRANCH;
if ((continueUpdate = filesToUpdate(50)) == false) {
m_returnCode = sendPullFailure();
}
} // send message to ISMAS about files which have
if (continueUpdate) { // been checked in into git repository
//qDebug() << UPDATE_STEP::COMPUTE_FILES_TO_UPDATE;
sendFoundFilesToUpdateSuccess();
if ((continueUpdate = updateFiles(60)) == false) {
m_returnCode = sendFileUpdateFailure();
}
}
if (continueUpdate) { // rsync (changed) files to file system
//qDebug() << UPDATE_STEP::DOWNLOAD_FILES_TO_UPDATE;
// TODO: rsync das komplette repository
if ((continueUpdate = syncCustomerRepositoryAndFS(70)) == false) {
m_returnCode = sendRsyncFailure();
}
}
if (continueUpdate) { // send message to ISMAS about installed versions
//qDebug() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY;
if ((continueUpdate = sendIsmasLastVersionNotification(80)) == false) {
m_returnCode = sendLastVersionFailure();
}
}
if (continueUpdate) { // future use: save logs of update process
sentIsmasLastVersionNotification = true;
if ((continueUpdate = saveLogFile(90)) == false) {
m_returnCode = sendSaveLogFilesFailure();
}
} // send message to ISMAS that update process
if (continueUpdate) { // succeeded
//qDebug() << UPDATE_STEP::UPDATE_SUCCESS;
sendUpdateSucceededAndActivated();
m_returnCode = UPDATE_SUCCESS_AND_ACTIVATED;
}
setProgress(100);
if (m_returnCode != 0) {
stopProgressLoop();
emit appendText(QString("UPDATE "), UPDATE_STEP_FAIL);
} else {
emit appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS);
sendFinalResult();
}
}
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_SUCCESS;
if (!sentIsmasLastVersionNotification) {
// try even if the backend is not connected
sendIsmasLastVersionNotification(100);
}
stopProgressLoop();
m_updateProcessRunning = false;
emit enableExit();
emit restartExitTimer();
}
std::optional<QString> Worker::getApismVersion() {
for (int repeat = 0; repeat < 10; ++repeat) {
qInfo() << "REPEAT" << repeat << "In getApismVersion() -> #M=APISM#C=REQ_SELF#J={}";
std::optional<QString> result
= IsmasClient::sendRequestReceiveResponse(
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_SELF#J={}");
if (result) {
QString msg = result.value();
qInfo() << "In getApismVersion() -> APISM response" << msg;
QJsonParseError parseError;
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
if (parseError.error != QJsonParseError::NoError) {
qCritical() << "(1) INVALID JSON MSG: PARSING FAILED (msg=" << msg << "):"
<< parseError.error << parseError.errorString();
m_updateStatus = UpdateStatus(UPDATE_STATUS::JSON_PARSE_FAILURE,
QString("(2) INVALID JSON %1 %2 %3")
.arg(msg)
.arg(parseError.error)
.arg(parseError.errorString()));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription));
return std::nullopt;
}
if (!document.isObject()) {
qCritical() << "FILE IS NOT A JSON OBJECT!";
m_updateStatus = UpdateStatus(UPDATE_STATUS::JSON_PARSE_FAILURE,
QString("NOT A JSON-OBJECT %1").arg(msg));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription));
return std::nullopt;
}
QJsonObject obj = document.object();
QStringList keys = obj.keys().filter("CMD_GET_APISMSTATUS_RESPONSE");
if (keys.size() != 1) {
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_CHECK_FAILURE,
"CMD_GET_APISMSTATUS_RESPONSE KEY NOT AVAILABLE");
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription));
emit showErrorMessage("apism response", m_updateStatus.m_statusDescription);
return std::nullopt;
} else {
QString const key = keys.at(0);
QJsonValue v = obj.value(key);
return v.toObject().value("Version").toString();
}
} else {
QThread::sleep(1);
////////////////////////////////////////////////////////////////////////////
//
// CHECK UPDATE TRIGGER
//
////////////////////////////////////////////////////////////////////////////
m_ismasTriggerActive = false;
if ((continueUpdate = updateTriggerSet()) == false) {
if (m_initialClone) {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER));
}
return;
} else {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER));
}
return std::nullopt;
if (m_ismasTriggerActive == false) {// make it explicit again: only if the
// ismas trigger is active ('WAIT'),
// then proceed
return;
}
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS));
////////////////////////////////////////////////////////////////////////////
//
// CHECK-OUT BRANCH
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = customerEnvironment()) == false) {
return;
}
CONSOLE() << UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS;
////////////////////////////////////////////////////////////////////////////
//
// COMPUTE CHANGED FILES OF CUSTOMER REPOSITORY
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = filesToUpdate()) == false) {
return;
}
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS));
////////////////////////////////////////////////////////////////////////////
//
// UPDATE THE PSA USING THE CHANGED FILES
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = updateFiles()) == false) {
return;
}
GUI() << (CONSOLE() << UPDATE_STEP::APPLY_REPOSITORY_CHANGES_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// (R)SYNC THE REPOSITORY WITH THE LOCAL FILEYSTEM
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = syncCustomerRepositoryAndFS()) == false) {
return;
}
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS));
////////////////////////////////////////////////////////////////////////////
//
// FUTURE: SAVE LOG FILES
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = saveLogFile()) == false) {
return;
}
// ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SAVE_LOGS_SUCCESS));
////////////////////////////////////////////////////////////////////////////
//
// FINAL MESSAGES (PART 1)
//
////////////////////////////////////////////////////////////////////////////
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_SUCCEEDED));
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_ACTIVATED));
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::FINISHED));
////////////////////////////////////////////////////////////////////////////
//
// FINAL MESSAGES (PART 2): SEND-LAST-VERSION
// (destructor of struct UpdateProcessRunning)
//
////////////////////////////////////////////////////////////////////////////
}
bool Worker::updateTriggerSet() {
// repository is existent and not corrupted. check now if the ISMAS-trigger
// (WAIT-button) is activated even in case of initial checkout
static const QString func = "UPDATE-TRIGGER-SET";
if (m_withoutIsmasDirectPort) { // useful for testing
return true;