00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifdef ENABLE_SSH
00017
00018 #include <globalsearch/queueinterfaces/remote.h>
00019
00020 #include <globalsearch/sshmanager.h>
00021 #include <globalsearch/sshconnection.h>
00022 #include <globalsearch/structure.h>
00023
00024 #include <QtCore/QFile>
00025 #include <QtCore/QTextStream>
00026
00027 namespace GlobalSearch {
00028
00029 RemoteQueueInterface::RemoteQueueInterface(OptBase *parent,
00030 const QString &settingFile) :
00031 QueueInterface(parent)
00032 {
00033 m_idString = "AbstractRemote";
00034 }
00035
00036 RemoteQueueInterface::~RemoteQueueInterface()
00037 {
00038 }
00039
00040 bool RemoteQueueInterface::writeFiles(Structure *s,
00041 const QHash<QString, QString> &fileHash) const
00042 {
00043
00044 QList<QFile*> files;
00045 QStringList filenames = fileHash.keys();
00046 for (int i = 0; i < filenames.size(); i++) {
00047 files.append(new QFile (s->fileName() + "/" + filenames.at(i)));
00048 }
00049
00050
00051 for (int i = 0; i < files.size(); i++) {
00052 if (!files.at(i)->open( QIODevice::WriteOnly | QIODevice::Text ) ) {
00053 m_opt->error(tr("Cannot write input file %1 (file writing failure)", "1 is a file path").arg(files.at(i)->fileName()));
00054 qDeleteAll(files);
00055 return false;
00056 }
00057 }
00058
00059
00060 QList<QTextStream*> streams;
00061 for (int i = 0; i < files.size(); i++) {
00062 streams.append(new QTextStream (files.at(i)));
00063 }
00064
00065
00066 for (int i = 0; i < streams.size(); i++) {
00067 *(streams.at(i)) << fileHash[filenames.at(i)];
00068 }
00069
00070
00071 for (int i = 0; i < files.size(); i++) {
00072 files.at(i)->close();
00073 }
00074
00075
00076 qDeleteAll(streams);
00077 qDeleteAll(files);
00078
00079
00080 SSHConnection *ssh = m_opt->ssh()->getFreeConnection();
00081
00082 if (ssh == NULL) {
00083 m_opt->warning(tr("Cannot connect to ssh server."));
00084 return false;
00085 }
00086
00087 if (!createRemoteDirectory(s, ssh) ||
00088 !cleanRemoteDirectory(s, ssh) ) {
00089 m_opt->ssh()->unlockConnection(ssh);
00090 return false;
00091 }
00092
00093
00094 QStringList templates = fileHash.keys();
00095 for (QStringList::const_iterator
00096 it = templates.constBegin(),
00097 it_end = templates.constEnd();
00098 it != it_end;
00099 ++it) {
00100 if (!ssh->copyFileToServer(s->fileName() + "/" + (*it),
00101 s->getRempath() + "/" + (*it))) {
00102 m_opt->warning(tr("Error copying \"%1\" to remote server (structure %2)")
00103 .arg(*it)
00104 .arg(s->getIDString()));
00105 m_opt->ssh()->unlockConnection(ssh);
00106 return false;
00107 }
00108 }
00109 m_opt->ssh()->unlockConnection(ssh);
00110 return true;
00111 }
00112
00113 bool RemoteQueueInterface::prepareForStructureUpdate(Structure *s) const
00114 {
00115 SSHConnection *ssh = m_opt->ssh()->getFreeConnection();
00116
00117 if (ssh == NULL) {
00118 m_opt->warning(tr("Cannot connect to ssh server"));
00119 return false;
00120 }
00121
00122 if (!copyRemoteFilesToLocalCache(s, ssh)) {
00123 m_opt->ssh()->unlockConnection(ssh);
00124 return false;
00125 }
00126
00127 m_opt->ssh()->unlockConnection(ssh);
00128 return true;
00129 }
00130
00131 bool RemoteQueueInterface::checkIfFileExists(Structure *s,
00132 const QString &filename,
00133 bool *exists)
00134 {
00135 SSHConnection *ssh = m_opt->ssh()->getFreeConnection();
00136
00137 if (ssh == NULL) {
00138 m_opt->warning(tr("Cannot connect to ssh server"));
00139 return false;
00140 }
00141
00142 const QString searchPath = s->getRempath();
00143 const QString needle = s->getRempath() + "/" + filename;
00144 QStringList haystack;
00145
00146 if (!ssh->readRemoteDirectoryContents(searchPath, haystack)) {
00147 m_opt->warning(tr("Error reading directory %1 on %2@%3:%4")
00148 .arg(searchPath)
00149 .arg(ssh->getUser())
00150 .arg(ssh->getHost())
00151 .arg(ssh->getPort()));
00152 m_opt->ssh()->unlockConnection(ssh);
00153 return false;
00154 }
00155 m_opt->ssh()->unlockConnection(ssh);
00156
00157 *exists = false;
00158 for (QStringList::const_iterator
00159 it = haystack.constBegin(),
00160 it_end = haystack.constEnd();
00161 it != it_end; ++it) {
00162 if (it->compare(needle) == 0) {
00163
00164 *exists = true;
00165 break;
00166 }
00167 }
00168
00169 return true;
00170 }
00171
00172 bool RemoteQueueInterface::fetchFile(Structure *s,
00173 const QString &rel_filename,
00174 QString *contents) const
00175 {
00176 SSHConnection *ssh = m_opt->ssh()->getFreeConnection();
00177
00178 if (ssh == NULL) {
00179 m_opt->warning(tr("Cannot connect to ssh server"));
00180 return false;
00181 }
00182
00183 if (!ssh->readRemoteFile(s->fileName() + "/" + rel_filename,
00184 *contents)) {
00185 m_opt->ssh()->unlockConnection(ssh);
00186 return false;
00187 }
00188
00189 m_opt->ssh()->unlockConnection(ssh);
00190 return true;
00191 }
00192
00193 bool RemoteQueueInterface::grepFile(Structure *s,
00194 const QString &matchText,
00195 const QString &filename,
00196 QStringList *matches,
00197 int *exitcode,
00198 const bool caseSensitive) const
00199 {
00200
00201
00202
00203 SSHConnection *ssh = m_opt->ssh()->getFreeConnection();
00204
00205 if (ssh == NULL) {
00206 m_opt->warning(tr("Cannot connect to ssh server"));
00207 return false;
00208 }
00209
00210 QString flags = "";
00211 if (!caseSensitive) {
00212 flags = "-i";
00213 }
00214
00215 QString stdout_str;
00216 QString stderr_str;
00217 int ec;
00218 if (!ssh->execute(QString("grep %1 '%2' %3/%4")
00219 .arg(flags)
00220 .arg(matchText)
00221 .arg(s->getRempath())
00222 .arg(filename),
00223 stdout_str,
00224 stderr_str,
00225 ec)) {
00226 m_opt->ssh()->unlockConnection(ssh);
00227 return false;
00228 }
00229
00230 if (exitcode) {
00231 *exitcode = ec;
00232 }
00233
00234 if (matches) {
00235 *matches = stdout_str.split('\n',
00236 QString::SkipEmptyParts);
00237 }
00238
00239 m_opt->ssh()->unlockConnection(ssh);
00240 return true;
00241 }
00242
00243 bool RemoteQueueInterface::createRemoteDirectory(Structure *structure,
00244 SSHConnection *ssh) const
00245 {
00246 QString command = "mkdir -p \"" + structure->getRempath() + "\"";
00247 QString stdout_str, stderr_str;
00248 int ec;
00249 if (!ssh->execute(command, stdout_str, stderr_str, ec) || ec != 0) {
00250 m_opt->warning(tr("Error executing %1: %2").arg(command).arg(stderr_str));
00251 return false;
00252 }
00253 return true;
00254 }
00255
00256 bool RemoteQueueInterface::cleanRemoteDirectory(Structure *structure,
00257 SSHConnection *ssh) const
00258 {
00259
00260 if (!ssh->removeRemoteDirectory(structure->getRempath(), true)) {
00261 m_opt->warning(tr("Error clearing remote directory %1")
00262 .arg(structure->getRempath()));
00263 return false;
00264 }
00265 return true;
00266 }
00267
00268 bool RemoteQueueInterface::copyRemoteFilesToLocalCache(Structure *structure,
00269 SSHConnection *ssh) const
00270 {
00271 if (!ssh->copyDirectoryFromServer(structure->getRempath(),
00272 structure->fileName())) {
00273 m_opt->error("Cannot copy from remote directory for Structure "
00274 + structure->getIDString());
00275 return false;
00276 }
00277 return true;
00278 }
00279 }
00280
00281 #endif // ENABLE_SSH