TAlienPackage.cxx

Go to the documentation of this file.
00001 // @(#)root/alien:$Id: TAlienPackage.cxx 29595 2009-07-27 13:55:26Z rdm $
00002 // Author: Lucia Jancurova/Andreas-Joachim Peters 1/10/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TSystem.h"
00014 #include "TGridResult.h"
00015 #include "TFile.h"
00016 #include "TObjString.h"
00017 #include "TObjArray.h"
00018 #include "TError.h"
00019 #include "TAlienPackage.h"
00020 
00021 //////////////////////////////////////////////////////////////////////////
00022 //                                                                      //
00023 // TAlienPackage                                                        //
00024 //                                                                      //
00025 // Class providing package management functionality like the AliEn      //
00026 // Package Management System.                                           //
00027 // Allows to setup software packages on a local desktop like in the     //
00028 // GRID environment and to execute the contained programs.              //
00029 // Registered Dependencies are automatically resolved and missing       //
00030 // packages are automatically installed.                                //
00031 // Currently there is no support for 'source' packages.                 //
00032 // The desired platform has to be specified in the constructor.         //
00033 // The default constructor takes packages from the global package       //
00034 // section in AliEn. If you want to install a user package, you have to //
00035 // set the AliEn package directory to your local package directory using//
00036 // 'package->SetAliEnMainPackageDir("/alice/cern.ch/user/..../packages")//
00037 //                                                                      //
00038 // ---------------------------------------------------------------------/////////////////////////
00039 // Examples of use:                                                                            //
00040 // root [0] TAlienPackage* package = new TAlienPackage("AliRoot","v4-07-Rev-01","Linux-i686"); //
00041 // root [1] package->Exec("aliroot -b -q ")                                                    //
00042 //                                                                                             //
00043 // root [0] TAlienPackage* package = new TAlienPackage("ROOT","v5-16-00","Linux-i686");        //
00044 // root [1] package->Exec("root -b -q ")                                                       //
00045 /////////////////////////////////////////////////////////////////////////////////////////////////
00046 
00047 
00048 
00049 ClassImp (TAlienPackage)
00050 
00051 //______________________________________________________________________________
00052 TAlienPackage::TAlienPackage() : fInstallList (0), fPackages (0), fDebugLevel (0)
00053 {
00054    // Default constructor of a AliEn package constructing a ROOT:v5-16-00 for Linux-i686.
00055 
00056    fName = "ROOT";
00057    fVersion = "v5-16-00";
00058    fPlatform = "Linux-i686";
00059    fAliEnMainPackageDir = "/alice/packages";
00060    fInstallationDirectory = "/var/tmp/alien/packages";
00061    fPostInstallCommand = "post_install";
00062    fEnableCommand = "";
00063 
00064    if (gDebug > 0)
00065       Info ("TAlienPackage",
00066             "\tPackage=%s Version=%s Platform=%s Installdir=%s AlienInstalldir=%s PostInstall=%s",
00067             fName.Data (), fVersion.Data (), fPlatform.Data (),
00068             fInstallationDirectory.Data (), fAliEnMainPackageDir.Data (),
00069             fPostInstallCommand.Data ());
00070    if (!gGrid)
00071       gGrid = TGrid::Connect ("alien://");
00072 
00073    if (!fInstallList)
00074       fInstallList = new TList ();
00075    if (!fPackages)
00076       fPackages = new TList ();
00077 
00078    fEnabled = kFALSE;
00079    fPackages->SetOwner (kFALSE);
00080 }
00081 
00082 //______________________________________________________________________________
00083 TAlienPackage::TAlienPackage(const char *name, const char *version,
00084                              const char *platform,
00085                              const char *installationdirectory) :
00086    fInstallList (0), fPackages (0), fDebugLevel (0)
00087 {
00088    // Constructor of a AliEn package.
00089 
00090    fName = name;
00091 
00092    fVersion = version;
00093 
00094    fAliEnMainPackageDir = "/alice/packages";
00095    fInstallationDirectory = installationdirectory;
00096    fPostInstallCommand = "post_install";
00097    fEnableCommand = "";
00098    fPlatform = platform;
00099    fEnabled = kFALSE;
00100 
00101    if (gDebug > 0)
00102       Info ("TAlienPackage",
00103             "\tPackage=%s Version=%s Platform=%s Installdir=%s AlienInstalldir=%s PostInstall=%s",
00104             name, version, platform, installationdirectory,
00105             fAliEnMainPackageDir.Data (), fPostInstallCommand.Data ());
00106 
00107    if (!gGrid)
00108       gGrid = TGrid::Connect ("alien://");
00109 
00110    if (!fInstallList)
00111       fInstallList = new TList ();
00112 
00113    if (!fPackages)
00114       fPackages = new TList ();
00115    fPackages->SetOwner (kFALSE);
00116 }
00117 
00118 //______________________________________________________________________________
00119 TAlienPackage::~TAlienPackage()
00120 {
00121    // Destructor.
00122 
00123    if (GetDebugLevel () > 2)
00124       Info ("~TAlienPackage", "\tDestr: Package=%s Version=%s Platform=%s",
00125             fName.Data (), fVersion.Data (), fPlatform.Data ());
00126    SafeDelete (fInstallList);
00127 }
00128 
00129 //______________________________________________________________________________
00130 Bool_t TAlienPackage::Enable()
00131 {
00132    // Install/enable an AliEn package on the local computer.
00133 
00134    fInstallList->Clear ();
00135    if (GetDebugLevel () > 1)
00136       Info ("Install", "\t\tInstalling Package=%s Version=%s Platform=%s",
00137             fName.Data (), fVersion.Data (), fPlatform.Data ());
00138 
00139    if (CheckDirectories (fName, fVersion) == kFALSE)
00140       return kFALSE;
00141 
00142    if (CheckDependencies () == kFALSE)
00143       return kFALSE;
00144 
00145    if (InstallAllPackages () == kFALSE)
00146       return kFALSE;
00147 
00148    gSystem->Exec(Form("mkdir -p %s/%s/%s/%s ; touch  %s/%s/%s/%s/.safeguard",
00149                  fInstallationDirectory.Data (), fName.Data (), fVersion.Data (),
00150                  fVersion.Data (), fInstallationDirectory.Data (), fName.Data (),
00151                  fVersion.Data (), fVersion.Data ()));
00152 
00153    fEnabled = kTRUE;
00154    return kTRUE;
00155 }
00156 
00157 //______________________________________________________________________________
00158 const char *TAlienPackage::GetEnable ()
00159 {
00160    // Return shell command to enable package.
00161 
00162    fEnableCommand =
00163       Form ("%s/%s/%s/.alienEnvironment %s/%s/%s ",
00164             fInstallationDirectory.Data (), fName.Data (), fVersion.Data (),
00165             fInstallationDirectory.Data (), fName.Data (), fVersion.Data ());
00166    return fEnableCommand.Data ();
00167 }
00168 
00169 //______________________________________________________________________________
00170 Bool_t TAlienPackage::UnInstall ()
00171 {
00172    // Uninstall a package e.g. remove it from the local disk.
00173 
00174    gSystem->Exec(Form
00175             ("test -e %s/%s/%s/%s/.safeguard && rm -rf %s/%s/%s",
00176              fInstallationDirectory.Data (), fName.Data (), fVersion.Data (),
00177              fVersion.Data (), fInstallationDirectory.Data (), fName.Data (),
00178              fVersion.Data ()));
00179    fEnabled = kFALSE;
00180    return kTRUE;
00181 }
00182 
00183 //______________________________________________________________________________
00184 Bool_t TAlienPackage::IsDirectory (const char *dir1, const char *str)
00185 {
00186    // Check that <str> is listed in GRID directory <dir1>.
00187 
00188    TGridResult *result = gGrid->Ls (dir1);
00189    Int_t i = 0;
00190    while (result->GetFileName (i)) {
00191       if (TString (result->GetFileName (i)) == str) {
00192          return kTRUE;
00193       }
00194       i++;
00195    }
00196 
00197    return kFALSE;
00198 }
00199 
00200 //______________________________________________________________________________
00201 Bool_t TAlienPackage::CheckDirectories (TString name, TString version)
00202 {
00203    // Check the name and version directory of package/version given.
00204 
00205    TString s(GetAliEnMainPackageDir());
00206 
00207    if ((IsDirectory (s.Data (), name.Data ())) == kTRUE) {
00208       if (GetDebugLevel () > 1)
00209          Info ("CheckDirectories", "\t%s/%s exists.", s.Data (), name.Data ());
00210 
00211       s += "/" + name;
00212       if ((IsDirectory (s, version.Data ())) == kTRUE) {
00213          if (GetDebugLevel () > 1)
00214             Info ("CheckDirectories", "\t%s/%s exist.", s.Data (), version.Data ());
00215 
00216          s += "/" + version;
00217          if ((IsDirectory (s, GetPlatform ().Data ())) == kTRUE) {
00218             if (GetDebugLevel () > 1)
00219                Info ("CheckDirectories", "\t%s/%s exist.", s.Data (), GetPlatform ().Data ());
00220             return kTRUE;
00221          } else {
00222             Error ("CheckDirectories", "\t%s/%s does not exist.", s.Data (), GetPlatform ().Data ());
00223          }
00224       } else {
00225          Error ("CheckDirectories", "\t%s/%s does not exist.", s.Data (), version.Data ());
00226       }
00227    }  else {
00228       Info ("CheckDirectories", "\t%s/%s exists.", s.Data (), name.Data ());
00229    }
00230 
00231    return kFALSE;
00232 }
00233 
00234 //______________________________________________________________________________
00235 Bool_t TAlienPackage::ReInstall ()
00236 {
00237    // Reinstalls a package e.g. uninstall + install.
00238 
00239    if (UnInstall () == kFALSE)
00240       return kFALSE;
00241 
00242    if (Enable () == kFALSE)
00243       return kFALSE;
00244    return kTRUE;
00245 }
00246 
00247 //______________________________________________________________________________
00248 Bool_t TAlienPackage::PostInstall (TString name, TString version)
00249 {
00250    // Execute post_install procedure for a package.
00251 
00252    TGridResult *result =
00253       gGrid->Command (Form
00254                ("showTagValue -z %s/%s/%s PackageDef",
00255                 fAliEnMainPackageDir.Data (), name.Data (), version.Data ()));
00256    TString post_install (result->GetKey (0, "post_install"));
00257 
00258    if (post_install.IsNull () == kTRUE) {
00259       if (GetDebugLevel () > 0)
00260          Info ("PostInstall",
00261                "\tNo post install procedure defined in AliEn.");
00262       return kTRUE;
00263    }
00264 
00265    if (GetDebugLevel () > 0)
00266       Info ("PostInstall",
00267             "\tDownloading PostInstall for Package=%s Version=%s",
00268             name.Data (), version.Data ());
00269 
00270    if (!TFile::Cp(Form("alien://%s", post_install.Data ()),
00271                   Form("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
00272                   version.Data (), fPostInstallCommand.Data ()))) {
00273       Error ("PostInstall", "\tCannot download the PostInstall script %s!", post_install.Data ());
00274       return kFALSE;
00275    }
00276 
00277    gSystem->ChangeDirectory (Form
00278                        ("%s/%s/%s", fInstallationDirectory.Data (),
00279                         name.Data (), version.Data ()));
00280    gSystem->Exec (Form ("chmod +x %s", fPostInstallCommand.Data ()));
00281    gSystem->Exec (Form ("./%s %s/%s/%s", fPostInstallCommand.Data (),
00282              fInstallationDirectory.Data (), name.Data (), version.Data ()));
00283 
00284    if (GetDebugLevel () > 1)
00285       Info ("PostInstall",
00286             "\tExecuted PostInstall for Package=%s Version=%s ", name.Data (),
00287             version.Data ());
00288    return kTRUE;
00289 }
00290 
00291 //______________________________________________________________________________
00292 Bool_t TAlienPackage::Exec (const char *cmdline)
00293 {
00294    // Execute package command.
00295 
00296    TString fullline = "";
00297 
00298    if (!fEnabled) {
00299       if (!Enable ())
00300          return kFALSE;
00301    }
00302 
00303    for (Int_t j = 0; j < fPackages->GetEntries (); j++) {
00304       TAlienPackage *package = (TAlienPackage *) fPackages->At (j);
00305       fullline += package->GetEnable ();
00306       fullline += " ";
00307    }
00308 
00309    fullline += cmdline;
00310 
00311    Info("Exec", "\t\tExecuting Package=%s Version=%s \"%s\"", fName.Data (),
00312         fVersion.Data (), fullline.Data ());
00313 
00314    gSystem->Exec(fullline.Data());
00315    return kTRUE;
00316 }
00317 
00318 //______________________________________________________________________________
00319 Bool_t TAlienPackage::CheckDependencies ()
00320 {
00321    // Check the dependency packages of this package.
00322 
00323    TString path (Form("%s/%s/%s", fAliEnMainPackageDir.Data (), fName.Data (),
00324              fVersion.Data ()));
00325 
00326    TGridResult *result =
00327       gGrid->Command (Form ("showTagValue -z %s PackageDef", path.Data ()));
00328 
00329    TString strDep (result->GetKey (0, "dependencies"));
00330 
00331    if (strDep.IsNull () == kTRUE) {
00332       if (GetDebugLevel () > 0)
00333          Info ("CheckDepencencies", "\tFound no dependencies ... ");
00334       TObjString *strObj =
00335          new TObjString (Form ("%s::%s", fName.Data (), fVersion.Data ()));
00336       fInstallList->Add (strObj);
00337       return kTRUE;
00338    }
00339 
00340    TObjArray *strDeps = strDep.Tokenize (",");
00341 
00342    if (GetDebugLevel () > 0)
00343       Info ("CheckDepencencies", "\tFound %d dependencies ... ",
00344             strDeps->GetEntries ());
00345 
00346    for (Int_t i = 0; i < strDeps->GetEntries (); i++) {
00347       TObjString *strObj = (TObjString *) strDeps->At (i);
00348       TObjArray *strDepsPackgAndVer = strObj->GetString ().Tokenize ("@");
00349       TObjString *strObj2 = (TObjString *) strDepsPackgAndVer->At (1);
00350 
00351       if (GetDebugLevel () > 2)
00352          Info ("CheckDependencies", "\t[%d] Dep. Package=%s", i,
00353                strObj2->GetString ().Data ());
00354       fInstallList->Add (strObj2);
00355    }
00356 
00357    TObjString *strObj = new TObjString (Form ("%s::%s", fName.Data (), fVersion.Data ()));
00358    fInstallList->Add (strObj);
00359 
00360    for (Int_t j = 0; j < fInstallList->GetEntries (); j++) {
00361       strObj = (TObjString *) fInstallList->At(j);
00362       TString strObjPackage, strObjVersion;
00363       Int_t from = 0;
00364       if (strObj->GetString().Tokenize(strObjPackage, from, "::")) {
00365          if (!strObj->GetString().Tokenize(strObjVersion, from, "::")) {
00366             Warning("CheckDepencencies", "version string not found for j=%d (%s)", j, strObj->GetName());
00367             continue;
00368          }
00369       } else {
00370          Warning("CheckDepencencies", "package string not found for j=%d (%s)", j, strObj->GetName());
00371          continue;
00372       }
00373 
00374       if (GetDebugLevel () > 2)
00375          Info ("CheckDepencencies", "\t[%d] Name=%s Version=%s", j,
00376                strObjPackage.Data(), strObjVersion.Data());
00377 
00378       if (CheckDirectories(strObjPackage, strObjVersion) == kFALSE)
00379          return kFALSE;
00380    }
00381 
00382    return kTRUE;
00383 }
00384 
00385 //______________________________________________________________________________
00386 Bool_t TAlienPackage::InstallSinglePackage(TString name, TString version, Bool_t isDep)
00387 {
00388    // Install a single package.
00389 
00390    Info ("InstallSinglePackage", "\t%s %s", name.Data (), version.Data ());
00391    // install a package without dependencies
00392    TString s1 (Form ("%s/%s/%s/%s", fAliEnMainPackageDir.Data (), name.Data (),
00393            version.Data (), fPlatform.Data ()));
00394    TString s2 (Form ("%s(%s)", name.Data (), version.Data ()));
00395    TString s3 (Form ("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
00396            version.Data (), version.Data ()));
00397    TString s4 (Form ("%s/%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
00398            version.Data (), version.Data (), fPlatform.Data ()));
00399    TString s5 (Form ("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
00400            version.Data (), fPlatform.Data ()));
00401    TString s6 (Form ("%s/%s", fAliEnMainPackageDir.Data (), name.Data ()));
00402    TString s7 (Form ("%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
00403            version.Data ()));
00404    TString s8 (Form ("%s/%s/%s/%s/.safeguard", fInstallationDirectory.Data (),
00405            name.Data (), version.Data (), version.Data ()));
00406 
00407    if (gSystem->AccessPathName (s8.Data ()) == 0) {
00408       if (isDep == kFALSE) {
00409          if (GetDebugLevel () > 0) {
00410             Warning ("InstallSinglePackage",
00411                      "\tPackage=%s exists in /%s directory.",
00412                      s2.Data (), s3.Data ());
00413             Warning ("InstallSinglePackage",
00414                      "\tYou might use function UnInstall() before Enable(), or do ReInstall() !!!!");
00415          }
00416          return kTRUE;
00417       } else {
00418          return kTRUE;
00419       }
00420    }
00421 
00422    if (GetDebugLevel () > 1)
00423       Info ("InstallSinglePackage", "\tCopying from alien://%s to %s ",
00424             s1.Data (), s5.Data ());
00425 
00426    gSystem->Exec (Form ("mkdir -p %s", s3.Data ()));
00427 
00428    if (gSystem->AccessPathName (s3.Data ())) {
00429       Error ("InstallSinglePackage", "\tCouldn't create directory %s !",
00430              s3.Data ());
00431       return kFALSE;
00432    }
00433 
00434    if (!TFile::Cp (Form ("alien://%s", s1.Data ()), Form ("%s", s5.Data ()))) {
00435       Error ("InstallSinglePackage", "\tCouldn't copy alien://%s -> %s",
00436              s1.Data (), s5.Data ());
00437       return kFALSE;
00438    }
00439 
00440    if (GetDebugLevel () > 2)
00441       Info ("InstallSinglePackage", "\tEntering directory %s ", s7.Data ());
00442 
00443    if (!gSystem->ChangeDirectory (Form ("%s", s7.Data ()))) {
00444       Error ("InstallSinglePackage", "\tCannot change into directory %s",
00445              s7.Data ());
00446       return kFALSE;
00447    }
00448 
00449    if (GetDebugLevel () > 2)
00450       Info ("InstallSinglePackage", "\tUnpacking the package %s ...",
00451             s2.Data ());
00452 
00453    gSystem->Exec (Form ("tar -xzf %s", fPlatform.Data ()));
00454 
00455    if (GetDebugLevel () > 2)
00456       Info ("InstallSinglePackage", "\tUnpacking the package %s DONE ...",
00457             s2.Data ());
00458 
00459    gSystem->Exec (Form ("rm -f %s", fPlatform.Data ()));
00460 
00461    if (GetDebugLevel () > 2)
00462       Info ("InstallSinglePackage",
00463             "\tCopying PostInstall alien://%s/%s -> %s", s6.Data (),
00464             fPostInstallCommand.Data (), s7.Data ());
00465 
00466    if (!PostInstall (name, version)) {
00467       Error ("InstallSinglePackage",
00468              "\tPostInstall procedure failed for package %s failed!",
00469              s2.Data ());
00470       return kFALSE;
00471    }
00472 
00473    return kTRUE;
00474 }
00475 
00476 //______________________________________________________________________________
00477 Bool_t TAlienPackage::InstallAllPackages ()
00478 {
00479    // Installs a package and all its direct dependencies.
00480 
00481    Bool_t isDep = kFALSE;
00482 
00483    Info ("InstallAllPackages", "\tPackage=%s Version=%s", fName.Data (),
00484          fVersion.Data ());
00485 
00486    for (Int_t j = 0; j < fPackages->GetEntries (); j++) {
00487       TAlienPackage *package = (TAlienPackage *) fPackages->At (j);
00488       if (package && (package != this))
00489          delete package;
00490    }
00491 
00492    fPackages->Clear ();
00493 
00494    for (Int_t j = 0; j < fInstallList->GetEntries (); j++) {
00495       TObjString *strObj = (TObjString *) fInstallList->At (j);
00496 
00497       TObjArray *strDepsPackgOrVer = strObj->GetString ().Tokenize ("::");
00498       TObjString *strObjPackage = (TObjString *) strDepsPackgOrVer->At (0);
00499       TObjString *strObjVersion = (TObjString *) strDepsPackgOrVer->At (1);
00500       if (GetDebugLevel () > 1)
00501          Info ("InstallAllPackages", "\tPackage=%s Version=%s",
00502                strObjPackage->GetString ().Data (),
00503                strObjVersion->GetString ().Data ());
00504 
00505       if (j < (fInstallList->GetEntries () - 1))
00506          isDep = kTRUE;
00507       else
00508          isDep = kFALSE;
00509 
00510       if (j == (fInstallList->GetEntries () - 1)) {
00511          if (InstallSinglePackage(strObjPackage->GetString (), strObjVersion->GetString (), isDep) == kFALSE)
00512             return kFALSE;
00513          fPackages->Add ((TObject *) this);
00514       } else {
00515          TAlienPackage *newpackage = new TAlienPackage(strObjPackage->GetName(),
00516                                                        strObjVersion->GetName(),
00517                                                        fPlatform.Data());
00518          if (newpackage) {
00519             if (!newpackage->Enable ())
00520                return kFALSE;
00521          } else {
00522             return kFALSE;
00523          }
00524 
00525          fPackages->Add ((TObject *) newpackage);
00526       }
00527    }
00528 
00529    return kTRUE;
00530 }

Generated on Tue Jul 5 14:45:30 2011 for ROOT_528-00b_version by  doxygen 1.5.1