Compare commits

..

11 Commits

Author SHA1 Message Date
29e6a25e72 Add comment for version 1.3.13 2023-10-19 13:45:52 +02:00
5abc057bda Minor: add possible debug messages. 2023-10-19 13:44:51 +02:00
8aeb7ecfea Don't check opkg_commands-file in the system-filesystem to remove
confusing error-messages.
2023-10-19 13:43:53 +02:00
4bb8e241b6 Update process: check sanity of customer repository: are etc/ and
opt/directories contained? If not, remove the repository and clone it
again. This is done without checking the ISMAS-WAIT-button.
2023-10-19 13:41:44 +02:00
4469a23f9c Implemented helpers:
bool isRepositoryCorrupted();
    bool repairCorruptedRepository();

    int sendCloneAndCheckoutSuccess();
    int sendCloneAndCheckoutFailure();
    int sendIsmasTriggerFailure();
2023-10-19 13:39:48 +02:00
d1f795e2db Added helpers:
bool isRepositoryCorrupted();
    bool repairCorruptedRepository();

    int sendCloneAndCheckoutSuccess();
    int sendCloneAndCheckoutFailure();
    int sendIsmasTriggerFailure();

and static variables

    static constexpr const int CLONE_AND_CHECKOUT_SUCCESS = 0;
    static constexpr const int CLONE_AND_CHECKOUT_FAILURE = -3;
    static constexpr const int ISMAS_TRIGGER_FAILURE = -5;
2023-10-19 13:38:16 +02:00
6865056f4b Replace regex in gitCloneCustomerRepository() with straight-forward
steing-handling: regex sometimes returned error.
2023-10-19 13:35:07 +02:00
37bd5c90d3 Add printUpdateStatus() helper for QString 2023-10-19 13:34:07 +02:00
fcba120dfa Minor: commented out unnecessary debug/info output 2023-10-18 16:21:44 +02:00
1d4f50fb9f Add printing-utils that also take string-lists 2023-10-18 16:20:49 +02:00
a78040a037 Minor: add error-debug-message in ase customer-nr is wrong 2023-10-18 16:19:37 +02:00
7 changed files with 306 additions and 117 deletions

View File

@@ -39,6 +39,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
# Use 'git pull' instead of 'git fetch'. # Use 'git pull' instead of 'git fetch'.
# Use 'git clone --filter=blob:none' instead of 'git clone' to speed # Use 'git clone --filter=blob:none' instead of 'git clone' to speed
# up cloning of customer repository. # up cloning of customer repository.
# 1.3.13: Fix: if the customer repository is corrupted, remove it and re-clone
# the repository (without checking the ISMAS-trigger (WAIT-)button.
win32 { win32 {
BUILD_DATE=$$system("date /t") BUILD_DATE=$$system("date /t")

View File

@@ -68,7 +68,11 @@ bool GitClient::gitCloneCustomerRepository() {
Note: git v2.18 does not support treeless clones: --filter=tree:0. Note: git v2.18 does not support treeless clones: --filter=tree:0.
*/ */
QString gitCommand("git clone --filter=blob:none ");
// Note: for some reason it is necessary to pass "--progress ---v",
// otherwise QProcess returns an error of 128 = 0x80 for the command.
QString gitCommand("git clone --progress -vvv --filter=blob:none ");
gitCommand += m_repositoryPath; gitCommand += m_repositoryPath;
Command c(gitCommand); Command c(gitCommand);
@@ -79,19 +83,32 @@ bool GitClient::gitCloneCustomerRepository() {
QString const result = c.getCommandResult(); QString const result = c.getCommandResult();
if (!result.isEmpty()) { if (!result.isEmpty()) {
// Cloning into 'customer_281'...\n // Cloning into 'customer_281'...\n
static QRegularExpression re("(^\\s*Cloning\\s+into\\s+[']\\s*)(.*)(\\s*['].*$)"); int customer = -1;
QRegularExpressionMatch match = re.match(result); int cloning = result.indexOf("Cloning", 0, Qt::CaseInsensitive);
if (match.hasMatch()) { if (cloning != -1) {
if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches customer = result.indexOf("customer_", cloning, Qt::CaseInsensitive);
if (match.captured(2).trimmed() == m_customerNr) { if (customer != -1) {
QString customerNr = result.mid(customer);
static constexpr char const ch = '\'';
int i = customerNr.indexOf(QChar(ch));
if (i != -1) {
if ((customerNr = customerNr.mid(0, i)) == m_customerNr) {
qInfo() << "CLONING" << m_repositoryPath << "OK"; qInfo() << "CLONING" << m_repositoryPath << "OK";
return true; return true;
} }
Utils::printCriticalErrorMsg(
QString("ERROR CLONE RESULT HAS WRONG CUSTOMER-NR. (%1 != %2) CLONE_RESULT=%3")
.arg(customerNr)
.arg(m_customerNr)
.arg(result));
return false;
}
} }
} }
Utils::printCriticalErrorMsg( Utils::printCriticalErrorMsg(
QString("ERROR CLONE RESULT HAS WRONG FORMAT. rcc=%1 CLONE_RESULT=%2") QString("ERROR CLONE RESULT HAS WRONG FORMAT. CLONING=%1 CUSTOMER=%2 CLONE_RESULT=%3")
.arg(re.captureCount()) .arg(cloning)
.arg(customer)
.arg(result)); .arg(result));
return false; return false;
} }

View File

@@ -56,6 +56,12 @@ void IsmasClient::printDebugMessage(int port,
QString const &clientIP, QString const &clientIP,
int clientPort, int clientPort,
QString const &message) { QString const &message) {
#if 1
Q_UNUSED(port);
Q_UNUSED(clientIP);
Q_UNUSED(clientPort);
Q_UNUSED(message);
#else
qDebug().noquote() qDebug().noquote()
<< "\n" << "\n"
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n" << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
@@ -64,12 +70,19 @@ void IsmasClient::printDebugMessage(int port,
<< "local address ..." << clientIP << "\n" << "local address ..." << clientIP << "\n"
<< "local port ......" << clientPort << "\n" << "local port ......" << clientPort << "\n"
<< message; << message;
#endif
} }
void IsmasClient::printInfoMessage(int port, void IsmasClient::printInfoMessage(int port,
QString const &clientIP, QString const &clientIP,
int clientPort, int clientPort,
QString const &message) { QString const &message) {
#if 1
Q_UNUSED(port);
Q_UNUSED(clientIP);
Q_UNUSED(clientPort);
Q_UNUSED(message);
#else
qInfo().noquote() qInfo().noquote()
<< "\n" << "\n"
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n" << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
@@ -78,6 +91,7 @@ void IsmasClient::printInfoMessage(int port,
<< "local address ..." << clientIP << "\n" << "local address ..." << clientIP << "\n"
<< "local port ......" << clientPort << "\n" << "local port ......" << clientPort << "\n"
<< message; << message;
#endif
} }
void IsmasClient::printErrorMessage(int port, void IsmasClient::printErrorMessage(int port,

View File

@@ -52,6 +52,22 @@ void Utils::printCriticalErrorMsg(QString const &errorMsg) {
qCritical() << QString(80, 'E'); qCritical() << QString(80, 'E');
} }
void Utils::printCriticalErrorMsg(QStringList const &errorMsg) {
qCritical() << QString(80, 'E');
for (int i = 0; i < errorMsg.size(); ++i) {
qCritical() << errorMsg.at(i);
}
qCritical() << QString(80, 'E');
}
void Utils::printUpdateStatusMsg(QStringList const &updateMsg) {
qCritical() << QString(80, 'U');
for (int i = 0; i < updateMsg.size(); ++i) {
qCritical() << updateMsg.at(i);
}
qCritical() << QString(80, 'U');
}
void Utils::printUpdateStatusMsg(QString const &updateMsg) { void Utils::printUpdateStatusMsg(QString const &updateMsg) {
qCritical() << QString(80, 'U'); qCritical() << QString(80, 'U');
qCritical() << updateMsg; qCritical() << updateMsg;
@@ -62,7 +78,14 @@ void Utils::printInfoMsg(QString const &infoMsg) {
qCritical() << QString(80, 'I'); qCritical() << QString(80, 'I');
qCritical() << infoMsg; qCritical() << infoMsg;
qCritical() << QString(80, 'I'); qCritical() << QString(80, 'I');
}
void Utils::printInfoMsg(QStringList const &infoMsg) {
qCritical() << QString(80, 'I');
for (int i = 0; i < infoMsg.size(); ++i) {
qCritical() << infoMsg.at(i);
}
qCritical() << QString(80, 'I');
} }
void Utils::printLineEditInfo(QStringList const &lines) { void Utils::printLineEditInfo(QStringList const &lines) {

View File

@@ -13,7 +13,10 @@ namespace Utils {
int read1stLineOfFile(QString fileName); int read1stLineOfFile(QString fileName);
QString zoneName(quint8 i); QString zoneName(quint8 i);
void printCriticalErrorMsg(QString const &errorMsg); void printCriticalErrorMsg(QString const &errorMsg);
void printCriticalErrorMsg(QStringList const &errorMsg);
void printInfoMsg(QString const &infoMsg); void printInfoMsg(QString const &infoMsg);
void printInfoMsg(QStringList const &infoMsg);
void printUpdateStatusMsg(QStringList const &updateMsg);
void printUpdateStatusMsg(QString const &updateMsg); void printUpdateStatusMsg(QString const &updateMsg);
void printLineEditInfo(QStringList const &lines); void printLineEditInfo(QStringList const &lines);
QString getTariffLoadTime(QString fileName); QString getTariffLoadTime(QString fileName);

View File

@@ -148,6 +148,83 @@ void Worker::update() {
std::call_once(once, &Worker::privateUpdate, this); 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() { void Worker::privateUpdate() {
if (!m_mainWindow) { if (!m_mainWindow) {
Utils::printCriticalErrorMsg("m_mainWindow NOT SET"); Utils::printCriticalErrorMsg("m_mainWindow NOT SET");
@@ -160,52 +237,88 @@ void Worker::privateUpdate() {
emit disableExit(); emit disableExit();
m_returnCode = -1; m_returnCode = -1;
QDir customerRepository(m_customerRepository); QDir customerRepository(m_customerRepository);
if (!customerRepository.exists()) { QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
Utils::printUpdateStatusMsg(
QStringList()
<< QString("STEP 1: CHECK SANITY OF CUSTOMER REPOSITORY %1...")
.arg(m_customerRepository));
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
// 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()) {
QString s("CORRUPTED CUSTOMER REPOSITORY. REPAIRING...");
if ((continueUpdate = repairCorruptedRepository()) == true) {
Utils::printUpdateStatusMsg(
QStringList() << s <<
QString("CORRUPTED CUSTOMER REPOSITORY. REPAIRING...DONE"));
} else {
Utils::printUpdateStatusMsg(
QStringList() << s <<
QString("CORRUPTED CUSTOMER REPOSITORY. REPAIRING...FAIL"));
}
}
if (continueUpdate) {
Utils::printUpdateStatusMsg(
QStringList()
<< QString("STEP 1: CHECKED SANITY OF CUSTOMER REPOSITORY %1 DONE")
.arg(m_customerRepository)
<< QString("STEP 2: FETCH CUSTOMER REPOSITORY %1...")
.arg(m_customerRepository));
if ((continueUpdate = customerRepository.exists()) == false) {
emit appendText("\nInitializing customer environment ..."); emit appendText("\nInitializing customer environment ...");
startProgressLoop(); startProgressLoop();
for (int i = 0; i < 5; ++i) { // try to checkout git repository
setProgress(i); // and switch to branch
if (m_gc.gitCloneAndCheckoutBranch()) { if (m_gc.gitCloneAndCheckoutBranch()) {
stopProgressLoop(); if (!isRepositoryCorrupted()) {
emit replaceLast("Initializing customer environment", UPDATE_STEP_DONE); emit replaceLast("Initializing customer environment", UPDATE_STEP_DONE);
m_returnCode = sendCloneAndCheckoutSuccess();
setProgress(5); continueUpdate = true;
initialClone = true;
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS, Utils::printInfoMsg("INITIAL CLONE DONE");
QString("CLONED AND CHECKED OUT: ") + m_customerRepository); break;
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);
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)) {
QThread::sleep(1); // maybe git needs more time
}
if (continueUpdate == false) {
emit replaceLast("Initializing customer environment", UPDATE_STEP_FAIL);
m_returnCode = sendCloneAndCheckoutFailure();
}
}
}
if (continueUpdate) { // repository is neither not existent nor
// corrupted. check now if the ISMAS-trigger
// (WAIT-BUTTON) is activated even in case of
// initial checkout
if (!initialClone) {
Utils::printUpdateStatusMsg(
QStringList()
<< QString("STEP 2: FETCHED CUSTOMER REPOSITORY %1 DONE")
.arg(m_customerRepository)
<< QString("STEP 3: CHECK ISMAS-UPDATE-TRIGGER FOR WAIT-STATUS..."));
//if ((continueUpdate = updateTriggerSet(10)) == false) {
// m_returnCode = sendIsmasTriggerFailure();
//}
if (updateTriggerSet(10)) {
if (customerEnvironment(30)) { if (customerEnvironment(30)) {
m_ismasClient.setProgressInPercent(50); m_ismasClient.setProgressInPercent(50);
if (filesToUpdate()) { if (filesToUpdate()) {
@@ -296,14 +409,12 @@ void Worker::privateUpdate() {
m_returnCode = -6; m_returnCode = -6;
} }
} else { } else {
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_TRIGGER_SET_FAILURE, m_returnCode = sendIsmasTriggerFailure();
QString("ISMAS update trigger wrong")); }
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT, } else { // initialClone
QString("#M=APISM#C=CMD_EVENT#J=") + Utils::printUpdateStatusMsg(
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, QString("STEP 2: FETCHED CUSTOMER REPOSITORY %1 DONE")
"CHECK-UPDATE-TRIGGER", .arg(m_customerRepository));
m_updateStatus.m_statusDescription));
m_returnCode = -5;
} }
} }
@@ -1148,8 +1259,8 @@ PSAInstalled Worker::getPSAInstalled() {
psaInstalled.hw.cpuSerial = m_cpuSerial; psaInstalled.hw.cpuSerial = m_cpuSerial;
psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameRepositoryOpkg); psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameRepositoryOpkg);
psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg); // psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg);
psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg); // psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg);
psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg); psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg);
psaInstalled.dc.versionHW = deviceControllerVersionHW; psaInstalled.dc.versionHW = deviceControllerVersionHW;
@@ -1327,6 +1438,10 @@ QDebug operator<< (QDebug debug, UpdateStatus status) {
debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ") debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ")
<< status.m_statusDescription; << status.m_statusDescription;
break; break;
case UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED:
debug << QString("UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED: ")
<< status.m_statusDescription;
break;
// default:; // default:;
} }
return debug; return debug;
@@ -1450,6 +1565,10 @@ QString& operator<< (QString& str, UpdateStatus status) {
str = QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: "); str = QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ");
str += status.m_statusDescription; str += status.m_statusDescription;
break; break;
case UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED:
str = QString("UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED: ");
str += status.m_statusDescription;
break;
//default:; //default:;
} }
return str; return str;

View File

@@ -52,7 +52,8 @@ enum class UPDATE_STATUS : quint8 {
PSA_UPDATE_FILES_FAILED, PSA_UPDATE_FILES_FAILED,
GIT_CHECK_FILES_TO_UPDATE_SUCCESS, GIT_CHECK_FILES_TO_UPDATE_SUCCESS,
ISMAS_SEND_LAST_VERSION_FAILED, ISMAS_SEND_LAST_VERSION_FAILED,
SAVE_LOG_FILES_FAILED SAVE_LOG_FILES_FAILED,
REMOVE_GIT_REPOSITORY_FAILED
}; };
struct UpdateStatus { struct UpdateStatus {
@@ -128,6 +129,16 @@ class Worker : public QObject {
QStringList getDCVersion() const; QStringList getDCVersion() const;
qint64 getFileSize(QString const &fileName) const; qint64 getFileSize(QString const &fileName) const;
bool isRepositoryCorrupted();
bool repairCorruptedRepository();
int sendCloneAndCheckoutSuccess();
int sendCloneAndCheckoutFailure();
int sendIsmasTriggerFailure();
static constexpr const int CLONE_AND_CHECKOUT_SUCCESS = 0;
static constexpr const int CLONE_AND_CHECKOUT_FAILURE = -3;
static constexpr const int ISMAS_TRIGGER_FAILURE = -5;
public: public:
static QString getATBUpdateToolYoctoVersion(); static QString getATBUpdateToolYoctoVersion();