summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--installerbuilder/libinstaller/createlocalrepositoryoperation.cpp383
-rw-r--r--installerbuilder/libinstaller/createlocalrepositoryoperation.h68
-rw-r--r--installerbuilder/libinstaller/init.cpp2
-rw-r--r--installerbuilder/libinstaller/libinstaller.pro6
-rw-r--r--installerbuilder/libinstaller/packagemanagercore.cpp12
-rw-r--r--installerbuilder/libinstaller/packagemanagercore.h3
-rw-r--r--installerbuilder/libinstaller/packagemanagercore_p.cpp43
-rw-r--r--installerbuilder/libinstaller/packagemanagercore_p.h1
-rw-r--r--installerbuilder/libinstaller/packagemanagergui.cpp9
9 files changed, 523 insertions, 4 deletions
diff --git a/installerbuilder/libinstaller/createlocalrepositoryoperation.cpp b/installerbuilder/libinstaller/createlocalrepositoryoperation.cpp
new file mode 100644
index 000000000..5e4af2fb1
--- /dev/null
+++ b/installerbuilder/libinstaller/createlocalrepositoryoperation.cpp
@@ -0,0 +1,383 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+#include "createlocalrepositoryoperation.h"
+
+#include "common/binaryformat.h"
+#include "common/errors.h"
+#include "common/fileutils.h"
+#include "copydirectoryoperation.h"
+#include "kdupdaterupdateoperations.h"
+#include "lib7z_facade.h"
+#include "packagemanagercore.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+
+#include <cerrno>
+
+namespace QInstaller {
+
+
+// -- AutoHelper
+
+class AutoHelper
+{
+public:
+ AutoHelper(CreateLocalRepositoryOperation *op)
+ : m_op(op)
+ {
+ }
+
+ virtual ~AutoHelper()
+ {
+ m_op->emitFullProgress();
+ m_op->setValue(QLatin1String("files"), m_files);
+ }
+
+ QStringList m_files;
+ CreateLocalRepositoryOperation *m_op;
+};
+
+
+// statics
+
+namespace Static {
+
+static void fixPermissions(const QString &repoPath)
+{
+ QDirIterator it(repoPath, QDirIterator::Subdirectories);
+ while (it.hasNext() && !it.next().isEmpty()) {
+ if (!it.fileInfo().isFile())
+ continue;
+
+ if (!QFile::setPermissions(it.filePath(), QFile::ReadOwner | QFile::WriteOwner
+ | QFile::ReadUser | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther)) {
+ throw Error(CreateLocalRepositoryOperation::tr("Could not set file permissions %1!")
+ .arg(it.filePath()));
+ }
+ }
+}
+
+static void removeDirectory(const QString &path, AutoHelper *const helper)
+{
+ QInstaller::removeDirectory(path);
+ QStringList files = helper->m_files.filter(path);
+ foreach (const QString &file, files)
+ helper->m_files.removeAll(file);
+}
+
+static void removeFiles(const QString &path, AutoHelper *const helper)
+{
+ const QFileInfoList entries = QDir(path).entryInfoList(QDir::AllEntries | QDir::Hidden);
+ foreach (const QFileInfo &fi, entries) {
+ if (fi.isSymLink() || fi.isFile()) {
+ QFile f(fi.filePath());
+ if (!f.remove())
+ throw Error(QObject::tr("Could not remove file %1: %2").arg(f.fileName(), f.errorString()));
+ helper->m_files.removeAll(f.fileName());
+ }
+ }
+}
+
+static QString createArchive(const QString repoPath, const QString &sourceDir, const QString &version
+ , AutoHelper *const helper)
+{
+ const QString fileName = QString::fromLatin1("/%1meta.7z").arg(version);
+
+ QFile archive(repoPath + fileName);
+ QInstaller::openForWrite(&archive, archive.fileName());
+ Lib7z::createArchive(&archive, QStringList() << sourceDir);
+ removeFiles(sourceDir, helper); // cleanup the files we compressed
+ if (!archive.rename(sourceDir + fileName)) {
+ throw Error(CreateLocalRepositoryOperation::tr("Could not move file %1 to %2. Error: %3").arg(archive
+ .fileName(), sourceDir + fileName, archive.errorString()));
+ }
+ return archive.fileName();
+}
+
+} // namespace Statics
+
+
+// -- CreateLocalRepositoryOperation
+
+CreateLocalRepositoryOperation::CreateLocalRepositoryOperation()
+{
+ setName(QLatin1String("CreateLocalRepository"));
+}
+
+void CreateLocalRepositoryOperation::backup()
+{
+}
+
+bool CreateLocalRepositoryOperation::performOperation()
+{
+ AutoHelper helper(this);
+ emit progressChanged(0.0);
+
+ const QStringList args = arguments();
+
+ if (args.count() != 2) {
+ emit progressChanged(1.0);
+ setError(InvalidArguments);
+ setErrorString(tr("Invalid arguments in %0: %1 arguments given, 2 expected.").arg(name())
+ .arg(args.count()));
+ return false;
+ }
+
+ QString repoPath;
+ try {
+ QString binaryPath = QFileInfo(args.at(0)).absoluteFilePath();
+ // Note the "/" at the end, important to make copy directory operation behave well
+ repoPath = QFileInfo(args.at(1)).absoluteFilePath() + QLatin1String("/repository/");
+
+ // if we're running as installer and install into an existing target, remove possible previous repos
+ PackageManagerCore *core = qVariantValue<PackageManagerCore*>(value(QLatin1String("installer")));
+ if (core && core->isOfflineOnly() && QFile::exists(repoPath)) {
+ Static::fixPermissions(repoPath);
+ QInstaller::removeDirectory(repoPath);
+ }
+
+ // create the local repository target dir
+ KDUpdater::MkdirOperation mkDirOp;
+ mkDirOp.setArguments(QStringList() << repoPath);
+ mkDirOp.backup();
+ if (!mkDirOp.performOperation()) {
+ setError(mkDirOp.error());
+ setErrorString(mkDirOp.errorString());
+ return false;
+ }
+ setValue(QLatin1String("createddir"), mkDirOp.value(QLatin1String("createddir")));
+
+ // copy the whole meta data into local repository
+ CopyDirectoryOperation copyDirOp;
+ copyDirOp.setArguments(QStringList() << QLatin1String(":/metadata/") << repoPath);
+ connect(&copyDirOp, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
+
+ const bool success = copyDirOp.performOperation();
+ helper.m_files = copyDirOp.value(QLatin1String("files")).toStringList();
+ if (!success) {
+ setError(copyDirOp.error());
+ setErrorString(copyDirOp.errorString());
+ return false;
+ }
+
+ emit progressChanged(0.25);
+
+ // we need to fix the folder and file permissions here, as copying from read only resource file
+ // systems sets all permissions to a completely bogus value...
+ Static::fixPermissions(repoPath);
+
+ // open the updates xml file we previously copied
+ QFile updatesXml(repoPath + QLatin1String("Updates.xml"));
+ if (!updatesXml.exists() || !updatesXml.open(QIODevice::ReadOnly))
+ throw QInstaller::Error(tr("Could not open file: %1").arg(updatesXml.fileName()));
+
+ // read the content of the updates xml
+ QString error;
+ QDomDocument doc;
+ if (!doc.setContent(&updatesXml, &error))
+ throw QInstaller::Error(tr("Could not read: %1. Error: %2").arg(updatesXml.fileName(), error));
+
+ // build for each available package a name - version mapping
+ QHash<QString, QString> versionMap;
+ const QDomElement root = doc.documentElement();
+ const QDomNodeList rootChildNodes = root.childNodes();
+ for (int i = 0; i < rootChildNodes.count(); ++i) {
+ const QDomElement element = rootChildNodes.at(i).toElement();
+ if (element.isNull())
+ continue;
+
+ QString name, version;
+ if (element.tagName() == QLatin1String("PackageUpdate")) {
+ const QDomNodeList elementChildNodes = element.childNodes();
+ for (int j = 0; j < elementChildNodes.count(); ++j) {
+ const QDomElement e = elementChildNodes.at(j).toElement();
+ if (e.tagName() == QLatin1String("Name"))
+ name = e.text();
+ else if (e.tagName() == QLatin1String("Version"))
+ version = e.text();
+ }
+ versionMap.insert(name, version);
+ }
+ }
+
+ emit progressChanged(0.50);
+
+ QSharedPointer<QFile> file(new QFile(binaryPath));
+ if (!file->open(QIODevice::ReadOnly)) {
+ throw QInstaller::Error(tr("Could not open file: %1. Error: %2").arg(file->fileName(),
+ file->errorString()));
+ }
+
+ // start to read the binary layout
+ BinaryLayout bl = BinaryContent::readBinaryLayout(file.data(), findMagicCookie(file.data(),
+ QInstaller::MagicCookie));
+
+ // calculate the offset of the component index start inside the binary
+ const qint64 resourceOffsetAndLengtSize = 2 * sizeof(qint64);
+ const qint64 resourceSectionSize = resourceOffsetAndLengtSize * bl.resourceCount;
+ file->seek(bl.endOfData - bl.indexSize - resourceSectionSize - resourceOffsetAndLengtSize);
+
+ const qint64 dataBlockStart = bl.endOfData - bl.dataBlockSize;
+ file->seek(retrieveInt64(file.data()) + dataBlockStart);
+ QInstallerCreator::ComponentIndex componentIndex = QInstallerCreator::ComponentIndex::read(file,
+ dataBlockStart);
+
+ QDirIterator it(repoPath, QDirIterator::Subdirectories);
+ while (it.hasNext() && !it.next().isEmpty()) {
+ if (it.fileInfo().isDir()) {
+ const QString fileName = it.fileName();
+ const QString absoluteTargetPath = QDir(repoPath).absoluteFilePath(fileName);
+
+ // zip the meta files that come with the offline installer
+ if (versionMap.contains(fileName)) {
+ helper.m_files.prepend(Static::createArchive(repoPath, absoluteTargetPath,
+ versionMap.value(fileName), &helper));
+ versionMap.remove(fileName);
+ emit outputTextChanged(helper.m_files.first());
+ }
+
+ // copy the 7z files that are inside the component index into the target
+ QInstallerCreator::Component c = componentIndex.componentByName(fileName.toUtf8());
+ if (c.archives().count()) {
+ QVector<QSharedPointer<QInstallerCreator::Archive> > archives = c.archives();
+ foreach (const QSharedPointer<QInstallerCreator::Archive> &a, archives) {
+ if (!a->open(QIODevice::ReadOnly))
+ continue;
+
+ QFile target(absoluteTargetPath + QDir::separator() + QString::fromUtf8(a->name()));
+ QInstaller::openForWrite(&target, target.fileName());
+ QInstaller::blockingCopy(a.data(), &target, a->size());
+ helper.m_files.prepend(target.fileName());
+ emit outputTextChanged(helper.m_files.first());
+ }
+ }
+ }
+ }
+
+ emit progressChanged(0.75);
+
+ QDir repo(repoPath);
+ if (!versionMap.isEmpty()) {
+ // offline installers might miss possible old components
+ foreach (const QString &dir, versionMap.keys()) {
+ const QString missingDir = repoPath + dir;
+ if (!repo.mkpath(missingDir))
+ throw QInstaller::Error(tr("Could not create target dir: %1.").arg(missingDir));
+ helper.m_files.prepend(Static::createArchive(repoPath, missingDir, versionMap.value(dir)
+ , &helper));
+ emit outputTextChanged(helper.m_files.first());
+ }
+ }
+
+ try {
+ // remove these, if we fail it doesn't hurt
+ Static::removeDirectory(QDir::cleanPath(repoPath + QLatin1String("/installer-config")),
+ &helper);
+ Static::removeDirectory(QDir::cleanPath(repoPath + QLatin1String("/config")), &helper);
+ const QStringList files = repo.entryList(QStringList() << QLatin1String("*.qrc"), QDir::Files);
+ foreach (const QString &file, files) {
+ if (repo.remove(file))
+ helper.m_files.removeAll(QDir::cleanPath(repoPath + file));
+ }
+ } catch (...) {}
+ setValue(QLatin1String("local-repo"), repoPath);
+ } catch (const Lib7z::SevenZipException &e) {
+ setError(UserDefinedError);
+ setErrorString(e.message());
+ return false;
+ } catch (const QInstaller::Error &e) {
+ setError(UserDefinedError);
+ setErrorString(e.message());
+ return false;
+ } catch (...) {
+ setError(UserDefinedError);
+ setErrorString(tr("Unknown exception caught: %1.").arg(QLatin1String(Q_FUNC_INFO)));
+ return false;
+ }
+ return true;
+}
+
+bool CreateLocalRepositoryOperation::undoOperation()
+{
+ Q_ASSERT(arguments().count() == 2);
+
+ AutoHelper _(this);
+ emit progressChanged(0.0);
+
+ QDir dir;
+ const QStringList files = value(QLatin1String("files")).toStringList();
+ foreach (const QString &file, files) {
+ emit outputTextChanged(tr("Removing file: %0").arg(file));
+ if (!QFile::remove(file)) {
+ setError(InvalidArguments);
+ setErrorString(tr("Could not remove %0.").arg(file));
+ return false;
+ }
+ dir.rmpath(QFileInfo(file).absolutePath());
+ }
+ setValue(QLatin1String("files"), QStringList());
+
+ QDir createdDir = QDir(value(QLatin1String("createddir")).toString());
+ if (createdDir == QDir::root() || !createdDir.exists())
+ return true;
+
+ QFile::remove(createdDir.path() + QLatin1String("/.DS_Store"));
+ QFile::remove(createdDir.path() + QLatin1String("/Thumbs.db"));
+
+ errno = 0;
+ const bool result = QDir::root().rmdir(createdDir.path());
+ if (!result) {
+ setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(),
+ QLatin1String(strerror(errno))));
+ }
+ setValue(QLatin1String("files"), QStringList());
+
+ return result;
+}
+
+bool CreateLocalRepositoryOperation::testOperation()
+{
+ return true;
+}
+
+Operation *CreateLocalRepositoryOperation::clone() const
+{
+ return new CreateLocalRepositoryOperation();
+}
+
+void CreateLocalRepositoryOperation::emitFullProgress()
+{
+ emit progressChanged(1.0);
+}
+
+} // namespace QInstaller
diff --git a/installerbuilder/libinstaller/createlocalrepositoryoperation.h b/installerbuilder/libinstaller/createlocalrepositoryoperation.h
new file mode 100644
index 000000000..928e2959e
--- /dev/null
+++ b/installerbuilder/libinstaller/createlocalrepositoryoperation.h
@@ -0,0 +1,68 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CREATELOCALREPOSITORYOPERATION_H
+#define CREATELOCALREPOSITORYOPERATION_H
+
+#include "qinstallerglobal.h"
+
+#include <QtCore/QObject>
+
+namespace QInstaller {
+
+class AutoHelper;
+
+class INSTALLER_EXPORT CreateLocalRepositoryOperation : public QObject, public Operation
+{
+ Q_OBJECT
+ friend class AutoHelper;
+
+public:
+ CreateLocalRepositoryOperation();
+
+ void backup();
+ bool performOperation();
+ bool undoOperation();
+ bool testOperation();
+ Operation *clone() const;
+
+signals:
+ void progressChanged(double progress);
+ void outputTextChanged(const QString &message);
+
+private:
+ void emitFullProgress();
+};
+
+} // namespace QInstaller
+
+#endif // CREATELOCALREPOSITORYOPERATION_H
diff --git a/installerbuilder/libinstaller/init.cpp b/installerbuilder/libinstaller/init.cpp
index 87b6de6d6..f71facf5b 100644
--- a/installerbuilder/libinstaller/init.cpp
+++ b/installerbuilder/libinstaller/init.cpp
@@ -34,6 +34,7 @@
#include "createshortcutoperation.h"
#include "createdesktopentryoperation.h"
+#include "createlocalrepositoryoperation.h"
#include "extractarchiveoperation.h"
#include "globalsettingsoperation.h"
#include "environmentvariablesoperation.h"
@@ -196,6 +197,7 @@ void QInstaller::init()
UpdateOperationFactory &factory = UpdateOperationFactory::instance();
factory.registerUpdateOperation<CreateShortcutOperation>(QLatin1String("CreateShortcut"));
factory.registerUpdateOperation<CreateDesktopEntryOperation>(QLatin1String("CreateDesktopEntry"));
+ factory.registerUpdateOperation<CreateLocalRepositoryOperation>(QLatin1String("CreateLocalRepository"));
factory.registerUpdateOperation<ExtractArchiveOperation>(QLatin1String("Extract"));
factory.registerUpdateOperation<GlobalSettingsOperation>(QLatin1String("GlobalConfig"));
factory.registerUpdateOperation<EnvironmentVariableOperation>(QLatin1String( "EnvironmentVariable"));
diff --git a/installerbuilder/libinstaller/libinstaller.pro b/installerbuilder/libinstaller/libinstaller.pro
index 7ff7c2130..c7a0599e7 100644
--- a/installerbuilder/libinstaller/libinstaller.pro
+++ b/installerbuilder/libinstaller/libinstaller.pro
@@ -101,7 +101,8 @@ HEADERS += $$PWD/packagemanagercore.h \
qprocesswrapper.h \
qsettingswrapper.h \
constants.h \
- packagemanagerproxyfactory.h
+ packagemanagerproxyfactory.h \
+ createlocalrepositoryoperation.h
SOURCES += $$PWD/packagemanagercore.cpp \
$$PWD/packagemanagercore_p.cpp \
@@ -168,7 +169,8 @@ SOURCES += $$PWD/packagemanagercore.cpp \
templates.cpp \
qsettingswrapper.cpp \
settings.cpp \
- packagemanagerproxyfactory.cpp
+ packagemanagerproxyfactory.cpp \
+ createlocalrepositoryoperation.cpp
macx {
HEADERS += macrelocateqt.h \
diff --git a/installerbuilder/libinstaller/packagemanagercore.cpp b/installerbuilder/libinstaller/packagemanagercore.cpp
index 0b24152c0..b47708c7a 100644
--- a/installerbuilder/libinstaller/packagemanagercore.cpp
+++ b/installerbuilder/libinstaller/packagemanagercore.cpp
@@ -1832,3 +1832,15 @@ QString PackageManagerCore::findDisplayVersion(const QString &componentName,
return findDisplayVersion(replaceWith, components, versionKey, visited);
}
+
+bool PackageManagerCore::createLocalRepositoryFromBinary() const
+{
+ return d->m_createLocalRepositoryFromBinary;
+}
+
+void PackageManagerCore::setCreateLocalRepositoryFromBinary(bool create)
+{
+ if (!isOfflineOnly())
+ return;
+ d->m_createLocalRepositoryFromBinary = create;
+}
diff --git a/installerbuilder/libinstaller/packagemanagercore.h b/installerbuilder/libinstaller/packagemanagercore.h
index eadbc841d..13509b6b1 100644
--- a/installerbuilder/libinstaller/packagemanagercore.h
+++ b/installerbuilder/libinstaller/packagemanagercore.h
@@ -223,6 +223,9 @@ public:
bool needsRestart() const;
bool finishedWithSuccess() const;
+ Q_INVOKABLE bool createLocalRepositoryFromBinary() const;
+ Q_INVOKABLE void setCreateLocalRepositoryFromBinary(bool create);
+
public Q_SLOTS:
bool runInstaller();
bool runUninstaller();
diff --git a/installerbuilder/libinstaller/packagemanagercore_p.cpp b/installerbuilder/libinstaller/packagemanagercore_p.cpp
index c3d2e3a01..abb1523a9 100644
--- a/installerbuilder/libinstaller/packagemanagercore_p.cpp
+++ b/installerbuilder/libinstaller/packagemanagercore_p.cpp
@@ -164,6 +164,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
, m_updateSourcesAdded(false)
, m_componentsToInstallCalculated(false)
, m_proxyFactory(0)
+ , m_createLocalRepositoryFromBinary(false)
{
}
@@ -186,6 +187,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
, m_magicBinaryMarker(magicInstallerMaker)
, m_componentsToInstallCalculated(false)
, m_proxyFactory(0)
+ , m_createLocalRepositoryFromBinary(false)
{
connect(this, SIGNAL(installationStarted()), m_core, SIGNAL(installationStarted()));
connect(this, SIGNAL(installationFinished()), m_core, SIGNAL(installationFinished()));
@@ -505,6 +507,7 @@ void PackageManagerCorePrivate::initialize()
{
m_coreCheckedHash.clear();
m_componentsToInstallCalculated = false;
+ m_createLocalRepositoryFromBinary = false;
// first set some common variables that may used e.g. as placeholder
// in some of the settings variables or in a script or...
@@ -1430,12 +1433,50 @@ void PackageManagerCorePrivate::runInstaller()
callBeginInstallation(componentsToInstall);
stopProcessesForUpdates(componentsToInstall);
- const int progressOperationCount = countProgressOperations(componentsToInstall);
+ const int progressOperationCount = countProgressOperations(componentsToInstall)
+ + (m_createLocalRepositoryFromBinary ? 1 : 0); // add one more operation as we support progress
double progressOperationSize = componentsInstallPartProgressSize / progressOperationCount;
foreach (Component *component, componentsToInstall)
installComponent(component, progressOperationSize, adminRightsGained);
+ if (m_createLocalRepositoryFromBinary) {
+ emit m_core->titleMessageChanged(tr("Creating local repository"));
+ ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(QString());
+ ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("Creating local repository"));
+
+ Operation *createRepo = createOwnedOperation(QLatin1String("CreateLocalRepository"));
+ if (createRepo) {
+ createRepo->setValue(QLatin1String("uninstall-only"), true);
+ createRepo->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
+ createRepo->setArguments(QStringList() << QCoreApplication::applicationFilePath() << target);
+
+ connectOperationToInstaller(createRepo, progressOperationSize);
+
+ bool success = performOperationThreaded(createRepo);
+ if (!success) {
+ adminRightsGained = m_core->gainAdminRights();
+ success = performOperationThreaded(createRepo);
+ }
+
+ if (success) {
+ QSet<Repository> repos;
+ foreach (Repository repo, m_settings.defaultRepositories()) {
+ repo.setEnabled(false);
+ repos.insert(repo);
+ }
+ repos.insert(Repository(QUrl::fromUserInput(createRepo
+ ->value(QLatin1String("local-repo")).toString()), true));
+ m_settings.setDefaultRepositories(repos);
+ addPerformed(takeOwnedOperation(createRepo));
+ } else {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("installationError"), tr("Error"), createRepo->errorString());
+ createRepo->undoOperation();
+ }
+ }
+ }
+
emit m_core->titleMessageChanged(tr("Creating Uninstaller"));
writeUninstaller(m_performedOperationsOld + m_performedOperationsCurrentSession);
diff --git a/installerbuilder/libinstaller/packagemanagercore_p.h b/installerbuilder/libinstaller/packagemanagercore_p.h
index 7f0b03918..1a585cf96 100644
--- a/installerbuilder/libinstaller/packagemanagercore_p.h
+++ b/installerbuilder/libinstaller/packagemanagercore_p.h
@@ -246,6 +246,7 @@ private:
QSet<Component*> m_componentsToUninstall;
QString m_componentsToInstallError;
FileDownloaderProxyFactory *m_proxyFactory;
+ bool m_createLocalRepositoryFromBinary;
private:
// remove once we deprecate isSelected, setSelected etc...
diff --git a/installerbuilder/libinstaller/packagemanagergui.cpp b/installerbuilder/libinstaller/packagemanagergui.cpp
index 62448dfc2..3fb88bee8 100644
--- a/installerbuilder/libinstaller/packagemanagergui.cpp
+++ b/installerbuilder/libinstaller/packagemanagergui.cpp
@@ -1610,8 +1610,15 @@ void ReadyForInstallationPage::entering()
tempRequired += extraSpace;
}
+ quint64 repositorySize = 0;
+ const bool createLocalRepository = packageManagerCore()->createLocalRepositoryFromBinary();
+ if (createLocalRepository) {
+ repositorySize = QFile(QCoreApplication::applicationFilePath()).size();
+ required += repositorySize; // if we create a local repository, take that space into account as well
+ }
+
qDebug() << "Installation space required:" << humanReadableSize(required) << "Temporary space required:"
- << humanReadableSize(tempRequired);
+ << humanReadableSize(tempRequired) << "Local repository size:" << humanReadableSize(repositorySize);
if (tempOnSameVolume && (installVolumeAvailableSize <= (required + tempRequired))) {
m_msgLabel->setText(tr("Not enough disk space to store temporary files and the installation! "