diff --git a/headers/backend/linbobackend.h b/headers/backend/linbobackend.h index 595bb17..b47fbc5 100644 --- a/headers/backend/linbobackend.h +++ b/headers/backend/linbobackend.h @@ -40,6 +40,7 @@ using namespace std; class LinboBackend : public QObject { Q_OBJECT + Q_PROPERTY(LinboState state READ getState NOTIFY stateChanged) public: explicit LinboBackend(QObject *parent = nullptr); @@ -49,9 +50,10 @@ public: Partitioning, Starting, Syncing, - Installing + Reinstalling }; + LinboState getState(); LinboConfig* getConfig(); QList getOperatingSystems(); @@ -64,25 +66,40 @@ protected: LinboDiskPartition* read_partition(ifstream* input); void read_globals( ifstream* input, LinboConfig* config ); void saveappend( QStringList& command, const QString& item ); - QStringList mksyncstartcommand(LinboConfig& config, LinboOs& os); - QStringList mksynccommand(LinboConfig& config, LinboOs& os); - QStringList mksyncrcommand(LinboConfig& config, LinboOs& os); QStringList mkpartitioncommand(vector &p); QStringList mkpartitioncommand_noformat(vector &p); QStringList mkcacheinitcommand(LinboConfig& config, vector &os, const QString& type); QStringList mklinboupdatecommand(LinboConfig& config); + void setState(LinboState state); + private: + LinboState state; LinboConfig* config; + QStringList linboCommandCache; QList operatingSystems; QList diskPartitions; QProcess* process; + QString executeCommand(bool waitForFinished); + + template + QString executeCommand(bool waitForFinished, QString argument, const Strings&... arguments) { + // this appends a quoted space in case item is empty and resolves + // problems with linbo_cmd's weird "shift"-usage + if (argument.isEmpty()) + this->linboCommandCache.append(""); + else + this->linboCommandCache.append(argument); + + return executeCommand(waitForFinished, arguments...); + } + void readFromStdout(); void readFromStderr(); - void executeCommand(QStringList commandArgs, bool waitForFinished = true); + QString executeCommand(bool wait, QString command, QStringList commandArgs); public slots: void executeAutostart(); @@ -90,10 +107,11 @@ public slots: void reboot(); bool startOs(LinboOs* os); - //bool syncStartOs(); - //bool reinstallStartOs(); + bool syncOs(LinboOs* os); + bool reinstallOs(LinboOs* os); signals: + void stateChanged(); }; diff --git a/headers/backend/linboos.h b/headers/backend/linboos.h index 4f4a324..24afa7e 100644 --- a/headers/backend/linboos.h +++ b/headers/backend/linboos.h @@ -20,6 +20,7 @@ #define LINBOOS_H #include +#include #include "linboimage.h" @@ -29,6 +30,13 @@ class LinboOs : public QObject public: friend class LinboBackend; + enum LinboOsStartAction { + UnknownAction = -1, + StartOs, + SyncOs, + ReinstallOs + }; + const QString& getName() const {return this->name;} const QString& getDescription() const {return this->description;} const QString& getVersion() const {return this->version;} @@ -45,9 +53,29 @@ public: const bool& getNewbutton() const {return this->newButton;} const bool& getAutostart() const {return this->autostart;} const int& getAutostartTimeout() const {return this->autostartTimeout;} - const QString& getDefaultAction() const {return this->defaultAction;} + const LinboOsStartAction& getDefaultAction() const {return this->defaultAction;} const bool& getHidden() const {return this->hidden;} + bool getActionEnabled(LinboOsStartAction action) { + switch (action) { + case StartOs: return this->getStartbutton(); + case SyncOs: return this->getSyncbutton(); + case ReinstallOs: return this->getNewbutton(); + case UnknownAction: return false; + } + } + + LinboOsStartAction startActionFromString(const QString& name) const { + qDebug() << "default action name is: " << name; + if(name == "start") + return StartOs; + else if(name == "sync") + return SyncOs; + else if(name == "new") + return ReinstallOs; + return UnknownAction; + } + protected: explicit LinboOs(QObject *parent = nullptr); @@ -67,27 +95,27 @@ protected: void setNewButton ( const bool& newButton ) {this->newButton = newButton;} void setAutostart ( const bool& autostart ) {this->autostart = autostart;} void setAutostartTimeout ( const int& autostartTimeout ) {this->autostartTimeout = autostartTimeout;} - void setDefaultAction ( const QString& defaultAction ) {this->defaultAction = defaultAction;} + void setDefaultAction ( const LinboOsStartAction& defaultAction ) {this->defaultAction = defaultAction;} void setHidden ( const bool& hidden ) {this->hidden = hidden;} private: - QString name, // OS Name - version, - description, - iconName, // Thumbnail for Image - rootPartition, // Root partition - bootPartition, // Root partition - image, - kernel, - initrd, - kernelOptions, - defaultAction; -int autostartTimeout; -bool syncButton, startButton, newButton, autostart, -hidden; // show OS tab or not + QString name, // OS Name + version, + description, + iconName, // Thumbnail for Image + rootPartition, // Root partition + bootPartition, // Root partition + image, + kernel, + initrd, + kernelOptions; + int autostartTimeout; + bool syncButton, startButton, newButton, autostart, + hidden; // show OS tab or not + LinboOsStartAction defaultAction; -LinboImage* baseImage; -LinboImage* differentialImage; + LinboImage* baseImage; + LinboImage* differentialImage; }; diff --git a/headers/linbostartactions.h b/headers/linbostartactions.h index c5c320a..8de8fa5 100644 --- a/headers/linbostartactions.h +++ b/headers/linbostartactions.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "linbobackend.h" #include "linboosselectionrow.h" @@ -28,9 +29,10 @@ private: QModernStackedWidget* stackView; QWidget* buttonWidget; - QModernPushButton* defaultActionButton; - QModernPushButton* secondActionButton; - QModernPushButton* thirdActionButton; + QModernPushButton* startOsButton; + QModernPushButton* syncOsButton; + QModernPushButton* reinstallOsButton; + QList actionButtons; QWidget* progressBarWidget; QModernProgressBar* progressBar; @@ -38,9 +40,12 @@ private: void resizeAndPositionAllItems(); private slots: - void startOs(); + void executeStartAction(); + void executeSyncAction(); + void executeReinstallAction(); signals: + void selectedOsChanged(); }; diff --git a/sources/backend/linbobackend.cpp b/sources/backend/linbobackend.cpp index 9154c8d..b82f901 100644 --- a/sources/backend/linbobackend.cpp +++ b/sources/backend/linbobackend.cpp @@ -18,7 +18,7 @@ #include "linbobackend.h" -#define LINBO_CMD(arg) QStringList("linbo_cmd") << (arg); +#define LINBO_CMD(arg) QStringList("linbo_cmd") << (arg) using namespace std; @@ -88,65 +88,33 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) */ // client ip - command = LINBO_CMD("ip"); - // myprocess->setArguments( command ); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setIpAddress(process->readAllStandardOutput()); + this->config->setIpAddress(this->executeCommand(true, "ip")); // mac address - command.clear(); - command = LINBO_CMD("mac"); - - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setMacAddress(process->readAllStandardOutput()); + this->config->setMacAddress(this->executeCommand(true, "mac")); // Version - command = LINBO_CMD("version"); - // myprocess->setArguments( command ); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setVersion(process->readAllStandardOutput().stripWhiteSpace()); + this->config->setVersion(this->executeCommand(true, "version").stripWhiteSpace()); // hostname - command = LINBO_CMD("hostname"); - // myprocess->setArguments( command ); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setHostname(process->readAllStandardOutput()); + this->config->setHostname(this->executeCommand(true, "hostname")); // CPU - command = LINBO_CMD("cpu"); - // myprocess->setArguments( command ); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setCpu(process->readAllStandardOutput()); + this->config->setCpu(this->executeCommand(true, "cpu")); // Memory - command = LINBO_CMD("memory"); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setRamSize(process->readAllStandardOutput()); + this->config->setRamSize(this->executeCommand(true, "memory")); // Cache Size - command = LINBO_CMD("size"); - saveappend( command, this->config->getCache() ); - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setCacheSize(process->readAllStandardOutput()); + this->config->setCacheSize(this->executeCommand(true, "size")); // Harddisk Size QRegExp *removePartition = new QRegExp("[0-9]{1,2}"); QString hd = this->config->getCache(); + // e.g. turn /dev/sda1 into /dev/sda hd.remove( *removePartition ); - command = LINBO_CMD("size"); - saveappend( command, hd ); - - process->start( command.join(" ") ); - while( !process->waitForFinished(10000) ) {} - this->config->setHddSize(process->readAllStandardOutput()); + this->config->setHddSize(this->executeCommand(true, "size", hd)); } // -------------------- @@ -158,36 +126,76 @@ void LinboBackend::executeAutostart() { } void LinboBackend::shutdown() { - QStringList command; - command.clear(); - command = QStringList("busybox"); - command.append("poweroff"); - // TODO logConsole->writeStdOut( QString("shutdown entered") ); - process->start( command.join(" ") ); + this->executeCommand(false, "busybox", QStringList("poweroff")); } void LinboBackend::reboot() { - QStringList command; - command.clear(); - command = QStringList("busybox"); - command.append("reboot"); - // TODO logConsole->writeStdOut( QString("reboot entered") ); - process->start( command.join(" ") ); + this->executeCommand(false, "busybox", QStringList("reboot")); } bool LinboBackend::startOs(LinboOs* os) { - if(os == nullptr) + if(os == nullptr || this->state != Idle) return false; - QStringList command = LINBO_CMD("start"); - saveappend( command, os->getBootPartition() ); - saveappend( command, os->getRootPartition() ); - saveappend( command, os->getKernel() ); - saveappend( command, os->getInitrd() ); - saveappend( command, os->getKernelOptions() ); - saveappend( command, this->config->getCache() ); + this->setState(Starting); - this->executeCommand(command, false); + this->executeCommand( + false, + "start", + os->getBootPartition(), + os->getRootPartition(), + os->getKernel(), + os->getInitrd(), + os->getKernelOptions(), + this->config->getCache() + ); + + return true; +} + +bool LinboBackend::syncOs(LinboOs* os) { + if(os == nullptr || this->state != Idle) + return false; + + this->setState(Syncing); + + this->executeCommand( + false, + "syncstart", + this->config->getServer(), + this->config->getCache(), + os->getBaseImage()->getName(), + os->getDifferentialImage()->getName(), + os->getBootPartition(), + os->getRootPartition(), + os->getKernel(), + os->getInitrd(), + os->getKernelOptions() + ); + + return true; +} + +bool LinboBackend::reinstallOs(LinboOs* os) { + if(os == nullptr || this->state != Idle) + return false; + + this->setState(Reinstalling); + + this->executeCommand( + false, + "syncr", + this->config->getServer(), + this->config->getCache(), + os->getBaseImage()->getName(), + os->getDifferentialImage()->getName(), + os->getBootPartition(), + os->getRootPartition(), + os->getKernel(), + os->getInitrd(), + os->getKernelOptions(), + QString("force") + ); return true; } @@ -205,19 +213,42 @@ QList LinboBackend::getOperatingSystems() { // - Helpers - // ----------- -void LinboBackend::executeCommand(QStringList commandArgs, bool waitForFinished) { +QString LinboBackend::executeCommand(bool waitForFinished) { + QStringList tmpList = this->linboCommandCache; + this->linboCommandCache.clear(); - QString command = commandArgs.takeFirst(); + return this->executeCommand(waitForFinished, "linbo_cmd", tmpList); +} + +QString LinboBackend::executeCommand(bool waitForFinished, QString command, QStringList commandArgs) { + + if(waitForFinished) + // clear old output + this->process->readAll(); qDebug() << "Executing: " << command << " " << commandArgs.join(" "); - return; - process->start(command, commandArgs); process->waitForStarted(); - if(waitForFinished) + if(waitForFinished) { while( !process->waitForFinished(10000) ) {} + return this->process->readAllStandardOutput(); + } + + return ""; +} + +LinboBackend::LinboState LinboBackend::getState() { + return this->state; +} + +void LinboBackend::setState(LinboState state) { + if(this->state == state) + return; + + this->state = state; + emit this->stateChanged(); } void LinboBackend::read_qstring( ifstream* input, QString& tmp ) { @@ -258,6 +289,7 @@ LinboOs* LinboBackend::read_os(ifstream* input) { LinboOs* os = new LinboOs(this); QString key, value; while(!input->eof() && read_pair(input, key, value)) { + qDebug() << key << "=" << value; if(key.compare("name") == 0) os->setName(value); else if(key.compare("description") == 0) os->setDescription(value); else if(key.compare("version") == 0) os->setVersion(value); @@ -272,7 +304,7 @@ LinboOs* LinboBackend::read_os(ifstream* input) { else if(key.compare("syncenabled") == 0) os->setSyncButton(toBool(value)); else if(key.compare("startenabled") == 0) os->setStartButton(toBool(value)); else if((key.compare("remotesyncenabled") == 0) || (key.compare("newenabled") == 0)) os->setNewButton(toBool(value)); - else if(key.compare("defaultaction") == 0) os->setDefaultAction(value); + else if(key.compare("defaultaction") == 0) os->setDefaultAction(os->startActionFromString(value)); else if(key.compare("autostart") == 0) os->setAutostart(toBool(value)); else if(key.compare("autostarttimeout") == 0) os->setAutostartTimeout(value.toInt()); else if(key.compare("hidden") == 0) os->setHidden(toBool(value)); @@ -316,61 +348,6 @@ void LinboBackend::read_globals( ifstream* input, LinboConfig* config ) { } } -// this appends a quoted space in case item is empty and resolves -// problems with linbo_cmd's weird "shift"-usage -void LinboBackend::saveappend( QStringList& command, const QString& item ) { - if ( item.isEmpty() ) - command.append(""); - else - command.append( item ); - -} - -// Sync+start image -QStringList LinboBackend::mksyncstartcommand(LinboConfig& config, LinboOs& os) { - QStringList command = LINBO_CMD("syncstart"); - saveappend( command, config.getServer() ); - saveappend( command, config.getCache() ); - saveappend( command, os.getBaseImage()->getName() ); - saveappend( command, os.getDifferentialImage()->getName() ); - saveappend( command, os.getBootPartition() ); // boot is same as root - saveappend( command, os.getRootPartition() ); - saveappend( command, os.getKernel() ); - saveappend( command, os.getInitrd() ); - saveappend( command, os.getKernelOptions() ); - return command; -} - -// Sync image from cache -QStringList LinboBackend::mksynccommand(LinboConfig& config, LinboOs& os) { - QStringList command = LINBO_CMD("sync"); - saveappend( command, config.getCache() ); - saveappend( command, os.getBaseImage()->getName() ); - saveappend( command, os.getDifferentialImage()->getName() ); - saveappend( command, os.getBootPartition() ); - saveappend( command, os.getRootPartition() ); - saveappend( command, os.getKernel() ); - saveappend( command, os.getInitrd() ); - saveappend( command, os.getKernelOptions() ); - return command; -} - -// Sync image from server -QStringList LinboBackend::mksyncrcommand(LinboConfig& config, LinboOs& os) { - QStringList command = LINBO_CMD("syncr"); - saveappend( command, config.getServer() ); - saveappend( command, config.getCache() ); - saveappend( command, os.getBaseImage()->getName() ); - saveappend( command, os.getDifferentialImage()->getName() ); - saveappend( command, os.getBootPartition() ); - saveappend( command, os.getRootPartition() ); - saveappend( command, os.getKernel() ); - saveappend( command, os.getInitrd() ); - saveappend( command, os.getKernelOptions() ); - saveappend( command, QString("force") ); - return command; -} - QStringList LinboBackend::mkpartitioncommand(vector &p) { QStringList command = LINBO_CMD("partition"); for(unsigned int i=0; i