Compare commits
24 Commits
4b9dcc5e99
...
v.1.3.13
Author | SHA1 | Date | |
---|---|---|---|
29e6a25e72 | |||
5abc057bda | |||
8aeb7ecfea | |||
4bb8e241b6 | |||
4469a23f9c | |||
d1f795e2db | |||
6865056f4b | |||
37bd5c90d3 | |||
fcba120dfa | |||
1d4f50fb9f | |||
a78040a037 | |||
9b175d7789 | |||
2d7f145a25 | |||
4589c4ca76 | |||
a32258a59e | |||
22f25e5251 | |||
258d883a51 | |||
504e242d42 | |||
731cdcbe09 | |||
b4e2d4c54a | |||
42961dea40 | |||
fd2f601f67 | |||
b45af505cd | |||
2dfe80b654 |
@@ -35,6 +35,12 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
# Fix display of UPDATE_SUCCESS when opkg_command fails. Detected when
|
||||
# updating apsim failed.
|
||||
# 1.3.11: Integrate version of ATBUpdateTool in SendLastVersion-ISMAS-message.
|
||||
# 1.3.12: Add command parameters for output of yocto-infos about ATBUpdateTool.
|
||||
# Use 'git pull' instead of 'git fetch'.
|
||||
# Use 'git clone --filter=blob:none' instead of 'git clone' to speed
|
||||
# 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 {
|
||||
BUILD_DATE=$$system("date /t")
|
||||
|
@@ -26,29 +26,93 @@ GitClient::GitClient(QString const &customerNrStr,
|
||||
}
|
||||
|
||||
bool GitClient::gitCloneCustomerRepository() {
|
||||
QString gitCommand("git clone ");
|
||||
/* Blobless clone
|
||||
==============
|
||||
|
||||
When using the --filter=blob:none option, the initial git clone will
|
||||
download all reachable commits and trees, and only download the blobs
|
||||
for commits when you do a git checkout. This includes the first checkout
|
||||
inside the git clone operation.
|
||||
|
||||
The important thing to notice is that we have a copy of every blob at
|
||||
HEAD but the blobs in the history are not present. If your repository
|
||||
has a deep history full of large blobs, then this option can
|
||||
significantly reduce your git clone times. The commit and tree data is
|
||||
still present, so any subsequent git checkout only needs to download
|
||||
the missing blobs. The Git client knows how to batch these requests to
|
||||
ask the server only for the missing blobs.
|
||||
|
||||
Further, when running git fetch in a blobless clone, the server only
|
||||
sends the new commits and trees. The new blobs are downloaded only
|
||||
after a git checkout. Note that git pull runs git fetch and then git
|
||||
merge, so it will download the necessary blobs during the git merge
|
||||
command.
|
||||
|
||||
When using a blobless clone, you will trigger a blob download whenever
|
||||
you need the contents of a file, but you will not need one if you only
|
||||
need the OID (object-id) of a file. This means that git log can detect
|
||||
which commits changed a given path without needing to download extra
|
||||
data.
|
||||
|
||||
This means that blobless clones can perform commands like git
|
||||
merge-base, git log, or even git log -- <path> with the same performance
|
||||
as a full clone.
|
||||
|
||||
Commands like git diff or git blame <path> require the contents of the
|
||||
paths to compute diffs, so these will trigger blob downloads the first
|
||||
time they are run. However, the good news is that after that you will
|
||||
have those blobs in your repository and do not need to download them a
|
||||
second time. Most developers only need to run git blame on a small
|
||||
number of files, so this tradeoff of a slightly slower git blame command
|
||||
is worth the faster clone and fetch times.
|
||||
|
||||
Note: git v2.18 does not support treeless clones: --filter=tree:0.
|
||||
*/
|
||||
|
||||
// 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;
|
||||
Command c(gitCommand);
|
||||
|
||||
qInfo() << "IN CURRENT WD" << m_workingDirectory
|
||||
<< "CLONE" << m_repositoryPath << "...";
|
||||
<< "CLONE VIA COMMAND" << gitCommand;
|
||||
|
||||
if (c.execute(m_workingDirectory)) { // execute the command in wd
|
||||
QString const result = c.getCommandResult();
|
||||
if (!result.isEmpty()) {
|
||||
// Cloning into 'customer_281'...\n
|
||||
static QRegularExpression re("(^\\s*Cloning\\s+into\\s+[']\\s*)(.*)(\\s*['].*$)");
|
||||
QRegularExpressionMatch match = re.match(result);
|
||||
if (match.hasMatch()) {
|
||||
if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
|
||||
if (match.captured(2).trimmed() == m_customerNr) {
|
||||
qInfo() << "CLONING" << m_repositoryPath << "OK";
|
||||
return true;
|
||||
int customer = -1;
|
||||
int cloning = result.indexOf("Cloning", 0, Qt::CaseInsensitive);
|
||||
if (cloning != -1) {
|
||||
customer = result.indexOf("customer_", cloning, Qt::CaseInsensitive);
|
||||
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";
|
||||
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(
|
||||
QString("ERROR CLONE RESULT HAS WRONG FORMAT. CLONING=%1 CUSTOMER=%2 CLONE_RESULT=%3")
|
||||
.arg(cloning)
|
||||
.arg(customer)
|
||||
.arg(result));
|
||||
return false;
|
||||
}
|
||||
Utils::printCriticalErrorMsg(QString("ERROR CLONE RESULT HAS WRONG FORMAT. CLONE_RESULT=") + result);
|
||||
Utils::printCriticalErrorMsg("ERROR CLONE RESULT IS EMPTY");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -218,11 +282,11 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
|
||||
/*
|
||||
Hat sich nichts geaendert, so werden auch keine Commits <>..<> angezeigt
|
||||
*/
|
||||
std::optional<QString> GitClient::gitFetch() {
|
||||
std::optional<QString> GitClient::gitPull() {
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
qInfo() << "BRANCH NAME" << m_branchName;
|
||||
|
||||
Command c("git fetch");
|
||||
Command c("git pull");
|
||||
if (c.execute(m_customerRepository)) {
|
||||
QString const s = c.getCommandResult().trimmed();
|
||||
if (!s.isEmpty()) {
|
||||
@@ -248,59 +312,38 @@ std::optional<QString> GitClient::gitFetch() {
|
||||
if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
|
||||
return match.captured(2);
|
||||
} else {
|
||||
emit m_worker->showErrorMessage("git fetch",
|
||||
emit m_worker->showErrorMessage("git pull",
|
||||
QString("(wrong cap-count (%1)").arg(re.captureCount()));
|
||||
}
|
||||
} else {
|
||||
emit m_worker->showErrorMessage("git fetch",
|
||||
emit m_worker->showErrorMessage("git pull",
|
||||
"no regex-match for commits");
|
||||
Utils::printCriticalErrorMsg("NO REGEX MATCH FOR COMMITS");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
emit m_worker->showErrorMessage("git fetch",
|
||||
emit m_worker->showErrorMessage("git pull",
|
||||
QString("unkown branch name ") + m_branchName);
|
||||
Utils::printCriticalErrorMsg("UNKNOWN BRANCH NAME " + m_branchName);
|
||||
}
|
||||
} else {
|
||||
emit m_worker->showErrorMessage("git fetch",
|
||||
QString("wrong format for result of 'git fetch' ") + s);
|
||||
emit m_worker->showErrorMessage("git pull",
|
||||
QString("wrong format for result of 'git pull' ") + s);
|
||||
Utils::printCriticalErrorMsg(QString("WRONG FORMAT FOR RESULT OF 'GIT FETCH' ") + s);
|
||||
}
|
||||
} else {
|
||||
// emit m_worker->showErrorMessage("git fetch", "empty result for 'git fetch'");
|
||||
Utils::printInfoMsg("EMPTY RESULT FOR 'GIT FETCH'");
|
||||
Utils::printInfoMsg("EMPTY RESULT FOR 'GIT PULL'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emit m_worker->showErrorMessage("git fetch", QString("repository ") + m_customerRepository + " does not exist");
|
||||
emit m_worker->showErrorMessage("git pull", QString("repository ") + m_customerRepository + " does not exist");
|
||||
Utils::printCriticalErrorMsg(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool GitClient::gitFetchAndDiff() {
|
||||
if (gitFetch()) {
|
||||
QString gitCommand("git diff --compact-summary HEAD..FETCH_HEAD");
|
||||
Command c(gitCommand);
|
||||
return c.execute(m_workingDirectory);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GitClient::gitPull() {
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
Command c("git pull");
|
||||
if (c.execute(m_customerRepository)) {
|
||||
qInfo() << "PULLED INTO" << m_customerRepository;
|
||||
return true;
|
||||
}
|
||||
Utils::printCriticalErrorMsg(QString("PULL INTO " + m_customerRepository + " FAILED"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<QStringList> GitClient::gitMerge() {
|
||||
Command c("git merge");
|
||||
if (c.execute(m_workingDirectory)) {
|
||||
|
@@ -43,9 +43,7 @@ class GitClient : public QObject {
|
||||
|
||||
bool gitCloneAndCheckoutBranch();
|
||||
|
||||
std::optional<QString> gitFetch();
|
||||
bool gitFetchAndDiff();
|
||||
bool gitPull();
|
||||
std::optional<QString> gitPull();
|
||||
std::optional<QStringList> gitDiff(QString const &commit);
|
||||
std::optional<QStringList> gitMerge();
|
||||
|
||||
|
@@ -56,6 +56,12 @@ void IsmasClient::printDebugMessage(int port,
|
||||
QString const &clientIP,
|
||||
int clientPort,
|
||||
QString const &message) {
|
||||
#if 1
|
||||
Q_UNUSED(port);
|
||||
Q_UNUSED(clientIP);
|
||||
Q_UNUSED(clientPort);
|
||||
Q_UNUSED(message);
|
||||
#else
|
||||
qDebug().noquote()
|
||||
<< "\n"
|
||||
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||
@@ -64,12 +70,19 @@ void IsmasClient::printDebugMessage(int port,
|
||||
<< "local address ..." << clientIP << "\n"
|
||||
<< "local port ......" << clientPort << "\n"
|
||||
<< message;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IsmasClient::printInfoMessage(int port,
|
||||
QString const &clientIP,
|
||||
int clientPort,
|
||||
QString const &message) {
|
||||
#if 1
|
||||
Q_UNUSED(port);
|
||||
Q_UNUSED(clientIP);
|
||||
Q_UNUSED(clientPort);
|
||||
Q_UNUSED(message);
|
||||
#else
|
||||
qInfo().noquote()
|
||||
<< "\n"
|
||||
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||
@@ -78,6 +91,7 @@ void IsmasClient::printInfoMessage(int port,
|
||||
<< "local address ..." << clientIP << "\n"
|
||||
<< "local port ......" << clientPort << "\n"
|
||||
<< message;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IsmasClient::printErrorMessage(int port,
|
||||
|
51
main.cpp
51
main.cpp
@@ -116,31 +116,63 @@ int main(int argc, char *argv[]) {
|
||||
QCoreApplication::translate("main", "Show extended version (including last git commit)."));
|
||||
parser.addOption(extendedVersionOption);
|
||||
|
||||
QCommandLineOption yoctoVersionOption(QStringList() << "y" << "yocto-version",
|
||||
QCoreApplication::translate("main", "Show yocto version of ATBUpdateTool."));
|
||||
parser.addOption(yoctoVersionOption);
|
||||
|
||||
QCommandLineOption yoctoInstallStatusOption(QStringList() << "Y" << "yocto-install",
|
||||
QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."));
|
||||
parser.addOption(yoctoInstallStatusOption);
|
||||
|
||||
// Process the actual command line arguments given by the user
|
||||
parser.process(a);
|
||||
QString plugInDir = parser.value(pluginDirectoryOption);
|
||||
QString plugInName = parser.value(pluginNameOption);
|
||||
QString workingDir = parser.value(workingDirectoryOption);
|
||||
bool const dryRun = parser.isSet(dryRunOption);
|
||||
bool const showYoctoVersion = parser.isSet(yoctoVersionOption);
|
||||
bool const showYoctoInstallStatus = parser.isSet(yoctoInstallStatusOption);
|
||||
bool const showExtendedVersion = parser.isSet(extendedVersionOption);
|
||||
QString const rtPath = QCoreApplication::applicationDirPath();
|
||||
|
||||
int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
|
||||
int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
|
||||
int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
|
||||
QString const branchName = (zoneNr != 0)
|
||||
? QString("zg1/zone%1").arg(zoneNr) : "master";
|
||||
|
||||
QThread::currentThread()->setObjectName("main thread");
|
||||
qInfo() << "Main thread" << QThread::currentThreadId();
|
||||
|
||||
if (showExtendedVersion) {
|
||||
printf(APP_EXTENDED_VERSION"\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (showYoctoVersion) {
|
||||
printf("%s\n", Worker::getATBUpdateToolYoctoVersion().toStdString().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (showYoctoInstallStatus) {
|
||||
printf("%s\n", Worker::getATBUpdateToolYoctoInstallationStatus().toStdString().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!QDir(plugInDir).exists()) {
|
||||
qCritical() << plugInDir
|
||||
<< "does not exists, but has to contain dc-library";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
qInfo() << "pwd ..............." << rtPath;
|
||||
qInfo() << "plugInDir ........." << plugInDir;
|
||||
qInfo() << "plugInName ........" << plugInName;
|
||||
qInfo() << "workingDir ........" << workingDir;
|
||||
qInfo() << "dryRun ............" << dryRun;
|
||||
qInfo() << "pwd ......................" << rtPath;
|
||||
qInfo() << "plugInDir ................" << plugInDir;
|
||||
qInfo() << "plugInName ..............." << plugInName;
|
||||
qInfo() << "workingDir ..............." << workingDir;
|
||||
qInfo() << "dryRun ..................." << dryRun;
|
||||
qInfo() << "extended-version ........." << APP_EXTENDED_VERSION;
|
||||
//qInfo() << "yocto-version ............" << Worker::getATBUpdateToolYoctoVersion();
|
||||
//qInfo() << "yocto-install-status ....." << Worker::getATBUpdateToolYoctoInstallationStatus();
|
||||
|
||||
// before loading the library, delete all possible shared memory segments
|
||||
#if defined Q_OS_LINUX || defined Q_OS_UNIX
|
||||
@@ -153,15 +185,6 @@ int main(int argc, char *argv[]) {
|
||||
hw->dc_autoRequest(true);
|
||||
// hw->dc_openSerial(5, "115200", "ttymxc2", 1);
|
||||
|
||||
int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
|
||||
int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
|
||||
int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
|
||||
QString const branchName = (zoneNr != 0)
|
||||
? QString("zg1/zone%1").arg(zoneNr) : "master";
|
||||
|
||||
QThread::currentThread()->setObjectName("main thread");
|
||||
qInfo() << "Main thread" << QThread::currentThreadId();
|
||||
|
||||
Worker worker(customerNr,
|
||||
machineNr,
|
||||
zoneNr,
|
||||
|
37
utils.cpp
37
utils.cpp
@@ -47,16 +47,45 @@ QString Utils::zoneName(quint8 i) {
|
||||
}
|
||||
|
||||
void Utils::printCriticalErrorMsg(QString const &errorMsg) {
|
||||
qCritical() << QString(80, '!');
|
||||
qCritical() << QString(80, 'E');
|
||||
qCritical() << errorMsg;
|
||||
qCritical() << QString(80, '!');
|
||||
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) {
|
||||
qCritical() << QString(80, 'U');
|
||||
qCritical() << updateMsg;
|
||||
qCritical() << QString(80, 'U');
|
||||
}
|
||||
|
||||
void Utils::printInfoMsg(QString const &infoMsg) {
|
||||
qCritical() << QString(80, '=');
|
||||
qCritical() << QString(80, 'I');
|
||||
qCritical() << infoMsg;
|
||||
qCritical() << QString(80, '=');
|
||||
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) {
|
||||
|
4
utils.h
4
utils.h
@@ -13,7 +13,11 @@ namespace Utils {
|
||||
int read1stLineOfFile(QString fileName);
|
||||
QString zoneName(quint8 i);
|
||||
void printCriticalErrorMsg(QString const &errorMsg);
|
||||
void printCriticalErrorMsg(QStringList const &errorMsg);
|
||||
void printInfoMsg(QString const &infoMsg);
|
||||
void printInfoMsg(QStringList const &infoMsg);
|
||||
void printUpdateStatusMsg(QStringList const &updateMsg);
|
||||
void printUpdateStatusMsg(QString const &updateMsg);
|
||||
void printLineEditInfo(QStringList const &lines);
|
||||
QString getTariffLoadTime(QString fileName);
|
||||
QString rstrip(QString const &str);
|
||||
|
357
worker.cpp
357
worker.cpp
@@ -148,6 +148,83 @@ void Worker::update() {
|
||||
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");
|
||||
@@ -160,150 +237,184 @@ void Worker::privateUpdate() {
|
||||
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);
|
||||
QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
|
||||
|
||||
setProgress(5);
|
||||
Utils::printUpdateStatusMsg(
|
||||
QStringList()
|
||||
<< QString("STEP 1: CHECK SANITY OF CUSTOMER REPOSITORY %1...")
|
||||
.arg(m_customerRepository));
|
||||
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CLONE_AND_CHECKOUT_SUCCESS,
|
||||
QString("CLONED AND CHECKED OUT: ") + 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.
|
||||
|
||||
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;
|
||||
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 {
|
||||
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;
|
||||
Utils::printUpdateStatusMsg(
|
||||
QStringList() << s <<
|
||||
QString("CORRUPTED CUSTOMER REPOSITORY. REPAIRING...FAIL"));
|
||||
}
|
||||
} 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());
|
||||
if (continueUpdate) {
|
||||
|
||||
m_returnCode = 0;
|
||||
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 ...");
|
||||
startProgressLoop();
|
||||
for (int i = 0; i < 5; ++i) { // try to checkout git repository
|
||||
setProgress(i); // and switch to branch
|
||||
if (m_gc.gitCloneAndCheckoutBranch()) {
|
||||
if (!isRepositoryCorrupted()) {
|
||||
emit replaceLast("Initializing customer environment", UPDATE_STEP_DONE);
|
||||
m_returnCode = sendCloneAndCheckoutSuccess();
|
||||
continueUpdate = true;
|
||||
initialClone = true;
|
||||
Utils::printInfoMsg("INITIAL CLONE DONE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
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"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"SAVE-LOG-FILES",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -11;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::SAVE_LOG_FILES_FAILED,
|
||||
QString("Saving log files failed"));
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED,
|
||||
QString("Sending ISMAS last version failed"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"SAVE-LOG-FILES",
|
||||
"ISMAS-SEND-LAST-VERSION",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -11;
|
||||
m_returnCode = -10;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_SEND_LAST_VERSION_FAILED,
|
||||
QString("Sending ISMAS last version failed"));
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_UPDATES_FAILURE,
|
||||
QString("Syncing files to update failed"));
|
||||
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",
|
||||
"RSYNC-UPDATE-FILES",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -10;
|
||||
m_returnCode = -9;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_UPDATES_FAILURE,
|
||||
QString("Syncing files to update failed"));
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::PSA_UPDATE_FILES_FAILED,
|
||||
QString("Updating files failed"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"RSYNC-UPDATE-FILES",
|
||||
"UPDATE-FILES",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -9;
|
||||
m_returnCode = -8;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::PSA_UPDATE_FILES_FAILED,
|
||||
QString("Updating files failed"));
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
||||
QString("No files to update"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"UPDATE-FILES",
|
||||
"FETCH-FILES-TO-UPDATE",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -8;
|
||||
m_returnCode = -7;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
||||
QString("No files to update"));
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE,
|
||||
QString("Configuring customer environment failed"));
|
||||
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",
|
||||
"GIT-CHECKOUT-BRANCH",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -7;
|
||||
m_returnCode = -6;
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH_FAILURE,
|
||||
QString("Configuring customer environment failed"));
|
||||
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||
m_ismasClient.updateOfPSAFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||
"GIT-CHECKOUT-BRANCH",
|
||||
m_updateStatus.m_statusDescription));
|
||||
m_returnCode = -6;
|
||||
m_returnCode = sendIsmasTriggerFailure();
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
m_returnCode = -5;
|
||||
} else { // initialClone
|
||||
Utils::printUpdateStatusMsg(
|
||||
QString("STEP 2: FETCHED CUSTOMER REPOSITORY %1 DONE")
|
||||
.arg(m_customerRepository));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,7 +839,7 @@ bool Worker::filesToUpdate() {
|
||||
// always execute contents of opkg_commands-file
|
||||
m_filesToUpdate << "etc/psa_update/opkg_commands";
|
||||
|
||||
if (std::optional<QString> changes = m_gc.gitFetch()) {
|
||||
if (std::optional<QString> changes = m_gc.gitPull()) {
|
||||
stopProgressLoop();
|
||||
int progress = (m_mainWindow->progressValue()/10) + 10;
|
||||
setProgress(progress);
|
||||
@@ -981,6 +1092,30 @@ QString Worker::getOsVersion() const {
|
||||
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");
|
||||
@@ -1124,8 +1259,8 @@ PSAInstalled Worker::getPSAInstalled() {
|
||||
psaInstalled.hw.cpuSerial = m_cpuSerial;
|
||||
|
||||
psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameRepositoryOpkg);
|
||||
psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg);
|
||||
psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg);
|
||||
// psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg);
|
||||
// psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg);
|
||||
psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg);
|
||||
|
||||
psaInstalled.dc.versionHW = deviceControllerVersionHW;
|
||||
@@ -1303,6 +1438,10 @@ QDebug operator<< (QDebug debug, UpdateStatus status) {
|
||||
debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ")
|
||||
<< status.m_statusDescription;
|
||||
break;
|
||||
case UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED:
|
||||
debug << QString("UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED: ")
|
||||
<< status.m_statusDescription;
|
||||
break;
|
||||
// default:;
|
||||
}
|
||||
return debug;
|
||||
@@ -1426,6 +1565,10 @@ QString& operator<< (QString& str, UpdateStatus status) {
|
||||
str = QString("UPDATE_STATUS::RSYNC_FILE_SUCCESS: ");
|
||||
str += status.m_statusDescription;
|
||||
break;
|
||||
case UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED:
|
||||
str = QString("UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED: ");
|
||||
str += status.m_statusDescription;
|
||||
break;
|
||||
//default:;
|
||||
}
|
||||
return str;
|
||||
|
16
worker.h
16
worker.h
@@ -52,7 +52,8 @@ enum class UPDATE_STATUS : quint8 {
|
||||
PSA_UPDATE_FILES_FAILED,
|
||||
GIT_CHECK_FILES_TO_UPDATE_SUCCESS,
|
||||
ISMAS_SEND_LAST_VERSION_FAILED,
|
||||
SAVE_LOG_FILES_FAILED
|
||||
SAVE_LOG_FILES_FAILED,
|
||||
REMOVE_GIT_REPOSITORY_FAILED
|
||||
};
|
||||
|
||||
struct UpdateStatus {
|
||||
@@ -128,8 +129,21 @@ class Worker : public QObject {
|
||||
QStringList getDCVersion() 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:
|
||||
static QString getATBUpdateToolYoctoVersion();
|
||||
static QString getATBUpdateToolYoctoInstallationStatus();
|
||||
|
||||
static const QString UPDATE_STEP_OK;
|
||||
static const QString UPDATE_STEP_DONE;
|
||||
static const QString UPDATE_STEP_FAIL;
|
||||
|
Reference in New Issue
Block a user