Changeset 96c5e841


Ignore:
Timestamp:
08/20/13 14:21:00 (14 months ago)
Author:
Ken Moore <ken@…>
Branches:
master, 9.2-release, releng/10.0, releng/10.0.1, releng/10.0.2, releng/10.0.3
Children:
bf5b6c3
Parents:
0de3f5a
Message:

Add the ability to create an SSH Key file, and copy that key file to a msdosfs/FAT32 formatted USB stick (still needs testing)

Location:
src-qt4/life-preserver
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • src-qt4/life-preserver/LPBackend.cpp

    r2a5e337 r96c5e841  
    2020  } 
    2121  list.removeDuplicates(); 
     22    
    2223  return list;   
    2324} 
     
    3839    if(!ds.isEmpty()){ list << ds; } 
    3940  } 
     41    
    4042  return list; 
    4143} 
     
    6163  } 
    6264  list.removeDuplicates();       
     65    
    6366  return list; 
    6467} 
     
    9194    } 
    9295  } 
     96    
    9397  return list;   
    9498} 
     
    111115    } 
    112116  } 
     117    
    113118  return list;           
    114119} 
     
    127132  for(int i=2; i<out.length(); i++){ //first 2 lines are headers 
    128133    //Format: <dataset>:::<lastsnapshot | NONE>:::<lastreplication | NONE> 
     134    if(out[i].isEmpty()){ continue; } 
    129135    QString ds  = out[i].section(" - ",0,0).simplified(); 
    130136    QString snap = out[i].section(" - ",1,1).simplified(); 
     
    134140    list << ds +":::"+ snap+":::"+rep; 
    135141  } 
     142    
    136143  return list; 
    137144} 
     
    152159  QString cmd = "lpreserver cronsnap "+dataset+" start "+freq+" "+QString::number(numToKeep); 
    153160  int ret = system(cmd.toUtf8()); 
     161    
    154162  return (ret == 0); 
    155163} 
     
    158166  QString cmd = "lpreserver cronsnap "+dataset+" stop"; 
    159167  int ret = system(cmd.toUtf8());        
     168    
    160169  return (ret == 0); 
    161170} 
     
    188197  } 
    189198  //qDebug() << "lpreserver cronsnap:\n" << out << QString::number(time) << QString::number(numToKeep); 
     199    
    190200  return ok; 
    191201} 
     
    197207  QString cmd = "lpreserver mksnap "+dataset; 
    198208  int ret = system(cmd.toUtf8()); 
     209    
    199210  return (ret == 0); 
    200211} 
     
    203214  QString cmd = "lpreserver rmsnap "+dataset +" "+snapshot; 
    204215  int ret = system(cmd.toUtf8());        
     216    
    205217  return (ret == 0); 
    206218} 
     
    209221  QString cmd = "lpreserver revertsnap "+dataset +" "+snapshot; 
    210222  int ret  = system(cmd.toUtf8()); 
     223    
    211224  return (ret == 0); 
    212225} 
     
    268281  QString cmd = "lpreserver replicate add "+remotehost+" "+user+" "+ QString::number(port)+" "+dataset+" "+remotedataset+" "+stime; 
    269282  int ret = system(cmd.toUtf8()); 
     283   
    270284  return (ret == 0); 
    271285} 
     
    274288  QString cmd = "lpreserver replicate remove "+dataset; 
    275289  int ret = system(cmd.toUtf8());        
     290    
    276291  return (ret == 0); 
    277292} 
     
    302317    } 
    303318  }        
     319    
    304320  return ok; 
    305321} 
     322 
     323// ====================== 
     324//          SSH Key Management 
     325// ====================== 
     326bool LPBackend::setupSSHKey(QString remoteHost, QString remoteUser, int remotePort){ 
     327  QString LPPATH = "/usr/local/share/lifePreserver"; 
     328  QString cmd = "xterm -e \""+LPPATH+"/scripts/setup-ssh-keys.sh "+remoteUser+" "+remoteHost+" "+QString::number(remotePort)+"\""; 
     329  int ret = system(cmd.toUtf8()); 
     330  return (ret == 0); 
     331} 
     332 
     333QStringList LPBackend::findValidUSBDevices(){ 
     334  //Return format: "<mountpoint> (<device node>") 
     335  QString cmd = "mount"; 
     336  //Need output, so run this in a QProcess 
     337  QProcess *proc = new QProcess; 
     338  proc->setProcessChannelMode(QProcess::MergedChannels); 
     339  proc->start(cmd); 
     340  proc->waitForFinished(); 
     341  QStringList out = QString(proc->readAllStandardOutput()).split("\n");  
     342  delete proc; 
     343  //Now process the output 
     344  QStringList list; 
     345  for(int i=0; i<out.length(); i++){ 
     346    if(out[i].startsWith("/dev/da") && out[i].contains("(msdosfs,local)")){ 
     347      QString mountpoint = out[i].section(" on ",1,1).section("(",0,0).simplified(); 
     348      QString devnode = out[i].section(" on ",0,0).section("/",-1).simplified(); 
     349      list << mountpoint +" ("+devnode+")"; 
     350    } 
     351  } 
     352  return list; 
     353} 
     354 
     355bool LPBackend::copySSHKey(QString mountPath, QString localHost){ 
     356  QString publicKey = "/root/.ssh/id_rsa.pub"; 
     357  //copy the file onto the designated USB stick 
     358  if(!mountPath.endsWith("/")){ mountPath.append("/"); } 
     359  mountPath.append("root/.ssh/"+localHost+"-id_rsa.pub"); 
     360  bool ok = QFile::copy(publicKey, mountPath); 
     361  return ok; 
     362} 
  • src-qt4/life-preserver/LPBackend.h

    r2a5e337 r96c5e841  
    3333        static bool removeReplication(QString dataset); 
    3434        static bool replicationInfo(QString dataset, QString& remotehost, QString& user, int& port, QString& remotedataset, int& time); 
    35  
     35        //SSH Key Management 
     36        static bool setupSSHKey(QString remoteHost, QString remoteUser, int remotePort); 
     37        static QStringList findValidUSBDevices(); 
     38        static bool copySSHKey(QString mountPath, QString localHost); 
    3639}; 
    3740#endif 
  • src-qt4/life-preserver/LPConfig.ui

    r2a5e337 r96c5e841  
    77    <x>0</x> 
    88    <y>0</y> 
    9     <width>400</width> 
    10     <height>315</height> 
     9    <width>374</width> 
     10    <height>327</height> 
    1111   </rect> 
    1212  </property> 
     
    176176         </property> 
    177177         <layout class="QGridLayout" name="gridLayout_5"> 
    178           <item row="0" column="0"> 
    179            <layout class="QHBoxLayout" name="horizontalLayout_8"> 
    180             <item> 
    181              <widget class="QLabel" name="label_9"> 
    182               <property name="text"> 
    183                <string>Host Name</string> 
    184               </property> 
    185              </widget> 
    186             </item> 
    187             <item> 
    188              <widget class="QLineEdit" name="lineHostName"/> 
    189             </item> 
    190            </layout> 
    191           </item> 
    192           <item row="1" column="0"> 
    193            <layout class="QHBoxLayout" name="horizontalLayout_7"> 
    194             <item> 
    195              <widget class="QLabel" name="label_10"> 
    196               <property name="text"> 
    197                <string>User Name</string> 
    198               </property> 
    199              </widget> 
    200             </item> 
    201             <item> 
    202              <widget class="QLineEdit" name="lineUserName"/> 
    203             </item> 
    204            </layout> 
    205           </item> 
    206178          <item row="2" column="0"> 
    207179           <layout class="QHBoxLayout" name="horizontalLayout_4"> 
     
    271243            <item> 
    272244             <widget class="QLineEdit" name="lineRemoteDataset"/> 
     245            </item> 
     246           </layout> 
     247          </item> 
     248          <item row="1" column="0"> 
     249           <layout class="QHBoxLayout" name="horizontalLayout_7"> 
     250            <item> 
     251             <widget class="QLabel" name="label_10"> 
     252              <property name="text"> 
     253               <string>User Name</string> 
     254              </property> 
     255             </widget> 
     256            </item> 
     257            <item> 
     258             <widget class="QLineEdit" name="lineUserName"/> 
     259            </item> 
     260           </layout> 
     261          </item> 
     262          <item row="0" column="0"> 
     263           <layout class="QHBoxLayout" name="horizontalLayout_8"> 
     264            <item> 
     265             <widget class="QLabel" name="label_9"> 
     266              <property name="text"> 
     267               <string>Host Name</string> 
     268              </property> 
     269             </widget> 
     270            </item> 
     271            <item> 
     272             <widget class="QLineEdit" name="lineHostName"/> 
    273273            </item> 
    274274           </layout> 
     
    324324           </widget> 
    325325          </item> 
     326          <item row="5" column="0"> 
     327           <spacer name="verticalSpacer"> 
     328            <property name="orientation"> 
     329             <enum>Qt::Vertical</enum> 
     330            </property> 
     331            <property name="sizeHint" stdset="0"> 
     332             <size> 
     333              <width>20</width> 
     334              <height>40</height> 
     335             </size> 
     336            </property> 
     337           </spacer> 
     338          </item> 
    326339         </layout> 
    327340        </widget> 
  • src-qt4/life-preserver/LPTray.cpp

    r2a5e337 r96c5e841  
    106106  } 
    107107  if(GUI->isVisible()){ 
    108     GUI->updateDisplay(); 
     108    GUI->setupUI(); 
    109109  } 
    110110} 
  • src-qt4/life-preserver/lPreserve.qrc

    r2a5e337 r96c5e841  
    11<RCC> 
    2   <qresource prefix="" > 
     2  <qresource> 
     3    <file>images/upload.png</file> 
     4    <file>images/key.png</file> 
    35    <file>images/lifepreserver.png</file> 
    46    <file>images/backup-ok.png</file> 
  • src-qt4/life-preserver/life-preserver.pro

    r2a5e337 r96c5e841  
    2828target.path=/usr/local/bin 
    2929 
     30scripts.path=/usr/local/share/lifePreserver/scripts 
     31scripts.files=scripts/setup-ssh-keys.sh 
     32 
    3033images.path=/usr/local/share/lifePreserver/images/ 
    3134images.files=images/lifepreserver.png 
     
    4043dotrans.extra=cd i18n && lrelease-qt4 -nounfinished *.ts && cp *.qm /usr/local/share/lifePreserver/i18n/ 
    4144 
    42 INSTALLS += target dotrans images 
     45INSTALLS += target dotrans images scripts 
    4346 
    4447TRANSLATIONS =  i18n/LifePreserver_af.ts \ 
  • src-qt4/life-preserver/mainUI.cpp

    r2a5e337 r96c5e841  
    1515  connect(brMenu,SIGNAL(triggered(QAction*)),this,SLOT(slotBrowseSnapshot(QAction*)) ); 
    1616  connect(addMenu, SIGNAL(triggered(QAction*)),this,SLOT(slotAddDataset(QAction*)) ); 
     17  //Setup the Key menu items (static items, never changed) 
     18  keyMenu = new QMenu(); 
     19    keyMenu->addAction(ui->actionKeyNew); //action from designer 
     20    keyMenu->addAction(ui->actionKeyCopy); //action from designer 
     21  ui->tool_keys->setMenu(keyMenu); 
     22  //Setup the update frequency limiter 
     23  freqTimer = new QTimer(); 
     24        freqTimer->setSingleShot(true); 
     25        freqTimer->setInterval(15000); 
     26        connect(freqTimer, SIGNAL(timeout()), this, SLOT(setupUI()) ); 
    1727} 
    1828 
     
    2232 
    2333void mainUI::setupUI(){ 
    24   qDebug() << "Setting up Life Preserver UI..."; 
    25   //Initialize the Hash 
    26   updateHash(); 
     34  //Initialize the Hash (make sure it is not run too frequently - causes kernel panics) 
     35  if(lastUpdate.isNull() || lastUpdate.addSecs(15) < QTime::currentTime() ){ 
     36    lastUpdate = QTime::currentTime();     
     37    qDebug() << "Updating the database"; 
     38    updateHash(); 
     39  }else{ 
     40    freqTimer->start(); 
     41  } 
    2742  //Update the display 
    28   updateUI(); 
    29   updateMenus(); 
    30 } 
    31  
    32 void mainUI::updateDisplay(){ 
    33   //Public function for the tray to be able to request that the UI update  
    34   // (In case there is a status message that goes by which changes things) 
    35   updateHash(); 
    3643  updateUI(); 
    3744  updateMenus(); 
     
    6572  } 
    6673  if(CLIST.isEmpty()){ ci = -1; } //catch for empty list 
    67    
    68   if(subsets.isEmpty()){ 
     74  if(DSC.subsetHash.size() < 1){ 
    6975    DSC.numberOfSnapshots = "0"; 
    7076    DSC.latestSnapshot= ""; 
     
    7379    DSC.numberOfSnapshots = QString::number(fSnap.length()); 
    7480    if(fSnap.isEmpty()){ DSC.latestSnapshot=""; } 
    75     else if(ci > -1){  
     81    else if(ci > -1 && ci < CLIST.length()){  
    7682      QString sna = CLIST[ci].section(":::",1,1); 
    7783      if(sna != "-"){ DSC.latestSnapshot= sna; } 
     
    95101// ================= 
    96102void mainUI::updateHash(QString ds){ 
     103  //qDebug() << "Get replication targets"; 
    97104  RLIST = LPBackend::listReplicationTargets(); //update list of replication datasets 
     105  //qDebug() << "Get possible datasets"; 
    98106  SLIST = LPBackend::listPossibleDatasets(); 
     107  //qDebug() << "List current status"; 
    99108  CLIST = LPBackend::listCurrentStatus(); 
     109  //qDebug() << "Check hash"; 
    100110  if(HLIST.contains(ds) && !ds.isEmpty()){ 
    101111    //only update the entry for the given dataset 
     
    103113  }else{ 
    104114    //Clear and fill the hash 
     115    //qDebug() << "Clear hash"; 
    105116    HLIST.clear(); 
     117    //qDebug() << "List datasets"; 
    106118    QStringList dsList = LPBackend::listDatasets(); 
    107119    for(int i=0; i<dsList.length(); i++){ 
     
    109121    } 
    110122  } 
    111  
     123  //qDebug() << "Done with Hash Update"; 
    112124} 
    113125 
     
    146158    ui->tool_remove->setVisible(false); 
    147159    ui->tool_config->setVisible(false); 
     160 
    148161  }else{ 
    149162    ui->tool_remove->setVisible(true); 
    150163    ui->tool_config->setVisible(true);     
     164  } 
     165  //Enabled/disable the SSH key management 
     166  if(RLIST.contains(ds) && !ds.isEmpty()){ 
     167    ui->tool_keys->setVisible(true); 
     168  }else{ 
     169    ui->tool_keys->setVisible(false); 
    151170  } 
    152171  //check for a valid ds/snapshot combination 
     
    225244  //Now update the UI if appropriate 
    226245  if(change){ 
    227     updateHash(ds); 
    228     updateUI(); 
    229     updateMenus(); 
     246    setupUI(); 
    230247  } 
    231248} 
     
    251268    } 
    252269  } 
    253   updateHash(); 
    254   updateUI(); 
    255   updateMenus(); 
     270  setupUI(); 
    256271} 
    257272 
     
    331346  } 
    332347  //Now update the UI/Hash 
    333   updateHash(); 
    334   updateUI(); 
    335   updateMenus(); 
     348  setupUI(); 
    336349} 
    337350 
     
    339352  this->close(); 
    340353} 
     354 
     355void mainUI::on_actionKeyNew_triggered(){ 
     356  QString ds = getSelectedDS(); 
     357  qDebug() << "New SSH Key triggered for DS:" << ds; 
     358  //Get the remote values for this dataset 
     359  QString remoteHost, user, remotedataset; 
     360  int port, time; 
     361  bool ok = LPBackend::replicationInfo(ds, remoteHost, user, port, remotedataset,  time); 
     362  if(ok){ 
     363    if( !LPBackend::setupSSHKey(remoteHost, user, port) ){ 
     364      QMessageBox::warning(this,tr("Failure"), tr("There was an error while creating the SSH key.")); 
     365    }else{ 
     366      QMessageBox::information(this,tr("Success"), tr("The SSH key was successfully generated.")); 
     367    } 
     368  }else{ 
     369    QMessageBox::warning(this,tr("Failure"), tr("There was an error in retrieving the remote replication information for this dataset. Please ensure that replication is enabled and try agin.") ); 
     370  } 
     371} 
     372 
     373void mainUI::on_actionKeyCopy_triggered(){ 
     374  QString ds = getSelectedDS();  
     375  qDebug() << "Copy SSH Key triggered for DS:" << ds; 
     376  //Get the local hostname 
     377  char host[1023] = "\0"; 
     378  gethostname(host,1023); 
     379  QString localHost = QString(host).simplified(); 
     380  qDebug() << " - hostname:" << localHost; 
     381  //Scan for mounted USB devices 
     382  QStringList devs = LPBackend::findValidUSBDevices(); 
     383  qDebug() << " - devs:" << devs; 
     384  if(devs.isEmpty()){ 
     385    QMessageBox::warning(this,tr("No Valid USB Devices"), tr("No valid USB devices could be found. Please mount a FAT32 formatted USB stick and try again.")); 
     386    return; 
     387  } 
     388  //Ask the user which one to save the file to 
     389  bool ok; 
     390  QString dev = QInputDialog::getItem(this, tr("Select USB Device"), tr("Available USB Devices:"), devs,0,false,&ok);    
     391  if(!ok or dev.isEmpty()){ return; } //cancelled 
     392  QString devPath = dev.section("(",0,0).simplified(); 
     393  //Now copy the file over 
     394  ok = LPBackend::copySSHKey(devPath, localHost); 
     395  if(ok){ 
     396    QMessageBox::information(this,tr("Success"), tr("The public SSH key file was successfully copied onto the USB device.")); 
     397  }else{ 
     398    QMessageBox::information(this,tr("Failure"), tr("The public SSH key file could not be copied onto the USB device.")); 
     399  } 
     400} 
     401 
    341402 
    342403// ============= 
  • src-qt4/life-preserver/mainUI.h

    r2a5e337 r96c5e841  
    1111#include <QCloseEvent> 
    1212#include <QFileDialog> 
     13#include <QInputDialog> 
     14#include <QTime> 
     15#include <QTimer> 
    1316 
    1417#include "LPBackend.h" 
     
    2932        explicit mainUI(QWidget* parent = 0); 
    3033        ~mainUI(); 
    31         void setupUI(); 
    3234 
    33         void updateDisplay(); //for the tray to call it as necessary 
     35 
     36public slots: 
     37        void setupUI(); //for the tray to call it as necessary 
    3438 
    3539private: 
     
    3943        QStringList SLIST; //available datasets on the system 
    4044        QStringList CLIST; //current status for all datasets 
    41         QMenu *revMenu, *brMenu, *addMenu; //revert/browse menu's 
     45        QMenu *revMenu, *brMenu, *addMenu, *keyMenu; //button menu's 
     46        QTime lastUpdate; 
     47        QTimer *freqTimer; 
    4248 
    4349        void updateHash(QString ds=""); 
     
    5763 
    5864        void on_actionClose_triggered(); 
     65        void on_actionKeyNew_triggered(); 
     66        void on_actionKeyCopy_triggered(); 
    5967 
    6068protected: 
  • src-qt4/life-preserver/mainUI.ui

    r2a5e337 r96c5e841  
    114114       </item> 
    115115       <item> 
     116        <widget class="QToolButton" name="tool_keys"> 
     117         <property name="statusTip"> 
     118          <string>Manage SSH keys for replication authentication</string> 
     119         </property> 
     120         <property name="text"> 
     121          <string>Key Setup</string> 
     122         </property> 
     123         <property name="icon"> 
     124          <iconset resource="lPreserve.qrc"> 
     125           <normaloff>:/images/key.png</normaloff>:/images/key.png</iconset> 
     126         </property> 
     127         <property name="popupMode"> 
     128          <enum>QToolButton::InstantPopup</enum> 
     129         </property> 
     130        </widget> 
     131       </item> 
     132       <item> 
    116133        <spacer name="horizontalSpacer_2"> 
    117134         <property name="orientation"> 
     
    192209   </property> 
    193210  </action> 
     211  <action name="actionKeyCopy"> 
     212   <property name="icon"> 
     213    <iconset resource="lPreserve.qrc"> 
     214     <normaloff>:/images/upload.png</normaloff>:/images/upload.png</iconset> 
     215   </property> 
     216   <property name="text"> 
     217    <string>Copy To USB Stick</string> 
     218   </property> 
     219  </action> 
     220  <action name="actionKeyNew"> 
     221   <property name="icon"> 
     222    <iconset resource="lPreserve.qrc"> 
     223     <normaloff>:/images/list-add.png</normaloff>:/images/list-add.png</iconset> 
     224   </property> 
     225   <property name="text"> 
     226    <string>Generate SSH Key</string> 
     227   </property> 
     228  </action> 
    194229 </widget> 
    195230 <resources> 
Note: See TracChangeset for help on using the changeset viewer.