TarPackageDeployService: Reuse TaskTree

Change-Id: I74d19719f5a946a79409f04b4536fe9368747bc1
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2022-11-22 20:25:27 +01:00
parent c88a829059
commit f9b4bcd3d8

View File

@@ -20,80 +20,36 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
using namespace Utils::Tasking;
namespace RemoteLinux::Internal { namespace RemoteLinux::Internal {
class TarPackageDeployService : public AbstractRemoteLinuxDeployService class TarPackageDeployService : public AbstractRemoteLinuxDeployService
{ {
public: public:
TarPackageDeployService();
void setPackageFilePath(const FilePath &filePath); void setPackageFilePath(const FilePath &filePath);
private: private:
enum State { Inactive, Uploading, Installing }; QString remoteFilePath() const;
void handleUploadFinished(const ProcessResultData &resultData);
void handleInstallationFinished(const QString &errorMsg);
QString uploadDir() const; // Defaults to remote user's home directory.
bool isDeploymentNecessary() const override; bool isDeploymentNecessary() const override;
void doDeploy() override; void doDeploy() override;
void stopDeployment() override; void stopDeployment() override;
TaskItem uploadTask();
TaskItem installTask();
void setFinished();
void installPackage(const IDeviceConstPtr &deviceConfig, const QString &packageFilePath);
State m_state = Inactive;
FileTransfer m_uploader;
FilePath m_packageFilePath; FilePath m_packageFilePath;
std::unique_ptr<TaskTree> m_taskTree;
IDevice::ConstPtr m_device;
QtcProcess m_installer;
}; };
TarPackageDeployService::TarPackageDeployService()
{
connect(&m_uploader, &FileTransfer::done, this,
&TarPackageDeployService::handleUploadFinished);
connect(&m_uploader, &FileTransfer::progress, this,
&TarPackageDeployService::progressMessage);
connect(&m_installer, &QtcProcess::readyReadStandardOutput, this, [this] {
emit stdOutData(QString::fromUtf8(m_installer.readAllStandardOutput()));
});
connect(&m_installer, &QtcProcess::readyReadStandardError, this, [this] {
emit stdErrData(QString::fromUtf8(m_installer.readAllStandardError()));
});
connect(&m_installer, &QtcProcess::done, this, [this] {
const QString errorMessage = m_installer.result() == ProcessResult::FinishedWithSuccess
? QString() : Tr::tr("Installing package failed.") + m_installer.errorString();
handleInstallationFinished(errorMessage);
});
}
void TarPackageDeployService::installPackage(const IDevice::ConstPtr &deviceConfig,
const QString &packageFilePath)
{
QTC_ASSERT(m_installer.state() == QProcess::NotRunning, return);
m_device = deviceConfig;
const QString cmdLine = QLatin1String("cd / && tar xvf ") + packageFilePath
+ " && (rm " + packageFilePath + " || :)";
m_installer.setCommand({m_device->filePath("/bin/sh"), {"-c", cmdLine}});
m_installer.start();
}
void TarPackageDeployService::setPackageFilePath(const FilePath &filePath) void TarPackageDeployService::setPackageFilePath(const FilePath &filePath)
{ {
m_packageFilePath = filePath; m_packageFilePath = filePath;
} }
QString TarPackageDeployService::uploadDir() const QString TarPackageDeployService::remoteFilePath() const
{ {
return QLatin1String("/tmp"); return QLatin1String("/tmp/") + m_packageFilePath.fileName();
} }
bool TarPackageDeployService::isDeploymentNecessary() const bool TarPackageDeployService::isDeploymentNecessary() const
@@ -101,61 +57,72 @@ bool TarPackageDeployService::isDeploymentNecessary() const
return hasLocalFileChanged(DeployableFile(m_packageFilePath, {})); return hasLocalFileChanged(DeployableFile(m_packageFilePath, {}));
} }
TaskItem TarPackageDeployService::uploadTask()
{
auto setupHandler = [this](FileTransfer &transfer) {
const FilesToTransfer files {{m_packageFilePath,
deviceConfiguration()->filePath(remoteFilePath())}};
transfer.setFilesToTransfer(files);
connect(&transfer, &FileTransfer::progress,
this, &TarPackageDeployService::progressMessage);
emit progressMessage(Tr::tr("Uploading package to device..."));
};
auto doneHandler = [this](const FileTransfer &) {
emit progressMessage(Tr::tr("Successfully uploaded package file."));
};
auto errorHandler = [this](const FileTransfer &transfer) {
const ProcessResultData result = transfer.resultData();
emit errorMessage(result.m_errorString);
};
return Transfer(setupHandler, doneHandler, errorHandler);
}
TaskItem TarPackageDeployService::installTask()
{
auto setupHandler = [this](QtcProcess &process) {
const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath()
+ " && (rm " + remoteFilePath() + " || :)";
process.setCommand({deviceConfiguration()->filePath("/bin/sh"), {"-c", cmdLine}});
QtcProcess *proc = &process;
connect(proc, &QtcProcess::readyReadStandardOutput, this, [this, proc] {
emit stdOutData(QString::fromUtf8(proc->readAllStandardOutput()));
});
connect(proc, &QtcProcess::readyReadStandardError, this, [this, proc] {
emit stdErrData(QString::fromUtf8(proc->readAllStandardError()));
});
emit progressMessage(Tr::tr("Installing package to device..."));
};
auto doneHandler = [this](const QtcProcess &) {
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
emit progressMessage(Tr::tr("Successfully installed package file."));
};
auto errorHandler = [this](const QtcProcess &process) {
emit errorMessage(Tr::tr("Installing package failed.") + process.errorString());
};
return Process(setupHandler, doneHandler, errorHandler);
}
void TarPackageDeployService::doDeploy() void TarPackageDeployService::doDeploy()
{ {
QTC_ASSERT(m_state == Inactive, return); QTC_ASSERT(!m_taskTree, return);
m_state = Uploading; auto finishHandler = [this] {
m_taskTree.release()->deleteLater();
const QString remoteFilePath = uploadDir() + QLatin1Char('/') + m_packageFilePath.fileName(); stopDeployment();
const FilesToTransfer files {{m_packageFilePath, };
deviceConfiguration()->filePath(remoteFilePath)}}; Group root {
m_uploader.setFilesToTransfer(files); uploadTask(),
m_uploader.start(); installTask(),
OnGroupDone(finishHandler),
OnGroupError(finishHandler),
};
m_taskTree.reset(new TaskTree(root));
m_taskTree->start();
} }
void TarPackageDeployService::stopDeployment() void TarPackageDeployService::stopDeployment()
{ {
QTC_ASSERT(m_state != Inactive, return); m_taskTree.reset();
setFinished();
}
void TarPackageDeployService::handleUploadFinished(const ProcessResultData &resultData)
{
QTC_ASSERT(m_state == Uploading, return);
if (resultData.m_error != QProcess::UnknownError) {
emit errorMessage(resultData.m_errorString);
setFinished();
return;
}
emit progressMessage(Tr::tr("Successfully uploaded package file."));
const QString remoteFilePath = uploadDir() + '/' + m_packageFilePath.fileName();
m_state = Installing;
emit progressMessage(Tr::tr("Installing package to device..."));
installPackage(deviceConfiguration(), remoteFilePath);
}
void TarPackageDeployService::handleInstallationFinished(const QString &errorMsg)
{
QTC_ASSERT(m_state == Installing, return);
if (errorMsg.isEmpty()) {
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
emit progressMessage(Tr::tr("Package installed."));
} else {
emit errorMessage(errorMsg);
}
setFinished();
}
void TarPackageDeployService::setFinished()
{
m_state = Inactive;
m_uploader.stop();
m_installer.close();
handleDeploymentDone(); handleDeploymentDone();
} }