Removed usage of any files. Removed any dependencies on git-hooks.

Removed handling of opkg-related things: they are done now inside the worker itself.
This commit is contained in:
Gerhard Hoffmann 2023-07-17 16:45:11 +02:00
parent c503750e90
commit 43f5f3ecae
2 changed files with 117 additions and 374 deletions

View File

@ -22,11 +22,6 @@
#include <QPluginLoader> #include <QPluginLoader>
#include <QMap> #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_OPKG (1)
#define UPDATE_DC (1) #define UPDATE_DC (1)
#define UPDATE_PRINTER_TEMPLATES (1) #define UPDATE_PRINTER_TEMPLATES (1)
@ -80,14 +75,10 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
} }
Update::Update(hwinf *hw, Update::Update(hwinf *hw,
QString update_ctrl_file, QString customerRepository,
QString repositoryPath, QString customerNrStr,
QString customerId,
QString branchName, QString branchName,
QString workingDir, QString workingDir,
bool maintenanceMode,
bool testMode,
bool executeScriptOnly,
bool dryRun, bool dryRun,
QObject *parent, QObject *parent,
char const *serialInterface, char const *serialInterface,
@ -96,118 +87,14 @@ Update::Update(hwinf *hw,
, m_hw(hw) , m_hw(hw)
, m_serialInterface(serialInterface) , m_serialInterface(serialInterface)
, m_baudrate(baudrate) , m_baudrate(baudrate)
, m_update_ctrl_file(update_ctrl_file) , m_customerRepository(customerRepository)
, m_update_ctrl_file_copy(update_ctrl_file + ".copy") , m_customerNrStr(customerNrStr)
, m_repositoryPath(repositoryPath)
, m_customerId(customerId)
, m_branchName(branchName) , m_branchName(branchName)
, m_workingDir(workingDir) , m_workingDir(workingDir)
, m_maintenanceMode(maintenanceMode) , m_dryRun(dryRun) {
, 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();
}
}
}
} }
Update::~Update() { 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 { Update::DownloadResult Update::sendStatus(int ret) const {
@ -589,22 +476,6 @@ bool Update::updateDeviceConf(QString jsFile) {
return downloadJson(FileTypeJson::DEVICE, 0, 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 Update::split(QString line, QChar sep) {
QStringList lst; QStringList lst;
QString next; QString next;
@ -639,76 +510,21 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError())); disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
} }
// bool Update::executeProcess(QString const &cmd); bool Update::doUpdate(QStringList const &filesToWorkOn) {
bool Update::doUpdate() {
// //
// ACHTUNG !!! // ACHTUNG !!!
// //
return true; 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 serialOpened = false;
bool serialOpen = false; bool serialOpen = false;
QStringList linesToWorkOn = getLinesToWorkOn(); if (filesToWorkOn.size() == 0) {
if (linesToWorkOn.size() == 0) { qCritical() << "NOTHING TO UPDATE";
qCritical() << "No lines to handle in" << m_update_ctrl_file.fileName();
return true; return true;
} }
qDebug() << "open lines...";
for (int i=0; i< linesToWorkOn.size(); ++i) {
qDebug() << "line" << i << ":" << linesToWorkOn.at(i).trimmed();
}
QList<QString>::const_iterator it;
for (it = linesToWorkOn.cbegin(); it != linesToWorkOn.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];
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 (!serialOpen) {
if (!isSerialOpen()) { // open serial only if not already open if (!isSerialOpen()) { // open serial only if not already open
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) { if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) {
@ -721,8 +537,15 @@ bool Update::doUpdate() {
qCritical() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")"; qCritical() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")";
} }
if (name.contains("dc2c", Qt::CaseInsensitive) && QList<QString>::const_iterator it;
name.endsWith(".bin", Qt::CaseInsensitive)) { for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
bool res = false;
QString fToWorkOn = (*it).trimmed();
if (fToWorkOn.contains("dc2c", Qt::CaseInsensitive) &&
fToWorkOn.endsWith(".bin", Qt::CaseInsensitive)) {
qDebug() << "sending sw/hw-requests..."; qDebug() << "sending sw/hw-requests...";
for (int i=0; i < 3; ++i) { // send explicit reuests to get for (int i=0; i < 3; ++i) { // send explicit reuests to get
// current SW/HW-versions // current SW/HW-versions
@ -730,12 +553,13 @@ bool Update::doUpdate() {
m_hw->request_DC2_HWversion(); m_hw->request_DC2_HWversion();
QThread::sleep(1); QThread::sleep(1);
} }
QString const hwVersion = m_hw->dc_getHWversion().toLower(); QString const hwVersion = m_hw->dc_getHWversion().toLower();
QString const fwVersion = m_hw->dc_getSWversion().toLower(); QString const fwVersion = m_hw->dc_getSWversion().toLower();
qInfo() << "current dc-hardware-version" << hwVersion; qInfo() << "current dc-hardware-version" << hwVersion;
qInfo() << "current dc-firmware-version" << fwVersion; qInfo() << "current dc-firmware-version" << fwVersion;
QFile fn(name); QFile fn(fToWorkOn);
QFileInfo linkTarget(fn.symLinkTarget()); QFileInfo linkTarget(fn.symLinkTarget());
if (!linkTarget.exists()) { // check for broken link if (!linkTarget.exists()) { // check for broken link
res = false; res = false;
@ -748,7 +572,7 @@ bool Update::doUpdate() {
} else { } else {
res = true; res = true;
qCritical() << "downloading" << name.trimmed() << "->" qCritical() << "downloading" << fToWorkOn.trimmed() << "->"
<< linkTarget.completeBaseName() << "to DC"; << linkTarget.completeBaseName() << "to DC";
#if UPDATE_DC == 1 #if UPDATE_DC == 1
m_hw->dc_autoRequest(false);// default: turn auto-request setting off m_hw->dc_autoRequest(false);// default: turn auto-request setting off
@ -756,8 +580,8 @@ bool Update::doUpdate() {
// commands sent to dc-hardware // commands sent to dc-hardware
qDebug() << "SET AUTO-REQUEST=FALSE"; qDebug() << "SET AUTO-REQUEST=FALSE";
if ((res = updateBinary(name.toStdString().c_str())) == true) { if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
qCritical() << "downloaded binary" << name; qCritical() << "downloaded binary" << fToWorkOn;
} }
m_hw->dc_autoRequest(true); // turn auto-request setting on m_hw->dc_autoRequest(true); // turn auto-request setting on
@ -766,45 +590,44 @@ bool Update::doUpdate() {
QThread::sleep(10); // wait to be sure that responses QThread::sleep(10); // wait to be sure that responses
// have been received // have been received
qCritical() << "updated dc-hardware-version" << m_hw->dc_getHWversion(); qCritical() << "updated dc-hardware-version" << m_hw->dc_getHWversion();
qCritical() << "updated dc-firmware-version" << m_hw->dc_getSWversion(); qCritical() << "updated dc-firmware-version" << m_hw->dc_getSWversion();
#endif #endif
} }
} }
} else if (name.contains("DC2C_print", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
&& name.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
#if UPDATE_PRINTER_TEMPLATES == 1 #if UPDATE_PRINTER_TEMPLATES == 1
int i = name.indexOf("DC2C_print", Qt::CaseInsensitive); int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
int const templateIdx = name.mid(i).midRef(10, 2).toInt(); int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
if ((templateIdx < 1) || (templateIdx > 32)) { if ((templateIdx < 1) || (templateIdx > 32)) {
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx; qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
res = false; res = false;
} else { } else {
if ((res = updatePrinterTemplate(templateIdx, name))) { if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
qInfo() << "downloaded printer template"<< name; qInfo() << "downloaded printer template"<< fToWorkOn;
} }
} }
#endif #endif
} else if (name.contains("DC2C_cash", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& name.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
#if UPDATE_CASH_TEMPLATE == 1 #if UPDATE_CASH_TEMPLATE == 1
if ((res = updateCashConf(name))) { if ((res = updateCashConf(name))) {
qInfo() << "downloaded cash template"<< name; qInfo() << "downloaded cash template"<< name;
} }
#endif #endif
} else if (name.contains("DC2C_conf", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& name.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
#if UPDATE_CONF_TEMPLATE == 1 #if UPDATE_CONF_TEMPLATE == 1
if ((res= updateConfig(name))) { if ((res= updateConfig(name))) {
qInfo() << "downloaded config template"<< name; qInfo() << "downloaded config template"<< name;
} }
#endif #endif
} else if (name.contains("DC2C_device", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& name.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
#if UPDATE_DEVICE_TEMPLATE == 1 #if UPDATE_DEVICE_TEMPLATE == 1
if ((res = updateDeviceConf(name))) { if ((res = updateDeviceConf(name))) {
@ -812,75 +635,13 @@ bool Update::doUpdate() {
} }
#endif #endif
} else { } else {
qCritical() << "UNKNOWN JSON FILE NAME" << name; qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false; 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";
}
#endif
} else {
// TODO
}
out << "DONE, " << name << ", "
<< QDateTime::currentDateTime().toString(Qt::ISODate) << ", "
<< ((res == true) ? "SUCCESS" : "ERROR") << "\n";
out.flush();
} // for (it = openLines.cbegin(); it != openLines.end(); ++it) { } // for (it = openLines.cbegin(); it != openLines.end(); ++it) {
m_hw->dc_autoRequest(true); // ALWAYS turn autoRequest ON m_hw->dc_autoRequest(true); // ALWAYS turn autoRequest ON
qDebug() << "SET AUTO-REQUEST=TRUE"; qDebug() << "SET AUTO-REQUEST=TRUE";
return 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;
} }

View File

@ -28,24 +28,12 @@ class Update : public QObject {
hwinf *m_hw; hwinf *m_hw;
char const *m_serialInterface; char const *m_serialInterface;
char const *m_baudrate; char const *m_baudrate;
QFile m_update_ctrl_file; QString m_customerRepository;
QFile m_update_ctrl_file_copy; QString m_customerNrStr;
QString m_repositoryPath;
QString m_customerId; // customer_281
QString m_branchName; QString m_branchName;
QString m_workingDir; QString m_workingDir;
bool m_maintenanceMode; bool m_maintenanceMode;
bool m_testMode;
bool m_executeScriptOnly;
bool m_dryRun; bool m_dryRun;
//ApismClient m_apismClient;
bool m_init;
bool finishUpdate(bool finish);
QStringList getLinesToWorkOn();
bool execUpdateScript();
public: public:
enum class DownloadResult {OK, ERROR, TIMEOUT, NOP}; enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
@ -56,29 +44,25 @@ public:
explicit Update(hwinf *hw, explicit Update(hwinf *hw,
QString update_ctrl_file, QString customerRepository,
QString repositoryPath, QString customerNrStr,
QString customerId,
QString branchName, QString branchName,
QString workingDir = ".", QString workingDir,
bool maintenanceMode = false,
bool testMode = false,
bool executeScriptOnly = false,
bool dryRun = false, bool dryRun = false,
QObject *parent = nullptr, QObject *parent = nullptr,
char const *serialInterface = SERIAL_PORT, char const *serialInterface = SERIAL_PORT,
char const *baudrate = "115200"); char const *baudrate = "115200");
virtual ~Update() override; virtual ~Update() override;
bool doUpdate(); bool doUpdate(QStringList const &linesToWorkOn);
QString customerId() { return m_customerId; } //QString customerId() { return m_customerId; }
QString const customerId() const { return m_customerId; } //QString const customerId() const { return m_customerId; }
QString branchName() { return m_branchName; } QString branchName() { return m_branchName; }
QString const branchName() const { return m_branchName; } QString const branchName() const { return m_branchName; }
QString repositoryPath() { return m_repositoryPath; } //QString repositoryPath() { return m_repositoryPath; }
QString const repositoryPath() const { return m_repositoryPath; } //QString const repositoryPath() const { return m_repositoryPath; }
private: private:
static QString jsonType(enum FileTypeJson type); static QString jsonType(enum FileTypeJson type);
@ -105,8 +89,6 @@ private:
bool downloadJson(enum FileTypeJson type, int templateIdx, bool downloadJson(enum FileTypeJson type, int templateIdx,
QString jsFileToSendToDC) const; QString jsFileToSendToDC) const;
bool executeProcess(QString const &cmd);
private slots: private slots:
void readyReadStandardOutput(); void readyReadStandardOutput();
void readyReadStandardError(); void readyReadStandardError();