source: src-qt4/life-preserver/lp-gui/LPGUtils.cpp @ b15a1b6

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2
Last change on this file since b15a1b6 was b15a1b6, checked in by Ken Moore <ken@…>, 9 months ago

Remove the *.desktop exclusion from the new LP. Kris reminded me that people might have customized *.desktop files that they want to keep, and it is better to have the user remove dead files afterward rather than lose important files.

  • Property mode set to 100644
File size: 10.5 KB
Line 
1#include "LPGUtils.h"
2
3LPDataset LPGUtils::loadPoolData(QString zpool){
4  //Load the current information for the given zpool
5  qDebug() << "New Dataset: " << zpool;
6  LPDataset DSC;
7  //List all the mountpoints in this dataset
8  QStringList subsets = LPBackend::listDatasetSubsets(zpool);
9  QStringList lpsnaps = LPBackend::listLPSnapshots(zpool);
10  //populate the list of snapshots available for each mountpoint
11  for(int i=0; i<subsets.length(); i++){
12    //qDebug() << "Subset:" << subsets[i];
13    QStringList snaps = LPBackend::listSnapshots(subsets[i]);
14    //qDebug() << " - Snapshots:" << snaps;
15    if(snaps.isEmpty()){
16      //invalid subset - remove it from the list
17      subsets.removeAt(i);
18      i--;
19    }else{
20      QStringList subsnaps;
21      //only list the valid snapshots that life preserver created
22      for(int s=0; s<lpsnaps.length(); s++){
23        int index = snaps.indexOf(lpsnaps[s]);
24        if(index > -1){ subsnaps << lpsnaps[s]; snaps.removeAt(index); }
25      }
26      /*//Now list all the other available snapshots (no certain ordering)
27      if(!snaps.isEmpty()){try
28        subsnaps << "--"; //so we know that this is a divider between the sections
29        subsnaps << snaps;
30      }*/
31      DSC.subsetHash.insert(subsets[i],subsnaps); //add it to the internal container hash
32    }
33  }
34  //Parse "zpool status <pool>"
35  QStringList zstat = LPBackend::getCmdOutput("zpool status "+zpool);
36  //qDebug() << "zpool status "+zpool+":\n" << zstat.join("\n");
37  bool atheader=false;
38  QStringList disks, diskstates, running, errors, finished;
39  for(int i=0; i<zstat.length(); i++){
40    if(zstat[i].isEmpty()){ continue; }
41    else if(zstat[i].startsWith("  scan:")){
42      QString line = zstat[i].section(":",1,50).replace("\t"," ").simplified();
43      if(line.contains("scrub repaired ")){
44        QString timestamp = line.section(" ",9,13,QString::SectionSkipEmpty);
45        QString numerrors = line.section(" ",6,6,QString::SectionSkipEmpty);
46        finished << QString(QObject::tr("Scrub Finished: %1 (%2 errors)")).arg(timestamp, numerrors);
47      }else if(line.contains("scrub cancel")){
48         QString timestamp = line.section(" ",3,7,QString::SectionSkipEmpty);     
49          finished << QString(QObject::tr("Scrub Cancelled: %1")).arg(timestamp);
50      }else if(line.contains("scrub")){
51        QString timestamp = line.section(" ",4,8,QString::SectionSkipEmpty);
52        running << QString(QObject::tr("Scrub Started: %1")).arg(timestamp);     
53      }else if(line.contains("resilvered")){
54        QString timestamp = line.section(" ",8,12,QString::SectionSkipEmpty);
55        QString numerrors = line.section(" ",5,5,QString::SectionSkipEmpty);
56        finished << QString(QObject::tr("Resilver Finished: %1 (%2 errors)")).arg(timestamp, numerrors);
57      }
58    }else if(zstat[i].contains("NAME") && zstat[i].contains("STATE") && zstat[i].contains("READ") ){
59      //qDebug() <<"Found header";
60      atheader=true;
61    }else if(zstat[i].startsWith("errors:")){ 
62      atheader=false; 
63    }else if(atheader){
64      QString line = zstat[i].replace("\t"," ").simplified();
65      QString dev = line.section(" ",0,0,QString::SectionSkipEmpty);
66      QString state = line.section(" ",1,1,QString::SectionSkipEmpty);
67      //qDebug() << "Found device:" << dev << state;
68      if(dev == zpool){
69        DSC.poolStatus = state;
70      }else if(line.contains("(resilvering)")){
71        disks << dev; diskstates << state; //record this disk and state
72        running << QString(QObject::tr("%1: Currently Resilvering")).arg(dev);
73      }else{
74        disks << dev; diskstates << state; //record this disk and state
75        if(state != "ONLINE"){
76          errors << QString(QObject::tr("%1: %2")).arg(dev, state);
77        }
78      }
79    }
80  }
81  //Now get the latest Snapshot/Replication information
82  QStringList lpstat = LPBackend::listCurrentStatus();
83  for(int i=0; i<lpstat.length(); i++){
84    if(lpstat[i].section(":::",0,0) == zpool){
85      QString lastSnap = lpstat[i].section(":::",1,1);
86      QString lastRep = lpstat[i].section(":::",2,2);
87      if(lastSnap=="-"){ DSC.latestSnapshot = QObject::tr("No Snapshots Available"); }
88      else{ DSC.latestSnapshot = lastSnap; }
89      if(lastRep!="-"){
90        finished << QString(QObject::tr("Latest Replication: %1")).arg(lastRep);
91      }else if(LPBackend::listReplicationTargets().contains(zpool) ){
92        errors << QObject::tr("No Successful Replication");
93      }
94    }
95  }
96  //Now save the info to the dataset
97  DSC.harddisks = disks;
98  DSC.harddiskStatus = diskstates;
99  DSC.errorStatus = errors.join("\n");
100  DSC.runningStatus = running.join("\n");
101  DSC.finishedStatus = finished.join("\n");
102  //Return the dataset
103  return DSC;
104}
105
106QString LPGUtils::generateReversionFileName(QString fileName, QString destDir){
107  fileName = fileName.section("/",-1); //Make sure we only have the filename (no paths)
108  if( !destDir.endsWith("/") ){ destDir.append("/"); }
109  //Quick check if that file already exists in the destination directory
110  if( !QFile::exists(destDir+fileName) ){ return fileName; }
111  //Change the filename to prevent overwriting an existing file
112  QString ext = fileName.section(".",-1); //Get the extension for the filename
113  if( fileName != ext && fileName != ("."+ext) ){
114    //Extension found - need careful adjustment of filename
115    QString newFileName = fileName;
116    newFileName.replace("."+ext, "-reversion."+ext);
117    int i=2;
118    while( QFile::exists(destDir+newFileName) ){
119      //Also need to append a reversion number
120      newFileName = fileName; 
121      newFileName.replace("."+ext, "-reversion"+QString::number(i)+"."+ext);
122      i++; //for the next time around
123    }
124    fileName = newFileName;
125  }else{
126    //no extension - just append the reversion
127    fileName.append("-reversion");
128    if(QFile::exists(destDir+fileName) ){
129      //Also need to append a reversion number
130      int i=2;
131      while( QFile::exists(destDir+fileName+QString::number(i)) ){ i++; }
132      fileName.append( QString::number(i) );
133    }
134  }
135  return fileName;
136}
137
138bool LPGUtils::revertFile(QString oldPath, QString newPath){
139  bool ok = QFile::copy(oldPath,newPath);
140  //return the path to the new file if the copy was successful
141  if(ok){ 
142    //reset the permissions on the reverted file to match the original
143    QFile::setPermissions(newPath, QFile::permissions(oldPath));
144    QFileInfo FI(oldPath);
145      system( QString("chown "+FI.owner()+":"+FI.group()+" "+newPath).toUtf8() );
146  }
147  return ok;
148}
149
150QStringList LPGUtils::revertDir(QString oldPath, QString newPath){
151  //Note: this is a recursive function and can take quite a while to perform lots of file copies
152
153  //Load the directories and create it if necessary
154  QDir oDir(oldPath);
155  QDir nDir(newPath);
156  bool ok=true;
157  if( !nDir.exists() ){
158    //Create the new Directory
159    nDir.cdUp();
160    ok = nDir.mkdir(newPath.section("/",-1));
161    if(ok){ 
162      nDir.cd(newPath.section("/",-1)); 
163      QFile::setPermissions(newPath, QFile::permissions(oldPath)); //make sure the new dir has the old permissions
164      QFileInfo FI(oldPath);
165      system( QString("chown "+FI.owner()+":"+FI.group()+" "+newPath).toUtf8() );
166    }
167  }
168  //Get a list of any files that error
169  QStringList errors;
170  if(!ok){
171    errors << newPath;
172    return errors;
173  }
174  //Get a list of all the files in the old dir and copy them over
175  QStringList fList = oDir.entryList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name);
176  for(int i=0; i<fList.length(); i++){
177    if( !revertFile(oldPath+"/"+fList[i], newPath+"/"+fList[i]) ){
178       errors << newPath+"/"+fList[i];
179    }
180  }
181  //Now list all the directories in the old dir and recursively copy them over
182  fList = oDir.entryList(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name);
183  for(int i=0; i<fList.length(); i++){
184    QStringList errs = revertDir(oldPath+"/"+fList[i], newPath+"/"+fList[i]);
185    if( !errs.isEmpty() ){ errors << errs; }
186  }
187  return errors;
188}
189
190QString LPGUtils::packageHomeDir(QString username, QString packageName){
191  //Check that the user directory exists
192  //qDebug() << "Start package dir:" << username << packageName;
193  if(!QFile::exists("/usr/home/"+username)){ return ""; }
194  //Check that the package has the right extension
195  if(!packageName.endsWith(".home.tar.gz")){ packageName.append(".home.tar.gz"); }
196  //Generate any additional files to be contained in the package
197 
198 
199  //Generate the command
200  QString cmd = "tar -czf /usr/home/"+packageName+" -C /usr/home "+username;
201  //Create the exclude list and skip these files
202  QStringList excludes;
203    excludes << "*flashplayer*"; //Don't overwrite the flash plugin
204  for(int i=0; i<excludes.length(); i++){
205    cmd.replace("-czf /usr/home", " --exclude \'"+excludes[i]+"\' -czf /usr/home");
206  }
207  //Run the command
208  qDebug() << "Package command:" << cmd;
209  system(cmd.toUtf8()); //need to be careful with the exclude syntax (quotes) so use system command
210  //qDebug() << "Command return:" << QString::number(ret);
211  //Check that the package was created
212  QString packagePath;
213  if(QFile::exists("/usr/home/"+packageName)){ packagePath = "/usr/home/"+packageName; }
214  //Now return the path to the package file
215  return packagePath;
216}
217
218bool LPGUtils::checkPackageUserPath(QString packagePath, QString *user){
219  user->clear();
220  //Determine if the file exists
221  if( !QFile::exists(packagePath) ){ return false; }
222  //Check the username of the home dir in the package
223  QStringList ret = LPBackend::getCmdOutput("tar -tvf "+packagePath);
224  if(ret.isEmpty()){ return false; }
225  QString username = ret[0].section(" ",2,2,QString::SectionSkipEmpty).simplified();
226  QString dirname = ret[0].section(" ",8,8,QString::SectionSkipEmpty).section("/",0,0).simplified();
227  user->append(username); //additional output
228  //Now check for the user on the local system
229  //This is just a simple check that the user directory exists, and the user/directory are the same within the package
230  return (username == dirname && QFile::exists("/usr/home/"+dirname) ); 
231}
232
233bool LPGUtils::extractHomeDirPackage(QString packagePath){
234 //Determine if the file exists
235  if( !QFile::exists(packagePath) ){ return false; }
236  //Now extract the archive in the home directory
237  QString cmd = "tar -xpf "+packagePath+" -C /usr/home";
238  qDebug() << "Extract command:" << cmd;
239  int ret = LPBackend::runCmd(cmd);
240  return (ret == 0);
241}
242
243QStringList LPGUtils::listAvailableHardDisks(){
244  QDir dev("/dev");
245  QStringList filters;
246        filters << "ada*" << "da*";
247  QStringList devs = dev.entryList(filters, QDir::Files | QDir::System | QDir::NoDotAndDotDot, QDir::Name);
248  //Filter out all the partitions (only keep full devices)
249  for(int i=0; i<devs.length(); i++){
250    devs[i] = devs[i].section("s",0,0,QString::SectionSkipEmpty);
251  }
252  devs.removeDuplicates();
253  return devs;
254}
Note: See TracBrowser for help on using the repository browser.