Commit e86b16cf authored by Christian Kandeler's avatar Christian Kandeler
Browse files

Maemo: Add direct SFTP deployment method.

Not used yet.
parent 63ebdb36
......@@ -34,6 +34,7 @@
#include "maemodeploystepfactory.h"
#include "maemodeploybymountstep.h"
#include "maemodirectdeviceuploadstep.h"
#include "maemoglobal.h"
#include "maemoinstalltosysrootstep.h"
#include "maemouploadandinstalldeploystep.h"
......@@ -104,6 +105,8 @@ QString MaemoDeployStepFactory::displayNameForId(const QString &id) const
return MaemoInstallRpmPackageToSysrootStep::DisplayName;
else if (id == MaemoCopyToSysrootStep::Id)
return MaemoCopyToSysrootStep::DisplayName;
else if (id == MaemoDirectDeviceUploadStep::Id)
return MaemoDirectDeviceUploadStep::DisplayName;
return QString();
}
......@@ -135,6 +138,8 @@ BuildStep *MaemoDeployStepFactory::create(BuildStepList *parent, const QString &
return new MaemoUploadAndInstallRpmPackageStep(parent);
} else if (id == MaemoUploadAndInstallTarPackageStep::Id) {
return new MaemoUploadAndInstallTarPackageStep(parent);
} else if (id == MaemoDirectDeviceUploadStep::Id) {
return new MaemoDirectDeviceUploadStep(parent);
}
return 0;
......@@ -189,6 +194,9 @@ BuildStep *MaemoDeployStepFactory::clone(BuildStepList *parent, BuildStep *produ
} else if (product->id() == MaemoCopyToSysrootStep::Id) {
return new MaemoCopyToSysrootStep(parent,
qobject_cast<MaemoCopyToSysrootStep *>(product));
} else if (product->id() == MaemoDirectDeviceUploadStep::Id) {
return new MaemoDirectDeviceUploadStep(parent,
qobject_cast<MaemoDirectDeviceUploadStep *>(product));
}
return 0;
}
......
#include "maemodirectdeviceuploadstep.h"
#include "maemodeployable.h"
#include "maemoglobal.h"
#include "qt4maemodeployconfiguration.h"
#include <utils/ssh/sftpchannel.h>
#include <utils/ssh/sshremoteprocess.h>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#define ASSERT_BASE_STATE(state) ASSERT_STATE_GENERIC(BaseState, state, baseState())
#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(ExtendedState, state, m_extendedState)
using namespace ProjectExplorer;
using namespace Utils;
namespace Qt4ProjectManager {
namespace Internal {
MaemoDirectDeviceUploadStep::MaemoDirectDeviceUploadStep(BuildStepList *parent)
: AbstractMaemoDeployStep(parent, Id)
{
ctor();
}
MaemoDirectDeviceUploadStep::MaemoDirectDeviceUploadStep(BuildStepList *parent,
MaemoDirectDeviceUploadStep *other)
: AbstractMaemoDeployStep(parent, other)
{
ctor();
}
MaemoDirectDeviceUploadStep::~MaemoDirectDeviceUploadStep() {}
void MaemoDirectDeviceUploadStep::ctor()
{
setDefaultDisplayName(DisplayName);
m_extendedState = Inactive;
}
bool MaemoDirectDeviceUploadStep::isDeploymentPossibleInternal(QString &whyNot) const
{
Q_UNUSED(whyNot);
return true;
}
bool MaemoDirectDeviceUploadStep::isDeploymentNeeded(const QString &hostName) const
{
m_filesToUpload.clear();
const QSharedPointer<MaemoDeployables> deployables
= maemoDeployConfig()->deployables();
const int deployableCount = deployables->deployableCount();
for (int i = 0; i < deployableCount; ++i)
checkDeploymentNeeded(hostName, deployables->deployableAt(i));
return !m_filesToUpload.isEmpty();
}
void MaemoDirectDeviceUploadStep::checkDeploymentNeeded(const QString &hostName,
const MaemoDeployable &deployable) const
{
QFileInfo fileInfo(deployable.localFilePath);
if (fileInfo.isDir()) {
const QStringList files = QDir(deployable.localFilePath)
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
if (files.isEmpty() && currentlyNeedsDeployment(hostName, deployable))
m_filesToUpload << deployable;
foreach (const QString &fileName, files) {
const QString localFilePath = deployable.localFilePath
+ QLatin1Char('/') + fileName;
const QString remoteDir = deployable.remoteDir + QLatin1Char('/')
+ fileInfo.fileName();
checkDeploymentNeeded(hostName,
MaemoDeployable(localFilePath, remoteDir));
}
} else if (currentlyNeedsDeployment(hostName, deployable)) {
m_filesToUpload << deployable;
}
}
void MaemoDirectDeviceUploadStep::startInternal()
{
Q_ASSERT(m_extendedState == Inactive);
m_uploader = connection()->createSftpChannel();
connect(m_uploader.data(), SIGNAL(initialized()),
SLOT(handleSftpInitialized()));
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)),
SLOT(handleSftpInitializationFailed(QString)));
m_uploader->initialize();
m_extendedState = InitializingSftp;
}
void MaemoDirectDeviceUploadStep::handleSftpInitializationFailed(const QString &errorMessage)
{
ASSERT_STATE(QList<ExtendedState>() << Inactive << InitializingSftp);
if (m_extendedState == InitializingSftp) {
raiseError(tr("SFTP initialization failed: %1").arg(errorMessage));
setFinished();
}
}
void MaemoDirectDeviceUploadStep::handleSftpInitialized()
{
ASSERT_STATE(QList<ExtendedState>() << Inactive << InitializingSftp);
if (m_extendedState == InitializingSftp) {
Q_ASSERT(!m_filesToUpload.isEmpty());
connect(m_uploader.data(), SIGNAL(finished(Utils::SftpJobId, QString)),
SLOT(handleUploadFinished(Utils::SftpJobId,QString)));
uploadNextFile();
}
}
void MaemoDirectDeviceUploadStep::uploadNextFile()
{
if (m_filesToUpload.isEmpty()) {
writeOutput(tr("All files successfully deployed."));
setFinished();
return;
}
const MaemoDeployable &d = m_filesToUpload.first();
QString dirToCreate = d.remoteDir;
QFileInfo fi(d.localFilePath);
if (fi.isDir())
dirToCreate += QLatin1Char('/') + fi.fileName();
const QByteArray command = "mkdir -p " + dirToCreate.toUtf8();
m_mkdirProc = connection()->createRemoteProcess(command);
connect(m_mkdirProc.data(), SIGNAL(closed(int)),
SLOT(handleMkdirFinished(int)));
// TODO: Connect stderr.
writeOutput(tr("Uploading file '%1'...")
.arg(QDir::toNativeSeparators(d.localFilePath)));
m_mkdirProc->start();
m_extendedState = Uploading;
}
void MaemoDirectDeviceUploadStep::handleMkdirFinished(int exitStatus)
{
ASSERT_STATE(QList<ExtendedState>() << Inactive << Uploading);
if (m_extendedState == Inactive)
return;
const MaemoDeployable &d = m_filesToUpload.first();
QFileInfo fi(d.localFilePath);
const QString nativePath = QDir::toNativeSeparators(d.localFilePath);
if (exitStatus != SshRemoteProcess::ExitedNormally
|| m_mkdirProc->exitCode() != 0) {
raiseError(tr("Failed to upload file '%1'.").arg(nativePath));
setFinished();
} else if (fi.isDir()) {
setDeployed(deviceConfig()->sshParameters().host, d);
m_filesToUpload.removeFirst();
uploadNextFile();
} else {
const SftpJobId job = m_uploader->uploadFile(d.localFilePath,
d.remoteDir + QLatin1Char('/') + fi.fileName(),
SftpOverwriteExisting);
if (job == SftpInvalidJob) {
raiseError(tr("Failed to upload file '%1': "
"Could not open for reading.").arg(nativePath));
setFinished();
}
}
}
void MaemoDirectDeviceUploadStep::handleUploadFinished(Utils::SftpJobId jobId,
const QString &errorMsg)
{
Q_UNUSED(jobId);
ASSERT_STATE(QList<ExtendedState>() << Inactive << Uploading);
if (m_extendedState == Inactive)
return;
const MaemoDeployable d = m_filesToUpload.takeFirst();
if (!errorMsg.isEmpty()) {
raiseError(tr("Upload of file '%1' failed: %2")
.arg(QDir::toNativeSeparators(d.localFilePath), errorMsg));
setFinished();
} else {
setDeployed(connection()->connectionParameters().host, d);
uploadNextFile();
}
}
void MaemoDirectDeviceUploadStep::stopInternal()
{
ASSERT_BASE_STATE(StopRequested);
ASSERT_STATE(QList<ExtendedState>() << InitializingSftp << Uploading);
setFinished();
}
void MaemoDirectDeviceUploadStep::setFinished()
{
m_extendedState = Inactive;
if (m_mkdirProc) {
disconnect(m_mkdirProc.data(), 0, this, 0);
}
if (m_uploader) {
disconnect(m_uploader.data(), 0, this, 0);
m_uploader->closeChannel();
}
setDeploymentFinished();
}
const QString MaemoDirectDeviceUploadStep::Id("MaemoDirectDeviceUploadStep");
const QString MaemoDirectDeviceUploadStep::DisplayName
= tr("Upload files via SFTP");
} // namespace Internal
} // namespace Qt4ProjectManager
#ifndef MAEMODIRECTDEVICEUPLOADSTEP_H
#define MAEMODIRECTDEVICEUPLOADSTEP_H
#include "abstractmaemodeploystep.h"
#include <utils/ssh/sftpdefs.h>
#include <QtCore/QList>
#include <QtCore/QSharedPointer>
namespace Utils {
class SshRemoteProcess;
class SftpChannel;
}
namespace Qt4ProjectManager {
namespace Internal {
class MaemoDeployable;
class MaemoDirectDeviceUploadStep : public AbstractMaemoDeployStep
{
Q_OBJECT
public:
MaemoDirectDeviceUploadStep(ProjectExplorer::BuildStepList *bc);
MaemoDirectDeviceUploadStep(ProjectExplorer::BuildStepList *bc,
MaemoDirectDeviceUploadStep *other);
~MaemoDirectDeviceUploadStep();
static const QString Id;
static const QString DisplayName;
private slots:
void handleSftpInitialized();
void handleSftpInitializationFailed(const QString &errorMessage);
void handleUploadFinished(Utils::SftpJobId jobId, const QString &errorMsg);
void handleMkdirFinished(int exitStatus);
private:
enum ExtendedState { Inactive, InitializingSftp, Uploading };
virtual bool isDeploymentPossibleInternal(QString &whynot) const;
virtual bool isDeploymentNeeded(const QString &hostName) const;
virtual void startInternal();
virtual void stopInternal();
virtual const AbstractMaemoPackageCreationStep *packagingStep() const { return 0; }
void ctor();
void setFinished();
void checkDeploymentNeeded(const QString &hostName,
const MaemoDeployable &deployable) const;
void uploadNextFile();
QSharedPointer<Utils::SftpChannel> m_uploader;
QSharedPointer<Utils::SshRemoteProcess> m_mkdirProc;
mutable QList<MaemoDeployable> m_filesToUpload;
ExtendedState m_extendedState;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // MAEMODIRECTDEVICEUPLOADSTEP_H
......@@ -58,7 +58,8 @@ HEADERS += \
$$PWD/maemoremotecopyfacility.h \
$$PWD/abstractmaemodeploystep.h \
$$PWD/maemodeploybymountstep.h \
$$PWD/maemouploadandinstalldeploystep.h
$$PWD/maemouploadandinstalldeploystep.h \
$$PWD/maemodirectdeviceuploadstep.h
SOURCES += \
$$PWD/maemoconfigtestdialog.cpp \
......@@ -117,7 +118,8 @@ SOURCES += \
$$PWD/maemoremotecopyfacility.cpp \
$$PWD/abstractmaemodeploystep.cpp \
$$PWD/maemodeploybymountstep.cpp \
$$PWD/maemouploadandinstalldeploystep.cpp
$$PWD/maemouploadandinstalldeploystep.cpp \
$$PWD/maemodirectdeviceuploadstep.cpp
FORMS += \
$$PWD/maemoconfigtestdialog.ui \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment