From 60f97e5cff42a59bcb78d02ee647353d1e684a15 Mon Sep 17 00:00:00 2001 From: ck <qt-info@nokia.com> Date: Thu, 7 Jan 2010 16:42:01 +0100 Subject: [PATCH] Maemo: Add key deployment feature to options page. --- .../qt-maemo/maemodeviceconfigurations.cpp | 13 +++ .../qt-maemo/maemodeviceconfigurations.h | 2 + .../qt-maemo/maemoruncontrol.cpp | 8 +- .../qt-maemo/maemosettingspage.cpp | 86 ++++++++++++++++++- .../qt-maemo/maemosettingswidget.ui | 59 +++++++++---- .../qt-maemo/maemosshconnection.cpp | 24 +++--- .../qt-maemo/maemosshconnection.h | 8 +- 7 files changed, 163 insertions(+), 37 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp index 39cd9d5c609..bd2e2aa06fc 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp @@ -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"); diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h index 887b82050c5..e79e19736d7 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h @@ -47,6 +47,8 @@ QT_END_NAMESPACE namespace Qt4ProjectManager { namespace Internal { +QString homeDirOnDevice(const QString &uname); + class MaemoDeviceConfig { public: diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp index 32c977cea32..de5f01476ae 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp @@ -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 diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosettingspage.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosettingspage.cpp index 236cd18a849..66575ff87e2 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosettingspage.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosettingspage.cpp @@ -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); diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosettingswidget.ui b/src/plugins/qt4projectmanager/qt-maemo/maemosettingswidget.ui index c7e95a5de3b..010dd4b6b49 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosettingswidget.ui +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosettingswidget.ui @@ -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> diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp index 3f8ef2a6452..9bf830ab89e 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp @@ -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()); + } + + qDebug("Deploying file %s to %s.", qPrintable(curSrcFile), qPrintable(curTgtFile)); - const QString &targetFile = deploySpec.targetDir() % QLatin1String("/") - % QFileInfo(curFile).fileName(); - if (!sftp->put(filePtr.data(), targetFile.toLatin1().data())) { + 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); } } diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h index c438ba95131..83774ab3f76 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h @@ -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; }; -- GitLab