/* * Copyright (c) 2010,2011 - RZ Uni Freiburg * Copyright (c) 2010,2011 - OpenSLX Project * * This program/file is free software distributed under the GPL version 2. * See http://gpl.openslx.org/ * * If you have any feedback please consult http://feedback.openslx.org/ and * send your feedback to feedback@openslx.org * * General information about OpenSLX - libChooser can be found under * http://openslx.org * */ #include #include #include #include #include #include #include #if 0 #include // available since Qt 4.7 #endif #include // for HOST_NAME_MAX #include // for gethostname(), getuid() #include // for getuid, getpwuid #include // for getpwuid //#include "globals.h" #include "VSession.h" #include "VSessionHandler.h" bool VSession::debugMode = false; VSession::VSession(VSessionHandler *parent) { sessionHandler = parent; } bool VSession::init(const QString& xml, const QString& baseDirPath) { this->baseDirPath_ = baseDirPath; _process = new QProcess(); return this->doc_.setContent(xml); } void VSession::addNodeWithAttribute(const QString& nodeName, const QString& value, const QString& attribute, bool replace) { QDomElement node = this->doc_.namedItem("eintrag").namedItem(nodeName).toElement(); if (replace == false || node.isNull()) { // create a new node node = this->doc_.createElement(nodeName); this->doc_.namedItem("eintrag").appendChild(node); } node.setAttribute(attribute, value); } QString VSession::icon() const { QString icon(getAttribute("icon")); if (icon.isEmpty()) { if (imgtype() == VMWARE) icon = "vmware"; else if (imgtype() == VBOX) icon = "virtualbox"; else icon = "unknown"; } else if (icon.contains(".") && QDir::isRelativePath(icon)) { // non-built-in icon with relative path icon.prepend(baseDirPath_ + "/"); } return icon; } QString VSession::screenshot() const { QString ret; ret = getAttribute("screenshot"); // qDebug() << ret; if (ret.size() > 0) { ret.prepend(baseDirPath_ + "/"); ret.prepend("file://"); return ret; } return QString("qrc:/img/noscreenshot"); }; QString VSession::toXml() const { QDomDocument doc; doc.appendChild(doc.createElement("settings")); doc.firstChild().appendChild(doc.importNode(doc_.documentElement(), true)); QDomNode xmlNode = doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\""); doc.insertBefore(xmlNode, doc.firstChild()); return doc.toString(); } QString VSession::getAttribute(const QString &nodeName, const QString &attribute) const { QDomDocument doc = this->doc_; QDomNode n = doc.namedItem("eintrag").namedItem(nodeName); return this->doc_.namedItem("eintrag").namedItem(nodeName).toElement() .attribute(attribute); } QString VSession::getNodeText(const QString& nodeName) const { QString str; QTextStream stream(&str); QDomNode node = this->doc_.namedItem("eintrag").namedItem(nodeName).toElement(); node.save(stream, 4); // return this->doc_.namedItem("eintrag").namedItem(nodeName).toElement().text(); return str; } ImgType VSession::imgtype() const { QString s(getAttribute("virtualmachine")); if (s.compare("vmware") == 0) { return VMWARE; } else if (s.compare("virtualbox") == 0 || s.compare("vbox") == 0) { return VBOX; } else { return OTHER; } } bool VSession::isActive() const { QString value(getAttribute("active")); if (value.compare("false") == 0) { return false; } else if (value.count("/") == 1) { // try to interpret value as date range // [YYYY-MM-DD]/[YYYY-MM-DD] // eg. "1970-01-01/1971-01-01" from Jan 1st 1970 till Jan 1st 1971 // "/1971-01-01" till Jan 1st 1971 // "1970-01-01/" from Jan 1st 1970 // "/" allways // note: invalid dates are treated as empty dates QStringList list(value.split("/")); QString from(list.value(0)); QString till(list.value(1)); QDate fromDate(QDate::fromString(from, Qt::ISODate)); QDate tillDate(QDate::fromString(till, Qt::ISODate)); QDate today(QDate::currentDate()); if (fromDate.isValid() && fromDate > today) { // fromDate is in the future if (debugMode) qDebug() << "Not active. Reason: fromDate is in the future"; return false; } if (tillDate.isValid() && tillDate < today) { // tillDate is in the past if (debugMode) qDebug() << "Not active. Reason: tillDate is in the past"; return false; } } if (sessionHandler->hasEnv()) { QStringList pools = getAttribute("pools").split("\\s*,\\s*"); if (!pools.isEmpty() && !pools.contains(sessionHandler->getEnv())) { // pools does not contain pool if (debugMode) qDebug() << "Not active. Reason: vsession is not part of active env"; return false; } } return true; } bool VSession::isLocked() const { // default to false return getAttribute("locked").compare("true") == 0; } bool VSession::isValid() const { // default to false return QFile::exists(QString(this->baseDirPath_).append("/").append(getAttribute("image_name"))); } int VSession::priority() const { return getAttribute("priority").toInt(); } void VSession::addPrinters(const QString& script, const QString& type) { QDomElement printersNode = this->doc_.namedItem("eintrag").namedItem(type + "s").toElement(); if (printersNode.isNull()) { // create new printers node printersNode = this->doc_.createElement(type + "s"); this->doc_.namedItem("eintrag").appendChild(printersNode); } QProcess addPrintersScript; addPrintersScript.start(script, QIODevice::ReadOnly); while (!addPrintersScript.atEnd()) { QString line(addPrintersScript.readLine()); QStringList tokens(line.split("\t")); if (tokens.size() < 2 or tokens.size() > 3) { // TODO error message // invalid output of printerScript // printserver\tprinter\tprinter description continue; } QDomElement printerNode(doc_.createElement(type)); printerNode.setAttribute("name", tokens.at(1)); printerNode.setAttribute("path", "\\\\" + tokens.at(0) + "\\" + tokens.at(1)); if (tokens.size() == 3) { QDomText printerDescriptionNode(doc_.createTextNode(tokens.at(3))); printerNode.appendChild(printerDescriptionNode); } printersNode.appendChild(printerNode); } addPrintersScript.close(); return; } void VSession::addScanners(const QString& script) { addPrinters(script, "scanner"); } void VSession::addUserAndHostname() { QString username(getpwuid(geteuid())->pw_name); this->addNodeWithAttribute("username", username); // Qt >= 4.7 has // QString hostname(QHostInfo::localHostName()); char hname[255]; gethostname(hname, sizeof(hname)); QString hostname(hname); this->addNodeWithAttribute("hostname", hostname); QString image(this->getAttribute("image_name")); if (QFileInfo(image).isRelative()) { // make path to image absolute this->addNodeWithAttribute("image_name", this->baseDirPath_ + "/" + image); } // insert computername as the first child of // bootpgm needs computername within the first 500 bytes QDomElement computername(doc_.createElement("computername")); computername.setAttribute("param", hostname); this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); } void VSession::mergePoolXml() { QDomDocument doc; QString poolXmlFile = sessionHandler->getConfPath() + "/vmchooser-" + sessionHandler->getEnv() + ".xml"; QFile file(poolXmlFile); if (!file.open(QIODevice::ReadOnly)) { return; } if (!doc.setContent(&file)) { file.close(); return; } file.close(); for (QDomElement envNode(doc.firstChildElement("environment")); !envNode.isNull(); envNode = envNode.nextSiblingElement()) { if (envNode.attribute("param") != sessionHandler->getEnv()) continue; for (QDomElement typeNode(envNode.firstChildElement()); !typeNode.isNull(); typeNode = typeNode.nextSiblingElement()) { QString type = typeNode.nodeName(); if (type != "shared_folders" && type != "printers" && type != "scanners") continue; QDomElement destinationNode = this->doc_.namedItem("eintrag").namedItem(type).toElement(); if (destinationNode.isNull()) { // create new node destinationNode = this->doc_.createElement(type); this->doc_.namedItem("eintrag").appendChild(destinationNode); } for (QDomElement el(typeNode.firstChildElement()); !el.isNull(); el = el.nextSiblingElement()) { destinationNode.appendChild(this->doc_.importNode(el, true)); } } } } bool VSession::run() const { QString command = getAttribute("command"); if (!command.isEmpty()) { return QProcess::startDetached(command); } VSession session = *this; session.addPrinters(sessionHandler->getPrinterScript()); session.addScanners(sessionHandler->getScannerScript()); session.addUserAndHostname(); session.mergePoolXml(); // write xml to temporary file QTemporaryFile tmpfile(QDir::tempPath() + "/vmchooser-XXXXXX.xml"); if (!tmpfile.open() || tmpfile.write(session.toXml().toUtf8()) == -1) { return false; } tmpfile.close(); tmpfile.setAutoRemove(false); _process->start(sessionHandler->getRunVmScript(), QStringList(tmpfile.fileName())); qDebug() << sessionHandler->getRunVmScript(); QObject::connect(_process, SIGNAL(finished(int, QProcess::ExitStatus)), QApplication::instance(), SLOT(quit())); if (_process->state() == QProcess::Starting || QProcess::Running) return true; else return false; } int VSession::type() const { return Session::VSESSION; } bool VSession::operator<(const Session& other) const { int p0 = this->priority(); int p1 = other.priority(); if (p0 < p1) return true; if (p0 == p1) { QString d0 = this->shortDescription(); QString d1 = other.shortDescription(); return d0.localeAwareCompare(d1) < 0; } return false; }