/* * @file: mainwindow.cpp * @author: Jordan P. Lefebvre, lefebvrejp@ornl.gov * * Created on June 24, 2018, 10:52 AM */ #include #include #include #include #include #include #include #include #include #include "rsmportalexample.hh" #include "radixbug/bug.hh" using namespace rsm; ExamplePortalWidget::ExamplePortalWidget(QWidget *parent) : QWidget(parent) { queue = &queueSGE; QGridLayout *layout = new QGridLayout(this); QLabel *proxyHostLabel = new QLabel("Proxy:", this); QLabel *hostLabel = new QLabel("Host:", this); QLabel *portLabel = new QLabel("Port:", this); QLabel *userNameLabel = new QLabel("Username:", this); mProxyEdit = new QLineEdit(this); mHostEdit = new QLineEdit("", this); mPortEdit = new QLineEdit("", this); mUserNameEdit = new QLineEdit("", this); mConnectButton = new QPushButton("Connect", this); mCommandEdit = new QLineEdit(this); mCommandSubmitButton = new QPushButton("Submit Command", this); mSchedulerBox = new QGroupBox(this); mPBSRadioButton = new QRadioButton("PBS", this); mSGERadioButton = new QRadioButton("SGE", this); mListAllQueuesButton = new QPushButton("List All Queues", this); mGetQueueInfoButton = new QPushButton("Queue Info", this); mGetQueueInfoTextEdit = new QLineEdit(this); mGetAllNodeInfoButton = new QPushButton("Node Info", this); mGetAllJobInfoButton = new QPushButton("Job Info", this); mSubmitJobButton = new QPushButton("Submit Job", this); mDeleteJobButton = new QPushButton("Delete Job(s)", this); mDeleteJobTextEdit = new QLineEdit(this); mSubmitJobTextEdit = new QLineEdit("", this); mTextEdit = new QTextEdit(this); mOpenFileButton = new QPushButton("Open File", this); mOpenFileEdit = new QLineEdit(this); mOpenDirButton = new QPushButton("Open Directory", this); mOpenDirEdit = new QLineEdit(this); int row = 0; layout->addWidget(proxyHostLabel, row, 0); layout->addWidget(mProxyEdit, row, 1); layout->addWidget(hostLabel, ++row, 0); layout->addWidget(mHostEdit, row, 1); layout->addWidget(portLabel, ++row, 0); layout->addWidget(mPortEdit, row, 1); layout->addWidget(userNameLabel, ++row, 0); layout->addWidget(mUserNameEdit, row, 1); layout->addWidget(mConnectButton, ++row, 1); QHBoxLayout *mSGBLayout = new QHBoxLayout(mSchedulerBox); mSchedulerBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum); mSGBLayout->addWidget(mPBSRadioButton); mSGBLayout->addWidget(mSGERadioButton); layout->addWidget(mSchedulerBox, ++row, 1); mSchedulerButtonGroup = new QButtonGroup(this); mSchedulerButtonGroup->addButton(mPBSRadioButton); mSchedulerButtonGroup->addButton(mSGERadioButton); layout->addWidget(mSchedulerBox, ++row, 1); layout->addWidget(mCommandSubmitButton, ++row, 1); layout->addWidget(mCommandEdit, row, 2); layout->addWidget(mListAllQueuesButton, ++row, 0); layout->addWidget(mGetQueueInfoButton, row, 1); layout->addWidget(mGetQueueInfoTextEdit, row, 2); layout->addWidget(mGetAllNodeInfoButton, ++row, 1); layout->addWidget(mSubmitJobButton, ++row, 1); layout->addWidget(mSubmitJobTextEdit, row, 2); layout->addWidget(mGetAllJobInfoButton, ++row, 1); layout->addWidget(mDeleteJobButton, ++row, 1); layout->addWidget(mDeleteJobTextEdit, row, 2); layout->addWidget(mTextEdit, ++row, 0, 2, 3); row++; layout->addWidget(mOpenFileButton, ++row, 1); layout->addWidget(mOpenFileEdit, row, 2); layout->addWidget(mOpenDirButton, ++row, 1); layout->addWidget(mOpenDirEdit, row, 2); connect(mConnectButton, &QPushButton::pressed, this, &ExamplePortalWidget::connectToHost); connect(mSchedulerButtonGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](int id) { (void)sizeof(id); QString name = mSchedulerButtonGroup->checkedButton()->text(); if ("PBS" == name) queue = &queuePBS; else if ("SGE" == name) queue = &queueSGE; }); mSGERadioButton->click(); connect(mCommandSubmitButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitCommandToHost); connect(mListAllQueuesButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitListAllQueuesToHost); connect(mGetQueueInfoButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitGetQueueInfoToHost); connect(mGetAllNodeInfoButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitGetAllNodeInfoToHost); connect(mGetAllJobInfoButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitGetAllJobInfoToHost); connect(mSubmitJobButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitSubmitJobToHost); connect(mDeleteJobButton, &QPushButton::pressed, this, &ExamplePortalWidget::submitDeleteJobToHost); mSessionCon = std::make_shared(); connect(mSessionCon.get(), &SessionController::connectionFailed, this, &ExamplePortalWidget::connectionFailed); connect(mSessionCon.get(), &SessionController::connectionSuccessful, this, &ExamplePortalWidget::connectionSuccessful); connect(mSessionCon.get(), &SessionController::disconnectSuccessful, this, &ExamplePortalWidget::disconnectSuccessful); connect(mSessionCon.get(), &SessionController::interactiveAuthenticationRequested, this, &ExamplePortalWidget::interactiveAuthenticationRequested); connect(mSessionCon.get(), &SessionController::getServerPublicKeyFailed, this, &ExamplePortalWidget::getServerPublicKeyFailed); connect(mSessionCon.get(), &SessionController::hostUnknown, this, &ExamplePortalWidget::hostUnknown); connect(mSessionCon.get(), &SessionController::hostPublicKeyChanged, this, &ExamplePortalWidget::hostPublicKeyChanged); connect(mSessionCon.get(), &SessionController::verifyKnownHostSuccessful, this, &ExamplePortalWidget::verifyKnownHostSuccessful); connect(mSessionCon.get(), &SessionController::knownHostError, this, &ExamplePortalWidget::knownHostError); connect(mSessionCon.get(), &SessionController::authenticationError, this, &ExamplePortalWidget::authenticationError); connect(mSessionCon.get(), &SessionController::authenticationSucceeded, this, &ExamplePortalWidget::authenticationSucceeded); connect(mSessionCon.get(), &SessionController::passwordRequested, this, &ExamplePortalWidget::passwordRequested); connect(mSessionCon.get(), &SessionController::loginBannerIssued, this, &ExamplePortalWidget::loginBannerIssued); connect(mSessionCon.get(), &SessionController::execOutputReady, this, &ExamplePortalWidget::execOutputReady); connect(mSessionCon.get(), &SessionController::execFailed, this, &ExamplePortalWidget::execFailed); connect(mSessionCon.get(), &SessionController::execFinished, this, &ExamplePortalWidget::execFinished); connect(mOpenFileButton, &QPushButton::pressed, this, &ExamplePortalWidget::openFile); connect(mOpenDirButton, &QPushButton::pressed, this, &ExamplePortalWidget::openDir); } void ExamplePortalWidget::connectToHost() { radix_tagged_line("Host:" << mHostEdit->text().toStdString()); if (mConnectButton->text().compare("Disconnect") == 0) { mSessionCon->disconnect(); mConnectButton->setText("Connect"); } else { mSessionCon->setProxyCommand(mProxyEdit->text()); mSessionCon->setHost(mHostEdit->text()); mSessionCon->setPort(mPortEdit->text().toInt()); mSessionCon->setUser(mUserNameEdit->text()); mSessionCon->connect(); } } void ExamplePortalWidget::submitCommandToHost() { radix_tagged_line("submitCommandToHost()"); QString command = mCommandEdit->text(); submitCommand("custom", command); } void ExamplePortalWidget::submitListAllQueuesToHost() { radix_tagged_line("submitListAllQueuesToHost()"); QString command = queue->listAllQueues(); submitCommand("listAllQueues", command); } void ExamplePortalWidget::submitGetQueueInfoToHost() { radix_tagged_line("submitGetQueueInfoToHost()"); QString command = queue->showQueueInfo(mGetQueueInfoTextEdit->text()); submitCommand("showQueueInfo", command); } void ExamplePortalWidget::submitGetAllNodeInfoToHost() { radix_tagged_line("submitGetAllNodeInfoToHost()"); QString command = queue->listAllNodeInfo(); submitCommand("listAllNodeInfo", command); } void ExamplePortalWidget::submitGetAllJobInfoToHost() { radix_tagged_line("submitGetAllJobInfoToHost()"); QString command = queue->checkJobs(QStringList()); submitCommand("checkJobs", command); } void ExamplePortalWidget::submitSubmitJobToHost() { radix_tagged_line("submitSubmitJobToHost()"); QStringList jobIDs = QStringList(); QString command = queue->submitJob(mSubmitJobTextEdit->text()); submitCommand("submitJob", command); } void ExamplePortalWidget::submitDeleteJobToHost() { radix_tagged_line("submitDeleteJobToHost()"); QStringList jobIDs = QStringList(); if (mDeleteJobTextEdit->text().length() > 0) jobIDs = mDeleteJobTextEdit->text().split(QRegExp("[ ,]")); QString command = queue->deleteJobs(jobIDs); submitCommand("deleteJobs", command); } void ExamplePortalWidget::submitCommand(QString commandType, QString command) { if ("" != execingCommandType) return; execingCommandType = commandType; mSessionCon->requestExec(command); } void ExamplePortalWidget::connectionFailed(QString message) { mTextEdit->append("Connection failed.\n"); mTextEdit->append(message); } void ExamplePortalWidget::connectionSuccessful() { mTextEdit->append("Connection successful.\nVerifying host...\n"); mSessionCon->verifyKnownHost(); } void ExamplePortalWidget::disconnectSuccessful() { mTextEdit->append("Disconnected.\n"); } void ExamplePortalWidget::verifyKnownHostSuccessful() { mTextEdit->append("Verification successful.\nAuthenticating...\n"); mSessionCon->authenticate(); } void ExamplePortalWidget::interactiveAuthenticationRequested( QString instruction, QString name, QStringList prompts) { mTextEdit->append("Interactive authentication requested."); mTextEdit->append("Instruction: "); mTextEdit->append(instruction); mTextEdit->append("Name:"); mTextEdit->append(name); for (int i = 0; i < prompts.size(); ++i) { mTextEdit->append(prompts.at(i)); } if (!prompts.isEmpty()) { QString text = QInputDialog::getText(this, "Authentication", prompts.at(0), QLineEdit::Password); if (text.isEmpty()) { mSessionCon->disconnect(); } else { QStringList responses; responses << text; mSessionCon->authenticatePrompts(responses); } } else { radix_tagged_line("Reponsing with empty handshake."); QStringList empty; mSessionCon->authenticatePrompts(empty); } } void ExamplePortalWidget::getServerPublicKeyFailed() { mTextEdit->append("Retrieval of host's public key failed.\n"); mSessionCon->disconnect(); } void ExamplePortalWidget::hostUnknown(QString host_hash) { int ret = QMessageBox::warning( this, tr("Host Unknown"), QString("The remote host is unknown.\n") .append("Are you sure you want to continue connecting?\n") .append("Remote host key:") .append(host_hash), QMessageBox::Yes | QMessageBox::Cancel); if (ret == QMessageBox::Yes) { mSessionCon->acceptHostPublicKeyUpdate(); } else { mSessionCon->disconnect(); } } void ExamplePortalWidget::hostPublicKeyChanged(QString host_hash) { mTextEdit->append("Host key has changed.\nChanged key:"); mTextEdit->append(host_hash); mTextEdit->append("This could be a man-in-the-middle attack.\n"); mSessionCon->disconnect(); } void ExamplePortalWidget::hostPublicKeyUnavailable() { mTextEdit->append("Host key is unavailable.\n"); mSessionCon->disconnect(); } void ExamplePortalWidget::knownHostError(QString message) { mTextEdit->append("Error verifying known host.\n"); mTextEdit->append(message); mTextEdit->append("\n"); mSessionCon->disconnect(); } void ExamplePortalWidget::authenticationError(QString message) { mTextEdit->append("Authentication error.\n"); mTextEdit->append(message); mTextEdit->append("\n"); mSessionCon->disconnect(); } void ExamplePortalWidget::authenticationSucceeded() { mTextEdit->append("Authentication succeeded."); mTextEdit->append("\n"); mConnectButton->setText("Disconnect"); } void ExamplePortalWidget::passwordRequested() { mTextEdit->append("Password requested."); mTextEdit->append("\n"); QString text = QInputDialog::getText(this, "Authentication", "Password:", QLineEdit::Password); if (text.isEmpty()) { mSessionCon->disconnect(); } else { mSessionCon->authenticateWithPassword(text); } } void ExamplePortalWidget::loginBannerIssued(QString message) { int ret = QMessageBox::warning(this, tr("Host Login Banner"), message, QMessageBox::Ok | QMessageBox::Cancel); if (ret != QMessageBox::Ok) { mSessionCon->disconnect(); } mTextEdit->append(message); mTextEdit->append("\n"); } void ExamplePortalWidget::execOutputReady() { mTextEdit->append(mSessionCon->readExecOutput()); } void ExamplePortalWidget::execFailed(QString message) { radix_tagged_line(message.toStdString()); mTextEdit->append(message); mTextEdit->append("\n"); execingCommandType = ""; } void ExamplePortalWidget::execFinished() { mTextEdit->append("Execution finished.\n"); if ("submitJob" == execingCommandType) { int jobID = queueSGE.parseSubmitJobReturn(mSessionCon->readExecOutput()); fprintf(stderr, "%d\n", jobID); } if ("checkJobs" == execingCommandType) { QSet jobIDs = queueSGE.parseCheckJobsReturn(mSessionCon->readExecOutput()); fprintf(stderr, "--\n"); for (auto jobID : jobIDs) fprintf(stderr, "%d\n", jobID); fprintf(stderr, "--\n"); } if ("deleteJobs" == execingCommandType) { QSet jobIDs = queueSGE.parseDeleteJobsReturn(mSessionCon->readExecOutput()); fprintf(stderr, "--\n"); for (auto jobID : jobIDs) fprintf(stderr, "%d\n", jobID); fprintf(stderr, "--\n"); } execingCommandType = ""; } void ExamplePortalWidget::openFile() { radix_tagged_line( "Opening remote file:" << mOpenFileEdit->text().toStdString()); std::unique_ptr sftpSession( mSessionCon->session()->newSFTPSession()); std::unique_ptr sftpFile( sftpSession->openFile(mOpenFileEdit->text(), O_RDONLY)); if (!sftpFile->isOpen()) { mTextEdit->append("FAILED to open file"); return; } // read some of the file QString tmpStr = sftpFile->read(1000); if (!sftpFile->isOpen()) { { mTextEdit->append("ERROR reading file"); return; } } mTextEdit->append("File contents:"); mTextEdit->append(tmpStr); if (!sftpFile->close()) { mTextEdit->append("ERROR closing file"); return; } } void ExamplePortalWidget::openDir() { radix_tagged_line( "Opening remote directory:" << mOpenFileEdit->text().toStdString()); std::unique_ptr sftpSession( mSessionCon->session()->newSFTPSession()); std::unique_ptr sftpDir(sftpSession->openDir(mOpenDirEdit->text())); if (!sftpDir->isOpen()) { mTextEdit->append("FAILED to open directory"); return; } mTextEdit->append("Directory entries:"); // read dir entries while (sftpDir->hasNext()) { SFTPAttributes *a = sftpDir->next(); if (nullptr == a) { mTextEdit->append("ERROR reading directory entry"); break; } mTextEdit->append(a->longname); delete a; } if (!sftpDir->close()) { mTextEdit->append("ERROR closing directory"); return; } } // ---------------------------------------------------------------------------- MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setGeometry(120, 120, 720, 720); QTabWidget *tab = new QTabWidget(this); ExamplePortalWidget *portalView = new ExamplePortalWidget(tab); tab->addTab(portalView, "connect"); setCentralWidget(tab); } MainWindow::~MainWindow() {} /******************************************************************************/ /******************************** MAIN PROGRAM ********************************/ /******************************************************************************/ int main(int argc, char **argv) { QApplication app(argc, argv); MainWindow mainWindow; mainWindow.show(); mainWindow.raise(); return app.exec(); }