27#include <QDirIterator>
29#include <zypp/RepoManager.h>
30#include <zypp/RepoInfo.h>
44SsuRepoManager::SsuRepoManager()
52 SsuLog *ssuLog = SsuLog::instance();
65 ssuLog->
print(LOG_ERR,
"Repository already added: "+repo);
69 if (repoUrl.isEmpty() && systemRepos.contains(repo)) {
71 QStringList enabledRepos;
72 if (ssuSettings->contains(
"enabled-repos"))
73 enabledRepos = ssuSettings->value(
"enabled-repos").toStringList();
76 enabledRepos.append(repo);
77 enabledRepos.removeDuplicates();
78 ssuSettings->setValue(
"enabled-repos", enabledRepos);
80 }
else if (!systemRepos.contains(repo)) {
81 ssuSettings->setValue(
"repository-urls/" + repo, repoUrl);
94 (domain.isEmpty() ? settings->
domain() : domain) +
"-domain",
95 "_ca-certificate").toString();
100 if (settings->contains(
"ca-certificate"))
101 return settings->value(
"ca-certificate").toString();
109 QStringList disabledRepos;
111 if (ssuSettings->contains(
"disabled-repos"))
112 disabledRepos = ssuSettings->value(
"disabled-repos").toStringList();
114 disabledRepos.append(repo);
115 disabledRepos.removeDuplicates();
117 ssuSettings->setValue(
"disabled-repos", disabledRepos);
126 QStringList disabledRepos;
128 if (ssuSettings->contains(
"disabled-repos")) {
129 disabledRepos = ssuSettings->value(
"disabled-repos").toStringList();
131 disabledRepos.removeAll(repo);
132 disabledRepos.removeDuplicates();
134 if (disabledRepos.size() > 0)
135 ssuSettings->setValue(
"disabled-repos", disabledRepos);
137 ssuSettings->remove(
"disabled-repos");
149 SsuLog *ssuLog = SsuLog::instance();
162 ssuLog->
print(LOG_ERR,
"Will not remove system repository: "+repo);
166 if (ssuSettings->contains(
"repository-urls/" + repo))
167 ssuSettings->remove(
"repository-urls/" + repo);
169 QStringList sections;
170 sections <<
"enabled-repos" <<
"disabled-repos";
171 for (
const QString §ion: sections) {
172 if (ssuSettings->contains(section)) {
173 QStringList
repos = ssuSettings->value(section).toStringList();
174 repos.removeAll(repo);
175 repos.removeDuplicates();
176 if (
repos.size() > 0)
177 ssuSettings->setValue(section,
repos);
179 ssuSettings->remove(section);
196 return repos(rnd, deviceInfo, filter);
203 return repos(rnd, deviceInfo, filter);
214 result = deviceInfo.
repos(rnd, filter);
220 result.append(featureManager.repos(rnd, filter));
235 ssuSettings->beginGroup(
"repository-urls");
236 QStringList repoUrls = ssuSettings->allKeys();
237 ssuSettings->endGroup();
238 result.append(repoUrls);
241 if (ssuSettings->contains(
"enabled-repos"))
242 result.append(ssuSettings->value(
"enabled-repos").toStringList());
246 if (ssuSettings->contains(
"enabled-repos") && appInstallMode) {
248 if (ssuSettings->value(
"enabled-repos").toStringList().contains(
"store"))
249 result.append(
"store");
256 foreach (
const QString &key, ssuSettings->value(
"disabled-repos").toStringList())
257 result.removeAll(key);
262 result.removeDuplicates();
274 SsuLog *ssuLog = SsuLog::instance();
277 ssuLog->
print(LOG_INFO,
"Repo management requested, but not enabled (option 'deviceMode')");
282 bool rndMode =
false;
288 QStringList repositoryList =
repos(rndMode);
290 zypp::RepoManager zyppManager;
291 std::list<zypp::RepoInfo> zyppRepos = zyppManager.knownRepositories();
297 foreach (zypp::RepoInfo zyppRepo, zyppRepos) {
298 if (zyppRepo.filepath().basename().substr(0, 4) !=
"ssu_") {
299 ssuLog->
print(LOG_INFO,
"Strict mode enabled, removing unmanaged repository " + QString::fromStdString(zyppRepo.name()));
300 zyppManager.removeRepository(zyppRepo);
306 zyppRepos = zyppManager.knownRepositories();
307 foreach (zypp::RepoInfo zyppRepo, zyppRepos) {
308 if (zyppRepo.filepath().basename().substr(0, 4) ==
"ssu_") {
309 QStringList parts = QString::fromStdString(zyppRepo.filepath().basename()).split(
"_");
311 if (parts.count() == 3) {
312 if (!repositoryList.contains(parts.at(1)) ||
313 parts.at(2) != (rndMode ?
"rnd.repo" :
"release.repo" )) {
315 zyppManager.removeRepository(zyppRepo);
319 zyppManager.removeRepository(zyppRepo);
325 foreach (
const QString &repo, repositoryList) {
328 QString repoName = repo;
330 if (repo.endsWith(
"-debuginfo")) {
331 debugSplit =
"&debug";
332 repoName = repo.left(repo.size() - 10);
337 QString repoFilePath = QString(
"%1/ssu_%2_%3.repo")
340 .arg(rndMode ?
"rnd" :
"release");
342 if (
url(repoName, rndMode).isEmpty()) {
345 QTextStream qerr(stderr);
346 qerr <<
"Repository " << repo <<
" does not contain valid URL, skipping and disabling." << endl;
348 QFile(repoFilePath).remove();
352 QFile repoFile(repoFilePath);
354 if (repoFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
355 QTextStream out(&repoFile);
358 out <<
"[" << repo <<
"]" << endl
359 <<
"name=" << repo << endl
360 <<
"failovermethod=priority" << endl
361 <<
"type=rpm-md" << endl
362 <<
"gpgcheck=0" << endl
363 <<
"enabled=1" << endl;
366 out <<
"baseurl=plugin:ssu?rnd&repo=" << repoName << debugSplit << endl;
368 out <<
"baseurl=plugin:ssu?repo=" << repoName << debugSplit << endl;
379 QStringList configSections;
381 QString release = settings->
release(rnd);
384 var.
variableSection(settings,
"repository-url-variables", storageHash);
394 storageHash->insert(
"flavour", settings->
flavour());
395 storageHash->insert(
"flavourName", settings->
flavour());
396 storageHash->insert(
"flavourPattern",
398 settings->
flavour() +
"-flavour/flavour-pattern").toString());
399 configSections << settings->
flavour() +
"-flavour" <<
"rnd" <<
"all";
405 configSections <<
"release" <<
"all";
408 storageHash->insert(
"release", release);
409 storageHash->insert(
"releaseMajor", release.section(
'.', 0, 0));
410 storageHash->insert(
"releaseMinor", release.section(
'.', 1, 1));
411 storageHash->insert(
"releaseMajorMinor", release.section(
'.', 0, 1));
413 if (!storageHash->contains(
"debugSplit"))
414 storageHash->insert(
"debugSplit",
"packages");
416 if (!storageHash->contains(
"arch"))
417 storageHash->insert(
"arch", settings->value(
"arch").toString());
419 return configSections;
425 QHash<QString, QString> repoParameters,
426 QHash<QString, QString> parametersOverride)
433 if (repoName.endsWith(
"-debuginfo") && !repoParameters.contains(
"debugSplit"))
434 repoParameters.insert(
"debugSplit",
"debug");
436 QStringList configSections =
repoVariables(&repoParameters, rndRepo);
439 if (parametersOverride.contains(
"model"))
442 repoParameters.insert(
"deviceFamily", deviceInfo.
deviceFamily());
443 repoParameters.insert(
"deviceModel", deviceInfo.
deviceModel());
444 repoParameters.insert(
"deviceVariant", deviceInfo.
deviceVariant(
true));
451 if (parametersOverride.contains(
"domain")) {
452 domain = parametersOverride.value(
"domain");
453 domain.replace(
"-",
":");
455 domain = settings->
domain();
457 repoParameters.insert(
"ssuDomain", domain);
459 repoParameters.insert(
"brand", settings->
brand());
464 var.
variableSection(&repoSettings, domain +
"-domain", &repoParameters);
467 QHash<QString, QString>::const_iterator i = parametersOverride.constBegin();
468 while (i != parametersOverride.constEnd()) {
469 repoParameters.insert(i.key(), i.value());
479 QString r = featureManager.url(adaptationRepoName, rndRepo);
482 foreach (
const QString §ion, configSections) {
483 repoSettings.beginGroup(section);
484 if (repoSettings.contains(adaptationRepoName)) {
485 r = repoSettings.value(adaptationRepoName).toString();
486 repoSettings.endGroup();
489 repoSettings.endGroup();
493 if (r.isEmpty() && settings->contains(
"repository-urls/" + adaptationRepoName)) {
494 r = settings->value(
"repository-urls/" + adaptationRepoName).toString();
Q_INVOKABLE QString domain(bool pretty=false)
Q_INVOKABLE Ssu::DeviceModeFlags deviceMode()
Q_INVOKABLE QString release(bool rnd=false)
Q_INVOKABLE QString brand()
Q_INVOKABLE QString flavour()
Q_INVOKABLE QString deviceFamily()
QString adaptationVariables(const QString &adaptationName, QHash< QString, QString > *storageHash)
QStringList repos(bool rnd=false, int filter=Ssu::NoFilter)
Q_INVOKABLE void setDeviceModel(const QString &model=QString())
Q_INVOKABLE QString deviceVariant(bool fallback=false)
Q_INVOKABLE QString deviceModel()
void print(int priority, const QString &message)
int remove(const QString &repo)
int add(const QString &repo, const QString &repoUrl=QString())
QStringList repos(int filter=Ssu::NoFilter|Ssu::UserBlacklist)
int enable(const QString &repo)
QString url(const QString &repoName, bool rndRepo=false, QHash< QString, QString > repoParameters=QHash< QString, QString >(), QHash< QString, QString > parametersOverride=QHash< QString, QString >())
int disable(const QString &repo)
static QString caCertificatePath(const QString &domain=QString())
QStringList repoVariables(QHash< QString, QString > *storageHash, bool rnd=false)
QVariant variable(const QString §ion, const QString &key)
void variableSection(const QString §ion, QHash< QString, QString > *storageHash)
static QString resolveString(const QString &pattern, QHash< QString, QString > *variables, int recursionDepth=0)
@ DisableRepoManager
Disable automagic repository management.
@ RndMode
Enable RnD mode for device.
@ UpdateMode
Do repo isolation and similar bits important for updating devices.
@ AppInstallMode
Do repo isolation, but keep store repository enabled.
@ LenientMode
Disable strict mode (i.e., keep unmanaged repositories).
@ UserFilter
Only user configured repositories.
@ NoFilter
All repositories (global | user).
@ UserBlacklist
User blacklist applied.
@ BoardFilter
Only global repositories.
@ Available
Include all defined repos, including disabled.
#define ZYPP_REPO_PATH
Path to zypper repo configuration.
#define SSU_REPO_CONFIGURATION_DIR
Path to config.d for ssu domain configurations.
#define SSU_REPO_CONFIGURATION
Path to the ssu domain configuration file.