This repository has been archived on 2022-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
modern-linbo-gui/sources/backend/linbobackend.cpp
Dorian Zedler cacd1f5468
- a few new buttons
- started to implement new backend
2020-11-16 18:01:03 +01:00

416 lines
16 KiB
C++

/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "linbobackend.h"
#define LINBO_CMD(arg) QStringList("linbo_cmd") << (arg);
using namespace std;
LinboBackend::LinboBackend(QObject *parent) : QObject(parent)
{
this->config = new LinboConfig(this);
// read start.conf
qDebug() << "Starting to parse start.conf";
ifstream input;
input.open( "start.conf", ios_base::in );
QString tmp_qstring;
while( !input.eof() ) {
// *** Image description section ***
// entry in start tab
read_qstring(&input, tmp_qstring);
if ( tmp_qstring.startsWith("#") || tmp_qstring.isEmpty() ) continue;
tmp_qstring = tmp_qstring.section("#",0,0).stripWhiteSpace(); // Strip comment
if(tmp_qstring.lower().compare("[os]") == 0) {
LinboOs* tmpOs = read_os(&input);
if(!tmpOs->getName().isEmpty()) {
this->operatingSystems.append(tmpOs);
// check if this is an additional/incremental image for an existing OS
/* TODO unsigned int i; // Being checked later.
for(i = 0; i < elements.size(); i++ ) {
if(tmp_os.get_name().lower().compare(elements[i].get_name().lower()) == 0) {
elements[i].image_history.push_back(tmp_image); break;
}
}
if(i==elements.size()) { // Not included yet -> new image
tmp_os.image_history.push_back(tmp_image);
elements.push_back(tmp_os);
}*/
}
else {
tmpOs->deleteLater();
}
} else if(tmp_qstring.lower().compare("[linbo]") == 0) {
read_globals(&input, config);
} else if(tmp_qstring.lower().compare("[partition]") == 0) {
LinboDiskPartition* tmpPartition = read_partition(&input);
if(!tmpPartition->getPath().isEmpty()) {
diskPartitions.append(tmpPartition);
}
else {
tmpPartition->deleteLater();
}
}
}
input.close();
qDebug() << "Finished parsing start.conf";
qDebug() << "Loading global configuration";
// load global config
QStringList command;
this->process = new QProcess();
// client ip
command = LINBO_CMD("ip");
// myprocess->setArguments( command );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setIpAddress(process->readAllStandardOutput());
// mac address
command.clear();
command = LINBO_CMD("mac");
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setMacAddress(process->readAllStandardOutput());
// Version
command = LINBO_CMD("version");
// myprocess->setArguments( command );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setVersion(process->readAllStandardOutput().stripWhiteSpace());
// hostname
command = LINBO_CMD("hostname");
// myprocess->setArguments( command );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setHostname(process->readAllStandardOutput());
// CPU
command = LINBO_CMD("cpu");
// myprocess->setArguments( command );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setCpu(process->readAllStandardOutput());
// Memory
command = LINBO_CMD("memory");
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setRamSize(process->readAllStandardOutput());
// Cache Size
command = LINBO_CMD("size");
saveappend( command, this->config->getCache() );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setCacheSize(process->readAllStandardOutput());
// Harddisk Size
QRegExp *removePartition = new QRegExp("[0-9]{1,2}");
QString hd = this->config->getCache();
hd.remove( *removePartition );
command = LINBO_CMD("size");
saveappend( command, hd );
process->start( command.join(" ") );
while( !process->waitForFinished(10000) ) {}
this->config->setHddSize(process->readAllStandardOutput());
}
// --------------------
// - Public functions -
// --------------------
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(" ") );
}
void LinboBackend::reboot() {
QStringList command;
command.clear();
command = QStringList("busybox");
command.append("reboot");
// TODO logConsole->writeStdOut( QString("reboot entered") );
process->start( command.join(" ") );
}
bool LinboBackend::startOs(LinboOs* os) {
if(os == nullptr)
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->executeCommand(command, false);
return true;
}
LinboConfig* LinboBackend::getConfig() {
return this->config;
}
QList<LinboOs*> LinboBackend::getOperatingSystems() {
return this->operatingSystems;
}
// -----------
// - Helpers -
// -----------
void LinboBackend::executeCommand(QStringList commandArgs, bool waitForFinished) {
QString command = commandArgs.takeFirst();
qDebug() << "Executing: " << command << " " << commandArgs.join(" ");
process->start(command, commandArgs);
process->waitForStarted();
if(waitForFinished)
while( !process->waitForFinished(10000) ) {}
}
void LinboBackend::read_qstring( ifstream* input, QString& tmp ) {
char line[500];
input->getline(line,500,'\n');
tmp = QString::fromAscii( line, -1 ).stripWhiteSpace();
}
void LinboBackend::read_bool( ifstream* input, bool& tmp) {
char line[500];
input->getline(line,500,'\n');
tmp = atoi( line );
}
// Return true unless beginning of new section '[' is found.
bool LinboBackend::read_pair(ifstream* input, QString& key, QString& value) {
char line[1024];
if(input->peek() == '[') return false; // Next section found.
input->getline(line,1024,'\n');
QString s = QString::fromAscii( line, -1 ).stripWhiteSpace();
key = s.section("=",0,0).stripWhiteSpace().lower();
if(s.startsWith("#")||key.isEmpty()) {
key = QString(""); value = QString("");
} else {
value=s.section("=",1).section("#",0,0).stripWhiteSpace();
}
return true;
}
bool LinboBackend::toBool(const QString& value) {
if(value.startsWith("yes",false)) return true;
if(value.startsWith("true",false)) return true;
if(value.startsWith("enable",false)) return true;
return false;
}
LinboOs* LinboBackend::read_os(ifstream* input) {
LinboOs* os = new LinboOs(this);
QString key, value;
while(!input->eof() && read_pair(input, 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);
else if(key.compare("iconname") == 0) os->setIconName(value);
else if(key.compare("image") == 0) os->setDifferentialImage(new LinboImage(value, os));
else if(key.compare("baseimage") == 0) os->setBaseImage(new LinboImage(value, os));
else if(key.compare("boot") == 0) os->setBootPartition(value);
else if(key.compare("root") == 0) os->setRootPartition(value);
else if(key.compare("kernel") == 0) os->setKernel(value);
else if(key.compare("initrd") == 0) os->setInitrd(value);
else if(key.compare("append") == 0) os->setKernelOptions(value);
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("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));
}
return os;
}
LinboDiskPartition* LinboBackend::read_partition(ifstream* input) {
LinboDiskPartition* partition = new LinboDiskPartition(this);
QString key, value;
while(!input->eof() && read_pair(input, key, value)) {
if(key.compare("dev") == 0) partition->setPath(value);
else if(key.compare("size") == 0) partition->setSize(value.toInt());
else if(key.compare("id") == 0) partition->setId(value);
else if(key.compare("fstype") == 0) partition->setFstype(value);
else if(key.startsWith("bootable", false)) partition->setBootable(toBool(value));
}
return partition;
}
void LinboBackend::read_globals( ifstream* input, LinboConfig* config ) {
QString key, value;
while(!input->eof() && read_pair(input, key, value)) {
if(key.compare("server") == 0) config->setServer(value);
else if(key.compare("cache") == 0) config->setCache(value);
else if(key.compare("roottimeout") == 0) config->setRootTimeout((unsigned int)value.toInt());
else if(key.compare("group") == 0) config->setHostgroup(value);
else if(key.compare("autopartition") == 0) config->setAutopartition(toBool(value));
else if(key.compare("autoinitcache") == 0) config->setAutoInitCache(toBool(value));
else if(key.compare("autoformat") == 0) config->setAutoFormat(toBool(value));
else if(key.compare("backgroundfontcolor") == 0) config->setBackgroundFontcolor(value);
else if(key.compare("consolefontcolorstdout") == 0) config->setConsoleFontcolorStdout(value);
else if(key.compare("consolefontcolorstderr") == 0) config->setConsoleFontcolorStderr(value);
else if(key.compare("usemulticast") == 0) {
if( (unsigned int)value.toInt() == 0 )
config->setDownloadType("rsync");
else
config->setDownloadType("multicast");
}
else if(key.compare("downloadtype") == 0) config->setDownloadType(value);
}
}
// 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 <LinboDiskPartition> &p) {
QStringList command = LINBO_CMD("partition");
for(unsigned int i=0; i<p.size(); i++) {
saveappend( command, p[i].getPath() );
saveappend( command, (QString::number(p[i].getSize())) );
saveappend( command, p[i].getId() );
saveappend( command, (QString((p[i].getBootable())?"bootable":"\" \"")) );
saveappend( command, p[i].getFstype() );
}
return command;
}
QStringList LinboBackend::mkpartitioncommand_noformat(vector <LinboDiskPartition> &p) {
QStringList command = LINBO_CMD("partition_noformat");
for(unsigned int i=0; i<p.size(); i++) {
saveappend( command, p[i].getPath() );
saveappend( command, (QString::number(p[i].getSize())) );
saveappend( command, p[i].getId() );
saveappend( command, (QString((p[i].getBootable())?"bootable":"\" \"")) );
saveappend( command, p[i].getFstype() );
}
return command;
}
// type is 0 for rsync, 1 for multicast, 3 for bittorrent
QStringList LinboBackend::mkcacheinitcommand(LinboConfig& config, vector<LinboOs> &os, const QString& type) {
QStringList command = LINBO_CMD("initcache");
saveappend( command, config.getServer() );
saveappend( command, config.getCache() );
if( ! type.isEmpty() )
command.append(type);
else
command.append("rsync");
for(unsigned int i = 0; i < os.size(); i++) {
saveappend( command, os[i].getBaseImage()->getName() );
/* TODO ?? for(unsigned int j = 0; j < os[i].image_history.size(); j++) {
saveappend( command, os[i].image_history[j].get_image() );
}*/
}
return command;
}
QStringList LinboBackend::mklinboupdatecommand(LinboConfig& config) {
QStringList command = LINBO_CMD("update");
saveappend( command, config.getServer() );
saveappend( command, config.getCache() );
return command;
}