forked from qt-creator/qt-creator
Maemo: Add key deployment feature to options page.
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QStringBuilder>
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -44,6 +45,18 @@
|
||||
namespace Qt4ProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
QString homeDirOnDevice(const QString &uname)
|
||||
{
|
||||
const QString &dir = uname == QLatin1String("root")
|
||||
? QLatin1String("/root")
|
||||
: uname == QLatin1String("developer")
|
||||
? QLatin1String("/var/local/mad-developer-home")
|
||||
: QLatin1String("/home/") + uname;
|
||||
qDebug("%s: user name %s is mapped to home dir %s",
|
||||
Q_FUNC_INFO, qPrintable(uname), qPrintable(dir));
|
||||
return dir;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const QLatin1String SettingsGroup("MaemoDeviceConfigs");
|
||||
const QLatin1String IdCounterKey("IdCounter");
|
||||
|
||||
@@ -47,6 +47,8 @@ QT_END_NAMESPACE
|
||||
namespace Qt4ProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
QString homeDirOnDevice(const QString &uname);
|
||||
|
||||
class MaemoDeviceConfig
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -123,8 +123,10 @@ void AbstractMaemoRunControl::deploy()
|
||||
foreach (const Deployable &deployable, deployables) {
|
||||
const QString srcFilePath
|
||||
= deployable.dir % QDir::separator() % deployable.fileName;
|
||||
const QString tgtFilePath
|
||||
= remoteDir() % QDir::separator() % deployable.fileName;
|
||||
files << srcFilePath;
|
||||
deploySpecs << SshDeploySpec(srcFilePath, remoteDir());
|
||||
deploySpecs << SshDeploySpec(srcFilePath, tgtFilePath);
|
||||
}
|
||||
emit addToOutputWindow(this, tr("Files to deploy: %1.").arg(files.join(" ")));
|
||||
sshDeployer.reset(new MaemoSshDeployer(devConfig, deploySpecs));
|
||||
@@ -249,9 +251,7 @@ const QString AbstractMaemoRunControl::executableFileName() const
|
||||
|
||||
const QString AbstractMaemoRunControl::remoteDir() const
|
||||
{
|
||||
return devConfig.uname == QString::fromLocal8Bit("root")
|
||||
? QString::fromLocal8Bit("/root")
|
||||
: QString::fromLocal8Bit("/home/") + devConfig.uname;
|
||||
return homeDirOnDevice(devConfig.uname);
|
||||
}
|
||||
|
||||
const QStringList AbstractMaemoRunControl::options() const
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
#include "ui_maemosettingswidget.h"
|
||||
#include "maemosettingspage.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QIntValidator>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -136,11 +138,18 @@ private slots:
|
||||
void userNameEditingFinished();
|
||||
void passwordEditingFinished();
|
||||
void keyFileEditingFinished();
|
||||
|
||||
// For configuration testing.
|
||||
void testConfig();
|
||||
void processSshOutput(const QString &data);
|
||||
void handleSshFinished();
|
||||
void handleTestThreadFinished();
|
||||
void stopConfigTest();
|
||||
|
||||
// For key deploying.
|
||||
void deployKey();
|
||||
void handleDeployThreadFinished();
|
||||
void stopDeploying();
|
||||
|
||||
private:
|
||||
void initGui();
|
||||
void display(const MaemoDeviceConfig &devConfig);
|
||||
@@ -156,6 +165,7 @@ private:
|
||||
PortAndTimeoutValidator m_timeoutValidator;
|
||||
NameValidator m_nameValidator;
|
||||
#ifdef USE_SSH_LIB
|
||||
MaemoSshDeployer *m_keyDeployer;
|
||||
MaemoSshRunner *m_deviceTester;
|
||||
#endif
|
||||
QString m_deviceTestOutput;
|
||||
@@ -237,6 +247,7 @@ void MaemoSettingsWidget::initGui()
|
||||
|
||||
#ifndef USE_SSH_LIB // Password authentication does not currently work due to ssh/scp issues.
|
||||
m_ui->testConfigButton->hide();
|
||||
m_ui->deployKeyButton->hide();
|
||||
m_ui->testResultEdit->hide();
|
||||
m_ui->authTypeLabel->hide();
|
||||
m_ui->authTypeButtonsWidget->hide();
|
||||
@@ -347,6 +358,7 @@ void MaemoSettingsWidget::authenticationTypeChanged()
|
||||
m_ui->passwordLabel->setEnabled(usePassword);
|
||||
m_ui->keyFileLineEdit->setEnabled(!usePassword);
|
||||
m_ui->keyLabel->setEnabled(!usePassword);
|
||||
m_ui->deployKeyButton->setEnabled(usePassword);
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::hostNameEditingFinished()
|
||||
@@ -407,7 +419,7 @@ void MaemoSettingsWidget::testConfig()
|
||||
connect(m_deviceTester, SIGNAL(remoteOutput(QString)),
|
||||
this, SLOT(processSshOutput(QString)));
|
||||
connect(m_deviceTester, SIGNAL(finished()),
|
||||
this, SLOT(handleSshFinished()));
|
||||
this, SLOT(handleTestThreadFinished()));
|
||||
m_ui->testConfigButton->setText(tr("Stop test"));
|
||||
connect(m_ui->testConfigButton, SIGNAL(clicked()),
|
||||
this, SLOT(stopConfigTest()));
|
||||
@@ -421,7 +433,7 @@ void MaemoSettingsWidget::processSshOutput(const QString &data)
|
||||
m_deviceTestOutput.append(data);
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::handleSshFinished()
|
||||
void MaemoSettingsWidget::handleTestThreadFinished()
|
||||
{
|
||||
#ifdef USE_SSH_LIB
|
||||
qDebug("================> %s", Q_FUNC_INFO);
|
||||
@@ -490,12 +502,80 @@ QString MaemoSettingsWidget::parseTestOutput()
|
||||
return output;
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::deployKey()
|
||||
{
|
||||
#ifdef USE_SSH_LIB
|
||||
qDebug("Deploying key");
|
||||
if (m_keyDeployer)
|
||||
return;
|
||||
|
||||
const QString &dir = QFileInfo(currentConfig().keyFile).path();
|
||||
const QString &keyFile
|
||||
= QFileDialog::getOpenFileName(this, tr("Choose public key file"), dir);
|
||||
if (keyFile.isEmpty())
|
||||
return;
|
||||
|
||||
m_ui->deployKeyButton->disconnect();
|
||||
SshDeploySpec deploySpec(keyFile,
|
||||
homeDirOnDevice(currentConfig().uname)
|
||||
+ QLatin1String("/.ssh/authorized_keys"),
|
||||
true);
|
||||
m_keyDeployer = new MaemoSshDeployer(currentConfig(),
|
||||
QList<SshDeploySpec>() << deploySpec);
|
||||
connect(m_keyDeployer, SIGNAL(finished()),
|
||||
this, SLOT(handleDeployThreadFinished()));
|
||||
m_ui->deployKeyButton->setText(tr("Stop deploying"));
|
||||
connect(m_ui->deployKeyButton, SIGNAL(clicked()),
|
||||
this, SLOT(stopDeploying()));
|
||||
m_keyDeployer->start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::handleDeployThreadFinished()
|
||||
{
|
||||
#ifdef USE_SSH_LIB
|
||||
qDebug("================> %s", Q_FUNC_INFO);
|
||||
if (!m_keyDeployer)
|
||||
return;
|
||||
|
||||
QString output;
|
||||
if (m_keyDeployer->hasError()) {
|
||||
output = tr("Key deployment failed: ");
|
||||
output.append(m_keyDeployer->error());
|
||||
} else {
|
||||
output = tr("Key was successfully deployed.");
|
||||
}
|
||||
m_ui->testResultEdit->setPlainText(output);
|
||||
stopDeploying();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::stopDeploying()
|
||||
{
|
||||
#ifdef USE_SSH_LIB
|
||||
qDebug("================> %s", Q_FUNC_INFO);
|
||||
if (m_keyDeployer) {
|
||||
m_ui->deployKeyButton->disconnect();
|
||||
const bool buttonWasEnabled = m_ui->deployKeyButton->isEnabled();
|
||||
m_keyDeployer->disconnect();
|
||||
m_keyDeployer->stop();
|
||||
delete m_keyDeployer;
|
||||
m_keyDeployer = 0;
|
||||
m_ui->deployKeyButton->setText(tr("Deploy key ..."));
|
||||
connect(m_ui->deployKeyButton, SIGNAL(clicked()),
|
||||
this, SLOT(deployKey()));
|
||||
m_ui->deployKeyButton->setEnabled(buttonWasEnabled);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MaemoSettingsWidget::selectionChanged()
|
||||
{
|
||||
const QList<QListWidgetItem *> &selectedItems =
|
||||
m_ui->configListWidget->selectedItems();
|
||||
Q_ASSERT(selectedItems.count() <= 1);
|
||||
stopConfigTest();
|
||||
stopDeploying();
|
||||
m_ui->testResultEdit->setPlainText(m_defaultTestOutput);
|
||||
if (selectedItems.isEmpty()) {
|
||||
m_ui->removeConfigButton->setEnabled(false);
|
||||
|
||||
@@ -187,8 +187,8 @@
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">No current test results available.</p></body></html></string>
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">No current test results available.</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -224,6 +224,16 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deployKeyButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Deploy key ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -278,8 +288,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>deviceTypeChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>170</y>
|
||||
<x>264</x>
|
||||
<y>175</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>511</x>
|
||||
@@ -294,8 +304,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>hostNameEditingFinished()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>397</x>
|
||||
<y>219</y>
|
||||
<x>385</x>
|
||||
<y>228</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>424</x>
|
||||
@@ -310,8 +320,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>portEditingFinished()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>397</x>
|
||||
<y>243</y>
|
||||
<x>385</x>
|
||||
<y>255</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>514</x>
|
||||
@@ -326,8 +336,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>timeoutEditingFinished()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>397</x>
|
||||
<y>268</y>
|
||||
<x>385</x>
|
||||
<y>282</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>425</x>
|
||||
@@ -342,8 +352,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>userNameEditingFinished()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>397</x>
|
||||
<y>293</y>
|
||||
<x>385</x>
|
||||
<y>309</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>422</x>
|
||||
@@ -358,8 +368,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>passwordEditingFinished()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>394</x>
|
||||
<y>317</y>
|
||||
<x>385</x>
|
||||
<y>336</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>423</x>
|
||||
@@ -374,8 +384,8 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>deviceTypeChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>388</x>
|
||||
<y>170</y>
|
||||
<x>376</x>
|
||||
<y>175</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>426</x>
|
||||
@@ -495,6 +505,22 @@ p, li { white-space: pre-wrap; }
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>deployKeyButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>maemoSettingsWidget</receiver>
|
||||
<slot>deployKey()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>438</x>
|
||||
<y>119</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>510</x>
|
||||
<y>458</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>configNameEditingFinished()</slot>
|
||||
@@ -510,5 +536,6 @@ p, li { white-space: pre-wrap; }
|
||||
<slot>authenticationTypeChanged()</slot>
|
||||
<slot>keyFileEditingFinished()</slot>
|
||||
<slot>testConfig()</slot>
|
||||
<slot>deployKey()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
||||
@@ -160,26 +160,30 @@ void MaemoSftpConnection::transferFiles(const QList<SshDeploySpec> &deploySpecs)
|
||||
{
|
||||
for (int i = 0; i < deploySpecs.count(); ++i) {
|
||||
const SshDeploySpec &deploySpec = deploySpecs.at(i);
|
||||
const QString &curFile = deploySpec.srcFilePath();
|
||||
QSharedPointer<FILE> filePtr(fopen(curFile.toLatin1().data(), "rb"),
|
||||
const QString &curSrcFile = deploySpec.srcFilePath();
|
||||
QSharedPointer<FILE> filePtr(fopen(curSrcFile.toLatin1().data(), "rb"),
|
||||
&std::fclose);
|
||||
if (filePtr.isNull())
|
||||
throw MaemoSshException(tr("Could not open file '%1'").arg(curFile));
|
||||
throw MaemoSshException(tr("Could not open file '%1'").arg(curSrcFile));
|
||||
|
||||
const QString &curTgtFile = deploySpec.tgtFilePath();
|
||||
|
||||
// TODO: Is the mkdir() method recursive? If not, we have to
|
||||
// introduce a recursive version ourselves.
|
||||
if (deploySpec.mkdir())
|
||||
sftp->mkdir(deploySpec.targetDir().toLatin1().data());
|
||||
if (deploySpec.mkdir()) {
|
||||
const QString &dir = QFileInfo(curTgtFile).path();
|
||||
sftp->mkdir(dir.toLatin1().data());
|
||||
}
|
||||
|
||||
const QString &targetFile = deploySpec.targetDir() % QLatin1String("/")
|
||||
% QFileInfo(curFile).fileName();
|
||||
if (!sftp->put(filePtr.data(), targetFile.toLatin1().data())) {
|
||||
qDebug("Deploying file %s to %s.", qPrintable(curSrcFile), qPrintable(curTgtFile));
|
||||
|
||||
if (!sftp->put(filePtr.data(), curTgtFile.toLatin1().data())) {
|
||||
const QString &error = tr("Could not copy local file '%1' "
|
||||
"to remote file '%2': %3").arg(curFile, targetFile)
|
||||
"to remote file '%2': %3").arg(curSrcFile, curTgtFile)
|
||||
.arg(lastError());
|
||||
throw MaemoSshException(error);
|
||||
}
|
||||
emit fileCopied(curFile);
|
||||
emit fileCopied(curSrcFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,19 +109,19 @@ private:
|
||||
class SshDeploySpec
|
||||
{
|
||||
public:
|
||||
SshDeploySpec(const QString &srcFilePath, const QString &targetDir,
|
||||
SshDeploySpec(const QString &srcFilePath, const QString &tgtFilePath,
|
||||
bool mkdir = false)
|
||||
: m_srcFilePath(srcFilePath), m_targetDir(targetDir), m_mkdir(mkdir)
|
||||
: m_srcFilePath(srcFilePath), m_tgtFilePath(tgtFilePath), m_mkdir(mkdir)
|
||||
{
|
||||
}
|
||||
|
||||
QString srcFilePath() const { return m_srcFilePath; }
|
||||
QString targetDir() const { return m_targetDir; }
|
||||
QString tgtFilePath() const { return m_tgtFilePath; }
|
||||
bool mkdir() const { return m_mkdir; }
|
||||
|
||||
private:
|
||||
QString m_srcFilePath;
|
||||
QString m_targetDir;
|
||||
QString m_tgtFilePath;
|
||||
bool m_mkdir;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user