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"
|
|
|
|
|
#include "maemodeployables.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"
|
|
|
|
|
#include "maemorunconfiguration.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>
|
|
|
|
|
|
|
|
|
|
#include <QtCore/QCryptographicHash>
|
|
|
|
|
#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 {
|
|
|
|
|
|
|
|
|
|
const QLatin1String MaemoDeployStep::Id("Qt4ProjectManager.MaemoDeployStep");
|
|
|
|
|
|
|
|
|
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc)
|
2010-07-14 12:21:35 +02:00
|
|
|
: BuildStep(bc, Id), m_deployables(new MaemoDeployables(this))
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc,
|
|
|
|
|
MaemoDeployStep *other)
|
2010-07-14 12:21:35 +02:00
|
|
|
: BuildStep(bc, other), m_deployables(new MaemoDeployables(this)),
|
|
|
|
|
m_lastDeployed(other->m_lastDeployed)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
|
|
|
|
ctor();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 12:21:35 +02:00
|
|
|
MaemoDeployStep::~MaemoDeployStep()
|
|
|
|
|
{
|
|
|
|
|
delete m_deployables;
|
|
|
|
|
}
|
2010-07-13 15:24:21 +02:00
|
|
|
|
|
|
|
|
void MaemoDeployStep::ctor()
|
2010-07-12 11:07:36 +02:00
|
|
|
{
|
2010-07-16 17:09:05 +02:00
|
|
|
m_deviceConfigModel = new MaemoDeviceConfigListModel(this);
|
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-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-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
|
|
|
|
|
= MaemoGlobal::buildStep<MaemoPackageCreationStep>(buildConfiguration());
|
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)
|
|
|
|
|
{
|
|
|
|
|
emit addTask(Task(Task::Error, errorString, QString(), -1,
|
|
|
|
|
Constants::TASK_CATEGORY_BUILDSYSTEM));
|
|
|
|
|
stop();
|
|
|
|
|
emit error();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::writeOutput(const QString &text,
|
2010-07-15 10:29:38 +02:00
|
|
|
ProjectExplorer::BuildStep::OutputFormat format)
|
2010-07-13 15:24:21 +02:00
|
|
|
{
|
|
|
|
|
emit addOutput(text, format);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::stop()
|
|
|
|
|
{
|
|
|
|
|
if (m_installer && m_installer->isRunning()) {
|
|
|
|
|
disconnect(m_installer.data(), 0, this, 0);
|
|
|
|
|
} else if (!m_uploadsInProgress.isEmpty() || !m_linksInProgress.isEmpty()) {
|
|
|
|
|
m_uploadsInProgress.clear();
|
|
|
|
|
m_linksInProgress.clear();
|
|
|
|
|
disconnect(m_uploader.data(), 0, this, 0);
|
2010-07-14 08:33:17 +02:00
|
|
|
m_uploader->closeChannel();
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
if (m_connection)
|
|
|
|
|
disconnect(m_connection.data(), 0, this, 0);
|
|
|
|
|
m_stopped = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaemoDeviceConfigListModel *MaemoDeployStep::deviceConfigModel() const
|
|
|
|
|
{
|
|
|
|
|
const MaemoRunConfiguration * const rc =
|
|
|
|
|
qobject_cast<const MaemoRunConfiguration *>(buildConfiguration()
|
|
|
|
|
->target()->activeRunConfiguration());
|
|
|
|
|
return rc ? rc->deviceConfigModel() : m_deviceConfigModel;
|
2010-07-13 15:24:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::start()
|
|
|
|
|
{
|
|
|
|
|
m_stopped = false;
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// TODO: Re-use if possible (disconnect + reconnect).
|
|
|
|
|
if (m_connection)
|
|
|
|
|
disconnect(m_connection.data(), 0, this, 0);
|
|
|
|
|
m_connection = SshConnection::create();
|
|
|
|
|
|
|
|
|
|
const MaemoDeviceConfig &devConfig = deviceConfig();
|
|
|
|
|
if (!devConfig.isValid()) {
|
|
|
|
|
raiseError(tr("Deployment failed: No valid device set."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
connect(m_connection.data(), SIGNAL(connected()), this,
|
|
|
|
|
SLOT(handleConnected()));
|
|
|
|
|
connect(m_connection.data(), SIGNAL(error(SshError)), this,
|
|
|
|
|
SLOT(handleConnectionFailure()));
|
|
|
|
|
m_connection->connectToHost(devConfig.server);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleConnected()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// TODO: If nothing to deploy, skip this step.
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleConnectionFailure()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
raiseError(tr("Could not connect to host: %1")
|
|
|
|
|
.arg(m_connection->errorString()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSftpChannelInitialized()
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_uploadsInProgress.clear();
|
|
|
|
|
m_linksInProgress.clear();
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
const MaemoPackageCreationStep * const pStep = packagingStep();
|
|
|
|
|
const QString hostName = m_connection->connectionParameters().host;
|
|
|
|
|
if (pStep->isPackagingEnabled()) {
|
2010-07-13 16:49:30 +02:00
|
|
|
const MaemoDeployable d(pStep->packageFilePath(), uploadDir());
|
2010-07-13 15:24:21 +02:00
|
|
|
if (currentlyNeedsDeployment(hostName, d)) {
|
|
|
|
|
if (!deploy(MaemoDeployable(d)))
|
|
|
|
|
return;
|
|
|
|
|
m_needsInstall = true;
|
|
|
|
|
} else {
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2010-07-14 12:21:35 +02:00
|
|
|
const int deployableCount = m_deployables->deployableCount();
|
2010-07-13 15:24:21 +02:00
|
|
|
for (int i = 0; i < deployableCount; ++i) {
|
2010-07-14 12:21:35 +02:00
|
|
|
const MaemoDeployable &d = m_deployables->deployableAt(i);
|
2010-07-13 15:24:21 +02:00
|
|
|
if (currentlyNeedsDeployment(hostName, d)
|
|
|
|
|
&& !deploy(MaemoDeployable(d)))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_needsInstall = false;
|
|
|
|
|
}
|
|
|
|
|
if (m_uploadsInProgress.isEmpty())
|
|
|
|
|
emit done();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MaemoDeployStep::deploy(const MaemoDeployable &deployable)
|
|
|
|
|
{
|
|
|
|
|
const QString fileName = QFileInfo(deployable.localFilePath).fileName();
|
|
|
|
|
const QString remoteFilePath = deployable.remoteDir + '/' + fileName;
|
|
|
|
|
const QString uploadFilePath = uploadDir() + '/' + fileName + '.'
|
|
|
|
|
+ QCryptographicHash::hash(remoteFilePath.toUtf8(),
|
|
|
|
|
QCryptographicHash::Md5).toHex();
|
|
|
|
|
const SftpJobId job = m_uploader->uploadFile(deployable.localFilePath,
|
|
|
|
|
uploadFilePath, SftpOverwriteExisting);
|
|
|
|
|
if (job == SftpInvalidJob) {
|
|
|
|
|
raiseError(tr("Upload failed: Could not open file '%1'")
|
|
|
|
|
.arg(deployable.localFilePath));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
writeOutput(tr("Started uploading file '%1'.").arg(deployable.localFilePath));
|
|
|
|
|
m_uploadsInProgress.insert(job, DeployInfo(deployable, uploadFilePath));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSftpChannelInitializationFailed(const QString &error)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
raiseError(tr("Could not set up SFTP connection: %1").arg(error));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleSftpJobFinished(Core::SftpJobId job,
|
|
|
|
|
const QString &error)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QMap<SftpJobId, DeployInfo>::Iterator it = m_uploadsInProgress.find(job);
|
|
|
|
|
if (it == m_uploadsInProgress.end()) {
|
|
|
|
|
qWarning("%s: Job %u not found in map.", Q_FUNC_INFO, job);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DeployInfo &deployInfo = it.value();
|
|
|
|
|
if (!error.isEmpty()) {
|
|
|
|
|
raiseError(tr("Failed to upload file %1: %2")
|
|
|
|
|
.arg(deployInfo.first.localFilePath, error));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writeOutput(tr("Successfully uploaded file '%1'.")
|
|
|
|
|
.arg(deployInfo.first.localFilePath));
|
|
|
|
|
const QString remoteFilePath = deployInfo.first.remoteDir + '/'
|
|
|
|
|
+ QFileInfo(deployInfo.first.localFilePath).fileName();
|
2010-07-13 17:00:12 +02:00
|
|
|
QByteArray linkCommand = MaemoGlobal::remoteSudo().toUtf8() + " ln -sf "
|
2010-07-13 15:24:21 +02:00
|
|
|
+ deployInfo.second.toUtf8() + ' ' + remoteFilePath.toUtf8();
|
|
|
|
|
SshRemoteProcess::Ptr linkProcess
|
|
|
|
|
= m_connection->createRemoteProcess(linkCommand);
|
|
|
|
|
connect(linkProcess.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleLinkProcessFinished(int)));
|
|
|
|
|
m_linksInProgress.insert(linkProcess, deployInfo.first);
|
|
|
|
|
linkProcess->start();
|
|
|
|
|
m_uploadsInProgress.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleLinkProcessFinished(int exitStatus)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
SshRemoteProcess * const proc = static_cast<SshRemoteProcess *>(sender());
|
|
|
|
|
|
|
|
|
|
// TODO: List instead of map? We can't use it for lookup anyway.
|
|
|
|
|
QMap<SshRemoteProcess::Ptr, MaemoDeployable>::Iterator it;
|
|
|
|
|
for (it = m_linksInProgress.begin(); it != m_linksInProgress.end(); ++it) {
|
|
|
|
|
if (it.key().data() == proc)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (it == m_linksInProgress.end()) {
|
|
|
|
|
qWarning("%s: Remote process %p not found in process list.",
|
|
|
|
|
Q_FUNC_INFO, proc);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MaemoDeployable &deployable = it.value();
|
|
|
|
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
|
|
|
|
|| proc->exitCode() != 0) {
|
|
|
|
|
raiseError(tr("Deployment failed for file '%1': "
|
|
|
|
|
"Could not create link '%2' on remote system.")
|
|
|
|
|
.arg(deployable.localFilePath, deployable.remoteDir + '/'
|
|
|
|
|
+ QFileInfo(deployable.localFilePath).fileName()));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setDeployed(m_connection->connectionParameters().host, it.value());
|
|
|
|
|
m_linksInProgress.erase(it);
|
|
|
|
|
if (m_linksInProgress.isEmpty() && m_uploadsInProgress.isEmpty()) {
|
|
|
|
|
if (m_needsInstall) {
|
|
|
|
|
writeOutput(tr("Installing package ..."));
|
2010-07-13 16:49:30 +02:00
|
|
|
const QString packageFileName
|
|
|
|
|
= QFileInfo(packagingStep()->packageFilePath()).fileName();
|
2010-07-13 17:00:12 +02:00
|
|
|
const QByteArray cmd = MaemoGlobal::remoteSudo().toUtf8()
|
|
|
|
|
+ " dpkg -i " + packageFileName.toUtf8();
|
2010-07-13 15:24:21 +02:00
|
|
|
m_installer = m_connection->createRemoteProcess(cmd);
|
|
|
|
|
connect(m_installer.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleInstallationFinished(int)));
|
|
|
|
|
connect(m_installer.data(), SIGNAL(outputAvailable(QByteArray)),
|
|
|
|
|
this, SLOT(handleInstallerOutput(QByteArray)));
|
|
|
|
|
connect(m_installer.data(),
|
|
|
|
|
SIGNAL(errorOutputAvailable(QByteArray)), this,
|
|
|
|
|
SLOT(handleInstallerErrorOutput(QByteArray)));
|
|
|
|
|
m_installer->start();
|
|
|
|
|
} else {
|
|
|
|
|
emit done();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleInstallationFinished(int exitStatus)
|
|
|
|
|
{
|
|
|
|
|
if (m_stopped)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (exitStatus != SshRemoteProcess::ExitedNormally
|
|
|
|
|
|| m_installer->exitCode() != 0) {
|
|
|
|
|
raiseError(tr("Installing package failed."));
|
|
|
|
|
} else {
|
|
|
|
|
writeOutput(tr("Package installation finished."));
|
|
|
|
|
emit done();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleInstallerOutput(const QByteArray &output)
|
|
|
|
|
{
|
|
|
|
|
writeOutput(QString::fromUtf8(output));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MaemoDeployStep::handleInstallerErrorOutput(const QByteArray &output)
|
|
|
|
|
{
|
2010-07-15 10:29:38 +02:00
|
|
|
writeOutput(output, BuildStep::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
|