Commit 9198aa23 authored by Christian Kandeler's avatar Christian Kandeler

RemoteLinux: Improve handling of symbolic links when deploying.

We used to follow the links, resulting in unnecessary traffic.
Now we just recreate the links.
Note: This requires the user to not have dependencies that resolve to
something outside the set of files to deploy.

Change-Id: I3f439739115b4d07b36a71fe2041d8725a25abfd
Reviewed-on: http://codereview.qt.nokia.com/1582Reviewed-by: default avatarChristian Kandeler <christian.kandeler@nokia.com>
parent d35d6afe
......@@ -64,6 +64,9 @@ public:
quint32 requestId);
SftpOutgoingPacket &generateWriteFile(const QByteArray &handle,
quint64 offset, const QByteArray &data, quint32 requestId);
// Note: OpenSSH's SFTP server has a bug that reverses the filePath and target
// arguments, so this operation is not portable.
SftpOutgoingPacket &generateCreateLink(const QString &filePath, const QString &target,
quint32 requestId);
......
......@@ -61,6 +61,7 @@ public:
QList<DeployableFile> filesToUpload;
SftpChannel::Ptr uploader;
SshRemoteProcess::Ptr mkdirProc;
SshRemoteProcess::Ptr lnProc;
QList<DeployableFile> deployableFiles;
};
......@@ -161,6 +162,28 @@ void GenericDirectUploadService::handleUploadFinished(Utils::SftpJobId jobId, co
}
}
void GenericDirectUploadService::handleLnFinished(int exitStatus)
{
QTC_ASSERT(m_d->state == Uploading, setFinished(); return);
if (m_d->stopRequested) {
setFinished();
handleDeploymentDone();
}
const DeployableFile d = m_d->filesToUpload.takeFirst();
const QString nativePath = QDir::toNativeSeparators(d.localFilePath);
if (exitStatus != SshRemoteProcess::ExitedNormally || m_d->lnProc->exitCode() != 0) {
emit errorMessage(tr("Failed to upload file '%1'.").arg(nativePath));
setFinished();
handleDeploymentDone();
return;
} else {
saveDeploymentTimeStamp(d);
uploadNextFile();
}
}
void GenericDirectUploadService::handleMkdirFinished(int exitStatus)
{
QTC_ASSERT(m_d->state == Uploading, setFinished(); return);
......@@ -182,18 +205,43 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus)
m_d->filesToUpload.removeFirst();
uploadNextFile();
} else {
const SftpJobId job = m_d->uploader->uploadFile(d.localFilePath,
d.remoteDir + QLatin1Char('/') + fi.fileName(),
SftpOverwriteExisting);
if (job == SftpInvalidJob) {
emit errorMessage(tr("Failed to upload file '%1': "
"Could not open for reading.").arg(nativePath));
setFinished();
handleDeploymentDone();
const QString remoteFilePath = d.remoteDir + QLatin1Char('/') + fi.fileName();
if (fi.isSymLink()) {
const QString target = fi.dir().relativeFilePath(fi.symLinkTarget()); // see QTBUG-5817.
const QString command = QLatin1String("ln -vsf ") + target + QLatin1Char(' ')
+ remoteFilePath;
// See comment in SftpChannel::createLink as to why we can't use it.
m_d->lnProc = connection()->createRemoteProcess(command.toUtf8());
connect(m_d->lnProc.data(), SIGNAL(closed(int)), SLOT(handleLnFinished(int)));
connect(m_d->lnProc.data(), SIGNAL(outputAvailable(QByteArray)),
SLOT(handleStdOutData(QByteArray)));
connect(m_d->lnProc.data(), SIGNAL(errorOutputAvailable(QByteArray)),
SLOT(handleStdErrData(QByteArray)));
m_d->lnProc->start();
} else {
const SftpJobId job = m_d->uploader->uploadFile(d.localFilePath, remoteFilePath,
SftpOverwriteExisting);
if (job == SftpInvalidJob) {
emit errorMessage(tr("Failed to upload file '%1': "
"Could not open for reading.").arg(nativePath));
setFinished();
handleDeploymentDone();
}
}
}
}
void GenericDirectUploadService::handleStdOutData(const QByteArray &data)
{
emit stdOutData(QString::fromUtf8(data));
}
void GenericDirectUploadService::handleStdErrData(const QByteArray &data)
{
emit stdErrData(QString::fromUtf8(data));
}
void GenericDirectUploadService::stopDeployment()
{
QTC_ASSERT(m_d->state == InitializingSftp || m_d->state == Uploading, setFinished(); return);
......@@ -226,9 +274,10 @@ void GenericDirectUploadService::setFinished()
{
m_d->stopRequested = false;
m_d->state = Inactive;
if (m_d->mkdirProc) {
if (m_d->mkdirProc)
disconnect(m_d->mkdirProc.data(), 0, this, 0);
}
if (m_d->lnProc)
disconnect(m_d->lnProc.data(), 0, this, 0);
if (m_d->uploader) {
disconnect(m_d->uploader.data(), 0, this, 0);
m_d->uploader->closeChannel();
......@@ -249,10 +298,13 @@ void GenericDirectUploadService::uploadNextFile()
QFileInfo fi(d.localFilePath);
if (fi.isDir())
dirToCreate += QLatin1Char('/') + fi.fileName();
const QByteArray command = "mkdir -p " + dirToCreate.toUtf8();
m_d->mkdirProc = connection()->createRemoteProcess(command);
const QString command = QLatin1String("mkdir -vp ") + dirToCreate;
m_d->mkdirProc = connection()->createRemoteProcess(command.toUtf8());
connect(m_d->mkdirProc.data(), SIGNAL(closed(int)), SLOT(handleMkdirFinished(int)));
// TODO: Connect stderr.
connect(m_d->mkdirProc.data(), SIGNAL(outputAvailable(QByteArray)),
SLOT(handleStdOutData(QByteArray)));
connect(m_d->mkdirProc.data(), SIGNAL(errorOutputAvailable(QByteArray)),
SLOT(handleStdErrData(QByteArray)));
emit progressMessage(tr("Uploading file '%1'...")
.arg(QDir::toNativeSeparators(d.localFilePath)));
m_d->mkdirProc->start();
......
......@@ -58,6 +58,9 @@ private slots:
void handleSftpInitializationFailed(const QString &errorMessage);
void handleUploadFinished(Utils::SftpJobId jobId, const QString &errorMsg);
void handleMkdirFinished(int exitStatus);
void handleLnFinished(int exitStatus);
void handleStdOutData(const QByteArray &data);
void handleStdErrData(const QByteArray &data);
private:
bool isDeploymentNecessary() const;
......
......@@ -138,7 +138,7 @@ void MaemoRemoteCopyFacility::copyNextFile()
sourceFilePath += d.localFilePath;
#endif
QString command = QString::fromLatin1("%1 mkdir -p %3 && %1 cp -r %2 %3")
QString command = QString::fromLatin1("%1 mkdir -p %3 && %1 cp -a %2 %3")
.arg(MaemoGlobal::remoteSudo(m_devConf->osType(),
m_copyRunner->connection()->connectionParameters().userName),
sourceFilePath, d.remoteDir);
......
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