Some more updater fixes

Paths were wrong - still used work directory instead of root
This commit is contained in:
Petr Mrázek 2014-01-05 13:17:42 +01:00
parent 76f58eb42c
commit 613c01dab5
7 changed files with 82 additions and 68 deletions

View File

@ -261,6 +261,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
return; return;
} }
*/ */
connect(this, SIGNAL(aboutToQuit()), SLOT(onExit()));
m_status = MultiMC::Initialized; m_status = MultiMC::Initialized;
} }
@ -510,8 +511,21 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
return m_javalist; return m_javalist;
} }
void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish) void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
{ {
// if we are going to update on exit, save the params now
if(flags & OnExit)
{
m_updateOnExitPath = updateFilesDir;
m_updateOnExitFlags = flags & ~OnExit;
return;
}
// otherwise if there already were some params for on exit update, clear them and continue
else if(m_updateOnExitPath.size())
{
m_updateOnExitFlags = None;
m_updateOnExitPath.clear();
}
QLOG_INFO() << "Installing updates."; QLOG_INFO() << "Installing updates.";
#ifdef WINDOWS #ifdef WINDOWS
QString finishCmd = MMC->applicationFilePath(); QString finishCmd = MMC->applicationFilePath();
@ -533,16 +547,15 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish
args << "--package-dir" << updateFilesDir; args << "--package-dir" << updateFilesDir;
args << "--script" << PathCombine(updateFilesDir, "file_list.xml"); args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
args << "--wait" << QString::number(MMC->applicationPid()); args << "--wait" << QString::number(MMC->applicationPid());
#ifdef MultiMC_UPDATER_DRY_RUN if(flags & DryRun)
args << "--dry-run"; args << "--dry-run";
#endif if (flags & RestartOnFinish)
if (restartOnFinish)
args << "--finish-cmd" << finishCmd; args << "--finish-cmd" << finishCmd;
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" "); QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755); QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
if (!QProcess::startDetached(updaterBinary, args)) if (!QProcess::startDetached(updaterBinary, args/*, root()*/))
{ {
QLOG_ERROR() << "Failed to start the updater process!"; QLOG_ERROR() << "Failed to start the updater process!";
return; return;
@ -552,14 +565,12 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish
MMC->quit(); MMC->quit();
} }
void MultiMC::setUpdateOnExit(const QString &updateFilesDir) void MultiMC::onExit()
{ {
m_updateOnExitPath = updateFilesDir; if(m_updateOnExitPath.size())
} {
installUpdates(m_updateOnExitPath, m_updateOnExitFlags);
QString MultiMC::getExitUpdatePath() const }
{
return m_updateOnExitPath;
} }
bool MultiMC::openJsonEditor(const QString &filename) bool MultiMC::openJsonEditor(const QString &filename)

View File

@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include "logger/QsLogDest.h" #include "logger/QsLogDest.h"
#include <QFlag>
class MinecraftVersionList; class MinecraftVersionList;
class LWJGLVersionList; class LWJGLVersionList;
@ -32,9 +33,19 @@ enum InstSortMode
// Sort alphabetically by name. // Sort alphabetically by name.
Sort_Name, Sort_Name,
// Sort by which instance was launched most recently. // Sort by which instance was launched most recently.
Sort_LastLaunch, Sort_LastLaunch
}; };
enum UpdateFlag
{
None = 0x0,
RestartOnFinish = 0x1,
DryRun = 0x2,
OnExit = 0x4
};
Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag);
Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateFlags);
class MultiMC : public QApplication class MultiMC : public QApplication
{ {
Q_OBJECT Q_OBJECT
@ -43,7 +54,7 @@ public:
{ {
Failed, Failed,
Succeeded, Succeeded,
Initialized, Initialized
}; };
public: public:
@ -110,21 +121,7 @@ public:
std::shared_ptr<JavaVersionList> javalist(); std::shared_ptr<JavaVersionList> javalist();
/*! void installUpdates(const QString updateFilesDir, UpdateFlags flags = None);
* Installs update from the given update files directory.
*/
void installUpdates(const QString &updateFilesDir, bool restartOnFinish = false);
/*!
* Sets MultiMC to install updates from the given directory when it exits.
*/
void setUpdateOnExit(const QString &updateFilesDir);
/*!
* Gets the path to install updates from on exit.
* If this is an empty string, no updates should be installed on exit.
*/
QString getExitUpdatePath() const;
/*! /*!
* Opens a json file using either a system default editor, or, if note empty, the editor * Opens a json file using either a system default editor, or, if note empty, the editor
@ -155,6 +152,12 @@ public:
return origcwdPath; return origcwdPath;
} }
private slots:
/**
* Do all the things that should be done before we exit
*/
void onExit();
private: private:
void initLogger(); void initLogger();
@ -187,6 +190,7 @@ private:
QsLogging::DestinationPtr m_debugDestination; QsLogging::DestinationPtr m_debugDestination;
QString m_updateOnExitPath; QString m_updateOnExitPath;
UpdateFlags m_updateOnExitFlags = None;
QString rootPath; QString rootPath;
QString binPath; QString binPath;

View File

@ -568,10 +568,14 @@ void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit
// If the task succeeds, install the updates. // If the task succeeds, install the updates.
if (updateDlg.exec(&updateTask)) if (updateDlg.exec(&updateTask))
{ {
UpdateFlags baseFlags = None;
#ifdef MultiMC_UPDATER_DRY_RUN
baseFlags |= DryRun;
#endif
if (installOnExit) if (installOnExit)
MMC->setUpdateOnExit(updateTask.updateFilesDir()); MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | OnExit);
else else
MMC->installUpdates(updateTask.updateFilesDir(), true); MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | RestartOnFinish);
} }
} }

View File

@ -290,12 +290,11 @@ DownloadUpdateTask::processFileLists(NetJob *job,
// delete anything in the current one version's list that isn't in the new version's list. // delete anything in the current one version's list that isn't in the new version's list.
for (VersionFileEntry entry : currentVersion) for (VersionFileEntry entry : currentVersion)
{ {
QFileInfo toDelete(entry.path); QFileInfo toDelete(PathCombine(MMC->root(), entry.path));
if (!toDelete.exists()) if (!toDelete.exists())
{ {
QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath() QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath()
<< " doesn't exist!"; << " doesn't exist!";
QLOG_ERROR() << "CWD: " << QDir::currentPath();
} }
bool keep = false; bool keep = false;
@ -314,7 +313,6 @@ DownloadUpdateTask::processFileLists(NetJob *job,
// If the loop reaches the end and we didn't find a match, delete the file. // If the loop reaches the end and we didn't find a match, delete the file.
if (!keep) if (!keep)
{ {
QFileInfo toDelete(entry.path);
if (toDelete.exists()) if (toDelete.exists())
ops.append(UpdateOperation::DeleteOp(entry.path)); ops.append(UpdateOperation::DeleteOp(entry.path));
} }
@ -326,8 +324,9 @@ DownloadUpdateTask::processFileLists(NetJob *job,
// TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
// way to do this in the background. // way to do this in the background.
QString fileMD5; QString fileMD5;
QFile entryFile(entry.path); QString realEntryPath = PathCombine(MMC->root(), entry.path);
QFileInfo entryInfo(entry.path); QFile entryFile(realEntryPath);
QFileInfo entryInfo(realEntryPath);
bool needs_upgrade = false; bool needs_upgrade = false;
if (!entryFile.exists()) if (!entryFile.exists())
@ -339,49 +338,52 @@ DownloadUpdateTask::processFileLists(NetJob *job,
bool pass = true; bool pass = true;
if (!entryInfo.isReadable()) if (!entryInfo.isReadable())
{ {
QLOG_ERROR() << "File " << entry.path << " is not readable."; QLOG_ERROR() << "File " << realEntryPath << " is not readable.";
pass = false; pass = false;
} }
if (!entryInfo.isWritable()) if (!entryInfo.isWritable())
{ {
QLOG_ERROR() << "File " << entry.path << " is not writable."; QLOG_ERROR() << "File " << realEntryPath << " is not writable.";
pass = false; pass = false;
} }
if (!entryFile.open(QFile::ReadOnly)) if (!entryFile.open(QFile::ReadOnly))
{ {
QLOG_ERROR() << "File " << entry.path << " cannot be opened for reading."; QLOG_ERROR() << "File " << realEntryPath << " cannot be opened for reading.";
pass = false; pass = false;
} }
if (!pass) if (!pass)
{ {
QLOG_ERROR() << "CWD: " << QDir::currentPath(); QLOG_ERROR() << "ROOT: " << MMC->root();
ops.clear(); ops.clear();
return false; return false;
} }
} }
QCryptographicHash hash(QCryptographicHash::Md5); if(!needs_upgrade)
auto foo = entryFile.readAll();
hash.addData(foo);
fileMD5 = hash.result().toHex();
if ((fileMD5 != entry.md5))
{ {
QLOG_DEBUG() << "MD5Sum does not match!"; QCryptographicHash hash(QCryptographicHash::Md5);
QLOG_DEBUG() << "Expected:'" << entry.md5 << "'"; auto foo = entryFile.readAll();
QLOG_DEBUG() << "Got: '" << fileMD5 << "'";
needs_upgrade = true; hash.addData(foo);
fileMD5 = hash.result().toHex();
if ((fileMD5 != entry.md5))
{
QLOG_DEBUG() << "MD5Sum does not match!";
QLOG_DEBUG() << "Expected:'" << entry.md5 << "'";
QLOG_DEBUG() << "Got: '" << fileMD5 << "'";
needs_upgrade = true;
}
} }
// skip file. it doesn't need an upgrade. // skip file. it doesn't need an upgrade.
if (!needs_upgrade) if (!needs_upgrade)
{ {
QLOG_DEBUG() << "File" << entry.path << " does not need updating."; QLOG_DEBUG() << "File" << realEntryPath << " does not need updating.";
continue; continue;
} }
// yep. this file actually needs an upgrade. PROCEED. // yep. this file actually needs an upgrade. PROCEED.
QLOG_DEBUG() << "Found file" << entry.path << " that needs updating."; QLOG_DEBUG() << "Found file" << realEntryPath << " that needs updating.";
// if it's the updater we want to treat it separately // if it's the updater we want to treat it separately
bool isUpdater = entry.path.endsWith("updater") || entry.path.endsWith("updater.exe"); bool isUpdater = entry.path.endsWith("updater") || entry.path.endsWith("updater.exe");

View File

@ -10,13 +10,7 @@ int main_gui(MultiMC &app)
mainWin.show(); mainWin.show();
mainWin.checkMigrateLegacyAssets(); mainWin.checkMigrateLegacyAssets();
mainWin.checkSetDefaultJava(); mainWin.checkSetDefaultJava();
auto exitCode = app.exec(); return app.exec();
// Update if necessary.
if (!app.getExitUpdatePath().isEmpty())
app.installUpdates(app.getExitUpdatePath(), false);
return exitCode;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -271,15 +271,15 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
{ {
std::string sourceFile = file.source; std::string sourceFile = file.source;
std::string destPath = file.dest; std::string destPath = file.dest;
std::string target = file.linkTarget; std::string absDestPath = FileUtils::makeAbsolute(destPath.c_str(), m_installDir.c_str());
LOG(Info,"Installing file " + sourceFile + " to " + destPath); LOG(Info,"Installing file " + sourceFile + " to " + absDestPath);
// backup the existing file if any // backup the existing file if any
backupFile(destPath); backupFile(absDestPath);
// create the target directory if it does not exist // create the target directory if it does not exist
std::string destDir = FileUtils::dirname(destPath.c_str()); std::string destDir = FileUtils::dirname(absDestPath.c_str());
if (!FileUtils::fileExists(destDir.c_str())) if (!FileUtils::fileExists(destDir.c_str()))
{ {
LOG(Info,"Destination path missing. Creating " + destDir); LOG(Info,"Destination path missing. Creating " + destDir);
@ -295,10 +295,10 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
} }
if(!m_dryRun) if(!m_dryRun)
{ {
FileUtils::copyFile(sourceFile.c_str(),destPath.c_str()); FileUtils::copyFile(sourceFile.c_str(),absDestPath.c_str());
// set the permissions on the newly extracted file // set the permissions on the newly extracted file
FileUtils::chmod(destPath.c_str(),file.permissions); FileUtils::chmod(absDestPath.c_str(),file.permissions);
} }
} }
@ -326,7 +326,7 @@ void UpdateInstaller::uninstallFiles()
std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin(); std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
for (;iter != m_script->filesToUninstall().end();iter++) for (;iter != m_script->filesToUninstall().end();iter++)
{ {
std::string path = m_installDir + '/' + iter->c_str(); std::string path = FileUtils::makeAbsolute(iter->c_str(), m_installDir.c_str());
if (FileUtils::fileExists(path.c_str())) if (FileUtils::fileExists(path.c_str()))
{ {
LOG(Info,"Uninstalling " + path); LOG(Info,"Uninstalling " + path);

View File

@ -41,7 +41,6 @@ class UpdateScriptFile
std::string source; std::string source;
/// The path to copy to. /// The path to copy to.
std::string dest; std::string dest;
std::string linkTarget;
/** The permissions for this file, specified /** The permissions for this file, specified
* using the standard Unix mode_t values. * using the standard Unix mode_t values.