forked from qt-creator/qt-creator
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/1582 Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
@@ -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,8 +205,22 @@ 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(),
|
||||
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': "
|
||||
@@ -192,6 +229,17 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus)
|
||||
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()
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user