diff --git a/declarative/declarativessudeviceinfo.h b/declarative/declarativessudeviceinfo.h index 8ed6cab..631f5e4 100644 --- a/declarative/declarativessudeviceinfo.h +++ b/declarative/declarativessudeviceinfo.h @@ -19,9 +19,9 @@ class DeclarativeSsuDeviceInfo : public QObject * A list of types ssu provides shiny values suitable for displaying */ enum DisplayType { - DeviceManufacturer = Ssu::DeviceManufacturer, ///< Manufacturer, like ACME Corp. Board mappings key "deviceManufacturer" - DeviceModel = Ssu::DeviceModel, ///< Marketed device name, like Pogoblaster 3000. Board mappings key "prettyModel" - DeviceDesignation = Ssu::DeviceDesignation, ///< Type designation, like NCC-1701. Beard mappings key "deviceDesignation" + DeviceManufacturer = Ssu::DeviceManufacturer, ///< Manufacturer, like ACME Corp. Board mappings key "deviceManufacturer" + DeviceModel = Ssu::DeviceModel, ///< Marketed device name, like Pogoblaster 3000. Board mappings key "prettyModel" + DeviceDesignation = Ssu::DeviceDesignation, ///< Type designation, like NCC-1701. Beard mappings key "deviceDesignation" }; DeclarativeSsuDeviceInfo(); @@ -37,7 +37,7 @@ class DeclarativeSsuDeviceInfo : public QObject * If the device is not a variant it will return an empty string. If * fallback is set to true it return the device model in this case. */ - Q_INVOKABLE QString deviceVariant(bool fallback=false); + Q_INVOKABLE QString deviceVariant(bool fallback = false); /** * Try to find out ond what kind of system this is running */ diff --git a/libssu/sandbox.cpp b/libssu/sandbox.cpp index a16f473..75e86a1 100644 --- a/libssu/sandbox.cpp +++ b/libssu/sandbox.cpp @@ -56,80 +56,86 @@ Sandbox *Sandbox::s_activeInstance = 0; Sandbox::Sandbox() - : m_defaultConstructed(true), m_usage(UseDirectly), m_scopes(ThisProcess), - m_sandboxPath(QProcessEnvironment::systemEnvironment().value("SSU_SANDBOX_DIR")), - m_prepared(false){ - if (!activate()){ - qFatal("%s: Failed to activate", Q_FUNC_INFO); - } + : m_defaultConstructed(true), m_usage(UseDirectly), m_scopes(ThisProcess), + m_sandboxPath(QProcessEnvironment::systemEnvironment().value("SSU_SANDBOX_DIR")), + m_prepared(false) +{ + if (!activate()) { + qFatal("%s: Failed to activate", Q_FUNC_INFO); + } } Sandbox::Sandbox(const QString &sandboxPath, Usage usage, Scopes scopes) - : m_defaultConstructed(false), m_usage(usage), m_scopes(scopes), - m_sandboxPath(sandboxPath), m_prepared(false){ - Q_ASSERT(!sandboxPath.isEmpty()); + : m_defaultConstructed(false), m_usage(usage), m_scopes(scopes), + m_sandboxPath(sandboxPath), m_prepared(false) +{ + Q_ASSERT(!sandboxPath.isEmpty()); } -Sandbox::~Sandbox(){ - if (isActive()){ - deactivate(); - } +Sandbox::~Sandbox() +{ + if (isActive()) { + deactivate(); + } - if (!m_tempDir.isEmpty() && QFileInfo(m_tempDir).exists()){ - if (QProcess::execute("rm", QStringList() << "-rf" << m_tempDir) != 0){ - qWarning("%s: Failed to remove temporary directory", Q_FUNC_INFO); + if (!m_tempDir.isEmpty() && QFileInfo(m_tempDir).exists()) { + if (QProcess::execute("rm", QStringList() << "-rf" << m_tempDir) != 0) { + qWarning("%s: Failed to remove temporary directory", Q_FUNC_INFO); + } } - } } -bool Sandbox::isActive() const{ - return s_activeInstance == this; +bool Sandbox::isActive() const +{ + return s_activeInstance == this; } -bool Sandbox::activate(){ - Q_ASSERT_X(s_activeInstance == 0, Q_FUNC_INFO, "Only one instance can be active!"); +bool Sandbox::activate() +{ + Q_ASSERT_X(s_activeInstance == 0, Q_FUNC_INFO, "Only one instance can be active!"); - if (!prepare()){ - return false; - } + if (!prepare()) { + return false; + } - if (m_scopes & ChildProcesses){ - setenv("SSU_SANDBOX_DIR", qPrintable(m_workingSandboxDir.path()), 1); - } + if (m_scopes & ChildProcesses) { + setenv("SSU_SANDBOX_DIR", qPrintable(m_workingSandboxDir.path()), 1); + } - s_activeInstance = this; - return true; + s_activeInstance = this; + return true; } -void Sandbox::deactivate(){ - Q_ASSERT(isActive()); +void Sandbox::deactivate() +{ + Q_ASSERT(isActive()); - if (m_scopes & ChildProcesses){ - unsetenv("SSU_SANDBOX_DIR"); - } + if (m_scopes & ChildProcesses) { + unsetenv("SSU_SANDBOX_DIR"); + } - s_activeInstance = 0; + s_activeInstance = 0; } QDir Sandbox::effectiveRootDir() { - return s_activeInstance != 0 && s_activeInstance->m_scopes & ThisProcess - ? s_activeInstance->m_workingSandboxDir - : QDir::root(); + return s_activeInstance != 0 && s_activeInstance->m_scopes & ThisProcess + ? s_activeInstance->m_workingSandboxDir + : QDir::root(); } QString Sandbox::map(const QString &fileName) { - return effectiveRootDir().filePath( - QDir::root().relativeFilePath( - QFileInfo(fileName).absoluteFilePath())); + return effectiveRootDir().filePath( + QDir::root().relativeFilePath( + QFileInfo(fileName).absoluteFilePath())); } QString Sandbox::map(const QString &pathName, const QString &fileName) { - return effectiveRootDir().filePath( - QDir::root().relativeFilePath( - QFileInfo(pathName + fileName).absoluteFilePath())); + return effectiveRootDir().filePath( + QDir::root().relativeFilePath( + QFileInfo(pathName + fileName).absoluteFilePath())); } /** @@ -138,184 +144,189 @@ QString Sandbox::map(const QString &pathName, const QString &fileName) * @c QDir::NoDotAndDotDot is always added into @a filters. */ bool Sandbox::addWorldFiles(const QString &directory, QDir::Filters filters, - const QStringList &filterNames, bool recurse){ - Q_ASSERT(!isActive()); - Q_ASSERT(!directory.isEmpty()); - - if (!prepare()){ - return false; - } - - const QString sandboxedDirectory = m_workingSandboxDir.filePath( - QDir::root().relativeFilePath( - QFileInfo(directory).absoluteFilePath())); - - if (!QFileInfo(directory).exists()){ - // Accept missing world directory - allow to create directories inside sandbox - qDebug("%s: Directory does not exist - an empty one will be created instead of copied: '%s'", - Q_FUNC_INFO, qPrintable(directory)); - } else if (!QFileInfo(directory).isDir()){ - qWarning("%s: Is not a directory: '%s'", Q_FUNC_INFO, qPrintable(directory)); - return false; - } - - if (!QFileInfo(sandboxedDirectory).exists()){ - if (!QDir().mkpath(sandboxedDirectory)){ - qWarning("%s: Failed to create sandbox directory '%s'", Q_FUNC_INFO, - qPrintable(sandboxedDirectory)); - return false; + const QStringList &filterNames, bool recurse) +{ + Q_ASSERT(!isActive()); + Q_ASSERT(!directory.isEmpty()); + + if (!prepare()) { + return false; } - } else if (!QFileInfo(sandboxedDirectory).isDir()){ - qWarning("%s: Failed to create sandbox directory '%s': Is not a directory", Q_FUNC_INFO, - qPrintable(sandboxedDirectory)); - return false; - } - if (filters == QDir::NoFilter){ - filters = QDir::AllEntries; - } + const QString sandboxedDirectory = m_workingSandboxDir.filePath( + QDir::root().relativeFilePath( + QFileInfo(directory).absoluteFilePath())); - filters |= QDir::NoDotAndDotDot; + if (!QFileInfo(directory).exists()) { + // Accept missing world directory - allow to create directories inside sandbox + qDebug("%s: Directory does not exist - an empty one will be created instead of copied: '%s'", + Q_FUNC_INFO, qPrintable(directory)); + } else if (!QFileInfo(directory).isDir()) { + qWarning("%s: Is not a directory: '%s'", Q_FUNC_INFO, qPrintable(directory)); + return false; + } - foreach (const QFileInfo &worldEntryInfo, QDir(directory).entryInfoList(filterNames, filters)){ + if (!QFileInfo(sandboxedDirectory).exists()) { + if (!QDir().mkpath(sandboxedDirectory)) { + qWarning("%s: Failed to create sandbox directory '%s'", Q_FUNC_INFO, + qPrintable(sandboxedDirectory)); + return false; + } + } else if (!QFileInfo(sandboxedDirectory).isDir()) { + qWarning("%s: Failed to create sandbox directory '%s': Is not a directory", Q_FUNC_INFO, + qPrintable(sandboxedDirectory)); + return false; + } - const QFileInfo sandboxEntryInfo(QDir(sandboxedDirectory).filePath(worldEntryInfo.fileName())); + if (filters == QDir::NoFilter) { + filters = QDir::AllEntries; + } - if (worldEntryInfo.isDir()){ - if (!sandboxEntryInfo.exists()){ - if (!QDir(sandboxedDirectory).mkdir(worldEntryInfo.fileName())){ - qWarning("%s: Failed to create overlay directory '%s/%s'", Q_FUNC_INFO, - qPrintable(sandboxedDirectory), qPrintable(worldEntryInfo.fileName())); - return false; - } - } else if (!sandboxEntryInfo.isDir()){ - qWarning("%s: Failed to create sandboxed copy '%s': Is not a directory", Q_FUNC_INFO, - qPrintable(sandboxEntryInfo.filePath())); - return false; - } - - if (recurse){ - if (!addWorldFiles(worldEntryInfo.absoluteFilePath(), filters, filterNames, true)){ - return false; - } - } - } else{ - if (!sandboxEntryInfo.exists()){ - if (!QFile(worldEntryInfo.filePath()).copy(sandboxEntryInfo.filePath())){ - qWarning("%s: Failed to copy file into sandbox '%s'", Q_FUNC_INFO, - qPrintable(worldEntryInfo.filePath())); - return false; + filters |= QDir::NoDotAndDotDot; + + foreach (const QFileInfo &worldEntryInfo, QDir(directory).entryInfoList(filterNames, filters)) { + + const QFileInfo sandboxEntryInfo(QDir(sandboxedDirectory).filePath(worldEntryInfo.fileName())); + + if (worldEntryInfo.isDir()) { + if (!sandboxEntryInfo.exists()) { + if (!QDir(sandboxedDirectory).mkdir(worldEntryInfo.fileName())) { + qWarning("%s: Failed to create overlay directory '%s/%s'", Q_FUNC_INFO, + qPrintable(sandboxedDirectory), qPrintable(worldEntryInfo.fileName())); + return false; + } + } else if (!sandboxEntryInfo.isDir()) { + qWarning("%s: Failed to create sandboxed copy '%s': Is not a directory", Q_FUNC_INFO, + qPrintable(sandboxEntryInfo.filePath())); + return false; + } + + if (recurse) { + if (!addWorldFiles(worldEntryInfo.absoluteFilePath(), filters, filterNames, true)) { + return false; + } + } + } else { + if (!sandboxEntryInfo.exists()) { + if (!QFile(worldEntryInfo.filePath()).copy(sandboxEntryInfo.filePath())) { + qWarning("%s: Failed to copy file into sandbox '%s'", Q_FUNC_INFO, + qPrintable(worldEntryInfo.filePath())); + return false; + } + } else if (sandboxEntryInfo.isDir()) { + qWarning("%s: Failed to create sandboxed copy '%s': Is a directory", Q_FUNC_INFO, + qPrintable(sandboxEntryInfo.filePath())); + return false; + } } - } else if (sandboxEntryInfo.isDir()){ - qWarning("%s: Failed to create sandboxed copy '%s': Is a directory", Q_FUNC_INFO, - qPrintable(sandboxEntryInfo.filePath())); - return false; - } } - } - return true; + return true; } -bool Sandbox::addWorldFile(const QString &file){ - return addWorldFiles(QFileInfo(file).path(), QDir::NoFilter, - QStringList() << QFileInfo(file).fileName()); +bool Sandbox::addWorldFile(const QString &file) +{ + return addWorldFiles(QFileInfo(file).path(), QDir::NoFilter, + QStringList() << QFileInfo(file).fileName()); } -bool Sandbox::prepare(){ - Q_ASSERT(m_defaultConstructed || !m_sandboxPath.isEmpty()); - - if (m_prepared){ - return true; - } +bool Sandbox::prepare() +{ + Q_ASSERT(m_defaultConstructed || !m_sandboxPath.isEmpty()); - if (m_sandboxPath.isEmpty()){ - return true; - } - - if (!QFileInfo(m_sandboxPath).exists()){ - qWarning("%s: Invalid sandboxPath: No such file or directory", qPrintable(m_sandboxPath)); - return false; - } - - if (!QFileInfo(m_sandboxPath).isDir()){ - qWarning("%s: Invalid sandboxPath: Not a directory", qPrintable(m_sandboxPath)); - return false; - } - - if (m_usage == UseAsSkeleton){ - if (m_tempDir = createTmpDir("ssu-sandbox.%1"), m_tempDir.isEmpty()){ - qWarning("%s: Failed to create sandbox directory", Q_FUNC_INFO); - return false; + if (m_prepared) { + return true; } - const QString sandboxCopyPath = QDir(m_tempDir).filePath("configroot"); + if (m_sandboxPath.isEmpty()) { + return true; + } - if (!copyDir(m_sandboxPath, sandboxCopyPath)){ - qWarning("%s: Failed to copy sandbox directory", Q_FUNC_INFO); - return false; + if (!QFileInfo(m_sandboxPath).exists()) { + qWarning("%s: Invalid sandboxPath: No such file or directory", qPrintable(m_sandboxPath)); + return false; } - m_workingSandboxDir = QDir(sandboxCopyPath); - } else{ - m_workingSandboxDir = QDir(m_sandboxPath); - } + if (!QFileInfo(m_sandboxPath).isDir()) { + qWarning("%s: Invalid sandboxPath: Not a directory", qPrintable(m_sandboxPath)); + return false; + } - m_prepared = true; - return true; -} + if (m_usage == UseAsSkeleton) { + if (m_tempDir = createTmpDir("ssu-sandbox.%1"), m_tempDir.isEmpty()) { + qWarning("%s: Failed to create sandbox directory", Q_FUNC_INFO); + return false; + } -QString Sandbox::createTmpDir(const QString &nameTemplate){ - static const int REASONABLE_REPEAT_COUNT = 10; + const QString sandboxCopyPath = QDir(m_tempDir).filePath("configroot"); - for (int i = 0; i < REASONABLE_REPEAT_COUNT; ++i){ - QString path; - int suffix = 0; - do{ - path = QDir::temp().filePath(nameTemplate.arg(++suffix)); - }while(QFileInfo(path).exists()); + if (!copyDir(m_sandboxPath, sandboxCopyPath)) { + qWarning("%s: Failed to copy sandbox directory", Q_FUNC_INFO); + return false; + } - if (QDir().mkpath(path)){ - return path; + m_workingSandboxDir = QDir(sandboxCopyPath); + } else { + m_workingSandboxDir = QDir(m_sandboxPath); } - } - qWarning("%s: Failed to create temporary directory", Q_FUNC_INFO); - return QString(); + m_prepared = true; + return true; } -bool Sandbox::copyDir(const QString &directory, const QString &newName){ - const QDir sourceRoot(directory); - const QDir destinationRoot(newName); +QString Sandbox::createTmpDir(const QString &nameTemplate) +{ + static const int REASONABLE_REPEAT_COUNT = 10; - QDirIterator it(directory, QDir::AllEntries|QDir::NoDotAndDotDot, QDirIterator::Subdirectories); - while (it.hasNext()){ - it.next(); + for (int i = 0; i < REASONABLE_REPEAT_COUNT; ++i) { + QString path; + int suffix = 0; + do { + path = QDir::temp().filePath(nameTemplate.arg(++suffix)); + } while (QFileInfo(path).exists()); - const QFileInfo destination = QFileInfo(destinationRoot.filePath( - sourceRoot.relativeFilePath(it.filePath()))); + if (QDir().mkpath(path)) { + return path; + } + } - if (it.fileInfo().isDir()){ - if (!QDir().mkpath(destination.absoluteFilePath())){ - qWarning("%s: Failed to mkpath '%s'", Q_FUNC_INFO, qPrintable(destination.absolutePath())); - return false; - } - } else if (it.fileInfo().isFile()){ - if (!QDir().mkpath(destination.absolutePath())){ - qWarning("%s: Failed to mkpath '%s'", Q_FUNC_INFO, qPrintable(destination.absolutePath())); - return false; - } + qWarning("%s: Failed to create temporary directory", Q_FUNC_INFO); + return QString(); +} - if (!QFile::copy(it.fileInfo().absoluteFilePath(), destination.absoluteFilePath())){ - qWarning("%s: Failed to copy file '%s'", Q_FUNC_INFO, qPrintable(it.filePath())); - return false; - } - } else{ - qWarning("%s: Cannot copy other than regular files: '%s'", Q_FUNC_INFO, - qPrintable(it.filePath())); - return false; +bool Sandbox::copyDir(const QString &directory, const QString &newName) +{ + const QDir sourceRoot(directory); + const QDir destinationRoot(newName); + + QDirIterator it(directory, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + + const QFileInfo destination = QFileInfo(destinationRoot.filePath( + sourceRoot.relativeFilePath(it.filePath()))); + + if (it.fileInfo().isDir()) { + if (!QDir().mkpath(destination.absoluteFilePath())) { + qWarning("%s: Failed to mkpath '%s'", Q_FUNC_INFO, qPrintable(destination.absolutePath())); + return false; + } + } else if (it.fileInfo().isFile()) { + if (!QDir().mkpath(destination.absolutePath())) { + qWarning("%s: Failed to mkpath '%s'", Q_FUNC_INFO, qPrintable(destination.absolutePath())); + return false; + } + + if (!QFile::copy(it.fileInfo().absoluteFilePath(), destination.absoluteFilePath())) { + qWarning("%s: Failed to copy file '%s'", Q_FUNC_INFO, qPrintable(it.filePath())); + return false; + } + } else { + qWarning("%s: Cannot copy other than regular files: '%s'", Q_FUNC_INFO, + qPrintable(it.filePath())); + return false; + } } - } - return true; + return true; } diff --git a/libssu/sandbox_p.h b/libssu/sandbox_p.h index 05214ad..da01ff9 100644 --- a/libssu/sandbox_p.h +++ b/libssu/sandbox_p.h @@ -18,20 +18,21 @@ getenv("SSU_TESTS_DATA_PATH") : \ TESTS_DATA_PATH) -class Sandbox { - public: +class Sandbox +{ +public: enum Usage { - UseDirectly, - UseAsSkeleton, + UseDirectly, + UseAsSkeleton, }; enum Scope { - ThisProcess = 0x01, - ChildProcesses = 0x02, + ThisProcess = 0x01, + ChildProcesses = 0x02, }; Q_DECLARE_FLAGS(Scopes, Scope) - public: +public: Sandbox(); Sandbox(const QString &sandboxPath, Usage usage, Scopes scopes); ~Sandbox(); @@ -45,15 +46,15 @@ class Sandbox { static QString map(const QString &pathName, const QString &fileName); bool addWorldFiles(const QString &directory, QDir::Filters filters = QDir::NoFilter, - const QStringList &filterNames = QStringList(), bool recurse = true); + const QStringList &filterNames = QStringList(), bool recurse = true); bool addWorldFile(const QString &file); - private: +private: bool prepare(); static QString createTmpDir(const QString &nameTemplate); static bool copyDir(const QString &directory, const QString &newName); - private: +private: static Sandbox *s_activeInstance; const bool m_defaultConstructed; const Usage m_usage; diff --git a/libssu/ssu.cpp b/libssu/ssu.cpp index cb1ece5..65af4ac 100644 --- a/libssu/ssu.cpp +++ b/libssu/ssu.cpp @@ -32,668 +32,697 @@ #define SSU_NETWORK_REQUEST_DOMAIN_DATA (static_cast(QNetworkRequest::User + 1)) -static void restoreUid(){ - if (getuid() == 0){ - seteuid(0); - setegid(0); - } +static void restoreUid() +{ + if (getuid() == 0) { + seteuid(0); + setegid(0); + } } -Ssu::Ssu(): QObject(){ - errorFlag = false; - pendingRequests = 0; +Ssu::Ssu(): QObject() +{ + errorFlag = false; + pendingRequests = 0; #ifdef SSUCONFHACK - // dirty hack to make sure we can write to the configuration - // this is currently required since there's no global gconf, - // and we migth not yet have users on bootstrap - QFileInfo settingsInfo(SSU_CONFIGURATION); - if (settingsInfo.groupId() != SSU_GROUP_ID || - !settingsInfo.permission(QFile::WriteGroup)){ - QProcess proc; - proc.start("/usr/bin/ssuconfperm"); - proc.waitForFinished(); - } + // dirty hack to make sure we can write to the configuration + // this is currently required since there's no global gconf, + // and we migth not yet have users on bootstrap + QFileInfo settingsInfo(SSU_CONFIGURATION); + if (settingsInfo.groupId() != SSU_GROUP_ID || + !settingsInfo.permission(QFile::WriteGroup)) { + QProcess proc; + proc.start("/usr/bin/ssuconfperm"); + proc.waitForFinished(); + } #endif - SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuCoreConfig *settings = SsuCoreConfig::instance(); #ifdef TARGET_ARCH - if (!settings->contains("arch")) - settings->setValue("arch", TARGET_ARCH); + if (!settings->contains("arch")) + settings->setValue("arch", TARGET_ARCH); #else // FIXME, try to guess a matching architecture #warning "TARGET_ARCH not defined" #endif - settings->sync(); + settings->sync(); - manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply *)), - SLOT(requestFinished(QNetworkReply *))); + manager = new QNetworkAccessManager(this); + connect(manager, SIGNAL(finished(QNetworkReply *)), + SLOT(requestFinished(QNetworkReply *))); } // FIXME, the whole credentials stuff needs reworking // should probably be part of repo handling instead of core configuration -QPair Ssu::credentials(QString scope){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->credentials(scope); +QPair Ssu::credentials(QString scope) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->credentials(scope); } -QString Ssu::credentialsScope(QString repoName, bool rndRepo){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); - - // hardcoded magic for doing special privileges store repositories - if (repoName == "store" || repoName.startsWith("store-c-")) - return "store"; - - // check if some repos are marked for using store-credentials - // in current domain, checking first for rnd/release specific - // settings, and if not found in generic settings - QString storeAuthReposKey = QString("store-auth-repos-%1") - .arg(rndRepo ? "rnd" : "release"); - QStringList storeAuthRepos = - SsuVariables::variable(&repoSettings, - domain() + "-domain", - storeAuthReposKey).toStringList(); - - if (storeAuthRepos.empty()) - storeAuthRepos = - SsuVariables::variable(&repoSettings, - domain() + "-domain", - "store-auth-repos").toStringList(); - - if (storeAuthRepos.contains(repoName)) - return "store"; - - // If we defined explicitly what credentials to use with which secure domain - // use those. - QHash secureDomainAuth; - SsuVariables::variableSection(&repoSettings, "secure-domain-auth", &secureDomainAuth); - QHashIterator i(secureDomainAuth); - while (i.hasNext()) { - i.next(); - if (repoUrl(repoName, rndRepo).contains(i.key()) && !i.value().isEmpty()) { - return i.value(); +QString Ssu::credentialsScope(QString repoName, bool rndRepo) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); + + // hardcoded magic for doing special privileges store repositories + if (repoName == "store" || repoName.startsWith("store-c-")) + return "store"; + + // check if some repos are marked for using store-credentials + // in current domain, checking first for rnd/release specific + // settings, and if not found in generic settings + QString storeAuthReposKey = QString("store-auth-repos-%1") + .arg(rndRepo ? "rnd" : "release"); + QStringList storeAuthRepos = + SsuVariables::variable(&repoSettings, + domain() + "-domain", + storeAuthReposKey).toStringList(); + + if (storeAuthRepos.empty()) + storeAuthRepos = + SsuVariables::variable(&repoSettings, + domain() + "-domain", + "store-auth-repos").toStringList(); + + if (storeAuthRepos.contains(repoName)) + return "store"; + + // If we defined explicitly what credentials to use with which secure domain + // use those. + QHash secureDomainAuth; + SsuVariables::variableSection(&repoSettings, "secure-domain-auth", &secureDomainAuth); + QHashIterator i(secureDomainAuth); + while (i.hasNext()) { + i.next(); + if (repoUrl(repoName, rndRepo).contains(i.key()) && !i.value().isEmpty()) { + return i.value(); + } } - } - return settings->credentialsScope(repoName, rndRepo); + return settings->credentialsScope(repoName, rndRepo); } -QString Ssu::credentialsUrl(QString scope){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->credentialsUrl(scope); +QString Ssu::credentialsUrl(QString scope) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->credentialsUrl(scope); } -bool Ssu::error(){ - return errorFlag; +bool Ssu::error() +{ + return errorFlag; } // Wrappers around SsuCoreConfig -QString Ssu::flavour(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->flavour(); +QString Ssu::flavour() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->flavour(); } -Ssu::DeviceModeFlags Ssu::deviceMode(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->deviceMode(); +Ssu::DeviceModeFlags Ssu::deviceMode() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->deviceMode(); } -QString Ssu::domain(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->domain(true); +QString Ssu::domain() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->domain(true); } -bool Ssu::isRegistered(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->isRegistered(); +bool Ssu::isRegistered() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->isRegistered(); } -QDateTime Ssu::lastCredentialsUpdate(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->lastCredentialsUpdate(); +QDateTime Ssu::lastCredentialsUpdate() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->lastCredentialsUpdate(); } -QString Ssu::release(bool rnd){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->release(rnd); +QString Ssu::release(bool rnd) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->release(rnd); } -void Ssu::setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->setDeviceMode(mode, editMode); +void Ssu::setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + settings->setDeviceMode(mode, editMode); } -void Ssu::setFlavour(QString flavour){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->setFlavour(flavour); +void Ssu::setFlavour(QString flavour) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + settings->setFlavour(flavour); } -void Ssu::setRelease(QString release, bool rnd){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->setRelease(release, rnd); +void Ssu::setRelease(QString release, bool rnd) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + settings->setRelease(release, rnd); } -void Ssu::setDomain(QString domain){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->setDomain(domain); +void Ssu::setDomain(QString domain) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + settings->setDomain(domain); } -bool Ssu::useSslVerify(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - return settings->useSslVerify(); +bool Ssu::useSslVerify() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + return settings->useSslVerify(); } //... -QString Ssu::lastError(){ - return errorString; +QString Ssu::lastError() +{ + return errorString; } -bool Ssu::registerDevice(QDomDocument *response){ - QString certificateString = response->elementsByTagName("certificate").at(0).toElement().text(); - QSslCertificate certificate(certificateString.toLatin1()); - SsuLog *ssuLog = SsuLog::instance(); - SsuCoreConfig *settings = SsuCoreConfig::instance(); +bool Ssu::registerDevice(QDomDocument *response) +{ + QString certificateString = response->elementsByTagName("certificate").at(0).toElement().text(); + QSslCertificate certificate(certificateString.toLatin1()); + SsuLog *ssuLog = SsuLog::instance(); + SsuCoreConfig *settings = SsuCoreConfig::instance(); - if (certificate.isNull()){ - // make sure device is in unregistered state on failed registration - settings->setValue("registered", false); - setError("Certificate is invalid"); - return false; - } else - settings->setValue("certificate", certificate.toPem()); + if (certificate.isNull()) { + // make sure device is in unregistered state on failed registration + settings->setValue("registered", false); + setError("Certificate is invalid"); + return false; + } else + settings->setValue("certificate", certificate.toPem()); - QString privateKeyString = response->elementsByTagName("privateKey").at(0).toElement().text(); - QSslKey privateKey(privateKeyString.toLatin1(), QSsl::Rsa); + QString privateKeyString = response->elementsByTagName("privateKey").at(0).toElement().text(); + QSslKey privateKey(privateKeyString.toLatin1(), QSsl::Rsa); - if (privateKey.isNull()){ - settings->setValue("registered", false); - setError("Private key is invalid"); - return false; - } else - settings->setValue("privateKey", privateKey.toPem()); - - // oldUser is just for reference purposes, in case we want to notify - // about owner changes for the device - QString oldUser = response->elementsByTagName("user").at(0).toElement().text(); - ssuLog->print(LOG_DEBUG, QString("Old user for your device was: %1").arg(oldUser)); - - // if we came that far everything required for device registration is done - settings->setValue("registered", true); - settings->sync(); - - if (!settings->isWritable()){ - setError("Configuration is not writable, device registration failed."); - return false; - } - - emit registrationStatusChanged(); - return true; + if (privateKey.isNull()) { + settings->setValue("registered", false); + setError("Private key is invalid"); + return false; + } else + settings->setValue("privateKey", privateKey.toPem()); + + // oldUser is just for reference purposes, in case we want to notify + // about owner changes for the device + QString oldUser = response->elementsByTagName("user").at(0).toElement().text(); + ssuLog->print(LOG_DEBUG, QString("Old user for your device was: %1").arg(oldUser)); + + // if we came that far everything required for device registration is done + settings->setValue("registered", true); + settings->sync(); + + if (!settings->isWritable()) { + setError("Configuration is not writable, device registration failed."); + return false; + } + + emit registrationStatusChanged(); + return true; } // RND repos have flavour (devel, testing, release), and release (latest, next) // Release repos only have release (latest, next, version number) QString Ssu::repoUrl(QString repoName, bool rndRepo, QHash repoParameters, - QHash parametersOverride){ - SsuRepoManager manager; - return manager.url(repoName, rndRepo, repoParameters, parametersOverride); + QHash parametersOverride) +{ + SsuRepoManager manager; + return manager.url(repoName, rndRepo, repoParameters, parametersOverride); } -void Ssu::requestFinished(QNetworkReply *reply){ - QSslConfiguration sslConfiguration = reply->sslConfiguration(); - SsuLog *ssuLog = SsuLog::instance(); - SsuCoreConfig *settings = SsuCoreConfig::instance(); - QNetworkRequest request = reply->request(); - QVariant originalDomainVariant = request.attribute(SSU_NETWORK_REQUEST_DOMAIN_DATA); +void Ssu::requestFinished(QNetworkReply *reply) +{ + QSslConfiguration sslConfiguration = reply->sslConfiguration(); + SsuLog *ssuLog = SsuLog::instance(); + SsuCoreConfig *settings = SsuCoreConfig::instance(); + QNetworkRequest request = reply->request(); + QVariant originalDomainVariant = request.attribute(SSU_NETWORK_REQUEST_DOMAIN_DATA); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - ssuLog->print(LOG_DEBUG, QString("Certificate used was issued for '%1' by '%2'. Complete chain:") - .arg(sslConfiguration.peerCertificate().subjectInfo(QSslCertificate::CommonName).join("")) - .arg(sslConfiguration.peerCertificate().issuerInfo(QSslCertificate::CommonName).join(""))); + ssuLog->print(LOG_DEBUG, QString("Certificate used was issued for '%1' by '%2'. Complete chain:") + .arg(sslConfiguration.peerCertificate().subjectInfo(QSslCertificate::CommonName).join("")) + .arg(sslConfiguration.peerCertificate().issuerInfo(QSslCertificate::CommonName).join(""))); - foreach (const QSslCertificate cert, sslConfiguration.peerCertificateChain()){ - ssuLog->print(LOG_DEBUG, QString("-> %1").arg(cert.subjectInfo(QSslCertificate::CommonName).join(""))); - } + foreach (const QSslCertificate cert, sslConfiguration.peerCertificateChain()) { + ssuLog->print(LOG_DEBUG, QString("-> %1").arg(cert.subjectInfo(QSslCertificate::CommonName).join(""))); + } #else - ssuLog->print(LOG_DEBUG, QString("Certificate used was issued for '%1' by '%2'. Complete chain:") - .arg(sslConfiguration.peerCertificate().subjectInfo(QSslCertificate::CommonName)) - .arg(sslConfiguration.peerCertificate().issuerInfo(QSslCertificate::CommonName))); + ssuLog->print(LOG_DEBUG, QString("Certificate used was issued for '%1' by '%2'. Complete chain:") + .arg(sslConfiguration.peerCertificate().subjectInfo(QSslCertificate::CommonName)) + .arg(sslConfiguration.peerCertificate().issuerInfo(QSslCertificate::CommonName))); - foreach (const QSslCertificate cert, sslConfiguration.peerCertificateChain()){ - ssuLog->print(LOG_DEBUG, QString("-> %1").arg(cert.subjectInfo(QSslCertificate::CommonName))); - } + foreach (const QSslCertificate cert, sslConfiguration.peerCertificateChain()) { + ssuLog->print(LOG_DEBUG, QString("-> %1").arg(cert.subjectInfo(QSslCertificate::CommonName))); + } #endif - pendingRequests--; + pendingRequests--; - QString action; - QByteArray data; - QDomDocument doc; - QString xmlError; + QString action; + QByteArray data; + QDomDocument doc; + QString xmlError; - /// @TODO: indicate that the device is not registered if there's a 404 on credentials update url - if (settings->contains("home-url")){ - QString homeUrl = settings->value("home-url").toString().arg(""); - homeUrl.remove(QRegExp("//+$")); + /// @TODO: indicate that the device is not registered if there's a 404 on credentials update url + if (settings->contains("home-url")) { + QString homeUrl = settings->value("home-url").toString().arg(""); + homeUrl.remove(QRegExp("//+$")); - if (request.url().toString().startsWith(homeUrl, Qt::CaseInsensitive)){ - // we don't care about errors on download request - if (reply->error() == 0) { - QByteArray data = reply->readAll(); - storeAuthorizedKeys(data); - } + if (request.url().toString().startsWith(homeUrl, Qt::CaseInsensitive)) { + // we don't care about errors on download request + if (reply->error() == 0) { + QByteArray data = reply->readAll(); + storeAuthorizedKeys(data); + } - goto success; + goto success; + } } - } - - if (reply->error() > 0){ - setError(reply->errorString()); - goto failure; - } - data = reply->readAll(); - ssuLog->print(LOG_DEBUG, QString("RequestOutput %1") - .arg(data.data())); + if (reply->error() > 0) { + setError(reply->errorString()); + goto failure; + } - if (!doc.setContent(data, &xmlError)){ - setError(tr("Unable to parse server response (%1)").arg(xmlError)); - goto failure; - } + data = reply->readAll(); + ssuLog->print(LOG_DEBUG, QString("RequestOutput %1") + .arg(data.data())); - action = doc.elementsByTagName("action").at(0).toElement().text(); + if (!doc.setContent(data, &xmlError)) { + setError(tr("Unable to parse server response (%1)").arg(xmlError)); + goto failure; + } - if (!verifyResponse(&doc)) { - goto failure; - } + action = doc.elementsByTagName("action").at(0).toElement().text(); - ssuLog->print(LOG_DEBUG, QString("Handling request of type %1") - .arg(action)); - if (action == "register") { - if (registerDevice(&doc)) { - goto success; + if (!verifyResponse(&doc)) { + goto failure; } - } else if (action == "credentials") { - if (setCredentials(&doc)) { - goto success; + + ssuLog->print(LOG_DEBUG, QString("Handling request of type %1") + .arg(action)); + if (action == "register") { + if (registerDevice(&doc)) { + goto success; + } + } else if (action == "credentials") { + if (setCredentials(&doc)) { + goto success; + } + } else { + setError(tr("Response to unknown action encountered: %1").arg(action)); } - } else { - setError(tr("Response to unknown action encountered: %1").arg(action)); - } failure: - // Restore the original domain in case of failures with the registration - if (!originalDomainVariant.isNull()) { - QString originalDomain = originalDomainVariant.toString(); - ssuLog->print(LOG_DEBUG, QString("Restoring domain on error: '%1'").arg(originalDomain)); - setDomain(originalDomain); - } - - // Fall through to cleanup handling in success from failure label + // Restore the original domain in case of failures with the registration + if (!originalDomainVariant.isNull()) { + QString originalDomain = originalDomainVariant.toString(); + ssuLog->print(LOG_DEBUG, QString("Restoring domain on error: '%1'").arg(originalDomain)); + setDomain(originalDomain); + } + + // Fall through to cleanup handling in success from failure label success: - ssuLog->print(LOG_DEBUG, QString("Request finished, pending requests: %1").arg(pendingRequests)); - if (pendingRequests == 0) { - emit done(); - } + ssuLog->print(LOG_DEBUG, QString("Request finished, pending requests: %1").arg(pendingRequests)); + if (pendingRequests == 0) { + emit done(); + } } -void Ssu::sendRegistration(QString usernameDomain, QString password){ - errorFlag = false; - - QString ssuCaCertificate, ssuRegisterUrl; - QString username, domainName; - - SsuLog *ssuLog = SsuLog::instance(); - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuDeviceInfo deviceInfo; - - QNetworkRequest request; - request.setAttribute(SSU_NETWORK_REQUEST_DOMAIN_DATA, domain()); - ssuLog->print(LOG_DEBUG, QString("Saving current domain before request: '%1'").arg(domain())); - - // Username can include also domain, (user@domain), separate those - if (usernameDomain.contains('@')) { - // separate domain/username and set domain - username = usernameDomain.section('@', 0, 0); - domainName = usernameDomain.section('@', 1, 1); - setDomain(domainName); - } else { - // No domain defined - username = usernameDomain; - if (settings->contains("default-rnd-domain")) - setDomain(settings->value("default-rnd-domain").toString()); - } - - ssuCaCertificate = SsuRepoManager::caCertificatePath(); - if (ssuCaCertificate.isEmpty()){ - setError("CA certificate for ssu not set ('_ca-certificate in domain')"); - return; - } - - if (!settings->contains("register-url")){ - ssuRegisterUrl = repoUrl("register-url"); - if (ssuRegisterUrl.isEmpty()){ - setError("URL for ssu registration not set (config key 'register-url')"); - return; +void Ssu::sendRegistration(QString usernameDomain, QString password) +{ + errorFlag = false; + + QString ssuCaCertificate, ssuRegisterUrl; + QString username, domainName; + + SsuLog *ssuLog = SsuLog::instance(); + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuDeviceInfo deviceInfo; + + QNetworkRequest request; + request.setAttribute(SSU_NETWORK_REQUEST_DOMAIN_DATA, domain()); + ssuLog->print(LOG_DEBUG, QString("Saving current domain before request: '%1'").arg(domain())); + + // Username can include also domain, (user@domain), separate those + if (usernameDomain.contains('@')) { + // separate domain/username and set domain + username = usernameDomain.section('@', 0, 0); + domainName = usernameDomain.section('@', 1, 1); + setDomain(domainName); + } else { + // No domain defined + username = usernameDomain; + if (settings->contains("default-rnd-domain")) + setDomain(settings->value("default-rnd-domain").toString()); } - } else - ssuRegisterUrl = settings->value("register-url").toString(); - QString IMEI = deviceInfo.deviceUid(); - if (IMEI == ""){ - setError("No valid UID available for your device. For phones: is your modem online?"); - return; - } + ssuCaCertificate = SsuRepoManager::caCertificatePath(); + if (ssuCaCertificate.isEmpty()) { + setError("CA certificate for ssu not set ('_ca-certificate in domain')"); + return; + } - QSslConfiguration sslConfiguration; - if (!useSslVerify()) - sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); + if (!settings->contains("register-url")) { + ssuRegisterUrl = repoUrl("register-url"); + if (ssuRegisterUrl.isEmpty()) { + setError("URL for ssu registration not set (config key 'register-url')"); + return; + } + } else + ssuRegisterUrl = settings->value("register-url").toString(); - sslConfiguration.setCaCertificates(QSslCertificate::fromPath(ssuCaCertificate)); + QString IMEI = deviceInfo.deviceUid(); + if (IMEI == "") { + setError("No valid UID available for your device. For phones: is your modem online?"); + return; + } + + QSslConfiguration sslConfiguration; + if (!useSslVerify()) + sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); - request.setUrl(QUrl(QString(ssuRegisterUrl) - .arg(IMEI) - )); - request.setSslConfiguration(sslConfiguration); - request.setRawHeader("Authorization", "Basic " + - QByteArray(QString("%1:%2") - .arg(username).arg(password) - .toLatin1()).toBase64()); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + sslConfiguration.setCaCertificates(QSslCertificate::fromPath(ssuCaCertificate)); - QUrl form; + request.setUrl(QUrl(QString(ssuRegisterUrl) + .arg(IMEI) + )); + request.setSslConfiguration(sslConfiguration); + request.setRawHeader("Authorization", "Basic " + + QByteArray(QString("%1:%2") + .arg(username).arg(password) + .toLatin1()).toBase64()); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + QUrl form; #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QUrlQuery q; - q.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION); - q.addQueryItem("deviceModel", deviceInfo.deviceModel()); - if (!domain().isEmpty()){ - q.addQueryItem("domain", domain()); - } - - form.setQuery(q); + QUrlQuery q; + q.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION); + q.addQueryItem("deviceModel", deviceInfo.deviceModel()); + if (!domain().isEmpty()) { + q.addQueryItem("domain", domain()); + } + + form.setQuery(q); #else - form.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION); - form.addQueryItem("deviceModel", deviceInfo.deviceModel()); - if (!domain().isEmpty()){ - form.addQueryItem("domain", domain()); - } + form.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION); + form.addQueryItem("deviceModel", deviceInfo.deviceModel()); + if (!domain().isEmpty()) { + form.addQueryItem("domain", domain()); + } #endif - ssuLog->print(LOG_DEBUG, QString("Sending request to %1") - .arg(request.url().url())); + ssuLog->print(LOG_DEBUG, QString("Sending request to %1") + .arg(request.url().url())); - QNetworkReply *reply; + QNetworkReply *reply; - pendingRequests++; + pendingRequests++; #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - reply = manager->post(request, form.query(QUrl::FullyEncoded).toStdString().c_str()); + reply = manager->post(request, form.query(QUrl::FullyEncoded).toStdString().c_str()); #else - reply = manager->post(request, form.encodedQuery()); + reply = manager->post(request, form.encodedQuery()); #endif - // we could expose downloadProgress() from reply in case we want progress info - - QString homeUrl = settings->value("home-url").toString().arg(username); - if (!homeUrl.isEmpty()){ - // clear header, the other request bits are reusable - request.setHeader(QNetworkRequest::ContentTypeHeader, 0); - request.setUrl(homeUrl + "/authorized_keys"); - ssuLog->print(LOG_DEBUG, QString("Trying to get SSH keys from %1").arg(request.url().toString())); - pendingRequests++; - manager->get(request); - } -} - -bool Ssu::setCredentials(QDomDocument *response){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - // generate list with all scopes for generic section, add sections - QDomNodeList credentialsList = response->elementsByTagName("credentials"); - QStringList credentialScopes; - for (int i=0;ivalue("home-url").toString().arg(username); + if (!homeUrl.isEmpty()) { + // clear header, the other request bits are reusable + request.setHeader(QNetworkRequest::ContentTypeHeader, 0); + request.setUrl(homeUrl + "/authorized_keys"); + ssuLog->print(LOG_DEBUG, QString("Trying to get SSH keys from %1").arg(request.url().toString())); + pendingRequests++; + manager->get(request); } +} - if (node.hasChildNodes()){ - QDomElement username = node.firstChildElement("username"); - QDomElement password = node.firstChildElement("password"); - if (username.isNull() || password.isNull()){ - setError(tr("Username and/or password not set")); - return false; - } else { - settings->beginGroup("credentials-" + scope); - settings->setValue("username", username.text()); - settings->setValue("password", password.text()); - settings->endGroup(); - settings->sync(); - credentialScopes.append(scope); - } - } else { - setError(""); - return false; +bool Ssu::setCredentials(QDomDocument *response) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + // generate list with all scopes for generic section, add sections + QDomNodeList credentialsList = response->elementsByTagName("credentials"); + QStringList credentialScopes; + for (int i = 0; i < credentialsList.size(); i++) { + QDomNode node = credentialsList.at(i); + QString scope; + + QDomNamedNodeMap attributes = node.attributes(); + if (attributes.contains("scope")) { + scope = attributes.namedItem("scope").toAttr().value(); + } else { + setError(tr("Credentials element does not have scope")); + return false; + } + + if (node.hasChildNodes()) { + QDomElement username = node.firstChildElement("username"); + QDomElement password = node.firstChildElement("password"); + if (username.isNull() || password.isNull()) { + setError(tr("Username and/or password not set")); + return false; + } else { + settings->beginGroup("credentials-" + scope); + settings->setValue("username", username.text()); + settings->setValue("password", password.text()); + settings->endGroup(); + settings->sync(); + credentialScopes.append(scope); + } + } else { + setError(""); + return false; + } } - } - settings->setValue("credentialScopes", credentialScopes); - settings->setValue("lastCredentialsUpdate", QDateTime::currentDateTime()); - settings->sync(); - emit credentialsChanged(); + settings->setValue("credentialScopes", credentialScopes); + settings->setValue("lastCredentialsUpdate", QDateTime::currentDateTime()); + settings->sync(); + emit credentialsChanged(); - return true; + return true; } -void Ssu::setError(QString errorMessage){ - errorFlag = true; - errorString = errorMessage; +void Ssu::setError(QString errorMessage) +{ + errorFlag = true; + errorString = errorMessage; - SsuLog *ssuLog = SsuLog::instance(); + SsuLog *ssuLog = SsuLog::instance(); - // dump error message to systemd journal for easier debugging - ssuLog->print(LOG_WARNING, errorMessage); + // dump error message to systemd journal for easier debugging + ssuLog->print(LOG_WARNING, errorMessage); - // assume that we don't even need to wait for other pending requests, - // and just die. This is only relevant for CLI, which will exit after done() - emit done(); + // assume that we don't even need to wait for other pending requests, + // and just die. This is only relevant for CLI, which will exit after done() + emit done(); } -void Ssu::storeAuthorizedKeys(QByteArray data){ - QDir dir; - SsuLog *ssuLog = SsuLog::instance(); - - int uid_min = getdef_num("UID_MIN", -1); - QString homePath; - - if (getuid() >= uid_min){ - homePath = dir.homePath(); - } else if (getuid() == 0){ - // place authorized_keys in the default users home when run with uid0 - struct passwd *pw = getpwuid(uid_min); - if (pw == NULL){ - ssuLog->print(LOG_DEBUG, QString("Unable to find password entry for uid %1") - .arg(uid_min)); - return; - } +void Ssu::storeAuthorizedKeys(QByteArray data) +{ + QDir dir; + SsuLog *ssuLog = SsuLog::instance(); + + int uid_min = getdef_num("UID_MIN", -1); + QString homePath; + + if (getuid() >= uid_min) { + homePath = dir.homePath(); + } else if (getuid() == 0) { + // place authorized_keys in the default users home when run with uid0 + struct passwd *pw = getpwuid(uid_min); + if (pw == NULL) { + ssuLog->print(LOG_DEBUG, QString("Unable to find password entry for uid %1") + .arg(uid_min)); + return; + } + + //homePath = QString(pw->pw_dir); + homePath = pw->pw_dir; + + // use users uid/gid for creating the directories and files + setegid(pw->pw_gid); + seteuid(uid_min); + ssuLog->print(LOG_DEBUG, QString("Dropping to %1/%2 for writing authorized keys") + .arg(uid_min) + .arg(pw->pw_gid)); + } else + return; - //homePath = QString(pw->pw_dir); - homePath = pw->pw_dir; + homePath = Sandbox::map(homePath); - // use users uid/gid for creating the directories and files - setegid(pw->pw_gid); - seteuid(uid_min); - ssuLog->print(LOG_DEBUG, QString("Dropping to %1/%2 for writing authorized keys") - .arg(uid_min) - .arg(pw->pw_gid)); - } else - return; + if (dir.exists(homePath + "/.ssh/authorized_keys")) { + ssuLog->print(LOG_DEBUG, QString(".ssh/authorized_keys already exists in %1") + .arg(homePath)); + restoreUid(); + return; + } - homePath = Sandbox::map(homePath); + if (!dir.exists(homePath + "/.ssh")) + if (!dir.mkdir(homePath + "/.ssh")) { + ssuLog->print(LOG_DEBUG, QString("Unable to create .ssh in %1") + .arg(homePath)); + restoreUid(); + return; + } + + QFile::setPermissions(homePath + "/.ssh", + QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner); + + QFile authorizedKeys(homePath + "/.ssh/authorized_keys"); + authorizedKeys.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + authorizedKeys.setPermissions(QFile::ReadOwner | QFile::WriteOwner); + QTextStream out(&authorizedKeys); + out << data; + out.flush(); + authorizedKeys.close(); - if (dir.exists(homePath + "/.ssh/authorized_keys")){ - ssuLog->print(LOG_DEBUG, QString(".ssh/authorized_keys already exists in %1") - .arg(homePath)); restoreUid(); - return; - } - - if (!dir.exists(homePath + "/.ssh")) - if (!dir.mkdir(homePath + "/.ssh")){ - ssuLog->print(LOG_DEBUG, QString("Unable to create .ssh in %1") - .arg(homePath)); - restoreUid(); - return; - } +} - QFile::setPermissions(homePath + "/.ssh", - QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner); +void Ssu::updateCredentials(bool force) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuDeviceInfo deviceInfo; + errorFlag = false; - QFile authorizedKeys(homePath + "/.ssh/authorized_keys"); - authorizedKeys.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - authorizedKeys.setPermissions(QFile::ReadOwner | QFile::WriteOwner); - QTextStream out(&authorizedKeys); - out << data; - out.flush(); - authorizedKeys.close(); + SsuLog *ssuLog = SsuLog::instance(); - restoreUid(); -} + if (deviceInfo.deviceUid() == "") { + setError("No valid UID available for your device. For phones: is your modem online?"); + return; + } -void Ssu::updateCredentials(bool force){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuDeviceInfo deviceInfo; - errorFlag = false; - - SsuLog *ssuLog = SsuLog::instance(); - - if (deviceInfo.deviceUid() == ""){ - setError("No valid UID available for your device. For phones: is your modem online?"); - return; - } - - QString ssuCaCertificate, ssuCredentialsUrl; - ssuCaCertificate = SsuRepoManager::caCertificatePath(); - if (ssuCaCertificate.isEmpty()){ - setError("CA certificate for ssu not set ('_ca-certificate in domain')"); - return; - } - - if (!settings->contains("credentials-url")){ - ssuCredentialsUrl = repoUrl("credentials-url"); - if (ssuCredentialsUrl.isEmpty()){ - setError("URL for credentials update not set (config key 'credentials-url')"); - return; + QString ssuCaCertificate, ssuCredentialsUrl; + ssuCaCertificate = SsuRepoManager::caCertificatePath(); + if (ssuCaCertificate.isEmpty()) { + setError("CA certificate for ssu not set ('_ca-certificate in domain')"); + return; } - } else - ssuCredentialsUrl = settings->value("credentials-url").toString(); - - if (!isRegistered()){ - setError("Device is not registered."); - return; - } - - if (!force){ - // skip updating if the last update was less than 30 minutes ago - QDateTime now = QDateTime::currentDateTime(); - - if (settings->contains("lastCredentialsUpdate")){ - QDateTime last = settings->value("lastCredentialsUpdate").toDateTime(); - if (last >= now.addSecs(-1800)){ - ssuLog->print(LOG_DEBUG, QString("Skipping credentials update, last update was at %1") - .arg(last.toString())); - emit done(); + + if (!settings->contains("credentials-url")) { + ssuCredentialsUrl = repoUrl("credentials-url"); + if (ssuCredentialsUrl.isEmpty()) { + setError("URL for credentials update not set (config key 'credentials-url')"); + return; + } + } else + ssuCredentialsUrl = settings->value("credentials-url").toString(); + + if (!isRegistered()) { + setError("Device is not registered."); return; - } } - } - // check when the last update was, decide if an update is required - QSslConfiguration sslConfiguration; - if (!useSslVerify()) - sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); + if (!force) { + // skip updating if the last update was less than 30 minutes ago + QDateTime now = QDateTime::currentDateTime(); + + if (settings->contains("lastCredentialsUpdate")) { + QDateTime last = settings->value("lastCredentialsUpdate").toDateTime(); + if (last >= now.addSecs(-1800)) { + ssuLog->print(LOG_DEBUG, QString("Skipping credentials update, last update was at %1") + .arg(last.toString())); + emit done(); + return; + } + } + } + + // check when the last update was, decide if an update is required + QSslConfiguration sslConfiguration; + if (!useSslVerify()) + sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); + + QSslKey privateKey(settings->value("privateKey").toByteArray(), QSsl::Rsa); + QSslCertificate certificate(settings->value("certificate").toByteArray()); - QSslKey privateKey(settings->value("privateKey").toByteArray(), QSsl::Rsa); - QSslCertificate certificate(settings->value("certificate").toByteArray()); + QList caCertificates; + caCertificates << QSslCertificate::fromPath(ssuCaCertificate); + sslConfiguration.setCaCertificates(caCertificates); - QList caCertificates; - caCertificates << QSslCertificate::fromPath(ssuCaCertificate); - sslConfiguration.setCaCertificates(caCertificates); + sslConfiguration.setPrivateKey(privateKey); + sslConfiguration.setLocalCertificate(certificate); - sslConfiguration.setPrivateKey(privateKey); - sslConfiguration.setLocalCertificate(certificate); + QNetworkRequest request; + request.setUrl(QUrl(ssuCredentialsUrl.arg(deviceInfo.deviceUid()))); - QNetworkRequest request; - request.setUrl(QUrl(ssuCredentialsUrl.arg(deviceInfo.deviceUid()))); + ssuLog->print(LOG_DEBUG, QString("Sending credential update request to %1") + .arg(request.url().toString())); + request.setSslConfiguration(sslConfiguration); - ssuLog->print(LOG_DEBUG, QString("Sending credential update request to %1") - .arg(request.url().toString())); - request.setSslConfiguration(sslConfiguration); + pendingRequests++; + manager->get(request); +} - pendingRequests++; - manager->get(request); +void Ssu::updateStoreCredentials() +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuLog *ssuLog = SsuLog::instance(); + + QDBusMessage message = QDBusMessage::createMethodCall("com.jolla.jollastore", + "/StoreClient", + "com.jolla.jollastore", + "storeCredentials"); + QDBusPendingReply reply = SsuCoreConfig::userSessionBus().asyncCall(message); + reply.waitForFinished(); + if (reply.isError()) { + if (settings->value("ignore-credential-errors").toBool() == true) { + ssuLog->print(LOG_WARNING, QString("Warning: ignore-credential-errors is set, passing auth errors down to libzypp")); + ssuLog->print(LOG_WARNING, QString("Store credentials not received. %1").arg(reply.error().message())); + } else + setError(QString("Store credentials not received. %1").arg(reply.error().message())); + } else { + SsuCoreConfig *settings = SsuCoreConfig::instance(); + settings->beginGroup("credentials-store"); + settings->setValue("username", reply.argumentAt<0>()); + settings->setValue("password", reply.argumentAt<1>()); + settings->endGroup(); + settings->sync(); + } } -void Ssu::updateStoreCredentials(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuLog *ssuLog = SsuLog::instance(); - - QDBusMessage message = QDBusMessage::createMethodCall("com.jolla.jollastore", - "/StoreClient", - "com.jolla.jollastore", - "storeCredentials"); - QDBusPendingReply reply = SsuCoreConfig::userSessionBus().asyncCall(message); - reply.waitForFinished(); - if (reply.isError()) { - if (settings->value("ignore-credential-errors").toBool() == true){ - ssuLog->print(LOG_WARNING, QString("Warning: ignore-credential-errors is set, passing auth errors down to libzypp")); - ssuLog->print(LOG_WARNING, QString("Store credentials not received. %1").arg(reply.error().message())); - } else - setError(QString("Store credentials not received. %1").arg(reply.error().message())); - } else { +void Ssu::unregister() +{ SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->beginGroup("credentials-store"); - settings->setValue("username", reply.argumentAt<0>()); - settings->setValue("password", reply.argumentAt<1>()); - settings->endGroup(); + settings->setValue("privateKey", ""); + settings->setValue("certificate", ""); + settings->setValue("registered", false); settings->sync(); - } + emit registrationStatusChanged(); } -void Ssu::unregister(){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - settings->setValue("privateKey", ""); - settings->setValue("certificate", ""); - settings->setValue("registered", false); - settings->sync(); - emit registrationStatusChanged(); -} +bool Ssu::verifyResponse(QDomDocument *response) +{ + QString action = response->elementsByTagName("action").at(0).toElement().text(); + QString deviceId = response->elementsByTagName("deviceId").at(0).toElement().text(); + QString protocolVersion = response->elementsByTagName("protocolVersion").at(0).toElement().text(); + // compare device ids + + if (protocolVersion != SSU_PROTOCOL_VERSION) { + setError( + tr("Response has unsupported protocol version %1, client requires version %2") + .arg(protocolVersion) + .arg(SSU_PROTOCOL_VERSION) + ); + return false; + } -bool Ssu::verifyResponse(QDomDocument *response){ - QString action = response->elementsByTagName("action").at(0).toElement().text(); - QString deviceId = response->elementsByTagName("deviceId").at(0).toElement().text(); - QString protocolVersion = response->elementsByTagName("protocolVersion").at(0).toElement().text(); - // compare device ids - - if (protocolVersion != SSU_PROTOCOL_VERSION){ - setError( - tr("Response has unsupported protocol version %1, client requires version %2") - .arg(protocolVersion) - .arg(SSU_PROTOCOL_VERSION) - ); - return false; - } - - return true; + return true; } diff --git a/libssu/ssu.h b/libssu/ssu.h index 6138c6b..15c4067 100644 --- a/libssu/ssu.h +++ b/libssu/ssu.h @@ -16,20 +16,21 @@ class QNetworkAccessManager; class QNetworkReply; class QDomDocument; -class Ssu: public QObject { +class Ssu: public QObject +{ Q_OBJECT friend class UrlResolverTest; - public: +public: /** * Filters to control the output of the repository lookup methods */ enum RepoFilter { - NoFilter, ///< All repositories (global + user) - UserFilter, ///< Only user configured repositories - BoardFilter, ///< Only global repositories, with user blacklist ignored - BoardFilterUserBlacklist, ///< Only global repositories, with user blacklist applied + NoFilter, ///< All repositories (global + user) + UserFilter, ///< Only user configured repositories + BoardFilter, ///< Only global repositories, with user blacklist ignored + BoardFilterUserBlacklist, ///< Only global repositories, with user blacklist applied }; /** @@ -43,12 +44,12 @@ class Ssu: public QObject { * like in AppInstallMode. */ enum DeviceMode { - DisableRepoManager = 0x1, ///< Disable automagic repository management - RndMode = 0x2, ///< Enable RnD mode for device - ReleaseMode = 0x4, ///< Enable Release mode - LenientMode = 0x8, ///< Disable strict mode (i.e., keep unmanaged repositories) - UpdateMode = 0x10, ///< Do repo isolation and similar bits important for updating devices - AppInstallMode = 0x20 ///< Do repo isolation, but keep store repository enabled + DisableRepoManager = 0x1, ///< Disable automagic repository management + RndMode = 0x2, ///< Enable RnD mode for device + ReleaseMode = 0x4, ///< Enable Release mode + LenientMode = 0x8, ///< Disable strict mode (i.e., keep unmanaged repositories) + UpdateMode = 0x10, ///< Do repo isolation and similar bits important for updating devices + AppInstallMode = 0x20 ///< Do repo isolation, but keep store repository enabled }; Q_DECLARE_FLAGS(DeviceModeFlags, DeviceMode) @@ -57,26 +58,26 @@ class Ssu: public QObject { * A list of types ssu provides shiny values suitable for displaying */ enum DisplayType { - DeviceManufacturer = 0, ///< Manufacturer, like ACME Corp. Board mappings key "deviceManufacturer" - DeviceModel, ///< Marketed device name, like Pogoblaster 3000. Board mappings key "prettyModel" - DeviceDesignation, ///< Type designation, like NCC-1701. Beard mappings key "deviceDesignation" + DeviceManufacturer = 0, ///< Manufacturer, like ACME Corp. Board mappings key "deviceManufacturer" + DeviceModel, ///< Marketed device name, like Pogoblaster 3000. Board mappings key "prettyModel" + DeviceDesignation, ///< Type designation, like NCC-1701. Beard mappings key "deviceDesignation" }; /** * Edit modes for variables containing bitmasks */ enum EditMode { - Replace = 0x1, ///< Replace the old value with the new one - Add = 0x2, ///< Make sure the given value is set in the bitmask - Remove = 0x4, ///< Make sure the given value is not set in the bitmask + Replace = 0x1, ///< Replace the old value with the new one + Add = 0x2, ///< Make sure the given value is set in the bitmask + Remove = 0x4, ///< Make sure the given value is not set in the bitmask }; /** * Return codes to signal success or error conditions */ enum ReturnValue { - Success = 0, - ErrUpdateMode = -10, + Success = 0, + ErrUpdateMode = -10, }; Ssu(); @@ -94,7 +95,7 @@ class Ssu: public QObject { * * @return a string containing the scope; it can be used to look up login credentials using credentials() */ - QString credentialsScope(QString repoName, bool rndRepo=false); + QString credentialsScope(QString repoName, bool rndRepo = false); /** * Return the URL for which credentials scope is valid */ @@ -115,9 +116,9 @@ class Ssu: public QObject { * Resolve a repository url * @return the repository URL on success, an empty string on error */ - QString repoUrl(QString repoName, bool rndRepo=false, - QHash repoParameters=QHash(), - QHash parametersOverride=QHash()); + QString repoUrl(QString repoName, bool rndRepo = false, + QHash repoParameters = QHash(), + QHash parametersOverride = QHash()); /** * Unregister a device. This will clean all registration data from a device, * though will not touch the information on ssu server; the information there @@ -141,19 +142,19 @@ class Ssu: public QObject { /// See SsuCoreConfig::lastCredentialsUpdate Q_INVOKABLE QDateTime lastCredentialsUpdate(); /// See SsuCoreConfig::release - Q_INVOKABLE QString release(bool rnd=false); + Q_INVOKABLE QString release(bool rnd = false); /// See SsuCoreConfig::setDeviceMode - Q_INVOKABLE void setDeviceMode(DeviceModeFlags mode, enum EditMode editMode=Replace); + Q_INVOKABLE void setDeviceMode(DeviceModeFlags mode, enum EditMode editMode = Replace); /// See SsuCoreConfig::setFlavour Q_INVOKABLE void setFlavour(QString flavour); /// See SsuCoreConfig::setRelease - Q_INVOKABLE void setRelease(QString release, bool rnd=false); + Q_INVOKABLE void setRelease(QString release, bool rnd = false); /// See SsuCoreConfig::setDomain Q_INVOKABLE void setDomain(QString domain); /// See SsuCoreConfig::useSslVerify Q_INVOKABLE bool useSslVerify(); - private: +private: QString errorString; bool errorFlag; QNetworkAccessManager *manager; @@ -163,7 +164,7 @@ class Ssu: public QObject { bool verifyResponse(QDomDocument *response); void storeAuthorizedKeys(QByteArray data); - private slots: +private slots: void requestFinished(QNetworkReply *reply); /** * Set errorString returned by lastError to errorMessage, set @@ -171,7 +172,7 @@ class Ssu: public QObject { */ void setError(QString errorMessage); - public slots: +public slots: /** * Attempt RND device registration, using @a username and @a password supplied * @param username Jolla username @@ -193,13 +194,13 @@ class Ssu: public QObject { * error() to check if an error occured, and use lastError() to retrieve the last * error message. */ - void updateCredentials(bool force=false); + void updateCredentials(bool force = false); /** * Try to update credentials for (Jolla) store */ void updateStoreCredentials(); - signals: +signals: /** * Emitted after an asynchronous operation finished */ diff --git a/libssu/ssucoreconfig.cpp b/libssu/ssucoreconfig.cpp index b9bb371..1419936 100644 --- a/libssu/ssucoreconfig.cpp +++ b/libssu/ssucoreconfig.cpp @@ -17,141 +17,157 @@ SsuCoreConfig *SsuCoreConfig::ssuCoreConfig = 0; -SsuCoreConfig *SsuCoreConfig::instance(){ - if (!ssuCoreConfig) - ssuCoreConfig = new SsuCoreConfig(); +SsuCoreConfig *SsuCoreConfig::instance() +{ + if (!ssuCoreConfig) + ssuCoreConfig = new SsuCoreConfig(); - return ssuCoreConfig; + return ssuCoreConfig; } -QPair SsuCoreConfig::credentials(QString scope){ - QPair ret; - beginGroup("credentials-" + scope); - ret.first = value("username").toString(); - ret.second = value("password").toString(); - endGroup(); - return ret; +QPair SsuCoreConfig::credentials(QString scope) +{ + QPair ret; + beginGroup("credentials-" + scope); + ret.first = value("username").toString(); + ret.second = value("password").toString(); + endGroup(); + return ret; } -QString SsuCoreConfig::credentialsScope(QString repoName, bool rndRepo){ - if (contains("credentials-scope")) - return value("credentials-scope").toString(); - else - return "your-configuration-is-broken-and-does-not-contain-credentials-scope"; -} - -QString SsuCoreConfig::credentialsUrl(QString scope){ - if (contains("credentials-url-" + scope)) - return value("credentials-url-" + scope).toString(); - else - return "your-configuration-is-broken-and-does-not-contain-credentials-url-for-" + scope; +QString SsuCoreConfig::credentialsScope(QString repoName, bool rndRepo) +{ + if (contains("credentials-scope")) + return value("credentials-scope").toString(); + else + return "your-configuration-is-broken-and-does-not-contain-credentials-scope"; } -QString SsuCoreConfig::flavour(){ - if (contains("flavour")) - return value("flavour").toString(); - else - return "release"; +QString SsuCoreConfig::credentialsUrl(QString scope) +{ + if (contains("credentials-url-" + scope)) + return value("credentials-url-" + scope).toString(); + else + return "your-configuration-is-broken-and-does-not-contain-credentials-url-for-" + scope; } -Ssu::DeviceModeFlags SsuCoreConfig::deviceMode(){ - if (!contains("deviceMode")) - return Ssu::ReleaseMode; - else - return Ssu::DeviceModeFlags(value("deviceMode").toInt()); +QString SsuCoreConfig::flavour() +{ + if (contains("flavour")) + return value("flavour").toString(); + else + return "release"; } -QString SsuCoreConfig::domain(bool pretty){ - if (contains("domain")){ - if (pretty) - return value("domain").toString().replace(":", "-"); +Ssu::DeviceModeFlags SsuCoreConfig::deviceMode() +{ + if (!contains("deviceMode")) + return Ssu::ReleaseMode; else - return value("domain").toString(); - } else - return ""; + return Ssu::DeviceModeFlags(value("deviceMode").toInt()); } -bool SsuCoreConfig::isRegistered(){ - if (!contains("privateKey")) - return false; - if (!contains("certificate")) - return false; - return value("registered").toBool(); +QString SsuCoreConfig::domain(bool pretty) +{ + if (contains("domain")) { + if (pretty) + return value("domain").toString().replace(":", "-"); + else + return value("domain").toString(); + } else + return ""; } -QDateTime SsuCoreConfig::lastCredentialsUpdate(){ - return value("lastCredentialsUpdate").toDateTime(); +bool SsuCoreConfig::isRegistered() +{ + if (!contains("privateKey")) + return false; + if (!contains("certificate")) + return false; + return value("registered").toBool(); } -QString SsuCoreConfig::release(bool rnd){ - if (rnd) - return value("rndRelease").toString(); - else - return value("release").toString(); +QDateTime SsuCoreConfig::lastCredentialsUpdate() +{ + return value("lastCredentialsUpdate").toDateTime(); } -void SsuCoreConfig::setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode){ - int oldMode = value("deviceMode").toInt(); +QString SsuCoreConfig::release(bool rnd) +{ + if (rnd) + return value("rndRelease").toString(); + else + return value("release").toString(); +} - if ((editMode & Ssu::Add) == Ssu::Add){ - oldMode |= mode; - } else if ((editMode & Ssu::Remove) == Ssu::Remove){ - oldMode &= ~mode; - } else - oldMode = mode; +void SsuCoreConfig::setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode) +{ + int oldMode = value("deviceMode").toInt(); - setValue("deviceMode", oldMode); - sync(); -} + if ((editMode & Ssu::Add) == Ssu::Add) { + oldMode |= mode; + } else if ((editMode & Ssu::Remove) == Ssu::Remove) { + oldMode &= ~mode; + } else + oldMode = mode; -void SsuCoreConfig::setFlavour(QString flavour){ - setValue("flavour", flavour); - // flavour is RnD only, so enable RnD mode - setDeviceMode(Ssu::RndMode, Ssu::Add); - sync(); + setValue("deviceMode", oldMode); + sync(); } -void SsuCoreConfig::setRelease(QString release, bool rnd){ - if (rnd) { - setValue("rndRelease", release); - // switch rndMode on/off when setting releases +void SsuCoreConfig::setFlavour(QString flavour) +{ + setValue("flavour", flavour); + // flavour is RnD only, so enable RnD mode setDeviceMode(Ssu::RndMode, Ssu::Add); - } else { - setValue("release", release); - setDeviceMode(Ssu::RndMode, Ssu::Remove); - } - sync(); -} - -void SsuCoreConfig::setDomain(QString domain){ - // - in domain messes with default section autodetection, - // so change it to : - setValue("domain", domain.replace("-", ":")); - sync(); -} - -bool SsuCoreConfig::useSslVerify(){ - if (contains("ssl-verify")) - return value("ssl-verify").toBool(); - else - return true; -} - -QDBusConnection SsuCoreConfig::userSessionBus(){ - int uid_min = getdef_num("UID_MIN", -1); - - // For calls from valid UID we assume that they are properly logged in users. - // If they are not the call will fail, but it's their fault. - if (getuid() >= uid_min){ - return QDBusConnection::sessionBus(); - } else { - // DBus security policy will prevent this beeing used by callers other - // than root at the moment. Still do it generic in case DBus policy will - // be extended later, and just use the usual 'DBus: THOU SHALL NOT PASS!' - // @TODO the uid to be used should be determined using the logind API from - // systemd package to support multiuser systems in the future - QString sessionBusAddress=QString("unix:path=/run/user/%1/dbus/user_bus_socket") - .arg(uid_min); - return QDBusConnection::connectToBus(sessionBusAddress, "userSessionBus"); - } + sync(); +} + +void SsuCoreConfig::setRelease(QString release, bool rnd) +{ + if (rnd) { + setValue("rndRelease", release); + // switch rndMode on/off when setting releases + setDeviceMode(Ssu::RndMode, Ssu::Add); + } else { + setValue("release", release); + setDeviceMode(Ssu::RndMode, Ssu::Remove); + } + sync(); +} + +void SsuCoreConfig::setDomain(QString domain) +{ + // - in domain messes with default section autodetection, + // so change it to : + setValue("domain", domain.replace("-", ":")); + sync(); +} + +bool SsuCoreConfig::useSslVerify() +{ + if (contains("ssl-verify")) + return value("ssl-verify").toBool(); + else + return true; +} + +QDBusConnection SsuCoreConfig::userSessionBus() +{ + int uid_min = getdef_num("UID_MIN", -1); + + // For calls from valid UID we assume that they are properly logged in users. + // If they are not the call will fail, but it's their fault. + if (getuid() >= uid_min) { + return QDBusConnection::sessionBus(); + } else { + // DBus security policy will prevent this beeing used by callers other + // than root at the moment. Still do it generic in case DBus policy will + // be extended later, and just use the usual 'DBus: THOU SHALL NOT PASS!' + // @TODO the uid to be used should be determined using the logind API from + // systemd package to support multiuser systems in the future + QString sessionBusAddress = QString("unix:path=/run/user/%1/dbus/user_bus_socket") + .arg(uid_min); + return QDBusConnection::connectToBus(sessionBusAddress, "userSessionBus"); + } } diff --git a/libssu/ssucoreconfig_p.h b/libssu/ssucoreconfig_p.h index a41aa98..e6f5170 100644 --- a/libssu/ssucoreconfig_p.h +++ b/libssu/ssucoreconfig_p.h @@ -24,10 +24,11 @@ class QDBusConnection; -class SsuCoreConfig: public SsuSettings { +class SsuCoreConfig: public SsuSettings +{ Q_OBJECT - public: +public: static SsuCoreConfig *instance(); /** * Find a username/password pair for the given scope @@ -43,7 +44,7 @@ class SsuCoreConfig: public SsuSettings { * * @return a string containing the scope; it can be used to look up login credentials using credentials() */ - QString credentialsScope(QString repoName, bool rndRepo=false); + QString credentialsScope(QString repoName, bool rndRepo = false); /** * Return the URL for which credentials scope is valid */ @@ -63,7 +64,7 @@ class SsuCoreConfig: public SsuSettings { * to print the domain name set pretty to true * @return domain, or "" if not set */ - Q_INVOKABLE QString domain(bool pretty=false); + Q_INVOKABLE QString domain(bool pretty = false); /** * Return devices RND registration status * @retval true device is registered @@ -78,11 +79,11 @@ class SsuCoreConfig: public SsuSettings { /** * Return the release version string for either a release, or a RnD snapshot */ - Q_INVOKABLE QString release(bool rnd=false); + Q_INVOKABLE QString release(bool rnd = false); /** * Set mode bits for the device */ - Q_INVOKABLE void setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode=Ssu::Replace); + Q_INVOKABLE void setDeviceMode(Ssu::DeviceModeFlags mode, enum Ssu::EditMode editMode = Ssu::Replace); /** * Set the flavour used when resolving RND repositories */ @@ -90,7 +91,7 @@ class SsuCoreConfig: public SsuSettings { /** * Set the release version string for either a release, or a RnD snapshot */ - Q_INVOKABLE void setRelease(QString release, bool rnd=false); + Q_INVOKABLE void setRelease(QString release, bool rnd = false); /** * Set the domain string (usually something like nemo, jolla, ..) */ @@ -107,7 +108,7 @@ class SsuCoreConfig: public SsuSettings { static QDBusConnection userSessionBus(); - private: +private: SsuCoreConfig(): SsuSettings(SSU_CONFIGURATION, QSettings::IniFormat, SSU_DEFAULT_CONFIGURATION) {}; SsuCoreConfig(const SsuCoreConfig &); // hide copy constructor diff --git a/libssu/ssudeviceinfo.cpp b/libssu/ssudeviceinfo.cpp index 311d5a0..3da4c0f 100644 --- a/libssu/ssudeviceinfo.cpp +++ b/libssu/ssudeviceinfo.cpp @@ -23,226 +23,234 @@ #include "../constants.h" -SsuDeviceInfo::SsuDeviceInfo(QString model): QObject(){ +SsuDeviceInfo::SsuDeviceInfo(QString model): QObject() +{ boardMappings = new SsuSettings(SSU_BOARD_MAPPING_CONFIGURATION, SSU_BOARD_MAPPING_CONFIGURATION_DIR); if (!model.isEmpty()) - cachedModel = model; + cachedModel = model; } -QStringList SsuDeviceInfo::adaptationRepos(){ - QStringList result; +QStringList SsuDeviceInfo::adaptationRepos() +{ + QStringList result; - QString model = deviceVariant(true); + QString model = deviceVariant(true); - if (boardMappings->contains(model + "/adaptation-repos")) - result = boardMappings->value(model + "/adaptation-repos").toStringList(); + if (boardMappings->contains(model + "/adaptation-repos")) + result = boardMappings->value(model + "/adaptation-repos").toStringList(); - return result; + return result; } -QString SsuDeviceInfo::adaptationVariables(const QString &adaptationName, QHash *storageHash){ - SsuLog *ssuLog = SsuLog::instance(); - QStringList adaptationRepoList = adaptationRepos(); - // special handling for adaptation-repositories - // - check if repo is in right format (adaptation\d*) - // - check if the configuration has that many adaptation repos - // - export the entry in the adaptation list as %(adaptation) - // - look up variables for that adaptation, and export matching - // adaptation variable - QRegExp regex("adaptation\\\d*", Qt::CaseSensitive, QRegExp::RegExp2); - if (regex.exactMatch(adaptationName)){ - regex.setPattern("\\\d*"); - regex.lastIndexIn(adaptationName); - int n = regex.cap().toInt(); - - if (!adaptationRepoList.isEmpty()){ - if (adaptationRepoList.size() <= n) { - ssuLog->print(LOG_INFO, "Note: repo index out of bounds, substituting 0" + adaptationName); - n = 0; - } - - QString adaptationRepo = adaptationRepoList.at(n); - storageHash->insert("adaptation", adaptationRepo); - ssuLog->print(LOG_DEBUG, "Found first adaptation " + adaptationName); - - QString model = deviceVariant(true); - QHash h; - - // add global variables for this model - if (boardMappings->contains(model + "/variables")){ - QStringList sections = boardMappings->value(model + "/variables").toStringList(); - foreach(const QString §ion, sections) - variableSection(section, &h); - } - - // override with variables specific to this repository - variableSection(adaptationRepo, &h); - - QHash::const_iterator i = h.constBegin(); - while (i != h.constEnd()){ - storageHash->insert(i.key(), i.value()); - i++; - } - } else - ssuLog->print(LOG_INFO, "Note: adaptation repo for invalid repo requested " + adaptationName); - - return "adaptation"; - } - return adaptationName; +QString SsuDeviceInfo::adaptationVariables(const QString &adaptationName, QHash *storageHash) +{ + SsuLog *ssuLog = SsuLog::instance(); + QStringList adaptationRepoList = adaptationRepos(); + // special handling for adaptation-repositories + // - check if repo is in right format (adaptation\d*) + // - check if the configuration has that many adaptation repos + // - export the entry in the adaptation list as %(adaptation) + // - look up variables for that adaptation, and export matching + // adaptation variable + QRegExp regex("adaptation\\\d*", Qt::CaseSensitive, QRegExp::RegExp2); + if (regex.exactMatch(adaptationName)) { + regex.setPattern("\\\d*"); + regex.lastIndexIn(adaptationName); + int n = regex.cap().toInt(); + + if (!adaptationRepoList.isEmpty()) { + if (adaptationRepoList.size() <= n) { + ssuLog->print(LOG_INFO, "Note: repo index out of bounds, substituting 0" + adaptationName); + n = 0; + } + + QString adaptationRepo = adaptationRepoList.at(n); + storageHash->insert("adaptation", adaptationRepo); + ssuLog->print(LOG_DEBUG, "Found first adaptation " + adaptationName); + + QString model = deviceVariant(true); + QHash h; + + // add global variables for this model + if (boardMappings->contains(model + "/variables")) { + QStringList sections = boardMappings->value(model + "/variables").toStringList(); + foreach (const QString §ion, sections) + variableSection(section, &h); + } + + // override with variables specific to this repository + variableSection(adaptationRepo, &h); + + QHash::const_iterator i = h.constBegin(); + while (i != h.constEnd()) { + storageHash->insert(i.key(), i.value()); + i++; + } + } else + ssuLog->print(LOG_INFO, "Note: adaptation repo for invalid repo requested " + adaptationName); + + return "adaptation"; + } + return adaptationName; } -void SsuDeviceInfo::clearCache(){ - cachedFamily = ""; - cachedModel = ""; - cachedVariant = ""; +void SsuDeviceInfo::clearCache() +{ + cachedFamily = ""; + cachedModel = ""; + cachedVariant = ""; } -bool SsuDeviceInfo::contains(const QString &model){ - QString oldModel = deviceModel(); - bool found = false; - - if (!model.isEmpty()){ - clearCache(); - setDeviceModel(model); - } - - if (!deviceVariant(false).isEmpty()) - found = true; - if (boardMappings->childGroups().contains(deviceModel())) - found = true; - - if (!model.isEmpty()){ - clearCache(); - setDeviceModel(oldModel); - } - return found; +bool SsuDeviceInfo::contains(const QString &model) +{ + QString oldModel = deviceModel(); + bool found = false; + + if (!model.isEmpty()) { + clearCache(); + setDeviceModel(model); + } + + if (!deviceVariant(false).isEmpty()) + found = true; + if (boardMappings->childGroups().contains(deviceModel())) + found = true; + + if (!model.isEmpty()) { + clearCache(); + setDeviceModel(oldModel); + } + return found; } -QString SsuDeviceInfo::deviceFamily(){ - if (!cachedFamily.isEmpty()) - return cachedFamily; +QString SsuDeviceInfo::deviceFamily() +{ + if (!cachedFamily.isEmpty()) + return cachedFamily; - QString model = deviceVariant(true); + QString model = deviceVariant(true); - cachedFamily = "UNKNOWN"; + cachedFamily = "UNKNOWN"; - if (boardMappings->contains(model + "/family")) - cachedFamily = boardMappings->value(model + "/family").toString(); + if (boardMappings->contains(model + "/family")) + cachedFamily = boardMappings->value(model + "/family").toString(); - return cachedFamily; + return cachedFamily; } -QString SsuDeviceInfo::deviceVariant(bool fallback){ - if (!cachedVariant.isEmpty()) - return cachedVariant; +QString SsuDeviceInfo::deviceVariant(bool fallback) +{ + if (!cachedVariant.isEmpty()) + return cachedVariant; - cachedVariant = ""; + cachedVariant = ""; - if (boardMappings->contains("variants/" + deviceModel())) { - cachedVariant = boardMappings->value("variants/" + deviceModel()).toString(); - } + if (boardMappings->contains("variants/" + deviceModel())) { + cachedVariant = boardMappings->value("variants/" + deviceModel()).toString(); + } - if (cachedVariant == "" && fallback) - return deviceModel(); + if (cachedVariant == "" && fallback) + return deviceModel(); - return cachedVariant; + return cachedVariant; } -QString SsuDeviceInfo::deviceModel(){ - QDir dir; - QFile procCpuinfo; - QStringList keys; - - if (!cachedModel.isEmpty()) - return cachedModel; +QString SsuDeviceInfo::deviceModel() +{ + QDir dir; + QFile procCpuinfo; + QStringList keys; - boardMappings->beginGroup("file.exists"); - keys = boardMappings->allKeys(); + if (!cachedModel.isEmpty()) + return cachedModel; - // check if the device can be identified by testing for a file - foreach (const QString &key, keys){ - QString value = boardMappings->value(key).toString(); - if (dir.exists(Sandbox::map(value))){ - cachedModel = key; - break; - } - } - boardMappings->endGroup(); - if (!cachedModel.isEmpty()) return cachedModel; - - // check if the device can be identified by a string in /proc/cpuinfo - procCpuinfo.setFileName(Sandbox::map("/proc/cpuinfo")); - procCpuinfo.open(QIODevice::ReadOnly | QIODevice::Text); - if (procCpuinfo.isOpen()){ - QTextStream in(&procCpuinfo); - QString cpuinfo = in.readAll(); - boardMappings->beginGroup("cpuinfo.contains"); + boardMappings->beginGroup("file.exists"); keys = boardMappings->allKeys(); - foreach (const QString &key, keys){ - QString value = boardMappings->value(key).toString(); - if (cpuinfo.contains(value)){ - cachedModel = key; - break; - } + // check if the device can be identified by testing for a file + foreach (const QString &key, keys) { + QString value = boardMappings->value(key).toString(); + if (dir.exists(Sandbox::map(value))) { + cachedModel = key; + break; + } } boardMappings->endGroup(); - } - if (!cachedModel.isEmpty()) return cachedModel; + if (!cachedModel.isEmpty()) return cachedModel; + + // check if the device can be identified by a string in /proc/cpuinfo + procCpuinfo.setFileName(Sandbox::map("/proc/cpuinfo")); + procCpuinfo.open(QIODevice::ReadOnly | QIODevice::Text); + if (procCpuinfo.isOpen()) { + QTextStream in(&procCpuinfo); + QString cpuinfo = in.readAll(); + boardMappings->beginGroup("cpuinfo.contains"); + keys = boardMappings->allKeys(); + + foreach (const QString &key, keys) { + QString value = boardMappings->value(key).toString(); + if (cpuinfo.contains(value)) { + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + } + if (!cachedModel.isEmpty()) return cachedModel; + + // mer-hybris adaptations: /etc/hw-release MER_HA_DEVICE variable + QString hwReleaseDevice = hwRelease()["MER_HA_DEVICE"]; + if (!hwReleaseDevice.isEmpty()) { + boardMappings->beginGroup("hwrelease.device"); + keys = boardMappings->allKeys(); + + foreach (const QString &key, keys) { + QString value = boardMappings->value(key).toString(); + if (hwReleaseDevice == value) { + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + } + if (!cachedModel.isEmpty()) return cachedModel; + + // check if the device can be identified by the kernel version string + struct utsname buf; + if (!uname(&buf)) { + QString utsRelease(buf.release); + boardMappings->beginGroup("uname-release.contains"); + keys = boardMappings->allKeys(); + + foreach (const QString &key, keys) { + QString value = boardMappings->value(key).toString(); + if (utsRelease.contains(value)) { + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + } + if (!cachedModel.isEmpty()) return cachedModel; - // mer-hybris adaptations: /etc/hw-release MER_HA_DEVICE variable - QString hwReleaseDevice = hwRelease()["MER_HA_DEVICE"]; - if (!hwReleaseDevice.isEmpty()) { - boardMappings->beginGroup("hwrelease.device"); + // check if there's a match on arch of generic fallback. This probably + // only makes sense for x86 + boardMappings->beginGroup("arch.equals"); keys = boardMappings->allKeys(); + SsuCoreConfig *settings = SsuCoreConfig::instance(); foreach (const QString &key, keys) { - QString value = boardMappings->value(key).toString(); - if (hwReleaseDevice == value) { - cachedModel = key; - break; - } - } - boardMappings->endGroup(); - } - if (!cachedModel.isEmpty()) return cachedModel; - - // check if the device can be identified by the kernel version string - struct utsname buf; - if (!uname(&buf)){ - QString utsRelease(buf.release); - boardMappings->beginGroup("uname-release.contains"); - keys = boardMappings->allKeys(); - - foreach (const QString &key, keys){ - QString value = boardMappings->value(key).toString(); - if (utsRelease.contains(value)){ - cachedModel = key; - break; - } + QString value = boardMappings->value(key).toString(); + if (settings->value("arch").toString() == value) { + cachedModel = key; + break; + } } boardMappings->endGroup(); - } - if (!cachedModel.isEmpty()) return cachedModel; - - // check if there's a match on arch of generic fallback. This probably - // only makes sense for x86 - boardMappings->beginGroup("arch.equals"); - keys = boardMappings->allKeys(); - - SsuCoreConfig *settings = SsuCoreConfig::instance(); - foreach (const QString &key, keys){ - QString value = boardMappings->value(key).toString(); - if (settings->value("arch").toString() == value){ - cachedModel = key; - break; - } - } - boardMappings->endGroup(); - if (cachedModel.isEmpty()) cachedModel = "UNKNOWN"; + if (cachedModel.isEmpty()) cachedModel = "UNKNOWN"; - return cachedModel; + return cachedModel; } static QStringList @@ -251,8 +259,8 @@ ofonoGetImeis() QStringList result; QDBusMessage reply = QDBusConnection::systemBus().call( - QDBusMessage::createMethodCall("org.ofono", "/", - "org.nemomobile.ofono.ModemManager", "GetIMEI")); + QDBusMessage::createMethodCall("org.ofono", "/", + "org.nemomobile.ofono.ModemManager", "GetIMEI")); QList arguments = reply.arguments(); if (arguments.count() > 0) { @@ -269,7 +277,7 @@ getWlanMacs() QStringList result; QStringList dirs = QDir(QLatin1String("/sys/class/net/")) - .entryList(QStringList() << QLatin1String("wlan*")); + .entryList(QStringList() << QLatin1String("wlan*")); foreach (const QString &dir, dirs) { QFile carrier(QString("/sys/class/net/%1/address").arg(dir)); if (carrier.open(QIODevice::ReadOnly)) { @@ -280,247 +288,255 @@ getWlanMacs() } static QString -normalizeUid(const QString& uid) +normalizeUid(const QString &uid) { // Normalize by stripping colons, dashes and making it lowercase return uid.trimmed().replace(":", "").replace("-", "").toLower(); } -QString SsuDeviceInfo::deviceUid(){ - SsuLog *ssuLog = SsuLog::instance(); - QStringList imeis = ofonoGetImeis(); - if (imeis.size() > 0) { - return imeis[0]; - } - - QStringList wlanMacs = getWlanMacs(); - if (wlanMacs.size() > 0) { - return normalizeUid(wlanMacs[0]); - } - - ssuLog->print(LOG_WARNING, "Could not get IMEI(s) from ofono, nor WLAN mac, trying fallback"); - - // The fallback list is taken from QtSystems' qdeviceinfo_linux.cpp - QStringList fallbackFiles; - fallbackFiles << "/sys/devices/virtual/dmi/id/product_uuid"; - fallbackFiles << "/etc/machine-id"; - fallbackFiles << "/etc/unique-id"; - fallbackFiles << "/var/lib/dbus/machine-id"; - - foreach (const QString &filename, fallbackFiles) { - QFile machineId(filename); - if (machineId.open(QFile::ReadOnly | QFile::Text)) { - QTextStream in(&machineId); - return normalizeUid(in.readAll()); - } - } - - ssuLog->print(LOG_CRIT, "Could not read fallback UID - returning empty string"); - return ""; +QString SsuDeviceInfo::deviceUid() +{ + SsuLog *ssuLog = SsuLog::instance(); + QStringList imeis = ofonoGetImeis(); + if (imeis.size() > 0) { + return imeis[0]; + } + + QStringList wlanMacs = getWlanMacs(); + if (wlanMacs.size() > 0) { + return normalizeUid(wlanMacs[0]); + } + + ssuLog->print(LOG_WARNING, "Could not get IMEI(s) from ofono, nor WLAN mac, trying fallback"); + + // The fallback list is taken from QtSystems' qdeviceinfo_linux.cpp + QStringList fallbackFiles; + fallbackFiles << "/sys/devices/virtual/dmi/id/product_uuid"; + fallbackFiles << "/etc/machine-id"; + fallbackFiles << "/etc/unique-id"; + fallbackFiles << "/var/lib/dbus/machine-id"; + + foreach (const QString &filename, fallbackFiles) { + QFile machineId(filename); + if (machineId.open(QFile::ReadOnly | QFile::Text)) { + QTextStream in(&machineId); + return normalizeUid(in.readAll()); + } + } + + ssuLog->print(LOG_CRIT, "Could not read fallback UID - returning empty string"); + return ""; } -QStringList SsuDeviceInfo::disabledRepos(){ - QStringList result; +QStringList SsuDeviceInfo::disabledRepos() +{ + QStringList result; - QString model = deviceVariant(true); + QString model = deviceVariant(true); - if (boardMappings->contains(model + "/disabled-repos")) - result = boardMappings->value(model + "/disabled-repos").toStringList(); + if (boardMappings->contains(model + "/disabled-repos")) + result = boardMappings->value(model + "/disabled-repos").toStringList(); - return result; + return result; } -QString SsuDeviceInfo::displayName(const int type){ - QString model = deviceModel(); - QString variant = deviceVariant(false); - QString value, key; +QString SsuDeviceInfo::displayName(const int type) +{ + QString model = deviceModel(); + QString variant = deviceVariant(false); + QString value, key; - switch (type){ + switch (type) { case Ssu::DeviceManufacturer: - key = "/deviceManufacturer"; - break; + key = "/deviceManufacturer"; + break; case Ssu::DeviceModel: - key = "/prettyModel"; - break; + key = "/prettyModel"; + break; case Ssu::DeviceDesignation: - key = "/deviceDesignation"; - break; + key = "/deviceDesignation"; + break; default: - return ""; - } - - /* - * Go through different levels of fallbacks: - * 1. model specific setting - * 2. variant specific setting - * 3. global setting - * 4. return model name, or "UNKNOWN" in case query was for manufacturer - */ - - if (boardMappings->contains(model + key)) - value = boardMappings->value(model + key).toString(); - else if (variant != "" && boardMappings->contains(variant + key)) - value = boardMappings->value(variant + key).toString(); - else if (boardMappings->contains(key)) - value = boardMappings->value(key).toString(); - else if (type != Ssu::DeviceManufacturer) - value = model; - else - value = "UNKNOWN"; - - return value; + return ""; + } + + /* + * Go through different levels of fallbacks: + * 1. model specific setting + * 2. variant specific setting + * 3. global setting + * 4. return model name, or "UNKNOWN" in case query was for manufacturer + */ + + if (boardMappings->contains(model + key)) + value = boardMappings->value(model + key).toString(); + else if (variant != "" && boardMappings->contains(variant + key)) + value = boardMappings->value(variant + key).toString(); + else if (boardMappings->contains(key)) + value = boardMappings->value(key).toString(); + else if (type != Ssu::DeviceManufacturer) + value = model; + else + value = "UNKNOWN"; + + return value; } // this half belongs into repo-manager, as it not only handles board-specific // repositories. Right now this one looks like the better place due to the // connection to board specific stuff, though -QStringList SsuDeviceInfo::repos(bool rnd, int filter){ - int adaptationCount = adaptationRepos().size(); - QStringList result; - - - ///@TODO move this to a hash, containing repo and enabled|disabled - /// write repos with enabled/disabled to disks - /// for the compat functions providing a stringlist, do the filtering - /// run only when creating the list, based on the enabled|disabled flags - if (filter == Ssu::NoFilter || - filter == Ssu::BoardFilter || - filter == Ssu::BoardFilterUserBlacklist){ - // for repo names we have adaptation0, adaptation1, ..., adaptationN - for (int i=0; icontains(deviceVariant(true) + "/repos")) - result.append(boardMappings->value(deviceVariant(true) + "/repos").toStringList()); - - // add device configured repos only valid for rnd and/or release - repoKey = (rnd ? "/repos-rnd" : "/repos-release"); - if (boardMappings->contains(deviceVariant(true) + repoKey)) - result.append(boardMappings->value(deviceVariant(true) + repoKey).toStringList()); - - // read the disabled repositories for this device - // user can override repositories disabled here in the user configuration - foreach (const QString &key, disabledRepos()) - result.removeAll(key); - } - - result.removeDuplicates(); - return result; +QStringList SsuDeviceInfo::repos(bool rnd, int filter) +{ + int adaptationCount = adaptationRepos().size(); + QStringList result; + + + ///@TODO move this to a hash, containing repo and enabled|disabled + /// write repos with enabled/disabled to disks + /// for the compat functions providing a stringlist, do the filtering + /// run only when creating the list, based on the enabled|disabled flags + if (filter == Ssu::NoFilter || + filter == Ssu::BoardFilter || + filter == Ssu::BoardFilterUserBlacklist) { + // for repo names we have adaptation0, adaptation1, ..., adaptationN + for (int i = 0; i < adaptationCount; i++) + result.append(QString("adaptation%1").arg(i)); + + // now read the release/rnd repos + SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); + QString repoKey = (rnd ? "default-repos/rnd" : "default-repos/release"); + if (repoSettings.contains(repoKey)) + result.append(repoSettings.value(repoKey).toStringList()); + + // TODO: add specific repos (developer, sdk, ..) + + // add device configured repos + if (boardMappings->contains(deviceVariant(true) + "/repos")) + result.append(boardMappings->value(deviceVariant(true) + "/repos").toStringList()); + + // add device configured repos only valid for rnd and/or release + repoKey = (rnd ? "/repos-rnd" : "/repos-release"); + if (boardMappings->contains(deviceVariant(true) + repoKey)) + result.append(boardMappings->value(deviceVariant(true) + repoKey).toStringList()); + + // read the disabled repositories for this device + // user can override repositories disabled here in the user configuration + foreach (const QString &key, disabledRepos()) + result.removeAll(key); + } + + result.removeDuplicates(); + return result; } -QVariant SsuDeviceInfo::variable(QString section, const QString &key){ - /// @todo compat-setting as ssudeviceinfo guaranteed to prepend sections with var-; - /// SsuVariables does not have this guarantee. Remove from here as well. - if (!section.startsWith("var-")) - section = "var-" + section; +QVariant SsuDeviceInfo::variable(QString section, const QString &key) +{ + /// @todo compat-setting as ssudeviceinfo guaranteed to prepend sections with var-; + /// SsuVariables does not have this guarantee. Remove from here as well. + if (!section.startsWith("var-")) + section = "var-" + section; - return SsuVariables::variable(boardMappings, section, key); + return SsuVariables::variable(boardMappings, section, key); } -void SsuDeviceInfo::variableSection(QString section, QHash *storageHash){ - if (!section.startsWith("var-")) - section = "var-" + section; +void SsuDeviceInfo::variableSection(QString section, QHash *storageHash) +{ + if (!section.startsWith("var-")) + section = "var-" + section; - SsuVariables::variableSection(boardMappings, section, storageHash); + SsuVariables::variableSection(boardMappings, section, storageHash); } -void SsuDeviceInfo::setDeviceModel(QString model){ - if (model == "") - cachedModel = ""; - else - cachedModel = model; +void SsuDeviceInfo::setDeviceModel(QString model) +{ + if (model == "") + cachedModel = ""; + else + cachedModel = model; - cachedFamily = ""; - cachedVariant = ""; + cachedFamily = ""; + cachedVariant = ""; } -QVariant SsuDeviceInfo::value(const QString &key, const QVariant &value){ - if (boardMappings->contains(deviceModel()+"/"+key)){ - return boardMappings->value(deviceModel()+"/"+key); - } else if (boardMappings->contains(deviceVariant()+"/"+key)){ - return boardMappings->value(deviceVariant()+"/"+key); - } +QVariant SsuDeviceInfo::value(const QString &key, const QVariant &value) +{ + if (boardMappings->contains(deviceModel() + "/" + key)) { + return boardMappings->value(deviceModel() + "/" + key); + } else if (boardMappings->contains(deviceVariant() + "/" + key)) { + return boardMappings->value(deviceVariant() + "/" + key); + } - return value; + return value; } QMap SsuDeviceInfo::hwRelease() { - QMap result; - - // Specification of the format, encoding is similar to /etc/os-release - // http://www.freedesktop.org/software/systemd/man/os-release.html - - QFile hwRelease("/etc/hw-release"); - if (hwRelease.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&hwRelease); - - // "All strings should be in UTF-8 format, and non-printable characters - // should not be used." - in.setCodec("UTF-8"); - - while (!in.atEnd()) { - QString line = in.readLine(); - - // "Lines beginning with "#" shall be ignored as comments." - if (line.startsWith('#')) { - continue; - } - - QString key = line.section('=', 0, 0); - QString value = line.section('=', 1); - - // Remove trailing whitespace in value - value = value.trimmed(); - - // POSIX.1-2001 says uppercase, digits and underscores. - // - // Bash uses "[a-zA-Z_]+[a-zA-Z0-9_]*", so we'll use that too, - // as we can safely assume that "shell-compatible variable - // assignments" means it should be compatible with bash. - // - // see http://stackoverflow.com/a/2821183 - // and http://stackoverflow.com/a/2821201 - if (!QRegExp("[a-zA-Z_]+[a-zA-Z0-9_]*").exactMatch(key)) { - qWarning("Invalid key in input line: '%s'", qPrintable(line)); - continue; - } - - // "Variable assignment values should be enclosed in double or - // single quotes if they include spaces, semicolons or other - // special characters outside of A-Z, a-z, 0-9." - if (((value.at(0) == '\'') || (value.at(0) == '"'))) { - if (value.at(0) != value.at(value.size() - 1)) { - qWarning("Quoting error in input line: '%s'", qPrintable(line)); - continue; + QMap result; + + // Specification of the format, encoding is similar to /etc/os-release + // http://www.freedesktop.org/software/systemd/man/os-release.html + + QFile hwRelease("/etc/hw-release"); + if (hwRelease.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&hwRelease); + + // "All strings should be in UTF-8 format, and non-printable characters + // should not be used." + in.setCodec("UTF-8"); + + while (!in.atEnd()) { + QString line = in.readLine(); + + // "Lines beginning with "#" shall be ignored as comments." + if (line.startsWith('#')) { + continue; + } + + QString key = line.section('=', 0, 0); + QString value = line.section('=', 1); + + // Remove trailing whitespace in value + value = value.trimmed(); + + // POSIX.1-2001 says uppercase, digits and underscores. + // + // Bash uses "[a-zA-Z_]+[a-zA-Z0-9_]*", so we'll use that too, + // as we can safely assume that "shell-compatible variable + // assignments" means it should be compatible with bash. + // + // see http://stackoverflow.com/a/2821183 + // and http://stackoverflow.com/a/2821201 + if (!QRegExp("[a-zA-Z_]+[a-zA-Z0-9_]*").exactMatch(key)) { + qWarning("Invalid key in input line: '%s'", qPrintable(line)); + continue; + } + + // "Variable assignment values should be enclosed in double or + // single quotes if they include spaces, semicolons or other + // special characters outside of A-Z, a-z, 0-9." + if (((value.at(0) == '\'') || (value.at(0) == '"'))) { + if (value.at(0) != value.at(value.size() - 1)) { + qWarning("Quoting error in input line: '%s'", qPrintable(line)); + continue; + } + + // Remove the quotes + value = value.mid(1, value.size() - 2); + } + + // "If double or single quotes or backslashes are to be used within + // variable assignments, they should be escaped with backslashes, + // following shell style." + value = value.replace("\\\"", "\""); + value = value.replace("\\'", "'"); + value = value.replace("\\\\", "\\"); + + result[key] = value; } - // Remove the quotes - value = value.mid(1, value.size() - 2); - } - - // "If double or single quotes or backslashes are to be used within - // variable assignments, they should be escaped with backslashes, - // following shell style." - value = value.replace("\\\"", "\""); - value = value.replace("\\'", "'"); - value = value.replace("\\\\", "\\"); - - result[key] = value; + hwRelease.close(); } - hwRelease.close(); - } - - return result; + return result; } diff --git a/libssu/ssudeviceinfo.h b/libssu/ssudeviceinfo.h index 77039de..046624c 100644 --- a/libssu/ssudeviceinfo.h +++ b/libssu/ssudeviceinfo.h @@ -14,14 +14,15 @@ class SsuSettings; -class SsuDeviceInfo: public QObject { +class SsuDeviceInfo: public QObject +{ Q_OBJECT - public: +public: /** * Initialize with device to override autodetection */ - SsuDeviceInfo(QString model=""); + SsuDeviceInfo(QString model = ""); /** * Return the list of adaptations used for the set model */ @@ -36,7 +37,7 @@ class SsuDeviceInfo: public QObject { * or as variant. If no model is provided as argument the autodetected or previously * set model is used. */ - bool contains(const QString &model=""); + bool contains(const QString &model = ""); /** * Try to find the device family for the system this is running on. This function * temporarily changes the detected model, and therefore should not be used in a @@ -48,7 +49,7 @@ class SsuDeviceInfo: public QObject { * If the device is not a variant it will return an empty string. If * fallback is set to true it return the device model in this case. */ - Q_INVOKABLE QString deviceVariant(bool fallback=false); + Q_INVOKABLE QString deviceVariant(bool fallback = false); /** * Try to find out ond what kind of system this is running */ @@ -80,11 +81,11 @@ class SsuDeviceInfo: public QObject { * only board-specific, or only user-specific are returned. * Disabled repositories are excluded depending on filter settings. */ - QStringList repos(bool rnd=false, int filter=Ssu::NoFilter); + QStringList repos(bool rnd = false, int filter = Ssu::NoFilter); /** * Override device model autodetection */ - Q_INVOKABLE void setDeviceModel(QString model=""); + Q_INVOKABLE void setDeviceModel(QString model = ""); /** * Return a variable from the given variable section. 'var'- is automatically * prepended to the section name if not specified already. Recursive search @@ -105,10 +106,10 @@ class SsuDeviceInfo: public QObject { * dedicated device section the key from the device section will get * returned, otherwise the one from the variant. */ - QVariant value(const QString &key, const QVariant &value=QVariant()); + QVariant value(const QString &key, const QVariant &value = QVariant()); - private: +private: SsuSettings *boardMappings; QString cachedFamily, cachedModel, cachedVariant; diff --git a/libssu/ssufeaturemanager.cpp b/libssu/ssufeaturemanager.cpp index 453e879..e899f18 100644 --- a/libssu/ssufeaturemanager.cpp +++ b/libssu/ssufeaturemanager.cpp @@ -18,8 +18,9 @@ #include "../constants.h" -SsuFeatureManager::SsuFeatureManager(): QObject() { - featureSettings = new SsuSettings(SSU_FEATURE_CONFIGURATION, SSU_FEATURE_CONFIGURATION_DIR); +SsuFeatureManager::SsuFeatureManager(): QObject() +{ + featureSettings = new SsuSettings(SSU_FEATURE_CONFIGURATION, SSU_FEATURE_CONFIGURATION_DIR); } @@ -30,41 +31,43 @@ SsuFeatureManager::SsuFeatureManager(): QObject() { // all features have a list of repositories in the repos key // if there are enabled/disabled features, check the repos keys from all enabled features // and only enable the repositories from those -QStringList SsuFeatureManager::repos(bool rndRepo, int filter){ - QStringList r; - QStringList keys; - SsuCoreConfig *settings = SsuCoreConfig::instance(); +QStringList SsuFeatureManager::repos(bool rndRepo, int filter) +{ + QStringList r; + QStringList keys; + SsuCoreConfig *settings = SsuCoreConfig::instance(); - // @TODO features currently can't be blacklisted, but just ignoring user filter - // is still the best way atm - if (filter == Ssu::UserFilter) - return r; + // @TODO features currently can't be blacklisted, but just ignoring user filter + // is still the best way atm + if (filter == Ssu::UserFilter) + return r; - QString repoHeader = QString("repositories-%1/") - .arg(rndRepo ? "rnd" : "release"); + QString repoHeader = QString("repositories-%1/") + .arg(rndRepo ? "rnd" : "release"); - // take the global groups - featureSettings->beginGroup("repositories"); - r.append(featureSettings->allKeys()); - featureSettings->endGroup(); + // take the global groups + featureSettings->beginGroup("repositories"); + r.append(featureSettings->allKeys()); + featureSettings->endGroup(); - // and override with rnd/release specific groups - featureSettings->beginGroup(repoHeader); - r.append(featureSettings->allKeys()); - featureSettings->endGroup(); + // and override with rnd/release specific groups + featureSettings->beginGroup(repoHeader); + r.append(featureSettings->allKeys()); + featureSettings->endGroup(); - r.removeDuplicates(); - return r; + r.removeDuplicates(); + return r; } -QString SsuFeatureManager::url(QString repo, bool rndRepo){ - QString repoHeader = QString("repositories-%1/") - .arg(rndRepo ? "rnd" : "release"); +QString SsuFeatureManager::url(QString repo, bool rndRepo) +{ + QString repoHeader = QString("repositories-%1/") + .arg(rndRepo ? "rnd" : "release"); - if (featureSettings->contains(repoHeader + repo)) - return featureSettings->value(repoHeader + repo).toString(); - else if (featureSettings->contains("repositories/" + repo)) - return featureSettings->value("repositories/" + repo).toString(); + if (featureSettings->contains(repoHeader + repo)) + return featureSettings->value(repoHeader + repo).toString(); + else if (featureSettings->contains("repositories/" + repo)) + return featureSettings->value("repositories/" + repo).toString(); - return ""; + return ""; } diff --git a/libssu/ssufeaturemanager.h b/libssu/ssufeaturemanager.h index 57b8926..c9e4544 100644 --- a/libssu/ssufeaturemanager.h +++ b/libssu/ssufeaturemanager.h @@ -15,15 +15,16 @@ #include "ssu.h" #include "ssusettings_p.h" -class SsuFeatureManager: public QObject { +class SsuFeatureManager: public QObject +{ Q_OBJECT - public: +public: SsuFeatureManager(); - QStringList repos(bool rndRepo, int filter=Ssu::NoFilter); + QStringList repos(bool rndRepo, int filter = Ssu::NoFilter); QString url(QString repo, bool rndRepo); - private: +private: SsuSettings *featureSettings; }; diff --git a/libssu/ssufeaturemodel.cpp b/libssu/ssufeaturemodel.cpp index b5bce6a..d46aad9 100644 --- a/libssu/ssufeaturemodel.cpp +++ b/libssu/ssufeaturemodel.cpp @@ -18,7 +18,8 @@ bool featureLessThan(const QHash &feature1, const QHash > features; + QString path; + QList > features; }; SsuFeatureModel::SsuFeatureModel(QObject *parent, const QString &path) @@ -120,7 +122,7 @@ QVariant SsuFeatureModel::data(const QModelIndex &index, int role) const QHash SsuFeatureModel::roleNames() const { - QHash roles; + QHash roles; roles.insert(Name, "name"); roles.insert(Version, "version"); return roles; diff --git a/libssu/ssulog.cpp b/libssu/ssulog.cpp index 0231afb..3e3f99b 100644 --- a/libssu/ssulog.cpp +++ b/libssu/ssulog.cpp @@ -13,43 +13,45 @@ SsuLog *SsuLog::ssuLog = 0; -SsuLog *SsuLog::instance(){ - if (!ssuLog){ - ssuLog = new SsuLog(); - ssuLog->fallbackLogPath = "/tmp/ssu.log"; - ssuLog->ssuLogLevel = -1; - } - - return ssuLog; +SsuLog *SsuLog::instance() +{ + if (!ssuLog) { + ssuLog = new SsuLog(); + ssuLog->fallbackLogPath = "/tmp/ssu.log"; + ssuLog->ssuLogLevel = -1; + } + + return ssuLog; } -void SsuLog::print(int priority, QString message){ - QByteArray ba = message.toUtf8(); - const char *ca = ba.constData(); - - // directly go through qsettings here to avoid recursive invocation - // of coreconfig / ssulog - if (ssuLogLevel == -1){ - QSettings settings(SSU_CONFIGURATION, QSettings::IniFormat); - - if (settings.contains("loglevel")) - ssuLog->ssuLogLevel = settings.value("loglevel").toInt(); - else - ssuLog->ssuLogLevel = LOG_ERR; - } - - // this is rather dirty, but since systemd does not seem to allow to enable debug - // logging only for specific services probably best way for now - if (priority > ssuLogLevel) - return; - - if (sd_journal_print(priority, "ssu: %s", ca) < 0 && fallbackLogPath != ""){ - QFile logfile; - QTextStream logstream; - logfile.setFileName(fallbackLogPath); - logfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append); - logstream.setDevice(&logfile); - logstream << message << "\n"; - logstream.flush(); - } +void SsuLog::print(int priority, QString message) +{ + QByteArray ba = message.toUtf8(); + const char *ca = ba.constData(); + + // directly go through qsettings here to avoid recursive invocation + // of coreconfig / ssulog + if (ssuLogLevel == -1) { + QSettings settings(SSU_CONFIGURATION, QSettings::IniFormat); + + if (settings.contains("loglevel")) + ssuLog->ssuLogLevel = settings.value("loglevel").toInt(); + else + ssuLog->ssuLogLevel = LOG_ERR; + } + + // this is rather dirty, but since systemd does not seem to allow to enable debug + // logging only for specific services probably best way for now + if (priority > ssuLogLevel) + return; + + if (sd_journal_print(priority, "ssu: %s", ca) < 0 && fallbackLogPath != "") { + QFile logfile; + QTextStream logstream; + logfile.setFileName(fallbackLogPath); + logfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append); + logstream.setDevice(&logfile); + logstream << message << "\n"; + logstream.flush(); + } } diff --git a/libssu/ssulog_p.h b/libssu/ssulog_p.h index 0a9329f..36ec044 100644 --- a/libssu/ssulog_p.h +++ b/libssu/ssulog_p.h @@ -12,16 +12,17 @@ #include -class SsuLog { +class SsuLog +{ - public: +public: static SsuLog *instance(); /** * Print a message to systemds journal, or to a text log file, if a fallback is defined */ void print(int priority, QString message); - private: +private: SsuLog() {}; SsuLog(const SsuLog &); // hide copy constructor diff --git a/libssu/ssurepomanager.cpp b/libssu/ssurepomanager.cpp index f508512..4774d8b 100644 --- a/libssu/ssurepomanager.cpp +++ b/libssu/ssurepomanager.cpp @@ -21,434 +21,446 @@ #include "../constants.h" -SsuRepoManager::SsuRepoManager(): QObject() { +SsuRepoManager::SsuRepoManager(): QObject() +{ } -int SsuRepoManager::add(QString repo, QString repoUrl){ - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); +int SsuRepoManager::add(QString repo, QString repoUrl) +{ + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - // adding a repo is a noop when device is in update mode... - if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) - return -1; + // adding a repo is a noop when device is in update mode... + if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) + return -1; - // ... or in AppInstallMode - if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode) - return -1; + // ... or in AppInstallMode + if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode) + return -1; - if (repoUrl == ""){ - // just enable a repository which has URL in repos.ini - QStringList enabledRepos; - if (ssuSettings->contains("enabled-repos")) - enabledRepos = ssuSettings->value("enabled-repos").toStringList(); + if (repoUrl == "") { + // just enable a repository which has URL in repos.ini + QStringList enabledRepos; + if (ssuSettings->contains("enabled-repos")) + enabledRepos = ssuSettings->value("enabled-repos").toStringList(); - enabledRepos.append(repo); - enabledRepos.removeDuplicates(); - ssuSettings->setValue("enabled-repos", enabledRepos); - } else - ssuSettings->setValue("repository-urls/" + repo, repoUrl); + enabledRepos.append(repo); + enabledRepos.removeDuplicates(); + ssuSettings->setValue("enabled-repos", enabledRepos); + } else + ssuSettings->setValue("repository-urls/" + repo, repoUrl); - ssuSettings->sync(); - return 0; + ssuSettings->sync(); + return 0; } -QString SsuRepoManager::caCertificatePath(QString domain){ - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); +QString SsuRepoManager::caCertificatePath(QString domain) +{ + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); - if (domain.isEmpty()) - domain = settings->domain(); + if (domain.isEmpty()) + domain = settings->domain(); - QString ca = SsuVariables::variable(&repoSettings, domain + "-domain", - "_ca-certificate").toString(); - if (!ca.isEmpty()) - return ca; + QString ca = SsuVariables::variable(&repoSettings, domain + "-domain", + "_ca-certificate").toString(); + if (!ca.isEmpty()) + return ca; - // compat setting, can go away after some time - if (settings->contains("ca-certificate")) - return settings->value("ca-certificate").toString(); + // compat setting, can go away after some time + if (settings->contains("ca-certificate")) + return settings->value("ca-certificate").toString(); - return ""; + return ""; } -int SsuRepoManager::disable(QString repo){ - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - QStringList disabledRepos; +int SsuRepoManager::disable(QString repo) +{ + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + QStringList disabledRepos; - if (ssuSettings->contains("disabled-repos")) - disabledRepos = ssuSettings->value("disabled-repos").toStringList(); + if (ssuSettings->contains("disabled-repos")) + disabledRepos = ssuSettings->value("disabled-repos").toStringList(); - disabledRepos.append(repo); - disabledRepos.removeDuplicates(); + disabledRepos.append(repo); + disabledRepos.removeDuplicates(); - ssuSettings->setValue("disabled-repos", disabledRepos); - ssuSettings->sync(); + ssuSettings->setValue("disabled-repos", disabledRepos); + ssuSettings->sync(); - return 0; + return 0; } -int SsuRepoManager::enable(QString repo){ - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - QStringList disabledRepos; +int SsuRepoManager::enable(QString repo) +{ + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + QStringList disabledRepos; - if (ssuSettings->contains("disabled-repos")) - disabledRepos = ssuSettings->value("disabled-repos").toStringList(); + if (ssuSettings->contains("disabled-repos")) + disabledRepos = ssuSettings->value("disabled-repos").toStringList(); - disabledRepos.removeAll(repo); - disabledRepos.removeDuplicates(); + disabledRepos.removeAll(repo); + disabledRepos.removeDuplicates(); - ssuSettings->setValue("disabled-repos", disabledRepos); - ssuSettings->sync(); + ssuSettings->setValue("disabled-repos", disabledRepos); + ssuSettings->sync(); - return 0; + return 0; } -int SsuRepoManager::remove(QString repo){ - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); +int SsuRepoManager::remove(QString repo) +{ + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - // removing a repo is a noop when device is in update mode... - if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) - return -1; + // removing a repo is a noop when device is in update mode... + if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) + return -1; - // ... or AppInstallMode - if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode) - return -1; + // ... or AppInstallMode + if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode) + return -1; - if (ssuSettings->contains("repository-urls/" + repo)) - ssuSettings->remove("repository-urls/" + repo); + if (ssuSettings->contains("repository-urls/" + repo)) + ssuSettings->remove("repository-urls/" + repo); - if (ssuSettings->contains("enabled-repos")){ - QStringList enabledRepos = ssuSettings->value("enabled-repos").toStringList(); - if (enabledRepos.contains(repo)){ - enabledRepos.removeAll(repo); - enabledRepos.removeDuplicates(); - ssuSettings->setValue("enabled-repos", enabledRepos); + if (ssuSettings->contains("enabled-repos")) { + QStringList enabledRepos = ssuSettings->value("enabled-repos").toStringList(); + if (enabledRepos.contains(repo)) { + enabledRepos.removeAll(repo); + enabledRepos.removeDuplicates(); + ssuSettings->setValue("enabled-repos", enabledRepos); + } } - } - ssuSettings->sync(); + ssuSettings->sync(); - return 0; + return 0; } -QStringList SsuRepoManager::repos(int filter){ - SsuDeviceInfo deviceInfo; - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - bool rnd = false; +QStringList SsuRepoManager::repos(int filter) +{ + SsuDeviceInfo deviceInfo; + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + bool rnd = false; - if ((ssuSettings->deviceMode() & Ssu::RndMode) == Ssu::RndMode) - rnd = true; + if ((ssuSettings->deviceMode() & Ssu::RndMode) == Ssu::RndMode) + rnd = true; - return repos(rnd, deviceInfo, filter); + return repos(rnd, deviceInfo, filter); } -QStringList SsuRepoManager::repos(bool rnd, int filter){ - SsuDeviceInfo deviceInfo; +QStringList SsuRepoManager::repos(bool rnd, int filter) +{ + SsuDeviceInfo deviceInfo; - return repos(rnd, deviceInfo, filter); + return repos(rnd, deviceInfo, filter); } // @todo the non-device specific repository resolving should move from deviceInfo to repomanager -QStringList SsuRepoManager::repos(bool rnd, SsuDeviceInfo &deviceInfo, int filter){ - QStringList result; - - // read the adaptation specific repositories, as well as the default - // repositories; default repos are read through deviceInfo as an - // adaptation is allowed to disable core repositories - result = deviceInfo.repos(rnd, filter); - - // read the repositories of the available features. While devices have - // a default list of features to be installed those are only relevant - // for bootstrapping, so this code just operates on installed features - SsuFeatureManager featureManager; - result.append(featureManager.repos(rnd, filter)); - - // read user-defined repositories from ssu.ini. This step needs to - // happen at the end, after all other required repositories are - // added already - - // TODO: in strict mode, filter the repository list from there - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - - bool updateMode = false; - bool appInstallMode = false; - - if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) - updateMode = true; - - if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode){ - updateMode = true; - appInstallMode = true; - } - - if (filter == Ssu::NoFilter || - filter == Ssu::UserFilter){ - // user defined repositories, or ones overriding URLs for default ones - // -> in update mode we need to check for each of those if it already - // exists. If it exists, keep it, if it does not, disable it - ssuSettings->beginGroup("repository-urls"); - QStringList repoUrls = ssuSettings->allKeys(); - ssuSettings->endGroup(); - - if (updateMode){ - foreach(const QString &key, repoUrls){ - if (result.contains(key)) - result.append(key); - } - } else { - result.append(repoUrls); - } +QStringList SsuRepoManager::repos(bool rnd, SsuDeviceInfo &deviceInfo, int filter) +{ + QStringList result; - // read user-enabled repositories from ssu.ini - if (ssuSettings->contains("enabled-repos") && !updateMode) - result.append(ssuSettings->value("enabled-repos").toStringList()); + // read the adaptation specific repositories, as well as the default + // repositories; default repos are read through deviceInfo as an + // adaptation is allowed to disable core repositories + result = deviceInfo.repos(rnd, filter); - // if the store repository is enabled keep it enabled in AppInstallMode - if (ssuSettings->contains("enabled-repos") && appInstallMode){ - // TODO store should not be hardcoded, but come via some store plugin - if (ssuSettings->value("enabled-repos").toStringList().contains("store")) - result.append("store"); - } - } - - if (filter == Ssu::NoFilter || - filter == Ssu::UserFilter || - filter == Ssu::BoardFilterUserBlacklist){ - // read the disabled repositories from user configuration - if (ssuSettings->contains("disabled-repos") && !updateMode){ - foreach (const QString &key, ssuSettings->value("disabled-repos").toStringList()) - result.removeAll(key); - } - } + // read the repositories of the available features. While devices have + // a default list of features to be installed those are only relevant + // for bootstrapping, so this code just operates on installed features + SsuFeatureManager featureManager; + result.append(featureManager.repos(rnd, filter)); + // read user-defined repositories from ssu.ini. This step needs to + // happen at the end, after all other required repositories are + // added already - result.sort(); - result.removeDuplicates(); + // TODO: in strict mode, filter the repository list from there + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - return result; -} + bool updateMode = false; + bool appInstallMode = false; + + if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) + updateMode = true; + + if ((ssuSettings->deviceMode() & Ssu::AppInstallMode) == Ssu::AppInstallMode) { + updateMode = true; + appInstallMode = true; + } -void SsuRepoManager::update(){ - // - delete all non-ssu managed repositories (missing ssu_ prefix) - // - create list of ssu-repositories for current adaptation - // - go through ssu_* repositories, delete all which are not in the list; write others + if (filter == Ssu::NoFilter || + filter == Ssu::UserFilter) { + // user defined repositories, or ones overriding URLs for default ones + // -> in update mode we need to check for each of those if it already + // exists. If it exists, keep it, if it does not, disable it + ssuSettings->beginGroup("repository-urls"); + QStringList repoUrls = ssuSettings->allKeys(); + ssuSettings->endGroup(); + + if (updateMode) { + foreach (const QString &key, repoUrls) { + if (result.contains(key)) + result.append(key); + } + } else { + result.append(repoUrls); + } + + // read user-enabled repositories from ssu.ini + if (ssuSettings->contains("enabled-repos") && !updateMode) + result.append(ssuSettings->value("enabled-repos").toStringList()); + + // if the store repository is enabled keep it enabled in AppInstallMode + if (ssuSettings->contains("enabled-repos") && appInstallMode) { + // TODO store should not be hardcoded, but come via some store plugin + if (ssuSettings->value("enabled-repos").toStringList().contains("store")) + result.append("store"); + } + } + + if (filter == Ssu::NoFilter || + filter == Ssu::UserFilter || + filter == Ssu::BoardFilterUserBlacklist) { + // read the disabled repositories from user configuration + if (ssuSettings->contains("disabled-repos") && !updateMode) { + foreach (const QString &key, ssuSettings->value("disabled-repos").toStringList()) + result.removeAll(key); + } + } - SsuDeviceInfo deviceInfo; - QStringList ssuFilters; - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - int deviceMode = ssuSettings->deviceMode(); + result.sort(); + result.removeDuplicates(); + + return result; +} - SsuLog *ssuLog = SsuLog::instance(); +void SsuRepoManager::update() +{ + // - delete all non-ssu managed repositories (missing ssu_ prefix) + // - create list of ssu-repositories for current adaptation + // - go through ssu_* repositories, delete all which are not in the list; write others - // if device is misconfigured, always assume release mode - bool rndMode = false; + SsuDeviceInfo deviceInfo; + QStringList ssuFilters; - if ((deviceMode & Ssu::DisableRepoManager) == Ssu::DisableRepoManager){ - ssuLog->print(LOG_INFO, "Repo management requested, but not enabled (option 'deviceMode')"); - return; - } + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + int deviceMode = ssuSettings->deviceMode(); - if ((deviceMode & Ssu::RndMode) == Ssu::RndMode) - rndMode = true; + SsuLog *ssuLog = SsuLog::instance(); - // get list of device-specific repositories... - QStringList repositoryList = repos(rndMode); + // if device is misconfigured, always assume release mode + bool rndMode = false; - // strict mode enabled -> delete all repositories not prefixed by ssu - // assume configuration error if there are no device repos, and don't delete - // anything, even in strict mode - if ((deviceMode & Ssu::LenientMode) != Ssu::LenientMode && !repositoryList.isEmpty()){ - QDirIterator it(Sandbox::map(ZYPP_REPO_PATH), QDir::AllEntries|QDir::NoDot|QDir::NoDotDot); - while (it.hasNext()){ - it.next(); - if (it.fileName().left(4) != "ssu_"){ - ssuLog->print(LOG_INFO, "Strict mode enabled, removing unmanaged repository " + it.fileName()); - QFile(it.filePath()).remove(); - } + if ((deviceMode & Ssu::DisableRepoManager) == Ssu::DisableRepoManager) { + ssuLog->print(LOG_INFO, "Repo management requested, but not enabled (option 'deviceMode')"); + return; } - } - - // ... delete all ssu-managed repositories not valid for this device ... - ssuFilters.append("ssu_*"); - QDirIterator it(Sandbox::map(ZYPP_REPO_PATH), ssuFilters); - while (it.hasNext()){ - QString f = it.next(); - - QStringList parts = it.fileName().split("_"); - // repo file structure is ssu__.repo -> splits to 3 parts - if (parts.count() == 3){ - if (!repositoryList.contains(parts.at(1)) || - parts.at(2) != (rndMode ? "rnd.repo" : "release.repo" )) - QFile(it.filePath()).remove(); - } else - QFile(it.filePath()).remove(); - } - - // ... and create all repositories required for this device - foreach (const QString &repo, repositoryList){ - // repo should be used where a unique identifier for silly human brains, or - // zypper is required. repoName contains the shortened form for ssu use - QString repoName = repo; - QString debugSplit; - if (repo.endsWith("-debuginfo")){ - debugSplit = "&debug"; - repoName = repo.left(repo.size() - 10); + + if ((deviceMode & Ssu::RndMode) == Ssu::RndMode) + rndMode = true; + + // get list of device-specific repositories... + QStringList repositoryList = repos(rndMode); + + // strict mode enabled -> delete all repositories not prefixed by ssu + // assume configuration error if there are no device repos, and don't delete + // anything, even in strict mode + if ((deviceMode & Ssu::LenientMode) != Ssu::LenientMode && !repositoryList.isEmpty()) { + QDirIterator it(Sandbox::map(ZYPP_REPO_PATH), QDir::AllEntries | QDir::NoDot | QDir::NoDotDot); + while (it.hasNext()) { + it.next(); + if (it.fileName().left(4) != "ssu_") { + ssuLog->print(LOG_INFO, "Strict mode enabled, removing unmanaged repository " + it.fileName()); + QFile(it.filePath()).remove(); + } + } } - QString repoFilePath = QString("%1/ssu_%2_%3.repo") - .arg(Sandbox::map(ZYPP_REPO_PATH)) - .arg(repo) - .arg(rndMode ? "rnd" : "release"); - - if (url(repoName, rndMode) == ""){ - // TODO, repositories should only be disabled if they're not required - // for this machine. For required repositories error is better - QTextStream qerr(stderr); - qerr << "Repository " << repo << " does not contain valid URL, skipping and disabling." << endl; - disable(repo); - QFile(repoFilePath).remove(); - continue; + // ... delete all ssu-managed repositories not valid for this device ... + ssuFilters.append("ssu_*"); + QDirIterator it(Sandbox::map(ZYPP_REPO_PATH), ssuFilters); + while (it.hasNext()) { + QString f = it.next(); + + QStringList parts = it.fileName().split("_"); + // repo file structure is ssu__.repo -> splits to 3 parts + if (parts.count() == 3) { + if (!repositoryList.contains(parts.at(1)) || + parts.at(2) != (rndMode ? "rnd.repo" : "release.repo" )) + QFile(it.filePath()).remove(); + } else + QFile(it.filePath()).remove(); } - QFile repoFile(repoFilePath); - - if (repoFile.open(QIODevice::WriteOnly | QIODevice::Text)){ - QTextStream out(&repoFile); - // TODO, add -rnd or -release if we want to support having rnd and - // release enabled at the same time - out << "[" << repo << "]" << endl - << "name=" << repo << endl - << "failovermethod=priority" << endl - << "type=rpm-md" << endl - << "gpgcheck=0" << endl - << "enabled=1" << endl; - - if (rndMode) - out << "baseurl=plugin:ssu?rnd&repo=" << repoName << debugSplit << endl; - else - out << "baseurl=plugin:ssu?repo=" << repoName << debugSplit << endl; - - out.flush(); + // ... and create all repositories required for this device + foreach (const QString &repo, repositoryList) { + // repo should be used where a unique identifier for silly human brains, or + // zypper is required. repoName contains the shortened form for ssu use + QString repoName = repo; + QString debugSplit; + if (repo.endsWith("-debuginfo")) { + debugSplit = "&debug"; + repoName = repo.left(repo.size() - 10); + } + + QString repoFilePath = QString("%1/ssu_%2_%3.repo") + .arg(Sandbox::map(ZYPP_REPO_PATH)) + .arg(repo) + .arg(rndMode ? "rnd" : "release"); + + if (url(repoName, rndMode) == "") { + // TODO, repositories should only be disabled if they're not required + // for this machine. For required repositories error is better + QTextStream qerr(stderr); + qerr << "Repository " << repo << " does not contain valid URL, skipping and disabling." << endl; + disable(repo); + QFile(repoFilePath).remove(); + continue; + } + + QFile repoFile(repoFilePath); + + if (repoFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&repoFile); + // TODO, add -rnd or -release if we want to support having rnd and + // release enabled at the same time + out << "[" << repo << "]" << endl + << "name=" << repo << endl + << "failovermethod=priority" << endl + << "type=rpm-md" << endl + << "gpgcheck=0" << endl + << "enabled=1" << endl; + + if (rndMode) + out << "baseurl=plugin:ssu?rnd&repo=" << repoName << debugSplit << endl; + else + out << "baseurl=plugin:ssu?repo=" << repoName << debugSplit << endl; + + out.flush(); + } } - } } -QStringList SsuRepoManager::repoVariables(QHash *storageHash, bool rnd){ - SsuVariables var; - SsuCoreConfig *settings = SsuCoreConfig::instance(); - QStringList configSections; - SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); - - // fill in all arbitrary repo specific variables from ssu.ini - var.variableSection(settings, "repository-url-variables", storageHash); - - // fill in all global variables from ssu.ini - // TODO: should be handled somewhere in core variable logic once variables - // are more widely used outside of repository urls, for now this is - // just for easier migration to "full" variable usage at a later point. - var.variableSection(settings, "global-variables", storageHash); - - // add/overwrite some of the variables with sane ones - if (rnd){ - storageHash->insert("flavour", - repoSettings.value( - settings->flavour()+"-flavour/flavour-pattern").toString()); - storageHash->insert("flavourPattern", - repoSettings.value( - settings->flavour()+"-flavour/flavour-pattern").toString()); - storageHash->insert("flavourName", settings->flavour()); - configSections << settings->flavour()+"-flavour" << "rnd" << "all"; - - // Make it possible to give any values with the flavour as well. - // These values can be overridden later with domain if needed. - var.variableSection(&repoSettings, settings->flavour()+"-flavour", storageHash); - } else { - configSections << "release" << "all"; - } - - storageHash->insert("release", settings->release(rnd)); - - if (!storageHash->contains("debugSplit")) - storageHash->insert("debugSplit", "packages"); - - if (!storageHash->contains("arch")) - storageHash->insert("arch", settings->value("arch").toString()); - - return configSections; +QStringList SsuRepoManager::repoVariables(QHash *storageHash, bool rnd) +{ + SsuVariables var; + SsuCoreConfig *settings = SsuCoreConfig::instance(); + QStringList configSections; + SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); + + // fill in all arbitrary repo specific variables from ssu.ini + var.variableSection(settings, "repository-url-variables", storageHash); + + // fill in all global variables from ssu.ini + // TODO: should be handled somewhere in core variable logic once variables + // are more widely used outside of repository urls, for now this is + // just for easier migration to "full" variable usage at a later point. + var.variableSection(settings, "global-variables", storageHash); + + // add/overwrite some of the variables with sane ones + if (rnd) { + storageHash->insert("flavour", + repoSettings.value( + settings->flavour() + "-flavour/flavour-pattern").toString()); + storageHash->insert("flavourPattern", + repoSettings.value( + settings->flavour() + "-flavour/flavour-pattern").toString()); + storageHash->insert("flavourName", settings->flavour()); + configSections << settings->flavour() + "-flavour" << "rnd" << "all"; + + // Make it possible to give any values with the flavour as well. + // These values can be overridden later with domain if needed. + var.variableSection(&repoSettings, settings->flavour() + "-flavour", storageHash); + } else { + configSections << "release" << "all"; + } + + storageHash->insert("release", settings->release(rnd)); + + if (!storageHash->contains("debugSplit")) + storageHash->insert("debugSplit", "packages"); + + if (!storageHash->contains("arch")) + storageHash->insert("arch", settings->value("arch").toString()); + + return configSections; } // RND repos have flavour (devel, testing, release), and release (latest, next) // Release repos only have release (latest, next, version number) QString SsuRepoManager::url(QString repoName, bool rndRepo, QHash repoParameters, - QHash parametersOverride){ - QString r; - QStringList configSections; - SsuVariables var; - SsuCoreConfig *settings = SsuCoreConfig::instance(); - SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); - SsuDeviceInfo deviceInfo; - - // set debugSplit for incorrectly configured debuginfo repositories (debugSplit - // should already be passed by the url resolver); might be overriden later on, - // if required - if (repoName.endsWith("-debuginfo") && !repoParameters.contains("debugSplit")) - repoParameters.insert("debugSplit", "debug"); - - configSections = repoVariables(&repoParameters, rndRepo); - - - // Override device model (and therefore all the family, ... stuff) - if (parametersOverride.contains("model")) - deviceInfo.setDeviceModel(parametersOverride.value("model")); - - repoParameters.insert("deviceFamily", deviceInfo.deviceFamily()); - repoParameters.insert("deviceModel", deviceInfo.deviceModel()); - - repoName = deviceInfo.adaptationVariables(repoName, &repoParameters); - - - QString domain; - if (parametersOverride.contains("domain")){ - domain = parametersOverride.value("domain"); - domain.replace("-", ":"); - } else - domain = settings->domain(); - - // variableSection does autodetection for the domain default section - var.variableSection(&repoSettings, - domain + "-domain", &repoParameters); - - // override arbitrary variables, mostly useful for generating mic URLs - QHash::const_iterator i = parametersOverride.constBegin(); - while (i != parametersOverride.constEnd()){ - repoParameters.insert(i.key(), i.value()); - i++; - } - - // search for URLs for repositories. Lookup order is: - // 1. overrides in ssu.ini - // 2. URLs from features - // 3. URLs from repos.ini - - SsuFeatureManager featureManager; - - if (settings->contains("repository-urls/" + repoName)) - r = settings->value("repository-urls/" + repoName).toString(); - else if (featureManager.url(repoName, rndRepo) != "") - r = featureManager.url(repoName, rndRepo); - else { - foreach (const QString §ion, configSections){ - repoSettings.beginGroup(section); - if (repoSettings.contains(repoName)){ - r = repoSettings.value(repoName).toString(); - repoSettings.endGroup(); - break; - } - repoSettings.endGroup(); + QHash parametersOverride) +{ + QString r; + QStringList configSections; + SsuVariables var; + SsuCoreConfig *settings = SsuCoreConfig::instance(); + SsuSettings repoSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); + SsuDeviceInfo deviceInfo; + + // set debugSplit for incorrectly configured debuginfo repositories (debugSplit + // should already be passed by the url resolver); might be overriden later on, + // if required + if (repoName.endsWith("-debuginfo") && !repoParameters.contains("debugSplit")) + repoParameters.insert("debugSplit", "debug"); + + configSections = repoVariables(&repoParameters, rndRepo); + + + // Override device model (and therefore all the family, ... stuff) + if (parametersOverride.contains("model")) + deviceInfo.setDeviceModel(parametersOverride.value("model")); + + repoParameters.insert("deviceFamily", deviceInfo.deviceFamily()); + repoParameters.insert("deviceModel", deviceInfo.deviceModel()); + + repoName = deviceInfo.adaptationVariables(repoName, &repoParameters); + + + QString domain; + if (parametersOverride.contains("domain")) { + domain = parametersOverride.value("domain"); + domain.replace("-", ":"); + } else + domain = settings->domain(); + + // variableSection does autodetection for the domain default section + var.variableSection(&repoSettings, + domain + "-domain", &repoParameters); + + // override arbitrary variables, mostly useful for generating mic URLs + QHash::const_iterator i = parametersOverride.constBegin(); + while (i != parametersOverride.constEnd()) { + repoParameters.insert(i.key(), i.value()); + i++; + } + + // search for URLs for repositories. Lookup order is: + // 1. overrides in ssu.ini + // 2. URLs from features + // 3. URLs from repos.ini + + SsuFeatureManager featureManager; + + if (settings->contains("repository-urls/" + repoName)) + r = settings->value("repository-urls/" + repoName).toString(); + else if (featureManager.url(repoName, rndRepo) != "") + r = featureManager.url(repoName, rndRepo); + else { + foreach (const QString §ion, configSections) { + repoSettings.beginGroup(section); + if (repoSettings.contains(repoName)) { + r = repoSettings.value(repoName).toString(); + repoSettings.endGroup(); + break; + } + repoSettings.endGroup(); + } } - } - return var.resolveString(r, &repoParameters); + return var.resolveString(r, &repoParameters); } diff --git a/libssu/ssurepomanager.h b/libssu/ssurepomanager.h index f9cd6de..064fe0e 100644 --- a/libssu/ssurepomanager.h +++ b/libssu/ssurepomanager.h @@ -15,10 +15,11 @@ class SsuDeviceInfo; -class SsuRepoManager: public QObject { +class SsuRepoManager: public QObject +{ Q_OBJECT - public: +public: SsuRepoManager(); /** * Add a repository. Note: Repositories ending with -debuginfo receive special @@ -28,7 +29,7 @@ class SsuRepoManager: public QObject { * * If the device is in UpdateMode this function does nothing. */ - int add(QString repo, QString repoUrl=""); + int add(QString repo, QString repoUrl = ""); /** * Return the path to the CA certificate to be used for the given domain, * or default domain, if omitted @@ -37,7 +38,7 @@ class SsuRepoManager: public QObject { * @retval -1 Repository not added because device is in update mode * @retval -2 Repository not added because third party repositories are disabled */ - static QString caCertificatePath(QString domain=""); + static QString caCertificatePath(QString domain = ""); /** * Disable a repository * @@ -65,18 +66,18 @@ class SsuRepoManager: public QObject { /** * Collect the list of repositories from different submodules */ - QStringList repos(int filter=Ssu::NoFilter); + QStringList repos(int filter = Ssu::NoFilter); /** * Collect the list of repositories from different submodules. * This form allows overriding rnd mode setting. */ - QStringList repos(bool rnd, int filter=Ssu::NoFilter); + QStringList repos(bool rnd, int filter = Ssu::NoFilter); /** * Collect the list of repositories from different submodules. * This form takes a reference to a custom device info instance * to allow overrides. */ - QStringList repos(bool rnd, SsuDeviceInfo &deviceInfo, int filter=Ssu::NoFilter); + QStringList repos(bool rnd, SsuDeviceInfo &deviceInfo, int filter = Ssu::NoFilter); /** * Resolve repository specific variables, and store them in storageHash. Does * not include adaptation specific variables, see SsuDeviceInfo::adaptationVariables @@ -84,7 +85,7 @@ class SsuRepoManager: public QObject { * Returns a list of sections in the configuration file that might contain repository * URLs */ - QStringList repoVariables(QHash *storageHash, bool rnd=false); + QStringList repoVariables(QHash *storageHash, bool rnd = false); /** * Update the repository files on disk */ @@ -93,9 +94,9 @@ class SsuRepoManager: public QObject { * Resolve a repository url * @return the repository URL on success, an empty string on error */ - QString url(QString repoName, bool rndRepo=false, - QHash repoParameters=QHash(), - QHash parametersOverride=QHash()); + QString url(QString repoName, bool rndRepo = false, + QHash repoParameters = QHash(), + QHash parametersOverride = QHash()); }; diff --git a/libssu/ssusettings.cpp b/libssu/ssusettings.cpp index eb2563b..894a93c 100644 --- a/libssu/ssusettings.cpp +++ b/libssu/ssusettings.cpp @@ -14,90 +14,96 @@ #include "ssusettings_p.h" #include "ssulog_p.h" -SsuSettings::SsuSettings(): QSettings(){ +SsuSettings::SsuSettings(): QSettings() +{ } SsuSettings::SsuSettings(const QString &fileName, Format format, QObject *parent): - QSettings(Sandbox::map(fileName), format, parent){ + QSettings(Sandbox::map(fileName), format, parent) +{ } SsuSettings::SsuSettings(const QString &fileName, Format format, const QString &defaultFileName, QObject *parent): - QSettings(Sandbox::map(fileName), format, parent){ - defaultSettingsFile = Sandbox::map(defaultFileName); - upgrade(); + QSettings(Sandbox::map(fileName), format, parent) +{ + defaultSettingsFile = Sandbox::map(defaultFileName); + upgrade(); } SsuSettings::SsuSettings(const QString &fileName, const QString &settingsDirectory, QObject *parent): - QSettings(Sandbox::map(fileName), QSettings::IniFormat, parent){ - settingsd = Sandbox::map(settingsDirectory); - merge(); + QSettings(Sandbox::map(fileName), QSettings::IniFormat, parent) +{ + settingsd = Sandbox::map(settingsDirectory); + merge(); } -void SsuSettings::merge(bool keepOld){ - if (settingsd == "") - return; +void SsuSettings::merge(bool keepOld) +{ + if (settingsd == "") + return; - bool skipMerge = true; + bool skipMerge = true; - SsuLog *ssuLog = SsuLog::instance(); + SsuLog *ssuLog = SsuLog::instance(); - QDirIterator it(settingsd, QDir::AllEntries|QDir::NoDot|QDir::NoDotDot, QDirIterator::FollowSymlinks); - QStringList settingsFiles; + QDirIterator it(settingsd, QDir::AllEntries | QDir::NoDot | QDir::NoDotDot, QDirIterator::FollowSymlinks); + QStringList settingsFiles; - QFileInfo oldSettingsInfo(fileName()); + QFileInfo oldSettingsInfo(fileName()); - while (it.hasNext()){ - QString f = it.next(); + while (it.hasNext()) { + QString f = it.next(); - settingsFiles.append(it.filePath()); + settingsFiles.append(it.filePath()); - QFileInfo info(it.filePath()); - if (info.lastModified() >= oldSettingsInfo.lastModified()) - skipMerge = false; - } + QFileInfo info(it.filePath()); + if (info.lastModified() >= oldSettingsInfo.lastModified()) + skipMerge = false; + } - if (skipMerge){ - // systemd journal does not seem to allow selective loglevels for different services, disabling for now - //ssuLog->print(LOG_DEBUG, QString("Configuration file is newer than all config.d files, skipping merge")); - return; - } + if (skipMerge) { + // systemd journal does not seem to allow selective loglevels for different services, disabling for now + //ssuLog->print(LOG_DEBUG, QString("Configuration file is newer than all config.d files, skipping merge")); + return; + } - settingsFiles.sort(); + settingsFiles.sort(); - // delete all keys in the cached settings - if (settingsFiles.count() > 0 && !keepOld) - clear(); + // delete all keys in the cached settings + if (settingsFiles.count() > 0 && !keepOld) + clear(); - merge(this, settingsFiles); - sync(); + merge(this, settingsFiles); + sync(); } -void SsuSettings::merge(QSettings *masterSettings, const QStringList &settingsFiles){ - SsuLog *ssuLog = SsuLog::instance(); +void SsuSettings::merge(QSettings *masterSettings, const QStringList &settingsFiles) +{ + SsuLog *ssuLog = SsuLog::instance(); - foreach (const QString &settingsFile, settingsFiles){ - QSettings settings(settingsFile, QSettings::IniFormat); - QStringList groups = settings.childGroups(); + foreach (const QString &settingsFile, settingsFiles) { + QSettings settings(settingsFile, QSettings::IniFormat); + QStringList groups = settings.childGroups(); - ssuLog->print(LOG_DEBUG, QString("Merging %1 into %2") - .arg(settingsFile) - .arg(masterSettings->fileName())); + ssuLog->print(LOG_DEBUG, QString("Merging %1 into %2") + .arg(settingsFile) + .arg(masterSettings->fileName())); - foreach (const QString &group, groups){ - masterSettings->beginGroup(group); - settings.beginGroup(group); + foreach (const QString &group, groups) { + masterSettings->beginGroup(group); + settings.beginGroup(group); - QStringList keys = settings.allKeys(); - foreach (const QString &key, keys){ - masterSettings->setValue(key, settings.value(key)); - } + QStringList keys = settings.allKeys(); + foreach (const QString &key, keys) { + masterSettings->setValue(key, settings.value(key)); + } - settings.endGroup(); - masterSettings->endGroup(); + settings.endGroup(); + masterSettings->endGroup(); + } } - } } /* @@ -106,90 +112,91 @@ void SsuSettings::merge(QSettings *masterSettings, const QStringList &settingsFi * `git diff testdata/upgrade/recipe`. See ut_settings/upgradetesthelper.cpp for * more details. */ -void SsuSettings::upgrade(){ - int configVersion=0; - int defaultConfigVersion=0; - - SsuLog *ssuLog = SsuLog::instance(); - - if (defaultSettingsFile == "") - return; - - QSettings defaultSettings(defaultSettingsFile, QSettings::IniFormat); - - if (contains("configVersion")) - configVersion = value("configVersion").toInt(); - if (defaultSettings.contains("configVersion")) - defaultConfigVersion = defaultSettings.value("configVersion").toInt(); - - if (configVersion < defaultConfigVersion){ - ssuLog->print(LOG_DEBUG, QString("Configuration is outdated, updating from %1 to %2") - .arg(configVersion) - .arg(defaultConfigVersion)); - - for (int i=configVersion+1;i<=defaultConfigVersion;i++){ - QStringList defaultKeys; - QString currentSection = QString("%1/").arg(i); - - ssuLog->print(LOG_DEBUG, QString("Processing configuration version %1").arg(i)); - defaultSettings.beginGroup(currentSection); - defaultKeys = defaultSettings.allKeys(); - defaultSettings.endGroup(); - foreach (const QString &key, defaultKeys){ - // Default keys support both commands and new keys - if (key.compare("cmd-remove", Qt::CaseSensitive) == 0){ - // Remove keys listed in value as string list - QStringList oldKeys = defaultSettings.value(currentSection + key).toStringList(); - foreach (const QString &oldKey, oldKeys){ - if (contains(oldKey)){ - remove(oldKey); - ssuLog->print(LOG_DEBUG, QString("Removing old key: %1").arg(oldKey)); - } - } - } else if (!contains(key)){ - // Add new keys.. - setValue(key, defaultSettings.value(currentSection + key)); - ssuLog->print(LOG_DEBUG, QString("Adding key: %1").arg(key)); - } else { - // ... or update the ones where default values has changed. - QVariant oldValue; - - // check if an old value exists in an older configuration version - for (int j=i-1;j>0;j--){ - if (defaultSettings.contains(QString("%1/").arg(j)+key)){ - oldValue = defaultSettings.value(QString("%1/").arg(j)+key); - break; +void SsuSettings::upgrade() +{ + int configVersion = 0; + int defaultConfigVersion = 0; + + SsuLog *ssuLog = SsuLog::instance(); + + if (defaultSettingsFile == "") + return; + + QSettings defaultSettings(defaultSettingsFile, QSettings::IniFormat); + + if (contains("configVersion")) + configVersion = value("configVersion").toInt(); + if (defaultSettings.contains("configVersion")) + defaultConfigVersion = defaultSettings.value("configVersion").toInt(); + + if (configVersion < defaultConfigVersion) { + ssuLog->print(LOG_DEBUG, QString("Configuration is outdated, updating from %1 to %2") + .arg(configVersion) + .arg(defaultConfigVersion)); + + for (int i = configVersion + 1; i <= defaultConfigVersion; i++) { + QStringList defaultKeys; + QString currentSection = QString("%1/").arg(i); + + ssuLog->print(LOG_DEBUG, QString("Processing configuration version %1").arg(i)); + defaultSettings.beginGroup(currentSection); + defaultKeys = defaultSettings.allKeys(); + defaultSettings.endGroup(); + foreach (const QString &key, defaultKeys) { + // Default keys support both commands and new keys + if (key.compare("cmd-remove", Qt::CaseSensitive) == 0) { + // Remove keys listed in value as string list + QStringList oldKeys = defaultSettings.value(currentSection + key).toStringList(); + foreach (const QString &oldKey, oldKeys) { + if (contains(oldKey)) { + remove(oldKey); + ssuLog->print(LOG_DEBUG, QString("Removing old key: %1").arg(oldKey)); + } + } + } else if (!contains(key)) { + // Add new keys.. + setValue(key, defaultSettings.value(currentSection + key)); + ssuLog->print(LOG_DEBUG, QString("Adding key: %1").arg(key)); + } else { + // ... or update the ones where default values has changed. + QVariant oldValue; + + // check if an old value exists in an older configuration version + for (int j = i - 1; j > 0; j--) { + if (defaultSettings.contains(QString("%1/").arg(j) + key)) { + oldValue = defaultSettings.value(QString("%1/").arg(j) + key); + break; + } + } + + // skip updating if there is no old value, since we can't check if the + // default value has changed + if (oldValue.isNull()) + continue; + + QVariant newValue = defaultSettings.value(currentSection + key); + if (oldValue == newValue) { + // old and new value match, no need to do anything, apart from beating the + // person who added a useless key + continue; + } else { + // default value has changed, so check if the configuration is still + // using the old default value... + QVariant currentValue = value(key); + // testcase: handles properly default update of thing with changed value in ssu.ini? + if (currentValue == oldValue) { + // ...and update the key if it does + setValue(key, newValue); + ssuLog->print(LOG_DEBUG, QString("Updating %1 from %2 to %3") + .arg(key) + .arg(currentValue.toString()) + .arg(newValue.toString())); + } + } + } } - } - - // skip updating if there is no old value, since we can't check if the - // default value has changed - if (oldValue.isNull()) - continue; - - QVariant newValue = defaultSettings.value(currentSection + key); - if (oldValue == newValue){ - // old and new value match, no need to do anything, apart from beating the - // person who added a useless key - continue; - } else { - // default value has changed, so check if the configuration is still - // using the old default value... - QVariant currentValue = value(key); - // testcase: handles properly default update of thing with changed value in ssu.ini? - if (currentValue == oldValue){ - // ...and update the key if it does - setValue(key, newValue); - ssuLog->print(LOG_DEBUG, QString("Updating %1 from %2 to %3") - .arg(key) - .arg(currentValue.toString()) - .arg(newValue.toString())); - } - } + setValue("configVersion", i); } - } - setValue("configVersion", i); + sync(); } - sync(); - } } diff --git a/libssu/ssusettings_p.h b/libssu/ssusettings_p.h index 0b3b376..ac84676 100644 --- a/libssu/ssusettings_p.h +++ b/libssu/ssusettings_p.h @@ -10,28 +10,29 @@ #include -class SsuSettings: public QSettings { +class SsuSettings: public QSettings +{ Q_OBJECT friend class SettingsTest; - public: +public: SsuSettings(); - SsuSettings(const QString &fileName, Format format, QObject *parent=0); + SsuSettings(const QString &fileName, Format format, QObject *parent = 0); /** * Initialize the settings object with a defaults settings file, resulting in * update to the configuration file if needed */ - SsuSettings(const QString &fileName, Format format, const QString &defaultFileName, QObject *parent=0); + SsuSettings(const QString &fileName, Format format, const QString &defaultFileName, QObject *parent = 0); /** * Initialize the settings object from a settings.d structure, if needed. Only INI * style settings are supported in this mode. */ - SsuSettings(const QString &fileName, const QString &settingsDirectory, QObject *parent=0); + SsuSettings(const QString &fileName, const QString &settingsDirectory, QObject *parent = 0); - private: +private: QString defaultSettingsFile, settingsd; - void merge(bool keepOld=false); + void merge(bool keepOld = false); static void merge(QSettings *masterSettings, const QStringList &settingsFiles); void upgrade(); diff --git a/libssu/ssuvariables.cpp b/libssu/ssuvariables.cpp index 815dc31..9087ac8 100644 --- a/libssu/ssuvariables.cpp +++ b/libssu/ssuvariables.cpp @@ -14,166 +14,176 @@ #include "../constants.h" -SsuVariables::SsuVariables(): QObject() { +SsuVariables::SsuVariables(): QObject() +{ } -QString SsuVariables::defaultSection(SsuSettings *settings, QString section){ - QStringList parts = section.split("-"); +QString SsuVariables::defaultSection(SsuSettings *settings, QString section) +{ + QStringList parts = section.split("-"); - if (section.startsWith("var-")) - parts.insert(1, "default"); - else - parts.replace(0, "default"); + if (section.startsWith("var-")) + parts.insert(1, "default"); + else + parts.replace(0, "default"); - QString key = parts.join("-"); + QString key = parts.join("-"); - if (settings->childGroups().contains(key)) - return key; - else - return ""; + if (settings->childGroups().contains(key)) + return key; + else + return ""; } -QString SsuVariables::resolveString(QString pattern, QHash *variables, int recursionDepth){ - if (recursionDepth >= SSU_MAX_RECURSION){ - return "maximum-recursion-level-reached"; - } - - QRegExp regex("%\\\([^%]*\\\)", Qt::CaseSensitive, QRegExp::RegExp2); - regex.setMinimal(true); - - int pos = 0; - while ((pos = regex.indexIn(pattern, pos)) != -1){ - QString match = regex.cap(0); - - if (match.contains(":")){ - // variable is special, resolve before replacing - QString variable = resolveVariable(match, variables); - pattern.replace(match, variable); - pos += variable.length(); - } else { - // look up variable name in hashmap, and replace it with stored value, - // if found, or "" - QString variableName = match; - variableName.remove(0,2); - variableName.chop(1); - if (variables->contains(variableName)){ - pattern.replace(match, variables->value(variableName)); - pos += variables->value(variableName).length(); - } else - pattern.replace(match, ""); +QString SsuVariables::resolveString(QString pattern, QHash *variables, int recursionDepth) +{ + if (recursionDepth >= SSU_MAX_RECURSION) { + return "maximum-recursion-level-reached"; } - } - // check if string still contains variables, and recurse - if (regex.indexIn(pattern, 0) != -1) - pattern = resolveString(pattern, variables, recursionDepth + 1); + QRegExp regex("%\\\([^%]*\\\)", Qt::CaseSensitive, QRegExp::RegExp2); + regex.setMinimal(true); + + int pos = 0; + while ((pos = regex.indexIn(pattern, pos)) != -1) { + QString match = regex.cap(0); + + if (match.contains(":")) { + // variable is special, resolve before replacing + QString variable = resolveVariable(match, variables); + pattern.replace(match, variable); + pos += variable.length(); + } else { + // look up variable name in hashmap, and replace it with stored value, + // if found, or "" + QString variableName = match; + variableName.remove(0, 2); + variableName.chop(1); + if (variables->contains(variableName)) { + pattern.replace(match, variables->value(variableName)); + pos += variables->value(variableName).length(); + } else + pattern.replace(match, ""); + } + } + + // check if string still contains variables, and recurse + if (regex.indexIn(pattern, 0) != -1) + pattern = resolveString(pattern, variables, recursionDepth + 1); - return pattern; + return pattern; } -QString SsuVariables::resolveVariable(QString variable, QHash *variables){ - QString variableValue = ""; +QString SsuVariables::resolveVariable(QString variable, QHash *variables) +{ + QString variableValue = ""; - if (variable.endsWith(")")) - variable.chop(1); - if (variable.startsWith("%(")) - variable.remove(0,2); + if (variable.endsWith(")")) + variable.chop(1); + if (variable.startsWith("%(")) + variable.remove(0, 2); - // hunt for your colon - int magic = variable.indexOf(":"); + // hunt for your colon + int magic = variable.indexOf(":"); - // seems you misplaced your colon - if (magic == -1) return variable; + // seems you misplaced your colon + if (magic == -1) return variable; - QStringRef variableName(&variable, 0, magic); - QStringRef variableSub(&variable, magic + 2, variable.length() - magic - 2); + QStringRef variableName(&variable, 0, magic); + QStringRef variableSub(&variable, magic + 2, variable.length() - magic - 2); - // Fill in variable value for later tests, if it exists - if (variables->contains(variableName.toString())) - variableValue = variables->value(variableName.toString()); + // Fill in variable value for later tests, if it exists + if (variables->contains(variableName.toString())) + variableValue = variables->value(variableName.toString()); - // find the operator who's after your colon - QChar op; - if (variable.length() > magic +1) - op = variable.at(magic + 1); + // find the operator who's after your colon + QChar op; + if (variable.length() > magic + 1) + op = variable.at(magic + 1); - switch(op.toLatin1()){ + switch (op.toLatin1()) { case '-': - // substitute default value if variable is empty - if (variableValue == "") - return variableSub.toString(); - break; + // substitute default value if variable is empty + if (variableValue == "") + return variableSub.toString(); + break; case '+': - // substitute default value if variable is not empty - if (variableValue != "") - return variableSub.toString(); - break; + // substitute default value if variable is not empty + if (variableValue != "") + return variableSub.toString(); + break; case '=': { - // %(%(foo):=bar?foobar|baz) - // if foo == bar then return foobar, else baz - QString sub = variableSub.toString(); - QString a = sub.left(sub.indexOf("?")); - QString b = sub.right(sub.length() - sub.indexOf("?") - 1); - if (b.indexOf("|") == -1) - return b; - if (variableName == a) - return b.left(b.indexOf("|")); - else - return b.right(b.length() - b.indexOf("|") - 1); + // %(%(foo):=bar?foobar|baz) + // if foo == bar then return foobar, else baz + QString sub = variableSub.toString(); + QString a = sub.left(sub.indexOf("?")); + QString b = sub.right(sub.length() - sub.indexOf("?") - 1); + if (b.indexOf("|") == -1) + return b; + if (variableName == a) + return b.left(b.indexOf("|")); + else + return b.right(b.length() - b.indexOf("|") - 1); + } } - } - // no proper substitution found -> return default value - return variableValue; + // no proper substitution found -> return default value + return variableValue; } -void SsuVariables::setSettings(SsuSettings *settings){ - m_settings = settings; +void SsuVariables::setSettings(SsuSettings *settings) +{ + m_settings = settings; } -SsuSettings *SsuVariables::settings(){ - return m_settings; +SsuSettings *SsuVariables::settings() +{ + return m_settings; } /// @todo add override capability with an override-section in ssu.ini -QVariant SsuVariables::variable(QString section, const QString &key){ - if (m_settings != NULL) - return variable(m_settings, section, key); - else - return QVariant(); +QVariant SsuVariables::variable(QString section, const QString &key) +{ + if (m_settings != NULL) + return variable(m_settings, section, key); + else + return QVariant(); } -QVariant SsuVariables::variable(SsuSettings *settings, QString section, const QString &key){ - QVariant value; +QVariant SsuVariables::variable(SsuSettings *settings, QString section, const QString &key) +{ + QVariant value; - value = readVariable(settings, section, key, 0); + value = readVariable(settings, section, key, 0); - // first check if the value is defined in the main section, and fall back - // to default sections - if (value.type() == QMetaType::UnknownType){ - QString dSection = defaultSection(settings, section); - if (!dSection.isEmpty()) - value = readVariable(settings, dSection, key, 0, false); - } + // first check if the value is defined in the main section, and fall back + // to default sections + if (value.type() == QMetaType::UnknownType) { + QString dSection = defaultSection(settings, section); + if (!dSection.isEmpty()) + value = readVariable(settings, dSection, key, 0, false); + } - return value; + return value; } -void SsuVariables::variableSection(QString section, QHash *storageHash){ - if (m_settings != NULL) - variableSection(m_settings, section, storageHash); +void SsuVariables::variableSection(QString section, QHash *storageHash) +{ + if (m_settings != NULL) + variableSection(m_settings, section, storageHash); } -void SsuVariables::variableSection(SsuSettings *settings, QString section, QHash *storageHash){ +void SsuVariables::variableSection(SsuSettings *settings, QString section, QHash *storageHash) +{ - QString dSection = defaultSection(settings, section); - if (dSection.isEmpty()) - readSection(settings, section, storageHash, 0); - else { - readSection(settings, dSection, storageHash, 0); - readSection(settings, section, storageHash, 0, false); - } + QString dSection = defaultSection(settings, section); + if (dSection.isEmpty()) + readSection(settings, section, storageHash, 0); + else { + readSection(settings, dSection, storageHash, 0); + readSection(settings, section, storageHash, 0, false); + } } // resolve a configuration section, recursively following all 'variables' sections. @@ -182,97 +192,99 @@ void SsuVariables::variableSection(SsuSettings *settings, QString section, QHash // the section itself gets evaluated at the end, again having a chance to overwrite variables void SsuVariables::readSection(SsuSettings *settings, QString section, QHash *storageHash, int recursionDepth, - bool logOverride){ - if (recursionDepth >= SSU_MAX_RECURSION){ - SsuLog::instance()->print(LOG_WARNING, - QString("Maximum recursion depth for resolving section %1 from %2") - .arg(section) - .arg(settings->fileName())); - return; - } - - if (settings->contains(section + "/variables")){ - // child should log unless the parent is a default section - bool childLogOverride = true; - if (section.startsWith("default-") || section.startsWith("var-default-")) - childLogOverride = false; - - QStringList sections = settings->value(section + "/variables").toStringList(); - foreach(const QString §ion, sections){ - if (section.startsWith("var-")) - readSection(settings, section, storageHash, recursionDepth + 1, childLogOverride); - else - readSection(settings, "var-" + section, storageHash, - recursionDepth + 1, childLogOverride); + bool logOverride) +{ + if (recursionDepth >= SSU_MAX_RECURSION) { + SsuLog::instance()->print(LOG_WARNING, + QString("Maximum recursion depth for resolving section %1 from %2") + .arg(section) + .arg(settings->fileName())); + return; } - } - - settings->beginGroup(section); - if (settings->group() != section) - return; - - QStringList locals; - if (settings->contains("local")) - locals = settings->value("local").toStringList(); - - QStringList keys = settings->allKeys(); - foreach (const QString &key, keys){ - // local variable - if (key.startsWith("_")) - continue; - - if (locals.contains(key)) - continue; - - if (key == "variables" || key == "local") - continue; - - if (storageHash->contains(key) && logOverride){ - SsuLog::instance()->print(LOG_DEBUG, - QString("Variable %1 overwritten from %2::%3") - .arg(key) - .arg(settings->fileName()) - .arg(section)); + + if (settings->contains(section + "/variables")) { + // child should log unless the parent is a default section + bool childLogOverride = true; + if (section.startsWith("default-") || section.startsWith("var-default-")) + childLogOverride = false; + + QStringList sections = settings->value(section + "/variables").toStringList(); + foreach (const QString §ion, sections) { + if (section.startsWith("var-")) + readSection(settings, section, storageHash, recursionDepth + 1, childLogOverride); + else + readSection(settings, "var-" + section, storageHash, + recursionDepth + 1, childLogOverride); + } } - storageHash->insert(key, settings->value(key).toString()); - } - settings->endGroup(); -} -QVariant SsuVariables::readVariable(SsuSettings *settings, QString section, const QString &key, - int recursionDepth, bool logOverride){ - QVariant value; + settings->beginGroup(section); + if (settings->group() != section) + return; + + QStringList locals; + if (settings->contains("local")) + locals = settings->value("local").toStringList(); + + QStringList keys = settings->allKeys(); + foreach (const QString &key, keys) { + // local variable + if (key.startsWith("_")) + continue; - if (recursionDepth >= SSU_MAX_RECURSION){ - SsuLog::instance()->print(LOG_WARNING, - QString("Maximum recursion depth for resolving %1 from %2::%3") + if (locals.contains(key)) + continue; + + if (key == "variables" || key == "local") + continue; + + if (storageHash->contains(key) && logOverride) { + SsuLog::instance()->print(LOG_DEBUG, + QString("Variable %1 overwritten from %2::%3") .arg(key) .arg(settings->fileName()) .arg(section)); - return value; - } - - // variables directly in the section take precedence - if (settings->contains(section + "/" + key)){ - return settings->value(section + "/" + key); - } - - /// @todo add logging for overrides - if (settings->contains(section + "/variables")){ - // child should log unless the parent is a default section - bool childLogOverride = true; - if (section.startsWith("default-") || section.startsWith("var-default-")) - childLogOverride = false; - - QStringList sections = settings->value(section + "/variables").toStringList(); - foreach(const QString §ion, sections){ - if (section.startsWith("var-")) - value = readVariable(settings, section, key, recursionDepth + 1, childLogOverride); - else - value = readVariable(settings, "var-" + section, key, - recursionDepth + 1, childLogOverride); + } + storageHash->insert(key, settings->value(key).toString()); + } + settings->endGroup(); +} + +QVariant SsuVariables::readVariable(SsuSettings *settings, QString section, const QString &key, + int recursionDepth, bool logOverride) +{ + QVariant value; + + if (recursionDepth >= SSU_MAX_RECURSION) { + SsuLog::instance()->print(LOG_WARNING, + QString("Maximum recursion depth for resolving %1 from %2::%3") + .arg(key) + .arg(settings->fileName()) + .arg(section)); + return value; + } + + // variables directly in the section take precedence + if (settings->contains(section + "/" + key)) { + return settings->value(section + "/" + key); } - } - return value; + /// @todo add logging for overrides + if (settings->contains(section + "/variables")) { + // child should log unless the parent is a default section + bool childLogOverride = true; + if (section.startsWith("default-") || section.startsWith("var-default-")) + childLogOverride = false; + + QStringList sections = settings->value(section + "/variables").toStringList(); + foreach (const QString §ion, sections) { + if (section.startsWith("var-")) + value = readVariable(settings, section, key, recursionDepth + 1, childLogOverride); + else + value = readVariable(settings, "var-" + section, key, + recursionDepth + 1, childLogOverride); + } + } + + return value; } diff --git a/libssu/ssuvariables_p.h b/libssu/ssuvariables_p.h index 2a36324..5a9c92e 100644 --- a/libssu/ssuvariables_p.h +++ b/libssu/ssuvariables_p.h @@ -13,10 +13,11 @@ #include "ssusettings_p.h" -class SsuVariables: public QObject { +class SsuVariables: public QObject +{ Q_OBJECT - public: +public: SsuVariables(); /** * Return a default variable section, if exists, or an empty string. @@ -29,7 +30,7 @@ class SsuVariables: public QObject { /** * Resolve a whole string, containing several variables. Variables inside variables are allowed */ - static QString resolveString(QString pattern, QHash *variables, int recursionDepth=0); + static QString resolveString(QString pattern, QHash *variables, int recursionDepth = 0); /** * Resolve variables; variable can be passed as %(var) or var */ @@ -67,12 +68,12 @@ class SsuVariables: public QObject { static void variableSection(SsuSettings *settings, QString section, QHash *storageHash); - private: +private: static void readSection(SsuSettings *settings, QString section, QHash *storageHash, int recursionDepth, - bool logOverride=true); + bool logOverride = true); static QVariant readVariable(SsuSettings *settings, QString section, const QString &key, - int recursionDepth, bool logOverride=true); + int recursionDepth, bool logOverride = true); SsuSettings *m_settings; }; diff --git a/ssucli/main.cpp b/ssucli/main.cpp index 5eedf8d..5b08a45 100644 --- a/ssucli/main.cpp +++ b/ssucli/main.cpp @@ -13,21 +13,22 @@ #include "libssunetworkproxy/ssunetworkproxy.h" #include "ssucli.h" -int main(int argc, char** argv){ - QCoreApplication app(argc, argv); - QCoreApplication::setOrganizationName("Jolla"); - QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); - QCoreApplication::setApplicationName("ssu"); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setOrganizationName("Jolla"); + QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); + QCoreApplication::setApplicationName("ssu"); - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&qtTranslator); + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + app.installTranslator(&qtTranslator); - set_application_proxy_factory(); + set_application_proxy_factory(); - SsuCli mw; - QTimer::singleShot(0, &mw, SLOT(run())); + SsuCli mw; + QTimer::singleShot(0, &mw, SLOT(run())); - return app.exec(); + return app.exec(); } diff --git a/ssucli/ssucli.cpp b/ssucli/ssucli.cpp index 41e6b23..f0926bc 100644 --- a/ssucli/ssucli.cpp +++ b/ssucli/ssucli.cpp @@ -19,699 +19,718 @@ #include "ssucli.h" -SsuCli::SsuCli(): QObject(){ - connect(this,SIGNAL(done()), - QCoreApplication::instance(),SLOT(quit()), Qt::DirectConnection); - connect(&ssu, SIGNAL(done()), - this, SLOT(handleResponse())); +SsuCli::SsuCli(): QObject() +{ + connect(this, SIGNAL(done()), + QCoreApplication::instance(), SLOT(quit()), Qt::DirectConnection); + connect(&ssu, SIGNAL(done()), + this, SLOT(handleResponse())); - ssuProxy = new SsuProxy("org.nemo.ssu", "/org/nemo/ssu", QDBusConnection::systemBus(), 0); + ssuProxy = new SsuProxy("org.nemo.ssu", "/org/nemo/ssu", QDBusConnection::systemBus(), 0); - connect(ssuProxy, SIGNAL(done()), - this, SLOT(handleDBusResponse())); + connect(ssuProxy, SIGNAL(done()), + this, SLOT(handleDBusResponse())); - state = Idle; + state = Idle; } -SsuCli::~SsuCli(){ - ssuProxy->quit(); +SsuCli::~SsuCli() +{ + ssuProxy->quit(); } -void SsuCli::handleResponse(){ - QTextStream qout(stdout); +void SsuCli::handleResponse() +{ + QTextStream qout(stdout); - if (ssu.error()){ - qout << "Last operation failed: \n" << ssu.lastError() << endl; - QCoreApplication::exit(1); - } else { - qout << "Operation successful (direct)" << endl; - QCoreApplication::exit(0); - } + if (ssu.error()) { + qout << "Last operation failed: \n" << ssu.lastError() << endl; + QCoreApplication::exit(1); + } else { + qout << "Operation successful (direct)" << endl; + QCoreApplication::exit(0); + } } -void SsuCli::handleDBusResponse(){ - QTextStream qout(stdout); +void SsuCli::handleDBusResponse() +{ + QTextStream qout(stdout); - if (ssuProxy->error()){ - qout << "Last operation failed: \n" << ssuProxy->lastError() << endl; - QCoreApplication::exit(1); - } else { - qout << "Operation successful" << endl; - QCoreApplication::exit(0); - } + if (ssuProxy->error()) { + qout << "Last operation failed: \n" << ssuProxy->lastError() << endl; + QCoreApplication::exit(1); + } else { + qout << "Operation successful" << endl; + QCoreApplication::exit(0); + } } -void SsuCli::optDomain(QStringList opt){ - QTextStream qout(stdout); +void SsuCli::optDomain(QStringList opt) +{ + QTextStream qout(stdout); - if (opt.count() == 3 && opt.at(2) == "-s"){ - qout << ssu.domain(); - state = Idle; - } else if (opt.count() == 3){ - qout << "Changing domain from " << ssu.domain() - << " to " << opt.at(2) << endl; - ssu.setDomain(opt.at(2)); + if (opt.count() == 3 && opt.at(2) == "-s") { + qout << ssu.domain(); + state = Idle; + } else if (opt.count() == 3) { + qout << "Changing domain from " << ssu.domain() + << " to " << opt.at(2) << endl; + ssu.setDomain(opt.at(2)); - state = Idle; - } else if (opt.count() == 2) { - qout << "Device domain is currently: " << ssu.domain() << endl; - state = Idle; - } + state = Idle; + } else if (opt.count() == 2) { + qout << "Device domain is currently: " << ssu.domain() << endl; + state = Idle; + } } -void SsuCli::optFlavour(QStringList opt){ - QTextStream qout(stdout); - QTextStream qerr(stderr); +void SsuCli::optFlavour(QStringList opt) +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); - if (opt.count() == 3 && opt.at(2) == "-s"){ - qout << ssu.flavour(); - state = Idle; - } else if (opt.count() == 3){ - qout << "Changing flavour from " << ssu.flavour() - << " to " << opt.at(2) << endl; + if (opt.count() == 3 && opt.at(2) == "-s") { + qout << ssu.flavour(); + state = Idle; + } else if (opt.count() == 3) { + qout << "Changing flavour from " << ssu.flavour() + << " to " << opt.at(2) << endl; - QDBusPendingReply<> reply = ssuProxy->setFlavour(opt.at(2)); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - ssu.setFlavour(opt.at(2)); + QDBusPendingReply<> reply = ssuProxy->setFlavour(opt.at(2)); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + ssu.setFlavour(opt.at(2)); - SsuRepoManager repoManager; - repoManager.update(); - uidWarning(); - } + SsuRepoManager repoManager; + repoManager.update(); + uidWarning(); + } - state = Idle; - } else if (opt.count() == 2) { - qout << "Device flavour is currently: " << ssu.flavour() << endl; - state = Idle; - } + state = Idle; + } else if (opt.count() == 2) { + qout << "Device flavour is currently: " << ssu.flavour() << endl; + state = Idle; + } } -void SsuCli::optMode(QStringList opt){ - QTextStream qout(stdout); - QTextStream qerr(stderr); - - // TODO: allow setting meaningful names instead of numbers - - if (opt.count() == 2){ - QStringList modeList; - int deviceMode = ssu.deviceMode(); - - if ((deviceMode & Ssu::DisableRepoManager) == Ssu::DisableRepoManager) - modeList.append("DisableRepoManager"); - if ((deviceMode & Ssu::RndMode) == Ssu::RndMode) - modeList.append("RndMode"); - if ((deviceMode & Ssu::ReleaseMode) == Ssu::ReleaseMode) - modeList.append("ReleaseMode"); - if ((deviceMode & Ssu::LenientMode) == Ssu::LenientMode) - modeList.append("LenientMode"); - if ((deviceMode & Ssu::UpdateMode) == Ssu::UpdateMode) - modeList.append("UpdateMode"); +void SsuCli::optMode(QStringList opt) +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); + + // TODO: allow setting meaningful names instead of numbers + + if (opt.count() == 2) { + QStringList modeList; + int deviceMode = ssu.deviceMode(); + + if ((deviceMode & Ssu::DisableRepoManager) == Ssu::DisableRepoManager) + modeList.append("DisableRepoManager"); + if ((deviceMode & Ssu::RndMode) == Ssu::RndMode) + modeList.append("RndMode"); + if ((deviceMode & Ssu::ReleaseMode) == Ssu::ReleaseMode) + modeList.append("ReleaseMode"); + if ((deviceMode & Ssu::LenientMode) == Ssu::LenientMode) + modeList.append("LenientMode"); + if ((deviceMode & Ssu::UpdateMode) == Ssu::UpdateMode) + modeList.append("UpdateMode"); if ((deviceMode & Ssu::AppInstallMode) == Ssu::AppInstallMode) - modeList.append("AppInstallMode"); - - qout << "Device mode is: " << ssu.deviceMode() - << " (" << modeList.join(" | ") << ")" << endl; + modeList.append("AppInstallMode"); - if ((deviceMode & Ssu::RndMode) == Ssu::RndMode && - (deviceMode & Ssu::ReleaseMode) == Ssu::ReleaseMode) - qout << "Both Release and RnD mode set, device is in RnD mode" << endl; - - state = Idle; - } else if (opt.count() == 3 && opt.at(2) == "-s"){ - qout << ssu.deviceMode(); - state = Idle; - } else if (opt.count() == 3){ - qout << "Setting device mode from " << ssu.deviceMode() - << " to " << opt.at(2) << endl; + qout << "Device mode is: " << ssu.deviceMode() + << " (" << modeList.join(" | ") << ")" << endl; - QDBusPendingReply<> reply = ssuProxy->setDeviceMode(opt.at(2).toInt()); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - ssu.setDeviceMode(Ssu::DeviceModeFlags(opt.at(2).toInt())); + if ((deviceMode & Ssu::RndMode) == Ssu::RndMode && + (deviceMode & Ssu::ReleaseMode) == Ssu::ReleaseMode) + qout << "Both Release and RnD mode set, device is in RnD mode" << endl; - SsuRepoManager repoManager; - repoManager.update(); - uidWarning(); - } + state = Idle; + } else if (opt.count() == 3 && opt.at(2) == "-s") { + qout << ssu.deviceMode(); + state = Idle; + } else if (opt.count() == 3) { + qout << "Setting device mode from " << ssu.deviceMode() + << " to " << opt.at(2) << endl; - state = Idle; - } -} + QDBusPendingReply<> reply = ssuProxy->setDeviceMode(opt.at(2).toInt()); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + ssu.setDeviceMode(Ssu::DeviceModeFlags(opt.at(2).toInt())); -void SsuCli::optModel(QStringList opt){ - QTextStream qout(stdout); - QTextStream qerr(stderr); - SsuDeviceInfo deviceInfo; + SsuRepoManager repoManager; + repoManager.update(); + uidWarning(); + } - if (opt.count() == 3 && opt.at(2) == "-s"){ - qout << deviceInfo.deviceModel(); - state = Idle; - } else if (opt.count() == 2){ - qout << "Device model is: " << deviceInfo.deviceModel() << endl; - state = Idle; - } + state = Idle; + } } -void SsuCli::optModifyRepo(enum Actions action, QStringList opt){ - SsuRepoManager repoManager; - QTextStream qout(stdout); - QTextStream qerr(stderr); +void SsuCli::optModel(QStringList opt) +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); + SsuDeviceInfo deviceInfo; - if (opt.count() == 3){ - QDBusPendingReply<> reply = ssuProxy->modifyRepo(action, opt.at(2)); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - - switch(action){ - case Add: - repoManager.add(opt.at(2)); - repoManager.update(); - uidWarning(); - break; - case Remove: - repoManager.remove(opt.at(2)); - repoManager.update(); - uidWarning(); - break; - case Disable: - repoManager.disable(opt.at(2)); - repoManager.update(); - uidWarning(); - break; - case Enable: - repoManager.enable(opt.at(2)); - repoManager.update(); - uidWarning(); - break; - } - } - } else if (opt.count() == 4 && action == Add){ - QString url, repo; - - if (opt.at(2).indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) == 0){ - url = opt.at(2); - repo = opt.at(3); - } else if (opt.at(3).indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) == 0){ - url = opt.at(3); - repo = opt.at(2); - } else { - qerr << "Invalid parameters for 'ssu ar': URL required." << endl; - return; + if (opt.count() == 3 && opt.at(2) == "-s") { + qout << deviceInfo.deviceModel(); + state = Idle; + } else if (opt.count() == 2) { + qout << "Device model is: " << deviceInfo.deviceModel() << endl; + state = Idle; } +} - QDBusPendingReply<> reply = ssuProxy->addRepo(repo, url); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - repoManager.add(repo, url); - repoManager.update(); - uidWarning(); +void SsuCli::optModifyRepo(enum Actions action, QStringList opt) +{ + SsuRepoManager repoManager; + QTextStream qout(stdout); + QTextStream qerr(stderr); + + if (opt.count() == 3) { + QDBusPendingReply<> reply = ssuProxy->modifyRepo(action, opt.at(2)); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + + switch (action) { + case Add: + repoManager.add(opt.at(2)); + repoManager.update(); + uidWarning(); + break; + case Remove: + repoManager.remove(opt.at(2)); + repoManager.update(); + uidWarning(); + break; + case Disable: + repoManager.disable(opt.at(2)); + repoManager.update(); + uidWarning(); + break; + case Enable: + repoManager.enable(opt.at(2)); + repoManager.update(); + uidWarning(); + break; + } + } + } else if (opt.count() == 4 && action == Add) { + QString url, repo; + + if (opt.at(2).indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) == 0) { + url = opt.at(2); + repo = opt.at(3); + } else if (opt.at(3).indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) == 0) { + url = opt.at(3); + repo = opt.at(2); + } else { + qerr << "Invalid parameters for 'ssu ar': URL required." << endl; + return; + } + + QDBusPendingReply<> reply = ssuProxy->addRepo(repo, url); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + repoManager.add(repo, url); + repoManager.update(); + uidWarning(); + } } - } } -void SsuCli::optRegister(QStringList opt){ - /* - * register a new device - */ +void SsuCli::optRegister(QStringList opt) +{ + /* + * register a new device + */ - QString username, password; - QTextStream qin(stdin); - QTextStream qout(stdout); - QTextStream qerr(stderr); - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + QString username, password; + QTextStream qin(stdin); + QTextStream qout(stdout); + QTextStream qerr(stderr); + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - struct termios termNew, termOld; + struct termios termNew, termOld; - qout << "Username: " << flush; - username = qin.readLine(); + qout << "Username: " << flush; + username = qin.readLine(); - tcgetattr(STDIN_FILENO, &termNew); - termOld = termNew; - termNew.c_lflag &= ~ECHO; - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &termNew) == -1) - qout << "WARNING: Unable to disable echo on your terminal, password will echo!" << endl; + tcgetattr(STDIN_FILENO, &termNew); + termOld = termNew; + termNew.c_lflag &= ~ECHO; + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &termNew) == -1) + qout << "WARNING: Unable to disable echo on your terminal, password will echo!" << endl; - qout << "Password: " << flush; - password = qin.readLine(); - qout << endl; + qout << "Password: " << flush; + password = qin.readLine(); + qout << endl; - tcsetattr(STDIN_FILENO, TCSANOW, &termOld); + tcsetattr(STDIN_FILENO, TCSANOW, &termOld); - if (opt.count() == 3 && opt.at(2) == "-h") - ssuSettings->setValue("repository-url-variables/user", username); + if (opt.count() == 3 && opt.at(2) == "-h") + ssuSettings->setValue("repository-url-variables/user", username); - QDBusPendingReply<> reply = ssuProxy->registerDevice(username, password); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - qerr << reply.error().message() << endl; - ssu.sendRegistration(username, password); - } + QDBusPendingReply<> reply = ssuProxy->registerDevice(username, password); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + qerr << reply.error().message() << endl; + ssu.sendRegistration(username, password); + } - state = Busy; + state = Busy; } -void SsuCli::optRelease(QStringList opt){ - QTextStream qout(stdout); - QTextStream qerr(stderr); - - if (opt.count() == 3){ - if (opt.at(2) == "-r"){ - qout << "Device release (RnD) is currently: " << ssu.release(true) << endl; - state = Idle; - } else { - qout << "Changing release from " << ssu.release() - << " to " << opt.at(2) << endl; - qout << "Your device is now in release mode!" << endl; - - QDBusPendingReply<> reply = ssuProxy->setRelease(opt.at(2), false); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - ssu.setRelease(opt.at(2)); +void SsuCli::optRelease(QStringList opt) +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); + + if (opt.count() == 3) { + if (opt.at(2) == "-r") { + qout << "Device release (RnD) is currently: " << ssu.release(true) << endl; + state = Idle; + } else { + qout << "Changing release from " << ssu.release() + << " to " << opt.at(2) << endl; + qout << "Your device is now in release mode!" << endl; + + QDBusPendingReply<> reply = ssuProxy->setRelease(opt.at(2), false); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + ssu.setRelease(opt.at(2)); + + SsuRepoManager repoManager; + repoManager.update(); + uidWarning(); + } + + state = Idle; + } + } else if (opt.count() == 2) { + qout << "Device release is currently: " << ssu.release() << endl; + state = Idle; + } else if (opt.count() == 4 && opt.at(2) == "-r") { + qout << "Changing release (RnD) from " << ssu.release(true) + << " to " << opt.at(3) << endl; + qout << "Your device is now in RnD mode!" << endl; + + QDBusPendingReply<> reply = ssuProxy->setRelease(opt.at(3), true); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + ssu.setRelease(opt.at(3), true); + + SsuRepoManager repoManager; + repoManager.update(); + uidWarning(); + } - SsuRepoManager repoManager; - repoManager.update(); - uidWarning(); - } + state = Idle; + } +} - state = Idle; +void SsuCli::optRepos(QStringList opt) +{ + QTextStream qout(stdout); + SsuRepoManager repoManager; + SsuDeviceInfo deviceInfo; + QHash repoParameters, repoOverride; + QString device = ""; + bool rndRepo = false; + int micMode = 0, flagStart = 0; + + if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) + rndRepo = true; + + if (opt.count() >= 3 && opt.at(2) == "-m") { + micMode = 1; + // TODO: read the default mic override variables from some config + /* + repoOverride.insert("release", "@RELEASE@"); + repoOverride.insert("rndRelease", "@RNDRELEASE@"); + repoOverride.insert("flavour", "@FLAVOUR@"); + repoOverride.insert("arch", "@ARCH@"); + */ } - } else if (opt.count() == 2) { - qout << "Device release is currently: " << ssu.release() << endl; - state = Idle; - } else if (opt.count() == 4 && opt.at(2) == "-r"){ - qout << "Changing release (RnD) from " << ssu.release(true) - << " to " << opt.at(3) << endl; - qout << "Your device is now in RnD mode!" << endl; - QDBusPendingReply<> reply = ssuProxy->setRelease(opt.at(3), true); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - ssu.setRelease(opt.at(3), true); + if (opt.count() >= 3 + micMode) { + // first argument is flag + if (opt.at(2 + micMode).contains("=")) { + flagStart = 2 + micMode; + } else if (!opt.at(2 + micMode).contains("=") && + opt.count() == 3 + micMode) { + // first (and only) argument is device) + device = opt.at(2 + micMode); + } else if (!opt.at(2 + micMode).contains("=") && + opt.count() > 3 + micMode && + opt.at(3 + micMode).contains("=")) { + // first argument is device, second flag + device = opt.at(2 + micMode); + flagStart = 3 + micMode; + } else { + state = UserError; + return; + } + } - SsuRepoManager repoManager; - repoManager.update(); - uidWarning(); + if (flagStart != 0) { + for (int i = flagStart; i < opt.count(); i++) { + if (opt.at(i).count("=") != 1) { + qout << "Invalid flag: " << opt.at(i) << endl; + state = Idle; + return; + } + QStringList split = opt.at(i).split("="); + repoOverride.insert(split.at(0), split.at(1)); + } } - state = Idle; - } -} + if (repoOverride.contains("rnd")) { + if (repoOverride.value("rnd") == "true") + rndRepo = true; + else if (repoOverride.value("rnd") == "false") + rndRepo = false; + } -void SsuCli::optRepos(QStringList opt){ - QTextStream qout(stdout); - SsuRepoManager repoManager; - SsuDeviceInfo deviceInfo; - QHash repoParameters, repoOverride; - QString device=""; - bool rndRepo = false; - int micMode=0, flagStart = 0; - - if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) - rndRepo = true; - - if (opt.count() >= 3 && opt.at(2) == "-m"){ - micMode = 1; - // TODO: read the default mic override variables from some config - /* - repoOverride.insert("release", "@RELEASE@"); - repoOverride.insert("rndRelease", "@RNDRELEASE@"); - repoOverride.insert("flavour", "@FLAVOUR@"); - repoOverride.insert("arch", "@ARCH@"); - */ - } - - if (opt.count() >= 3 + micMode){ - // first argument is flag - if (opt.at(2 + micMode).contains("=")){ - flagStart = 2 + micMode; - } else if (!opt.at(2 + micMode).contains("=") && - opt.count() == 3 + micMode) { - // first (and only) argument is device) - device = opt.at(2 + micMode); - } else if(!opt.at(2 + micMode).contains("=") && - opt.count() > 3 + micMode && - opt.at(3 + micMode).contains("=")){ - // first argument is device, second flag - device = opt.at(2 + micMode); - flagStart = 3 + micMode; - } else { - state = UserError; - return; + if (device != "") { + deviceInfo.setDeviceModel(device); + repoOverride.insert("model", device); } - } - if (flagStart != 0){ - for (int i=flagStart; i longestField) - longestField = repo.length(); - - qout.setFieldAlignment(QTextStream::AlignLeft); - - foreach (const QString &repo, repos){ - QString repoName = repo; - if (repo.endsWith("-debuginfo")){ - repoName = repo.left(repo.size() - 10); - repoParameters.insert("debugSplit", "debug"); - } else if (repoParameters.value("debugSplit") == "debug") - repoParameters.remove("debugSplit"); - - QString repoUrl = ssu.repoUrl(repoName, rndRepo, repoParameters, repoOverride); - qout << " - " << qSetFieldWidth(longestField) << repo << qSetFieldWidth(0) << " ... " << repoUrl << endl; + + if (device.isEmpty()) + repos = repoManager.repos(rndRepo, deviceInfo, Ssu::BoardFilterUserBlacklist); + else { + qout << "Printing repository configuration for '" << device << "'" << endl << endl; + repos = repoManager.repos(rndRepo, deviceInfo, Ssu::BoardFilter); } - if (i==0){ - if (device != ""){ - repos.clear(); - continue; - } - repos = repoManager.repos(rndRepo, deviceInfo, Ssu::UserFilter); - qout << endl << "Enabled repositories (user): " << endl; - } else if (i==1){ - repos = deviceInfo.disabledRepos(); - if (device.isEmpty()) - qout << endl << "Disabled repositories (global, might be overridden by user config): " << endl; - else - qout << endl << "Disabled repositories (global): " << endl; - } else if (i==2) { - repos.clear(); - if (device != "") - continue; - if (ssuSettings->contains("disabled-repos")) - repos.append(ssuSettings->value("disabled-repos").toStringList()); - qout << endl << "Disabled repositories (user): " << endl; + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + + qout << "Enabled repositories (global): " << endl; + for (int i = 0; i <= 3; i++) { + // for each repository, print repo and resolve url + int longestField = 0; + foreach (const QString &repo, repos) + if (repo.length() > longestField) + longestField = repo.length(); + + qout.setFieldAlignment(QTextStream::AlignLeft); + + foreach (const QString &repo, repos) { + QString repoName = repo; + if (repo.endsWith("-debuginfo")) { + repoName = repo.left(repo.size() - 10); + repoParameters.insert("debugSplit", "debug"); + } else if (repoParameters.value("debugSplit") == "debug") + repoParameters.remove("debugSplit"); + + QString repoUrl = ssu.repoUrl(repoName, rndRepo, repoParameters, repoOverride); + qout << " - " << qSetFieldWidth(longestField) << repo << qSetFieldWidth(0) << " ... " << repoUrl << endl; + } + + if (i == 0) { + if (device != "") { + repos.clear(); + continue; + } + repos = repoManager.repos(rndRepo, deviceInfo, Ssu::UserFilter); + qout << endl << "Enabled repositories (user): " << endl; + } else if (i == 1) { + repos = deviceInfo.disabledRepos(); + if (device.isEmpty()) + qout << endl << "Disabled repositories (global, might be overridden by user config): " << endl; + else + qout << endl << "Disabled repositories (global): " << endl; + } else if (i == 2) { + repos.clear(); + if (device != "") + continue; + if (ssuSettings->contains("disabled-repos")) + repos.append(ssuSettings->value("disabled-repos").toStringList()); + qout << endl << "Disabled repositories (user): " << endl; + } } - } - state = Idle; + state = Idle; } -void SsuCli::optSet(QStringList opt){ - QTextStream qout(stdout); - SsuVariables var; - SsuCoreConfig *settings = SsuCoreConfig::instance(); - QHash storageHash; - - // set repository specific variable - if (opt.count() == 5 && opt.at(2) == "-r"){ - settings->setValue("repository-url-variables/" + opt.at(3), opt.at(4)); - // clear repo specific variable - } else if (opt.count() == 4 && opt.at(2) == "-r"){ - settings->remove("repository-url-variables/" + opt.at(3)); - // list repo specific variables - } else if (opt.count() == 3 && opt.at(2) == "-r"){ - qout << "Repository specific variables:" << endl << endl; - var.variableSection(settings, "repository-url-variables", &storageHash); - // set global variable - } else if (opt.count() == 4){ - settings->setValue("global-variables/" + opt.at(2), opt.at(3)); - // clear global variable - } else if (opt.count() == 3){ - settings->remove("global-variables/" + opt.at(2)); - // list global variables - } else if (opt.count() == 2){ - qout << "Global variables:" << endl << endl; - var.variableSection(settings, "global-variables", &storageHash); - } - - settings->sync(); - - if (!storageHash.isEmpty()){ - QHash::const_iterator i = storageHash.constBegin(); - while (i != storageHash.constEnd()){ - qout << i.key() << "=" << i.value() << endl; - i++; +void SsuCli::optSet(QStringList opt) +{ + QTextStream qout(stdout); + SsuVariables var; + SsuCoreConfig *settings = SsuCoreConfig::instance(); + QHash storageHash; + + // set repository specific variable + if (opt.count() == 5 && opt.at(2) == "-r") { + settings->setValue("repository-url-variables/" + opt.at(3), opt.at(4)); + // clear repo specific variable + } else if (opt.count() == 4 && opt.at(2) == "-r") { + settings->remove("repository-url-variables/" + opt.at(3)); + // list repo specific variables + } else if (opt.count() == 3 && opt.at(2) == "-r") { + qout << "Repository specific variables:" << endl << endl; + var.variableSection(settings, "repository-url-variables", &storageHash); + // set global variable + } else if (opt.count() == 4) { + settings->setValue("global-variables/" + opt.at(2), opt.at(3)); + // clear global variable + } else if (opt.count() == 3) { + settings->remove("global-variables/" + opt.at(2)); + // list global variables + } else if (opt.count() == 2) { + qout << "Global variables:" << endl << endl; + var.variableSection(settings, "global-variables", &storageHash); } - } - state = Idle; + settings->sync(); + + if (!storageHash.isEmpty()) { + QHash::const_iterator i = storageHash.constBegin(); + while (i != storageHash.constEnd()) { + qout << i.key() << "=" << i.value() << endl; + i++; + } + } + + state = Idle; } -void SsuCli::optStatus(QStringList opt){ - QTextStream qout(stdout); - QTextStream qerr(stderr); - SsuDeviceInfo deviceInfo; - - /* - * print device information and registration status - */ - - QString deviceUid; - - QDBusPendingReply reply = ssuProxy->deviceUid(); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus unavailable, UUID not necessarily connected to reality." << endl; - deviceUid = deviceInfo.deviceUid(); - } else - deviceUid = reply.value(); - - qout << "Device registration status: " - << (ssu.isRegistered() ? "registered" : "not registered") << endl; - qout << "Device model: " << deviceInfo.displayName(Ssu::DeviceModel) << " (" - << deviceInfo.deviceModel() << " / " - << deviceInfo.displayName(Ssu::DeviceDesignation) << ")" << endl; - if (deviceInfo.deviceVariant() != "") - qout << "Device variant: " << deviceInfo.deviceVariant() << endl; - qout << "Device UID: " << deviceUid << endl; - if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) - qout << "Release (rnd): " << ssu.release(true) << " (" << ssu.flavour() << ")" << endl; - else - qout << "Release: " << ssu.release() << endl; - qout << "Domain: " << ssu.domain() << endl; +void SsuCli::optStatus(QStringList opt) +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); + SsuDeviceInfo deviceInfo; + + /* + * print device information and registration status + */ + + QString deviceUid; + + QDBusPendingReply reply = ssuProxy->deviceUid(); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus unavailable, UUID not necessarily connected to reality." << endl; + deviceUid = deviceInfo.deviceUid(); + } else + deviceUid = reply.value(); + + qout << "Device registration status: " + << (ssu.isRegistered() ? "registered" : "not registered") << endl; + qout << "Device model: " << deviceInfo.displayName(Ssu::DeviceModel) << " (" + << deviceInfo.deviceModel() << " / " + << deviceInfo.displayName(Ssu::DeviceDesignation) << ")" << endl; + if (deviceInfo.deviceVariant() != "") + qout << "Device variant: " << deviceInfo.deviceVariant() << endl; + qout << "Device UID: " << deviceUid << endl; + if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) + qout << "Release (rnd): " << ssu.release(true) << " (" << ssu.flavour() << ")" << endl; + else + qout << "Release: " << ssu.release() << endl; + qout << "Domain: " << ssu.domain() << endl; } -void SsuCli::optUpdateCredentials(QStringList opt){ - QTextStream qout(stdout); - /* - * update the credentials - * optional argument: -f - */ - bool force=false; - if (opt.count() == 3 && opt.at(2) == "-f") - force=true; - - if (!ssu.isRegistered()){ - qout << "Device is not registered, can't update credentials" << endl; - state = Idle; - QCoreApplication::exit(1); - } else { - ssu.updateCredentials(force); - state = Busy; - } +void SsuCli::optUpdateCredentials(QStringList opt) +{ + QTextStream qout(stdout); + /* + * update the credentials + * optional argument: -f + */ + bool force = false; + if (opt.count() == 3 && opt.at(2) == "-f") + force = true; + + if (!ssu.isRegistered()) { + qout << "Device is not registered, can't update credentials" << endl; + state = Idle; + QCoreApplication::exit(1); + } else { + ssu.updateCredentials(force); + state = Busy; + } } -void SsuCli::optUpdateRepos(QStringList opt){ - QTextStream qerr(stdout); +void SsuCli::optUpdateRepos(QStringList opt) +{ + QTextStream qerr(stdout); - QDBusPendingReply<> reply = ssuProxy->updateRepos(); - reply.waitForFinished(); - if (reply.isError()){ - qerr << "DBus call failed, falling back to libssu" << endl; - SsuRepoManager repoManager; - repoManager.update(); - uidWarning(); - } + QDBusPendingReply<> reply = ssuProxy->updateRepos(); + reply.waitForFinished(); + if (reply.isError()) { + qerr << "DBus call failed, falling back to libssu" << endl; + SsuRepoManager repoManager; + repoManager.update(); + uidWarning(); + } } -void SsuCli::run(){ - QTextStream qout(stdout); - QTextStream qerr(stderr); - - QStringList arguments = QCoreApplication::arguments(); - - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - if (!ssuSettings->isWritable()) - qerr << "WARNING: ssu.ini does not seem to be writable. Setting values might not work." << endl; - - // make sure there's a first argument to parse - if (arguments.count() < 2){ - usage(); - return; - } - - struct { - const char *longopt; // long option name - const char *shortopt; // option shortcut name - int minargs; // minimum number of required args - int maxargs; // -1 for "function will handle max args" - void (SsuCli::*handler)(QStringList opt); // handler function - } handlers[] = { - // functions accepting no additional arguments - "status", "s", 0, 0, &SsuCli::optStatus, - "updaterepos", "ur", 0, 0, &SsuCli::optUpdateRepos, - - // functions requiring at least one argument - "addrepo", "ar", 1, 2, &SsuCli::optAddRepo, - "removerepo", "rr", 1, 1, &SsuCli::optRemoveRepo, - "enablerepo", "er", 1, 1, &SsuCli::optEnableRepo, - "disablerepo", "dr", 1, 1, &SsuCli::optDisableRepo, - - // functions accepting 0 or more arguments - // those need to set state to Idle on success - "register", "r", 0, -1, &SsuCli::optRegister, - "repos", "lr", 0, -1, &SsuCli::optRepos, - "flavour", "fl", 0, -1, &SsuCli::optFlavour, - "mode", "m", 0, -1, &SsuCli::optMode, - "model", "mo", 0, -1, &SsuCli::optModel, - "release", "re", 0, -1, &SsuCli::optRelease, - "update", "up", 0, -1, &SsuCli::optUpdateCredentials, - "domain", "do", 0, -1, &SsuCli::optDomain, - "set", "set", 0, -1, &SsuCli::optSet, - }; - - bool found = false; - int argc = arguments.count() - 2; - - for (int i=0; i handlers[i].maxargs) { - usage(QString("%1: Too many arguments").arg(handlers[i].longopt)); - return; - } - - // Call option handler - (this->*(handlers[i].handler))(arguments); - - found = true; - break; - } - - if (!found) - state = UserError; - - // functions that need to wait for a response from ssu should set a flag so - // we can do default exit catchall here - if (state == Idle) - QCoreApplication::exit(0); - else if (state == UserError) - usage(); +void SsuCli::run() +{ + QTextStream qout(stdout); + QTextStream qerr(stderr); + + QStringList arguments = QCoreApplication::arguments(); + + SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); + if (!ssuSettings->isWritable()) + qerr << "WARNING: ssu.ini does not seem to be writable. Setting values might not work." << endl; + + // make sure there's a first argument to parse + if (arguments.count() < 2) { + usage(); + return; + } + + struct { + const char *longopt; // long option name + const char *shortopt; // option shortcut name + int minargs; // minimum number of required args + int maxargs; // -1 for "function will handle max args" + void (SsuCli::*handler)(QStringList opt); // handler function + } handlers[] = { + // functions accepting no additional arguments + "status", "s", 0, 0, &SsuCli::optStatus, + "updaterepos", "ur", 0, 0, &SsuCli::optUpdateRepos, + + // functions requiring at least one argument + "addrepo", "ar", 1, 2, &SsuCli::optAddRepo, + "removerepo", "rr", 1, 1, &SsuCli::optRemoveRepo, + "enablerepo", "er", 1, 1, &SsuCli::optEnableRepo, + "disablerepo", "dr", 1, 1, &SsuCli::optDisableRepo, + + // functions accepting 0 or more arguments + // those need to set state to Idle on success + "register", "r", 0, -1, &SsuCli::optRegister, + "repos", "lr", 0, -1, &SsuCli::optRepos, + "flavour", "fl", 0, -1, &SsuCli::optFlavour, + "mode", "m", 0, -1, &SsuCli::optMode, + "model", "mo", 0, -1, &SsuCli::optModel, + "release", "re", 0, -1, &SsuCli::optRelease, + "update", "up", 0, -1, &SsuCli::optUpdateCredentials, + "domain", "do", 0, -1, &SsuCli::optDomain, + "set", "set", 0, -1, &SsuCli::optSet, + }; + + bool found = false; + int argc = arguments.count() - 2; + + for (int i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) { + if ((arguments.at(1) != handlers[i].longopt) && + (arguments.at(1) != handlers[i].shortopt)) { + continue; + } + + if (argc < handlers[i].minargs) { + usage(QString("%1: Too few arguments").arg(handlers[i].longopt)); + return; + } + + if (handlers[i].maxargs != -1 && argc > handlers[i].maxargs) { + usage(QString("%1: Too many arguments").arg(handlers[i].longopt)); + return; + } + + // Call option handler + (this->*(handlers[i].handler))(arguments); + + found = true; + break; + } + + if (!found) + state = UserError; + + // functions that need to wait for a response from ssu should set a flag so + // we can do default exit catchall here + if (state == Idle) + QCoreApplication::exit(0); + else if (state == UserError) + usage(); } -void SsuCli::uidWarning(QString message){ - if (message.isEmpty()) - message = "Run 'ssu ur' as root to recreate repository files"; +void SsuCli::uidWarning(QString message) +{ + if (message.isEmpty()) + message = "Run 'ssu ur' as root to recreate repository files"; - if (geteuid() != 0){ - QTextStream qout(stderr); - qout << "You're not root. " << message << endl; - } + if (geteuid() != 0) { + QTextStream qout(stderr); + qout << "You're not root. " << message << endl; + } } -void SsuCli::usage(QString message){ - QTextStream qout(stderr); - qout << "\nUsage: ssu [-command-options] [arguments]" << endl - << endl - << "Repository management:" << endl - << "\tupdaterepos, ur \tupdate repository files" << endl - << "\trepos, lr \tlist configured repositories" << endl - << "\t [-m] \tformat output suitable for kickstart" << endl - << "\t [device] \tuse repos for 'device'" << endl - << "\t [flags] \tadditional flags" << endl - << "\t rnd= \tset rnd or release mode (default: take from host)" << endl - << "\taddrepo, ar \tadd this repository" << endl - << "\t [url] \tspecify URL, if not configured" << endl - << "\tremoverepo, rr \tremove this repository from configuration" << endl - << "\tenablerepo, er \tenable this repository" << endl - << "\tdisablerepo, dr \tdisable this repository" << endl - << endl - << "Configuration management:" << endl - << "\tflavour, fl \tdisplay flavour used (RnD only)" << endl - << "\t [newflavour] \tset new flavour" << endl - << "\trelease, re \tdisplay release used" << endl - << "\t [-r] \tuse RnD release" << endl - << "\t [newrelease] \tset new (RnD)release" << endl - << "\tset \tdisplay global variables" << endl - << "\t [-r] \toperate on repository only variables" << endl - << "\t \tdisplay value of " << endl - << "\t \tset value of to " << endl - << endl - << "Device management:" << endl - << "\tstatus, s \tprint registration status and device information" << endl - << "\tregister, r \tregister this device" << endl - << "\t [-h] \tconfigure user for OBS home" << endl - << "\tupdate, up \tupdate repository credentials" << endl - << "\t [-f] \tforce update" << endl - << "\tmodel, mo \tprint name of device model (like N9)" << endl - << endl; - if (!message.isEmpty()) - qout << message << endl; - qout.flush(); - QCoreApplication::exit(1); +void SsuCli::usage(QString message) +{ + QTextStream qout(stderr); + qout << "\nUsage: ssu [-command-options] [arguments]" << endl + << endl + << "Repository management:" << endl + << "\tupdaterepos, ur \tupdate repository files" << endl + << "\trepos, lr \tlist configured repositories" << endl + << "\t [-m] \tformat output suitable for kickstart" << endl + << "\t [device] \tuse repos for 'device'" << endl + << "\t [flags] \tadditional flags" << endl + << "\t rnd= \tset rnd or release mode (default: take from host)" << endl + << "\taddrepo, ar \tadd this repository" << endl + << "\t [url] \tspecify URL, if not configured" << endl + << "\tremoverepo, rr \tremove this repository from configuration" << endl + << "\tenablerepo, er \tenable this repository" << endl + << "\tdisablerepo, dr \tdisable this repository" << endl + << endl + << "Configuration management:" << endl + << "\tflavour, fl \tdisplay flavour used (RnD only)" << endl + << "\t [newflavour] \tset new flavour" << endl + << "\trelease, re \tdisplay release used" << endl + << "\t [-r] \tuse RnD release" << endl + << "\t [newrelease] \tset new (RnD)release" << endl + << "\tset \tdisplay global variables" << endl + << "\t [-r] \toperate on repository only variables" << endl + << "\t \tdisplay value of " << endl + << "\t \tset value of to " << endl + << endl + << "Device management:" << endl + << "\tstatus, s \tprint registration status and device information" << endl + << "\tregister, r \tregister this device" << endl + << "\t [-h] \tconfigure user for OBS home" << endl + << "\tupdate, up \tupdate repository credentials" << endl + << "\t [-f] \tforce update" << endl + << "\tmodel, mo \tprint name of device model (like N9)" << endl + << endl; + if (!message.isEmpty()) + qout << message << endl; + qout.flush(); + QCoreApplication::exit(1); } diff --git a/ssucli/ssucli.h b/ssucli/ssucli.h index 91380c1..d33daab 100644 --- a/ssucli/ssucli.h +++ b/ssucli/ssucli.h @@ -16,23 +16,24 @@ #include "libssu/ssu.h" #include "ssuproxy.h" -class SsuCli: public QObject { +class SsuCli: public QObject +{ Q_OBJECT - public: +public: SsuCli(); ~SsuCli(); - public slots: +public slots: void run(); - private: +private: Ssu ssu; SsuProxy *ssuProxy; QSettings settings; int state; - void usage(QString message=""); - void uidWarning(QString message=""); + void usage(QString message = ""); + void uidWarning(QString message = ""); void optDomain(QStringList opt); void optFlavour(QStringList opt); void optMode(QStringList opt); @@ -46,30 +47,42 @@ class SsuCli: public QObject { void optUpdateRepos(QStringList opt); enum Actions { - Remove = 0, - Add = 1, - Disable = 2, - Enable = 3, + Remove = 0, + Add = 1, + Disable = 2, + Enable = 3, }; void optModifyRepo(enum Actions action, QStringList opt); - void optAddRepo(QStringList opt) { optModifyRepo(Add, opt); } - void optRemoveRepo(QStringList opt) { optModifyRepo(Remove, opt); } - void optEnableRepo(QStringList opt) { optModifyRepo(Enable, opt); } - void optDisableRepo(QStringList opt) { optModifyRepo(Disable, opt); } + void optAddRepo(QStringList opt) + { + optModifyRepo(Add, opt); + } + void optRemoveRepo(QStringList opt) + { + optModifyRepo(Remove, opt); + } + void optEnableRepo(QStringList opt) + { + optModifyRepo(Enable, opt); + } + void optDisableRepo(QStringList opt) + { + optModifyRepo(Disable, opt); + } enum State { - Idle, - Busy, - UserError + Idle, + Busy, + UserError }; - private slots: +private slots: void handleResponse(); void handleDBusResponse(); - signals: +signals: void done(); }; diff --git a/ssud/main.cpp b/ssud/main.cpp index 2ec828c..62d757c 100644 --- a/ssud/main.cpp +++ b/ssud/main.cpp @@ -12,20 +12,21 @@ #include "libssunetworkproxy/ssunetworkproxy.h" #include "ssud.h" -int main(int argc, char** argv){ - QCoreApplication app(argc, argv); - QCoreApplication::setOrganizationName("Jolla"); - QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); - QCoreApplication::setApplicationName("ssud"); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setOrganizationName("Jolla"); + QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); + QCoreApplication::setApplicationName("ssud"); - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&qtTranslator); + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + app.installTranslator(&qtTranslator); - set_application_proxy_factory(); + set_application_proxy_factory(); - Ssud ssud; + Ssud ssud; - app.exec(); + app.exec(); } diff --git a/ssud/ssud.cpp b/ssud/ssud.cpp index 864abac..fc9d8fa 100644 --- a/ssud/ssud.cpp +++ b/ssud/ssud.cpp @@ -16,192 +16,216 @@ const char *Ssud::SERVICE_NAME = "org.nemo.ssu"; const char *Ssud::OBJECT_PATH = "/org/nemo/ssu"; -Ssud::Ssud(QObject *parent): QObject(parent){ - QDBusConnection connection = QDBusConnection::systemBus(); - if (!connection.registerObject(OBJECT_PATH, this)) { - qFatal("Cannot register object at %s", OBJECT_PATH); - } +Ssud::Ssud(QObject *parent): QObject(parent) +{ + QDBusConnection connection = QDBusConnection::systemBus(); + if (!connection.registerObject(OBJECT_PATH, this)) { + qFatal("Cannot register object at %s", OBJECT_PATH); + } - if (!connection.registerService(SERVICE_NAME)) { - qFatal("Cannot register D-Bus service at %s", SERVICE_NAME); - } + if (!connection.registerService(SERVICE_NAME)) { + qFatal("Cannot register D-Bus service at %s", SERVICE_NAME); + } - // prepare for controlled suicide on boredom - const int AUTOCLOSE_TIMEOUT_MS = 180 * 1000; + // prepare for controlled suicide on boredom + const int AUTOCLOSE_TIMEOUT_MS = 180 * 1000; - autoclose.setSingleShot(true); - autoclose.setInterval(AUTOCLOSE_TIMEOUT_MS); + autoclose.setSingleShot(true); + autoclose.setInterval(AUTOCLOSE_TIMEOUT_MS); - connect(&autoclose, SIGNAL(timeout()), - this, SLOT(quit())); + connect(&autoclose, SIGNAL(timeout()), + this, SLOT(quit())); - new SsuAdaptor(this); + new SsuAdaptor(this); - connect(&ssu, SIGNAL(done()), - this, SIGNAL(done())); - connect(&ssu, SIGNAL(credentialsChanged()), - this, SIGNAL(credentialsChanged())); - connect(&ssu, SIGNAL(registrationStatusChanged()), - this, SIGNAL(registrationStatusChanged())); + connect(&ssu, SIGNAL(done()), + this, SIGNAL(done())); + connect(&ssu, SIGNAL(credentialsChanged()), + this, SIGNAL(credentialsChanged())); + connect(&ssu, SIGNAL(registrationStatusChanged()), + this, SIGNAL(registrationStatusChanged())); - // a cry for help everytime we do something to prevent suicide - autoclose.start(); + // a cry for help everytime we do something to prevent suicide + autoclose.start(); } -Ssud::~Ssud(){ +Ssud::~Ssud() +{ } -QString Ssud::deviceModel(){ - SsuDeviceInfo deviceInfo; +QString Ssud::deviceModel() +{ + SsuDeviceInfo deviceInfo; - autoclose.start(); - return deviceInfo.deviceModel(); + autoclose.start(); + return deviceInfo.deviceModel(); } -QString Ssud::deviceFamily(){ - SsuDeviceInfo deviceInfo; +QString Ssud::deviceFamily() +{ + SsuDeviceInfo deviceInfo; - autoclose.start(); - return deviceInfo.deviceFamily(); + autoclose.start(); + return deviceInfo.deviceFamily(); } -QString Ssud::deviceUid(){ - SsuDeviceInfo deviceInfo; +QString Ssud::deviceUid() +{ + SsuDeviceInfo deviceInfo; - autoclose.start(); - return deviceInfo.deviceUid(); + autoclose.start(); + return deviceInfo.deviceUid(); } -QString Ssud::deviceVariant(){ - SsuDeviceInfo deviceInfo; +QString Ssud::deviceVariant() +{ + SsuDeviceInfo deviceInfo; - autoclose.start(); - return deviceInfo.deviceVariant(); + autoclose.start(); + return deviceInfo.deviceVariant(); } -QString Ssud::displayName(int type){ - SsuDeviceInfo deviceInfo; +QString Ssud::displayName(int type) +{ + SsuDeviceInfo deviceInfo; - autoclose.start(); - return deviceInfo.displayName(type); + autoclose.start(); + return deviceInfo.displayName(type); } -bool Ssud::error(){ - autoclose.start(); - return ssu.error(); +bool Ssud::error() +{ + autoclose.start(); + return ssu.error(); } -QString Ssud::lastError(){ - autoclose.start(); - return ssu.lastError(); +QString Ssud::lastError() +{ + autoclose.start(); + return ssu.lastError(); } -void Ssud::quit(){ - QCoreApplication::quit(); +void Ssud::quit() +{ + QCoreApplication::quit(); } -bool Ssud::isRegistered(){ - autoclose.start(); - return ssu.isRegistered(); +bool Ssud::isRegistered() +{ + autoclose.start(); + return ssu.isRegistered(); } -void Ssud::registerDevice(const QString &username, const QString &password){ - autoclose.stop(); - ssu.sendRegistration(username, password); - autoclose.start(); +void Ssud::registerDevice(const QString &username, const QString &password) +{ + autoclose.stop(); + ssu.sendRegistration(username, password); + autoclose.start(); } -void Ssud::unregisterDevice(){ - autoclose.start(); - ssu.unregister(); +void Ssud::unregisterDevice() +{ + autoclose.start(); + ssu.unregister(); }; -QString Ssud::domain(){ +QString Ssud::domain() +{ autoclose.start(); return ssu.domain(); } -Ssu::DeviceModeFlags Ssud::deviceMode(){ - autoclose.start(); - return ssu.deviceMode(); +Ssu::DeviceModeFlags Ssud::deviceMode() +{ + autoclose.start(); + return ssu.deviceMode(); } -void Ssud::setDeviceMode(int mode){ - setDeviceMode(mode, Ssu::Replace); +void Ssud::setDeviceMode(int mode) +{ + setDeviceMode(mode, Ssu::Replace); } -void Ssud::setDeviceMode(int mode, int editMode){ - ssu.setDeviceMode( - Ssu::DeviceModeFlags(mode), - Ssu::EditMode(editMode) +void Ssud::setDeviceMode(int mode, int editMode) +{ + ssu.setDeviceMode( + Ssu::DeviceModeFlags(mode), + Ssu::EditMode(editMode) ); - SsuRepoManager repoManager; - repoManager.update(); - autoclose.start(); + SsuRepoManager repoManager; + repoManager.update(); + autoclose.start(); } -QString Ssud::flavour(){ - autoclose.start(); - return ssu.flavour(); +QString Ssud::flavour() +{ + autoclose.start(); + return ssu.flavour(); } -void Ssud::setFlavour(const QString &flavour){ - ssu.setFlavour(flavour); +void Ssud::setFlavour(const QString &flavour) +{ + ssu.setFlavour(flavour); - SsuRepoManager repoManager; - repoManager.update(); - autoclose.start(); + SsuRepoManager repoManager; + repoManager.update(); + autoclose.start(); } -QString Ssud::release(bool rnd){ - autoclose.start(); - return ssu.release(rnd); +QString Ssud::release(bool rnd) +{ + autoclose.start(); + return ssu.release(rnd); } -void Ssud::setRelease(const QString &release, bool rnd){ - ssu.setRelease(release, rnd); +void Ssud::setRelease(const QString &release, bool rnd) +{ + ssu.setRelease(release, rnd); - SsuRepoManager repoManager; - repoManager.update(); - autoclose.start(); + SsuRepoManager repoManager; + repoManager.update(); + autoclose.start(); } -void Ssud::modifyRepo(int action, const QString &repo){ - SsuRepoManager repoManager; +void Ssud::modifyRepo(int action, const QString &repo) +{ + SsuRepoManager repoManager; - autoclose.stop(); + autoclose.stop(); - switch(action){ + switch (action) { case Add: - repoManager.add(repo); - break; + repoManager.add(repo); + break; case Remove: - repoManager.remove(repo); - break; + repoManager.remove(repo); + break; case Disable: - repoManager.disable(repo); - break; + repoManager.disable(repo); + break; case Enable: - repoManager.enable(repo); - break; - } + repoManager.enable(repo); + break; + } - repoManager.update(); - autoclose.start(); + repoManager.update(); + autoclose.start(); } -void Ssud::addRepo(const QString &repo, const QString &url){ - SsuRepoManager repoManager; - repoManager.add(repo, url); - repoManager.update(); - autoclose.start(); +void Ssud::addRepo(const QString &repo, const QString &url) +{ + SsuRepoManager repoManager; + repoManager.add(repo, url); + repoManager.update(); + autoclose.start(); } -void Ssud::updateRepos(){ - SsuRepoManager repoManager; - autoclose.stop(); - repoManager.update(); - autoclose.start(); +void Ssud::updateRepos() +{ + SsuRepoManager repoManager; + autoclose.stop(); + repoManager.update(); + autoclose.start(); } diff --git a/ssud/ssud.h b/ssud/ssud.h index 5aa1baa..e79b2bf 100644 --- a/ssud/ssud.h +++ b/ssud/ssud.h @@ -14,14 +14,15 @@ #include "libssu/ssu.h" -class Ssud: public QObject { +class Ssud: public QObject +{ Q_OBJECT - public: - Ssud(QObject *parent=NULL); +public: + Ssud(QObject *parent = NULL); virtual ~Ssud(); - public slots: +public slots: /* device info */ QString deviceModel(); QString deviceFamily(); @@ -51,22 +52,22 @@ class Ssud: public QObject { void quit(); - signals: +signals: void done(); void credentialsChanged(); void registrationStatusChanged(); - private: +private: Ssu ssu; static const char *SERVICE_NAME; static const char *OBJECT_PATH; QTimer autoclose; enum Actions { - Remove = 0, - Add = 1, - Disable = 2, - Enable = 3, + Remove = 0, + Add = 1, + Disable = 2, + Enable = 3, }; }; diff --git a/ssuks/ssukickstarter.cpp b/ssuks/ssukickstarter.cpp index 4ee97b7..08b1f92 100644 --- a/ssuks/ssukickstarter.cpp +++ b/ssuks/ssukickstarter.cpp @@ -22,381 +22,389 @@ */ -SsuKickstarter::SsuKickstarter() { - SsuDeviceInfo deviceInfo; - deviceModel = deviceInfo.deviceModel(); - - if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) - rndMode = true; - else - rndMode = false; +SsuKickstarter::SsuKickstarter() +{ + SsuDeviceInfo deviceInfo; + deviceModel = deviceInfo.deviceModel(); + + if ((ssu.deviceMode() & Ssu::RndMode) == Ssu::RndMode) + rndMode = true; + else + rndMode = false; } -QStringList SsuKickstarter::commands(){ - SsuDeviceInfo deviceInfo(deviceModel); - QStringList result; +QStringList SsuKickstarter::commands() +{ + SsuDeviceInfo deviceInfo(deviceModel); + QStringList result; - QHash h; + QHash h; - deviceInfo.variableSection("kickstart-commands", &h); + deviceInfo.variableSection("kickstart-commands", &h); - // read commands from variable, ... + // read commands from variable, ... - QHash::const_iterator it = h.constBegin(); - while (it != h.constEnd()){ - result.append(it.key() + " " + it.value()); - it++; - } + QHash::const_iterator it = h.constBegin(); + while (it != h.constEnd()) { + result.append(it.key() + " " + it.value()); + it++; + } - return result; + return result; } -QStringList SsuKickstarter::commandSection(const QString §ion, const QString &description){ - QStringList result; - SsuDeviceInfo deviceInfo(deviceModel); - QString commandFile; - QFile part; - - QDir dir(Sandbox::map(QString("/%1/kickstart/%2/") - .arg(SSU_DATA_DIR) - .arg(section))); - - if (dir.exists(replaceSpaces(deviceModel.toLower()))) - commandFile = replaceSpaces(deviceModel.toLower()); - else if (dir.exists(replaceSpaces(deviceInfo.deviceVariant(true).toLower()))) - commandFile = replaceSpaces(deviceInfo.deviceVariant(true).toLower()); - else if (dir.exists("default")) - commandFile = "default"; - else { - if (description.isEmpty()) - result.append("## No suitable configuration found in " + dir.path()); - else - result.append("## No configuration for " + description + " found."); - return result; - } +QStringList SsuKickstarter::commandSection(const QString §ion, const QString &description) +{ + QStringList result; + SsuDeviceInfo deviceInfo(deviceModel); + QString commandFile; + QFile part; + + QDir dir(Sandbox::map(QString("/%1/kickstart/%2/") + .arg(SSU_DATA_DIR) + .arg(section))); + + if (dir.exists(replaceSpaces(deviceModel.toLower()))) + commandFile = replaceSpaces(deviceModel.toLower()); + else if (dir.exists(replaceSpaces(deviceInfo.deviceVariant(true).toLower()))) + commandFile = replaceSpaces(deviceInfo.deviceVariant(true).toLower()); + else if (dir.exists("default")) + commandFile = "default"; + else { + if (description.isEmpty()) + result.append("## No suitable configuration found in " + dir.path()); + else + result.append("## No configuration for " + description + " found."); + return result; + } - QFile file(dir.path() + "/" + commandFile); + QFile file(dir.path() + "/" + commandFile); - if (description.isEmpty()) - result.append("### Commands from " + dir.path() + "/" + commandFile); - else - result.append("### " + description + " from " + commandFile); + if (description.isEmpty()) + result.append("### Commands from " + dir.path() + "/" + commandFile); + else + result.append("### " + description + " from " + commandFile); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)){ - QTextStream in(&file); - while (!in.atEnd()) - result.append(in.readLine()); - } + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + while (!in.atEnd()) + result.append(in.readLine()); + } - return result; + return result; } -QString SsuKickstarter::replaceSpaces(const QString &value){ - QString retval = value; - return retval.replace(" ", "_"); +QString SsuKickstarter::replaceSpaces(const QString &value) +{ + QString retval = value; + return retval.replace(" ", "_"); } -QStringList SsuKickstarter::repos(){ - QStringList result; - SsuDeviceInfo deviceInfo(deviceModel); - SsuRepoManager repoManager; - QTextStream qerr(stderr); +QStringList SsuKickstarter::repos() +{ + QStringList result; + SsuDeviceInfo deviceInfo(deviceModel); + SsuRepoManager repoManager; + QTextStream qerr(stderr); + + QStringList repos = repoManager.repos(rndMode, deviceInfo, Ssu::BoardFilter); + + foreach (const QString &repo, repos) { + QString repoUrl = ssu.repoUrl(repo, rndMode, QHash(), repoOverride); + + if (repoUrl == "") { + qerr << "Repository " << repo << " does not have an URL, ignoring" << endl; + continue; + } + + // Adaptation repos need to have separate naming so that when images are done + // the repository caches will not be mixed with each other. + if (repo.startsWith("adaptation")) { + result.append(QString("repo --name=%1-%2-%3%4 --baseurl=%5") + .arg(repo) + .arg(replaceSpaces(deviceModel)) + .arg((rndMode ? repoOverride.value("rndRelease") + : repoOverride.value("release"))) + .arg((rndMode ? "-" + repoOverride.value("flavourName") + : "")) + .arg(repoUrl) + ); + } else + result.append(QString("repo --name=%1-%2%3 --baseurl=%4") + .arg(repo) + .arg((rndMode ? repoOverride.value("rndRelease") + : repoOverride.value("release"))) + .arg((rndMode ? "-" + repoOverride.value("flavourName") + : "")) + .arg(repoUrl) + ); + } - QStringList repos = repoManager.repos(rndMode, deviceInfo, Ssu::BoardFilter); + return result; +} - foreach (const QString &repo, repos){ - QString repoUrl = ssu.repoUrl(repo, rndMode, QHash(), repoOverride); +QStringList SsuKickstarter::packagesSection(QString name) +{ + QStringList result; - if (repoUrl == ""){ - qerr << "Repository " << repo << " does not have an URL, ignoring" << endl; - continue; - } + if (name == "packages") { + // insert @vendor configuration device + QString configuration = QString("@%1 Configuration %2") + .arg(repoOverride.value("brand")) + .arg(deviceModel); + result.append(configuration); - // Adaptation repos need to have separate naming so that when images are done - // the repository caches will not be mixed with each other. - if (repo.startsWith("adaptation")) { - result.append(QString("repo --name=%1-%2-%3%4 --baseurl=%5") - .arg(repo) - .arg(replaceSpaces(deviceModel)) - .arg((rndMode ? repoOverride.value("rndRelease") - : repoOverride.value("release"))) - .arg((rndMode ? "-" + repoOverride.value("flavourName") - : "")) - .arg(repoUrl) - ); + result.sort(); + result.removeDuplicates(); + } else { + result = commandSection(name); } - else - result.append(QString("repo --name=%1-%2%3 --baseurl=%4") - .arg(repo) - .arg((rndMode ? repoOverride.value("rndRelease") - : repoOverride.value("release"))) - .arg((rndMode ? "-" + repoOverride.value("flavourName") - : "")) - .arg(repoUrl) - ); - } - - return result; -} -QStringList SsuKickstarter::packagesSection(QString name){ - QStringList result; - - if (name == "packages") { - // insert @vendor configuration device - QString configuration = QString("@%1 Configuration %2") - .arg(repoOverride.value("brand")) - .arg(deviceModel); - result.append(configuration); - - result.sort(); - result.removeDuplicates(); - } else { - result = commandSection(name); - } - - result.prepend("%" + name); - result.append("%end"); - return result; + result.prepend("%" + name); + result.append("%end"); + return result; } // we intentionally don't support device-specific post scriptlets -QStringList SsuKickstarter::scriptletSection(QString name, int flags){ - QStringList result; - QString path; - QDir dir; - - if ((flags & NoChroot) == NoChroot) - path = Sandbox::map(QString("/%1/kickstart/%2_nochroot/") - .arg(SSU_DATA_DIR) - .arg(name)); - else - path = Sandbox::map(QString("/%1/kickstart/%2/") - .arg(SSU_DATA_DIR) - .arg(name)); - - if ((flags & DeviceSpecific) == DeviceSpecific){ - if (dir.exists(path + "/" + replaceSpaces(deviceModel.toLower()))) - path = path + "/" + replaceSpaces(deviceModel.toLower()); +QStringList SsuKickstarter::scriptletSection(QString name, int flags) +{ + QStringList result; + QString path; + QDir dir; + + if ((flags & NoChroot) == NoChroot) + path = Sandbox::map(QString("/%1/kickstart/%2_nochroot/") + .arg(SSU_DATA_DIR) + .arg(name)); else - path = path + "/default"; - } - - dir.setPath(path); - QStringList scriptlets = dir.entryList(QDir::AllEntries|QDir::NoDot|QDir::NoDotDot, - QDir::Name); - - foreach (const QString &scriptlet, scriptlets){ - QFile file(dir.filePath(scriptlet)); - result.append("### begin " + scriptlet); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)){ - QTextStream in(&file); - while (!in.atEnd()) - result.append(in.readLine()); + path = Sandbox::map(QString("/%1/kickstart/%2/") + .arg(SSU_DATA_DIR) + .arg(name)); + + if ((flags & DeviceSpecific) == DeviceSpecific) { + if (dir.exists(path + "/" + replaceSpaces(deviceModel.toLower()))) + path = path + "/" + replaceSpaces(deviceModel.toLower()); + else + path = path + "/default"; } - result.append("### end " + scriptlet); - } - if (!result.isEmpty()){ - result.prepend(QString("export SSU_RELEASE_TYPE=%1") - .arg(rndMode ? "rnd" : "release")); + dir.setPath(path); + QStringList scriptlets = dir.entryList(QDir::AllEntries | QDir::NoDot | QDir::NoDotDot, + QDir::Name); + + foreach (const QString &scriptlet, scriptlets) { + QFile file(dir.filePath(scriptlet)); + result.append("### begin " + scriptlet); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + while (!in.atEnd()) + result.append(in.readLine()); + } + result.append("### end " + scriptlet); + } - if ((flags & NoChroot) == NoChroot) - result.prepend("%" + name + " --nochroot"); - else - result.prepend("%" + name); + if (!result.isEmpty()) { + result.prepend(QString("export SSU_RELEASE_TYPE=%1") + .arg(rndMode ? "rnd" : "release")); - result.append("%end"); - } + if ((flags & NoChroot) == NoChroot) + result.prepend("%" + name + " --nochroot"); + else + result.prepend("%" + name); + + result.append("%end"); + } - return result; + return result; } -void SsuKickstarter::setRepoParameters(QHash parameters){ - repoOverride = parameters; +void SsuKickstarter::setRepoParameters(QHash parameters) +{ + repoOverride = parameters; - if (repoOverride.contains("model")) - deviceModel = repoOverride.value("model"); + if (repoOverride.contains("model")) + deviceModel = repoOverride.value("model"); } -bool SsuKickstarter::write(QString kickstart){ - QFile ks; - QTextStream kout; - QTextStream qerr(stderr); - SsuDeviceInfo deviceInfo(deviceModel); - SsuRepoManager repoManager; - SsuVariables var; - QStringList commandSections; - - // initialize with default 'part' for compatibility, as partitions - // used to work without configuration. It'll get replaced with - // configuration values, if found - commandSections.append("part"); - - // rnd mode should not come from the defaults - if (repoOverride.contains("rnd")){ - if (repoOverride.value("rnd") == "true") - rndMode = true; - else if (repoOverride.value("rnd") == "false") - rndMode = false; - } - - QHash defaults; - // get generic repo variables; domain and adaptation specific bits are not interesting - // in the kickstart - repoManager.repoVariables(&defaults, rndMode); - - // overwrite with kickstart defaults - deviceInfo.variableSection("kickstart-defaults", &defaults); - if (deviceInfo.variable("kickstart-defaults", "commandSections") - .canConvert(QMetaType::QStringList)){ - commandSections = - deviceInfo.variable("kickstart-defaults", "commandSections").toStringList(); - } - - QHash::const_iterator it = defaults.constBegin(); - while (it != defaults.constEnd()){ - if (!repoOverride.contains(it.key())) - repoOverride.insert(it.key(), it.value()); - it++; - } - - // in rnd mode both rndRelease an release should be the same, - // as the variable name used is %(release) - if (rndMode && repoOverride.contains("rndRelease")) - repoOverride.insert("release", repoOverride.value("rndRelease")); - - // release mode variables should not contain flavourName - if (!rndMode && repoOverride.contains("flavourName")) - repoOverride.remove("flavourName"); - - //TODO: check for mandatory keys, brand, .. - if (!repoOverride.contains("deviceModel")) - repoOverride.insert("deviceModel", deviceInfo.deviceModel()); - - // do sanity checking on the model - if (deviceInfo.contains() == false) { - qerr << "Device model '" << deviceInfo.deviceModel() << "' does not exist" << endl; - - if (repoOverride.value("force") != "true") - return false; - } - - QRegExp regex(" {2,}", Qt::CaseSensitive, QRegExp::RegExp2); - if (regex.indexIn(deviceInfo.deviceModel(), 0) != -1){ - qerr << "Device model '" << deviceInfo.deviceModel() - << "' contains multiple consecutive spaces." << endl; - if (deviceInfo.contains()) - qerr << "Since the model exists it looks like your configuration is broken." << endl; - return false; - } - - if (!repoOverride.contains("brand")){ - qerr << "No brand set. Check your configuration." << endl; - return false; - } - - bool opened = false; - QString outputDir = repoOverride.value("outputdir"); - if (!outputDir.isEmpty()) outputDir.append("/"); - - if (kickstart.isEmpty()){ - if (repoOverride.contains("filename")){ - QString fileName = QString("%1%2") - .arg(outputDir) - .arg(replaceSpaces(var.resolveString(repoOverride.value("filename"), - &repoOverride))); - - ks.setFileName(fileName); - opened = ks.open(QIODevice::WriteOnly); - } else { - qerr << "No filename specified, and no default filename configured" << endl; - return false; +bool SsuKickstarter::write(QString kickstart) +{ + QFile ks; + QTextStream kout; + QTextStream qerr(stderr); + SsuDeviceInfo deviceInfo(deviceModel); + SsuRepoManager repoManager; + SsuVariables var; + QStringList commandSections; + + // initialize with default 'part' for compatibility, as partitions + // used to work without configuration. It'll get replaced with + // configuration values, if found + commandSections.append("part"); + + // rnd mode should not come from the defaults + if (repoOverride.contains("rnd")) { + if (repoOverride.value("rnd") == "true") + rndMode = true; + else if (repoOverride.value("rnd") == "false") + rndMode = false; } - } else if (kickstart == "-") - opened = ks.open(stdout, QIODevice::WriteOnly); - else { - ks.setFileName(outputDir + kickstart); - opened = ks.open(QIODevice::WriteOnly); - } - - if (!opened) { - qerr << "Unable to write output file " << ks.fileName() << ": " << ks.errorString() << endl; - return false; - } else if (!ks.fileName().isEmpty()) - qerr << "Writing kickstart to " << ks.fileName() << endl; - - QString displayName = QString("# DisplayName: %1 %2/%3 (%4) %5") - .arg(repoOverride.value("brand")) - .arg(deviceInfo.deviceModel()) - .arg(repoOverride.value("arch")) - .arg((rndMode ? "rnd" - : "release")) - .arg(repoOverride.value("version")); - - QStringList featuresList = deviceInfo.value("img-features").toStringList(); - - QString suggestedFeatures; - - // work around some idiotic JS list parsing on our side by terminating one-element list by comma - if (featuresList.count() == 1) - suggestedFeatures = QString("# SuggestedFeatures: %1,") - .arg(deviceInfo.value("img-features").toStringList().join(", ")); - else if (featuresList.count() > 1) - suggestedFeatures = QString("# SuggestedFeatures: %1") - .arg(deviceInfo.value("img-features").toStringList().join(", ")); - - QString imageType = "fs"; - if (!deviceInfo.value("img-type").toString().isEmpty()) - imageType = deviceInfo.value("img-type").toString(); - - QString imageArchitecture = "armv7hl"; - if (!deviceInfo.value("img-arch").toString().isEmpty()) - imageArchitecture = deviceInfo.value("img-arch").toString(); - - QString kickstartType = QString("# KickstartType: %1") - .arg((rndMode ? "rnd" : "release")); - - kout.setDevice(&ks); - kout << displayName << endl; - kout << kickstartType << endl; - if (!suggestedFeatures.isEmpty()) - kout << suggestedFeatures << endl; - kout << "# SuggestedImageType: " << imageType << endl; - kout << "# SuggestedArchitecture: " << imageArchitecture << endl << endl; - kout << commands().join("\n") << endl << endl; - foreach (const QString §ion, commandSections){ - kout << commandSection(section).join("\n") << endl << endl; - } - - // this allows simple search and replace postprocessing of the repos section - // to overcome shortcomings of the "keep image creation simple token based" - // approach - // TODO: QHash looks messy in the config, provide tool to edit it - QString repoSection = repos().join("\n"); - if (deviceInfo.variable("kickstart-defaults", "urlPostprocess") - .canConvert(QMetaType::QVariantHash)){ - QHash postproc = - deviceInfo.variable("kickstart-defaults", "urlPostprocess").toHash(); - - QHash::const_iterator it = postproc.constBegin(); - while (it != postproc.constEnd()){ - QRegExp regex(it.key(), Qt::CaseSensitive, QRegExp::RegExp2); - - repoSection.replace(regex, it.value().toString()); - it++; + + QHash defaults; + // get generic repo variables; domain and adaptation specific bits are not interesting + // in the kickstart + repoManager.repoVariables(&defaults, rndMode); + + // overwrite with kickstart defaults + deviceInfo.variableSection("kickstart-defaults", &defaults); + if (deviceInfo.variable("kickstart-defaults", "commandSections") + .canConvert(QMetaType::QStringList)) { + commandSections = + deviceInfo.variable("kickstart-defaults", "commandSections").toStringList(); + } + + QHash::const_iterator it = defaults.constBegin(); + while (it != defaults.constEnd()) { + if (!repoOverride.contains(it.key())) + repoOverride.insert(it.key(), it.value()); + it++; + } + + // in rnd mode both rndRelease an release should be the same, + // as the variable name used is %(release) + if (rndMode && repoOverride.contains("rndRelease")) + repoOverride.insert("release", repoOverride.value("rndRelease")); + + // release mode variables should not contain flavourName + if (!rndMode && repoOverride.contains("flavourName")) + repoOverride.remove("flavourName"); + + //TODO: check for mandatory keys, brand, .. + if (!repoOverride.contains("deviceModel")) + repoOverride.insert("deviceModel", deviceInfo.deviceModel()); + + // do sanity checking on the model + if (deviceInfo.contains() == false) { + qerr << "Device model '" << deviceInfo.deviceModel() << "' does not exist" << endl; + + if (repoOverride.value("force") != "true") + return false; + } + + QRegExp regex(" {2,}", Qt::CaseSensitive, QRegExp::RegExp2); + if (regex.indexIn(deviceInfo.deviceModel(), 0) != -1) { + qerr << "Device model '" << deviceInfo.deviceModel() + << "' contains multiple consecutive spaces." << endl; + if (deviceInfo.contains()) + qerr << "Since the model exists it looks like your configuration is broken." << endl; + return false; } - } - - kout << repoSection << endl << endl; - kout << packagesSection("packages").join("\n") << endl << endl; - kout << packagesSection("attachment").join("\n") << endl << endl; - // TODO: now that extending scriptlet section is might make sense to make it configurable - kout << scriptletSection("pre", Chroot).join("\n") << endl << endl; - kout << scriptletSection("post", Chroot).join("\n") << endl << endl; - kout << scriptletSection("post", NoChroot).join("\n") << endl << endl; - kout << scriptletSection("pack", DeviceSpecific).join("\n") << endl << endl; - // POST, die-on-error - - return true; + + if (!repoOverride.contains("brand")) { + qerr << "No brand set. Check your configuration." << endl; + return false; + } + + bool opened = false; + QString outputDir = repoOverride.value("outputdir"); + if (!outputDir.isEmpty()) outputDir.append("/"); + + if (kickstart.isEmpty()) { + if (repoOverride.contains("filename")) { + QString fileName = QString("%1%2") + .arg(outputDir) + .arg(replaceSpaces(var.resolveString(repoOverride.value("filename"), + &repoOverride))); + + ks.setFileName(fileName); + opened = ks.open(QIODevice::WriteOnly); + } else { + qerr << "No filename specified, and no default filename configured" << endl; + return false; + } + } else if (kickstart == "-") + opened = ks.open(stdout, QIODevice::WriteOnly); + else { + ks.setFileName(outputDir + kickstart); + opened = ks.open(QIODevice::WriteOnly); + } + + if (!opened) { + qerr << "Unable to write output file " << ks.fileName() << ": " << ks.errorString() << endl; + return false; + } else if (!ks.fileName().isEmpty()) + qerr << "Writing kickstart to " << ks.fileName() << endl; + + QString displayName = QString("# DisplayName: %1 %2/%3 (%4) %5") + .arg(repoOverride.value("brand")) + .arg(deviceInfo.deviceModel()) + .arg(repoOverride.value("arch")) + .arg((rndMode ? "rnd" + : "release")) + .arg(repoOverride.value("version")); + + QStringList featuresList = deviceInfo.value("img-features").toStringList(); + + QString suggestedFeatures; + + // work around some idiotic JS list parsing on our side by terminating one-element list by comma + if (featuresList.count() == 1) + suggestedFeatures = QString("# SuggestedFeatures: %1,") + .arg(deviceInfo.value("img-features").toStringList().join(", ")); + else if (featuresList.count() > 1) + suggestedFeatures = QString("# SuggestedFeatures: %1") + .arg(deviceInfo.value("img-features").toStringList().join(", ")); + + QString imageType = "fs"; + if (!deviceInfo.value("img-type").toString().isEmpty()) + imageType = deviceInfo.value("img-type").toString(); + + QString imageArchitecture = "armv7hl"; + if (!deviceInfo.value("img-arch").toString().isEmpty()) + imageArchitecture = deviceInfo.value("img-arch").toString(); + + QString kickstartType = QString("# KickstartType: %1") + .arg((rndMode ? "rnd" : "release")); + + kout.setDevice(&ks); + kout << displayName << endl; + kout << kickstartType << endl; + if (!suggestedFeatures.isEmpty()) + kout << suggestedFeatures << endl; + kout << "# SuggestedImageType: " << imageType << endl; + kout << "# SuggestedArchitecture: " << imageArchitecture << endl << endl; + kout << commands().join("\n") << endl << endl; + foreach (const QString §ion, commandSections) { + kout << commandSection(section).join("\n") << endl << endl; + } + + // this allows simple search and replace postprocessing of the repos section + // to overcome shortcomings of the "keep image creation simple token based" + // approach + // TODO: QHash looks messy in the config, provide tool to edit it + QString repoSection = repos().join("\n"); + if (deviceInfo.variable("kickstart-defaults", "urlPostprocess") + .canConvert(QMetaType::QVariantHash)) { + QHash postproc = + deviceInfo.variable("kickstart-defaults", "urlPostprocess").toHash(); + + QHash::const_iterator it = postproc.constBegin(); + while (it != postproc.constEnd()) { + QRegExp regex(it.key(), Qt::CaseSensitive, QRegExp::RegExp2); + + repoSection.replace(regex, it.value().toString()); + it++; + } + } + + kout << repoSection << endl << endl; + kout << packagesSection("packages").join("\n") << endl << endl; + kout << packagesSection("attachment").join("\n") << endl << endl; + // TODO: now that extending scriptlet section is might make sense to make it configurable + kout << scriptletSection("pre", Chroot).join("\n") << endl << endl; + kout << scriptletSection("post", Chroot).join("\n") << endl << endl; + kout << scriptletSection("post", NoChroot).join("\n") << endl << endl; + kout << scriptletSection("pack", DeviceSpecific).join("\n") << endl << endl; + // POST, die-on-error + + return true; } diff --git a/ssuks/ssukickstarter.h b/ssuks/ssukickstarter.h index bd68406..8233303 100644 --- a/ssuks/ssukickstarter.h +++ b/ssuks/ssukickstarter.h @@ -15,31 +15,32 @@ #include "libssu/ssudeviceinfo.h" #include "libssu/ssu.h" -class SsuKickstarter { - public: +class SsuKickstarter +{ +public: SsuKickstarter(); void setRepoParameters(QHash parameters); - bool write(QString kickstart=""); + bool write(QString kickstart = ""); enum ScriptletFlags { - /// Chroot is not useful, but helps in making the code more readable - Chroot = 0, - NoChroot = 0x1, - DeviceSpecific = 0x2, + /// Chroot is not useful, but helps in making the code more readable + Chroot = 0, + NoChroot = 0x1, + DeviceSpecific = 0x2, }; - private: +private: QHash repoOverride; Ssu ssu; bool rndMode; QString deviceModel; QStringList commands(); /// read a command section from file system - QStringList commandSection(const QString §ion, const QString &description=""); + QStringList commandSection(const QString §ion, const QString &description = ""); QStringList packagesSection(QString name); QString replaceSpaces(const QString &value); QStringList repos(); - QStringList scriptletSection(QString name, int flags=Chroot); + QStringList scriptletSection(QString name, int flags = Chroot); }; #endif diff --git a/ssuks/ssuks.cpp b/ssuks/ssuks.cpp index 918297b..2e14d2d 100644 --- a/ssuks/ssuks.cpp +++ b/ssuks/ssuks.cpp @@ -20,98 +20,101 @@ #include "ssuks.h" -void SsuKs::run(){ - QStringList arguments = QCoreApplication::arguments(); - // get rid of the binary name - arguments.removeFirst(); - - QTextStream qout(stdout); - QTextStream qerr(stderr); - QHash repoParameters; - - if (arguments.count() == 1 && - (arguments.at(0) == "help" || - arguments.at(0) == "--help" || - arguments.at(0) == "-h")) { - usage(); - return; - } - - QString fileName; - if (arguments.count() >= 1 && !arguments.at(0).contains("=")){ - fileName = arguments.at(0); +void SsuKs::run() +{ + QStringList arguments = QCoreApplication::arguments(); + // get rid of the binary name arguments.removeFirst(); - } - - for (int i=0; i repoParameters; - sb = new Sandbox(sandbox, Sandbox::UseDirectly, Sandbox::ThisProcess); + if (arguments.count() == 1 && + (arguments.at(0) == "help" || + arguments.at(0) == "--help" || + arguments.at(0) == "-h")) { + usage(); + return; + } - if (!sb->addWorldFiles(SSU_DATA_DIR)){ - qerr << "Failed to copy files into sandbox, using empty sandbox" << endl; + QString fileName; + if (arguments.count() >= 1 && !arguments.at(0).contains("=")) { + fileName = arguments.at(0); + arguments.removeFirst(); } - if (sb->activate()) - qerr << "Using sandbox at " << sandbox << endl; - else { - qerr << "Failed to activate sandbox" << endl; - QCoreApplication::exit(1); - return; + for (int i = 0; i < arguments.count(); i++) { + if (arguments.at(i).count("=") != 1) { + qout << "Invalid flag: " << arguments.at(i) << endl; + QCoreApplication::exit(1); + return; + } + QStringList split = arguments.at(i).split("="); + repoParameters.insert(split.at(0), split.at(1)); } - // force re-merge of settings - QFile::remove(Sandbox::map(SSU_BOARD_MAPPING_CONFIGURATION)); - SsuSettings(SSU_BOARD_MAPPING_CONFIGURATION, SSU_BOARD_MAPPING_CONFIGURATION_DIR); - } + QString sandbox; + Sandbox *sb; + if (repoParameters.contains("sandbox")) { + sandbox = repoParameters.value("sandbox"); + repoParameters.remove("sandbox"); + + sb = new Sandbox(sandbox, Sandbox::UseDirectly, Sandbox::ThisProcess); + + if (!sb->addWorldFiles(SSU_DATA_DIR)) { + qerr << "Failed to copy files into sandbox, using empty sandbox" << endl; + } + + if (sb->activate()) + qerr << "Using sandbox at " << sandbox << endl; + else { + qerr << "Failed to activate sandbox" << endl; + QCoreApplication::exit(1); + return; + } + + // force re-merge of settings + QFile::remove(Sandbox::map(SSU_BOARD_MAPPING_CONFIGURATION)); + SsuSettings(SSU_BOARD_MAPPING_CONFIGURATION, SSU_BOARD_MAPPING_CONFIGURATION_DIR); + } - SsuKickstarter kickstarter; - kickstarter.setRepoParameters(repoParameters); - QCoreApplication::exit(!kickstarter.write(fileName)); - return; + SsuKickstarter kickstarter; + kickstarter.setRepoParameters(repoParameters); + QCoreApplication::exit(!kickstarter.write(fileName)); + return; - QCoreApplication::exit(0); + QCoreApplication::exit(0); } -void SsuKs::usage(){ - QTextStream qout(stdout); - qout << "\nUsage: ssuks " << endl - << endl - << "Flags are in the form key=value. 'model', 'force', 'rnd' and 'sandbox' keys have special meanings." << endl - << "To do a kickstart for N9 do 'ssuks model=N9'" << endl - << "To force generating a kickstart for a non-existant device add force=true" << endl - << endl; - qout.flush(); - QCoreApplication::exit(1); +void SsuKs::usage() +{ + QTextStream qout(stdout); + qout << "\nUsage: ssuks " << endl + << endl + << "Flags are in the form key=value. 'model', 'force', 'rnd' and 'sandbox' keys have special meanings." << endl + << "To do a kickstart for N9 do 'ssuks model=N9'" << endl + << "To force generating a kickstart for a non-existant device add force=true" << endl + << endl; + qout.flush(); + QCoreApplication::exit(1); } -int main(int argc, char** argv){ - QCoreApplication app(argc, argv); - QCoreApplication::setOrganizationName("Jolla"); - QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); - QCoreApplication::setApplicationName("ssuks"); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setOrganizationName("Jolla"); + QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); + QCoreApplication::setApplicationName("ssuks"); - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&qtTranslator); + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + app.installTranslator(&qtTranslator); - SsuKs mw; - QTimer::singleShot(0, &mw, SLOT(run())); + SsuKs mw; + QTimer::singleShot(0, &mw, SLOT(run())); - return app.exec(); + return app.exec(); } diff --git a/ssuks/ssuks.h b/ssuks/ssuks.h index 4b0a72e..76e973c 100644 --- a/ssuks/ssuks.h +++ b/ssuks/ssuks.h @@ -11,16 +11,17 @@ #include #include -class SsuKs: public QObject { +class SsuKs: public QObject +{ Q_OBJECT - public: - SsuKs(){}; +public: + SsuKs() {}; - public slots: +public slots: void run(); - private: +private: void usage(); }; diff --git a/ssuslipstream/ssuslipstream.h b/ssuslipstream/ssuslipstream.h index 5ee9d17..3b60f60 100644 --- a/ssuslipstream/ssuslipstream.h +++ b/ssuslipstream/ssuslipstream.h @@ -23,7 +23,8 @@ #include -class SsuSlipstream : public QObject { +class SsuSlipstream : public QObject +{ Q_OBJECT public: diff --git a/ssuurlresolver/main.cpp b/ssuurlresolver/main.cpp index fb4a756..b41faa8 100644 --- a/ssuurlresolver/main.cpp +++ b/ssuurlresolver/main.cpp @@ -13,21 +13,22 @@ #include "libssunetworkproxy/ssunetworkproxy.h" #include "ssuurlresolver.h" -int main(int argc, char** argv){ - QCoreApplication app(argc, argv); - QCoreApplication::setOrganizationName("Jolla"); - QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); - QCoreApplication::setApplicationName("SSU Url Resolver"); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setOrganizationName("Jolla"); + QCoreApplication::setOrganizationDomain("http://www.jollamobile.com"); + QCoreApplication::setApplicationName("SSU Url Resolver"); - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&qtTranslator); + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + app.installTranslator(&qtTranslator); - set_application_proxy_factory(); + set_application_proxy_factory(); - SsuUrlResolver mw; - QTimer::singleShot(0, &mw, SLOT(run())); + SsuUrlResolver mw; + QTimer::singleShot(0, &mw, SLOT(run())); - return app.exec(); + return app.exec(); } diff --git a/ssuurlresolver/ssuurlresolver.cpp b/ssuurlresolver/ssuurlresolver.cpp index 57d00f4..7b77283 100644 --- a/ssuurlresolver/ssuurlresolver.cpp +++ b/ssuurlresolver/ssuurlresolver.cpp @@ -16,168 +16,172 @@ #include "libssu/sandbox_p.h" #include "libssu/ssulog_p.h" -SsuUrlResolver::SsuUrlResolver(): QObject(){ - QObject::connect(this,SIGNAL(done()), - QCoreApplication::instance(),SLOT(quit()), - Qt::QueuedConnection); +SsuUrlResolver::SsuUrlResolver(): QObject() +{ + QObject::connect(this, SIGNAL(done()), + QCoreApplication::instance(), SLOT(quit()), + Qt::QueuedConnection); } -void SsuUrlResolver::error(QString message){ - SsuLog *ssuLog = SsuLog::instance(); - ssuLog->print(LOG_WARNING, message); +void SsuUrlResolver::error(QString message) +{ + SsuLog *ssuLog = SsuLog::instance(); + ssuLog->print(LOG_WARNING, message); - PluginFrame out("ERROR"); - out.setBody(message.toStdString()); - out.writeTo(std::cout); - QCoreApplication::exit(1); + PluginFrame out("ERROR"); + out.setBody(message.toStdString()); + out.writeTo(std::cout); + QCoreApplication::exit(1); } -bool SsuUrlResolver::writeZyppCredentialsIfNeeded(QString credentialsScope){ - QString filePath = Sandbox::map("/etc/zypp/credentials.d/" + credentialsScope); - QFileInfo credentialsFileInfo(filePath); +bool SsuUrlResolver::writeZyppCredentialsIfNeeded(QString credentialsScope) +{ + QString filePath = Sandbox::map("/etc/zypp/credentials.d/" + credentialsScope); + QFileInfo credentialsFileInfo(filePath); + + /// @TODO: add scope to lastCredentialsUpdate() to allow scope specific update + /// tracking + if (credentialsFileInfo.exists() && + credentialsFileInfo.lastModified() > ssu.lastCredentialsUpdate() && + credentialsScope != "store") { + // zypp credentials up to date + return true; + } + + QFile credentialsFile(filePath); + QPair credentials = ssu.credentials(credentialsScope); + SsuLog *ssuLog = SsuLog::instance(); - /// @TODO: add scope to lastCredentialsUpdate() to allow scope specific update - /// tracking - if (credentialsFileInfo.exists() && - credentialsFileInfo.lastModified() > ssu.lastCredentialsUpdate() && - credentialsScope != "store"){ - // zypp credentials up to date + if (credentials.first == "" || credentials.second == "") { + ssuLog->print(LOG_WARNING, "Returned credentials are empty, skip writing"); + return false; + } + + if (!credentialsFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + ssuLog->print(LOG_WARNING, "Unable to open credentials file for writing"); + return false; + } + + QTextStream out(&credentialsFile); + out << "[" << ssu.credentialsUrl(credentialsScope) << "]\n"; + out << "username=" << credentials.first << "\n"; + out << "password=" << credentials.second << "\n"; + out.flush(); + credentialsFile.close(); return true; - } - - QFile credentialsFile(filePath); - QPair credentials = ssu.credentials(credentialsScope); - SsuLog *ssuLog = SsuLog::instance(); - - if (credentials.first == "" || credentials.second == ""){ - ssuLog->print(LOG_WARNING, "Returned credentials are empty, skip writing"); - return false; - } - - if (!credentialsFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){ - ssuLog->print(LOG_WARNING, "Unable to open credentials file for writing"); - return false; - } - - QTextStream out(&credentialsFile); - out << "[" << ssu.credentialsUrl(credentialsScope) << "]\n"; - out << "username=" << credentials.first << "\n"; - out << "password=" << credentials.second << "\n"; - out.flush(); - credentialsFile.close(); - return true; } -void SsuUrlResolver::run(){ - QHash repoParameters; - QString resolvedUrl, repo; - bool isRnd = false; - SsuLog *ssuLog = SsuLog::instance(); - - PluginFrame in(std::cin); - - if (in.headerEmpty()){ - error("Received empty header list. Most likely your ssu setup is broken"); - } - - PluginFrame::HeaderListIterator it; - QStringList headerList; - - /* - hasKey() for some reason makes zypper run into timeouts, so we have - to handle special keys here - */ - for (it=in.headerBegin();it!=in.headerEnd();it++){ - QString first = QString::fromStdString((*it).first); - QString second = QString::fromStdString((*it).second); - - if (first == "repo"){ - repo = second; - } else if (first == "rnd"){ - isRnd = true; - } else if (first == "deviceFamily"){ - repoParameters.insert(first, second); - } else if (first == "arch"){ - repoParameters.insert(first, second); - } else if (first == "debug"){ - repoParameters.insert("debugSplit", "debug"); - } else { - if ((*it).second.empty()) - headerList.append(first); - else - headerList.append(QString("%1=%2") - .arg(first) - .arg(second)); +void SsuUrlResolver::run() +{ + QHash repoParameters; + QString resolvedUrl, repo; + bool isRnd = false; + SsuLog *ssuLog = SsuLog::instance(); + + PluginFrame in(std::cin); + + if (in.headerEmpty()) { + error("Received empty header list. Most likely your ssu setup is broken"); } - } - - if (!ssu.useSslVerify()) - headerList.append("ssl_verify=no"); - - if (ssu.isRegistered()){ - SignalWait w; - connect(&ssu, SIGNAL(done()), &w, SLOT(finished())); - ssu.updateCredentials(); - w.sleep(); - - // error can be found in ssu.log, so just exit - // TODO: figure out if there's better eror handling for - // zypper plugins than 'blow up' - if (ssu.error()){ - error(ssu.lastError()); + + PluginFrame::HeaderListIterator it; + QStringList headerList; + + /* + hasKey() for some reason makes zypper run into timeouts, so we have + to handle special keys here + */ + for (it = in.headerBegin(); it != in.headerEnd(); it++) { + QString first = QString::fromStdString((*it).first); + QString second = QString::fromStdString((*it).second); + + if (first == "repo") { + repo = second; + } else if (first == "rnd") { + isRnd = true; + } else if (first == "deviceFamily") { + repoParameters.insert(first, second); + } else if (first == "arch") { + repoParameters.insert(first, second); + } else if (first == "debug") { + repoParameters.insert("debugSplit", "debug"); + } else { + if ((*it).second.empty()) + headerList.append(first); + else + headerList.append(QString("%1=%2") + .arg(first) + .arg(second)); + } } - } else - ssuLog->print(LOG_DEBUG, "Device not registered -- skipping credential update"); - - // resolve base url - resolvedUrl = ssu.repoUrl(repo, isRnd, repoParameters); - - QString credentialsScope = ssu.credentialsScope(repo, isRnd); - // only do credentials magic on secure connections - if (resolvedUrl.startsWith("https://") && !credentialsScope.isEmpty() && - (ssu.isRegistered() || credentialsScope == "store")){ - // TODO: check for credentials scope required for repository; check if the file exists; - // compare with configuration, and dump credentials to file if necessary - ssuLog->print(LOG_DEBUG, QString("Requesting credentials for '%1' with RND status %2...").arg(repo).arg(isRnd)); - - // personal store repositories as well as the ones listed in the - // store-auth-repos domain setting use store credentials. Refresh - // here, as we only know after checking scope if we need to have - // store credentials at all - if (credentialsScope == "store"){ - ssu.updateStoreCredentials(); - if (ssu.error()) - error (ssu.lastError()); + + if (!ssu.useSslVerify()) + headerList.append("ssl_verify=no"); + + if (ssu.isRegistered()) { + SignalWait w; + connect(&ssu, SIGNAL(done()), &w, SLOT(finished())); + ssu.updateCredentials(); + w.sleep(); + + // error can be found in ssu.log, so just exit + // TODO: figure out if there's better eror handling for + // zypper plugins than 'blow up' + if (ssu.error()) { + error(ssu.lastError()); + } + } else + ssuLog->print(LOG_DEBUG, "Device not registered -- skipping credential update"); + + // resolve base url + resolvedUrl = ssu.repoUrl(repo, isRnd, repoParameters); + + QString credentialsScope = ssu.credentialsScope(repo, isRnd); + // only do credentials magic on secure connections + if (resolvedUrl.startsWith("https://") && !credentialsScope.isEmpty() && + (ssu.isRegistered() || credentialsScope == "store")) { + // TODO: check for credentials scope required for repository; check if the file exists; + // compare with configuration, and dump credentials to file if necessary + ssuLog->print(LOG_DEBUG, QString("Requesting credentials for '%1' with RND status %2...").arg(repo).arg(isRnd)); + + // personal store repositories as well as the ones listed in the + // store-auth-repos domain setting use store credentials. Refresh + // here, as we only know after checking scope if we need to have + // store credentials at all + if (credentialsScope == "store") { + ssu.updateStoreCredentials(); + if (ssu.error()) + error (ssu.lastError()); + } + headerList.append(QString("credentials=%1").arg(credentialsScope)); + writeZyppCredentialsIfNeeded(credentialsScope); + } else + ssuLog->print(LOG_DEBUG, QString("Skipping credential for %1 with scope %2").arg(repo).arg(credentialsScope)); + + if (!headerList.isEmpty() && !resolvedUrl.isEmpty()) { + QUrl url(resolvedUrl); + + if (url.hasQuery()) { + url.setQuery(url.query() + "&" + headerList.join("&")); + } else + url.setQuery(headerList.join("&")); + + resolvedUrl = url.toString(); } - headerList.append(QString("credentials=%1").arg(credentialsScope)); - writeZyppCredentialsIfNeeded(credentialsScope); - } else - ssuLog->print(LOG_DEBUG, QString("Skipping credential for %1 with scope %2").arg(repo).arg(credentialsScope)); - if (!headerList.isEmpty() && !resolvedUrl.isEmpty()){ - QUrl url(resolvedUrl); + // TODO, we should bail out here if the configuration specifies that the repo + // is protected, but device is not registered and/or we don't have credentials + ssuLog->print(LOG_INFO, QString("%1 resolved to %2").arg(repo).arg(resolvedUrl)); - if (url.hasQuery()){ - url.setQuery(url.query() + "&" + headerList.join("&")); - } else - url.setQuery(headerList.join("&")); - - resolvedUrl = url.toString(); - } - - // TODO, we should bail out here if the configuration specifies that the repo - // is protected, but device is not registered and/or we don't have credentials - ssuLog->print(LOG_INFO, QString("%1 resolved to %2").arg(repo).arg(resolvedUrl)); - - if (resolvedUrl.isEmpty()){ - error("URL for repository is not set."); - } else if (resolvedUrl.indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) != 0) { - error("URL for repository is invalid."); - } else { - PluginFrame out("RESOLVEDURL"); - out.setBody(resolvedUrl.toStdString()); - out.writeTo(std::cout); - } + if (resolvedUrl.isEmpty()) { + error("URL for repository is not set."); + } else if (resolvedUrl.indexOf(QRegExp("[a-z]*://", Qt::CaseInsensitive)) != 0) { + error("URL for repository is invalid."); + } else { + PluginFrame out("RESOLVEDURL"); + out.setBody(resolvedUrl.toStdString()); + out.writeTo(std::cout); + } - emit done(); + emit done(); } diff --git a/ssuurlresolver/ssuurlresolver.h b/ssuurlresolver/ssuurlresolver.h index ef65492..c904664 100644 --- a/ssuurlresolver/ssuurlresolver.h +++ b/ssuurlresolver/ssuurlresolver.h @@ -20,47 +20,52 @@ #include "libssu/ssu.h" // quick hack for waiting for a signal -class SignalWait: public QObject { +class SignalWait: public QObject +{ Q_OBJECT - public: - SignalWait(){ - needRunning=1; +public: + SignalWait() + { + needRunning = 1; } - public slots: - void sleep(){ - if (needRunning==1) - loop.exec(); +public slots: + void sleep() + { + if (needRunning == 1) + loop.exec(); } - virtual void finished(){ - needRunning=0; - loop.exit(); + virtual void finished() + { + needRunning = 0; + loop.exit(); } - private: +private: QEventLoop loop; int needRunning; }; using namespace zypp; -class SsuUrlResolver: public QObject { +class SsuUrlResolver: public QObject +{ Q_OBJECT - public: +public: SsuUrlResolver(); - private: +private: Ssu ssu; void error(QString message); void printJournal(int priority, QString message); bool writeZyppCredentialsIfNeeded(QString credentialsScope); - public slots: +public slots: void run(); - signals: +signals: void done(); }; diff --git a/tests/formatoutput/main.cpp b/tests/formatoutput/main.cpp index 040d3f9..caf2003 100644 --- a/tests/formatoutput/main.cpp +++ b/tests/formatoutput/main.cpp @@ -9,88 +9,91 @@ #include #include -void usage(){ - QTextStream out(stderr); - out << "Parse QTest output on STDIN and make it shiny" << endl - << endl - << "Usage: formatoutput [options]" << endl - << endl - << "\t--skip-pass \tSkip PASS lines [yes]" << endl - << "\t--skip-debug \tSkip QDEBUG lines [yes]" << endl - << "\t--skip-warn \tSkip QWARN lines [no]" << endl - << "\t--skip-config \tSkip Config: lines [yes]" << endl - << endl - << "\t--help \tThis help text" << endl - << endl; +void usage() +{ + QTextStream out(stderr); + out << "Parse QTest output on STDIN and make it shiny" << endl + << endl + << "Usage: formatoutput [options]" << endl + << endl + << "\t--skip-pass \tSkip PASS lines [yes]" << endl + << "\t--skip-debug \tSkip QDEBUG lines [yes]" << endl + << "\t--skip-warn \tSkip QWARN lines [no]" << endl + << "\t--skip-config \tSkip Config: lines [yes]" << endl + << endl + << "\t--help \tThis help text" << endl + << endl; } -bool isTrue(char *argument){ - if (!strcasecmp(argument, "yes") || - !strcasecmp(argument, "true") || - !strcmp(argument, "1")) - return true; - else return false; +bool isTrue(char *argument) +{ + if (!strcasecmp(argument, "yes") || + !strcasecmp(argument, "true") || + !strcmp(argument, "1")) + return true; + else return false; } -int main(int argc, char **argv){ - QTextStream in(stdin); - QTextStream out(stdout); - int c, option_index; +int main(int argc, char **argv) +{ + QTextStream in(stdin); + QTextStream out(stdout); + int c, option_index; - static struct option long_options[] = { - {"skip-pass", required_argument, 0, 0 }, - {"skip-debug", required_argument, 0, 0 }, - {"skip-warn", required_argument, 0, 0 }, - {"skip-config", required_argument, 0, 0 }, - {"help", no_argument, 0, 0 } - }; + static struct option long_options[] = { + {"skip-pass", required_argument, 0, 0 }, + {"skip-debug", required_argument, 0, 0 }, + {"skip-warn", required_argument, 0, 0 }, + {"skip-config", required_argument, 0, 0 }, + {"help", no_argument, 0, 0 } + }; - struct { - bool skip_pass = true; - bool skip_debug = true; - bool skip_warn = false; - bool skip_config = true; - } options; + struct { + bool skip_pass = true; + bool skip_debug = true; + bool skip_warn = false; + bool skip_config = true; + } options; - while ((c=getopt_long_only(argc, argv, "", - long_options, &option_index)) != EOF){ - switch(c){ - case 0: - if (!strcmp(long_options[option_index].name, "help")){ - usage(); - exit(0); - } else if (!strcmp(long_options[option_index].name, "skip-pass")){ - options.skip_pass = isTrue(optarg); - } else if (!strcmp(long_options[option_index].name, "skip-debug")){ - options.skip_debug = isTrue(optarg); - } else if (!strcmp(long_options[option_index].name, "skip-warn")){ - options.skip_warn = isTrue(optarg); - } else if (!strcmp(long_options[option_index].name, "skip-config")){ - options.skip_config = isTrue(optarg); + while ((c = getopt_long_only(argc, argv, "", + long_options, &option_index)) != EOF) { + switch (c) { + case 0: + if (!strcmp(long_options[option_index].name, "help")) { + usage(); + exit(0); + } else if (!strcmp(long_options[option_index].name, "skip-pass")) { + options.skip_pass = isTrue(optarg); + } else if (!strcmp(long_options[option_index].name, "skip-debug")) { + options.skip_debug = isTrue(optarg); + } else if (!strcmp(long_options[option_index].name, "skip-warn")) { + options.skip_warn = isTrue(optarg); + } else if (!strcmp(long_options[option_index].name, "skip-config")) { + options.skip_config = isTrue(optarg); + } + break; + default: + usage(); + exit(-1); } - break; - default: - usage(); - exit(-1); } - } - while (!in.atEnd()){ - QString line = in.readLine(); + while (!in.atEnd()) { + QString line = in.readLine(); - if (line.startsWith("PASS") && options.skip_pass) continue; - if (line.startsWith("QDEBUG") && options.skip_debug) continue; - if (line.startsWith("QWARN") && options.skip_warn) continue; - if (line.startsWith("Config:") && options.skip_config) continue; + if (line.startsWith("PASS") && options.skip_pass) continue; + if (line.startsWith("QDEBUG") && options.skip_debug) continue; + if (line.startsWith("QWARN") && options.skip_warn) continue; + if (line.startsWith("Config:") && options.skip_config) continue; - line.replace(QRegExp("^(\\*{3}.*\\*{3})"), "\033[0;36m\\1\033[0;0m"); - line.replace(QRegExp("^(QDEBUG .*)"), "\033[0;90m\\1\033[0;0m"); - line.replace(QRegExp("^(QWARN .*)"), "\033[0;34m\\1\033[0;0m"); - line.replace(QRegExp("^FAIL!"), "\033[0;31mFAIL!\033[0;0m"); - line.replace(QRegExp("^PASS"), "\033[0;32mPASS\033[0;0m"); - line.replace(QRegExp("^Totals: (\\d{1,} passed), (\\d{1,} failed), (\\d{1,} skipped)"), - "Totals: \033[0;32m\\1\033[0;0m, \033[0;31m\\2\033[0;0m, \033[0;33m\\3\033[0;0m"); - out << line << endl; - } + line.replace(QRegExp("^(\\*{3}.*\\*{3})"), "\033[0;36m\\1\033[0;0m"); + line.replace(QRegExp("^(QDEBUG .*)"), "\033[0;90m\\1\033[0;0m"); + line.replace(QRegExp("^(QWARN .*)"), "\033[0;34m\\1\033[0;0m"); + line.replace(QRegExp("^FAIL!"), "\033[0;31mFAIL!\033[0;0m"); + line.replace(QRegExp("^PASS"), "\033[0;32mPASS\033[0;0m"); + line.replace(QRegExp("^Totals: (\\d{1,} passed), (\\d{1,} failed), (\\d{1,} skipped)"), + "Totals: \033[0;32m\\1\033[0;0m, \033[0;31m\\2\033[0;0m, \033[0;33m\\3\033[0;0m"); + out << line << endl; + } } diff --git a/tests/testutils/process.cpp b/tests/testutils/process.cpp index 5141bdb..c7763a5 100644 --- a/tests/testutils/process.cpp +++ b/tests/testutils/process.cpp @@ -24,47 +24,50 @@ Process::Process() : m_expectFail(false), m_timedOut(false) {} QString Process::execute(const QString &program, const QStringList &arguments, - bool expectedResult){ - Q_ASSERT(m_process.state() == QProcess::NotRunning); - m_program = program; - m_arguments = arguments; - m_expectFail = expectedResult == ExpectFail; - m_process.start(program, arguments); - m_timedOut = !m_process.waitForFinished(); - return m_process.readAllStandardOutput(); + bool expectedResult) +{ + Q_ASSERT(m_process.state() == QProcess::NotRunning); + m_program = program; + m_arguments = arguments; + m_expectFail = expectedResult == ExpectFail; + m_process.start(program, arguments); + m_timedOut = !m_process.waitForFinished(); + return m_process.readAllStandardOutput(); } -bool Process::hasError(){ - return m_timedOut - || m_process.error() != QProcess::UnknownError - || m_process.exitStatus() != QProcess::NormalExit - || (m_process.exitCode() != 0) != m_expectFail; +bool Process::hasError() +{ + return m_timedOut + || m_process.error() != QProcess::UnknownError + || m_process.exitStatus() != QProcess::NormalExit + || (m_process.exitCode() != 0) != m_expectFail; } -QString Process::fmtErrorMessage(){ - if (!hasError()){ - return QString(); - } - - QStringList reasons; - if (m_timedOut){ - reasons.append("Timed out"); - }else if (m_process.exitStatus() != QProcess::NormalExit){ - reasons.append("Process crashed"); - }else if (m_expectFail && (m_process.exitCode() == 0)){ - reasons.append("Did not fail while it was expected to"); - }else{ - if (m_process.error() != QProcess::UnknownError){ - reasons.append(m_process.errorString()); +QString Process::fmtErrorMessage() +{ + if (!hasError()) { + return QString(); } - const QString errorOut = m_process.readAllStandardError(); - if (!errorOut.isEmpty()){ - reasons.append(errorOut); + + QStringList reasons; + if (m_timedOut) { + reasons.append("Timed out"); + } else if (m_process.exitStatus() != QProcess::NormalExit) { + reasons.append("Process crashed"); + } else if (m_expectFail && (m_process.exitCode() == 0)) { + reasons.append("Did not fail while it was expected to"); + } else { + if (m_process.error() != QProcess::UnknownError) { + reasons.append(m_process.errorString()); + } + const QString errorOut = m_process.readAllStandardError(); + if (!errorOut.isEmpty()) { + reasons.append(errorOut); + } } - } - return QString("Failed to execute `%1 %2`: %3") - .arg(m_program) - .arg(QStringList(m_arguments).replaceInStrings(QRegExp("^|$"), "\"").join(" ")) - .arg(reasons.join(": ")); + return QString("Failed to execute `%1 %2`: %3") + .arg(m_program) + .arg(QStringList(m_arguments).replaceInStrings(QRegExp("^|$"), "\"").join(" ")) + .arg(reasons.join(": ")); } diff --git a/tests/testutils/process.h b/tests/testutils/process.h index 4c6fbcf..185f93b 100644 --- a/tests/testutils/process.h +++ b/tests/testutils/process.h @@ -10,22 +10,23 @@ #include -class Process { - public: +class Process +{ +public: enum ExpectedResult { - ExpectSuccess, - ExpectFail + ExpectSuccess, + ExpectFail }; - public: +public: Process(); QString execute(const QString &program, const QStringList &arguments, - bool expectedResult = ExpectSuccess); + bool expectedResult = ExpectSuccess); bool hasError(); QString fmtErrorMessage(); - private: +private: QProcess m_process; QString m_program; QStringList m_arguments; diff --git a/tests/testutils/sandboxhook.cpp b/tests/testutils/sandboxhook.cpp index 9dcc740..c8a9751 100644 --- a/tests/testutils/sandboxhook.cpp +++ b/tests/testutils/sandboxhook.cpp @@ -4,9 +4,9 @@ extern "C" void qt_startup_hook() { - Sandbox *const sandbox = new Sandbox(); - Q_UNUSED(sandbox); + Sandbox *const sandbox = new Sandbox(); + Q_UNUSED(sandbox); - static void(*next_qt_startup_hook)() = (void (*)()) dlsym(RTLD_NEXT, "qt_startup_hook"); - next_qt_startup_hook(); + static void(*next_qt_startup_hook)() = (void (*)()) dlsym(RTLD_NEXT, "qt_startup_hook"); + next_qt_startup_hook(); } diff --git a/tests/ut_coreconfig/coreconfigtest.cpp b/tests/ut_coreconfig/coreconfigtest.cpp index 9993764..1207a45 100644 --- a/tests/ut_coreconfig/coreconfigtest.cpp +++ b/tests/ut_coreconfig/coreconfigtest.cpp @@ -11,76 +11,86 @@ #include "libssu/ssucoreconfig_p.h" -void CoreconfigTest::testCredentialsScope(){ - QCOMPARE(SsuCoreConfig::instance()->credentialsScope("/*ignored*/", false), QString("example")); +void CoreconfigTest::testCredentialsScope() +{ + QCOMPARE(SsuCoreConfig::instance()->credentialsScope("/*ignored*/", false), QString("example")); } -void CoreconfigTest::testCredentials(){ - QCOMPARE(SsuCoreConfig::instance()->credentials("example").first, QString("example_username")); - QCOMPARE(SsuCoreConfig::instance()->credentials("example").second, QString("example_password")); +void CoreconfigTest::testCredentials() +{ + QCOMPARE(SsuCoreConfig::instance()->credentials("example").first, QString("example_username")); + QCOMPARE(SsuCoreConfig::instance()->credentials("example").second, QString("example_password")); } -void CoreconfigTest::testCredentialsUrl(){ - QCOMPARE(SsuCoreConfig::instance()->credentialsUrl("example"), QString("http://creden.tia.ls/")); +void CoreconfigTest::testCredentialsUrl() +{ + QCOMPARE(SsuCoreConfig::instance()->credentialsUrl("example"), QString("http://creden.tia.ls/")); } -void CoreconfigTest::testFlavour(){ - QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("testing")); - SsuCoreConfig::instance()->setFlavour("release"); - QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("release")); +void CoreconfigTest::testFlavour() +{ + QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("testing")); + SsuCoreConfig::instance()->setFlavour("release"); + QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("release")); } -void CoreconfigTest::testDeviceMode(){ - SsuCoreConfig::instance()->remove("deviceMode"); - QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); - SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Add); - QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); - SsuCoreConfig::instance()->setDeviceMode(Ssu::LenientMode, Ssu::Add); - QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode | Ssu::LenientMode); - SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Remove); - QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::LenientMode); - SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); - QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); +void CoreconfigTest::testDeviceMode() +{ + SsuCoreConfig::instance()->remove("deviceMode"); + QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); + SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Add); + QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); + SsuCoreConfig::instance()->setDeviceMode(Ssu::LenientMode, Ssu::Add); + QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode | Ssu::LenientMode); + SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Remove); + QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::LenientMode); + SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); + QCOMPARE(SsuCoreConfig::instance()->deviceMode(), Ssu::ReleaseMode); } -void CoreconfigTest::testDomain(){ - QCOMPARE(SsuCoreConfig::instance()->domain(), QString("")); - SsuCoreConfig::instance()->setDomain("foo"); - QCOMPARE(SsuCoreConfig::instance()->domain(), QString("foo")); +void CoreconfigTest::testDomain() +{ + QCOMPARE(SsuCoreConfig::instance()->domain(), QString("")); + SsuCoreConfig::instance()->setDomain("foo"); + QCOMPARE(SsuCoreConfig::instance()->domain(), QString("foo")); } -void CoreconfigTest::testRegistered(){ - QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); - SsuCoreConfig::instance()->setValue("registered", true); - QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); - SsuCoreConfig::instance()->setValue("privateKey", "fooKey"); - QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); - SsuCoreConfig::instance()->setValue("certificate", "fooCert"); - QCOMPARE(SsuCoreConfig::instance()->isRegistered(), true); +void CoreconfigTest::testRegistered() +{ + QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); + SsuCoreConfig::instance()->setValue("registered", true); + QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); + SsuCoreConfig::instance()->setValue("privateKey", "fooKey"); + QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false); + SsuCoreConfig::instance()->setValue("certificate", "fooCert"); + QCOMPARE(SsuCoreConfig::instance()->isRegistered(), true); } -void CoreconfigTest::testLastCredentialsUpdate(){ - QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(), QDateTime()); - SsuCoreConfig::instance()->setValue("lastCredentialsUpdate", - QDateTime::fromString("2013-04-08", Qt::ISODate)); - QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(), - QDateTime::fromString("2013-04-08", Qt::ISODate)); +void CoreconfigTest::testLastCredentialsUpdate() +{ + QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(), QDateTime()); + SsuCoreConfig::instance()->setValue("lastCredentialsUpdate", + QDateTime::fromString("2013-04-08", Qt::ISODate)); + QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(), + QDateTime::fromString("2013-04-08", Qt::ISODate)); } -void CoreconfigTest::testRelease(){ - QCOMPARE(SsuCoreConfig::instance()->release(false), QString("latest")); - QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next")); - SsuCoreConfig::instance()->setRelease("next", false); - QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next")); - QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next")); - SsuCoreConfig::instance()->setRelease("latest", true); - QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next")); - QCOMPARE(SsuCoreConfig::instance()->release(true), QString("latest")); +void CoreconfigTest::testRelease() +{ + QCOMPARE(SsuCoreConfig::instance()->release(false), QString("latest")); + QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next")); + SsuCoreConfig::instance()->setRelease("next", false); + QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next")); + QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next")); + SsuCoreConfig::instance()->setRelease("latest", true); + QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next")); + QCOMPARE(SsuCoreConfig::instance()->release(true), QString("latest")); } -void CoreconfigTest::testSslVerify(){ - QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), true); - SsuCoreConfig::instance()->setValue("ssl-verify", false); - QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), false); +void CoreconfigTest::testSslVerify() +{ + QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), true); + SsuCoreConfig::instance()->setValue("ssl-verify", false); + QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), false); } diff --git a/tests/ut_coreconfig/coreconfigtest.h b/tests/ut_coreconfig/coreconfigtest.h index 1206d01..aedfad1 100644 --- a/tests/ut_coreconfig/coreconfigtest.h +++ b/tests/ut_coreconfig/coreconfigtest.h @@ -10,10 +10,11 @@ #include -class CoreconfigTest: public QObject { +class CoreconfigTest: public QObject +{ Q_OBJECT - private slots: +private slots: void testCredentialsScope(); void testCredentials(); void testCredentialsUrl(); diff --git a/tests/ut_coreconfig/main.cpp b/tests/ut_coreconfig/main.cpp index a967946..40500b2 100644 --- a/tests/ut_coreconfig/main.cpp +++ b/tests/ut_coreconfig/main.cpp @@ -10,17 +10,18 @@ #include "libssu/sandbox_p.h" #include "coreconfigtest.h" -int main(int argc, char **argv){ - Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess); - if (!sandbox.activate()){ - qFatal("Failed to activate sandbox"); - } +int main(int argc, char **argv) +{ + Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess); + if (!sandbox.activate()) { + qFatal("Failed to activate sandbox"); + } - CoreconfigTest coreconfigTest; + CoreconfigTest coreconfigTest; - if (QTest::qExec(&coreconfigTest, argc, argv)) - return 1; + if (QTest::qExec(&coreconfigTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_deviceinfo/deviceinfotest.cpp b/tests/ut_deviceinfo/deviceinfotest.cpp index e51853d..8c00969 100644 --- a/tests/ut_deviceinfo/deviceinfotest.cpp +++ b/tests/ut_deviceinfo/deviceinfotest.cpp @@ -11,61 +11,65 @@ #include "libssu/ssudeviceinfo.h" -void DeviceInfoTest::testAdaptationVariables(){ - SsuDeviceInfo deviceInfo("N950"); - QHash variables; - QHash variablesExpected; - variablesExpected["adaptation"] = "n950-n9"; - variablesExpected["foo-n9"] = "foo-n9-val"; - variablesExpected["foo-n950-n9"] = "foo-n950-n9-val"; - - QString repoName = deviceInfo.adaptationVariables("adaptation1", &variables); - - QCOMPARE(variables, variablesExpected); - QCOMPARE(repoName, QString("adaptation")); +void DeviceInfoTest::testAdaptationVariables() +{ + SsuDeviceInfo deviceInfo("N950"); + QHash variables; + QHash variablesExpected; + variablesExpected["adaptation"] = "n950-n9"; + variablesExpected["foo-n9"] = "foo-n9-val"; + variablesExpected["foo-n950-n9"] = "foo-n950-n9-val"; + + QString repoName = deviceInfo.adaptationVariables("adaptation1", &variables); + + QCOMPARE(variables, variablesExpected); + QCOMPARE(repoName, QString("adaptation")); } -void DeviceInfoTest::testDeviceUid(){ - QVERIFY2(!SsuDeviceInfo().deviceUid().isEmpty(), "No method to get device UID on this platform"); +void DeviceInfoTest::testDeviceUid() +{ + QVERIFY2(!SsuDeviceInfo().deviceUid().isEmpty(), "No method to get device UID on this platform"); } -void DeviceInfoTest::testVariableSection(){ - SsuDeviceInfo deviceInfo; +void DeviceInfoTest::testVariableSection() +{ + SsuDeviceInfo deviceInfo; - QHash fooVars; - QHash fooVarsExpected; - fooVarsExpected["foo1"] = "foo1Val"; - fooVarsExpected["foo2"] = "foo2Val"; + QHash fooVars; + QHash fooVarsExpected; + fooVarsExpected["foo1"] = "foo1Val"; + fooVarsExpected["foo2"] = "foo2Val"; - deviceInfo.variableSection("foo", &fooVars); + deviceInfo.variableSection("foo", &fooVars); - QCOMPARE(fooVars, fooVarsExpected); + QCOMPARE(fooVars, fooVarsExpected); - QHash barVars; - QHash barVarsExpected; - barVarsExpected["bar1"] = "bar1Val"; - barVarsExpected["bar2"] = "bar2Val"; + QHash barVars; + QHash barVarsExpected; + barVarsExpected["bar1"] = "bar1Val"; + barVarsExpected["bar2"] = "bar2Val"; - deviceInfo.variableSection("bar", &barVars); + deviceInfo.variableSection("bar", &barVars); - QCOMPARE(barVars, barVarsExpected); + QCOMPARE(barVars, barVarsExpected); - QHash bazVars; - QHash bazVarsExpected; - bazVarsExpected["foo1"] = "foo1Val"; - bazVarsExpected["foo2"] = "foo2Val"; - bazVarsExpected["bar1"] = "bar1Val"; - bazVarsExpected["bar2"] = "bar2Val"; + QHash bazVars; + QHash bazVarsExpected; + bazVarsExpected["foo1"] = "foo1Val"; + bazVarsExpected["foo2"] = "foo2Val"; + bazVarsExpected["bar1"] = "bar1Val"; + bazVarsExpected["bar2"] = "bar2Val"; - deviceInfo.variableSection("baz", &bazVars); + deviceInfo.variableSection("baz", &bazVars); - QCOMPARE(bazVars, bazVarsExpected); + QCOMPARE(bazVars, bazVarsExpected); } -void DeviceInfoTest::testValue(){ - SsuDeviceInfo deviceInfo("N950"); - QCOMPARE(deviceInfo.value("family").toString(), QString("n950-n9")); - QCOMPARE(deviceInfo.value("adaptation-repos").toStringList(), - QString("n9xx-common,n950-n9").split(',')); - QCOMPARE(deviceInfo.value("foo").toString(), QString("n950-foo")); +void DeviceInfoTest::testValue() +{ + SsuDeviceInfo deviceInfo("N950"); + QCOMPARE(deviceInfo.value("family").toString(), QString("n950-n9")); + QCOMPARE(deviceInfo.value("adaptation-repos").toStringList(), + QString("n9xx-common,n950-n9").split(',')); + QCOMPARE(deviceInfo.value("foo").toString(), QString("n950-foo")); } diff --git a/tests/ut_deviceinfo/deviceinfotest.h b/tests/ut_deviceinfo/deviceinfotest.h index 58da514..bd71fe6 100644 --- a/tests/ut_deviceinfo/deviceinfotest.h +++ b/tests/ut_deviceinfo/deviceinfotest.h @@ -10,10 +10,11 @@ #include -class DeviceInfoTest: public QObject { +class DeviceInfoTest: public QObject +{ Q_OBJECT - private slots: +private slots: void testAdaptationVariables(); void testDeviceUid(); void testVariableSection(); diff --git a/tests/ut_deviceinfo/main.cpp b/tests/ut_deviceinfo/main.cpp index b7519ad..0259cbf 100644 --- a/tests/ut_deviceinfo/main.cpp +++ b/tests/ut_deviceinfo/main.cpp @@ -10,17 +10,18 @@ #include "libssu/sandbox_p.h" #include "deviceinfotest.h" -int main(int argc, char **argv){ - Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess); - if (!sandbox.activate()){ - qFatal("Failed to activate sandbox"); - } +int main(int argc, char **argv) +{ + Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess); + if (!sandbox.activate()) { + qFatal("Failed to activate sandbox"); + } - DeviceInfoTest deviceinfoTest; + DeviceInfoTest deviceinfoTest; - if (QTest::qExec(&deviceinfoTest, argc, argv)) - return 1; + if (QTest::qExec(&deviceinfoTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_featuremodel/featuremodeltest.cpp b/tests/ut_featuremodel/featuremodeltest.cpp index 2b8a5a4..af9956c 100644 --- a/tests/ut_featuremodel/featuremodeltest.cpp +++ b/tests/ut_featuremodel/featuremodeltest.cpp @@ -11,15 +11,18 @@ #include #include "libssu/ssufeaturemodel.h" -void FeatureModelTest::initTestCase(){ +void FeatureModelTest::initTestCase() +{ } -void FeatureModelTest::cleanupTestCase(){ +void FeatureModelTest::cleanupTestCase() +{ } -void FeatureModelTest::testFeatures(){ +void FeatureModelTest::testFeatures() +{ SsuFeatureModel featureModel(0, ":/testdata"); // Features with no name are skipped (feature-noname.ini) diff --git a/tests/ut_featuremodel/featuremodeltest.h b/tests/ut_featuremodel/featuremodeltest.h index bd21a4a..e394031 100644 --- a/tests/ut_featuremodel/featuremodeltest.h +++ b/tests/ut_featuremodel/featuremodeltest.h @@ -10,10 +10,11 @@ #include -class FeatureModelTest: public QObject { +class FeatureModelTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void cleanupTestCase(); void testFeatures(); diff --git a/tests/ut_featuremodel/main.cpp b/tests/ut_featuremodel/main.cpp index cd2a5a0..3f538fc 100644 --- a/tests/ut_featuremodel/main.cpp +++ b/tests/ut_featuremodel/main.cpp @@ -10,13 +10,14 @@ #include "featuremodeltest.h" -int main(int argc, char **argv){ - QCoreApplication app(argc, argv); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); - FeatureModelTest featureModelTest; + FeatureModelTest featureModelTest; - if (QTest::qExec(&featureModelTest, argc, argv)) - return 1; + if (QTest::qExec(&featureModelTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_repomanager/main.cpp b/tests/ut_repomanager/main.cpp index 8c36ff8..3321595 100644 --- a/tests/ut_repomanager/main.cpp +++ b/tests/ut_repomanager/main.cpp @@ -10,17 +10,18 @@ #include "libssu/sandbox_p.h" #include "repomanagertest.h" -int main(int argc, char **argv){ - Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess); - if (!sandbox.activate()){ - qFatal("Failed to activate sandbox"); - } +int main(int argc, char **argv) +{ + Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess); + if (!sandbox.activate()) { + qFatal("Failed to activate sandbox"); + } - RepoManagerTest repomanagerTest; + RepoManagerTest repomanagerTest; - if (QTest::qExec(&repomanagerTest, argc, argv)) - return 1; + if (QTest::qExec(&repomanagerTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_repomanager/repomanagertest.cpp b/tests/ut_repomanager/repomanagertest.cpp index 8a09f49..b2bd442 100644 --- a/tests/ut_repomanager/repomanagertest.cpp +++ b/tests/ut_repomanager/repomanagertest.cpp @@ -14,199 +14,203 @@ #include "libssu/ssucoreconfig_p.h" #include "libssu/ssurepomanager.h" -void RepoManagerTest::initTestCase(){ - rndRepos << "mer-core" << "adaptation" << "nemo" << "non-oss" << "oss"; - releaseRepos << "vendor" << "apps"; +void RepoManagerTest::initTestCase() +{ + rndRepos << "mer-core" << "adaptation" << "nemo" << "non-oss" << "oss"; + releaseRepos << "vendor" << "apps"; } -void RepoManagerTest::testSettings(){ - SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); - SsuRepoManager repoManager; - - repoManager.add("repo1", "http://repo1"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - - repoManager.enable("repo1"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - - repoManager.add("repo1"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - - repoManager.disable("repo1"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(coreConfig->value("disabled-repos").toStringList().contains("repo1")); - - repoManager.enable("repo1"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - - repoManager.add("repo2", "http://repo2"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); - - repoManager.disable("repo2"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(coreConfig->value("disabled-repos").toStringList().contains("repo2")); - - repoManager.enable("repo2"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); - - repoManager.add("repo2"); - QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); - - repoManager.remove("repo1"); - QVERIFY(!coreConfig->contains("repository-urls/repo1")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); - QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); - - repoManager.remove("repo2"); - QVERIFY(!coreConfig->contains("repository-urls/repo1")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); - QVERIFY(!coreConfig->contains("repository-urls/repo2")); - QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); - QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); +void RepoManagerTest::testSettings() +{ + SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); + SsuRepoManager repoManager; + + repoManager.add("repo1", "http://repo1"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + + repoManager.enable("repo1"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + + repoManager.add("repo1"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + + repoManager.disable("repo1"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(coreConfig->value("disabled-repos").toStringList().contains("repo1")); + + repoManager.enable("repo1"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + + repoManager.add("repo2", "http://repo2"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); + + repoManager.disable("repo2"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(coreConfig->value("disabled-repos").toStringList().contains("repo2")); + + repoManager.enable("repo2"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); + + repoManager.add("repo2"); + QCOMPARE(coreConfig->value("repository-urls/repo1").toString(), QString("http://repo1")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); + + repoManager.remove("repo1"); + QVERIFY(!coreConfig->contains("repository-urls/repo1")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QCOMPARE(coreConfig->value("repository-urls/repo2").toString(), QString("http://repo2")); + QVERIFY(coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); + + repoManager.remove("repo2"); + QVERIFY(!coreConfig->contains("repository-urls/repo1")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo1")); + QVERIFY(!coreConfig->contains("repository-urls/repo2")); + QVERIFY(!coreConfig->value("enabled-repos").toStringList().contains("repo2")); + QVERIFY(!coreConfig->value("disabled-repos").toStringList().contains("repo2")); } -void RepoManagerTest::testCustomRepos(){ - SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); - SsuRepoManager repoManager; - QStringList customRepos; - QSet set; - - repoManager.add("r1", "http://localhost/r1/"); - repoManager.add("r2", "http://localhost/r2/"); - customRepos << "r1" << "r2"; - - QCOMPARE(releaseRepos.toSet().count(), 2); - - // check default release repos + custom repos - coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); - set = releaseRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 4); - QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); - - // check default rnd repos + custom repos - coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::RndMode); - set = rndRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 7); - QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); - - // enable store repository as preconfigured custom repo - customRepos << "store"; - repoManager.add("store"); - set = rndRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 8); - QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); - - // check store repo with release mode - coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); - set = releaseRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 5); - QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); - - // check repositories in update mode - // store + other custom repositories should be gone - coreConfig->setDeviceMode(Ssu::UpdateMode, Ssu::Add); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::UpdateMode); - QVERIFY(releaseRepos.toSet() == repoManager.repos().toSet()); - - // check rndmode + update mode - coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::UpdateMode | Ssu::RndMode); - QVERIFY(rndRepos.toSet() == repoManager.repos().toSet()); - - coreConfig->setDeviceMode(Ssu::RndMode | Ssu::UpdateMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::UpdateMode | Ssu::RndMode); - QVERIFY(rndRepos.toSet() == repoManager.repos().toSet()); - - // check appinstall mode - // custom repositories, apart from store, should be gone - customRepos.clear(); - customRepos << "store"; - - // check release mode - coreConfig->setDeviceMode(Ssu::ReleaseMode | Ssu::AppInstallMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::AppInstallMode); - set = releaseRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 3); - QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); - - // and rnd mode - coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::AppInstallMode | Ssu::RndMode); - set = rndRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 6); - QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); - - coreConfig->setDeviceMode(Ssu::RndMode | Ssu::AppInstallMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::AppInstallMode | Ssu::RndMode); - set = rndRepos.toSet().unite(repoManager.repos().toSet()); - QCOMPARE(set.count(), 6); - QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); +void RepoManagerTest::testCustomRepos() +{ + SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); + SsuRepoManager repoManager; + QStringList customRepos; + QSet set; + + repoManager.add("r1", "http://localhost/r1/"); + repoManager.add("r2", "http://localhost/r2/"); + customRepos << "r1" << "r2"; + + QCOMPARE(releaseRepos.toSet().count(), 2); + + // check default release repos + custom repos + coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); + set = releaseRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 4); + QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); + + // check default rnd repos + custom repos + coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::RndMode); + set = rndRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 7); + QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); + + // enable store repository as preconfigured custom repo + customRepos << "store"; + repoManager.add("store"); + set = rndRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 8); + QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); + + // check store repo with release mode + coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); + set = releaseRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 5); + QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); + + // check repositories in update mode + // store + other custom repositories should be gone + coreConfig->setDeviceMode(Ssu::UpdateMode, Ssu::Add); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::UpdateMode); + QVERIFY(releaseRepos.toSet() == repoManager.repos().toSet()); + + // check rndmode + update mode + coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::UpdateMode | Ssu::RndMode); + QVERIFY(rndRepos.toSet() == repoManager.repos().toSet()); + + coreConfig->setDeviceMode(Ssu::RndMode | Ssu::UpdateMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::UpdateMode | Ssu::RndMode); + QVERIFY(rndRepos.toSet() == repoManager.repos().toSet()); + + // check appinstall mode + // custom repositories, apart from store, should be gone + customRepos.clear(); + customRepos << "store"; + + // check release mode + coreConfig->setDeviceMode(Ssu::ReleaseMode | Ssu::AppInstallMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::AppInstallMode); + set = releaseRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 3); + QVERIFY(set == customRepos.toSet().unite(releaseRepos.toSet())); + + // and rnd mode + coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::AppInstallMode | Ssu::RndMode); + set = rndRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 6); + QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); + + coreConfig->setDeviceMode(Ssu::RndMode | Ssu::AppInstallMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::AppInstallMode | Ssu::RndMode); + set = rndRepos.toSet().unite(repoManager.repos().toSet()); + QCOMPARE(set.count(), 6); + QVERIFY(set == customRepos.toSet().unite(rndRepos.toSet())); } -void RepoManagerTest::testRepos(){ - SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); - SsuRepoManager repoManager; - QSet set; - - // first, check if the repository lists are correct by explicitely - // specifying rnd and release modes - set = rndRepos.toSet().subtract(repoManager.repos(true).toSet()); - QVERIFY(set.isEmpty()); - - set = releaseRepos.toSet().subtract(repoManager.repos(false).toSet()); - QVERIFY(set.isEmpty()); - - // second, check if changing the device mode in the configuration - // properly switches between modes - coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); - set = releaseRepos.toSet().subtract(repoManager.repos().toSet()); - QVERIFY(set.isEmpty()); - - // both adding rnd-mode on top of release mode, and setting it - // to rnd mode only should switch the device to rnd mode - coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); - QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::RndMode); - set = rndRepos.toSet().subtract(repoManager.repos().toSet()); - QVERIFY(set.isEmpty()); - - coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Replace); - QCOMPARE(coreConfig->deviceMode(), Ssu::RndMode); - set = rndRepos.toSet().subtract(repoManager.repos().toSet()); - QVERIFY(set.isEmpty()); +void RepoManagerTest::testRepos() +{ + SsuCoreConfig *const coreConfig = SsuCoreConfig::instance(); + SsuRepoManager repoManager; + QSet set; + + // first, check if the repository lists are correct by explicitely + // specifying rnd and release modes + set = rndRepos.toSet().subtract(repoManager.repos(true).toSet()); + QVERIFY(set.isEmpty()); + + set = releaseRepos.toSet().subtract(repoManager.repos(false).toSet()); + QVERIFY(set.isEmpty()); + + // second, check if changing the device mode in the configuration + // properly switches between modes + coreConfig->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode); + set = releaseRepos.toSet().subtract(repoManager.repos().toSet()); + QVERIFY(set.isEmpty()); + + // both adding rnd-mode on top of release mode, and setting it + // to rnd mode only should switch the device to rnd mode + coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Add); + QCOMPARE(coreConfig->deviceMode(), Ssu::ReleaseMode | Ssu::RndMode); + set = rndRepos.toSet().subtract(repoManager.repos().toSet()); + QVERIFY(set.isEmpty()); + + coreConfig->setDeviceMode(Ssu::RndMode, Ssu::Replace); + QCOMPARE(coreConfig->deviceMode(), Ssu::RndMode); + set = rndRepos.toSet().subtract(repoManager.repos().toSet()); + QVERIFY(set.isEmpty()); } diff --git a/tests/ut_repomanager/repomanagertest.h b/tests/ut_repomanager/repomanagertest.h index 560dafd..25ea381 100644 --- a/tests/ut_repomanager/repomanagertest.h +++ b/tests/ut_repomanager/repomanagertest.h @@ -11,16 +11,17 @@ #include #include -class RepoManagerTest: public QObject { +class RepoManagerTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void testSettings(); void testCustomRepos(); void testRepos(); - private: +private: QStringList rndRepos, releaseRepos; }; diff --git a/tests/ut_sandbox/main.cpp b/tests/ut_sandbox/main.cpp index 2dae6a3..350dd50 100644 --- a/tests/ut_sandbox/main.cpp +++ b/tests/ut_sandbox/main.cpp @@ -9,11 +9,12 @@ #include "sandboxtest.h" -int main(int argc, char **argv){ - SandboxTest sandboxTest; +int main(int argc, char **argv) +{ + SandboxTest sandboxTest; - if (QTest::qExec(&sandboxTest, argc, argv)) - return 1; + if (QTest::qExec(&sandboxTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_sandbox/sandboxtest.cpp b/tests/ut_sandbox/sandboxtest.cpp index 17480c4..864d664 100644 --- a/tests/ut_sandbox/sandboxtest.cpp +++ b/tests/ut_sandbox/sandboxtest.cpp @@ -11,69 +11,71 @@ #include "libssu/sandbox_p.h" -void SandboxTest::test(){ +void SandboxTest::test() +{ - const QDir::Filters noHidden = QDir::AllEntries | QDir::NoDotAndDotDot; + const QDir::Filters noHidden = QDir::AllEntries | QDir::NoDotAndDotDot; - QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name), - QStringList() - << "world-and-sandbox" - << "world-only" - << "world-only-to-be-copied-into-sandbox"); + QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name), + QStringList() + << "world-and-sandbox" + << "world-only" + << "world-only-to-be-copied-into-sandbox"); - QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).trimmed(), - QString("world/world-only")); + QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).trimmed(), + QString("world/world-only")); - QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(), - QString("world/world-and-sandbox")); + QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(), + QString("world/world-and-sandbox")); - QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) - .isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) - .trimmed(), QString("world/world-only-to-be-copied-into-sandbox")); + QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) + .isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) + .trimmed(), QString("world/world-only-to-be-copied-into-sandbox")); - QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists()); + QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists()); - Sandbox sandbox(Sandbox::map(LOCATE_DATA_PATH, "/sandbox"), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess | Sandbox::ChildProcesses); - sandbox.addWorldFiles(Sandbox::map(LOCATE_DATA_PATH, "/world"), QDir::AllEntries, - QStringList() << "*-to-be-copied-into-sandbox"); - QVERIFY(sandbox.activate()); + Sandbox sandbox(Sandbox::map(LOCATE_DATA_PATH, "/sandbox"), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess | Sandbox::ChildProcesses); + sandbox.addWorldFiles(Sandbox::map(LOCATE_DATA_PATH, "/world"), QDir::AllEntries, + QStringList() << "*-to-be-copied-into-sandbox"); + QVERIFY(sandbox.activate()); - QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name), - QStringList() - << "sandbox-only" - << "world-and-sandbox" - << "world-only-to-be-copied-into-sandbox"); + QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name), + QStringList() + << "sandbox-only" + << "world-and-sandbox" + << "world-only-to-be-copied-into-sandbox"); - QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).exists()); + QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).exists()); - QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(), - QString("sandbox/world-and-sandbox")); + QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(), + QString("sandbox/world-and-sandbox")); - QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) - .isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) - .trimmed(), QString("world/world-only-to-be-copied-into-sandbox")); + QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) + .isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox")) + .trimmed(), QString("world/world-only-to-be-copied-into-sandbox")); - QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists()); - QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).isWritable()); - QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).trimmed(), - QString("sandbox/sandbox-only")); + QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists()); + QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).isWritable()); + QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).trimmed(), + QString("sandbox/sandbox-only")); } -QString SandboxTest::readAll(const QString &fileName){ - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)){ - qWarning("%s: Failed to open file for reading: '%s': %s", Q_FUNC_INFO, qPrintable(fileName), - qPrintable(file.errorString())); - return QString(); - } +QString SandboxTest::readAll(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + qWarning("%s: Failed to open file for reading: '%s': %s", Q_FUNC_INFO, qPrintable(fileName), + qPrintable(file.errorString())); + return QString(); + } - return file.readAll(); + return file.readAll(); } diff --git a/tests/ut_sandbox/sandboxtest.h b/tests/ut_sandbox/sandboxtest.h index dbb0e15..22cba3c 100644 --- a/tests/ut_sandbox/sandboxtest.h +++ b/tests/ut_sandbox/sandboxtest.h @@ -10,13 +10,14 @@ #include -class SandboxTest: public QObject { +class SandboxTest: public QObject +{ Q_OBJECT - private slots: +private slots: void test(); - private: +private: static QString readAll(const QString &fileName); }; diff --git a/tests/ut_settings/main.cpp b/tests/ut_settings/main.cpp index 2e1e7a9..a266b0d 100644 --- a/tests/ut_settings/main.cpp +++ b/tests/ut_settings/main.cpp @@ -11,18 +11,19 @@ #include "settingstest.h" #include "upgradetesthelper.h" -int main(int argc, char **argv){ - QCoreApplication app(argc, argv); +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); - if (app.arguments().contains("-generate-upgrade-test-recipe")){ - QTextStream out(stdout); - return UpgradeTestHelper::generateSnapshotRecipe(&out) ? 0 : 1; - } + if (app.arguments().contains("-generate-upgrade-test-recipe")) { + QTextStream out(stdout); + return UpgradeTestHelper::generateSnapshotRecipe(&out) ? 0 : 1; + } - SettingsTest settingsTest; + SettingsTest settingsTest; - if (QTest::qExec(&settingsTest, argc, argv)) - return 1; + if (QTest::qExec(&settingsTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_settings/settingstest.cpp b/tests/ut_settings/settingstest.cpp index c3fefa3..6ac127e 100644 --- a/tests/ut_settings/settingstest.cpp +++ b/tests/ut_settings/settingstest.cpp @@ -12,125 +12,131 @@ #include "libssu/ssusettings_p.h" #include "upgradetesthelper.h" -void SettingsTest::initTestCase(){ +void SettingsTest::initTestCase() +{ } -void SettingsTest::cleanupTestCase(){ +void SettingsTest::cleanupTestCase() +{ } -void SettingsTest::testMerge_data(){ - // Key names state which file(s) a key is set in (master, foo or bar). Value - // is always in form "-value" based on which file it is taken from. +void SettingsTest::testMerge_data() +{ + // Key names state which file(s) a key is set in (master, foo or bar). Value + // is always in form "-value" based on which file it is taken from. - const QScopedPointer masterFile( - QTemporaryFile::createLocalFile(":/testdata/merge/settings.ini")); - QSettings master(masterFile->fileName(), QSettings::IniFormat); + const QScopedPointer masterFile( + QTemporaryFile::createLocalFile(":/testdata/merge/settings.ini")); + QSettings master(masterFile->fileName(), QSettings::IniFormat); - const QStringList settingsFiles = QStringList() - << ":/testdata/merge/settings.d/bar.ini" - << ":/testdata/merge/settings.d/foo.ini"; + const QStringList settingsFiles = QStringList() + << ":/testdata/merge/settings.d/bar.ini" + << ":/testdata/merge/settings.d/foo.ini"; - SsuSettings::merge(&master, settingsFiles); + SsuSettings::merge(&master, settingsFiles); - QSettings expected(":/testdata/merge/merged.ini", QSettings::IniFormat); + QSettings expected(":/testdata/merge/merged.ini", QSettings::IniFormat); - const QSet masterKeys = master.allKeys().toSet(); - const QSet expectedKeys = expected.allKeys().toSet(); + const QSet masterKeys = master.allKeys().toSet(); + const QSet expectedKeys = expected.allKeys().toSet(); - QTest::addColumn("keyIsMerged"); - QTest::addColumn("keyShouldBeMerged"); - QTest::addColumn("actualValue"); - QTest::addColumn("expectedValue"); + QTest::addColumn("keyIsMerged"); + QTest::addColumn("keyShouldBeMerged"); + QTest::addColumn("actualValue"); + QTest::addColumn("expectedValue"); - foreach (const QString &key, masterKeys + expectedKeys){ - QTest::newRow(qPrintable(key)) - << masterKeys.contains(key) - << expectedKeys.contains(key) - << master.value(key).toString() - << expected.value(key).toString(); - } + foreach (const QString &key, masterKeys + expectedKeys) { + QTest::newRow(qPrintable(key)) + << masterKeys.contains(key) + << expectedKeys.contains(key) + << master.value(key).toString() + << expected.value(key).toString(); + } } -void SettingsTest::testMerge(){ - QFETCH(bool, keyIsMerged); - QFETCH(bool, keyShouldBeMerged); - QFETCH(QString, actualValue); - QFETCH(QString, expectedValue); +void SettingsTest::testMerge() +{ + QFETCH(bool, keyIsMerged); + QFETCH(bool, keyShouldBeMerged); + QFETCH(QString, actualValue); + QFETCH(QString, expectedValue); - QCOMPARE(keyIsMerged, keyShouldBeMerged); - QCOMPARE(actualValue, expectedValue); + QCOMPARE(keyIsMerged, keyShouldBeMerged); + QCOMPARE(actualValue, expectedValue); } -void SettingsTest::testUpgrade_data(){ - // Read recipe - QFile recipe(":/testdata/upgrade/recipe"); - QVERIFY(recipe.open(QIODevice::ReadOnly)); - QList testCases = UpgradeTestHelper::readRecipe(&recipe); +void SettingsTest::testUpgrade_data() +{ + // Read recipe + QFile recipe(":/testdata/upgrade/recipe"); + QVERIFY(recipe.open(QIODevice::ReadOnly)); + QList testCases = UpgradeTestHelper::readRecipe(&recipe); - // Generate settings file according to recipe - QTemporaryFile settingsFile; - QVERIFY(settingsFile.open() == true); + // Generate settings file according to recipe + QTemporaryFile settingsFile; + QVERIFY(settingsFile.open() == true); - QSettings settings(settingsFile.fileName(), QSettings::IniFormat); + QSettings settings(settingsFile.fileName(), QSettings::IniFormat); - UpgradeTestHelper::fillSettings(&settings, testCases); + UpgradeTestHelper::fillSettings(&settings, testCases); - // Generate defaults file according to recipe - QTemporaryFile defaultSettingsFile; - QVERIFY(defaultSettingsFile.open() == true); + // Generate defaults file according to recipe + QTemporaryFile defaultSettingsFile; + QVERIFY(defaultSettingsFile.open() == true); - QSettings defaultSettings(defaultSettingsFile.fileName(), QSettings::IniFormat); + QSettings defaultSettings(defaultSettingsFile.fileName(), QSettings::IniFormat); - UpgradeTestHelper::fillDefaultSettings(&defaultSettings, testCases); + UpgradeTestHelper::fillDefaultSettings(&defaultSettings, testCases); - // Parse settings -- do upgrade + // Parse settings -- do upgrade #if 0 - settingsFile.seek(0); - defaultSettingsFile.seek(0); - qDebug() << "SETTINGS {{{\n" << settingsFile.readAll() << "\n}}}"; - qDebug() << "DEFAULT SETTINGS {{{\n" << defaultSettingsFile.readAll() << "\n}}}"; + settingsFile.seek(0); + defaultSettingsFile.seek(0); + qDebug() << "SETTINGS {{{\n" << settingsFile.readAll() << "\n}}}"; + qDebug() << "DEFAULT SETTINGS {{{\n" << defaultSettingsFile.readAll() << "\n}}}"; #endif - SsuSettings ssuSettings(settingsFile.fileName(), QSettings::IniFormat, - defaultSettingsFile.fileName()); + SsuSettings ssuSettings(settingsFile.fileName(), QSettings::IniFormat, + defaultSettingsFile.fileName()); #if 0 - settingsFile.seek(0); - qDebug() << "SETTINGS UPGRADED {{{\n" << settingsFile.readAll() << "\n}}}"; + settingsFile.seek(0); + qDebug() << "SETTINGS UPGRADED {{{\n" << settingsFile.readAll() << "\n}}}"; #endif - // Record data for verification phase - QTest::addColumn("keyIsSet"); - QTest::addColumn("keyShouldBeSet"); - QTest::addColumn("actualValue"); - QTest::addColumn("expectedValue"); - - foreach (const UpgradeTestHelper::TestCase &testCase, testCases){ - foreach (const QString &group, UpgradeTestHelper::groups()){ - const QString key = group.isEmpty() ? testCase.key() : group + '/' + testCase.key(); - QTest::newRow(qPrintable(QString("%1%2:%3:%4") - .arg(group.isEmpty() ? "" : group + "/") - .arg(testCase.history()) - .arg(testCase.current()) - .arg(testCase.expected()))) - << ssuSettings.contains(key) - << testCase.keyShouldBeSet() - << ssuSettings.value(key).toString() - << testCase.expected(); + // Record data for verification phase + QTest::addColumn("keyIsSet"); + QTest::addColumn("keyShouldBeSet"); + QTest::addColumn("actualValue"); + QTest::addColumn("expectedValue"); + + foreach (const UpgradeTestHelper::TestCase &testCase, testCases) { + foreach (const QString &group, UpgradeTestHelper::groups()) { + const QString key = group.isEmpty() ? testCase.key() : group + '/' + testCase.key(); + QTest::newRow(qPrintable(QString("%1%2:%3:%4") + .arg(group.isEmpty() ? "" : group + "/") + .arg(testCase.history()) + .arg(testCase.current()) + .arg(testCase.expected()))) + << ssuSettings.contains(key) + << testCase.keyShouldBeSet() + << ssuSettings.value(key).toString() + << testCase.expected(); + } } - } } -void SettingsTest::testUpgrade(){ - QFETCH(bool, keyIsSet); - QFETCH(bool, keyShouldBeSet); - QFETCH(QString, actualValue); - QFETCH(QString, expectedValue); +void SettingsTest::testUpgrade() +{ + QFETCH(bool, keyIsSet); + QFETCH(bool, keyShouldBeSet); + QFETCH(QString, actualValue); + QFETCH(QString, expectedValue); - QCOMPARE(keyIsSet, keyShouldBeSet); - if (keyIsSet){ - QCOMPARE(actualValue, expectedValue); - } + QCOMPARE(keyIsSet, keyShouldBeSet); + if (keyIsSet) { + QCOMPARE(actualValue, expectedValue); + } } diff --git a/tests/ut_settings/settingstest.h b/tests/ut_settings/settingstest.h index 42c7b49..62c4706 100644 --- a/tests/ut_settings/settingstest.h +++ b/tests/ut_settings/settingstest.h @@ -10,10 +10,11 @@ #include -class SettingsTest: public QObject { +class SettingsTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void cleanupTestCase(); void testMerge_data(); @@ -21,7 +22,7 @@ class SettingsTest: public QObject { void testUpgrade_data(); void testUpgrade(); - private: +private: }; #endif diff --git a/tests/ut_settings/upgradetesthelper.cpp b/tests/ut_settings/upgradetesthelper.cpp index edf8c47..635d02f 100644 --- a/tests/ut_settings/upgradetesthelper.cpp +++ b/tests/ut_settings/upgradetesthelper.cpp @@ -87,170 +87,175 @@ * @endverbatim */ -QList UpgradeTestHelper::readRecipe(QIODevice *recipe){ - QList testCases; - - while (!recipe->atEnd()){ - const QString line = recipe->readLine().trimmed(); - if (line.startsWith('#') || line.isEmpty()) - continue; - const QStringList splitted = line.split(':'); - Q_ASSERT_X(splitted.count() == 3, Q_FUNC_INFO, - qPrintable(QString("Inalid recipe line '%1'").arg(line))); - testCases.append(TestCase(splitted.at(0), splitted.at(1), splitted.at(2))); - } - - return testCases; +QList UpgradeTestHelper::readRecipe(QIODevice *recipe) +{ + QList testCases; + + while (!recipe->atEnd()) { + const QString line = recipe->readLine().trimmed(); + if (line.startsWith('#') || line.isEmpty()) + continue; + const QStringList splitted = line.split(':'); + Q_ASSERT_X(splitted.count() == 3, Q_FUNC_INFO, + qPrintable(QString("Inalid recipe line '%1'").arg(line))); + testCases.append(TestCase(splitted.at(0), splitted.at(1), splitted.at(2))); + } + + return testCases; } -void UpgradeTestHelper::fillSettings(QSettings *settings, const QList &testCases){ - settings->setValue("configVersion", CurrentVersion); +void UpgradeTestHelper::fillSettings(QSettings *settings, const QList &testCases) +{ + settings->setValue("configVersion", CurrentVersion); - foreach (const QString &group, groups()){ - settings->beginGroup(group); + foreach (const QString &group, groups()) { + settings->beginGroup(group); - foreach (const TestCase &testCase, testCases){ - if (!testCase.current().isEmpty()){ - settings->setValue(testCase.key(), testCase.current()); - } - } + foreach (const TestCase &testCase, testCases) { + if (!testCase.current().isEmpty()) { + settings->setValue(testCase.key(), testCase.current()); + } + } - settings->endGroup(); - } + settings->endGroup(); + } - settings->sync(); + settings->sync(); } void UpgradeTestHelper::fillDefaultSettings(QSettings *defaultSettings, const QList - &testCases){ - defaultSettings->setValue("configVersion", HistoryLength); + &testCases) +{ + defaultSettings->setValue("configVersion", HistoryLength); - QHash lastSetValue; // for the (K)eep action; no need to qualify with group + QHash lastSetValue; // for the (K)eep action; no need to qualify with group - for (int revision = 1; revision <= HistoryLength; ++revision){ - defaultSettings->beginGroup(QString::number(revision)); + for (int revision = 1; revision <= HistoryLength; ++revision) { + defaultSettings->beginGroup(QString::number(revision)); - QStringList keysToRemove; + QStringList keysToRemove; - foreach (const QString &group, groups()){ - defaultSettings->beginGroup(group); + foreach (const QString &group, groups()) { + defaultSettings->beginGroup(group); - foreach (const TestCase &testCase, testCases){ - switch (testCase.history().at(revision - 1).toLatin1()){ - case 'S': // (S)et value - lastSetValue[testCase.key()] = QString("v%1-default").arg(revision); - defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]); - break; + foreach (const TestCase &testCase, testCases) { + switch (testCase.history().at(revision - 1).toLatin1()) { + case 'S': // (S)et value + lastSetValue[testCase.key()] = QString("v%1-default").arg(revision); + defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]); + break; - case 'K': // (K)eep value - Q_ASSERT_X(!lastSetValue[testCase.key()].isEmpty(), Q_FUNC_INFO, - qPrintable(QString("Inalid TestCase::history: '%1'").arg(testCase.history()))); - defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]); - break; + case 'K': // (K)eep value + Q_ASSERT_X(!lastSetValue[testCase.key()].isEmpty(), Q_FUNC_INFO, + qPrintable(QString("Inalid TestCase::history: '%1'").arg(testCase.history()))); + defaultSettings->setValue(testCase.key(), lastSetValue[testCase.key()]); + break; - case 'R': // (R)emove key - keysToRemove.append((group.isEmpty() ? group : group + "/") + testCase.key()); - lastSetValue.remove(testCase.key()); - break; + case 'R': // (R)emove key + keysToRemove.append((group.isEmpty() ? group : group + "/") + testCase.key()); + lastSetValue.remove(testCase.key()); + break; - case 'N': // (N)oop - break; + case 'N': // (N)oop + break; - default: - Q_ASSERT_X(false, Q_FUNC_INFO, qPrintable(QString( - "Inalid TestCase::history: '%1': invalid command-code '%2'") - .arg(testCase.history()) - .arg(testCase.history().at(revision - 1)))); - } + default: + Q_ASSERT_X(false, Q_FUNC_INFO, qPrintable(QString( + "Inalid TestCase::history: '%1': invalid command-code '%2'") + .arg(testCase.history()) + .arg(testCase.history().at(revision - 1)))); + } - } + } - defaultSettings->endGroup(); - } + defaultSettings->endGroup(); + } - if (!keysToRemove.isEmpty()){ - defaultSettings->setValue("cmd-remove", keysToRemove); - } + if (!keysToRemove.isEmpty()) { + defaultSettings->setValue("cmd-remove", keysToRemove); + } - defaultSettings->endGroup(); - } + defaultSettings->endGroup(); + } - defaultSettings->sync(); + defaultSettings->sync(); } -bool UpgradeTestHelper::generateSnapshotRecipe(QTextStream *out){ - const QString actions = "SKRN"; - - QBuffer buf; - buf.open(QIODevice::ReadWrite); - QTextStream stream(&buf); +bool UpgradeTestHelper::generateSnapshotRecipe(QTextStream *out) +{ + const QString actions = "SKRN"; + + QBuffer buf; + buf.open(QIODevice::ReadWrite); + QTextStream stream(&buf); + + // for all "valid" variations of the letters "SKRN" of length HistoryLength + for (int i = 0; i < qPow(actions.count(), HistoryLength); ++i) { + QString history = QString::number(i, actions.count()); + // Left pad to HistoryLength + history.prepend(QString(HistoryLength - history.length(), '0')); + for (int revision = 0; revision < history.length(); ++revision) { + history.replace(revision, 1, actions.at(history.at(revision).digitValue())); + } - // for all "valid" variations of the letters "SKRN" of length HistoryLength - for (int i = 0; i < qPow(actions.count(), HistoryLength); ++i){ - QString history = QString::number(i, actions.count()); - // Left pad to HistoryLength - history.prepend(QString(HistoryLength - history.length(), '0')); - for (int revision = 0; revision < history.length(); ++revision){ - history.replace(revision, 1, actions.at(history.at(revision).digitValue())); - } + static const QRegExp invalidSequence("(^[^S]*K|R[^S]*K|^R)"); + if (history.contains(invalidSequence)) { + continue; + } - static const QRegExp invalidSequence("(^[^S]*K|R[^S]*K|^R)"); - if (history.contains(invalidSequence)){ - continue; - } + for (int revision = 0; revision < HistoryLength; ++revision) { + stream << history << QString(":v%1-default:\n").arg(revision); + } - for (int revision = 0; revision < HistoryLength; ++revision){ - stream << history << QString(":v%1-default:\n").arg(revision); + stream << history << ":custom:\n"; } - stream << history << ":custom:\n"; - } - - stream.flush(); + stream.flush(); - // Read recipe - buf.seek(0); - QList testCases = readRecipe(&buf); + // Read recipe + buf.seek(0); + QList testCases = readRecipe(&buf); - // Generate settings file according to recipe - QTemporaryFile settingsFile; - if (!settingsFile.open()){ - return false; - } + // Generate settings file according to recipe + QTemporaryFile settingsFile; + if (!settingsFile.open()) { + return false; + } - QSettings settings(settingsFile.fileName(), QSettings::IniFormat); + QSettings settings(settingsFile.fileName(), QSettings::IniFormat); - fillSettings(&settings, testCases); + fillSettings(&settings, testCases); - // Generate defaults file according to recipe - QTemporaryFile defaultSettingsFile; - if (!defaultSettingsFile.open()){ - return false; - } + // Generate defaults file according to recipe + QTemporaryFile defaultSettingsFile; + if (!defaultSettingsFile.open()) { + return false; + } - QSettings defaultSettings(defaultSettingsFile.fileName(), QSettings::IniFormat); + QSettings defaultSettings(defaultSettingsFile.fileName(), QSettings::IniFormat); - fillDefaultSettings(&defaultSettings, testCases); + fillDefaultSettings(&defaultSettings, testCases); - // Parse settings -- do upgrade - SsuSettings ssuSettings(settingsFile.fileName(), QSettings::IniFormat, - defaultSettingsFile.fileName()); + // Parse settings -- do upgrade + SsuSettings ssuSettings(settingsFile.fileName(), QSettings::IniFormat, + defaultSettingsFile.fileName()); - // Output recipe - foreach (const UpgradeTestHelper::TestCase &testCase, testCases){ - const QString expected = ssuSettings.contains(testCase.key()) - ? ssuSettings.value(testCase.key()).toString() - : "@NOTSET@"; - *out << QString("%1:%2:%3\n") - .arg(testCase.history()) - .arg(testCase.current()) - .arg(expected); - } + // Output recipe + foreach (const UpgradeTestHelper::TestCase &testCase, testCases) { + const QString expected = ssuSettings.contains(testCase.key()) + ? ssuSettings.value(testCase.key()).toString() + : "@NOTSET@"; + *out << QString("%1:%2:%3\n") + .arg(testCase.history()) + .arg(testCase.current()) + .arg(expected); + } - return true; + return true; } -QStringList UpgradeTestHelper::groups(){ - static const QStringList groups = QStringList() << "" /* General */ << "groupA"; - return groups; +QStringList UpgradeTestHelper::groups() +{ + static const QStringList groups = QStringList() << "" /* General */ << "groupA"; + return groups; } diff --git a/tests/ut_settings/upgradetesthelper.h b/tests/ut_settings/upgradetesthelper.h index 388cc5e..50403ae 100644 --- a/tests/ut_settings/upgradetesthelper.h +++ b/tests/ut_settings/upgradetesthelper.h @@ -15,8 +15,9 @@ class QIODevice; class QSettings; class QTextStream; -class UpgradeTestHelper { - public: +class UpgradeTestHelper +{ +public: enum { HistoryLength = 5, CurrentVersion = 3 }; struct TestCase; @@ -30,25 +31,37 @@ class UpgradeTestHelper { }; struct UpgradeTestHelper::TestCase { - TestCase(const QString &history, const QString ¤t, const QString &expected) : - m_history(history), m_current(current), m_expected(expected){ - } + TestCase(const QString &history, const QString ¤t, const QString &expected) : + m_history(history), m_current(current), m_expected(expected) + { + } - QString history() const { return m_history; } - QString current() const { return m_current; } - QString expected() const { return m_expected; } + QString history() const + { + return m_history; + } + QString current() const + { + return m_current; + } + QString expected() const + { + return m_expected; + } - QString key() const{ - return QString("%1__%2").arg(m_history).arg(m_current); - } + QString key() const + { + return QString("%1__%2").arg(m_history).arg(m_current); + } - bool keyShouldBeSet() const{ - return m_expected != "@NOTSET@"; - } + bool keyShouldBeSet() const + { + return m_expected != "@NOTSET@"; + } - QString m_history; // Sequence of (S)et, (K)eep, (R)emove, (N)oop - QString m_current; - QString m_expected; + QString m_history; // Sequence of (S)et, (K)eep, (R)emove, (N)oop + QString m_current; + QString m_expected; }; #endif diff --git a/tests/ut_ssu/main.cpp b/tests/ut_ssu/main.cpp index 6ffd4a5..41d35bf 100644 --- a/tests/ut_ssu/main.cpp +++ b/tests/ut_ssu/main.cpp @@ -10,17 +10,18 @@ #include "libssu/sandbox_p.h" #include "ssutest.h" -int main(int argc, char **argv){ - Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess); - if (!sandbox.activate()){ - qFatal("Failed to activate sandbox"); - } +int main(int argc, char **argv) +{ + Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess); + if (!sandbox.activate()) { + qFatal("Failed to activate sandbox"); + } - SsuTest ssuTest; + SsuTest ssuTest; - if (QTest::qExec(&ssuTest, argc, argv)) - return 1; + if (QTest::qExec(&ssuTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_ssu/ssutest.cpp b/tests/ut_ssu/ssutest.cpp index 965122e..6b392e8 100644 --- a/tests/ut_ssu/ssutest.cpp +++ b/tests/ut_ssu/ssutest.cpp @@ -14,54 +14,58 @@ #include "libssu/ssurepomanager.h" #include "libssu/ssu.h" -void SsuTest::initTestCase(){ +void SsuTest::initTestCase() +{ } -void SsuTest::testCredentialsScope(){ - // For store repo store is returned always no matter what - QCOMPARE(ssu.credentialsScope(QString("store")),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("store-c-example")),QString("store")); +void SsuTest::testCredentialsScope() +{ + // For store repo store is returned always no matter what + QCOMPARE(ssu.credentialsScope(QString("store")), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("store-c-example")), QString("store")); - ssu.setDomain(QString("default")); - QCOMPARE(ssu.domain(),QString("default")); + ssu.setDomain(QString("default")); + QCOMPARE(ssu.domain(), QString("default")); - QCOMPARE(ssu.credentialsScope(QString("store")),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("apps")),QString("vendor")); - QCOMPARE(ssu.credentialsScope(QString("vendor")),QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("store")), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("apps")), QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("vendor")), QString("vendor")); - QCOMPARE(ssu.credentialsScope(QString("store"),true),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("adaptation"),true),QString("vendor")); - QCOMPARE(ssu.credentialsScope(QString("oss"),true),QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("store"), true), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("adaptation"), true), QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("oss"), true), QString("vendor")); } -void SsuTest::testCredentialsScopeStoreAuthRepos() { - ssu.setDomain(QString("example")); - QCOMPARE(ssu.domain(),QString("example")); +void SsuTest::testCredentialsScopeStoreAuthRepos() +{ + ssu.setDomain(QString("example")); + QCOMPARE(ssu.domain(), QString("example")); - QCOMPARE(ssu.credentialsScope(QString("store")),QString("store")); - // store-auth-repos=apps in example domain - QCOMPARE(ssu.credentialsScope(QString("apps")),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("vendor")),QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("store")), QString("store")); + // store-auth-repos=apps in example domain + QCOMPARE(ssu.credentialsScope(QString("apps")), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("vendor")), QString("vendor")); - QCOMPARE(ssu.credentialsScope(QString("store"),true),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("adaptation"),true),QString("vendor")); - QCOMPARE(ssu.credentialsScope(QString("oss"),true),QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("store"), true), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("adaptation"), true), QString("vendor")); + QCOMPARE(ssu.credentialsScope(QString("oss"), true), QString("vendor")); } -void SsuTest::testCredentialsScopeSecureDomainAuth(){ - // [secure-domain-auth] - // packages.example2.com=example2 +void SsuTest::testCredentialsScopeSecureDomainAuth() +{ + // [secure-domain-auth] + // packages.example2.com=example2 - ssu.setDomain("example2"); - QCOMPARE(ssu.domain(),QString("example2")); + ssu.setDomain("example2"); + QCOMPARE(ssu.domain(), QString("example2")); - QCOMPARE(ssu.credentialsScope(QString("store"),false),QString("store")); - QCOMPARE(ssu.credentialsScope(QString("apps"),false),QString("example2")); - QCOMPARE(ssu.credentialsScope(QString("vendor"),false),QString("example2")); + QCOMPARE(ssu.credentialsScope(QString("store"), false), QString("store")); + QCOMPARE(ssu.credentialsScope(QString("apps"), false), QString("example2")); + QCOMPARE(ssu.credentialsScope(QString("vendor"), false), QString("example2")); - // adaptation uses packages.example2.com - QCOMPARE(ssu.credentialsScope(QString("adaptation"),true),QString("example2")); - // oss uses dump.example2.com, thus vendor - QCOMPARE(ssu.credentialsScope(QString("oss"),true),QString("vendor")); + // adaptation uses packages.example2.com + QCOMPARE(ssu.credentialsScope(QString("adaptation"), true), QString("example2")); + // oss uses dump.example2.com, thus vendor + QCOMPARE(ssu.credentialsScope(QString("oss"), true), QString("vendor")); } diff --git a/tests/ut_ssu/ssutest.h b/tests/ut_ssu/ssutest.h index 6ed0ff5..c52e078 100644 --- a/tests/ut_ssu/ssutest.h +++ b/tests/ut_ssu/ssutest.h @@ -13,15 +13,16 @@ #include "libssu/ssu.h" -class SsuTest: public QObject { +class SsuTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void testCredentialsScope(); void testCredentialsScopeStoreAuthRepos(); - void testCredentialsScopeSecureDomainAuth(); - private: + void testCredentialsScopeSecureDomainAuth(); +private: Ssu ssu; }; diff --git a/tests/ut_ssucli/main.cpp b/tests/ut_ssucli/main.cpp index 1e8e468..a40461b 100644 --- a/tests/ut_ssucli/main.cpp +++ b/tests/ut_ssucli/main.cpp @@ -9,11 +9,12 @@ #include "ssuclitest.h" -int main(int argc, char **argv){ - SsuCliTest ssuCliTest; +int main(int argc, char **argv) +{ + SsuCliTest ssuCliTest; - if (QTest::qExec(&ssuCliTest, argc, argv)) - return 1; + if (QTest::qExec(&ssuCliTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_ssucli/ssuclitest.cpp b/tests/ut_ssucli/ssuclitest.cpp index 4544cd8..e872867 100644 --- a/tests/ut_ssucli/ssuclitest.cpp +++ b/tests/ut_ssucli/ssuclitest.cpp @@ -17,151 +17,156 @@ typedef QStringList Args; // improve readability -void SsuCliTest::init(){ - Q_ASSERT(m_sandbox == 0); - - m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ChildProcesses); - if (!m_sandbox->activate()){ - QFAIL("Failed to activate sandbox"); - } - if (getenv("SSU_SANDBOX_PATH")){ - qDebug() << "Using in-tree sandbox"; - setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1); - } else - setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1); - - m_bus = new QProcess(this); - m_bus->start("dbus-daemon", - Args() << "--session" << "--nofork" << "--nopidfile" << "--print-address"); - if (!m_bus->waitForReadyRead()){ - QFAIL("Failed to run sandboxed D-Bus instance"); - } - const QByteArray busAddress = m_bus->readAllStandardOutput(); - setenv("DBUS_SESSION_BUS_ADDRESS", busAddress.constData(), 1); - setenv("DBUS_SYSTEM_BUS_ADDRESS", busAddress.constData(), 1); - - m_ssud = new QProcess(this); - m_ssud->start("ssud"); - if (!m_ssud->waitForStarted()){ - QFAIL("Failed to run sandboxed ssud instance"); - } +void SsuCliTest::init() +{ + Q_ASSERT(m_sandbox == 0); + + m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ChildProcesses); + if (!m_sandbox->activate()) { + QFAIL("Failed to activate sandbox"); + } + if (getenv("SSU_SANDBOX_PATH")) { + qDebug() << "Using in-tree sandbox"; + setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1); + } else + setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1); + + m_bus = new QProcess(this); + m_bus->start("dbus-daemon", + Args() << "--session" << "--nofork" << "--nopidfile" << "--print-address"); + if (!m_bus->waitForReadyRead()) { + QFAIL("Failed to run sandboxed D-Bus instance"); + } + const QByteArray busAddress = m_bus->readAllStandardOutput(); + setenv("DBUS_SESSION_BUS_ADDRESS", busAddress.constData(), 1); + setenv("DBUS_SYSTEM_BUS_ADDRESS", busAddress.constData(), 1); + + m_ssud = new QProcess(this); + m_ssud->start("ssud"); + if (!m_ssud->waitForStarted()) { + QFAIL("Failed to run sandboxed ssud instance"); + } } -void SsuCliTest::cleanup(){ - if (m_ssud->state() != QProcess::Running){ - QFAIL("Sandboxed ssud instance exited unexpectedly"); - } - delete m_ssud; - m_ssud = 0; - - if (m_bus->state() != QProcess::Running){ - QFAIL("Sandboxed D-Bus instance exited unexpectedly"); - } - unsetenv("DBUS_SESSION_BUS_ADDRESS"); - unsetenv("DBUS_SYSTEM_BUS_ADDRESS"); - delete m_bus; - m_bus = 0; - - delete m_sandbox; - m_sandbox = 0; +void SsuCliTest::cleanup() +{ + if (m_ssud->state() != QProcess::Running) { + QFAIL("Sandboxed ssud instance exited unexpectedly"); + } + delete m_ssud; + m_ssud = 0; + + if (m_bus->state() != QProcess::Running) { + QFAIL("Sandboxed D-Bus instance exited unexpectedly"); + } + unsetenv("DBUS_SESSION_BUS_ADDRESS"); + unsetenv("DBUS_SYSTEM_BUS_ADDRESS"); + delete m_bus; + m_bus = 0; + + delete m_sandbox; + m_sandbox = 0; } -void SsuCliTest::testSubcommandFlavour(){ - Process ssu; - QString output; +void SsuCliTest::testSubcommandFlavour() +{ + Process ssu; + QString output; - // set flavour to 'release' - ssu.execute("ssu", Args() << "flavour" << "release"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set flavour to 'release' + ssu.execute("ssu", Args() << "flavour" << "release"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "flavour").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "flavour").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device flavour is currently: release")); + QCOMPARE(output, QString("Device flavour is currently: release")); - // set flavour to 'testing' - ssu.execute("ssu", Args() << "flavour" << "testing"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set flavour to 'testing' + ssu.execute("ssu", Args() << "flavour" << "testing"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "flavour").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "flavour").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device flavour is currently: testing")); + QCOMPARE(output, QString("Device flavour is currently: testing")); } -void SsuCliTest::testSubcommandRelease(){ - Process ssu; - QString output; +void SsuCliTest::testSubcommandRelease() +{ + Process ssu; + QString output; - // set release to latest - ssu.execute("ssu", Args() << "release" << "latest"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set release to latest + ssu.execute("ssu", Args() << "release" << "latest"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "release").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "release").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device release is currently: latest")); + QCOMPARE(output, QString("Device release is currently: latest")); - // set release to next - ssu.execute("ssu", Args() << "release" << "next"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set release to next + ssu.execute("ssu", Args() << "release" << "next"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "release").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "release").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device release is currently: next")); + QCOMPARE(output, QString("Device release is currently: next")); - // verify the mode is release - output = ssu.execute("ssu", Args() << "mode").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // verify the mode is release + output = ssu.execute("ssu", Args() << "mode").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device mode is: 0 ()")); + QCOMPARE(output, QString("Device mode is: 0 ()")); - // set RnD release to latest - ssu.execute("ssu", Args() << "release" << "-r" << "latest"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set RnD release to latest + ssu.execute("ssu", Args() << "release" << "-r" << "latest"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "release" << "-r").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "release" << "-r").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device release (RnD) is currently: latest")); + QCOMPARE(output, QString("Device release (RnD) is currently: latest")); - // set RnD release to next - ssu.execute("ssu", Args() << "release" << "-r" << "next"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set RnD release to next + ssu.execute("ssu", Args() << "release" << "-r" << "next"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "release" << "-r").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "release" << "-r").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device release (RnD) is currently: next")); + QCOMPARE(output, QString("Device release (RnD) is currently: next")); - // verify the mode is RnD - output = ssu.execute("ssu", Args() << "mode").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // verify the mode is RnD + output = ssu.execute("ssu", Args() << "mode").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device mode is: 2 (RndMode)")); + QCOMPARE(output, QString("Device mode is: 2 (RndMode)")); } -void SsuCliTest::testSubcommandMode(){ - Process ssu; - QString output; +void SsuCliTest::testSubcommandMode() +{ + Process ssu; + QString output; - // set release mode - ssu.execute("ssu", Args() << "mode" << "0"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set release mode + ssu.execute("ssu", Args() << "mode" << "0"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "mode").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "mode").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device mode is: 0 ()")); + QCOMPARE(output, QString("Device mode is: 0 ()")); - // set RnD mode - ssu.execute("ssu", Args() << "mode" << "2"); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + // set RnD mode + ssu.execute("ssu", Args() << "mode" << "2"); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - output = ssu.execute("ssu", Args() << "mode").trimmed(); - QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); + output = ssu.execute("ssu", Args() << "mode").trimmed(); + QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage())); - QCOMPARE(output, QString("Device mode is: 2 (RndMode)")); + QCOMPARE(output, QString("Device mode is: 2 (RndMode)")); } diff --git a/tests/ut_ssucli/ssuclitest.h b/tests/ut_ssucli/ssuclitest.h index 5dec911..1f8e62b 100644 --- a/tests/ut_ssucli/ssuclitest.h +++ b/tests/ut_ssucli/ssuclitest.h @@ -14,13 +14,14 @@ class QProcess; class Sandbox; -class SsuCliTest: public QObject { +class SsuCliTest: public QObject +{ Q_OBJECT - public: +public: SsuCliTest(): m_sandbox(0) {} - private slots: +private slots: void init(); void cleanup(); @@ -28,7 +29,7 @@ class SsuCliTest: public QObject { void testSubcommandRelease(); void testSubcommandMode(); - private: +private: Sandbox *m_sandbox; QProcess *m_bus; QProcess *m_ssud; diff --git a/tests/ut_ssuurlresolver/main.cpp b/tests/ut_ssuurlresolver/main.cpp index 7eee5a1..6c416ae 100644 --- a/tests/ut_ssuurlresolver/main.cpp +++ b/tests/ut_ssuurlresolver/main.cpp @@ -9,11 +9,12 @@ #include "ssuurlresolvertest.h" -int main(int argc, char **argv){ - SsuUrlResolverTest ssuUrlResolverTest; +int main(int argc, char **argv) +{ + SsuUrlResolverTest ssuUrlResolverTest; - if (QTest::qExec(&ssuUrlResolverTest, argc, argv)) - return 1; + if (QTest::qExec(&ssuUrlResolverTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_ssuurlresolver/ssuurlresolvertest.cpp b/tests/ut_ssuurlresolver/ssuurlresolvertest.cpp index 369b542..e0e86fc 100644 --- a/tests/ut_ssuurlresolver/ssuurlresolvertest.cpp +++ b/tests/ut_ssuurlresolver/ssuurlresolvertest.cpp @@ -21,40 +21,44 @@ * This test verifies the UrlResolverPlugin works well with installed version of libzypp. */ -void SsuUrlResolverTest::initTestCase(){ - m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseDirectly, Sandbox::ChildProcesses); - if (!m_sandbox->activate()){ - QFAIL("Failed to activate sandbox"); - } - if (getenv("SSU_SANDBOX_PATH")){ - qDebug() << "Using in-tree sandbox"; - setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1); - } else - setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1); +void SsuUrlResolverTest::initTestCase() +{ + m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseDirectly, Sandbox::ChildProcesses); + if (!m_sandbox->activate()) { + QFAIL("Failed to activate sandbox"); + } + if (getenv("SSU_SANDBOX_PATH")) { + qDebug() << "Using in-tree sandbox"; + setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1); + } else + setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1); } -void SsuUrlResolverTest::cleanupTestCase(){ - delete m_sandbox; - m_sandbox = 0; +void SsuUrlResolverTest::cleanupTestCase() +{ + delete m_sandbox; + m_sandbox = 0; } -void SsuUrlResolverTest::test_data(){ - QTest::addColumn("input"); - QTest::addColumn("expected"); +void SsuUrlResolverTest::test_data() +{ + QTest::addColumn("input"); + QTest::addColumn("expected"); - QTest::newRow("basic") - << "plugin:ssu?repo=mer-core&debug&arch=i586" - << "https://packages.testing.com//mer/i586/debug/"; + QTest::newRow("basic") + << "plugin:ssu?repo=mer-core&debug&arch=i586" + << "https://packages.testing.com//mer/i586/debug/"; } -void SsuUrlResolverTest::test(){ - QFETCH(QString, input); - QFETCH(QString, expected); +void SsuUrlResolverTest::test() +{ + QFETCH(QString, input); + QFETCH(QString, expected); - zypp::media::UrlResolverPlugin::HeaderList customHeaders; - const QString resolved = QString::fromStdString( - zypp::media::UrlResolverPlugin::resolveUrl(input.toStdString(), customHeaders).asString()); + zypp::media::UrlResolverPlugin::HeaderList customHeaders; + const QString resolved = QString::fromStdString( + zypp::media::UrlResolverPlugin::resolveUrl(input.toStdString(), customHeaders).asString()); - QCOMPARE(resolved, expected); + QCOMPARE(resolved, expected); } diff --git a/tests/ut_ssuurlresolver/ssuurlresolvertest.h b/tests/ut_ssuurlresolver/ssuurlresolvertest.h index e244301..4815b19 100644 --- a/tests/ut_ssuurlresolver/ssuurlresolvertest.h +++ b/tests/ut_ssuurlresolver/ssuurlresolvertest.h @@ -12,19 +12,20 @@ class Sandbox; -class SsuUrlResolverTest: public QObject { +class SsuUrlResolverTest: public QObject +{ Q_OBJECT - public: +public: SsuUrlResolverTest(): m_sandbox(0) {} - private slots: +private slots: void initTestCase(); void cleanupTestCase(); void test_data(); void test(); - private: +private: Sandbox *m_sandbox; }; diff --git a/tests/ut_urlresolver/main.cpp b/tests/ut_urlresolver/main.cpp index 147d8f4..a2d44ef 100644 --- a/tests/ut_urlresolver/main.cpp +++ b/tests/ut_urlresolver/main.cpp @@ -10,17 +10,18 @@ #include "libssu/sandbox_p.h" #include "urlresolvertest.cpp" -int main(int argc, char **argv){ - Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), - Sandbox::UseAsSkeleton, Sandbox::ThisProcess); - if (!sandbox.activate()){ - qFatal("Failed to activate sandbox"); - } +int main(int argc, char **argv) +{ + Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH), + Sandbox::UseAsSkeleton, Sandbox::ThisProcess); + if (!sandbox.activate()) { + qFatal("Failed to activate sandbox"); + } - UrlResolverTest urlResolverTest; + UrlResolverTest urlResolverTest; - if (QTest::qExec(&urlResolverTest, argc, argv)) - return 1; + if (QTest::qExec(&urlResolverTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_urlresolver/urlresolvertest.cpp b/tests/ut_urlresolver/urlresolvertest.cpp index 850741e..e615853 100644 --- a/tests/ut_urlresolver/urlresolvertest.cpp +++ b/tests/ut_urlresolver/urlresolvertest.cpp @@ -13,272 +13,284 @@ #include "libssu/sandbox_p.h" #include "testutils/process.h" -void UrlResolverTest::initTestCase(){ - // test will fail if executed without proper installation of libssu and repos - QString arch = ""; +void UrlResolverTest::initTestCase() +{ + // test will fail if executed without proper installation of libssu and repos + QString arch = ""; #ifdef TARGET_ARCH - arch = TARGET_ARCH; + arch = TARGET_ARCH; #else #warning "TARGET_ARCH not defined" #warning "In-tree tests will fail without using run-tests script" #endif - rndRepos["nemo"] = QString("https://packages.example.com/nemo/latest/platform/%1/").arg(arch); - rndRepos["mer-core"] = QString("https://packages.example.com/mer/latest/builds/%1/packages/").arg(arch); -/* - rndRepos["non-oss"] = ""; -*/ - releaseRepos["nemo"] = QString("https://packages.example.com/releases/0.1/nemo/platform/%1/").arg(arch); - releaseRepos["mer-core"] = QString("https://packages.example.com/0.1/mer/%1/packages/").arg(arch); - releaseRepos["jolla"] = QString("https://packages.example.com/releases/0.1/jolla/%1/").arg(arch); + rndRepos["nemo"] = QString("https://packages.example.com/nemo/latest/platform/%1/").arg(arch); + rndRepos["mer-core"] = QString("https://packages.example.com/mer/latest/builds/%1/packages/").arg(arch); + /* + rndRepos["non-oss"] = ""; + */ + releaseRepos["nemo"] = QString("https://packages.example.com/releases/0.1/nemo/platform/%1/").arg(arch); + releaseRepos["mer-core"] = QString("https://packages.example.com/0.1/mer/%1/packages/").arg(arch); + releaseRepos["jolla"] = QString("https://packages.example.com/releases/0.1/jolla/%1/").arg(arch); } -void UrlResolverTest::cleanupTestCase(){ +void UrlResolverTest::cleanupTestCase() +{ } -void UrlResolverTest::checkFlavour(){ - ssu.setFlavour("testing"); - QCOMPARE(ssu.flavour(), QString("testing")); - ssu.setFlavour("release"); - QCOMPARE(ssu.flavour(), QString("release")); - Ssu ssu2; - QCOMPARE(ssu2.flavour(), QString("release")); +void UrlResolverTest::checkFlavour() +{ + ssu.setFlavour("testing"); + QCOMPARE(ssu.flavour(), QString("testing")); + ssu.setFlavour("release"); + QCOMPARE(ssu.flavour(), QString("release")); + Ssu ssu2; + QCOMPARE(ssu2.flavour(), QString("release")); } -void UrlResolverTest::checkRelease(){ - ssu.setRelease("0.1"); - QCOMPARE(ssu.release(), QString("0.1")); - ssu.setRelease("0.2", true); - QCOMPARE(ssu.release(), QString("0.1")); - QCOMPARE(ssu.release(true), QString("0.2")); - Ssu ssu2; - QCOMPARE(ssu2.release(), QString("0.1")); - QCOMPARE(ssu2.release(true), QString("0.2")); - ssu.setRelease("latest", true); +void UrlResolverTest::checkRelease() +{ + ssu.setRelease("0.1"); + QCOMPARE(ssu.release(), QString("0.1")); + ssu.setRelease("0.2", true); + QCOMPARE(ssu.release(), QString("0.1")); + QCOMPARE(ssu.release(true), QString("0.2")); + Ssu ssu2; + QCOMPARE(ssu2.release(), QString("0.1")); + QCOMPARE(ssu2.release(true), QString("0.2")); + ssu.setRelease("latest", true); } -void UrlResolverTest::checkDomain(){ - QString credentialsUrl; - QString registerUrl; +void UrlResolverTest::checkDomain() +{ + QString credentialsUrl; + QString registerUrl; - // domain not defined -> default - ssu.setDomain(""); - credentialsUrl = ssu.repoUrl("credentials-url"); - QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml")); + // domain not defined -> default + ssu.setDomain(""); + credentialsUrl = ssu.repoUrl("credentials-url"); + QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml")); - // domain defined but not matching block -> default - ssu.setDomain("nevermind"); - credentialsUrl = ssu.repoUrl("credentials-url"); - QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml")); + // domain defined but not matching block -> default + ssu.setDomain("nevermind"); + credentialsUrl = ssu.repoUrl("credentials-url"); + QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml")); - ssu.setDomain("example"); - QCOMPARE(ssu.domain(), QString("example")); - credentialsUrl = ssu.repoUrl("credentials-url"); - QCOMPARE(credentialsUrl, QString("https://ssu.example.com/ssu/device/%1/credentials.xml")); - registerUrl = ssu.repoUrl("register-url"); - QCOMPARE(registerUrl, QString("https://ssu.example.com/ssu/device/%1/register.xml")); + ssu.setDomain("example"); + QCOMPARE(ssu.domain(), QString("example")); + credentialsUrl = ssu.repoUrl("credentials-url"); + QCOMPARE(credentialsUrl, QString("https://ssu.example.com/ssu/device/%1/credentials.xml")); + registerUrl = ssu.repoUrl("register-url"); + QCOMPARE(registerUrl, QString("https://ssu.example.com/ssu/device/%1/register.xml")); } -void UrlResolverTest::checkCleanUrl(){ - QHashIterator i(rndRepos); - while (i.hasNext()){ - i.next(); - QString url=ssu.repoUrl(i.key(), true); - QVERIFY(!url.contains("%(")); - } +void UrlResolverTest::checkCleanUrl() +{ + QHashIterator i(rndRepos); + while (i.hasNext()) { + i.next(); + QString url = ssu.repoUrl(i.key(), true); + QVERIFY(!url.contains("%(")); + } } -void UrlResolverTest::simpleRepoUrlLookup(){ - QHashIterator i(rndRepos); - while (i.hasNext()){ - QString url; - i.next(); - url=ssu.repoUrl(i.key(), true); - QCOMPARE(url, i.value()); - url=ssu.repoUrl(i.key(), false); - QVERIFY(url.compare(i.value()) != 0); - } -/* - QCOMPARE(ssu.repoUrl("jolla", 0), QString("")); - QCOMPARE(ssu.repoUrl("non-oss", 1), QString("")); -*/ +void UrlResolverTest::simpleRepoUrlLookup() +{ + QHashIterator i(rndRepos); + while (i.hasNext()) { + QString url; + i.next(); + url = ssu.repoUrl(i.key(), true); + QCOMPARE(url, i.value()); + url = ssu.repoUrl(i.key(), false); + QVERIFY(url.compare(i.value()) != 0); + } + /* + QCOMPARE(ssu.repoUrl("jolla", 0), QString("")); + QCOMPARE(ssu.repoUrl("non-oss", 1), QString("")); + */ } -void UrlResolverTest::checkReleaseRepoUrls(){ - QHashIterator i(releaseRepos); - while (i.hasNext()){ - QString url; - i.next(); - url=ssu.repoUrl(i.key(), false); - QCOMPARE(url, i.value()); - url=ssu.repoUrl(i.key()); - QCOMPARE(url, i.value()); - } +void UrlResolverTest::checkReleaseRepoUrls() +{ + QHashIterator i(releaseRepos); + while (i.hasNext()) { + QString url; + i.next(); + url = ssu.repoUrl(i.key(), false); + QCOMPARE(url, i.value()); + url = ssu.repoUrl(i.key()); + QCOMPARE(url, i.value()); + } } -void UrlResolverTest::checkRegisterDevice(){ - QDomDocument doc("foo"); +void UrlResolverTest::checkRegisterDevice() +{ + QDomDocument doc("foo"); - QDomElement root = doc.createElement("foo"); - doc.appendChild(root); + QDomElement root = doc.createElement("foo"); + doc.appendChild(root); - QDomElement certificate = doc.createElement("certificate"); - root.appendChild(certificate); + QDomElement certificate = doc.createElement("certificate"); + root.appendChild(certificate); - QVERIFY2(!ssu.registerDevice(&doc), - "Ssu::registerDevice() should fail when 'certificate' is empty"); + QVERIFY2(!ssu.registerDevice(&doc), + "Ssu::registerDevice() should fail when 'certificate' is empty"); - QFile certificateFile(QString("%1/mycert.crt").arg(LOCATE_DATA_PATH)); - QVERIFY(certificateFile.open(QIODevice::ReadOnly)); + QFile certificateFile(QString("%1/mycert.crt").arg(LOCATE_DATA_PATH)); + QVERIFY(certificateFile.open(QIODevice::ReadOnly)); - certificate.appendChild(doc.createTextNode(certificateFile.readAll())); + certificate.appendChild(doc.createTextNode(certificateFile.readAll())); - QDomElement privateKey = doc.createElement("privateKey"); - root.appendChild(privateKey); + QDomElement privateKey = doc.createElement("privateKey"); + root.appendChild(privateKey); - QVERIFY2(!ssu.registerDevice(&doc), - "Ssu::registerDevice() should fail when 'privateKey' is empty"); + QVERIFY2(!ssu.registerDevice(&doc), + "Ssu::registerDevice() should fail when 'privateKey' is empty"); - QFile privateKeyFile(QString("%1/mykey.key").arg(LOCATE_DATA_PATH)); - QVERIFY(privateKeyFile.open(QIODevice::ReadOnly)); + QFile privateKeyFile(QString("%1/mykey.key").arg(LOCATE_DATA_PATH)); + QVERIFY(privateKeyFile.open(QIODevice::ReadOnly)); - privateKey.appendChild(doc.createTextNode(privateKeyFile.readAll())); + privateKey.appendChild(doc.createTextNode(privateKeyFile.readAll())); - QDomElement user = doc.createElement("user"); - root.appendChild(user); - user.appendChild(doc.createTextNode("john.doe")); + QDomElement user = doc.createElement("user"); + root.appendChild(user); + user.appendChild(doc.createTextNode("john.doe")); - QSignalSpy registrationStatusChanged_spy(&ssu, SIGNAL(registrationStatusChanged())); + QSignalSpy registrationStatusChanged_spy(&ssu, SIGNAL(registrationStatusChanged())); - QVERIFY(ssu.registerDevice(&doc)); + QVERIFY(ssu.registerDevice(&doc)); - QVERIFY(registrationStatusChanged_spy.count() == 1); - QVERIFY(ssu.isRegistered()); + QVERIFY(registrationStatusChanged_spy.count() == 1); + QVERIFY(ssu.isRegistered()); - ssu.unregister(); + ssu.unregister(); - QVERIFY(registrationStatusChanged_spy.count() == 2); - QVERIFY(!ssu.isRegistered()); + QVERIFY(registrationStatusChanged_spy.count() == 2); + QVERIFY(!ssu.isRegistered()); } -void UrlResolverTest::checkSetCredentials(){ - QDomDocument doc("foo"); +void UrlResolverTest::checkSetCredentials() +{ + QDomDocument doc("foo"); - QDomElement root = doc.createElement("foo"); - doc.appendChild(root); + QDomElement root = doc.createElement("foo"); + doc.appendChild(root); - QDomElement credentials1 = doc.createElement("credentials"); - root.appendChild(credentials1); + QDomElement credentials1 = doc.createElement("credentials"); + root.appendChild(credentials1); - QVERIFY2(!ssu.setCredentials(&doc), - "Ssu::setCredentials() should fail when 'scope' is not defined"); + QVERIFY2(!ssu.setCredentials(&doc), + "Ssu::setCredentials() should fail when 'scope' is not defined"); - credentials1.setAttribute("scope", "utscope1"); + credentials1.setAttribute("scope", "utscope1"); - QVERIFY2(!ssu.setCredentials(&doc), - "Ssu::setCredentials() should fail when username/password is missing"); + QVERIFY2(!ssu.setCredentials(&doc), + "Ssu::setCredentials() should fail when username/password is missing"); - QDomElement username1 = doc.createElement("username"); - credentials1.appendChild(username1); - username1.appendChild(doc.createTextNode("john.doe1")); + QDomElement username1 = doc.createElement("username"); + credentials1.appendChild(username1); + username1.appendChild(doc.createTextNode("john.doe1")); - QVERIFY2(!ssu.setCredentials(&doc), - "Ssu::setCredentials() should fail when password is missing"); + QVERIFY2(!ssu.setCredentials(&doc), + "Ssu::setCredentials() should fail when password is missing"); - QDomElement password1 = doc.createElement("password"); - credentials1.appendChild(password1); - password1.appendChild(doc.createTextNode("SeCrEt1")); + QDomElement password1 = doc.createElement("password"); + credentials1.appendChild(password1); + password1.appendChild(doc.createTextNode("SeCrEt1")); - QVERIFY2(ssu.setCredentials(&doc), - qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError()))); + QVERIFY2(ssu.setCredentials(&doc), + qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError()))); - QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) && - ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(), - "Ssu::lastCredentialsUpdate was not updated"); + QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) && + ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(), + "Ssu::lastCredentialsUpdate was not updated"); - //QVERIFY(ssu.credentialScopes().contains("utscope1")); - QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1")); - QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1")); + //QVERIFY(ssu.credentialScopes().contains("utscope1")); + QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1")); + QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1")); - QDomElement credentials2 = doc.createElement("credentials"); - root.appendChild(credentials2); - credentials2.setAttribute("scope", "utscope2"); + QDomElement credentials2 = doc.createElement("credentials"); + root.appendChild(credentials2); + credentials2.setAttribute("scope", "utscope2"); - QDomElement username2 = doc.createElement("username"); - credentials2.appendChild(username2); - username2.appendChild(doc.createTextNode("john.doe2")); + QDomElement username2 = doc.createElement("username"); + credentials2.appendChild(username2); + username2.appendChild(doc.createTextNode("john.doe2")); - QDomElement password2 = doc.createElement("password"); - credentials2.appendChild(password2); - password2.appendChild(doc.createTextNode("SeCrEt2")); + QDomElement password2 = doc.createElement("password"); + credentials2.appendChild(password2); + password2.appendChild(doc.createTextNode("SeCrEt2")); - QVERIFY2(ssu.setCredentials(&doc), - qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError()))); + QVERIFY2(ssu.setCredentials(&doc), + qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError()))); - QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) && - ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(), - "Ssu::lastCredentialsUpdate was not updated"); + QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) && + ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(), + "Ssu::lastCredentialsUpdate was not updated"); - //QVERIFY(ssu.credentialScopes().contains("utscope1")); - QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1")); - QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1")); + //QVERIFY(ssu.credentialScopes().contains("utscope1")); + QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1")); + QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1")); - //QVERIFY(ssu.credentialScopes().contains("utscope2")); - QCOMPARE(ssu.credentials("utscope2").first, QString("john.doe2")); - QCOMPARE(ssu.credentials("utscope2").second, QString("SeCrEt2")); + //QVERIFY(ssu.credentialScopes().contains("utscope2")); + QCOMPARE(ssu.credentials("utscope2").first, QString("john.doe2")); + QCOMPARE(ssu.credentials("utscope2").second, QString("SeCrEt2")); } -void UrlResolverTest::checkStoreAuthorizedKeys(){ - QVERIFY(QDir().mkpath(Sandbox::map(QDir::homePath()))); +void UrlResolverTest::checkStoreAuthorizedKeys() +{ + QVERIFY(QDir().mkpath(Sandbox::map(QDir::homePath()))); - QByteArray testData("# test data\n"); - ssu.storeAuthorizedKeys(testData); + QByteArray testData("# test data\n"); + ssu.storeAuthorizedKeys(testData); - QFile authorizedKeys(Sandbox::map(QDir::home().filePath(".ssh/authorized_keys"))); - QVERIFY(authorizedKeys.open(QIODevice::ReadOnly)); + QFile authorizedKeys(Sandbox::map(QDir::home().filePath(".ssh/authorized_keys"))); + QVERIFY(authorizedKeys.open(QIODevice::ReadOnly)); - QVERIFY(authorizedKeys.readAll().split('\n').contains(testData.trimmed())); + QVERIFY(authorizedKeys.readAll().split('\n').contains(testData.trimmed())); - QByteArray testData2("# test data2\n"); - ssu.storeAuthorizedKeys(testData2); + QByteArray testData2("# test data2\n"); + ssu.storeAuthorizedKeys(testData2); - QEXPECT_FAIL("", "Ssu::storeAuthorizedKeys() does not modify existing authorized_keys", Continue); - authorizedKeys.seek(0); - QVERIFY(authorizedKeys.readAll().split('\n').contains(testData2.trimmed())); + QEXPECT_FAIL("", "Ssu::storeAuthorizedKeys() does not modify existing authorized_keys", Continue); + authorizedKeys.seek(0); + QVERIFY(authorizedKeys.readAll().split('\n').contains(testData2.trimmed())); - const QFile::Permissions go_rwx = - QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | - QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; - QVERIFY((QFileInfo(Sandbox::map(QDir::home().filePath(".ssh"))).permissions() & go_rwx) == 0); + const QFile::Permissions go_rwx = + QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | + QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; + QVERIFY((QFileInfo(Sandbox::map(QDir::home().filePath(".ssh"))).permissions() & go_rwx) == 0); } -void UrlResolverTest::checkVerifyResponse(){ - QDomDocument doc("foo"); +void UrlResolverTest::checkVerifyResponse() +{ + QDomDocument doc("foo"); - QDomElement root = doc.createElement("foo"); - doc.appendChild(root); + QDomElement root = doc.createElement("foo"); + doc.appendChild(root); - QDomElement action = doc.createElement("action"); - root.appendChild(action); - action.appendChild(doc.createTextNode("register")); + QDomElement action = doc.createElement("action"); + root.appendChild(action); + action.appendChild(doc.createTextNode("register")); - QDomElement deviceId = doc.createElement("deviceId"); - root.appendChild(deviceId); - deviceId.appendChild(doc.createTextNode("deadbeef-dead-beef-dead")); + QDomElement deviceId = doc.createElement("deviceId"); + root.appendChild(deviceId); + deviceId.appendChild(doc.createTextNode("deadbeef-dead-beef-dead")); - QDomElement protocolVersion = doc.createElement("protocolVersion"); - root.appendChild(protocolVersion); + QDomElement protocolVersion = doc.createElement("protocolVersion"); + root.appendChild(protocolVersion); - QDomText protocolVersionText = doc.createTextNode(SSU_PROTOCOL_VERSION); - protocolVersion.appendChild(protocolVersionText); + QDomText protocolVersionText = doc.createTextNode(SSU_PROTOCOL_VERSION); + protocolVersion.appendChild(protocolVersionText); - QVERIFY(ssu.verifyResponse(&doc)); + QVERIFY(ssu.verifyResponse(&doc)); - protocolVersionText.setData(SSU_PROTOCOL_VERSION ".invalid"); + protocolVersionText.setData(SSU_PROTOCOL_VERSION ".invalid"); - QVERIFY2(!ssu.verifyResponse(&doc), - "Ssu::verifyResponse() should fail when protocolVersion does not match SSU_PROTOCOL_VERSION"); + QVERIFY2(!ssu.verifyResponse(&doc), + "Ssu::verifyResponse() should fail when protocolVersion does not match SSU_PROTOCOL_VERSION"); } diff --git a/tests/ut_urlresolver/urlresolvertest.h b/tests/ut_urlresolver/urlresolvertest.h index 40540bb..e01af99 100644 --- a/tests/ut_urlresolver/urlresolvertest.h +++ b/tests/ut_urlresolver/urlresolvertest.h @@ -14,10 +14,11 @@ #include "libssu/ssu.h" -class UrlResolverTest: public QObject { +class UrlResolverTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void cleanupTestCase(); void checkFlavour(); @@ -31,7 +32,7 @@ class UrlResolverTest: public QObject { void checkStoreAuthorizedKeys(); void checkVerifyResponse(); - private: +private: Ssu ssu; QHash rndRepos, releaseRepos; }; diff --git a/tests/ut_variables/main.cpp b/tests/ut_variables/main.cpp index 73e0fbf..e83e74b 100644 --- a/tests/ut_variables/main.cpp +++ b/tests/ut_variables/main.cpp @@ -9,11 +9,12 @@ #include "variablestest.h" -int main(int argc, char **argv){ - VariablesTest variablesTest; +int main(int argc, char **argv) +{ + VariablesTest variablesTest; - if (QTest::qExec(&variablesTest, argc, argv)) - return 1; + if (QTest::qExec(&variablesTest, argc, argv)) + return 1; - return 0; + return 0; } diff --git a/tests/ut_variables/variablestest.cpp b/tests/ut_variables/variablestest.cpp index 94b9ab7..52e4960 100644 --- a/tests/ut_variables/variablestest.cpp +++ b/tests/ut_variables/variablestest.cpp @@ -7,62 +7,65 @@ #include "variablestest.h" -void VariablesTest::initTestCase(){ - variables.insert("packagesDomain", "packages.example.com"); - variables.insert("releaseDomain", "releases.example.com"); - variables.insert("rndProtocol", "https"); - variables.insert("release", "devel"); - variables.insert("arch", "armv8"); - variables.insert("flavourName", "flavour"); +void VariablesTest::initTestCase() +{ + variables.insert("packagesDomain", "packages.example.com"); + variables.insert("releaseDomain", "releases.example.com"); + variables.insert("rndProtocol", "https"); + variables.insert("release", "devel"); + variables.insert("arch", "armv8"); + variables.insert("flavourName", "flavour"); - urls.insert("http://%(packagesDomain)/releases/%(release)/jolla/%(arch)/", - "http://packages.example.com/releases/devel/jolla/armv8/"); - urls.insert("%(rndProtocol)://%(releaseDomain)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); - // test missing operator, which should fall back to just variable value - urls.insert("%(rndProtocol)://%(unsetDomain:)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https:///nemo/devel-flavour/platform/armv8/"); - urls.insert("%(rndProtocol)://%(releaseDomain:)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); - urls.insert("%(rndProtocol)://%(releaseDomain:unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); - // check if :- works - urls.insert("%(rndProtocol)://%(releaseDomain:-unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); - urls.insert("%(rndProtocol)://%(unsetDomain:-unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://unset.example.com/nemo/devel-flavour/platform/armv8/"); - // test with empty replacement pattern - urls.insert("%(rndProtocol)://%(unsetDomain:-)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https:///nemo/devel-flavour/platform/armv8/"); - // check if :+ works - // substitution of variable with set.example.com - urls.insert("%(rndProtocol)://%(releaseDomain:+set.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://set.example.com/nemo/devel-flavour/platform/armv8/"); - // substitution of variable with variable + /set - urls.insert("%(rndProtocol)://%(releaseDomain:+%(releaseDomain)/set)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https://releases.example.com/set/nemo/devel-flavour/platform/armv8/"); - // substitution of variable with empty variable + /set -- should substitute to "" - urls.insert("%(rndProtocol)://%(unsetDomain:+%(unsetDomain)/set)/nemo/%(release)-%(flavourName)/platform/%(arch)/", - "https:///nemo/devel-flavour/platform/armv8/"); - // test := - urls.insert("%(%(rndProtocol):=https?https://%(releaseDomain)/%(release)-%(flavourName)|http://%(releaseDomain)/%(release)-%(flavourName))", - "https://releases.example.com/devel-flavour"); - urls.insert("%(%(rndProtocol):=http?https://%(releaseDomain)/%(release)-%(flavourName)|http://%(releaseDomain)/%(release)-%(flavourName))", - "http://releases.example.com/devel-flavour"); + urls.insert("http://%(packagesDomain)/releases/%(release)/jolla/%(arch)/", + "http://packages.example.com/releases/devel/jolla/armv8/"); + urls.insert("%(rndProtocol)://%(releaseDomain)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); + // test missing operator, which should fall back to just variable value + urls.insert("%(rndProtocol)://%(unsetDomain:)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https:///nemo/devel-flavour/platform/armv8/"); + urls.insert("%(rndProtocol)://%(releaseDomain:)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); + urls.insert("%(rndProtocol)://%(releaseDomain:unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); + // check if :- works + urls.insert("%(rndProtocol)://%(releaseDomain:-unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://releases.example.com/nemo/devel-flavour/platform/armv8/"); + urls.insert("%(rndProtocol)://%(unsetDomain:-unset.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://unset.example.com/nemo/devel-flavour/platform/armv8/"); + // test with empty replacement pattern + urls.insert("%(rndProtocol)://%(unsetDomain:-)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https:///nemo/devel-flavour/platform/armv8/"); + // check if :+ works + // substitution of variable with set.example.com + urls.insert("%(rndProtocol)://%(releaseDomain:+set.example.com)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://set.example.com/nemo/devel-flavour/platform/armv8/"); + // substitution of variable with variable + /set + urls.insert("%(rndProtocol)://%(releaseDomain:+%(releaseDomain)/set)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https://releases.example.com/set/nemo/devel-flavour/platform/armv8/"); + // substitution of variable with empty variable + /set -- should substitute to "" + urls.insert("%(rndProtocol)://%(unsetDomain:+%(unsetDomain)/set)/nemo/%(release)-%(flavourName)/platform/%(arch)/", + "https:///nemo/devel-flavour/platform/armv8/"); + // test := + urls.insert("%(%(rndProtocol):=https?https://%(releaseDomain)/%(release)-%(flavourName)|http://%(releaseDomain)/%(release)-%(flavourName))", + "https://releases.example.com/devel-flavour"); + urls.insert("%(%(rndProtocol):=http?https://%(releaseDomain)/%(release)-%(flavourName)|http://%(releaseDomain)/%(release)-%(flavourName))", + "http://releases.example.com/devel-flavour"); } -void VariablesTest::cleanupTestCase(){ +void VariablesTest::cleanupTestCase() +{ } -void VariablesTest::checkResolveString(){ - QHashIterator i(urls); +void VariablesTest::checkResolveString() +{ + QHashIterator i(urls); - while (i.hasNext()){ - i.next(); - QString result = var.resolveString(i.key(), &variables); - qDebug() << i.key() << " resolved to " << result; - QCOMPARE(result, i.value()); - } + while (i.hasNext()) { + i.next(); + QString result = var.resolveString(i.key(), &variables); + qDebug() << i.key() << " resolved to " << result; + QCOMPARE(result, i.value()); + } } diff --git a/tests/ut_variables/variablestest.h b/tests/ut_variables/variablestest.h index e4ee07f..f6268b6 100644 --- a/tests/ut_variables/variablestest.h +++ b/tests/ut_variables/variablestest.h @@ -15,16 +15,17 @@ #include "libssu/ssu.h" #include "libssu/ssuvariables_p.h" -class VariablesTest: public QObject { +class VariablesTest: public QObject +{ Q_OBJECT - private slots: +private slots: void initTestCase(); void cleanupTestCase(); void checkResolveString(); - private: +private: Ssu ssu; SsuVariables var; QHash variables, urls;