зеркало из https://github.com/nextcloud/desktop.git
Merge pull request #3472 from owncloud/linux_restart_on_new_version
On Linux restart if new version is found on disk
This commit is contained in:
Коммит
6a20ea5e73
|
@ -88,6 +88,7 @@ Application::Application(int &argc, char **argv) :
|
|||
_gui(0),
|
||||
_theme(Theme::instance()),
|
||||
_helpOnly(false),
|
||||
_versionOnly(false),
|
||||
_showLogWindow(false),
|
||||
_logExpire(0),
|
||||
_logFlush(false),
|
||||
|
@ -104,7 +105,7 @@ Application::Application(int &argc, char **argv) :
|
|||
#endif
|
||||
parseOptions(arguments());
|
||||
//no need to waste time;
|
||||
if ( _helpOnly ) return;
|
||||
if ( _helpOnly || _versionOnly ) return;
|
||||
|
||||
if (isRunning())
|
||||
return;
|
||||
|
@ -174,6 +175,11 @@ Application::Application(int &argc, char **argv) :
|
|||
// Cleanup at Quit.
|
||||
connect (this, SIGNAL(aboutToQuit()), SLOT(slotCleanup()));
|
||||
|
||||
// remember the version of the currently running binary. On Linux it might happen that the
|
||||
// package management updates the package while the app is running. This is detected in the
|
||||
// updater slot: If the installed binary on the hd has a different version than the one
|
||||
// running, the running app is restart. That happens in folderman.
|
||||
_runningAppVersion = Utility::versionOfInstalledBinary();
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
|
@ -211,6 +217,16 @@ void Application::slotCleanup()
|
|||
_gui->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
if( Utility::isLinux() ) {
|
||||
// on linux, check if the installed binary is still the same version
|
||||
// as the one that is running. If not, restart if possible.
|
||||
const QByteArray fsVersion = Utility::versionOfInstalledBinary();
|
||||
|
||||
if( !(fsVersion.isEmpty() || _runningAppVersion.isEmpty()) && fsVersion != _runningAppVersion ) {
|
||||
_folderManager->slotScheduleAppRestart();
|
||||
}
|
||||
}
|
||||
void Application::slotCheckConnection()
|
||||
{
|
||||
auto list = AccountManager::instance()->accounts();
|
||||
|
@ -339,6 +355,8 @@ void Application::parseOptions(const QStringList &options)
|
|||
}
|
||||
} else if (option == QLatin1String("--debug")) {
|
||||
_debugMode = true;
|
||||
} else if (option == QLatin1String("--version")) {
|
||||
_versionOnly = true;
|
||||
} else {
|
||||
showHint("Unrecognized option '" + option.toStdString() + "'");
|
||||
}
|
||||
|
@ -389,6 +407,17 @@ void Application::showHelp()
|
|||
displayHelpText(helpText);
|
||||
}
|
||||
|
||||
void Application::showVersion()
|
||||
{
|
||||
QString helpText;
|
||||
QTextStream stream(&helpText);
|
||||
stream << _theme->appName().toLatin1().constData()
|
||||
<< QLatin1String(" version ")
|
||||
<< _theme->version().toLatin1().constData() << endl;
|
||||
|
||||
displayHelpText(helpText);
|
||||
}
|
||||
|
||||
void Application::showHint(std::string errorHint)
|
||||
{
|
||||
static QString binName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
|
||||
|
@ -485,6 +514,11 @@ bool Application::giveHelp()
|
|||
return _helpOnly;
|
||||
}
|
||||
|
||||
bool Application::versionOnly()
|
||||
{
|
||||
return _versionOnly;
|
||||
}
|
||||
|
||||
void Application::showSettingsDialog()
|
||||
{
|
||||
_gui->slotShowSettings();
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
void showHelp();
|
||||
void showHint(std::string errorHint);
|
||||
bool debugMode();
|
||||
bool versionOnly(); // only display the version?
|
||||
void showVersion();
|
||||
|
||||
void showSettingsDialog();
|
||||
|
||||
|
@ -93,6 +95,7 @@ private:
|
|||
Theme *_theme;
|
||||
|
||||
bool _helpOnly;
|
||||
bool _versionOnly;
|
||||
|
||||
// options from command line:
|
||||
bool _showLogWindow;
|
||||
|
@ -102,6 +105,7 @@ private:
|
|||
bool _logFlush;
|
||||
bool _userTriggeredConnect;
|
||||
bool _debugMode;
|
||||
QByteArray _runningAppVersion;
|
||||
|
||||
ClientProxy _proxy;
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ static qint64 msBetweenRequestAndSync = 2000;
|
|||
FolderMan::FolderMan(QObject *parent) :
|
||||
QObject(parent),
|
||||
_currentSyncFolder(0),
|
||||
_syncEnabled( true )
|
||||
_syncEnabled( true ),
|
||||
_appRestartRequired(false)
|
||||
{
|
||||
Q_ASSERT(!_instance);
|
||||
_instance = this;
|
||||
|
@ -473,6 +474,12 @@ void FolderMan::slotScheduleAllFolders()
|
|||
}
|
||||
}
|
||||
|
||||
void FolderMan::slotScheduleAppRestart()
|
||||
{
|
||||
_appRestartRequired = true;
|
||||
qDebug() << "## Application restart requested!";
|
||||
}
|
||||
|
||||
/*
|
||||
* if a folder wants to be synced, it calls this slot and is added
|
||||
* to the queue. The slot to actually start a sync is called afterwards.
|
||||
|
@ -540,6 +547,11 @@ void FolderMan::slotRunOneEtagJob()
|
|||
}
|
||||
if (_currentEtagJob.isNull()) {
|
||||
qDebug() << "No more remote ETag check jobs to schedule.";
|
||||
|
||||
/* now it might be a good time to check for restarting... */
|
||||
if( _currentSyncFolder == NULL && _appRestartRequired ) {
|
||||
restartApplication();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Scheduling" << alias << "to check remote ETag";
|
||||
_currentEtagJob->start(); // on destroy/end it will continue the queue via slotEtagJobDestroyed
|
||||
|
@ -1164,5 +1176,19 @@ QString FolderMan::checkPathValidityForNewFolder(const QString& path, bool forNe
|
|||
|
||||
}
|
||||
|
||||
void FolderMan::restartApplication()
|
||||
{
|
||||
if( Utility::isLinux() ) {
|
||||
// restart:
|
||||
qDebug() << "### Restarting application NOW, PID" << qApp->applicationPid() << "is ending.";
|
||||
qApp->quit();
|
||||
QStringList args = qApp->arguments();
|
||||
QString prg = args.takeFirst();
|
||||
|
||||
QProcess::startDetached(prg, args);
|
||||
} else {
|
||||
qDebug() << "On this platform we do not restart.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -148,6 +148,11 @@ public slots:
|
|||
*/
|
||||
void slotAccountStateChanged();
|
||||
|
||||
/**
|
||||
* restart the client as soon as it is possible, ie. no folders syncing.
|
||||
*/
|
||||
void slotScheduleAppRestart();
|
||||
|
||||
private slots:
|
||||
// slot to take the next folder from queue and start syncing.
|
||||
void slotStartScheduledFolderSync();
|
||||
|
@ -176,6 +181,9 @@ private:
|
|||
QString getBackupName( QString fullPathName ) const;
|
||||
void registerFolderMonitor( Folder *folder );
|
||||
|
||||
// restarts the application (Linux only)
|
||||
void restartApplication();
|
||||
|
||||
QString unescapeAlias( const QString& ) const;
|
||||
|
||||
QSet<Folder*> _disabledFolders;
|
||||
|
@ -196,6 +204,8 @@ private:
|
|||
/** When the timer expires one of the scheduled syncs will be started. */
|
||||
QTimer _startScheduledSyncTimer;
|
||||
|
||||
bool _appRestartRequired;
|
||||
|
||||
static FolderMan *_instance;
|
||||
explicit FolderMan(QObject *parent = 0);
|
||||
friend class OCC::Application;
|
||||
|
|
|
@ -59,6 +59,10 @@ int main(int argc, char **argv)
|
|||
app.showHelp();
|
||||
return 0;
|
||||
}
|
||||
if( app.versionOnly() ) {
|
||||
app.showVersion();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check a environment variable for core dumps
|
||||
#ifdef Q_OS_UNIX
|
||||
|
|
|
@ -393,6 +393,35 @@ void Utility::crash()
|
|||
*a = 1;
|
||||
}
|
||||
|
||||
// read the output of the owncloud --version command from the owncloud
|
||||
// version that is on disk. This works for most versions of the client,
|
||||
// because clients that do not yet know the --version flag return the
|
||||
// version in the first line of the help output :-)
|
||||
//
|
||||
// This version only delivers output on linux, as Mac and Win get their
|
||||
// restarting from the installer.
|
||||
QByteArray Utility::versionOfInstalledBinary( const QString& command )
|
||||
{
|
||||
QByteArray re;
|
||||
if( isLinux() ) {
|
||||
QString binary(command);
|
||||
if( binary.isEmpty() ) {
|
||||
binary = qApp->arguments()[0];
|
||||
}
|
||||
QStringList params;
|
||||
params << QLatin1String("--version");
|
||||
QProcess process;
|
||||
process.start(binary, params);
|
||||
process.waitForFinished(); // sets current thread to sleep and waits for pingProcess end
|
||||
re = process.readAllStandardOutput();
|
||||
int newline = re.indexOf(QChar('\n'));
|
||||
if( newline > 0 ) {
|
||||
re.truncate( newline );
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
static const char STOPWATCH_END_TAG[] = "_STOPWATCH_END";
|
||||
|
||||
void Utility::StopWatch::start()
|
||||
|
|
|
@ -98,6 +98,13 @@ namespace Utility
|
|||
// if false, the two cases are two different files.
|
||||
OWNCLOUDSYNC_EXPORT bool fsCasePreserving();
|
||||
|
||||
// Call the given command with the switch --version and retrun the first line
|
||||
// of the output.
|
||||
// If command is empty, the function calls the running application which, on
|
||||
// Linux, might have changed while this one is running.
|
||||
// For Mac and Windows, it returns QString()
|
||||
OWNCLOUDSYNC_EXPORT QByteArray versionOfInstalledBinary(const QString& command = QString() );
|
||||
|
||||
class OWNCLOUDSYNC_EXPORT StopWatch {
|
||||
private:
|
||||
QHash<QString, quint64> _lapTimes;
|
||||
|
|
|
@ -26,6 +26,8 @@ if( UNIX AND NOT APPLE )
|
|||
owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
|
||||
endif(UNIX AND NOT APPLE)
|
||||
|
||||
configure_file(oc_bin.h.in oc_bin.h)
|
||||
|
||||
owncloud_add_test(CSyncSqlite "")
|
||||
owncloud_add_test(NetrcParser ../src/cmd/netrcparser.cpp)
|
||||
owncloud_add_test(OwnSql "")
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
#define OWNCLOUD_BIN "@CMAKE_BINARY_DIR@/bin/owncloud"
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "utility.h"
|
||||
|
||||
#include "oc_bin.h"
|
||||
|
||||
using namespace OCC::Utility;
|
||||
|
||||
class TestUtility : public QObject
|
||||
|
@ -100,6 +102,20 @@ private slots:
|
|||
|
||||
|
||||
}
|
||||
|
||||
void testVersionOfInstalledBinary()
|
||||
{
|
||||
if( isLinux() ) {
|
||||
QString ver = versionOfInstalledBinary(OWNCLOUD_BIN);
|
||||
qDebug() << "Version of installed ownCloud Binary: " << ver;
|
||||
QVERIFY( !ver.isEmpty());
|
||||
|
||||
QRegExp rx( "ownCloud version \\d+\\.\\d+\\.\\d+.+" );
|
||||
QVERIFY( rx.exactMatch(ver));
|
||||
} else {
|
||||
QVERIFY( versionOfInstalledBinary().isEmpty());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче