forked from qt-creator/qt-creator
RemoteLinux: Fix deployment when building remotely
By using a generic file transfer method based of FilePath::copyFile() that doesn't require either of the transfer end point to be the local host. Change-Id: Ia2e4273df52f5ce6533046d96be3f6b521b7f0a5 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -98,12 +98,17 @@ void FileTransferPrivate::start()
|
||||
return startFailed(tr("No files to transfer."));
|
||||
|
||||
const FileTransferDirection direction = transferDirection(m_setup.m_files);
|
||||
if (direction == FileTransferDirection::Invalid)
|
||||
return startFailed(tr("Mixing different types of transfer in one go."));
|
||||
|
||||
const IDeviceConstPtr device = matchedDevice(direction, m_setup.m_files);
|
||||
if (!device)
|
||||
return startFailed(tr("Trying to transfer into / from not matching device."));
|
||||
IDeviceConstPtr device;
|
||||
if (direction != FileTransferDirection::Invalid)
|
||||
device = matchedDevice(direction, m_setup.m_files);
|
||||
|
||||
if (!device) {
|
||||
// Fall back to generic copy.
|
||||
const FilePath &filePath = m_setup.m_files.first().m_target;
|
||||
device = DeviceManager::deviceForPath(filePath);
|
||||
m_setup.m_method = FileTransferMethod::GenericCopy;
|
||||
}
|
||||
|
||||
run(m_setup, device);
|
||||
}
|
||||
@@ -190,6 +195,7 @@ QString FileTransfer::transferMethodName(FileTransferMethod method)
|
||||
switch (method) {
|
||||
case FileTransferMethod::Sftp: return FileTransfer::tr("sftp");
|
||||
case FileTransferMethod::Rsync: return FileTransfer::tr("rsync");
|
||||
case FileTransferMethod::GenericCopy: return FileTransfer::tr("generic file copy");
|
||||
}
|
||||
QTC_CHECK(false);
|
||||
return {};
|
||||
|
@@ -20,6 +20,7 @@ enum class FileTransferDirection {
|
||||
enum class FileTransferMethod {
|
||||
Sftp,
|
||||
Rsync,
|
||||
GenericCopy,
|
||||
Default = Sftp
|
||||
};
|
||||
|
||||
|
@@ -1428,12 +1428,73 @@ private:
|
||||
int m_currentIndex = 0;
|
||||
};
|
||||
|
||||
class GenericTransferImpl : public FileTransferInterface
|
||||
{
|
||||
public:
|
||||
GenericTransferImpl(const FileTransferSetupData &setup, LinuxDevicePrivate *)
|
||||
: FileTransferInterface(setup)
|
||||
{}
|
||||
|
||||
private:
|
||||
void start() final
|
||||
{
|
||||
m_fileCount = m_setup.m_files.size();
|
||||
m_currentIndex = 0;
|
||||
m_checkedDirectories.clear();
|
||||
nextFile();
|
||||
}
|
||||
|
||||
void nextFile()
|
||||
{
|
||||
ProcessResultData result;
|
||||
if (m_currentIndex >= m_fileCount) {
|
||||
emit done(result);
|
||||
return;
|
||||
}
|
||||
|
||||
const FileToTransfer &file = m_setup.m_files.at(m_currentIndex);
|
||||
const FilePath &source = file.m_source;
|
||||
const FilePath &target = file.m_target;
|
||||
++m_currentIndex;
|
||||
|
||||
const FilePath targetDir = target.parentDir();
|
||||
if (!m_checkedDirectories.contains(targetDir)) {
|
||||
emit progress(tr("Creating directory: %1")
|
||||
.arg(targetDir.toUserOutput()));
|
||||
if (!targetDir.ensureWritableDir()) {
|
||||
result.m_errorString = tr("Failed.");
|
||||
result.m_exitCode = -1; // Random pick
|
||||
emit done(result);
|
||||
return;
|
||||
}
|
||||
m_checkedDirectories.insert(targetDir);
|
||||
}
|
||||
|
||||
emit progress(tr("Copying %1/%2: %3 -> %4")
|
||||
.arg(m_currentIndex).arg(m_fileCount).arg(source.toUserOutput(), target.toUserOutput()));
|
||||
if (!source.copyFile(target)) {
|
||||
result.m_errorString = tr("Failed.");
|
||||
result.m_exitCode = -1; // Random pick
|
||||
emit done(result);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Use asyncCopyFile instead
|
||||
nextFile();
|
||||
}
|
||||
|
||||
int m_currentIndex = 0;
|
||||
int m_fileCount = 0;
|
||||
QSet<FilePath> m_checkedDirectories;
|
||||
};
|
||||
|
||||
FileTransferInterface *LinuxDevice::createFileTransferInterface(
|
||||
const FileTransferSetupData &setup) const
|
||||
{
|
||||
switch (setup.m_method) {
|
||||
case FileTransferMethod::Sftp: return new SftpTransferImpl(setup, d);
|
||||
case FileTransferMethod::Rsync: return new RsyncTransferImpl(setup, d);
|
||||
case FileTransferMethod::GenericCopy: return new GenericTransferImpl(setup, d);
|
||||
}
|
||||
QTC_CHECK(false);
|
||||
return {};
|
||||
|
@@ -236,6 +236,7 @@ void GenericLinuxDeviceTester::testFileTransfer(FileTransferMethod method)
|
||||
switch (method) {
|
||||
case FileTransferMethod::Sftp: d->state = TestingSftp; break;
|
||||
case FileTransferMethod::Rsync: d->state = TestingRsync; break;
|
||||
case FileTransferMethod::GenericCopy: QTC_CHECK(false) /* not tested */; break;
|
||||
}
|
||||
emit progressMessage(Tr::tr("Checking whether \"%1\" works...")
|
||||
.arg(FileTransfer::transferMethodName(method)));
|
||||
|
@@ -39,6 +39,9 @@ RemoteLinuxDeployConfigurationFactory::RemoteLinuxDeployConfigurationFactory()
|
||||
|
||||
addInitialStep(Constants::MakeInstallStepId, needsMakeInstall);
|
||||
addInitialStep(Constants::KillAppStepId);
|
||||
|
||||
// Todo: Check: Instead of having two different steps here, have one
|
||||
// and shift the logic into the implementation there?
|
||||
addInitialStep(Constants::RsyncDeployStepId, [](Target *target) {
|
||||
auto runDevice = DeviceKitAspect::device(target->kit());
|
||||
auto buildDevice = BuildDeviceKitAspect::device(target->kit());
|
||||
@@ -49,8 +52,11 @@ RemoteLinuxDeployConfigurationFactory::RemoteLinuxDeployConfigurationFactory()
|
||||
return runDevice && runDevice->extraData(Constants::SupportsRSync).toBool();
|
||||
});
|
||||
addInitialStep(Constants::DirectUploadStepId, [](Target *target) {
|
||||
auto device = DeviceKitAspect::device(target->kit());
|
||||
return device && !device->extraData(Constants::SupportsRSync).toBool();
|
||||
auto runDevice = DeviceKitAspect::device(target->kit());
|
||||
auto buildDevice = BuildDeviceKitAspect::device(target->kit());
|
||||
if (runDevice == buildDevice)
|
||||
return true;
|
||||
return runDevice && !runDevice->extraData(Constants::SupportsRSync).toBool();
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user