/* * Copyright (C) 2018-2021 QuasarApp. * Distributed under the lgplv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ #include "Distributions/idistribution.h" #include "deployconfig.h" #include "filemanager.h" #include "packing.h" #include "pathutils.h" #include "quasarapp.h" #include #include #include #include #include #define TMP_PACKAGE_DIR "tmp_data" Packing::Packing(FileManager *fileManager) { assert(fileManager); _fileManager = fileManager; _proc = new QProcess(this); connect(_proc, SIGNAL(readyReadStandardError()), this, SLOT(handleOutputUpdate())); connect(_proc, SIGNAL(readyReadStandardOutput()), this, SLOT(handleOutputUpdate())); } Packing::~Packing() { _proc->kill(); } void Packing::setDistribution(const QList &pakages) { _pakages = pakages; } void Packing::calcDistributiveHash(const iDistribution* distro) { if (QuasarAppUtils::Params::isEndable("noHashSum")) { return; } if (!distro) { internalError(); return; } auto files = distro->outPutFiles(); for (const auto &file: files) { QFileInfo info(file); QuasarAppUtils::Params::log("Computing hash of " + info.absoluteFilePath(), QuasarAppUtils::Info); QFile out(info.absoluteFilePath() + ".md5"); if (!out.open(QIODevice::WriteOnly | QIODevice::Truncate)) { QuasarAppUtils::Params::log("Failed to open " + info.absoluteFilePath(), QuasarAppUtils::Error); continue; } out.write(calcHash(info.absoluteFilePath())); out.close(); _fileManager->addToDeployed(out.fileName()); } } bool Packing::create() { if (!collectPackages()) { QuasarAppUtils::Params::log("Fail to collect packages data.", QuasarAppUtils::Error); return false; } for (auto package : qAsConst(_pakages)) { if (!package) { internalError(); return false; } if (!package->deployTemplate(*this)) { QuasarAppUtils::Params::log(QString("Failed to deploy a package template. Package: %0."). arg(package->getClassName()), QuasarAppUtils::Error); return false; } auto commands = package->runCmd(); for (const auto& cmd: commands) { const DeployConfig *cfg = DeployCore::_config; QFileInfo cmdInfo(cmd.command); auto allExecRight = QFile::ExeUser | QFile::ExeGroup | QFile::ExeOwner; if (!cmdInfo.permission(allExecRight)) { QFile::setPermissions(cmdInfo.absoluteFilePath(), cmdInfo.permissions() | allExecRight); } _proc->setProgram(cmd.command); _proc->setProcessEnvironment(_proc->processEnvironment()); _proc->setArguments(cmd.arguments); _proc->setWorkingDirectory(cfg->getTargetDir()); _proc->start(); QuasarAppUtils::Params::log(cmd.command + " " + cmd.arguments.join(' '), QuasarAppUtils::Debug); if (!_proc->waitForStarted()) { QuasarAppUtils::Params::log(_proc->errorString(), QuasarAppUtils::Error); QuasarAppUtils::Params::log(QString("Process error code: %0").arg(_proc->error()), QuasarAppUtils::Error); return false; } if (!_proc->waitForFinished(-1)) { QuasarAppUtils::Params::log(_proc->errorString(), QuasarAppUtils::Error); QuasarAppUtils::Params::log(QString("Process error code: %0").arg(_proc->error()), QuasarAppUtils::Error); return false; } QString stdoutLog = _proc->readAllStandardOutput(); QString erroutLog = _proc->readAllStandardError(); auto message = QString("message = %0").arg(stdoutLog + " " + erroutLog); if (_proc->exitCode() != 0) { QuasarAppUtils::Params::log(message, QuasarAppUtils::Error); return false; } } if (!package->cb()) { internalError(); return false; } if (!restorePackagesLocations()) { internalError(); return false; } calcDistributiveHash(package); package->removeTemplate(); delete package; } const DeployConfig *cfg = DeployCore::_config; if (!QDir(cfg->getTargetDir() + "/" + TMP_PACKAGE_DIR).removeRecursively()) { QuasarAppUtils::Params::log("Failed to remove " + cfg->getTargetDir() + "/" + TMP_PACKAGE_DIR, QuasarAppUtils::Error); return false; } return true; } bool Packing::movePackage(const QString &package, const QString &newLocation) { // Disable moving data for extracting defaults templates. if (QuasarAppUtils::Params::isEndable("getDefaultTemplate")) { return true; } if (moveData(_packagesLocations.value(package), newLocation)) { _packagesLocations[package] = newLocation; return true; } return false; } bool Packing::copyPackage(const QString &package, const QString &newLocation) { return _fileManager->copyFolder(_packagesLocations[package], newLocation, {}, nullptr, nullptr, true); } bool Packing::extractTemplates() { const DeployConfig *cfg = DeployCore::_config; QuasarAppUtils::Params::log("You use the getDefaultTemplate. All using templates will be extracted into " + cfg->getTargetDir(), QuasarAppUtils::Info); if (!prepareTemplatesForExtract()) { return false; } for (auto package : qAsConst(_pakages)) { if (!package) return false; if (!package->deployRawTemplate(*this)) return false; delete package; } return true; } QStringList Packing::availablePackages() const { return _packagesLocations.keys(); } bool Packing::collectPackages() { const DeployConfig *cfg = DeployCore::_config; for (auto it = cfg->packages().begin(); it != cfg->packages().end(); ++it) { auto from = cfg->getTargetDir() + "/" + it.key(); if (PackageControl::isEmpty(from)) { continue; } if (!moveData(from, cfg->getTargetDir() + "/" + TMP_PACKAGE_DIR + "/" + it.key())) { QuasarAppUtils::Params::log("Fail to move " + from, QuasarAppUtils::Error); return false; } _packagesLocations.insert(it.key(), cfg->getTargetDir() + "/" + TMP_PACKAGE_DIR + "/" + it.key()); } _defaultPackagesLocations = _packagesLocations; return true; } bool Packing::prepareTemplatesForExtract() { const DeployConfig *cfg = DeployCore::_config; for (auto it = cfg->packages().begin(); it != cfg->packages().end(); ++it) { _packagesLocations.insert(it.key(), cfg->getTargetDir() + "/" + TMP_PACKAGE_DIR + "/" + it.key()); } _defaultPackagesLocations = _packagesLocations; return true; } bool Packing::moveData(const QString &from, const QString &to, const QString &ignore) const { if (from == to ) return true; if (!_fileManager->moveFolder(from, to, ignore)) { return false; } return QDir(from).removeRecursively(); } bool Packing::restorePackagesLocations() { for (auto it = _packagesLocations.begin(); it != _packagesLocations.end(); ++it) { if (!moveData(it.value(), _defaultPackagesLocations.value(it.key()))) { return false; } } _packagesLocations = _defaultPackagesLocations; return true; } QByteArray Packing::calcHash(const QString &file) { QFile f(file); if (!f.open(QIODevice::ReadOnly)) { return ""; } QByteArray hash = QCryptographicHash::hash(f.readAll(), QCryptographicHash::Md5).toHex(); f.close(); return hash; } void Packing::handleOutputUpdate() { QByteArray stdoutLog = _proc->readAllStandardOutput(); QByteArray erroutLog = _proc->readAllStandardError(); if (stdoutLog.size()) QuasarAppUtils::Params::log(stdoutLog, QuasarAppUtils::Info); if (erroutLog.size()) QuasarAppUtils::Params::log(erroutLog, QuasarAppUtils::Error); }