Compare commits
8 Commits
077eb803a1
...
60084450e6
Author | SHA1 | Date | |
---|---|---|---|
60084450e6 | |||
9775792916 | |||
93d6277386 | |||
37c5c7c4f6 | |||
5eb33f3e31 | |||
43f5f3ecae | |||
c503750e90 | |||
7054c18113 |
@ -61,6 +61,7 @@ void ApismClient::restartApism() {
|
||||
|
||||
void ApismClient::sendTransaction(const VendingData *vendingData) {
|
||||
|
||||
Q_UNUSED(vendingData);
|
||||
|
||||
#if 0
|
||||
QScopedPointer<ISMAS::TransferData> transferData(new ISMAS::TransferData());
|
||||
@ -411,14 +412,14 @@ void ApismClient::sendCmdSendVersionToIsmas(QString const &msg) {
|
||||
QByteArray data = "#M=APISM#C=CMD_SENDVERSION#J=";
|
||||
data += document.toJson(QJsonDocument::Compact);
|
||||
|
||||
printf("data=%s\n", QString(data).toStdString().c_str());
|
||||
// printf("data=%s\n", QString(data).toStdString().c_str());
|
||||
|
||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
||||
this->apismTcpSendClient->sendData(data);
|
||||
|
||||
}
|
||||
|
||||
void ApismClient::sendUpdateInfoToIsmas(QString const &msg) {
|
||||
void ApismClient::emulateUpdatesAvailable(QString const &msg) {
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
@ -435,7 +436,7 @@ void ApismClient::sendUpdateInfoToIsmas(QString const &msg) {
|
||||
QByteArray data = "#M=APISM#C=CMD_EVENT#J=";
|
||||
data += document.toJson(QJsonDocument::Compact);
|
||||
|
||||
printf("data=%s\n", QString(data).toStdString().c_str());
|
||||
qDebug() << "EMULATE UPDATES AVAILABLE" << QString(data).toStdString().c_str();
|
||||
|
||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
||||
this->apismTcpSendClient->sendData(data);
|
||||
@ -447,7 +448,6 @@ void ApismClient::sendState(const QString & state, const QString & msg)
|
||||
qCritical() << " state: " << state;
|
||||
qCritical() << " msg: " << msg;
|
||||
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
|
@ -57,7 +57,7 @@ public slots:
|
||||
//void sendEvent(const ATBMachineEvent* machineEvent);
|
||||
|
||||
void sendState(const QString & state, const QString & msg);
|
||||
void sendUpdateInfoToIsmas(QString const &msg);
|
||||
void emulateUpdatesAvailable(QString const &msg);
|
||||
void sendCmdSendVersionToIsmas(QString const &msg);
|
||||
void requestAvailableIsmasUpdates();
|
||||
|
||||
|
@ -7,20 +7,18 @@
|
||||
#include <QDir>
|
||||
|
||||
|
||||
GitClient::GitClient(QString const &repositoryPath,
|
||||
QString const &customerId,
|
||||
GitClient::GitClient(QString const &customerNrStr,
|
||||
QString const &customerRepository,
|
||||
QString const &workingDirectory,
|
||||
QString const &branchName,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_worker(qobject_cast<Worker *>(parent))
|
||||
, m_repositoryPath(repositoryPath)
|
||||
, m_customerId(customerId)
|
||||
, m_repositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(customerNrStr))
|
||||
, m_customerNr(customerNrStr)
|
||||
, m_workingDirectory(workingDirectory)
|
||||
, m_branchName(branchName)
|
||||
, m_customerRepository(QDir::cleanPath(m_workingDirectory
|
||||
+ QDir::separator()
|
||||
+ m_customerId)) {
|
||||
, m_customerRepository(customerRepository) {
|
||||
if (!m_worker) {
|
||||
qCritical() << "ERROR CASTING PARENT TO WORKER FAILED";
|
||||
}
|
||||
@ -63,18 +61,6 @@ void GitClient::onIsmasUpdatesAvailable() {
|
||||
if (gitCloneAndCheckoutBranch()) {
|
||||
qInfo() << "CLONED" << m_repositoryPath
|
||||
<< "AND CHECKED OUT INTO" << m_customerRepository;
|
||||
if (m_worker) {
|
||||
qDebug() << "WORKER EXECUTE OPKG COMMANDS";
|
||||
QStringList opkgCommands;
|
||||
// To make sure that opkg upgrade does not break your system
|
||||
// because of an unstable connection
|
||||
// Add a line "option cache cachedir" to /etc/opkg/opkg.conf to
|
||||
// avoid the --cache option on command line.
|
||||
opkgCommands << "opkg update";
|
||||
//opkgCommands << "opkg --cache cachedir --download-only upgrade";
|
||||
//opkgCommands << "opkg --cache cachedir upgrade";
|
||||
emit m_worker->executeOpkgCommands(opkgCommands);
|
||||
}
|
||||
} else {
|
||||
qCritical() << "ERROR CLONING " << m_repositoryPath
|
||||
<< "AND/OR CHECKING OUT INTO" << m_customerRepository;
|
||||
@ -99,7 +85,7 @@ bool GitClient::gitCloneCustomerRepository() {
|
||||
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_customerId) {
|
||||
if (match.captured(2).trimmed() == m_customerNr) {
|
||||
qInfo() << "CLONING" << m_repositoryPath << "OK";
|
||||
return true;
|
||||
}
|
||||
@ -112,7 +98,7 @@ bool GitClient::gitCloneCustomerRepository() {
|
||||
}
|
||||
|
||||
bool GitClient::copyGitConfigFromMaster() { // only allowed when called in
|
||||
// master branch
|
||||
// master branch (???)
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
QString const cp = QString("cp .gitconfig .git/config");
|
||||
Command c("bash");
|
||||
@ -139,9 +125,9 @@ bool GitClient::gitCheckoutBranch() {
|
||||
bool GitClient::gitCloneAndCheckoutBranch() {
|
||||
qInfo() << "CLONE" << m_repositoryPath << "AND CHECKOUT" << m_branchName;
|
||||
if (gitCloneCustomerRepository()) {
|
||||
if (copyGitConfigFromMaster()) {
|
||||
//if (copyGitConfigFromMaster()) {
|
||||
return gitCheckoutBranch();
|
||||
}
|
||||
//}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -191,11 +177,9 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
|
||||
Hat sich nichts geaendert, so werden auch keine Commits <>..<> angezeigt
|
||||
*/
|
||||
std::optional<QString> GitClient::gitFetch() {
|
||||
QString const &customerRepository
|
||||
= QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerId);
|
||||
if (QDir(customerRepository).exists()) {
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
Command c("git fetch");
|
||||
if (c.execute(customerRepository)) {
|
||||
if (c.execute(m_customerRepository)) {
|
||||
QString const s = c.getCommandResult().trimmed();
|
||||
if (!s.isEmpty()) {
|
||||
QStringList lines = Update::split(s, '\n');
|
||||
@ -220,7 +204,7 @@ std::optional<QString> GitClient::gitFetch() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qCritical() << "ERROR" << customerRepository << "DOES NOT EXIST";
|
||||
qCritical() << "ERROR" << m_customerRepository << "DOES NOT EXIST";
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class GitClient : public QObject {
|
||||
|
||||
Worker *m_worker;
|
||||
QString const m_repositoryPath;
|
||||
QString const m_customerId;
|
||||
QString const m_customerNr;
|
||||
QString const m_workingDirectory;
|
||||
QString const m_branchName;
|
||||
QString const m_customerRepository;
|
||||
@ -20,8 +20,8 @@ class GitClient : public QObject {
|
||||
bool copyGitConfigFromMaster();
|
||||
|
||||
public:
|
||||
explicit GitClient(QString const &repositoryPath,
|
||||
QString const &customerId,
|
||||
explicit GitClient(QString const &customerNrStr,
|
||||
QString const &repositoryPath,
|
||||
QString const &workingDirectory = QCoreApplication::applicationDirPath(),
|
||||
QString const &branchName = "master",
|
||||
QObject *parent = 0);
|
||||
|
35
main.cpp
35
main.cpp
@ -84,16 +84,6 @@ int main(int argc, char *argv[]) {
|
||||
QCoreApplication::translate("main", "Maintenance mode for underlying script"));
|
||||
parser.addOption(maintenanceOption);
|
||||
|
||||
// test-mode: edit the file update_log.csv and execute the commands
|
||||
// contained in it. Do not call the update-script.
|
||||
QCommandLineOption testOption(QStringList() << "t" << "test",
|
||||
QCoreApplication::translate("main", "Test mode for ATBUpdateTool"));
|
||||
parser.addOption(testOption);
|
||||
|
||||
QCommandLineOption execScriptOption(QStringList() << "e" << "execute-script-only",
|
||||
QCoreApplication::translate("main", "ATBUpdateTool executes update-script only. No download of any files."));
|
||||
parser.addOption(execScriptOption);
|
||||
|
||||
QCommandLineOption dryRunOption(QStringList() << "d" << "dry-run",
|
||||
QCoreApplication::translate("main", "Start ATBUpdateTool in dry-run-mode. No actual actions."));
|
||||
parser.addOption(dryRunOption);
|
||||
@ -112,8 +102,6 @@ int main(int argc, char *argv[]) {
|
||||
QString plugInName = parser.value(pluginNameOption);
|
||||
QString workingDir = parser.value(workingDirectoryOption);
|
||||
bool maintenanceMode = parser.isSet(maintenanceOption);
|
||||
bool testMode = parser.isSet(testOption);
|
||||
bool executeScriptOnly = parser.isSet(execScriptOption);
|
||||
bool dryRun = parser.isSet(dryRunOption);
|
||||
QString const rtPath = QCoreApplication::applicationDirPath();
|
||||
|
||||
@ -131,8 +119,6 @@ int main(int argc, char *argv[]) {
|
||||
qInfo() << "plugInName ........" << plugInName;
|
||||
qInfo() << "workingDir ........" << workingDir;
|
||||
qInfo() << "maintenanceMode ..." << maintenanceMode;
|
||||
qInfo() << "testMode .........." << testMode;
|
||||
qInfo() << "execScriptOnly ...." << executeScriptOnly;
|
||||
qInfo() << "dryRun ............" << dryRun;
|
||||
|
||||
// before loading the library, delete all possible shared memory segments
|
||||
@ -146,15 +132,22 @@ int main(int argc, char *argv[]) {
|
||||
// hw->dc_autoRequest(false);
|
||||
|
||||
QString const update_ctrl_file = "/opt/app/tools/atbupdate/update_log.csv";
|
||||
Worker worker(hw, update_ctrl_file,
|
||||
"https://git.mimbach49.de/GerhardHoffmann/customer_999.git",
|
||||
"customer_999",
|
||||
"zg1/zone1",
|
||||
|
||||
int machineNr = Worker::read1stLineOfFile("/etc/machine_nr");
|
||||
int customerNr = Worker::read1stLineOfFile("/etc/cust_nr");
|
||||
QString customerNrStr = QString("customer_") + QString::number(customerNr).rightJustified(3, '0');
|
||||
int zoneNr = Worker::read1stLineOfFile("/etc/zone_nr");
|
||||
QString branchName = QString("zg1/zone%1").arg(zoneNr);
|
||||
|
||||
Worker worker(hw,
|
||||
customerNr,
|
||||
machineNr,
|
||||
zoneNr,
|
||||
branchName,
|
||||
workingDir,
|
||||
maintenanceMode,
|
||||
testMode,
|
||||
executeScriptOnly,
|
||||
dryRun);
|
||||
dryRun
|
||||
);
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ bool Command::execute(QString workingDirectory, QStringList args) {
|
||||
connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
|
||||
connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
|
||||
|
||||
qCritical() << "START COMMAND" << m_command << "IN" << workingDirectory;
|
||||
qCritical() << "START COMMAND" << m_command << "WITH ARGS" << args
|
||||
<< "IN" << workingDirectory;
|
||||
|
||||
p->setWorkingDirectory(workingDirectory);
|
||||
if (!args.isEmpty()) {
|
||||
@ -55,8 +56,11 @@ bool Command::execute(QString workingDirectory, QStringList args) {
|
||||
}
|
||||
|
||||
if (p->waitForStarted(m_waitForStartTimeout)) {
|
||||
qDebug() << "PROCESS" << m_command << "STARTED";
|
||||
if (p->state() == QProcess::ProcessState::Running) {
|
||||
qDebug() << "PROCESS" << m_command << "RUNNING";
|
||||
if (p->waitForFinished(m_waitForFinishTimeout)) {
|
||||
qDebug() << "PROCESS" << m_command << "FINISHED";
|
||||
if (p->exitStatus() == QProcess::NormalExit) {
|
||||
qInfo() << "EXECUTED" << m_command
|
||||
<< "with code" << p->exitCode();
|
||||
|
453
update.cpp
453
update.cpp
@ -22,11 +22,6 @@
|
||||
#include <QPluginLoader>
|
||||
#include <QMap>
|
||||
|
||||
#define COLUMN_REQUEST (0)
|
||||
#define COLUMN_NAME (1)
|
||||
#define COLUMN_DATE_TIME (2)
|
||||
#define COLUMN_RESULT (3)
|
||||
|
||||
#define UPDATE_OPKG (1)
|
||||
#define UPDATE_DC (1)
|
||||
#define UPDATE_PRINTER_TEMPLATES (1)
|
||||
@ -80,14 +75,10 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
|
||||
}
|
||||
|
||||
Update::Update(hwinf *hw,
|
||||
QString update_ctrl_file,
|
||||
QString repositoryPath,
|
||||
QString customerId,
|
||||
QString customerRepository,
|
||||
QString customerNrStr,
|
||||
QString branchName,
|
||||
QString workingDir,
|
||||
bool maintenanceMode,
|
||||
bool testMode,
|
||||
bool executeScriptOnly,
|
||||
bool dryRun,
|
||||
QObject *parent,
|
||||
char const *serialInterface,
|
||||
@ -96,118 +87,14 @@ Update::Update(hwinf *hw,
|
||||
, m_hw(hw)
|
||||
, m_serialInterface(serialInterface)
|
||||
, m_baudrate(baudrate)
|
||||
, m_update_ctrl_file(update_ctrl_file)
|
||||
, m_update_ctrl_file_copy(update_ctrl_file + ".copy")
|
||||
, m_repositoryPath(repositoryPath)
|
||||
, m_customerId(customerId)
|
||||
, m_customerRepository(customerRepository)
|
||||
, m_customerNrStr(customerNrStr)
|
||||
, m_branchName(branchName)
|
||||
, m_workingDir(workingDir)
|
||||
, m_maintenanceMode(maintenanceMode)
|
||||
, m_testMode(testMode)
|
||||
, m_executeScriptOnly(executeScriptOnly)
|
||||
, m_dryRun(dryRun)
|
||||
//, m_apismClient(nullptr, nullptr, nullptr)
|
||||
, m_init(true) {
|
||||
|
||||
// m_apismClient.sendSelfTest();
|
||||
|
||||
if (!m_testMode) {
|
||||
// make sure the files are empty
|
||||
if (m_update_ctrl_file.exists()) {
|
||||
if (m_update_ctrl_file.open(QIODevice::ReadWrite |
|
||||
QIODevice::Truncate |
|
||||
QIODevice::Text)) {
|
||||
m_update_ctrl_file.close();
|
||||
}
|
||||
} else {
|
||||
qCritical() << "Update-file" << m_update_ctrl_file.fileName()
|
||||
<< "does not exist";
|
||||
m_init = false;
|
||||
}
|
||||
if (m_update_ctrl_file_copy.exists()) {
|
||||
if (m_update_ctrl_file_copy.open(QIODevice::ReadWrite |
|
||||
QIODevice::Truncate |
|
||||
QIODevice::Text)) {
|
||||
m_update_ctrl_file_copy.close();
|
||||
}
|
||||
} else {
|
||||
qCritical() << "Update-file-copy" << m_update_ctrl_file_copy.fileName()
|
||||
<< "does not exist";
|
||||
m_init = false;
|
||||
}
|
||||
}
|
||||
|
||||
// execute update_psa-script
|
||||
if (m_init) {
|
||||
if (!m_testMode) {
|
||||
if ((m_init = execUpdateScript()) == false) {
|
||||
qCritical() << "UPDATE_SCRIPT FAILED";
|
||||
}
|
||||
}
|
||||
if (m_init) {
|
||||
if (!m_update_ctrl_file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
qCritical() << "CAN NOT OPEN" << m_update_ctrl_file.fileName();
|
||||
m_init = false;
|
||||
} else {
|
||||
qDebug() << "OPENED" << m_update_ctrl_file.fileName();
|
||||
}
|
||||
if (!m_update_ctrl_file_copy.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
qCritical() << "CAN NOT OPEN" << m_update_ctrl_file_copy.fileName();
|
||||
m_init = false;
|
||||
} else {
|
||||
qDebug() << "OPENED" << m_update_ctrl_file_copy.fileName();
|
||||
}
|
||||
}
|
||||
}
|
||||
, m_dryRun(dryRun) {
|
||||
}
|
||||
|
||||
Update::~Update() {
|
||||
// make sure the files are closed
|
||||
m_update_ctrl_file.close();
|
||||
m_update_ctrl_file_copy.close();
|
||||
}
|
||||
|
||||
bool Update::execUpdateScript() {
|
||||
// path of update-script 'update_psa'
|
||||
QString update_psa("/opt/app/tools/atbupdate/update_psa ");
|
||||
if (m_maintenanceMode) {
|
||||
update_psa += " -m ";
|
||||
}
|
||||
update_psa += " --wdir ";
|
||||
update_psa += m_workingDir;
|
||||
|
||||
qCritical() << "update_psa: " << update_psa;
|
||||
|
||||
QScopedPointer<QProcess> p(new QProcess(this));
|
||||
p->setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
|
||||
connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
|
||||
|
||||
p->start(update_psa);
|
||||
|
||||
if (p->waitForStarted(1000)) {
|
||||
if (p->state() == QProcess::ProcessState::Running) {
|
||||
// maintenance_mode: update_psa script enters an infinite loop
|
||||
int const timeout = (m_maintenanceMode ? 200000: -1);
|
||||
if (p->waitForFinished(timeout)) {
|
||||
QString output = p->readAllStandardOutput().toStdString().c_str();
|
||||
QStringList lst = output.split('\n');
|
||||
for (int i = 0; i < lst.size(); ++i) {
|
||||
qDebug() << lst[i];
|
||||
}
|
||||
if (p->exitStatus() == QProcess::NormalExit) {
|
||||
qInfo() << "EXECUTED" << update_psa
|
||||
<< "with code" << p->exitCode();
|
||||
return (p->exitCode() == 0);
|
||||
}
|
||||
} else {
|
||||
qCritical() << "update-script TIMEDOUT after"
|
||||
<< timeout/1000 << "seconds";
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Update::DownloadResult Update::sendStatus(int ret) const {
|
||||
@ -589,22 +476,6 @@ bool Update::updateDeviceConf(QString jsFile) {
|
||||
return downloadJson(FileTypeJson::DEVICE, 0, jsFile);
|
||||
}
|
||||
|
||||
QStringList Update::getLinesToWorkOn() {
|
||||
QStringList linesToWorkOn;
|
||||
|
||||
QTextStream in(&m_update_ctrl_file);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed();
|
||||
if (line.startsWith("DONE")) {
|
||||
m_update_ctrl_file_copy.write(line.toUtf8().constData());
|
||||
m_update_ctrl_file_copy.write("\n");
|
||||
} else {
|
||||
linesToWorkOn << line;
|
||||
}
|
||||
}
|
||||
return linesToWorkOn;
|
||||
}
|
||||
|
||||
QStringList Update::split(QString line, QChar sep) {
|
||||
QStringList lst;
|
||||
QString next;
|
||||
@ -639,248 +510,138 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
|
||||
disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
|
||||
}
|
||||
|
||||
// bool Update::executeProcess(QString const &cmd);
|
||||
|
||||
bool Update::doUpdate() {
|
||||
bool Update::doUpdate(QStringList const &filesToWorkOn) {
|
||||
|
||||
//
|
||||
// ACHTUNG !!!
|
||||
//
|
||||
return true;
|
||||
|
||||
/*
|
||||
The file referred to by 'update_data' has the following structure for
|
||||
each line:
|
||||
|
||||
# ======================================================================
|
||||
# REQUEST | NAME | DATE | RESULT
|
||||
# ======================================================================
|
||||
# where
|
||||
#
|
||||
# STATUS: DOWNLOAD, EXECUTE or DONE
|
||||
# NAME : If starting with 'opkg' it is an opkg-command to be executed.
|
||||
# Otherwise its the name of a file which has to be updated.
|
||||
# DATE : 0000-00-00T00:00:00
|
||||
# RESULT: SUCCESS or ERROR (possibly with description)
|
||||
#
|
||||
*/
|
||||
|
||||
if (!m_init) {
|
||||
qCritical() << "DO UPDATE: INITIALIZATION OR UPDATE-SCRIPT FAILED";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_executeScriptOnly) { // basically a test flag for executing only the
|
||||
return true; // update script.
|
||||
}
|
||||
|
||||
bool serialOpened = false;
|
||||
bool serialOpen = false;
|
||||
|
||||
QStringList linesToWorkOn = getLinesToWorkOn();
|
||||
if (linesToWorkOn.size() == 0) {
|
||||
qCritical() << "No lines to handle in" << m_update_ctrl_file.fileName();
|
||||
if (filesToWorkOn.size() == 0) {
|
||||
qCritical() << "NOTHING TO UPDATE";
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug() << "open lines...";
|
||||
for (int i=0; i< linesToWorkOn.size(); ++i) {
|
||||
qDebug() << "line" << i << ":" << linesToWorkOn.at(i).trimmed();
|
||||
if (!serialOpen) {
|
||||
if (!isSerialOpen()) { // open serial only if not already open
|
||||
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) {
|
||||
qCritical() << "CANNOT OPEN" << m_serialInterface << "(BAUDRATE="
|
||||
<< m_baudrate << ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
serialOpen = true;
|
||||
qCritical() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")";
|
||||
}
|
||||
|
||||
QList<QString>::const_iterator it;
|
||||
for (it = linesToWorkOn.cbegin(); it != linesToWorkOn.cend(); ++it) {
|
||||
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
|
||||
bool res = false;
|
||||
QString line = (*it).trimmed();
|
||||
if (line.size() == 0 || line.startsWith(QChar('#'))) {
|
||||
continue;
|
||||
}
|
||||
QStringList lst = split(line.trimmed());
|
||||
if (lst.size() != 4) {
|
||||
qCritical() << "PARSING ERROR FOR LINE"
|
||||
<< line << "IN" << m_update_ctrl_file.fileName();
|
||||
continue;
|
||||
}
|
||||
QString const &request = lst[COLUMN_REQUEST];
|
||||
QString const &name = lst[COLUMN_NAME];
|
||||
QString fToWorkOn = (*it).trimmed();
|
||||
|
||||
QTextStream out(&m_update_ctrl_file_copy);
|
||||
// QString const &datetime = lst[COLUMN_DATE_TIME];
|
||||
// QString const &result = lst[COLUMN_RESULT];
|
||||
qDebug() << "request=" << request << ", name=" << name;
|
||||
if (request.trimmed() == "DOWNLOAD") {
|
||||
if (!serialOpen) {
|
||||
if (!isSerialOpen()) { // open serial only if not already open
|
||||
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) {
|
||||
qCritical() << "CANNOT OPEN" << m_serialInterface << "(BAUDRATE="
|
||||
<< m_baudrate << ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
serialOpen = true;
|
||||
qCritical() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")";
|
||||
|
||||
if (fToWorkOn.contains("dc2c", Qt::CaseInsensitive) &&
|
||||
fToWorkOn.endsWith(".bin", Qt::CaseInsensitive)) {
|
||||
|
||||
qDebug() << "sending sw/hw-requests...";
|
||||
for (int i=0; i < 3; ++i) { // send explicit reuests to get
|
||||
// current SW/HW-versions
|
||||
m_hw->request_DC2_SWversion();
|
||||
m_hw->request_DC2_HWversion();
|
||||
QThread::sleep(1);
|
||||
}
|
||||
|
||||
if (name.contains("dc2c", Qt::CaseInsensitive) &&
|
||||
name.endsWith(".bin", Qt::CaseInsensitive)) {
|
||||
qDebug() << "sending sw/hw-requests...";
|
||||
for (int i=0; i < 3; ++i) { // send explicit reuests to get
|
||||
// current SW/HW-versions
|
||||
m_hw->request_DC2_SWversion();
|
||||
m_hw->request_DC2_HWversion();
|
||||
QThread::sleep(1);
|
||||
}
|
||||
QString const hwVersion = m_hw->dc_getHWversion().toLower();
|
||||
QString const fwVersion = m_hw->dc_getSWversion().toLower();
|
||||
qInfo() << "current dc-hardware-version" << hwVersion;
|
||||
qInfo() << "current dc-firmware-version" << fwVersion;
|
||||
QString const hwVersion = m_hw->dc_getHWversion().toLower();
|
||||
QString const fwVersion = m_hw->dc_getSWversion().toLower();
|
||||
qInfo() << "current dc-hardware-version" << hwVersion;
|
||||
qInfo() << "current dc-firmware-version" << fwVersion;
|
||||
|
||||
QFile fn(name);
|
||||
QFileInfo linkTarget(fn.symLinkTarget());
|
||||
if (!linkTarget.exists()) { // check for broken link
|
||||
res = false;
|
||||
} else {
|
||||
if (false) {
|
||||
//if (fwVersion.startsWith(linkTarget.completeBaseName())) {
|
||||
// qCritical() << "current dc-firmware-version" << fwVersion
|
||||
// << "already installed";
|
||||
// res = false;
|
||||
} else {
|
||||
res = true;
|
||||
|
||||
qCritical() << "downloading" << name.trimmed() << "->"
|
||||
<< linkTarget.completeBaseName() << "to DC";
|
||||
#if UPDATE_DC == 1
|
||||
m_hw->dc_autoRequest(false);// default: turn auto-request setting off
|
||||
QThread::sleep(1); // wait to be sure that there are no more
|
||||
// commands sent to dc-hardware
|
||||
qDebug() << "SET AUTO-REQUEST=FALSE";
|
||||
|
||||
if ((res = updateBinary(name.toStdString().c_str())) == true) {
|
||||
qCritical() << "downloaded binary" << name;
|
||||
}
|
||||
|
||||
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
||||
qDebug() << "SET AUTO-REQUEST=TRUE";
|
||||
qDebug() << "WAIT 10 SECS TO RECEIVE RESPONSES...";
|
||||
|
||||
QThread::sleep(10); // wait to be sure that responses
|
||||
// have been received
|
||||
|
||||
qCritical() << "updated dc-hardware-version" << m_hw->dc_getHWversion();
|
||||
qCritical() << "updated dc-firmware-version" << m_hw->dc_getSWversion();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (name.contains("DC2C_print", Qt::CaseInsensitive)
|
||||
&& name.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_PRINTER_TEMPLATES == 1
|
||||
int i = name.indexOf("DC2C_print", Qt::CaseInsensitive);
|
||||
int const templateIdx = name.mid(i).midRef(10, 2).toInt();
|
||||
if ((templateIdx < 1) || (templateIdx > 32)) {
|
||||
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
|
||||
res = false;
|
||||
} else {
|
||||
if ((res = updatePrinterTemplate(templateIdx, name))) {
|
||||
qInfo() << "downloaded printer template"<< name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if (name.contains("DC2C_cash", Qt::CaseInsensitive)
|
||||
&& name.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_CASH_TEMPLATE == 1
|
||||
if ((res = updateCashConf(name))) {
|
||||
qInfo() << "downloaded cash template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else if (name.contains("DC2C_conf", Qt::CaseInsensitive)
|
||||
&& name.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_CONF_TEMPLATE == 1
|
||||
if ((res= updateConfig(name))) {
|
||||
qInfo() << "downloaded config template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else if (name.contains("DC2C_device", Qt::CaseInsensitive)
|
||||
&& name.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_DEVICE_TEMPLATE == 1
|
||||
if ((res = updateDeviceConf(name))) {
|
||||
qInfo() << "downloaded device template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
qCritical() << "UNKNOWN JSON FILE NAME" << name;
|
||||
QFile fn(fToWorkOn);
|
||||
QFileInfo linkTarget(fn.symLinkTarget());
|
||||
if (!linkTarget.exists()) { // check for broken link
|
||||
res = false;
|
||||
}
|
||||
} else if (request == "EXECUTE" && name.contains("opkg")) {
|
||||
qInfo() << "starting" << name.trimmed();
|
||||
res = true;
|
||||
#if UPDATE_OPKG == 1
|
||||
QScopedPointer<QProcess> p(new QProcess(this));
|
||||
p->setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
|
||||
connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
|
||||
|
||||
p->start(name.trimmed());
|
||||
|
||||
if (p->waitForStarted(1000)) {
|
||||
if (p->state() == QProcess::ProcessState::Running) {
|
||||
if (p->waitForFinished(100000)) {
|
||||
QString output = p->readAllStandardOutput();
|
||||
QStringList outputLst = split(output, QChar('\n'));
|
||||
for (int line=0; line < outputLst.size(); ++line) {
|
||||
qDebug() << outputLst[line];
|
||||
}
|
||||
if (p->exitStatus() == QProcess::NormalExit) {
|
||||
qInfo() << "EXECUTED" << name
|
||||
<< "with code" << p->exitCode();
|
||||
res = true;
|
||||
} else {
|
||||
qCritical() << "PROCESS" << name << "CRASHED";
|
||||
}
|
||||
} else {
|
||||
qCritical() << "PROCESS" << name << "DID NOT FINISH";
|
||||
}
|
||||
} else {
|
||||
qCritical() << "WRONG PROCESS STATE" << p->state();
|
||||
}
|
||||
} else {
|
||||
qCritical() << "PROCESS" << name << "TIMEOUT AT START";
|
||||
if (false) {
|
||||
//if (fwVersion.startsWith(linkTarget.completeBaseName())) {
|
||||
// qCritical() << "current dc-firmware-version" << fwVersion
|
||||
// << "already installed";
|
||||
// res = false;
|
||||
} else {
|
||||
res = true;
|
||||
|
||||
qCritical() << "downloading" << fToWorkOn.trimmed() << "->"
|
||||
<< linkTarget.completeBaseName() << "to DC";
|
||||
#if UPDATE_DC == 1
|
||||
m_hw->dc_autoRequest(false);// default: turn auto-request setting off
|
||||
QThread::sleep(1); // wait to be sure that there are no more
|
||||
// commands sent to dc-hardware
|
||||
qDebug() << "SET AUTO-REQUEST=FALSE";
|
||||
|
||||
if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
|
||||
qCritical() << "downloaded binary" << fToWorkOn;
|
||||
}
|
||||
|
||||
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
||||
qDebug() << "SET AUTO-REQUEST=TRUE";
|
||||
qDebug() << "WAIT 10 SECS TO RECEIVE RESPONSES...";
|
||||
|
||||
QThread::sleep(10); // wait to be sure that responses
|
||||
// have been received
|
||||
qCritical() << "updated dc-hardware-version" << m_hw->dc_getHWversion();
|
||||
qCritical() << "updated dc-firmware-version" << m_hw->dc_getSWversion();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
|
||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_PRINTER_TEMPLATES == 1
|
||||
int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
|
||||
int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
|
||||
if ((templateIdx < 1) || (templateIdx > 32)) {
|
||||
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
|
||||
res = false;
|
||||
} else {
|
||||
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
|
||||
qInfo() << "downloaded printer template"<< fToWorkOn;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
|
||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_CASH_TEMPLATE == 1
|
||||
if ((res = updateCashConf(name))) {
|
||||
qInfo() << "downloaded cash template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
|
||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_CONF_TEMPLATE == 1
|
||||
if ((res= updateConfig(name))) {
|
||||
qInfo() << "downloaded config template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
|
||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
res = true;
|
||||
#if UPDATE_DEVICE_TEMPLATE == 1
|
||||
if ((res = updateDeviceConf(name))) {
|
||||
qInfo() << "downloaded device template"<< name;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// TODO
|
||||
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
|
||||
res = false;
|
||||
}
|
||||
out << "DONE, " << name << ", "
|
||||
<< QDateTime::currentDateTime().toString(Qt::ISODate) << ", "
|
||||
<< ((res == true) ? "SUCCESS" : "ERROR") << "\n";
|
||||
out.flush();
|
||||
|
||||
} // for (it = openLines.cbegin(); it != openLines.end(); ++it) {
|
||||
|
||||
m_hw->dc_autoRequest(true); // ALWAYS turn autoRequest ON
|
||||
qDebug() << "SET AUTO-REQUEST=TRUE";
|
||||
|
||||
return true;
|
||||
|
||||
// return finishUpdate(linesToWorkOn.size() > 0);
|
||||
}
|
||||
|
||||
bool Update::finishUpdate(bool swapCtrlFiles) {
|
||||
if (swapCtrlFiles) {
|
||||
m_update_ctrl_file.close();
|
||||
m_update_ctrl_file_copy.close();
|
||||
|
||||
//std::ifstream source(m_update_ctrl_file_copy.fileName().toStdString().c_str(), std::ios::binary);
|
||||
//std::ofstream dest(m_update_ctrl_file.fileName().toStdString().c_str(), std::ios::binary);
|
||||
|
||||
//dest << source.rdbuf();
|
||||
//source.close();
|
||||
//dest.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
38
update.h
38
update.h
@ -28,24 +28,12 @@ class Update : public QObject {
|
||||
hwinf *m_hw;
|
||||
char const *m_serialInterface;
|
||||
char const *m_baudrate;
|
||||
QFile m_update_ctrl_file;
|
||||
QFile m_update_ctrl_file_copy;
|
||||
QString m_repositoryPath;
|
||||
QString m_customerId; // customer_281
|
||||
QString m_customerRepository;
|
||||
QString m_customerNrStr;
|
||||
QString m_branchName;
|
||||
QString m_workingDir;
|
||||
bool m_maintenanceMode;
|
||||
bool m_testMode;
|
||||
bool m_executeScriptOnly;
|
||||
bool m_dryRun;
|
||||
//ApismClient m_apismClient;
|
||||
|
||||
bool m_init;
|
||||
|
||||
bool finishUpdate(bool finish);
|
||||
QStringList getLinesToWorkOn();
|
||||
|
||||
bool execUpdateScript();
|
||||
|
||||
public:
|
||||
enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
|
||||
@ -56,29 +44,25 @@ public:
|
||||
|
||||
|
||||
explicit Update(hwinf *hw,
|
||||
QString update_ctrl_file,
|
||||
QString repositoryPath,
|
||||
QString customerId,
|
||||
QString customerRepository,
|
||||
QString customerNrStr,
|
||||
QString branchName,
|
||||
QString workingDir = ".",
|
||||
bool maintenanceMode = false,
|
||||
bool testMode = false,
|
||||
bool executeScriptOnly = false,
|
||||
QString workingDir,
|
||||
bool dryRun = false,
|
||||
QObject *parent = nullptr,
|
||||
char const *serialInterface = SERIAL_PORT,
|
||||
char const *baudrate = "115200");
|
||||
virtual ~Update() override;
|
||||
bool doUpdate();
|
||||
bool doUpdate(QStringList const &linesToWorkOn);
|
||||
|
||||
QString customerId() { return m_customerId; }
|
||||
QString const customerId() const { return m_customerId; }
|
||||
//QString customerId() { return m_customerId; }
|
||||
//QString const customerId() const { return m_customerId; }
|
||||
|
||||
QString branchName() { return m_branchName; }
|
||||
QString const branchName() const { return m_branchName; }
|
||||
|
||||
QString repositoryPath() { return m_repositoryPath; }
|
||||
QString const repositoryPath() const { return m_repositoryPath; }
|
||||
//QString repositoryPath() { return m_repositoryPath; }
|
||||
//QString const repositoryPath() const { return m_repositoryPath; }
|
||||
|
||||
private:
|
||||
static QString jsonType(enum FileTypeJson type);
|
||||
@ -105,8 +89,6 @@ private:
|
||||
bool downloadJson(enum FileTypeJson type, int templateIdx,
|
||||
QString jsFileToSendToDC) const;
|
||||
|
||||
bool executeProcess(QString const &cmd);
|
||||
|
||||
private slots:
|
||||
void readyReadStandardOutput();
|
||||
void readyReadStandardError();
|
||||
|
254
worker.cpp
254
worker.cpp
@ -18,25 +18,67 @@
|
||||
#include "ismas/ismas_client.h"
|
||||
#include "apism/apism_client.h"
|
||||
|
||||
Worker::Worker(hwinf *hw, QString update_ctrl_file, QString repositoryPath,
|
||||
QString customerId, QString branchName, QString workingDirectory, bool maintenanceMode,
|
||||
bool testMode, bool executeScriptOnly, bool dryRun, QObject *parent,
|
||||
char const *serialInterface, char const *baudrate)
|
||||
int Worker::read1stLineOfFile(QString fileName) {
|
||||
QFile f(fileName);
|
||||
if (f.exists()) {
|
||||
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&f);
|
||||
in.setCodec("UTF-8");
|
||||
while(!in.atEnd()) {
|
||||
return in.readLine().toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Worker::Worker(hwinf *hw,
|
||||
int customerNr,
|
||||
int machineNr,
|
||||
int zoneNr,
|
||||
QString branchName,
|
||||
QString workingDirectory,
|
||||
bool maintenanceMode,
|
||||
bool dryRun,
|
||||
QObject *parent,
|
||||
char const *serialInterface,
|
||||
char const *baudrate)
|
||||
: m_workerThread("workerThread")
|
||||
, m_apismClient(0, 0, 0, this) // TODO
|
||||
, m_gc(repositoryPath, customerId, workingDirectory, branchName, this)
|
||||
, m_customerId(customerId)
|
||||
, m_customerNr(customerNr)
|
||||
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
|
||||
, m_machineNr(machineNr)
|
||||
, m_zoneNr(zoneNr)
|
||||
, m_workingDirectory(workingDirectory)
|
||||
, m_branchName(branchName)
|
||||
, m_customerRepository(QDir::cleanPath(m_workingDirectory
|
||||
+ QDir::separator()
|
||||
+ m_customerId))
|
||||
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
|
||||
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
|
||||
, m_maintenanceMode(maintenanceMode)
|
||||
, m_osVersion(getOsVersion())
|
||||
, m_ismasUpdateRequests(ISMAS_UPDATE_REQUESTS)
|
||||
, m_waitForNewUpdates(this) {
|
||||
this->moveToThread(&m_workerThread);
|
||||
//m_apismClient.moveToThread(&m_workerThread);
|
||||
|
||||
QDir::setCurrent(m_workingDirectory);
|
||||
|
||||
qInfo() << "CURRENT TIME ..............." << QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
qInfo() << "OS VERSION ................." << m_osVersion;
|
||||
qInfo() << "CUSTOMER_NR ................" << m_customerNr;
|
||||
qInfo() << "CUSTOMER_NR_STR ............" << m_customerNrStr;
|
||||
qInfo() << "CUSTOMER_REPOSITORY_PATH ..." << QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr);
|
||||
qInfo() << "CUSTOMER_REPOSITORY ........" << m_customerRepository;
|
||||
qInfo() << "MACHINE_NR ................." << m_machineNr;
|
||||
qInfo() << "ZONE_NR ...................." << m_zoneNr;
|
||||
qInfo() << "BRANCH_NAME ................" << m_branchName;
|
||||
qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory;
|
||||
|
||||
QProcess p;
|
||||
p.start("/bin/systemctl", {"restart", "apism"});
|
||||
if (!p.waitForStarted(5000) || !p.waitForFinished(5000)) {
|
||||
qCritical() << "APISM-RESTART-FAILURE";
|
||||
return;
|
||||
}
|
||||
|
||||
this->moveToThread(&m_workerThread);
|
||||
m_workerThread.start();
|
||||
|
||||
int cnt = 0;
|
||||
@ -48,18 +90,8 @@ Worker::Worker(hwinf *hw, QString update_ctrl_file, QString repositoryPath,
|
||||
QThread::sleep(1);
|
||||
}
|
||||
|
||||
m_update = new Update(hw, update_ctrl_file, repositoryPath, customerId,
|
||||
branchName, workingDirectory,
|
||||
maintenanceMode, testMode, executeScriptOnly, dryRun,
|
||||
parent, serialInterface, baudrate);
|
||||
|
||||
connect(&m_apismClient, SIGNAL(ismasResponseAvailable(QJsonObject)), this,
|
||||
SLOT(onIsmasResponseReceived(QJsonObject)));
|
||||
|
||||
connect(this, SIGNAL(executeOpkgCommands(QStringList)), this,
|
||||
SLOT(onExecuteOpkgCommands(QStringList)), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(executeOpkgCommand(QString)), this,
|
||||
SLOT(onExecuteOpkgCommand(QString)), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(summarizeRepositoryStatus()), this,
|
||||
SLOT(onSummarizeRepositoryStatus()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(sendCmdSendVersionToIsmas()), this,
|
||||
@ -73,16 +105,24 @@ Worker::Worker(hwinf *hw, QString update_ctrl_file, QString repositoryPath,
|
||||
connect(this, SIGNAL(terminateUpdateProcess()), this,
|
||||
SLOT(onTerminateUpdateProcess()), Qt::QueuedConnection);
|
||||
|
||||
//connect(this, SIGNAL(workNow()), this, SLOT(work()), Qt::QueuedConnection);
|
||||
connect(&m_startUpdateProcess, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
||||
m_startUpdateProcess.setSingleShot(true);
|
||||
m_startUpdateProcess.start(1000);
|
||||
QDir customerRepository(m_customerRepository);
|
||||
if (!customerRepository.exists()) {
|
||||
if (m_gc.gitCloneAndCheckoutBranch()) {
|
||||
// do nothing else, not even executing opkg-commands
|
||||
onFinishUpdateProcess(false);
|
||||
}
|
||||
} else {
|
||||
m_update = new Update(hw, m_customerRepository, m_customerNrStr,
|
||||
m_branchName, m_workingDirectory,
|
||||
dryRun, parent, serialInterface, baudrate);
|
||||
|
||||
connect(&m_waitForNewUpdates, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
||||
m_waitForNewUpdates.setSingleShot(false);
|
||||
connect(&m_startUpdateProcess, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
||||
m_startUpdateProcess.setSingleShot(true);
|
||||
m_startUpdateProcess.start(1000);
|
||||
|
||||
m_machineNr = 996;
|
||||
m_customerNr = 281;
|
||||
connect(&m_waitForNewUpdates, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
||||
m_waitForNewUpdates.setSingleShot(false);
|
||||
}
|
||||
}
|
||||
|
||||
Worker::~Worker() {
|
||||
@ -101,39 +141,81 @@ Worker::~Worker() {
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
void Worker::onHandleChangedFiles(QStringList changedFiles) {
|
||||
qCritical() << QDir::currentPath() << "ON HANDLE CHANGED FILES" << changedFiles;
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
if (QDir::setCurrent(m_customerRepository)) {
|
||||
QString const params("--recursive "
|
||||
"--progress "
|
||||
"--checksum "
|
||||
"--exclude=.* "
|
||||
"--include=*.bin "
|
||||
"--include=*.json "
|
||||
"--include=opkg_commands "
|
||||
"--include=*.ini");
|
||||
QStringList cmds;
|
||||
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
|
||||
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
|
||||
|
||||
QString cmd;
|
||||
bool error = false;
|
||||
foreach (cmd, cmds) {
|
||||
if (!error) {
|
||||
Command c("bash");
|
||||
qInfo() << "EXCUTING CMD..." << cmd;
|
||||
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
|
||||
qDebug() << c.getCommandResult();
|
||||
} else {
|
||||
qCritical() << "CMD" << cmd << "FAILED";
|
||||
error = true;
|
||||
}
|
||||
QString opkg_commands;
|
||||
static const QRegularExpression re("^.*opkg_commands\\s*$");
|
||||
static const QRegularExpression comment("^\\s*#.*$");
|
||||
int idx = changedFiles.indexOf(re);
|
||||
if (idx != -1) {
|
||||
m_updateStatus = UPDATE_STATUS::EXEC_OPKG_COMMANDS_REQUEST;
|
||||
m_statusDescription = "EXECUTE OPKG COMMANDS";
|
||||
|
||||
opkg_commands = changedFiles.takeAt(idx);
|
||||
|
||||
QFile f(opkg_commands);
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
QTextStream in(&f);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
if (line.indexOf(comment, 0) == -1) {
|
||||
// found opkg command
|
||||
QString opkgCommand = line.trimmed();
|
||||
executeOpkgCommand(opkgCommand);
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
onFinishUpdateProcess(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// m_updateStatus = UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS;
|
||||
// m_statusDescription = QString("EXECUTE OPKG COMMANDS %1 OK").arg(opkgCommands.join('\n'));
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
if (m_update->doUpdate(changedFiles)) { // first update the hardware
|
||||
// then sync the file-system
|
||||
if (QDir(m_customerRepository).exists()) {
|
||||
if (QDir::setCurrent(m_customerRepository)) {
|
||||
QString const params("--recursive "
|
||||
"--progress "
|
||||
"--checksum "
|
||||
"--exclude=.* "
|
||||
"--include=*.bin "
|
||||
"--include=*.json "
|
||||
"--include=opkg_commands "
|
||||
"--include=*.ini");
|
||||
QStringList cmds;
|
||||
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
|
||||
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
|
||||
|
||||
QString cmd;
|
||||
bool error = false;
|
||||
foreach (cmd, cmds) {
|
||||
if (!error) {
|
||||
Command c("bash");
|
||||
qInfo() << "EXCUTING CMD..." << cmd;
|
||||
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
|
||||
qDebug() << c.getCommandResult();
|
||||
} else {
|
||||
qCritical() << "CMD" << cmd << "FAILED";
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
onFinishUpdateProcess(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,24 +273,22 @@ void Worker::onSummarizeRepositoryStatus() {
|
||||
*/
|
||||
}
|
||||
|
||||
void Worker::onExecuteOpkgCommands(QStringList opkgCommands) {
|
||||
QString opkgCommand;
|
||||
foreach (opkgCommand, opkgCommands) {
|
||||
emit this->executeOpkgCommand(opkgCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void Worker::onExecuteOpkgCommand(QString opkgCommand) {
|
||||
void Worker::executeOpkgCommand(QString opkgCommand) {
|
||||
Command c(opkgCommand);
|
||||
if (c.execute(m_workingDirectory)) {
|
||||
QString const r = c.getCommandResult();
|
||||
qDebug() << opkgCommand << ": RESULT" << r;
|
||||
m_updateStatus = UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS;
|
||||
m_statusDescription = QString("EXECUTE OPKG COMMAND %1 OK").arg(opkgCommand);
|
||||
} else {
|
||||
m_updateStatus = UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE;
|
||||
m_statusDescription = QString("EXECUTE OPKG COMMAND %1 FAILED").arg(opkgCommand);
|
||||
onTerminateUpdateProcess();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// sollte ParameterResponse heissen
|
||||
void Worker::onIsmasResponseReceived(QJsonObject ismasResponse) {
|
||||
|
||||
if (!ismasResponse.isEmpty()) {
|
||||
QStringList const keys = ismasResponse.keys();
|
||||
static QRegularExpression re("^REQ_ISMASPARAMETER.*");
|
||||
@ -225,32 +305,44 @@ void Worker::onIsmasResponseReceived(QJsonObject ismasResponse) {
|
||||
int customerNr = c.toInt(-1);
|
||||
int machineNr = m.toInt(-1);
|
||||
if (customerNr != m_customerNr) {
|
||||
qCritical() << "CUSTOMER-NR (" << customerNr << ") !="
|
||||
<< "LOCAL CUSTOMER-NR (" << m_customerNr << ")";
|
||||
m_updateStatus = UPDATE_STATUS::ERROR_BACKEND;
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
||||
m_statusDescription
|
||||
= QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)")
|
||||
.arg(customerNr).arg(m_customerNr);
|
||||
return;
|
||||
}
|
||||
if (machineNr != m_machineNr) {
|
||||
qCritical() << "MACHINE-NR (" << machineNr << ") !="
|
||||
<< "LOCAL MACHINE-NR (" << m_machineNr << ")";
|
||||
m_updateStatus = UPDATE_STATUS::ERROR_BACKEND;
|
||||
m_statusDescription
|
||||
= QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)")
|
||||
.arg(machineNr).arg(m_machineNr);
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: check if zone_nr is correct
|
||||
|
||||
if (keys.contains("Fileupload", Qt::CaseInsensitive)) {
|
||||
QJsonObject fileUpload = ismasResponse["Fileupload"].toObject();
|
||||
QJsonValue v = fileUpload.value("TRG");
|
||||
if (!v.isNull() && !v.isUndefined()) {
|
||||
QString const s = v.toString("");
|
||||
if (s == "WAIT") {
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS;
|
||||
m_ismasUpdateRequests = ISMAS_UPDATE_REQUESTS;
|
||||
qCritical() << "ISMAS UPDATES AVAILABLE";
|
||||
m_statusDescription = "ISMAS UPDATES AVAILABLE";
|
||||
emit m_gc.ismasUpdatesAvailable();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
||||
m_statusDescription = "NO FILEUPLOAD KEY AVAILABLE";
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
||||
m_statusDescription = "NO ISMAS RESPONSE AVAILABLE (EMPTY)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,7 +366,7 @@ void Worker::onSendCmdSendVersionToIsmas() {
|
||||
int tariffZone = 1;
|
||||
QString const tariffInfo = "test_tariff_info";
|
||||
QString const tariffLoadTime = QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||
QString const linuxVersion = "test_linux_version";
|
||||
// QString const linuxVersion = "test_linux_version";
|
||||
QString const cpuSerial = "test_cpu_serial";
|
||||
QString const deviceControllerVersion = "test_dc_version";
|
||||
QString const deviceControllerGitBlob = "test_dc_blob_2a3b4f50";
|
||||
@ -296,7 +388,7 @@ void Worker::onSendCmdSendVersionToIsmas() {
|
||||
tariffZone,
|
||||
tariffInfo,
|
||||
tariffLoadTime,
|
||||
linuxVersion,
|
||||
m_osVersion,
|
||||
cpuSerial,
|
||||
deviceControllerVersion,
|
||||
deviceControllerGitBlob,
|
||||
@ -317,17 +409,19 @@ void Worker::onSendCmdSendVersionToIsmas() {
|
||||
|
||||
void Worker::askIsmasForNewData() {
|
||||
if (m_maintenanceMode) {
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_EMULATE_DATA_AVAILABLE;
|
||||
QString data = m_ismasClient.setUpdatesAvailable();
|
||||
m_apismClient.sendUpdateInfoToIsmas(data);
|
||||
m_apismClient.emulateUpdatesAvailable(data);
|
||||
}
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING;
|
||||
m_apismClient.requestAvailableIsmasUpdates();
|
||||
|
||||
if (--m_ismasUpdateRequests > 0) {
|
||||
// if the timer is already running, it will be stopped and restarted.
|
||||
m_waitForNewUpdates.start(10000);
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING;
|
||||
} else {
|
||||
qCritical() << "REQUESTING ISMAS FOR UPDATES TIMED OUT";
|
||||
m_workerThread.quit();
|
||||
QApplication::quit();
|
||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_TIMEOUT;
|
||||
onTerminateUpdateProcess();
|
||||
}
|
||||
}
|
||||
|
72
worker.h
72
worker.h
@ -22,6 +22,43 @@
|
||||
#endif
|
||||
|
||||
|
||||
enum class UPDATE_STATUS : quint8 {
|
||||
ISMAS_EMULATE_DATA_AVAILABLE,
|
||||
ISMAS_UPDATE_REQUEST_PENDING,
|
||||
ISMAS_UPDATE_REQUEST_FAILURE,
|
||||
ISMAS_UPDATE_REQUEST_TIMEOUT,
|
||||
ISMAS_UPDATE_REQUEST_SUCCESS,
|
||||
GIT_CHECKOUT_BRANCH_REQUEST,
|
||||
GIT_CHECKOUT_BRANCH_REQUEST_FAILURE,
|
||||
GIT_CHECKOUT_BRANCH_NOT_EXISTS,
|
||||
GIT_CHECKOUT_BRANCH_CHECKOUT_ERROR,
|
||||
GIT_FETCH_UPDATES_REQUEST,
|
||||
GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
||||
GIT_FETCH_UPDATES_REQUEST_SSUCCESS,
|
||||
EXEC_OPKG_COMMANDS_REQUEST,
|
||||
EXEC_OPKG_COMMANDS_FAILURE,
|
||||
EXEC_OPKG_COMMAND_FAILURE,
|
||||
EXEC_OPKG_COMMAND_SUCCESS,
|
||||
EXEC_OPKG_COMMANDS_SUCCESS,
|
||||
RSYNC_UPDATES,
|
||||
RSYNC_UPDATES_FAILURE,
|
||||
RSYNC_UPDATES_SUCESS,
|
||||
DEVICE_CONTROLLER_UPDATE,
|
||||
DEVICE_CONTROLLER_UPDATE_FAILURE,
|
||||
DEVICE_CONTROLLER_UPDATE_SUCCESS,
|
||||
JSON_UPDATE,
|
||||
JSON_UPDATE_FAILURE,
|
||||
JSON_UPDATE_SUCCESS,
|
||||
ISMAS_UPDATE_INFO_CONFIRM,
|
||||
ISMAS_UPDATE_INFO_CONFIRM_FAILURE,
|
||||
ISMAS_UPDATE_INFO_CONFIRM_SUCCESS,
|
||||
ISMAS_CURRENT_PSA_STATUS_CONFIRM,
|
||||
ISMAS_CURRENT_PSA_STATUS_CONFIRM_FAILURE,
|
||||
ISMAS_CURRENT_PSA_STATUS_CONFIRM_SUCCESS
|
||||
};
|
||||
|
||||
#define ISMAS_UPDATE_REQUESTS (6)
|
||||
|
||||
class hwinf;
|
||||
class Worker : public QObject {
|
||||
Q_OBJECT
|
||||
@ -30,38 +67,35 @@ class Worker : public QObject {
|
||||
QTimer m_startUpdateProcess;
|
||||
Update *m_update;
|
||||
ApismClient m_apismClient;
|
||||
GitClient m_gc;
|
||||
QString const m_customerId;
|
||||
int const m_customerNr;
|
||||
QString const m_customerNrStr;
|
||||
int const m_machineNr;
|
||||
int const m_zoneNr;
|
||||
QString const m_workingDirectory;
|
||||
QString const m_branchName;
|
||||
QString const m_customerRepository;
|
||||
GitClient m_gc;
|
||||
bool m_maintenanceMode;
|
||||
QString const m_osVersion;
|
||||
int m_ismasUpdateRequests;
|
||||
QTimer m_waitForNewUpdates;
|
||||
IsmasClient m_ismasClient;
|
||||
|
||||
int m_machineNr; // setzen
|
||||
int m_customerNr;
|
||||
UPDATE_STATUS m_updateStatus;
|
||||
QString m_statusDescription;
|
||||
|
||||
|
||||
enum { ISMAS_UPDATE_REQUESTS = 6 };
|
||||
|
||||
enum class UPDATE_STATUS : quint8 {
|
||||
STARTED,
|
||||
STOPPED,
|
||||
ERROR_BACKEND
|
||||
} m_updateStatus;
|
||||
void executeOpkgCommand(QString opkgCommand);
|
||||
QString getOsVersion() const;
|
||||
|
||||
public:
|
||||
explicit Worker(hwinf *hw,
|
||||
QString update_ctrl_file,
|
||||
QString repositoryPath,
|
||||
QString customerId,
|
||||
int customerNr, // 281
|
||||
int machineNr,
|
||||
int zoneNr,
|
||||
QString branchName,
|
||||
QString workingDir = ".",
|
||||
bool maintenanceMode = false,
|
||||
bool testMode = false,
|
||||
bool executeScriptOnly = false,
|
||||
bool dryRun = false,
|
||||
QObject *parent = nullptr,
|
||||
char const *serialInterface = SERIAL_PORT,
|
||||
@ -69,9 +103,9 @@ public:
|
||||
~Worker();
|
||||
void quit() { return m_workerThread.quit(); }
|
||||
|
||||
static int read1stLineOfFile(QString fileName);
|
||||
|
||||
signals:
|
||||
void executeOpkgCommands(QStringList);
|
||||
void executeOpkgCommand(QString);
|
||||
void handleChangedFiles(QStringList);
|
||||
void summarizeUpload(QStringList);
|
||||
void summarizeRepositoryStatus();
|
||||
@ -81,8 +115,6 @@ signals:
|
||||
|
||||
public slots:
|
||||
void onIsmasResponseReceived(QJsonObject ismasResponse);
|
||||
void onExecuteOpkgCommands(QStringList opkgCommands);
|
||||
void onExecuteOpkgCommand(QString opkgCommand);
|
||||
|
||||
private slots:
|
||||
void askIsmasForNewData();
|
||||
|
Loading…
x
Reference in New Issue
Block a user