diff --git a/libssu/ssu.h b/libssu/ssu.h index 816d412..8dabdb9 100644 --- a/libssu/ssu.h +++ b/libssu/ssu.h @@ -116,7 +116,8 @@ class Ssu: public QObject { 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) + LenientMode = 0x8, ///< Disable strict mode (i.e., keep unmanaged repositories) + UpdateMode = 0x10 ///< Do repo isolation and similar bits important for updating devices }; /** * A list of types ssu provides shiny values suitable for displaying @@ -136,6 +137,14 @@ class Ssu: public QObject { 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, + }; + private: QString errorString; bool errorFlag; diff --git a/libssu/ssudeviceinfo.cpp b/libssu/ssudeviceinfo.cpp index d0baf15..a3029a1 100644 --- a/libssu/ssudeviceinfo.cpp +++ b/libssu/ssudeviceinfo.cpp @@ -403,6 +403,11 @@ 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){ @@ -433,31 +438,6 @@ QStringList SsuDeviceInfo::repos(bool rnd, int filter){ result.removeAll(key); } - // read user-defined repositories from ssu.ini - // TODO: in strict mode, filter the repository list from there - SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - - if (filter == Ssu::NoFilter || - filter == Ssu::UserFilter){ - ssuSettings->beginGroup("repository-urls"); - result.append(ssuSettings->allKeys()); - ssuSettings->endGroup(); - - // read user-enabled repositories from ssu.ini - if (ssuSettings->contains("enabled-repos")) - result.append(ssuSettings->value("enabled-repos").toStringList()); - } - - if (filter == Ssu::NoFilter || - filter == Ssu::UserFilter || - filter == Ssu::BoardFilterUserBlacklist){ - // read the disabled repositories from user configuration - if (ssuSettings->contains("disabled-repos")){ - foreach (const QString &key, ssuSettings->value("disabled-repos").toStringList()) - result.removeAll(key); - } - } - result.removeDuplicates(); return result; } diff --git a/libssu/ssurepomanager.cpp b/libssu/ssurepomanager.cpp index 04c7645..1a84219 100644 --- a/libssu/ssurepomanager.cpp +++ b/libssu/ssurepomanager.cpp @@ -25,9 +25,13 @@ SsuRepoManager::SsuRepoManager(): QObject() { } -void SsuRepoManager::add(QString repo, QString repoUrl){ +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; + if (repoUrl == ""){ // just enable a repository which has URL in repos.ini QStringList enabledRepos; @@ -41,6 +45,7 @@ void SsuRepoManager::add(QString repo, QString repoUrl){ ssuSettings->setValue("repository-urls/" + repo, repoUrl); ssuSettings->sync(); + return 0; } QString SsuRepoManager::caCertificatePath(QString domain){ @@ -62,7 +67,7 @@ QString SsuRepoManager::caCertificatePath(QString domain){ return ""; } -void SsuRepoManager::disable(QString repo){ +int SsuRepoManager::disable(QString repo){ SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); QStringList disabledRepos; @@ -74,9 +79,11 @@ void SsuRepoManager::disable(QString repo){ ssuSettings->setValue("disabled-repos", disabledRepos); ssuSettings->sync(); + + return 0; } -void SsuRepoManager::enable(QString repo){ +int SsuRepoManager::enable(QString repo){ SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); QStringList disabledRepos; @@ -88,10 +95,17 @@ void SsuRepoManager::enable(QString repo){ ssuSettings->setValue("disabled-repos", disabledRepos); ssuSettings->sync(); + + return 0; } -void SsuRepoManager::remove(QString repo){ +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; + if (ssuSettings->contains("repository-urls/" + repo)) ssuSettings->remove("repository-urls/" + repo); @@ -105,6 +119,8 @@ void SsuRepoManager::remove(QString repo){ } ssuSettings->sync(); + + return 0; } QStringList SsuRepoManager::repos(bool rnd, int filter){ @@ -116,11 +132,63 @@ QStringList SsuRepoManager::repos(bool rnd, int 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; + if ((ssuSettings->deviceMode() & Ssu::UpdateMode) == Ssu::UpdateMode) + updateMode = 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); + } + + // read user-enabled repositories from ssu.ini + if (ssuSettings->contains("enabled-repos") && !updateMode) + result.append(ssuSettings->value("enabled-repos").toStringList()); + } + + 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); + } + } + + result.sort(); result.removeDuplicates(); @@ -136,7 +204,7 @@ void SsuRepoManager::update(){ QStringList ssuFilters; SsuCoreConfig *ssuSettings = SsuCoreConfig::instance(); - int deviceMode = ssuSettings->value("deviceMode").toInt(); + int deviceMode = ssuSettings->deviceMode(); SsuLog *ssuLog = SsuLog::instance(); diff --git a/libssu/ssurepomanager.h b/libssu/ssurepomanager.h index 35c5123..6e85a99 100644 --- a/libssu/ssurepomanager.h +++ b/libssu/ssurepomanager.h @@ -25,25 +25,43 @@ class SsuRepoManager: public QObject { * treatment. They'll get saved with the full name to make zypper and the user * happy, but internally the -debuginfo will be stripped, and the debugSplit * parameter set to debug instead. + * + * If the device is in UpdateMode this function does nothing. */ - void 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 + * + * @retval 0 Success + * @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=""); /** * Disable a repository + * + * @retval 0 Success + * @retval -1 Request ignored because device is in update mode + * @retval -2 Request ignored because 3rd party repositories are disabled */ - void disable(QString repo); + int disable(QString repo); /** * Enable a repository, given it's not disabled by board configuration + * + * @retval 0 Success + * @retval -1 Request ignored because device is in update mode + * @retval -2 Request ignored because 3rd party repositories are disabled */ - void enable(QString repo); + int enable(QString repo); /** * Remove a repository + * + * @retval 0 Success + * @retval -1 Request ignored because device is in update mode + * @retval -2 Request ignored because 3rd party repositories are disabled */ - void remove(QString repo); + int remove(QString repo); /** * Collect the list of repositories from different submodules */ diff --git a/ssucli/ssucli.cpp b/ssucli/ssucli.cpp index 55f7ff2..47bd444 100644 --- a/ssucli/ssucli.cpp +++ b/ssucli/ssucli.cpp @@ -125,6 +125,8 @@ void SsuCli::optMode(QStringList opt){ modeList.append("ReleaseMode"); if ((deviceMode & Ssu::LenientMode) == Ssu::LenientMode) modeList.append("LenientMode"); + if ((deviceMode & Ssu::UpdateMode) == Ssu::UpdateMode) + modeList.append("UpdateMode"); qout << "Device mode is: " << ssu.deviceMode() << " (" << modeList.join(" | ") << ")" << endl;