2010-07-13 15:26:12 +02:00
|
|
|
/**************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
|
|
|
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
|
|
|
**
|
|
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
|
|
|
**
|
|
|
|
|
** Commercial Usage
|
|
|
|
|
**
|
|
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Nokia.
|
|
|
|
|
**
|
|
|
|
|
** GNU Lesser General Public License Usage
|
|
|
|
|
**
|
|
|
|
|
** Alternatively, 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.
|
|
|
|
|
**
|
|
|
|
|
** If you are unsure which license is appropriate for your use, please
|
|
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
|
|
|
|
**
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
2010-07-12 11:07:36 +02:00
|
|
|
#include "maemodeploystep.h"
|
|
|
|
|
|
2010-07-13 15:24:21 +02:00
|
|
|
#include "maemoconstants.h"
|
2010-07-12 11:07:36 +02:00
|
|
|
#include "maemodeploystepwidget.h"
|
2010-07-16 17:09:05 +02:00
|
|
|
#include "maemodeviceconfiglistmodel.h"
|
2010-07-13 17:00:12 +02:00
|
|
|
#include "maemoglobal.h"
|
2010-07-13 15:24:21 +02:00
|
|
|
#include "maemopackagecreationstep.h"
|
2010-08-11 16:31:59 +02:00
|
|
|
#include "maemoremotemounter.h"
|
2010-07-13 15:24:21 +02:00
|
|
|
#include "maemorunconfiguration.h"
|
2010-08-11 16:31:59 +02:00
|
|
|
#include "maemotoolchain.h"
|
2010-07-12 11:07:36 +02:00
|
|
|
|
2010-07-13 15:24:21 +02:00
|
|
|
#include <coreplugin/ssh/sftpchannel.h>
|
|
|
|
|
#include <coreplugin/ssh/sshconnection.h>
|
|
|
|
|
#include <coreplugin/ssh/sshremoteprocess.h>
|
|
|
|
|
|
|
|
|
|
#include <projectexplorer/buildconfiguration.h>
|
|
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
|
|
|
|
#include <projectexplorer/target.h>
|
|
|
|
|
|
2010-08-11 16:31:59 +02:00
|
|
|
#include <qt4projectmanager/qt4buildconfiguration.h>
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
#include <QtCore/QCoreApplication>
|
2010-08-11 16:31:59 +02:00
|
|
|
#include <QtCore/QDir>
|
2010-07-13 15:24:21 +02:00
|
|
|
#include <QtCore/QEventLoop>
|
|
|
|
|
#include <QtCore/QFileInfo>
|
|
|
|
|
#include <QtCore/QTimer>
|
|
|
|
|
|
|
|
|
|
using namespace Core;
|
2010-07-12 11:07:36 +02:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
|
|
|
|
|
namespace Qt4ProjectManager {
|
|
|
|
|
namespace Internal {
|
2010-08-12 10:31:52 +02:00
|
|
|
namespace { const int DefaultMountPort = 1050; }
|
2010-07-12 11:07:36 +02:00
|
|
|
|
|
|
|
|
const QLatin1String MaemoDeployStep::Id("Qt4ProjectManager.MaemoDeployStep");
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildStepList *parent)
|
2010-10-27 10:50:52 +02:00
|
|
|
: BuildStep(parent, Id)
|
2010-07-12 11:07:36 +02:00
|
|
|
{
|
2010-07-13 15:24:21 +02:00
|
|
|
ctor();
|
2010-07-12 11:07:36 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildStepList *parent,
|
2010-07-12 11:07:36 +02:00
|
|
|
MaemoDeployStep *other)
|
2010-10-27 10:50:52 +02:00
|
|
|
: BuildStep(parent, other), m_lastDeployed(other->m_lastDeployed)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
|
|
|
|
ctor();
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-27 10:50:52 +02:00
|
|
|
MaemoDeployStep::~MaemoDeployStep() { }
|
2010-07-13 15:24:21 +02:00
|
|
|
|
|
|
|
|
void MaemoDeployStep::ctor()
|
2010-07-12 11:07:36 +02:00
|
|
|
{
|
2010-08-19 12:26:21 +02:00
|
|
|
//: MaemoDeployStep default display name
|
|
|
|
|
setDefaultDisplayName(tr("Deploy to Maemo device"));
|
2010-08-16 11:40:41 +02:00
|
|
|
|
2010-10-27 10:50:52 +02:00
|
|
|
// A MaemoDeployables object is only dependent on the active build
|
|
|
|
|
// configuration and therefore can (and should) be shared among all
|
|
|
|
|
// deploy steps.
|
|
|
|
|
const QList<DeployConfiguration *> &deployConfigs
|
|
|
|
|
= target()->deployConfigurations();
|
|
|
|
|
if (deployConfigs.isEmpty()) {
|
|
|
|
|
m_deployables = QSharedPointer<MaemoDeployables>(new MaemoDeployables(this));
|
|
|
|
|
} else {
|
|
|
|
|
const MaemoDeployStep *const other
|
|
|
|
|
= MaemoGlobal::buildStep<MaemoDeployStep>(deployConfigs.first());
|
|
|
|
|
m_deployables = other->deployables();
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-11 16:31:59 +02:00
|
|
|
m_connecting = false;
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
m_stopped = false;
|
2010-07-16 17:09:05 +02:00
|
|
|
m_deviceConfigModel = new MaemoDeviceConfigListModel(this);
|
2010-08-11 16:31:59 +02:00
|
|
|
m_canStart = true;
|
2010-08-20 12:50:10 +02:00
|
|
|
m_sysrootInstaller = new QProcess(this);
|
|
|
|
|
connect(m_sysrootInstaller, SIGNAL(finished(int,QProcess::ExitStatus)),
|
|
|
|
|
this, SLOT(handleSysrootInstallerFinished()));
|
|
|
|
|
connect(m_sysrootInstaller, SIGNAL(readyReadStandardOutput()), this,
|
|
|
|
|
SLOT(handleSysrootInstallerOutput()));
|
|
|
|
|
connect(m_sysrootInstaller, SIGNAL(readyReadStandardError()), this,
|
|
|
|
|
SLOT(handleSysrootInstallerErrorOutput()));
|
2010-08-11 16:31:59 +02:00
|
|
|
m_cleanupTimer = new QTimer(this);
|
|
|
|
|
connect(m_cleanupTimer, SIGNAL(timeout()), this,
|
|
|
|
|
SLOT(handleCleanupTimeout()));
|
2010-08-23 15:54:35 +02:00
|
|
|
m_mounter = new MaemoRemoteMounter(this);
|
2010-08-11 16:31:59 +02:00
|
|
|
connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted()));
|
|
|
|
|
connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted()));
|
|
|
|
|
connect(m_mounter, SIGNAL(error(QString)), this,
|
|
|
|
|
SLOT(handleMountError(QString)));
|
|
|
|
|
connect(m_mounter, SIGNAL(reportProgress(QString)), this,
|
|
|
|
|
SLOT(handleProgressReport(QString)));
|
2010-08-26 11:17:40 +02:00
|
|
|
connect(m_mounter, SIGNAL(debugOutput(QString)), this,
|
|
|
|
|
SLOT(handleMountDebugOutput(QString)));
|
2010-07-12 11:07:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MaemoDeployStep::init()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::run(QFutureInterface<bool> &fi)
|
|
|
|
|
{
|
2010-07-13 15:24:21 +02:00
|
|
|
// Move to GUI thread for connection sharing with run control.
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(start()));
|
|
|
|
|
|
|
|
|
|
MaemoDeployEventHandler eventHandler(this, fi);
|
2010-07-14 08:33:17 +02:00
|
|
|
connect (&eventHandler, SIGNAL(destroyed()), this, SLOT(stop()));
|
2010-07-12 11:07:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BuildStepConfigWidget *MaemoDeployStep::createConfigWidget()
|
|
|
|
|
{
|
2010-07-13 15:24:21 +02:00
|
|
|
return new MaemoDeployStepWidget(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariantMap MaemoDeployStep::toMap() const
|
|
|
|
|
{
|
|
|
|
|
QVariantMap map(BuildStep::toMap());
|
|
|
|
|
addDeployTimesToMap(map);
|
2010-08-20 12:50:10 +02:00
|
|
|
map.insert(DeployToSysrootKey, m_deployToSysroot);
|
2010-07-16 17:09:05 +02:00
|
|
|
map.unite(m_deviceConfigModel->toMap());
|
2010-07-13 15:24:21 +02:00
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::addDeployTimesToMap(QVariantMap &map) const
|
|
|
|
|
{
|
|
|
|
|
QVariantList hostList;
|
|
|
|
|
QVariantList fileList;
|
|
|
|
|
QVariantList remotePathList;
|
|
|
|
|
QVariantList timeList;
|
|
|
|
|
typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt;
|
|
|
|
|
for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) {
|
|
|
|
|
fileList << it.key().first.localFilePath;
|
|
|
|
|
remotePathList << it.key().first.remoteDir;
|
|
|
|
|
hostList << it.key().second;
|
|
|
|
|
timeList << it.value();
|
|
|
|
|
}
|
|
|
|
|
map.insert(LastDeployedHostsKey, hostList);
|
|
|
|
|
map.insert(LastDeployedFilesKey, fileList);
|
|
|
|
|
map.insert(LastDeployedRemotePathsKey, remotePathList);
|
|
|
|
|
map.insert(LastDeployedTimesKey, timeList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MaemoDeployStep::fromMap(const QVariantMap &map)
|
|
|
|
|
{
|
|
|
|
|
if (!BuildStep::fromMap(map))
|
|
|
|
|
return false;
|
|
|
|
|
getDeployTimesFromMap(map);
|
2010-07-16 17:09:05 +02:00
|
|
|
m_deviceConfigModel->fromMap(map);
|
2010-08-20 12:50:10 +02:00
|
|
|
m_deployToSysroot = map.value(DeployToSysrootKey, true).toBool();
|
2010-07-13 15:24:21 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::getDeployTimesFromMap(const QVariantMap &map)
|
|
|
|
|
{
|
|
|
|
|
const QVariantList &hostList = map.value(LastDeployedHostsKey).toList();
|
|
|
|
|
const QVariantList &fileList = map.value(LastDeployedFilesKey).toList();
|
|
|
|
|
const QVariantList &remotePathList
|
|
|
|
|
= map.value(LastDeployedRemotePathsKey).toList();
|
|
|
|
|
const QVariantList &timeList = map.value(LastDeployedTimesKey).toList();
|
|
|
|
|
const int elemCount
|
|
|
|
|
= qMin(qMin(hostList.size(), fileList.size()),
|
|
|
|
|
qMin(remotePathList.size(), timeList.size()));
|
|
|
|
|
for (int i = 0; i < elemCount; ++i) {
|
|
|
|
|
const MaemoDeployable d(fileList.at(i).toString(),
|
|
|
|
|
remotePathList.at(i).toString());
|
|
|
|
|
m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()),
|
|
|
|
|
timeList.at(i).toDateTime());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MaemoPackageCreationStep *MaemoDeployStep::packagingStep() const
|
|
|
|
|
{
|
2010-07-13 17:16:23 +02:00
|
|
|
const MaemoPackageCreationStep * const step
|
2010-08-02 16:01:02 +02:00
|
|
|
= MaemoGlobal::buildStep<MaemoPackageCreationStep>(target()->activeDeployConfiguration());
|
2010-07-14 12:21:35 +02:00
|
|
|
Q_ASSERT_X(step, Q_FUNC_INFO,
|
|
|
|
|
"Impossible: Maemo build configuration without packaging step.");
|
2010-07-13 17:16:23 +02:00
|
|
|
return step;
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::raiseError(const QString &errorString)
|
|
|
|
|
{
|
2010-08-17 10:47:36 +02:00
|
|
|
disconnect(m_connection.data(), 0, this, 0);
|
2010-07-13 15:24:21 +02:00
|
|
|
emit addTask(Task(Task::Error, errorString, QString(), -1,
|
|
|
|
|
Constants::TASK_CATEGORY_BUILDSYSTEM));
|
|
|
|
|
emit error();
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-20 12:50:10 +02:00
|
|
|
void MaemoDeployStep::writeOutput(const QString &text, OutputFormat format)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
|
|
|
|
emit addOutput(text, format);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::stop()
|
|
|
|
|
{
|
2010-08-11 16:31:59 +02:00
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
const bool remoteProcessRunning
|
|
|
|
|
= (m_deviceInstaller && m_deviceInstaller->isRunning())
|
|
|
|
|
|| m_currentDeviceDeployAction;
|
|
|
|
|
const bool isActive = remoteProcessRunning || m_connecting
|
|
|
|
|
|| m_needsInstall || !m_filesToCopy.isEmpty();
|
|
|
|
|
if (!isActive) {
|
|
|
|
|
if (m_connection)
|
|
|
|
|
disconnect(m_connection.data(), 0, this, 0);
|
|
|
|
|
return;
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
2010-08-24 14:49:48 +02:00
|
|
|
|
|
|
|
|
if (remoteProcessRunning) {
|
|
|
|
|
const QByteArray programToKill
|
2010-08-24 17:41:19 +02:00
|
|
|
= m_currentDeviceDeployAction ? "/bin/cp" : "/usr/bin/dpkg";
|
|
|
|
|
const QByteArray cmdLine = "pkill " + programToKill
|
|
|
|
|
+ "; sleep 1; pkill -9 " + programToKill;
|
2010-08-24 14:49:48 +02:00
|
|
|
SshRemoteProcess::Ptr killProc
|
|
|
|
|
= m_connection->createRemoteProcess(cmdLine);
|
|
|
|
|
killProc->start();
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
2010-08-24 14:49:48 +02:00
|
|
|
m_stopped = true;
|
|
|
|
|
m_unmountState = CurrentMountsUnmount;
|
|
|
|
|
m_canStart = false;
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
m_filesToCopy.clear();
|
|
|
|
|
m_connecting = false;
|
|
|
|
|
m_sysrootInstaller->terminate();
|
|
|
|
|
m_sysrootInstaller->waitForFinished(500);
|
|
|
|
|
m_sysrootInstaller->kill();
|
|
|
|
|
m_cleanupTimer->start(5000);
|
|
|
|
|
m_mounter->stop();
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString MaemoDeployStep::uploadDir() const
|
|
|
|
|
{
|
2010-07-13 17:00:12 +02:00
|
|
|
return MaemoGlobal::homeDirOnDevice(m_connection->connectionParameters().uname);
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MaemoDeployStep::currentlyNeedsDeployment(const QString &host,
|
|
|
|
|
const MaemoDeployable &deployable) const
|
|
|
|
|
{
|
|
|
|
|
const QDateTime &lastDeployed
|
|
|
|
|
= m_lastDeployed.value(DeployablePerHost(deployable, host));
|
|
|
|
|
return !lastDeployed.isValid()
|
|
|
|
|
|| QFileInfo(deployable.localFilePath).lastModified() > lastDeployed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::setDeployed(const QString &host,
|
|
|
|
|
const MaemoDeployable &deployable)
|
|
|
|
|
{
|
|
|
|
|
m_lastDeployed.insert(DeployablePerHost(deployable, host),
|
|
|
|
|
QDateTime::currentDateTime());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaemoDeviceConfig MaemoDeployStep::deviceConfig() const
|
|
|
|
|
{
|
2010-07-16 17:09:05 +02:00
|
|
|
return deviceConfigModel()->current();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-13 15:24:21 +02:00
|
|
|
void MaemoDeployStep::start()
|
|
|
|
|
{
|
2010-08-11 16:31:59 +02:00
|
|
|
if (!m_canStart) {
|
2010-09-10 12:15:40 +02:00
|
|
|
raiseError(tr("Cannot start deployment, as the clean-up from the last time has not finished yet."));
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
m_cleanupTimer->stop();
|
|
|
|
|
m_stopped = false;
|
2010-07-13 15:24:21 +02:00
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
if (!deviceConfig().isValid()) {
|
2010-07-13 15:24:21 +02:00
|
|
|
raiseError(tr("Deployment failed: No valid device set."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-08-12 18:06:58 +02:00
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
Q_ASSERT(!m_currentDeviceDeployAction);
|
2010-08-11 16:31:59 +02:00
|
|
|
Q_ASSERT(!m_needsInstall);
|
|
|
|
|
Q_ASSERT(m_filesToCopy.isEmpty());
|
|
|
|
|
const MaemoPackageCreationStep * const pStep = packagingStep();
|
2010-08-24 14:49:48 +02:00
|
|
|
const QString hostName = deviceConfig().server.host;
|
2010-08-11 16:31:59 +02:00
|
|
|
if (pStep->isPackagingEnabled()) {
|
|
|
|
|
const MaemoDeployable d(pStep->packageFilePath(), QString());
|
|
|
|
|
if (currentlyNeedsDeployment(hostName, d))
|
|
|
|
|
m_needsInstall = true;
|
|
|
|
|
} else {
|
|
|
|
|
const int deployableCount = m_deployables->deployableCount();
|
|
|
|
|
for (int i = 0; i < deployableCount; ++i) {
|
|
|
|
|
const MaemoDeployable &d = m_deployables->deployableAt(i);
|
|
|
|
|
if (currentlyNeedsDeployment(hostName, d))
|
|
|
|
|
m_filesToCopy << d;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
|
2010-08-11 16:31:59 +02:00
|
|
|
if (m_needsInstall || !m_filesToCopy.isEmpty()) {
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_deployToSysroot)
|
|
|
|
|
installToSysroot();
|
|
|
|
|
else
|
|
|
|
|
connectToDevice();
|
2010-08-11 16:31:59 +02:00
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("All files up to date, no installation necessary."));
|
|
|
|
|
emit done();
|
|
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleConnectionFailure()
|
|
|
|
|
{
|
2010-08-11 16:31:59 +02:00
|
|
|
m_connecting = false;
|
|
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
raiseError(tr("Could not connect to host: %1")
|
|
|
|
|
.arg(m_connection->errorString()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSftpChannelInitialized()
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
const QString filePath = packagingStep()->packageFilePath();
|
|
|
|
|
const QString filePathNative = QDir::toNativeSeparators(filePath);
|
|
|
|
|
const QString fileName = QFileInfo(filePath).fileName();
|
|
|
|
|
const QString remoteFilePath = uploadDir() + QLatin1Char('/') + fileName;
|
|
|
|
|
const SftpJobId job = m_uploader->uploadFile(filePath,
|
|
|
|
|
remoteFilePath, SftpOverwriteExisting);
|
2010-07-13 15:24:21 +02:00
|
|
|
if (job == SftpInvalidJob) {
|
|
|
|
|
raiseError(tr("Upload failed: Could not open file '%1'")
|
2010-08-24 14:49:48 +02:00
|
|
|
.arg(filePathNative));
|
|
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("Started uploading file '%1'.").arg(filePathNative));
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSftpChannelInitializationFailed(const QString &error)
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
2010-08-24 14:49:48 +02:00
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
raiseError(tr("Could not set up SFTP connection: %1").arg(error));
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
void MaemoDeployStep::handleSftpJobFinished(Core::SftpJobId,
|
2010-07-13 15:24:21 +02:00
|
|
|
const QString &error)
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
const QString filePathNative
|
|
|
|
|
= QDir::toNativeSeparators(packagingStep()->packageFilePath());
|
2010-07-13 15:24:21 +02:00
|
|
|
if (!error.isEmpty()) {
|
|
|
|
|
raiseError(tr("Failed to upload file %1: %2")
|
2010-08-24 14:49:48 +02:00
|
|
|
.arg(filePathNative, error));
|
2010-07-13 15:24:21 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writeOutput(tr("Successfully uploaded file '%1'.")
|
2010-08-24 14:49:48 +02:00
|
|
|
.arg(filePathNative));
|
|
|
|
|
const QString remoteFilePath
|
|
|
|
|
= uploadDir() + QLatin1Char('/') + QFileInfo(filePathNative).fileName();
|
2010-10-29 11:41:39 +02:00
|
|
|
runDpkg(remoteFilePath, true);
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
2010-08-11 16:31:59 +02:00
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleMounted()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped) {
|
|
|
|
|
m_mounter->unmount();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_needsInstall) {
|
2010-08-24 14:49:48 +02:00
|
|
|
const QString remoteFilePath = deployMountPoint() + QLatin1Char('/')
|
|
|
|
|
+ QFileInfo(packagingStep()->packageFilePath()).fileName();
|
2010-10-29 11:41:39 +02:00
|
|
|
runDpkg(remoteFilePath, false);
|
2010-08-11 16:31:59 +02:00
|
|
|
} else {
|
2010-08-24 14:49:48 +02:00
|
|
|
copyNextFileToDevice();
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleUnmounted()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped) {
|
2010-08-20 12:50:10 +02:00
|
|
|
m_mounter->resetMountSpecifications();
|
2010-08-11 16:31:59 +02:00
|
|
|
m_canStart = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
switch (m_unmountState) {
|
|
|
|
|
case OldDirsUnmount:
|
2010-10-11 18:12:46 +02:00
|
|
|
#if 0 // TODO: Disabled for 2.1. Re-enable later or throw away for good.
|
2010-08-24 14:49:48 +02:00
|
|
|
if (toolChain()->allowsRemoteMounts())
|
|
|
|
|
setupMount();
|
|
|
|
|
else
|
2010-10-11 18:12:46 +02:00
|
|
|
#endif
|
2010-08-24 14:49:48 +02:00
|
|
|
prepareSftpConnection();
|
|
|
|
|
break;
|
|
|
|
|
case CurrentDirsUnmount:
|
2010-11-02 10:24:50 +01:00
|
|
|
// m_mounter->mount(); TODO: See above
|
2010-08-24 14:49:48 +02:00
|
|
|
break;
|
|
|
|
|
case CurrentMountsUnmount:
|
2010-08-20 12:50:10 +02:00
|
|
|
writeOutput(tr("Deployment finished."));
|
|
|
|
|
emit done();
|
2010-08-24 14:49:48 +02:00
|
|
|
break;
|
2010-08-20 12:50:10 +02:00
|
|
|
}
|
2010-08-24 14:49:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleMountError(const QString &errorMsg)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
m_canStart = true;
|
|
|
|
|
else
|
|
|
|
|
raiseError(errorMsg);
|
|
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
|
2010-08-26 11:17:40 +02:00
|
|
|
void MaemoDeployStep::handleMountDebugOutput(const QString &output)
|
|
|
|
|
{
|
|
|
|
|
if (!m_stopped)
|
|
|
|
|
writeOutput(output, ErrorOutput);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
void MaemoDeployStep::setupMount()
|
|
|
|
|
{
|
2010-08-20 12:50:10 +02:00
|
|
|
Q_ASSERT(m_needsInstall || !m_filesToCopy.isEmpty());
|
|
|
|
|
m_mounter->resetMountSpecifications();
|
2010-08-23 15:54:35 +02:00
|
|
|
m_mounter->setToolchain(toolChain());
|
2010-08-20 12:50:10 +02:00
|
|
|
if (m_needsInstall) {
|
|
|
|
|
const QString localDir
|
|
|
|
|
= QFileInfo(packagingStep()->packageFilePath()).absolutePath();
|
|
|
|
|
const MaemoMountSpecification mountSpec(localDir, deployMountPoint());
|
|
|
|
|
if (!addMountSpecification(mountSpec))
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
2010-08-11 16:31:59 +02:00
|
|
|
#ifdef Q_OS_WIN
|
2010-08-20 12:50:10 +02:00
|
|
|
bool drivesToMount[26];
|
2010-09-09 09:58:17 +02:00
|
|
|
qFill(drivesToMount, drivesToMount + sizeof drivesToMount / sizeof drivesToMount[0], false);
|
2010-08-20 12:50:10 +02:00
|
|
|
for (int i = 0; i < m_filesToCopy.count(); ++i) {
|
|
|
|
|
const QString localDir
|
|
|
|
|
= QFileInfo(m_filesToCopy.at(i).localFilePath).canonicalPath();
|
|
|
|
|
const char driveLetter = localDir.at(0).toLower().toLatin1();
|
|
|
|
|
if (driveLetter < 'a' || driveLetter > 'z') {
|
|
|
|
|
qWarning("Weird: drive letter is '%c'.", driveLetter);
|
|
|
|
|
continue;
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
|
|
|
|
|
const int index = driveLetter - 'a';
|
|
|
|
|
if (drivesToMount[index])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const QString mountPoint = deployMountPoint() + QLatin1Char('/')
|
|
|
|
|
+ QLatin1Char(driveLetter);
|
|
|
|
|
const MaemoMountSpecification mountSpec(localDir.left(3),
|
|
|
|
|
mountPoint);
|
|
|
|
|
if (!addMountSpecification(mountSpec))
|
2010-08-13 15:25:22 +02:00
|
|
|
return;
|
2010-08-20 12:50:10 +02:00
|
|
|
drivesToMount[index] = true;
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
#else
|
|
|
|
|
if (!addMountSpecification(MaemoMountSpecification(QLatin1String("/"),
|
|
|
|
|
deployMountPoint())))
|
|
|
|
|
return;
|
|
|
|
|
#endif
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
m_unmountState = CurrentDirsUnmount;
|
|
|
|
|
m_mounter->unmount();
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
void MaemoDeployStep::prepareSftpConnection()
|
2010-08-11 16:31:59 +02:00
|
|
|
{
|
2010-10-03 10:38:21 +02:00
|
|
|
// TODO: Close channel when upload has finished/failed/etc.
|
|
|
|
|
if (m_uploader) {
|
|
|
|
|
disconnect(m_uploader.data(), 0, this, 0);
|
|
|
|
|
m_uploader->closeChannel();
|
|
|
|
|
}
|
2010-08-24 14:49:48 +02:00
|
|
|
m_uploader = m_connection->createSftpChannel();
|
|
|
|
|
connect(m_uploader.data(), SIGNAL(initialized()), this,
|
|
|
|
|
SLOT(handleSftpChannelInitialized()));
|
|
|
|
|
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
|
|
|
|
|
SLOT(handleSftpChannelInitializationFailed(QString)));
|
|
|
|
|
connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)),
|
|
|
|
|
this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString)));
|
|
|
|
|
m_uploader->initialize();
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-20 12:50:10 +02:00
|
|
|
void MaemoDeployStep::installToSysroot()
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_needsInstall) {
|
|
|
|
|
writeOutput(tr("Installing package to sysroot ..."));
|
|
|
|
|
const MaemoToolChain * const tc = toolChain();
|
|
|
|
|
const QStringList args = QStringList() << QLatin1String("-t")
|
|
|
|
|
<< tc->targetName() << QLatin1String("xdpkg") << QLatin1String("-i")
|
|
|
|
|
<< packagingStep()->packageFilePath();
|
|
|
|
|
m_sysrootInstaller->start(tc->madAdminCommand(), args);
|
|
|
|
|
if (!m_sysrootInstaller->waitForStarted()) {
|
|
|
|
|
writeOutput(tr("Installation to sysroot failed, continuing anyway."),
|
|
|
|
|
ErrorMessageOutput);
|
|
|
|
|
connectToDevice();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("Copying files to sysroot ..."));
|
|
|
|
|
Q_ASSERT(!m_filesToCopy.isEmpty());
|
|
|
|
|
QDir sysRootDir(toolChain()->sysrootRoot());
|
|
|
|
|
foreach (const MaemoDeployable &d, m_filesToCopy) {
|
|
|
|
|
const QLatin1Char sep('/');
|
|
|
|
|
const QString targetFilePath = toolChain()->sysrootRoot() + sep
|
|
|
|
|
+ d.remoteDir + sep + QFileInfo(d.localFilePath).fileName();
|
2010-08-26 13:17:40 +02:00
|
|
|
sysRootDir.mkpath(d.remoteDir.mid(1));
|
|
|
|
|
QFile::remove(targetFilePath);
|
|
|
|
|
if (!QFile::copy(d.localFilePath, targetFilePath)) {
|
2010-08-24 14:49:48 +02:00
|
|
|
writeOutput(tr("Sysroot installation failed: "
|
|
|
|
|
"Could not copy '%1' to '%2'. Continuing anyway.")
|
|
|
|
|
.arg(QDir::toNativeSeparators(d.localFilePath),
|
|
|
|
|
QDir::toNativeSeparators(targetFilePath)),
|
|
|
|
|
ErrorMessageOutput);
|
|
|
|
|
}
|
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
connectToDevice();
|
2010-08-20 12:50:10 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSysrootInstallerFinished()
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-20 12:50:10 +02:00
|
|
|
if (m_sysrootInstaller->error() != QProcess::UnknownError
|
|
|
|
|
|| m_sysrootInstaller->exitCode() != 0) {
|
|
|
|
|
writeOutput(tr("Installation to sysroot failed, continuing anyway."),
|
|
|
|
|
ErrorMessageOutput);
|
|
|
|
|
}
|
2010-08-24 14:49:48 +02:00
|
|
|
connectToDevice();
|
2010-08-20 12:50:10 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
void MaemoDeployStep::connectToDevice()
|
|
|
|
|
{
|
|
|
|
|
m_connecting = false;
|
|
|
|
|
const bool canReUse = m_connection
|
|
|
|
|
&& m_connection->state() == SshConnection::Connected
|
|
|
|
|
&& m_connection->connectionParameters() == deviceConfig().server;
|
|
|
|
|
if (!canReUse)
|
|
|
|
|
m_connection = SshConnection::create();
|
|
|
|
|
connect(m_connection.data(), SIGNAL(connected()), this,
|
|
|
|
|
SLOT(handleConnected()));
|
2010-10-06 10:53:33 +02:00
|
|
|
connect(m_connection.data(), SIGNAL(error(Core::SshError)), this,
|
2010-08-24 14:49:48 +02:00
|
|
|
SLOT(handleConnectionFailure()));
|
|
|
|
|
if (canReUse) {
|
|
|
|
|
unmountOldDirs();
|
|
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("Connecting to device..."));
|
|
|
|
|
m_connecting = true;
|
|
|
|
|
m_connection->connectToHost(deviceConfig().server);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleConnected()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped) {
|
|
|
|
|
m_canStart = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unmountOldDirs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::unmountOldDirs()
|
|
|
|
|
{
|
|
|
|
|
m_unmountState = OldDirsUnmount;
|
|
|
|
|
m_mounter->setConnection(m_connection);
|
|
|
|
|
m_mounter->unmount();
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-29 11:41:39 +02:00
|
|
|
void MaemoDeployStep::runDpkg(const QString &packageFilePath,
|
|
|
|
|
bool removeAfterInstall)
|
2010-08-20 12:50:10 +02:00
|
|
|
{
|
|
|
|
|
writeOutput(tr("Installing package to device..."));
|
2010-10-29 11:41:39 +02:00
|
|
|
QByteArray cmd = MaemoGlobal::remoteSudo().toUtf8() + " dpkg -i "
|
2010-08-24 14:49:48 +02:00
|
|
|
+ packageFilePath.toUtf8();
|
2010-10-29 11:41:39 +02:00
|
|
|
if (removeAfterInstall)
|
|
|
|
|
cmd += " && rm " + packageFilePath.toUtf8() + " || :";
|
2010-08-20 12:50:10 +02:00
|
|
|
m_deviceInstaller = m_connection->createRemoteProcess(cmd);
|
|
|
|
|
connect(m_deviceInstaller.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleInstallationFinished(int)));
|
|
|
|
|
connect(m_deviceInstaller.data(), SIGNAL(outputAvailable(QByteArray)),
|
|
|
|
|
this, SLOT(handleDeviceInstallerOutput(QByteArray)));
|
|
|
|
|
connect(m_deviceInstaller.data(),
|
|
|
|
|
SIGNAL(errorOutputAvailable(QByteArray)), this,
|
|
|
|
|
SLOT(handleDeviceInstallerErrorOutput(QByteArray)));
|
|
|
|
|
m_deviceInstaller->start();
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-11 16:31:59 +02:00
|
|
|
void MaemoDeployStep::handleProgressReport(const QString &progressMsg)
|
|
|
|
|
{
|
|
|
|
|
writeOutput(progressMsg);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
void MaemoDeployStep::copyNextFileToDevice()
|
2010-08-11 16:31:59 +02:00
|
|
|
{
|
|
|
|
|
Q_ASSERT(!m_filesToCopy.isEmpty());
|
2010-08-24 14:49:48 +02:00
|
|
|
Q_ASSERT(!m_currentDeviceDeployAction);
|
2010-08-11 16:31:59 +02:00
|
|
|
const MaemoDeployable d = m_filesToCopy.takeFirst();
|
|
|
|
|
QString sourceFilePath = deployMountPoint();
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
const QString localFilePath = QDir::fromNativeSeparators(d.localFilePath);
|
|
|
|
|
sourceFilePath += QLatin1Char('/') + localFilePath.at(0).toLower()
|
|
|
|
|
+ localFilePath.mid(2);
|
|
|
|
|
#else
|
|
|
|
|
sourceFilePath += d.localFilePath;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
QString command = QString::fromLatin1("%1 cp -r %2 %3")
|
|
|
|
|
.arg(MaemoGlobal::remoteSudo(), sourceFilePath,
|
|
|
|
|
d.remoteDir + QLatin1Char('/'));
|
|
|
|
|
SshRemoteProcess::Ptr copyProcess
|
|
|
|
|
= m_connection->createRemoteProcess(command.toUtf8());
|
|
|
|
|
connect(copyProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)),
|
2010-08-20 12:50:10 +02:00
|
|
|
this, SLOT(handleDeviceInstallerErrorOutput(QByteArray)));
|
2010-08-11 16:31:59 +02:00
|
|
|
connect(copyProcess.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleCopyProcessFinished(int)));
|
2010-08-24 14:49:48 +02:00
|
|
|
m_currentDeviceDeployAction.reset(new DeviceDeployAction(d, copyProcess));
|
2010-08-11 16:31:59 +02:00
|
|
|
writeOutput(tr("Copying file '%1' to path '%2' on the device...")
|
|
|
|
|
.arg(d.localFilePath, d.remoteDir));
|
|
|
|
|
copyProcess->start();
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-13 15:25:22 +02:00
|
|
|
bool MaemoDeployStep::addMountSpecification(const MaemoMountSpecification &mountSpec)
|
|
|
|
|
{
|
|
|
|
|
if (!m_mounter->addMountSpecification(mountSpec, true)) {
|
|
|
|
|
raiseError(tr("Device has not enough free ports for deployment."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-11 16:31:59 +02:00
|
|
|
void MaemoDeployStep::handleCopyProcessFinished(int exitStatus)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped) {
|
|
|
|
|
m_mounter->unmount();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-24 14:49:48 +02:00
|
|
|
Q_ASSERT(m_currentDeviceDeployAction);
|
|
|
|
|
const QString localFilePath = m_currentDeviceDeployAction->first.localFilePath;
|
2010-08-11 16:31:59 +02:00
|
|
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
2010-08-24 14:49:48 +02:00
|
|
|
|| m_currentDeviceDeployAction->second->exitCode() != 0) {
|
2010-08-11 16:31:59 +02:00
|
|
|
raiseError(tr("Copying file '%1' failed.").arg(localFilePath));
|
|
|
|
|
m_mounter->unmount();
|
2010-08-24 14:49:48 +02:00
|
|
|
m_currentDeviceDeployAction.reset(0);
|
2010-08-11 16:31:59 +02:00
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("Successfully copied file '%1'.").arg(localFilePath));
|
|
|
|
|
setDeployed(m_connection->connectionParameters().host,
|
2010-08-24 14:49:48 +02:00
|
|
|
m_currentDeviceDeployAction->first);
|
|
|
|
|
m_currentDeviceDeployAction.reset(0);
|
2010-08-11 16:31:59 +02:00
|
|
|
if (m_filesToCopy.isEmpty()) {
|
|
|
|
|
writeOutput(tr("All files copied."));
|
2010-08-20 12:50:10 +02:00
|
|
|
m_unmountState = CurrentMountsUnmount;
|
2010-08-11 16:31:59 +02:00
|
|
|
m_mounter->unmount();
|
|
|
|
|
} else {
|
2010-08-24 14:49:48 +02:00
|
|
|
copyNextFileToDevice();
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleCleanupTimeout()
|
|
|
|
|
{
|
2010-08-24 14:49:48 +02:00
|
|
|
m_cleanupTimer->stop();
|
2010-08-11 16:31:59 +02:00
|
|
|
if (!m_canStart) {
|
|
|
|
|
m_canStart = true;
|
|
|
|
|
disconnect(m_connection.data(), 0, this, 0);
|
2010-08-20 12:50:10 +02:00
|
|
|
if (m_deviceInstaller)
|
|
|
|
|
disconnect(m_deviceInstaller.data(), 0, this, 0);
|
2010-08-24 14:49:48 +02:00
|
|
|
if (m_currentDeviceDeployAction) {
|
|
|
|
|
disconnect(m_currentDeviceDeployAction->second.data(), 0, this, 0);
|
|
|
|
|
m_currentDeviceDeployAction.reset(0);
|
|
|
|
|
}
|
2010-08-11 16:31:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString MaemoDeployStep::deployMountPoint() const
|
|
|
|
|
{
|
|
|
|
|
return MaemoGlobal::homeDirOnDevice(deviceConfig().server.uname)
|
|
|
|
|
+ QLatin1String("/deployMountPoint");
|
|
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
|
|
|
|
|
const MaemoToolChain *MaemoDeployStep::toolChain() const
|
|
|
|
|
{
|
|
|
|
|
const Qt4BuildConfiguration * const bc
|
|
|
|
|
= static_cast<Qt4BuildConfiguration *>(buildConfiguration());
|
|
|
|
|
return static_cast<MaemoToolChain *>(bc->toolChain());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSysrootInstallerOutput()
|
|
|
|
|
{
|
|
|
|
|
if (!m_stopped) {
|
|
|
|
|
writeOutput(QString::fromLocal8Bit(m_sysrootInstaller->readAllStandardOutput()),
|
|
|
|
|
NormalOutput);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSysrootInstallerErrorOutput()
|
|
|
|
|
{
|
|
|
|
|
if (!m_stopped) {
|
|
|
|
|
writeOutput(QString::fromLocal8Bit(m_sysrootInstaller->readAllStandardError()),
|
|
|
|
|
BuildStep::ErrorOutput);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleInstallationFinished(int exitStatus)
|
|
|
|
|
{
|
2010-08-11 16:31:59 +02:00
|
|
|
if (m_stopped) {
|
|
|
|
|
m_mounter->unmount();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
2010-08-20 12:50:10 +02:00
|
|
|
|| m_deviceInstaller->exitCode() != 0) {
|
2010-08-11 16:31:59 +02:00
|
|
|
raiseError(tr("Installing package failed."));
|
|
|
|
|
} else {
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
setDeployed(m_connection->connectionParameters().host,
|
|
|
|
|
MaemoDeployable(packagingStep()->packageFilePath(), QString()));
|
|
|
|
|
writeOutput(tr("Package installed."));
|
|
|
|
|
}
|
2010-08-20 12:50:10 +02:00
|
|
|
m_unmountState = CurrentMountsUnmount;
|
2010-08-11 16:31:59 +02:00
|
|
|
m_mounter->unmount();
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-20 12:50:10 +02:00
|
|
|
void MaemoDeployStep::handleDeviceInstallerOutput(const QByteArray &output)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
2010-08-20 12:50:10 +02:00
|
|
|
writeOutput(QString::fromUtf8(output), NormalOutput);
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-20 12:50:10 +02:00
|
|
|
void MaemoDeployStep::handleDeviceInstallerErrorOutput(const QByteArray &output)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
2010-08-20 12:50:10 +02:00
|
|
|
writeOutput(QString::fromUtf8(output), ErrorOutput);
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaemoDeployEventHandler::MaemoDeployEventHandler(MaemoDeployStep *deployStep,
|
|
|
|
|
QFutureInterface<bool> &future)
|
|
|
|
|
: m_deployStep(deployStep), m_future(future), m_eventLoop(new QEventLoop)
|
|
|
|
|
{
|
|
|
|
|
connect(m_deployStep, SIGNAL(done()), this, SLOT(handleDeployingDone()));
|
|
|
|
|
connect(m_deployStep, SIGNAL(error()), this, SLOT(handleDeployingFailed()));
|
|
|
|
|
QTimer cancelChecker;
|
|
|
|
|
connect(&cancelChecker, SIGNAL(timeout()), this, SLOT(checkForCanceled()));
|
|
|
|
|
cancelChecker.start(500);
|
|
|
|
|
future.reportResult(m_eventLoop->exec() == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployEventHandler::handleDeployingDone()
|
|
|
|
|
{
|
|
|
|
|
m_eventLoop->exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployEventHandler::handleDeployingFailed()
|
|
|
|
|
{
|
|
|
|
|
m_eventLoop->exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployEventHandler::checkForCanceled()
|
|
|
|
|
{
|
|
|
|
|
if (m_future.isCanceled())
|
|
|
|
|
handleDeployingFailed();
|
2010-07-12 11:07:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Qt4ProjectManager
|