UpdatePTUDevCtrl/worker.cpp

1534 lines
72 KiB
C++
Raw Normal View History

2023-06-16 16:47:13 +02:00
#include "worker.h"
#include "update.h"
#include <QCoreApplication>
#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
2023-06-16 16:47:13 +02:00
#include <QThread>
#include <QRegularExpression>
#include <QDateTime>
#include <QString>
#include <QMessageBox>
#include <QPushButton>
#include <QJsonParseError>
#include <Qt>
#include <thread>
2023-06-16 16:47:13 +02:00
#include "message_handler.h"
#include "plugins/interfaces.h"
#include "ismas/ismas_client.h"
#include "progress_event.h"
#include "mainwindow.h"
#include "utils.h"
QString const Worker::UPDATE_STEP_OK(" [ ok]");
QString const Worker::UPDATE_STEP_DONE(" [done]");
QString const Worker::UPDATE_STEP_FAIL(" [FAIL]");
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
Worker::Worker(int customerNr,
int machineNr,
int zoneNr,
QString branchName,
QString pluginName,
QString workingDirectory,
bool dryRun,
QObject *parent,
char const *serialInterface,
char const *baudrate)
: m_workerThread("workerThread")
, m_customerNr(customerNr)
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
, m_machineNr(machineNr)
, m_zoneNr(zoneNr)
, m_pluginName(pluginName)
, m_workingDirectory(workingDirectory)
, m_branchName(branchName)
, m_customerRepositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr))
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
, m_dryRun(dryRun)
, m_parent(parent)
, m_serialInterface(serialInterface)
, m_baudrate(baudrate)
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
, m_osVersion(getOsVersion())
, m_atbqtVersion(getATBQTVersion())
, m_atbUpdateToolVersion(getATBUpdateToolVersion())
, m_cpuSerial(getCPUSerial())
, m_pluginVersionATBDeciceController(getPluginVersion("/opt/app/ATBAPP/plugins/libATBDeviceControllerPlugin.so"))
, m_pluginVersionIngenicoISelf(getPluginVersion("/opt/app/ATBAPP/plugins/libIngenicoISelf_CCPlugin.so"))
, m_pluginVersionMobilisisCalc(getPluginVersion("/opt/app/ATBAPP/plugins/libMOBILISIS_CalculatePricePlugin.so"))
, m_pluginVersionMobilisisCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libMOBILISIS_CalculatePricePlugin_ConfigUi.so"))
, m_pluginVersionPrmCalc(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin.so"))
, m_pluginVersionPrmCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin_ConfigUi.so"))
, m_pluginVersionTcpZvt(getPluginVersion("/opt/app/ATBAPP/plugins/libTCP_ZVT_CCPlugin.so"))
, m_ismasUpdateRequests(ISMAS_UPDATE_REQUESTS)
, m_waitForNewUpdates(this)
, m_filesToUpdate()
2023-08-11 10:55:53 +02:00
, m_updateProcessRunning(true)
, m_returnCode(0)
, m_mainWindow(nullptr) /* contains plugin */
2023-08-09 16:14:59 +02:00
, m_progressValue(0)
//, m_withoutIsmasDirectPort(true) /* useful for testing */ {
, m_withoutIsmasDirectPort(false) /* useful for testing */ {
this->setObjectName("worker-object");
QDir::setCurrent(m_workingDirectory);
if (std::optional<QString> v = getApismVersion()) {
m_apismVersion = v.value();
}
Utils::printInfoMsg("STARTING PTU-UPDATE");
qInfo() << "CURRENT TIME ..............." << QDateTime::currentDateTime().toString(Qt::ISODate);
qInfo() << "OS VERSION ................." << m_osVersion;
qInfo() << "ATBQT VERSION .............." << m_atbqtVersion;
qInfo() << "CPU SERIAL ................." << m_cpuSerial;
qInfo() << "CUSTOMER_NR ................" << m_customerNr;
qInfo() << "CUSTOMER_NR_STR ............" << m_customerNrStr;
qInfo() << "CUSTOMER_REPOSITORY_PATH ..." << m_customerRepositoryPath;
qInfo() << "CUSTOMER_REPOSITORY ........" << m_customerRepository;
qInfo() << "MACHINE_NR ................." << m_machineNr;
qInfo() << "ZONE_NR ...................." << m_zoneNr;
qInfo() << "BRANCH_NAME ................" << m_branchName;
qInfo() << "PLUGIN_NAME ................" << m_pluginName;
qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory;
qInfo() << "APISM VERSION .............." << m_apismVersion;
qInfo() << "ATB UPDATE TOOL VERSION ...." << m_atbUpdateToolVersion;
this->moveToThread(&m_workerThread);
2023-06-16 16:47:13 +02:00
m_workerThread.start();
int cnt = 0;
while (!m_workerThread.isRunning()) {
if (++cnt > 5) {
Utils::printCriticalErrorMsg("starting worker thread FAILED");
2023-06-16 16:47:13 +02:00
return;
}
QThread::sleep(1);
}
}
Worker::~Worker() {
int cnt = 0;
m_workerThread.quit();
while (!m_workerThread.isFinished()) {
if (!m_workerThread.wait(1000)) {
if (++cnt > 5) {
Utils::printCriticalErrorMsg("stopping worker thread FAILED");
2023-06-16 16:47:13 +02:00
return;
}
}
}
}
void Worker::setProgress(int progress) {
if (m_mainWindow) {
m_progressValue = progress;
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, progress));
}
}
void Worker::startProgressLoop() {
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, MainWindow::START_PROGRESS_LOOP));
}
void Worker::stopProgressLoop() {
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, MainWindow::STOP_PROGRESS_LOOP));
}
static std::once_flag once;
void Worker::update() {
// user should not start the update process several times
std::call_once(once, &Worker::privateUpdate, this);
}
bool Worker::isRepositoryCorrupted() {
QDir customerRepository(m_customerRepository);
if (customerRepository.exists()) {
QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
QDir customerRepositoryOpt(QDir::cleanPath(m_customerRepository + QDir::separator() + "opt/"));
QDir customerRepositoryGit(QDir::cleanPath(m_customerRepository + QDir::separator() + ".git/"));
// etc-directory inside git-repository does not exist, which means the
// git-repository is corrupted -> remove it and start from scratch
if (!customerRepositoryEtc.exists()
|| !customerRepositoryGit.exists()
|| !customerRepositoryOpt.exists()) {
// should never happen
Utils::printCriticalErrorMsg("CORRUPTED CUSTOMER REPOSITORY");
return true;
}
}
return false;
}
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);
return false;
}
return true;
}
int Worker::sendCloneAndCheckoutFailure() {
stopProgressLoop();
setProgress(0);
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE,
QString("CLONE OR CHECKOUT FAILED: ") + m_customerRepository);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.errorGitClone(100, m_updateStatus.m_statusDescription));
return CLONE_AND_CHECKOUT_FAILURE;
}
int Worker::sendCloneAndCheckoutSuccess() {
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS,
QString("CLONED REPOSITORY %1 AND CHECKED OUT BRANCH %2")
.arg(m_customerRepository)
.arg(m_gc.branchName()));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.cloneAndCheckoutCustomerRepository(
m_updateStatus.m_statusDescription));
return CLONE_AND_CHECKOUT_SUCCESS;
}
int Worker::sendIsmasTriggerFailure() {
stopProgressLoop();
setProgress(0);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET_FAILURE,
QString("ISMAS update trigger wrong"));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"CHECK-UPDATE-TRIGGER",
m_updateStatus.m_statusDescription));
return ISMAS_TRIGGER_FAILURE;
}
void Worker::privateUpdate() {
if (!m_mainWindow) {
Utils::printCriticalErrorMsg("m_mainWindow NOT SET");
return;
}
m_updateProcessRunning = true;
bool sentIsmasLastVersionNotification = false;
2023-08-09 16:14:59 +02:00
emit disableExit();
m_returnCode = -1;
QDir customerRepository(m_customerRepository);
if (!customerRepository.exists()) {
emit appendText("\nInitializing customer environment ...");
startProgressLoop();
if (m_gc.gitCloneAndCheckoutBranch()) {
stopProgressLoop();
emit replaceLast("Initializing customer environment", UPDATE_STEP_DONE);
setProgress(5);
2023-08-16 12:41:42 +02:00
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS,
QString("CLONED AND CHECKED OUT: ") + m_customerRepository);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.cloneAndCheckoutCustomerRepository(
m_updateStatus.m_statusDescription));
setProgress(10);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSASucceeded(""));
setProgress(100);
m_ismasClient.setProgressInPercent(100);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") + m_ismasClient.updateOfPSAActivated());
m_returnCode = 0;
} else {
stopProgressLoop();
setProgress(0);
emit replaceLast("Initializing customer environment", UPDATE_STEP_FAIL);
2023-08-16 12:41:42 +02:00
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE,
QString("CLONE OR CHECKOUT FAILED: ") + m_customerRepository);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.errorGitClone(100, m_updateStatus.m_statusDescription));
m_returnCode = -3;
}
} else {
if (updateTriggerSet(5)) {
if (customerEnvironment(30)) {
m_ismasClient.setProgressInPercent(50);
if (filesToUpdate()) {
// send message to ISMAS about files which have been
// checked in into git repository
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECK_FILES_TO_UPDATE_SUCCESS,
QString("Files to update: ") + m_filesToUpdate.join(','));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAContinues("CHECK-FILES-TO-UPDATE",
m_updateStatus.m_statusDescription));
if (updateFiles(60)) {
m_ismasClient.setProgressInPercent(70);
if (syncCustomerRepositoryAndFS()) {
m_ismasClient.setProgressInPercent(80);
if (sendIsmasLastVersionNotification()) {
m_ismasClient.setProgressInPercent(90);
sentIsmasLastVersionNotification = true;
if (saveLogFile()) {
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSASucceeded(""));
// 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());
m_returnCode = 0;
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::SAVE_LOG_FILES_FAILED,
QString("Saving log files failed"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"SAVE-LOG-FILES",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -11;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED,
QString("Sending ISMAS last version failed"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"ISMAS-SEND-LAST-VERSION",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -10;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_UPDATES_FAILURE,
QString("Syncing files to update failed"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"RSYNC-UPDATE-FILES",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -9;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::PSA_UPDATE_FILES_FAILED,
QString("Updating files failed"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"UPDATE-FILES",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -8;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE,
QString("No files to update"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"FETCH-FILES-TO-UPDATE",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -7;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE,
QString("Configuring customer environment failed"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"GIT-CHECKOUT-BRANCH",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -6;
}
} else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET_FAILURE,
QString("ISMAS update trigger wrong"));
2023-08-11 10:55:53 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
"CHECK-UPDATE-TRIGGER",
2023-08-11 10:55:53 +02:00
m_updateStatus.m_statusDescription));
m_returnCode = -5;
}
}
m_ismasClient.setProgressInPercent(100);
setProgress(100);
if (m_returnCode != 0) {
stopProgressLoop();
emit appendText(QString("UPDATE "), UPDATE_STEP_FAIL);
// m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_FAILURE,
// QString("Update process failed"));
// if (std::optional<QString> s = m_ismasClient.finalResult(IsmasClient::RESULT_CODE::INSTALL_ERROR,
// m_updateStatus.m_statusDescription)) {
// IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") + s.value());
// }
} else {
emit appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS);
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_SUCCESS,
QString("Update process succeeded. Reset WAIT."));
if (std::optional<QString> s = m_ismasClient.finalResult(IsmasClient::RESULT_CODE::SUCCESS,
m_updateStatus.m_statusDescription)) {
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") + s.value());
}
}
if (!sentIsmasLastVersionNotification) {
// try even if the backend is not connected
sendIsmasLastVersionNotification();
}
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;
2023-08-11 10:55:53 +02:00
} else {
QString const key = keys.at(0);
QJsonValue v = obj.value(key);
return v.toObject().value("Version").toString();
}
} else {
QThread::sleep(1);
}
2023-08-11 10:55:53 +02:00
}
return std::nullopt;
}
#define CHECK_UPDATE_TRIGGER_SET "Check update trigger ..."
bool Worker::updateTriggerSet(int progress) {
if (m_withoutIsmasDirectPort) { // useful for testing
return true;
}
emit appendText("\n" CHECK_UPDATE_TRIGGER_SET);
QString triggerValue("");
int const startMs = QTime::currentTime().msecsSinceStartOfDay();
for (int repeat = 1; repeat <= 100; ++repeat) {
2023-08-11 10:56:36 +02:00
qInfo() << "UPDATE TRIGGER SET -> REPEAT" << repeat;
if (repeat > 1) {
int const durationMs = QTime::currentTime().msecsSinceStartOfDay() - startMs;
QString const &msg = QString("elapsed: %1.%2s").arg(durationMs / 1000).arg(durationMs % 1000);
qInfo() << "REPEAT" << msg;
emit showErrorMessage("check update trigger", msg);
} else {
emit showErrorMessage("check update trigger", "");
}
if ((repeat % 10) == 0) {
qInfo() << "CHECK UPDATE TRIGGER. RESTART APISM ...";
Command c("systemctl restart apism");
if (c.execute("/tmp")) {
QThread::sleep(20); // give APISM some time to reconnect
qInfo() << "CHECK UPDATE TRIGGER. RESTARTING APISM DONE";
}
}
startProgressLoop();
if (std::optional<QString> result
= IsmasClient::sendRequestReceiveResponse(
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_ISMASPARAMETER#J={}")) {
stopProgressLoop();
setProgress(m_mainWindow->progressValue()/10 + 11);
QString msg = result.value();
qInfo() << "REPEAT" << repeat << "APISM RESPONSE (" << msg << ")";
QJsonParseError parseError;
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
if (parseError.error != QJsonParseError::NoError) {
qCritical() << "(2) INVALID JSON MSG: PARSING FAILED (msg=" << msg << "):"
<< parseError.error << parseError.errorString();
2023-08-11 10:58:29 +02:00
setProgress(100);
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));
emit showErrorMessage("check update trigger",
QString("invalid json ") + msg.mid(0, 20));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
return false;
}
if (!document.isObject()) {
qCritical() << "FILE IS NOT A JSON OBJECT!";
2023-08-11 10:58:29 +02:00
setProgress(100);
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));
emit showErrorMessage("check update trigger", QString("not a json object") + msg);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
return false;
}
setProgress(m_mainWindow->progressValue()/10 + 11);
QJsonObject obj = document.object();
// always look for an 'error' first
if (obj.contains("error")) {
setProgress(m_mainWindow->progressValue()/10 + 11);
QString value = obj.value("error").toString();
emit showErrorMessage("check update trigger", QString("REPEAT %1 error=<").arg(repeat) + value + ">");
qInfo() << "REPEAT" << repeat << "In updateTriggerSet() error=<"
<< value << ">";
QThread::sleep(6);
continue;
}
// sanity check: cust_nr and machine_nr of PSA correct ?
// note: this check has to be done here, as the cust_nr and the machine_nr
// of the PSA are sent by ISMAS.
if (obj.contains("Dev_ID")) {
QJsonValue v = obj.value("Dev_ID");
if (v.isObject()) {
QJsonObject obj = v.toObject();
if (obj.contains("Custom_ID") && obj.contains("Device_ID")) {
QJsonValue const c = obj.value("Custom_ID");
QJsonValue const m = obj.value("Device_ID");
int customerNr = c.toInt(-1);
int machineNr = m.toInt(-1);
if (customerNr != m_customerNr) {
2023-08-11 10:59:26 +02:00
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)")
.arg(customerNr).arg(m_customerNr));
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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
return false;
}
if (machineNr != m_machineNr) {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)")
.arg(machineNr).arg(m_machineNr));
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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
return false;
}
2023-08-11 10:58:29 +02:00
qInfo() << "MACHINE-AND-CUSTOMER-CHECK" << m_updateStatus.m_statusDescription;
} else {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"Dev_ID DOES NOT CONTAIN Custom_ID AND/OR Device_ID");
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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
return false;
}
2023-08-11 10:58:29 +02:00
} else {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"Dev_ID KEY NOT A JSON-OBJECT");
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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
return false;
}
2023-08-11 10:58:29 +02:00
} else {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"Dev_ID 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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
return false;
}
setProgress(m_mainWindow->progressValue()/10 + 11);
if (obj.contains("Fileupload")) {
QJsonValue v = obj.value("Fileupload");
if (v.isObject()) {
obj = v.toObject();
if (obj.contains("TRG")) {
2023-08-11 11:00:52 +02:00
triggerValue = obj.value("TRG").toString();
qInfo() << "REPEAT" << repeat
<< "In updateTriggerSet() TRG value=<"
<< triggerValue << ">";
2023-08-11 10:58:29 +02:00
if (triggerValue == "WAIT") {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_SANITY_CHECK_OK,
QString("MACHINE-NR (%1) AND CUST-NR (%2) OK")
.arg(m_machineNr).arg(m_customerNr));
m_ismasClient.setProgressInPercent(progress);
2023-08-11 10:58:29 +02:00
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateOfPSAContinues("MACHINE-AND-CUSTOMER-CHECK",
m_updateStatus.m_statusDescription));
progress += 5;
m_ismasClient.setProgressInPercent(progress);
2023-08-16 12:41:42 +02:00
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET,
2023-08-11 10:58:29 +02:00
QString("UPDATE TRIGGER SET. CONTINUE. "));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateTriggerSet(m_updateStatus.m_statusDescription, ""));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_DONE);
2023-08-11 10:58:29 +02:00
return true;
} else
if (QRegExp("\\s*").exactMatch(triggerValue)) { // check for whitespace
stopProgressLoop();
setProgress(m_mainWindow->progressValue()/10 + 11);
emit showErrorMessage("check update trigger", "empty update-trigger");
QThread::sleep(6);
continue;
2023-08-11 10:58:29 +02:00
} else {
// if the download-button once has the wrong value, it will never recover
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
QString("TRIGGER-VALUE=<") + triggerValue + "> NOT 'WAIT'");
2023-08-11 10:58:29 +02:00
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("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
return false;
}
} else {
2023-08-11 10:58:29 +02:00
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"TRG 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 replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false;
}
} else {
2023-08-11 10:58:29 +02:00
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"Fileupload NOT A JSON-OBJECT");
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 replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false;
}
2023-08-11 10:58:29 +02:00
} else {
setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
"Fileupload 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 replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
2023-08-11 10:58:29 +02:00
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false;
}
} else {
stopProgressLoop();
setProgress(m_mainWindow->progressValue()/10 + 11);
emit showErrorMessage("check update trigger", "no ISMAS response");
QThread::sleep(6);
}
}
setProgress(100);
2023-08-16 12:41:42 +02:00
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_NOT_SET_OR_WRONG,
QString("ISMAS_UPDATE-TRIGGER-NOT-SET-OR-WRONG: VALUE=(") +
triggerValue + ")");
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.errorUpdateTrigger(m_updateStatus.m_statusDescription, ""));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL);
return false;
}
bool Worker::customerEnvironment(int progress) {
emit appendText("\nPrepare customer environment ...");
if (QDir(m_customerRepository).exists()) {
startProgressLoop();
setProgress(m_mainWindow->progressValue()/10 + 11);
if (m_gc.gitCheckoutBranch()) {
stopProgressLoop();
m_ismasClient.setProgressInPercent(progress);
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH,
QString("CHECKED-OUT BRANCH ") + m_gc.branchName());
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.checkoutBranch(m_updateStatus.m_statusDescription, ""));
setProgress(100);
emit replaceLast("Prepare customer environment ...", UPDATE_STEP_DONE);
2023-08-09 16:16:36 +02:00
qInfo() << "PREPARE CUSTOMER ENVIRONMENT DONE";
return true;
} else {
stopProgressLoop();
m_ismasClient.setProgressInPercent(0);
emit showErrorMessage("cust-env",
QString("Checkout ") + m_customerRepository + " failed");
Utils::printCriticalErrorMsg(QString("CHECKOUT OF " + m_customerRepository + "FAILED"));
}
} else {
emit showErrorMessage("cust-env", m_customerRepository + " does not exist");
Utils::printCriticalErrorMsg(m_customerRepository + " DOES NOT EXIST");
}
setProgress(100);
emit replaceLast("Prepare customer environment ...", UPDATE_STEP_FAIL);
return false;
}
bool Worker::filesToUpdate() {
emit appendText("\nFetch changes files ...");
startProgressLoop();
// always execute contents of opkg_commands-file
m_filesToUpdate << "etc/psa_update/opkg_commands";
if (std::optional<QString> changes = m_gc.gitPull()) {
stopProgressLoop();
int progress = (m_mainWindow->progressValue()/10) + 10;
setProgress(progress);
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES,
QString("FETCHING OF ") + m_customerRepositoryPath +
QString(" INTO ") + m_customerRepository);
setProgress(progress + 10);
if (std::optional<QStringList> changedFileNames = m_gc.gitDiff(changes.value())) {
setProgress(progress + 20);
if (m_gc.gitPull()) {
emit replaceLast(QString("Fetch changes files ..."), UPDATE_STEP_DONE);
m_filesToUpdate << changedFileNames.value();
} else {
emit showErrorMessage("files to update", "pulling files failed");
Utils::printCriticalErrorMsg("PULLING FILES FAILED");
2023-08-09 16:16:36 +02:00
emit replaceLast(QString("Fetch changes files ..."), UPDATE_STEP_FAIL);
2023-08-09 16:16:36 +02:00
stopProgressLoop();
setProgress(100);
return false;
}
}
2023-08-09 16:16:36 +02:00
Utils::printInfoMsg("FILES-TO-UPDATE " + m_filesToUpdate.join(','));
m_filesToUpdate.removeDuplicates();
int const size = m_filesToUpdate.size();
if (size > 1) {
emit appendText(QString("Found %1 files to update :").arg(size), UPDATE_STEP_DONE);
for (int i = 0; i < size; ++i) {
emit appendText(QString("\n ") + m_filesToUpdate.at(i));
}
} else {
emit appendText("Found 1 file to update :", UPDATE_STEP_DONE);
emit appendText(QString("\n ") + m_filesToUpdate.at(0));
}
2023-08-09 16:16:36 +02:00
setProgress(progress + 30);
}
return true;
}
bool Worker::updateFiles(quint8 percent) {
QStringList filesToDownload;
m_displayIndex = 0;
startProgressLoop();
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
QString const fName = m_filesToUpdate.at(i);
Utils::printInfoMsg(QString("FNAME ") + fName);
2023-08-09 16:16:36 +02:00
if (fName.contains("opkg_commands", Qt::CaseInsensitive)) {
2023-08-09 16:16:36 +02:00
emit appendText("\n( ) Update opkg pakets ...");
// execute opkg commands
if (QDir::setCurrent(m_customerRepository)) {
QFile f(fName);
if (f.exists()) {
if (f.open(QIODevice::ReadOnly)) {
QTextStream in(&f);
QStringList opkgCommands;
bool executeOpkgCommandFailed = false;
while (!in.atEnd()) {
QString line = in.readLine();
static const QRegularExpression comment("^\\s*#.*$");
if (line.indexOf(comment, 0) == -1) {
// found opkg command
QString opkgCommand = line.trimmed();
if (!executeOpkgCommand(opkgCommand)) {
executeOpkgCommandFailed = true;
} else {
QString cmd = "\n " + opkgCommand;
emit appendText(cmd);
opkgCommands << cmd;
m_ismasClient.setProgressInPercent(++percent);
m_updateStatus = UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND,
QString("EXEC OPKG-COMMAND ") + opkgCommand);
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.execOpkgCommand(m_updateStatus.m_statusDescription, ""));
}
}
}
f.close();
if (!executeOpkgCommandFailed) {
if (opkgCommands.size() > 0) {
m_displayIndex = 1;
QString prepend = QString("(") + QString("%1").arg(m_displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update opkg pakets ... ");
opkgCommands.prepend(prepend);
emit replaceLast(opkgCommands, UPDATE_STEP_DONE);
}
} else {
m_displayIndex = 1;
emit replaceLast(QString("(") + QString("%1").arg(m_displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update opkg pakets ... "), UPDATE_STEP_FAIL);
stopProgressLoop();
setProgress(100);
return false;
}
}
}
}
} else
if (fName.contains("DC2C_print", Qt::CaseInsensitive) ||
fName.contains("DC2C_device", Qt::CaseInsensitive) ||
fName.contains("DC2C_conf", Qt::CaseInsensitive) ||
fName.contains("DC2C_cash", Qt::CaseInsensitive)) {
filesToDownload << fName; // download printer-config-files
2023-08-09 16:16:36 +02:00
} else {
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
2023-08-09 16:16:36 +02:00
if (fName.contains(version)) {
filesToDownload << fName; // download device controller
}
}
}
2023-08-09 16:16:36 +02:00
stopProgressLoop();
setProgress(100);
if (filesToDownload.size() > 0) {
Utils::printInfoMsg(QString("FILES_TO_DOWNLOAD_TO_PSA_HW ") + filesToDownload.join(','));
Update *update = m_mainWindow->getUpdate();
if (update) {
return update->doUpdate(m_displayIndex, filesToDownload);
2023-10-06 10:44:55 +02:00
} else {
Utils::printCriticalErrorMsg("UPDATE NOT SET");
}
2023-08-09 16:16:36 +02:00
} else {
Utils::printCriticalErrorMsg("NO FILES_TO_DOWNLOAD_TO_PSA_HW");
}
return true;
}
bool Worker::syncCustomerRepositoryAndFS() {
// this step is currently needed only for updating tariff-files
setProgress(0);
emit appendText("\nSync customer environment with filesystem ...");
if (QDir(m_customerRepository).exists()) {
if (QDir::setCurrent(m_customerRepository)) {
Command md("bash");
if (!md.execute(m_customerRepository,
QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/dc /etc/psa_tariff")) {
qCritical() << "COULD NOT EXECUTE '" << md.command() << "' exitCode=(" << md.exitCode() << ")";
}
int progress = 10;
setProgress(progress);
QString const params("-vvv "
"--recursive "
"--progress "
"--checksum "
"--exclude=.* "
"--include=*.bin "
"--include=*.json "
"--include=*.ini");
QStringList cmds;
if (QDir(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/")).exists()) {
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
Utils::printInfoMsg(QString("CONFIGURED SYNCING TO /ETC"));
}
if (QDir(QDir::cleanPath(m_customerRepository + QDir::separator() + "opt/")).exists()) {
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
Utils::printInfoMsg(QString("CONFIGURED SYNCING TO /OPT"));
}
QString cmd;
bool error = false;
foreach (cmd, cmds) {
progress += 5;
setProgress(progress);
if (!error) {
Command c("bash");
qInfo() << "EXECUTING CMD..." << cmd;
Utils::printInfoMsg(QString("EXECUTING CMD %1...").arg(cmd));
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
2023-08-04 13:49:32 +02:00
QStringList result = c.getCommandResult().split('\n');
QString const &p1 = "send_files mapped ";
QString const &p2 = "of size";
2023-08-04 13:49:32 +02:00
for (int i = 0; i < result.size(); ++i) {
QString line = result.at(i);
qInfo() << line;
// "send_files mapped etc/psa_tariff/tariff01.json of size 19339"
int sendFilesAtPos = line.indexOf(p1);
int ofSizeAtPos = line.indexOf(p2);
if (sendFilesAtPos != -1 && ofSizeAtPos != -1) {
sendFilesAtPos += p1.length();
QString const &s = line.mid(sendFilesAtPos, ofSizeAtPos - sendFilesAtPos).trimmed();
m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_FILE_SUCCESS,
QString("RSYNC FILE ") + s.split("/").last() +
" LAST-COMMIT: " + m_gc.gitLastCommit(s));
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.rsyncFile(m_updateStatus.m_statusDescription, ""));
}
2023-08-04 13:49:32 +02:00
}
} else {
Utils::printCriticalErrorMsg(QString("CMD ") + cmd + " FAILED: "
+ c.getCommandResult() + QString(" EXIT_CODE=(%1)").arg(c.exitCode()));
error = true;
}
}
}
progress += 5;
setProgress(progress);
if (!error) {
// now check tariff-files in etc and /etc/psa_tariff
QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff"));
QDir dir2("/etc/psa_tariff");
if (Utils::sameFilesInDirs(dir1, dir2)) {
setProgress(100);
emit replaceLast(QString("Sync customer environment with filesystem ..."), UPDATE_STEP_DONE);
return true;
} else {
// TODO: send message to ISMAS
}
}
}
}
setProgress(100);
emit replaceLast(QString("Sync customer environment with filesystem ..."), UPDATE_STEP_FAIL);
return false;
}
bool Worker::sendIsmasLastVersionNotification() {
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_SENDVERSION#J=") +
m_ismasClient.updateOfPSASendVersion(getPSAInstalled()));
emit appendText(QString("Send last version info "), UPDATE_STEP_DONE);
return true;
}
bool Worker::saveLogFile() {
return true;
}
QString Worker::getOsVersion() const {
QString const cmd = QString("echo -n $(cat /etc/os-release | head -n 1 | cut -d'\"' -f2 | tr -d '\"')");
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QString Worker::getATBUpdateToolYoctoVersion() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A1 atbupdatetool | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.3.9+git0+226553a8ab-r0
}
}
return "N/A";
}
QString Worker::getATBUpdateToolYoctoInstallationStatus() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A3 atbupdatetool | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2,3,4)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.3.9+git0+226553a8ab-r0
}
}
return "N/A";
}
QString Worker::getATBQTVersion() const {
QString const cmd = QString("echo -n $(/opt/app/ATBAPP/ATBQT -v | head -n 2 | cut -d':' -f2)");
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QString Worker::getATBUpdateToolVersion() const {
return APP_EXTENDED_VERSION;
}
QString Worker::getCPUSerial() const {
QString const cmd = QString("echo -n $(cat /proc/cpuinfo | grep -i Serial | cut -d':' -f2)");
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QString Worker::getRaucVersion() const {
QString const cmd = QString("echo -n $(rauc --version)");
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QString Worker::getOpkgVersion() const {
QString const cmd = QString("echo -n $(opkg --version)");
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QString Worker::getPluginVersion(QString const &pluginFileName) const {
QString const cmd = QString("echo -n $(strings %1 | grep \\\"Version\\\" | cut -d':' -f2 | tr -d '\"' | tr -d ',')").arg(pluginFileName);
Command c("bash");
if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) {
return c.getCommandResult();
}
return "N/A";
}
QStringList Worker::getDCVersion() const {
QStringList lst = (QStringList() << "N/A" << "N/A");
hwinf *hwi = m_mainWindow->getPlugin();
if (hwi) {
hwi->dc_autoRequest(true); // turn auto-request setting on
QByteArray const cmp(8, char(0));
QByteArray hw(""), sw("");
for (int i=0; i<5; ++i) {
hw = hwi->dc_getHWversion().toUtf8();
sw = hwi->dc_getSWversion().toUtf8();
if (!hw.startsWith(cmp)) {
lst.clear();
qInfo() << hw << sw;
lst << hw << sw;
break;
}
QThread::sleep(1);
}
}
return lst;
}
qint64 Worker::getFileSize(QString const &fileName) const {
// fileName has to be an absolute path
QFileInfo fInfo(fileName);
return fInfo.exists() ? fInfo.size() : -1;
}
bool Worker::executeOpkgCommand(QString opkgCommand) {
Command c(opkgCommand);
if (c.execute(m_workingDirectory)) {
QString const r = c.getCommandResult();
Utils::printInfoMsg(QString("EXECUTE OPKG COMMAND %1 OK: %2")
.arg(opkgCommand)
.arg(c.getCommandResult()));
return true;
} else {
Utils::printCriticalErrorMsg(QString("EXECUTE OPKG COMMAND %1 FAILED")
.arg(opkgCommand));
}
return false;
2023-06-16 16:47:13 +02:00
}
PSAInstalled Worker::getPSAInstalled() {
QStringList const dcVersion = getDCVersion();
QString const deviceControllerVersionHW = dcVersion.first();
QString const deviceControllerVersionSW = dcVersion.last();
qInfo() << "CURRENT DC-HW-VERSION: " << deviceControllerVersionHW;
qInfo() << "CURRENT DC-SW-VERSION: " << deviceControllerVersionSW;
QString const deviceControllerGitBlob = "N/A";
QString const deviceControllerGitLastCommit = "N/A";
PSAInstalled psaInstalled;
QString printSysDir("/etc/psa_config");
QString tariffSysDir("/etc/psa_tariff");
QString tariffRepoDir("etc/psa_tariff");
2023-08-22 13:49:09 +02:00
QString opkgRepoDir("etc/psa_update");
QString const &absPathNameRepositoryOpkg = QDir::cleanPath(opkgRepoDir + QDir::separator() + "opkg_commands");
QString absPathName;
QString absPathNameRepository;
psaInstalled.versionInfo.lastCommit = "";
psaInstalled.versionInfo.reason = "";
psaInstalled.versionInfo.created = "";
QStringList versionInfo = m_gc.gitShowReason(m_branchName);
if (versionInfo.size() == 3) {
psaInstalled.versionInfo.lastCommit = versionInfo.at(0);
psaInstalled.versionInfo.reason = versionInfo.at(1);
psaInstalled.versionInfo.created = versionInfo.at(2);
}
if (m_zoneNr != 0) {
QString const &n = QString("%1").arg(m_zoneNr).rightJustified(2, '0');
psaInstalled.tariff.name = QString("tariff%1.json").arg(n);
absPathName = QDir::cleanPath(tariffSysDir + QDir::separator() + psaInstalled.tariff.name);
psaInstalled.tariff.blob = m_gc.gitBlob(absPathName);
absPathNameRepository = QDir::cleanPath(tariffRepoDir + QDir::separator() + psaInstalled.tariff.name);
psaInstalled.tariff.lastCommit = m_gc.gitLastCommit(absPathNameRepository);
psaInstalled.tariff.size = getFileSize(absPathName);
psaInstalled.tariff.zone = m_zoneNr;
psaInstalled.tariff.loadTime = Utils::getTariffLoadTime(absPathName);
}
psaInstalled.tariff.project = "Szeged";
psaInstalled.tariff.info = "N/A";
psaInstalled.tariff.version = "N/A";
psaInstalled.hw.linuxVersion = getOsVersion();
psaInstalled.hw.cpuSerial = m_cpuSerial;
psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameRepositoryOpkg);
psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg);
psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg);
2023-08-22 13:49:09 +02:00
psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg);
psaInstalled.dc.versionHW = deviceControllerVersionHW;
psaInstalled.dc.versionSW = deviceControllerVersionSW;
psaInstalled.dc.gitBlob = "N/A";
psaInstalled.dc.gitLastCommit = "N/A";
psaInstalled.dc.size = -1;
if (std::optional<QString> v = getApismVersion()) {
psaInstalled.sw.apismVersion = v.value();
}
psaInstalled.sw.atbQTVersion = getATBQTVersion();
psaInstalled.sw.atbUpdateToolVersion = m_atbUpdateToolVersion;
psaInstalled.pluginVersion.deviceController = m_pluginVersionATBDeciceController;
psaInstalled.pluginVersion.ingenicoISelfCC = m_pluginVersionIngenicoISelf;
psaInstalled.pluginVersion.mobilisisCalculatePrice = m_pluginVersionMobilisisCalc;
psaInstalled.pluginVersion.mobilisisCalculatePriceConfigUi = m_pluginVersionMobilisisCalcConfig;
psaInstalled.pluginVersion.prmCalculatePrice = m_pluginVersionPrmCalc;
psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig;
psaInstalled.pluginVersion.tcpZVT = m_pluginVersionTcpZvt;
psaInstalled.cash.name = "DC2C_cash.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name);
psaInstalled.cash.blob = m_gc.gitBlob(absPathName);
psaInstalled.cash.size = getFileSize(absPathName);
psaInstalled.conf.name = "DC2C_conf.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name);
psaInstalled.conf.blob = m_gc.gitBlob(absPathName);
psaInstalled.conf.size = getFileSize(absPathName);
psaInstalled.device.name = "DC2C_device.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name);
psaInstalled.device.blob = m_gc.gitBlob(absPathName);
psaInstalled.device.size = getFileSize(absPathName);
for (int i=0; i < 32; ++i) {
QString const &n = QString("%1").arg(i+1).rightJustified(2, '0');
psaInstalled.print[i].name = QString("DC2C_print%1.json").arg(n);
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name);
psaInstalled.print[i].blob = m_gc.gitBlob(absPathName);
psaInstalled.print[i].size = getFileSize(absPathName);
}
return psaInstalled;
}
hwinf *Worker::getPlugin() {
return m_mainWindow ? m_mainWindow->getPlugin() : nullptr;
}
hwinf const *Worker::getPlugin() const {
return m_mainWindow ? m_mainWindow->getPlugin() : nullptr;
}
/************************************************************************************************
* operators
*/
QDebug operator<< (QDebug debug, UpdateStatus status) {
switch(status.m_updateStatus) {
2023-08-16 12:41:42 +02:00
case UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED:
debug << QString("UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::SAVE_LOG_FILES_FAILED:
debug << QString("UPDATE_STATUS::SAVE_LOG_FILES_FAILED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECK_FILES_TO_UPDATE_SUCCESS:
debug << QString("UPDATE_STATUS::GIT_CHECK_FILES_TO_UPDATE_SUCCESS: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::PSA_UPDATE_FILES_FAILED:
debug << QString("UPDATE_STATUS::PSA_UPDATE_FILES_FAILED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_UPDATES_SUCCESS:
debug << QString("UPDATE_STATUS::RSYNC_UPDATES_SUCCESS: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_UPDATES_FAILURE:
debug << QString("UPDATE_STATUS::RSYNC_UPDATES_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::EXEC_OPKG_COMMAND:
debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMAND: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS:
debug << QString("UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE:
debug << QString("UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::NOT_DEFINED:
debug << QString("UPDATE_STATUS::NOT_DEFINED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::UPDATE_PROCESS_FAILURE:
debug << QString("UPDATE_STATUS::UPDATE_PROCESS_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET_FAILURE:
debug << QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE:
debug << QString("UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECKOUT_BRANCH:
debug << QString("UPDATE_STATUS::GIT_CHECKOUT_BRANCH: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_NOT_SET_OR_WRONG:
debug << QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_NOT_SET_OR_WRONG: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET:
debug << QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_SANITY_CHECK_OK:
debug << QString("UPDATE_STATUS::ISMAS_SANITY_CHECK_OK: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::JSON_PARSE_FAILURE:
debug << QString("UPDATE_STATUS::JSON_PARSE_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_CHECK:
debug << QString("UPDATE_STATUS::BACKEND_CHECK: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_CHECK_FAILURE:
debug << QString("UPDATE_STATUS::BACKEND_CHECK_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_NOT_CONNECTED:
debug << QString("UPDATE_STATUS::BACKEND_NOT_CONNECTED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::UPDATE_PROCESS_SUCCESS:
debug << QString("UPDATE_STATUS::UPDATE_PROCESS_SUCCESS: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING:
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE:
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_FETCH_UPDATES:
debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED:
debug << QString("UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_FILE_SUCCESS:
debug << QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ")
<< status.m_statusDescription;
break;
case UPDATE_STATUS::EXEC_OPKG_COMMANDS:
debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ")
<< status.m_statusDescription;
break;
2023-08-16 12:41:42 +02:00
// default:;
}
return debug;
}
QString& operator<< (QString& str, UpdateStatus status) {
switch(status.m_updateStatus) {
2023-08-16 12:41:42 +02:00
case UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED:
str = QString("UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::SAVE_LOG_FILES_FAILED:
str = QString("UPDATE_STATUS::SAVE_LOG_FILES_FAILED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECK_FILES_TO_UPDATE_SUCCESS:
str = QString("UPDATE_STATUS::GIT_CHECK_FILES_TO_UPDATE_SUCCESS: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::PSA_UPDATE_FILES_FAILED:
str = QString("UPDATE_STATUS::PSA_UPDATE_FILES_FAILED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_UPDATES_SUCCESS:
str = QString("UPDATE_STATUS::RSYNC_UPDATES_SUCCESS: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_UPDATES_FAILURE:
str = QString("UPDATE_STATUS::RSYNC_UPDATES_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::EXEC_OPKG_COMMAND:
str = QString("UPDATE_STATUS::EXEC_OPKG_COMMAND: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS:
str = QString("UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE:
str = QString("UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::NOT_DEFINED:
str = QString("UPDATE_STATUS::NOT_DEFINED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::UPDATE_PROCESS_FAILURE:
str = QString("UPDATE_STATUS::UPDATE_PROCESS_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET_FAILURE:
str = QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE:
str = QString("UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_CHECKOUT_BRANCH:
str = QString("UPDATE_STATUS::GIT_CHECKOUT_BRANCH: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_NOT_SET_OR_WRONG:
str = QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_NOT_SET_OR_WRONG: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE:
str = QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET:
str = QString("UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_SANITY_CHECK_OK:
str = QString("UPDATE_STATUS::ISMAS_SANITY_CHECK_OK: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::JSON_PARSE_FAILURE:
str = QString("UPDATE_STATUS::JSON_PARSE_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_CHECK:
str = QString("UPDATE_STATUS::BACKEND_CHECK: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_CHECK_FAILURE:
str = QString("UPDATE_STATUS::BACKEND_CHECK_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::BACKEND_NOT_CONNECTED:
str = QString("UPDATE_STATUS::BACKEND_NOT_CONNECTED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::UPDATE_PROCESS_SUCCESS:
str = QString("UPDATE_STATUS::UPDATE_PROCESS_SUCCESS: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING:
str = QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_FETCH_UPDATES:
str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED:
str = QString("UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::EXEC_OPKG_COMMANDS:
str = QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ");
str += status.m_statusDescription;
break;
case UPDATE_STATUS::RSYNC_FILE_SUCCESS:
str = QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ");
str += status.m_statusDescription;
break;
2023-08-16 12:41:42 +02:00
//default:;
}
return str;
}